1 // Copyright Joyent, Inc. and other Node contributors.
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:
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
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.
22 #ifndef SRC_NODE_CRYPTO_H_
23 #define SRC_NODE_CRYPTO_H_
27 #include "node_object_wrap.h"
30 #include <openssl/ssl.h>
31 #include <openssl/err.h>
32 #include <openssl/evp.h>
33 #include <openssl/pem.h>
34 #include <openssl/x509.h>
35 #include <openssl/x509v3.h>
36 #include <openssl/hmac.h>
37 #include <openssl/rand.h>
39 #ifdef OPENSSL_NPN_NEGOTIATED
40 #include "node_buffer.h"
43 #define EVP_F_EVP_DECRYPTFINAL 101
49 static X509_STORE* root_cert_store;
51 class SecureContext : ObjectWrap {
53 static void Initialize(v8::Handle<v8::Object> target);
56 // TODO: ca_store_ should probably be removed, it's not used anywhere.
57 X509_STORE *ca_store_;
60 static v8::Handle<v8::Value> New(const v8::Arguments& args);
61 static v8::Handle<v8::Value> Init(const v8::Arguments& args);
62 static v8::Handle<v8::Value> SetKey(const v8::Arguments& args);
63 static v8::Handle<v8::Value> SetCert(const v8::Arguments& args);
64 static v8::Handle<v8::Value> AddCACert(const v8::Arguments& args);
65 static v8::Handle<v8::Value> AddCRL(const v8::Arguments& args);
66 static v8::Handle<v8::Value> AddRootCerts(const v8::Arguments& args);
67 static v8::Handle<v8::Value> SetCiphers(const v8::Arguments& args);
68 static v8::Handle<v8::Value> SetOptions(const v8::Arguments& args);
69 static v8::Handle<v8::Value> SetSessionIdContext(const v8::Arguments& args);
70 static v8::Handle<v8::Value> Close(const v8::Arguments& args);
72 SecureContext() : ObjectWrap() {
79 if (ctx_->cert_store == root_cert_store) {
80 // SSL_CTX_free() will attempt to free the cert_store as well.
81 // Since we want our root_cert_store to stay around forever
82 // we just clear the field. Hopefully OpenSSL will not modify this
83 // struct in future versions.
84 ctx_->cert_store = NULL;
90 assert(ca_store_ == NULL);
101 class Connection : ObjectWrap {
103 static void Initialize(v8::Handle<v8::Object> target);
105 #ifdef OPENSSL_NPN_NEGOTIATED
106 v8::Persistent<v8::Object> npnProtos_;
107 v8::Persistent<v8::Value> selectedNPNProto_;
110 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
111 v8::Persistent<v8::Function> sniCallback_;
112 v8::Persistent<v8::Value> sniContext_;
113 v8::Persistent<v8::String> servername_;
117 static v8::Handle<v8::Value> New(const v8::Arguments& args);
118 static v8::Handle<v8::Value> EncIn(const v8::Arguments& args);
119 static v8::Handle<v8::Value> ClearOut(const v8::Arguments& args);
120 static v8::Handle<v8::Value> ClearPending(const v8::Arguments& args);
121 static v8::Handle<v8::Value> EncPending(const v8::Arguments& args);
122 static v8::Handle<v8::Value> EncOut(const v8::Arguments& args);
123 static v8::Handle<v8::Value> ClearIn(const v8::Arguments& args);
124 static v8::Handle<v8::Value> GetPeerCertificate(const v8::Arguments& args);
125 static v8::Handle<v8::Value> GetSession(const v8::Arguments& args);
126 static v8::Handle<v8::Value> SetSession(const v8::Arguments& args);
127 static v8::Handle<v8::Value> IsSessionReused(const v8::Arguments& args);
128 static v8::Handle<v8::Value> IsInitFinished(const v8::Arguments& args);
129 static v8::Handle<v8::Value> VerifyError(const v8::Arguments& args);
130 static v8::Handle<v8::Value> GetCurrentCipher(const v8::Arguments& args);
131 static v8::Handle<v8::Value> Shutdown(const v8::Arguments& args);
132 static v8::Handle<v8::Value> ReceivedShutdown(const v8::Arguments& args);
133 static v8::Handle<v8::Value> Start(const v8::Arguments& args);
134 static v8::Handle<v8::Value> Close(const v8::Arguments& args);
136 #ifdef OPENSSL_NPN_NEGOTIATED
138 static v8::Handle<v8::Value> GetNegotiatedProto(const v8::Arguments& args);
139 static v8::Handle<v8::Value> SetNPNProtocols(const v8::Arguments& args);
140 static int AdvertiseNextProtoCallback_(SSL *s,
141 const unsigned char **data,
144 static int SelectNextProtoCallback_(SSL *s,
145 unsigned char **out, unsigned char *outlen,
146 const unsigned char* in,
147 unsigned int inlen, void *arg);
150 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
152 static v8::Handle<v8::Value> GetServername(const v8::Arguments& args);
153 static v8::Handle<v8::Value> SetSNICallback(const v8::Arguments& args);
154 static int SelectSNIContextCallback_(SSL *s, int *ad, void* arg);
157 int HandleBIOError(BIO *bio, const char* func, int rv);
158 int HandleSSLError(const char* func, int rv);
161 void SetShutdownFlags();
163 static Connection* Unwrap(const v8::Arguments& args) {
164 Connection* ss = ObjectWrap::Unwrap<Connection>(args.Holder());
169 Connection() : ObjectWrap() {
170 bio_read_ = bio_write_ = NULL;
180 #ifdef OPENSSL_NPN_NEGOTIATED
181 if (!npnProtos_.IsEmpty()) npnProtos_.Dispose();
182 if (!selectedNPNProto_.IsEmpty()) selectedNPNProto_.Dispose();
185 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
186 if (!sniCallback_.IsEmpty()) sniCallback_.Dispose();
187 if (!sniContext_.IsEmpty()) sniContext_.Dispose();
188 if (!servername_.IsEmpty()) servername_.Dispose();
193 static void SSLInfoCallback(const SSL *ssl, int where, int ret);
199 bool is_server_; /* coverity[member_decl] */
202 void InitCrypto(v8::Handle<v8::Object> target);
204 } // namespace crypto
207 #endif // SRC_NODE_CRYPTO_H_