2 * Copyright (c) 2021 Eivind Næss. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * 3. The name(s) of the authors of this software must not be used to
17 * endorse or promote products derived from this software without
18 * prior written permission.
20 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
21 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
23 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
25 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
26 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
34 #include <openssl/ssl.h>
35 #include <openssl/err.h>
36 #include <openssl/x509v3.h>
38 #include "pppd-private.h"
42 * Structure used in verifying the peer certificate
52 #if OPENSSL_VERSION_NUMBER < 0x10100000L
55 * OpenSSL 1.1+ introduced a generic TLS_method()
56 * For older releases we substitute the appropriate method
58 #define TLS_method SSLv23_method
60 #ifndef SSL_CTX_set_max_proto_version
61 /** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
62 static inline int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
66 if (tls_ver_max < TLS1_VERSION)
68 sslopt |= SSL_OP_NO_TLSv1;
70 #ifdef SSL_OP_NO_TLSv1_1
71 if (tls_ver_max < TLS1_1_VERSION)
73 sslopt |= SSL_OP_NO_TLSv1_1;
76 #ifdef SSL_OP_NO_TLSv1_2
77 if (tls_ver_max < TLS1_2_VERSION)
79 sslopt |= SSL_OP_NO_TLSv1_2;
82 SSL_CTX_set_options(ctx, sslopt);
86 #endif /* SSL_CTX_set_max_proto_version */
88 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
92 * Verify a certificate. Most of the work (signatures and issuer attributes checking)
93 * is done by ssl; we check the CN in the peer certificate against the peer name.
95 static int tls_verify_callback(int ok, X509_STORE_CTX *ctx)
102 struct tls_info *inf;
103 char *ptr1 = NULL, *ptr2 = NULL;
105 peer_cert = X509_STORE_CTX_get_current_cert(ctx);
106 err = X509_STORE_CTX_get_error(ctx);
107 depth = X509_STORE_CTX_get_error_depth(ctx);
109 dbglog("certificate verify depth: %d", depth);
111 if (auth_required && !ok) {
112 X509_NAME_oneline(X509_get_subject_name(peer_cert),
115 X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
116 NID_commonName, cn_str, 256);
118 dbglog("Certificate verification error:\n depth: %d CN: %s"
119 "\n err: %d (%s)\n", depth, cn_str, err,
120 X509_verify_cert_error_string(err));
125 ssl = X509_STORE_CTX_get_ex_data(ctx,
126 SSL_get_ex_data_X509_STORE_CTX_idx());
128 inf = (struct tls_info*) SSL_get_ex_data(ssl, 0);
130 error("Error: SSL_get_ex_data returned NULL");
138 /* Verify certificate based on certificate type and extended key usage */
139 if (tls_verify_key_usage) {
140 int purpose = inf->client ? X509_PURPOSE_SSL_SERVER : X509_PURPOSE_SSL_CLIENT ;
141 if (X509_check_purpose(peer_cert, purpose, 0) == 0) {
142 error("Certificate verification error: nsCertType mismatch");
146 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
147 int flags = inf->client ? XKU_SSL_SERVER : XKU_SSL_CLIENT;
148 if (!(X509_get_extended_key_usage(peer_cert) & flags)) {
149 error("Certificate verification error: invalid extended key usage");
153 info("Certificate key usage: OK");
157 * If acting as client and the name of the server wasn't specified
158 * explicitely, we can't verify the server authenticity
160 if (!tls_verify_method)
161 tls_verify_method = TLS_VERIFY_NONE;
163 if (!inf->peer_name || !strcmp(TLS_VERIFY_NONE, tls_verify_method)) {
164 warn("Certificate verication disabled or no peer name was specified");
168 /* This is the peer certificate */
169 X509_NAME_oneline(X509_get_subject_name(peer_cert),
172 X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
173 NID_commonName, cn_str, 256);
175 /* Verify based on subject name */
176 ptr1 = inf->peer_name;
177 if (!strcmp(TLS_VERIFY_SUBJECT, tls_verify_method)) {
181 /* Verify based on common name (default) */
182 if (strlen(tls_verify_method) == 0 ||
183 !strcmp(TLS_VERIFY_NAME, tls_verify_method)) {
187 /* Match the suffix of common name */
188 if (!strcmp(TLS_VERIFY_SUFFIX, tls_verify_method)) {
189 int len = strlen(ptr1);
190 int off = strlen(cn_str) - len;
197 if (strcmp(ptr1, ptr2)) {
198 error("Certificate verification error: CN (%s) != %s", ptr1, ptr2);
202 if (inf->peer_cert) {
203 if (X509_cmp(inf->peer_cert, peer_cert) != 0) {
204 error("Peer certificate doesn't match stored certificate");
209 info("Certificate CN: %s, peer name %s", cn_str, inf->peer_name);
217 #if OPENSSL_VERSION_NUMBER < 0x10100000L
219 SSL_load_error_strings();
224 int tls_set_verify(SSL_CTX *ctx, int depth)
226 SSL_CTX_set_verify_depth(ctx, depth);
227 SSL_CTX_set_verify(ctx,
229 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
230 &tls_verify_callback);
234 int tls_set_verify_info(SSL *ssl, const char *peer_name, const char *peer_cert,
235 bool client, struct tls_info **out)
238 struct tls_info *tmp = calloc(1, sizeof(struct tls_info));
240 fatal("Allocation error");
243 tmp->client = client;
245 tmp->peer_name = strdup(peer_name);
248 if (peer_cert && strlen(peer_cert) > 0) {
249 FILE *fp = fopen(peer_cert, "r");
251 tmp->peer_cert = PEM_read_X509(fp, NULL, NULL, NULL);
255 if (!tmp->peer_cert) {
256 error("EAP-TLS: Error loading client certificate from file %s",
258 tls_free_verify_info(&tmp);
263 SSL_set_ex_data(ssl, 0, tmp);
271 void tls_free_verify_info(struct tls_info **in) {
273 struct tls_info *tmp = *in;
274 if (tmp->peer_name) {
275 free(tmp->peer_name);
277 if (tmp->peer_cert) {
278 X509_free(tmp->peer_cert);
285 const SSL_METHOD* tls_method() {
289 int tls_set_version(SSL_CTX *ctx, const char *max_version)
291 #if defined(TLS1_2_VERSION)
292 long tls_version = TLS1_2_VERSION;
293 #elif defined(TLS1_1_VERSION)
294 long tls_version = TLS1_1_VERSION;
296 long tls_version = TLS1_VERSION;
299 /* As EAP-TLS+TLSv1.3 is highly experimental we offer the user a chance to override */
301 if (strncmp(max_version, "1.0", 3) == 0) {
302 tls_version = TLS1_VERSION;
304 else if (strncmp(max_version, "1.1", 3) == 0) {
305 tls_version = TLS1_1_VERSION;
307 else if (strncmp(max_version, "1.2", 3) == 0) {
308 #ifdef TLS1_2_VERSION
309 tls_version = TLS1_2_VERSION;
311 warn("TLSv1.2 not available. Defaulting to TLSv1.1");
312 tls_version = TLS_1_1_VERSION;
315 else if (strncmp(max_version, "1.3", 3) == 0) {
316 #ifdef TLS1_3_VERSION
317 tls_version = TLS1_3_VERSION;
319 warn("TLSv1.3 not available.");
324 dbglog("Setting max protocol version to 0x%X", tls_version);
325 if (!SSL_CTX_set_max_proto_version(ctx, tls_version)) {
326 error("Could not set max protocol version");
333 int tls_set_opts(SSL_CTX *ctx) {
335 /* Explicitly set the NO_TICKETS flag to support Win7/Win8 clients */
336 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3
337 #ifdef SSL_OP_NO_TICKET
340 | SSL_OP_NO_COMPRESSION
343 /* OpenSSL 1.1.1+ does not include RC4 ciphers by default.
344 * This causes totally obsolete WinXP clients to fail. If you really
345 * need ppp+EAP-TLS+openssl 1.1.1+WinXP then enable RC4 cipers and
346 * make sure that you use an OpenSSL that supports them
348 SSL_CTX_set_cipher_list(ctx, "RC4");
353 int tls_set_crl(SSL_CTX *ctx, const char *crl_dir, const char *crl_file)
355 X509_STORE *certstore = NULL;
356 X509_LOOKUP *lookup = NULL;
361 if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
362 error("Failed to get certificate store");
367 X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) {
368 error("Store lookup for CRL failed");
372 X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM);
373 X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
377 X509_CRL *crl = NULL;
379 fp = fopen(crl_file, "r");
381 error("Cannot open CRL file '%s'", crl_file);
385 crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL);
387 error("Cannot read CRL file '%s'", crl_file);
391 if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
392 error("Failed to get certificate store");
395 if (!X509_STORE_add_crl(certstore, crl)) {
396 error("Cannot add CRL to certificate store");
399 X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
413 int tls_set_ca(SSL_CTX *ctx, const char *ca_dir, const char *ca_file)
415 if (ca_file && strlen(ca_file) == 0) {
419 if (ca_dir && strlen(ca_dir) == 0) {
423 if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_dir)) {
425 error("Cannot load verify locations");
427 dbglog("CA certificate file = [%s]", ca_file);
431 dbglog("CA certificate path = [%s]", ca_dir);
440 void tls_log_sslerr( void )
442 unsigned long ssl_err = ERR_get_error();
445 dbglog("EAP-TLS SSL error stack:");
446 while (ssl_err != 0) {
447 dbglog( ERR_error_string( ssl_err, NULL ) );
448 ssl_err = ERR_get_error();