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_context.cc Lines: 587 680 86.3 %
Date: 2021-02-11 04:11:15 Branches: 336 533 63.0 %

Line Branch Exec Source
1
#include "crypto/crypto_context.h"
2
#include "crypto/crypto_bio.h"
3
#include "crypto/crypto_common.h"
4
#include "crypto/crypto_util.h"
5
#include "base_object-inl.h"
6
#include "env-inl.h"
7
#include "memory_tracker-inl.h"
8
#include "node.h"
9
#include "node_buffer.h"
10
#include "node_options.h"
11
#include "util.h"
12
#include "v8.h"
13
14
#include <openssl/x509.h>
15
#include <openssl/pkcs12.h>
16
#ifndef OPENSSL_NO_ENGINE
17
#include <openssl/engine.h>
18
#endif  // !OPENSSL_NO_ENGINE
19
20
namespace node {
21
22
using v8::Array;
23
using v8::ArrayBufferView;
24
using v8::Context;
25
using v8::DontDelete;
26
using v8::Exception;
27
using v8::External;
28
using v8::FunctionCallbackInfo;
29
using v8::FunctionTemplate;
30
using v8::HandleScope;
31
using v8::Int32;
32
using v8::Integer;
33
using v8::Local;
34
using v8::Object;
35
using v8::PropertyAttribute;
36
using v8::ReadOnly;
37
using v8::Signature;
38
using v8::String;
39
using v8::Value;
40
41
namespace crypto {
42
static const char* const root_certs[] = {
43
#include "node_root_certs.h"  // NOLINT(build/include_order)
44
};
45
46
static const char system_cert_path[] = NODE_OPENSSL_SYSTEM_CERT_PATH;
47
48
static X509_STORE* root_cert_store;
49
50
static bool extra_root_certs_loaded = false;
51
52
// Takes a string or buffer and loads it into a BIO.
53
// Caller responsible for BIO_free_all-ing the returned object.
54
2302
BIOPointer LoadBIO(Environment* env, Local<Value> v) {
55
4604
  HandleScope scope(env->isolate());
56
57
4604
  if (v->IsString()) {
58
2652
    Utf8Value s(env->isolate(), v);
59
1326
    return NodeBIO::NewFixed(*s, s.length());
60
  }
61
62
976
  if (v->IsArrayBufferView()) {
63
976
    ArrayBufferViewContents<char> buf(v.As<ArrayBufferView>());
64
976
    return NodeBIO::NewFixed(buf.data(), buf.length());
65
  }
66
67
  return nullptr;
68
}
69
70
namespace {
71
875
int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
72
                                  X509Pointer&& x,
73
                                  STACK_OF(X509)* extra_certs,
74
                                  X509Pointer* cert,
75
                                  X509Pointer* issuer_) {
76
875
  CHECK(!*issuer_);
77
875
  CHECK(!*cert);
78
875
  X509* issuer = nullptr;
79
80
875
  int ret = SSL_CTX_use_certificate(ctx, x.get());
81
82
875
  if (ret) {
83
    // If we could set up our certificate, now proceed to
84
    // the CA certificates.
85
875
    SSL_CTX_clear_extra_chain_certs(ctx);
86
87
1294
    for (int i = 0; i < sk_X509_num(extra_certs); i++) {
88
419
      X509* ca = sk_X509_value(extra_certs, i);
89
90
      // NOTE: Increments reference count on `ca`
91
419
      if (!SSL_CTX_add1_chain_cert(ctx, ca)) {
92
        ret = 0;
93
        issuer = nullptr;
94
        break;
95
      }
96
      // Note that we must not free r if it was successfully
97
      // added to the chain (while we must free the main
98
      // certificate, since its reference count is increased
99
      // by SSL_CTX_use_certificate).
100
101
      // Find issuer
102

419
      if (issuer != nullptr || X509_check_issued(ca, x.get()) != X509_V_OK)
103
4
        continue;
104
105
415
      issuer = ca;
106
    }
107
  }
108
109
  // Try getting issuer from a cert store
110
875
  if (ret) {
111
875
    if (issuer == nullptr) {
112
460
      ret = SSL_CTX_get_issuer(ctx, x.get(), &issuer);
113
460
      ret = ret < 0 ? 0 : 1;
114
      // NOTE: get_cert_store doesn't increment reference count,
115
      // no need to free `store`
116
    } else {
117
      // Increment issuer reference count
118
415
      issuer = X509_dup(issuer);
119
415
      if (issuer == nullptr) {
120
        ret = 0;
121
      }
122
    }
123
  }
124
125
875
  issuer_->reset(issuer);
126
127

875
  if (ret && x != nullptr) {
128
875
    cert->reset(X509_dup(x.get()));
129
875
    if (!*cert)
130
      ret = 0;
131
  }
132
875
  return ret;
133
}
134
135
// Read a file that contains our certificate in "PEM" format,
136
// possibly followed by a sequence of CA certificates that should be
137
// sent to the peer in the Certificate message.
138
//
139
// Taken from OpenSSL - edited for style.
140
863
int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
141
                                  BIOPointer&& in,
142
                                  X509Pointer* cert,
143
                                  X509Pointer* issuer) {
144
  // Just to ensure that `ERR_peek_last_error` below will return only errors
145
  // that we are interested in
146
863
  ERR_clear_error();
147
148
  X509Pointer x(
149
1726
      PEM_read_bio_X509_AUX(in.get(), nullptr, NoPasswordCallback, nullptr));
150
151
863
  if (!x)
152
    return 0;
153
154
863
  unsigned long err = 0;  // NOLINT(runtime/int)
155
156
1726
  StackOfX509 extra_certs(sk_X509_new_null());
157
863
  if (!extra_certs)
158
    return 0;
159
160
  while (X509Pointer extra {PEM_read_bio_X509(in.get(),
161
                                    nullptr,
162
                                    NoPasswordCallback,
163
1273
                                    nullptr)}) {
164
410
    if (sk_X509_push(extra_certs.get(), extra.get())) {
165
410
      extra.release();
166
410
      continue;
167
    }
168
169
    return 0;
170
410
  }
171
172
  // When the while loop ends, it's usually just EOF.
173
863
  err = ERR_peek_last_error();
174

1726
  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
175
863
      ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
176
863
    ERR_clear_error();
177
  } else {
178
    // some real error
179
    return 0;
180
  }
181
182
863
  return SSL_CTX_use_certificate_chain(ctx,
183
863
                                       std::move(x),
184
                                       extra_certs.get(),
185
                                       cert,
186
863
                                       issuer);
187
}
188
189
}  // namespace
190
191
266
X509_STORE* NewRootCertStore() {
192

266
  static std::vector<X509*> root_certs_vector;
193

266
  static Mutex root_certs_vector_mutex;
194
532
  Mutex::ScopedLock lock(root_certs_vector_mutex);
195
196

525
  if (root_certs_vector.empty() &&
197
259
      per_process::cli_options->ssl_openssl_cert_store == false) {
198
35862
    for (size_t i = 0; i < arraysize(root_certs); i++) {
199
      X509* x509 =
200
71208
          PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i],
201
35604
                                              strlen(root_certs[i])).get(),
202
                            nullptr,   // no re-use of X509 structure
203
                            NoPasswordCallback,
204
35604
                            nullptr);  // no callback data
