GeezerVison is showing github.com — crypto: do not advertise unsupported algorithms · nodejs/node@0fff4d2
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: src/crypto/crypto_cipher.cc +12-1Lines changed: 12 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -235,8 +235,19 @@ void CipherBase::GetSSLCiphers(const FunctionCallbackInfo<Value>& args) { | 235 | 235 |
| 236 | 236 | void CipherBase::GetCiphers(const FunctionCallbackInfo<Value>& args) { | 237 | 237 | Environment* env = Environment::GetCurrent(args); | | 238 | + MarkPopErrorOnReturn mark_pop_error_on_return; | 238 | 239 | CipherPushContext ctx(env); | 239 | | - EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx); | | 240 | + EVP_CIPHER_do_all_sorted( | | 241 | +#if OPENSSL_VERSION_MAJOR >= 3 | | 242 | + array_push_back<EVP_CIPHER, | | 243 | + EVP_CIPHER_fetch, | | 244 | + EVP_CIPHER_free, | | 245 | + EVP_get_cipherbyname, | | 246 | + EVP_CIPHER_get0_name>, | | 247 | +#else | | 248 | + array_push_back<EVP_CIPHER>, | | 249 | +#endif | | 250 | + &ctx); | 240 | 251 | args.GetReturnValue().Set(ctx.ToJSArray()); | 241 | 252 | } | 242 | 253 |
| |
Collapse file Copy file name to clipboardExpand all lines: src/crypto/crypto_hash.cc +12-1Lines changed: 12 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -35,8 +35,19 @@ void Hash::MemoryInfo(MemoryTracker* tracker) const { | 35 | 35 |
| 36 | 36 | void Hash::GetHashes(const FunctionCallbackInfo<Value>& args) { | 37 | 37 | Environment* env = Environment::GetCurrent(args); | | 38 | + MarkPopErrorOnReturn mark_pop_error_on_return; | 38 | 39 | CipherPushContext ctx(env); | 39 | | - EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx); | | 40 | + EVP_MD_do_all_sorted( | | 41 | +#if OPENSSL_VERSION_MAJOR >= 3 | | 42 | + array_push_back<EVP_MD, | | 43 | + EVP_MD_fetch, | | 44 | + EVP_MD_free, | | 45 | + EVP_get_digestbyname, | | 46 | + EVP_MD_get0_name>, | | 47 | +#else | | 48 | + array_push_back<EVP_MD>, | | 49 | +#endif | | 50 | + &ctx); | 40 | 51 | args.GetReturnValue().Set(ctx.ToJSArray()); | 41 | 52 | } | 42 | 53 |
| |
Collapse file Copy file name to clipboardExpand all lines: src/crypto/crypto_util.h +39-1Lines changed: 39 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -616,13 +616,51 @@ class CipherPushContext { | 616 | 616 | Environment* env_; | 617 | 617 | }; | 618 | 618 |
| | 619 | +#if OPENSSL_VERSION_MAJOR >= 3 | | 620 | +template <class TypeName, | | 621 | + TypeName* fetch_type(OSSL_LIB_CTX*, const char*, const char*), | | 622 | + void free_type(TypeName*), | | 623 | + const TypeName* getbyname(const char*), | | 624 | + const char* getname(const TypeName*)> | | 625 | +void array_push_back(const TypeName* evp_ref, | | 626 | + const char* from, | | 627 | + const char* to, | | 628 | + void* arg) { | | 629 | + if (!from) | | 630 | + return; | | 631 | + | | 632 | + const TypeName* real_instance = getbyname(from); | | 633 | + if (!real_instance) | | 634 | + return; | | 635 | + | | 636 | + const char* real_name = getname(real_instance); | | 637 | + if (!real_name) | | 638 | + return; | | 639 | + | | 640 | + // EVP_*_fetch() does not support alias names, so we need to pass it the | | 641 | + // real/original algorithm name. | | 642 | + // We use EVP_*_fetch() as a filter here because it will only return an | | 643 | + // instance if the algorithm is supported by the public OpenSSL APIs (some | | 644 | + // algorithms are used internally by OpenSSL and are also passed to this | | 645 | + // callback). | | 646 | + TypeName* fetched = fetch_type(nullptr, real_name, nullptr); | | 647 | + if (!fetched) | | 648 | + return; | | 649 | + | | 650 | + free_type(fetched); | | 651 | + static_cast<CipherPushContext*>(arg)->push_back(from); | | 652 | +} | | 653 | +#else | 619 | 654 | template <class TypeName> | 620 | | -void array_push_back(const TypeName* md, | | 655 | +void array_push_back(const TypeName* evp_ref, | 621 | 656 | const char* from, | 622 | 657 | const char* to, | 623 | 658 | void* arg) { | | 659 | + if (!from) | | 660 | + return; | 624 | 661 | static_cast<CipherPushContext*>(arg)->push_back(from); | 625 | 662 | } | | 663 | +#endif | 626 | 664 |
| 627 | 665 | inline bool IsAnyByteSource(v8::Local<v8::Value> arg) { | 628 | 666 | return arg->IsArrayBufferView() || | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-crypto.js +16Lines changed: 16 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -121,6 +121,19 @@ function validateList(list) { | 121 | 121 | const cryptoCiphers = crypto.getCiphers(); | 122 | 122 | assert(crypto.getCiphers().includes('aes-128-cbc')); | 123 | 123 | validateList(cryptoCiphers); | | 124 | +// Make sure all of the ciphers are supported by OpenSSL | | 125 | +for (const algo of cryptoCiphers) { | | 126 | + const { ivLength, keyLength, mode } = crypto.getCipherInfo(algo); | | 127 | + let options; | | 128 | + if (mode === 'ccm') | | 129 | + options = { authTagLength: 8 }; | | 130 | + else if (mode === 'ocb' || algo === 'chacha20-poly1305') | | 131 | + options = { authTagLength: 16 }; | | 132 | + crypto.createCipheriv(algo, | | 133 | + crypto.randomBytes(keyLength), | | 134 | + crypto.randomBytes(ivLength || 0), | | 135 | + options); | | 136 | +} | 124 | 137 |
| 125 | 138 | // Assume that we have at least AES256-SHA. | 126 | 139 | const tlsCiphers = tls.getCiphers(); | @@ -140,6 +153,9 @@ assert(!crypto.getHashes().includes('SHA256')); | 140 | 153 | assert(crypto.getHashes().includes('RSA-SHA1')); | 141 | 154 | assert(!crypto.getHashes().includes('rsa-sha1')); | 142 | 155 | validateList(crypto.getHashes()); | | 156 | +// Make sure all of the hashes are supported by OpenSSL | | 157 | +for (const algo of crypto.getHashes()) | | 158 | + crypto.createHash(algo); | 143 | 159 |
| 144 | 160 | // Assume that we have at least secp384r1. | 145 | 161 | assert.notStrictEqual(crypto.getCurves().length, 0); | |
|