diff options
author | Anton Gerasimov <agerasimov@twilio.com> | 2019-09-18 17:48:44 +0300 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2019-09-24 09:32:45 +0300 |
commit | 0c32ca96c878488c923022a8828bef541e0df9ae (patch) | |
tree | cc02885d1b3dcd79ba87162dfe771c7b88e265bb /src/node_crypto.cc | |
parent | e078e482c5ba41641d85bc3ba136148cc44b4d22 (diff) |
tls: add option to override signature algorithms
Passes the list down to SSL_CTX_set1_sigalgs_list.
Option to get the list of shared signature algorithms
from a TLS socket added as well for testing.
Signed-off-by: Anton Gerasimov <agerasimov@twilio.com>
PR-URL: https://github.com/nodejs/node/pull/29598
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/node_crypto.cc')
-rw-r--r-- | src/node_crypto.cc | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/node_crypto.cc b/src/node_crypto.cc index edf70d0cd7e..5f2e744e584 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -477,6 +477,7 @@ void SecureContext::Initialize(Environment* env, Local<Object> target) { env->SetProtoMethod(t, "addRootCerts", AddRootCerts); env->SetProtoMethod(t, "setCipherSuites", SetCipherSuites); env->SetProtoMethod(t, "setCiphers", SetCiphers); + env->SetProtoMethod(t, "setSigalgs", SetSigalgs); env->SetProtoMethod(t, "setECDHCurve", SetECDHCurve); env->SetProtoMethod(t, "setDHParam", SetDHParam); env->SetProtoMethod(t, "setMaxProto", SetMaxProto); @@ -745,6 +746,23 @@ void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) { } } +void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) { + SecureContext* sc; + ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + Environment* env = sc->env(); + ClearErrorOnReturn clear_error_on_return; + + CHECK_EQ(args.Length(), 1); + CHECK(args[0]->IsString()); + + const node::Utf8Value sigalgs(env->isolate(), args[0]); + + int rv = SSL_CTX_set1_sigalgs_list(sc->ctx_.get(), *sigalgs); + + if (rv == 0) { + return ThrowCryptoError(env, ERR_get_error()); + } +} int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) { X509_STORE* store = SSL_CTX_get_cert_store(ctx); @@ -1690,6 +1708,7 @@ void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) { env->SetProtoMethodNoSideEffect(t, "isSessionReused", IsSessionReused); env->SetProtoMethodNoSideEffect(t, "verifyError", VerifyError); env->SetProtoMethodNoSideEffect(t, "getCipher", GetCipher); + env->SetProtoMethodNoSideEffect(t, "getSharedSigalgs", GetSharedSigalgs); env->SetProtoMethod(t, "endParser", EndParser); env->SetProtoMethod(t, "certCbDone", CertCbDone); env->SetProtoMethod(t, "renegotiate", Renegotiate); @@ -2624,6 +2643,88 @@ void SSLWrap<Base>::GetCipher(const FunctionCallbackInfo<Value>& args) { template <class Base> +void SSLWrap<Base>::GetSharedSigalgs(const FunctionCallbackInfo<Value>& args) { + Base* w; + ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + Environment* env = w->ssl_env(); + std::vector<Local<Value>> ret_arr; + + SSL* ssl = w->ssl_.get(); + int nsig = SSL_get_shared_sigalgs(ssl, 0, nullptr, nullptr, nullptr, nullptr, + nullptr); + + for (int i = 0; i < nsig; i++) { + int hash_nid; + int sign_nid; + std::string sig_with_md; + + SSL_get_shared_sigalgs(ssl, i, &sign_nid, &hash_nid, nullptr, nullptr, + nullptr); + + switch (sign_nid) { + case EVP_PKEY_RSA: + sig_with_md = "RSA+"; + break; + + case EVP_PKEY_RSA_PSS: + sig_with_md = "RSA-PSS+"; + break; + + case EVP_PKEY_DSA: + sig_with_md = "DSA+"; + break; + + case EVP_PKEY_EC: + sig_with_md = "ECDSA+"; + break; + + case NID_ED25519: + sig_with_md = "Ed25519+"; + break; + + case NID_ED448: + sig_with_md = "Ed448+"; + break; + + case NID_id_GostR3410_2001: + sig_with_md = "gost2001+"; + break; + + case NID_id_GostR3410_2012_256: + sig_with_md = "gost2012_256+"; + break; + + case NID_id_GostR3410_2012_512: + sig_with_md = "gost2012_512+"; + break; + + default: + const char* sn = OBJ_nid2sn(sign_nid); + + if (sn != nullptr) { + sig_with_md = std::string(sn) + "+"; + } else { + sig_with_md = "UNDEF+"; + } + break; + } + + const char* sn_hash = OBJ_nid2sn(hash_nid); + if (sn_hash != nullptr) { + sig_with_md += std::string(sn_hash); + } else { + sig_with_md += "UNDEF"; + } + + ret_arr.push_back(OneByteString(env->isolate(), sig_with_md.c_str())); + } + + args.GetReturnValue().Set( + Array::New(env->isolate(), ret_arr.data(), ret_arr.size())); +} + + +template <class Base> void SSLWrap<Base>::GetProtocol(const FunctionCallbackInfo<Value>& args) { Base* w; ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); |