summaryrefslogtreecommitdiff
path: root/src/node_crypto.cc
diff options
context:
space:
mode:
authorssuda <sambasivarao@gmail.com>2012-05-14 01:08:23 +0530
committerBen Noordhuis <info@bnoordhuis.nl>2012-05-14 17:12:59 +0200
commitfb7348ae060bf9dd4b0521ac2533fc1d66c44d8b (patch)
tree0fb6d3419831be14ba09275d3f940779add629eb /src/node_crypto.cc
parentbd907174e8082afd6dd8553940aac09cae3dcfb7 (diff)
downloadnode-fb7348ae060bf9dd4b0521ac2533fc1d66c44d8b.tar.gz
crypto: add PKCS12/PFX support
Fixes #2845.
Diffstat (limited to 'src/node_crypto.cc')
-rw-r--r--src/node_crypto.cc79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index bf95d7970..b2858f508 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -43,6 +43,7 @@
# include <pthread.h>
#endif
+
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
# define OPENSSL_CONST const
#else
@@ -169,6 +170,7 @@ void SecureContext::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
SecureContext::SetSessionIdContext);
NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
+ NODE_SET_PROTOTYPE_METHOD(t, "loadPKCS12", SecureContext::LoadPKCS12);
target->Set(String::NewSymbol("SecureContext"), t->GetFunction());
}
@@ -595,6 +597,83 @@ Handle<Value> SecureContext::Close(const Arguments& args) {
return False();
}
+//Takes .pfx or .p12 and password in string or buffer format
+Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
+ HandleScope scope;
+
+ BIO* in = NULL;
+ PKCS12* p12 = NULL;
+ EVP_PKEY* pkey = NULL;
+ X509* cert = NULL;
+ STACK_OF(X509)* extraCerts = NULL;
+ char* pass = NULL;
+ bool ret = false;
+
+ SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
+
+ if (args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Bad parameter")));
+ }
+
+ in = LoadBIO(args[0]);
+ if (in == NULL) {
+ return ThrowException(Exception::Error(
+ String::New("Unable to load BIO")));
+ }
+
+ if (args.Length() >= 2) {
+ ASSERT_IS_STRING_OR_BUFFER(args[1]);
+
+ int passlen = DecodeBytes(args[1], BINARY);
+ if (passlen < 0) {
+ BIO_free(in);
+ return ThrowException(Exception::TypeError(
+ String::New("Bad password")));
+ }
+ pass = new char[passlen + 1];
+ int pass_written = DecodeWrite(pass, passlen, args[1], BINARY);
+
+ assert(pass_written == passlen);
+ pass[passlen] = '\0';
+ }
+
+ if (d2i_PKCS12_bio(in, &p12) &&
+ PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
+ SSL_CTX_use_certificate(sc->ctx_, cert) &&
+ SSL_CTX_use_PrivateKey(sc->ctx_, pkey))
+ {
+ // set extra certs
+ while (X509* x509 = sk_X509_pop(extraCerts)) {
+ if (!sc->ca_store_) {
+ sc->ca_store_ = X509_STORE_new();
+ SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
+ }
+
+ X509_STORE_add_cert(sc->ca_store_, x509);
+ SSL_CTX_add_client_CA(sc->ctx_, x509);
+ }
+
+ EVP_PKEY_free(pkey);
+ X509_free(cert);
+ sk_X509_free(extraCerts);
+
+ ret = true;
+ }
+
+ PKCS12_free(p12);
+ BIO_free(in);
+ delete[] pass;
+
+ if (!ret) {
+ unsigned long err = ERR_get_error();
+ const char *str = ERR_reason_error_string(err);
+ return ThrowException(Exception::Error(String::New(str)));
+ }
+
+ return True();
+}
+
#ifdef SSL_PRINT_DEBUG
# define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)