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);
122 Handle<Value> ThrowCryptoErrorHelper(unsigned long err, bool is_type_error) {
125 ERR_error_string_n(err, errmsg, sizeof(errmsg));
126 return is_type_error ? ThrowTypeError(errmsg) : ThrowError(errmsg);
130 Handle<Value> ThrowCryptoError(unsigned long err) {
131 return ThrowCryptoErrorHelper(err, false);
135 Handle<Value> ThrowCryptoTypeError(unsigned long err) {
136 return ThrowCryptoErrorHelper(err, true);
140 void SecureContext::Initialize(Handle<Object> target) {
143 Local<FunctionTemplate> t = FunctionTemplate::New(SecureContext::New);
144 secure_context_constructor = Persistent<FunctionTemplate>::New(t);
146 t->InstanceTemplate()->SetInternalFieldCount(1);
147 t->SetClassName(String::NewSymbol("SecureContext"));
149 NODE_SET_PROTOTYPE_METHOD(t, "init", SecureContext::Init);
150 NODE_SET_PROTOTYPE_METHOD(t, "setKey", SecureContext::SetKey);
151 NODE_SET_PROTOTYPE_METHOD(t, "setCert", SecureContext::SetCert);
152 NODE_SET_PROTOTYPE_METHOD(t, "addCACert", SecureContext::AddCACert);
153 NODE_SET_PROTOTYPE_METHOD(t, "addCRL", SecureContext::AddCRL);
154 NODE_SET_PROTOTYPE_METHOD(t, "addRootCerts", SecureContext::AddRootCerts);
155 NODE_SET_PROTOTYPE_METHOD(t, "setCiphers", SecureContext::SetCiphers);
156 NODE_SET_PROTOTYPE_METHOD(t, "setOptions", SecureContext::SetOptions);
157 NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
158 SecureContext::SetSessionIdContext);
159 NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
160 NODE_SET_PROTOTYPE_METHOD(t, "loadPKCS12", SecureContext::LoadPKCS12);
162 target->Set(String::NewSymbol("SecureContext"), t->GetFunction());
166 Handle<Value> SecureContext::New(const Arguments& args) {
168 SecureContext *p = new SecureContext();
169 p->Wrap(args.Holder());
174 Handle<Value> SecureContext::Init(const Arguments& args) {
177 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
179 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
181 if (args.Length() == 1 && args[0]->IsString()) {
182 String::Utf8Value sslmethod(args[0]);
184 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
185 #ifndef OPENSSL_NO_SSL2
186 method = SSLv2_method();
188 return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
190 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
191 #ifndef OPENSSL_NO_SSL2
192 method = SSLv2_server_method();
194 return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
196 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
197 #ifndef OPENSSL_NO_SSL2
198 method = SSLv2_client_method();
200 return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
202 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
203 method = SSLv3_method();
204 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
205 method = SSLv3_server_method();
206 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
207 method = SSLv3_client_method();
208 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
209 method = SSLv23_method();
210 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
211 method = SSLv23_server_method();
212 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
213 method = SSLv23_client_method();
214 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
215 method = TLSv1_method();
216 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
217 method = TLSv1_server_method();
218 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
219 method = TLSv1_client_method();
221 return ThrowException(Exception::Error(String::New("Unknown method")));
225 sc->ctx_ = SSL_CTX_new(method);
227 // SSL session cache configuration
228 SSL_CTX_set_session_cache_mode(sc->ctx_,
229 SSL_SESS_CACHE_SERVER |
230 SSL_SESS_CACHE_NO_INTERNAL |
231 SSL_SESS_CACHE_NO_AUTO_CLEAR);
232 SSL_CTX_sess_set_get_cb(sc->ctx_, GetSessionCallback);
233 SSL_CTX_sess_set_new_cb(sc->ctx_, NewSessionCallback);
235 sc->ca_store_ = NULL;
240 SSL_SESSION* SecureContext::GetSessionCallback(SSL* s,
246 Connection* p = static_cast<Connection*>(SSL_get_app_data(s));
249 SSL_SESSION* sess = p->next_sess_;
250 p->next_sess_ = NULL;
256 void SessionDataFree(char* data, void* hint) {
261 int SecureContext::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
264 Connection* p = static_cast<Connection*>(SSL_get_app_data(s));
266 // Check if session is small enough to be stored
267 int size = i2d_SSL_SESSION(sess, NULL);
268 if (size > kMaxSessionSize) return 0;
271 char* serialized = new char[size];
272 unsigned char* pserialized = reinterpret_cast<unsigned char*>(serialized);
273 memset(serialized, 0, size);
274 i2d_SSL_SESSION(sess, &pserialized);
276 Handle<Value> argv[2] = {
277 Buffer::New(reinterpret_cast<char*>(sess->session_id),
278 sess->session_id_length)->handle_,
279 Buffer::New(serialized, size, SessionDataFree, NULL)->handle_
282 if (onnewsession_sym.IsEmpty()) {
283 onnewsession_sym = NODE_PSYMBOL("onnewsession");
285 MakeCallback(p->handle_, onnewsession_sym, ARRAY_SIZE(argv), argv);
291 // Takes a string or buffer and loads it into a BIO.
292 // Caller responsible for BIO_free-ing the returned object.
293 static BIO* LoadBIO (Handle<Value> v) {
294 BIO *bio = BIO_new(BIO_s_mem());
295 if (!bio) return NULL;
302 String::Utf8Value s(v);
303 r = BIO_write(bio, *s, s.length());
304 } else if (Buffer::HasInstance(v)) {
305 char* buffer_data = Buffer::Data(v);
306 size_t buffer_length = Buffer::Length(v);
307 r = BIO_write(bio, buffer_data, buffer_length);
319 // Takes a string or buffer and loads it into an X509
320 // Caller responsible for X509_free-ing the returned object.
321 static X509* LoadX509 (Handle<Value> v) {
322 HandleScope scope; // necessary?
324 BIO *bio = LoadBIO(v);
325 if (!bio) return NULL;
327 X509 * x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
338 Handle<Value> SecureContext::SetKey(const Arguments& args) {
341 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
343 unsigned int len = args.Length();
344 if (len != 1 && len != 2) {
345 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
347 if (len == 2 && !args[1]->IsString()) {
348 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
351 BIO *bio = LoadBIO(args[0]);
352 if (!bio) return False();
354 String::Utf8Value passphrase(args[1]);
356 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, NULL,
357 len == 1 ? NULL : *passphrase);
361 unsigned long err = ERR_get_error();
363 return ThrowException(Exception::Error(
364 String::New("PEM_read_bio_PrivateKey")));
366 return ThrowCryptoError(err);
369 SSL_CTX_use_PrivateKey(sc->ctx_, key);
377 // Read a file that contains our certificate in "PEM" format,
378 // possibly followed by a sequence of CA certificates that should be
379 // sent to the peer in the Certificate message.
381 // Taken from OpenSSL - editted for style.
382 int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, BIO *in) {
386 x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
389 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
393 ret = SSL_CTX_use_certificate(ctx, x);
395 if (ERR_peek_error() != 0) {
396 // Key/certificate mismatch doesn't imply ret==0 ...
401 // If we could set up our certificate, now proceed to
402 // the CA certificates.
407 if (ctx->extra_certs != NULL) {
408 sk_X509_pop_free(ctx->extra_certs, X509_free);
409 ctx->extra_certs = NULL;
412 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
413 r = SSL_CTX_add_extra_chain_cert(ctx, ca);
420 // Note that we must not free r if it was successfully
421 // added to the chain (while we must free the main
422 // certificate, since its reference count is increased
423 // by SSL_CTX_use_certificate).
426 // When the while loop ends, it's usually just EOF.
427 err = ERR_peek_last_error();
428 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
429 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
438 if (x != NULL) X509_free(x);
443 Handle<Value> SecureContext::SetCert(const Arguments& args) {
446 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
448 if (args.Length() != 1) {
449 return ThrowException(Exception::TypeError(
450 String::New("Bad parameter")));
453 BIO* bio = LoadBIO(args[0]);
454 if (!bio) return False();
456 int rv = SSL_CTX_use_certificate_chain(sc->ctx_, bio);
461 unsigned long err = ERR_get_error();
463 return ThrowException(Exception::Error(
464 String::New("SSL_CTX_use_certificate_chain")));
466 return ThrowCryptoError(err);
473 Handle<Value> SecureContext::AddCACert(const Arguments& args) {
474 bool newCAStore = false;
477 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
479 if (args.Length() != 1) {
480 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
483 if (!sc->ca_store_) {
484 sc->ca_store_ = X509_STORE_new();
488 X509* x509 = LoadX509(args[0]);
489 if (!x509) return False();
491 X509_STORE_add_cert(sc->ca_store_, x509);
492 SSL_CTX_add_client_CA(sc->ctx_, x509);
497 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
504 Handle<Value> SecureContext::AddCRL(const Arguments& args) {
507 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
509 if (args.Length() != 1) {
510 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
513 BIO *bio = LoadBIO(args[0]);
514 if (!bio) return False();
516 X509_CRL *x509 = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
523 X509_STORE_add_crl(sc->ca_store_, x509);
525 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
526 X509_V_FLAG_CRL_CHECK_ALL);
536 Handle<Value> SecureContext::AddRootCerts(const Arguments& args) {
539 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
541 assert(sc->ca_store_ == NULL);
543 if (!root_cert_store) {
544 root_cert_store = X509_STORE_new();
546 for (int i = 0; root_certs[i]; i++) {
547 BIO *bp = BIO_new(BIO_s_mem());
549 if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
554 X509 *x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
561 X509_STORE_add_cert(root_cert_store, x509);
568 sc->ca_store_ = root_cert_store;
569 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
575 Handle<Value> SecureContext::SetCiphers(const Arguments& args) {
578 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
580 if (args.Length() != 1 || !args[0]->IsString()) {
581 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
584 String::Utf8Value ciphers(args[0]);
585 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
590 Handle<Value> SecureContext::SetOptions(const Arguments& args) {
593 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
595 if (args.Length() != 1 || !args[0]->IntegerValue()) {
596 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
599 SSL_CTX_set_options(sc->ctx_, args[0]->IntegerValue());
604 Handle<Value> SecureContext::SetSessionIdContext(const Arguments& args) {
607 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
609 if (args.Length() != 1 || !args[0]->IsString()) {
610 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
613 String::Utf8Value sessionIdContext(args[0]);
614 const unsigned char* sid_ctx = (const unsigned char*) *sessionIdContext;
615 unsigned int sid_ctx_len = sessionIdContext.length();
617 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
619 Local<String> message;
622 if ((bio = BIO_new(BIO_s_mem()))) {
623 ERR_print_errors(bio);
624 BIO_get_mem_ptr(bio, &mem);
625 message = String::New(mem->data, mem->length);
628 message = String::New("SSL_CTX_set_session_id_context error");
630 return ThrowException(Exception::TypeError(message));
636 Handle<Value> SecureContext::Close(const Arguments& args) {
638 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
643 //Takes .pfx or .p12 and password in string or buffer format
644 Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
649 EVP_PKEY* pkey = NULL;
651 STACK_OF(X509)* extraCerts = NULL;
655 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
657 if (args.Length() < 1) {
658 return ThrowException(Exception::TypeError(
659 String::New("Bad parameter")));
662 in = LoadBIO(args[0]);
664 return ThrowException(Exception::Error(
665 String::New("Unable to load BIO")));
668 if (args.Length() >= 2) {
669 ASSERT_IS_BUFFER(args[1]);
671 int passlen = Buffer::Length(args[1]);
674 return ThrowException(Exception::TypeError(
675 String::New("Bad password")));
677 pass = new char[passlen + 1];
678 int pass_written = DecodeWrite(pass, passlen, args[1], BINARY);
680 assert(pass_written == passlen);
681 pass[passlen] = '\0';
684 if (d2i_PKCS12_bio(in, &p12) &&
685 PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
686 SSL_CTX_use_certificate(sc->ctx_, cert) &&
687 SSL_CTX_use_PrivateKey(sc->ctx_, pkey))
690 while (X509* x509 = sk_X509_pop(extraCerts)) {
691 if (!sc->ca_store_) {
692 sc->ca_store_ = X509_STORE_new();
693 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
696 X509_STORE_add_cert(sc->ca_store_, x509);
697 SSL_CTX_add_client_CA(sc->ctx_, x509);
702 sk_X509_free(extraCerts);
712 unsigned long err = ERR_get_error();
713 const char* str = ERR_reason_error_string(err);
714 return ThrowException(Exception::Error(String::New(str)));
721 size_t ClientHelloParser::Write(const uint8_t* data, size_t len) {
724 // Just accumulate data, everything will be pushed to BIO later
725 if (state_ == kPaused) return 0;
727 // Copy incoming data to the internal buffer
728 // (which has a size of the biggest possible TLS frame)
729 size_t available = sizeof(data_) - offset_;
730 size_t copied = len < available ? len : available;
731 memcpy(data_ + offset_, data, copied);
734 // Vars for parsing hello
735 bool is_clienthello = false;
736 uint8_t session_size = -1;
737 uint8_t* session_id = NULL;
739 Handle<Value> argv[1];
743 // >= 5 bytes for header parsing
744 if (offset_ < 5) break;
746 if (data_[0] == kChangeCipherSpec || data_[0] == kAlert ||
747 data_[0] == kHandshake || data_[0] == kApplicationData) {
748 frame_len_ = (data_[3] << 8) + data_[4];
752 frame_len_ = (data_[0] << 8) + data_[1];
755 // header with padding
763 // Sanity check (too big frame, or too small)
764 if (frame_len_ >= sizeof(data_)) {
765 // Let OpenSSL handle it
771 // >= 5 + frame size bytes for frame parsing
772 if (offset_ < body_offset_ + frame_len_) break;
774 // Skip unsupported frames and gather some data from frame
776 // TODO: Check protocol version
777 if (data_[body_offset_] == kClientHello) {
778 is_clienthello = true;
780 size_t session_offset;
782 if (state_ == kTLSHeader) {
783 // Skip frame header, hello header, protocol version and random data
784 session_offset = body_offset_ + 4 + 2 + 32;
786 if (session_offset + 1 < offset_) {
787 body = data_ + session_offset;
788 session_size = *body;
789 session_id = body + 1;
791 } else if (state_ == kSSLHeader) {
792 // Skip header, version
793 session_offset = body_offset_ + 3;
795 if (session_offset + 4 < offset_) {
796 body = data_ + session_offset;
798 int ciphers_size = (body[0] << 8) + body[1];
800 if (body + 4 + ciphers_size < data_ + offset_) {
801 session_size = (body[2] << 8) + body[3];
802 session_id = body + 4 + ciphers_size;
806 // Whoa? How did we get here?
810 // Check if we overflowed (do not reply with any private data)
811 if (session_id == NULL ||
813 session_id + session_size > data_ + offset_) {
818 // TODO: Parse other things?
821 // Not client hello - let OpenSSL handle it
822 if (!is_clienthello) {
827 // Parse frame, call javascript handler and
828 // move parser into the paused state
829 if (onclienthello_sym.IsEmpty()) {
830 onclienthello_sym = NODE_PSYMBOL("onclienthello");
832 if (sessionid_sym.IsEmpty()) {
833 sessionid_sym = NODE_PSYMBOL("sessionId");
837 hello = Object::New();
838 hello->Set(sessionid_sym,
839 Buffer::New(reinterpret_cast<char*>(session_id),
840 session_size)->handle_);
843 MakeCallback(conn_->handle_, onclienthello_sym, 1, argv);
854 void ClientHelloParser::Finish() {
855 assert(state_ != kEnded);
858 // Write all accumulated data
859 int r = BIO_write(conn_->bio_read_, reinterpret_cast<char*>(data_), offset_);
860 conn_->HandleBIOError(conn_->bio_read_, "BIO_write", r);
861 conn_->SetShutdownFlags();
865 #ifdef SSL_PRINT_DEBUG
866 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
868 # define DEBUG_PRINT(...)
872 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
873 if (rv >= 0) return rv;
875 int retry = BIO_should_retry(bio);
876 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
878 if (BIO_should_write(bio)) {
879 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n", ssl_, func, retry);
882 } else if (BIO_should_read(bio)) {
883 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
887 static char ssl_error_buf[512];
888 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
891 Local<Value> e = Exception::Error(String::New(ssl_error_buf));
892 handle_->Set(String::New("error"), e);
894 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n", ssl_, func, rv, ssl_error_buf);
903 int Connection::HandleSSLError(const char* func, int rv, ZeroStatus zs) {
904 // Forcibly clear OpenSSL's error stack on return. This stops stale errors
905 // from popping up later in the lifecycle of the SSL connection where they
906 // would cause spurious failures. It's a rather blunt method, though.
907 // ERR_clear_error() isn't necessarily cheap either.
908 struct ClearErrorOnReturn {
909 ~ClearErrorOnReturn() { ERR_clear_error(); }
911 ClearErrorOnReturn clear_error_on_return;
912 (void) &clear_error_on_return; // Silence unused variable warning.
914 if (rv > 0) return rv;
915 if ((rv == 0) && (zs == kZeroIsNotAnError)) return rv;
917 int err = SSL_get_error(ssl_, rv);
919 if (err == SSL_ERROR_NONE) {
922 } else if (err == SSL_ERROR_WANT_WRITE) {
923 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
926 } else if (err == SSL_ERROR_WANT_READ) {
927 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
930 } else if (err == SSL_ERROR_ZERO_RETURN) {
931 handle_->Set(String::New("error"),
932 Exception::Error(String::New("ZERO_RETURN")));
940 assert(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
942 // XXX We need to drain the error queue for this thread or else OpenSSL
943 // has the possibility of blocking connections? This problem is not well
944 // understood. And we should be somehow propagating these errors up
945 // into JavaScript. There is no test which demonstrates this problem.
946 // https://github.com/joyent/node/issues/1719
947 if ((bio = BIO_new(BIO_s_mem()))) {
948 ERR_print_errors(bio);
949 BIO_get_mem_ptr(bio, &mem);
950 Local<Value> e = Exception::Error(String::New(mem->data, mem->length));
951 handle_->Set(String::New("error"), e);
962 void Connection::ClearError() {
966 // We should clear the error in JS-land
967 assert(handle_->Get(String::New("error"))->BooleanValue() == false);
972 void Connection::SetShutdownFlags() {
975 int flags = SSL_get_shutdown(ssl_);
977 if (flags & SSL_SENT_SHUTDOWN) {
978 handle_->Set(String::New("sentShutdown"), True());
981 if (flags & SSL_RECEIVED_SHUTDOWN) {
982 handle_->Set(String::New("receivedShutdown"), True());
987 void Connection::Initialize(Handle<Object> target) {
990 Local<FunctionTemplate> t = FunctionTemplate::New(Connection::New);
991 t->InstanceTemplate()->SetInternalFieldCount(1);
992 t->SetClassName(String::NewSymbol("Connection"));
994 NODE_SET_PROTOTYPE_METHOD(t, "encIn", Connection::EncIn);
995 NODE_SET_PROTOTYPE_METHOD(t, "clearOut", Connection::ClearOut);
996 NODE_SET_PROTOTYPE_METHOD(t, "clearIn", Connection::ClearIn);
997 NODE_SET_PROTOTYPE_METHOD(t, "encOut", Connection::EncOut);
998 NODE_SET_PROTOTYPE_METHOD(t, "clearPending", Connection::ClearPending);
999 NODE_SET_PROTOTYPE_METHOD(t, "encPending", Connection::EncPending);
1000 NODE_SET_PROTOTYPE_METHOD(t, "getPeerCertificate", Connection::GetPeerCertificate);
1001 NODE_SET_PROTOTYPE_METHOD(t, "getSession", Connection::GetSession);
1002 NODE_SET_PROTOTYPE_METHOD(t, "setSession", Connection::SetSession);
1003 NODE_SET_PROTOTYPE_METHOD(t, "loadSession", Connection::LoadSession);
1004 NODE_SET_PROTOTYPE_METHOD(t, "isSessionReused", Connection::IsSessionReused);
1005 NODE_SET_PROTOTYPE_METHOD(t, "isInitFinished", Connection::IsInitFinished);
1006 NODE_SET_PROTOTYPE_METHOD(t, "verifyError", Connection::VerifyError);
1007 NODE_SET_PROTOTYPE_METHOD(t, "getCurrentCipher", Connection::GetCurrentCipher);
1008 NODE_SET_PROTOTYPE_METHOD(t, "start", Connection::Start);
1009 NODE_SET_PROTOTYPE_METHOD(t, "shutdown", Connection::Shutdown);
1010 NODE_SET_PROTOTYPE_METHOD(t, "receivedShutdown", Connection::ReceivedShutdown);
1011 NODE_SET_PROTOTYPE_METHOD(t, "close", Connection::Close);
1013 #ifdef OPENSSL_NPN_NEGOTIATED
1014 NODE_SET_PROTOTYPE_METHOD(t, "getNegotiatedProtocol", Connection::GetNegotiatedProto);
1015 NODE_SET_PROTOTYPE_METHOD(t, "setNPNProtocols", Connection::SetNPNProtocols);
1019 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1020 NODE_SET_PROTOTYPE_METHOD(t, "getServername", Connection::GetServername);
1021 NODE_SET_PROTOTYPE_METHOD(t, "setSNICallback", Connection::SetSNICallback);
1024 target->Set(String::NewSymbol("Connection"), t->GetFunction());
1028 static int VerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) {
1029 // Quoting SSL_set_verify(3ssl):
1031 // The VerifyCallback function is used to control the behaviour when
1032 // the SSL_VERIFY_PEER flag is set. It must be supplied by the
1033 // application and receives two arguments: preverify_ok indicates,
1034 // whether the verification of the certificate in question was passed
1035 // (preverify_ok=1) or not (preverify_ok=0). x509_ctx is a pointer to
1036 // the complete context used for the certificate chain verification.
1038 // The certificate chain is checked starting with the deepest nesting
1039 // level (the root CA certificate) and worked upward to the peer's
1040 // certificate. At each level signatures and issuer attributes are
1041 // checked. Whenever a verification error is found, the error number is
1042 // stored in x509_ctx and VerifyCallback is called with preverify_ok=0.
1043 // By applying X509_CTX_store_* functions VerifyCallback can locate the
1044 // certificate in question and perform additional steps (see EXAMPLES).
1045 // If no error is found for a certificate, VerifyCallback is called
1046 // with preverify_ok=1 before advancing to the next level.
1048 // The return value of VerifyCallback controls the strategy of the
1049 // further verification process. If VerifyCallback returns 0, the
1050 // verification process is immediately stopped with "verification
1051 // failed" state. If SSL_VERIFY_PEER is set, a verification failure
1052 // alert is sent to the peer and the TLS/SSL handshake is terminated. If
1053 // VerifyCallback returns 1, the verification process is continued. If
1054 // VerifyCallback always returns 1, the TLS/SSL handshake will not be
1055 // terminated with respect to verification failures and the connection
1056 // will be established. The calling process can however retrieve the
1057 // error code of the last verification error using
1058 // SSL_get_verify_result(3) or by maintaining its own error storage
1059 // managed by VerifyCallback.
1061 // If no VerifyCallback is specified, the default callback will be
1062 // used. Its return value is identical to preverify_ok, so that any
1063 // verification failure will lead to a termination of the TLS/SSL
1064 // handshake with an alert message, if SSL_VERIFY_PEER is set.
1066 // Since we cannot perform I/O quickly enough in this callback, we ignore
1067 // all preverify_ok errors and let the handshake continue. It is
1068 // imparative that the user use Connection::VerifyError after the
1069 // 'secure' callback has been made.
1073 #ifdef OPENSSL_NPN_NEGOTIATED
1075 int Connection::AdvertiseNextProtoCallback_(SSL *s,
1076 const unsigned char** data,
1080 Connection *p = static_cast<Connection*>(SSL_get_app_data(s));
1082 if (p->npnProtos_.IsEmpty()) {
1083 // No initialization - no NPN protocols
1084 *data = reinterpret_cast<const unsigned char*>("");
1087 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(p->npnProtos_));
1088 *len = Buffer::Length(p->npnProtos_);
1091 return SSL_TLSEXT_ERR_OK;
1094 int Connection::SelectNextProtoCallback_(SSL *s,
1095 unsigned char** out, unsigned char* outlen,
1096 const unsigned char* in,
1097 unsigned int inlen, void *arg) {
1098 Connection *p = static_cast<Connection*> SSL_get_app_data(s);
1100 // Release old protocol handler if present
1101 if (!p->selectedNPNProto_.IsEmpty()) {
1102 p->selectedNPNProto_.Dispose();
1105 if (p->npnProtos_.IsEmpty()) {
1106 // We should at least select one protocol
1107 // If server is using NPN
1108 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
1111 // set status unsupported
1112 p->selectedNPNProto_ = Persistent<Value>::New(False());
1114 return SSL_TLSEXT_ERR_OK;
1117 const unsigned char* npnProtos =
1118 reinterpret_cast<const unsigned char*>(Buffer::Data(p->npnProtos_));
1120 int status = SSL_select_next_proto(out, outlen, in, inlen, npnProtos,
1121 Buffer::Length(p->npnProtos_));
1124 case OPENSSL_NPN_UNSUPPORTED:
1125 p->selectedNPNProto_ = Persistent<Value>::New(Null());
1127 case OPENSSL_NPN_NEGOTIATED:
1128 p->selectedNPNProto_ = Persistent<Value>::New(String::New(
1129 reinterpret_cast<const char*>(*out), *outlen
1132 case OPENSSL_NPN_NO_OVERLAP:
1133 p->selectedNPNProto_ = Persistent<Value>::New(False());
1139 return SSL_TLSEXT_ERR_OK;
1143 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1144 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
1147 Connection *p = static_cast<Connection*> SSL_get_app_data(s);
1149 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
1152 if (!p->servername_.IsEmpty()) {
1153 p->servername_.Dispose();
1155 p->servername_ = Persistent<String>::New(String::New(servername));
1157 // Call the SNI callback and use its return value as context
1158 if (!p->sniObject_.IsEmpty()) {
1159 if (!p->sniContext_.IsEmpty()) {
1160 p->sniContext_.Dispose();
1163 // Get callback init args
1164 Local<Value> argv[1] = {*p->servername_};
1167 Local<Value> ret = Local<Value>::New(MakeCallback(p->sniObject_,
1172 // If ret is SecureContext
1173 if (secure_context_constructor->HasInstance(ret)) {
1174 p->sniContext_ = Persistent<Value>::New(ret);
1175 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(
1176 Local<Object>::Cast(ret));
1177 SSL_set_SSL_CTX(s, sc->ctx_);
1179 return SSL_TLSEXT_ERR_NOACK;
1184 return SSL_TLSEXT_ERR_OK;
1188 Handle<Value> Connection::New(const Arguments& args) {
1191 Connection *p = new Connection();
1192 p->Wrap(args.Holder());
1194 if (args.Length() < 1 || !args[0]->IsObject()) {
1195 return ThrowException(Exception::Error(String::New(
1196 "First argument must be a crypto module Credentials")));
1199 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args[0]->ToObject());
1201 bool is_server = args[1]->BooleanValue();
1203 p->ssl_ = SSL_new(sc->ctx_);
1204 p->bio_read_ = BIO_new(BIO_s_mem());
1205 p->bio_write_ = BIO_new(BIO_s_mem());
1207 SSL_set_app_data(p->ssl_, p);
1209 if (is_server) SSL_set_info_callback(p->ssl_, SSLInfoCallback);
1211 #ifdef OPENSSL_NPN_NEGOTIATED
1213 // Server should advertise NPN protocols
1214 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
1215 AdvertiseNextProtoCallback_,
1218 // Client should select protocol from advertised
1219 // If server supports NPN
1220 SSL_CTX_set_next_proto_select_cb(sc->ctx_,
1221 SelectNextProtoCallback_,
1226 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1228 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
1230 String::Utf8Value servername(args[2]);
1231 SSL_set_tlsext_host_name(p->ssl_, *servername);
1235 SSL_set_bio(p->ssl_, p->bio_read_, p->bio_write_);
1237 #ifdef SSL_MODE_RELEASE_BUFFERS
1238 long mode = SSL_get_mode(p->ssl_);
1239 SSL_set_mode(p->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
1245 bool request_cert = args[2]->BooleanValue();
1246 if (!request_cert) {
1247 // Note reject_unauthorized ignored.
1248 verify_mode = SSL_VERIFY_NONE;
1250 bool reject_unauthorized = args[3]->BooleanValue();
1251 verify_mode = SSL_VERIFY_PEER;
1252 if (reject_unauthorized) verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1255 // Note request_cert and reject_unauthorized are ignored for clients.
1256 verify_mode = SSL_VERIFY_NONE;
1260 // Always allow a connection. We'll reject in javascript.
1261 SSL_set_verify(p->ssl_, verify_mode, VerifyCallback);
1263 if ((p->is_server_ = is_server)) {
1264 SSL_set_accept_state(p->ssl_);
1266 SSL_set_connect_state(p->ssl_);
1273 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
1274 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
1275 // a non-const SSL* in OpenSSL <= 0.9.7e.
1276 SSL* ssl = const_cast<SSL*>(ssl_);
1277 if (where & SSL_CB_HANDSHAKE_START) {
1279 Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl));
1280 if (onhandshakestart_sym.IsEmpty()) {
1281 onhandshakestart_sym = NODE_PSYMBOL("onhandshakestart");
1283 MakeCallback(c->handle_, onhandshakestart_sym, 0, NULL);
1285 if (where & SSL_CB_HANDSHAKE_DONE) {
1287 Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl));
1288 if (onhandshakedone_sym.IsEmpty()) {
1289 onhandshakedone_sym = NODE_PSYMBOL("onhandshakedone");
1291 MakeCallback(c->handle_, onhandshakedone_sym, 0, NULL);
1296 Handle<Value> Connection::EncIn(const Arguments& args) {
1299 Connection *ss = Connection::Unwrap(args);
1301 if (args.Length() < 3) {
1302 return ThrowException(Exception::TypeError(
1303 String::New("Takes 3 parameters")));
1306 if (!Buffer::HasInstance(args[0])) {
1307 return ThrowException(Exception::TypeError(
1308 String::New("Second argument should be a buffer")));
1311 char* buffer_data = Buffer::Data(args[0]);
1312 size_t buffer_length = Buffer::Length(args[0]);
1314 size_t off = args[1]->Int32Value();
1315 size_t len = args[2]->Int32Value();
1316 if (off + len > buffer_length) {
1317 return ThrowException(Exception::Error(
1318 String::New("off + len > buffer.length")));
1322 char* data = buffer_data + off;
1324 if (ss->is_server_ && !ss->hello_parser_.ended()) {
1325 bytes_written = ss->hello_parser_.Write(reinterpret_cast<uint8_t*>(data),
1328 bytes_written = BIO_write(ss->bio_read_, data, len);
1329 ss->HandleBIOError(ss->bio_read_, "BIO_write", bytes_written);
1330 ss->SetShutdownFlags();
1333 return scope.Close(Integer::New(bytes_written));
1337 Handle<Value> Connection::ClearOut(const Arguments& args) {
1340 Connection *ss = Connection::Unwrap(args);
1342 if (args.Length() < 3) {
1343 return ThrowException(Exception::TypeError(
1344 String::New("Takes 3 parameters")));
1347 if (!Buffer::HasInstance(args[0])) {
1348 return ThrowException(Exception::TypeError(
1349 String::New("Second argument should be a buffer")));
1352 char* buffer_data = Buffer::Data(args[0]);
1353 size_t buffer_length = Buffer::Length(args[0]);
1355 size_t off = args[1]->Int32Value();
1356 size_t len = args[2]->Int32Value();
1357 if (off + len > buffer_length) {
1358 return ThrowException(Exception::Error(
1359 String::New("off + len > buffer.length")));
1362 if (!SSL_is_init_finished(ss->ssl_)) {
1365 if (ss->is_server_) {
1366 rv = SSL_accept(ss->ssl_);
1367 ss->HandleSSLError("SSL_accept:ClearOut", rv, kZeroIsAnError);
1369 rv = SSL_connect(ss->ssl_);
1370 ss->HandleSSLError("SSL_connect:ClearOut", rv, kZeroIsAnError);
1373 if (rv < 0) return scope.Close(Integer::New(rv));
1376 int bytes_read = SSL_read(ss->ssl_, buffer_data + off, len);
1377 ss->HandleSSLError("SSL_read:ClearOut", bytes_read, kZeroIsNotAnError);
1378 ss->SetShutdownFlags();
1380 return scope.Close(Integer::New(bytes_read));
1384 Handle<Value> Connection::ClearPending(const Arguments& args) {
1387 Connection *ss = Connection::Unwrap(args);
1389 int bytes_pending = BIO_pending(ss->bio_read_);
1390 return scope.Close(Integer::New(bytes_pending));
1394 Handle<Value> Connection::EncPending(const Arguments& args) {
1397 Connection *ss = Connection::Unwrap(args);
1399 int bytes_pending = BIO_pending(ss->bio_write_);
1400 return scope.Close(Integer::New(bytes_pending));
1404 Handle<Value> Connection::EncOut(const Arguments& args) {
1407 Connection *ss = Connection::Unwrap(args);
1409 if (args.Length() < 3) {
1410 return ThrowException(Exception::TypeError(
1411 String::New("Takes 3 parameters")));
1414 if (!Buffer::HasInstance(args[0])) {
1415 return ThrowException(Exception::TypeError(
1416 String::New("Second argument should be a buffer")));
1419 char* buffer_data = Buffer::Data(args[0]);
1420 size_t buffer_length = Buffer::Length(args[0]);
1422 size_t off = args[1]->Int32Value();
1423 size_t len = args[2]->Int32Value();
1424 if (off + len > buffer_length) {
1425 return ThrowException(Exception::Error(
1426 String::New("off + len > buffer.length")));
1429 int bytes_read = BIO_read(ss->bio_write_, buffer_data + off, len);
1431 ss->HandleBIOError(ss->bio_write_, "BIO_read:EncOut", bytes_read);
1432 ss->SetShutdownFlags();
1434 return scope.Close(Integer::New(bytes_read));
1438 Handle<Value> Connection::ClearIn(const Arguments& args) {
1441 Connection *ss = Connection::Unwrap(args);
1443 if (args.Length() < 3) {
1444 return ThrowException(Exception::TypeError(
1445 String::New("Takes 3 parameters")));
1448 if (!Buffer::HasInstance(args[0])) {
1449 return ThrowException(Exception::TypeError(
1450 String::New("Second argument should be a buffer")));
1453 char* buffer_data = Buffer::Data(args[0]);
1454 size_t buffer_length = Buffer::Length(args[0]);
1456 size_t off = args[1]->Int32Value();
1457 size_t len = args[2]->Int32Value();
1458 if (off + len > buffer_length) {
1459 return ThrowException(Exception::Error(
1460 String::New("off + len > buffer.length")));
1463 if (!SSL_is_init_finished(ss->ssl_)) {
1465 if (ss->is_server_) {
1466 rv = SSL_accept(ss->ssl_);
1467 ss->HandleSSLError("SSL_accept:ClearIn", rv, kZeroIsAnError);
1469 rv = SSL_connect(ss->ssl_);
1470 ss->HandleSSLError("SSL_connect:ClearIn", rv, kZeroIsAnError);
1473 if (rv < 0) return scope.Close(Integer::New(rv));
1476 int bytes_written = SSL_write(ss->ssl_, buffer_data + off, len);
1478 ss->HandleSSLError("SSL_write:ClearIn",
1480 len == 0 ? kZeroIsNotAnError : kZeroIsAnError);
1481 ss->SetShutdownFlags();
1483 return scope.Close(Integer::New(bytes_written));
1487 Handle<Value> Connection::GetPeerCertificate(const Arguments& args) {
1490 Connection *ss = Connection::Unwrap(args);
1492 if (ss->ssl_ == NULL) return Undefined();
1493 Local<Object> info = Object::New();
1494 X509* peer_cert = SSL_get_peer_certificate(ss->ssl_);
1495 if (peer_cert != NULL) {
1496 BIO* bio = BIO_new(BIO_s_mem());
1498 if (X509_NAME_print_ex(bio, X509_get_subject_name(peer_cert), 0,
1499 X509_NAME_FLAGS) > 0) {
1500 BIO_get_mem_ptr(bio, &mem);
1501 info->Set(subject_symbol, String::New(mem->data, mem->length));
1503 (void) BIO_reset(bio);
1505 if (X509_NAME_print_ex(bio, X509_get_issuer_name(peer_cert), 0,
1506 X509_NAME_FLAGS) > 0) {
1507 BIO_get_mem_ptr(bio, &mem);
1508 info->Set(issuer_symbol, String::New(mem->data, mem->length));
1510 (void) BIO_reset(bio);
1512 int index = X509_get_ext_by_NID(peer_cert, NID_subject_alt_name, -1);
1514 X509_EXTENSION* ext;
1517 ext = X509_get_ext(peer_cert, index);
1518 assert(ext != NULL);
1520 rv = X509V3_EXT_print(bio, ext, 0, 0);
1523 BIO_get_mem_ptr(bio, &mem);
1524 info->Set(subjectaltname_symbol, String::New(mem->data, mem->length));
1526 (void) BIO_reset(bio);
1529 EVP_PKEY *pkey = NULL;
1531 if( NULL != (pkey = X509_get_pubkey(peer_cert))
1532 && NULL != (rsa = EVP_PKEY_get1_RSA(pkey)) ) {
1533 BN_print(bio, rsa->n);
1534 BIO_get_mem_ptr(bio, &mem);
1535 info->Set(modulus_symbol, String::New(mem->data, mem->length) );
1536 (void) BIO_reset(bio);
1538 BN_print(bio, rsa->e);
1539 BIO_get_mem_ptr(bio, &mem);
1540 info->Set(exponent_symbol, String::New(mem->data, mem->length) );
1541 (void) BIO_reset(bio);
1545 EVP_PKEY_free(pkey);
1553 ASN1_TIME_print(bio, X509_get_notBefore(peer_cert));
1554 BIO_get_mem_ptr(bio, &mem);
1555 info->Set(valid_from_symbol, String::New(mem->data, mem->length));
1556 (void) BIO_reset(bio);
1558 ASN1_TIME_print(bio, X509_get_notAfter(peer_cert));
1559 BIO_get_mem_ptr(bio, &mem);
1560 info->Set(valid_to_symbol, String::New(mem->data, mem->length));
1563 unsigned int md_size, i;
1564 unsigned char md[EVP_MAX_MD_SIZE];
1565 if (X509_digest(peer_cert, EVP_sha1(), md, &md_size)) {
1566 const char hex[] = "0123456789ABCDEF";
1567 char fingerprint[EVP_MAX_MD_SIZE * 3];
1569 for (i=0; i<md_size; i++) {
1570 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1571 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1572 fingerprint[(3*i)+2] = ':';
1576 fingerprint[(3*(md_size-1))+2] = '\0';
1579 fingerprint[0] = '\0';
1582 info->Set(fingerprint_symbol, String::New(fingerprint));
1585 STACK_OF(ASN1_OBJECT) *eku = (STACK_OF(ASN1_OBJECT) *)X509_get_ext_d2i(
1586 peer_cert, NID_ext_key_usage, NULL, NULL);
1588 Local<Array> ext_key_usage = Array::New();
1591 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1592 memset(buf, 0, sizeof(buf));
1593 OBJ_obj2txt(buf, sizeof(buf) - 1, sk_ASN1_OBJECT_value(eku, i), 1);
1594 ext_key_usage->Set(Integer::New(i), String::New(buf));
1597 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1598 info->Set(ext_key_usage_symbol, ext_key_usage);
1601 X509_free(peer_cert);
1603 return scope.Close(info);
1606 Handle<Value> Connection::GetSession(const Arguments& args) {
1609 Connection *ss = Connection::Unwrap(args);
1611 if (ss->ssl_ == NULL) return Undefined();
1613 SSL_SESSION* sess = SSL_get_session(ss->ssl_);
1614 if (!sess) return Undefined();
1616 int slen = i2d_SSL_SESSION(sess, NULL);
1620 unsigned char* sbuf = new unsigned char[slen];
1621 unsigned char* p = sbuf;
1622 i2d_SSL_SESSION(sess, &p);
1623 Local<Value> s = Encode(sbuf, slen, BINARY);
1625 return scope.Close(s);
1631 Handle<Value> Connection::SetSession(const Arguments& args) {
1634 Connection *ss = Connection::Unwrap(args);
1636 if (args.Length() < 1 ||
1637 (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
1638 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
1639 return ThrowException(exception);
1642 ASSERT_IS_BUFFER(args[0]);
1643 ssize_t slen = Buffer::Length(args[0]);
1646 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
1647 return ThrowException(exception);
1650 char* sbuf = new char[slen];
1652 ssize_t wlen = DecodeWrite(sbuf, slen, args[0], BINARY);
1653 assert(wlen == slen);
1655 const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
1656 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, wlen);
1663 int r = SSL_set_session(ss->ssl_, sess);
1664 SSL_SESSION_free(sess);
1667 Local<String> eStr = String::New("SSL_set_session error");
1668 return ThrowException(Exception::Error(eStr));
1674 Handle<Value> Connection::LoadSession(const Arguments& args) {
1677 Connection *ss = Connection::Unwrap(args);
1679 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1680 ssize_t slen = Buffer::Length(args[0].As<Object>());
1681 char* sbuf = Buffer::Data(args[0].As<Object>());
1683 const unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
1684 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, slen);
1686 // Setup next session and move hello to the BIO buffer
1687 if (ss->next_sess_ != NULL) {
1688 SSL_SESSION_free(ss->next_sess_);
1690 ss->next_sess_ = sess;
1693 ss->hello_parser_.Finish();
1698 Handle<Value> Connection::IsSessionReused(const Arguments& args) {
1701 Connection *ss = Connection::Unwrap(args);
1703 if (ss->ssl_ == NULL || SSL_session_reused(ss->ssl_) == false) {
1711 Handle<Value> Connection::Start(const Arguments& args) {
1714 Connection *ss = Connection::Unwrap(args);
1716 if (!SSL_is_init_finished(ss->ssl_)) {
1718 if (ss->is_server_) {
1719 rv = SSL_accept(ss->ssl_);
1720 ss->HandleSSLError("SSL_accept:Start", rv, kZeroIsAnError);
1722 rv = SSL_connect(ss->ssl_);
1723 ss->HandleSSLError("SSL_connect:Start", rv, kZeroIsAnError);
1726 return scope.Close(Integer::New(rv));
1729 return scope.Close(Integer::New(0));
1733 Handle<Value> Connection::Shutdown(const Arguments& args) {
1736 Connection *ss = Connection::Unwrap(args);
1738 if (ss->ssl_ == NULL) return False();
1739 int rv = SSL_shutdown(ss->ssl_);
1740 ss->HandleSSLError("SSL_shutdown", rv, kZeroIsNotAnError);
1741 ss->SetShutdownFlags();
1743 return scope.Close(Integer::New(rv));
1747 Handle<Value> Connection::ReceivedShutdown(const Arguments& args) {
1750 Connection *ss = Connection::Unwrap(args);
1752 if (ss->ssl_ == NULL) return False();
1753 int r = SSL_get_shutdown(ss->ssl_);
1755 if (r & SSL_RECEIVED_SHUTDOWN) return True();
1761 Handle<Value> Connection::IsInitFinished(const Arguments& args) {
1764 Connection *ss = Connection::Unwrap(args);
1766 if (ss->ssl_ == NULL || SSL_is_init_finished(ss->ssl_) == false) {
1774 Handle<Value> Connection::VerifyError(const Arguments& args) {
1777 Connection *ss = Connection::Unwrap(args);
1779 if (ss->ssl_ == NULL) return Null();
1782 // XXX Do this check in JS land?
1783 X509* peer_cert = SSL_get_peer_certificate(ss->ssl_);
1784 if (peer_cert == NULL) {
1785 // We requested a certificate and they did not send us one.
1786 // Definitely an error.
1787 // XXX is this the right error message?
1788 return scope.Close(Exception::Error(
1789 String::New("UNABLE_TO_GET_ISSUER_CERT")));
1791 X509_free(peer_cert);
1794 long x509_verify_error = SSL_get_verify_result(ss->ssl_);
1798 switch (x509_verify_error) {
1802 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1803 s = String::New("UNABLE_TO_GET_ISSUER_CERT");
1806 case X509_V_ERR_UNABLE_TO_GET_CRL:
1807 s = String::New("UNABLE_TO_GET_CRL");
1810 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1811 s = String::New("UNABLE_TO_DECRYPT_CERT_SIGNATURE");
1814 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1815 s = String::New("UNABLE_TO_DECRYPT_CRL_SIGNATURE");
1818 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1819 s = String::New("UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY");
1822 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1823 s = String::New("CERT_SIGNATURE_FAILURE");
1826 case X509_V_ERR_CRL_SIGNATURE_FAILURE:
1827 s = String::New("CRL_SIGNATURE_FAILURE");
1830 case X509_V_ERR_CERT_NOT_YET_VALID:
1831 s = String::New("CERT_NOT_YET_VALID");
1834 case X509_V_ERR_CERT_HAS_EXPIRED:
1835 s = String::New("CERT_HAS_EXPIRED");
1838 case X509_V_ERR_CRL_NOT_YET_VALID:
1839 s = String::New("CRL_NOT_YET_VALID");
1842 case X509_V_ERR_CRL_HAS_EXPIRED:
1843 s = String::New("CRL_HAS_EXPIRED");
1846 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1847 s = String::New("ERROR_IN_CERT_NOT_BEFORE_FIELD");
1850 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1851 s = String::New("ERROR_IN_CERT_NOT_AFTER_FIELD");
1854 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1855 s = String::New("ERROR_IN_CRL_LAST_UPDATE_FIELD");
1858 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1859 s = String::New("ERROR_IN_CRL_NEXT_UPDATE_FIELD");
1862 case X509_V_ERR_OUT_OF_MEM:
1863 s = String::New("OUT_OF_MEM");
1866 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1867 s = String::New("DEPTH_ZERO_SELF_SIGNED_CERT");
1870 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1871 s = String::New("SELF_SIGNED_CERT_IN_CHAIN");
1874 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1875 s = String::New("UNABLE_TO_GET_ISSUER_CERT_LOCALLY");
1878 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1879 s = String::New("UNABLE_TO_VERIFY_LEAF_SIGNATURE");
1882 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1883 s = String::New("CERT_CHAIN_TOO_LONG");
1886 case X509_V_ERR_CERT_REVOKED:
1887 s = String::New("CERT_REVOKED");
1890 case X509_V_ERR_INVALID_CA:
1891 s = String::New("INVALID_CA");
1894 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1895 s = String::New("PATH_LENGTH_EXCEEDED");
1898 case X509_V_ERR_INVALID_PURPOSE:
1899 s = String::New("INVALID_PURPOSE");
1902 case X509_V_ERR_CERT_UNTRUSTED:
1903 s = String::New("CERT_UNTRUSTED");
1906 case X509_V_ERR_CERT_REJECTED:
1907 s = String::New("CERT_REJECTED");
1911 s = String::New(X509_verify_cert_error_string(x509_verify_error));
1915 return scope.Close(Exception::Error(s));
1919 Handle<Value> Connection::GetCurrentCipher(const Arguments& args) {
1922 Connection *ss = Connection::Unwrap(args);
1924 OPENSSL_CONST SSL_CIPHER *c;
1926 if ( ss->ssl_ == NULL ) return Undefined();
1927 c = SSL_get_current_cipher(ss->ssl_);
1928 if ( c == NULL ) return Undefined();
1929 Local<Object> info = Object::New();
1930 const char* cipher_name = SSL_CIPHER_get_name(c);
1931 info->Set(name_symbol, String::New(cipher_name));
1932 const char* cipher_version = SSL_CIPHER_get_version(c);
1933 info->Set(version_symbol, String::New(cipher_version));
1934 return scope.Close(info);
1937 Handle<Value> Connection::Close(const Arguments& args) {
1940 Connection *ss = Connection::Unwrap(args);
1942 if (ss->ssl_ != NULL) {
1949 #ifdef OPENSSL_NPN_NEGOTIATED
1950 Handle<Value> Connection::GetNegotiatedProto(const Arguments& args) {
1953 Connection *ss = Connection::Unwrap(args);
1955 if (ss->is_server_) {
1956 const unsigned char* npn_proto;
1957 unsigned int npn_proto_len;
1959 SSL_get0_next_proto_negotiated(ss->ssl_, &npn_proto, &npn_proto_len);
1965 return scope.Close(String::New(reinterpret_cast<const char*>(npn_proto),
1968 return ss->selectedNPNProto_;
1972 Handle<Value> Connection::SetNPNProtocols(const Arguments& args) {
1975 Connection *ss = Connection::Unwrap(args);
1977 if (args.Length() < 1 || !Buffer::HasInstance(args[0])) {
1978 return ThrowException(Exception::Error(String::New(
1979 "Must give a Buffer as first argument")));
1982 // Release old handle
1983 if (!ss->npnProtos_.IsEmpty()) {
1984 ss->npnProtos_.Dispose();
1986 ss->npnProtos_ = Persistent<Object>::New(args[0]->ToObject());
1992 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1993 Handle<Value> Connection::GetServername(const Arguments& args) {
1996 Connection *ss = Connection::Unwrap(args);
1998 if (ss->is_server_ && !ss->servername_.IsEmpty()) {
1999 return ss->servername_;
2005 Handle<Value> Connection::SetSNICallback(const Arguments& args) {
2008 Connection *ss = Connection::Unwrap(args);
2010 if (args.Length() < 1 || !args[0]->IsFunction()) {
2011 return ThrowException(Exception::Error(String::New(
2012 "Must give a Function as first argument")));
2015 // Release old handle
2016 if (!ss->sniObject_.IsEmpty()) {
2017 ss->sniObject_.Dispose();
2019 ss->sniObject_ = Persistent<Object>::New(Object::New());
2020 ss->sniObject_->Set(String::New("onselect"), args[0]);
2027 class Cipher : public ObjectWrap {
2029 static void Initialize (v8::Handle<v8::Object> target) {
2032 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2034 t->InstanceTemplate()->SetInternalFieldCount(1);
2036 NODE_SET_PROTOTYPE_METHOD(t, "init", CipherInit);
2037 NODE_SET_PROTOTYPE_METHOD(t, "initiv", CipherInitIv);
2038 NODE_SET_PROTOTYPE_METHOD(t, "update", CipherUpdate);
2039 NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
2040 NODE_SET_PROTOTYPE_METHOD(t, "final", CipherFinal);
2042 target->Set(String::NewSymbol("Cipher"), t->GetFunction());
2046 bool CipherInit(char* cipherType, char* key_buf, int key_buf_len) {
2047 cipher = EVP_get_cipherbyname(cipherType);
2049 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2053 unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
2054 int key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL,
2055 (unsigned char*) key_buf, key_buf_len, 1, key, iv);
2057 EVP_CIPHER_CTX_init(&ctx);
2058 EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, NULL, true);
2059 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2060 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2061 EVP_CIPHER_CTX_cleanup(&ctx);
2064 EVP_CipherInit_ex(&ctx, NULL, NULL,
2065 (unsigned char*)key,
2066 (unsigned char*)iv, true);
2067 initialised_ = true;
2072 bool CipherInitIv(char* cipherType,
2077 cipher = EVP_get_cipherbyname(cipherType);
2079 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2082 /* OpenSSL versions up to 0.9.8l failed to return the correct
2083 iv_length (0) for ECB ciphers */
2084 if (EVP_CIPHER_iv_length(cipher) != iv_len &&
2085 !(EVP_CIPHER_mode(cipher) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2086 fprintf(stderr, "node-crypto : Invalid IV length %d\n", iv_len);
2089 EVP_CIPHER_CTX_init(&ctx);
2090 EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, NULL, true);
2091 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2092 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2093 EVP_CIPHER_CTX_cleanup(&ctx);
2096 EVP_CipherInit_ex(&ctx, NULL, NULL,
2097 (unsigned char*)key,
2098 (unsigned char*)iv, true);
2099 initialised_ = true;
2103 int CipherUpdate(char* data, int len, unsigned char** out, int* out_len) {
2104 if (!initialised_) return 0;
2105 *out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
2106 *out= new unsigned char[*out_len];
2107 return EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
2110 int SetAutoPadding(bool auto_padding) {
2111 if (!initialised_) return 0;
2112 return EVP_CIPHER_CTX_set_padding(&ctx, auto_padding ? 1 : 0);
2115 int CipherFinal(unsigned char** out, int *out_len) {
2116 if (!initialised_) return 0;
2117 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx)];
2118 int r = EVP_CipherFinal_ex(&ctx,*out, out_len);
2119 EVP_CIPHER_CTX_cleanup(&ctx);
2120 initialised_ = false;
2127 static Handle<Value> New(const Arguments& args) {
2130 Cipher *cipher = new Cipher();
2131 cipher->Wrap(args.This());
2135 static Handle<Value> CipherInit(const Arguments& args) {
2138 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2140 if (args.Length() <= 1
2141 || !args[0]->IsString()
2142 || !(args[1]->IsString() || Buffer::HasInstance(args[1])))
2144 return ThrowException(Exception::Error(String::New(
2145 "Must give cipher-type, key")));
2148 ASSERT_IS_BUFFER(args[1]);
2149 ssize_t key_buf_len = Buffer::Length(args[1]);
2151 if (key_buf_len < 0) {
2152 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2153 return ThrowException(exception);
2156 char* key_buf = new char[key_buf_len];
2157 ssize_t key_written = DecodeWrite(key_buf, key_buf_len, args[1], BINARY);
2158 assert(key_written == key_buf_len);
2160 String::Utf8Value cipherType(args[0]);
2162 bool r = cipher->CipherInit(*cipherType, key_buf, key_buf_len);
2166 if (!r) return ThrowCryptoError(ERR_get_error());
2172 static Handle<Value> CipherInitIv(const Arguments& args) {
2173 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2178 if (args.Length() <= 2
2179 || !args[0]->IsString()
2180 || !(args[1]->IsString() || Buffer::HasInstance(args[1]))
2181 || !(args[2]->IsString() || Buffer::HasInstance(args[2])))
2183 return ThrowException(Exception::Error(String::New(
2184 "Must give cipher-type, key, and iv as argument")));
2187 ASSERT_IS_BUFFER(args[1]);
2188 ssize_t key_len = Buffer::Length(args[1]);
2191 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2192 return ThrowException(exception);
2195 ASSERT_IS_BUFFER(args[2]);
2196 ssize_t iv_len = Buffer::Length(args[2]);
2199 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2200 return ThrowException(exception);
2203 char* key_buf = new char[key_len];
2204 ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY);
2205 assert(key_written == key_len);
2207 char* iv_buf = new char[iv_len];
2208 ssize_t iv_written = DecodeWrite(iv_buf, iv_len, args[2], BINARY);
2209 assert(iv_written == iv_len);
2211 String::Utf8Value cipherType(args[0]);
2213 bool r = cipher->CipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
2218 if (!r) return ThrowCryptoError(ERR_get_error());
2223 static Handle<Value> CipherUpdate(const Arguments& args) {
2224 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2228 ASSERT_IS_BUFFER(args[0]);
2230 unsigned char* out=0;
2232 char* buffer_data = Buffer::Data(args[0]);
2233 size_t buffer_length = Buffer::Length(args[0]);
2235 r = cipher->CipherUpdate(buffer_data, buffer_length, &out, &out_len);
2239 return ThrowCryptoTypeError(ERR_get_error());
2242 Local<Value> outString;
2243 outString = Encode(out, out_len, BUFFER);
2245 if (out) delete [] out;
2247 return scope.Close(outString);
2250 static Handle<Value> SetAutoPadding(const Arguments& args) {
2252 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2254 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2259 static Handle<Value> CipherFinal(const Arguments& args) {
2260 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2264 unsigned char* out_value = NULL;
2266 Local<Value> outString ;
2268 int r = cipher->CipherFinal(&out_value, &out_len);
2270 if (out_len <= 0 || r == 0) {
2273 if (r == 0) return ThrowCryptoTypeError(ERR_get_error());
2276 outString = Encode(out_value, out_len, BUFFER);
2278 delete [] out_value;
2279 return scope.Close(outString);
2282 Cipher () : ObjectWrap ()
2284 initialised_ = false;
2289 EVP_CIPHER_CTX_cleanup(&ctx);
2295 EVP_CIPHER_CTX ctx; /* coverity[member_decl] */
2296 const EVP_CIPHER *cipher; /* coverity[member_decl] */
2302 class Decipher : public ObjectWrap {
2305 Initialize (v8::Handle<v8::Object> target)
2309 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2311 t->InstanceTemplate()->SetInternalFieldCount(1);
2313 NODE_SET_PROTOTYPE_METHOD(t, "init", DecipherInit);
2314 NODE_SET_PROTOTYPE_METHOD(t, "initiv", DecipherInitIv);
2315 NODE_SET_PROTOTYPE_METHOD(t, "update", DecipherUpdate);
2316 NODE_SET_PROTOTYPE_METHOD(t, "final", DecipherFinal);
2317 NODE_SET_PROTOTYPE_METHOD(t, "finaltol", DecipherFinal); // remove someday
2318 NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
2320 target->Set(String::NewSymbol("Decipher"), t->GetFunction());
2323 bool DecipherInit(char* cipherType, char* key_buf, int key_buf_len) {
2324 cipher_ = EVP_get_cipherbyname(cipherType);
2327 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2331 unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
2332 int key_len = EVP_BytesToKey(cipher_,
2335 (unsigned char*)(key_buf),
2341 EVP_CIPHER_CTX_init(&ctx);
2342 EVP_CipherInit_ex(&ctx, cipher_, NULL, NULL, NULL, false);
2343 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2344 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2345 EVP_CIPHER_CTX_cleanup(&ctx);
2348 EVP_CipherInit_ex(&ctx, NULL, NULL,
2349 (unsigned char*)key,
2350 (unsigned char*)iv, false);
2351 initialised_ = true;
2356 bool DecipherInitIv(char* cipherType,
2361 cipher_ = EVP_get_cipherbyname(cipherType);
2363 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2366 /* OpenSSL versions up to 0.9.8l failed to return the correct
2367 iv_length (0) for ECB ciphers */
2368 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
2369 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2370 fprintf(stderr, "node-crypto : Invalid IV length %d\n", iv_len);
2373 EVP_CIPHER_CTX_init(&ctx);
2374 EVP_CipherInit_ex(&ctx, cipher_, NULL, NULL, NULL, false);
2375 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2376 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2377 EVP_CIPHER_CTX_cleanup(&ctx);
2380 EVP_CipherInit_ex(&ctx, NULL, NULL,
2381 (unsigned char*)key,
2382 (unsigned char*)iv, false);
2383 initialised_ = true;
2387 int DecipherUpdate(char* data, int len, unsigned char** out, int* out_len) {
2388 if (!initialised_) {
2394 *out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
2395 *out= new unsigned char[*out_len];
2397 return EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
2400 int SetAutoPadding(bool auto_padding) {
2401 if (!initialised_) return 0;
2402 return EVP_CIPHER_CTX_set_padding(&ctx, auto_padding ? 1 : 0);
2405 // coverity[alloc_arg]
2406 int DecipherFinal(unsigned char** out, int *out_len) {
2409 if (!initialised_) {
2415 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx)];
2416 r = EVP_CipherFinal_ex(&ctx,*out,out_len);
2417 EVP_CIPHER_CTX_cleanup(&ctx);
2418 initialised_ = false;
2425 static Handle<Value> New (const Arguments& args) {
2428 Decipher *cipher = new Decipher();
2429 cipher->Wrap(args.This());
2433 static Handle<Value> DecipherInit(const Arguments& args) {
2434 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2438 if (args.Length() <= 1
2439 || !args[0]->IsString()
2440 || !(args[1]->IsString() || Buffer::HasInstance(args[1])))
2442 return ThrowException(Exception::Error(String::New(
2443 "Must give cipher-type, key as argument")));
2446 ASSERT_IS_BUFFER(args[1]);
2447 ssize_t key_len = Buffer::Length(args[1]);
2450 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2451 return ThrowException(exception);
2454 char* key_buf = new char[key_len];
2455 ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY);
2456 assert(key_written == key_len);
2458 String::Utf8Value cipherType(args[0]);
2460 bool r = cipher->DecipherInit(*cipherType, key_buf,key_len);
2465 return ThrowException(Exception::Error(String::New("DecipherInit error")));
2471 static Handle<Value> DecipherInitIv(const Arguments& args) {
2472 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2476 if (args.Length() <= 2
2477 || !args[0]->IsString()
2478 || !(args[1]->IsString() || Buffer::HasInstance(args[1]))
2479 || !(args[2]->IsString() || Buffer::HasInstance(args[2])))
2481 return ThrowException(Exception::Error(String::New(
2482 "Must give cipher-type, key, and iv as argument")));
2485 ASSERT_IS_BUFFER(args[1]);
2486 ssize_t key_len = Buffer::Length(args[1]);
2489 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2490 return ThrowException(exception);
2493 ASSERT_IS_BUFFER(args[2]);
2494 ssize_t iv_len = Buffer::Length(args[2]);
2497 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2498 return ThrowException(exception);
2501 char* key_buf = new char[key_len];
2502 ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY);
2503 assert(key_written == key_len);
2505 char* iv_buf = new char[iv_len];
2506 ssize_t iv_written = DecodeWrite(iv_buf, iv_len, args[2], BINARY);
2507 assert(iv_written == iv_len);
2509 String::Utf8Value cipherType(args[0]);
2511 bool r = cipher->DecipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
2517 return ThrowException(Exception::Error(String::New("DecipherInitIv error")));
2523 static Handle<Value> DecipherUpdate(const Arguments& args) {
2526 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2528 ASSERT_IS_BUFFER(args[0]);
2533 // if alloc_buf then buf must be deleted later
2534 bool alloc_buf = false;
2535 char* buffer_data = Buffer::Data(args[0]);
2536 size_t buffer_length = Buffer::Length(args[0]);
2539 len = buffer_length;
2541 unsigned char* out=0;
2543 int r = cipher->DecipherUpdate(buf, len, &out, &out_len);
2547 return ThrowCryptoTypeError(ERR_get_error());
2550 Local<Value> outString;
2551 outString = Encode(out, out_len, BUFFER);
2553 if (out) delete [] out;
2555 if (alloc_buf) delete [] buf;
2556 return scope.Close(outString);
2560 static Handle<Value> SetAutoPadding(const Arguments& args) {
2562 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2564 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2569 static Handle<Value> DecipherFinal(const Arguments& args) {
2572 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2574 unsigned char* out_value = NULL;
2576 Local<Value> outString;
2578 int r = cipher->DecipherFinal(&out_value, &out_len);
2580 if (out_len <= 0 || r == 0) {
2581 delete [] out_value; // allocated even if out_len == 0
2583 if (r == 0) return ThrowCryptoTypeError(ERR_get_error());
2586 outString = Encode(out_value, out_len, BUFFER);
2587 delete [] out_value;
2588 return scope.Close(outString);
2591 Decipher () : ObjectWrap () {
2592 initialised_ = false;
2597 EVP_CIPHER_CTX_cleanup(&ctx);
2604 const EVP_CIPHER *cipher_;
2611 class Hmac : public ObjectWrap {
2613 static void Initialize (v8::Handle<v8::Object> target) {
2616 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2618 t->InstanceTemplate()->SetInternalFieldCount(1);
2620 NODE_SET_PROTOTYPE_METHOD(t, "init", HmacInit);
2621 NODE_SET_PROTOTYPE_METHOD(t, "update", HmacUpdate);
2622 NODE_SET_PROTOTYPE_METHOD(t, "digest", HmacDigest);
2624 target->Set(String::NewSymbol("Hmac"), t->GetFunction());
2627 bool HmacInit(char* hashType, char* key, int key_len) {
2628 md = EVP_get_digestbyname(hashType);
2630 fprintf(stderr, "node-crypto : Unknown message digest %s\n", hashType);
2633 HMAC_CTX_init(&ctx);
2635 HMAC_Init(&ctx, "", 0, md);
2637 HMAC_Init(&ctx, key, key_len, md);
2639 initialised_ = true;
2644 int HmacUpdate(char* data, int len) {
2645 if (!initialised_) return 0;
2646 HMAC_Update(&ctx, (unsigned char*)data, len);
2650 int HmacDigest(unsigned char** md_value, unsigned int *md_len) {
2651 if (!initialised_) return 0;
2652 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
2653 HMAC_Final(&ctx, *md_value, md_len);
2654 HMAC_CTX_cleanup(&ctx);
2655 initialised_ = false;
2662 static Handle<Value> New (const Arguments& args) {
2665 Hmac *hmac = new Hmac();
2666 hmac->Wrap(args.This());
2670 static Handle<Value> HmacInit(const Arguments& args) {
2671 Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());
2675 if (args.Length() == 0 || !args[0]->IsString()) {
2676 return ThrowException(Exception::Error(String::New(
2677 "Must give hashtype string as argument")));
2680 ASSERT_IS_BUFFER(args[1]);
2681 ssize_t len = Buffer::Length(args[1]);
2684 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2685 return ThrowException(exception);
2688 String::Utf8Value hashType(args[0]);
2692 if( Buffer::HasInstance(args[1])) {
2693 char* buffer_data = Buffer::Data(args[1]);
2694 size_t buffer_length = Buffer::Length(args[1]);
2696 r = hmac->HmacInit(*hashType, buffer_data, buffer_length);
2698 char* buf = new char[len];
2699 ssize_t written = DecodeWrite(buf, len, args[1], BINARY);
2700 assert(written == len);
2702 r = hmac->HmacInit(*hashType, buf, len);
2708 return ThrowException(Exception::Error(String::New("hmac error")));
2714 static Handle<Value> HmacUpdate(const Arguments& args) {
2715 Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());
2719 ASSERT_IS_BUFFER(args[0]);
2723 char* buffer_data = Buffer::Data(args[0]);
2724 size_t buffer_length = Buffer::Length(args[0]);
2726 r = hmac->HmacUpdate(buffer_data, buffer_length);
2729 Local<Value> exception = Exception::TypeError(String::New("HmacUpdate fail"));
2730 return ThrowException(exception);
2736 static Handle<Value> HmacDigest(const Arguments& args) {
2737 Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());
2741 unsigned char* md_value = NULL;
2742 unsigned int md_len = 0;
2743 Local<Value> outString;
2745 int r = hmac->HmacDigest(&md_value, &md_len);
2751 outString = Encode(md_value, md_len, BUFFER);
2754 return scope.Close(outString);
2757 Hmac () : ObjectWrap () {
2758 initialised_ = false;
2763 HMAC_CTX_cleanup(&ctx);
2769 HMAC_CTX ctx; /* coverity[member_decl] */
2770 const EVP_MD *md; /* coverity[member_decl] */
2775 class Hash : public ObjectWrap {
2777 static void Initialize (v8::Handle<v8::Object> target) {
2780 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2782 t->InstanceTemplate()->SetInternalFieldCount(1);
2784 NODE_SET_PROTOTYPE_METHOD(t, "update", HashUpdate);
2785 NODE_SET_PROTOTYPE_METHOD(t, "digest", HashDigest);
2787 target->Set(String::NewSymbol("Hash"), t->GetFunction());
2790 bool HashInit (const char* hashType) {
2791 md = EVP_get_digestbyname(hashType);
2792 if(!md) return false;
2793 EVP_MD_CTX_init(&mdctx);
2794 EVP_DigestInit_ex(&mdctx, md, NULL);
2795 initialised_ = true;
2799 int HashUpdate(char* data, int len) {
2800 if (!initialised_) return 0;
2801 EVP_DigestUpdate(&mdctx, data, len);
2808 static Handle<Value> New (const Arguments& args) {
2811 if (args.Length() == 0 || !args[0]->IsString()) {
2812 return ThrowException(Exception::Error(String::New(
2813 "Must give hashtype string as argument")));
2816 String::Utf8Value hashType(args[0]);
2818 Hash *hash = new Hash();
2819 if (!hash->HashInit(*hashType)) {
2821 return ThrowException(Exception::Error(String::New(
2822 "Digest method not supported")));
2825 hash->Wrap(args.This());
2829 static Handle<Value> HashUpdate(const Arguments& args) {
2832 Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
2834 ASSERT_IS_BUFFER(args[0]);
2838 char* buffer_data = Buffer::Data(args[0]);
2839 size_t buffer_length = Buffer::Length(args[0]);
2840 r = hash->HashUpdate(buffer_data, buffer_length);
2843 Local<Value> exception = Exception::TypeError(String::New("HashUpdate fail"));
2844 return ThrowException(exception);
2850 static Handle<Value> HashDigest(const Arguments& args) {
2853 Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
2855 if (!hash->initialised_) {
2856 return ThrowException(Exception::Error(String::New("Not initialized")));
2859 unsigned char md_value[EVP_MAX_MD_SIZE];
2860 unsigned int md_len;
2862 EVP_DigestFinal_ex(&hash->mdctx, md_value, &md_len);
2863 EVP_MD_CTX_cleanup(&hash->mdctx);
2864 hash->initialised_ = false;
2866 Local<Value> outString;
2868 outString = Encode(md_value, md_len, BUFFER);
2870 return scope.Close(outString);
2873 Hash () : ObjectWrap () {
2874 initialised_ = false;
2879 EVP_MD_CTX_cleanup(&mdctx);
2885 EVP_MD_CTX mdctx; /* coverity[member_decl] */
2886 const EVP_MD *md; /* coverity[member_decl] */
2890 class Sign : public ObjectWrap {
2893 Initialize (v8::Handle<v8::Object> target) {
2896 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2898 t->InstanceTemplate()->SetInternalFieldCount(1);
2900 NODE_SET_PROTOTYPE_METHOD(t, "init", SignInit);
2901 NODE_SET_PROTOTYPE_METHOD(t, "update", SignUpdate);
2902 NODE_SET_PROTOTYPE_METHOD(t, "sign", SignFinal);
2904 target->Set(String::NewSymbol("Sign"), t->GetFunction());
2907 bool SignInit (const char* signType) {
2908 md = EVP_get_digestbyname(signType);
2910 printf("Unknown message digest %s\n", signType);
2913 EVP_MD_CTX_init(&mdctx);
2914 EVP_SignInit_ex(&mdctx, md, NULL);
2915 initialised_ = true;
2920 int SignUpdate(char* data, int len) {
2921 if (!initialised_) return 0;
2922 EVP_SignUpdate(&mdctx, data, len);
2926 int SignFinal(unsigned char** md_value,
2927 unsigned int *md_len,
2930 if (!initialised_) return 0;
2934 bp = BIO_new(BIO_s_mem());
2935 if(!BIO_write(bp, key_pem, key_pemLen)) return 0;
2937 pkey = PEM_read_bio_PrivateKey( bp, NULL, NULL, NULL );
2938 if (pkey == NULL) return 0;
2940 EVP_SignFinal(&mdctx, *md_value, md_len, pkey);
2941 EVP_MD_CTX_cleanup(&mdctx);
2942 initialised_ = false;
2943 EVP_PKEY_free(pkey);
2951 static Handle<Value> New (const Arguments& args) {
2954 Sign *sign = new Sign();
2955 sign->Wrap(args.This());
2960 static Handle<Value> SignInit(const Arguments& args) {
2963 Sign *sign = ObjectWrap::Unwrap<Sign>(args.This());
2965 if (args.Length() == 0 || !args[0]->IsString()) {
2966 return ThrowException(Exception::Error(String::New(
2967 "Must give signtype string as argument")));
2970 String::Utf8Value signType(args[0]);
2972 bool r = sign->SignInit(*signType);
2975 return ThrowException(Exception::Error(String::New("SignInit error")));
2981 static Handle<Value> SignUpdate(const Arguments& args) {
2982 Sign *sign = ObjectWrap::Unwrap<Sign>(args.This());
2986 ASSERT_IS_BUFFER(args[0]);
2990 char* buffer_data = Buffer::Data(args[0]);
2991 size_t buffer_length = Buffer::Length(args[0]);
2993 r = sign->SignUpdate(buffer_data, buffer_length);
2996 Local<Value> exception = Exception::TypeError(String::New("SignUpdate fail"));
2997 return ThrowException(exception);
3003 static Handle<Value> SignFinal(const Arguments& args) {
3004 Sign *sign = ObjectWrap::Unwrap<Sign>(args.This());
3008 unsigned char* md_value;
3009 unsigned int md_len;
3010 Local<Value> outString;
3012 md_len = 8192; // Maximum key size is 8192 bits
3013 md_value = new unsigned char[md_len];
3015 ASSERT_IS_BUFFER(args[0]);
3016 ssize_t len = Buffer::Length(args[0]);
3018 char* buf = new char[len];
3019 ssize_t written = DecodeWrite(buf, len, args[0], BUFFER);
3020 assert(written == len);
3022 int r = sign->SignFinal(&md_value, &md_len, buf, len);
3030 outString = Encode(md_value, md_len, BUFFER);
3033 return scope.Close(outString);
3036 Sign () : ObjectWrap () {
3037 initialised_ = false;
3042 EVP_MD_CTX_cleanup(&mdctx);
3048 EVP_MD_CTX mdctx; /* coverity[member_decl] */
3049 const EVP_MD *md; /* coverity[member_decl] */
3053 class Verify : public ObjectWrap {
3055 static void Initialize (v8::Handle<v8::Object> target) {
3058 Local<FunctionTemplate> t = FunctionTemplate::New(New);
3060 t->InstanceTemplate()->SetInternalFieldCount(1);
3062 NODE_SET_PROTOTYPE_METHOD(t, "init", VerifyInit);
3063 NODE_SET_PROTOTYPE_METHOD(t, "update", VerifyUpdate);
3064 NODE_SET_PROTOTYPE_METHOD(t, "verify", VerifyFinal);
3066 target->Set(String::NewSymbol("Verify"), t->GetFunction());
3070 bool VerifyInit (const char* verifyType) {
3071 md = EVP_get_digestbyname(verifyType);
3073 fprintf(stderr, "node-crypto : Unknown message digest %s\n", verifyType);
3076 EVP_MD_CTX_init(&mdctx);
3077 EVP_VerifyInit_ex(&mdctx, md, NULL);
3078 initialised_ = true;
3083 int VerifyUpdate(char* data, int len) {
3084 if (!initialised_) return 0;
3085 EVP_VerifyUpdate(&mdctx, data, len);
3090 int VerifyFinal(char* key_pem, int key_pemLen, unsigned char* sig, int siglen) {
3091 if (!initialised_) return 0;
3093 EVP_PKEY* pkey = NULL;
3098 bp = BIO_new(BIO_s_mem());
3100 ERR_print_errors_fp(stderr);
3103 if(!BIO_write(bp, key_pem, key_pemLen)) {
3104 ERR_print_errors_fp(stderr);
3108 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3109 // Split this out into a separate function once we have more than one
3110 // consumer of public keys.
3111 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3112 pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
3114 ERR_print_errors_fp(stderr);
3117 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3118 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
3120 pkey = EVP_PKEY_new();
3121 if (pkey) EVP_PKEY_set1_RSA(pkey, rsa);
3125 ERR_print_errors_fp(stderr);
3130 x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
3132 ERR_print_errors_fp(stderr);
3136 pkey = X509_get_pubkey(x509);
3138 ERR_print_errors_fp(stderr);
3143 r = EVP_VerifyFinal(&mdctx, sig, siglen, pkey);
3146 EVP_PKEY_free (pkey);
3151 EVP_MD_CTX_cleanup(&mdctx);
3152 initialised_ = false;
3160 static Handle<Value> New (const Arguments& args) {
3163 Verify *verify = new Verify();
3164 verify->Wrap(args.This());
3170 static Handle<Value> VerifyInit(const Arguments& args) {
3171 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
3175 if (args.Length() == 0 || !args[0]->IsString()) {
3176 return ThrowException(Exception::Error(String::New(
3177 "Must give verifytype string as argument")));
3180 String::Utf8Value verifyType(args[0]);
3182 bool r = verify->VerifyInit(*verifyType);
3185 return ThrowException(Exception::Error(String::New("VerifyInit error")));
3192 static Handle<Value> VerifyUpdate(const Arguments& args) {
3195 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
3197 ASSERT_IS_BUFFER(args[0]);
3201 char* buffer_data = Buffer::Data(args[0]);
3202 size_t buffer_length = Buffer::Length(args[0]);
3204 r = verify->VerifyUpdate(buffer_data, buffer_length);
3207 Local<Value> exception = Exception::TypeError(String::New("VerifyUpdate fail"));
3208 return ThrowException(exception);
3215 static Handle<Value> VerifyFinal(const Arguments& args) {
3218 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
3220 ASSERT_IS_BUFFER(args[0]);
3221 ssize_t klen = Buffer::Length(args[0]);
3224 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3225 return ThrowException(exception);
3228 char* kbuf = new char[klen];
3229 ssize_t kwritten = DecodeWrite(kbuf, klen, args[0], BINARY);
3230 assert(kwritten == klen);
3232 ASSERT_IS_BUFFER(args[1]);
3233 ssize_t hlen = Buffer::Length(args[1]);
3237 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3238 return ThrowException(exception);
3241 unsigned char* hbuf = new unsigned char[hlen];
3242 ssize_t hwritten = DecodeWrite((char*)hbuf, hlen, args[1], BINARY);
3243 assert(hwritten == hlen);
3247 r = verify->VerifyFinal(kbuf, klen, hbuf, hlen);
3252 return Boolean::New(r && r != -1);
3255 Verify () : ObjectWrap () {
3256 initialised_ = false;
3261 EVP_MD_CTX_cleanup(&mdctx);
3267 EVP_MD_CTX mdctx; /* coverity[member_decl] */
3268 const EVP_MD *md; /* coverity[member_decl] */
3273 class DiffieHellman : public ObjectWrap {
3275 static void Initialize(v8::Handle<v8::Object> target) {
3278 Local<FunctionTemplate> t = FunctionTemplate::New(New);
3280 t->InstanceTemplate()->SetInternalFieldCount(1);
3282 NODE_SET_PROTOTYPE_METHOD(t, "generateKeys", GenerateKeys);
3283 NODE_SET_PROTOTYPE_METHOD(t, "computeSecret", ComputeSecret);
3284 NODE_SET_PROTOTYPE_METHOD(t, "getPrime", GetPrime);
3285 NODE_SET_PROTOTYPE_METHOD(t, "getGenerator", GetGenerator);
3286 NODE_SET_PROTOTYPE_METHOD(t, "getPublicKey", GetPublicKey);
3287 NODE_SET_PROTOTYPE_METHOD(t, "getPrivateKey", GetPrivateKey);
3288 NODE_SET_PROTOTYPE_METHOD(t, "setPublicKey", SetPublicKey);
3289 NODE_SET_PROTOTYPE_METHOD(t, "setPrivateKey", SetPrivateKey);
3291 target->Set(String::NewSymbol("DiffieHellman"), t->GetFunction());
3293 Local<FunctionTemplate> t2 = FunctionTemplate::New(DiffieHellmanGroup);
3294 t2->InstanceTemplate()->SetInternalFieldCount(1);
3296 NODE_SET_PROTOTYPE_METHOD(t2, "generateKeys", GenerateKeys);
3297 NODE_SET_PROTOTYPE_METHOD(t2, "computeSecret", ComputeSecret);
3298 NODE_SET_PROTOTYPE_METHOD(t2, "getPrime", GetPrime);
3299 NODE_SET_PROTOTYPE_METHOD(t2, "getGenerator", GetGenerator);
3300 NODE_SET_PROTOTYPE_METHOD(t2, "getPublicKey", GetPublicKey);
3301 NODE_SET_PROTOTYPE_METHOD(t2, "getPrivateKey", GetPrivateKey);
3303 target->Set(String::NewSymbol("DiffieHellmanGroup"), t2->GetFunction());
3306 bool Init(int primeLength) {
3308 DH_generate_parameters_ex(dh, primeLength, DH_GENERATOR_2, 0);
3309 bool result = VerifyContext();
3310 if (!result) return false;
3311 initialised_ = true;
3315 bool Init(unsigned char* p, int p_len) {
3317 dh->p = BN_bin2bn(p, p_len, 0);
3319 if (!BN_set_word(dh->g, 2)) return false;
3320 bool result = VerifyContext();
3321 if (!result) return false;
3322 initialised_ = true;
3326 bool Init(unsigned char* p, int p_len, unsigned char* g, int g_len) {
3328 dh->p = BN_bin2bn(p, p_len, 0);
3329 dh->g = BN_bin2bn(g, g_len, 0);
3330 initialised_ = true;
3335 static Handle<Value> DiffieHellmanGroup(const Arguments& args) {
3338 DiffieHellman* diffieHellman = new DiffieHellman();
3340 if (args.Length() != 1 || !args[0]->IsString()) {
3341 return ThrowException(Exception::Error(
3342 String::New("No group name given")));
3345 String::Utf8Value group_name(args[0]);
3347 modp_group* it = modp_groups;
3349 while(it->name != NULL) {
3350 if (!strcasecmp(*group_name, it->name))
3355 if (it->name != NULL) {
3356 diffieHellman->Init(it->prime, it->prime_size,
3357 it->gen, it->gen_size);
3359 return ThrowException(Exception::Error(
3360 String::New("Unknown group")));
3363 diffieHellman->Wrap(args.This());
3368 static Handle<Value> New(const Arguments& args) {
3371 DiffieHellman* diffieHellman = new DiffieHellman();
3372 bool initialized = false;
3374 if (args.Length() > 0) {
3375 if (args[0]->IsInt32()) {
3376 initialized = diffieHellman->Init(args[0]->Int32Value());
3378 initialized = diffieHellman->Init(
3379 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3380 Buffer::Length(args[0]));
3385 return ThrowException(Exception::Error(
3386 String::New("Initialization failed")));
3389 diffieHellman->Wrap(args.This());
3394 static Handle<Value> GenerateKeys(const Arguments& args) {
3395 DiffieHellman* diffieHellman =
3396 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3400 if (!diffieHellman->initialised_) {
3401 return ThrowException(Exception::Error(
3402 String::New("Not initialized")));
3405 if (!DH_generate_key(diffieHellman->dh)) {
3406 return ThrowException(Exception::Error(
3407 String::New("Key generation failed")));
3410 Local<Value> outString;
3412 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3413 char* data = new char[dataSize];
3414 BN_bn2bin(diffieHellman->dh->pub_key,
3415 reinterpret_cast<unsigned char*>(data));
3417 outString = Encode(data, dataSize, BUFFER);
3420 return scope.Close(outString);
3423 static Handle<Value> GetPrime(const Arguments& args) {
3424 DiffieHellman* diffieHellman =
3425 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3429 if (!diffieHellman->initialised_) {
3430 return ThrowException(Exception::Error(String::New("Not initialized")));
3433 int dataSize = BN_num_bytes(diffieHellman->dh->p);
3434 char* data = new char[dataSize];
3435 BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
3437 Local<Value> outString;
3439 outString = Encode(data, dataSize, BUFFER);
3443 return scope.Close(outString);
3446 static Handle<Value> GetGenerator(const Arguments& args) {
3447 DiffieHellman* diffieHellman =
3448 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3452 if (!diffieHellman->initialised_) {
3453 return ThrowException(Exception::Error(String::New("Not initialized")));
3456 int dataSize = BN_num_bytes(diffieHellman->dh->g);
3457 char* data = new char[dataSize];
3458 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
3460 Local<Value> outString;
3462 outString = Encode(data, dataSize, BUFFER);
3466 return scope.Close(outString);
3469 static Handle<Value> GetPublicKey(const Arguments& args) {
3470 DiffieHellman* diffieHellman =
3471 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3475 if (!diffieHellman->initialised_) {
3476 return ThrowException(Exception::Error(String::New("Not initialized")));
3479 if (diffieHellman->dh->pub_key == NULL) {
3480 return ThrowException(Exception::Error(
3481 String::New("No public key - did you forget to generate one?")));
3484 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3485 char* data = new char[dataSize];
3486 BN_bn2bin(diffieHellman->dh->pub_key,
3487 reinterpret_cast<unsigned char*>(data));
3489 Local<Value> outString;
3491 outString = Encode(data, dataSize, BUFFER);
3495 return scope.Close(outString);
3498 static Handle<Value> GetPrivateKey(const Arguments& args) {
3499 DiffieHellman* diffieHellman =
3500 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3504 if (!diffieHellman->initialised_) {
3505 return ThrowException(Exception::Error(String::New("Not initialized")));
3508 if (diffieHellman->dh->priv_key == NULL) {
3509 return ThrowException(Exception::Error(
3510 String::New("No private key - did you forget to generate one?")));
3513 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
3514 char* data = new char[dataSize];
3515 BN_bn2bin(diffieHellman->dh->priv_key,
3516 reinterpret_cast<unsigned char*>(data));
3518 Local<Value> outString;
3520 outString = Encode(data, dataSize, BUFFER);
3524 return scope.Close(outString);
3527 static Handle<Value> ComputeSecret(const Arguments& args) {
3530 DiffieHellman* diffieHellman =
3531 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3533 if (!diffieHellman->initialised_) {
3534 return ThrowException(Exception::Error(String::New("Not initialized")));
3539 if (args.Length() == 0) {
3540 return ThrowException(Exception::Error(
3541 String::New("First argument must be other party's public key")));
3543 ASSERT_IS_BUFFER(args[0]);
3545 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3546 Buffer::Length(args[0]), 0);
3549 int dataSize = DH_size(diffieHellman->dh);
3550 char* data = new char[dataSize];
3552 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
3553 key, diffieHellman->dh);
3559 checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
3564 return ThrowException(Exception::Error(String::New("Invalid key")));
3565 } else if (checkResult) {
3566 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
3567 return ThrowException(Exception::Error(
3568 String::New("Supplied key is too small")));
3569 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
3570 return ThrowException(Exception::Error(
3571 String::New("Supplied key is too large")));
3573 return ThrowException(Exception::Error(String::New("Invalid key")));
3576 return ThrowException(Exception::Error(String::New("Invalid key")));
3583 // DH_size returns number of bytes in a prime number
3584 // DH_compute_key returns number of bytes in a remainder of exponent, which
3585 // may have less bytes than a prime number. Therefore add 0-padding to the
3586 // allocated buffer.
3587 if (size != dataSize) {
3588 assert(dataSize > size);
3589 memmove(data + dataSize - size, data, size);
3590 memset(data, 0, dataSize - size);
3593 Local<Value> outString;
3595 outString = Encode(data, dataSize, BUFFER);
3598 return scope.Close(outString);
3601 static Handle<Value> SetPublicKey(const Arguments& args) {
3604 DiffieHellman* diffieHellman =
3605 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3607 if (!diffieHellman->initialised_) {
3608 return ThrowException(Exception::Error(String::New("Not initialized")));
3611 if (args.Length() == 0) {
3612 return ThrowException(Exception::Error(
3613 String::New("First argument must be public key")));
3615 ASSERT_IS_BUFFER(args[0]);
3616 diffieHellman->dh->pub_key =
3618 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3619 Buffer::Length(args[0]), 0);
3625 static Handle<Value> SetPrivateKey(const Arguments& args) {
3628 DiffieHellman* diffieHellman =
3629 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3631 if (!diffieHellman->initialised_) {
3632 return ThrowException(Exception::Error(
3633 String::New("Not initialized")));
3636 if (args.Length() == 0) {
3637 return ThrowException(Exception::Error(
3638 String::New("First argument must be private key")));
3640 ASSERT_IS_BUFFER(args[0]);
3641 diffieHellman->dh->priv_key =
3643 reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
3644 Buffer::Length(args[0]), 0);
3650 DiffieHellman() : ObjectWrap() {
3651 initialised_ = false;
3662 bool VerifyContext() {
3664 if (!DH_check(dh, &codes)) return false;
3665 if (codes & DH_CHECK_P_NOT_SAFE_PRIME) return false;
3666 if (codes & DH_CHECK_P_NOT_PRIME) return false;
3667 if (codes & DH_UNABLE_TO_CHECK_GENERATOR) return false;
3668 if (codes & DH_NOT_SUITABLE_GENERATOR) return false;
3687 Persistent<Object> obj;
3691 void EIO_PBKDF2(pbkdf2_req* req) {
3692 req->err = PKCS5_PBKDF2_HMAC_SHA1(
3695 (unsigned char*)req->salt,
3699 (unsigned char*)req->key);
3700 memset(req->pass, 0, req->passlen);
3701 memset(req->salt, 0, req->saltlen);
3705 void EIO_PBKDF2(uv_work_t* work_req) {
3706 pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
3711 void EIO_PBKDF2After(pbkdf2_req* req, Local<Value> argv[2]) {
3713 argv[0] = Local<Value>::New(Undefined());
3714 argv[1] = Encode(req->key, req->keylen, BUFFER);
3715 memset(req->key, 0, req->keylen);
3717 argv[0] = Exception::Error(String::New("PBKDF2 error"));
3718 argv[1] = Local<Value>::New(Undefined());
3728 void EIO_PBKDF2After(uv_work_t* work_req, int status) {
3729 assert(status == 0);
3730 pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
3732 Local<Value> argv[2];
3733 Persistent<Object> obj = req->obj;
3734 EIO_PBKDF2After(req, argv);
3735 MakeCallback(obj, "ondone", ARRAY_SIZE(argv), argv);
3740 Handle<Value> PBKDF2(const Arguments& args) {
3743 const char* type_error = NULL;
3746 ssize_t passlen = -1;
3747 ssize_t saltlen = -1;
3748 ssize_t keylen = -1;
3749 ssize_t pass_written = -1;
3750 ssize_t salt_written = -1;
3752 pbkdf2_req* req = NULL;
3754 if (args.Length() != 4 && args.Length() != 5) {
3755 type_error = "Bad parameter";
3759 ASSERT_IS_BUFFER(args[0]);
3760 passlen = Buffer::Length(args[0]);
3762 type_error = "Bad password";
3766 pass = new char[passlen];
3767 pass_written = DecodeWrite(pass, passlen, args[0], BINARY);
3768 assert(pass_written == passlen);
3770 ASSERT_IS_BUFFER(args[1]);
3771 saltlen = Buffer::Length(args[1]);
3773 type_error = "Bad salt";
3777 salt = new char[saltlen];
3778 salt_written = DecodeWrite(salt, saltlen, args[1], BINARY);
3779 assert(salt_written == saltlen);
3781 if (!args[2]->IsNumber()) {
3782 type_error = "Iterations not a number";
3786 iter = args[2]->Int32Value();
3788 type_error = "Bad iterations";
3792 if (!args[3]->IsNumber()) {
3793 type_error = "Key length not a number";
3797 keylen = args[3]->Int32Value();
3799 type_error = "Bad key length";
3803 req = new pbkdf2_req;
3806 req->passlen = passlen;
3808 req->saltlen = saltlen;
3810 req->key = new char[keylen];
3811 req->keylen = keylen;
3813 if (args[4]->IsFunction()) {
3814 req->obj = Persistent<Object>::New(Object::New());
3815 req->obj->Set(String::New("ondone"), args[4]);
3816 uv_queue_work(uv_default_loop(),
3822 Local<Value> argv[2];
3824 EIO_PBKDF2After(req, argv);
3825 if (argv[0]->IsObject()) return ThrowException(argv[0]);
3826 return scope.Close(argv[1]);
3832 return ThrowException(Exception::TypeError(String::New(type_error)));
3836 struct RandomBytesRequest {
3837 ~RandomBytesRequest();
3838 Persistent<Object> obj_;
3839 unsigned long error_; // openssl error code or zero
3840 uv_work_t work_req_;
3846 RandomBytesRequest::~RandomBytesRequest() {
3847 if (obj_.IsEmpty()) return;
3853 void RandomBytesFree(char* data, void* hint) {
3858 template <bool pseudoRandom>
3859 void RandomBytesWork(uv_work_t* work_req) {
3860 RandomBytesRequest* req = container_of(work_req,
3865 if (pseudoRandom == true) {
3866 r = RAND_pseudo_bytes(reinterpret_cast<unsigned char*>(req->data_),
3869 r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data_), req->size_);
3872 // RAND_bytes() returns 0 on error. RAND_pseudo_bytes() returns 0 when the
3873 // result is not cryptographically strong - but that's not an error.
3874 if (r == 0 && pseudoRandom == false) {
3875 req->error_ = ERR_get_error();
3876 } else if (r == -1) {
3877 req->error_ = static_cast<unsigned long>(-1);
3882 // don't call this function without a valid HandleScope
3883 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
3885 char errmsg[256] = "Operation not supported";
3887 if (req->error_ != (unsigned long) -1)
3888 ERR_error_string_n(req->error_, errmsg, sizeof errmsg);
3890 argv[0] = Exception::Error(String::New(errmsg));
3891 argv[1] = Local<Value>::New(Null());
3894 // avoids the malloc + memcpy
3895 Buffer* buffer = Buffer::New(req->data_, req->size_, RandomBytesFree, NULL);
3896 argv[0] = Local<Value>::New(Null());
3897 argv[1] = Local<Object>::New(buffer->handle_);
3902 void RandomBytesAfter(uv_work_t* work_req, int status) {
3903 assert(status == 0);
3904 RandomBytesRequest* req = container_of(work_req,
3908 Local<Value> argv[2];
3909 RandomBytesCheck(req, argv);
3910 MakeCallback(req->obj_, "ondone", ARRAY_SIZE(argv), argv);
3915 template <bool pseudoRandom>
3916 Handle<Value> RandomBytes(const Arguments& args) {
3919 // maybe allow a buffer to write to? cuts down on object creation
3920 // when generating random data in a loop
3921 if (!args[0]->IsUint32()) {
3922 return ThrowTypeError("Argument #1 must be number > 0");
3925 const uint32_t size = args[0]->Uint32Value();
3926 if (size > Buffer::kMaxLength) {
3927 return ThrowTypeError("size > Buffer::kMaxLength");
3930 RandomBytesRequest* req = new RandomBytesRequest();
3932 req->data_ = new char[size];
3935 if (args[1]->IsFunction()) {
3936 req->obj_ = Persistent<Object>::New(Object::New());
3937 req->obj_->Set(String::New("ondone"), args[1]);
3939 uv_queue_work(uv_default_loop(),
3941 RandomBytesWork<pseudoRandom>,
3947 Local<Value> argv[2];
3948 RandomBytesWork<pseudoRandom>(&req->work_req_);
3949 RandomBytesCheck(req, argv);
3952 if (!argv[0]->IsNull())
3953 return ThrowException(argv[0]);
3960 Handle<Value> GetSSLCiphers(const Arguments& args) {
3963 SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
3965 return ThrowError("SSL_CTX_new() failed.");
3968 SSL* ssl = SSL_new(ctx);
3971 return ThrowError("SSL_new() failed.");
3974 Local<Array> arr = Array::New();
3975 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl);
3977 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
3978 SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
3979 arr->Set(i, String::New(SSL_CIPHER_get_name(cipher)));
3985 return scope.Close(arr);
3989 template <class TypeName>
3990 static void array_push_back(const TypeName* md,
3994 Local<Array>& arr = *static_cast<Local<Array>*>(arg);
3995 arr->Set(arr->Length(), String::New(from));
3999 Handle<Value> GetCiphers(const Arguments& args) {
4001 Local<Array> arr = Array::New();
4002 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &arr);
4003 return scope.Close(arr);
4007 Handle<Value> GetHashes(const Arguments& args) {
4009 Local<Array> arr = Array::New();
4010 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &arr);
4011 return scope.Close(arr);
4015 void InitCrypto(Handle<Object> target) {
4019 OpenSSL_add_all_algorithms();
4020 OpenSSL_add_all_digests();
4021 SSL_load_error_strings();
4022 ERR_load_crypto_strings();
4025 CRYPTO_set_locking_callback(crypto_lock_cb);
4026 CRYPTO_THREADID_set_callback(crypto_threadid_cb);
4028 // Turn off compression. Saves memory - do it in userland.
4029 #if !defined(OPENSSL_NO_COMP)
4030 STACK_OF(SSL_COMP)* comp_methods =
4031 #if OPENSSL_VERSION_NUMBER < 0x00908000L
4032 SSL_COMP_get_compression_method()
4034 SSL_COMP_get_compression_methods()
4037 sk_SSL_COMP_zero(comp_methods);
4038 assert(sk_SSL_COMP_num(comp_methods) == 0);
4041 SecureContext::Initialize(target);
4042 Connection::Initialize(target);
4043 Cipher::Initialize(target);
4044 Decipher::Initialize(target);
4045 DiffieHellman::Initialize(target);
4046 Hmac::Initialize(target);
4047 Hash::Initialize(target);
4048 Sign::Initialize(target);
4049 Verify::Initialize(target);
4051 NODE_SET_METHOD(target, "PBKDF2", PBKDF2);
4052 NODE_SET_METHOD(target, "randomBytes", RandomBytes<false>);
4053 NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<true>);
4054 NODE_SET_METHOD(target, "getSSLCiphers", GetSSLCiphers);
4055 NODE_SET_METHOD(target, "getCiphers", GetCiphers);
4056 NODE_SET_METHOD(target, "getHashes", GetHashes);
4058 subject_symbol = NODE_PSYMBOL("subject");
4059 issuer_symbol = NODE_PSYMBOL("issuer");
4060 valid_from_symbol = NODE_PSYMBOL("valid_from");
4061 valid_to_symbol = NODE_PSYMBOL("valid_to");
4062 subjectaltname_symbol = NODE_PSYMBOL("subjectaltname");
4063 modulus_symbol = NODE_PSYMBOL("modulus");
4064 exponent_symbol = NODE_PSYMBOL("exponent");
4065 fingerprint_symbol = NODE_PSYMBOL("fingerprint");
4066 name_symbol = NODE_PSYMBOL("name");
4067 version_symbol = NODE_PSYMBOL("version");
4068 ext_key_usage_symbol = NODE_PSYMBOL("ext_key_usage");
4071 } // namespace crypto
4074 NODE_MODULE(node_crypto, node::crypto::InitCrypto)