GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_util.cc Lines: 285 323 88.2 %
Date: 2021-09-20 04:12:42 Branches: 125 232 53.9 %

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
#if OPENSSL_VERSION_MAJOR >= 3
18
#include "openssl/provider.h"
19
#endif
20
21
#include <openssl/rand.h>
22
23
namespace node {
24
25
using v8::ArrayBuffer;
26
using v8::BackingStore;
27
using v8::BigInt;
28
using v8::Context;
29
using v8::Exception;
30
using v8::FunctionCallbackInfo;
31
using v8::HandleScope;
32
using v8::Isolate;
33
using v8::Just;
34
using v8::Local;
35
using v8::Maybe;
36
using v8::MaybeLocal;
37
using v8::NewStringType;
38
using v8::Nothing;
39
using v8::Object;
40
using v8::String;
41
using v8::Uint32;
42
using v8::Uint8Array;
43
using v8::Value;
44
45
namespace crypto {
46
2162
int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
47
  // From https://www.openssl.org/docs/man1.1.1/man3/SSL_verify_cb:
48
  //
49
  //   If VerifyCallback returns 1, the verification process is continued. If
50
  //   VerifyCallback always returns 1, the TLS/SSL handshake will not be
51
  //   terminated with respect to verification failures and the connection will
52
  //   be established. The calling process can however retrieve the error code
53
  //   of the last verification error using SSL_get_verify_result(3) or by
54
  //   maintaining its own error storage managed by VerifyCallback.
55
  //
56
  // Since we cannot perform I/O quickly enough with X509_STORE_CTX_ APIs in
57
  // this callback, we ignore all preverify_ok errors and let the handshake
58
  // continue. It is imperative that the user use Connection::VerifyError after
59
  // the 'secure' callback has been made.
60
2162
  return 1;
61
}
62
63
16644
void CheckEntropy() {
64
  for (;;) {
65
16644
    int status = RAND_status();
66
16644
    CHECK_GE(status, 0);  // Cannot fail.
67
16644
    if (status != 0)
68
16644
      break;
69
70
    // Give up, RAND_poll() not supported.
71
    if (RAND_poll() == 0)
72
      break;
73
  }
74
16644
}
75
76
15963
bool EntropySource(unsigned char* buffer, size_t length) {
77
  // Ensure that OpenSSL's PRNG is properly seeded.
78
15963
  CheckEntropy();
79
  // RAND_bytes() can return 0 to indicate that the entropy data is not truly
80
  // random. That's okay, it's still better than V8's stock source of entropy,
81
  // which is /dev/urandom on UNIX platforms and the current time on Windows.
82
15963
  return RAND_bytes(buffer, length) != -1;
83
}
84
85
103
int PasswordCallback(char* buf, int size, int rwflag, void* u) {
86
103
  const ByteSource* passphrase = *static_cast<const ByteSource**>(u);
87
103
  if (passphrase != nullptr) {
88
92
    size_t buflen = static_cast<size_t>(size);
89
92
    size_t len = passphrase->size();
90
92
    if (buflen < len)
91
1
      return -1;
92
91
    memcpy(buf, passphrase->get(), len);
93
91
    return len;
94
  }
95
96
11
  return -1;
97
}
98
99
// This callback is used to avoid the default passphrase callback in OpenSSL
100
// which will typically prompt for the passphrase. The prompting is designed
101
// for the OpenSSL CLI, but works poorly for Node.js because it involves
102
// synchronous interaction with the controlling terminal, something we never
103
// want, and use this function to avoid it.
104
int NoPasswordCallback(char* buf, int size, int rwflag, void* u) {
105
  return 0;
106
}
107
108
4867
bool ProcessFipsOptions() {
109
  /* Override FIPS settings in configuration file, if needed. */
110

9727
  if (per_process::cli_options->enable_fips_crypto ||
111
4860
      per_process::cli_options->force_fips_crypto) {
112
#if OPENSSL_VERSION_MAJOR >= 3
113
    OSSL_PROVIDER* fips_provider = OSSL_PROVIDER_load(nullptr, "fips");
114
    if (fips_provider == nullptr)
115
      return false;
116
    OSSL_PROVIDER_unload(fips_provider);
117
118
    return EVP_default_properties_enable_fips(nullptr, 1) &&
119
           EVP_default_properties_is_fips_enabled(nullptr);
120
#else
121

13
    return FIPS_mode() == 0 && FIPS_mode_set(1);
122
#endif
123
  }
124
4854
  return true;
125
}
126
127
4149
void InitCryptoOnce() {
128
#ifndef OPENSSL_IS_BORINGSSL
129
4149
  OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
130
131
#if OPENSSL_VERSION_MAJOR < 3
132
  // --openssl-config=...
133
4149
  if (!per_process::cli_options->openssl_config.empty()) {
134
5
    const char* conf = per_process::cli_options->openssl_config.c_str();
135
5
    OPENSSL_INIT_set_config_filename(settings, conf);
136
  }
137
#endif
138
139
4149
  OPENSSL_init_ssl(0, settings);
140
4149
  OPENSSL_INIT_free(settings);
141
4149
  settings = nullptr;
142
143
#ifndef _WIN32
144
4149
  if (per_process::cli_options->secure_heap != 0) {
145

1
    switch (CRYPTO_secure_malloc_init(
146
1
                per_process::cli_options->secure_heap,
147
1
                static_cast<int>(per_process::cli_options->secure_heap_min))) {
148
      case 0:
149
        fprintf(stderr, "Unable to initialize openssl secure heap.\n");
150
        break;
151
      case 2:
152
        // Not a fatal error but worthy of a warning.
153
        fprintf(stderr, "Unable to memory map openssl secure heap.\n");
154
        break;
155
1
      case 1:
156
        // OK!
157
1
        break;
158
    }
159
  }
160
#endif
161
162
#endif  // OPENSSL_IS_BORINGSSL
163
164
  // Turn off compression. Saves memory and protects against CRIME attacks.
165
  // No-op with OPENSSL_NO_COMP builds of OpenSSL.
166
4149
  sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
167
168
#ifndef OPENSSL_NO_ENGINE
169
4149
  ERR_load_ENGINE_strings();
170
4149
  ENGINE_load_builtin_engines();
171
#endif  // !OPENSSL_NO_ENGINE
172
173
4149
  NodeBIO::GetMethod();
174
4149
}
175
176
416
void GetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
177
#if OPENSSL_VERSION_MAJOR >= 3
178
  args.GetReturnValue().Set(EVP_default_properties_is_fips_enabled(nullptr) ?
179
      1 : 0);
180
#else
181
416
  args.GetReturnValue().Set(FIPS_mode() ? 1 : 0);
182
#endif
183
416
}
184
185
4
void SetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
186
4
  CHECK(!per_process::cli_options->force_fips_crypto);
