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_util.cc Lines: 237 269 88.1 %
Date: 2020-11-20 19:51:53 Branches: 108 206 52.4 %

Line Branch Exec Source
1
#include "crypto/crypto_util.h"
2
#include "crypto/crypto_bio.h"
3
#include "crypto/crypto_keys.h"
4
#include "allocated_buffer-inl.h"
5
#include "async_wrap-inl.h"
6
#include "env-inl.h"
7
#include "memory_tracker-inl.h"
8
#include "node_buffer.h"
9
#include "node_options-inl.h"
10
#include "string_bytes.h"
11
#include "threadpoolwork-inl.h"
12
#include "util-inl.h"
13
#include "v8.h"
14
15
#include "math.h"
16
17
namespace node {
18
19
using v8::ArrayBuffer;
20
using v8::BackingStore;
21
using v8::Context;
22
using v8::Exception;
23
using v8::FunctionCallbackInfo;
24
using v8::HandleScope;
25
using v8::Isolate;
26
using v8::Just;
27
using v8::Local;
28
using v8::Maybe;
29
using v8::MaybeLocal;
30
using v8::NewStringType;
31
using v8::Nothing;
32
using v8::Object;
33
using v8::String;
34
using v8::Value;
35
36
namespace crypto {
37
1962
int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
38
  // From https://www.openssl.org/docs/man1.1.1/man3/SSL_verify_cb:
39
  //
40
  //   If VerifyCallback returns 1, the verification process is continued. If
41
  //   VerifyCallback always returns 1, the TLS/SSL handshake will not be
42
  //   terminated with respect to verification failures and the connection will
43
  //   be established. The calling process can however retrieve the error code
44
  //   of the last verification error using SSL_get_verify_result(3) or by
45
  //   maintaining its own error storage managed by VerifyCallback.
46
  //
47
  // Since we cannot perform I/O quickly enough with X509_STORE_CTX_ APIs in
48
  // this callback, we ignore all preverify_ok errors and let the handshake
49
  // continue. It is imperative that the user use Connection::VerifyError after
50
  // the 'secure' callback has been made.
51
1962
  return 1;
52
}
53
54
15496
void CheckEntropy() {
55
  for (;;) {
56
15496
    int status = RAND_status();
57
15496
    CHECK_GE(status, 0);  // Cannot fail.
58
15496
    if (status != 0)
59
30992
      break;
60
61
    // Give up, RAND_poll() not supported.
62
    if (RAND_poll() == 0)
63
      break;
64
  }
65
15496
}
66
67
14760
bool EntropySource(unsigned char* buffer, size_t length) {
68
  // Ensure that OpenSSL's PRNG is properly seeded.
69
14760
  CheckEntropy();
70
  // RAND_bytes() can return 0 to indicate that the entropy data is not truly
71
  // random. That's okay, it's still better than V8's stock source of entropy,
72
  // which is /dev/urandom on UNIX platforms and the current time on Windows.
73
14760
  return RAND_bytes(buffer, length) != -1;
74
}
75
76
102
int PasswordCallback(char* buf, int size, int rwflag, void* u) {
77
102
  const ByteSource* passphrase = *static_cast<const ByteSource**>(u);
78
102
  if (passphrase != nullptr) {
79
91
    size_t buflen = static_cast<size_t>(size);
80
91
    size_t len = passphrase->size();
81
91
    if (buflen < len)
82
1
      return -1;
83
90
    memcpy(buf, passphrase->get(), len);
84
90
    return len;
85
  }
86
87
11
  return -1;
88
}
89
90
// This callback is used to avoid the default passphrase callback in OpenSSL
91
// which will typically prompt for the passphrase. The prompting is designed
92
// for the OpenSSL CLI, but works poorly for Node.js because it involves
93
// synchronous interaction with the controlling terminal, something we never
94
// want, and use this function to avoid it.
95
int NoPasswordCallback(char* buf, int size, int rwflag, void* u) {
96
  return 0;
97
}
98
99
637
void InitCryptoOnce() {
100
#ifndef OPENSSL_IS_BORINGSSL
101
637
  OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
102
103
  // --openssl-config=...
104
637
  if (!per_process::cli_options->openssl_config.empty()) {
105
5
    const char* conf = per_process::cli_options->openssl_config.c_str();
106
5
    OPENSSL_INIT_set_config_filename(settings, conf);
107
  }
108
109
637
  OPENSSL_init_ssl(0, settings);
110
637
  OPENSSL_INIT_free(settings);
111
637
  settings = nullptr;
112
#endif
113
114
#ifdef NODE_FIPS_MODE
115
  /* Override FIPS settings in cnf file, if needed. */
116
  unsigned long err = 0;  // NOLINT(runtime/int)
117
  if (per_process::cli_options->enable_fips_crypto ||
118
      per_process::cli_options->force_fips_crypto) {
119
    if (0 == FIPS_mode() && !FIPS_mode_set(1)) {
120
      err = ERR_get_error();
121
    }
122
  }
123
  if (0 != err) {
124
    fprintf(stderr,
125
            "openssl fips failed: %s\n",
126
            ERR_error_string(err, nullptr));
127
    UNREACHABLE();
128
  }
129
#endif  // NODE_FIPS_MODE
130
131
  // Turn off compression. Saves memory and protects against CRIME attacks.
132
  // No-op with OPENSSL_NO_COMP builds of OpenSSL.
133
637
  sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
134
135
#ifndef OPENSSL_NO_ENGINE
136
637
  ERR_load_ENGINE_strings();
137
637
  ENGINE_load_builtin_engines();
138
#endif  // !OPENSSL_NO_ENGINE
139
140
637
  NodeBIO::GetMethod();
141
637
}
142
143
#ifdef NODE_FIPS_MODE
144
void GetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
145
  args.GetReturnValue().Set(FIPS_mode() ? 1 : 0);
146
}
147
148
void SetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
149
  CHECK(!per_process::cli_options->force_fips_crypto);
