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"
26 #define strcasecmp _stricmp
29 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
30 #define OPENSSL_CONST const
35 #define THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(val) \
37 if (!Buffer::HasInstance(val) && !val->IsString()) { \
38 return env->ThrowTypeError("Not a string or buffer"); \
42 #define THROW_AND_RETURN_IF_NOT_BUFFER(val) \
44 if (!Buffer::HasInstance(val)) { \
45 return env->ThrowTypeError("Not a buffer"); \
49 static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----";
50 static const int PUBLIC_KEY_PFX_LEN = sizeof(PUBLIC_KEY_PFX) - 1;
51 static const char PUBRSA_KEY_PFX[] = "-----BEGIN RSA PUBLIC KEY-----";
52 static const int PUBRSA_KEY_PFX_LEN = sizeof(PUBRSA_KEY_PFX) - 1;
53 static const char CERTIFICATE_PFX[] = "-----BEGIN CERTIFICATE-----";
54 static const int CERTIFICATE_PFX_LEN = sizeof(CERTIFICATE_PFX) - 1;
56 static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
57 | ASN1_STRFLGS_UTF8_CONVERT
58 | XN_FLAG_SEP_MULTILINE
69 using v8::EscapableHandleScope;
73 using v8::FunctionCallbackInfo;
74 using v8::FunctionTemplate;
76 using v8::HandleScope;
83 using v8::PropertyAttribute;
84 using v8::PropertyCallbackInfo;
91 // Subject DER of CNNIC ROOT CA and CNNIC EV ROOT CA are taken from
92 // https://hg.mozilla.org/mozilla-central/file/98820360ab66/security/
93 // certverifier/NSSCertDBTrustDomain.cpp#l672
94 // C = CN, O = CNNIC, CN = CNNIC ROOT
95 static const uint8_t CNNIC_ROOT_CA_SUBJECT_DATA[] =
96 "\x30\x32\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x4E\x31\x0E\x30"
97 "\x0C\x06\x03\x55\x04\x0A\x13\x05\x43\x4E\x4E\x49\x43\x31\x13\x30\x11\x06"
98 "\x03\x55\x04\x03\x13\x0A\x43\x4E\x4E\x49\x43\x20\x52\x4F\x4F\x54";
99 static const uint8_t* cnnic_p = CNNIC_ROOT_CA_SUBJECT_DATA;
100 static X509_NAME* cnnic_name =
101 d2i_X509_NAME(nullptr, &cnnic_p, sizeof(CNNIC_ROOT_CA_SUBJECT_DATA)-1);
103 // C = CN, O = China Internet Network Information Center, CN = China
104 // Internet Network Information Center EV Certificates Root
105 static const uint8_t CNNIC_EV_ROOT_CA_SUBJECT_DATA[] =
106 "\x30\x81\x8A\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x4E\x31\x32"
107 "\x30\x30\x06\x03\x55\x04\x0A\x0C\x29\x43\x68\x69\x6E\x61\x20\x49\x6E\x74"
108 "\x65\x72\x6E\x65\x74\x20\x4E\x65\x74\x77\x6F\x72\x6B\x20\x49\x6E\x66\x6F"
109 "\x72\x6D\x61\x74\x69\x6F\x6E\x20\x43\x65\x6E\x74\x65\x72\x31\x47\x30\x45"
110 "\x06\x03\x55\x04\x03\x0C\x3E\x43\x68\x69\x6E\x61\x20\x49\x6E\x74\x65\x72"
111 "\x6E\x65\x74\x20\x4E\x65\x74\x77\x6F\x72\x6B\x20\x49\x6E\x66\x6F\x72\x6D"
112 "\x61\x74\x69\x6F\x6E\x20\x43\x65\x6E\x74\x65\x72\x20\x45\x56\x20\x43\x65"
113 "\x72\x74\x69\x66\x69\x63\x61\x74\x65\x73\x20\x52\x6F\x6F\x74";
114 static const uint8_t* cnnic_ev_p = CNNIC_EV_ROOT_CA_SUBJECT_DATA;
115 static X509_NAME *cnnic_ev_name =
116 d2i_X509_NAME(nullptr, &cnnic_ev_p,
117 sizeof(CNNIC_EV_ROOT_CA_SUBJECT_DATA)-1);
119 // Forcibly clear OpenSSL's error stack on return. This stops stale errors
120 // from popping up later in the lifecycle of crypto operations where they
121 // would cause spurious failures. It's a rather blunt method, though.
122 // ERR_clear_error() isn't necessarily cheap either.
123 struct ClearErrorOnReturn {
124 ~ClearErrorOnReturn() { ERR_clear_error(); }
127 static uv_rwlock_t* locks;
129 const char* const root_certs[] = {
130 #include "node_root_certs.h" // NOLINT(build/include_order)
133 X509_STORE* root_cert_store;
135 // Just to generate static methods
136 template class SSLWrap<TLSWrap>;
137 template void SSLWrap<TLSWrap>::AddMethods(Environment* env,
138 Handle<FunctionTemplate> t);
139 template void SSLWrap<TLSWrap>::InitNPN(SecureContext* sc);
140 template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
145 template int SSLWrap<TLSWrap>::NewSessionCallback(SSL* s,
147 template void SSLWrap<TLSWrap>::OnClientHello(
149 const ClientHelloParser::ClientHello& hello);
151 #ifdef OPENSSL_NPN_NEGOTIATED
152 template int SSLWrap<TLSWrap>::AdvertiseNextProtoCallback(
154 const unsigned char** data,
157 template int SSLWrap<TLSWrap>::SelectNextProtoCallback(
160 unsigned char* outlen,
161 const unsigned char* in,
165 template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void* arg);
166 template void SSLWrap<TLSWrap>::DestroySSL();
167 template int SSLWrap<TLSWrap>::SSLCertCallback(SSL* s, void* arg);
168 template void SSLWrap<TLSWrap>::WaitForCertCb(CertCb cb, void* arg);
171 static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
172 static_assert(sizeof(uv_thread_t) <= sizeof(void*), // NOLINT(runtime/sizeof)
173 "uv_thread_t does not fit in a pointer");
174 CRYPTO_THREADID_set_pointer(tid, reinterpret_cast<void*>(uv_thread_self()));
178 static void crypto_lock_init(void) {
181 n = CRYPTO_num_locks();
182 locks = new uv_rwlock_t[n];
184 for (i = 0; i < n; i++)
185 if (uv_rwlock_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 if (mode & CRYPTO_READ)
196 uv_rwlock_rdlock(locks + n);
198 uv_rwlock_wrlock(locks + n);
200 if (mode & CRYPTO_READ)
201 uv_rwlock_rdunlock(locks + n);
203 uv_rwlock_wrunlock(locks + n);
208 static int CryptoPemCallback(char *buf, int size, int rwflag, void *u) {
210 size_t buflen = static_cast<size_t>(size);
211 size_t len = strlen(static_cast<const char*>(u));
212 len = len > buflen ? buflen : len;
221 void ThrowCryptoError(Environment* env,
223 const char* default_message = nullptr) {
224 HandleScope scope(env->isolate());
225 if (err != 0 || default_message == nullptr) {
226 char errmsg[128] = { 0 };
227 ERR_error_string_n(err, errmsg, sizeof(errmsg));
228 env->ThrowError(errmsg);
230 env->ThrowError(default_message);
235 // Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.
236 // The entropy pool starts out empty and needs to fill up before the PRNG
237 // can be used securely. Once the pool is filled, it never dries up again;
238 // its contents is stirred and reused when necessary.
240 // OpenSSL normally fills the pool automatically but not when someone starts
241 // generating random numbers before the pool is full: in that case OpenSSL
242 // keeps lowering the entropy estimate to thwart attackers trying to guess
243 // the initial state of the PRNG.
245 // When that happens, we will have to wait until enough entropy is available.
246 // That should normally never take longer than a few milliseconds.
248 // OpenSSL draws from /dev/random and /dev/urandom. While /dev/random may
249 // block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't
250 // block under normal circumstances.
252 // The only time when /dev/urandom may conceivably block is right after boot,
253 // when the whole system is still low on entropy. That's not something we can
254 // do anything about.
255 inline void CheckEntropy() {
257 int status = RAND_status();
258 CHECK_GE(status, 0); // Cannot fail.
262 // Give up, RAND_poll() not supported.
263 if (RAND_poll() == 0)
269 bool EntropySource(unsigned char* buffer, size_t length) {
270 // Ensure that OpenSSL's PRNG is properly seeded.
272 // RAND_bytes() can return 0 to indicate that the entropy data is not truly
273 // random. That's okay, it's still better than V8's stock source of entropy,
274 // which is /dev/urandom on UNIX platforms and the current time on Windows.
275 return RAND_bytes(buffer, length) != -1;
279 void SecureContext::Initialize(Environment* env, Handle<Object> target) {
280 Local<FunctionTemplate> t = env->NewFunctionTemplate(SecureContext::New);
281 t->InstanceTemplate()->SetInternalFieldCount(1);
282 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"));
284 env->SetProtoMethod(t, "init", SecureContext::Init);
285 env->SetProtoMethod(t, "setKey", SecureContext::SetKey);
286 env->SetProtoMethod(t, "setCert", SecureContext::SetCert);
287 env->SetProtoMethod(t, "addCACert", SecureContext::AddCACert);
288 env->SetProtoMethod(t, "addCRL", SecureContext::AddCRL);
289 env->SetProtoMethod(t, "addRootCerts", SecureContext::AddRootCerts);
290 env->SetProtoMethod(t, "setCiphers", SecureContext::SetCiphers);
291 env->SetProtoMethod(t, "setECDHCurve", SecureContext::SetECDHCurve);
292 env->SetProtoMethod(t, "setDHParam", SecureContext::SetDHParam);
293 env->SetProtoMethod(t, "setOptions", SecureContext::SetOptions);
294 env->SetProtoMethod(t, "setSessionIdContext",
295 SecureContext::SetSessionIdContext);
296 env->SetProtoMethod(t, "setSessionTimeout",
297 SecureContext::SetSessionTimeout);
298 env->SetProtoMethod(t, "close", SecureContext::Close);
299 env->SetProtoMethod(t, "loadPKCS12", SecureContext::LoadPKCS12);
300 env->SetProtoMethod(t, "getTicketKeys", SecureContext::GetTicketKeys);
301 env->SetProtoMethod(t, "setTicketKeys", SecureContext::SetTicketKeys);
302 env->SetProtoMethod(t, "setFreeListLength", SecureContext::SetFreeListLength);
303 env->SetProtoMethod(t, "getCertificate", SecureContext::GetCertificate<true>);
304 env->SetProtoMethod(t, "getIssuer", SecureContext::GetCertificate<false>);
306 t->PrototypeTemplate()->SetAccessor(
307 FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
312 static_cast<PropertyAttribute>(ReadOnly | DontDelete));
314 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"),
316 env->set_secure_context_constructor_template(t);
320 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
321 Environment* env = Environment::GetCurrent(args);
322 new SecureContext(env, args.This());
326 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
327 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
328 Environment* env = sc->env();
330 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
332 if (args.Length() == 1 && args[0]->IsString()) {
333 const node::Utf8Value sslmethod(env->isolate(), args[0]);
335 // Note that SSLv2 and SSLv3 are disallowed but SSLv2_method and friends
336 // are still accepted. They are OpenSSL's way of saying that all known
337 // protocols are supported unless explicitly disabled (which we do below
338 // for SSLv2 and SSLv3.)
339 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
340 return env->ThrowError("SSLv2 methods disabled");
341 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
342 return env->ThrowError("SSLv2 methods disabled");
343 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
344 return env->ThrowError("SSLv2 methods disabled");
345 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
346 return env->ThrowError("SSLv3 methods disabled");
347 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
348 return env->ThrowError("SSLv3 methods disabled");
349 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
350 return env->ThrowError("SSLv3 methods disabled");
351 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
352 method = SSLv23_method();
353 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
354 method = SSLv23_server_method();
355 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
356 method = SSLv23_client_method();
357 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
358 method = TLSv1_method();
359 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
360 method = TLSv1_server_method();
361 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
362 method = TLSv1_client_method();
363 } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
364 method = TLSv1_1_method();
365 } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
366 method = TLSv1_1_server_method();
367 } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
368 method = TLSv1_1_client_method();
369 } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
370 method = TLSv1_2_method();
371 } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
372 method = TLSv1_2_server_method();
373 } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
374 method = TLSv1_2_client_method();
376 return env->ThrowError("Unknown method");
380 sc->ctx_ = SSL_CTX_new(method);
382 // Disable SSLv2 in the case when method == SSLv23_method() and the
383 // cipher list contains SSLv2 ciphers (not the default, should be rare.)
384 // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
385 // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
386 SSL_CTX_set_options(sc->ctx_, SSL_OP_NO_SSLv2);
387 SSL_CTX_set_options(sc->ctx_, SSL_OP_NO_SSLv3);
389 // SSL session cache configuration
390 SSL_CTX_set_session_cache_mode(sc->ctx_,
391 SSL_SESS_CACHE_SERVER |
392 SSL_SESS_CACHE_NO_INTERNAL |
393 SSL_SESS_CACHE_NO_AUTO_CLEAR);
394 SSL_CTX_sess_set_get_cb(sc->ctx_, SSLWrap<Connection>::GetSessionCallback);
395 SSL_CTX_sess_set_new_cb(sc->ctx_, SSLWrap<Connection>::NewSessionCallback);
397 sc->ca_store_ = nullptr;
401 // Takes a string or buffer and loads it into a BIO.
402 // Caller responsible for BIO_free_all-ing the returned object.
403 static BIO* LoadBIO(Environment* env, Handle<Value> v) {
404 BIO* bio = NodeBIO::New();
408 HandleScope scope(env->isolate());
413 const node::Utf8Value s(env->isolate(), v);
414 r = BIO_write(bio, *s, s.length());
415 } else if (Buffer::HasInstance(v)) {
416 char* buffer_data = Buffer::Data(v);
417 size_t buffer_length = Buffer::Length(v);
418 r = BIO_write(bio, buffer_data, buffer_length);
430 // Takes a string or buffer and loads it into an X509
431 // Caller responsible for X509_free-ing the returned object.
432 static X509* LoadX509(Environment* env, Handle<Value> v) {
433 HandleScope scope(env->isolate());
435 BIO *bio = LoadBIO(env, v);
439 X509 * x509 = PEM_read_bio_X509(bio, nullptr, CryptoPemCallback, nullptr);
450 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
451 Environment* env = Environment::GetCurrent(args);
453 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
455 unsigned int len = args.Length();
456 if (len != 1 && len != 2) {
457 return env->ThrowTypeError("Bad parameter");
459 if (len == 2 && !args[1]->IsString()) {
460 return env->ThrowTypeError("Bad parameter");
463 BIO *bio = LoadBIO(env, args[0]);
467 node::Utf8Value passphrase(env->isolate(), args[1]);
469 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio,
472 len == 1 ? nullptr : *passphrase);
476 unsigned long err = ERR_get_error();
478 return env->ThrowError("PEM_read_bio_PrivateKey");
480 return ThrowCryptoError(env, err);
483 int rv = SSL_CTX_use_PrivateKey(sc->ctx_, key);
488 unsigned long err = ERR_get_error();
490 return env->ThrowError("SSL_CTX_use_PrivateKey");
491 return ThrowCryptoError(env, err);
496 int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) {
499 X509_STORE* store = SSL_CTX_get_cert_store(ctx);
500 X509_STORE_CTX store_ctx;
502 ret = X509_STORE_CTX_init(&store_ctx, store, nullptr, nullptr);
506 ret = X509_STORE_CTX_get1_issuer(issuer, &store_ctx, cert);
507 X509_STORE_CTX_cleanup(&store_ctx);
514 // Read a file that contains our certificate in "PEM" format,
515 // possibly followed by a sequence of CA certificates that should be
516 // sent to the peer in the Certificate message.
518 // Taken from OpenSSL - editted for style.
519 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
526 x = PEM_read_bio_X509_AUX(in, nullptr, CryptoPemCallback, nullptr);
529 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
533 ret = SSL_CTX_use_certificate(ctx, x);
536 // If we could set up our certificate, now proceed to
537 // the CA certificates.
542 if (ctx->extra_certs != nullptr) {
543 sk_X509_pop_free(ctx->extra_certs, X509_free);
544 ctx->extra_certs = nullptr;
547 while ((ca = PEM_read_bio_X509(in, nullptr, CryptoPemCallback, nullptr))) {
548 // NOTE: Increments reference count on `ca`
549 r = SSL_CTX_add1_chain_cert(ctx, ca);
556 // Note that we must not free r if it was successfully
557 // added to the chain (while we must free the main
558 // certificate, since its reference count is increased
559 // by SSL_CTX_use_certificate).
562 if (*issuer != nullptr || X509_check_issued(ca, x) != X509_V_OK)
567 // When the while loop ends, it's usually just EOF.
568 err = ERR_peek_last_error();
569 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
570 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
578 // Try getting issuer from a cert store
580 if (*issuer == nullptr) {
581 ret = SSL_CTX_get_issuer(ctx, x, issuer);
582 ret = ret < 0 ? 0 : 1;
583 // NOTE: get_cert_store doesn't increment reference count,
584 // no need to free `store`
586 // Increment issuer reference count
587 CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
598 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
599 Environment* env = Environment::GetCurrent(args);
601 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
603 if (args.Length() != 1) {
604 return env->ThrowTypeError("Bad parameter");
607 BIO* bio = LoadBIO(env, args[0]);
611 int rv = SSL_CTX_use_certificate_chain(sc->ctx_,
619 unsigned long err = ERR_get_error();
621 return env->ThrowError("SSL_CTX_use_certificate_chain");
623 return ThrowCryptoError(env, err);
628 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
629 bool newCAStore = false;
630 Environment* env = Environment::GetCurrent(args);
632 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
633 ClearErrorOnReturn clear_error_on_return;
634 (void) &clear_error_on_return; // Silence compiler warning.
636 if (args.Length() != 1) {
637 return env->ThrowTypeError("Bad parameter");
640 if (!sc->ca_store_) {
641 sc->ca_store_ = X509_STORE_new();
645 X509* x509 = LoadX509(env, args[0]);
649 X509_STORE_add_cert(sc->ca_store_, x509);
650 SSL_CTX_add_client_CA(sc->ctx_, x509);
655 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
660 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
661 Environment* env = Environment::GetCurrent(args);
663 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
665 if (args.Length() != 1) {
666 return env->ThrowTypeError("Bad parameter");
669 ClearErrorOnReturn clear_error_on_return;
670 (void) &clear_error_on_return; // Silence compiler warning.
672 BIO *bio = LoadBIO(env, args[0]);
677 PEM_read_bio_X509_CRL(bio, nullptr, CryptoPemCallback, nullptr);
679 if (x509 == nullptr) {
684 X509_STORE_add_crl(sc->ca_store_, x509);
685 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
686 X509_V_FLAG_CRL_CHECK_ALL);
693 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
694 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
695 ClearErrorOnReturn clear_error_on_return;
696 (void) &clear_error_on_return; // Silence compiler warning.
698 CHECK_EQ(sc->ca_store_, nullptr);
700 if (!root_cert_store) {
701 root_cert_store = X509_STORE_new();
703 for (size_t i = 0; i < ARRAY_SIZE(root_certs); i++) {
704 BIO* bp = NodeBIO::New();
706 if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
711 X509 *x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
713 if (x509 == nullptr) {
718 X509_STORE_add_cert(root_cert_store, x509);
725 sc->ca_store_ = root_cert_store;
726 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
730 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
731 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
732 ClearErrorOnReturn clear_error_on_return;
733 (void) &clear_error_on_return; // Silence compiler warning.
735 if (args.Length() != 1 || !args[0]->IsString()) {
736 return sc->env()->ThrowTypeError("Bad parameter");
739 const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
740 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
744 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
745 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
746 Environment* env = sc->env();
748 if (args.Length() != 1 || !args[0]->IsString())
749 return env->ThrowTypeError("First argument should be a string");
751 node::Utf8Value curve(env->isolate(), args[0]);
753 int nid = OBJ_sn2nid(*curve);
755 if (nid == NID_undef)
756 return env->ThrowTypeError("First argument should be a valid curve name");
758 EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
761 return env->ThrowTypeError("First argument should be a valid curve name");
763 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
764 SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
770 void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
771 SecureContext* sc = Unwrap<SecureContext>(args.This());
772 Environment* env = sc->env();
773 ClearErrorOnReturn clear_error_on_return;
774 (void) &clear_error_on_return; // Silence compiler warning.
776 // Auto DH is not supported in openssl 1.0.1, so dhparam needs
777 // to be specifed explicitly
778 if (args.Length() != 1)
779 return env->ThrowTypeError("Bad parameter");
781 // Invalid dhparam is silently discarded and DHE is no longer used.
782 BIO* bio = LoadBIO(env, args[0]);
786 DH* dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
792 const int keylen = BN_num_bits(dh->p);
794 return env->ThrowError("DH parameter is less than 1024 bits");
795 else if (keylen < 2048)
796 fprintf(stderr, "WARNING: DH parameter is less than 2048 bits\n");
798 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_DH_USE);
799 int r = SSL_CTX_set_tmp_dh(sc->ctx_, dh);
803 return env->ThrowTypeError("Error setting temp DH parameter");
807 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
808 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
810 if (args.Length() != 1 || !args[0]->IntegerValue()) {
811 return sc->env()->ThrowTypeError("Bad parameter");
814 SSL_CTX_set_options(sc->ctx_, static_cast<long>(args[0]->IntegerValue()));
818 void SecureContext::SetSessionIdContext(
819 const FunctionCallbackInfo<Value>& args) {
820 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
822 if (args.Length() != 1 || !args[0]->IsString()) {
823 return sc->env()->ThrowTypeError("Bad parameter");
826 const node::Utf8Value sessionIdContext(args.GetIsolate(), args[0]);
827 const unsigned char* sid_ctx =
828 reinterpret_cast<const unsigned char*>(*sessionIdContext);
829 unsigned int sid_ctx_len = sessionIdContext.length();
831 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
837 Local<String> message;
839 bio = BIO_new(BIO_s_mem());
840 if (bio == nullptr) {
841 message = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
842 "SSL_CTX_set_session_id_context error");
844 ERR_print_errors(bio);
845 BIO_get_mem_ptr(bio, &mem);
846 message = OneByteString(args.GetIsolate(), mem->data, mem->length);
850 args.GetIsolate()->ThrowException(Exception::TypeError(message));
854 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
855 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
857 if (args.Length() != 1 || !args[0]->IsInt32()) {
858 return sc->env()->ThrowTypeError("Bad parameter");
861 int32_t sessionTimeout = args[0]->Int32Value();
862 SSL_CTX_set_timeout(sc->ctx_, sessionTimeout);
866 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
867 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
872 // Takes .pfx or .p12 and password in string or buffer format
873 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
874 Environment* env = Environment::GetCurrent(args);
877 PKCS12* p12 = nullptr;
878 EVP_PKEY* pkey = nullptr;
879 X509* cert = nullptr;
880 STACK_OF(X509)* extraCerts = nullptr;
881 char* pass = nullptr;
884 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
885 ClearErrorOnReturn clear_error_on_return;
886 (void) &clear_error_on_return; // Silence compiler warning.
888 if (args.Length() < 1) {
889 return env->ThrowTypeError("Bad parameter");
892 in = LoadBIO(env, args[0]);
894 return env->ThrowError("Unable to load BIO");
897 if (args.Length() >= 2) {
898 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
899 size_t passlen = Buffer::Length(args[1]);
900 pass = new char[passlen + 1];
901 memcpy(pass, Buffer::Data(args[1]), passlen);
902 pass[passlen] = '\0';
905 if (d2i_PKCS12_bio(in, &p12) &&
906 PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
907 SSL_CTX_use_certificate(sc->ctx_, cert) &&
908 SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) {
910 while (X509* x509 = sk_X509_pop(extraCerts)) {
911 if (!sc->ca_store_) {
912 sc->ca_store_ = X509_STORE_new();
913 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
916 X509_STORE_add_cert(sc->ca_store_, x509);
917 SSL_CTX_add_client_CA(sc->ctx_, x509);
923 sk_X509_free(extraCerts);
933 unsigned long err = ERR_get_error();
934 const char* str = ERR_reason_error_string(err);
935 return env->ThrowError(str);
940 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
941 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
943 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
945 Local<Object> buff = Buffer::New(wrap->env(), 48);
946 if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_,
948 Buffer::Length(buff)) != 1) {
949 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
952 args.GetReturnValue().Set(buff);
953 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
957 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
958 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
959 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
961 if (args.Length() < 1 ||
962 !Buffer::HasInstance(args[0]) ||
963 Buffer::Length(args[0]) != 48) {
964 return wrap->env()->ThrowTypeError("Bad argument");
967 if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_,
968 Buffer::Data(args[0]),
969 Buffer::Length(args[0])) != 1) {
970 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
973 args.GetReturnValue().Set(true);
974 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
978 void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
979 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
981 wrap->ctx_->freelist_max_len = args[0]->Int32Value();
985 void SecureContext::CtxGetter(Local<String> property,
986 const PropertyCallbackInfo<Value>& info) {
987 HandleScope scope(info.GetIsolate());
989 SSL_CTX* ctx = Unwrap<SecureContext>(info.Holder())->ctx_;
990 Local<External> ext = External::New(info.GetIsolate(), ctx);
991 info.GetReturnValue().Set(ext);
995 template <bool primary>
996 void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
997 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
998 Environment* env = wrap->env();
1004 cert = wrap->issuer_;
1005 if (cert == nullptr)
1006 return args.GetReturnValue().Set(Null(env->isolate()));
1008 int size = i2d_X509(cert, nullptr);
1009 Local<Object> buff = Buffer::New(env, size);
1010 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1011 Buffer::Data(buff));
1012 i2d_X509(cert, &serialized);
1014 args.GetReturnValue().Set(buff);
1018 template <class Base>
1019 void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
1020 HandleScope scope(env->isolate());
1022 env->SetProtoMethod(t, "getPeerCertificate", GetPeerCertificate);
1023 env->SetProtoMethod(t, "getSession", GetSession);
1024 env->SetProtoMethod(t, "setSession", SetSession);
1025 env->SetProtoMethod(t, "loadSession", LoadSession);
1026 env->SetProtoMethod(t, "isSessionReused", IsSessionReused);
1027 env->SetProtoMethod(t, "isInitFinished", IsInitFinished);
1028 env->SetProtoMethod(t, "verifyError", VerifyError);
1029 env->SetProtoMethod(t, "getCurrentCipher", GetCurrentCipher);
1030 env->SetProtoMethod(t, "endParser", EndParser);
1031 env->SetProtoMethod(t, "certCbDone", CertCbDone);
1032 env->SetProtoMethod(t, "renegotiate", Renegotiate);
1033 env->SetProtoMethod(t, "shutdownSSL", Shutdown);
1034 env->SetProtoMethod(t, "getTLSTicket", GetTLSTicket);
1035 env->SetProtoMethod(t, "newSessionDone", NewSessionDone);
1036 env->SetProtoMethod(t, "setOCSPResponse", SetOCSPResponse);
1037 env->SetProtoMethod(t, "requestOCSP", RequestOCSP);
1039 #ifdef SSL_set_max_send_fragment
1040 env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment);
1041 #endif // SSL_set_max_send_fragment
1043 #ifdef OPENSSL_NPN_NEGOTIATED
1044 env->SetProtoMethod(t, "getNegotiatedProtocol", GetNegotiatedProto);
1045 #endif // OPENSSL_NPN_NEGOTIATED
1047 #ifdef OPENSSL_NPN_NEGOTIATED
1048 env->SetProtoMethod(t, "setNPNProtocols", SetNPNProtocols);
1051 t->PrototypeTemplate()->SetAccessor(
1052 FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
1057 static_cast<PropertyAttribute>(ReadOnly | DontDelete));
1061 template <class Base>
1062 void SSLWrap<Base>::InitNPN(SecureContext* sc) {
1063 #ifdef OPENSSL_NPN_NEGOTIATED
1064 // Server should advertise NPN protocols
1065 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
1066 AdvertiseNextProtoCallback,
1068 // Client should select protocol from list of advertised
1069 // If server supports NPN
1070 SSL_CTX_set_next_proto_select_cb(sc->ctx_, SelectNextProtoCallback, nullptr);
1071 #endif // OPENSSL_NPN_NEGOTIATED
1073 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1075 SSL_CTX_set_tlsext_status_cb(sc->ctx_, TLSExtStatusCallback);
1076 SSL_CTX_set_tlsext_status_arg(sc->ctx_, nullptr);
1077 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1081 template <class Base>
1082 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
1086 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1089 SSL_SESSION* sess = w->next_sess_;
1090 w->next_sess_ = nullptr;
1096 template <class Base>
1097 int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
1098 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1099 Environment* env = w->ssl_env();
1100 HandleScope handle_scope(env->isolate());
1101 Context::Scope context_scope(env->context());
1103 if (!w->session_callbacks_)
1106 // Check if session is small enough to be stored
1107 int size = i2d_SSL_SESSION(sess, nullptr);
1108 if (size > SecureContext::kMaxSessionSize)
1111 // Serialize session
1112 Local<Object> buff = Buffer::New(env, size);
1113 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1114 Buffer::Data(buff));
1115 memset(serialized, 0, size);
1116 i2d_SSL_SESSION(sess, &serialized);
1118 Local<Object> session = Buffer::New(env,
1119 reinterpret_cast<char*>(sess->session_id),
1120 sess->session_id_length);
1121 Local<Value> argv[] = { session, buff };
1122 w->new_session_wait_ = true;
1123 w->MakeCallback(env->onnewsession_string(), ARRAY_SIZE(argv), argv);
1129 template <class Base>
1130 void SSLWrap<Base>::OnClientHello(void* arg,
1131 const ClientHelloParser::ClientHello& hello) {
1132 Base* w = static_cast<Base*>(arg);
1133 Environment* env = w->ssl_env();
1134 HandleScope handle_scope(env->isolate());
1135 Context::Scope context_scope(env->context());
1137 Local<Object> hello_obj = Object::New(env->isolate());
1138 Local<Object> buff = Buffer::New(
1140 reinterpret_cast<const char*>(hello.session_id()),
1141 hello.session_size());
1142 hello_obj->Set(env->session_id_string(), buff);
1143 if (hello.servername() == nullptr) {
1144 hello_obj->Set(env->servername_string(), String::Empty(env->isolate()));
1146 Local<String> servername = OneByteString(env->isolate(),
1148 hello.servername_size());
1149 hello_obj->Set(env->servername_string(), servername);
1151 hello_obj->Set(env->tls_ticket_string(),
1152 Boolean::New(env->isolate(), hello.has_ticket()));
1153 hello_obj->Set(env->ocsp_request_string(),
1154 Boolean::New(env->isolate(), hello.ocsp_request()));
1156 Local<Value> argv[] = { hello_obj };
1157 w->MakeCallback(env->onclienthello_string(), ARRAY_SIZE(argv), argv);
1161 static bool SafeX509ExtPrint(BIO* out, X509_EXTENSION* ext) {
1162 const X509V3_EXT_METHOD* method = X509V3_EXT_get(ext);
1164 if (method != X509V3_EXT_get_nid(NID_subject_alt_name))
1167 const unsigned char* p = ext->value->data;
1168 GENERAL_NAMES* names = reinterpret_cast<GENERAL_NAMES*>(ASN1_item_d2i(
1172 ASN1_ITEM_ptr(method->it)));
1176 for (int i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1177 GENERAL_NAME* gen = sk_GENERAL_NAME_value(names, i);
1180 BIO_write(out, ", ", 2);
1182 if (gen->type == GEN_DNS) {
1183 ASN1_IA5STRING* name = gen->d.dNSName;
1185 BIO_write(out, "DNS:", 4);
1186 BIO_write(out, name->data, name->length);
1188 STACK_OF(CONF_VALUE)* nval = i2v_GENERAL_NAME(
1189 const_cast<X509V3_EXT_METHOD*>(method), gen, NULL);
1192 X509V3_EXT_val_prn(out, nval, 0, 0);
1195 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
1201 static Local<Object> X509ToObject(Environment* env, X509* cert) {
1202 EscapableHandleScope scope(env->isolate());
1204 Local<Object> info = Object::New(env->isolate());
1206 BIO* bio = BIO_new(BIO_s_mem());
1208 if (X509_NAME_print_ex(bio,
1209 X509_get_subject_name(cert),
1211 X509_NAME_FLAGS) > 0) {
1212 BIO_get_mem_ptr(bio, &mem);
1213 info->Set(env->subject_string(),
1214 String::NewFromUtf8(env->isolate(), mem->data,
1215 String::kNormalString, mem->length));
1217 (void) BIO_reset(bio);
1219 X509_NAME* issuer_name = X509_get_issuer_name(cert);
1220 if (X509_NAME_print_ex(bio, issuer_name, 0, X509_NAME_FLAGS) > 0) {
1221 BIO_get_mem_ptr(bio, &mem);
1222 info->Set(env->issuer_string(),
1223 String::NewFromUtf8(env->isolate(), mem->data,
1224 String::kNormalString, mem->length));
1226 (void) BIO_reset(bio);
1228 int nids[] = { NID_subject_alt_name, NID_info_access };
1229 Local<String> keys[] = { env->subjectaltname_string(),
1230 env->infoaccess_string() };
1231 CHECK_EQ(ARRAY_SIZE(nids), ARRAY_SIZE(keys));
1232 for (unsigned int i = 0; i < ARRAY_SIZE(nids); i++) {
1233 int index = X509_get_ext_by_NID(cert, nids[i], -1);
1237 X509_EXTENSION* ext;
1240 ext = X509_get_ext(cert, index);
1241 CHECK_NE(ext, nullptr);
1243 if (!SafeX509ExtPrint(bio, ext)) {
1244 rv = X509V3_EXT_print(bio, ext, 0, 0);
1248 BIO_get_mem_ptr(bio, &mem);
1250 String::NewFromUtf8(env->isolate(), mem->data,
1251 String::kNormalString, mem->length));
1253 (void) BIO_reset(bio);
1256 EVP_PKEY* pkey = X509_get_pubkey(cert);
1258 if (pkey != nullptr)
1259 rsa = EVP_PKEY_get1_RSA(pkey);
1261 if (rsa != nullptr) {
1262 BN_print(bio, rsa->n);
1263 BIO_get_mem_ptr(bio, &mem);
1264 info->Set(env->modulus_string(),
1265 String::NewFromUtf8(env->isolate(), mem->data,
1266 String::kNormalString, mem->length));
1267 (void) BIO_reset(bio);
1269 BN_print(bio, rsa->e);
1270 BIO_get_mem_ptr(bio, &mem);
1271 info->Set(env->exponent_string(),
1272 String::NewFromUtf8(env->isolate(), mem->data,
1273 String::kNormalString, mem->length));
1274 (void) BIO_reset(bio);
1277 if (pkey != nullptr) {
1278 EVP_PKEY_free(pkey);
1281 if (rsa != nullptr) {
1286 ASN1_TIME_print(bio, X509_get_notBefore(cert));
1287 BIO_get_mem_ptr(bio, &mem);
1288 info->Set(env->valid_from_string(),
1289 String::NewFromUtf8(env->isolate(), mem->data,
1290 String::kNormalString, mem->length));
1291 (void) BIO_reset(bio);
1293 ASN1_TIME_print(bio, X509_get_notAfter(cert));
1294 BIO_get_mem_ptr(bio, &mem);
1295 info->Set(env->valid_to_string(),
1296 String::NewFromUtf8(env->isolate(), mem->data,
1297 String::kNormalString, mem->length));
1300 unsigned int md_size, i;
1301 unsigned char md[EVP_MAX_MD_SIZE];
1302 if (X509_digest(cert, EVP_sha1(), md, &md_size)) {
1303 const char hex[] = "0123456789ABCDEF";
1304 char fingerprint[EVP_MAX_MD_SIZE * 3];
1306 // TODO(indutny): Unify it with buffer's code
1307 for (i = 0; i < md_size; i++) {
1308 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1309 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1310 fingerprint[(3*i)+2] = ':';
1314 fingerprint[(3*(md_size-1))+2] = '\0';
1316 fingerprint[0] = '\0';
1319 info->Set(env->fingerprint_string(),
1320 OneByteString(env->isolate(), fingerprint));
1323 STACK_OF(ASN1_OBJECT)* eku = static_cast<STACK_OF(ASN1_OBJECT)*>(
1324 X509_get_ext_d2i(cert, NID_ext_key_usage, nullptr, nullptr));
1325 if (eku != nullptr) {
1326 Local<Array> ext_key_usage = Array::New(env->isolate());
1330 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1331 if (OBJ_obj2txt(buf, sizeof(buf), sk_ASN1_OBJECT_value(eku, i), 1) >= 0)
1332 ext_key_usage->Set(j++, OneByteString(env->isolate(), buf));
1335 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1336 info->Set(env->ext_key_usage_string(), ext_key_usage);
1339 if (ASN1_INTEGER* serial_number = X509_get_serialNumber(cert)) {
1340 if (BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, nullptr)) {
1341 if (char* buf = BN_bn2hex(bn)) {
1342 info->Set(env->serial_number_string(),
1343 OneByteString(env->isolate(), buf));
1350 // Raw DER certificate
1351 int size = i2d_X509(cert, nullptr);
1352 Local<Object> buff = Buffer::New(env, size);
1353 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1354 Buffer::Data(buff));
1355 i2d_X509(cert, &serialized);
1356 info->Set(env->raw_string(), buff);
1358 return scope.Escape(info);
1362 // TODO(indutny): Split it into multiple smaller functions
1363 template <class Base>
1364 void SSLWrap<Base>::GetPeerCertificate(
1365 const FunctionCallbackInfo<Value>& args) {
1366 Base* w = Unwrap<Base>(args.Holder());
1367 Environment* env = w->ssl_env();
1369 ClearErrorOnReturn clear_error_on_return;
1370 (void) &clear_error_on_return; // Silence unused variable warning.
1372 Local<Object> result;
1375 // NOTE: This is because of the odd OpenSSL behavior. On client `cert_chain`
1376 // contains the `peer_certificate`, but on server it doesn't
1377 X509* cert = w->is_server() ? SSL_get_peer_certificate(w->ssl_) : nullptr;
1378 STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(w->ssl_);
1379 STACK_OF(X509)* peer_certs = nullptr;
1380 if (cert == nullptr && ssl_certs == nullptr)
1383 if (cert == nullptr && sk_X509_num(ssl_certs) == 0)
1386 // Short result requested
1387 if (args.Length() < 1 || !args[0]->IsTrue()) {
1388 result = X509ToObject(env,
1389 cert == nullptr ? sk_X509_value(ssl_certs, 0) : cert);
1393 // Clone `ssl_certs`, because we are going to destruct it
1394 peer_certs = sk_X509_new(nullptr);
1395 if (cert != nullptr)
1396 sk_X509_push(peer_certs, cert);
1397 for (int i = 0; i < sk_X509_num(ssl_certs); i++) {
1398 cert = X509_dup(sk_X509_value(ssl_certs, i));
1399 if (cert == nullptr)
1401 if (!sk_X509_push(peer_certs, cert))
1405 // First and main certificate
1406 cert = sk_X509_value(peer_certs, 0);
1407 result = X509ToObject(env, cert);
1410 // Put issuer inside the object
1411 cert = sk_X509_delete(peer_certs, 0);
1412 while (sk_X509_num(peer_certs) > 0) {
1414 for (i = 0; i < sk_X509_num(peer_certs); i++) {
1415 X509* ca = sk_X509_value(peer_certs, i);
1416 if (X509_check_issued(ca, cert) != X509_V_OK)
1419 Local<Object> ca_info = X509ToObject(env, ca);
1420 info->Set(env->issuercert_string(), ca_info);
1423 // NOTE: Intentionally freeing cert that is not used anymore
1426 // Delete cert and continue aggregating issuers
1427 cert = sk_X509_delete(peer_certs, i);
1431 // Issuer not found, break out of the loop
1432 if (i == sk_X509_num(peer_certs))
1436 // Last certificate should be self-signed
1437 while (X509_check_issued(cert, cert) != X509_V_OK) {
1439 if (SSL_CTX_get_issuer(w->ssl_->ctx, cert, &ca) <= 0)
1442 Local<Object> ca_info = X509ToObject(env, ca);
1443 info->Set(env->issuercert_string(), ca_info);
1446 // NOTE: Intentionally freeing cert that is not used anymore
1449 // Delete cert and continue aggregating issuers
1453 // Self-issued certificate
1454 if (X509_check_issued(cert, cert) == X509_V_OK)
1455 info->Set(env->issuercert_string(), info);
1457 CHECK_NE(cert, nullptr);
1460 if (cert != nullptr)
1462 if (peer_certs != nullptr)
1463 sk_X509_pop_free(peer_certs, X509_free);
1464 if (result.IsEmpty())
1465 result = Object::New(env->isolate());
1466 args.GetReturnValue().Set(result);
1470 template <class Base>
1471 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
1472 Environment* env = Environment::GetCurrent(args);
1474 Base* w = Unwrap<Base>(args.Holder());
1476 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1477 if (sess == nullptr)
1480 int slen = i2d_SSL_SESSION(sess, nullptr);
1483 char* sbuf = new char[slen];
1484 unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1485 i2d_SSL_SESSION(sess, &p);
1486 args.GetReturnValue().Set(Encode(env->isolate(), sbuf, slen, BUFFER));
1491 template <class Base>
1492 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
1493 Environment* env = Environment::GetCurrent(args);
1495 Base* w = Unwrap<Base>(args.Holder());
1497 if (args.Length() < 1 ||
1498 (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
1499 return env->ThrowTypeError("Bad argument");
1502 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
1503 size_t slen = Buffer::Length(args[0]);
1504 char* sbuf = new char[slen];
1505 memcpy(sbuf, Buffer::Data(args[0]), slen);
1507 const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
1508 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, slen);
1512 if (sess == nullptr)
1515 int r = SSL_set_session(w->ssl_, sess);
1516 SSL_SESSION_free(sess);
1519 return env->ThrowError("SSL_set_session error");
1523 template <class Base>
1524 void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
1525 Base* w = Unwrap<Base>(args.Holder());
1526 Environment* env = w->ssl_env();
1528 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1529 ssize_t slen = Buffer::Length(args[0]);
1530 char* sbuf = Buffer::Data(args[0]);
1532 const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1533 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, slen);
1535 // Setup next session and move hello to the BIO buffer
1536 if (w->next_sess_ != nullptr)
1537 SSL_SESSION_free(w->next_sess_);
1538 w->next_sess_ = sess;
1540 Local<Object> info = Object::New(env->isolate());
1541 #ifndef OPENSSL_NO_TLSEXT
1542 if (sess->tlsext_hostname == nullptr) {
1543 info->Set(env->servername_string(), False(args.GetIsolate()));
1545 info->Set(env->servername_string(),
1546 OneByteString(args.GetIsolate(), sess->tlsext_hostname));
1549 args.GetReturnValue().Set(info);
1554 template <class Base>
1555 void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
1556 Base* w = Unwrap<Base>(args.Holder());
1557 bool yes = SSL_session_reused(w->ssl_);
1558 args.GetReturnValue().Set(yes);
1562 template <class Base>
1563 void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
1564 Base* w = Unwrap<Base>(args.Holder());
1565 w->hello_parser_.End();
1569 template <class Base>
1570 void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
1571 Base* w = Unwrap<Base>(args.Holder());
1573 ClearErrorOnReturn clear_error_on_return;
1574 (void) &clear_error_on_return; // Silence unused variable warning.
1576 bool yes = SSL_renegotiate(w->ssl_) == 1;
1577 args.GetReturnValue().Set(yes);
1581 template <class Base>
1582 void SSLWrap<Base>::Shutdown(const FunctionCallbackInfo<Value>& args) {
1583 Base* w = Unwrap<Base>(args.Holder());
1585 int rv = SSL_shutdown(w->ssl_);
1586 args.GetReturnValue().Set(rv);
1590 template <class Base>
1591 void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
1592 Base* w = Unwrap<Base>(args.Holder());
1593 Environment* env = w->ssl_env();
1595 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1596 if (sess == nullptr || sess->tlsext_tick == nullptr)
1599 Local<Object> buf = Buffer::New(env,
1600 reinterpret_cast<char*>(sess->tlsext_tick),
1601 sess->tlsext_ticklen);
1603 args.GetReturnValue().Set(buf);
1607 template <class Base>
1608 void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
1609 Base* w = Unwrap<Base>(args.Holder());
1610 w->new_session_wait_ = false;
1611 w->NewSessionDoneCb();
1615 template <class Base>
1616 void SSLWrap<Base>::SetOCSPResponse(
1617 const v8::FunctionCallbackInfo<v8::Value>& args) {
1618 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1619 HandleScope scope(args.GetIsolate());
1621 Base* w = Unwrap<Base>(args.Holder());
1622 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1623 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1625 w->ocsp_response_.Reset(args.GetIsolate(), args[0].As<Object>());
1626 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1630 template <class Base>
1631 void SSLWrap<Base>::RequestOCSP(
1632 const v8::FunctionCallbackInfo<v8::Value>& args) {
1633 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1634 HandleScope scope(args.GetIsolate());
1636 Base* w = Unwrap<Base>(args.Holder());
1638 SSL_set_tlsext_status_type(w->ssl_, TLSEXT_STATUSTYPE_ocsp);
1639 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1643 #ifdef SSL_set_max_send_fragment
1644 template <class Base>
1645 void SSLWrap<Base>::SetMaxSendFragment(
1646 const v8::FunctionCallbackInfo<v8::Value>& args) {
1647 HandleScope scope(args.GetIsolate());
1648 CHECK(args.Length() >= 1 && args[0]->IsNumber());
1650 Base* w = Unwrap<Base>(args.Holder());
1652 int rv = SSL_set_max_send_fragment(w->ssl_, args[0]->Int32Value());
1653 args.GetReturnValue().Set(rv);
1655 #endif // SSL_set_max_send_fragment
1658 template <class Base>
1659 void SSLWrap<Base>::IsInitFinished(const FunctionCallbackInfo<Value>& args) {
1660 Base* w = Unwrap<Base>(args.Holder());
1661 bool yes = SSL_is_init_finished(w->ssl_);
1662 args.GetReturnValue().Set(yes);
1666 template <class Base>
1667 void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
1668 Base* w = Unwrap<Base>(args.Holder());
1670 // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
1671 // peer certificate is questionable but it's compatible with what was
1673 long x509_verify_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
1674 if (X509* peer_cert = SSL_get_peer_certificate(w->ssl_)) {
1675 X509_free(peer_cert);
1676 x509_verify_error = SSL_get_verify_result(w->ssl_);
1679 if (x509_verify_error == X509_V_OK)
1680 return args.GetReturnValue().SetNull();
1682 // XXX(bnoordhuis) X509_verify_cert_error_string() is not actually thread-safe
1683 // in the presence of invalid error codes. Probably academical but something
1684 // to keep in mind if/when node ever grows multi-isolate capabilities.
1685 const char* reason = X509_verify_cert_error_string(x509_verify_error);
1686 const char* code = reason;
1687 #define CASE_X509_ERR(CODE) case X509_V_ERR_##CODE: code = #CODE; break;
1688 switch (x509_verify_error) {
1689 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT)
1690 CASE_X509_ERR(UNABLE_TO_GET_CRL)
1691 CASE_X509_ERR(UNABLE_TO_DECRYPT_CERT_SIGNATURE)
1692 CASE_X509_ERR(UNABLE_TO_DECRYPT_CRL_SIGNATURE)
1693 CASE_X509_ERR(UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)
1694 CASE_X509_ERR(CERT_SIGNATURE_FAILURE)
1695 CASE_X509_ERR(CRL_SIGNATURE_FAILURE)
1696 CASE_X509_ERR(CERT_NOT_YET_VALID)
1697 CASE_X509_ERR(CERT_HAS_EXPIRED)
1698 CASE_X509_ERR(CRL_NOT_YET_VALID)
1699 CASE_X509_ERR(CRL_HAS_EXPIRED)
1700 CASE_X509_ERR(ERROR_IN_CERT_NOT_BEFORE_FIELD)
1701 CASE_X509_ERR(ERROR_IN_CERT_NOT_AFTER_FIELD)
1702 CASE_X509_ERR(ERROR_IN_CRL_LAST_UPDATE_FIELD)
1703 CASE_X509_ERR(ERROR_IN_CRL_NEXT_UPDATE_FIELD)
1704 CASE_X509_ERR(OUT_OF_MEM)
1705 CASE_X509_ERR(DEPTH_ZERO_SELF_SIGNED_CERT)
1706 CASE_X509_ERR(SELF_SIGNED_CERT_IN_CHAIN)
1707 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
1708 CASE_X509_ERR(UNABLE_TO_VERIFY_LEAF_SIGNATURE)
1709 CASE_X509_ERR(CERT_CHAIN_TOO_LONG)
1710 CASE_X509_ERR(CERT_REVOKED)
1711 CASE_X509_ERR(INVALID_CA)
1712 CASE_X509_ERR(PATH_LENGTH_EXCEEDED)
1713 CASE_X509_ERR(INVALID_PURPOSE)
1714 CASE_X509_ERR(CERT_UNTRUSTED)
1715 CASE_X509_ERR(CERT_REJECTED)
1717 #undef CASE_X509_ERR
1719 Isolate* isolate = args.GetIsolate();
1720 Local<String> reason_string = OneByteString(isolate, reason);
1721 Local<Value> exception_value = Exception::Error(reason_string);
1722 Local<Object> exception_object = exception_value->ToObject(isolate);
1723 exception_object->Set(FIXED_ONE_BYTE_STRING(isolate, "code"),
1724 OneByteString(isolate, code));
1725 args.GetReturnValue().Set(exception_object);
1729 template <class Base>
1730 void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
1731 Base* w = Unwrap<Base>(args.Holder());
1732 Environment* env = w->ssl_env();
1734 OPENSSL_CONST SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_);
1738 Local<Object> info = Object::New(env->isolate());
1739 const char* cipher_name = SSL_CIPHER_get_name(c);
1740 info->Set(env->name_string(), OneByteString(args.GetIsolate(), cipher_name));
1741 const char* cipher_version = SSL_CIPHER_get_version(c);
1742 info->Set(env->version_string(),
1743 OneByteString(args.GetIsolate(), cipher_version));
1744 args.GetReturnValue().Set(info);
1748 #ifdef OPENSSL_NPN_NEGOTIATED
1749 template <class Base>
1750 int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s,
1751 const unsigned char** data,
1754 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1755 Environment* env = w->env();
1756 HandleScope handle_scope(env->isolate());
1757 Context::Scope context_scope(env->context());
1759 if (w->npn_protos_.IsEmpty()) {
1760 // No initialization - no NPN protocols
1761 *data = reinterpret_cast<const unsigned char*>("");
1764 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1765 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1766 *len = Buffer::Length(obj);
1769 return SSL_TLSEXT_ERR_OK;
1773 template <class Base>
1774 int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
1775 unsigned char** out,
1776 unsigned char* outlen,
1777 const unsigned char* in,
1780 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1781 Environment* env = w->env();
1782 HandleScope handle_scope(env->isolate());
1783 Context::Scope context_scope(env->context());
1785 // Release old protocol handler if present
1786 w->selected_npn_proto_.Reset();
1788 if (w->npn_protos_.IsEmpty()) {
1789 // We should at least select one protocol
1790 // If server is using NPN
1791 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
1794 // set status: unsupported
1795 w->selected_npn_proto_.Reset(env->isolate(), False(env->isolate()));
1797 return SSL_TLSEXT_ERR_OK;
1800 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1801 const unsigned char* npn_protos =
1802 reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1803 size_t len = Buffer::Length(obj);
1805 int status = SSL_select_next_proto(out, outlen, in, inlen, npn_protos, len);
1806 Handle<Value> result;
1808 case OPENSSL_NPN_UNSUPPORTED:
1809 result = Null(env->isolate());
1811 case OPENSSL_NPN_NEGOTIATED:
1812 result = OneByteString(env->isolate(), *out, *outlen);
1814 case OPENSSL_NPN_NO_OVERLAP:
1815 result = False(env->isolate());
1821 if (!result.IsEmpty())
1822 w->selected_npn_proto_.Reset(env->isolate(), result);
1824 return SSL_TLSEXT_ERR_OK;
1828 template <class Base>
1829 void SSLWrap<Base>::GetNegotiatedProto(
1830 const FunctionCallbackInfo<Value>& args) {
1831 Base* w = Unwrap<Base>(args.Holder());
1833 if (w->is_client()) {
1834 if (w->selected_npn_proto_.IsEmpty() == false) {
1835 args.GetReturnValue().Set(w->selected_npn_proto_);
1840 const unsigned char* npn_proto;
1841 unsigned int npn_proto_len;
1843 SSL_get0_next_proto_negotiated(w->ssl_, &npn_proto, &npn_proto_len);
1846 return args.GetReturnValue().Set(false);
1848 args.GetReturnValue().Set(
1849 OneByteString(args.GetIsolate(), npn_proto, npn_proto_len));
1853 template <class Base>
1854 void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
1855 Base* w = Unwrap<Base>(args.Holder());
1857 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1858 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1860 w->npn_protos_.Reset(args.GetIsolate(), args[0].As<Object>());
1862 #endif // OPENSSL_NPN_NEGOTIATED
1865 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1866 template <class Base>
1867 int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
1868 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1869 Environment* env = w->env();
1870 HandleScope handle_scope(env->isolate());
1872 if (w->is_client()) {
1873 // Incoming response
1874 const unsigned char* resp;
1875 int len = SSL_get_tlsext_status_ocsp_resp(s, &resp);
1877 if (resp == nullptr) {
1878 arg = Null(env->isolate());
1882 reinterpret_cast<char*>(const_cast<unsigned char*>(resp)),
1886 w->MakeCallback(env->onocspresponse_string(), 1, &arg);
1888 // Somehow, client is expecting different return value here
1891 // Outgoing response
1892 if (w->ocsp_response_.IsEmpty())
1893 return SSL_TLSEXT_ERR_NOACK;
1895 Local<Object> obj = PersistentToLocal(env->isolate(), w->ocsp_response_);
1896 char* resp = Buffer::Data(obj);
1897 size_t len = Buffer::Length(obj);
1899 // OpenSSL takes control of the pointer after accepting it
1900 char* data = reinterpret_cast<char*>(malloc(len));
1901 CHECK_NE(data, nullptr);
1902 memcpy(data, resp, len);
1904 if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
1906 w->ocsp_response_.Reset();
1908 return SSL_TLSEXT_ERR_OK;
1911 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1914 template <class Base>
1915 void SSLWrap<Base>::WaitForCertCb(CertCb cb, void* arg) {
1921 template <class Base>
1922 int SSLWrap<Base>::SSLCertCallback(SSL* s, void* arg) {
1923 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1925 if (!w->is_server())
1928 if (!w->is_waiting_cert_cb())
1931 if (w->cert_cb_running_)
1934 Environment* env = w->env();
1935 HandleScope handle_scope(env->isolate());
1936 Context::Scope context_scope(env->context());
1937 w->cert_cb_running_ = true;
1939 Local<Object> info = Object::New(env->isolate());
1941 SSL_SESSION* sess = SSL_get_session(s);
1942 if (sess != nullptr) {
1943 if (sess->tlsext_hostname == nullptr) {
1944 info->Set(env->servername_string(), String::Empty(env->isolate()));
1946 Local<String> servername = OneByteString(env->isolate(),
1947 sess->tlsext_hostname,
1948 strlen(sess->tlsext_hostname));
1949 info->Set(env->servername_string(), servername);
1951 info->Set(env->tls_ticket_string(),
1952 Boolean::New(env->isolate(), sess->tlsext_ticklen != 0));
1954 bool ocsp = s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp;
1955 info->Set(env->ocsp_request_string(), Boolean::New(env->isolate(), ocsp));
1957 Local<Value> argv[] = { info };
1958 w->MakeCallback(env->oncertcb_string(), ARRAY_SIZE(argv), argv);
1960 if (!w->cert_cb_running_)
1963 // Performing async action, wait...
1968 template <class Base>
1969 void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
1970 Base* w = Unwrap<Base>(args.Holder());
1971 Environment* env = w->env();
1973 CHECK(w->is_waiting_cert_cb() && w->cert_cb_running_);
1975 Local<Object> object = w->object();
1976 Local<Value> ctx = object->Get(env->sni_context_string());
1977 Local<FunctionTemplate> cons = env->secure_context_constructor_template();
1979 // Not an object, probably undefined or null
1980 if (!ctx->IsObject())
1983 if (cons->HasInstance(ctx)) {
1984 SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
1985 w->sni_context_.Reset();
1986 w->sni_context_.Reset(env->isolate(), ctx);
1990 // NOTE: reference count is not increased by this API methods
1991 X509* x509 = SSL_CTX_get0_certificate(sc->ctx_);
1992 EVP_PKEY* pkey = SSL_CTX_get0_privatekey(sc->ctx_);
1993 STACK_OF(X509)* chain;
1995 rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain);
1997 rv = SSL_use_certificate(w->ssl_, x509);
1999 rv = SSL_use_PrivateKey(w->ssl_, pkey);
2000 if (rv && chain != nullptr)
2001 rv = SSL_set1_chain(w->ssl_, chain);
2003 unsigned long err = ERR_get_error();
2005 return env->ThrowError("CertCbDone");
2006 return ThrowCryptoError(env, err);
2009 // Failure: incorrect SNI context object
2010 Local<Value> err = Exception::TypeError(env->sni_context_err_string());
2011 w->MakeCallback(env->onerror_string(), 1, &err);
2020 arg = w->cert_cb_arg_;
2022 w->cert_cb_running_ = false;
2023 w->cert_cb_ = nullptr;
2024 w->cert_cb_arg_ = nullptr;
2030 template <class Base>
2031 void SSLWrap<Base>::SSLGetter(Local<String> property,
2032 const PropertyCallbackInfo<Value>& info) {
2033 HandleScope scope(info.GetIsolate());
2035 SSL* ssl = Unwrap<Base>(info.Holder())->ssl_;
2036 Local<External> ext = External::New(info.GetIsolate(), ssl);
2037 info.GetReturnValue().Set(ext);
2041 template <class Base>
2042 void SSLWrap<Base>::DestroySSL() {
2043 if (ssl_ == nullptr)
2047 env_->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
2052 void Connection::OnClientHelloParseEnd(void* arg) {
2053 Connection* conn = static_cast<Connection*>(arg);
2055 // Write all accumulated data
2056 int r = BIO_write(conn->bio_read_,
2057 reinterpret_cast<char*>(conn->hello_data_),
2058 conn->hello_offset_);
2059 conn->HandleBIOError(conn->bio_read_, "BIO_write", r);
2060 conn->SetShutdownFlags();
2064 #ifdef SSL_PRINT_DEBUG
2065 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
2067 # define DEBUG_PRINT(...)
2071 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
2075 int retry = BIO_should_retry(bio);
2076 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
2078 if (BIO_should_write(bio)) {
2079 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n",
2085 } else if (BIO_should_read(bio)) {
2086 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
2090 char ssl_error_buf[512];
2091 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
2093 HandleScope scope(ssl_env()->isolate());
2094 Local<Value> exception =
2095 Exception::Error(OneByteString(ssl_env()->isolate(), ssl_error_buf));
2096 object()->Set(ssl_env()->error_string(), exception);
2098 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
2111 int Connection::HandleSSLError(const char* func,
2115 ClearErrorOnReturn clear_error_on_return;
2116 (void) &clear_error_on_return; // Silence unused variable warning.
2120 if (rv == 0 && zs == kZeroIsNotAnError)
2123 int err = SSL_get_error(ssl_, rv);
2125 if (err == SSL_ERROR_NONE) {
2128 } else if (err == SSL_ERROR_WANT_WRITE) {
2129 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
2132 } else if (err == SSL_ERROR_WANT_READ) {
2133 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
2136 } else if (err == SSL_ERROR_WANT_X509_LOOKUP) {
2137 DEBUG_PRINT("[%p] SSL: %s want x509 lookup\n", ssl_, func);
2140 } else if (err == SSL_ERROR_ZERO_RETURN) {
2141 HandleScope scope(ssl_env()->isolate());
2143 Local<Value> exception =
2144 Exception::Error(ssl_env()->zero_return_string());
2145 object()->Set(ssl_env()->error_string(), exception);
2148 } else if (err == SSL_ERROR_SYSCALL && ss == kIgnoreSyscall) {
2152 HandleScope scope(ssl_env()->isolate());
2156 CHECK(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
2158 // XXX We need to drain the error queue for this thread or else OpenSSL
2159 // has the possibility of blocking connections? This problem is not well
2160 // understood. And we should be somehow propagating these errors up
2161 // into JavaScript. There is no test which demonstrates this problem.
2162 // https://github.com/joyent/node/issues/1719
2163 bio = BIO_new(BIO_s_mem());
2164 if (bio != nullptr) {
2165 ERR_print_errors(bio);
2166 BIO_get_mem_ptr(bio, &mem);
2167 Local<Value> exception = Exception::Error(
2168 OneByteString(ssl_env()->isolate(),
2171 object()->Set(ssl_env()->error_string(), exception);
2182 void Connection::ClearError() {
2184 HandleScope scope(ssl_env()->isolate());
2186 // We should clear the error in JS-land
2187 Local<String> error_key = ssl_env()->error_string();
2188 Local<Value> error = object()->Get(error_key);
2189 CHECK_EQ(error->BooleanValue(), false);
2194 void Connection::SetShutdownFlags() {
2195 HandleScope scope(ssl_env()->isolate());
2197 int flags = SSL_get_shutdown(ssl_);
2199 if (flags & SSL_SENT_SHUTDOWN) {
2200 Local<String> sent_shutdown_key = ssl_env()->sent_shutdown_string();
2201 object()->Set(sent_shutdown_key, True(ssl_env()->isolate()));
2204 if (flags & SSL_RECEIVED_SHUTDOWN) {
2205 Local<String> received_shutdown_key = ssl_env()->received_shutdown_string();
2206 object()->Set(received_shutdown_key, True(ssl_env()->isolate()));
2211 void Connection::NewSessionDoneCb() {
2212 HandleScope scope(env()->isolate());
2214 MakeCallback(env()->onnewsessiondone_string(), 0, nullptr);
2218 void Connection::Initialize(Environment* env, Handle<Object> target) {
2219 Local<FunctionTemplate> t = env->NewFunctionTemplate(Connection::New);
2220 t->InstanceTemplate()->SetInternalFieldCount(1);
2221 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"));
2223 env->SetProtoMethod(t, "encIn", Connection::EncIn);
2224 env->SetProtoMethod(t, "clearOut", Connection::ClearOut);
2225 env->SetProtoMethod(t, "clearIn", Connection::ClearIn);
2226 env->SetProtoMethod(t, "encOut", Connection::EncOut);
2227 env->SetProtoMethod(t, "clearPending", Connection::ClearPending);
2228 env->SetProtoMethod(t, "encPending", Connection::EncPending);
2229 env->SetProtoMethod(t, "start", Connection::Start);
2230 env->SetProtoMethod(t, "close", Connection::Close);
2232 SSLWrap<Connection>::AddMethods(env, t);
2235 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2236 env->SetProtoMethod(t, "getServername", Connection::GetServername);
2237 env->SetProtoMethod(t, "setSNICallback", Connection::SetSNICallback);
2240 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"),
2245 inline int compar(const void* a, const void* b) {
2246 return memcmp(a, b, CNNIC_WHITELIST_HASH_LEN);
2250 inline int IsSelfSigned(X509* cert) {
2251 return X509_NAME_cmp(X509_get_subject_name(cert),
2252 X509_get_issuer_name(cert)) == 0;
2256 inline X509* FindRoot(STACK_OF(X509)* sk) {
2257 for (int i = 0; i < sk_X509_num(sk); i++) {
2258 X509* cert = sk_X509_value(sk, i);
2259 if (IsSelfSigned(cert))
2266 // Whitelist check for certs issued by CNNIC. See
2267 // https://blog.mozilla.org/security/2015/04/02
2268 // /distrusting-new-cnnic-certificates/
2269 inline CheckResult CheckWhitelistedServerCert(X509_STORE_CTX* ctx) {
2270 unsigned char hash[CNNIC_WHITELIST_HASH_LEN];
2271 unsigned int hashlen = CNNIC_WHITELIST_HASH_LEN;
2273 STACK_OF(X509)* chain = X509_STORE_CTX_get1_chain(ctx);
2274 CHECK_NE(chain, nullptr);
2275 CHECK_GT(sk_X509_num(chain), 0);
2277 // Take the last cert as root at the first time.
2278 X509* root_cert = sk_X509_value(chain, sk_X509_num(chain)-1);
2279 X509_NAME* root_name = X509_get_subject_name(root_cert);
2281 if (!IsSelfSigned(root_cert)) {
2282 root_cert = FindRoot(chain);
2283 CHECK_NE(root_cert, nullptr);
2284 root_name = X509_get_subject_name(root_cert);
2287 // When the cert is issued from either CNNNIC ROOT CA or CNNNIC EV
2288 // ROOT CA, check a hash of its leaf cert if it is in the whitelist.
2289 if (X509_NAME_cmp(root_name, cnnic_name) == 0 ||
2290 X509_NAME_cmp(root_name, cnnic_ev_name) == 0) {
2291 X509* leaf_cert = sk_X509_value(chain, 0);
2292 int ret = X509_digest(leaf_cert, EVP_sha256(), hash,
2296 void* result = bsearch(hash, WhitelistedCNNICHashes,
2297 ARRAY_SIZE(WhitelistedCNNICHashes),
2298 CNNIC_WHITELIST_HASH_LEN, compar);
2299 if (result == nullptr) {
2300 sk_X509_pop_free(chain, X509_free);
2301 return CHECK_CERT_REVOKED;
2305 sk_X509_pop_free(chain, X509_free);
2310 inline int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
2311 // Failure on verification of the cert is handled in
2312 // Connection::VerifyError.
2313 if (preverify_ok == 0)
2316 // Server does not need to check the whitelist.
2317 SSL* ssl = static_cast<SSL*>(
2318 X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
2320 if (SSL_is_server(ssl))
2323 // Client needs to check if the server cert is listed in the
2324 // whitelist when it is issued by the specific rootCAs.
2325 CheckResult ret = CheckWhitelistedServerCert(ctx);
2326 if (ret == CHECK_CERT_REVOKED)
2327 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
2333 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2334 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
2335 Connection* conn = static_cast<Connection*>(SSL_get_app_data(s));
2336 Environment* env = conn->env();
2337 HandleScope scope(env->isolate());
2339 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
2342 conn->servername_.Reset(env->isolate(),
2343 OneByteString(env->isolate(), servername));
2345 // Call the SNI callback and use its return value as context
2346 if (!conn->sniObject_.IsEmpty()) {
2347 conn->sni_context_.Reset();
2349 Local<Value> arg = PersistentToLocal(env->isolate(), conn->servername_);
2350 Local<Value> ret = conn->MakeCallback(env->onselect_string(), 1, &arg);
2352 // If ret is SecureContext
2353 Local<FunctionTemplate> secure_context_constructor_template =
2354 env->secure_context_constructor_template();
2355 if (secure_context_constructor_template->HasInstance(ret)) {
2356 conn->sni_context_.Reset(env->isolate(), ret);
2357 SecureContext* sc = Unwrap<SecureContext>(ret.As<Object>());
2359 SSL_set_SSL_CTX(s, sc->ctx_);
2361 return SSL_TLSEXT_ERR_NOACK;
2366 return SSL_TLSEXT_ERR_OK;
2370 void Connection::New(const FunctionCallbackInfo<Value>& args) {
2371 Environment* env = Environment::GetCurrent(args);
2373 if (args.Length() < 1 || !args[0]->IsObject()) {
2374 env->ThrowError("First argument must be a tls module SecureContext");
2378 SecureContext* sc = Unwrap<SecureContext>(args[0]->ToObject(env->isolate()));
2380 bool is_server = args[1]->BooleanValue();
2382 SSLWrap<Connection>::Kind kind =
2383 is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient;
2384 Connection* conn = new Connection(env, args.This(), sc, kind);
2385 conn->bio_read_ = NodeBIO::New();
2386 conn->bio_write_ = NodeBIO::New();
2388 SSL_set_app_data(conn->ssl_, conn);
2391 SSL_set_info_callback(conn->ssl_, SSLInfoCallback);
2395 SSL_set_cert_cb(conn->ssl_, SSLWrap<Connection>::SSLCertCallback, conn);
2397 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2399 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
2400 } else if (args[2]->IsString()) {
2401 const node::Utf8Value servername(env->isolate(), args[2]);
2402 SSL_set_tlsext_host_name(conn->ssl_, *servername);
2406 SSL_set_bio(conn->ssl_, conn->bio_read_, conn->bio_write_);
2408 #ifdef SSL_MODE_RELEASE_BUFFERS
2409 long mode = SSL_get_mode(conn->ssl_);
2410 SSL_set_mode(conn->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
2416 bool request_cert = args[2]->BooleanValue();
2417 if (!request_cert) {
2418 // Note reject_unauthorized ignored.
2419 verify_mode = SSL_VERIFY_NONE;
2421 bool reject_unauthorized = args[3]->BooleanValue();
2422 verify_mode = SSL_VERIFY_PEER;
2423 if (reject_unauthorized)
2424 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2427 // Note request_cert and reject_unauthorized are ignored for clients.
2428 verify_mode = SSL_VERIFY_NONE;
2432 // Always allow a connection. We'll reject in javascript.
2433 SSL_set_verify(conn->ssl_, verify_mode, VerifyCallback);
2436 SSL_set_accept_state(conn->ssl_);
2438 SSL_set_connect_state(conn->ssl_);
2443 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
2444 if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
2447 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
2448 // a non-const SSL* in OpenSSL <= 0.9.7e.
2449 SSL* ssl = const_cast<SSL*>(ssl_);
2450 Connection* conn = static_cast<Connection*>(SSL_get_app_data(ssl));
2451 Environment* env = conn->env();
2452 HandleScope handle_scope(env->isolate());
2453 Context::Scope context_scope(env->context());
2455 if (where & SSL_CB_HANDSHAKE_START) {
2456 conn->MakeCallback(env->onhandshakestart_string(), 0, nullptr);
2459 if (where & SSL_CB_HANDSHAKE_DONE) {
2460 conn->MakeCallback(env->onhandshakedone_string(), 0, nullptr);
2465 void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
2466 Connection* conn = Unwrap<Connection>(args.Holder());
2467 Environment* env = conn->env();
2469 if (args.Length() < 3) {
2470 return env->ThrowTypeError("Takes 3 parameters");
2473 if (!Buffer::HasInstance(args[0])) {
2474 return env->ThrowTypeError("Second argument should be a buffer");
2477 char* buffer_data = Buffer::Data(args[0]);
2478 size_t buffer_length = Buffer::Length(args[0]);
2480 size_t off = args[1]->Int32Value();
2481 size_t len = args[2]->Int32Value();
2483 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2484 return env->ThrowError("off + len > buffer.length");
2487 char* data = buffer_data + off;
2489 if (conn->is_server() && !conn->hello_parser_.IsEnded()) {
2490 // Just accumulate data, everything will be pushed to BIO later
2491 if (conn->hello_parser_.IsPaused()) {
2494 // Copy incoming data to the internal buffer
2495 // (which has a size of the biggest possible TLS frame)
2496 size_t available = sizeof(conn->hello_data_) - conn->hello_offset_;
2497 size_t copied = len < available ? len : available;
2498 memcpy(conn->hello_data_ + conn->hello_offset_, data, copied);
2499 conn->hello_offset_ += copied;
2501 conn->hello_parser_.Parse(conn->hello_data_, conn->hello_offset_);
2502 bytes_written = copied;
2505 bytes_written = BIO_write(conn->bio_read_, data, len);
2506 conn->HandleBIOError(conn->bio_read_, "BIO_write", bytes_written);
2507 conn->SetShutdownFlags();
2510 args.GetReturnValue().Set(bytes_written);
2514 void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
2515 Connection* conn = Unwrap<Connection>(args.Holder());
2516 Environment* env = conn->env();
2518 if (args.Length() < 3) {
2519 return env->ThrowTypeError("Takes 3 parameters");
2522 if (!Buffer::HasInstance(args[0])) {
2523 return env->ThrowTypeError("Second argument should be a buffer");
2526 char* buffer_data = Buffer::Data(args[0]);
2527 size_t buffer_length = Buffer::Length(args[0]);
2529 size_t off = args[1]->Int32Value();
2530 size_t len = args[2]->Int32Value();
2532 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2533 return env->ThrowError("off + len > buffer.length");
2535 if (!SSL_is_init_finished(conn->ssl_)) {
2538 if (conn->is_server()) {
2539 rv = SSL_accept(conn->ssl_);
2540 conn->HandleSSLError("SSL_accept:ClearOut",
2545 rv = SSL_connect(conn->ssl_);
2546 conn->HandleSSLError("SSL_connect:ClearOut",
2553 return args.GetReturnValue().Set(rv);
2557 int bytes_read = SSL_read(conn->ssl_, buffer_data + off, len);
2558 conn->HandleSSLError("SSL_read:ClearOut",
2562 conn->SetShutdownFlags();
2564 args.GetReturnValue().Set(bytes_read);
2568 void Connection::ClearPending(const FunctionCallbackInfo<Value>& args) {
2569 Connection* conn = Unwrap<Connection>(args.Holder());
2570 int bytes_pending = BIO_pending(conn->bio_read_);
2571 args.GetReturnValue().Set(bytes_pending);
2575 void Connection::EncPending(const FunctionCallbackInfo<Value>& args) {
2576 Connection* conn = Unwrap<Connection>(args.Holder());
2577 int bytes_pending = BIO_pending(conn->bio_write_);
2578 args.GetReturnValue().Set(bytes_pending);
2582 void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
2583 Connection* conn = Unwrap<Connection>(args.Holder());
2584 Environment* env = conn->env();
2586 if (args.Length() < 3) {
2587 return env->ThrowTypeError("Takes 3 parameters");
2590 if (!Buffer::HasInstance(args[0])) {
2591 return env->ThrowTypeError("Second argument should be a buffer");
2594 char* buffer_data = Buffer::Data(args[0]);
2595 size_t buffer_length = Buffer::Length(args[0]);
2597 size_t off = args[1]->Int32Value();
2598 size_t len = args[2]->Int32Value();
2600 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2601 return env->ThrowError("off + len > buffer.length");
2603 int bytes_read = BIO_read(conn->bio_write_, buffer_data + off, len);
2605 conn->HandleBIOError(conn->bio_write_, "BIO_read:EncOut", bytes_read);
2606 conn->SetShutdownFlags();
2608 args.GetReturnValue().Set(bytes_read);
2612 void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
2613 Connection* conn = Unwrap<Connection>(args.Holder());
2614 Environment* env = conn->env();
2616 if (args.Length() < 3) {
2617 return env->ThrowTypeError("Takes 3 parameters");
2620 if (!Buffer::HasInstance(args[0])) {
2621 return env->ThrowTypeError("Second argument should be a buffer");
2624 char* buffer_data = Buffer::Data(args[0]);
2625 size_t buffer_length = Buffer::Length(args[0]);
2627 size_t off = args[1]->Int32Value();
2628 size_t len = args[2]->Int32Value();
2630 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2631 return env->ThrowError("off + len > buffer.length");
2633 if (!SSL_is_init_finished(conn->ssl_)) {
2635 if (conn->is_server()) {
2636 rv = SSL_accept(conn->ssl_);
2637 conn->HandleSSLError("SSL_accept:ClearIn",
2642 rv = SSL_connect(conn->ssl_);
2643 conn->HandleSSLError("SSL_connect:ClearIn",
2650 return args.GetReturnValue().Set(rv);
2654 int bytes_written = SSL_write(conn->ssl_, buffer_data + off, len);
2656 conn->HandleSSLError("SSL_write:ClearIn",
2658 len == 0 ? kZeroIsNotAnError : kZeroIsAnError,
2660 conn->SetShutdownFlags();
2662 args.GetReturnValue().Set(bytes_written);
2666 void Connection::Start(const FunctionCallbackInfo<Value>& args) {
2667 Connection* conn = Unwrap<Connection>(args.Holder());
2670 if (!SSL_is_init_finished(conn->ssl_)) {
2671 if (conn->is_server()) {
2672 rv = SSL_accept(conn->ssl_);
2673 conn->HandleSSLError("SSL_accept:Start",
2678 rv = SSL_connect(conn->ssl_);
2679 conn->HandleSSLError("SSL_connect:Start",
2685 args.GetReturnValue().Set(rv);
2689 void Connection::Close(const FunctionCallbackInfo<Value>& args) {
2690 Connection* conn = Unwrap<Connection>(args.Holder());
2692 if (conn->ssl_ != nullptr) {
2693 SSL_free(conn->ssl_);
2694 conn->ssl_ = nullptr;
2699 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2700 void Connection::GetServername(const FunctionCallbackInfo<Value>& args) {
2701 Connection* conn = Unwrap<Connection>(args.Holder());
2703 if (conn->is_server() && !conn->servername_.IsEmpty()) {
2704 args.GetReturnValue().Set(conn->servername_);
2706 args.GetReturnValue().Set(false);
2711 void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) {
2712 Connection* conn = Unwrap<Connection>(args.Holder());
2713 Environment* env = conn->env();
2715 if (args.Length() < 1 || !args[0]->IsFunction()) {
2716 return env->ThrowError("Must give a Function as first argument");
2719 Local<Object> obj = Object::New(env->isolate());
2720 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "onselect"), args[0]);
2721 conn->sniObject_.Reset(args.GetIsolate(), obj);
2726 void CipherBase::Initialize(Environment* env, Handle<Object> target) {
2727 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
2729 t->InstanceTemplate()->SetInternalFieldCount(1);
2731 env->SetProtoMethod(t, "init", Init);
2732 env->SetProtoMethod(t, "initiv", InitIv);
2733 env->SetProtoMethod(t, "update", Update);
2734 env->SetProtoMethod(t, "final", Final);
2735 env->SetProtoMethod(t, "setAutoPadding", SetAutoPadding);
2736 env->SetProtoMethod(t, "getAuthTag", GetAuthTag);
2737 env->SetProtoMethod(t, "setAuthTag", SetAuthTag);
2738 env->SetProtoMethod(t, "setAAD", SetAAD);
2740 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "CipherBase"),
2745 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
2746 CHECK_EQ(args.IsConstructCall(), true);
2747 CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
2748 Environment* env = Environment::GetCurrent(args);
2749 new CipherBase(env, args.This(), kind);
2753 void CipherBase::Init(const char* cipher_type,
2754 const char* key_buf,
2756 HandleScope scope(env()->isolate());
2758 CHECK_EQ(cipher_, nullptr);
2759 cipher_ = EVP_get_cipherbyname(cipher_type);
2760 if (cipher_ == nullptr) {
2761 return env()->ThrowError("Unknown cipher");
2764 unsigned char key[EVP_MAX_KEY_LENGTH];
2765 unsigned char iv[EVP_MAX_IV_LENGTH];
2767 int key_len = EVP_BytesToKey(cipher_,
2770 reinterpret_cast<const unsigned char*>(key_buf),
2776 EVP_CIPHER_CTX_init(&ctx_);
2777 const bool encrypt = (kind_ == kCipher);
2778 EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
2779 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2780 EVP_CIPHER_CTX_cleanup(&ctx_);
2781 return env()->ThrowError("Invalid key length");
2784 EVP_CipherInit_ex(&ctx_,
2787 reinterpret_cast<unsigned char*>(key),
2788 reinterpret_cast<unsigned char*>(iv),
2790 initialised_ = true;
2794 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
2795 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2797 if (args.Length() < 2 ||
2798 !(args[0]->IsString() && Buffer::HasInstance(args[1]))) {
2799 return cipher->env()->ThrowError("Must give cipher-type, key");
2802 const node::Utf8Value cipher_type(args.GetIsolate(), args[0]);
2803 const char* key_buf = Buffer::Data(args[1]);
2804 ssize_t key_buf_len = Buffer::Length(args[1]);
2805 cipher->Init(*cipher_type, key_buf, key_buf_len);
2809 void CipherBase::InitIv(const char* cipher_type,
2814 HandleScope scope(env()->isolate());
2816 cipher_ = EVP_get_cipherbyname(cipher_type);
2817 if (cipher_ == nullptr) {
2818 return env()->ThrowError("Unknown cipher");
2821 /* OpenSSL versions up to 0.9.8l failed to return the correct
2822 iv_length (0) for ECB ciphers */
2823 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
2824 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2825 return env()->ThrowError("Invalid IV length");
2827 EVP_CIPHER_CTX_init(&ctx_);
2828 const bool encrypt = (kind_ == kCipher);
2829 EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
2830 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2831 EVP_CIPHER_CTX_cleanup(&ctx_);
2832 return env()->ThrowError("Invalid key length");
2835 EVP_CipherInit_ex(&ctx_,
2838 reinterpret_cast<const unsigned char*>(key),
2839 reinterpret_cast<const unsigned char*>(iv),
2841 initialised_ = true;
2845 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
2846 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2847 Environment* env = cipher->env();
2849 if (args.Length() < 3 || !args[0]->IsString()) {
2850 return env->ThrowError("Must give cipher-type, key, and iv as argument");
2853 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
2854 THROW_AND_RETURN_IF_NOT_BUFFER(args[2]);
2856 const node::Utf8Value cipher_type(env->isolate(), args[0]);
2857 ssize_t key_len = Buffer::Length(args[1]);
2858 const char* key_buf = Buffer::Data(args[1]);
2859 ssize_t iv_len = Buffer::Length(args[2]);
2860 const char* iv_buf = Buffer::Data(args[2]);
2861 cipher->InitIv(*cipher_type, key_buf, key_len, iv_buf, iv_len);
2865 bool CipherBase::IsAuthenticatedMode() const {
2866 // check if this cipher operates in an AEAD mode that we support.
2869 int mode = EVP_CIPHER_mode(cipher_);
2870 return mode == EVP_CIPH_GCM_MODE;
2874 bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
2875 // only callable after Final and if encrypting.
2876 if (initialised_ || kind_ != kCipher || !auth_tag_)
2878 *out_len = auth_tag_len_;
2879 *out = new char[auth_tag_len_];
2880 memcpy(*out, auth_tag_, auth_tag_len_);
2885 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
2886 Environment* env = Environment::GetCurrent(args);
2887 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2889 char* out = nullptr;
2890 unsigned int out_len = 0;
2892 if (cipher->GetAuthTag(&out, &out_len)) {
2893 Local<Object> buf = Buffer::Use(env, out, out_len);
2894 args.GetReturnValue().Set(buf);
2896 env->ThrowError("Attempting to get auth tag in unsupported state");
2901 bool CipherBase::SetAuthTag(const char* data, unsigned int len) {
2902 if (!initialised_ || !IsAuthenticatedMode() || kind_ != kDecipher)
2905 auth_tag_len_ = len;
2906 auth_tag_ = new char[len];
2907 memcpy(auth_tag_, data, len);
2912 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
2913 Environment* env = Environment::GetCurrent(args);
2915 Local<Object> buf = args[0].As<Object>();
2916 if (!buf->IsObject() || !Buffer::HasInstance(buf))
2917 return env->ThrowTypeError("Argument must be a Buffer");
2919 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2921 if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf)))
2922 env->ThrowError("Attempting to set auth tag in unsupported state");
2926 bool CipherBase::SetAAD(const char* data, unsigned int len) {
2927 if (!initialised_ || !IsAuthenticatedMode())
2930 if (!EVP_CipherUpdate(&ctx_,
2933 reinterpret_cast<const unsigned char*>(data),
2941 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
2942 Environment* env = Environment::GetCurrent(args);
2944 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
2946 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2948 if (!cipher->SetAAD(Buffer::Data(args[0]), Buffer::Length(args[0])))
2949 env->ThrowError("Attempting to set AAD in unsupported state");
2953 bool CipherBase::Update(const char* data,
2955 unsigned char** out,
2961 if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_ != nullptr) {
2962 EVP_CIPHER_CTX_ctrl(&ctx_,
2963 EVP_CTRL_GCM_SET_TAG,
2965 reinterpret_cast<unsigned char*>(auth_tag_));
2967 auth_tag_ = nullptr;
2970 *out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
2971 *out = new unsigned char[*out_len];
2972 return EVP_CipherUpdate(&ctx_,
2975 reinterpret_cast<const unsigned char*>(data),
2980 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
2981 Environment* env = Environment::GetCurrent(args);
2983 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2985 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
2987 unsigned char* out = nullptr;
2991 // Only copy the data if we have to, because it's a string
2992 if (args[0]->IsString()) {
2993 StringBytes::InlineDecoder decoder;
2994 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
2996 r = cipher->Update(decoder.out(), decoder.size(), &out, &out_len);
2998 char* buf = Buffer::Data(args[0]);
2999 size_t buflen = Buffer::Length(args[0]);
3000 r = cipher->Update(buf, buflen, &out, &out_len);
3005 return ThrowCryptoError(env,
3007 "Trying to add data in unsupported state");
3010 Local<Object> buf = Buffer::New(env, reinterpret_cast<char*>(out), out_len);
3014 args.GetReturnValue().Set(buf);
3018 bool CipherBase::SetAutoPadding(bool auto_padding) {
3021 return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
3025 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
3026 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3027 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
3031 bool CipherBase::Final(unsigned char** out, int *out_len) {
3035 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx_)];
3036 int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
3038 if (r && kind_ == kCipher) {
3040 auth_tag_ = nullptr;
3041 if (IsAuthenticatedMode()) {
3042 auth_tag_len_ = EVP_GCM_TLS_TAG_LEN; // use default tag length
3043 auth_tag_ = new char[auth_tag_len_];
3044 memset(auth_tag_, 0, auth_tag_len_);
3045 EVP_CIPHER_CTX_ctrl(&ctx_,
3046 EVP_CTRL_GCM_GET_TAG,
3048 reinterpret_cast<unsigned char*>(auth_tag_));
3052 EVP_CIPHER_CTX_cleanup(&ctx_);
3053 initialised_ = false;
3059 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
3060 Environment* env = Environment::GetCurrent(args);
3062 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
3064 unsigned char* out_value = nullptr;
3066 Local<Value> outString;
3068 bool r = cipher->Final(&out_value, &out_len);
3070 if (out_len <= 0 || !r) {
3072 out_value = nullptr;
3075 const char* msg = cipher->IsAuthenticatedMode() ?
3076 "Unsupported state or unable to authenticate data" :
3077 "Unsupported state";
3079 return ThrowCryptoError(env,
3085 args.GetReturnValue().Set(
3086 Buffer::New(env, reinterpret_cast<char*>(out_value), out_len));
3091 void Hmac::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3092 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3094 t->InstanceTemplate()->SetInternalFieldCount(1);
3096 env->SetProtoMethod(t, "init", HmacInit);
3097 env->SetProtoMethod(t, "update", HmacUpdate);
3098 env->SetProtoMethod(t, "digest", HmacDigest);
3100 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hmac"), t->GetFunction());
3104 void Hmac::New(const FunctionCallbackInfo<Value>& args) {
3105 Environment* env = Environment::GetCurrent(args);
3106 new Hmac(env, args.This());
3110 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
3111 HandleScope scope(env()->isolate());
3113 CHECK_EQ(md_, nullptr);
3114 md_ = EVP_get_digestbyname(hash_type);
3115 if (md_ == nullptr) {
3116 return env()->ThrowError("Unknown message digest");
3118 HMAC_CTX_init(&ctx_);
3120 HMAC_Init(&ctx_, "", 0, md_);
3122 HMAC_Init(&ctx_, key, key_len, md_);
3124 initialised_ = true;
3128 void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
3129 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3130 Environment* env = hmac->env();
3132 if (args.Length() < 2 || !args[0]->IsString()) {
3133 return env->ThrowError("Must give hashtype string, key as arguments");
3136 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
3138 const node::Utf8Value hash_type(env->isolate(), args[0]);
3139 const char* buffer_data = Buffer::Data(args[1]);
3140 size_t buffer_length = Buffer::Length(args[1]);
3141 hmac->HmacInit(*hash_type, buffer_data, buffer_length);
3145 bool Hmac::HmacUpdate(const char* data, int len) {
3148 HMAC_Update(&ctx_, reinterpret_cast<const unsigned char*>(data), len);
3153 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
3154 Environment* env = Environment::GetCurrent(args);
3156 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3158 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3160 // Only copy the data if we have to, because it's a string
3162 if (args[0]->IsString()) {
3163 StringBytes::InlineDecoder decoder;
3164 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3166 r = hmac->HmacUpdate(decoder.out(), decoder.size());
3168 char* buf = Buffer::Data(args[0]);
3169 size_t buflen = Buffer::Length(args[0]);
3170 r = hmac->HmacUpdate(buf, buflen);
3174 return env->ThrowTypeError("HmacUpdate fail");
3179 bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
3182 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
3183 HMAC_Final(&ctx_, *md_value, md_len);
3184 HMAC_CTX_cleanup(&ctx_);
3185 initialised_ = false;
3190 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
3191 Environment* env = Environment::GetCurrent(args);
3193 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3195 enum encoding encoding = BUFFER;
3196 if (args.Length() >= 1) {
3197 encoding = ParseEncoding(env->isolate(),
3198 args[0]->ToString(env->isolate()),
3202 unsigned char* md_value = nullptr;
3203 unsigned int md_len = 0;
3205 bool r = hmac->HmacDigest(&md_value, &md_len);
3211 Local<Value> rc = StringBytes::Encode(env->isolate(),
3212 reinterpret_cast<const char*>(md_value),
3216 args.GetReturnValue().Set(rc);
3220 void Hash::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3221 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3223 t->InstanceTemplate()->SetInternalFieldCount(1);
3225 env->SetProtoMethod(t, "update", HashUpdate);
3226 env->SetProtoMethod(t, "digest", HashDigest);
3228 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hash"), t->GetFunction());
3232 void Hash::New(const FunctionCallbackInfo<Value>& args) {
3233 Environment* env = Environment::GetCurrent(args);
3235 if (args.Length() == 0 || !args[0]->IsString()) {
3236 return env->ThrowError("Must give hashtype string as argument");
3239 const node::Utf8Value hash_type(env->isolate(), args[0]);
3241 Hash* hash = new Hash(env, args.This());
3242 if (!hash->HashInit(*hash_type)) {
3243 return env->ThrowError("Digest method not supported");
3248 bool Hash::HashInit(const char* hash_type) {
3249 CHECK_EQ(md_, nullptr);
3250 md_ = EVP_get_digestbyname(hash_type);
3253 EVP_MD_CTX_init(&mdctx_);
3254 EVP_DigestInit_ex(&mdctx_, md_, nullptr);
3255 initialised_ = true;
3260 bool Hash::HashUpdate(const char* data, int len) {
3263 EVP_DigestUpdate(&mdctx_, data, len);
3268 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
3269 Environment* env = Environment::GetCurrent(args);
3271 Hash* hash = Unwrap<Hash>(args.Holder());
3273 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3275 // Only copy the data if we have to, because it's a string
3277 if (args[0]->IsString()) {
3278 StringBytes::InlineDecoder decoder;
3279 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3281 r = hash->HashUpdate(decoder.out(), decoder.size());
3283 char* buf = Buffer::Data(args[0]);
3284 size_t buflen = Buffer::Length(args[0]);
3285 r = hash->HashUpdate(buf, buflen);
3289 return env->ThrowTypeError("HashUpdate fail");
3294 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
3295 Environment* env = Environment::GetCurrent(args);
3297 Hash* hash = Unwrap<Hash>(args.Holder());
3299 if (!hash->initialised_) {
3300 return env->ThrowError("Not initialized");
3303 enum encoding encoding = BUFFER;
3304 if (args.Length() >= 1) {
3305 encoding = ParseEncoding(env->isolate(),
3306 args[0]->ToString(env->isolate()),
3310 unsigned char md_value[EVP_MAX_MD_SIZE];
3311 unsigned int md_len;
3313 EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len);
3314 EVP_MD_CTX_cleanup(&hash->mdctx_);
3315 hash->initialised_ = false;
3317 Local<Value> rc = StringBytes::Encode(env->isolate(),
3318 reinterpret_cast<const char*>(md_value),
3321 args.GetReturnValue().Set(rc);
3325 void SignBase::CheckThrow(SignBase::Error error) {
3326 HandleScope scope(env()->isolate());
3329 case kSignUnknownDigest:
3330 return env()->ThrowError("Unknown message digest");
3332 case kSignNotInitialised:
3333 return env()->ThrowError("Not initialised");
3337 case kSignPrivateKey:
3338 case kSignPublicKey:
3340 unsigned long err = ERR_get_error();
3342 return ThrowCryptoError(env(), err);
3345 return env()->ThrowError("EVP_SignInit_ex failed");
3347 return env()->ThrowError("EVP_SignUpdate failed");
3348 case kSignPrivateKey:
3349 return env()->ThrowError("PEM_read_bio_PrivateKey failed");
3350 case kSignPublicKey:
3351 return env()->ThrowError("PEM_read_bio_PUBKEY failed");
3365 void Sign::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3366 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3368 t->InstanceTemplate()->SetInternalFieldCount(1);
3370 env->SetProtoMethod(t, "init", SignInit);
3371 env->SetProtoMethod(t, "update", SignUpdate);
3372 env->SetProtoMethod(t, "sign", SignFinal);
3374 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"), t->GetFunction());
3378 void Sign::New(const FunctionCallbackInfo<Value>& args) {
3379 Environment* env = Environment::GetCurrent(args);
3380 new Sign(env, args.This());
3384 SignBase::Error Sign::SignInit(const char* sign_type) {
3385 CHECK_EQ(md_, nullptr);
3386 md_ = EVP_get_digestbyname(sign_type);
3388 return kSignUnknownDigest;
3390 EVP_MD_CTX_init(&mdctx_);
3391 if (!EVP_SignInit_ex(&mdctx_, md_, nullptr))
3393 initialised_ = true;
3399 void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
3400 Sign* sign = Unwrap<Sign>(args.Holder());
3402 if (args.Length() == 0 || !args[0]->IsString()) {
3403 return sign->env()->ThrowError("Must give signtype string as argument");
3406 const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
3407 sign->CheckThrow(sign->SignInit(*sign_type));
3411 SignBase::Error Sign::SignUpdate(const char* data, int len) {
3413 return kSignNotInitialised;
3414 if (!EVP_SignUpdate(&mdctx_, data, len))
3420 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
3421 Environment* env = Environment::GetCurrent(args);
3423 Sign* sign = Unwrap<Sign>(args.Holder());
3425 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3427 // Only copy the data if we have to, because it's a string
3429 if (args[0]->IsString()) {
3430 StringBytes::InlineDecoder decoder;
3431 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3433 err = sign->SignUpdate(decoder.out(), decoder.size());
3435 char* buf = Buffer::Data(args[0]);
3436 size_t buflen = Buffer::Length(args[0]);
3437 err = sign->SignUpdate(buf, buflen);
3440 sign->CheckThrow(err);
3444 SignBase::Error Sign::SignFinal(const char* key_pem,
3446 const char* passphrase,
3447 unsigned char** sig,
3448 unsigned int *sig_len) {
3450 return kSignNotInitialised;
3453 EVP_PKEY* pkey = nullptr;
3456 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3460 pkey = PEM_read_bio_PrivateKey(bp,
3463 const_cast<char*>(passphrase));
3464 if (pkey == nullptr)
3467 if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey))
3470 initialised_ = false;
3473 if (pkey != nullptr)
3474 EVP_PKEY_free(pkey);
3478 EVP_MD_CTX_cleanup(&mdctx_);
3481 return kSignPrivateKey;
3487 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
3488 Environment* env = Environment::GetCurrent(args);
3490 Sign* sign = Unwrap<Sign>(args.Holder());
3492 unsigned char* md_value;
3493 unsigned int md_len;
3495 unsigned int len = args.Length();
3496 enum encoding encoding = BUFFER;
3497 if (len >= 2 && args[1]->IsString()) {
3498 encoding = ParseEncoding(env->isolate(),
3499 args[1]->ToString(env->isolate()),
3503 node::Utf8Value passphrase(env->isolate(), args[2]);
3505 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3506 size_t buf_len = Buffer::Length(args[0]);
3507 char* buf = Buffer::Data(args[0]);
3509 md_len = 8192; // Maximum key size is 8192 bits
3510 md_value = new unsigned char[md_len];
3512 Error err = sign->SignFinal(
3515 len >= 3 && !args[2]->IsNull() ? *passphrase : nullptr,
3518 if (err != kSignOk) {
3522 return sign->CheckThrow(err);
3525 Local<Value> rc = StringBytes::Encode(env->isolate(),
3526 reinterpret_cast<const char*>(md_value),
3530 args.GetReturnValue().Set(rc);
3534 void Verify::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3535 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3537 t->InstanceTemplate()->SetInternalFieldCount(1);
3539 env->SetProtoMethod(t, "init", VerifyInit);
3540 env->SetProtoMethod(t, "update", VerifyUpdate);
3541 env->SetProtoMethod(t, "verify", VerifyFinal);
3543 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
3548 void Verify::New(const FunctionCallbackInfo<Value>& args) {
3549 Environment* env = Environment::GetCurrent(args);
3550 new Verify(env, args.This());
3554 SignBase::Error Verify::VerifyInit(const char* verify_type) {
3555 CHECK_EQ(md_, nullptr);
3556 md_ = EVP_get_digestbyname(verify_type);
3558 return kSignUnknownDigest;
3560 EVP_MD_CTX_init(&mdctx_);
3561 if (!EVP_VerifyInit_ex(&mdctx_, md_, nullptr))
3563 initialised_ = true;
3569 void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
3570 Verify* verify = Unwrap<Verify>(args.Holder());
3572 if (args.Length() == 0 || !args[0]->IsString()) {
3573 return verify->env()->ThrowError("Must give verifytype string as argument");
3576 const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
3577 verify->CheckThrow(verify->VerifyInit(*verify_type));
3581 SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
3583 return kSignNotInitialised;
3585 if (!EVP_VerifyUpdate(&mdctx_, data, len))
3592 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
3593 Environment* env = Environment::GetCurrent(args);
3595 Verify* verify = Unwrap<Verify>(args.Holder());
3597 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3599 // Only copy the data if we have to, because it's a string
3601 if (args[0]->IsString()) {
3602 StringBytes::InlineDecoder decoder;
3603 if (!decoder.Decode(env, args[0].As<String>(), args[1], BINARY))
3605 err = verify->VerifyUpdate(decoder.out(), decoder.size());
3607 char* buf = Buffer::Data(args[0]);
3608 size_t buflen = Buffer::Length(args[0]);
3609 err = verify->VerifyUpdate(buf, buflen);
3612 verify->CheckThrow(err);
3616 SignBase::Error Verify::VerifyFinal(const char* key_pem,
3620 bool* verify_result) {
3622 return kSignNotInitialised;
3624 ClearErrorOnReturn clear_error_on_return;
3625 (void) &clear_error_on_return; // Silence compiler warning.
3627 EVP_PKEY* pkey = nullptr;
3629 X509* x509 = nullptr;
3633 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3637 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3638 // Split this out into a separate function once we have more than one
3639 // consumer of public keys.
3640 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3641 pkey = PEM_read_bio_PUBKEY(bp, nullptr, CryptoPemCallback, nullptr);
3642 if (pkey == nullptr)
3644 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3646 PEM_read_bio_RSAPublicKey(bp, nullptr, CryptoPemCallback, nullptr);
3648 pkey = EVP_PKEY_new();
3650 EVP_PKEY_set1_RSA(pkey, rsa);
3653 if (pkey == nullptr)
3657 x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
3658 if (x509 == nullptr)
3661 pkey = X509_get_pubkey(x509);
3662 if (pkey == nullptr)
3667 r = EVP_VerifyFinal(&mdctx_,
3668 reinterpret_cast<const unsigned char*>(sig),
3673 if (pkey != nullptr)
3674 EVP_PKEY_free(pkey);
3677 if (x509 != nullptr)
3680 EVP_MD_CTX_cleanup(&mdctx_);
3681 initialised_ = false;
3684 return kSignPublicKey;
3686 *verify_result = r == 1;
3691 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
3692 Environment* env = Environment::GetCurrent(args);
3694 Verify* verify = Unwrap<Verify>(args.Holder());
3696 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3697 char* kbuf = Buffer::Data(args[0]);
3698 ssize_t klen = Buffer::Length(args[0]);
3700 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[1]);
3702 // BINARY works for both buffers and binary strings.
3703 enum encoding encoding = BINARY;
3704 if (args.Length() >= 3) {
3705 encoding = ParseEncoding(env->isolate(),
3706 args[2]->ToString(env->isolate()),
3710 ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);
3712 // only copy if we need to, because it's a string.
3714 if (args[1]->IsString()) {
3715 hbuf = new char[hlen];
3716 ssize_t hwritten = StringBytes::Write(env->isolate(),
3721 CHECK_EQ(hwritten, hlen);
3723 hbuf = Buffer::Data(args[1]);
3727 Error err = verify->VerifyFinal(kbuf, klen, hbuf, hlen, &verify_result);
3728 if (args[1]->IsString())
3731 return verify->CheckThrow(err);
3732 args.GetReturnValue().Set(verify_result);
3736 template <PublicKeyCipher::Operation operation,
3737 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3738 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3739 bool PublicKeyCipher::Cipher(const char* key_pem,
3741 const char* passphrase,
3743 const unsigned char* data,
3745 unsigned char** out,
3747 EVP_PKEY* pkey = nullptr;
3748 EVP_PKEY_CTX* ctx = nullptr;
3750 X509* x509 = nullptr;
3753 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3757 // Check if this is a PKCS#8 or RSA public key before trying as X.509 and
3759 if (operation == kPublic &&
3760 strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3761 pkey = PEM_read_bio_PUBKEY(bp, nullptr, nullptr, nullptr);
3762 if (pkey == nullptr)
3764 } else if (operation == kPublic &&
3765 strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3766 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, nullptr, nullptr, nullptr);
3768 pkey = EVP_PKEY_new();
3770 EVP_PKEY_set1_RSA(pkey, rsa);
3773 if (pkey == nullptr)
3775 } else if (operation == kPublic &&
3776 strncmp(key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0) {
3777 x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
3778 if (x509 == nullptr)
3781 pkey = X509_get_pubkey(x509);
3782 if (pkey == nullptr)
3785 pkey = PEM_read_bio_PrivateKey(bp,
3788 const_cast<char*>(passphrase));
3789 if (pkey == nullptr)
3793 ctx = EVP_PKEY_CTX_new(pkey, nullptr);
3796 if (EVP_PKEY_cipher_init(ctx) <= 0)
3798 if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0)
3801 if (EVP_PKEY_cipher(ctx, nullptr, out_len, data, len) <= 0)
3804 *out = new unsigned char[*out_len];
3806 if (EVP_PKEY_cipher(ctx, *out, out_len, data, len) <= 0)
3812 if (pkey != nullptr)
3813 EVP_PKEY_free(pkey);
3817 EVP_PKEY_CTX_free(ctx);
3823 template <PublicKeyCipher::Operation operation,
3824 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3825 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3826 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
3827 Environment* env = Environment::GetCurrent(args);
3829 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3830 char* kbuf = Buffer::Data(args[0]);
3831 ssize_t klen = Buffer::Length(args[0]);
3833 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
3834 char* buf = Buffer::Data(args[1]);
3835 ssize_t len = Buffer::Length(args[1]);
3837 int padding = args[2]->Uint32Value();
3839 String::Utf8Value passphrase(args[3]);
3841 unsigned char* out_value = nullptr;
3844 bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
3847 args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : nullptr,
3849 reinterpret_cast<const unsigned char*>(buf),
3854 if (out_len == 0 || !r) {
3856 out_value = nullptr;
3859 return ThrowCryptoError(env,
3864 args.GetReturnValue().Set(
3865 Buffer::New(env, reinterpret_cast<char*>(out_value), out_len));
3870 void DiffieHellman::Initialize(Environment* env, Handle<Object> target) {
3871 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3873 const PropertyAttribute attributes =
3874 static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
3876 t->InstanceTemplate()->SetInternalFieldCount(1);
3878 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
3879 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
3880 env->SetProtoMethod(t, "getPrime", GetPrime);
3881 env->SetProtoMethod(t, "getGenerator", GetGenerator);
3882 env->SetProtoMethod(t, "getPublicKey", GetPublicKey);
3883 env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey);
3884 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
3885 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
3887 t->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3888 DiffieHellman::VerifyErrorGetter,
3894 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"),
3897 Local<FunctionTemplate> t2 = env->NewFunctionTemplate(DiffieHellmanGroup);
3898 t2->InstanceTemplate()->SetInternalFieldCount(1);
3900 env->SetProtoMethod(t2, "generateKeys", GenerateKeys);
3901 env->SetProtoMethod(t2, "computeSecret", ComputeSecret);
3902 env->SetProtoMethod(t2, "getPrime", GetPrime);
3903 env->SetProtoMethod(t2, "getGenerator", GetGenerator);
3904 env->SetProtoMethod(t2, "getPublicKey", GetPublicKey);
3905 env->SetProtoMethod(t2, "getPrivateKey", GetPrivateKey);
3907 t2->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3908 DiffieHellman::VerifyErrorGetter,
3914 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
3919 bool DiffieHellman::Init(int primeLength, int g) {
3921 DH_generate_parameters_ex(dh, primeLength, g, 0);
3922 bool result = VerifyContext();
3925 initialised_ = true;
3930 bool DiffieHellman::Init(const char* p, int p_len, int g) {
3932 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3934 if (!BN_set_word(dh->g, g))
3936 bool result = VerifyContext();
3939 initialised_ = true;
3944 bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
3946 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3947 dh->g = BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, 0);
3948 bool result = VerifyContext();
3951 initialised_ = true;
3956 void DiffieHellman::DiffieHellmanGroup(
3957 const FunctionCallbackInfo<Value>& args) {
3958 Environment* env = Environment::GetCurrent(args);
3959 DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
3961 if (args.Length() != 1 || !args[0]->IsString()) {
3962 return env->ThrowError("No group name given");
3965 bool initialized = false;
3967 const node::Utf8Value group_name(env->isolate(), args[0]);
3968 for (unsigned int i = 0; i < ARRAY_SIZE(modp_groups); ++i) {
3969 const modp_group* it = modp_groups + i;
3971 if (strcasecmp(*group_name, it->name) != 0)
3974 initialized = diffieHellman->Init(it->prime,
3979 env->ThrowError("Initialization failed");
3983 env->ThrowError("Unknown group");
3987 void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
3988 Environment* env = Environment::GetCurrent(args);
3989 DiffieHellman* diffieHellman =
3990 new DiffieHellman(env, args.This());
3991 bool initialized = false;
3993 if (args.Length() == 2) {
3994 if (args[0]->IsInt32()) {
3995 if (args[1]->IsInt32()) {
3996 initialized = diffieHellman->Init(args[0]->Int32Value(),
3997 args[1]->Int32Value());
4000 if (args[1]->IsInt32()) {
4001 initialized = diffieHellman->Init(Buffer::Data(args[0]),
4002 Buffer::Length(args[0]),
4003 args[1]->Int32Value());
4005 initialized = diffieHellman->Init(Buffer::Data(args[0]),
4006 Buffer::Length(args[0]),
4007 Buffer::Data(args[1]),
4008 Buffer::Length(args[1]));
4014 return env->ThrowError("Initialization failed");
4019 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4020 Environment* env = Environment::GetCurrent(args);
4022 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4024 if (!diffieHellman->initialised_) {
4025 return env->ThrowError("Not initialized");
4028 if (!DH_generate_key(diffieHellman->dh)) {
4029 return env->ThrowError("Key generation failed");
4032 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
4033 char* data = new char[dataSize];
4034 BN_bn2bin(diffieHellman->dh->pub_key,
4035 reinterpret_cast<unsigned char*>(data));
4037 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4042 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
4043 Environment* env = Environment::GetCurrent(args);
4045 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4047 if (!diffieHellman->initialised_) {
4048 return env->ThrowError("Not initialized");
4051 int dataSize = BN_num_bytes(diffieHellman->dh->p);
4052 char* data = new char[dataSize];
4053 BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
4055 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4060 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
4061 Environment* env = Environment::GetCurrent(args);
4063 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4065 if (!diffieHellman->initialised_) {
4066 return env->ThrowError("Not initialized");
4069 int dataSize = BN_num_bytes(diffieHellman->dh->g);
4070 char* data = new char[dataSize];
4071 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
4073 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4078 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
4079 Environment* env = Environment::GetCurrent(args);
4081 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4083 if (!diffieHellman->initialised_) {
4084 return env->ThrowError("Not initialized");
4087 if (diffieHellman->dh->pub_key == nullptr) {
4088 return env->ThrowError("No public key - did you forget to generate one?");
4091 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
4092 char* data = new char[dataSize];
4093 BN_bn2bin(diffieHellman->dh->pub_key,
4094 reinterpret_cast<unsigned char*>(data));
4096 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4101 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4102 Environment* env = Environment::GetCurrent(args);
4104 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4106 if (!diffieHellman->initialised_) {
4107 return env->ThrowError("Not initialized");
4110 if (diffieHellman->dh->priv_key == nullptr) {
4111 return env->ThrowError("No private key - did you forget to generate one?");
4114 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
4115 char* data = new char[dataSize];
4116 BN_bn2bin(diffieHellman->dh->priv_key,
4117 reinterpret_cast<unsigned char*>(data));
4119 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4124 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4125 Environment* env = Environment::GetCurrent(args);
4127 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4129 if (!diffieHellman->initialised_) {
4130 return env->ThrowError("Not initialized");
4133 ClearErrorOnReturn clear_error_on_return;
4134 (void) &clear_error_on_return; // Silence compiler warning.
4135 BIGNUM* key = nullptr;
4137 if (args.Length() == 0) {
4138 return env->ThrowError("First argument must be other party's public key");
4140 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4142 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4143 Buffer::Length(args[0]),
4147 int dataSize = DH_size(diffieHellman->dh);
4148 char* data = new char[dataSize];
4150 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
4158 checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
4163 return env->ThrowError("Invalid key");
4164 } else if (checkResult) {
4165 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
4166 return env->ThrowError("Supplied key is too small");
4167 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
4168 return env->ThrowError("Supplied key is too large");
4170 return env->ThrowError("Invalid key");
4173 return env->ThrowError("Invalid key");
4180 // DH_size returns number of bytes in a prime number
4181 // DH_compute_key returns number of bytes in a remainder of exponent, which
4182 // may have less bytes than a prime number. Therefore add 0-padding to the
4183 // allocated buffer.
4184 if (size != dataSize) {
4185 CHECK(dataSize > size);
4186 memmove(data + dataSize - size, data, size);
4187 memset(data, 0, dataSize - size);
4190 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4195 void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4196 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4197 Environment* env = diffieHellman->env();
4199 if (!diffieHellman->initialised_) {
4200 return env->ThrowError("Not initialized");
4203 if (args.Length() == 0) {
4204 return env->ThrowError("First argument must be public key");
4206 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4207 diffieHellman->dh->pub_key = BN_bin2bn(
4208 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4209 Buffer::Length(args[0]), 0);
4214 void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4215 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4216 Environment* env = diffieHellman->env();
4218 if (!diffieHellman->initialised_) {
4219 return env->ThrowError("Not initialized");
4222 if (args.Length() == 0) {
4223 return env->ThrowError("First argument must be private key");
4225 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4226 diffieHellman->dh->priv_key = BN_bin2bn(
4227 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4228 Buffer::Length(args[0]),
4234 void DiffieHellman::VerifyErrorGetter(Local<String> property,
4235 const PropertyCallbackInfo<Value>& args) {
4236 HandleScope scope(args.GetIsolate());
4238 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4240 if (!diffieHellman->initialised_)
4241 return diffieHellman->env()->ThrowError("Not initialized");
4243 args.GetReturnValue().Set(diffieHellman->verifyError_);
4247 bool DiffieHellman::VerifyContext() {
4249 if (!DH_check(dh, &codes))
4251 verifyError_ = codes;
4256 void ECDH::Initialize(Environment* env, Handle<Object> target) {
4257 HandleScope scope(env->isolate());
4259 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4261 t->InstanceTemplate()->SetInternalFieldCount(1);
4263 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
4264 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
4265 env->SetProtoMethod(t, "getPublicKey", GetPublicKey);
4266 env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey);
4267 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
4268 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
4270 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH"),
4275 void ECDH::New(const FunctionCallbackInfo<Value>& args) {
4276 Environment* env = Environment::GetCurrent(args);
4278 // TODO(indutny): Support raw curves?
4279 CHECK(args[0]->IsString());
4280 node::Utf8Value curve(env->isolate(), args[0]);
4282 int nid = OBJ_sn2nid(*curve);
4283 if (nid == NID_undef)
4284 return env->ThrowTypeError("First argument should be a valid curve name");
4286 EC_KEY* key = EC_KEY_new_by_curve_name(nid);
4288 return env->ThrowError("Failed to create EC_KEY using curve name");
4290 new ECDH(env, args.This(), key);
4294 void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4295 Environment* env = Environment::GetCurrent(args);
4297 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4299 if (!EC_KEY_generate_key(ecdh->key_))
4300 return env->ThrowError("Failed to generate EC_KEY");
4302 ecdh->generated_ = true;
4306 EC_POINT* ECDH::BufferToPoint(char* data, size_t len) {
4310 pub = EC_POINT_new(group_);
4311 if (pub == nullptr) {
4312 env()->ThrowError("Failed to allocate EC_POINT for a public key");
4316 r = EC_POINT_oct2point(
4319 reinterpret_cast<unsigned char*>(data),
4323 env()->ThrowError("Failed to translate Buffer to a EC_POINT");
4335 void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4336 Environment* env = Environment::GetCurrent(args);
4338 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4340 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4342 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0]),
4343 Buffer::Length(args[0]));
4347 // NOTE: field_size is in bits
4348 int field_size = EC_GROUP_get_degree(ecdh->group_);
4349 size_t out_len = (field_size + 7) / 8;
4350 char* out = static_cast<char*>(malloc(out_len));
4351 CHECK_NE(out, nullptr);
4353 int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr);
4357 return env->ThrowError("Failed to compute ECDH key");
4360 args.GetReturnValue().Set(Buffer::Use(env, out, out_len));
4364 void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
4365 Environment* env = Environment::GetCurrent(args);
4368 CHECK_EQ(args.Length(), 1);
4370 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4372 if (!ecdh->generated_)
4373 return env->ThrowError("You should generate ECDH keys first");
4375 const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_);
4377 return env->ThrowError("Failed to get ECDH public key");
4380 point_conversion_form_t form =
4381 static_cast<point_conversion_form_t>(args[0]->Uint32Value());
4383 size = EC_POINT_point2oct(ecdh->group_, pub, form, nullptr, 0, nullptr);
4385 return env->ThrowError("Failed to get public key length");
4387 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4388 CHECK_NE(out, nullptr);
4390 int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr);
4393 return env->ThrowError("Failed to get public key");
4396 args.GetReturnValue().Set(Buffer::Use(env,
4397 reinterpret_cast<char*>(out),
4402 void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4403 Environment* env = Environment::GetCurrent(args);
4405 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4407 if (!ecdh->generated_)
4408 return env->ThrowError("You should generate ECDH keys first");
4410 const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_);
4412 return env->ThrowError("Failed to get ECDH private key");
4414 int size = BN_num_bytes(b);
4415 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4416 CHECK_NE(out, nullptr);
4418 if (size != BN_bn2bin(b, out)) {
4420 return env->ThrowError("Failed to convert ECDH private key to Buffer");
4423 args.GetReturnValue().Set(Buffer::Use(env,
4424 reinterpret_cast<char*>(out),
4429 void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4430 Environment* env = Environment::GetCurrent(args);
4432 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4434 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4436 BIGNUM* priv = BN_bin2bn(
4437 reinterpret_cast<unsigned char*>(Buffer::Data(args[0].As<Object>())),
4438 Buffer::Length(args[0].As<Object>()),
4440 if (priv == nullptr)
4441 return env->ThrowError("Failed to convert Buffer to BN");
4443 if (!EC_KEY_set_private_key(ecdh->key_, priv))
4444 return env->ThrowError("Failed to convert BN to a private key");
4448 void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4449 Environment* env = Environment::GetCurrent(args);
4451 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4453 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4455 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0].As<Object>()),
4456 Buffer::Length(args[0].As<Object>()));
4460 int r = EC_KEY_set_public_key(ecdh->key_, pub);
4463 return env->ThrowError("Failed to convert BN to a private key");
4467 class PBKDF2Request : public AsyncWrap {
4469 PBKDF2Request(Environment* env,
4470 Local<Object> object,
4471 const EVP_MD* digest,
4478 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4486 key_(static_cast<char*>(malloc(keylen))),
4488 if (key() == nullptr)
4489 FatalError("node::PBKDF2Request()", "Out of Memory");
4492 ~PBKDF2Request() override {
4493 persistent().Reset();
4496 uv_work_t* work_req() {
4500 inline const EVP_MD* digest() const {
4504 inline ssize_t passlen() const {
4508 inline char* pass() const {
4512 inline ssize_t saltlen() const {
4516 inline char* salt() const {
4520 inline ssize_t keylen() const {
4524 inline char* key() const {
4528 inline ssize_t iter() const {
4532 inline void release() {
4541 inline int error() const {
4545 inline void set_error(int err) {
4549 uv_work_t work_req_;
4552 const EVP_MD* digest_;
4564 void EIO_PBKDF2(PBKDF2Request* req) {
4565 req->set_error(PKCS5_PBKDF2_HMAC(
4568 reinterpret_cast<unsigned char*>(req->salt()),
4573 reinterpret_cast<unsigned char*>(req->key())));
4574 memset(req->pass(), 0, req->passlen());
4575 memset(req->salt(), 0, req->saltlen());
4579 void EIO_PBKDF2(uv_work_t* work_req) {
4580 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4585 void EIO_PBKDF2After(PBKDF2Request* req, Local<Value> argv[2]) {
4587 argv[0] = Undefined(req->env()->isolate());
4588 argv[1] = Encode(req->env()->isolate(), req->key(), req->keylen(), BUFFER);
4589 memset(req->key(), 0, req->keylen());
4591 argv[0] = Exception::Error(req->env()->pbkdf2_error_string());
4592 argv[1] = Undefined(req->env()->isolate());
4597 void EIO_PBKDF2After(uv_work_t* work_req, int status) {
4598 CHECK_EQ(status, 0);
4599 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4600 Environment* env = req->env();
4601 HandleScope handle_scope(env->isolate());
4602 Context::Scope context_scope(env->context());
4603 Local<Value> argv[2];
4604 EIO_PBKDF2After(req, argv);
4605 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4611 void PBKDF2(const FunctionCallbackInfo<Value>& args) {
4612 Environment* env = Environment::GetCurrent(args);
4614 const EVP_MD* digest = nullptr;
4615 const char* type_error = nullptr;
4616 char* pass = nullptr;
4617 char* salt = nullptr;
4618 ssize_t passlen = -1;
4619 ssize_t saltlen = -1;
4620 ssize_t keylen = -1;
4622 PBKDF2Request* req = nullptr;
4625 if (args.Length() != 5 && args.Length() != 6) {
4626 type_error = "Bad parameter";
4630 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4631 passlen = Buffer::Length(args[0]);
4633 type_error = "Bad password";
4637 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
4639 pass = static_cast<char*>(malloc(passlen));
4640 if (pass == nullptr) {
4641 FatalError("node::PBKDF2()", "Out of Memory");
4643 memcpy(pass, Buffer::Data(args[0]), passlen);
4645 saltlen = Buffer::Length(args[1]);
4647 type_error = "Bad salt";
4651 salt = static_cast<char*>(malloc(saltlen));
4652 if (salt == nullptr) {
4653 FatalError("node::PBKDF2()", "Out of Memory");
4655 memcpy(salt, Buffer::Data(args[1]), saltlen);
4657 if (!args[2]->IsNumber()) {
4658 type_error = "Iterations not a number";
4662 iter = args[2]->Int32Value();
4664 type_error = "Bad iterations";
4668 if (!args[3]->IsNumber()) {
4669 type_error = "Key length not a number";
4673 keylen = args[3]->Int32Value();
4675 type_error = "Bad key length";
4679 if (args[4]->IsString()) {
4680 node::Utf8Value digest_name(env->isolate(), args[4]);
4681 digest = EVP_get_digestbyname(*digest_name);
4682 if (digest == nullptr) {
4683 type_error = "Bad digest name";
4688 if (digest == nullptr) {
4689 digest = EVP_sha1();
4692 obj = Object::New(env->isolate());
4693 req = new PBKDF2Request(env,
4703 if (args[5]->IsFunction()) {
4704 obj->Set(env->ondone_string(), args[5]);
4705 // XXX(trevnorris): This will need to go with the rest of domains.
4706 if (env->in_domain())
4707 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4708 uv_queue_work(env->event_loop(),
4713 env->PrintSyncTrace();
4714 Local<Value> argv[2];
4716 EIO_PBKDF2After(req, argv);
4717 if (argv[0]->IsObject())
4718 env->isolate()->ThrowException(argv[0]);
4720 args.GetReturnValue().Set(argv[1]);
4727 return env->ThrowTypeError(type_error);
4731 // Only instantiate within a valid HandleScope.
4732 class RandomBytesRequest : public AsyncWrap {
4734 RandomBytesRequest(Environment* env, Local<Object> object, size_t size)
4735 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4738 data_(static_cast<char*>(malloc(size))) {
4739 if (data() == nullptr)
4740 FatalError("node::RandomBytesRequest()", "Out of Memory");
4743 ~RandomBytesRequest() override {
4744 persistent().Reset();
4747 uv_work_t* work_req() {
4751 inline size_t size() const {
4755 inline char* data() const {
4759 inline void release() {
4764 inline void return_memory(char** d, size_t* len) {
4771 inline unsigned long error() const {
4775 inline void set_error(unsigned long err) {
4779 uv_work_t work_req_;
4782 unsigned long error_;
4788 void RandomBytesWork(uv_work_t* work_req) {
4789 RandomBytesRequest* req =
4790 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4792 // Ensure that OpenSSL's PRNG is properly seeded.
4795 const int r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data()),
4798 // RAND_bytes() returns 0 on error.
4800 req->set_error(ERR_get_error());
4801 } else if (r == -1) {
4802 req->set_error(static_cast<unsigned long>(-1));
4807 // don't call this function without a valid HandleScope
4808 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
4810 char errmsg[256] = "Operation not supported";
4812 if (req->error() != static_cast<unsigned long>(-1))
4813 ERR_error_string_n(req->error(), errmsg, sizeof errmsg);
4815 argv[0] = Exception::Error(OneByteString(req->env()->isolate(), errmsg));
4816 argv[1] = Null(req->env()->isolate());
4819 char* data = nullptr;
4821 req->return_memory(&data, &size);
4822 argv[0] = Null(req->env()->isolate());
4823 argv[1] = Buffer::Use(req->env()->isolate(), data, size);
4828 void RandomBytesAfter(uv_work_t* work_req, int status) {
4829 CHECK_EQ(status, 0);
4830 RandomBytesRequest* req =
4831 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4832 Environment* env = req->env();
4833 HandleScope handle_scope(env->isolate());
4834 Context::Scope context_scope(env->context());
4835 Local<Value> argv[2];
4836 RandomBytesCheck(req, argv);
4837 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4842 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
4843 Environment* env = Environment::GetCurrent(args);
4845 // maybe allow a buffer to write to? cuts down on object creation
4846 // when generating random data in a loop
4847 if (!args[0]->IsUint32()) {
4848 return env->ThrowTypeError("size must be a number >= 0");
4851 const uint32_t size = args[0]->Uint32Value();
4852 if (size > Buffer::kMaxLength) {
4853 return env->ThrowTypeError("size > Buffer::kMaxLength");
4856 Local<Object> obj = Object::New(env->isolate());
4857 RandomBytesRequest* req = new RandomBytesRequest(env, obj, size);
4859 if (args[1]->IsFunction()) {
4860 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "ondone"), args[1]);
4861 // XXX(trevnorris): This will need to go with the rest of domains.
4862 if (env->in_domain())
4863 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4864 uv_queue_work(env->event_loop(),
4868 args.GetReturnValue().Set(obj);
4870 env->PrintSyncTrace();
4871 Local<Value> argv[2];
4872 RandomBytesWork(req->work_req());
4873 RandomBytesCheck(req, argv);
4876 if (!argv[0]->IsNull())
4877 env->isolate()->ThrowException(argv[0]);
4879 args.GetReturnValue().Set(argv[1]);
4884 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
4885 Environment* env = Environment::GetCurrent(args);
4887 SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
4888 if (ctx == nullptr) {
4889 return env->ThrowError("SSL_CTX_new() failed.");
4892 SSL* ssl = SSL_new(ctx);
4893 if (ssl == nullptr) {
4895 return env->ThrowError("SSL_new() failed.");
4898 Local<Array> arr = Array::New(env->isolate());
4899 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
4901 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
4902 SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
4903 arr->Set(i, OneByteString(args.GetIsolate(), SSL_CIPHER_get_name(cipher)));
4909 args.GetReturnValue().Set(arr);
4913 class CipherPushContext {
4915 explicit CipherPushContext(Environment* env)
4916 : arr(Array::New(env->isolate())),
4920 inline Environment* env() const { return env_; }
4929 template <class TypeName>
4930 static void array_push_back(const TypeName* md,
4934 CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
4935 ctx->arr->Set(ctx->arr->Length(), OneByteString(ctx->env()->isolate(), from));
4939 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
4940 Environment* env = Environment::GetCurrent(args);
4941 CipherPushContext ctx(env);
4942 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
4943 args.GetReturnValue().Set(ctx.arr);
4947 void GetHashes(const FunctionCallbackInfo<Value>& args) {
4948 Environment* env = Environment::GetCurrent(args);
4949 CipherPushContext ctx(env);
4950 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
4951 args.GetReturnValue().Set(ctx.arr);
4955 void GetCurves(const FunctionCallbackInfo<Value>& args) {
4956 Environment* env = Environment::GetCurrent(args);
4957 const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
4958 Local<Array> arr = Array::New(env->isolate(), num_curves);
4959 EC_builtin_curve* curves;
4963 alloc_size = sizeof(*curves) * num_curves;
4964 curves = static_cast<EC_builtin_curve*>(malloc(alloc_size));
4966 CHECK_NE(curves, nullptr);
4968 if (EC_get_builtin_curves(curves, num_curves)) {
4969 for (size_t i = 0; i < num_curves; i++) {
4970 arr->Set(i, OneByteString(env->isolate(), OBJ_nid2sn(curves[i].nid)));
4977 args.GetReturnValue().Set(arr);
4981 void Certificate::Initialize(Environment* env, Handle<Object> target) {
4982 HandleScope scope(env->isolate());
4984 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4986 t->InstanceTemplate()->SetInternalFieldCount(1);
4988 env->SetProtoMethod(t, "verifySpkac", VerifySpkac);
4989 env->SetProtoMethod(t, "exportPublicKey", ExportPublicKey);
4990 env->SetProtoMethod(t, "exportChallenge", ExportChallenge);
4992 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Certificate"),
4997 void Certificate::New(const FunctionCallbackInfo<Value>& args) {
4998 Environment* env = Environment::GetCurrent(args);
4999 new Certificate(env, args.This());
5003 bool Certificate::VerifySpkac(const char* data, unsigned int len) {
5005 EVP_PKEY* pkey = nullptr;
5006 NETSCAPE_SPKI* spki = nullptr;
5008 spki = NETSCAPE_SPKI_b64_decode(data, len);
5009 if (spki == nullptr)
5012 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
5013 if (pkey == nullptr)
5016 i = NETSCAPE_SPKI_verify(spki, pkey) > 0;
5019 if (pkey != nullptr)
5020 EVP_PKEY_free(pkey);
5022 if (spki != nullptr)
5023 NETSCAPE_SPKI_free(spki);
5029 void Certificate::VerifySpkac(const FunctionCallbackInfo<Value>& args) {
5030 Certificate* certificate = Unwrap<Certificate>(args.Holder());
5031 Environment* env = certificate->env();
5034 if (args.Length() < 1)
5035 return env->ThrowTypeError("Missing argument");
5037 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
5039 size_t length = Buffer::Length(args[0]);
5041 return args.GetReturnValue().Set(i);
5043 char* data = Buffer::Data(args[0]);
5044 CHECK_NE(data, nullptr);
5046 i = certificate->VerifySpkac(data, length);
5048 args.GetReturnValue().Set(i);
5052 const char* Certificate::ExportPublicKey(const char* data, int len) {
5053 char* buf = nullptr;
5054 EVP_PKEY* pkey = nullptr;
5055 NETSCAPE_SPKI* spki = nullptr;
5057 BIO* bio = BIO_new(BIO_s_mem());
5061 spki = NETSCAPE_SPKI_b64_decode(data, len);
5062 if (spki == nullptr)
5065 pkey = NETSCAPE_SPKI_get_pubkey(spki);
5066 if (pkey == nullptr)
5069 if (PEM_write_bio_PUBKEY(bio, pkey) <= 0)
5072 BIO_write(bio, "\0", 1);
5074 BIO_get_mem_ptr(bio, &ptr);
5076 buf = new char[ptr->length];
5077 memcpy(buf, ptr->data, ptr->length);
5080 if (pkey != nullptr)
5081 EVP_PKEY_free(pkey);
5083 if (spki != nullptr)
5084 NETSCAPE_SPKI_free(spki);
5093 void Certificate::ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
5094 Environment* env = Environment::GetCurrent(args);
5096 Certificate* certificate = Unwrap<Certificate>(args.Holder());
5098 if (args.Length() < 1)
5099 return env->ThrowTypeError("Missing argument");
5101 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
5103 size_t length = Buffer::Length(args[0]);
5105 return args.GetReturnValue().SetEmptyString();
5107 char* data = Buffer::Data(args[0]);
5108 CHECK_NE(data, nullptr);
5110 const char* pkey = certificate->ExportPublicKey(data, length);
5111 if (pkey == nullptr)
5112 return args.GetReturnValue().SetEmptyString();
5114 Local<Value> out = Encode(env->isolate(), pkey, strlen(pkey), BUFFER);
5118 args.GetReturnValue().Set(out);
5122 const char* Certificate::ExportChallenge(const char* data, int len) {
5123 NETSCAPE_SPKI* sp = nullptr;
5125 sp = NETSCAPE_SPKI_b64_decode(data, len);
5129 const char* buf = nullptr;
5130 buf = reinterpret_cast<const char*>(ASN1_STRING_data(sp->spkac->challenge));
5136 void Certificate::ExportChallenge(const FunctionCallbackInfo<Value>& args) {
5137 Environment* env = Environment::GetCurrent(args);
5139 Certificate* crt = Unwrap<Certificate>(args.Holder());
5141 if (args.Length() < 1)
5142 return env->ThrowTypeError("Missing argument");
5144 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
5146 size_t len = Buffer::Length(args[0]);
5148 return args.GetReturnValue().SetEmptyString();
5150 char* data = Buffer::Data(args[0]);
5151 CHECK_NE(data, nullptr);
5153 const char* cert = crt->ExportChallenge(data, len);
5154 if (cert == nullptr)
5155 return args.GetReturnValue().SetEmptyString();
5157 Local<Value> outString = Encode(env->isolate(), cert, strlen(cert), BUFFER);
5161 args.GetReturnValue().Set(outString);
5165 void InitCryptoOnce() {
5167 OpenSSL_add_all_algorithms();
5168 SSL_load_error_strings();
5171 CRYPTO_set_locking_callback(crypto_lock_cb);
5172 CRYPTO_THREADID_set_callback(crypto_threadid_cb);
5175 if (!FIPS_mode_set(1)) {
5176 int err = ERR_get_error();
5177 fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(err, NULL));
5180 #endif // OPENSSL_FIPS
5183 // Turn off compression. Saves memory and protects against CRIME attacks.
5184 #if !defined(OPENSSL_NO_COMP)
5185 #if OPENSSL_VERSION_NUMBER < 0x00908000L
5186 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_method();
5188 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
5190 sk_SSL_COMP_zero(comp_methods);
5191 CHECK_EQ(sk_SSL_COMP_num(comp_methods), 0);
5194 #ifndef OPENSSL_NO_ENGINE
5195 ERR_load_ENGINE_strings();
5196 ENGINE_load_builtin_engines();
5197 #endif // !OPENSSL_NO_ENGINE
5201 #ifndef OPENSSL_NO_ENGINE
5202 void SetEngine(const FunctionCallbackInfo<Value>& args) {
5203 Environment* env = Environment::GetCurrent(args);
5204 CHECK(args.Length() >= 2 && args[0]->IsString());
5205 unsigned int flags = args[1]->Uint32Value();
5207 ClearErrorOnReturn clear_error_on_return;
5208 (void) &clear_error_on_return; // Silence compiler warning.
5210 const node::Utf8Value engine_id(env->isolate(), args[0]);
5211 ENGINE* engine = ENGINE_by_id(*engine_id);
5213 // Engine not found, try loading dynamically
5214 if (engine == nullptr) {
5215 engine = ENGINE_by_id("dynamic");
5216 if (engine != nullptr) {
5217 if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", *engine_id, 0) ||
5218 !ENGINE_ctrl_cmd_string(engine, "LOAD", nullptr, 0)) {
5219 ENGINE_free(engine);
5225 if (engine == nullptr) {
5226 int err = ERR_get_error();
5229 snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id);
5230 return env->ThrowError(tmp);
5232 return ThrowCryptoError(env, err);
5236 int r = ENGINE_set_default(engine, flags);
5237 ENGINE_free(engine);
5239 return ThrowCryptoError(env, ERR_get_error());
5241 #endif // !OPENSSL_NO_ENGINE
5244 // FIXME(bnoordhuis) Handle global init correctly.
5245 void InitCrypto(Handle<Object> target,
5246 Handle<Value> unused,
5247 Handle<Context> context,
5249 static uv_once_t init_once = UV_ONCE_INIT;
5250 uv_once(&init_once, InitCryptoOnce);
5252 Environment* env = Environment::GetCurrent(context);
5253 SecureContext::Initialize(env, target);
5254 Connection::Initialize(env, target);
5255 CipherBase::Initialize(env, target);
5256 DiffieHellman::Initialize(env, target);
5257 ECDH::Initialize(env, target);
5258 Hmac::Initialize(env, target);
5259 Hash::Initialize(env, target);
5260 Sign::Initialize(env, target);
5261 Verify::Initialize(env, target);
5262 Certificate::Initialize(env, target);
5264 #ifndef OPENSSL_NO_ENGINE
5265 env->SetMethod(target, "setEngine", SetEngine);
5266 #endif // !OPENSSL_NO_ENGINE
5267 env->SetMethod(target, "PBKDF2", PBKDF2);
5268 env->SetMethod(target, "randomBytes", RandomBytes);
5269 env->SetMethod(target, "getSSLCiphers", GetSSLCiphers);
5270 env->SetMethod(target, "getCiphers", GetCiphers);
5271 env->SetMethod(target, "getHashes", GetHashes);
5272 env->SetMethod(target, "getCurves", GetCurves);
5273 env->SetMethod(target, "publicEncrypt",
5274 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
5275 EVP_PKEY_encrypt_init,
5277 env->SetMethod(target, "privateDecrypt",
5278 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
5279 EVP_PKEY_decrypt_init,
5281 env->SetMethod(target, "privateEncrypt",
5282 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
5285 env->SetMethod(target, "publicDecrypt",
5286 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
5287 EVP_PKEY_verify_recover_init,
5288 EVP_PKEY_verify_recover>);
5291 } // namespace crypto
5294 NODE_MODULE_CONTEXT_AWARE_BUILTIN(crypto, node::crypto::InitCrypto)