GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/crypto/crypto_x509.cc Lines: 227 285 79.6 %
Date: 2021-01-16 04:10:54 Branches: 74 180 41.1 %

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::Array;
19
using v8::ArrayBufferView;
20
using v8::Context;
21
using v8::EscapableHandleScope;
22
using v8::Function;
23
using v8::FunctionCallbackInfo;
24
using v8::FunctionTemplate;
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
2
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
5
Local<FunctionTemplate> X509Certificate::GetConstructorTemplate(
55
    Environment* env) {
56
5
  Local<FunctionTemplate> tmpl = env->x509_constructor_template();
57
5
  if (tmpl.IsEmpty()) {
58
1
    tmpl = FunctionTemplate::New(env->isolate());
59
2
    tmpl->InstanceTemplate()->SetInternalFieldCount(1);
60
2
    tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
61
2
    tmpl->SetClassName(
62
1
        FIXED_ONE_BYTE_STRING(env->isolate(), "X509Certificate"));
63
1
    env->SetProtoMethod(tmpl, "subject", Subject);
64
1
    env->SetProtoMethod(tmpl, "subjectAltName", SubjectAltName);
65
1
    env->SetProtoMethod(tmpl, "infoAccess", InfoAccess);
66
1
    env->SetProtoMethod(tmpl, "issuer", Issuer);
67
1
    env->SetProtoMethod(tmpl, "validTo", ValidTo);
68
1
    env->SetProtoMethod(tmpl, "validFrom", ValidFrom);
69
1
    env->SetProtoMethod(tmpl, "fingerprint", Fingerprint);
70
1
    env->SetProtoMethod(tmpl, "fingerprint256", Fingerprint256);
71
1
    env->SetProtoMethod(tmpl, "keyUsage", KeyUsage);
72
1
    env->SetProtoMethod(tmpl, "serialNumber", SerialNumber);
73
1
    env->SetProtoMethod(tmpl, "pem", Pem);
74
1
    env->SetProtoMethod(tmpl, "raw", Raw);
75
1
    env->SetProtoMethod(tmpl, "publicKey", PublicKey);
76
1
    env->SetProtoMethod(tmpl, "checkCA", CheckCA);
77
1
    env->SetProtoMethod(tmpl, "checkHost", CheckHost);
78
1
    env->SetProtoMethod(tmpl, "checkEmail", CheckEmail);
79
1
    env->SetProtoMethod(tmpl, "checkIP", CheckIP);
80
1
    env->SetProtoMethod(tmpl, "checkIssued", CheckIssued);
81
1
    env->SetProtoMethod(tmpl, "checkPrivateKey", CheckPrivateKey);
82
1
    env->SetProtoMethod(tmpl, "verify", Verify);
83
1
    env->SetProtoMethod(tmpl, "toLegacy", ToLegacy);
84
1
    env->set_x509_constructor_template(tmpl);
85
  }
86
5
  return tmpl;
87
}
88
89
2
bool X509Certificate::HasInstance(Environment* env, Local<Object> object) {
90
4
  return GetConstructorTemplate(env)->HasInstance(object);
91
}
92
93
2
MaybeLocal<Object> X509Certificate::New(
94
    Environment* env,
95
    X509Pointer cert) {
96
4
  std::shared_ptr<ManagedX509> mcert(new ManagedX509(std::move(cert)));
97
4
  return New(env, std::move(mcert));
98
}
99
100
3
MaybeLocal<Object> X509Certificate::New(
101
    Environment* env,
102
    std::shared_ptr<ManagedX509> cert) {
103
3
  EscapableHandleScope scope(env->isolate());
104
  Local<Function> ctor;
105
9
  if (!GetConstructorTemplate(env)->GetFunction(env->context()).ToLocal(&ctor))
106
    return MaybeLocal<Object>();
107
108
  Local<Object> obj;
109
9
  if (!ctor->NewInstance(env->context()).ToLocal(&obj))
110
    return MaybeLocal<Object>();
111
112
3
  new X509Certificate(env, obj, std::move(cert));
113
3
  return scope.Escape(obj);
114
}
115
116
MaybeLocal<Object> X509Certificate::GetCert(
117
    Environment* env,
118
    const SSLPointer& ssl) {
119
  ClearErrorOnReturn clear_error_on_return;
120
  X509* cert = SSL_get_certificate(ssl.get());
121
  if (cert == nullptr)
122
    return MaybeLocal<Object>();
123
124
  X509Pointer ptr(cert);
125
  return New(env, std::move(ptr));
126
}
127
128
MaybeLocal<Object> X509Certificate::GetPeerCert(
129
    Environment* env,
130
    const SSLPointer& ssl,
131
    GetPeerCertificateFlag flag) {
132
  EscapableHandleScope scope(env->isolate());
133
  ClearErrorOnReturn clear_error_on_return;
134
  Local<Object> obj;
135
  MaybeLocal<Object> maybe_cert;
136
137
  bool is_server =
138
      static_cast<int>(flag) & static_cast<int>(GetPeerCertificateFlag::SERVER);
139
  bool abbreviated =
140
      static_cast<int>(flag)
141
      & static_cast<int>(GetPeerCertificateFlag::ABBREVIATED);
142
143
  X509Pointer cert(is_server ? SSL_get_peer_certificate(ssl.get()) : nullptr);
144
  STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(ssl.get());
145
  if (!cert && (ssl_certs == nullptr || sk_X509_num(ssl_certs) == 0))
146
    return MaybeLocal<Object>();
147
148
  std::vector<Local<Value>> certs;
149
150
  if (!cert) cert.reset(sk_X509_value(ssl_certs, 0));
151
  if (!X509Certificate::New(env, std::move(cert)).ToLocal(&obj))
152
    return MaybeLocal<Object>();
153
154
  certs.push_back(obj);
155
156
  int count = sk_X509_num(ssl_certs);
157
  if (!abbreviated) {
158
    for (int i = 0; i < count; i++) {
159
      cert.reset(X509_dup(sk_X509_value(ssl_certs, i)));
160
      if (!cert || !X509Certificate::New(env, std::move(cert)).ToLocal(&obj))
161
        return MaybeLocal<Object>();
162
      certs.push_back(obj);
163
    }
164
  }
165
166
  return scope.Escape(Array::New(env->isolate(), certs.data(), certs.size()));
167
}
168
169
2
void X509Certificate::Parse(const FunctionCallbackInfo<Value>& args) {
170
2
  Environment* env = Environment::GetCurrent(args);
171
172
4
  CHECK(args[0]->IsArrayBufferView());
173
4
  ArrayBufferViewContents<unsigned char> buf(args[0].As<ArrayBufferView>());
174
2
  const unsigned char* data = buf.data();
175
2
  unsigned data_len = buf.length();
176
177
2
  ClearErrorOnReturn clear_error_on_return;
178
4
  BIOPointer bio(LoadBIO(env, args[0]));
179
2
  if (!bio)
180
    return ThrowCryptoError(env, ERR_get_error());
181
182
  Local<Object> cert;
183
184
  X509Pointer pem(PEM_read_bio_X509_AUX(
185
4
      bio.get(), nullptr, NoPasswordCallback, nullptr));
186
2
  if (!pem) {
187
    // Try as DER, but return the original PEM failure if it isn't DER.
188
    MarkPopErrorOnReturn mark_here;
189
190
    X509Pointer der(d2i_X509(nullptr, &data, data_len));
191
    if (!der)
192
      return ThrowCryptoError(env, ERR_get_error());
193
194
    if (!X509Certificate::New(env, std::move(der)).ToLocal(&cert))
195
      return;
196
4
  } else if (!X509Certificate::New(env, std::move(pem)).ToLocal(&cert)) {
197
    return;
198
  }
199
200
4
  args.GetReturnValue().Set(cert);
201
}
202
203
1
void X509Certificate::Subject(const FunctionCallbackInfo<Value>& args) {
204
1
  Environment* env = Environment::GetCurrent(args);
205
  X509Certificate* cert;
206
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
207
2
  BIOPointer bio(BIO_new(BIO_s_mem()));
208
  Local<Value> ret;
209
2
  if (GetSubject(env, bio, cert->get()).ToLocal(&ret))
210
2
    args.GetReturnValue().Set(ret);
211
}
212
213
1
void X509Certificate::Issuer(const FunctionCallbackInfo<Value>& args) {
214
1
  Environment* env = Environment::GetCurrent(args);
215
  X509Certificate* cert;
216
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
217
2
  BIOPointer bio(BIO_new(BIO_s_mem()));
218
  Local<Value> ret;
219
2
  if (GetIssuerString(env, bio, cert->get()).ToLocal(&ret))
220
2
    args.GetReturnValue().Set(ret);
221
}
222
223
1
void X509Certificate::SubjectAltName(const FunctionCallbackInfo<Value>& args) {
224
1
  Environment* env = Environment::GetCurrent(args);
225
  X509Certificate* cert;
226
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
227
2
  BIOPointer bio(BIO_new(BIO_s_mem()));
228
  Local<Value> ret;
229
2
  if (GetInfoString<NID_subject_alt_name>(env, bio, cert->get()).ToLocal(&ret))
230
2
    args.GetReturnValue().Set(ret);
231
}
232
233
1
void X509Certificate::InfoAccess(const FunctionCallbackInfo<Value>& args) {
234
1
  Environment* env = Environment::GetCurrent(args);
235
  X509Certificate* cert;
236
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
237
2
  BIOPointer bio(BIO_new(BIO_s_mem()));
238
  Local<Value> ret;
239
2
  if (GetInfoString<NID_info_access>(env, bio, cert->get()).ToLocal(&ret))
240
2
    args.GetReturnValue().Set(ret);
241
}
242
243
1
void X509Certificate::ValidFrom(const FunctionCallbackInfo<Value>& args) {
244
1
  Environment* env = Environment::GetCurrent(args);
245
  X509Certificate* cert;
246
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
247
2
  BIOPointer bio(BIO_new(BIO_s_mem()));
248
  Local<Value> ret;
249
2
  if (GetValidFrom(env, cert->get(), bio).ToLocal(&ret))
250
2
    args.GetReturnValue().Set(ret);
251
}
252
253
1
void X509Certificate::ValidTo(const FunctionCallbackInfo<Value>& args) {
254
1
  Environment* env = Environment::GetCurrent(args);
255
  X509Certificate* cert;
256
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
257
2
  BIOPointer bio(BIO_new(BIO_s_mem()));
258
  Local<Value> ret;
259
2
  if (GetValidTo(env, cert->get(), bio).ToLocal(&ret))
260
2
    args.GetReturnValue().Set(ret);
261
}
262
263
1
void X509Certificate::Fingerprint(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_sha1(), cert->get()).ToLocal(&ret))
269
2
    args.GetReturnValue().Set(ret);