150
  Environment* env = Environment::GetCurrent(args);
151
  bool enable = args[0]->BooleanValue(env->isolate());
152
153
  if (enable == FIPS_mode())
154
    return;  // No action needed.
155
156
  if (!FIPS_mode_set(enable)) {
157
    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
158
    return ThrowCryptoError(env, err);
159
  }
160
}
161
#endif /* NODE_FIPS_MODE */
162
163
96
void CryptoErrorVector::Capture() {
164
96
  clear();
165
143
  while (auto err = ERR_get_error()) {
166
    char buf[256];
167
47
    ERR_error_string_n(err, buf, sizeof(buf));
168
47
    push_back(buf);
169
47
  }
170
96
  std::reverse(begin(), end());
171
96
}
172
173
114
MaybeLocal<Value> CryptoErrorVector::ToException(
174
    Environment* env,
175
    Local<String> exception_string) const {
176
114
  if (exception_string.IsEmpty()) {
177
36
    CryptoErrorVector copy(*this);
178
18
    if (copy.empty()) copy.push_back("no error");  // But possibly a bug...
179
    // Use last element as the error message, everything else goes
180
    // into the .opensslErrorStack property on the exception object.
181
    Local<String> exception_string;
182
36
    if (!String::NewFromUtf8(
183
            env->isolate(),
184
18
            copy.back().data(),
185
            NewStringType::kNormal,
186
54
            copy.back().size()).ToLocal(&exception_string)) {
187
      return MaybeLocal<Value>();
188
    }
189
18
    copy.pop_back();
190
18
    return copy.ToException(env, exception_string);
191
  }
192
193
96
  Local<Value> exception_v = Exception::Error(exception_string);
194
96
  CHECK(!exception_v.IsEmpty());
195
196
96
  if (!empty()) {
197
21
    CHECK(exception_v->IsObject());
198
21
    Local<Object> exception = exception_v.As<Object>();
199
    Local<Value> stack;
200

84
    if (!ToV8Value(env->context(), *this).ToLocal(&stack) ||
201
84
        exception->Set(env->context(), env->openssl_error_stack(), stack)
202
21
            .IsNothing()) {
203
1
      return MaybeLocal<Value>();
204
    }
205
  }
206
207
95
  return exception_v;
208
}
209
210
12354
ByteSource::ByteSource(ByteSource&& other) noexcept
211
12354
    : data_(other.data_),
212
12354
      allocated_data_(other.allocated_data_),
