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