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: 588 693 84.8 %
Date: 2021-04-22 04:13:51 Branches: 336 537 62.6 %

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
2314
BIOPointer LoadBIO(Environment* env, Local<Value> v) {
55
4628
  HandleScope scope(env->isolate());
56
57
4628
  if (v->IsString()) {
58
2652
    Utf8Value s(env->isolate(), v);
59
1326
    return NodeBIO::NewFixed(*s, s.length());
60
  }
61
62
988
  if (v->IsArrayBufferView()) {
63
988
    ArrayBufferViewContents<char> buf(v.As<ArrayBufferView>());
64
988
    return NodeBIO::NewFixed(buf.data(), buf.length());
65
  }
66
67
  return nullptr;
68
}
69
70
namespace {
71
880
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
880
  CHECK(!*issuer_);
77
880
  CHECK(!*cert);
78
880
  X509* issuer = nullptr;
79
80
880
  int ret = SSL_CTX_use_certificate(ctx, x.get());
81
82
880
  if (ret) {
83
    // If we could set up our certificate, now proceed to
84
    // the CA certificates.
85
880
    SSL_CTX_clear_extra_chain_certs(ctx);
86
87
1299
    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
880
  if (ret) {
111
880
    if (issuer == nullptr) {
112
465
      ret = SSL_CTX_get_issuer(ctx, x.get(), &issuer);
113
465
      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
880
  issuer_->reset(issuer);
126
127

880
  if (ret && x != nullptr) {
128
880
    cert->reset(X509_dup(x.get()));
129
880
    if (!*cert)
130
      ret = 0;
131
  }
132
880
  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
868
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
868
  ERR_clear_error();
147
148
  X509Pointer x(
149
1736
      PEM_read_bio_X509_AUX(in.get(), nullptr, NoPasswordCallback, nullptr));
150
151
868
  if (!x)
152
    return 0;
153
154
868
  unsigned long err = 0;  // NOLINT(runtime/int)
155
156
1736
  StackOfX509 extra_certs(sk_X509_new_null());
157
868
  if (!extra_certs)
158
    return 0;
159
160
  while (X509Pointer extra {PEM_read_bio_X509(in.get(),
161
                                    nullptr,
162
                                    NoPasswordCallback,
163
1278
                                    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
868
  err = ERR_peek_last_error();
174

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

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

270
  static Mutex root_certs_vector_mutex;
194
540
  Mutex::ScopedLock lock(root_certs_vector_mutex);
195
196

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

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

712
        sslmethod == "SSLv2_server_method" ||
401
348
        sslmethod == "SSLv2_client_method") {
402
17
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled");
403
17
      return;
404

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

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

6924
  if (RAND_bytes(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) <= 0 ||
497

4616
      RAND_bytes(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)) <= 0 ||
498
2308
      RAND_bytes(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)) <= 0) {
499
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
500
        env, "Error generating ticket keys");
501
  }
502
2308
  SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
503
}
504
505
12244
SSLPointer SecureContext::CreateSSL() {
506
12244
  return SSLPointer(SSL_new(ctx_.get()));
507
}
508
509
12244
void SecureContext::SetNewSessionCallback(NewSessionCb cb) {
510
12244
  SSL_CTX_sess_set_new_cb(ctx_.get(), cb);
511
12244
}
512
513
12244
void SecureContext::SetGetSessionCallback(GetSessionCb cb) {
514
12244
  SSL_CTX_sess_set_get_cb(ctx_.get(), cb);
515
12244
}
516
517
866
void SecureContext::SetSelectSNIContextCallback(SelectSNIContextCb cb) {
518
866
  SSL_CTX_set_tlsext_servername_callback(ctx_.get(), cb);
519
866
}
520
521
8
void SecureContext::SetKeylogCallback(KeylogCb cb) {
522
8
  SSL_CTX_set_keylog_callback(ctx_.get(), cb);
523
8
}
524
525
850
void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
526
850
  Environment* env = Environment::GetCurrent(args);
527
528
  SecureContext* sc;
529
858
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
530
531
850
  CHECK_GE(args.Length(), 1);  // Private key argument is mandatory
532
533
1692
  BIOPointer bio(LoadBIO(env, args[0]));
534
850
  if (!bio)
535
    return;
536
537
1692
  ByteSource passphrase;
538
2550
  if (args[1]->IsString())
539
48
    passphrase = ByteSource::FromString(env, args[1].As<String>());
540
  // This redirection is necessary because the PasswordCallback expects a
541
  // pointer to a pointer to the passphrase ByteSource to allow passing in
542
  // const ByteSources.
543
850
  const ByteSource* pass_ptr = &passphrase;
544
545
  EVPKeyPointer key(
546
      PEM_read_bio_PrivateKey(bio.get(),
547
                              nullptr,
548
                              PasswordCallback,
549
1692
                              &pass_ptr));
550
551
850
  if (!key)
552
7
    return ThrowCryptoError(env, ERR_get_error(), "PEM_read_bio_PrivateKey");
553
554
843
  if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
555
1
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
556
}
557
558
8
void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) {
559
  SecureContext* sc;
560
8
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
561
8
  Environment* env = sc->env();
562
8
  ClearErrorOnReturn clear_error_on_return;
563
564
8
  CHECK_EQ(args.Length(), 1);
565
24
  CHECK(args[0]->IsString());
566
567
16
  const Utf8Value sigalgs(env->isolate(), args[0]);
568
569
8
  if (!SSL_CTX_set1_sigalgs_list(sc->ctx_.get(), *sigalgs))
570
    return ThrowCryptoError(env, ERR_get_error());
571
}
572
573
#ifndef OPENSSL_NO_ENGINE
574
void SecureContext::SetEngineKey(const FunctionCallbackInfo<Value>& args) {
575
  Environment* env = Environment::GetCurrent(args);
576
577
  SecureContext* sc;
578
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
579
580
  CHECK_EQ(args.Length(), 2);
581
582
  CryptoErrorStore errors;
583
  Utf8Value engine_id(env->isolate(), args[1]);
584
  EnginePointer engine = LoadEngineById(*engine_id, &errors);
585
  if (!engine) {
586
    Local<Value> exception;
587
    if (errors.ToException(env).ToLocal(&exception))
588
      env->isolate()->ThrowException(exception);
589
    return;
590
  }
591
592
  if (!ENGINE_init(engine.get())) {
593
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
594
        env, "Failure to initialize engine");
595
  }
596
597
  engine.finish_on_exit = true;
598
599
  Utf8Value key_name(env->isolate(), args[0]);
600
  EVPKeyPointer key(ENGINE_load_private_key(engine.get(), *key_name,
601
                                            nullptr, nullptr));
602
603
  if (!key)
604
    return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key");
605
606
  if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
607
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
608
609
  sc->private_key_engine_ = std::move(engine);
610
}
611
#endif  // !OPENSSL_NO_ENGINE
612
613
868
void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
614
868
  Environment* env = Environment::GetCurrent(args);
