• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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