205
206
      // Parse errors from the built-in roots are fatal.
207
35604
      CHECK_NOT_NULL(x509);
208
209
35604
      root_certs_vector.push_back(x509);
210
    }
211
  }
212
213
266
  X509_STORE* store = X509_STORE_new();
214
266
  if (*system_cert_path != '\0') {
215
    ERR_set_mark();
216
    X509_STORE_load_locations(store, system_cert_path, nullptr);
217
    ERR_pop_to_mark();
218
  }
219
220
532
  Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex);
221
266
  if (per_process::cli_options->ssl_openssl_cert_store) {
222
1
    X509_STORE_set_default_paths(store);
223
  } else {
224
36835
    for (X509* cert : root_certs_vector) {
225
36570
      X509_up_ref(cert);
226
36570
      X509_STORE_add_cert(store, cert);
227
    }
228
  }
229
230
532
  return store;
231
}
232
233
214
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
234
214
  Environment* env = Environment::GetCurrent(args);
235
29746
  Local<Value> result[arraysize(root_certs)];
236
237
29746
  for (size_t i = 0; i < arraysize(root_certs); i++) {
238
59064
    if (!String::NewFromOneByte(
239
            env->isolate(),
240
29532
            reinterpret_cast<const uint8_t*>(root_certs[i]))
241
59064
            .ToLocal(&result[i])) {
242
      return;
243
    }
244
  }
245
246
642
  args.GetReturnValue().Set(
247
      Array::New(env->isolate(), result, arraysize(root_certs)));
248
}
249
250
667
void SecureContext::Initialize(Environment* env, Local<Object> target) {
251
667
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
252
2001
  t->InstanceTemplate()->SetInternalFieldCount(
253
667
      SecureContext::kInternalFieldCount);
254
1334
  t->Inherit(BaseObject::GetConstructorTemplate(env));
255
256
667
  env->SetProtoMethod(t, "init", Init);
257
667
  env->SetProtoMethod(t, "setKey", SetKey);
258
#ifndef OPENSSL_NO_ENGINE
259
667
  env->SetProtoMethod(t, "setEngineKey", SetEngineKey);
260
#endif  // !OPENSSL_NO_ENGINE
261
667
  env->SetProtoMethod(t, "setCert", SetCert);
262
667
  env->SetProtoMethod(t, "addCACert", AddCACert);
263
667
  env->SetProtoMethod(t, "addCRL", AddCRL);
264
667
  env->SetProtoMethod(t, "addRootCerts", AddRootCerts);
265
667
  env->SetProtoMethod(t, "setCipherSuites", SetCipherSuites);
266
667
  env->SetProtoMethod(t, "setCiphers", SetCiphers);
267
667
  env->SetProtoMethod(t, "setSigalgs", SetSigalgs);
268
667
  env->SetProtoMethod(t, "setECDHCurve", SetECDHCurve);
269
667
  env->SetProtoMethod(t, "setDHParam", SetDHParam);
270
667
  env->SetProtoMethod(t, "setMaxProto", SetMaxProto);
271
667
  env->SetProtoMethod(t, "setMinProto", SetMinProto);
272
667
  env->SetProtoMethod(t, "getMaxProto", GetMaxProto);
273
667
  env->SetProtoMethod(t, "getMinProto", GetMinProto);
274
667
  env->SetProtoMethod(t, "setOptions", SetOptions);
275
667
  env->SetProtoMethod(t, "setSessionIdContext", SetSessionIdContext);
276
667
  env->SetProtoMethod(t, "setSessionTimeout", SetSessionTimeout);
277
667
  env->SetProtoMethod(t, "close", Close);
278
667
  env->SetProtoMethod(t, "loadPKCS12", LoadPKCS12);
279
#ifndef OPENSSL_NO_ENGINE
280
667
  env->SetProtoMethod(t, "setClientCertEngine", SetClientCertEngine);
281
#endif  // !OPENSSL_NO_ENGINE
282
667
  env->SetProtoMethodNoSideEffect(t, "getTicketKeys", GetTicketKeys);
283
667
  env->SetProtoMethod(t, "setTicketKeys", SetTicketKeys);
284
667
  env->SetProtoMethod(t, "setFreeListLength", SetFreeListLength);
285
667
  env->SetProtoMethod(t, "enableTicketKeyCallback", EnableTicketKeyCallback);
286
667
  env->SetProtoMethodNoSideEffect(t, "getCertificate", GetCertificate<true>);
287
667
  env->SetProtoMethodNoSideEffect(t, "getIssuer", GetCertificate<false>);
288
289
#define SET_INTEGER_CONSTANTS(name, value)                                     \
290
    t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), name),                        \
291
           Integer::NewFromUnsigned(env->isolate(), value));
292
2001
  SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex);
293
2001
  SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex);
294
2001
  SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex);
295
2001
  SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex);
296
2001
  SET_INTEGER_CONSTANTS("kTicketKeyIVIndex", kTicketKeyIVIndex);
297
298
#undef SET_INTEGER_CONSTANTS
299
300
  Local<FunctionTemplate> ctx_getter_templ =
301
      FunctionTemplate::New(env->isolate(),
302
                            CtxGetter,
303
                            Local<Value>(),
304
1334
                            Signature::New(env->isolate(), t));
