|
|
@ -355,7 +355,7 @@ static BIO* LoadBIO (Handle<Value> v) { |
|
|
|
// Takes a string or buffer and loads it into an X509
|
|
|
|
// Caller responsible for X509_free-ing the returned object.
|
|
|
|
static X509* LoadX509(Handle<Value> v) { |
|
|
|
HandleScope scope(node_isolate); // necessary?
|
|
|
|
HandleScope scope(node_isolate); |
|
|
|
|
|
|
|
BIO *bio = LoadBIO(v); |
|
|
|
if (!bio) return NULL; |
|
|
@ -648,8 +648,7 @@ void SecureContext::SetSessionIdContext( |
|
|
|
bio = BIO_new(BIO_s_mem()); |
|
|
|
if (bio == NULL) { |
|
|
|
message = String::New("SSL_CTX_set_session_id_context error"); |
|
|
|
} |
|
|
|
else { |
|
|
|
} else { |
|
|
|
ERR_print_errors(bio); |
|
|
|
BIO_get_mem_ptr(bio, &mem); |
|
|
|
message = String::New(mem->data, mem->length); |
|
|
@ -722,8 +721,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) { |
|
|
|
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)) |
|
|
|
{ |
|
|
|
SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) { |
|
|
|
// set extra certs
|
|
|
|
while (X509* x509 = sk_X509_pop(extraCerts)) { |
|
|
|
if (!sc->ca_store_) { |
|
|
@ -819,10 +817,13 @@ size_t ClientHelloParser::Write(const uint8_t* data, size_t len) { |
|
|
|
switch (state_) { |
|
|
|
case kWaiting: |
|
|
|
// >= 5 bytes for header parsing
|
|
|
|
if (offset_ < 5) break; |
|
|
|
if (offset_ < 5) |
|
|
|
break; |
|
|
|
|
|
|
|
if (data_[0] == kChangeCipherSpec || data_[0] == kAlert || |
|
|
|
data_[0] == kHandshake || data_[0] == kApplicationData) { |
|
|
|
if (data_[0] == kChangeCipherSpec || |
|
|
|
data_[0] == kAlert || |
|
|
|
data_[0] == kHandshake || |
|
|
|
data_[0] == kApplicationData) { |
|
|
|
frame_len_ = (data_[3] << 8) + data_[4]; |
|
|
|
state_ = kTLSHeader; |
|
|
|
body_offset_ = 5; |
|
|
@ -847,11 +848,11 @@ size_t ClientHelloParser::Write(const uint8_t* data, size_t len) { |
|
|
|
case kTLSHeader: |
|
|
|
case kSSLHeader: |
|
|
|
// >= 5 + frame size bytes for frame parsing
|
|
|
|
if (offset_ < body_offset_ + frame_len_) break; |
|
|
|
if (offset_ < body_offset_ + frame_len_) |
|
|
|
break; |
|
|
|
|
|
|
|
// Skip unsupported frames and gather some data from frame
|
|
|
|
|
|
|
|
// TODO: Check protocol version
|
|
|
|
if (data_[body_offset_] == kClientHello) { |
|
|
|
is_clienthello = true; |
|
|
|
uint8_t* body; |
|
|
@ -892,8 +893,6 @@ size_t ClientHelloParser::Write(const uint8_t* data, size_t len) { |
|
|
|
Finish(); |
|
|
|
return copied; |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: Parse other things?
|
|
|
|
} |
|
|
|
|
|
|
|
// Not client hello - let OpenSSL handle it
|
|
|
@ -904,12 +903,10 @@ size_t ClientHelloParser::Write(const uint8_t* data, size_t len) { |
|
|
|
|
|
|
|
// Parse frame, call javascript handler and
|
|
|
|
// move parser into the paused state
|
|
|
|
if (onclienthello_sym.IsEmpty()) { |
|
|
|
if (onclienthello_sym.IsEmpty()) |
|
|
|
onclienthello_sym = String::New("onclienthello"); |
|
|
|
} |
|
|
|
if (sessionid_sym.IsEmpty()) { |
|
|
|
if (sessionid_sym.IsEmpty()) |
|
|
|
sessionid_sym = String::New("sessionId"); |
|
|
|
} |
|
|
|
|
|
|
|
state_ = kPaused; |
|
|
|
hello = Object::New(); |
|
|
@ -957,7 +954,10 @@ int Connection::HandleBIOError(BIO *bio, const char* func, int rv) { |
|
|
|
(void) retry; // unused if !defined(SSL_PRINT_DEBUG)
|
|
|
|
|
|
|
|
if (BIO_should_write(bio)) { |
|
|
|
DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n", ssl_, func, retry); |
|
|
|
DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n", |
|
|
|
ssl_, |
|
|
|
func, |
|
|
|
retry); |
|
|
|
return 0; |
|
|
|
|
|
|
|
} else if (BIO_should_read(bio)) { |
|
|
@ -972,7 +972,11 @@ int Connection::HandleBIOError(BIO *bio, const char* func, int rv) { |
|
|
|
Local<Value> e = Exception::Error(String::New(ssl_error_buf)); |
|
|
|
handle(node_isolate)->Set(String::New("error"), e); |
|
|
|
|
|
|
|
DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n", ssl_, func, rv, ssl_error_buf); |
|
|
|
DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n", |
|
|
|
ssl_, |
|
|
|
func, |
|
|
|
rv, |
|
|
|
ssl_error_buf); |
|
|
|
|
|
|
|
return rv; |
|
|
|
} |
|
|
@ -1079,22 +1083,32 @@ void Connection::Initialize(Handle<Object> target) { |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "encOut", Connection::EncOut); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "clearPending", Connection::ClearPending); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "encPending", Connection::EncPending); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "getPeerCertificate", Connection::GetPeerCertificate); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, |
|
|
|
"getPeerCertificate", |
|
|
|
Connection::GetPeerCertificate); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "getSession", Connection::GetSession); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "setSession", Connection::SetSession); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "loadSession", Connection::LoadSession); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "isSessionReused", Connection::IsSessionReused); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "isInitFinished", Connection::IsInitFinished); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "verifyError", Connection::VerifyError); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "getCurrentCipher", Connection::GetCurrentCipher); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, |
|
|
|
"getCurrentCipher", |
|
|
|
Connection::GetCurrentCipher); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "start", Connection::Start); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "shutdown", Connection::Shutdown); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "receivedShutdown", Connection::ReceivedShutdown); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, |
|
|
|
"receivedShutdown", |
|
|
|
Connection::ReceivedShutdown); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "close", Connection::Close); |
|
|
|
|
|
|
|
#ifdef OPENSSL_NPN_NEGOTIATED |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "getNegotiatedProtocol", Connection::GetNegotiatedProto); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "setNPNProtocols", Connection::SetNPNProtocols); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, |
|
|
|
"getNegotiatedProtocol", |
|
|
|
Connection::GetNegotiatedProto); |
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, |
|
|
|
"setNPNProtocols", |
|
|
|
Connection::SetNPNProtocols); |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
@ -1158,7 +1172,6 @@ int Connection::AdvertiseNextProtoCallback_(SSL *s, |
|
|
|
const unsigned char** data, |
|
|
|
unsigned int *len, |
|
|
|
void *arg) { |
|
|
|
|
|
|
|
Connection *p = static_cast<Connection*>(SSL_get_app_data(s)); |
|
|
|
|
|
|
|
if (p->npnProtos_.IsEmpty()) { |
|
|
@ -1599,8 +1612,8 @@ void Connection::GetPeerCertificate(const FunctionCallbackInfo<Value>& args) { |
|
|
|
|
|
|
|
EVP_PKEY *pkey = NULL; |
|
|
|
RSA *rsa = NULL; |
|
|
|
if( NULL != (pkey = X509_get_pubkey(peer_cert)) |
|
|
|
&& NULL != (rsa = EVP_PKEY_get1_RSA(pkey)) ) { |
|
|
|
if (NULL != (pkey = X509_get_pubkey(peer_cert)) && |
|
|
|
NULL != (rsa = EVP_PKEY_get1_RSA(pkey))) { |
|
|
|
BN_print(bio, rsa->n); |
|
|
|
BIO_get_mem_ptr(bio, &mem); |
|
|
|
info->Set(modulus_symbol, String::New(mem->data, mem->length) ); |
|
|
@ -1645,8 +1658,7 @@ void Connection::GetPeerCertificate(const FunctionCallbackInfo<Value>& args) { |
|
|
|
|
|
|
|
if (md_size > 0) { |
|
|
|
fingerprint[(3*(md_size-1))+2] = '\0'; |
|
|
|
} |
|
|
|
else { |
|
|
|
} else { |
|
|
|
fingerprint[0] = '\0'; |
|
|
|
} |
|
|
|
|
|
|
@ -1840,7 +1852,6 @@ void Connection::VerifyError(const FunctionCallbackInfo<Value>& args) { |
|
|
|
} |
|
|
|
X509_free(peer_cert); |
|
|
|
|
|
|
|
|
|
|
|
long x509_verify_error = SSL_get_verify_result(ss->ssl_); |
|
|
|
|
|
|
|
Local<String> s; |
|
|
@ -3460,8 +3471,7 @@ void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) { |
|
|
|
|
|
|
|
argv[0] = Exception::Error(String::New(errmsg)); |
|
|
|
argv[1] = Null(node_isolate); |
|
|
|
} |
|
|
|
else { |
|
|
|
} else { |
|
|
|
argv[0] = Null(node_isolate); |
|
|
|
argv[1] = Buffer::Use(req->data_, req->size_); |
|
|
|
} |
|
|
@ -3511,8 +3521,7 @@ void RandomBytes(const FunctionCallbackInfo<Value>& args) { |
|
|
|
RandomBytesWork<pseudoRandom>, |
|
|
|
RandomBytesAfter); |
|
|
|
args.GetReturnValue().Set(obj); |
|
|
|
} |
|
|
|
else { |
|
|
|
} else { |
|
|
|
Local<Value> argv[2]; |
|
|
|
RandomBytesWork<pseudoRandom>(&req->work_req_); |
|
|
|
RandomBytesCheck(req, argv); |
|
|
@ -3596,13 +3605,11 @@ void InitCrypto(Handle<Object> target) { |
|
|
|
|
|
|
|
// Turn off compression. Saves memory - do it in userland.
|
|
|
|
#if !defined(OPENSSL_NO_COMP) |
|
|
|
STACK_OF(SSL_COMP)* comp_methods = |
|
|
|
#if OPENSSL_VERSION_NUMBER < 0x00908000L |
|
|
|
SSL_COMP_get_compression_method() |
|
|
|
STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_method(); |
|
|
|
#else |
|
|
|
SSL_COMP_get_compression_methods() |
|
|
|
STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods(); |
|
|
|
#endif |
|
|
|
; |
|
|
|
sk_SSL_COMP_zero(comp_methods); |
|
|
|
assert(sk_SSL_COMP_num(comp_methods) == 0); |
|
|
|
#endif |
|
|
|