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 int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
69 | ASN1_STRFLGS_ESC_MSB
70 | XN_FLAG_SEP_MULTILINE
81 using v8::FunctionCallbackInfo;
82 using v8::FunctionTemplate;
84 using v8::HandleScope;
91 using v8::PropertyAttribute;
92 using v8::PropertyCallbackInfo;
98 // Forcibly clear OpenSSL's error stack on return. This stops stale errors
99 // from popping up later in the lifecycle of crypto operations where they
100 // would cause spurious failures. It's a rather blunt method, though.
101 // ERR_clear_error() isn't necessarily cheap either.
102 struct ClearErrorOnReturn {
103 ~ClearErrorOnReturn() { ERR_clear_error(); }
106 static uv_rwlock_t* locks;
108 const char* root_certs[] = {
109 #include "node_root_certs.h" // NOLINT(build/include_order)
113 X509_STORE* root_cert_store;
115 // Just to generate static methods
116 template class SSLWrap<TLSCallbacks>;
117 template void SSLWrap<TLSCallbacks>::AddMethods(Environment* env,
118 Handle<FunctionTemplate> t);
119 template void SSLWrap<TLSCallbacks>::InitNPN(SecureContext* sc,
121 template SSL_SESSION* SSLWrap<TLSCallbacks>::GetSessionCallback(
126 template int SSLWrap<TLSCallbacks>::NewSessionCallback(SSL* s,
128 template void SSLWrap<TLSCallbacks>::OnClientHello(
130 const ClientHelloParser::ClientHello& hello);
132 #ifdef OPENSSL_NPN_NEGOTIATED
133 template int SSLWrap<TLSCallbacks>::AdvertiseNextProtoCallback(
135 const unsigned char** data,
138 template int SSLWrap<TLSCallbacks>::SelectNextProtoCallback(
141 unsigned char* outlen,
142 const unsigned char* in,
148 static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
149 CRYPTO_THREADID_set_numeric(tid, uv_thread_self());
153 static void crypto_lock_init(void) {
156 n = CRYPTO_num_locks();
157 locks = new uv_rwlock_t[n];
159 for (i = 0; i < n; i++)
160 if (uv_rwlock_init(locks + i))
165 static void crypto_lock_cb(int mode, int n, const char* file, int line) {
166 assert((mode & CRYPTO_LOCK) || (mode & CRYPTO_UNLOCK));
167 assert((mode & CRYPTO_READ) || (mode & CRYPTO_WRITE));
169 if (mode & CRYPTO_LOCK) {
170 if (mode & CRYPTO_READ)
171 uv_rwlock_rdlock(locks + n);
173 uv_rwlock_wrlock(locks + n);
175 if (mode & CRYPTO_READ)
176 uv_rwlock_rdunlock(locks + n);
178 uv_rwlock_wrunlock(locks + n);
183 static int CryptoPemCallback(char *buf, int size, int rwflag, void *u) {
185 size_t buflen = static_cast<size_t>(size);
186 size_t len = strlen(static_cast<const char*>(u));
187 len = len > buflen ? buflen : len;
196 void ThrowCryptoErrorHelper(Environment* env,
198 bool is_type_error) {
199 HandleScope scope(env->isolate());
201 ERR_error_string_n(err, errmsg, sizeof(errmsg));
203 env->ThrowTypeError(errmsg);
205 env->ThrowError(errmsg);
209 void ThrowCryptoError(Environment* env, unsigned long err) {
210 ThrowCryptoErrorHelper(env, err, false);
214 void ThrowCryptoTypeError(Environment* env, unsigned long err) {
215 ThrowCryptoErrorHelper(env, err, true);
219 bool EntropySource(unsigned char* buffer, size_t length) {
220 // RAND_bytes() can return 0 to indicate that the entropy data is not truly
221 // random. That's okay, it's still better than V8's stock source of entropy,
222 // which is /dev/urandom on UNIX platforms and the current time on Windows.
223 return RAND_bytes(buffer, length) != -1;
227 void SecureContext::Initialize(Environment* env, Handle<Object> target) {
228 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(),
230 t->InstanceTemplate()->SetInternalFieldCount(1);
231 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"));
233 NODE_SET_PROTOTYPE_METHOD(t, "init", SecureContext::Init);
234 NODE_SET_PROTOTYPE_METHOD(t, "setKey", SecureContext::SetKey);
235 NODE_SET_PROTOTYPE_METHOD(t, "setCert", SecureContext::SetCert);
236 NODE_SET_PROTOTYPE_METHOD(t, "addCACert", SecureContext::AddCACert);
237 NODE_SET_PROTOTYPE_METHOD(t, "addCRL", SecureContext::AddCRL);
238 NODE_SET_PROTOTYPE_METHOD(t, "addRootCerts", SecureContext::AddRootCerts);
239 NODE_SET_PROTOTYPE_METHOD(t, "setCiphers", SecureContext::SetCiphers);
240 NODE_SET_PROTOTYPE_METHOD(t, "setECDHCurve", SecureContext::SetECDHCurve);
241 NODE_SET_PROTOTYPE_METHOD(t, "setOptions", SecureContext::SetOptions);
242 NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
243 SecureContext::SetSessionIdContext);
244 NODE_SET_PROTOTYPE_METHOD(t, "setSessionTimeout",
245 SecureContext::SetSessionTimeout);
246 NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
247 NODE_SET_PROTOTYPE_METHOD(t, "loadPKCS12", SecureContext::LoadPKCS12);
248 NODE_SET_PROTOTYPE_METHOD(t, "getTicketKeys", SecureContext::GetTicketKeys);
249 NODE_SET_PROTOTYPE_METHOD(t, "setTicketKeys", SecureContext::SetTicketKeys);
251 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"),
253 env->set_secure_context_constructor_template(t);
257 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
258 HandleScope handle_scope(args.GetIsolate());
259 Environment* env = Environment::GetCurrent(args.GetIsolate());
260 new SecureContext(env, args.This());
264 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
265 HandleScope scope(args.GetIsolate());
267 SecureContext* sc = Unwrap<SecureContext>(args.This());
268 Environment* env = sc->env();
270 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
272 if (args.Length() == 1 && args[0]->IsString()) {
273 const String::Utf8Value sslmethod(args[0]);
275 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
276 #ifndef OPENSSL_NO_SSL2
277 method = SSLv2_method();
279 return env->ThrowError("SSLv2 methods disabled");
281 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
282 #ifndef OPENSSL_NO_SSL2
283 method = SSLv2_server_method();
285 return env->ThrowError("SSLv2 methods disabled");
287 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
288 #ifndef OPENSSL_NO_SSL2
289 method = SSLv2_client_method();
291 return env->ThrowError("SSLv2 methods disabled");
293 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
294 method = SSLv3_method();
295 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
296 method = SSLv3_server_method();
297 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
298 method = SSLv3_client_method();
299 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
300 method = SSLv23_method();
301 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
302 method = SSLv23_server_method();
303 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
304 method = SSLv23_client_method();
305 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
306 method = TLSv1_method();
307 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
308 method = TLSv1_server_method();
309 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
310 method = TLSv1_client_method();
311 } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
312 method = TLSv1_1_method();
313 } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
314 method = TLSv1_1_server_method();
315 } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
316 method = TLSv1_1_client_method();
317 } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
318 method = TLSv1_2_method();
319 } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
320 method = TLSv1_2_server_method();
321 } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
322 method = TLSv1_2_client_method();
324 return env->ThrowError("Unknown method");
328 sc->ctx_ = SSL_CTX_new(method);
330 // SSL session cache configuration
331 SSL_CTX_set_session_cache_mode(sc->ctx_,
332 SSL_SESS_CACHE_SERVER |
333 SSL_SESS_CACHE_NO_INTERNAL |
334 SSL_SESS_CACHE_NO_AUTO_CLEAR);
335 SSL_CTX_sess_set_get_cb(sc->ctx_, SSLWrap<Connection>::GetSessionCallback);
336 SSL_CTX_sess_set_new_cb(sc->ctx_, SSLWrap<Connection>::NewSessionCallback);
338 sc->ca_store_ = NULL;
342 // Takes a string or buffer and loads it into a BIO.
343 // Caller responsible for BIO_free_all-ing the returned object.
344 static BIO* LoadBIO(Environment* env, Handle<Value> v) {
345 BIO* bio = NodeBIO::New();
349 HandleScope scope(env->isolate());
354 const String::Utf8Value s(v);
355 r = BIO_write(bio, *s, s.length());
356 } else if (Buffer::HasInstance(v)) {
357 char* buffer_data = Buffer::Data(v);
358 size_t buffer_length = Buffer::Length(v);
359 r = BIO_write(bio, buffer_data, buffer_length);
371 // Takes a string or buffer and loads it into an X509
372 // Caller responsible for X509_free-ing the returned object.
373 static X509* LoadX509(Environment* env, Handle<Value> v) {
374 HandleScope scope(env->isolate());
376 BIO *bio = LoadBIO(env, v);
380 X509 * x509 = PEM_read_bio_X509(bio, NULL, CryptoPemCallback, NULL);
391 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
392 Environment* env = Environment::GetCurrent(args.GetIsolate());
393 HandleScope scope(env->isolate());
395 SecureContext* sc = Unwrap<SecureContext>(args.This());
397 unsigned int len = args.Length();
398 if (len != 1 && len != 2) {
399 return env->ThrowTypeError("Bad parameter");
401 if (len == 2 && !args[1]->IsString()) {
402 return env->ThrowTypeError("Bad parameter");
405 BIO *bio = LoadBIO(env, args[0]);
409 String::Utf8Value passphrase(args[1]);
411 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio,
414 len == 1 ? NULL : *passphrase);
418 unsigned long err = ERR_get_error();
420 return env->ThrowError("PEM_read_bio_PrivateKey");
422 return ThrowCryptoError(env, err);
425 SSL_CTX_use_PrivateKey(sc->ctx_, key);
431 // Read a file that contains our certificate in "PEM" format,
432 // possibly followed by a sequence of CA certificates that should be
433 // sent to the peer in the Certificate message.
435 // Taken from OpenSSL - editted for style.
436 int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, BIO *in) {
440 x = PEM_read_bio_X509_AUX(in, NULL, CryptoPemCallback, NULL);
443 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
447 ret = SSL_CTX_use_certificate(ctx, x);
449 if (ERR_peek_error() != 0) {
450 // Key/certificate mismatch doesn't imply ret==0 ...
455 // If we could set up our certificate, now proceed to
456 // the CA certificates.
461 if (ctx->extra_certs != NULL) {
462 sk_X509_pop_free(ctx->extra_certs, X509_free);
463 ctx->extra_certs = NULL;
466 while ((ca = PEM_read_bio_X509(in, NULL, CryptoPemCallback, NULL))) {
467 r = SSL_CTX_add_extra_chain_cert(ctx, ca);
474 // Note that we must not free r if it was successfully
475 // added to the chain (while we must free the main
476 // certificate, since its reference count is increased
477 // by SSL_CTX_use_certificate).
480 // When the while loop ends, it's usually just EOF.
481 err = ERR_peek_last_error();
482 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
483 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
498 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
499 Environment* env = Environment::GetCurrent(args.GetIsolate());
500 HandleScope scope(env->isolate());
502 SecureContext* sc = Unwrap<SecureContext>(args.This());
504 if (args.Length() != 1) {
505 return env->ThrowTypeError("Bad parameter");
508 BIO* bio = LoadBIO(env, args[0]);
512 int rv = SSL_CTX_use_certificate_chain(sc->ctx_, bio);
517 unsigned long err = ERR_get_error();
519 return env->ThrowError("SSL_CTX_use_certificate_chain");
521 return ThrowCryptoError(env, err);
526 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
527 bool newCAStore = false;
528 Environment* env = Environment::GetCurrent(args.GetIsolate());
529 HandleScope scope(env->isolate());
531 SecureContext* sc = Unwrap<SecureContext>(args.This());
533 if (args.Length() != 1) {
534 return env->ThrowTypeError("Bad parameter");
537 if (!sc->ca_store_) {
538 sc->ca_store_ = X509_STORE_new();
542 X509* x509 = LoadX509(env, args[0]);
546 X509_STORE_add_cert(sc->ca_store_, x509);
547 SSL_CTX_add_client_CA(sc->ctx_, x509);
552 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
557 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
558 Environment* env = Environment::GetCurrent(args.GetIsolate());
559 HandleScope scope(env->isolate());
561 SecureContext* sc = Unwrap<SecureContext>(args.This());
563 if (args.Length() != 1) {
564 return env->ThrowTypeError("Bad parameter");
567 ClearErrorOnReturn clear_error_on_return;
568 (void) &clear_error_on_return; // Silence compiler warning.
570 BIO *bio = LoadBIO(env, args[0]);
574 X509_CRL *x509 = PEM_read_bio_X509_CRL(bio, NULL, CryptoPemCallback, NULL);
581 X509_STORE_add_crl(sc->ca_store_, x509);
582 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
583 X509_V_FLAG_CRL_CHECK_ALL);
590 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
591 HandleScope scope(args.GetIsolate());
593 SecureContext* sc = Unwrap<SecureContext>(args.This());
595 assert(sc->ca_store_ == NULL);
597 if (!root_cert_store) {
598 root_cert_store = X509_STORE_new();
600 for (int i = 0; root_certs[i]; i++) {
601 BIO* bp = NodeBIO::New();
603 if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
608 X509 *x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
615 X509_STORE_add_cert(root_cert_store, x509);
622 sc->ca_store_ = root_cert_store;
623 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
627 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
628 HandleScope scope(args.GetIsolate());
630 SecureContext* sc = Unwrap<SecureContext>(args.This());
632 if (args.Length() != 1 || !args[0]->IsString()) {
633 return sc->env()->ThrowTypeError("Bad parameter");
636 const String::Utf8Value ciphers(args[0]);
637 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
641 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
642 HandleScope scope(args.GetIsolate());
644 SecureContext* sc = Unwrap<SecureContext>(args.This());
645 Environment* env = sc->env();
647 if (args.Length() != 1 || !args[0]->IsString())
648 return env->ThrowTypeError("First argument should be a string");
650 String::Utf8Value curve(args[0]);
652 int nid = OBJ_sn2nid(*curve);
654 if (nid == NID_undef)
655 return env->ThrowTypeError("First argument should be a valid curve name");
657 EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
660 return env->ThrowTypeError("First argument should be a valid curve name");
662 SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
663 SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
669 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
670 HandleScope scope(args.GetIsolate());
672 SecureContext* sc = Unwrap<SecureContext>(args.This());
674 if (args.Length() != 1 || !args[0]->IntegerValue()) {
675 return sc->env()->ThrowTypeError("Bad parameter");
678 SSL_CTX_set_options(sc->ctx_, args[0]->IntegerValue());
682 void SecureContext::SetSessionIdContext(
683 const FunctionCallbackInfo<Value>& args) {
684 HandleScope scope(args.GetIsolate());
686 SecureContext* sc = Unwrap<SecureContext>(args.This());
688 if (args.Length() != 1 || !args[0]->IsString()) {
689 return sc->env()->ThrowTypeError("Bad parameter");
692 const String::Utf8Value sessionIdContext(args[0]);
693 const unsigned char* sid_ctx =
694 reinterpret_cast<const unsigned char*>(*sessionIdContext);
695 unsigned int sid_ctx_len = sessionIdContext.length();
697 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
703 Local<String> message;
705 bio = BIO_new(BIO_s_mem());
707 message = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
708 "SSL_CTX_set_session_id_context error");
710 ERR_print_errors(bio);
711 BIO_get_mem_ptr(bio, &mem);
712 message = OneByteString(args.GetIsolate(), mem->data, mem->length);
716 args.GetIsolate()->ThrowException(Exception::TypeError(message));
720 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
721 HandleScope scope(args.GetIsolate());
723 SecureContext* sc = Unwrap<SecureContext>(args.This());
725 if (args.Length() != 1 || !args[0]->IsInt32()) {
726 return sc->env()->ThrowTypeError("Bad parameter");
729 int32_t sessionTimeout = args[0]->Int32Value();
730 SSL_CTX_set_timeout(sc->ctx_, sessionTimeout);
734 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
735 HandleScope scope(args.GetIsolate());
736 SecureContext* sc = Unwrap<SecureContext>(args.This());
741 // Takes .pfx or .p12 and password in string or buffer format
742 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
743 Environment* env = Environment::GetCurrent(args.GetIsolate());
744 HandleScope scope(env->isolate());
748 EVP_PKEY* pkey = NULL;
750 STACK_OF(X509)* extraCerts = NULL;
754 SecureContext* sc = Unwrap<SecureContext>(args.This());
756 if (args.Length() < 1) {
757 return env->ThrowTypeError("Bad parameter");
760 in = LoadBIO(env, args[0]);
762 return env->ThrowError("Unable to load BIO");
765 if (args.Length() >= 2) {
766 ASSERT_IS_BUFFER(args[1]);
768 int passlen = Buffer::Length(args[1]);
771 return env->ThrowTypeError("Bad password");
773 pass = new char[passlen + 1];
774 int pass_written = DecodeWrite(env->isolate(),
780 assert(pass_written == passlen);
781 pass[passlen] = '\0';
784 if (d2i_PKCS12_bio(in, &p12) &&
785 PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
786 SSL_CTX_use_certificate(sc->ctx_, cert) &&
787 SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) {
789 while (X509* x509 = sk_X509_pop(extraCerts)) {
790 if (!sc->ca_store_) {
791 sc->ca_store_ = X509_STORE_new();
792 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
795 X509_STORE_add_cert(sc->ca_store_, x509);
796 SSL_CTX_add_client_CA(sc->ctx_, x509);
802 sk_X509_free(extraCerts);
812 unsigned long err = ERR_get_error();
813 const char* str = ERR_reason_error_string(err);
814 return env->ThrowError(str);
819 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
820 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
821 HandleScope handle_scope(args.GetIsolate());
823 SecureContext* wrap = Unwrap<SecureContext>(args.This());
825 Local<Object> buff = Buffer::New(wrap->env(), 48);
826 if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_,
828 Buffer::Length(buff)) != 1) {
829 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
832 args.GetReturnValue().Set(buff);
833 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
837 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
838 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
839 HandleScope scope(args.GetIsolate());
840 SecureContext* wrap = Unwrap<SecureContext>(args.This());
842 if (args.Length() < 1 ||
843 !Buffer::HasInstance(args[0]) ||
844 Buffer::Length(args[0]) != 48) {
845 return wrap->env()->ThrowTypeError("Bad argument");
848 if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_,
849 Buffer::Data(args[0]),
850 Buffer::Length(args[0])) != 1) {
851 return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
854 args.GetReturnValue().Set(true);
855 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
859 template <class Base>
860 void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
861 HandleScope scope(env->isolate());
863 NODE_SET_PROTOTYPE_METHOD(t, "getPeerCertificate", GetPeerCertificate);
864 NODE_SET_PROTOTYPE_METHOD(t, "getSession", GetSession);
865 NODE_SET_PROTOTYPE_METHOD(t, "setSession", SetSession);
866 NODE_SET_PROTOTYPE_METHOD(t, "loadSession", LoadSession);
867 NODE_SET_PROTOTYPE_METHOD(t, "isSessionReused", IsSessionReused);
868 NODE_SET_PROTOTYPE_METHOD(t, "isInitFinished", IsInitFinished);
869 NODE_SET_PROTOTYPE_METHOD(t, "verifyError", VerifyError);
870 NODE_SET_PROTOTYPE_METHOD(t, "getCurrentCipher", GetCurrentCipher);
871 NODE_SET_PROTOTYPE_METHOD(t, "endParser", EndParser);
872 NODE_SET_PROTOTYPE_METHOD(t, "renegotiate", Renegotiate);
873 NODE_SET_PROTOTYPE_METHOD(t, "shutdown", Shutdown);
874 NODE_SET_PROTOTYPE_METHOD(t, "getTLSTicket", GetTLSTicket);
875 NODE_SET_PROTOTYPE_METHOD(t, "newSessionDone", NewSessionDone);
877 #ifdef SSL_set_max_send_fragment
878 NODE_SET_PROTOTYPE_METHOD(t, "setMaxSendFragment", SetMaxSendFragment);
879 #endif // SSL_set_max_send_fragment
881 #ifdef OPENSSL_NPN_NEGOTIATED
882 NODE_SET_PROTOTYPE_METHOD(t, "getNegotiatedProtocol", GetNegotiatedProto);
883 NODE_SET_PROTOTYPE_METHOD(t, "setNPNProtocols", SetNPNProtocols);
884 #endif // OPENSSL_NPN_NEGOTIATED
888 template <class Base>
889 void SSLWrap<Base>::InitNPN(SecureContext* sc, Base* base) {
890 if (base->is_server()) {
891 #ifdef OPENSSL_NPN_NEGOTIATED
892 // Server should advertise NPN protocols
893 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
894 AdvertiseNextProtoCallback,
896 #endif // OPENSSL_NPN_NEGOTIATED
898 #ifdef OPENSSL_NPN_NEGOTIATED
899 // Client should select protocol from list of advertised
900 // If server supports NPN
901 SSL_CTX_set_next_proto_select_cb(sc->ctx_, SelectNextProtoCallback, base);
902 #endif // OPENSSL_NPN_NEGOTIATED
907 template <class Base>
908 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
912 Base* w = static_cast<Base*>(SSL_get_app_data(s));
915 SSL_SESSION* sess = w->next_sess_;
916 w->next_sess_ = NULL;
922 template <class Base>
923 int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
924 Base* w = static_cast<Base*>(SSL_get_app_data(s));
925 Environment* env = w->ssl_env();
926 HandleScope handle_scope(env->isolate());
927 Context::Scope context_scope(env->context());
929 if (!w->session_callbacks_)
932 // Check if session is small enough to be stored
933 int size = i2d_SSL_SESSION(sess, NULL);
934 if (size > SecureContext::kMaxSessionSize)
938 Local<Object> buff = Buffer::New(env, size);
939 unsigned char* serialized = reinterpret_cast<unsigned char*>(
941 memset(serialized, 0, size);
942 i2d_SSL_SESSION(sess, &serialized);
944 Local<Object> session = Buffer::New(env,
945 reinterpret_cast<char*>(sess->session_id),
946 sess->session_id_length);
947 Local<Value> argv[] = { session, buff };
948 w->new_session_wait_ = true;
949 w->MakeCallback(env->onnewsession_string(), ARRAY_SIZE(argv), argv);
955 template <class Base>
956 void SSLWrap<Base>::OnClientHello(void* arg,
957 const ClientHelloParser::ClientHello& hello) {
958 Base* w = static_cast<Base*>(arg);
959 Environment* env = w->ssl_env();
960 HandleScope handle_scope(env->isolate());
961 Context::Scope context_scope(env->context());
963 Local<Object> hello_obj = Object::New(env->isolate());
964 Local<Object> buff = Buffer::New(
966 reinterpret_cast<const char*>(hello.session_id()),
967 hello.session_size());
968 hello_obj->Set(env->session_id_string(), buff);
969 if (hello.servername() == NULL) {
970 hello_obj->Set(env->servername_string(), String::Empty(env->isolate()));
972 Local<String> servername = OneByteString(env->isolate(),
974 hello.servername_size());
975 hello_obj->Set(env->servername_string(), servername);
977 hello_obj->Set(env->tls_ticket_string(),
978 Boolean::New(env->isolate(), hello.has_ticket()));
980 Local<Value> argv[] = { hello_obj };
981 w->MakeCallback(env->onclienthello_string(), ARRAY_SIZE(argv), argv);
985 // TODO(indutny): Split it into multiple smaller functions
986 template <class Base>
987 void SSLWrap<Base>::GetPeerCertificate(
988 const FunctionCallbackInfo<Value>& args) {
989 HandleScope scope(args.GetIsolate());
991 Base* w = Unwrap<Base>(args.This());
992 Environment* env = w->ssl_env();
994 ClearErrorOnReturn clear_error_on_return;
995 (void) &clear_error_on_return; // Silence unused variable warning.
997 Local<Object> info = Object::New(env->isolate());
998 X509* peer_cert = SSL_get_peer_certificate(w->ssl_);
999 if (peer_cert != NULL) {
1000 BIO* bio = BIO_new(BIO_s_mem());
1002 if (X509_NAME_print_ex(bio,
1003 X509_get_subject_name(peer_cert),
1005 X509_NAME_FLAGS) > 0) {
1006 BIO_get_mem_ptr(bio, &mem);
1007 info->Set(env->subject_string(),
1008 OneByteString(args.GetIsolate(), mem->data, mem->length));
1010 (void) BIO_reset(bio);
1012 X509_NAME* issuer_name = X509_get_issuer_name(peer_cert);
1013 if (X509_NAME_print_ex(bio, issuer_name, 0, X509_NAME_FLAGS) > 0) {
1014 BIO_get_mem_ptr(bio, &mem);
1015 info->Set(env->issuer_string(),
1016 OneByteString(args.GetIsolate(), mem->data, mem->length));
1018 (void) BIO_reset(bio);
1020 int index = X509_get_ext_by_NID(peer_cert, NID_subject_alt_name, -1);
1022 X509_EXTENSION* ext;
1025 ext = X509_get_ext(peer_cert, index);
1026 assert(ext != NULL);
1028 rv = X509V3_EXT_print(bio, ext, 0, 0);
1031 BIO_get_mem_ptr(bio, &mem);
1032 info->Set(env->subjectaltname_string(),
1033 OneByteString(args.GetIsolate(), mem->data, mem->length));
1035 (void) BIO_reset(bio);
1038 EVP_PKEY* pkey = X509_get_pubkey(peer_cert);
1041 rsa = EVP_PKEY_get1_RSA(pkey);
1044 BN_print(bio, rsa->n);
1045 BIO_get_mem_ptr(bio, &mem);
1046 info->Set(env->modulus_string(),
1047 OneByteString(args.GetIsolate(), mem->data, mem->length));
1048 (void) BIO_reset(bio);
1050 BN_print(bio, rsa->e);
1051 BIO_get_mem_ptr(bio, &mem);
1052 info->Set(env->exponent_string(),
1053 OneByteString(args.GetIsolate(), mem->data, mem->length));
1054 (void) BIO_reset(bio);
1058 EVP_PKEY_free(pkey);
1066 ASN1_TIME_print(bio, X509_get_notBefore(peer_cert));
1067 BIO_get_mem_ptr(bio, &mem);
1068 info->Set(env->valid_from_string(),
1069 OneByteString(args.GetIsolate(), mem->data, mem->length));
1070 (void) BIO_reset(bio);
1072 ASN1_TIME_print(bio, X509_get_notAfter(peer_cert));
1073 BIO_get_mem_ptr(bio, &mem);
1074 info->Set(env->valid_to_string(),
1075 OneByteString(args.GetIsolate(), mem->data, mem->length));
1078 unsigned int md_size, i;
1079 unsigned char md[EVP_MAX_MD_SIZE];
1080 if (X509_digest(peer_cert, EVP_sha1(), md, &md_size)) {
1081 const char hex[] = "0123456789ABCDEF";
1082 char fingerprint[EVP_MAX_MD_SIZE * 3];
1084 // TODO(indutny): Unify it with buffer's code
1085 for (i = 0; i < md_size; i++) {
1086 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1087 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1088 fingerprint[(3*i)+2] = ':';
1092 fingerprint[(3*(md_size-1))+2] = '\0';
1094 fingerprint[0] = '\0';
1097 info->Set(env->fingerprint_string(),
1098 OneByteString(args.GetIsolate(), fingerprint));
1101 STACK_OF(ASN1_OBJECT)* eku = static_cast<STACK_OF(ASN1_OBJECT)*>(
1102 X509_get_ext_d2i(peer_cert, NID_ext_key_usage, NULL, NULL));
1104 Local<Array> ext_key_usage = Array::New(env->isolate());
1108 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1109 if (OBJ_obj2txt(buf, sizeof(buf), sk_ASN1_OBJECT_value(eku, i), 1) >= 0)
1110 ext_key_usage->Set(j++, OneByteString(args.GetIsolate(), buf));
1113 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1114 info->Set(env->ext_key_usage_string(), ext_key_usage);
1117 if (ASN1_INTEGER* serial_number = X509_get_serialNumber(peer_cert)) {
1118 if (BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, NULL)) {
1119 if (char* buf = BN_bn2hex(bn)) {
1120 info->Set(env->serial_number_string(),
1121 OneByteString(args.GetIsolate(), buf));
1128 X509_free(peer_cert);
1131 args.GetReturnValue().Set(info);
1135 template <class Base>
1136 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
1137 Environment* env = Environment::GetCurrent(args.GetIsolate());
1138 HandleScope scope(env->isolate());
1140 Base* w = Unwrap<Base>(args.This());
1142 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1146 int slen = i2d_SSL_SESSION(sess, NULL);
1149 unsigned char* sbuf = new unsigned char[slen];
1150 unsigned char* p = sbuf;
1151 i2d_SSL_SESSION(sess, &p);
1152 args.GetReturnValue().Set(Encode(env->isolate(), sbuf, slen, BUFFER));
1157 template <class Base>
1158 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
1159 Environment* env = Environment::GetCurrent(args.GetIsolate());
1160 HandleScope scope(env->isolate());
1162 Base* w = Unwrap<Base>(args.This());
1164 if (args.Length() < 1 ||
1165 (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
1166 return env->ThrowTypeError("Bad argument");
1169 ASSERT_IS_BUFFER(args[0]);
1170 ssize_t slen = Buffer::Length(args[0]);
1173 return env->ThrowTypeError("Bad argument");
1175 char* sbuf = new char[slen];
1177 ssize_t wlen = DecodeWrite(env->isolate(), sbuf, slen, args[0], BINARY);
1178 assert(wlen == slen);
1180 const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
1181 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, wlen);
1188 int r = SSL_set_session(w->ssl_, sess);
1189 SSL_SESSION_free(sess);
1192 return env->ThrowError("SSL_set_session error");
1196 template <class Base>
1197 void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
1198 HandleScope scope(args.GetIsolate());
1200 Base* w = Unwrap<Base>(args.This());
1201 Environment* env = w->ssl_env();
1203 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1204 ssize_t slen = Buffer::Length(args[0]);
1205 char* sbuf = Buffer::Data(args[0]);
1207 const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1208 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, slen);
1210 // Setup next session and move hello to the BIO buffer
1211 if (w->next_sess_ != NULL)
1212 SSL_SESSION_free(w->next_sess_);
1213 w->next_sess_ = sess;
1215 Local<Object> info = Object::New(env->isolate());
1216 #ifndef OPENSSL_NO_TLSEXT
1217 if (sess->tlsext_hostname == NULL) {
1218 info->Set(env->servername_string(), False(args.GetIsolate()));
1220 info->Set(env->servername_string(),
1221 OneByteString(args.GetIsolate(), sess->tlsext_hostname));
1224 args.GetReturnValue().Set(info);
1229 template <class Base>
1230 void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
1231 HandleScope scope(args.GetIsolate());
1232 Base* w = Unwrap<Base>(args.This());
1233 bool yes = SSL_session_reused(w->ssl_);
1234 args.GetReturnValue().Set(yes);
1238 template <class Base>
1239 void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
1240 HandleScope scope(args.GetIsolate());
1241 Base* w = Unwrap<Base>(args.This());
1242 w->hello_parser_.End();
1246 template <class Base>
1247 void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
1248 HandleScope scope(args.GetIsolate());
1250 Base* w = Unwrap<Base>(args.This());
1252 ClearErrorOnReturn clear_error_on_return;
1253 (void) &clear_error_on_return; // Silence unused variable warning.
1255 bool yes = SSL_renegotiate(w->ssl_) == 1;
1256 args.GetReturnValue().Set(yes);
1260 template <class Base>
1261 void SSLWrap<Base>::Shutdown(const FunctionCallbackInfo<Value>& args) {
1262 HandleScope scope(args.GetIsolate());
1264 Base* w = Unwrap<Base>(args.This());
1266 int rv = SSL_shutdown(w->ssl_);
1267 args.GetReturnValue().Set(rv);
1271 template <class Base>
1272 void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
1273 HandleScope scope(args.GetIsolate());
1275 Base* w = Unwrap<Base>(args.This());
1276 Environment* env = w->ssl_env();
1278 SSL_SESSION* sess = SSL_get_session(w->ssl_);
1279 if (sess == NULL || sess->tlsext_tick == NULL)
1282 Local<Object> buf = Buffer::New(env,
1283 reinterpret_cast<char*>(sess->tlsext_tick),
1284 sess->tlsext_ticklen);
1286 args.GetReturnValue().Set(buf);
1290 template <class Base>
1291 void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
1292 HandleScope scope(args.GetIsolate());
1294 Base* w = Unwrap<Base>(args.This());
1295 w->new_session_wait_ = false;
1296 w->NewSessionDoneCb();
1300 #ifdef SSL_set_max_send_fragment
1301 template <class Base>
1302 void SSLWrap<Base>::SetMaxSendFragment(
1303 const v8::FunctionCallbackInfo<v8::Value>& args) {
1304 HandleScope scope(args.GetIsolate());
1305 CHECK(args.Length() >= 1 && args[0]->IsNumber());
1307 Base* w = Unwrap<Base>(args.This());
1309 int rv = SSL_set_max_send_fragment(w->ssl_, args[0]->Int32Value());
1310 args.GetReturnValue().Set(rv);
1312 #endif // SSL_set_max_send_fragment
1315 template <class Base>
1316 void SSLWrap<Base>::IsInitFinished(const FunctionCallbackInfo<Value>& args) {
1317 HandleScope scope(args.GetIsolate());
1318 Base* w = Unwrap<Base>(args.This());
1319 bool yes = SSL_is_init_finished(w->ssl_);
1320 args.GetReturnValue().Set(yes);
1324 template <class Base>
1325 void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
1326 HandleScope scope(args.GetIsolate());
1328 Base* w = Unwrap<Base>(args.This());
1330 // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
1331 // peer certificate is questionable but it's compatible with what was
1333 long x509_verify_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
1334 if (X509* peer_cert = SSL_get_peer_certificate(w->ssl_)) {
1335 X509_free(peer_cert);
1336 x509_verify_error = SSL_get_verify_result(w->ssl_);
1339 if (x509_verify_error == X509_V_OK)
1340 return args.GetReturnValue().SetNull();
1342 // XXX(bnoordhuis) X509_verify_cert_error_string() is not actually thread-safe
1343 // in the presence of invalid error codes. Probably academical but something
1344 // to keep in mind if/when node ever grows multi-isolate capabilities.
1345 const char* reason = X509_verify_cert_error_string(x509_verify_error);
1346 const char* code = reason;
1347 #define CASE_X509_ERR(CODE) case X509_V_ERR_##CODE: code = #CODE; break;
1348 switch (x509_verify_error) {
1349 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT)
1350 CASE_X509_ERR(UNABLE_TO_GET_CRL)
1351 CASE_X509_ERR(UNABLE_TO_DECRYPT_CERT_SIGNATURE)
1352 CASE_X509_ERR(UNABLE_TO_DECRYPT_CRL_SIGNATURE)
1353 CASE_X509_ERR(UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)
1354 CASE_X509_ERR(CERT_SIGNATURE_FAILURE)
1355 CASE_X509_ERR(CRL_SIGNATURE_FAILURE)
1356 CASE_X509_ERR(CERT_NOT_YET_VALID)
1357 CASE_X509_ERR(CERT_HAS_EXPIRED)
1358 CASE_X509_ERR(CRL_NOT_YET_VALID)
1359 CASE_X509_ERR(CRL_HAS_EXPIRED)
1360 CASE_X509_ERR(ERROR_IN_CERT_NOT_BEFORE_FIELD)
1361 CASE_X509_ERR(ERROR_IN_CERT_NOT_AFTER_FIELD)
1362 CASE_X509_ERR(ERROR_IN_CRL_LAST_UPDATE_FIELD)
1363 CASE_X509_ERR(ERROR_IN_CRL_NEXT_UPDATE_FIELD)
1364 CASE_X509_ERR(OUT_OF_MEM)
1365 CASE_X509_ERR(DEPTH_ZERO_SELF_SIGNED_CERT)
1366 CASE_X509_ERR(SELF_SIGNED_CERT_IN_CHAIN)
1367 CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
1368 CASE_X509_ERR(UNABLE_TO_VERIFY_LEAF_SIGNATURE)
1369 CASE_X509_ERR(CERT_CHAIN_TOO_LONG)
1370 CASE_X509_ERR(CERT_REVOKED)
1371 CASE_X509_ERR(INVALID_CA)
1372 CASE_X509_ERR(PATH_LENGTH_EXCEEDED)
1373 CASE_X509_ERR(INVALID_PURPOSE)
1374 CASE_X509_ERR(CERT_UNTRUSTED)
1375 CASE_X509_ERR(CERT_REJECTED)
1377 #undef CASE_X509_ERR
1379 Isolate* isolate = args.GetIsolate();
1380 Local<String> reason_string = OneByteString(isolate, reason);
1381 Local<Value> exception_value = Exception::Error(reason_string);
1382 Local<Object> exception_object = exception_value->ToObject();
1383 exception_object->Set(FIXED_ONE_BYTE_STRING(isolate, "code"),
1384 OneByteString(isolate, code));
1385 args.GetReturnValue().Set(exception_object);
1389 template <class Base>
1390 void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
1391 HandleScope scope(args.GetIsolate());
1393 Base* w = Unwrap<Base>(args.This());
1394 Environment* env = w->ssl_env();
1396 OPENSSL_CONST SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_);
1400 Local<Object> info = Object::New(env->isolate());
1401 const char* cipher_name = SSL_CIPHER_get_name(c);
1402 info->Set(env->name_string(), OneByteString(args.GetIsolate(), cipher_name));
1403 const char* cipher_version = SSL_CIPHER_get_version(c);
1404 info->Set(env->version_string(),
1405 OneByteString(args.GetIsolate(), cipher_version));
1406 args.GetReturnValue().Set(info);
1410 #ifdef OPENSSL_NPN_NEGOTIATED
1411 template <class Base>
1412 int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s,
1413 const unsigned char** data,
1416 Base* w = static_cast<Base*>(arg);
1417 Environment* env = w->env();
1418 HandleScope handle_scope(env->isolate());
1419 Context::Scope context_scope(env->context());
1421 if (w->npn_protos_.IsEmpty()) {
1422 // No initialization - no NPN protocols
1423 *data = reinterpret_cast<const unsigned char*>("");
1426 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1427 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1428 *len = Buffer::Length(obj);
1431 return SSL_TLSEXT_ERR_OK;
1435 template <class Base>
1436 int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
1437 unsigned char** out,
1438 unsigned char* outlen,
1439 const unsigned char* in,
1442 Base* w = static_cast<Base*>(arg);
1443 Environment* env = w->env();
1444 HandleScope handle_scope(env->isolate());
1445 Context::Scope context_scope(env->context());
1447 // Release old protocol handler if present
1448 w->selected_npn_proto_.Reset();
1450 if (w->npn_protos_.IsEmpty()) {
1451 // We should at least select one protocol
1452 // If server is using NPN
1453 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
1456 // set status: unsupported
1457 w->selected_npn_proto_.Reset(env->isolate(), False(env->isolate()));
1459 return SSL_TLSEXT_ERR_OK;
1462 Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
1463 const unsigned char* npn_protos =
1464 reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
1465 size_t len = Buffer::Length(obj);
1467 int status = SSL_select_next_proto(out, outlen, in, inlen, npn_protos, len);
1468 Handle<Value> result;
1470 case OPENSSL_NPN_UNSUPPORTED:
1471 result = Null(env->isolate());
1473 case OPENSSL_NPN_NEGOTIATED:
1474 result = OneByteString(env->isolate(), *out, *outlen);
1476 case OPENSSL_NPN_NO_OVERLAP:
1477 result = False(env->isolate());
1483 if (!result.IsEmpty())
1484 w->selected_npn_proto_.Reset(env->isolate(), result);
1486 return SSL_TLSEXT_ERR_OK;
1490 template <class Base>
1491 void SSLWrap<Base>::GetNegotiatedProto(
1492 const FunctionCallbackInfo<Value>& args) {
1493 HandleScope scope(args.GetIsolate());
1495 Base* w = Unwrap<Base>(args.This());
1497 if (w->is_client()) {
1498 if (w->selected_npn_proto_.IsEmpty() == false) {
1499 args.GetReturnValue().Set(w->selected_npn_proto_);
1504 const unsigned char* npn_proto;
1505 unsigned int npn_proto_len;
1507 SSL_get0_next_proto_negotiated(w->ssl_, &npn_proto, &npn_proto_len);
1510 return args.GetReturnValue().Set(false);
1512 args.GetReturnValue().Set(
1513 OneByteString(args.GetIsolate(), npn_proto, npn_proto_len));
1517 template <class Base>
1518 void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
1519 HandleScope scope(args.GetIsolate());
1521 Base* w = Unwrap<Base>(args.This());
1523 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
1524 return w->env()->ThrowTypeError("Must give a Buffer as first argument");
1526 w->npn_protos_.Reset(args.GetIsolate(), args[0].As<Object>());
1528 #endif // OPENSSL_NPN_NEGOTIATED
1531 void Connection::OnClientHelloParseEnd(void* arg) {
1532 Connection* conn = static_cast<Connection*>(arg);
1534 // Write all accumulated data
1535 int r = BIO_write(conn->bio_read_,
1536 reinterpret_cast<char*>(conn->hello_data_),
1537 conn->hello_offset_);
1538 conn->HandleBIOError(conn->bio_read_, "BIO_write", r);
1539 conn->SetShutdownFlags();
1543 #ifdef SSL_PRINT_DEBUG
1544 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
1546 # define DEBUG_PRINT(...)
1550 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
1554 int retry = BIO_should_retry(bio);
1555 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
1557 if (BIO_should_write(bio)) {
1558 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n",
1564 } else if (BIO_should_read(bio)) {
1565 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
1569 char ssl_error_buf[512];
1570 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
1572 HandleScope scope(ssl_env()->isolate());
1573 Local<Value> exception =
1574 Exception::Error(OneByteString(ssl_env()->isolate(), ssl_error_buf));
1575 object()->Set(ssl_env()->error_string(), exception);
1577 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
1590 int Connection::HandleSSLError(const char* func,
1594 ClearErrorOnReturn clear_error_on_return;
1595 (void) &clear_error_on_return; // Silence unused variable warning.
1599 if (rv == 0 && zs == kZeroIsNotAnError)
1602 int err = SSL_get_error(ssl_, rv);
1604 if (err == SSL_ERROR_NONE) {
1607 } else if (err == SSL_ERROR_WANT_WRITE) {
1608 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
1611 } else if (err == SSL_ERROR_WANT_READ) {
1612 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
1615 } else if (err == SSL_ERROR_ZERO_RETURN) {
1616 HandleScope scope(ssl_env()->isolate());
1618 Local<Value> exception =
1619 Exception::Error(ssl_env()->zero_return_string());
1620 object()->Set(ssl_env()->error_string(), exception);
1623 } else if (err == SSL_ERROR_SYSCALL && ss == kIgnoreSyscall) {
1627 HandleScope scope(ssl_env()->isolate());
1631 assert(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
1633 // XXX We need to drain the error queue for this thread or else OpenSSL
1634 // has the possibility of blocking connections? This problem is not well
1635 // understood. And we should be somehow propagating these errors up
1636 // into JavaScript. There is no test which demonstrates this problem.
1637 // https://github.com/joyent/node/issues/1719
1638 bio = BIO_new(BIO_s_mem());
1640 ERR_print_errors(bio);
1641 BIO_get_mem_ptr(bio, &mem);
1642 Local<Value> exception = Exception::Error(
1643 OneByteString(ssl_env()->isolate(),
1646 object()->Set(ssl_env()->error_string(), exception);
1657 void Connection::ClearError() {
1659 HandleScope scope(ssl_env()->isolate());
1661 // We should clear the error in JS-land
1662 Local<String> error_key = ssl_env()->error_string();
1663 Local<Value> error = object()->Get(error_key);
1664 assert(error->BooleanValue() == false);
1669 void Connection::SetShutdownFlags() {
1670 HandleScope scope(ssl_env()->isolate());
1672 int flags = SSL_get_shutdown(ssl_);
1674 if (flags & SSL_SENT_SHUTDOWN) {
1675 Local<String> sent_shutdown_key = ssl_env()->sent_shutdown_string();
1676 object()->Set(sent_shutdown_key, True(ssl_env()->isolate()));
1679 if (flags & SSL_RECEIVED_SHUTDOWN) {
1680 Local<String> received_shutdown_key = ssl_env()->received_shutdown_string();
1681 object()->Set(received_shutdown_key, True(ssl_env()->isolate()));
1686 void Connection::NewSessionDoneCb() {
1687 HandleScope scope(env()->isolate());
1689 MakeCallback(env()->onnewsessiondone_string(), 0, NULL);
1693 void Connection::Initialize(Environment* env, Handle<Object> target) {
1694 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(),
1696 t->InstanceTemplate()->SetInternalFieldCount(1);
1697 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"));
1699 NODE_SET_PROTOTYPE_METHOD(t, "encIn", Connection::EncIn);
1700 NODE_SET_PROTOTYPE_METHOD(t, "clearOut", Connection::ClearOut);
1701 NODE_SET_PROTOTYPE_METHOD(t, "clearIn", Connection::ClearIn);
1702 NODE_SET_PROTOTYPE_METHOD(t, "encOut", Connection::EncOut);
1703 NODE_SET_PROTOTYPE_METHOD(t, "clearPending", Connection::ClearPending);
1704 NODE_SET_PROTOTYPE_METHOD(t, "encPending", Connection::EncPending);
1705 NODE_SET_PROTOTYPE_METHOD(t, "start", Connection::Start);
1706 NODE_SET_PROTOTYPE_METHOD(t, "close", Connection::Close);
1708 SSLWrap<Connection>::AddMethods(env, t);
1710 #ifdef OPENSSL_NPN_NEGOTIATED
1711 NODE_SET_PROTOTYPE_METHOD(t,
1712 "getNegotiatedProtocol",
1713 Connection::GetNegotiatedProto);
1714 NODE_SET_PROTOTYPE_METHOD(t,
1716 Connection::SetNPNProtocols);
1720 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1721 NODE_SET_PROTOTYPE_METHOD(t, "getServername", Connection::GetServername);
1722 NODE_SET_PROTOTYPE_METHOD(t, "setSNICallback", Connection::SetSNICallback);
1725 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection"),
1730 int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
1731 // Quoting SSL_set_verify(3ssl):
1733 // The VerifyCallback function is used to control the behaviour when
1734 // the SSL_VERIFY_PEER flag is set. It must be supplied by the
1735 // application and receives two arguments: preverify_ok indicates,
1736 // whether the verification of the certificate in question was passed
1737 // (preverify_ok=1) or not (preverify_ok=0). x509_ctx is a pointer to
1738 // the complete context used for the certificate chain verification.
1740 // The certificate chain is checked starting with the deepest nesting
1741 // level (the root CA certificate) and worked upward to the peer's
1742 // certificate. At each level signatures and issuer attributes are
1743 // checked. Whenever a verification error is found, the error number is
1744 // stored in x509_ctx and VerifyCallback is called with preverify_ok=0.
1745 // By applying X509_CTX_store_* functions VerifyCallback can locate the
1746 // certificate in question and perform additional steps (see EXAMPLES).
1747 // If no error is found for a certificate, VerifyCallback is called
1748 // with preverify_ok=1 before advancing to the next level.
1750 // The return value of VerifyCallback controls the strategy of the
1751 // further verification process. If VerifyCallback returns 0, the
1752 // verification process is immediately stopped with "verification
1753 // failed" state. If SSL_VERIFY_PEER is set, a verification failure
1754 // alert is sent to the peer and the TLS/SSL handshake is terminated. If
1755 // VerifyCallback returns 1, the verification process is continued. If
1756 // VerifyCallback always returns 1, the TLS/SSL handshake will not be
1757 // terminated with respect to verification failures and the connection
1758 // will be established. The calling process can however retrieve the
1759 // error code of the last verification error using
1760 // SSL_get_verify_result(3) or by maintaining its own error storage
1761 // managed by VerifyCallback.
1763 // If no VerifyCallback is specified, the default callback will be
1764 // used. Its return value is identical to preverify_ok, so that any
1765 // verification failure will lead to a termination of the TLS/SSL
1766 // handshake with an alert message, if SSL_VERIFY_PEER is set.
1768 // Since we cannot perform I/O quickly enough in this callback, we ignore
1769 // all preverify_ok errors and let the handshake continue. It is
1770 // imparative that the user use Connection::VerifyError after the
1771 // 'secure' callback has been made.
1776 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1777 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
1778 Connection* conn = static_cast<Connection*>(SSL_get_app_data(s));
1779 Environment* env = conn->env();
1780 HandleScope scope(env->isolate());
1782 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
1785 conn->servername_.Reset(env->isolate(),
1786 OneByteString(env->isolate(), servername));
1788 // Call the SNI callback and use its return value as context
1789 if (!conn->sniObject_.IsEmpty()) {
1790 conn->sniContext_.Reset();
1792 Local<Value> arg = PersistentToLocal(env->isolate(), conn->servername_);
1793 Local<Value> ret = conn->MakeCallback(env->onselect_string(), 1, &arg);
1795 // If ret is SecureContext
1796 Local<FunctionTemplate> secure_context_constructor_template =
1797 env->secure_context_constructor_template();
1798 if (secure_context_constructor_template->HasInstance(ret)) {
1799 conn->sniContext_.Reset(env->isolate(), ret);
1800 SecureContext* sc = Unwrap<SecureContext>(ret.As<Object>());
1802 SSL_set_SSL_CTX(s, sc->ctx_);
1804 return SSL_TLSEXT_ERR_NOACK;
1809 return SSL_TLSEXT_ERR_OK;
1813 void Connection::New(const FunctionCallbackInfo<Value>& args) {
1814 Environment* env = Environment::GetCurrent(args.GetIsolate());
1815 HandleScope scope(env->isolate());
1817 if (args.Length() < 1 || !args[0]->IsObject()) {
1818 env->ThrowError("First argument must be a crypto module Credentials");
1822 SecureContext* sc = Unwrap<SecureContext>(args[0]->ToObject());
1824 bool is_server = args[1]->BooleanValue();
1826 SSLWrap<Connection>::Kind kind =
1827 is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient;
1828 Connection* conn = new Connection(env, args.This(), sc, kind);
1829 conn->ssl_ = SSL_new(sc->ctx_);
1830 conn->bio_read_ = NodeBIO::New();
1831 conn->bio_write_ = NodeBIO::New();
1833 SSL_set_app_data(conn->ssl_, conn);
1836 SSL_set_info_callback(conn->ssl_, SSLInfoCallback);
1840 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1842 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
1843 } else if (args[2]->IsString()) {
1844 const String::Utf8Value servername(args[2]);
1845 SSL_set_tlsext_host_name(conn->ssl_, *servername);
1849 SSL_set_bio(conn->ssl_, conn->bio_read_, conn->bio_write_);
1851 #ifdef SSL_MODE_RELEASE_BUFFERS
1852 long mode = SSL_get_mode(conn->ssl_);
1853 SSL_set_mode(conn->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
1859 bool request_cert = args[2]->BooleanValue();
1860 if (!request_cert) {
1861 // Note reject_unauthorized ignored.
1862 verify_mode = SSL_VERIFY_NONE;
1864 bool reject_unauthorized = args[3]->BooleanValue();
1865 verify_mode = SSL_VERIFY_PEER;
1866 if (reject_unauthorized)
1867 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1870 // Note request_cert and reject_unauthorized are ignored for clients.
1871 verify_mode = SSL_VERIFY_NONE;
1875 // Always allow a connection. We'll reject in javascript.
1876 SSL_set_verify(conn->ssl_, verify_mode, VerifyCallback);
1879 SSL_set_accept_state(conn->ssl_);
1881 SSL_set_connect_state(conn->ssl_);
1886 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
1887 if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
1890 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
1891 // a non-const SSL* in OpenSSL <= 0.9.7e.
1892 SSL* ssl = const_cast<SSL*>(ssl_);
1893 Connection* conn = static_cast<Connection*>(SSL_get_app_data(ssl));
1894 Environment* env = conn->env();
1895 HandleScope handle_scope(env->isolate());
1896 Context::Scope context_scope(env->context());
1898 if (where & SSL_CB_HANDSHAKE_START) {
1899 conn->MakeCallback(env->onhandshakestart_string(), 0, NULL);
1902 if (where & SSL_CB_HANDSHAKE_DONE) {
1903 conn->MakeCallback(env->onhandshakedone_string(), 0, NULL);
1908 void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
1909 HandleScope scope(args.GetIsolate());
1911 Connection* conn = Unwrap<Connection>(args.This());
1912 Environment* env = conn->env();
1914 if (args.Length() < 3) {
1915 return env->ThrowTypeError("Takes 3 parameters");
1918 if (!Buffer::HasInstance(args[0])) {
1919 return env->ThrowTypeError("Second argument should be a buffer");
1922 char* buffer_data = Buffer::Data(args[0]);
1923 size_t buffer_length = Buffer::Length(args[0]);
1925 size_t off = args[1]->Int32Value();
1926 size_t len = args[2]->Int32Value();
1928 if (!Buffer::IsWithinBounds(off, len, buffer_length))
1929 return env->ThrowError("off + len > buffer.length");
1932 char* data = buffer_data + off;
1934 if (conn->is_server() && !conn->hello_parser_.IsEnded()) {
1935 // Just accumulate data, everything will be pushed to BIO later
1936 if (conn->hello_parser_.IsPaused()) {
1939 // Copy incoming data to the internal buffer
1940 // (which has a size of the biggest possible TLS frame)
1941 size_t available = sizeof(conn->hello_data_) - conn->hello_offset_;
1942 size_t copied = len < available ? len : available;
1943 memcpy(conn->hello_data_ + conn->hello_offset_, data, copied);
1944 conn->hello_offset_ += copied;
1946 conn->hello_parser_.Parse(conn->hello_data_, conn->hello_offset_);
1947 bytes_written = copied;
1950 bytes_written = BIO_write(conn->bio_read_, data, len);
1951 conn->HandleBIOError(conn->bio_read_, "BIO_write", bytes_written);
1952 conn->SetShutdownFlags();
1955 args.GetReturnValue().Set(bytes_written);
1959 void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
1960 HandleScope scope(args.GetIsolate());
1962 Connection* conn = Unwrap<Connection>(args.This());
1963 Environment* env = conn->env();
1965 if (args.Length() < 3) {
1966 return env->ThrowTypeError("Takes 3 parameters");
1969 if (!Buffer::HasInstance(args[0])) {
1970 return env->ThrowTypeError("Second argument should be a buffer");
1973 char* buffer_data = Buffer::Data(args[0]);
1974 size_t buffer_length = Buffer::Length(args[0]);
1976 size_t off = args[1]->Int32Value();
1977 size_t len = args[2]->Int32Value();
1979 if (!Buffer::IsWithinBounds(off, len, buffer_length))
1980 return env->ThrowError("off + len > buffer.length");
1982 if (!SSL_is_init_finished(conn->ssl_)) {
1985 if (conn->is_server()) {
1986 rv = SSL_accept(conn->ssl_);
1987 conn->HandleSSLError("SSL_accept:ClearOut",
1992 rv = SSL_connect(conn->ssl_);
1993 conn->HandleSSLError("SSL_connect:ClearOut",
2000 return args.GetReturnValue().Set(rv);
2004 int bytes_read = SSL_read(conn->ssl_, buffer_data + off, len);
2005 conn->HandleSSLError("SSL_read:ClearOut",
2009 conn->SetShutdownFlags();
2011 args.GetReturnValue().Set(bytes_read);
2015 void Connection::ClearPending(const FunctionCallbackInfo<Value>& args) {
2016 HandleScope scope(args.GetIsolate());
2017 Connection* conn = Unwrap<Connection>(args.This());
2018 int bytes_pending = BIO_pending(conn->bio_read_);
2019 args.GetReturnValue().Set(bytes_pending);
2023 void Connection::EncPending(const FunctionCallbackInfo<Value>& args) {
2024 HandleScope scope(args.GetIsolate());
2025 Connection* conn = Unwrap<Connection>(args.This());
2026 int bytes_pending = BIO_pending(conn->bio_write_);
2027 args.GetReturnValue().Set(bytes_pending);
2031 void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
2032 HandleScope scope(args.GetIsolate());
2034 Connection* conn = Unwrap<Connection>(args.This());
2035 Environment* env = conn->env();
2037 if (args.Length() < 3) {
2038 return env->ThrowTypeError("Takes 3 parameters");
2041 if (!Buffer::HasInstance(args[0])) {
2042 return env->ThrowTypeError("Second argument should be a buffer");
2045 char* buffer_data = Buffer::Data(args[0]);
2046 size_t buffer_length = Buffer::Length(args[0]);
2048 size_t off = args[1]->Int32Value();
2049 size_t len = args[2]->Int32Value();
2051 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2052 return env->ThrowError("off + len > buffer.length");
2054 int bytes_read = BIO_read(conn->bio_write_, buffer_data + off, len);
2056 conn->HandleBIOError(conn->bio_write_, "BIO_read:EncOut", bytes_read);
2057 conn->SetShutdownFlags();
2059 args.GetReturnValue().Set(bytes_read);
2063 void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
2064 HandleScope scope(args.GetIsolate());
2066 Connection* conn = Unwrap<Connection>(args.This());
2067 Environment* env = conn->env();
2069 if (args.Length() < 3) {
2070 return env->ThrowTypeError("Takes 3 parameters");
2073 if (!Buffer::HasInstance(args[0])) {
2074 return env->ThrowTypeError("Second argument should be a buffer");
2077 char* buffer_data = Buffer::Data(args[0]);
2078 size_t buffer_length = Buffer::Length(args[0]);
2080 size_t off = args[1]->Int32Value();
2081 size_t len = args[2]->Int32Value();
2083 if (!Buffer::IsWithinBounds(off, len, buffer_length))
2084 return env->ThrowError("off + len > buffer.length");
2086 if (!SSL_is_init_finished(conn->ssl_)) {
2088 if (conn->is_server()) {
2089 rv = SSL_accept(conn->ssl_);
2090 conn->HandleSSLError("SSL_accept:ClearIn",
2095 rv = SSL_connect(conn->ssl_);
2096 conn->HandleSSLError("SSL_connect:ClearIn",
2103 return args.GetReturnValue().Set(rv);
2107 int bytes_written = SSL_write(conn->ssl_, buffer_data + off, len);
2109 conn->HandleSSLError("SSL_write:ClearIn",
2111 len == 0 ? kZeroIsNotAnError : kZeroIsAnError,
2113 conn->SetShutdownFlags();
2115 args.GetReturnValue().Set(bytes_written);
2119 void Connection::Start(const FunctionCallbackInfo<Value>& args) {
2120 HandleScope scope(args.GetIsolate());
2122 Connection* conn = Unwrap<Connection>(args.This());
2125 if (!SSL_is_init_finished(conn->ssl_)) {
2126 if (conn->is_server()) {
2127 rv = SSL_accept(conn->ssl_);
2128 conn->HandleSSLError("SSL_accept:Start",
2133 rv = SSL_connect(conn->ssl_);
2134 conn->HandleSSLError("SSL_connect:Start",
2140 args.GetReturnValue().Set(rv);
2144 void Connection::Close(const FunctionCallbackInfo<Value>& args) {
2145 HandleScope scope(args.GetIsolate());
2147 Connection* conn = Unwrap<Connection>(args.This());
2149 if (conn->ssl_ != NULL) {
2150 SSL_free(conn->ssl_);
2156 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2157 void Connection::GetServername(const FunctionCallbackInfo<Value>& args) {
2158 HandleScope scope(args.GetIsolate());
2160 Connection* conn = Unwrap<Connection>(args.This());
2162 if (conn->is_server() && !conn->servername_.IsEmpty()) {
2163 args.GetReturnValue().Set(conn->servername_);
2165 args.GetReturnValue().Set(false);
2170 void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) {
2171 HandleScope scope(args.GetIsolate());
2173 Connection* conn = Unwrap<Connection>(args.This());
2174 Environment* env = conn->env();
2176 if (args.Length() < 1 || !args[0]->IsFunction()) {
2177 return env->ThrowError("Must give a Function as first argument");
2180 Local<Object> obj = Object::New(env->isolate());
2181 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "onselect"), args[0]);
2182 conn->sniObject_.Reset(args.GetIsolate(), obj);
2187 void CipherBase::Initialize(Environment* env, Handle<Object> target) {
2188 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
2190 t->InstanceTemplate()->SetInternalFieldCount(1);
2192 NODE_SET_PROTOTYPE_METHOD(t, "init", Init);
2193 NODE_SET_PROTOTYPE_METHOD(t, "initiv", InitIv);
2194 NODE_SET_PROTOTYPE_METHOD(t, "update", Update);
2195 NODE_SET_PROTOTYPE_METHOD(t, "final", Final);
2196 NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
2197 NODE_SET_PROTOTYPE_METHOD(t, "getAuthTag", GetAuthTag);
2198 NODE_SET_PROTOTYPE_METHOD(t, "setAuthTag", SetAuthTag);
2199 NODE_SET_PROTOTYPE_METHOD(t, "setAAD", SetAAD);
2201 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "CipherBase"),
2206 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
2207 assert(args.IsConstructCall() == true);
2208 HandleScope handle_scope(args.GetIsolate());
2209 CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
2210 Environment* env = Environment::GetCurrent(args.GetIsolate());
2211 new CipherBase(env, args.This(), kind);
2215 void CipherBase::Init(const char* cipher_type,
2216 const char* key_buf,
2218 HandleScope scope(env()->isolate());
2220 assert(cipher_ == NULL);
2221 cipher_ = EVP_get_cipherbyname(cipher_type);
2222 if (cipher_ == NULL) {
2223 return env()->ThrowError("Unknown cipher");
2226 unsigned char key[EVP_MAX_KEY_LENGTH];
2227 unsigned char iv[EVP_MAX_IV_LENGTH];
2229 int key_len = EVP_BytesToKey(cipher_,
2232 reinterpret_cast<const unsigned char*>(key_buf),
2238 EVP_CIPHER_CTX_init(&ctx_);
2239 EVP_CipherInit_ex(&ctx_, cipher_, NULL, NULL, NULL, kind_ == kCipher);
2240 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2241 EVP_CIPHER_CTX_cleanup(&ctx_);
2242 return env()->ThrowError("Invalid key length");
2245 EVP_CipherInit_ex(&ctx_,
2248 reinterpret_cast<unsigned char*>(key),
2249 reinterpret_cast<unsigned char*>(iv),
2251 initialised_ = true;
2255 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
2256 HandleScope scope(args.GetIsolate());
2258 CipherBase* cipher = Unwrap<CipherBase>(args.This());
2260 if (args.Length() < 2 ||
2261 !(args[0]->IsString() && Buffer::HasInstance(args[1]))) {
2262 return cipher->env()->ThrowError("Must give cipher-type, key");
2265 const String::Utf8Value cipher_type(args[0]);
2266 const char* key_buf = Buffer::Data(args[1]);
2267 ssize_t key_buf_len = Buffer::Length(args[1]);
2268 cipher->Init(*cipher_type, key_buf, key_buf_len);
2272 void CipherBase::InitIv(const char* cipher_type,
2277 HandleScope scope(env()->isolate());
2279 cipher_ = EVP_get_cipherbyname(cipher_type);
2280 if (cipher_ == NULL) {
2281 return env()->ThrowError("Unknown cipher");
2284 /* OpenSSL versions up to 0.9.8l failed to return the correct
2285 iv_length (0) for ECB ciphers */
2286 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
2287 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2288 return env()->ThrowError("Invalid IV length");
2290 EVP_CIPHER_CTX_init(&ctx_);
2291 EVP_CipherInit_ex(&ctx_, cipher_, NULL, NULL, NULL, kind_ == kCipher);
2292 if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
2293 EVP_CIPHER_CTX_cleanup(&ctx_);
2294 return env()->ThrowError("Invalid key length");
2297 EVP_CipherInit_ex(&ctx_,
2300 reinterpret_cast<const unsigned char*>(key),
2301 reinterpret_cast<const unsigned char*>(iv),
2303 initialised_ = true;
2307 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
2308 HandleScope scope(args.GetIsolate());
2310 CipherBase* cipher = Unwrap<CipherBase>(args.This());
2311 Environment* env = cipher->env();
2313 if (args.Length() < 3 || !args[0]->IsString()) {
2314 return env->ThrowError("Must give cipher-type, key, and iv as argument");
2317 ASSERT_IS_BUFFER(args[1]);
2318 ASSERT_IS_BUFFER(args[2]);
2320 const String::Utf8Value cipher_type(args[0]);
2321 ssize_t key_len = Buffer::Length(args[1]);
2322 const char* key_buf = Buffer::Data(args[1]);
2323 ssize_t iv_len = Buffer::Length(args[2]);
2324 const char* iv_buf = Buffer::Data(args[2]);
2325 cipher->InitIv(*cipher_type, key_buf, key_len, iv_buf, iv_len);
2329 bool CipherBase::IsAuthenticatedMode() const {
2330 // check if this cipher operates in an AEAD mode that we support.
2333 int mode = EVP_CIPHER_mode(cipher_);
2334 return mode == EVP_CIPH_GCM_MODE;
2338 bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
2339 // only callable after Final and if encrypting.
2340 if (initialised_ || kind_ != kCipher || !auth_tag_)
2342 *out_len = auth_tag_len_;
2343 *out = new char[auth_tag_len_];
2344 memcpy(*out, auth_tag_, auth_tag_len_);
2349 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
2350 Environment* env = Environment::GetCurrent(args.GetIsolate());
2351 HandleScope handle_scope(args.GetIsolate());
2352 CipherBase* cipher = Unwrap<CipherBase>(args.This());
2355 unsigned int out_len = 0;
2357 if (cipher->GetAuthTag(&out, &out_len)) {
2358 Local<Object> buf = Buffer::Use(env, out, out_len);
2359 args.GetReturnValue().Set(buf);
2361 env->ThrowError("Attempting to get auth tag in unsupported state");
2366 bool CipherBase::SetAuthTag(const char* data, unsigned int len) {
2367 if (!initialised_ || !IsAuthenticatedMode() || kind_ != kDecipher)
2370 auth_tag_len_ = len;
2371 auth_tag_ = new char[len];
2372 memcpy(auth_tag_, data, len);
2377 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
2378 HandleScope handle_scope(args.GetIsolate());
2379 Environment* env = Environment::GetCurrent(args.GetIsolate());
2381 Local<Object> buf = args[0].As<Object>();
2382 if (!buf->IsObject() || !Buffer::HasInstance(buf))
2383 return env->ThrowTypeError("Argument must be a Buffer");
2385 CipherBase* cipher = Unwrap<CipherBase>(args.This());
2387 if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf)))
2388 env->ThrowError("Attempting to set auth tag in unsupported state");
2392 bool CipherBase::SetAAD(const char* data, unsigned int len) {
2393 if (!initialised_ || !IsAuthenticatedMode())
2396 if (!EVP_CipherUpdate(&ctx_,
2399 reinterpret_cast<const unsigned char*>(data),
2401 ThrowCryptoTypeError(env(), ERR_get_error());
2408 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
2409 Environment* env = Environment::GetCurrent(args.GetIsolate());
2410 HandleScope handle_scope(env->isolate());
2412 ASSERT_IS_BUFFER(args[0]);
2414 CipherBase* cipher = Unwrap<CipherBase>(args.This());
2416 if (!cipher->SetAAD(Buffer::Data(args[0]), Buffer::Length(args[0])))
2417 env->ThrowError("Attempting to set AAD in unsupported state");
2421 bool CipherBase::Update(const char* data,
2423 unsigned char** out,
2429 if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_ != NULL) {
2430 EVP_CIPHER_CTX_ctrl(&ctx_,
2431 EVP_CTRL_GCM_SET_TAG,
2433 reinterpret_cast<unsigned char*>(auth_tag_));
2438 *out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
2439 *out = new unsigned char[*out_len];
2440 return EVP_CipherUpdate(&ctx_,
2443 reinterpret_cast<const unsigned char*>(data),
2448 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
2449 HandleScope handle_scope(args.GetIsolate());
2450 Environment* env = Environment::GetCurrent(args.GetIsolate());
2452 CipherBase* cipher = Unwrap<CipherBase>(args.This());
2454 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2456 unsigned char* out = NULL;
2460 // Only copy the data if we have to, because it's a string
2461 if (args[0]->IsString()) {
2462 Local<String> string = args[0].As<String>();
2463 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2464 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2465 return env->ThrowTypeError("Bad input string");
2466 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2467 char* buf = new char[buflen];
2468 size_t written = StringBytes::Write(env->isolate(),
2473 r = cipher->Update(buf, written, &out, &out_len);
2476 char* buf = Buffer::Data(args[0]);
2477 size_t buflen = Buffer::Length(args[0]);
2478 r = cipher->Update(buf, buflen, &out, &out_len);
2483 return ThrowCryptoTypeError(env, ERR_get_error());
2486 Local<Object> buf = Buffer::New(env, reinterpret_cast<char*>(out), out_len);
2490 args.GetReturnValue().Set(buf);
2494 bool CipherBase::SetAutoPadding(bool auto_padding) {
2497 return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
2501 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
2502 HandleScope scope(args.GetIsolate());
2503 CipherBase* cipher = Unwrap<CipherBase>(args.This());
2504 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2508 bool CipherBase::Final(unsigned char** out, int *out_len) {
2512 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx_)];
2513 int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
2515 if (r && kind_ == kCipher) {
2518 if (IsAuthenticatedMode()) {
2519 auth_tag_len_ = EVP_GCM_TLS_TAG_LEN; // use default tag length
2520 auth_tag_ = new char[auth_tag_len_];
2521 memset(auth_tag_, 0, auth_tag_len_);
2522 EVP_CIPHER_CTX_ctrl(&ctx_,
2523 EVP_CTRL_GCM_GET_TAG,
2525 reinterpret_cast<unsigned char*>(auth_tag_));
2529 EVP_CIPHER_CTX_cleanup(&ctx_);
2530 initialised_ = false;
2536 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
2537 HandleScope handle_scope(args.GetIsolate());
2538 Environment* env = Environment::GetCurrent(args.GetIsolate());
2540 CipherBase* cipher = Unwrap<CipherBase>(args.This());
2542 unsigned char* out_value = NULL;
2544 Local<Value> outString;
2546 bool r = cipher->Final(&out_value, &out_len);
2548 if (out_len <= 0 || !r) {
2553 return ThrowCryptoTypeError(env, ERR_get_error());
2556 args.GetReturnValue().Set(
2557 Buffer::New(env, reinterpret_cast<char*>(out_value), out_len));
2561 void Hmac::Initialize(Environment* env, v8::Handle<v8::Object> target) {
2562 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
2564 t->InstanceTemplate()->SetInternalFieldCount(1);
2566 NODE_SET_PROTOTYPE_METHOD(t, "init", HmacInit);
2567 NODE_SET_PROTOTYPE_METHOD(t, "update", HmacUpdate);
2568 NODE_SET_PROTOTYPE_METHOD(t, "digest", HmacDigest);
2570 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hmac"), t->GetFunction());
2574 void Hmac::New(const FunctionCallbackInfo<Value>& args) {
2575 HandleScope handle_scope(args.GetIsolate());
2576 Environment* env = Environment::GetCurrent(args.GetIsolate());
2577 new Hmac(env, args.This());
2581 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
2582 HandleScope scope(env()->isolate());
2584 assert(md_ == NULL);
2585 md_ = EVP_get_digestbyname(hash_type);
2587 return env()->ThrowError("Unknown message digest");
2589 HMAC_CTX_init(&ctx_);
2591 HMAC_Init(&ctx_, "", 0, md_);
2593 HMAC_Init(&ctx_, key, key_len, md_);
2595 initialised_ = true;
2599 void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
2600 HandleScope scope(args.GetIsolate());
2602 Hmac* hmac = Unwrap<Hmac>(args.This());
2603 Environment* env = hmac->env();
2605 if (args.Length() < 2 || !args[0]->IsString()) {
2606 return env->ThrowError("Must give hashtype string, key as arguments");
2609 ASSERT_IS_BUFFER(args[1]);
2611 const String::Utf8Value hash_type(args[0]);
2612 const char* buffer_data = Buffer::Data(args[1]);
2613 size_t buffer_length = Buffer::Length(args[1]);
2614 hmac->HmacInit(*hash_type, buffer_data, buffer_length);
2618 bool Hmac::HmacUpdate(const char* data, int len) {
2621 HMAC_Update(&ctx_, reinterpret_cast<const unsigned char*>(data), len);
2626 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
2627 Environment* env = Environment::GetCurrent(args.GetIsolate());
2628 HandleScope scope(env->isolate());
2630 Hmac* hmac = Unwrap<Hmac>(args.This());
2632 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2634 // Only copy the data if we have to, because it's a string
2636 if (args[0]->IsString()) {
2637 Local<String> string = args[0].As<String>();
2638 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2639 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2640 return env->ThrowTypeError("Bad input string");
2641 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2642 char* buf = new char[buflen];
2643 size_t written = StringBytes::Write(env->isolate(),
2648 r = hmac->HmacUpdate(buf, written);
2651 char* buf = Buffer::Data(args[0]);
2652 size_t buflen = Buffer::Length(args[0]);
2653 r = hmac->HmacUpdate(buf, buflen);
2657 return env->ThrowTypeError("HmacUpdate fail");
2662 bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
2665 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
2666 HMAC_Final(&ctx_, *md_value, md_len);
2667 HMAC_CTX_cleanup(&ctx_);
2668 initialised_ = false;
2673 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
2674 Environment* env = Environment::GetCurrent(args.GetIsolate());
2675 HandleScope scope(env->isolate());
2677 Hmac* hmac = Unwrap<Hmac>(args.This());
2679 enum encoding encoding = BUFFER;
2680 if (args.Length() >= 1) {
2681 encoding = ParseEncoding(env->isolate(), args[0]->ToString(), BUFFER);
2684 unsigned char* md_value = NULL;
2685 unsigned int md_len = 0;
2687 bool r = hmac->HmacDigest(&md_value, &md_len);
2693 Local<Value> rc = StringBytes::Encode(env->isolate(),
2694 reinterpret_cast<const char*>(md_value),
2698 args.GetReturnValue().Set(rc);
2702 void Hash::Initialize(Environment* env, v8::Handle<v8::Object> target) {
2703 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
2705 t->InstanceTemplate()->SetInternalFieldCount(1);
2707 NODE_SET_PROTOTYPE_METHOD(t, "update", HashUpdate);
2708 NODE_SET_PROTOTYPE_METHOD(t, "digest", HashDigest);
2710 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Hash"), t->GetFunction());
2714 void Hash::New(const FunctionCallbackInfo<Value>& args) {
2715 Environment* env = Environment::GetCurrent(args.GetIsolate());
2716 HandleScope scope(env->isolate());
2718 if (args.Length() == 0 || !args[0]->IsString()) {
2719 return env->ThrowError("Must give hashtype string as argument");
2722 const String::Utf8Value hash_type(args[0]);
2724 Hash* hash = new Hash(env, args.This());
2725 if (!hash->HashInit(*hash_type)) {
2726 return env->ThrowError("Digest method not supported");
2731 bool Hash::HashInit(const char* hash_type) {
2732 assert(md_ == NULL);
2733 md_ = EVP_get_digestbyname(hash_type);
2736 EVP_MD_CTX_init(&mdctx_);
2737 EVP_DigestInit_ex(&mdctx_, md_, NULL);
2738 initialised_ = true;
2743 bool Hash::HashUpdate(const char* data, int len) {
2746 EVP_DigestUpdate(&mdctx_, data, len);
2751 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
2752 Environment* env = Environment::GetCurrent(args.GetIsolate());
2753 HandleScope scope(env->isolate());
2755 Hash* hash = Unwrap<Hash>(args.This());
2757 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2759 // Only copy the data if we have to, because it's a string
2761 if (args[0]->IsString()) {
2762 Local<String> string = args[0].As<String>();
2763 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2764 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2765 return env->ThrowTypeError("Bad input string");
2766 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2767 char* buf = new char[buflen];
2768 size_t written = StringBytes::Write(env->isolate(),
2773 r = hash->HashUpdate(buf, written);
2776 char* buf = Buffer::Data(args[0]);
2777 size_t buflen = Buffer::Length(args[0]);
2778 r = hash->HashUpdate(buf, buflen);
2782 return env->ThrowTypeError("HashUpdate fail");
2787 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
2788 Environment* env = Environment::GetCurrent(args.GetIsolate());
2789 HandleScope scope(env->isolate());
2791 Hash* hash = Unwrap<Hash>(args.This());
2793 if (!hash->initialised_) {
2794 return env->ThrowError("Not initialized");
2797 enum encoding encoding = BUFFER;
2798 if (args.Length() >= 1) {
2799 encoding = ParseEncoding(env->isolate(), args[0]->ToString(), BUFFER);
2802 unsigned char md_value[EVP_MAX_MD_SIZE];
2803 unsigned int md_len;
2805 EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len);
2806 EVP_MD_CTX_cleanup(&hash->mdctx_);
2807 hash->initialised_ = false;
2809 Local<Value> rc = StringBytes::Encode(env->isolate(),
2810 reinterpret_cast<const char*>(md_value),
2813 args.GetReturnValue().Set(rc);
2817 void SignBase::CheckThrow(SignBase::Error error) {
2818 HandleScope scope(env()->isolate());
2821 case kSignUnknownDigest:
2822 return env()->ThrowError("Unknown message digest");
2824 case kSignNotInitialised:
2825 return env()->ThrowError("Not initialised");
2829 case kSignPrivateKey:
2830 case kSignPublicKey:
2832 unsigned long err = ERR_get_error();
2834 return ThrowCryptoError(env(), err);
2837 return env()->ThrowError("EVP_SignInit_ex failed");
2839 return env()->ThrowError("EVP_SignUpdate failed");
2840 case kSignPrivateKey:
2841 return env()->ThrowError("PEM_read_bio_PrivateKey failed");
2842 case kSignPublicKey:
2843 return env()->ThrowError("PEM_read_bio_PUBKEY failed");
2857 void Sign::Initialize(Environment* env, v8::Handle<v8::Object> target) {
2858 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
2860 t->InstanceTemplate()->SetInternalFieldCount(1);
2862 NODE_SET_PROTOTYPE_METHOD(t, "init", SignInit);
2863 NODE_SET_PROTOTYPE_METHOD(t, "update", SignUpdate);
2864 NODE_SET_PROTOTYPE_METHOD(t, "sign", SignFinal);
2866 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"), t->GetFunction());
2870 void Sign::New(const FunctionCallbackInfo<Value>& args) {
2871 HandleScope handle_scope(args.GetIsolate());
2872 Environment* env = Environment::GetCurrent(args.GetIsolate());
2873 new Sign(env, args.This());
2877 SignBase::Error Sign::SignInit(const char* sign_type) {
2878 assert(md_ == NULL);
2879 md_ = EVP_get_digestbyname(sign_type);
2881 return kSignUnknownDigest;
2883 EVP_MD_CTX_init(&mdctx_);
2884 if (!EVP_SignInit_ex(&mdctx_, md_, NULL))
2886 initialised_ = true;
2892 void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
2893 HandleScope scope(args.GetIsolate());
2895 Sign* sign = Unwrap<Sign>(args.This());
2897 if (args.Length() == 0 || !args[0]->IsString()) {
2898 return sign->env()->ThrowError("Must give signtype string as argument");
2901 const String::Utf8Value sign_type(args[0]);
2902 sign->CheckThrow(sign->SignInit(*sign_type));
2906 SignBase::Error Sign::SignUpdate(const char* data, int len) {
2908 return kSignNotInitialised;
2909 if (!EVP_SignUpdate(&mdctx_, data, len))
2915 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
2916 Environment* env = Environment::GetCurrent(args.GetIsolate());
2917 HandleScope scope(env->isolate());
2919 Sign* sign = Unwrap<Sign>(args.This());
2921 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2923 // Only copy the data if we have to, because it's a string
2925 if (args[0]->IsString()) {
2926 Local<String> string = args[0].As<String>();
2927 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
2928 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
2929 return env->ThrowTypeError("Bad input string");
2930 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
2931 char* buf = new char[buflen];
2932 size_t written = StringBytes::Write(env->isolate(),
2937 err = sign->SignUpdate(buf, written);
2940 char* buf = Buffer::Data(args[0]);
2941 size_t buflen = Buffer::Length(args[0]);
2942 err = sign->SignUpdate(buf, buflen);
2945 sign->CheckThrow(err);
2949 SignBase::Error Sign::SignFinal(const char* key_pem,
2951 const char* passphrase,
2952 unsigned char** sig,
2953 unsigned int *sig_len) {
2955 return kSignNotInitialised;
2958 EVP_PKEY* pkey = NULL;
2961 bp = BIO_new(BIO_s_mem());
2965 if (!BIO_write(bp, key_pem, key_pem_len))
2968 pkey = PEM_read_bio_PrivateKey(bp,
2971 const_cast<char*>(passphrase));
2975 if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey))
2978 initialised_ = false;
2982 EVP_PKEY_free(pkey);
2986 EVP_MD_CTX_cleanup(&mdctx_);
2989 return kSignPrivateKey;
2995 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
2996 Environment* env = Environment::GetCurrent(args.GetIsolate());
2997 HandleScope scope(env->isolate());
2999 Sign* sign = Unwrap<Sign>(args.This());
3001 unsigned char* md_value;
3002 unsigned int md_len;
3004 unsigned int len = args.Length();
3005 enum encoding encoding = BUFFER;
3006 if (len >= 2 && args[1]->IsString()) {
3007 encoding = ParseEncoding(env->isolate(), args[1]->ToString(), BUFFER);
3010 String::Utf8Value passphrase(args[2]);
3012 ASSERT_IS_BUFFER(args[0]);
3013 size_t buf_len = Buffer::Length(args[0]);
3014 char* buf = Buffer::Data(args[0]);
3016 md_len = 8192; // Maximum key size is 8192 bits
3017 md_value = new unsigned char[md_len];
3019 Error err = sign->SignFinal(
3022 len >= 3 && !args[2]->IsNull() ? *passphrase : NULL,
3025 if (err != kSignOk) {
3029 return sign->CheckThrow(err);
3032 Local<Value> rc = StringBytes::Encode(env->isolate(),
3033 reinterpret_cast<const char*>(md_value),
3037 args.GetReturnValue().Set(rc);
3041 void Verify::Initialize(Environment* env, v8::Handle<v8::Object> target) {
3042 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
3044 t->InstanceTemplate()->SetInternalFieldCount(1);
3046 NODE_SET_PROTOTYPE_METHOD(t, "init", VerifyInit);
3047 NODE_SET_PROTOTYPE_METHOD(t, "update", VerifyUpdate);
3048 NODE_SET_PROTOTYPE_METHOD(t, "verify", VerifyFinal);
3050 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
3055 void Verify::New(const FunctionCallbackInfo<Value>& args) {
3056 HandleScope handle_scope(args.GetIsolate());
3057 Environment* env = Environment::GetCurrent(args.GetIsolate());
3058 new Verify(env, args.This());
3062 SignBase::Error Verify::VerifyInit(const char* verify_type) {
3063 assert(md_ == NULL);
3064 md_ = EVP_get_digestbyname(verify_type);
3066 return kSignUnknownDigest;
3068 EVP_MD_CTX_init(&mdctx_);
3069 if (!EVP_VerifyInit_ex(&mdctx_, md_, NULL))
3071 initialised_ = true;
3077 void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
3078 HandleScope scope(args.GetIsolate());
3080 Verify* verify = Unwrap<Verify>(args.This());
3082 if (args.Length() == 0 || !args[0]->IsString()) {
3083 return verify->env()->ThrowError("Must give verifytype string as argument");
3086 const String::Utf8Value verify_type(args[0]);
3087 verify->CheckThrow(verify->VerifyInit(*verify_type));
3091 SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
3093 return kSignNotInitialised;
3095 if (!EVP_VerifyUpdate(&mdctx_, data, len))
3102 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
3103 Environment* env = Environment::GetCurrent(args.GetIsolate());
3104 HandleScope scope(env->isolate());
3106 Verify* verify = Unwrap<Verify>(args.This());
3108 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3110 // Only copy the data if we have to, because it's a string
3112 if (args[0]->IsString()) {
3113 Local<String> string = args[0].As<String>();
3114 enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
3115 if (!StringBytes::IsValidString(env->isolate(), string, encoding))
3116 return env->ThrowTypeError("Bad input string");
3117 size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
3118 char* buf = new char[buflen];
3119 size_t written = StringBytes::Write(env->isolate(),
3124 err = verify->VerifyUpdate(buf, written);
3127 char* buf = Buffer::Data(args[0]);
3128 size_t buflen = Buffer::Length(args[0]);
3129 err = verify->VerifyUpdate(buf, buflen);
3132 verify->CheckThrow(err);
3136 SignBase::Error Verify::VerifyFinal(const char* key_pem,
3140 bool* verify_result) {
3142 return kSignNotInitialised;
3144 ClearErrorOnReturn clear_error_on_return;
3145 (void) &clear_error_on_return; // Silence compiler warning.
3147 EVP_PKEY* pkey = NULL;
3153 bp = BIO_new(BIO_s_mem());
3157 if (!BIO_write(bp, key_pem, key_pem_len))
3160 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3161 // Split this out into a separate function once we have more than one
3162 // consumer of public keys.
3163 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3164 pkey = PEM_read_bio_PUBKEY(bp, NULL, CryptoPemCallback, NULL);
3167 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3168 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, CryptoPemCallback, NULL);
3170 pkey = EVP_PKEY_new();
3172 EVP_PKEY_set1_RSA(pkey, rsa);
3179 x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
3183 pkey = X509_get_pubkey(x509);
3189 r = EVP_VerifyFinal(&mdctx_,
3190 reinterpret_cast<const unsigned char*>(sig),
3196 EVP_PKEY_free(pkey);
3202 EVP_MD_CTX_cleanup(&mdctx_);
3203 initialised_ = false;
3206 return kSignPublicKey;
3208 *verify_result = r == 1;
3213 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
3214 Environment* env = Environment::GetCurrent(args.GetIsolate());
3215 HandleScope scope(env->isolate());
3217 Verify* verify = Unwrap<Verify>(args.This());
3219 ASSERT_IS_BUFFER(args[0]);
3220 char* kbuf = Buffer::Data(args[0]);
3221 ssize_t klen = Buffer::Length(args[0]);
3223 ASSERT_IS_STRING_OR_BUFFER(args[1]);
3224 // BINARY works for both buffers and binary strings.
3225 enum encoding encoding = BINARY;
3226 if (args.Length() >= 3) {
3227 encoding = ParseEncoding(env->isolate(), args[2]->ToString(), BINARY);
3230 ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);
3232 // only copy if we need to, because it's a string.
3234 if (args[1]->IsString()) {
3235 hbuf = new char[hlen];
3236 ssize_t hwritten = StringBytes::Write(env->isolate(),
3241 assert(hwritten == hlen);
3243 hbuf = Buffer::Data(args[1]);
3247 Error err = verify->VerifyFinal(kbuf, klen, hbuf, hlen, &verify_result);
3248 if (args[1]->IsString())
3251 return verify->CheckThrow(err);
3252 args.GetReturnValue().Set(verify_result);
3256 void DiffieHellman::Initialize(Environment* env, Handle<Object> target) {
3257 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
3259 static enum PropertyAttribute attributes =
3260 static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
3262 t->InstanceTemplate()->SetInternalFieldCount(1);
3264 NODE_SET_PROTOTYPE_METHOD(t, "generateKeys", GenerateKeys);
3265 NODE_SET_PROTOTYPE_METHOD(t, "computeSecret", ComputeSecret);
3266 NODE_SET_PROTOTYPE_METHOD(t, "getPrime", GetPrime);
3267 NODE_SET_PROTOTYPE_METHOD(t, "getGenerator", GetGenerator);
3268 NODE_SET_PROTOTYPE_METHOD(t, "getPublicKey", GetPublicKey);
3269 NODE_SET_PROTOTYPE_METHOD(t, "getPrivateKey", GetPrivateKey);
3270 NODE_SET_PROTOTYPE_METHOD(t, "setPublicKey", SetPublicKey);
3271 NODE_SET_PROTOTYPE_METHOD(t, "setPrivateKey", SetPrivateKey);
3273 t->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3274 DiffieHellman::VerifyErrorGetter,
3280 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"),
3283 Local<FunctionTemplate> t2 = FunctionTemplate::New(env->isolate(),
3284 DiffieHellmanGroup);
3285 t2->InstanceTemplate()->SetInternalFieldCount(1);
3287 NODE_SET_PROTOTYPE_METHOD(t2, "generateKeys", GenerateKeys);
3288 NODE_SET_PROTOTYPE_METHOD(t2, "computeSecret", ComputeSecret);
3289 NODE_SET_PROTOTYPE_METHOD(t2, "getPrime", GetPrime);
3290 NODE_SET_PROTOTYPE_METHOD(t2, "getGenerator", GetGenerator);
3291 NODE_SET_PROTOTYPE_METHOD(t2, "getPublicKey", GetPublicKey);
3292 NODE_SET_PROTOTYPE_METHOD(t2, "getPrivateKey", GetPrivateKey);
3294 t2->InstanceTemplate()->SetAccessor(env->verify_error_string(),
3295 DiffieHellman::VerifyErrorGetter,
3301 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
3306 bool DiffieHellman::Init(int primeLength, int g) {
3308 DH_generate_parameters_ex(dh, primeLength, g, 0);
3309 bool result = VerifyContext();
3312 initialised_ = true;
3317 bool DiffieHellman::Init(const char* p, int p_len, int g) {
3319 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3321 if (!BN_set_word(dh->g, g))
3323 bool result = VerifyContext();
3326 initialised_ = true;
3331 bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
3333 dh->p = BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, 0);
3334 dh->g = BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, 0);
3335 bool result = VerifyContext();
3338 initialised_ = true;
3343 void DiffieHellman::DiffieHellmanGroup(
3344 const FunctionCallbackInfo<Value>& args) {
3345 HandleScope scope(args.GetIsolate());
3347 Environment* env = Environment::GetCurrent(args.GetIsolate());
3348 DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
3350 if (args.Length() != 1 || !args[0]->IsString()) {
3351 return env->ThrowError("No group name given");
3354 bool initialized = false;
3356 const String::Utf8Value group_name(args[0]);
3357 for (unsigned int i = 0; i < ARRAY_SIZE(modp_groups); ++i) {
3358 const modp_group* it = modp_groups + i;
3360 if (strcasecmp(*group_name, it->name) != 0)
3363 initialized = diffieHellman->Init(it->prime,
3368 env->ThrowError("Initialization failed");
3372 env->ThrowError("Unknown group");
3376 void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
3377 HandleScope scope(args.GetIsolate());
3379 Environment* env = Environment::GetCurrent(args.GetIsolate());
3380 DiffieHellman* diffieHellman =
3381 new DiffieHellman(env, args.This());
3382 bool initialized = false;
3384 if (args.Length() == 2) {
3385 if (args[0]->IsInt32()) {
3386 if (args[1]->IsInt32()) {
3387 initialized = diffieHellman->Init(args[0]->Int32Value(),
3388 args[1]->Int32Value());
3391 if (args[1]->IsInt32()) {
3392 initialized = diffieHellman->Init(Buffer::Data(args[0]),
3393 Buffer::Length(args[0]),
3394 args[1]->Int32Value());
3396 initialized = diffieHellman->Init(Buffer::Data(args[0]),
3397 Buffer::Length(args[0]),
3398 Buffer::Data(args[1]),
3399 Buffer::Length(args[1]));
3405 return env->ThrowError("Initialization failed");
3410 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
3411 Environment* env = Environment::GetCurrent(args.GetIsolate());
3412 HandleScope scope(env->isolate());
3414 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
3416 if (!diffieHellman->initialised_) {
3417 return env->ThrowError("Not initialized");
3420 if (!DH_generate_key(diffieHellman->dh)) {
3421 return env->ThrowError("Key generation failed");
3424 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3425 char* data = new char[dataSize];
3426 BN_bn2bin(diffieHellman->dh->pub_key,
3427 reinterpret_cast<unsigned char*>(data));
3429 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3434 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
3435 Environment* env = Environment::GetCurrent(args.GetIsolate());
3436 HandleScope scope(env->isolate());
3438 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
3440 if (!diffieHellman->initialised_) {
3441 return env->ThrowError("Not initialized");
3444 int dataSize = BN_num_bytes(diffieHellman->dh->p);
3445 char* data = new char[dataSize];
3446 BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
3448 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3453 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
3454 Environment* env = Environment::GetCurrent(args.GetIsolate());
3455 HandleScope scope(env->isolate());
3457 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
3459 if (!diffieHellman->initialised_) {
3460 return env->ThrowError("Not initialized");
3463 int dataSize = BN_num_bytes(diffieHellman->dh->g);
3464 char* data = new char[dataSize];
3465 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
3467 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3472 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
3473 Environment* env = Environment::GetCurrent(args.GetIsolate());
3474 HandleScope scope(env->isolate());
3476 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
3478 if (!diffieHellman->initialised_) {
3479 return env->ThrowError("Not initialized");
3482 if (diffieHellman->dh->pub_key == NULL) {
3483 return env->ThrowError("No public key - did you forget to generate one?");
3486 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3487 char* data = new char[dataSize];
3488 BN_bn2bin(diffieHellman->dh->pub_key,
3489 reinterpret_cast<unsigned char*>(data));
3491 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3496 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
3497 Environment* env = Environment::GetCurrent(args.GetIsolate());
3498 HandleScope scope(env->isolate());
3500 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
3502 if (!diffieHellman->initialised_) {
3503 return env->ThrowError("Not initialized");
3506 if (diffieHellman->dh->priv_key == NULL) {
3507 return env->ThrowError("No private key - did you forget to generate one?");
3510 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
3511 char* data = new char[dataSize];
3512 BN_bn2bin(diffieHellman->dh->priv_key,
3513 reinterpret_cast<unsigned char*>(data));
3515 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3520 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
3521 Environment* env = Environment::GetCurrent(args.GetIsolate());
3522 HandleScope scope(env->isolate());
3524 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
3526 if (!diffieHellman->initialised_) {
3527 return env->ThrowError("Not initialized");
3530 ClearErrorOnReturn clear_error_on_return;
3531 (void) &clear_error_on_return; // Silence compiler warning.
3534 if (args.Length() == 0) {
3535 return env->ThrowError("First argument must be other party's public key");
3537 ASSERT_IS_BUFFER(args[0]);
3539 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3540 Buffer::Length(args[0]),
3544 int dataSize = DH_size(diffieHellman->dh);
3545 char* data = new char[dataSize];
3547 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
3555 checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
3560 return env->ThrowError("Invalid key");
3561 } else if (checkResult) {
3562 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
3563 return env->ThrowError("Supplied key is too small");
3564 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
3565 return env->ThrowError("Supplied key is too large");
3567 return env->ThrowError("Invalid key");
3570 return env->ThrowError("Invalid key");
3577 // DH_size returns number of bytes in a prime number
3578 // DH_compute_key returns number of bytes in a remainder of exponent, which
3579 // may have less bytes than a prime number. Therefore add 0-padding to the
3580 // allocated buffer.
3581 if (size != dataSize) {
3582 assert(dataSize > size);
3583 memmove(data + dataSize - size, data, size);
3584 memset(data, 0, dataSize - size);
3587 args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
3592 void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
3593 HandleScope scope(args.GetIsolate());
3595 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
3596 Environment* env = diffieHellman->env();
3598 if (!diffieHellman->initialised_) {
3599 return env->ThrowError("Not initialized");
3602 if (args.Length() == 0) {
3603 return env->ThrowError("First argument must be public key");
3605 ASSERT_IS_BUFFER(args[0]);
3606 diffieHellman->dh->pub_key = BN_bin2bn(
3607 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3608 Buffer::Length(args[0]), 0);
3613 void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
3614 HandleScope scope(args.GetIsolate());
3616 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
3617 Environment* env = diffieHellman->env();
3619 if (!diffieHellman->initialised_) {
3620 return env->ThrowError("Not initialized");
3623 if (args.Length() == 0) {
3624 return env->ThrowError("First argument must be private key");
3626 ASSERT_IS_BUFFER(args[0]);
3627 diffieHellman->dh->priv_key = BN_bin2bn(
3628 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3629 Buffer::Length(args[0]),
3635 void DiffieHellman::VerifyErrorGetter(Local<String> property,
3636 const PropertyCallbackInfo<Value>& args) {
3637 HandleScope scope(args.GetIsolate());
3639 DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
3641 if (!diffieHellman->initialised_)
3642 return diffieHellman->env()->ThrowError("Not initialized");
3644 args.GetReturnValue().Set(diffieHellman->verifyError_);
3648 bool DiffieHellman::VerifyContext() {
3650 if (!DH_check(dh, &codes))
3652 verifyError_ = codes;
3657 class PBKDF2Request : public AsyncWrap {
3659 PBKDF2Request(Environment* env,
3660 Local<Object> object,
3661 const EVP_MD* digest,
3668 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
3676 key_(static_cast<char*>(malloc(keylen))),
3679 FatalError("node::PBKDF2Request()", "Out of Memory");
3683 persistent().Reset();
3686 uv_work_t* work_req() {
3690 inline const EVP_MD* digest() const {
3694 inline ssize_t passlen() const {
3698 inline char* pass() const {
3702 inline ssize_t saltlen() const {
3706 inline char* salt() const {
3710 inline ssize_t keylen() const {
3714 inline char* key() const {
3718 inline ssize_t iter() const {
3722 inline void release() {
3731 inline int error() const {
3735 inline void set_error(int err) {
3739 // TODO(trevnorris): Make private and make work with CONTAINER_OF macro.
3740 uv_work_t work_req_;
3743 const EVP_MD* digest_;
3755 void EIO_PBKDF2(PBKDF2Request* req) {
3756 req->set_error(PKCS5_PBKDF2_HMAC(
3759 reinterpret_cast<unsigned char*>(req->salt()),
3764 reinterpret_cast<unsigned char*>(req->key())));
3765 memset(req->pass(), 0, req->passlen());
3766 memset(req->salt(), 0, req->saltlen());
3770 void EIO_PBKDF2(uv_work_t* work_req) {
3771 PBKDF2Request* req = CONTAINER_OF(work_req, PBKDF2Request, work_req_);
3776 void EIO_PBKDF2After(PBKDF2Request* req, Local<Value> argv[2]) {
3778 argv[0] = Undefined(req->env()->isolate());
3779 argv[1] = Encode(req->env()->isolate(), req->key(), req->keylen(), BUFFER);
3780 memset(req->key(), 0, req->keylen());
3782 argv[0] = Exception::Error(req->env()->pbkdf2_error_string());
3783 argv[1] = Undefined(req->env()->isolate());
3788 void EIO_PBKDF2After(uv_work_t* work_req, int status) {
3789 assert(status == 0);
3790 PBKDF2Request* req = CONTAINER_OF(work_req, PBKDF2Request, work_req_);
3791 Environment* env = req->env();
3792 HandleScope handle_scope(env->isolate());
3793 Context::Scope context_scope(env->context());
3794 Local<Value> argv[2];
3795 EIO_PBKDF2After(req, argv);
3796 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
3802 void PBKDF2(const FunctionCallbackInfo<Value>& args) {
3803 Environment* env = Environment::GetCurrent(args.GetIsolate());
3804 HandleScope scope(env->isolate());
3806 const EVP_MD* digest = NULL;
3807 const char* type_error = NULL;
3810 ssize_t passlen = -1;
3811 ssize_t saltlen = -1;
3812 ssize_t keylen = -1;
3813 ssize_t pass_written = -1;
3814 ssize_t salt_written = -1;
3816 PBKDF2Request* req = NULL;
3819 if (args.Length() != 5 && args.Length() != 6) {
3820 type_error = "Bad parameter";
3824 ASSERT_IS_BUFFER(args[0]);
3825 passlen = Buffer::Length(args[0]);
3827 type_error = "Bad password";
3831 pass = static_cast<char*>(malloc(passlen));
3833 FatalError("node::PBKDF2()", "Out of Memory");
3835 pass_written = DecodeWrite(env->isolate(), pass, passlen, args[0], BINARY);
3836 assert(pass_written == passlen);
3838 ASSERT_IS_BUFFER(args[1]);
3839 saltlen = Buffer::Length(args[1]);
3841 type_error = "Bad salt";
3845 salt = static_cast<char*>(malloc(saltlen));
3847 FatalError("node::PBKDF2()", "Out of Memory");
3849 salt_written = DecodeWrite(env->isolate(), salt, saltlen, args[1], BINARY);
3850 assert(salt_written == saltlen);
3852 if (!args[2]->IsNumber()) {
3853 type_error = "Iterations not a number";
3857 iter = args[2]->Int32Value();
3859 type_error = "Bad iterations";
3863 if (!args[3]->IsNumber()) {
3864 type_error = "Key length not a number";
3868 keylen = args[3]->Int32Value();
3870 type_error = "Bad key length";
3874 if (args[4]->IsString()) {
3875 String::Utf8Value digest_name(args[4]);
3876 digest = EVP_get_digestbyname(*digest_name);
3877 if (digest == NULL) {
3878 type_error = "Bad digest name";
3883 if (digest == NULL) {
3884 digest = EVP_sha1();
3887 obj = Object::New(env->isolate());
3888 req = new PBKDF2Request(env,
3898 if (args[5]->IsFunction()) {
3899 obj->Set(env->ondone_string(), args[5]);
3900 // XXX(trevnorris): This will need to go with the rest of domains.
3901 if (env->in_domain())
3902 obj->Set(env->domain_string(), env->domain_array()->Get(0));
3903 uv_queue_work(env->event_loop(),
3908 Local<Value> argv[2];
3910 EIO_PBKDF2After(req, argv);
3911 if (argv[0]->IsObject())
3912 env->isolate()->ThrowException(argv[0]);
3914 args.GetReturnValue().Set(argv[1]);
3921 return env->ThrowTypeError(type_error);
3925 // Only instantiate within a valid HandleScope.
3926 class RandomBytesRequest : public AsyncWrap {
3928 RandomBytesRequest(Environment* env, Local<Object> object, size_t size)
3929 : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
3932 data_(static_cast<char*>(malloc(size))) {
3934 FatalError("node::RandomBytesRequest()", "Out of Memory");
3937 ~RandomBytesRequest() {
3938 persistent().Reset();
3941 uv_work_t* work_req() {
3945 inline size_t size() const {
3949 inline char* data() const {
3953 inline void release() {
3958 inline void return_memory(char** d, size_t* len) {
3965 inline unsigned long error() const {
3969 inline void set_error(unsigned long err) {
3973 // TODO(trevnorris): Make private and make work with CONTAINER_OF macro.
3974 uv_work_t work_req_;
3977 unsigned long error_;
3983 template <bool pseudoRandom>
3984 void RandomBytesWork(uv_work_t* work_req) {
3985 RandomBytesRequest* req = CONTAINER_OF(work_req,
3990 if (pseudoRandom == true) {
3991 r = RAND_pseudo_bytes(reinterpret_cast<unsigned char*>(req->data()),
3994 r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data()), req->size());
3997 // RAND_bytes() returns 0 on error. RAND_pseudo_bytes() returns 0 when the
3998 // result is not cryptographically strong - but that's not an error.
3999 if (r == 0 && pseudoRandom == false) {
4000 req->set_error(ERR_get_error());
4001 } else if (r == -1) {
4002 req->set_error(static_cast<unsigned long>(-1));
4007 // don't call this function without a valid HandleScope
4008 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
4010 char errmsg[256] = "Operation not supported";
4012 if (req->error() != static_cast<unsigned long>(-1))
4013 ERR_error_string_n(req->error(), errmsg, sizeof errmsg);
4015 argv[0] = Exception::Error(OneByteString(req->env()->isolate(), errmsg));
4016 argv[1] = Null(req->env()->isolate());
4021 req->return_memory(&data, &size);
4022 argv[0] = Null(req->env()->isolate());
4023 argv[1] = Buffer::Use(data, size);
4028 void RandomBytesAfter(uv_work_t* work_req, int status) {
4029 assert(status == 0);
4030 RandomBytesRequest* req = CONTAINER_OF(work_req,
4033 Environment* env = req->env();
4034 HandleScope handle_scope(env->isolate());
4035 Context::Scope context_scope(env->context());
4036 Local<Value> argv[2];
4037 RandomBytesCheck(req, argv);
4038 req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
4043 template <bool pseudoRandom>
4044 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
4045 HandleScope handle_scope(args.GetIsolate());
4046 Environment* env = Environment::GetCurrent(args.GetIsolate());
4048 // maybe allow a buffer to write to? cuts down on object creation
4049 // when generating random data in a loop
4050 if (!args[0]->IsUint32()) {
4051 return env->ThrowTypeError("Argument #1 must be number > 0");
4054 const uint32_t size = args[0]->Uint32Value();
4055 if (size > Buffer::kMaxLength) {
4056 return env->ThrowTypeError("size > Buffer::kMaxLength");
4059 Local<Object> obj = Object::New(env->isolate());
4060 RandomBytesRequest* req = new RandomBytesRequest(env, obj, size);
4062 if (args[1]->IsFunction()) {
4063 obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "ondone"), args[1]);
4064 // XXX(trevnorris): This will need to go with the rest of domains.
4065 if (env->in_domain())
4066 obj->Set(env->domain_string(), env->domain_array()->Get(0));
4067 uv_queue_work(env->event_loop(),
4069 RandomBytesWork<pseudoRandom>,
4071 args.GetReturnValue().Set(obj);
4073 Local<Value> argv[2];
4074 RandomBytesWork<pseudoRandom>(req->work_req());
4075 RandomBytesCheck(req, argv);
4078 if (!argv[0]->IsNull())
4079 env->isolate()->ThrowException(argv[0]);
4081 args.GetReturnValue().Set(argv[1]);
4086 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
4087 Environment* env = Environment::GetCurrent(args.GetIsolate());
4088 HandleScope scope(env->isolate());
4090 SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
4092 return env->ThrowError("SSL_CTX_new() failed.");
4095 SSL* ssl = SSL_new(ctx);
4098 return env->ThrowError("SSL_new() failed.");
4101 Local<Array> arr = Array::New(env->isolate());
4102 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
4104 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
4105 SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
4106 arr->Set(i, OneByteString(args.GetIsolate(), SSL_CIPHER_get_name(cipher)));
4112 args.GetReturnValue().Set(arr);
4116 class CipherPushContext {
4118 explicit CipherPushContext(Environment* env)
4119 : arr(Array::New(env->isolate())),
4123 inline Environment* env() const { return env_; }
4132 template <class TypeName>
4133 static void array_push_back(const TypeName* md,
4137 CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
4138 ctx->arr->Set(ctx->arr->Length(), OneByteString(ctx->env()->isolate(), from));
4142 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
4143 Environment* env = Environment::GetCurrent(args.GetIsolate());
4144 HandleScope scope(env->isolate());
4145 CipherPushContext ctx(env);
4146 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
4147 args.GetReturnValue().Set(ctx.arr);
4151 void GetHashes(const FunctionCallbackInfo<Value>& args) {
4152 Environment* env = Environment::GetCurrent(args.GetIsolate());
4153 HandleScope scope(env->isolate());
4154 CipherPushContext ctx(env);
4155 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
4156 args.GetReturnValue().Set(ctx.arr);
4160 void Certificate::Initialize(Environment* env, Handle<Object> target) {
4161 HandleScope scope(env->isolate());
4163 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
4165 t->InstanceTemplate()->SetInternalFieldCount(1);
4167 NODE_SET_PROTOTYPE_METHOD(t, "verifySpkac", VerifySpkac);
4168 NODE_SET_PROTOTYPE_METHOD(t, "exportPublicKey", ExportPublicKey);
4169 NODE_SET_PROTOTYPE_METHOD(t, "exportChallenge", ExportChallenge);
4171 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Certificate"),
4176 void Certificate::New(const FunctionCallbackInfo<Value>& args) {
4177 HandleScope handle_scope(args.GetIsolate());
4178 Environment* env = Environment::GetCurrent(args.GetIsolate());
4179 new Certificate(env, args.This());
4183 bool Certificate::VerifySpkac(const char* data, unsigned int len) {
4185 EVP_PKEY* pkey = NULL;
4186 NETSCAPE_SPKI* spki = NULL;
4188 spki = NETSCAPE_SPKI_b64_decode(data, len);
4192 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
4196 i = NETSCAPE_SPKI_verify(spki, pkey) > 0;
4200 EVP_PKEY_free(pkey);
4203 NETSCAPE_SPKI_free(spki);
4209 void Certificate::VerifySpkac(const FunctionCallbackInfo<Value>& args) {
4210 HandleScope scope(args.GetIsolate());
4212 Certificate* certificate = Unwrap<Certificate>(args.This());
4213 Environment* env = certificate->env();
4216 if (args.Length() < 1)
4217 return env->ThrowTypeError("Missing argument");
4219 ASSERT_IS_BUFFER(args[0]);
4221 size_t length = Buffer::Length(args[0]);
4223 return args.GetReturnValue().Set(i);
4225 char* data = Buffer::Data(args[0]);
4226 assert(data != NULL);
4228 i = certificate->VerifySpkac(data, length) > 0;
4230 args.GetReturnValue().Set(i);
4234 const char* Certificate::ExportPublicKey(const char* data, int len) {
4236 EVP_PKEY* pkey = NULL;
4237 NETSCAPE_SPKI* spki = NULL;
4239 BIO* bio = BIO_new(BIO_s_mem());
4243 spki = NETSCAPE_SPKI_b64_decode(data, len);
4247 pkey = NETSCAPE_SPKI_get_pubkey(spki);
4251 if (PEM_write_bio_PUBKEY(bio, pkey) <= 0)
4254 BIO_write(bio, "\0", 1);
4256 BIO_get_mem_ptr(bio, &ptr);
4258 buf = new char[ptr->length];
4259 memcpy(buf, ptr->data, ptr->length);
4263 EVP_PKEY_free(pkey);
4266 NETSCAPE_SPKI_free(spki);
4275 void Certificate::ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
4276 Environment* env = Environment::GetCurrent(args.GetIsolate());
4277 HandleScope scope(env->isolate());
4279 Certificate* certificate = Unwrap<Certificate>(args.This());
4281 if (args.Length() < 1)
4282 return env->ThrowTypeError("Missing argument");
4284 ASSERT_IS_BUFFER(args[0]);
4286 size_t length = Buffer::Length(args[0]);
4288 return args.GetReturnValue().SetEmptyString();
4290 char* data = Buffer::Data(args[0]);
4291 assert(data != NULL);
4293 const char* pkey = certificate->ExportPublicKey(data, length);
4295 return args.GetReturnValue().SetEmptyString();
4297 Local<Value> out = Encode(env->isolate(), pkey, strlen(pkey), BUFFER);
4301 args.GetReturnValue().Set(out);
4305 const char* Certificate::ExportChallenge(const char* data, int len) {
4306 NETSCAPE_SPKI* sp = NULL;
4308 sp = NETSCAPE_SPKI_b64_decode(data, len);
4312 const char* buf = NULL;
4313 buf = reinterpret_cast<const char*>(ASN1_STRING_data(sp->spkac->challenge));
4319 void Certificate::ExportChallenge(const FunctionCallbackInfo<Value>& args) {
4320 Environment* env = Environment::GetCurrent(args.GetIsolate());
4321 HandleScope scope(env->isolate());
4323 Certificate* crt = Unwrap<Certificate>(args.This());
4325 if (args.Length() < 1)
4326 return env->ThrowTypeError("Missing argument");
4328 ASSERT_IS_BUFFER(args[0]);
4330 size_t len = Buffer::Length(args[0]);
4332 return args.GetReturnValue().SetEmptyString();
4334 char* data = Buffer::Data(args[0]);
4335 assert(data != NULL);
4337 const char* cert = crt->ExportChallenge(data, len);
4339 return args.GetReturnValue().SetEmptyString();
4341 Local<Value> outString = Encode(env->isolate(), cert, strlen(cert), BUFFER);
4345 args.GetReturnValue().Set(outString);
4349 void InitCryptoOnce() {
4351 OpenSSL_add_all_algorithms();
4352 SSL_load_error_strings();
4355 CRYPTO_set_locking_callback(crypto_lock_cb);
4356 CRYPTO_THREADID_set_callback(crypto_threadid_cb);
4358 // Turn off compression. Saves memory and protects against CRIME attacks.
4359 #if !defined(OPENSSL_NO_COMP)
4360 #if OPENSSL_VERSION_NUMBER < 0x00908000L
4361 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_method();
4363 STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
4365 sk_SSL_COMP_zero(comp_methods);
4366 assert(sk_SSL_COMP_num(comp_methods) == 0);
4369 #ifndef OPENSSL_NO_ENGINE
4370 ERR_load_ENGINE_strings();
4371 ENGINE_load_builtin_engines();
4372 #endif // !OPENSSL_NO_ENGINE
4376 #ifndef OPENSSL_NO_ENGINE
4377 void SetEngine(const FunctionCallbackInfo<Value>& args) {
4378 Environment* env = Environment::GetCurrent(args.GetIsolate());
4379 CHECK(args.Length() >= 2 && args[0]->IsString());
4380 unsigned int flags = args[1]->Uint32Value();
4382 ClearErrorOnReturn clear_error_on_return;
4383 (void) &clear_error_on_return; // Silence compiler warning.
4385 const String::Utf8Value engine_id(args[0]);
4386 ENGINE* engine = ENGINE_by_id(*engine_id);
4388 // Engine not found, try loading dynamically
4389 if (engine == NULL) {
4390 engine = ENGINE_by_id("dynamic");
4391 if (engine != NULL) {
4392 if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", *engine_id, 0) ||
4393 !ENGINE_ctrl_cmd_string(engine, "LOAD", NULL, 0)) {
4394 ENGINE_free(engine);
4400 if (engine == NULL) {
4401 int err = ERR_get_error();
4404 snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id);
4405 return env->ThrowError(tmp);
4407 return ThrowCryptoError(env, err);
4411 int r = ENGINE_set_default(engine, flags);
4412 ENGINE_free(engine);
4414 return ThrowCryptoError(env, ERR_get_error());
4416 #endif // !OPENSSL_NO_ENGINE
4419 // FIXME(bnoordhuis) Handle global init correctly.
4420 void InitCrypto(Handle<Object> target,
4421 Handle<Value> unused,
4422 Handle<Context> context,
4424 static uv_once_t init_once = UV_ONCE_INIT;
4425 uv_once(&init_once, InitCryptoOnce);
4427 Environment* env = Environment::GetCurrent(context);
4428 SecureContext::Initialize(env, target);
4429 Connection::Initialize(env, target);
4430 CipherBase::Initialize(env, target);
4431 DiffieHellman::Initialize(env, target);
4432 Hmac::Initialize(env, target);
4433 Hash::Initialize(env, target);
4434 Sign::Initialize(env, target);
4435 Verify::Initialize(env, target);
4436 Certificate::Initialize(env, target);
4438 #ifndef OPENSSL_NO_ENGINE
4439 NODE_SET_METHOD(target, "setEngine", SetEngine);
4440 #endif // !OPENSSL_NO_ENGINE
4441 NODE_SET_METHOD(target, "PBKDF2", PBKDF2);
4442 NODE_SET_METHOD(target, "randomBytes", RandomBytes<false>);
4443 NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<true>);
4444 NODE_SET_METHOD(target, "getSSLCiphers", GetSSLCiphers);
4445 NODE_SET_METHOD(target, "getCiphers", GetCiphers);
4446 NODE_SET_METHOD(target, "getHashes", GetHashes);
4449 } // namespace crypto
4452 NODE_MODULE_CONTEXT_AWARE_BUILTIN(crypto, node::crypto::InitCrypto)