187
4
  Environment* env = Environment::GetCurrent(args);
188
4
  bool enable = args[0]->BooleanValue(env->isolate());
189
190
#if OPENSSL_VERSION_MAJOR >= 3
191
  if (enable == EVP_default_properties_is_fips_enabled(nullptr))
192
#else
193
4
  if (static_cast<int>(enable) == FIPS_mode())
194
#endif
195
1
    return;  // No action needed.
196
197
#if OPENSSL_VERSION_MAJOR >= 3
198
  if (!EVP_default_properties_enable_fips(nullptr, enable)) {
199
#else
200
3
  if (!FIPS_mode_set(enable)) {
201
#endif
202
3
    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
203
3
    return ThrowCryptoError(env, err);
204
  }
205
}
206
207
33
void TestFipsCrypto(const v8::FunctionCallbackInfo<v8::Value>& args) {
208
#ifdef OPENSSL_FIPS
209
#if OPENSSL_VERSION_MAJOR >= 3
210
  OSSL_PROVIDER* fips_provider = nullptr;
211
  if (OSSL_PROVIDER_available(nullptr, "fips")) {
212
    fips_provider = OSSL_PROVIDER_load(nullptr, "fips");
213
  }
214
  const auto enabled = fips_provider == nullptr ? 0 :
215
      OSSL_PROVIDER_self_test(fips_provider) ? 1 : 0;
216
#else
217
  const auto enabled = FIPS_selftest() ? 1 : 0;
218
#endif
219
#else  // OPENSSL_FIPS
220
33
  const auto enabled = 0;
221
#endif  // OPENSSL_FIPS
222
223
33
  args.GetReturnValue().Set(enabled);
224
33
}
225
226
1506
void CryptoErrorStore::Capture() {
227
1506
  errors_.clear();
228
1582
  while (const uint32_t err = ERR_get_error()) {
229
    char buf[256];
230
76
    ERR_error_string_n(err, buf, sizeof(buf));
231
76
    errors_.emplace_back(buf);
232
76
  }
233
1506
  std::reverse(std::begin(errors_), std::end(errors_));
234
1506
}
235
236
6319
bool CryptoErrorStore::Empty() const {
237
6319
  return errors_.empty();
238
}
239
240
203
MaybeLocal<Value> CryptoErrorStore::ToException(
241
    Environment* env,
242
    Local<String> exception_string) const {
243
203
  if (exception_string.IsEmpty()) {
244
104
    CryptoErrorStore copy(*this);
245
52
    if (copy.Empty()) {
246
      // But possibly a bug...
247
      copy.Insert(NodeCryptoError::OK);
248
    }
249
    // Use last element as the error message, everything else goes
250
    // into the .opensslErrorStack property on the exception object.
251
52
    const std::string& last_error_string = copy.errors_.back();
252
    Local<String> exception_string;
253
52
    if (!String::NewFromUtf8(
254
            env->isolate(),
255
            last_error_string.data(),
256
            NewStringType::kNormal,
257
104
            last_error_string.size()).ToLocal(&exception_string)) {
258
      return MaybeLocal<Value>();
259
    }
260
52
    copy.errors_.pop_back();
261
52
    return copy.ToException(env, exception_string);
262
  }
263
264
151
  Local<Value> exception_v = Exception::Error(exception_string);
265
151
  CHECK(!exception_v.IsEmpty());
266
267
151
  if (!Empty()) {
268
25
    CHECK(exception_v->IsObject());
269
25
    Local<Object> exception = exception_v.As<Object>();
270
    Local<Value> stack;
271
75
    if (!ToV8Value(env->context(), errors_).ToLocal(&stack) ||
272
75
        exception->Set(env->context(), env->openssl_error_stack(), stack)
273
25
            .IsNothing()) {
274
1
      return MaybeLocal<Value>();
275
    }
276
  }
277
278
150
  return exception_v;
279
}
280
281
18774
ByteSource::ByteSource(ByteSource&& other) noexcept
282
18774
    : data_(other.data_),