615
616
  SecureContext* sc;
617
868
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
618
619
868
  CHECK_GE(args.Length(), 1);  // Certificate argument is mandator
620
621
1736
  BIOPointer bio(LoadBIO(env, args[0]));
622
868
  if (!bio)
623
    return;
624
625
868
  sc->cert_.reset();
626
868
  sc->issuer_.reset();
627
628
2604
  if (!SSL_CTX_use_certificate_chain(
629
868
          sc->ctx_.get(),
630
868
          std::move(bio),
631
868
          &sc->cert_,
632
868
          &sc->issuer_)) {
633
    return ThrowCryptoError(
634
        env,
635
        ERR_get_error(),
636
        "SSL_CTX_use_certificate_chain");
637
  }
638
}
639
640
564
void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
641
564
  Environment* env = Environment::GetCurrent(args);
642
643
  SecureContext* sc;
644
564
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
645
564
  ClearErrorOnReturn clear_error_on_return;
646
647
564
  CHECK_GE(args.Length(), 1);  // CA certificate argument is mandatory
648
649
1128
  BIOPointer bio(LoadBIO(env, args[0]));
650
564
  if (!bio)
651
    return;
652
653
564
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
654
1470
  while (X509* x509 = PEM_read_bio_X509_AUX(
655
1470
      bio.get(), nullptr, NoPasswordCallback, nullptr)) {
656
906
    if (cert_store == root_cert_store) {
657
1
      cert_store = NewRootCertStore();
658
1
      SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
659
    }
660
906
    X509_STORE_add_cert(cert_store, x509);
661
906
    SSL_CTX_add_client_CA(sc->ctx_.get(), x509);
662
906
    X509_free(x509);
663
906
  }
