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
47 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
48 # define OPENSSL_CONST const
50 # define OPENSSL_CONST
53 #define ASSERT_IS_STRING_OR_BUFFER(val) \
54 if (!val->IsString() && !Buffer::HasInstance(val)) { \
55 return ThrowException(Exception::TypeError(String::New("Not a string or buffer"))); \
58 static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----";
59 static const int PUBLIC_KEY_PFX_LEN = sizeof(PUBLIC_KEY_PFX) - 1;
60 static const char PUBRSA_KEY_PFX[] = "-----BEGIN RSA PUBLIC KEY-----";
61 static const int PUBRSA_KEY_PFX_LEN = sizeof(PUBRSA_KEY_PFX) - 1;
62 static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
63 | ASN1_STRFLGS_ESC_MSB
64 | XN_FLAG_SEP_MULTILINE
72 static Persistent<String> errno_symbol;
73 static Persistent<String> syscall_symbol;
74 static Persistent<String> subject_symbol;
75 static Persistent<String> subjectaltname_symbol;
76 static Persistent<String> modulus_symbol;
77 static Persistent<String> exponent_symbol;
78 static Persistent<String> issuer_symbol;
79 static Persistent<String> valid_from_symbol;
80 static Persistent<String> valid_to_symbol;
81 static Persistent<String> fingerprint_symbol;
82 static Persistent<String> name_symbol;
83 static Persistent<String> version_symbol;
84 static Persistent<String> ext_key_usage_symbol;
85 static Persistent<String> onhandshakestart_sym;
86 static Persistent<String> onhandshakedone_sym;
88 static Persistent<FunctionTemplate> secure_context_constructor;
90 static uv_rwlock_t* locks;
93 static unsigned long crypto_id_cb(void) {
95 return (unsigned long) GetCurrentThreadId();
97 return (unsigned long) pthread_self();
102 static void crypto_lock_init(void) {
105 n = CRYPTO_num_locks();
106 locks = new uv_rwlock_t[n];
108 for (i = 0; i < n; i++)
109 if (uv_rwlock_init(locks + i))
114 static void crypto_lock_cb(int mode, int n, const char* file, int line) {
115 assert((mode & CRYPTO_LOCK) || (mode & CRYPTO_UNLOCK));
116 assert((mode & CRYPTO_READ) || (mode & CRYPTO_WRITE));
118 if (mode & CRYPTO_LOCK) {
119 if (mode & CRYPTO_READ)
120 uv_rwlock_rdlock(locks + n);
122 uv_rwlock_wrlock(locks + n);
124 if (mode & CRYPTO_READ)
125 uv_rwlock_rdunlock(locks + n);
127 uv_rwlock_wrunlock(locks + n);
134 void SecureContext::Initialize(Handle<Object> target) {
137 Local<FunctionTemplate> t = FunctionTemplate::New(SecureContext::New);
138 secure_context_constructor = Persistent<FunctionTemplate>::New(t);
140 t->InstanceTemplate()->SetInternalFieldCount(1);
141 t->SetClassName(String::NewSymbol("SecureContext"));
143 NODE_SET_PROTOTYPE_METHOD(t, "init", SecureContext::Init);
144 NODE_SET_PROTOTYPE_METHOD(t, "setKey", SecureContext::SetKey);
145 NODE_SET_PROTOTYPE_METHOD(t, "setCert", SecureContext::SetCert);
146 NODE_SET_PROTOTYPE_METHOD(t, "addCACert", SecureContext::AddCACert);
147 NODE_SET_PROTOTYPE_METHOD(t, "addCRL", SecureContext::AddCRL);
148 NODE_SET_PROTOTYPE_METHOD(t, "addRootCerts", SecureContext::AddRootCerts);
149 NODE_SET_PROTOTYPE_METHOD(t, "setCiphers", SecureContext::SetCiphers);
150 NODE_SET_PROTOTYPE_METHOD(t, "setOptions", SecureContext::SetOptions);
151 NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
152 SecureContext::SetSessionIdContext);
153 NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
154 NODE_SET_PROTOTYPE_METHOD(t, "loadPKCS12", SecureContext::LoadPKCS12);
156 target->Set(String::NewSymbol("SecureContext"), t->GetFunction());
160 Handle<Value> SecureContext::New(const Arguments& args) {
162 SecureContext *p = new SecureContext();
163 p->Wrap(args.Holder());
168 Handle<Value> SecureContext::Init(const Arguments& args) {
171 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
173 OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
175 if (args.Length() == 1 && args[0]->IsString()) {
176 String::Utf8Value sslmethod(args[0]);
178 if (strcmp(*sslmethod, "SSLv2_method") == 0) {
179 #ifndef OPENSSL_NO_SSL2
180 method = SSLv2_method();
182 return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
184 } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
185 #ifndef OPENSSL_NO_SSL2
186 method = SSLv2_server_method();
188 return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
190 } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
191 #ifndef OPENSSL_NO_SSL2
192 method = SSLv2_client_method();
194 return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
196 } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
197 method = SSLv3_method();
198 } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
199 method = SSLv3_server_method();
200 } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) {
201 method = SSLv3_client_method();
202 } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
203 method = SSLv23_method();
204 } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
205 method = SSLv23_server_method();
206 } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
207 method = SSLv23_client_method();
208 } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
209 method = TLSv1_method();
210 } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
211 method = TLSv1_server_method();
212 } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
213 method = TLSv1_client_method();
215 return ThrowException(Exception::Error(String::New("Unknown method")));
219 sc->ctx_ = SSL_CTX_new(method);
220 // Enable session caching?
221 SSL_CTX_set_session_cache_mode(sc->ctx_, SSL_SESS_CACHE_SERVER);
222 // SSL_CTX_set_session_cache_mode(sc->ctx_,SSL_SESS_CACHE_OFF);
224 sc->ca_store_ = NULL;
229 // Takes a string or buffer and loads it into a BIO.
230 // Caller responsible for BIO_free-ing the returned object.
231 static BIO* LoadBIO (Handle<Value> v) {
232 BIO *bio = BIO_new(BIO_s_mem());
233 if (!bio) return NULL;
240 String::Utf8Value s(v);
241 r = BIO_write(bio, *s, s.length());
242 } else if (Buffer::HasInstance(v)) {
243 Local<Object> buffer_obj = v->ToObject();
244 char *buffer_data = Buffer::Data(buffer_obj);
245 size_t buffer_length = Buffer::Length(buffer_obj);
246 r = BIO_write(bio, buffer_data, buffer_length);
258 // Takes a string or buffer and loads it into an X509
259 // Caller responsible for X509_free-ing the returned object.
260 static X509* LoadX509 (Handle<Value> v) {
261 HandleScope scope; // necessary?
263 BIO *bio = LoadBIO(v);
264 if (!bio) return NULL;
266 X509 * x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
277 Handle<Value> SecureContext::SetKey(const Arguments& args) {
280 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
282 unsigned int len = args.Length();
283 if (len != 1 && len != 2) {
284 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
286 if (len == 2 && !args[1]->IsString()) {
287 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
290 BIO *bio = LoadBIO(args[0]);
291 if (!bio) return False();
293 String::Utf8Value passphrase(args[1]);
295 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, NULL,
296 len == 1 ? NULL : *passphrase);
300 unsigned long err = ERR_get_error();
302 return ThrowException(Exception::Error(
303 String::New("PEM_read_bio_PrivateKey")));
306 ERR_error_string_n(err, string, sizeof string);
307 return ThrowException(Exception::Error(String::New(string)));
310 SSL_CTX_use_PrivateKey(sc->ctx_, key);
318 // Read a file that contains our certificate in "PEM" format,
319 // possibly followed by a sequence of CA certificates that should be
320 // sent to the peer in the Certificate message.
322 // Taken from OpenSSL - editted for style.
323 int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, BIO *in) {
327 x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
330 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
334 ret = SSL_CTX_use_certificate(ctx, x);
336 if (ERR_peek_error() != 0) {
337 // Key/certificate mismatch doesn't imply ret==0 ...
342 // If we could set up our certificate, now proceed to
343 // the CA certificates.
348 if (ctx->extra_certs != NULL) {
349 sk_X509_pop_free(ctx->extra_certs, X509_free);
350 ctx->extra_certs = NULL;
353 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
354 r = SSL_CTX_add_extra_chain_cert(ctx, ca);
361 // Note that we must not free r if it was successfully
362 // added to the chain (while we must free the main
363 // certificate, since its reference count is increased
364 // by SSL_CTX_use_certificate).
367 // When the while loop ends, it's usually just EOF.
368 err = ERR_peek_last_error();
369 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
370 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
379 if (x != NULL) X509_free(x);
384 Handle<Value> SecureContext::SetCert(const Arguments& args) {
387 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
389 if (args.Length() != 1) {
390 return ThrowException(Exception::TypeError(
391 String::New("Bad parameter")));
394 BIO* bio = LoadBIO(args[0]);
395 if (!bio) return False();
397 int rv = SSL_CTX_use_certificate_chain(sc->ctx_, bio);
402 unsigned long err = ERR_get_error();
404 return ThrowException(Exception::Error(
405 String::New("SSL_CTX_use_certificate_chain")));
408 ERR_error_string_n(err, string, sizeof string);
409 return ThrowException(Exception::Error(String::New(string)));
416 Handle<Value> SecureContext::AddCACert(const Arguments& args) {
417 bool newCAStore = false;
420 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
422 if (args.Length() != 1) {
423 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
426 if (!sc->ca_store_) {
427 sc->ca_store_ = X509_STORE_new();
431 X509* x509 = LoadX509(args[0]);
432 if (!x509) return False();
434 X509_STORE_add_cert(sc->ca_store_, x509);
435 SSL_CTX_add_client_CA(sc->ctx_, x509);
440 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
447 Handle<Value> SecureContext::AddCRL(const Arguments& args) {
450 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
452 if (args.Length() != 1) {
453 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
456 BIO *bio = LoadBIO(args[0]);
457 if (!bio) return False();
459 X509_CRL *x509 = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
466 X509_STORE_add_crl(sc->ca_store_, x509);
468 X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK |
469 X509_V_FLAG_CRL_CHECK_ALL);
479 Handle<Value> SecureContext::AddRootCerts(const Arguments& args) {
482 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
484 assert(sc->ca_store_ == NULL);
486 if (!root_cert_store) {
487 root_cert_store = X509_STORE_new();
489 for (int i = 0; root_certs[i]; i++) {
490 BIO *bp = BIO_new(BIO_s_mem());
492 if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
497 X509 *x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
504 X509_STORE_add_cert(root_cert_store, x509);
511 sc->ca_store_ = root_cert_store;
512 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
518 Handle<Value> SecureContext::SetCiphers(const Arguments& args) {
521 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
523 if (args.Length() != 1 || !args[0]->IsString()) {
524 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
527 String::Utf8Value ciphers(args[0]);
528 SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
533 Handle<Value> SecureContext::SetOptions(const Arguments& args) {
536 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
538 if (args.Length() != 1 || !args[0]->IsUint32()) {
539 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
542 unsigned int opts = args[0]->Uint32Value();
544 SSL_CTX_set_options(sc->ctx_, opts);
549 Handle<Value> SecureContext::SetSessionIdContext(const Arguments& args) {
552 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
554 if (args.Length() != 1 || !args[0]->IsString()) {
555 return ThrowException(Exception::TypeError(String::New("Bad parameter")));
558 String::Utf8Value sessionIdContext(args[0]);
559 const unsigned char* sid_ctx = (const unsigned char*) *sessionIdContext;
560 unsigned int sid_ctx_len = sessionIdContext.length();
562 int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len);
564 Local<String> message;
567 if ((bio = BIO_new(BIO_s_mem()))) {
568 ERR_print_errors(bio);
569 BIO_get_mem_ptr(bio, &mem);
570 message = String::New(mem->data, mem->length);
573 message = String::New("SSL_CTX_set_session_id_context error");
575 return ThrowException(Exception::TypeError(message));
581 Handle<Value> SecureContext::Close(const Arguments& args) {
583 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
588 //Takes .pfx or .p12 and password in string or buffer format
589 Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
594 EVP_PKEY* pkey = NULL;
596 STACK_OF(X509)* extraCerts = NULL;
600 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
602 if (args.Length() < 1) {
603 return ThrowException(Exception::TypeError(
604 String::New("Bad parameter")));
607 in = LoadBIO(args[0]);
609 return ThrowException(Exception::Error(
610 String::New("Unable to load BIO")));
613 if (args.Length() >= 2) {
614 ASSERT_IS_STRING_OR_BUFFER(args[1]);
616 int passlen = DecodeBytes(args[1], BINARY);
619 return ThrowException(Exception::TypeError(
620 String::New("Bad password")));
622 pass = new char[passlen + 1];
623 int pass_written = DecodeWrite(pass, passlen, args[1], BINARY);
625 assert(pass_written == passlen);
626 pass[passlen] = '\0';
629 if (d2i_PKCS12_bio(in, &p12) &&
630 PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
631 SSL_CTX_use_certificate(sc->ctx_, cert) &&
632 SSL_CTX_use_PrivateKey(sc->ctx_, pkey))
635 while (X509* x509 = sk_X509_pop(extraCerts)) {
636 if (!sc->ca_store_) {
637 sc->ca_store_ = X509_STORE_new();
638 SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
641 X509_STORE_add_cert(sc->ca_store_, x509);
642 SSL_CTX_add_client_CA(sc->ctx_, x509);
647 sk_X509_free(extraCerts);
657 unsigned long err = ERR_get_error();
658 const char *str = ERR_reason_error_string(err);
659 return ThrowException(Exception::Error(String::New(str)));
666 #ifdef SSL_PRINT_DEBUG
667 # define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
669 # define DEBUG_PRINT(...)
673 int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
674 if (rv >= 0) return rv;
676 int retry = BIO_should_retry(bio);
677 (void) retry; // unused if !defined(SSL_PRINT_DEBUG)
679 if (BIO_should_write(bio)) {
680 DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n", ssl_, func, retry);
683 } else if (BIO_should_read(bio)) {
684 DEBUG_PRINT("[%p] BIO: %s want read. should retry %d\n", ssl_, func, retry);
688 static char ssl_error_buf[512];
689 ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
692 Local<Value> e = Exception::Error(String::New(ssl_error_buf));
693 handle_->Set(String::New("error"), e);
695 DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n", ssl_, func, rv, ssl_error_buf);
704 int Connection::HandleSSLError(const char* func, int rv) {
705 if (rv >= 0) return rv;
707 int err = SSL_get_error(ssl_, rv);
709 if (err == SSL_ERROR_NONE) {
712 } else if (err == SSL_ERROR_WANT_WRITE) {
713 DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
716 } else if (err == SSL_ERROR_WANT_READ) {
717 DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
725 assert(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
727 // XXX We need to drain the error queue for this thread or else OpenSSL
728 // has the possibility of blocking connections? This problem is not well
729 // understood. And we should be somehow propagating these errors up
730 // into JavaScript. There is no test which demonstrates this problem.
731 // https://github.com/joyent/node/issues/1719
732 if ((bio = BIO_new(BIO_s_mem()))) {
733 ERR_print_errors(bio);
734 BIO_get_mem_ptr(bio, &mem);
735 Local<Value> e = Exception::Error(String::New(mem->data, mem->length));
736 handle_->Set(String::New("error"), e);
747 void Connection::ClearError() {
751 // We should clear the error in JS-land
752 assert(handle_->Get(String::New("error"))->BooleanValue() == false);
757 void Connection::SetShutdownFlags() {
760 int flags = SSL_get_shutdown(ssl_);
762 if (flags & SSL_SENT_SHUTDOWN) {
763 handle_->Set(String::New("sentShutdown"), True());
766 if (flags & SSL_RECEIVED_SHUTDOWN) {
767 handle_->Set(String::New("receivedShutdown"), True());
772 void Connection::Initialize(Handle<Object> target) {
775 Local<FunctionTemplate> t = FunctionTemplate::New(Connection::New);
776 t->InstanceTemplate()->SetInternalFieldCount(1);
777 t->SetClassName(String::NewSymbol("Connection"));
779 NODE_SET_PROTOTYPE_METHOD(t, "encIn", Connection::EncIn);
780 NODE_SET_PROTOTYPE_METHOD(t, "clearOut", Connection::ClearOut);
781 NODE_SET_PROTOTYPE_METHOD(t, "clearIn", Connection::ClearIn);
782 NODE_SET_PROTOTYPE_METHOD(t, "encOut", Connection::EncOut);
783 NODE_SET_PROTOTYPE_METHOD(t, "clearPending", Connection::ClearPending);
784 NODE_SET_PROTOTYPE_METHOD(t, "encPending", Connection::EncPending);
785 NODE_SET_PROTOTYPE_METHOD(t, "getPeerCertificate", Connection::GetPeerCertificate);
786 NODE_SET_PROTOTYPE_METHOD(t, "getSession", Connection::GetSession);
787 NODE_SET_PROTOTYPE_METHOD(t, "setSession", Connection::SetSession);
788 NODE_SET_PROTOTYPE_METHOD(t, "isSessionReused", Connection::IsSessionReused);
789 NODE_SET_PROTOTYPE_METHOD(t, "isInitFinished", Connection::IsInitFinished);
790 NODE_SET_PROTOTYPE_METHOD(t, "verifyError", Connection::VerifyError);
791 NODE_SET_PROTOTYPE_METHOD(t, "getCurrentCipher", Connection::GetCurrentCipher);
792 NODE_SET_PROTOTYPE_METHOD(t, "start", Connection::Start);
793 NODE_SET_PROTOTYPE_METHOD(t, "shutdown", Connection::Shutdown);
794 NODE_SET_PROTOTYPE_METHOD(t, "receivedShutdown", Connection::ReceivedShutdown);
795 NODE_SET_PROTOTYPE_METHOD(t, "close", Connection::Close);
797 #ifdef OPENSSL_NPN_NEGOTIATED
798 NODE_SET_PROTOTYPE_METHOD(t, "getNegotiatedProtocol", Connection::GetNegotiatedProto);
799 NODE_SET_PROTOTYPE_METHOD(t, "setNPNProtocols", Connection::SetNPNProtocols);
803 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
804 NODE_SET_PROTOTYPE_METHOD(t, "getServername", Connection::GetServername);
805 NODE_SET_PROTOTYPE_METHOD(t, "setSNICallback", Connection::SetSNICallback);
808 target->Set(String::NewSymbol("Connection"), t->GetFunction());
812 static int VerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) {
813 // Quoting SSL_set_verify(3ssl):
815 // The VerifyCallback function is used to control the behaviour when
816 // the SSL_VERIFY_PEER flag is set. It must be supplied by the
817 // application and receives two arguments: preverify_ok indicates,
818 // whether the verification of the certificate in question was passed
819 // (preverify_ok=1) or not (preverify_ok=0). x509_ctx is a pointer to
820 // the complete context used for the certificate chain verification.
822 // The certificate chain is checked starting with the deepest nesting
823 // level (the root CA certificate) and worked upward to the peer's
824 // certificate. At each level signatures and issuer attributes are
825 // checked. Whenever a verification error is found, the error number is
826 // stored in x509_ctx and VerifyCallback is called with preverify_ok=0.
827 // By applying X509_CTX_store_* functions VerifyCallback can locate the
828 // certificate in question and perform additional steps (see EXAMPLES).
829 // If no error is found for a certificate, VerifyCallback is called
830 // with preverify_ok=1 before advancing to the next level.
832 // The return value of VerifyCallback controls the strategy of the
833 // further verification process. If VerifyCallback returns 0, the
834 // verification process is immediately stopped with "verification
835 // failed" state. If SSL_VERIFY_PEER is set, a verification failure
836 // alert is sent to the peer and the TLS/SSL handshake is terminated. If
837 // VerifyCallback returns 1, the verification process is continued. If
838 // VerifyCallback always returns 1, the TLS/SSL handshake will not be
839 // terminated with respect to verification failures and the connection
840 // will be established. The calling process can however retrieve the
841 // error code of the last verification error using
842 // SSL_get_verify_result(3) or by maintaining its own error storage
843 // managed by VerifyCallback.
845 // If no VerifyCallback is specified, the default callback will be
846 // used. Its return value is identical to preverify_ok, so that any
847 // verification failure will lead to a termination of the TLS/SSL
848 // handshake with an alert message, if SSL_VERIFY_PEER is set.
850 // Since we cannot perform I/O quickly enough in this callback, we ignore
851 // all preverify_ok errors and let the handshake continue. It is
852 // imparative that the user use Connection::VerifyError after the
853 // 'secure' callback has been made.
857 #ifdef OPENSSL_NPN_NEGOTIATED
859 int Connection::AdvertiseNextProtoCallback_(SSL *s,
860 const unsigned char **data,
864 Connection *p = static_cast<Connection*>(SSL_get_app_data(s));
866 if (p->npnProtos_.IsEmpty()) {
867 // No initialization - no NPN protocols
868 *data = reinterpret_cast<const unsigned char*>("");
871 *data = reinterpret_cast<const unsigned char*>(Buffer::Data(p->npnProtos_));
872 *len = Buffer::Length(p->npnProtos_);
875 return SSL_TLSEXT_ERR_OK;
878 int Connection::SelectNextProtoCallback_(SSL *s,
879 unsigned char **out, unsigned char *outlen,
880 const unsigned char* in,
881 unsigned int inlen, void *arg) {
882 Connection *p = static_cast<Connection*> SSL_get_app_data(s);
884 // Release old protocol handler if present
885 if (!p->selectedNPNProto_.IsEmpty()) {
886 p->selectedNPNProto_.Dispose();
889 if (p->npnProtos_.IsEmpty()) {
890 // We should at least select one protocol
891 // If server is using NPN
892 *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1"));
895 // set status unsupported
896 p->selectedNPNProto_ = Persistent<Value>::New(False());
898 return SSL_TLSEXT_ERR_OK;
901 const unsigned char* npnProtos =
902 reinterpret_cast<const unsigned char*>(Buffer::Data(p->npnProtos_));
904 int status = SSL_select_next_proto(out, outlen, in, inlen, npnProtos,
905 Buffer::Length(p->npnProtos_));
908 case OPENSSL_NPN_UNSUPPORTED:
909 p->selectedNPNProto_ = Persistent<Value>::New(Null());
911 case OPENSSL_NPN_NEGOTIATED:
912 p->selectedNPNProto_ = Persistent<Value>::New(String::New(
913 reinterpret_cast<const char*>(*out), *outlen
916 case OPENSSL_NPN_NO_OVERLAP:
917 p->selectedNPNProto_ = Persistent<Value>::New(False());
923 return SSL_TLSEXT_ERR_OK;
927 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
928 int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
931 Connection *p = static_cast<Connection*> SSL_get_app_data(s);
933 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
936 if (!p->servername_.IsEmpty()) {
937 p->servername_.Dispose();
939 p->servername_ = Persistent<String>::New(String::New(servername));
941 // Call the SNI callback and use its return value as context
942 if (!p->sniObject_.IsEmpty()) {
943 if (!p->sniContext_.IsEmpty()) {
944 p->sniContext_.Dispose();
947 // Get callback init args
948 Local<Value> argv[1] = {*p->servername_};
951 Local<Value> ret = Local<Value>::New(MakeCallback(p->sniObject_,
956 // If ret is SecureContext
957 if (secure_context_constructor->HasInstance(ret)) {
958 p->sniContext_ = Persistent<Value>::New(ret);
959 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(
960 Local<Object>::Cast(ret));
961 SSL_set_SSL_CTX(s, sc->ctx_);
963 return SSL_TLSEXT_ERR_NOACK;
968 return SSL_TLSEXT_ERR_OK;
972 Handle<Value> Connection::New(const Arguments& args) {
975 Connection *p = new Connection();
976 p->Wrap(args.Holder());
978 if (args.Length() < 1 || !args[0]->IsObject()) {
979 return ThrowException(Exception::Error(String::New(
980 "First argument must be a crypto module Credentials")));
983 SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args[0]->ToObject());
985 bool is_server = args[1]->BooleanValue();
987 p->ssl_ = SSL_new(sc->ctx_);
988 p->bio_read_ = BIO_new(BIO_s_mem());
989 p->bio_write_ = BIO_new(BIO_s_mem());
991 SSL_set_app_data(p->ssl_, p);
993 if (is_server) SSL_set_info_callback(p->ssl_, SSLInfoCallback);
995 #ifdef OPENSSL_NPN_NEGOTIATED
997 // Server should advertise NPN protocols
998 SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
999 AdvertiseNextProtoCallback_,
1002 // Client should select protocol from advertised
1003 // If server supports NPN
1004 SSL_CTX_set_next_proto_select_cb(sc->ctx_,
1005 SelectNextProtoCallback_,
1010 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1012 SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
1014 String::Utf8Value servername(args[2]);
1015 SSL_set_tlsext_host_name(p->ssl_, *servername);
1019 SSL_set_bio(p->ssl_, p->bio_read_, p->bio_write_);
1021 #ifdef SSL_MODE_RELEASE_BUFFERS
1022 long mode = SSL_get_mode(p->ssl_);
1023 SSL_set_mode(p->ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
1029 bool request_cert = args[2]->BooleanValue();
1030 if (!request_cert) {
1031 // Note reject_unauthorized ignored.
1032 verify_mode = SSL_VERIFY_NONE;
1034 bool reject_unauthorized = args[3]->BooleanValue();
1035 verify_mode = SSL_VERIFY_PEER;
1036 if (reject_unauthorized) verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1039 // Note request_cert and reject_unauthorized are ignored for clients.
1040 verify_mode = SSL_VERIFY_NONE;
1044 // Always allow a connection. We'll reject in javascript.
1045 SSL_set_verify(p->ssl_, verify_mode, VerifyCallback);
1047 if ((p->is_server_ = is_server)) {
1048 SSL_set_accept_state(p->ssl_);
1050 SSL_set_connect_state(p->ssl_);
1057 void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
1058 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
1059 // a non-const SSL* in OpenSSL <= 0.9.7e.
1060 SSL* ssl = const_cast<SSL*>(ssl_);
1061 if (where & SSL_CB_HANDSHAKE_START) {
1063 Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl));
1064 if (onhandshakestart_sym.IsEmpty()) {
1065 onhandshakestart_sym = NODE_PSYMBOL("onhandshakestart");
1067 MakeCallback(c->handle_, onhandshakestart_sym, 0, NULL);
1069 if (where & SSL_CB_HANDSHAKE_DONE) {
1071 Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl));
1072 if (onhandshakedone_sym.IsEmpty()) {
1073 onhandshakedone_sym = NODE_PSYMBOL("onhandshakedone");
1075 MakeCallback(c->handle_, onhandshakedone_sym, 0, NULL);
1080 Handle<Value> Connection::EncIn(const Arguments& args) {
1083 Connection *ss = Connection::Unwrap(args);
1085 if (args.Length() < 3) {
1086 return ThrowException(Exception::TypeError(
1087 String::New("Takes 3 parameters")));
1090 if (!Buffer::HasInstance(args[0])) {
1091 return ThrowException(Exception::TypeError(
1092 String::New("Second argument should be a buffer")));
1095 Local<Object> buffer_obj = args[0]->ToObject();
1096 char *buffer_data = Buffer::Data(buffer_obj);
1097 size_t buffer_length = Buffer::Length(buffer_obj);
1099 size_t off = args[1]->Int32Value();
1100 if (off >= buffer_length) {
1101 return ThrowException(Exception::Error(
1102 String::New("Offset is out of bounds")));
1105 size_t len = args[2]->Int32Value();
1106 if (off + len > buffer_length) {
1107 return ThrowException(Exception::Error(
1108 String::New("off + len > buffer.length")));
1111 int bytes_written = BIO_write(ss->bio_read_, buffer_data + off, len);
1112 ss->HandleBIOError(ss->bio_read_, "BIO_write", bytes_written);
1113 ss->SetShutdownFlags();
1115 return scope.Close(Integer::New(bytes_written));
1119 Handle<Value> Connection::ClearOut(const Arguments& args) {
1122 Connection *ss = Connection::Unwrap(args);
1124 if (args.Length() < 3) {
1125 return ThrowException(Exception::TypeError(
1126 String::New("Takes 3 parameters")));
1129 if (!Buffer::HasInstance(args[0])) {
1130 return ThrowException(Exception::TypeError(
1131 String::New("Second argument should be a buffer")));
1134 Local<Object> buffer_obj = args[0]->ToObject();
1135 char *buffer_data = Buffer::Data(buffer_obj);
1136 size_t buffer_length = Buffer::Length(buffer_obj);
1138 size_t off = args[1]->Int32Value();
1139 if (off >= buffer_length) {
1140 return ThrowException(Exception::Error(
1141 String::New("Offset is out of bounds")));
1144 size_t len = args[2]->Int32Value();
1145 if (off + len > buffer_length) {
1146 return ThrowException(Exception::Error(
1147 String::New("off + len > buffer.length")));
1150 if (!SSL_is_init_finished(ss->ssl_)) {
1153 if (ss->is_server_) {
1154 rv = SSL_accept(ss->ssl_);
1155 ss->HandleSSLError("SSL_accept:ClearOut", rv);
1157 rv = SSL_connect(ss->ssl_);
1158 ss->HandleSSLError("SSL_connect:ClearOut", rv);
1161 if (rv < 0) return scope.Close(Integer::New(rv));
1164 int bytes_read = SSL_read(ss->ssl_, buffer_data + off, len);
1165 ss->HandleSSLError("SSL_read:ClearOut", bytes_read);
1166 ss->SetShutdownFlags();
1168 return scope.Close(Integer::New(bytes_read));
1172 Handle<Value> Connection::ClearPending(const Arguments& args) {
1175 Connection *ss = Connection::Unwrap(args);
1177 int bytes_pending = BIO_pending(ss->bio_read_);
1178 return scope.Close(Integer::New(bytes_pending));
1182 Handle<Value> Connection::EncPending(const Arguments& args) {
1185 Connection *ss = Connection::Unwrap(args);
1187 int bytes_pending = BIO_pending(ss->bio_write_);
1188 return scope.Close(Integer::New(bytes_pending));
1192 Handle<Value> Connection::EncOut(const Arguments& args) {
1195 Connection *ss = Connection::Unwrap(args);
1197 if (args.Length() < 3) {
1198 return ThrowException(Exception::TypeError(
1199 String::New("Takes 3 parameters")));
1202 if (!Buffer::HasInstance(args[0])) {
1203 return ThrowException(Exception::TypeError(
1204 String::New("Second argument should be a buffer")));
1207 Local<Object> buffer_obj = args[0]->ToObject();
1208 char *buffer_data = Buffer::Data(buffer_obj);
1209 size_t buffer_length = Buffer::Length(buffer_obj);
1211 size_t off = args[1]->Int32Value();
1212 if (off >= buffer_length) {
1213 return ThrowException(Exception::Error(
1214 String::New("Offset is out of bounds")));
1217 size_t len = args[2]->Int32Value();
1218 if (off + len > buffer_length) {
1219 return ThrowException(Exception::Error(
1220 String::New("off + len > buffer.length")));
1223 int bytes_read = BIO_read(ss->bio_write_, buffer_data + off, len);
1225 ss->HandleBIOError(ss->bio_write_, "BIO_read:EncOut", bytes_read);
1226 ss->SetShutdownFlags();
1228 return scope.Close(Integer::New(bytes_read));
1232 Handle<Value> Connection::ClearIn(const Arguments& args) {
1235 Connection *ss = Connection::Unwrap(args);
1237 if (args.Length() < 3) {
1238 return ThrowException(Exception::TypeError(
1239 String::New("Takes 3 parameters")));
1242 if (!Buffer::HasInstance(args[0])) {
1243 return ThrowException(Exception::TypeError(
1244 String::New("Second argument should be a buffer")));
1247 Local<Object> buffer_obj = args[0]->ToObject();
1248 char *buffer_data = Buffer::Data(buffer_obj);
1249 size_t buffer_length = Buffer::Length(buffer_obj);
1251 size_t off = args[1]->Int32Value();
1252 if (off > buffer_length) {
1253 return ThrowException(Exception::Error(
1254 String::New("Offset is out of bounds")));
1257 size_t len = args[2]->Int32Value();
1258 if (off + len > buffer_length) {
1259 return ThrowException(Exception::Error(
1260 String::New("off + len > buffer.length")));
1263 if (!SSL_is_init_finished(ss->ssl_)) {
1265 if (ss->is_server_) {
1266 rv = SSL_accept(ss->ssl_);
1267 ss->HandleSSLError("SSL_accept:ClearIn", rv);
1269 rv = SSL_connect(ss->ssl_);
1270 ss->HandleSSLError("SSL_connect:ClearIn", rv);
1273 if (rv < 0) return scope.Close(Integer::New(rv));
1276 int bytes_written = SSL_write(ss->ssl_, buffer_data + off, len);
1278 ss->HandleSSLError("SSL_write:ClearIn", bytes_written);
1279 ss->SetShutdownFlags();
1281 return scope.Close(Integer::New(bytes_written));
1285 Handle<Value> Connection::GetPeerCertificate(const Arguments& args) {
1288 Connection *ss = Connection::Unwrap(args);
1290 if (ss->ssl_ == NULL) return Undefined();
1291 Local<Object> info = Object::New();
1292 X509* peer_cert = SSL_get_peer_certificate(ss->ssl_);
1293 if (peer_cert != NULL) {
1294 BIO* bio = BIO_new(BIO_s_mem());
1296 if (X509_NAME_print_ex(bio, X509_get_subject_name(peer_cert), 0,
1297 X509_NAME_FLAGS) > 0) {
1298 BIO_get_mem_ptr(bio, &mem);
1299 info->Set(subject_symbol, String::New(mem->data, mem->length));
1301 (void) BIO_reset(bio);
1303 if (X509_NAME_print_ex(bio, X509_get_issuer_name(peer_cert), 0,
1304 X509_NAME_FLAGS) > 0) {
1305 BIO_get_mem_ptr(bio, &mem);
1306 info->Set(issuer_symbol, String::New(mem->data, mem->length));
1308 (void) BIO_reset(bio);
1310 int index = X509_get_ext_by_NID(peer_cert, NID_subject_alt_name, -1);
1312 X509_EXTENSION* ext;
1315 ext = X509_get_ext(peer_cert, index);
1316 assert(ext != NULL);
1318 rv = X509V3_EXT_print(bio, ext, 0, 0);
1321 BIO_get_mem_ptr(bio, &mem);
1322 info->Set(subjectaltname_symbol, String::New(mem->data, mem->length));
1324 (void) BIO_reset(bio);
1327 EVP_PKEY *pkey = NULL;
1329 if( NULL != (pkey = X509_get_pubkey(peer_cert))
1330 && NULL != (rsa = EVP_PKEY_get1_RSA(pkey)) ) {
1331 BN_print(bio, rsa->n);
1332 BIO_get_mem_ptr(bio, &mem);
1333 info->Set(modulus_symbol, String::New(mem->data, mem->length) );
1334 (void) BIO_reset(bio);
1336 BN_print(bio, rsa->e);
1337 BIO_get_mem_ptr(bio, &mem);
1338 info->Set(exponent_symbol, String::New(mem->data, mem->length) );
1339 (void) BIO_reset(bio);
1342 ASN1_TIME_print(bio, X509_get_notBefore(peer_cert));
1343 BIO_get_mem_ptr(bio, &mem);
1344 info->Set(valid_from_symbol, String::New(mem->data, mem->length));
1345 (void) BIO_reset(bio);
1347 ASN1_TIME_print(bio, X509_get_notAfter(peer_cert));
1348 BIO_get_mem_ptr(bio, &mem);
1349 info->Set(valid_to_symbol, String::New(mem->data, mem->length));
1352 unsigned int md_size, i;
1353 unsigned char md[EVP_MAX_MD_SIZE];
1354 if (X509_digest(peer_cert, EVP_sha1(), md, &md_size)) {
1355 const char hex[] = "0123456789ABCDEF";
1356 char fingerprint[EVP_MAX_MD_SIZE * 3];
1358 for (i=0; i<md_size; i++) {
1359 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1360 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1361 fingerprint[(3*i)+2] = ':';
1365 fingerprint[(3*(md_size-1))+2] = '\0';
1368 fingerprint[0] = '\0';
1371 info->Set(fingerprint_symbol, String::New(fingerprint));
1374 STACK_OF(ASN1_OBJECT) *eku = (STACK_OF(ASN1_OBJECT) *)X509_get_ext_d2i(
1375 peer_cert, NID_ext_key_usage, NULL, NULL);
1377 Local<Array> ext_key_usage = Array::New();
1380 for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
1381 memset(buf, 0, sizeof(buf));
1382 OBJ_obj2txt(buf, sizeof(buf) - 1, sk_ASN1_OBJECT_value(eku, i), 1);
1383 ext_key_usage->Set(Integer::New(i), String::New(buf));
1386 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1387 info->Set(ext_key_usage_symbol, ext_key_usage);
1390 X509_free(peer_cert);
1392 return scope.Close(info);
1395 Handle<Value> Connection::GetSession(const Arguments& args) {
1398 Connection *ss = Connection::Unwrap(args);
1400 if (ss->ssl_ == NULL) return Undefined();
1402 SSL_SESSION* sess = SSL_get_session(ss->ssl_);
1403 if (!sess) return Undefined();
1405 int slen = i2d_SSL_SESSION(sess, NULL);
1409 unsigned char* sbuf = new unsigned char[slen];
1410 unsigned char* p = sbuf;
1411 i2d_SSL_SESSION(sess, &p);
1412 Local<Value> s = Encode(sbuf, slen, BINARY);
1414 return scope.Close(s);
1420 Handle<Value> Connection::SetSession(const Arguments& args) {
1423 Connection *ss = Connection::Unwrap(args);
1425 if (args.Length() < 1 || !args[0]->IsString()) {
1426 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
1427 return ThrowException(exception);
1430 ASSERT_IS_STRING_OR_BUFFER(args[0]);
1431 ssize_t slen = DecodeBytes(args[0], BINARY);
1434 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
1435 return ThrowException(exception);
1438 char* sbuf = new char[slen];
1440 ssize_t wlen = DecodeWrite(sbuf, slen, args[0], BINARY);
1441 assert(wlen == slen);
1443 const unsigned char* p = (unsigned char*) sbuf;
1444 SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, wlen);
1451 int r = SSL_set_session(ss->ssl_, sess);
1452 SSL_SESSION_free(sess);
1455 Local<String> eStr = String::New("SSL_set_session error");
1456 return ThrowException(Exception::Error(eStr));
1462 Handle<Value> Connection::IsSessionReused(const Arguments& args) {
1465 Connection *ss = Connection::Unwrap(args);
1467 if (ss->ssl_ == NULL) return False();
1468 return SSL_session_reused(ss->ssl_) ? True() : False();
1472 Handle<Value> Connection::Start(const Arguments& args) {
1475 Connection *ss = Connection::Unwrap(args);
1477 if (!SSL_is_init_finished(ss->ssl_)) {
1479 if (ss->is_server_) {
1480 rv = SSL_accept(ss->ssl_);
1481 ss->HandleSSLError("SSL_accept:Start", rv);
1483 rv = SSL_connect(ss->ssl_);
1484 ss->HandleSSLError("SSL_connect:Start", rv);
1487 return scope.Close(Integer::New(rv));
1490 return scope.Close(Integer::New(0));
1494 Handle<Value> Connection::Shutdown(const Arguments& args) {
1497 Connection *ss = Connection::Unwrap(args);
1499 if (ss->ssl_ == NULL) return False();
1500 int rv = SSL_shutdown(ss->ssl_);
1502 ss->HandleSSLError("SSL_shutdown", rv);
1503 ss->SetShutdownFlags();
1505 return scope.Close(Integer::New(rv));
1509 Handle<Value> Connection::ReceivedShutdown(const Arguments& args) {
1512 Connection *ss = Connection::Unwrap(args);
1514 if (ss->ssl_ == NULL) return False();
1515 int r = SSL_get_shutdown(ss->ssl_);
1517 if (r & SSL_RECEIVED_SHUTDOWN) return True();
1523 Handle<Value> Connection::IsInitFinished(const Arguments& args) {
1526 Connection *ss = Connection::Unwrap(args);
1528 if (ss->ssl_ == NULL) return False();
1529 return SSL_is_init_finished(ss->ssl_) ? True() : False();
1533 Handle<Value> Connection::VerifyError(const Arguments& args) {
1536 Connection *ss = Connection::Unwrap(args);
1538 if (ss->ssl_ == NULL) return Null();
1541 // XXX Do this check in JS land?
1542 X509* peer_cert = SSL_get_peer_certificate(ss->ssl_);
1543 if (peer_cert == NULL) {
1544 // We requested a certificate and they did not send us one.
1545 // Definitely an error.
1546 // XXX is this the right error message?
1547 return scope.Close(Exception::Error(
1548 String::New("UNABLE_TO_GET_ISSUER_CERT")));
1550 X509_free(peer_cert);
1553 long x509_verify_error = SSL_get_verify_result(ss->ssl_);
1557 switch (x509_verify_error) {
1561 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1562 s = String::New("UNABLE_TO_GET_ISSUER_CERT");
1565 case X509_V_ERR_UNABLE_TO_GET_CRL:
1566 s = String::New("UNABLE_TO_GET_CRL");
1569 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1570 s = String::New("UNABLE_TO_DECRYPT_CERT_SIGNATURE");
1573 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1574 s = String::New("UNABLE_TO_DECRYPT_CRL_SIGNATURE");
1577 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1578 s = String::New("UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY");
1581 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1582 s = String::New("CERT_SIGNATURE_FAILURE");
1585 case X509_V_ERR_CRL_SIGNATURE_FAILURE:
1586 s = String::New("CRL_SIGNATURE_FAILURE");
1589 case X509_V_ERR_CERT_NOT_YET_VALID:
1590 s = String::New("CERT_NOT_YET_VALID");
1593 case X509_V_ERR_CERT_HAS_EXPIRED:
1594 s = String::New("CERT_HAS_EXPIRED");
1597 case X509_V_ERR_CRL_NOT_YET_VALID:
1598 s = String::New("CRL_NOT_YET_VALID");
1601 case X509_V_ERR_CRL_HAS_EXPIRED:
1602 s = String::New("CRL_HAS_EXPIRED");
1605 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1606 s = String::New("ERROR_IN_CERT_NOT_BEFORE_FIELD");
1609 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1610 s = String::New("ERROR_IN_CERT_NOT_AFTER_FIELD");
1613 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1614 s = String::New("ERROR_IN_CRL_LAST_UPDATE_FIELD");
1617 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1618 s = String::New("ERROR_IN_CRL_NEXT_UPDATE_FIELD");
1621 case X509_V_ERR_OUT_OF_MEM:
1622 s = String::New("OUT_OF_MEM");
1625 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1626 s = String::New("DEPTH_ZERO_SELF_SIGNED_CERT");
1629 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1630 s = String::New("SELF_SIGNED_CERT_IN_CHAIN");
1633 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1634 s = String::New("UNABLE_TO_GET_ISSUER_CERT_LOCALLY");
1637 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1638 s = String::New("UNABLE_TO_VERIFY_LEAF_SIGNATURE");
1641 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1642 s = String::New("CERT_CHAIN_TOO_LONG");
1645 case X509_V_ERR_CERT_REVOKED:
1646 s = String::New("CERT_REVOKED");
1649 case X509_V_ERR_INVALID_CA:
1650 s = String::New("INVALID_CA");
1653 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1654 s = String::New("PATH_LENGTH_EXCEEDED");
1657 case X509_V_ERR_INVALID_PURPOSE:
1658 s = String::New("INVALID_PURPOSE");
1661 case X509_V_ERR_CERT_UNTRUSTED:
1662 s = String::New("CERT_UNTRUSTED");
1665 case X509_V_ERR_CERT_REJECTED:
1666 s = String::New("CERT_REJECTED");
1670 s = String::New(X509_verify_cert_error_string(x509_verify_error));
1674 return scope.Close(Exception::Error(s));
1678 Handle<Value> Connection::GetCurrentCipher(const Arguments& args) {
1681 Connection *ss = Connection::Unwrap(args);
1683 OPENSSL_CONST SSL_CIPHER *c;
1685 if ( ss->ssl_ == NULL ) return Undefined();
1686 c = SSL_get_current_cipher(ss->ssl_);
1687 if ( c == NULL ) return Undefined();
1688 Local<Object> info = Object::New();
1689 const char *cipher_name = SSL_CIPHER_get_name(c);
1690 info->Set(name_symbol, String::New(cipher_name));
1691 const char *cipher_version = SSL_CIPHER_get_version(c);
1692 info->Set(version_symbol, String::New(cipher_version));
1693 return scope.Close(info);
1696 Handle<Value> Connection::Close(const Arguments& args) {
1699 Connection *ss = Connection::Unwrap(args);
1701 if (ss->ssl_ != NULL) {
1708 #ifdef OPENSSL_NPN_NEGOTIATED
1709 Handle<Value> Connection::GetNegotiatedProto(const Arguments& args) {
1712 Connection *ss = Connection::Unwrap(args);
1714 if (ss->is_server_) {
1715 const unsigned char *npn_proto;
1716 unsigned int npn_proto_len;
1718 SSL_get0_next_proto_negotiated(ss->ssl_, &npn_proto, &npn_proto_len);
1724 return String::New((const char*) npn_proto, npn_proto_len);
1726 return ss->selectedNPNProto_;
1730 Handle<Value> Connection::SetNPNProtocols(const Arguments& args) {
1733 Connection *ss = Connection::Unwrap(args);
1735 if (args.Length() < 1 || !Buffer::HasInstance(args[0])) {
1736 return ThrowException(Exception::Error(String::New(
1737 "Must give a Buffer as first argument")));
1740 // Release old handle
1741 if (!ss->npnProtos_.IsEmpty()) {
1742 ss->npnProtos_.Dispose();
1744 ss->npnProtos_ = Persistent<Object>::New(args[0]->ToObject());
1750 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1751 Handle<Value> Connection::GetServername(const Arguments& args) {
1754 Connection *ss = Connection::Unwrap(args);
1756 if (ss->is_server_ && !ss->servername_.IsEmpty()) {
1757 return ss->servername_;
1763 Handle<Value> Connection::SetSNICallback(const Arguments& args) {
1766 Connection *ss = Connection::Unwrap(args);
1768 if (args.Length() < 1 || !args[0]->IsFunction()) {
1769 return ThrowException(Exception::Error(String::New(
1770 "Must give a Function as first argument")));
1773 // Release old handle
1774 if (!ss->sniObject_.IsEmpty()) {
1775 ss->sniObject_.Dispose();
1777 ss->sniObject_ = Persistent<Object>::New(Object::New());
1778 ss->sniObject_->Set(String::New("onselect"), args[0]);
1784 static void HexEncode(unsigned char *md_value,
1786 char** md_hexdigest,
1788 *md_hex_len = (2*(md_len));
1789 *md_hexdigest = new char[*md_hex_len + 1];
1791 char* buff = *md_hexdigest;
1792 const int len = *md_hex_len;
1793 for (int i = 0; i < len; i += 2) {
1795 const int index = i / 2;
1796 const char msb = (md_value[index] >> 4) & 0x0f;
1797 const char lsb = md_value[index] & 0x0f;
1799 buff[i] = (msb < 10) ? msb + '0' : (msb - 10) + 'a';
1800 buff[i + 1] = (lsb < 10) ? lsb + '0' : (lsb - 10) + 'a';
1803 buff[*md_hex_len] = '\0';
1806 #define hex2i(c) ((c) <= '9' ? ((c) - '0') : (c) <= 'Z' ? ((c) - 'A' + 10) \
1809 static void HexDecode(unsigned char *input,
1813 *buf64_len = (length/2);
1814 *buf64 = new char[length/2 + 1];
1816 for(int i = 0; i < length-1; i+=2) {
1817 b[i/2] = (hex2i(input[i])<<4) | (hex2i(input[i+1]));
1822 void base64(unsigned char *input, int length, char** buf64, int* buf64_len) {
1823 BIO *b64 = BIO_new(BIO_f_base64());
1824 BIO *bmem = BIO_new(BIO_s_mem());
1825 b64 = BIO_push(b64, bmem);
1826 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
1827 int len = BIO_write(b64, input, length);
1828 assert(len == length);
1829 int r = BIO_flush(b64);
1833 BIO_get_mem_ptr(b64, &bptr);
1835 *buf64_len = bptr->length;
1836 *buf64 = new char[*buf64_len+1];
1837 memcpy(*buf64, bptr->data, *buf64_len);
1845 void unbase64(unsigned char *input,
1850 *buffer = new char[length];
1851 memset(*buffer, 0, length);
1853 b64 = BIO_new(BIO_f_base64());
1854 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
1855 bmem = BIO_new_mem_buf(input, length);
1856 bmem = BIO_push(b64, bmem);
1858 *buffer_len = BIO_read(bmem, *buffer, length);
1863 // LengthWithoutIncompleteUtf8 from V8 d8-posix.cc
1864 // see http://v8.googlecode.com/svn/trunk/src/d8-posix.cc
1865 static int LengthWithoutIncompleteUtf8(char* buffer, int len) {
1868 static const int kUtf8SingleByteMask = 0x80;
1869 static const int kUtf8SingleByteValue = 0x00;
1871 static const int kUtf8TwoByteMask = 0xe0;
1872 static const int kUtf8TwoByteValue = 0xc0;
1874 static const int kUtf8ThreeByteMask = 0xf0;
1875 static const int kUtf8ThreeByteValue = 0xe0;
1877 static const int kUtf8FourByteMask = 0xf8;
1878 static const int kUtf8FourByteValue = 0xf0;
1879 // Subsequent bytes of a multi-byte encoding.
1880 static const int kMultiByteMask = 0xc0;
1881 static const int kMultiByteValue = 0x80;
1882 int multi_byte_bytes_seen = 0;
1883 while (answer > 0) {
1884 int c = buffer[answer - 1];
1885 // Ends in valid single-byte sequence?
1886 if ((c & kUtf8SingleByteMask) == kUtf8SingleByteValue) return answer;
1887 // Ends in one or more subsequent bytes of a multi-byte value?
1888 if ((c & kMultiByteMask) == kMultiByteValue) {
1889 multi_byte_bytes_seen++;
1892 if ((c & kUtf8TwoByteMask) == kUtf8TwoByteValue) {
1893 if (multi_byte_bytes_seen >= 1) {
1897 } else if ((c & kUtf8ThreeByteMask) == kUtf8ThreeByteValue) {
1898 if (multi_byte_bytes_seen >= 2) {
1902 } else if ((c & kUtf8FourByteMask) == kUtf8FourByteValue) {
1903 if (multi_byte_bytes_seen >= 3) {
1908 return answer; // Malformed UTF-8.
1916 // local decrypt final without strict padding check
1917 // to work with php mcrypt
1918 // see http://www.mail-archive.com/openssl-dev@openssl.org/msg19927.html
1919 int local_EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx,
1926 b=ctx->cipher->block_size;
1928 if (ctx->flags & EVP_CIPH_NO_PADDING) {
1930 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
1938 if (ctx->buf_len || !ctx->final_used) {
1939 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
1943 if (b > (int)(sizeof(ctx->final) / sizeof(ctx->final[0]))) {
1944 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
1951 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
1955 for (i=0; i<n; i++) {
1956 if (ctx->final[--b] != n) {
1957 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
1962 n=ctx->cipher->block_size-n;
1964 for (i=0; i<n; i++) {
1965 out[i]=ctx->final[i];
1976 class Cipher : public ObjectWrap {
1978 static void Initialize (v8::Handle<v8::Object> target) {
1981 Local<FunctionTemplate> t = FunctionTemplate::New(New);
1983 t->InstanceTemplate()->SetInternalFieldCount(1);
1985 NODE_SET_PROTOTYPE_METHOD(t, "init", CipherInit);
1986 NODE_SET_PROTOTYPE_METHOD(t, "initiv", CipherInitIv);
1987 NODE_SET_PROTOTYPE_METHOD(t, "update", CipherUpdate);
1988 NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
1989 NODE_SET_PROTOTYPE_METHOD(t, "final", CipherFinal);
1991 target->Set(String::NewSymbol("Cipher"), t->GetFunction());
1995 bool CipherInit(char* cipherType, char* key_buf, int key_buf_len) {
1996 cipher = EVP_get_cipherbyname(cipherType);
1998 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2002 unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
2003 int key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL,
2004 (unsigned char*) key_buf, key_buf_len, 1, key, iv);
2006 EVP_CIPHER_CTX_init(&ctx);
2007 EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, NULL, true);
2008 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2009 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2010 EVP_CIPHER_CTX_cleanup(&ctx);
2013 EVP_CipherInit_ex(&ctx, NULL, NULL,
2014 (unsigned char *)key,
2015 (unsigned char *)iv, true);
2016 initialised_ = true;
2021 bool CipherInitIv(char* cipherType,
2026 cipher = EVP_get_cipherbyname(cipherType);
2028 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2031 /* OpenSSL versions up to 0.9.8l failed to return the correct
2032 iv_length (0) for ECB ciphers */
2033 if (EVP_CIPHER_iv_length(cipher) != iv_len &&
2034 !(EVP_CIPHER_mode(cipher) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2035 fprintf(stderr, "node-crypto : Invalid IV length %d\n", iv_len);
2038 EVP_CIPHER_CTX_init(&ctx);
2039 EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, NULL, true);
2040 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2041 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2042 EVP_CIPHER_CTX_cleanup(&ctx);
2045 EVP_CipherInit_ex(&ctx, NULL, NULL,
2046 (unsigned char *)key,
2047 (unsigned char *)iv, true);
2048 initialised_ = true;
2052 int CipherUpdate(char* data, int len, unsigned char** out, int* out_len) {
2053 if (!initialised_) return 0;
2054 *out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
2055 *out= new unsigned char[*out_len];
2057 EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
2061 int SetAutoPadding(bool auto_padding) {
2062 if (!initialised_) return 0;
2063 return EVP_CIPHER_CTX_set_padding(&ctx, auto_padding ? 1 : 0);
2066 int CipherFinal(unsigned char** out, int *out_len) {
2067 if (!initialised_) return 0;
2068 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx)];
2069 int r = EVP_CipherFinal_ex(&ctx,*out, out_len);
2070 EVP_CIPHER_CTX_cleanup(&ctx);
2071 initialised_ = false;
2078 static Handle<Value> New(const Arguments& args) {
2081 Cipher *cipher = new Cipher();
2082 cipher->Wrap(args.This());
2086 static Handle<Value> CipherInit(const Arguments& args) {
2089 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2091 cipher->incomplete_base64 = NULL;
2093 if (args.Length() <= 1
2094 || !args[0]->IsString()
2095 || !(args[1]->IsString() || Buffer::HasInstance(args[1])))
2097 return ThrowException(Exception::Error(String::New(
2098 "Must give cipher-type, key")));
2101 ASSERT_IS_STRING_OR_BUFFER(args[1]);
2102 ssize_t key_buf_len = DecodeBytes(args[1], BINARY);
2104 if (key_buf_len < 0) {
2105 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2106 return ThrowException(exception);
2109 char* key_buf = new char[key_buf_len];
2110 ssize_t key_written = DecodeWrite(key_buf, key_buf_len, args[1], BINARY);
2111 assert(key_written == key_buf_len);
2113 String::Utf8Value cipherType(args[0]);
2115 bool r = cipher->CipherInit(*cipherType, key_buf, key_buf_len);
2120 return ThrowException(Exception::Error(String::New("CipherInit error")));
2127 static Handle<Value> CipherInitIv(const Arguments& args) {
2128 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2132 cipher->incomplete_base64 = NULL;
2134 if (args.Length() <= 2
2135 || !args[0]->IsString()
2136 || !(args[1]->IsString() || Buffer::HasInstance(args[1]))
2137 || !(args[2]->IsString() || Buffer::HasInstance(args[2])))
2139 return ThrowException(Exception::Error(String::New(
2140 "Must give cipher-type, key, and iv as argument")));
2143 ASSERT_IS_STRING_OR_BUFFER(args[1]);
2144 ssize_t key_len = DecodeBytes(args[1], BINARY);
2147 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2148 return ThrowException(exception);
2151 ASSERT_IS_STRING_OR_BUFFER(args[2]);
2152 ssize_t iv_len = DecodeBytes(args[2], BINARY);
2155 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2156 return ThrowException(exception);
2159 char* key_buf = new char[key_len];
2160 ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY);
2161 assert(key_written == key_len);
2163 char* iv_buf = new char[iv_len];
2164 ssize_t iv_written = DecodeWrite(iv_buf, iv_len, args[2], BINARY);
2165 assert(iv_written == iv_len);
2167 String::Utf8Value cipherType(args[0]);
2169 bool r = cipher->CipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
2175 return ThrowException(Exception::Error(String::New("CipherInitIv error")));
2181 static Handle<Value> CipherUpdate(const Arguments& args) {
2182 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2186 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2188 enum encoding enc = ParseEncoding(args[1]);
2189 ssize_t len = DecodeBytes(args[0], enc);
2192 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2193 return ThrowException(exception);
2196 unsigned char *out=0;
2198 if (Buffer::HasInstance(args[0])) {
2199 Local<Object> buffer_obj = args[0]->ToObject();
2200 char *buffer_data = Buffer::Data(buffer_obj);
2201 size_t buffer_length = Buffer::Length(buffer_obj);
2203 r = cipher->CipherUpdate(buffer_data, buffer_length, &out, &out_len);
2205 char* buf = new char[len];
2206 ssize_t written = DecodeWrite(buf, len, args[0], enc);
2207 assert(written == len);
2208 r = cipher->CipherUpdate(buf, len,&out,&out_len);
2214 Local<Value> exception = Exception::TypeError(String::New("DecipherUpdate fail"));
2215 return ThrowException(exception);
2218 Local<Value> outString;
2220 outString=String::New("");
2222 char* out_hexdigest;
2224 enum encoding enc = ParseEncoding(args[2], BINARY);
2227 HexEncode(out, out_len, &out_hexdigest, &out_hex_len);
2228 outString = Encode(out_hexdigest, out_hex_len, BINARY);
2229 delete [] out_hexdigest;
2230 } else if (enc == BASE64) {
2232 // Check to see if we need to add in previous base64 overhang
2233 if (cipher->incomplete_base64!=NULL){
2234 unsigned char* complete_base64 = new unsigned char[out_len+cipher->incomplete_base64_len+1];
2235 memcpy(complete_base64, cipher->incomplete_base64, cipher->incomplete_base64_len);
2236 memcpy(&complete_base64[cipher->incomplete_base64_len], out, out_len);
2239 delete [] cipher->incomplete_base64;
2240 cipher->incomplete_base64=NULL;
2242 out=complete_base64;
2243 out_len += cipher->incomplete_base64_len;
2246 // Check to see if we need to trim base64 stream
2248 cipher->incomplete_base64_len = out_len%3;
2249 cipher->incomplete_base64 = new char[cipher->incomplete_base64_len+1];
2250 memcpy(cipher->incomplete_base64,
2251 &out[out_len-cipher->incomplete_base64_len],
2252 cipher->incomplete_base64_len);
2253 out_len -= cipher->incomplete_base64_len;
2257 base64(out, out_len, &out_hexdigest, &out_hex_len);
2258 outString = Encode(out_hexdigest, out_hex_len, BINARY);
2259 delete [] out_hexdigest;
2260 } else if (enc == BINARY) {
2261 outString = Encode(out, out_len, BINARY);
2263 fprintf(stderr, "node-crypto : Cipher .update encoding "
2264 "can be binary, hex or base64\n");
2268 if (out) delete [] out;
2270 return scope.Close(outString);
2273 static Handle<Value> SetAutoPadding(const Arguments& args) {
2275 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2277 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2282 static Handle<Value> CipherFinal(const Arguments& args) {
2283 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
2287 unsigned char* out_value = NULL;
2289 char* out_hexdigest;
2291 Local<Value> outString ;
2293 int r = cipher->CipherFinal(&out_value, &out_len);
2295 assert(out_value != NULL);
2296 assert(out_len != -1 || r == 0);
2298 if (out_len == 0 || r == 0) {
2299 // out_value always get allocated.
2302 Local<Value> exception = Exception::TypeError(
2303 String::New("CipherFinal fail"));
2304 return ThrowException(exception);
2306 return scope.Close(String::New(""));
2310 enum encoding enc = ParseEncoding(args[0], BINARY);
2313 HexEncode(out_value, out_len, &out_hexdigest, &out_hex_len);
2314 outString = Encode(out_hexdigest, out_hex_len, BINARY);
2315 delete [] out_hexdigest;
2316 } else if (enc == BASE64) {
2317 // Check to see if we need to add in previous base64 overhang
2318 if (cipher->incomplete_base64!=NULL){
2319 unsigned char* complete_base64 = new unsigned char[out_len+cipher->incomplete_base64_len+1];
2320 memcpy(complete_base64, cipher->incomplete_base64, cipher->incomplete_base64_len);
2321 memcpy(&complete_base64[cipher->incomplete_base64_len], out_value, out_len);
2322 delete [] out_value;
2324 delete [] cipher->incomplete_base64;
2325 cipher->incomplete_base64=NULL;
2327 out_value=complete_base64;
2328 out_len += cipher->incomplete_base64_len;
2330 base64(out_value, out_len, &out_hexdigest, &out_hex_len);
2331 outString = Encode(out_hexdigest, out_hex_len, BINARY);
2332 delete [] out_hexdigest;
2333 } else if (enc == BINARY) {
2334 outString = Encode(out_value, out_len, BINARY);
2336 fprintf(stderr, "node-crypto : Cipher .final encoding "
2337 "can be binary, hex or base64\n");
2340 delete [] out_value;
2341 return scope.Close(outString);
2344 Cipher () : ObjectWrap ()
2346 initialised_ = false;
2351 EVP_CIPHER_CTX_cleanup(&ctx);
2357 EVP_CIPHER_CTX ctx; /* coverity[member_decl] */
2358 const EVP_CIPHER *cipher; /* coverity[member_decl] */
2360 char* incomplete_base64; /* coverity[member_decl] */
2361 int incomplete_base64_len; /* coverity[member_decl] */
2367 class Decipher : public ObjectWrap {
2370 Initialize (v8::Handle<v8::Object> target)
2374 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2376 t->InstanceTemplate()->SetInternalFieldCount(1);
2378 NODE_SET_PROTOTYPE_METHOD(t, "init", DecipherInit);
2379 NODE_SET_PROTOTYPE_METHOD(t, "initiv", DecipherInitIv);
2380 NODE_SET_PROTOTYPE_METHOD(t, "update", DecipherUpdate);
2381 NODE_SET_PROTOTYPE_METHOD(t, "final", DecipherFinal<false>);
2382 // This is completely undocumented:
2383 NODE_SET_PROTOTYPE_METHOD(t, "finaltol", DecipherFinal<true>);
2384 NODE_SET_PROTOTYPE_METHOD(t, "setAutoPadding", SetAutoPadding);
2386 target->Set(String::NewSymbol("Decipher"), t->GetFunction());
2389 bool DecipherInit(char* cipherType, char* key_buf, int key_buf_len) {
2390 cipher_ = EVP_get_cipherbyname(cipherType);
2393 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2397 unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
2398 int key_len = EVP_BytesToKey(cipher_,
2401 (unsigned char*)(key_buf),
2407 EVP_CIPHER_CTX_init(&ctx);
2408 EVP_CipherInit_ex(&ctx, cipher_, NULL, NULL, NULL, false);
2409 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2410 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2411 EVP_CIPHER_CTX_cleanup(&ctx);
2414 EVP_CipherInit_ex(&ctx, NULL, NULL,
2415 (unsigned char *)key,
2416 (unsigned char *)iv, false);
2417 initialised_ = true;
2422 bool DecipherInitIv(char* cipherType,
2427 cipher_ = EVP_get_cipherbyname(cipherType);
2429 fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
2432 /* OpenSSL versions up to 0.9.8l failed to return the correct
2433 iv_length (0) for ECB ciphers */
2434 if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
2435 !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
2436 fprintf(stderr, "node-crypto : Invalid IV length %d\n", iv_len);
2439 EVP_CIPHER_CTX_init(&ctx);
2440 EVP_CipherInit_ex(&ctx, cipher_, NULL, NULL, NULL, false);
2441 if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
2442 fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
2443 EVP_CIPHER_CTX_cleanup(&ctx);
2446 EVP_CipherInit_ex(&ctx, NULL, NULL,
2447 (unsigned char *)key,
2448 (unsigned char *)iv, false);
2449 initialised_ = true;
2453 int DecipherUpdate(char* data, int len, unsigned char** out, int* out_len) {
2454 if (!initialised_) {
2460 *out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
2461 *out= new unsigned char[*out_len];
2463 EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
2467 int SetAutoPadding(bool auto_padding) {
2468 if (!initialised_) return 0;
2469 return EVP_CIPHER_CTX_set_padding(&ctx, auto_padding ? 1 : 0);
2472 // coverity[alloc_arg]
2473 template <bool TOLERATE_PADDING>
2474 int DecipherFinal(unsigned char** out, int *out_len) {
2477 if (!initialised_) {
2483 *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx)];
2484 if (TOLERATE_PADDING) {
2485 r = local_EVP_DecryptFinal_ex(&ctx,*out,out_len);
2487 r = EVP_CipherFinal_ex(&ctx,*out,out_len);
2489 EVP_CIPHER_CTX_cleanup(&ctx);
2490 initialised_ = false;
2497 static Handle<Value> New (const Arguments& args) {
2500 Decipher *cipher = new Decipher();
2501 cipher->Wrap(args.This());
2505 static Handle<Value> DecipherInit(const Arguments& args) {
2506 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2510 cipher->incomplete_utf8 = NULL;
2511 cipher->incomplete_hex_flag = false;
2513 if (args.Length() <= 1
2514 || !args[0]->IsString()
2515 || !(args[1]->IsString() || Buffer::HasInstance(args[1])))
2517 return ThrowException(Exception::Error(String::New(
2518 "Must give cipher-type, key as argument")));
2521 ASSERT_IS_STRING_OR_BUFFER(args[1]);
2522 ssize_t key_len = DecodeBytes(args[1], BINARY);
2525 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2526 return ThrowException(exception);
2529 char* key_buf = new char[key_len];
2530 ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY);
2531 assert(key_written == key_len);
2533 String::Utf8Value cipherType(args[0]);
2535 bool r = cipher->DecipherInit(*cipherType, key_buf,key_len);
2540 return ThrowException(Exception::Error(String::New("DecipherInit error")));
2546 static Handle<Value> DecipherInitIv(const Arguments& args) {
2547 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2551 cipher->incomplete_utf8 = NULL;
2552 cipher->incomplete_hex_flag = false;
2554 if (args.Length() <= 2
2555 || !args[0]->IsString()
2556 || !(args[1]->IsString() || Buffer::HasInstance(args[1]))
2557 || !(args[2]->IsString() || Buffer::HasInstance(args[2])))
2559 return ThrowException(Exception::Error(String::New(
2560 "Must give cipher-type, key, and iv as argument")));
2563 ASSERT_IS_STRING_OR_BUFFER(args[1]);
2564 ssize_t key_len = DecodeBytes(args[1], BINARY);
2567 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2568 return ThrowException(exception);
2571 ASSERT_IS_STRING_OR_BUFFER(args[2]);
2572 ssize_t iv_len = DecodeBytes(args[2], BINARY);
2575 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2576 return ThrowException(exception);
2579 char* key_buf = new char[key_len];
2580 ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY);
2581 assert(key_written == key_len);
2583 char* iv_buf = new char[iv_len];
2584 ssize_t iv_written = DecodeWrite(iv_buf, iv_len, args[2], BINARY);
2585 assert(iv_written == iv_len);
2587 String::Utf8Value cipherType(args[0]);
2589 bool r = cipher->DecipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
2595 return ThrowException(Exception::Error(String::New("DecipherInitIv error")));
2601 static Handle<Value> DecipherUpdate(const Arguments& args) {
2604 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2606 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2608 ssize_t len = DecodeBytes(args[0], BINARY);
2610 return ThrowException(Exception::Error(String::New(
2611 "node`DecodeBytes() failed")));
2615 // if alloc_buf then buf must be deleted later
2616 bool alloc_buf = false;
2617 if (Buffer::HasInstance(args[0])) {
2618 Local<Object> buffer_obj = args[0]->ToObject();
2619 char *buffer_data = Buffer::Data(buffer_obj);
2620 size_t buffer_length = Buffer::Length(buffer_obj);
2623 len = buffer_length;
2626 buf = new char[len];
2627 ssize_t written = DecodeWrite(buf, len, args[0], BINARY);
2628 assert(written == len);
2634 enum encoding enc = ParseEncoding(args[1], BINARY);
2637 // Do we have a previous hex carry over?
2638 if (cipher->incomplete_hex_flag) {
2639 char* complete_hex = new char[len+2];
2640 memcpy(complete_hex, &cipher->incomplete_hex, 1);
2641 memcpy(complete_hex+1, buf, len);
2642 if (alloc_buf) delete [] buf;
2647 // Do we have an incomplete hex stream?
2648 if ((len>0) && (len % 2 !=0)) {
2650 cipher->incomplete_hex=buf[len];
2651 cipher->incomplete_hex_flag=true;
2654 HexDecode((unsigned char*)buf, len, (char **)&ciphertext, &ciphertext_len);
2660 len = ciphertext_len;
2663 } else if (enc == BASE64) {
2664 unbase64((unsigned char*)buf, len, (char **)&ciphertext, &ciphertext_len);
2669 len = ciphertext_len;
2672 } else if (enc == BINARY) {
2673 // Binary - do nothing
2676 fprintf(stderr, "node-crypto : Decipher .update encoding "
2677 "can be binary, hex or base64\n");
2680 unsigned char *out=0;
2682 int r = cipher->DecipherUpdate(buf, len, &out, &out_len);
2686 Local<Value> exception = Exception::TypeError(String::New("DecipherUpdate fail"));
2687 return ThrowException(exception);
2690 Local<Value> outString;
2692 outString=String::New("");
2694 enum encoding enc = ParseEncoding(args[2], BINARY);
2696 // See if we have any overhang from last utf8 partial ending
2697 if (cipher->incomplete_utf8!=NULL) {
2698 char* complete_out = new char[cipher->incomplete_utf8_len + out_len];
2699 memcpy(complete_out, cipher->incomplete_utf8, cipher->incomplete_utf8_len);
2700 memcpy((char *)complete_out+cipher->incomplete_utf8_len, out, out_len);
2703 delete [] cipher->incomplete_utf8;
2704 cipher->incomplete_utf8 = NULL;
2706 out = (unsigned char*)complete_out;
2707 out_len += cipher->incomplete_utf8_len;
2709 // Check to see if we have a complete utf8 stream
2710 int utf8_len = LengthWithoutIncompleteUtf8((char *)out, out_len);
2711 if (utf8_len<out_len) { // We have an incomplete ut8 ending
2712 cipher->incomplete_utf8_len = out_len-utf8_len;
2713 cipher->incomplete_utf8 = new unsigned char[cipher->incomplete_utf8_len+1];
2714 memcpy(cipher->incomplete_utf8, &out[utf8_len], cipher->incomplete_utf8_len);
2716 outString = Encode(out, utf8_len, enc);
2718 outString = Encode(out, out_len, enc);
2722 if (out) delete [] out;
2724 if (alloc_buf) delete [] buf;
2725 return scope.Close(outString);
2729 static Handle<Value> SetAutoPadding(const Arguments& args) {
2731 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2733 cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
2738 template <bool TOLERATE_PADDING>
2739 static Handle<Value> DecipherFinal(const Arguments& args) {
2742 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
2744 unsigned char* out_value = NULL;
2746 Local<Value> outString;
2748 int r = cipher->DecipherFinal<TOLERATE_PADDING>(&out_value, &out_len);
2750 assert(out_value != NULL);
2751 assert(out_len != -1);
2753 if (out_len == 0 || r == 0) {
2754 delete [] out_value; // allocated even if out_len == 0
2756 Local<Value> exception = Exception::TypeError(
2757 String::New("DecipherFinal fail"));
2758 return ThrowException(exception);
2760 return scope.Close(String::New(""));
2764 if (args.Length() == 0 || !args[0]->IsString()) {
2765 outString = Encode(out_value, out_len, BINARY);
2767 enum encoding enc = ParseEncoding(args[0]);
2769 // See if we have any overhang from last utf8 partial ending
2770 if (cipher->incomplete_utf8!=NULL) {
2771 char* complete_out = new char[cipher->incomplete_utf8_len + out_len];
2772 memcpy(complete_out, cipher->incomplete_utf8, cipher->incomplete_utf8_len);
2773 memcpy((char *)complete_out+cipher->incomplete_utf8_len, out_value, out_len);
2775 delete [] cipher->incomplete_utf8;
2776 cipher->incomplete_utf8=NULL;
2778 outString = Encode(complete_out, cipher->incomplete_utf8_len+out_len, enc);
2779 delete [] complete_out;
2781 outString = Encode(out_value, out_len, enc);
2784 outString = Encode(out_value, out_len, enc);
2787 delete [] out_value;
2788 return scope.Close(outString);
2791 Decipher () : ObjectWrap () {
2792 initialised_ = false;
2797 EVP_CIPHER_CTX_cleanup(&ctx);
2804 const EVP_CIPHER *cipher_;
2806 unsigned char* incomplete_utf8;
2807 int incomplete_utf8_len;
2808 char incomplete_hex;
2809 bool incomplete_hex_flag;
2815 class Hmac : public ObjectWrap {
2817 static void Initialize (v8::Handle<v8::Object> target) {
2820 Local<FunctionTemplate> t = FunctionTemplate::New(New);
2822 t->InstanceTemplate()->SetInternalFieldCount(1);
2824 NODE_SET_PROTOTYPE_METHOD(t, "init", HmacInit);
2825 NODE_SET_PROTOTYPE_METHOD(t, "update", HmacUpdate);
2826 NODE_SET_PROTOTYPE_METHOD(t, "digest", HmacDigest);
2828 target->Set(String::NewSymbol("Hmac"), t->GetFunction());
2831 bool HmacInit(char* hashType, char* key, int key_len) {
2832 md = EVP_get_digestbyname(hashType);
2834 fprintf(stderr, "node-crypto : Unknown message digest %s\n", hashType);
2837 HMAC_CTX_init(&ctx);
2838 HMAC_Init(&ctx, key, key_len, md);
2839 initialised_ = true;
2844 int HmacUpdate(char* data, int len) {
2845 if (!initialised_) return 0;
2846 HMAC_Update(&ctx, (unsigned char*)data, len);
2850 int HmacDigest(unsigned char** md_value, unsigned int *md_len) {
2851 if (!initialised_) return 0;
2852 *md_value = new unsigned char[EVP_MAX_MD_SIZE];
2853 HMAC_Final(&ctx, *md_value, md_len);
2854 HMAC_CTX_cleanup(&ctx);
2855 initialised_ = false;
2862 static Handle<Value> New (const Arguments& args) {
2865 Hmac *hmac = new Hmac();
2866 hmac->Wrap(args.This());
2870 static Handle<Value> HmacInit(const Arguments& args) {
2871 Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());
2875 if (args.Length() == 0 || !args[0]->IsString()) {
2876 return ThrowException(Exception::Error(String::New(
2877 "Must give hashtype string as argument")));
2880 ASSERT_IS_STRING_OR_BUFFER(args[1]);
2881 ssize_t len = DecodeBytes(args[1], BINARY);
2884 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2885 return ThrowException(exception);
2888 String::Utf8Value hashType(args[0]);
2892 if( Buffer::HasInstance(args[1])) {
2893 Local<Object> buffer_obj = args[1]->ToObject();
2894 char* buffer_data = Buffer::Data(buffer_obj);
2895 size_t buffer_length = Buffer::Length(buffer_obj);
2897 r = hmac->HmacInit(*hashType, buffer_data, buffer_length);
2899 char* buf = new char[len];
2900 ssize_t written = DecodeWrite(buf, len, args[1], BINARY);
2901 assert(written == len);
2903 r = hmac->HmacInit(*hashType, buf, len);
2909 return ThrowException(Exception::Error(String::New("hmac error")));
2915 static Handle<Value> HmacUpdate(const Arguments& args) {
2916 Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());
2920 ASSERT_IS_STRING_OR_BUFFER(args[0]);
2921 enum encoding enc = ParseEncoding(args[1]);
2922 ssize_t len = DecodeBytes(args[0], enc);
2925 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
2926 return ThrowException(exception);
2931 if( Buffer::HasInstance(args[0])) {
2932 Local<Object> buffer_obj = args[0]->ToObject();
2933 char *buffer_data = Buffer::Data(buffer_obj);
2934 size_t buffer_length = Buffer::Length(buffer_obj);
2936 r = hmac->HmacUpdate(buffer_data, buffer_length);
2938 char* buf = new char[len];
2939 ssize_t written = DecodeWrite(buf, len, args[0], enc);
2940 assert(written == len);
2941 r = hmac->HmacUpdate(buf, len);
2946 Local<Value> exception = Exception::TypeError(String::New("HmacUpdate fail"));
2947 return ThrowException(exception);
2953 static Handle<Value> HmacDigest(const Arguments& args) {
2954 Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());
2958 unsigned char* md_value = NULL;
2959 unsigned int md_len = 0;
2962 Local<Value> outString;
2964 int r = hmac->HmacDigest(&md_value, &md_len);
2965 if (md_len == 0 || r == 0) {
2966 return scope.Close(String::New(""));
2969 enum encoding enc = ParseEncoding(args[0], BINARY);
2972 HexEncode(md_value, md_len, &md_hexdigest, &md_hex_len);
2973 outString = Encode(md_hexdigest, md_hex_len, BINARY);
2974 delete [] md_hexdigest;
2975 } else if (enc == BASE64) {
2976 base64(md_value, md_len, &md_hexdigest, &md_hex_len);
2977 outString = Encode(md_hexdigest, md_hex_len, BINARY);
2978 delete [] md_hexdigest;
2979 } else if (enc == BINARY) {
2980 outString = Encode(md_value, md_len, BINARY);
2982 fprintf(stderr, "node-crypto : Hmac .digest encoding "
2983 "can be binary, hex or base64\n");
2986 return scope.Close(outString);
2989 Hmac () : ObjectWrap () {
2990 initialised_ = false;
2995 HMAC_CTX_cleanup(&ctx);
3001 HMAC_CTX ctx; /* coverity[member_decl] */
3002 const EVP_MD *md; /* coverity[member_decl] */
3007 class Hash : public ObjectWrap {
3009 static void Initialize (v8::Handle<v8::Object> target) {
3012 Local<FunctionTemplate> t = FunctionTemplate::New(New);
3014 t->InstanceTemplate()->SetInternalFieldCount(1);
3016 NODE_SET_PROTOTYPE_METHOD(t, "update", HashUpdate);
3017 NODE_SET_PROTOTYPE_METHOD(t, "digest", HashDigest);
3019 target->Set(String::NewSymbol("Hash"), t->GetFunction());
3022 bool HashInit (const char* hashType) {
3023 md = EVP_get_digestbyname(hashType);
3024 if(!md) return false;
3025 EVP_MD_CTX_init(&mdctx);
3026 EVP_DigestInit_ex(&mdctx, md, NULL);
3027 initialised_ = true;
3031 int HashUpdate(char* data, int len) {
3032 if (!initialised_) return 0;
3033 EVP_DigestUpdate(&mdctx, data, len);
3040 static Handle<Value> New (const Arguments& args) {
3043 if (args.Length() == 0 || !args[0]->IsString()) {
3044 return ThrowException(Exception::Error(String::New(
3045 "Must give hashtype string as argument")));
3048 String::Utf8Value hashType(args[0]);
3050 Hash *hash = new Hash();
3051 if (!hash->HashInit(*hashType)) {
3053 return ThrowException(Exception::Error(String::New(
3054 "Digest method not supported")));
3057 hash->Wrap(args.This());
3061 static Handle<Value> HashUpdate(const Arguments& args) {
3064 Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
3066 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3067 enum encoding enc = ParseEncoding(args[1]);
3068 ssize_t len = DecodeBytes(args[0], enc);
3071 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3072 return ThrowException(exception);
3077 if (Buffer::HasInstance(args[0])) {
3078 Local<Object> buffer_obj = args[0]->ToObject();
3079 char *buffer_data = Buffer::Data(buffer_obj);
3080 size_t buffer_length = Buffer::Length(buffer_obj);
3081 r = hash->HashUpdate(buffer_data, buffer_length);
3083 char* buf = new char[len];
3084 ssize_t written = DecodeWrite(buf, len, args[0], enc);
3085 assert(written == len);
3086 r = hash->HashUpdate(buf, len);
3091 Local<Value> exception = Exception::TypeError(String::New("HashUpdate fail"));
3092 return ThrowException(exception);
3098 static Handle<Value> HashDigest(const Arguments& args) {
3101 Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
3103 if (!hash->initialised_) {
3104 return ThrowException(Exception::Error(String::New("Not initialized")));
3107 unsigned char md_value[EVP_MAX_MD_SIZE];
3108 unsigned int md_len;
3110 EVP_DigestFinal_ex(&hash->mdctx, md_value, &md_len);
3111 EVP_MD_CTX_cleanup(&hash->mdctx);
3112 hash->initialised_ = false;
3115 return scope.Close(String::New(""));
3118 Local<Value> outString;
3120 enum encoding enc = ParseEncoding(args[0], BINARY);
3125 HexEncode(md_value, md_len, &md_hexdigest, &md_hex_len);
3126 outString = Encode(md_hexdigest, md_hex_len, BINARY);
3127 delete [] md_hexdigest;
3128 } else if (enc == BASE64) {
3131 base64(md_value, md_len, &md_hexdigest, &md_hex_len);
3132 outString = Encode(md_hexdigest, md_hex_len, BINARY);
3133 delete [] md_hexdigest;
3134 } else if (enc == BINARY) {
3135 outString = Encode(md_value, md_len, BINARY);
3137 fprintf(stderr, "node-crypto : Hash .digest encoding "
3138 "can be binary, hex or base64\n");
3141 return scope.Close(outString);
3144 Hash () : ObjectWrap () {
3145 initialised_ = false;
3150 EVP_MD_CTX_cleanup(&mdctx);
3156 EVP_MD_CTX mdctx; /* coverity[member_decl] */
3157 const EVP_MD *md; /* coverity[member_decl] */
3161 class Sign : public ObjectWrap {
3164 Initialize (v8::Handle<v8::Object> target) {
3167 Local<FunctionTemplate> t = FunctionTemplate::New(New);
3169 t->InstanceTemplate()->SetInternalFieldCount(1);
3171 NODE_SET_PROTOTYPE_METHOD(t, "init", SignInit);
3172 NODE_SET_PROTOTYPE_METHOD(t, "update", SignUpdate);
3173 NODE_SET_PROTOTYPE_METHOD(t, "sign", SignFinal);
3175 target->Set(String::NewSymbol("Sign"), t->GetFunction());
3178 bool SignInit (const char* signType) {
3179 md = EVP_get_digestbyname(signType);
3181 printf("Unknown message digest %s\n", signType);
3184 EVP_MD_CTX_init(&mdctx);
3185 EVP_SignInit_ex(&mdctx, md, NULL);
3186 initialised_ = true;
3191 int SignUpdate(char* data, int len) {
3192 if (!initialised_) return 0;
3193 EVP_SignUpdate(&mdctx, data, len);
3197 int SignFinal(unsigned char** md_value,
3198 unsigned int *md_len,
3201 if (!initialised_) return 0;
3205 bp = BIO_new(BIO_s_mem());
3206 if(!BIO_write(bp, key_pem, key_pemLen)) return 0;
3208 pkey = PEM_read_bio_PrivateKey( bp, NULL, NULL, NULL );
3209 if (pkey == NULL) return 0;
3211 EVP_SignFinal(&mdctx, *md_value, md_len, pkey);
3212 EVP_MD_CTX_cleanup(&mdctx);
3213 initialised_ = false;
3214 EVP_PKEY_free(pkey);
3222 static Handle<Value> New (const Arguments& args) {
3225 Sign *sign = new Sign();
3226 sign->Wrap(args.This());
3231 static Handle<Value> SignInit(const Arguments& args) {
3234 Sign *sign = ObjectWrap::Unwrap<Sign>(args.This());
3236 if (args.Length() == 0 || !args[0]->IsString()) {
3237 return ThrowException(Exception::Error(String::New(
3238 "Must give signtype string as argument")));
3241 String::Utf8Value signType(args[0]);
3243 bool r = sign->SignInit(*signType);
3246 return ThrowException(Exception::Error(String::New("SignInit error")));
3252 static Handle<Value> SignUpdate(const Arguments& args) {
3253 Sign *sign = ObjectWrap::Unwrap<Sign>(args.This());
3257 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3258 enum encoding enc = ParseEncoding(args[1]);
3259 ssize_t len = DecodeBytes(args[0], enc);
3262 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3263 return ThrowException(exception);
3268 if (Buffer::HasInstance(args[0])) {
3269 Local<Object> buffer_obj = args[0]->ToObject();
3270 char *buffer_data = Buffer::Data(buffer_obj);
3271 size_t buffer_length = Buffer::Length(buffer_obj);
3273 r = sign->SignUpdate(buffer_data, buffer_length);
3275 char* buf = new char[len];
3276 ssize_t written = DecodeWrite(buf, len, args[0], enc);
3277 assert(written == len);
3278 r = sign->SignUpdate(buf, len);
3283 Local<Value> exception = Exception::TypeError(String::New("SignUpdate fail"));
3284 return ThrowException(exception);
3290 static Handle<Value> SignFinal(const Arguments& args) {
3291 Sign *sign = ObjectWrap::Unwrap<Sign>(args.This());
3295 unsigned char* md_value;
3296 unsigned int md_len;
3299 Local<Value> outString;
3301 md_len = 8192; // Maximum key size is 8192 bits
3302 md_value = new unsigned char[md_len];
3304 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3305 ssize_t len = DecodeBytes(args[0], BINARY);
3309 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3310 return ThrowException(exception);
3313 char* buf = new char[len];
3314 ssize_t written = DecodeWrite(buf, len, args[0], BINARY);
3315 assert(written == len);
3317 int r = sign->SignFinal(&md_value, &md_len, buf, len);
3321 if (md_len == 0 || r == 0) {
3323 return scope.Close(String::New(""));
3326 enum encoding enc = ParseEncoding(args[1], BINARY);
3329 HexEncode(md_value, md_len, &md_hexdigest, &md_hex_len);
3330 outString = Encode(md_hexdigest, md_hex_len, BINARY);
3331 delete [] md_hexdigest;
3332 } else if (enc == BASE64) {
3333 base64(md_value, md_len, &md_hexdigest, &md_hex_len);
3334 outString = Encode(md_hexdigest, md_hex_len, BINARY);
3335 delete [] md_hexdigest;
3336 } else if (enc == BINARY) {
3337 outString = Encode(md_value, md_len, BINARY);
3339 outString = String::New("");
3340 fprintf(stderr, "node-crypto : Sign .sign encoding "
3341 "can be binary, hex or base64\n");
3345 return scope.Close(outString);
3348 Sign () : ObjectWrap () {
3349 initialised_ = false;
3354 EVP_MD_CTX_cleanup(&mdctx);
3360 EVP_MD_CTX mdctx; /* coverity[member_decl] */
3361 const EVP_MD *md; /* coverity[member_decl] */
3365 class Verify : public ObjectWrap {
3367 static void Initialize (v8::Handle<v8::Object> target) {
3370 Local<FunctionTemplate> t = FunctionTemplate::New(New);
3372 t->InstanceTemplate()->SetInternalFieldCount(1);
3374 NODE_SET_PROTOTYPE_METHOD(t, "init", VerifyInit);
3375 NODE_SET_PROTOTYPE_METHOD(t, "update", VerifyUpdate);
3376 NODE_SET_PROTOTYPE_METHOD(t, "verify", VerifyFinal);
3378 target->Set(String::NewSymbol("Verify"), t->GetFunction());
3382 bool VerifyInit (const char* verifyType) {
3383 md = EVP_get_digestbyname(verifyType);
3385 fprintf(stderr, "node-crypto : Unknown message digest %s\n", verifyType);
3388 EVP_MD_CTX_init(&mdctx);
3389 EVP_VerifyInit_ex(&mdctx, md, NULL);
3390 initialised_ = true;
3395 int VerifyUpdate(char* data, int len) {
3396 if (!initialised_) return 0;
3397 EVP_VerifyUpdate(&mdctx, data, len);
3402 int VerifyFinal(char* key_pem, int key_pemLen, unsigned char* sig, int siglen) {
3403 if (!initialised_) return 0;
3405 EVP_PKEY* pkey = NULL;
3410 bp = BIO_new(BIO_s_mem());
3412 ERR_print_errors_fp(stderr);
3415 if(!BIO_write(bp, key_pem, key_pemLen)) {
3416 ERR_print_errors_fp(stderr);
3420 // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3421 // Split this out into a separate function once we have more than one
3422 // consumer of public keys.
3423 if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
3424 pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
3426 ERR_print_errors_fp(stderr);
3429 } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
3430 RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
3432 pkey = EVP_PKEY_new();
3433 if (pkey) EVP_PKEY_set1_RSA(pkey, rsa);
3437 ERR_print_errors_fp(stderr);
3442 x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
3444 ERR_print_errors_fp(stderr);
3448 pkey = X509_get_pubkey(x509);
3450 ERR_print_errors_fp(stderr);
3455 r = EVP_VerifyFinal(&mdctx, sig, siglen, pkey);
3458 EVP_PKEY_free (pkey);
3463 EVP_MD_CTX_cleanup(&mdctx);
3464 initialised_ = false;
3472 static Handle<Value> New (const Arguments& args) {
3475 Verify *verify = new Verify();
3476 verify->Wrap(args.This());
3482 static Handle<Value> VerifyInit(const Arguments& args) {
3483 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
3487 if (args.Length() == 0 || !args[0]->IsString()) {
3488 return ThrowException(Exception::Error(String::New(
3489 "Must give verifytype string as argument")));
3492 String::Utf8Value verifyType(args[0]);
3494 bool r = verify->VerifyInit(*verifyType);
3497 return ThrowException(Exception::Error(String::New("VerifyInit error")));
3504 static Handle<Value> VerifyUpdate(const Arguments& args) {
3507 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
3509 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3510 enum encoding enc = ParseEncoding(args[1]);
3511 ssize_t len = DecodeBytes(args[0], enc);
3514 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3515 return ThrowException(exception);
3520 if(Buffer::HasInstance(args[0])) {
3521 Local<Object> buffer_obj = args[0]->ToObject();
3522 char *buffer_data = Buffer::Data(buffer_obj);
3523 size_t buffer_length = Buffer::Length(buffer_obj);
3525 r = verify->VerifyUpdate(buffer_data, buffer_length);
3527 char* buf = new char[len];
3528 ssize_t written = DecodeWrite(buf, len, args[0], enc);
3529 assert(written == len);
3530 r = verify->VerifyUpdate(buf, len);
3535 Local<Value> exception = Exception::TypeError(String::New("VerifyUpdate fail"));
3536 return ThrowException(exception);
3543 static Handle<Value> VerifyFinal(const Arguments& args) {
3546 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
3548 ASSERT_IS_STRING_OR_BUFFER(args[0]);
3549 ssize_t klen = DecodeBytes(args[0], BINARY);
3552 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3553 return ThrowException(exception);
3556 char* kbuf = new char[klen];
3557 ssize_t kwritten = DecodeWrite(kbuf, klen, args[0], BINARY);
3558 assert(kwritten == klen);
3560 ASSERT_IS_STRING_OR_BUFFER(args[1]);
3561 ssize_t hlen = DecodeBytes(args[1], BINARY);
3565 Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
3566 return ThrowException(exception);
3569 unsigned char* hbuf = new unsigned char[hlen];
3570 ssize_t hwritten = DecodeWrite((char *)hbuf, hlen, args[1], BINARY);
3571 assert(hwritten == hlen);
3572 unsigned char* dbuf;
3577 enum encoding enc = ParseEncoding(args[2], BINARY);
3580 HexDecode(hbuf, hlen, (char **)&dbuf, &dlen);
3581 r = verify->VerifyFinal(kbuf, klen, dbuf, dlen);
3583 } else if (enc == BASE64) {
3585 unbase64(hbuf, hlen, (char **)&dbuf, &dlen);
3586 r = verify->VerifyFinal(kbuf, klen, dbuf, dlen);
3588 } else if (enc == BINARY) {
3589 r = verify->VerifyFinal(kbuf, klen, hbuf, hlen);
3591 fprintf(stderr, "node-crypto : Verify .verify encoding "
3592 "can be binary, hex or base64\n");
3598 return Boolean::New(r && r != -1);
3601 Verify () : ObjectWrap () {
3602 initialised_ = false;
3607 EVP_MD_CTX_cleanup(&mdctx);
3613 EVP_MD_CTX mdctx; /* coverity[member_decl] */
3614 const EVP_MD *md; /* coverity[member_decl] */
3619 class DiffieHellman : public ObjectWrap {
3621 static void Initialize(v8::Handle<v8::Object> target) {
3624 Local<FunctionTemplate> t = FunctionTemplate::New(New);
3626 t->InstanceTemplate()->SetInternalFieldCount(1);
3628 NODE_SET_PROTOTYPE_METHOD(t, "generateKeys", GenerateKeys);
3629 NODE_SET_PROTOTYPE_METHOD(t, "computeSecret", ComputeSecret);
3630 NODE_SET_PROTOTYPE_METHOD(t, "getPrime", GetPrime);
3631 NODE_SET_PROTOTYPE_METHOD(t, "getGenerator", GetGenerator);
3632 NODE_SET_PROTOTYPE_METHOD(t, "getPublicKey", GetPublicKey);
3633 NODE_SET_PROTOTYPE_METHOD(t, "getPrivateKey", GetPrivateKey);
3634 NODE_SET_PROTOTYPE_METHOD(t, "setPublicKey", SetPublicKey);
3635 NODE_SET_PROTOTYPE_METHOD(t, "setPrivateKey", SetPrivateKey);
3637 target->Set(String::NewSymbol("DiffieHellman"), t->GetFunction());
3639 Local<FunctionTemplate> t2 = FunctionTemplate::New(DiffieHellmanGroup);
3640 t2->InstanceTemplate()->SetInternalFieldCount(1);
3642 NODE_SET_PROTOTYPE_METHOD(t2, "generateKeys", GenerateKeys);
3643 NODE_SET_PROTOTYPE_METHOD(t2, "computeSecret", ComputeSecret);
3644 NODE_SET_PROTOTYPE_METHOD(t2, "getPrime", GetPrime);
3645 NODE_SET_PROTOTYPE_METHOD(t2, "getGenerator", GetGenerator);
3646 NODE_SET_PROTOTYPE_METHOD(t2, "getPublicKey", GetPublicKey);
3647 NODE_SET_PROTOTYPE_METHOD(t2, "getPrivateKey", GetPrivateKey);
3649 target->Set(String::NewSymbol("DiffieHellmanGroup"), t2->GetFunction());
3652 bool Init(int primeLength) {
3654 DH_generate_parameters_ex(dh, primeLength, DH_GENERATOR_2, 0);
3655 bool result = VerifyContext();
3656 if (!result) return false;
3657 initialised_ = true;
3661 bool Init(unsigned char* p, int p_len) {
3663 dh->p = BN_bin2bn(p, p_len, 0);
3665 if (!BN_set_word(dh->g, 2)) return false;
3666 bool result = VerifyContext();
3667 if (!result) return false;
3668 initialised_ = true;
3672 bool Init(unsigned char* p, int p_len, unsigned char* g, int g_len) {
3674 dh->p = BN_bin2bn(p, p_len, 0);
3675 dh->g = BN_bin2bn(g, g_len, 0);
3676 initialised_ = true;
3681 static Handle<Value> DiffieHellmanGroup(const Arguments& args) {
3684 DiffieHellman* diffieHellman = new DiffieHellman();
3686 if (args.Length() != 1 || !args[0]->IsString()) {
3687 return ThrowException(Exception::Error(
3688 String::New("No group name given")));
3691 String::Utf8Value group_name(args[0]);
3693 modp_group* it = modp_groups;
3695 while(it->name != NULL) {
3696 if (!strcasecmp(*group_name, it->name))
3701 if (it->name != NULL) {
3702 diffieHellman->Init(it->prime, it->prime_size,
3703 it->gen, it->gen_size);
3705 return ThrowException(Exception::Error(
3706 String::New("Unknown group")));
3709 diffieHellman->Wrap(args.This());
3714 static Handle<Value> New(const Arguments& args) {
3717 DiffieHellman* diffieHellman = new DiffieHellman();
3718 bool initialized = false;
3720 if (args.Length() > 0) {
3721 if (args[0]->IsInt32()) {
3722 initialized = diffieHellman->Init(args[0]->Int32Value());
3724 if (args[0]->IsString()) {
3727 if (args.Length() > 1 && args[1]->IsString()) {
3728 len = DecodeWithEncoding(args[0], args[1], &buf);
3730 len = DecodeBinary(args[0], &buf);
3735 return ThrowException(Exception::Error(
3736 String::New("Invalid argument")));
3738 initialized = diffieHellman->Init(
3739 reinterpret_cast<unsigned char*>(buf), len);
3742 } else if (Buffer::HasInstance(args[0])) {
3743 Local<Object> buffer = args[0]->ToObject();
3744 initialized = diffieHellman->Init(
3745 reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
3746 Buffer::Length(buffer));
3752 return ThrowException(Exception::Error(
3753 String::New("Initialization failed")));
3756 diffieHellman->Wrap(args.This());
3761 static Handle<Value> GenerateKeys(const Arguments& args) {
3762 DiffieHellman* diffieHellman =
3763 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3767 if (!diffieHellman->initialised_) {
3768 return ThrowException(Exception::Error(
3769 String::New("Not initialized")));
3772 if (!DH_generate_key(diffieHellman->dh)) {
3773 return ThrowException(Exception::Error(
3774 String::New("Key generation failed")));
3777 Local<Value> outString;
3779 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3780 char* data = new char[dataSize];
3781 BN_bn2bin(diffieHellman->dh->pub_key,
3782 reinterpret_cast<unsigned char*>(data));
3784 if (args.Length() > 0 && args[0]->IsString()) {
3785 outString = EncodeWithEncoding(args[0], data, dataSize);
3787 outString = Encode(data, dataSize, BINARY);
3791 return scope.Close(outString);
3794 static Handle<Value> GetPrime(const Arguments& args) {
3795 DiffieHellman* diffieHellman =
3796 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3800 if (!diffieHellman->initialised_) {
3801 return ThrowException(Exception::Error(String::New("Not initialized")));
3804 int dataSize = BN_num_bytes(diffieHellman->dh->p);
3805 char* data = new char[dataSize];
3806 BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
3808 Local<Value> outString;
3810 if (args.Length() > 0 && args[0]->IsString()) {
3811 outString = EncodeWithEncoding(args[0], data, dataSize);
3813 outString = Encode(data, dataSize, BINARY);
3818 return scope.Close(outString);
3821 static Handle<Value> GetGenerator(const Arguments& args) {
3822 DiffieHellman* diffieHellman =
3823 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3827 if (!diffieHellman->initialised_) {
3828 return ThrowException(Exception::Error(String::New("Not initialized")));
3831 int dataSize = BN_num_bytes(diffieHellman->dh->g);
3832 char* data = new char[dataSize];
3833 BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
3835 Local<Value> outString;
3837 if (args.Length() > 0 && args[0]->IsString()) {
3838 outString = EncodeWithEncoding(args[0], data, dataSize);
3840 outString = Encode(data, dataSize, BINARY);
3845 return scope.Close(outString);
3848 static Handle<Value> GetPublicKey(const Arguments& args) {
3849 DiffieHellman* diffieHellman =
3850 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3854 if (!diffieHellman->initialised_) {
3855 return ThrowException(Exception::Error(String::New("Not initialized")));
3858 if (diffieHellman->dh->pub_key == NULL) {
3859 return ThrowException(Exception::Error(
3860 String::New("No public key - did you forget to generate one?")));
3863 int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
3864 char* data = new char[dataSize];
3865 BN_bn2bin(diffieHellman->dh->pub_key,
3866 reinterpret_cast<unsigned char*>(data));
3868 Local<Value> outString;
3870 if (args.Length() > 0 && args[0]->IsString()) {
3871 outString = EncodeWithEncoding(args[0], data, dataSize);
3873 outString = Encode(data, dataSize, BINARY);
3878 return scope.Close(outString);
3881 static Handle<Value> GetPrivateKey(const Arguments& args) {
3882 DiffieHellman* diffieHellman =
3883 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3887 if (!diffieHellman->initialised_) {
3888 return ThrowException(Exception::Error(String::New("Not initialized")));
3891 if (diffieHellman->dh->priv_key == NULL) {
3892 return ThrowException(Exception::Error(
3893 String::New("No private key - did you forget to generate one?")));
3896 int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
3897 char* data = new char[dataSize];
3898 BN_bn2bin(diffieHellman->dh->priv_key,
3899 reinterpret_cast<unsigned char*>(data));
3901 Local<Value> outString;
3903 if (args.Length() > 0 && args[0]->IsString()) {
3904 outString = EncodeWithEncoding(args[0], data, dataSize);
3906 outString = Encode(data, dataSize, BINARY);
3911 return scope.Close(outString);
3914 static Handle<Value> ComputeSecret(const Arguments& args) {
3917 DiffieHellman* diffieHellman =
3918 ObjectWrap::Unwrap<DiffieHellman>(args.This());
3920 if (!diffieHellman->initialised_) {
3921 return ThrowException(Exception::Error(String::New("Not initialized")));
3926 if (args.Length() == 0) {
3927 return ThrowException(Exception::Error(
3928 String::New("First argument must be other party's public key")));
3930 if (args[0]->IsString()) {
3933 if (args.Length() > 1) {
3934 len = DecodeWithEncoding(args[0], args[1], &buf);
3936 len = DecodeBinary(args[0], &buf);
3940 return ThrowException(Exception::Error(
3941 String::New("Invalid argument")));
3943 key = BN_bin2bn(reinterpret_cast<unsigned char*>(buf), len, 0);
3945 } else if (Buffer::HasInstance(args[0])) {
3946 Local<Object> buffer = args[0]->ToObject();
3948 reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
3949 Buffer::Length(buffer), 0);
3951 return ThrowException(Exception::Error(
3952 String::New("First argument must be other party's public key")));
3956 int dataSize = DH_size(diffieHellman->dh);
3957 char* data = new char[dataSize];
3959 int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
3960 key, diffieHellman->dh);
3963 Local<Value> outString;
3965 // DH_size returns number of bytes in a prime number
3966 // DH_compute_key returns number of bytes in a remainder of exponent, which
3967 // may have less bytes than a prime number. Therefore add 0-padding to the
3968 // allocated buffer.
3969 if (size != dataSize) {
3970 assert(dataSize > size);
3971 memset(data + size, 0, dataSize - size);
3976 if (!DH_check_pub_key(diffieHellman->dh, key, &checkResult)) {
3977 return ThrowException(Exception::Error(String::New("Invalid key")));
3978 } else if (checkResult) {
3979 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
3980 return ThrowException(Exception::Error(
3981 String::New("Supplied key is too small")));
3982 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
3983 return ThrowException(Exception::Error(
3984 String::New("Supplied key is too large")));
3986 return ThrowException(Exception::Error(String::New("Invalid key")));
3989 return ThrowException(Exception::Error(String::New("Invalid key")));
3992 if (args.Length() > 2 && args[2]->IsString()) {
3993 outString = EncodeWithEncoding(args[2], data, dataSize);
3994 } else if (args.Length() > 1 && args[1]->IsString()) {
3995 outString = EncodeWithEncoding(args[1], data, dataSize);
3997 outString = Encode(data, dataSize, BINARY);
4002 return scope.Close(outString);
4005 static Handle<Value> SetPublicKey(const Arguments& args) {
4008 DiffieHellman* diffieHellman =
4009 ObjectWrap::Unwrap<DiffieHellman>(args.This());
4011 if (!diffieHellman->initialised_) {
4012 return ThrowException(Exception::Error(String::New("Not initialized")));
4015 if (args.Length() == 0) {
4016 return ThrowException(Exception::Error(
4017 String::New("First argument must be public key")));
4019 if (args[0]->IsString()) {
4022 if (args.Length() > 1) {
4023 len = DecodeWithEncoding(args[0], args[1], &buf);
4025 len = DecodeBinary(args[0], &buf);
4029 return ThrowException(Exception::Error(
4030 String::New("Invalid argument")));
4032 diffieHellman->dh->pub_key =
4033 BN_bin2bn(reinterpret_cast<unsigned char*>(buf), len, 0);
4035 } else if (Buffer::HasInstance(args[0])) {
4036 Local<Object> buffer = args[0]->ToObject();
4037 diffieHellman->dh->pub_key =
4039 reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
4040 Buffer::Length(buffer), 0);
4042 return ThrowException(Exception::Error(
4043 String::New("First argument must be public key")));
4050 static Handle<Value> SetPrivateKey(const Arguments& args) {
4053 DiffieHellman* diffieHellman =
4054 ObjectWrap::Unwrap<DiffieHellman>(args.This());
4056 if (!diffieHellman->initialised_) {
4057 return ThrowException(Exception::Error(
4058 String::New("Not initialized")));
4061 if (args.Length() == 0) {
4062 return ThrowException(Exception::Error(
4063 String::New("First argument must be private key")));
4065 if (args[0]->IsString()) {
4068 if (args.Length() > 1) {
4069 len = DecodeWithEncoding(args[0], args[1], &buf);
4071 len = DecodeBinary(args[0], &buf);
4075 return ThrowException(Exception::Error(
4076 String::New("Invalid argument")));
4078 diffieHellman->dh->priv_key =
4079 BN_bin2bn(reinterpret_cast<unsigned char*>(buf), len, 0);
4081 } else if (Buffer::HasInstance(args[0])) {
4082 Local<Object> buffer = args[0]->ToObject();
4083 diffieHellman->dh->priv_key =
4085 reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
4086 Buffer::Length(buffer), 0);
4088 return ThrowException(Exception::Error(
4089 String::New("First argument must be private key")));
4096 DiffieHellman() : ObjectWrap() {
4097 initialised_ = false;
4108 bool VerifyContext() {
4110 if (!DH_check(dh, &codes)) return false;
4111 if (codes & DH_CHECK_P_NOT_SAFE_PRIME) return false;
4112 if (codes & DH_CHECK_P_NOT_PRIME) return false;
4113 if (codes & DH_UNABLE_TO_CHECK_GENERATOR) return false;
4114 if (codes & DH_NOT_SUITABLE_GENERATOR) return false;
4118 static int DecodeBinary(Handle<Value> str, char** buf) {
4119 int len = DecodeBytes(str);
4120 *buf = new char[len];
4121 int written = DecodeWrite(*buf, len, str, BINARY);
4122 if (written != len) {
4128 static int DecodeWithEncoding(Handle<Value> str, Handle<Value> encoding_v,
4130 int len = DecodeBinary(str, buf);
4134 enum encoding enc = ParseEncoding(encoding_v, (enum encoding) -1);
4139 HexDecode((unsigned char*)*buf, len, &retbuf, &retlen);
4141 } else if (enc == BASE64) {
4142 unbase64((unsigned char*)*buf, len, &retbuf, &retlen);
4144 } else if (enc == BINARY) {
4145 // Binary - do nothing
4147 fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding "
4148 "can be binary, hex or base64\n");
4160 static Local<Value> EncodeWithEncoding(Handle<Value> encoding_v, char* buf,
4164 Local<Value> outString;
4165 enum encoding enc = ParseEncoding(encoding_v, (enum encoding) -1);
4171 HexEncode(reinterpret_cast<unsigned char*>(buf), len, &retbuf, &retlen);
4172 outString = Encode(retbuf, retlen, BINARY);
4174 } else if (enc == BASE64) {
4175 base64(reinterpret_cast<unsigned char*>(buf), len, &retbuf, &retlen);
4176 outString = Encode(retbuf, retlen, BINARY);
4178 } else if (enc == BINARY) {
4179 outString = Encode(buf, len, BINARY);
4181 fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding "
4182 "can be binary, hex or base64\n");
4185 return scope.Close(outString);
4201 Persistent<Object> obj;
4205 EIO_PBKDF2(uv_work_t* req) {
4206 pbkdf2_req* request = (pbkdf2_req*)req->data;
4207 request->err = PKCS5_PBKDF2_HMAC_SHA1(
4210 (unsigned char*)request->salt,
4214 (unsigned char*)request->key);
4215 memset(request->pass, 0, request->passlen);
4216 memset(request->salt, 0, request->saltlen);
4220 EIO_PBKDF2After(uv_work_t* req) {
4223 pbkdf2_req* request = (pbkdf2_req*)req->data;
4226 Local<Value> argv[2];
4228 argv[0] = Local<Value>::New(Undefined());
4229 argv[1] = Encode(request->key, request->keylen, BINARY);
4230 memset(request->key, 0, request->keylen);
4232 argv[0] = Exception::Error(String::New("PBKDF2 error"));
4233 argv[1] = Local<Value>::New(Undefined());
4236 MakeCallback(request->obj, "ondone", ARRAY_SIZE(argv), argv);
4238 delete[] request->pass;
4239 delete[] request->salt;
4240 delete[] request->key;
4241 request->obj.Dispose();
4242 request->obj.Clear();
4248 PBKDF2(const Arguments& args) {
4251 const char* type_error = NULL;
4255 ssize_t passlen = -1;
4256 ssize_t saltlen = -1;
4257 ssize_t keylen = -1;
4258 ssize_t pass_written = -1;
4259 ssize_t salt_written = -1;
4261 Local<Function> callback;
4262 pbkdf2_req* request = NULL;
4263 uv_work_t* req = NULL;
4264 Persistent<Object> obj;
4266 if (args.Length() != 5) {
4267 type_error = "Bad parameter";
4271 ASSERT_IS_STRING_OR_BUFFER(args[0]);
4272 passlen = DecodeBytes(args[0], BINARY);
4274 type_error = "Bad password";
4278 pass = new char[passlen];
4279 pass_written = DecodeWrite(pass, passlen, args[0], BINARY);
4280 assert(pass_written == passlen);
4282 ASSERT_IS_STRING_OR_BUFFER(args[1]);
4283 saltlen = DecodeBytes(args[1], BINARY);
4285 type_error = "Bad salt";
4289 salt = new char[saltlen];
4290 salt_written = DecodeWrite(salt, saltlen, args[1], BINARY);
4291 assert(salt_written == saltlen);
4293 if (!args[2]->IsNumber()) {
4294 type_error = "Iterations not a number";
4298 iter = args[2]->Int32Value();
4300 type_error = "Bad iterations";
4304 if (!args[3]->IsNumber()) {
4305 type_error = "Key length not a number";
4309 keylen = args[3]->Int32Value();
4311 type_error = "Bad key length";
4315 key = new char[keylen];
4317 if (!args[4]->IsFunction()) {
4318 type_error = "Callback not a function";
4322 obj = Persistent<Object>::New(Object::New());
4323 obj->Set(String::New("ondone"), args[4]);
4325 request = new pbkdf2_req;
4327 request->pass = pass;
4328 request->passlen = passlen;
4329 request->salt = salt;
4330 request->saltlen = saltlen;
4331 request->iter = iter;
4333 request->keylen = keylen;
4336 req = new uv_work_t();
4337 req->data = request;
4338 uv_queue_work(uv_default_loop(), req, EIO_PBKDF2, EIO_PBKDF2After);
4345 return ThrowException(Exception::TypeError(String::New(type_error)));
4349 typedef int (*RandomBytesGenerator)(unsigned char* buf, int size);
4351 struct RandomBytesRequest {
4352 ~RandomBytesRequest();
4353 Persistent<Object> obj_;
4354 unsigned long error_; // openssl error code or zero
4355 uv_work_t work_req_;
4361 RandomBytesRequest::~RandomBytesRequest() {
4362 if (obj_.IsEmpty()) return;
4368 void RandomBytesFree(char* data, void* hint) {
4373 template <RandomBytesGenerator generator>
4374 void RandomBytesWork(uv_work_t* work_req) {
4375 RandomBytesRequest* req =
4376 container_of(work_req, RandomBytesRequest, work_req_);
4378 int r = generator(reinterpret_cast<unsigned char*>(req->data_), req->size_);
4382 // RAND_bytes() returns 0 on error, RAND_pseudo_bytes() returns 0
4383 // when the result is not cryptographically strong - the latter
4384 // sucks but is not an error
4385 if (generator == RAND_bytes)
4386 req->error_ = ERR_get_error();
4390 // not supported - can this actually happen?
4391 req->error_ = (unsigned long) -1;
4397 // don't call this function without a valid HandleScope
4398 void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
4400 char errmsg[256] = "Operation not supported";
4402 if (req->error_ != (unsigned long) -1)
4403 ERR_error_string_n(req->error_, errmsg, sizeof errmsg);
4405 argv[0] = Exception::Error(String::New(errmsg));
4406 argv[1] = Local<Value>::New(Null());
4409 // avoids the malloc + memcpy
4410 Buffer* buffer = Buffer::New(req->data_, req->size_, RandomBytesFree, NULL);
4411 argv[0] = Local<Value>::New(Null());
4412 argv[1] = Local<Object>::New(buffer->handle_);
4417 template <RandomBytesGenerator generator>
4418 void RandomBytesAfter(uv_work_t* work_req) {
4419 RandomBytesRequest* req =
4420 container_of(work_req, RandomBytesRequest, work_req_);
4423 Local<Value> argv[2];
4424 RandomBytesCheck(req, argv);
4425 MakeCallback(req->obj_, "ondone", ARRAY_SIZE(argv), argv);
4431 template <RandomBytesGenerator generator>
4432 Handle<Value> RandomBytes(const Arguments& args) {
4435 // maybe allow a buffer to write to? cuts down on object creation
4436 // when generating random data in a loop
4437 if (!args[0]->IsUint32()) {
4438 Local<String> s = String::New("Argument #1 must be number > 0");
4439 return ThrowException(Exception::TypeError(s));
4442 const size_t size = args[0]->Uint32Value();
4444 RandomBytesRequest* req = new RandomBytesRequest();
4446 req->data_ = new char[size];
4449 if (args[1]->IsFunction()) {
4450 req->obj_ = Persistent<Object>::New(Object::New());
4451 req->obj_->Set(String::New("ondone"), args[1]);
4453 uv_queue_work(uv_default_loop(),
4455 RandomBytesWork<generator>,
4456 RandomBytesAfter<generator>);
4461 Local<Value> argv[2];
4462 RandomBytesWork<generator>(&req->work_req_);
4463 RandomBytesCheck(req, argv);
4466 if (!argv[0]->IsNull())
4467 return ThrowException(argv[0]);
4474 void InitCrypto(Handle<Object> target) {
4478 OpenSSL_add_all_algorithms();
4479 OpenSSL_add_all_digests();
4480 SSL_load_error_strings();
4481 ERR_load_crypto_strings();
4484 CRYPTO_set_locking_callback(crypto_lock_cb);
4485 CRYPTO_set_id_callback(crypto_id_cb);
4487 // Turn off compression. Saves memory - do it in userland.
4488 #if !defined(OPENSSL_NO_COMP)
4489 STACK_OF(SSL_COMP)* comp_methods =
4490 #if OPENSSL_VERSION_NUMBER < 0x00908000L
4491 SSL_COMP_get_compression_method()
4493 SSL_COMP_get_compression_methods()
4496 sk_SSL_COMP_zero(comp_methods);
4497 assert(sk_SSL_COMP_num(comp_methods) == 0);
4500 SecureContext::Initialize(target);
4501 Connection::Initialize(target);
4502 Cipher::Initialize(target);
4503 Decipher::Initialize(target);
4504 DiffieHellman::Initialize(target);
4505 Hmac::Initialize(target);
4506 Hash::Initialize(target);
4507 Sign::Initialize(target);
4508 Verify::Initialize(target);
4510 NODE_SET_METHOD(target, "PBKDF2", PBKDF2);
4511 NODE_SET_METHOD(target, "randomBytes", RandomBytes<RAND_bytes>);
4512 NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<RAND_pseudo_bytes>);
4514 subject_symbol = NODE_PSYMBOL("subject");
4515 issuer_symbol = NODE_PSYMBOL("issuer");
4516 valid_from_symbol = NODE_PSYMBOL("valid_from");
4517 valid_to_symbol = NODE_PSYMBOL("valid_to");
4518 subjectaltname_symbol = NODE_PSYMBOL("subjectaltname");
4519 modulus_symbol = NODE_PSYMBOL("modulus");
4520 exponent_symbol = NODE_PSYMBOL("exponent");
4521 fingerprint_symbol = NODE_PSYMBOL("fingerprint");
4522 name_symbol = NODE_PSYMBOL("name");
4523 version_symbol = NODE_PSYMBOL("version");
4524 ext_key_usage_symbol = NODE_PSYMBOL("ext_key_usage");
4527 } // namespace crypto
4530 NODE_MODULE(node_crypto, node::crypto::InitCrypto)