270
}
271
272
1
void X509Certificate::Fingerprint256(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_sha256(), 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
1
void X509Certificate::SerialNumber(const FunctionCallbackInfo<Value>& args) {
291
1
  Environment* env = Environment::GetCurrent(args);
292
  X509Certificate* cert;
293
1
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
294
  Local<Value> ret;
295
2
  if (GetSerialNumber(env, cert->get()).ToLocal(&ret))
296
2
    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
3
    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
3
  args.GetReturnValue().Set(X509_check_ca(cert->get()) == 1);
336
}
337
338
3
void X509Certificate::CheckHost(const FunctionCallbackInfo<Value>& args) {
339
3
  Environment* env = Environment::GetCurrent(args);
340
  X509Certificate* cert;
341
3
  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
342
343
9
  CHECK(args[0]->IsString());  // name
344
6
  CHECK(args[1]->IsUint32());  // flags
345
346
6
  Utf8Value name(env->isolate(), args[0]);
347
9
  uint32_t flags = args[1].As<Uint32>()->Value();
348
  char* peername;
349
350

6
  switch (X509_check_host(
351
              cert->get(),
352
3
              *name,
353
              name.length(),
354
              flags,
355
              &peername)) {
356
    case 1:  {  // Match!
357
1
      Local<Value> ret = args[0];
358
1
      if (peername != nullptr) {
359
2
        ret = OneByteString(env->isolate(), peername);
360
1
        OPENSSL_free(peername);
361
      }
362
2
      return args.GetReturnValue().Set(ret);
363
    }
364
    case 0:  // No Match!
365
1
      return;  // No return value is set
366
    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
9
  CHECK(args[0]->IsString());  // name
379
6
  CHECK(args[1]->IsUint32());  // flags
380
381
6
  Utf8Value name(env->isolate(), args[0]);
382
9
  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
    case 1:  // Match!
390
2
      return args.GetReturnValue().Set(args[0]);
391
    case 0:  // No Match!
392
1
      return;  // No return value is set
393
    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
9
  CHECK(args[0]->IsString());  // IP
406
6
  CHECK(args[1]->IsUint32());  // flags
407
408
6
  Utf8Value name(env->isolate(), args[0]);
409
9
  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
    case 0:  // No Match!
415
2
      return;  // No return value is set
416
    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
4
  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
6
  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
2
  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
3
  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
4
  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
6
  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()).ToLocal(&ret))
474
2
    args.GetReturnValue().Set(ret);
475
}
476
477
3
X509Certificate::X509Certificate(
478
    Environment* env,
479
    Local<Object> object,
480
3
    std::shared_ptr<ManagedX509> cert)