283
18774
      allocated_data_(other.allocated_data_),
284
37548
      size_(other.size_) {
285
18774
  other.allocated_data_ = nullptr;
286
18774
}
287
288
127160
ByteSource::~ByteSource() {
289
63580
  OPENSSL_clear_free(allocated_data_, size_);
290
63580
}
291
292
void ByteSource::reset() {
293
  OPENSSL_clear_free(allocated_data_, size_);
294
  data_ = nullptr;
295
  size_ = 0;
296
}
297
298
12349
ByteSource& ByteSource::operator=(ByteSource&& other) noexcept {
299
12349
  if (&other != this) {
300
12349
    OPENSSL_clear_free(allocated_data_, size_);
301
12349
    data_ = other.data_;
302
12349
    allocated_data_ = other.allocated_data_;
303
12349
    other.allocated_data_ = nullptr;
304
12349
    size_ = other.size_;
305
  }
306
12349
  return *this;
307
}
308
309
3117
std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore() {
310
  // It's ok for allocated_data_ to be nullptr but
311
  // only if size_ is zero.
312

3117
  CHECK_IMPLIES(size_ > 0, allocated_data_ != nullptr);
313
  std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore(
314
3117
      allocated_data_,
315
      size(),
316
3114
      [](void* data, size_t length, void* deleter_data) {
317
3114
        OPENSSL_clear_free(deleter_data, length);
318
3117
      }, allocated_data_);
319
3117
  CHECK(ptr);
320
3117
  allocated_data_ = nullptr;
321
3117
  data_ = nullptr;
322
3117
  size_ = 0;
323
3117
  return ptr;
324
}
325
326
3117
Local<ArrayBuffer> ByteSource::ToArrayBuffer(Environment* env) {
327
3117
  std::unique_ptr<BackingStore> store = ReleaseToBackingStore();
328
3117
  return ArrayBuffer::New(env->isolate(), std::move(store));
329
}
330
331
20202
const char* ByteSource::get() const {
332
20202
  return data_;
333
}
334
335
26414
size_t ByteSource::size() const {
336
26414
  return size_;
337
}
338
339
503
ByteSource ByteSource::FromBIO(const BIOPointer& bio) {
340
503
  CHECK(bio);
341
  BUF_MEM* bptr;
342
503
  BIO_get_mem_ptr(bio.get(), &bptr);
343
503
  char* data = MallocOpenSSL<char>(bptr->length);
344
503
  memcpy(data, bptr->data, bptr->length);
345
503
  return Allocated(data, bptr->length);
346
}
347
348
3111
ByteSource ByteSource::FromEncodedString(Environment* env,
349
                                         Local<String> key,
350
                                         enum encoding enc) {
351
3111
  size_t length = 0;
352
3111
  size_t actual = 0;
353
3111
  char* data = nullptr;
354
355

6222
  if (StringBytes::Size(env->isolate(), key, enc).To(&length) && length > 0) {
356
3111
    data = MallocOpenSSL<char>(length);
357
3111
    actual = StringBytes::Write(env->isolate(), data, length, key, enc);
358
359
3111
    CHECK(actual <= length);
360
361
3111
    if (actual == 0) {
362
      OPENSSL_clear_free(data, length);
363
      data = nullptr;
364
3111
    } else if (actual < length) {
365
      data = reinterpret_cast<char*>(OPENSSL_realloc(data, actual));
366
    }
367
  }
368
369
3111
  return Allocated(data, actual);
370
}
371
372
2470
ByteSource ByteSource::FromStringOrBuffer(Environment* env,
373
                                          Local<Value> value) {
374
2470
  return IsAnyByteSource(value) ? FromBuffer(value)
375
2470
                                : FromString(env, value.As<String>());
376
}
377
378
24
ByteSource ByteSource::FromString(Environment* env, Local<String> str,
379
                                  bool ntc) {
380
48
  CHECK(str->IsString());
381
24
  size_t size = str->Utf8Length(env->isolate());
382
24
  size_t alloc_size = ntc ? size + 1 : size;
383
24
  char* data = MallocOpenSSL<char>(alloc_size);
384
24
  int opts = String::NO_OPTIONS;
385
24
  if (!ntc) opts |= String::NO_NULL_TERMINATION;
386
24
  str->WriteUtf8(env->isolate(), data, alloc_size, nullptr, opts);
387
24
  return Allocated(data, size);
388
}
389
390
2472
ByteSource ByteSource::FromBuffer(Local<Value> buffer, bool ntc) {
391
4944
  ArrayBufferOrViewContents<char> buf(buffer);
392
2472
  return ntc ? buf.ToNullTerminatedCopy() : buf.ToByteSource();
393
}
394
395
1348
ByteSource ByteSource::FromSecretKeyBytes(
396
    Environment* env,
397
    Local<Value> value) {
398
  // A key can be passed as a string, buffer or KeyObject with type 'secret'.
399
  // If it is a string, we need to convert it to a buffer. We are not doing that
400
  // in JS to avoid creating an unprotected copy on the heap.
401

2696
  return value->IsString() || IsAnyByteSource(value) ?
402
           ByteSource::FromStringOrBuffer(env, value) :
403
1348
           ByteSource::FromSymmetricKeyObjectHandle(value);
404
}
405
406
ByteSource ByteSource::NullTerminatedCopy(Environment* env,
407
                                          Local<Value> value) {
408
  return Buffer::HasInstance(value) ? FromBuffer(value, true)
409
                                    : FromString(env, value.As<String>(), true);
410
}
411
412
14
ByteSource ByteSource::FromSymmetricKeyObjectHandle(Local<Value> handle) {
413
14
  CHECK(handle->IsObject());
414
14
  KeyObjectHandle* key = Unwrap<KeyObjectHandle>(handle.As<Object>());
415
14
  CHECK_NOT_NULL(key);
416
14
  return Foreign(key->Data()->GetSymmetricKey(),
417
28
                 key->Data()->GetSymmetricKeySize());
418
}
419
420
22099
ByteSource::ByteSource(const char* data, char* allocated_data, size_t size)
421
    : data_(data),
