The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / src / node_crypto.h @ 6f92da2d

History | View | Annotate | Download (14.5 KB)

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
#include "node_object_wrap.h"
29

    
30
#ifdef OPENSSL_NPN_NEGOTIATED
31
#include "node_buffer.h"
32
#endif
33

    
34
#include "v8.h"
35

    
36
#include <openssl/ssl.h>
37
#include <openssl/err.h>
38
#include <openssl/evp.h>
39
#include <openssl/pem.h>
40
#include <openssl/x509.h>
41
#include <openssl/x509v3.h>
42
#include <openssl/hmac.h>
43
#include <openssl/rand.h>
44
#include <openssl/pkcs12.h>
45

    
46
#define EVP_F_EVP_DECRYPTFINAL 101
47

    
48

    
49
namespace node {
50
namespace crypto {
51

    
52
static X509_STORE* root_cert_store;
53

    
54
// Forward declaration
55
class Connection;
56

    
57
class SecureContext : ObjectWrap {
58
 public:
59
  static void Initialize(v8::Handle<v8::Object> target);
60

    
61
  SSL_CTX *ctx_;
62
  // TODO(indutny): ca_store_ should probably be removed, it's not used anywhere
63
  X509_STORE *ca_store_;
64

    
65
  static const int kMaxSessionSize = 10 * 1024;
66

    
67
 protected:
68

    
69
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
70
  static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
71
  static void SetKey(const v8::FunctionCallbackInfo<v8::Value>& args);
72
  static void SetCert(const v8::FunctionCallbackInfo<v8::Value>& args);
73
  static void AddCACert(const v8::FunctionCallbackInfo<v8::Value>& args);
74
  static void AddCRL(const v8::FunctionCallbackInfo<v8::Value>& args);
75
  static void AddRootCerts(const v8::FunctionCallbackInfo<v8::Value>& args);
76
  static void SetCiphers(const v8::FunctionCallbackInfo<v8::Value>& args);
77
  static void SetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
78
  static void SetSessionIdContext(
79
      const v8::FunctionCallbackInfo<v8::Value>& args);
80
  static void SetSessionTimeout(
81
      const v8::FunctionCallbackInfo<v8::Value>& args);
82
  static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
83
  static void LoadPKCS12(const v8::FunctionCallbackInfo<v8::Value>& args);
84
  static void GetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
85
  static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
86

    
87
  static SSL_SESSION* GetSessionCallback(SSL* s,
88
                                         unsigned char* key,
89
                                         int len,
90
                                         int* copy);
91
  static int NewSessionCallback(SSL* s, SSL_SESSION* sess);
92

    
93
  SecureContext() : ObjectWrap() {
94
    ctx_ = NULL;
95
    ca_store_ = NULL;
96
  }
97

    
98
  void FreeCTXMem() {
99
    if (ctx_) {
100
      if (ctx_->cert_store == root_cert_store) {
101
        // SSL_CTX_free() will attempt to free the cert_store as well.
102
        // Since we want our root_cert_store to stay around forever
103
        // we just clear the field. Hopefully OpenSSL will not modify this
104
        // struct in future versions.
105
        ctx_->cert_store = NULL;
106
      }
107
      SSL_CTX_free(ctx_);
108
      ctx_ = NULL;
109
      ca_store_ = NULL;
110
    } else {
111
      assert(ca_store_ == NULL);
112
    }
113
  }
114

    
115
  ~SecureContext() {
116
    FreeCTXMem();
117
  }
118

    
119
 private:
120
};
121

    
122
class Connection : ObjectWrap {
123
 public:
124
  static void Initialize(v8::Handle<v8::Object> target);
125

    
126
#ifdef OPENSSL_NPN_NEGOTIATED
127
  v8::Persistent<v8::Object> npnProtos_;
128
  v8::Persistent<v8::Value> selectedNPNProto_;
129
#endif
130

    
131
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
132
  v8::Persistent<v8::Object> sniObject_;
133
  v8::Persistent<v8::Value> sniContext_;
134
  v8::Persistent<v8::String> servername_;
135
#endif
136

    
137
 protected:
138
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
139
  static void EncIn(const v8::FunctionCallbackInfo<v8::Value>& args);
140
  static void ClearOut(const v8::FunctionCallbackInfo<v8::Value>& args);
141
  static void ClearPending(const v8::FunctionCallbackInfo<v8::Value>& args);
142
  static void EncPending(const v8::FunctionCallbackInfo<v8::Value>& args);
143
  static void EncOut(const v8::FunctionCallbackInfo<v8::Value>& args);
144
  static void ClearIn(const v8::FunctionCallbackInfo<v8::Value>& args);
145
  static void GetPeerCertificate(
146
      const v8::FunctionCallbackInfo<v8::Value>& args);
147
  static void GetSession(const v8::FunctionCallbackInfo<v8::Value>& args);
148
  static void SetSession(const v8::FunctionCallbackInfo<v8::Value>& args);
149
  static void LoadSession(const v8::FunctionCallbackInfo<v8::Value>& args);
150
  static void IsSessionReused(const v8::FunctionCallbackInfo<v8::Value>& args);
151
  static void IsInitFinished(const v8::FunctionCallbackInfo<v8::Value>& args);
152
  static void VerifyError(const v8::FunctionCallbackInfo<v8::Value>& args);
153
  static void GetCurrentCipher(const v8::FunctionCallbackInfo<v8::Value>& args);
154
  static void Shutdown(const v8::FunctionCallbackInfo<v8::Value>& args);
155
  static void ReceivedShutdown(const v8::FunctionCallbackInfo<v8::Value>& args);
156
  static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
157
  static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
158

    
159
#ifdef OPENSSL_NPN_NEGOTIATED
160
  // NPN
161
  static void GetNegotiatedProto(
162
      const v8::FunctionCallbackInfo<v8::Value>& args);
163
  static void SetNPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args);
164
  static int AdvertiseNextProtoCallback_(SSL* s,
165
                                         const unsigned char** data,
166
                                         unsigned int* len,
167
                                         void* arg);
168
  static int SelectNextProtoCallback_(SSL* s,
169
                                      unsigned char** out,
170
                                      unsigned char* outlen,
171
                                      const unsigned char* in,
172
                                      unsigned int inlen,
173
                                      void* arg);
174
#endif
175

    
176
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
177
  // SNI
178
  static void GetServername(const v8::FunctionCallbackInfo<v8::Value>& args);
179
  static void SetSNICallback(const v8::FunctionCallbackInfo<v8::Value>& args);
180
  static int SelectSNIContextCallback_(SSL* s, int* ad, void* arg);
181
#endif
182

    
183
  static void OnClientHello(void* arg,
184
                            const ClientHelloParser::ClientHello& hello);
185
  static void OnClientHelloParseEnd(void* arg);
186

    
187
  int HandleBIOError(BIO* bio, const char* func, int rv);
188

    
189
  enum ZeroStatus {
190
    kZeroIsNotAnError,
191
    kZeroIsAnError
192
  };
193

    
194
  enum SyscallStatus {
195
    kIgnoreSyscall,
196
    kSyscallError
197
  };
198

    
199
  int HandleSSLError(const char* func, int rv, ZeroStatus zs, SyscallStatus ss);
200

    
201
  void ClearError();
202
  void SetShutdownFlags();
203

    
204
  static Connection* Unwrap(const v8::FunctionCallbackInfo<v8::Value>& args) {
205
    Connection* ss = ObjectWrap::Unwrap<Connection>(args.This());
206
    ss->ClearError();
207
    return ss;
208
  }
209

    
210
  Connection() : ObjectWrap(), hello_offset_(0) {
211
    bio_read_ = bio_write_ = NULL;
212
    ssl_ = NULL;
213
    next_sess_ = NULL;
214
    hello_parser_.Start(OnClientHello, OnClientHelloParseEnd, this);
215
  }
216

    
217
  ~Connection() {
218
    if (ssl_ != NULL) {
219
      SSL_free(ssl_);
220
      ssl_ = NULL;
221
    }
222

    
223
    if (next_sess_ != NULL) {
224
      SSL_SESSION_free(next_sess_);
225
      next_sess_ = NULL;
226
    }
227

    
228
#ifdef OPENSSL_NPN_NEGOTIATED
229
    npnProtos_.Dispose();
230
    selectedNPNProto_.Dispose();
231
#endif
232

    
233
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
234
    sniObject_.Dispose();
235
    sniContext_.Dispose();
236
    servername_.Dispose();
237
#endif
238
  }
239

    
240
 private:
241
  static void SSLInfoCallback(const SSL *ssl, int where, int ret);
242

    
243
  BIO *bio_read_;
244
  BIO *bio_write_;
245
  SSL *ssl_;
246

    
247
  ClientHelloParser hello_parser_;
248

    
249
  bool is_server_; /* coverity[member_decl] */
250
  SSL_SESSION* next_sess_;
251

    
252
  uint8_t hello_data_[18432];
253
  size_t hello_offset_;
254

    
255
  friend class ClientHelloParser;
256
  friend class SecureContext;
257
};
258

    
259
class CipherBase : public ObjectWrap {
260
 public:
261
  static void Initialize(v8::Handle<v8::Object> target);
262

    
263
 protected:
264
  enum CipherKind {
265
    kCipher,
266
    kDecipher
267
  };
268

    
269
  void Init(const char* cipher_type, const char* key_buf, int key_buf_len);
270
  void InitIv(const char* cipher_type,
271
              const char* key,
272
              int key_len,
273
              const char* iv,
274
              int iv_len);
275
  bool Update(const char* data, int len, unsigned char** out, int* out_len);
276
  bool Final(unsigned char** out, int *out_len);
277
  bool SetAutoPadding(bool auto_padding);
278

    
279
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
280
  static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
281
  static void InitIv(const v8::FunctionCallbackInfo<v8::Value>& args);
282
  static void Update(const v8::FunctionCallbackInfo<v8::Value>& args);
283
  static void Final(const v8::FunctionCallbackInfo<v8::Value>& args);
284
  static void SetAutoPadding(const v8::FunctionCallbackInfo<v8::Value>& args);
285

    
286
  explicit CipherBase(CipherKind kind) : cipher_(NULL),
287
                                         initialised_(false),
288
                                         kind_(kind) {
289
  }
290

    
291
  ~CipherBase() {
292
    if (!initialised_) return;
293
    EVP_CIPHER_CTX_cleanup(&ctx_);
294
  }
295

    
296
 private:
297
  EVP_CIPHER_CTX ctx_; /* coverity[member_decl] */
298
  const EVP_CIPHER* cipher_; /* coverity[member_decl] */
299
  bool initialised_;
300
  CipherKind kind_;
301
};
302

    
303
class Hmac : public ObjectWrap {
304
 public:
305
  static void Initialize(v8::Handle<v8::Object> target);
306

    
307
 protected:
308
  void HmacInit(const char* hash_type, const char* key, int key_len);
309
  bool HmacUpdate(const char* data, int len);
310
  bool HmacDigest(unsigned char** md_value, unsigned int* md_len);
311

    
312
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
313
  static void HmacInit(const v8::FunctionCallbackInfo<v8::Value>& args);
314
  static void HmacUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
315
  static void HmacDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
316

    
317
  Hmac() : md_(NULL), initialised_(false) {
318
  }
319

    
320
  ~Hmac() {
321
    if (!initialised_) return;
322
    HMAC_CTX_cleanup(&ctx_);
323
  }
324

    
325
 private:
326
  HMAC_CTX ctx_; /* coverity[member_decl] */
327
  const EVP_MD* md_; /* coverity[member_decl] */
328
  bool initialised_;
329
};
330

    
331
class Hash : public ObjectWrap {
332
 public:
333
  static void Initialize(v8::Handle<v8::Object> target);
334

    
335
  bool HashInit(const char* hash_type);
336
  bool HashUpdate(const char* data, int len);
337

    
338
 protected:
339
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
340
  static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
341
  static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
342

    
343
  Hash() : md_(NULL), initialised_(false) {
344
  }
345

    
346
  ~Hash() {
347
    if (!initialised_) return;
348
    EVP_MD_CTX_cleanup(&mdctx_);
349
  }
350

    
351
 private:
352
  EVP_MD_CTX mdctx_; /* coverity[member_decl] */
353
  const EVP_MD* md_; /* coverity[member_decl] */
354
  bool initialised_;
355
};
356

    
357
class Sign : public ObjectWrap {
358
 public:
359
  static void Initialize(v8::Handle<v8::Object> target);
360

    
361
  void SignInit(const char* sign_type);
362
  bool SignUpdate(const char* data, int len);
363
  bool SignFinal(unsigned char** md_value,
364
                 unsigned int *md_len,
365
                 const char* key_pem,
366
                 int key_pem_len);
367

    
368
 protected:
369
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
370
  static void SignInit(const v8::FunctionCallbackInfo<v8::Value>& args);
371
  static void SignUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
372
  static void SignFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
373

    
374
  Sign() : md_(NULL), initialised_(false) {
375
  }
376

    
377
  ~Sign() {
378
    if (!initialised_) return;
379
    EVP_MD_CTX_cleanup(&mdctx_);
380
  }
381

    
382
 private:
383
  EVP_MD_CTX mdctx_; /* coverity[member_decl] */
384
  const EVP_MD* md_; /* coverity[member_decl] */
385
  bool initialised_;
386
};
387

    
388
class Verify : public ObjectWrap {
389
 public:
390
  static void Initialize(v8::Handle<v8::Object> target);
391

    
392
  void VerifyInit(const char* verify_type);
393
  bool VerifyUpdate(const char* data, int len);
394
  bool VerifyFinal(const char* key_pem,
395
                   int key_pem_len,
396
                   const char* sig,
397
                   int siglen);
398

    
399
 protected:
400
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
401
  static void VerifyInit(const v8::FunctionCallbackInfo<v8::Value>& args);
402
  static void VerifyUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
403
  static void VerifyFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
404

    
405
  Verify() : md_(NULL), initialised_(false) {
406
  }
407

    
408
  ~Verify() {
409
    if (!initialised_) return;
410
    EVP_MD_CTX_cleanup(&mdctx_);
411
  }
412

    
413
 private:
414
  EVP_MD_CTX mdctx_; /* coverity[member_decl] */
415
  const EVP_MD* md_; /* coverity[member_decl] */
416
  bool initialised_;
417
};
418

    
419
class DiffieHellman : public ObjectWrap {
420
 public:
421
  static void Initialize(v8::Handle<v8::Object> target);
422

    
423
  bool Init(int primeLength);
424
  bool Init(const char* p, int p_len);
425
  bool Init(const char* p, int p_len, const char* g, int g_len);
426

    
427
 protected:
428
  static void DiffieHellmanGroup(
429
      const v8::FunctionCallbackInfo<v8::Value>& args);
430
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
431
  static void GenerateKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
432
  static void GetPrime(const v8::FunctionCallbackInfo<v8::Value>& args);
433
  static void GetGenerator(const v8::FunctionCallbackInfo<v8::Value>& args);
434
  static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
435
  static void GetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
436
  static void ComputeSecret(const v8::FunctionCallbackInfo<v8::Value>& args);
437
  static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
438
  static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
439

    
440
  DiffieHellman() : ObjectWrap(), initialised_(false), dh(NULL) {
441
  }
442

    
443
  ~DiffieHellman() {
444
    if (dh != NULL) {
445
      DH_free(dh);
446
    }
447
  }
448

    
449
 private:
450
  bool VerifyContext();
451

    
452
  bool initialised_;
453
  DH* dh;
454
};
455

    
456
void InitCrypto(v8::Handle<v8::Object> target);
457

    
458
}  // namespace crypto
459
}  // namespace node
460

    
461
#endif  // SRC_NODE_CRYPTO_H_