• 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 #ifndef SRC_NODE_CRYPTO_H_
23 #define SRC_NODE_CRYPTO_H_
24 
25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26 
27 // ClientHelloParser
28 #include "node_crypto_clienthello.h"
29 
30 #include "allocated_buffer.h"
31 #include "env.h"
32 #include "base_object.h"
33 #include "util.h"
34 #include "node_messaging.h"
35 
36 #include "v8.h"
37 
38 #include <openssl/err.h>
39 #include <openssl/ssl.h>
40 #include <openssl/bn.h>
41 #include <openssl/dh.h>
42 #include <openssl/ec.h>
43 #include <openssl/rsa.h>
44 
45 namespace node {
46 namespace crypto {
47 
48 // Forcibly clear OpenSSL's error stack on return. This stops stale errors
49 // from popping up later in the lifecycle of crypto operations where they
50 // would cause spurious failures. It's a rather blunt method, though.
51 // ERR_clear_error() isn't necessarily cheap either.
52 struct ClearErrorOnReturn {
~ClearErrorOnReturnClearErrorOnReturn53   ~ClearErrorOnReturn() { ERR_clear_error(); }
54 };
55 
56 // Pop errors from OpenSSL's error stack that were added
57 // between when this was constructed and destructed.
58 struct MarkPopErrorOnReturn {
MarkPopErrorOnReturnMarkPopErrorOnReturn59   MarkPopErrorOnReturn() { ERR_set_mark(); }
~MarkPopErrorOnReturnMarkPopErrorOnReturn60   ~MarkPopErrorOnReturn() { ERR_pop_to_mark(); }
61 };
62 
63 // Define smart pointers for the most commonly used OpenSSL types:
64 using X509Pointer = DeleteFnPtr<X509, X509_free>;
65 using BIOPointer = DeleteFnPtr<BIO, BIO_free_all>;
66 using SSLCtxPointer = DeleteFnPtr<SSL_CTX, SSL_CTX_free>;
67 using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>;
68 using SSLPointer = DeleteFnPtr<SSL, SSL_free>;
69 using PKCS8Pointer = DeleteFnPtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>;
70 using EVPKeyPointer = DeleteFnPtr<EVP_PKEY, EVP_PKEY_free>;
71 using EVPKeyCtxPointer = DeleteFnPtr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
72 using EVPMDPointer = DeleteFnPtr<EVP_MD_CTX, EVP_MD_CTX_free>;
73 using RSAPointer = DeleteFnPtr<RSA, RSA_free>;
74 using ECPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>;
75 using BignumPointer = DeleteFnPtr<BIGNUM, BN_free>;
76 using NetscapeSPKIPointer = DeleteFnPtr<NETSCAPE_SPKI, NETSCAPE_SPKI_free>;
77 using ECGroupPointer = DeleteFnPtr<EC_GROUP, EC_GROUP_free>;
78 using ECPointPointer = DeleteFnPtr<EC_POINT, EC_POINT_free>;
79 using ECKeyPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>;
80 using DHPointer = DeleteFnPtr<DH, DH_free>;
81 using ECDSASigPointer = DeleteFnPtr<ECDSA_SIG, ECDSA_SIG_free>;
82 
83 extern int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx);
84 
85 extern void UseExtraCaCerts(const std::string& file);
86 
87 void InitCryptoOnce();
88 
89 class SecureContext final : public BaseObject {
90  public:
91   ~SecureContext() override;
92 
93   static void Initialize(Environment* env, v8::Local<v8::Object> target);
94 
95   SSL_CTX* operator*() const { return ctx_.get(); }
96 
97   // TODO(joyeecheung): track the memory used by OpenSSL types
98   SET_NO_MEMORY_INFO()
99   SET_MEMORY_INFO_NAME(SecureContext)
100   SET_SELF_SIZE(SecureContext)
101 
102   SSLCtxPointer ctx_;
103   X509Pointer cert_;
104   X509Pointer issuer_;
105 #ifndef OPENSSL_NO_ENGINE
106   bool client_cert_engine_provided_ = false;
107   std::unique_ptr<ENGINE, std::function<void(ENGINE*)>> private_key_engine_;
108 #endif  // !OPENSSL_NO_ENGINE
109 
110   static const int kMaxSessionSize = 10 * 1024;
111 
112   // See TicketKeyCallback
113   static const int kTicketKeyReturnIndex = 0;
114   static const int kTicketKeyHMACIndex = 1;
115   static const int kTicketKeyAESIndex = 2;
116   static const int kTicketKeyNameIndex = 3;
117   static const int kTicketKeyIVIndex = 4;
118 
119   unsigned char ticket_key_name_[16];
120   unsigned char ticket_key_aes_[16];
121   unsigned char ticket_key_hmac_[16];
122 
123  protected:
124   // OpenSSL structures are opaque. This is sizeof(SSL_CTX) for OpenSSL 1.1.1b:
125   static const int64_t kExternalSize = 1024;
126 
127   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
128   static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
129   static void SetKey(const v8::FunctionCallbackInfo<v8::Value>& args);
130 #ifndef OPENSSL_NO_ENGINE
131   static void SetEngineKey(const v8::FunctionCallbackInfo<v8::Value>& args);
132 #endif  // !OPENSSL_NO_ENGINE
133   static void SetCert(const v8::FunctionCallbackInfo<v8::Value>& args);
134   static void AddCACert(const v8::FunctionCallbackInfo<v8::Value>& args);
135   static void AddCRL(const v8::FunctionCallbackInfo<v8::Value>& args);
136   static void AddRootCerts(const v8::FunctionCallbackInfo<v8::Value>& args);
137   static void SetCipherSuites(const v8::FunctionCallbackInfo<v8::Value>& args);
138   static void SetCiphers(const v8::FunctionCallbackInfo<v8::Value>& args);
139   static void SetSigalgs(const v8::FunctionCallbackInfo<v8::Value>& args);
140   static void SetECDHCurve(const v8::FunctionCallbackInfo<v8::Value>& args);
141   static void SetDHParam(const v8::FunctionCallbackInfo<v8::Value>& args);
142   static void SetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
143   static void SetSessionIdContext(
144       const v8::FunctionCallbackInfo<v8::Value>& args);
145   static void SetSessionTimeout(
146       const v8::FunctionCallbackInfo<v8::Value>& args);
147   static void SetMinProto(const v8::FunctionCallbackInfo<v8::Value>& args);
148   static void SetMaxProto(const v8::FunctionCallbackInfo<v8::Value>& args);
149   static void GetMinProto(const v8::FunctionCallbackInfo<v8::Value>& args);
150   static void GetMaxProto(const v8::FunctionCallbackInfo<v8::Value>& args);
151   static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
152   static void LoadPKCS12(const v8::FunctionCallbackInfo<v8::Value>& args);
153 #ifndef OPENSSL_NO_ENGINE
154   static void SetClientCertEngine(
155       const v8::FunctionCallbackInfo<v8::Value>& args);
156 #endif  // !OPENSSL_NO_ENGINE
157   static void GetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
158   static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
159   static void SetFreeListLength(
160       const v8::FunctionCallbackInfo<v8::Value>& args);
161   static void EnableTicketKeyCallback(
162       const v8::FunctionCallbackInfo<v8::Value>& args);
163   static void CtxGetter(const v8::FunctionCallbackInfo<v8::Value>& info);
164 
165   template <bool primary>
166   static void GetCertificate(const v8::FunctionCallbackInfo<v8::Value>& args);
167 
168   static int TicketKeyCallback(SSL* ssl,
169                                unsigned char* name,
170                                unsigned char* iv,
171                                EVP_CIPHER_CTX* ectx,
172                                HMAC_CTX* hctx,
173                                int enc);
174 
175   static int TicketCompatibilityCallback(SSL* ssl,
176                                          unsigned char* name,
177                                          unsigned char* iv,
178                                          EVP_CIPHER_CTX* ectx,
179                                          HMAC_CTX* hctx,
180                                          int enc);
181 
182   SecureContext(Environment* env, v8::Local<v8::Object> wrap);
183   void Reset();
184 };
185 
186 // SSLWrap implicitly depends on the inheriting class' handle having an
187 // internal pointer to the Base class.
188 template <class Base>
189 class SSLWrap {
190  public:
191   enum Kind {
192     kClient,
193     kServer
194   };
195 
SSLWrap(Environment * env,SecureContext * sc,Kind kind)196   SSLWrap(Environment* env, SecureContext* sc, Kind kind)
197       : env_(env),
198         kind_(kind),
199         next_sess_(nullptr),
200         session_callbacks_(false),
201         awaiting_new_session_(false),
202         cert_cb_(nullptr),
203         cert_cb_arg_(nullptr),
204         cert_cb_running_(false) {
205     ssl_.reset(SSL_new(sc->ctx_.get()));
206     CHECK(ssl_);
207     env_->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
208   }
209 
~SSLWrap()210   virtual ~SSLWrap() {
211     DestroySSL();
212   }
213 
enable_session_callbacks()214   inline void enable_session_callbacks() { session_callbacks_ = true; }
is_server()215   inline bool is_server() const { return kind_ == kServer; }
is_client()216   inline bool is_client() const { return kind_ == kClient; }
is_awaiting_new_session()217   inline bool is_awaiting_new_session() const { return awaiting_new_session_; }
is_waiting_cert_cb()218   inline bool is_waiting_cert_cb() const { return cert_cb_ != nullptr; }
219 
220   void MemoryInfo(MemoryTracker* tracker) const;
221 
222  protected:
223   typedef void (*CertCb)(void* arg);
224 
225   // OpenSSL structures are opaque. Estimate SSL memory size for OpenSSL 1.1.1b:
226   //   SSL: 6224
227   //   SSL->SSL3_STATE: 1040
228   //   ...some buffers: 42 * 1024
229   // NOTE: Actually it is much more than this
230   static const int64_t kExternalSize = 6224 + 1040 + 42 * 1024;
231 
232   static void ConfigureSecureContext(SecureContext* sc);
233   static void AddMethods(Environment* env, v8::Local<v8::FunctionTemplate> t);
234 
235   static SSL_SESSION* GetSessionCallback(SSL* s,
236                                          const unsigned char* key,
237                                          int len,
238                                          int* copy);
239   static int NewSessionCallback(SSL* s, SSL_SESSION* sess);
240   static void KeylogCallback(const SSL* s, const char* line);
241   static void OnClientHello(void* arg,
242                             const ClientHelloParser::ClientHello& hello);
243 
244   static void GetPeerCertificate(
245       const v8::FunctionCallbackInfo<v8::Value>& args);
246   static void GetCertificate(const v8::FunctionCallbackInfo<v8::Value>& args);
247   static void GetFinished(const v8::FunctionCallbackInfo<v8::Value>& args);
248   static void GetPeerFinished(const v8::FunctionCallbackInfo<v8::Value>& args);
249   static void GetSession(const v8::FunctionCallbackInfo<v8::Value>& args);
250   static void SetSession(const v8::FunctionCallbackInfo<v8::Value>& args);
251   static void LoadSession(const v8::FunctionCallbackInfo<v8::Value>& args);
252   static void IsSessionReused(const v8::FunctionCallbackInfo<v8::Value>& args);
253   static void VerifyError(const v8::FunctionCallbackInfo<v8::Value>& args);
254   static void GetCipher(const v8::FunctionCallbackInfo<v8::Value>& args);
255   static void GetSharedSigalgs(const v8::FunctionCallbackInfo<v8::Value>& args);
256   static void ExportKeyingMaterial(
257       const v8::FunctionCallbackInfo<v8::Value>& args);
258   static void EndParser(const v8::FunctionCallbackInfo<v8::Value>& args);
259   static void CertCbDone(const v8::FunctionCallbackInfo<v8::Value>& args);
260   static void Renegotiate(const v8::FunctionCallbackInfo<v8::Value>& args);
261   static void GetTLSTicket(const v8::FunctionCallbackInfo<v8::Value>& args);
262   static void NewSessionDone(const v8::FunctionCallbackInfo<v8::Value>& args);
263   static void SetOCSPResponse(const v8::FunctionCallbackInfo<v8::Value>& args);
264   static void RequestOCSP(const v8::FunctionCallbackInfo<v8::Value>& args);
265   static void GetEphemeralKeyInfo(
266       const v8::FunctionCallbackInfo<v8::Value>& args);
267   static void GetProtocol(const v8::FunctionCallbackInfo<v8::Value>& args);
268 
269 #ifdef SSL_set_max_send_fragment
270   static void SetMaxSendFragment(
271       const v8::FunctionCallbackInfo<v8::Value>& args);
272 #endif  // SSL_set_max_send_fragment
273 
274   static void GetALPNNegotiatedProto(
275       const v8::FunctionCallbackInfo<v8::Value>& args);
276   static void SetALPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args);
277   static int SelectALPNCallback(SSL* s,
278                                 const unsigned char** out,
279                                 unsigned char* outlen,
280                                 const unsigned char* in,
281                                 unsigned int inlen,
282                                 void* arg);
283   static int TLSExtStatusCallback(SSL* s, void* arg);
284   static int SSLCertCallback(SSL* s, void* arg);
285 
286   void DestroySSL();
287   void WaitForCertCb(CertCb cb, void* arg);
288   int SetCACerts(SecureContext* sc);
289 
ssl_env()290   inline Environment* ssl_env() const {
291     return env_;
292   }
293 
294   Environment* const env_;
295   Kind kind_;
296   SSLSessionPointer next_sess_;
297   SSLPointer ssl_;
298   bool session_callbacks_;
299   bool awaiting_new_session_;
300 
301   // SSL_set_cert_cb
302   CertCb cert_cb_;
303   void* cert_cb_arg_;
304   bool cert_cb_running_;
305 
306   ClientHelloParser hello_parser_;
307 
308   v8::Global<v8::ArrayBufferView> ocsp_response_;
309   BaseObjectPtr<SecureContext> sni_context_;
310 
311   friend class SecureContext;
312 };
313 
314 // A helper class representing a read-only byte array. When deallocated, its
315 // contents are zeroed.
316 class ByteSource {
317  public:
318   ByteSource() = default;
319   ByteSource(ByteSource&& other);
320   ~ByteSource();
321 
322   ByteSource& operator=(ByteSource&& other);
323 
324   const char* get() const;
325   size_t size() const;
326 
327   inline operator bool() const {
328     return data_ != nullptr;
329   }
330 
331   static ByteSource Allocated(char* data, size_t size);
332   static ByteSource Foreign(const char* data, size_t size);
333 
334   static ByteSource FromStringOrBuffer(Environment* env,
335                                        v8::Local<v8::Value> value);
336 
337   static ByteSource FromString(Environment* env,
338                                v8::Local<v8::String> str,
339                                bool ntc = false);
340 
341   static ByteSource FromBuffer(v8::Local<v8::Value> buffer,
342                                bool ntc = false);
343 
344   static ByteSource NullTerminatedCopy(Environment* env,
345                                        v8::Local<v8::Value> value);
346 
347   static ByteSource FromSymmetricKeyObjectHandle(v8::Local<v8::Value> handle);
348 
349   ByteSource(const ByteSource&) = delete;
350   ByteSource& operator=(const ByteSource&) = delete;
351 
352  private:
353   const char* data_ = nullptr;
354   char* allocated_data_ = nullptr;
355   size_t size_ = 0;
356 
357   ByteSource(const char* data, char* allocated_data, size_t size);
358 };
359 
360 enum PKEncodingType {
361   // RSAPublicKey / RSAPrivateKey according to PKCS#1.
362   kKeyEncodingPKCS1,
363   // PrivateKeyInfo or EncryptedPrivateKeyInfo according to PKCS#8.
364   kKeyEncodingPKCS8,
365   // SubjectPublicKeyInfo according to X.509.
366   kKeyEncodingSPKI,
367   // ECPrivateKey according to SEC1.
368   kKeyEncodingSEC1
369 };
370 
371 enum PKFormatType {
372   kKeyFormatDER,
373   kKeyFormatPEM
374 };
375 
376 struct AsymmetricKeyEncodingConfig {
377   bool output_key_object_;
378   PKFormatType format_;
379   v8::Maybe<PKEncodingType> type_ = v8::Nothing<PKEncodingType>();
380 };
381 
382 typedef AsymmetricKeyEncodingConfig PublicKeyEncodingConfig;
383 
384 struct PrivateKeyEncodingConfig : public AsymmetricKeyEncodingConfig {
385   const EVP_CIPHER* cipher_;
386   ByteSource passphrase_;
387 };
388 
389 enum KeyType {
390   kKeyTypeSecret,
391   kKeyTypePublic,
392   kKeyTypePrivate
393 };
394 
395 // This uses the built-in reference counter of OpenSSL to manage an EVP_PKEY
396 // which is slightly more efficient than using a shared pointer and easier to
397 // use.
398 class ManagedEVPPKey {
399  public:
400   ManagedEVPPKey() = default;
401   explicit ManagedEVPPKey(EVPKeyPointer&& pkey);
402   ManagedEVPPKey(const ManagedEVPPKey& that);
403   ManagedEVPPKey& operator=(const ManagedEVPPKey& that);
404 
405   operator bool() const;
406   EVP_PKEY* get() const;
407 
408  private:
409   EVPKeyPointer pkey_;
410 };
411 
412 // Objects of this class can safely be shared among threads.
413 class KeyObjectData {
414  public:
415   static std::shared_ptr<KeyObjectData> CreateSecret(
416       v8::Local<v8::ArrayBufferView> abv);
417   static std::shared_ptr<KeyObjectData> CreateAsymmetric(
418       KeyType type, const ManagedEVPPKey& pkey);
419 
420   KeyType GetKeyType() const;
421 
422   // These functions allow unprotected access to the raw key material and should
423   // only be used to implement cryptographic operations requiring the key.
424   ManagedEVPPKey GetAsymmetricKey() const;
425   const char* GetSymmetricKey() const;
426   size_t GetSymmetricKeySize() const;
427 
428  private:
KeyObjectData(std::unique_ptr<char,std::function<void (char *)>> symmetric_key,unsigned int symmetric_key_len)429   KeyObjectData(std::unique_ptr<char, std::function<void(char*)>> symmetric_key,
430                 unsigned int symmetric_key_len)
431       : key_type_(KeyType::kKeyTypeSecret),
432         symmetric_key_(std::move(symmetric_key)),
433         symmetric_key_len_(symmetric_key_len),
434         asymmetric_key_() {}
435 
KeyObjectData(KeyType type,const ManagedEVPPKey & pkey)436   KeyObjectData(KeyType type, const ManagedEVPPKey& pkey)
437       : key_type_(type),
438         symmetric_key_(),
439         symmetric_key_len_(0),
440         asymmetric_key_{pkey} {}
441 
442   const KeyType key_type_;
443   const std::unique_ptr<char, std::function<void(char*)>> symmetric_key_;
444   const unsigned int symmetric_key_len_;
445   const ManagedEVPPKey asymmetric_key_;
446 };
447 
448 class KeyObjectHandle : public BaseObject {
449  public:
450   static v8::Local<v8::Function> Initialize(Environment* env);
451 
452   static v8::MaybeLocal<v8::Object> Create(Environment* env,
453                                            std::shared_ptr<KeyObjectData> data);
454 
455   // TODO(tniessen): track the memory used by OpenSSL types
456   SET_NO_MEMORY_INFO()
457   SET_MEMORY_INFO_NAME(KeyObjectHandle)
458   SET_SELF_SIZE(KeyObjectHandle)
459 
460   const std::shared_ptr<KeyObjectData>& Data();
461 
462  protected:
463   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
464 
465   static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
466 
467   static void GetAsymmetricKeyType(
468       const v8::FunctionCallbackInfo<v8::Value>& args);
469   v8::Local<v8::Value> GetAsymmetricKeyType() const;
470 
471   static void GetSymmetricKeySize(
472       const v8::FunctionCallbackInfo<v8::Value>& args);
473 
474   static void Export(const v8::FunctionCallbackInfo<v8::Value>& args);
475   v8::Local<v8::Value> ExportSecretKey() const;
476   v8::MaybeLocal<v8::Value> ExportPublicKey(
477       const PublicKeyEncodingConfig& config) const;
478   v8::MaybeLocal<v8::Value> ExportPrivateKey(
479       const PrivateKeyEncodingConfig& config) const;
480 
481   KeyObjectHandle(Environment* env,
482                   v8::Local<v8::Object> wrap);
483 
484  private:
485   std::shared_ptr<KeyObjectData> data_;
486 };
487 
488 class NativeKeyObject : public BaseObject {
489  public:
490   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
491 
492   SET_NO_MEMORY_INFO()
SET_MEMORY_INFO_NAME(NativeKeyObject)493   SET_MEMORY_INFO_NAME(NativeKeyObject)
494   SET_SELF_SIZE(NativeKeyObject)
495 
496   class KeyObjectTransferData : public worker::TransferData {
497    public:
498     explicit KeyObjectTransferData(const std::shared_ptr<KeyObjectData>& data)
499         : data_(data) {}
500 
501     BaseObjectPtr<BaseObject> Deserialize(
502         Environment* env,
503         v8::Local<v8::Context> context,
504         std::unique_ptr<worker::TransferData> self) override;
505 
506     SET_MEMORY_INFO_NAME(KeyObjectTransferData)
507     SET_SELF_SIZE(KeyObjectTransferData)
508     SET_NO_MEMORY_INFO()
509 
510    private:
511     std::shared_ptr<KeyObjectData> data_;
512   };
513 
514   BaseObject::TransferMode GetTransferMode() const override;
515   std::unique_ptr<worker::TransferData> CloneForMessaging() const override;
516 
517  private:
NativeKeyObject(Environment * env,v8::Local<v8::Object> wrap,const std::shared_ptr<KeyObjectData> & handle_data)518   NativeKeyObject(Environment* env,
519                   v8::Local<v8::Object> wrap,
520                   const std::shared_ptr<KeyObjectData>& handle_data)
521     : BaseObject(env, wrap),
522       handle_data_(handle_data) {
523     MakeWeak();
524   }
525 
526   std::shared_ptr<KeyObjectData> handle_data_;
527 };
528 
529 class CipherBase : public BaseObject {
530  public:
531   static void Initialize(Environment* env, v8::Local<v8::Object> target);
532 
533   // TODO(joyeecheung): track the memory used by OpenSSL types
534   SET_NO_MEMORY_INFO()
535   SET_MEMORY_INFO_NAME(CipherBase)
536   SET_SELF_SIZE(CipherBase)
537 
538  protected:
539   enum CipherKind {
540     kCipher,
541     kDecipher
542   };
543   enum UpdateResult {
544     kSuccess,
545     kErrorMessageSize,
546     kErrorState
547   };
548   enum AuthTagState {
549     kAuthTagUnknown,
550     kAuthTagKnown,
551     kAuthTagPassedToOpenSSL
552   };
553   static const unsigned kNoAuthTagLength = static_cast<unsigned>(-1);
554 
555   void CommonInit(const char* cipher_type,
556                   const EVP_CIPHER* cipher,
557                   const unsigned char* key,
558                   int key_len,
559                   const unsigned char* iv,
560                   int iv_len,
561                   unsigned int auth_tag_len);
562   void Init(const char* cipher_type,
563             const char* key_buf,
564             int key_buf_len,
565             unsigned int auth_tag_len);
566   void InitIv(const char* cipher_type,
567               const unsigned char* key,
568               int key_len,
569               const unsigned char* iv,
570               int iv_len,
571               unsigned int auth_tag_len);
572   bool InitAuthenticated(const char* cipher_type, int iv_len,
573                          unsigned int auth_tag_len);
574   bool CheckCCMMessageLength(int message_len);
575   UpdateResult Update(const char* data, int len, AllocatedBuffer* out);
576   bool Final(AllocatedBuffer* out);
577   bool SetAutoPadding(bool auto_padding);
578 
579   bool IsAuthenticatedMode() const;
580   bool SetAAD(const char* data, unsigned int len, int plaintext_len);
581   bool MaybePassAuthTagToOpenSSL();
582 
583   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
584   static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
585   static void InitIv(const v8::FunctionCallbackInfo<v8::Value>& args);
586   static void Update(const v8::FunctionCallbackInfo<v8::Value>& args);
587   static void Final(const v8::FunctionCallbackInfo<v8::Value>& args);
588   static void SetAutoPadding(const v8::FunctionCallbackInfo<v8::Value>& args);
589 
590   static void GetAuthTag(const v8::FunctionCallbackInfo<v8::Value>& args);
591   static void SetAuthTag(const v8::FunctionCallbackInfo<v8::Value>& args);
592   static void SetAAD(const v8::FunctionCallbackInfo<v8::Value>& args);
593 
594   CipherBase(Environment* env, v8::Local<v8::Object> wrap, CipherKind kind);
595 
596  private:
597   DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> ctx_;
598   const CipherKind kind_;
599   AuthTagState auth_tag_state_;
600   unsigned int auth_tag_len_;
601   char auth_tag_[EVP_GCM_TLS_TAG_LEN];
602   bool pending_auth_failed_;
603   int max_message_size_;
604 };
605 
606 class Hmac : public BaseObject {
607  public:
608   static void Initialize(Environment* env, v8::Local<v8::Object> target);
609 
610   // TODO(joyeecheung): track the memory used by OpenSSL types
611   SET_NO_MEMORY_INFO()
612   SET_MEMORY_INFO_NAME(Hmac)
613   SET_SELF_SIZE(Hmac)
614 
615  protected:
616   void HmacInit(const char* hash_type, const char* key, int key_len);
617   bool HmacUpdate(const char* data, int len);
618 
619   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
620   static void HmacInit(const v8::FunctionCallbackInfo<v8::Value>& args);
621   static void HmacUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
622   static void HmacDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
623 
624   Hmac(Environment* env, v8::Local<v8::Object> wrap);
625 
626  private:
627   DeleteFnPtr<HMAC_CTX, HMAC_CTX_free> ctx_;
628 };
629 
630 class Hash final : public BaseObject {
631  public:
632   ~Hash() override;
633 
634   static void Initialize(Environment* env, v8::Local<v8::Object> target);
635 
636   // TODO(joyeecheung): track the memory used by OpenSSL types
637   SET_NO_MEMORY_INFO()
638   SET_MEMORY_INFO_NAME(Hash)
639   SET_SELF_SIZE(Hash)
640 
641   bool HashInit(const EVP_MD* md, v8::Maybe<unsigned int> xof_md_len);
642   bool HashUpdate(const char* data, int len);
643 
644  protected:
645   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
646   static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
647   static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
648 
649   Hash(Environment* env, v8::Local<v8::Object> wrap);
650 
651  private:
652   EVPMDPointer mdctx_;
653   bool has_md_;
654   unsigned int md_len_;
655   unsigned char* md_value_;
656 };
657 
658 class SignBase : public BaseObject {
659  public:
660   typedef enum {
661     kSignOk,
662     kSignUnknownDigest,
663     kSignInit,
664     kSignNotInitialised,
665     kSignUpdate,
666     kSignPrivateKey,
667     kSignPublicKey,
668     kSignMalformedSignature
669   } Error;
670 
671   SignBase(Environment* env, v8::Local<v8::Object> wrap);
672 
673   Error Init(const char* sign_type);
674   Error Update(const char* data, int len);
675 
676   // TODO(joyeecheung): track the memory used by OpenSSL types
677   SET_NO_MEMORY_INFO()
678   SET_MEMORY_INFO_NAME(SignBase)
679   SET_SELF_SIZE(SignBase)
680 
681  protected:
682   void CheckThrow(Error error);
683 
684   EVPMDPointer mdctx_;
685 };
686 
687 enum DSASigEnc {
688   kSigEncDER, kSigEncP1363
689 };
690 
691 class Sign : public SignBase {
692  public:
693   static void Initialize(Environment* env, v8::Local<v8::Object> target);
694 
695   struct SignResult {
696     Error error;
697     AllocatedBuffer signature;
698 
699     explicit SignResult(
700         Error err,
701         AllocatedBuffer&& sig = AllocatedBuffer())
errorSignResult702       : error(err), signature(std::move(sig)) {}
703   };
704 
705   SignResult SignFinal(
706       const ManagedEVPPKey& pkey,
707       int padding,
708       const v8::Maybe<int>& saltlen,
709       DSASigEnc dsa_sig_enc);
710 
711  protected:
712   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
713   static void SignInit(const v8::FunctionCallbackInfo<v8::Value>& args);
714   static void SignUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
715   static void SignFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
716 
717   Sign(Environment* env, v8::Local<v8::Object> wrap);
718 };
719 
720 class Verify : public SignBase {
721  public:
722   static void Initialize(Environment* env, v8::Local<v8::Object> target);
723 
724   Error VerifyFinal(const ManagedEVPPKey& key,
725                     const ByteSource& sig,
726                     int padding,
727                     const v8::Maybe<int>& saltlen,
728                     bool* verify_result);
729 
730  protected:
731   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
732   static void VerifyInit(const v8::FunctionCallbackInfo<v8::Value>& args);
733   static void VerifyUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
734   static void VerifyFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
735 
736   Verify(Environment* env, v8::Local<v8::Object> wrap);
737 };
738 
739 class PublicKeyCipher {
740  public:
741   typedef int (*EVP_PKEY_cipher_init_t)(EVP_PKEY_CTX* ctx);
742   typedef int (*EVP_PKEY_cipher_t)(EVP_PKEY_CTX* ctx,
743                                    unsigned char* out, size_t* outlen,
744                                    const unsigned char* in, size_t inlen);
745 
746   enum Operation {
747     kPublic,
748     kPrivate
749   };
750 
751   template <Operation operation,
752             EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
753             EVP_PKEY_cipher_t EVP_PKEY_cipher>
754   static bool Cipher(Environment* env,
755                      const ManagedEVPPKey& pkey,
756                      int padding,
757                      const EVP_MD* digest,
758                      const void* oaep_label,
759                      size_t oaep_label_size,
760                      const unsigned char* data,
761                      int len,
762                      AllocatedBuffer* out);
763 
764   template <Operation operation,
765             EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
766             EVP_PKEY_cipher_t EVP_PKEY_cipher>
767   static void Cipher(const v8::FunctionCallbackInfo<v8::Value>& args);
768 };
769 
770 class DiffieHellman : public BaseObject {
771  public:
772   static void Initialize(Environment* env, v8::Local<v8::Object> target);
773 
774   bool Init(int primeLength, int g);
775   bool Init(const char* p, int p_len, int g);
776   bool Init(const char* p, int p_len, const char* g, int g_len);
777 
778  protected:
779   static void DiffieHellmanGroup(
780       const v8::FunctionCallbackInfo<v8::Value>& args);
781   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
782   static void GenerateKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
783   static void GetPrime(const v8::FunctionCallbackInfo<v8::Value>& args);
784   static void GetGenerator(const v8::FunctionCallbackInfo<v8::Value>& args);
785   static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
786   static void GetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
787   static void ComputeSecret(const v8::FunctionCallbackInfo<v8::Value>& args);
788   static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
789   static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
790   static void VerifyErrorGetter(
791       const v8::FunctionCallbackInfo<v8::Value>& args);
792 
793   DiffieHellman(Environment* env, v8::Local<v8::Object> wrap);
794 
795   // TODO(joyeecheung): track the memory used by OpenSSL types
796   SET_NO_MEMORY_INFO()
797   SET_MEMORY_INFO_NAME(DiffieHellman)
798   SET_SELF_SIZE(DiffieHellman)
799 
800  private:
801   static void GetField(const v8::FunctionCallbackInfo<v8::Value>& args,
802                        const BIGNUM* (*get_field)(const DH*),
803                        const char* err_if_null);
804   static void SetKey(const v8::FunctionCallbackInfo<v8::Value>& args,
805                      int (*set_field)(DH*, BIGNUM*), const char* what);
806   bool VerifyContext();
807 
808   int verifyError_;
809   DHPointer dh_;
810 };
811 
812 class ECDH final : public BaseObject {
813  public:
814   ~ECDH() override;
815 
816   static void Initialize(Environment* env, v8::Local<v8::Object> target);
817   static ECPointPointer BufferToPoint(Environment* env,
818                                       const EC_GROUP* group,
819                                       v8::Local<v8::Value> buf);
820 
821   // TODO(joyeecheung): track the memory used by OpenSSL types
822   SET_NO_MEMORY_INFO()
823   SET_MEMORY_INFO_NAME(ECDH)
824   SET_SELF_SIZE(ECDH)
825 
826  protected:
827   ECDH(Environment* env, v8::Local<v8::Object> wrap, ECKeyPointer&& key);
828 
829   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
830   static void GenerateKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
831   static void ComputeSecret(const v8::FunctionCallbackInfo<v8::Value>& args);
832   static void GetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
833   static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
834   static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
835   static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
836 
837   bool IsKeyPairValid();
838   bool IsKeyValidForCurve(const BignumPointer& private_key);
839 
840   ECKeyPointer key_;
841   const EC_GROUP* group_;
842 };
843 
844 bool EntropySource(unsigned char* buffer, size_t length);
845 #ifndef OPENSSL_NO_ENGINE
846 void SetEngine(const v8::FunctionCallbackInfo<v8::Value>& args);
847 #endif  // !OPENSSL_NO_ENGINE
848 void InitCrypto(v8::Local<v8::Object> target);
849 
850 void ThrowCryptoError(Environment* env,
851                       unsigned long err,  // NOLINT(runtime/int)
852                       const char* message = nullptr);
853 
854 template <typename T>
MallocOpenSSL(size_t count)855 inline T* MallocOpenSSL(size_t count) {
856   void* mem = OPENSSL_malloc(MultiplyWithOverflowCheck(count, sizeof(T)));
857   CHECK_IMPLIES(mem == nullptr, count == 0);
858   return static_cast<T*>(mem);
859 }
860 
861 }  // namespace crypto
862 }  // namespace node
863 
864 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
865 
866 #endif  // SRC_NODE_CRYPTO_H_
867