305
306
307
2668
  t->PrototypeTemplate()->SetAccessorProperty(
308
      FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
309
      ctx_getter_templ,
310
      Local<FunctionTemplate>(),
311
667
      static_cast<PropertyAttribute>(ReadOnly | DontDelete));
312
313
667
  env->SetConstructorFunction(target, "SecureContext", t);
314
315
667
  env->set_secure_context_constructor_template(t);
316
317
  env->SetMethodNoSideEffect(target, "getRootCertificates",
318
667
                             GetRootCertificates);
319
  // Exposed for testing purposes only.
320
  env->SetMethodNoSideEffect(target, "isExtraRootCertsFileLoaded",
321
667
                             IsExtraRootCertsFileLoaded);
322
667
}
323
324
2333
SecureContext::SecureContext(Environment* env, Local<Object> wrap)
325
2333
    : BaseObject(env, wrap) {
326
2333
  MakeWeak();
327
2333
  env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
328
2333
}
329
330
3592
inline void SecureContext::Reset() {
331
3592
  if (ctx_ != nullptr) {
332
2261
    env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
333
  }
334
3592
  ctx_.reset();
335
3592
  cert_.reset();
336
3592
  issuer_.reset();
337
3592
}
338
339
6936
SecureContext::~SecureContext() {
340
2312
  Reset();
341
4624
}
342
343
2333
void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
344
2333
  Environment* env = Environment::GetCurrent(args);
345
2333
  new SecureContext(env, args.This());
346
2333
}
347
348
2331
void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
349
  SecureContext* sc;
350
2380
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
351
2331
  Environment* env = sc->env();
352
353
2331
  CHECK_EQ(args.Length(), 3);
354
4662
  CHECK(args[1]->IsInt32());
355
4662
  CHECK(args[2]->IsInt32());
356
357
6993
  int min_version = args[1].As<Int32>()->Value();
358
6993
  int max_version = args[2].As<Int32>()->Value();
359
2331
  const SSL_METHOD* method = TLS_method();
360
361
2331
  if (max_version == 0)
362
    max_version = kMaxSupportedVersion;
363
364
6993
  if (args[0]->IsString()) {
365
679
    Utf8Value sslmethod(env->isolate(), args[0]);
366
367
    // Note that SSLv2 and SSLv3 are disallowed but SSLv23_method and friends
368
    // are still accepted.  They are OpenSSL's way of saying that all known
369
    // protocols below TLS 1.3 are supported unless explicitly disabled (which
370
    // we do below for SSLv2 and SSLv3.)
371

1077
    if (sslmethod == "SSLv2_method" ||
372

712
        sslmethod == "SSLv2_server_method" ||
373
348
        sslmethod == "SSLv2_client_method") {
374
17
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled");
375
17
      return;
376

1026
    } else if (sslmethod == "SSLv3_method" ||
377

678
               sslmethod == "SSLv3_server_method" ||
378
331
               sslmethod == "SSLv3_client_method") {
379
17
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv3 methods disabled");
380
17
      return;
381
330
    } else if (sslmethod == "SSLv23_method") {
382
36
      max_version = TLS1_2_VERSION;
383
294
    } else if (sslmethod == "SSLv23_server_method") {
384
1
      max_version = TLS1_2_VERSION;
385
1
      method = TLS_server_method();
386
293
    } else if (sslmethod == "SSLv23_client_method") {
387
1
      max_version = TLS1_2_VERSION;
388
1
      method = TLS_client_method();
389
292
    } else if (sslmethod == "TLS_method") {
390
53
      min_version = 0;
391
53
      max_version = kMaxSupportedVersion;
392
239
    } else if (sslmethod == "TLS_server_method") {
393
      min_version = 0;
394
      max_version = kMaxSupportedVersion;
395
      method = TLS_server_method();
396
239
    } else if (sslmethod == "TLS_client_method") {
397
      min_version = 0;
398
      max_version = kMaxSupportedVersion;
399
      method = TLS_client_method();
400
239
    } else if (sslmethod == "TLSv1_method") {
401
71
      min_version = TLS1_VERSION;
402
71
      max_version = TLS1_VERSION;
403
168
    } else if (sslmethod == "TLSv1_server_method") {
404
1
      min_version = TLS1_VERSION;
405
1
      max_version = TLS1_VERSION;
406
1
      method = TLS_server_method();
407
167
    } else if (sslmethod == "TLSv1_client_method") {
408
1
      min_version = TLS1_VERSION;
409
1
      max_version = TLS1_VERSION;
410
1
      method = TLS_client_method();
411
166
    } else if (sslmethod == "TLSv1_1_method") {
412
71
      min_version = TLS1_1_VERSION;
413
71
      max_version = TLS1_1_VERSION;
414
95
    } else if (sslmethod == "TLSv1_1_server_method") {
415
1
      min_version = TLS1_1_VERSION;
416
1
      max_version = TLS1_1_VERSION;
417
1
      method = TLS_server_method();
418
94
    } else if (sslmethod == "TLSv1_1_client_method") {
419
1
      min_version = TLS1_1_VERSION;
420
1
      max_version = TLS1_1_VERSION;
421
1
      method = TLS_client_method();
422
93
    } else if (sslmethod == "TLSv1_2_method") {
423
75
      min_version = TLS1_2_VERSION;
424
75
      max_version = TLS1_2_VERSION;
425
18
    } else if (sslmethod == "TLSv1_2_server_method") {
426
2
      min_version = TLS1_2_VERSION;
427
2
      max_version = TLS1_2_VERSION;
428
2
      method = TLS_server_method();
429
16
    } else if (sslmethod == "TLSv1_2_client_method") {
430
1
      min_version = TLS1_2_VERSION;
431
1
      max_version = TLS1_2_VERSION;
432
1
      method = TLS_client_method();
433
    } else {
434
30
      const std::string msg("Unknown method: ");
435
15
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, (msg + * sslmethod).c_str());
436
15
      return;
437
    }
438
  }
439
440
2282
  sc->ctx_.reset(SSL_CTX_new(method));
441
2282
  SSL_CTX_set_app_data(sc->ctx_.get(), sc);
442
443
  // Disable SSLv2 in the case when method == TLS_method() and the
444
  // cipher list contains SSLv2 ciphers (not the default, should be rare.)