664
}
665
666
2
void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
667
2
  Environment* env = Environment::GetCurrent(args);
668
669
  SecureContext* sc;
670
3
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
671
672
2
  CHECK_GE(args.Length(), 1);  // CRL argument is mandatory
673
674
1
  ClearErrorOnReturn clear_error_on_return;
675
676
3
  BIOPointer bio(LoadBIO(env, args[0]));
677
2
  if (!bio)
678
    return;
679
680
  DeleteFnPtr<X509_CRL, X509_CRL_free> crl(
681
3
      PEM_read_bio_X509_CRL(bio.get(), nullptr, NoPasswordCallback, nullptr));
682
683
2
  if (!crl)
684
1
    return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to parse CRL");
685
686
1
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
687
1
  if (cert_store == root_cert_store) {
688
    cert_store = NewRootCertStore();
689
    SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
690
  }
691
692
1
  X509_STORE_add_crl(cert_store, crl.get());
693
  X509_STORE_set_flags(cert_store,
694
1
                       X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
695
}
696
697
1764
void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
698
  SecureContext* sc;
699
1764
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
700
1764
  ClearErrorOnReturn clear_error_on_return;
701
702
1764
  if (root_cert_store == nullptr) {
703
258
    root_cert_store = NewRootCertStore();
704
  }
705
706
  // Increment reference count so global store is not deleted along with CTX.
707
1764
  X509_STORE_up_ref(root_cert_store);
708
1764
  SSL_CTX_set_cert_store(sc->ctx_.get(), root_cert_store);
709
}
710
711
2232
void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
712
  // BoringSSL doesn't allow API config of TLS1.3 cipher suites.
713
#ifndef OPENSSL_IS_BORINGSSL
714
  SecureContext* sc;
715
2233
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
716
2232
  Environment* env = sc->env();
717
2231
  ClearErrorOnReturn clear_error_on_return;
718
719
2232
  CHECK_EQ(args.Length(), 1);
720
6696
  CHECK(args[0]->IsString());
721
722
4463
  const Utf8Value ciphers(env->isolate(), args[0]);
723
2232
  if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers))
724
1
    return ThrowCryptoError(env, ERR_get_error(), "Failed to set ciphers");
725
#endif
726
}
727
728
2234
void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
729
  SecureContext* sc;
730
2249
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
731
2234
  Environment* env = sc->env();
732
2219
  ClearErrorOnReturn clear_error_on_return;
733
734
2234
  CHECK_EQ(args.Length(), 1);
735
6702
  CHECK(args[0]->IsString());
736
737
4453
  Utf8Value ciphers(env->isolate(), args[0]);
738
2234
  if (!SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) {
739
15
    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
740
741

15
    if (strlen(*ciphers) == 0 && ERR_GET_REASON(err) == SSL_R_NO_CIPHER_MATCH) {
742
      // TLS1.2 ciphers were deliberately cleared, so don't consider
743
      // SSL_R_NO_CIPHER_MATCH to be an error (this is how _set_cipher_suites()
744
      // works). If the user actually sets a value (like "no-such-cipher"), then
745
      // that's actually an error.
746
11
      return;
747
    }
748
4
    return ThrowCryptoError(env, err, "Failed to set ciphers");
749
  }
