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.
22 #include "node_crypto.h"
23 #include "node_crypto_groups.h"
27 #include "node_buffer.h"
28 #include "node_root_certs.h"
32 #define strcasecmp _stricmp
38 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
39 # define OPENSSL_CONST const
41 # define OPENSSL_CONST
44 #define ASSERT_IS_BUFFER(val) \
45 if (!Buffer::HasInstance(val)) { \
46 return ThrowException(Exception::TypeError(String::New("Not a buffer"))); \
49 static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----";
50 static const int PUBLIC_KEY_PFX_LEN = sizeof(PUBLIC_KEY_PFX) - 1;
51 static const char PUBRSA_KEY_PFX[] = "-----BEGIN RSA PUBLIC KEY-----";
52 static const int PUBRSA_KEY_PFX_LEN = sizeof(PUBRSA_KEY_PFX) - 1;
53 static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
54 | ASN1_STRFLGS_ESC_MSB
55 | XN_FLAG_SEP_MULTILINE
63 static Persistent<String> errno_symbol;
64 static Persistent<String> syscall_symbol;
65 static Persistent<String> subject_symbol;
66 static Persistent<String> subjectaltname_symbol;
67 static Persistent<String> modulus_symbol;
68 static Persistent<String> exponent_symbol;
69 static Persistent<String> issuer_symbol;
70 static Persistent<String> valid_from_symbol;
71 static Persistent<String> valid_to_symbol;
72 static Persistent<String> fingerprint_symbol;
73 static Persistent<String> name_symbol;
74 static Persistent<String> version_symbol;
75 static Persistent<String> ext_key_usage_symbol;
76 static Persistent<String> onhandshakestart_sym;
77 static Persistent<String> onhandshakedone_sym;
78 static Persistent<String> onclienthello_sym;
79 static Persistent<String> onnewsession_sym;
80 static Persistent<String> sessionid_sym;
82 static Persistent<FunctionTemplate> secure_context_constructor;
84 static uv_rwlock_t* locks;
87 static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
88 CRYPTO_THREADID_set_numeric(tid, uv_thread_self());
92 static void crypto_lock_init(void) {
95 n = CRYPTO_num_locks();
96 locks = new uv_rwlock_t[n];
98 for (i = 0; i < n; i++)
99 if (uv_rwlock_init(locks + i))
104 static void crypto_lock_cb(int mode, int n, const char* file, int line) {
105 assert((mode & CRYPTO_LOCK) || (mode & CRYPTO_UNLOCK));
106 assert((mode & CRYPTO_READ) || (mode & CRYPTO_WRITE));
108 if (mode & CRYPTO_LOCK) {
109 if (mode & CRYPTO_READ)
110 uv_rwlock_rdlock(locks + n);
112 uv_rwlock_wrlock(locks + n);
114 if (mode & CRYPTO_READ)
115 uv_rwlock_rdunlock(locks + n);
117 uv_rwlock_wrunlock(locks + n);
124 void SecureContext::Initialize(Handle<Object> target) {
127 Local<FunctionTemplate> t = FunctionTemplate::New(SecureContext::New);
128 secure_context_constructor = Persistent<FunctionTemplate>::New(t);
130 t->InstanceTemplate()->SetInternalFieldCount(1);
131 t->SetClassName(String::NewSymbol("SecureContext"));
133 NODE_SET_PROTOTYPE_METHOD(t, "init", SecureContext::Init);
134 NODE_SET_PROTOTYPE_METHOD(t, "setKey", SecureContext::SetKey);
135 NODE_SET_PROTOTYPE_METHOD(t, "setCert", SecureContext::SetCert);
136 NODE_SET_PROTOTYPE_METHOD(t, "addCACert", SecureContext::AddCACert);
137 NODE_SET_PROTOTYPE_METHOD(t, "addCRL", SecureContext::AddCRL);
138 NODE_SET_PROTOTYPE_METHOD(t, "addRootCerts", SecureContext::AddRootCerts);
139 NODE_SET_PROTOTYPE_METHOD(t, "setCiphers", SecureContext::SetCiphers);
140 NODE_SET_PROTOTYPE_METHOD(t, "setOptions", SecureContext::SetOptions);
141 NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
142 SecureContext::SetSessionIdContext);
143 NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
144 NODE_SET_PROTOTYPE_METHOD(t, "loadPKCS12", SecureContext::LoadPKCS12);
146 target->Set(String::NewSymbol("SecureContext"), t->GetFunction());
150 Handle<Value> SecureContext::New(const Arguments& args) {
152 SecureContext *p = new SecureContext();
153 p->Wrap(args.Holder());
158 Handle<Value> SecureContext::Init(const Arguments& args) {
161 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
163 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
165 if (args.Length() == 1 && args[0]->IsString()) {
166 String::Utf8Value sslmethod(args[0]);
168 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
169 #ifndef OPENSSL_NO_SSL2
170 method = SSLv2_method();
172 return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
174 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
175 #ifndef OPENSSL_NO_SSL2
176 method = SSLv2_server_method();
178 return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
180 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
181 #ifndef OPENSSL_NO_SSL2
182 method = SSLv2_client_method();
184 return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
186 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
187 method = SSLv3_method();
188 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
189 method = SSLv3_server_method();
190 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
191 method = SSLv3_client_method();
192 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
193 method = SSLv23_method();
194 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
195 method = SSLv23_server_method();
196 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
197 method = SSLv23_client_method();
198 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
199 method = TLSv1_method();
200 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
201 method = TLSv1_server_method();
202 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
203 method = TLSv1_client_method();
205 return ThrowException(Exception::Error(String::New("Unknown method")));
209 sc->ctx_ = SSL_CTX_new(method);
211 // SSL session cache configuration
212 SSL_CTX_set_session_cache_mode(sc->ctx_,
213 SSL_SESS_CACHE_SERVER |
214 SSL_SESS_CACHE_NO_INTERNAL |
215 SSL_SESS_CACHE_NO_AUTO_CLEAR);
216 SSL_CTX_sess_set_get_cb(sc->ctx_, GetSessionCallback);
217 SSL_CTX_sess_set_new_cb(sc->ctx_, NewSessionCallback);
219 sc->ca_store_ = NULL;
220 return True(node_isolate);
224 SSL_SESSION* SecureContext::GetSessionCallback(SSL* s,
230 Connection* p = static_cast<Connection*>(SSL_get_app_data(s));
233 SSL_SESSION* sess = p->next_sess_;
234 p->next_sess_ = NULL;
240 void SessionDataFree(char* data, void* hint) {
245 int SecureContext::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
248 Connection* p = static_cast<Connection*>(SSL_get_app_data(s));
250 // Check if session is small enough to be stored
251 int size = i2d_SSL_SESSION(sess, NULL);
252 if (size > kMaxSessionSize) return 0;
255 char* serialized = new char[size];
256 unsigned char* pserialized = reinterpret_cast<unsigned char*>(serialized);
257 memset(serialized, 0, size);
258 i2d_SSL_SESSION(sess, &pserialized);
260 Handle<Value> argv[2] = {
261 Buffer::New(reinterpret_cast<char*>(sess->session_id),
262 sess->session_id_length)->handle_,
263 Buffer::New(serialized, size, SessionDataFree, NULL)->handle_
266 if (onnewsession_sym.IsEmpty()) {
267 onnewsession_sym = NODE_PSYMBOL("onnewsession");
269 MakeCallback(p->handle_, onnewsession_sym, ARRAY_SIZE(argv), argv);
275 // Takes a string or buffer and loads it into a BIO.
276 // Caller responsible for BIO_free-ing the returned object.
277 static BIO* LoadBIO (Handle<Value> v) {
278 BIO *bio = BIO_new(BIO_s_mem());
279 if (!bio) return NULL;
286 String::Utf8Value s(v);
287 r = BIO_write(bio, *s, s.length());
288 } else if (Buffer::HasInstance(v)) {
289 char* buffer_data = Buffer::Data(v);
290 size_t buffer_length = Buffer::Length(v);
291 r = BIO_write(bio, buffer_data, buffer_length);
303 // Takes a string or buffer and loads it into an X509
304 // Caller responsible for X509_free-ing the returned object.
305 static X509* LoadX509 (Handle<Value> v) {
306 HandleScope scope; // necessary?
308 BIO *bio = LoadBIO(v);
309 if (!bio) return NULL;
311 X509 * x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
322 Handle<Value> SecureContext::SetKey(const Arguments& args) {
325 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
327 unsigned int len = args.Length();
328 if (len != 1 && len != 2) {
329 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
331 if (len == 2 && !args[1]->IsString()) {
332 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
335 BIO *bio = LoadBIO(args[0]);
336 if (!bio) return False(node_isolate);
338 String::Utf8Value passphrase(args[1]);
340 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, NULL,
341 len == 1 ? NULL : *passphrase);
345 unsigned long err = ERR_get_error();
347 return ThrowException(Exception::Error(
348 String::New("PEM_read_bio_PrivateKey")));
351 ERR_error_string_n(err, string, sizeof string);
352 return ThrowException(Exception::Error(String::New(string)));
355 SSL_CTX_use_PrivateKey(sc->ctx_, key);
359 return True(node_isolate);
363 // Read a file that contains our certificate in "PEM" format,
364 // possibly followed by a sequence of CA certificates that should be
365 // sent to the peer in the Certificate message.
367 // Taken from OpenSSL - editted for style.
368 int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, BIO *in) {
372 x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
375 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
379 ret = SSL_CTX_use_certificate(ctx, x);
381 if (ERR_peek_error() != 0) {
382 // Key/certificate mismatch doesn't imply ret==0 ...
387 // If we could set up our certificate, now proceed to
388 // the CA certificates.
393 if (ctx->extra_certs != NULL) {
394 sk_X509_pop_free(ctx->extra_certs, X509_free);
395 ctx->extra_certs = NULL;
398 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
399 r = SSL_CTX_add_extra_chain_cert(ctx, ca);
406 // Note that we must not free r if it was successfully
407 // added to the chain (while we must free the main
408 // certificate, since its reference count is increased
409 // by SSL_CTX_use_certificate).
412 // When the while loop ends, it's usually just EOF.
413 err = ERR_peek_last_error();
414 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
415 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
424 if (x != NULL) X509_free(x);
429 Handle<Value> SecureContext::SetCert(const Arguments& args) {
432 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
434 if (args.Length() != 1) {
435 return ThrowException(Exception::TypeError(
436 String::New("Bad parameter")));
439 BIO* bio = LoadBIO(args[0]);
440 if (!bio) return False(node_isolate);
442 int rv = SSL_CTX_use_certificate_chain(sc->ctx_, bio);
447 unsigned long err = ERR_get_error();
449 return ThrowException(Exception::Error(
450 String::New("SSL_CTX_use_certificate_chain")));
453 ERR_error_string_n(err, string, sizeof string);
454 return ThrowException(Exception::Error(String::New(string)));
457 return True(node_isolate);
461 Handle<Value> SecureContext::AddCACert(const Arguments& args) {
462 bool newCAStore = false;
465 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
467 if (args.Length() != 1) {
468 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
471 if (!sc->ca_store_) {
472 sc->ca_store_ = X509_STORE_new();
476 X509* x509 = LoadX509(args[0]);
477 if (!x509) return False(node_isolate);
479 X509_STORE_add_cert(sc->ca_store_, x509);
480 SSL_CTX_add_client_CA(sc->ctx_, x509);
485 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
488 return True(node_isolate);
492 Handle<Value> SecureContext::AddCRL(const Arguments& args) {
495 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
497 if (args.Length() != 1) {
498 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
501 BIO *bio = LoadBIO(args[0]);
502 if (!bio) return False(node_isolate);
504 X509_CRL *x509 = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
508 return False(node_isolate);
511 X509_STORE_add_crl(sc->ca_store_, x509);
513 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
514 X509_V_FLAG_CRL_CHECK_ALL);
519 return True(node_isolate);
524 Handle<Value> SecureContext::AddRootCerts(const Arguments& args) {
527 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
529 assert(sc->ca_store_ == NULL);
531 if (!root_cert_store) {
532 root_cert_store = X509_STORE_new();
534 for (int i = 0; root_certs[i]; i++) {
535 BIO *bp = BIO_new(BIO_s_mem());
537 if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
539 return False(node_isolate);
542 X509 *x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
546 return False(node_isolate);
549 X509_STORE_add_cert(root_cert_store, x509);
556 sc->ca_store_ = root_cert_store;
557 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
559 return True(node_isolate);
563 Handle<Value> SecureContext::SetCiphers(const Arguments& args) {
566 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
568 if (args.Length() != 1 || !args[0]->IsString()) {
569 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
572 String::Utf8Value ciphers(args[0]);
573 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
575 return True(node_isolate);
578 Handle<Value> SecureContext::SetOptions(const Arguments& args) {
581 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
583 if (args.Length() != 1 || !args[0]->IntegerValue()) {
584 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
587 SSL_CTX_set_options(sc->ctx_, args[0]->IntegerValue());
589 return True(node_isolate);
592 Handle<Value> SecureContext::SetSessionIdContext(const Arguments& args) {
595 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
597 if (args.Length() != 1 || !args[0]->IsString()) {
598 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
601 String::Utf8Value sessionIdContext(args[0]);
602 const unsigned char* sid_ctx = (const unsigned char*) *sessionIdContext;
603 unsigned int sid_ctx_len = sessionIdContext.length();
605 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
607 Local<String> message;
610 if ((bio = BIO_new(BIO_s_mem()))) {
611 ERR_print_errors(bio);
612 BIO_get_mem_ptr(bio, &mem);
613 message = String::New(mem->data, mem->length);
616 message = String::New("SSL_CTX_set_session_id_context error");
618 return ThrowException(Exception::TypeError(message));
621 return True(node_isolate);
624 Handle<Value> SecureContext::Close(const Arguments& args) {
626 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
628 return False(node_isolate);
631 //Takes .pfx or .p12 and password in string or buffer format
632 Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
637 EVP_PKEY* pkey = NULL;
639 STACK_OF(X509)* extraCerts = NULL;
643 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
645 if (args.Length() < 1) {
646 return ThrowException(Exception::TypeError(
647 String::New("Bad parameter")));
650 in = LoadBIO(args[0]);
652 return ThrowException(Exception::Error(
653 String::New("Unable to load BIO")));
656 if (args.Length() >= 2) {
657 ASSERT_IS_BUFFER(args[1]);
659 int passlen = Buffer::Length(args[1]);
662 return ThrowException(Exception::TypeError(
663 String::New("Bad password")));
665 pass = new char[passlen + 1];
666 int pass_written = DecodeWrite(pass, passlen, args[1], BINARY);
668 assert(pass_written == passlen);
669 pass[passlen] = '\0';
672 if (d2i_PKCS12_bio(in, &p12) &&
673 PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
674 SSL_CTX_use_certificate(sc->ctx_, cert) &&
675 SSL_CTX_use_PrivateKey(sc->ctx_, pkey))
678 while (X509* x509 = sk_X509_pop(extraCerts)) {
679 if (!sc->ca_store_) {
680 sc->ca_store_ = X509_STORE_new();
681 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
684 X509_STORE_add_cert(sc->ca_store_, x509);
685 SSL_CTX_add_client_CA(sc->ctx_, x509);
690 sk_X509_free(extraCerts);
700 unsigned long err = ERR_get_error();
701 const char* str = ERR_reason_error_string(err);
702 return ThrowException(Exception::Error(String::New(str)));
705 return True(node_isolate);
709 size_t ClientHelloParser::Write(const uint8_t* data, size_t len) {
712 // Just accumulate data, everything will be pushed to BIO later
713 if (state_ == kPaused) return 0;
715 // Copy incoming data to the internal buffer
716 // (which has a size of the biggest possible TLS frame)
717 size_t available = sizeof(data_) - offset_;
718 size_t copied = len < available ? len : available;
719 memcpy(data_ + offset_, data, copied);
722 // Vars for parsing hello
723 bool is_clienthello = false;
724 uint8_t session_size = -1;
725 uint8_t* session_id = NULL;
727 Handle<Value> argv[1];
731 // >= 5 bytes for header parsing
732 if (offset_ < 5) break;
734 if (data_[0] == kChangeCipherSpec || data_[0] == kAlert ||
735 data_[0] == kHandshake || data_[0] == kApplicationData) {
736 frame_len_ = (data_[3] << 8) + data_[4];
740 frame_len_ = (data_[0] << 8) + data_[1];
743 // header with padding
751 // Sanity check (too big frame, or too small)
752 if (frame_len_ >= sizeof(data_)) {
753 // Let OpenSSL handle it
759 // >= 5 + frame size bytes for frame parsing
760 if (offset_ < body_offset_ + frame_len_) break;
762 // Skip unsupported frames and gather some data from frame
764 // TODO: Check protocol version
765 if (data_[body_offset_] == kClientHello) {
766 is_clienthello = true;
768 size_t session_offset;
770 if (state_ == kTLSHeader) {
771 // Skip frame header, hello header, protocol version and random data
772 session_offset = body_offset_ + 4 + 2 + 32;
774 if (session_offset + 1 < offset_) {
775 body = data_ + session_offset;
776 session_size = *body;
777 session_id = body + 1;
779 } else if (state_ == kSSLHeader) {
780 // Skip header, version
781 session_offset = body_offset_ + 3;
783 if (session_offset + 4 < offset_) {
784 body = data_ + session_offset;
786 int ciphers_size = (body[0] << 8) + body[1];
788 if (body + 4 + ciphers_size < data_ + offset_) {
789 session_size = (body[2] << 8) + body[3];
790 session_id = body + 4 + ciphers_size;
794 // Whoa? How did we get here?
798 // Check if we overflowed (do not reply with any private data)
799 if (session_id == NULL ||
801 session_id + session_size > data_ + offset_) {
806 // TODO: Parse other things?
809 // Not client hello - let OpenSSL handle it
810 if (!is_clienthello) {
815 // Parse frame, call javascript handler and
816 // move parser into the paused state
817 if (onclienthello_sym.IsEmpty()) {
818 onclienthello_sym = NODE_PSYMBOL("onclienthello");
820 if (sessionid_sym.IsEmpty()) {
821 sessionid_sym = NODE_PSYMBOL("sessionId");
825 hello = Object::New();
826 hello->Set(sessionid_sym,
827 Buffer::New(reinterpret_cast<char*>(session_id),
828 session_size)->handle_);
831 MakeCallback(conn_->handle_, onclienthello_sym, 1, argv);
842 void ClientHelloParser::Finish() {
843 assert(state_ != kEnded);
846 // Write all accumulated data
847 int r = BIO_write(conn_->bio_read_, reinterpret_cast<char*>(data_), offset_);
848 conn_->HandleBIOError(conn_->bio_read_, "BIO_write", r);
849 conn_->SetShutdownFlags();
853 #ifdef SSL_PRINT_DEBUG
854 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
856 # define DEBUG_PRINT(...)
860 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
861 if (rv >= 0) return rv;
863 int retry = BIO_should_retry(bio);
864 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
866 if (BIO_should_write(bio)) {
867 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n", ssl_, func, retry);
870 } else if (BIO_should_read(bio)) {
871 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
875 static char ssl_error_buf[512];
876 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
879 Local<Value> e = Exception::Error(String::New(ssl_error_buf));
880 handle_->Set(String::New("error"), e);
882 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n", ssl_, func, rv, ssl_error_buf);
891 int Connection::HandleSSLError(const char* func, int rv, ZeroStatus zs) {
892 if (rv > 0) return rv;
893 if ((rv == 0) && (zs == kZeroIsNotAnError)) return rv;
895 int err = SSL_get_error(ssl_, rv);
897 if (err == SSL_ERROR_NONE) {
900 } else if (err == SSL_ERROR_WANT_WRITE) {
901 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
904 } else if (err == SSL_ERROR_WANT_READ) {
905 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
913 assert(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
915 // XXX We need to drain the error queue for this thread or else OpenSSL
916 // has the possibility of blocking connections? This problem is not well
917 // understood. And we should be somehow propagating these errors up
918 // into JavaScript. There is no test which demonstrates this problem.
919 // https://github.com/joyent/node/issues/1719
920 if ((bio = BIO_new(BIO_s_mem()))) {
921 ERR_print_errors(bio);
922 BIO_get_mem_ptr(bio, &mem);
923 Local<Value> e = Exception::Error(String::New(mem->data, mem->length));
924 handle_->Set(String::New("error"), e);
935 void Connection::ClearError() {
939 // We should clear the error in JS-land
940 assert(handle_->Get(String::New("error"))->BooleanValue() == false);
945 void Connection::SetShutdownFlags() {
948 int flags = SSL_get_shutdown(ssl_);
950 if (flags & SSL_SENT_SHUTDOWN) {
951 handle_->Set(String::New("sentShutdown"), True(node_isolate));
954 if (flags & SSL_RECEIVED_SHUTDOWN) {
955 handle_->Set(String::New("receivedShutdown"), True(node_isolate));
960 void Connection::Initialize(Handle<Object> target) {
963 Local<FunctionTemplate> t = FunctionTemplate::New(Connection::New);
964 t->InstanceTemplate()->SetInternalFieldCount(1);
965 t->SetClassName(String::NewSymbol("Connection"));
967 NODE_SET_PROTOTYPE_METHOD(t, "encIn", Connection::EncIn);
968 NODE_SET_PROTOTYPE_METHOD(t, "clearOut", Connection::ClearOut);
969 NODE_SET_PROTOTYPE_METHOD(t, "clearIn", Connection::ClearIn);
970 NODE_SET_PROTOTYPE_METHOD(t, "encOut", Connection::EncOut);
971 NODE_SET_PROTOTYPE_METHOD(t, "clearPending", Connection::ClearPending);
972 NODE_SET_PROTOTYPE_METHOD(t, "encPending", Connection::EncPending);
973 NODE_SET_PROTOTYPE_METHOD(t, "getPeerCertificate", Connection::GetPeerCertificate);
974 NODE_SET_PROTOTYPE_METHOD(t, "getSession", Connection::GetSession);
975 NODE_SET_PROTOTYPE_METHOD(t, "setSession", Connection::SetSession);
976 NODE_SET_PROTOTYPE_METHOD(t, "loadSession", Connection::LoadSession);
977 NODE_SET_PROTOTYPE_METHOD(t, "isSessionReused", Connection::IsSessionReused);
978 NODE_SET_PROTOTYPE_METHOD(t, "isInitFinished", Connection::IsInitFinished);
979 NODE_SET_PROTOTYPE_METHOD(t, "verifyError", Connection::VerifyError);
980 NODE_SET_PROTOTYPE_METHOD(t, "getCurrentCipher", Connection::GetCurrentCipher);
981 NODE_SET_PROTOTYPE_METHOD(t, "start", Connection::Start);
982 NODE_SET_PROTOTYPE_METHOD(t, "shutdown", Connection::Shutdown);
983 NODE_SET_PROTOTYPE_METHOD(t, "receivedShutdown", Connection::ReceivedShutdown);
984 NODE_SET_PROTOTYPE_METHOD(t, "close", Connection::Close);
986 #ifdef OPENSSL_NPN_NEGOTIATED
987 NODE_SET_PROTOTYPE_METHOD(t, "getNegotiatedProtocol", Connection::GetNegotiatedProto);
988 NODE_SET_PROTOTYPE_METHOD(t, "setNPNProtocols", Connection::SetNPNProtocols);
992 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
993 NODE_SET_PROTOTYPE_METHOD(t, "getServername", Connection::GetServername);
994 NODE_SET_PROTOTYPE_METHOD(t, "setSNICallback", Connection::SetSNICallback);
997 target->Set(String::NewSymbol("Connection"), t->GetFunction());
1001 static int VerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) {
1002 // Quoting SSL_set_verify(3ssl):
1004 // The VerifyCallback function is used to control the behaviour when
1005 // the SSL_VERIFY_PEER flag is set. It must be supplied by the
1006 // application and receives two arguments: preverify_ok indicates,
1007 // whether the verification of the certificate in question was passed
1008 // (preverify_ok=1) or not (preverify_ok=0). x509_ctx is a pointer to
1009 // the complete context used for the certificate chain verification.
1011 // The certificate chain is checked starting with the deepest nesting
1012 // level (the root CA certificate) and worked upward to the peer's
1013 // certificate. At each level signatures and issuer attributes are
1014 // checked. Whenever a verification error is found, the error number is
1015 // stored in x509_ctx and VerifyCallback is called with preverify_ok=0.
1016 // By applying X509_CTX_store_* functions VerifyCallback can locate the
1017 // certificate in question and perform additional steps (see EXAMPLES).
1018 // If no error is found for a certificate, VerifyCallback is called
1019 // with preverify_ok=1 before advancing to the next level.
1021 // The return value of VerifyCallback controls the strategy of the
1022 // further verification process. If VerifyCallback returns 0, the
1023 // verification process is immediately stopped with "verification
1024 // failed" state. If SSL_VERIFY_PEER is set, a verification failure
1025 // alert is sent to the peer and the TLS/SSL handshake is terminated. If
1026 // VerifyCallback returns 1, the verification process is continued. If
1027 // VerifyCallback always returns 1, the TLS/SSL handshake will not be
1028 // terminated with respect to verification failures and the connection
1029 // will be established. The calling process can however retrieve the
1030 // error code of the last verification error using
1031 // SSL_get_verify_result(3) or by maintaining its own error storage
1032 // managed by VerifyCallback.
1034 // If no VerifyCallback is specified, the default callback will be
1035 // used. Its return value is identical to preverify_ok, so that any
1036 // verification failure will lead to a termination of the TLS/SSL
1037 // handshake with an alert message, if SSL_VERIFY_PEER is set.
1039 // Since we cannot perform I/O quickly enough in this callback, we ignore
1040 // all preverify_ok errors and let the handshake continue. It is
1041 // imparative that the user use Connection::VerifyError after the
1042 // 'secure' callback has been made.
1046 #ifdef OPENSSL_NPN_NEGOTIATED
1048 int Connection::AdvertiseNextProtoCallback_(SSL *s,
1049 const unsigned char** data,
1053 Connection *p = static_cast<Connection*>(SSL_get_app_data(s));
1055 if (p->npnProtos_.IsEmpty()) {
1056 // No initialization - no NPN protocols
1057 *data = reinterpret_cast<const unsigned char*>("");
1060 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(p->npnProtos_));
1061 *len = Buffer::Length(p->npnProtos_);
1064 return SSL_TLSEXT_ERR_OK;
1067 int Connection::SelectNextProtoCallback_(SSL *s,
1068 unsigned char** out, unsigned char* outlen,
1069 const unsigned char* in,
1070 unsigned int inlen, void *arg) {
1071 Connection *p = static_cast<Connection*> SSL_get_app_data(s);
1073 // Release old protocol handler if present
1074 if (!p->selectedNPNProto_.IsEmpty()) {
1075 p->selectedNPNProto_.Dispose();
1078 if (p->npnProtos_.IsEmpty()) {
1079 // We should at least select one protocol
1080 // If server is using NPN
1081 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
1084 // set status unsupported
1085 p->selectedNPNProto_ = Persistent<Value>::New(False(node_isolate));
1087 return SSL_TLSEXT_ERR_OK;
1090 const unsigned char* npnProtos =
1091 reinterpret_cast<const unsigned char*>(Buffer::Data(p->npnProtos_));
1093 int status = SSL_select_next_proto(out, outlen, in, inlen, npnProtos,
1094 Buffer::Length(p->npnProtos_));
1097 case OPENSSL_NPN_UNSUPPORTED:
1098 p->selectedNPNProto_ = Persistent<Value>::New(Null());
1100 case OPENSSL_NPN_NEGOTIATED:
1101 p->selectedNPNProto_ = Persistent<Value>::New(String::New(
1102 reinterpret_cast<const char*>(*out), *outlen
1105 case OPENSSL_NPN_NO_OVERLAP:
1106 p->selectedNPNProto_ = Persistent<Value>::New(False(node_isolate));
1112 return SSL_TLSEXT_ERR_OK;
1116 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1117 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
1120 Connection *p = static_cast<Connection*> SSL_get_app_data(s);
1122 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
1125 if (!p->servername_.IsEmpty()) {
1126 p->servername_.Dispose();
1128 p->servername_ = Persistent<String>::New(String::New(servername));
1130 // Call the SNI callback and use its return value as context
1131 if (!p->sniObject_.IsEmpty()) {
1132 if (!p->sniContext_.IsEmpty()) {
1133 p->sniContext_.Dispose();
1136 // Get callback init args
1137 Local<Value> argv[1] = {*p->servername_};
1140 Local<Value> ret = Local<Value>::New(node_isolate,
1141 MakeCallback(p->sniObject_,
1146 // If ret is SecureContext
1147 if (secure_context_constructor->HasInstance(ret)) {
1148 p->sniContext_ = Persistent<Value>::New(ret);
1149 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(
1150 Local<Object>::Cast(ret));
1151 SSL_set_SSL_CTX(s, sc->ctx_);
1153 return SSL_TLSEXT_ERR_NOACK;
1158 return SSL_TLSEXT_ERR_OK;
1162 Handle<Value> Connection::New(const Arguments& args) {
1165 Connection *p = new Connection();
1166 p->Wrap(args.Holder());
1168 if (args.Length() < 1 || !args[0]->IsObject()) {
1169 return ThrowException(Exception::Error(String::New(
1170 "First argument must be a crypto module Credentials")));
1173 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args[0]->ToObject());
1175 bool is_server = args[1]->BooleanValue();
1177 p->ssl_ = SSL_new(sc->ctx_);
1178 p->bio_read_ = BIO_new(BIO_s_mem());
1179 p->bio_write_ = BIO_new(BIO_s_mem());
1181 SSL_set_app_data(p->ssl_, p);
1183 if (is_server) SSL_set_info_callback(p->ssl_, SSLInfoCallback);
1185 #ifdef OPENSSL_NPN_NEGOTIATED
1187 // Server should advertise NPN protocols
1188 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
1189 AdvertiseNextProtoCallback_,
1192 // Client should select protocol from advertised
1193 // If server supports NPN
1194 SSL_CTX_set_next_proto_select_cb(sc->ctx_,
1195 SelectNextProtoCallback_,
1200 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1202 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
1204 String::Utf8Value servername(args[2]);
1205 SSL_set_tlsext_host_name(p->ssl_, *servername);
1209 SSL_set_bio(p->ssl_, p->bio_read_, p->bio_write_);
1211 #ifdef SSL_MODE_RELEASE_BUFFERS
1212 long mode = SSL_get_mode(p->ssl_);
1213 SSL_set_mode(p->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
1219 bool request_cert = args[2]->BooleanValue();
1220 if (!request_cert) {
1221 // Note reject_unauthorized ignored.
1222 verify_mode = SSL_VERIFY_NONE;
1224 bool reject_unauthorized = args[3]->BooleanValue();
1225 verify_mode = SSL_VERIFY_PEER;
1226 if (reject_unauthorized) verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1229 // Note request_cert and reject_unauthorized are ignored for clients.
1230 verify_mode = SSL_VERIFY_NONE;
1234 // Always allow a connection. We'll reject in javascript.
1235 SSL_set_verify(p->ssl_, verify_mode, VerifyCallback);
1237 if ((p->is_server_ = is_server)) {
1238 SSL_set_accept_state(p->ssl_);
1240 SSL_set_connect_state(p->ssl_);
1247 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
1248 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
1249 // a non-const SSL* in OpenSSL <= 0.9.7e.
1250 SSL* ssl = const_cast<SSL*>(ssl_);
1251 if (where & SSL_CB_HANDSHAKE_START) {
1253 Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl));
1254 if (onhandshakestart_sym.IsEmpty()) {
1255 onhandshakestart_sym = NODE_PSYMBOL("onhandshakestart");
1257 MakeCallback(c->handle_, onhandshakestart_sym, 0, NULL);
1259 if (where & SSL_CB_HANDSHAKE_DONE) {
1261 Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl));
1262 if (onhandshakedone_sym.IsEmpty()) {
1263 onhandshakedone_sym = NODE_PSYMBOL("onhandshakedone");
1265 MakeCallback(c->handle_, onhandshakedone_sym, 0, NULL);
1270 Handle<Value> Connection::EncIn(const Arguments& args) {
1273 Connection *ss = Connection::Unwrap(args);
1275 if (args.Length() < 3) {
1276 return ThrowException(Exception::TypeError(
1277 String::New("Takes 3 parameters")));
1280 if (!Buffer::HasInstance(args[0])) {
1281 return ThrowException(Exception::TypeError(
1282 String::New("Second argument should be a buffer")));
1285 char* buffer_data = Buffer::Data(args[0]);
1286 size_t buffer_length = Buffer::Length(args[0]);
1288 size_t off = args[1]->Int32Value();
1289 if (off >= buffer_length) {
1290 return ThrowException(Exception::Error(
1291 String::New("Offset is out of bounds")));
1294 size_t len = args[2]->Int32Value();
1295 if (off + len > buffer_length) {
1296 return ThrowException(Exception::Error(
1297 String::New("off + len > buffer.length")));
1301 char* data = buffer_data + off;
1303 if (ss->is_server_ && !ss->hello_parser_.ended()) {
1304 bytes_written = ss->hello_parser_.Write(reinterpret_cast<uint8_t*>(data),
1307 bytes_written = BIO_write(ss->bio_read_, data, len);
1308 ss->HandleBIOError(ss->bio_read_, "BIO_write", bytes_written);
1309 ss->SetShutdownFlags();
1312 return scope.Close(Integer::New(bytes_written, node_isolate));
1316 Handle<Value> Connection::ClearOut(const Arguments& args) {
1319 Connection *ss = Connection::Unwrap(args);
1321 if (args.Length() < 3) {
1322 return ThrowException(Exception::TypeError(
1323 String::New("Takes 3 parameters")));
1326 if (!Buffer::HasInstance(args[0])) {
1327 return ThrowException(Exception::TypeError(
1328 String::New("Second argument should be a buffer")));
1331 char* buffer_data = Buffer::Data(args[0]);
1332 size_t buffer_length = Buffer::Length(args[0]);
1334 size_t off = args[1]->Int32Value();
1335 if (off >= buffer_length) {
1336 return ThrowException(Exception::Error(
1337 String::New("Offset is out of bounds")));
1340 size_t len = args[2]->Int32Value();
1341 if (off + len > buffer_length) {
1342 return ThrowException(Exception::Error(
1343 String::New("off + len > buffer.length")));
1346 if (!SSL_is_init_finished(ss->ssl_)) {
1349 if (ss->is_server_) {
1350 rv = SSL_accept(ss->ssl_);
1351 ss->HandleSSLError("SSL_accept:ClearOut", rv, kZeroIsAnError);
1353 rv = SSL_connect(ss->ssl_);
1354 ss->HandleSSLError("SSL_connect:ClearOut", rv, kZeroIsAnError);
1357 if (rv < 0) return scope.Close(Integer::New(rv, node_isolate));
1360 int bytes_read = SSL_read(ss->ssl_, buffer_data + off, len);
1361 ss->HandleSSLError("SSL_read:ClearOut", bytes_read, kZeroIsNotAnError);
1362 ss->SetShutdownFlags();
1364 return scope.Close(Integer::New(bytes_read, node_isolate));
1368 Handle<Value> Connection::ClearPending(const Arguments& args) {
1371 Connection *ss = Connection::Unwrap(args);
1373 int bytes_pending = BIO_pending(ss->bio_read_);
1374 return scope.Close(Integer::New(bytes_pending, node_isolate));
1378 Handle<Value> Connection::EncPending(const Arguments& args) {
1381 Connection *ss = Connection::Unwrap(args);
1383 int bytes_pending = BIO_pending(ss->bio_write_);
1384 return scope.Close(Integer::New(bytes_pending, node_isolate));
1388 Handle<Value> Connection::EncOut(const Arguments& args) {
1391 Connection *ss = Connection::Unwrap(args);
1393 if (args.Length() < 3) {
1394 return ThrowException(Exception::TypeError(
1395 String::New("Takes 3 parameters")));
1398 if (!Buffer::HasInstance(args[0])) {
1399 return ThrowException(Exception::TypeError(
1400 String::New("Second argument should be a buffer")));
1403 char* buffer_data = Buffer::Data(args[0]);
1404 size_t buffer_length = Buffer::Length(args[0]);
1406 size_t off = args[1]->Int32Value();
1407 if (off >= buffer_length) {
1408 return ThrowException(Exception::Error(
1409 String::New("Offset is out of bounds")));
1412 size_t len = args[2]->Int32Value();
1413 if (off + len > buffer_length) {
1414 return ThrowException(Exception::Error(
1415 String::New("off + len > buffer.length")));
1418 int bytes_read = BIO_read(ss->bio_write_, buffer_data + off, len);
1420 ss->HandleBIOError(ss->bio_write_, "BIO_read:EncOut", bytes_read);
1421 ss->SetShutdownFlags();
1423 return scope.Close(Integer::New(bytes_read, node_isolate));
1427 Handle<Value> Connection::ClearIn(const Arguments& args) {
1430 Connection *ss = Connection::Unwrap(args);
1432 if (args.Length() < 3) {
1433 return ThrowException(Exception::TypeError(
1434 String::New("Takes 3 parameters")));
1437 if (!Buffer::HasInstance(args[0])) {
1438 return ThrowException(Exception::TypeError(
1439 String::New("Second argument should be a buffer")));
1442 char* buffer_data = Buffer::Data(args[0]);
1443 size_t buffer_length = Buffer::Length(args[0]);
1445 size_t off = args[1]->Int32Value();
1446 if (off > buffer_length) {
1447 return ThrowException(Exception::Error(
1448 String::New("Offset is out of bounds")));
1451 size_t len = args[2]->Int32Value();
1452 if (off + len > buffer_length) {
1453 return ThrowException(Exception::Error(
1454 String::New("off + len > buffer.length")));
1457 if (!SSL_is_init_finished(ss->ssl_)) {
1459 if (ss->is_server_) {
1460 rv = SSL_accept(ss->ssl_);
1461 ss->HandleSSLError("SSL_accept:ClearIn", rv, kZeroIsAnError);
1463 rv = SSL_connect(ss->ssl_);
1464 ss->HandleSSLError("SSL_connect:ClearIn", rv, kZeroIsAnError);
1467 if (rv < 0) return scope.Close(Integer::New(rv, node_isolate));
1470 int bytes_written = SSL_write(ss->ssl_, buffer_data + off, len);
1472 ss->HandleSSLError("SSL_write:ClearIn", bytes_written, kZeroIsAnError);
1473 ss->SetShutdownFlags();
1475 return scope.Close(Integer::New(bytes_written, node_isolate));
1479 Handle<Value> Connection::GetPeerCertificate(const Arguments& args) {
1482 Connection *ss = Connection::Unwrap(args);
1484 if (ss->ssl_ == NULL) return Undefined();
1485 Local<Object> info = Object::New();
1486 X509* peer_cert = SSL_get_peer_certificate(ss->ssl_);
1487 if (peer_cert != NULL) {
1488 BIO* bio = BIO_new(BIO_s_mem());
1490 if (X509_NAME_print_ex(bio, X509_get_subject_name(peer_cert), 0,
1491 X509_NAME_FLAGS) > 0) {
1492 BIO_get_mem_ptr(bio, &mem);
1493 info->Set(subject_symbol, String::New(mem->data, mem->length));
1495 (void) BIO_reset(bio);
1497 if (X509_NAME_print_ex(bio, X509_get_issuer_name(peer_cert), 0,
1498 X509_NAME_FLAGS) > 0) {
1499 BIO_get_mem_ptr(bio, &mem);
1500 info->Set(issuer_symbol, String::New(mem->data, mem->length));
1502 (void) BIO_reset(bio);
1504 int index = X509_get_ext_by_NID(peer_cert, NID_subject_alt_name, -1);
1506 X509_EXTENSION* ext;
1509 ext = X509_get_ext(peer_cert, index);
1510 assert(ext != NULL);
1512 rv = X509V3_EXT_print(bio, ext, 0, 0);
1515 BIO_get_mem_ptr(bio, &mem);
1516 info->Set(subjectaltname_symbol, String::New(mem->data, mem->length));
1518 (void) BIO_reset(bio);
1521 EVP_PKEY *pkey = NULL;
1523 if( NULL != (pkey = X509_get_pubkey(peer_cert))
1524 && NULL != (rsa = EVP_PKEY_get1_RSA(pkey)) ) {
1525 BN_print(bio, rsa->n);
1526 BIO_get_mem_ptr(bio, &mem);
1527 info->Set(modulus_symbol, String::New(mem->data, mem->length) );
1528 (void) BIO_reset(bio);
1530 BN_print(bio, rsa->e);
1531 BIO_get_mem_ptr(bio, &mem);
1532 info->Set(exponent_symbol, String::New(mem->data, mem->length) );
1533 (void) BIO_reset(bio);
1537 EVP_PKEY_free(pkey);
1545 ASN1_TIME_print(bio, X509_get_notBefore(peer_cert));
1546 BIO_get_mem_ptr(bio, &mem);
1547 info->Set(valid_from_symbol, String::New(mem->data, mem->length));
1548 (void) BIO_reset(bio);
1550 ASN1_TIME_print(bio, X509_get_notAfter(peer_cert));
1551 BIO_get_mem_ptr(bio, &mem);
1552 info->Set(valid_to_symbol, String::New(mem->data, mem->length));
1555 unsigned int md_size, i;
1556 unsigned char md[EVP_MAX_MD_SIZE];
1557 if (X509_digest(peer_cert, EVP_sha1(), md, &md_size)) {
1558 const char hex[] = "0123456789ABCDEF";
1559 char fingerprint[EVP_MAX_MD_SIZE * 3];
1561 for (i=0; i<md_size; i++) {
1562 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1563 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1564 fingerprint[(3*i)+2] = ':';
1568 fingerprint[(3*(md_size-1))+2] = '\0';
1571 fingerprint[0] = '\0';
1574 info->Set(fingerprint_symbol, String::New(fingerprint));
1577 STACK_OF(ASN1_OBJECT) *eku = (STACK_OF(ASN1_OBJECT) *)X509_get_ext_d2i(
1578 peer_cert, NID_ext_key_usage, NULL, NULL);
1580 Local<Array> ext_key_usage = Array::New();
1583 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1584 memset(buf, 0, sizeof(buf));
1585 OBJ_obj2txt(buf, sizeof(buf) - 1, sk_ASN1_OBJECT_value(eku, i), 1);
1586 ext_key_usage->Set(Integer::New(i, node_isolate), String::New(buf));
1589 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1590 info->Set(ext_key_usage_symbol, ext_key_usage);
1593 X509_free(peer_cert);
1595 return scope.Close(info);
1598 Handle<Value> Connection::GetSession(const Arguments& args) {
1601 Connection *ss = Connection::Unwrap(args);
1603 if (ss->ssl_ == NULL) return Undefined();
1605 SSL_SESSION* sess = SSL_get_session(ss->ssl_);
1606 if (!sess) return Undefined();
1608 int slen = i2d_SSL_SESSION(sess, NULL);
1612 unsigned char* sbuf = new unsigned char[slen];
1613 unsigned char* p = sbuf;
1614 i2d_SSL_SESSION(sess, &p);
1615 Local<Value> s = Encode(sbuf, slen, BINARY);
1617 return scope.Close(s);
1623 Handle<Value> Connection::SetSession(const Arguments& args) {
1626 Connection *ss = Connection::Unwrap(args);
1628 if (args.Length() < 1 ||
1629 (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
1630 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
1631 return ThrowException(exception);
1634 ASSERT_IS_BUFFER(args[0]);
1635 ssize_t slen = Buffer::Length(args[0]);
1638 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
1639 return ThrowException(exception);
1642 char* sbuf = new char[slen];
1644 ssize_t wlen = DecodeWrite(sbuf, slen, args[0], BINARY);
1645 assert(wlen == slen);
1647 const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
1648 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, wlen);
1655 int r = SSL_set_session(ss->ssl_, sess);
1656 SSL_SESSION_free(sess);
1659 Local<String> eStr = String::New("SSL_set_session error");
1660 return ThrowException(Exception::Error(eStr));
1663 return True(node_isolate);
1666 Handle<Value> Connection::LoadSession(const Arguments& args) {
1669 Connection *ss = Connection::Unwrap(args);
1671 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1672 ssize_t slen = Buffer::Length(args[0].As<Object>());
1673 char* sbuf = Buffer::Data(args[0].As<Object>());
1675 const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1676 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, slen);
1678 // Setup next session and move hello to the BIO buffer
1679 if (ss->next_sess_ != NULL) {
1680 SSL_SESSION_free(ss->next_sess_);
1682 ss->next_sess_ = sess;
1685 ss->hello_parser_.Finish();
1687 return True(node_isolate);
1690 Handle<Value> Connection::IsSessionReused(const Arguments& args) {
1693 Connection *ss = Connection::Unwrap(args);
1695 if (ss->ssl_ == NULL || SSL_session_reused(ss->ssl_) == false) {
1696 return False(node_isolate);
1699 return True(node_isolate);
1703 Handle<Value> Connection::Start(const Arguments& args) {
1706 Connection *ss = Connection::Unwrap(args);
1708 if (!SSL_is_init_finished(ss->ssl_)) {
1710 if (ss->is_server_) {
1711 rv = SSL_accept(ss->ssl_);
1712 ss->HandleSSLError("SSL_accept:Start", rv, kZeroIsAnError);
1714 rv = SSL_connect(ss->ssl_);
1715 ss->HandleSSLError("SSL_connect:Start", rv, kZeroIsAnError);
1718 return scope.Close(Integer::New(rv, node_isolate));
1721 return scope.Close(Integer::New(0, node_isolate));
1725 Handle<Value> Connection::Shutdown(const Arguments& args) {
1728 Connection *ss = Connection::Unwrap(args);
1730 if (ss->ssl_ == NULL) return False(node_isolate);
1731 int rv = SSL_shutdown(ss->ssl_);
1732 ss->HandleSSLError("SSL_shutdown", rv, kZeroIsNotAnError);
1733 ss->SetShutdownFlags();
1735 return scope.Close(Integer::New(rv, node_isolate));
1739 Handle<Value> Connection::ReceivedShutdown(const Arguments& args) {
1742 Connection *ss = Connection::Unwrap(args);
1744 if (ss->ssl_ == NULL) return False(node_isolate);
1745 int r = SSL_get_shutdown(ss->ssl_);
1747 if (r & SSL_RECEIVED_SHUTDOWN) return True(node_isolate);
1749 return False(node_isolate);
1753 Handle<Value> Connection::IsInitFinished(const Arguments& args) {
1756 Connection *ss = Connection::Unwrap(args);
1758 if (ss->ssl_ == NULL || SSL_is_init_finished(ss->ssl_) == false) {
1759 return False(node_isolate);
1762 return True(node_isolate);
1766 Handle<Value> Connection::VerifyError(const Arguments& args) {
1769 Connection *ss = Connection::Unwrap(args);
1771 if (ss->ssl_ == NULL) return Null();
1774 // XXX Do this check in JS land?
1775 X509* peer_cert = SSL_get_peer_certificate(ss->ssl_);
1776 if (peer_cert == NULL) {
1777 // We requested a certificate and they did not send us one.
1778 // Definitely an error.
1779 // XXX is this the right error message?
1780 return scope.Close(Exception::Error(
1781 String::New("UNABLE_TO_GET_ISSUER_CERT")));
1783 X509_free(peer_cert);
1786 long x509_verify_error = SSL_get_verify_result(ss->ssl_);
1790 switch (x509_verify_error) {
1794 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1795 s = String::New("UNABLE_TO_GET_ISSUER_CERT");
1798 case X509_V_ERR_UNABLE_TO_GET_CRL:
1799 s = String::New("UNABLE_TO_GET_CRL");
1802 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1803 s = String::New("UNABLE_TO_DECRYPT_CERT_SIGNATURE");
1806 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1807 s = String::New("UNABLE_TO_DECRYPT_CRL_SIGNATURE");
1810 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1811 s = String::New("UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY");
1814 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1815 s = String::New("CERT_SIGNATURE_FAILURE");
1818 case X509_V_ERR_CRL_SIGNATURE_FAILURE:
1819 s = String::New("CRL_SIGNATURE_FAILURE");
1822 case X509_V_ERR_CERT_NOT_YET_VALID:
1823 s = String::New("CERT_NOT_YET_VALID");
1826 case X509_V_ERR_CERT_HAS_EXPIRED:
1827 s = String::New("CERT_HAS_EXPIRED");
1830 case X509_V_ERR_CRL_NOT_YET_VALID:
1831 s = String::New("CRL_NOT_YET_VALID");
1834 case X509_V_ERR_CRL_HAS_EXPIRED:
1835 s = String::New("CRL_HAS_EXPIRED");
1838 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1839 s = String::New("ERROR_IN_CERT_NOT_BEFORE_FIELD");
1842 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1843 s = String::New("ERROR_IN_CERT_NOT_AFTER_FIELD");
1846 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1847 s = String::New("ERROR_IN_CRL_LAST_UPDATE_FIELD");
1850 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1851 s = String::New("ERROR_IN_CRL_NEXT_UPDATE_FIELD");
1854 case X509_V_ERR_OUT_OF_MEM:
1855 s = String::New("OUT_OF_MEM");
1858 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1859 s = String::New("DEPTH_ZERO_SELF_SIGNED_CERT");
1862 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1863 s = String::New("SELF_SIGNED_CERT_IN_CHAIN");
1866 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1867 s = String::New("UNABLE_TO_GET_ISSUER_CERT_LOCALLY");
1870 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1871 s = String::New("UNABLE_TO_VERIFY_LEAF_SIGNATURE");
1874 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1875 s = String::New("CERT_CHAIN_TOO_LONG");
1878 case X509_V_ERR_CERT_REVOKED:
1879 s = String::New("CERT_REVOKED");
1882 case X509_V_ERR_INVALID_CA:
1883 s = String::New("INVALID_CA");
1886 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1887 s = String::New("PATH_LENGTH_EXCEEDED");
1890 case X509_V_ERR_INVALID_PURPOSE:
1891 s = String::New("INVALID_PURPOSE");
1894 case X509_V_ERR_CERT_UNTRUSTED:
1895 s = String::New("CERT_UNTRUSTED");
1898 case X509_V_ERR_CERT_REJECTED:
1899 s = String::New("CERT_REJECTED");
1903 s = String::New(X509_verify_cert_error_string(x509_verify_error));
1907 return scope.Close(Exception::Error(s));
1911 Handle<Value> Connection::GetCurrentCipher(const Arguments& args) {
1914 Connection *ss = Connection::Unwrap(args);
1916 OPENSSL_CONST SSL_CIPHER *c;
1918 if ( ss->ssl_ == NULL ) return Undefined();
1919 c = SSL_get_current_cipher(ss->ssl_);
1920 if ( c == NULL ) return Undefined();
1921 Local<Object> info = Object::New();
1922 const char* cipher_name = SSL_CIPHER_get_name(c);
1923 info->Set(name_symbol, String::New(cipher_name));
1924 const char* cipher_version = SSL_CIPHER_get_version(c);
1925 info->Set(version_symbol, String::New(cipher_version));
1926 return scope.Close(info);
1929 Handle<Value> Connection::Close(const Arguments& args) {
1932 Connection *ss = Connection::Unwrap(args);
1934 if (ss->ssl_ != NULL) {
1938 return True(node_isolate);
1941 #ifdef OPENSSL_NPN_NEGOTIATED
1942 Handle<Value> Connection::GetNegotiatedProto(const Arguments& args) {
1945 Connection *ss = Connection::Unwrap(args);
1947 if (ss->is_server_) {
1948 const unsigned char* npn_proto;
1949 unsigned int npn_proto_len;
1951 SSL_get0_next_proto_negotiated(ss->ssl_, &npn_proto, &npn_proto_len);
1954 return False(node_isolate);
1957 return String::New((const char*) npn_proto, npn_proto_len);
1959 return ss->selectedNPNProto_;
1963 Handle<Value> Connection::SetNPNProtocols(const Arguments& args) {
1966 Connection *ss = Connection::Unwrap(args);
1968 if (args.Length() < 1 || !Buffer::HasInstance(args[0])) {
1969 return ThrowException(Exception::Error(String::New(
1970 "Must give a Buffer as first argument")));
1973 // Release old handle
1974 if (!ss->npnProtos_.IsEmpty()) {
1975 ss->npnProtos_.Dispose();
1977 ss->npnProtos_ = Persistent<Object>::New(args[0]->ToObject());
1979 return True(node_isolate);
1983 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1984 Handle<Value> Connection::GetServername(const Arguments& args) {
1987 Connection *ss = Connection::Unwrap(args);
1989 if (ss->is_server_ && !ss->servername_.IsEmpty()) {
1990 return ss->servername_;
1992 return False(node_isolate);
1996 Handle<Value> Connection::SetSNICallback(const Arguments& args) {
1999 Connection *ss = Connection::Unwrap(args);
2001 if (args.Length() < 1 || !args[0]->IsFunction()) {
2002 return ThrowException(Exception::Error(String::New(
2003 "Must give a Function as first argument")));
2006 // Release old handle
2007 if (!ss->sniObject_.IsEmpty()) {
2008 ss->sniObject_.Dispose();
2010 ss->sniObject_ = Persistent<Object>::New(Object::New());
2011 ss->sniObject_->Set(String::New("onselect"), args[0]);
2013 return True(node_isolate);
2018 class Cipher : public ObjectWrap {
2020 static void Initialize (v8::Handle<v8::Object> target) {
2023 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2025 t->InstanceTemplate()->SetInternalFieldCount(1);
2027 NODE_SET_PROTOTYPE_METHOD(t, "init", CipherInit);
2028 NODE_SET_PROTOTYPE_METHOD(t, "initiv", CipherInitIv);
2029 NODE_SET_PROTOTYPE_METHOD(t, "update", CipherUpdate);
2030 NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
2031 NODE_SET_PROTOTYPE_METHOD(t, "final", CipherFinal);
2033 target->Set(String::NewSymbol("Cipher"), t->GetFunction());
2037 bool CipherInit(char* cipherType, char* key_buf, int key_buf_len) {
2038 cipher = EVP_get_cipherbyname(cipherType);
2040 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2044 unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
2045 int key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL,
2046 (unsigned char*) key_buf, key_buf_len, 1, key, iv);
2048 EVP_CIPHER_CTX_init(&ctx);
2049 EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, NULL, true);
2050 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2051 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2052 EVP_CIPHER_CTX_cleanup(&ctx);
2055 EVP_CipherInit_ex(&ctx, NULL, NULL,
2056 (unsigned char*)key,
2057 (unsigned char*)iv, true);
2058 initialised_ = true;
2063 bool CipherInitIv(char* cipherType,
2068 cipher = EVP_get_cipherbyname(cipherType);
2070 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2073 /* OpenSSL versions up to 0.9.8l failed to return the correct
2074 iv_length (0) for ECB ciphers */
2075 if (EVP_CIPHER_iv_length(cipher) != iv_len &&
2076 !(EVP_CIPHER_mode(cipher) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2077 fprintf(stderr, "node-crypto : Invalid IV length %d\n", iv_len);
2080 EVP_CIPHER_CTX_init(&ctx);
2081 EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, NULL, true);
2082 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2083 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2084 EVP_CIPHER_CTX_cleanup(&ctx);
2087 EVP_CipherInit_ex(&ctx, NULL, NULL,
2088 (unsigned char*)key,
2089 (unsigned char*)iv, true);
2090 initialised_ = true;
2094 int CipherUpdate(char* data, int len, unsigned char** out, int* out_len) {
2095 if (!initialised_) return 0;
2096 *out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
2097 *out= new unsigned char[*out_len];
2099 EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
2103 int SetAutoPadding(bool auto_padding) {
2104 if (!initialised_) return 0;
2105 return EVP_CIPHER_CTX_set_padding(&ctx, auto_padding ? 1 : 0);
2108 int CipherFinal(unsigned char** out, int *out_len) {
2109 if (!initialised_) return 0;
2110 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx)];
2111 int r = EVP_CipherFinal_ex(&ctx,*out, out_len);
2112 EVP_CIPHER_CTX_cleanup(&ctx);
2113 initialised_ = false;
2120 static Handle<Value> New(const Arguments& args) {
2123 Cipher *cipher = new Cipher();
2124 cipher->Wrap(args.This());
2128 static Handle<Value> CipherInit(const Arguments& args) {
2131 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2133 if (args.Length() <= 1
2134 || !args[0]->IsString()
2135 || !(args[1]->IsString() || Buffer::HasInstance(args[1])))
2137 return ThrowException(Exception::Error(String::New(
2138 "Must give cipher-type, key")));
2141 ASSERT_IS_BUFFER(args[1]);
2142 ssize_t key_buf_len = Buffer::Length(args[1]);
2144 if (key_buf_len < 0) {
2145 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2146 return ThrowException(exception);
2149 char* key_buf = new char[key_buf_len];
2150 ssize_t key_written = DecodeWrite(key_buf, key_buf_len, args[1], BINARY);
2151 assert(key_written == key_buf_len);
2153 String::Utf8Value cipherType(args[0]);
2155 bool r = cipher->CipherInit(*cipherType, key_buf, key_buf_len);
2160 return ThrowException(Exception::Error(String::New("CipherInit error")));
2167 static Handle<Value> CipherInitIv(const Arguments& args) {
2168 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2173 if (args.Length() <= 2
2174 || !args[0]->IsString()
2175 || !(args[1]->IsString() || Buffer::HasInstance(args[1]))
2176 || !(args[2]->IsString() || Buffer::HasInstance(args[2])))
2178 return ThrowException(Exception::Error(String::New(
2179 "Must give cipher-type, key, and iv as argument")));
2182 ASSERT_IS_BUFFER(args[1]);
2183 ssize_t key_len = Buffer::Length(args[1]);
2186 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2187 return ThrowException(exception);
2190 ASSERT_IS_BUFFER(args[2]);
2191 ssize_t iv_len = Buffer::Length(args[2]);
2194 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2195 return ThrowException(exception);
2198 char* key_buf = new char[key_len];
2199 ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY);
2200 assert(key_written == key_len);
2202 char* iv_buf = new char[iv_len];
2203 ssize_t iv_written = DecodeWrite(iv_buf, iv_len, args[2], BINARY);
2204 assert(iv_written == iv_len);
2206 String::Utf8Value cipherType(args[0]);
2208 bool r = cipher->CipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
2214 return ThrowException(Exception::Error(String::New("CipherInitIv error")));
2220 static Handle<Value> CipherUpdate(const Arguments& args) {
2221 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2225 ASSERT_IS_BUFFER(args[0]);
2227 unsigned char* out=0;
2229 char* buffer_data = Buffer::Data(args[0]);
2230 size_t buffer_length = Buffer::Length(args[0]);
2232 r = cipher->CipherUpdate(buffer_data, buffer_length, &out, &out_len);
2236 Local<Value> exception = Exception::TypeError(String::New("DecipherUpdate fail"));
2237 return ThrowException(exception);
2240 Local<Value> outString;
2241 outString = Encode(out, out_len, BUFFER);
2243 if (out) delete [] out;
2245 return scope.Close(outString);
2248 static Handle<Value> SetAutoPadding(const Arguments& args) {
2250 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2252 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2257 static Handle<Value> CipherFinal(const Arguments& args) {
2258 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2262 unsigned char* out_value = NULL;
2264 Local<Value> outString ;
2266 int r = cipher->CipherFinal(&out_value, &out_len);
2268 assert(out_value != NULL);
2269 assert(out_len != -1 || r == 0);
2271 if (out_len == 0 || r == 0) {
2272 // out_value always get allocated.
2276 Local<Value> exception = Exception::TypeError(
2277 String::New("CipherFinal fail"));
2278 return ThrowException(exception);
2282 outString = Encode(out_value, out_len, BUFFER);
2284 delete [] out_value;
2285 return scope.Close(outString);
2288 Cipher () : ObjectWrap ()
2290 initialised_ = false;
2295 EVP_CIPHER_CTX_cleanup(&ctx);
2301 EVP_CIPHER_CTX ctx; /* coverity[member_decl] */
2302 const EVP_CIPHER *cipher; /* coverity[member_decl] */
2308 class Decipher : public ObjectWrap {
2311 Initialize (v8::Handle<v8::Object> target)
2315 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2317 t->InstanceTemplate()->SetInternalFieldCount(1);
2319 NODE_SET_PROTOTYPE_METHOD(t, "init", DecipherInit);
2320 NODE_SET_PROTOTYPE_METHOD(t, "initiv", DecipherInitIv);
2321 NODE_SET_PROTOTYPE_METHOD(t, "update", DecipherUpdate);
2322 NODE_SET_PROTOTYPE_METHOD(t, "final", DecipherFinal);
2323 NODE_SET_PROTOTYPE_METHOD(t, "finaltol", DecipherFinal); // remove someday
2324 NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
2326 target->Set(String::NewSymbol("Decipher"), t->GetFunction());
2329 bool DecipherInit(char* cipherType, char* key_buf, int key_buf_len) {
2330 cipher_ = EVP_get_cipherbyname(cipherType);
2333 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2337 unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
2338 int key_len = EVP_BytesToKey(cipher_,
2341 (unsigned char*)(key_buf),
2347 EVP_CIPHER_CTX_init(&ctx);
2348 EVP_CipherInit_ex(&ctx, cipher_, NULL, NULL, NULL, false);
2349 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2350 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2351 EVP_CIPHER_CTX_cleanup(&ctx);
2354 EVP_CipherInit_ex(&ctx, NULL, NULL,
2355 (unsigned char*)key,
2356 (unsigned char*)iv, false);
2357 initialised_ = true;
2362 bool DecipherInitIv(char* cipherType,
2367 cipher_ = EVP_get_cipherbyname(cipherType);
2369 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2372 /* OpenSSL versions up to 0.9.8l failed to return the correct
2373 iv_length (0) for ECB ciphers */
2374 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
2375 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2376 fprintf(stderr, "node-crypto : Invalid IV length %d\n", iv_len);
2379 EVP_CIPHER_CTX_init(&ctx);
2380 EVP_CipherInit_ex(&ctx, cipher_, NULL, NULL, NULL, false);
2381 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2382 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2383 EVP_CIPHER_CTX_cleanup(&ctx);
2386 EVP_CipherInit_ex(&ctx, NULL, NULL,
2387 (unsigned char*)key,
2388 (unsigned char*)iv, false);
2389 initialised_ = true;
2393 int DecipherUpdate(char* data, int len, unsigned char** out, int* out_len) {
2394 if (!initialised_) {
2400 *out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
2401 *out= new unsigned char[*out_len];
2403 EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
2407 int SetAutoPadding(bool auto_padding) {
2408 if (!initialised_) return 0;
2409 return EVP_CIPHER_CTX_set_padding(&ctx, auto_padding ? 1 : 0);
2412 // coverity[alloc_arg]
2413 int DecipherFinal(unsigned char** out, int *out_len) {
2416 if (!initialised_) {
2422 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx)];
2423 r = EVP_CipherFinal_ex(&ctx,*out,out_len);
2424 EVP_CIPHER_CTX_cleanup(&ctx);
2425 initialised_ = false;
2432 static Handle<Value> New (const Arguments& args) {
2435 Decipher *cipher = new Decipher();
2436 cipher->Wrap(args.This());
2440 static Handle<Value> DecipherInit(const Arguments& args) {
2441 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2445 if (args.Length() <= 1
2446 || !args[0]->IsString()
2447 || !(args[1]->IsString() || Buffer::HasInstance(args[1])))
2449 return ThrowException(Exception::Error(String::New(
2450 "Must give cipher-type, key as argument")));
2453 ASSERT_IS_BUFFER(args[1]);
2454 ssize_t key_len = Buffer::Length(args[1]);
2457 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2458 return ThrowException(exception);
2461 char* key_buf = new char[key_len];
2462 ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY);
2463 assert(key_written == key_len);
2465 String::Utf8Value cipherType(args[0]);
2467 bool r = cipher->DecipherInit(*cipherType, key_buf,key_len);
2472 return ThrowException(Exception::Error(String::New("DecipherInit error")));
2478 static Handle<Value> DecipherInitIv(const Arguments& args) {
2479 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2483 if (args.Length() <= 2
2484 || !args[0]->IsString()
2485 || !(args[1]->IsString() || Buffer::HasInstance(args[1]))
2486 || !(args[2]->IsString() || Buffer::HasInstance(args[2])))
2488 return ThrowException(Exception::Error(String::New(
2489 "Must give cipher-type, key, and iv as argument")));
2492 ASSERT_IS_BUFFER(args[1]);
2493 ssize_t key_len = Buffer::Length(args[1]);
2496 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2497 return ThrowException(exception);
2500 ASSERT_IS_BUFFER(args[2]);
2501 ssize_t iv_len = Buffer::Length(args[2]);
2504 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2505 return ThrowException(exception);
2508 char* key_buf = new char[key_len];
2509 ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY);
2510 assert(key_written == key_len);
2512 char* iv_buf = new char[iv_len];
2513 ssize_t iv_written = DecodeWrite(iv_buf, iv_len, args[2], BINARY);
2514 assert(iv_written == iv_len);
2516 String::Utf8Value cipherType(args[0]);
2518 bool r = cipher->DecipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
2524 return ThrowException(Exception::Error(String::New("DecipherInitIv error")));
2530 static Handle<Value> DecipherUpdate(const Arguments& args) {
2533 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2535 ASSERT_IS_BUFFER(args[0]);
2540 // if alloc_buf then buf must be deleted later
2541 bool alloc_buf = false;
2542 char* buffer_data = Buffer::Data(args[0]);
2543 size_t buffer_length = Buffer::Length(args[0]);
2546 len = buffer_length;
2548 unsigned char* out=0;
2550 int r = cipher->DecipherUpdate(buf, len, &out, &out_len);
2554 Local<Value> exception = Exception::TypeError(String::New("DecipherUpdate fail"));
2555 return ThrowException(exception);
2558 Local<Value> outString;
2559 outString = Encode(out, out_len, BUFFER);
2561 if (out) delete [] out;
2563 if (alloc_buf) delete [] buf;
2564 return scope.Close(outString);
2568 static Handle<Value> SetAutoPadding(const Arguments& args) {
2570 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2572 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2577 static Handle<Value> DecipherFinal(const Arguments& args) {
2580 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2582 unsigned char* out_value = NULL;
2584 Local<Value> outString;
2586 int r = cipher->DecipherFinal(&out_value, &out_len);
2588 assert(out_value != NULL);
2589 assert(out_len != -1);
2591 if (out_len == 0 || r == 0) {
2592 delete [] out_value; // allocated even if out_len == 0
2595 Local<Value> exception = Exception::TypeError(
2596 String::New("DecipherFinal fail"));
2597 return ThrowException(exception);
2601 outString = Encode(out_value, out_len, BUFFER);
2602 delete [] out_value;
2603 return scope.Close(outString);
2606 Decipher () : ObjectWrap () {
2607 initialised_ = false;
2612 EVP_CIPHER_CTX_cleanup(&ctx);
2619 const EVP_CIPHER *cipher_;
2626 class Hmac : public ObjectWrap {
2628 static void Initialize (v8::Handle<v8::Object> target) {
2631 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2633 t->InstanceTemplate()->SetInternalFieldCount(1);
2635 NODE_SET_PROTOTYPE_METHOD(t, "init", HmacInit);
2636 NODE_SET_PROTOTYPE_METHOD(t, "update", HmacUpdate);
2637 NODE_SET_PROTOTYPE_METHOD(t, "digest", HmacDigest);
2639 target->Set(String::NewSymbol("Hmac"), t->GetFunction());
2642 bool HmacInit(char* hashType, char* key, int key_len) {
2643 md = EVP_get_digestbyname(hashType);
2645 fprintf(stderr, "node-crypto : Unknown message digest %s\n", hashType);
2648 HMAC_CTX_init(&ctx);
2649 HMAC_Init(&ctx, key, key_len, md);
2650 initialised_ = true;
2655 int HmacUpdate(char* data, int len) {
2656 if (!initialised_) return 0;
2657 HMAC_Update(&ctx, (unsigned char*)data, len);
2661 int HmacDigest(unsigned char** md_value, unsigned int *md_len) {
2662 if (!initialised_) return 0;
2663 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
2664 HMAC_Final(&ctx, *md_value, md_len);
2665 HMAC_CTX_cleanup(&ctx);
2666 initialised_ = false;
2673 static Handle<Value> New (const Arguments& args) {
2676 Hmac *hmac = new Hmac();
2677 hmac->Wrap(args.This());
2681 static Handle<Value> HmacInit(const Arguments& args) {
2682 Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());
2686 if (args.Length() == 0 || !args[0]->IsString()) {
2687 return ThrowException(Exception::Error(String::New(
2688 "Must give hashtype string as argument")));
2691 ASSERT_IS_BUFFER(args[1]);
2692 ssize_t len = Buffer::Length(args[1]);
2695 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2696 return ThrowException(exception);
2699 String::Utf8Value hashType(args[0]);
2703 if( Buffer::HasInstance(args[1])) {
2704 char* buffer_data = Buffer::Data(args[1]);
2705 size_t buffer_length = Buffer::Length(args[1]);
2707 r = hmac->HmacInit(*hashType, buffer_data, buffer_length);
2709 char* buf = new char[len];
2710 ssize_t written = DecodeWrite(buf, len, args[1], BINARY);
2711 assert(written == len);
2713 r = hmac->HmacInit(*hashType, buf, len);
2719 return ThrowException(Exception::Error(String::New("hmac error")));
2725 static Handle<Value> HmacUpdate(const Arguments& args) {
2726 Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());
2730 ASSERT_IS_BUFFER(args[0]);
2734 char* buffer_data = Buffer::Data(args[0]);
2735 size_t buffer_length = Buffer::Length(args[0]);
2737 r = hmac->HmacUpdate(buffer_data, buffer_length);
2740 Local<Value> exception = Exception::TypeError(String::New("HmacUpdate fail"));
2741 return ThrowException(exception);
2747 static Handle<Value> HmacDigest(const Arguments& args) {
2748 Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());
2752 unsigned char* md_value = NULL;
2753 unsigned int md_len = 0;
2754 Local<Value> outString;
2756 int r = hmac->HmacDigest(&md_value, &md_len);
2762 outString = Encode(md_value, md_len, BUFFER);
2765 return scope.Close(outString);
2768 Hmac () : ObjectWrap () {
2769 initialised_ = false;
2774 HMAC_CTX_cleanup(&ctx);
2780 HMAC_CTX ctx; /* coverity[member_decl] */
2781 const EVP_MD *md; /* coverity[member_decl] */
2786 class Hash : public ObjectWrap {
2788 static void Initialize (v8::Handle<v8::Object> target) {
2791 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2793 t->InstanceTemplate()->SetInternalFieldCount(1);
2795 NODE_SET_PROTOTYPE_METHOD(t, "update", HashUpdate);
2796 NODE_SET_PROTOTYPE_METHOD(t, "digest", HashDigest);
2798 target->Set(String::NewSymbol("Hash"), t->GetFunction());
2801 bool HashInit (const char* hashType) {
2802 md = EVP_get_digestbyname(hashType);
2803 if(!md) return false;
2804 EVP_MD_CTX_init(&mdctx);
2805 EVP_DigestInit_ex(&mdctx, md, NULL);
2806 initialised_ = true;
2810 int HashUpdate(char* data, int len) {
2811 if (!initialised_) return 0;
2812 EVP_DigestUpdate(&mdctx, data, len);
2819 static Handle<Value> New (const Arguments& args) {
2822 if (args.Length() == 0 || !args[0]->IsString()) {
2823 return ThrowException(Exception::Error(String::New(
2824 "Must give hashtype string as argument")));
2827 String::Utf8Value hashType(args[0]);
2829 Hash *hash = new Hash();
2830 if (!hash->HashInit(*hashType)) {
2832 return ThrowException(Exception::Error(String::New(
2833 "Digest method not supported")));
2836 hash->Wrap(args.This());
2840 static Handle<Value> HashUpdate(const Arguments& args) {
2843 Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
2845 ASSERT_IS_BUFFER(args[0]);
2849 char* buffer_data = Buffer::Data(args[0]);
2850 size_t buffer_length = Buffer::Length(args[0]);
2851 r = hash->HashUpdate(buffer_data, buffer_length);
2854 Local<Value> exception = Exception::TypeError(String::New("HashUpdate fail"));
2855 return ThrowException(exception);
2861 static Handle<Value> HashDigest(const Arguments& args) {
2864 Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
2866 if (!hash->initialised_) {
2867 return ThrowException(Exception::Error(String::New("Not initialized")));
2870 unsigned char md_value[EVP_MAX_MD_SIZE];
2871 unsigned int md_len;
2873 EVP_DigestFinal_ex(&hash->mdctx, md_value, &md_len);
2874 EVP_MD_CTX_cleanup(&hash->mdctx);
2875 hash->initialised_ = false;
2877 Local<Value> outString;
2879 outString = Encode(md_value, md_len, BUFFER);
2881 return scope.Close(outString);
2884 Hash () : ObjectWrap () {
2885 initialised_ = false;
2890 EVP_MD_CTX_cleanup(&mdctx);
2896 EVP_MD_CTX mdctx; /* coverity[member_decl] */
2897 const EVP_MD *md; /* coverity[member_decl] */
2901 class Sign : public ObjectWrap {
2904 Initialize (v8::Handle<v8::Object> target) {
2907 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2909 t->InstanceTemplate()->SetInternalFieldCount(1);
2911 NODE_SET_PROTOTYPE_METHOD(t, "init", SignInit);
2912 NODE_SET_PROTOTYPE_METHOD(t, "update", SignUpdate);
2913 NODE_SET_PROTOTYPE_METHOD(t, "sign", SignFinal);
2915 target->Set(String::NewSymbol("Sign"), t->GetFunction());
2918 bool SignInit (const char* signType) {
2919 md = EVP_get_digestbyname(signType);
2921 printf("Unknown message digest %s\n", signType);
2924 EVP_MD_CTX_init(&mdctx);
2925 EVP_SignInit_ex(&mdctx, md, NULL);
2926 initialised_ = true;
2931 int SignUpdate(char* data, int len) {
2932 if (!initialised_) return 0;
2933 EVP_SignUpdate(&mdctx, data, len);
2937 int SignFinal(unsigned char** md_value,
2938 unsigned int *md_len,
2941 if (!initialised_) return 0;
2945 bp = BIO_new(BIO_s_mem());
2946 if(!BIO_write(bp, key_pem, key_pemLen)) return 0;
2948 pkey = PEM_read_bio_PrivateKey( bp, NULL, NULL, NULL );
2949 if (pkey == NULL) return 0;
2951 EVP_SignFinal(&mdctx, *md_value, md_len, pkey);
2952 EVP_MD_CTX_cleanup(&mdctx);
2953 initialised_ = false;
2954 EVP_PKEY_free(pkey);
2962 static Handle<Value> New (const Arguments& args) {
2965 Sign *sign = new Sign();
2966 sign->Wrap(args.This());
2971 static Handle<Value> SignInit(const Arguments& args) {
2974 Sign *sign = ObjectWrap::Unwrap<Sign>(args.This());
2976 if (args.Length() == 0 || !args[0]->IsString()) {
2977 return ThrowException(Exception::Error(String::New(
2978 "Must give signtype string as argument")));
2981 String::Utf8Value signType(args[0]);
2983 bool r = sign->SignInit(*signType);
2986 return ThrowException(Exception::Error(String::New("SignInit error")));
2992 static Handle<Value> SignUpdate(const Arguments& args) {
2993 Sign *sign = ObjectWrap::Unwrap<Sign>(args.This());
2997 ASSERT_IS_BUFFER(args[0]);
3001 char* buffer_data = Buffer::Data(args[0]);
3002 size_t buffer_length = Buffer::Length(args[0]);
3004 r = sign->SignUpdate(buffer_data, buffer_length);
3007 Local<Value> exception = Exception::TypeError(String::New("SignUpdate fail"));
3008 return ThrowException(exception);
3014 static Handle<Value> SignFinal(const Arguments& args) {
3015 Sign *sign = ObjectWrap::Unwrap<Sign>(args.This());
3019 unsigned char* md_value;
3020 unsigned int md_len;
3021 Local<Value> outString;
3023 md_len = 8192; // Maximum key size is 8192 bits
3024 md_value = new unsigned char[md_len];
3026 ASSERT_IS_BUFFER(args[0]);
3027 ssize_t len = Buffer::Length(args[0]);
3029 char* buf = new char[len];
3030 ssize_t written = DecodeWrite(buf, len, args[0], BUFFER);
3031 assert(written == len);
3033 int r = sign->SignFinal(&md_value, &md_len, buf, len);
3041 outString = Encode(md_value, md_len, BUFFER);
3044 return scope.Close(outString);
3047 Sign () : ObjectWrap () {
3048 initialised_ = false;
3053 EVP_MD_CTX_cleanup(&mdctx);
3059 EVP_MD_CTX mdctx; /* coverity[member_decl] */
3060 const EVP_MD *md; /* coverity[member_decl] */
3064 class Verify : public ObjectWrap {
3066 static void Initialize (v8::Handle<v8::Object> target) {
3069 Local<FunctionTemplate> t = FunctionTemplate::New(New);
3071 t->InstanceTemplate()->SetInternalFieldCount(1);
3073 NODE_SET_PROTOTYPE_METHOD(t, "init", VerifyInit);
3074 NODE_SET_PROTOTYPE_METHOD(t, "update", VerifyUpdate);
3075 NODE_SET_PROTOTYPE_METHOD(t, "verify", VerifyFinal);
3077 target->Set(String::NewSymbol("Verify"), t->GetFunction());
3081 bool VerifyInit (const char* verifyType) {
3082 md = EVP_get_digestbyname(verifyType);
3084 fprintf(stderr, "node-crypto : Unknown message digest %s\n", verifyType);
3087 EVP_MD_CTX_init(&mdctx);
3088 EVP_VerifyInit_ex(&mdctx, md, NULL);
3089 initialised_ = true;
3094 int VerifyUpdate(char* data, int len) {
3095 if (!initialised_) return 0;
3096 EVP_VerifyUpdate(&mdctx, data, len);
3101 int VerifyFinal(char* key_pem, int key_pemLen, unsigned char* sig, int siglen) {
3102 if (!initialised_) return 0;
3104 EVP_PKEY* pkey = NULL;
3109 bp = BIO_new(BIO_s_mem());
3111 ERR_print_errors_fp(stderr);
3114 if(!BIO_write(bp, key_pem, key_pemLen)) {
3115 ERR_print_errors_fp(stderr);
3119 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3120 // Split this out into a separate function once we have more than one
3121 // consumer of public keys.
3122 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3123 pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
3125 ERR_print_errors_fp(stderr);
3128 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3129 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
3131 pkey = EVP_PKEY_new();
3132 if (pkey) EVP_PKEY_set1_RSA(pkey, rsa);
3136 ERR_print_errors_fp(stderr);
3141 x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
3143 ERR_print_errors_fp(stderr);
3147 pkey = X509_get_pubkey(x509);
3149 ERR_print_errors_fp(stderr);
3154 r = EVP_VerifyFinal(&mdctx, sig, siglen, pkey);
3157 EVP_PKEY_free (pkey);
3162 EVP_MD_CTX_cleanup(&mdctx);
3163 initialised_ = false;
3171 static Handle<Value> New (const Arguments& args) {
3174 Verify *verify = new Verify();
3175 verify->Wrap(args.This());
3181 static Handle<Value> VerifyInit(const Arguments& args) {
3182 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
3186 if (args.Length() == 0 || !args[0]->IsString()) {
3187 return ThrowException(Exception::Error(String::New(
3188 "Must give verifytype string as argument")));
3191 String::Utf8Value verifyType(args[0]);
3193 bool r = verify->VerifyInit(*verifyType);
3196 return ThrowException(Exception::Error(String::New("VerifyInit error")));
3203 static Handle<Value> VerifyUpdate(const Arguments& args) {
3206 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
3208 ASSERT_IS_BUFFER(args[0]);
3212 char* buffer_data = Buffer::Data(args[0]);
3213 size_t buffer_length = Buffer::Length(args[0]);
3215 r = verify->VerifyUpdate(buffer_data, buffer_length);
3218 Local<Value> exception = Exception::TypeError(String::New("VerifyUpdate fail"));
3219 return ThrowException(exception);
3226 static Handle<Value> VerifyFinal(const Arguments& args) {
3229 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
3231 ASSERT_IS_BUFFER(args[0]);
3232 ssize_t klen = Buffer::Length(args[0]);
3235 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3236 return ThrowException(exception);
3239 char* kbuf = new char[klen];
3240 ssize_t kwritten = DecodeWrite(kbuf, klen, args[0], BINARY);
3241 assert(kwritten == klen);
3243 ASSERT_IS_BUFFER(args[1]);
3244 ssize_t hlen = Buffer::Length(args[1]);
3248 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3249 return ThrowException(exception);
3252 unsigned char* hbuf = new unsigned char[hlen];
3253 ssize_t hwritten = DecodeWrite((char*)hbuf, hlen, args[1], BINARY);
3254 assert(hwritten == hlen);
3258 r = verify->VerifyFinal(kbuf, klen, hbuf, hlen);
3263 return Boolean::New(r && r != -1);
3266 Verify () : ObjectWrap () {
3267 initialised_ = false;
3272 EVP_MD_CTX_cleanup(&mdctx);
3278 EVP_MD_CTX mdctx; /* coverity[member_decl] */
3279 const EVP_MD *md; /* coverity[member_decl] */
3284 class DiffieHellman : public ObjectWrap {
3286 static void Initialize(v8::Handle<v8::Object> target) {
3289 Local<FunctionTemplate> t = FunctionTemplate::New(New);
3291 t->InstanceTemplate()->SetInternalFieldCount(1);
3293 NODE_SET_PROTOTYPE_METHOD(t, "generateKeys", GenerateKeys);
3294 NODE_SET_PROTOTYPE_METHOD(t, "computeSecret", ComputeSecret);
3295 NODE_SET_PROTOTYPE_METHOD(t, "getPrime", GetPrime);
3296 NODE_SET_PROTOTYPE_METHOD(t, "getGenerator", GetGenerator);
3297 NODE_SET_PROTOTYPE_METHOD(t, "getPublicKey", GetPublicKey);
3298 NODE_SET_PROTOTYPE_METHOD(t, "getPrivateKey", GetPrivateKey);
3299 NODE_SET_PROTOTYPE_METHOD(t, "setPublicKey", SetPublicKey);
3300 NODE_SET_PROTOTYPE_METHOD(t, "setPrivateKey", SetPrivateKey);
3302 target->Set(String::NewSymbol("DiffieHellman"), t->GetFunction());
3304 Local<FunctionTemplate> t2 = FunctionTemplate::New(DiffieHellmanGroup);
3305 t2->InstanceTemplate()->SetInternalFieldCount(1);
3307 NODE_SET_PROTOTYPE_METHOD(t2, "generateKeys", GenerateKeys);
3308 NODE_SET_PROTOTYPE_METHOD(t2, "computeSecret", ComputeSecret);
3309 NODE_SET_PROTOTYPE_METHOD(t2, "getPrime", GetPrime);
3310 NODE_SET_PROTOTYPE_METHOD(t2, "getGenerator", GetGenerator);
3311 NODE_SET_PROTOTYPE_METHOD(t2, "getPublicKey", GetPublicKey);
3312 NODE_SET_PROTOTYPE_METHOD(t2, "getPrivateKey", GetPrivateKey);
3314 target->Set(String::NewSymbol("DiffieHellmanGroup"), t2->GetFunction());
3317 bool Init(int primeLength) {
3319 DH_generate_parameters_ex(dh, primeLength, DH_GENERATOR_2, 0);
3320 bool result = VerifyContext();
3321 if (!result) return false;
3322 initialised_ = true;
3326 bool Init(unsigned char* p, int p_len) {
3328 dh->p = BN_bin2bn(p, p_len, 0);
3330 if (!BN_set_word(dh->g, 2)) return false;
3331 bool result = VerifyContext();
3332 if (!result) return false;
3333 initialised_ = true;
3337 bool Init(unsigned char* p, int p_len, unsigned char* g, int g_len) {
3339 dh->p = BN_bin2bn(p, p_len, 0);
3340 dh->g = BN_bin2bn(g, g_len, 0);
3341 initialised_ = true;
3346 static Handle<Value> DiffieHellmanGroup(const Arguments& args) {
3349 DiffieHellman* diffieHellman = new DiffieHellman();
3351 if (args.Length() != 1 || !args[0]->IsString()) {
3352 return ThrowException(Exception::Error(
3353 String::New("No group name given")));
3356 String::Utf8Value group_name(args[0]);
3358 modp_group* it = modp_groups;
3360 while(it->name != NULL) {
3361 if (!strcasecmp(*group_name, it->name))
3366 if (it->name != NULL) {
3367 diffieHellman->Init(it->prime, it->prime_size,
3368 it->gen, it->gen_size);
3370 return ThrowException(Exception::Error(
3371 String::New("Unknown group")));
3374 diffieHellman->Wrap(args.This());
3379 static Handle<Value> New(const Arguments& args) {
3382 DiffieHellman* diffieHellman = new DiffieHellman();
3383 bool initialized = false;
3385 if (args.Length() > 0) {
3386 if (args[0]->IsInt32()) {
3387 initialized = diffieHellman->Init(args[0]->Int32Value());
3389 initialized = diffieHellman->Init(
3390 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3391 Buffer::Length(args[0]));
3396 return ThrowException(Exception::Error(
3397 String::New("Initialization failed")));
3400 diffieHellman->Wrap(args.This());
3405 static Handle<Value> GenerateKeys(const Arguments& args) {
3406 DiffieHellman* diffieHellman =
3407 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3411 if (!diffieHellman->initialised_) {
3412 return ThrowException(Exception::Error(
3413 String::New("Not initialized")));
3416 if (!DH_generate_key(diffieHellman->dh)) {
3417 return ThrowException(Exception::Error(
3418 String::New("Key generation failed")));
3421 Local<Value> outString;
3423 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3424 char* data = new char[dataSize];
3425 BN_bn2bin(diffieHellman->dh->pub_key,
3426 reinterpret_cast<unsigned char*>(data));
3428 outString = Encode(data, dataSize, BUFFER);
3431 return scope.Close(outString);
3434 static Handle<Value> GetPrime(const Arguments& args) {
3435 DiffieHellman* diffieHellman =
3436 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3440 if (!diffieHellman->initialised_) {
3441 return ThrowException(Exception::Error(String::New("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 Local<Value> outString;
3450 outString = Encode(data, dataSize, BUFFER);
3454 return scope.Close(outString);
3457 static Handle<Value> GetGenerator(const Arguments& args) {
3458 DiffieHellman* diffieHellman =
3459 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3463 if (!diffieHellman->initialised_) {
3464 return ThrowException(Exception::Error(String::New("Not initialized")));
3467 int dataSize = BN_num_bytes(diffieHellman->dh->g);
3468 char* data = new char[dataSize];
3469 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
3471 Local<Value> outString;
3473 outString = Encode(data, dataSize, BUFFER);
3477 return scope.Close(outString);
3480 static Handle<Value> GetPublicKey(const Arguments& args) {
3481 DiffieHellman* diffieHellman =
3482 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3486 if (!diffieHellman->initialised_) {
3487 return ThrowException(Exception::Error(String::New("Not initialized")));
3490 if (diffieHellman->dh->pub_key == NULL) {
3491 return ThrowException(Exception::Error(
3492 String::New("No public key - did you forget to generate one?")));
3495 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3496 char* data = new char[dataSize];
3497 BN_bn2bin(diffieHellman->dh->pub_key,
3498 reinterpret_cast<unsigned char*>(data));
3500 Local<Value> outString;
3502 outString = Encode(data, dataSize, BUFFER);
3506 return scope.Close(outString);
3509 static Handle<Value> GetPrivateKey(const Arguments& args) {
3510 DiffieHellman* diffieHellman =
3511 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3515 if (!diffieHellman->initialised_) {
3516 return ThrowException(Exception::Error(String::New("Not initialized")));
3519 if (diffieHellman->dh->priv_key == NULL) {
3520 return ThrowException(Exception::Error(
3521 String::New("No private key - did you forget to generate one?")));
3524 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
3525 char* data = new char[dataSize];
3526 BN_bn2bin(diffieHellman->dh->priv_key,
3527 reinterpret_cast<unsigned char*>(data));
3529 Local<Value> outString;
3531 outString = Encode(data, dataSize, BUFFER);
3535 return scope.Close(outString);
3538 static Handle<Value> ComputeSecret(const Arguments& args) {
3541 DiffieHellman* diffieHellman =
3542 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3544 if (!diffieHellman->initialised_) {
3545 return ThrowException(Exception::Error(String::New("Not initialized")));
3550 if (args.Length() == 0) {
3551 return ThrowException(Exception::Error(
3552 String::New("First argument must be other party's public key")));
3554 ASSERT_IS_BUFFER(args[0]);
3556 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3557 Buffer::Length(args[0]), 0);
3560 int dataSize = DH_size(diffieHellman->dh);
3561 char* data = new char[dataSize];
3563 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
3564 key, diffieHellman->dh);
3570 checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
3575 return ThrowException(Exception::Error(String::New("Invalid key")));
3576 } else if (checkResult) {
3577 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
3578 return ThrowException(Exception::Error(
3579 String::New("Supplied key is too small")));
3580 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
3581 return ThrowException(Exception::Error(
3582 String::New("Supplied key is too large")));
3584 return ThrowException(Exception::Error(String::New("Invalid key")));
3587 return ThrowException(Exception::Error(String::New("Invalid key")));
3594 // DH_size returns number of bytes in a prime number
3595 // DH_compute_key returns number of bytes in a remainder of exponent, which
3596 // may have less bytes than a prime number. Therefore add 0-padding to the
3597 // allocated buffer.
3598 if (size != dataSize) {
3599 assert(dataSize > size);
3600 memset(data + size, 0, dataSize - size);
3603 Local<Value> outString;
3605 outString = Encode(data, dataSize, BUFFER);
3608 return scope.Close(outString);
3611 static Handle<Value> SetPublicKey(const Arguments& args) {
3614 DiffieHellman* diffieHellman =
3615 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3617 if (!diffieHellman->initialised_) {
3618 return ThrowException(Exception::Error(String::New("Not initialized")));
3621 if (args.Length() == 0) {
3622 return ThrowException(Exception::Error(
3623 String::New("First argument must be public key")));
3625 ASSERT_IS_BUFFER(args[0]);
3626 diffieHellman->dh->pub_key =
3628 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3629 Buffer::Length(args[0]), 0);
3635 static Handle<Value> SetPrivateKey(const Arguments& args) {
3638 DiffieHellman* diffieHellman =
3639 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3641 if (!diffieHellman->initialised_) {
3642 return ThrowException(Exception::Error(
3643 String::New("Not initialized")));
3646 if (args.Length() == 0) {
3647 return ThrowException(Exception::Error(
3648 String::New("First argument must be private key")));
3650 ASSERT_IS_BUFFER(args[0]);
3651 diffieHellman->dh->priv_key =
3653 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3654 Buffer::Length(args[0]), 0);
3660 DiffieHellman() : ObjectWrap() {
3661 initialised_ = false;
3672 bool VerifyContext() {
3674 if (!DH_check(dh, &codes)) return false;
3675 if (codes & DH_CHECK_P_NOT_SAFE_PRIME) return false;
3676 if (codes & DH_CHECK_P_NOT_PRIME) return false;
3677 if (codes & DH_UNABLE_TO_CHECK_GENERATOR) return false;
3678 if (codes & DH_NOT_SUITABLE_GENERATOR) return false;
3697 Persistent<Object> obj;
3701 void EIO_PBKDF2(pbkdf2_req* req) {
3702 req->err = PKCS5_PBKDF2_HMAC_SHA1(
3705 (unsigned char*)req->salt,
3709 (unsigned char*)req->key);
3710 memset(req->pass, 0, req->passlen);
3711 memset(req->salt, 0, req->saltlen);
3715 void EIO_PBKDF2(uv_work_t* work_req) {
3716 pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
3721 void EIO_PBKDF2After(pbkdf2_req* req, Local<Value> argv[2]) {
3723 argv[0] = Local<Value>::New(node_isolate, Undefined());
3724 argv[1] = Encode(req->key, req->keylen, BUFFER);
3725 memset(req->key, 0, req->keylen);
3727 argv[0] = Exception::Error(String::New("PBKDF2 error"));
3728 argv[1] = Local<Value>::New(node_isolate, Undefined());
3738 void EIO_PBKDF2After(uv_work_t* work_req, int status) {
3739 assert(status == 0);
3740 pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
3742 Local<Value> argv[2];
3743 Persistent<Object> obj = req->obj;
3744 EIO_PBKDF2After(req, argv);
3745 MakeCallback(obj, "ondone", ARRAY_SIZE(argv), argv);
3750 Handle<Value> PBKDF2(const Arguments& args) {
3753 const char* type_error = NULL;
3756 ssize_t passlen = -1;
3757 ssize_t saltlen = -1;
3758 ssize_t keylen = -1;
3759 ssize_t pass_written = -1;
3760 ssize_t salt_written = -1;
3762 pbkdf2_req* req = NULL;
3764 if (args.Length() != 4 && args.Length() != 5) {
3765 type_error = "Bad parameter";
3769 ASSERT_IS_BUFFER(args[0]);
3770 passlen = Buffer::Length(args[0]);
3772 type_error = "Bad password";
3776 pass = new char[passlen];
3777 pass_written = DecodeWrite(pass, passlen, args[0], BINARY);
3778 assert(pass_written == passlen);
3780 ASSERT_IS_BUFFER(args[1]);
3781 saltlen = Buffer::Length(args[1]);
3783 type_error = "Bad salt";
3787 salt = new char[saltlen];
3788 salt_written = DecodeWrite(salt, saltlen, args[1], BINARY);
3789 assert(salt_written == saltlen);
3791 if (!args[2]->IsNumber()) {
3792 type_error = "Iterations not a number";
3796 iter = args[2]->Int32Value();
3798 type_error = "Bad iterations";
3802 if (!args[3]->IsNumber()) {
3803 type_error = "Key length not a number";
3807 keylen = args[3]->Int32Value();
3809 type_error = "Bad key length";
3813 req = new pbkdf2_req;
3816 req->passlen = passlen;
3818 req->saltlen = saltlen;
3820 req->key = new char[keylen];
3821 req->keylen = keylen;
3823 if (args[4]->IsFunction()) {
3824 req->obj = Persistent<Object>::New(Object::New());
3825 req->obj->Set(String::New("ondone"), args[4]);
3826 uv_queue_work(uv_default_loop(),
3832 Local<Value> argv[2];
3834 EIO_PBKDF2After(req, argv);
3835 if (argv[0]->IsObject()) return ThrowException(argv[0]);
3836 return scope.Close(argv[1]);
3842 return ThrowException(Exception::TypeError(String::New(type_error)));
3846 struct RandomBytesRequest {
3847 ~RandomBytesRequest();
3848 Persistent<Object> obj_;
3849 unsigned long error_; // openssl error code or zero
3850 uv_work_t work_req_;
3856 RandomBytesRequest::~RandomBytesRequest() {
3857 if (obj_.IsEmpty()) return;
3863 void RandomBytesFree(char* data, void* hint) {
3868 template <bool pseudoRandom>
3869 void RandomBytesWork(uv_work_t* work_req) {
3870 RandomBytesRequest* req = container_of(work_req,
3875 if (pseudoRandom == true) {
3876 r = RAND_pseudo_bytes(reinterpret_cast<unsigned char*>(req->data_),
3879 r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data_), req->size_);
3882 // RAND_bytes() returns 0 on error. RAND_pseudo_bytes() returns 0 when the
3883 // result is not cryptographically strong - but that's not an error.
3884 if (r == 0 && pseudoRandom == false) {
3885 req->error_ = ERR_get_error();
3886 } else if (r == -1) {
3887 req->error_ = static_cast<unsigned long>(-1);
3892 // don't call this function without a valid HandleScope
3893 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
3895 char errmsg[256] = "Operation not supported";
3897 if (req->error_ != (unsigned long) -1)
3898 ERR_error_string_n(req->error_, errmsg, sizeof errmsg);
3900 argv[0] = Exception::Error(String::New(errmsg));
3901 argv[1] = Local<Value>::New(node_isolate, Null());
3904 // avoids the malloc + memcpy
3905 Buffer* buffer = Buffer::New(req->data_, req->size_, RandomBytesFree, NULL);
3906 argv[0] = Local<Value>::New(node_isolate, Null());
3907 argv[1] = Local<Object>::New(node_isolate, buffer->handle_);
3912 void RandomBytesAfter(uv_work_t* work_req, int status) {
3913 assert(status == 0);
3914 RandomBytesRequest* req = container_of(work_req,
3918 Local<Value> argv[2];
3919 RandomBytesCheck(req, argv);
3920 MakeCallback(req->obj_, "ondone", ARRAY_SIZE(argv), argv);
3925 template <bool pseudoRandom>
3926 Handle<Value> RandomBytes(const Arguments& args) {
3929 // maybe allow a buffer to write to? cuts down on object creation
3930 // when generating random data in a loop
3931 if (!args[0]->IsUint32()) {
3932 Local<String> s = String::New("Argument #1 must be number > 0");
3933 return ThrowException(Exception::TypeError(s));
3936 const size_t size = args[0]->Uint32Value();
3938 RandomBytesRequest* req = new RandomBytesRequest();
3940 req->data_ = new char[size];
3943 if (args[1]->IsFunction()) {
3944 req->obj_ = Persistent<Object>::New(Object::New());
3945 req->obj_->Set(String::New("ondone"), args[1]);
3947 uv_queue_work(uv_default_loop(),
3949 RandomBytesWork<pseudoRandom>,
3955 Local<Value> argv[2];
3956 RandomBytesWork<pseudoRandom>(&req->work_req_);
3957 RandomBytesCheck(req, argv);
3960 if (!argv[0]->IsNull())
3961 return ThrowException(argv[0]);
3968 Handle<Value> GetCiphers(const Arguments& args) {
3971 SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
3973 return ThrowError("SSL_CTX_new() failed.");
3976 SSL* ssl = SSL_new(ctx);
3979 return ThrowError("SSL_new() failed.");
3982 Local<Array> arr = Array::New();
3983 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
3985 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
3986 SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
3987 arr->Set(i, String::New(SSL_CIPHER_get_name(cipher)));
3993 return scope.Close(arr);
3997 static void add_hash_to_array(const EVP_MD* md,
4001 Local<Array>& arr = *static_cast<Local<Array>*>(arg);
4002 arr->Set(arr->Length(), String::New(from));
4006 Handle<Value> GetHashes(const Arguments& args) {
4008 Local<Array> arr = Array::New();
4009 EVP_MD_do_all_sorted(add_hash_to_array, &arr);
4010 return scope.Close(arr);
4014 void InitCrypto(Handle<Object> target) {
4018 OpenSSL_add_all_algorithms();
4019 OpenSSL_add_all_digests();
4020 SSL_load_error_strings();
4021 ERR_load_crypto_strings();
4024 CRYPTO_set_locking_callback(crypto_lock_cb);
4025 CRYPTO_THREADID_set_callback(crypto_threadid_cb);
4027 // Turn off compression. Saves memory - do it in userland.
4028 #if !defined(OPENSSL_NO_COMP)
4029 STACK_OF(SSL_COMP)* comp_methods =
4030 #if OPENSSL_VERSION_NUMBER < 0x00908000L
4031 SSL_COMP_get_compression_method()
4033 SSL_COMP_get_compression_methods()
4036 sk_SSL_COMP_zero(comp_methods);
4037 assert(sk_SSL_COMP_num(comp_methods) == 0);
4040 SecureContext::Initialize(target);
4041 Connection::Initialize(target);
4042 Cipher::Initialize(target);
4043 Decipher::Initialize(target);
4044 DiffieHellman::Initialize(target);
4045 Hmac::Initialize(target);
4046 Hash::Initialize(target);
4047 Sign::Initialize(target);
4048 Verify::Initialize(target);
4050 NODE_SET_METHOD(target, "PBKDF2", PBKDF2);
4051 NODE_SET_METHOD(target, "randomBytes", RandomBytes<false>);
4052 NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<true>);
4053 NODE_SET_METHOD(target, "getCiphers", GetCiphers);
4054 NODE_SET_METHOD(target, "getHashes", GetHashes);
4056 subject_symbol = NODE_PSYMBOL("subject");
4057 issuer_symbol = NODE_PSYMBOL("issuer");
4058 valid_from_symbol = NODE_PSYMBOL("valid_from");
4059 valid_to_symbol = NODE_PSYMBOL("valid_to");
4060 subjectaltname_symbol = NODE_PSYMBOL("subjectaltname");
4061 modulus_symbol = NODE_PSYMBOL("modulus");
4062 exponent_symbol = NODE_PSYMBOL("exponent");
4063 fingerprint_symbol = NODE_PSYMBOL("fingerprint");
4064 name_symbol = NODE_PSYMBOL("name");
4065 version_symbol = NODE_PSYMBOL("version");
4066 ext_key_usage_symbol = NODE_PSYMBOL("ext_key_usage");
4069 } // namespace crypto
4072 NODE_MODULE(node_crypto, node::crypto::InitCrypto)