445
  // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
446
  // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
447
2282
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv2);
448
2282
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv3);
449
450
  // Enable automatic cert chaining. This is enabled by default in OpenSSL, but
451
  // disabled by default in BoringSSL. Enable it explicitly to make the
452
  // behavior match when Node is built with BoringSSL.
453
2282
  SSL_CTX_clear_mode(sc->ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
454
455
  // SSL session cache configuration
456
2282
  SSL_CTX_set_session_cache_mode(sc->ctx_.get(),
457
                                 SSL_SESS_CACHE_CLIENT |
458
                                 SSL_SESS_CACHE_SERVER |
459
                                 SSL_SESS_CACHE_NO_INTERNAL |
460
2282
                                 SSL_SESS_CACHE_NO_AUTO_CLEAR);
461
462
2282
  SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version);
463
2282
  SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
464
465
  // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
466
  // exposed in the public API. To retain compatibility, install a callback
467
  // which restores the old algorithm.
468

6846
  if (RAND_bytes(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) <= 0 ||
469

4564
      RAND_bytes(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)) <= 0 ||
470
2282
      RAND_bytes(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)) <= 0) {
471
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
472
        env, "Error generating ticket keys");
473
  }
474
2282
  SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
475
}
476
477
12219
SSLPointer SecureContext::CreateSSL() {
478
12219
  return SSLPointer(SSL_new(ctx_.get()));
479
}
480
481
12219
void SecureContext::SetNewSessionCallback(NewSessionCb cb) {
482
12219
  SSL_CTX_sess_set_new_cb(ctx_.get(), cb);
483
12219
}
484
485
12219
void SecureContext::SetGetSessionCallback(GetSessionCb cb) {
486
12219
  SSL_CTX_sess_set_get_cb(ctx_.get(), cb);
487
12219
}
488
489
861
void SecureContext::SetSelectSNIContextCallback(SelectSNIContextCb cb) {
490
861
  SSL_CTX_set_tlsext_servername_callback(ctx_.get(), cb);
491
861
}
492
493
8
void SecureContext::SetKeylogCallback(KeylogCb cb) {
494
8
  SSL_CTX_set_keylog_callback(ctx_.get(), cb);
495
8
}
496
497
845
void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
498
845
  Environment* env = Environment::GetCurrent(args);
499
500
  SecureContext* sc;
501
853
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
502
503
845
  CHECK_GE(args.Length(), 1);  // Private key argument is mandatory
504
505
1682
  BIOPointer bio(LoadBIO(env, args[0]));
506
845
  if (!bio)
507
    return;
508
509
1682
  ByteSource passphrase;
510
2535
  if (args[1]->IsString())
511
48
    passphrase = ByteSource::FromString(env, args[1].As<String>());
512
  // This redirection is necessary because the PasswordCallback expects a
513
  // pointer to a pointer to the passphrase ByteSource to allow passing in
514
  // const ByteSources.
515
845
  const ByteSource* pass_ptr = &passphrase;
516
517
  EVPKeyPointer key(
518
      PEM_read_bio_PrivateKey(bio.get(),
519
                              nullptr,
520
                              PasswordCallback,
521
1682
                              &pass_ptr));
522
523
845
  if (!key)
524
7
    return ThrowCryptoError(env, ERR_get_error(), "PEM_read_bio_PrivateKey");
525
526
838
  if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
527
1
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
528
}
529
530
8
void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) {
531
  SecureContext* sc;
532
8
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
533
8
  Environment* env = sc->env();
534
8
  ClearErrorOnReturn clear_error_on_return;
535
536
8
  CHECK_EQ(args.Length(), 1);
537
24
  CHECK(args[0]->IsString());
538
539
16
  const Utf8Value sigalgs(env->isolate(), args[0]);
540
541
8
  if (!SSL_CTX_set1_sigalgs_list(sc->ctx_.get(), *sigalgs))
542
    return ThrowCryptoError(env, ERR_get_error());
543
}
544
545
#ifndef OPENSSL_NO_ENGINE
546
void SecureContext::SetEngineKey(const FunctionCallbackInfo<Value>& args) {
547
  Environment* env = Environment::GetCurrent(args);
548
549
  SecureContext* sc;
550
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
551
552
  CHECK_EQ(args.Length(), 2);
553
554
  CryptoErrorVector errors;
555
  Utf8Value engine_id(env->isolate(), args[1]);
556
  EnginePointer engine = LoadEngineById(*engine_id, &errors);
557
  if (!engine) {
558
    Local<Value> exception;
559
    if (errors.ToException(env).ToLocal(&exception))
560
      env->isolate()->ThrowException(exception);
561
    return;
562
  }
563
564
  if (!ENGINE_init(engine.get())) {
565
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
566
        env, "Failure to initialize engine");
567
  }
568
569
  engine.finish_on_exit = true;
570
571
  Utf8Value key_name(env->isolate(), args[0]);
572
  EVPKeyPointer key(ENGINE_load_private_key(engine.get(), *key_name,
573
                                            nullptr, nullptr));
574
575
  if (!key)
576
    return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key");
577
578
  if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
579
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
580
581
  sc->private_key_engine_ = std::move(engine);
582
}
583
#endif  // !OPENSSL_NO_ENGINE
584
585
863
void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
586
863
  Environment* env = Environment::GetCurrent(args);
587
588
  SecureContext* sc;
589
863
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
590
591
863
  CHECK_GE(args.Length(), 1);  // Certificate argument is mandator
592
593
1726
  BIOPointer bio(LoadBIO(env, args[0]));
594
863
  if (!bio)
595
    return;
596
597
863
  sc->cert_.reset();
598
863
  sc->issuer_.reset();
599
600
2589
  if (!SSL_CTX_use_certificate_chain(
601
863
          sc->ctx_.get(),
602
863
          std::move(bio),
603
863
          &sc->cert_,
604
863
          &sc->issuer_)) {
605
    return ThrowCryptoError(
606
        env,
607
        ERR_get_error(),
608
        "SSL_CTX_use_certificate_chain");
609
  }
610
}
611
612
562
void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
613
562
  Environment* env = Environment::GetCurrent(args);
614
615
  SecureContext* sc;
616
562
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
617
562
  ClearErrorOnReturn clear_error_on_return;
