x509_openssl.c (12889B)
1 /* Copyright (c) 2003, Roger Dingledine. 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 /** 7 * \file x509_openssl.c 8 * \brief Wrapper functions to present a consistent interface to 9 * X.509 functions from OpenSSL. 10 **/ 11 12 #define TOR_X509_PRIVATE 13 #include "lib/tls/x509.h" 14 #include "lib/tls/x509_internal.h" 15 #include "lib/tls/tortls.h" 16 #include "lib/crypt_ops/crypto_rand.h" 17 #include "lib/crypt_ops/crypto_util.h" 18 #include "lib/crypt_ops/compat_openssl.h" 19 20 /* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in 21 * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */ 22 DISABLE_GCC_WARNING("-Wredundant-decls") 23 24 #include <openssl/opensslv.h> 25 26 #ifdef OPENSSL_NO_EC 27 #error "We require OpenSSL with ECC support" 28 #endif 29 30 #include <openssl/err.h> 31 #include <openssl/asn1.h> 32 #include <openssl/bio.h> 33 #include <openssl/bn.h> 34 #include <openssl/evp.h> 35 #include <openssl/objects.h> 36 #include <openssl/rsa.h> 37 #include <openssl/x509.h> 38 39 ENABLE_GCC_WARNING("-Wredundant-decls") 40 41 #include "lib/log/log.h" 42 #include "lib/log/util_bug.h" 43 #include "lib/ctime/di_ops.h" 44 #include "lib/encoding/time_fmt.h" 45 46 #include <stdlib.h> 47 #include <string.h> 48 49 #define X509_get_notBefore_const(cert) \ 50 X509_get0_notBefore(cert) 51 #define X509_get_notAfter_const(cert) \ 52 X509_get0_notAfter(cert) 53 #ifndef X509_get_notBefore 54 #define X509_get_notBefore(cert) \ 55 X509_getm_notBefore(cert) 56 #endif 57 #ifndef X509_get_notAfter 58 #define X509_get_notAfter(cert) \ 59 X509_getm_notAfter(cert) 60 #endif 61 62 /** Return a newly allocated X509 name with commonName <b>cname</b>. */ 63 static X509_NAME * 64 tor_x509_name_new(const char *cname) 65 { 66 int nid; 67 X509_NAME *name; 68 /* LCOV_EXCL_BR_START : these branches will only fail on OOM errors */ 69 if (!(name = X509_NAME_new())) 70 return NULL; 71 if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error; 72 if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC, 73 (unsigned char*)cname, -1, -1, 0))) 74 goto error; 75 /* LCOV_EXCL_BR_STOP */ 76 return name; 77 78 /* LCOV_EXCL_START : these lines will only execute on out of memory errors*/ 79 error: 80 X509_NAME_free(name); 81 return NULL; 82 /* LCOV_EXCL_STOP */ 83 } 84 85 /** Generate and sign an X509 certificate with the public key <b>rsa</b>, 86 * signed by the private key <b>rsa_sign</b>. The commonName of the 87 * certificate will be <b>cname</b>; the commonName of the issuer will be 88 * <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b> 89 * seconds, starting from some time in the past. 90 * 91 * Return a certificate on success, NULL on failure. 92 */ 93 MOCK_IMPL(X509 *, 94 tor_tls_create_certificate,(crypto_pk_t *rsa, 95 crypto_pk_t *rsa_sign, 96 const char *cname, 97 const char *cname_sign, 98 unsigned int cert_lifetime)) 99 { 100 /* OpenSSL generates self-signed certificates with random 64-bit serial 101 * numbers, so let's do that too. */ 102 #define SERIAL_NUMBER_SIZE 8 103 104 time_t start_time, end_time; 105 BIGNUM *serial_number = NULL; 106 unsigned char serial_tmp[SERIAL_NUMBER_SIZE]; 107 EVP_PKEY *sign_pkey = NULL, *pkey=NULL; 108 X509 *x509 = NULL; 109 X509_NAME *name = NULL, *name_issuer=NULL; 110 111 tor_tls_init(); 112 113 time_t now = time(NULL); 114 115 tor_tls_pick_certificate_lifetime(now, cert_lifetime, 116 &start_time, &end_time); 117 118 tor_assert(rsa); 119 tor_assert(cname); 120 tor_assert(rsa_sign); 121 tor_assert(cname_sign); 122 if (!(sign_pkey = crypto_pk_get_openssl_evp_pkey_(rsa_sign,1))) 123 goto error; 124 if (!(pkey = crypto_pk_get_openssl_evp_pkey_(rsa,0))) 125 goto error; 126 if (!(x509 = X509_new())) 127 goto error; 128 if (!(X509_set_version(x509, 2))) 129 goto error; 130 131 { /* our serial number is 8 random bytes. */ 132 crypto_rand((char *)serial_tmp, sizeof(serial_tmp)); 133 if (!(serial_number = BN_bin2bn(serial_tmp, sizeof(serial_tmp), NULL))) 134 goto error; 135 if (!(BN_to_ASN1_INTEGER(serial_number, X509_get_serialNumber(x509)))) 136 goto error; 137 } 138 139 if (!(name = tor_x509_name_new(cname))) 140 goto error; 141 if (!(X509_set_subject_name(x509, name))) 142 goto error; 143 if (!(name_issuer = tor_x509_name_new(cname_sign))) 144 goto error; 145 if (!(X509_set_issuer_name(x509, name_issuer))) 146 goto error; 147 148 if (!X509_time_adj(X509_get_notBefore(x509),0,&start_time)) 149 goto error; 150 if (!X509_time_adj(X509_get_notAfter(x509),0,&end_time)) 151 goto error; 152 if (!X509_set_pubkey(x509, pkey)) 153 goto error; 154 155 if (!X509_sign(x509, sign_pkey, EVP_sha256())) 156 goto error; 157 158 goto done; 159 error: 160 if (x509) { 161 X509_free(x509); 162 x509 = NULL; 163 } 164 done: 165 tls_log_errors(NULL, LOG_WARN, LD_NET, "generating certificate"); 166 if (sign_pkey) 167 EVP_PKEY_free(sign_pkey); 168 if (pkey) 169 EVP_PKEY_free(pkey); 170 if (serial_number) 171 BN_clear_free(serial_number); 172 if (name) 173 X509_NAME_free(name); 174 if (name_issuer) 175 X509_NAME_free(name_issuer); 176 return x509; 177 178 #undef SERIAL_NUMBER_SIZE 179 } 180 181 /** Set the 'encoded' and 'encoded_len' fields of "cert" from cert->cert. */ 182 int 183 tor_x509_cert_set_cached_der_encoding(tor_x509_cert_t *cert) 184 { 185 unsigned char *buf = NULL; 186 int length = i2d_X509(cert->cert, &buf); 187 188 if (length <= 0 || buf == NULL) { 189 return -1; 190 } 191 cert->encoded_len = (size_t) length; 192 cert->encoded = tor_malloc(length); 193 memcpy(cert->encoded, buf, length); 194 OPENSSL_free(buf); 195 return 0; 196 } 197 198 void 199 tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert) 200 { 201 if (cert) 202 X509_free(cert); 203 } 204 205 tor_x509_cert_impl_t * 206 tor_x509_cert_impl_dup_(tor_x509_cert_impl_t *cert) 207 { 208 if (cert) 209 return X509_dup(cert); 210 else 211 return NULL; 212 } 213 214 /** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER 215 * representation and length, respectively. */ 216 void 217 tor_x509_cert_get_der(const tor_x509_cert_t *cert, 218 const uint8_t **encoded_out, size_t *size_out) 219 { 220 tor_assert(cert); 221 tor_assert(encoded_out); 222 tor_assert(size_out); 223 *encoded_out = cert->encoded; 224 *size_out = cert->encoded_len; 225 } 226 227 /** Read a DER-encoded X509 cert, of length exactly <b>certificate_len</b>, 228 * from a <b>certificate</b>. Return a newly allocated tor_x509_cert_t on 229 * success and NULL on failure. */ 230 tor_x509_cert_t * 231 tor_x509_cert_decode(const uint8_t *certificate, size_t certificate_len) 232 { 233 X509 *x509; 234 const unsigned char *cp = (const unsigned char *)certificate; 235 tor_x509_cert_t *newcert; 236 tor_assert(certificate); 237 check_no_tls_errors(); 238 239 if (certificate_len > INT_MAX) 240 goto err; 241 242 x509 = d2i_X509(NULL, &cp, (int)certificate_len); 243 244 if (!x509) 245 goto err; /* Couldn't decode */ 246 if (cp - certificate != (int)certificate_len) { 247 X509_free(x509); 248 goto err; /* Didn't use all the bytes */ 249 } 250 newcert = tor_x509_cert_new(x509); 251 if (!newcert) { 252 goto err; 253 } 254 if (newcert->encoded_len != certificate_len || 255 fast_memneq(newcert->encoded, certificate, certificate_len)) { 256 /* Cert wasn't in DER */ 257 tor_x509_cert_free(newcert); 258 goto err; 259 } 260 return newcert; 261 err: 262 tls_log_errors(NULL, LOG_INFO, LD_CRYPTO, "decoding a certificate"); 263 return NULL; 264 } 265 266 /** 267 * Return a newly allocated copy of the public key that a certificate 268 * certifies. Watch out! This returns NULL if the cert's key is not RSA. 269 */ 270 crypto_pk_t * 271 tor_tls_cert_get_key(tor_x509_cert_t *cert) 272 { 273 crypto_pk_t *result = NULL; 274 EVP_PKEY *pkey = X509_get_pubkey(cert->cert); 275 RSA *rsa; 276 if (!pkey) 277 return NULL; 278 rsa = EVP_PKEY_get1_RSA(pkey); 279 if (!rsa) { 280 EVP_PKEY_free(pkey); 281 return NULL; 282 } 283 result = crypto_new_pk_from_openssl_rsa_(rsa); 284 EVP_PKEY_free(pkey); 285 return result; 286 } 287 288 /** Check whether <b>cert</b> is well-formed, currently live, and correctly 289 * signed by the public key in <b>signing_cert</b>. If <b>check_rsa_1024</b>, 290 * make sure that it has an RSA key with 1024 bits; otherwise, just check that 291 * the key is long enough. Return 1 if the cert is good, and 0 if it's bad or 292 * we couldn't check it. */ 293 int 294 tor_tls_cert_is_valid(int severity, 295 const tor_x509_cert_t *cert, 296 const tor_x509_cert_t *signing_cert, 297 time_t now, 298 int check_rsa_1024) 299 { 300 check_no_tls_errors(); 301 EVP_PKEY *cert_key; 302 int r, key_ok = 0; 303 304 if (!signing_cert || !cert) 305 goto bad; 306 307 EVP_PKEY *signing_key = X509_get_pubkey(signing_cert->cert); 308 if (!signing_key) 309 goto bad; 310 r = X509_verify(cert->cert, signing_key); 311 EVP_PKEY_free(signing_key); 312 if (r <= 0) 313 goto bad; 314 315 /* okay, the signature checked out right. Now let's check the check the 316 * lifetime. */ 317 if (tor_x509_check_cert_lifetime_internal(severity, cert->cert, now, 318 TOR_X509_PAST_SLOP, 319 TOR_X509_FUTURE_SLOP) < 0) 320 goto bad; 321 322 cert_key = X509_get_pubkey(cert->cert); 323 if (check_rsa_1024 && cert_key) { 324 RSA *rsa = EVP_PKEY_get1_RSA(cert_key); 325 if (rsa && RSA_bits(rsa) == 1024) { 326 key_ok = 1; 327 } else { 328 log_fn(severity, LD_CRYPTO, "Invalid certificate: Key is not RSA1024."); 329 } 330 331 if (rsa) 332 RSA_free(rsa); 333 } else if (cert_key) { 334 int min_bits = 1024; 335 #ifdef EVP_PKEY_EC 336 if (EVP_PKEY_base_id(cert_key) == EVP_PKEY_EC) 337 min_bits = 128; 338 #endif 339 if (EVP_PKEY_bits(cert_key) >= min_bits) 340 key_ok = 1; 341 } 342 EVP_PKEY_free(cert_key); 343 if (!key_ok) 344 goto bad; 345 346 /* XXXX compare DNs or anything? */ 347 348 return 1; 349 bad: 350 tls_log_errors(NULL, LOG_INFO, LD_CRYPTO, "checking a certificate"); 351 return 0; 352 } 353 354 /** Warn that a certificate lifetime extends through a certain range. */ 355 static void 356 log_cert_lifetime(int severity, const X509 *cert, const char *problem, 357 time_t now) 358 { 359 BIO *bio = NULL; 360 BUF_MEM *buf; 361 char *s1=NULL, *s2=NULL; 362 char mytime[33]; 363 struct tm tm; 364 size_t n; 365 366 if (problem) 367 tor_log(severity, LD_GENERAL, 368 "Certificate %s. Either their clock is set wrong, or your clock " 369 "is wrong.", 370 problem); 371 372 if (!(bio = BIO_new(BIO_s_mem()))) { 373 log_warn(LD_GENERAL, "Couldn't allocate BIO!"); goto end; 374 } 375 if (!(ASN1_TIME_print(bio, X509_get_notBefore_const(cert)))) { 376 tls_log_errors(NULL, LOG_WARN, LD_NET, "printing certificate lifetime"); 377 goto end; 378 } 379 BIO_get_mem_ptr(bio, &buf); 380 s1 = tor_strndup(buf->data, buf->length); 381 382 (void)BIO_reset(bio); 383 if (!(ASN1_TIME_print(bio, X509_get_notAfter_const(cert)))) { 384 tls_log_errors(NULL, LOG_WARN, LD_NET, "printing certificate lifetime"); 385 goto end; 386 } 387 BIO_get_mem_ptr(bio, &buf); 388 s2 = tor_strndup(buf->data, buf->length); 389 390 n = strftime(mytime, 32, "%b %d %H:%M:%S %Y UTC", tor_gmtime_r(&now, &tm)); 391 if (n > 0) { 392 tor_log(severity, LD_GENERAL, 393 "(certificate lifetime runs from %s through %s. Your time is %s.)", 394 s1,s2,mytime); 395 } else { 396 tor_log(severity, LD_GENERAL, 397 "(certificate lifetime runs from %s through %s. " 398 "Couldn't get your time.)", 399 s1, s2); 400 } 401 402 end: 403 /* Not expected to get invoked */ 404 tls_log_errors(NULL, LOG_WARN, LD_NET, "getting certificate lifetime"); 405 if (bio) 406 BIO_free(bio); 407 tor_free(s1); 408 tor_free(s2); 409 } 410 411 /** Helper: check whether <b>cert</b> is expired give or take 412 * <b>past_tolerance</b> seconds, or not-yet-valid give or take 413 * <b>future_tolerance</b> seconds. (Relative to the current time 414 * <b>now</b>.) If it is live, return 0. If it is not live, log a message 415 * and return -1. */ 416 int 417 tor_x509_check_cert_lifetime_internal(int severity, const X509 *cert, 418 time_t now, 419 int past_tolerance, int future_tolerance) 420 { 421 time_t t; 422 423 t = now + future_tolerance; 424 if (X509_cmp_time(X509_get_notBefore_const(cert), &t) > 0) { 425 log_cert_lifetime(severity, cert, "not yet valid", now); 426 return -1; 427 } 428 t = now - past_tolerance; 429 if (X509_cmp_time(X509_get_notAfter_const(cert), &t) < 0) { 430 log_cert_lifetime(severity, cert, "already expired", now); 431 return -1; 432 } 433 434 return 0; 435 } 436 437 #ifdef TOR_UNIT_TESTS 438 /* Testing only: return a new x509 cert with the same contents as <b>inp</b>, 439 but with the expiration time <b>new_expiration_time</b>, signed with 440 <b>signing_key</b>. */ 441 STATIC tor_x509_cert_t * 442 tor_x509_cert_replace_expiration(const tor_x509_cert_t *inp, 443 time_t new_expiration_time, 444 crypto_pk_t *signing_key) 445 { 446 X509 *newc = X509_dup(inp->cert); 447 X509_time_adj(X509_get_notAfter(newc), 0, &new_expiration_time); 448 EVP_PKEY *pk = crypto_pk_get_openssl_evp_pkey_(signing_key, 1); 449 tor_assert(X509_sign(newc, pk, EVP_sha256())); 450 EVP_PKEY_free(pk); 451 return tor_x509_cert_new(newc); 452 } 453 #endif /* defined(TOR_UNIT_TESTS) */