750
}
751
752
2226
void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
753
  SecureContext* sc;
754
2229
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
755
2226
  Environment* env = sc->env();
756
757
2226
  CHECK_GE(args.Length(), 1);  // ECDH curve name argument is mandatory
758
6678
  CHECK(args[0]->IsString());
759
760
4449
  Utf8Value curve(env->isolate(), args[0]);
761
762

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

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

9
          kTicketPartSize).ToLocal(&argv[0]) ||
1106
9
      !Buffer::Copy(
1107
          env,
1108
          reinterpret_cast<char*>(iv),
1109
3
          kTicketPartSize).ToLocal(&argv[1])) {
1110
    return -1;
1111
  }
1112
1113
6
  argv[2] = env != 0 ? v8::True(env->isolate()) : v8::False(env->isolate());
1114
1115
  Local<Value> ret;
1116
9
  if (!node::MakeCallback(
1117
          env->isolate(),
1118
          sc->object(),
1119
          env->ticketkeycallback_string(),
1120
3
          arraysize(argv),
1121
          argv,
1122

15
          {0, 0}).ToLocal(&ret) ||
1123
3
      !ret->IsArray()) {
1124
    return -1;
1125
  }
1126
3
  Local<Array> arr = ret.As<Array>();
1127
1128
  Local<Value> val;
1129

12
  if (!arr->Get(env->context(), kTicketKeyReturnIndex).ToLocal(&val) ||
1130
3
      !val->IsInt32()) {
1131
    return -1;
1132
  }
1133
1134
6
  int r = val.As<Int32>()->Value();
1135
3
  if (r < 0)
1136
    return r;
1137
1138
  Local<Value> hmac;
1139
  Local<Value> aes;
1140
1141

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

15
      !arr->Get(env->context(), kTicketKeyAESIndex).ToLocal(&aes) ||
1143
3
      Buffer::Length(aes) != kTicketPartSize) {
1144
    return -1;
1145
  }
1146
1147
3
  if (enc) {
1148
    Local<Value> name_val;
1149
    Local<Value> iv_val;
1150

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

6
        Buffer::Length(name_val) != kTicketPartSize ||
1153
2
        Buffer::Length(iv_val) != kTicketPartSize) {
1154
      return -1;
1155
    }
1156
1157
4
    name_val.As<ArrayBufferView>()->CopyContents(name, kTicketPartSize);
1158
4
    iv_val.As<ArrayBufferView>()->CopyContents(iv, kTicketPartSize);
1159
  }
1160
1161
3
  ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
1162
6
  HMAC_Init_ex(hctx,
1163
3
               hmac_buf.data(),
1164
3
               hmac_buf.length(),
1165
               EVP_sha256(),
1166
3
               nullptr);
1167
1168
3
  ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
1169
3
  if (enc) {
1170
2
    EVP_EncryptInit_ex(ectx,
1171
                       EVP_aes_128_cbc(),
1172
                       nullptr,
1173
                       aes_key.data(),
1174
2
                       iv);
1175
  } else {
1176
1
    EVP_DecryptInit_ex(ectx,
1177
                       EVP_aes_128_cbc(),
1178
                       nullptr,
1179
                       aes_key.data(),
1180
1
                       iv);
1181
  }
1182
1183
3
  return r;
1184
}
1185
1186
1190
int SecureContext::TicketCompatibilityCallback(SSL* ssl,
1187
                                               unsigned char* name,
1188
                                               unsigned char* iv,
1189
                                               EVP_CIPHER_CTX* ectx,
1190
                                               HMAC_CTX* hctx,
1191
                                               int enc) {
1192
  SecureContext* sc = static_cast<SecureContext*>(
1193
1190
      SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1194
1195
1190
  if (enc) {
1196
1136
    memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
1197

3408
    if (RAND_bytes(iv, 16) <= 0 ||
1198
1136
        EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr,
1199

2272
                           sc->ticket_key_aes_, iv) <= 0 ||
1200
1136
        HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1201
                     EVP_sha256(), nullptr) <= 0) {
1202
      return -1;
1203
    }
1204
1136
    return 1;
1205
  }