618
619
562
  CHECK_GE(args.Length(), 1);  // CA certificate argument is mandatory
620
621
1124
  BIOPointer bio(LoadBIO(env, args[0]));
622
562
  if (!bio)
623
    return;
624
625
562
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
626
1466
  while (X509* x509 = PEM_read_bio_X509_AUX(
627
1466
      bio.get(), nullptr, NoPasswordCallback, nullptr)) {
628
904
    if (cert_store == root_cert_store) {
629
1
      cert_store = NewRootCertStore();
630
1
      SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
631
    }
632
904
    X509_STORE_add_cert(cert_store, x509);
633
904
    SSL_CTX_add_client_CA(sc->ctx_.get(), x509);
634
904
    X509_free(x509);
635
904
  }
636
}
637
638
2
void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
639
2
  Environment* env = Environment::GetCurrent(args);
640
641
  SecureContext* sc;
642
3
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
643
644
2
  CHECK_GE(args.Length(), 1);  // CRL argument is mandatory
645
646
1
  ClearErrorOnReturn clear_error_on_return;
647
648
3
  BIOPointer bio(LoadBIO(env, args[0]));
649
2
  if (!bio)
650
    return;
651
652
  DeleteFnPtr<X509_CRL, X509_CRL_free> crl(
653
3
      PEM_read_bio_X509_CRL(bio.get(), nullptr, NoPasswordCallback, nullptr));
654
655
2
  if (!crl)
656
1
    return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to parse CRL");
657
658
1
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
659
1
  if (cert_store == root_cert_store) {
660
    cert_store = NewRootCertStore();
661
    SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
662
  }
663
664
1
  X509_STORE_add_crl(cert_store, crl.get());
665
  X509_STORE_set_flags(cert_store,
666
1
                       X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
667
}
668
669
1740
void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
670
  SecureContext* sc;
671
1740
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
672
1740
  ClearErrorOnReturn clear_error_on_return;
673
674
1740
  if (root_cert_store == nullptr) {
675
254
    root_cert_store = NewRootCertStore();
676
  }
677
678
  // Increment reference count so global store is not deleted along with CTX.
679
1740
  X509_STORE_up_ref(root_cert_store);
680
1740
  SSL_CTX_set_cert_store(sc->ctx_.get(), root_cert_store);
681
}
682
683
2206
void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
684
  // BoringSSL doesn't allow API config of TLS1.3 cipher suites.
685
#ifndef OPENSSL_IS_BORINGSSL
686
  SecureContext* sc;
687
2207
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
688
2206
  Environment* env = sc->env();
689
2205
  ClearErrorOnReturn clear_error_on_return;
690
691
2206
  CHECK_EQ(args.Length(), 1);
692
6618
  CHECK(args[0]->IsString());
693
694
4411
  const Utf8Value ciphers(env->isolate(), args[0]);
695
2206
  if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers))
696
1
    return ThrowCryptoError(env, ERR_get_error(), "Failed to set ciphers");
697
#endif
698
}
699
700
2208
void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
701
  SecureContext* sc;
702
2223
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
703
2208
  Environment* env = sc->env();
704
2193
  ClearErrorOnReturn clear_error_on_return;
705
706
2208
  CHECK_EQ(args.Length(), 1);
707
6624
  CHECK(args[0]->IsString());
708
709
4401
  Utf8Value ciphers(env->isolate(), args[0]);
710
2208
  if (!SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) {
711
15
    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
712
713

15
    if (strlen(*ciphers) == 0 && ERR_GET_REASON(err) == SSL_R_NO_CIPHER_MATCH) {
714
      // TLS1.2 ciphers were deliberately cleared, so don't consider
715
      // SSL_R_NO_CIPHER_MATCH to be an error (this is how _set_cipher_suites()
716
      // works). If the user actually sets a value (like "no-such-cipher"), then
717
      // that's actually an error.
718
11
      return;
719
    }
720
4
    return ThrowCryptoError(env, err, "Failed to set ciphers");
721
  }
722
}
723
724
2200
void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
725
  SecureContext* sc;
726
2203
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
727
2200
  Environment* env = sc->env();
728
729
2200
  CHECK_GE(args.Length(), 1);  // ECDH curve name argument is mandatory
730
6600
  CHECK(args[0]->IsString());
731
732
4397
  Utf8Value curve(env->isolate(), args[0]);
733
734

2210
  if (strcmp(*curve, "auto") != 0 &&
735
10
      !SSL_CTX_set1_curves_list(sc->ctx_.get(), *curve)) {
736
3
    return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to set ECDH curve");
737
  }
738
}
739
740
10
void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
741
  SecureContext* sc;
742
13
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
743
10
  Environment* env = sc->env();
744
7
  ClearErrorOnReturn clear_error_on_return;
745
746
10
  CHECK_GE(args.Length(), 1);  // DH argument is mandatory
747
748
17
  DHPointer dh;
749
  {
750
20
    BIOPointer bio(LoadBIO(env, args[0]));
751
10
    if (!bio)
752
      return;
753
754
10
    dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr));
755
  }
756
757
  // Invalid dhparam is silently discarded and DHE is no longer used.
758
10
  if (!dh)
759
1
    return;
760
761
  const BIGNUM* p;
762
9
  DH_get0_pqg(dh.get(), &p, nullptr, nullptr);
763
9
  const int size = BN_num_bits(p);
764
9
  if (size < 1024) {
765
    return THROW_ERR_INVALID_ARG_VALUE(
766
2
        env, "DH parameter is less than 1024 bits");
767
7
  } else if (size < 2048) {
768
9
    args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(
769
        env->isolate(), "DH parameter is less than 2048 bits"));
770
  }
771
772
7
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_SINGLE_DH_USE);
773
774
7
  if (!SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get())) {
775
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
776
        env, "Error setting temp DH parameter");
777
  }
778
}
779
780
11
void SecureContext::SetMinProto(const FunctionCallbackInfo<Value>& args) {
781
  SecureContext* sc;
782
11
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
783
784
11
  CHECK_EQ(args.Length(), 1);
785
22
  CHECK(args[0]->IsInt32());
786
787
33
  int version = args[0].As<Int32>()->Value();
788
789
11
  CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), version));
