15
15
16
16
namespace node {
17
17
18
- using v8::Array;
19
18
using v8::ArrayBufferView;
20
19
using v8::Context;
21
20
using v8::EscapableHandleScope;
@@ -82,6 +81,7 @@ Local<FunctionTemplate> X509Certificate::GetConstructorTemplate(
82
81
env->SetProtoMethod (tmpl, " checkPrivateKey" , CheckPrivateKey);
83
82
env->SetProtoMethod (tmpl, " verify" , Verify);
84
83
env->SetProtoMethod (tmpl, " toLegacy" , ToLegacy);
84
+ env->SetProtoMethod (tmpl, " getIssuerCert" , GetIssuerCert);
85
85
env->set_x509_constructor_template (tmpl);
86
86
}
87
87
return tmpl;
@@ -93,14 +93,16 @@ bool X509Certificate::HasInstance(Environment* env, Local<Object> object) {
93
93
94
94
MaybeLocal<Object> X509Certificate::New (
95
95
Environment* env,
96
- X509Pointer cert) {
96
+ X509Pointer cert,
97
+ STACK_OF (X509)* issuer_chain) {
97
98
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 );
99
100
}
100
101
101
102
MaybeLocal<Object> X509Certificate::New (
102
103
Environment* env,
103
- std::shared_ptr<ManagedX509> cert) {
104
+ std::shared_ptr<ManagedX509> cert,
105
+ STACK_OF (X509)* issuer_chain) {
104
106
EscapableHandleScope scope (env->isolate ());
105
107
Local<Function> ctor;
106
108
if (!GetConstructorTemplate (env)->GetFunction (env->context ()).ToLocal (&ctor))
@@ -110,7 +112,7 @@ MaybeLocal<Object> X509Certificate::New(
110
112
if (!ctor->NewInstance (env->context ()).ToLocal (&obj))
111
113
return MaybeLocal<Object>();
112
114
113
- new X509Certificate (env, obj, std::move (cert));
115
+ new X509Certificate (env, obj, std::move (cert), issuer_chain );
114
116
return scope.Escape (obj);
115
117
}
116
118
@@ -122,24 +124,20 @@ MaybeLocal<Object> X509Certificate::GetCert(
122
124
if (cert == nullptr )
123
125
return MaybeLocal<Object>();
124
126
125
- X509Pointer ptr (cert);
127
+ X509Pointer ptr (X509_dup ( cert) );
126
128
return New (env, std::move (ptr));
127
129
}
128
130
129
131
MaybeLocal<Object> X509Certificate::GetPeerCert (
130
132
Environment* env,
131
133
const SSLPointer& ssl,
132
134
GetPeerCertificateFlag flag) {
133
- EscapableHandleScope scope (env->isolate ());
134
135
ClearErrorOnReturn clear_error_on_return;
135
136
Local<Object> obj;
136
137
MaybeLocal<Object> maybe_cert;
137
138
138
139
bool is_server =
139
140
static_cast <int >(flag) & static_cast <int >(GetPeerCertificateFlag::SERVER);
140
- bool abbreviated =
141
- static_cast <int >(flag)
142
- & static_cast <int >(GetPeerCertificateFlag::ABBREVIATED);
143
141
144
142
X509Pointer cert (is_server ? SSL_get_peer_certificate (ssl.get ()) : nullptr );
145
143
STACK_OF (X509)* ssl_certs = SSL_get_peer_cert_chain (ssl.get ());
@@ -148,23 +146,14 @@ MaybeLocal<Object> X509Certificate::GetPeerCert(
148
146
149
147
std::vector<Local<Value>> certs;
150
148
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 );
165
152
}
166
153
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));
168
157
}
169
158
170
159
void X509Certificate::Parse (const FunctionCallbackInfo<Value>& args) {
@@ -475,13 +464,32 @@ void X509Certificate::ToLegacy(const FunctionCallbackInfo<Value>& args) {
475
464
args.GetReturnValue ().Set (ret);
476
465
}
477
466
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
+
478
474
X509Certificate::X509Certificate (
479
475
Environment* env,
480
476
Local<Object> object,
481
- std::shared_ptr<ManagedX509> cert)
477
+ std::shared_ptr<ManagedX509> cert,
478
+ STACK_OF (X509)* issuer_chain)
482
479
: BaseObject(env, object),
483
480
cert_(std::move(cert)) {
484
481
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
+ }
485
493
}
486
494
487
495
void X509Certificate::MemoryInfo (MemoryTracker* tracker) const {
0 commit comments