Skip to content
Newer
Older
100644 279 lines (229 sloc) 8.53 KB
55048cd @ry Update copyright headers
ry authored
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
fb3a9cd @waveto Initial openssl support for net2
waveto authored
22 #ifndef SRC_NODE_CRYPTO_H_
23 #define SRC_NODE_CRYPTO_H_
24
ff4a9d3 @bnoordhuis core: use proper #include directives
bnoordhuis authored
25 #include "node.h"
c9b40da @indutny OpenSSL NPN in node.js
indutny authored
26
ff4a9d3 @bnoordhuis core: use proper #include directives
bnoordhuis authored
27 #include "node_object_wrap.h"
28 #include "v8.h"
fb3a9cd @waveto Initial openssl support for net2
waveto authored
29
30 #include <openssl/ssl.h>
31 #include <openssl/err.h>
8017439 @waveto Moved Credentials into crypto module. Added node_crypto into crypto m…
waveto authored
32 #include <openssl/evp.h>
33 #include <openssl/pem.h>
34 #include <openssl/x509.h>
7b2536a @niclashoyer Added additional properties to getPeerCertificate, now includes subje…
niclashoyer authored
35 #include <openssl/x509v3.h>
8017439 @waveto Moved Credentials into crypto module. Added node_crypto into crypto m…
waveto authored
36 #include <openssl/hmac.h>
c4eaf7e @bnoordhuis crypto: implement randomBytes() and pseudoRandomBytes()
bnoordhuis authored
37 #include <openssl/rand.h>
fb7348a crypto: add PKCS12/PFX support
ssuda authored
38 #include <openssl/pkcs12.h>
8017439 @waveto Moved Credentials into crypto module. Added node_crypto into crypto m…
waveto authored
39
c9b40da @indutny OpenSSL NPN in node.js
indutny authored
40 #ifdef OPENSSL_NPN_NEGOTIATED
ff4a9d3 @bnoordhuis core: use proper #include directives
bnoordhuis authored
41 #include "node_buffer.h"
c9b40da @indutny OpenSSL NPN in node.js
indutny authored
42 #endif
43
8017439 @waveto Moved Credentials into crypto module. Added node_crypto into crypto m…
waveto authored
44 #define EVP_F_EVP_DECRYPTFINAL 101
45
fb3a9cd @waveto Initial openssl support for net2
waveto authored
46
47 namespace node {
e3d1808 @ry Rename node::SecureStream to node::crypto::Connection
ry authored
48 namespace crypto {
fb3a9cd @waveto Initial openssl support for net2
waveto authored
49
5c35dff @ry Don't load root certs for each SSL context
ry authored
50 static X509_STORE* root_cert_store;
51
8e0c830 @indutny tls: async session storage
indutny authored
52 // Forward declaration
53 class Connection;
54
fb3a9cd @waveto Initial openssl support for net2
waveto authored
55 class SecureContext : ObjectWrap {
56 public:
57 static void Initialize(v8::Handle<v8::Object> target);
58
9911629 @ry Fix style in node_crypto.cc
ry authored
59 SSL_CTX *ctx_;
5c35dff @ry Don't load root certs for each SSL context
ry authored
60 // TODO: ca_store_ should probably be removed, it's not used anywhere.
9911629 @ry Fix style in node_crypto.cc
ry authored
61 X509_STORE *ca_store_;
fb3a9cd @waveto Initial openssl support for net2
waveto authored
62
63 protected:
8e0c830 @indutny tls: async session storage
indutny authored
64 static const int kMaxSessionSize = 10 * 1024;
65
fb3a9cd @waveto Initial openssl support for net2
waveto authored
66 static v8::Handle<v8::Value> New(const v8::Arguments& args);
67 static v8::Handle<v8::Value> Init(const v8::Arguments& args);
68 static v8::Handle<v8::Value> SetKey(const v8::Arguments& args);
69 static v8::Handle<v8::Value> SetCert(const v8::Arguments& args);
70 static v8::Handle<v8::Value> AddCACert(const v8::Arguments& args);
01a864a @postwait TLS: CRL support
postwait authored
71 static v8::Handle<v8::Value> AddCRL(const v8::Arguments& args);
4b94731 @ry Move root certs out of JavaScript
ry authored
72 static v8::Handle<v8::Value> AddRootCerts(const v8::Arguments& args);
fb3a9cd @waveto Initial openssl support for net2
waveto authored
73 static v8::Handle<v8::Value> SetCiphers(const v8::Arguments& args);
2a88dd3 @postwait TLS: Add secureOptions flag
postwait authored
74 static v8::Handle<v8::Value> SetOptions(const v8::Arguments& args);
19a8553 @koichik tls: requestCert unusable with Firefox and Chrome
koichik authored
75 static v8::Handle<v8::Value> SetSessionIdContext(const v8::Arguments& args);
fb3a9cd @waveto Initial openssl support for net2
waveto authored
76 static v8::Handle<v8::Value> Close(const v8::Arguments& args);
fb7348a crypto: add PKCS12/PFX support
ssuda authored
77 static v8::Handle<v8::Value> LoadPKCS12(const v8::Arguments& args);
fb3a9cd @waveto Initial openssl support for net2
waveto authored
78
8e0c830 @indutny tls: async session storage
indutny authored
79 static SSL_SESSION* GetSessionCallback(SSL* s,
80 unsigned char* key,
81 int len,
82 int* copy);
83 static int NewSessionCallback(SSL* s, SSL_SESSION* sess);
84
fb3a9cd @waveto Initial openssl support for net2
waveto authored
85 SecureContext() : ObjectWrap() {
9911629 @ry Fix style in node_crypto.cc
ry authored
86 ctx_ = NULL;
87 ca_store_ = NULL;
fb3a9cd @waveto Initial openssl support for net2
waveto authored
88 }
89
5c35dff @ry Don't load root certs for each SSL context
ry authored
90 void FreeCTXMem() {
355936d @ry Implement SecureContext destructor
ry authored
91 if (ctx_) {
5c35dff @ry Don't load root certs for each SSL context
ry authored
92 if (ctx_->cert_store == root_cert_store) {
93 // SSL_CTX_free() will attempt to free the cert_store as well.
94 // Since we want our root_cert_store to stay around forever
95 // we just clear the field. Hopefully OpenSSL will not modify this
96 // struct in future versions.
97 ctx_->cert_store = NULL;
98 }
355936d @ry Implement SecureContext destructor
ry authored
99 SSL_CTX_free(ctx_);
100 ctx_ = NULL;
101 ca_store_ = NULL;
28a86c3 @ry Remove unnecessary call to X509_STORE_free
ry authored
102 } else {
103 assert(ca_store_ == NULL);
355936d @ry Implement SecureContext destructor
ry authored
104 }
fb3a9cd @waveto Initial openssl support for net2
waveto authored
105 }
106
5c35dff @ry Don't load root certs for each SSL context
ry authored
107 ~SecureContext() {
108 FreeCTXMem();
109 }
110
fb3a9cd @waveto Initial openssl support for net2
waveto authored
111 private:
112 };
113
8e0c830 @indutny tls: async session storage
indutny authored
114 class ClientHelloParser {
115 public:
116 enum FrameType {
117 kChangeCipherSpec = 20,
118 kAlert = 21,
119 kHandshake = 22,
120 kApplicationData = 23,
121 kOther = 255
122 };
123
124 enum HandshakeType {
125 kClientHello = 1
126 };
127
128 enum ParseState {
129 kWaiting,
130 kTLSHeader,
131 kSSLHeader,
132 kPaused,
133 kEnded
134 };
135
136 ClientHelloParser(Connection* c) : conn_(c),
137 state_(kWaiting),
138 offset_(0),
139 body_offset_(0),
140 written_(0) {
141 }
142
143 size_t Write(const uint8_t* data, size_t len);
144 void Finish();
145
146 inline bool ended() { return state_ == kEnded; }
147
148 private:
149 Connection* conn_;
150 ParseState state_;
151 size_t frame_len_;
152
153 uint8_t data_[18432];
154 size_t offset_;
155 size_t body_offset_;
156 size_t written_;
157 };
158
e3d1808 @ry Rename node::SecureStream to node::crypto::Connection
ry authored
159 class Connection : ObjectWrap {
fb3a9cd @waveto Initial openssl support for net2
waveto authored
160 public:
161 static void Initialize(v8::Handle<v8::Object> target);
162
c9b40da @indutny OpenSSL NPN in node.js
indutny authored
163 #ifdef OPENSSL_NPN_NEGOTIATED
164 v8::Persistent<v8::Object> npnProtos_;
165 v8::Persistent<v8::Value> selectedNPNProto_;
166 #endif
167
9010f5f @indutny Add support for TLS SNI
indutny authored
168 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
7dfa587 @bnoordhuis crypto, tls: make setSNICallback() compatible with domains
bnoordhuis authored
169 v8::Persistent<v8::Object> sniObject_;
9010f5f @indutny Add support for TLS SNI
indutny authored
170 v8::Persistent<v8::Value> sniContext_;
171 v8::Persistent<v8::String> servername_;
172 #endif
173
fb3a9cd @waveto Initial openssl support for net2
waveto authored
174 protected:
175 static v8::Handle<v8::Value> New(const v8::Arguments& args);
163485c @ry Rename some SecureStream methods
ry authored
176 static v8::Handle<v8::Value> EncIn(const v8::Arguments& args);
177 static v8::Handle<v8::Value> ClearOut(const v8::Arguments& args);
178 static v8::Handle<v8::Value> ClearPending(const v8::Arguments& args);
179 static v8::Handle<v8::Value> EncPending(const v8::Arguments& args);
180 static v8::Handle<v8::Value> EncOut(const v8::Arguments& args);
181 static v8::Handle<v8::Value> ClearIn(const v8::Arguments& args);
fb3a9cd @waveto Initial openssl support for net2
waveto authored
182 static v8::Handle<v8::Value> GetPeerCertificate(const v8::Arguments& args);
eb99083 @scunningham tls: add client-side session resumption support
scunningham authored
183 static v8::Handle<v8::Value> GetSession(const v8::Arguments& args);
184 static v8::Handle<v8::Value> SetSession(const v8::Arguments& args);
8e0c830 @indutny tls: async session storage
indutny authored
185 static v8::Handle<v8::Value> LoadSession(const v8::Arguments& args);
eb99083 @scunningham tls: add client-side session resumption support
scunningham authored
186 static v8::Handle<v8::Value> IsSessionReused(const v8::Arguments& args);
fb3a9cd @waveto Initial openssl support for net2
waveto authored
187 static v8::Handle<v8::Value> IsInitFinished(const v8::Arguments& args);
504a80d @ry Rename VerifyPeerError to VerifyError
ry authored
188 static v8::Handle<v8::Value> VerifyError(const v8::Arguments& args);
fb3a9cd @waveto Initial openssl support for net2
waveto authored
189 static v8::Handle<v8::Value> GetCurrentCipher(const v8::Arguments& args);
190 static v8::Handle<v8::Value> Shutdown(const v8::Arguments& args);
70baeba @ry Add receivedShutdown() binding
ry authored
191 static v8::Handle<v8::Value> ReceivedShutdown(const v8::Arguments& args);
1ce4684 @pquerna Centralize error handling in SecureStream
pquerna authored
192 static v8::Handle<v8::Value> Start(const v8::Arguments& args);
fb3a9cd @waveto Initial openssl support for net2
waveto authored
193 static v8::Handle<v8::Value> Close(const v8::Arguments& args);
194
c9b40da @indutny OpenSSL NPN in node.js
indutny authored
195 #ifdef OPENSSL_NPN_NEGOTIATED
196 // NPN
197 static v8::Handle<v8::Value> GetNegotiatedProto(const v8::Arguments& args);
198 static v8::Handle<v8::Value> SetNPNProtocols(const v8::Arguments& args);
199 static int AdvertiseNextProtoCallback_(SSL *s,
200 const unsigned char **data,
201 unsigned int *len,
202 void *arg);
203 static int SelectNextProtoCallback_(SSL *s,
204 unsigned char **out, unsigned char *outlen,
205 const unsigned char* in,
206 unsigned int inlen, void *arg);
207 #endif
208
9010f5f @indutny Add support for TLS SNI
indutny authored
209 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
210 // SNI
211 static v8::Handle<v8::Value> GetServername(const v8::Arguments& args);
212 static v8::Handle<v8::Value> SetSNICallback(const v8::Arguments& args);
213 static int SelectSNIContextCallback_(SSL *s, int *ad, void* arg);
214 #endif
215
56ab929 @ry Remove unused parameter from crypto::Handle*Error
ry authored
216 int HandleBIOError(BIO *bio, const char* func, int rv);
217 int HandleSSLError(const char* func, int rv);
218
2ff593a @ry TLS: better error reporting at binding layer
ry authored
219 void ClearError();
807fca6 @ry TLS: Set ssl.receivedShutdown after each read
ry authored
220 void SetShutdownFlags();
2ff593a @ry TLS: better error reporting at binding layer
ry authored
221
222 static Connection* Unwrap(const v8::Arguments& args) {
223 Connection* ss = ObjectWrap::Unwrap<Connection>(args.Holder());
224 ss->ClearError();
225 return ss;
226 }
227
8e0c830 @indutny tls: async session storage
indutny authored
228 Connection() : ObjectWrap(), hello_parser_(this) {
9911629 @ry Fix style in node_crypto.cc
ry authored
229 bio_read_ = bio_write_ = NULL;
230 ssl_ = NULL;
8e0c830 @indutny tls: async session storage
indutny authored
231 next_sess_ = NULL;
fb3a9cd @waveto Initial openssl support for net2
waveto authored
232 }
233
e3d1808 @ry Rename node::SecureStream to node::crypto::Connection
ry authored
234 ~Connection() {
9911629 @ry Fix style in node_crypto.cc
ry authored
235 if (ssl_ != NULL) {
236 SSL_free(ssl_);
237 ssl_ = NULL;
238 }
759fb36 @indutny crypto: dispose persistent properties on class destruction
indutny authored
239
8e0c830 @indutny tls: async session storage
indutny authored
240 if (next_sess_ != NULL) {
241 SSL_SESSION_free(next_sess_);
242 next_sess_ = NULL;
243 }
244
759fb36 @indutny crypto: dispose persistent properties on class destruction
indutny authored
245 #ifdef OPENSSL_NPN_NEGOTIATED
246 if (!npnProtos_.IsEmpty()) npnProtos_.Dispose();
247 if (!selectedNPNProto_.IsEmpty()) selectedNPNProto_.Dispose();
248 #endif
9010f5f @indutny Add support for TLS SNI
indutny authored
249
250 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
7dfa587 @bnoordhuis crypto, tls: make setSNICallback() compatible with domains
bnoordhuis authored
251 if (!sniObject_.IsEmpty()) sniObject_.Dispose();
9010f5f @indutny Add support for TLS SNI
indutny authored
252 if (!sniContext_.IsEmpty()) sniContext_.Dispose();
253 if (!servername_.IsEmpty()) servername_.Dispose();
254 #endif
fb3a9cd @waveto Initial openssl support for net2
waveto authored
255 }
256
257 private:
3415427 @bnoordhuis tls: mitigate session renegotiation attacks
bnoordhuis authored
258 static void SSLInfoCallback(const SSL *ssl, int where, int ret);
259
9911629 @ry Fix style in node_crypto.cc
ry authored
260 BIO *bio_read_;
261 BIO *bio_write_;
262 SSL *ssl_;
189dd8f @piscisaureus Fix line endings and trailing whitespace
piscisaureus authored
263
8e0c830 @indutny tls: async session storage
indutny authored
264 ClientHelloParser hello_parser_;
265
9911629 @ry Fix style in node_crypto.cc
ry authored
266 bool is_server_; /* coverity[member_decl] */
8e0c830 @indutny tls: async session storage
indutny authored
267 SSL_SESSION* next_sess_;
268
269 friend class ClientHelloParser;
270 friend class SecureContext;
fb3a9cd @waveto Initial openssl support for net2
waveto authored
271 };
272
273 void InitCrypto(v8::Handle<v8::Object> target);
e3d1808 @ry Rename node::SecureStream to node::crypto::Connection
ry authored
274
275 } // namespace crypto
276 } // namespace node
fb3a9cd @waveto Initial openssl support for net2
waveto authored
277
278 #endif // SRC_NODE_CRYPTO_H_
Something went wrong with that request. Please try again.