src: deduplicate CHECK_EQ/CHECK_NE macros
[platform/upstream/nodejs.git] / src / node_crypto.h
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 #include "node.h"
26 #include "node_crypto_clienthello.h"  // ClientHelloParser
27 #include "node_crypto_clienthello-inl.h"
28
29 #ifdef OPENSSL_NPN_NEGOTIATED
30 #include "node_buffer.h"
31 #endif
32
33 #include "env.h"
34 #include "async-wrap.h"
35 #include "async-wrap-inl.h"
36 #include "base-object.h"
37 #include "base-object-inl.h"
38
39 #include "v8.h"
40
41 #include <openssl/ssl.h>
42 #ifndef OPENSSL_NO_ENGINE
43 # include <openssl/engine.h>
44 #endif  // !OPENSSL_NO_ENGINE
45 #include <openssl/err.h>
46 #include <openssl/evp.h>
47 #include <openssl/pem.h>
48 #include <openssl/x509.h>
49 #include <openssl/x509v3.h>
50 #include <openssl/hmac.h>
51 #include <openssl/rand.h>
52 #include <openssl/pkcs12.h>
53
54 #define EVP_F_EVP_DECRYPTFINAL 101
55
56
57 namespace node {
58 namespace crypto {
59
60 extern int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx);
61
62 extern X509_STORE* root_cert_store;
63
64 // Forward declaration
65 class Connection;
66
67 class SecureContext : public BaseObject {
68  public:
69   ~SecureContext() {
70     FreeCTXMem();
71   }
72
73   static void Initialize(Environment* env, v8::Handle<v8::Object> target);
74
75   X509_STORE* ca_store_;
76   SSL_CTX* ctx_;
77
78   static const int kMaxSessionSize = 10 * 1024;
79
80  protected:
81
82   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
83   static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
84   static void SetKey(const v8::FunctionCallbackInfo<v8::Value>& args);
85   static void SetCert(const v8::FunctionCallbackInfo<v8::Value>& args);
86   static void AddCACert(const v8::FunctionCallbackInfo<v8::Value>& args);
87   static void AddCRL(const v8::FunctionCallbackInfo<v8::Value>& args);
88   static void AddRootCerts(const v8::FunctionCallbackInfo<v8::Value>& args);
89   static void SetCiphers(const v8::FunctionCallbackInfo<v8::Value>& args);
90   static void SetECDHCurve(const v8::FunctionCallbackInfo<v8::Value>& args);
91   static void SetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
92   static void SetSessionIdContext(
93       const v8::FunctionCallbackInfo<v8::Value>& args);
94   static void SetSessionTimeout(
95       const v8::FunctionCallbackInfo<v8::Value>& args);
96   static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
97   static void LoadPKCS12(const v8::FunctionCallbackInfo<v8::Value>& args);
98   static void GetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
99   static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
100
101   SecureContext(Environment* env, v8::Local<v8::Object> wrap)
102       : BaseObject(env, wrap),
103         ca_store_(NULL),
104         ctx_(NULL) {
105     MakeWeak<SecureContext>(this);
106   }
107
108   void FreeCTXMem() {
109     if (ctx_) {
110       if (ctx_->cert_store == root_cert_store) {
111         // SSL_CTX_free() will attempt to free the cert_store as well.
112         // Since we want our root_cert_store to stay around forever
113         // we just clear the field. Hopefully OpenSSL will not modify this
114         // struct in future versions.
115         ctx_->cert_store = NULL;
116       }
117       SSL_CTX_free(ctx_);
118       ctx_ = NULL;
119       ca_store_ = NULL;
120     } else {
121       assert(ca_store_ == NULL);
122     }
123   }
124 };
125
126 // SSLWrap implicitly depends on the inheriting class' handle having an
127 // internal pointer to the Base class.
128 template <class Base>
129 class SSLWrap {
130  public:
131   enum Kind {
132     kClient,
133     kServer
134   };
135
136   SSLWrap(Environment* env, SecureContext* sc, Kind kind)
137       : env_(env),
138         kind_(kind),
139         next_sess_(NULL),
140         session_callbacks_(false),
141         new_session_wait_(false) {
142     ssl_ = SSL_new(sc->ctx_);
143     assert(ssl_ != NULL);
144   }
145
146   ~SSLWrap() {
147     if (ssl_ != NULL) {
148       SSL_free(ssl_);
149       ssl_ = NULL;
150     }
151     if (next_sess_ != NULL) {
152       SSL_SESSION_free(next_sess_);
153       next_sess_ = NULL;
154     }
155
156 #ifdef OPENSSL_NPN_NEGOTIATED
157     npn_protos_.Reset();
158     selected_npn_proto_.Reset();
159 #endif
160   }
161
162   inline SSL* ssl() const { return ssl_; }
163   inline void enable_session_callbacks() { session_callbacks_ = true; }
164   inline bool is_server() const { return kind_ == kServer; }
165   inline bool is_client() const { return kind_ == kClient; }
166   inline bool is_waiting_new_session() const { return new_session_wait_; }
167
168  protected:
169   static void InitNPN(SecureContext* sc, Base* base);
170   static void AddMethods(Environment* env, v8::Handle<v8::FunctionTemplate> t);
171
172   static SSL_SESSION* GetSessionCallback(SSL* s,
173                                          unsigned char* key,
174                                          int len,
175                                          int* copy);
176   static int NewSessionCallback(SSL* s, SSL_SESSION* sess);
177   static void OnClientHello(void* arg,
178                             const ClientHelloParser::ClientHello& hello);
179
180   static void GetPeerCertificate(
181       const v8::FunctionCallbackInfo<v8::Value>& args);
182   static void GetSession(const v8::FunctionCallbackInfo<v8::Value>& args);
183   static void SetSession(const v8::FunctionCallbackInfo<v8::Value>& args);
184   static void LoadSession(const v8::FunctionCallbackInfo<v8::Value>& args);
185   static void IsSessionReused(const v8::FunctionCallbackInfo<v8::Value>& args);
186   static void IsInitFinished(const v8::FunctionCallbackInfo<v8::Value>& args);
187   static void VerifyError(const v8::FunctionCallbackInfo<v8::Value>& args);
188   static void GetCurrentCipher(const v8::FunctionCallbackInfo<v8::Value>& args);
189   static void EndParser(const v8::FunctionCallbackInfo<v8::Value>& args);
190   static void Renegotiate(const v8::FunctionCallbackInfo<v8::Value>& args);
191   static void Shutdown(const v8::FunctionCallbackInfo<v8::Value>& args);
192   static void GetTLSTicket(const v8::FunctionCallbackInfo<v8::Value>& args);
193   static void NewSessionDone(const v8::FunctionCallbackInfo<v8::Value>& args);
194
195 #ifdef SSL_set_max_send_fragment
196   static void SetMaxSendFragment(
197       const v8::FunctionCallbackInfo<v8::Value>& args);
198 #endif  // SSL_set_max_send_fragment
199
200 #ifdef OPENSSL_NPN_NEGOTIATED
201   static void GetNegotiatedProto(
202       const v8::FunctionCallbackInfo<v8::Value>& args);
203   static void SetNPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args);
204   static int AdvertiseNextProtoCallback(SSL* s,
205                                         const unsigned char** data,
206                                         unsigned int* len,
207                                         void* arg);
208   static int SelectNextProtoCallback(SSL* s,
209                                      unsigned char** out,
210                                      unsigned char* outlen,
211                                      const unsigned char* in,
212                                      unsigned int inlen,
213                                      void* arg);
214 #endif  // OPENSSL_NPN_NEGOTIATED
215
216   inline Environment* ssl_env() const {
217     return env_;
218   }
219
220   Environment* const env_;
221   Kind kind_;
222   SSL_SESSION* next_sess_;
223   SSL* ssl_;
224   bool session_callbacks_;
225   bool new_session_wait_;
226   ClientHelloParser hello_parser_;
227
228 #ifdef OPENSSL_NPN_NEGOTIATED
229   v8::Persistent<v8::Object> npn_protos_;
230   v8::Persistent<v8::Value> selected_npn_proto_;
231 #endif  // OPENSSL_NPN_NEGOTIATED
232
233   friend class SecureContext;
234 };
235
236 // Connection inherits from AsyncWrap because SSLWrap makes calls to
237 // MakeCallback, but SSLWrap doesn't store the handle itself. Instead it
238 // assumes that any args.This() called will be the handle from Connection.
239 class Connection : public SSLWrap<Connection>, public AsyncWrap {
240  public:
241   ~Connection() {
242 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
243     sniObject_.Reset();
244     sniContext_.Reset();
245     servername_.Reset();
246 #endif
247   }
248
249   static void Initialize(Environment* env, v8::Handle<v8::Object> target);
250   void NewSessionDoneCb();
251
252 #ifdef OPENSSL_NPN_NEGOTIATED
253   v8::Persistent<v8::Object> npnProtos_;
254   v8::Persistent<v8::Value> selectedNPNProto_;
255 #endif
256
257 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
258   v8::Persistent<v8::Object> sniObject_;
259   v8::Persistent<v8::Value> sniContext_;
260   v8::Persistent<v8::String> servername_;
261 #endif
262
263  protected:
264   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
265   static void EncIn(const v8::FunctionCallbackInfo<v8::Value>& args);
266   static void ClearOut(const v8::FunctionCallbackInfo<v8::Value>& args);
267   static void ClearPending(const v8::FunctionCallbackInfo<v8::Value>& args);
268   static void EncPending(const v8::FunctionCallbackInfo<v8::Value>& args);
269   static void EncOut(const v8::FunctionCallbackInfo<v8::Value>& args);
270   static void ClearIn(const v8::FunctionCallbackInfo<v8::Value>& args);
271   static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
272   static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
273
274 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
275   // SNI
276   static void GetServername(const v8::FunctionCallbackInfo<v8::Value>& args);
277   static void SetSNICallback(const v8::FunctionCallbackInfo<v8::Value>& args);
278   static int SelectSNIContextCallback_(SSL* s, int* ad, void* arg);
279 #endif
280
281   static void OnClientHelloParseEnd(void* arg);
282
283   int HandleBIOError(BIO* bio, const char* func, int rv);
284
285   enum ZeroStatus {
286     kZeroIsNotAnError,
287     kZeroIsAnError
288   };
289
290   enum SyscallStatus {
291     kIgnoreSyscall,
292     kSyscallError
293   };
294
295   int HandleSSLError(const char* func, int rv, ZeroStatus zs, SyscallStatus ss);
296
297   void ClearError();
298   void SetShutdownFlags();
299
300   Connection(Environment* env,
301              v8::Local<v8::Object> wrap,
302              SecureContext* sc,
303              SSLWrap<Connection>::Kind kind)
304       : SSLWrap<Connection>(env, sc, kind),
305         AsyncWrap(env, wrap, AsyncWrap::PROVIDER_CRYPTO),
306         bio_read_(NULL),
307         bio_write_(NULL),
308         hello_offset_(0) {
309     MakeWeak<Connection>(this);
310     hello_parser_.Start(SSLWrap<Connection>::OnClientHello,
311                         OnClientHelloParseEnd,
312                         this);
313     enable_session_callbacks();
314   }
315
316  private:
317   static void SSLInfoCallback(const SSL *ssl, int where, int ret);
318
319   BIO *bio_read_;
320   BIO *bio_write_;
321
322   uint8_t hello_data_[18432];
323   size_t hello_offset_;
324
325   friend class ClientHelloParser;
326   friend class SecureContext;
327 };
328
329 class CipherBase : public BaseObject {
330  public:
331   ~CipherBase() {
332     if (!initialised_)
333       return;
334     delete[] auth_tag_;
335     EVP_CIPHER_CTX_cleanup(&ctx_);
336   }
337
338   static void Initialize(Environment* env, v8::Handle<v8::Object> target);
339
340  protected:
341   enum CipherKind {
342     kCipher,
343     kDecipher
344   };
345
346   void Init(const char* cipher_type, const char* key_buf, int key_buf_len);
347   void InitIv(const char* cipher_type,
348               const char* key,
349               int key_len,
350               const char* iv,
351               int iv_len);
352   bool Update(const char* data, int len, unsigned char** out, int* out_len);
353   bool Final(unsigned char** out, int *out_len);
354   bool SetAutoPadding(bool auto_padding);
355
356   bool IsAuthenticatedMode() const;
357   bool GetAuthTag(char** out, unsigned int* out_len) const;
358   bool SetAuthTag(const char* data, unsigned int len);
359   bool SetAAD(const char* data, unsigned int len);
360
361   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
362   static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
363   static void InitIv(const v8::FunctionCallbackInfo<v8::Value>& args);
364   static void Update(const v8::FunctionCallbackInfo<v8::Value>& args);
365   static void Final(const v8::FunctionCallbackInfo<v8::Value>& args);
366   static void SetAutoPadding(const v8::FunctionCallbackInfo<v8::Value>& args);
367
368   static void GetAuthTag(const v8::FunctionCallbackInfo<v8::Value>& args);
369   static void SetAuthTag(const v8::FunctionCallbackInfo<v8::Value>& args);
370   static void SetAAD(const v8::FunctionCallbackInfo<v8::Value>& args);
371
372   CipherBase(Environment* env,
373              v8::Local<v8::Object> wrap,
374              CipherKind kind)
375       : BaseObject(env, wrap),
376         cipher_(NULL),
377         initialised_(false),
378         kind_(kind),
379         auth_tag_(NULL),
380         auth_tag_len_(0) {
381     MakeWeak<CipherBase>(this);
382   }
383
384  private:
385   EVP_CIPHER_CTX ctx_; /* coverity[member_decl] */
386   const EVP_CIPHER* cipher_; /* coverity[member_decl] */
387   bool initialised_;
388   CipherKind kind_;
389   char* auth_tag_;
390   unsigned int auth_tag_len_;
391 };
392
393 class Hmac : public BaseObject {
394  public:
395   ~Hmac() {
396     if (!initialised_)
397       return;
398     HMAC_CTX_cleanup(&ctx_);
399   }
400
401   static void Initialize(Environment* env, v8::Handle<v8::Object> target);
402
403  protected:
404   void HmacInit(const char* hash_type, const char* key, int key_len);
405   bool HmacUpdate(const char* data, int len);
406   bool HmacDigest(unsigned char** md_value, unsigned int* md_len);
407
408   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
409   static void HmacInit(const v8::FunctionCallbackInfo<v8::Value>& args);
410   static void HmacUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
411   static void HmacDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
412
413   Hmac(Environment* env, v8::Local<v8::Object> wrap)
414       : BaseObject(env, wrap),
415         md_(NULL),
416         initialised_(false) {
417     MakeWeak<Hmac>(this);
418   }
419
420  private:
421   HMAC_CTX ctx_; /* coverity[member_decl] */
422   const EVP_MD* md_; /* coverity[member_decl] */
423   bool initialised_;
424 };
425
426 class Hash : public BaseObject {
427  public:
428   ~Hash() {
429     if (!initialised_)
430       return;
431     EVP_MD_CTX_cleanup(&mdctx_);
432   }
433
434   static void Initialize(Environment* env, v8::Handle<v8::Object> target);
435
436   bool HashInit(const char* hash_type);
437   bool HashUpdate(const char* data, int len);
438
439  protected:
440   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
441   static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
442   static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
443
444   Hash(Environment* env, v8::Local<v8::Object> wrap)
445       : BaseObject(env, wrap),
446         md_(NULL),
447         initialised_(false) {
448     MakeWeak<Hash>(this);
449   }
450
451  private:
452   EVP_MD_CTX mdctx_; /* coverity[member_decl] */
453   const EVP_MD* md_; /* coverity[member_decl] */
454   bool initialised_;
455 };
456
457 class SignBase : public BaseObject {
458  public:
459   typedef enum {
460     kSignOk,
461     kSignUnknownDigest,
462     kSignInit,
463     kSignNotInitialised,
464     kSignUpdate,
465     kSignPrivateKey,
466     kSignPublicKey
467   } Error;
468
469   SignBase(Environment* env, v8::Local<v8::Object> wrap)
470       : BaseObject(env, wrap),
471         md_(NULL),
472         initialised_(false) {
473   }
474
475   ~SignBase() {
476     if (!initialised_)
477       return;
478     EVP_MD_CTX_cleanup(&mdctx_);
479   }
480
481  protected:
482   void CheckThrow(Error error);
483
484   EVP_MD_CTX mdctx_; /* coverity[member_decl] */
485   const EVP_MD* md_; /* coverity[member_decl] */
486   bool initialised_;
487 };
488
489 class Sign : public SignBase {
490  public:
491
492   static void Initialize(Environment* env, v8::Handle<v8::Object> target);
493
494   Error SignInit(const char* sign_type);
495   Error SignUpdate(const char* data, int len);
496   Error SignFinal(const char* key_pem,
497                   int key_pem_len,
498                   const char* passphrase,
499                   unsigned char** sig,
500                   unsigned int *sig_len);
501
502  protected:
503   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
504   static void SignInit(const v8::FunctionCallbackInfo<v8::Value>& args);
505   static void SignUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
506   static void SignFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
507
508   Sign(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) {
509     MakeWeak<Sign>(this);
510   }
511 };
512
513 class Verify : public SignBase {
514  public:
515   static void Initialize(Environment* env, v8::Handle<v8::Object> target);
516
517   Error VerifyInit(const char* verify_type);
518   Error VerifyUpdate(const char* data, int len);
519   Error VerifyFinal(const char* key_pem,
520                     int key_pem_len,
521                     const char* sig,
522                     int siglen,
523                     bool* verify_result);
524
525  protected:
526   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
527   static void VerifyInit(const v8::FunctionCallbackInfo<v8::Value>& args);
528   static void VerifyUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
529   static void VerifyFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
530
531   Verify(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) {
532     MakeWeak<Verify>(this);
533   }
534 };
535
536 class DiffieHellman : public BaseObject {
537  public:
538   ~DiffieHellman() {
539     if (dh != NULL) {
540       DH_free(dh);
541     }
542   }
543
544   static void Initialize(Environment* env, v8::Handle<v8::Object> target);
545
546   bool Init(int primeLength, int g);
547   bool Init(const char* p, int p_len, int g);
548   bool Init(const char* p, int p_len, const char* g, int g_len);
549
550  protected:
551   static void DiffieHellmanGroup(
552       const v8::FunctionCallbackInfo<v8::Value>& args);
553   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
554   static void GenerateKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
555   static void GetPrime(const v8::FunctionCallbackInfo<v8::Value>& args);
556   static void GetGenerator(const v8::FunctionCallbackInfo<v8::Value>& args);
557   static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
558   static void GetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
559   static void ComputeSecret(const v8::FunctionCallbackInfo<v8::Value>& args);
560   static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
561   static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
562   static void VerifyErrorGetter(
563       v8::Local<v8::String> property,
564       const v8::PropertyCallbackInfo<v8::Value>& args);
565
566   DiffieHellman(Environment* env, v8::Local<v8::Object> wrap)
567       : BaseObject(env, wrap),
568         initialised_(false),
569         verifyError_(0),
570         dh(NULL) {
571     MakeWeak<DiffieHellman>(this);
572   }
573
574  private:
575   bool VerifyContext();
576
577   bool initialised_;
578   int verifyError_;
579   DH* dh;
580 };
581
582 class Certificate : public AsyncWrap {
583  public:
584   static void Initialize(Environment* env, v8::Handle<v8::Object> target);
585
586   v8::Handle<v8::Value> CertificateInit(const char* sign_type);
587   bool VerifySpkac(const char* data, unsigned int len);
588   const char* ExportPublicKey(const char* data, int len);
589   const char* ExportChallenge(const char* data, int len);
590
591  protected:
592   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
593   static void VerifySpkac(const v8::FunctionCallbackInfo<v8::Value>& args);
594   static void ExportPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
595   static void ExportChallenge(const v8::FunctionCallbackInfo<v8::Value>& args);
596
597   Certificate(Environment* env, v8::Local<v8::Object> wrap)
598       : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_CRYPTO) {
599     MakeWeak<Certificate>(this);
600   }
601 };
602
603 bool EntropySource(unsigned char* buffer, size_t length);
604 #ifndef OPENSSL_NO_ENGINE
605 void SetEngine(const v8::FunctionCallbackInfo<v8::Value>& args);
606 #endif  // !OPENSSL_NO_ENGINE
607 void InitCrypto(v8::Handle<v8::Object> target);
608
609 }  // namespace crypto
610 }  // namespace node
611
612 #endif  // SRC_NODE_CRYPTO_H_