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"
22 #include <limits.h> // INT_MAX
28 #define strcasecmp _stricmp
31 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
32 #define OPENSSL_CONST const
37 #define THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(val) \
39 if (!Buffer::HasInstance(val) && !val->IsString()) { \
40 return env->ThrowTypeError("Not a string or buffer"); \
44 #define THROW_AND_RETURN_IF_NOT_BUFFER(val) \
46 if (!Buffer::HasInstance(val)) { \
47 return env->ThrowTypeError("Not a buffer"); \
51 static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----";
52 static const int PUBLIC_KEY_PFX_LEN = sizeof(PUBLIC_KEY_PFX) - 1;
53 static const char PUBRSA_KEY_PFX[] = "-----BEGIN RSA PUBLIC KEY-----";
54 static const int PUBRSA_KEY_PFX_LEN = sizeof(PUBRSA_KEY_PFX) - 1;
55 static const char CERTIFICATE_PFX[] = "-----BEGIN CERTIFICATE-----";
56 static const int CERTIFICATE_PFX_LEN = sizeof(CERTIFICATE_PFX) - 1;
58 static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
59 | ASN1_STRFLGS_UTF8_CONVERT
60 | XN_FLAG_SEP_MULTILINE
66 using v8::AccessorSignature;
72 using v8::EscapableHandleScope;
76 using v8::FunctionCallbackInfo;
77 using v8::FunctionTemplate;
78 using v8::HandleScope;
85 using v8::PropertyAttribute;
86 using v8::PropertyCallbackInfo;
93 // Subject DER of CNNIC ROOT CA and CNNIC EV ROOT CA are taken from
94 // https://hg.mozilla.org/mozilla-central/file/98820360ab66/security/
95 // certverifier/NSSCertDBTrustDomain.cpp#l672
96 // C = CN, O = CNNIC, CN = CNNIC ROOT
97 static const uint8_t CNNIC_ROOT_CA_SUBJECT_DATA[] =
98 "\x30\x32\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x4E\x31\x0E\x30"
99 "\x0C\x06\x03\x55\x04\x0A\x13\x05\x43\x4E\x4E\x49\x43\x31\x13\x30\x11\x06"
100 "\x03\x55\x04\x03\x13\x0A\x43\x4E\x4E\x49\x43\x20\x52\x4F\x4F\x54";
101 static const uint8_t* cnnic_p = CNNIC_ROOT_CA_SUBJECT_DATA;
102 static X509_NAME* cnnic_name =
103 d2i_X509_NAME(nullptr, &cnnic_p, sizeof(CNNIC_ROOT_CA_SUBJECT_DATA)-1);
105 // C = CN, O = China Internet Network Information Center, CN = China
106 // Internet Network Information Center EV Certificates Root
107 static const uint8_t CNNIC_EV_ROOT_CA_SUBJECT_DATA[] =
108 "\x30\x81\x8A\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x4E\x31\x32"
109 "\x30\x30\x06\x03\x55\x04\x0A\x0C\x29\x43\x68\x69\x6E\x61\x20\x49\x6E\x74"
110 "\x65\x72\x6E\x65\x74\x20\x4E\x65\x74\x77\x6F\x72\x6B\x20\x49\x6E\x66\x6F"
111 "\x72\x6D\x61\x74\x69\x6F\x6E\x20\x43\x65\x6E\x74\x65\x72\x31\x47\x30\x45"
112 "\x06\x03\x55\x04\x03\x0C\x3E\x43\x68\x69\x6E\x61\x20\x49\x6E\x74\x65\x72"
113 "\x6E\x65\x74\x20\x4E\x65\x74\x77\x6F\x72\x6B\x20\x49\x6E\x66\x6F\x72\x6D"
114 "\x61\x74\x69\x6F\x6E\x20\x43\x65\x6E\x74\x65\x72\x20\x45\x56\x20\x43\x65"
115 "\x72\x74\x69\x66\x69\x63\x61\x74\x65\x73\x20\x52\x6F\x6F\x74";
116 static const uint8_t* cnnic_ev_p = CNNIC_EV_ROOT_CA_SUBJECT_DATA;
117 static X509_NAME *cnnic_ev_name =
118 d2i_X509_NAME(nullptr, &cnnic_ev_p,
119 sizeof(CNNIC_EV_ROOT_CA_SUBJECT_DATA)-1);
121 static uv_mutex_t* locks;
123 const char* const root_certs[] = {
124 #include "node_root_certs.h" // NOLINT(build/include_order)
127 X509_STORE* root_cert_store;
129 // Just to generate static methods
130 template class SSLWrap<TLSWrap>;
131 template void SSLWrap<TLSWrap>::AddMethods(Environment* env,
132 Local<FunctionTemplate> t);
133 template void SSLWrap<TLSWrap>::InitNPN(SecureContext* sc);
134 template void SSLWrap<TLSWrap>::SetSNIContext(SecureContext* sc);
135 template int SSLWrap<TLSWrap>::SetCACerts(SecureContext* sc);
136 template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
141 template int SSLWrap<TLSWrap>::NewSessionCallback(SSL* s,
143 template void SSLWrap<TLSWrap>::OnClientHello(
145 const ClientHelloParser::ClientHello& hello);
147 #ifdef OPENSSL_NPN_NEGOTIATED
148 template int SSLWrap<TLSWrap>::AdvertiseNextProtoCallback(
150 const unsigned char** data,
153 template int SSLWrap<TLSWrap>::SelectNextProtoCallback(
156 unsigned char* outlen,
157 const unsigned char* in,
162 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
163 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),
320 AccessorSignature::New(env->isolate(), t));
322 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"),
324 env->set_secure_context_constructor_template(t);
328 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
329 Environment* env = Environment::GetCurrent(args);
330 new SecureContext(env, args.This());
334 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
335 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
336 Environment* env = sc->env();
338 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
340 if (args.Length() == 1 && args[0]->IsString()) {
341 const node::Utf8Value sslmethod(env->isolate(), args[0]);
343 // Note that SSLv2 and SSLv3 are disallowed but SSLv2_method and friends
344 // are still accepted. They are OpenSSL's way of saying that all known
345 // protocols are supported unless explicitly disabled (which we do below
346 // for SSLv2 and SSLv3.)
347 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
348 return env->ThrowError("SSLv2 methods disabled");
349 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
350 return env->ThrowError("SSLv2 methods disabled");
351 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
352 return env->ThrowError("SSLv2 methods disabled");
353 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
354 return env->ThrowError("SSLv3 methods disabled");
355 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
356 return env->ThrowError("SSLv3 methods disabled");
357 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
358 return env->ThrowError("SSLv3 methods disabled");
359 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
360 method = SSLv23_method();
361 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
362 method = SSLv23_server_method();
363 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
364 method = SSLv23_client_method();
365 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
366 method = TLSv1_method();
367 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
368 method = TLSv1_server_method();
369 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
370 method = TLSv1_client_method();
371 } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
372 method = TLSv1_1_method();
373 } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
374 method = TLSv1_1_server_method();
375 } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
376 method = TLSv1_1_client_method();
377 } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
378 method = TLSv1_2_method();
379 } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
380 method = TLSv1_2_server_method();
381 } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
382 method = TLSv1_2_client_method();
384 return env->ThrowError("Unknown method");
388 sc->ctx_ = SSL_CTX_new(method);
389 SSL_CTX_set_app_data(sc->ctx_, sc);
391 // Disable SSLv2 in the case when method == SSLv23_method() and the
392 // cipher list contains SSLv2 ciphers (not the default, should be rare.)
393 // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
394 // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
395 SSL_CTX_set_options(sc->ctx_, SSL_OP_NO_SSLv2);
396 SSL_CTX_set_options(sc->ctx_, SSL_OP_NO_SSLv3);
398 // SSL session cache configuration
399 SSL_CTX_set_session_cache_mode(sc->ctx_,
400 SSL_SESS_CACHE_SERVER |
401 SSL_SESS_CACHE_NO_INTERNAL |
402 SSL_SESS_CACHE_NO_AUTO_CLEAR);
403 SSL_CTX_sess_set_get_cb(sc->ctx_, SSLWrap<Connection>::GetSessionCallback);
404 SSL_CTX_sess_set_new_cb(sc->ctx_, SSLWrap<Connection>::NewSessionCallback);
406 sc->ca_store_ = nullptr;
410 // Takes a string or buffer and loads it into a BIO.
411 // Caller responsible for BIO_free_all-ing the returned object.
412 static BIO* LoadBIO(Environment* env, Local<Value> v) {
413 HandleScope scope(env->isolate());
416 const node::Utf8Value s(env->isolate(), v);
417 return NodeBIO::NewFixed(*s, s.length());
420 if (Buffer::HasInstance(v)) {
421 return NodeBIO::NewFixed(Buffer::Data(v), Buffer::Length(v));
428 // Takes a string or buffer and loads it into an X509
429 // Caller responsible for X509_free-ing the returned object.
430 static X509* LoadX509(Environment* env, Local<Value> v) {
431 HandleScope scope(env->isolate());
433 BIO *bio = LoadBIO(env, v);
437 X509 * x509 = PEM_read_bio_X509(bio, nullptr, CryptoPemCallback, nullptr);
448 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
449 Environment* env = Environment::GetCurrent(args);
451 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
453 unsigned int len = args.Length();
454 if (len != 1 && len != 2) {
455 return env->ThrowTypeError("Bad parameter");
457 if (len == 2 && !args[1]->IsString()) {
458 return env->ThrowTypeError("Bad parameter");
461 BIO *bio = LoadBIO(env, args[0]);
465 node::Utf8Value passphrase(env->isolate(), args[1]);
467 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio,
470 len == 1 ? nullptr : *passphrase);
474 unsigned long err = ERR_get_error();
476 return env->ThrowError("PEM_read_bio_PrivateKey");
478 return ThrowCryptoError(env, err);
481 int rv = SSL_CTX_use_PrivateKey(sc->ctx_, key);
486 unsigned long err = ERR_get_error();
488 return env->ThrowError("SSL_CTX_use_PrivateKey");
489 return ThrowCryptoError(env, err);
494 int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) {
497 X509_STORE* store = SSL_CTX_get_cert_store(ctx);
498 X509_STORE_CTX store_ctx;
500 ret = X509_STORE_CTX_init(&store_ctx, store, nullptr, nullptr);
504 ret = X509_STORE_CTX_get1_issuer(issuer, &store_ctx, cert);
505 X509_STORE_CTX_cleanup(&store_ctx);
512 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
514 STACK_OF(X509)* extra_certs,
517 CHECK_EQ(*issuer, nullptr);
518 CHECK_EQ(*cert, nullptr);
520 int ret = SSL_CTX_use_certificate(ctx, x);
523 // If we could set up our certificate, now proceed to
524 // the CA certificates.
527 SSL_CTX_clear_extra_chain_certs(ctx);
529 for (int i = 0; i < sk_X509_num(extra_certs); i++) {
530 X509* ca = sk_X509_value(extra_certs, i);
532 // NOTE: Increments reference count on `ca`
533 r = SSL_CTX_add1_chain_cert(ctx, ca);
540 // Note that we must not free r if it was successfully
541 // added to the chain (while we must free the main
542 // certificate, since its reference count is increased
543 // by SSL_CTX_use_certificate).
546 if (*issuer != nullptr || X509_check_issued(ca, x) != X509_V_OK)
553 // Try getting issuer from a cert store
555 if (*issuer == nullptr) {
556 ret = SSL_CTX_get_issuer(ctx, x, issuer);
557 ret = ret < 0 ? 0 : 1;
558 // NOTE: get_cert_store doesn't increment reference count,
559 // no need to free `store`
561 // Increment issuer reference count
562 *issuer = X509_dup(*issuer);
563 if (*issuer == nullptr) {
571 if (ret && x != nullptr) {
573 if (*cert == nullptr)
580 // Read a file that contains our certificate in "PEM" format,
581 // possibly followed by a sequence of CA certificates that should be
582 // sent to the peer in the Certificate message.
584 // Taken from OpenSSL - edited for style.
585 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
591 // Just to ensure that `ERR_peek_last_error` below will return only errors
592 // that we are interested in
595 x = PEM_read_bio_X509_AUX(in, nullptr, CryptoPemCallback, nullptr);
598 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
602 X509* extra = nullptr;
604 unsigned long err = 0;
607 STACK_OF(X509)* extra_certs = sk_X509_new_null();
608 if (extra_certs == nullptr) {
609 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE);
613 while ((extra = PEM_read_bio_X509(in, nullptr, CryptoPemCallback, nullptr))) {
614 if (sk_X509_push(extra_certs, extra))
617 // Failure, free all certs
622 // When the while loop ends, it's usually just EOF.
623 err = ERR_peek_last_error();
624 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
625 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
632 ret = SSL_CTX_use_certificate_chain(ctx, x, extra_certs, cert, issuer);
637 if (extra_certs != nullptr)
638 sk_X509_pop_free(extra_certs, X509_free);
639 if (extra != nullptr)
648 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
649 Environment* env = Environment::GetCurrent(args);
651 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
653 if (args.Length() != 1) {
654 return env->ThrowTypeError("Bad parameter");
657 BIO* bio = LoadBIO(env, args[0]);
661 // Free previous certs
662 if (sc->issuer_ != nullptr) {
663 X509_free(sc->issuer_);
664 sc->issuer_ = nullptr;
666 if (sc->cert_ != nullptr) {
667 X509_free(sc->cert_);
671 int rv = SSL_CTX_use_certificate_chain(sc->ctx_,
679 unsigned long err = ERR_get_error();
681 return env->ThrowError("SSL_CTX_use_certificate_chain");
683 return ThrowCryptoError(env, err);
688 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
689 bool newCAStore = false;
690 Environment* env = Environment::GetCurrent(args);
692 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
693 ClearErrorOnReturn clear_error_on_return;
694 (void) &clear_error_on_return; // Silence compiler warning.
696 if (args.Length() != 1) {
697 return env->ThrowTypeError("Bad parameter");
700 if (!sc->ca_store_) {
701 sc->ca_store_ = X509_STORE_new();
705 X509* x509 = LoadX509(env, args[0]);
709 X509_STORE_add_cert(sc->ca_store_, x509);
710 SSL_CTX_add_client_CA(sc->ctx_, x509);
715 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
720 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
721 Environment* env = Environment::GetCurrent(args);
723 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
725 if (args.Length() != 1) {
726 return env->ThrowTypeError("Bad parameter");
729 ClearErrorOnReturn clear_error_on_return;
730 (void) &clear_error_on_return; // Silence compiler warning.
732 BIO *bio = LoadBIO(env, args[0]);
737 PEM_read_bio_X509_CRL(bio, nullptr, CryptoPemCallback, nullptr);
739 if (x509 == nullptr) {
744 X509_STORE_add_crl(sc->ca_store_, x509);
745 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
746 X509_V_FLAG_CRL_CHECK_ALL);
753 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
754 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
755 ClearErrorOnReturn clear_error_on_return;
756 (void) &clear_error_on_return; // Silence compiler warning.
758 CHECK_EQ(sc->ca_store_, nullptr);
760 if (!root_cert_store) {
761 root_cert_store = X509_STORE_new();
763 for (size_t i = 0; i < ARRAY_SIZE(root_certs); i++) {
764 BIO* bp = NodeBIO::NewFixed(root_certs[i], strlen(root_certs[i]));
769 X509 *x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
770 if (x509 == nullptr) {
775 X509_STORE_add_cert(root_cert_store, x509);
782 sc->ca_store_ = root_cert_store;
783 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
787 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
788 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
789 ClearErrorOnReturn clear_error_on_return;
790 (void) &clear_error_on_return; // Silence compiler warning.
792 if (args.Length() != 1 || !args[0]->IsString()) {
793 return sc->env()->ThrowTypeError("Bad parameter");
796 const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
797 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
801 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
802 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
803 Environment* env = sc->env();
805 if (args.Length() != 1 || !args[0]->IsString())
806 return env->ThrowTypeError("First argument should be a string");
808 node::Utf8Value curve(env->isolate(), args[0]);
810 int nid = OBJ_sn2nid(*curve);
812 if (nid == NID_undef)
813 return env->ThrowTypeError("First argument should be a valid curve name");
815 EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
818 return env->ThrowTypeError("First argument should be a valid curve name");
820 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
821 SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
827 void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
828 SecureContext* sc = Unwrap<SecureContext>(args.This());
829 Environment* env = sc->env();
830 ClearErrorOnReturn clear_error_on_return;
831 (void) &clear_error_on_return; // Silence compiler warning.
833 // Auto DH is not supported in openssl 1.0.1, so dhparam needs
834 // to be specifed explicitly
835 if (args.Length() != 1)
836 return env->ThrowTypeError("Bad parameter");
838 // Invalid dhparam is silently discarded and DHE is no longer used.
839 BIO* bio = LoadBIO(env, args[0]);
843 DH* dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
849 const int keylen = BN_num_bits(dh->p);
852 return env->ThrowError("DH parameter is less than 1024 bits");
853 } else if (keylen < 2048) {
854 fprintf(stderr, "WARNING: DH parameter is less than 2048 bits\n");
857 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_DH_USE);
858 int r = SSL_CTX_set_tmp_dh(sc->ctx_, dh);
862 return env->ThrowTypeError("Error setting temp DH parameter");
866 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
867 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
869 if (args.Length() != 1 || !args[0]->IntegerValue()) {
870 return sc->env()->ThrowTypeError("Bad parameter");
873 SSL_CTX_set_options(sc->ctx_, static_cast<long>(args[0]->IntegerValue()));
877 void SecureContext::SetSessionIdContext(
878 const FunctionCallbackInfo<Value>& args) {
879 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
881 if (args.Length() != 1 || !args[0]->IsString()) {
882 return sc->env()->ThrowTypeError("Bad parameter");
885 const node::Utf8Value sessionIdContext(args.GetIsolate(), args[0]);
886 const unsigned char* sid_ctx =
887 reinterpret_cast<const unsigned char*>(*sessionIdContext);
888 unsigned int sid_ctx_len = sessionIdContext.length();
890 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
896 Local<String> message;
898 bio = BIO_new(BIO_s_mem());
899 if (bio == nullptr) {
900 message = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
901 "SSL_CTX_set_session_id_context error");
903 ERR_print_errors(bio);
904 BIO_get_mem_ptr(bio, &mem);
905 message = OneByteString(args.GetIsolate(), mem->data, mem->length);
909 args.GetIsolate()->ThrowException(Exception::TypeError(message));
913 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
914 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
916 if (args.Length() != 1 || !args[0]->IsInt32()) {
917 return sc->env()->ThrowTypeError("Bad parameter");
920 int32_t sessionTimeout = args[0]->Int32Value();
921 SSL_CTX_set_timeout(sc->ctx_, sessionTimeout);
925 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
926 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
931 // Takes .pfx or .p12 and password in string or buffer format
932 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
933 Environment* env = Environment::GetCurrent(args);
936 PKCS12* p12 = nullptr;
937 EVP_PKEY* pkey = nullptr;
938 X509* cert = nullptr;
939 STACK_OF(X509)* extra_certs = nullptr;
940 char* pass = nullptr;
943 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
944 ClearErrorOnReturn clear_error_on_return;
945 (void) &clear_error_on_return; // Silence compiler warning.
947 if (args.Length() < 1) {
948 return env->ThrowTypeError("Bad parameter");
951 in = LoadBIO(env, args[0]);
953 return env->ThrowError("Unable to load BIO");
956 if (args.Length() >= 2) {
957 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
958 size_t passlen = Buffer::Length(args[1]);
959 pass = new char[passlen + 1];
960 memcpy(pass, Buffer::Data(args[1]), passlen);
961 pass[passlen] = '\0';
964 // Free previous certs
965 if (sc->issuer_ != nullptr) {
966 X509_free(sc->issuer_);
967 sc->issuer_ = nullptr;
969 if (sc->cert_ != nullptr) {
970 X509_free(sc->cert_);
974 if (d2i_PKCS12_bio(in, &p12) &&
975 PKCS12_parse(p12, pass, &pkey, &cert, &extra_certs) &&
976 SSL_CTX_use_certificate_chain(sc->ctx_,
981 SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) {
983 for (int i = 0; i < sk_X509_num(extra_certs); i++) {
984 X509* ca = sk_X509_value(extra_certs, i);
986 if (!sc->ca_store_) {
987 sc->ca_store_ = X509_STORE_new();
988 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
990 X509_STORE_add_cert(sc->ca_store_, ca);
991 SSL_CTX_add_client_CA(sc->ctx_, ca);
1000 if (extra_certs != nullptr)
1001 sk_X509_pop_free(extra_certs, X509_free);
1008 unsigned long err = ERR_get_error();
1009 const char* str = ERR_reason_error_string(err);
1010 return env->ThrowError(str);
1015 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1016 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1018 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
1020 Local<Object> buff = Buffer::New(wrap->env(), 48).ToLocalChecked();
1021 if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_,
1023 Buffer::Length(buff)) != 1) {
1024 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
1027 args.GetReturnValue().Set(buff);
1028 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1032 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1033 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1034 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
1036 if (args.Length() < 1 ||
1037 !Buffer::HasInstance(args[0]) ||
1038 Buffer::Length(args[0]) != 48) {
1039 return wrap->env()->ThrowTypeError("Bad argument");
1042 if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_,
1043 Buffer::Data(args[0]),
1044 Buffer::Length(args[0])) != 1) {
1045 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
1048 args.GetReturnValue().Set(true);
1049 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1053 void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
1054 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
1056 wrap->ctx_->freelist_max_len = args[0]->Int32Value();
1060 void SecureContext::EnableTicketKeyCallback(
1061 const FunctionCallbackInfo<Value>& args) {
1062 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
1064 SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_, TicketKeyCallback);
1068 int SecureContext::TicketKeyCallback(SSL* ssl,
1069 unsigned char* name,
1071 EVP_CIPHER_CTX* ectx,
1074 static const int kTicketPartSize = 16;
1076 SecureContext* sc = static_cast<SecureContext*>(
1077 SSL_CTX_get_app_data(ssl->ctx));
1079 Environment* env = sc->env();
1080 HandleScope handle_scope(env->isolate());
1081 Context::Scope context_scope(env->context());
1083 Local<Value> argv[] = {
1085 reinterpret_cast<char*>(name),
1086 kTicketPartSize).ToLocalChecked(),
1088 reinterpret_cast<char*>(iv),
1089 kTicketPartSize).ToLocalChecked(),
1090 Boolean::New(env->isolate(), enc != 0)
1092 Local<Value> ret = node::MakeCallback(env,
1094 env->ticketkeycallback_string(),
1097 Local<Array> arr = ret.As<Array>();
1099 int r = arr->Get(kTicketKeyReturnIndex)->Int32Value();
1103 Local<Value> hmac = arr->Get(kTicketKeyHMACIndex);
1104 Local<Value> aes = arr->Get(kTicketKeyAESIndex);
1105 if (Buffer::Length(aes) != kTicketPartSize)
1109 Local<Value> name_val = arr->Get(kTicketKeyNameIndex);
1110 Local<Value> iv_val = arr->Get(kTicketKeyIVIndex);
1112 if (Buffer::Length(name_val) != kTicketPartSize ||
1113 Buffer::Length(iv_val) != kTicketPartSize) {
1117 memcpy(name, Buffer::Data(name_val), kTicketPartSize);
1118 memcpy(iv, Buffer::Data(iv_val), kTicketPartSize);
1123 Buffer::Length(hmac),
1127 const unsigned char* aes_key =
1128 reinterpret_cast<unsigned char*>(Buffer::Data(aes));
1130 EVP_EncryptInit_ex(ectx,
1136 EVP_DecryptInit_ex(ectx,
1149 void SecureContext::CtxGetter(Local<String> property,
1150 const PropertyCallbackInfo<Value>& info) {
1151 SSL_CTX* ctx = Unwrap<SecureContext>(info.This())->ctx_;
1152 Local<External> ext = External::New(info.GetIsolate(), ctx);
1153 info.GetReturnValue().Set(ext);
1157 template <bool primary>
1158 void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1159 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
1160 Environment* env = wrap->env();
1166 cert = wrap->issuer_;
1167 if (cert == nullptr)
1168 return args.GetReturnValue().Set(Null(env->isolate()));
1170 int size = i2d_X509(cert, nullptr);
1171 Local<Object> buff = Buffer::New(env, size).ToLocalChecked();
1172 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1173 Buffer::Data(buff));
1174 i2d_X509(cert, &serialized);
1176 args.GetReturnValue().Set(buff);
1180 template <class Base>
1181 void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) {
1182 HandleScope scope(env->isolate());
1184 env->SetProtoMethod(t, "getPeerCertificate", GetPeerCertificate);
1185 env->SetProtoMethod(t, "getSession", GetSession);
1186 env->SetProtoMethod(t, "setSession", SetSession);
1187 env->SetProtoMethod(t, "loadSession", LoadSession);
1188 env->SetProtoMethod(t, "isSessionReused", IsSessionReused);
1189 env->SetProtoMethod(t, "isInitFinished", IsInitFinished);
1190 env->SetProtoMethod(t, "verifyError", VerifyError);
1191 env->SetProtoMethod(t, "getCurrentCipher", GetCurrentCipher);
1192 env->SetProtoMethod(t, "endParser", EndParser);
1193 env->SetProtoMethod(t, "certCbDone", CertCbDone);
1194 env->SetProtoMethod(t, "renegotiate", Renegotiate);
1195 env->SetProtoMethod(t, "shutdownSSL", Shutdown);
1196 env->SetProtoMethod(t, "getTLSTicket", GetTLSTicket);
1197 env->SetProtoMethod(t, "newSessionDone", NewSessionDone);
1198 env->SetProtoMethod(t, "setOCSPResponse", SetOCSPResponse);
1199 env->SetProtoMethod(t, "requestOCSP", RequestOCSP);
1201 #ifdef SSL_set_max_send_fragment
1202 env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment);
1203 #endif // SSL_set_max_send_fragment
1205 #ifdef OPENSSL_NPN_NEGOTIATED
1206 env->SetProtoMethod(t, "getNegotiatedProtocol", GetNegotiatedProto);
1207 #endif // OPENSSL_NPN_NEGOTIATED
1209 #ifdef OPENSSL_NPN_NEGOTIATED
1210 env->SetProtoMethod(t, "setNPNProtocols", SetNPNProtocols);
1213 t->PrototypeTemplate()->SetAccessor(
1214 FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
1219 static_cast<PropertyAttribute>(ReadOnly | DontDelete),
1220 AccessorSignature::New(env->isolate(), t));
1224 template <class Base>
1225 void SSLWrap<Base>::InitNPN(SecureContext* sc) {
1226 #ifdef OPENSSL_NPN_NEGOTIATED
1227 // Server should advertise NPN protocols
1228 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
1229 AdvertiseNextProtoCallback,
1231 // Client should select protocol from list of advertised
1232 // If server supports NPN
1233 SSL_CTX_set_next_proto_select_cb(sc->ctx_, SelectNextProtoCallback, nullptr);
1234 #endif // OPENSSL_NPN_NEGOTIATED
1236 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1238 SSL_CTX_set_tlsext_status_cb(sc->ctx_, TLSExtStatusCallback);
1239 SSL_CTX_set_tlsext_status_arg(sc->ctx_, nullptr);
1240 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1244 template <class Base>
1245 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
1249 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1252 SSL_SESSION* sess = w->next_sess_;
1253 w->next_sess_ = nullptr;
1259 template <class Base>
1260 int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
1261 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1262 Environment* env = w->ssl_env();
1263 HandleScope handle_scope(env->isolate());
1264 Context::Scope context_scope(env->context());
1266 if (!w->session_callbacks_)
1269 // Check if session is small enough to be stored
1270 int size = i2d_SSL_SESSION(sess, nullptr);
1271 if (size > SecureContext::kMaxSessionSize)
1274 // Serialize session
1275 Local<Object> buff = Buffer::New(env, size).ToLocalChecked();
1276 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1277 Buffer::Data(buff));
1278 memset(serialized, 0, size);
1279 i2d_SSL_SESSION(sess, &serialized);
1281 Local<Object> session = Buffer::Copy(
1283 reinterpret_cast<char*>(sess->session_id),
1284 sess->session_id_length).ToLocalChecked();
1285 Local<Value> argv[] = { session, buff };
1286 w->new_session_wait_ = true;
1287 w->MakeCallback(env->onnewsession_string(), ARRAY_SIZE(argv), argv);
1293 template <class Base>
1294 void SSLWrap<Base>::OnClientHello(void* arg,
1295 const ClientHelloParser::ClientHello& hello) {
1296 Base* w = static_cast<Base*>(arg);
1297 Environment* env = w->ssl_env();
1298 HandleScope handle_scope(env->isolate());
1299 Context::Scope context_scope(env->context());
1301 Local<Object> hello_obj = Object::New(env->isolate());
1302 Local<Object> buff = Buffer::Copy(
1304 reinterpret_cast<const char*>(hello.session_id()),
1305 hello.session_size()).ToLocalChecked();
1306 hello_obj->Set(env->session_id_string(), buff);
1307 if (hello.servername() == nullptr) {
1308 hello_obj->Set(env->servername_string(), String::Empty(env->isolate()));
1310 Local<String> servername = OneByteString(env->isolate(),
1312 hello.servername_size());
1313 hello_obj->Set(env->servername_string(), servername);
1315 hello_obj->Set(env->tls_ticket_string(),
1316 Boolean::New(env->isolate(), hello.has_ticket()));
1317 hello_obj->Set(env->ocsp_request_string(),
1318 Boolean::New(env->isolate(), hello.ocsp_request()));
1320 Local<Value> argv[] = { hello_obj };
1321 w->MakeCallback(env->onclienthello_string(), ARRAY_SIZE(argv), argv);
1325 static bool SafeX509ExtPrint(BIO* out, X509_EXTENSION* ext) {
1326 const X509V3_EXT_METHOD* method = X509V3_EXT_get(ext);
1328 if (method != X509V3_EXT_get_nid(NID_subject_alt_name))
1331 const unsigned char* p = ext->value->data;
1332 GENERAL_NAMES* names = reinterpret_cast<GENERAL_NAMES*>(ASN1_item_d2i(
1336 ASN1_ITEM_ptr(method->it)));
1340 for (int i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1341 GENERAL_NAME* gen = sk_GENERAL_NAME_value(names, i);
1344 BIO_write(out, ", ", 2);
1346 if (gen->type == GEN_DNS) {
1347 ASN1_IA5STRING* name = gen->d.dNSName;
1349 BIO_write(out, "DNS:", 4);
1350 BIO_write(out, name->data, name->length);
1352 STACK_OF(CONF_VALUE)* nval = i2v_GENERAL_NAME(
1353 const_cast<X509V3_EXT_METHOD*>(method), gen, NULL);
1356 X509V3_EXT_val_prn(out, nval, 0, 0);
1357 sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
1360 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
1366 static Local<Object> X509ToObject(Environment* env, X509* cert) {
1367 EscapableHandleScope scope(env->isolate());
1369 Local<Object> info = Object::New(env->isolate());
1371 BIO* bio = BIO_new(BIO_s_mem());
1373 if (X509_NAME_print_ex(bio,
1374 X509_get_subject_name(cert),
1376 X509_NAME_FLAGS) > 0) {
1377 BIO_get_mem_ptr(bio, &mem);
1378 info->Set(env->subject_string(),
1379 String::NewFromUtf8(env->isolate(), mem->data,
1380 String::kNormalString, mem->length));
1382 (void) BIO_reset(bio);
1384 X509_NAME* issuer_name = X509_get_issuer_name(cert);
1385 if (X509_NAME_print_ex(bio, issuer_name, 0, X509_NAME_FLAGS) > 0) {
1386 BIO_get_mem_ptr(bio, &mem);
1387 info->Set(env->issuer_string(),
1388 String::NewFromUtf8(env->isolate(), mem->data,
1389 String::kNormalString, mem->length));
1391 (void) BIO_reset(bio);
1393 int nids[] = { NID_subject_alt_name, NID_info_access };
1394 Local<String> keys[] = { env->subjectaltname_string(),
1395 env->infoaccess_string() };
1396 CHECK_EQ(ARRAY_SIZE(nids), ARRAY_SIZE(keys));
1397 for (unsigned int i = 0; i < ARRAY_SIZE(nids); i++) {
1398 int index = X509_get_ext_by_NID(cert, nids[i], -1);
1402 X509_EXTENSION* ext;
1405 ext = X509_get_ext(cert, index);
1406 CHECK_NE(ext, nullptr);
1408 if (!SafeX509ExtPrint(bio, ext)) {
1409 rv = X509V3_EXT_print(bio, ext, 0, 0);
1413 BIO_get_mem_ptr(bio, &mem);
1415 String::NewFromUtf8(env->isolate(), mem->data,
1416 String::kNormalString, mem->length));
1418 (void) BIO_reset(bio);
1421 EVP_PKEY* pkey = X509_get_pubkey(cert);
1423 if (pkey != nullptr)
1424 rsa = EVP_PKEY_get1_RSA(pkey);
1426 if (rsa != nullptr) {
1427 BN_print(bio, rsa->n);
1428 BIO_get_mem_ptr(bio, &mem);
1429 info->Set(env->modulus_string(),
1430 String::NewFromUtf8(env->isolate(), mem->data,
1431 String::kNormalString, mem->length));
1432 (void) BIO_reset(bio);
1434 unsigned long exponent_word = BN_get_word(rsa->e);
1435 BIO_printf(bio, "0x%lx", exponent_word);
1437 BIO_get_mem_ptr(bio, &mem);
1438 info->Set(env->exponent_string(),
1439 String::NewFromUtf8(env->isolate(), mem->data,
1440 String::kNormalString, mem->length));
1441 (void) BIO_reset(bio);
1444 if (pkey != nullptr) {
1445 EVP_PKEY_free(pkey);
1448 if (rsa != nullptr) {
1453 ASN1_TIME_print(bio, X509_get_notBefore(cert));
1454 BIO_get_mem_ptr(bio, &mem);
1455 info->Set(env->valid_from_string(),
1456 String::NewFromUtf8(env->isolate(), mem->data,
1457 String::kNormalString, mem->length));
1458 (void) BIO_reset(bio);
1460 ASN1_TIME_print(bio, X509_get_notAfter(cert));
1461 BIO_get_mem_ptr(bio, &mem);
1462 info->Set(env->valid_to_string(),
1463 String::NewFromUtf8(env->isolate(), mem->data,
1464 String::kNormalString, mem->length));
1467 unsigned int md_size, i;
1468 unsigned char md[EVP_MAX_MD_SIZE];
1469 if (X509_digest(cert, EVP_sha1(), md, &md_size)) {
1470 const char hex[] = "0123456789ABCDEF";
1471 char fingerprint[EVP_MAX_MD_SIZE * 3];
1473 // TODO(indutny): Unify it with buffer's code
1474 for (i = 0; i < md_size; i++) {
1475 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1476 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1477 fingerprint[(3*i)+2] = ':';
1481 fingerprint[(3*(md_size-1))+2] = '\0';
1483 fingerprint[0] = '\0';
1486 info->Set(env->fingerprint_string(),
1487 OneByteString(env->isolate(), fingerprint));
1490 STACK_OF(ASN1_OBJECT)* eku = static_cast<STACK_OF(ASN1_OBJECT)*>(
1491 X509_get_ext_d2i(cert, NID_ext_key_usage, nullptr, nullptr));
1492 if (eku != nullptr) {
1493 Local<Array> ext_key_usage = Array::New(env->isolate());
1497 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1498 if (OBJ_obj2txt(buf, sizeof(buf), sk_ASN1_OBJECT_value(eku, i), 1) >= 0)
1499 ext_key_usage->Set(j++, OneByteString(env->isolate(), buf));
1502 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1503 info->Set(env->ext_key_usage_string(), ext_key_usage);
1506 if (ASN1_INTEGER* serial_number = X509_get_serialNumber(cert)) {
1507 if (BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, nullptr)) {
1508 if (char* buf = BN_bn2hex(bn)) {
1509 info->Set(env->serial_number_string(),
1510 OneByteString(env->isolate(), buf));
1517 // Raw DER certificate
1518 int size = i2d_X509(cert, nullptr);
1519 Local<Object> buff = Buffer::New(env, size).ToLocalChecked();
1520 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1521 Buffer::Data(buff));
1522 i2d_X509(cert, &serialized);
1523 info->Set(env->raw_string(), buff);
1525 return scope.Escape(info);
1529 // TODO(indutny): Split it into multiple smaller functions
1530 template <class Base>
1531 void SSLWrap<Base>::GetPeerCertificate(
1532 const FunctionCallbackInfo<Value>& args) {
1533 Base* w = Unwrap<Base>(args.Holder());
1534 Environment* env = w->ssl_env();
1536 ClearErrorOnReturn clear_error_on_return;
1537 (void) &clear_error_on_return; // Silence unused variable warning.
1539 Local<Object> result;
1542 // NOTE: This is because of the odd OpenSSL behavior. On client `cert_chain`
1543 // contains the `peer_certificate`, but on server it doesn't
1544 X509* cert = w->is_server() ? SSL_get_peer_certificate(w->ssl_) : nullptr;
1545 STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(w->ssl_);
1546 STACK_OF(X509)* peer_certs = nullptr;
1547 if (cert == nullptr && ssl_certs == nullptr)
1550 if (cert == nullptr && sk_X509_num(ssl_certs) == 0)
1553 // Short result requested
1554 if (args.Length() < 1 || !args[0]->IsTrue()) {
1555 result = X509ToObject(env,
1556 cert == nullptr ? sk_X509_value(ssl_certs, 0) : cert);
1560 // Clone `ssl_certs`, because we are going to destruct it
1561 peer_certs = sk_X509_new(nullptr);
1562 if (cert != nullptr)
1563 sk_X509_push(peer_certs, cert);
1564 for (int i = 0; i < sk_X509_num(ssl_certs); i++) {
1565 cert = X509_dup(sk_X509_value(ssl_certs, i));
1566 if (cert == nullptr)
1568 if (!sk_X509_push(peer_certs, cert))
1572 // First and main certificate
1573 cert = sk_X509_value(peer_certs, 0);
1574 result = X509ToObject(env, cert);
1577 // Put issuer inside the object
1578 cert = sk_X509_delete(peer_certs, 0);
1579 while (sk_X509_num(peer_certs) > 0) {
1581 for (i = 0; i < sk_X509_num(peer_certs); i++) {
1582 X509* ca = sk_X509_value(peer_certs, i);
1583 if (X509_check_issued(ca, cert) != X509_V_OK)
1586 Local<Object> ca_info = X509ToObject(env, ca);
1587 info->Set(env->issuercert_string(), ca_info);
1590 // NOTE: Intentionally freeing cert that is not used anymore
1593 // Delete cert and continue aggregating issuers
1594 cert = sk_X509_delete(peer_certs, i);
1598 // Issuer not found, break out of the loop
1599 if (i == sk_X509_num(peer_certs))
1603 // Last certificate should be self-signed
1604 while (X509_check_issued(cert, cert) != X509_V_OK) {
1606 if (SSL_CTX_get_issuer(w->ssl_->ctx, cert, &ca) <= 0)
1609 Local<Object> ca_info = X509ToObject(env, ca);
1610 info->Set(env->issuercert_string(), ca_info);
1613 // NOTE: Intentionally freeing cert that is not used anymore
1616 // Delete cert and continue aggregating issuers
1620 // Self-issued certificate
1621 if (X509_check_issued(cert, cert) == X509_V_OK)
1622 info->Set(env->issuercert_string(), info);
1624 CHECK_NE(cert, nullptr);
1627 if (cert != nullptr)
1629 if (peer_certs != nullptr)
1630 sk_X509_pop_free(peer_certs, X509_free);
1631 if (result.IsEmpty())
1632 result = Object::New(env->isolate());
1633 args.GetReturnValue().Set(result);
1637 template <class Base>
1638 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
1639 Environment* env = Environment::GetCurrent(args);
1641 Base* w = Unwrap<Base>(args.Holder());
1643 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1644 if (sess == nullptr)
1647 int slen = i2d_SSL_SESSION(sess, nullptr);
1650 char* sbuf = new char[slen];
1651 unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1652 i2d_SSL_SESSION(sess, &p);
1653 args.GetReturnValue().Set(Encode(env->isolate(), sbuf, slen, BUFFER));
1658 template <class Base>
1659 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
1660 Environment* env = Environment::GetCurrent(args);
1662 Base* w = Unwrap<Base>(args.Holder());
1664 if (args.Length() < 1 ||
1665 (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
1666 return env->ThrowTypeError("Bad argument");
1669 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
1670 size_t slen = Buffer::Length(args[0]);
1671 char* sbuf = new char[slen];
1672 memcpy(sbuf, Buffer::Data(args[0]), slen);
1674 const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
1675 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, slen);
1679 if (sess == nullptr)
1682 int r = SSL_set_session(w->ssl_, sess);
1683 SSL_SESSION_free(sess);
1686 return env->ThrowError("SSL_set_session error");
1690 template <class Base>
1691 void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
1692 Base* w = Unwrap<Base>(args.Holder());
1693 Environment* env = w->ssl_env();
1695 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1696 ssize_t slen = Buffer::Length(args[0]);
1697 char* sbuf = Buffer::Data(args[0]);
1699 const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1700 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, slen);
1702 // Setup next session and move hello to the BIO buffer
1703 if (w->next_sess_ != nullptr)
1704 SSL_SESSION_free(w->next_sess_);
1705 w->next_sess_ = sess;
1707 Local<Object> info = Object::New(env->isolate());
1708 #ifndef OPENSSL_NO_TLSEXT
1709 if (sess->tlsext_hostname == nullptr) {
1710 info->Set(env->servername_string(), False(args.GetIsolate()));
1712 info->Set(env->servername_string(),
1713 OneByteString(args.GetIsolate(), sess->tlsext_hostname));
1716 args.GetReturnValue().Set(info);
1721 template <class Base>
1722 void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
1723 Base* w = Unwrap<Base>(args.Holder());
1724 bool yes = SSL_session_reused(w->ssl_);
1725 args.GetReturnValue().Set(yes);
1729 template <class Base>
1730 void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
1731 Base* w = Unwrap<Base>(args.Holder());
1732 w->hello_parser_.End();
1736 template <class Base>
1737 void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
1738 Base* w = Unwrap<Base>(args.Holder());
1740 ClearErrorOnReturn clear_error_on_return;
1741 (void) &clear_error_on_return; // Silence unused variable warning.
1743 bool yes = SSL_renegotiate(w->ssl_) == 1;
1744 args.GetReturnValue().Set(yes);
1748 template <class Base>
1749 void SSLWrap<Base>::Shutdown(const FunctionCallbackInfo<Value>& args) {
1750 Base* w = Unwrap<Base>(args.Holder());
1752 int rv = SSL_shutdown(w->ssl_);
1753 args.GetReturnValue().Set(rv);
1757 template <class Base>
1758 void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
1759 Base* w = Unwrap<Base>(args.Holder());
1760 Environment* env = w->ssl_env();
1762 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1763 if (sess == nullptr || sess->tlsext_tick == nullptr)
1766 Local<Object> buff = Buffer::Copy(
1768 reinterpret_cast<char*>(sess->tlsext_tick),
1769 sess->tlsext_ticklen).ToLocalChecked();
1771 args.GetReturnValue().Set(buff);
1775 template <class Base>
1776 void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
1777 Base* w = Unwrap<Base>(args.Holder());
1778 w->new_session_wait_ = false;
1779 w->NewSessionDoneCb();
1783 template <class Base>
1784 void SSLWrap<Base>::SetOCSPResponse(
1785 const v8::FunctionCallbackInfo<v8::Value>& args) {
1786 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1787 HandleScope scope(args.GetIsolate());
1789 Base* w = Unwrap<Base>(args.Holder());
1790 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1791 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1793 w->ocsp_response_.Reset(args.GetIsolate(), args[0].As<Object>());
1794 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1798 template <class Base>
1799 void SSLWrap<Base>::RequestOCSP(
1800 const v8::FunctionCallbackInfo<v8::Value>& args) {
1801 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1802 HandleScope scope(args.GetIsolate());
1804 Base* w = Unwrap<Base>(args.Holder());
1806 SSL_set_tlsext_status_type(w->ssl_, TLSEXT_STATUSTYPE_ocsp);
1807 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1811 #ifdef SSL_set_max_send_fragment
1812 template <class Base>
1813 void SSLWrap<Base>::SetMaxSendFragment(
1814 const v8::FunctionCallbackInfo<v8::Value>& args) {
1815 HandleScope scope(args.GetIsolate());
1816 CHECK(args.Length() >= 1 && args[0]->IsNumber());
1818 Base* w = Unwrap<Base>(args.Holder());
1820 int rv = SSL_set_max_send_fragment(w->ssl_, args[0]->Int32Value());
1821 args.GetReturnValue().Set(rv);
1823 #endif // SSL_set_max_send_fragment
1826 template <class Base>
1827 void SSLWrap<Base>::IsInitFinished(const FunctionCallbackInfo<Value>& args) {
1828 Base* w = Unwrap<Base>(args.Holder());
1829 bool yes = SSL_is_init_finished(w->ssl_);
1830 args.GetReturnValue().Set(yes);
1834 template <class Base>
1835 void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
1836 Base* w = Unwrap<Base>(args.Holder());
1838 // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
1839 // peer certificate is questionable but it's compatible with what was
1841 long x509_verify_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
1842 if (X509* peer_cert = SSL_get_peer_certificate(w->ssl_)) {
1843 X509_free(peer_cert);
1844 x509_verify_error = SSL_get_verify_result(w->ssl_);
1847 if (x509_verify_error == X509_V_OK)
1848 return args.GetReturnValue().SetNull();
1850 // XXX(bnoordhuis) X509_verify_cert_error_string() is not actually thread-safe
1851 // in the presence of invalid error codes. Probably academical but something
1852 // to keep in mind if/when node ever grows multi-isolate capabilities.
1853 const char* reason = X509_verify_cert_error_string(x509_verify_error);
1854 const char* code = reason;
1855 #define CASE_X509_ERR(CODE) case X509_V_ERR_##CODE: code = #CODE; break;
1856 switch (x509_verify_error) {
1857 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT)
1858 CASE_X509_ERR(UNABLE_TO_GET_CRL)
1859 CASE_X509_ERR(UNABLE_TO_DECRYPT_CERT_SIGNATURE)
1860 CASE_X509_ERR(UNABLE_TO_DECRYPT_CRL_SIGNATURE)
1861 CASE_X509_ERR(UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)
1862 CASE_X509_ERR(CERT_SIGNATURE_FAILURE)
1863 CASE_X509_ERR(CRL_SIGNATURE_FAILURE)
1864 CASE_X509_ERR(CERT_NOT_YET_VALID)
1865 CASE_X509_ERR(CERT_HAS_EXPIRED)
1866 CASE_X509_ERR(CRL_NOT_YET_VALID)
1867 CASE_X509_ERR(CRL_HAS_EXPIRED)
1868 CASE_X509_ERR(ERROR_IN_CERT_NOT_BEFORE_FIELD)
1869 CASE_X509_ERR(ERROR_IN_CERT_NOT_AFTER_FIELD)
1870 CASE_X509_ERR(ERROR_IN_CRL_LAST_UPDATE_FIELD)
1871 CASE_X509_ERR(ERROR_IN_CRL_NEXT_UPDATE_FIELD)
1872 CASE_X509_ERR(OUT_OF_MEM)
1873 CASE_X509_ERR(DEPTH_ZERO_SELF_SIGNED_CERT)
1874 CASE_X509_ERR(SELF_SIGNED_CERT_IN_CHAIN)
1875 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
1876 CASE_X509_ERR(UNABLE_TO_VERIFY_LEAF_SIGNATURE)
1877 CASE_X509_ERR(CERT_CHAIN_TOO_LONG)
1878 CASE_X509_ERR(CERT_REVOKED)
1879 CASE_X509_ERR(INVALID_CA)
1880 CASE_X509_ERR(PATH_LENGTH_EXCEEDED)
1881 CASE_X509_ERR(INVALID_PURPOSE)
1882 CASE_X509_ERR(CERT_UNTRUSTED)
1883 CASE_X509_ERR(CERT_REJECTED)
1885 #undef CASE_X509_ERR
1887 Isolate* isolate = args.GetIsolate();
1888 Local<String> reason_string = OneByteString(isolate, reason);
1889 Local<Value> exception_value = Exception::Error(reason_string);
1890 Local<Object> exception_object = exception_value->ToObject(isolate);
1891 exception_object->Set(FIXED_ONE_BYTE_STRING(isolate, "code"),
1892 OneByteString(isolate, code));
1893 args.GetReturnValue().Set(exception_object);
1897 template <class Base>
1898 void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
1899 Base* w = Unwrap<Base>(args.Holder());
1900 Environment* env = w->ssl_env();
1902 OPENSSL_CONST SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_);
1906 Local<Object> info = Object::New(env->isolate());
1907 const char* cipher_name = SSL_CIPHER_get_name(c);
1908 info->Set(env->name_string(), OneByteString(args.GetIsolate(), cipher_name));
1909 const char* cipher_version = SSL_CIPHER_get_version(c);
1910 info->Set(env->version_string(),
1911 OneByteString(args.GetIsolate(), cipher_version));
1912 args.GetReturnValue().Set(info);
1916 #ifdef OPENSSL_NPN_NEGOTIATED
1917 template <class Base>
1918 int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s,
1919 const unsigned char** data,
1922 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1923 Environment* env = w->env();
1924 HandleScope handle_scope(env->isolate());
1925 Context::Scope context_scope(env->context());
1927 if (w->npn_protos_.IsEmpty()) {
1928 // No initialization - no NPN protocols
1929 *data = reinterpret_cast<const unsigned char*>("");
1932 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1933 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1934 *len = Buffer::Length(obj);
1937 return SSL_TLSEXT_ERR_OK;
1941 template <class Base>
1942 int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
1943 unsigned char** out,
1944 unsigned char* outlen,
1945 const unsigned char* in,
1948 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1949 Environment* env = w->env();
1950 HandleScope handle_scope(env->isolate());
1951 Context::Scope context_scope(env->context());
1953 // Release old protocol handler if present
1954 w->selected_npn_proto_.Reset();
1956 if (w->npn_protos_.IsEmpty()) {
1957 // We should at least select one protocol
1958 // If server is using NPN
1959 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
1962 // set status: unsupported
1963 w->selected_npn_proto_.Reset(env->isolate(), False(env->isolate()));
1965 return SSL_TLSEXT_ERR_OK;
1968 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1969 const unsigned char* npn_protos =
1970 reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1971 size_t len = Buffer::Length(obj);
1973 int status = SSL_select_next_proto(out, outlen, in, inlen, npn_protos, len);
1974 Local<Value> result;
1976 case OPENSSL_NPN_UNSUPPORTED:
1977 result = Null(env->isolate());
1979 case OPENSSL_NPN_NEGOTIATED:
1980 result = OneByteString(env->isolate(), *out, *outlen);
1982 case OPENSSL_NPN_NO_OVERLAP:
1983 result = False(env->isolate());
1989 if (!result.IsEmpty())
1990 w->selected_npn_proto_.Reset(env->isolate(), result);
1992 return SSL_TLSEXT_ERR_OK;
1996 template <class Base>
1997 void SSLWrap<Base>::GetNegotiatedProto(
1998 const FunctionCallbackInfo<Value>& args) {
1999 Base* w = Unwrap<Base>(args.Holder());
2001 if (w->is_client()) {
2002 if (w->selected_npn_proto_.IsEmpty() == false) {
2003 args.GetReturnValue().Set(w->selected_npn_proto_);
2008 const unsigned char* npn_proto;
2009 unsigned int npn_proto_len;
2011 SSL_get0_next_proto_negotiated(w->ssl_, &npn_proto, &npn_proto_len);
2014 return args.GetReturnValue().Set(false);
2016 args.GetReturnValue().Set(
2017 OneByteString(args.GetIsolate(), npn_proto, npn_proto_len));
2021 template <class Base>
2022 void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
2023 Base* w = Unwrap<Base>(args.Holder());
2025 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
2026 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
2028 w->npn_protos_.Reset(args.GetIsolate(), args[0].As<Object>());
2030 #endif // OPENSSL_NPN_NEGOTIATED
2033 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
2034 template <class Base>
2035 int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
2036 Base* w = static_cast<Base*>(SSL_get_app_data(s));
2037 Environment* env = w->env();
2038 HandleScope handle_scope(env->isolate());
2040 if (w->is_client()) {
2041 // Incoming response
2042 const unsigned char* resp;
2043 int len = SSL_get_tlsext_status_ocsp_resp(s, &resp);
2045 if (resp == nullptr) {
2046 arg = Null(env->isolate());
2050 reinterpret_cast<char*>(const_cast<unsigned char*>(resp)),
2051 len).ToLocalChecked();
2054 w->MakeCallback(env->onocspresponse_string(), 1, &arg);
2056 // Somehow, client is expecting different return value here
2059 // Outgoing response
2060 if (w->ocsp_response_.IsEmpty())
2061 return SSL_TLSEXT_ERR_NOACK;
2063 Local<Object> obj = PersistentToLocal(env->isolate(), w->ocsp_response_);
2064 char* resp = Buffer::Data(obj);
2065 size_t len = Buffer::Length(obj);
2067 // OpenSSL takes control of the pointer after accepting it
2068 char* data = reinterpret_cast<char*>(malloc(len));
2069 CHECK_NE(data, nullptr);
2070 memcpy(data, resp, len);
2072 if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
2074 w->ocsp_response_.Reset();
2076 return SSL_TLSEXT_ERR_OK;
2079 #endif // NODE__HAVE_TLSEXT_STATUS_CB
2082 template <class Base>
2083 void SSLWrap<Base>::WaitForCertCb(CertCb cb, void* arg) {
2089 template <class Base>
2090 int SSLWrap<Base>::SSLCertCallback(SSL* s, void* arg) {
2091 Base* w = static_cast<Base*>(SSL_get_app_data(s));
2093 if (!w->is_server())
2096 if (!w->is_waiting_cert_cb())
2099 if (w->cert_cb_running_)
2102 Environment* env = w->env();
2103 HandleScope handle_scope(env->isolate());
2104 Context::Scope context_scope(env->context());
2105 w->cert_cb_running_ = true;
2107 Local<Object> info = Object::New(env->isolate());
2109 SSL_SESSION* sess = SSL_get_session(s);
2110 if (sess != nullptr) {
2111 if (sess->tlsext_hostname == nullptr) {
2112 info->Set(env->servername_string(), String::Empty(env->isolate()));
2114 Local<String> servername = OneByteString(env->isolate(),
2115 sess->tlsext_hostname,
2116 strlen(sess->tlsext_hostname));
2117 info->Set(env->servername_string(), servername);
2119 info->Set(env->tls_ticket_string(),
2120 Boolean::New(env->isolate(), sess->tlsext_ticklen != 0));
2124 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
2125 ocsp = s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp;
2128 info->Set(env->ocsp_request_string(), Boolean::New(env->isolate(), ocsp));
2130 Local<Value> argv[] = { info };
2131 w->MakeCallback(env->oncertcb_string(), ARRAY_SIZE(argv), argv);
2133 if (!w->cert_cb_running_)
2136 // Performing async action, wait...
2141 template <class Base>
2142 void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
2143 Base* w = Unwrap<Base>(args.Holder());
2144 Environment* env = w->env();
2146 CHECK(w->is_waiting_cert_cb() && w->cert_cb_running_);
2148 Local<Object> object = w->object();
2149 Local<Value> ctx = object->Get(env->sni_context_string());
2150 Local<FunctionTemplate> cons = env->secure_context_constructor_template();
2152 // Not an object, probably undefined or null
2153 if (!ctx->IsObject())
2156 if (cons->HasInstance(ctx)) {
2157 SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
2158 w->sni_context_.Reset();
2159 w->sni_context_.Reset(env->isolate(), ctx);
2163 // NOTE: reference count is not increased by this API methods
2164 X509* x509 = SSL_CTX_get0_certificate(sc->ctx_);
2165 EVP_PKEY* pkey = SSL_CTX_get0_privatekey(sc->ctx_);
2166 STACK_OF(X509)* chain;
2168 rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain);
2170 rv = SSL_use_certificate(w->ssl_, x509);
2172 rv = SSL_use_PrivateKey(w->ssl_, pkey);
2173 if (rv && chain != nullptr)
2174 rv = SSL_set1_chain(w->ssl_, chain);
2176 rv = w->SetCACerts(sc);
2178 unsigned long err = ERR_get_error();
2180 return env->ThrowError("CertCbDone");
2181 return ThrowCryptoError(env, err);
2184 // Failure: incorrect SNI context object
2185 Local<Value> err = Exception::TypeError(env->sni_context_err_string());
2186 w->MakeCallback(env->onerror_string(), 1, &err);
2195 arg = w->cert_cb_arg_;
2197 w->cert_cb_running_ = false;
2198 w->cert_cb_ = nullptr;
2199 w->cert_cb_arg_ = nullptr;
2205 template <class Base>
2206 void SSLWrap<Base>::SSLGetter(Local<String> property,
2207 const PropertyCallbackInfo<Value>& info) {
2208 SSL* ssl = Unwrap<Base>(info.This())->ssl_;
2209 Local<External> ext = External::New(info.GetIsolate(), ssl);
2210 info.GetReturnValue().Set(ext);
2214 template <class Base>
2215 void SSLWrap<Base>::DestroySSL() {
2216 if (ssl_ == nullptr)
2220 env_->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
2225 template <class Base>
2226 void SSLWrap<Base>::SetSNIContext(SecureContext* sc) {
2228 CHECK_EQ(SSL_set_SSL_CTX(ssl_, sc->ctx_), sc->ctx_);
2234 template <class Base>
2235 int SSLWrap<Base>::SetCACerts(SecureContext* sc) {
2236 int err = SSL_set1_verify_cert_store(ssl_, SSL_CTX_get_cert_store(sc->ctx_));
2240 STACK_OF(X509_NAME)* list = SSL_dup_CA_list(
2241 SSL_CTX_get_client_CA_list(sc->ctx_));
2243 // NOTE: `SSL_set_client_CA_list` takes the ownership of `list`
2244 SSL_set_client_CA_list(ssl_, list);
2249 void Connection::OnClientHelloParseEnd(void* arg) {
2250 Connection* conn = static_cast<Connection*>(arg);
2252 // Write all accumulated data
2253 int r = BIO_write(conn->bio_read_,
2254 reinterpret_cast<char*>(conn->hello_data_),
2255 conn->hello_offset_);
2256 conn->HandleBIOError(conn->bio_read_, "BIO_write", r);
2257 conn->SetShutdownFlags();
2261 #ifdef SSL_PRINT_DEBUG
2262 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
2264 # define DEBUG_PRINT(...)
2268 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
2272 int retry = BIO_should_retry(bio);
2273 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
2275 if (BIO_should_write(bio)) {
2276 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n",
2282 } else if (BIO_should_read(bio)) {
2283 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
2287 char ssl_error_buf[512];
2288 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
2290 HandleScope scope(ssl_env()->isolate());
2291 Local<Value> exception =
2292 Exception::Error(OneByteString(ssl_env()->isolate(), ssl_error_buf));
2293 object()->Set(ssl_env()->error_string(), exception);
2295 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
2308 int Connection::HandleSSLError(const char* func,
2312 ClearErrorOnReturn clear_error_on_return;
2313 (void) &clear_error_on_return; // Silence unused variable warning.
2317 if (rv == 0 && zs == kZeroIsNotAnError)
2320 int err = SSL_get_error(ssl_, rv);
2322 if (err == SSL_ERROR_NONE) {
2325 } else if (err == SSL_ERROR_WANT_WRITE) {
2326 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
2329 } else if (err == SSL_ERROR_WANT_READ) {
2330 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
2333 } else if (err == SSL_ERROR_WANT_X509_LOOKUP) {
2334 DEBUG_PRINT("[%p] SSL: %s want x509 lookup\n", ssl_, func);
2337 } else if (err == SSL_ERROR_ZERO_RETURN) {
2338 HandleScope scope(ssl_env()->isolate());
2340 Local<Value> exception =
2341 Exception::Error(ssl_env()->zero_return_string());
2342 object()->Set(ssl_env()->error_string(), exception);
2345 } else if (err == SSL_ERROR_SYSCALL && ss == kIgnoreSyscall) {
2349 HandleScope scope(ssl_env()->isolate());
2353 CHECK(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
2355 // XXX We need to drain the error queue for this thread or else OpenSSL
2356 // has the possibility of blocking connections? This problem is not well
2357 // understood. And we should be somehow propagating these errors up
2358 // into JavaScript. There is no test which demonstrates this problem.
2359 // https://github.com/joyent/node/issues/1719
2360 bio = BIO_new(BIO_s_mem());
2361 if (bio != nullptr) {
2362 ERR_print_errors(bio);
2363 BIO_get_mem_ptr(bio, &mem);
2364 Local<Value> exception = Exception::Error(
2365 OneByteString(ssl_env()->isolate(),
2368 object()->Set(ssl_env()->error_string(), exception);
2379 void Connection::ClearError() {
2381 HandleScope scope(ssl_env()->isolate());
2383 // We should clear the error in JS-land
2384 Local<String> error_key = ssl_env()->error_string();
2385 Local<Value> error = object()->Get(error_key);
2386 CHECK_EQ(error->BooleanValue(), false);
2391 void Connection::SetShutdownFlags() {
2392 HandleScope scope(ssl_env()->isolate());
2394 int flags = SSL_get_shutdown(ssl_);
2396 if (flags & SSL_SENT_SHUTDOWN) {
2397 Local<String> sent_shutdown_key = ssl_env()->sent_shutdown_string();
2398 object()->Set(sent_shutdown_key, True(ssl_env()->isolate()));
2401 if (flags & SSL_RECEIVED_SHUTDOWN) {
2402 Local<String> received_shutdown_key = ssl_env()->received_shutdown_string();
2403 object()->Set(received_shutdown_key, True(ssl_env()->isolate()));
2408 void Connection::NewSessionDoneCb() {
2409 HandleScope scope(env()->isolate());
2411 MakeCallback(env()->onnewsessiondone_string(), 0, nullptr);
2415 void Connection::Initialize(Environment* env, Local<Object> target) {
2416 Local<FunctionTemplate> t = env->NewFunctionTemplate(Connection::New);
2417 t->InstanceTemplate()->SetInternalFieldCount(1);
2418 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"));
2420 env->SetProtoMethod(t, "encIn", Connection::EncIn);
2421 env->SetProtoMethod(t, "clearOut", Connection::ClearOut);
2422 env->SetProtoMethod(t, "clearIn", Connection::ClearIn);
2423 env->SetProtoMethod(t, "encOut", Connection::EncOut);
2424 env->SetProtoMethod(t, "clearPending", Connection::ClearPending);
2425 env->SetProtoMethod(t, "encPending", Connection::EncPending);
2426 env->SetProtoMethod(t, "start", Connection::Start);
2427 env->SetProtoMethod(t, "close", Connection::Close);
2429 SSLWrap<Connection>::AddMethods(env, t);
2432 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2433 env->SetProtoMethod(t, "getServername", Connection::GetServername);
2434 env->SetProtoMethod(t, "setSNICallback", Connection::SetSNICallback);
2437 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"),
2442 inline int compar(const void* a, const void* b) {
2443 return memcmp(a, b, CNNIC_WHITELIST_HASH_LEN);
2447 inline int IsSelfSigned(X509* cert) {
2448 return X509_NAME_cmp(X509_get_subject_name(cert),
2449 X509_get_issuer_name(cert)) == 0;
2453 inline X509* FindRoot(STACK_OF(X509)* sk) {
2454 for (int i = 0; i < sk_X509_num(sk); i++) {
2455 X509* cert = sk_X509_value(sk, i);
2456 if (IsSelfSigned(cert))
2463 // Whitelist check for certs issued by CNNIC. See
2464 // https://blog.mozilla.org/security/2015/04/02
2465 // /distrusting-new-cnnic-certificates/
2466 inline CheckResult CheckWhitelistedServerCert(X509_STORE_CTX* ctx) {
2467 unsigned char hash[CNNIC_WHITELIST_HASH_LEN];
2468 unsigned int hashlen = CNNIC_WHITELIST_HASH_LEN;
2470 STACK_OF(X509)* chain = X509_STORE_CTX_get1_chain(ctx);
2471 CHECK_NE(chain, nullptr);
2472 CHECK_GT(sk_X509_num(chain), 0);
2474 // Take the last cert as root at the first time.
2475 X509* root_cert = sk_X509_value(chain, sk_X509_num(chain)-1);
2476 X509_NAME* root_name = X509_get_subject_name(root_cert);
2478 if (!IsSelfSigned(root_cert)) {
2479 root_cert = FindRoot(chain);
2480 CHECK_NE(root_cert, nullptr);
2481 root_name = X509_get_subject_name(root_cert);
2484 // When the cert is issued from either CNNNIC ROOT CA or CNNNIC EV
2485 // ROOT CA, check a hash of its leaf cert if it is in the whitelist.
2486 if (X509_NAME_cmp(root_name, cnnic_name) == 0 ||
2487 X509_NAME_cmp(root_name, cnnic_ev_name) == 0) {
2488 X509* leaf_cert = sk_X509_value(chain, 0);
2489 int ret = X509_digest(leaf_cert, EVP_sha256(), hash,
2493 void* result = bsearch(hash, WhitelistedCNNICHashes,
2494 ARRAY_SIZE(WhitelistedCNNICHashes),
2495 CNNIC_WHITELIST_HASH_LEN, compar);
2496 if (result == nullptr) {
2497 sk_X509_pop_free(chain, X509_free);
2498 return CHECK_CERT_REVOKED;
2502 sk_X509_pop_free(chain, X509_free);
2507 inline int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
2508 // Failure on verification of the cert is handled in
2509 // Connection::VerifyError.
2510 if (preverify_ok == 0 || X509_STORE_CTX_get_error(ctx) != X509_V_OK)
2513 // Server does not need to check the whitelist.
2514 SSL* ssl = static_cast<SSL*>(
2515 X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
2517 if (SSL_is_server(ssl))
2520 // Client needs to check if the server cert is listed in the
2521 // whitelist when it is issued by the specific rootCAs.
2522 CheckResult ret = CheckWhitelistedServerCert(ctx);
2523 if (ret == CHECK_CERT_REVOKED)
2524 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
2530 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2531 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
2532 Connection* conn = static_cast<Connection*>(SSL_get_app_data(s));
2533 Environment* env = conn->env();
2534 HandleScope scope(env->isolate());
2536 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
2539 conn->servername_.Reset(env->isolate(),
2540 OneByteString(env->isolate(), servername));
2542 // Call the SNI callback and use its return value as context
2543 if (!conn->sniObject_.IsEmpty()) {
2544 conn->sni_context_.Reset();
2546 Local<Object> sni_obj = PersistentToLocal(env->isolate(),
2549 Local<Value> arg = PersistentToLocal(env->isolate(), conn->servername_);
2550 Local<Value> ret = node::MakeCallback(env->isolate(),
2552 env->onselect_string(),
2556 // If ret is SecureContext
2557 Local<FunctionTemplate> secure_context_constructor_template =
2558 env->secure_context_constructor_template();
2559 if (secure_context_constructor_template->HasInstance(ret)) {
2560 conn->sni_context_.Reset(env->isolate(), ret);
2561 SecureContext* sc = Unwrap<SecureContext>(ret.As<Object>());
2562 conn->SetSNIContext(sc);
2564 return SSL_TLSEXT_ERR_NOACK;
2569 return SSL_TLSEXT_ERR_OK;
2573 void Connection::New(const FunctionCallbackInfo<Value>& args) {
2574 Environment* env = Environment::GetCurrent(args);
2576 if (args.Length() < 1 || !args[0]->IsObject()) {
2577 env->ThrowError("First argument must be a tls module SecureContext");
2581 SecureContext* sc = Unwrap<SecureContext>(args[0]->ToObject(env->isolate()));
2583 bool is_server = args[1]->BooleanValue();
2585 SSLWrap<Connection>::Kind kind =
2586 is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient;
2587 Connection* conn = new Connection(env, args.This(), sc, kind);
2588 conn->bio_read_ = NodeBIO::New();
2589 conn->bio_write_ = NodeBIO::New();
2591 SSL_set_app_data(conn->ssl_, conn);
2594 SSL_set_info_callback(conn->ssl_, SSLInfoCallback);
2598 SSL_set_cert_cb(conn->ssl_, SSLWrap<Connection>::SSLCertCallback, conn);
2600 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2602 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
2603 } else if (args[2]->IsString()) {
2604 const node::Utf8Value servername(env->isolate(), args[2]);
2605 SSL_set_tlsext_host_name(conn->ssl_, *servername);
2609 SSL_set_bio(conn->ssl_, conn->bio_read_, conn->bio_write_);
2611 #ifdef SSL_MODE_RELEASE_BUFFERS
2612 long mode = SSL_get_mode(conn->ssl_);
2613 SSL_set_mode(conn->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
2619 bool request_cert = args[2]->BooleanValue();
2620 if (!request_cert) {
2621 // Note reject_unauthorized ignored.
2622 verify_mode = SSL_VERIFY_NONE;
2624 bool reject_unauthorized = args[3]->BooleanValue();
2625 verify_mode = SSL_VERIFY_PEER;
2626 if (reject_unauthorized)
2627 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2630 // Note request_cert and reject_unauthorized are ignored for clients.
2631 verify_mode = SSL_VERIFY_NONE;
2635 // Always allow a connection. We'll reject in javascript.
2636 SSL_set_verify(conn->ssl_, verify_mode, VerifyCallback);
2639 SSL_set_accept_state(conn->ssl_);
2641 SSL_set_connect_state(conn->ssl_);
2646 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
2647 if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
2650 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
2651 // a non-const SSL* in OpenSSL <= 0.9.7e.
2652 SSL* ssl = const_cast<SSL*>(ssl_);
2653 Connection* conn = static_cast<Connection*>(SSL_get_app_data(ssl));
2654 Environment* env = conn->env();
2655 HandleScope handle_scope(env->isolate());
2656 Context::Scope context_scope(env->context());
2658 if (where & SSL_CB_HANDSHAKE_START) {
2659 conn->MakeCallback(env->onhandshakestart_string(), 0, nullptr);
2662 if (where & SSL_CB_HANDSHAKE_DONE) {
2663 conn->MakeCallback(env->onhandshakedone_string(), 0, nullptr);
2668 void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
2669 Connection* conn = Unwrap<Connection>(args.Holder());
2670 Environment* env = conn->env();
2672 if (args.Length() < 3) {
2673 return env->ThrowTypeError("Takes 3 parameters");
2676 if (!Buffer::HasInstance(args[0])) {
2677 return env->ThrowTypeError("Second argument should be a buffer");
2680 char* buffer_data = Buffer::Data(args[0]);
2681 size_t buffer_length = Buffer::Length(args[0]);
2683 size_t off = args[1]->Int32Value();
2684 size_t len = args[2]->Int32Value();
2686 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2687 return env->ThrowError("off + len > buffer.length");
2690 char* data = buffer_data + off;
2692 if (conn->is_server() && !conn->hello_parser_.IsEnded()) {
2693 // Just accumulate data, everything will be pushed to BIO later
2694 if (conn->hello_parser_.IsPaused()) {
2697 // Copy incoming data to the internal buffer
2698 // (which has a size of the biggest possible TLS frame)
2699 size_t available = sizeof(conn->hello_data_) - conn->hello_offset_;
2700 size_t copied = len < available ? len : available;
2701 memcpy(conn->hello_data_ + conn->hello_offset_, data, copied);
2702 conn->hello_offset_ += copied;
2704 conn->hello_parser_.Parse(conn->hello_data_, conn->hello_offset_);
2705 bytes_written = copied;
2708 bytes_written = BIO_write(conn->bio_read_, data, len);
2709 conn->HandleBIOError(conn->bio_read_, "BIO_write", bytes_written);
2710 conn->SetShutdownFlags();
2713 args.GetReturnValue().Set(bytes_written);
2717 void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
2718 Connection* conn = Unwrap<Connection>(args.Holder());
2719 Environment* env = conn->env();
2721 if (args.Length() < 3) {
2722 return env->ThrowTypeError("Takes 3 parameters");
2725 if (!Buffer::HasInstance(args[0])) {
2726 return env->ThrowTypeError("Second argument should be a buffer");
2729 char* buffer_data = Buffer::Data(args[0]);
2730 size_t buffer_length = Buffer::Length(args[0]);
2732 size_t off = args[1]->Int32Value();
2733 size_t len = args[2]->Int32Value();
2735 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2736 return env->ThrowError("off + len > buffer.length");
2738 if (!SSL_is_init_finished(conn->ssl_)) {
2741 if (conn->is_server()) {
2742 rv = SSL_accept(conn->ssl_);
2743 conn->HandleSSLError("SSL_accept:ClearOut",
2748 rv = SSL_connect(conn->ssl_);
2749 conn->HandleSSLError("SSL_connect:ClearOut",
2756 return args.GetReturnValue().Set(rv);
2760 int bytes_read = SSL_read(conn->ssl_, buffer_data + off, len);
2761 conn->HandleSSLError("SSL_read:ClearOut",
2765 conn->SetShutdownFlags();
2767 args.GetReturnValue().Set(bytes_read);
2771 void Connection::ClearPending(const FunctionCallbackInfo<Value>& args) {
2772 Connection* conn = Unwrap<Connection>(args.Holder());
2773 int bytes_pending = BIO_pending(conn->bio_read_);
2774 args.GetReturnValue().Set(bytes_pending);
2778 void Connection::EncPending(const FunctionCallbackInfo<Value>& args) {
2779 Connection* conn = Unwrap<Connection>(args.Holder());
2780 int bytes_pending = BIO_pending(conn->bio_write_);
2781 args.GetReturnValue().Set(bytes_pending);
2785 void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
2786 Connection* conn = Unwrap<Connection>(args.Holder());
2787 Environment* env = conn->env();
2789 if (args.Length() < 3) {
2790 return env->ThrowTypeError("Takes 3 parameters");
2793 if (!Buffer::HasInstance(args[0])) {
2794 return env->ThrowTypeError("Second argument should be a buffer");
2797 char* buffer_data = Buffer::Data(args[0]);
2798 size_t buffer_length = Buffer::Length(args[0]);
2800 size_t off = args[1]->Int32Value();
2801 size_t len = args[2]->Int32Value();
2803 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2804 return env->ThrowError("off + len > buffer.length");
2806 int bytes_read = BIO_read(conn->bio_write_, buffer_data + off, len);
2808 conn->HandleBIOError(conn->bio_write_, "BIO_read:EncOut", bytes_read);
2809 conn->SetShutdownFlags();
2811 args.GetReturnValue().Set(bytes_read);
2815 void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
2816 Connection* conn = Unwrap<Connection>(args.Holder());
2817 Environment* env = conn->env();
2819 if (args.Length() < 3) {
2820 return env->ThrowTypeError("Takes 3 parameters");
2823 if (!Buffer::HasInstance(args[0])) {
2824 return env->ThrowTypeError("Second argument should be a buffer");
2827 char* buffer_data = Buffer::Data(args[0]);
2828 size_t buffer_length = Buffer::Length(args[0]);
2830 size_t off = args[1]->Int32Value();
2831 size_t len = args[2]->Int32Value();
2833 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2834 return env->ThrowError("off + len > buffer.length");
2836 if (!SSL_is_init_finished(conn->ssl_)) {
2838 if (conn->is_server()) {
2839 rv = SSL_accept(conn->ssl_);
2840 conn->HandleSSLError("SSL_accept:ClearIn",
2845 rv = SSL_connect(conn->ssl_);
2846 conn->HandleSSLError("SSL_connect:ClearIn",
2853 return args.GetReturnValue().Set(rv);
2857 int bytes_written = SSL_write(conn->ssl_, buffer_data + off, len);
2859 conn->HandleSSLError("SSL_write:ClearIn",
2861 len == 0 ? kZeroIsNotAnError : kZeroIsAnError,
2863 conn->SetShutdownFlags();
2865 args.GetReturnValue().Set(bytes_written);
2869 void Connection::Start(const FunctionCallbackInfo<Value>& args) {
2870 Connection* conn = Unwrap<Connection>(args.Holder());
2873 if (!SSL_is_init_finished(conn->ssl_)) {
2874 if (conn->is_server()) {
2875 rv = SSL_accept(conn->ssl_);
2876 conn->HandleSSLError("SSL_accept:Start",
2881 rv = SSL_connect(conn->ssl_);
2882 conn->HandleSSLError("SSL_connect:Start",
2888 args.GetReturnValue().Set(rv);
2892 void Connection::Close(const FunctionCallbackInfo<Value>& args) {
2893 Connection* conn = Unwrap<Connection>(args.Holder());
2895 if (conn->ssl_ != nullptr) {
2896 SSL_free(conn->ssl_);
2897 conn->ssl_ = nullptr;
2902 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2903 void Connection::GetServername(const FunctionCallbackInfo<Value>& args) {
2904 Connection* conn = Unwrap<Connection>(args.Holder());
2906 if (conn->is_server() && !conn->servername_.IsEmpty()) {
2907 args.GetReturnValue().Set(conn->servername_);
2909 args.GetReturnValue().Set(false);
2914 void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) {
2915 Connection* conn = Unwrap<Connection>(args.Holder());
2916 Environment* env = conn->env();
2918 if (args.Length() < 1 || !args[0]->IsFunction()) {
2919 return env->ThrowError("Must give a Function as first argument");
2922 Local<Object> obj = Object::New(env->isolate());
2923 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "onselect"), args[0]);
2924 conn->sniObject_.Reset(args.GetIsolate(), obj);
2929 void CipherBase::Initialize(Environment* env, Local<Object> target) {
2930 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
2932 t->InstanceTemplate()->SetInternalFieldCount(1);
2934 env->SetProtoMethod(t, "init", Init);
2935 env->SetProtoMethod(t, "initiv", InitIv);
2936 env->SetProtoMethod(t, "update", Update);
2937 env->SetProtoMethod(t, "final", Final);
2938 env->SetProtoMethod(t, "setAutoPadding", SetAutoPadding);
2939 env->SetProtoMethod(t, "getAuthTag", GetAuthTag);
2940 env->SetProtoMethod(t, "setAuthTag", SetAuthTag);
2941 env->SetProtoMethod(t, "setAAD", SetAAD);
2943 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "CipherBase"),
2948 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
2949 CHECK_EQ(args.IsConstructCall(), true);
2950 CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
2951 Environment* env = Environment::GetCurrent(args);
2952 new CipherBase(env, args.This(), kind);
2956 void CipherBase::Init(const char* cipher_type,
2957 const char* key_buf,
2959 HandleScope scope(env()->isolate());
2961 #ifdef NODE_FIPS_MODE
2962 return env()->ThrowError(
2963 "crypto.createCipher() is not supported in FIPS mode.");
2964 #endif // NODE_FIPS_MODE
2966 CHECK_EQ(cipher_, nullptr);
2967 cipher_ = EVP_get_cipherbyname(cipher_type);
2968 if (cipher_ == nullptr) {
2969 return env()->ThrowError("Unknown cipher");
2972 unsigned char key[EVP_MAX_KEY_LENGTH];
2973 unsigned char iv[EVP_MAX_IV_LENGTH];
2975 int key_len = EVP_BytesToKey(cipher_,
2978 reinterpret_cast<const unsigned char*>(key_buf),
2984 EVP_CIPHER_CTX_init(&ctx_);
2985 const bool encrypt = (kind_ == kCipher);
2986 EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
2987 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2988 EVP_CIPHER_CTX_cleanup(&ctx_);
2989 return env()->ThrowError("Invalid key length");
2992 EVP_CipherInit_ex(&ctx_,
2995 reinterpret_cast<unsigned char*>(key),
2996 reinterpret_cast<unsigned char*>(iv),
2998 initialised_ = true;
3002 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
3003 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3005 if (args.Length() < 2 ||
3006 !(args[0]->IsString() && Buffer::HasInstance(args[1]))) {
3007 return cipher->env()->ThrowError("Must give cipher-type, key");
3010 const node::Utf8Value cipher_type(args.GetIsolate(), args[0]);
3011 const char* key_buf = Buffer::Data(args[1]);
3012 ssize_t key_buf_len = Buffer::Length(args[1]);
3013 cipher->Init(*cipher_type, key_buf, key_buf_len);
3017 void CipherBase::InitIv(const char* cipher_type,
3022 HandleScope scope(env()->isolate());
3024 cipher_ = EVP_get_cipherbyname(cipher_type);
3025 if (cipher_ == nullptr) {
3026 return env()->ThrowError("Unknown cipher");
3029 /* OpenSSL versions up to 0.9.8l failed to return the correct
3030 iv_length (0) for ECB ciphers */
3031 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
3032 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
3033 return env()->ThrowError("Invalid IV length");
3035 EVP_CIPHER_CTX_init(&ctx_);
3036 const bool encrypt = (kind_ == kCipher);
3037 EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
3038 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
3039 EVP_CIPHER_CTX_cleanup(&ctx_);
3040 return env()->ThrowError("Invalid key length");
3043 EVP_CipherInit_ex(&ctx_,
3046 reinterpret_cast<const unsigned char*>(key),
3047 reinterpret_cast<const unsigned char*>(iv),
3049 initialised_ = true;
3053 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
3054 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3055 Environment* env = cipher->env();
3057 if (args.Length() < 3 || !args[0]->IsString()) {
3058 return env->ThrowError("Must give cipher-type, key, and iv as argument");
3061 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
3062 THROW_AND_RETURN_IF_NOT_BUFFER(args[2]);
3064 const node::Utf8Value cipher_type(env->isolate(), args[0]);
3065 ssize_t key_len = Buffer::Length(args[1]);
3066 const char* key_buf = Buffer::Data(args[1]);
3067 ssize_t iv_len = Buffer::Length(args[2]);
3068 const char* iv_buf = Buffer::Data(args[2]);
3069 cipher->InitIv(*cipher_type, key_buf, key_len, iv_buf, iv_len);
3073 bool CipherBase::IsAuthenticatedMode() const {
3074 // check if this cipher operates in an AEAD mode that we support.
3077 int mode = EVP_CIPHER_mode(cipher_);
3078 return mode == EVP_CIPH_GCM_MODE;
3082 bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
3083 // only callable after Final and if encrypting.
3084 if (initialised_ || kind_ != kCipher || !auth_tag_)
3086 *out_len = auth_tag_len_;
3087 *out = static_cast<char*>(malloc(auth_tag_len_));
3088 CHECK_NE(*out, nullptr);
3089 memcpy(*out, auth_tag_, auth_tag_len_);
3094 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
3095 Environment* env = Environment::GetCurrent(args);
3096 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3098 char* out = nullptr;
3099 unsigned int out_len = 0;
3101 if (cipher->GetAuthTag(&out, &out_len)) {
3102 Local<Object> buf = Buffer::New(env, out, out_len).ToLocalChecked();
3103 args.GetReturnValue().Set(buf);
3105 env->ThrowError("Attempting to get auth tag in unsupported state");
3110 bool CipherBase::SetAuthTag(const char* data, unsigned int len) {
3111 if (!initialised_ || !IsAuthenticatedMode() || kind_ != kDecipher)
3114 auth_tag_len_ = len;
3115 auth_tag_ = new char[len];
3116 memcpy(auth_tag_, data, len);
3121 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
3122 Environment* env = Environment::GetCurrent(args);
3124 Local<Object> buf = args[0].As<Object>();
3125 if (!buf->IsObject() || !Buffer::HasInstance(buf))
3126 return env->ThrowTypeError("Argument must be a Buffer");
3128 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3130 if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf)))
3131 env->ThrowError("Attempting to set auth tag in unsupported state");
3135 bool CipherBase::SetAAD(const char* data, unsigned int len) {
3136 if (!initialised_ || !IsAuthenticatedMode())
3139 if (!EVP_CipherUpdate(&ctx_,
3142 reinterpret_cast<const unsigned char*>(data),
3150 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
3151 Environment* env = Environment::GetCurrent(args);
3153 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3155 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3157 if (!cipher->SetAAD(Buffer::Data(args[0]), Buffer::Length(args[0])))
3158 env->ThrowError("Attempting to set AAD in unsupported state");
3162 bool CipherBase::Update(const char* data,
3164 unsigned char** out,
3170 if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_ != nullptr) {
3171 EVP_CIPHER_CTX_ctrl(&ctx_,
3172 EVP_CTRL_GCM_SET_TAG,
3174 reinterpret_cast<unsigned char*>(auth_tag_));
3176 auth_tag_ = nullptr;
3179 *out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
3180 *out = new unsigned char[*out_len];
3181 return EVP_CipherUpdate(&ctx_,
3184 reinterpret_cast<const unsigned char*>(data),
3189 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
3190 Environment* env = Environment::GetCurrent(args);
3192 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3194 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3196 unsigned char* out = nullptr;
3200 // Only copy the data if we have to, because it's a string
3201 if (args[0]->IsString()) {
3202 StringBytes::InlineDecoder decoder;
3203 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3205 r = cipher->Update(decoder.out(), decoder.size(), &out, &out_len);
3207 char* buf = Buffer::Data(args[0]);
3208 size_t buflen = Buffer::Length(args[0]);
3209 r = cipher->Update(buf, buflen, &out, &out_len);
3214 return ThrowCryptoError(env,
3216 "Trying to add data in unsupported state");
3219 CHECK(out != nullptr || out_len == 0);
3221 Buffer::Copy(env, reinterpret_cast<char*>(out), out_len).ToLocalChecked();
3225 args.GetReturnValue().Set(buf);
3229 bool CipherBase::SetAutoPadding(bool auto_padding) {
3232 return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
3236 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
3237 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3238 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
3242 bool CipherBase::Final(unsigned char** out, int *out_len) {
3246 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx_)];
3247 int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
3249 if (r && kind_ == kCipher) {
3251 auth_tag_ = nullptr;
3252 if (IsAuthenticatedMode()) {
3253 auth_tag_len_ = EVP_GCM_TLS_TAG_LEN; // use default tag length
3254 auth_tag_ = new char[auth_tag_len_];
3255 memset(auth_tag_, 0, auth_tag_len_);
3256 EVP_CIPHER_CTX_ctrl(&ctx_,
3257 EVP_CTRL_GCM_GET_TAG,
3259 reinterpret_cast<unsigned char*>(auth_tag_));
3263 EVP_CIPHER_CTX_cleanup(&ctx_);
3264 initialised_ = false;
3270 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
3271 Environment* env = Environment::GetCurrent(args);
3273 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3275 unsigned char* out_value = nullptr;
3277 Local<Value> outString;
3279 bool r = cipher->Final(&out_value, &out_len);
3281 if (out_len <= 0 || !r) {
3283 out_value = nullptr;
3286 const char* msg = cipher->IsAuthenticatedMode() ?
3287 "Unsupported state or unable to authenticate data" :
3288 "Unsupported state";
3290 return ThrowCryptoError(env,
3296 Local<Object> buf = Buffer::Copy(
3298 reinterpret_cast<char*>(out_value),
3299 out_len).ToLocalChecked();
3300 args.GetReturnValue().Set(buf);
3305 void Hmac::Initialize(Environment* env, v8::Local<v8::Object> target) {
3306 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3308 t->InstanceTemplate()->SetInternalFieldCount(1);
3310 env->SetProtoMethod(t, "init", HmacInit);
3311 env->SetProtoMethod(t, "update", HmacUpdate);
3312 env->SetProtoMethod(t, "digest", HmacDigest);
3314 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hmac"), t->GetFunction());
3318 void Hmac::New(const FunctionCallbackInfo<Value>& args) {
3319 Environment* env = Environment::GetCurrent(args);
3320 new Hmac(env, args.This());
3324 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
3325 HandleScope scope(env()->isolate());
3327 CHECK_EQ(md_, nullptr);
3328 md_ = EVP_get_digestbyname(hash_type);
3329 if (md_ == nullptr) {
3330 return env()->ThrowError("Unknown message digest");
3332 HMAC_CTX_init(&ctx_);
3335 result = HMAC_Init(&ctx_, "", 0, md_);
3337 result = HMAC_Init(&ctx_, key, key_len, md_);
3340 return ThrowCryptoError(env(), ERR_get_error());
3342 initialised_ = true;
3346 void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
3347 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3348 Environment* env = hmac->env();
3350 if (args.Length() < 2 || !args[0]->IsString()) {
3351 return env->ThrowError("Must give hashtype string, key as arguments");
3354 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
3356 const node::Utf8Value hash_type(env->isolate(), args[0]);
3357 const char* buffer_data = Buffer::Data(args[1]);
3358 size_t buffer_length = Buffer::Length(args[1]);
3359 hmac->HmacInit(*hash_type, buffer_data, buffer_length);
3363 bool Hmac::HmacUpdate(const char* data, int len) {
3366 HMAC_Update(&ctx_, reinterpret_cast<const unsigned char*>(data), len);
3371 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
3372 Environment* env = Environment::GetCurrent(args);
3374 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3376 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3378 // Only copy the data if we have to, because it's a string
3380 if (args[0]->IsString()) {
3381 StringBytes::InlineDecoder decoder;
3382 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3384 r = hmac->HmacUpdate(decoder.out(), decoder.size());
3386 char* buf = Buffer::Data(args[0]);
3387 size_t buflen = Buffer::Length(args[0]);
3388 r = hmac->HmacUpdate(buf, buflen);
3392 return env->ThrowTypeError("HmacUpdate fail");
3397 bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
3400 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
3401 HMAC_Final(&ctx_, *md_value, md_len);
3402 HMAC_CTX_cleanup(&ctx_);
3403 initialised_ = false;
3408 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
3409 Environment* env = Environment::GetCurrent(args);
3411 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3413 enum encoding encoding = BUFFER;
3414 if (args.Length() >= 1) {
3415 encoding = ParseEncoding(env->isolate(),
3416 args[0]->ToString(env->isolate()),
3420 unsigned char* md_value = nullptr;
3421 unsigned int md_len = 0;
3423 bool r = hmac->HmacDigest(&md_value, &md_len);
3429 Local<Value> rc = StringBytes::Encode(env->isolate(),
3430 reinterpret_cast<const char*>(md_value),
3434 args.GetReturnValue().Set(rc);
3438 void Hash::Initialize(Environment* env, v8::Local<v8::Object> target) {
3439 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3441 t->InstanceTemplate()->SetInternalFieldCount(1);
3443 env->SetProtoMethod(t, "update", HashUpdate);
3444 env->SetProtoMethod(t, "digest", HashDigest);
3446 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hash"), t->GetFunction());
3450 void Hash::New(const FunctionCallbackInfo<Value>& args) {
3451 Environment* env = Environment::GetCurrent(args);
3453 if (args.Length() == 0 || !args[0]->IsString()) {
3454 return env->ThrowError("Must give hashtype string as argument");
3457 const node::Utf8Value hash_type(env->isolate(), args[0]);
3459 Hash* hash = new Hash(env, args.This());
3460 if (!hash->HashInit(*hash_type)) {
3461 return ThrowCryptoError(env, ERR_get_error(),
3462 "Digest method not supported");
3467 bool Hash::HashInit(const char* hash_type) {
3468 CHECK_EQ(md_, nullptr);
3469 md_ = EVP_get_digestbyname(hash_type);
3472 EVP_MD_CTX_init(&mdctx_);
3473 if (EVP_DigestInit_ex(&mdctx_, md_, nullptr) <= 0) {
3476 initialised_ = true;
3481 bool Hash::HashUpdate(const char* data, int len) {
3484 EVP_DigestUpdate(&mdctx_, data, len);
3489 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
3490 Environment* env = Environment::GetCurrent(args);
3492 Hash* hash = Unwrap<Hash>(args.Holder());
3494 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3496 // Only copy the data if we have to, because it's a string
3498 if (args[0]->IsString()) {
3499 StringBytes::InlineDecoder decoder;
3500 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3502 r = hash->HashUpdate(decoder.out(), decoder.size());
3504 char* buf = Buffer::Data(args[0]);
3505 size_t buflen = Buffer::Length(args[0]);
3506 r = hash->HashUpdate(buf, buflen);
3510 return env->ThrowTypeError("HashUpdate fail");
3515 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
3516 Environment* env = Environment::GetCurrent(args);
3518 Hash* hash = Unwrap<Hash>(args.Holder());
3520 if (!hash->initialised_) {
3521 return env->ThrowError("Not initialized");
3524 enum encoding encoding = BUFFER;
3525 if (args.Length() >= 1) {
3526 encoding = ParseEncoding(env->isolate(),
3527 args[0]->ToString(env->isolate()),
3531 unsigned char md_value[EVP_MAX_MD_SIZE];
3532 unsigned int md_len;
3534 EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len);
3535 EVP_MD_CTX_cleanup(&hash->mdctx_);
3536 hash->initialised_ = false;
3538 Local<Value> rc = StringBytes::Encode(env->isolate(),
3539 reinterpret_cast<const char*>(md_value),
3542 args.GetReturnValue().Set(rc);
3546 void SignBase::CheckThrow(SignBase::Error error) {
3547 HandleScope scope(env()->isolate());
3550 case kSignUnknownDigest:
3551 return env()->ThrowError("Unknown message digest");
3553 case kSignNotInitialised:
3554 return env()->ThrowError("Not initialised");
3558 case kSignPrivateKey:
3559 case kSignPublicKey:
3561 unsigned long err = ERR_get_error();
3563 return ThrowCryptoError(env(), err);
3566 return env()->ThrowError("EVP_SignInit_ex failed");
3568 return env()->ThrowError("EVP_SignUpdate failed");
3569 case kSignPrivateKey:
3570 return env()->ThrowError("PEM_read_bio_PrivateKey failed");
3571 case kSignPublicKey:
3572 return env()->ThrowError("PEM_read_bio_PUBKEY failed");
3586 void Sign::Initialize(Environment* env, v8::Local<v8::Object> target) {
3587 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3589 t->InstanceTemplate()->SetInternalFieldCount(1);
3591 env->SetProtoMethod(t, "init", SignInit);
3592 env->SetProtoMethod(t, "update", SignUpdate);
3593 env->SetProtoMethod(t, "sign", SignFinal);
3595 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"), t->GetFunction());
3599 void Sign::New(const FunctionCallbackInfo<Value>& args) {
3600 Environment* env = Environment::GetCurrent(args);
3601 new Sign(env, args.This());
3605 SignBase::Error Sign::SignInit(const char* sign_type) {
3606 CHECK_EQ(md_, nullptr);
3607 md_ = EVP_get_digestbyname(sign_type);
3609 return kSignUnknownDigest;
3611 EVP_MD_CTX_init(&mdctx_);
3612 if (!EVP_SignInit_ex(&mdctx_, md_, nullptr))
3614 initialised_ = true;
3620 void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
3621 Sign* sign = Unwrap<Sign>(args.Holder());
3623 if (args.Length() == 0 || !args[0]->IsString()) {
3624 return sign->env()->ThrowError("Must give signtype string as argument");
3627 const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
3628 sign->CheckThrow(sign->SignInit(*sign_type));
3632 SignBase::Error Sign::SignUpdate(const char* data, int len) {
3634 return kSignNotInitialised;
3635 if (!EVP_SignUpdate(&mdctx_, data, len))
3641 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
3642 Environment* env = Environment::GetCurrent(args);
3644 Sign* sign = Unwrap<Sign>(args.Holder());
3646 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3648 // Only copy the data if we have to, because it's a string
3650 if (args[0]->IsString()) {
3651 StringBytes::InlineDecoder decoder;
3652 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3654 err = sign->SignUpdate(decoder.out(), decoder.size());
3656 char* buf = Buffer::Data(args[0]);
3657 size_t buflen = Buffer::Length(args[0]);
3658 err = sign->SignUpdate(buf, buflen);
3661 sign->CheckThrow(err);
3665 SignBase::Error Sign::SignFinal(const char* key_pem,
3667 const char* passphrase,
3668 unsigned char** sig,
3669 unsigned int *sig_len) {
3671 return kSignNotInitialised;
3674 EVP_PKEY* pkey = nullptr;
3677 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3681 pkey = PEM_read_bio_PrivateKey(bp,
3684 const_cast<char*>(passphrase));
3686 // Errors might be injected into OpenSSL's error stack
3687 // without `pkey` being set to nullptr;
3688 // cf. the test of `test_bad_rsa_privkey.pem` for an example.
3689 if (pkey == nullptr || 0 != ERR_peek_error())
3692 #ifdef NODE_FIPS_MODE
3693 /* Validate DSA2 parameters from FIPS 186-4 */
3694 if (EVP_PKEY_DSA == pkey->type) {
3695 size_t L = BN_num_bits(pkey->pkey.dsa->p);
3696 size_t N = BN_num_bits(pkey->pkey.dsa->q);
3697 bool result = false;
3699 if (L == 1024 && N == 160)
3701 else if (L == 2048 && N == 224)
3703 else if (L == 2048 && N == 256)
3705 else if (L == 3072 && N == 256)
3713 #endif // NODE_FIPS_MODE
3715 if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey))
3718 initialised_ = false;
3721 if (pkey != nullptr)
3722 EVP_PKEY_free(pkey);
3726 EVP_MD_CTX_cleanup(&mdctx_);
3729 return kSignPrivateKey;
3735 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
3736 Environment* env = Environment::GetCurrent(args);
3738 Sign* sign = Unwrap<Sign>(args.Holder());
3740 unsigned char* md_value;
3741 unsigned int md_len;
3743 unsigned int len = args.Length();
3744 enum encoding encoding = BUFFER;
3745 if (len >= 2 && args[1]->IsString()) {
3746 encoding = ParseEncoding(env->isolate(),
3747 args[1]->ToString(env->isolate()),
3751 node::Utf8Value passphrase(env->isolate(), args[2]);
3753 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3754 size_t buf_len = Buffer::Length(args[0]);
3755 char* buf = Buffer::Data(args[0]);
3757 md_len = 8192; // Maximum key size is 8192 bits
3758 md_value = new unsigned char[md_len];
3760 ClearErrorOnReturn clear_error_on_return;
3761 (void) &clear_error_on_return; // Silence compiler warning.
3763 Error err = sign->SignFinal(
3766 len >= 3 && !args[2]->IsNull() ? *passphrase : nullptr,
3769 if (err != kSignOk) {
3773 return sign->CheckThrow(err);
3776 Local<Value> rc = StringBytes::Encode(env->isolate(),
3777 reinterpret_cast<const char*>(md_value),
3781 args.GetReturnValue().Set(rc);
3785 void Verify::Initialize(Environment* env, v8::Local<v8::Object> target) {
3786 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3788 t->InstanceTemplate()->SetInternalFieldCount(1);
3790 env->SetProtoMethod(t, "init", VerifyInit);
3791 env->SetProtoMethod(t, "update", VerifyUpdate);
3792 env->SetProtoMethod(t, "verify", VerifyFinal);
3794 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
3799 void Verify::New(const FunctionCallbackInfo<Value>& args) {
3800 Environment* env = Environment::GetCurrent(args);
3801 new Verify(env, args.This());
3805 SignBase::Error Verify::VerifyInit(const char* verify_type) {
3806 CHECK_EQ(md_, nullptr);
3807 md_ = EVP_get_digestbyname(verify_type);
3809 return kSignUnknownDigest;
3811 EVP_MD_CTX_init(&mdctx_);
3812 if (!EVP_VerifyInit_ex(&mdctx_, md_, nullptr))
3814 initialised_ = true;
3820 void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
3821 Verify* verify = Unwrap<Verify>(args.Holder());
3823 if (args.Length() == 0 || !args[0]->IsString()) {
3824 return verify->env()->ThrowError("Must give verifytype string as argument");
3827 const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
3828 verify->CheckThrow(verify->VerifyInit(*verify_type));
3832 SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
3834 return kSignNotInitialised;
3836 if (!EVP_VerifyUpdate(&mdctx_, data, len))
3843 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
3844 Environment* env = Environment::GetCurrent(args);
3846 Verify* verify = Unwrap<Verify>(args.Holder());
3848 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3850 // Only copy the data if we have to, because it's a string
3852 if (args[0]->IsString()) {
3853 StringBytes::InlineDecoder decoder;
3854 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3856 err = verify->VerifyUpdate(decoder.out(), decoder.size());
3858 char* buf = Buffer::Data(args[0]);
3859 size_t buflen = Buffer::Length(args[0]);
3860 err = verify->VerifyUpdate(buf, buflen);
3863 verify->CheckThrow(err);
3867 SignBase::Error Verify::VerifyFinal(const char* key_pem,
3871 bool* verify_result) {
3873 return kSignNotInitialised;
3875 ClearErrorOnReturn clear_error_on_return;
3876 (void) &clear_error_on_return; // Silence compiler warning.
3878 EVP_PKEY* pkey = nullptr;
3880 X509* x509 = nullptr;
3884 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3888 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3889 // Split this out into a separate function once we have more than one
3890 // consumer of public keys.
3891 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3892 pkey = PEM_read_bio_PUBKEY(bp, nullptr, CryptoPemCallback, nullptr);
3893 if (pkey == nullptr)
3895 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3897 PEM_read_bio_RSAPublicKey(bp, nullptr, CryptoPemCallback, nullptr);
3899 pkey = EVP_PKEY_new();
3901 EVP_PKEY_set1_RSA(pkey, rsa);
3904 if (pkey == nullptr)
3908 x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
3909 if (x509 == nullptr)
3912 pkey = X509_get_pubkey(x509);
3913 if (pkey == nullptr)
3918 r = EVP_VerifyFinal(&mdctx_,
3919 reinterpret_cast<const unsigned char*>(sig),
3924 if (pkey != nullptr)
3925 EVP_PKEY_free(pkey);
3928 if (x509 != nullptr)
3931 EVP_MD_CTX_cleanup(&mdctx_);
3932 initialised_ = false;
3935 return kSignPublicKey;
3937 *verify_result = r == 1;
3942 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
3943 Environment* env = Environment::GetCurrent(args);
3945 Verify* verify = Unwrap<Verify>(args.Holder());
3947 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3948 char* kbuf = Buffer::Data(args[0]);
3949 ssize_t klen = Buffer::Length(args[0]);
3951 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[1]);
3953 // BINARY works for both buffers and binary strings.
3954 enum encoding encoding = BINARY;
3955 if (args.Length() >= 3) {
3956 encoding = ParseEncoding(env->isolate(),
3957 args[2]->ToString(env->isolate()),
3961 ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);
3963 // only copy if we need to, because it's a string.
3965 if (args[1]->IsString()) {
3966 hbuf = new char[hlen];
3967 ssize_t hwritten = StringBytes::Write(env->isolate(),
3972 CHECK_EQ(hwritten, hlen);
3974 hbuf = Buffer::Data(args[1]);
3978 Error err = verify->VerifyFinal(kbuf, klen, hbuf, hlen, &verify_result);
3979 if (args[1]->IsString())
3982 return verify->CheckThrow(err);
3983 args.GetReturnValue().Set(verify_result);
3987 template <PublicKeyCipher::Operation operation,
3988 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3989 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3990 bool PublicKeyCipher::Cipher(const char* key_pem,
3992 const char* passphrase,
3994 const unsigned char* data,
3996 unsigned char** out,
3998 EVP_PKEY* pkey = nullptr;
3999 EVP_PKEY_CTX* ctx = nullptr;
4001 X509* x509 = nullptr;
4004 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
4008 // Check if this is a PKCS#8 or RSA public key before trying as X.509 and
4010 if (operation == kPublic &&
4011 strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
4012 pkey = PEM_read_bio_PUBKEY(bp, nullptr, nullptr, nullptr);
4013 if (pkey == nullptr)
4015 } else if (operation == kPublic &&
4016 strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
4017 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, nullptr, nullptr, nullptr);
4019 pkey = EVP_PKEY_new();
4021 EVP_PKEY_set1_RSA(pkey, rsa);
4024 if (pkey == nullptr)
4026 } else if (operation == kPublic &&
4027 strncmp(key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0) {
4028 x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
4029 if (x509 == nullptr)
4032 pkey = X509_get_pubkey(x509);
4033 if (pkey == nullptr)
4036 pkey = PEM_read_bio_PrivateKey(bp,
4039 const_cast<char*>(passphrase));
4040 if (pkey == nullptr)
4044 ctx = EVP_PKEY_CTX_new(pkey, nullptr);
4047 if (EVP_PKEY_cipher_init(ctx) <= 0)
4049 if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0)
4052 if (EVP_PKEY_cipher(ctx, nullptr, out_len, data, len) <= 0)
4055 *out = new unsigned char[*out_len];
4057 if (EVP_PKEY_cipher(ctx, *out, out_len, data, len) <= 0)
4063 if (x509 != nullptr)
4065 if (pkey != nullptr)
4066 EVP_PKEY_free(pkey);
4070 EVP_PKEY_CTX_free(ctx);
4076 template <PublicKeyCipher::Operation operation,
4077 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
4078 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
4079 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
4080 Environment* env = Environment::GetCurrent(args);
4082 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4083 char* kbuf = Buffer::Data(args[0]);
4084 ssize_t klen = Buffer::Length(args[0]);
4086 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
4087 char* buf = Buffer::Data(args[1]);
4088 ssize_t len = Buffer::Length(args[1]);
4090 int padding = args[2]->Uint32Value();
4092 String::Utf8Value passphrase(args[3]);
4094 unsigned char* out_value = nullptr;
4097 ClearErrorOnReturn clear_error_on_return;
4098 (void) &clear_error_on_return; // Silence compiler warning.
4100 bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
4103 args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : nullptr,
4105 reinterpret_cast<const unsigned char*>(buf),
4110 if (out_len == 0 || !r) {
4112 out_value = nullptr;
4115 return ThrowCryptoError(env,
4120 Local<Object> vbuf = Buffer::Copy(
4122 reinterpret_cast<char*>(out_value),
4123 out_len).ToLocalChecked();
4124 args.GetReturnValue().Set(vbuf);
4129 void DiffieHellman::Initialize(Environment* env, Local<Object> target) {
4130 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4132 const PropertyAttribute attributes =
4133 static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
4135 t->InstanceTemplate()->SetInternalFieldCount(1);
4137 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
4138 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
4139 env->SetProtoMethod(t, "getPrime", GetPrime);
4140 env->SetProtoMethod(t, "getGenerator", GetGenerator);
4141 env->SetProtoMethod(t, "getPublicKey", GetPublicKey);
4142 env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey);
4143 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
4144 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
4146 t->InstanceTemplate()->SetAccessor(
4147 env->verify_error_string(),
4148 DiffieHellman::VerifyErrorGetter,
4153 AccessorSignature::New(env->isolate(), t));
4155 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"),
4158 Local<FunctionTemplate> t2 = env->NewFunctionTemplate(DiffieHellmanGroup);
4159 t2->InstanceTemplate()->SetInternalFieldCount(1);
4161 env->SetProtoMethod(t2, "generateKeys", GenerateKeys);
4162 env->SetProtoMethod(t2, "computeSecret", ComputeSecret);
4163 env->SetProtoMethod(t2, "getPrime", GetPrime);
4164 env->SetProtoMethod(t2, "getGenerator", GetGenerator);
4165 env->SetProtoMethod(t2, "getPublicKey", GetPublicKey);
4166 env->SetProtoMethod(t2, "getPrivateKey", GetPrivateKey);
4168 t2->InstanceTemplate()->SetAccessor(
4169 env->verify_error_string(),
4170 DiffieHellman::VerifyErrorGetter,
4175 AccessorSignature::New(env->isolate(), t2));
4177 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
4182 bool DiffieHellman::Init(int primeLength, int g) {
4184 if (!DH_generate_parameters_ex(dh, primeLength, g, 0))
4186 bool result = VerifyContext();
4189 initialised_ = true;
4194 bool DiffieHellman::Init(const char* p, int p_len, int g) {
4196 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
4198 if (!BN_set_word(dh->g, g))
4200 bool result = VerifyContext();
4203 initialised_ = true;
4208 bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
4210 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
4211 dh->g = BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, 0);
4212 bool result = VerifyContext();
4215 initialised_ = true;
4220 void DiffieHellman::DiffieHellmanGroup(
4221 const FunctionCallbackInfo<Value>& args) {
4222 Environment* env = Environment::GetCurrent(args);
4223 DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
4225 if (args.Length() != 1 || !args[0]->IsString()) {
4226 return env->ThrowError("No group name given");
4229 bool initialized = false;
4231 const node::Utf8Value group_name(env->isolate(), args[0]);
4232 for (unsigned int i = 0; i < ARRAY_SIZE(modp_groups); ++i) {
4233 const modp_group* it = modp_groups + i;
4235 if (strcasecmp(*group_name, it->name) != 0)
4238 initialized = diffieHellman->Init(it->prime,
4243 env->ThrowError("Initialization failed");
4247 env->ThrowError("Unknown group");
4251 void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
4252 Environment* env = Environment::GetCurrent(args);
4253 DiffieHellman* diffieHellman =
4254 new DiffieHellman(env, args.This());
4255 bool initialized = false;
4257 if (args.Length() == 2) {
4258 if (args[0]->IsInt32()) {
4259 if (args[1]->IsInt32()) {
4260 initialized = diffieHellman->Init(args[0]->Int32Value(),
4261 args[1]->Int32Value());
4264 if (args[1]->IsInt32()) {
4265 initialized = diffieHellman->Init(Buffer::Data(args[0]),
4266 Buffer::Length(args[0]),
4267 args[1]->Int32Value());
4269 initialized = diffieHellman->Init(Buffer::Data(args[0]),
4270 Buffer::Length(args[0]),
4271 Buffer::Data(args[1]),
4272 Buffer::Length(args[1]));
4278 return ThrowCryptoError(env, ERR_get_error(), "Initialization failed");
4283 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4284 Environment* env = Environment::GetCurrent(args);
4286 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4288 if (!diffieHellman->initialised_) {
4289 return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
4292 if (!DH_generate_key(diffieHellman->dh)) {
4293 return ThrowCryptoError(env, ERR_get_error(), "Key generation failed");
4296 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
4297 char* data = new char[dataSize];
4298 BN_bn2bin(diffieHellman->dh->pub_key,
4299 reinterpret_cast<unsigned char*>(data));
4301 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4306 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
4307 Environment* env = Environment::GetCurrent(args);
4309 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4311 if (!diffieHellman->initialised_) {
4312 return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
4315 int dataSize = BN_num_bytes(diffieHellman->dh->p);
4316 char* data = new char[dataSize];
4317 BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
4319 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4324 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
4325 Environment* env = Environment::GetCurrent(args);
4327 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4329 if (!diffieHellman->initialised_) {
4330 return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
4333 int dataSize = BN_num_bytes(diffieHellman->dh->g);
4334 char* data = new char[dataSize];
4335 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
4337 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4342 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
4343 Environment* env = Environment::GetCurrent(args);
4345 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4347 if (!diffieHellman->initialised_) {
4348 return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
4351 if (diffieHellman->dh->pub_key == nullptr) {
4352 return env->ThrowError("No public key - did you forget to generate one?");
4355 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
4356 char* data = new char[dataSize];
4357 BN_bn2bin(diffieHellman->dh->pub_key,
4358 reinterpret_cast<unsigned char*>(data));
4360 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4365 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4366 Environment* env = Environment::GetCurrent(args);
4368 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4370 if (!diffieHellman->initialised_) {
4371 return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
4374 if (diffieHellman->dh->priv_key == nullptr) {
4375 return env->ThrowError("No private key - did you forget to generate one?");
4378 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
4379 char* data = new char[dataSize];
4380 BN_bn2bin(diffieHellman->dh->priv_key,
4381 reinterpret_cast<unsigned char*>(data));
4383 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4388 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4389 Environment* env = Environment::GetCurrent(args);
4391 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4393 if (!diffieHellman->initialised_) {
4394 return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
4397 ClearErrorOnReturn clear_error_on_return;
4398 (void) &clear_error_on_return; // Silence compiler warning.
4399 BIGNUM* key = nullptr;
4401 if (args.Length() == 0) {
4402 return env->ThrowError("First argument must be other party's public key");
4404 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4406 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4407 Buffer::Length(args[0]),
4411 int dataSize = DH_size(diffieHellman->dh);
4412 char* data = new char[dataSize];
4414 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
4422 checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
4427 return ThrowCryptoError(env, ERR_get_error(), "Invalid Key");
4428 } else if (checkResult) {
4429 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
4430 return env->ThrowError("Supplied key is too small");
4431 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
4432 return env->ThrowError("Supplied key is too large");
4434 return env->ThrowError("Invalid key");
4437 return env->ThrowError("Invalid key");
4444 // DH_size returns number of bytes in a prime number
4445 // DH_compute_key returns number of bytes in a remainder of exponent, which
4446 // may have less bytes than a prime number. Therefore add 0-padding to the
4447 // allocated buffer.
4448 if (size != dataSize) {
4449 CHECK(dataSize > size);
4450 memmove(data + dataSize - size, data, size);
4451 memset(data, 0, dataSize - size);
4454 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4459 void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4460 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4461 Environment* env = diffieHellman->env();
4463 if (!diffieHellman->initialised_) {
4464 return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
4467 if (args.Length() == 0) {
4468 return env->ThrowError("First argument must be public key");
4470 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4471 diffieHellman->dh->pub_key = BN_bin2bn(
4472 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4473 Buffer::Length(args[0]), 0);
4478 void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4479 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4480 Environment* env = diffieHellman->env();
4482 if (!diffieHellman->initialised_) {
4483 return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
4486 if (args.Length() == 0) {
4487 return env->ThrowError("First argument must be private key");
4489 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4490 diffieHellman->dh->priv_key = BN_bin2bn(
4491 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4492 Buffer::Length(args[0]),
4498 void DiffieHellman::VerifyErrorGetter(Local<String> property,
4499 const PropertyCallbackInfo<Value>& args) {
4500 HandleScope scope(args.GetIsolate());
4502 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4504 if (!diffieHellman->initialised_)
4505 return ThrowCryptoError(diffieHellman->env(), ERR_get_error(),
4508 args.GetReturnValue().Set(diffieHellman->verifyError_);
4512 bool DiffieHellman::VerifyContext() {
4514 if (!DH_check(dh, &codes))
4516 verifyError_ = codes;
4521 void ECDH::Initialize(Environment* env, Local<Object> target) {
4522 HandleScope scope(env->isolate());
4524 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4526 t->InstanceTemplate()->SetInternalFieldCount(1);
4528 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
4529 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
4530 env->SetProtoMethod(t, "getPublicKey", GetPublicKey);
4531 env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey);
4532 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
4533 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
4535 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH"),
4540 void ECDH::New(const FunctionCallbackInfo<Value>& args) {
4541 Environment* env = Environment::GetCurrent(args);
4543 MarkPopErrorOnReturn mark_pop_error_on_return;
4545 // TODO(indutny): Support raw curves?
4546 CHECK(args[0]->IsString());
4547 node::Utf8Value curve(env->isolate(), args[0]);
4549 int nid = OBJ_sn2nid(*curve);
4550 if (nid == NID_undef)
4551 return env->ThrowTypeError("First argument should be a valid curve name");
4553 EC_KEY* key = EC_KEY_new_by_curve_name(nid);
4555 return env->ThrowError("Failed to create EC_KEY using curve name");
4557 new ECDH(env, args.This(), key);
4561 void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4562 Environment* env = Environment::GetCurrent(args);
4564 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4566 if (!EC_KEY_generate_key(ecdh->key_))
4567 return env->ThrowError("Failed to generate EC_KEY");
4569 ecdh->generated_ = true;
4573 EC_POINT* ECDH::BufferToPoint(char* data, size_t len) {
4577 pub = EC_POINT_new(group_);
4578 if (pub == nullptr) {
4579 env()->ThrowError("Failed to allocate EC_POINT for a public key");
4583 r = EC_POINT_oct2point(
4586 reinterpret_cast<unsigned char*>(data),
4590 env()->ThrowError("Failed to translate Buffer to a EC_POINT");
4602 void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4603 Environment* env = Environment::GetCurrent(args);
4605 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4607 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4609 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0]),
4610 Buffer::Length(args[0]));
4614 // NOTE: field_size is in bits
4615 int field_size = EC_GROUP_get_degree(ecdh->group_);
4616 size_t out_len = (field_size + 7) / 8;
4617 char* out = static_cast<char*>(malloc(out_len));
4618 CHECK_NE(out, nullptr);
4620 int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr);
4624 return env->ThrowError("Failed to compute ECDH key");
4627 Local<Object> buf = Buffer::New(env, out, out_len).ToLocalChecked();
4628 args.GetReturnValue().Set(buf);
4632 void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
4633 Environment* env = Environment::GetCurrent(args);
4636 CHECK_EQ(args.Length(), 1);
4638 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4640 if (!ecdh->generated_)
4641 return env->ThrowError("You should generate ECDH keys first");
4643 const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_);
4645 return env->ThrowError("Failed to get ECDH public key");
4648 point_conversion_form_t form =
4649 static_cast<point_conversion_form_t>(args[0]->Uint32Value());
4651 size = EC_POINT_point2oct(ecdh->group_, pub, form, nullptr, 0, nullptr);
4653 return env->ThrowError("Failed to get public key length");
4655 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4656 CHECK_NE(out, nullptr);
4658 int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr);
4661 return env->ThrowError("Failed to get public key");
4665 Buffer::New(env, reinterpret_cast<char*>(out), size).ToLocalChecked();
4666 args.GetReturnValue().Set(buf);
4670 void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4671 Environment* env = Environment::GetCurrent(args);
4673 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4675 if (!ecdh->generated_)
4676 return env->ThrowError("You should generate ECDH keys first");
4678 const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_);
4680 return env->ThrowError("Failed to get ECDH private key");
4682 int size = BN_num_bytes(b);
4683 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4684 CHECK_NE(out, nullptr);
4686 if (size != BN_bn2bin(b, out)) {
4688 return env->ThrowError("Failed to convert ECDH private key to Buffer");
4692 Buffer::New(env, reinterpret_cast<char*>(out), size).ToLocalChecked();
4693 args.GetReturnValue().Set(buf);
4697 void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4698 Environment* env = Environment::GetCurrent(args);
4700 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4702 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4704 BIGNUM* priv = BN_bin2bn(
4705 reinterpret_cast<unsigned char*>(Buffer::Data(args[0].As<Object>())),
4706 Buffer::Length(args[0].As<Object>()),
4708 if (priv == nullptr)
4709 return env->ThrowError("Failed to convert Buffer to BN");
4711 int result = EC_KEY_set_private_key(ecdh->key_, priv);
4715 return env->ThrowError("Failed to convert BN to a private key");
4720 void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4721 Environment* env = Environment::GetCurrent(args);
4723 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4725 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4727 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0].As<Object>()),
4728 Buffer::Length(args[0].As<Object>()));
4732 int r = EC_KEY_set_public_key(ecdh->key_, pub);
4735 return env->ThrowError("Failed to convert BN to a private key");
4739 class PBKDF2Request : public AsyncWrap {
4741 PBKDF2Request(Environment* env,
4742 Local<Object> object,
4743 const EVP_MD* digest,
4750 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4758 key_(static_cast<char*>(malloc(keylen))),
4760 if (key() == nullptr)
4761 FatalError("node::PBKDF2Request()", "Out of Memory");
4765 ~PBKDF2Request() override {
4767 persistent().Reset();
4770 uv_work_t* work_req() {
4774 inline const EVP_MD* digest() const {
4778 inline int passlen() const {
4782 inline char* pass() const {
4786 inline int saltlen() const {
4790 inline char* salt() const {
4794 inline int keylen() const {
4798 inline char* key() const {
4802 inline int iter() const {
4806 inline void release() {
4820 inline int error() const {
4824 inline void set_error(int err) {
4828 size_t self_size() const override { return sizeof(*this); }
4830 uv_work_t work_req_;
4833 const EVP_MD* digest_;
4845 void EIO_PBKDF2(PBKDF2Request* req) {
4846 req->set_error(PKCS5_PBKDF2_HMAC(
4849 reinterpret_cast<unsigned char*>(req->salt()),
4854 reinterpret_cast<unsigned char*>(req->key())));
4855 OPENSSL_cleanse(req->pass(), req->passlen());
4856 OPENSSL_cleanse(req->salt(), req->saltlen());
4860 void EIO_PBKDF2(uv_work_t* work_req) {
4861 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4866 void EIO_PBKDF2After(PBKDF2Request* req, Local<Value> argv[2]) {
4868 argv[0] = Undefined(req->env()->isolate());
4869 argv[1] = Encode(req->env()->isolate(), req->key(), req->keylen(), BUFFER);
4870 OPENSSL_cleanse(req->key(), req->keylen());
4872 argv[0] = Exception::Error(req->env()->pbkdf2_error_string());
4873 argv[1] = Undefined(req->env()->isolate());
4878 void EIO_PBKDF2After(uv_work_t* work_req, int status) {
4879 CHECK_EQ(status, 0);
4880 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4881 Environment* env = req->env();
4882 HandleScope handle_scope(env->isolate());
4883 Context::Scope context_scope(env->context());
4884 Local<Value> argv[2];
4885 EIO_PBKDF2After(req, argv);
4886 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4891 void PBKDF2(const FunctionCallbackInfo<Value>& args) {
4892 Environment* env = Environment::GetCurrent(args);
4894 const EVP_MD* digest = nullptr;
4895 const char* type_error = nullptr;
4896 char* pass = nullptr;
4897 char* salt = nullptr;
4900 double raw_keylen = -1;
4903 PBKDF2Request* req = nullptr;
4906 if (args.Length() != 5 && args.Length() != 6) {
4907 type_error = "Bad parameter";
4911 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4912 passlen = Buffer::Length(args[0]);
4914 type_error = "Bad password";
4918 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
4920 pass = static_cast<char*>(malloc(passlen));
4921 if (pass == nullptr) {
4922 FatalError("node::PBKDF2()", "Out of Memory");
4924 memcpy(pass, Buffer::Data(args[0]), passlen);
4926 saltlen = Buffer::Length(args[1]);
4928 type_error = "Bad salt";
4932 salt = static_cast<char*>(malloc(saltlen));
4933 if (salt == nullptr) {
4934 FatalError("node::PBKDF2()", "Out of Memory");
4936 memcpy(salt, Buffer::Data(args[1]), saltlen);
4938 if (!args[2]->IsNumber()) {
4939 type_error = "Iterations not a number";
4943 iter = args[2]->Int32Value();
4945 type_error = "Bad iterations";
4949 if (!args[3]->IsNumber()) {
4950 type_error = "Key length not a number";
4954 raw_keylen = args[3]->NumberValue();
4955 if (raw_keylen < 0.0 || isnan(raw_keylen) || isinf(raw_keylen) ||
4956 raw_keylen > INT_MAX) {
4957 type_error = "Bad key length";
4961 keylen = static_cast<int>(raw_keylen);
4963 if (args[4]->IsString()) {
4964 node::Utf8Value digest_name(env->isolate(), args[4]);
4965 digest = EVP_get_digestbyname(*digest_name);
4966 if (digest == nullptr) {
4967 type_error = "Bad digest name";
4972 if (digest == nullptr) {
4973 digest = EVP_sha1();
4976 obj = env->NewInternalFieldObject();
4977 req = new PBKDF2Request(env,
4987 if (args[5]->IsFunction()) {
4988 obj->Set(env->ondone_string(), args[5]);
4990 if (env->in_domain())
4991 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4992 uv_queue_work(env->event_loop(),
4997 env->PrintSyncTrace();
4998 Local<Value> argv[2];
5000 EIO_PBKDF2After(req, argv);
5004 if (argv[0]->IsObject())
5005 env->isolate()->ThrowException(argv[0]);
5007 args.GetReturnValue().Set(argv[1]);
5014 return env->ThrowTypeError(type_error);
5018 // Only instantiate within a valid HandleScope.
5019 class RandomBytesRequest : public AsyncWrap {
5021 RandomBytesRequest(Environment* env, Local<Object> object, size_t size)
5022 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
5025 data_(static_cast<char*>(malloc(size))) {
5026 if (data() == nullptr)
5027 FatalError("node::RandomBytesRequest()", "Out of Memory");
5031 ~RandomBytesRequest() override {
5032 persistent().Reset();
5035 uv_work_t* work_req() {
5039 inline size_t size() const {
5043 inline char* data() const {
5047 inline void release() {
5052 inline void return_memory(char** d, size_t* len) {
5059 inline unsigned long error() const {
5063 inline void set_error(unsigned long err) {
5067 size_t self_size() const override { return sizeof(*this); }
5069 uv_work_t work_req_;
5072 unsigned long error_;
5078 void RandomBytesWork(uv_work_t* work_req) {
5079 RandomBytesRequest* req =
5080 ContainerOf(&RandomBytesRequest::work_req_, work_req);
5082 // Ensure that OpenSSL's PRNG is properly seeded.
5085 const int r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data()),
5088 // RAND_bytes() returns 0 on error.
5090 req->set_error(ERR_get_error());
5091 } else if (r == -1) {
5092 req->set_error(static_cast<unsigned long>(-1));
5097 // don't call this function without a valid HandleScope
5098 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
5100 char errmsg[256] = "Operation not supported";
5102 if (req->error() != static_cast<unsigned long>(-1))
5103 ERR_error_string_n(req->error(), errmsg, sizeof errmsg);
5105 argv[0] = Exception::Error(OneByteString(req->env()->isolate(), errmsg));
5106 argv[1] = Null(req->env()->isolate());
5109 char* data = nullptr;
5111 req->return_memory(&data, &size);
5112 argv[0] = Null(req->env()->isolate());
5113 argv[1] = Buffer::New(req->env(), data, size).ToLocalChecked();
5118 void RandomBytesAfter(uv_work_t* work_req, int status) {
5119 CHECK_EQ(status, 0);
5120 RandomBytesRequest* req =
5121 ContainerOf(&RandomBytesRequest::work_req_, work_req);
5122 Environment* env = req->env();
5123 HandleScope handle_scope(env->isolate());
5124 Context::Scope context_scope(env->context());
5125 Local<Value> argv[2];
5126 RandomBytesCheck(req, argv);
5127 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
5132 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
5133 Environment* env = Environment::GetCurrent(args);
5135 // maybe allow a buffer to write to? cuts down on object creation
5136 // when generating random data in a loop
5137 if (!args[0]->IsUint32()) {
5138 return env->ThrowTypeError("size must be a number >= 0");
5141 const int64_t size = args[0]->IntegerValue();
5142 if (size < 0 || size > Buffer::kMaxLength)
5143 return env->ThrowRangeError("size is not a valid Smi");
5145 Local<Object> obj = env->NewInternalFieldObject();
5146 RandomBytesRequest* req = new RandomBytesRequest(env, obj, size);
5148 if (args[1]->IsFunction()) {
5149 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "ondone"), args[1]);
5151 if (env->in_domain())
5152 obj->Set(env->domain_string(), env->domain_array()->Get(0));
5153 uv_queue_work(env->event_loop(),
5157 args.GetReturnValue().Set(obj);
5159 env->PrintSyncTrace();
5160 Local<Value> argv[2];
5161 RandomBytesWork(req->work_req());
5162 RandomBytesCheck(req, argv);
5165 if (!argv[0]->IsNull())
5166 env->isolate()->ThrowException(argv[0]);
5168 args.GetReturnValue().Set(argv[1]);
5173 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
5174 Environment* env = Environment::GetCurrent(args);
5176 SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
5177 if (ctx == nullptr) {
5178 return env->ThrowError("SSL_CTX_new() failed.");
5181 SSL* ssl = SSL_new(ctx);
5182 if (ssl == nullptr) {
5184 return env->ThrowError("SSL_new() failed.");
5187 Local<Array> arr = Array::New(env->isolate());
5188 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
5190 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
5191 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
5192 arr->Set(i, OneByteString(args.GetIsolate(), SSL_CIPHER_get_name(cipher)));
5198 args.GetReturnValue().Set(arr);
5202 class CipherPushContext {
5204 explicit CipherPushContext(Environment* env)
5205 : arr(Array::New(env->isolate())),
5209 inline Environment* env() const { return env_; }
5218 template <class TypeName>
5219 static void array_push_back(const TypeName* md,
5223 CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
5224 ctx->arr->Set(ctx->arr->Length(), OneByteString(ctx->env()->isolate(), from));
5228 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
5229 Environment* env = Environment::GetCurrent(args);
5230 CipherPushContext ctx(env);
5231 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
5232 args.GetReturnValue().Set(ctx.arr);
5236 void GetHashes(const FunctionCallbackInfo<Value>& args) {
5237 Environment* env = Environment::GetCurrent(args);
5238 CipherPushContext ctx(env);
5239 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
5240 args.GetReturnValue().Set(ctx.arr);
5244 void GetCurves(const FunctionCallbackInfo<Value>& args) {
5245 Environment* env = Environment::GetCurrent(args);
5246 const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
5247 Local<Array> arr = Array::New(env->isolate(), num_curves);
5248 EC_builtin_curve* curves;
5252 alloc_size = sizeof(*curves) * num_curves;
5253 curves = static_cast<EC_builtin_curve*>(malloc(alloc_size));
5255 CHECK_NE(curves, nullptr);
5257 if (EC_get_builtin_curves(curves, num_curves)) {
5258 for (size_t i = 0; i < num_curves; i++) {
5259 arr->Set(i, OneByteString(env->isolate(), OBJ_nid2sn(curves[i].nid)));
5266 args.GetReturnValue().Set(arr);
5270 void Certificate::Initialize(Environment* env, Local<Object> target) {
5271 HandleScope scope(env->isolate());
5273 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
5275 t->InstanceTemplate()->SetInternalFieldCount(1);
5277 env->SetProtoMethod(t, "verifySpkac", VerifySpkac);
5278 env->SetProtoMethod(t, "exportPublicKey", ExportPublicKey);
5279 env->SetProtoMethod(t, "exportChallenge", ExportChallenge);
5281 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Certificate"),
5286 void Certificate::New(const FunctionCallbackInfo<Value>& args) {
5287 Environment* env = Environment::GetCurrent(args);
5288 new Certificate(env, args.This());
5292 bool Certificate::VerifySpkac(const char* data, unsigned int len) {
5294 EVP_PKEY* pkey = nullptr;
5295 NETSCAPE_SPKI* spki = nullptr;
5297 spki = NETSCAPE_SPKI_b64_decode(data, len);
5298 if (spki == nullptr)
5301 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
5302 if (pkey == nullptr)
5305 i = NETSCAPE_SPKI_verify(spki, pkey) > 0;
5308 if (pkey != nullptr)
5309 EVP_PKEY_free(pkey);
5311 if (spki != nullptr)
5312 NETSCAPE_SPKI_free(spki);
5318 void Certificate::VerifySpkac(const FunctionCallbackInfo<Value>& args) {
5319 Certificate* certificate = Unwrap<Certificate>(args.Holder());
5320 Environment* env = certificate->env();
5323 if (args.Length() < 1)
5324 return env->ThrowTypeError("Missing argument");
5326 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
5328 size_t length = Buffer::Length(args[0]);
5330 return args.GetReturnValue().Set(i);
5332 char* data = Buffer::Data(args[0]);
5333 CHECK_NE(data, nullptr);
5335 i = certificate->VerifySpkac(data, length);
5337 args.GetReturnValue().Set(i);
5341 const char* Certificate::ExportPublicKey(const char* data, int len) {
5342 char* buf = nullptr;
5343 EVP_PKEY* pkey = nullptr;
5344 NETSCAPE_SPKI* spki = nullptr;
5346 BIO* bio = BIO_new(BIO_s_mem());
5350 spki = NETSCAPE_SPKI_b64_decode(data, len);
5351 if (spki == nullptr)
5354 pkey = NETSCAPE_SPKI_get_pubkey(spki);
5355 if (pkey == nullptr)
5358 if (PEM_write_bio_PUBKEY(bio, pkey) <= 0)
5361 BIO_write(bio, "\0", 1);
5363 BIO_get_mem_ptr(bio, &ptr);
5365 buf = new char[ptr->length];
5366 memcpy(buf, ptr->data, ptr->length);
5369 if (pkey != nullptr)
5370 EVP_PKEY_free(pkey);
5372 if (spki != nullptr)
5373 NETSCAPE_SPKI_free(spki);
5382 void Certificate::ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
5383 Environment* env = Environment::GetCurrent(args);
5385 Certificate* certificate = Unwrap<Certificate>(args.Holder());
5387 if (args.Length() < 1)
5388 return env->ThrowTypeError("Missing argument");
5390 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
5392 size_t length = Buffer::Length(args[0]);
5394 return args.GetReturnValue().SetEmptyString();
5396 char* data = Buffer::Data(args[0]);
5397 CHECK_NE(data, nullptr);
5399 const char* pkey = certificate->ExportPublicKey(data, length);
5400 if (pkey == nullptr)
5401 return args.GetReturnValue().SetEmptyString();
5403 Local<Value> out = Encode(env->isolate(), pkey, strlen(pkey), BUFFER);
5407 args.GetReturnValue().Set(out);
5411 const char* Certificate::ExportChallenge(const char* data, int len) {
5412 NETSCAPE_SPKI* sp = nullptr;
5414 sp = NETSCAPE_SPKI_b64_decode(data, len);
5418 unsigned char* buf = nullptr;
5419 ASN1_STRING_to_UTF8(&buf, sp->spkac->challenge);
5421 NETSCAPE_SPKI_free(sp);
5423 return reinterpret_cast<const char*>(buf);
5427 void Certificate::ExportChallenge(const FunctionCallbackInfo<Value>& args) {
5428 Environment* env = Environment::GetCurrent(args);
5430 Certificate* crt = Unwrap<Certificate>(args.Holder());
5432 if (args.Length() < 1)
5433 return env->ThrowTypeError("Missing argument");
5435 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
5437 size_t len = Buffer::Length(args[0]);
5439 return args.GetReturnValue().SetEmptyString();
5441 char* data = Buffer::Data(args[0]);
5442 CHECK_NE(data, nullptr);
5444 const char* cert = crt->ExportChallenge(data, len);
5445 if (cert == nullptr)
5446 return args.GetReturnValue().SetEmptyString();
5448 Local<Value> outString = Encode(env->isolate(), cert, strlen(cert), BUFFER);
5450 OPENSSL_free(const_cast<char*>(cert));
5452 args.GetReturnValue().Set(outString);
5456 void InitCryptoOnce() {
5458 OpenSSL_add_all_algorithms();
5459 SSL_load_error_strings();
5462 CRYPTO_set_locking_callback(crypto_lock_cb);
5463 CRYPTO_THREADID_set_callback(crypto_threadid_cb);
5465 #ifdef NODE_FIPS_MODE
5466 if (!FIPS_mode_set(1)) {
5467 int err = ERR_get_error();
5468 fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(err, NULL));
5471 #endif // NODE_FIPS_MODE
5474 // Turn off compression. Saves memory and protects against CRIME attacks.
5475 #if !defined(OPENSSL_NO_COMP)
5476 #if OPENSSL_VERSION_NUMBER < 0x00908000L
5477 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_method();
5479 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
5481 sk_SSL_COMP_zero(comp_methods);
5482 CHECK_EQ(sk_SSL_COMP_num(comp_methods), 0);
5485 #ifndef OPENSSL_NO_ENGINE
5486 ERR_load_ENGINE_strings();
5487 ENGINE_load_builtin_engines();
5488 #endif // !OPENSSL_NO_ENGINE
5492 #ifndef OPENSSL_NO_ENGINE
5493 void SetEngine(const FunctionCallbackInfo<Value>& args) {
5494 Environment* env = Environment::GetCurrent(args);
5495 CHECK(args.Length() >= 2 && args[0]->IsString());
5496 unsigned int flags = args[1]->Uint32Value();
5498 ClearErrorOnReturn clear_error_on_return;
5499 (void) &clear_error_on_return; // Silence compiler warning.
5501 const node::Utf8Value engine_id(env->isolate(), args[0]);
5502 ENGINE* engine = ENGINE_by_id(*engine_id);
5504 // Engine not found, try loading dynamically
5505 if (engine == nullptr) {
5506 engine = ENGINE_by_id("dynamic");
5507 if (engine != nullptr) {
5508 if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", *engine_id, 0) ||
5509 !ENGINE_ctrl_cmd_string(engine, "LOAD", nullptr, 0)) {
5510 ENGINE_free(engine);
5516 if (engine == nullptr) {
5517 int err = ERR_get_error();
5520 snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id);
5521 return env->ThrowError(tmp);
5523 return ThrowCryptoError(env, err);
5527 int r = ENGINE_set_default(engine, flags);
5528 ENGINE_free(engine);
5530 return ThrowCryptoError(env, ERR_get_error());
5532 #endif // !OPENSSL_NO_ENGINE
5535 // FIXME(bnoordhuis) Handle global init correctly.
5536 void InitCrypto(Local<Object> target,
5537 Local<Value> unused,
5538 Local<Context> context,
5540 static uv_once_t init_once = UV_ONCE_INIT;
5541 uv_once(&init_once, InitCryptoOnce);
5543 Environment* env = Environment::GetCurrent(context);
5544 SecureContext::Initialize(env, target);
5545 Connection::Initialize(env, target);
5546 CipherBase::Initialize(env, target);
5547 DiffieHellman::Initialize(env, target);
5548 ECDH::Initialize(env, target);
5549 Hmac::Initialize(env, target);
5550 Hash::Initialize(env, target);
5551 Sign::Initialize(env, target);
5552 Verify::Initialize(env, target);
5553 Certificate::Initialize(env, target);
5555 #ifndef OPENSSL_NO_ENGINE
5556 env->SetMethod(target, "setEngine", SetEngine);
5557 #endif // !OPENSSL_NO_ENGINE
5558 env->SetMethod(target, "PBKDF2", PBKDF2);
5559 env->SetMethod(target, "randomBytes", RandomBytes);
5560 env->SetMethod(target, "getSSLCiphers", GetSSLCiphers);
5561 env->SetMethod(target, "getCiphers", GetCiphers);
5562 env->SetMethod(target, "getHashes", GetHashes);
5563 env->SetMethod(target, "getCurves", GetCurves);
5564 env->SetMethod(target, "publicEncrypt",
5565 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
5566 EVP_PKEY_encrypt_init,
5568 env->SetMethod(target, "privateDecrypt",
5569 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
5570 EVP_PKEY_decrypt_init,
5572 env->SetMethod(target, "privateEncrypt",
5573 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
5576 env->SetMethod(target, "publicDecrypt",
5577 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
5578 EVP_PKEY_verify_recover_init,
5579 EVP_PKEY_verify_recover>);
5582 } // namespace crypto
5585 NODE_MODULE_CONTEXT_AWARE_BUILTIN(crypto, node::crypto::InitCrypto)