790
}
791
792
48
void SecureContext::SetMaxProto(const FunctionCallbackInfo<Value>& args) {
793
  SecureContext* sc;
794
48
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
795
796
48
  CHECK_EQ(args.Length(), 1);
797
96
  CHECK(args[0]->IsInt32());
798
799
144
  int version = args[0].As<Int32>()->Value();
800
801
48
  CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), version));
802
}
803
804
59
void SecureContext::GetMinProto(const FunctionCallbackInfo<Value>& args) {
805
  SecureContext* sc;
806
59
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
807
808
59
  CHECK_EQ(args.Length(), 0);
809
810
  long version =  // NOLINT(runtime/int)
811
59
    SSL_CTX_get_min_proto_version(sc->ctx_.get());
812
177
  args.GetReturnValue().Set(static_cast<uint32_t>(version));
813
}
814
815
78
void SecureContext::GetMaxProto(const FunctionCallbackInfo<Value>& args) {
816
  SecureContext* sc;
817
78
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
818
819
78
  CHECK_EQ(args.Length(), 0);
820
821
  long version =  // NOLINT(runtime/int)
822
78
    SSL_CTX_get_max_proto_version(sc->ctx_.get());
823
234
  args.GetReturnValue().Set(static_cast<uint32_t>(version));
824
}
825
826
845
void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
827
845
  Environment* env = Environment::GetCurrent(args);
828
  SecureContext* sc;
829
845
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
830
831
845
  CHECK_GE(args.Length(), 1);
832
1690
  CHECK(args[0]->IsNumber());
833
834
3380
  int64_t val = args[0]->IntegerValue(env->context()).FromMaybe(0);
835
836
845
  SSL_CTX_set_options(sc->ctx_.get(),
837
845
                      static_cast<long>(val));  // NOLINT(runtime/int)
838
}
839
840
774
void SecureContext::SetSessionIdContext(
841
    const FunctionCallbackInfo<Value>& args) {
842
  SecureContext* sc;
843
1548
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
844
774
  Environment* env = sc->env();
845
846
774
  CHECK_GE(args.Length(), 1);
847
2322
  CHECK(args[0]->IsString());
848
849
774
  const Utf8Value sessionIdContext(env->isolate(), args[0]);
850
  const unsigned char* sid_ctx =
851
774
      reinterpret_cast<const unsigned char*>(*sessionIdContext);
852
774
  unsigned int sid_ctx_len = sessionIdContext.length();
853
854
774
  if (SSL_CTX_set_session_id_context(sc->ctx_.get(), sid_ctx, sid_ctx_len) == 1)
855
774
    return;
856
857
  BUF_MEM* mem;
858
  Local<String> message;
859
860
  BIOPointer bio(BIO_new(BIO_s_mem()));
861
  if (!bio) {
862
    message = FIXED_ONE_BYTE_STRING(env->isolate(),
863
                                    "SSL_CTX_set_session_id_context error");
864
  } else {
865
    ERR_print_errors(bio.get());
866
    BIO_get_mem_ptr(bio.get(), &mem);
867
    message = OneByteString(env->isolate(), mem->data, mem->length);
868
  }
869
870
  env->isolate()->ThrowException(Exception::TypeError(message));
871
}
872
873
1
void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
874
  SecureContext* sc;
875
1
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
876
877
1
  CHECK_GE(args.Length(), 1);
878
2
  CHECK(args[0]->IsInt32());
879
880
3
  int32_t sessionTimeout = args[0].As<Int32>()->Value();
881
1
  SSL_CTX_set_timeout(sc->ctx_.get(), sessionTimeout);
882
}
883
884
1280
void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
885
  SecureContext* sc;
886
1280
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
887
1280
  sc->Reset();
888
}
889
890
// Takes .pfx or .p12 and password in string or buffer format
891
18
void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
892
18
  Environment* env = Environment::GetCurrent(args);
893
894
30
  std::vector<char> pass;
895
18
  bool ret = false;
896
897
  SecureContext* sc;
898
18
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
899
12
  ClearErrorOnReturn clear_error_on_return;
900
901
18
  if (args.Length() < 1) {
902
    return THROW_ERR_MISSING_ARGS(env, "PFX certificate argument is mandatory");
903
  }
904
905
30
  BIOPointer in(LoadBIO(env, args[0]));
906
18
  if (!in) {
907
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
908
        env, "Unable to load PFX certificate");
909
  }
910
911
18
  if (args.Length() >= 2) {
912
15
    THROW_AND_RETURN_IF_NOT_BUFFER(env, args[1], "Pass phrase");
913
30
    Local<ArrayBufferView> abv = args[1].As<ArrayBufferView>();
914
15
    size_t passlen = abv->ByteLength();
915
15
    pass.resize(passlen + 1);
916
30
    abv->CopyContents(pass.data(), passlen);
917
15
    pass[passlen] = '\0';
918
  }
919
920
  // Free previous certs
921
18
  sc->issuer_.reset();
922
18
  sc->cert_.reset();
923
924
18
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
925
926
30
  DeleteFnPtr<PKCS12, PKCS12_free> p12;
927
30
  EVPKeyPointer pkey;
928
30
  X509Pointer cert;
929
30
  StackOfX509 extra_certs;
930
931
18
  PKCS12* p12_ptr = nullptr;
932
18
  EVP_PKEY* pkey_ptr = nullptr;
933
18
  X509* cert_ptr = nullptr;
934
18
  STACK_OF(X509)* extra_certs_ptr = nullptr;
935
36
  if (d2i_PKCS12_bio(in.get(), &p12_ptr) &&
936
32
      (p12.reset(p12_ptr), true) &&  // Move ownership to the smart pointer.
937
16
      PKCS12_parse(p12.get(), pass.data(),
938
                   &pkey_ptr,
939
                   &cert_ptr,
940
                   &extra_certs_ptr) &&
941
12
      (pkey.reset(pkey_ptr), cert.reset(cert_ptr),
942
24
       extra_certs.reset(extra_certs_ptr), true) &&  // Move ownership.
943
36
      SSL_CTX_use_certificate_chain(sc->ctx_.get(),
944
12
                                    std::move(cert),
945
                                    extra_certs.get(),
946
12
                                    &sc->cert_,
947

42
                                    &sc->issuer_) &&
948
12
      SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) {
949
    // Add CA certs too
950
21
    for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) {
951
9
      X509* ca = sk_X509_value(extra_certs.get(), i);
952
953
9
      if (cert_store == root_cert_store) {
954
6
        cert_store = NewRootCertStore();
955
6
        SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
956
      }
957
9
      X509_STORE_add_cert(cert_store, ca);
958
9
      SSL_CTX_add_client_CA(sc->ctx_.get(), ca);
959
    }