481
    : BaseObject(env, object),
482
3
      cert_(std::move(cert)) {
483
3
  MakeWeak();
484
3
}
485
486
void X509Certificate::MemoryInfo(MemoryTracker* tracker) const {
487
  tracker->TrackField("cert", cert_);
488
}
489
490
BaseObjectPtr<BaseObject>
491
1
X509Certificate::X509CertificateTransferData::Deserialize(
492
    Environment* env,
493
    Local<Context> context,
494
    std::unique_ptr<worker::TransferData> self) {
495
2
  if (context != env->context()) {
496
    THROW_ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE(env);
497
    return {};
498
  }
499
500
  Local<Value> handle;
501
2
  if (!X509Certificate::New(env, data_).ToLocal(&handle))
502
    return {};
503
504
  return BaseObjectPtr<BaseObject>(
505
1
      Unwrap<X509Certificate>(handle.As<Object>()));
506
}
507
508
509
1
BaseObject::TransferMode X509Certificate::GetTransferMode() const {
510
1
  return BaseObject::TransferMode::kCloneable;
511
}
512
513
1
std::unique_ptr<worker::TransferData> X509Certificate::CloneForMessaging()
514
    const {
515
1
  return std::make_unique<X509CertificateTransferData>(cert_);
516
}
517
518
519
663
void X509Certificate::Initialize(Environment* env, Local<Object> target) {
520
663
  env->SetMethod(target, "parseX509", X509Certificate::Parse);
521
522
2652
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT);
523
663
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NEVER_CHECK_SUBJECT);
524
1989
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NO_WILDCARDS);
525
3315
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
526
6630
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS);
527
6630
  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS);
528
6630
}
529
4641
530
1989
}  // namespace crypto
531

15321
}  // namespace node