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, "setOptions", SecureContext::SetOptions);
274 NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
275 SecureContext::SetSessionIdContext);
276 NODE_SET_PROTOTYPE_METHOD(t, "setSessionTimeout",
277 SecureContext::SetSessionTimeout);
278 NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
279 NODE_SET_PROTOTYPE_METHOD(t, "loadPKCS12", SecureContext::LoadPKCS12);
280 NODE_SET_PROTOTYPE_METHOD(t, "getTicketKeys", SecureContext::GetTicketKeys);
281 NODE_SET_PROTOTYPE_METHOD(t, "setTicketKeys", SecureContext::SetTicketKeys);
282 NODE_SET_PROTOTYPE_METHOD(t,
284 SecureContext::GetCertificate<true>);
285 NODE_SET_PROTOTYPE_METHOD(t,
287 SecureContext::GetCertificate<false>);
289 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"),
291 env->set_secure_context_constructor_template(t);
295 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
296 HandleScope handle_scope(args.GetIsolate());
297 Environment* env = Environment::GetCurrent(args.GetIsolate());
298 new SecureContext(env, args.This());
302 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
303 HandleScope scope(args.GetIsolate());
305 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
306 Environment* env = sc->env();
308 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
310 if (args.Length() == 1 && args[0]->IsString()) {
311 const node::Utf8Value sslmethod(args[0]);
313 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
314 #ifndef OPENSSL_NO_SSL2
315 method = SSLv2_method();
317 return env->ThrowError("SSLv2 methods disabled");
319 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
320 #ifndef OPENSSL_NO_SSL2
321 method = SSLv2_server_method();
323 return env->ThrowError("SSLv2 methods disabled");
325 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
326 #ifndef OPENSSL_NO_SSL2
327 method = SSLv2_client_method();
329 return env->ThrowError("SSLv2 methods disabled");
331 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
332 method = SSLv3_method();
333 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
334 method = SSLv3_server_method();
335 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
336 method = SSLv3_client_method();
337 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
338 method = SSLv23_method();
339 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
340 method = SSLv23_server_method();
341 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
342 method = SSLv23_client_method();
343 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
344 method = TLSv1_method();
345 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
346 method = TLSv1_server_method();
347 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
348 method = TLSv1_client_method();
349 } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
350 method = TLSv1_1_method();
351 } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
352 method = TLSv1_1_server_method();
353 } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
354 method = TLSv1_1_client_method();
355 } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
356 method = TLSv1_2_method();
357 } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
358 method = TLSv1_2_server_method();
359 } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
360 method = TLSv1_2_client_method();
362 return env->ThrowError("Unknown method");
366 sc->ctx_ = SSL_CTX_new(method);
368 // SSL session cache configuration
369 SSL_CTX_set_session_cache_mode(sc->ctx_,
370 SSL_SESS_CACHE_SERVER |
371 SSL_SESS_CACHE_NO_INTERNAL |
372 SSL_SESS_CACHE_NO_AUTO_CLEAR);
373 SSL_CTX_sess_set_get_cb(sc->ctx_, SSLWrap<Connection>::GetSessionCallback);
374 SSL_CTX_sess_set_new_cb(sc->ctx_, SSLWrap<Connection>::NewSessionCallback);
376 sc->ca_store_ = NULL;
380 // Takes a string or buffer and loads it into a BIO.
381 // Caller responsible for BIO_free_all-ing the returned object.
382 static BIO* LoadBIO(Environment* env, Handle<Value> v) {
383 BIO* bio = NodeBIO::New();
387 HandleScope scope(env->isolate());
392 const node::Utf8Value s(v);
393 r = BIO_write(bio, *s, s.length());
394 } else if (Buffer::HasInstance(v)) {
395 char* buffer_data = Buffer::Data(v);
396 size_t buffer_length = Buffer::Length(v);
397 r = BIO_write(bio, buffer_data, buffer_length);
409 // Takes a string or buffer and loads it into an X509
410 // Caller responsible for X509_free-ing the returned object.
411 static X509* LoadX509(Environment* env, Handle<Value> v) {
412 HandleScope scope(env->isolate());
414 BIO *bio = LoadBIO(env, v);
418 X509 * x509 = PEM_read_bio_X509(bio, NULL, CryptoPemCallback, NULL);
429 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
430 Environment* env = Environment::GetCurrent(args.GetIsolate());
431 HandleScope scope(env->isolate());
433 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
435 unsigned int len = args.Length();
436 if (len != 1 && len != 2) {
437 return env->ThrowTypeError("Bad parameter");
439 if (len == 2 && !args[1]->IsString()) {
440 return env->ThrowTypeError("Bad parameter");
443 BIO *bio = LoadBIO(env, args[0]);
447 node::Utf8Value passphrase(args[1]);
449 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio,
452 len == 1 ? NULL : *passphrase);
456 unsigned long err = ERR_get_error();
458 return env->ThrowError("PEM_read_bio_PrivateKey");
460 return ThrowCryptoError(env, err);
463 SSL_CTX_use_PrivateKey(sc->ctx_, key);
469 int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) {
472 X509_STORE* store = SSL_CTX_get_cert_store(ctx);
473 X509_STORE_CTX store_ctx;
475 ret = X509_STORE_CTX_init(&store_ctx, store, NULL, NULL);
479 ret = X509_STORE_CTX_get1_issuer(issuer, &store_ctx, cert);
480 X509_STORE_CTX_cleanup(&store_ctx);
487 // Read a file that contains our certificate in "PEM" format,
488 // possibly followed by a sequence of CA certificates that should be
489 // sent to the peer in the Certificate message.
491 // Taken from OpenSSL - editted for style.
492 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
499 x = PEM_read_bio_X509_AUX(in, NULL, CryptoPemCallback, NULL);
502 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
506 ret = SSL_CTX_use_certificate(ctx, x);
508 if (ERR_peek_error() != 0) {
509 // Key/certificate mismatch doesn't imply ret==0 ...
514 // If we could set up our certificate, now proceed to
515 // the CA certificates.
520 if (ctx->extra_certs != NULL) {
521 sk_X509_pop_free(ctx->extra_certs, X509_free);
522 ctx->extra_certs = NULL;
525 while ((ca = PEM_read_bio_X509(in, NULL, CryptoPemCallback, NULL))) {
526 r = SSL_CTX_add_extra_chain_cert(ctx, ca);
533 // Note that we must not free r if it was successfully
534 // added to the chain (while we must free the main
535 // certificate, since its reference count is increased
536 // by SSL_CTX_use_certificate).
539 if (*issuer != NULL || X509_check_issued(ca, x) != X509_V_OK)
544 // When the while loop ends, it's usually just EOF.
545 err = ERR_peek_last_error();
546 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
547 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
555 // Try getting issuer from a cert store
557 if (*issuer == NULL) {
558 ret = SSL_CTX_get_issuer(ctx, x, issuer);
559 ret = ret < 0 ? 0 : 1;
560 // NOTE: get_cert_store doesn't increment reference count,
561 // no need to free `store`
563 // Increment issuer reference count
564 CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
575 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
576 Environment* env = Environment::GetCurrent(args.GetIsolate());
577 HandleScope scope(env->isolate());
579 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
581 if (args.Length() != 1) {
582 return env->ThrowTypeError("Bad parameter");
585 BIO* bio = LoadBIO(env, args[0]);
589 int rv = SSL_CTX_use_certificate_chain(sc->ctx_,
597 unsigned long err = ERR_get_error();
599 return env->ThrowError("SSL_CTX_use_certificate_chain");
601 return ThrowCryptoError(env, err);
606 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
607 bool newCAStore = false;
608 Environment* env = Environment::GetCurrent(args.GetIsolate());
609 HandleScope scope(env->isolate());
611 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
613 if (args.Length() != 1) {
614 return env->ThrowTypeError("Bad parameter");
617 if (!sc->ca_store_) {
618 sc->ca_store_ = X509_STORE_new();
622 X509* x509 = LoadX509(env, args[0]);
626 X509_STORE_add_cert(sc->ca_store_, x509);
627 SSL_CTX_add_client_CA(sc->ctx_, x509);
632 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
637 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
638 Environment* env = Environment::GetCurrent(args.GetIsolate());
639 HandleScope scope(env->isolate());
641 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
643 if (args.Length() != 1) {
644 return env->ThrowTypeError("Bad parameter");
647 ClearErrorOnReturn clear_error_on_return;
648 (void) &clear_error_on_return; // Silence compiler warning.
650 BIO *bio = LoadBIO(env, args[0]);
654 X509_CRL *x509 = PEM_read_bio_X509_CRL(bio, NULL, CryptoPemCallback, NULL);
661 X509_STORE_add_crl(sc->ca_store_, x509);
662 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
663 X509_V_FLAG_CRL_CHECK_ALL);
670 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
671 HandleScope scope(args.GetIsolate());
673 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
675 assert(sc->ca_store_ == NULL);
677 if (!root_cert_store) {
678 root_cert_store = X509_STORE_new();
680 for (int i = 0; root_certs[i]; i++) {
681 BIO* bp = NodeBIO::New();
683 if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
688 X509 *x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
695 X509_STORE_add_cert(root_cert_store, x509);
702 sc->ca_store_ = root_cert_store;
703 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
707 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
708 HandleScope scope(args.GetIsolate());
710 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
712 if (args.Length() != 1 || !args[0]->IsString()) {
713 return sc->env()->ThrowTypeError("Bad parameter");
716 const node::Utf8Value ciphers(args[0]);
717 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
721 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
722 HandleScope scope(args.GetIsolate());
724 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
725 Environment* env = sc->env();
727 if (args.Length() != 1 || !args[0]->IsString())
728 return env->ThrowTypeError("First argument should be a string");
730 node::Utf8Value curve(args[0]);
732 int nid = OBJ_sn2nid(*curve);
734 if (nid == NID_undef)
735 return env->ThrowTypeError("First argument should be a valid curve name");
737 EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
740 return env->ThrowTypeError("First argument should be a valid curve name");
742 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
743 SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
749 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
750 HandleScope scope(args.GetIsolate());
752 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
754 if (args.Length() != 1 || !args[0]->IntegerValue()) {
755 return sc->env()->ThrowTypeError("Bad parameter");
758 SSL_CTX_set_options(sc->ctx_, static_cast<long>(args[0]->IntegerValue()));
762 void SecureContext::SetSessionIdContext(
763 const FunctionCallbackInfo<Value>& args) {
764 HandleScope scope(args.GetIsolate());
766 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
768 if (args.Length() != 1 || !args[0]->IsString()) {
769 return sc->env()->ThrowTypeError("Bad parameter");
772 const node::Utf8Value sessionIdContext(args[0]);
773 const unsigned char* sid_ctx =
774 reinterpret_cast<const unsigned char*>(*sessionIdContext);
775 unsigned int sid_ctx_len = sessionIdContext.length();
777 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
783 Local<String> message;
785 bio = BIO_new(BIO_s_mem());
787 message = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
788 "SSL_CTX_set_session_id_context error");
790 ERR_print_errors(bio);
791 BIO_get_mem_ptr(bio, &mem);
792 message = OneByteString(args.GetIsolate(), mem->data, mem->length);
796 args.GetIsolate()->ThrowException(Exception::TypeError(message));
800 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
801 HandleScope scope(args.GetIsolate());
803 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
805 if (args.Length() != 1 || !args[0]->IsInt32()) {
806 return sc->env()->ThrowTypeError("Bad parameter");
809 int32_t sessionTimeout = args[0]->Int32Value();
810 SSL_CTX_set_timeout(sc->ctx_, sessionTimeout);
814 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
815 HandleScope scope(args.GetIsolate());
816 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
821 // Takes .pfx or .p12 and password in string or buffer format
822 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
823 Environment* env = Environment::GetCurrent(args.GetIsolate());
824 HandleScope scope(env->isolate());
828 EVP_PKEY* pkey = NULL;
830 STACK_OF(X509)* extraCerts = NULL;
834 SecureContext* sc = Unwrap<SecureContext>(args.Holder());
836 if (args.Length() < 1) {
837 return env->ThrowTypeError("Bad parameter");
840 in = LoadBIO(env, args[0]);
842 return env->ThrowError("Unable to load BIO");
845 if (args.Length() >= 2) {
846 ASSERT_IS_BUFFER(args[1]);
847 size_t passlen = Buffer::Length(args[1]);
848 pass = new char[passlen + 1];
849 memcpy(pass, Buffer::Data(args[1]), passlen);
850 pass[passlen] = '\0';
853 if (d2i_PKCS12_bio(in, &p12) &&
854 PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
855 SSL_CTX_use_certificate(sc->ctx_, cert) &&
856 SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) {
858 while (X509* x509 = sk_X509_pop(extraCerts)) {
859 if (!sc->ca_store_) {
860 sc->ca_store_ = X509_STORE_new();
861 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
864 X509_STORE_add_cert(sc->ca_store_, x509);
865 SSL_CTX_add_client_CA(sc->ctx_, x509);
871 sk_X509_free(extraCerts);
881 unsigned long err = ERR_get_error();
882 const char* str = ERR_reason_error_string(err);
883 return env->ThrowError(str);
888 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
889 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
890 HandleScope handle_scope(args.GetIsolate());
892 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
894 Local<Object> buff = Buffer::New(wrap->env(), 48);
895 if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_,
897 Buffer::Length(buff)) != 1) {
898 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
901 args.GetReturnValue().Set(buff);
902 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
906 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
907 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
908 HandleScope scope(args.GetIsolate());
909 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
911 if (args.Length() < 1 ||
912 !Buffer::HasInstance(args[0]) ||
913 Buffer::Length(args[0]) != 48) {
914 return wrap->env()->ThrowTypeError("Bad argument");
917 if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_,
918 Buffer::Data(args[0]),
919 Buffer::Length(args[0])) != 1) {
920 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
923 args.GetReturnValue().Set(true);
924 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
928 template <bool primary>
929 void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
930 HandleScope scope(args.GetIsolate());
931 SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
932 Environment* env = wrap->env();
938 cert = wrap->issuer_;
940 return args.GetReturnValue().Set(Null(env->isolate()));
942 int size = i2d_X509(cert, NULL);
943 Local<Object> buff = Buffer::New(env, size);
944 unsigned char* serialized = reinterpret_cast<unsigned char*>(
946 i2d_X509(cert, &serialized);
948 args.GetReturnValue().Set(buff);
952 template <class Base>
953 void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
954 HandleScope scope(env->isolate());
956 NODE_SET_PROTOTYPE_METHOD(t, "getPeerCertificate", GetPeerCertificate);
957 NODE_SET_PROTOTYPE_METHOD(t, "getSession", GetSession);
958 NODE_SET_PROTOTYPE_METHOD(t, "setSession", SetSession);
959 NODE_SET_PROTOTYPE_METHOD(t, "loadSession", LoadSession);
960 NODE_SET_PROTOTYPE_METHOD(t, "isSessionReused", IsSessionReused);
961 NODE_SET_PROTOTYPE_METHOD(t, "isInitFinished", IsInitFinished);
962 NODE_SET_PROTOTYPE_METHOD(t, "verifyError", VerifyError);
963 NODE_SET_PROTOTYPE_METHOD(t, "getCurrentCipher", GetCurrentCipher);
964 NODE_SET_PROTOTYPE_METHOD(t, "endParser", EndParser);
965 NODE_SET_PROTOTYPE_METHOD(t, "renegotiate", Renegotiate);
966 NODE_SET_PROTOTYPE_METHOD(t, "shutdown", Shutdown);
967 NODE_SET_PROTOTYPE_METHOD(t, "getTLSTicket", GetTLSTicket);
968 NODE_SET_PROTOTYPE_METHOD(t, "newSessionDone", NewSessionDone);
969 NODE_SET_PROTOTYPE_METHOD(t, "setOCSPResponse", SetOCSPResponse);
970 NODE_SET_PROTOTYPE_METHOD(t, "requestOCSP", RequestOCSP);
972 #ifdef SSL_set_max_send_fragment
973 NODE_SET_PROTOTYPE_METHOD(t, "setMaxSendFragment", SetMaxSendFragment);
974 #endif // SSL_set_max_send_fragment
976 #ifdef OPENSSL_NPN_NEGOTIATED
977 NODE_SET_PROTOTYPE_METHOD(t, "getNegotiatedProtocol", GetNegotiatedProto);
978 NODE_SET_PROTOTYPE_METHOD(t, "setNPNProtocols", SetNPNProtocols);
979 #endif // OPENSSL_NPN_NEGOTIATED
983 template <class Base>
984 void SSLWrap<Base>::InitNPN(SecureContext* sc, Base* base) {
985 if (base->is_server()) {
986 #ifdef OPENSSL_NPN_NEGOTIATED
987 // Server should advertise NPN protocols
988 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
989 AdvertiseNextProtoCallback,
991 #endif // OPENSSL_NPN_NEGOTIATED
993 #ifdef OPENSSL_NPN_NEGOTIATED
994 // Client should select protocol from list of advertised
995 // If server supports NPN
996 SSL_CTX_set_next_proto_select_cb(sc->ctx_, SelectNextProtoCallback, base);
997 #endif // OPENSSL_NPN_NEGOTIATED
1000 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1002 SSL_CTX_set_tlsext_status_cb(sc->ctx_, TLSExtStatusCallback);
1003 SSL_CTX_set_tlsext_status_arg(sc->ctx_, base);
1004 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1008 template <class Base>
1009 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
1013 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1016 SSL_SESSION* sess = w->next_sess_;
1017 w->next_sess_ = NULL;
1023 template <class Base>
1024 int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
1025 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1026 Environment* env = w->ssl_env();
1027 HandleScope handle_scope(env->isolate());
1028 Context::Scope context_scope(env->context());
1030 if (!w->session_callbacks_)
1033 // Check if session is small enough to be stored
1034 int size = i2d_SSL_SESSION(sess, NULL);
1035 if (size > SecureContext::kMaxSessionSize)
1038 // Serialize session
1039 Local<Object> buff = Buffer::New(env, size);
1040 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1041 Buffer::Data(buff));
1042 memset(serialized, 0, size);
1043 i2d_SSL_SESSION(sess, &serialized);
1045 Local<Object> session = Buffer::New(env,
1046 reinterpret_cast<char*>(sess->session_id),
1047 sess->session_id_length);
1048 Local<Value> argv[] = { session, buff };
1049 w->new_session_wait_ = true;
1050 w->MakeCallback(env->onnewsession_string(), ARRAY_SIZE(argv), argv);
1056 template <class Base>
1057 void SSLWrap<Base>::OnClientHello(void* arg,
1058 const ClientHelloParser::ClientHello& hello) {
1059 Base* w = static_cast<Base*>(arg);
1060 Environment* env = w->ssl_env();
1061 HandleScope handle_scope(env->isolate());
1062 Context::Scope context_scope(env->context());
1064 Local<Object> hello_obj = Object::New(env->isolate());
1065 Local<Object> buff = Buffer::New(
1067 reinterpret_cast<const char*>(hello.session_id()),
1068 hello.session_size());
1069 hello_obj->Set(env->session_id_string(), buff);
1070 if (hello.servername() == NULL) {
1071 hello_obj->Set(env->servername_string(), String::Empty(env->isolate()));
1073 Local<String> servername = OneByteString(env->isolate(),
1075 hello.servername_size());
1076 hello_obj->Set(env->servername_string(), servername);
1078 hello_obj->Set(env->tls_ticket_string(),
1079 Boolean::New(env->isolate(), hello.has_ticket()));
1080 hello_obj->Set(env->ocsp_request_string(),
1081 Boolean::New(env->isolate(), hello.ocsp_request()));
1083 Local<Value> argv[] = { hello_obj };
1084 w->MakeCallback(env->onclienthello_string(), ARRAY_SIZE(argv), argv);
1088 static Local<Object> X509ToObject(Environment* env, X509* cert) {
1089 EscapableHandleScope scope(env->isolate());
1091 Local<Object> info = Object::New(env->isolate());
1093 BIO* bio = BIO_new(BIO_s_mem());
1095 if (X509_NAME_print_ex(bio,
1096 X509_get_subject_name(cert),
1098 X509_NAME_FLAGS) > 0) {
1099 BIO_get_mem_ptr(bio, &mem);
1100 info->Set(env->subject_string(),
1101 OneByteString(env->isolate(), mem->data, mem->length));
1103 (void) BIO_reset(bio);
1105 X509_NAME* issuer_name = X509_get_issuer_name(cert);
1106 if (X509_NAME_print_ex(bio, issuer_name, 0, X509_NAME_FLAGS) > 0) {
1107 BIO_get_mem_ptr(bio, &mem);
1108 info->Set(env->issuer_string(),
1109 OneByteString(env->isolate(), mem->data, mem->length));
1111 (void) BIO_reset(bio);
1113 int nids[] = { NID_subject_alt_name, NID_info_access };
1114 Local<String> keys[] = { env->subjectaltname_string(),
1115 env->infoaccess_string() };
1116 CHECK_EQ(ARRAY_SIZE(nids), ARRAY_SIZE(keys));
1117 for (unsigned int i = 0; i < ARRAY_SIZE(nids); i++) {
1118 int index = X509_get_ext_by_NID(cert, nids[i], -1);
1122 X509_EXTENSION* ext;
1125 ext = X509_get_ext(cert, index);
1126 assert(ext != NULL);
1128 rv = X509V3_EXT_print(bio, ext, 0, 0);
1131 BIO_get_mem_ptr(bio, &mem);
1133 OneByteString(env->isolate(), mem->data, mem->length));
1135 (void) BIO_reset(bio);
1138 EVP_PKEY* pkey = X509_get_pubkey(cert);
1141 rsa = EVP_PKEY_get1_RSA(pkey);
1144 BN_print(bio, rsa->n);
1145 BIO_get_mem_ptr(bio, &mem);
1146 info->Set(env->modulus_string(),
1147 OneByteString(env->isolate(), mem->data, mem->length));
1148 (void) BIO_reset(bio);
1150 BN_print(bio, rsa->e);
1151 BIO_get_mem_ptr(bio, &mem);
1152 info->Set(env->exponent_string(),
1153 OneByteString(env->isolate(), mem->data, mem->length));
1154 (void) BIO_reset(bio);
1158 EVP_PKEY_free(pkey);
1166 ASN1_TIME_print(bio, X509_get_notBefore(cert));
1167 BIO_get_mem_ptr(bio, &mem);
1168 info->Set(env->valid_from_string(),
1169 OneByteString(env->isolate(), mem->data, mem->length));
1170 (void) BIO_reset(bio);
1172 ASN1_TIME_print(bio, X509_get_notAfter(cert));
1173 BIO_get_mem_ptr(bio, &mem);
1174 info->Set(env->valid_to_string(),
1175 OneByteString(env->isolate(), mem->data, mem->length));
1178 unsigned int md_size, i;
1179 unsigned char md[EVP_MAX_MD_SIZE];
1180 if (X509_digest(cert, EVP_sha1(), md, &md_size)) {
1181 const char hex[] = "0123456789ABCDEF";
1182 char fingerprint[EVP_MAX_MD_SIZE * 3];
1184 // TODO(indutny): Unify it with buffer's code
1185 for (i = 0; i < md_size; i++) {
1186 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1187 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1188 fingerprint[(3*i)+2] = ':';
1192 fingerprint[(3*(md_size-1))+2] = '\0';
1194 fingerprint[0] = '\0';
1197 info->Set(env->fingerprint_string(),
1198 OneByteString(env->isolate(), fingerprint));
1201 STACK_OF(ASN1_OBJECT)* eku = static_cast<STACK_OF(ASN1_OBJECT)*>(
1202 X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL));
1204 Local<Array> ext_key_usage = Array::New(env->isolate());
1208 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1209 if (OBJ_obj2txt(buf, sizeof(buf), sk_ASN1_OBJECT_value(eku, i), 1) >= 0)
1210 ext_key_usage->Set(j++, OneByteString(env->isolate(), buf));
1213 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1214 info->Set(env->ext_key_usage_string(), ext_key_usage);
1217 if (ASN1_INTEGER* serial_number = X509_get_serialNumber(cert)) {
1218 if (BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, NULL)) {
1219 if (char* buf = BN_bn2hex(bn)) {
1220 info->Set(env->serial_number_string(),
1221 OneByteString(env->isolate(), buf));
1228 // Raw DER certificate
1229 int size = i2d_X509(cert, NULL);
1230 Local<Object> buff = Buffer::New(env, size);
1231 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1232 Buffer::Data(buff));
1233 i2d_X509(cert, &serialized);
1234 info->Set(env->raw_string(), buff);
1236 return scope.Escape(info);
1240 // TODO(indutny): Split it into multiple smaller functions
1241 template <class Base>
1242 void SSLWrap<Base>::GetPeerCertificate(
1243 const FunctionCallbackInfo<Value>& args) {
1244 HandleScope scope(args.GetIsolate());
1246 Base* w = Unwrap<Base>(args.Holder());
1247 Environment* env = w->ssl_env();
1249 ClearErrorOnReturn clear_error_on_return;
1250 (void) &clear_error_on_return; // Silence unused variable warning.
1252 Local<Object> result;
1255 // NOTE: This is because of the odd OpenSSL behavior. On client `cert_chain`
1256 // contains the `peer_certificate`, but on server it doesn't
1257 X509* cert = w->is_server() ? SSL_get_peer_certificate(w->ssl_) : NULL;
1258 STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(w->ssl_);
1259 STACK_OF(X509)* peer_certs = NULL;
1260 if (cert == NULL && ssl_certs == NULL)
1263 if (cert == NULL && sk_X509_num(ssl_certs) == 0)
1266 // Short result requested
1267 if (args.Length() < 1 || !args[0]->IsTrue()) {
1268 result = X509ToObject(env,
1269 cert == NULL ? sk_X509_value(ssl_certs, 0) : cert);
1273 // Clone `ssl_certs`, because we are going to destruct it
1274 peer_certs = sk_X509_new(NULL);
1276 sk_X509_push(peer_certs, cert);
1277 for (int i = 0; i < sk_X509_num(ssl_certs); i++) {
1278 cert = X509_dup(sk_X509_value(ssl_certs, i));
1281 if (!sk_X509_push(peer_certs, cert))
1285 // First and main certificate
1286 cert = sk_X509_value(peer_certs, 0);
1287 result = X509ToObject(env, cert);
1290 // Put issuer inside the object
1291 cert = sk_X509_delete(peer_certs, 0);
1292 while (sk_X509_num(peer_certs) > 0) {
1294 for (i = 0; i < sk_X509_num(peer_certs); i++) {
1295 X509* ca = sk_X509_value(peer_certs, i);
1296 if (X509_check_issued(ca, cert) != X509_V_OK)
1299 Local<Object> ca_info = X509ToObject(env, ca);
1300 info->Set(env->issuercert_string(), ca_info);
1303 // NOTE: Intentionally freeing cert that is not used anymore
1306 // Delete cert and continue aggregating issuers
1307 cert = sk_X509_delete(peer_certs, i);
1311 // Issuer not found, break out of the loop
1312 if (i == sk_X509_num(peer_certs))
1316 // Last certificate should be self-signed
1317 while (X509_check_issued(cert, cert) != X509_V_OK) {
1319 if (SSL_CTX_get_issuer(w->ssl_->ctx, cert, &ca) <= 0)
1322 Local<Object> ca_info = X509ToObject(env, ca);
1323 info->Set(env->issuercert_string(), ca_info);
1326 // NOTE: Intentionally freeing cert that is not used anymore
1329 // Delete cert and continue aggregating issuers
1333 // Self-issued certificate
1334 if (X509_check_issued(cert, cert) == X509_V_OK)
1335 info->Set(env->issuercert_string(), info);
1337 CHECK_NE(cert, NULL);
1341 if (peer_certs != NULL)
1342 sk_X509_pop_free(peer_certs, X509_free);
1343 if (result.IsEmpty())
1344 result = Object::New(env->isolate());
1345 args.GetReturnValue().Set(result);
1349 template <class Base>
1350 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
1351 Environment* env = Environment::GetCurrent(args.GetIsolate());
1352 HandleScope scope(env->isolate());
1354 Base* w = Unwrap<Base>(args.Holder());
1356 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1360 int slen = i2d_SSL_SESSION(sess, NULL);
1363 unsigned char* sbuf = new unsigned char[slen];
1364 unsigned char* p = sbuf;
1365 i2d_SSL_SESSION(sess, &p);
1366 args.GetReturnValue().Set(Encode(env->isolate(), sbuf, slen, BUFFER));
1371 template <class Base>
1372 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
1373 Environment* env = Environment::GetCurrent(args.GetIsolate());
1374 HandleScope scope(env->isolate());
1376 Base* w = Unwrap<Base>(args.Holder());
1378 if (args.Length() < 1 ||
1379 (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
1380 return env->ThrowTypeError("Bad argument");
1383 ASSERT_IS_BUFFER(args[0]);
1384 size_t slen = Buffer::Length(args[0]);
1385 char* sbuf = new char[slen];
1386 memcpy(sbuf, Buffer::Data(args[0]), slen);
1388 const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
1389 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, slen);
1396 int r = SSL_set_session(w->ssl_, sess);
1397 SSL_SESSION_free(sess);
1400 return env->ThrowError("SSL_set_session error");
1404 template <class Base>
1405 void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
1406 HandleScope scope(args.GetIsolate());
1408 Base* w = Unwrap<Base>(args.Holder());
1409 Environment* env = w->ssl_env();
1411 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1412 ssize_t slen = Buffer::Length(args[0]);
1413 char* sbuf = Buffer::Data(args[0]);
1415 const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1416 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, slen);
1418 // Setup next session and move hello to the BIO buffer
1419 if (w->next_sess_ != NULL)
1420 SSL_SESSION_free(w->next_sess_);
1421 w->next_sess_ = sess;
1423 Local<Object> info = Object::New(env->isolate());
1424 #ifndef OPENSSL_NO_TLSEXT
1425 if (sess->tlsext_hostname == NULL) {
1426 info->Set(env->servername_string(), False(args.GetIsolate()));
1428 info->Set(env->servername_string(),
1429 OneByteString(args.GetIsolate(), sess->tlsext_hostname));
1432 args.GetReturnValue().Set(info);
1437 template <class Base>
1438 void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
1439 HandleScope scope(args.GetIsolate());
1440 Base* w = Unwrap<Base>(args.Holder());
1441 bool yes = SSL_session_reused(w->ssl_);
1442 args.GetReturnValue().Set(yes);
1446 template <class Base>
1447 void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
1448 HandleScope scope(args.GetIsolate());
1449 Base* w = Unwrap<Base>(args.Holder());
1450 w->hello_parser_.End();
1454 template <class Base>
1455 void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
1456 HandleScope scope(args.GetIsolate());
1458 Base* w = Unwrap<Base>(args.Holder());
1460 ClearErrorOnReturn clear_error_on_return;
1461 (void) &clear_error_on_return; // Silence unused variable warning.
1463 bool yes = SSL_renegotiate(w->ssl_) == 1;
1464 args.GetReturnValue().Set(yes);
1468 template <class Base>
1469 void SSLWrap<Base>::Shutdown(const FunctionCallbackInfo<Value>& args) {
1470 HandleScope scope(args.GetIsolate());
1472 Base* w = Unwrap<Base>(args.Holder());
1474 int rv = SSL_shutdown(w->ssl_);
1475 args.GetReturnValue().Set(rv);
1479 template <class Base>
1480 void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
1481 HandleScope scope(args.GetIsolate());
1483 Base* w = Unwrap<Base>(args.Holder());
1484 Environment* env = w->ssl_env();
1486 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1487 if (sess == NULL || sess->tlsext_tick == NULL)
1490 Local<Object> buf = Buffer::New(env,
1491 reinterpret_cast<char*>(sess->tlsext_tick),
1492 sess->tlsext_ticklen);
1494 args.GetReturnValue().Set(buf);
1498 template <class Base>
1499 void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
1500 HandleScope scope(args.GetIsolate());
1502 Base* w = Unwrap<Base>(args.Holder());
1503 w->new_session_wait_ = false;
1504 w->NewSessionDoneCb();
1508 template <class Base>
1509 void SSLWrap<Base>::SetOCSPResponse(
1510 const v8::FunctionCallbackInfo<v8::Value>& args) {
1511 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1512 HandleScope scope(args.GetIsolate());
1514 Base* w = Unwrap<Base>(args.Holder());
1515 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1516 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1518 w->ocsp_response_.Reset(args.GetIsolate(), args[0].As<Object>());
1519 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1523 template <class Base>
1524 void SSLWrap<Base>::RequestOCSP(
1525 const v8::FunctionCallbackInfo<v8::Value>& args) {
1526 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1527 HandleScope scope(args.GetIsolate());
1529 Base* w = Unwrap<Base>(args.Holder());
1531 SSL_set_tlsext_status_type(w->ssl_, TLSEXT_STATUSTYPE_ocsp);
1532 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1536 #ifdef SSL_set_max_send_fragment
1537 template <class Base>
1538 void SSLWrap<Base>::SetMaxSendFragment(
1539 const v8::FunctionCallbackInfo<v8::Value>& args) {
1540 HandleScope scope(args.GetIsolate());
1541 CHECK(args.Length() >= 1 && args[0]->IsNumber());
1543 Base* w = Unwrap<Base>(args.Holder());
1545 int rv = SSL_set_max_send_fragment(w->ssl_, args[0]->Int32Value());
1546 args.GetReturnValue().Set(rv);
1548 #endif // SSL_set_max_send_fragment
1551 template <class Base>
1552 void SSLWrap<Base>::IsInitFinished(const FunctionCallbackInfo<Value>& args) {
1553 HandleScope scope(args.GetIsolate());
1554 Base* w = Unwrap<Base>(args.Holder());
1555 bool yes = SSL_is_init_finished(w->ssl_);
1556 args.GetReturnValue().Set(yes);
1560 template <class Base>
1561 void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
1562 HandleScope scope(args.GetIsolate());
1564 Base* w = Unwrap<Base>(args.Holder());
1566 // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
1567 // peer certificate is questionable but it's compatible with what was
1569 long x509_verify_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
1570 if (X509* peer_cert = SSL_get_peer_certificate(w->ssl_)) {
1571 X509_free(peer_cert);
1572 x509_verify_error = SSL_get_verify_result(w->ssl_);
1575 if (x509_verify_error == X509_V_OK)
1576 return args.GetReturnValue().SetNull();
1578 // XXX(bnoordhuis) X509_verify_cert_error_string() is not actually thread-safe
1579 // in the presence of invalid error codes. Probably academical but something
1580 // to keep in mind if/when node ever grows multi-isolate capabilities.
1581 const char* reason = X509_verify_cert_error_string(x509_verify_error);
1582 const char* code = reason;
1583 #define CASE_X509_ERR(CODE) case X509_V_ERR_##CODE: code = #CODE; break;
1584 switch (x509_verify_error) {
1585 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT)
1586 CASE_X509_ERR(UNABLE_TO_GET_CRL)
1587 CASE_X509_ERR(UNABLE_TO_DECRYPT_CERT_SIGNATURE)
1588 CASE_X509_ERR(UNABLE_TO_DECRYPT_CRL_SIGNATURE)
1589 CASE_X509_ERR(UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)
1590 CASE_X509_ERR(CERT_SIGNATURE_FAILURE)
1591 CASE_X509_ERR(CRL_SIGNATURE_FAILURE)
1592 CASE_X509_ERR(CERT_NOT_YET_VALID)
1593 CASE_X509_ERR(CERT_HAS_EXPIRED)
1594 CASE_X509_ERR(CRL_NOT_YET_VALID)
1595 CASE_X509_ERR(CRL_HAS_EXPIRED)
1596 CASE_X509_ERR(ERROR_IN_CERT_NOT_BEFORE_FIELD)
1597 CASE_X509_ERR(ERROR_IN_CERT_NOT_AFTER_FIELD)
1598 CASE_X509_ERR(ERROR_IN_CRL_LAST_UPDATE_FIELD)
1599 CASE_X509_ERR(ERROR_IN_CRL_NEXT_UPDATE_FIELD)
1600 CASE_X509_ERR(OUT_OF_MEM)
1601 CASE_X509_ERR(DEPTH_ZERO_SELF_SIGNED_CERT)
1602 CASE_X509_ERR(SELF_SIGNED_CERT_IN_CHAIN)
1603 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
1604 CASE_X509_ERR(UNABLE_TO_VERIFY_LEAF_SIGNATURE)
1605 CASE_X509_ERR(CERT_CHAIN_TOO_LONG)
1606 CASE_X509_ERR(CERT_REVOKED)
1607 CASE_X509_ERR(INVALID_CA)
1608 CASE_X509_ERR(PATH_LENGTH_EXCEEDED)
1609 CASE_X509_ERR(INVALID_PURPOSE)
1610 CASE_X509_ERR(CERT_UNTRUSTED)
1611 CASE_X509_ERR(CERT_REJECTED)
1613 #undef CASE_X509_ERR
1615 Isolate* isolate = args.GetIsolate();
1616 Local<String> reason_string = OneByteString(isolate, reason);
1617 Local<Value> exception_value = Exception::Error(reason_string);
1618 Local<Object> exception_object = exception_value->ToObject();
1619 exception_object->Set(FIXED_ONE_BYTE_STRING(isolate, "code"),
1620 OneByteString(isolate, code));
1621 args.GetReturnValue().Set(exception_object);
1625 template <class Base>
1626 void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
1627 HandleScope scope(args.GetIsolate());
1629 Base* w = Unwrap<Base>(args.Holder());
1630 Environment* env = w->ssl_env();
1632 OPENSSL_CONST SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_);
1636 Local<Object> info = Object::New(env->isolate());
1637 const char* cipher_name = SSL_CIPHER_get_name(c);
1638 info->Set(env->name_string(), OneByteString(args.GetIsolate(), cipher_name));
1639 const char* cipher_version = SSL_CIPHER_get_version(c);
1640 info->Set(env->version_string(),
1641 OneByteString(args.GetIsolate(), cipher_version));
1642 args.GetReturnValue().Set(info);
1646 #ifdef OPENSSL_NPN_NEGOTIATED
1647 template <class Base>
1648 int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s,
1649 const unsigned char** data,
1652 Base* w = static_cast<Base*>(arg);
1653 Environment* env = w->env();
1654 HandleScope handle_scope(env->isolate());
1655 Context::Scope context_scope(env->context());
1657 if (w->npn_protos_.IsEmpty()) {
1658 // No initialization - no NPN protocols
1659 *data = reinterpret_cast<const unsigned char*>("");
1662 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1663 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1664 *len = Buffer::Length(obj);
1667 return SSL_TLSEXT_ERR_OK;
1671 template <class Base>
1672 int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
1673 unsigned char** out,
1674 unsigned char* outlen,
1675 const unsigned char* in,
1678 Base* w = static_cast<Base*>(arg);
1679 Environment* env = w->env();
1680 HandleScope handle_scope(env->isolate());
1681 Context::Scope context_scope(env->context());
1683 // Release old protocol handler if present
1684 w->selected_npn_proto_.Reset();
1686 if (w->npn_protos_.IsEmpty()) {
1687 // We should at least select one protocol
1688 // If server is using NPN
1689 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
1692 // set status: unsupported
1693 w->selected_npn_proto_.Reset(env->isolate(), False(env->isolate()));
1695 return SSL_TLSEXT_ERR_OK;
1698 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1699 const unsigned char* npn_protos =
1700 reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1701 size_t len = Buffer::Length(obj);
1703 int status = SSL_select_next_proto(out, outlen, in, inlen, npn_protos, len);
1704 Handle<Value> result;
1706 case OPENSSL_NPN_UNSUPPORTED:
1707 result = Null(env->isolate());
1709 case OPENSSL_NPN_NEGOTIATED:
1710 result = OneByteString(env->isolate(), *out, *outlen);
1712 case OPENSSL_NPN_NO_OVERLAP:
1713 result = False(env->isolate());
1719 if (!result.IsEmpty())
1720 w->selected_npn_proto_.Reset(env->isolate(), result);
1722 return SSL_TLSEXT_ERR_OK;
1726 template <class Base>
1727 void SSLWrap<Base>::GetNegotiatedProto(
1728 const FunctionCallbackInfo<Value>& args) {
1729 HandleScope scope(args.GetIsolate());
1731 Base* w = Unwrap<Base>(args.Holder());
1733 if (w->is_client()) {
1734 if (w->selected_npn_proto_.IsEmpty() == false) {
1735 args.GetReturnValue().Set(w->selected_npn_proto_);
1740 const unsigned char* npn_proto;
1741 unsigned int npn_proto_len;
1743 SSL_get0_next_proto_negotiated(w->ssl_, &npn_proto, &npn_proto_len);
1746 return args.GetReturnValue().Set(false);
1748 args.GetReturnValue().Set(
1749 OneByteString(args.GetIsolate(), npn_proto, npn_proto_len));
1753 template <class Base>
1754 void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
1755 HandleScope scope(args.GetIsolate());
1757 Base* w = Unwrap<Base>(args.Holder());
1759 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1760 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1762 w->npn_protos_.Reset(args.GetIsolate(), args[0].As<Object>());
1764 #endif // OPENSSL_NPN_NEGOTIATED
1767 #ifdef NODE__HAVE_TLSEXT_STATUS_CB
1768 template <class Base>
1769 int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
1770 Base* w = static_cast<Base*>(arg);
1771 Environment* env = w->env();
1772 HandleScope handle_scope(env->isolate());
1774 if (w->is_client()) {
1775 // Incoming response
1776 const unsigned char* resp;
1777 int len = SSL_get_tlsext_status_ocsp_resp(s, &resp);
1780 arg = Null(env->isolate());
1784 reinterpret_cast<char*>(const_cast<unsigned char*>(resp)),
1788 w->MakeCallback(env->onocspresponse_string(), 1, &arg);
1790 // Somehow, client is expecting different return value here
1793 // Outgoing response
1794 if (w->ocsp_response_.IsEmpty())
1795 return SSL_TLSEXT_ERR_NOACK;
1797 Local<Object> obj = PersistentToLocal(env->isolate(), w->ocsp_response_);
1798 char* resp = Buffer::Data(obj);
1799 size_t len = Buffer::Length(obj);
1801 // OpenSSL takes control of the pointer after accepting it
1802 char* data = reinterpret_cast<char*>(malloc(len));
1803 assert(data != NULL);
1804 memcpy(data, resp, len);
1806 if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
1808 w->ocsp_response_.Reset();
1810 return SSL_TLSEXT_ERR_OK;
1813 #endif // NODE__HAVE_TLSEXT_STATUS_CB
1816 void Connection::OnClientHelloParseEnd(void* arg) {
1817 Connection* conn = static_cast<Connection*>(arg);
1819 // Write all accumulated data
1820 int r = BIO_write(conn->bio_read_,
1821 reinterpret_cast<char*>(conn->hello_data_),
1822 conn->hello_offset_);
1823 conn->HandleBIOError(conn->bio_read_, "BIO_write", r);
1824 conn->SetShutdownFlags();
1828 #ifdef SSL_PRINT_DEBUG
1829 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
1831 # define DEBUG_PRINT(...)
1835 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
1839 int retry = BIO_should_retry(bio);
1840 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
1842 if (BIO_should_write(bio)) {
1843 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n",
1849 } else if (BIO_should_read(bio)) {
1850 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
1854 char ssl_error_buf[512];
1855 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
1857 HandleScope scope(ssl_env()->isolate());
1858 Local<Value> exception =
1859 Exception::Error(OneByteString(ssl_env()->isolate(), ssl_error_buf));
1860 object()->Set(ssl_env()->error_string(), exception);
1862 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
1875 int Connection::HandleSSLError(const char* func,
1879 ClearErrorOnReturn clear_error_on_return;
1880 (void) &clear_error_on_return; // Silence unused variable warning.
1884 if (rv == 0 && zs == kZeroIsNotAnError)
1887 int err = SSL_get_error(ssl_, rv);
1889 if (err == SSL_ERROR_NONE) {
1892 } else if (err == SSL_ERROR_WANT_WRITE) {
1893 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
1896 } else if (err == SSL_ERROR_WANT_READ) {
1897 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
1900 } else if (err == SSL_ERROR_ZERO_RETURN) {
1901 HandleScope scope(ssl_env()->isolate());
1903 Local<Value> exception =
1904 Exception::Error(ssl_env()->zero_return_string());
1905 object()->Set(ssl_env()->error_string(), exception);
1908 } else if (err == SSL_ERROR_SYSCALL && ss == kIgnoreSyscall) {
1912 HandleScope scope(ssl_env()->isolate());
1916 assert(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
1918 // XXX We need to drain the error queue for this thread or else OpenSSL
1919 // has the possibility of blocking connections? This problem is not well
1920 // understood. And we should be somehow propagating these errors up
1921 // into JavaScript. There is no test which demonstrates this problem.
1922 // https://github.com/joyent/node/issues/1719
1923 bio = BIO_new(BIO_s_mem());
1925 ERR_print_errors(bio);
1926 BIO_get_mem_ptr(bio, &mem);
1927 Local<Value> exception = Exception::Error(
1928 OneByteString(ssl_env()->isolate(),
1931 object()->Set(ssl_env()->error_string(), exception);
1942 void Connection::ClearError() {
1944 HandleScope scope(ssl_env()->isolate());
1946 // We should clear the error in JS-land
1947 Local<String> error_key = ssl_env()->error_string();
1948 Local<Value> error = object()->Get(error_key);
1949 assert(error->BooleanValue() == false);
1954 void Connection::SetShutdownFlags() {
1955 HandleScope scope(ssl_env()->isolate());
1957 int flags = SSL_get_shutdown(ssl_);
1959 if (flags & SSL_SENT_SHUTDOWN) {
1960 Local<String> sent_shutdown_key = ssl_env()->sent_shutdown_string();
1961 object()->Set(sent_shutdown_key, True(ssl_env()->isolate()));
1964 if (flags & SSL_RECEIVED_SHUTDOWN) {
1965 Local<String> received_shutdown_key = ssl_env()->received_shutdown_string();
1966 object()->Set(received_shutdown_key, True(ssl_env()->isolate()));
1971 void Connection::NewSessionDoneCb() {
1972 HandleScope scope(env()->isolate());
1974 MakeCallback(env()->onnewsessiondone_string(), 0, NULL);
1978 void Connection::Initialize(Environment* env, Handle<Object> target) {
1979 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(),
1981 t->InstanceTemplate()->SetInternalFieldCount(1);
1982 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"));
1984 NODE_SET_PROTOTYPE_METHOD(t, "encIn", Connection::EncIn);
1985 NODE_SET_PROTOTYPE_METHOD(t, "clearOut", Connection::ClearOut);
1986 NODE_SET_PROTOTYPE_METHOD(t, "clearIn", Connection::ClearIn);
1987 NODE_SET_PROTOTYPE_METHOD(t, "encOut", Connection::EncOut);
1988 NODE_SET_PROTOTYPE_METHOD(t, "clearPending", Connection::ClearPending);
1989 NODE_SET_PROTOTYPE_METHOD(t, "encPending", Connection::EncPending);
1990 NODE_SET_PROTOTYPE_METHOD(t, "start", Connection::Start);
1991 NODE_SET_PROTOTYPE_METHOD(t, "close", Connection::Close);
1993 SSLWrap<Connection>::AddMethods(env, t);
1995 #ifdef OPENSSL_NPN_NEGOTIATED
1996 NODE_SET_PROTOTYPE_METHOD(t,
1997 "getNegotiatedProtocol",
1998 Connection::GetNegotiatedProto);
1999 NODE_SET_PROTOTYPE_METHOD(t,
2001 Connection::SetNPNProtocols);
2005 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2006 NODE_SET_PROTOTYPE_METHOD(t, "getServername", Connection::GetServername);
2007 NODE_SET_PROTOTYPE_METHOD(t, "setSNICallback", Connection::SetSNICallback);
2010 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"),
2015 int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
2016 // Quoting SSL_set_verify(3ssl):
2018 // The VerifyCallback function is used to control the behaviour when
2019 // the SSL_VERIFY_PEER flag is set. It must be supplied by the
2020 // application and receives two arguments: preverify_ok indicates,
2021 // whether the verification of the certificate in question was passed
2022 // (preverify_ok=1) or not (preverify_ok=0). x509_ctx is a pointer to
2023 // the complete context used for the certificate chain verification.
2025 // The certificate chain is checked starting with the deepest nesting
2026 // level (the root CA certificate) and worked upward to the peer's
2027 // certificate. At each level signatures and issuer attributes are
2028 // checked. Whenever a verification error is found, the error number is
2029 // stored in x509_ctx and VerifyCallback is called with preverify_ok=0.
2030 // By applying X509_CTX_store_* functions VerifyCallback can locate the
2031 // certificate in question and perform additional steps (see EXAMPLES).
2032 // If no error is found for a certificate, VerifyCallback is called
2033 // with preverify_ok=1 before advancing to the next level.
2035 // The return value of VerifyCallback controls the strategy of the
2036 // further verification process. If VerifyCallback returns 0, the
2037 // verification process is immediately stopped with "verification
2038 // failed" state. If SSL_VERIFY_PEER is set, a verification failure
2039 // alert is sent to the peer and the TLS/SSL handshake is terminated. If
2040 // VerifyCallback returns 1, the verification process is continued. If
2041 // VerifyCallback always returns 1, the TLS/SSL handshake will not be
2042 // terminated with respect to verification failures and the connection
2043 // will be established. The calling process can however retrieve the
2044 // error code of the last verification error using
2045 // SSL_get_verify_result(3) or by maintaining its own error storage
2046 // managed by VerifyCallback.
2048 // If no VerifyCallback is specified, the default callback will be
2049 // used. Its return value is identical to preverify_ok, so that any
2050 // verification failure will lead to a termination of the TLS/SSL
2051 // handshake with an alert message, if SSL_VERIFY_PEER is set.
2053 // Since we cannot perform I/O quickly enough in this callback, we ignore
2054 // all preverify_ok errors and let the handshake continue. It is
2055 // imparative that the user use Connection::VerifyError after the
2056 // 'secure' callback has been made.
2061 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2062 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
2063 Connection* conn = static_cast<Connection*>(SSL_get_app_data(s));
2064 Environment* env = conn->env();
2065 HandleScope scope(env->isolate());
2067 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
2070 conn->servername_.Reset(env->isolate(),
2071 OneByteString(env->isolate(), servername));
2073 // Call the SNI callback and use its return value as context
2074 if (!conn->sniObject_.IsEmpty()) {
2075 conn->sniContext_.Reset();
2077 Local<Value> arg = PersistentToLocal(env->isolate(), conn->servername_);
2078 Local<Value> ret = conn->MakeCallback(env->onselect_string(), 1, &arg);
2080 // If ret is SecureContext
2081 Local<FunctionTemplate> secure_context_constructor_template =
2082 env->secure_context_constructor_template();
2083 if (secure_context_constructor_template->HasInstance(ret)) {
2084 conn->sniContext_.Reset(env->isolate(), ret);
2085 SecureContext* sc = Unwrap<SecureContext>(ret.As<Object>());
2087 SSL_set_SSL_CTX(s, sc->ctx_);
2089 return SSL_TLSEXT_ERR_NOACK;
2094 return SSL_TLSEXT_ERR_OK;
2098 void Connection::New(const FunctionCallbackInfo<Value>& args) {
2099 Environment* env = Environment::GetCurrent(args.GetIsolate());
2100 HandleScope scope(env->isolate());
2102 if (args.Length() < 1 || !args[0]->IsObject()) {
2103 env->ThrowError("First argument must be a tls module SecureContext");
2107 SecureContext* sc = Unwrap<SecureContext>(args[0]->ToObject());
2109 bool is_server = args[1]->BooleanValue();
2111 SSLWrap<Connection>::Kind kind =
2112 is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient;
2113 Connection* conn = new Connection(env, args.This(), sc, kind);
2114 conn->bio_read_ = NodeBIO::New();
2115 conn->bio_write_ = NodeBIO::New();
2117 SSL_set_app_data(conn->ssl_, conn);
2120 SSL_set_info_callback(conn->ssl_, SSLInfoCallback);
2124 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2126 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
2127 } else if (args[2]->IsString()) {
2128 const node::Utf8Value servername(args[2]);
2129 SSL_set_tlsext_host_name(conn->ssl_, *servername);
2133 SSL_set_bio(conn->ssl_, conn->bio_read_, conn->bio_write_);
2135 #ifdef SSL_MODE_RELEASE_BUFFERS
2136 long mode = SSL_get_mode(conn->ssl_);
2137 SSL_set_mode(conn->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
2143 bool request_cert = args[2]->BooleanValue();
2144 if (!request_cert) {
2145 // Note reject_unauthorized ignored.
2146 verify_mode = SSL_VERIFY_NONE;
2148 bool reject_unauthorized = args[3]->BooleanValue();
2149 verify_mode = SSL_VERIFY_PEER;
2150 if (reject_unauthorized)
2151 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2154 // Note request_cert and reject_unauthorized are ignored for clients.
2155 verify_mode = SSL_VERIFY_NONE;
2159 // Always allow a connection. We'll reject in javascript.
2160 SSL_set_verify(conn->ssl_, verify_mode, VerifyCallback);
2163 SSL_set_accept_state(conn->ssl_);
2165 SSL_set_connect_state(conn->ssl_);
2170 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
2171 if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
2174 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
2175 // a non-const SSL* in OpenSSL <= 0.9.7e.
2176 SSL* ssl = const_cast<SSL*>(ssl_);
2177 Connection* conn = static_cast<Connection*>(SSL_get_app_data(ssl));
2178 Environment* env = conn->env();
2179 HandleScope handle_scope(env->isolate());
2180 Context::Scope context_scope(env->context());
2182 if (where & SSL_CB_HANDSHAKE_START) {
2183 conn->MakeCallback(env->onhandshakestart_string(), 0, NULL);
2186 if (where & SSL_CB_HANDSHAKE_DONE) {
2187 conn->MakeCallback(env->onhandshakedone_string(), 0, NULL);
2192 void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
2193 HandleScope scope(args.GetIsolate());
2195 Connection* conn = Unwrap<Connection>(args.Holder());
2196 Environment* env = conn->env();
2198 if (args.Length() < 3) {
2199 return env->ThrowTypeError("Takes 3 parameters");
2202 if (!Buffer::HasInstance(args[0])) {
2203 return env->ThrowTypeError("Second argument should be a buffer");
2206 char* buffer_data = Buffer::Data(args[0]);
2207 size_t buffer_length = Buffer::Length(args[0]);
2209 size_t off = args[1]->Int32Value();
2210 size_t len = args[2]->Int32Value();
2212 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2213 return env->ThrowError("off + len > buffer.length");
2216 char* data = buffer_data + off;
2218 if (conn->is_server() && !conn->hello_parser_.IsEnded()) {
2219 // Just accumulate data, everything will be pushed to BIO later
2220 if (conn->hello_parser_.IsPaused()) {
2223 // Copy incoming data to the internal buffer
2224 // (which has a size of the biggest possible TLS frame)
2225 size_t available = sizeof(conn->hello_data_) - conn->hello_offset_;
2226 size_t copied = len < available ? len : available;
2227 memcpy(conn->hello_data_ + conn->hello_offset_, data, copied);
2228 conn->hello_offset_ += copied;
2230 conn->hello_parser_.Parse(conn->hello_data_, conn->hello_offset_);
2231 bytes_written = copied;
2234 bytes_written = BIO_write(conn->bio_read_, data, len);
2235 conn->HandleBIOError(conn->bio_read_, "BIO_write", bytes_written);
2236 conn->SetShutdownFlags();
2239 args.GetReturnValue().Set(bytes_written);
2243 void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
2244 HandleScope scope(args.GetIsolate());
2246 Connection* conn = Unwrap<Connection>(args.Holder());
2247 Environment* env = conn->env();
2249 if (args.Length() < 3) {
2250 return env->ThrowTypeError("Takes 3 parameters");
2253 if (!Buffer::HasInstance(args[0])) {
2254 return env->ThrowTypeError("Second argument should be a buffer");
2257 char* buffer_data = Buffer::Data(args[0]);
2258 size_t buffer_length = Buffer::Length(args[0]);
2260 size_t off = args[1]->Int32Value();
2261 size_t len = args[2]->Int32Value();
2263 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2264 return env->ThrowError("off + len > buffer.length");
2266 if (!SSL_is_init_finished(conn->ssl_)) {
2269 if (conn->is_server()) {
2270 rv = SSL_accept(conn->ssl_);
2271 conn->HandleSSLError("SSL_accept:ClearOut",
2276 rv = SSL_connect(conn->ssl_);
2277 conn->HandleSSLError("SSL_connect:ClearOut",
2284 return args.GetReturnValue().Set(rv);
2288 int bytes_read = SSL_read(conn->ssl_, buffer_data + off, len);
2289 conn->HandleSSLError("SSL_read:ClearOut",
2293 conn->SetShutdownFlags();
2295 args.GetReturnValue().Set(bytes_read);
2299 void Connection::ClearPending(const FunctionCallbackInfo<Value>& args) {
2300 HandleScope scope(args.GetIsolate());
2301 Connection* conn = Unwrap<Connection>(args.Holder());
2302 int bytes_pending = BIO_pending(conn->bio_read_);
2303 args.GetReturnValue().Set(bytes_pending);
2307 void Connection::EncPending(const FunctionCallbackInfo<Value>& args) {
2308 HandleScope scope(args.GetIsolate());
2309 Connection* conn = Unwrap<Connection>(args.Holder());
2310 int bytes_pending = BIO_pending(conn->bio_write_);
2311 args.GetReturnValue().Set(bytes_pending);
2315 void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
2316 HandleScope scope(args.GetIsolate());
2318 Connection* conn = Unwrap<Connection>(args.Holder());
2319 Environment* env = conn->env();
2321 if (args.Length() < 3) {
2322 return env->ThrowTypeError("Takes 3 parameters");
2325 if (!Buffer::HasInstance(args[0])) {
2326 return env->ThrowTypeError("Second argument should be a buffer");
2329 char* buffer_data = Buffer::Data(args[0]);
2330 size_t buffer_length = Buffer::Length(args[0]);
2332 size_t off = args[1]->Int32Value();
2333 size_t len = args[2]->Int32Value();
2335 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2336 return env->ThrowError("off + len > buffer.length");
2338 int bytes_read = BIO_read(conn->bio_write_, buffer_data + off, len);
2340 conn->HandleBIOError(conn->bio_write_, "BIO_read:EncOut", bytes_read);
2341 conn->SetShutdownFlags();
2343 args.GetReturnValue().Set(bytes_read);
2347 void Connection::ClearIn(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 if (!SSL_is_init_finished(conn->ssl_)) {
2372 if (conn->is_server()) {
2373 rv = SSL_accept(conn->ssl_);
2374 conn->HandleSSLError("SSL_accept:ClearIn",
2379 rv = SSL_connect(conn->ssl_);
2380 conn->HandleSSLError("SSL_connect:ClearIn",
2387 return args.GetReturnValue().Set(rv);
2391 int bytes_written = SSL_write(conn->ssl_, buffer_data + off, len);
2393 conn->HandleSSLError("SSL_write:ClearIn",
2395 len == 0 ? kZeroIsNotAnError : kZeroIsAnError,
2397 conn->SetShutdownFlags();
2399 args.GetReturnValue().Set(bytes_written);
2403 void Connection::Start(const FunctionCallbackInfo<Value>& args) {
2404 HandleScope scope(args.GetIsolate());
2406 Connection* conn = Unwrap<Connection>(args.Holder());
2409 if (!SSL_is_init_finished(conn->ssl_)) {
2410 if (conn->is_server()) {
2411 rv = SSL_accept(conn->ssl_);
2412 conn->HandleSSLError("SSL_accept:Start",
2417 rv = SSL_connect(conn->ssl_);
2418 conn->HandleSSLError("SSL_connect:Start",
2424 args.GetReturnValue().Set(rv);
2428 void Connection::Close(const FunctionCallbackInfo<Value>& args) {
2429 HandleScope scope(args.GetIsolate());
2431 Connection* conn = Unwrap<Connection>(args.Holder());
2433 if (conn->ssl_ != NULL) {
2434 SSL_free(conn->ssl_);
2440 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2441 void Connection::GetServername(const FunctionCallbackInfo<Value>& args) {
2442 HandleScope scope(args.GetIsolate());
2444 Connection* conn = Unwrap<Connection>(args.Holder());
2446 if (conn->is_server() && !conn->servername_.IsEmpty()) {
2447 args.GetReturnValue().Set(conn->servername_);
2449 args.GetReturnValue().Set(false);
2454 void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) {
2455 HandleScope scope(args.GetIsolate());
2457 Connection* conn = Unwrap<Connection>(args.Holder());
2458 Environment* env = conn->env();
2460 if (args.Length() < 1 || !args[0]->IsFunction()) {
2461 return env->ThrowError("Must give a Function as first argument");
2464 Local<Object> obj = Object::New(env->isolate());
2465 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "onselect"), args[0]);
2466 conn->sniObject_.Reset(args.GetIsolate(), obj);
2471 void CipherBase::Initialize(Environment* env, Handle<Object> target) {
2472 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
2474 t->InstanceTemplate()->SetInternalFieldCount(1);
2476 NODE_SET_PROTOTYPE_METHOD(t, "init", Init);
2477 NODE_SET_PROTOTYPE_METHOD(t, "initiv", InitIv);
2478 NODE_SET_PROTOTYPE_METHOD(t, "update", Update);
2479 NODE_SET_PROTOTYPE_METHOD(t, "final", Final);
2480 NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
2481 NODE_SET_PROTOTYPE_METHOD(t, "getAuthTag", GetAuthTag);
2482 NODE_SET_PROTOTYPE_METHOD(t, "setAuthTag", SetAuthTag);
2483 NODE_SET_PROTOTYPE_METHOD(t, "setAAD", SetAAD);
2485 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "CipherBase"),
2490 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
2491 assert(args.IsConstructCall() == true);
2492 HandleScope handle_scope(args.GetIsolate());
2493 CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
2494 Environment* env = Environment::GetCurrent(args.GetIsolate());
2495 new CipherBase(env, args.This(), kind);
2499 void CipherBase::Init(const char* cipher_type,
2500 const char* key_buf,
2502 HandleScope scope(env()->isolate());
2504 assert(cipher_ == NULL);
2505 cipher_ = EVP_get_cipherbyname(cipher_type);
2506 if (cipher_ == NULL) {
2507 return env()->ThrowError("Unknown cipher");
2510 unsigned char key[EVP_MAX_KEY_LENGTH];
2511 unsigned char iv[EVP_MAX_IV_LENGTH];
2513 int key_len = EVP_BytesToKey(cipher_,
2516 reinterpret_cast<const unsigned char*>(key_buf),
2522 EVP_CIPHER_CTX_init(&ctx_);
2523 EVP_CipherInit_ex(&ctx_, cipher_, NULL, NULL, NULL, kind_ == kCipher);
2524 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2525 EVP_CIPHER_CTX_cleanup(&ctx_);
2526 return env()->ThrowError("Invalid key length");
2529 EVP_CipherInit_ex(&ctx_,
2532 reinterpret_cast<unsigned char*>(key),
2533 reinterpret_cast<unsigned char*>(iv),
2535 initialised_ = true;
2539 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
2540 HandleScope scope(args.GetIsolate());
2542 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2544 if (args.Length() < 2 ||
2545 !(args[0]->IsString() && Buffer::HasInstance(args[1]))) {
2546 return cipher->env()->ThrowError("Must give cipher-type, key");
2549 const node::Utf8Value cipher_type(args[0]);
2550 const char* key_buf = Buffer::Data(args[1]);
2551 ssize_t key_buf_len = Buffer::Length(args[1]);
2552 cipher->Init(*cipher_type, key_buf, key_buf_len);
2556 void CipherBase::InitIv(const char* cipher_type,
2561 HandleScope scope(env()->isolate());
2563 cipher_ = EVP_get_cipherbyname(cipher_type);
2564 if (cipher_ == NULL) {
2565 return env()->ThrowError("Unknown cipher");
2568 /* OpenSSL versions up to 0.9.8l failed to return the correct
2569 iv_length (0) for ECB ciphers */
2570 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
2571 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2572 return env()->ThrowError("Invalid IV length");
2574 EVP_CIPHER_CTX_init(&ctx_);
2575 EVP_CipherInit_ex(&ctx_, cipher_, NULL, NULL, NULL, kind_ == kCipher);
2576 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2577 EVP_CIPHER_CTX_cleanup(&ctx_);
2578 return env()->ThrowError("Invalid key length");
2581 EVP_CipherInit_ex(&ctx_,
2584 reinterpret_cast<const unsigned char*>(key),
2585 reinterpret_cast<const unsigned char*>(iv),
2587 initialised_ = true;
2591 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
2592 HandleScope scope(args.GetIsolate());
2594 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2595 Environment* env = cipher->env();
2597 if (args.Length() < 3 || !args[0]->IsString()) {
2598 return env->ThrowError("Must give cipher-type, key, and iv as argument");
2601 ASSERT_IS_BUFFER(args[1]);
2602 ASSERT_IS_BUFFER(args[2]);
2604 const node::Utf8Value cipher_type(args[0]);
2605 ssize_t key_len = Buffer::Length(args[1]);
2606 const char* key_buf = Buffer::Data(args[1]);
2607 ssize_t iv_len = Buffer::Length(args[2]);
2608 const char* iv_buf = Buffer::Data(args[2]);
2609 cipher->InitIv(*cipher_type, key_buf, key_len, iv_buf, iv_len);
2613 bool CipherBase::IsAuthenticatedMode() const {
2614 // check if this cipher operates in an AEAD mode that we support.
2617 int mode = EVP_CIPHER_mode(cipher_);
2618 return mode == EVP_CIPH_GCM_MODE;
2622 bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
2623 // only callable after Final and if encrypting.
2624 if (initialised_ || kind_ != kCipher || !auth_tag_)
2626 *out_len = auth_tag_len_;
2627 *out = new char[auth_tag_len_];
2628 memcpy(*out, auth_tag_, auth_tag_len_);
2633 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
2634 Environment* env = Environment::GetCurrent(args.GetIsolate());
2635 HandleScope handle_scope(args.GetIsolate());
2636 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2639 unsigned int out_len = 0;
2641 if (cipher->GetAuthTag(&out, &out_len)) {
2642 Local<Object> buf = Buffer::Use(env, out, out_len);
2643 args.GetReturnValue().Set(buf);
2645 env->ThrowError("Attempting to get auth tag in unsupported state");
2650 bool CipherBase::SetAuthTag(const char* data, unsigned int len) {
2651 if (!initialised_ || !IsAuthenticatedMode() || kind_ != kDecipher)
2654 auth_tag_len_ = len;
2655 auth_tag_ = new char[len];
2656 memcpy(auth_tag_, data, len);
2661 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
2662 HandleScope handle_scope(args.GetIsolate());
2663 Environment* env = Environment::GetCurrent(args.GetIsolate());
2665 Local<Object> buf = args[0].As<Object>();
2666 if (!buf->IsObject() || !Buffer::HasInstance(buf))
2667 return env->ThrowTypeError("Argument must be a Buffer");
2669 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2671 if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf)))
2672 env->ThrowError("Attempting to set auth tag in unsupported state");
2676 bool CipherBase::SetAAD(const char* data, unsigned int len) {
2677 if (!initialised_ || !IsAuthenticatedMode())
2680 if (!EVP_CipherUpdate(&ctx_,
2683 reinterpret_cast<const unsigned char*>(data),
2691 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
2692 Environment* env = Environment::GetCurrent(args.GetIsolate());
2693 HandleScope handle_scope(env->isolate());
2695 ASSERT_IS_BUFFER(args[0]);
2697 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2699 if (!cipher->SetAAD(Buffer::Data(args[0]), Buffer::Length(args[0])))
2700 env->ThrowError("Attempting to set AAD in unsupported state");
2704 bool CipherBase::Update(const char* data,
2706 unsigned char** out,
2712 if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_ != NULL) {
2713 EVP_CIPHER_CTX_ctrl(&ctx_,
2714 EVP_CTRL_GCM_SET_TAG,
2716 reinterpret_cast<unsigned char*>(auth_tag_));
2721 *out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
2722 *out = new unsigned char[*out_len];
2723 return EVP_CipherUpdate(&ctx_,
2726 reinterpret_cast<const unsigned char*>(data),
2731 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
2732 HandleScope handle_scope(args.GetIsolate());
2733 Environment* env = Environment::GetCurrent(args.GetIsolate());
2735 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2737 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2739 unsigned char* out = NULL;
2743 // Only copy the data if we have to, because it's a string
2744 if (args[0]->IsString()) {
2745 Local<String> string = args[0].As<String>();
2746 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2747 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2748 return env->ThrowTypeError("Bad input string");
2749 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2750 char* buf = new char[buflen];
2751 size_t written = StringBytes::Write(env->isolate(),
2756 r = cipher->Update(buf, written, &out, &out_len);
2759 char* buf = Buffer::Data(args[0]);
2760 size_t buflen = Buffer::Length(args[0]);
2761 r = cipher->Update(buf, buflen, &out, &out_len);
2766 return ThrowCryptoError(env,
2768 "Trying to add data in unsupported state");
2771 Local<Object> buf = Buffer::New(env, reinterpret_cast<char*>(out), out_len);
2775 args.GetReturnValue().Set(buf);
2779 bool CipherBase::SetAutoPadding(bool auto_padding) {
2782 return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
2786 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
2787 HandleScope scope(args.GetIsolate());
2788 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2789 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2793 bool CipherBase::Final(unsigned char** out, int *out_len) {
2797 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx_)];
2798 int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
2800 if (r && kind_ == kCipher) {
2803 if (IsAuthenticatedMode()) {
2804 auth_tag_len_ = EVP_GCM_TLS_TAG_LEN; // use default tag length
2805 auth_tag_ = new char[auth_tag_len_];
2806 memset(auth_tag_, 0, auth_tag_len_);
2807 EVP_CIPHER_CTX_ctrl(&ctx_,
2808 EVP_CTRL_GCM_GET_TAG,
2810 reinterpret_cast<unsigned char*>(auth_tag_));
2814 EVP_CIPHER_CTX_cleanup(&ctx_);
2815 initialised_ = false;
2821 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
2822 HandleScope handle_scope(args.GetIsolate());
2823 Environment* env = Environment::GetCurrent(args.GetIsolate());
2825 CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
2827 unsigned char* out_value = NULL;
2829 Local<Value> outString;
2831 bool r = cipher->Final(&out_value, &out_len);
2833 if (out_len <= 0 || !r) {
2838 const char* msg = cipher->IsAuthenticatedMode() ?
2839 "Unsupported state or unable to authenticate data" :
2840 "Unsupported state";
2842 return ThrowCryptoError(env,
2848 args.GetReturnValue().Set(
2849 Buffer::New(env, reinterpret_cast<char*>(out_value), out_len));
2854 void Hmac::Initialize(Environment* env, v8::Handle<v8::Object> target) {
2855 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
2857 t->InstanceTemplate()->SetInternalFieldCount(1);
2859 NODE_SET_PROTOTYPE_METHOD(t, "init", HmacInit);
2860 NODE_SET_PROTOTYPE_METHOD(t, "update", HmacUpdate);
2861 NODE_SET_PROTOTYPE_METHOD(t, "digest", HmacDigest);
2863 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hmac"), t->GetFunction());
2867 void Hmac::New(const FunctionCallbackInfo<Value>& args) {
2868 HandleScope handle_scope(args.GetIsolate());
2869 Environment* env = Environment::GetCurrent(args.GetIsolate());
2870 new Hmac(env, args.This());
2874 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
2875 HandleScope scope(env()->isolate());
2877 assert(md_ == NULL);
2878 md_ = EVP_get_digestbyname(hash_type);
2880 return env()->ThrowError("Unknown message digest");
2882 HMAC_CTX_init(&ctx_);
2884 HMAC_Init(&ctx_, "", 0, md_);
2886 HMAC_Init(&ctx_, key, key_len, md_);
2888 initialised_ = true;
2892 void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
2893 HandleScope scope(args.GetIsolate());
2895 Hmac* hmac = Unwrap<Hmac>(args.Holder());
2896 Environment* env = hmac->env();
2898 if (args.Length() < 2 || !args[0]->IsString()) {
2899 return env->ThrowError("Must give hashtype string, key as arguments");
2902 ASSERT_IS_BUFFER(args[1]);
2904 const node::Utf8Value hash_type(args[0]);
2905 const char* buffer_data = Buffer::Data(args[1]);
2906 size_t buffer_length = Buffer::Length(args[1]);
2907 hmac->HmacInit(*hash_type, buffer_data, buffer_length);
2911 bool Hmac::HmacUpdate(const char* data, int len) {
2914 HMAC_Update(&ctx_, reinterpret_cast<const unsigned char*>(data), len);
2919 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
2920 Environment* env = Environment::GetCurrent(args.GetIsolate());
2921 HandleScope scope(env->isolate());
2923 Hmac* hmac = Unwrap<Hmac>(args.Holder());
2925 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2927 // Only copy the data if we have to, because it's a string
2929 if (args[0]->IsString()) {
2930 Local<String> string = args[0].As<String>();
2931 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2932 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2933 return env->ThrowTypeError("Bad input string");
2934 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2935 char* buf = new char[buflen];
2936 size_t written = StringBytes::Write(env->isolate(),
2941 r = hmac->HmacUpdate(buf, written);
2944 char* buf = Buffer::Data(args[0]);
2945 size_t buflen = Buffer::Length(args[0]);
2946 r = hmac->HmacUpdate(buf, buflen);
2950 return env->ThrowTypeError("HmacUpdate fail");
2955 bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
2958 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
2959 HMAC_Final(&ctx_, *md_value, md_len);
2960 HMAC_CTX_cleanup(&ctx_);
2961 initialised_ = false;
2966 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
2967 Environment* env = Environment::GetCurrent(args.GetIsolate());
2968 HandleScope scope(env->isolate());
2970 Hmac* hmac = Unwrap<Hmac>(args.Holder());
2972 enum encoding encoding = BUFFER;
2973 if (args.Length() >= 1) {
2974 encoding = ParseEncoding(env->isolate(), args[0]->ToString(), BUFFER);
2977 unsigned char* md_value = NULL;
2978 unsigned int md_len = 0;
2980 bool r = hmac->HmacDigest(&md_value, &md_len);
2986 Local<Value> rc = StringBytes::Encode(env->isolate(),
2987 reinterpret_cast<const char*>(md_value),
2991 args.GetReturnValue().Set(rc);
2995 void Hash::Initialize(Environment* env, v8::Handle<v8::Object> target) {
2996 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
2998 t->InstanceTemplate()->SetInternalFieldCount(1);
3000 NODE_SET_PROTOTYPE_METHOD(t, "update", HashUpdate);
3001 NODE_SET_PROTOTYPE_METHOD(t, "digest", HashDigest);
3003 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hash"), t->GetFunction());
3007 void Hash::New(const FunctionCallbackInfo<Value>& args) {
3008 Environment* env = Environment::GetCurrent(args.GetIsolate());
3009 HandleScope scope(env->isolate());
3011 if (args.Length() == 0 || !args[0]->IsString()) {
3012 return env->ThrowError("Must give hashtype string as argument");
3015 const node::Utf8Value hash_type(args[0]);
3017 Hash* hash = new Hash(env, args.This());
3018 if (!hash->HashInit(*hash_type)) {
3019 return env->ThrowError("Digest method not supported");
3024 bool Hash::HashInit(const char* hash_type) {
3025 assert(md_ == NULL);
3026 md_ = EVP_get_digestbyname(hash_type);
3029 EVP_MD_CTX_init(&mdctx_);
3030 EVP_DigestInit_ex(&mdctx_, md_, NULL);
3031 initialised_ = true;
3036 bool Hash::HashUpdate(const char* data, int len) {
3039 EVP_DigestUpdate(&mdctx_, data, len);
3044 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
3045 Environment* env = Environment::GetCurrent(args.GetIsolate());
3046 HandleScope scope(env->isolate());
3048 Hash* hash = Unwrap<Hash>(args.Holder());
3050 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3052 // Only copy the data if we have to, because it's a string
3054 if (args[0]->IsString()) {
3055 Local<String> string = args[0].As<String>();
3056 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3057 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3058 return env->ThrowTypeError("Bad input string");
3059 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3060 char* buf = new char[buflen];
3061 size_t written = StringBytes::Write(env->isolate(),
3066 r = hash->HashUpdate(buf, written);
3069 char* buf = Buffer::Data(args[0]);
3070 size_t buflen = Buffer::Length(args[0]);
3071 r = hash->HashUpdate(buf, buflen);
3075 return env->ThrowTypeError("HashUpdate fail");
3080 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
3081 Environment* env = Environment::GetCurrent(args.GetIsolate());
3082 HandleScope scope(env->isolate());
3084 Hash* hash = Unwrap<Hash>(args.Holder());
3086 if (!hash->initialised_) {
3087 return env->ThrowError("Not initialized");
3090 enum encoding encoding = BUFFER;
3091 if (args.Length() >= 1) {
3092 encoding = ParseEncoding(env->isolate(), args[0]->ToString(), BUFFER);
3095 unsigned char md_value[EVP_MAX_MD_SIZE];
3096 unsigned int md_len;
3098 EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len);
3099 EVP_MD_CTX_cleanup(&hash->mdctx_);
3100 hash->initialised_ = false;
3102 Local<Value> rc = StringBytes::Encode(env->isolate(),
3103 reinterpret_cast<const char*>(md_value),
3106 args.GetReturnValue().Set(rc);
3110 void SignBase::CheckThrow(SignBase::Error error) {
3111 HandleScope scope(env()->isolate());
3114 case kSignUnknownDigest:
3115 return env()->ThrowError("Unknown message digest");
3117 case kSignNotInitialised:
3118 return env()->ThrowError("Not initialised");
3122 case kSignPrivateKey:
3123 case kSignPublicKey:
3125 unsigned long err = ERR_get_error();
3127 return ThrowCryptoError(env(), err);
3130 return env()->ThrowError("EVP_SignInit_ex failed");
3132 return env()->ThrowError("EVP_SignUpdate failed");
3133 case kSignPrivateKey:
3134 return env()->ThrowError("PEM_read_bio_PrivateKey failed");
3135 case kSignPublicKey:
3136 return env()->ThrowError("PEM_read_bio_PUBKEY failed");
3150 void Sign::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3151 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
3153 t->InstanceTemplate()->SetInternalFieldCount(1);
3155 NODE_SET_PROTOTYPE_METHOD(t, "init", SignInit);
3156 NODE_SET_PROTOTYPE_METHOD(t, "update", SignUpdate);
3157 NODE_SET_PROTOTYPE_METHOD(t, "sign", SignFinal);
3159 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"), t->GetFunction());
3163 void Sign::New(const FunctionCallbackInfo<Value>& args) {
3164 HandleScope handle_scope(args.GetIsolate());
3165 Environment* env = Environment::GetCurrent(args.GetIsolate());
3166 new Sign(env, args.This());
3170 SignBase::Error Sign::SignInit(const char* sign_type) {
3171 assert(md_ == NULL);
3172 md_ = EVP_get_digestbyname(sign_type);
3174 return kSignUnknownDigest;
3176 EVP_MD_CTX_init(&mdctx_);
3177 if (!EVP_SignInit_ex(&mdctx_, md_, NULL))
3179 initialised_ = true;
3185 void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
3186 HandleScope scope(args.GetIsolate());
3188 Sign* sign = Unwrap<Sign>(args.Holder());
3190 if (args.Length() == 0 || !args[0]->IsString()) {
3191 return sign->env()->ThrowError("Must give signtype string as argument");
3194 const node::Utf8Value sign_type(args[0]);
3195 sign->CheckThrow(sign->SignInit(*sign_type));
3199 SignBase::Error Sign::SignUpdate(const char* data, int len) {
3201 return kSignNotInitialised;
3202 if (!EVP_SignUpdate(&mdctx_, data, len))
3208 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
3209 Environment* env = Environment::GetCurrent(args.GetIsolate());
3210 HandleScope scope(env->isolate());
3212 Sign* sign = Unwrap<Sign>(args.Holder());
3214 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3216 // Only copy the data if we have to, because it's a string
3218 if (args[0]->IsString()) {
3219 Local<String> string = args[0].As<String>();
3220 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3221 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3222 return env->ThrowTypeError("Bad input string");
3223 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3224 char* buf = new char[buflen];
3225 size_t written = StringBytes::Write(env->isolate(),
3230 err = sign->SignUpdate(buf, written);
3233 char* buf = Buffer::Data(args[0]);
3234 size_t buflen = Buffer::Length(args[0]);
3235 err = sign->SignUpdate(buf, buflen);
3238 sign->CheckThrow(err);
3242 SignBase::Error Sign::SignFinal(const char* key_pem,
3244 const char* passphrase,
3245 unsigned char** sig,
3246 unsigned int *sig_len) {
3248 return kSignNotInitialised;
3251 EVP_PKEY* pkey = NULL;
3254 bp = BIO_new(BIO_s_mem());
3258 if (!BIO_write(bp, key_pem, key_pem_len))
3261 pkey = PEM_read_bio_PrivateKey(bp,
3264 const_cast<char*>(passphrase));
3268 if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey))
3271 initialised_ = false;
3275 EVP_PKEY_free(pkey);
3279 EVP_MD_CTX_cleanup(&mdctx_);
3282 return kSignPrivateKey;
3288 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
3289 Environment* env = Environment::GetCurrent(args.GetIsolate());
3290 HandleScope scope(env->isolate());
3292 Sign* sign = Unwrap<Sign>(args.Holder());
3294 unsigned char* md_value;
3295 unsigned int md_len;
3297 unsigned int len = args.Length();
3298 enum encoding encoding = BUFFER;
3299 if (len >= 2 && args[1]->IsString()) {
3300 encoding = ParseEncoding(env->isolate(), args[1]->ToString(), BUFFER);
3303 node::Utf8Value passphrase(args[2]);
3305 ASSERT_IS_BUFFER(args[0]);
3306 size_t buf_len = Buffer::Length(args[0]);
3307 char* buf = Buffer::Data(args[0]);
3309 md_len = 8192; // Maximum key size is 8192 bits
3310 md_value = new unsigned char[md_len];
3312 Error err = sign->SignFinal(
3315 len >= 3 && !args[2]->IsNull() ? *passphrase : NULL,
3318 if (err != kSignOk) {
3322 return sign->CheckThrow(err);
3325 Local<Value> rc = StringBytes::Encode(env->isolate(),
3326 reinterpret_cast<const char*>(md_value),
3330 args.GetReturnValue().Set(rc);
3334 void Verify::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3335 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
3337 t->InstanceTemplate()->SetInternalFieldCount(1);
3339 NODE_SET_PROTOTYPE_METHOD(t, "init", VerifyInit);
3340 NODE_SET_PROTOTYPE_METHOD(t, "update", VerifyUpdate);
3341 NODE_SET_PROTOTYPE_METHOD(t, "verify", VerifyFinal);
3343 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
3348 void Verify::New(const FunctionCallbackInfo<Value>& args) {
3349 HandleScope handle_scope(args.GetIsolate());
3350 Environment* env = Environment::GetCurrent(args.GetIsolate());
3351 new Verify(env, args.This());
3355 SignBase::Error Verify::VerifyInit(const char* verify_type) {
3356 assert(md_ == NULL);
3357 md_ = EVP_get_digestbyname(verify_type);
3359 return kSignUnknownDigest;
3361 EVP_MD_CTX_init(&mdctx_);
3362 if (!EVP_VerifyInit_ex(&mdctx_, md_, NULL))
3364 initialised_ = true;
3370 void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
3371 HandleScope scope(args.GetIsolate());
3373 Verify* verify = Unwrap<Verify>(args.Holder());
3375 if (args.Length() == 0 || !args[0]->IsString()) {
3376 return verify->env()->ThrowError("Must give verifytype string as argument");
3379 const node::Utf8Value verify_type(args[0]);
3380 verify->CheckThrow(verify->VerifyInit(*verify_type));
3384 SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
3386 return kSignNotInitialised;
3388 if (!EVP_VerifyUpdate(&mdctx_, data, len))
3395 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
3396 Environment* env = Environment::GetCurrent(args.GetIsolate());
3397 HandleScope scope(env->isolate());
3399 Verify* verify = Unwrap<Verify>(args.Holder());
3401 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3403 // Only copy the data if we have to, because it's a string
3405 if (args[0]->IsString()) {
3406 Local<String> string = args[0].As<String>();
3407 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3408 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3409 return env->ThrowTypeError("Bad input string");
3410 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3411 char* buf = new char[buflen];
3412 size_t written = StringBytes::Write(env->isolate(),
3417 err = verify->VerifyUpdate(buf, written);
3420 char* buf = Buffer::Data(args[0]);
3421 size_t buflen = Buffer::Length(args[0]);
3422 err = verify->VerifyUpdate(buf, buflen);
3425 verify->CheckThrow(err);
3429 SignBase::Error Verify::VerifyFinal(const char* key_pem,
3433 bool* verify_result) {
3435 return kSignNotInitialised;
3437 ClearErrorOnReturn clear_error_on_return;
3438 (void) &clear_error_on_return; // Silence compiler warning.
3440 EVP_PKEY* pkey = NULL;
3446 bp = BIO_new(BIO_s_mem());
3450 if (!BIO_write(bp, key_pem, key_pem_len))
3453 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3454 // Split this out into a separate function once we have more than one
3455 // consumer of public keys.
3456 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3457 pkey = PEM_read_bio_PUBKEY(bp, NULL, CryptoPemCallback, NULL);
3460 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3461 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, CryptoPemCallback, NULL);
3463 pkey = EVP_PKEY_new();
3465 EVP_PKEY_set1_RSA(pkey, rsa);
3472 x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
3476 pkey = X509_get_pubkey(x509);
3482 r = EVP_VerifyFinal(&mdctx_,
3483 reinterpret_cast<const unsigned char*>(sig),
3489 EVP_PKEY_free(pkey);
3495 EVP_MD_CTX_cleanup(&mdctx_);
3496 initialised_ = false;
3499 return kSignPublicKey;
3501 *verify_result = r == 1;
3506 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
3507 Environment* env = Environment::GetCurrent(args.GetIsolate());
3508 HandleScope scope(env->isolate());
3510 Verify* verify = Unwrap<Verify>(args.Holder());
3512 ASSERT_IS_BUFFER(args[0]);
3513 char* kbuf = Buffer::Data(args[0]);
3514 ssize_t klen = Buffer::Length(args[0]);
3516 ASSERT_IS_STRING_OR_BUFFER(args[1]);
3517 // BINARY works for both buffers and binary strings.
3518 enum encoding encoding = BINARY;
3519 if (args.Length() >= 3) {
3520 encoding = ParseEncoding(env->isolate(), args[2]->ToString(), BINARY);
3523 ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);
3525 // only copy if we need to, because it's a string.
3527 if (args[1]->IsString()) {
3528 hbuf = new char[hlen];
3529 ssize_t hwritten = StringBytes::Write(env->isolate(),
3534 assert(hwritten == hlen);
3536 hbuf = Buffer::Data(args[1]);
3540 Error err = verify->VerifyFinal(kbuf, klen, hbuf, hlen, &verify_result);
3541 if (args[1]->IsString())
3544 return verify->CheckThrow(err);
3545 args.GetReturnValue().Set(verify_result);
3549 template <PublicKeyCipher::Operation operation,
3550 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3551 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3552 bool PublicKeyCipher::Cipher(const char* key_pem,
3554 const char* passphrase,
3555 const unsigned char* data,
3557 unsigned char** out,
3559 EVP_PKEY* pkey = NULL;
3560 EVP_PKEY_CTX* ctx = NULL;
3565 bp = BIO_new(BIO_s_mem());
3569 if (!BIO_write(bp, key_pem, key_pem_len))
3572 // Check if this is a PKCS#8 or RSA public key before trying as X.509 and
3574 if (operation == kEncrypt &&
3575 strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3576 pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
3579 } else if (operation == kEncrypt &&
3580 strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3581 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
3583 pkey = EVP_PKEY_new();
3585 EVP_PKEY_set1_RSA(pkey, rsa);
3590 } else if (operation == kEncrypt &&
3591 strncmp(key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0) {
3592 x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
3596 pkey = X509_get_pubkey(x509);
3600 pkey = PEM_read_bio_PrivateKey(bp,
3603 const_cast<char*>(passphrase));
3608 ctx = EVP_PKEY_CTX_new(pkey, NULL);
3611 if (EVP_PKEY_cipher_init(ctx) <= 0)
3613 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
3615 if (EVP_PKEY_cipher(ctx, NULL, out_len, data, len) <= 0)
3618 *out = new unsigned char[*out_len];
3620 if (EVP_PKEY_cipher(ctx, *out, out_len, data, len) <= 0)
3627 EVP_PKEY_free(pkey);
3631 EVP_PKEY_CTX_free(ctx);
3637 template <PublicKeyCipher::Operation operation,
3638 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
3639 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
3640 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
3641 Environment* env = Environment::GetCurrent(args.GetIsolate());
3642 HandleScope scope(env->isolate());
3644 ASSERT_IS_BUFFER(args[0]);
3645 char* kbuf = Buffer::Data(args[0]);
3646 ssize_t klen = Buffer::Length(args[0]);
3648 ASSERT_IS_BUFFER(args[1]);
3649 char* buf = Buffer::Data(args[1]);
3650 ssize_t len = Buffer::Length(args[1]);
3652 String::Utf8Value passphrase(args[2]);
3654 unsigned char* out_value = NULL;
3655 size_t out_len = -1;
3657 bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
3660 args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : NULL,
3661 reinterpret_cast<const unsigned char*>(buf),
3666 if (out_len <= 0 || !r) {
3671 return ThrowCryptoError(env,
3676 args.GetReturnValue().Set(
3677 Buffer::New(env, reinterpret_cast<char*>(out_value), out_len));
3682 void DiffieHellman::Initialize(Environment* env, Handle<Object> target) {
3683 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
3685 static enum PropertyAttribute attributes =
3686 static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
3688 t->InstanceTemplate()->SetInternalFieldCount(1);
3690 NODE_SET_PROTOTYPE_METHOD(t, "generateKeys", GenerateKeys);
3691 NODE_SET_PROTOTYPE_METHOD(t, "computeSecret", ComputeSecret);
3692 NODE_SET_PROTOTYPE_METHOD(t, "getPrime", GetPrime);
3693 NODE_SET_PROTOTYPE_METHOD(t, "getGenerator", GetGenerator);
3694 NODE_SET_PROTOTYPE_METHOD(t, "getPublicKey", GetPublicKey);
3695 NODE_SET_PROTOTYPE_METHOD(t, "getPrivateKey", GetPrivateKey);
3696 NODE_SET_PROTOTYPE_METHOD(t, "setPublicKey", SetPublicKey);
3697 NODE_SET_PROTOTYPE_METHOD(t, "setPrivateKey", SetPrivateKey);
3699 t->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3700 DiffieHellman::VerifyErrorGetter,
3706 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"),
3709 Local<FunctionTemplate> t2 = FunctionTemplate::New(env->isolate(),
3710 DiffieHellmanGroup);
3711 t2->InstanceTemplate()->SetInternalFieldCount(1);
3713 NODE_SET_PROTOTYPE_METHOD(t2, "generateKeys", GenerateKeys);
3714 NODE_SET_PROTOTYPE_METHOD(t2, "computeSecret", ComputeSecret);
3715 NODE_SET_PROTOTYPE_METHOD(t2, "getPrime", GetPrime);
3716 NODE_SET_PROTOTYPE_METHOD(t2, "getGenerator", GetGenerator);
3717 NODE_SET_PROTOTYPE_METHOD(t2, "getPublicKey", GetPublicKey);
3718 NODE_SET_PROTOTYPE_METHOD(t2, "getPrivateKey", GetPrivateKey);
3720 t2->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3721 DiffieHellman::VerifyErrorGetter,
3727 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
3732 bool DiffieHellman::Init(int primeLength, int g) {
3734 DH_generate_parameters_ex(dh, primeLength, g, 0);
3735 bool result = VerifyContext();
3738 initialised_ = true;
3743 bool DiffieHellman::Init(const char* p, int p_len, int g) {
3745 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3747 if (!BN_set_word(dh->g, g))
3749 bool result = VerifyContext();
3752 initialised_ = true;
3757 bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
3759 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3760 dh->g = BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, 0);
3761 bool result = VerifyContext();
3764 initialised_ = true;
3769 void DiffieHellman::DiffieHellmanGroup(
3770 const FunctionCallbackInfo<Value>& args) {
3771 HandleScope scope(args.GetIsolate());
3773 Environment* env = Environment::GetCurrent(args.GetIsolate());
3774 DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
3776 if (args.Length() != 1 || !args[0]->IsString()) {
3777 return env->ThrowError("No group name given");
3780 bool initialized = false;
3782 const node::Utf8Value group_name(args[0]);
3783 for (unsigned int i = 0; i < ARRAY_SIZE(modp_groups); ++i) {
3784 const modp_group* it = modp_groups + i;
3786 if (strcasecmp(*group_name, it->name) != 0)
3789 initialized = diffieHellman->Init(it->prime,
3794 env->ThrowError("Initialization failed");
3798 env->ThrowError("Unknown group");
3802 void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
3803 HandleScope scope(args.GetIsolate());
3805 Environment* env = Environment::GetCurrent(args.GetIsolate());
3806 DiffieHellman* diffieHellman =
3807 new DiffieHellman(env, args.This());
3808 bool initialized = false;
3810 if (args.Length() == 2) {
3811 if (args[0]->IsInt32()) {
3812 if (args[1]->IsInt32()) {
3813 initialized = diffieHellman->Init(args[0]->Int32Value(),
3814 args[1]->Int32Value());
3817 if (args[1]->IsInt32()) {
3818 initialized = diffieHellman->Init(Buffer::Data(args[0]),
3819 Buffer::Length(args[0]),
3820 args[1]->Int32Value());
3822 initialized = diffieHellman->Init(Buffer::Data(args[0]),
3823 Buffer::Length(args[0]),
3824 Buffer::Data(args[1]),
3825 Buffer::Length(args[1]));
3831 return env->ThrowError("Initialization failed");
3836 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
3837 Environment* env = Environment::GetCurrent(args.GetIsolate());
3838 HandleScope scope(env->isolate());
3840 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3842 if (!diffieHellman->initialised_) {
3843 return env->ThrowError("Not initialized");
3846 if (!DH_generate_key(diffieHellman->dh)) {
3847 return env->ThrowError("Key generation failed");
3850 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3851 char* data = new char[dataSize];
3852 BN_bn2bin(diffieHellman->dh->pub_key,
3853 reinterpret_cast<unsigned char*>(data));
3855 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3860 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
3861 Environment* env = Environment::GetCurrent(args.GetIsolate());
3862 HandleScope scope(env->isolate());
3864 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3866 if (!diffieHellman->initialised_) {
3867 return env->ThrowError("Not initialized");
3870 int dataSize = BN_num_bytes(diffieHellman->dh->p);
3871 char* data = new char[dataSize];
3872 BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
3874 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3879 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
3880 Environment* env = Environment::GetCurrent(args.GetIsolate());
3881 HandleScope scope(env->isolate());
3883 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3885 if (!diffieHellman->initialised_) {
3886 return env->ThrowError("Not initialized");
3889 int dataSize = BN_num_bytes(diffieHellman->dh->g);
3890 char* data = new char[dataSize];
3891 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
3893 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3898 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
3899 Environment* env = Environment::GetCurrent(args.GetIsolate());
3900 HandleScope scope(env->isolate());
3902 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3904 if (!diffieHellman->initialised_) {
3905 return env->ThrowError("Not initialized");
3908 if (diffieHellman->dh->pub_key == NULL) {
3909 return env->ThrowError("No public key - did you forget to generate one?");
3912 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3913 char* data = new char[dataSize];
3914 BN_bn2bin(diffieHellman->dh->pub_key,
3915 reinterpret_cast<unsigned char*>(data));
3917 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3922 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
3923 Environment* env = Environment::GetCurrent(args.GetIsolate());
3924 HandleScope scope(env->isolate());
3926 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3928 if (!diffieHellman->initialised_) {
3929 return env->ThrowError("Not initialized");
3932 if (diffieHellman->dh->priv_key == NULL) {
3933 return env->ThrowError("No private key - did you forget to generate one?");
3936 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
3937 char* data = new char[dataSize];
3938 BN_bn2bin(diffieHellman->dh->priv_key,
3939 reinterpret_cast<unsigned char*>(data));
3941 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3946 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
3947 Environment* env = Environment::GetCurrent(args.GetIsolate());
3948 HandleScope scope(env->isolate());
3950 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
3952 if (!diffieHellman->initialised_) {
3953 return env->ThrowError("Not initialized");
3956 ClearErrorOnReturn clear_error_on_return;
3957 (void) &clear_error_on_return; // Silence compiler warning.
3960 if (args.Length() == 0) {
3961 return env->ThrowError("First argument must be other party's public key");
3963 ASSERT_IS_BUFFER(args[0]);
3965 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3966 Buffer::Length(args[0]),
3970 int dataSize = DH_size(diffieHellman->dh);
3971 char* data = new char[dataSize];
3973 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
3981 checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
3986 return env->ThrowError("Invalid key");
3987 } else if (checkResult) {
3988 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
3989 return env->ThrowError("Supplied key is too small");
3990 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
3991 return env->ThrowError("Supplied key is too large");
3993 return env->ThrowError("Invalid key");
3996 return env->ThrowError("Invalid key");
4003 // DH_size returns number of bytes in a prime number
4004 // DH_compute_key returns number of bytes in a remainder of exponent, which
4005 // may have less bytes than a prime number. Therefore add 0-padding to the
4006 // allocated buffer.
4007 if (size != dataSize) {
4008 assert(dataSize > size);
4009 memmove(data + dataSize - size, data, size);
4010 memset(data, 0, dataSize - size);
4013 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
4018 void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
4019 HandleScope scope(args.GetIsolate());
4021 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4022 Environment* env = diffieHellman->env();
4024 if (!diffieHellman->initialised_) {
4025 return env->ThrowError("Not initialized");
4028 if (args.Length() == 0) {
4029 return env->ThrowError("First argument must be public key");
4031 ASSERT_IS_BUFFER(args[0]);
4032 diffieHellman->dh->pub_key = BN_bin2bn(
4033 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4034 Buffer::Length(args[0]), 0);
4039 void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
4040 HandleScope scope(args.GetIsolate());
4042 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4043 Environment* env = diffieHellman->env();
4045 if (!diffieHellman->initialised_) {
4046 return env->ThrowError("Not initialized");
4049 if (args.Length() == 0) {
4050 return env->ThrowError("First argument must be private key");
4052 ASSERT_IS_BUFFER(args[0]);
4053 diffieHellman->dh->priv_key = BN_bin2bn(
4054 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
4055 Buffer::Length(args[0]),
4061 void DiffieHellman::VerifyErrorGetter(Local<String> property,
4062 const PropertyCallbackInfo<Value>& args) {
4063 HandleScope scope(args.GetIsolate());
4065 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
4067 if (!diffieHellman->initialised_)
4068 return diffieHellman->env()->ThrowError("Not initialized");
4070 args.GetReturnValue().Set(diffieHellman->verifyError_);
4074 bool DiffieHellman::VerifyContext() {
4076 if (!DH_check(dh, &codes))
4078 verifyError_ = codes;
4083 class PBKDF2Request : public AsyncWrap {
4085 PBKDF2Request(Environment* env,
4086 Local<Object> object,
4087 const EVP_MD* digest,
4094 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4102 key_(static_cast<char*>(malloc(keylen))),
4105 FatalError("node::PBKDF2Request()", "Out of Memory");
4109 persistent().Reset();
4112 uv_work_t* work_req() {
4116 inline const EVP_MD* digest() const {
4120 inline ssize_t passlen() const {
4124 inline char* pass() const {
4128 inline ssize_t saltlen() const {
4132 inline char* salt() const {
4136 inline ssize_t keylen() const {
4140 inline char* key() const {
4144 inline ssize_t iter() const {
4148 inline void release() {
4157 inline int error() const {
4161 inline void set_error(int err) {
4165 uv_work_t work_req_;
4168 const EVP_MD* digest_;
4180 void EIO_PBKDF2(PBKDF2Request* req) {
4181 req->set_error(PKCS5_PBKDF2_HMAC(
4184 reinterpret_cast<unsigned char*>(req->salt()),
4189 reinterpret_cast<unsigned char*>(req->key())));
4190 memset(req->pass(), 0, req->passlen());
4191 memset(req->salt(), 0, req->saltlen());
4195 void EIO_PBKDF2(uv_work_t* work_req) {
4196 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4201 void EIO_PBKDF2After(PBKDF2Request* req, Local<Value> argv[2]) {
4203 argv[0] = Undefined(req->env()->isolate());
4204 argv[1] = Encode(req->env()->isolate(), req->key(), req->keylen(), BUFFER);
4205 memset(req->key(), 0, req->keylen());
4207 argv[0] = Exception::Error(req->env()->pbkdf2_error_string());
4208 argv[1] = Undefined(req->env()->isolate());
4213 void EIO_PBKDF2After(uv_work_t* work_req, int status) {
4214 assert(status == 0);
4215 PBKDF2Request* req = ContainerOf(&PBKDF2Request::work_req_, work_req);
4216 Environment* env = req->env();
4217 HandleScope handle_scope(env->isolate());
4218 Context::Scope context_scope(env->context());
4219 Local<Value> argv[2];
4220 EIO_PBKDF2After(req, argv);
4221 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4227 void PBKDF2(const FunctionCallbackInfo<Value>& args) {
4228 Environment* env = Environment::GetCurrent(args.GetIsolate());
4229 HandleScope scope(env->isolate());
4231 const EVP_MD* digest = NULL;
4232 const char* type_error = NULL;
4235 ssize_t passlen = -1;
4236 ssize_t saltlen = -1;
4237 ssize_t keylen = -1;
4239 PBKDF2Request* req = NULL;
4242 if (args.Length() != 5 && args.Length() != 6) {
4243 type_error = "Bad parameter";
4247 ASSERT_IS_BUFFER(args[0]);
4248 passlen = Buffer::Length(args[0]);
4250 type_error = "Bad password";
4254 pass = static_cast<char*>(malloc(passlen));
4256 FatalError("node::PBKDF2()", "Out of Memory");
4258 memcpy(pass, Buffer::Data(args[0]), passlen);
4260 ASSERT_IS_BUFFER(args[1]);
4261 saltlen = Buffer::Length(args[1]);
4263 type_error = "Bad salt";
4267 salt = static_cast<char*>(malloc(saltlen));
4269 FatalError("node::PBKDF2()", "Out of Memory");
4271 memcpy(salt, Buffer::Data(args[1]), saltlen);
4273 if (!args[2]->IsNumber()) {
4274 type_error = "Iterations not a number";
4278 iter = args[2]->Int32Value();
4280 type_error = "Bad iterations";
4284 if (!args[3]->IsNumber()) {
4285 type_error = "Key length not a number";
4289 keylen = args[3]->Int32Value();
4291 type_error = "Bad key length";
4295 if (args[4]->IsString()) {
4296 node::Utf8Value digest_name(args[4]);
4297 digest = EVP_get_digestbyname(*digest_name);
4298 if (digest == NULL) {
4299 type_error = "Bad digest name";
4304 if (digest == NULL) {
4305 digest = EVP_sha1();
4308 obj = Object::New(env->isolate());
4309 req = new PBKDF2Request(env,
4319 if (args[5]->IsFunction()) {
4320 obj->Set(env->ondone_string(), args[5]);
4321 // XXX(trevnorris): This will need to go with the rest of domains.
4322 if (env->in_domain())
4323 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4324 uv_queue_work(env->event_loop(),
4329 Local<Value> argv[2];
4331 EIO_PBKDF2After(req, argv);
4332 if (argv[0]->IsObject())
4333 env->isolate()->ThrowException(argv[0]);
4335 args.GetReturnValue().Set(argv[1]);
4342 return env->ThrowTypeError(type_error);
4346 // Only instantiate within a valid HandleScope.
4347 class RandomBytesRequest : public AsyncWrap {
4349 RandomBytesRequest(Environment* env, Local<Object> object, size_t size)
4350 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
4353 data_(static_cast<char*>(malloc(size))) {
4355 FatalError("node::RandomBytesRequest()", "Out of Memory");
4358 ~RandomBytesRequest() {
4359 persistent().Reset();
4362 uv_work_t* work_req() {
4366 inline size_t size() const {
4370 inline char* data() const {
4374 inline void release() {
4379 inline void return_memory(char** d, size_t* len) {
4386 inline unsigned long error() const {
4390 inline void set_error(unsigned long err) {
4394 uv_work_t work_req_;
4397 unsigned long error_;
4403 template <bool pseudoRandom>
4404 void RandomBytesWork(uv_work_t* work_req) {
4405 RandomBytesRequest* req =
4406 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4409 // Ensure that OpenSSL's PRNG is properly seeded.
4412 if (pseudoRandom == true) {
4413 r = RAND_pseudo_bytes(reinterpret_cast<unsigned char*>(req->data()),
4416 r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data()), req->size());
4419 // RAND_bytes() returns 0 on error. RAND_pseudo_bytes() returns 0 when the
4420 // result is not cryptographically strong - but that's not an error.
4421 if (r == 0 && pseudoRandom == false) {
4422 req->set_error(ERR_get_error());
4423 } else if (r == -1) {
4424 req->set_error(static_cast<unsigned long>(-1));
4429 // don't call this function without a valid HandleScope
4430 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
4432 char errmsg[256] = "Operation not supported";
4434 if (req->error() != static_cast<unsigned long>(-1))
4435 ERR_error_string_n(req->error(), errmsg, sizeof errmsg);
4437 argv[0] = Exception::Error(OneByteString(req->env()->isolate(), errmsg));
4438 argv[1] = Null(req->env()->isolate());
4443 req->return_memory(&data, &size);
4444 argv[0] = Null(req->env()->isolate());
4445 argv[1] = Buffer::Use(data, size);
4450 void RandomBytesAfter(uv_work_t* work_req, int status) {
4451 assert(status == 0);
4452 RandomBytesRequest* req =
4453 ContainerOf(&RandomBytesRequest::work_req_, work_req);
4454 Environment* env = req->env();
4455 HandleScope handle_scope(env->isolate());
4456 Context::Scope context_scope(env->context());
4457 Local<Value> argv[2];
4458 RandomBytesCheck(req, argv);
4459 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4464 template <bool pseudoRandom>
4465 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
4466 HandleScope handle_scope(args.GetIsolate());
4467 Environment* env = Environment::GetCurrent(args.GetIsolate());
4469 // maybe allow a buffer to write to? cuts down on object creation
4470 // when generating random data in a loop
4471 if (!args[0]->IsUint32()) {
4472 return env->ThrowTypeError("Argument #1 must be number > 0");
4475 const uint32_t size = args[0]->Uint32Value();
4476 if (size > Buffer::kMaxLength) {
4477 return env->ThrowTypeError("size > Buffer::kMaxLength");
4480 Local<Object> obj = Object::New(env->isolate());
4481 RandomBytesRequest* req = new RandomBytesRequest(env, obj, size);
4483 if (args[1]->IsFunction()) {
4484 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "ondone"), args[1]);
4485 // XXX(trevnorris): This will need to go with the rest of domains.
4486 if (env->in_domain())
4487 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4488 uv_queue_work(env->event_loop(),
4490 RandomBytesWork<pseudoRandom>,
4492 args.GetReturnValue().Set(obj);
4494 Local<Value> argv[2];
4495 RandomBytesWork<pseudoRandom>(req->work_req());
4496 RandomBytesCheck(req, argv);
4499 if (!argv[0]->IsNull())
4500 env->isolate()->ThrowException(argv[0]);
4502 args.GetReturnValue().Set(argv[1]);
4507 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
4508 Environment* env = Environment::GetCurrent(args.GetIsolate());
4509 HandleScope scope(env->isolate());
4511 SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
4513 return env->ThrowError("SSL_CTX_new() failed.");
4516 SSL* ssl = SSL_new(ctx);
4519 return env->ThrowError("SSL_new() failed.");
4522 Local<Array> arr = Array::New(env->isolate());
4523 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
4525 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
4526 SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
4527 arr->Set(i, OneByteString(args.GetIsolate(), SSL_CIPHER_get_name(cipher)));
4533 args.GetReturnValue().Set(arr);
4537 class CipherPushContext {
4539 explicit CipherPushContext(Environment* env)
4540 : arr(Array::New(env->isolate())),
4544 inline Environment* env() const { return env_; }
4553 template <class TypeName>
4554 static void array_push_back(const TypeName* md,
4558 CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
4559 ctx->arr->Set(ctx->arr->Length(), OneByteString(ctx->env()->isolate(), from));
4563 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
4564 Environment* env = Environment::GetCurrent(args.GetIsolate());
4565 HandleScope scope(env->isolate());
4566 CipherPushContext ctx(env);
4567 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
4568 args.GetReturnValue().Set(ctx.arr);
4572 void GetHashes(const FunctionCallbackInfo<Value>& args) {
4573 Environment* env = Environment::GetCurrent(args.GetIsolate());
4574 HandleScope scope(env->isolate());
4575 CipherPushContext ctx(env);
4576 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
4577 args.GetReturnValue().Set(ctx.arr);
4581 void Certificate::Initialize(Environment* env, Handle<Object> target) {
4582 HandleScope scope(env->isolate());
4584 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
4586 t->InstanceTemplate()->SetInternalFieldCount(1);
4588 NODE_SET_PROTOTYPE_METHOD(t, "verifySpkac", VerifySpkac);
4589 NODE_SET_PROTOTYPE_METHOD(t, "exportPublicKey", ExportPublicKey);
4590 NODE_SET_PROTOTYPE_METHOD(t, "exportChallenge", ExportChallenge);
4592 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Certificate"),
4597 void Certificate::New(const FunctionCallbackInfo<Value>& args) {
4598 HandleScope handle_scope(args.GetIsolate());
4599 Environment* env = Environment::GetCurrent(args.GetIsolate());
4600 new Certificate(env, args.This());
4604 bool Certificate::VerifySpkac(const char* data, unsigned int len) {
4606 EVP_PKEY* pkey = NULL;
4607 NETSCAPE_SPKI* spki = NULL;
4609 spki = NETSCAPE_SPKI_b64_decode(data, len);
4613 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
4617 i = NETSCAPE_SPKI_verify(spki, pkey) > 0;
4621 EVP_PKEY_free(pkey);
4624 NETSCAPE_SPKI_free(spki);
4630 void Certificate::VerifySpkac(const FunctionCallbackInfo<Value>& args) {
4631 HandleScope scope(args.GetIsolate());
4633 Certificate* certificate = Unwrap<Certificate>(args.Holder());
4634 Environment* env = certificate->env();
4637 if (args.Length() < 1)
4638 return env->ThrowTypeError("Missing argument");
4640 ASSERT_IS_BUFFER(args[0]);
4642 size_t length = Buffer::Length(args[0]);
4644 return args.GetReturnValue().Set(i);
4646 char* data = Buffer::Data(args[0]);
4647 assert(data != NULL);
4649 i = certificate->VerifySpkac(data, length);
4651 args.GetReturnValue().Set(i);
4655 const char* Certificate::ExportPublicKey(const char* data, int len) {
4657 EVP_PKEY* pkey = NULL;
4658 NETSCAPE_SPKI* spki = NULL;
4660 BIO* bio = BIO_new(BIO_s_mem());
4664 spki = NETSCAPE_SPKI_b64_decode(data, len);
4668 pkey = NETSCAPE_SPKI_get_pubkey(spki);
4672 if (PEM_write_bio_PUBKEY(bio, pkey) <= 0)
4675 BIO_write(bio, "\0", 1);
4677 BIO_get_mem_ptr(bio, &ptr);
4679 buf = new char[ptr->length];
4680 memcpy(buf, ptr->data, ptr->length);
4684 EVP_PKEY_free(pkey);
4687 NETSCAPE_SPKI_free(spki);
4696 void Certificate::ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
4697 Environment* env = Environment::GetCurrent(args.GetIsolate());
4698 HandleScope scope(env->isolate());
4700 Certificate* certificate = Unwrap<Certificate>(args.Holder());
4702 if (args.Length() < 1)
4703 return env->ThrowTypeError("Missing argument");
4705 ASSERT_IS_BUFFER(args[0]);
4707 size_t length = Buffer::Length(args[0]);
4709 return args.GetReturnValue().SetEmptyString();
4711 char* data = Buffer::Data(args[0]);
4712 assert(data != NULL);
4714 const char* pkey = certificate->ExportPublicKey(data, length);
4716 return args.GetReturnValue().SetEmptyString();
4718 Local<Value> out = Encode(env->isolate(), pkey, strlen(pkey), BUFFER);
4722 args.GetReturnValue().Set(out);
4726 const char* Certificate::ExportChallenge(const char* data, int len) {
4727 NETSCAPE_SPKI* sp = NULL;
4729 sp = NETSCAPE_SPKI_b64_decode(data, len);
4733 const char* buf = NULL;
4734 buf = reinterpret_cast<const char*>(ASN1_STRING_data(sp->spkac->challenge));
4740 void Certificate::ExportChallenge(const FunctionCallbackInfo<Value>& args) {
4741 Environment* env = Environment::GetCurrent(args.GetIsolate());
4742 HandleScope scope(env->isolate());
4744 Certificate* crt = Unwrap<Certificate>(args.Holder());
4746 if (args.Length() < 1)
4747 return env->ThrowTypeError("Missing argument");
4749 ASSERT_IS_BUFFER(args[0]);
4751 size_t len = Buffer::Length(args[0]);
4753 return args.GetReturnValue().SetEmptyString();
4755 char* data = Buffer::Data(args[0]);
4756 assert(data != NULL);
4758 const char* cert = crt->ExportChallenge(data, len);
4760 return args.GetReturnValue().SetEmptyString();
4762 Local<Value> outString = Encode(env->isolate(), cert, strlen(cert), BUFFER);
4766 args.GetReturnValue().Set(outString);
4770 void InitCryptoOnce() {
4772 OpenSSL_add_all_algorithms();
4773 SSL_load_error_strings();
4776 CRYPTO_set_locking_callback(crypto_lock_cb);
4777 CRYPTO_THREADID_set_callback(crypto_threadid_cb);
4779 // Turn off compression. Saves memory and protects against CRIME attacks.
4780 #if !defined(OPENSSL_NO_COMP)
4781 #if OPENSSL_VERSION_NUMBER < 0x00908000L
4782 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_method();
4784 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
4786 sk_SSL_COMP_zero(comp_methods);
4787 assert(sk_SSL_COMP_num(comp_methods) == 0);
4790 #ifndef OPENSSL_NO_ENGINE
4791 ERR_load_ENGINE_strings();
4792 ENGINE_load_builtin_engines();
4793 #endif // !OPENSSL_NO_ENGINE
4797 #ifndef OPENSSL_NO_ENGINE
4798 void SetEngine(const FunctionCallbackInfo<Value>& args) {
4799 Environment* env = Environment::GetCurrent(args.GetIsolate());
4800 CHECK(args.Length() >= 2 && args[0]->IsString());
4801 unsigned int flags = args[1]->Uint32Value();
4803 ClearErrorOnReturn clear_error_on_return;
4804 (void) &clear_error_on_return; // Silence compiler warning.
4806 const node::Utf8Value engine_id(args[0]);
4807 ENGINE* engine = ENGINE_by_id(*engine_id);
4809 // Engine not found, try loading dynamically
4810 if (engine == NULL) {
4811 engine = ENGINE_by_id("dynamic");
4812 if (engine != NULL) {
4813 if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", *engine_id, 0) ||
4814 !ENGINE_ctrl_cmd_string(engine, "LOAD", NULL, 0)) {
4815 ENGINE_free(engine);
4821 if (engine == NULL) {
4822 int err = ERR_get_error();
4825 snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id);
4826 return env->ThrowError(tmp);
4828 return ThrowCryptoError(env, err);
4832 int r = ENGINE_set_default(engine, flags);
4833 ENGINE_free(engine);
4835 return ThrowCryptoError(env, ERR_get_error());
4837 #endif // !OPENSSL_NO_ENGINE
4840 // FIXME(bnoordhuis) Handle global init correctly.
4841 void InitCrypto(Handle<Object> target,
4842 Handle<Value> unused,
4843 Handle<Context> context,
4845 static uv_once_t init_once = UV_ONCE_INIT;
4846 uv_once(&init_once, InitCryptoOnce);
4848 Environment* env = Environment::GetCurrent(context);
4849 SecureContext::Initialize(env, target);
4850 Connection::Initialize(env, target);
4851 CipherBase::Initialize(env, target);
4852 DiffieHellman::Initialize(env, target);
4853 Hmac::Initialize(env, target);
4854 Hash::Initialize(env, target);
4855 Sign::Initialize(env, target);
4856 Verify::Initialize(env, target);
4857 Certificate::Initialize(env, target);
4859 #ifndef OPENSSL_NO_ENGINE
4860 NODE_SET_METHOD(target, "setEngine", SetEngine);
4861 #endif // !OPENSSL_NO_ENGINE
4862 NODE_SET_METHOD(target, "PBKDF2", PBKDF2);
4863 NODE_SET_METHOD(target, "randomBytes", RandomBytes<false>);
4864 NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<true>);
4865 NODE_SET_METHOD(target, "getSSLCiphers", GetSSLCiphers);
4866 NODE_SET_METHOD(target, "getCiphers", GetCiphers);
4867 NODE_SET_METHOD(target, "getHashes", GetHashes);
4868 NODE_SET_METHOD(target,
4870 PublicKeyCipher::Cipher<PublicKeyCipher::kEncrypt,
4871 EVP_PKEY_encrypt_init,
4873 NODE_SET_METHOD(target,
4875 PublicKeyCipher::Cipher<PublicKeyCipher::kDecrypt,
4876 EVP_PKEY_decrypt_init,
4880 } // namespace crypto
4883 NODE_MODULE_CONTEXT_AWARE_BUILTIN(crypto, node::crypto::InitCrypto)