960
12
    ret = true;
961
  }
962
963
18
  if (!ret) {
964
    // TODO(@jasnell): Should this use ThrowCryptoError?
965
6
    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
966
6
    const char* str = ERR_reason_error_string(err);
967
6
    return env->ThrowError(str);
968
  }
969
}
970
971
#ifndef OPENSSL_NO_ENGINE
972
void SecureContext::SetClientCertEngine(
973
    const FunctionCallbackInfo<Value>& args) {
974
  Environment* env = Environment::GetCurrent(args);
975
  CHECK_EQ(args.Length(), 1);
976
  CHECK(args[0]->IsString());
977
978
  SecureContext* sc;
979
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
980
981
  MarkPopErrorOnReturn mark_pop_error_on_return;
982
983
  // SSL_CTX_set_client_cert_engine does not itself support multiple
984
  // calls by cleaning up before overwriting the client_cert_engine
985
  // internal context variable.
986
  // Instead of trying to fix up this problem we in turn also do not
987
  // support multiple calls to SetClientCertEngine.
988
  CHECK(!sc->client_cert_engine_provided_);
989
990
  CryptoErrorVector errors;
991
  const Utf8Value engine_id(env->isolate(), args[0]);
992
  EnginePointer engine = LoadEngineById(*engine_id, &errors);
993
  if (!engine) {
994
    Local<Value> exception;
995
    if (errors.ToException(env).ToLocal(&exception))
996
      env->isolate()->ThrowException(exception);
997
    return;
998
  }
999
1000
  // Note that this takes another reference to `engine`.
1001
  if (!SSL_CTX_set_client_cert_engine(sc->ctx_.get(), engine.get()))
1002
    return ThrowCryptoError(env, ERR_get_error());
1003
  sc->client_cert_engine_provided_ = true;
1004
}
1005
#endif  // !OPENSSL_NO_ENGINE
1006
1007
10
void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1008
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1009
1010
  SecureContext* wrap;
1011
10
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1012
1013
  Local<Object> buff;
1014
20
  if (!Buffer::New(wrap->env(), 48).ToLocal(&buff))
1015
    return;
1016
1017
10
  memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16);
1018
10
  memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16);
1019
10
  memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16);
1020
1021
20
  args.GetReturnValue().Set(buff);
1022
#endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1023
}
1024
1025
23
void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1026
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1027
  SecureContext* wrap;
1028
23
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1029
1030
23
  CHECK_GE(args.Length(), 1);  // Ticket keys argument is mandatory
1031
46
  CHECK(args[0]->IsArrayBufferView());
1032
46
  ArrayBufferViewContents<char> buf(args[0].As<ArrayBufferView>());
1033
1034
23
  CHECK_EQ(buf.length(), 48);
1035
1036
23
  memcpy(wrap->ticket_key_name_, buf.data(), 16);
1037
23
  memcpy(wrap->ticket_key_hmac_, buf.data() + 16, 16);
1038
23
  memcpy(wrap->ticket_key_aes_, buf.data() + 32, 16);
1039
1040
46
  args.GetReturnValue().Set(true);
1041
#endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1042
}
1043
1044
1307
void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
1045
1307
}
1046
1047
// Currently, EnableTicketKeyCallback and TicketKeyCallback are only present for
1048
// the regression test in test/parallel/test-https-resume-after-renew.js.
1049
1
void SecureContext::EnableTicketKeyCallback(
1050
    const FunctionCallbackInfo<Value>& args) {
1051
  SecureContext* wrap;
1052
1
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1053
1054
1
  SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback);
