Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Exposing pkey, cert from crypto context to js land

This will solve exposing pkey, cert from pkcs12/pfx to js
  • Loading branch information...
commit e550dd0ae27159469adf6fa3915bc53fc77438f0 1 parent 3053f4d
ssuda authored
View
2  lib/crypto.js
@@ -85,7 +85,7 @@ exports.createCredentials = function(options, context) {
}
}
- if (options.cert) c.context.setCert(options.cert);
+ if (options.cert) c.context.cert = options.cert;
if (options.ciphers) c.context.setCiphers(options.ciphers);
View
72 src/node_crypto.cc
@@ -126,13 +126,15 @@ void SecureContext::Initialize(Handle<Object> target) {
Local<FunctionTemplate> t = FunctionTemplate::New(SecureContext::New);
secure_context_constructor = Persistent<FunctionTemplate>::New(t);
+ Local<ObjectTemplate> o = t->InstanceTemplate();
- t->InstanceTemplate()->SetInternalFieldCount(1);
+ o->SetInternalFieldCount(1);
+ o->SetAccessor(String::New("cert"), SecureContext::GetCert, SecureContext::SetCert);
+ o->SetAccessor(String::New("pkey"), SecureContext::GetKey, NULL);
t->SetClassName(String::NewSymbol("SecureContext"));
NODE_SET_PROTOTYPE_METHOD(t, "init", SecureContext::Init);
NODE_SET_PROTOTYPE_METHOD(t, "setKey", SecureContext::SetKey);
- NODE_SET_PROTOTYPE_METHOD(t, "setCert", SecureContext::SetCert);
NODE_SET_PROTOTYPE_METHOD(t, "addCACert", SecureContext::AddCACert);
NODE_SET_PROTOTYPE_METHOD(t, "addCRL", SecureContext::AddCRL);
NODE_SET_PROTOTYPE_METHOD(t, "addRootCerts", SecureContext::AddRootCerts);
@@ -319,6 +321,14 @@ static X509* LoadX509 (Handle<Value> v) {
return x509;
}
+Handle<Value> SecureContext::GetKey(Local<String> property,
+ const AccessorInfo &info) {
+ SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(info.Holder());
+ if (sc->pkey_)
+ return sc->pkey_->handle_;
+ return Null();
+}
+
Handle<Value> SecureContext::SetKey(const Arguments& args) {
HandleScope scope;
@@ -336,6 +346,10 @@ Handle<Value> SecureContext::SetKey(const Arguments& args) {
BIO *bio = LoadBIO(args[0]);
if (!bio) return False();
+ BUF_MEM *bio_buf;
+ BIO_get_mem_ptr(bio, &bio_buf);
+ sc->pkey_ = Buffer::New(bio_buf->data, bio_buf->length);
+
String::Utf8Value passphrase(args[1]);
EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, NULL,
@@ -427,35 +441,45 @@ int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, BIO *in) {
}
-Handle<Value> SecureContext::SetCert(const Arguments& args) {
+Handle<Value> SecureContext::GetCert(Local<String> property,
+ const AccessorInfo &info) {
+ SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(info.Holder());
+ if (sc->cert_)
+ return sc->cert_->handle_;
+ return Null();
+}
+
+
+void SecureContext::SetCert(Local<String> property,
+ Local<Value> value,
+ const AccessorInfo& info) {
HandleScope scope;
- SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
+ SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(info.Holder());
- if (args.Length() != 1) {
- return ThrowException(Exception::TypeError(
- String::New("Bad parameter")));
- }
- BIO* bio = LoadBIO(args[0]);
- if (!bio) return False();
+ BIO* bio = LoadBIO(value);
+ if (!bio) return;
- int rv = SSL_CTX_use_certificate_chain(sc->ctx_, bio);
+ BUF_MEM *bio_buf;
+ BIO_get_mem_ptr(bio, &bio_buf);
+
+ sc->cert_ = Buffer::New(bio_buf->data, bio_buf->length);
+ int rv = SSL_CTX_use_certificate_chain(sc->ctx_, bio);
BIO_free(bio);
if (!rv) {
unsigned long err = ERR_get_error();
if (!err) {
- return ThrowException(Exception::Error(
+ ThrowException(Exception::Error(
String::New("SSL_CTX_use_certificate_chain")));
+ return;
}
char string[120];
ERR_error_string_n(err, string, sizeof string);
- return ThrowException(Exception::Error(String::New(string)));
+ ThrowException(Exception::Error(String::New(string)));
}
-
- return True();
}
@@ -688,6 +712,24 @@ Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
SSL_CTX_add_client_CA(sc->ctx_, x509);
}
+ BIO *bio_out = BIO_new(BIO_s_mem());
+ if (PEM_write_bio_X509(bio_out, cert)) {
+ BUF_MEM *bio_buf;
+ BIO_get_mem_ptr(bio_out, &bio_buf);
+ sc->cert_ = Buffer::New(bio_buf->data, bio_buf->length);
+ }
+ BIO_free(bio_out);
+
+ bio_out = BIO_new(BIO_s_mem());
+ if (PEM_ASN1_write_bio((i2d_of_void*)i2d_PrivateKey,
+ ((pkey->type == EVP_PKEY_DSA)? PEM_STRING_DSA:PEM_STRING_RSA), bio_out,
+ (void *)pkey, NULL, NULL, 0, NULL, NULL)) {
+ BUF_MEM *bio_buf;
+ BIO_get_mem_ptr(bio_out, &bio_buf);
+ sc->pkey_ = Buffer::New(bio_buf->data, bio_buf->length);
+ }
+ BIO_free(bio_out);
+
EVP_PKEY_free(pkey);
X509_free(cert);
sk_X509_free(extraCerts);
View
12 src/node_crypto.h
@@ -59,14 +59,22 @@ class SecureContext : ObjectWrap {
SSL_CTX *ctx_;
// TODO: ca_store_ should probably be removed, it's not used anywhere.
X509_STORE *ca_store_;
+
+ Buffer *cert_, *pkey_;
protected:
static const int kMaxSessionSize = 10 * 1024;
static v8::Handle<v8::Value> New(const v8::Arguments& args);
static v8::Handle<v8::Value> Init(const v8::Arguments& args);
+ static v8::Handle<v8::Value> GetKey(v8::Local<v8::String> property,
+ const v8::AccessorInfo &info);
static v8::Handle<v8::Value> SetKey(const v8::Arguments& args);
- static v8::Handle<v8::Value> SetCert(const v8::Arguments& args);
+ static v8::Handle<v8::Value> GetCert(v8::Local<v8::String> property,
+ const v8::AccessorInfo &info);
+ static void SetCert(v8::Local<v8::String> property,
+ v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info);
static v8::Handle<v8::Value> AddCACert(const v8::Arguments& args);
static v8::Handle<v8::Value> AddCRL(const v8::Arguments& args);
static v8::Handle<v8::Value> AddRootCerts(const v8::Arguments& args);
@@ -85,6 +93,8 @@ class SecureContext : ObjectWrap {
SecureContext() : ObjectWrap() {
ctx_ = NULL;
ca_store_ = NULL;
+ cert_ = NULL;
+ pkey_ = NULL;
}
void FreeCTXMem() {
View
9 test/simple/test-crypto.js
@@ -72,6 +72,15 @@ assert.throws(function() {
crypto.createCredentials({pfx:'sample', passphrase:'test'});
}, 'not enough data');
+//Cert, Key Read Tests
+assert.equal(certPem, credentials.context.cert.toString('ascii'));
+assert.equal(keyPem, credentials.context.pkey.toString('ascii'));
+assert.doesNotThrow(function() {
+ var c = crypto.createCredentials({pfx:certPfx, passphrase:'sample'});
+ assert.equal(certPem, c.context.cert.toString('ascii'));
+ assert.equal(keyPem, c.context.pkey.toString('ascii'));
+});
+
// Test HMAC
var h1 = crypto.createHmac('sha1', 'Node')
.update('some data')
Please sign in to comment.
Something went wrong with that request. Please try again.