2 #include "node_buffer.h"
3 #include "node_crypto.h"
4 #include "node_crypto_bio.h"
5 #include "node_crypto_groups.h"
6 #include "tls_wrap.h" // TLSWrap
8 #include "async-wrap.h"
9 #include "async-wrap-inl.h"
12 #include "string_bytes.h"
16 // CNNIC Hash WhiteList is taken from
17 // https://hg.mozilla.org/mozilla-central/raw-file/98820360ab66/security/
18 // certverifier/CNNICHashWhitelist.inc
19 #include "CNNICHashWhitelist.inc"
27 #define strcasecmp _stricmp
30 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
31 #define OPENSSL_CONST const
36 #define THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(val) \
38 if (!Buffer::HasInstance(val) && !val->IsString()) { \
39 return env->ThrowTypeError("Not a string or buffer"); \
43 #define THROW_AND_RETURN_IF_NOT_BUFFER(val) \
45 if (!Buffer::HasInstance(val)) { \
46 return env->ThrowTypeError("Not a buffer"); \
50 static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----";
51 static const int PUBLIC_KEY_PFX_LEN = sizeof(PUBLIC_KEY_PFX) - 1;
52 static const char PUBRSA_KEY_PFX[] = "-----BEGIN RSA PUBLIC KEY-----";
53 static const int PUBRSA_KEY_PFX_LEN = sizeof(PUBRSA_KEY_PFX) - 1;
54 static const char CERTIFICATE_PFX[] = "-----BEGIN CERTIFICATE-----";
55 static const int CERTIFICATE_PFX_LEN = sizeof(CERTIFICATE_PFX) - 1;
57 static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
58 | ASN1_STRFLGS_UTF8_CONVERT
59 | XN_FLAG_SEP_MULTILINE
70 using v8::EscapableHandleScope;
74 using v8::FunctionCallbackInfo;
75 using v8::FunctionTemplate;
76 using v8::HandleScope;
83 using v8::PropertyAttribute;
84 using v8::PropertyCallbackInfo;
91 // Subject DER of CNNIC ROOT CA and CNNIC EV ROOT CA are taken from
92 // https://hg.mozilla.org/mozilla-central/file/98820360ab66/security/
93 // certverifier/NSSCertDBTrustDomain.cpp#l672
94 // C = CN, O = CNNIC, CN = CNNIC ROOT
95 static const uint8_t CNNIC_ROOT_CA_SUBJECT_DATA[] =
96 "\x30\x32\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x4E\x31\x0E\x30"
97 "\x0C\x06\x03\x55\x04\x0A\x13\x05\x43\x4E\x4E\x49\x43\x31\x13\x30\x11\x06"
98 "\x03\x55\x04\x03\x13\x0A\x43\x4E\x4E\x49\x43\x20\x52\x4F\x4F\x54";
99 static const uint8_t* cnnic_p = CNNIC_ROOT_CA_SUBJECT_DATA;
100 static X509_NAME* cnnic_name =
101 d2i_X509_NAME(nullptr, &cnnic_p, sizeof(CNNIC_ROOT_CA_SUBJECT_DATA)-1);
103 // C = CN, O = China Internet Network Information Center, CN = China
104 // Internet Network Information Center EV Certificates Root
105 static const uint8_t CNNIC_EV_ROOT_CA_SUBJECT_DATA[] =
106 "\x30\x81\x8A\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x4E\x31\x32"
107 "\x30\x30\x06\x03\x55\x04\x0A\x0C\x29\x43\x68\x69\x6E\x61\x20\x49\x6E\x74"
108 "\x65\x72\x6E\x65\x74\x20\x4E\x65\x74\x77\x6F\x72\x6B\x20\x49\x6E\x66\x6F"
109 "\x72\x6D\x61\x74\x69\x6F\x6E\x20\x43\x65\x6E\x74\x65\x72\x31\x47\x30\x45"
110 "\x06\x03\x55\x04\x03\x0C\x3E\x43\x68\x69\x6E\x61\x20\x49\x6E\x74\x65\x72"
111 "\x6E\x65\x74\x20\x4E\x65\x74\x77\x6F\x72\x6B\x20\x49\x6E\x66\x6F\x72\x6D"
112 "\x61\x74\x69\x6F\x6E\x20\x43\x65\x6E\x74\x65\x72\x20\x45\x56\x20\x43\x65"
113 "\x72\x74\x69\x66\x69\x63\x61\x74\x65\x73\x20\x52\x6F\x6F\x74";
114 static const uint8_t* cnnic_ev_p = CNNIC_EV_ROOT_CA_SUBJECT_DATA;
115 static X509_NAME *cnnic_ev_name =
116 d2i_X509_NAME(nullptr, &cnnic_ev_p,
117 sizeof(CNNIC_EV_ROOT_CA_SUBJECT_DATA)-1);
119 // Forcibly clear OpenSSL's error stack on return. This stops stale errors
120 // from popping up later in the lifecycle of crypto operations where they
121 // would cause spurious failures. It's a rather blunt method, though.
122 // ERR_clear_error() isn't necessarily cheap either.
123 struct ClearErrorOnReturn {
124 ~ClearErrorOnReturn() { ERR_clear_error(); }
127 static uv_mutex_t* locks;
129 const char* const root_certs[] = {
130 #include "node_root_certs.h" // NOLINT(build/include_order)
133 X509_STORE* root_cert_store;
135 // Just to generate static methods
136 template class SSLWrap<TLSWrap>;
137 template void SSLWrap<TLSWrap>::AddMethods(Environment* env,
138 Local<FunctionTemplate> t);
139 template void SSLWrap<TLSWrap>::InitNPN(SecureContext* sc);
140 template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
145 template int SSLWrap<TLSWrap>::NewSessionCallback(SSL* s,
147 template void SSLWrap<TLSWrap>::OnClientHello(
149 const ClientHelloParser::ClientHello& hello);
151 #ifdef OPENSSL_NPN_NEGOTIATED
152 template int SSLWrap<TLSWrap>::AdvertiseNextProtoCallback(
154 const unsigned char** data,
157 template int SSLWrap<TLSWrap>::SelectNextProtoCallback(
160 unsigned char* outlen,
161 const unsigned char* in,
165 template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void* arg);
166 template void SSLWrap<TLSWrap>::DestroySSL();
167 template int SSLWrap<TLSWrap>::SSLCertCallback(SSL* s, void* arg);
168 template void SSLWrap<TLSWrap>::WaitForCertCb(CertCb cb, void* arg);
171 static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
172 static_assert(sizeof(uv_thread_t) <= sizeof(void*), // NOLINT(runtime/sizeof)
173 "uv_thread_t does not fit in a pointer");
174 CRYPTO_THREADID_set_pointer(tid, reinterpret_cast<void*>(uv_thread_self()));
178 static void crypto_lock_init(void) {
181 n = CRYPTO_num_locks();
182 locks = new uv_mutex_t[n];
184 for (i = 0; i < n; i++)
185 if (uv_mutex_init(locks + i))
190 static void crypto_lock_cb(int mode, int n, const char* file, int line) {
191 CHECK(!(mode & CRYPTO_LOCK) ^ !(mode & CRYPTO_UNLOCK));
192 CHECK(!(mode & CRYPTO_READ) ^ !(mode & CRYPTO_WRITE));
194 if (mode & CRYPTO_LOCK)
195 uv_mutex_lock(locks + n);
197 uv_mutex_unlock(locks + n);
201 static int CryptoPemCallback(char *buf, int size, int rwflag, void *u) {
203 size_t buflen = static_cast<size_t>(size);
204 size_t len = strlen(static_cast<const char*>(u));
205 len = len > buflen ? buflen : len;
214 void ThrowCryptoError(Environment* env,
216 const char* default_message = nullptr) {
217 HandleScope scope(env->isolate());
218 if (err != 0 || default_message == nullptr) {
219 char errmsg[128] = { 0 };
220 ERR_error_string_n(err, errmsg, sizeof(errmsg));
221 env->ThrowError(errmsg);
223 env->ThrowError(default_message);
228 // Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.
229 // The entropy pool starts out empty and needs to fill up before the PRNG
230 // can be used securely. Once the pool is filled, it never dries up again;
231 // its contents is stirred and reused when necessary.
233 // OpenSSL normally fills the pool automatically but not when someone starts
234 // generating random numbers before the pool is full: in that case OpenSSL
235 // keeps lowering the entropy estimate to thwart attackers trying to guess
236 // the initial state of the PRNG.
238 // When that happens, we will have to wait until enough entropy is available.
239 // That should normally never take longer than a few milliseconds.
241 // OpenSSL draws from /dev/random and /dev/urandom. While /dev/random may
242 // block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't
243 // block under normal circumstances.
245 // The only time when /dev/urandom may conceivably block is right after boot,
246 // when the whole system is still low on entropy. That's not something we can
247 // do anything about.
248 inline void CheckEntropy() {
250 int status = RAND_status();
251 CHECK_GE(status, 0); // Cannot fail.
255 // Give up, RAND_poll() not supported.
256 if (RAND_poll() == 0)
262 bool EntropySource(unsigned char* buffer, size_t length) {
263 // Ensure that OpenSSL's PRNG is properly seeded.
265 // RAND_bytes() can return 0 to indicate that the entropy data is not truly
266 // random. That's okay, it's still better than V8's stock source of entropy,
267 // which is /dev/urandom on UNIX platforms and the current time on Windows.
268 return RAND_bytes(buffer, length) != -1;
272 void SecureContext::Initialize(Environment* env, Local<Object> target) {
273 Local<FunctionTemplate> t = env->NewFunctionTemplate(SecureContext::New);
274 t->InstanceTemplate()->SetInternalFieldCount(1);
275 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"));
277 env->SetProtoMethod(t, "init", SecureContext::Init);
278 env->SetProtoMethod(t, "setKey", SecureContext::SetKey);
279 env->SetProtoMethod(t, "setCert", SecureContext::SetCert);
280 env->SetProtoMethod(t, "addCACert", SecureContext::AddCACert);
281 env->SetProtoMethod(t, "addCRL", SecureContext::AddCRL);
282 env->SetProtoMethod(t, "addRootCerts", SecureContext::AddRootCerts);
283 env->SetProtoMethod(t, "setCiphers", SecureContext::SetCiphers);
284 env->SetProtoMethod(t, "setECDHCurve", SecureContext::SetECDHCurve);
285 env->SetProtoMethod(t, "setDHParam", SecureContext::SetDHParam);
286 env->SetProtoMethod(t, "setOptions", SecureContext::SetOptions);
287 env->SetProtoMethod(t, "setSessionIdContext",
288 SecureContext::SetSessionIdContext);
289 env->SetProtoMethod(t, "setSessionTimeout",
290 SecureContext::SetSessionTimeout);
291 env->SetProtoMethod(t, "close", SecureContext::Close);
292 env->SetProtoMethod(t, "loadPKCS12", SecureContext::LoadPKCS12);
293 env->SetProtoMethod(t, "getTicketKeys", SecureContext::GetTicketKeys);
294 env->SetProtoMethod(t, "setTicketKeys", SecureContext::SetTicketKeys);
295 env->SetProtoMethod(t, "setFreeListLength", SecureContext::SetFreeListLength);
296 env->SetProtoMethod(t,
297 "enableTicketKeyCallback",
298 SecureContext::EnableTicketKeyCallback);
299 env->SetProtoMethod(t, "getCertificate", SecureContext::GetCertificate<true>);
300 env->SetProtoMethod(t, "getIssuer", SecureContext::GetCertificate<false>);
302 t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kTicketKeyReturnIndex"),
303 Integer::NewFromUnsigned(env->isolate(), kTicketKeyReturnIndex));
304 t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kTicketKeyHMACIndex"),
305 Integer::NewFromUnsigned(env->isolate(), kTicketKeyHMACIndex));
306 t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kTicketKeyAESIndex"),
307 Integer::NewFromUnsigned(env->isolate(), kTicketKeyAESIndex));
308 t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kTicketKeyNameIndex"),
309 Integer::NewFromUnsigned(env->isolate(), kTicketKeyNameIndex));
310 t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kTicketKeyIVIndex"),
311 Integer::NewFromUnsigned(env->isolate(), kTicketKeyIVIndex));
313 t->PrototypeTemplate()->SetAccessor(
314 FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
319 static_cast<PropertyAttribute>(ReadOnly | DontDelete));
321 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"),
323 env->set_secure_context_constructor_template(t);
327 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
328 Environment* env = Environment::GetCurrent(args);
329 new SecureContext(env, args.This());
333 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
334 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
335 Environment* env = sc->env();
337 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
339 if (args.Length() == 1 && args[0]->IsString()) {
340 const node::Utf8Value sslmethod(env->isolate(), args[0]);
342 // Note that SSLv2 and SSLv3 are disallowed but SSLv2_method and friends
343 // are still accepted. They are OpenSSL's way of saying that all known
344 // protocols are supported unless explicitly disabled (which we do below
345 // for SSLv2 and SSLv3.)
346 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
347 return env->ThrowError("SSLv2 methods disabled");
348 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
349 return env->ThrowError("SSLv2 methods disabled");
350 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
351 return env->ThrowError("SSLv2 methods disabled");
352 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
353 return env->ThrowError("SSLv3 methods disabled");
354 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
355 return env->ThrowError("SSLv3 methods disabled");
356 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
357 return env->ThrowError("SSLv3 methods disabled");
358 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
359 method = SSLv23_method();
360 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
361 method = SSLv23_server_method();
362 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
363 method = SSLv23_client_method();
364 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
365 method = TLSv1_method();
366 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
367 method = TLSv1_server_method();
368 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
369 method = TLSv1_client_method();
370 } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
371 method = TLSv1_1_method();
372 } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
373 method = TLSv1_1_server_method();
374 } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
375 method = TLSv1_1_client_method();
376 } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
377 method = TLSv1_2_method();
378 } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
379 method = TLSv1_2_server_method();
380 } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
381 method = TLSv1_2_client_method();
383 return env->ThrowError("Unknown method");
387 sc->ctx_ = SSL_CTX_new(method);
388 SSL_CTX_set_app_data(sc->ctx_, sc);
390 // Disable SSLv2 in the case when method == SSLv23_method() and the
391 // cipher list contains SSLv2 ciphers (not the default, should be rare.)
392 // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
393 // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
394 SSL_CTX_set_options(sc->ctx_, SSL_OP_NO_SSLv2);
395 SSL_CTX_set_options(sc->ctx_, SSL_OP_NO_SSLv3);
397 // SSL session cache configuration
398 SSL_CTX_set_session_cache_mode(sc->ctx_,
399 SSL_SESS_CACHE_SERVER |
400 SSL_SESS_CACHE_NO_INTERNAL |
401 SSL_SESS_CACHE_NO_AUTO_CLEAR);
402 SSL_CTX_sess_set_get_cb(sc->ctx_, SSLWrap<Connection>::GetSessionCallback);
403 SSL_CTX_sess_set_new_cb(sc->ctx_, SSLWrap<Connection>::NewSessionCallback);
405 sc->ca_store_ = nullptr;
409 // Takes a string or buffer and loads it into a BIO.
410 // Caller responsible for BIO_free_all-ing the returned object.
411 static BIO* LoadBIO(Environment* env, Local<Value> v) {
412 BIO* bio = NodeBIO::New();
416 HandleScope scope(env->isolate());
421 const node::Utf8Value s(env->isolate(), v);
422 r = BIO_write(bio, *s, s.length());
423 } else if (Buffer::HasInstance(v)) {
424 char* buffer_data = Buffer::Data(v);
425 size_t buffer_length = Buffer::Length(v);
426 r = BIO_write(bio, buffer_data, buffer_length);
438 // Takes a string or buffer and loads it into an X509
439 // Caller responsible for X509_free-ing the returned object.
440 static X509* LoadX509(Environment* env, Local<Value> v) {
441 HandleScope scope(env->isolate());
443 BIO *bio = LoadBIO(env, v);
447 X509 * x509 = PEM_read_bio_X509(bio, nullptr, CryptoPemCallback, nullptr);
458 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
459 Environment* env = Environment::GetCurrent(args);
461 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
463 unsigned int len = args.Length();
464 if (len != 1 && len != 2) {
465 return env->ThrowTypeError("Bad parameter");
467 if (len == 2 && !args[1]->IsString()) {
468 return env->ThrowTypeError("Bad parameter");
471 BIO *bio = LoadBIO(env, args[0]);
475 node::Utf8Value passphrase(env->isolate(), args[1]);
477 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio,
480 len == 1 ? nullptr : *passphrase);
484 unsigned long err = ERR_get_error();
486 return env->ThrowError("PEM_read_bio_PrivateKey");
488 return ThrowCryptoError(env, err);
491 int rv = SSL_CTX_use_PrivateKey(sc->ctx_, key);
496 unsigned long err = ERR_get_error();
498 return env->ThrowError("SSL_CTX_use_PrivateKey");
499 return ThrowCryptoError(env, err);
504 int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) {
507 X509_STORE* store = SSL_CTX_get_cert_store(ctx);
508 X509_STORE_CTX store_ctx;
510 ret = X509_STORE_CTX_init(&store_ctx, store, nullptr, nullptr);
514 ret = X509_STORE_CTX_get1_issuer(issuer, &store_ctx, cert);
515 X509_STORE_CTX_cleanup(&store_ctx);
522 // Read a file that contains our certificate in "PEM" format,
523 // possibly followed by a sequence of CA certificates that should be
524 // sent to the peer in the Certificate message.
526 // Taken from OpenSSL - editted for style.
527 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
534 x = PEM_read_bio_X509_AUX(in, nullptr, CryptoPemCallback, nullptr);
537 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
541 ret = SSL_CTX_use_certificate(ctx, x);
544 // If we could set up our certificate, now proceed to
545 // the CA certificates.
550 if (ctx->extra_certs != nullptr) {
551 sk_X509_pop_free(ctx->extra_certs, X509_free);
552 ctx->extra_certs = nullptr;
555 while ((ca = PEM_read_bio_X509(in, nullptr, CryptoPemCallback, nullptr))) {
556 // NOTE: Increments reference count on `ca`
557 r = SSL_CTX_add1_chain_cert(ctx, ca);
564 // Note that we must not free r if it was successfully
565 // added to the chain (while we must free the main
566 // certificate, since its reference count is increased
567 // by SSL_CTX_use_certificate).
570 if (*issuer != nullptr || X509_check_issued(ca, x) != X509_V_OK)
575 // When the while loop ends, it's usually just EOF.
576 err = ERR_peek_last_error();
577 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
578 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
586 // Try getting issuer from a cert store
588 if (*issuer == nullptr) {
589 ret = SSL_CTX_get_issuer(ctx, x, issuer);
590 ret = ret < 0 ? 0 : 1;
591 // NOTE: get_cert_store doesn't increment reference count,
592 // no need to free `store`
594 // Increment issuer reference count
595 CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
606 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
607 Environment* env = Environment::GetCurrent(args);
609 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
611 if (args.Length() != 1) {
612 return env->ThrowTypeError("Bad parameter");
615 BIO* bio = LoadBIO(env, args[0]);
619 int rv = SSL_CTX_use_certificate_chain(sc->ctx_,
627 unsigned long err = ERR_get_error();
629 return env->ThrowError("SSL_CTX_use_certificate_chain");
631 return ThrowCryptoError(env, err);
636 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
637 bool newCAStore = false;
638 Environment* env = Environment::GetCurrent(args);
640 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
641 ClearErrorOnReturn clear_error_on_return;
642 (void) &clear_error_on_return; // Silence compiler warning.
644 if (args.Length() != 1) {
645 return env->ThrowTypeError("Bad parameter");
648 if (!sc->ca_store_) {
649 sc->ca_store_ = X509_STORE_new();
653 X509* x509 = LoadX509(env, args[0]);
657 X509_STORE_add_cert(sc->ca_store_, x509);
658 SSL_CTX_add_client_CA(sc->ctx_, x509);
663 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
668 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
669 Environment* env = Environment::GetCurrent(args);
671 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
673 if (args.Length() != 1) {
674 return env->ThrowTypeError("Bad parameter");
677 ClearErrorOnReturn clear_error_on_return;
678 (void) &clear_error_on_return; // Silence compiler warning.
680 BIO *bio = LoadBIO(env, args[0]);
685 PEM_read_bio_X509_CRL(bio, nullptr, CryptoPemCallback, nullptr);
687 if (x509 == nullptr) {
692 X509_STORE_add_crl(sc->ca_store_, x509);
693 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
694 X509_V_FLAG_CRL_CHECK_ALL);
701 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
702 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
703 ClearErrorOnReturn clear_error_on_return;
704 (void) &clear_error_on_return; // Silence compiler warning.
706 CHECK_EQ(sc->ca_store_, nullptr);
708 if (!root_cert_store) {
709 root_cert_store = X509_STORE_new();
711 for (size_t i = 0; i < ARRAY_SIZE(root_certs); i++) {
712 BIO* bp = NodeBIO::New();
714 if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
719 X509 *x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
721 if (x509 == nullptr) {
726 X509_STORE_add_cert(root_cert_store, x509);
733 sc->ca_store_ = root_cert_store;
734 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
738 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
739 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
740 ClearErrorOnReturn clear_error_on_return;
741 (void) &clear_error_on_return; // Silence compiler warning.
743 if (args.Length() != 1 || !args[0]->IsString()) {
744 return sc->env()->ThrowTypeError("Bad parameter");
747 const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
748 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
752 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
753 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
754 Environment* env = sc->env();
756 if (args.Length() != 1 || !args[0]->IsString())
757 return env->ThrowTypeError("First argument should be a string");
759 node::Utf8Value curve(env->isolate(), args[0]);
761 int nid = OBJ_sn2nid(*curve);
763 if (nid == NID_undef)
764 return env->ThrowTypeError("First argument should be a valid curve name");
766 EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
769 return env->ThrowTypeError("First argument should be a valid curve name");
771 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
772 SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
778 void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
779 SecureContext* sc = Unwrap<SecureContext>(args.This());
780 Environment* env = sc->env();
781 ClearErrorOnReturn clear_error_on_return;
782 (void) &clear_error_on_return; // Silence compiler warning.
784 // Auto DH is not supported in openssl 1.0.1, so dhparam needs
785 // to be specifed explicitly
786 if (args.Length() != 1)
787 return env->ThrowTypeError("Bad parameter");
789 // Invalid dhparam is silently discarded and DHE is no longer used.
790 BIO* bio = LoadBIO(env, args[0]);
794 DH* dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
800 const int keylen = BN_num_bits(dh->p);
803 return env->ThrowError("DH parameter is less than 1024 bits");
804 } else if (keylen < 2048) {
805 fprintf(stderr, "WARNING: DH parameter is less than 2048 bits\n");
808 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_DH_USE);
809 int r = SSL_CTX_set_tmp_dh(sc->ctx_, dh);
813 return env->ThrowTypeError("Error setting temp DH parameter");
817 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
818 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
820 if (args.Length() != 1 || !args[0]->IntegerValue()) {
821 return sc->env()->ThrowTypeError("Bad parameter");
824 SSL_CTX_set_options(sc->ctx_, static_cast<long>(args[0]->IntegerValue()));
828 void SecureContext::SetSessionIdContext(
829 const FunctionCallbackInfo<Value>& args) {
830 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
832 if (args.Length() != 1 || !args[0]->IsString()) {
833 return sc->env()->ThrowTypeError("Bad parameter");
836 const node::Utf8Value sessionIdContext(args.GetIsolate(), args[0]);
837 const unsigned char* sid_ctx =
838 reinterpret_cast<const unsigned char*>(*sessionIdContext);
839 unsigned int sid_ctx_len = sessionIdContext.length();
841 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
847 Local<String> message;
849 bio = BIO_new(BIO_s_mem());
850 if (bio == nullptr) {
851 message = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
852 "SSL_CTX_set_session_id_context error");
854 ERR_print_errors(bio);
855 BIO_get_mem_ptr(bio, &mem);
856 message = OneByteString(args.GetIsolate(), mem->data, mem->length);
860 args.GetIsolate()->ThrowException(Exception::TypeError(message));
864 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
865 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
867 if (args.Length() != 1 || !args[0]->IsInt32()) {
868 return sc->env()->ThrowTypeError("Bad parameter");
871 int32_t sessionTimeout = args[0]->Int32Value();
872 SSL_CTX_set_timeout(sc->ctx_, sessionTimeout);
876 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
877 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
882 // Takes .pfx or .p12 and password in string or buffer format
883 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
884 Environment* env = Environment::GetCurrent(args);
887 PKCS12* p12 = nullptr;
888 EVP_PKEY* pkey = nullptr;
889 X509* cert = nullptr;
890 STACK_OF(X509)* extraCerts = nullptr;
891 char* pass = nullptr;
894 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
895 ClearErrorOnReturn clear_error_on_return;
896 (void) &clear_error_on_return; // Silence compiler warning.
898 if (args.Length() < 1) {
899 return env->ThrowTypeError("Bad parameter");
902 in = LoadBIO(env, args[0]);
904 return env->ThrowError("Unable to load BIO");
907 if (args.Length() >= 2) {
908 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
909 size_t passlen = Buffer::Length(args[1]);
910 pass = new char[passlen + 1];
911 memcpy(pass, Buffer::Data(args[1]), passlen);
912 pass[passlen] = '\0';
915 if (d2i_PKCS12_bio(in, &p12) &&
916 PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
917 SSL_CTX_use_certificate(sc->ctx_, cert) &&
918 SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) {
920 while (X509* x509 = sk_X509_pop(extraCerts)) {
921 if (!sc->ca_store_) {
922 sc->ca_store_ = X509_STORE_new();
923 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
926 X509_STORE_add_cert(sc->ca_store_, x509);
927 SSL_CTX_add_client_CA(sc->ctx_, x509);
933 sk_X509_free(extraCerts);
943 unsigned long err = ERR_get_error();
944 const char* str = ERR_reason_error_string(err);
945 return env->ThrowError(str);
950 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
951 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
953 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
955 Local<Object> buff = Buffer::New(wrap->env(), 48).ToLocalChecked();
956 if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_,
958 Buffer::Length(buff)) != 1) {
959 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
962 args.GetReturnValue().Set(buff);
963 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
967 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
968 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
969 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
971 if (args.Length() < 1 ||
972 !Buffer::HasInstance(args[0]) ||
973 Buffer::Length(args[0]) != 48) {
974 return wrap->env()->ThrowTypeError("Bad argument");
977 if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_,
978 Buffer::Data(args[0]),
979 Buffer::Length(args[0])) != 1) {
980 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
983 args.GetReturnValue().Set(true);
984 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
988 void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
989 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
991 wrap->ctx_->freelist_max_len = args[0]->Int32Value();
995 void SecureContext::EnableTicketKeyCallback(
996 const FunctionCallbackInfo<Value>& args) {
997 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
999 SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_, TicketKeyCallback);
1003 int SecureContext::TicketKeyCallback(SSL* ssl,
1004 unsigned char* name,
1006 EVP_CIPHER_CTX* ectx,
1009 static const int kTicketPartSize = 16;
1011 SecureContext* sc = static_cast<SecureContext*>(
1012 SSL_CTX_get_app_data(ssl->ctx));
1014 Environment* env = sc->env();
1015 HandleScope handle_scope(env->isolate());
1016 Context::Scope context_scope(env->context());
1018 Local<Value> argv[] = {
1020 reinterpret_cast<char*>(name),
1021 kTicketPartSize).ToLocalChecked(),
1023 reinterpret_cast<char*>(iv),
1024 kTicketPartSize).ToLocalChecked(),
1025 Boolean::New(env->isolate(), enc != 0)
1027 Local<Value> ret = node::MakeCallback(env,
1029 env->ticketkeycallback_string(),
1032 Local<Array> arr = ret.As<Array>();
1034 int r = arr->Get(kTicketKeyReturnIndex)->Int32Value();
1038 Local<Value> hmac = arr->Get(kTicketKeyHMACIndex);
1039 Local<Value> aes = arr->Get(kTicketKeyAESIndex);
1040 if (Buffer::Length(aes) != kTicketPartSize)
1044 Local<Value> name_val = arr->Get(kTicketKeyNameIndex);
1045 Local<Value> iv_val = arr->Get(kTicketKeyIVIndex);
1047 if (Buffer::Length(name_val) != kTicketPartSize ||
1048 Buffer::Length(iv_val) != kTicketPartSize) {
1052 memcpy(name, Buffer::Data(name_val), kTicketPartSize);
1053 memcpy(iv, Buffer::Data(iv_val), kTicketPartSize);
1058 Buffer::Length(hmac),
1062 const unsigned char* aes_key =
1063 reinterpret_cast<unsigned char*>(Buffer::Data(aes));
1065 EVP_EncryptInit_ex(ectx,
1071 EVP_DecryptInit_ex(ectx,
1084 void SecureContext::CtxGetter(Local<String> property,
1085 const PropertyCallbackInfo<Value>& info) {
1086 HandleScope scope(info.GetIsolate());
1088 SSL_CTX* ctx = Unwrap<SecureContext>(info.Holder())->ctx_;
1089 Local<External> ext = External::New(info.GetIsolate(), ctx);
1090 info.GetReturnValue().Set(ext);
1094 template <bool primary>
1095 void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1096 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
1097 Environment* env = wrap->env();
1103 cert = wrap->issuer_;
1104 if (cert == nullptr)
1105 return args.GetReturnValue().Set(Null(env->isolate()));
1107 int size = i2d_X509(cert, nullptr);
1108 Local<Object> buff = Buffer::New(env, size).ToLocalChecked();
1109 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1110 Buffer::Data(buff));
1111 i2d_X509(cert, &serialized);
1113 args.GetReturnValue().Set(buff);
1117 template <class Base>
1118 void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) {
1119 HandleScope scope(env->isolate());
1121 env->SetProtoMethod(t, "getPeerCertificate", GetPeerCertificate);
1122 env->SetProtoMethod(t, "getSession", GetSession);
1123 env->SetProtoMethod(t, "setSession", SetSession);
1124 env->SetProtoMethod(t, "loadSession", LoadSession);
1125 env->SetProtoMethod(t, "isSessionReused", IsSessionReused);
1126 env->SetProtoMethod(t, "isInitFinished", IsInitFinished);
1127 env->SetProtoMethod(t, "verifyError", VerifyError);
1128 env->SetProtoMethod(t, "getCurrentCipher", GetCurrentCipher);
1129 env->SetProtoMethod(t, "endParser", EndParser);
1130 env->SetProtoMethod(t, "certCbDone", CertCbDone);
1131 env->SetProtoMethod(t, "renegotiate", Renegotiate);
1132 env->SetProtoMethod(t, "shutdownSSL", Shutdown);
1133 env->SetProtoMethod(t, "getTLSTicket", GetTLSTicket);
1134 env->SetProtoMethod(t, "newSessionDone", NewSessionDone);
1135 env->SetProtoMethod(t, "setOCSPResponse", SetOCSPResponse);
1136 env->SetProtoMethod(t, "requestOCSP", RequestOCSP);
1138 #ifdef SSL_set_max_send_fragment
1139 env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment);
1140 #endif // SSL_set_max_send_fragment
1142 #ifdef OPENSSL_NPN_NEGOTIATED
1143 env->SetProtoMethod(t, "getNegotiatedProtocol", GetNegotiatedProto);
1144 #endif // OPENSSL_NPN_NEGOTIATED
1146 #ifdef OPENSSL_NPN_NEGOTIATED
1147 env->SetProtoMethod(t, "setNPNProtocols", SetNPNProtocols);
1150 t->PrototypeTemplate()->SetAccessor(
1151 FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
1156 static_cast<PropertyAttribute>(ReadOnly | DontDelete));
1160 template <class Base>
1161 void SSLWrap<Base>::InitNPN(SecureContext* sc) {
1162 #ifdef OPENSSL_NPN_NEGOTIATED
1163 // Server should advertise NPN protocols
1164 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
1165 AdvertiseNextProtoCallback,
1167 // Client should select protocol from list of advertised
1168 // If server supports NPN
1169 SSL_CTX_set_next_proto_select_cb(sc->ctx_, SelectNextProtoCallback, nullptr);
1170 #endif // OPENSSL_NPN_NEGOTIATED
1172 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1174 SSL_CTX_set_tlsext_status_cb(sc->ctx_, TLSExtStatusCallback);
1175 SSL_CTX_set_tlsext_status_arg(sc->ctx_, nullptr);
1176 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1180 template <class Base>
1181 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
1185 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1188 SSL_SESSION* sess = w->next_sess_;
1189 w->next_sess_ = nullptr;
1195 template <class Base>
1196 int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
1197 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1198 Environment* env = w->ssl_env();
1199 HandleScope handle_scope(env->isolate());
1200 Context::Scope context_scope(env->context());
1202 if (!w->session_callbacks_)
1205 // Check if session is small enough to be stored
1206 int size = i2d_SSL_SESSION(sess, nullptr);
1207 if (size > SecureContext::kMaxSessionSize)
1210 // Serialize session
1211 Local<Object> buff = Buffer::New(env, size).ToLocalChecked();
1212 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1213 Buffer::Data(buff));
1214 memset(serialized, 0, size);
1215 i2d_SSL_SESSION(sess, &serialized);
1217 Local<Object> session = Buffer::Copy(
1219 reinterpret_cast<char*>(sess->session_id),
1220 sess->session_id_length).ToLocalChecked();
1221 Local<Value> argv[] = { session, buff };
1222 w->new_session_wait_ = true;
1223 w->MakeCallback(env->onnewsession_string(), ARRAY_SIZE(argv), argv);
1229 template <class Base>
1230 void SSLWrap<Base>::OnClientHello(void* arg,
1231 const ClientHelloParser::ClientHello& hello) {
1232 Base* w = static_cast<Base*>(arg);
1233 Environment* env = w->ssl_env();
1234 HandleScope handle_scope(env->isolate());
1235 Context::Scope context_scope(env->context());
1237 Local<Object> hello_obj = Object::New(env->isolate());
1238 Local<Object> buff = Buffer::Copy(
1240 reinterpret_cast<const char*>(hello.session_id()),
1241 hello.session_size()).ToLocalChecked();
1242 hello_obj->Set(env->session_id_string(), buff);
1243 if (hello.servername() == nullptr) {
1244 hello_obj->Set(env->servername_string(), String::Empty(env->isolate()));
1246 Local<String> servername = OneByteString(env->isolate(),
1248 hello.servername_size());
1249 hello_obj->Set(env->servername_string(), servername);
1251 hello_obj->Set(env->tls_ticket_string(),
1252 Boolean::New(env->isolate(), hello.has_ticket()));
1253 hello_obj->Set(env->ocsp_request_string(),
1254 Boolean::New(env->isolate(), hello.ocsp_request()));
1256 Local<Value> argv[] = { hello_obj };
1257 w->MakeCallback(env->onclienthello_string(), ARRAY_SIZE(argv), argv);
1261 static bool SafeX509ExtPrint(BIO* out, X509_EXTENSION* ext) {
1262 const X509V3_EXT_METHOD* method = X509V3_EXT_get(ext);
1264 if (method != X509V3_EXT_get_nid(NID_subject_alt_name))
1267 const unsigned char* p = ext->value->data;
1268 GENERAL_NAMES* names = reinterpret_cast<GENERAL_NAMES*>(ASN1_item_d2i(
1272 ASN1_ITEM_ptr(method->it)));
1276 for (int i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1277 GENERAL_NAME* gen = sk_GENERAL_NAME_value(names, i);
1280 BIO_write(out, ", ", 2);
1282 if (gen->type == GEN_DNS) {
1283 ASN1_IA5STRING* name = gen->d.dNSName;
1285 BIO_write(out, "DNS:", 4);
1286 BIO_write(out, name->data, name->length);
1288 STACK_OF(CONF_VALUE)* nval = i2v_GENERAL_NAME(
1289 const_cast<X509V3_EXT_METHOD*>(method), gen, NULL);
1292 X509V3_EXT_val_prn(out, nval, 0, 0);
1293 sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
1296 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
1302 static Local<Object> X509ToObject(Environment* env, X509* cert) {
1303 EscapableHandleScope scope(env->isolate());
1305 Local<Object> info = Object::New(env->isolate());
1307 BIO* bio = BIO_new(BIO_s_mem());
1309 if (X509_NAME_print_ex(bio,
1310 X509_get_subject_name(cert),
1312 X509_NAME_FLAGS) > 0) {
1313 BIO_get_mem_ptr(bio, &mem);
1314 info->Set(env->subject_string(),
1315 String::NewFromUtf8(env->isolate(), mem->data,
1316 String::kNormalString, mem->length));
1318 (void) BIO_reset(bio);
1320 X509_NAME* issuer_name = X509_get_issuer_name(cert);
1321 if (X509_NAME_print_ex(bio, issuer_name, 0, X509_NAME_FLAGS) > 0) {
1322 BIO_get_mem_ptr(bio, &mem);
1323 info->Set(env->issuer_string(),
1324 String::NewFromUtf8(env->isolate(), mem->data,
1325 String::kNormalString, mem->length));
1327 (void) BIO_reset(bio);
1329 int nids[] = { NID_subject_alt_name, NID_info_access };
1330 Local<String> keys[] = { env->subjectaltname_string(),
1331 env->infoaccess_string() };
1332 CHECK_EQ(ARRAY_SIZE(nids), ARRAY_SIZE(keys));
1333 for (unsigned int i = 0; i < ARRAY_SIZE(nids); i++) {
1334 int index = X509_get_ext_by_NID(cert, nids[i], -1);
1338 X509_EXTENSION* ext;
1341 ext = X509_get_ext(cert, index);
1342 CHECK_NE(ext, nullptr);
1344 if (!SafeX509ExtPrint(bio, ext)) {
1345 rv = X509V3_EXT_print(bio, ext, 0, 0);
1349 BIO_get_mem_ptr(bio, &mem);
1351 String::NewFromUtf8(env->isolate(), mem->data,
1352 String::kNormalString, mem->length));
1354 (void) BIO_reset(bio);
1357 EVP_PKEY* pkey = X509_get_pubkey(cert);
1359 if (pkey != nullptr)
1360 rsa = EVP_PKEY_get1_RSA(pkey);
1362 if (rsa != nullptr) {
1363 BN_print(bio, rsa->n);
1364 BIO_get_mem_ptr(bio, &mem);
1365 info->Set(env->modulus_string(),
1366 String::NewFromUtf8(env->isolate(), mem->data,
1367 String::kNormalString, mem->length));
1368 (void) BIO_reset(bio);
1370 unsigned long exponent_word = BN_get_word(rsa->e);
1371 BIO_printf(bio, "0x%lx", exponent_word);
1373 BIO_get_mem_ptr(bio, &mem);
1374 info->Set(env->exponent_string(),
1375 String::NewFromUtf8(env->isolate(), mem->data,
1376 String::kNormalString, mem->length));
1377 (void) BIO_reset(bio);
1380 if (pkey != nullptr) {
1381 EVP_PKEY_free(pkey);
1384 if (rsa != nullptr) {
1389 ASN1_TIME_print(bio, X509_get_notBefore(cert));
1390 BIO_get_mem_ptr(bio, &mem);
1391 info->Set(env->valid_from_string(),
1392 String::NewFromUtf8(env->isolate(), mem->data,
1393 String::kNormalString, mem->length));
1394 (void) BIO_reset(bio);
1396 ASN1_TIME_print(bio, X509_get_notAfter(cert));
1397 BIO_get_mem_ptr(bio, &mem);
1398 info->Set(env->valid_to_string(),
1399 String::NewFromUtf8(env->isolate(), mem->data,
1400 String::kNormalString, mem->length));
1403 unsigned int md_size, i;
1404 unsigned char md[EVP_MAX_MD_SIZE];
1405 if (X509_digest(cert, EVP_sha1(), md, &md_size)) {
1406 const char hex[] = "0123456789ABCDEF";
1407 char fingerprint[EVP_MAX_MD_SIZE * 3];
1409 // TODO(indutny): Unify it with buffer's code
1410 for (i = 0; i < md_size; i++) {
1411 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1412 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1413 fingerprint[(3*i)+2] = ':';
1417 fingerprint[(3*(md_size-1))+2] = '\0';
1419 fingerprint[0] = '\0';
1422 info->Set(env->fingerprint_string(),
1423 OneByteString(env->isolate(), fingerprint));
1426 STACK_OF(ASN1_OBJECT)* eku = static_cast<STACK_OF(ASN1_OBJECT)*>(
1427 X509_get_ext_d2i(cert, NID_ext_key_usage, nullptr, nullptr));
1428 if (eku != nullptr) {
1429 Local<Array> ext_key_usage = Array::New(env->isolate());
1433 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1434 if (OBJ_obj2txt(buf, sizeof(buf), sk_ASN1_OBJECT_value(eku, i), 1) >= 0)
1435 ext_key_usage->Set(j++, OneByteString(env->isolate(), buf));
1438 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1439 info->Set(env->ext_key_usage_string(), ext_key_usage);
1442 if (ASN1_INTEGER* serial_number = X509_get_serialNumber(cert)) {
1443 if (BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, nullptr)) {
1444 if (char* buf = BN_bn2hex(bn)) {
1445 info->Set(env->serial_number_string(),
1446 OneByteString(env->isolate(), buf));
1453 // Raw DER certificate
1454 int size = i2d_X509(cert, nullptr);
1455 Local<Object> buff = Buffer::New(env, size).ToLocalChecked();
1456 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1457 Buffer::Data(buff));
1458 i2d_X509(cert, &serialized);
1459 info->Set(env->raw_string(), buff);
1461 return scope.Escape(info);
1465 // TODO(indutny): Split it into multiple smaller functions
1466 template <class Base>
1467 void SSLWrap<Base>::GetPeerCertificate(
1468 const FunctionCallbackInfo<Value>& args) {
1469 Base* w = Unwrap<Base>(args.Holder());
1470 Environment* env = w->ssl_env();
1472 ClearErrorOnReturn clear_error_on_return;
1473 (void) &clear_error_on_return; // Silence unused variable warning.
1475 Local<Object> result;
1478 // NOTE: This is because of the odd OpenSSL behavior. On client `cert_chain`
1479 // contains the `peer_certificate`, but on server it doesn't
1480 X509* cert = w->is_server() ? SSL_get_peer_certificate(w->ssl_) : nullptr;
1481 STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(w->ssl_);
1482 STACK_OF(X509)* peer_certs = nullptr;
1483 if (cert == nullptr && ssl_certs == nullptr)
1486 if (cert == nullptr && sk_X509_num(ssl_certs) == 0)
1489 // Short result requested
1490 if (args.Length() < 1 || !args[0]->IsTrue()) {
1491 result = X509ToObject(env,
1492 cert == nullptr ? sk_X509_value(ssl_certs, 0) : cert);
1496 // Clone `ssl_certs`, because we are going to destruct it
1497 peer_certs = sk_X509_new(nullptr);
1498 if (cert != nullptr)
1499 sk_X509_push(peer_certs, cert);
1500 for (int i = 0; i < sk_X509_num(ssl_certs); i++) {
1501 cert = X509_dup(sk_X509_value(ssl_certs, i));
1502 if (cert == nullptr)
1504 if (!sk_X509_push(peer_certs, cert))
1508 // First and main certificate
1509 cert = sk_X509_value(peer_certs, 0);
1510 result = X509ToObject(env, cert);
1513 // Put issuer inside the object
1514 cert = sk_X509_delete(peer_certs, 0);
1515 while (sk_X509_num(peer_certs) > 0) {
1517 for (i = 0; i < sk_X509_num(peer_certs); i++) {
1518 X509* ca = sk_X509_value(peer_certs, i);
1519 if (X509_check_issued(ca, cert) != X509_V_OK)
1522 Local<Object> ca_info = X509ToObject(env, ca);
1523 info->Set(env->issuercert_string(), ca_info);
1526 // NOTE: Intentionally freeing cert that is not used anymore
1529 // Delete cert and continue aggregating issuers
1530 cert = sk_X509_delete(peer_certs, i);
1534 // Issuer not found, break out of the loop
1535 if (i == sk_X509_num(peer_certs))
1539 // Last certificate should be self-signed
1540 while (X509_check_issued(cert, cert) != X509_V_OK) {
1542 if (SSL_CTX_get_issuer(w->ssl_->ctx, cert, &ca) <= 0)
1545 Local<Object> ca_info = X509ToObject(env, ca);
1546 info->Set(env->issuercert_string(), ca_info);
1549 // NOTE: Intentionally freeing cert that is not used anymore
1552 // Delete cert and continue aggregating issuers
1556 // Self-issued certificate
1557 if (X509_check_issued(cert, cert) == X509_V_OK)
1558 info->Set(env->issuercert_string(), info);
1560 CHECK_NE(cert, nullptr);
1563 if (cert != nullptr)
1565 if (peer_certs != nullptr)
1566 sk_X509_pop_free(peer_certs, X509_free);
1567 if (result.IsEmpty())
1568 result = Object::New(env->isolate());
1569 args.GetReturnValue().Set(result);
1573 template <class Base>
1574 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
1575 Environment* env = Environment::GetCurrent(args);
1577 Base* w = Unwrap<Base>(args.Holder());
1579 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1580 if (sess == nullptr)
1583 int slen = i2d_SSL_SESSION(sess, nullptr);
1586 char* sbuf = new char[slen];
1587 unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1588 i2d_SSL_SESSION(sess, &p);
1589 args.GetReturnValue().Set(Encode(env->isolate(), sbuf, slen, BUFFER));
1594 template <class Base>
1595 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
1596 Environment* env = Environment::GetCurrent(args);
1598 Base* w = Unwrap<Base>(args.Holder());
1600 if (args.Length() < 1 ||
1601 (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
1602 return env->ThrowTypeError("Bad argument");
1605 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
1606 size_t slen = Buffer::Length(args[0]);
1607 char* sbuf = new char[slen];
1608 memcpy(sbuf, Buffer::Data(args[0]), slen);
1610 const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
1611 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, slen);
1615 if (sess == nullptr)
1618 int r = SSL_set_session(w->ssl_, sess);
1619 SSL_SESSION_free(sess);
1622 return env->ThrowError("SSL_set_session error");
1626 template <class Base>
1627 void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
1628 Base* w = Unwrap<Base>(args.Holder());
1629 Environment* env = w->ssl_env();
1631 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1632 ssize_t slen = Buffer::Length(args[0]);
1633 char* sbuf = Buffer::Data(args[0]);
1635 const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1636 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, slen);
1638 // Setup next session and move hello to the BIO buffer
1639 if (w->next_sess_ != nullptr)
1640 SSL_SESSION_free(w->next_sess_);
1641 w->next_sess_ = sess;
1643 Local<Object> info = Object::New(env->isolate());
1644 #ifndef OPENSSL_NO_TLSEXT
1645 if (sess->tlsext_hostname == nullptr) {
1646 info->Set(env->servername_string(), False(args.GetIsolate()));
1648 info->Set(env->servername_string(),
1649 OneByteString(args.GetIsolate(), sess->tlsext_hostname));
1652 args.GetReturnValue().Set(info);
1657 template <class Base>
1658 void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
1659 Base* w = Unwrap<Base>(args.Holder());
1660 bool yes = SSL_session_reused(w->ssl_);
1661 args.GetReturnValue().Set(yes);
1665 template <class Base>
1666 void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
1667 Base* w = Unwrap<Base>(args.Holder());
1668 w->hello_parser_.End();
1672 template <class Base>
1673 void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
1674 Base* w = Unwrap<Base>(args.Holder());
1676 ClearErrorOnReturn clear_error_on_return;
1677 (void) &clear_error_on_return; // Silence unused variable warning.
1679 bool yes = SSL_renegotiate(w->ssl_) == 1;
1680 args.GetReturnValue().Set(yes);
1684 template <class Base>
1685 void SSLWrap<Base>::Shutdown(const FunctionCallbackInfo<Value>& args) {
1686 Base* w = Unwrap<Base>(args.Holder());
1688 int rv = SSL_shutdown(w->ssl_);
1689 args.GetReturnValue().Set(rv);
1693 template <class Base>
1694 void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
1695 Base* w = Unwrap<Base>(args.Holder());
1696 Environment* env = w->ssl_env();
1698 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1699 if (sess == nullptr || sess->tlsext_tick == nullptr)
1702 Local<Object> buff = Buffer::Copy(
1704 reinterpret_cast<char*>(sess->tlsext_tick),
1705 sess->tlsext_ticklen).ToLocalChecked();
1707 args.GetReturnValue().Set(buff);
1711 template <class Base>
1712 void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
1713 Base* w = Unwrap<Base>(args.Holder());
1714 w->new_session_wait_ = false;
1715 w->NewSessionDoneCb();
1719 template <class Base>
1720 void SSLWrap<Base>::SetOCSPResponse(
1721 const v8::FunctionCallbackInfo<v8::Value>& args) {
1722 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1723 HandleScope scope(args.GetIsolate());
1725 Base* w = Unwrap<Base>(args.Holder());
1726 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1727 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1729 w->ocsp_response_.Reset(args.GetIsolate(), args[0].As<Object>());
1730 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1734 template <class Base>
1735 void SSLWrap<Base>::RequestOCSP(
1736 const v8::FunctionCallbackInfo<v8::Value>& args) {
1737 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1738 HandleScope scope(args.GetIsolate());
1740 Base* w = Unwrap<Base>(args.Holder());
1742 SSL_set_tlsext_status_type(w->ssl_, TLSEXT_STATUSTYPE_ocsp);
1743 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1747 #ifdef SSL_set_max_send_fragment
1748 template <class Base>
1749 void SSLWrap<Base>::SetMaxSendFragment(
1750 const v8::FunctionCallbackInfo<v8::Value>& args) {
1751 HandleScope scope(args.GetIsolate());
1752 CHECK(args.Length() >= 1 && args[0]->IsNumber());
1754 Base* w = Unwrap<Base>(args.Holder());
1756 int rv = SSL_set_max_send_fragment(w->ssl_, args[0]->Int32Value());
1757 args.GetReturnValue().Set(rv);
1759 #endif // SSL_set_max_send_fragment
1762 template <class Base>
1763 void SSLWrap<Base>::IsInitFinished(const FunctionCallbackInfo<Value>& args) {
1764 Base* w = Unwrap<Base>(args.Holder());
1765 bool yes = SSL_is_init_finished(w->ssl_);
1766 args.GetReturnValue().Set(yes);
1770 template <class Base>
1771 void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
1772 Base* w = Unwrap<Base>(args.Holder());
1774 // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
1775 // peer certificate is questionable but it's compatible with what was
1777 long x509_verify_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
1778 if (X509* peer_cert = SSL_get_peer_certificate(w->ssl_)) {
1779 X509_free(peer_cert);
1780 x509_verify_error = SSL_get_verify_result(w->ssl_);
1783 if (x509_verify_error == X509_V_OK)
1784 return args.GetReturnValue().SetNull();
1786 // XXX(bnoordhuis) X509_verify_cert_error_string() is not actually thread-safe
1787 // in the presence of invalid error codes. Probably academical but something
1788 // to keep in mind if/when node ever grows multi-isolate capabilities.
1789 const char* reason = X509_verify_cert_error_string(x509_verify_error);
1790 const char* code = reason;
1791 #define CASE_X509_ERR(CODE) case X509_V_ERR_##CODE: code = #CODE; break;
1792 switch (x509_verify_error) {
1793 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT)
1794 CASE_X509_ERR(UNABLE_TO_GET_CRL)
1795 CASE_X509_ERR(UNABLE_TO_DECRYPT_CERT_SIGNATURE)
1796 CASE_X509_ERR(UNABLE_TO_DECRYPT_CRL_SIGNATURE)
1797 CASE_X509_ERR(UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)
1798 CASE_X509_ERR(CERT_SIGNATURE_FAILURE)
1799 CASE_X509_ERR(CRL_SIGNATURE_FAILURE)
1800 CASE_X509_ERR(CERT_NOT_YET_VALID)
1801 CASE_X509_ERR(CERT_HAS_EXPIRED)
1802 CASE_X509_ERR(CRL_NOT_YET_VALID)
1803 CASE_X509_ERR(CRL_HAS_EXPIRED)
1804 CASE_X509_ERR(ERROR_IN_CERT_NOT_BEFORE_FIELD)
1805 CASE_X509_ERR(ERROR_IN_CERT_NOT_AFTER_FIELD)
1806 CASE_X509_ERR(ERROR_IN_CRL_LAST_UPDATE_FIELD)
1807 CASE_X509_ERR(ERROR_IN_CRL_NEXT_UPDATE_FIELD)
1808 CASE_X509_ERR(OUT_OF_MEM)
1809 CASE_X509_ERR(DEPTH_ZERO_SELF_SIGNED_CERT)
1810 CASE_X509_ERR(SELF_SIGNED_CERT_IN_CHAIN)
1811 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
1812 CASE_X509_ERR(UNABLE_TO_VERIFY_LEAF_SIGNATURE)
1813 CASE_X509_ERR(CERT_CHAIN_TOO_LONG)
1814 CASE_X509_ERR(CERT_REVOKED)
1815 CASE_X509_ERR(INVALID_CA)
1816 CASE_X509_ERR(PATH_LENGTH_EXCEEDED)
1817 CASE_X509_ERR(INVALID_PURPOSE)
1818 CASE_X509_ERR(CERT_UNTRUSTED)
1819 CASE_X509_ERR(CERT_REJECTED)
1821 #undef CASE_X509_ERR
1823 Isolate* isolate = args.GetIsolate();
1824 Local<String> reason_string = OneByteString(isolate, reason);
1825 Local<Value> exception_value = Exception::Error(reason_string);
1826 Local<Object> exception_object = exception_value->ToObject(isolate);
1827 exception_object->Set(FIXED_ONE_BYTE_STRING(isolate, "code"),
1828 OneByteString(isolate, code));
1829 args.GetReturnValue().Set(exception_object);
1833 template <class Base>
1834 void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
1835 Base* w = Unwrap<Base>(args.Holder());
1836 Environment* env = w->ssl_env();
1838 OPENSSL_CONST SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_);
1842 Local<Object> info = Object::New(env->isolate());
1843 const char* cipher_name = SSL_CIPHER_get_name(c);
1844 info->Set(env->name_string(), OneByteString(args.GetIsolate(), cipher_name));
1845 const char* cipher_version = SSL_CIPHER_get_version(c);
1846 info->Set(env->version_string(),
1847 OneByteString(args.GetIsolate(), cipher_version));
1848 args.GetReturnValue().Set(info);
1852 #ifdef OPENSSL_NPN_NEGOTIATED
1853 template <class Base>
1854 int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s,
1855 const unsigned char** data,
1858 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1859 Environment* env = w->env();
1860 HandleScope handle_scope(env->isolate());
1861 Context::Scope context_scope(env->context());
1863 if (w->npn_protos_.IsEmpty()) {
1864 // No initialization - no NPN protocols
1865 *data = reinterpret_cast<const unsigned char*>("");
1868 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1869 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1870 *len = Buffer::Length(obj);
1873 return SSL_TLSEXT_ERR_OK;
1877 template <class Base>
1878 int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
1879 unsigned char** out,
1880 unsigned char* outlen,
1881 const unsigned char* in,
1884 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1885 Environment* env = w->env();
1886 HandleScope handle_scope(env->isolate());
1887 Context::Scope context_scope(env->context());
1889 // Release old protocol handler if present
1890 w->selected_npn_proto_.Reset();
1892 if (w->npn_protos_.IsEmpty()) {
1893 // We should at least select one protocol
1894 // If server is using NPN
1895 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
1898 // set status: unsupported
1899 w->selected_npn_proto_.Reset(env->isolate(), False(env->isolate()));
1901 return SSL_TLSEXT_ERR_OK;
1904 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1905 const unsigned char* npn_protos =
1906 reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1907 size_t len = Buffer::Length(obj);
1909 int status = SSL_select_next_proto(out, outlen, in, inlen, npn_protos, len);
1910 Local<Value> result;
1912 case OPENSSL_NPN_UNSUPPORTED:
1913 result = Null(env->isolate());
1915 case OPENSSL_NPN_NEGOTIATED:
1916 result = OneByteString(env->isolate(), *out, *outlen);
1918 case OPENSSL_NPN_NO_OVERLAP:
1919 result = False(env->isolate());
1925 if (!result.IsEmpty())
1926 w->selected_npn_proto_.Reset(env->isolate(), result);
1928 return SSL_TLSEXT_ERR_OK;
1932 template <class Base>
1933 void SSLWrap<Base>::GetNegotiatedProto(
1934 const FunctionCallbackInfo<Value>& args) {
1935 Base* w = Unwrap<Base>(args.Holder());
1937 if (w->is_client()) {
1938 if (w->selected_npn_proto_.IsEmpty() == false) {
1939 args.GetReturnValue().Set(w->selected_npn_proto_);
1944 const unsigned char* npn_proto;
1945 unsigned int npn_proto_len;
1947 SSL_get0_next_proto_negotiated(w->ssl_, &npn_proto, &npn_proto_len);
1950 return args.GetReturnValue().Set(false);
1952 args.GetReturnValue().Set(
1953 OneByteString(args.GetIsolate(), npn_proto, npn_proto_len));
1957 template <class Base>
1958 void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
1959 Base* w = Unwrap<Base>(args.Holder());
1961 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1962 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1964 w->npn_protos_.Reset(args.GetIsolate(), args[0].As<Object>());
1966 #endif // OPENSSL_NPN_NEGOTIATED
1969 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1970 template <class Base>
1971 int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
1972 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1973 Environment* env = w->env();
1974 HandleScope handle_scope(env->isolate());
1976 if (w->is_client()) {
1977 // Incoming response
1978 const unsigned char* resp;
1979 int len = SSL_get_tlsext_status_ocsp_resp(s, &resp);
1981 if (resp == nullptr) {
1982 arg = Null(env->isolate());
1986 reinterpret_cast<char*>(const_cast<unsigned char*>(resp)),
1987 len).ToLocalChecked();
1990 w->MakeCallback(env->onocspresponse_string(), 1, &arg);
1992 // Somehow, client is expecting different return value here
1995 // Outgoing response
1996 if (w->ocsp_response_.IsEmpty())
1997 return SSL_TLSEXT_ERR_NOACK;
1999 Local<Object> obj = PersistentToLocal(env->isolate(), w->ocsp_response_);
2000 char* resp = Buffer::Data(obj);
2001 size_t len = Buffer::Length(obj);
2003 // OpenSSL takes control of the pointer after accepting it
2004 char* data = reinterpret_cast<char*>(malloc(len));
2005 CHECK_NE(data, nullptr);
2006 memcpy(data, resp, len);
2008 if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
2010 w->ocsp_response_.Reset();
2012 return SSL_TLSEXT_ERR_OK;
2015 #endif // NODE__HAVE_TLSEXT_STATUS_CB
2018 template <class Base>
2019 void SSLWrap<Base>::WaitForCertCb(CertCb cb, void* arg) {
2025 template <class Base>
2026 int SSLWrap<Base>::SSLCertCallback(SSL* s, void* arg) {
2027 Base* w = static_cast<Base*>(SSL_get_app_data(s));
2029 if (!w->is_server())
2032 if (!w->is_waiting_cert_cb())
2035 if (w->cert_cb_running_)
2038 Environment* env = w->env();
2039 HandleScope handle_scope(env->isolate());
2040 Context::Scope context_scope(env->context());
2041 w->cert_cb_running_ = true;
2043 Local<Object> info = Object::New(env->isolate());
2045 SSL_SESSION* sess = SSL_get_session(s);
2046 if (sess != nullptr) {
2047 if (sess->tlsext_hostname == nullptr) {
2048 info->Set(env->servername_string(), String::Empty(env->isolate()));
2050 Local<String> servername = OneByteString(env->isolate(),
2051 sess->tlsext_hostname,
2052 strlen(sess->tlsext_hostname));
2053 info->Set(env->servername_string(), servername);
2055 info->Set(env->tls_ticket_string(),
2056 Boolean::New(env->isolate(), sess->tlsext_ticklen != 0));
2058 bool ocsp = s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp;
2059 info->Set(env->ocsp_request_string(), Boolean::New(env->isolate(), ocsp));
2061 Local<Value> argv[] = { info };
2062 w->MakeCallback(env->oncertcb_string(), ARRAY_SIZE(argv), argv);
2064 if (!w->cert_cb_running_)
2067 // Performing async action, wait...
2072 template <class Base>
2073 void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
2074 Base* w = Unwrap<Base>(args.Holder());
2075 Environment* env = w->env();
2077 CHECK(w->is_waiting_cert_cb() && w->cert_cb_running_);
2079 Local<Object> object = w->object();
2080 Local<Value> ctx = object->Get(env->sni_context_string());
2081 Local<FunctionTemplate> cons = env->secure_context_constructor_template();
2083 // Not an object, probably undefined or null
2084 if (!ctx->IsObject())
2087 if (cons->HasInstance(ctx)) {
2088 SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
2089 w->sni_context_.Reset();
2090 w->sni_context_.Reset(env->isolate(), ctx);
2094 // NOTE: reference count is not increased by this API methods
2095 X509* x509 = SSL_CTX_get0_certificate(sc->ctx_);
2096 EVP_PKEY* pkey = SSL_CTX_get0_privatekey(sc->ctx_);
2097 STACK_OF(X509)* chain;
2099 rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain);
2101 rv = SSL_use_certificate(w->ssl_, x509);
2103 rv = SSL_use_PrivateKey(w->ssl_, pkey);
2104 if (rv && chain != nullptr)
2105 rv = SSL_set1_chain(w->ssl_, chain);
2107 unsigned long err = ERR_get_error();
2109 return env->ThrowError("CertCbDone");
2110 return ThrowCryptoError(env, err);
2113 // Failure: incorrect SNI context object
2114 Local<Value> err = Exception::TypeError(env->sni_context_err_string());
2115 w->MakeCallback(env->onerror_string(), 1, &err);
2124 arg = w->cert_cb_arg_;
2126 w->cert_cb_running_ = false;
2127 w->cert_cb_ = nullptr;
2128 w->cert_cb_arg_ = nullptr;
2134 template <class Base>
2135 void SSLWrap<Base>::SSLGetter(Local<String> property,
2136 const PropertyCallbackInfo<Value>& info) {
2137 HandleScope scope(info.GetIsolate());
2139 SSL* ssl = Unwrap<Base>(info.Holder())->ssl_;
2140 Local<External> ext = External::New(info.GetIsolate(), ssl);
2141 info.GetReturnValue().Set(ext);
2145 template <class Base>
2146 void SSLWrap<Base>::DestroySSL() {
2147 if (ssl_ == nullptr)
2151 env_->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
2156 void Connection::OnClientHelloParseEnd(void* arg) {
2157 Connection* conn = static_cast<Connection*>(arg);
2159 // Write all accumulated data
2160 int r = BIO_write(conn->bio_read_,
2161 reinterpret_cast<char*>(conn->hello_data_),
2162 conn->hello_offset_);
2163 conn->HandleBIOError(conn->bio_read_, "BIO_write", r);
2164 conn->SetShutdownFlags();
2168 #ifdef SSL_PRINT_DEBUG
2169 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
2171 # define DEBUG_PRINT(...)
2175 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
2179 int retry = BIO_should_retry(bio);
2180 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
2182 if (BIO_should_write(bio)) {
2183 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n",
2189 } else if (BIO_should_read(bio)) {
2190 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
2194 char ssl_error_buf[512];
2195 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
2197 HandleScope scope(ssl_env()->isolate());
2198 Local<Value> exception =
2199 Exception::Error(OneByteString(ssl_env()->isolate(), ssl_error_buf));
2200 object()->Set(ssl_env()->error_string(), exception);
2202 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
2215 int Connection::HandleSSLError(const char* func,
2219 ClearErrorOnReturn clear_error_on_return;
2220 (void) &clear_error_on_return; // Silence unused variable warning.
2224 if (rv == 0 && zs == kZeroIsNotAnError)
2227 int err = SSL_get_error(ssl_, rv);
2229 if (err == SSL_ERROR_NONE) {
2232 } else if (err == SSL_ERROR_WANT_WRITE) {
2233 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
2236 } else if (err == SSL_ERROR_WANT_READ) {
2237 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
2240 } else if (err == SSL_ERROR_WANT_X509_LOOKUP) {
2241 DEBUG_PRINT("[%p] SSL: %s want x509 lookup\n", ssl_, func);
2244 } else if (err == SSL_ERROR_ZERO_RETURN) {
2245 HandleScope scope(ssl_env()->isolate());
2247 Local<Value> exception =
2248 Exception::Error(ssl_env()->zero_return_string());
2249 object()->Set(ssl_env()->error_string(), exception);
2252 } else if (err == SSL_ERROR_SYSCALL && ss == kIgnoreSyscall) {
2256 HandleScope scope(ssl_env()->isolate());
2260 CHECK(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
2262 // XXX We need to drain the error queue for this thread or else OpenSSL
2263 // has the possibility of blocking connections? This problem is not well
2264 // understood. And we should be somehow propagating these errors up
2265 // into JavaScript. There is no test which demonstrates this problem.
2266 // https://github.com/joyent/node/issues/1719
2267 bio = BIO_new(BIO_s_mem());
2268 if (bio != nullptr) {
2269 ERR_print_errors(bio);
2270 BIO_get_mem_ptr(bio, &mem);
2271 Local<Value> exception = Exception::Error(
2272 OneByteString(ssl_env()->isolate(),
2275 object()->Set(ssl_env()->error_string(), exception);
2286 void Connection::ClearError() {
2288 HandleScope scope(ssl_env()->isolate());
2290 // We should clear the error in JS-land
2291 Local<String> error_key = ssl_env()->error_string();
2292 Local<Value> error = object()->Get(error_key);
2293 CHECK_EQ(error->BooleanValue(), false);
2298 void Connection::SetShutdownFlags() {
2299 HandleScope scope(ssl_env()->isolate());
2301 int flags = SSL_get_shutdown(ssl_);
2303 if (flags & SSL_SENT_SHUTDOWN) {
2304 Local<String> sent_shutdown_key = ssl_env()->sent_shutdown_string();
2305 object()->Set(sent_shutdown_key, True(ssl_env()->isolate()));
2308 if (flags & SSL_RECEIVED_SHUTDOWN) {
2309 Local<String> received_shutdown_key = ssl_env()->received_shutdown_string();
2310 object()->Set(received_shutdown_key, True(ssl_env()->isolate()));
2315 void Connection::NewSessionDoneCb() {
2316 HandleScope scope(env()->isolate());
2318 MakeCallback(env()->onnewsessiondone_string(), 0, nullptr);
2322 void Connection::Initialize(Environment* env, Local<Object> target) {
2323 Local<FunctionTemplate> t = env->NewFunctionTemplate(Connection::New);
2324 t->InstanceTemplate()->SetInternalFieldCount(1);
2325 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"));
2327 env->SetProtoMethod(t, "encIn", Connection::EncIn);
2328 env->SetProtoMethod(t, "clearOut", Connection::ClearOut);
2329 env->SetProtoMethod(t, "clearIn", Connection::ClearIn);
2330 env->SetProtoMethod(t, "encOut", Connection::EncOut);
2331 env->SetProtoMethod(t, "clearPending", Connection::ClearPending);
2332 env->SetProtoMethod(t, "encPending", Connection::EncPending);
2333 env->SetProtoMethod(t, "start", Connection::Start);
2334 env->SetProtoMethod(t, "close", Connection::Close);
2336 SSLWrap<Connection>::AddMethods(env, t);
2339 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2340 env->SetProtoMethod(t, "getServername", Connection::GetServername);
2341 env->SetProtoMethod(t, "setSNICallback", Connection::SetSNICallback);
2344 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"),
2349 inline int compar(const void* a, const void* b) {
2350 return memcmp(a, b, CNNIC_WHITELIST_HASH_LEN);
2354 inline int IsSelfSigned(X509* cert) {
2355 return X509_NAME_cmp(X509_get_subject_name(cert),
2356 X509_get_issuer_name(cert)) == 0;
2360 inline X509* FindRoot(STACK_OF(X509)* sk) {
2361 for (int i = 0; i < sk_X509_num(sk); i++) {
2362 X509* cert = sk_X509_value(sk, i);
2363 if (IsSelfSigned(cert))
2370 // Whitelist check for certs issued by CNNIC. See
2371 // https://blog.mozilla.org/security/2015/04/02
2372 // /distrusting-new-cnnic-certificates/
2373 inline CheckResult CheckWhitelistedServerCert(X509_STORE_CTX* ctx) {
2374 unsigned char hash[CNNIC_WHITELIST_HASH_LEN];
2375 unsigned int hashlen = CNNIC_WHITELIST_HASH_LEN;
2377 STACK_OF(X509)* chain = X509_STORE_CTX_get1_chain(ctx);
2378 CHECK_NE(chain, nullptr);
2379 CHECK_GT(sk_X509_num(chain), 0);
2381 // Take the last cert as root at the first time.
2382 X509* root_cert = sk_X509_value(chain, sk_X509_num(chain)-1);
2383 X509_NAME* root_name = X509_get_subject_name(root_cert);
2385 if (!IsSelfSigned(root_cert)) {
2386 root_cert = FindRoot(chain);
2387 CHECK_NE(root_cert, nullptr);
2388 root_name = X509_get_subject_name(root_cert);
2391 // When the cert is issued from either CNNNIC ROOT CA or CNNNIC EV
2392 // ROOT CA, check a hash of its leaf cert if it is in the whitelist.
2393 if (X509_NAME_cmp(root_name, cnnic_name) == 0 ||
2394 X509_NAME_cmp(root_name, cnnic_ev_name) == 0) {
2395 X509* leaf_cert = sk_X509_value(chain, 0);
2396 int ret = X509_digest(leaf_cert, EVP_sha256(), hash,
2400 void* result = bsearch(hash, WhitelistedCNNICHashes,
2401 ARRAY_SIZE(WhitelistedCNNICHashes),
2402 CNNIC_WHITELIST_HASH_LEN, compar);
2403 if (result == nullptr) {
2404 sk_X509_pop_free(chain, X509_free);
2405 return CHECK_CERT_REVOKED;
2409 sk_X509_pop_free(chain, X509_free);
2414 inline int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
2415 // Failure on verification of the cert is handled in
2416 // Connection::VerifyError.
2417 if (preverify_ok == 0 || X509_STORE_CTX_get_error(ctx) != X509_V_OK)
2420 // Server does not need to check the whitelist.
2421 SSL* ssl = static_cast<SSL*>(
2422 X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
2424 if (SSL_is_server(ssl))
2427 // Client needs to check if the server cert is listed in the
2428 // whitelist when it is issued by the specific rootCAs.
2429 CheckResult ret = CheckWhitelistedServerCert(ctx);
2430 if (ret == CHECK_CERT_REVOKED)
2431 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
2437 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2438 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
2439 Connection* conn = static_cast<Connection*>(SSL_get_app_data(s));
2440 Environment* env = conn->env();
2441 HandleScope scope(env->isolate());
2443 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
2446 conn->servername_.Reset(env->isolate(),
2447 OneByteString(env->isolate(), servername));
2449 // Call the SNI callback and use its return value as context
2450 if (!conn->sniObject_.IsEmpty()) {
2451 conn->sni_context_.Reset();
2453 Local<Object> sni_obj = PersistentToLocal(env->isolate(),
2456 Local<Value> arg = PersistentToLocal(env->isolate(), conn->servername_);
2457 Local<Value> ret = node::MakeCallback(env->isolate(),
2459 env->onselect_string(),
2463 // If ret is SecureContext
2464 Local<FunctionTemplate> secure_context_constructor_template =
2465 env->secure_context_constructor_template();
2466 if (secure_context_constructor_template->HasInstance(ret)) {
2467 conn->sni_context_.Reset(env->isolate(), ret);
2468 SecureContext* sc = Unwrap<SecureContext>(ret.As<Object>());
2470 SSL_set_SSL_CTX(s, sc->ctx_);
2472 return SSL_TLSEXT_ERR_NOACK;
2477 return SSL_TLSEXT_ERR_OK;
2481 void Connection::New(const FunctionCallbackInfo<Value>& args) {
2482 Environment* env = Environment::GetCurrent(args);
2484 if (args.Length() < 1 || !args[0]->IsObject()) {
2485 env->ThrowError("First argument must be a tls module SecureContext");
2489 SecureContext* sc = Unwrap<SecureContext>(args[0]->ToObject(env->isolate()));
2491 bool is_server = args[1]->BooleanValue();
2493 SSLWrap<Connection>::Kind kind =
2494 is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient;
2495 Connection* conn = new Connection(env, args.This(), sc, kind);
2496 conn->bio_read_ = NodeBIO::New();
2497 conn->bio_write_ = NodeBIO::New();
2499 SSL_set_app_data(conn->ssl_, conn);
2502 SSL_set_info_callback(conn->ssl_, SSLInfoCallback);
2506 SSL_set_cert_cb(conn->ssl_, SSLWrap<Connection>::SSLCertCallback, conn);
2508 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2510 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
2511 } else if (args[2]->IsString()) {
2512 const node::Utf8Value servername(env->isolate(), args[2]);
2513 SSL_set_tlsext_host_name(conn->ssl_, *servername);
2517 SSL_set_bio(conn->ssl_, conn->bio_read_, conn->bio_write_);
2519 #ifdef SSL_MODE_RELEASE_BUFFERS
2520 long mode = SSL_get_mode(conn->ssl_);
2521 SSL_set_mode(conn->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
2527 bool request_cert = args[2]->BooleanValue();
2528 if (!request_cert) {
2529 // Note reject_unauthorized ignored.
2530 verify_mode = SSL_VERIFY_NONE;
2532 bool reject_unauthorized = args[3]->BooleanValue();
2533 verify_mode = SSL_VERIFY_PEER;
2534 if (reject_unauthorized)
2535 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2538 // Note request_cert and reject_unauthorized are ignored for clients.
2539 verify_mode = SSL_VERIFY_NONE;
2543 // Always allow a connection. We'll reject in javascript.
2544 SSL_set_verify(conn->ssl_, verify_mode, VerifyCallback);
2547 SSL_set_accept_state(conn->ssl_);
2549 SSL_set_connect_state(conn->ssl_);
2554 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
2555 if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
2558 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
2559 // a non-const SSL* in OpenSSL <= 0.9.7e.
2560 SSL* ssl = const_cast<SSL*>(ssl_);
2561 Connection* conn = static_cast<Connection*>(SSL_get_app_data(ssl));
2562 Environment* env = conn->env();
2563 HandleScope handle_scope(env->isolate());
2564 Context::Scope context_scope(env->context());
2566 if (where & SSL_CB_HANDSHAKE_START) {
2567 conn->MakeCallback(env->onhandshakestart_string(), 0, nullptr);
2570 if (where & SSL_CB_HANDSHAKE_DONE) {
2571 conn->MakeCallback(env->onhandshakedone_string(), 0, nullptr);
2576 void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
2577 Connection* conn = Unwrap<Connection>(args.Holder());
2578 Environment* env = conn->env();
2580 if (args.Length() < 3) {
2581 return env->ThrowTypeError("Takes 3 parameters");
2584 if (!Buffer::HasInstance(args[0])) {
2585 return env->ThrowTypeError("Second argument should be a buffer");
2588 char* buffer_data = Buffer::Data(args[0]);
2589 size_t buffer_length = Buffer::Length(args[0]);
2591 size_t off = args[1]->Int32Value();
2592 size_t len = args[2]->Int32Value();
2594 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2595 return env->ThrowError("off + len > buffer.length");
2598 char* data = buffer_data + off;
2600 if (conn->is_server() && !conn->hello_parser_.IsEnded()) {
2601 // Just accumulate data, everything will be pushed to BIO later
2602 if (conn->hello_parser_.IsPaused()) {
2605 // Copy incoming data to the internal buffer
2606 // (which has a size of the biggest possible TLS frame)
2607 size_t available = sizeof(conn->hello_data_) - conn->hello_offset_;
2608 size_t copied = len < available ? len : available;
2609 memcpy(conn->hello_data_ + conn->hello_offset_, data, copied);
2610 conn->hello_offset_ += copied;
2612 conn->hello_parser_.Parse(conn->hello_data_, conn->hello_offset_);
2613 bytes_written = copied;
2616 bytes_written = BIO_write(conn->bio_read_, data, len);
2617 conn->HandleBIOError(conn->bio_read_, "BIO_write", bytes_written);
2618 conn->SetShutdownFlags();
2621 args.GetReturnValue().Set(bytes_written);
2625 void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
2626 Connection* conn = Unwrap<Connection>(args.Holder());
2627 Environment* env = conn->env();
2629 if (args.Length() < 3) {
2630 return env->ThrowTypeError("Takes 3 parameters");
2633 if (!Buffer::HasInstance(args[0])) {
2634 return env->ThrowTypeError("Second argument should be a buffer");
2637 char* buffer_data = Buffer::Data(args[0]);
2638 size_t buffer_length = Buffer::Length(args[0]);
2640 size_t off = args[1]->Int32Value();
2641 size_t len = args[2]->Int32Value();
2643 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2644 return env->ThrowError("off + len > buffer.length");
2646 if (!SSL_is_init_finished(conn->ssl_)) {
2649 if (conn->is_server()) {
2650 rv = SSL_accept(conn->ssl_);
2651 conn->HandleSSLError("SSL_accept:ClearOut",
2656 rv = SSL_connect(conn->ssl_);
2657 conn->HandleSSLError("SSL_connect:ClearOut",
2664 return args.GetReturnValue().Set(rv);
2668 int bytes_read = SSL_read(conn->ssl_, buffer_data + off, len);
2669 conn->HandleSSLError("SSL_read:ClearOut",
2673 conn->SetShutdownFlags();
2675 args.GetReturnValue().Set(bytes_read);
2679 void Connection::ClearPending(const FunctionCallbackInfo<Value>& args) {
2680 Connection* conn = Unwrap<Connection>(args.Holder());
2681 int bytes_pending = BIO_pending(conn->bio_read_);
2682 args.GetReturnValue().Set(bytes_pending);
2686 void Connection::EncPending(const FunctionCallbackInfo<Value>& args) {
2687 Connection* conn = Unwrap<Connection>(args.Holder());
2688 int bytes_pending = BIO_pending(conn->bio_write_);
2689 args.GetReturnValue().Set(bytes_pending);
2693 void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
2694 Connection* conn = Unwrap<Connection>(args.Holder());
2695 Environment* env = conn->env();
2697 if (args.Length() < 3) {
2698 return env->ThrowTypeError("Takes 3 parameters");
2701 if (!Buffer::HasInstance(args[0])) {
2702 return env->ThrowTypeError("Second argument should be a buffer");
2705 char* buffer_data = Buffer::Data(args[0]);
2706 size_t buffer_length = Buffer::Length(args[0]);
2708 size_t off = args[1]->Int32Value();
2709 size_t len = args[2]->Int32Value();
2711 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2712 return env->ThrowError("off + len > buffer.length");
2714 int bytes_read = BIO_read(conn->bio_write_, buffer_data + off, len);
2716 conn->HandleBIOError(conn->bio_write_, "BIO_read:EncOut", bytes_read);
2717 conn->SetShutdownFlags();
2719 args.GetReturnValue().Set(bytes_read);
2723 void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
2724 Connection* conn = Unwrap<Connection>(args.Holder());
2725 Environment* env = conn->env();
2727 if (args.Length() < 3) {
2728 return env->ThrowTypeError("Takes 3 parameters");
2731 if (!Buffer::HasInstance(args[0])) {
2732 return env->ThrowTypeError("Second argument should be a buffer");
2735 char* buffer_data = Buffer::Data(args[0]);
2736 size_t buffer_length = Buffer::Length(args[0]);
2738 size_t off = args[1]->Int32Value();
2739 size_t len = args[2]->Int32Value();
2741 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2742 return env->ThrowError("off + len > buffer.length");
2744 if (!SSL_is_init_finished(conn->ssl_)) {
2746 if (conn->is_server()) {
2747 rv = SSL_accept(conn->ssl_);
2748 conn->HandleSSLError("SSL_accept:ClearIn",
2753 rv = SSL_connect(conn->ssl_);
2754 conn->HandleSSLError("SSL_connect:ClearIn",
2761 return args.GetReturnValue().Set(rv);
2765 int bytes_written = SSL_write(conn->ssl_, buffer_data + off, len);
2767 conn->HandleSSLError("SSL_write:ClearIn",
2769 len == 0 ? kZeroIsNotAnError : kZeroIsAnError,
2771 conn->SetShutdownFlags();
2773 args.GetReturnValue().Set(bytes_written);
2777 void Connection::Start(const FunctionCallbackInfo<Value>& args) {
2778 Connection* conn = Unwrap<Connection>(args.Holder());
2781 if (!SSL_is_init_finished(conn->ssl_)) {
2782 if (conn->is_server()) {
2783 rv = SSL_accept(conn->ssl_);
2784 conn->HandleSSLError("SSL_accept:Start",
2789 rv = SSL_connect(conn->ssl_);
2790 conn->HandleSSLError("SSL_connect:Start",
2796 args.GetReturnValue().Set(rv);
2800 void Connection::Close(const FunctionCallbackInfo<Value>& args) {
2801 Connection* conn = Unwrap<Connection>(args.Holder());
2803 if (conn->ssl_ != nullptr) {
2804 SSL_free(conn->ssl_);
2805 conn->ssl_ = nullptr;
2810 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2811 void Connection::GetServername(const FunctionCallbackInfo<Value>& args) {
2812 Connection* conn = Unwrap<Connection>(args.Holder());
2814 if (conn->is_server() && !conn->servername_.IsEmpty()) {
2815 args.GetReturnValue().Set(conn->servername_);
2817 args.GetReturnValue().Set(false);
2822 void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) {
2823 Connection* conn = Unwrap<Connection>(args.Holder());
2824 Environment* env = conn->env();
2826 if (args.Length() < 1 || !args[0]->IsFunction()) {
2827 return env->ThrowError("Must give a Function as first argument");
2830 Local<Object> obj = Object::New(env->isolate());
2831 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "onselect"), args[0]);
2832 conn->sniObject_.Reset(args.GetIsolate(), obj);
2837 void CipherBase::Initialize(Environment* env, Local<Object> target) {
2838 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
2840 t->InstanceTemplate()->SetInternalFieldCount(1);
2842 env->SetProtoMethod(t, "init", Init);
2843 env->SetProtoMethod(t, "initiv", InitIv);
2844 env->SetProtoMethod(t, "update", Update);
2845 env->SetProtoMethod(t, "final", Final);
2846 env->SetProtoMethod(t, "setAutoPadding", SetAutoPadding);
2847 env->SetProtoMethod(t, "getAuthTag", GetAuthTag);
2848 env->SetProtoMethod(t, "setAuthTag", SetAuthTag);
2849 env->SetProtoMethod(t, "setAAD", SetAAD);
2851 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "CipherBase"),
2856 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
2857 CHECK_EQ(args.IsConstructCall(), true);
2858 CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
2859 Environment* env = Environment::GetCurrent(args);
2860 new CipherBase(env, args.This(), kind);
2864 void CipherBase::Init(const char* cipher_type,
2865 const char* key_buf,
2867 HandleScope scope(env()->isolate());
2869 CHECK_EQ(cipher_, nullptr);
2870 cipher_ = EVP_get_cipherbyname(cipher_type);
2871 if (cipher_ == nullptr) {
2872 return env()->ThrowError("Unknown cipher");
2875 unsigned char key[EVP_MAX_KEY_LENGTH];
2876 unsigned char iv[EVP_MAX_IV_LENGTH];
2878 int key_len = EVP_BytesToKey(cipher_,
2881 reinterpret_cast<const unsigned char*>(key_buf),
2887 EVP_CIPHER_CTX_init(&ctx_);
2888 const bool encrypt = (kind_ == kCipher);
2889 EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
2890 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2891 EVP_CIPHER_CTX_cleanup(&ctx_);
2892 return env()->ThrowError("Invalid key length");
2895 EVP_CipherInit_ex(&ctx_,
2898 reinterpret_cast<unsigned char*>(key),
2899 reinterpret_cast<unsigned char*>(iv),
2901 initialised_ = true;
2905 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
2906 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2908 if (args.Length() < 2 ||
2909 !(args[0]->IsString() && Buffer::HasInstance(args[1]))) {
2910 return cipher->env()->ThrowError("Must give cipher-type, key");
2913 const node::Utf8Value cipher_type(args.GetIsolate(), args[0]);
2914 const char* key_buf = Buffer::Data(args[1]);
2915 ssize_t key_buf_len = Buffer::Length(args[1]);
2916 cipher->Init(*cipher_type, key_buf, key_buf_len);
2920 void CipherBase::InitIv(const char* cipher_type,
2925 HandleScope scope(env()->isolate());
2927 cipher_ = EVP_get_cipherbyname(cipher_type);
2928 if (cipher_ == nullptr) {
2929 return env()->ThrowError("Unknown cipher");
2932 /* OpenSSL versions up to 0.9.8l failed to return the correct
2933 iv_length (0) for ECB ciphers */
2934 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
2935 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2936 return env()->ThrowError("Invalid IV length");
2938 EVP_CIPHER_CTX_init(&ctx_);
2939 const bool encrypt = (kind_ == kCipher);
2940 EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
2941 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2942 EVP_CIPHER_CTX_cleanup(&ctx_);
2943 return env()->ThrowError("Invalid key length");
2946 EVP_CipherInit_ex(&ctx_,
2949 reinterpret_cast<const unsigned char*>(key),
2950 reinterpret_cast<const unsigned char*>(iv),
2952 initialised_ = true;
2956 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
2957 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2958 Environment* env = cipher->env();
2960 if (args.Length() < 3 || !args[0]->IsString()) {
2961 return env->ThrowError("Must give cipher-type, key, and iv as argument");
2964 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
2965 THROW_AND_RETURN_IF_NOT_BUFFER(args[2]);
2967 const node::Utf8Value cipher_type(env->isolate(), args[0]);
2968 ssize_t key_len = Buffer::Length(args[1]);
2969 const char* key_buf = Buffer::Data(args[1]);
2970 ssize_t iv_len = Buffer::Length(args[2]);
2971 const char* iv_buf = Buffer::Data(args[2]);
2972 cipher->InitIv(*cipher_type, key_buf, key_len, iv_buf, iv_len);
2976 bool CipherBase::IsAuthenticatedMode() const {
2977 // check if this cipher operates in an AEAD mode that we support.
2980 int mode = EVP_CIPHER_mode(cipher_);
2981 return mode == EVP_CIPH_GCM_MODE;
2985 bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
2986 // only callable after Final and if encrypting.
2987 if (initialised_ || kind_ != kCipher || !auth_tag_)
2989 *out_len = auth_tag_len_;
2990 *out = static_cast<char*>(malloc(auth_tag_len_));
2991 CHECK_NE(*out, nullptr);
2992 memcpy(*out, auth_tag_, auth_tag_len_);
2997 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
2998 Environment* env = Environment::GetCurrent(args);
2999 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3001 char* out = nullptr;
3002 unsigned int out_len = 0;
3004 if (cipher->GetAuthTag(&out, &out_len)) {
3005 Local<Object> buf = Buffer::New(env, out, out_len).ToLocalChecked();
3006 args.GetReturnValue().Set(buf);
3008 env->ThrowError("Attempting to get auth tag in unsupported state");
3013 bool CipherBase::SetAuthTag(const char* data, unsigned int len) {
3014 if (!initialised_ || !IsAuthenticatedMode() || kind_ != kDecipher)
3017 auth_tag_len_ = len;
3018 auth_tag_ = new char[len];
3019 memcpy(auth_tag_, data, len);
3024 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
3025 Environment* env = Environment::GetCurrent(args);
3027 Local<Object> buf = args[0].As<Object>();
3028 if (!buf->IsObject() || !Buffer::HasInstance(buf))
3029 return env->ThrowTypeError("Argument must be a Buffer");
3031 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3033 if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf)))
3034 env->ThrowError("Attempting to set auth tag in unsupported state");
3038 bool CipherBase::SetAAD(const char* data, unsigned int len) {
3039 if (!initialised_ || !IsAuthenticatedMode())
3042 if (!EVP_CipherUpdate(&ctx_,
3045 reinterpret_cast<const unsigned char*>(data),
3053 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
3054 Environment* env = Environment::GetCurrent(args);
3056 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3058 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3060 if (!cipher->SetAAD(Buffer::Data(args[0]), Buffer::Length(args[0])))
3061 env->ThrowError("Attempting to set AAD in unsupported state");
3065 bool CipherBase::Update(const char* data,
3067 unsigned char** out,
3073 if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_ != nullptr) {
3074 EVP_CIPHER_CTX_ctrl(&ctx_,
3075 EVP_CTRL_GCM_SET_TAG,
3077 reinterpret_cast<unsigned char*>(auth_tag_));
3079 auth_tag_ = nullptr;
3082 *out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
3083 *out = new unsigned char[*out_len];
3084 return EVP_CipherUpdate(&ctx_,
3087 reinterpret_cast<const unsigned char*>(data),
3092 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
3093 Environment* env = Environment::GetCurrent(args);
3095 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3097 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3099 unsigned char* out = nullptr;
3103 // Only copy the data if we have to, because it's a string
3104 if (args[0]->IsString()) {
3105 StringBytes::InlineDecoder decoder;
3106 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3108 r = cipher->Update(decoder.out(), decoder.size(), &out, &out_len);
3110 char* buf = Buffer::Data(args[0]);
3111 size_t buflen = Buffer::Length(args[0]);
3112 r = cipher->Update(buf, buflen, &out, &out_len);
3117 return ThrowCryptoError(env,
3119 "Trying to add data in unsupported state");
3122 CHECK(out != nullptr || out_len == 0);
3124 Buffer::Copy(env, reinterpret_cast<char*>(out), out_len).ToLocalChecked();
3128 args.GetReturnValue().Set(buf);
3132 bool CipherBase::SetAutoPadding(bool auto_padding) {
3135 return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
3139 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
3140 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3141 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
3145 bool CipherBase::Final(unsigned char** out, int *out_len) {
3149 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx_)];
3150 int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
3152 if (r && kind_ == kCipher) {
3154 auth_tag_ = nullptr;
3155 if (IsAuthenticatedMode()) {
3156 auth_tag_len_ = EVP_GCM_TLS_TAG_LEN; // use default tag length
3157 auth_tag_ = new char[auth_tag_len_];
3158 memset(auth_tag_, 0, auth_tag_len_);
3159 EVP_CIPHER_CTX_ctrl(&ctx_,
3160 EVP_CTRL_GCM_GET_TAG,
3162 reinterpret_cast<unsigned char*>(auth_tag_));
3166 EVP_CIPHER_CTX_cleanup(&ctx_);
3167 initialised_ = false;
3173 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
3174 Environment* env = Environment::GetCurrent(args);
3176 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3178 unsigned char* out_value = nullptr;
3180 Local<Value> outString;
3182 bool r = cipher->Final(&out_value, &out_len);
3184 if (out_len <= 0 || !r) {
3186 out_value = nullptr;
3189 const char* msg = cipher->IsAuthenticatedMode() ?
3190 "Unsupported state or unable to authenticate data" :
3191 "Unsupported state";
3193 return ThrowCryptoError(env,
3199 Local<Object> buf = Buffer::Copy(
3201 reinterpret_cast<char*>(out_value),
3202 out_len).ToLocalChecked();
3203 args.GetReturnValue().Set(buf);
3208 void Hmac::Initialize(Environment* env, v8::Local<v8::Object> target) {
3209 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3211 t->InstanceTemplate()->SetInternalFieldCount(1);
3213 env->SetProtoMethod(t, "init", HmacInit);
3214 env->SetProtoMethod(t, "update", HmacUpdate);
3215 env->SetProtoMethod(t, "digest", HmacDigest);
3217 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hmac"), t->GetFunction());
3221 void Hmac::New(const FunctionCallbackInfo<Value>& args) {
3222 Environment* env = Environment::GetCurrent(args);
3223 new Hmac(env, args.This());
3227 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
3228 HandleScope scope(env()->isolate());
3230 CHECK_EQ(md_, nullptr);
3231 md_ = EVP_get_digestbyname(hash_type);
3232 if (md_ == nullptr) {
3233 return env()->ThrowError("Unknown message digest");
3235 HMAC_CTX_init(&ctx_);
3237 HMAC_Init(&ctx_, "", 0, md_);
3239 HMAC_Init(&ctx_, key, key_len, md_);
3241 initialised_ = true;
3245 void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
3246 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3247 Environment* env = hmac->env();
3249 if (args.Length() < 2 || !args[0]->IsString()) {
3250 return env->ThrowError("Must give hashtype string, key as arguments");
3253 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
3255 const node::Utf8Value hash_type(env->isolate(), args[0]);
3256 const char* buffer_data = Buffer::Data(args[1]);
3257 size_t buffer_length = Buffer::Length(args[1]);
3258 hmac->HmacInit(*hash_type, buffer_data, buffer_length);
3262 bool Hmac::HmacUpdate(const char* data, int len) {
3265 HMAC_Update(&ctx_, reinterpret_cast<const unsigned char*>(data), len);
3270 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
3271 Environment* env = Environment::GetCurrent(args);
3273 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3275 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3277 // Only copy the data if we have to, because it's a string
3279 if (args[0]->IsString()) {
3280 StringBytes::InlineDecoder decoder;
3281 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3283 r = hmac->HmacUpdate(decoder.out(), decoder.size());
3285 char* buf = Buffer::Data(args[0]);
3286 size_t buflen = Buffer::Length(args[0]);
3287 r = hmac->HmacUpdate(buf, buflen);
3291 return env->ThrowTypeError("HmacUpdate fail");
3296 bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
3299 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
3300 HMAC_Final(&ctx_, *md_value, md_len);
3301 HMAC_CTX_cleanup(&ctx_);
3302 initialised_ = false;
3307 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
3308 Environment* env = Environment::GetCurrent(args);
3310 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3312 enum encoding encoding = BUFFER;
3313 if (args.Length() >= 1) {
3314 encoding = ParseEncoding(env->isolate(),
3315 args[0]->ToString(env->isolate()),
3319 unsigned char* md_value = nullptr;
3320 unsigned int md_len = 0;
3322 bool r = hmac->HmacDigest(&md_value, &md_len);
3328 Local<Value> rc = StringBytes::Encode(env->isolate(),
3329 reinterpret_cast<const char*>(md_value),
3333 args.GetReturnValue().Set(rc);
3337 void Hash::Initialize(Environment* env, v8::Local<v8::Object> target) {
3338 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3340 t->InstanceTemplate()->SetInternalFieldCount(1);
3342 env->SetProtoMethod(t, "update", HashUpdate);
3343 env->SetProtoMethod(t, "digest", HashDigest);
3345 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hash"), t->GetFunction());
3349 void Hash::New(const FunctionCallbackInfo<Value>& args) {
3350 Environment* env = Environment::GetCurrent(args);
3352 if (args.Length() == 0 || !args[0]->IsString()) {
3353 return env->ThrowError("Must give hashtype string as argument");
3356 const node::Utf8Value hash_type(env->isolate(), args[0]);
3358 Hash* hash = new Hash(env, args.This());
3359 if (!hash->HashInit(*hash_type)) {
3360 return env->ThrowError("Digest method not supported");
3365 bool Hash::HashInit(const char* hash_type) {
3366 CHECK_EQ(md_, nullptr);
3367 md_ = EVP_get_digestbyname(hash_type);
3370 EVP_MD_CTX_init(&mdctx_);
3371 EVP_DigestInit_ex(&mdctx_, md_, nullptr);
3372 initialised_ = true;
3377 bool Hash::HashUpdate(const char* data, int len) {
3380 EVP_DigestUpdate(&mdctx_, data, len);
3385 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
3386 Environment* env = Environment::GetCurrent(args);
3388 Hash* hash = Unwrap<Hash>(args.Holder());
3390 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3392 // Only copy the data if we have to, because it's a string
3394 if (args[0]->IsString()) {
3395 StringBytes::InlineDecoder decoder;
3396 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3398 r = hash->HashUpdate(decoder.out(), decoder.size());
3400 char* buf = Buffer::Data(args[0]);
3401 size_t buflen = Buffer::Length(args[0]);
3402 r = hash->HashUpdate(buf, buflen);
3406 return env->ThrowTypeError("HashUpdate fail");
3411 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
3412 Environment* env = Environment::GetCurrent(args);
3414 Hash* hash = Unwrap<Hash>(args.Holder());
3416 if (!hash->initialised_) {
3417 return env->ThrowError("Not initialized");
3420 enum encoding encoding = BUFFER;
3421 if (args.Length() >= 1) {
3422 encoding = ParseEncoding(env->isolate(),
3423 args[0]->ToString(env->isolate()),
3427 unsigned char md_value[EVP_MAX_MD_SIZE];
3428 unsigned int md_len;
3430 EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len);
3431 EVP_MD_CTX_cleanup(&hash->mdctx_);
3432 hash->initialised_ = false;
3434 Local<Value> rc = StringBytes::Encode(env->isolate(),
3435 reinterpret_cast<const char*>(md_value),
3438 args.GetReturnValue().Set(rc);
3442 void SignBase::CheckThrow(SignBase::Error error) {
3443 HandleScope scope(env()->isolate());
3446 case kSignUnknownDigest:
3447 return env()->ThrowError("Unknown message digest");
3449 case kSignNotInitialised:
3450 return env()->ThrowError("Not initialised");
3454 case kSignPrivateKey:
3455 case kSignPublicKey:
3457 unsigned long err = ERR_get_error();
3459 return ThrowCryptoError(env(), err);
3462 return env()->ThrowError("EVP_SignInit_ex failed");
3464 return env()->ThrowError("EVP_SignUpdate failed");
3465 case kSignPrivateKey:
3466 return env()->ThrowError("PEM_read_bio_PrivateKey failed");
3467 case kSignPublicKey:
3468 return env()->ThrowError("PEM_read_bio_PUBKEY failed");
3482 void Sign::Initialize(Environment* env, v8::Local<v8::Object> target) {
3483 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3485 t->InstanceTemplate()->SetInternalFieldCount(1);
3487 env->SetProtoMethod(t, "init", SignInit);
3488 env->SetProtoMethod(t, "update", SignUpdate);
3489 env->SetProtoMethod(t, "sign", SignFinal);
3491 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"), t->GetFunction());
3495 void Sign::New(const FunctionCallbackInfo<Value>& args) {
3496 Environment* env = Environment::GetCurrent(args);
3497 new Sign(env, args.This());
3501 SignBase::Error Sign::SignInit(const char* sign_type) {
3502 CHECK_EQ(md_, nullptr);
3503 md_ = EVP_get_digestbyname(sign_type);
3505 return kSignUnknownDigest;
3507 EVP_MD_CTX_init(&mdctx_);
3508 if (!EVP_SignInit_ex(&mdctx_, md_, nullptr))
3510 initialised_ = true;
3516 void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
3517 Sign* sign = Unwrap<Sign>(args.Holder());
3519 if (args.Length() == 0 || !args[0]->IsString()) {
3520 return sign->env()->ThrowError("Must give signtype string as argument");
3523 const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
3524 sign->CheckThrow(sign->SignInit(*sign_type));
3528 SignBase::Error Sign::SignUpdate(const char* data, int len) {
3530 return kSignNotInitialised;
3531 if (!EVP_SignUpdate(&mdctx_, data, len))
3537 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
3538 Environment* env = Environment::GetCurrent(args);
3540 Sign* sign = Unwrap<Sign>(args.Holder());
3542 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3544 // Only copy the data if we have to, because it's a string
3546 if (args[0]->IsString()) {
3547 StringBytes::InlineDecoder decoder;
3548 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3550 err = sign->SignUpdate(decoder.out(), decoder.size());
3552 char* buf = Buffer::Data(args[0]);
3553 size_t buflen = Buffer::Length(args[0]);
3554 err = sign->SignUpdate(buf, buflen);
3557 sign->CheckThrow(err);
3561 SignBase::Error Sign::SignFinal(const char* key_pem,
3563 const char* passphrase,
3564 unsigned char** sig,
3565 unsigned int *sig_len) {
3567 return kSignNotInitialised;
3570 EVP_PKEY* pkey = nullptr;
3573 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3577 pkey = PEM_read_bio_PrivateKey(bp,
3580 const_cast<char*>(passphrase));
3582 // Errors might be injected into OpenSSL's error stack
3583 // without `pkey` being set to nullptr;
3584 // cf. the test of `test_bad_rsa_privkey.pem` for an example.
3585 if (pkey == nullptr || 0 != ERR_peek_error())
3588 if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey))
3591 initialised_ = false;
3594 if (pkey != nullptr)
3595 EVP_PKEY_free(pkey);
3599 EVP_MD_CTX_cleanup(&mdctx_);
3602 return kSignPrivateKey;
3608 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
3609 Environment* env = Environment::GetCurrent(args);
3611 Sign* sign = Unwrap<Sign>(args.Holder());
3613 unsigned char* md_value;
3614 unsigned int md_len;
3616 unsigned int len = args.Length();
3617 enum encoding encoding = BUFFER;
3618 if (len >= 2 && args[1]->IsString()) {
3619 encoding = ParseEncoding(env->isolate(),
3620 args[1]->ToString(env->isolate()),
3624 node::Utf8Value passphrase(env->isolate(), args[2]);
3626 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3627 size_t buf_len = Buffer::Length(args[0]);
3628 char* buf = Buffer::Data(args[0]);
3630 md_len = 8192; // Maximum key size is 8192 bits
3631 md_value = new unsigned char[md_len];
3633 ClearErrorOnReturn clear_error_on_return;
3634 (void) &clear_error_on_return; // Silence compiler warning.
3636 Error err = sign->SignFinal(
3639 len >= 3 && !args[2]->IsNull() ? *passphrase : nullptr,
3642 if (err != kSignOk) {
3646 return sign->CheckThrow(err);
3649 Local<Value> rc = StringBytes::Encode(env->isolate(),
3650 reinterpret_cast<const char*>(md_value),
3654 args.GetReturnValue().Set(rc);
3658 void Verify::Initialize(Environment* env, v8::Local<v8::Object> target) {
3659 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3661 t->InstanceTemplate()->SetInternalFieldCount(1);
3663 env->SetProtoMethod(t, "init", VerifyInit);
3664 env->SetProtoMethod(t, "update", VerifyUpdate);
3665 env->SetProtoMethod(t, "verify", VerifyFinal);
3667 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
3672 void Verify::New(const FunctionCallbackInfo<Value>& args) {
3673 Environment* env = Environment::GetCurrent(args);
3674 new Verify(env, args.This());
3678 SignBase::Error Verify::VerifyInit(const char* verify_type) {
3679 CHECK_EQ(md_, nullptr);
3680 md_ = EVP_get_digestbyname(verify_type);
3682 return kSignUnknownDigest;
3684 EVP_MD_CTX_init(&mdctx_);
3685 if (!EVP_VerifyInit_ex(&mdctx_, md_, nullptr))
3687 initialised_ = true;
3693 void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
3694 Verify* verify = Unwrap<Verify>(args.Holder());
3696 if (args.Length() == 0 || !args[0]->IsString()) {
3697 return verify->env()->ThrowError("Must give verifytype string as argument");
3700 const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
3701 verify->CheckThrow(verify->VerifyInit(*verify_type));
3705 SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
3707 return kSignNotInitialised;
3709 if (!EVP_VerifyUpdate(&mdctx_, data, len))
3716 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
3717 Environment* env = Environment::GetCurrent(args);
3719 Verify* verify = Unwrap<Verify>(args.Holder());
3721 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3723 // Only copy the data if we have to, because it's a string
3725 if (args[0]->IsString()) {
3726 StringBytes::InlineDecoder decoder;
3727 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3729 err = verify->VerifyUpdate(decoder.out(), decoder.size());
3731 char* buf = Buffer::Data(args[0]);
3732 size_t buflen = Buffer::Length(args[0]);
3733 err = verify->VerifyUpdate(buf, buflen);
3736 verify->CheckThrow(err);
3740 SignBase::Error Verify::VerifyFinal(const char* key_pem,
3744 bool* verify_result) {
3746 return kSignNotInitialised;
3748 ClearErrorOnReturn clear_error_on_return;
3749 (void) &clear_error_on_return; // Silence compiler warning.
3751 EVP_PKEY* pkey = nullptr;
3753 X509* x509 = nullptr;
3757 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3761 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3762 // Split this out into a separate function once we have more than one
3763 // consumer of public keys.
3764 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3765 pkey = PEM_read_bio_PUBKEY(bp, nullptr, CryptoPemCallback, nullptr);
3766 if (pkey == nullptr)
3768 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3770 PEM_read_bio_RSAPublicKey(bp, nullptr, CryptoPemCallback, nullptr);
3772 pkey = EVP_PKEY_new();
3774 EVP_PKEY_set1_RSA(pkey, rsa);
3777 if (pkey == nullptr)
3781 x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
3782 if (x509 == nullptr)
3785 pkey = X509_get_pubkey(x509);
3786 if (pkey == nullptr)
3791 r = EVP_VerifyFinal(&mdctx_,
3792 reinterpret_cast<const unsigned char*>(sig),
3797 if (pkey != nullptr)
3798 EVP_PKEY_free(pkey);
3801 if (x509 != nullptr)
3804 EVP_MD_CTX_cleanup(&mdctx_);
3805 initialised_ = false;
3808 return kSignPublicKey;
3810 *verify_result = r == 1;
3815 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
3816 Environment* env = Environment::GetCurrent(args);
3818 Verify* verify = Unwrap<Verify>(args.Holder());
3820 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3821 char* kbuf = Buffer::Data(args[0]);
3822 ssize_t klen = Buffer::Length(args[0]);
3824 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[1]);
3826 // BINARY works for both buffers and binary strings.
3827 enum encoding encoding = BINARY;
3828 if (args.Length() >= 3) {
3829 encoding = ParseEncoding(env->isolate(),
3830 args[2]->ToString(env->isolate()),
3834 ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);
3836 // only copy if we need to, because it's a string.
3838 if (args[1]->IsString()) {
3839 hbuf = new char[hlen];
3840 ssize_t hwritten = StringBytes::Write(env->isolate(),
3845 CHECK_EQ(hwritten, hlen);
3847 hbuf = Buffer::Data(args[1]);
3851 Error err = verify->VerifyFinal(kbuf, klen, hbuf, hlen, &verify_result);
3852 if (args[1]->IsString())
3855 return verify->CheckThrow(err);
3856 args.GetReturnValue().Set(verify_result);
3860 template <PublicKeyCipher::Operation operation,
3861 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3862 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3863 bool PublicKeyCipher::Cipher(const char* key_pem,
3865 const char* passphrase,
3867 const unsigned char* data,
3869 unsigned char** out,
3871 EVP_PKEY* pkey = nullptr;
3872 EVP_PKEY_CTX* ctx = nullptr;
3874 X509* x509 = nullptr;
3877 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3881 // Check if this is a PKCS#8 or RSA public key before trying as X.509 and
3883 if (operation == kPublic &&
3884 strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3885 pkey = PEM_read_bio_PUBKEY(bp, nullptr, nullptr, nullptr);
3886 if (pkey == nullptr)
3888 } else if (operation == kPublic &&
3889 strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3890 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, nullptr, nullptr, nullptr);
3892 pkey = EVP_PKEY_new();
3894 EVP_PKEY_set1_RSA(pkey, rsa);
3897 if (pkey == nullptr)
3899 } else if (operation == kPublic &&
3900 strncmp(key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0) {
3901 x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
3902 if (x509 == nullptr)
3905 pkey = X509_get_pubkey(x509);
3906 if (pkey == nullptr)
3909 pkey = PEM_read_bio_PrivateKey(bp,
3912 const_cast<char*>(passphrase));
3913 if (pkey == nullptr)
3917 ctx = EVP_PKEY_CTX_new(pkey, nullptr);
3920 if (EVP_PKEY_cipher_init(ctx) <= 0)
3922 if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0)
3925 if (EVP_PKEY_cipher(ctx, nullptr, out_len, data, len) <= 0)
3928 *out = new unsigned char[*out_len];
3930 if (EVP_PKEY_cipher(ctx, *out, out_len, data, len) <= 0)
3936 if (x509 != nullptr)
3938 if (pkey != nullptr)
3939 EVP_PKEY_free(pkey);
3943 EVP_PKEY_CTX_free(ctx);
3949 template <PublicKeyCipher::Operation operation,
3950 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3951 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3952 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
3953 Environment* env = Environment::GetCurrent(args);
3955 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3956 char* kbuf = Buffer::Data(args[0]);
3957 ssize_t klen = Buffer::Length(args[0]);
3959 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
3960 char* buf = Buffer::Data(args[1]);
3961 ssize_t len = Buffer::Length(args[1]);
3963 int padding = args[2]->Uint32Value();
3965 String::Utf8Value passphrase(args[3]);
3967 unsigned char* out_value = nullptr;
3970 ClearErrorOnReturn clear_error_on_return;
3971 (void) &clear_error_on_return; // Silence compiler warning.
3973 bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
3976 args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : nullptr,
3978 reinterpret_cast<const unsigned char*>(buf),
3983 if (out_len == 0 || !r) {
3985 out_value = nullptr;
3988 return ThrowCryptoError(env,
3993 Local<Object> vbuf = Buffer::Copy(
3995 reinterpret_cast<char*>(out_value),
3996 out_len).ToLocalChecked();
3997 args.GetReturnValue().Set(vbuf);
4002 void DiffieHellman::Initialize(Environment* env, Local<Object> target) {
4003 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4005 const PropertyAttribute attributes =
4006 static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
4008 t->InstanceTemplate()->SetInternalFieldCount(1);
4010 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
4011 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
4012 env->SetProtoMethod(t, "getPrime", GetPrime);
4013 env->SetProtoMethod(t, "getGenerator", GetGenerator);
4014 env->SetProtoMethod(t, "getPublicKey", GetPublicKey);
4015 env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey);
4016 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
4017 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
4019 t->InstanceTemplate()->SetAccessor(env->verify_error_string(),
4020 DiffieHellman::VerifyErrorGetter,
4026 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"),
4029 Local<FunctionTemplate> t2 = env->NewFunctionTemplate(DiffieHellmanGroup);
4030 t2->InstanceTemplate()->SetInternalFieldCount(1);
4032 env->SetProtoMethod(t2, "generateKeys", GenerateKeys);
4033 env->SetProtoMethod(t2, "computeSecret", ComputeSecret);
4034 env->SetProtoMethod(t2, "getPrime", GetPrime);
4035 env->SetProtoMethod(t2, "getGenerator", GetGenerator);
4036 env->SetProtoMethod(t2, "getPublicKey", GetPublicKey);
4037 env->SetProtoMethod(t2, "getPrivateKey", GetPrivateKey);
4039 t2->InstanceTemplate()->SetAccessor(env->verify_error_string(),
4040 DiffieHellman::VerifyErrorGetter,
4046 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
4051 bool DiffieHellman::Init(int primeLength, int g) {
4053 DH_generate_parameters_ex(dh, primeLength, g, 0);
4054 bool result = VerifyContext();
4057 initialised_ = true;
4062 bool DiffieHellman::Init(const char* p, int p_len, int g) {
4064 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
4066 if (!BN_set_word(dh->g, g))
4068 bool result = VerifyContext();
4071 initialised_ = true;
4076 bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
4078 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
4079 dh->g = BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, 0);
4080 bool result = VerifyContext();
4083 initialised_ = true;
4088 void DiffieHellman::DiffieHellmanGroup(
4089 const FunctionCallbackInfo<Value>& args) {
4090 Environment* env = Environment::GetCurrent(args);
4091 DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
4093 if (args.Length() != 1 || !args[0]->IsString()) {
4094 return env->ThrowError("No group name given");
4097 bool initialized = false;
4099 const node::Utf8Value group_name(env->isolate(), args[0]);
4100 for (unsigned int i = 0; i < ARRAY_SIZE(modp_groups); ++i) {
4101 const modp_group* it = modp_groups + i;
4103 if (strcasecmp(*group_name, it->name) != 0)
4106 initialized = diffieHellman->Init(it->prime,
4111 env->ThrowError("Initialization failed");
4115 env->ThrowError("Unknown group");
4119 void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
4120 Environment* env = Environment::GetCurrent(args);
4121 DiffieHellman* diffieHellman =
4122 new DiffieHellman(env, args.This());
4123 bool initialized = false;
4125 if (args.Length() == 2) {
4126 if (args[0]->IsInt32()) {
4127 if (args[1]->IsInt32()) {
4128 initialized = diffieHellman->Init(args[0]->Int32Value(),
4129 args[1]->Int32Value());
4132 if (args[1]->IsInt32()) {
4133 initialized = diffieHellman->Init(Buffer::Data(args[0]),
4134 Buffer::Length(args[0]),
4135 args[1]->Int32Value());
4137 initialized = diffieHellman->Init(Buffer::Data(args[0]),
4138 Buffer::Length(args[0]),
4139 Buffer::Data(args[1]),
4140 Buffer::Length(args[1]));
4146 return env->ThrowError("Initialization failed");
4151 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4152 Environment* env = Environment::GetCurrent(args);
4154 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4156 if (!diffieHellman->initialised_) {
4157 return env->ThrowError("Not initialized");
4160 if (!DH_generate_key(diffieHellman->dh)) {
4161 return env->ThrowError("Key generation failed");
4164 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
4165 char* data = new char[dataSize];
4166 BN_bn2bin(diffieHellman->dh->pub_key,
4167 reinterpret_cast<unsigned char*>(data));
4169 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4174 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
4175 Environment* env = Environment::GetCurrent(args);
4177 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4179 if (!diffieHellman->initialised_) {
4180 return env->ThrowError("Not initialized");
4183 int dataSize = BN_num_bytes(diffieHellman->dh->p);
4184 char* data = new char[dataSize];
4185 BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
4187 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4192 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
4193 Environment* env = Environment::GetCurrent(args);
4195 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4197 if (!diffieHellman->initialised_) {
4198 return env->ThrowError("Not initialized");
4201 int dataSize = BN_num_bytes(diffieHellman->dh->g);
4202 char* data = new char[dataSize];
4203 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
4205 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4210 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
4211 Environment* env = Environment::GetCurrent(args);
4213 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4215 if (!diffieHellman->initialised_) {
4216 return env->ThrowError("Not initialized");
4219 if (diffieHellman->dh->pub_key == nullptr) {
4220 return env->ThrowError("No public key - did you forget to generate one?");
4223 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
4224 char* data = new char[dataSize];
4225 BN_bn2bin(diffieHellman->dh->pub_key,
4226 reinterpret_cast<unsigned char*>(data));
4228 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4233 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4234 Environment* env = Environment::GetCurrent(args);
4236 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4238 if (!diffieHellman->initialised_) {
4239 return env->ThrowError("Not initialized");
4242 if (diffieHellman->dh->priv_key == nullptr) {
4243 return env->ThrowError("No private key - did you forget to generate one?");
4246 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
4247 char* data = new char[dataSize];
4248 BN_bn2bin(diffieHellman->dh->priv_key,
4249 reinterpret_cast<unsigned char*>(data));
4251 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4256 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4257 Environment* env = Environment::GetCurrent(args);
4259 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4261 if (!diffieHellman->initialised_) {
4262 return env->ThrowError("Not initialized");
4265 ClearErrorOnReturn clear_error_on_return;
4266 (void) &clear_error_on_return; // Silence compiler warning.
4267 BIGNUM* key = nullptr;
4269 if (args.Length() == 0) {
4270 return env->ThrowError("First argument must be other party's public key");
4272 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4274 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4275 Buffer::Length(args[0]),
4279 int dataSize = DH_size(diffieHellman->dh);
4280 char* data = new char[dataSize];
4282 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
4290 checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
4295 return env->ThrowError("Invalid key");
4296 } else if (checkResult) {
4297 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
4298 return env->ThrowError("Supplied key is too small");
4299 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
4300 return env->ThrowError("Supplied key is too large");
4302 return env->ThrowError("Invalid key");
4305 return env->ThrowError("Invalid key");
4312 // DH_size returns number of bytes in a prime number
4313 // DH_compute_key returns number of bytes in a remainder of exponent, which
4314 // may have less bytes than a prime number. Therefore add 0-padding to the
4315 // allocated buffer.
4316 if (size != dataSize) {
4317 CHECK(dataSize > size);
4318 memmove(data + dataSize - size, data, size);
4319 memset(data, 0, dataSize - size);
4322 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4327 void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4328 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4329 Environment* env = diffieHellman->env();
4331 if (!diffieHellman->initialised_) {
4332 return env->ThrowError("Not initialized");
4335 if (args.Length() == 0) {
4336 return env->ThrowError("First argument must be public key");
4338 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4339 diffieHellman->dh->pub_key = BN_bin2bn(
4340 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4341 Buffer::Length(args[0]), 0);
4346 void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4347 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4348 Environment* env = diffieHellman->env();
4350 if (!diffieHellman->initialised_) {
4351 return env->ThrowError("Not initialized");
4354 if (args.Length() == 0) {
4355 return env->ThrowError("First argument must be private key");
4357 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4358 diffieHellman->dh->priv_key = BN_bin2bn(
4359 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4360 Buffer::Length(args[0]),
4366 void DiffieHellman::VerifyErrorGetter(Local<String> property,
4367 const PropertyCallbackInfo<Value>& args) {
4368 HandleScope scope(args.GetIsolate());
4370 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4372 if (!diffieHellman->initialised_)
4373 return diffieHellman->env()->ThrowError("Not initialized");
4375 args.GetReturnValue().Set(diffieHellman->verifyError_);
4379 bool DiffieHellman::VerifyContext() {
4381 if (!DH_check(dh, &codes))
4383 verifyError_ = codes;
4388 void ECDH::Initialize(Environment* env, Local<Object> target) {
4389 HandleScope scope(env->isolate());
4391 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4393 t->InstanceTemplate()->SetInternalFieldCount(1);
4395 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
4396 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
4397 env->SetProtoMethod(t, "getPublicKey", GetPublicKey);
4398 env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey);
4399 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
4400 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
4402 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH"),
4407 void ECDH::New(const FunctionCallbackInfo<Value>& args) {
4408 Environment* env = Environment::GetCurrent(args);
4410 // TODO(indutny): Support raw curves?
4411 CHECK(args[0]->IsString());
4412 node::Utf8Value curve(env->isolate(), args[0]);
4414 int nid = OBJ_sn2nid(*curve);
4415 if (nid == NID_undef)
4416 return env->ThrowTypeError("First argument should be a valid curve name");
4418 EC_KEY* key = EC_KEY_new_by_curve_name(nid);
4420 return env->ThrowError("Failed to create EC_KEY using curve name");
4422 new ECDH(env, args.This(), key);
4426 void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4427 Environment* env = Environment::GetCurrent(args);
4429 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4431 if (!EC_KEY_generate_key(ecdh->key_))
4432 return env->ThrowError("Failed to generate EC_KEY");
4434 ecdh->generated_ = true;
4438 EC_POINT* ECDH::BufferToPoint(char* data, size_t len) {
4442 pub = EC_POINT_new(group_);
4443 if (pub == nullptr) {
4444 env()->ThrowError("Failed to allocate EC_POINT for a public key");
4448 r = EC_POINT_oct2point(
4451 reinterpret_cast<unsigned char*>(data),
4455 env()->ThrowError("Failed to translate Buffer to a EC_POINT");
4467 void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4468 Environment* env = Environment::GetCurrent(args);
4470 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4472 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4474 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0]),
4475 Buffer::Length(args[0]));
4479 // NOTE: field_size is in bits
4480 int field_size = EC_GROUP_get_degree(ecdh->group_);
4481 size_t out_len = (field_size + 7) / 8;
4482 char* out = static_cast<char*>(malloc(out_len));
4483 CHECK_NE(out, nullptr);
4485 int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr);
4489 return env->ThrowError("Failed to compute ECDH key");
4492 Local<Object> buf = Buffer::New(env, out, out_len).ToLocalChecked();
4493 args.GetReturnValue().Set(buf);
4497 void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
4498 Environment* env = Environment::GetCurrent(args);
4501 CHECK_EQ(args.Length(), 1);
4503 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4505 if (!ecdh->generated_)
4506 return env->ThrowError("You should generate ECDH keys first");
4508 const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_);
4510 return env->ThrowError("Failed to get ECDH public key");
4513 point_conversion_form_t form =
4514 static_cast<point_conversion_form_t>(args[0]->Uint32Value());
4516 size = EC_POINT_point2oct(ecdh->group_, pub, form, nullptr, 0, nullptr);
4518 return env->ThrowError("Failed to get public key length");
4520 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4521 CHECK_NE(out, nullptr);
4523 int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr);
4526 return env->ThrowError("Failed to get public key");
4530 Buffer::New(env, reinterpret_cast<char*>(out), size).ToLocalChecked();
4531 args.GetReturnValue().Set(buf);
4535 void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4536 Environment* env = Environment::GetCurrent(args);
4538 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4540 if (!ecdh->generated_)
4541 return env->ThrowError("You should generate ECDH keys first");
4543 const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_);
4545 return env->ThrowError("Failed to get ECDH private key");
4547 int size = BN_num_bytes(b);
4548 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4549 CHECK_NE(out, nullptr);
4551 if (size != BN_bn2bin(b, out)) {
4553 return env->ThrowError("Failed to convert ECDH private key to Buffer");
4557 Buffer::New(env, reinterpret_cast<char*>(out), size).ToLocalChecked();
4558 args.GetReturnValue().Set(buf);
4562 void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4563 Environment* env = Environment::GetCurrent(args);
4565 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4567 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4569 BIGNUM* priv = BN_bin2bn(
4570 reinterpret_cast<unsigned char*>(Buffer::Data(args[0].As<Object>())),
4571 Buffer::Length(args[0].As<Object>()),
4573 if (priv == nullptr)
4574 return env->ThrowError("Failed to convert Buffer to BN");
4576 int result = EC_KEY_set_private_key(ecdh->key_, priv);
4580 return env->ThrowError("Failed to convert BN to a private key");
4585 void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4586 Environment* env = Environment::GetCurrent(args);
4588 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4590 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4592 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0].As<Object>()),
4593 Buffer::Length(args[0].As<Object>()));
4597 int r = EC_KEY_set_public_key(ecdh->key_, pub);
4600 return env->ThrowError("Failed to convert BN to a private key");
4604 class PBKDF2Request : public AsyncWrap {
4606 PBKDF2Request(Environment* env,
4607 Local<Object> object,
4608 const EVP_MD* digest,
4615 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4623 key_(static_cast<char*>(malloc(keylen))),
4625 if (key() == nullptr)
4626 FatalError("node::PBKDF2Request()", "Out of Memory");
4630 ~PBKDF2Request() override {
4632 persistent().Reset();
4635 uv_work_t* work_req() {
4639 inline const EVP_MD* digest() const {
4643 inline ssize_t passlen() const {
4647 inline char* pass() const {
4651 inline ssize_t saltlen() const {
4655 inline char* salt() const {
4659 inline ssize_t keylen() const {
4663 inline char* key() const {
4667 inline ssize_t iter() const {
4671 inline void release() {
4685 inline int error() const {
4689 inline void set_error(int err) {
4693 size_t self_size() const override { return sizeof(*this); }
4695 uv_work_t work_req_;
4698 const EVP_MD* digest_;
4710 void EIO_PBKDF2(PBKDF2Request* req) {
4711 req->set_error(PKCS5_PBKDF2_HMAC(
4714 reinterpret_cast<unsigned char*>(req->salt()),
4719 reinterpret_cast<unsigned char*>(req->key())));
4720 OPENSSL_cleanse(req->pass(), req->passlen());
4721 OPENSSL_cleanse(req->salt(), req->saltlen());
4725 void EIO_PBKDF2(uv_work_t* work_req) {
4726 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4731 void EIO_PBKDF2After(PBKDF2Request* req, Local<Value> argv[2]) {
4733 argv[0] = Undefined(req->env()->isolate());
4734 argv[1] = Encode(req->env()->isolate(), req->key(), req->keylen(), BUFFER);
4735 OPENSSL_cleanse(req->key(), req->keylen());
4737 argv[0] = Exception::Error(req->env()->pbkdf2_error_string());
4738 argv[1] = Undefined(req->env()->isolate());
4743 void EIO_PBKDF2After(uv_work_t* work_req, int status) {
4744 CHECK_EQ(status, 0);
4745 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4746 Environment* env = req->env();
4747 HandleScope handle_scope(env->isolate());
4748 Context::Scope context_scope(env->context());
4749 Local<Value> argv[2];
4750 EIO_PBKDF2After(req, argv);
4751 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4756 void PBKDF2(const FunctionCallbackInfo<Value>& args) {
4757 Environment* env = Environment::GetCurrent(args);
4759 const EVP_MD* digest = nullptr;
4760 const char* type_error = nullptr;
4761 char* pass = nullptr;
4762 char* salt = nullptr;
4763 ssize_t passlen = -1;
4764 ssize_t saltlen = -1;
4767 PBKDF2Request* req = nullptr;
4770 if (args.Length() != 5 && args.Length() != 6) {
4771 type_error = "Bad parameter";
4775 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4776 passlen = Buffer::Length(args[0]);
4778 type_error = "Bad password";
4782 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
4784 pass = static_cast<char*>(malloc(passlen));
4785 if (pass == nullptr) {
4786 FatalError("node::PBKDF2()", "Out of Memory");
4788 memcpy(pass, Buffer::Data(args[0]), passlen);
4790 saltlen = Buffer::Length(args[1]);
4792 type_error = "Bad salt";
4796 salt = static_cast<char*>(malloc(saltlen));
4797 if (salt == nullptr) {
4798 FatalError("node::PBKDF2()", "Out of Memory");
4800 memcpy(salt, Buffer::Data(args[1]), saltlen);
4802 if (!args[2]->IsNumber()) {
4803 type_error = "Iterations not a number";
4807 iter = args[2]->Int32Value();
4809 type_error = "Bad iterations";
4813 if (!args[3]->IsNumber()) {
4814 type_error = "Key length not a number";
4818 keylen = args[3]->NumberValue();
4819 if (keylen < 0 || isnan(keylen) || isinf(keylen)) {
4820 type_error = "Bad key length";
4824 if (args[4]->IsString()) {
4825 node::Utf8Value digest_name(env->isolate(), args[4]);
4826 digest = EVP_get_digestbyname(*digest_name);
4827 if (digest == nullptr) {
4828 type_error = "Bad digest name";
4833 if (digest == nullptr) {
4834 digest = EVP_sha1();
4837 obj = env->NewInternalFieldObject();
4838 req = new PBKDF2Request(env,
4846 static_cast<ssize_t>(keylen));
4848 if (args[5]->IsFunction()) {
4849 obj->Set(env->ondone_string(), args[5]);
4850 // XXX(trevnorris): This will need to go with the rest of domains.
4851 if (env->in_domain())
4852 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4853 uv_queue_work(env->event_loop(),
4858 env->PrintSyncTrace();
4859 Local<Value> argv[2];
4861 EIO_PBKDF2After(req, argv);
4865 if (argv[0]->IsObject())
4866 env->isolate()->ThrowException(argv[0]);
4868 args.GetReturnValue().Set(argv[1]);
4875 return env->ThrowTypeError(type_error);
4879 // Only instantiate within a valid HandleScope.
4880 class RandomBytesRequest : public AsyncWrap {
4882 RandomBytesRequest(Environment* env, Local<Object> object, size_t size)
4883 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4886 data_(static_cast<char*>(malloc(size))) {
4887 if (data() == nullptr)
4888 FatalError("node::RandomBytesRequest()", "Out of Memory");
4892 ~RandomBytesRequest() override {
4893 persistent().Reset();
4896 uv_work_t* work_req() {
4900 inline size_t size() const {
4904 inline char* data() const {
4908 inline void release() {
4913 inline void return_memory(char** d, size_t* len) {
4920 inline unsigned long error() const {
4924 inline void set_error(unsigned long err) {
4928 size_t self_size() const override { return sizeof(*this); }
4930 uv_work_t work_req_;
4933 unsigned long error_;
4939 void RandomBytesWork(uv_work_t* work_req) {
4940 RandomBytesRequest* req =
4941 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4943 // Ensure that OpenSSL's PRNG is properly seeded.
4946 const int r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data()),
4949 // RAND_bytes() returns 0 on error.
4951 req->set_error(ERR_get_error());
4952 } else if (r == -1) {
4953 req->set_error(static_cast<unsigned long>(-1));
4958 // don't call this function without a valid HandleScope
4959 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
4961 char errmsg[256] = "Operation not supported";
4963 if (req->error() != static_cast<unsigned long>(-1))
4964 ERR_error_string_n(req->error(), errmsg, sizeof errmsg);
4966 argv[0] = Exception::Error(OneByteString(req->env()->isolate(), errmsg));
4967 argv[1] = Null(req->env()->isolate());
4970 char* data = nullptr;
4972 req->return_memory(&data, &size);
4973 argv[0] = Null(req->env()->isolate());
4974 argv[1] = Buffer::New(req->env(), data, size).ToLocalChecked();
4979 void RandomBytesAfter(uv_work_t* work_req, int status) {
4980 CHECK_EQ(status, 0);
4981 RandomBytesRequest* req =
4982 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4983 Environment* env = req->env();
4984 HandleScope handle_scope(env->isolate());
4985 Context::Scope context_scope(env->context());
4986 Local<Value> argv[2];
4987 RandomBytesCheck(req, argv);
4988 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4993 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
4994 Environment* env = Environment::GetCurrent(args);
4996 // maybe allow a buffer to write to? cuts down on object creation
4997 // when generating random data in a loop
4998 if (!args[0]->IsUint32()) {
4999 return env->ThrowTypeError("size must be a number >= 0");
5002 const int64_t size = args[0]->IntegerValue();
5003 if (size < 0 || size > Buffer::kMaxLength)
5004 return env->ThrowRangeError("size is not a valid Smi");
5006 Local<Object> obj = env->NewInternalFieldObject();
5007 RandomBytesRequest* req = new RandomBytesRequest(env, obj, size);
5009 if (args[1]->IsFunction()) {
5010 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "ondone"), args[1]);
5011 // XXX(trevnorris): This will need to go with the rest of domains.
5012 if (env->in_domain())
5013 obj->Set(env->domain_string(), env->domain_array()->Get(0));
5014 uv_queue_work(env->event_loop(),
5018 args.GetReturnValue().Set(obj);
5020 env->PrintSyncTrace();
5021 Local<Value> argv[2];
5022 RandomBytesWork(req->work_req());
5023 RandomBytesCheck(req, argv);
5026 if (!argv[0]->IsNull())
5027 env->isolate()->ThrowException(argv[0]);
5029 args.GetReturnValue().Set(argv[1]);
5034 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
5035 Environment* env = Environment::GetCurrent(args);
5037 SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
5038 if (ctx == nullptr) {
5039 return env->ThrowError("SSL_CTX_new() failed.");
5042 SSL* ssl = SSL_new(ctx);
5043 if (ssl == nullptr) {
5045 return env->ThrowError("SSL_new() failed.");
5048 Local<Array> arr = Array::New(env->isolate());
5049 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
5051 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
5052 SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
5053 arr->Set(i, OneByteString(args.GetIsolate(), SSL_CIPHER_get_name(cipher)));
5059 args.GetReturnValue().Set(arr);
5063 class CipherPushContext {
5065 explicit CipherPushContext(Environment* env)
5066 : arr(Array::New(env->isolate())),
5070 inline Environment* env() const { return env_; }
5079 template <class TypeName>
5080 static void array_push_back(const TypeName* md,
5084 CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
5085 ctx->arr->Set(ctx->arr->Length(), OneByteString(ctx->env()->isolate(), from));
5089 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
5090 Environment* env = Environment::GetCurrent(args);
5091 CipherPushContext ctx(env);
5092 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
5093 args.GetReturnValue().Set(ctx.arr);
5097 void GetHashes(const FunctionCallbackInfo<Value>& args) {
5098 Environment* env = Environment::GetCurrent(args);
5099 CipherPushContext ctx(env);
5100 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
5101 args.GetReturnValue().Set(ctx.arr);
5105 void GetCurves(const FunctionCallbackInfo<Value>& args) {
5106 Environment* env = Environment::GetCurrent(args);
5107 const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
5108 Local<Array> arr = Array::New(env->isolate(), num_curves);
5109 EC_builtin_curve* curves;
5113 alloc_size = sizeof(*curves) * num_curves;
5114 curves = static_cast<EC_builtin_curve*>(malloc(alloc_size));
5116 CHECK_NE(curves, nullptr);
5118 if (EC_get_builtin_curves(curves, num_curves)) {
5119 for (size_t i = 0; i < num_curves; i++) {
5120 arr->Set(i, OneByteString(env->isolate(), OBJ_nid2sn(curves[i].nid)));
5127 args.GetReturnValue().Set(arr);
5131 void Certificate::Initialize(Environment* env, Local<Object> target) {
5132 HandleScope scope(env->isolate());
5134 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
5136 t->InstanceTemplate()->SetInternalFieldCount(1);
5138 env->SetProtoMethod(t, "verifySpkac", VerifySpkac);
5139 env->SetProtoMethod(t, "exportPublicKey", ExportPublicKey);
5140 env->SetProtoMethod(t, "exportChallenge", ExportChallenge);
5142 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Certificate"),
5147 void Certificate::New(const FunctionCallbackInfo<Value>& args) {
5148 Environment* env = Environment::GetCurrent(args);
5149 new Certificate(env, args.This());
5153 bool Certificate::VerifySpkac(const char* data, unsigned int len) {
5155 EVP_PKEY* pkey = nullptr;
5156 NETSCAPE_SPKI* spki = nullptr;
5158 spki = NETSCAPE_SPKI_b64_decode(data, len);
5159 if (spki == nullptr)
5162 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
5163 if (pkey == nullptr)
5166 i = NETSCAPE_SPKI_verify(spki, pkey) > 0;
5169 if (pkey != nullptr)
5170 EVP_PKEY_free(pkey);
5172 if (spki != nullptr)
5173 NETSCAPE_SPKI_free(spki);
5179 void Certificate::VerifySpkac(const FunctionCallbackInfo<Value>& args) {
5180 Certificate* certificate = Unwrap<Certificate>(args.Holder());
5181 Environment* env = certificate->env();
5184 if (args.Length() < 1)
5185 return env->ThrowTypeError("Missing argument");
5187 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
5189 size_t length = Buffer::Length(args[0]);
5191 return args.GetReturnValue().Set(i);
5193 char* data = Buffer::Data(args[0]);
5194 CHECK_NE(data, nullptr);
5196 i = certificate->VerifySpkac(data, length);
5198 args.GetReturnValue().Set(i);
5202 const char* Certificate::ExportPublicKey(const char* data, int len) {
5203 char* buf = nullptr;
5204 EVP_PKEY* pkey = nullptr;
5205 NETSCAPE_SPKI* spki = nullptr;
5207 BIO* bio = BIO_new(BIO_s_mem());
5211 spki = NETSCAPE_SPKI_b64_decode(data, len);
5212 if (spki == nullptr)
5215 pkey = NETSCAPE_SPKI_get_pubkey(spki);
5216 if (pkey == nullptr)
5219 if (PEM_write_bio_PUBKEY(bio, pkey) <= 0)
5222 BIO_write(bio, "\0", 1);
5224 BIO_get_mem_ptr(bio, &ptr);
5226 buf = new char[ptr->length];
5227 memcpy(buf, ptr->data, ptr->length);
5230 if (pkey != nullptr)
5231 EVP_PKEY_free(pkey);
5233 if (spki != nullptr)
5234 NETSCAPE_SPKI_free(spki);
5243 void Certificate::ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
5244 Environment* env = Environment::GetCurrent(args);
5246 Certificate* certificate = Unwrap<Certificate>(args.Holder());
5248 if (args.Length() < 1)
5249 return env->ThrowTypeError("Missing argument");
5251 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
5253 size_t length = Buffer::Length(args[0]);
5255 return args.GetReturnValue().SetEmptyString();
5257 char* data = Buffer::Data(args[0]);
5258 CHECK_NE(data, nullptr);
5260 const char* pkey = certificate->ExportPublicKey(data, length);
5261 if (pkey == nullptr)
5262 return args.GetReturnValue().SetEmptyString();
5264 Local<Value> out = Encode(env->isolate(), pkey, strlen(pkey), BUFFER);
5268 args.GetReturnValue().Set(out);
5272 const char* Certificate::ExportChallenge(const char* data, int len) {
5273 NETSCAPE_SPKI* sp = nullptr;
5275 sp = NETSCAPE_SPKI_b64_decode(data, len);
5279 unsigned char* buf = nullptr;
5280 ASN1_STRING_to_UTF8(&buf, sp->spkac->challenge);
5282 NETSCAPE_SPKI_free(sp);
5284 return reinterpret_cast<const char*>(buf);
5288 void Certificate::ExportChallenge(const FunctionCallbackInfo<Value>& args) {
5289 Environment* env = Environment::GetCurrent(args);
5291 Certificate* crt = Unwrap<Certificate>(args.Holder());
5293 if (args.Length() < 1)
5294 return env->ThrowTypeError("Missing argument");
5296 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
5298 size_t len = Buffer::Length(args[0]);
5300 return args.GetReturnValue().SetEmptyString();
5302 char* data = Buffer::Data(args[0]);
5303 CHECK_NE(data, nullptr);
5305 const char* cert = crt->ExportChallenge(data, len);
5306 if (cert == nullptr)
5307 return args.GetReturnValue().SetEmptyString();
5309 Local<Value> outString = Encode(env->isolate(), cert, strlen(cert), BUFFER);
5311 OPENSSL_free(const_cast<char*>(cert));
5313 args.GetReturnValue().Set(outString);
5317 void InitCryptoOnce() {
5319 OpenSSL_add_all_algorithms();
5320 SSL_load_error_strings();
5323 CRYPTO_set_locking_callback(crypto_lock_cb);
5324 CRYPTO_THREADID_set_callback(crypto_threadid_cb);
5326 #ifdef NODE_FIPS_MODE
5327 if (!FIPS_mode_set(1)) {
5328 int err = ERR_get_error();
5329 fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(err, NULL));
5332 #endif // NODE_FIPS_MODE
5335 // Turn off compression. Saves memory and protects against CRIME attacks.
5336 #if !defined(OPENSSL_NO_COMP)
5337 #if OPENSSL_VERSION_NUMBER < 0x00908000L
5338 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_method();
5340 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
5342 sk_SSL_COMP_zero(comp_methods);
5343 CHECK_EQ(sk_SSL_COMP_num(comp_methods), 0);
5346 #ifndef OPENSSL_NO_ENGINE
5347 ERR_load_ENGINE_strings();
5348 ENGINE_load_builtin_engines();
5349 #endif // !OPENSSL_NO_ENGINE
5353 #ifndef OPENSSL_NO_ENGINE
5354 void SetEngine(const FunctionCallbackInfo<Value>& args) {
5355 Environment* env = Environment::GetCurrent(args);
5356 CHECK(args.Length() >= 2 && args[0]->IsString());
5357 unsigned int flags = args[1]->Uint32Value();
5359 ClearErrorOnReturn clear_error_on_return;
5360 (void) &clear_error_on_return; // Silence compiler warning.
5362 const node::Utf8Value engine_id(env->isolate(), args[0]);
5363 ENGINE* engine = ENGINE_by_id(*engine_id);
5365 // Engine not found, try loading dynamically
5366 if (engine == nullptr) {
5367 engine = ENGINE_by_id("dynamic");
5368 if (engine != nullptr) {
5369 if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", *engine_id, 0) ||
5370 !ENGINE_ctrl_cmd_string(engine, "LOAD", nullptr, 0)) {
5371 ENGINE_free(engine);
5377 if (engine == nullptr) {
5378 int err = ERR_get_error();
5381 snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id);
5382 return env->ThrowError(tmp);
5384 return ThrowCryptoError(env, err);
5388 int r = ENGINE_set_default(engine, flags);
5389 ENGINE_free(engine);
5391 return ThrowCryptoError(env, ERR_get_error());
5393 #endif // !OPENSSL_NO_ENGINE
5396 // FIXME(bnoordhuis) Handle global init correctly.
5397 void InitCrypto(Local<Object> target,
5398 Local<Value> unused,
5399 Local<Context> context,
5401 static uv_once_t init_once = UV_ONCE_INIT;
5402 uv_once(&init_once, InitCryptoOnce);
5404 Environment* env = Environment::GetCurrent(context);
5405 SecureContext::Initialize(env, target);
5406 Connection::Initialize(env, target);
5407 CipherBase::Initialize(env, target);
5408 DiffieHellman::Initialize(env, target);
5409 ECDH::Initialize(env, target);
5410 Hmac::Initialize(env, target);
5411 Hash::Initialize(env, target);
5412 Sign::Initialize(env, target);
5413 Verify::Initialize(env, target);
5414 Certificate::Initialize(env, target);
5416 #ifndef OPENSSL_NO_ENGINE
5417 env->SetMethod(target, "setEngine", SetEngine);
5418 #endif // !OPENSSL_NO_ENGINE
5419 env->SetMethod(target, "PBKDF2", PBKDF2);
5420 env->SetMethod(target, "randomBytes", RandomBytes);
5421 env->SetMethod(target, "getSSLCiphers", GetSSLCiphers);
5422 env->SetMethod(target, "getCiphers", GetCiphers);
5423 env->SetMethod(target, "getHashes", GetHashes);
5424 env->SetMethod(target, "getCurves", GetCurves);
5425 env->SetMethod(target, "publicEncrypt",
5426 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
5427 EVP_PKEY_encrypt_init,
5429 env->SetMethod(target, "privateDecrypt",
5430 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
5431 EVP_PKEY_decrypt_init,
5433 env->SetMethod(target, "privateEncrypt",
5434 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
5437 env->SetMethod(target, "publicDecrypt",
5438 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
5439 EVP_PKEY_verify_recover_init,
5440 EVP_PKEY_verify_recover>);
5443 } // namespace crypto
5446 NODE_MODULE_CONTEXT_AWARE_BUILTIN(crypto, node::crypto::InitCrypto)