1055
}
1056
1057
3
int SecureContext::TicketKeyCallback(SSL* ssl,
1058
                                     unsigned char* name,
1059
                                     unsigned char* iv,
1060
                                     EVP_CIPHER_CTX* ectx,
1061
                                     HMAC_CTX* hctx,
1062
                                     int enc) {
1063
  static const int kTicketPartSize = 16;
1064
1065
  SecureContext* sc = static_cast<SecureContext*>(
1066
3
      SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1067
1068
3
  Environment* env = sc->env();
1069
6
  HandleScope handle_scope(env->isolate());
1070
3
  Context::Scope context_scope(env->context());
1071
1072
12
  Local<Value> argv[3];
1073
1074
12
  if (!Buffer::Copy(
1075
          env,
1076
          reinterpret_cast<char*>(name),
1077

9
          kTicketPartSize).ToLocal(&argv[0]) ||
1078
9
      !Buffer::Copy(
1079
          env,
1080
          reinterpret_cast<char*>(iv),
1081
3
          kTicketPartSize).ToLocal(&argv[1])) {
1082
    return -1;
1083
  }
1084
1085
6
  argv[2] = env != 0 ? v8::True(env->isolate()) : v8::False(env->isolate());
1086
1087
  Local<Value> ret;
1088
9
  if (!node::MakeCallback(
1089
          env->isolate(),
1090
          sc->object(),
1091
          env->ticketkeycallback_string(),
1092
3
          arraysize(argv),
1093
          argv,
1094

15
          {0, 0}).ToLocal(&ret) ||
1095
3
      !ret->IsArray()) {
1096
    return -1;
1097
  }
1098
3
  Local<Array> arr = ret.As<Array>();
1099
1100
  Local<Value> val;
1101

12
  if (!arr->Get(env->context(), kTicketKeyReturnIndex).ToLocal(&val) ||
1102
3
      !val->IsInt32()) {
1103
    return -1;
1104
  }
1105
1106
6
  int r = val.As<Int32>()->Value();
1107
3
  if (r < 0)
1108
    return r;
1109
1110
  Local<Value> hmac;
1111
  Local<Value> aes;
1112
1113

18
  if (!arr->Get(env->context(), kTicketKeyHMACIndex).ToLocal(&hmac) ||
1114

15
      !arr->Get(env->context(), kTicketKeyAESIndex).ToLocal(&aes) ||
1115
3
      Buffer::Length(aes) != kTicketPartSize) {
1116
    return -1;
1117
  }
1118
1119
3
  if (enc) {
1120
    Local<Value> name_val;
1121
    Local<Value> iv_val;
1122

12
    if (!arr->Get(env->context(), kTicketKeyNameIndex).ToLocal(&name_val) ||
1123
10
        !arr->Get(env->context(), kTicketKeyIVIndex).ToLocal(&iv_val) ||
1124

6
        Buffer::Length(name_val) != kTicketPartSize ||
1125
2
        Buffer::Length(iv_val) != kTicketPartSize) {
1126
      return -1;
1127
    }
1128
1129
4
    name_val.As<ArrayBufferView>()->CopyContents(name, kTicketPartSize);
1130
4
    iv_val.As<ArrayBufferView>()->CopyContents(iv, kTicketPartSize);
1131
  }
1132
1133
3
  ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
1134
6
  HMAC_Init_ex(hctx,
1135
3
               hmac_buf.data(),
1136
3
               hmac_buf.length(),
1137
               EVP_sha256(),
1138
3
               nullptr);
1139
1140
3
  ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
1141
3
  if (enc) {
1142
2
    EVP_EncryptInit_ex(ectx,
1143
                       EVP_aes_128_cbc(),
1144
                       nullptr,
1145
                       aes_key.data(),
1146
2
                       iv);
1147
  } else {
1148
1
    EVP_DecryptInit_ex(ectx,
1149
                       EVP_aes_128_cbc(),
1150
                       nullptr,
1151
                       aes_key.data(),
1152
1
                       iv);
1153
  }
1154
1155
3
  return r;
1156
}
1157
1158
1192
int SecureContext::TicketCompatibilityCallback(SSL* ssl,
1159
                                               unsigned char* name,
1160
                                               unsigned char* iv,
1161
                                               EVP_CIPHER_CTX* ectx,
1162
                                               HMAC_CTX* hctx,
1163
                                               int enc) {
1164
  SecureContext* sc = static_cast<SecureContext*>(
1165
1192
      SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1166
1167
1192
  if (enc) {
1168
1138
    memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
1169

3414
    if (RAND_bytes(iv, 16) <= 0 ||
1170
1138
        EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr,
1171

2276
                           sc->ticket_key_aes_, iv) <= 0 ||
1172
1138
        HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1173
                     EVP_sha256(), nullptr) <= 0) {
1174
      return -1;
1175
    }
1176
1138
    return 1;
1177
  }
1178
1179
54
  if (memcmp(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) != 0) {
1180
    // The ticket key name does not match. Discard the ticket.
1181
12
    return 0;
1182
  }
1183
1184
84
  if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
1185

84
                         iv) <= 0 ||
1186
42
      HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1187
                   EVP_sha256(), nullptr) <= 0) {
1188
    return -1;
1189
  }
1190
42
  return 1;
1191
}
1192
1193
2
void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
1194
  SecureContext* sc;
1195
2
  ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
1196
4
  Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get());
1197
4
  info.GetReturnValue().Set(ext);
1198
}
1199
1200
template <bool primary>
1201
6
void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1202
  SecureContext* wrap;
1203

6
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1204
6
  Environment* env = wrap->env();
1205
  X509* cert;
1206
1207
  if (primary)
1208
3
    cert = wrap->cert_.get();
1209
  else
1210
3
    cert = wrap->issuer_.get();
1211

6
  if (cert == nullptr)
1212
    return args.GetReturnValue().SetNull();
1213
1214
6
  int size = i2d_X509(cert, nullptr);
1215
  Local<Object> buff;
1216

12
  if (!Buffer::New(env, size).ToLocal(&buff))
1217
    return;
1218
  unsigned char* serialized = reinterpret_cast<unsigned char*>(
1219
6
      Buffer::Data(buff));
1220
6
  i2d_X509(cert, &serialized);
1221
1222
12
  args.GetReturnValue().Set(buff);
1223
}
1224
1225
namespace {
1226
4
unsigned long AddCertsFromFile(  // NOLINT(runtime/int)
1227
    X509_STORE* store,
1228
    const char* file) {
1229
4
  ERR_clear_error();
1230
8
  MarkPopErrorOnReturn mark_pop_error_on_return;
1231
1232
8
  BIOPointer bio(BIO_new_file(file, "r"));
1233
4
  if (!bio)
1234
1
    return ERR_get_error();
1235
1236
  while (X509* x509 =
1237
6
      PEM_read_bio_X509(bio.get(), nullptr, NoPasswordCallback, nullptr)) {
1238
3
    X509_STORE_add_cert(store, x509);
1239
3
    X509_free(x509);
1240
3
  }
1241
1242
3
  unsigned long err = ERR_peek_error();  // NOLINT(runtime/int)
1243
  // Ignore error if its EOF/no start line found.
1244

6
  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
1245
3
      ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
1246
3
    return 0;
1247
  }
1248
1249
  return err;
1250
}
1251
}  // namespace
1252
1253
// UseExtraCaCerts is called only once at the start of the Node.js process.
1254
4
void UseExtraCaCerts(const std::string& file) {
1255
4
  ClearErrorOnReturn clear_error_on_return;
1256
1257
4
  if (root_cert_store == nullptr) {
1258
4
    root_cert_store = NewRootCertStore();
1259
1260
4
    if (!file.empty()) {
1261
4
      unsigned long err = AddCertsFromFile(  // NOLINT(runtime/int)
1262
                                           root_cert_store,
1263
4
                                           file.c_str());
1264
4
      if (err) {
1265
1
        fprintf(stderr,
1266
                "Warning: Ignoring extra certs from `%s`, load failed: %s\n",
1267
                file.c_str(),
1268
1
                ERR_error_string(err, nullptr));
1269
      } else {
1270
3
        extra_root_certs_loaded = true;
1271
      }
1272
    }
1273
  }
1274
4
}
1275
1276
// Exposed to JavaScript strictly for testing purposes.
1277
3
void IsExtraRootCertsFileLoaded(
1278
    const FunctionCallbackInfo<Value>& args) {
1279
9
  return args.GetReturnValue().Set(extra_root_certs_loaded);
1280
}
1281
1282
}  // namespace crypto
1283

14097
}  // namespace node