422
      allocated_data_(allocated_data),
423
22099
      size_(size) {}
424
425
16990
ByteSource ByteSource::Allocated(char* data, size_t size) {
426
16990
  return ByteSource(data, data, size);
427
}
428
429
5109
ByteSource ByteSource::Foreign(const char* data, size_t size) {
430
5109
  return ByteSource(data, nullptr, size);
431
}
432
433
namespace error {
434
98
Maybe<bool> Decorate(Environment* env, Local<Object> obj,
435
              unsigned long err) {  // NOLINT(runtime/int)
436
98
  if (err == 0) return Just(true);  // No decoration necessary.
437
438
85
  const char* ls = ERR_lib_error_string(err);
439
85
  const char* fs = ERR_func_error_string(err);
440
85
  const char* rs = ERR_reason_error_string(err);
441
442
85
  Isolate* isolate = env->isolate();
443
85
  Local<Context> context = isolate->GetCurrentContext();
444
445
85
  if (ls != nullptr) {
446
170
    if (obj->Set(context, env->library_string(),
447
340
                 OneByteString(isolate, ls)).IsNothing()) {
448
1
      return Nothing<bool>();
449
    }
450
  }
451
84
  if (fs != nullptr) {
452
168
    if (obj->Set(context, env->function_string(),
453
336
                 OneByteString(isolate, fs)).IsNothing()) {
454
      return Nothing<bool>();
455
    }
456
  }
457
84
  if (rs != nullptr) {
458
168
    if (obj->Set(context, env->reason_string(),
459
336
                 OneByteString(isolate, rs)).IsNothing()) {
460
      return Nothing<bool>();
461
    }
462
463
    // SSL has no API to recover the error name from the number, so we
464
    // transform reason strings like "this error" to "ERR_SSL_THIS_ERROR",
465
    // which ends up being close to the original error macro name.
466
84
    std::string reason(rs);
467
468
1526
    for (auto& c : reason) {
469
1442
      if (c == ' ')
470
166
        c = '_';
471
      else
472
1276
        c = ToUpper(c);
473
    }
474
475
#define OSSL_ERROR_CODES_MAP(V)                                               \
476
    V(SYS)                                                                    \
477
    V(BN)                                                                     \
478
    V(RSA)                                                                    \
479
    V(DH)                                                                     \
480
    V(EVP)                                                                    \
481
    V(BUF)                                                                    \
482
    V(OBJ)                                                                    \
483
    V(PEM)                                                                    \
484
    V(DSA)                                                                    \
485
    V(X509)                                                                   \
486
    V(ASN1)                                                                   \
487
    V(CONF)                                                                   \
488
    V(CRYPTO)                                                                 \
489
    V(EC)                                                                     \
490
    V(SSL)                                                                    \
491
    V(BIO)                                                                    \
492
    V(PKCS7)                                                                  \
493
    V(X509V3)                                                                 \
494
    V(PKCS12)                                                                 \
495
    V(RAND)                                                                   \
496
    V(DSO)                                                                    \
497
    V(ENGINE)                                                                 \
498
    V(OCSP)                                                                   \
499
    V(UI)                                                                     \
500
    V(COMP)                                                                   \
501
    V(ECDSA)                                                                  \
502
    V(ECDH)                                                                   \
503
    V(OSSL_STORE)                                                             \
504
    V(FIPS)                                                                   \
505
    V(CMS)                                                                    \
506
    V(TS)                                                                     \
507
    V(HMAC)                                                                   \
508
    V(CT)                                                                     \
509
    V(ASYNC)                                                                  \
510
    V(KDF)                                                                    \
511
    V(SM2)                                                                    \
512
    V(USER)                                                                   \
513
514
#define V(name) case ERR_LIB_##name: lib = #name "_"; break;
515
84
    const char* lib = "";
516
84
    const char* prefix = "OSSL_";
517









84
    switch (ERR_GET_LIB(err)) { OSSL_ERROR_CODES_MAP(V) }
518
#undef V
519
#undef OSSL_ERROR_CODES_MAP
520
    // Don't generate codes like "ERR_OSSL_SSL_".
521

84
    if (lib && strcmp(lib, "SSL_") == 0)
522
6
      prefix = "";
523
524
    // All OpenSSL reason strings fit in a single 80-column macro definition,
525
    // all prefix lengths are <= 10, and ERR_OSSL_ is 9, so 128 is more than
526
    // sufficient.
527
    char code[128];
528
84
    snprintf(code, sizeof(code), "ERR_%s%s%s", prefix, lib, reason.c_str());
529
530
168
    if (obj->Set(env->isolate()->GetCurrentContext(),
531
             env->code_string(),
532
336
             OneByteString(env->isolate(), code)).IsNothing())
533
      return Nothing<bool>();
534
  }
535
536
84
  return Just(true);
537
}
538
}  // namespace error
539
540
99
void ThrowCryptoError(Environment* env,
541
                      unsigned long err,  // NOLINT(runtime/int)
542
                      // Default, only used if there is no SSL `err` which can
543
                      // be used to create a long-style message string.
544
                      const char* message) {
545
99
  char message_buffer[128] = {0};
546

99
  if (err != 0 || message == nullptr) {
547
86
    ERR_error_string_n(err, message_buffer, sizeof(message_buffer));
548
86
    message = message_buffer;
549
  }
550
99
  HandleScope scope(env->isolate());
551
  Local<String> exception_string;
552
  Local<Value> exception;
553
  Local<Object> obj;
554
198
  if (!String::NewFromUtf8(env->isolate(), message).ToLocal(&exception_string))
555
    return;
556
99
  CryptoErrorStore errors;
557
99
  errors.Capture();
558
99
  if (!errors.ToException(env, exception_string).ToLocal(&exception) ||
559

393
      !exception->ToObject(env->context()).ToLocal(&obj) ||
560

295
      error::Decorate(env, obj, err).IsNothing()) {
561
2
    return;
562
  }
563
97
  env->isolate()->ThrowException(exception);
564
}
565
566
#ifndef OPENSSL_NO_ENGINE
567
2
EnginePointer LoadEngineById(const char* id, CryptoErrorStore* errors) {
568
4
  MarkPopErrorOnReturn mark_pop_error_on_return;
569
570
2
  EnginePointer engine(ENGINE_by_id(id));
571
2
  if (!engine) {
572
    // Engine not found, try loading dynamically.
573
2
    engine = EnginePointer(ENGINE_by_id("dynamic"));
574
2
    if (engine) {
575

4
      if (!ENGINE_ctrl_cmd_string(engine.get(), "SO_PATH", id, 0) ||
576
2
          !ENGINE_ctrl_cmd_string(engine.get(), "LOAD", nullptr, 0)) {
577
2
        engine.reset();
578
      }
579
    }
580
  }
581
582

2
  if (!engine && errors != nullptr) {
583
    if (ERR_get_error() != 0) {
584
      errors->Capture();
585
    } else {
586
      errors->Insert(NodeCryptoError::ENGINE_NOT_FOUND, id);
587
    }
588
  }
589
590
2
  return engine;
591
}
592
593
2
bool SetEngine(const char* id, uint32_t flags, CryptoErrorStore* errors) {
594
2
  ClearErrorOnReturn clear_error_on_return;
595
4
  EnginePointer engine = LoadEngineById(id, errors);
596
2
  if (!engine)
597
2
    return false;
598
599
  if (!ENGINE_set_default(engine.get(), flags)) {
600
    if (errors != nullptr)
601
      errors->Capture();
602
    return false;
603
  }
604
605
  return true;
606
}
607
608
2
void SetEngine(const FunctionCallbackInfo<Value>& args) {
609
2
  Environment* env = Environment::GetCurrent(args);
610

6
  CHECK(args.Length() >= 2 && args[0]->IsString());
611
  uint32_t flags;
612
4
  if (!args[1]->Uint32Value(env->context()).To(&flags)) return;
613
614
2
  const node::Utf8Value engine_id(env->isolate(), args[0]);
615
616
4
  args.GetReturnValue().Set(SetEngine(*engine_id, flags));
617
}
618
#endif  // !OPENSSL_NO_ENGINE
619
620
2603
MaybeLocal<Value> EncodeBignum(
621
    Environment* env,
622
    const BIGNUM* bn,
623
    int size,
624
    Local<Value>* error) {
625
5206
  std::vector<uint8_t> buf(size);
626
2603
  CHECK_EQ(BN_bn2binpad(bn, buf.data(), size), size);
627
  return StringBytes::Encode(
628
      env->isolate(),
629
2603
      reinterpret_cast<const char*>(buf.data()),
630
      buf.size(),
631
      BASE64URL,
632
5206
      error);
633
}
634
635
2603
Maybe<bool> SetEncodedValue(
636
    Environment* env,
637
    Local<Object> target,
638
    Local<String> name,
639
    const BIGNUM* bn,
640
    int size) {
641
  Local<Value> value;
642
  Local<Value> error;
643
2603
  CHECK_NOT_NULL(bn);
644
2603
  if (size == 0)
645
2094
    size = BN_num_bytes(bn);
646
5206
  if (!EncodeBignum(env, bn, size, &error).ToLocal(&value)) {
647
    if (!error.IsEmpty())
648
      env->isolate()->ThrowException(error);
649
    return Nothing<bool>();
650
  }
651
2603
  return target->Set(env->context(), name, value);
652
}
653
654
5196
CryptoJobMode GetCryptoJobMode(v8::Local<v8::Value> args) {
655
5196
  CHECK(args->IsUint32());
656
5196
  uint32_t mode = args.As<v8::Uint32>()->Value();
657
5196
  CHECK_LE(mode, kCryptoJobSync);
658
5196
  return static_cast<CryptoJobMode>(mode);
659
}
660
661
namespace {
662
// SecureBuffer uses openssl to allocate a Uint8Array using
663
// OPENSSL_secure_malloc. Because we do not yet actually
664
// make use of secure heap, this has the same semantics as
665
// using OPENSSL_malloc. However, if the secure heap is
666
// initialized, SecureBuffer will automatically use it.
667
4
void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
668
4
  CHECK(args[0]->IsUint32());
669
4
  Environment* env = Environment::GetCurrent(args);
670
8
  uint32_t len = args[0].As<Uint32>()->Value();
671
4
  char* data = static_cast<char*>(OPENSSL_secure_malloc(len));
672
4
  if (data == nullptr) {
673
    // There's no memory available for the allocation.
674
    // Return nothing.
675
    return;
676
  }
677
4
  memset(data, 0, len);
678
  std::shared_ptr<BackingStore> store =
679
4
      ArrayBuffer::NewBackingStore(
680
          data,
681
          len,
682
4
          [](void* data, size_t len, void* deleter_data) {
683
4
            OPENSSL_secure_clear_free(data, len);
684
4
          },
685
4
          data);
686
4
  Local<ArrayBuffer> buffer = ArrayBuffer::New(env->isolate(), store);
687
8
  args.GetReturnValue().Set(Uint8Array::New(buffer, 0, len));
688
}
689
690
4
void SecureHeapUsed(const FunctionCallbackInfo<Value>& args) {
691
4
  Environment* env = Environment::GetCurrent(args);
692
4
  if (CRYPTO_secure_malloc_initialized())
693
8
    args.GetReturnValue().Set(
694
4
        BigInt::New(env->isolate(), CRYPTO_secure_used()));
695
4
}
696
}  // namespace
697
698
namespace Util {
699
4299
void Initialize(Environment* env, Local<Object> target) {
700
#ifndef OPENSSL_NO_ENGINE
701
4299
  env->SetMethod(target, "setEngine", SetEngine);
702
#endif  // !OPENSSL_NO_ENGINE
703
704
4299
  env->SetMethodNoSideEffect(target, "getFipsCrypto", GetFipsCrypto);
705
4299
  env->SetMethod(target, "setFipsCrypto", SetFipsCrypto);
706
4299
  env->SetMethodNoSideEffect(target, "testFipsCrypto", TestFipsCrypto);
707
708
12897
  NODE_DEFINE_CONSTANT(target, kCryptoJobAsync);
709
8598
  NODE_DEFINE_CONSTANT(target, kCryptoJobSync);
710
711
4299
  env->SetMethod(target, "secureBuffer", SecureBuffer);
712
4299
  env->SetMethod(target, "secureHeapUsed", SecureHeapUsed);
713
4299
}
714
}  // namespace Util
715
716
}  // namespace crypto
717
}  // namespace node