GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_x509.cc Lines: 293 330 88.8 %
Date: 2022-02-13 04:14:14 Branches: 103 198 52.0 %

Line Branch Exec Source
1
#include "base_object-inl.h"
2
#include "crypto_x509.h"
3
#include "crypto_common.h"
4
#include "crypto_context.h"
5
#include "crypto_keys.h"
6
#include "crypto_bio.h"
7
#include "env-inl.h"
8
#include "memory_tracker-inl.h"
9
#include "node_errors.h"
10
#include "util-inl.h"
11
#include "v8.h"
12
13
#include <string>
14
#include <vector>
15
16
namespace node {
17
18
using v8::ArrayBufferView;
19
using v8::Context;
20
using v8::EscapableHandleScope;
21
using v8::Function;
22
using v8::FunctionCallbackInfo;
23
using v8::FunctionTemplate;
24
using v8::Local;
25
using v8::MaybeLocal;
26
using v8::Object;
27
using v8::Uint32;
28
using v8::Value;
29
30
namespace crypto {
31
32
53
ManagedX509::ManagedX509(X509Pointer&& cert) : cert_(std::move(cert)) {}
33
34
ManagedX509::ManagedX509(const ManagedX509& that) {
35
  *this = that;
36
}
37
38
ManagedX509& ManagedX509::operator=(const ManagedX509& that) {
39
  cert_.reset(that.get());
40
41
  if (cert_)
42
    X509_up_ref(cert_.get());
43
44
  return *this;
45
}
46
47
void ManagedX509::MemoryInfo(MemoryTracker* tracker) const {
48
  // This is an approximation based on the der encoding size.
49
  int size = i2d_X509(cert_.get(), nullptr);
50
  tracker->TrackFieldWithSize("cert", size);
51
}
52
53
56
Local<FunctionTemplate> X509Certificate::GetConstructorTemplate(
54
    Environment* env) {
55
56
  Local<FunctionTemplate> tmpl = env->x509_constructor_template();
56
56
  if (tmpl.IsEmpty()) {
57
3
    tmpl = FunctionTemplate::New(env->isolate());
58
6
    tmpl->InstanceTemplate()->SetInternalFieldCount(
59
        BaseObject::kInternalFieldCount);
60
3
    tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
61
3
    tmpl->SetClassName(
62
        FIXED_ONE_BYTE_STRING(env->isolate(), "X509Certificate"));
63
3
    env->SetProtoMethod(tmpl, "subject", Subject);
64
3
    env->SetProtoMethod(tmpl, "subjectAltName", SubjectAltName);
65
3
    env->SetProtoMethod(tmpl, "infoAccess", InfoAccess);
66
3
    env->SetProtoMethod(tmpl, "issuer", Issuer);
67
3
    env->SetProtoMethod(tmpl, "validTo", ValidTo);
68
3
    env->SetProtoMethod(tmpl, "validFrom", ValidFrom);
69
3
    env->SetProtoMethod(tmpl, "fingerprint", Fingerprint);
70
3
    env->SetProtoMethod(tmpl, "fingerprint256", Fingerprint256);
71
3
    env->SetProtoMethod(tmpl, "fingerprint512", Fingerprint512);
72
3
    env->SetProtoMethod(tmpl, "keyUsage", KeyUsage);
73
3
    env->SetProtoMethod(tmpl, "serialNumber", SerialNumber);
74
3
    env->SetProtoMethod(tmpl, "pem", Pem);
75
3
    env->SetProtoMethod(tmpl, "raw", Raw);
76
3
    env->SetProtoMethod(tmpl, "publicKey", PublicKey);
77
3
    env->SetProtoMethod(tmpl, "checkCA", CheckCA);
78
3
    env->SetProtoMethod(tmpl, "checkHost", CheckHost);
79
3
    env->SetProtoMethod(tmpl, "checkEmail", CheckEmail);
80
3
    env->SetProtoMethod(tmpl, "checkIP", CheckIP);
81
3
    env->SetProtoMethod(tmpl, "checkIssued", CheckIssued);
82
3
    env->SetProtoMethod(tmpl, "checkPrivateKey", CheckPrivateKey);
83
3
    env->SetProtoMethod(tmpl, "verify", Verify);
84
3
    env->SetProtoMethod(tmpl, "toLegacy", ToLegacy);
85
3
    env->SetProtoMethod(tmpl, "getIssuerCert", GetIssuerCert);
86
3
    env->set_x509_constructor_template(tmpl);
87
  }
88
56
  return tmpl;
89
}
90
91
2
bool X509Certificate::HasInstance(Environment* env, Local<Object> object) {
92
4
  return GetConstructorTemplate(env)->HasInstance(object);
93
}
94
95
53
MaybeLocal<Object> X509Certificate::New(
96
    Environment* env,
97
    X509Pointer cert,
98
    STACK_OF(X509)* issuer_chain) {
99
53
  std::shared_ptr<ManagedX509> mcert(new ManagedX509(std::move(cert)));
100
53
  return New(env, std::move(mcert), issuer_chain);
101
}
102
103
54
MaybeLocal<Object> X509Certificate::New(
104
    Environment* env,
105
    std::shared_ptr<ManagedX509> cert,
106
    STACK_OF(X509)* issuer_chain) {
107
54
  EscapableHandleScope scope(env->isolate());
108
  Local<Function> ctor;
109
162
  if (!GetConstructorTemplate(env)->GetFunction(env->context()).ToLocal(&ctor))
110
    return MaybeLocal<Object>();
111
112
  Local<Object> obj;
113
108
  if (!ctor->NewInstance(env->context()).ToLocal(&obj))
114
    return MaybeLocal<Object>();
115
116
54
  new X509Certificate(env, obj, std::move(cert), issuer_chain);
117
54
  return scope.Escape(obj);
118
}
119
120
1
MaybeLocal<Object> X509Certificate::GetCert(
121
    Environment* env,
122
    const SSLPointer& ssl) {
123
1
  ClearErrorOnReturn clear_error_on_return;
124
1
  X509* cert = SSL_get_certificate(ssl.get());
125
1
  if (cert == nullptr)
126
    return MaybeLocal<Object>();
127
128
1
  X509Pointer ptr(X509_dup(cert));
129
1
  return New(env, std::move(ptr));
130
}
131
132
1
MaybeLocal<Object> X509Certificate::GetPeerCert(
133
    Environment* env,
134
    const SSLPointer& ssl,
135
    GetPeerCertificateFlag flag) {
136
1
  ClearErrorOnReturn clear_error_on_return;
137
  Local<Object> obj;
138
  MaybeLocal<Object> maybe_cert;
139
140
1
  bool is_server =
141
1
      static_cast<int>(flag) & static_cast<int>(GetPeerCertificateFlag::SERVER);
142
143
2
  X509Pointer cert(is_server ? SSL_get_peer_certificate(ssl.get()) : nullptr);
144
1
  STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(ssl.get());
145


1
  if (!cert && (ssl_certs == nullptr || sk_X509_num(ssl_certs) == 0))
146
    return MaybeLocal<Object>();
147
148
1
  std::vector<Local<Value>> certs;
149
150
1
  if (!cert) {
151
1
    cert.reset(sk_X509_value(ssl_certs, 0));
152
1
    sk_X509_delete(ssl_certs, 0);
153
  }
154
155
1
  return sk_X509_num(ssl_certs)
156
2
      ? New(env, std::move(cert), ssl_certs)
157

2
      : New(env, std::move(cert));
158
}
159
160
50
void X509Certificate::Parse(const FunctionCallbackInfo<Value>& args) {
161
50
  Environment* env = Environment::GetCurrent(args);
162
163
50
  CHECK(args[0]->IsArrayBufferView());
164
100
  ArrayBufferViewContents<unsigned char> buf(args[0].As<ArrayBufferView>());
165
50
  const unsigned char* data = buf.data();
166
50
  unsigned data_len = buf.length();
167
168
  ClearErrorOnReturn clear_error_on_return;
169
50
  BIOPointer bio(LoadBIO(env, args[0]));
170
50
  if (!bio)
171
    return ThrowCryptoError(env, ERR_get_error());
172
173
  Local<Object> cert;
174
175
  X509Pointer pem(PEM_read_bio_X509_AUX(
176
50
      bio.get(), nullptr, NoPasswordCallback, nullptr));
177
50
  if (!pem) {
178
    // Try as DER, but return the original PEM failure if it isn't DER.
179
    MarkPopErrorOnReturn mark_here;
180
181
    X509Pointer der(d2i_X509(nullptr, &data, data_len));
182
    if (!der)
183
      return ThrowCryptoError(env, ERR_get_error());
184
185
    if (!X509Certificate::New(env, std::move(der)).ToLocal(&cert))
186
      return;
187
100
  } else if (!X509Certificate::New(env, std::move(pem)).ToLocal(&cert)) {
188
    return;
189
  }
190
191
100
  args.GetReturnValue().Set(cert);
192
}
193
194
13
void X509Certificate::Subject(const FunctionCallbackInfo<Value>& args) {
195
13
  Environment* env = Environment::GetCurrent(args);
196
  X509Certificate* cert;
197
13
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
198
26
  BIOPointer bio(BIO_new(BIO_s_mem()));
199
  Local<Value> ret;
200
26
  if (GetSubject(env, bio, cert->get()).ToLocal(&ret))
201
26
    args.GetReturnValue().Set(ret);
202
}
203
204
11
void X509Certificate::Issuer(const FunctionCallbackInfo<Value>& args) {
205
11
  Environment* env = Environment::GetCurrent(args);
206
  X509Certificate* cert;
207
11
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
208
22
  BIOPointer bio(BIO_new(BIO_s_mem()));
209
  Local<Value> ret;
210
22
  if (GetIssuerString(env, bio, cert->get()).ToLocal(&ret))
211
22
    args.GetReturnValue().Set(ret);
212
}
213
214
34
void X509Certificate::SubjectAltName(const FunctionCallbackInfo<Value>& args) {
215
34
  Environment* env = Environment::GetCurrent(args);
216
  X509Certificate* cert;
217
34
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
218
68
  BIOPointer bio(BIO_new(BIO_s_mem()));
219
  Local<Value> ret;
220
68
  if (GetSubjectAltNameString(env, bio, cert->get()).ToLocal(&ret))
221
68
    args.GetReturnValue().Set(ret);
222
}
223
224
6
void X509Certificate::InfoAccess(const FunctionCallbackInfo<Value>& args) {
225
6
  Environment* env = Environment::GetCurrent(args);
226
  X509Certificate* cert;
227
6
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
228
12
  BIOPointer bio(BIO_new(BIO_s_mem()));
229
  Local<Value> ret;
230
12
  if (GetInfoAccessString(env, bio, cert->get()).ToLocal(&ret))
231
12
    args.GetReturnValue().Set(ret);
232
}
233
234
1
void X509Certificate::ValidFrom(const FunctionCallbackInfo<Value>& args) {
235
1
  Environment* env = Environment::GetCurrent(args);
236
  X509Certificate* cert;
237
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
238
2
  BIOPointer bio(BIO_new(BIO_s_mem()));
239
  Local<Value> ret;
240
2
  if (GetValidFrom(env, cert->get(), bio).ToLocal(&ret))
241
2
    args.GetReturnValue().Set(ret);
242
}
243
244
1
void X509Certificate::ValidTo(const FunctionCallbackInfo<Value>& args) {
245
1
  Environment* env = Environment::GetCurrent(args);
246
  X509Certificate* cert;
247
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
248
2
  BIOPointer bio(BIO_new(BIO_s_mem()));
249
  Local<Value> ret;
250
2
  if (GetValidTo(env, cert->get(), bio).ToLocal(&ret))
251
2
    args.GetReturnValue().Set(ret);
252
}
253
254
1
void X509Certificate::Fingerprint(const FunctionCallbackInfo<Value>& args) {
255
1
  Environment* env = Environment::GetCurrent(args);
256
  X509Certificate* cert;
257
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
258
  Local<Value> ret;
259
2
  if (GetFingerprintDigest(env, EVP_sha1(), cert->get()).ToLocal(&ret))
260
2
    args.GetReturnValue().Set(ret);
261
}
262
263
1
void X509Certificate::Fingerprint256(const FunctionCallbackInfo<Value>& args) {
264
1
  Environment* env = Environment::GetCurrent(args);
265
  X509Certificate* cert;
266
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
267
  Local<Value> ret;
268
2
  if (GetFingerprintDigest(env, EVP_sha256(), cert->get()).ToLocal(&ret))
269
2
    args.GetReturnValue().Set(ret);
270
}
271
272
1
void X509Certificate::Fingerprint512(const FunctionCallbackInfo<Value>& args) {
273
1
  Environment* env = Environment::GetCurrent(args);
274
  X509Certificate* cert;
275
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
276
  Local<Value> ret;
277
2
  if (GetFingerprintDigest(env, EVP_sha512(), cert->get()).ToLocal(&ret))
278
2
    args.GetReturnValue().Set(ret);
279
}
280
281
1
void X509Certificate::KeyUsage(const FunctionCallbackInfo<Value>& args) {
282
1
  Environment* env = Environment::GetCurrent(args);
283
  X509Certificate* cert;
284
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
285
  Local<Value> ret;
286
2
  if (GetKeyUsage(env, cert->get()).ToLocal(&ret))
287
2
    args.GetReturnValue().Set(ret);
288
}
289
290
3
void X509Certificate::SerialNumber(const FunctionCallbackInfo<Value>& args) {
291
3
  Environment* env = Environment::GetCurrent(args);
292
  X509Certificate* cert;
293
3
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
294
  Local<Value> ret;
295
6
  if (GetSerialNumber(env, cert->get()).ToLocal(&ret))
296
6
    args.GetReturnValue().Set(ret);
297
}
298
299
2
void X509Certificate::Raw(const FunctionCallbackInfo<Value>& args) {
300
2
  Environment* env = Environment::GetCurrent(args);
301
  X509Certificate* cert;
302
2
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
303
  Local<Value> ret;
304
4
  if (GetRawDERCertificate(env, cert->get()).ToLocal(&ret))
305
4
    args.GetReturnValue().Set(ret);
306
}
307
308
2
void X509Certificate::PublicKey(const FunctionCallbackInfo<Value>& args) {
309
2
  Environment* env = Environment::GetCurrent(args);
310
  X509Certificate* cert;
311
2
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
312
313
4
  EVPKeyPointer pkey(X509_get_pubkey(cert->get()));
314
4
  ManagedEVPPKey epkey(std::move(pkey));
315
  std::shared_ptr<KeyObjectData> key_data =
316
4
      KeyObjectData::CreateAsymmetric(kKeyTypePublic, epkey);
317
318
  Local<Value> ret;
319
4
  if (KeyObjectHandle::Create(env, key_data).ToLocal(&ret))
320
4
    args.GetReturnValue().Set(ret);
321
}
322
323
1
void X509Certificate::Pem(const FunctionCallbackInfo<Value>& args) {
324
1
  Environment* env = Environment::GetCurrent(args);
325
  X509Certificate* cert;
326
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
327
2
  BIOPointer bio(BIO_new(BIO_s_mem()));
328
1
  if (PEM_write_bio_X509(bio.get(), cert->get()))
329
2
    args.GetReturnValue().Set(ToV8Value(env, bio));
330
}
331
332
1
void X509Certificate::CheckCA(const FunctionCallbackInfo<Value>& args) {
333
  X509Certificate* cert;
334
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
335
2
  args.GetReturnValue().Set(X509_check_ca(cert->get()) == 1);
336
}
337
338
11
void X509Certificate::CheckHost(const FunctionCallbackInfo<Value>& args) {
339
11
  Environment* env = Environment::GetCurrent(args);
340
  X509Certificate* cert;
341
11
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
342
343
22
  CHECK(args[0]->IsString());  // name
344
11
  CHECK(args[1]->IsUint32());  // flags
345
346
22
  Utf8Value name(env->isolate(), args[0]);
347
22
  uint32_t flags = args[1].As<Uint32>()->Value();
348
  char* peername;
349
350

22
  switch (X509_check_host(
351
              cert->get(),
352
11
              *name,
353
              name.length(),
354
              flags,
355
              &peername)) {
356
5
    case 1:  {  // Match!
357
5
      Local<Value> ret = args[0];
358
5
      if (peername != nullptr) {
359
5
        ret = OneByteString(env->isolate(), peername);
360
5
        OPENSSL_free(peername);
361
      }
362
10
      return args.GetReturnValue().Set(ret);
363
    }
364
5
    case 0:  // No Match!
365
5
      return;  // No return value is set
366
1
    case -2:  // Error!
367
1
      return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name");
368
    default:  // Error!
369
      return THROW_ERR_CRYPTO_OPERATION_FAILED(env);
370
  }
371
}
372
373
3
void X509Certificate::CheckEmail(const FunctionCallbackInfo<Value>& args) {
374
3
  Environment* env = Environment::GetCurrent(args);
375
  X509Certificate* cert;
376
3
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
377
378
6
  CHECK(args[0]->IsString());  // name
379
3
  CHECK(args[1]->IsUint32());  // flags
380
381
6
  Utf8Value name(env->isolate(), args[0]);
382
6
  uint32_t flags = args[1].As<Uint32>()->Value();
383
384

6
  switch (X509_check_email(
385
              cert->get(),
386
3
              *name,
387
              name.length(),
388
              flags)) {
389
1
    case 1:  // Match!
390

3
      return args.GetReturnValue().Set(args[0]);
391
1
    case 0:  // No Match!
392
1
      return;  // No return value is set
393
1
    case -2:  // Error!
394
1
      return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name");
395
    default:  // Error!
396
      return THROW_ERR_CRYPTO_OPERATION_FAILED(env);
397
  }
398
}
399
400
3
void X509Certificate::CheckIP(const FunctionCallbackInfo<Value>& args) {
401
3
  Environment* env = Environment::GetCurrent(args);
402
  X509Certificate* cert;
403
3
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
404
405
6
  CHECK(args[0]->IsString());  // IP
406
3
  CHECK(args[1]->IsUint32());  // flags
407
408
6
  Utf8Value name(env->isolate(), args[0]);
409
6
  uint32_t flags = args[1].As<Uint32>()->Value();
410
411

3
  switch (X509_check_ip_asc(cert->get(), *name, flags)) {
412
    case 1:  // Match!
413
      return args.GetReturnValue().Set(args[0]);
414
2
    case 0:  // No Match!
415
2
      return;  // No return value is set
416
1
    case -2:  // Error!
417
1
      return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP");
418
    default:  // Error!
419
      return THROW_ERR_CRYPTO_OPERATION_FAILED(env);
420
  }
421
}
422
423
2
void X509Certificate::CheckIssued(const FunctionCallbackInfo<Value>& args) {
424
2
  Environment* env = Environment::GetCurrent(args);
425
  X509Certificate* cert;
426
2
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
427
428
2
  CHECK(args[0]->IsObject());
429
4
  CHECK(X509Certificate::HasInstance(env, args[0].As<Object>()));
430
431
  X509Certificate* issuer;
432
2
  ASSIGN_OR_RETURN_UNWRAP(&issuer, args[0]);
433
434
4
  args.GetReturnValue().Set(
435
2
    X509_check_issued(issuer->get(), cert->get()) == X509_V_OK);
436
}
437
438
1
void X509Certificate::CheckPrivateKey(const FunctionCallbackInfo<Value>& args) {
439
  X509Certificate* cert;
440
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
441
442
1
  CHECK(args[0]->IsObject());
443
  KeyObjectHandle* key;
444
1
  ASSIGN_OR_RETURN_UNWRAP(&key, args[0]);
445
1
  CHECK_EQ(key->Data()->GetKeyType(), kKeyTypePrivate);
446
447
1
  args.GetReturnValue().Set(
448
1
      X509_check_private_key(
449
1
          cert->get(),
450
2
          key->Data()->GetAsymmetricKey().get()) == 1);
451
}
452
453
2
void X509Certificate::Verify(const FunctionCallbackInfo<Value>& args) {
454
  X509Certificate* cert;
455
2
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
456
457
2
  CHECK(args[0]->IsObject());
458
  KeyObjectHandle* key;
459
2
  ASSIGN_OR_RETURN_UNWRAP(&key, args[0]);
460
2
  CHECK_EQ(key->Data()->GetKeyType(), kKeyTypePublic);
461
462
2
  args.GetReturnValue().Set(
463
2
      X509_verify(
464
          cert->get(),
465
4
          key->Data()->GetAsymmetricKey().get()) > 0);
466
}
467
468
1
void X509Certificate::ToLegacy(const FunctionCallbackInfo<Value>& args) {
469
1
  Environment* env = Environment::GetCurrent(args);
470
  X509Certificate* cert;
471
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
472
  Local<Value> ret;
473
2
  if (X509ToObject(env, cert->get(), true).ToLocal(&ret))
474
2
    args.GetReturnValue().Set(ret);
475
}
476
477
3
void X509Certificate::GetIssuerCert(const FunctionCallbackInfo<Value>& args) {
478
  X509Certificate* cert;
479
3
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
480
3
  if (cert->issuer_cert_)
481
4
    args.GetReturnValue().Set(cert->issuer_cert_->object());
482
}
483
484
54
X509Certificate::X509Certificate(
485
    Environment* env,
486
    Local<Object> object,
487
    std::shared_ptr<ManagedX509> cert,
488
54
    STACK_OF(X509)* issuer_chain)
489
    : BaseObject(env, object),
490
54
      cert_(std::move(cert)) {
491
54
  MakeWeak();
492
493

54
  if (issuer_chain != nullptr && sk_X509_num(issuer_chain)) {
494
1
    X509Pointer cert(X509_dup(sk_X509_value(issuer_chain, 0)));
495
1
    sk_X509_delete(issuer_chain, 0);
496
1
    Local<Object> obj = sk_X509_num(issuer_chain)
497
        ? X509Certificate::New(env, std::move(cert), issuer_chain)
498
            .ToLocalChecked()
499

2
        : X509Certificate::New(env, std::move(cert))
500
2
            .ToLocalChecked();
501
1
    issuer_cert_.reset(Unwrap<X509Certificate>(obj));
502
  }
503
54
}
504
505
void X509Certificate::MemoryInfo(MemoryTracker* tracker) const {
506
  tracker->TrackField("cert", cert_);
507
}
508
509
BaseObjectPtr<BaseObject>
510
1
X509Certificate::X509CertificateTransferData::Deserialize(
511
    Environment* env,
512
    Local<Context> context,
513
    std::unique_ptr<worker::TransferData> self) {
514
2
  if (context != env->context()) {
515
    THROW_ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE(env);
516
    return {};
517
  }
518
519
  Local<Value> handle;
520
2
  if (!X509Certificate::New(env, data_).ToLocal(&handle))
521
    return {};
522
523
  return BaseObjectPtr<BaseObject>(
524
1
      Unwrap<X509Certificate>(handle.As<Object>()));
525
}
526
527
528
1
BaseObject::TransferMode X509Certificate::GetTransferMode() const {
529
1
  return BaseObject::TransferMode::kCloneable;
530
}
531
532
1
std::unique_ptr<worker::TransferData> X509Certificate::CloneForMessaging()
533
    const {
534
1
  return std::make_unique<X509CertificateTransferData>(cert_);
535
}
536
537
538
4377
void X509Certificate::Initialize(Environment* env, Local<Object> target) {
539
4377
  env->SetMethod(target, "parseX509", X509Certificate::Parse);
540
541
13131
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT);
542
13131
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NEVER_CHECK_SUBJECT);
543
13131
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NO_WILDCARDS);
544
13131
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
545
13131
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS);
546
8754
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS);
547
4377
}
548
549
4935
void X509Certificate::RegisterExternalReferences(
550
    ExternalReferenceRegistry* registry) {
551
4935
  registry->Register(X509Certificate::Parse);
552
4935
  registry->Register(Subject);
553
4935
  registry->Register(SubjectAltName);
554
4935
  registry->Register(InfoAccess);
555
4935
  registry->Register(Issuer);
556
4935
  registry->Register(ValidTo);
557
4935
  registry->Register(ValidFrom);
558
4935
  registry->Register(Fingerprint);
559
4935
  registry->Register(Fingerprint256);
560
4935
  registry->Register(KeyUsage);
561
4935
  registry->Register(SerialNumber);
562
4935
  registry->Register(Pem);
563
4935
  registry->Register(Raw);
564
4935
  registry->Register(PublicKey);
565
4935
  registry->Register(CheckCA);
566
4935
  registry->Register(CheckHost);
567
4935
  registry->Register(CheckEmail);
568
4935
  registry->Register(CheckIP);
569
4935
  registry->Register(CheckIssued);
570
4935
  registry->Register(CheckPrivateKey);
571
4935
  registry->Register(Verify);
572
4935
  registry->Register(ToLegacy);
573
4935
  registry->Register(GetIssuerCert);
574
4935
}
575
}  // namespace crypto
576
}  // namespace node