x509_nss.c (13865B)
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_nss.c 8 * \brief Wrapper functions to present a consistent interface to 9 * X.509 functions from NSS. 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/crypto_nss_mgt.h" 19 #include "lib/log/util_bug.h" 20 #include "lib/encoding/time_fmt.h" 21 #include "lib/string/printf.h" 22 23 DISABLE_GCC_WARNING("-Wstrict-prototypes") 24 #include <pk11pub.h> 25 #include <cryptohi.h> 26 #include <cert.h> 27 #include <keyhi.h> 28 #include <time.h> 29 ENABLE_GCC_WARNING("-Wstrict-prototypes") 30 31 /* Units of PRTime per second. 32 * 33 * (PRTime is based in microseconds since the Unix 34 * epoch.) */ 35 #define PRTIME_PER_SEC (1000*1000) 36 37 static tor_x509_cert_impl_t *tor_x509_cert_decode_internal( 38 const uint8_t *certificate, int certificate_len); 39 40 static tor_x509_cert_impl_t * 41 tor_tls_create_certificate_internal(crypto_pk_t *rsa, 42 crypto_pk_t *rsa_sign, 43 CERTName *subject_dn, 44 CERTName *issuer_dn, 45 time_t start_time, 46 time_t end_time) 47 { 48 if (! crypto_pk_key_is_private(rsa_sign)) { 49 return NULL; 50 } 51 52 const SECKEYPublicKey *subject_key = crypto_pk_get_nss_pubkey(rsa); 53 const SECKEYPrivateKey *signing_key = crypto_pk_get_nss_privkey(rsa_sign); 54 SECStatus s; 55 56 CERTSubjectPublicKeyInfo *subject_spki = NULL; 57 CERTCertificateRequest *request = NULL; 58 CERTValidity *validity = NULL; 59 CERTCertificate *cert = NULL; 60 SECItem der = { .data = NULL, .len = 0 }; 61 SECItem signed_der = { .data = NULL, .len = 0 }; 62 63 CERTCertificate *result_cert = NULL; 64 65 validity = CERT_CreateValidity(((PRTime)start_time) * PRTIME_PER_SEC, 66 ((PRTime)end_time) * PRTIME_PER_SEC); 67 if (BUG(! validity)) { 68 /* LCOV_EXCL_START */ 69 crypto_nss_log_errors(LOG_WARN, "creating a validity object"); 70 goto err; 71 /* LCOV_EXCL_STOP */ 72 } 73 74 unsigned long serial_number; 75 crypto_rand((char*)&serial_number, sizeof(serial_number)); 76 77 subject_spki = SECKEY_CreateSubjectPublicKeyInfo(subject_key); 78 if (!subject_spki) 79 goto err; 80 81 /* Make a CSR ... */ 82 // XXX do we need to set any attributes? 83 request = CERT_CreateCertificateRequest(subject_dn, 84 subject_spki, 85 NULL /* attributes */); 86 if (!request) 87 goto err; 88 89 /* Put it into a certificate ... */ 90 cert = CERT_CreateCertificate(serial_number, 91 issuer_dn, 92 validity, 93 request); 94 if (!cert) 95 goto err; 96 97 /* version 3 cert */ 98 *cert->version.data = 2; /* 2 means version 3. */ 99 cert->version.len = 1; 100 101 // XXX do we need to set anything else on the cert? 102 103 /* Sign it. */ 104 KeyType privkey_type = SECKEY_GetPrivateKeyType(signing_key); 105 SECOidTag oid_tag = SEC_GetSignatureAlgorithmOidTag(privkey_type, 106 SEC_OID_SHA256); 107 if (oid_tag == SEC_OID_UNKNOWN) 108 goto err; 109 s = SECOID_SetAlgorithmID(cert->arena, &cert->signature, oid_tag, NULL); 110 if (s != SECSuccess) 111 goto err; 112 113 void *tmp; 114 tmp = SEC_ASN1EncodeItem(cert->arena, &der, cert, 115 SEC_ASN1_GET(CERT_CertificateTemplate)); 116 if (!tmp) 117 goto err; 118 119 #if 0 120 s = SEC_DerSignDataWithAlgorithmID(cert->arena, 121 &signed_der, 122 der.data, der.len, 123 (SECKEYPrivateKey *)signing_key,//const 124 &cert->signature); 125 #else /* !(0) */ 126 s = SEC_DerSignData(cert->arena, 127 &signed_der, 128 der.data, der.len, 129 (SECKEYPrivateKey *)signing_key,//const 130 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION); 131 #endif /* 0 */ 132 133 if (s != SECSuccess) 134 goto err; 135 136 /* Re-parse it, to make sure all the certificates we actually use 137 * appear via being decoded. */ 138 result_cert = tor_x509_cert_decode_internal(signed_der.data, signed_der.len); 139 140 #if 1 141 { 142 // Can we check the cert we just signed? 143 tor_assert(result_cert); 144 SECKEYPublicKey *issuer_pk = (SECKEYPublicKey *) 145 crypto_pk_get_nss_pubkey(rsa_sign); 146 SECStatus cert_ok = CERT_VerifySignedDataWithPublicKey( 147 &result_cert->signatureWrap, issuer_pk, NULL); 148 tor_assert(cert_ok == SECSuccess); 149 } 150 #endif /* 1 */ 151 152 err: 153 if (subject_spki) 154 SECKEY_DestroySubjectPublicKeyInfo(subject_spki); 155 if (request) 156 CERT_DestroyCertificateRequest(request); 157 if (validity) 158 CERT_DestroyValidity(validity); 159 160 // unnecessary, since these are allocated in the cert's arena. 161 //SECITEM_FreeItem(&der, PR_FALSE); 162 //SECITEM_FreeItem(&signed_der, PR_FALSE); 163 if (cert) 164 CERT_DestroyCertificate(cert); 165 166 return result_cert; 167 } 168 169 MOCK_IMPL(tor_x509_cert_impl_t *, 170 tor_tls_create_certificate,(crypto_pk_t *rsa, 171 crypto_pk_t *rsa_sign, 172 const char *cname, 173 const char *cname_sign, 174 unsigned int cert_lifetime)) 175 { 176 tor_assert(rsa); 177 tor_assert(rsa_sign); 178 tor_assert(cname); 179 tor_assert(cname_sign); 180 181 char *cname_rfc_1485 = NULL, *cname_sign_rfc_1485 = NULL; 182 CERTName *subject_dn = NULL, *issuer_dn = NULL; 183 time_t start_time; 184 time_t end_time; 185 CERTCertificate *result = NULL; 186 187 tor_asprintf(&cname_rfc_1485, "CN=%s", cname); 188 tor_asprintf(&cname_sign_rfc_1485, "CN=%s", cname_sign); 189 190 subject_dn = CERT_AsciiToName(cname_rfc_1485); 191 issuer_dn = CERT_AsciiToName(cname_sign_rfc_1485); 192 if (!subject_dn || !issuer_dn) 193 goto err; 194 195 tor_tls_pick_certificate_lifetime(time(NULL), cert_lifetime, 196 &start_time, &end_time); 197 198 result = tor_tls_create_certificate_internal(rsa, 199 rsa_sign, 200 subject_dn, 201 issuer_dn, 202 start_time, 203 end_time); 204 err: 205 tor_free(cname_rfc_1485); 206 tor_free(cname_sign_rfc_1485); 207 if (subject_dn) 208 CERT_DestroyName(subject_dn); 209 if (issuer_dn) 210 CERT_DestroyName(issuer_dn); 211 212 return result; 213 } 214 215 /** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER 216 * representation and length, respectively. */ 217 void 218 tor_x509_cert_get_der(const tor_x509_cert_t *cert, 219 const uint8_t **encoded_out, size_t *size_out) 220 { 221 tor_assert(cert); 222 tor_assert(cert->cert); 223 tor_assert(encoded_out); 224 tor_assert(size_out); 225 226 const SECItem *item = &cert->cert->derCert; 227 *encoded_out = item->data; 228 *size_out = (size_t)item->len; 229 } 230 231 void 232 tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert) 233 { 234 if (cert) 235 CERT_DestroyCertificate(cert); 236 } 237 238 tor_x509_cert_impl_t * 239 tor_x509_cert_impl_dup_(tor_x509_cert_impl_t *cert) 240 { 241 if (cert) 242 return CERT_DupCertificate(cert); 243 else 244 return NULL; 245 } 246 247 /** 248 * As tor_x509_cert_decode, but return the NSS certificate type 249 */ 250 static tor_x509_cert_impl_t * 251 tor_x509_cert_decode_internal(const uint8_t *certificate, 252 int certificate_len) 253 { 254 tor_assert(certificate); 255 if (certificate_len > INT_MAX) 256 return NULL; 257 258 SECItem der = { .type = siBuffer, 259 .data = (unsigned char *)certificate, 260 .len = certificate_len }; 261 CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); 262 tor_assert(certdb); 263 return CERT_NewTempCertificate(certdb, 264 &der, 265 NULL /* nickname */, 266 PR_FALSE, /* isPerm */ 267 PR_TRUE /* CopyDER */); 268 } 269 270 tor_x509_cert_t * 271 tor_x509_cert_decode(const uint8_t *certificate, 272 size_t certificate_len) 273 { 274 CERTCertificate *cert = tor_x509_cert_decode_internal(certificate, 275 (int)certificate_len); 276 if (! cert) { 277 crypto_nss_log_errors(LOG_INFO, "decoding certificate"); 278 return NULL; 279 } 280 281 tor_x509_cert_t *newcert = tor_x509_cert_new(cert); 282 283 return newcert; 284 } 285 286 crypto_pk_t * 287 tor_tls_cert_get_key(tor_x509_cert_t *cert) 288 { 289 tor_assert(cert); 290 CERTSubjectPublicKeyInfo *spki = &cert->cert->subjectPublicKeyInfo; 291 SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(spki); // we own this pointer 292 if (pub == NULL) 293 return NULL; 294 295 if (SECKEY_GetPublicKeyType(pub) != rsaKey) { 296 SECKEY_DestroyPublicKey(pub); 297 return NULL; 298 } 299 300 return crypto_pk_new_from_nss_pubkey(pub); 301 } 302 303 int 304 tor_tls_cert_is_valid(int severity, 305 const tor_x509_cert_t *cert, 306 const tor_x509_cert_t *signing_cert, 307 time_t now, 308 int check_rsa_1024) 309 { 310 int result = 0; 311 312 tor_assert(cert); 313 tor_assert(signing_cert); 314 315 SECKEYPublicKey *pk = CERT_ExtractPublicKey(signing_cert->cert); 316 if (pk == NULL) { 317 log_fn(severity, LD_CRYPTO, 318 "Invalid certificate: could not extract issuer key"); 319 goto fail; 320 } 321 322 SECStatus s = CERT_VerifySignedDataWithPublicKey(&cert->cert->signatureWrap, 323 pk, NULL); 324 if (s != SECSuccess) { 325 log_fn(severity, LD_CRYPTO, 326 "Invalid certificate: could not validate signature."); 327 goto fail; 328 } 329 330 if (tor_x509_check_cert_lifetime_internal(severity, 331 cert->cert, 332 now, 333 TOR_X509_PAST_SLOP, 334 TOR_X509_FUTURE_SLOP) < 0) 335 goto fail; 336 337 if (check_rsa_1024) { 338 /* We require that this is a 1024-bit RSA key, for legacy reasons .:p */ 339 if (SECKEY_GetPublicKeyType(pk) != rsaKey || 340 SECKEY_PublicKeyStrengthInBits(pk) != 1024) { 341 log_fn(severity, LD_CRYPTO, "Invalid certificate: Key is not RSA1024."); 342 goto fail; 343 } 344 } else { 345 /* We require that this key is at least minimally strong. */ 346 unsigned min_bits = (SECKEY_GetPublicKeyType(pk) == ecKey) ? 128: 1024; 347 if (SECKEY_PublicKeyStrengthInBits(pk) < min_bits) { 348 log_fn(severity, LD_CRYPTO, "Invalid certificate: Key is too weak."); 349 goto fail; 350 } 351 } 352 353 /* The certificate is valid. */ 354 result = 1; 355 356 fail: 357 if (pk) 358 SECKEY_DestroyPublicKey(pk); 359 return result; 360 } 361 362 static void 363 log_cert_lifetime(int severity, 364 const char *status, 365 time_t now, 366 PRTime notBefore, 367 PRTime notAfter) 368 { 369 log_fn(severity, LD_GENERAL, 370 "Certificate %s. Either their clock is set wrong, or your clock " 371 "is incorrect.", status); 372 373 char nowbuf[ISO_TIME_LEN+1]; 374 char nbbuf[ISO_TIME_LEN+1]; 375 char nabuf[ISO_TIME_LEN+1]; 376 377 format_iso_time(nowbuf, now); 378 format_iso_time(nbbuf, notBefore / PRTIME_PER_SEC); 379 format_iso_time(nabuf, notAfter / PRTIME_PER_SEC); 380 381 log_fn(severity, LD_GENERAL, 382 "(The certificate is valid from %s until %s. Your time is %s.)", 383 nbbuf, nabuf, nowbuf); 384 } 385 386 int 387 tor_x509_check_cert_lifetime_internal(int severity, 388 const tor_x509_cert_impl_t *cert, 389 time_t now, 390 int past_tolerance, 391 int future_tolerance) 392 { 393 tor_assert(cert); 394 395 PRTime notBefore=0, notAfter=0; 396 int64_t t; 397 SECStatus r = CERT_GetCertTimes(cert, ¬Before, ¬After); 398 if (r != SECSuccess) { 399 log_fn(severity, LD_CRYPTO, 400 "Couldn't get validity times from certificate"); 401 return -1; 402 } 403 404 t = ((int64_t)now) + future_tolerance; 405 t *= PRTIME_PER_SEC; 406 if (notBefore > t) { 407 log_cert_lifetime(severity, "not yet valid", now, 408 notBefore, notAfter); 409 return -1; 410 } 411 412 t = ((int64_t)now) - past_tolerance; 413 t *= PRTIME_PER_SEC; 414 if (notAfter < t) { 415 log_cert_lifetime(severity, "already expired", now, 416 notBefore, notAfter); 417 return -1; 418 } 419 420 return 0; 421 } 422 423 #ifdef TOR_UNIT_TESTS 424 tor_x509_cert_t * 425 tor_x509_cert_replace_expiration(const tor_x509_cert_t *inp, 426 time_t new_expiration_time, 427 crypto_pk_t *signing_key) 428 { 429 tor_assert(inp); 430 tor_assert(signing_key); 431 432 PRTime notBefore=0, notAfter=0; 433 SECStatus r = CERT_GetCertTimes(inp->cert, ¬Before, ¬After); 434 if (r != SECSuccess) 435 return NULL; 436 437 time_t start_time = notBefore / PRTIME_PER_SEC; 438 if (new_expiration_time < start_time) { 439 /* This prevents an NSS error. */ 440 start_time = new_expiration_time - 10; 441 } 442 443 crypto_pk_t *subject_key = tor_tls_cert_get_key((tor_x509_cert_t *)inp); 444 if (!subject_key) 445 return NULL; 446 447 CERTCertificate *newcert; 448 449 newcert = tor_tls_create_certificate_internal(subject_key, 450 signing_key, 451 &inp->cert->subject, 452 &inp->cert->issuer, 453 start_time, 454 new_expiration_time); 455 456 crypto_pk_free(subject_key); 457 458 return newcert ? tor_x509_cert_new(newcert) : NULL; 459 } 460 #endif /* defined(TOR_UNIT_TESTS) */