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" // TLSCallbacks
8 #include "async-wrap.h"
9 #include "async-wrap-inl.h"
12 #include "string_bytes.h"
22 #define strcasecmp _stricmp
25 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
26 #define OPENSSL_CONST const
31 #define THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(val) \
33 if (!Buffer::HasInstance(val) && !val->IsString()) { \
34 return env->ThrowTypeError("Not a string or buffer"); \
38 #define THROW_AND_RETURN_IF_NOT_BUFFER(val) \
40 if (!Buffer::HasInstance(val)) { \
41 return env->ThrowTypeError("Not a buffer"); \
45 static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----";
46 static const int PUBLIC_KEY_PFX_LEN = sizeof(PUBLIC_KEY_PFX) - 1;
47 static const char PUBRSA_KEY_PFX[] = "-----BEGIN RSA PUBLIC KEY-----";
48 static const int PUBRSA_KEY_PFX_LEN = sizeof(PUBRSA_KEY_PFX) - 1;
49 static const char CERTIFICATE_PFX[] = "-----BEGIN CERTIFICATE-----";
50 static const int CERTIFICATE_PFX_LEN = sizeof(CERTIFICATE_PFX) - 1;
52 static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
53 | ASN1_STRFLGS_UTF8_CONVERT
54 | XN_FLAG_SEP_MULTILINE
63 using v8::EscapableHandleScope;
67 using v8::FunctionCallbackInfo;
68 using v8::FunctionTemplate;
70 using v8::HandleScope;
77 using v8::PropertyAttribute;
78 using v8::PropertyCallbackInfo;
84 // Forcibly clear OpenSSL's error stack on return. This stops stale errors
85 // from popping up later in the lifecycle of crypto operations where they
86 // would cause spurious failures. It's a rather blunt method, though.
87 // ERR_clear_error() isn't necessarily cheap either.
88 struct ClearErrorOnReturn {
89 ~ClearErrorOnReturn() { ERR_clear_error(); }
92 static uv_rwlock_t* locks;
94 const char* const root_certs[] = {
95 #include "node_root_certs.h" // NOLINT(build/include_order)
98 X509_STORE* root_cert_store;
100 // Just to generate static methods
101 template class SSLWrap<TLSCallbacks>;
102 template void SSLWrap<TLSCallbacks>::AddMethods(Environment* env,
103 Handle<FunctionTemplate> t);
104 template void SSLWrap<TLSCallbacks>::InitNPN(SecureContext* sc);
105 template SSL_SESSION* SSLWrap<TLSCallbacks>::GetSessionCallback(
110 template int SSLWrap<TLSCallbacks>::NewSessionCallback(SSL* s,
112 template void SSLWrap<TLSCallbacks>::OnClientHello(
114 const ClientHelloParser::ClientHello& hello);
116 #ifdef OPENSSL_NPN_NEGOTIATED
117 template int SSLWrap<TLSCallbacks>::AdvertiseNextProtoCallback(
119 const unsigned char** data,
122 template int SSLWrap<TLSCallbacks>::SelectNextProtoCallback(
125 unsigned char* outlen,
126 const unsigned char* in,
130 template int SSLWrap<TLSCallbacks>::TLSExtStatusCallback(SSL* s, void* arg);
133 static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
134 static_assert(sizeof(uv_thread_t) <= sizeof(void*), // NOLINT(runtime/sizeof)
135 "uv_thread_t does not fit in a pointer");
136 CRYPTO_THREADID_set_pointer(tid, reinterpret_cast<void*>(uv_thread_self()));
140 static void crypto_lock_init(void) {
143 n = CRYPTO_num_locks();
144 locks = new uv_rwlock_t[n];
146 for (i = 0; i < n; i++)
147 if (uv_rwlock_init(locks + i))
152 static void crypto_lock_cb(int mode, int n, const char* file, int line) {
153 CHECK((mode & CRYPTO_LOCK) || (mode & CRYPTO_UNLOCK));
154 CHECK((mode & CRYPTO_READ) || (mode & CRYPTO_WRITE));
156 if (mode & CRYPTO_LOCK) {
157 if (mode & CRYPTO_READ)
158 uv_rwlock_rdlock(locks + n);
160 uv_rwlock_wrlock(locks + n);
162 if (mode & CRYPTO_READ)
163 uv_rwlock_rdunlock(locks + n);
165 uv_rwlock_wrunlock(locks + n);
170 static int CryptoPemCallback(char *buf, int size, int rwflag, void *u) {
172 size_t buflen = static_cast<size_t>(size);
173 size_t len = strlen(static_cast<const char*>(u));
174 len = len > buflen ? buflen : len;
183 void ThrowCryptoError(Environment* env,
185 const char* default_message = nullptr) {
186 HandleScope scope(env->isolate());
187 if (err != 0 || default_message == nullptr) {
188 char errmsg[128] = { 0 };
189 ERR_error_string_n(err, errmsg, sizeof(errmsg));
190 env->ThrowError(errmsg);
192 env->ThrowError(default_message);
197 // Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.
198 // The entropy pool starts out empty and needs to fill up before the PRNG
199 // can be used securely. Once the pool is filled, it never dries up again;
200 // its contents is stirred and reused when necessary.
202 // OpenSSL normally fills the pool automatically but not when someone starts
203 // generating random numbers before the pool is full: in that case OpenSSL
204 // keeps lowering the entropy estimate to thwart attackers trying to guess
205 // the initial state of the PRNG.
207 // When that happens, we will have to wait until enough entropy is available.
208 // That should normally never take longer than a few milliseconds.
210 // OpenSSL draws from /dev/random and /dev/urandom. While /dev/random may
211 // block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't
212 // block under normal circumstances.
214 // The only time when /dev/urandom may conceivably block is right after boot,
215 // when the whole system is still low on entropy. That's not something we can
216 // do anything about.
217 inline void CheckEntropy() {
219 int status = RAND_status();
220 CHECK_GE(status, 0); // Cannot fail.
224 // Give up, RAND_poll() not supported.
225 if (RAND_poll() == 0)
231 bool EntropySource(unsigned char* buffer, size_t length) {
232 // Ensure that OpenSSL's PRNG is properly seeded.
234 // RAND_bytes() can return 0 to indicate that the entropy data is not truly
235 // random. That's okay, it's still better than V8's stock source of entropy,
236 // which is /dev/urandom on UNIX platforms and the current time on Windows.
237 return RAND_bytes(buffer, length) != -1;
241 void SecureContext::Initialize(Environment* env, Handle<Object> target) {
242 Local<FunctionTemplate> t = env->NewFunctionTemplate(SecureContext::New);
243 t->InstanceTemplate()->SetInternalFieldCount(1);
244 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"));
246 env->SetProtoMethod(t, "init", SecureContext::Init);
247 env->SetProtoMethod(t, "setKey", SecureContext::SetKey);
248 env->SetProtoMethod(t, "setCert", SecureContext::SetCert);
249 env->SetProtoMethod(t, "addCACert", SecureContext::AddCACert);
250 env->SetProtoMethod(t, "addCRL", SecureContext::AddCRL);
251 env->SetProtoMethod(t, "addRootCerts", SecureContext::AddRootCerts);
252 env->SetProtoMethod(t, "setCiphers", SecureContext::SetCiphers);
253 env->SetProtoMethod(t, "setECDHCurve", SecureContext::SetECDHCurve);
254 env->SetProtoMethod(t, "setDHParam", SecureContext::SetDHParam);
255 env->SetProtoMethod(t, "setOptions", SecureContext::SetOptions);
256 env->SetProtoMethod(t, "setSessionIdContext",
257 SecureContext::SetSessionIdContext);
258 env->SetProtoMethod(t, "setSessionTimeout",
259 SecureContext::SetSessionTimeout);
260 env->SetProtoMethod(t, "close", SecureContext::Close);
261 env->SetProtoMethod(t, "loadPKCS12", SecureContext::LoadPKCS12);
262 env->SetProtoMethod(t, "getTicketKeys", SecureContext::GetTicketKeys);
263 env->SetProtoMethod(t, "setTicketKeys", SecureContext::SetTicketKeys);
264 env->SetProtoMethod(t, "getCertificate", SecureContext::GetCertificate<true>);
265 env->SetProtoMethod(t, "getIssuer", SecureContext::GetCertificate<false>);
268 t->PrototypeTemplate(),
272 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"),
274 env->set_secure_context_constructor_template(t);
278 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
279 Environment* env = Environment::GetCurrent(args);
280 new SecureContext(env, args.This());
284 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
285 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
286 Environment* env = sc->env();
288 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
290 if (args.Length() == 1 && args[0]->IsString()) {
291 const node::Utf8Value sslmethod(env->isolate(), args[0]);
293 // Note that SSLv2 and SSLv3 are disallowed but SSLv2_method and friends
294 // are still accepted. They are OpenSSL's way of saying that all known
295 // protocols are supported unless explicitly disabled (which we do below
296 // for SSLv2 and SSLv3.)
297 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
298 return env->ThrowError("SSLv2 methods disabled");
299 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
300 return env->ThrowError("SSLv2 methods disabled");
301 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
302 return env->ThrowError("SSLv2 methods disabled");
303 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
304 return env->ThrowError("SSLv3 methods disabled");
305 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
306 return env->ThrowError("SSLv3 methods disabled");
307 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
308 return env->ThrowError("SSLv3 methods disabled");
309 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
310 method = SSLv23_method();
311 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
312 method = SSLv23_server_method();
313 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
314 method = SSLv23_client_method();
315 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
316 method = TLSv1_method();
317 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
318 method = TLSv1_server_method();
319 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
320 method = TLSv1_client_method();
321 } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
322 method = TLSv1_1_method();
323 } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
324 method = TLSv1_1_server_method();
325 } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
326 method = TLSv1_1_client_method();
327 } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
328 method = TLSv1_2_method();
329 } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
330 method = TLSv1_2_server_method();
331 } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
332 method = TLSv1_2_client_method();
334 return env->ThrowError("Unknown method");
338 sc->ctx_ = SSL_CTX_new(method);
340 // Disable SSLv2 in the case when method == SSLv23_method() and the
341 // cipher list contains SSLv2 ciphers (not the default, should be rare.)
342 // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
343 // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
344 SSL_CTX_set_options(sc->ctx_, SSL_OP_NO_SSLv2);
345 SSL_CTX_set_options(sc->ctx_, SSL_OP_NO_SSLv3);
347 // SSL session cache configuration
348 SSL_CTX_set_session_cache_mode(sc->ctx_,
349 SSL_SESS_CACHE_SERVER |
350 SSL_SESS_CACHE_NO_INTERNAL |
351 SSL_SESS_CACHE_NO_AUTO_CLEAR);
352 SSL_CTX_sess_set_get_cb(sc->ctx_, SSLWrap<Connection>::GetSessionCallback);
353 SSL_CTX_sess_set_new_cb(sc->ctx_, SSLWrap<Connection>::NewSessionCallback);
355 sc->ca_store_ = nullptr;
359 // Takes a string or buffer and loads it into a BIO.
360 // Caller responsible for BIO_free_all-ing the returned object.
361 static BIO* LoadBIO(Environment* env, Handle<Value> v) {
362 BIO* bio = NodeBIO::New();
366 HandleScope scope(env->isolate());
371 const node::Utf8Value s(env->isolate(), v);
372 r = BIO_write(bio, *s, s.length());
373 } else if (Buffer::HasInstance(v)) {
374 char* buffer_data = Buffer::Data(v);
375 size_t buffer_length = Buffer::Length(v);
376 r = BIO_write(bio, buffer_data, buffer_length);
388 // Takes a string or buffer and loads it into an X509
389 // Caller responsible for X509_free-ing the returned object.
390 static X509* LoadX509(Environment* env, Handle<Value> v) {
391 HandleScope scope(env->isolate());
393 BIO *bio = LoadBIO(env, v);
397 X509 * x509 = PEM_read_bio_X509(bio, nullptr, CryptoPemCallback, nullptr);
408 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
409 Environment* env = Environment::GetCurrent(args);
411 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
413 unsigned int len = args.Length();
414 if (len != 1 && len != 2) {
415 return env->ThrowTypeError("Bad parameter");
417 if (len == 2 && !args[1]->IsString()) {
418 return env->ThrowTypeError("Bad parameter");
421 BIO *bio = LoadBIO(env, args[0]);
425 node::Utf8Value passphrase(env->isolate(), args[1]);
427 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio,
430 len == 1 ? nullptr : *passphrase);
434 unsigned long err = ERR_get_error();
436 return env->ThrowError("PEM_read_bio_PrivateKey");
438 return ThrowCryptoError(env, err);
441 int rv = SSL_CTX_use_PrivateKey(sc->ctx_, key);
446 unsigned long err = ERR_get_error();
448 return env->ThrowError("SSL_CTX_use_PrivateKey");
449 return ThrowCryptoError(env, err);
454 int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) {
457 X509_STORE* store = SSL_CTX_get_cert_store(ctx);
458 X509_STORE_CTX store_ctx;
460 ret = X509_STORE_CTX_init(&store_ctx, store, nullptr, nullptr);
464 ret = X509_STORE_CTX_get1_issuer(issuer, &store_ctx, cert);
465 X509_STORE_CTX_cleanup(&store_ctx);
472 // Read a file that contains our certificate in "PEM" format,
473 // possibly followed by a sequence of CA certificates that should be
474 // sent to the peer in the Certificate message.
476 // Taken from OpenSSL - editted for style.
477 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
484 x = PEM_read_bio_X509_AUX(in, nullptr, CryptoPemCallback, nullptr);
487 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
491 ret = SSL_CTX_use_certificate(ctx, x);
494 // If we could set up our certificate, now proceed to
495 // the CA certificates.
500 if (ctx->extra_certs != nullptr) {
501 sk_X509_pop_free(ctx->extra_certs, X509_free);
502 ctx->extra_certs = nullptr;
505 while ((ca = PEM_read_bio_X509(in, nullptr, CryptoPemCallback, nullptr))) {
506 r = SSL_CTX_add_extra_chain_cert(ctx, ca);
513 // Note that we must not free r if it was successfully
514 // added to the chain (while we must free the main
515 // certificate, since its reference count is increased
516 // by SSL_CTX_use_certificate).
519 if (*issuer != nullptr || X509_check_issued(ca, x) != X509_V_OK)
524 // When the while loop ends, it's usually just EOF.
525 err = ERR_peek_last_error();
526 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
527 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
535 // Try getting issuer from a cert store
537 if (*issuer == nullptr) {
538 ret = SSL_CTX_get_issuer(ctx, x, issuer);
539 ret = ret < 0 ? 0 : 1;
540 // NOTE: get_cert_store doesn't increment reference count,
541 // no need to free `store`
543 // Increment issuer reference count
544 CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
555 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
556 Environment* env = Environment::GetCurrent(args);
558 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
560 if (args.Length() != 1) {
561 return env->ThrowTypeError("Bad parameter");
564 BIO* bio = LoadBIO(env, args[0]);
568 int rv = SSL_CTX_use_certificate_chain(sc->ctx_,
576 unsigned long err = ERR_get_error();
578 return env->ThrowError("SSL_CTX_use_certificate_chain");
580 return ThrowCryptoError(env, err);
585 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
586 bool newCAStore = false;
587 Environment* env = Environment::GetCurrent(args);
589 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
591 if (args.Length() != 1) {
592 return env->ThrowTypeError("Bad parameter");
595 if (!sc->ca_store_) {
596 sc->ca_store_ = X509_STORE_new();
600 X509* x509 = LoadX509(env, args[0]);
604 X509_STORE_add_cert(sc->ca_store_, x509);
605 SSL_CTX_add_client_CA(sc->ctx_, x509);
610 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
615 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
616 Environment* env = Environment::GetCurrent(args);
618 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
620 if (args.Length() != 1) {
621 return env->ThrowTypeError("Bad parameter");
624 ClearErrorOnReturn clear_error_on_return;
625 (void) &clear_error_on_return; // Silence compiler warning.
627 BIO *bio = LoadBIO(env, args[0]);
632 PEM_read_bio_X509_CRL(bio, nullptr, CryptoPemCallback, nullptr);
634 if (x509 == nullptr) {
639 X509_STORE_add_crl(sc->ca_store_, x509);
640 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
641 X509_V_FLAG_CRL_CHECK_ALL);
648 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
649 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
651 CHECK_EQ(sc->ca_store_, nullptr);
653 if (!root_cert_store) {
654 root_cert_store = X509_STORE_new();
656 for (size_t i = 0; i < ARRAY_SIZE(root_certs); i++) {
657 BIO* bp = NodeBIO::New();
659 if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
664 X509 *x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
666 if (x509 == nullptr) {
671 X509_STORE_add_cert(root_cert_store, x509);
678 sc->ca_store_ = root_cert_store;
679 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
683 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
684 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
686 if (args.Length() != 1 || !args[0]->IsString()) {
687 return sc->env()->ThrowTypeError("Bad parameter");
690 const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
691 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
695 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
696 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
697 Environment* env = sc->env();
699 if (args.Length() != 1 || !args[0]->IsString())
700 return env->ThrowTypeError("First argument should be a string");
702 node::Utf8Value curve(env->isolate(), args[0]);
704 int nid = OBJ_sn2nid(*curve);
706 if (nid == NID_undef)
707 return env->ThrowTypeError("First argument should be a valid curve name");
709 EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
712 return env->ThrowTypeError("First argument should be a valid curve name");
714 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
715 SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
721 void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
722 SecureContext* sc = Unwrap<SecureContext>(args.This());
723 Environment* env = sc->env();
725 // Auto DH is not supported in openssl 1.0.1, so dhparam needs
726 // to be specifed explicitly
727 if (args.Length() != 1)
728 return env->ThrowTypeError("Bad parameter");
730 // Invalid dhparam is silently discarded and DHE is no longer used.
731 BIO* bio = LoadBIO(env, args[0]);
735 DH* dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
741 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_DH_USE);
742 int r = SSL_CTX_set_tmp_dh(sc->ctx_, dh);
746 return env->ThrowTypeError("Error setting temp DH parameter");
750 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
751 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
753 if (args.Length() != 1 || !args[0]->IntegerValue()) {
754 return sc->env()->ThrowTypeError("Bad parameter");
757 SSL_CTX_set_options(sc->ctx_, static_cast<long>(args[0]->IntegerValue()));
761 void SecureContext::SetSessionIdContext(
762 const FunctionCallbackInfo<Value>& args) {
763 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
765 if (args.Length() != 1 || !args[0]->IsString()) {
766 return sc->env()->ThrowTypeError("Bad parameter");
769 const node::Utf8Value sessionIdContext(args.GetIsolate(), args[0]);
770 const unsigned char* sid_ctx =
771 reinterpret_cast<const unsigned char*>(*sessionIdContext);
772 unsigned int sid_ctx_len = sessionIdContext.length();
774 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
780 Local<String> message;
782 bio = BIO_new(BIO_s_mem());
783 if (bio == nullptr) {
784 message = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
785 "SSL_CTX_set_session_id_context error");
787 ERR_print_errors(bio);
788 BIO_get_mem_ptr(bio, &mem);
789 message = OneByteString(args.GetIsolate(), mem->data, mem->length);
793 args.GetIsolate()->ThrowException(Exception::TypeError(message));
797 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
798 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
800 if (args.Length() != 1 || !args[0]->IsInt32()) {
801 return sc->env()->ThrowTypeError("Bad parameter");
804 int32_t sessionTimeout = args[0]->Int32Value();
805 SSL_CTX_set_timeout(sc->ctx_, sessionTimeout);
809 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
810 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
815 // Takes .pfx or .p12 and password in string or buffer format
816 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
817 Environment* env = Environment::GetCurrent(args);
820 PKCS12* p12 = nullptr;
821 EVP_PKEY* pkey = nullptr;
822 X509* cert = nullptr;
823 STACK_OF(X509)* extraCerts = nullptr;
824 char* pass = nullptr;
827 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
829 if (args.Length() < 1) {
830 return env->ThrowTypeError("Bad parameter");
833 in = LoadBIO(env, args[0]);
835 return env->ThrowError("Unable to load BIO");
838 if (args.Length() >= 2) {
839 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
840 size_t passlen = Buffer::Length(args[1]);
841 pass = new char[passlen + 1];
842 memcpy(pass, Buffer::Data(args[1]), passlen);
843 pass[passlen] = '\0';
846 if (d2i_PKCS12_bio(in, &p12) &&
847 PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
848 SSL_CTX_use_certificate(sc->ctx_, cert) &&
849 SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) {
851 while (X509* x509 = sk_X509_pop(extraCerts)) {
852 if (!sc->ca_store_) {
853 sc->ca_store_ = X509_STORE_new();
854 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
857 X509_STORE_add_cert(sc->ca_store_, x509);
858 SSL_CTX_add_client_CA(sc->ctx_, x509);
864 sk_X509_free(extraCerts);
874 unsigned long err = ERR_get_error();
875 const char* str = ERR_reason_error_string(err);
876 return env->ThrowError(str);
881 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
882 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
884 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
886 Local<Object> buff = Buffer::New(wrap->env(), 48);
887 if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_,
889 Buffer::Length(buff)) != 1) {
890 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
893 args.GetReturnValue().Set(buff);
894 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
898 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
899 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
900 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
902 if (args.Length() < 1 ||
903 !Buffer::HasInstance(args[0]) ||
904 Buffer::Length(args[0]) != 48) {
905 return wrap->env()->ThrowTypeError("Bad argument");
908 if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_,
909 Buffer::Data(args[0]),
910 Buffer::Length(args[0])) != 1) {
911 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
914 args.GetReturnValue().Set(true);
915 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
919 void SecureContext::CtxGetter(Local<String> property,
920 const PropertyCallbackInfo<Value>& info) {
921 HandleScope scope(info.GetIsolate());
923 SSL_CTX* ctx = Unwrap<SecureContext>(info.Holder())->ctx_;
924 Local<External> ext = External::New(info.GetIsolate(), ctx);
925 info.GetReturnValue().Set(ext);
929 template <bool primary>
930 void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
931 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
932 Environment* env = wrap->env();
938 cert = wrap->issuer_;
940 return args.GetReturnValue().Set(Null(env->isolate()));
942 int size = i2d_X509(cert, nullptr);
943 Local<Object> buff = Buffer::New(env, size);
944 unsigned char* serialized = reinterpret_cast<unsigned char*>(
946 i2d_X509(cert, &serialized);
948 args.GetReturnValue().Set(buff);
952 template <class Base>
953 void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
954 HandleScope scope(env->isolate());
956 env->SetProtoMethod(t, "getPeerCertificate", GetPeerCertificate);
957 env->SetProtoMethod(t, "getSession", GetSession);
958 env->SetProtoMethod(t, "setSession", SetSession);
959 env->SetProtoMethod(t, "loadSession", LoadSession);
960 env->SetProtoMethod(t, "isSessionReused", IsSessionReused);
961 env->SetProtoMethod(t, "isInitFinished", IsInitFinished);
962 env->SetProtoMethod(t, "verifyError", VerifyError);
963 env->SetProtoMethod(t, "getCurrentCipher", GetCurrentCipher);
964 env->SetProtoMethod(t, "endParser", EndParser);
965 env->SetProtoMethod(t, "renegotiate", Renegotiate);
966 env->SetProtoMethod(t, "shutdown", Shutdown);
967 env->SetProtoMethod(t, "getTLSTicket", GetTLSTicket);
968 env->SetProtoMethod(t, "newSessionDone", NewSessionDone);
969 env->SetProtoMethod(t, "setOCSPResponse", SetOCSPResponse);
970 env->SetProtoMethod(t, "requestOCSP", RequestOCSP);
972 #ifdef SSL_set_max_send_fragment
973 env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment);
974 #endif // SSL_set_max_send_fragment
976 #ifdef OPENSSL_NPN_NEGOTIATED
977 env->SetProtoMethod(t, "getNegotiatedProtocol", GetNegotiatedProto);
978 #endif // OPENSSL_NPN_NEGOTIATED
980 #ifdef OPENSSL_NPN_NEGOTIATED
981 env->SetProtoMethod(t, "setNPNProtocols", SetNPNProtocols);
985 t->PrototypeTemplate(),
991 template <class Base>
992 void SSLWrap<Base>::InitNPN(SecureContext* sc) {
993 #ifdef OPENSSL_NPN_NEGOTIATED
994 // Server should advertise NPN protocols
995 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
996 AdvertiseNextProtoCallback,
998 // Client should select protocol from list of advertised
999 // If server supports NPN
1000 SSL_CTX_set_next_proto_select_cb(sc->ctx_, SelectNextProtoCallback, nullptr);
1001 #endif // OPENSSL_NPN_NEGOTIATED
1003 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1005 SSL_CTX_set_tlsext_status_cb(sc->ctx_, TLSExtStatusCallback);
1006 SSL_CTX_set_tlsext_status_arg(sc->ctx_, nullptr);
1007 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1011 template <class Base>
1012 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
1016 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1019 SSL_SESSION* sess = w->next_sess_;
1020 w->next_sess_ = nullptr;
1026 template <class Base>
1027 int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
1028 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1029 Environment* env = w->ssl_env();
1030 HandleScope handle_scope(env->isolate());
1031 Context::Scope context_scope(env->context());
1033 if (!w->session_callbacks_)
1036 // Check if session is small enough to be stored
1037 int size = i2d_SSL_SESSION(sess, nullptr);
1038 if (size > SecureContext::kMaxSessionSize)
1041 // Serialize session
1042 Local<Object> buff = Buffer::New(env, size);
1043 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1044 Buffer::Data(buff));
1045 memset(serialized, 0, size);
1046 i2d_SSL_SESSION(sess, &serialized);
1048 Local<Object> session = Buffer::New(env,
1049 reinterpret_cast<char*>(sess->session_id),
1050 sess->session_id_length);
1051 Local<Value> argv[] = { session, buff };
1052 w->new_session_wait_ = true;
1053 w->MakeCallback(env->onnewsession_string(), ARRAY_SIZE(argv), argv);
1059 template <class Base>
1060 void SSLWrap<Base>::OnClientHello(void* arg,
1061 const ClientHelloParser::ClientHello& hello) {
1062 Base* w = static_cast<Base*>(arg);
1063 Environment* env = w->ssl_env();
1064 HandleScope handle_scope(env->isolate());
1065 Context::Scope context_scope(env->context());
1067 Local<Object> hello_obj = Object::New(env->isolate());
1068 Local<Object> buff = Buffer::New(
1070 reinterpret_cast<const char*>(hello.session_id()),
1071 hello.session_size());
1072 hello_obj->Set(env->session_id_string(), buff);
1073 if (hello.servername() == nullptr) {
1074 hello_obj->Set(env->servername_string(), String::Empty(env->isolate()));
1076 Local<String> servername = OneByteString(env->isolate(),
1078 hello.servername_size());
1079 hello_obj->Set(env->servername_string(), servername);
1081 hello_obj->Set(env->tls_ticket_string(),
1082 Boolean::New(env->isolate(), hello.has_ticket()));
1083 hello_obj->Set(env->ocsp_request_string(),
1084 Boolean::New(env->isolate(), hello.ocsp_request()));
1086 Local<Value> argv[] = { hello_obj };
1087 w->MakeCallback(env->onclienthello_string(), ARRAY_SIZE(argv), argv);
1091 static bool SafeX509ExtPrint(BIO* out, X509_EXTENSION* ext) {
1092 // Only alt_name is escaped at the moment
1093 if (OBJ_obj2nid(ext->object) != NID_subject_alt_name)
1096 const X509V3_EXT_METHOD* method = X509V3_EXT_get(ext);
1097 if (method == NULL || method->it == NULL)
1100 if (method->i2v != reinterpret_cast<X509V3_EXT_I2V>(i2v_GENERAL_NAMES))
1103 const unsigned char* p = ext->value->data;
1104 GENERAL_NAMES* names = reinterpret_cast<GENERAL_NAMES*>(ASN1_item_d2i(
1108 ASN1_ITEM_ptr(method->it)));
1112 for (int i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1113 GENERAL_NAME* gen = sk_GENERAL_NAME_value(names, i);
1116 BIO_write(out, ", ", 2);
1118 if (gen->type == GEN_DNS) {
1119 ASN1_IA5STRING* name = gen->d.dNSName;
1121 BIO_write(out, "DNS:", 4);
1122 BIO_write(out, name->data, name->length);
1124 STACK_OF(CONF_VALUE)* nval = i2v_GENERAL_NAME(
1125 const_cast<X509V3_EXT_METHOD*>(method), gen, NULL);
1128 X509V3_EXT_val_prn(out, nval, 0, 0);
1136 static Local<Object> X509ToObject(Environment* env, X509* cert) {
1137 EscapableHandleScope scope(env->isolate());
1139 Local<Object> info = Object::New(env->isolate());
1141 BIO* bio = BIO_new(BIO_s_mem());
1143 if (X509_NAME_print_ex(bio,
1144 X509_get_subject_name(cert),
1146 X509_NAME_FLAGS) > 0) {
1147 BIO_get_mem_ptr(bio, &mem);
1148 info->Set(env->subject_string(),
1149 String::NewFromUtf8(env->isolate(), mem->data,
1150 String::kNormalString, mem->length));
1152 (void) BIO_reset(bio);
1154 X509_NAME* issuer_name = X509_get_issuer_name(cert);
1155 if (X509_NAME_print_ex(bio, issuer_name, 0, X509_NAME_FLAGS) > 0) {
1156 BIO_get_mem_ptr(bio, &mem);
1157 info->Set(env->issuer_string(),
1158 String::NewFromUtf8(env->isolate(), mem->data,
1159 String::kNormalString, mem->length));
1161 (void) BIO_reset(bio);
1163 int nids[] = { NID_subject_alt_name, NID_info_access };
1164 Local<String> keys[] = { env->subjectaltname_string(),
1165 env->infoaccess_string() };
1166 CHECK_EQ(ARRAY_SIZE(nids), ARRAY_SIZE(keys));
1167 for (unsigned int i = 0; i < ARRAY_SIZE(nids); i++) {
1168 int index = X509_get_ext_by_NID(cert, nids[i], -1);
1172 X509_EXTENSION* ext;
1175 ext = X509_get_ext(cert, index);
1176 CHECK_NE(ext, nullptr);
1178 if (!SafeX509ExtPrint(bio, ext)) {
1179 rv = X509V3_EXT_print(bio, ext, 0, 0);
1183 BIO_get_mem_ptr(bio, &mem);
1185 String::NewFromUtf8(env->isolate(), mem->data,
1186 String::kNormalString, mem->length));
1188 (void) BIO_reset(bio);
1191 EVP_PKEY* pkey = X509_get_pubkey(cert);
1193 if (pkey != nullptr)
1194 rsa = EVP_PKEY_get1_RSA(pkey);
1196 if (rsa != nullptr) {
1197 BN_print(bio, rsa->n);
1198 BIO_get_mem_ptr(bio, &mem);
1199 info->Set(env->modulus_string(),
1200 String::NewFromUtf8(env->isolate(), mem->data,
1201 String::kNormalString, mem->length));
1202 (void) BIO_reset(bio);
1204 BN_print(bio, rsa->e);
1205 BIO_get_mem_ptr(bio, &mem);
1206 info->Set(env->exponent_string(),
1207 String::NewFromUtf8(env->isolate(), mem->data,
1208 String::kNormalString, mem->length));
1209 (void) BIO_reset(bio);
1212 if (pkey != nullptr) {
1213 EVP_PKEY_free(pkey);
1216 if (rsa != nullptr) {
1221 ASN1_TIME_print(bio, X509_get_notBefore(cert));
1222 BIO_get_mem_ptr(bio, &mem);
1223 info->Set(env->valid_from_string(),
1224 String::NewFromUtf8(env->isolate(), mem->data,
1225 String::kNormalString, mem->length));
1226 (void) BIO_reset(bio);
1228 ASN1_TIME_print(bio, X509_get_notAfter(cert));
1229 BIO_get_mem_ptr(bio, &mem);
1230 info->Set(env->valid_to_string(),
1231 String::NewFromUtf8(env->isolate(), mem->data,
1232 String::kNormalString, mem->length));
1235 unsigned int md_size, i;
1236 unsigned char md[EVP_MAX_MD_SIZE];
1237 if (X509_digest(cert, EVP_sha1(), md, &md_size)) {
1238 const char hex[] = "0123456789ABCDEF";
1239 char fingerprint[EVP_MAX_MD_SIZE * 3];
1241 // TODO(indutny): Unify it with buffer's code
1242 for (i = 0; i < md_size; i++) {
1243 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1244 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1245 fingerprint[(3*i)+2] = ':';
1249 fingerprint[(3*(md_size-1))+2] = '\0';
1251 fingerprint[0] = '\0';
1254 info->Set(env->fingerprint_string(),
1255 OneByteString(env->isolate(), fingerprint));
1258 STACK_OF(ASN1_OBJECT)* eku = static_cast<STACK_OF(ASN1_OBJECT)*>(
1259 X509_get_ext_d2i(cert, NID_ext_key_usage, nullptr, nullptr));
1260 if (eku != nullptr) {
1261 Local<Array> ext_key_usage = Array::New(env->isolate());
1265 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1266 if (OBJ_obj2txt(buf, sizeof(buf), sk_ASN1_OBJECT_value(eku, i), 1) >= 0)
1267 ext_key_usage->Set(j++, OneByteString(env->isolate(), buf));
1270 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1271 info->Set(env->ext_key_usage_string(), ext_key_usage);
1274 if (ASN1_INTEGER* serial_number = X509_get_serialNumber(cert)) {
1275 if (BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, nullptr)) {
1276 if (char* buf = BN_bn2hex(bn)) {
1277 info->Set(env->serial_number_string(),
1278 OneByteString(env->isolate(), buf));
1285 // Raw DER certificate
1286 int size = i2d_X509(cert, nullptr);
1287 Local<Object> buff = Buffer::New(env, size);
1288 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1289 Buffer::Data(buff));
1290 i2d_X509(cert, &serialized);
1291 info->Set(env->raw_string(), buff);
1293 return scope.Escape(info);
1297 // TODO(indutny): Split it into multiple smaller functions
1298 template <class Base>
1299 void SSLWrap<Base>::GetPeerCertificate(
1300 const FunctionCallbackInfo<Value>& args) {
1301 Base* w = Unwrap<Base>(args.Holder());
1302 Environment* env = w->ssl_env();
1304 ClearErrorOnReturn clear_error_on_return;
1305 (void) &clear_error_on_return; // Silence unused variable warning.
1307 Local<Object> result;
1310 // NOTE: This is because of the odd OpenSSL behavior. On client `cert_chain`
1311 // contains the `peer_certificate`, but on server it doesn't
1312 X509* cert = w->is_server() ? SSL_get_peer_certificate(w->ssl_) : nullptr;
1313 STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(w->ssl_);
1314 STACK_OF(X509)* peer_certs = nullptr;
1315 if (cert == nullptr && ssl_certs == nullptr)
1318 if (cert == nullptr && sk_X509_num(ssl_certs) == 0)
1321 // Short result requested
1322 if (args.Length() < 1 || !args[0]->IsTrue()) {
1323 result = X509ToObject(env,
1324 cert == nullptr ? sk_X509_value(ssl_certs, 0) : cert);
1328 // Clone `ssl_certs`, because we are going to destruct it
1329 peer_certs = sk_X509_new(nullptr);
1330 if (cert != nullptr)
1331 sk_X509_push(peer_certs, cert);
1332 for (int i = 0; i < sk_X509_num(ssl_certs); i++) {
1333 cert = X509_dup(sk_X509_value(ssl_certs, i));
1334 if (cert == nullptr)
1336 if (!sk_X509_push(peer_certs, cert))
1340 // First and main certificate
1341 cert = sk_X509_value(peer_certs, 0);
1342 result = X509ToObject(env, cert);
1345 // Put issuer inside the object
1346 cert = sk_X509_delete(peer_certs, 0);
1347 while (sk_X509_num(peer_certs) > 0) {
1349 for (i = 0; i < sk_X509_num(peer_certs); i++) {
1350 X509* ca = sk_X509_value(peer_certs, i);
1351 if (X509_check_issued(ca, cert) != X509_V_OK)
1354 Local<Object> ca_info = X509ToObject(env, ca);
1355 info->Set(env->issuercert_string(), ca_info);
1358 // NOTE: Intentionally freeing cert that is not used anymore
1361 // Delete cert and continue aggregating issuers
1362 cert = sk_X509_delete(peer_certs, i);
1366 // Issuer not found, break out of the loop
1367 if (i == sk_X509_num(peer_certs))
1371 // Last certificate should be self-signed
1372 while (X509_check_issued(cert, cert) != X509_V_OK) {
1374 if (SSL_CTX_get_issuer(w->ssl_->ctx, cert, &ca) <= 0)
1377 Local<Object> ca_info = X509ToObject(env, ca);
1378 info->Set(env->issuercert_string(), ca_info);
1381 // NOTE: Intentionally freeing cert that is not used anymore
1384 // Delete cert and continue aggregating issuers
1388 // Self-issued certificate
1389 if (X509_check_issued(cert, cert) == X509_V_OK)
1390 info->Set(env->issuercert_string(), info);
1392 CHECK_NE(cert, nullptr);
1395 if (cert != nullptr)
1397 if (peer_certs != nullptr)
1398 sk_X509_pop_free(peer_certs, X509_free);
1399 if (result.IsEmpty())
1400 result = Object::New(env->isolate());
1401 args.GetReturnValue().Set(result);
1405 template <class Base>
1406 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
1407 Environment* env = Environment::GetCurrent(args);
1409 Base* w = Unwrap<Base>(args.Holder());
1411 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1412 if (sess == nullptr)
1415 int slen = i2d_SSL_SESSION(sess, nullptr);
1418 char* sbuf = new char[slen];
1419 unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1420 i2d_SSL_SESSION(sess, &p);
1421 args.GetReturnValue().Set(Encode(env->isolate(), sbuf, slen, BUFFER));
1426 template <class Base>
1427 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
1428 Environment* env = Environment::GetCurrent(args);
1430 Base* w = Unwrap<Base>(args.Holder());
1432 if (args.Length() < 1 ||
1433 (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
1434 return env->ThrowTypeError("Bad argument");
1437 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
1438 size_t slen = Buffer::Length(args[0]);
1439 char* sbuf = new char[slen];
1440 memcpy(sbuf, Buffer::Data(args[0]), slen);
1442 const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
1443 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, slen);
1447 if (sess == nullptr)
1450 int r = SSL_set_session(w->ssl_, sess);
1451 SSL_SESSION_free(sess);
1454 return env->ThrowError("SSL_set_session error");
1458 template <class Base>
1459 void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
1460 Base* w = Unwrap<Base>(args.Holder());
1461 Environment* env = w->ssl_env();
1463 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1464 ssize_t slen = Buffer::Length(args[0]);
1465 char* sbuf = Buffer::Data(args[0]);
1467 const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1468 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, slen);
1470 // Setup next session and move hello to the BIO buffer
1471 if (w->next_sess_ != nullptr)
1472 SSL_SESSION_free(w->next_sess_);
1473 w->next_sess_ = sess;
1475 Local<Object> info = Object::New(env->isolate());
1476 #ifndef OPENSSL_NO_TLSEXT
1477 if (sess->tlsext_hostname == nullptr) {
1478 info->Set(env->servername_string(), False(args.GetIsolate()));
1480 info->Set(env->servername_string(),
1481 OneByteString(args.GetIsolate(), sess->tlsext_hostname));
1484 args.GetReturnValue().Set(info);
1489 template <class Base>
1490 void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
1491 Base* w = Unwrap<Base>(args.Holder());
1492 bool yes = SSL_session_reused(w->ssl_);
1493 args.GetReturnValue().Set(yes);
1497 template <class Base>
1498 void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
1499 Base* w = Unwrap<Base>(args.Holder());
1500 w->hello_parser_.End();
1504 template <class Base>
1505 void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
1506 Base* w = Unwrap<Base>(args.Holder());
1508 ClearErrorOnReturn clear_error_on_return;
1509 (void) &clear_error_on_return; // Silence unused variable warning.
1511 bool yes = SSL_renegotiate(w->ssl_) == 1;
1512 args.GetReturnValue().Set(yes);
1516 template <class Base>
1517 void SSLWrap<Base>::Shutdown(const FunctionCallbackInfo<Value>& args) {
1518 Base* w = Unwrap<Base>(args.Holder());
1520 int rv = SSL_shutdown(w->ssl_);
1521 args.GetReturnValue().Set(rv);
1525 template <class Base>
1526 void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
1527 Base* w = Unwrap<Base>(args.Holder());
1528 Environment* env = w->ssl_env();
1530 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1531 if (sess == nullptr || sess->tlsext_tick == nullptr)
1534 Local<Object> buf = Buffer::New(env,
1535 reinterpret_cast<char*>(sess->tlsext_tick),
1536 sess->tlsext_ticklen);
1538 args.GetReturnValue().Set(buf);
1542 template <class Base>
1543 void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
1544 Base* w = Unwrap<Base>(args.Holder());
1545 w->new_session_wait_ = false;
1546 w->NewSessionDoneCb();
1550 template <class Base>
1551 void SSLWrap<Base>::SetOCSPResponse(
1552 const v8::FunctionCallbackInfo<v8::Value>& args) {
1553 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1554 HandleScope scope(args.GetIsolate());
1556 Base* w = Unwrap<Base>(args.Holder());
1557 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1558 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1560 w->ocsp_response_.Reset(args.GetIsolate(), args[0].As<Object>());
1561 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1565 template <class Base>
1566 void SSLWrap<Base>::RequestOCSP(
1567 const v8::FunctionCallbackInfo<v8::Value>& args) {
1568 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1569 HandleScope scope(args.GetIsolate());
1571 Base* w = Unwrap<Base>(args.Holder());
1573 SSL_set_tlsext_status_type(w->ssl_, TLSEXT_STATUSTYPE_ocsp);
1574 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1578 #ifdef SSL_set_max_send_fragment
1579 template <class Base>
1580 void SSLWrap<Base>::SetMaxSendFragment(
1581 const v8::FunctionCallbackInfo<v8::Value>& args) {
1582 HandleScope scope(args.GetIsolate());
1583 CHECK(args.Length() >= 1 && args[0]->IsNumber());
1585 Base* w = Unwrap<Base>(args.Holder());
1587 int rv = SSL_set_max_send_fragment(w->ssl_, args[0]->Int32Value());
1588 args.GetReturnValue().Set(rv);
1590 #endif // SSL_set_max_send_fragment
1593 template <class Base>
1594 void SSLWrap<Base>::IsInitFinished(const FunctionCallbackInfo<Value>& args) {
1595 Base* w = Unwrap<Base>(args.Holder());
1596 bool yes = SSL_is_init_finished(w->ssl_);
1597 args.GetReturnValue().Set(yes);
1601 template <class Base>
1602 void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
1603 Base* w = Unwrap<Base>(args.Holder());
1605 // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
1606 // peer certificate is questionable but it's compatible with what was
1608 long x509_verify_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
1609 if (X509* peer_cert = SSL_get_peer_certificate(w->ssl_)) {
1610 X509_free(peer_cert);
1611 x509_verify_error = SSL_get_verify_result(w->ssl_);
1614 if (x509_verify_error == X509_V_OK)
1615 return args.GetReturnValue().SetNull();
1617 // XXX(bnoordhuis) X509_verify_cert_error_string() is not actually thread-safe
1618 // in the presence of invalid error codes. Probably academical but something
1619 // to keep in mind if/when node ever grows multi-isolate capabilities.
1620 const char* reason = X509_verify_cert_error_string(x509_verify_error);
1621 const char* code = reason;
1622 #define CASE_X509_ERR(CODE) case X509_V_ERR_##CODE: code = #CODE; break;
1623 switch (x509_verify_error) {
1624 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT)
1625 CASE_X509_ERR(UNABLE_TO_GET_CRL)
1626 CASE_X509_ERR(UNABLE_TO_DECRYPT_CERT_SIGNATURE)
1627 CASE_X509_ERR(UNABLE_TO_DECRYPT_CRL_SIGNATURE)
1628 CASE_X509_ERR(UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)
1629 CASE_X509_ERR(CERT_SIGNATURE_FAILURE)
1630 CASE_X509_ERR(CRL_SIGNATURE_FAILURE)
1631 CASE_X509_ERR(CERT_NOT_YET_VALID)
1632 CASE_X509_ERR(CERT_HAS_EXPIRED)
1633 CASE_X509_ERR(CRL_NOT_YET_VALID)
1634 CASE_X509_ERR(CRL_HAS_EXPIRED)
1635 CASE_X509_ERR(ERROR_IN_CERT_NOT_BEFORE_FIELD)
1636 CASE_X509_ERR(ERROR_IN_CERT_NOT_AFTER_FIELD)
1637 CASE_X509_ERR(ERROR_IN_CRL_LAST_UPDATE_FIELD)
1638 CASE_X509_ERR(ERROR_IN_CRL_NEXT_UPDATE_FIELD)
1639 CASE_X509_ERR(OUT_OF_MEM)
1640 CASE_X509_ERR(DEPTH_ZERO_SELF_SIGNED_CERT)
1641 CASE_X509_ERR(SELF_SIGNED_CERT_IN_CHAIN)
1642 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
1643 CASE_X509_ERR(UNABLE_TO_VERIFY_LEAF_SIGNATURE)
1644 CASE_X509_ERR(CERT_CHAIN_TOO_LONG)
1645 CASE_X509_ERR(CERT_REVOKED)
1646 CASE_X509_ERR(INVALID_CA)
1647 CASE_X509_ERR(PATH_LENGTH_EXCEEDED)
1648 CASE_X509_ERR(INVALID_PURPOSE)
1649 CASE_X509_ERR(CERT_UNTRUSTED)
1650 CASE_X509_ERR(CERT_REJECTED)
1652 #undef CASE_X509_ERR
1654 Isolate* isolate = args.GetIsolate();
1655 Local<String> reason_string = OneByteString(isolate, reason);
1656 Local<Value> exception_value = Exception::Error(reason_string);
1657 Local<Object> exception_object = exception_value->ToObject(isolate);
1658 exception_object->Set(FIXED_ONE_BYTE_STRING(isolate, "code"),
1659 OneByteString(isolate, code));
1660 args.GetReturnValue().Set(exception_object);
1664 template <class Base>
1665 void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
1666 Base* w = Unwrap<Base>(args.Holder());
1667 Environment* env = w->ssl_env();
1669 OPENSSL_CONST SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_);
1673 Local<Object> info = Object::New(env->isolate());
1674 const char* cipher_name = SSL_CIPHER_get_name(c);
1675 info->Set(env->name_string(), OneByteString(args.GetIsolate(), cipher_name));
1676 const char* cipher_version = SSL_CIPHER_get_version(c);
1677 info->Set(env->version_string(),
1678 OneByteString(args.GetIsolate(), cipher_version));
1679 args.GetReturnValue().Set(info);
1683 #ifdef OPENSSL_NPN_NEGOTIATED
1684 template <class Base>
1685 int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s,
1686 const unsigned char** data,
1689 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1690 Environment* env = w->env();
1691 HandleScope handle_scope(env->isolate());
1692 Context::Scope context_scope(env->context());
1694 if (w->npn_protos_.IsEmpty()) {
1695 // No initialization - no NPN protocols
1696 *data = reinterpret_cast<const unsigned char*>("");
1699 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1700 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1701 *len = Buffer::Length(obj);
1704 return SSL_TLSEXT_ERR_OK;
1708 template <class Base>
1709 int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
1710 unsigned char** out,
1711 unsigned char* outlen,
1712 const unsigned char* in,
1715 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1716 Environment* env = w->env();
1717 HandleScope handle_scope(env->isolate());
1718 Context::Scope context_scope(env->context());
1720 // Release old protocol handler if present
1721 w->selected_npn_proto_.Reset();
1723 if (w->npn_protos_.IsEmpty()) {
1724 // We should at least select one protocol
1725 // If server is using NPN
1726 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
1729 // set status: unsupported
1730 w->selected_npn_proto_.Reset(env->isolate(), False(env->isolate()));
1732 return SSL_TLSEXT_ERR_OK;
1735 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1736 const unsigned char* npn_protos =
1737 reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1738 size_t len = Buffer::Length(obj);
1740 int status = SSL_select_next_proto(out, outlen, in, inlen, npn_protos, len);
1741 Handle<Value> result;
1743 case OPENSSL_NPN_UNSUPPORTED:
1744 result = Null(env->isolate());
1746 case OPENSSL_NPN_NEGOTIATED:
1747 result = OneByteString(env->isolate(), *out, *outlen);
1749 case OPENSSL_NPN_NO_OVERLAP:
1750 result = False(env->isolate());
1756 if (!result.IsEmpty())
1757 w->selected_npn_proto_.Reset(env->isolate(), result);
1759 return SSL_TLSEXT_ERR_OK;
1763 template <class Base>
1764 void SSLWrap<Base>::GetNegotiatedProto(
1765 const FunctionCallbackInfo<Value>& args) {
1766 Base* w = Unwrap<Base>(args.Holder());
1768 if (w->is_client()) {
1769 if (w->selected_npn_proto_.IsEmpty() == false) {
1770 args.GetReturnValue().Set(w->selected_npn_proto_);
1775 const unsigned char* npn_proto;
1776 unsigned int npn_proto_len;
1778 SSL_get0_next_proto_negotiated(w->ssl_, &npn_proto, &npn_proto_len);
1781 return args.GetReturnValue().Set(false);
1783 args.GetReturnValue().Set(
1784 OneByteString(args.GetIsolate(), npn_proto, npn_proto_len));
1788 template <class Base>
1789 void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
1790 Base* w = Unwrap<Base>(args.Holder());
1792 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1793 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1795 w->npn_protos_.Reset(args.GetIsolate(), args[0].As<Object>());
1797 #endif // OPENSSL_NPN_NEGOTIATED
1800 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1801 template <class Base>
1802 int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
1803 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1804 Environment* env = w->env();
1805 HandleScope handle_scope(env->isolate());
1807 if (w->is_client()) {
1808 // Incoming response
1809 const unsigned char* resp;
1810 int len = SSL_get_tlsext_status_ocsp_resp(s, &resp);
1812 if (resp == nullptr) {
1813 arg = Null(env->isolate());
1817 reinterpret_cast<char*>(const_cast<unsigned char*>(resp)),
1821 w->MakeCallback(env->onocspresponse_string(), 1, &arg);
1823 // Somehow, client is expecting different return value here
1826 // Outgoing response
1827 if (w->ocsp_response_.IsEmpty())
1828 return SSL_TLSEXT_ERR_NOACK;
1830 Local<Object> obj = PersistentToLocal(env->isolate(), w->ocsp_response_);
1831 char* resp = Buffer::Data(obj);
1832 size_t len = Buffer::Length(obj);
1834 // OpenSSL takes control of the pointer after accepting it
1835 char* data = reinterpret_cast<char*>(malloc(len));
1836 CHECK_NE(data, nullptr);
1837 memcpy(data, resp, len);
1839 if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
1841 w->ocsp_response_.Reset();
1843 return SSL_TLSEXT_ERR_OK;
1846 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1849 template <class Base>
1850 void SSLWrap<Base>::SSLGetter(Local<String> property,
1851 const PropertyCallbackInfo<Value>& info) {
1852 HandleScope scope(info.GetIsolate());
1854 SSL* ssl = Unwrap<Base>(info.Holder())->ssl_;
1855 Local<External> ext = External::New(info.GetIsolate(), ssl);
1856 info.GetReturnValue().Set(ext);
1860 void Connection::OnClientHelloParseEnd(void* arg) {
1861 Connection* conn = static_cast<Connection*>(arg);
1863 // Write all accumulated data
1864 int r = BIO_write(conn->bio_read_,
1865 reinterpret_cast<char*>(conn->hello_data_),
1866 conn->hello_offset_);
1867 conn->HandleBIOError(conn->bio_read_, "BIO_write", r);
1868 conn->SetShutdownFlags();
1872 #ifdef SSL_PRINT_DEBUG
1873 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
1875 # define DEBUG_PRINT(...)
1879 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
1883 int retry = BIO_should_retry(bio);
1884 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
1886 if (BIO_should_write(bio)) {
1887 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n",
1893 } else if (BIO_should_read(bio)) {
1894 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
1898 char ssl_error_buf[512];
1899 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
1901 HandleScope scope(ssl_env()->isolate());
1902 Local<Value> exception =
1903 Exception::Error(OneByteString(ssl_env()->isolate(), ssl_error_buf));
1904 object()->Set(ssl_env()->error_string(), exception);
1906 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
1919 int Connection::HandleSSLError(const char* func,
1923 ClearErrorOnReturn clear_error_on_return;
1924 (void) &clear_error_on_return; // Silence unused variable warning.
1928 if (rv == 0 && zs == kZeroIsNotAnError)
1931 int err = SSL_get_error(ssl_, rv);
1933 if (err == SSL_ERROR_NONE) {
1936 } else if (err == SSL_ERROR_WANT_WRITE) {
1937 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
1940 } else if (err == SSL_ERROR_WANT_READ) {
1941 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
1944 } else if (err == SSL_ERROR_ZERO_RETURN) {
1945 HandleScope scope(ssl_env()->isolate());
1947 Local<Value> exception =
1948 Exception::Error(ssl_env()->zero_return_string());
1949 object()->Set(ssl_env()->error_string(), exception);
1952 } else if (err == SSL_ERROR_SYSCALL && ss == kIgnoreSyscall) {
1956 HandleScope scope(ssl_env()->isolate());
1960 CHECK(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
1962 // XXX We need to drain the error queue for this thread or else OpenSSL
1963 // has the possibility of blocking connections? This problem is not well
1964 // understood. And we should be somehow propagating these errors up
1965 // into JavaScript. There is no test which demonstrates this problem.
1966 // https://github.com/joyent/node/issues/1719
1967 bio = BIO_new(BIO_s_mem());
1968 if (bio != nullptr) {
1969 ERR_print_errors(bio);
1970 BIO_get_mem_ptr(bio, &mem);
1971 Local<Value> exception = Exception::Error(
1972 OneByteString(ssl_env()->isolate(),
1975 object()->Set(ssl_env()->error_string(), exception);
1986 void Connection::ClearError() {
1988 HandleScope scope(ssl_env()->isolate());
1990 // We should clear the error in JS-land
1991 Local<String> error_key = ssl_env()->error_string();
1992 Local<Value> error = object()->Get(error_key);
1993 CHECK_EQ(error->BooleanValue(), false);
1998 void Connection::SetShutdownFlags() {
1999 HandleScope scope(ssl_env()->isolate());
2001 int flags = SSL_get_shutdown(ssl_);
2003 if (flags & SSL_SENT_SHUTDOWN) {
2004 Local<String> sent_shutdown_key = ssl_env()->sent_shutdown_string();
2005 object()->Set(sent_shutdown_key, True(ssl_env()->isolate()));
2008 if (flags & SSL_RECEIVED_SHUTDOWN) {
2009 Local<String> received_shutdown_key = ssl_env()->received_shutdown_string();
2010 object()->Set(received_shutdown_key, True(ssl_env()->isolate()));
2015 void Connection::NewSessionDoneCb() {
2016 HandleScope scope(env()->isolate());
2018 MakeCallback(env()->onnewsessiondone_string(), 0, nullptr);
2022 void Connection::Initialize(Environment* env, Handle<Object> target) {
2023 Local<FunctionTemplate> t = env->NewFunctionTemplate(Connection::New);
2024 t->InstanceTemplate()->SetInternalFieldCount(1);
2025 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"));
2027 env->SetProtoMethod(t, "encIn", Connection::EncIn);
2028 env->SetProtoMethod(t, "clearOut", Connection::ClearOut);
2029 env->SetProtoMethod(t, "clearIn", Connection::ClearIn);
2030 env->SetProtoMethod(t, "encOut", Connection::EncOut);
2031 env->SetProtoMethod(t, "clearPending", Connection::ClearPending);
2032 env->SetProtoMethod(t, "encPending", Connection::EncPending);
2033 env->SetProtoMethod(t, "start", Connection::Start);
2034 env->SetProtoMethod(t, "close", Connection::Close);
2036 SSLWrap<Connection>::AddMethods(env, t);
2039 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2040 env->SetProtoMethod(t, "getServername", Connection::GetServername);
2041 env->SetProtoMethod(t, "setSNICallback", Connection::SetSNICallback);
2044 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"),
2049 int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
2050 // Quoting SSL_set_verify(3ssl):
2052 // The VerifyCallback function is used to control the behaviour when
2053 // the SSL_VERIFY_PEER flag is set. It must be supplied by the
2054 // application and receives two arguments: preverify_ok indicates,
2055 // whether the verification of the certificate in question was passed
2056 // (preverify_ok=1) or not (preverify_ok=0). x509_ctx is a pointer to
2057 // the complete context used for the certificate chain verification.
2059 // The certificate chain is checked starting with the deepest nesting
2060 // level (the root CA certificate) and worked upward to the peer's
2061 // certificate. At each level signatures and issuer attributes are
2062 // checked. Whenever a verification error is found, the error number is
2063 // stored in x509_ctx and VerifyCallback is called with preverify_ok=0.
2064 // By applying X509_CTX_store_* functions VerifyCallback can locate the
2065 // certificate in question and perform additional steps (see EXAMPLES).
2066 // If no error is found for a certificate, VerifyCallback is called
2067 // with preverify_ok=1 before advancing to the next level.
2069 // The return value of VerifyCallback controls the strategy of the
2070 // further verification process. If VerifyCallback returns 0, the
2071 // verification process is immediately stopped with "verification
2072 // failed" state. If SSL_VERIFY_PEER is set, a verification failure
2073 // alert is sent to the peer and the TLS/SSL handshake is terminated. If
2074 // VerifyCallback returns 1, the verification process is continued. If
2075 // VerifyCallback always returns 1, the TLS/SSL handshake will not be
2076 // terminated with respect to verification failures and the connection
2077 // will be established. The calling process can however retrieve the
2078 // error code of the last verification error using
2079 // SSL_get_verify_result(3) or by maintaining its own error storage
2080 // managed by VerifyCallback.
2082 // If no VerifyCallback is specified, the default callback will be
2083 // used. Its return value is identical to preverify_ok, so that any
2084 // verification failure will lead to a termination of the TLS/SSL
2085 // handshake with an alert message, if SSL_VERIFY_PEER is set.
2087 // Since we cannot perform I/O quickly enough in this callback, we ignore
2088 // all preverify_ok errors and let the handshake continue. It is
2089 // imparative that the user use Connection::VerifyError after the
2090 // 'secure' callback has been made.
2095 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2096 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
2097 Connection* conn = static_cast<Connection*>(SSL_get_app_data(s));
2098 Environment* env = conn->env();
2099 HandleScope scope(env->isolate());
2101 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
2104 conn->servername_.Reset(env->isolate(),
2105 OneByteString(env->isolate(), servername));
2107 // Call the SNI callback and use its return value as context
2108 if (!conn->sniObject_.IsEmpty()) {
2109 conn->sniContext_.Reset();
2111 Local<Value> arg = PersistentToLocal(env->isolate(), conn->servername_);
2112 Local<Value> ret = conn->MakeCallback(env->onselect_string(), 1, &arg);
2114 // If ret is SecureContext
2115 Local<FunctionTemplate> secure_context_constructor_template =
2116 env->secure_context_constructor_template();
2117 if (secure_context_constructor_template->HasInstance(ret)) {
2118 conn->sniContext_.Reset(env->isolate(), ret);
2119 SecureContext* sc = Unwrap<SecureContext>(ret.As<Object>());
2121 SSL_set_SSL_CTX(s, sc->ctx_);
2123 return SSL_TLSEXT_ERR_NOACK;
2128 return SSL_TLSEXT_ERR_OK;
2132 void Connection::New(const FunctionCallbackInfo<Value>& args) {
2133 Environment* env = Environment::GetCurrent(args);
2135 if (args.Length() < 1 || !args[0]->IsObject()) {
2136 env->ThrowError("First argument must be a tls module SecureContext");
2140 SecureContext* sc = Unwrap<SecureContext>(args[0]->ToObject(env->isolate()));
2142 bool is_server = args[1]->BooleanValue();
2144 SSLWrap<Connection>::Kind kind =
2145 is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient;
2146 Connection* conn = new Connection(env, args.This(), sc, kind);
2147 conn->bio_read_ = NodeBIO::New();
2148 conn->bio_write_ = NodeBIO::New();
2150 SSL_set_app_data(conn->ssl_, conn);
2153 SSL_set_info_callback(conn->ssl_, SSLInfoCallback);
2157 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2159 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
2160 } else if (args[2]->IsString()) {
2161 const node::Utf8Value servername(env->isolate(), args[2]);
2162 SSL_set_tlsext_host_name(conn->ssl_, *servername);
2166 SSL_set_bio(conn->ssl_, conn->bio_read_, conn->bio_write_);
2168 #ifdef SSL_MODE_RELEASE_BUFFERS
2169 long mode = SSL_get_mode(conn->ssl_);
2170 SSL_set_mode(conn->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
2176 bool request_cert = args[2]->BooleanValue();
2177 if (!request_cert) {
2178 // Note reject_unauthorized ignored.
2179 verify_mode = SSL_VERIFY_NONE;
2181 bool reject_unauthorized = args[3]->BooleanValue();
2182 verify_mode = SSL_VERIFY_PEER;
2183 if (reject_unauthorized)
2184 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2187 // Note request_cert and reject_unauthorized are ignored for clients.
2188 verify_mode = SSL_VERIFY_NONE;
2192 // Always allow a connection. We'll reject in javascript.
2193 SSL_set_verify(conn->ssl_, verify_mode, VerifyCallback);
2196 SSL_set_accept_state(conn->ssl_);
2198 SSL_set_connect_state(conn->ssl_);
2203 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
2204 if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
2207 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
2208 // a non-const SSL* in OpenSSL <= 0.9.7e.
2209 SSL* ssl = const_cast<SSL*>(ssl_);
2210 Connection* conn = static_cast<Connection*>(SSL_get_app_data(ssl));
2211 Environment* env = conn->env();
2212 HandleScope handle_scope(env->isolate());
2213 Context::Scope context_scope(env->context());
2215 if (where & SSL_CB_HANDSHAKE_START) {
2216 conn->MakeCallback(env->onhandshakestart_string(), 0, nullptr);
2219 if (where & SSL_CB_HANDSHAKE_DONE) {
2220 conn->MakeCallback(env->onhandshakedone_string(), 0, nullptr);
2225 void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
2226 Connection* conn = Unwrap<Connection>(args.Holder());
2227 Environment* env = conn->env();
2229 if (args.Length() < 3) {
2230 return env->ThrowTypeError("Takes 3 parameters");
2233 if (!Buffer::HasInstance(args[0])) {
2234 return env->ThrowTypeError("Second argument should be a buffer");
2237 char* buffer_data = Buffer::Data(args[0]);
2238 size_t buffer_length = Buffer::Length(args[0]);
2240 size_t off = args[1]->Int32Value();
2241 size_t len = args[2]->Int32Value();
2243 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2244 return env->ThrowError("off + len > buffer.length");
2247 char* data = buffer_data + off;
2249 if (conn->is_server() && !conn->hello_parser_.IsEnded()) {
2250 // Just accumulate data, everything will be pushed to BIO later
2251 if (conn->hello_parser_.IsPaused()) {
2254 // Copy incoming data to the internal buffer
2255 // (which has a size of the biggest possible TLS frame)
2256 size_t available = sizeof(conn->hello_data_) - conn->hello_offset_;
2257 size_t copied = len < available ? len : available;
2258 memcpy(conn->hello_data_ + conn->hello_offset_, data, copied);
2259 conn->hello_offset_ += copied;
2261 conn->hello_parser_.Parse(conn->hello_data_, conn->hello_offset_);
2262 bytes_written = copied;
2265 bytes_written = BIO_write(conn->bio_read_, data, len);
2266 conn->HandleBIOError(conn->bio_read_, "BIO_write", bytes_written);
2267 conn->SetShutdownFlags();
2270 args.GetReturnValue().Set(bytes_written);
2274 void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
2275 Connection* conn = Unwrap<Connection>(args.Holder());
2276 Environment* env = conn->env();
2278 if (args.Length() < 3) {
2279 return env->ThrowTypeError("Takes 3 parameters");
2282 if (!Buffer::HasInstance(args[0])) {
2283 return env->ThrowTypeError("Second argument should be a buffer");
2286 char* buffer_data = Buffer::Data(args[0]);
2287 size_t buffer_length = Buffer::Length(args[0]);
2289 size_t off = args[1]->Int32Value();
2290 size_t len = args[2]->Int32Value();
2292 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2293 return env->ThrowError("off + len > buffer.length");
2295 if (!SSL_is_init_finished(conn->ssl_)) {
2298 if (conn->is_server()) {
2299 rv = SSL_accept(conn->ssl_);
2300 conn->HandleSSLError("SSL_accept:ClearOut",
2305 rv = SSL_connect(conn->ssl_);
2306 conn->HandleSSLError("SSL_connect:ClearOut",
2313 return args.GetReturnValue().Set(rv);
2317 int bytes_read = SSL_read(conn->ssl_, buffer_data + off, len);
2318 conn->HandleSSLError("SSL_read:ClearOut",
2322 conn->SetShutdownFlags();
2324 args.GetReturnValue().Set(bytes_read);
2328 void Connection::ClearPending(const FunctionCallbackInfo<Value>& args) {
2329 Connection* conn = Unwrap<Connection>(args.Holder());
2330 int bytes_pending = BIO_pending(conn->bio_read_);
2331 args.GetReturnValue().Set(bytes_pending);
2335 void Connection::EncPending(const FunctionCallbackInfo<Value>& args) {
2336 Connection* conn = Unwrap<Connection>(args.Holder());
2337 int bytes_pending = BIO_pending(conn->bio_write_);
2338 args.GetReturnValue().Set(bytes_pending);
2342 void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
2343 Connection* conn = Unwrap<Connection>(args.Holder());
2344 Environment* env = conn->env();
2346 if (args.Length() < 3) {
2347 return env->ThrowTypeError("Takes 3 parameters");
2350 if (!Buffer::HasInstance(args[0])) {
2351 return env->ThrowTypeError("Second argument should be a buffer");
2354 char* buffer_data = Buffer::Data(args[0]);
2355 size_t buffer_length = Buffer::Length(args[0]);
2357 size_t off = args[1]->Int32Value();
2358 size_t len = args[2]->Int32Value();
2360 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2361 return env->ThrowError("off + len > buffer.length");
2363 int bytes_read = BIO_read(conn->bio_write_, buffer_data + off, len);
2365 conn->HandleBIOError(conn->bio_write_, "BIO_read:EncOut", bytes_read);
2366 conn->SetShutdownFlags();
2368 args.GetReturnValue().Set(bytes_read);
2372 void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
2373 Connection* conn = Unwrap<Connection>(args.Holder());
2374 Environment* env = conn->env();
2376 if (args.Length() < 3) {
2377 return env->ThrowTypeError("Takes 3 parameters");
2380 if (!Buffer::HasInstance(args[0])) {
2381 return env->ThrowTypeError("Second argument should be a buffer");
2384 char* buffer_data = Buffer::Data(args[0]);
2385 size_t buffer_length = Buffer::Length(args[0]);
2387 size_t off = args[1]->Int32Value();
2388 size_t len = args[2]->Int32Value();
2390 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2391 return env->ThrowError("off + len > buffer.length");
2393 if (!SSL_is_init_finished(conn->ssl_)) {
2395 if (conn->is_server()) {
2396 rv = SSL_accept(conn->ssl_);
2397 conn->HandleSSLError("SSL_accept:ClearIn",
2402 rv = SSL_connect(conn->ssl_);
2403 conn->HandleSSLError("SSL_connect:ClearIn",
2410 return args.GetReturnValue().Set(rv);
2414 int bytes_written = SSL_write(conn->ssl_, buffer_data + off, len);
2416 conn->HandleSSLError("SSL_write:ClearIn",
2418 len == 0 ? kZeroIsNotAnError : kZeroIsAnError,
2420 conn->SetShutdownFlags();
2422 args.GetReturnValue().Set(bytes_written);
2426 void Connection::Start(const FunctionCallbackInfo<Value>& args) {
2427 Connection* conn = Unwrap<Connection>(args.Holder());
2430 if (!SSL_is_init_finished(conn->ssl_)) {
2431 if (conn->is_server()) {
2432 rv = SSL_accept(conn->ssl_);
2433 conn->HandleSSLError("SSL_accept:Start",
2438 rv = SSL_connect(conn->ssl_);
2439 conn->HandleSSLError("SSL_connect:Start",
2445 args.GetReturnValue().Set(rv);
2449 void Connection::Close(const FunctionCallbackInfo<Value>& args) {
2450 Connection* conn = Unwrap<Connection>(args.Holder());
2452 if (conn->ssl_ != nullptr) {
2453 SSL_free(conn->ssl_);
2454 conn->ssl_ = nullptr;
2459 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2460 void Connection::GetServername(const FunctionCallbackInfo<Value>& args) {
2461 Connection* conn = Unwrap<Connection>(args.Holder());
2463 if (conn->is_server() && !conn->servername_.IsEmpty()) {
2464 args.GetReturnValue().Set(conn->servername_);
2466 args.GetReturnValue().Set(false);
2471 void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) {
2472 Connection* conn = Unwrap<Connection>(args.Holder());
2473 Environment* env = conn->env();
2475 if (args.Length() < 1 || !args[0]->IsFunction()) {
2476 return env->ThrowError("Must give a Function as first argument");
2479 Local<Object> obj = Object::New(env->isolate());
2480 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "onselect"), args[0]);
2481 conn->sniObject_.Reset(args.GetIsolate(), obj);
2486 void CipherBase::Initialize(Environment* env, Handle<Object> target) {
2487 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
2489 t->InstanceTemplate()->SetInternalFieldCount(1);
2491 env->SetProtoMethod(t, "init", Init);
2492 env->SetProtoMethod(t, "initiv", InitIv);
2493 env->SetProtoMethod(t, "update", Update);
2494 env->SetProtoMethod(t, "final", Final);
2495 env->SetProtoMethod(t, "setAutoPadding", SetAutoPadding);
2496 env->SetProtoMethod(t, "getAuthTag", GetAuthTag);
2497 env->SetProtoMethod(t, "setAuthTag", SetAuthTag);
2498 env->SetProtoMethod(t, "setAAD", SetAAD);
2500 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "CipherBase"),
2505 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
2506 CHECK_EQ(args.IsConstructCall(), true);
2507 CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
2508 Environment* env = Environment::GetCurrent(args);
2509 new CipherBase(env, args.This(), kind);
2513 void CipherBase::Init(const char* cipher_type,
2514 const char* key_buf,
2516 HandleScope scope(env()->isolate());
2518 CHECK_EQ(cipher_, nullptr);
2519 cipher_ = EVP_get_cipherbyname(cipher_type);
2520 if (cipher_ == nullptr) {
2521 return env()->ThrowError("Unknown cipher");
2524 unsigned char key[EVP_MAX_KEY_LENGTH];
2525 unsigned char iv[EVP_MAX_IV_LENGTH];
2527 int key_len = EVP_BytesToKey(cipher_,
2530 reinterpret_cast<const unsigned char*>(key_buf),
2536 EVP_CIPHER_CTX_init(&ctx_);
2537 const bool encrypt = (kind_ == kCipher);
2538 EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
2539 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2540 EVP_CIPHER_CTX_cleanup(&ctx_);
2541 return env()->ThrowError("Invalid key length");
2544 EVP_CipherInit_ex(&ctx_,
2547 reinterpret_cast<unsigned char*>(key),
2548 reinterpret_cast<unsigned char*>(iv),
2550 initialised_ = true;
2554 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
2555 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2557 if (args.Length() < 2 ||
2558 !(args[0]->IsString() && Buffer::HasInstance(args[1]))) {
2559 return cipher->env()->ThrowError("Must give cipher-type, key");
2562 const node::Utf8Value cipher_type(args.GetIsolate(), args[0]);
2563 const char* key_buf = Buffer::Data(args[1]);
2564 ssize_t key_buf_len = Buffer::Length(args[1]);
2565 cipher->Init(*cipher_type, key_buf, key_buf_len);
2569 void CipherBase::InitIv(const char* cipher_type,
2574 HandleScope scope(env()->isolate());
2576 cipher_ = EVP_get_cipherbyname(cipher_type);
2577 if (cipher_ == nullptr) {
2578 return env()->ThrowError("Unknown cipher");
2581 /* OpenSSL versions up to 0.9.8l failed to return the correct
2582 iv_length (0) for ECB ciphers */
2583 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
2584 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2585 return env()->ThrowError("Invalid IV length");
2587 EVP_CIPHER_CTX_init(&ctx_);
2588 const bool encrypt = (kind_ == kCipher);
2589 EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
2590 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2591 EVP_CIPHER_CTX_cleanup(&ctx_);
2592 return env()->ThrowError("Invalid key length");
2595 EVP_CipherInit_ex(&ctx_,
2598 reinterpret_cast<const unsigned char*>(key),
2599 reinterpret_cast<const unsigned char*>(iv),
2601 initialised_ = true;
2605 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
2606 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2607 Environment* env = cipher->env();
2609 if (args.Length() < 3 || !args[0]->IsString()) {
2610 return env->ThrowError("Must give cipher-type, key, and iv as argument");
2613 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
2614 THROW_AND_RETURN_IF_NOT_BUFFER(args[2]);
2616 const node::Utf8Value cipher_type(env->isolate(), args[0]);
2617 ssize_t key_len = Buffer::Length(args[1]);
2618 const char* key_buf = Buffer::Data(args[1]);
2619 ssize_t iv_len = Buffer::Length(args[2]);
2620 const char* iv_buf = Buffer::Data(args[2]);
2621 cipher->InitIv(*cipher_type, key_buf, key_len, iv_buf, iv_len);
2625 bool CipherBase::IsAuthenticatedMode() const {
2626 // check if this cipher operates in an AEAD mode that we support.
2629 int mode = EVP_CIPHER_mode(cipher_);
2630 return mode == EVP_CIPH_GCM_MODE;
2634 bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
2635 // only callable after Final and if encrypting.
2636 if (initialised_ || kind_ != kCipher || !auth_tag_)
2638 *out_len = auth_tag_len_;
2639 *out = new char[auth_tag_len_];
2640 memcpy(*out, auth_tag_, auth_tag_len_);
2645 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
2646 Environment* env = Environment::GetCurrent(args);
2647 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2649 char* out = nullptr;
2650 unsigned int out_len = 0;
2652 if (cipher->GetAuthTag(&out, &out_len)) {
2653 Local<Object> buf = Buffer::Use(env, out, out_len);
2654 args.GetReturnValue().Set(buf);
2656 env->ThrowError("Attempting to get auth tag in unsupported state");
2661 bool CipherBase::SetAuthTag(const char* data, unsigned int len) {
2662 if (!initialised_ || !IsAuthenticatedMode() || kind_ != kDecipher)
2665 auth_tag_len_ = len;
2666 auth_tag_ = new char[len];
2667 memcpy(auth_tag_, data, len);
2672 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
2673 Environment* env = Environment::GetCurrent(args);
2675 Local<Object> buf = args[0].As<Object>();
2676 if (!buf->IsObject() || !Buffer::HasInstance(buf))
2677 return env->ThrowTypeError("Argument must be a Buffer");
2679 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2681 if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf)))
2682 env->ThrowError("Attempting to set auth tag in unsupported state");
2686 bool CipherBase::SetAAD(const char* data, unsigned int len) {
2687 if (!initialised_ || !IsAuthenticatedMode())
2690 if (!EVP_CipherUpdate(&ctx_,
2693 reinterpret_cast<const unsigned char*>(data),
2701 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
2702 Environment* env = Environment::GetCurrent(args);
2704 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
2706 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2708 if (!cipher->SetAAD(Buffer::Data(args[0]), Buffer::Length(args[0])))
2709 env->ThrowError("Attempting to set AAD in unsupported state");
2713 bool CipherBase::Update(const char* data,
2715 unsigned char** out,
2721 if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_ != nullptr) {
2722 EVP_CIPHER_CTX_ctrl(&ctx_,
2723 EVP_CTRL_GCM_SET_TAG,
2725 reinterpret_cast<unsigned char*>(auth_tag_));
2727 auth_tag_ = nullptr;
2730 *out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
2731 *out = new unsigned char[*out_len];
2732 return EVP_CipherUpdate(&ctx_,
2735 reinterpret_cast<const unsigned char*>(data),
2740 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
2741 Environment* env = Environment::GetCurrent(args);
2743 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2745 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
2747 unsigned char* out = nullptr;
2751 // Only copy the data if we have to, because it's a string
2752 if (args[0]->IsString()) {
2753 Local<String> string = args[0].As<String>();
2754 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2755 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2756 return env->ThrowTypeError("Bad input string");
2757 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2758 char* buf = new char[buflen];
2759 size_t written = StringBytes::Write(env->isolate(),
2764 r = cipher->Update(buf, written, &out, &out_len);
2767 char* buf = Buffer::Data(args[0]);
2768 size_t buflen = Buffer::Length(args[0]);
2769 r = cipher->Update(buf, buflen, &out, &out_len);
2774 return ThrowCryptoError(env,
2776 "Trying to add data in unsupported state");
2779 Local<Object> buf = Buffer::New(env, reinterpret_cast<char*>(out), out_len);
2783 args.GetReturnValue().Set(buf);
2787 bool CipherBase::SetAutoPadding(bool auto_padding) {
2790 return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
2794 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
2795 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2796 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2800 bool CipherBase::Final(unsigned char** out, int *out_len) {
2804 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx_)];
2805 int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
2807 if (r && kind_ == kCipher) {
2809 auth_tag_ = nullptr;
2810 if (IsAuthenticatedMode()) {
2811 auth_tag_len_ = EVP_GCM_TLS_TAG_LEN; // use default tag length
2812 auth_tag_ = new char[auth_tag_len_];
2813 memset(auth_tag_, 0, auth_tag_len_);
2814 EVP_CIPHER_CTX_ctrl(&ctx_,
2815 EVP_CTRL_GCM_GET_TAG,
2817 reinterpret_cast<unsigned char*>(auth_tag_));
2821 EVP_CIPHER_CTX_cleanup(&ctx_);
2822 initialised_ = false;
2828 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
2829 Environment* env = Environment::GetCurrent(args);
2831 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2833 unsigned char* out_value = nullptr;
2835 Local<Value> outString;
2837 bool r = cipher->Final(&out_value, &out_len);
2839 if (out_len <= 0 || !r) {
2841 out_value = nullptr;
2844 const char* msg = cipher->IsAuthenticatedMode() ?
2845 "Unsupported state or unable to authenticate data" :
2846 "Unsupported state";
2848 return ThrowCryptoError(env,
2854 args.GetReturnValue().Set(
2855 Buffer::New(env, reinterpret_cast<char*>(out_value), out_len));
2860 void Hmac::Initialize(Environment* env, v8::Handle<v8::Object> target) {
2861 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
2863 t->InstanceTemplate()->SetInternalFieldCount(1);
2865 env->SetProtoMethod(t, "init", HmacInit);
2866 env->SetProtoMethod(t, "update", HmacUpdate);
2867 env->SetProtoMethod(t, "digest", HmacDigest);
2869 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hmac"), t->GetFunction());
2873 void Hmac::New(const FunctionCallbackInfo<Value>& args) {
2874 Environment* env = Environment::GetCurrent(args);
2875 new Hmac(env, args.This());
2879 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
2880 HandleScope scope(env()->isolate());
2882 CHECK_EQ(md_, nullptr);
2883 md_ = EVP_get_digestbyname(hash_type);
2884 if (md_ == nullptr) {
2885 return env()->ThrowError("Unknown message digest");
2887 HMAC_CTX_init(&ctx_);
2889 HMAC_Init(&ctx_, "", 0, md_);
2891 HMAC_Init(&ctx_, key, key_len, md_);
2893 initialised_ = true;
2897 void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
2898 Hmac* hmac = Unwrap<Hmac>(args.Holder());
2899 Environment* env = hmac->env();
2901 if (args.Length() < 2 || !args[0]->IsString()) {
2902 return env->ThrowError("Must give hashtype string, key as arguments");
2905 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
2907 const node::Utf8Value hash_type(env->isolate(), args[0]);
2908 const char* buffer_data = Buffer::Data(args[1]);
2909 size_t buffer_length = Buffer::Length(args[1]);
2910 hmac->HmacInit(*hash_type, buffer_data, buffer_length);
2914 bool Hmac::HmacUpdate(const char* data, int len) {
2917 HMAC_Update(&ctx_, reinterpret_cast<const unsigned char*>(data), len);
2922 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
2923 Environment* env = Environment::GetCurrent(args);
2925 Hmac* hmac = Unwrap<Hmac>(args.Holder());
2927 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
2929 // Only copy the data if we have to, because it's a string
2931 if (args[0]->IsString()) {
2932 Local<String> string = args[0].As<String>();
2933 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2934 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2935 return env->ThrowTypeError("Bad input string");
2936 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2937 char* buf = new char[buflen];
2938 size_t written = StringBytes::Write(env->isolate(),
2943 r = hmac->HmacUpdate(buf, written);
2946 char* buf = Buffer::Data(args[0]);
2947 size_t buflen = Buffer::Length(args[0]);
2948 r = hmac->HmacUpdate(buf, buflen);
2952 return env->ThrowTypeError("HmacUpdate fail");
2957 bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
2960 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
2961 HMAC_Final(&ctx_, *md_value, md_len);
2962 HMAC_CTX_cleanup(&ctx_);
2963 initialised_ = false;
2968 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
2969 Environment* env = Environment::GetCurrent(args);
2971 Hmac* hmac = Unwrap<Hmac>(args.Holder());
2973 enum encoding encoding = BUFFER;
2974 if (args.Length() >= 1) {
2975 encoding = ParseEncoding(env->isolate(),
2976 args[0]->ToString(env->isolate()),
2980 unsigned char* md_value = nullptr;
2981 unsigned int md_len = 0;
2983 bool r = hmac->HmacDigest(&md_value, &md_len);
2989 Local<Value> rc = StringBytes::Encode(env->isolate(),
2990 reinterpret_cast<const char*>(md_value),
2994 args.GetReturnValue().Set(rc);
2998 void Hash::Initialize(Environment* env, v8::Handle<v8::Object> target) {
2999 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3001 t->InstanceTemplate()->SetInternalFieldCount(1);
3003 env->SetProtoMethod(t, "update", HashUpdate);
3004 env->SetProtoMethod(t, "digest", HashDigest);
3006 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hash"), t->GetFunction());
3010 void Hash::New(const FunctionCallbackInfo<Value>& args) {
3011 Environment* env = Environment::GetCurrent(args);
3013 if (args.Length() == 0 || !args[0]->IsString()) {
3014 return env->ThrowError("Must give hashtype string as argument");
3017 const node::Utf8Value hash_type(env->isolate(), args[0]);
3019 Hash* hash = new Hash(env, args.This());
3020 if (!hash->HashInit(*hash_type)) {
3021 return env->ThrowError("Digest method not supported");
3026 bool Hash::HashInit(const char* hash_type) {
3027 CHECK_EQ(md_, nullptr);
3028 md_ = EVP_get_digestbyname(hash_type);
3031 EVP_MD_CTX_init(&mdctx_);
3032 EVP_DigestInit_ex(&mdctx_, md_, nullptr);
3033 initialised_ = true;
3038 bool Hash::HashUpdate(const char* data, int len) {
3041 EVP_DigestUpdate(&mdctx_, data, len);
3046 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
3047 Environment* env = Environment::GetCurrent(args);
3049 Hash* hash = Unwrap<Hash>(args.Holder());
3051 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3053 // Only copy the data if we have to, because it's a string
3055 if (args[0]->IsString()) {
3056 Local<String> string = args[0].As<String>();
3057 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3058 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3059 return env->ThrowTypeError("Bad input string");
3060 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3061 char* buf = new char[buflen];
3062 size_t written = StringBytes::Write(env->isolate(),
3067 r = hash->HashUpdate(buf, written);
3070 char* buf = Buffer::Data(args[0]);
3071 size_t buflen = Buffer::Length(args[0]);
3072 r = hash->HashUpdate(buf, buflen);
3076 return env->ThrowTypeError("HashUpdate fail");
3081 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
3082 Environment* env = Environment::GetCurrent(args);
3084 Hash* hash = Unwrap<Hash>(args.Holder());
3086 if (!hash->initialised_) {
3087 return env->ThrowError("Not initialized");
3090 enum encoding encoding = BUFFER;
3091 if (args.Length() >= 1) {
3092 encoding = ParseEncoding(env->isolate(),
3093 args[0]->ToString(env->isolate()),
3097 unsigned char md_value[EVP_MAX_MD_SIZE];
3098 unsigned int md_len;
3100 EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len);
3101 EVP_MD_CTX_cleanup(&hash->mdctx_);
3102 hash->initialised_ = false;
3104 Local<Value> rc = StringBytes::Encode(env->isolate(),
3105 reinterpret_cast<const char*>(md_value),
3108 args.GetReturnValue().Set(rc);
3112 void SignBase::CheckThrow(SignBase::Error error) {
3113 HandleScope scope(env()->isolate());
3116 case kSignUnknownDigest:
3117 return env()->ThrowError("Unknown message digest");
3119 case kSignNotInitialised:
3120 return env()->ThrowError("Not initialised");
3124 case kSignPrivateKey:
3125 case kSignPublicKey:
3127 unsigned long err = ERR_get_error();
3129 return ThrowCryptoError(env(), err);
3132 return env()->ThrowError("EVP_SignInit_ex failed");
3134 return env()->ThrowError("EVP_SignUpdate failed");
3135 case kSignPrivateKey:
3136 return env()->ThrowError("PEM_read_bio_PrivateKey failed");
3137 case kSignPublicKey:
3138 return env()->ThrowError("PEM_read_bio_PUBKEY failed");
3152 void Sign::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3153 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3155 t->InstanceTemplate()->SetInternalFieldCount(1);
3157 env->SetProtoMethod(t, "init", SignInit);
3158 env->SetProtoMethod(t, "update", SignUpdate);
3159 env->SetProtoMethod(t, "sign", SignFinal);
3161 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"), t->GetFunction());
3165 void Sign::New(const FunctionCallbackInfo<Value>& args) {
3166 Environment* env = Environment::GetCurrent(args);
3167 new Sign(env, args.This());
3171 SignBase::Error Sign::SignInit(const char* sign_type) {
3172 CHECK_EQ(md_, nullptr);
3173 md_ = EVP_get_digestbyname(sign_type);
3175 return kSignUnknownDigest;
3177 EVP_MD_CTX_init(&mdctx_);
3178 if (!EVP_SignInit_ex(&mdctx_, md_, nullptr))
3180 initialised_ = true;
3186 void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
3187 Sign* sign = Unwrap<Sign>(args.Holder());
3189 if (args.Length() == 0 || !args[0]->IsString()) {
3190 return sign->env()->ThrowError("Must give signtype string as argument");
3193 const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
3194 sign->CheckThrow(sign->SignInit(*sign_type));
3198 SignBase::Error Sign::SignUpdate(const char* data, int len) {
3200 return kSignNotInitialised;
3201 if (!EVP_SignUpdate(&mdctx_, data, len))
3207 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
3208 Environment* env = Environment::GetCurrent(args);
3210 Sign* sign = Unwrap<Sign>(args.Holder());
3212 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3214 // Only copy the data if we have to, because it's a string
3216 if (args[0]->IsString()) {
3217 Local<String> string = args[0].As<String>();
3218 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3219 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3220 return env->ThrowTypeError("Bad input string");
3221 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3222 char* buf = new char[buflen];
3223 size_t written = StringBytes::Write(env->isolate(),
3228 err = sign->SignUpdate(buf, written);
3231 char* buf = Buffer::Data(args[0]);
3232 size_t buflen = Buffer::Length(args[0]);
3233 err = sign->SignUpdate(buf, buflen);
3236 sign->CheckThrow(err);
3240 SignBase::Error Sign::SignFinal(const char* key_pem,
3242 const char* passphrase,
3243 unsigned char** sig,
3244 unsigned int *sig_len) {
3246 return kSignNotInitialised;
3249 EVP_PKEY* pkey = nullptr;
3252 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3256 pkey = PEM_read_bio_PrivateKey(bp,
3259 const_cast<char*>(passphrase));
3260 if (pkey == nullptr)
3263 if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey))
3266 initialised_ = false;
3269 if (pkey != nullptr)
3270 EVP_PKEY_free(pkey);
3274 EVP_MD_CTX_cleanup(&mdctx_);
3277 return kSignPrivateKey;
3283 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
3284 Environment* env = Environment::GetCurrent(args);
3286 Sign* sign = Unwrap<Sign>(args.Holder());
3288 unsigned char* md_value;
3289 unsigned int md_len;
3291 unsigned int len = args.Length();
3292 enum encoding encoding = BUFFER;
3293 if (len >= 2 && args[1]->IsString()) {
3294 encoding = ParseEncoding(env->isolate(),
3295 args[1]->ToString(env->isolate()),
3299 node::Utf8Value passphrase(env->isolate(), args[2]);
3301 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3302 size_t buf_len = Buffer::Length(args[0]);
3303 char* buf = Buffer::Data(args[0]);
3305 md_len = 8192; // Maximum key size is 8192 bits
3306 md_value = new unsigned char[md_len];
3308 Error err = sign->SignFinal(
3311 len >= 3 && !args[2]->IsNull() ? *passphrase : nullptr,
3314 if (err != kSignOk) {
3318 return sign->CheckThrow(err);
3321 Local<Value> rc = StringBytes::Encode(env->isolate(),
3322 reinterpret_cast<const char*>(md_value),
3326 args.GetReturnValue().Set(rc);
3330 void Verify::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3331 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3333 t->InstanceTemplate()->SetInternalFieldCount(1);
3335 env->SetProtoMethod(t, "init", VerifyInit);
3336 env->SetProtoMethod(t, "update", VerifyUpdate);
3337 env->SetProtoMethod(t, "verify", VerifyFinal);
3339 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
3344 void Verify::New(const FunctionCallbackInfo<Value>& args) {
3345 Environment* env = Environment::GetCurrent(args);
3346 new Verify(env, args.This());
3350 SignBase::Error Verify::VerifyInit(const char* verify_type) {
3351 CHECK_EQ(md_, nullptr);
3352 md_ = EVP_get_digestbyname(verify_type);
3354 return kSignUnknownDigest;
3356 EVP_MD_CTX_init(&mdctx_);
3357 if (!EVP_VerifyInit_ex(&mdctx_, md_, nullptr))
3359 initialised_ = true;
3365 void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
3366 Verify* verify = Unwrap<Verify>(args.Holder());
3368 if (args.Length() == 0 || !args[0]->IsString()) {
3369 return verify->env()->ThrowError("Must give verifytype string as argument");
3372 const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
3373 verify->CheckThrow(verify->VerifyInit(*verify_type));
3377 SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
3379 return kSignNotInitialised;
3381 if (!EVP_VerifyUpdate(&mdctx_, data, len))
3388 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
3389 Environment* env = Environment::GetCurrent(args);
3391 Verify* verify = Unwrap<Verify>(args.Holder());
3393 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0]);
3395 // Only copy the data if we have to, because it's a string
3397 if (args[0]->IsString()) {
3398 Local<String> string = args[0].As<String>();
3399 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3400 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3401 return env->ThrowTypeError("Bad input string");
3402 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3403 char* buf = new char[buflen];
3404 size_t written = StringBytes::Write(env->isolate(),
3409 err = verify->VerifyUpdate(buf, written);
3412 char* buf = Buffer::Data(args[0]);
3413 size_t buflen = Buffer::Length(args[0]);
3414 err = verify->VerifyUpdate(buf, buflen);
3417 verify->CheckThrow(err);
3421 SignBase::Error Verify::VerifyFinal(const char* key_pem,
3425 bool* verify_result) {
3427 return kSignNotInitialised;
3429 ClearErrorOnReturn clear_error_on_return;
3430 (void) &clear_error_on_return; // Silence compiler warning.
3432 EVP_PKEY* pkey = nullptr;
3434 X509* x509 = nullptr;
3438 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3442 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3443 // Split this out into a separate function once we have more than one
3444 // consumer of public keys.
3445 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3446 pkey = PEM_read_bio_PUBKEY(bp, nullptr, CryptoPemCallback, nullptr);
3447 if (pkey == nullptr)
3449 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3451 PEM_read_bio_RSAPublicKey(bp, nullptr, CryptoPemCallback, nullptr);
3453 pkey = EVP_PKEY_new();
3455 EVP_PKEY_set1_RSA(pkey, rsa);
3458 if (pkey == nullptr)
3462 x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
3463 if (x509 == nullptr)
3466 pkey = X509_get_pubkey(x509);
3467 if (pkey == nullptr)
3472 r = EVP_VerifyFinal(&mdctx_,
3473 reinterpret_cast<const unsigned char*>(sig),
3478 if (pkey != nullptr)
3479 EVP_PKEY_free(pkey);
3482 if (x509 != nullptr)
3485 EVP_MD_CTX_cleanup(&mdctx_);
3486 initialised_ = false;
3489 return kSignPublicKey;
3491 *verify_result = r == 1;
3496 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
3497 Environment* env = Environment::GetCurrent(args);
3499 Verify* verify = Unwrap<Verify>(args.Holder());
3501 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3502 char* kbuf = Buffer::Data(args[0]);
3503 ssize_t klen = Buffer::Length(args[0]);
3505 THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[1]);
3507 // BINARY works for both buffers and binary strings.
3508 enum encoding encoding = BINARY;
3509 if (args.Length() >= 3) {
3510 encoding = ParseEncoding(env->isolate(),
3511 args[2]->ToString(env->isolate()),
3515 ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);
3517 // only copy if we need to, because it's a string.
3519 if (args[1]->IsString()) {
3520 hbuf = new char[hlen];
3521 ssize_t hwritten = StringBytes::Write(env->isolate(),
3526 CHECK_EQ(hwritten, hlen);
3528 hbuf = Buffer::Data(args[1]);
3532 Error err = verify->VerifyFinal(kbuf, klen, hbuf, hlen, &verify_result);
3533 if (args[1]->IsString())
3536 return verify->CheckThrow(err);
3537 args.GetReturnValue().Set(verify_result);
3541 template <PublicKeyCipher::Operation operation,
3542 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3543 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3544 bool PublicKeyCipher::Cipher(const char* key_pem,
3546 const char* passphrase,
3548 const unsigned char* data,
3550 unsigned char** out,
3552 EVP_PKEY* pkey = nullptr;
3553 EVP_PKEY_CTX* ctx = nullptr;
3555 X509* x509 = nullptr;
3558 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3562 // Check if this is a PKCS#8 or RSA public key before trying as X.509 and
3564 if (operation == kEncrypt &&
3565 strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3566 pkey = PEM_read_bio_PUBKEY(bp, nullptr, nullptr, nullptr);
3567 if (pkey == nullptr)
3569 } else if (operation == kEncrypt &&
3570 strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3571 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, nullptr, nullptr, nullptr);
3573 pkey = EVP_PKEY_new();
3575 EVP_PKEY_set1_RSA(pkey, rsa);
3578 if (pkey == nullptr)
3580 } else if (operation == kEncrypt &&
3581 strncmp(key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0) {
3582 x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
3583 if (x509 == nullptr)
3586 pkey = X509_get_pubkey(x509);
3587 if (pkey == nullptr)
3590 pkey = PEM_read_bio_PrivateKey(bp,
3593 const_cast<char*>(passphrase));
3594 if (pkey == nullptr)
3598 ctx = EVP_PKEY_CTX_new(pkey, nullptr);
3601 if (EVP_PKEY_cipher_init(ctx) <= 0)
3603 if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0)
3606 if (EVP_PKEY_cipher(ctx, nullptr, out_len, data, len) <= 0)
3609 *out = new unsigned char[*out_len];
3611 if (EVP_PKEY_cipher(ctx, *out, out_len, data, len) <= 0)
3617 if (pkey != nullptr)
3618 EVP_PKEY_free(pkey);
3622 EVP_PKEY_CTX_free(ctx);
3628 template <PublicKeyCipher::Operation operation,
3629 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3630 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3631 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
3632 Environment* env = Environment::GetCurrent(args);
3634 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3635 char* kbuf = Buffer::Data(args[0]);
3636 ssize_t klen = Buffer::Length(args[0]);
3638 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
3639 char* buf = Buffer::Data(args[1]);
3640 ssize_t len = Buffer::Length(args[1]);
3642 int padding = args[2]->Uint32Value();
3644 String::Utf8Value passphrase(args[3]);
3646 unsigned char* out_value = nullptr;
3649 bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
3652 args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : nullptr,
3654 reinterpret_cast<const unsigned char*>(buf),
3659 if (out_len == 0 || !r) {
3661 out_value = nullptr;
3664 return ThrowCryptoError(env,
3669 args.GetReturnValue().Set(
3670 Buffer::New(env, reinterpret_cast<char*>(out_value), out_len));
3675 void DiffieHellman::Initialize(Environment* env, Handle<Object> target) {
3676 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3678 const PropertyAttribute attributes =
3679 static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
3681 t->InstanceTemplate()->SetInternalFieldCount(1);
3683 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
3684 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
3685 env->SetProtoMethod(t, "getPrime", GetPrime);
3686 env->SetProtoMethod(t, "getGenerator", GetGenerator);
3687 env->SetProtoMethod(t, "getPublicKey", GetPublicKey);
3688 env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey);
3689 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
3690 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
3692 t->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3693 DiffieHellman::VerifyErrorGetter,
3699 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"),
3702 Local<FunctionTemplate> t2 = env->NewFunctionTemplate(DiffieHellmanGroup);
3703 t2->InstanceTemplate()->SetInternalFieldCount(1);
3705 env->SetProtoMethod(t2, "generateKeys", GenerateKeys);
3706 env->SetProtoMethod(t2, "computeSecret", ComputeSecret);
3707 env->SetProtoMethod(t2, "getPrime", GetPrime);
3708 env->SetProtoMethod(t2, "getGenerator", GetGenerator);
3709 env->SetProtoMethod(t2, "getPublicKey", GetPublicKey);
3710 env->SetProtoMethod(t2, "getPrivateKey", GetPrivateKey);
3712 t2->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3713 DiffieHellman::VerifyErrorGetter,
3719 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
3724 bool DiffieHellman::Init(int primeLength, int g) {
3726 DH_generate_parameters_ex(dh, primeLength, g, 0);
3727 bool result = VerifyContext();
3730 initialised_ = true;
3735 bool DiffieHellman::Init(const char* p, int p_len, int g) {
3737 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3739 if (!BN_set_word(dh->g, g))
3741 bool result = VerifyContext();
3744 initialised_ = true;
3749 bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
3751 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3752 dh->g = BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, 0);
3753 bool result = VerifyContext();
3756 initialised_ = true;
3761 void DiffieHellman::DiffieHellmanGroup(
3762 const FunctionCallbackInfo<Value>& args) {
3763 Environment* env = Environment::GetCurrent(args);
3764 DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
3766 if (args.Length() != 1 || !args[0]->IsString()) {
3767 return env->ThrowError("No group name given");
3770 bool initialized = false;
3772 const node::Utf8Value group_name(env->isolate(), args[0]);
3773 for (unsigned int i = 0; i < ARRAY_SIZE(modp_groups); ++i) {
3774 const modp_group* it = modp_groups + i;
3776 if (strcasecmp(*group_name, it->name) != 0)
3779 initialized = diffieHellman->Init(it->prime,
3784 env->ThrowError("Initialization failed");
3788 env->ThrowError("Unknown group");
3792 void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
3793 Environment* env = Environment::GetCurrent(args);
3794 DiffieHellman* diffieHellman =
3795 new DiffieHellman(env, args.This());
3796 bool initialized = false;
3798 if (args.Length() == 2) {
3799 if (args[0]->IsInt32()) {
3800 if (args[1]->IsInt32()) {
3801 initialized = diffieHellman->Init(args[0]->Int32Value(),
3802 args[1]->Int32Value());
3805 if (args[1]->IsInt32()) {
3806 initialized = diffieHellman->Init(Buffer::Data(args[0]),
3807 Buffer::Length(args[0]),
3808 args[1]->Int32Value());
3810 initialized = diffieHellman->Init(Buffer::Data(args[0]),
3811 Buffer::Length(args[0]),
3812 Buffer::Data(args[1]),
3813 Buffer::Length(args[1]));
3819 return env->ThrowError("Initialization failed");
3824 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
3825 Environment* env = Environment::GetCurrent(args);
3827 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3829 if (!diffieHellman->initialised_) {
3830 return env->ThrowError("Not initialized");
3833 if (!DH_generate_key(diffieHellman->dh)) {
3834 return env->ThrowError("Key generation failed");
3837 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3838 char* data = new char[dataSize];
3839 BN_bn2bin(diffieHellman->dh->pub_key,
3840 reinterpret_cast<unsigned char*>(data));
3842 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3847 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
3848 Environment* env = Environment::GetCurrent(args);
3850 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3852 if (!diffieHellman->initialised_) {
3853 return env->ThrowError("Not initialized");
3856 int dataSize = BN_num_bytes(diffieHellman->dh->p);
3857 char* data = new char[dataSize];
3858 BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
3860 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3865 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
3866 Environment* env = Environment::GetCurrent(args);
3868 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3870 if (!diffieHellman->initialised_) {
3871 return env->ThrowError("Not initialized");
3874 int dataSize = BN_num_bytes(diffieHellman->dh->g);
3875 char* data = new char[dataSize];
3876 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
3878 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3883 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
3884 Environment* env = Environment::GetCurrent(args);
3886 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3888 if (!diffieHellman->initialised_) {
3889 return env->ThrowError("Not initialized");
3892 if (diffieHellman->dh->pub_key == nullptr) {
3893 return env->ThrowError("No public key - did you forget to generate one?");
3896 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3897 char* data = new char[dataSize];
3898 BN_bn2bin(diffieHellman->dh->pub_key,
3899 reinterpret_cast<unsigned char*>(data));
3901 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3906 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
3907 Environment* env = Environment::GetCurrent(args);
3909 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3911 if (!diffieHellman->initialised_) {
3912 return env->ThrowError("Not initialized");
3915 if (diffieHellman->dh->priv_key == nullptr) {
3916 return env->ThrowError("No private key - did you forget to generate one?");
3919 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
3920 char* data = new char[dataSize];
3921 BN_bn2bin(diffieHellman->dh->priv_key,
3922 reinterpret_cast<unsigned char*>(data));
3924 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3929 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
3930 Environment* env = Environment::GetCurrent(args);
3932 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3934 if (!diffieHellman->initialised_) {
3935 return env->ThrowError("Not initialized");
3938 ClearErrorOnReturn clear_error_on_return;
3939 (void) &clear_error_on_return; // Silence compiler warning.
3940 BIGNUM* key = nullptr;
3942 if (args.Length() == 0) {
3943 return env->ThrowError("First argument must be other party's public key");
3945 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
3947 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3948 Buffer::Length(args[0]),
3952 int dataSize = DH_size(diffieHellman->dh);
3953 char* data = new char[dataSize];
3955 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
3963 checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
3968 return env->ThrowError("Invalid key");
3969 } else if (checkResult) {
3970 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
3971 return env->ThrowError("Supplied key is too small");
3972 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
3973 return env->ThrowError("Supplied key is too large");
3975 return env->ThrowError("Invalid key");
3978 return env->ThrowError("Invalid key");
3985 // DH_size returns number of bytes in a prime number
3986 // DH_compute_key returns number of bytes in a remainder of exponent, which
3987 // may have less bytes than a prime number. Therefore add 0-padding to the
3988 // allocated buffer.
3989 if (size != dataSize) {
3990 CHECK(dataSize > size);
3991 memmove(data + dataSize - size, data, size);
3992 memset(data, 0, dataSize - size);
3995 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4000 void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4001 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4002 Environment* env = diffieHellman->env();
4004 if (!diffieHellman->initialised_) {
4005 return env->ThrowError("Not initialized");
4008 if (args.Length() == 0) {
4009 return env->ThrowError("First argument must be public key");
4011 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4012 diffieHellman->dh->pub_key = BN_bin2bn(
4013 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4014 Buffer::Length(args[0]), 0);
4019 void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4020 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4021 Environment* env = diffieHellman->env();
4023 if (!diffieHellman->initialised_) {
4024 return env->ThrowError("Not initialized");
4027 if (args.Length() == 0) {
4028 return env->ThrowError("First argument must be private key");
4030 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4031 diffieHellman->dh->priv_key = BN_bin2bn(
4032 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4033 Buffer::Length(args[0]),
4039 void DiffieHellman::VerifyErrorGetter(Local<String> property,
4040 const PropertyCallbackInfo<Value>& args) {
4041 HandleScope scope(args.GetIsolate());
4043 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4045 if (!diffieHellman->initialised_)
4046 return diffieHellman->env()->ThrowError("Not initialized");
4048 args.GetReturnValue().Set(diffieHellman->verifyError_);
4052 bool DiffieHellman::VerifyContext() {
4054 if (!DH_check(dh, &codes))
4056 verifyError_ = codes;
4061 void ECDH::Initialize(Environment* env, Handle<Object> target) {
4062 HandleScope scope(env->isolate());
4064 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4066 t->InstanceTemplate()->SetInternalFieldCount(1);
4068 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
4069 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
4070 env->SetProtoMethod(t, "getPublicKey", GetPublicKey);
4071 env->SetProtoMethod(t, "getPrivateKey", GetPrivateKey);
4072 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
4073 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
4075 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH"),
4080 void ECDH::New(const FunctionCallbackInfo<Value>& args) {
4081 Environment* env = Environment::GetCurrent(args);
4083 // TODO(indutny): Support raw curves?
4084 CHECK(args[0]->IsString());
4085 node::Utf8Value curve(env->isolate(), args[0]);
4087 int nid = OBJ_sn2nid(*curve);
4088 if (nid == NID_undef)
4089 return env->ThrowTypeError("First argument should be a valid curve name");
4091 EC_KEY* key = EC_KEY_new_by_curve_name(nid);
4093 return env->ThrowError("Failed to create EC_KEY using curve name");
4095 new ECDH(env, args.This(), key);
4099 void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4100 Environment* env = Environment::GetCurrent(args);
4102 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4104 if (!EC_KEY_generate_key(ecdh->key_))
4105 return env->ThrowError("Failed to generate EC_KEY");
4107 ecdh->generated_ = true;
4111 EC_POINT* ECDH::BufferToPoint(char* data, size_t len) {
4115 pub = EC_POINT_new(group_);
4116 if (pub == nullptr) {
4117 env()->ThrowError("Failed to allocate EC_POINT for a public key");
4121 r = EC_POINT_oct2point(
4124 reinterpret_cast<unsigned char*>(data),
4128 env()->ThrowError("Failed to translate Buffer to a EC_POINT");
4140 void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4141 Environment* env = Environment::GetCurrent(args);
4143 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4145 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4147 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0]),
4148 Buffer::Length(args[0]));
4152 // NOTE: field_size is in bits
4153 int field_size = EC_GROUP_get_degree(ecdh->group_);
4154 size_t out_len = (field_size + 7) / 8;
4155 char* out = static_cast<char*>(malloc(out_len));
4156 CHECK_NE(out, nullptr);
4158 int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr);
4162 return env->ThrowError("Failed to compute ECDH key");
4165 args.GetReturnValue().Set(Buffer::Use(env, out, out_len));
4169 void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
4170 Environment* env = Environment::GetCurrent(args);
4173 CHECK_EQ(args.Length(), 1);
4175 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4177 if (!ecdh->generated_)
4178 return env->ThrowError("You should generate ECDH keys first");
4180 const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_);
4182 return env->ThrowError("Failed to get ECDH public key");
4185 point_conversion_form_t form =
4186 static_cast<point_conversion_form_t>(args[0]->Uint32Value());
4188 size = EC_POINT_point2oct(ecdh->group_, pub, form, nullptr, 0, nullptr);
4190 return env->ThrowError("Failed to get public key length");
4192 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4193 CHECK_NE(out, nullptr);
4195 int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr);
4198 return env->ThrowError("Failed to get public key");
4201 args.GetReturnValue().Set(Buffer::Use(env,
4202 reinterpret_cast<char*>(out),
4207 void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4208 Environment* env = Environment::GetCurrent(args);
4210 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4212 if (!ecdh->generated_)
4213 return env->ThrowError("You should generate ECDH keys first");
4215 const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_);
4217 return env->ThrowError("Failed to get ECDH private key");
4219 int size = BN_num_bytes(b);
4220 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4221 CHECK_NE(out, nullptr);
4223 if (size != BN_bn2bin(b, out)) {
4225 return env->ThrowError("Failed to convert ECDH private key to Buffer");
4228 args.GetReturnValue().Set(Buffer::Use(env,
4229 reinterpret_cast<char*>(out),
4234 void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4235 Environment* env = Environment::GetCurrent(args);
4237 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4239 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4241 BIGNUM* priv = BN_bin2bn(
4242 reinterpret_cast<unsigned char*>(Buffer::Data(args[0].As<Object>())),
4243 Buffer::Length(args[0].As<Object>()),
4245 if (priv == nullptr)
4246 return env->ThrowError("Failed to convert Buffer to BN");
4248 if (!EC_KEY_set_private_key(ecdh->key_, priv))
4249 return env->ThrowError("Failed to convert BN to a private key");
4253 void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4254 Environment* env = Environment::GetCurrent(args);
4256 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4258 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4260 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0].As<Object>()),
4261 Buffer::Length(args[0].As<Object>()));
4265 int r = EC_KEY_set_public_key(ecdh->key_, pub);
4268 return env->ThrowError("Failed to convert BN to a private key");
4272 class PBKDF2Request : public AsyncWrap {
4274 PBKDF2Request(Environment* env,
4275 Local<Object> object,
4276 const EVP_MD* digest,
4283 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4291 key_(static_cast<char*>(malloc(keylen))),
4293 if (key() == nullptr)
4294 FatalError("node::PBKDF2Request()", "Out of Memory");
4297 ~PBKDF2Request() override {
4298 persistent().Reset();
4301 uv_work_t* work_req() {
4305 inline const EVP_MD* digest() const {
4309 inline ssize_t passlen() const {
4313 inline char* pass() const {
4317 inline ssize_t saltlen() const {
4321 inline char* salt() const {
4325 inline ssize_t keylen() const {
4329 inline char* key() const {
4333 inline ssize_t iter() const {
4337 inline void release() {
4346 inline int error() const {
4350 inline void set_error(int err) {
4354 uv_work_t work_req_;
4357 const EVP_MD* digest_;
4369 void EIO_PBKDF2(PBKDF2Request* req) {
4370 req->set_error(PKCS5_PBKDF2_HMAC(
4373 reinterpret_cast<unsigned char*>(req->salt()),
4378 reinterpret_cast<unsigned char*>(req->key())));
4379 memset(req->pass(), 0, req->passlen());
4380 memset(req->salt(), 0, req->saltlen());
4384 void EIO_PBKDF2(uv_work_t* work_req) {
4385 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4390 void EIO_PBKDF2After(PBKDF2Request* req, Local<Value> argv[2]) {
4392 argv[0] = Undefined(req->env()->isolate());
4393 argv[1] = Encode(req->env()->isolate(), req->key(), req->keylen(), BUFFER);
4394 memset(req->key(), 0, req->keylen());
4396 argv[0] = Exception::Error(req->env()->pbkdf2_error_string());
4397 argv[1] = Undefined(req->env()->isolate());
4402 void EIO_PBKDF2After(uv_work_t* work_req, int status) {
4403 CHECK_EQ(status, 0);
4404 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4405 Environment* env = req->env();
4406 HandleScope handle_scope(env->isolate());
4407 Context::Scope context_scope(env->context());
4408 Local<Value> argv[2];
4409 EIO_PBKDF2After(req, argv);
4410 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4416 void PBKDF2(const FunctionCallbackInfo<Value>& args) {
4417 Environment* env = Environment::GetCurrent(args);
4419 const EVP_MD* digest = nullptr;
4420 const char* type_error = nullptr;
4421 char* pass = nullptr;
4422 char* salt = nullptr;
4423 ssize_t passlen = -1;
4424 ssize_t saltlen = -1;
4425 ssize_t keylen = -1;
4427 PBKDF2Request* req = nullptr;
4430 if (args.Length() != 5 && args.Length() != 6) {
4431 type_error = "Bad parameter";
4435 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4436 passlen = Buffer::Length(args[0]);
4438 type_error = "Bad password";
4442 THROW_AND_RETURN_IF_NOT_BUFFER(args[1]);
4444 pass = static_cast<char*>(malloc(passlen));
4445 if (pass == nullptr) {
4446 FatalError("node::PBKDF2()", "Out of Memory");
4448 memcpy(pass, Buffer::Data(args[0]), passlen);
4450 saltlen = Buffer::Length(args[1]);
4452 type_error = "Bad salt";
4456 salt = static_cast<char*>(malloc(saltlen));
4457 if (salt == nullptr) {
4458 FatalError("node::PBKDF2()", "Out of Memory");
4460 memcpy(salt, Buffer::Data(args[1]), saltlen);
4462 if (!args[2]->IsNumber()) {
4463 type_error = "Iterations not a number";
4467 iter = args[2]->Int32Value();
4469 type_error = "Bad iterations";
4473 if (!args[3]->IsNumber()) {
4474 type_error = "Key length not a number";
4478 keylen = args[3]->Int32Value();
4480 type_error = "Bad key length";
4484 if (args[4]->IsString()) {
4485 node::Utf8Value digest_name(env->isolate(), args[4]);
4486 digest = EVP_get_digestbyname(*digest_name);
4487 if (digest == nullptr) {
4488 type_error = "Bad digest name";
4493 if (digest == nullptr) {
4494 digest = EVP_sha1();
4497 obj = Object::New(env->isolate());
4498 req = new PBKDF2Request(env,
4508 if (args[5]->IsFunction()) {
4509 obj->Set(env->ondone_string(), args[5]);
4510 // XXX(trevnorris): This will need to go with the rest of domains.
4511 if (env->in_domain())
4512 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4513 uv_queue_work(env->event_loop(),
4518 Local<Value> argv[2];
4520 EIO_PBKDF2After(req, argv);
4521 if (argv[0]->IsObject())
4522 env->isolate()->ThrowException(argv[0]);
4524 args.GetReturnValue().Set(argv[1]);
4531 return env->ThrowTypeError(type_error);
4535 // Only instantiate within a valid HandleScope.
4536 class RandomBytesRequest : public AsyncWrap {
4538 RandomBytesRequest(Environment* env, Local<Object> object, size_t size)
4539 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4542 data_(static_cast<char*>(malloc(size))) {
4543 if (data() == nullptr)
4544 FatalError("node::RandomBytesRequest()", "Out of Memory");
4547 ~RandomBytesRequest() override {
4548 persistent().Reset();
4551 uv_work_t* work_req() {
4555 inline size_t size() const {
4559 inline char* data() const {
4563 inline void release() {
4568 inline void return_memory(char** d, size_t* len) {
4575 inline unsigned long error() const {
4579 inline void set_error(unsigned long err) {
4583 uv_work_t work_req_;
4586 unsigned long error_;
4592 void RandomBytesWork(uv_work_t* work_req) {
4593 RandomBytesRequest* req =
4594 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4596 // Ensure that OpenSSL's PRNG is properly seeded.
4599 const int r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data()),
4602 // RAND_bytes() returns 0 on error.
4604 req->set_error(ERR_get_error());
4605 } else if (r == -1) {
4606 req->set_error(static_cast<unsigned long>(-1));
4611 // don't call this function without a valid HandleScope
4612 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
4614 char errmsg[256] = "Operation not supported";
4616 if (req->error() != static_cast<unsigned long>(-1))
4617 ERR_error_string_n(req->error(), errmsg, sizeof errmsg);
4619 argv[0] = Exception::Error(OneByteString(req->env()->isolate(), errmsg));
4620 argv[1] = Null(req->env()->isolate());
4623 char* data = nullptr;
4625 req->return_memory(&data, &size);
4626 argv[0] = Null(req->env()->isolate());
4627 argv[1] = Buffer::Use(data, size);
4632 void RandomBytesAfter(uv_work_t* work_req, int status) {
4633 CHECK_EQ(status, 0);
4634 RandomBytesRequest* req =
4635 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4636 Environment* env = req->env();
4637 HandleScope handle_scope(env->isolate());
4638 Context::Scope context_scope(env->context());
4639 Local<Value> argv[2];
4640 RandomBytesCheck(req, argv);
4641 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4646 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
4647 Environment* env = Environment::GetCurrent(args);
4649 // maybe allow a buffer to write to? cuts down on object creation
4650 // when generating random data in a loop
4651 if (!args[0]->IsUint32()) {
4652 return env->ThrowTypeError("size must be a number >= 0");
4655 const uint32_t size = args[0]->Uint32Value();
4656 if (size > Buffer::kMaxLength) {
4657 return env->ThrowTypeError("size > Buffer::kMaxLength");
4660 Local<Object> obj = Object::New(env->isolate());
4661 RandomBytesRequest* req = new RandomBytesRequest(env, obj, size);
4663 if (args[1]->IsFunction()) {
4664 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "ondone"), args[1]);
4665 // XXX(trevnorris): This will need to go with the rest of domains.
4666 if (env->in_domain())
4667 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4668 uv_queue_work(env->event_loop(),
4672 args.GetReturnValue().Set(obj);
4674 Local<Value> argv[2];
4675 RandomBytesWork(req->work_req());
4676 RandomBytesCheck(req, argv);
4679 if (!argv[0]->IsNull())
4680 env->isolate()->ThrowException(argv[0]);
4682 args.GetReturnValue().Set(argv[1]);
4687 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
4688 Environment* env = Environment::GetCurrent(args);
4690 SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
4691 if (ctx == nullptr) {
4692 return env->ThrowError("SSL_CTX_new() failed.");
4695 SSL* ssl = SSL_new(ctx);
4696 if (ssl == nullptr) {
4698 return env->ThrowError("SSL_new() failed.");
4701 Local<Array> arr = Array::New(env->isolate());
4702 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
4704 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
4705 SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
4706 arr->Set(i, OneByteString(args.GetIsolate(), SSL_CIPHER_get_name(cipher)));
4712 args.GetReturnValue().Set(arr);
4716 class CipherPushContext {
4718 explicit CipherPushContext(Environment* env)
4719 : arr(Array::New(env->isolate())),
4723 inline Environment* env() const { return env_; }
4732 template <class TypeName>
4733 static void array_push_back(const TypeName* md,
4737 CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
4738 ctx->arr->Set(ctx->arr->Length(), OneByteString(ctx->env()->isolate(), from));
4742 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
4743 Environment* env = Environment::GetCurrent(args);
4744 CipherPushContext ctx(env);
4745 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
4746 args.GetReturnValue().Set(ctx.arr);
4750 void GetHashes(const FunctionCallbackInfo<Value>& args) {
4751 Environment* env = Environment::GetCurrent(args);
4752 CipherPushContext ctx(env);
4753 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
4754 args.GetReturnValue().Set(ctx.arr);
4758 void Certificate::Initialize(Environment* env, Handle<Object> target) {
4759 HandleScope scope(env->isolate());
4761 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4763 t->InstanceTemplate()->SetInternalFieldCount(1);
4765 env->SetProtoMethod(t, "verifySpkac", VerifySpkac);
4766 env->SetProtoMethod(t, "exportPublicKey", ExportPublicKey);
4767 env->SetProtoMethod(t, "exportChallenge", ExportChallenge);
4769 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Certificate"),
4774 void Certificate::New(const FunctionCallbackInfo<Value>& args) {
4775 Environment* env = Environment::GetCurrent(args);
4776 new Certificate(env, args.This());
4780 bool Certificate::VerifySpkac(const char* data, unsigned int len) {
4782 EVP_PKEY* pkey = nullptr;
4783 NETSCAPE_SPKI* spki = nullptr;
4785 spki = NETSCAPE_SPKI_b64_decode(data, len);
4786 if (spki == nullptr)
4789 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
4790 if (pkey == nullptr)
4793 i = NETSCAPE_SPKI_verify(spki, pkey) > 0;
4796 if (pkey != nullptr)
4797 EVP_PKEY_free(pkey);
4799 if (spki != nullptr)
4800 NETSCAPE_SPKI_free(spki);
4806 void Certificate::VerifySpkac(const FunctionCallbackInfo<Value>& args) {
4807 Certificate* certificate = Unwrap<Certificate>(args.Holder());
4808 Environment* env = certificate->env();
4811 if (args.Length() < 1)
4812 return env->ThrowTypeError("Missing argument");
4814 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4816 size_t length = Buffer::Length(args[0]);
4818 return args.GetReturnValue().Set(i);
4820 char* data = Buffer::Data(args[0]);
4821 CHECK_NE(data, nullptr);
4823 i = certificate->VerifySpkac(data, length);
4825 args.GetReturnValue().Set(i);
4829 const char* Certificate::ExportPublicKey(const char* data, int len) {
4830 char* buf = nullptr;
4831 EVP_PKEY* pkey = nullptr;
4832 NETSCAPE_SPKI* spki = nullptr;
4834 BIO* bio = BIO_new(BIO_s_mem());
4838 spki = NETSCAPE_SPKI_b64_decode(data, len);
4839 if (spki == nullptr)
4842 pkey = NETSCAPE_SPKI_get_pubkey(spki);
4843 if (pkey == nullptr)
4846 if (PEM_write_bio_PUBKEY(bio, pkey) <= 0)
4849 BIO_write(bio, "\0", 1);
4851 BIO_get_mem_ptr(bio, &ptr);
4853 buf = new char[ptr->length];
4854 memcpy(buf, ptr->data, ptr->length);
4857 if (pkey != nullptr)
4858 EVP_PKEY_free(pkey);
4860 if (spki != nullptr)
4861 NETSCAPE_SPKI_free(spki);
4870 void Certificate::ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
4871 Environment* env = Environment::GetCurrent(args);
4873 Certificate* certificate = Unwrap<Certificate>(args.Holder());
4875 if (args.Length() < 1)
4876 return env->ThrowTypeError("Missing argument");
4878 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4880 size_t length = Buffer::Length(args[0]);
4882 return args.GetReturnValue().SetEmptyString();
4884 char* data = Buffer::Data(args[0]);
4885 CHECK_NE(data, nullptr);
4887 const char* pkey = certificate->ExportPublicKey(data, length);
4888 if (pkey == nullptr)
4889 return args.GetReturnValue().SetEmptyString();
4891 Local<Value> out = Encode(env->isolate(), pkey, strlen(pkey), BUFFER);
4895 args.GetReturnValue().Set(out);
4899 const char* Certificate::ExportChallenge(const char* data, int len) {
4900 NETSCAPE_SPKI* sp = nullptr;
4902 sp = NETSCAPE_SPKI_b64_decode(data, len);
4906 const char* buf = nullptr;
4907 buf = reinterpret_cast<const char*>(ASN1_STRING_data(sp->spkac->challenge));
4913 void Certificate::ExportChallenge(const FunctionCallbackInfo<Value>& args) {
4914 Environment* env = Environment::GetCurrent(args);
4916 Certificate* crt = Unwrap<Certificate>(args.Holder());
4918 if (args.Length() < 1)
4919 return env->ThrowTypeError("Missing argument");
4921 THROW_AND_RETURN_IF_NOT_BUFFER(args[0]);
4923 size_t len = Buffer::Length(args[0]);
4925 return args.GetReturnValue().SetEmptyString();
4927 char* data = Buffer::Data(args[0]);
4928 CHECK_NE(data, nullptr);
4930 const char* cert = crt->ExportChallenge(data, len);
4931 if (cert == nullptr)
4932 return args.GetReturnValue().SetEmptyString();
4934 Local<Value> outString = Encode(env->isolate(), cert, strlen(cert), BUFFER);
4938 args.GetReturnValue().Set(outString);
4942 void InitCryptoOnce() {
4944 OpenSSL_add_all_algorithms();
4945 SSL_load_error_strings();
4948 CRYPTO_set_locking_callback(crypto_lock_cb);
4949 CRYPTO_THREADID_set_callback(crypto_threadid_cb);
4951 // Turn off compression. Saves memory and protects against CRIME attacks.
4952 #if !defined(OPENSSL_NO_COMP)
4953 #if OPENSSL_VERSION_NUMBER < 0x00908000L
4954 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_method();
4956 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
4958 sk_SSL_COMP_zero(comp_methods);
4959 CHECK_EQ(sk_SSL_COMP_num(comp_methods), 0);
4962 #ifndef OPENSSL_NO_ENGINE
4963 ERR_load_ENGINE_strings();
4964 ENGINE_load_builtin_engines();
4965 #endif // !OPENSSL_NO_ENGINE
4969 #ifndef OPENSSL_NO_ENGINE
4970 void SetEngine(const FunctionCallbackInfo<Value>& args) {
4971 Environment* env = Environment::GetCurrent(args);
4972 CHECK(args.Length() >= 2 && args[0]->IsString());
4973 unsigned int flags = args[1]->Uint32Value();
4975 ClearErrorOnReturn clear_error_on_return;
4976 (void) &clear_error_on_return; // Silence compiler warning.
4978 const node::Utf8Value engine_id(env->isolate(), args[0]);
4979 ENGINE* engine = ENGINE_by_id(*engine_id);
4981 // Engine not found, try loading dynamically
4982 if (engine == nullptr) {
4983 engine = ENGINE_by_id("dynamic");
4984 if (engine != nullptr) {
4985 if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", *engine_id, 0) ||
4986 !ENGINE_ctrl_cmd_string(engine, "LOAD", nullptr, 0)) {
4987 ENGINE_free(engine);
4993 if (engine == nullptr) {
4994 int err = ERR_get_error();
4997 snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id);
4998 return env->ThrowError(tmp);
5000 return ThrowCryptoError(env, err);
5004 int r = ENGINE_set_default(engine, flags);
5005 ENGINE_free(engine);
5007 return ThrowCryptoError(env, ERR_get_error());
5009 #endif // !OPENSSL_NO_ENGINE
5012 // FIXME(bnoordhuis) Handle global init correctly.
5013 void InitCrypto(Handle<Object> target,
5014 Handle<Value> unused,
5015 Handle<Context> context,
5017 static uv_once_t init_once = UV_ONCE_INIT;
5018 uv_once(&init_once, InitCryptoOnce);
5020 Environment* env = Environment::GetCurrent(context);
5021 SecureContext::Initialize(env, target);
5022 Connection::Initialize(env, target);
5023 CipherBase::Initialize(env, target);
5024 DiffieHellman::Initialize(env, target);
5025 ECDH::Initialize(env, target);
5026 Hmac::Initialize(env, target);
5027 Hash::Initialize(env, target);
5028 Sign::Initialize(env, target);
5029 Verify::Initialize(env, target);
5030 Certificate::Initialize(env, target);
5032 #ifndef OPENSSL_NO_ENGINE
5033 env->SetMethod(target, "setEngine", SetEngine);
5034 #endif // !OPENSSL_NO_ENGINE
5035 env->SetMethod(target, "PBKDF2", PBKDF2);
5036 env->SetMethod(target, "randomBytes", RandomBytes);
5037 env->SetMethod(target, "getSSLCiphers", GetSSLCiphers);
5038 env->SetMethod(target, "getCiphers", GetCiphers);
5039 env->SetMethod(target, "getHashes", GetHashes);
5040 env->SetMethod(target, "publicEncrypt",
5041 PublicKeyCipher::Cipher<PublicKeyCipher::kEncrypt,
5042 EVP_PKEY_encrypt_init,
5044 env->SetMethod(target, "privateDecrypt",
5045 PublicKeyCipher::Cipher<PublicKeyCipher::kDecrypt,
5046 EVP_PKEY_decrypt_init,
5050 } // namespace crypto
5053 NODE_MODULE_CONTEXT_AWARE_BUILTIN(crypto, node::crypto::InitCrypto)