1515
1616namespace node {
1717
18- using v8::Array;
1918using v8::ArrayBufferView;
2019using v8::Context;
2120using v8::EscapableHandleScope;
@@ -82,6 +81,7 @@ Local<FunctionTemplate> X509Certificate::GetConstructorTemplate(
8281 env->SetProtoMethod (tmpl, " checkPrivateKey" , CheckPrivateKey);
8382 env->SetProtoMethod (tmpl, " verify" , Verify);
8483 env->SetProtoMethod (tmpl, " toLegacy" , ToLegacy);
84+ env->SetProtoMethod (tmpl, " getIssuerCert" , GetIssuerCert);
8585 env->set_x509_constructor_template (tmpl);
8686 }
8787 return tmpl;
@@ -93,14 +93,16 @@ bool X509Certificate::HasInstance(Environment* env, Local<Object> object) {
9393
9494MaybeLocal<Object> X509Certificate::New (
9595 Environment* env,
96- X509Pointer cert) {
96+ X509Pointer cert,
97+ STACK_OF (X509)* issuer_chain) {
9798 std::shared_ptr<ManagedX509> mcert (new ManagedX509 (std::move (cert)));
98- return New (env, std::move (mcert));
99+ return New (env, std::move (mcert), issuer_chain );
99100}
100101
101102MaybeLocal<Object> X509Certificate::New (
102103 Environment* env,
103- std::shared_ptr<ManagedX509> cert) {
104+ std::shared_ptr<ManagedX509> cert,
105+ STACK_OF (X509)* issuer_chain) {
104106 EscapableHandleScope scope (env->isolate ());
105107 Local<Function> ctor;
106108 if (!GetConstructorTemplate (env)->GetFunction (env->context ()).ToLocal (&ctor))
@@ -110,7 +112,7 @@ MaybeLocal<Object> X509Certificate::New(
110112 if (!ctor->NewInstance (env->context ()).ToLocal (&obj))
111113 return MaybeLocal<Object>();
112114
113- new X509Certificate (env, obj, std::move (cert));
115+ new X509Certificate (env, obj, std::move (cert), issuer_chain );
114116 return scope.Escape (obj);
115117}
116118
@@ -122,24 +124,20 @@ MaybeLocal<Object> X509Certificate::GetCert(
122124 if (cert == nullptr )
123125 return MaybeLocal<Object>();
124126
125- X509Pointer ptr (cert);
127+ X509Pointer ptr (X509_dup ( cert) );
126128 return New (env, std::move (ptr));
127129}
128130
129131MaybeLocal<Object> X509Certificate::GetPeerCert (
130132 Environment* env,
131133 const SSLPointer& ssl,
132134 GetPeerCertificateFlag flag) {
133- EscapableHandleScope scope (env->isolate ());
134135 ClearErrorOnReturn clear_error_on_return;
135136 Local<Object> obj;
136137 MaybeLocal<Object> maybe_cert;
137138
138139 bool is_server =
139140 static_cast <int >(flag) & static_cast <int >(GetPeerCertificateFlag::SERVER);
140- bool abbreviated =
141- static_cast <int >(flag)
142- & static_cast <int >(GetPeerCertificateFlag::ABBREVIATED);
143141
144142 X509Pointer cert (is_server ? SSL_get_peer_certificate (ssl.get ()) : nullptr );
145143 STACK_OF (X509)* ssl_certs = SSL_get_peer_cert_chain (ssl.get ());
@@ -148,23 +146,14 @@ MaybeLocal<Object> X509Certificate::GetPeerCert(
148146
149147 std::vector<Local<Value>> certs;
150148
151- if (!cert) cert.reset (sk_X509_value (ssl_certs, 0 ));
152- if (!X509Certificate::New (env, std::move (cert)).ToLocal (&obj))
153- return MaybeLocal<Object>();
154-
155- certs.push_back (obj);
156-
157- int count = sk_X509_num (ssl_certs);
158- if (!abbreviated) {
159- for (int i = 0 ; i < count; i++) {
160- cert.reset (X509_dup (sk_X509_value (ssl_certs, i)));
161- if (!cert || !X509Certificate::New (env, std::move (cert)).ToLocal (&obj))
162- return MaybeLocal<Object>();
163- certs.push_back (obj);
164- }
149+ if (!cert) {
150+ cert.reset (sk_X509_value (ssl_certs, 0 ));
151+ sk_X509_delete (ssl_certs, 0 );
165152 }
166153
167- return scope.Escape (Array::New (env->isolate (), certs.data (), certs.size ()));
154+ return sk_X509_num (ssl_certs)
155+ ? New (env, std::move (cert), ssl_certs)
156+ : New (env, std::move (cert));
168157}
169158
170159void X509Certificate::Parse (const FunctionCallbackInfo<Value>& args) {
@@ -475,13 +464,32 @@ void X509Certificate::ToLegacy(const FunctionCallbackInfo<Value>& args) {
475464 args.GetReturnValue ().Set (ret);
476465}
477466
467+ void X509Certificate::GetIssuerCert (const FunctionCallbackInfo<Value>& args) {
468+ X509Certificate* cert;
469+ ASSIGN_OR_RETURN_UNWRAP (&cert, args.Holder ());
470+ if (cert->issuer_cert_ )
471+ args.GetReturnValue ().Set (cert->issuer_cert_ ->object ());
472+ }
473+
478474X509Certificate::X509Certificate (
479475 Environment* env,
480476 Local<Object> object,
481- std::shared_ptr<ManagedX509> cert)
477+ std::shared_ptr<ManagedX509> cert,
478+ STACK_OF (X509)* issuer_chain)
482479 : BaseObject(env, object),
483480 cert_(std::move(cert)) {
484481 MakeWeak ();
482+
483+ if (issuer_chain != nullptr && sk_X509_num (issuer_chain)) {
484+ X509Pointer cert (X509_dup (sk_X509_value (issuer_chain, 0 )));
485+ sk_X509_delete (issuer_chain, 0 );
486+ Local<Object> obj = sk_X509_num (issuer_chain)
487+ ? X509Certificate::New (env, std::move (cert), issuer_chain)
488+ .ToLocalChecked ()
489+ : X509Certificate::New (env, std::move (cert))
490+ .ToLocalChecked ();
491+ issuer_cert_.reset (Unwrap<X509Certificate>(obj));
492+ }
485493}
486494
487495void X509Certificate::MemoryInfo (MemoryTracker* tracker) const {
0 commit comments