213
24708
      size_(other.size_) {
214
12354
  other.allocated_data_ = nullptr;
215
12354
}
216
217
86271
ByteSource::~ByteSource() {
218
43136
  OPENSSL_clear_free(allocated_data_, size_);
219
43135
}
220
221
void ByteSource::reset() {
222
  OPENSSL_clear_free(allocated_data_, size_);
223
  data_ = nullptr;
224
  size_ = 0;
225
}
226
227
9337
ByteSource& ByteSource::operator=(ByteSource&& other) noexcept {
228
9337
  if (&other != this) {
229
9337
    OPENSSL_clear_free(allocated_data_, size_);
230
9337
    data_ = other.data_;
231
9337
    allocated_data_ = other.allocated_data_;
232
9337
    other.allocated_data_ = nullptr;
233
9337
    size_ = other.size_;
234
  }
235
9337
  return *this;
236
}
237
238
2467
std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore() {
239
  // It's ok for allocated_data_ to be nullptr but
240
  // only if size_ is zero.
241

2467
  CHECK_IMPLIES(size_ > 0, allocated_data_ != nullptr);
242
  std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore(
243
2467
      allocated_data_,
244
      size(),
245
7397
      [](void* data, size_t length, void* deleter_data) {
246
2465
        OPENSSL_clear_free(deleter_data, length);
247
12331
      }, allocated_data_);
248
2467
  CHECK(ptr);
249
2467
  allocated_data_ = nullptr;
250
2467
  data_ = nullptr;
251
2467
  size_ = 0;
252
2467
  return ptr;
253
}
254
255
2467
Local<ArrayBuffer> ByteSource::ToArrayBuffer(Environment* env) {
256
4934
  std::unique_ptr<BackingStore> store = ReleaseToBackingStore();
257
4934
  return ArrayBuffer::New(env->isolate(), std::move(store));
258
}
259
260
15248
const char* ByteSource::get() const {
261
15248
  return data_;
262
}
263
264
15796
size_t ByteSource::size() const {
265
15796
  return size_;
266
}
267
268
224
ByteSource ByteSource::FromBIO(const BIOPointer& bio) {
269
224
  CHECK(bio);
270
  BUF_MEM* bptr;
271
224
  BIO_get_mem_ptr(bio.get(), &bptr);
272
224
  char* data = MallocOpenSSL<char>(bptr->length);
273
224
  memcpy(data, bptr->data, bptr->length);
274
224
  return Allocated(data, bptr->length);
275
}
276
277
1093
ByteSource ByteSource::FromEncodedString(Environment* env,
278
                                         Local<String> key,
279
                                         enum encoding enc) {
280
1093
  size_t length = 0;
281
1093
  size_t actual = 0;
282
1093
  char* data = nullptr;
283
284

2186
  if (StringBytes::Size(env->isolate(), key, enc).To(&length) && length > 0) {
285
1093
    data = MallocOpenSSL<char>(length);
286
1093
    actual = StringBytes::Write(env->isolate(), data, length, key, enc);
287
288
1093
    CHECK(actual <= length);
289
290
1093
    if (actual == 0) {
291
      OPENSSL_clear_free(data, length);
292
      data = nullptr;
293
1093
    } else if (actual < length) {
294
      data = reinterpret_cast<char*>(OPENSSL_realloc(data, actual));
295
    }
296
  }
297
298
1093
  return Allocated(data, actual);
299
}
300
301
1806
ByteSource ByteSource::FromStringOrBuffer(Environment* env,
302
                                          Local<Value> value) {
303
1806
  return IsAnyByteSource(value) ? FromBuffer(value)
304
1806
                                : FromString(env, value.As<String>());
305
}
306
307
24
ByteSource ByteSource::FromString(Environment* env, Local<String> str,
308
                                  bool ntc) {
309
48
  CHECK(str->IsString());
310
48
  size_t size = str->Utf8Length(env->isolate());
311
24
  size_t alloc_size = ntc ? size + 1 : size;
312
24
  char* data = MallocOpenSSL<char>(alloc_size);
313
24
  int opts = String::NO_OPTIONS;
314
24
  if (!ntc) opts |= String::NO_NULL_TERMINATION;
315
48
  str->WriteUtf8(env->isolate(), data, alloc_size, nullptr, opts);
316
24
  return Allocated(data, size);
317
}
318
319
1808
ByteSource ByteSource::FromBuffer(Local<Value> buffer, bool ntc) {
320
3616
  ArrayBufferOrViewContents<char> buf(buffer);
321
3616
  return ntc ? buf.ToNullTerminatedCopy() : buf.ToByteSource();
322
}
323
324
1347
ByteSource ByteSource::FromSecretKeyBytes(
325
    Environment* env,
326
    Local<Value> value) {
327
  // A key can be passed as a string, buffer or KeyObject with type 'secret'.
328
  // If it is a string, we need to convert it to a buffer. We are not doing that
329
  // in JS to avoid creating an unprotected copy on the heap.
330

2694
  return value->IsString() || IsAnyByteSource(value) ?
331
           ByteSource::FromStringOrBuffer(env, value) :
332
1333
           ByteSource::FromSymmetricKeyObjectHandle(value);
333
}
334
335
ByteSource ByteSource::NullTerminatedCopy(Environment* env,
336
                                          Local<Value> value) {
337
  return Buffer::HasInstance(value) ? FromBuffer(value, true)
338
                                    : FromString(env, value.As<String>(), true);
339
}
340
341
14
ByteSource ByteSource::FromSymmetricKeyObjectHandle(Local<Value> handle) {
342
14
  CHECK(handle->IsObject());
343
14
  KeyObjectHandle* key = Unwrap<KeyObjectHandle>(handle.As<Object>());
344
14
  CHECK_NOT_NULL(key);
345
14
  return Foreign(key->Data()->GetSymmetricKey(),
346
28
                 key->Data()->GetSymmetricKeySize());
347
}
348
349
15782
ByteSource::ByteSource(const char* data, char* allocated_data, size_t size)
350
    : data_(data),
