1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 #include "node_crypto.h"
23 #include "node_buffer.h"
24 #include "node_crypto_bio.h"
25 #include "node_crypto_common.h"
26 #include "node_crypto_clienthello-inl.h"
27 #include "node_crypto_groups.h"
28 #include "node_errors.h"
29 #include "node_mutex.h"
30 #include "node_process.h"
31 #include "tls_wrap.h" // TLSWrap
32
33 #include "async_wrap-inl.h"
34 #include "base_object-inl.h"
35 #include "env-inl.h"
36 #include "memory_tracker-inl.h"
37 #include "string_bytes.h"
38 #include "threadpoolwork-inl.h"
39 #include "util-inl.h"
40 #include "v8.h"
41
42 #include <openssl/ec.h>
43 #include <openssl/ecdh.h>
44 #ifndef OPENSSL_NO_ENGINE
45 # include <openssl/engine.h>
46 #endif // !OPENSSL_NO_ENGINE
47 #include <openssl/evp.h>
48 #include <openssl/pem.h>
49 #include <openssl/x509v3.h>
50 #include <openssl/hmac.h>
51 #include <openssl/rand.h>
52 #include <openssl/pkcs12.h>
53
54 #include <cerrno>
55 #include <climits> // INT_MAX
56 #include <cstring>
57
58 #include <algorithm>
59 #include <memory>
60 #include <utility>
61 #include <vector>
62
63 namespace node {
64 namespace crypto {
65
66 using node::THROW_ERR_TLS_INVALID_PROTOCOL_METHOD;
67
68 using v8::Array;
69 using v8::ArrayBufferView;
70 using v8::Boolean;
71 using v8::ConstructorBehavior;
72 using v8::Context;
73 using v8::DontDelete;
74 using v8::Exception;
75 using v8::External;
76 using v8::False;
77 using v8::Function;
78 using v8::FunctionCallback;
79 using v8::FunctionCallbackInfo;
80 using v8::FunctionTemplate;
81 using v8::HandleScope;
82 using v8::Int32;
83 using v8::Integer;
84 using v8::Isolate;
85 using v8::Just;
86 using v8::Local;
87 using v8::Maybe;
88 using v8::MaybeLocal;
89 using v8::NewStringType;
90 using v8::Nothing;
91 using v8::Null;
92 using v8::Object;
93 using v8::PropertyAttribute;
94 using v8::ReadOnly;
95 using v8::SideEffectType;
96 using v8::Signature;
97 using v8::String;
98 using v8::Uint32;
99 using v8::Undefined;
100 using v8::Value;
101
102 #ifdef OPENSSL_NO_OCB
103 # define IS_OCB_MODE(mode) false
104 #else
105 # define IS_OCB_MODE(mode) ((mode) == EVP_CIPH_OCB_MODE)
106 #endif
107
108 static const char* const root_certs[] = {
109 #include "node_root_certs.h" // NOLINT(build/include_order)
110 };
111
112 static const char system_cert_path[] = NODE_OPENSSL_SYSTEM_CERT_PATH;
113
114 static X509_STORE* root_cert_store;
115
116 static bool extra_root_certs_loaded = false;
117
118 // Just to generate static methods
119 template void SSLWrap<TLSWrap>::AddMethods(Environment* env,
120 Local<FunctionTemplate> t);
121 template void SSLWrap<TLSWrap>::ConfigureSecureContext(SecureContext* sc);
122 template int SSLWrap<TLSWrap>::SetCACerts(SecureContext* sc);
123 template void SSLWrap<TLSWrap>::MemoryInfo(MemoryTracker* tracker) const;
124 template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
125 SSL* s,
126 const unsigned char* key,
127 int len,
128 int* copy);
129 template int SSLWrap<TLSWrap>::NewSessionCallback(SSL* s,
130 SSL_SESSION* sess);
131 template void SSLWrap<TLSWrap>::KeylogCallback(const SSL* s,
132 const char* line);
133 template void SSLWrap<TLSWrap>::OnClientHello(
134 void* arg,
135 const ClientHelloParser::ClientHello& hello);
136 template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void* arg);
137 template void SSLWrap<TLSWrap>::DestroySSL();
138 template int SSLWrap<TLSWrap>::SSLCertCallback(SSL* s, void* arg);
139 template void SSLWrap<TLSWrap>::WaitForCertCb(CertCb cb, void* arg);
140 template int SSLWrap<TLSWrap>::SelectALPNCallback(
141 SSL* s,
142 const unsigned char** out,
143 unsigned char* outlen,
144 const unsigned char* in,
145 unsigned int inlen,
146 void* arg);
147
PasswordCallback(char * buf,int size,int rwflag,void * u)148 static int PasswordCallback(char* buf, int size, int rwflag, void* u) {
149 const char* passphrase = static_cast<char*>(u);
150 if (passphrase != nullptr) {
151 size_t buflen = static_cast<size_t>(size);
152 size_t len = strlen(passphrase);
153 if (buflen < len)
154 return -1;
155 memcpy(buf, passphrase, len);
156 return len;
157 }
158
159 return -1;
160 }
161
162 // Loads OpenSSL engine by engine id and returns it. The loaded engine
163 // gets a reference so remember the corresponding call to ENGINE_free.
164 // In case of error the appropriate js exception is scheduled
165 // and nullptr is returned.
166 #ifndef OPENSSL_NO_ENGINE
LoadEngineById(const char * engine_id,char (* errmsg)[1024])167 static ENGINE* LoadEngineById(const char* engine_id, char (*errmsg)[1024]) {
168 MarkPopErrorOnReturn mark_pop_error_on_return;
169
170 ENGINE* engine = ENGINE_by_id(engine_id);
171
172 if (engine == nullptr) {
173 // Engine not found, try loading dynamically.
174 engine = ENGINE_by_id("dynamic");
175 if (engine != nullptr) {
176 if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", engine_id, 0) ||
177 !ENGINE_ctrl_cmd_string(engine, "LOAD", nullptr, 0)) {
178 ENGINE_free(engine);
179 engine = nullptr;
180 }
181 }
182 }
183
184 if (engine == nullptr) {
185 int err = ERR_get_error();
186 if (err != 0) {
187 ERR_error_string_n(err, *errmsg, sizeof(*errmsg));
188 } else {
189 snprintf(*errmsg, sizeof(*errmsg),
190 "Engine \"%s\" was not found", engine_id);
191 }
192 }
193
194 return engine;
195 }
196 #endif // !OPENSSL_NO_ENGINE
197
198 // This callback is used to avoid the default passphrase callback in OpenSSL
199 // which will typically prompt for the passphrase. The prompting is designed
200 // for the OpenSSL CLI, but works poorly for Node.js because it involves
201 // synchronous interaction with the controlling terminal, something we never
202 // want, and use this function to avoid it.
NoPasswordCallback(char * buf,int size,int rwflag,void * u)203 static int NoPasswordCallback(char* buf, int size, int rwflag, void* u) {
204 return 0;
205 }
206
207
208 // namespace node::crypto::error
209 namespace error {
Decorate(Environment * env,Local<Object> obj,unsigned long err)210 Maybe<bool> Decorate(Environment* env, Local<Object> obj,
211 unsigned long err) { // NOLINT(runtime/int)
212 if (err == 0) return Just(true); // No decoration necessary.
213
214 const char* ls = ERR_lib_error_string(err);
215 const char* fs = ERR_func_error_string(err);
216 const char* rs = ERR_reason_error_string(err);
217
218 Isolate* isolate = env->isolate();
219 Local<Context> context = isolate->GetCurrentContext();
220
221 if (ls != nullptr) {
222 if (obj->Set(context, env->library_string(),
223 OneByteString(isolate, ls)).IsNothing()) {
224 return Nothing<bool>();
225 }
226 }
227 if (fs != nullptr) {
228 if (obj->Set(context, env->function_string(),
229 OneByteString(isolate, fs)).IsNothing()) {
230 return Nothing<bool>();
231 }
232 }
233 if (rs != nullptr) {
234 if (obj->Set(context, env->reason_string(),
235 OneByteString(isolate, rs)).IsNothing()) {
236 return Nothing<bool>();
237 }
238
239 // SSL has no API to recover the error name from the number, so we
240 // transform reason strings like "this error" to "ERR_SSL_THIS_ERROR",
241 // which ends up being close to the original error macro name.
242 std::string reason(rs);
243
244 for (auto& c : reason) {
245 if (c == ' ')
246 c = '_';
247 else
248 c = ToUpper(c);
249 }
250
251 #define OSSL_ERROR_CODES_MAP(V) \
252 V(SYS) \
253 V(BN) \
254 V(RSA) \
255 V(DH) \
256 V(EVP) \
257 V(BUF) \
258 V(OBJ) \
259 V(PEM) \
260 V(DSA) \
261 V(X509) \
262 V(ASN1) \
263 V(CONF) \
264 V(CRYPTO) \
265 V(EC) \
266 V(SSL) \
267 V(BIO) \
268 V(PKCS7) \
269 V(X509V3) \
270 V(PKCS12) \
271 V(RAND) \
272 V(DSO) \
273 V(ENGINE) \
274 V(OCSP) \
275 V(UI) \
276 V(COMP) \
277 V(ECDSA) \
278 V(ECDH) \
279 V(OSSL_STORE) \
280 V(FIPS) \
281 V(CMS) \
282 V(TS) \
283 V(HMAC) \
284 V(CT) \
285 V(ASYNC) \
286 V(KDF) \
287 V(SM2) \
288 V(USER) \
289
290 #define V(name) case ERR_LIB_##name: lib = #name "_"; break;
291 const char* lib = "";
292 const char* prefix = "OSSL_";
293 switch (ERR_GET_LIB(err)) { OSSL_ERROR_CODES_MAP(V) }
294 #undef V
295 #undef OSSL_ERROR_CODES_MAP
296 // Don't generate codes like "ERR_OSSL_SSL_".
297 if (lib && strcmp(lib, "SSL_") == 0)
298 prefix = "";
299
300 // All OpenSSL reason strings fit in a single 80-column macro definition,
301 // all prefix lengths are <= 10, and ERR_OSSL_ is 9, so 128 is more than
302 // sufficient.
303 char code[128];
304 snprintf(code, sizeof(code), "ERR_%s%s%s", prefix, lib, reason.c_str());
305
306 if (obj->Set(env->isolate()->GetCurrentContext(),
307 env->code_string(),
308 OneByteString(env->isolate(), code)).IsNothing())
309 return Nothing<bool>();
310 }
311
312 return Just(true);
313 }
314 } // namespace error
315
316
317 struct CryptoErrorVector : public std::vector<std::string> {
Capturenode::crypto::CryptoErrorVector318 inline void Capture() {
319 clear();
320 while (auto err = ERR_get_error()) {
321 char buf[256];
322 ERR_error_string_n(err, buf, sizeof(buf));
323 push_back(buf);
324 }
325 std::reverse(begin(), end());
326 }
327
ToExceptionnode::crypto::CryptoErrorVector328 inline MaybeLocal<Value> ToException(
329 Environment* env,
330 Local<String> exception_string = Local<String>()) const {
331 if (exception_string.IsEmpty()) {
332 CryptoErrorVector copy(*this);
333 if (copy.empty()) copy.push_back("no error"); // But possibly a bug...
334 // Use last element as the error message, everything else goes
335 // into the .opensslErrorStack property on the exception object.
336 auto exception_string =
337 String::NewFromUtf8(env->isolate(), copy.back().data(),
338 NewStringType::kNormal, copy.back().size())
339 .ToLocalChecked();
340 copy.pop_back();
341 return copy.ToException(env, exception_string);
342 }
343
344 Local<Value> exception_v = Exception::Error(exception_string);
345 CHECK(!exception_v.IsEmpty());
346
347 if (!empty()) {
348 CHECK(exception_v->IsObject());
349 Local<Object> exception = exception_v.As<Object>();
350 Maybe<bool> ok = exception->Set(env->context(),
351 env->openssl_error_stack(),
352 ToV8Value(env->context(), *this).ToLocalChecked());
353 if (ok.IsNothing())
354 return MaybeLocal<Value>();
355 }
356
357 return exception_v;
358 }
359 };
360
361
ThrowCryptoError(Environment * env,unsigned long err,const char * message)362 void ThrowCryptoError(Environment* env,
363 unsigned long err, // NOLINT(runtime/int)
364 // Default, only used if there is no SSL `err` which can
365 // be used to create a long-style message string.
366 const char* message) {
367 char message_buffer[128] = {0};
368 if (err != 0 || message == nullptr) {
369 ERR_error_string_n(err, message_buffer, sizeof(message_buffer));
370 message = message_buffer;
371 }
372 HandleScope scope(env->isolate());
373 Local<String> exception_string =
374 String::NewFromUtf8(env->isolate(), message, NewStringType::kNormal)
375 .ToLocalChecked();
376 CryptoErrorVector errors;
377 errors.Capture();
378 Local<Value> exception;
379 if (!errors.ToException(env, exception_string).ToLocal(&exception))
380 return;
381 Local<Object> obj;
382 if (!exception->ToObject(env->context()).ToLocal(&obj))
383 return;
384 if (error::Decorate(env, obj, err).IsNothing())
385 return;
386 env->isolate()->ThrowException(exception);
387 }
388
389
390 // Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.
391 // The entropy pool starts out empty and needs to fill up before the PRNG
392 // can be used securely. Once the pool is filled, it never dries up again;
393 // its contents is stirred and reused when necessary.
394 //
395 // OpenSSL normally fills the pool automatically but not when someone starts
396 // generating random numbers before the pool is full: in that case OpenSSL
397 // keeps lowering the entropy estimate to thwart attackers trying to guess
398 // the initial state of the PRNG.
399 //
400 // When that happens, we will have to wait until enough entropy is available.
401 // That should normally never take longer than a few milliseconds.
402 //
403 // OpenSSL draws from /dev/random and /dev/urandom. While /dev/random may
404 // block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't
405 // block under normal circumstances.
406 //
407 // The only time when /dev/urandom may conceivably block is right after boot,
408 // when the whole system is still low on entropy. That's not something we can
409 // do anything about.
CheckEntropy()410 inline void CheckEntropy() {
411 for (;;) {
412 int status = RAND_status();
413 CHECK_GE(status, 0); // Cannot fail.
414 if (status != 0)
415 break;
416
417 // Give up, RAND_poll() not supported.
418 if (RAND_poll() == 0)
419 break;
420 }
421 }
422
423
EntropySource(unsigned char * buffer,size_t length)424 bool EntropySource(unsigned char* buffer, size_t length) {
425 // Ensure that OpenSSL's PRNG is properly seeded.
426 CheckEntropy();
427 // RAND_bytes() can return 0 to indicate that the entropy data is not truly
428 // random. That's okay, it's still better than V8's stock source of entropy,
429 // which is /dev/urandom on UNIX platforms and the current time on Windows.
430 return RAND_bytes(buffer, length) != -1;
431 }
432
Initialize(Environment * env,Local<Object> target)433 void SecureContext::Initialize(Environment* env, Local<Object> target) {
434 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
435 t->InstanceTemplate()->SetInternalFieldCount(
436 SecureContext::kInternalFieldCount);
437 t->Inherit(BaseObject::GetConstructorTemplate(env));
438 Local<String> secureContextString =
439 FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext");
440 t->SetClassName(secureContextString);
441
442 env->SetProtoMethod(t, "init", Init);
443 env->SetProtoMethod(t, "setKey", SetKey);
444 #ifndef OPENSSL_NO_ENGINE
445 env->SetProtoMethod(t, "setEngineKey", SetEngineKey);
446 #endif // !OPENSSL_NO_ENGINE
447 env->SetProtoMethod(t, "setCert", SetCert);
448 env->SetProtoMethod(t, "addCACert", AddCACert);
449 env->SetProtoMethod(t, "addCRL", AddCRL);
450 env->SetProtoMethod(t, "addRootCerts", AddRootCerts);
451 env->SetProtoMethod(t, "setCipherSuites", SetCipherSuites);
452 env->SetProtoMethod(t, "setCiphers", SetCiphers);
453 env->SetProtoMethod(t, "setSigalgs", SetSigalgs);
454 env->SetProtoMethod(t, "setECDHCurve", SetECDHCurve);
455 env->SetProtoMethod(t, "setDHParam", SetDHParam);
456 env->SetProtoMethod(t, "setMaxProto", SetMaxProto);
457 env->SetProtoMethod(t, "setMinProto", SetMinProto);
458 env->SetProtoMethod(t, "getMaxProto", GetMaxProto);
459 env->SetProtoMethod(t, "getMinProto", GetMinProto);
460 env->SetProtoMethod(t, "setOptions", SetOptions);
461 env->SetProtoMethod(t, "setSessionIdContext", SetSessionIdContext);
462 env->SetProtoMethod(t, "setSessionTimeout", SetSessionTimeout);
463 env->SetProtoMethod(t, "close", Close);
464 env->SetProtoMethod(t, "loadPKCS12", LoadPKCS12);
465 #ifndef OPENSSL_NO_ENGINE
466 env->SetProtoMethod(t, "setClientCertEngine", SetClientCertEngine);
467 #endif // !OPENSSL_NO_ENGINE
468 env->SetProtoMethodNoSideEffect(t, "getTicketKeys", GetTicketKeys);
469 env->SetProtoMethod(t, "setTicketKeys", SetTicketKeys);
470 env->SetProtoMethod(t, "setFreeListLength", SetFreeListLength);
471 env->SetProtoMethod(t, "enableTicketKeyCallback", EnableTicketKeyCallback);
472 env->SetProtoMethodNoSideEffect(t, "getCertificate", GetCertificate<true>);
473 env->SetProtoMethodNoSideEffect(t, "getIssuer", GetCertificate<false>);
474
475 #define SET_INTEGER_CONSTANTS(name, value) \
476 t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), name), \
477 Integer::NewFromUnsigned(env->isolate(), value));
478 SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex);
479 SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex);
480 SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex);
481 SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex);
482 SET_INTEGER_CONSTANTS("kTicketKeyIVIndex", kTicketKeyIVIndex);
483
484 #undef SET_INTEGER_CONSTANTS
485
486 Local<FunctionTemplate> ctx_getter_templ =
487 FunctionTemplate::New(env->isolate(),
488 CtxGetter,
489 env->as_callback_data(),
490 Signature::New(env->isolate(), t));
491
492
493 t->PrototypeTemplate()->SetAccessorProperty(
494 FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
495 ctx_getter_templ,
496 Local<FunctionTemplate>(),
497 static_cast<PropertyAttribute>(ReadOnly | DontDelete));
498
499 target->Set(env->context(), secureContextString,
500 t->GetFunction(env->context()).ToLocalChecked()).Check();
501 env->set_secure_context_constructor_template(t);
502 }
503
SecureContext(Environment * env,Local<Object> wrap)504 SecureContext::SecureContext(Environment* env, Local<Object> wrap)
505 : BaseObject(env, wrap) {
506 MakeWeak();
507 env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
508 }
509
Reset()510 inline void SecureContext::Reset() {
511 if (ctx_ != nullptr) {
512 env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
513 }
514 ctx_.reset();
515 cert_.reset();
516 issuer_.reset();
517 }
518
~SecureContext()519 SecureContext::~SecureContext() {
520 Reset();
521 }
522
New(const FunctionCallbackInfo<Value> & args)523 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
524 Environment* env = Environment::GetCurrent(args);
525 new SecureContext(env, args.This());
526 }
527
528 // A maxVersion of 0 means "any", but OpenSSL may support TLS versions that
529 // Node.js doesn't, so pin the max to what we do support.
530 const int MAX_SUPPORTED_VERSION = TLS1_3_VERSION;
531
Init(const FunctionCallbackInfo<Value> & args)532 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
533 SecureContext* sc;
534 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
535 Environment* env = sc->env();
536
537 CHECK_EQ(args.Length(), 3);
538 CHECK(args[1]->IsInt32());
539 CHECK(args[2]->IsInt32());
540
541 int min_version = args[1].As<Int32>()->Value();
542 int max_version = args[2].As<Int32>()->Value();
543 const SSL_METHOD* method = TLS_method();
544
545 if (max_version == 0)
546 max_version = MAX_SUPPORTED_VERSION;
547
548 if (args[0]->IsString()) {
549 const node::Utf8Value sslmethod(env->isolate(), args[0]);
550
551 // Note that SSLv2 and SSLv3 are disallowed but SSLv23_method and friends
552 // are still accepted. They are OpenSSL's way of saying that all known
553 // protocols below TLS 1.3 are supported unless explicitly disabled (which
554 // we do below for SSLv2 and SSLv3.)
555 if (sslmethod == "SSLv2_method" ||
556 sslmethod == "SSLv2_server_method" ||
557 sslmethod == "SSLv2_client_method") {
558 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled");
559 return;
560 } else if (sslmethod == "SSLv3_method" ||
561 sslmethod == "SSLv3_server_method" ||
562 sslmethod == "SSLv3_client_method") {
563 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv3 methods disabled");
564 return;
565 } else if (sslmethod == "SSLv23_method") {
566 max_version = TLS1_2_VERSION;
567 } else if (sslmethod == "SSLv23_server_method") {
568 max_version = TLS1_2_VERSION;
569 method = TLS_server_method();
570 } else if (sslmethod == "SSLv23_client_method") {
571 max_version = TLS1_2_VERSION;
572 method = TLS_client_method();
573 } else if (sslmethod == "TLS_method") {
574 min_version = 0;
575 max_version = MAX_SUPPORTED_VERSION;
576 } else if (sslmethod == "TLS_server_method") {
577 min_version = 0;
578 max_version = MAX_SUPPORTED_VERSION;
579 method = TLS_server_method();
580 } else if (sslmethod == "TLS_client_method") {
581 min_version = 0;
582 max_version = MAX_SUPPORTED_VERSION;
583 method = TLS_client_method();
584 } else if (sslmethod == "TLSv1_method") {
585 min_version = TLS1_VERSION;
586 max_version = TLS1_VERSION;
587 } else if (sslmethod == "TLSv1_server_method") {
588 min_version = TLS1_VERSION;
589 max_version = TLS1_VERSION;
590 method = TLS_server_method();
591 } else if (sslmethod == "TLSv1_client_method") {
592 min_version = TLS1_VERSION;
593 max_version = TLS1_VERSION;
594 method = TLS_client_method();
595 } else if (sslmethod == "TLSv1_1_method") {
596 min_version = TLS1_1_VERSION;
597 max_version = TLS1_1_VERSION;
598 } else if (sslmethod == "TLSv1_1_server_method") {
599 min_version = TLS1_1_VERSION;
600 max_version = TLS1_1_VERSION;
601 method = TLS_server_method();
602 } else if (sslmethod == "TLSv1_1_client_method") {
603 min_version = TLS1_1_VERSION;
604 max_version = TLS1_1_VERSION;
605 method = TLS_client_method();
606 } else if (sslmethod == "TLSv1_2_method") {
607 min_version = TLS1_2_VERSION;
608 max_version = TLS1_2_VERSION;
609 } else if (sslmethod == "TLSv1_2_server_method") {
610 min_version = TLS1_2_VERSION;
611 max_version = TLS1_2_VERSION;
612 method = TLS_server_method();
613 } else if (sslmethod == "TLSv1_2_client_method") {
614 min_version = TLS1_2_VERSION;
615 max_version = TLS1_2_VERSION;
616 method = TLS_client_method();
617 } else {
618 const std::string msg("Unknown method: ");
619 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, (msg + * sslmethod).c_str());
620 return;
621 }
622 }
623
624 sc->ctx_.reset(SSL_CTX_new(method));
625 SSL_CTX_set_app_data(sc->ctx_.get(), sc);
626
627 // Disable SSLv2 in the case when method == TLS_method() and the
628 // cipher list contains SSLv2 ciphers (not the default, should be rare.)
629 // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
630 // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
631 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv2);
632 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv3);
633
634 // Enable automatic cert chaining. This is enabled by default in OpenSSL, but
635 // disabled by default in BoringSSL. Enable it explicitly to make the
636 // behavior match when Node is built with BoringSSL.
637 SSL_CTX_clear_mode(sc->ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
638
639 // SSL session cache configuration
640 SSL_CTX_set_session_cache_mode(sc->ctx_.get(),
641 SSL_SESS_CACHE_CLIENT |
642 SSL_SESS_CACHE_SERVER |
643 SSL_SESS_CACHE_NO_INTERNAL |
644 SSL_SESS_CACHE_NO_AUTO_CLEAR);
645
646 SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version);
647 SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
648
649 // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
650 // exposed in the public API. To retain compatibility, install a callback
651 // which restores the old algorithm.
652 if (RAND_bytes(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) <= 0 ||
653 RAND_bytes(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)) <= 0 ||
654 RAND_bytes(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)) <= 0) {
655 return env->ThrowError("Error generating ticket keys");
656 }
657 SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
658 }
659
660
661 // Takes a string or buffer and loads it into a BIO.
662 // Caller responsible for BIO_free_all-ing the returned object.
LoadBIO(Environment * env,Local<Value> v)663 static BIOPointer LoadBIO(Environment* env, Local<Value> v) {
664 HandleScope scope(env->isolate());
665
666 if (v->IsString()) {
667 const node::Utf8Value s(env->isolate(), v);
668 return NodeBIO::NewFixed(*s, s.length());
669 }
670
671 if (v->IsArrayBufferView()) {
672 ArrayBufferViewContents<char> buf(v.As<ArrayBufferView>());
673 return NodeBIO::NewFixed(buf.data(), buf.length());
674 }
675
676 return nullptr;
677 }
678
679
SetKey(const FunctionCallbackInfo<Value> & args)680 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
681 Environment* env = Environment::GetCurrent(args);
682
683 SecureContext* sc;
684 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
685
686 unsigned int len = args.Length();
687 if (len < 1) {
688 return THROW_ERR_MISSING_ARGS(env, "Private key argument is mandatory");
689 }
690
691 if (len > 2) {
692 return env->ThrowError("Only private key and pass phrase are expected");
693 }
694
695 if (len == 2) {
696 if (args[1]->IsUndefined() || args[1]->IsNull())
697 len = 1;
698 else
699 THROW_AND_RETURN_IF_NOT_STRING(env, args[1], "Pass phrase");
700 }
701
702 BIOPointer bio(LoadBIO(env, args[0]));
703 if (!bio)
704 return;
705
706 node::Utf8Value passphrase(env->isolate(), args[1]);
707
708 EVPKeyPointer key(
709 PEM_read_bio_PrivateKey(bio.get(),
710 nullptr,
711 PasswordCallback,
712 *passphrase));
713
714 if (!key) {
715 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
716 return ThrowCryptoError(env, err, "PEM_read_bio_PrivateKey");
717 }
718
719 int rv = SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get());
720
721 if (!rv) {
722 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
723 return ThrowCryptoError(env, err, "SSL_CTX_use_PrivateKey");
724 }
725 }
726
SetSigalgs(const FunctionCallbackInfo<Value> & args)727 void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) {
728 SecureContext* sc;
729 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
730 Environment* env = sc->env();
731 ClearErrorOnReturn clear_error_on_return;
732
733 CHECK_EQ(args.Length(), 1);
734 CHECK(args[0]->IsString());
735
736 const node::Utf8Value sigalgs(env->isolate(), args[0]);
737
738 int rv = SSL_CTX_set1_sigalgs_list(sc->ctx_.get(), *sigalgs);
739
740 if (rv == 0) {
741 return ThrowCryptoError(env, ERR_get_error());
742 }
743 }
744
745 #ifndef OPENSSL_NO_ENGINE
746 // Helpers for the smart pointer.
ENGINE_free_fn(ENGINE * engine)747 void ENGINE_free_fn(ENGINE* engine) { ENGINE_free(engine); }
748
ENGINE_finish_and_free_fn(ENGINE * engine)749 void ENGINE_finish_and_free_fn(ENGINE* engine) {
750 ENGINE_finish(engine);
751 ENGINE_free(engine);
752 }
753
SetEngineKey(const FunctionCallbackInfo<Value> & args)754 void SecureContext::SetEngineKey(const FunctionCallbackInfo<Value>& args) {
755 Environment* env = Environment::GetCurrent(args);
756
757 SecureContext* sc;
758 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
759
760 CHECK_EQ(args.Length(), 2);
761
762 char errmsg[1024];
763 const node::Utf8Value engine_id(env->isolate(), args[1]);
764 std::unique_ptr<ENGINE, std::function<void(ENGINE*)>> e =
765 { LoadEngineById(*engine_id, &errmsg),
766 ENGINE_free_fn };
767 if (e.get() == nullptr) {
768 return env->ThrowError(errmsg);
769 }
770
771 if (!ENGINE_init(e.get())) {
772 return env->ThrowError("ENGINE_init");
773 }
774
775 e.get_deleter() = ENGINE_finish_and_free_fn;
776
777 const node::Utf8Value key_name(env->isolate(), args[0]);
778 EVPKeyPointer key(ENGINE_load_private_key(e.get(), *key_name,
779 nullptr, nullptr));
780
781 if (!key) {
782 return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key");
783 }
784
785 int rv = SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get());
786
787 if (rv == 0) {
788 return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
789 }
790
791 sc->private_key_engine_ = std::move(e);
792 }
793 #endif // !OPENSSL_NO_ENGINE
794
SSL_CTX_use_certificate_chain(SSL_CTX * ctx,X509Pointer && x,STACK_OF (X509)* extra_certs,X509Pointer * cert,X509Pointer * issuer_)795 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
796 X509Pointer&& x,
797 STACK_OF(X509)* extra_certs,
798 X509Pointer* cert,
799 X509Pointer* issuer_) {
800 CHECK(!*issuer_);
801 CHECK(!*cert);
802 X509* issuer = nullptr;
803
804 int ret = SSL_CTX_use_certificate(ctx, x.get());
805
806 if (ret) {
807 // If we could set up our certificate, now proceed to
808 // the CA certificates.
809 SSL_CTX_clear_extra_chain_certs(ctx);
810
811 for (int i = 0; i < sk_X509_num(extra_certs); i++) {
812 X509* ca = sk_X509_value(extra_certs, i);
813
814 // NOTE: Increments reference count on `ca`
815 if (!SSL_CTX_add1_chain_cert(ctx, ca)) {
816 ret = 0;
817 issuer = nullptr;
818 break;
819 }
820 // Note that we must not free r if it was successfully
821 // added to the chain (while we must free the main
822 // certificate, since its reference count is increased
823 // by SSL_CTX_use_certificate).
824
825 // Find issuer
826 if (issuer != nullptr || X509_check_issued(ca, x.get()) != X509_V_OK)
827 continue;
828
829 issuer = ca;
830 }
831 }
832
833 // Try getting issuer from a cert store
834 if (ret) {
835 if (issuer == nullptr) {
836 ret = SSL_CTX_get_issuer(ctx, x.get(), &issuer);
837 ret = ret < 0 ? 0 : 1;
838 // NOTE: get_cert_store doesn't increment reference count,
839 // no need to free `store`
840 } else {
841 // Increment issuer reference count
842 issuer = X509_dup(issuer);
843 if (issuer == nullptr) {
844 ret = 0;
845 }
846 }
847 }
848
849 issuer_->reset(issuer);
850
851 if (ret && x != nullptr) {
852 cert->reset(X509_dup(x.get()));
853 if (!*cert)
854 ret = 0;
855 }
856 return ret;
857 }
858
859
860 // Read a file that contains our certificate in "PEM" format,
861 // possibly followed by a sequence of CA certificates that should be
862 // sent to the peer in the Certificate message.
863 //
864 // Taken from OpenSSL - edited for style.
SSL_CTX_use_certificate_chain(SSL_CTX * ctx,BIOPointer && in,X509Pointer * cert,X509Pointer * issuer)865 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
866 BIOPointer&& in,
867 X509Pointer* cert,
868 X509Pointer* issuer) {
869 // Just to ensure that `ERR_peek_last_error` below will return only errors
870 // that we are interested in
871 ERR_clear_error();
872
873 X509Pointer x(
874 PEM_read_bio_X509_AUX(in.get(), nullptr, NoPasswordCallback, nullptr));
875
876 if (!x)
877 return 0;
878
879 unsigned long err = 0; // NOLINT(runtime/int)
880
881 StackOfX509 extra_certs(sk_X509_new_null());
882 if (!extra_certs)
883 return 0;
884
885 while (X509Pointer extra {PEM_read_bio_X509(in.get(),
886 nullptr,
887 NoPasswordCallback,
888 nullptr)}) {
889 if (sk_X509_push(extra_certs.get(), extra.get())) {
890 extra.release();
891 continue;
892 }
893
894 return 0;
895 }
896
897 // When the while loop ends, it's usually just EOF.
898 err = ERR_peek_last_error();
899 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
900 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
901 ERR_clear_error();
902 } else {
903 // some real error
904 return 0;
905 }
906
907 return SSL_CTX_use_certificate_chain(ctx,
908 std::move(x),
909 extra_certs.get(),
910 cert,
911 issuer);
912 }
913
914
SetCert(const FunctionCallbackInfo<Value> & args)915 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
916 Environment* env = Environment::GetCurrent(args);
917
918 SecureContext* sc;
919 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
920
921 if (args.Length() != 1) {
922 return THROW_ERR_MISSING_ARGS(env, "Certificate argument is mandatory");
923 }
924
925 BIOPointer bio(LoadBIO(env, args[0]));
926 if (!bio)
927 return;
928
929 sc->cert_.reset();
930 sc->issuer_.reset();
931
932 int rv = SSL_CTX_use_certificate_chain(sc->ctx_.get(),
933 std::move(bio),
934 &sc->cert_,
935 &sc->issuer_);
936
937 if (!rv) {
938 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
939 return ThrowCryptoError(env, err, "SSL_CTX_use_certificate_chain");
940 }
941 }
942
943
NewRootCertStore()944 static X509_STORE* NewRootCertStore() {
945 static std::vector<X509*> root_certs_vector;
946 static Mutex root_certs_vector_mutex;
947 Mutex::ScopedLock lock(root_certs_vector_mutex);
948
949 if (root_certs_vector.empty()) {
950 for (size_t i = 0; i < arraysize(root_certs); i++) {
951 X509* x509 =
952 PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i],
953 strlen(root_certs[i])).get(),
954 nullptr, // no re-use of X509 structure
955 NoPasswordCallback,
956 nullptr); // no callback data
957
958 // Parse errors from the built-in roots are fatal.
959 CHECK_NOT_NULL(x509);
960
961 root_certs_vector.push_back(x509);
962 }
963 }
964
965 X509_STORE* store = X509_STORE_new();
966 if (*system_cert_path != '\0') {
967 X509_STORE_load_locations(store, system_cert_path, nullptr);
968 }
969
970 Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex);
971 if (per_process::cli_options->ssl_openssl_cert_store) {
972 X509_STORE_set_default_paths(store);
973 } else {
974 for (X509* cert : root_certs_vector) {
975 X509_up_ref(cert);
976 X509_STORE_add_cert(store, cert);
977 }
978 }
979
980 return store;
981 }
982
983
GetRootCertificates(const FunctionCallbackInfo<Value> & args)984 void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
985 Environment* env = Environment::GetCurrent(args);
986 Local<Value> result[arraysize(root_certs)];
987
988 for (size_t i = 0; i < arraysize(root_certs); i++) {
989 if (!String::NewFromOneByte(
990 env->isolate(),
991 reinterpret_cast<const uint8_t*>(root_certs[i]),
992 NewStringType::kNormal).ToLocal(&result[i])) {
993 return;
994 }
995 }
996
997 args.GetReturnValue().Set(
998 Array::New(env->isolate(), result, arraysize(root_certs)));
999 }
1000
1001
AddCACert(const FunctionCallbackInfo<Value> & args)1002 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
1003 Environment* env = Environment::GetCurrent(args);
1004
1005 SecureContext* sc;
1006 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1007 ClearErrorOnReturn clear_error_on_return;
1008
1009 if (args.Length() != 1) {
1010 return THROW_ERR_MISSING_ARGS(env, "CA certificate argument is mandatory");
1011 }
1012
1013 BIOPointer bio(LoadBIO(env, args[0]));
1014 if (!bio)
1015 return;
1016
1017 X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
1018 while (X509* x509 = PEM_read_bio_X509_AUX(
1019 bio.get(), nullptr, NoPasswordCallback, nullptr)) {
1020 if (cert_store == root_cert_store) {
1021 cert_store = NewRootCertStore();
1022 SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
1023 }
1024 X509_STORE_add_cert(cert_store, x509);
1025 SSL_CTX_add_client_CA(sc->ctx_.get(), x509);
1026 X509_free(x509);
1027 }
1028 }
1029
1030
AddCRL(const FunctionCallbackInfo<Value> & args)1031 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
1032 Environment* env = Environment::GetCurrent(args);
1033
1034 SecureContext* sc;
1035 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1036
1037 if (args.Length() != 1) {
1038 return THROW_ERR_MISSING_ARGS(env, "CRL argument is mandatory");
1039 }
1040
1041 ClearErrorOnReturn clear_error_on_return;
1042
1043 BIOPointer bio(LoadBIO(env, args[0]));
1044 if (!bio)
1045 return;
1046
1047 DeleteFnPtr<X509_CRL, X509_CRL_free> crl(
1048 PEM_read_bio_X509_CRL(bio.get(), nullptr, NoPasswordCallback, nullptr));
1049
1050 if (!crl)
1051 return env->ThrowError("Failed to parse CRL");
1052
1053 X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
1054 if (cert_store == root_cert_store) {
1055 cert_store = NewRootCertStore();
1056 SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
1057 }
1058
1059 X509_STORE_add_crl(cert_store, crl.get());
1060 X509_STORE_set_flags(cert_store,
1061 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1062 }
1063
1064
AddCertsFromFile(X509_STORE * store,const char * file)1065 static unsigned long AddCertsFromFile( // NOLINT(runtime/int)
1066 X509_STORE* store,
1067 const char* file) {
1068 ERR_clear_error();
1069 MarkPopErrorOnReturn mark_pop_error_on_return;
1070
1071 BIOPointer bio(BIO_new_file(file, "r"));
1072 if (!bio)
1073 return ERR_get_error();
1074
1075 while (X509* x509 =
1076 PEM_read_bio_X509(bio.get(), nullptr, NoPasswordCallback, nullptr)) {
1077 X509_STORE_add_cert(store, x509);
1078 X509_free(x509);
1079 }
1080
1081 unsigned long err = ERR_peek_error(); // NOLINT(runtime/int)
1082 // Ignore error if its EOF/no start line found.
1083 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
1084 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
1085 return 0;
1086 }
1087
1088 return err;
1089 }
1090
1091
UseExtraCaCerts(const std::string & file)1092 void UseExtraCaCerts(const std::string& file) {
1093 ClearErrorOnReturn clear_error_on_return;
1094
1095 if (root_cert_store == nullptr) {
1096 root_cert_store = NewRootCertStore();
1097
1098 if (!file.empty()) {
1099 unsigned long err = AddCertsFromFile( // NOLINT(runtime/int)
1100 root_cert_store,
1101 file.c_str());
1102 if (err) {
1103 fprintf(stderr,
1104 "Warning: Ignoring extra certs from `%s`, load failed: %s\n",
1105 file.c_str(),
1106 ERR_error_string(err, nullptr));
1107 } else {
1108 extra_root_certs_loaded = true;
1109 }
1110 }
1111 }
1112 }
1113
1114
IsExtraRootCertsFileLoaded(const FunctionCallbackInfo<Value> & args)1115 static void IsExtraRootCertsFileLoaded(
1116 const FunctionCallbackInfo<Value>& args) {
1117 return args.GetReturnValue().Set(extra_root_certs_loaded);
1118 }
1119
1120
AddRootCerts(const FunctionCallbackInfo<Value> & args)1121 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
1122 SecureContext* sc;
1123 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1124 ClearErrorOnReturn clear_error_on_return;
1125
1126 if (root_cert_store == nullptr) {
1127 root_cert_store = NewRootCertStore();
1128 }
1129
1130 // Increment reference count so global store is not deleted along with CTX.
1131 X509_STORE_up_ref(root_cert_store);
1132 SSL_CTX_set_cert_store(sc->ctx_.get(), root_cert_store);
1133 }
1134
1135
SetCipherSuites(const FunctionCallbackInfo<Value> & args)1136 void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
1137 // BoringSSL doesn't allow API config of TLS1.3 cipher suites.
1138 #ifndef OPENSSL_IS_BORINGSSL
1139 SecureContext* sc;
1140 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1141 Environment* env = sc->env();
1142 ClearErrorOnReturn clear_error_on_return;
1143
1144 CHECK_EQ(args.Length(), 1);
1145 CHECK(args[0]->IsString());
1146
1147 const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
1148 if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers)) {
1149 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
1150 return ThrowCryptoError(env, err, "Failed to set ciphers");
1151 }
1152 #endif
1153 }
1154
1155
SetCiphers(const FunctionCallbackInfo<Value> & args)1156 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
1157 SecureContext* sc;
1158 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1159 Environment* env = sc->env();
1160 ClearErrorOnReturn clear_error_on_return;
1161
1162 CHECK_EQ(args.Length(), 1);
1163 CHECK(args[0]->IsString());
1164
1165 const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
1166 if (!SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) {
1167 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
1168
1169 if (strlen(*ciphers) == 0 && ERR_GET_REASON(err) == SSL_R_NO_CIPHER_MATCH) {
1170 // TLS1.2 ciphers were deliberately cleared, so don't consider
1171 // SSL_R_NO_CIPHER_MATCH to be an error (this is how _set_cipher_suites()
1172 // works). If the user actually sets a value (like "no-such-cipher"), then
1173 // that's actually an error.
1174 return;
1175 }
1176 return ThrowCryptoError(env, err, "Failed to set ciphers");
1177 }
1178 }
1179
1180
SetECDHCurve(const FunctionCallbackInfo<Value> & args)1181 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
1182 SecureContext* sc;
1183 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1184 Environment* env = sc->env();
1185
1186 if (args.Length() != 1)
1187 return THROW_ERR_MISSING_ARGS(env, "ECDH curve name argument is mandatory");
1188
1189 THROW_AND_RETURN_IF_NOT_STRING(env, args[0], "ECDH curve name");
1190
1191 node::Utf8Value curve(env->isolate(), args[0]);
1192
1193 if (strcmp(*curve, "auto") == 0)
1194 return;
1195
1196 if (!SSL_CTX_set1_curves_list(sc->ctx_.get(), *curve))
1197 return env->ThrowError("Failed to set ECDH curve");
1198 }
1199
1200
SetDHParam(const FunctionCallbackInfo<Value> & args)1201 void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
1202 SecureContext* sc;
1203 ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
1204 Environment* env = sc->env();
1205 ClearErrorOnReturn clear_error_on_return;
1206
1207 // Auto DH is not supported in openssl 1.0.1, so dhparam needs
1208 // to be specified explicitly
1209 if (args.Length() != 1)
1210 return THROW_ERR_MISSING_ARGS(env, "DH argument is mandatory");
1211
1212 DHPointer dh;
1213 {
1214 BIOPointer bio(LoadBIO(env, args[0]));
1215 if (!bio)
1216 return;
1217
1218 dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr));
1219 }
1220
1221 // Invalid dhparam is silently discarded and DHE is no longer used.
1222 if (!dh)
1223 return;
1224
1225 const BIGNUM* p;
1226 DH_get0_pqg(dh.get(), &p, nullptr, nullptr);
1227 const int size = BN_num_bits(p);
1228 if (size < 1024) {
1229 return THROW_ERR_INVALID_ARG_VALUE(
1230 env, "DH parameter is less than 1024 bits");
1231 } else if (size < 2048) {
1232 args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(
1233 env->isolate(), "DH parameter is less than 2048 bits"));
1234 }
1235
1236 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_SINGLE_DH_USE);
1237 int r = SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get());
1238
1239 if (!r)
1240 return env->ThrowTypeError("Error setting temp DH parameter");
1241 }
1242
1243
SetMinProto(const FunctionCallbackInfo<Value> & args)1244 void SecureContext::SetMinProto(const FunctionCallbackInfo<Value>& args) {
1245 SecureContext* sc;
1246 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1247
1248 CHECK_EQ(args.Length(), 1);
1249 CHECK(args[0]->IsInt32());
1250
1251 int version = args[0].As<Int32>()->Value();
1252
1253 CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), version));
1254 }
1255
1256
SetMaxProto(const FunctionCallbackInfo<Value> & args)1257 void SecureContext::SetMaxProto(const FunctionCallbackInfo<Value>& args) {
1258 SecureContext* sc;
1259 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1260
1261 CHECK_EQ(args.Length(), 1);
1262 CHECK(args[0]->IsInt32());
1263
1264 int version = args[0].As<Int32>()->Value();
1265
1266 CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), version));
1267 }
1268
1269
GetMinProto(const FunctionCallbackInfo<Value> & args)1270 void SecureContext::GetMinProto(const FunctionCallbackInfo<Value>& args) {
1271 SecureContext* sc;
1272 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1273
1274 CHECK_EQ(args.Length(), 0);
1275
1276 long version = // NOLINT(runtime/int)
1277 SSL_CTX_get_min_proto_version(sc->ctx_.get());
1278 args.GetReturnValue().Set(static_cast<uint32_t>(version));
1279 }
1280
1281
GetMaxProto(const FunctionCallbackInfo<Value> & args)1282 void SecureContext::GetMaxProto(const FunctionCallbackInfo<Value>& args) {
1283 SecureContext* sc;
1284 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1285
1286 CHECK_EQ(args.Length(), 0);
1287
1288 long version = // NOLINT(runtime/int)
1289 SSL_CTX_get_max_proto_version(sc->ctx_.get());
1290 args.GetReturnValue().Set(static_cast<uint32_t>(version));
1291 }
1292
1293
SetOptions(const FunctionCallbackInfo<Value> & args)1294 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
1295 SecureContext* sc;
1296 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1297 int64_t val;
1298
1299 if (args.Length() != 1 ||
1300 !args[0]->IntegerValue(args.GetIsolate()->GetCurrentContext()).To(&val)) {
1301 return THROW_ERR_INVALID_ARG_TYPE(
1302 sc->env(), "Options must be an integer value");
1303 }
1304
1305 SSL_CTX_set_options(sc->ctx_.get(),
1306 static_cast<long>(val)); // NOLINT(runtime/int)
1307 }
1308
1309
SetSessionIdContext(const FunctionCallbackInfo<Value> & args)1310 void SecureContext::SetSessionIdContext(
1311 const FunctionCallbackInfo<Value>& args) {
1312 SecureContext* sc;
1313 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1314 Environment* env = sc->env();
1315
1316 if (args.Length() != 1) {
1317 return THROW_ERR_MISSING_ARGS(
1318 env, "Session ID context argument is mandatory");
1319 }
1320
1321 THROW_AND_RETURN_IF_NOT_STRING(env, args[0], "Session ID context");
1322
1323 const node::Utf8Value sessionIdContext(args.GetIsolate(), args[0]);
1324 const unsigned char* sid_ctx =
1325 reinterpret_cast<const unsigned char*>(*sessionIdContext);
1326 unsigned int sid_ctx_len = sessionIdContext.length();
1327
1328 int r = SSL_CTX_set_session_id_context(sc->ctx_.get(), sid_ctx, sid_ctx_len);
1329 if (r == 1)
1330 return;
1331
1332 BUF_MEM* mem;
1333 Local<String> message;
1334
1335 BIOPointer bio(BIO_new(BIO_s_mem()));
1336 if (!bio) {
1337 message = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
1338 "SSL_CTX_set_session_id_context error");
1339 } else {
1340 ERR_print_errors(bio.get());
1341 BIO_get_mem_ptr(bio.get(), &mem);
1342 message = OneByteString(args.GetIsolate(), mem->data, mem->length);
1343 }
1344
1345 args.GetIsolate()->ThrowException(Exception::TypeError(message));
1346 }
1347
1348
SetSessionTimeout(const FunctionCallbackInfo<Value> & args)1349 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
1350 SecureContext* sc;
1351 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1352
1353 if (args.Length() != 1 || !args[0]->IsInt32()) {
1354 return THROW_ERR_INVALID_ARG_TYPE(
1355 sc->env(), "Session timeout must be a 32-bit integer");
1356 }
1357
1358 int32_t sessionTimeout = args[0].As<Int32>()->Value();
1359 SSL_CTX_set_timeout(sc->ctx_.get(), sessionTimeout);
1360 }
1361
1362
Close(const FunctionCallbackInfo<Value> & args)1363 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
1364 SecureContext* sc;
1365 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1366 sc->Reset();
1367 }
1368
1369
1370 // Takes .pfx or .p12 and password in string or buffer format
LoadPKCS12(const FunctionCallbackInfo<Value> & args)1371 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
1372 Environment* env = Environment::GetCurrent(args);
1373
1374 std::vector<char> pass;
1375 bool ret = false;
1376
1377 SecureContext* sc;
1378 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1379 ClearErrorOnReturn clear_error_on_return;
1380
1381 if (args.Length() < 1) {
1382 return THROW_ERR_MISSING_ARGS(env, "PFX certificate argument is mandatory");
1383 }
1384
1385 BIOPointer in(LoadBIO(env, args[0]));
1386 if (!in)
1387 return env->ThrowError("Unable to load BIO");
1388
1389 if (args.Length() >= 2) {
1390 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[1], "Pass phrase");
1391 Local<ArrayBufferView> abv = args[1].As<ArrayBufferView>();
1392 size_t passlen = abv->ByteLength();
1393 pass.resize(passlen + 1);
1394 abv->CopyContents(pass.data(), passlen);
1395 pass[passlen] = '\0';
1396 }
1397
1398 // Free previous certs
1399 sc->issuer_.reset();
1400 sc->cert_.reset();
1401
1402 X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
1403
1404 DeleteFnPtr<PKCS12, PKCS12_free> p12;
1405 EVPKeyPointer pkey;
1406 X509Pointer cert;
1407 StackOfX509 extra_certs;
1408
1409 PKCS12* p12_ptr = nullptr;
1410 EVP_PKEY* pkey_ptr = nullptr;
1411 X509* cert_ptr = nullptr;
1412 STACK_OF(X509)* extra_certs_ptr = nullptr;
1413 if (d2i_PKCS12_bio(in.get(), &p12_ptr) &&
1414 (p12.reset(p12_ptr), true) && // Move ownership to the smart pointer.
1415 PKCS12_parse(p12.get(), pass.data(),
1416 &pkey_ptr,
1417 &cert_ptr,
1418 &extra_certs_ptr) &&
1419 (pkey.reset(pkey_ptr), cert.reset(cert_ptr),
1420 extra_certs.reset(extra_certs_ptr), true) && // Move ownership.
1421 SSL_CTX_use_certificate_chain(sc->ctx_.get(),
1422 std::move(cert),
1423 extra_certs.get(),
1424 &sc->cert_,
1425 &sc->issuer_) &&
1426 SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) {
1427 // Add CA certs too
1428 for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) {
1429 X509* ca = sk_X509_value(extra_certs.get(), i);
1430
1431 if (cert_store == root_cert_store) {
1432 cert_store = NewRootCertStore();
1433 SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
1434 }
1435 X509_STORE_add_cert(cert_store, ca);
1436 SSL_CTX_add_client_CA(sc->ctx_.get(), ca);
1437 }
1438 ret = true;
1439 }
1440
1441 if (!ret) {
1442 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
1443 const char* str = ERR_reason_error_string(err);
1444 return env->ThrowError(str);
1445 }
1446 }
1447
1448
1449 #ifndef OPENSSL_NO_ENGINE
SetClientCertEngine(const FunctionCallbackInfo<Value> & args)1450 void SecureContext::SetClientCertEngine(
1451 const FunctionCallbackInfo<Value>& args) {
1452 Environment* env = Environment::GetCurrent(args);
1453 CHECK_EQ(args.Length(), 1);
1454 CHECK(args[0]->IsString());
1455
1456 SecureContext* sc;
1457 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1458
1459 MarkPopErrorOnReturn mark_pop_error_on_return;
1460
1461 // SSL_CTX_set_client_cert_engine does not itself support multiple
1462 // calls by cleaning up before overwriting the client_cert_engine
1463 // internal context variable.
1464 // Instead of trying to fix up this problem we in turn also do not
1465 // support multiple calls to SetClientCertEngine.
1466 if (sc->client_cert_engine_provided_) {
1467 return env->ThrowError(
1468 "Multiple calls to SetClientCertEngine are not allowed");
1469 }
1470
1471 const node::Utf8Value engine_id(env->isolate(), args[0]);
1472 char errmsg[1024];
1473 DeleteFnPtr<ENGINE, ENGINE_free_fn> engine(
1474 LoadEngineById(*engine_id, &errmsg));
1475
1476 if (!engine)
1477 return env->ThrowError(errmsg);
1478
1479 // Note that this takes another reference to `engine`.
1480 int r = SSL_CTX_set_client_cert_engine(sc->ctx_.get(), engine.get());
1481 if (r == 0)
1482 return ThrowCryptoError(env, ERR_get_error());
1483 sc->client_cert_engine_provided_ = true;
1484 }
1485 #endif // !OPENSSL_NO_ENGINE
1486
1487
GetTicketKeys(const FunctionCallbackInfo<Value> & args)1488 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1489 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1490
1491 SecureContext* wrap;
1492 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1493
1494 Local<Object> buff = Buffer::New(wrap->env(), 48).ToLocalChecked();
1495 memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16);
1496 memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16);
1497 memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16);
1498
1499 args.GetReturnValue().Set(buff);
1500 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1501 }
1502
1503
SetTicketKeys(const FunctionCallbackInfo<Value> & args)1504 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1505 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1506 SecureContext* wrap;
1507 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1508 Environment* env = wrap->env();
1509
1510 // TODO(@sam-github) Move type and len check to js, and CHECK() in C++.
1511 if (args.Length() < 1) {
1512 return THROW_ERR_MISSING_ARGS(env, "Ticket keys argument is mandatory");
1513 }
1514
1515 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Ticket keys");
1516 ArrayBufferViewContents<char> buf(args[0].As<ArrayBufferView>());
1517
1518 if (buf.length() != 48) {
1519 return THROW_ERR_INVALID_ARG_VALUE(
1520 env, "Ticket keys length must be 48 bytes");
1521 }
1522
1523 memcpy(wrap->ticket_key_name_, buf.data(), 16);
1524 memcpy(wrap->ticket_key_hmac_, buf.data() + 16, 16);
1525 memcpy(wrap->ticket_key_aes_, buf.data() + 32, 16);
1526
1527 args.GetReturnValue().Set(true);
1528 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1529 }
1530
1531
SetFreeListLength(const FunctionCallbackInfo<Value> & args)1532 void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
1533 }
1534
1535
1536 // Currently, EnableTicketKeyCallback and TicketKeyCallback are only present for
1537 // the regression test in test/parallel/test-https-resume-after-renew.js.
EnableTicketKeyCallback(const FunctionCallbackInfo<Value> & args)1538 void SecureContext::EnableTicketKeyCallback(
1539 const FunctionCallbackInfo<Value>& args) {
1540 SecureContext* wrap;
1541 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1542
1543 SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback);
1544 }
1545
1546
TicketKeyCallback(SSL * ssl,unsigned char * name,unsigned char * iv,EVP_CIPHER_CTX * ectx,HMAC_CTX * hctx,int enc)1547 int SecureContext::TicketKeyCallback(SSL* ssl,
1548 unsigned char* name,
1549 unsigned char* iv,
1550 EVP_CIPHER_CTX* ectx,
1551 HMAC_CTX* hctx,
1552 int enc) {
1553 static const int kTicketPartSize = 16;
1554
1555 SecureContext* sc = static_cast<SecureContext*>(
1556 SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1557
1558 Environment* env = sc->env();
1559 HandleScope handle_scope(env->isolate());
1560 Context::Scope context_scope(env->context());
1561
1562 Local<Value> argv[] = {
1563 Buffer::Copy(env,
1564 reinterpret_cast<char*>(name),
1565 kTicketPartSize).ToLocalChecked(),
1566 Buffer::Copy(env,
1567 reinterpret_cast<char*>(iv),
1568 kTicketPartSize).ToLocalChecked(),
1569 Boolean::New(env->isolate(), enc != 0)
1570 };
1571
1572 Local<Value> ret = node::MakeCallback(env->isolate(),
1573 sc->object(),
1574 env->ticketkeycallback_string(),
1575 arraysize(argv),
1576 argv,
1577 {0, 0}).ToLocalChecked();
1578 Local<Array> arr = ret.As<Array>();
1579
1580 int r =
1581 arr->Get(env->context(),
1582 kTicketKeyReturnIndex).ToLocalChecked()
1583 ->Int32Value(env->context()).FromJust();
1584 if (r < 0)
1585 return r;
1586
1587 Local<Value> hmac = arr->Get(env->context(),
1588 kTicketKeyHMACIndex).ToLocalChecked();
1589 Local<Value> aes = arr->Get(env->context(),
1590 kTicketKeyAESIndex).ToLocalChecked();
1591 if (Buffer::Length(aes) != kTicketPartSize)
1592 return -1;
1593
1594 if (enc) {
1595 Local<Value> name_val = arr->Get(env->context(),
1596 kTicketKeyNameIndex).ToLocalChecked();
1597 Local<Value> iv_val = arr->Get(env->context(),
1598 kTicketKeyIVIndex).ToLocalChecked();
1599
1600 if (Buffer::Length(name_val) != kTicketPartSize ||
1601 Buffer::Length(iv_val) != kTicketPartSize) {
1602 return -1;
1603 }
1604
1605 name_val.As<ArrayBufferView>()->CopyContents(name, kTicketPartSize);
1606 iv_val.As<ArrayBufferView>()->CopyContents(iv, kTicketPartSize);
1607 }
1608
1609 ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
1610 HMAC_Init_ex(hctx,
1611 hmac_buf.data(),
1612 hmac_buf.length(),
1613 EVP_sha256(),
1614 nullptr);
1615
1616 ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
1617 if (enc) {
1618 EVP_EncryptInit_ex(ectx,
1619 EVP_aes_128_cbc(),
1620 nullptr,
1621 aes_key.data(),
1622 iv);
1623 } else {
1624 EVP_DecryptInit_ex(ectx,
1625 EVP_aes_128_cbc(),
1626 nullptr,
1627 aes_key.data(),
1628 iv);
1629 }
1630
1631 return r;
1632 }
1633
1634
TicketCompatibilityCallback(SSL * ssl,unsigned char * name,unsigned char * iv,EVP_CIPHER_CTX * ectx,HMAC_CTX * hctx,int enc)1635 int SecureContext::TicketCompatibilityCallback(SSL* ssl,
1636 unsigned char* name,
1637 unsigned char* iv,
1638 EVP_CIPHER_CTX* ectx,
1639 HMAC_CTX* hctx,
1640 int enc) {
1641 SecureContext* sc = static_cast<SecureContext*>(
1642 SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1643
1644 if (enc) {
1645 memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
1646 if (RAND_bytes(iv, 16) <= 0 ||
1647 EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr,
1648 sc->ticket_key_aes_, iv) <= 0 ||
1649 HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1650 EVP_sha256(), nullptr) <= 0) {
1651 return -1;
1652 }
1653 return 1;
1654 }
1655
1656 if (memcmp(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) != 0) {
1657 // The ticket key name does not match. Discard the ticket.
1658 return 0;
1659 }
1660
1661 if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
1662 iv) <= 0 ||
1663 HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1664 EVP_sha256(), nullptr) <= 0) {
1665 return -1;
1666 }
1667 return 1;
1668 }
1669
1670
CtxGetter(const FunctionCallbackInfo<Value> & info)1671 void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
1672 SecureContext* sc;
1673 ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
1674 Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get());
1675 info.GetReturnValue().Set(ext);
1676 }
1677
1678
1679 template <bool primary>
GetCertificate(const FunctionCallbackInfo<Value> & args)1680 void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1681 SecureContext* wrap;
1682 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1683 Environment* env = wrap->env();
1684 X509* cert;
1685
1686 if (primary)
1687 cert = wrap->cert_.get();
1688 else
1689 cert = wrap->issuer_.get();
1690 if (cert == nullptr)
1691 return args.GetReturnValue().SetNull();
1692
1693 int size = i2d_X509(cert, nullptr);
1694 Local<Object> buff = Buffer::New(env, size).ToLocalChecked();
1695 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1696 Buffer::Data(buff));
1697 i2d_X509(cert, &serialized);
1698
1699 args.GetReturnValue().Set(buff);
1700 }
1701
1702
1703 template <class Base>
AddMethods(Environment * env,Local<FunctionTemplate> t)1704 void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) {
1705 HandleScope scope(env->isolate());
1706
1707 env->SetProtoMethodNoSideEffect(t, "getPeerCertificate", GetPeerCertificate);
1708 env->SetProtoMethodNoSideEffect(t, "getCertificate", GetCertificate);
1709 env->SetProtoMethodNoSideEffect(t, "getFinished", GetFinished);
1710 env->SetProtoMethodNoSideEffect(t, "getPeerFinished", GetPeerFinished);
1711 env->SetProtoMethodNoSideEffect(t, "getSession", GetSession);
1712 env->SetProtoMethod(t, "setSession", SetSession);
1713 env->SetProtoMethod(t, "loadSession", LoadSession);
1714 env->SetProtoMethodNoSideEffect(t, "isSessionReused", IsSessionReused);
1715 env->SetProtoMethodNoSideEffect(t, "verifyError", VerifyError);
1716 env->SetProtoMethodNoSideEffect(t, "getCipher", GetCipher);
1717 env->SetProtoMethodNoSideEffect(t, "getSharedSigalgs", GetSharedSigalgs);
1718 env->SetProtoMethodNoSideEffect(
1719 t, "exportKeyingMaterial", ExportKeyingMaterial);
1720 env->SetProtoMethod(t, "endParser", EndParser);
1721 env->SetProtoMethod(t, "certCbDone", CertCbDone);
1722 env->SetProtoMethod(t, "renegotiate", Renegotiate);
1723 env->SetProtoMethodNoSideEffect(t, "getTLSTicket", GetTLSTicket);
1724 env->SetProtoMethod(t, "newSessionDone", NewSessionDone);
1725 env->SetProtoMethod(t, "setOCSPResponse", SetOCSPResponse);
1726 env->SetProtoMethod(t, "requestOCSP", RequestOCSP);
1727 env->SetProtoMethodNoSideEffect(t, "getEphemeralKeyInfo",
1728 GetEphemeralKeyInfo);
1729 env->SetProtoMethodNoSideEffect(t, "getProtocol", GetProtocol);
1730
1731 env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment);
1732
1733 env->SetProtoMethodNoSideEffect(t, "getALPNNegotiatedProtocol",
1734 GetALPNNegotiatedProto);
1735 env->SetProtoMethod(t, "setALPNProtocols", SetALPNProtocols);
1736 }
1737
1738
1739 template <class Base>
ConfigureSecureContext(SecureContext * sc)1740 void SSLWrap<Base>::ConfigureSecureContext(SecureContext* sc) {
1741 // OCSP stapling
1742 SSL_CTX_set_tlsext_status_cb(sc->ctx_.get(), TLSExtStatusCallback);
1743 SSL_CTX_set_tlsext_status_arg(sc->ctx_.get(), nullptr);
1744 }
1745
1746
1747 template <class Base>
GetSessionCallback(SSL * s,const unsigned char * key,int len,int * copy)1748 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
1749 const unsigned char* key,
1750 int len,
1751 int* copy) {
1752 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1753
1754 *copy = 0;
1755 return w->next_sess_.release();
1756 }
1757
1758
1759 template <class Base>
NewSessionCallback(SSL * s,SSL_SESSION * sess)1760 int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
1761 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1762 Environment* env = w->ssl_env();
1763 HandleScope handle_scope(env->isolate());
1764 Context::Scope context_scope(env->context());
1765
1766 if (!w->session_callbacks_)
1767 return 0;
1768
1769 // Check if session is small enough to be stored
1770 int size = i2d_SSL_SESSION(sess, nullptr);
1771 if (size > SecureContext::kMaxSessionSize)
1772 return 0;
1773
1774 // Serialize session
1775 Local<Object> session = Buffer::New(env, size).ToLocalChecked();
1776 unsigned char* session_data = reinterpret_cast<unsigned char*>(
1777 Buffer::Data(session));
1778 memset(session_data, 0, size);
1779 i2d_SSL_SESSION(sess, &session_data);
1780
1781 unsigned int session_id_length;
1782 const unsigned char* session_id_data = SSL_SESSION_get_id(sess,
1783 &session_id_length);
1784 Local<Object> session_id = Buffer::Copy(
1785 env,
1786 reinterpret_cast<const char*>(session_id_data),
1787 session_id_length).ToLocalChecked();
1788 Local<Value> argv[] = { session_id, session };
1789 // On servers, we pause the handshake until callback of 'newSession', which
1790 // calls NewSessionDoneCb(). On clients, there is no callback to wait for.
1791 if (w->is_server())
1792 w->awaiting_new_session_ = true;
1793 w->MakeCallback(env->onnewsession_string(), arraysize(argv), argv);
1794
1795 return 0;
1796 }
1797
1798
1799 template <class Base>
KeylogCallback(const SSL * s,const char * line)1800 void SSLWrap<Base>::KeylogCallback(const SSL* s, const char* line) {
1801 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1802 Environment* env = w->ssl_env();
1803 HandleScope handle_scope(env->isolate());
1804 Context::Scope context_scope(env->context());
1805
1806 const size_t size = strlen(line);
1807 Local<Value> line_bf = Buffer::Copy(env, line, 1 + size).ToLocalChecked();
1808 char* data = Buffer::Data(line_bf);
1809 data[size] = '\n';
1810 w->MakeCallback(env->onkeylog_string(), 1, &line_bf);
1811 }
1812
1813
1814 template <class Base>
OnClientHello(void * arg,const ClientHelloParser::ClientHello & hello)1815 void SSLWrap<Base>::OnClientHello(void* arg,
1816 const ClientHelloParser::ClientHello& hello) {
1817 Base* w = static_cast<Base*>(arg);
1818 Environment* env = w->ssl_env();
1819 HandleScope handle_scope(env->isolate());
1820 Local<Context> context = env->context();
1821 Context::Scope context_scope(context);
1822
1823 Local<Object> hello_obj = Object::New(env->isolate());
1824 Local<Object> buff = Buffer::Copy(
1825 env,
1826 reinterpret_cast<const char*>(hello.session_id()),
1827 hello.session_size()).ToLocalChecked();
1828 hello_obj->Set(context, env->session_id_string(), buff).Check();
1829 if (hello.servername() == nullptr) {
1830 hello_obj->Set(context,
1831 env->servername_string(),
1832 String::Empty(env->isolate())).Check();
1833 } else {
1834 Local<String> servername = OneByteString(env->isolate(),
1835 hello.servername(),
1836 hello.servername_size());
1837 hello_obj->Set(context, env->servername_string(), servername).Check();
1838 }
1839 hello_obj->Set(context,
1840 env->tls_ticket_string(),
1841 Boolean::New(env->isolate(), hello.has_ticket())).Check();
1842
1843 Local<Value> argv[] = { hello_obj };
1844 w->MakeCallback(env->onclienthello_string(), arraysize(argv), argv);
1845 }
1846
1847 template <class Base>
GetPeerCertificate(const FunctionCallbackInfo<Value> & args)1848 void SSLWrap<Base>::GetPeerCertificate(
1849 const FunctionCallbackInfo<Value>& args) {
1850 Base* w;
1851 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1852 Environment* env = w->ssl_env();
1853
1854 bool abbreviated = args.Length() < 1 || !args[0]->IsTrue();
1855
1856 Local<Value> ret;
1857 if (GetPeerCert(env, w->ssl_, abbreviated, w->is_server()).ToLocal(&ret))
1858 args.GetReturnValue().Set(ret);
1859 }
1860
1861
1862 template <class Base>
GetCertificate(const FunctionCallbackInfo<Value> & args)1863 void SSLWrap<Base>::GetCertificate(
1864 const FunctionCallbackInfo<Value>& args) {
1865 Base* w;
1866 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1867 Environment* env = w->ssl_env();
1868
1869 Local<Value> ret;
1870 if (GetCert(env, w->ssl_).ToLocal(&ret))
1871 args.GetReturnValue().Set(ret);
1872 }
1873
1874
1875 template <class Base>
GetFinished(const FunctionCallbackInfo<Value> & args)1876 void SSLWrap<Base>::GetFinished(const FunctionCallbackInfo<Value>& args) {
1877 Environment* env = Environment::GetCurrent(args);
1878
1879 Base* w;
1880 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1881
1882 // We cannot just pass nullptr to SSL_get_finished()
1883 // because it would further be propagated to memcpy(),
1884 // where the standard requirements as described in ISO/IEC 9899:2011
1885 // sections 7.21.2.1, 7.21.1.2, and 7.1.4, would be violated.
1886 // Thus, we use a dummy byte.
1887 char dummy[1];
1888 size_t len = SSL_get_finished(w->ssl_.get(), dummy, sizeof dummy);
1889 if (len == 0)
1890 return;
1891
1892 AllocatedBuffer buf = env->AllocateManaged(len);
1893 CHECK_EQ(len, SSL_get_finished(w->ssl_.get(), buf.data(), len));
1894 args.GetReturnValue().Set(buf.ToBuffer().ToLocalChecked());
1895 }
1896
1897
1898 template <class Base>
GetPeerFinished(const FunctionCallbackInfo<Value> & args)1899 void SSLWrap<Base>::GetPeerFinished(const FunctionCallbackInfo<Value>& args) {
1900 Environment* env = Environment::GetCurrent(args);
1901
1902 Base* w;
1903 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1904
1905 // We cannot just pass nullptr to SSL_get_peer_finished()
1906 // because it would further be propagated to memcpy(),
1907 // where the standard requirements as described in ISO/IEC 9899:2011
1908 // sections 7.21.2.1, 7.21.1.2, and 7.1.4, would be violated.
1909 // Thus, we use a dummy byte.
1910 char dummy[1];
1911 size_t len = SSL_get_peer_finished(w->ssl_.get(), dummy, sizeof dummy);
1912 if (len == 0)
1913 return;
1914
1915 AllocatedBuffer buf = env->AllocateManaged(len);
1916 CHECK_EQ(len, SSL_get_peer_finished(w->ssl_.get(), buf.data(), len));
1917 args.GetReturnValue().Set(buf.ToBuffer().ToLocalChecked());
1918 }
1919
1920
1921 template <class Base>
GetSession(const FunctionCallbackInfo<Value> & args)1922 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
1923 Environment* env = Environment::GetCurrent(args);
1924
1925 Base* w;
1926 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1927
1928 SSL_SESSION* sess = SSL_get_session(w->ssl_.get());
1929 if (sess == nullptr)
1930 return;
1931
1932 int slen = i2d_SSL_SESSION(sess, nullptr);
1933 if (slen <= 0)
1934 return; // Invalid or malformed session.
1935
1936 AllocatedBuffer sbuf = env->AllocateManaged(slen);
1937 unsigned char* p = reinterpret_cast<unsigned char*>(sbuf.data());
1938 CHECK_LT(0, i2d_SSL_SESSION(sess, &p));
1939 args.GetReturnValue().Set(sbuf.ToBuffer().ToLocalChecked());
1940 }
1941
1942
1943 template <class Base>
SetSession(const FunctionCallbackInfo<Value> & args)1944 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
1945 Environment* env = Environment::GetCurrent(args);
1946
1947 Base* w;
1948 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1949
1950 if (args.Length() < 1)
1951 return THROW_ERR_MISSING_ARGS(env, "Session argument is mandatory");
1952
1953 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Session");
1954
1955 SSLSessionPointer sess = GetTLSSession(args[0]);
1956 if (sess == nullptr)
1957 return;
1958
1959 if (!SetTLSSession(w->ssl_, sess))
1960 return env->ThrowError("SSL_set_session error");
1961 }
1962
1963
1964 template <class Base>
LoadSession(const FunctionCallbackInfo<Value> & args)1965 void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
1966 Base* w;
1967 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1968
1969 // TODO(@sam-github) check arg length and types in js, and CHECK in c++
1970 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
1971 ArrayBufferViewContents<unsigned char> sbuf(args[0]);
1972
1973 const unsigned char* p = sbuf.data();
1974 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, sbuf.length());
1975
1976 // Setup next session and move hello to the BIO buffer
1977 w->next_sess_.reset(sess);
1978 }
1979 }
1980
1981
1982 template <class Base>
IsSessionReused(const FunctionCallbackInfo<Value> & args)1983 void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
1984 Base* w;
1985 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1986 bool yes = SSL_session_reused(w->ssl_.get());
1987 args.GetReturnValue().Set(yes);
1988 }
1989
1990
1991 template <class Base>
EndParser(const FunctionCallbackInfo<Value> & args)1992 void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
1993 Base* w;
1994 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1995 w->hello_parser_.End();
1996 }
1997
1998
1999 template <class Base>
Renegotiate(const FunctionCallbackInfo<Value> & args)2000 void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
2001 Base* w;
2002 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2003
2004 ClearErrorOnReturn clear_error_on_return;
2005
2006 if (SSL_renegotiate(w->ssl_.get()) != 1) {
2007 return ThrowCryptoError(w->ssl_env(), ERR_get_error());
2008 }
2009 }
2010
2011
2012 template <class Base>
GetTLSTicket(const FunctionCallbackInfo<Value> & args)2013 void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
2014 Base* w;
2015 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2016 Environment* env = w->ssl_env();
2017
2018 SSL_SESSION* sess = SSL_get_session(w->ssl_.get());
2019 if (sess == nullptr)
2020 return;
2021
2022 const unsigned char* ticket;
2023 size_t length;
2024 SSL_SESSION_get0_ticket(sess, &ticket, &length);
2025
2026 if (ticket == nullptr)
2027 return;
2028
2029 Local<Object> buff = Buffer::Copy(
2030 env, reinterpret_cast<const char*>(ticket), length).ToLocalChecked();
2031
2032 args.GetReturnValue().Set(buff);
2033 }
2034
2035
2036 template <class Base>
NewSessionDone(const FunctionCallbackInfo<Value> & args)2037 void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
2038 Base* w;
2039 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2040 w->awaiting_new_session_ = false;
2041 w->NewSessionDoneCb();
2042 }
2043
2044
2045 template <class Base>
SetOCSPResponse(const FunctionCallbackInfo<Value> & args)2046 void SSLWrap<Base>::SetOCSPResponse(const FunctionCallbackInfo<Value>& args) {
2047 Base* w;
2048 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2049 Environment* env = w->env();
2050
2051 if (args.Length() < 1)
2052 return THROW_ERR_MISSING_ARGS(env, "OCSP response argument is mandatory");
2053
2054 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "OCSP response");
2055
2056 w->ocsp_response_.Reset(args.GetIsolate(), args[0].As<ArrayBufferView>());
2057 }
2058
2059
2060 template <class Base>
RequestOCSP(const FunctionCallbackInfo<Value> & args)2061 void SSLWrap<Base>::RequestOCSP(const FunctionCallbackInfo<Value>& args) {
2062 Base* w;
2063 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2064
2065 SSL_set_tlsext_status_type(w->ssl_.get(), TLSEXT_STATUSTYPE_ocsp);
2066 }
2067
2068
2069 template <class Base>
GetEphemeralKeyInfo(const FunctionCallbackInfo<Value> & args)2070 void SSLWrap<Base>::GetEphemeralKeyInfo(
2071 const FunctionCallbackInfo<Value>& args) {
2072 Base* w;
2073 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2074 Environment* env = Environment::GetCurrent(args);
2075
2076 CHECK(w->ssl_);
2077
2078 // tmp key is available on only client
2079 if (w->is_server())
2080 return args.GetReturnValue().SetNull();
2081
2082 Local<Object> ret;
2083 if (GetEphemeralKey(env, w->ssl_).ToLocal(&ret))
2084 args.GetReturnValue().Set(ret);
2085
2086 // TODO(@sam-github) semver-major: else return ThrowCryptoError(env,
2087 // ERR_get_error())
2088 }
2089
2090 template <class Base>
SetMaxSendFragment(const FunctionCallbackInfo<Value> & args)2091 void SSLWrap<Base>::SetMaxSendFragment(
2092 const FunctionCallbackInfo<Value>& args) {
2093 CHECK(args.Length() >= 1 && args[0]->IsNumber());
2094
2095 Base* w;
2096 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2097
2098 int rv = SSL_set_max_send_fragment(
2099 w->ssl_.get(),
2100 args[0]->Int32Value(w->ssl_env()->context()).FromJust());
2101 args.GetReturnValue().Set(rv);
2102 }
2103
2104
2105 template <class Base>
VerifyError(const FunctionCallbackInfo<Value> & args)2106 void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
2107 Base* w;
2108 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2109
2110 // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
2111 // peer certificate is questionable but it's compatible with what was
2112 // here before.
2113 long x509_verify_error = // NOLINT(runtime/int)
2114 VerifyPeerCertificate(w->ssl_, X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT);
2115
2116 if (x509_verify_error == X509_V_OK)
2117 return args.GetReturnValue().SetNull();
2118
2119 const char* reason = X509_verify_cert_error_string(x509_verify_error);
2120 const char* code = reason;
2121 code = X509ErrorCode(x509_verify_error);
2122
2123 Isolate* isolate = args.GetIsolate();
2124 Local<String> reason_string = OneByteString(isolate, reason);
2125 Local<Value> exception_value = Exception::Error(reason_string);
2126 Local<Object> exception_object =
2127 exception_value->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
2128 exception_object->Set(w->env()->context(), w->env()->code_string(),
2129 OneByteString(isolate, code)).Check();
2130 args.GetReturnValue().Set(exception_object);
2131 }
2132
2133
2134 template <class Base>
GetCipher(const FunctionCallbackInfo<Value> & args)2135 void SSLWrap<Base>::GetCipher(const FunctionCallbackInfo<Value>& args) {
2136 Base* w;
2137 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2138 Environment* env = w->ssl_env();
2139
2140 const SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_.get());
2141 if (c == nullptr)
2142 return;
2143
2144 Local<Object> ret;
2145 if (GetCipherInfo(env, w->ssl_).ToLocal(&ret))
2146 args.GetReturnValue().Set(ret);
2147 }
2148
2149
2150 template <class Base>
GetSharedSigalgs(const FunctionCallbackInfo<Value> & args)2151 void SSLWrap<Base>::GetSharedSigalgs(const FunctionCallbackInfo<Value>& args) {
2152 Base* w;
2153 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2154 Environment* env = w->ssl_env();
2155
2156 SSL* ssl = w->ssl_.get();
2157 int nsig = SSL_get_shared_sigalgs(ssl, 0, nullptr, nullptr, nullptr, nullptr,
2158 nullptr);
2159 MaybeStackBuffer<Local<Value>, 16> ret_arr(nsig);
2160
2161 for (int i = 0; i < nsig; i++) {
2162 int hash_nid;
2163 int sign_nid;
2164 std::string sig_with_md;
2165
2166 SSL_get_shared_sigalgs(ssl, i, &sign_nid, &hash_nid, nullptr, nullptr,
2167 nullptr);
2168
2169 switch (sign_nid) {
2170 case EVP_PKEY_RSA:
2171 sig_with_md = "RSA+";
2172 break;
2173
2174 case EVP_PKEY_RSA_PSS:
2175 sig_with_md = "RSA-PSS+";
2176 break;
2177
2178 case EVP_PKEY_DSA:
2179 sig_with_md = "DSA+";
2180 break;
2181
2182 case EVP_PKEY_EC:
2183 sig_with_md = "ECDSA+";
2184 break;
2185
2186 case NID_ED25519:
2187 sig_with_md = "Ed25519+";
2188 break;
2189
2190 case NID_ED448:
2191 sig_with_md = "Ed448+";
2192 break;
2193 #ifndef OPENSSL_NO_GOST
2194 case NID_id_GostR3410_2001:
2195 sig_with_md = "gost2001+";
2196 break;
2197
2198 case NID_id_GostR3410_2012_256:
2199 sig_with_md = "gost2012_256+";
2200 break;
2201
2202 case NID_id_GostR3410_2012_512:
2203 sig_with_md = "gost2012_512+";
2204 break;
2205 #endif // !OPENSSL_NO_GOST
2206 default:
2207 const char* sn = OBJ_nid2sn(sign_nid);
2208
2209 if (sn != nullptr) {
2210 sig_with_md = std::string(sn) + "+";
2211 } else {
2212 sig_with_md = "UNDEF+";
2213 }
2214 break;
2215 }
2216
2217 const char* sn_hash = OBJ_nid2sn(hash_nid);
2218 if (sn_hash != nullptr) {
2219 sig_with_md += std::string(sn_hash);
2220 } else {
2221 sig_with_md += "UNDEF";
2222 }
2223 ret_arr[i] = OneByteString(env->isolate(), sig_with_md.c_str());
2224 }
2225
2226 args.GetReturnValue().Set(
2227 Array::New(env->isolate(), ret_arr.out(), ret_arr.length()));
2228 }
2229
2230 template <class Base>
ExportKeyingMaterial(const FunctionCallbackInfo<Value> & args)2231 void SSLWrap<Base>::ExportKeyingMaterial(
2232 const FunctionCallbackInfo<Value>& args) {
2233 CHECK(args[0]->IsInt32());
2234 CHECK(args[1]->IsString());
2235
2236 Base* w;
2237 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2238 Environment* env = w->ssl_env();
2239
2240 uint32_t olen = args[0].As<Uint32>()->Value();
2241 node::Utf8Value label(env->isolate(), args[1]);
2242
2243 AllocatedBuffer out = env->AllocateManaged(olen);
2244
2245 ByteSource context;
2246 bool use_context = !args[2]->IsUndefined();
2247 if (use_context)
2248 context = ByteSource::FromBuffer(args[2]);
2249
2250 if (SSL_export_keying_material(w->ssl_.get(),
2251 reinterpret_cast<unsigned char*>(out.data()),
2252 olen,
2253 *label,
2254 label.length(),
2255 reinterpret_cast<const unsigned char*>(
2256 context.get()),
2257 context.size(),
2258 use_context) != 1) {
2259 return ThrowCryptoError(env, ERR_get_error(), "SSL_export_keying_material");
2260 }
2261
2262 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
2263 }
2264
2265 template <class Base>
GetProtocol(const FunctionCallbackInfo<Value> & args)2266 void SSLWrap<Base>::GetProtocol(const FunctionCallbackInfo<Value>& args) {
2267 Base* w;
2268 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2269
2270 const char* tls_version = SSL_get_version(w->ssl_.get());
2271 args.GetReturnValue().Set(OneByteString(args.GetIsolate(), tls_version));
2272 }
2273
2274
2275 template <class Base>
SelectALPNCallback(SSL * s,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)2276 int SSLWrap<Base>::SelectALPNCallback(SSL* s,
2277 const unsigned char** out,
2278 unsigned char* outlen,
2279 const unsigned char* in,
2280 unsigned int inlen,
2281 void* arg) {
2282 Base* w = static_cast<Base*>(SSL_get_app_data(s));
2283 Environment* env = w->env();
2284 HandleScope handle_scope(env->isolate());
2285 Context::Scope context_scope(env->context());
2286
2287 Local<Value> alpn_buffer =
2288 w->object()->GetPrivate(
2289 env->context(),
2290 env->alpn_buffer_private_symbol()).ToLocalChecked();
2291 ArrayBufferViewContents<unsigned char> alpn_protos(alpn_buffer);
2292 int status = SSL_select_next_proto(const_cast<unsigned char**>(out), outlen,
2293 alpn_protos.data(), alpn_protos.length(),
2294 in, inlen);
2295 // According to 3.2. Protocol Selection of RFC7301, fatal
2296 // no_application_protocol alert shall be sent but OpenSSL 1.0.2 does not
2297 // support it yet. See
2298 // https://rt.openssl.org/Ticket/Display.html?id=3463&user=guest&pass=guest
2299 return status == OPENSSL_NPN_NEGOTIATED ? SSL_TLSEXT_ERR_OK
2300 : SSL_TLSEXT_ERR_NOACK;
2301 }
2302
2303
2304 template <class Base>
GetALPNNegotiatedProto(const FunctionCallbackInfo<Value> & args)2305 void SSLWrap<Base>::GetALPNNegotiatedProto(
2306 const FunctionCallbackInfo<Value>& args) {
2307 Base* w;
2308 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2309
2310 const unsigned char* alpn_proto;
2311 unsigned int alpn_proto_len;
2312
2313 SSL_get0_alpn_selected(w->ssl_.get(), &alpn_proto, &alpn_proto_len);
2314
2315 Local<Value> result;
2316 if (alpn_proto_len == 0) {
2317 result = False(args.GetIsolate());
2318 } else if (alpn_proto_len == sizeof("h2") - 1 &&
2319 0 == memcmp(alpn_proto, "h2", sizeof("h2") - 1)) {
2320 result = w->env()->h2_string();
2321 } else if (alpn_proto_len == sizeof("http/1.1") - 1 &&
2322 0 == memcmp(alpn_proto, "http/1.1", sizeof("http/1.1") - 1)) {
2323 result = w->env()->http_1_1_string();
2324 } else {
2325 result = OneByteString(args.GetIsolate(), alpn_proto, alpn_proto_len);
2326 }
2327
2328 args.GetReturnValue().Set(result);
2329 }
2330
2331
2332 template <class Base>
SetALPNProtocols(const FunctionCallbackInfo<Value> & args)2333 void SSLWrap<Base>::SetALPNProtocols(const FunctionCallbackInfo<Value>& args) {
2334 Base* w;
2335 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2336 Environment* env = w->env();
2337 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
2338 return env->ThrowTypeError("Must give a Buffer as first argument");
2339
2340 if (w->is_client()) {
2341 CHECK(SetALPN(w->ssl_, args[0]));
2342 } else {
2343 CHECK(
2344 w->object()->SetPrivate(
2345 env->context(),
2346 env->alpn_buffer_private_symbol(),
2347 args[0]).FromJust());
2348 // Server should select ALPN protocol from list of advertised by client
2349 SSL_CTX_set_alpn_select_cb(SSL_get_SSL_CTX(w->ssl_.get()),
2350 SelectALPNCallback,
2351 nullptr);
2352 }
2353 }
2354
2355
2356 template <class Base>
TLSExtStatusCallback(SSL * s,void * arg)2357 int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
2358 Base* w = static_cast<Base*>(SSL_get_app_data(s));
2359 Environment* env = w->env();
2360 HandleScope handle_scope(env->isolate());
2361
2362 if (w->is_client()) {
2363 // Incoming response
2364 Local<Value> arg;
2365 MaybeLocal<Value> ret = GetSSLOCSPResponse(env, s, Null(env->isolate()));
2366 if (ret.ToLocal(&arg))
2367 w->MakeCallback(env->onocspresponse_string(), 1, &arg);
2368
2369 // No async acceptance is possible, so always return 1 to accept the
2370 // response. The listener for 'OCSPResponse' event has no control over
2371 // return value, but it can .destroy() the connection if the response is not
2372 // acceptable.
2373 return 1;
2374 } else {
2375 // Outgoing response
2376 if (w->ocsp_response_.IsEmpty())
2377 return SSL_TLSEXT_ERR_NOACK;
2378
2379 Local<ArrayBufferView> obj = PersistentToLocal::Default(env->isolate(),
2380 w->ocsp_response_);
2381 size_t len = obj->ByteLength();
2382
2383 // OpenSSL takes control of the pointer after accepting it
2384 unsigned char* data = MallocOpenSSL<unsigned char>(len);
2385 obj->CopyContents(data, len);
2386
2387 if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
2388 OPENSSL_free(data);
2389 w->ocsp_response_.Reset();
2390
2391 return SSL_TLSEXT_ERR_OK;
2392 }
2393 }
2394
2395
2396 template <class Base>
WaitForCertCb(CertCb cb,void * arg)2397 void SSLWrap<Base>::WaitForCertCb(CertCb cb, void* arg) {
2398 cert_cb_ = cb;
2399 cert_cb_arg_ = arg;
2400 }
2401
2402
2403 template <class Base>
SSLCertCallback(SSL * s,void * arg)2404 int SSLWrap<Base>::SSLCertCallback(SSL* s, void* arg) {
2405 Base* w = static_cast<Base*>(SSL_get_app_data(s));
2406
2407 if (!w->is_server())
2408 return 1;
2409
2410 if (!w->is_waiting_cert_cb())
2411 return 1;
2412
2413 if (w->cert_cb_running_)
2414 // Not an error. Suspend handshake with SSL_ERROR_WANT_X509_LOOKUP, and
2415 // handshake will continue after certcb is done.
2416 return -1;
2417
2418 Environment* env = w->env();
2419 Local<Context> context = env->context();
2420 HandleScope handle_scope(env->isolate());
2421 Context::Scope context_scope(context);
2422 w->cert_cb_running_ = true;
2423
2424 Local<Object> info = Object::New(env->isolate());
2425
2426 const char* servername = GetServerName(s);
2427 if (servername == nullptr) {
2428 info->Set(context,
2429 env->servername_string(),
2430 String::Empty(env->isolate())).Check();
2431 } else {
2432 Local<String> str = OneByteString(env->isolate(), servername,
2433 strlen(servername));
2434 info->Set(context, env->servername_string(), str).Check();
2435 }
2436
2437 const bool ocsp = (SSL_get_tlsext_status_type(s) == TLSEXT_STATUSTYPE_ocsp);
2438 info->Set(context, env->ocsp_request_string(),
2439 Boolean::New(env->isolate(), ocsp)).Check();
2440
2441 Local<Value> argv[] = { info };
2442 w->MakeCallback(env->oncertcb_string(), arraysize(argv), argv);
2443
2444 if (!w->cert_cb_running_)
2445 return 1;
2446
2447 // Performing async action, wait...
2448 return -1;
2449 }
2450
2451
2452 template <class Base>
CertCbDone(const FunctionCallbackInfo<Value> & args)2453 void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
2454 Base* w;
2455 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2456 Environment* env = w->env();
2457
2458 CHECK(w->is_waiting_cert_cb() && w->cert_cb_running_);
2459
2460 Local<Object> object = w->object();
2461 Local<Value> ctx = object->Get(env->context(),
2462 env->sni_context_string()).ToLocalChecked();
2463 Local<FunctionTemplate> cons = env->secure_context_constructor_template();
2464
2465 if (cons->HasInstance(ctx)) {
2466 SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
2467 CHECK_NOT_NULL(sc);
2468 // Store the SNI context for later use.
2469 w->sni_context_ = BaseObjectPtr<SecureContext>(sc);
2470
2471 if (UseSNIContext(w->ssl_, w->sni_context_) && !w->SetCACerts(sc)) {
2472 // Not clear why sometimes we throw error, and sometimes we call
2473 // onerror(). Both cause .destroy(), but onerror does a bit more.
2474 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
2475 return ThrowCryptoError(env, err, "CertCbDone");
2476 }
2477 } else if (ctx->IsObject()) {
2478 // Failure: incorrect SNI context object
2479 Local<Value> err = Exception::TypeError(env->sni_context_err_string());
2480 w->MakeCallback(env->onerror_string(), 1, &err);
2481 return;
2482 }
2483
2484 CertCb cb;
2485 void* arg;
2486
2487 cb = w->cert_cb_;
2488 arg = w->cert_cb_arg_;
2489
2490 w->cert_cb_running_ = false;
2491 w->cert_cb_ = nullptr;
2492 w->cert_cb_arg_ = nullptr;
2493
2494 cb(arg);
2495 }
2496
2497
2498 template <class Base>
DestroySSL()2499 void SSLWrap<Base>::DestroySSL() {
2500 if (!ssl_)
2501 return;
2502
2503 env_->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
2504 ssl_.reset();
2505 }
2506
2507
2508 template <class Base>
SetCACerts(SecureContext * sc)2509 int SSLWrap<Base>::SetCACerts(SecureContext* sc) {
2510 int err = SSL_set1_verify_cert_store(ssl_.get(),
2511 SSL_CTX_get_cert_store(sc->ctx_.get()));
2512 if (err != 1)
2513 return err;
2514
2515 STACK_OF(X509_NAME)* list = SSL_dup_CA_list(
2516 SSL_CTX_get_client_CA_list(sc->ctx_.get()));
2517
2518 // NOTE: `SSL_set_client_CA_list` takes the ownership of `list`
2519 SSL_set_client_CA_list(ssl_.get(), list);
2520 return 1;
2521 }
2522
2523 template <class Base>
MemoryInfo(MemoryTracker * tracker) const2524 void SSLWrap<Base>::MemoryInfo(MemoryTracker* tracker) const {
2525 tracker->TrackField("ocsp_response", ocsp_response_);
2526 tracker->TrackField("sni_context", sni_context_);
2527 }
2528
VerifyCallback(int preverify_ok,X509_STORE_CTX * ctx)2529 int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
2530 // From https://www.openssl.org/docs/man1.1.1/man3/SSL_verify_cb:
2531 //
2532 // If VerifyCallback returns 1, the verification process is continued. If
2533 // VerifyCallback always returns 1, the TLS/SSL handshake will not be
2534 // terminated with respect to verification failures and the connection will
2535 // be established. The calling process can however retrieve the error code
2536 // of the last verification error using SSL_get_verify_result(3) or by
2537 // maintaining its own error storage managed by VerifyCallback.
2538 //
2539 // Since we cannot perform I/O quickly enough with X509_STORE_CTX_ APIs in
2540 // this callback, we ignore all preverify_ok errors and let the handshake
2541 // continue. It is imperative that the user use Connection::VerifyError after
2542 // the 'secure' callback has been made.
2543 return 1;
2544 }
2545
IsSupportedAuthenticatedMode(const EVP_CIPHER * cipher)2546 static bool IsSupportedAuthenticatedMode(const EVP_CIPHER* cipher) {
2547 const int mode = EVP_CIPHER_mode(cipher);
2548 // Check `chacha20-poly1305` separately, it is also an AEAD cipher,
2549 // but its mode is 0 which doesn't indicate
2550 return EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305 ||
2551 mode == EVP_CIPH_CCM_MODE ||
2552 mode == EVP_CIPH_GCM_MODE ||
2553 IS_OCB_MODE(mode);
2554 }
2555
IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX * ctx)2556 static bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX* ctx) {
2557 const EVP_CIPHER* cipher = EVP_CIPHER_CTX_cipher(ctx);
2558 return IsSupportedAuthenticatedMode(cipher);
2559 }
2560
2561 enum class ParseKeyResult {
2562 kParseKeyOk,
2563 kParseKeyNotRecognized,
2564 kParseKeyNeedPassphrase,
2565 kParseKeyFailed
2566 };
2567
TryParsePublicKey(EVPKeyPointer * pkey,const BIOPointer & bp,const char * name,const std::function<EVP_PKEY * (const unsigned char ** p,long l)> & parse)2568 static ParseKeyResult TryParsePublicKey(
2569 EVPKeyPointer* pkey,
2570 const BIOPointer& bp,
2571 const char* name,
2572 // NOLINTNEXTLINE(runtime/int)
2573 const std::function<EVP_PKEY*(const unsigned char** p, long l)>& parse) {
2574 unsigned char* der_data;
2575 long der_len; // NOLINT(runtime/int)
2576
2577 // This skips surrounding data and decodes PEM to DER.
2578 {
2579 MarkPopErrorOnReturn mark_pop_error_on_return;
2580 if (PEM_bytes_read_bio(&der_data, &der_len, nullptr, name,
2581 bp.get(), nullptr, nullptr) != 1)
2582 return ParseKeyResult::kParseKeyNotRecognized;
2583 }
2584
2585 // OpenSSL might modify the pointer, so we need to make a copy before parsing.
2586 const unsigned char* p = der_data;
2587 pkey->reset(parse(&p, der_len));
2588 OPENSSL_clear_free(der_data, der_len);
2589
2590 return *pkey ? ParseKeyResult::kParseKeyOk :
2591 ParseKeyResult::kParseKeyFailed;
2592 }
2593
ParsePublicKeyPEM(EVPKeyPointer * pkey,const char * key_pem,int key_pem_len)2594 static ParseKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
2595 const char* key_pem,
2596 int key_pem_len) {
2597 BIOPointer bp(BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len));
2598 if (!bp)
2599 return ParseKeyResult::kParseKeyFailed;
2600
2601 ParseKeyResult ret;
2602
2603 // Try parsing as a SubjectPublicKeyInfo first.
2604 ret = TryParsePublicKey(pkey, bp, "PUBLIC KEY",
2605 [](const unsigned char** p, long l) { // NOLINT(runtime/int)
2606 return d2i_PUBKEY(nullptr, p, l);
2607 });
2608 if (ret != ParseKeyResult::kParseKeyNotRecognized)
2609 return ret;
2610
2611 // Maybe it is PKCS#1.
2612 CHECK(BIO_reset(bp.get()));
2613 ret = TryParsePublicKey(pkey, bp, "RSA PUBLIC KEY",
2614 [](const unsigned char** p, long l) { // NOLINT(runtime/int)
2615 return d2i_PublicKey(EVP_PKEY_RSA, nullptr, p, l);
2616 });
2617 if (ret != ParseKeyResult::kParseKeyNotRecognized)
2618 return ret;
2619
2620 // X.509 fallback.
2621 CHECK(BIO_reset(bp.get()));
2622 return TryParsePublicKey(pkey, bp, "CERTIFICATE",
2623 [](const unsigned char** p, long l) { // NOLINT(runtime/int)
2624 X509Pointer x509(d2i_X509(nullptr, p, l));
2625 return x509 ? X509_get_pubkey(x509.get()) : nullptr;
2626 });
2627 }
2628
ParsePublicKey(EVPKeyPointer * pkey,const PublicKeyEncodingConfig & config,const char * key,size_t key_len)2629 static ParseKeyResult ParsePublicKey(EVPKeyPointer* pkey,
2630 const PublicKeyEncodingConfig& config,
2631 const char* key,
2632 size_t key_len) {
2633 if (config.format_ == kKeyFormatPEM) {
2634 return ParsePublicKeyPEM(pkey, key, key_len);
2635 } else {
2636 CHECK_EQ(config.format_, kKeyFormatDER);
2637
2638 const unsigned char* p = reinterpret_cast<const unsigned char*>(key);
2639 if (config.type_.ToChecked() == kKeyEncodingPKCS1) {
2640 pkey->reset(d2i_PublicKey(EVP_PKEY_RSA, nullptr, &p, key_len));
2641 } else {
2642 CHECK_EQ(config.type_.ToChecked(), kKeyEncodingSPKI);
2643 pkey->reset(d2i_PUBKEY(nullptr, &p, key_len));
2644 }
2645
2646 return *pkey ? ParseKeyResult::kParseKeyOk :
2647 ParseKeyResult::kParseKeyFailed;
2648 }
2649 }
2650
BIOToStringOrBuffer(Environment * env,BIO * bio,PKFormatType format)2651 static inline Local<Value> BIOToStringOrBuffer(Environment* env,
2652 BIO* bio,
2653 PKFormatType format) {
2654 BUF_MEM* bptr;
2655 BIO_get_mem_ptr(bio, &bptr);
2656 if (format == kKeyFormatPEM) {
2657 // PEM is an ASCII format, so we will return it as a string.
2658 return String::NewFromUtf8(env->isolate(), bptr->data,
2659 NewStringType::kNormal,
2660 bptr->length).ToLocalChecked();
2661 } else {
2662 CHECK_EQ(format, kKeyFormatDER);
2663 // DER is binary, return it as a buffer.
2664 return Buffer::Copy(env, bptr->data, bptr->length).ToLocalChecked();
2665 }
2666 }
2667
WritePublicKeyInner(EVP_PKEY * pkey,const BIOPointer & bio,const PublicKeyEncodingConfig & config)2668 static bool WritePublicKeyInner(EVP_PKEY* pkey,
2669 const BIOPointer& bio,
2670 const PublicKeyEncodingConfig& config) {
2671 if (config.type_.ToChecked() == kKeyEncodingPKCS1) {
2672 // PKCS#1 is only valid for RSA keys.
2673 CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_RSA);
2674 RSAPointer rsa(EVP_PKEY_get1_RSA(pkey));
2675 if (config.format_ == kKeyFormatPEM) {
2676 // Encode PKCS#1 as PEM.
2677 return PEM_write_bio_RSAPublicKey(bio.get(), rsa.get()) == 1;
2678 } else {
2679 // Encode PKCS#1 as DER.
2680 CHECK_EQ(config.format_, kKeyFormatDER);
2681 return i2d_RSAPublicKey_bio(bio.get(), rsa.get()) == 1;
2682 }
2683 } else {
2684 CHECK_EQ(config.type_.ToChecked(), kKeyEncodingSPKI);
2685 if (config.format_ == kKeyFormatPEM) {
2686 // Encode SPKI as PEM.
2687 return PEM_write_bio_PUBKEY(bio.get(), pkey) == 1;
2688 } else {
2689 // Encode SPKI as DER.
2690 CHECK_EQ(config.format_, kKeyFormatDER);
2691 return i2d_PUBKEY_bio(bio.get(), pkey) == 1;
2692 }
2693 }
2694 }
2695
WritePublicKey(Environment * env,EVP_PKEY * pkey,const PublicKeyEncodingConfig & config)2696 static MaybeLocal<Value> WritePublicKey(Environment* env,
2697 EVP_PKEY* pkey,
2698 const PublicKeyEncodingConfig& config) {
2699 BIOPointer bio(BIO_new(BIO_s_mem()));
2700 CHECK(bio);
2701
2702 if (!WritePublicKeyInner(pkey, bio, config)) {
2703 ThrowCryptoError(env, ERR_get_error(), "Failed to encode public key");
2704 return MaybeLocal<Value>();
2705 }
2706 return BIOToStringOrBuffer(env, bio.get(), config.format_);
2707 }
2708
IsASN1Sequence(const unsigned char * data,size_t size,size_t * data_offset,size_t * data_size)2709 static bool IsASN1Sequence(const unsigned char* data, size_t size,
2710 size_t* data_offset, size_t* data_size) {
2711 if (size < 2 || data[0] != 0x30)
2712 return false;
2713
2714 if (data[1] & 0x80) {
2715 // Long form.
2716 size_t n_bytes = data[1] & ~0x80;
2717 if (n_bytes + 2 > size || n_bytes > sizeof(size_t))
2718 return false;
2719 size_t length = 0;
2720 for (size_t i = 0; i < n_bytes; i++)
2721 length = (length << 8) | data[i + 2];
2722 *data_offset = 2 + n_bytes;
2723 *data_size = std::min(size - 2 - n_bytes, length);
2724 } else {
2725 // Short form.
2726 *data_offset = 2;
2727 *data_size = std::min<size_t>(size - 2, data[1]);
2728 }
2729
2730 return true;
2731 }
2732
IsRSAPrivateKey(const unsigned char * data,size_t size)2733 static bool IsRSAPrivateKey(const unsigned char* data, size_t size) {
2734 // Both RSAPrivateKey and RSAPublicKey structures start with a SEQUENCE.
2735 size_t offset, len;
2736 if (!IsASN1Sequence(data, size, &offset, &len))
2737 return false;
2738
2739 // An RSAPrivateKey sequence always starts with a single-byte integer whose
2740 // value is either 0 or 1, whereas an RSAPublicKey starts with the modulus
2741 // (which is the product of two primes and therefore at least 4), so we can
2742 // decide the type of the structure based on the first three bytes of the
2743 // sequence.
2744 return len >= 3 &&
2745 data[offset] == 2 &&
2746 data[offset + 1] == 1 &&
2747 !(data[offset + 2] & 0xfe);
2748 }
2749
IsEncryptedPrivateKeyInfo(const unsigned char * data,size_t size)2750 static bool IsEncryptedPrivateKeyInfo(const unsigned char* data, size_t size) {
2751 // Both PrivateKeyInfo and EncryptedPrivateKeyInfo start with a SEQUENCE.
2752 size_t offset, len;
2753 if (!IsASN1Sequence(data, size, &offset, &len))
2754 return false;
2755
2756 // A PrivateKeyInfo sequence always starts with an integer whereas an
2757 // EncryptedPrivateKeyInfo starts with an AlgorithmIdentifier.
2758 return len >= 1 &&
2759 data[offset] != 2;
2760 }
2761
ParsePrivateKey(EVPKeyPointer * pkey,const PrivateKeyEncodingConfig & config,const char * key,size_t key_len)2762 static ParseKeyResult ParsePrivateKey(EVPKeyPointer* pkey,
2763 const PrivateKeyEncodingConfig& config,
2764 const char* key,
2765 size_t key_len) {
2766 // OpenSSL needs a non-const pointer, that's why the const_cast is required.
2767 char* const passphrase = const_cast<char*>(config.passphrase_.get());
2768
2769 if (config.format_ == kKeyFormatPEM) {
2770 BIOPointer bio(BIO_new_mem_buf(key, key_len));
2771 if (!bio)
2772 return ParseKeyResult::kParseKeyFailed;
2773
2774 pkey->reset(PEM_read_bio_PrivateKey(bio.get(),
2775 nullptr,
2776 PasswordCallback,
2777 passphrase));
2778 } else {
2779 CHECK_EQ(config.format_, kKeyFormatDER);
2780
2781 if (config.type_.ToChecked() == kKeyEncodingPKCS1) {
2782 const unsigned char* p = reinterpret_cast<const unsigned char*>(key);
2783 pkey->reset(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &p, key_len));
2784 } else if (config.type_.ToChecked() == kKeyEncodingPKCS8) {
2785 BIOPointer bio(BIO_new_mem_buf(key, key_len));
2786 if (!bio)
2787 return ParseKeyResult::kParseKeyFailed;
2788
2789 if (IsEncryptedPrivateKeyInfo(
2790 reinterpret_cast<const unsigned char*>(key), key_len)) {
2791 pkey->reset(d2i_PKCS8PrivateKey_bio(bio.get(),
2792 nullptr,
2793 PasswordCallback,
2794 passphrase));
2795 } else {
2796 PKCS8Pointer p8inf(d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), nullptr));
2797 if (p8inf)
2798 pkey->reset(EVP_PKCS82PKEY(p8inf.get()));
2799 }
2800 } else {
2801 CHECK_EQ(config.type_.ToChecked(), kKeyEncodingSEC1);
2802 const unsigned char* p = reinterpret_cast<const unsigned char*>(key);
2803 pkey->reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, key_len));
2804 }
2805 }
2806
2807 // OpenSSL can fail to parse the key but still return a non-null pointer.
2808 unsigned long err = ERR_peek_error(); // NOLINT(runtime/int)
2809 if (err != 0)
2810 pkey->reset();
2811
2812 if (*pkey)
2813 return ParseKeyResult::kParseKeyOk;
2814 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
2815 ERR_GET_REASON(err) == PEM_R_BAD_PASSWORD_READ) {
2816 if (config.passphrase_.get() == nullptr)
2817 return ParseKeyResult::kParseKeyNeedPassphrase;
2818 }
2819 return ParseKeyResult::kParseKeyFailed;
2820 }
2821
ByteSource(ByteSource && other)2822 ByteSource::ByteSource(ByteSource&& other)
2823 : data_(other.data_),
2824 allocated_data_(other.allocated_data_),
2825 size_(other.size_) {
2826 other.allocated_data_ = nullptr;
2827 }
2828
~ByteSource()2829 ByteSource::~ByteSource() {
2830 OPENSSL_clear_free(allocated_data_, size_);
2831 }
2832
operator =(ByteSource && other)2833 ByteSource& ByteSource::operator=(ByteSource&& other) {
2834 if (&other != this) {
2835 OPENSSL_clear_free(allocated_data_, size_);
2836 data_ = other.data_;
2837 allocated_data_ = other.allocated_data_;
2838 other.allocated_data_ = nullptr;
2839 size_ = other.size_;
2840 }
2841 return *this;
2842 }
2843
get() const2844 const char* ByteSource::get() const {
2845 return data_;
2846 }
2847
size() const2848 size_t ByteSource::size() const {
2849 return size_;
2850 }
2851
FromStringOrBuffer(Environment * env,Local<Value> value)2852 ByteSource ByteSource::FromStringOrBuffer(Environment* env,
2853 Local<Value> value) {
2854 return Buffer::HasInstance(value) ? FromBuffer(value)
2855 : FromString(env, value.As<String>());
2856 }
2857
FromString(Environment * env,Local<String> str,bool ntc)2858 ByteSource ByteSource::FromString(Environment* env, Local<String> str,
2859 bool ntc) {
2860 CHECK(str->IsString());
2861 size_t size = str->Utf8Length(env->isolate());
2862 size_t alloc_size = ntc ? size + 1 : size;
2863 char* data = MallocOpenSSL<char>(alloc_size);
2864 int opts = String::NO_OPTIONS;
2865 if (!ntc) opts |= String::NO_NULL_TERMINATION;
2866 str->WriteUtf8(env->isolate(), data, alloc_size, nullptr, opts);
2867 return Allocated(data, size);
2868 }
2869
FromBuffer(Local<Value> buffer,bool ntc)2870 ByteSource ByteSource::FromBuffer(Local<Value> buffer, bool ntc) {
2871 CHECK(buffer->IsArrayBufferView());
2872 Local<ArrayBufferView> abv = buffer.As<ArrayBufferView>();
2873 size_t size = abv->ByteLength();
2874 if (ntc) {
2875 char* data = MallocOpenSSL<char>(size + 1);
2876 abv->CopyContents(data, size);
2877 data[size] = 0;
2878 return Allocated(data, size);
2879 }
2880 return Foreign(Buffer::Data(buffer), size);
2881 }
2882
NullTerminatedCopy(Environment * env,Local<Value> value)2883 ByteSource ByteSource::NullTerminatedCopy(Environment* env,
2884 Local<Value> value) {
2885 return Buffer::HasInstance(value) ? FromBuffer(value, true)
2886 : FromString(env, value.As<String>(), true);
2887 }
2888
FromSymmetricKeyObjectHandle(Local<Value> handle)2889 ByteSource ByteSource::FromSymmetricKeyObjectHandle(Local<Value> handle) {
2890 CHECK(handle->IsObject());
2891 KeyObjectHandle* key = Unwrap<KeyObjectHandle>(handle.As<Object>());
2892 CHECK_NOT_NULL(key);
2893 return Foreign(key->Data()->GetSymmetricKey(),
2894 key->Data()->GetSymmetricKeySize());
2895 }
2896
ByteSource(const char * data,char * allocated_data,size_t size)2897 ByteSource::ByteSource(const char* data, char* allocated_data, size_t size)
2898 : data_(data),
2899 allocated_data_(allocated_data),
2900 size_(size) {}
2901
Allocated(char * data,size_t size)2902 ByteSource ByteSource::Allocated(char* data, size_t size) {
2903 return ByteSource(data, data, size);
2904 }
2905
Foreign(const char * data,size_t size)2906 ByteSource ByteSource::Foreign(const char* data, size_t size) {
2907 return ByteSource(data, nullptr, size);
2908 }
2909
2910 enum KeyEncodingContext {
2911 kKeyContextInput,
2912 kKeyContextExport,
2913 kKeyContextGenerate
2914 };
2915
GetKeyFormatAndTypeFromJs(AsymmetricKeyEncodingConfig * config,const FunctionCallbackInfo<Value> & args,unsigned int * offset,KeyEncodingContext context)2916 static void GetKeyFormatAndTypeFromJs(
2917 AsymmetricKeyEncodingConfig* config,
2918 const FunctionCallbackInfo<Value>& args,
2919 unsigned int* offset,
2920 KeyEncodingContext context) {
2921 // During key pair generation, it is possible not to specify a key encoding,
2922 // which will lead to a key object being returned.
2923 if (args[*offset]->IsUndefined()) {
2924 CHECK_EQ(context, kKeyContextGenerate);
2925 CHECK(args[*offset + 1]->IsUndefined());
2926 config->output_key_object_ = true;
2927 } else {
2928 config->output_key_object_ = false;
2929
2930 CHECK(args[*offset]->IsInt32());
2931 config->format_ = static_cast<PKFormatType>(
2932 args[*offset].As<Int32>()->Value());
2933
2934 if (args[*offset + 1]->IsInt32()) {
2935 config->type_ = Just<PKEncodingType>(static_cast<PKEncodingType>(
2936 args[*offset + 1].As<Int32>()->Value()));
2937 } else {
2938 CHECK(context == kKeyContextInput && config->format_ == kKeyFormatPEM);
2939 CHECK(args[*offset + 1]->IsNullOrUndefined());
2940 config->type_ = Nothing<PKEncodingType>();
2941 }
2942 }
2943
2944 *offset += 2;
2945 }
2946
GetPublicKeyEncodingFromJs(const FunctionCallbackInfo<Value> & args,unsigned int * offset,KeyEncodingContext context)2947 static PublicKeyEncodingConfig GetPublicKeyEncodingFromJs(
2948 const FunctionCallbackInfo<Value>& args,
2949 unsigned int* offset,
2950 KeyEncodingContext context) {
2951 PublicKeyEncodingConfig result;
2952 GetKeyFormatAndTypeFromJs(&result, args, offset, context);
2953 return result;
2954 }
2955
GetParsedKey(Environment * env,EVPKeyPointer && pkey,ParseKeyResult ret,const char * default_msg)2956 static inline ManagedEVPPKey GetParsedKey(Environment* env,
2957 EVPKeyPointer&& pkey,
2958 ParseKeyResult ret,
2959 const char* default_msg) {
2960 switch (ret) {
2961 case ParseKeyResult::kParseKeyOk:
2962 CHECK(pkey);
2963 break;
2964 case ParseKeyResult::kParseKeyNeedPassphrase:
2965 THROW_ERR_MISSING_PASSPHRASE(env,
2966 "Passphrase required for encrypted key");
2967 break;
2968 default:
2969 ThrowCryptoError(env, ERR_get_error(), default_msg);
2970 }
2971
2972 return ManagedEVPPKey(std::move(pkey));
2973 }
2974
GetPrivateKeyEncodingFromJs(const FunctionCallbackInfo<Value> & args,unsigned int * offset,KeyEncodingContext context)2975 static NonCopyableMaybe<PrivateKeyEncodingConfig> GetPrivateKeyEncodingFromJs(
2976 const FunctionCallbackInfo<Value>& args,
2977 unsigned int* offset,
2978 KeyEncodingContext context) {
2979 Environment* env = Environment::GetCurrent(args);
2980
2981 PrivateKeyEncodingConfig result;
2982 GetKeyFormatAndTypeFromJs(&result, args, offset, context);
2983
2984 if (result.output_key_object_) {
2985 if (context != kKeyContextInput)
2986 (*offset)++;
2987 } else {
2988 bool needs_passphrase = false;
2989 if (context != kKeyContextInput) {
2990 if (args[*offset]->IsString()) {
2991 String::Utf8Value cipher_name(env->isolate(),
2992 args[*offset].As<String>());
2993 result.cipher_ = EVP_get_cipherbyname(*cipher_name);
2994 if (result.cipher_ == nullptr) {
2995 THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env);
2996 return NonCopyableMaybe<PrivateKeyEncodingConfig>();
2997 }
2998 needs_passphrase = true;
2999 } else {
3000 CHECK(args[*offset]->IsNullOrUndefined());
3001 result.cipher_ = nullptr;
3002 }
3003 (*offset)++;
3004 }
3005
3006 if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
3007 CHECK_IMPLIES(context != kKeyContextInput, result.cipher_ != nullptr);
3008
3009 result.passphrase_ = ByteSource::NullTerminatedCopy(env, args[*offset]);
3010 } else {
3011 CHECK(args[*offset]->IsNullOrUndefined() && !needs_passphrase);
3012 }
3013 }
3014
3015 (*offset)++;
3016 return NonCopyableMaybe<PrivateKeyEncodingConfig>(std::move(result));
3017 }
3018
GetPrivateKeyFromJs(const FunctionCallbackInfo<Value> & args,unsigned int * offset,bool allow_key_object)3019 static ManagedEVPPKey GetPrivateKeyFromJs(
3020 const FunctionCallbackInfo<Value>& args,
3021 unsigned int* offset,
3022 bool allow_key_object) {
3023 if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
3024 Environment* env = Environment::GetCurrent(args);
3025 ByteSource key = ByteSource::FromStringOrBuffer(env, args[(*offset)++]);
3026 NonCopyableMaybe<PrivateKeyEncodingConfig> config =
3027 GetPrivateKeyEncodingFromJs(args, offset, kKeyContextInput);
3028 if (config.IsEmpty())
3029 return ManagedEVPPKey();
3030
3031 EVPKeyPointer pkey;
3032 ParseKeyResult ret =
3033 ParsePrivateKey(&pkey, config.Release(), key.get(), key.size());
3034 return GetParsedKey(env, std::move(pkey), ret,
3035 "Failed to read private key");
3036 } else {
3037 CHECK(args[*offset]->IsObject() && allow_key_object);
3038 KeyObjectHandle* key;
3039 ASSIGN_OR_RETURN_UNWRAP(&key, args[*offset].As<Object>(), ManagedEVPPKey());
3040 CHECK_EQ(key->Data()->GetKeyType(), kKeyTypePrivate);
3041 (*offset) += 4;
3042 return key->Data()->GetAsymmetricKey();
3043 }
3044 }
3045
GetPublicOrPrivateKeyFromJs(const FunctionCallbackInfo<Value> & args,unsigned int * offset)3046 static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
3047 const FunctionCallbackInfo<Value>& args,
3048 unsigned int* offset) {
3049 if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
3050 Environment* env = Environment::GetCurrent(args);
3051 ByteSource data = ByteSource::FromStringOrBuffer(env, args[(*offset)++]);
3052 NonCopyableMaybe<PrivateKeyEncodingConfig> config_ =
3053 GetPrivateKeyEncodingFromJs(args, offset, kKeyContextInput);
3054 if (config_.IsEmpty())
3055 return ManagedEVPPKey();
3056
3057 ParseKeyResult ret;
3058 PrivateKeyEncodingConfig config = config_.Release();
3059 EVPKeyPointer pkey;
3060 if (config.format_ == kKeyFormatPEM) {
3061 // For PEM, we can easily determine whether it is a public or private key
3062 // by looking for the respective PEM tags.
3063 ret = ParsePublicKeyPEM(&pkey, data.get(), data.size());
3064 if (ret == ParseKeyResult::kParseKeyNotRecognized) {
3065 ret = ParsePrivateKey(&pkey, config, data.get(), data.size());
3066 }
3067 } else {
3068 // For DER, the type determines how to parse it. SPKI, PKCS#8 and SEC1 are
3069 // easy, but PKCS#1 can be a public key or a private key.
3070 bool is_public;
3071 switch (config.type_.ToChecked()) {
3072 case kKeyEncodingPKCS1:
3073 is_public = !IsRSAPrivateKey(
3074 reinterpret_cast<const unsigned char*>(data.get()), data.size());
3075 break;
3076 case kKeyEncodingSPKI:
3077 is_public = true;
3078 break;
3079 case kKeyEncodingPKCS8:
3080 case kKeyEncodingSEC1:
3081 is_public = false;
3082 break;
3083 default:
3084 UNREACHABLE("Invalid key encoding type");
3085 }
3086
3087 if (is_public) {
3088 ret = ParsePublicKey(&pkey, config, data.get(), data.size());
3089 } else {
3090 ret = ParsePrivateKey(&pkey, config, data.get(), data.size());
3091 }
3092 }
3093
3094 return GetParsedKey(env, std::move(pkey), ret,
3095 "Failed to read asymmetric key");
3096 } else {
3097 CHECK(args[*offset]->IsObject());
3098 KeyObjectHandle* key = Unwrap<KeyObjectHandle>(args[*offset].As<Object>());
3099 CHECK_NOT_NULL(key);
3100 CHECK_NE(key->Data()->GetKeyType(), kKeyTypeSecret);
3101 (*offset) += 4;
3102 return key->Data()->GetAsymmetricKey();
3103 }
3104 }
3105
WritePrivateKey(Environment * env,EVP_PKEY * pkey,const PrivateKeyEncodingConfig & config)3106 static MaybeLocal<Value> WritePrivateKey(
3107 Environment* env,
3108 EVP_PKEY* pkey,
3109 const PrivateKeyEncodingConfig& config) {
3110 BIOPointer bio(BIO_new(BIO_s_mem()));
3111 CHECK(bio);
3112
3113 bool err;
3114
3115 PKEncodingType encoding_type = config.type_.ToChecked();
3116 if (encoding_type == kKeyEncodingPKCS1) {
3117 // PKCS#1 is only permitted for RSA keys.
3118 CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_RSA);
3119
3120 RSAPointer rsa(EVP_PKEY_get1_RSA(pkey));
3121 if (config.format_ == kKeyFormatPEM) {
3122 // Encode PKCS#1 as PEM.
3123 const char* pass = config.passphrase_.get();
3124 err = PEM_write_bio_RSAPrivateKey(
3125 bio.get(), rsa.get(),
3126 config.cipher_,
3127 reinterpret_cast<unsigned char*>(const_cast<char*>(pass)),
3128 config.passphrase_.size(),
3129 nullptr, nullptr) != 1;
3130 } else {
3131 // Encode PKCS#1 as DER. This does not permit encryption.
3132 CHECK_EQ(config.format_, kKeyFormatDER);
3133 CHECK_NULL(config.cipher_);
3134 err = i2d_RSAPrivateKey_bio(bio.get(), rsa.get()) != 1;
3135 }
3136 } else if (encoding_type == kKeyEncodingPKCS8) {
3137 if (config.format_ == kKeyFormatPEM) {
3138 // Encode PKCS#8 as PEM.
3139 err = PEM_write_bio_PKCS8PrivateKey(
3140 bio.get(), pkey,
3141 config.cipher_,
3142 const_cast<char*>(config.passphrase_.get()),
3143 config.passphrase_.size(),
3144 nullptr, nullptr) != 1;
3145 } else {
3146 // Encode PKCS#8 as DER.
3147 CHECK_EQ(config.format_, kKeyFormatDER);
3148 err = i2d_PKCS8PrivateKey_bio(
3149 bio.get(), pkey,
3150 config.cipher_,
3151 const_cast<char*>(config.passphrase_.get()),
3152 config.passphrase_.size(),
3153 nullptr, nullptr) != 1;
3154 }
3155 } else {
3156 CHECK_EQ(encoding_type, kKeyEncodingSEC1);
3157
3158 // SEC1 is only permitted for EC keys.
3159 CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_EC);
3160
3161 ECKeyPointer ec_key(EVP_PKEY_get1_EC_KEY(pkey));
3162 if (config.format_ == kKeyFormatPEM) {
3163 // Encode SEC1 as PEM.
3164 const char* pass = config.passphrase_.get();
3165 err = PEM_write_bio_ECPrivateKey(
3166 bio.get(), ec_key.get(),
3167 config.cipher_,
3168 reinterpret_cast<unsigned char*>(const_cast<char*>(pass)),
3169 config.passphrase_.size(),
3170 nullptr, nullptr) != 1;
3171 } else {
3172 // Encode SEC1 as DER. This does not permit encryption.
3173 CHECK_EQ(config.format_, kKeyFormatDER);
3174 CHECK_NULL(config.cipher_);
3175 err = i2d_ECPrivateKey_bio(bio.get(), ec_key.get()) != 1;
3176 }
3177 }
3178
3179 if (err) {
3180 ThrowCryptoError(env, ERR_get_error(), "Failed to encode private key");
3181 return MaybeLocal<Value>();
3182 }
3183 return BIOToStringOrBuffer(env, bio.get(), config.format_);
3184 }
3185
ManagedEVPPKey(EVPKeyPointer && pkey)3186 ManagedEVPPKey::ManagedEVPPKey(EVPKeyPointer&& pkey) : pkey_(std::move(pkey)) {}
3187
ManagedEVPPKey(const ManagedEVPPKey & that)3188 ManagedEVPPKey::ManagedEVPPKey(const ManagedEVPPKey& that) {
3189 *this = that;
3190 }
3191
operator =(const ManagedEVPPKey & that)3192 ManagedEVPPKey& ManagedEVPPKey::operator=(const ManagedEVPPKey& that) {
3193 pkey_.reset(that.get());
3194
3195 if (pkey_)
3196 EVP_PKEY_up_ref(pkey_.get());
3197
3198 return *this;
3199 }
3200
operator bool() const3201 ManagedEVPPKey::operator bool() const {
3202 return !!pkey_;
3203 }
3204
get() const3205 EVP_PKEY* ManagedEVPPKey::get() const {
3206 return pkey_.get();
3207 }
3208
CreateSecret(Local<ArrayBufferView> abv)3209 std::shared_ptr<KeyObjectData> KeyObjectData::CreateSecret(
3210 Local<ArrayBufferView> abv) {
3211 size_t key_len = abv->ByteLength();
3212 char* mem = MallocOpenSSL<char>(key_len);
3213 abv->CopyContents(mem, key_len);
3214 return std::shared_ptr<KeyObjectData>(new KeyObjectData(
3215 std::unique_ptr<char, std::function<void(char*)>>(mem,
3216 [key_len](char* p) {
3217 OPENSSL_clear_free(p, key_len);
3218 }),
3219 key_len));
3220 }
3221
CreateAsymmetric(KeyType key_type,const ManagedEVPPKey & pkey)3222 std::shared_ptr<KeyObjectData> KeyObjectData::CreateAsymmetric(
3223 KeyType key_type,
3224 const ManagedEVPPKey& pkey) {
3225 CHECK(pkey);
3226 return std::shared_ptr<KeyObjectData>(new KeyObjectData(key_type, pkey));
3227 }
3228
GetKeyType() const3229 KeyType KeyObjectData::GetKeyType() const {
3230 return key_type_;
3231 }
3232
GetAsymmetricKey() const3233 ManagedEVPPKey KeyObjectData::GetAsymmetricKey() const {
3234 CHECK_NE(key_type_, kKeyTypeSecret);
3235 return asymmetric_key_;
3236 }
3237
GetSymmetricKey() const3238 const char* KeyObjectData::GetSymmetricKey() const {
3239 CHECK_EQ(key_type_, kKeyTypeSecret);
3240 return symmetric_key_.get();
3241 }
3242
GetSymmetricKeySize() const3243 size_t KeyObjectData::GetSymmetricKeySize() const {
3244 CHECK_EQ(key_type_, kKeyTypeSecret);
3245 return symmetric_key_len_;
3246 }
3247
Initialize(Environment * env)3248 Local<Function> KeyObjectHandle::Initialize(Environment* env) {
3249 Local<Function> templ = env->crypto_key_object_handle_constructor();
3250 if (!templ.IsEmpty()) {
3251 return templ;
3252 }
3253 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3254 t->InstanceTemplate()->SetInternalFieldCount(
3255 KeyObjectHandle::kInternalFieldCount);
3256 t->Inherit(BaseObject::GetConstructorTemplate(env));
3257
3258 env->SetProtoMethod(t, "init", Init);
3259 env->SetProtoMethodNoSideEffect(t, "getSymmetricKeySize",
3260 GetSymmetricKeySize);
3261 env->SetProtoMethodNoSideEffect(t, "getAsymmetricKeyType",
3262 GetAsymmetricKeyType);
3263 env->SetProtoMethod(t, "export", Export);
3264
3265 auto function = t->GetFunction(env->context()).ToLocalChecked();
3266 env->set_crypto_key_object_handle_constructor(function);
3267 return KeyObjectHandle::Initialize(env);
3268 }
3269
Create(Environment * env,std::shared_ptr<KeyObjectData> data)3270 MaybeLocal<Object> KeyObjectHandle::Create(
3271 Environment* env,
3272 std::shared_ptr<KeyObjectData> data) {
3273 Local<Object> obj;
3274 Local<Function> fctun = KeyObjectHandle::Initialize(env);
3275 if (!fctun->NewInstance(env->context(), 0, nullptr).ToLocal(&obj)) {
3276 return MaybeLocal<Object>();
3277 }
3278
3279 KeyObjectHandle* key = Unwrap<KeyObjectHandle>(obj);
3280 CHECK_NOT_NULL(key);
3281 key->data_ = data;
3282 return obj;
3283 }
3284
Data()3285 const std::shared_ptr<KeyObjectData>& KeyObjectHandle::Data() {
3286 return data_;
3287 }
3288
New(const FunctionCallbackInfo<Value> & args)3289 void KeyObjectHandle::New(const FunctionCallbackInfo<Value>& args) {
3290 CHECK(args.IsConstructCall());
3291 Environment* env = Environment::GetCurrent(args);
3292 new KeyObjectHandle(env, args.This());
3293 }
3294
KeyObjectHandle(Environment * env,Local<Object> wrap)3295 KeyObjectHandle::KeyObjectHandle(Environment* env,
3296 Local<Object> wrap)
3297 : BaseObject(env, wrap) {
3298 MakeWeak();
3299 }
3300
Init(const FunctionCallbackInfo<Value> & args)3301 void KeyObjectHandle::Init(const FunctionCallbackInfo<Value>& args) {
3302 KeyObjectHandle* key;
3303 ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
3304 MarkPopErrorOnReturn mark_pop_error_on_return;
3305
3306 CHECK(args[0]->IsInt32());
3307 KeyType type = static_cast<KeyType>(args[0].As<Uint32>()->Value());
3308
3309 unsigned int offset;
3310 ManagedEVPPKey pkey;
3311
3312 switch (type) {
3313 case kKeyTypeSecret:
3314 CHECK_EQ(args.Length(), 2);
3315 CHECK(args[1]->IsArrayBufferView());
3316 key->data_ = KeyObjectData::CreateSecret(args[1].As<ArrayBufferView>());
3317 break;
3318 case kKeyTypePublic:
3319 CHECK_EQ(args.Length(), 4);
3320
3321 offset = 1;
3322 pkey = GetPublicOrPrivateKeyFromJs(args, &offset);
3323 if (!pkey)
3324 return;
3325 key->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
3326 break;
3327 case kKeyTypePrivate:
3328 CHECK_EQ(args.Length(), 5);
3329
3330 offset = 1;
3331 pkey = GetPrivateKeyFromJs(args, &offset, false);
3332 if (!pkey)
3333 return;
3334 key->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
3335 break;
3336 default:
3337 CHECK(false);
3338 }
3339 }
3340
GetAsymmetricKeyType() const3341 Local<Value> KeyObjectHandle::GetAsymmetricKeyType() const {
3342 const ManagedEVPPKey& key = data_->GetAsymmetricKey();
3343 switch (EVP_PKEY_id(key.get())) {
3344 case EVP_PKEY_RSA:
3345 return env()->crypto_rsa_string();
3346 case EVP_PKEY_RSA_PSS:
3347 return env()->crypto_rsa_pss_string();
3348 case EVP_PKEY_DSA:
3349 return env()->crypto_dsa_string();
3350 case EVP_PKEY_DH:
3351 return env()->crypto_dh_string();
3352 case EVP_PKEY_EC:
3353 return env()->crypto_ec_string();
3354 case EVP_PKEY_ED25519:
3355 return env()->crypto_ed25519_string();
3356 case EVP_PKEY_ED448:
3357 return env()->crypto_ed448_string();
3358 case EVP_PKEY_X25519:
3359 return env()->crypto_x25519_string();
3360 case EVP_PKEY_X448:
3361 return env()->crypto_x448_string();
3362 default:
3363 return Undefined(env()->isolate());
3364 }
3365 }
3366
GetAsymmetricKeyType(const FunctionCallbackInfo<Value> & args)3367 void KeyObjectHandle::GetAsymmetricKeyType(
3368 const FunctionCallbackInfo<Value>& args) {
3369 KeyObjectHandle* key;
3370 ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
3371
3372 args.GetReturnValue().Set(key->GetAsymmetricKeyType());
3373 }
3374
GetSymmetricKeySize(const FunctionCallbackInfo<Value> & args)3375 void KeyObjectHandle::GetSymmetricKeySize(
3376 const FunctionCallbackInfo<Value>& args) {
3377 KeyObjectHandle* key;
3378 ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
3379 args.GetReturnValue().Set(
3380 static_cast<uint32_t>(key->Data()->GetSymmetricKeySize()));
3381 }
3382
Export(const FunctionCallbackInfo<Value> & args)3383 void KeyObjectHandle::Export(const FunctionCallbackInfo<Value>& args) {
3384 KeyObjectHandle* key;
3385 ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
3386
3387 KeyType type = key->Data()->GetKeyType();
3388
3389 MaybeLocal<Value> result;
3390 if (type == kKeyTypeSecret) {
3391 result = key->ExportSecretKey();
3392 } else if (type == kKeyTypePublic) {
3393 unsigned int offset = 0;
3394 PublicKeyEncodingConfig config =
3395 GetPublicKeyEncodingFromJs(args, &offset, kKeyContextExport);
3396 CHECK_EQ(offset, static_cast<unsigned int>(args.Length()));
3397 result = key->ExportPublicKey(config);
3398 } else {
3399 CHECK_EQ(type, kKeyTypePrivate);
3400 unsigned int offset = 0;
3401 NonCopyableMaybe<PrivateKeyEncodingConfig> config =
3402 GetPrivateKeyEncodingFromJs(args, &offset, kKeyContextExport);
3403 if (config.IsEmpty())
3404 return;
3405 CHECK_EQ(offset, static_cast<unsigned int>(args.Length()));
3406 result = key->ExportPrivateKey(config.Release());
3407 }
3408
3409 if (!result.IsEmpty())
3410 args.GetReturnValue().Set(result.ToLocalChecked());
3411 }
3412
ExportSecretKey() const3413 Local<Value> KeyObjectHandle::ExportSecretKey() const {
3414 const char* buf = data_->GetSymmetricKey();
3415 unsigned int len = data_->GetSymmetricKeySize();
3416 return Buffer::Copy(env(), buf, len).ToLocalChecked();
3417 }
3418
ExportPublicKey(const PublicKeyEncodingConfig & config) const3419 MaybeLocal<Value> KeyObjectHandle::ExportPublicKey(
3420 const PublicKeyEncodingConfig& config) const {
3421 return WritePublicKey(env(), data_->GetAsymmetricKey().get(), config);
3422 }
3423
ExportPrivateKey(const PrivateKeyEncodingConfig & config) const3424 MaybeLocal<Value> KeyObjectHandle::ExportPrivateKey(
3425 const PrivateKeyEncodingConfig& config) const {
3426 return WritePrivateKey(env(), data_->GetAsymmetricKey().get(), config);
3427 }
3428
New(const FunctionCallbackInfo<Value> & args)3429 void NativeKeyObject::New(const FunctionCallbackInfo<Value>& args) {
3430 Environment* env = Environment::GetCurrent(args);
3431 CHECK_EQ(args.Length(), 1);
3432 CHECK(args[0]->IsObject());
3433 KeyObjectHandle* handle = Unwrap<KeyObjectHandle>(args[0].As<Object>());
3434 new NativeKeyObject(env, args.This(), handle->Data());
3435 }
3436
Deserialize(Environment * env,Local<Context> context,std::unique_ptr<worker::TransferData> self)3437 BaseObjectPtr<BaseObject> NativeKeyObject::KeyObjectTransferData::Deserialize(
3438 Environment* env,
3439 Local<Context> context,
3440 std::unique_ptr<worker::TransferData> self) {
3441 if (context != env->context()) {
3442 THROW_ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE(env);
3443 return {};
3444 }
3445
3446 Local<Value> handle = KeyObjectHandle::Create(env, data_).ToLocalChecked();
3447 Local<Function> key_ctor;
3448 Local<Value> arg = FIXED_ONE_BYTE_STRING(env->isolate(),
3449 "internal/crypto/keys");
3450 if (env->native_module_require()->
3451 Call(context, Null(env->isolate()), 1, &arg).IsEmpty())
3452 return {};
3453 switch (data_->GetKeyType()) {
3454 case kKeyTypeSecret:
3455 key_ctor = env->crypto_key_object_secret_constructor();
3456 break;
3457 case kKeyTypePublic:
3458 key_ctor = env->crypto_key_object_public_constructor();
3459 break;
3460 case kKeyTypePrivate:
3461 key_ctor = env->crypto_key_object_private_constructor();
3462 break;
3463 default:
3464 CHECK(false);
3465 }
3466
3467 Local<Value> key =
3468 key_ctor->NewInstance(context, 1, &handle).ToLocalChecked();
3469 return BaseObjectPtr<BaseObject>(Unwrap<KeyObjectHandle>(key.As<Object>()));
3470 }
3471
GetTransferMode() const3472 BaseObject::TransferMode NativeKeyObject::GetTransferMode() const {
3473 return BaseObject::TransferMode::kCloneable;
3474 }
3475
CloneForMessaging() const3476 std::unique_ptr<worker::TransferData> NativeKeyObject::CloneForMessaging()
3477 const {
3478 return std::make_unique<KeyObjectTransferData>(handle_data_);
3479 }
3480
CreateNativeKeyObjectClass(const FunctionCallbackInfo<Value> & args)3481 static void CreateNativeKeyObjectClass(
3482 const FunctionCallbackInfo<Value>& args) {
3483 Environment* env = Environment::GetCurrent(args);
3484
3485 CHECK_EQ(args.Length(), 1);
3486 Local<Value> callback = args[0];
3487 CHECK(callback->IsFunction());
3488
3489 Local<FunctionTemplate> t = env->NewFunctionTemplate(NativeKeyObject::New);
3490 t->InstanceTemplate()->SetInternalFieldCount(
3491 KeyObjectHandle::kInternalFieldCount);
3492 t->Inherit(BaseObject::GetConstructorTemplate(env));
3493
3494 Local<Value> ctor = t->GetFunction(env->context()).ToLocalChecked();
3495
3496 Local<Value> recv = Undefined(env->isolate());
3497 Local<Value> ret_v;
3498 if (!callback.As<Function>()->Call(
3499 env->context(), recv, 1, &ctor).ToLocal(&ret_v)) {
3500 return;
3501 }
3502 Local<Array> ret = ret_v.As<Array>();
3503 if (!ret->Get(env->context(), 1).ToLocal(&ctor)) return;
3504 env->set_crypto_key_object_secret_constructor(ctor.As<Function>());
3505 if (!ret->Get(env->context(), 2).ToLocal(&ctor)) return;
3506 env->set_crypto_key_object_public_constructor(ctor.As<Function>());
3507 if (!ret->Get(env->context(), 3).ToLocal(&ctor)) return;
3508 env->set_crypto_key_object_private_constructor(ctor.As<Function>());
3509 args.GetReturnValue().Set(ret);
3510 }
3511
CipherBase(Environment * env,Local<Object> wrap,CipherKind kind)3512 CipherBase::CipherBase(Environment* env,
3513 Local<Object> wrap,
3514 CipherKind kind)
3515 : BaseObject(env, wrap),
3516 ctx_(nullptr),
3517 kind_(kind),
3518 auth_tag_state_(kAuthTagUnknown),
3519 auth_tag_len_(kNoAuthTagLength),
3520 pending_auth_failed_(false) {
3521 MakeWeak();
3522 }
3523
Initialize(Environment * env,Local<Object> target)3524 void CipherBase::Initialize(Environment* env, Local<Object> target) {
3525 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3526
3527 t->InstanceTemplate()->SetInternalFieldCount(
3528 CipherBase::kInternalFieldCount);
3529 t->Inherit(BaseObject::GetConstructorTemplate(env));
3530
3531 env->SetProtoMethod(t, "init", Init);
3532 env->SetProtoMethod(t, "initiv", InitIv);
3533 env->SetProtoMethod(t, "update", Update);
3534 env->SetProtoMethod(t, "final", Final);
3535 env->SetProtoMethod(t, "setAutoPadding", SetAutoPadding);
3536 env->SetProtoMethodNoSideEffect(t, "getAuthTag", GetAuthTag);
3537 env->SetProtoMethod(t, "setAuthTag", SetAuthTag);
3538 env->SetProtoMethod(t, "setAAD", SetAAD);
3539
3540 target->Set(env->context(),
3541 FIXED_ONE_BYTE_STRING(env->isolate(), "CipherBase"),
3542 t->GetFunction(env->context()).ToLocalChecked()).Check();
3543 }
3544
3545
New(const FunctionCallbackInfo<Value> & args)3546 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
3547 CHECK(args.IsConstructCall());
3548 CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
3549 Environment* env = Environment::GetCurrent(args);
3550 new CipherBase(env, args.This(), kind);
3551 }
3552
CommonInit(const char * cipher_type,const EVP_CIPHER * cipher,const unsigned char * key,int key_len,const unsigned char * iv,int iv_len,unsigned int auth_tag_len)3553 void CipherBase::CommonInit(const char* cipher_type,
3554 const EVP_CIPHER* cipher,
3555 const unsigned char* key,
3556 int key_len,
3557 const unsigned char* iv,
3558 int iv_len,
3559 unsigned int auth_tag_len) {
3560 CHECK(!ctx_);
3561 ctx_.reset(EVP_CIPHER_CTX_new());
3562
3563 const int mode = EVP_CIPHER_mode(cipher);
3564 if (mode == EVP_CIPH_WRAP_MODE)
3565 EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
3566
3567 const bool encrypt = (kind_ == kCipher);
3568 if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
3569 nullptr, nullptr, encrypt)) {
3570 return ThrowCryptoError(env(), ERR_get_error(),
3571 "Failed to initialize cipher");
3572 }
3573
3574 if (IsSupportedAuthenticatedMode(cipher)) {
3575 CHECK_GE(iv_len, 0);
3576 if (!InitAuthenticated(cipher_type, iv_len, auth_tag_len))
3577 return;
3578 }
3579
3580 if (!EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len)) {
3581 ctx_.reset();
3582 return env()->ThrowError("Invalid key length");
3583 }
3584
3585 if (1 != EVP_CipherInit_ex(ctx_.get(), nullptr, nullptr, key, iv, encrypt)) {
3586 return ThrowCryptoError(env(), ERR_get_error(),
3587 "Failed to initialize cipher");
3588 }
3589 }
3590
Init(const char * cipher_type,const char * key_buf,int key_buf_len,unsigned int auth_tag_len)3591 void CipherBase::Init(const char* cipher_type,
3592 const char* key_buf,
3593 int key_buf_len,
3594 unsigned int auth_tag_len) {
3595 HandleScope scope(env()->isolate());
3596 MarkPopErrorOnReturn mark_pop_error_on_return;
3597
3598 #ifdef NODE_FIPS_MODE
3599 if (FIPS_mode()) {
3600 return env()->ThrowError(
3601 "crypto.createCipher() is not supported in FIPS mode.");
3602 }
3603 #endif // NODE_FIPS_MODE
3604
3605 const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
3606 if (cipher == nullptr)
3607 return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
3608
3609 unsigned char key[EVP_MAX_KEY_LENGTH];
3610 unsigned char iv[EVP_MAX_IV_LENGTH];
3611
3612 int key_len = EVP_BytesToKey(cipher,
3613 EVP_md5(),
3614 nullptr,
3615 reinterpret_cast<const unsigned char*>(key_buf),
3616 key_buf_len,
3617 1,
3618 key,
3619 iv);
3620 CHECK_NE(key_len, 0);
3621
3622 const int mode = EVP_CIPHER_mode(cipher);
3623 if (kind_ == kCipher && (mode == EVP_CIPH_CTR_MODE ||
3624 mode == EVP_CIPH_GCM_MODE ||
3625 mode == EVP_CIPH_CCM_MODE)) {
3626 // Ignore the return value (i.e. possible exception) because we are
3627 // not calling back into JS anyway.
3628 ProcessEmitWarning(env(),
3629 "Use Cipheriv for counter mode of %s",
3630 cipher_type);
3631 }
3632
3633 CommonInit(cipher_type, cipher, key, key_len, iv,
3634 EVP_CIPHER_iv_length(cipher), auth_tag_len);
3635 }
3636
3637
Init(const FunctionCallbackInfo<Value> & args)3638 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
3639 CipherBase* cipher;
3640 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3641
3642 CHECK_GE(args.Length(), 3);
3643
3644 const node::Utf8Value cipher_type(args.GetIsolate(), args[0]);
3645 ArrayBufferViewContents<char> key_buf(args[1]);
3646
3647 // Don't assign to cipher->auth_tag_len_ directly; the value might not
3648 // represent a valid length at this point.
3649 unsigned int auth_tag_len;
3650 if (args[2]->IsUint32()) {
3651 auth_tag_len = args[2].As<Uint32>()->Value();
3652 } else {
3653 CHECK(args[2]->IsInt32() && args[2].As<Int32>()->Value() == -1);
3654 auth_tag_len = kNoAuthTagLength;
3655 }
3656
3657 cipher->Init(*cipher_type, key_buf.data(), key_buf.length(), auth_tag_len);
3658 }
3659
InitIv(const char * cipher_type,const unsigned char * key,int key_len,const unsigned char * iv,int iv_len,unsigned int auth_tag_len)3660 void CipherBase::InitIv(const char* cipher_type,
3661 const unsigned char* key,
3662 int key_len,
3663 const unsigned char* iv,
3664 int iv_len,
3665 unsigned int auth_tag_len) {
3666 HandleScope scope(env()->isolate());
3667 MarkPopErrorOnReturn mark_pop_error_on_return;
3668
3669 const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
3670 if (cipher == nullptr) {
3671 return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
3672 }
3673
3674 const int expected_iv_len = EVP_CIPHER_iv_length(cipher);
3675 const bool is_authenticated_mode = IsSupportedAuthenticatedMode(cipher);
3676 const bool has_iv = iv_len >= 0;
3677
3678 // Throw if no IV was passed and the cipher requires an IV
3679 if (!has_iv && expected_iv_len != 0) {
3680 char msg[128];
3681 snprintf(msg, sizeof(msg), "Missing IV for cipher %s", cipher_type);
3682 return env()->ThrowError(msg);
3683 }
3684
3685 // Throw if an IV was passed which does not match the cipher's fixed IV length
3686 if (!is_authenticated_mode && has_iv && iv_len != expected_iv_len) {
3687 return env()->ThrowError("Invalid IV length");
3688 }
3689
3690 if (EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305) {
3691 CHECK(has_iv);
3692 // Check for invalid IV lengths, since OpenSSL does not under some
3693 // conditions:
3694 // https://www.openssl.org/news/secadv/20190306.txt.
3695 if (iv_len > 12) {
3696 return env()->ThrowError("Invalid IV length");
3697 }
3698 }
3699
3700 CommonInit(cipher_type, cipher, key, key_len, iv, iv_len, auth_tag_len);
3701 }
3702
3703
GetSecretKeyBytes(Environment * env,Local<Value> value)3704 static ByteSource GetSecretKeyBytes(Environment* env, Local<Value> value) {
3705 // A key can be passed as a string, buffer or KeyObject with type 'secret'.
3706 // If it is a string, we need to convert it to a buffer. We are not doing that
3707 // in JS to avoid creating an unprotected copy on the heap.
3708 return value->IsString() || Buffer::HasInstance(value) ?
3709 ByteSource::FromStringOrBuffer(env, value) :
3710 ByteSource::FromSymmetricKeyObjectHandle(value);
3711 }
3712
InitIv(const FunctionCallbackInfo<Value> & args)3713 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
3714 CipherBase* cipher;
3715 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3716 Environment* env = cipher->env();
3717
3718 CHECK_GE(args.Length(), 4);
3719
3720 const node::Utf8Value cipher_type(env->isolate(), args[0]);
3721 const ByteSource key = GetSecretKeyBytes(env, args[1]);
3722
3723 ArrayBufferViewContents<unsigned char> iv_buf;
3724 ssize_t iv_len = -1;
3725 if (!args[2]->IsNull()) {
3726 CHECK(args[2]->IsArrayBufferView());
3727 iv_buf.Read(args[2].As<ArrayBufferView>());
3728 iv_len = iv_buf.length();
3729 }
3730
3731 // Don't assign to cipher->auth_tag_len_ directly; the value might not
3732 // represent a valid length at this point.
3733 unsigned int auth_tag_len;
3734 if (args[3]->IsUint32()) {
3735 auth_tag_len = args[3].As<Uint32>()->Value();
3736 } else {
3737 CHECK(args[3]->IsInt32() && args[3].As<Int32>()->Value() == -1);
3738 auth_tag_len = kNoAuthTagLength;
3739 }
3740
3741 cipher->InitIv(*cipher_type,
3742 reinterpret_cast<const unsigned char*>(key.get()),
3743 key.size(),
3744 iv_buf.data(),
3745 static_cast<int>(iv_len),
3746 auth_tag_len);
3747 }
3748
3749
IsValidGCMTagLength(unsigned int tag_len)3750 static bool IsValidGCMTagLength(unsigned int tag_len) {
3751 return tag_len == 4 || tag_len == 8 || (tag_len >= 12 && tag_len <= 16);
3752 }
3753
InitAuthenticated(const char * cipher_type,int iv_len,unsigned int auth_tag_len)3754 bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
3755 unsigned int auth_tag_len) {
3756 CHECK(IsAuthenticatedMode());
3757 MarkPopErrorOnReturn mark_pop_error_on_return;
3758
3759 if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
3760 EVP_CTRL_AEAD_SET_IVLEN,
3761 iv_len,
3762 nullptr)) {
3763 env()->ThrowError("Invalid IV length");
3764 return false;
3765 }
3766
3767 const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
3768 if (mode == EVP_CIPH_GCM_MODE) {
3769 if (auth_tag_len != kNoAuthTagLength) {
3770 if (!IsValidGCMTagLength(auth_tag_len)) {
3771 char msg[50];
3772 snprintf(msg, sizeof(msg),
3773 "Invalid authentication tag length: %u", auth_tag_len);
3774 env()->ThrowError(msg);
3775 return false;
3776 }
3777
3778 // Remember the given authentication tag length for later.
3779 auth_tag_len_ = auth_tag_len;
3780 }
3781 } else {
3782 if (auth_tag_len == kNoAuthTagLength) {
3783 char msg[128];
3784 snprintf(msg, sizeof(msg), "authTagLength required for %s", cipher_type);
3785 env()->ThrowError(msg);
3786 return false;
3787 }
3788
3789 #ifdef NODE_FIPS_MODE
3790 // TODO(tniessen) Support CCM decryption in FIPS mode
3791 if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && FIPS_mode()) {
3792 env()->ThrowError("CCM decryption not supported in FIPS mode");
3793 return false;
3794 }
3795 #endif
3796
3797 // Tell OpenSSL about the desired length.
3798 if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
3799 nullptr)) {
3800 env()->ThrowError("Invalid authentication tag length");
3801 return false;
3802 }
3803
3804 // Remember the given authentication tag length for later.
3805 auth_tag_len_ = auth_tag_len;
3806
3807 if (mode == EVP_CIPH_CCM_MODE) {
3808 // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes.
3809 CHECK(iv_len >= 7 && iv_len <= 13);
3810 max_message_size_ = INT_MAX;
3811 if (iv_len == 12) max_message_size_ = 16777215;
3812 if (iv_len == 13) max_message_size_ = 65535;
3813 }
3814 }
3815
3816 return true;
3817 }
3818
3819
CheckCCMMessageLength(int message_len)3820 bool CipherBase::CheckCCMMessageLength(int message_len) {
3821 CHECK(ctx_);
3822 CHECK(EVP_CIPHER_CTX_mode(ctx_.get()) == EVP_CIPH_CCM_MODE);
3823
3824 if (message_len > max_message_size_) {
3825 env()->ThrowError("Message exceeds maximum size");
3826 return false;
3827 }
3828
3829 return true;
3830 }
3831
3832
IsAuthenticatedMode() const3833 bool CipherBase::IsAuthenticatedMode() const {
3834 // Check if this cipher operates in an AEAD mode that we support.
3835 CHECK(ctx_);
3836 return IsSupportedAuthenticatedMode(ctx_.get());
3837 }
3838
3839
GetAuthTag(const FunctionCallbackInfo<Value> & args)3840 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
3841 Environment* env = Environment::GetCurrent(args);
3842 CipherBase* cipher;
3843 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3844
3845 // Only callable after Final and if encrypting.
3846 if (cipher->ctx_ ||
3847 cipher->kind_ != kCipher ||
3848 cipher->auth_tag_len_ == kNoAuthTagLength) {
3849 return args.GetReturnValue().SetUndefined();
3850 }
3851
3852 Local<Object> buf =
3853 Buffer::Copy(env, cipher->auth_tag_, cipher->auth_tag_len_)
3854 .ToLocalChecked();
3855 args.GetReturnValue().Set(buf);
3856 }
3857
3858
SetAuthTag(const FunctionCallbackInfo<Value> & args)3859 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
3860 CipherBase* cipher;
3861 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3862
3863 if (!cipher->ctx_ ||
3864 !cipher->IsAuthenticatedMode() ||
3865 cipher->kind_ != kDecipher ||
3866 cipher->auth_tag_state_ != kAuthTagUnknown) {
3867 return args.GetReturnValue().Set(false);
3868 }
3869
3870 unsigned int tag_len = Buffer::Length(args[0]);
3871 const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get());
3872 bool is_valid;
3873 if (mode == EVP_CIPH_GCM_MODE) {
3874 // Restrict GCM tag lengths according to NIST 800-38d, page 9.
3875 is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength ||
3876 cipher->auth_tag_len_ == tag_len) &&
3877 IsValidGCMTagLength(tag_len);
3878 } else {
3879 // At this point, the tag length is already known and must match the
3880 // length of the given authentication tag.
3881 CHECK(IsSupportedAuthenticatedMode(cipher->ctx_.get()));
3882 CHECK_NE(cipher->auth_tag_len_, kNoAuthTagLength);
3883 is_valid = cipher->auth_tag_len_ == tag_len;
3884 }
3885
3886 if (!is_valid) {
3887 char msg[50];
3888 snprintf(msg, sizeof(msg),
3889 "Invalid authentication tag length: %u", tag_len);
3890 return cipher->env()->ThrowError(msg);
3891 }
3892
3893 cipher->auth_tag_len_ = tag_len;
3894 cipher->auth_tag_state_ = kAuthTagKnown;
3895 CHECK_LE(cipher->auth_tag_len_, sizeof(cipher->auth_tag_));
3896
3897 memset(cipher->auth_tag_, 0, sizeof(cipher->auth_tag_));
3898 args[0].As<ArrayBufferView>()->CopyContents(
3899 cipher->auth_tag_, cipher->auth_tag_len_);
3900
3901 args.GetReturnValue().Set(true);
3902 }
3903
3904
MaybePassAuthTagToOpenSSL()3905 bool CipherBase::MaybePassAuthTagToOpenSSL() {
3906 if (auth_tag_state_ == kAuthTagKnown) {
3907 if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
3908 EVP_CTRL_AEAD_SET_TAG,
3909 auth_tag_len_,
3910 reinterpret_cast<unsigned char*>(auth_tag_))) {
3911 return false;
3912 }
3913 auth_tag_state_ = kAuthTagPassedToOpenSSL;
3914 }
3915 return true;
3916 }
3917
3918
SetAAD(const char * data,unsigned int len,int plaintext_len)3919 bool CipherBase::SetAAD(const char* data, unsigned int len, int plaintext_len) {
3920 if (!ctx_ || !IsAuthenticatedMode())
3921 return false;
3922 MarkPopErrorOnReturn mark_pop_error_on_return;
3923
3924 int outlen;
3925 const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
3926
3927 // When in CCM mode, we need to set the authentication tag and the plaintext
3928 // length in advance.
3929 if (mode == EVP_CIPH_CCM_MODE) {
3930 if (plaintext_len < 0) {
3931 env()->ThrowError("plaintextLength required for CCM mode with AAD");
3932 return false;
3933 }
3934
3935 if (!CheckCCMMessageLength(plaintext_len))
3936 return false;
3937
3938 if (kind_ == kDecipher) {
3939 if (!MaybePassAuthTagToOpenSSL())
3940 return false;
3941 }
3942
3943 // Specify the plaintext length.
3944 if (!EVP_CipherUpdate(ctx_.get(), nullptr, &outlen, nullptr, plaintext_len))
3945 return false;
3946 }
3947
3948 return 1 == EVP_CipherUpdate(ctx_.get(),
3949 nullptr,
3950 &outlen,
3951 reinterpret_cast<const unsigned char*>(data),
3952 len);
3953 }
3954
3955
SetAAD(const FunctionCallbackInfo<Value> & args)3956 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
3957 CipherBase* cipher;
3958 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3959
3960 CHECK_EQ(args.Length(), 2);
3961 CHECK(args[1]->IsInt32());
3962 int plaintext_len = args[1].As<Int32>()->Value();
3963 ArrayBufferViewContents<char> buf(args[0]);
3964
3965 bool b = cipher->SetAAD(buf.data(), buf.length(), plaintext_len);
3966 args.GetReturnValue().Set(b); // Possibly report invalid state failure
3967 }
3968
Update(const char * data,int len,AllocatedBuffer * out)3969 CipherBase::UpdateResult CipherBase::Update(const char* data,
3970 int len,
3971 AllocatedBuffer* out) {
3972 if (!ctx_)
3973 return kErrorState;
3974 MarkPopErrorOnReturn mark_pop_error_on_return;
3975
3976 const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
3977
3978 if (mode == EVP_CIPH_CCM_MODE) {
3979 if (!CheckCCMMessageLength(len))
3980 return kErrorMessageSize;
3981 }
3982
3983 // Pass the authentication tag to OpenSSL if possible. This will only happen
3984 // once, usually on the first update.
3985 if (kind_ == kDecipher && IsAuthenticatedMode()) {
3986 CHECK(MaybePassAuthTagToOpenSSL());
3987 }
3988
3989 int buf_len = len + EVP_CIPHER_CTX_block_size(ctx_.get());
3990 // For key wrapping algorithms, get output size by calling
3991 // EVP_CipherUpdate() with null output.
3992 if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE &&
3993 EVP_CipherUpdate(ctx_.get(),
3994 nullptr,
3995 &buf_len,
3996 reinterpret_cast<const unsigned char*>(data),
3997 len) != 1) {
3998 return kErrorState;
3999 }
4000
4001 *out = env()->AllocateManaged(buf_len);
4002 int r = EVP_CipherUpdate(ctx_.get(),
4003 reinterpret_cast<unsigned char*>(out->data()),
4004 &buf_len,
4005 reinterpret_cast<const unsigned char*>(data),
4006 len);
4007
4008 CHECK_LE(static_cast<size_t>(buf_len), out->size());
4009 out->Resize(buf_len);
4010
4011 // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
4012 // invalid. In that case, remember the error and throw in final().
4013 if (!r && kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
4014 pending_auth_failed_ = true;
4015 return kSuccess;
4016 }
4017 return r == 1 ? kSuccess : kErrorState;
4018 }
4019
4020
Update(const FunctionCallbackInfo<Value> & args)4021 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
4022 Environment* env = Environment::GetCurrent(args);
4023
4024 CipherBase* cipher;
4025 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
4026
4027 AllocatedBuffer out;
4028 UpdateResult r;
4029
4030 // Only copy the data if we have to, because it's a string
4031 if (args[0]->IsString()) {
4032 StringBytes::InlineDecoder decoder;
4033 if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8)
4034 .FromMaybe(false))
4035 return;
4036 r = cipher->Update(decoder.out(), decoder.size(), &out);
4037 } else {
4038 ArrayBufferViewContents<char> buf(args[0]);
4039 r = cipher->Update(buf.data(), buf.length(), &out);
4040 }
4041
4042 if (r != kSuccess) {
4043 if (r == kErrorState) {
4044 ThrowCryptoError(env, ERR_get_error(),
4045 "Trying to add data in unsupported state");
4046 }
4047 return;
4048 }
4049
4050 CHECK(out.data() != nullptr || out.size() == 0);
4051
4052 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
4053 }
4054
4055
SetAutoPadding(bool auto_padding)4056 bool CipherBase::SetAutoPadding(bool auto_padding) {
4057 if (!ctx_)
4058 return false;
4059 MarkPopErrorOnReturn mark_pop_error_on_return;
4060 return EVP_CIPHER_CTX_set_padding(ctx_.get(), auto_padding);
4061 }
4062
4063
SetAutoPadding(const FunctionCallbackInfo<Value> & args)4064 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
4065 CipherBase* cipher;
4066 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
4067
4068 bool b = cipher->SetAutoPadding(args.Length() < 1 || args[0]->IsTrue());
4069 args.GetReturnValue().Set(b); // Possibly report invalid state failure
4070 }
4071
Final(AllocatedBuffer * out)4072 bool CipherBase::Final(AllocatedBuffer* out) {
4073 if (!ctx_)
4074 return false;
4075
4076 const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
4077
4078 *out = env()->AllocateManaged(
4079 static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
4080
4081 if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get())) {
4082 MaybePassAuthTagToOpenSSL();
4083 }
4084
4085 // In CCM mode, final() only checks whether authentication failed in update().
4086 // EVP_CipherFinal_ex must not be called and will fail.
4087 bool ok;
4088 if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
4089 ok = !pending_auth_failed_;
4090 *out = AllocatedBuffer(env()); // Empty buffer.
4091 } else {
4092 int out_len = out->size();
4093 ok = EVP_CipherFinal_ex(ctx_.get(),
4094 reinterpret_cast<unsigned char*>(out->data()),
4095 &out_len) == 1;
4096
4097 if (out_len >= 0)
4098 out->Resize(out_len);
4099 else
4100 *out = AllocatedBuffer(); // *out will not be used.
4101
4102 if (ok && kind_ == kCipher && IsAuthenticatedMode()) {
4103 // In GCM mode, the authentication tag length can be specified in advance,
4104 // but defaults to 16 bytes when encrypting. In CCM and OCB mode, it must
4105 // always be given by the user.
4106 if (auth_tag_len_ == kNoAuthTagLength) {
4107 CHECK(mode == EVP_CIPH_GCM_MODE);
4108 auth_tag_len_ = sizeof(auth_tag_);
4109 }
4110 CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
4111 auth_tag_len_,
4112 reinterpret_cast<unsigned char*>(auth_tag_)));
4113 }
4114 }
4115
4116 ctx_.reset();
4117
4118 return ok;
4119 }
4120
4121
Final(const FunctionCallbackInfo<Value> & args)4122 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
4123 Environment* env = Environment::GetCurrent(args);
4124
4125 CipherBase* cipher;
4126 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
4127 if (cipher->ctx_ == nullptr) return env->ThrowError("Unsupported state");
4128
4129 AllocatedBuffer out;
4130
4131 // Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
4132 const bool is_auth_mode = cipher->IsAuthenticatedMode();
4133 bool r = cipher->Final(&out);
4134
4135 if (!r) {
4136 const char* msg = is_auth_mode
4137 ? "Unsupported state or unable to authenticate data"
4138 : "Unsupported state";
4139
4140 return ThrowCryptoError(env, ERR_get_error(), msg);
4141 }
4142
4143 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
4144 }
4145
Hmac(Environment * env,Local<Object> wrap)4146 Hmac::Hmac(Environment* env, Local<Object> wrap)
4147 : BaseObject(env, wrap),
4148 ctx_(nullptr) {
4149 MakeWeak();
4150 }
4151
Initialize(Environment * env,Local<Object> target)4152 void Hmac::Initialize(Environment* env, Local<Object> target) {
4153 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4154
4155 t->InstanceTemplate()->SetInternalFieldCount(
4156 Hmac::kInternalFieldCount);
4157 t->Inherit(BaseObject::GetConstructorTemplate(env));
4158
4159 env->SetProtoMethod(t, "init", HmacInit);
4160 env->SetProtoMethod(t, "update", HmacUpdate);
4161 env->SetProtoMethod(t, "digest", HmacDigest);
4162
4163 target->Set(env->context(),
4164 FIXED_ONE_BYTE_STRING(env->isolate(), "Hmac"),
4165 t->GetFunction(env->context()).ToLocalChecked()).Check();
4166 }
4167
4168
New(const FunctionCallbackInfo<Value> & args)4169 void Hmac::New(const FunctionCallbackInfo<Value>& args) {
4170 Environment* env = Environment::GetCurrent(args);
4171 new Hmac(env, args.This());
4172 }
4173
4174
HmacInit(const char * hash_type,const char * key,int key_len)4175 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
4176 HandleScope scope(env()->isolate());
4177
4178 const EVP_MD* md = EVP_get_digestbyname(hash_type);
4179 if (md == nullptr) {
4180 return env()->ThrowError("Unknown message digest");
4181 }
4182 if (key_len == 0) {
4183 key = "";
4184 }
4185 ctx_.reset(HMAC_CTX_new());
4186 if (!ctx_ || !HMAC_Init_ex(ctx_.get(), key, key_len, md, nullptr)) {
4187 ctx_.reset();
4188 return ThrowCryptoError(env(), ERR_get_error());
4189 }
4190 }
4191
4192
HmacInit(const FunctionCallbackInfo<Value> & args)4193 void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
4194 Hmac* hmac;
4195 ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder());
4196 Environment* env = hmac->env();
4197
4198 const node::Utf8Value hash_type(env->isolate(), args[0]);
4199 ByteSource key = GetSecretKeyBytes(env, args[1]);
4200 hmac->HmacInit(*hash_type, key.get(), key.size());
4201 }
4202
4203
HmacUpdate(const char * data,int len)4204 bool Hmac::HmacUpdate(const char* data, int len) {
4205 if (!ctx_)
4206 return false;
4207 int r = HMAC_Update(ctx_.get(),
4208 reinterpret_cast<const unsigned char*>(data),
4209 len);
4210 return r == 1;
4211 }
4212
4213
HmacUpdate(const FunctionCallbackInfo<Value> & args)4214 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
4215 Environment* env = Environment::GetCurrent(args);
4216
4217 Hmac* hmac;
4218 ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder());
4219
4220 // Only copy the data if we have to, because it's a string
4221 bool r = false;
4222 if (args[0]->IsString()) {
4223 StringBytes::InlineDecoder decoder;
4224 if (decoder.Decode(env, args[0].As<String>(), args[1], UTF8)
4225 .FromMaybe(false)) {
4226 r = hmac->HmacUpdate(decoder.out(), decoder.size());
4227 }
4228 } else {
4229 ArrayBufferViewContents<char> buf(args[0]);
4230 r = hmac->HmacUpdate(buf.data(), buf.length());
4231 }
4232
4233 args.GetReturnValue().Set(r);
4234 }
4235
4236
HmacDigest(const FunctionCallbackInfo<Value> & args)4237 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
4238 Environment* env = Environment::GetCurrent(args);
4239
4240 Hmac* hmac;
4241 ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder());
4242
4243 enum encoding encoding = BUFFER;
4244 if (args.Length() >= 1) {
4245 encoding = ParseEncoding(env->isolate(), args[0], BUFFER);
4246 }
4247
4248 unsigned char md_value[EVP_MAX_MD_SIZE];
4249 unsigned int md_len = 0;
4250
4251 if (hmac->ctx_) {
4252 HMAC_Final(hmac->ctx_.get(), md_value, &md_len);
4253 hmac->ctx_.reset();
4254 }
4255
4256 Local<Value> error;
4257 MaybeLocal<Value> rc =
4258 StringBytes::Encode(env->isolate(),
4259 reinterpret_cast<const char*>(md_value),
4260 md_len,
4261 encoding,
4262 &error);
4263 if (rc.IsEmpty()) {
4264 CHECK(!error.IsEmpty());
4265 env->isolate()->ThrowException(error);
4266 return;
4267 }
4268 args.GetReturnValue().Set(rc.ToLocalChecked());
4269 }
4270
Hash(Environment * env,Local<Object> wrap)4271 Hash::Hash(Environment* env, Local<Object> wrap)
4272 : BaseObject(env, wrap),
4273 mdctx_(nullptr),
4274 has_md_(false),
4275 md_value_(nullptr) {
4276 MakeWeak();
4277 }
4278
Initialize(Environment * env,Local<Object> target)4279 void Hash::Initialize(Environment* env, Local<Object> target) {
4280 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4281
4282 t->InstanceTemplate()->SetInternalFieldCount(
4283 Hash::kInternalFieldCount);
4284 t->Inherit(BaseObject::GetConstructorTemplate(env));
4285
4286 env->SetProtoMethod(t, "update", HashUpdate);
4287 env->SetProtoMethod(t, "digest", HashDigest);
4288
4289 target->Set(env->context(),
4290 FIXED_ONE_BYTE_STRING(env->isolate(), "Hash"),
4291 t->GetFunction(env->context()).ToLocalChecked()).Check();
4292 }
4293
~Hash()4294 Hash::~Hash() {
4295 if (md_value_ != nullptr)
4296 OPENSSL_clear_free(md_value_, md_len_);
4297 }
4298
New(const FunctionCallbackInfo<Value> & args)4299 void Hash::New(const FunctionCallbackInfo<Value>& args) {
4300 Environment* env = Environment::GetCurrent(args);
4301
4302 const Hash* orig = nullptr;
4303 const EVP_MD* md = nullptr;
4304
4305 if (args[0]->IsObject()) {
4306 ASSIGN_OR_RETURN_UNWRAP(&orig, args[0].As<Object>());
4307 md = EVP_MD_CTX_md(orig->mdctx_.get());
4308 } else {
4309 const node::Utf8Value hash_type(env->isolate(), args[0]);
4310 md = EVP_get_digestbyname(*hash_type);
4311 }
4312
4313 Maybe<unsigned int> xof_md_len = Nothing<unsigned int>();
4314 if (!args[1]->IsUndefined()) {
4315 CHECK(args[1]->IsUint32());
4316 xof_md_len = Just<unsigned int>(args[1].As<Uint32>()->Value());
4317 }
4318
4319 Hash* hash = new Hash(env, args.This());
4320 if (md == nullptr || !hash->HashInit(md, xof_md_len)) {
4321 return ThrowCryptoError(env, ERR_get_error(),
4322 "Digest method not supported");
4323 }
4324
4325 if (orig != nullptr &&
4326 0 >= EVP_MD_CTX_copy(hash->mdctx_.get(), orig->mdctx_.get())) {
4327 return ThrowCryptoError(env, ERR_get_error(), "Digest copy error");
4328 }
4329 }
4330
4331
HashInit(const EVP_MD * md,Maybe<unsigned int> xof_md_len)4332 bool Hash::HashInit(const EVP_MD* md, Maybe<unsigned int> xof_md_len) {
4333 mdctx_.reset(EVP_MD_CTX_new());
4334 if (!mdctx_ || EVP_DigestInit_ex(mdctx_.get(), md, nullptr) <= 0) {
4335 mdctx_.reset();
4336 return false;
4337 }
4338
4339 md_len_ = EVP_MD_size(md);
4340 if (xof_md_len.IsJust() && xof_md_len.FromJust() != md_len_) {
4341 // This is a little hack to cause createHash to fail when an incorrect
4342 // hashSize option was passed for a non-XOF hash function.
4343 if ((EVP_MD_flags(md) & EVP_MD_FLAG_XOF) == 0) {
4344 EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
4345 return false;
4346 }
4347 md_len_ = xof_md_len.FromJust();
4348 }
4349
4350 return true;
4351 }
4352
4353
HashUpdate(const char * data,int len)4354 bool Hash::HashUpdate(const char* data, int len) {
4355 if (!mdctx_)
4356 return false;
4357 EVP_DigestUpdate(mdctx_.get(), data, len);
4358 return true;
4359 }
4360
4361
HashUpdate(const FunctionCallbackInfo<Value> & args)4362 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
4363 Environment* env = Environment::GetCurrent(args);
4364
4365 Hash* hash;
4366 ASSIGN_OR_RETURN_UNWRAP(&hash, args.Holder());
4367
4368 // Only copy the data if we have to, because it's a string
4369 bool r = true;
4370 if (args[0]->IsString()) {
4371 StringBytes::InlineDecoder decoder;
4372 if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8)
4373 .FromMaybe(false)) {
4374 args.GetReturnValue().Set(false);
4375 return;
4376 }
4377 r = hash->HashUpdate(decoder.out(), decoder.size());
4378 } else if (args[0]->IsArrayBufferView()) {
4379 ArrayBufferViewContents<char> buf(args[0].As<ArrayBufferView>());
4380 r = hash->HashUpdate(buf.data(), buf.length());
4381 }
4382
4383 args.GetReturnValue().Set(r);
4384 }
4385
4386
HashDigest(const FunctionCallbackInfo<Value> & args)4387 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
4388 Environment* env = Environment::GetCurrent(args);
4389
4390 Hash* hash;
4391 ASSIGN_OR_RETURN_UNWRAP(&hash, args.Holder());
4392
4393 enum encoding encoding = BUFFER;
4394 if (args.Length() >= 1) {
4395 encoding = ParseEncoding(env->isolate(), args[0], BUFFER);
4396 }
4397
4398 // TODO(tniessen): SHA3_squeeze does not work for zero-length outputs on all
4399 // platforms and will cause a segmentation fault if called. This workaround
4400 // causes hash.digest() to correctly return an empty buffer / string.
4401 // See https://github.com/openssl/openssl/issues/9431.
4402 if (!hash->has_md_ && hash->md_len_ == 0) {
4403 hash->has_md_ = true;
4404 }
4405
4406 if (!hash->has_md_) {
4407 // Some hash algorithms such as SHA3 do not support calling
4408 // EVP_DigestFinal_ex more than once, however, Hash._flush
4409 // and Hash.digest can both be used to retrieve the digest,
4410 // so we need to cache it.
4411 // See https://github.com/nodejs/node/issues/28245.
4412
4413 hash->md_value_ = MallocOpenSSL<unsigned char>(hash->md_len_);
4414
4415 size_t default_len = EVP_MD_CTX_size(hash->mdctx_.get());
4416 int ret;
4417 if (hash->md_len_ == default_len) {
4418 ret = EVP_DigestFinal_ex(hash->mdctx_.get(), hash->md_value_,
4419 &hash->md_len_);
4420 } else {
4421 ret = EVP_DigestFinalXOF(hash->mdctx_.get(), hash->md_value_,
4422 hash->md_len_);
4423 }
4424
4425 if (ret != 1) {
4426 OPENSSL_free(hash->md_value_);
4427 hash->md_value_ = nullptr;
4428 return ThrowCryptoError(env, ERR_get_error());
4429 }
4430
4431 hash->has_md_ = true;
4432 }
4433
4434 Local<Value> error;
4435 MaybeLocal<Value> rc =
4436 StringBytes::Encode(env->isolate(),
4437 reinterpret_cast<const char*>(hash->md_value_),
4438 hash->md_len_,
4439 encoding,
4440 &error);
4441 if (rc.IsEmpty()) {
4442 CHECK(!error.IsEmpty());
4443 env->isolate()->ThrowException(error);
4444 return;
4445 }
4446 args.GetReturnValue().Set(rc.ToLocalChecked());
4447 }
4448
4449
Init(const char * sign_type)4450 SignBase::Error SignBase::Init(const char* sign_type) {
4451 CHECK_NULL(mdctx_);
4452 // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
4453 // exposed through the public API.
4454 if (strcmp(sign_type, "dss1") == 0 ||
4455 strcmp(sign_type, "DSS1") == 0) {
4456 sign_type = "SHA1";
4457 }
4458 const EVP_MD* md = EVP_get_digestbyname(sign_type);
4459 if (md == nullptr)
4460 return kSignUnknownDigest;
4461
4462 mdctx_.reset(EVP_MD_CTX_new());
4463 if (!mdctx_ || !EVP_DigestInit_ex(mdctx_.get(), md, nullptr)) {
4464 mdctx_.reset();
4465 return kSignInit;
4466 }
4467
4468 return kSignOk;
4469 }
4470
4471
Update(const char * data,int len)4472 SignBase::Error SignBase::Update(const char* data, int len) {
4473 if (mdctx_ == nullptr)
4474 return kSignNotInitialised;
4475 if (!EVP_DigestUpdate(mdctx_.get(), data, len))
4476 return kSignUpdate;
4477 return kSignOk;
4478 }
4479
4480
CheckThrow(Environment * env,SignBase::Error error)4481 void CheckThrow(Environment* env, SignBase::Error error) {
4482 HandleScope scope(env->isolate());
4483
4484 switch (error) {
4485 case SignBase::Error::kSignUnknownDigest:
4486 return env->ThrowError("Unknown message digest");
4487
4488 case SignBase::Error::kSignNotInitialised:
4489 return env->ThrowError("Not initialised");
4490
4491 case SignBase::Error::kSignMalformedSignature:
4492 return env->ThrowError("Malformed signature");
4493
4494 case SignBase::Error::kSignInit:
4495 case SignBase::Error::kSignUpdate:
4496 case SignBase::Error::kSignPrivateKey:
4497 case SignBase::Error::kSignPublicKey:
4498 {
4499 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
4500 if (err)
4501 return ThrowCryptoError(env, err);
4502 switch (error) {
4503 case SignBase::Error::kSignInit:
4504 return env->ThrowError("EVP_SignInit_ex failed");
4505 case SignBase::Error::kSignUpdate:
4506 return env->ThrowError("EVP_SignUpdate failed");
4507 case SignBase::Error::kSignPrivateKey:
4508 return env->ThrowError("PEM_read_bio_PrivateKey failed");
4509 case SignBase::Error::kSignPublicKey:
4510 return env->ThrowError("PEM_read_bio_PUBKEY failed");
4511 default:
4512 ABORT();
4513 }
4514 }
4515
4516 case SignBase::Error::kSignOk:
4517 return;
4518 }
4519 }
4520
SignBase(Environment * env,Local<Object> wrap)4521 SignBase::SignBase(Environment* env, Local<Object> wrap)
4522 : BaseObject(env, wrap) {
4523 }
4524
CheckThrow(SignBase::Error error)4525 void SignBase::CheckThrow(SignBase::Error error) {
4526 node::crypto::CheckThrow(env(), error);
4527 }
4528
ApplyRSAOptions(const ManagedEVPPKey & pkey,EVP_PKEY_CTX * pkctx,int padding,const Maybe<int> & salt_len)4529 static bool ApplyRSAOptions(const ManagedEVPPKey& pkey,
4530 EVP_PKEY_CTX* pkctx,
4531 int padding,
4532 const Maybe<int>& salt_len) {
4533 if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA ||
4534 EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2 ||
4535 EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA_PSS) {
4536 if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0)
4537 return false;
4538 if (padding == RSA_PKCS1_PSS_PADDING && salt_len.IsJust()) {
4539 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, salt_len.FromJust()) <= 0)
4540 return false;
4541 }
4542 }
4543
4544 return true;
4545 }
4546
4547
Sign(Environment * env,Local<Object> wrap)4548 Sign::Sign(Environment* env, Local<Object> wrap) : SignBase(env, wrap) {
4549 MakeWeak();
4550 }
4551
Initialize(Environment * env,Local<Object> target)4552 void Sign::Initialize(Environment* env, Local<Object> target) {
4553 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4554
4555 t->InstanceTemplate()->SetInternalFieldCount(
4556 SignBase::kInternalFieldCount);
4557 t->Inherit(BaseObject::GetConstructorTemplate(env));
4558
4559 env->SetProtoMethod(t, "init", SignInit);
4560 env->SetProtoMethod(t, "update", SignUpdate);
4561 env->SetProtoMethod(t, "sign", SignFinal);
4562
4563 target->Set(env->context(),
4564 FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"),
4565 t->GetFunction(env->context()).ToLocalChecked()).Check();
4566 }
4567
4568
New(const FunctionCallbackInfo<Value> & args)4569 void Sign::New(const FunctionCallbackInfo<Value>& args) {
4570 Environment* env = Environment::GetCurrent(args);
4571 new Sign(env, args.This());
4572 }
4573
4574
SignInit(const FunctionCallbackInfo<Value> & args)4575 void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
4576 Sign* sign;
4577 ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
4578
4579 const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
4580 sign->CheckThrow(sign->Init(*sign_type));
4581 }
4582
4583
SignUpdate(const FunctionCallbackInfo<Value> & args)4584 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
4585 Sign* sign;
4586 ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
4587
4588 Error err;
4589 ArrayBufferViewContents<char> buf(args[0]);
4590 err = sign->Update(buf.data(), buf.length());
4591
4592 sign->CheckThrow(err);
4593 }
4594
GetDefaultSignPadding(const ManagedEVPPKey & key)4595 static int GetDefaultSignPadding(const ManagedEVPPKey& key) {
4596 return EVP_PKEY_id(key.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING :
4597 RSA_PKCS1_PADDING;
4598 }
4599
4600 static const unsigned int kNoDsaSignature = static_cast<unsigned int>(-1);
4601
4602 // Returns the maximum size of each of the integers (r, s) of the DSA signature.
GetBytesOfRS(const ManagedEVPPKey & pkey)4603 static unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) {
4604 int bits, base_id = EVP_PKEY_base_id(pkey.get());
4605
4606 if (base_id == EVP_PKEY_DSA) {
4607 DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get());
4608 // Both r and s are computed mod q, so their width is limited by that of q.
4609 bits = BN_num_bits(DSA_get0_q(dsa_key));
4610 } else if (base_id == EVP_PKEY_EC) {
4611 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get());
4612 const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
4613 bits = EC_GROUP_order_bits(ec_group);
4614 } else {
4615 return kNoDsaSignature;
4616 }
4617
4618 return (bits + 7) / 8;
4619 }
4620
ConvertSignatureToP1363(Environment * env,const ManagedEVPPKey & pkey,AllocatedBuffer && signature)4621 static AllocatedBuffer ConvertSignatureToP1363(Environment* env,
4622 const ManagedEVPPKey& pkey,
4623 AllocatedBuffer&& signature) {
4624 unsigned int n = GetBytesOfRS(pkey);
4625 if (n == kNoDsaSignature)
4626 return std::move(signature);
4627
4628 const unsigned char* sig_data =
4629 reinterpret_cast<unsigned char*>(signature.data());
4630
4631 ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, signature.size()));
4632 if (!asn1_sig)
4633 return AllocatedBuffer();
4634
4635 AllocatedBuffer buf = env->AllocateManaged(2 * n);
4636 unsigned char* data = reinterpret_cast<unsigned char*>(buf.data());
4637
4638 const BIGNUM* r = ECDSA_SIG_get0_r(asn1_sig.get());
4639 const BIGNUM* s = ECDSA_SIG_get0_s(asn1_sig.get());
4640 CHECK_EQ(n, static_cast<unsigned int>(BN_bn2binpad(r, data, n)));
4641 CHECK_EQ(n, static_cast<unsigned int>(BN_bn2binpad(s, data + n, n)));
4642
4643 return buf;
4644 }
4645
ConvertSignatureToDER(const ManagedEVPPKey & pkey,const ArrayBufferViewContents<char> & signature)4646 static ByteSource ConvertSignatureToDER(
4647 const ManagedEVPPKey& pkey,
4648 const ArrayBufferViewContents<char>& signature) {
4649 unsigned int n = GetBytesOfRS(pkey);
4650 if (n == kNoDsaSignature)
4651 return ByteSource::Foreign(signature.data(), signature.length());
4652
4653 const unsigned char* sig_data =
4654 reinterpret_cast<const unsigned char*>(signature.data());
4655
4656 if (signature.length() != 2 * n)
4657 return ByteSource();
4658
4659 ECDSASigPointer asn1_sig(ECDSA_SIG_new());
4660 CHECK(asn1_sig);
4661 BIGNUM* r = BN_new();
4662 CHECK_NOT_NULL(r);
4663 BIGNUM* s = BN_new();
4664 CHECK_NOT_NULL(s);
4665 CHECK_EQ(r, BN_bin2bn(sig_data, n, r));
4666 CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s));
4667 CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r, s));
4668
4669 unsigned char* data = nullptr;
4670 int len = i2d_ECDSA_SIG(asn1_sig.get(), &data);
4671
4672 if (len <= 0)
4673 return ByteSource();
4674
4675 CHECK_NOT_NULL(data);
4676
4677 return ByteSource::Allocated(reinterpret_cast<char*>(data), len);
4678 }
4679
Node_SignFinal(Environment * env,EVPMDPointer && mdctx,const ManagedEVPPKey & pkey,int padding,Maybe<int> pss_salt_len)4680 static AllocatedBuffer Node_SignFinal(Environment* env,
4681 EVPMDPointer&& mdctx,
4682 const ManagedEVPPKey& pkey,
4683 int padding,
4684 Maybe<int> pss_salt_len) {
4685 unsigned char m[EVP_MAX_MD_SIZE];
4686 unsigned int m_len;
4687
4688 if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
4689 return AllocatedBuffer();
4690
4691 int signed_sig_len = EVP_PKEY_size(pkey.get());
4692 CHECK_GE(signed_sig_len, 0);
4693 size_t sig_len = static_cast<size_t>(signed_sig_len);
4694 AllocatedBuffer sig = env->AllocateManaged(sig_len);
4695
4696 EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
4697 if (pkctx &&
4698 EVP_PKEY_sign_init(pkctx.get()) > 0 &&
4699 ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) &&
4700 EVP_PKEY_CTX_set_signature_md(pkctx.get(),
4701 EVP_MD_CTX_md(mdctx.get())) > 0 &&
4702 EVP_PKEY_sign(pkctx.get(),
4703 reinterpret_cast<unsigned char*>(sig.data()),
4704 &sig_len,
4705 m,
4706 m_len) > 0) {
4707 sig.Resize(sig_len);
4708 return sig;
4709 }
4710
4711 return AllocatedBuffer();
4712 }
4713
ValidateDSAParameters(EVP_PKEY * key)4714 static inline bool ValidateDSAParameters(EVP_PKEY* key) {
4715 #ifdef NODE_FIPS_MODE
4716 /* Validate DSA2 parameters from FIPS 186-4 */
4717 if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(key)) {
4718 DSA* dsa = EVP_PKEY_get0_DSA(key);
4719 const BIGNUM* p;
4720 DSA_get0_pqg(dsa, &p, nullptr, nullptr);
4721 size_t L = BN_num_bits(p);
4722 const BIGNUM* q;
4723 DSA_get0_pqg(dsa, nullptr, &q, nullptr);
4724 size_t N = BN_num_bits(q);
4725
4726 return (L == 1024 && N == 160) ||
4727 (L == 2048 && N == 224) ||
4728 (L == 2048 && N == 256) ||
4729 (L == 3072 && N == 256);
4730 }
4731 #endif // NODE_FIPS_MODE
4732
4733 return true;
4734 }
4735
SignFinal(const ManagedEVPPKey & pkey,int padding,const Maybe<int> & salt_len,DSASigEnc dsa_sig_enc)4736 Sign::SignResult Sign::SignFinal(
4737 const ManagedEVPPKey& pkey,
4738 int padding,
4739 const Maybe<int>& salt_len,
4740 DSASigEnc dsa_sig_enc) {
4741 if (!mdctx_)
4742 return SignResult(kSignNotInitialised);
4743
4744 EVPMDPointer mdctx = std::move(mdctx_);
4745
4746 if (!ValidateDSAParameters(pkey.get()))
4747 return SignResult(kSignPrivateKey);
4748
4749 AllocatedBuffer buffer =
4750 Node_SignFinal(env(), std::move(mdctx), pkey, padding, salt_len);
4751 Error error = buffer.data() == nullptr ? kSignPrivateKey : kSignOk;
4752 if (error == kSignOk && dsa_sig_enc == kSigEncP1363) {
4753 buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer));
4754 CHECK_NOT_NULL(buffer.data());
4755 }
4756 return SignResult(error, std::move(buffer));
4757 }
4758
4759
SignFinal(const FunctionCallbackInfo<Value> & args)4760 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
4761 Sign* sign;
4762 ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
4763
4764 ClearErrorOnReturn clear_error_on_return;
4765
4766 unsigned int offset = 0;
4767 ManagedEVPPKey key = GetPrivateKeyFromJs(args, &offset, true);
4768 if (!key)
4769 return;
4770
4771 int padding = GetDefaultSignPadding(key);
4772 if (!args[offset]->IsUndefined()) {
4773 CHECK(args[offset]->IsInt32());
4774 padding = args[offset].As<Int32>()->Value();
4775 }
4776
4777 Maybe<int> salt_len = Nothing<int>();
4778 if (!args[offset + 1]->IsUndefined()) {
4779 CHECK(args[offset + 1]->IsInt32());
4780 salt_len = Just<int>(args[offset + 1].As<Int32>()->Value());
4781 }
4782
4783 CHECK(args[offset + 2]->IsInt32());
4784 DSASigEnc dsa_sig_enc =
4785 static_cast<DSASigEnc>(args[offset + 2].As<Int32>()->Value());
4786
4787 SignResult ret = sign->SignFinal(
4788 key,
4789 padding,
4790 salt_len,
4791 dsa_sig_enc);
4792
4793 if (ret.error != kSignOk)
4794 return sign->CheckThrow(ret.error);
4795
4796 args.GetReturnValue().Set(ret.signature.ToBuffer().ToLocalChecked());
4797 }
4798
SignOneShot(const FunctionCallbackInfo<Value> & args)4799 void SignOneShot(const FunctionCallbackInfo<Value>& args) {
4800 ClearErrorOnReturn clear_error_on_return;
4801 Environment* env = Environment::GetCurrent(args);
4802
4803 unsigned int offset = 0;
4804 ManagedEVPPKey key = GetPrivateKeyFromJs(args, &offset, true);
4805 if (!key)
4806 return;
4807
4808 if (!ValidateDSAParameters(key.get()))
4809 return CheckThrow(env, SignBase::Error::kSignPrivateKey);
4810
4811 ArrayBufferViewContents<char> data(args[offset]);
4812
4813 const EVP_MD* md;
4814 if (args[offset + 1]->IsNullOrUndefined()) {
4815 md = nullptr;
4816 } else {
4817 const node::Utf8Value sign_type(args.GetIsolate(), args[offset + 1]);
4818 md = EVP_get_digestbyname(*sign_type);
4819 if (md == nullptr)
4820 return CheckThrow(env, SignBase::Error::kSignUnknownDigest);
4821 }
4822
4823 int rsa_padding = GetDefaultSignPadding(key);
4824 if (!args[offset + 2]->IsUndefined()) {
4825 CHECK(args[offset + 2]->IsInt32());
4826 rsa_padding = args[offset + 2].As<Int32>()->Value();
4827 }
4828
4829 Maybe<int> rsa_salt_len = Nothing<int>();
4830 if (!args[offset + 3]->IsUndefined()) {
4831 CHECK(args[offset + 3]->IsInt32());
4832 rsa_salt_len = Just<int>(args[offset + 3].As<Int32>()->Value());
4833 }
4834
4835 CHECK(args[offset + 4]->IsInt32());
4836 DSASigEnc dsa_sig_enc =
4837 static_cast<DSASigEnc>(args[offset + 4].As<Int32>()->Value());
4838
4839 EVP_PKEY_CTX* pkctx = nullptr;
4840 EVPMDPointer mdctx(EVP_MD_CTX_new());
4841 if (!mdctx ||
4842 !EVP_DigestSignInit(mdctx.get(), &pkctx, md, nullptr, key.get())) {
4843 return CheckThrow(env, SignBase::Error::kSignInit);
4844 }
4845
4846 if (!ApplyRSAOptions(key, pkctx, rsa_padding, rsa_salt_len))
4847 return CheckThrow(env, SignBase::Error::kSignPrivateKey);
4848
4849 const unsigned char* input =
4850 reinterpret_cast<const unsigned char*>(data.data());
4851 size_t sig_len;
4852 if (!EVP_DigestSign(mdctx.get(), nullptr, &sig_len, input, data.length()))
4853 return CheckThrow(env, SignBase::Error::kSignPrivateKey);
4854
4855 AllocatedBuffer signature = env->AllocateManaged(sig_len);
4856 if (!EVP_DigestSign(mdctx.get(),
4857 reinterpret_cast<unsigned char*>(signature.data()),
4858 &sig_len,
4859 input,
4860 data.length())) {
4861 return CheckThrow(env, SignBase::Error::kSignPrivateKey);
4862 }
4863
4864 signature.Resize(sig_len);
4865
4866 if (dsa_sig_enc == kSigEncP1363) {
4867 signature = ConvertSignatureToP1363(env, key, std::move(signature));
4868 }
4869
4870 args.GetReturnValue().Set(signature.ToBuffer().ToLocalChecked());
4871 }
4872
Verify(Environment * env,Local<Object> wrap)4873 Verify::Verify(Environment* env, Local<Object> wrap)
4874 : SignBase(env, wrap) {
4875 MakeWeak();
4876 }
4877
Initialize(Environment * env,Local<Object> target)4878 void Verify::Initialize(Environment* env, Local<Object> target) {
4879 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4880
4881 t->InstanceTemplate()->SetInternalFieldCount(
4882 SignBase::kInternalFieldCount);
4883 t->Inherit(BaseObject::GetConstructorTemplate(env));
4884
4885 env->SetProtoMethod(t, "init", VerifyInit);
4886 env->SetProtoMethod(t, "update", VerifyUpdate);
4887 env->SetProtoMethod(t, "verify", VerifyFinal);
4888
4889 target->Set(env->context(),
4890 FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
4891 t->GetFunction(env->context()).ToLocalChecked()).Check();
4892 }
4893
4894
New(const FunctionCallbackInfo<Value> & args)4895 void Verify::New(const FunctionCallbackInfo<Value>& args) {
4896 Environment* env = Environment::GetCurrent(args);
4897 new Verify(env, args.This());
4898 }
4899
4900
VerifyInit(const FunctionCallbackInfo<Value> & args)4901 void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
4902 Verify* verify;
4903 ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
4904
4905 const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
4906 verify->CheckThrow(verify->Init(*verify_type));
4907 }
4908
4909
VerifyUpdate(const FunctionCallbackInfo<Value> & args)4910 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
4911 Verify* verify;
4912 ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
4913
4914 Error err;
4915 ArrayBufferViewContents<char> buf(args[0]);
4916 err = verify->Update(buf.data(), buf.length());
4917
4918 verify->CheckThrow(err);
4919 }
4920
4921
VerifyFinal(const ManagedEVPPKey & pkey,const ByteSource & sig,int padding,const Maybe<int> & saltlen,bool * verify_result)4922 SignBase::Error Verify::VerifyFinal(const ManagedEVPPKey& pkey,
4923 const ByteSource& sig,
4924 int padding,
4925 const Maybe<int>& saltlen,
4926 bool* verify_result) {
4927 if (!mdctx_)
4928 return kSignNotInitialised;
4929
4930 unsigned char m[EVP_MAX_MD_SIZE];
4931 unsigned int m_len;
4932 *verify_result = false;
4933 EVPMDPointer mdctx = std::move(mdctx_);
4934
4935 if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
4936 return kSignPublicKey;
4937
4938 EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
4939 if (pkctx &&
4940 EVP_PKEY_verify_init(pkctx.get()) > 0 &&
4941 ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) &&
4942 EVP_PKEY_CTX_set_signature_md(pkctx.get(),
4943 EVP_MD_CTX_md(mdctx.get())) > 0) {
4944 const unsigned char* s = reinterpret_cast<const unsigned char*>(sig.get());
4945 const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len);
4946 *verify_result = r == 1;
4947 }
4948
4949 return kSignOk;
4950 }
4951
4952
VerifyFinal(const FunctionCallbackInfo<Value> & args)4953 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
4954 ClearErrorOnReturn clear_error_on_return;
4955
4956 Verify* verify;
4957 ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
4958
4959 unsigned int offset = 0;
4960 ManagedEVPPKey pkey = GetPublicOrPrivateKeyFromJs(args, &offset);
4961 if (!pkey)
4962 return;
4963
4964 ArrayBufferViewContents<char> hbuf(args[offset]);
4965
4966 int padding = GetDefaultSignPadding(pkey);
4967 if (!args[offset + 1]->IsUndefined()) {
4968 CHECK(args[offset + 1]->IsInt32());
4969 padding = args[offset + 1].As<Int32>()->Value();
4970 }
4971
4972 Maybe<int> salt_len = Nothing<int>();
4973 if (!args[offset + 2]->IsUndefined()) {
4974 CHECK(args[offset + 2]->IsInt32());
4975 salt_len = Just<int>(args[offset + 2].As<Int32>()->Value());
4976 }
4977
4978 CHECK(args[offset + 3]->IsInt32());
4979 DSASigEnc dsa_sig_enc =
4980 static_cast<DSASigEnc>(args[offset + 3].As<Int32>()->Value());
4981
4982 ByteSource signature = ByteSource::Foreign(hbuf.data(), hbuf.length());
4983 if (dsa_sig_enc == kSigEncP1363) {
4984 signature = ConvertSignatureToDER(pkey, hbuf);
4985 if (signature.get() == nullptr)
4986 return verify->CheckThrow(Error::kSignMalformedSignature);
4987 }
4988
4989 bool verify_result;
4990 Error err = verify->VerifyFinal(pkey, signature, padding,
4991 salt_len, &verify_result);
4992 if (err != kSignOk)
4993 return verify->CheckThrow(err);
4994 args.GetReturnValue().Set(verify_result);
4995 }
4996
VerifyOneShot(const FunctionCallbackInfo<Value> & args)4997 void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
4998 ClearErrorOnReturn clear_error_on_return;
4999 Environment* env = Environment::GetCurrent(args);
5000
5001 unsigned int offset = 0;
5002 ManagedEVPPKey key = GetPublicOrPrivateKeyFromJs(args, &offset);
5003 if (!key)
5004 return;
5005
5006 ArrayBufferViewContents<char> sig(args[offset]);
5007
5008 ArrayBufferViewContents<char> data(args[offset + 1]);
5009
5010 const EVP_MD* md;
5011 if (args[offset + 2]->IsNullOrUndefined()) {
5012 md = nullptr;
5013 } else {
5014 const node::Utf8Value sign_type(args.GetIsolate(), args[offset + 2]);
5015 md = EVP_get_digestbyname(*sign_type);
5016 if (md == nullptr)
5017 return CheckThrow(env, SignBase::Error::kSignUnknownDigest);
5018 }
5019
5020 int rsa_padding = GetDefaultSignPadding(key);
5021 if (!args[offset + 3]->IsUndefined()) {
5022 CHECK(args[offset + 3]->IsInt32());
5023 rsa_padding = args[offset + 3].As<Int32>()->Value();
5024 }
5025
5026 Maybe<int> rsa_salt_len = Nothing<int>();
5027 if (!args[offset + 4]->IsUndefined()) {
5028 CHECK(args[offset + 4]->IsInt32());
5029 rsa_salt_len = Just<int>(args[offset + 4].As<Int32>()->Value());
5030 }
5031
5032 CHECK(args[offset + 5]->IsInt32());
5033 DSASigEnc dsa_sig_enc =
5034 static_cast<DSASigEnc>(args[offset + 5].As<Int32>()->Value());
5035
5036 EVP_PKEY_CTX* pkctx = nullptr;
5037 EVPMDPointer mdctx(EVP_MD_CTX_new());
5038 if (!mdctx ||
5039 !EVP_DigestVerifyInit(mdctx.get(), &pkctx, md, nullptr, key.get())) {
5040 return CheckThrow(env, SignBase::Error::kSignInit);
5041 }
5042
5043 if (!ApplyRSAOptions(key, pkctx, rsa_padding, rsa_salt_len))
5044 return CheckThrow(env, SignBase::Error::kSignPublicKey);
5045
5046 ByteSource sig_bytes = ByteSource::Foreign(sig.data(), sig.length());
5047 if (dsa_sig_enc == kSigEncP1363) {
5048 sig_bytes = ConvertSignatureToDER(key, sig);
5049 if (!sig_bytes)
5050 return CheckThrow(env, SignBase::Error::kSignMalformedSignature);
5051 }
5052
5053 bool verify_result;
5054 const int r = EVP_DigestVerify(
5055 mdctx.get(),
5056 reinterpret_cast<const unsigned char*>(sig_bytes.get()),
5057 sig_bytes.size(),
5058 reinterpret_cast<const unsigned char*>(data.data()),
5059 data.length());
5060 switch (r) {
5061 case 1:
5062 verify_result = true;
5063 break;
5064 case 0:
5065 verify_result = false;
5066 break;
5067 default:
5068 return CheckThrow(env, SignBase::Error::kSignPublicKey);
5069 }
5070
5071 args.GetReturnValue().Set(verify_result);
5072 }
5073
5074 template <PublicKeyCipher::Operation operation,
5075 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
5076 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
Cipher(Environment * env,const ManagedEVPPKey & pkey,int padding,const EVP_MD * digest,const void * oaep_label,size_t oaep_label_len,const unsigned char * data,int len,AllocatedBuffer * out)5077 bool PublicKeyCipher::Cipher(Environment* env,
5078 const ManagedEVPPKey& pkey,
5079 int padding,
5080 const EVP_MD* digest,
5081 const void* oaep_label,
5082 size_t oaep_label_len,
5083 const unsigned char* data,
5084 int len,
5085 AllocatedBuffer* out) {
5086 EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
5087 if (!ctx)
5088 return false;
5089 if (EVP_PKEY_cipher_init(ctx.get()) <= 0)
5090 return false;
5091 if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), padding) <= 0)
5092 return false;
5093
5094 if (digest != nullptr) {
5095 if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), digest) <= 0)
5096 return false;
5097 }
5098
5099 if (oaep_label_len != 0) {
5100 // OpenSSL takes ownership of the label, so we need to create a copy.
5101 void* label = OPENSSL_memdup(oaep_label, oaep_label_len);
5102 CHECK_NOT_NULL(label);
5103 if (0 >= EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(),
5104 reinterpret_cast<unsigned char*>(label),
5105 oaep_label_len)) {
5106 OPENSSL_free(label);
5107 return false;
5108 }
5109 }
5110
5111 size_t out_len = 0;
5112 if (EVP_PKEY_cipher(ctx.get(), nullptr, &out_len, data, len) <= 0)
5113 return false;
5114
5115 *out = env->AllocateManaged(out_len);
5116
5117 if (EVP_PKEY_cipher(ctx.get(),
5118 reinterpret_cast<unsigned char*>(out->data()),
5119 &out_len,
5120 data,
5121 len) <= 0) {
5122 return false;
5123 }
5124
5125 out->Resize(out_len);
5126 return true;
5127 }
5128
5129
5130 template <PublicKeyCipher::Operation operation,
5131 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
5132 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
Cipher(const FunctionCallbackInfo<Value> & args)5133 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
5134 MarkPopErrorOnReturn mark_pop_error_on_return;
5135 Environment* env = Environment::GetCurrent(args);
5136
5137 unsigned int offset = 0;
5138 ManagedEVPPKey pkey = GetPublicOrPrivateKeyFromJs(args, &offset);
5139 if (!pkey)
5140 return;
5141
5142 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[offset], "Data");
5143 ArrayBufferViewContents<unsigned char> buf(args[offset]);
5144
5145 uint32_t padding;
5146 if (!args[offset + 1]->Uint32Value(env->context()).To(&padding)) return;
5147
5148 const node::Utf8Value oaep_str(env->isolate(), args[offset + 2]);
5149 const char* oaep_hash = args[offset + 2]->IsString() ? *oaep_str : nullptr;
5150 const EVP_MD* digest = nullptr;
5151 if (oaep_hash != nullptr) {
5152 digest = EVP_get_digestbyname(oaep_hash);
5153 if (digest == nullptr)
5154 return THROW_ERR_OSSL_EVP_INVALID_DIGEST(env);
5155 }
5156
5157 ArrayBufferViewContents<unsigned char> oaep_label;
5158 if (!args[offset + 3]->IsUndefined()) {
5159 CHECK(args[offset + 3]->IsArrayBufferView());
5160 oaep_label.Read(args[offset + 3].As<ArrayBufferView>());
5161 }
5162
5163 AllocatedBuffer out;
5164
5165 bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
5166 env,
5167 pkey,
5168 padding,
5169 digest,
5170 oaep_label.data(),
5171 oaep_label.length(),
5172 buf.data(),
5173 buf.length(),
5174 &out);
5175
5176 if (!r)
5177 return ThrowCryptoError(env, ERR_get_error());
5178
5179 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
5180 }
5181
DiffieHellman(Environment * env,Local<Object> wrap)5182 DiffieHellman::DiffieHellman(Environment* env, Local<Object> wrap)
5183 : BaseObject(env, wrap), verifyError_(0) {
5184 MakeWeak();
5185 }
5186
Initialize(Environment * env,Local<Object> target)5187 void DiffieHellman::Initialize(Environment* env, Local<Object> target) {
5188 auto make = [&] (Local<String> name, FunctionCallback callback) {
5189 Local<FunctionTemplate> t = env->NewFunctionTemplate(callback);
5190
5191 const PropertyAttribute attributes =
5192 static_cast<PropertyAttribute>(ReadOnly | DontDelete);
5193
5194 t->InstanceTemplate()->SetInternalFieldCount(
5195 DiffieHellman::kInternalFieldCount);
5196 t->Inherit(BaseObject::GetConstructorTemplate(env));
5197
5198 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
5199 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
5200 env->SetProtoMethodNoSideEffect(t, "getPrime", GetPrime);
5201 env->SetProtoMethodNoSideEffect(t, "getGenerator", GetGenerator);
5202 env->SetProtoMethodNoSideEffect(t, "getPublicKey", GetPublicKey);
5203 env->SetProtoMethodNoSideEffect(t, "getPrivateKey", GetPrivateKey);
5204 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
5205 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
5206
5207 Local<FunctionTemplate> verify_error_getter_templ =
5208 FunctionTemplate::New(env->isolate(),
5209 DiffieHellman::VerifyErrorGetter,
5210 env->as_callback_data(),
5211 Signature::New(env->isolate(), t),
5212 /* length */ 0,
5213 ConstructorBehavior::kThrow,
5214 SideEffectType::kHasNoSideEffect);
5215
5216 t->InstanceTemplate()->SetAccessorProperty(
5217 env->verify_error_string(),
5218 verify_error_getter_templ,
5219 Local<FunctionTemplate>(),
5220 attributes);
5221
5222 target->Set(env->context(),
5223 name,
5224 t->GetFunction(env->context()).ToLocalChecked()).Check();
5225 };
5226
5227 make(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"), New);
5228 make(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
5229 DiffieHellmanGroup);
5230 }
5231
5232
Init(int primeLength,int g)5233 bool DiffieHellman::Init(int primeLength, int g) {
5234 dh_.reset(DH_new());
5235 if (!DH_generate_parameters_ex(dh_.get(), primeLength, g, nullptr))
5236 return false;
5237 return VerifyContext();
5238 }
5239
5240
Init(const char * p,int p_len,int g)5241 bool DiffieHellman::Init(const char* p, int p_len, int g) {
5242 dh_.reset(DH_new());
5243 if (p_len <= 0) {
5244 BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
5245 return false;
5246 }
5247 if (g <= 1) {
5248 DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
5249 return false;
5250 }
5251 BIGNUM* bn_p =
5252 BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, nullptr);
5253 BIGNUM* bn_g = BN_new();
5254 if (!BN_set_word(bn_g, g) ||
5255 !DH_set0_pqg(dh_.get(), bn_p, nullptr, bn_g)) {
5256 BN_free(bn_p);
5257 BN_free(bn_g);
5258 return false;
5259 }
5260 return VerifyContext();
5261 }
5262
5263
Init(const char * p,int p_len,const char * g,int g_len)5264 bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
5265 dh_.reset(DH_new());
5266 if (p_len <= 0) {
5267 BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
5268 return false;
5269 }
5270 if (g_len <= 0) {
5271 DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
5272 return false;
5273 }
5274 BIGNUM* bn_g =
5275 BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, nullptr);
5276 if (BN_is_zero(bn_g) || BN_is_one(bn_g)) {
5277 BN_free(bn_g);
5278 DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
5279 return false;
5280 }
5281 BIGNUM* bn_p =
5282 BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, nullptr);
5283 if (!DH_set0_pqg(dh_.get(), bn_p, nullptr, bn_g)) {
5284 BN_free(bn_p);
5285 BN_free(bn_g);
5286 return false;
5287 }
5288 return VerifyContext();
5289 }
5290
FindDiffieHellmanGroup(const char * name)5291 inline const modp_group* FindDiffieHellmanGroup(const char* name) {
5292 for (const modp_group& group : modp_groups) {
5293 if (StringEqualNoCase(name, group.name))
5294 return &group;
5295 }
5296 return nullptr;
5297 }
5298
DiffieHellmanGroup(const FunctionCallbackInfo<Value> & args)5299 void DiffieHellman::DiffieHellmanGroup(
5300 const FunctionCallbackInfo<Value>& args) {
5301 Environment* env = Environment::GetCurrent(args);
5302 DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
5303
5304 CHECK_EQ(args.Length(), 1);
5305 THROW_AND_RETURN_IF_NOT_STRING(env, args[0], "Group name");
5306
5307 bool initialized = false;
5308
5309 const node::Utf8Value group_name(env->isolate(), args[0]);
5310 const modp_group* group = FindDiffieHellmanGroup(*group_name);
5311 if (group == nullptr)
5312 return THROW_ERR_CRYPTO_UNKNOWN_DH_GROUP(env, "Unknown group");
5313
5314 initialized = diffieHellman->Init(group->prime,
5315 group->prime_size,
5316 group->gen);
5317 if (!initialized)
5318 env->ThrowError("Initialization failed");
5319 }
5320
5321
New(const FunctionCallbackInfo<Value> & args)5322 void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
5323 Environment* env = Environment::GetCurrent(args);
5324 DiffieHellman* diffieHellman =
5325 new DiffieHellman(env, args.This());
5326 bool initialized = false;
5327
5328 if (args.Length() == 2) {
5329 if (args[0]->IsInt32()) {
5330 if (args[1]->IsInt32()) {
5331 initialized = diffieHellman->Init(args[0].As<Int32>()->Value(),
5332 args[1].As<Int32>()->Value());
5333 }
5334 } else {
5335 ArrayBufferViewContents<char> arg0(args[0]);
5336 if (args[1]->IsInt32()) {
5337 initialized = diffieHellman->Init(arg0.data(),
5338 arg0.length(),
5339 args[1].As<Int32>()->Value());
5340 } else {
5341 ArrayBufferViewContents<char> arg1(args[1]);
5342 initialized = diffieHellman->Init(arg0.data(), arg0.length(),
5343 arg1.data(), arg1.length());
5344 }
5345 }
5346 }
5347
5348 if (!initialized) {
5349 return ThrowCryptoError(env, ERR_get_error(), "Initialization failed");
5350 }
5351 }
5352
5353
GenerateKeys(const FunctionCallbackInfo<Value> & args)5354 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
5355 Environment* env = Environment::GetCurrent(args);
5356
5357 DiffieHellman* diffieHellman;
5358 ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
5359
5360 if (!DH_generate_key(diffieHellman->dh_.get())) {
5361 return ThrowCryptoError(env, ERR_get_error(), "Key generation failed");
5362 }
5363
5364 const BIGNUM* pub_key;
5365 DH_get0_key(diffieHellman->dh_.get(), &pub_key, nullptr);
5366 const int size = BN_num_bytes(pub_key);
5367 CHECK_GE(size, 0);
5368 AllocatedBuffer data = env->AllocateManaged(size);
5369 CHECK_EQ(size,
5370 BN_bn2binpad(
5371 pub_key, reinterpret_cast<unsigned char*>(data.data()), size));
5372 args.GetReturnValue().Set(data.ToBuffer().ToLocalChecked());
5373 }
5374
5375
GetField(const FunctionCallbackInfo<Value> & args,const BIGNUM * (* get_field)(const DH *),const char * err_if_null)5376 void DiffieHellman::GetField(const FunctionCallbackInfo<Value>& args,
5377 const BIGNUM* (*get_field)(const DH*),
5378 const char* err_if_null) {
5379 Environment* env = Environment::GetCurrent(args);
5380
5381 DiffieHellman* dh;
5382 ASSIGN_OR_RETURN_UNWRAP(&dh, args.Holder());
5383
5384 const BIGNUM* num = get_field(dh->dh_.get());
5385 if (num == nullptr) return env->ThrowError(err_if_null);
5386
5387 const int size = BN_num_bytes(num);
5388 CHECK_GE(size, 0);
5389 AllocatedBuffer data = env->AllocateManaged(size);
5390 CHECK_EQ(
5391 size,
5392 BN_bn2binpad(num, reinterpret_cast<unsigned char*>(data.data()), size));
5393 args.GetReturnValue().Set(data.ToBuffer().ToLocalChecked());
5394 }
5395
GetPrime(const FunctionCallbackInfo<Value> & args)5396 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
5397 GetField(args, [](const DH* dh) -> const BIGNUM* {
5398 const BIGNUM* p;
5399 DH_get0_pqg(dh, &p, nullptr, nullptr);
5400 return p;
5401 }, "p is null");
5402 }
5403
5404
GetGenerator(const FunctionCallbackInfo<Value> & args)5405 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
5406 GetField(args, [](const DH* dh) -> const BIGNUM* {
5407 const BIGNUM* g;
5408 DH_get0_pqg(dh, nullptr, nullptr, &g);
5409 return g;
5410 }, "g is null");
5411 }
5412
5413
GetPublicKey(const FunctionCallbackInfo<Value> & args)5414 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
5415 GetField(args, [](const DH* dh) -> const BIGNUM* {
5416 const BIGNUM* pub_key;
5417 DH_get0_key(dh, &pub_key, nullptr);
5418 return pub_key;
5419 }, "No public key - did you forget to generate one?");
5420 }
5421
5422
GetPrivateKey(const FunctionCallbackInfo<Value> & args)5423 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
5424 GetField(args, [](const DH* dh) -> const BIGNUM* {
5425 const BIGNUM* priv_key;
5426 DH_get0_key(dh, nullptr, &priv_key);
5427 return priv_key;
5428 }, "No private key - did you forget to generate one?");
5429 }
5430
ZeroPadDiffieHellmanSecret(size_t remainder_size,AllocatedBuffer * ret)5431 static void ZeroPadDiffieHellmanSecret(size_t remainder_size,
5432 AllocatedBuffer* ret) {
5433 // DH_size returns number of bytes in a prime number.
5434 // DH_compute_key returns number of bytes in a remainder of exponent, which
5435 // may have less bytes than a prime number. Therefore add 0-padding to the
5436 // allocated buffer.
5437 const size_t prime_size = ret->size();
5438 if (remainder_size != prime_size) {
5439 CHECK_LT(remainder_size, prime_size);
5440 const size_t padding = prime_size - remainder_size;
5441 memmove(ret->data() + padding, ret->data(), remainder_size);
5442 memset(ret->data(), 0, padding);
5443 }
5444 }
5445
ComputeSecret(const FunctionCallbackInfo<Value> & args)5446 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
5447 Environment* env = Environment::GetCurrent(args);
5448
5449 DiffieHellman* diffieHellman;
5450 ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
5451
5452 ClearErrorOnReturn clear_error_on_return;
5453
5454 CHECK_EQ(args.Length(), 1);
5455 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Other party's public key");
5456 ArrayBufferViewContents<unsigned char> key_buf(args[0].As<ArrayBufferView>());
5457 BignumPointer key(BN_bin2bn(key_buf.data(), key_buf.length(), nullptr));
5458
5459 AllocatedBuffer ret = env->AllocateManaged(DH_size(diffieHellman->dh_.get()));
5460
5461 int size = DH_compute_key(reinterpret_cast<unsigned char*>(ret.data()),
5462 key.get(),
5463 diffieHellman->dh_.get());
5464
5465 if (size == -1) {
5466 int checkResult;
5467 int checked;
5468
5469 checked = DH_check_pub_key(diffieHellman->dh_.get(),
5470 key.get(),
5471 &checkResult);
5472
5473 if (!checked) {
5474 return ThrowCryptoError(env, ERR_get_error(), "Invalid Key");
5475 } else if (checkResult) {
5476 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
5477 return env->ThrowError("Supplied key is too small");
5478 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
5479 return env->ThrowError("Supplied key is too large");
5480 } else {
5481 return env->ThrowError("Invalid key");
5482 }
5483 } else {
5484 return env->ThrowError("Invalid key");
5485 }
5486
5487 UNREACHABLE();
5488 }
5489
5490 CHECK_GE(size, 0);
5491 ZeroPadDiffieHellmanSecret(static_cast<size_t>(size), &ret);
5492
5493 args.GetReturnValue().Set(ret.ToBuffer().ToLocalChecked());
5494 }
5495
SetKey(const FunctionCallbackInfo<Value> & args,int (* set_field)(DH *,BIGNUM *),const char * what)5496 void DiffieHellman::SetKey(const FunctionCallbackInfo<Value>& args,
5497 int (*set_field)(DH*, BIGNUM*), const char* what) {
5498 Environment* env = Environment::GetCurrent(args);
5499
5500 DiffieHellman* dh;
5501 ASSIGN_OR_RETURN_UNWRAP(&dh, args.Holder());
5502
5503 char errmsg[64];
5504
5505 CHECK_EQ(args.Length(), 1);
5506 if (!Buffer::HasInstance(args[0])) {
5507 snprintf(errmsg, sizeof(errmsg), "%s must be a buffer", what);
5508 return THROW_ERR_INVALID_ARG_TYPE(env, errmsg);
5509 }
5510
5511 ArrayBufferViewContents<unsigned char> buf(args[0].As<ArrayBufferView>());
5512 BIGNUM* num =
5513 BN_bin2bn(buf.data(), buf.length(), nullptr);
5514 CHECK_NOT_NULL(num);
5515 CHECK_EQ(1, set_field(dh->dh_.get(), num));
5516 }
5517
5518
SetPublicKey(const FunctionCallbackInfo<Value> & args)5519 void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
5520 SetKey(args,
5521 [](DH* dh, BIGNUM* num) { return DH_set0_key(dh, num, nullptr); },
5522 "Public key");
5523 }
5524
SetPrivateKey(const FunctionCallbackInfo<Value> & args)5525 void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
5526 SetKey(args,
5527 [](DH* dh, BIGNUM* num) { return DH_set0_key(dh, nullptr, num); },
5528 "Private key");
5529 }
5530
5531
VerifyErrorGetter(const FunctionCallbackInfo<Value> & args)5532 void DiffieHellman::VerifyErrorGetter(const FunctionCallbackInfo<Value>& args) {
5533 HandleScope scope(args.GetIsolate());
5534
5535 DiffieHellman* diffieHellman;
5536 ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
5537
5538 args.GetReturnValue().Set(diffieHellman->verifyError_);
5539 }
5540
5541
VerifyContext()5542 bool DiffieHellman::VerifyContext() {
5543 int codes;
5544 if (!DH_check(dh_.get(), &codes))
5545 return false;
5546 verifyError_ = codes;
5547 return true;
5548 }
5549
5550
Initialize(Environment * env,Local<Object> target)5551 void ECDH::Initialize(Environment* env, Local<Object> target) {
5552 HandleScope scope(env->isolate());
5553
5554 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
5555 t->Inherit(BaseObject::GetConstructorTemplate(env));
5556
5557 t->InstanceTemplate()->SetInternalFieldCount(ECDH::kInternalFieldCount);
5558
5559 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
5560 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
5561 env->SetProtoMethodNoSideEffect(t, "getPublicKey", GetPublicKey);
5562 env->SetProtoMethodNoSideEffect(t, "getPrivateKey", GetPrivateKey);
5563 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
5564 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
5565
5566 target->Set(env->context(),
5567 FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH"),
5568 t->GetFunction(env->context()).ToLocalChecked()).Check();
5569 }
5570
ECDH(Environment * env,Local<Object> wrap,ECKeyPointer && key)5571 ECDH::ECDH(Environment* env, Local<Object> wrap, ECKeyPointer&& key)
5572 : BaseObject(env, wrap),
5573 key_(std::move(key)),
5574 group_(EC_KEY_get0_group(key_.get())) {
5575 MakeWeak();
5576 CHECK_NOT_NULL(group_);
5577 }
5578
~ECDH()5579 ECDH::~ECDH() {}
5580
New(const FunctionCallbackInfo<Value> & args)5581 void ECDH::New(const FunctionCallbackInfo<Value>& args) {
5582 Environment* env = Environment::GetCurrent(args);
5583
5584 MarkPopErrorOnReturn mark_pop_error_on_return;
5585
5586 // TODO(indutny): Support raw curves?
5587 CHECK(args[0]->IsString());
5588 node::Utf8Value curve(env->isolate(), args[0]);
5589
5590 int nid = OBJ_sn2nid(*curve);
5591 if (nid == NID_undef)
5592 return THROW_ERR_INVALID_ARG_VALUE(env,
5593 "First argument should be a valid curve name");
5594
5595 ECKeyPointer key(EC_KEY_new_by_curve_name(nid));
5596 if (!key)
5597 return env->ThrowError("Failed to create EC_KEY using curve name");
5598
5599 new ECDH(env, args.This(), std::move(key));
5600 }
5601
5602
GenerateKeys(const FunctionCallbackInfo<Value> & args)5603 void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
5604 Environment* env = Environment::GetCurrent(args);
5605
5606 ECDH* ecdh;
5607 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5608
5609 if (!EC_KEY_generate_key(ecdh->key_.get()))
5610 return env->ThrowError("Failed to generate EC_KEY");
5611 }
5612
5613
BufferToPoint(Environment * env,const EC_GROUP * group,Local<Value> buf)5614 ECPointPointer ECDH::BufferToPoint(Environment* env,
5615 const EC_GROUP* group,
5616 Local<Value> buf) {
5617 int r;
5618
5619 ECPointPointer pub(EC_POINT_new(group));
5620 if (!pub) {
5621 env->ThrowError("Failed to allocate EC_POINT for a public key");
5622 return pub;
5623 }
5624
5625 ArrayBufferViewContents<unsigned char> input(buf);
5626 r = EC_POINT_oct2point(
5627 group,
5628 pub.get(),
5629 input.data(),
5630 input.length(),
5631 nullptr);
5632 if (!r)
5633 return ECPointPointer();
5634
5635 return pub;
5636 }
5637
5638
ComputeSecret(const FunctionCallbackInfo<Value> & args)5639 void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
5640 Environment* env = Environment::GetCurrent(args);
5641
5642 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Data");
5643
5644 ECDH* ecdh;
5645 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5646
5647 MarkPopErrorOnReturn mark_pop_error_on_return;
5648
5649 if (!ecdh->IsKeyPairValid())
5650 return env->ThrowError("Invalid key pair");
5651
5652 ECPointPointer pub(
5653 ECDH::BufferToPoint(env,
5654 ecdh->group_,
5655 args[0]));
5656 if (!pub) {
5657 args.GetReturnValue().Set(
5658 FIXED_ONE_BYTE_STRING(env->isolate(),
5659 "ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY"));
5660 return;
5661 }
5662
5663 // NOTE: field_size is in bits
5664 int field_size = EC_GROUP_get_degree(ecdh->group_);
5665 size_t out_len = (field_size + 7) / 8;
5666 AllocatedBuffer out = env->AllocateManaged(out_len);
5667
5668 int r = ECDH_compute_key(
5669 out.data(), out_len, pub.get(), ecdh->key_.get(), nullptr);
5670 if (!r)
5671 return env->ThrowError("Failed to compute ECDH key");
5672
5673 Local<Object> buf = out.ToBuffer().ToLocalChecked();
5674 args.GetReturnValue().Set(buf);
5675 }
5676
5677
GetPublicKey(const FunctionCallbackInfo<Value> & args)5678 void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
5679 Environment* env = Environment::GetCurrent(args);
5680
5681 // Conversion form
5682 CHECK_EQ(args.Length(), 1);
5683
5684 ECDH* ecdh;
5685 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5686
5687 const EC_GROUP* group = EC_KEY_get0_group(ecdh->key_.get());
5688 const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_.get());
5689 if (pub == nullptr)
5690 return env->ThrowError("Failed to get ECDH public key");
5691
5692 CHECK(args[0]->IsUint32());
5693 uint32_t val = args[0].As<Uint32>()->Value();
5694 point_conversion_form_t form = static_cast<point_conversion_form_t>(val);
5695
5696 const char* error;
5697 Local<Object> buf;
5698 if (!ECPointToBuffer(env, group, pub, form, &error).ToLocal(&buf))
5699 return env->ThrowError(error);
5700 args.GetReturnValue().Set(buf);
5701 }
5702
5703
GetPrivateKey(const FunctionCallbackInfo<Value> & args)5704 void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
5705 Environment* env = Environment::GetCurrent(args);
5706
5707 ECDH* ecdh;
5708 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5709
5710 const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_.get());
5711 if (b == nullptr)
5712 return env->ThrowError("Failed to get ECDH private key");
5713
5714 const int size = BN_num_bytes(b);
5715 AllocatedBuffer out = env->AllocateManaged(size);
5716 CHECK_EQ(size, BN_bn2binpad(b,
5717 reinterpret_cast<unsigned char*>(out.data()),
5718 size));
5719
5720 Local<Object> buf = out.ToBuffer().ToLocalChecked();
5721 args.GetReturnValue().Set(buf);
5722 }
5723
5724
SetPrivateKey(const FunctionCallbackInfo<Value> & args)5725 void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
5726 Environment* env = Environment::GetCurrent(args);
5727
5728 ECDH* ecdh;
5729 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5730
5731 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Private key");
5732 ArrayBufferViewContents<unsigned char> priv_buffer(args[0]);
5733
5734 BignumPointer priv(BN_bin2bn(
5735 priv_buffer.data(), priv_buffer.length(), nullptr));
5736 if (!priv)
5737 return env->ThrowError("Failed to convert Buffer to BN");
5738
5739 if (!ecdh->IsKeyValidForCurve(priv)) {
5740 return env->ThrowError("Private key is not valid for specified curve.");
5741 }
5742
5743 ECKeyPointer new_key(EC_KEY_dup(ecdh->key_.get()));
5744 CHECK(new_key);
5745
5746 int result = EC_KEY_set_private_key(new_key.get(), priv.get());
5747 priv.reset();
5748
5749 if (!result) {
5750 return env->ThrowError("Failed to convert BN to a private key");
5751 }
5752
5753 MarkPopErrorOnReturn mark_pop_error_on_return;
5754 USE(&mark_pop_error_on_return);
5755
5756 const BIGNUM* priv_key = EC_KEY_get0_private_key(new_key.get());
5757 CHECK_NOT_NULL(priv_key);
5758
5759 ECPointPointer pub(EC_POINT_new(ecdh->group_));
5760 CHECK(pub);
5761
5762 if (!EC_POINT_mul(ecdh->group_, pub.get(), priv_key,
5763 nullptr, nullptr, nullptr)) {
5764 return env->ThrowError("Failed to generate ECDH public key");
5765 }
5766
5767 if (!EC_KEY_set_public_key(new_key.get(), pub.get()))
5768 return env->ThrowError("Failed to set generated public key");
5769
5770 EC_KEY_copy(ecdh->key_.get(), new_key.get());
5771 ecdh->group_ = EC_KEY_get0_group(ecdh->key_.get());
5772 }
5773
5774
SetPublicKey(const FunctionCallbackInfo<Value> & args)5775 void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
5776 Environment* env = Environment::GetCurrent(args);
5777
5778 ECDH* ecdh;
5779 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5780
5781 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Public key");
5782
5783 MarkPopErrorOnReturn mark_pop_error_on_return;
5784
5785 ECPointPointer pub(
5786 ECDH::BufferToPoint(env,
5787 ecdh->group_,
5788 args[0]));
5789 if (!pub)
5790 return env->ThrowError("Failed to convert Buffer to EC_POINT");
5791
5792 int r = EC_KEY_set_public_key(ecdh->key_.get(), pub.get());
5793 if (!r)
5794 return env->ThrowError("Failed to set EC_POINT as the public key");
5795 }
5796
5797
IsKeyValidForCurve(const BignumPointer & private_key)5798 bool ECDH::IsKeyValidForCurve(const BignumPointer& private_key) {
5799 CHECK(group_);
5800 CHECK(private_key);
5801 // Private keys must be in the range [1, n-1].
5802 // Ref: Section 3.2.1 - http://www.secg.org/sec1-v2.pdf
5803 if (BN_cmp(private_key.get(), BN_value_one()) < 0) {
5804 return false;
5805 }
5806 BignumPointer order(BN_new());
5807 CHECK(order);
5808 return EC_GROUP_get_order(group_, order.get(), nullptr) &&
5809 BN_cmp(private_key.get(), order.get()) < 0;
5810 }
5811
5812
IsKeyPairValid()5813 bool ECDH::IsKeyPairValid() {
5814 MarkPopErrorOnReturn mark_pop_error_on_return;
5815 USE(&mark_pop_error_on_return);
5816 return 1 == EC_KEY_check_key(key_.get());
5817 }
5818
5819
5820 // TODO(addaleax): If there is an `AsyncWrap`, it currently has no access to
5821 // this object. This makes proper reporting of memory usage impossible.
5822 struct CryptoJob : public ThreadPoolWork {
5823 std::unique_ptr<AsyncWrap> async_wrap;
CryptoJobnode::crypto::CryptoJob5824 inline explicit CryptoJob(Environment* env) : ThreadPoolWork(env) {}
5825 inline void AfterThreadPoolWork(int status) final;
5826 virtual void AfterThreadPoolWork() = 0;
5827 static inline void Run(std::unique_ptr<CryptoJob> job, Local<Value> wrap);
5828 };
5829
5830
AfterThreadPoolWork(int status)5831 void CryptoJob::AfterThreadPoolWork(int status) {
5832 CHECK(status == 0 || status == UV_ECANCELED);
5833 std::unique_ptr<CryptoJob> job(this);
5834 if (status == UV_ECANCELED) return;
5835 HandleScope handle_scope(env()->isolate());
5836 Context::Scope context_scope(env()->context());
5837 CHECK_EQ(false, async_wrap->persistent().IsWeak());
5838 AfterThreadPoolWork();
5839 }
5840
5841
Run(std::unique_ptr<CryptoJob> job,Local<Value> wrap)5842 void CryptoJob::Run(std::unique_ptr<CryptoJob> job, Local<Value> wrap) {
5843 CHECK(wrap->IsObject());
5844 CHECK_NULL(job->async_wrap);
5845 job->async_wrap.reset(Unwrap<AsyncWrap>(wrap.As<Object>()));
5846 CHECK_EQ(false, job->async_wrap->persistent().IsWeak());
5847 job->ScheduleWork();
5848 job.release(); // Run free, little job!
5849 }
5850
5851
CopyBuffer(Local<Value> buf,std::vector<char> * vec)5852 inline void CopyBuffer(Local<Value> buf, std::vector<char>* vec) {
5853 CHECK(buf->IsArrayBufferView());
5854 vec->clear();
5855 vec->resize(buf.As<ArrayBufferView>()->ByteLength());
5856 buf.As<ArrayBufferView>()->CopyContents(vec->data(), vec->size());
5857 }
5858
5859
5860 struct RandomBytesJob : public CryptoJob {
5861 unsigned char* data;
5862 size_t size;
5863 CryptoErrorVector errors;
5864 Maybe<int> rc;
5865
RandomBytesJobnode::crypto::RandomBytesJob5866 inline explicit RandomBytesJob(Environment* env)
5867 : CryptoJob(env), rc(Nothing<int>()) {}
5868
DoThreadPoolWorknode::crypto::RandomBytesJob5869 inline void DoThreadPoolWork() override {
5870 CheckEntropy(); // Ensure that OpenSSL's PRNG is properly seeded.
5871 rc = Just(RAND_bytes(data, size));
5872 if (0 == rc.FromJust()) errors.Capture();
5873 }
5874
AfterThreadPoolWorknode::crypto::RandomBytesJob5875 inline void AfterThreadPoolWork() override {
5876 Local<Value> arg = ToResult();
5877 async_wrap->MakeCallback(env()->ondone_string(), 1, &arg);
5878 }
5879
ToResultnode::crypto::RandomBytesJob5880 inline Local<Value> ToResult() const {
5881 if (errors.empty()) return Undefined(env()->isolate());
5882 return errors.ToException(env()).ToLocalChecked();
5883 }
5884 };
5885
5886
RandomBytes(const FunctionCallbackInfo<Value> & args)5887 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
5888 CHECK(args[0]->IsArrayBufferView()); // buffer; wrap object retains ref.
5889 CHECK(args[1]->IsUint32()); // offset
5890 CHECK(args[2]->IsUint32()); // size
5891 CHECK(args[3]->IsObject() || args[3]->IsUndefined()); // wrap object
5892 const uint32_t offset = args[1].As<Uint32>()->Value();
5893 const uint32_t size = args[2].As<Uint32>()->Value();
5894 CHECK_GE(offset + size, offset); // Overflow check.
5895 CHECK_LE(offset + size, Buffer::Length(args[0])); // Bounds check.
5896 Environment* env = Environment::GetCurrent(args);
5897 std::unique_ptr<RandomBytesJob> job(new RandomBytesJob(env));
5898 job->data = reinterpret_cast<unsigned char*>(Buffer::Data(args[0])) + offset;
5899 job->size = size;
5900 if (args[3]->IsObject()) return RandomBytesJob::Run(std::move(job), args[3]);
5901 env->PrintSyncTrace();
5902 job->DoThreadPoolWork();
5903 args.GetReturnValue().Set(job->ToResult());
5904 }
5905
5906
5907 struct PBKDF2Job : public CryptoJob {
5908 unsigned char* keybuf_data;
5909 size_t keybuf_size;
5910 std::vector<char> pass;
5911 std::vector<char> salt;
5912 uint32_t iteration_count;
5913 const EVP_MD* digest;
5914 Maybe<bool> success;
5915
PBKDF2Jobnode::crypto::PBKDF2Job5916 inline explicit PBKDF2Job(Environment* env)
5917 : CryptoJob(env), success(Nothing<bool>()) {}
5918
~PBKDF2Jobnode::crypto::PBKDF2Job5919 inline ~PBKDF2Job() override {
5920 Cleanse();
5921 }
5922
DoThreadPoolWorknode::crypto::PBKDF2Job5923 inline void DoThreadPoolWork() override {
5924 auto salt_data = reinterpret_cast<const unsigned char*>(salt.data());
5925 const bool ok =
5926 PKCS5_PBKDF2_HMAC(pass.data(), pass.size(), salt_data, salt.size(),
5927 iteration_count, digest, keybuf_size, keybuf_data);
5928 success = Just(ok);
5929 Cleanse();
5930 }
5931
AfterThreadPoolWorknode::crypto::PBKDF2Job5932 inline void AfterThreadPoolWork() override {
5933 Local<Value> arg = ToResult();
5934 async_wrap->MakeCallback(env()->ondone_string(), 1, &arg);
5935 }
5936
ToResultnode::crypto::PBKDF2Job5937 inline Local<Value> ToResult() const {
5938 return Boolean::New(env()->isolate(), success.FromJust());
5939 }
5940
Cleansenode::crypto::PBKDF2Job5941 inline void Cleanse() {
5942 OPENSSL_cleanse(pass.data(), pass.size());
5943 OPENSSL_cleanse(salt.data(), salt.size());
5944 pass.clear();
5945 salt.clear();
5946 }
5947 };
5948
5949
PBKDF2(const FunctionCallbackInfo<Value> & args)5950 inline void PBKDF2(const FunctionCallbackInfo<Value>& args) {
5951 auto rv = args.GetReturnValue();
5952 Environment* env = Environment::GetCurrent(args);
5953 CHECK(args[0]->IsArrayBufferView()); // keybuf; wrap object retains ref.
5954 CHECK(args[1]->IsArrayBufferView()); // pass
5955 CHECK(args[2]->IsArrayBufferView()); // salt
5956 CHECK(args[3]->IsUint32()); // iteration_count
5957 CHECK(args[4]->IsString()); // digest_name
5958 CHECK(args[5]->IsObject() || args[5]->IsUndefined()); // wrap object
5959 std::unique_ptr<PBKDF2Job> job(new PBKDF2Job(env));
5960 job->keybuf_data = reinterpret_cast<unsigned char*>(Buffer::Data(args[0]));
5961 job->keybuf_size = Buffer::Length(args[0]);
5962 CopyBuffer(args[1], &job->pass);
5963 CopyBuffer(args[2], &job->salt);
5964 job->iteration_count = args[3].As<Uint32>()->Value();
5965 Utf8Value digest_name(args.GetIsolate(), args[4]);
5966 job->digest = EVP_get_digestbyname(*digest_name);
5967 if (job->digest == nullptr) return rv.Set(-1);
5968 if (args[5]->IsObject()) return PBKDF2Job::Run(std::move(job), args[5]);
5969 env->PrintSyncTrace();
5970 job->DoThreadPoolWork();
5971 rv.Set(job->ToResult());
5972 }
5973
5974
5975 #ifndef OPENSSL_NO_SCRYPT
5976 struct ScryptJob : public CryptoJob {
5977 unsigned char* keybuf_data;
5978 size_t keybuf_size;
5979 std::vector<char> pass;
5980 std::vector<char> salt;
5981 uint32_t N;
5982 uint32_t r;
5983 uint32_t p;
5984 uint64_t maxmem;
5985 CryptoErrorVector errors;
5986
ScryptJobnode::crypto::ScryptJob5987 inline explicit ScryptJob(Environment* env) : CryptoJob(env) {}
5988
~ScryptJobnode::crypto::ScryptJob5989 inline ~ScryptJob() override {
5990 Cleanse();
5991 }
5992
Validatenode::crypto::ScryptJob5993 inline bool Validate() {
5994 if (1 == EVP_PBE_scrypt(nullptr, 0, nullptr, 0, N, r, p, maxmem,
5995 nullptr, 0)) {
5996 return true;
5997 } else {
5998 // Note: EVP_PBE_scrypt() does not always put errors on the error stack.
5999 errors.Capture();
6000 return false;
6001 }
6002 }
6003
DoThreadPoolWorknode::crypto::ScryptJob6004 inline void DoThreadPoolWork() override {
6005 auto salt_data = reinterpret_cast<const unsigned char*>(salt.data());
6006 if (1 != EVP_PBE_scrypt(pass.data(), pass.size(), salt_data, salt.size(),
6007 N, r, p, maxmem, keybuf_data, keybuf_size)) {
6008 errors.Capture();
6009 }
6010 }
6011
AfterThreadPoolWorknode::crypto::ScryptJob6012 inline void AfterThreadPoolWork() override {
6013 Local<Value> arg = ToResult();
6014 async_wrap->MakeCallback(env()->ondone_string(), 1, &arg);
6015 }
6016
ToResultnode::crypto::ScryptJob6017 inline Local<Value> ToResult() const {
6018 if (errors.empty()) return Undefined(env()->isolate());
6019 return errors.ToException(env()).ToLocalChecked();
6020 }
6021
Cleansenode::crypto::ScryptJob6022 inline void Cleanse() {
6023 OPENSSL_cleanse(pass.data(), pass.size());
6024 OPENSSL_cleanse(salt.data(), salt.size());
6025 pass.clear();
6026 salt.clear();
6027 }
6028 };
6029
6030
Scrypt(const FunctionCallbackInfo<Value> & args)6031 void Scrypt(const FunctionCallbackInfo<Value>& args) {
6032 Environment* env = Environment::GetCurrent(args);
6033 CHECK(args[0]->IsArrayBufferView()); // keybuf; wrap object retains ref.
6034 CHECK(args[1]->IsArrayBufferView()); // pass
6035 CHECK(args[2]->IsArrayBufferView()); // salt
6036 CHECK(args[3]->IsUint32()); // N
6037 CHECK(args[4]->IsUint32()); // r
6038 CHECK(args[5]->IsUint32()); // p
6039 CHECK(args[6]->IsNumber()); // maxmem
6040 CHECK(args[7]->IsObject() || args[7]->IsUndefined()); // wrap object
6041 std::unique_ptr<ScryptJob> job(new ScryptJob(env));
6042 job->keybuf_data = reinterpret_cast<unsigned char*>(Buffer::Data(args[0]));
6043 job->keybuf_size = Buffer::Length(args[0]);
6044 CopyBuffer(args[1], &job->pass);
6045 CopyBuffer(args[2], &job->salt);
6046 job->N = args[3].As<Uint32>()->Value();
6047 job->r = args[4].As<Uint32>()->Value();
6048 job->p = args[5].As<Uint32>()->Value();
6049 Local<Context> ctx = env->isolate()->GetCurrentContext();
6050 job->maxmem = static_cast<uint64_t>(args[6]->IntegerValue(ctx).ToChecked());
6051 if (!job->Validate()) {
6052 // EVP_PBE_scrypt() does not always put errors on the error stack
6053 // and therefore ToResult() may or may not return an exception
6054 // object. Return a sentinel value to inform JS land it should
6055 // throw an ERR_CRYPTO_SCRYPT_INVALID_PARAMETER on our behalf.
6056 auto result = job->ToResult();
6057 if (result->IsUndefined()) result = Null(args.GetIsolate());
6058 return args.GetReturnValue().Set(result);
6059 }
6060 if (args[7]->IsObject()) return ScryptJob::Run(std::move(job), args[7]);
6061 env->PrintSyncTrace();
6062 job->DoThreadPoolWork();
6063 args.GetReturnValue().Set(job->ToResult());
6064 }
6065 #endif // OPENSSL_NO_SCRYPT
6066
6067
6068 class KeyPairGenerationConfig {
6069 public:
6070 virtual EVPKeyCtxPointer Setup() = 0;
Configure(const EVPKeyCtxPointer & ctx)6071 virtual bool Configure(const EVPKeyCtxPointer& ctx) {
6072 return true;
6073 }
6074 virtual ~KeyPairGenerationConfig() = default;
6075 };
6076
6077 class RSAKeyPairGenerationConfig : public KeyPairGenerationConfig {
6078 public:
RSAKeyPairGenerationConfig(unsigned int modulus_bits,unsigned int exponent)6079 RSAKeyPairGenerationConfig(unsigned int modulus_bits, unsigned int exponent)
6080 : modulus_bits_(modulus_bits), exponent_(exponent) {}
6081
Setup()6082 EVPKeyCtxPointer Setup() override {
6083 return EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr));
6084 }
6085
Configure(const EVPKeyCtxPointer & ctx)6086 bool Configure(const EVPKeyCtxPointer& ctx) override {
6087 if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), modulus_bits_) <= 0)
6088 return false;
6089
6090 // 0x10001 is the default RSA exponent.
6091 if (exponent_ != 0x10001) {
6092 BignumPointer bn(BN_new());
6093 CHECK_NOT_NULL(bn.get());
6094 CHECK(BN_set_word(bn.get(), exponent_));
6095 // EVP_CTX acceps ownership of bn on success.
6096 if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx.get(), bn.get()) <= 0)
6097 return false;
6098 bn.release();
6099 }
6100
6101 return true;
6102 }
6103
6104 private:
6105 const unsigned int modulus_bits_;
6106 const unsigned int exponent_;
6107 };
6108
6109 class RSAPSSKeyPairGenerationConfig : public RSAKeyPairGenerationConfig {
6110 public:
RSAPSSKeyPairGenerationConfig(unsigned int modulus_bits,unsigned int exponent,const EVP_MD * md,const EVP_MD * mgf1_md,int saltlen)6111 RSAPSSKeyPairGenerationConfig(unsigned int modulus_bits,
6112 unsigned int exponent,
6113 const EVP_MD* md,
6114 const EVP_MD* mgf1_md,
6115 int saltlen)
6116 : RSAKeyPairGenerationConfig(modulus_bits, exponent),
6117 md_(md), mgf1_md_(mgf1_md), saltlen_(saltlen) {}
6118
Setup()6119 EVPKeyCtxPointer Setup() override {
6120 return EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA_PSS, nullptr));
6121 }
6122
Configure(const EVPKeyCtxPointer & ctx)6123 bool Configure(const EVPKeyCtxPointer& ctx) override {
6124 if (!RSAKeyPairGenerationConfig::Configure(ctx))
6125 return false;
6126
6127 if (md_ != nullptr) {
6128 if (EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx.get(), md_) <= 0)
6129 return false;
6130 }
6131
6132 if (mgf1_md_ != nullptr) {
6133 if (EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx.get(), mgf1_md_) <= 0)
6134 return false;
6135 }
6136
6137 if (saltlen_ >= 0) {
6138 if (EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx.get(), saltlen_) <= 0)
6139 return false;
6140 }
6141
6142 return true;
6143 }
6144
6145 private:
6146 const EVP_MD* md_;
6147 const EVP_MD* mgf1_md_;
6148 const int saltlen_;
6149 };
6150
6151 class DSAKeyPairGenerationConfig : public KeyPairGenerationConfig {
6152 public:
DSAKeyPairGenerationConfig(unsigned int modulus_bits,int divisor_bits)6153 DSAKeyPairGenerationConfig(unsigned int modulus_bits, int divisor_bits)
6154 : modulus_bits_(modulus_bits), divisor_bits_(divisor_bits) {}
6155
Setup()6156 EVPKeyCtxPointer Setup() override {
6157 EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, nullptr));
6158 if (!param_ctx)
6159 return nullptr;
6160
6161 if (EVP_PKEY_paramgen_init(param_ctx.get()) <= 0)
6162 return nullptr;
6163
6164 if (EVP_PKEY_CTX_set_dsa_paramgen_bits(param_ctx.get(), modulus_bits_) <= 0)
6165 return nullptr;
6166
6167 if (divisor_bits_ != -1) {
6168 if (EVP_PKEY_CTX_ctrl(param_ctx.get(), EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
6169 EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, divisor_bits_,
6170 nullptr) <= 0) {
6171 return nullptr;
6172 }
6173 }
6174
6175 EVP_PKEY* raw_params = nullptr;
6176 if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0)
6177 return nullptr;
6178 EVPKeyPointer params(raw_params);
6179 param_ctx.reset();
6180
6181 EVPKeyCtxPointer key_ctx(EVP_PKEY_CTX_new(params.get(), nullptr));
6182 return key_ctx;
6183 }
6184
6185 private:
6186 const unsigned int modulus_bits_;
6187 const int divisor_bits_;
6188 };
6189
6190 class ECKeyPairGenerationConfig : public KeyPairGenerationConfig {
6191 public:
ECKeyPairGenerationConfig(int curve_nid,int param_encoding)6192 ECKeyPairGenerationConfig(int curve_nid, int param_encoding)
6193 : curve_nid_(curve_nid), param_encoding_(param_encoding) {}
6194
Setup()6195 EVPKeyCtxPointer Setup() override {
6196 EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
6197 if (!param_ctx)
6198 return nullptr;
6199
6200 if (EVP_PKEY_paramgen_init(param_ctx.get()) <= 0)
6201 return nullptr;
6202
6203 if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(param_ctx.get(),
6204 curve_nid_) <= 0)
6205 return nullptr;
6206
6207 if (EVP_PKEY_CTX_set_ec_param_enc(param_ctx.get(), param_encoding_) <= 0)
6208 return nullptr;
6209
6210 EVP_PKEY* raw_params = nullptr;
6211 if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0)
6212 return nullptr;
6213 EVPKeyPointer params(raw_params);
6214 param_ctx.reset();
6215
6216 EVPKeyCtxPointer key_ctx(EVP_PKEY_CTX_new(params.get(), nullptr));
6217 return key_ctx;
6218 }
6219
6220 private:
6221 const int curve_nid_;
6222 const int param_encoding_;
6223 };
6224
6225 class NidKeyPairGenerationConfig : public KeyPairGenerationConfig {
6226 public:
NidKeyPairGenerationConfig(int id)6227 explicit NidKeyPairGenerationConfig(int id) : id_(id) {}
6228
Setup()6229 EVPKeyCtxPointer Setup() override {
6230 return EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(id_, nullptr));
6231 }
6232
6233 private:
6234 const int id_;
6235 };
6236
6237 // TODO(tniessen): Use std::variant instead.
6238 // Diffie-Hellman can either generate keys using a fixed prime, or by first
6239 // generating a random prime of a given size (in bits). Only one of both options
6240 // may be specified.
6241 struct PrimeInfo {
6242 BignumPointer fixed_value_;
6243 unsigned int prime_size_;
6244 };
6245
6246 class DHKeyPairGenerationConfig : public KeyPairGenerationConfig {
6247 public:
DHKeyPairGenerationConfig(PrimeInfo && prime_info,unsigned int generator)6248 explicit DHKeyPairGenerationConfig(PrimeInfo&& prime_info,
6249 unsigned int generator)
6250 : prime_info_(std::move(prime_info)),
6251 generator_(generator) {}
6252
Setup()6253 EVPKeyCtxPointer Setup() override {
6254 EVPKeyPointer params;
6255 if (prime_info_.fixed_value_) {
6256 DHPointer dh(DH_new());
6257 if (!dh)
6258 return nullptr;
6259
6260 BIGNUM* prime = prime_info_.fixed_value_.get();
6261 BignumPointer bn_g(BN_new());
6262 if (!BN_set_word(bn_g.get(), generator_) ||
6263 !DH_set0_pqg(dh.get(), prime, nullptr, bn_g.get()))
6264 return nullptr;
6265
6266 prime_info_.fixed_value_.release();
6267 bn_g.release();
6268
6269 params = EVPKeyPointer(EVP_PKEY_new());
6270 CHECK(params);
6271 EVP_PKEY_assign_DH(params.get(), dh.release());
6272 } else {
6273 EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DH, nullptr));
6274 if (!param_ctx)
6275 return nullptr;
6276
6277 if (EVP_PKEY_paramgen_init(param_ctx.get()) <= 0)
6278 return nullptr;
6279
6280 if (EVP_PKEY_CTX_set_dh_paramgen_prime_len(param_ctx.get(),
6281 prime_info_.prime_size_) <= 0)
6282 return nullptr;
6283
6284 if (EVP_PKEY_CTX_set_dh_paramgen_generator(param_ctx.get(),
6285 generator_) <= 0)
6286 return nullptr;
6287
6288 EVP_PKEY* raw_params = nullptr;
6289 if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0)
6290 return nullptr;
6291 params = EVPKeyPointer(raw_params);
6292 }
6293
6294 return EVPKeyCtxPointer(EVP_PKEY_CTX_new(params.get(), nullptr));
6295 }
6296
6297 private:
6298 PrimeInfo prime_info_;
6299 unsigned int generator_;
6300 };
6301
6302 class GenerateKeyPairJob : public CryptoJob {
6303 public:
GenerateKeyPairJob(Environment * env,std::unique_ptr<KeyPairGenerationConfig> config,PublicKeyEncodingConfig public_key_encoding,PrivateKeyEncodingConfig && private_key_encoding)6304 GenerateKeyPairJob(Environment* env,
6305 std::unique_ptr<KeyPairGenerationConfig> config,
6306 PublicKeyEncodingConfig public_key_encoding,
6307 PrivateKeyEncodingConfig&& private_key_encoding)
6308 : CryptoJob(env),
6309 config_(std::move(config)),
6310 public_key_encoding_(public_key_encoding),
6311 private_key_encoding_(std::forward<PrivateKeyEncodingConfig>(
6312 private_key_encoding)),
6313 pkey_(nullptr) {}
6314
DoThreadPoolWork()6315 inline void DoThreadPoolWork() override {
6316 if (!GenerateKey())
6317 errors_.Capture();
6318 }
6319
GenerateKey()6320 inline bool GenerateKey() {
6321 // Make sure that the CSPRNG is properly seeded so the results are secure.
6322 CheckEntropy();
6323
6324 // Create the key generation context.
6325 EVPKeyCtxPointer ctx = config_->Setup();
6326 if (!ctx)
6327 return false;
6328
6329 // Initialize key generation.
6330 if (EVP_PKEY_keygen_init(ctx.get()) <= 0)
6331 return false;
6332
6333 // Configure key generation.
6334 if (!config_->Configure(ctx))
6335 return false;
6336
6337 // Generate the key.
6338 EVP_PKEY* pkey = nullptr;
6339 if (EVP_PKEY_keygen(ctx.get(), &pkey) != 1)
6340 return false;
6341 pkey_ = ManagedEVPPKey(EVPKeyPointer(pkey));
6342 return true;
6343 }
6344
AfterThreadPoolWork()6345 inline void AfterThreadPoolWork() override {
6346 Local<Value> args[3];
6347 ToResult(&args[0], &args[1], &args[2]);
6348 async_wrap->MakeCallback(env()->ondone_string(), 3, args);
6349 }
6350
ToResult(Local<Value> * err,Local<Value> * pubkey,Local<Value> * privkey)6351 inline void ToResult(Local<Value>* err,
6352 Local<Value>* pubkey,
6353 Local<Value>* privkey) {
6354 if (pkey_ && EncodeKeys(pubkey, privkey)) {
6355 CHECK(errors_.empty());
6356 *err = Undefined(env()->isolate());
6357 } else {
6358 if (errors_.empty())
6359 errors_.Capture();
6360 CHECK(!errors_.empty());
6361 *err = errors_.ToException(env()).ToLocalChecked();
6362 *pubkey = Undefined(env()->isolate());
6363 *privkey = Undefined(env()->isolate());
6364 }
6365 }
6366
EncodeKeys(Local<Value> * pubkey,Local<Value> * privkey)6367 inline bool EncodeKeys(Local<Value>* pubkey, Local<Value>* privkey) {
6368 // Encode the public key.
6369 if (public_key_encoding_.output_key_object_) {
6370 // Note that this has the downside of containing sensitive data of the
6371 // private key.
6372 std::shared_ptr<KeyObjectData> data =
6373 KeyObjectData::CreateAsymmetric(kKeyTypePublic, pkey_);
6374 if (!KeyObjectHandle::Create(env(), data).ToLocal(pubkey))
6375 return false;
6376 } else {
6377 if (!WritePublicKey(env(), pkey_.get(), public_key_encoding_)
6378 .ToLocal(pubkey))
6379 return false;
6380 }
6381
6382 // Now do the same for the private key.
6383 if (private_key_encoding_.output_key_object_) {
6384 std::shared_ptr<KeyObjectData> data =
6385 KeyObjectData::CreateAsymmetric(kKeyTypePrivate, pkey_);
6386 if (!KeyObjectHandle::Create(env(), data).ToLocal(privkey))
6387 return false;
6388 } else {
6389 if (!WritePrivateKey(env(), pkey_.get(), private_key_encoding_)
6390 .ToLocal(privkey))
6391 return false;
6392 }
6393
6394 return true;
6395 }
6396
6397 private:
6398 CryptoErrorVector errors_;
6399 std::unique_ptr<KeyPairGenerationConfig> config_;
6400 PublicKeyEncodingConfig public_key_encoding_;
6401 PrivateKeyEncodingConfig private_key_encoding_;
6402 ManagedEVPPKey pkey_;
6403 };
6404
GenerateKeyPair(const FunctionCallbackInfo<Value> & args,unsigned int offset,std::unique_ptr<KeyPairGenerationConfig> config)6405 void GenerateKeyPair(const FunctionCallbackInfo<Value>& args,
6406 unsigned int offset,
6407 std::unique_ptr<KeyPairGenerationConfig> config) {
6408 Environment* env = Environment::GetCurrent(args);
6409
6410 PublicKeyEncodingConfig public_key_encoding =
6411 GetPublicKeyEncodingFromJs(args, &offset, kKeyContextGenerate);
6412 NonCopyableMaybe<PrivateKeyEncodingConfig> private_key_encoding =
6413 GetPrivateKeyEncodingFromJs(args, &offset, kKeyContextGenerate);
6414
6415 if (private_key_encoding.IsEmpty())
6416 return;
6417
6418 std::unique_ptr<GenerateKeyPairJob> job(
6419 new GenerateKeyPairJob(env, std::move(config), public_key_encoding,
6420 private_key_encoding.Release()));
6421 if (args[offset]->IsObject())
6422 return GenerateKeyPairJob::Run(std::move(job), args[offset]);
6423 env->PrintSyncTrace();
6424 job->DoThreadPoolWork();
6425 Local<Value> err, pubkey, privkey;
6426 job->ToResult(&err, &pubkey, &privkey);
6427
6428 Local<Value> ret[] = { err, pubkey, privkey };
6429 args.GetReturnValue().Set(Array::New(env->isolate(), ret, arraysize(ret)));
6430 }
6431
GenerateKeyPairRSA(const FunctionCallbackInfo<Value> & args)6432 void GenerateKeyPairRSA(const FunctionCallbackInfo<Value>& args) {
6433 CHECK(args[0]->IsUint32());
6434 const uint32_t modulus_bits = args[0].As<Uint32>()->Value();
6435 CHECK(args[1]->IsUint32());
6436 const uint32_t exponent = args[1].As<Uint32>()->Value();
6437 std::unique_ptr<KeyPairGenerationConfig> config(
6438 new RSAKeyPairGenerationConfig(modulus_bits, exponent));
6439 GenerateKeyPair(args, 2, std::move(config));
6440 }
6441
GenerateKeyPairRSAPSS(const FunctionCallbackInfo<Value> & args)6442 void GenerateKeyPairRSAPSS(const FunctionCallbackInfo<Value>& args) {
6443 Environment* env = Environment::GetCurrent(args);
6444
6445 CHECK(args[0]->IsUint32());
6446 const uint32_t modulus_bits = args[0].As<Uint32>()->Value();
6447 CHECK(args[1]->IsUint32());
6448 const uint32_t exponent = args[1].As<Uint32>()->Value();
6449
6450 const EVP_MD* md = nullptr;
6451 if (!args[2]->IsUndefined()) {
6452 CHECK(args[2]->IsString());
6453 String::Utf8Value md_name(env->isolate(), args[2].As<String>());
6454 md = EVP_get_digestbyname(*md_name);
6455 if (md == nullptr)
6456 return env->ThrowTypeError("Digest method not supported");
6457 }
6458
6459 const EVP_MD* mgf1_md = nullptr;
6460 if (!args[3]->IsUndefined()) {
6461 CHECK(args[3]->IsString());
6462 String::Utf8Value mgf1_md_name(env->isolate(), args[3].As<String>());
6463 mgf1_md = EVP_get_digestbyname(*mgf1_md_name);
6464 if (mgf1_md == nullptr)
6465 return env->ThrowTypeError("Digest method not supported");
6466 }
6467
6468 int saltlen = -1;
6469 if (!args[4]->IsUndefined()) {
6470 CHECK(args[4]->IsInt32());
6471 saltlen = args[4].As<Int32>()->Value();
6472 }
6473
6474 std::unique_ptr<KeyPairGenerationConfig> config(
6475 new RSAPSSKeyPairGenerationConfig(modulus_bits, exponent,
6476 md, mgf1_md, saltlen));
6477 GenerateKeyPair(args, 5, std::move(config));
6478 }
6479
GenerateKeyPairDSA(const FunctionCallbackInfo<Value> & args)6480 void GenerateKeyPairDSA(const FunctionCallbackInfo<Value>& args) {
6481 CHECK(args[0]->IsUint32());
6482 const uint32_t modulus_bits = args[0].As<Uint32>()->Value();
6483 CHECK(args[1]->IsInt32());
6484 const int32_t divisor_bits = args[1].As<Int32>()->Value();
6485 std::unique_ptr<KeyPairGenerationConfig> config(
6486 new DSAKeyPairGenerationConfig(modulus_bits, divisor_bits));
6487 GenerateKeyPair(args, 2, std::move(config));
6488 }
6489
GenerateKeyPairEC(const FunctionCallbackInfo<Value> & args)6490 void GenerateKeyPairEC(const FunctionCallbackInfo<Value>& args) {
6491 CHECK(args[0]->IsString());
6492 String::Utf8Value curve_name(args.GetIsolate(), args[0].As<String>());
6493 int curve_nid = EC_curve_nist2nid(*curve_name);
6494 if (curve_nid == NID_undef)
6495 curve_nid = OBJ_sn2nid(*curve_name);
6496 // TODO(tniessen): Should we also support OBJ_ln2nid? (Other APIs don't.)
6497 if (curve_nid == NID_undef) {
6498 Environment* env = Environment::GetCurrent(args);
6499 return env->ThrowTypeError("Invalid ECDH curve name");
6500 }
6501 CHECK(args[1]->IsUint32());
6502 const uint32_t param_encoding = args[1].As<Int32>()->Value();
6503 CHECK(param_encoding == OPENSSL_EC_NAMED_CURVE ||
6504 param_encoding == OPENSSL_EC_EXPLICIT_CURVE);
6505 std::unique_ptr<KeyPairGenerationConfig> config(
6506 new ECKeyPairGenerationConfig(curve_nid, param_encoding));
6507 GenerateKeyPair(args, 2, std::move(config));
6508 }
6509
GenerateKeyPairNid(const FunctionCallbackInfo<Value> & args)6510 void GenerateKeyPairNid(const FunctionCallbackInfo<Value>& args) {
6511 CHECK(args[0]->IsInt32());
6512 const int id = args[0].As<Int32>()->Value();
6513 std::unique_ptr<KeyPairGenerationConfig> config(
6514 new NidKeyPairGenerationConfig(id));
6515 GenerateKeyPair(args, 1, std::move(config));
6516 }
6517
GenerateKeyPairDH(const FunctionCallbackInfo<Value> & args)6518 void GenerateKeyPairDH(const FunctionCallbackInfo<Value>& args) {
6519 Environment* env = Environment::GetCurrent(args);
6520
6521 PrimeInfo prime_info = {};
6522 unsigned int generator;
6523 if (args[0]->IsString()) {
6524 String::Utf8Value group_name(args.GetIsolate(), args[0].As<String>());
6525 const modp_group* group = FindDiffieHellmanGroup(*group_name);
6526 if (group == nullptr)
6527 return THROW_ERR_CRYPTO_UNKNOWN_DH_GROUP(env);
6528
6529 prime_info.fixed_value_ = BignumPointer(
6530 BN_bin2bn(reinterpret_cast<const unsigned char*>(group->prime),
6531 group->prime_size, nullptr));
6532 generator = group->gen;
6533 } else {
6534 if (args[0]->IsInt32()) {
6535 prime_info.prime_size_ = args[0].As<Int32>()->Value();
6536 } else {
6537 ArrayBufferViewContents<unsigned char> input(args[0]);
6538 prime_info.fixed_value_ = BignumPointer(
6539 BN_bin2bn(input.data(), input.length(), nullptr));
6540 }
6541
6542 CHECK(args[1]->IsInt32());
6543 generator = args[1].As<Int32>()->Value();
6544 }
6545
6546 std::unique_ptr<KeyPairGenerationConfig> config(
6547 new DHKeyPairGenerationConfig(std::move(prime_info), generator));
6548 GenerateKeyPair(args, 2, std::move(config));
6549 }
6550
6551
GetSSLCiphers(const FunctionCallbackInfo<Value> & args)6552 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
6553 Environment* env = Environment::GetCurrent(args);
6554
6555 SSLCtxPointer ctx(SSL_CTX_new(TLS_method()));
6556 CHECK(ctx);
6557
6558 SSLPointer ssl(SSL_new(ctx.get()));
6559 CHECK(ssl);
6560
6561 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl.get());
6562 // TLSv1.3 ciphers aren't listed by EVP. There are only 5, we could just
6563 // document them, but since there are only 5, easier to just add them manually
6564 // and not have to explain their absence in the API docs. They are lower-cased
6565 // because the docs say they will be.
6566 static const char* TLS13_CIPHERS[] = {
6567 "tls_aes_256_gcm_sha384",
6568 "tls_chacha20_poly1305_sha256",
6569 "tls_aes_128_gcm_sha256",
6570 "tls_aes_128_ccm_8_sha256",
6571 "tls_aes_128_ccm_sha256"
6572 };
6573
6574 const int n = sk_SSL_CIPHER_num(ciphers);
6575 std::vector<Local<Value>> arr(n + arraysize(TLS13_CIPHERS));
6576
6577 for (int i = 0; i < n; ++i) {
6578 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
6579 arr[i] = OneByteString(env->isolate(), SSL_CIPHER_get_name(cipher));
6580 }
6581
6582 for (unsigned i = 0; i < arraysize(TLS13_CIPHERS); ++i) {
6583 const char* name = TLS13_CIPHERS[i];
6584 arr[n + i] = OneByteString(env->isolate(), name);
6585 }
6586
6587 args.GetReturnValue().Set(Array::New(env->isolate(), arr.data(), arr.size()));
6588 }
6589
6590
6591 class CipherPushContext {
6592 public:
CipherPushContext(Environment * env)6593 explicit CipherPushContext(Environment* env)
6594 : arr(Array::New(env->isolate())),
6595 env_(env) {
6596 }
6597
env() const6598 inline Environment* env() const { return env_; }
6599
6600 Local<Array> arr;
6601
6602 private:
6603 Environment* env_;
6604 };
6605
6606
6607 template <class TypeName>
array_push_back(const TypeName * md,const char * from,const char * to,void * arg)6608 static void array_push_back(const TypeName* md,
6609 const char* from,
6610 const char* to,
6611 void* arg) {
6612 CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
6613 ctx->arr->Set(ctx->env()->context(),
6614 ctx->arr->Length(),
6615 OneByteString(ctx->env()->isolate(), from)).Check();
6616 }
6617
6618
GetCiphers(const FunctionCallbackInfo<Value> & args)6619 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
6620 Environment* env = Environment::GetCurrent(args);
6621 CipherPushContext ctx(env);
6622 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
6623 args.GetReturnValue().Set(ctx.arr);
6624 }
6625
6626
GetHashes(const FunctionCallbackInfo<Value> & args)6627 void GetHashes(const FunctionCallbackInfo<Value>& args) {
6628 Environment* env = Environment::GetCurrent(args);
6629 CipherPushContext ctx(env);
6630 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
6631 args.GetReturnValue().Set(ctx.arr);
6632 }
6633
6634
GetCurves(const FunctionCallbackInfo<Value> & args)6635 void GetCurves(const FunctionCallbackInfo<Value>& args) {
6636 Environment* env = Environment::GetCurrent(args);
6637 const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
6638
6639 if (num_curves) {
6640 std::vector<EC_builtin_curve> curves(num_curves);
6641
6642 if (EC_get_builtin_curves(curves.data(), num_curves)) {
6643 std::vector<Local<Value>> arr(num_curves);
6644
6645 for (size_t i = 0; i < num_curves; i++)
6646 arr[i] = OneByteString(env->isolate(), OBJ_nid2sn(curves[i].nid));
6647
6648 args.GetReturnValue().Set(
6649 Array::New(env->isolate(), arr.data(), arr.size()));
6650 return;
6651 }
6652 }
6653
6654 args.GetReturnValue().Set(Array::New(env->isolate()));
6655 }
6656
6657
VerifySpkac(const char * data,unsigned int len)6658 bool VerifySpkac(const char* data, unsigned int len) {
6659 NetscapeSPKIPointer spki(NETSCAPE_SPKI_b64_decode(data, len));
6660 if (!spki)
6661 return false;
6662
6663 EVPKeyPointer pkey(X509_PUBKEY_get(spki->spkac->pubkey));
6664 if (!pkey)
6665 return false;
6666
6667 return NETSCAPE_SPKI_verify(spki.get(), pkey.get()) > 0;
6668 }
6669
6670
VerifySpkac(const FunctionCallbackInfo<Value> & args)6671 void VerifySpkac(const FunctionCallbackInfo<Value>& args) {
6672 bool verify_result = false;
6673
6674 ArrayBufferViewContents<char> input(args[0]);
6675 if (input.length() == 0)
6676 return args.GetReturnValue().SetEmptyString();
6677
6678 CHECK_NOT_NULL(input.data());
6679
6680 verify_result = VerifySpkac(input.data(), input.length());
6681
6682 args.GetReturnValue().Set(verify_result);
6683 }
6684
ExportPublicKey(Environment * env,const char * data,int len,size_t * size)6685 AllocatedBuffer ExportPublicKey(Environment* env,
6686 const char* data,
6687 int len,
6688 size_t* size) {
6689 BIOPointer bio(BIO_new(BIO_s_mem()));
6690 if (!bio) return AllocatedBuffer();
6691
6692 NetscapeSPKIPointer spki(NETSCAPE_SPKI_b64_decode(data, len));
6693 if (!spki) return AllocatedBuffer();
6694
6695 EVPKeyPointer pkey(NETSCAPE_SPKI_get_pubkey(spki.get()));
6696 if (!pkey) return AllocatedBuffer();
6697
6698 if (PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0)
6699 return AllocatedBuffer();
6700
6701 BUF_MEM* ptr;
6702 BIO_get_mem_ptr(bio.get(), &ptr);
6703
6704 *size = ptr->length;
6705 AllocatedBuffer buf = env->AllocateManaged(*size);
6706 memcpy(buf.data(), ptr->data, *size);
6707
6708 return buf;
6709 }
6710
6711
ExportPublicKey(const FunctionCallbackInfo<Value> & args)6712 void ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
6713 Environment* env = Environment::GetCurrent(args);
6714
6715 ArrayBufferViewContents<char> input(args[0]);
6716 if (input.length() == 0)
6717 return args.GetReturnValue().SetEmptyString();
6718
6719 CHECK_NOT_NULL(input.data());
6720
6721 size_t pkey_size;
6722 AllocatedBuffer pkey =
6723 ExportPublicKey(env, input.data(), input.length(), &pkey_size);
6724 if (pkey.data() == nullptr)
6725 return args.GetReturnValue().SetEmptyString();
6726
6727 args.GetReturnValue().Set(pkey.ToBuffer().ToLocalChecked());
6728 }
6729
6730
ExportChallenge(const char * data,int len)6731 OpenSSLBuffer ExportChallenge(const char* data, int len) {
6732 NetscapeSPKIPointer sp(NETSCAPE_SPKI_b64_decode(data, len));
6733 if (!sp)
6734 return nullptr;
6735
6736 unsigned char* buf = nullptr;
6737 ASN1_STRING_to_UTF8(&buf, sp->spkac->challenge);
6738
6739 return OpenSSLBuffer(reinterpret_cast<char*>(buf));
6740 }
6741
6742
ExportChallenge(const FunctionCallbackInfo<Value> & args)6743 void ExportChallenge(const FunctionCallbackInfo<Value>& args) {
6744 Environment* env = Environment::GetCurrent(args);
6745
6746 ArrayBufferViewContents<char> input(args[0]);
6747 if (input.length() == 0)
6748 return args.GetReturnValue().SetEmptyString();
6749
6750 OpenSSLBuffer cert = ExportChallenge(input.data(), input.length());
6751 if (!cert)
6752 return args.GetReturnValue().SetEmptyString();
6753
6754 Local<Value> outString =
6755 Encode(env->isolate(), cert.get(), strlen(cert.get()), BUFFER);
6756
6757 args.GetReturnValue().Set(outString);
6758 }
6759
6760
6761 // Convert the input public key to compressed, uncompressed, or hybrid formats.
ConvertKey(const FunctionCallbackInfo<Value> & args)6762 void ConvertKey(const FunctionCallbackInfo<Value>& args) {
6763 MarkPopErrorOnReturn mark_pop_error_on_return;
6764 Environment* env = Environment::GetCurrent(args);
6765
6766 CHECK_EQ(args.Length(), 3);
6767 CHECK(args[0]->IsArrayBufferView());
6768
6769 size_t len = args[0].As<ArrayBufferView>()->ByteLength();
6770 if (len == 0)
6771 return args.GetReturnValue().SetEmptyString();
6772
6773 node::Utf8Value curve(env->isolate(), args[1]);
6774
6775 int nid = OBJ_sn2nid(*curve);
6776 if (nid == NID_undef)
6777 return env->ThrowTypeError("Invalid ECDH curve name");
6778
6779 ECGroupPointer group(
6780 EC_GROUP_new_by_curve_name(nid));
6781 if (group == nullptr)
6782 return env->ThrowError("Failed to get EC_GROUP");
6783
6784 ECPointPointer pub(
6785 ECDH::BufferToPoint(env,
6786 group.get(),
6787 args[0]));
6788
6789 if (pub == nullptr)
6790 return env->ThrowError("Failed to convert Buffer to EC_POINT");
6791
6792 CHECK(args[2]->IsUint32());
6793 uint32_t val = args[2].As<Uint32>()->Value();
6794 point_conversion_form_t form = static_cast<point_conversion_form_t>(val);
6795
6796 const char* error;
6797 Local<Object> buf;
6798 if (!ECPointToBuffer(env, group.get(), pub.get(), form, &error).ToLocal(&buf))
6799 return env->ThrowError(error);
6800 args.GetReturnValue().Set(buf);
6801 }
6802
StatelessDiffieHellman(Environment * env,ManagedEVPPKey our_key,ManagedEVPPKey their_key)6803 AllocatedBuffer StatelessDiffieHellman(Environment* env, ManagedEVPPKey our_key,
6804 ManagedEVPPKey their_key) {
6805 size_t out_size;
6806
6807 EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(our_key.get(), nullptr));
6808 if (!ctx ||
6809 EVP_PKEY_derive_init(ctx.get()) <= 0 ||
6810 EVP_PKEY_derive_set_peer(ctx.get(), their_key.get()) <= 0 ||
6811 EVP_PKEY_derive(ctx.get(), nullptr, &out_size) <= 0)
6812 return AllocatedBuffer();
6813
6814 AllocatedBuffer result = env->AllocateManaged(out_size);
6815 CHECK_NOT_NULL(result.data());
6816
6817 unsigned char* data = reinterpret_cast<unsigned char*>(result.data());
6818 if (EVP_PKEY_derive(ctx.get(), data, &out_size) <= 0)
6819 return AllocatedBuffer();
6820
6821 ZeroPadDiffieHellmanSecret(out_size, &result);
6822 return result;
6823 }
6824
StatelessDiffieHellman(const FunctionCallbackInfo<Value> & args)6825 void StatelessDiffieHellman(const FunctionCallbackInfo<Value>& args) {
6826 Environment* env = Environment::GetCurrent(args);
6827
6828 CHECK(args[0]->IsObject() && args[1]->IsObject());
6829 KeyObjectHandle* our_key_object;
6830 ASSIGN_OR_RETURN_UNWRAP(&our_key_object, args[0].As<Object>());
6831 CHECK_EQ(our_key_object->Data()->GetKeyType(), kKeyTypePrivate);
6832 KeyObjectHandle* their_key_object;
6833 ASSIGN_OR_RETURN_UNWRAP(&their_key_object, args[1].As<Object>());
6834 CHECK_NE(their_key_object->Data()->GetKeyType(), kKeyTypeSecret);
6835
6836 ManagedEVPPKey our_key = our_key_object->Data()->GetAsymmetricKey();
6837 ManagedEVPPKey their_key = their_key_object->Data()->GetAsymmetricKey();
6838
6839 AllocatedBuffer out = StatelessDiffieHellman(env, our_key, their_key);
6840 if (out.size() == 0)
6841 return ThrowCryptoError(env, ERR_get_error(), "diffieHellman failed");
6842
6843 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
6844 }
6845
6846
TimingSafeEqual(const FunctionCallbackInfo<Value> & args)6847 void TimingSafeEqual(const FunctionCallbackInfo<Value>& args) {
6848 // Moving the type checking into JS leads to test failures, most likely due
6849 // to V8 inlining certain parts of the wrapper. Therefore, keep them in C++.
6850 // Refs: https://github.com/nodejs/node/issues/34073.
6851 Environment* env = Environment::GetCurrent(args);
6852 if (!args[0]->IsArrayBufferView()) {
6853 THROW_ERR_INVALID_ARG_TYPE(
6854 env, "The \"buf1\" argument must be an instance of "
6855 "Buffer, TypedArray, or DataView.");
6856 return;
6857 }
6858 if (!args[1]->IsArrayBufferView()) {
6859 THROW_ERR_INVALID_ARG_TYPE(
6860 env, "The \"buf2\" argument must be an instance of "
6861 "Buffer, TypedArray, or DataView.");
6862 return;
6863 }
6864
6865 ArrayBufferViewContents<char> buf1(args[0].As<ArrayBufferView>());
6866 ArrayBufferViewContents<char> buf2(args[1].As<ArrayBufferView>());
6867
6868 if (buf1.length() != buf2.length()) {
6869 THROW_ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH(env);
6870 return;
6871 }
6872
6873 return args.GetReturnValue().Set(
6874 CRYPTO_memcmp(buf1.data(), buf2.data(), buf1.length()) == 0);
6875 }
6876
InitCryptoOnce()6877 void InitCryptoOnce() {
6878 #ifndef OPENSSL_IS_BORINGSSL
6879 OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
6880
6881 // --openssl-config=...
6882 if (!per_process::cli_options->openssl_config.empty()) {
6883 const char* conf = per_process::cli_options->openssl_config.c_str();
6884 OPENSSL_INIT_set_config_filename(settings, conf);
6885 }
6886
6887 OPENSSL_init_ssl(0, settings);
6888 OPENSSL_INIT_free(settings);
6889 settings = nullptr;
6890 #endif
6891
6892 #ifdef NODE_FIPS_MODE
6893 /* Override FIPS settings in cnf file, if needed. */
6894 unsigned long err = 0; // NOLINT(runtime/int)
6895 if (per_process::cli_options->enable_fips_crypto ||
6896 per_process::cli_options->force_fips_crypto) {
6897 if (0 == FIPS_mode() && !FIPS_mode_set(1)) {
6898 err = ERR_get_error();
6899 }
6900 }
6901 if (0 != err) {
6902 fprintf(stderr,
6903 "openssl fips failed: %s\n",
6904 ERR_error_string(err, nullptr));
6905 UNREACHABLE();
6906 }
6907 #endif // NODE_FIPS_MODE
6908
6909
6910 // Turn off compression. Saves memory and protects against CRIME attacks.
6911 // No-op with OPENSSL_NO_COMP builds of OpenSSL.
6912 sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
6913
6914 #ifndef OPENSSL_NO_ENGINE
6915 ERR_load_ENGINE_strings();
6916 ENGINE_load_builtin_engines();
6917 #endif // !OPENSSL_NO_ENGINE
6918
6919 NodeBIO::GetMethod();
6920 }
6921
6922
6923 #ifndef OPENSSL_NO_ENGINE
SetEngine(const FunctionCallbackInfo<Value> & args)6924 void SetEngine(const FunctionCallbackInfo<Value>& args) {
6925 Environment* env = Environment::GetCurrent(args);
6926 CHECK(args.Length() >= 2 && args[0]->IsString());
6927 uint32_t flags;
6928 if (!args[1]->Uint32Value(env->context()).To(&flags)) return;
6929
6930 ClearErrorOnReturn clear_error_on_return;
6931
6932 // Load engine.
6933 const node::Utf8Value engine_id(env->isolate(), args[0]);
6934 char errmsg[1024];
6935 ENGINE* engine = LoadEngineById(*engine_id, &errmsg);
6936
6937 if (engine == nullptr) {
6938 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
6939 if (err == 0)
6940 return args.GetReturnValue().Set(false);
6941 return ThrowCryptoError(env, err);
6942 }
6943
6944 int r = ENGINE_set_default(engine, flags);
6945 ENGINE_free(engine);
6946 if (r == 0)
6947 return ThrowCryptoError(env, ERR_get_error());
6948
6949 args.GetReturnValue().Set(true);
6950 }
6951 #endif // !OPENSSL_NO_ENGINE
6952
6953 #ifdef NODE_FIPS_MODE
GetFipsCrypto(const FunctionCallbackInfo<Value> & args)6954 void GetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
6955 args.GetReturnValue().Set(FIPS_mode() ? 1 : 0);
6956 }
6957
SetFipsCrypto(const FunctionCallbackInfo<Value> & args)6958 void SetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
6959 CHECK(!per_process::cli_options->force_fips_crypto);
6960 Environment* env = Environment::GetCurrent(args);
6961 const bool enabled = FIPS_mode();
6962 bool enable = args[0]->BooleanValue(env->isolate());
6963
6964 if (enable == enabled)
6965 return; // No action needed.
6966 if (!FIPS_mode_set(enable)) {
6967 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
6968 return ThrowCryptoError(env, err);
6969 }
6970 }
6971 #endif /* NODE_FIPS_MODE */
6972
6973
Initialize(Local<Object> target,Local<Value> unused,Local<Context> context,void * priv)6974 void Initialize(Local<Object> target,
6975 Local<Value> unused,
6976 Local<Context> context,
6977 void* priv) {
6978 static uv_once_t init_once = UV_ONCE_INIT;
6979 uv_once(&init_once, InitCryptoOnce);
6980
6981 Environment* env = Environment::GetCurrent(context);
6982 SecureContext::Initialize(env, target);
6983 target->Set(env->context(),
6984 FIXED_ONE_BYTE_STRING(env->isolate(), "KeyObjectHandle"),
6985 KeyObjectHandle::Initialize(env)).Check();
6986 env->SetMethod(target, "createNativeKeyObjectClass",
6987 CreateNativeKeyObjectClass);
6988 CipherBase::Initialize(env, target);
6989 DiffieHellman::Initialize(env, target);
6990 ECDH::Initialize(env, target);
6991 Hmac::Initialize(env, target);
6992 Hash::Initialize(env, target);
6993 Sign::Initialize(env, target);
6994 Verify::Initialize(env, target);
6995
6996 env->SetMethodNoSideEffect(target, "certVerifySpkac", VerifySpkac);
6997 env->SetMethodNoSideEffect(target, "certExportPublicKey", ExportPublicKey);
6998 env->SetMethodNoSideEffect(target, "certExportChallenge", ExportChallenge);
6999 env->SetMethodNoSideEffect(target, "getRootCertificates",
7000 GetRootCertificates);
7001 // Exposed for testing purposes only.
7002 env->SetMethodNoSideEffect(target, "isExtraRootCertsFileLoaded",
7003 IsExtraRootCertsFileLoaded);
7004
7005 env->SetMethodNoSideEffect(target, "ECDHConvertKey", ConvertKey);
7006 #ifndef OPENSSL_NO_ENGINE
7007 env->SetMethod(target, "setEngine", SetEngine);
7008 #endif // !OPENSSL_NO_ENGINE
7009
7010 #ifdef NODE_FIPS_MODE
7011 env->SetMethodNoSideEffect(target, "getFipsCrypto", GetFipsCrypto);
7012 env->SetMethod(target, "setFipsCrypto", SetFipsCrypto);
7013 #endif
7014
7015 env->SetMethod(target, "pbkdf2", PBKDF2);
7016 env->SetMethod(target, "generateKeyPairRSA", GenerateKeyPairRSA);
7017 env->SetMethod(target, "generateKeyPairRSAPSS", GenerateKeyPairRSAPSS);
7018 env->SetMethod(target, "generateKeyPairDSA", GenerateKeyPairDSA);
7019 env->SetMethod(target, "generateKeyPairEC", GenerateKeyPairEC);
7020 env->SetMethod(target, "generateKeyPairNid", GenerateKeyPairNid);
7021 env->SetMethod(target, "generateKeyPairDH", GenerateKeyPairDH);
7022 NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED25519);
7023 NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED448);
7024 NODE_DEFINE_CONSTANT(target, EVP_PKEY_X25519);
7025 NODE_DEFINE_CONSTANT(target, EVP_PKEY_X448);
7026 NODE_DEFINE_CONSTANT(target, OPENSSL_EC_NAMED_CURVE);
7027 NODE_DEFINE_CONSTANT(target, OPENSSL_EC_EXPLICIT_CURVE);
7028 NODE_DEFINE_CONSTANT(target, kKeyEncodingPKCS1);
7029 NODE_DEFINE_CONSTANT(target, kKeyEncodingPKCS8);
7030 NODE_DEFINE_CONSTANT(target, kKeyEncodingSPKI);
7031 NODE_DEFINE_CONSTANT(target, kKeyEncodingSEC1);
7032 NODE_DEFINE_CONSTANT(target, kKeyFormatDER);
7033 NODE_DEFINE_CONSTANT(target, kKeyFormatPEM);
7034 NODE_DEFINE_CONSTANT(target, kKeyTypeSecret);
7035 NODE_DEFINE_CONSTANT(target, kKeyTypePublic);
7036 NODE_DEFINE_CONSTANT(target, kKeyTypePrivate);
7037 NODE_DEFINE_CONSTANT(target, kSigEncDER);
7038 NODE_DEFINE_CONSTANT(target, kSigEncP1363);
7039 env->SetMethodNoSideEffect(target, "statelessDH", StatelessDiffieHellman);
7040 env->SetMethod(target, "randomBytes", RandomBytes);
7041 env->SetMethod(target, "signOneShot", SignOneShot);
7042 env->SetMethod(target, "verifyOneShot", VerifyOneShot);
7043 env->SetMethodNoSideEffect(target, "timingSafeEqual", TimingSafeEqual);
7044 env->SetMethodNoSideEffect(target, "getSSLCiphers", GetSSLCiphers);
7045 env->SetMethodNoSideEffect(target, "getCiphers", GetCiphers);
7046 env->SetMethodNoSideEffect(target, "getHashes", GetHashes);
7047 env->SetMethodNoSideEffect(target, "getCurves", GetCurves);
7048 env->SetMethod(target, "publicEncrypt",
7049 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
7050 EVP_PKEY_encrypt_init,
7051 EVP_PKEY_encrypt>);
7052 env->SetMethod(target, "privateDecrypt",
7053 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
7054 EVP_PKEY_decrypt_init,
7055 EVP_PKEY_decrypt>);
7056 env->SetMethod(target, "privateEncrypt",
7057 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
7058 EVP_PKEY_sign_init,
7059 EVP_PKEY_sign>);
7060 env->SetMethod(target, "publicDecrypt",
7061 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
7062 EVP_PKEY_verify_recover_init,
7063 EVP_PKEY_verify_recover>);
7064 #ifndef OPENSSL_NO_SCRYPT
7065 env->SetMethod(target, "scrypt", Scrypt);
7066 #endif // OPENSSL_NO_SCRYPT
7067 }
7068
7069 } // namespace crypto
7070 } // namespace node
7071
7072 NODE_MODULE_CONTEXT_AWARE_INTERNAL(crypto, node::crypto::Initialize)
7073