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