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#include <openssl/rand.h> 17#ifndef OPENSSL_NO_ENGINE 18#include <openssl/engine.h> 19#endif // !OPENSSL_NO_ENGINE 20 21namespace node { 22 23using v8::Array; 24using v8::ArrayBufferView; 25using v8::Boolean; 26using v8::Context; 27using v8::DontDelete; 28using v8::Exception; 29using v8::External; 30using v8::FunctionCallbackInfo; 31using v8::FunctionTemplate; 32using v8::HandleScope; 33using v8::Int32; 34using v8::Integer; 35using v8::Isolate; 36using v8::Just; 37using v8::Local; 38using v8::Maybe; 39using v8::Nothing; 40using v8::Object; 41using v8::PropertyAttribute; 42using v8::ReadOnly; 43using v8::Signature; 44using v8::String; 45using v8::Value; 46 47namespace crypto { 48static const char* const root_certs[] = { 49#include "node_root_certs.h" // NOLINT(build/include_order) 50}; 51 52static const char system_cert_path[] = NODE_OPENSSL_SYSTEM_CERT_PATH; 53 54static bool extra_root_certs_loaded = false; 55 56inline X509_STORE* GetOrCreateRootCertStore() { 57 // Guaranteed thread-safe by standard, just don't use -fno-threadsafe-statics. 58 static X509_STORE* store = NewRootCertStore(); 59 return store; 60} 61 62// Takes a string or buffer and loads it into a BIO. 63// Caller responsible for BIO_free_all-ing the returned object. 64BIOPointer LoadBIO(Environment* env, Local<Value> v) { 65 if (v->IsString() || v->IsArrayBufferView()) { 66 BIOPointer bio(BIO_new(BIO_s_secmem())); 67 if (!bio) return nullptr; 68 ByteSource bsrc = ByteSource::FromStringOrBuffer(env, v); 69 if (bsrc.size() > INT_MAX) return nullptr; 70 int written = BIO_write(bio.get(), bsrc.data<char>(), bsrc.size()); 71 if (written < 0) return nullptr; 72 if (static_cast<size_t>(written) != bsrc.size()) return nullptr; 73 return bio; 74 } 75 return nullptr; 76} 77 78namespace { 79int SSL_CTX_use_certificate_chain(SSL_CTX* ctx, 80 X509Pointer&& x, 81 STACK_OF(X509)* extra_certs, 82 X509Pointer* cert, 83 X509Pointer* issuer_) { 84 CHECK(!*issuer_); 85 CHECK(!*cert); 86 X509* issuer = nullptr; 87 88 int ret = SSL_CTX_use_certificate(ctx, x.get()); 89 90 if (ret) { 91 // If we could set up our certificate, now proceed to 92 // the CA certificates. 93 SSL_CTX_clear_extra_chain_certs(ctx); 94 95 for (int i = 0; i < sk_X509_num(extra_certs); i++) { 96 X509* ca = sk_X509_value(extra_certs, i); 97 98 // NOTE: Increments reference count on `ca` 99 if (!SSL_CTX_add1_chain_cert(ctx, ca)) { 100 ret = 0; 101 issuer = nullptr; 102 break; 103 } 104 // Note that we must not free r if it was successfully 105 // added to the chain (while we must free the main 106 // certificate, since its reference count is increased 107 // by SSL_CTX_use_certificate). 108 109 // Find issuer 110 if (issuer != nullptr || X509_check_issued(ca, x.get()) != X509_V_OK) 111 continue; 112 113 issuer = ca; 114 } 115 } 116 117 // Try getting issuer from a cert store 118 if (ret) { 119 if (issuer == nullptr) { 120 // TODO(tniessen): SSL_CTX_get_issuer does not allow the caller to 121 // distinguish between a failed operation and an empty result. Fix that 122 // and then handle the potential error properly here (set ret to 0). 123 *issuer_ = SSL_CTX_get_issuer(ctx, x.get()); 124 // NOTE: get_cert_store doesn't increment reference count, 125 // no need to free `store` 126 } else { 127 // Increment issuer reference count 128 issuer_->reset(X509_dup(issuer)); 129 if (!*issuer_) { 130 ret = 0; 131 } 132 } 133 } 134 135 if (ret && x != nullptr) { 136 cert->reset(X509_dup(x.get())); 137 if (!*cert) 138 ret = 0; 139 } 140 return ret; 141} 142 143// Read a file that contains our certificate in "PEM" format, 144// possibly followed by a sequence of CA certificates that should be 145// sent to the peer in the Certificate message. 146// 147// Taken from OpenSSL - edited for style. 148int SSL_CTX_use_certificate_chain(SSL_CTX* ctx, 149 BIOPointer&& in, 150 X509Pointer* cert, 151 X509Pointer* issuer) { 152 // Just to ensure that `ERR_peek_last_error` below will return only errors 153 // that we are interested in 154 ERR_clear_error(); 155 156 X509Pointer x( 157 PEM_read_bio_X509_AUX(in.get(), nullptr, NoPasswordCallback, nullptr)); 158 159 if (!x) 160 return 0; 161 162 unsigned long err = 0; // NOLINT(runtime/int) 163 164 StackOfX509 extra_certs(sk_X509_new_null()); 165 if (!extra_certs) 166 return 0; 167 168 while (X509Pointer extra {PEM_read_bio_X509(in.get(), 169 nullptr, 170 NoPasswordCallback, 171 nullptr)}) { 172 if (sk_X509_push(extra_certs.get(), extra.get())) { 173 extra.release(); 174 continue; 175 } 176 177 return 0; 178 } 179 180 // When the while loop ends, it's usually just EOF. 181 err = ERR_peek_last_error(); 182 if (ERR_GET_LIB(err) == ERR_LIB_PEM && 183 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { 184 ERR_clear_error(); 185 } else { 186 // some real error 187 return 0; 188 } 189 190 return SSL_CTX_use_certificate_chain(ctx, 191 std::move(x), 192 extra_certs.get(), 193 cert, 194 issuer); 195} 196 197} // namespace 198 199X509_STORE* NewRootCertStore() { 200 static std::vector<X509*> root_certs_vector; 201 static Mutex root_certs_vector_mutex; 202 Mutex::ScopedLock lock(root_certs_vector_mutex); 203 204 if (root_certs_vector.empty() && 205 per_process::cli_options->ssl_openssl_cert_store == false) { 206 for (size_t i = 0; i < arraysize(root_certs); i++) { 207 X509* x509 = 208 PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i], 209 strlen(root_certs[i])).get(), 210 nullptr, // no re-use of X509 structure 211 NoPasswordCallback, 212 nullptr); // no callback data 213 214 // Parse errors from the built-in roots are fatal. 215 CHECK_NOT_NULL(x509); 216 217 root_certs_vector.push_back(x509); 218 } 219 } 220 221 X509_STORE* store = X509_STORE_new(); 222 if (*system_cert_path != '\0') { 223 ERR_set_mark(); 224 X509_STORE_load_locations(store, system_cert_path, nullptr); 225 ERR_pop_to_mark(); 226 } 227 228 Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex); 229 if (per_process::cli_options->ssl_openssl_cert_store) { 230 X509_STORE_set_default_paths(store); 231 } else { 232 for (X509* cert : root_certs_vector) { 233 X509_up_ref(cert); 234 X509_STORE_add_cert(store, cert); 235 } 236 } 237 238 return store; 239} 240 241void GetRootCertificates(const FunctionCallbackInfo<Value>& args) { 242 Environment* env = Environment::GetCurrent(args); 243 Local<Value> result[arraysize(root_certs)]; 244 245 for (size_t i = 0; i < arraysize(root_certs); i++) { 246 if (!String::NewFromOneByte( 247 env->isolate(), 248 reinterpret_cast<const uint8_t*>(root_certs[i])) 249 .ToLocal(&result[i])) { 250 return; 251 } 252 } 253 254 args.GetReturnValue().Set( 255 Array::New(env->isolate(), result, arraysize(root_certs))); 256} 257 258bool SecureContext::HasInstance(Environment* env, const Local<Value>& value) { 259 return GetConstructorTemplate(env)->HasInstance(value); 260} 261 262Local<FunctionTemplate> SecureContext::GetConstructorTemplate( 263 Environment* env) { 264 Local<FunctionTemplate> tmpl = env->secure_context_constructor_template(); 265 if (tmpl.IsEmpty()) { 266 Isolate* isolate = env->isolate(); 267 tmpl = NewFunctionTemplate(isolate, New); 268 tmpl->InstanceTemplate()->SetInternalFieldCount( 269 SecureContext::kInternalFieldCount); 270 tmpl->Inherit(BaseObject::GetConstructorTemplate(env)); 271 tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext")); 272 273 SetProtoMethod(isolate, tmpl, "init", Init); 274 SetProtoMethod(isolate, tmpl, "setKey", SetKey); 275 SetProtoMethod(isolate, tmpl, "setCert", SetCert); 276 SetProtoMethod(isolate, tmpl, "addCACert", AddCACert); 277 SetProtoMethod(isolate, tmpl, "addCRL", AddCRL); 278 SetProtoMethod(isolate, tmpl, "addRootCerts", AddRootCerts); 279 SetProtoMethod(isolate, tmpl, "setCipherSuites", SetCipherSuites); 280 SetProtoMethod(isolate, tmpl, "setCiphers", SetCiphers); 281 SetProtoMethod(isolate, tmpl, "setSigalgs", SetSigalgs); 282 SetProtoMethod(isolate, tmpl, "setECDHCurve", SetECDHCurve); 283 SetProtoMethod(isolate, tmpl, "setDHParam", SetDHParam); 284 SetProtoMethod(isolate, tmpl, "setMaxProto", SetMaxProto); 285 SetProtoMethod(isolate, tmpl, "setMinProto", SetMinProto); 286 SetProtoMethod(isolate, tmpl, "getMaxProto", GetMaxProto); 287 SetProtoMethod(isolate, tmpl, "getMinProto", GetMinProto); 288 SetProtoMethod(isolate, tmpl, "setOptions", SetOptions); 289 SetProtoMethod(isolate, tmpl, "setSessionIdContext", SetSessionIdContext); 290 SetProtoMethod(isolate, tmpl, "setSessionTimeout", SetSessionTimeout); 291 SetProtoMethod(isolate, tmpl, "close", Close); 292 SetProtoMethod(isolate, tmpl, "loadPKCS12", LoadPKCS12); 293 SetProtoMethod(isolate, tmpl, "setTicketKeys", SetTicketKeys); 294 SetProtoMethod( 295 isolate, tmpl, "enableTicketKeyCallback", EnableTicketKeyCallback); 296 297 SetProtoMethodNoSideEffect(isolate, tmpl, "getTicketKeys", GetTicketKeys); 298 SetProtoMethodNoSideEffect( 299 isolate, tmpl, "getCertificate", GetCertificate<true>); 300 SetProtoMethodNoSideEffect( 301 isolate, tmpl, "getIssuer", GetCertificate<false>); 302 303#ifndef OPENSSL_NO_ENGINE 304 SetProtoMethod(isolate, tmpl, "setEngineKey", SetEngineKey); 305 SetProtoMethod(isolate, tmpl, "setClientCertEngine", SetClientCertEngine); 306#endif // !OPENSSL_NO_ENGINE 307 308#define SET_INTEGER_CONSTANTS(name, value) \ 309 tmpl->Set(FIXED_ONE_BYTE_STRING(isolate, name), \ 310 Integer::NewFromUnsigned(isolate, value)); 311 SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex); 312 SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex); 313 SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex); 314 SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex); 315 SET_INTEGER_CONSTANTS("kTicketKeyIVIndex", kTicketKeyIVIndex); 316 #undef SET_INTEGER_CONSTANTS 317 318 Local<FunctionTemplate> ctx_getter_templ = FunctionTemplate::New( 319 isolate, CtxGetter, Local<Value>(), Signature::New(isolate, tmpl)); 320 321 tmpl->PrototypeTemplate()->SetAccessorProperty( 322 FIXED_ONE_BYTE_STRING(isolate, "_external"), 323 ctx_getter_templ, 324 Local<FunctionTemplate>(), 325 static_cast<PropertyAttribute>(ReadOnly | DontDelete)); 326 327 env->set_secure_context_constructor_template(tmpl); 328 } 329 return tmpl; 330} 331 332void SecureContext::Initialize(Environment* env, Local<Object> target) { 333 Local<Context> context = env->context(); 334 SetConstructorFunction(context, 335 target, 336 "SecureContext", 337 GetConstructorTemplate(env), 338 SetConstructorFunctionFlag::NONE); 339 340 SetMethodNoSideEffect( 341 context, target, "getRootCertificates", GetRootCertificates); 342 // Exposed for testing purposes only. 343 SetMethodNoSideEffect(context, 344 target, 345 "isExtraRootCertsFileLoaded", 346 IsExtraRootCertsFileLoaded); 347} 348 349void SecureContext::RegisterExternalReferences( 350 ExternalReferenceRegistry* registry) { 351 registry->Register(New); 352 registry->Register(Init); 353 registry->Register(SetKey); 354 registry->Register(SetCert); 355 registry->Register(AddCACert); 356 registry->Register(AddCRL); 357 registry->Register(AddRootCerts); 358 registry->Register(SetCipherSuites); 359 registry->Register(SetCiphers); 360 registry->Register(SetSigalgs); 361 registry->Register(SetECDHCurve); 362 registry->Register(SetDHParam); 363 registry->Register(SetMaxProto); 364 registry->Register(SetMinProto); 365 registry->Register(GetMaxProto); 366 registry->Register(GetMinProto); 367 registry->Register(SetOptions); 368 registry->Register(SetSessionIdContext); 369 registry->Register(SetSessionTimeout); 370 registry->Register(Close); 371 registry->Register(LoadPKCS12); 372 registry->Register(SetTicketKeys); 373 registry->Register(EnableTicketKeyCallback); 374 registry->Register(GetTicketKeys); 375 registry->Register(GetCertificate<true>); 376 registry->Register(GetCertificate<false>); 377 378#ifndef OPENSSL_NO_ENGINE 379 registry->Register(SetEngineKey); 380 registry->Register(SetClientCertEngine); 381#endif // !OPENSSL_NO_ENGINE 382 383 registry->Register(CtxGetter); 384 385 registry->Register(GetRootCertificates); 386 registry->Register(IsExtraRootCertsFileLoaded); 387} 388 389SecureContext* SecureContext::Create(Environment* env) { 390 Local<Object> obj; 391 if (!GetConstructorTemplate(env) 392 ->InstanceTemplate() 393 ->NewInstance(env->context()).ToLocal(&obj)) { 394 return nullptr; 395 } 396 397 return new SecureContext(env, obj); 398} 399 400SecureContext::SecureContext(Environment* env, Local<Object> wrap) 401 : BaseObject(env, wrap) { 402 MakeWeak(); 403 env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize); 404} 405 406inline void SecureContext::Reset() { 407 if (ctx_ != nullptr) { 408 env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize); 409 } 410 ctx_.reset(); 411 cert_.reset(); 412 issuer_.reset(); 413} 414 415SecureContext::~SecureContext() { 416 Reset(); 417} 418 419void SecureContext::New(const FunctionCallbackInfo<Value>& args) { 420 Environment* env = Environment::GetCurrent(args); 421 new SecureContext(env, args.This()); 422} 423 424void SecureContext::Init(const FunctionCallbackInfo<Value>& args) { 425 SecureContext* sc; 426 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 427 Environment* env = sc->env(); 428 429 CHECK_EQ(args.Length(), 3); 430 CHECK(args[1]->IsInt32()); 431 CHECK(args[2]->IsInt32()); 432 433 int min_version = args[1].As<Int32>()->Value(); 434 int max_version = args[2].As<Int32>()->Value(); 435 const SSL_METHOD* method = TLS_method(); 436 437 if (max_version == 0) 438 max_version = kMaxSupportedVersion; 439 440 if (args[0]->IsString()) { 441 Utf8Value sslmethod(env->isolate(), args[0]); 442 443 // Note that SSLv2 and SSLv3 are disallowed but SSLv23_method and friends 444 // are still accepted. They are OpenSSL's way of saying that all known 445 // protocols below TLS 1.3 are supported unless explicitly disabled (which 446 // we do below for SSLv2 and SSLv3.) 447 if (sslmethod == "SSLv2_method" || 448 sslmethod == "SSLv2_server_method" || 449 sslmethod == "SSLv2_client_method") { 450 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled"); 451 return; 452 } else if (sslmethod == "SSLv3_method" || 453 sslmethod == "SSLv3_server_method" || 454 sslmethod == "SSLv3_client_method") { 455 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv3 methods disabled"); 456 return; 457 } else if (sslmethod == "SSLv23_method") { 458 max_version = TLS1_2_VERSION; 459 } else if (sslmethod == "SSLv23_server_method") { 460 max_version = TLS1_2_VERSION; 461 method = TLS_server_method(); 462 } else if (sslmethod == "SSLv23_client_method") { 463 max_version = TLS1_2_VERSION; 464 method = TLS_client_method(); 465 } else if (sslmethod == "TLS_method") { 466 min_version = 0; 467 max_version = kMaxSupportedVersion; 468 } else if (sslmethod == "TLS_server_method") { 469 min_version = 0; 470 max_version = kMaxSupportedVersion; 471 method = TLS_server_method(); 472 } else if (sslmethod == "TLS_client_method") { 473 min_version = 0; 474 max_version = kMaxSupportedVersion; 475 method = TLS_client_method(); 476 } else if (sslmethod == "TLSv1_method") { 477 min_version = TLS1_VERSION; 478 max_version = TLS1_VERSION; 479 } else if (sslmethod == "TLSv1_server_method") { 480 min_version = TLS1_VERSION; 481 max_version = TLS1_VERSION; 482 method = TLS_server_method(); 483 } else if (sslmethod == "TLSv1_client_method") { 484 min_version = TLS1_VERSION; 485 max_version = TLS1_VERSION; 486 method = TLS_client_method(); 487 } else if (sslmethod == "TLSv1_1_method") { 488 min_version = TLS1_1_VERSION; 489 max_version = TLS1_1_VERSION; 490 } else if (sslmethod == "TLSv1_1_server_method") { 491 min_version = TLS1_1_VERSION; 492 max_version = TLS1_1_VERSION; 493 method = TLS_server_method(); 494 } else if (sslmethod == "TLSv1_1_client_method") { 495 min_version = TLS1_1_VERSION; 496 max_version = TLS1_1_VERSION; 497 method = TLS_client_method(); 498 } else if (sslmethod == "TLSv1_2_method") { 499 min_version = TLS1_2_VERSION; 500 max_version = TLS1_2_VERSION; 501 } else if (sslmethod == "TLSv1_2_server_method") { 502 min_version = TLS1_2_VERSION; 503 max_version = TLS1_2_VERSION; 504 method = TLS_server_method(); 505 } else if (sslmethod == "TLSv1_2_client_method") { 506 min_version = TLS1_2_VERSION; 507 max_version = TLS1_2_VERSION; 508 method = TLS_client_method(); 509 } else { 510 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD( 511 env, "Unknown method: %s", *sslmethod); 512 return; 513 } 514 } 515 516 sc->ctx_.reset(SSL_CTX_new(method)); 517 if (!sc->ctx_) { 518 return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_new"); 519 } 520 SSL_CTX_set_app_data(sc->ctx_.get(), sc); 521 522 // Disable SSLv2 in the case when method == TLS_method() and the 523 // cipher list contains SSLv2 ciphers (not the default, should be rare.) 524 // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may. 525 // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.) 526 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv2); 527 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv3); 528#if OPENSSL_VERSION_MAJOR >= 3 529 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_ALLOW_CLIENT_RENEGOTIATION); 530#endif 531 532 // Enable automatic cert chaining. This is enabled by default in OpenSSL, but 533 // disabled by default in BoringSSL. Enable it explicitly to make the 534 // behavior match when Node is built with BoringSSL. 535 SSL_CTX_clear_mode(sc->ctx_.get(), SSL_MODE_NO_AUTO_CHAIN); 536 537 // SSL session cache configuration 538 SSL_CTX_set_session_cache_mode(sc->ctx_.get(), 539 SSL_SESS_CACHE_CLIENT | 540 SSL_SESS_CACHE_SERVER | 541 SSL_SESS_CACHE_NO_INTERNAL | 542 SSL_SESS_CACHE_NO_AUTO_CLEAR); 543 544 SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version); 545 SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version); 546 547 // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was 548 // exposed in the public API. To retain compatibility, install a callback 549 // which restores the old algorithm. 550 if (CSPRNG(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)).is_err() || 551 CSPRNG(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)).is_err() || 552 CSPRNG(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)).is_err()) { 553 return THROW_ERR_CRYPTO_OPERATION_FAILED( 554 env, "Error generating ticket keys"); 555 } 556 SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback); 557} 558 559SSLPointer SecureContext::CreateSSL() { 560 return SSLPointer(SSL_new(ctx_.get())); 561} 562 563void SecureContext::SetNewSessionCallback(NewSessionCb cb) { 564 SSL_CTX_sess_set_new_cb(ctx_.get(), cb); 565} 566 567void SecureContext::SetGetSessionCallback(GetSessionCb cb) { 568 SSL_CTX_sess_set_get_cb(ctx_.get(), cb); 569} 570 571void SecureContext::SetSelectSNIContextCallback(SelectSNIContextCb cb) { 572 SSL_CTX_set_tlsext_servername_callback(ctx_.get(), cb); 573} 574 575void SecureContext::SetKeylogCallback(KeylogCb cb) { 576 SSL_CTX_set_keylog_callback(ctx_.get(), cb); 577} 578 579Maybe<bool> SecureContext::UseKey(Environment* env, 580 std::shared_ptr<KeyObjectData> key) { 581 if (key->GetKeyType() != KeyType::kKeyTypePrivate) { 582 THROW_ERR_CRYPTO_INVALID_KEYTYPE(env); 583 return Nothing<bool>(); 584 } 585 586 ClearErrorOnReturn clear_error_on_return; 587 if (!SSL_CTX_use_PrivateKey(ctx_.get(), key->GetAsymmetricKey().get())) { 588 ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey"); 589 return Nothing<bool>(); 590 } 591 592 return Just(true); 593} 594 595void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) { 596 Environment* env = Environment::GetCurrent(args); 597 598 SecureContext* sc; 599 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 600 601 CHECK_GE(args.Length(), 1); // Private key argument is mandatory 602 603 BIOPointer bio(LoadBIO(env, args[0])); 604 if (!bio) 605 return; 606 607 ByteSource passphrase; 608 if (args[1]->IsString()) 609 passphrase = ByteSource::FromString(env, args[1].As<String>()); 610 // This redirection is necessary because the PasswordCallback expects a 611 // pointer to a pointer to the passphrase ByteSource to allow passing in 612 // const ByteSources. 613 const ByteSource* pass_ptr = &passphrase; 614 615 EVPKeyPointer key( 616 PEM_read_bio_PrivateKey(bio.get(), 617 nullptr, 618 PasswordCallback, 619 &pass_ptr)); 620 621 if (!key) 622 return ThrowCryptoError(env, ERR_get_error(), "PEM_read_bio_PrivateKey"); 623 624 if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get())) 625 return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey"); 626} 627 628void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) { 629 SecureContext* sc; 630 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 631 Environment* env = sc->env(); 632 ClearErrorOnReturn clear_error_on_return; 633 634 CHECK_EQ(args.Length(), 1); 635 CHECK(args[0]->IsString()); 636 637 const Utf8Value sigalgs(env->isolate(), args[0]); 638 639 if (!SSL_CTX_set1_sigalgs_list(sc->ctx_.get(), *sigalgs)) 640 return ThrowCryptoError(env, ERR_get_error()); 641} 642 643#ifndef OPENSSL_NO_ENGINE 644void SecureContext::SetEngineKey(const FunctionCallbackInfo<Value>& args) { 645 Environment* env = Environment::GetCurrent(args); 646 647 SecureContext* sc; 648 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 649 650 CHECK_EQ(args.Length(), 2); 651 652 CryptoErrorStore errors; 653 Utf8Value engine_id(env->isolate(), args[1]); 654 EnginePointer engine = LoadEngineById(*engine_id, &errors); 655 if (!engine) { 656 Local<Value> exception; 657 if (errors.ToException(env).ToLocal(&exception)) 658 env->isolate()->ThrowException(exception); 659 return; 660 } 661 662 if (!ENGINE_init(engine.get())) { 663 return THROW_ERR_CRYPTO_OPERATION_FAILED( 664 env, "Failure to initialize engine"); 665 } 666 667 engine.finish_on_exit = true; 668 669 Utf8Value key_name(env->isolate(), args[0]); 670 EVPKeyPointer key(ENGINE_load_private_key(engine.get(), *key_name, 671 nullptr, nullptr)); 672 673 if (!key) 674 return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key"); 675 676 if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get())) 677 return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey"); 678 679 sc->private_key_engine_ = std::move(engine); 680} 681#endif // !OPENSSL_NO_ENGINE 682 683Maybe<bool> SecureContext::AddCert(Environment* env, BIOPointer&& bio) { 684 ClearErrorOnReturn clear_error_on_return; 685 if (!bio) return Just(false); 686 cert_.reset(); 687 issuer_.reset(); 688 689 // The SSL_CTX_use_certificate_chain call here is not from openssl, this is 690 // the method implemented elsewhere in this file. The naming is a bit 691 // confusing, unfortunately. 692 if (SSL_CTX_use_certificate_chain( 693 ctx_.get(), std::move(bio), &cert_, &issuer_) == 0) { 694 ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_certificate_chain"); 695 return Nothing<bool>(); 696 } 697 return Just(true); 698} 699 700void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) { 701 Environment* env = Environment::GetCurrent(args); 702 703 SecureContext* sc; 704 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 705 706 CHECK_GE(args.Length(), 1); // Certificate argument is mandatory 707 708 BIOPointer bio(LoadBIO(env, args[0])); 709 USE(sc->AddCert(env, std::move(bio))); 710} 711 712void SecureContext::SetCACert(const BIOPointer& bio) { 713 ClearErrorOnReturn clear_error_on_return; 714 if (!bio) return; 715 X509_STORE* cert_store = SSL_CTX_get_cert_store(ctx_.get()); 716 while (X509Pointer x509 = X509Pointer(PEM_read_bio_X509_AUX( 717 bio.get(), nullptr, NoPasswordCallback, nullptr))) { 718 if (cert_store == GetOrCreateRootCertStore()) { 719 cert_store = NewRootCertStore(); 720 SSL_CTX_set_cert_store(ctx_.get(), cert_store); 721 } 722 CHECK_EQ(1, X509_STORE_add_cert(cert_store, x509.get())); 723 CHECK_EQ(1, SSL_CTX_add_client_CA(ctx_.get(), x509.get())); 724 } 725} 726 727void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) { 728 Environment* env = Environment::GetCurrent(args); 729 730 SecureContext* sc; 731 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 732 733 CHECK_GE(args.Length(), 1); // CA certificate argument is mandatory 734 735 BIOPointer bio(LoadBIO(env, args[0])); 736 sc->SetCACert(bio); 737} 738 739Maybe<bool> SecureContext::SetCRL(Environment* env, const BIOPointer& bio) { 740 ClearErrorOnReturn clear_error_on_return; 741 if (!bio) return Just(false); 742 743 DeleteFnPtr<X509_CRL, X509_CRL_free> crl( 744 PEM_read_bio_X509_CRL(bio.get(), nullptr, NoPasswordCallback, nullptr)); 745 746 if (!crl) { 747 THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to parse CRL"); 748 return Nothing<bool>(); 749 } 750 751 X509_STORE* cert_store = SSL_CTX_get_cert_store(ctx_.get()); 752 if (cert_store == GetOrCreateRootCertStore()) { 753 cert_store = NewRootCertStore(); 754 SSL_CTX_set_cert_store(ctx_.get(), cert_store); 755 } 756 757 CHECK_EQ(1, X509_STORE_add_crl(cert_store, crl.get())); 758 CHECK_EQ(1, 759 X509_STORE_set_flags( 760 cert_store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL)); 761 return Just(true); 762} 763 764void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) { 765 Environment* env = Environment::GetCurrent(args); 766 767 SecureContext* sc; 768 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 769 770 CHECK_GE(args.Length(), 1); // CRL argument is mandatory 771 772 BIOPointer bio(LoadBIO(env, args[0])); 773 USE(sc->SetCRL(env, bio)); 774} 775 776void SecureContext::SetRootCerts() { 777 ClearErrorOnReturn clear_error_on_return; 778 auto store = GetOrCreateRootCertStore(); 779 780 // Increment reference count so global store is not deleted along with CTX. 781 X509_STORE_up_ref(store); 782 SSL_CTX_set_cert_store(ctx_.get(), store); 783} 784 785void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) { 786 SecureContext* sc; 787 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 788 sc->SetRootCerts(); 789} 790 791void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) { 792 // BoringSSL doesn't allow API config of TLS1.3 cipher suites. 793#ifndef OPENSSL_IS_BORINGSSL 794 SecureContext* sc; 795 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 796 Environment* env = sc->env(); 797 ClearErrorOnReturn clear_error_on_return; 798 799 CHECK_EQ(args.Length(), 1); 800 CHECK(args[0]->IsString()); 801 802 const Utf8Value ciphers(env->isolate(), args[0]); 803 if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers)) 804 return ThrowCryptoError(env, ERR_get_error(), "Failed to set ciphers"); 805#endif 806} 807 808void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) { 809 SecureContext* sc; 810 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 811 Environment* env = sc->env(); 812 ClearErrorOnReturn clear_error_on_return; 813 814 CHECK_EQ(args.Length(), 1); 815 CHECK(args[0]->IsString()); 816 817 Utf8Value ciphers(env->isolate(), args[0]); 818 if (!SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) { 819 unsigned long err = ERR_get_error(); // NOLINT(runtime/int) 820 821 if (strlen(*ciphers) == 0 && ERR_GET_REASON(err) == SSL_R_NO_CIPHER_MATCH) { 822 // TLS1.2 ciphers were deliberately cleared, so don't consider 823 // SSL_R_NO_CIPHER_MATCH to be an error (this is how _set_cipher_suites() 824 // works). If the user actually sets a value (like "no-such-cipher"), then 825 // that's actually an error. 826 return; 827 } 828 return ThrowCryptoError(env, err, "Failed to set ciphers"); 829 } 830} 831 832void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) { 833 SecureContext* sc; 834 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 835 Environment* env = sc->env(); 836 837 CHECK_GE(args.Length(), 1); // ECDH curve name argument is mandatory 838 CHECK(args[0]->IsString()); 839 840 Utf8Value curve(env->isolate(), args[0]); 841 842 if (curve != "auto" && !SSL_CTX_set1_curves_list(sc->ctx_.get(), *curve)) { 843 return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to set ECDH curve"); 844 } 845} 846 847void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) { 848 SecureContext* sc; 849 ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); 850 Environment* env = sc->env(); 851 ClearErrorOnReturn clear_error_on_return; 852 853 CHECK_GE(args.Length(), 1); // DH argument is mandatory 854 855 // If the user specified "auto" for dhparams, the JavaScript layer will pass 856 // true to this function instead of the original string. Any other string 857 // value will be interpreted as custom DH parameters below. 858 if (args[0]->IsTrue()) { 859 CHECK(SSL_CTX_set_dh_auto(sc->ctx_.get(), true)); 860 return; 861 } 862 863 DHPointer dh; 864 { 865 BIOPointer bio(LoadBIO(env, args[0])); 866 if (!bio) 867 return; 868 869 dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr)); 870 } 871 872 // Invalid dhparam is silently discarded and DHE is no longer used. 873 // TODO(tniessen): don't silently discard invalid dhparam. 874 if (!dh) 875 return; 876 877 const BIGNUM* p; 878 DH_get0_pqg(dh.get(), &p, nullptr, nullptr); 879 const int size = BN_num_bits(p); 880 if (size < 1024) { 881 return THROW_ERR_INVALID_ARG_VALUE( 882 env, "DH parameter is less than 1024 bits"); 883 } else if (size < 2048) { 884 args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING( 885 env->isolate(), "DH parameter is less than 2048 bits")); 886 } 887 888 if (!SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get())) { 889 return THROW_ERR_CRYPTO_OPERATION_FAILED( 890 env, "Error setting temp DH parameter"); 891 } 892} 893 894void SecureContext::SetMinProto(const FunctionCallbackInfo<Value>& args) { 895 SecureContext* sc; 896 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 897 898 CHECK_EQ(args.Length(), 1); 899 CHECK(args[0]->IsInt32()); 900 901 int version = args[0].As<Int32>()->Value(); 902 903 CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), version)); 904} 905 906void SecureContext::SetMaxProto(const FunctionCallbackInfo<Value>& args) { 907 SecureContext* sc; 908 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 909 910 CHECK_EQ(args.Length(), 1); 911 CHECK(args[0]->IsInt32()); 912 913 int version = args[0].As<Int32>()->Value(); 914 915 CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), version)); 916} 917 918void SecureContext::GetMinProto(const FunctionCallbackInfo<Value>& args) { 919 SecureContext* sc; 920 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 921 922 CHECK_EQ(args.Length(), 0); 923 924 long version = // NOLINT(runtime/int) 925 SSL_CTX_get_min_proto_version(sc->ctx_.get()); 926 args.GetReturnValue().Set(static_cast<uint32_t>(version)); 927} 928 929void SecureContext::GetMaxProto(const FunctionCallbackInfo<Value>& args) { 930 SecureContext* sc; 931 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 932 933 CHECK_EQ(args.Length(), 0); 934 935 long version = // NOLINT(runtime/int) 936 SSL_CTX_get_max_proto_version(sc->ctx_.get()); 937 args.GetReturnValue().Set(static_cast<uint32_t>(version)); 938} 939 940void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) { 941 Environment* env = Environment::GetCurrent(args); 942 SecureContext* sc; 943 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 944 945 CHECK_GE(args.Length(), 1); 946 CHECK(args[0]->IsNumber()); 947 948 int64_t val = args[0]->IntegerValue(env->context()).FromMaybe(0); 949 950 SSL_CTX_set_options(sc->ctx_.get(), 951 static_cast<long>(val)); // NOLINT(runtime/int) 952} 953 954void SecureContext::SetSessionIdContext( 955 const FunctionCallbackInfo<Value>& args) { 956 SecureContext* sc; 957 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 958 Environment* env = sc->env(); 959 960 CHECK_GE(args.Length(), 1); 961 CHECK(args[0]->IsString()); 962 963 const Utf8Value sessionIdContext(env->isolate(), args[0]); 964 const unsigned char* sid_ctx = 965 reinterpret_cast<const unsigned char*>(*sessionIdContext); 966 unsigned int sid_ctx_len = sessionIdContext.length(); 967 968 if (SSL_CTX_set_session_id_context(sc->ctx_.get(), sid_ctx, sid_ctx_len) == 1) 969 return; 970 971 BUF_MEM* mem; 972 Local<String> message; 973 974 BIOPointer bio(BIO_new(BIO_s_mem())); 975 if (!bio) { 976 message = FIXED_ONE_BYTE_STRING(env->isolate(), 977 "SSL_CTX_set_session_id_context error"); 978 } else { 979 ERR_print_errors(bio.get()); 980 BIO_get_mem_ptr(bio.get(), &mem); 981 message = OneByteString(env->isolate(), mem->data, mem->length); 982 } 983 984 env->isolate()->ThrowException(Exception::TypeError(message)); 985} 986 987void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) { 988 SecureContext* sc; 989 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 990 991 CHECK_GE(args.Length(), 1); 992 CHECK(args[0]->IsInt32()); 993 994 int32_t sessionTimeout = args[0].As<Int32>()->Value(); 995 SSL_CTX_set_timeout(sc->ctx_.get(), sessionTimeout); 996} 997 998void SecureContext::Close(const FunctionCallbackInfo<Value>& args) { 999 SecureContext* sc; 1000 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 1001 sc->Reset(); 1002} 1003 1004// Takes .pfx or .p12 and password in string or buffer format 1005void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) { 1006 Environment* env = Environment::GetCurrent(args); 1007 1008 std::vector<char> pass; 1009 bool ret = false; 1010 1011 SecureContext* sc; 1012 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 1013 ClearErrorOnReturn clear_error_on_return; 1014 1015 if (args.Length() < 1) { 1016 return THROW_ERR_MISSING_ARGS(env, "PFX certificate argument is mandatory"); 1017 } 1018 1019 BIOPointer in(LoadBIO(env, args[0])); 1020 if (!in) { 1021 return THROW_ERR_CRYPTO_OPERATION_FAILED( 1022 env, "Unable to load PFX certificate"); 1023 } 1024 1025 if (args.Length() >= 2) { 1026 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[1], "Pass phrase"); 1027 Local<ArrayBufferView> abv = args[1].As<ArrayBufferView>(); 1028 size_t passlen = abv->ByteLength(); 1029 pass.resize(passlen + 1); 1030 abv->CopyContents(pass.data(), passlen); 1031 pass[passlen] = '\0'; 1032 } 1033 1034 // Free previous certs 1035 sc->issuer_.reset(); 1036 sc->cert_.reset(); 1037 1038 X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get()); 1039 1040 DeleteFnPtr<PKCS12, PKCS12_free> p12; 1041 EVPKeyPointer pkey; 1042 X509Pointer cert; 1043 StackOfX509 extra_certs; 1044 1045 PKCS12* p12_ptr = nullptr; 1046 EVP_PKEY* pkey_ptr = nullptr; 1047 X509* cert_ptr = nullptr; 1048 STACK_OF(X509)* extra_certs_ptr = nullptr; 1049 if (d2i_PKCS12_bio(in.get(), &p12_ptr) && 1050 (p12.reset(p12_ptr), true) && // Move ownership to the smart pointer. 1051 PKCS12_parse(p12.get(), pass.data(), 1052 &pkey_ptr, 1053 &cert_ptr, 1054 &extra_certs_ptr) && 1055 (pkey.reset(pkey_ptr), cert.reset(cert_ptr), 1056 extra_certs.reset(extra_certs_ptr), true) && // Move ownership. 1057 SSL_CTX_use_certificate_chain(sc->ctx_.get(), 1058 std::move(cert), 1059 extra_certs.get(), 1060 &sc->cert_, 1061 &sc->issuer_) && 1062 SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) { 1063 // Add CA certs too 1064 for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) { 1065 X509* ca = sk_X509_value(extra_certs.get(), i); 1066 1067 if (cert_store == GetOrCreateRootCertStore()) { 1068 cert_store = NewRootCertStore(); 1069 SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store); 1070 } 1071 X509_STORE_add_cert(cert_store, ca); 1072 SSL_CTX_add_client_CA(sc->ctx_.get(), ca); 1073 } 1074 ret = true; 1075 } 1076 1077 if (!ret) { 1078 // TODO(@jasnell): Should this use ThrowCryptoError? 1079 unsigned long err = ERR_get_error(); // NOLINT(runtime/int) 1080 const char* str = ERR_reason_error_string(err); 1081 str = str != nullptr ? str : "Unknown error"; 1082 1083 return env->ThrowError(str); 1084 } 1085} 1086 1087#ifndef OPENSSL_NO_ENGINE 1088void SecureContext::SetClientCertEngine( 1089 const FunctionCallbackInfo<Value>& args) { 1090 Environment* env = Environment::GetCurrent(args); 1091 CHECK_EQ(args.Length(), 1); 1092 CHECK(args[0]->IsString()); 1093 1094 SecureContext* sc; 1095 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); 1096 1097 MarkPopErrorOnReturn mark_pop_error_on_return; 1098 1099 // SSL_CTX_set_client_cert_engine does not itself support multiple 1100 // calls by cleaning up before overwriting the client_cert_engine 1101 // internal context variable. 1102 // Instead of trying to fix up this problem we in turn also do not 1103 // support multiple calls to SetClientCertEngine. 1104 CHECK(!sc->client_cert_engine_provided_); 1105 1106 CryptoErrorStore errors; 1107 const Utf8Value engine_id(env->isolate(), args[0]); 1108 EnginePointer engine = LoadEngineById(*engine_id, &errors); 1109 if (!engine) { 1110 Local<Value> exception; 1111 if (errors.ToException(env).ToLocal(&exception)) 1112 env->isolate()->ThrowException(exception); 1113 return; 1114 } 1115 1116 // Note that this takes another reference to `engine`. 1117 if (!SSL_CTX_set_client_cert_engine(sc->ctx_.get(), engine.get())) 1118 return ThrowCryptoError(env, ERR_get_error()); 1119 sc->client_cert_engine_provided_ = true; 1120} 1121#endif // !OPENSSL_NO_ENGINE 1122 1123void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) { 1124 SecureContext* wrap; 1125 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); 1126 1127 Local<Object> buff; 1128 if (!Buffer::New(wrap->env(), 48).ToLocal(&buff)) 1129 return; 1130 1131 memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16); 1132 memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16); 1133 memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16); 1134 1135 args.GetReturnValue().Set(buff); 1136} 1137 1138void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) { 1139 SecureContext* wrap; 1140 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); 1141 1142 CHECK_GE(args.Length(), 1); // Ticket keys argument is mandatory 1143 CHECK(args[0]->IsArrayBufferView()); 1144 ArrayBufferViewContents<char> buf(args[0].As<ArrayBufferView>()); 1145 1146 CHECK_EQ(buf.length(), 48); 1147 1148 memcpy(wrap->ticket_key_name_, buf.data(), 16); 1149 memcpy(wrap->ticket_key_hmac_, buf.data() + 16, 16); 1150 memcpy(wrap->ticket_key_aes_, buf.data() + 32, 16); 1151 1152 args.GetReturnValue().Set(true); 1153} 1154 1155// Currently, EnableTicketKeyCallback and TicketKeyCallback are only present for 1156// the regression test in test/parallel/test-https-resume-after-renew.js. 1157void SecureContext::EnableTicketKeyCallback( 1158 const FunctionCallbackInfo<Value>& args) { 1159 SecureContext* wrap; 1160 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); 1161 1162 SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback); 1163} 1164 1165int SecureContext::TicketKeyCallback(SSL* ssl, 1166 unsigned char* name, 1167 unsigned char* iv, 1168 EVP_CIPHER_CTX* ectx, 1169 HMAC_CTX* hctx, 1170 int enc) { 1171 static const int kTicketPartSize = 16; 1172 1173 SecureContext* sc = static_cast<SecureContext*>( 1174 SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl))); 1175 1176 Environment* env = sc->env(); 1177 HandleScope handle_scope(env->isolate()); 1178 Context::Scope context_scope(env->context()); 1179 1180 Local<Value> argv[3]; 1181 1182 if (!Buffer::Copy( 1183 env, 1184 reinterpret_cast<char*>(name), 1185 kTicketPartSize).ToLocal(&argv[0]) || 1186 !Buffer::Copy( 1187 env, 1188 reinterpret_cast<char*>(iv), 1189 kTicketPartSize).ToLocal(&argv[1])) { 1190 return -1; 1191 } 1192 1193 argv[2] = Boolean::New(env->isolate(), enc != 0); 1194 1195 Local<Value> ret; 1196 if (!node::MakeCallback( 1197 env->isolate(), 1198 sc->object(), 1199 env->ticketkeycallback_string(), 1200 arraysize(argv), 1201 argv, 1202 {0, 0}).ToLocal(&ret) || 1203 !ret->IsArray()) { 1204 return -1; 1205 } 1206 Local<Array> arr = ret.As<Array>(); 1207 1208 Local<Value> val; 1209 if (!arr->Get(env->context(), kTicketKeyReturnIndex).ToLocal(&val) || 1210 !val->IsInt32()) { 1211 return -1; 1212 } 1213 1214 int r = val.As<Int32>()->Value(); 1215 if (r < 0) 1216 return r; 1217 1218 Local<Value> hmac; 1219 Local<Value> aes; 1220 1221 if (!arr->Get(env->context(), kTicketKeyHMACIndex).ToLocal(&hmac) || 1222 !arr->Get(env->context(), kTicketKeyAESIndex).ToLocal(&aes) || 1223 Buffer::Length(aes) != kTicketPartSize) { 1224 return -1; 1225 } 1226 1227 if (enc) { 1228 Local<Value> name_val; 1229 Local<Value> iv_val; 1230 if (!arr->Get(env->context(), kTicketKeyNameIndex).ToLocal(&name_val) || 1231 !arr->Get(env->context(), kTicketKeyIVIndex).ToLocal(&iv_val) || 1232 Buffer::Length(name_val) != kTicketPartSize || 1233 Buffer::Length(iv_val) != kTicketPartSize) { 1234 return -1; 1235 } 1236 1237 name_val.As<ArrayBufferView>()->CopyContents(name, kTicketPartSize); 1238 iv_val.As<ArrayBufferView>()->CopyContents(iv, kTicketPartSize); 1239 } 1240 1241 ArrayBufferViewContents<unsigned char> hmac_buf(hmac); 1242 HMAC_Init_ex(hctx, 1243 hmac_buf.data(), 1244 hmac_buf.length(), 1245 EVP_sha256(), 1246 nullptr); 1247 1248 ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>()); 1249 if (enc) { 1250 EVP_EncryptInit_ex(ectx, 1251 EVP_aes_128_cbc(), 1252 nullptr, 1253 aes_key.data(), 1254 iv); 1255 } else { 1256 EVP_DecryptInit_ex(ectx, 1257 EVP_aes_128_cbc(), 1258 nullptr, 1259 aes_key.data(), 1260 iv); 1261 } 1262 1263 return r; 1264} 1265 1266int SecureContext::TicketCompatibilityCallback(SSL* ssl, 1267 unsigned char* name, 1268 unsigned char* iv, 1269 EVP_CIPHER_CTX* ectx, 1270 HMAC_CTX* hctx, 1271 int enc) { 1272 SecureContext* sc = static_cast<SecureContext*>( 1273 SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl))); 1274 1275 if (enc) { 1276 memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)); 1277 if (CSPRNG(iv, 16).is_err() || 1278 EVP_EncryptInit_ex( 1279 ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_, iv) <= 0 || 1280 HMAC_Init_ex(hctx, 1281 sc->ticket_key_hmac_, 1282 sizeof(sc->ticket_key_hmac_), 1283 EVP_sha256(), 1284 nullptr) <= 0) { 1285 return -1; 1286 } 1287 return 1; 1288 } 1289 1290 if (memcmp(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) != 0) { 1291 // The ticket key name does not match. Discard the ticket. 1292 return 0; 1293 } 1294 1295 if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_, 1296 iv) <= 0 || 1297 HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_), 1298 EVP_sha256(), nullptr) <= 0) { 1299 return -1; 1300 } 1301 return 1; 1302} 1303 1304void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) { 1305 SecureContext* sc; 1306 ASSIGN_OR_RETURN_UNWRAP(&sc, info.This()); 1307 Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get()); 1308 info.GetReturnValue().Set(ext); 1309} 1310 1311template <bool primary> 1312void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) { 1313 SecureContext* wrap; 1314 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); 1315 Environment* env = wrap->env(); 1316 X509* cert; 1317 1318 if (primary) 1319 cert = wrap->cert_.get(); 1320 else 1321 cert = wrap->issuer_.get(); 1322 if (cert == nullptr) 1323 return args.GetReturnValue().SetNull(); 1324 1325 int size = i2d_X509(cert, nullptr); 1326 Local<Object> buff; 1327 if (!Buffer::New(env, size).ToLocal(&buff)) 1328 return; 1329 unsigned char* serialized = reinterpret_cast<unsigned char*>( 1330 Buffer::Data(buff)); 1331 i2d_X509(cert, &serialized); 1332 1333 args.GetReturnValue().Set(buff); 1334} 1335 1336namespace { 1337unsigned long AddCertsFromFile( // NOLINT(runtime/int) 1338 X509_STORE* store, 1339 const char* file) { 1340 ERR_clear_error(); 1341 MarkPopErrorOnReturn mark_pop_error_on_return; 1342 1343 BIOPointer bio(BIO_new_file(file, "r")); 1344 if (!bio) 1345 return ERR_get_error(); 1346 1347 while (X509Pointer x509 = X509Pointer(PEM_read_bio_X509( 1348 bio.get(), nullptr, NoPasswordCallback, nullptr))) { 1349 X509_STORE_add_cert(store, x509.get()); 1350 } 1351 1352 unsigned long err = ERR_peek_error(); // NOLINT(runtime/int) 1353 // Ignore error if its EOF/no start line found. 1354 if (ERR_GET_LIB(err) == ERR_LIB_PEM && 1355 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { 1356 return 0; 1357 } 1358 1359 return err; 1360} 1361} // namespace 1362 1363// UseExtraCaCerts is called only once at the start of the Node.js process. 1364void UseExtraCaCerts(const std::string& file) { 1365 if (file.empty()) return; 1366 ClearErrorOnReturn clear_error_on_return; 1367 X509_STORE* store = GetOrCreateRootCertStore(); 1368 if (auto err = AddCertsFromFile(store, file.c_str())) { 1369 char buf[256]; 1370 ERR_error_string_n(err, buf, sizeof(buf)); 1371 fprintf(stderr, 1372 "Warning: Ignoring extra certs from `%s`, load failed: %s\n", 1373 file.c_str(), 1374 buf); 1375 } else { 1376 extra_root_certs_loaded = true; 1377 } 1378} 1379 1380// Exposed to JavaScript strictly for testing purposes. 1381void IsExtraRootCertsFileLoaded( 1382 const FunctionCallbackInfo<Value>& args) { 1383 return args.GetReturnValue().Set(extra_root_certs_loaded); 1384} 1385 1386} // namespace crypto 1387} // namespace node 1388