1206
1207
54
  if (memcmp(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) != 0) {
1208
    // The ticket key name does not match. Discard the ticket.
1209
12
    return 0;
1210
  }
1211
1212
84
  if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
1213

84
                         iv) <= 0 ||
1214
42
      HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1215
                   EVP_sha256(), nullptr) <= 0) {
1216
    return -1;
1217
  }
1218
42
  return 1;
1219
}
1220
1221
2
void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
1222
  SecureContext* sc;
1223
2
  ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
1224
4
  Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get());
1225
4
  info.GetReturnValue().Set(ext);
1226
}
1227
1228
template <bool primary>
1229
6
void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1230
  SecureContext* wrap;
1231

6
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1232
6
  Environment* env = wrap->env();
1233
  X509* cert;
1234
1235
  if (primary)
1236
3
    cert = wrap->cert_.get();
1237
  else
1238
3
    cert = wrap->issuer_.get();
1239

6
  if (cert == nullptr)
1240
    return args.GetReturnValue().SetNull();
1241
1242
6
  int size = i2d_X509(cert, nullptr);
1243
  Local<Object> buff;
1244

12
  if (!Buffer::New(env, size).ToLocal(&buff))
1245
    return;
1246
  unsigned char* serialized = reinterpret_cast<unsigned char*>(
1247
6
      Buffer::Data(buff));
1248
6
  i2d_X509(cert, &serialized);
1249
1250
12
  args.GetReturnValue().Set(buff);
1251
}
1252
1253
namespace {
1254
4
unsigned long AddCertsFromFile(  // NOLINT(runtime/int)
1255
    X509_STORE* store,
1256
    const char* file) {
1257
4
  ERR_clear_error();
1258
8
  MarkPopErrorOnReturn mark_pop_error_on_return;
1259
1260
8
  BIOPointer bio(BIO_new_file(file, "r"));
1261
4
  if (!bio)
1262
1
    return ERR_get_error();
1263
1264
  while (X509* x509 =
1265
6
      PEM_read_bio_X509(bio.get(), nullptr, NoPasswordCallback, nullptr)) {
1266
3
    X509_STORE_add_cert(store, x509);
1267
3
    X509_free(x509);
1268
3
  }
1269
1270
3
  unsigned long err = ERR_peek_error();  // NOLINT(runtime/int)
1271
  // Ignore error if its EOF/no start line found.
1272

6
  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
1273
3
      ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
1274
3
    return 0;
1275
  }
1276
1277
  return err;
1278
}
1279
}  // namespace
1280
1281
// UseExtraCaCerts is called only once at the start of the Node.js process.
1282
4
void UseExtraCaCerts(const std::string& file) {
1283
4
  ClearErrorOnReturn clear_error_on_return;
1284
1285
4
  if (root_cert_store == nullptr) {
1286
4
    root_cert_store = NewRootCertStore();
1287
1288
4
    if (!file.empty()) {
1289
4
      unsigned long err = AddCertsFromFile(  // NOLINT(runtime/int)
1290
                                           root_cert_store,
1291
4
                                           file.c_str());
1292
4
      if (err) {
1293
1
        fprintf(stderr,
1294
                "Warning: Ignoring extra certs from `%s`, load failed: %s\n",
1295
                file.c_str(),
1296
1
                ERR_error_string(err, nullptr));
1297
      } else {
1298
3
        extra_root_certs_loaded = true;
1299
      }
1300
    }
1301
  }
1302
4
}
1303
1304
// Exposed to JavaScript strictly for testing purposes.
1305
3
void IsExtraRootCertsFileLoaded(
1306
    const FunctionCallbackInfo<Value>& args) {
1307
9
  return args.GetReturnValue().Set(extra_root_certs_loaded);
1308
}
1309
1310
}  // namespace crypto
1311

14310
}  // namespace node