| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -147,7 +147,12 @@ DataPointer DataPointer::SecureAlloc(size_t len) { | |||
| 147 | 147 | #ifndef OPENSSL_IS_BORINGSSL | |
| 148 | 148 | auto ptr = OPENSSL_secure_zalloc(len); | |
| 149 | 149 | if (ptr == nullptr) return {}; | |
| 150 | - return DataPointer(ptr, len, true); | ||
| 150 | + // OPENSSL_secure_zalloc transparently falls back to a regular allocation | ||
| 151 | + // when the secure heap is not initialized or is exhausted. Reflect the | ||
| 152 | + // actual provenance of the pointer so that reset() routes to the correct | ||
| 153 | + // free function (OPENSSL_secure_clear_free vs. OPENSSL_clear_free) and | ||
| 154 | + // callers of isSecure() get a truthful answer. | ||
| 155 | + return DataPointer(ptr, len, CRYPTO_secure_allocated(ptr) == 1); | ||
| 151 | 156 | #else | |
| 152 | 157 | // BoringSSL does not implement the OPENSSL_secure_zalloc API. | |
| 153 | 158 | auto ptr = OPENSSL_malloc(len); | |
@@ -3103,9 +3108,13 @@ const Cipher Cipher::AES_256_GCM = Cipher::FromNid(NID_aes_256_gcm); | |||
| 3103 | 3108 | const Cipher Cipher::AES_128_KW = Cipher::FromNid(NID_id_aes128_wrap); | |
| 3104 | 3109 | const Cipher Cipher::AES_192_KW = Cipher::FromNid(NID_id_aes192_wrap); | |
| 3105 | 3110 | const Cipher Cipher::AES_256_KW = Cipher::FromNid(NID_id_aes256_wrap); | |
| 3111 | + | ||
| 3112 | + #ifndef OPENSSL_IS_BORINGSSL | ||
| 3106 | 3113 | const Cipher Cipher::AES_128_OCB = Cipher::FromNid(NID_aes_128_ocb); | |
| 3107 | 3114 | const Cipher Cipher::AES_192_OCB = Cipher::FromNid(NID_aes_192_ocb); | |
| 3108 | 3115 | const Cipher Cipher::AES_256_OCB = Cipher::FromNid(NID_aes_256_ocb); | |
| 3116 | + #endif | ||
| 3117 | + | ||
| 3109 | 3118 | const Cipher Cipher::CHACHA20_POLY1305 = Cipher::FromNid(NID_chacha20_poly1305); | |
| 3110 | 3119 | ||
| 3111 | 3120 | bool Cipher::isGcmMode() const { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -309,9 +309,12 @@ class Cipher final { | |||
| 309 | 309 | #else | |
| 310 | 310 | static constexpr size_t MAX_AUTH_TAG_LENGTH = 16; | |
| 311 | 311 | #endif | |
| 312 | - static_assert(EVP_GCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH && | ||
| 313 | - EVP_CCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH && | ||
| 314 | - EVP_CHACHAPOLY_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH); | ||
| 312 | + static_assert(EVP_GCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH | ||
| 313 | + #ifndef OPENSSL_IS_BORINGSSL | ||
| 314 | + && EVP_CCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH && | ||
| 315 | + EVP_CHACHAPOLY_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH | ||
| 316 | + #endif | ||
| 317 | + ); // NOLINT(whitespace/parens) | ||
| 315 | 318 | ||
| 316 | 319 | Cipher() = default; | |
| 317 | 320 | Cipher(const EVP_CIPHER* cipher) : cipher_(cipher) {} | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -432,61 +432,46 @@ bool CipherBase::InitAuthenticated(const char* cipher_type, | |||
| 432 | 432 | return false; | |
| 433 | 433 | } | |
| 434 | 434 | ||
| 435 | - if (ctx_.isGcmMode()) { | ||
| 436 | - if (auth_tag_len != kNoAuthTagLength) { | ||
| 437 | - if (!Cipher::IsValidGCMTagLength(auth_tag_len)) { | ||
| 438 | - THROW_ERR_CRYPTO_INVALID_AUTH_TAG( | ||
| 439 | - env(), | ||
| 440 | - "Invalid authentication tag length: %u", | ||
| 441 | - auth_tag_len); | ||
| 442 | - return false; | ||
| 443 | - } | ||
| 444 | - | ||
| 445 | - // Remember the given authentication tag length for later. | ||
| 446 | - auth_tag_len_ = auth_tag_len; | ||
| 447 | - } | ||
| 448 | - } else { | ||
| 449 | - if (auth_tag_len == kNoAuthTagLength) { | ||
| 450 | - // We treat ChaCha20-Poly1305 specially. Like GCM, the authentication tag | ||
| 451 | - // length defaults to 16 bytes when encrypting. Unlike GCM, the | ||
| 452 | - // authentication tag length also defaults to 16 bytes when decrypting, | ||
| 453 | - // whereas GCM would accept any valid authentication tag length. | ||
| 454 | - if (ctx_.isChaCha20Poly1305()) { | ||
| 455 | - auth_tag_len = EVP_CHACHAPOLY_TLS_TAG_LEN; | ||
| 456 | - } else { | ||
| 457 | - THROW_ERR_CRYPTO_INVALID_AUTH_TAG( | ||
| 458 | - env(), "authTagLength required for %s", cipher_type); | ||
| 459 | - return false; | ||
| 460 | - } | ||
| 461 | - } | ||
| 462 | - | ||
| 435 | + if (ctx_.isCcmMode()) { | ||
| 463 | 436 | // TODO(tniessen) Support CCM decryption in FIPS mode | |
| 464 | - | ||
| 465 | - if (ctx_.isCcmMode() && kind_ == kDecipher && ncrypto::isFipsEnabled()) { | ||
| 466 | - THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(), | ||
| 467 | - "CCM encryption not supported in FIPS mode"); | ||
| 437 | + if (kind_ == kDecipher && ncrypto::isFipsEnabled()) { | ||
| 438 | + THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION( | ||
| 439 | + env(), "CCM encryption not supported in FIPS mode"); | ||
| 468 | 440 | return false; | |
| 469 | 441 | } | |
| 470 | 442 | ||
| 471 | - // Tell OpenSSL about the desired length. | ||
| 472 | - if (!ctx_.setAeadTagLength(auth_tag_len)) { | ||
| 443 | + // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes. | ||
| 444 | + CHECK(iv_len >= 7 && iv_len <= 13); | ||
| 445 | + max_message_size_ = INT_MAX; | ||
| 446 | + if (iv_len == 12) max_message_size_ = 16777215; | ||
| 447 | + if (iv_len == 13) max_message_size_ = 65535; | ||
| 448 | + } | ||
| 449 | + | ||
| 450 | + if (auth_tag_len == kNoAuthTagLength) { | ||
| 451 | + // GCM accepts any valid authentication tag length when decrypting without | ||
| 452 | + // an explicit authTagLength. This remains deprecated, but supported. | ||
| 453 | + if (ctx_.isGcmMode()) { | ||
| 454 | + return true; | ||
| 455 | + #ifdef EVP_CHACHAPOLY_TLS_TAG_LEN | ||
| 456 | + } else if (ctx_.isChaCha20Poly1305()) { | ||
| 457 | + auth_tag_len = EVP_CHACHAPOLY_TLS_TAG_LEN; | ||
| 458 | + #endif | ||
| 459 | + } else { | ||
| 473 | 460 | THROW_ERR_CRYPTO_INVALID_AUTH_TAG( | |
| 474 | - env(), "Invalid authentication tag length: %u", auth_tag_len); | ||
| 461 | + env(), "authTagLength required for %s", cipher_type); | ||
| 475 | 462 | return false; | |
| 476 | 463 | } | |
| 477 | - | ||
| 478 | - // Remember the given authentication tag length for later. | ||
| 479 | - auth_tag_len_ = auth_tag_len; | ||
| 480 | - | ||
| 481 | - if (ctx_.isCcmMode()) { | ||
| 482 | - // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes. | ||
| 483 | - CHECK(iv_len >= 7 && iv_len <= 13); | ||
| 484 | - max_message_size_ = INT_MAX; | ||
| 485 | - if (iv_len == 12) max_message_size_ = 16777215; | ||
| 486 | - if (iv_len == 13) max_message_size_ = 65535; | ||
| 487 | - } | ||
| 464 | + } else if ((ctx_.isGcmMode() && !Cipher::IsValidGCMTagLength(auth_tag_len)) || | ||
| 465 | + (!ctx_.isGcmMode() && !ctx_.setAeadTagLength(auth_tag_len))) { | ||
| 466 | + // GCM authentication tag lengths are restricted according to NIST 800-38d, | ||
| 467 | + // page 9. For other modes, we rely on OpenSSL to validate the length. | ||
| 468 | + THROW_ERR_CRYPTO_INVALID_AUTH_TAG( | ||
| 469 | + env(), "Invalid authentication tag length: %u", auth_tag_len); | ||
| 470 | + return false; | ||
| 488 | 471 | } | |
| 489 | 472 | ||
| 473 | + // Remember the given authentication tag length for later. | ||
| 474 | + auth_tag_len_ = auth_tag_len; | ||
| 490 | 475 | return true; | |
| 491 | 476 | } | |
| 492 | 477 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1915,8 +1915,13 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) { | |||
| 1915 | 1915 | // true to this function instead of the original string. Any other string | |
| 1916 | 1916 | // value will be interpreted as custom DH parameters below. | |
| 1917 | 1917 | if (args[0]->IsTrue()) { | |
| 1918 | + #ifdef SSL_CTX_set_dh_auto | ||
| 1918 | 1919 | CHECK(SSL_CTX_set_dh_auto(sc->ctx_.get(), true)); | |
| 1919 | 1920 | return; | |
| 1921 | + #else | ||
| 1922 | + return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION( | ||
| 1923 | + env, "Automatic DH parameter selection is not supported"); | ||
| 1924 | + #endif | ||
| 1920 | 1925 | } | |
| 1921 | 1926 | ||
| 1922 | 1927 | DHPointer dh; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -309,15 +309,17 @@ void ComputeSecret(const FunctionCallbackInfo<Value>& args) { | |||
| 309 | 309 | BignumPointer key(key_buf.data(), key_buf.size()); | |
| 310 | 310 | ||
| 311 | 311 | switch (dh.checkPublicKey(key)) { | |
| 312 | - case DHPointer::CheckPublicKeyResult::INVALID: | ||
| 313 | - // Fall-through | ||
| 314 | 312 | case DHPointer::CheckPublicKeyResult::CHECK_FAILED: | |
| 315 | 313 | return THROW_ERR_CRYPTO_INVALID_KEYTYPE(env, | |
| 316 | 314 | "Unspecified validation error"); | |
| 315 | + #ifndef OPENSSL_IS_BORINGSSL | ||
| 317 | 316 | case DHPointer::CheckPublicKeyResult::TOO_SMALL: | |
| 318 | 317 | return THROW_ERR_CRYPTO_INVALID_KEYLEN(env, "Supplied key is too small"); | |
| 319 | 318 | case DHPointer::CheckPublicKeyResult::TOO_LARGE: | |
| 320 | 319 | return THROW_ERR_CRYPTO_INVALID_KEYLEN(env, "Supplied key is too large"); | |
| 320 | + #endif | ||
| 321 | + case DHPointer::CheckPublicKeyResult::INVALID: | ||
| 322 | + return THROW_ERR_CRYPTO_INVALID_KEYTYPE(env, "Supplied key is invalid"); | ||
| 321 | 323 | case DHPointer::CheckPublicKeyResult::NONE: | |
| 322 | 324 | break; | |
| 323 | 325 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -135,6 +135,18 @@ Maybe<void> RsaKeyGenTraits::AdditionalConfig( | |||
| 135 | 135 | params->params.modulus_bits = args[*offset + 1].As<Uint32>()->Value(); | |
| 136 | 136 | params->params.exponent = args[*offset + 2].As<Uint32>()->Value(); | |
| 137 | 137 | ||
| 138 | + #ifdef OPENSSL_IS_BORINGSSL | ||
| 139 | + // BoringSSL hangs indefinitely generating an RSA key with e=1, and for | ||
| 140 | + // other invalid exponents (e=0, even values) reports the misleading error | ||
| 141 | + // RSA_R_TOO_MANY_ITERATIONS only after running the full keygen loop. Reject | ||
| 142 | + // those up-front with a clear error. The constraint here (odd integer >= 3) | ||
| 143 | + // matches BoringSSL's own rsa_check_public_key validation. | ||
| 144 | + if (params->params.exponent < 3 || (params->params.exponent & 1) == 0) { | ||
| 145 | + THROW_ERR_OUT_OF_RANGE(env, "publicExponent is invalid"); | ||
| 146 | + return Nothing<void>(); | ||
| 147 | + } | ||
| 148 | + #endif | ||
| 149 | + | ||
| 138 | 150 | *offset += 3; | |
| 139 | 151 | ||
| 140 | 152 | if (params->params.variant == kKeyVariantRSA_PSS) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -514,44 +514,51 @@ Maybe<void> Decorate(Environment* env, | |||
| 514 | 514 | c = ToUpper(c); | |
| 515 | 515 | } | |
| 516 | 516 | ||
| 517 | - #define OSSL_ERROR_CODES_MAP(V) \ | ||
| 518 | - V(SYS) \ | ||
| 519 | - V(BN) \ | ||
| 520 | - V(RSA) \ | ||
| 521 | - V(DH) \ | ||
| 522 | - V(EVP) \ | ||
| 523 | - V(BUF) \ | ||
| 524 | - V(OBJ) \ | ||
| 525 | - V(PEM) \ | ||
| 526 | - V(DSA) \ | ||
| 527 | - V(X509) \ | ||
| 528 | - V(ASN1) \ | ||
| 529 | - V(CONF) \ | ||
| 530 | - V(CRYPTO) \ | ||
| 531 | - V(EC) \ | ||
| 532 | - V(SSL) \ | ||
| 533 | - V(BIO) \ | ||
| 534 | - V(PKCS7) \ | ||
| 535 | - V(X509V3) \ | ||
| 536 | - V(PKCS12) \ | ||
| 537 | - V(RAND) \ | ||
| 538 | - V(DSO) \ | ||
| 539 | - V(ENGINE) \ | ||
| 540 | - V(OCSP) \ | ||
| 541 | - V(UI) \ | ||
| 542 | - V(COMP) \ | ||
| 543 | - V(ECDSA) \ | ||
| 544 | - V(ECDH) \ | ||
| 545 | - V(OSSL_STORE) \ | ||
| 546 | - V(FIPS) \ | ||
| 547 | - V(CMS) \ | ||
| 548 | - V(TS) \ | ||
| 549 | - V(HMAC) \ | ||
| 550 | - V(CT) \ | ||
| 551 | - V(ASYNC) \ | ||
| 552 | - V(KDF) \ | ||
| 553 | - V(SM2) \ | ||
| 554 | - V(USER) \ | ||
| 517 | + #ifdef OPENSSL_IS_BORINGSSL | ||
| 518 | + #define OSSL_ERROR_CODES_MAP_OPENSSL_ONLY(V) | ||
| 519 | + #else | ||
| 520 | + #define OSSL_ERROR_CODES_MAP_OPENSSL_ONLY(V) \ | ||
| 521 | + V(PKCS12) \ | ||
| 522 | + V(DSO) \ | ||
| 523 | + V(OSSL_STORE) \ | ||
| 524 | + V(FIPS) \ | ||
| 525 | + V(TS) \ | ||
| 526 | + V(CT) \ | ||
| 527 | + V(ASYNC) \ | ||
| 528 | + V(KDF) \ | ||
| 529 | + V(SM2) | ||
| 530 | + #endif | ||
| 531 | + | ||
| 532 | + #define OSSL_ERROR_CODES_MAP(V) \ | ||
| 533 | + V(SYS) \ | ||
| 534 | + V(BN) \ | ||
| 535 | + V(RSA) \ | ||
| 536 | + V(DH) \ | ||
| 537 | + V(EVP) \ | ||
| 538 | + V(BUF) \ | ||
| 539 | + V(OBJ) \ | ||
| 540 | + V(PEM) \ | ||
| 541 | + V(DSA) \ | ||
| 542 | + V(X509) \ | ||
| 543 | + V(ASN1) \ | ||
| 544 | + V(CONF) \ | ||
| 545 | + V(CRYPTO) \ | ||
| 546 | + V(EC) \ | ||
| 547 | + V(SSL) \ | ||
| 548 | + V(BIO) \ | ||
| 549 | + V(PKCS7) \ | ||
| 550 | + V(X509V3) \ | ||
| 551 | + V(RAND) \ | ||
| 552 | + V(ENGINE) \ | ||
| 553 | + V(OCSP) \ | ||
| 554 | + V(UI) \ | ||
| 555 | + V(COMP) \ | ||
| 556 | + V(ECDSA) \ | ||
| 557 | + V(ECDH) \ | ||
| 558 | + V(CMS) \ | ||
| 559 | + V(HMAC) \ | ||
| 560 | + V(USER) \ | ||
| 561 | + OSSL_ERROR_CODES_MAP_OPENSSL_ONLY(V) | ||
| 555 | 562 | ||
| 556 | 563 | #define V(name) case ERR_LIB_##name: lib = #name "_"; break; | |
| 557 | 564 | const char* lib = ""; | |
@@ -561,6 +568,7 @@ Maybe<void> Decorate(Environment* env, | |||
| 561 | 568 | } | |
| 562 | 569 | #undef V | |
| 563 | 570 | #undef OSSL_ERROR_CODES_MAP | |
| 571 | + #undef OSSL_ERROR_CODES_MAP_OPENSSL_ONLY | ||
| 564 | 572 | // Don't generate codes like "ERR_OSSL_SSL_". | |
| 565 | 573 | if (lib && strcmp(lib, "SSL_") == 0) | |
| 566 | 574 | prefix = ""; | |
@@ -689,7 +697,6 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) { | |||
| 689 | 697 | uint32_t len = args[0].As<Uint32>()->Value(); | |
| 690 | 698 | ||
| 691 | 699 | auto data = DataPointer::SecureAlloc(len); | |
| 692 | - CHECK(data.isSecure()); | ||
| 693 | 700 | if (!data) { | |
| 694 | 701 | return THROW_ERR_OPERATION_FAILED(env, "Allocation failed"); | |
| 695 | 702 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -102,17 +102,19 @@ if (!process.features.openssl_is_boringssl) { | |||
| 102 | 102 | // ECDSA w/ ieee-p1363 signature encoding | |
| 103 | 103 | test('ec_secp256k1_public.pem', 'ec_secp256k1_private.pem', 'sha384', false, | |
| 104 | 104 | { dsaEncoding: 'ieee-p1363' }); | |
| 105 | - } | ||
| 106 | 105 | ||
| 107 | - // DSA w/ der signature encoding | ||
| 108 | - test('dsa_public.pem', 'dsa_private.pem', 'sha256', | ||
| 109 | - false); | ||
| 110 | - test('dsa_public.pem', 'dsa_private.pem', 'sha256', | ||
| 111 | - false, { dsaEncoding: 'der' }); | ||
| 106 | + // DSA w/ der signature encoding | ||
| 107 | + test('dsa_public.pem', 'dsa_private.pem', 'sha256', | ||
| 108 | + false); | ||
| 109 | + test('dsa_public.pem', 'dsa_private.pem', 'sha256', | ||
| 110 | + false, { dsaEncoding: 'der' }); | ||
| 112 | 111 | ||
| 113 | - // DSA w/ ieee-p1363 signature encoding | ||
| 114 | - test('dsa_public.pem', 'dsa_private.pem', 'sha256', false, | ||
| 115 | - { dsaEncoding: 'ieee-p1363' }); | ||
| 112 | + // DSA w/ ieee-p1363 signature encoding | ||
| 113 | + test('dsa_public.pem', 'dsa_private.pem', 'sha256', false, | ||
| 114 | + { dsaEncoding: 'ieee-p1363' }); | ||
| 115 | + } else { | ||
| 116 | + common.printSkipMessage('Skipping unsupported ed448/secp256k1/dsa test cases'); | ||
| 117 | + } | ||
| 116 | 118 | ||
| 117 | 119 | // Test Parallel Execution w/ KeyObject is threadsafe in openssl3 | |
| 118 | 120 | { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments