diff options
author | Fedor Indutny <fedor@indutny.com> | 2014-04-18 03:53:15 +0400 |
---|---|---|
committer | Fedor Indutny <fedor@indutny.com> | 2014-04-22 16:19:57 +0400 |
commit | 0f3b72460b9987192d498700bbb02143a632f721 (patch) | |
tree | a3bf8bc8b59c2a609e7d140c108d67257765c2ec /src/node_crypto.cc | |
parent | afaff70a9b782c728b06a018d8473567c073df60 (diff) | |
download | node-new-0f3b72460b9987192d498700bbb02143a632f721.tar.gz |
crypto: work around OpenSSL oddness
OpenSSL behaves oddly: on client `cert_chain` contains
the `peer_certificate`, but on server it doesn't.
Signed-off-by: Fedor Indutny <fedor@indutny.com>
Diffstat (limited to 'src/node_crypto.cc')
-rw-r--r-- | src/node_crypto.cc | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 76d5a5fb55..adb1e90690 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -1257,25 +1257,29 @@ void SSLWrap<Base>::GetPeerCertificate( Local<Object> result; Local<Object> info; - X509* cert; + // NOTE: This is because of the odd OpenSSL behavior. On client `cert_chain` + // contains the `peer_certificate`, but on server it doesn't + X509* cert = w->is_server() ? SSL_get_peer_certificate(w->ssl_) : NULL; STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(w->ssl_); STACK_OF(X509)* peer_certs = NULL; - if (ssl_certs == NULL) + if (cert == NULL && ssl_certs == NULL) goto done; - if (sk_X509_num(ssl_certs) == 0) { + if (cert == NULL && sk_X509_num(ssl_certs) == 0) goto done; - } // Short result requested if (args.Length() < 1 || !args[0]->IsTrue()) { - result = X509ToObject(env, sk_X509_value(ssl_certs, 0)); + result = X509ToObject(env, + cert == NULL ? sk_X509_value(ssl_certs, 0) : cert); goto done; } // Clone `ssl_certs`, because we are going to destruct it peer_certs = sk_X509_new(NULL); + if (cert != NULL) + sk_X509_push(peer_certs, cert); for (int i = 0; i < sk_X509_num(ssl_certs); i++) { cert = X509_dup(sk_X509_value(ssl_certs, i)); if (cert == NULL) |