351
      allocated_data_(allocated_data),
352
15782
      size_(size) {}
353
354
12444
ByteSource ByteSource::Allocated(char* data, size_t size) {
355
12444
  return ByteSource(data, data, size);
356
}
357
358
3337
ByteSource ByteSource::Foreign(const char* data, size_t size) {
359
3337
  return ByteSource(data, nullptr, size);
360
}
361
362
namespace error {
363
77
Maybe<bool> Decorate(Environment* env, Local<Object> obj,
364
              unsigned long err) {  // NOLINT(runtime/int)
365
77
  if (err == 0) return Just(true);  // No decoration necessary.
366
367
66
  const char* ls = ERR_lib_error_string(err);
368
66
  const char* fs = ERR_func_error_string(err);
369
66
  const char* rs = ERR_reason_error_string(err);
370
371
66
  Isolate* isolate = env->isolate();
372
66
  Local<Context> context = isolate->GetCurrentContext();
373
374
66
  if (ls != nullptr) {
375
198
    if (obj->Set(context, env->library_string(),
376
264
                 OneByteString(isolate, ls)).IsNothing()) {
377
1
      return Nothing<bool>();
378
    }
379
  }
380
65
  if (fs != nullptr) {
381
195
    if (obj->Set(context, env->function_string(),
382
260
                 OneByteString(isolate, fs)).IsNothing()) {
383
      return Nothing<bool>();
384
    }
385
  }
386
65
  if (rs != nullptr) {
387
195
    if (obj->Set(context, env->reason_string(),
388
260
                 OneByteString(isolate, rs)).IsNothing()) {
389
      return Nothing<bool>();
390
    }
391
392
    // SSL has no API to recover the error name from the number, so we
393
    // transform reason strings like "this error" to "ERR_SSL_THIS_ERROR",
394
    // which ends up being close to the original error macro name.
395
130
    std::string reason(rs);
396
397
1160
    for (auto& c : reason) {
398
1095
      if (c == ' ')
399
123
        c = '_';
400
      else
401
972
        c = ToUpper(c);
402
    }
403
404
#define OSSL_ERROR_CODES_MAP(V)                                               \
405
    V(SYS)                                                                    \
406
    V(BN)                                                                     \
407
    V(RSA)                                                                    \
408
    V(DH)                                                                     \
409
    V(EVP)                                                                    \
410
    V(BUF)                                                                    \
411
    V(OBJ)                                                                    \
412
    V(PEM)                                                                    \
413
    V(DSA)                                                                    \
414
    V(X509)                                                                   \
415
    V(ASN1)                                                                   \
416
    V(CONF)                                                                   \
417
    V(CRYPTO)                                                                 \
418
    V(EC)                                                                     \
419
    V(SSL)                                                                    \
420
    V(BIO)                                                                    \
421
    V(PKCS7)                                                                  \
422
    V(X509V3)                                                                 \
423
    V(PKCS12)                                                                 \
424
    V(RAND)                                                                   \
425
    V(DSO)                                                                    \
426
    V(ENGINE)                                                                 \
427
    V(OCSP)                                                                   \
428
    V(UI)                                                                     \
429
    V(COMP)                                                                   \
430
    V(ECDSA)                                                                  \
431
    V(ECDH)                                                                   \
432
    V(OSSL_STORE)                                                             \
433
    V(FIPS)                                                                   \
434
    V(CMS)                                                                    \
435
    V(TS)                                                                     \
436
    V(HMAC)                                                                   \
437
    V(CT)                                                                     \
438
    V(ASYNC)                                                                  \
439
    V(KDF)                                                                    \
440
    V(SM2)                                                                    \
441
    V(USER)                                                                   \
442
443
#define V(name) case ERR_LIB_##name: lib = #name "_"; break;
444
65
    const char* lib = "";
445
65
    const char* prefix = "OSSL_";
446









65
    switch (ERR_GET_LIB(err)) { OSSL_ERROR_CODES_MAP(V) }
447
16
#undef V
448
#undef OSSL_ERROR_CODES_MAP
449
2
    // Don't generate codes like "ERR_OSSL_SSL_".
450

71
    if (lib && strcmp(lib, "SSL_") == 0)
451
6
      prefix = "";
452
453
    // All OpenSSL reason strings fit in a single 80-column macro definition,
454
    // all prefix lengths are <= 10, and ERR_OSSL_ is 9, so 128 is more than
455
    // sufficient.
456
    char code[128];
457
65
    snprintf(code, sizeof(code), "ERR_%s%s%s", prefix, lib, reason.c_str());
458
459
195
    if (obj->Set(env->isolate()->GetCurrentContext(),
460
             env->code_string(),
461
325
             OneByteString(env->isolate(), code)).IsNothing())
462
      return Nothing<bool>();
463
  }
464
465
65
  return Just(true);
466
}
467
}  // namespace error
468
469
78
void ThrowCryptoError(Environment* env,
470
                      unsigned long err,  // NOLINT(runtime/int)
471
                      // Default, only used if there is no SSL `err` which can
472
                      // be used to create a long-style message string.
473
                      const char* message) {
474
78
  char message_buffer[128] = {0};
475

78
  if (err != 0 || message == nullptr) {
476
67
    ERR_error_string_n(err, message_buffer, sizeof(message_buffer));
477
67
    message = message_buffer;
478
  }
479
154
  HandleScope scope(env->isolate());
480
  Local<String> exception_string;
481
  Local<Value> exception;
482
  Local<Object> obj;
483
156
  if (!String::NewFromUtf8(env->isolate(), message).ToLocal(&exception_string))
484
    return;
485
154
  CryptoErrorVector errors;
486
78
  errors.Capture();
487

389
  if (!errors.ToException(env, exception_string).ToLocal(&exception) ||
488

387
      !exception->ToObject(env->context()).ToLocal(&obj) ||
489
232
      error::Decorate(env, obj, err).IsNothing()) {
490
2
    return;
491
  }
492
76
  env->isolate()->ThrowException(exception);
493
}
494
495
#ifndef OPENSSL_NO_ENGINE
496
2
EnginePointer LoadEngineById(const char* id, CryptoErrorVector* errors) {
497
4
  MarkPopErrorOnReturn mark_pop_error_on_return;
498
499
2
  EnginePointer engine(ENGINE_by_id(id));
500
2
  if (!engine) {
501
    // Engine not found, try loading dynamically.
502
2
    engine = EnginePointer(ENGINE_by_id("dynamic"));
503
2
    if (engine) {
504

4
      if (!ENGINE_ctrl_cmd_string(engine.get(), "SO_PATH", id, 0) ||
505
2
          !ENGINE_ctrl_cmd_string(engine.get(), "LOAD", nullptr, 0)) {
506
2
        engine.reset();
507
      }
508
    }
509
  }
510
511

2
  if (!engine && errors != nullptr) {
512
    if (ERR_get_error() != 0) {
513
      errors->Capture();
514
    } else {
515
      errors->push_back(std::string("Engine \"") + id + "\" was not found");
516
    }
517
  }
518
519
4
  return engine;
520
}
521
522
2
bool SetEngine(const char* id, uint32_t flags, CryptoErrorVector* errors) {
523
2
  ClearErrorOnReturn clear_error_on_return;
524
4
  EnginePointer engine = LoadEngineById(id, errors);
525
2
  if (!engine)
526
2
    return false;
527
528
  if (!ENGINE_set_default(engine.get(), flags)) {
529
    if (errors != nullptr)
530
      errors->Capture();
531
    return false;
532
  }
533
534
  return true;
535
}
536
537
2
void SetEngine(const FunctionCallbackInfo<Value>& args) {
538
2
  Environment* env = Environment::GetCurrent(args);
539

8
  CHECK(args.Length() >= 2 && args[0]->IsString());
540
  uint32_t flags;
541
8
  if (!args[1]->Uint32Value(env->context()).To(&flags)) return;
542
543
4
  const node::Utf8Value engine_id(env->isolate(), args[0]);
544
545
6
  args.GetReturnValue().Set(SetEngine(*engine_id, flags));
546
}
547
#endif  // !OPENSSL_NO_ENGINE
548
549
933
MaybeLocal<Value> EncodeBignum(
550
    Environment* env,
551
    const BIGNUM* bn,
552
    int size,
553
    Local<Value>* error) {
554
1866
  std::vector<uint8_t> buf(size);
555
933
  CHECK_EQ(BN_bn2binpad(bn, buf.data(), size), size);
556
  return StringBytes::Encode(
557
      env->isolate(),
558
933
      reinterpret_cast<const char*>(buf.data()),
559
      buf.size(),
560
      BASE64URL,
561
2799
      error);
562
}
563
564
933
Maybe<bool> SetEncodedValue(
565
    Environment* env,
566
    Local<Object> target,
567
    Local<String> name,
568
    const BIGNUM* bn,
569
    int size) {
570
  Local<Value> value;
571
  Local<Value> error;
572
933
  CHECK_NOT_NULL(bn);
573
933
  if (size == 0)
574
760
    size = BN_num_bytes(bn);
575
1866
  if (!EncodeBignum(env, bn, size, &error).ToLocal(&value)) {
576
    if (!error.IsEmpty())
577
      env->isolate()->ThrowException(error);
578
    return Nothing<bool>();
579
  }
580
1866
  return target->Set(env->context(), name, value);
581
}
582
583
3471
CryptoJobMode GetCryptoJobMode(v8::Local<v8::Value> args) {
584
3471
  CHECK(args->IsUint32());
585
6942
  uint32_t mode = args.As<v8::Uint32>()->Value();
586
3471
  CHECK_LE(mode, kCryptoJobSync);
587
3471
  return static_cast<CryptoJobMode>(mode);
588
}
589
590
namespace Util {
591
653
void Initialize(Environment* env, Local<Object> target) {
592
#ifndef OPENSSL_NO_ENGINE
593
653
  env->SetMethod(target, "setEngine", SetEngine);
594
#endif  // !OPENSSL_NO_ENGINE
595
596
#ifdef NODE_FIPS_MODE
597
  env->SetMethodNoSideEffect(target, "getFipsCrypto", GetFipsCrypto);
598
  env->SetMethod(target, "setFipsCrypto", SetFipsCrypto);
599
#endif
600
601
2616
  NODE_DEFINE_CONSTANT(target, kCryptoJobAsync);
602
654
  NODE_DEFINE_CONSTANT(target, kCryptoJobSync);
603
1962
}
604
654
}  // namespace Util
605
3270
606
1308
}  // namespace crypto
607

14034
}  // namespace node