GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_x509.cc Lines: 303 340 89.1 %
Date: 2022-12-07 04:23:16 Branches: 110 210 52.4 %

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


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

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

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

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

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

54
  if (issuer_chain != nullptr && sk_X509_num(issuer_chain)) {
507
1
    X509Pointer cert(X509_dup(sk_X509_value(issuer_chain, 0)));
508
1
    sk_X509_delete(issuer_chain, 0);
509
1
    Local<Object> obj = sk_X509_num(issuer_chain)
510
        ? X509Certificate::New(env, std::move(cert), issuer_chain)
511
            .ToLocalChecked()
512

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