1 /* 2 * Copyright (c) 2021 Eivind Nss. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 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 14 * distribution. 15 * 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. 19 * 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. 27 */ 28 29 #ifdef HAVE_CONFIG_H 30 #include "config.h" 31 #endif 32 33 #include <string.h> 34 #include <openssl/ssl.h> 35 #include <openssl/err.h> 36 #include <openssl/x509v3.h> 37 38 #include "pppd-private.h" 39 #include "tls.h" 40 41 /** 42 * Structure used in verifying the peer certificate 43 */ 44 struct tls_info 45 { 46 char *peer_name; 47 X509 *peer_cert; 48 bool client; 49 }; 50 51 52 #if OPENSSL_VERSION_NUMBER < 0x10100000L 53 54 /* 55 * OpenSSL 1.1+ introduced a generic TLS_method() 56 * For older releases we substitute the appropriate method 57 */ 58 #define TLS_method SSLv23_method 59 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) 63 { 64 long sslopt = 0; 65 66 if (tls_ver_max < TLS1_VERSION) 67 { 68 sslopt |= SSL_OP_NO_TLSv1; 69 } 70 #ifdef SSL_OP_NO_TLSv1_1 71 if (tls_ver_max < TLS1_1_VERSION) 72 { 73 sslopt |= SSL_OP_NO_TLSv1_1; 74 } 75 #endif 76 #ifdef SSL_OP_NO_TLSv1_2 77 if (tls_ver_max < TLS1_2_VERSION) 78 { 79 sslopt |= SSL_OP_NO_TLSv1_2; 80 } 81 #endif 82 SSL_CTX_set_options(ctx, sslopt); 83 84 return 1; 85 } 86 #endif /* SSL_CTX_set_max_proto_version */ 87 88 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ 89 90 91 /* 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. 94 */ 95 static int tls_verify_callback(int ok, X509_STORE_CTX *ctx) 96 { 97 char subject[256]; 98 char cn_str[256]; 99 X509 *peer_cert; 100 int err, depth; 101 SSL *ssl; 102 struct tls_info *inf; 103 char *ptr1 = NULL, *ptr2 = NULL; 104 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); 108 109 dbglog("certificate verify depth: %d", depth); 110 111 if (auth_required && !ok) { 112 X509_NAME_oneline(X509_get_subject_name(peer_cert), 113 subject, 256); 114 115 X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), 116 NID_commonName, cn_str, 256); 117 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)); 121 122 return 0; 123 } 124 125 ssl = X509_STORE_CTX_get_ex_data(ctx, 126 SSL_get_ex_data_X509_STORE_CTX_idx()); 127 128 inf = (struct tls_info*) SSL_get_ex_data(ssl, 0); 129 if (inf == NULL) { 130 error("Error: SSL_get_ex_data returned NULL"); 131 return 0; 132 } 133 134 tls_log_sslerr(); 135 136 if (!depth) 137 { 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"); 143 return 0; 144 } 145 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"); 150 return 0; 151 } 152 #endif 153 info("Certificate key usage: OK"); 154 } 155 156 /* 157 * If acting as client and the name of the server wasn't specified 158 * explicitely, we can't verify the server authenticity 159 */ 160 if (!tls_verify_method) 161 tls_verify_method = TLS_VERIFY_NONE; 162 163 if (!inf->peer_name || !strcmp(TLS_VERIFY_NONE, tls_verify_method)) { 164 warn("Certificate verication disabled or no peer name was specified"); 165 return ok; 166 } 167 168 /* This is the peer certificate */ 169 X509_NAME_oneline(X509_get_subject_name(peer_cert), 170 subject, 256); 171 172 X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), 173 NID_commonName, cn_str, 256); 174 175 /* Verify based on subject name */ 176 ptr1 = inf->peer_name; 177 if (!strcmp(TLS_VERIFY_SUBJECT, tls_verify_method)) { 178 ptr2 = subject; 179 } 180 181 /* Verify based on common name (default) */ 182 if (strlen(tls_verify_method) == 0 || 183 !strcmp(TLS_VERIFY_NAME, tls_verify_method)) { 184 ptr2 = cn_str; 185 } 186 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; 191 ptr2 = cn_str; 192 if (off > 0) { 193 ptr2 = cn_str + off; 194 } 195 } 196 197 if (strcmp(ptr1, ptr2)) { 198 error("Certificate verification error: CN (%s) != %s", ptr1, ptr2); 199 return 0; 200 } 201 202 if (inf->peer_cert) { 203 if (X509_cmp(inf->peer_cert, peer_cert) != 0) { 204 error("Peer certificate doesn't match stored certificate"); 205 return 0; 206 } 207 } 208 209 info("Certificate CN: %s, peer name %s", cn_str, inf->peer_name); 210 } 211 212 return ok; 213 } 214 215 int tls_init() 216 { 217 #if OPENSSL_VERSION_NUMBER < 0x10100000L 218 SSL_library_init(); 219 SSL_load_error_strings(); 220 #endif 221 return 0; 222 } 223 224 int tls_set_verify(SSL_CTX *ctx, int depth) 225 { 226 SSL_CTX_set_verify_depth(ctx, depth); 227 SSL_CTX_set_verify(ctx, 228 SSL_VERIFY_PEER | 229 SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 230 &tls_verify_callback); 231 return 0; 232 } 233 234 int tls_set_verify_info(SSL *ssl, const char *peer_name, const char *peer_cert, 235 bool client, struct tls_info **out) 236 { 237 if (out != NULL) { 238 struct tls_info *tmp = calloc(1, sizeof(struct tls_info)); 239 if (!tmp) { 240 fatal("Allocation error"); 241 } 242 243 tmp->client = client; 244 if (peer_name) { 245 tmp->peer_name = strdup(peer_name); 246 } 247 248 if (peer_cert && strlen(peer_cert) > 0) { 249 FILE *fp = fopen(peer_cert, "r"); 250 if (fp) { 251 tmp->peer_cert = PEM_read_X509(fp, NULL, NULL, NULL); 252 fclose(fp); 253 } 254 255 if (!tmp->peer_cert) { 256 error("EAP-TLS: Error loading client certificate from file %s", 257 peer_cert); 258 tls_free_verify_info(&tmp); 259 return -1; 260 } 261 } 262 263 SSL_set_ex_data(ssl, 0, tmp); 264 *out = tmp; 265 return 0; 266 } 267 268 return -1; 269 } 270 271 void tls_free_verify_info(struct tls_info **in) { 272 if (in && *in) { 273 struct tls_info *tmp = *in; 274 if (tmp->peer_name) { 275 free(tmp->peer_name); 276 } 277 if (tmp->peer_cert) { 278 X509_free(tmp->peer_cert); 279 } 280 free(tmp); 281 *in = NULL; 282 } 283 } 284 285 const SSL_METHOD* tls_method() { 286 return TLS_method(); 287 } 288 289 int tls_set_version(SSL_CTX *ctx, const char *max_version) 290 { 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; 295 #else 296 long tls_version = TLS1_VERSION; 297 #endif 298 299 /* As EAP-TLS+TLSv1.3 is highly experimental we offer the user a chance to override */ 300 if (max_version) { 301 if (strncmp(max_version, "1.0", 3) == 0) { 302 tls_version = TLS1_VERSION; 303 } 304 else if (strncmp(max_version, "1.1", 3) == 0) { 305 tls_version = TLS1_1_VERSION; 306 } 307 else if (strncmp(max_version, "1.2", 3) == 0) { 308 #ifdef TLS1_2_VERSION 309 tls_version = TLS1_2_VERSION; 310 #else 311 warn("TLSv1.2 not available. Defaulting to TLSv1.1"); 312 tls_version = TLS_1_1_VERSION; 313 #endif 314 } 315 else if (strncmp(max_version, "1.3", 3) == 0) { 316 #ifdef TLS1_3_VERSION 317 tls_version = TLS1_3_VERSION; 318 #else 319 warn("TLSv1.3 not available."); 320 #endif 321 } 322 } 323 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"); 327 return -1; 328 } 329 330 return 0; 331 } 332 333 int tls_set_opts(SSL_CTX *ctx) { 334 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 338 | SSL_OP_NO_TICKET 339 #endif 340 | SSL_OP_NO_COMPRESSION 341 ); 342 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 347 348 SSL_CTX_set_cipher_list(ctx, "RC4"); 349 */ 350 return 0; 351 } 352 353 int tls_set_crl(SSL_CTX *ctx, const char *crl_dir, const char *crl_file) 354 { 355 X509_STORE *certstore = NULL; 356 X509_LOOKUP *lookup = NULL; 357 FILE *fp = NULL; 358 int status = -1; 359 360 if (crl_dir) { 361 if (!(certstore = SSL_CTX_get_cert_store(ctx))) { 362 error("Failed to get certificate store"); 363 goto done; 364 } 365 366 if (!(lookup = 367 X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) { 368 error("Store lookup for CRL failed"); 369 goto done; 370 } 371 372 X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM); 373 X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); 374 } 375 376 if (crl_file) { 377 X509_CRL *crl = NULL; 378 379 fp = fopen(crl_file, "r"); 380 if (!fp) { 381 error("Cannot open CRL file '%s'", crl_file); 382 goto done; 383 } 384 385 crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL); 386 if (!crl) { 387 error("Cannot read CRL file '%s'", crl_file); 388 goto done; 389 } 390 391 if (!(certstore = SSL_CTX_get_cert_store(ctx))) { 392 error("Failed to get certificate store"); 393 goto done; 394 } 395 if (!X509_STORE_add_crl(certstore, crl)) { 396 error("Cannot add CRL to certificate store"); 397 goto done; 398 } 399 X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); 400 } 401 402 status = 0; 403 404 done: 405 406 if (fp != NULL) { 407 fclose(fp); 408 } 409 410 return status; 411 } 412 413 int tls_set_ca(SSL_CTX *ctx, const char *ca_dir, const char *ca_file) 414 { 415 if (ca_file && strlen(ca_file) == 0) { 416 ca_file = NULL; 417 } 418 419 if (ca_dir && strlen(ca_dir) == 0) { 420 ca_dir = NULL; 421 } 422 423 if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_dir)) { 424 425 error("Cannot load verify locations"); 426 if (ca_file) { 427 dbglog("CA certificate file = [%s]", ca_file); 428 } 429 430 if (ca_dir) { 431 dbglog("CA certificate path = [%s]", ca_dir); 432 } 433 434 return -1; 435 } 436 437 return 0; 438 } 439 440 void tls_log_sslerr( void ) 441 { 442 unsigned long ssl_err = ERR_get_error(); 443 444 if (ssl_err != 0) 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(); 449 } 450 } 451 452