1 // Copyright Joyent, Inc. and other Node contributors.
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #include "node_buffer.h"
24 #include "node_crypto.h"
25 #include "node_crypto_bio.h"
26 #include "node_crypto_groups.h"
27 #include "tls_wrap.h" // TLSCallbacks
29 #include "async-wrap.h"
30 #include "async-wrap-inl.h"
33 #include "string_bytes.h"
43 #define strcasecmp _stricmp
46 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
47 #define OPENSSL_CONST const
52 #define ASSERT_IS_STRING_OR_BUFFER(val) do { \
53 if (!Buffer::HasInstance(val) && !val->IsString()) { \
54 return env->ThrowTypeError("Not a string or buffer"); \
58 #define ASSERT_IS_BUFFER(val) do { \
59 if (!Buffer::HasInstance(val)) { \
60 return env->ThrowTypeError("Not a buffer"); \
64 static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----";
65 static const int PUBLIC_KEY_PFX_LEN = sizeof(PUBLIC_KEY_PFX) - 1;
66 static const char PUBRSA_KEY_PFX[] = "-----BEGIN RSA PUBLIC KEY-----";
67 static const int PUBRSA_KEY_PFX_LEN = sizeof(PUBRSA_KEY_PFX) - 1;
68 static const char CERTIFICATE_PFX[] = "-----BEGIN CERTIFICATE-----";
69 static const int CERTIFICATE_PFX_LEN = sizeof(CERTIFICATE_PFX) - 1;
71 static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
72 | ASN1_STRFLGS_ESC_MSB
73 | XN_FLAG_SEP_MULTILINE
82 using v8::EscapableHandleScope;
85 using v8::FunctionCallbackInfo;
86 using v8::FunctionTemplate;
88 using v8::HandleScope;
95 using v8::PropertyAttribute;
96 using v8::PropertyCallbackInfo;
102 // Forcibly clear OpenSSL's error stack on return. This stops stale errors
103 // from popping up later in the lifecycle of crypto operations where they
104 // would cause spurious failures. It's a rather blunt method, though.
105 // ERR_clear_error() isn't necessarily cheap either.
106 struct ClearErrorOnReturn {
107 ~ClearErrorOnReturn() { ERR_clear_error(); }
110 static uv_rwlock_t* locks;
112 const char* root_certs[] = {
113 #include "node_root_certs.h" // NOLINT(build/include_order)
117 X509_STORE* root_cert_store;
119 // Just to generate static methods
120 template class SSLWrap<TLSCallbacks>;
121 template void SSLWrap<TLSCallbacks>::AddMethods(Environment* env,
122 Handle<FunctionTemplate> t);
123 template void SSLWrap<TLSCallbacks>::InitNPN(SecureContext* sc,
125 template SSL_SESSION* SSLWrap<TLSCallbacks>::GetSessionCallback(
130 template int SSLWrap<TLSCallbacks>::NewSessionCallback(SSL* s,
132 template void SSLWrap<TLSCallbacks>::OnClientHello(
134 const ClientHelloParser::ClientHello& hello);
136 #ifdef OPENSSL_NPN_NEGOTIATED
137 template int SSLWrap<TLSCallbacks>::AdvertiseNextProtoCallback(
139 const unsigned char** data,
142 template int SSLWrap<TLSCallbacks>::SelectNextProtoCallback(
145 unsigned char* outlen,
146 const unsigned char* in,
150 template int SSLWrap<TLSCallbacks>::TLSExtStatusCallback(SSL* s, void* arg);
153 static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
154 CRYPTO_THREADID_set_numeric(tid, uv_thread_self());
158 static void crypto_lock_init(void) {
161 n = CRYPTO_num_locks();
162 locks = new uv_rwlock_t[n];
164 for (i = 0; i < n; i++)
165 if (uv_rwlock_init(locks + i))
170 static void crypto_lock_cb(int mode, int n, const char* file, int line) {
171 assert((mode & CRYPTO_LOCK) || (mode & CRYPTO_UNLOCK));
172 assert((mode & CRYPTO_READ) || (mode & CRYPTO_WRITE));
174 if (mode & CRYPTO_LOCK) {
175 if (mode & CRYPTO_READ)
176 uv_rwlock_rdlock(locks + n);
178 uv_rwlock_wrlock(locks + n);
180 if (mode & CRYPTO_READ)
181 uv_rwlock_rdunlock(locks + n);
183 uv_rwlock_wrunlock(locks + n);
188 static int CryptoPemCallback(char *buf, int size, int rwflag, void *u) {
190 size_t buflen = static_cast<size_t>(size);
191 size_t len = strlen(static_cast<const char*>(u));
192 len = len > buflen ? buflen : len;
201 void ThrowCryptoError(Environment* env,
203 const char* default_message = NULL) {
204 HandleScope scope(env->isolate());
205 if (err != 0 || default_message == NULL) {
206 char errmsg[128] = { 0 };
207 ERR_error_string_n(err, errmsg, sizeof(errmsg));
208 env->ThrowError(errmsg);
210 env->ThrowError(default_message);
215 // Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.
216 // The entropy pool starts out empty and needs to fill up before the PRNG
217 // can be used securely. Once the pool is filled, it never dries up again;
218 // its contents is stirred and reused when necessary.
220 // OpenSSL normally fills the pool automatically but not when someone starts
221 // generating random numbers before the pool is full: in that case OpenSSL
222 // keeps lowering the entropy estimate to thwart attackers trying to guess
223 // the initial state of the PRNG.
225 // When that happens, we will have to wait until enough entropy is available.
226 // That should normally never take longer than a few milliseconds.
228 // OpenSSL draws from /dev/random and /dev/urandom. While /dev/random may
229 // block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't
230 // block under normal circumstances.
232 // The only time when /dev/urandom may conceivably block is right after boot,
233 // when the whole system is still low on entropy. That's not something we can
234 // do anything about.
235 inline void CheckEntropy() {
237 int status = RAND_status();
238 CHECK_GE(status, 0); // Cannot fail.
242 // Give up, RAND_poll() not supported.
243 if (RAND_poll() == 0)
249 bool EntropySource(unsigned char* buffer, size_t length) {
250 // Ensure that OpenSSL's PRNG is properly seeded.
252 // RAND_bytes() can return 0 to indicate that the entropy data is not truly
253 // random. That's okay, it's still better than V8's stock source of entropy,
254 // which is /dev/urandom on UNIX platforms and the current time on Windows.
255 return RAND_bytes(buffer, length) != -1;
259 void SecureContext::Initialize(Environment* env, Handle<Object> target) {
260 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(),
262 t->InstanceTemplate()->SetInternalFieldCount(1);
263 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"));
265 NODE_SET_PROTOTYPE_METHOD(t, "init", SecureContext::Init);
266 NODE_SET_PROTOTYPE_METHOD(t, "setKey", SecureContext::SetKey);
267 NODE_SET_PROTOTYPE_METHOD(t, "setCert", SecureContext::SetCert);
268 NODE_SET_PROTOTYPE_METHOD(t, "addCACert", SecureContext::AddCACert);
269 NODE_SET_PROTOTYPE_METHOD(t, "addCRL", SecureContext::AddCRL);
270 NODE_SET_PROTOTYPE_METHOD(t, "addRootCerts", SecureContext::AddRootCerts);
271 NODE_SET_PROTOTYPE_METHOD(t, "setCiphers", SecureContext::SetCiphers);
272 NODE_SET_PROTOTYPE_METHOD(t, "setECDHCurve", SecureContext::SetECDHCurve);
273 NODE_SET_PROTOTYPE_METHOD(t, "setDHParam", SecureContext::SetDHParam);
274 NODE_SET_PROTOTYPE_METHOD(t, "setOptions", SecureContext::SetOptions);
275 NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
276 SecureContext::SetSessionIdContext);
277 NODE_SET_PROTOTYPE_METHOD(t, "setSessionTimeout",
278 SecureContext::SetSessionTimeout);
279 NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
280 NODE_SET_PROTOTYPE_METHOD(t, "loadPKCS12", SecureContext::LoadPKCS12);
281 NODE_SET_PROTOTYPE_METHOD(t, "getTicketKeys", SecureContext::GetTicketKeys);
282 NODE_SET_PROTOTYPE_METHOD(t, "setTicketKeys", SecureContext::SetTicketKeys);
283 NODE_SET_PROTOTYPE_METHOD(t,
285 SecureContext::GetCertificate<true>);
286 NODE_SET_PROTOTYPE_METHOD(t,
288 SecureContext::GetCertificate<false>);
290 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"),
292 env->set_secure_context_constructor_template(t);
296 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
297 HandleScope handle_scope(args.GetIsolate());
298 Environment* env = Environment::GetCurrent(args.GetIsolate());
299 new SecureContext(env, args.This());
303 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
304 HandleScope scope(args.GetIsolate());
306 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
307 Environment* env = sc->env();
309 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
311 if (args.Length() == 1 && args[0]->IsString()) {
312 const node::Utf8Value sslmethod(args[0]);
314 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
315 #ifndef OPENSSL_NO_SSL2
316 method = SSLv2_method();
318 return env->ThrowError("SSLv2 methods disabled");
320 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
321 #ifndef OPENSSL_NO_SSL2
322 method = SSLv2_server_method();
324 return env->ThrowError("SSLv2 methods disabled");
326 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
327 #ifndef OPENSSL_NO_SSL2
328 method = SSLv2_client_method();
330 return env->ThrowError("SSLv2 methods disabled");
332 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
333 method = SSLv3_method();
334 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
335 method = SSLv3_server_method();
336 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
337 method = SSLv3_client_method();
338 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
339 method = SSLv23_method();
340 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
341 method = SSLv23_server_method();
342 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
343 method = SSLv23_client_method();
344 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
345 method = TLSv1_method();
346 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
347 method = TLSv1_server_method();
348 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
349 method = TLSv1_client_method();
350 } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
351 method = TLSv1_1_method();
352 } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
353 method = TLSv1_1_server_method();
354 } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
355 method = TLSv1_1_client_method();
356 } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
357 method = TLSv1_2_method();
358 } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
359 method = TLSv1_2_server_method();
360 } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
361 method = TLSv1_2_client_method();
363 return env->ThrowError("Unknown method");
367 sc->ctx_ = SSL_CTX_new(method);
369 // SSL session cache configuration
370 SSL_CTX_set_session_cache_mode(sc->ctx_,
371 SSL_SESS_CACHE_SERVER |
372 SSL_SESS_CACHE_NO_INTERNAL |
373 SSL_SESS_CACHE_NO_AUTO_CLEAR);
374 SSL_CTX_sess_set_get_cb(sc->ctx_, SSLWrap<Connection>::GetSessionCallback);
375 SSL_CTX_sess_set_new_cb(sc->ctx_, SSLWrap<Connection>::NewSessionCallback);
377 sc->ca_store_ = NULL;
381 // Takes a string or buffer and loads it into a BIO.
382 // Caller responsible for BIO_free_all-ing the returned object.
383 static BIO* LoadBIO(Environment* env, Handle<Value> v) {
384 BIO* bio = NodeBIO::New();
388 HandleScope scope(env->isolate());
393 const node::Utf8Value s(v);
394 r = BIO_write(bio, *s, s.length());
395 } else if (Buffer::HasInstance(v)) {
396 char* buffer_data = Buffer::Data(v);
397 size_t buffer_length = Buffer::Length(v);
398 r = BIO_write(bio, buffer_data, buffer_length);
410 // Takes a string or buffer and loads it into an X509
411 // Caller responsible for X509_free-ing the returned object.
412 static X509* LoadX509(Environment* env, Handle<Value> v) {
413 HandleScope scope(env->isolate());
415 BIO *bio = LoadBIO(env, v);
419 X509 * x509 = PEM_read_bio_X509(bio, NULL, CryptoPemCallback, NULL);
430 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
431 Environment* env = Environment::GetCurrent(args.GetIsolate());
432 HandleScope scope(env->isolate());
434 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
436 unsigned int len = args.Length();
437 if (len != 1 && len != 2) {
438 return env->ThrowTypeError("Bad parameter");
440 if (len == 2 && !args[1]->IsString()) {
441 return env->ThrowTypeError("Bad parameter");
444 BIO *bio = LoadBIO(env, args[0]);
448 node::Utf8Value passphrase(args[1]);
450 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio,
453 len == 1 ? NULL : *passphrase);
457 unsigned long err = ERR_get_error();
459 return env->ThrowError("PEM_read_bio_PrivateKey");
461 return ThrowCryptoError(env, err);
464 SSL_CTX_use_PrivateKey(sc->ctx_, key);
470 int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) {
473 X509_STORE* store = SSL_CTX_get_cert_store(ctx);
474 X509_STORE_CTX store_ctx;
476 ret = X509_STORE_CTX_init(&store_ctx, store, NULL, NULL);
480 ret = X509_STORE_CTX_get1_issuer(issuer, &store_ctx, cert);
481 X509_STORE_CTX_cleanup(&store_ctx);
488 // Read a file that contains our certificate in "PEM" format,
489 // possibly followed by a sequence of CA certificates that should be
490 // sent to the peer in the Certificate message.
492 // Taken from OpenSSL - editted for style.
493 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
500 x = PEM_read_bio_X509_AUX(in, NULL, CryptoPemCallback, NULL);
503 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
507 ret = SSL_CTX_use_certificate(ctx, x);
509 if (ERR_peek_error() != 0) {
510 // Key/certificate mismatch doesn't imply ret==0 ...
515 // If we could set up our certificate, now proceed to
516 // the CA certificates.
521 if (ctx->extra_certs != NULL) {
522 sk_X509_pop_free(ctx->extra_certs, X509_free);
523 ctx->extra_certs = NULL;
526 while ((ca = PEM_read_bio_X509(in, NULL, CryptoPemCallback, NULL))) {
527 r = SSL_CTX_add_extra_chain_cert(ctx, ca);
534 // Note that we must not free r if it was successfully
535 // added to the chain (while we must free the main
536 // certificate, since its reference count is increased
537 // by SSL_CTX_use_certificate).
540 if (*issuer != NULL || X509_check_issued(ca, x) != X509_V_OK)
545 // When the while loop ends, it's usually just EOF.
546 err = ERR_peek_last_error();
547 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
548 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
556 // Try getting issuer from a cert store
558 if (*issuer == NULL) {
559 ret = SSL_CTX_get_issuer(ctx, x, issuer);
560 ret = ret < 0 ? 0 : 1;
561 // NOTE: get_cert_store doesn't increment reference count,
562 // no need to free `store`
564 // Increment issuer reference count
565 CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
576 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
577 Environment* env = Environment::GetCurrent(args.GetIsolate());
578 HandleScope scope(env->isolate());
580 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
582 if (args.Length() != 1) {
583 return env->ThrowTypeError("Bad parameter");
586 BIO* bio = LoadBIO(env, args[0]);
590 int rv = SSL_CTX_use_certificate_chain(sc->ctx_,
598 unsigned long err = ERR_get_error();
600 return env->ThrowError("SSL_CTX_use_certificate_chain");
602 return ThrowCryptoError(env, err);
607 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
608 bool newCAStore = false;
609 Environment* env = Environment::GetCurrent(args.GetIsolate());
610 HandleScope scope(env->isolate());
612 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
614 if (args.Length() != 1) {
615 return env->ThrowTypeError("Bad parameter");
618 if (!sc->ca_store_) {
619 sc->ca_store_ = X509_STORE_new();
623 X509* x509 = LoadX509(env, args[0]);
627 X509_STORE_add_cert(sc->ca_store_, x509);
628 SSL_CTX_add_client_CA(sc->ctx_, x509);
633 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
638 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
639 Environment* env = Environment::GetCurrent(args.GetIsolate());
640 HandleScope scope(env->isolate());
642 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
644 if (args.Length() != 1) {
645 return env->ThrowTypeError("Bad parameter");
648 ClearErrorOnReturn clear_error_on_return;
649 (void) &clear_error_on_return; // Silence compiler warning.
651 BIO *bio = LoadBIO(env, args[0]);
655 X509_CRL *x509 = PEM_read_bio_X509_CRL(bio, NULL, CryptoPemCallback, NULL);
662 X509_STORE_add_crl(sc->ca_store_, x509);
663 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
664 X509_V_FLAG_CRL_CHECK_ALL);
671 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
672 HandleScope scope(args.GetIsolate());
674 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
676 assert(sc->ca_store_ == NULL);
678 if (!root_cert_store) {
679 root_cert_store = X509_STORE_new();
681 for (int i = 0; root_certs[i]; i++) {
682 BIO* bp = NodeBIO::New();
684 if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
689 X509 *x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
696 X509_STORE_add_cert(root_cert_store, x509);
703 sc->ca_store_ = root_cert_store;
704 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
708 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
709 HandleScope scope(args.GetIsolate());
711 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
713 if (args.Length() != 1 || !args[0]->IsString()) {
714 return sc->env()->ThrowTypeError("Bad parameter");
717 const node::Utf8Value ciphers(args[0]);
718 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
722 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
723 HandleScope scope(args.GetIsolate());
725 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
726 Environment* env = sc->env();
728 if (args.Length() != 1 || !args[0]->IsString())
729 return env->ThrowTypeError("First argument should be a string");
731 node::Utf8Value curve(args[0]);
733 int nid = OBJ_sn2nid(*curve);
735 if (nid == NID_undef)
736 return env->ThrowTypeError("First argument should be a valid curve name");
738 EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
741 return env->ThrowTypeError("First argument should be a valid curve name");
743 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
744 SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
750 void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
751 HandleScope scope(args.GetIsolate());
753 SecureContext* sc = Unwrap<SecureContext>(args.This());
754 Environment* env = sc->env();
756 // Auto DH is not supported in openssl 1.0.1, so dhparam needs
757 // to be specifed explicitly
758 if (args.Length() != 1)
759 return env->ThrowTypeError("Bad parameter");
761 // Invalid dhparam is silently discarded and DHE is no longer used.
762 BIO* bio = LoadBIO(env, args[0]);
766 DH* dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
772 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_DH_USE);
773 int r = SSL_CTX_set_tmp_dh(sc->ctx_, dh);
777 return env->ThrowTypeError("Error setting temp DH parameter");
781 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
782 HandleScope scope(args.GetIsolate());
784 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
786 if (args.Length() != 1 || !args[0]->IntegerValue()) {
787 return sc->env()->ThrowTypeError("Bad parameter");
790 SSL_CTX_set_options(sc->ctx_, static_cast<long>(args[0]->IntegerValue()));
794 void SecureContext::SetSessionIdContext(
795 const FunctionCallbackInfo<Value>& args) {
796 HandleScope scope(args.GetIsolate());
798 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
800 if (args.Length() != 1 || !args[0]->IsString()) {
801 return sc->env()->ThrowTypeError("Bad parameter");
804 const node::Utf8Value sessionIdContext(args[0]);
805 const unsigned char* sid_ctx =
806 reinterpret_cast<const unsigned char*>(*sessionIdContext);
807 unsigned int sid_ctx_len = sessionIdContext.length();
809 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
815 Local<String> message;
817 bio = BIO_new(BIO_s_mem());
819 message = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
820 "SSL_CTX_set_session_id_context error");
822 ERR_print_errors(bio);
823 BIO_get_mem_ptr(bio, &mem);
824 message = OneByteString(args.GetIsolate(), mem->data, mem->length);
828 args.GetIsolate()->ThrowException(Exception::TypeError(message));
832 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
833 HandleScope scope(args.GetIsolate());
835 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
837 if (args.Length() != 1 || !args[0]->IsInt32()) {
838 return sc->env()->ThrowTypeError("Bad parameter");
841 int32_t sessionTimeout = args[0]->Int32Value();
842 SSL_CTX_set_timeout(sc->ctx_, sessionTimeout);
846 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
847 HandleScope scope(args.GetIsolate());
848 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
853 // Takes .pfx or .p12 and password in string or buffer format
854 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
855 Environment* env = Environment::GetCurrent(args.GetIsolate());
856 HandleScope scope(env->isolate());
860 EVP_PKEY* pkey = NULL;
862 STACK_OF(X509)* extraCerts = NULL;
866 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
868 if (args.Length() < 1) {
869 return env->ThrowTypeError("Bad parameter");
872 in = LoadBIO(env, args[0]);
874 return env->ThrowError("Unable to load BIO");
877 if (args.Length() >= 2) {
878 ASSERT_IS_BUFFER(args[1]);
879 size_t passlen = Buffer::Length(args[1]);
880 pass = new char[passlen + 1];
881 memcpy(pass, Buffer::Data(args[1]), passlen);
882 pass[passlen] = '\0';
885 if (d2i_PKCS12_bio(in, &p12) &&
886 PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
887 SSL_CTX_use_certificate(sc->ctx_, cert) &&
888 SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) {
890 while (X509* x509 = sk_X509_pop(extraCerts)) {
891 if (!sc->ca_store_) {
892 sc->ca_store_ = X509_STORE_new();
893 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
896 X509_STORE_add_cert(sc->ca_store_, x509);
897 SSL_CTX_add_client_CA(sc->ctx_, x509);
903 sk_X509_free(extraCerts);
913 unsigned long err = ERR_get_error();
914 const char* str = ERR_reason_error_string(err);
915 return env->ThrowError(str);
920 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
921 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
922 HandleScope handle_scope(args.GetIsolate());
924 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
926 Local<Object> buff = Buffer::New(wrap->env(), 48);
927 if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_,
929 Buffer::Length(buff)) != 1) {
930 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
933 args.GetReturnValue().Set(buff);
934 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
938 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
939 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
940 HandleScope scope(args.GetIsolate());
941 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
943 if (args.Length() < 1 ||
944 !Buffer::HasInstance(args[0]) ||
945 Buffer::Length(args[0]) != 48) {
946 return wrap->env()->ThrowTypeError("Bad argument");
949 if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_,
950 Buffer::Data(args[0]),
951 Buffer::Length(args[0])) != 1) {
952 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
955 args.GetReturnValue().Set(true);
956 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
960 template <bool primary>
961 void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
962 HandleScope scope(args.GetIsolate());
963 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
964 Environment* env = wrap->env();
970 cert = wrap->issuer_;
972 return args.GetReturnValue().Set(Null(env->isolate()));
974 int size = i2d_X509(cert, NULL);
975 Local<Object> buff = Buffer::New(env, size);
976 unsigned char* serialized = reinterpret_cast<unsigned char*>(
978 i2d_X509(cert, &serialized);
980 args.GetReturnValue().Set(buff);
984 template <class Base>
985 void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
986 HandleScope scope(env->isolate());
988 NODE_SET_PROTOTYPE_METHOD(t, "getPeerCertificate", GetPeerCertificate);
989 NODE_SET_PROTOTYPE_METHOD(t, "getSession", GetSession);
990 NODE_SET_PROTOTYPE_METHOD(t, "setSession", SetSession);
991 NODE_SET_PROTOTYPE_METHOD(t, "loadSession", LoadSession);
992 NODE_SET_PROTOTYPE_METHOD(t, "isSessionReused", IsSessionReused);
993 NODE_SET_PROTOTYPE_METHOD(t, "isInitFinished", IsInitFinished);
994 NODE_SET_PROTOTYPE_METHOD(t, "verifyError", VerifyError);
995 NODE_SET_PROTOTYPE_METHOD(t, "getCurrentCipher", GetCurrentCipher);
996 NODE_SET_PROTOTYPE_METHOD(t, "endParser", EndParser);
997 NODE_SET_PROTOTYPE_METHOD(t, "renegotiate", Renegotiate);
998 NODE_SET_PROTOTYPE_METHOD(t, "shutdown", Shutdown);
999 NODE_SET_PROTOTYPE_METHOD(t, "getTLSTicket", GetTLSTicket);
1000 NODE_SET_PROTOTYPE_METHOD(t, "newSessionDone", NewSessionDone);
1001 NODE_SET_PROTOTYPE_METHOD(t, "setOCSPResponse", SetOCSPResponse);
1002 NODE_SET_PROTOTYPE_METHOD(t, "requestOCSP", RequestOCSP);
1004 #ifdef SSL_set_max_send_fragment
1005 NODE_SET_PROTOTYPE_METHOD(t, "setMaxSendFragment", SetMaxSendFragment);
1006 #endif // SSL_set_max_send_fragment
1008 #ifdef OPENSSL_NPN_NEGOTIATED
1009 NODE_SET_PROTOTYPE_METHOD(t, "getNegotiatedProtocol", GetNegotiatedProto);
1010 NODE_SET_PROTOTYPE_METHOD(t, "setNPNProtocols", SetNPNProtocols);
1011 #endif // OPENSSL_NPN_NEGOTIATED
1015 template <class Base>
1016 void SSLWrap<Base>::InitNPN(SecureContext* sc, Base* base) {
1017 if (base->is_server()) {
1018 #ifdef OPENSSL_NPN_NEGOTIATED
1019 // Server should advertise NPN protocols
1020 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
1021 AdvertiseNextProtoCallback,
1023 #endif // OPENSSL_NPN_NEGOTIATED
1025 #ifdef OPENSSL_NPN_NEGOTIATED
1026 // Client should select protocol from list of advertised
1027 // If server supports NPN
1028 SSL_CTX_set_next_proto_select_cb(sc->ctx_, SelectNextProtoCallback, base);
1029 #endif // OPENSSL_NPN_NEGOTIATED
1032 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1034 SSL_CTX_set_tlsext_status_cb(sc->ctx_, TLSExtStatusCallback);
1035 SSL_CTX_set_tlsext_status_arg(sc->ctx_, base);
1036 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1040 template <class Base>
1041 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
1045 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1048 SSL_SESSION* sess = w->next_sess_;
1049 w->next_sess_ = NULL;
1055 template <class Base>
1056 int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
1057 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1058 Environment* env = w->ssl_env();
1059 HandleScope handle_scope(env->isolate());
1060 Context::Scope context_scope(env->context());
1062 if (!w->session_callbacks_)
1065 // Check if session is small enough to be stored
1066 int size = i2d_SSL_SESSION(sess, NULL);
1067 if (size > SecureContext::kMaxSessionSize)
1070 // Serialize session
1071 Local<Object> buff = Buffer::New(env, size);
1072 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1073 Buffer::Data(buff));
1074 memset(serialized, 0, size);
1075 i2d_SSL_SESSION(sess, &serialized);
1077 Local<Object> session = Buffer::New(env,
1078 reinterpret_cast<char*>(sess->session_id),
1079 sess->session_id_length);
1080 Local<Value> argv[] = { session, buff };
1081 w->new_session_wait_ = true;
1082 w->MakeCallback(env->onnewsession_string(), ARRAY_SIZE(argv), argv);
1088 template <class Base>
1089 void SSLWrap<Base>::OnClientHello(void* arg,
1090 const ClientHelloParser::ClientHello& hello) {
1091 Base* w = static_cast<Base*>(arg);
1092 Environment* env = w->ssl_env();
1093 HandleScope handle_scope(env->isolate());
1094 Context::Scope context_scope(env->context());
1096 Local<Object> hello_obj = Object::New(env->isolate());
1097 Local<Object> buff = Buffer::New(
1099 reinterpret_cast<const char*>(hello.session_id()),
1100 hello.session_size());
1101 hello_obj->Set(env->session_id_string(), buff);
1102 if (hello.servername() == NULL) {
1103 hello_obj->Set(env->servername_string(), String::Empty(env->isolate()));
1105 Local<String> servername = OneByteString(env->isolate(),
1107 hello.servername_size());
1108 hello_obj->Set(env->servername_string(), servername);
1110 hello_obj->Set(env->tls_ticket_string(),
1111 Boolean::New(env->isolate(), hello.has_ticket()));
1112 hello_obj->Set(env->ocsp_request_string(),
1113 Boolean::New(env->isolate(), hello.ocsp_request()));
1115 Local<Value> argv[] = { hello_obj };
1116 w->MakeCallback(env->onclienthello_string(), ARRAY_SIZE(argv), argv);
1120 static Local<Object> X509ToObject(Environment* env, X509* cert) {
1121 EscapableHandleScope scope(env->isolate());
1123 Local<Object> info = Object::New(env->isolate());
1125 BIO* bio = BIO_new(BIO_s_mem());
1127 if (X509_NAME_print_ex(bio,
1128 X509_get_subject_name(cert),
1130 X509_NAME_FLAGS) > 0) {
1131 BIO_get_mem_ptr(bio, &mem);
1132 info->Set(env->subject_string(),
1133 OneByteString(env->isolate(), mem->data, mem->length));
1135 (void) BIO_reset(bio);
1137 X509_NAME* issuer_name = X509_get_issuer_name(cert);
1138 if (X509_NAME_print_ex(bio, issuer_name, 0, X509_NAME_FLAGS) > 0) {
1139 BIO_get_mem_ptr(bio, &mem);
1140 info->Set(env->issuer_string(),
1141 OneByteString(env->isolate(), mem->data, mem->length));
1143 (void) BIO_reset(bio);
1145 int nids[] = { NID_subject_alt_name, NID_info_access };
1146 Local<String> keys[] = { env->subjectaltname_string(),
1147 env->infoaccess_string() };
1148 CHECK_EQ(ARRAY_SIZE(nids), ARRAY_SIZE(keys));
1149 for (unsigned int i = 0; i < ARRAY_SIZE(nids); i++) {
1150 int index = X509_get_ext_by_NID(cert, nids[i], -1);
1154 X509_EXTENSION* ext;
1157 ext = X509_get_ext(cert, index);
1158 assert(ext != NULL);
1160 rv = X509V3_EXT_print(bio, ext, 0, 0);
1163 BIO_get_mem_ptr(bio, &mem);
1165 OneByteString(env->isolate(), mem->data, mem->length));
1167 (void) BIO_reset(bio);
1170 EVP_PKEY* pkey = X509_get_pubkey(cert);
1173 rsa = EVP_PKEY_get1_RSA(pkey);
1176 BN_print(bio, rsa->n);
1177 BIO_get_mem_ptr(bio, &mem);
1178 info->Set(env->modulus_string(),
1179 OneByteString(env->isolate(), mem->data, mem->length));
1180 (void) BIO_reset(bio);
1182 BN_print(bio, rsa->e);
1183 BIO_get_mem_ptr(bio, &mem);
1184 info->Set(env->exponent_string(),
1185 OneByteString(env->isolate(), mem->data, mem->length));
1186 (void) BIO_reset(bio);
1190 EVP_PKEY_free(pkey);
1198 ASN1_TIME_print(bio, X509_get_notBefore(cert));
1199 BIO_get_mem_ptr(bio, &mem);
1200 info->Set(env->valid_from_string(),
1201 OneByteString(env->isolate(), mem->data, mem->length));
1202 (void) BIO_reset(bio);
1204 ASN1_TIME_print(bio, X509_get_notAfter(cert));
1205 BIO_get_mem_ptr(bio, &mem);
1206 info->Set(env->valid_to_string(),
1207 OneByteString(env->isolate(), mem->data, mem->length));
1210 unsigned int md_size, i;
1211 unsigned char md[EVP_MAX_MD_SIZE];
1212 if (X509_digest(cert, EVP_sha1(), md, &md_size)) {
1213 const char hex[] = "0123456789ABCDEF";
1214 char fingerprint[EVP_MAX_MD_SIZE * 3];
1216 // TODO(indutny): Unify it with buffer's code
1217 for (i = 0; i < md_size; i++) {
1218 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1219 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1220 fingerprint[(3*i)+2] = ':';
1224 fingerprint[(3*(md_size-1))+2] = '\0';
1226 fingerprint[0] = '\0';
1229 info->Set(env->fingerprint_string(),
1230 OneByteString(env->isolate(), fingerprint));
1233 STACK_OF(ASN1_OBJECT)* eku = static_cast<STACK_OF(ASN1_OBJECT)*>(
1234 X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL));
1236 Local<Array> ext_key_usage = Array::New(env->isolate());
1240 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1241 if (OBJ_obj2txt(buf, sizeof(buf), sk_ASN1_OBJECT_value(eku, i), 1) >= 0)
1242 ext_key_usage->Set(j++, OneByteString(env->isolate(), buf));
1245 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1246 info->Set(env->ext_key_usage_string(), ext_key_usage);
1249 if (ASN1_INTEGER* serial_number = X509_get_serialNumber(cert)) {
1250 if (BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, NULL)) {
1251 if (char* buf = BN_bn2hex(bn)) {
1252 info->Set(env->serial_number_string(),
1253 OneByteString(env->isolate(), buf));
1260 // Raw DER certificate
1261 int size = i2d_X509(cert, NULL);
1262 Local<Object> buff = Buffer::New(env, size);
1263 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1264 Buffer::Data(buff));
1265 i2d_X509(cert, &serialized);
1266 info->Set(env->raw_string(), buff);
1268 return scope.Escape(info);
1272 // TODO(indutny): Split it into multiple smaller functions
1273 template <class Base>
1274 void SSLWrap<Base>::GetPeerCertificate(
1275 const FunctionCallbackInfo<Value>& args) {
1276 HandleScope scope(args.GetIsolate());
1278 Base* w = Unwrap<Base>(args.Holder());
1279 Environment* env = w->ssl_env();
1281 ClearErrorOnReturn clear_error_on_return;
1282 (void) &clear_error_on_return; // Silence unused variable warning.
1284 Local<Object> result;
1287 // NOTE: This is because of the odd OpenSSL behavior. On client `cert_chain`
1288 // contains the `peer_certificate`, but on server it doesn't
1289 X509* cert = w->is_server() ? SSL_get_peer_certificate(w->ssl_) : NULL;
1290 STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(w->ssl_);
1291 STACK_OF(X509)* peer_certs = NULL;
1292 if (cert == NULL && ssl_certs == NULL)
1295 if (cert == NULL && sk_X509_num(ssl_certs) == 0)
1298 // Short result requested
1299 if (args.Length() < 1 || !args[0]->IsTrue()) {
1300 result = X509ToObject(env,
1301 cert == NULL ? sk_X509_value(ssl_certs, 0) : cert);
1305 // Clone `ssl_certs`, because we are going to destruct it
1306 peer_certs = sk_X509_new(NULL);
1308 sk_X509_push(peer_certs, cert);
1309 for (int i = 0; i < sk_X509_num(ssl_certs); i++) {
1310 cert = X509_dup(sk_X509_value(ssl_certs, i));
1313 if (!sk_X509_push(peer_certs, cert))
1317 // First and main certificate
1318 cert = sk_X509_value(peer_certs, 0);
1319 result = X509ToObject(env, cert);
1322 // Put issuer inside the object
1323 cert = sk_X509_delete(peer_certs, 0);
1324 while (sk_X509_num(peer_certs) > 0) {
1326 for (i = 0; i < sk_X509_num(peer_certs); i++) {
1327 X509* ca = sk_X509_value(peer_certs, i);
1328 if (X509_check_issued(ca, cert) != X509_V_OK)
1331 Local<Object> ca_info = X509ToObject(env, ca);
1332 info->Set(env->issuercert_string(), ca_info);
1335 // NOTE: Intentionally freeing cert that is not used anymore
1338 // Delete cert and continue aggregating issuers
1339 cert = sk_X509_delete(peer_certs, i);
1343 // Issuer not found, break out of the loop
1344 if (i == sk_X509_num(peer_certs))
1348 // Last certificate should be self-signed
1349 while (X509_check_issued(cert, cert) != X509_V_OK) {
1351 if (SSL_CTX_get_issuer(w->ssl_->ctx, cert, &ca) <= 0)
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
1365 // Self-issued certificate
1366 if (X509_check_issued(cert, cert) == X509_V_OK)
1367 info->Set(env->issuercert_string(), info);
1369 CHECK_NE(cert, NULL);
1373 if (peer_certs != NULL)
1374 sk_X509_pop_free(peer_certs, X509_free);
1375 if (result.IsEmpty())
1376 result = Object::New(env->isolate());
1377 args.GetReturnValue().Set(result);
1381 template <class Base>
1382 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
1383 Environment* env = Environment::GetCurrent(args.GetIsolate());
1384 HandleScope scope(env->isolate());
1386 Base* w = Unwrap<Base>(args.Holder());
1388 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1392 int slen = i2d_SSL_SESSION(sess, NULL);
1395 unsigned char* sbuf = new unsigned char[slen];
1396 unsigned char* p = sbuf;
1397 i2d_SSL_SESSION(sess, &p);
1398 args.GetReturnValue().Set(Encode(env->isolate(), sbuf, slen, BUFFER));
1403 template <class Base>
1404 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
1405 Environment* env = Environment::GetCurrent(args.GetIsolate());
1406 HandleScope scope(env->isolate());
1408 Base* w = Unwrap<Base>(args.Holder());
1410 if (args.Length() < 1 ||
1411 (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
1412 return env->ThrowTypeError("Bad argument");
1415 ASSERT_IS_BUFFER(args[0]);
1416 size_t slen = Buffer::Length(args[0]);
1417 char* sbuf = new char[slen];
1418 memcpy(sbuf, Buffer::Data(args[0]), slen);
1420 const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
1421 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, slen);
1428 int r = SSL_set_session(w->ssl_, sess);
1429 SSL_SESSION_free(sess);
1432 return env->ThrowError("SSL_set_session error");
1436 template <class Base>
1437 void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
1438 HandleScope scope(args.GetIsolate());
1440 Base* w = Unwrap<Base>(args.Holder());
1441 Environment* env = w->ssl_env();
1443 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1444 ssize_t slen = Buffer::Length(args[0]);
1445 char* sbuf = Buffer::Data(args[0]);
1447 const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1448 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, slen);
1450 // Setup next session and move hello to the BIO buffer
1451 if (w->next_sess_ != NULL)
1452 SSL_SESSION_free(w->next_sess_);
1453 w->next_sess_ = sess;
1455 Local<Object> info = Object::New(env->isolate());
1456 #ifndef OPENSSL_NO_TLSEXT
1457 if (sess->tlsext_hostname == NULL) {
1458 info->Set(env->servername_string(), False(args.GetIsolate()));
1460 info->Set(env->servername_string(),
1461 OneByteString(args.GetIsolate(), sess->tlsext_hostname));
1464 args.GetReturnValue().Set(info);
1469 template <class Base>
1470 void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
1471 HandleScope scope(args.GetIsolate());
1472 Base* w = Unwrap<Base>(args.Holder());
1473 bool yes = SSL_session_reused(w->ssl_);
1474 args.GetReturnValue().Set(yes);
1478 template <class Base>
1479 void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
1480 HandleScope scope(args.GetIsolate());
1481 Base* w = Unwrap<Base>(args.Holder());
1482 w->hello_parser_.End();
1486 template <class Base>
1487 void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
1488 HandleScope scope(args.GetIsolate());
1490 Base* w = Unwrap<Base>(args.Holder());
1492 ClearErrorOnReturn clear_error_on_return;
1493 (void) &clear_error_on_return; // Silence unused variable warning.
1495 bool yes = SSL_renegotiate(w->ssl_) == 1;
1496 args.GetReturnValue().Set(yes);
1500 template <class Base>
1501 void SSLWrap<Base>::Shutdown(const FunctionCallbackInfo<Value>& args) {
1502 HandleScope scope(args.GetIsolate());
1504 Base* w = Unwrap<Base>(args.Holder());
1506 int rv = SSL_shutdown(w->ssl_);
1507 args.GetReturnValue().Set(rv);
1511 template <class Base>
1512 void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
1513 HandleScope scope(args.GetIsolate());
1515 Base* w = Unwrap<Base>(args.Holder());
1516 Environment* env = w->ssl_env();
1518 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1519 if (sess == NULL || sess->tlsext_tick == NULL)
1522 Local<Object> buf = Buffer::New(env,
1523 reinterpret_cast<char*>(sess->tlsext_tick),
1524 sess->tlsext_ticklen);
1526 args.GetReturnValue().Set(buf);
1530 template <class Base>
1531 void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
1532 HandleScope scope(args.GetIsolate());
1534 Base* w = Unwrap<Base>(args.Holder());
1535 w->new_session_wait_ = false;
1536 w->NewSessionDoneCb();
1540 template <class Base>
1541 void SSLWrap<Base>::SetOCSPResponse(
1542 const v8::FunctionCallbackInfo<v8::Value>& args) {
1543 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1544 HandleScope scope(args.GetIsolate());
1546 Base* w = Unwrap<Base>(args.Holder());
1547 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1548 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1550 w->ocsp_response_.Reset(args.GetIsolate(), args[0].As<Object>());
1551 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1555 template <class Base>
1556 void SSLWrap<Base>::RequestOCSP(
1557 const v8::FunctionCallbackInfo<v8::Value>& args) {
1558 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1559 HandleScope scope(args.GetIsolate());
1561 Base* w = Unwrap<Base>(args.Holder());
1563 SSL_set_tlsext_status_type(w->ssl_, TLSEXT_STATUSTYPE_ocsp);
1564 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1568 #ifdef SSL_set_max_send_fragment
1569 template <class Base>
1570 void SSLWrap<Base>::SetMaxSendFragment(
1571 const v8::FunctionCallbackInfo<v8::Value>& args) {
1572 HandleScope scope(args.GetIsolate());
1573 CHECK(args.Length() >= 1 && args[0]->IsNumber());
1575 Base* w = Unwrap<Base>(args.Holder());
1577 int rv = SSL_set_max_send_fragment(w->ssl_, args[0]->Int32Value());
1578 args.GetReturnValue().Set(rv);
1580 #endif // SSL_set_max_send_fragment
1583 template <class Base>
1584 void SSLWrap<Base>::IsInitFinished(const FunctionCallbackInfo<Value>& args) {
1585 HandleScope scope(args.GetIsolate());
1586 Base* w = Unwrap<Base>(args.Holder());
1587 bool yes = SSL_is_init_finished(w->ssl_);
1588 args.GetReturnValue().Set(yes);
1592 template <class Base>
1593 void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
1594 HandleScope scope(args.GetIsolate());
1596 Base* w = Unwrap<Base>(args.Holder());
1598 // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
1599 // peer certificate is questionable but it's compatible with what was
1601 long x509_verify_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
1602 if (X509* peer_cert = SSL_get_peer_certificate(w->ssl_)) {
1603 X509_free(peer_cert);
1604 x509_verify_error = SSL_get_verify_result(w->ssl_);
1607 if (x509_verify_error == X509_V_OK)
1608 return args.GetReturnValue().SetNull();
1610 // XXX(bnoordhuis) X509_verify_cert_error_string() is not actually thread-safe
1611 // in the presence of invalid error codes. Probably academical but something
1612 // to keep in mind if/when node ever grows multi-isolate capabilities.
1613 const char* reason = X509_verify_cert_error_string(x509_verify_error);
1614 const char* code = reason;
1615 #define CASE_X509_ERR(CODE) case X509_V_ERR_##CODE: code = #CODE; break;
1616 switch (x509_verify_error) {
1617 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT)
1618 CASE_X509_ERR(UNABLE_TO_GET_CRL)
1619 CASE_X509_ERR(UNABLE_TO_DECRYPT_CERT_SIGNATURE)
1620 CASE_X509_ERR(UNABLE_TO_DECRYPT_CRL_SIGNATURE)
1621 CASE_X509_ERR(UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)
1622 CASE_X509_ERR(CERT_SIGNATURE_FAILURE)
1623 CASE_X509_ERR(CRL_SIGNATURE_FAILURE)
1624 CASE_X509_ERR(CERT_NOT_YET_VALID)
1625 CASE_X509_ERR(CERT_HAS_EXPIRED)
1626 CASE_X509_ERR(CRL_NOT_YET_VALID)
1627 CASE_X509_ERR(CRL_HAS_EXPIRED)
1628 CASE_X509_ERR(ERROR_IN_CERT_NOT_BEFORE_FIELD)
1629 CASE_X509_ERR(ERROR_IN_CERT_NOT_AFTER_FIELD)
1630 CASE_X509_ERR(ERROR_IN_CRL_LAST_UPDATE_FIELD)
1631 CASE_X509_ERR(ERROR_IN_CRL_NEXT_UPDATE_FIELD)
1632 CASE_X509_ERR(OUT_OF_MEM)
1633 CASE_X509_ERR(DEPTH_ZERO_SELF_SIGNED_CERT)
1634 CASE_X509_ERR(SELF_SIGNED_CERT_IN_CHAIN)
1635 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
1636 CASE_X509_ERR(UNABLE_TO_VERIFY_LEAF_SIGNATURE)
1637 CASE_X509_ERR(CERT_CHAIN_TOO_LONG)
1638 CASE_X509_ERR(CERT_REVOKED)
1639 CASE_X509_ERR(INVALID_CA)
1640 CASE_X509_ERR(PATH_LENGTH_EXCEEDED)
1641 CASE_X509_ERR(INVALID_PURPOSE)
1642 CASE_X509_ERR(CERT_UNTRUSTED)
1643 CASE_X509_ERR(CERT_REJECTED)
1645 #undef CASE_X509_ERR
1647 Isolate* isolate = args.GetIsolate();
1648 Local<String> reason_string = OneByteString(isolate, reason);
1649 Local<Value> exception_value = Exception::Error(reason_string);
1650 Local<Object> exception_object = exception_value->ToObject();
1651 exception_object->Set(FIXED_ONE_BYTE_STRING(isolate, "code"),
1652 OneByteString(isolate, code));
1653 args.GetReturnValue().Set(exception_object);
1657 template <class Base>
1658 void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
1659 HandleScope scope(args.GetIsolate());
1661 Base* w = Unwrap<Base>(args.Holder());
1662 Environment* env = w->ssl_env();
1664 OPENSSL_CONST SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_);
1668 Local<Object> info = Object::New(env->isolate());
1669 const char* cipher_name = SSL_CIPHER_get_name(c);
1670 info->Set(env->name_string(), OneByteString(args.GetIsolate(), cipher_name));
1671 const char* cipher_version = SSL_CIPHER_get_version(c);
1672 info->Set(env->version_string(),
1673 OneByteString(args.GetIsolate(), cipher_version));
1674 args.GetReturnValue().Set(info);
1678 #ifdef OPENSSL_NPN_NEGOTIATED
1679 template <class Base>
1680 int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s,
1681 const unsigned char** data,
1684 Base* w = static_cast<Base*>(arg);
1685 Environment* env = w->env();
1686 HandleScope handle_scope(env->isolate());
1687 Context::Scope context_scope(env->context());
1689 if (w->npn_protos_.IsEmpty()) {
1690 // No initialization - no NPN protocols
1691 *data = reinterpret_cast<const unsigned char*>("");
1694 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1695 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1696 *len = Buffer::Length(obj);
1699 return SSL_TLSEXT_ERR_OK;
1703 template <class Base>
1704 int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
1705 unsigned char** out,
1706 unsigned char* outlen,
1707 const unsigned char* in,
1710 Base* w = static_cast<Base*>(arg);
1711 Environment* env = w->env();
1712 HandleScope handle_scope(env->isolate());
1713 Context::Scope context_scope(env->context());
1715 // Release old protocol handler if present
1716 w->selected_npn_proto_.Reset();
1718 if (w->npn_protos_.IsEmpty()) {
1719 // We should at least select one protocol
1720 // If server is using NPN
1721 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
1724 // set status: unsupported
1725 w->selected_npn_proto_.Reset(env->isolate(), False(env->isolate()));
1727 return SSL_TLSEXT_ERR_OK;
1730 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1731 const unsigned char* npn_protos =
1732 reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1733 size_t len = Buffer::Length(obj);
1735 int status = SSL_select_next_proto(out, outlen, in, inlen, npn_protos, len);
1736 Handle<Value> result;
1738 case OPENSSL_NPN_UNSUPPORTED:
1739 result = Null(env->isolate());
1741 case OPENSSL_NPN_NEGOTIATED:
1742 result = OneByteString(env->isolate(), *out, *outlen);
1744 case OPENSSL_NPN_NO_OVERLAP:
1745 result = False(env->isolate());
1751 if (!result.IsEmpty())
1752 w->selected_npn_proto_.Reset(env->isolate(), result);
1754 return SSL_TLSEXT_ERR_OK;
1758 template <class Base>
1759 void SSLWrap<Base>::GetNegotiatedProto(
1760 const FunctionCallbackInfo<Value>& args) {
1761 HandleScope scope(args.GetIsolate());
1763 Base* w = Unwrap<Base>(args.Holder());
1765 if (w->is_client()) {
1766 if (w->selected_npn_proto_.IsEmpty() == false) {
1767 args.GetReturnValue().Set(w->selected_npn_proto_);
1772 const unsigned char* npn_proto;
1773 unsigned int npn_proto_len;
1775 SSL_get0_next_proto_negotiated(w->ssl_, &npn_proto, &npn_proto_len);
1778 return args.GetReturnValue().Set(false);
1780 args.GetReturnValue().Set(
1781 OneByteString(args.GetIsolate(), npn_proto, npn_proto_len));
1785 template <class Base>
1786 void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
1787 HandleScope scope(args.GetIsolate());
1789 Base* w = Unwrap<Base>(args.Holder());
1791 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1792 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1794 w->npn_protos_.Reset(args.GetIsolate(), args[0].As<Object>());
1796 #endif // OPENSSL_NPN_NEGOTIATED
1799 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1800 template <class Base>
1801 int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
1802 Base* w = static_cast<Base*>(arg);
1803 Environment* env = w->env();
1804 HandleScope handle_scope(env->isolate());
1806 if (w->is_client()) {
1807 // Incoming response
1808 const unsigned char* resp;
1809 int len = SSL_get_tlsext_status_ocsp_resp(s, &resp);
1812 arg = Null(env->isolate());
1816 reinterpret_cast<char*>(const_cast<unsigned char*>(resp)),
1820 w->MakeCallback(env->onocspresponse_string(), 1, &arg);
1822 // Somehow, client is expecting different return value here
1825 // Outgoing response
1826 if (w->ocsp_response_.IsEmpty())
1827 return SSL_TLSEXT_ERR_NOACK;
1829 Local<Object> obj = PersistentToLocal(env->isolate(), w->ocsp_response_);
1830 char* resp = Buffer::Data(obj);
1831 size_t len = Buffer::Length(obj);
1833 // OpenSSL takes control of the pointer after accepting it
1834 char* data = reinterpret_cast<char*>(malloc(len));
1835 assert(data != NULL);
1836 memcpy(data, resp, len);
1838 if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
1840 w->ocsp_response_.Reset();
1842 return SSL_TLSEXT_ERR_OK;
1845 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1848 void Connection::OnClientHelloParseEnd(void* arg) {
1849 Connection* conn = static_cast<Connection*>(arg);
1851 // Write all accumulated data
1852 int r = BIO_write(conn->bio_read_,
1853 reinterpret_cast<char*>(conn->hello_data_),
1854 conn->hello_offset_);
1855 conn->HandleBIOError(conn->bio_read_, "BIO_write", r);
1856 conn->SetShutdownFlags();
1860 #ifdef SSL_PRINT_DEBUG
1861 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
1863 # define DEBUG_PRINT(...)
1867 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
1871 int retry = BIO_should_retry(bio);
1872 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
1874 if (BIO_should_write(bio)) {
1875 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n",
1881 } else if (BIO_should_read(bio)) {
1882 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
1886 char ssl_error_buf[512];
1887 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
1889 HandleScope scope(ssl_env()->isolate());
1890 Local<Value> exception =
1891 Exception::Error(OneByteString(ssl_env()->isolate(), ssl_error_buf));
1892 object()->Set(ssl_env()->error_string(), exception);
1894 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
1907 int Connection::HandleSSLError(const char* func,
1911 ClearErrorOnReturn clear_error_on_return;
1912 (void) &clear_error_on_return; // Silence unused variable warning.
1916 if (rv == 0 && zs == kZeroIsNotAnError)
1919 int err = SSL_get_error(ssl_, rv);
1921 if (err == SSL_ERROR_NONE) {
1924 } else if (err == SSL_ERROR_WANT_WRITE) {
1925 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
1928 } else if (err == SSL_ERROR_WANT_READ) {
1929 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
1932 } else if (err == SSL_ERROR_ZERO_RETURN) {
1933 HandleScope scope(ssl_env()->isolate());
1935 Local<Value> exception =
1936 Exception::Error(ssl_env()->zero_return_string());
1937 object()->Set(ssl_env()->error_string(), exception);
1940 } else if (err == SSL_ERROR_SYSCALL && ss == kIgnoreSyscall) {
1944 HandleScope scope(ssl_env()->isolate());
1948 assert(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
1950 // XXX We need to drain the error queue for this thread or else OpenSSL
1951 // has the possibility of blocking connections? This problem is not well
1952 // understood. And we should be somehow propagating these errors up
1953 // into JavaScript. There is no test which demonstrates this problem.
1954 // https://github.com/joyent/node/issues/1719
1955 bio = BIO_new(BIO_s_mem());
1957 ERR_print_errors(bio);
1958 BIO_get_mem_ptr(bio, &mem);
1959 Local<Value> exception = Exception::Error(
1960 OneByteString(ssl_env()->isolate(),
1963 object()->Set(ssl_env()->error_string(), exception);
1974 void Connection::ClearError() {
1976 HandleScope scope(ssl_env()->isolate());
1978 // We should clear the error in JS-land
1979 Local<String> error_key = ssl_env()->error_string();
1980 Local<Value> error = object()->Get(error_key);
1981 assert(error->BooleanValue() == false);
1986 void Connection::SetShutdownFlags() {
1987 HandleScope scope(ssl_env()->isolate());
1989 int flags = SSL_get_shutdown(ssl_);
1991 if (flags & SSL_SENT_SHUTDOWN) {
1992 Local<String> sent_shutdown_key = ssl_env()->sent_shutdown_string();
1993 object()->Set(sent_shutdown_key, True(ssl_env()->isolate()));
1996 if (flags & SSL_RECEIVED_SHUTDOWN) {
1997 Local<String> received_shutdown_key = ssl_env()->received_shutdown_string();
1998 object()->Set(received_shutdown_key, True(ssl_env()->isolate()));
2003 void Connection::NewSessionDoneCb() {
2004 HandleScope scope(env()->isolate());
2006 MakeCallback(env()->onnewsessiondone_string(), 0, NULL);
2010 void Connection::Initialize(Environment* env, Handle<Object> target) {
2011 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(),
2013 t->InstanceTemplate()->SetInternalFieldCount(1);
2014 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"));
2016 NODE_SET_PROTOTYPE_METHOD(t, "encIn", Connection::EncIn);
2017 NODE_SET_PROTOTYPE_METHOD(t, "clearOut", Connection::ClearOut);
2018 NODE_SET_PROTOTYPE_METHOD(t, "clearIn", Connection::ClearIn);
2019 NODE_SET_PROTOTYPE_METHOD(t, "encOut", Connection::EncOut);
2020 NODE_SET_PROTOTYPE_METHOD(t, "clearPending", Connection::ClearPending);
2021 NODE_SET_PROTOTYPE_METHOD(t, "encPending", Connection::EncPending);
2022 NODE_SET_PROTOTYPE_METHOD(t, "start", Connection::Start);
2023 NODE_SET_PROTOTYPE_METHOD(t, "close", Connection::Close);
2025 SSLWrap<Connection>::AddMethods(env, t);
2027 #ifdef OPENSSL_NPN_NEGOTIATED
2028 NODE_SET_PROTOTYPE_METHOD(t,
2029 "getNegotiatedProtocol",
2030 Connection::GetNegotiatedProto);
2031 NODE_SET_PROTOTYPE_METHOD(t,
2033 Connection::SetNPNProtocols);
2037 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2038 NODE_SET_PROTOTYPE_METHOD(t, "getServername", Connection::GetServername);
2039 NODE_SET_PROTOTYPE_METHOD(t, "setSNICallback", Connection::SetSNICallback);
2042 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"),
2047 int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
2048 // Quoting SSL_set_verify(3ssl):
2050 // The VerifyCallback function is used to control the behaviour when
2051 // the SSL_VERIFY_PEER flag is set. It must be supplied by the
2052 // application and receives two arguments: preverify_ok indicates,
2053 // whether the verification of the certificate in question was passed
2054 // (preverify_ok=1) or not (preverify_ok=0). x509_ctx is a pointer to
2055 // the complete context used for the certificate chain verification.
2057 // The certificate chain is checked starting with the deepest nesting
2058 // level (the root CA certificate) and worked upward to the peer's
2059 // certificate. At each level signatures and issuer attributes are
2060 // checked. Whenever a verification error is found, the error number is
2061 // stored in x509_ctx and VerifyCallback is called with preverify_ok=0.
2062 // By applying X509_CTX_store_* functions VerifyCallback can locate the
2063 // certificate in question and perform additional steps (see EXAMPLES).
2064 // If no error is found for a certificate, VerifyCallback is called
2065 // with preverify_ok=1 before advancing to the next level.
2067 // The return value of VerifyCallback controls the strategy of the
2068 // further verification process. If VerifyCallback returns 0, the
2069 // verification process is immediately stopped with "verification
2070 // failed" state. If SSL_VERIFY_PEER is set, a verification failure
2071 // alert is sent to the peer and the TLS/SSL handshake is terminated. If
2072 // VerifyCallback returns 1, the verification process is continued. If
2073 // VerifyCallback always returns 1, the TLS/SSL handshake will not be
2074 // terminated with respect to verification failures and the connection
2075 // will be established. The calling process can however retrieve the
2076 // error code of the last verification error using
2077 // SSL_get_verify_result(3) or by maintaining its own error storage
2078 // managed by VerifyCallback.
2080 // If no VerifyCallback is specified, the default callback will be
2081 // used. Its return value is identical to preverify_ok, so that any
2082 // verification failure will lead to a termination of the TLS/SSL
2083 // handshake with an alert message, if SSL_VERIFY_PEER is set.
2085 // Since we cannot perform I/O quickly enough in this callback, we ignore
2086 // all preverify_ok errors and let the handshake continue. It is
2087 // imparative that the user use Connection::VerifyError after the
2088 // 'secure' callback has been made.
2093 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2094 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
2095 Connection* conn = static_cast<Connection*>(SSL_get_app_data(s));
2096 Environment* env = conn->env();
2097 HandleScope scope(env->isolate());
2099 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
2102 conn->servername_.Reset(env->isolate(),
2103 OneByteString(env->isolate(), servername));
2105 // Call the SNI callback and use its return value as context
2106 if (!conn->sniObject_.IsEmpty()) {
2107 conn->sniContext_.Reset();
2109 Local<Value> arg = PersistentToLocal(env->isolate(), conn->servername_);
2110 Local<Value> ret = conn->MakeCallback(env->onselect_string(), 1, &arg);
2112 // If ret is SecureContext
2113 Local<FunctionTemplate> secure_context_constructor_template =
2114 env->secure_context_constructor_template();
2115 if (secure_context_constructor_template->HasInstance(ret)) {
2116 conn->sniContext_.Reset(env->isolate(), ret);
2117 SecureContext* sc = Unwrap<SecureContext>(ret.As<Object>());
2119 SSL_set_SSL_CTX(s, sc->ctx_);
2121 return SSL_TLSEXT_ERR_NOACK;
2126 return SSL_TLSEXT_ERR_OK;
2130 void Connection::New(const FunctionCallbackInfo<Value>& args) {
2131 Environment* env = Environment::GetCurrent(args.GetIsolate());
2132 HandleScope scope(env->isolate());
2134 if (args.Length() < 1 || !args[0]->IsObject()) {
2135 env->ThrowError("First argument must be a tls module SecureContext");
2139 SecureContext* sc = Unwrap<SecureContext>(args[0]->ToObject());
2141 bool is_server = args[1]->BooleanValue();
2143 SSLWrap<Connection>::Kind kind =
2144 is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient;
2145 Connection* conn = new Connection(env, args.This(), sc, kind);
2146 conn->bio_read_ = NodeBIO::New();
2147 conn->bio_write_ = NodeBIO::New();
2149 SSL_set_app_data(conn->ssl_, conn);
2152 SSL_set_info_callback(conn->ssl_, SSLInfoCallback);
2156 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2158 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
2159 } else if (args[2]->IsString()) {
2160 const node::Utf8Value servername(args[2]);
2161 SSL_set_tlsext_host_name(conn->ssl_, *servername);
2165 SSL_set_bio(conn->ssl_, conn->bio_read_, conn->bio_write_);
2167 #ifdef SSL_MODE_RELEASE_BUFFERS
2168 long mode = SSL_get_mode(conn->ssl_);
2169 SSL_set_mode(conn->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
2175 bool request_cert = args[2]->BooleanValue();
2176 if (!request_cert) {
2177 // Note reject_unauthorized ignored.
2178 verify_mode = SSL_VERIFY_NONE;
2180 bool reject_unauthorized = args[3]->BooleanValue();
2181 verify_mode = SSL_VERIFY_PEER;
2182 if (reject_unauthorized)
2183 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2186 // Note request_cert and reject_unauthorized are ignored for clients.
2187 verify_mode = SSL_VERIFY_NONE;
2191 // Always allow a connection. We'll reject in javascript.
2192 SSL_set_verify(conn->ssl_, verify_mode, VerifyCallback);
2195 SSL_set_accept_state(conn->ssl_);
2197 SSL_set_connect_state(conn->ssl_);
2202 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
2203 if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
2206 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
2207 // a non-const SSL* in OpenSSL <= 0.9.7e.
2208 SSL* ssl = const_cast<SSL*>(ssl_);
2209 Connection* conn = static_cast<Connection*>(SSL_get_app_data(ssl));
2210 Environment* env = conn->env();
2211 HandleScope handle_scope(env->isolate());
2212 Context::Scope context_scope(env->context());
2214 if (where & SSL_CB_HANDSHAKE_START) {
2215 conn->MakeCallback(env->onhandshakestart_string(), 0, NULL);
2218 if (where & SSL_CB_HANDSHAKE_DONE) {
2219 conn->MakeCallback(env->onhandshakedone_string(), 0, NULL);
2224 void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
2225 HandleScope scope(args.GetIsolate());
2227 Connection* conn = Unwrap<Connection>(args.Holder());
2228 Environment* env = conn->env();
2230 if (args.Length() < 3) {
2231 return env->ThrowTypeError("Takes 3 parameters");
2234 if (!Buffer::HasInstance(args[0])) {
2235 return env->ThrowTypeError("Second argument should be a buffer");
2238 char* buffer_data = Buffer::Data(args[0]);
2239 size_t buffer_length = Buffer::Length(args[0]);
2241 size_t off = args[1]->Int32Value();
2242 size_t len = args[2]->Int32Value();
2244 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2245 return env->ThrowError("off + len > buffer.length");
2248 char* data = buffer_data + off;
2250 if (conn->is_server() && !conn->hello_parser_.IsEnded()) {
2251 // Just accumulate data, everything will be pushed to BIO later
2252 if (conn->hello_parser_.IsPaused()) {
2255 // Copy incoming data to the internal buffer
2256 // (which has a size of the biggest possible TLS frame)
2257 size_t available = sizeof(conn->hello_data_) - conn->hello_offset_;
2258 size_t copied = len < available ? len : available;
2259 memcpy(conn->hello_data_ + conn->hello_offset_, data, copied);
2260 conn->hello_offset_ += copied;
2262 conn->hello_parser_.Parse(conn->hello_data_, conn->hello_offset_);
2263 bytes_written = copied;
2266 bytes_written = BIO_write(conn->bio_read_, data, len);
2267 conn->HandleBIOError(conn->bio_read_, "BIO_write", bytes_written);
2268 conn->SetShutdownFlags();
2271 args.GetReturnValue().Set(bytes_written);
2275 void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
2276 HandleScope scope(args.GetIsolate());
2278 Connection* conn = Unwrap<Connection>(args.Holder());
2279 Environment* env = conn->env();
2281 if (args.Length() < 3) {
2282 return env->ThrowTypeError("Takes 3 parameters");
2285 if (!Buffer::HasInstance(args[0])) {
2286 return env->ThrowTypeError("Second argument should be a buffer");
2289 char* buffer_data = Buffer::Data(args[0]);
2290 size_t buffer_length = Buffer::Length(args[0]);
2292 size_t off = args[1]->Int32Value();
2293 size_t len = args[2]->Int32Value();
2295 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2296 return env->ThrowError("off + len > buffer.length");
2298 if (!SSL_is_init_finished(conn->ssl_)) {
2301 if (conn->is_server()) {
2302 rv = SSL_accept(conn->ssl_);
2303 conn->HandleSSLError("SSL_accept:ClearOut",
2308 rv = SSL_connect(conn->ssl_);
2309 conn->HandleSSLError("SSL_connect:ClearOut",
2316 return args.GetReturnValue().Set(rv);
2320 int bytes_read = SSL_read(conn->ssl_, buffer_data + off, len);
2321 conn->HandleSSLError("SSL_read:ClearOut",
2325 conn->SetShutdownFlags();
2327 args.GetReturnValue().Set(bytes_read);
2331 void Connection::ClearPending(const FunctionCallbackInfo<Value>& args) {
2332 HandleScope scope(args.GetIsolate());
2333 Connection* conn = Unwrap<Connection>(args.Holder());
2334 int bytes_pending = BIO_pending(conn->bio_read_);
2335 args.GetReturnValue().Set(bytes_pending);
2339 void Connection::EncPending(const FunctionCallbackInfo<Value>& args) {
2340 HandleScope scope(args.GetIsolate());
2341 Connection* conn = Unwrap<Connection>(args.Holder());
2342 int bytes_pending = BIO_pending(conn->bio_write_);
2343 args.GetReturnValue().Set(bytes_pending);
2347 void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
2348 HandleScope scope(args.GetIsolate());
2350 Connection* conn = Unwrap<Connection>(args.Holder());
2351 Environment* env = conn->env();
2353 if (args.Length() < 3) {
2354 return env->ThrowTypeError("Takes 3 parameters");
2357 if (!Buffer::HasInstance(args[0])) {
2358 return env->ThrowTypeError("Second argument should be a buffer");
2361 char* buffer_data = Buffer::Data(args[0]);
2362 size_t buffer_length = Buffer::Length(args[0]);
2364 size_t off = args[1]->Int32Value();
2365 size_t len = args[2]->Int32Value();
2367 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2368 return env->ThrowError("off + len > buffer.length");
2370 int bytes_read = BIO_read(conn->bio_write_, buffer_data + off, len);
2372 conn->HandleBIOError(conn->bio_write_, "BIO_read:EncOut", bytes_read);
2373 conn->SetShutdownFlags();
2375 args.GetReturnValue().Set(bytes_read);
2379 void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
2380 HandleScope scope(args.GetIsolate());
2382 Connection* conn = Unwrap<Connection>(args.Holder());
2383 Environment* env = conn->env();
2385 if (args.Length() < 3) {
2386 return env->ThrowTypeError("Takes 3 parameters");
2389 if (!Buffer::HasInstance(args[0])) {
2390 return env->ThrowTypeError("Second argument should be a buffer");
2393 char* buffer_data = Buffer::Data(args[0]);
2394 size_t buffer_length = Buffer::Length(args[0]);
2396 size_t off = args[1]->Int32Value();
2397 size_t len = args[2]->Int32Value();
2399 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2400 return env->ThrowError("off + len > buffer.length");
2402 if (!SSL_is_init_finished(conn->ssl_)) {
2404 if (conn->is_server()) {
2405 rv = SSL_accept(conn->ssl_);
2406 conn->HandleSSLError("SSL_accept:ClearIn",
2411 rv = SSL_connect(conn->ssl_);
2412 conn->HandleSSLError("SSL_connect:ClearIn",
2419 return args.GetReturnValue().Set(rv);
2423 int bytes_written = SSL_write(conn->ssl_, buffer_data + off, len);
2425 conn->HandleSSLError("SSL_write:ClearIn",
2427 len == 0 ? kZeroIsNotAnError : kZeroIsAnError,
2429 conn->SetShutdownFlags();
2431 args.GetReturnValue().Set(bytes_written);
2435 void Connection::Start(const FunctionCallbackInfo<Value>& args) {
2436 HandleScope scope(args.GetIsolate());
2438 Connection* conn = Unwrap<Connection>(args.Holder());
2441 if (!SSL_is_init_finished(conn->ssl_)) {
2442 if (conn->is_server()) {
2443 rv = SSL_accept(conn->ssl_);
2444 conn->HandleSSLError("SSL_accept:Start",
2449 rv = SSL_connect(conn->ssl_);
2450 conn->HandleSSLError("SSL_connect:Start",
2456 args.GetReturnValue().Set(rv);
2460 void Connection::Close(const FunctionCallbackInfo<Value>& args) {
2461 HandleScope scope(args.GetIsolate());
2463 Connection* conn = Unwrap<Connection>(args.Holder());
2465 if (conn->ssl_ != NULL) {
2466 SSL_free(conn->ssl_);
2472 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2473 void Connection::GetServername(const FunctionCallbackInfo<Value>& args) {
2474 HandleScope scope(args.GetIsolate());
2476 Connection* conn = Unwrap<Connection>(args.Holder());
2478 if (conn->is_server() && !conn->servername_.IsEmpty()) {
2479 args.GetReturnValue().Set(conn->servername_);
2481 args.GetReturnValue().Set(false);
2486 void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) {
2487 HandleScope scope(args.GetIsolate());
2489 Connection* conn = Unwrap<Connection>(args.Holder());
2490 Environment* env = conn->env();
2492 if (args.Length() < 1 || !args[0]->IsFunction()) {
2493 return env->ThrowError("Must give a Function as first argument");
2496 Local<Object> obj = Object::New(env->isolate());
2497 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "onselect"), args[0]);
2498 conn->sniObject_.Reset(args.GetIsolate(), obj);
2503 void CipherBase::Initialize(Environment* env, Handle<Object> target) {
2504 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
2506 t->InstanceTemplate()->SetInternalFieldCount(1);
2508 NODE_SET_PROTOTYPE_METHOD(t, "init", Init);
2509 NODE_SET_PROTOTYPE_METHOD(t, "initiv", InitIv);
2510 NODE_SET_PROTOTYPE_METHOD(t, "update", Update);
2511 NODE_SET_PROTOTYPE_METHOD(t, "final", Final);
2512 NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
2513 NODE_SET_PROTOTYPE_METHOD(t, "getAuthTag", GetAuthTag);
2514 NODE_SET_PROTOTYPE_METHOD(t, "setAuthTag", SetAuthTag);
2515 NODE_SET_PROTOTYPE_METHOD(t, "setAAD", SetAAD);
2517 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "CipherBase"),
2522 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
2523 assert(args.IsConstructCall() == true);
2524 HandleScope handle_scope(args.GetIsolate());
2525 CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
2526 Environment* env = Environment::GetCurrent(args.GetIsolate());
2527 new CipherBase(env, args.This(), kind);
2531 void CipherBase::Init(const char* cipher_type,
2532 const char* key_buf,
2534 HandleScope scope(env()->isolate());
2536 assert(cipher_ == NULL);
2537 cipher_ = EVP_get_cipherbyname(cipher_type);
2538 if (cipher_ == NULL) {
2539 return env()->ThrowError("Unknown cipher");
2542 unsigned char key[EVP_MAX_KEY_LENGTH];
2543 unsigned char iv[EVP_MAX_IV_LENGTH];
2545 int key_len = EVP_BytesToKey(cipher_,
2548 reinterpret_cast<const unsigned char*>(key_buf),
2554 EVP_CIPHER_CTX_init(&ctx_);
2555 EVP_CipherInit_ex(&ctx_, cipher_, NULL, NULL, NULL, kind_ == kCipher);
2556 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2557 EVP_CIPHER_CTX_cleanup(&ctx_);
2558 return env()->ThrowError("Invalid key length");
2561 EVP_CipherInit_ex(&ctx_,
2564 reinterpret_cast<unsigned char*>(key),
2565 reinterpret_cast<unsigned char*>(iv),
2567 initialised_ = true;
2571 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
2572 HandleScope scope(args.GetIsolate());
2574 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2576 if (args.Length() < 2 ||
2577 !(args[0]->IsString() && Buffer::HasInstance(args[1]))) {
2578 return cipher->env()->ThrowError("Must give cipher-type, key");
2581 const node::Utf8Value cipher_type(args[0]);
2582 const char* key_buf = Buffer::Data(args[1]);
2583 ssize_t key_buf_len = Buffer::Length(args[1]);
2584 cipher->Init(*cipher_type, key_buf, key_buf_len);
2588 void CipherBase::InitIv(const char* cipher_type,
2593 HandleScope scope(env()->isolate());
2595 cipher_ = EVP_get_cipherbyname(cipher_type);
2596 if (cipher_ == NULL) {
2597 return env()->ThrowError("Unknown cipher");
2600 /* OpenSSL versions up to 0.9.8l failed to return the correct
2601 iv_length (0) for ECB ciphers */
2602 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
2603 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2604 return env()->ThrowError("Invalid IV length");
2606 EVP_CIPHER_CTX_init(&ctx_);
2607 EVP_CipherInit_ex(&ctx_, cipher_, NULL, NULL, NULL, kind_ == kCipher);
2608 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2609 EVP_CIPHER_CTX_cleanup(&ctx_);
2610 return env()->ThrowError("Invalid key length");
2613 EVP_CipherInit_ex(&ctx_,
2616 reinterpret_cast<const unsigned char*>(key),
2617 reinterpret_cast<const unsigned char*>(iv),
2619 initialised_ = true;
2623 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
2624 HandleScope scope(args.GetIsolate());
2626 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2627 Environment* env = cipher->env();
2629 if (args.Length() < 3 || !args[0]->IsString()) {
2630 return env->ThrowError("Must give cipher-type, key, and iv as argument");
2633 ASSERT_IS_BUFFER(args[1]);
2634 ASSERT_IS_BUFFER(args[2]);
2636 const node::Utf8Value cipher_type(args[0]);
2637 ssize_t key_len = Buffer::Length(args[1]);
2638 const char* key_buf = Buffer::Data(args[1]);
2639 ssize_t iv_len = Buffer::Length(args[2]);
2640 const char* iv_buf = Buffer::Data(args[2]);
2641 cipher->InitIv(*cipher_type, key_buf, key_len, iv_buf, iv_len);
2645 bool CipherBase::IsAuthenticatedMode() const {
2646 // check if this cipher operates in an AEAD mode that we support.
2649 int mode = EVP_CIPHER_mode(cipher_);
2650 return mode == EVP_CIPH_GCM_MODE;
2654 bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
2655 // only callable after Final and if encrypting.
2656 if (initialised_ || kind_ != kCipher || !auth_tag_)
2658 *out_len = auth_tag_len_;
2659 *out = new char[auth_tag_len_];
2660 memcpy(*out, auth_tag_, auth_tag_len_);
2665 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
2666 Environment* env = Environment::GetCurrent(args.GetIsolate());
2667 HandleScope handle_scope(args.GetIsolate());
2668 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2671 unsigned int out_len = 0;
2673 if (cipher->GetAuthTag(&out, &out_len)) {
2674 Local<Object> buf = Buffer::Use(env, out, out_len);
2675 args.GetReturnValue().Set(buf);
2677 env->ThrowError("Attempting to get auth tag in unsupported state");
2682 bool CipherBase::SetAuthTag(const char* data, unsigned int len) {
2683 if (!initialised_ || !IsAuthenticatedMode() || kind_ != kDecipher)
2686 auth_tag_len_ = len;
2687 auth_tag_ = new char[len];
2688 memcpy(auth_tag_, data, len);
2693 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
2694 HandleScope handle_scope(args.GetIsolate());
2695 Environment* env = Environment::GetCurrent(args.GetIsolate());
2697 Local<Object> buf = args[0].As<Object>();
2698 if (!buf->IsObject() || !Buffer::HasInstance(buf))
2699 return env->ThrowTypeError("Argument must be a Buffer");
2701 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2703 if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf)))
2704 env->ThrowError("Attempting to set auth tag in unsupported state");
2708 bool CipherBase::SetAAD(const char* data, unsigned int len) {
2709 if (!initialised_ || !IsAuthenticatedMode())
2712 if (!EVP_CipherUpdate(&ctx_,
2715 reinterpret_cast<const unsigned char*>(data),
2723 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
2724 Environment* env = Environment::GetCurrent(args.GetIsolate());
2725 HandleScope handle_scope(env->isolate());
2727 ASSERT_IS_BUFFER(args[0]);
2729 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2731 if (!cipher->SetAAD(Buffer::Data(args[0]), Buffer::Length(args[0])))
2732 env->ThrowError("Attempting to set AAD in unsupported state");
2736 bool CipherBase::Update(const char* data,
2738 unsigned char** out,
2744 if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_ != NULL) {
2745 EVP_CIPHER_CTX_ctrl(&ctx_,
2746 EVP_CTRL_GCM_SET_TAG,
2748 reinterpret_cast<unsigned char*>(auth_tag_));
2753 *out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
2754 *out = new unsigned char[*out_len];
2755 return EVP_CipherUpdate(&ctx_,
2758 reinterpret_cast<const unsigned char*>(data),
2763 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
2764 HandleScope handle_scope(args.GetIsolate());
2765 Environment* env = Environment::GetCurrent(args.GetIsolate());
2767 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2769 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2771 unsigned char* out = NULL;
2775 // Only copy the data if we have to, because it's a string
2776 if (args[0]->IsString()) {
2777 Local<String> string = args[0].As<String>();
2778 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2779 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2780 return env->ThrowTypeError("Bad input string");
2781 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2782 char* buf = new char[buflen];
2783 size_t written = StringBytes::Write(env->isolate(),
2788 r = cipher->Update(buf, written, &out, &out_len);
2791 char* buf = Buffer::Data(args[0]);
2792 size_t buflen = Buffer::Length(args[0]);
2793 r = cipher->Update(buf, buflen, &out, &out_len);
2798 return ThrowCryptoError(env,
2800 "Trying to add data in unsupported state");
2803 Local<Object> buf = Buffer::New(env, reinterpret_cast<char*>(out), out_len);
2807 args.GetReturnValue().Set(buf);
2811 bool CipherBase::SetAutoPadding(bool auto_padding) {
2814 return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
2818 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
2819 HandleScope scope(args.GetIsolate());
2820 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2821 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2825 bool CipherBase::Final(unsigned char** out, int *out_len) {
2829 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx_)];
2830 int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
2832 if (r && kind_ == kCipher) {
2835 if (IsAuthenticatedMode()) {
2836 auth_tag_len_ = EVP_GCM_TLS_TAG_LEN; // use default tag length
2837 auth_tag_ = new char[auth_tag_len_];
2838 memset(auth_tag_, 0, auth_tag_len_);
2839 EVP_CIPHER_CTX_ctrl(&ctx_,
2840 EVP_CTRL_GCM_GET_TAG,
2842 reinterpret_cast<unsigned char*>(auth_tag_));
2846 EVP_CIPHER_CTX_cleanup(&ctx_);
2847 initialised_ = false;
2853 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
2854 HandleScope handle_scope(args.GetIsolate());
2855 Environment* env = Environment::GetCurrent(args.GetIsolate());
2857 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2859 unsigned char* out_value = NULL;
2861 Local<Value> outString;
2863 bool r = cipher->Final(&out_value, &out_len);
2865 if (out_len <= 0 || !r) {
2870 const char* msg = cipher->IsAuthenticatedMode() ?
2871 "Unsupported state or unable to authenticate data" :
2872 "Unsupported state";
2874 return ThrowCryptoError(env,
2880 args.GetReturnValue().Set(
2881 Buffer::New(env, reinterpret_cast<char*>(out_value), out_len));
2886 void Hmac::Initialize(Environment* env, v8::Handle<v8::Object> target) {
2887 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
2889 t->InstanceTemplate()->SetInternalFieldCount(1);
2891 NODE_SET_PROTOTYPE_METHOD(t, "init", HmacInit);
2892 NODE_SET_PROTOTYPE_METHOD(t, "update", HmacUpdate);
2893 NODE_SET_PROTOTYPE_METHOD(t, "digest", HmacDigest);
2895 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hmac"), t->GetFunction());
2899 void Hmac::New(const FunctionCallbackInfo<Value>& args) {
2900 HandleScope handle_scope(args.GetIsolate());
2901 Environment* env = Environment::GetCurrent(args.GetIsolate());
2902 new Hmac(env, args.This());
2906 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
2907 HandleScope scope(env()->isolate());
2909 assert(md_ == NULL);
2910 md_ = EVP_get_digestbyname(hash_type);
2912 return env()->ThrowError("Unknown message digest");
2914 HMAC_CTX_init(&ctx_);
2916 HMAC_Init(&ctx_, "", 0, md_);
2918 HMAC_Init(&ctx_, key, key_len, md_);
2920 initialised_ = true;
2924 void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
2925 HandleScope scope(args.GetIsolate());
2927 Hmac* hmac = Unwrap<Hmac>(args.Holder());
2928 Environment* env = hmac->env();
2930 if (args.Length() < 2 || !args[0]->IsString()) {
2931 return env->ThrowError("Must give hashtype string, key as arguments");
2934 ASSERT_IS_BUFFER(args[1]);
2936 const node::Utf8Value hash_type(args[0]);
2937 const char* buffer_data = Buffer::Data(args[1]);
2938 size_t buffer_length = Buffer::Length(args[1]);
2939 hmac->HmacInit(*hash_type, buffer_data, buffer_length);
2943 bool Hmac::HmacUpdate(const char* data, int len) {
2946 HMAC_Update(&ctx_, reinterpret_cast<const unsigned char*>(data), len);
2951 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
2952 Environment* env = Environment::GetCurrent(args.GetIsolate());
2953 HandleScope scope(env->isolate());
2955 Hmac* hmac = Unwrap<Hmac>(args.Holder());
2957 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2959 // Only copy the data if we have to, because it's a string
2961 if (args[0]->IsString()) {
2962 Local<String> string = args[0].As<String>();
2963 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2964 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2965 return env->ThrowTypeError("Bad input string");
2966 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2967 char* buf = new char[buflen];
2968 size_t written = StringBytes::Write(env->isolate(),
2973 r = hmac->HmacUpdate(buf, written);
2976 char* buf = Buffer::Data(args[0]);
2977 size_t buflen = Buffer::Length(args[0]);
2978 r = hmac->HmacUpdate(buf, buflen);
2982 return env->ThrowTypeError("HmacUpdate fail");
2987 bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
2990 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
2991 HMAC_Final(&ctx_, *md_value, md_len);
2992 HMAC_CTX_cleanup(&ctx_);
2993 initialised_ = false;
2998 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
2999 Environment* env = Environment::GetCurrent(args.GetIsolate());
3000 HandleScope scope(env->isolate());
3002 Hmac* hmac = Unwrap<Hmac>(args.Holder());
3004 enum encoding encoding = BUFFER;
3005 if (args.Length() >= 1) {
3006 encoding = ParseEncoding(env->isolate(), args[0]->ToString(), BUFFER);
3009 unsigned char* md_value = NULL;
3010 unsigned int md_len = 0;
3012 bool r = hmac->HmacDigest(&md_value, &md_len);
3018 Local<Value> rc = StringBytes::Encode(env->isolate(),
3019 reinterpret_cast<const char*>(md_value),
3023 args.GetReturnValue().Set(rc);
3027 void Hash::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3028 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
3030 t->InstanceTemplate()->SetInternalFieldCount(1);
3032 NODE_SET_PROTOTYPE_METHOD(t, "update", HashUpdate);
3033 NODE_SET_PROTOTYPE_METHOD(t, "digest", HashDigest);
3035 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hash"), t->GetFunction());
3039 void Hash::New(const FunctionCallbackInfo<Value>& args) {
3040 Environment* env = Environment::GetCurrent(args.GetIsolate());
3041 HandleScope scope(env->isolate());
3043 if (args.Length() == 0 || !args[0]->IsString()) {
3044 return env->ThrowError("Must give hashtype string as argument");
3047 const node::Utf8Value hash_type(args[0]);
3049 Hash* hash = new Hash(env, args.This());
3050 if (!hash->HashInit(*hash_type)) {
3051 return env->ThrowError("Digest method not supported");
3056 bool Hash::HashInit(const char* hash_type) {
3057 assert(md_ == NULL);
3058 md_ = EVP_get_digestbyname(hash_type);
3061 EVP_MD_CTX_init(&mdctx_);
3062 EVP_DigestInit_ex(&mdctx_, md_, NULL);
3063 initialised_ = true;
3068 bool Hash::HashUpdate(const char* data, int len) {
3071 EVP_DigestUpdate(&mdctx_, data, len);
3076 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
3077 Environment* env = Environment::GetCurrent(args.GetIsolate());
3078 HandleScope scope(env->isolate());
3080 Hash* hash = Unwrap<Hash>(args.Holder());
3082 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3084 // Only copy the data if we have to, because it's a string
3086 if (args[0]->IsString()) {
3087 Local<String> string = args[0].As<String>();
3088 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3089 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3090 return env->ThrowTypeError("Bad input string");
3091 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3092 char* buf = new char[buflen];
3093 size_t written = StringBytes::Write(env->isolate(),
3098 r = hash->HashUpdate(buf, written);
3101 char* buf = Buffer::Data(args[0]);
3102 size_t buflen = Buffer::Length(args[0]);
3103 r = hash->HashUpdate(buf, buflen);
3107 return env->ThrowTypeError("HashUpdate fail");
3112 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
3113 Environment* env = Environment::GetCurrent(args.GetIsolate());
3114 HandleScope scope(env->isolate());
3116 Hash* hash = Unwrap<Hash>(args.Holder());
3118 if (!hash->initialised_) {
3119 return env->ThrowError("Not initialized");
3122 enum encoding encoding = BUFFER;
3123 if (args.Length() >= 1) {
3124 encoding = ParseEncoding(env->isolate(), args[0]->ToString(), BUFFER);
3127 unsigned char md_value[EVP_MAX_MD_SIZE];
3128 unsigned int md_len;
3130 EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len);
3131 EVP_MD_CTX_cleanup(&hash->mdctx_);
3132 hash->initialised_ = false;
3134 Local<Value> rc = StringBytes::Encode(env->isolate(),
3135 reinterpret_cast<const char*>(md_value),
3138 args.GetReturnValue().Set(rc);
3142 void SignBase::CheckThrow(SignBase::Error error) {
3143 HandleScope scope(env()->isolate());
3146 case kSignUnknownDigest:
3147 return env()->ThrowError("Unknown message digest");
3149 case kSignNotInitialised:
3150 return env()->ThrowError("Not initialised");
3154 case kSignPrivateKey:
3155 case kSignPublicKey:
3157 unsigned long err = ERR_get_error();
3159 return ThrowCryptoError(env(), err);
3162 return env()->ThrowError("EVP_SignInit_ex failed");
3164 return env()->ThrowError("EVP_SignUpdate failed");
3165 case kSignPrivateKey:
3166 return env()->ThrowError("PEM_read_bio_PrivateKey failed");
3167 case kSignPublicKey:
3168 return env()->ThrowError("PEM_read_bio_PUBKEY failed");
3182 void Sign::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3183 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
3185 t->InstanceTemplate()->SetInternalFieldCount(1);
3187 NODE_SET_PROTOTYPE_METHOD(t, "init", SignInit);
3188 NODE_SET_PROTOTYPE_METHOD(t, "update", SignUpdate);
3189 NODE_SET_PROTOTYPE_METHOD(t, "sign", SignFinal);
3191 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"), t->GetFunction());
3195 void Sign::New(const FunctionCallbackInfo<Value>& args) {
3196 HandleScope handle_scope(args.GetIsolate());
3197 Environment* env = Environment::GetCurrent(args.GetIsolate());
3198 new Sign(env, args.This());
3202 SignBase::Error Sign::SignInit(const char* sign_type) {
3203 assert(md_ == NULL);
3204 md_ = EVP_get_digestbyname(sign_type);
3206 return kSignUnknownDigest;
3208 EVP_MD_CTX_init(&mdctx_);
3209 if (!EVP_SignInit_ex(&mdctx_, md_, NULL))
3211 initialised_ = true;
3217 void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
3218 HandleScope scope(args.GetIsolate());
3220 Sign* sign = Unwrap<Sign>(args.Holder());
3222 if (args.Length() == 0 || !args[0]->IsString()) {
3223 return sign->env()->ThrowError("Must give signtype string as argument");
3226 const node::Utf8Value sign_type(args[0]);
3227 sign->CheckThrow(sign->SignInit(*sign_type));
3231 SignBase::Error Sign::SignUpdate(const char* data, int len) {
3233 return kSignNotInitialised;
3234 if (!EVP_SignUpdate(&mdctx_, data, len))
3240 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
3241 Environment* env = Environment::GetCurrent(args.GetIsolate());
3242 HandleScope scope(env->isolate());
3244 Sign* sign = Unwrap<Sign>(args.Holder());
3246 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3248 // Only copy the data if we have to, because it's a string
3250 if (args[0]->IsString()) {
3251 Local<String> string = args[0].As<String>();
3252 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3253 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3254 return env->ThrowTypeError("Bad input string");
3255 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3256 char* buf = new char[buflen];
3257 size_t written = StringBytes::Write(env->isolate(),
3262 err = sign->SignUpdate(buf, written);
3265 char* buf = Buffer::Data(args[0]);
3266 size_t buflen = Buffer::Length(args[0]);
3267 err = sign->SignUpdate(buf, buflen);
3270 sign->CheckThrow(err);
3274 SignBase::Error Sign::SignFinal(const char* key_pem,
3276 const char* passphrase,
3277 unsigned char** sig,
3278 unsigned int *sig_len) {
3280 return kSignNotInitialised;
3283 EVP_PKEY* pkey = NULL;
3286 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3290 pkey = PEM_read_bio_PrivateKey(bp,
3293 const_cast<char*>(passphrase));
3297 if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey))
3300 initialised_ = false;
3304 EVP_PKEY_free(pkey);
3308 EVP_MD_CTX_cleanup(&mdctx_);
3311 return kSignPrivateKey;
3317 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
3318 Environment* env = Environment::GetCurrent(args.GetIsolate());
3319 HandleScope scope(env->isolate());
3321 Sign* sign = Unwrap<Sign>(args.Holder());
3323 unsigned char* md_value;
3324 unsigned int md_len;
3326 unsigned int len = args.Length();
3327 enum encoding encoding = BUFFER;
3328 if (len >= 2 && args[1]->IsString()) {
3329 encoding = ParseEncoding(env->isolate(), args[1]->ToString(), BUFFER);
3332 node::Utf8Value passphrase(args[2]);
3334 ASSERT_IS_BUFFER(args[0]);
3335 size_t buf_len = Buffer::Length(args[0]);
3336 char* buf = Buffer::Data(args[0]);
3338 md_len = 8192; // Maximum key size is 8192 bits
3339 md_value = new unsigned char[md_len];
3341 Error err = sign->SignFinal(
3344 len >= 3 && !args[2]->IsNull() ? *passphrase : NULL,
3347 if (err != kSignOk) {
3351 return sign->CheckThrow(err);
3354 Local<Value> rc = StringBytes::Encode(env->isolate(),
3355 reinterpret_cast<const char*>(md_value),
3359 args.GetReturnValue().Set(rc);
3363 void Verify::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3364 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
3366 t->InstanceTemplate()->SetInternalFieldCount(1);
3368 NODE_SET_PROTOTYPE_METHOD(t, "init", VerifyInit);
3369 NODE_SET_PROTOTYPE_METHOD(t, "update", VerifyUpdate);
3370 NODE_SET_PROTOTYPE_METHOD(t, "verify", VerifyFinal);
3372 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
3377 void Verify::New(const FunctionCallbackInfo<Value>& args) {
3378 HandleScope handle_scope(args.GetIsolate());
3379 Environment* env = Environment::GetCurrent(args.GetIsolate());
3380 new Verify(env, args.This());
3384 SignBase::Error Verify::VerifyInit(const char* verify_type) {
3385 assert(md_ == NULL);
3386 md_ = EVP_get_digestbyname(verify_type);
3388 return kSignUnknownDigest;
3390 EVP_MD_CTX_init(&mdctx_);
3391 if (!EVP_VerifyInit_ex(&mdctx_, md_, NULL))
3393 initialised_ = true;
3399 void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
3400 HandleScope scope(args.GetIsolate());
3402 Verify* verify = Unwrap<Verify>(args.Holder());
3404 if (args.Length() == 0 || !args[0]->IsString()) {
3405 return verify->env()->ThrowError("Must give verifytype string as argument");
3408 const node::Utf8Value verify_type(args[0]);
3409 verify->CheckThrow(verify->VerifyInit(*verify_type));
3413 SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
3415 return kSignNotInitialised;
3417 if (!EVP_VerifyUpdate(&mdctx_, data, len))
3424 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
3425 Environment* env = Environment::GetCurrent(args.GetIsolate());
3426 HandleScope scope(env->isolate());
3428 Verify* verify = Unwrap<Verify>(args.Holder());
3430 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3432 // Only copy the data if we have to, because it's a string
3434 if (args[0]->IsString()) {
3435 Local<String> string = args[0].As<String>();
3436 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3437 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3438 return env->ThrowTypeError("Bad input string");
3439 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3440 char* buf = new char[buflen];
3441 size_t written = StringBytes::Write(env->isolate(),
3446 err = verify->VerifyUpdate(buf, written);
3449 char* buf = Buffer::Data(args[0]);
3450 size_t buflen = Buffer::Length(args[0]);
3451 err = verify->VerifyUpdate(buf, buflen);
3454 verify->CheckThrow(err);
3458 SignBase::Error Verify::VerifyFinal(const char* key_pem,
3462 bool* verify_result) {
3464 return kSignNotInitialised;
3466 ClearErrorOnReturn clear_error_on_return;
3467 (void) &clear_error_on_return; // Silence compiler warning.
3469 EVP_PKEY* pkey = NULL;
3475 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3479 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3480 // Split this out into a separate function once we have more than one
3481 // consumer of public keys.
3482 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3483 pkey = PEM_read_bio_PUBKEY(bp, NULL, CryptoPemCallback, NULL);
3486 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3487 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, CryptoPemCallback, NULL);
3489 pkey = EVP_PKEY_new();
3491 EVP_PKEY_set1_RSA(pkey, rsa);
3498 x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
3502 pkey = X509_get_pubkey(x509);
3508 r = EVP_VerifyFinal(&mdctx_,
3509 reinterpret_cast<const unsigned char*>(sig),
3515 EVP_PKEY_free(pkey);
3521 EVP_MD_CTX_cleanup(&mdctx_);
3522 initialised_ = false;
3525 return kSignPublicKey;
3527 *verify_result = r == 1;
3532 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
3533 Environment* env = Environment::GetCurrent(args.GetIsolate());
3534 HandleScope scope(env->isolate());
3536 Verify* verify = Unwrap<Verify>(args.Holder());
3538 ASSERT_IS_BUFFER(args[0]);
3539 char* kbuf = Buffer::Data(args[0]);
3540 ssize_t klen = Buffer::Length(args[0]);
3542 ASSERT_IS_STRING_OR_BUFFER(args[1]);
3543 // BINARY works for both buffers and binary strings.
3544 enum encoding encoding = BINARY;
3545 if (args.Length() >= 3) {
3546 encoding = ParseEncoding(env->isolate(), args[2]->ToString(), BINARY);
3549 ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);
3551 // only copy if we need to, because it's a string.
3553 if (args[1]->IsString()) {
3554 hbuf = new char[hlen];
3555 ssize_t hwritten = StringBytes::Write(env->isolate(),
3560 assert(hwritten == hlen);
3562 hbuf = Buffer::Data(args[1]);
3566 Error err = verify->VerifyFinal(kbuf, klen, hbuf, hlen, &verify_result);
3567 if (args[1]->IsString())
3570 return verify->CheckThrow(err);
3571 args.GetReturnValue().Set(verify_result);
3575 template <PublicKeyCipher::Operation operation,
3576 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3577 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3578 bool PublicKeyCipher::Cipher(const char* key_pem,
3580 const char* passphrase,
3582 const unsigned char* data,
3584 unsigned char** out,
3586 EVP_PKEY* pkey = NULL;
3587 EVP_PKEY_CTX* ctx = NULL;
3592 bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
3596 // Check if this is a PKCS#8 or RSA public key before trying as X.509 and
3598 if (operation == kEncrypt &&
3599 strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3600 pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
3603 } else if (operation == kEncrypt &&
3604 strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3605 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
3607 pkey = EVP_PKEY_new();
3609 EVP_PKEY_set1_RSA(pkey, rsa);
3614 } else if (operation == kEncrypt &&
3615 strncmp(key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0) {
3616 x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
3620 pkey = X509_get_pubkey(x509);
3624 pkey = PEM_read_bio_PrivateKey(bp,
3627 const_cast<char*>(passphrase));
3632 ctx = EVP_PKEY_CTX_new(pkey, NULL);
3635 if (EVP_PKEY_cipher_init(ctx) <= 0)
3637 if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0)
3640 if (EVP_PKEY_cipher(ctx, NULL, out_len, data, len) <= 0)
3643 *out = new unsigned char[*out_len];
3645 if (EVP_PKEY_cipher(ctx, *out, out_len, data, len) <= 0)
3652 EVP_PKEY_free(pkey);
3656 EVP_PKEY_CTX_free(ctx);
3662 template <PublicKeyCipher::Operation operation,
3663 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3664 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3665 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
3666 Environment* env = Environment::GetCurrent(args.GetIsolate());
3667 HandleScope scope(env->isolate());
3669 ASSERT_IS_BUFFER(args[0]);
3670 char* kbuf = Buffer::Data(args[0]);
3671 ssize_t klen = Buffer::Length(args[0]);
3673 ASSERT_IS_BUFFER(args[1]);
3674 char* buf = Buffer::Data(args[1]);
3675 ssize_t len = Buffer::Length(args[1]);
3677 int padding = args[2]->Uint32Value();
3679 String::Utf8Value passphrase(args[3]);
3681 unsigned char* out_value = NULL;
3684 bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
3687 args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : NULL,
3689 reinterpret_cast<const unsigned char*>(buf),
3694 if (out_len == 0 || !r) {
3699 return ThrowCryptoError(env,
3704 args.GetReturnValue().Set(
3705 Buffer::New(env, reinterpret_cast<char*>(out_value), out_len));
3710 void DiffieHellman::Initialize(Environment* env, Handle<Object> target) {
3711 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
3713 static enum PropertyAttribute attributes =
3714 static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
3716 t->InstanceTemplate()->SetInternalFieldCount(1);
3718 NODE_SET_PROTOTYPE_METHOD(t, "generateKeys", GenerateKeys);
3719 NODE_SET_PROTOTYPE_METHOD(t, "computeSecret", ComputeSecret);
3720 NODE_SET_PROTOTYPE_METHOD(t, "getPrime", GetPrime);
3721 NODE_SET_PROTOTYPE_METHOD(t, "getGenerator", GetGenerator);
3722 NODE_SET_PROTOTYPE_METHOD(t, "getPublicKey", GetPublicKey);
3723 NODE_SET_PROTOTYPE_METHOD(t, "getPrivateKey", GetPrivateKey);
3724 NODE_SET_PROTOTYPE_METHOD(t, "setPublicKey", SetPublicKey);
3725 NODE_SET_PROTOTYPE_METHOD(t, "setPrivateKey", SetPrivateKey);
3727 t->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3728 DiffieHellman::VerifyErrorGetter,
3734 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"),
3737 Local<FunctionTemplate> t2 = FunctionTemplate::New(env->isolate(),
3738 DiffieHellmanGroup);
3739 t2->InstanceTemplate()->SetInternalFieldCount(1);
3741 NODE_SET_PROTOTYPE_METHOD(t2, "generateKeys", GenerateKeys);
3742 NODE_SET_PROTOTYPE_METHOD(t2, "computeSecret", ComputeSecret);
3743 NODE_SET_PROTOTYPE_METHOD(t2, "getPrime", GetPrime);
3744 NODE_SET_PROTOTYPE_METHOD(t2, "getGenerator", GetGenerator);
3745 NODE_SET_PROTOTYPE_METHOD(t2, "getPublicKey", GetPublicKey);
3746 NODE_SET_PROTOTYPE_METHOD(t2, "getPrivateKey", GetPrivateKey);
3748 t2->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3749 DiffieHellman::VerifyErrorGetter,
3755 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
3760 bool DiffieHellman::Init(int primeLength, int g) {
3762 DH_generate_parameters_ex(dh, primeLength, g, 0);
3763 bool result = VerifyContext();
3766 initialised_ = true;
3771 bool DiffieHellman::Init(const char* p, int p_len, int g) {
3773 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3775 if (!BN_set_word(dh->g, g))
3777 bool result = VerifyContext();
3780 initialised_ = true;
3785 bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
3787 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3788 dh->g = BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, 0);
3789 bool result = VerifyContext();
3792 initialised_ = true;
3797 void DiffieHellman::DiffieHellmanGroup(
3798 const FunctionCallbackInfo<Value>& args) {
3799 HandleScope scope(args.GetIsolate());
3801 Environment* env = Environment::GetCurrent(args.GetIsolate());
3802 DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
3804 if (args.Length() != 1 || !args[0]->IsString()) {
3805 return env->ThrowError("No group name given");
3808 bool initialized = false;
3810 const node::Utf8Value group_name(args[0]);
3811 for (unsigned int i = 0; i < ARRAY_SIZE(modp_groups); ++i) {
3812 const modp_group* it = modp_groups + i;
3814 if (strcasecmp(*group_name, it->name) != 0)
3817 initialized = diffieHellman->Init(it->prime,
3822 env->ThrowError("Initialization failed");
3826 env->ThrowError("Unknown group");
3830 void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
3831 HandleScope scope(args.GetIsolate());
3833 Environment* env = Environment::GetCurrent(args.GetIsolate());
3834 DiffieHellman* diffieHellman =
3835 new DiffieHellman(env, args.This());
3836 bool initialized = false;
3838 if (args.Length() == 2) {
3839 if (args[0]->IsInt32()) {
3840 if (args[1]->IsInt32()) {
3841 initialized = diffieHellman->Init(args[0]->Int32Value(),
3842 args[1]->Int32Value());
3845 if (args[1]->IsInt32()) {
3846 initialized = diffieHellman->Init(Buffer::Data(args[0]),
3847 Buffer::Length(args[0]),
3848 args[1]->Int32Value());
3850 initialized = diffieHellman->Init(Buffer::Data(args[0]),
3851 Buffer::Length(args[0]),
3852 Buffer::Data(args[1]),
3853 Buffer::Length(args[1]));
3859 return env->ThrowError("Initialization failed");
3864 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
3865 Environment* env = Environment::GetCurrent(args.GetIsolate());
3866 HandleScope scope(env->isolate());
3868 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3870 if (!diffieHellman->initialised_) {
3871 return env->ThrowError("Not initialized");
3874 if (!DH_generate_key(diffieHellman->dh)) {
3875 return env->ThrowError("Key generation failed");
3878 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3879 char* data = new char[dataSize];
3880 BN_bn2bin(diffieHellman->dh->pub_key,
3881 reinterpret_cast<unsigned char*>(data));
3883 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3888 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
3889 Environment* env = Environment::GetCurrent(args.GetIsolate());
3890 HandleScope scope(env->isolate());
3892 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3894 if (!diffieHellman->initialised_) {
3895 return env->ThrowError("Not initialized");
3898 int dataSize = BN_num_bytes(diffieHellman->dh->p);
3899 char* data = new char[dataSize];
3900 BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
3902 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3907 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
3908 Environment* env = Environment::GetCurrent(args.GetIsolate());
3909 HandleScope scope(env->isolate());
3911 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3913 if (!diffieHellman->initialised_) {
3914 return env->ThrowError("Not initialized");
3917 int dataSize = BN_num_bytes(diffieHellman->dh->g);
3918 char* data = new char[dataSize];
3919 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
3921 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3926 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
3927 Environment* env = Environment::GetCurrent(args.GetIsolate());
3928 HandleScope scope(env->isolate());
3930 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3932 if (!diffieHellman->initialised_) {
3933 return env->ThrowError("Not initialized");
3936 if (diffieHellman->dh->pub_key == NULL) {
3937 return env->ThrowError("No public key - did you forget to generate one?");
3940 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3941 char* data = new char[dataSize];
3942 BN_bn2bin(diffieHellman->dh->pub_key,
3943 reinterpret_cast<unsigned char*>(data));
3945 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3950 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
3951 Environment* env = Environment::GetCurrent(args.GetIsolate());
3952 HandleScope scope(env->isolate());
3954 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3956 if (!diffieHellman->initialised_) {
3957 return env->ThrowError("Not initialized");
3960 if (diffieHellman->dh->priv_key == NULL) {
3961 return env->ThrowError("No private key - did you forget to generate one?");
3964 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
3965 char* data = new char[dataSize];
3966 BN_bn2bin(diffieHellman->dh->priv_key,
3967 reinterpret_cast<unsigned char*>(data));
3969 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3974 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
3975 Environment* env = Environment::GetCurrent(args.GetIsolate());
3976 HandleScope scope(env->isolate());
3978 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3980 if (!diffieHellman->initialised_) {
3981 return env->ThrowError("Not initialized");
3984 ClearErrorOnReturn clear_error_on_return;
3985 (void) &clear_error_on_return; // Silence compiler warning.
3988 if (args.Length() == 0) {
3989 return env->ThrowError("First argument must be other party's public key");
3991 ASSERT_IS_BUFFER(args[0]);
3993 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3994 Buffer::Length(args[0]),
3998 int dataSize = DH_size(diffieHellman->dh);
3999 char* data = new char[dataSize];
4001 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
4009 checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
4014 return env->ThrowError("Invalid key");
4015 } else if (checkResult) {
4016 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
4017 return env->ThrowError("Supplied key is too small");
4018 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
4019 return env->ThrowError("Supplied key is too large");
4021 return env->ThrowError("Invalid key");
4024 return env->ThrowError("Invalid key");
4031 // DH_size returns number of bytes in a prime number
4032 // DH_compute_key returns number of bytes in a remainder of exponent, which
4033 // may have less bytes than a prime number. Therefore add 0-padding to the
4034 // allocated buffer.
4035 if (size != dataSize) {
4036 assert(dataSize > size);
4037 memmove(data + dataSize - size, data, size);
4038 memset(data, 0, dataSize - size);
4041 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4046 void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4047 HandleScope scope(args.GetIsolate());
4049 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4050 Environment* env = diffieHellman->env();
4052 if (!diffieHellman->initialised_) {
4053 return env->ThrowError("Not initialized");
4056 if (args.Length() == 0) {
4057 return env->ThrowError("First argument must be public key");
4059 ASSERT_IS_BUFFER(args[0]);
4060 diffieHellman->dh->pub_key = BN_bin2bn(
4061 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4062 Buffer::Length(args[0]), 0);
4067 void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4068 HandleScope scope(args.GetIsolate());
4070 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4071 Environment* env = diffieHellman->env();
4073 if (!diffieHellman->initialised_) {
4074 return env->ThrowError("Not initialized");
4077 if (args.Length() == 0) {
4078 return env->ThrowError("First argument must be private key");
4080 ASSERT_IS_BUFFER(args[0]);
4081 diffieHellman->dh->priv_key = BN_bin2bn(
4082 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4083 Buffer::Length(args[0]),
4089 void DiffieHellman::VerifyErrorGetter(Local<String> property,
4090 const PropertyCallbackInfo<Value>& args) {
4091 HandleScope scope(args.GetIsolate());
4093 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4095 if (!diffieHellman->initialised_)
4096 return diffieHellman->env()->ThrowError("Not initialized");
4098 args.GetReturnValue().Set(diffieHellman->verifyError_);
4102 bool DiffieHellman::VerifyContext() {
4104 if (!DH_check(dh, &codes))
4106 verifyError_ = codes;
4111 void ECDH::Initialize(Environment* env, Handle<Object> target) {
4112 HandleScope scope(env->isolate());
4114 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
4116 t->InstanceTemplate()->SetInternalFieldCount(1);
4118 NODE_SET_PROTOTYPE_METHOD(t, "generateKeys", GenerateKeys);
4119 NODE_SET_PROTOTYPE_METHOD(t, "computeSecret", ComputeSecret);
4120 NODE_SET_PROTOTYPE_METHOD(t, "getPublicKey", GetPublicKey);
4121 NODE_SET_PROTOTYPE_METHOD(t, "getPrivateKey", GetPrivateKey);
4122 NODE_SET_PROTOTYPE_METHOD(t, "setPublicKey", SetPublicKey);
4123 NODE_SET_PROTOTYPE_METHOD(t, "setPrivateKey", SetPrivateKey);
4125 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH"),
4130 void ECDH::New(const FunctionCallbackInfo<Value>& args) {
4131 Environment* env = Environment::GetCurrent(args.GetIsolate());
4132 HandleScope scope(env->isolate());
4134 // TODO(indutny): Support raw curves?
4135 CHECK(args[0]->IsString());
4136 node::Utf8Value curve(args[0]);
4138 int nid = OBJ_sn2nid(*curve);
4139 if (nid == NID_undef)
4140 return env->ThrowTypeError("First argument should be a valid curve name");
4142 EC_KEY* key = EC_KEY_new_by_curve_name(nid);
4144 return env->ThrowError("Failed to create EC_KEY using curve name");
4146 new ECDH(env, args.This(), key);
4150 void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4151 Environment* env = Environment::GetCurrent(args.GetIsolate());
4152 HandleScope scope(env->isolate());
4154 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4156 if (!EC_KEY_generate_key(ecdh->key_))
4157 return env->ThrowError("Failed to generate EC_KEY");
4159 ecdh->generated_ = true;
4163 EC_POINT* ECDH::BufferToPoint(char* data, size_t len) {
4167 pub = EC_POINT_new(group_);
4169 env()->ThrowError("Failed to allocate EC_POINT for a public key");
4173 r = EC_POINT_oct2point(
4176 reinterpret_cast<unsigned char*>(data),
4180 env()->ThrowError("Failed to translate Buffer to a EC_POINT");
4192 void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4193 Environment* env = Environment::GetCurrent(args.GetIsolate());
4194 HandleScope scope(env->isolate());
4196 ASSERT_IS_BUFFER(args[0]);
4198 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4200 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0]),
4201 Buffer::Length(args[0]));
4205 // NOTE: field_size is in bits
4206 int field_size = EC_GROUP_get_degree(ecdh->group_);
4207 size_t out_len = (field_size + 7) / 8;
4208 char* out = static_cast<char*>(malloc(out_len));
4209 CHECK_NE(out, NULL);
4211 int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, NULL);
4215 return env->ThrowError("Failed to compute ECDH key");
4218 args.GetReturnValue().Set(Buffer::Use(env, out, out_len));
4222 void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
4223 Environment* env = Environment::GetCurrent(args.GetIsolate());
4224 HandleScope scope(env->isolate());
4227 CHECK_EQ(args.Length(), 1);
4229 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4231 if (!ecdh->generated_)
4232 return env->ThrowError("You should generate ECDH keys first");
4234 const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_);
4236 return env->ThrowError("Failed to get ECDH public key");
4239 point_conversion_form_t form =
4240 static_cast<point_conversion_form_t>(args[0]->Uint32Value());
4242 size = EC_POINT_point2oct(ecdh->group_, pub, form, NULL, 0, NULL);
4244 return env->ThrowError("Failed to get public key length");
4246 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4247 CHECK_NE(out, NULL);
4249 int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, NULL);
4252 return env->ThrowError("Failed to get public key");
4255 args.GetReturnValue().Set(Buffer::Use(env,
4256 reinterpret_cast<char*>(out),
4261 void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4262 Environment* env = Environment::GetCurrent(args.GetIsolate());
4263 HandleScope scope(env->isolate());
4265 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4267 if (!ecdh->generated_)
4268 return env->ThrowError("You should generate ECDH keys first");
4270 const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_);
4272 return env->ThrowError("Failed to get ECDH private key");
4274 int size = BN_num_bytes(b);
4275 unsigned char* out = static_cast<unsigned char*>(malloc(size));
4276 CHECK_NE(out, NULL);
4278 if (size != BN_bn2bin(b, out)) {
4280 return env->ThrowError("Failed to convert ECDH private key to Buffer");
4283 args.GetReturnValue().Set(Buffer::Use(env,
4284 reinterpret_cast<char*>(out),
4289 void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4290 Environment* env = Environment::GetCurrent(args.GetIsolate());
4291 HandleScope scope(env->isolate());
4293 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4295 ASSERT_IS_BUFFER(args[0]);
4297 BIGNUM* priv = BN_bin2bn(
4298 reinterpret_cast<unsigned char*>(Buffer::Data(args[0].As<Object>())),
4299 Buffer::Length(args[0].As<Object>()),
4302 return env->ThrowError("Failed to convert Buffer to BN");
4304 if (!EC_KEY_set_private_key(ecdh->key_, priv))
4305 return env->ThrowError("Failed to convert BN to a private key");
4309 void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4310 Environment* env = Environment::GetCurrent(args.GetIsolate());
4311 HandleScope scope(env->isolate());
4313 ECDH* ecdh = Unwrap<ECDH>(args.Holder());
4315 ASSERT_IS_BUFFER(args[0]);
4317 EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0].As<Object>()),
4318 Buffer::Length(args[0].As<Object>()));
4322 int r = EC_KEY_set_public_key(ecdh->key_, pub);
4325 return env->ThrowError("Failed to convert BN to a private key");
4329 class PBKDF2Request : public AsyncWrap {
4331 PBKDF2Request(Environment* env,
4332 Local<Object> object,
4333 const EVP_MD* digest,
4340 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4348 key_(static_cast<char*>(malloc(keylen))),
4351 FatalError("node::PBKDF2Request()", "Out of Memory");
4355 persistent().Reset();
4358 uv_work_t* work_req() {
4362 inline const EVP_MD* digest() const {
4366 inline ssize_t passlen() const {
4370 inline char* pass() const {
4374 inline ssize_t saltlen() const {
4378 inline char* salt() const {
4382 inline ssize_t keylen() const {
4386 inline char* key() const {
4390 inline ssize_t iter() const {
4394 inline void release() {
4403 inline int error() const {
4407 inline void set_error(int err) {
4411 uv_work_t work_req_;
4414 const EVP_MD* digest_;
4426 void EIO_PBKDF2(PBKDF2Request* req) {
4427 req->set_error(PKCS5_PBKDF2_HMAC(
4430 reinterpret_cast<unsigned char*>(req->salt()),
4435 reinterpret_cast<unsigned char*>(req->key())));
4436 memset(req->pass(), 0, req->passlen());
4437 memset(req->salt(), 0, req->saltlen());
4441 void EIO_PBKDF2(uv_work_t* work_req) {
4442 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4447 void EIO_PBKDF2After(PBKDF2Request* req, Local<Value> argv[2]) {
4449 argv[0] = Undefined(req->env()->isolate());
4450 argv[1] = Encode(req->env()->isolate(), req->key(), req->keylen(), BUFFER);
4451 memset(req->key(), 0, req->keylen());
4453 argv[0] = Exception::Error(req->env()->pbkdf2_error_string());
4454 argv[1] = Undefined(req->env()->isolate());
4459 void EIO_PBKDF2After(uv_work_t* work_req, int status) {
4460 assert(status == 0);
4461 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4462 Environment* env = req->env();
4463 HandleScope handle_scope(env->isolate());
4464 Context::Scope context_scope(env->context());
4465 Local<Value> argv[2];
4466 EIO_PBKDF2After(req, argv);
4467 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4473 void PBKDF2(const FunctionCallbackInfo<Value>& args) {
4474 Environment* env = Environment::GetCurrent(args.GetIsolate());
4475 HandleScope scope(env->isolate());
4477 const EVP_MD* digest = NULL;
4478 const char* type_error = NULL;
4481 ssize_t passlen = -1;
4482 ssize_t saltlen = -1;
4483 ssize_t keylen = -1;
4485 PBKDF2Request* req = NULL;
4488 if (args.Length() != 5 && args.Length() != 6) {
4489 type_error = "Bad parameter";
4493 ASSERT_IS_BUFFER(args[0]);
4494 passlen = Buffer::Length(args[0]);
4496 type_error = "Bad password";
4500 ASSERT_IS_BUFFER(args[1]);
4502 pass = static_cast<char*>(malloc(passlen));
4504 FatalError("node::PBKDF2()", "Out of Memory");
4506 memcpy(pass, Buffer::Data(args[0]), passlen);
4508 saltlen = Buffer::Length(args[1]);
4510 type_error = "Bad salt";
4514 salt = static_cast<char*>(malloc(saltlen));
4516 FatalError("node::PBKDF2()", "Out of Memory");
4518 memcpy(salt, Buffer::Data(args[1]), saltlen);
4520 if (!args[2]->IsNumber()) {
4521 type_error = "Iterations not a number";
4525 iter = args[2]->Int32Value();
4527 type_error = "Bad iterations";
4531 if (!args[3]->IsNumber()) {
4532 type_error = "Key length not a number";
4536 keylen = args[3]->Int32Value();
4538 type_error = "Bad key length";
4542 if (args[4]->IsString()) {
4543 node::Utf8Value digest_name(args[4]);
4544 digest = EVP_get_digestbyname(*digest_name);
4545 if (digest == NULL) {
4546 type_error = "Bad digest name";
4551 if (digest == NULL) {
4552 digest = EVP_sha1();
4555 obj = Object::New(env->isolate());
4556 req = new PBKDF2Request(env,
4566 if (args[5]->IsFunction()) {
4567 obj->Set(env->ondone_string(), args[5]);
4568 // XXX(trevnorris): This will need to go with the rest of domains.
4569 if (env->in_domain())
4570 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4571 uv_queue_work(env->event_loop(),
4576 Local<Value> argv[2];
4578 EIO_PBKDF2After(req, argv);
4579 if (argv[0]->IsObject())
4580 env->isolate()->ThrowException(argv[0]);
4582 args.GetReturnValue().Set(argv[1]);
4589 return env->ThrowTypeError(type_error);
4593 // Only instantiate within a valid HandleScope.
4594 class RandomBytesRequest : public AsyncWrap {
4596 RandomBytesRequest(Environment* env, Local<Object> object, size_t size)
4597 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4600 data_(static_cast<char*>(malloc(size))) {
4602 FatalError("node::RandomBytesRequest()", "Out of Memory");
4605 ~RandomBytesRequest() {
4606 persistent().Reset();
4609 uv_work_t* work_req() {
4613 inline size_t size() const {
4617 inline char* data() const {
4621 inline void release() {
4626 inline void return_memory(char** d, size_t* len) {
4633 inline unsigned long error() const {
4637 inline void set_error(unsigned long err) {
4641 uv_work_t work_req_;
4644 unsigned long error_;
4650 template <bool pseudoRandom>
4651 void RandomBytesWork(uv_work_t* work_req) {
4652 RandomBytesRequest* req =
4653 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4656 // Ensure that OpenSSL's PRNG is properly seeded.
4659 if (pseudoRandom == true) {
4660 r = RAND_pseudo_bytes(reinterpret_cast<unsigned char*>(req->data()),
4663 r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data()), req->size());
4666 // RAND_bytes() returns 0 on error. RAND_pseudo_bytes() returns 0 when the
4667 // result is not cryptographically strong - but that's not an error.
4668 if (r == 0 && pseudoRandom == false) {
4669 req->set_error(ERR_get_error());
4670 } else if (r == -1) {
4671 req->set_error(static_cast<unsigned long>(-1));
4676 // don't call this function without a valid HandleScope
4677 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
4679 char errmsg[256] = "Operation not supported";
4681 if (req->error() != static_cast<unsigned long>(-1))
4682 ERR_error_string_n(req->error(), errmsg, sizeof errmsg);
4684 argv[0] = Exception::Error(OneByteString(req->env()->isolate(), errmsg));
4685 argv[1] = Null(req->env()->isolate());
4690 req->return_memory(&data, &size);
4691 argv[0] = Null(req->env()->isolate());
4692 argv[1] = Buffer::Use(data, size);
4697 void RandomBytesAfter(uv_work_t* work_req, int status) {
4698 assert(status == 0);
4699 RandomBytesRequest* req =
4700 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4701 Environment* env = req->env();
4702 HandleScope handle_scope(env->isolate());
4703 Context::Scope context_scope(env->context());
4704 Local<Value> argv[2];
4705 RandomBytesCheck(req, argv);
4706 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4711 template <bool pseudoRandom>
4712 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
4713 HandleScope handle_scope(args.GetIsolate());
4714 Environment* env = Environment::GetCurrent(args.GetIsolate());
4716 // maybe allow a buffer to write to? cuts down on object creation
4717 // when generating random data in a loop
4718 if (!args[0]->IsUint32()) {
4719 return env->ThrowTypeError("Argument #1 must be number > 0");
4722 const uint32_t size = args[0]->Uint32Value();
4723 if (size > Buffer::kMaxLength) {
4724 return env->ThrowTypeError("size > Buffer::kMaxLength");
4727 Local<Object> obj = Object::New(env->isolate());
4728 RandomBytesRequest* req = new RandomBytesRequest(env, obj, size);
4730 if (args[1]->IsFunction()) {
4731 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "ondone"), args[1]);
4732 // XXX(trevnorris): This will need to go with the rest of domains.
4733 if (env->in_domain())
4734 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4735 uv_queue_work(env->event_loop(),
4737 RandomBytesWork<pseudoRandom>,
4739 args.GetReturnValue().Set(obj);
4741 Local<Value> argv[2];
4742 RandomBytesWork<pseudoRandom>(req->work_req());
4743 RandomBytesCheck(req, argv);
4746 if (!argv[0]->IsNull())
4747 env->isolate()->ThrowException(argv[0]);
4749 args.GetReturnValue().Set(argv[1]);
4754 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
4755 Environment* env = Environment::GetCurrent(args.GetIsolate());
4756 HandleScope scope(env->isolate());
4758 SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
4760 return env->ThrowError("SSL_CTX_new() failed.");
4763 SSL* ssl = SSL_new(ctx);
4766 return env->ThrowError("SSL_new() failed.");
4769 Local<Array> arr = Array::New(env->isolate());
4770 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
4772 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
4773 SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
4774 arr->Set(i, OneByteString(args.GetIsolate(), SSL_CIPHER_get_name(cipher)));
4780 args.GetReturnValue().Set(arr);
4784 class CipherPushContext {
4786 explicit CipherPushContext(Environment* env)
4787 : arr(Array::New(env->isolate())),
4791 inline Environment* env() const { return env_; }
4800 template <class TypeName>
4801 static void array_push_back(const TypeName* md,
4805 CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
4806 ctx->arr->Set(ctx->arr->Length(), OneByteString(ctx->env()->isolate(), from));
4810 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
4811 Environment* env = Environment::GetCurrent(args.GetIsolate());
4812 HandleScope scope(env->isolate());
4813 CipherPushContext ctx(env);
4814 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
4815 args.GetReturnValue().Set(ctx.arr);
4819 void GetHashes(const FunctionCallbackInfo<Value>& args) {
4820 Environment* env = Environment::GetCurrent(args.GetIsolate());
4821 HandleScope scope(env->isolate());
4822 CipherPushContext ctx(env);
4823 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
4824 args.GetReturnValue().Set(ctx.arr);
4828 void Certificate::Initialize(Environment* env, Handle<Object> target) {
4829 HandleScope scope(env->isolate());
4831 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
4833 t->InstanceTemplate()->SetInternalFieldCount(1);
4835 NODE_SET_PROTOTYPE_METHOD(t, "verifySpkac", VerifySpkac);
4836 NODE_SET_PROTOTYPE_METHOD(t, "exportPublicKey", ExportPublicKey);
4837 NODE_SET_PROTOTYPE_METHOD(t, "exportChallenge", ExportChallenge);
4839 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Certificate"),
4844 void Certificate::New(const FunctionCallbackInfo<Value>& args) {
4845 HandleScope handle_scope(args.GetIsolate());
4846 Environment* env = Environment::GetCurrent(args.GetIsolate());
4847 new Certificate(env, args.This());
4851 bool Certificate::VerifySpkac(const char* data, unsigned int len) {
4853 EVP_PKEY* pkey = NULL;
4854 NETSCAPE_SPKI* spki = NULL;
4856 spki = NETSCAPE_SPKI_b64_decode(data, len);
4860 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
4864 i = NETSCAPE_SPKI_verify(spki, pkey) > 0;
4868 EVP_PKEY_free(pkey);
4871 NETSCAPE_SPKI_free(spki);
4877 void Certificate::VerifySpkac(const FunctionCallbackInfo<Value>& args) {
4878 HandleScope scope(args.GetIsolate());
4880 Certificate* certificate = Unwrap<Certificate>(args.Holder());
4881 Environment* env = certificate->env();
4884 if (args.Length() < 1)
4885 return env->ThrowTypeError("Missing argument");
4887 ASSERT_IS_BUFFER(args[0]);
4889 size_t length = Buffer::Length(args[0]);
4891 return args.GetReturnValue().Set(i);
4893 char* data = Buffer::Data(args[0]);
4894 assert(data != NULL);
4896 i = certificate->VerifySpkac(data, length);
4898 args.GetReturnValue().Set(i);
4902 const char* Certificate::ExportPublicKey(const char* data, int len) {
4904 EVP_PKEY* pkey = NULL;
4905 NETSCAPE_SPKI* spki = NULL;
4907 BIO* bio = BIO_new(BIO_s_mem());
4911 spki = NETSCAPE_SPKI_b64_decode(data, len);
4915 pkey = NETSCAPE_SPKI_get_pubkey(spki);
4919 if (PEM_write_bio_PUBKEY(bio, pkey) <= 0)
4922 BIO_write(bio, "\0", 1);
4924 BIO_get_mem_ptr(bio, &ptr);
4926 buf = new char[ptr->length];
4927 memcpy(buf, ptr->data, ptr->length);
4931 EVP_PKEY_free(pkey);
4934 NETSCAPE_SPKI_free(spki);
4943 void Certificate::ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
4944 Environment* env = Environment::GetCurrent(args.GetIsolate());
4945 HandleScope scope(env->isolate());
4947 Certificate* certificate = Unwrap<Certificate>(args.Holder());
4949 if (args.Length() < 1)
4950 return env->ThrowTypeError("Missing argument");
4952 ASSERT_IS_BUFFER(args[0]);
4954 size_t length = Buffer::Length(args[0]);
4956 return args.GetReturnValue().SetEmptyString();
4958 char* data = Buffer::Data(args[0]);
4959 assert(data != NULL);
4961 const char* pkey = certificate->ExportPublicKey(data, length);
4963 return args.GetReturnValue().SetEmptyString();
4965 Local<Value> out = Encode(env->isolate(), pkey, strlen(pkey), BUFFER);
4969 args.GetReturnValue().Set(out);
4973 const char* Certificate::ExportChallenge(const char* data, int len) {
4974 NETSCAPE_SPKI* sp = NULL;
4976 sp = NETSCAPE_SPKI_b64_decode(data, len);
4980 const char* buf = NULL;
4981 buf = reinterpret_cast<const char*>(ASN1_STRING_data(sp->spkac->challenge));
4987 void Certificate::ExportChallenge(const FunctionCallbackInfo<Value>& args) {
4988 Environment* env = Environment::GetCurrent(args.GetIsolate());
4989 HandleScope scope(env->isolate());
4991 Certificate* crt = Unwrap<Certificate>(args.Holder());
4993 if (args.Length() < 1)
4994 return env->ThrowTypeError("Missing argument");
4996 ASSERT_IS_BUFFER(args[0]);
4998 size_t len = Buffer::Length(args[0]);
5000 return args.GetReturnValue().SetEmptyString();
5002 char* data = Buffer::Data(args[0]);
5003 assert(data != NULL);
5005 const char* cert = crt->ExportChallenge(data, len);
5007 return args.GetReturnValue().SetEmptyString();
5009 Local<Value> outString = Encode(env->isolate(), cert, strlen(cert), BUFFER);
5013 args.GetReturnValue().Set(outString);
5017 void InitCryptoOnce() {
5019 OpenSSL_add_all_algorithms();
5020 SSL_load_error_strings();
5023 CRYPTO_set_locking_callback(crypto_lock_cb);
5024 CRYPTO_THREADID_set_callback(crypto_threadid_cb);
5026 // Turn off compression. Saves memory and protects against CRIME attacks.
5027 #if !defined(OPENSSL_NO_COMP)
5028 #if OPENSSL_VERSION_NUMBER < 0x00908000L
5029 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_method();
5031 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
5033 sk_SSL_COMP_zero(comp_methods);
5034 assert(sk_SSL_COMP_num(comp_methods) == 0);
5037 #ifndef OPENSSL_NO_ENGINE
5038 ERR_load_ENGINE_strings();
5039 ENGINE_load_builtin_engines();
5040 #endif // !OPENSSL_NO_ENGINE
5044 #ifndef OPENSSL_NO_ENGINE
5045 void SetEngine(const FunctionCallbackInfo<Value>& args) {
5046 Environment* env = Environment::GetCurrent(args.GetIsolate());
5047 CHECK(args.Length() >= 2 && args[0]->IsString());
5048 unsigned int flags = args[1]->Uint32Value();
5050 ClearErrorOnReturn clear_error_on_return;
5051 (void) &clear_error_on_return; // Silence compiler warning.
5053 const node::Utf8Value engine_id(args[0]);
5054 ENGINE* engine = ENGINE_by_id(*engine_id);
5056 // Engine not found, try loading dynamically
5057 if (engine == NULL) {
5058 engine = ENGINE_by_id("dynamic");
5059 if (engine != NULL) {
5060 if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", *engine_id, 0) ||
5061 !ENGINE_ctrl_cmd_string(engine, "LOAD", NULL, 0)) {
5062 ENGINE_free(engine);
5068 if (engine == NULL) {
5069 int err = ERR_get_error();
5072 snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id);
5073 return env->ThrowError(tmp);
5075 return ThrowCryptoError(env, err);
5079 int r = ENGINE_set_default(engine, flags);
5080 ENGINE_free(engine);
5082 return ThrowCryptoError(env, ERR_get_error());
5084 #endif // !OPENSSL_NO_ENGINE
5087 // FIXME(bnoordhuis) Handle global init correctly.
5088 void InitCrypto(Handle<Object> target,
5089 Handle<Value> unused,
5090 Handle<Context> context,
5092 static uv_once_t init_once = UV_ONCE_INIT;
5093 uv_once(&init_once, InitCryptoOnce);
5095 Environment* env = Environment::GetCurrent(context);
5096 SecureContext::Initialize(env, target);
5097 Connection::Initialize(env, target);
5098 CipherBase::Initialize(env, target);
5099 DiffieHellman::Initialize(env, target);
5100 ECDH::Initialize(env, target);
5101 Hmac::Initialize(env, target);
5102 Hash::Initialize(env, target);
5103 Sign::Initialize(env, target);
5104 Verify::Initialize(env, target);
5105 Certificate::Initialize(env, target);
5107 #ifndef OPENSSL_NO_ENGINE
5108 NODE_SET_METHOD(target, "setEngine", SetEngine);
5109 #endif // !OPENSSL_NO_ENGINE
5110 NODE_SET_METHOD(target, "PBKDF2", PBKDF2);
5111 NODE_SET_METHOD(target, "randomBytes", RandomBytes<false>);
5112 NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<true>);
5113 NODE_SET_METHOD(target, "getSSLCiphers", GetSSLCiphers);
5114 NODE_SET_METHOD(target, "getCiphers", GetCiphers);
5115 NODE_SET_METHOD(target, "getHashes", GetHashes);
5116 NODE_SET_METHOD(target,
5118 PublicKeyCipher::Cipher<PublicKeyCipher::kEncrypt,
5119 EVP_PKEY_encrypt_init,
5121 NODE_SET_METHOD(target,
5123 PublicKeyCipher::Cipher<PublicKeyCipher::kDecrypt,
5124 EVP_PKEY_decrypt_init,
5128 } // namespace crypto
5131 NODE_MODULE_CONTEXT_AWARE_BUILTIN(crypto, node::crypto::InitCrypto)