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 |
|
|
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
26 |
|
|
|
27 |
|
|
// ClientHelloParser |
28 |
|
|
#include "node_crypto_clienthello.h" |
29 |
|
|
|
30 |
|
|
#include "env.h" |
31 |
|
|
#include "base_object.h" |
32 |
|
|
#include "util.h" |
33 |
|
|
|
34 |
|
|
#include "v8.h" |
35 |
|
|
|
36 |
|
|
#include <openssl/err.h> |
37 |
|
|
#include <openssl/ssl.h> |
38 |
|
|
|
39 |
|
|
namespace node { |
40 |
|
|
namespace crypto { |
41 |
|
|
|
42 |
|
|
// Forcibly clear OpenSSL's error stack on return. This stops stale errors |
43 |
|
|
// from popping up later in the lifecycle of crypto operations where they |
44 |
|
|
// would cause spurious failures. It's a rather blunt method, though. |
45 |
|
|
// ERR_clear_error() isn't necessarily cheap either. |
46 |
|
|
struct ClearErrorOnReturn { |
47 |
|
12762 |
~ClearErrorOnReturn() { ERR_clear_error(); } |
48 |
|
|
}; |
49 |
|
|
|
50 |
|
|
// Pop errors from OpenSSL's error stack that were added |
51 |
|
|
// between when this was constructed and destructed. |
52 |
|
|
struct MarkPopErrorOnReturn { |
53 |
|
18708 |
MarkPopErrorOnReturn() { ERR_set_mark(); } |
54 |
|
18707 |
~MarkPopErrorOnReturn() { ERR_pop_to_mark(); } |
55 |
|
|
}; |
56 |
|
|
|
57 |
|
|
// Define smart pointers for the most commonly used OpenSSL types: |
58 |
|
|
using X509Pointer = DeleteFnPtr<X509, X509_free>; |
59 |
|
|
using BIOPointer = DeleteFnPtr<BIO, BIO_free_all>; |
60 |
|
|
using SSLCtxPointer = DeleteFnPtr<SSL_CTX, SSL_CTX_free>; |
61 |
|
|
using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>; |
62 |
|
|
using SSLPointer = DeleteFnPtr<SSL, SSL_free>; |
63 |
|
|
using PKCS8Pointer = DeleteFnPtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>; |
64 |
|
|
using EVPKeyPointer = DeleteFnPtr<EVP_PKEY, EVP_PKEY_free>; |
65 |
|
|
using EVPKeyCtxPointer = DeleteFnPtr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>; |
66 |
|
|
using EVPMDPointer = DeleteFnPtr<EVP_MD_CTX, EVP_MD_CTX_free>; |
67 |
|
|
using RSAPointer = DeleteFnPtr<RSA, RSA_free>; |
68 |
|
|
using ECPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>; |
69 |
|
|
using BignumPointer = DeleteFnPtr<BIGNUM, BN_free>; |
70 |
|
|
using NetscapeSPKIPointer = DeleteFnPtr<NETSCAPE_SPKI, NETSCAPE_SPKI_free>; |
71 |
|
|
using ECGroupPointer = DeleteFnPtr<EC_GROUP, EC_GROUP_free>; |
72 |
|
|
using ECPointPointer = DeleteFnPtr<EC_POINT, EC_POINT_free>; |
73 |
|
|
using ECKeyPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>; |
74 |
|
|
using DHPointer = DeleteFnPtr<DH, DH_free>; |
75 |
|
|
|
76 |
|
|
extern int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx); |
77 |
|
|
|
78 |
|
|
extern void UseExtraCaCerts(const std::string& file); |
79 |
|
|
|
80 |
|
|
void InitCryptoOnce(); |
81 |
|
|
|
82 |
|
|
class SecureContext : public BaseObject { |
83 |
|
|
public: |
84 |
|
6930 |
~SecureContext() override { |
85 |
|
2310 |
Reset(); |
86 |
✗✓ |
4620 |
} |
87 |
|
|
|
88 |
|
|
static void Initialize(Environment* env, v8::Local<v8::Object> target); |
89 |
|
|
|
90 |
|
|
// TODO(joyeecheung): track the memory used by OpenSSL types |
91 |
|
3 |
SET_NO_MEMORY_INFO() |
92 |
|
3 |
SET_MEMORY_INFO_NAME(SecureContext) |
93 |
|
3 |
SET_SELF_SIZE(SecureContext) |
94 |
|
|
|
95 |
|
|
SSLCtxPointer ctx_; |
96 |
|
|
X509Pointer cert_; |
97 |
|
|
X509Pointer issuer_; |
98 |
|
|
#ifndef OPENSSL_NO_ENGINE |
99 |
|
|
bool client_cert_engine_provided_ = false; |
100 |
|
|
#endif // !OPENSSL_NO_ENGINE |
101 |
|
|
|
102 |
|
|
static const int kMaxSessionSize = 10 * 1024; |
103 |
|
|
|
104 |
|
|
// See TicketKeyCallback |
105 |
|
|
static const int kTicketKeyReturnIndex = 0; |
106 |
|
|
static const int kTicketKeyHMACIndex = 1; |
107 |
|
|
static const int kTicketKeyAESIndex = 2; |
108 |
|
|
static const int kTicketKeyNameIndex = 3; |
109 |
|
|
static const int kTicketKeyIVIndex = 4; |
110 |
|
|
|
111 |
|
|
unsigned char ticket_key_name_[16]; |
112 |
|
|
unsigned char ticket_key_aes_[16]; |
113 |
|
|
unsigned char ticket_key_hmac_[16]; |
114 |
|
|
|
115 |
|
|
protected: |
116 |
|
|
// OpenSSL structures are opaque. This is sizeof(SSL_CTX) for OpenSSL 1.1.1b: |
117 |
|
|
static const int64_t kExternalSize = 1024; |
118 |
|
|
|
119 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
120 |
|
|
static void Init(const v8::FunctionCallbackInfo<v8::Value>& args); |
121 |
|
|
static void SetKey(const v8::FunctionCallbackInfo<v8::Value>& args); |
122 |
|
|
static void SetCert(const v8::FunctionCallbackInfo<v8::Value>& args); |
123 |
|
|
static void AddCACert(const v8::FunctionCallbackInfo<v8::Value>& args); |
124 |
|
|
static void AddCRL(const v8::FunctionCallbackInfo<v8::Value>& args); |
125 |
|
|
static void AddRootCerts(const v8::FunctionCallbackInfo<v8::Value>& args); |
126 |
|
|
static void SetCipherSuites(const v8::FunctionCallbackInfo<v8::Value>& args); |
127 |
|
|
static void SetCiphers(const v8::FunctionCallbackInfo<v8::Value>& args); |
128 |
|
|
static void SetSigalgs(const v8::FunctionCallbackInfo<v8::Value>& args); |
129 |
|
|
static void SetECDHCurve(const v8::FunctionCallbackInfo<v8::Value>& args); |
130 |
|
|
static void SetDHParam(const v8::FunctionCallbackInfo<v8::Value>& args); |
131 |
|
|
static void SetOptions(const v8::FunctionCallbackInfo<v8::Value>& args); |
132 |
|
|
static void SetSessionIdContext( |
133 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
134 |
|
|
static void SetSessionTimeout( |
135 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
136 |
|
|
static void SetMinProto(const v8::FunctionCallbackInfo<v8::Value>& args); |
137 |
|
|
static void SetMaxProto(const v8::FunctionCallbackInfo<v8::Value>& args); |
138 |
|
|
static void GetMinProto(const v8::FunctionCallbackInfo<v8::Value>& args); |
139 |
|
|
static void GetMaxProto(const v8::FunctionCallbackInfo<v8::Value>& args); |
140 |
|
|
static void Close(const v8::FunctionCallbackInfo<v8::Value>& args); |
141 |
|
|
static void LoadPKCS12(const v8::FunctionCallbackInfo<v8::Value>& args); |
142 |
|
|
#ifndef OPENSSL_NO_ENGINE |
143 |
|
|
static void SetClientCertEngine( |
144 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
145 |
|
|
#endif // !OPENSSL_NO_ENGINE |
146 |
|
|
static void GetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args); |
147 |
|
|
static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args); |
148 |
|
|
static void SetFreeListLength( |
149 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
150 |
|
|
static void EnableTicketKeyCallback( |
151 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
152 |
|
|
static void CtxGetter(const v8::FunctionCallbackInfo<v8::Value>& info); |
153 |
|
|
|
154 |
|
|
template <bool primary> |
155 |
|
|
static void GetCertificate(const v8::FunctionCallbackInfo<v8::Value>& args); |
156 |
|
|
|
157 |
|
|
static int TicketKeyCallback(SSL* ssl, |
158 |
|
|
unsigned char* name, |
159 |
|
|
unsigned char* iv, |
160 |
|
|
EVP_CIPHER_CTX* ectx, |
161 |
|
|
HMAC_CTX* hctx, |
162 |
|
|
int enc); |
163 |
|
|
|
164 |
|
|
static int TicketCompatibilityCallback(SSL* ssl, |
165 |
|
|
unsigned char* name, |
166 |
|
|
unsigned char* iv, |
167 |
|
|
EVP_CIPHER_CTX* ectx, |
168 |
|
|
HMAC_CTX* hctx, |
169 |
|
|
int enc); |
170 |
|
|
|
171 |
|
2336 |
SecureContext(Environment* env, v8::Local<v8::Object> wrap) |
172 |
|
2336 |
: BaseObject(env, wrap) { |
173 |
|
2336 |
MakeWeak(); |
174 |
|
2336 |
env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize); |
175 |
|
2336 |
} |
176 |
|
|
|
177 |
|
3628 |
inline void Reset() { |
178 |
✓✓ |
3628 |
if (ctx_ != nullptr) { |
179 |
|
2267 |
env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize); |
180 |
|
|
} |
181 |
|
3628 |
ctx_.reset(); |
182 |
|
3628 |
cert_.reset(); |
183 |
|
3628 |
issuer_.reset(); |
184 |
|
3628 |
} |
185 |
|
|
}; |
186 |
|
|
|
187 |
|
|
// SSLWrap implicitly depends on the inheriting class' handle having an |
188 |
|
|
// internal pointer to the Base class. |
189 |
|
|
template <class Base> |
190 |
|
|
class SSLWrap { |
191 |
|
|
public: |
192 |
|
|
enum Kind { |
193 |
|
|
kClient, |
194 |
|
|
kServer |
195 |
|
|
}; |
196 |
|
|
|
197 |
|
12243 |
SSLWrap(Environment* env, SecureContext* sc, Kind kind) |
198 |
|
|
: env_(env), |
199 |
|
|
kind_(kind), |
200 |
|
|
next_sess_(nullptr), |
201 |
|
|
session_callbacks_(false), |
202 |
|
|
awaiting_new_session_(false), |
203 |
|
|
cert_cb_(nullptr), |
204 |
|
|
cert_cb_arg_(nullptr), |
205 |
|
24486 |
cert_cb_running_(false) { |
206 |
|
12243 |
ssl_.reset(SSL_new(sc->ctx_.get())); |
207 |
✗✓ |
12243 |
CHECK(ssl_); |
208 |
|
12243 |
env_->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize); |
209 |
|
12243 |
} |
210 |
|
|
|
211 |
|
12175 |
virtual ~SSLWrap() { |
212 |
|
12175 |
DestroySSL(); |
213 |
✗✓ |
48700 |
} |
214 |
|
|
|
215 |
|
263 |
inline void enable_session_callbacks() { session_callbacks_ = true; } |
216 |
|
39308 |
inline bool is_server() const { return kind_ == kServer; } |
217 |
|
13474 |
inline bool is_client() const { return kind_ == kClient; } |
218 |
|
16430 |
inline bool is_awaiting_new_session() const { return awaiting_new_session_; } |
219 |
|
866 |
inline bool is_waiting_cert_cb() const { return cert_cb_ != nullptr; } |
220 |
|
|
|
221 |
|
|
protected: |
222 |
|
|
typedef void (*CertCb)(void* arg); |
223 |
|
|
|
224 |
|
|
// OpenSSL structures are opaque. Estimate SSL memory size for OpenSSL 1.1.1b: |
225 |
|
|
// SSL: 6224 |
226 |
|
|
// SSL->SSL3_STATE: 1040 |
227 |
|
|
// ...some buffers: 42 * 1024 |
228 |
|
|
// NOTE: Actually it is much more than this |
229 |
|
|
static const int64_t kExternalSize = 6224 + 1040 + 42 * 1024; |
230 |
|
|
|
231 |
|
|
static void ConfigureSecureContext(SecureContext* sc); |
232 |
|
|
static void AddMethods(Environment* env, v8::Local<v8::FunctionTemplate> t); |
233 |
|
|
|
234 |
|
|
static SSL_SESSION* GetSessionCallback(SSL* s, |
235 |
|
|
const unsigned char* key, |
236 |
|
|
int len, |
237 |
|
|
int* copy); |
238 |
|
|
static int NewSessionCallback(SSL* s, SSL_SESSION* sess); |
239 |
|
|
static void KeylogCallback(const SSL* s, const char* line); |
240 |
|
|
static void OnClientHello(void* arg, |
241 |
|
|
const ClientHelloParser::ClientHello& hello); |
242 |
|
|
|
243 |
|
|
static void GetPeerCertificate( |
244 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
245 |
|
|
static void GetCertificate(const v8::FunctionCallbackInfo<v8::Value>& args); |
246 |
|
|
static void GetFinished(const v8::FunctionCallbackInfo<v8::Value>& args); |
247 |
|
|
static void GetPeerFinished(const v8::FunctionCallbackInfo<v8::Value>& args); |
248 |
|
|
static void GetSession(const v8::FunctionCallbackInfo<v8::Value>& args); |
249 |
|
|
static void SetSession(const v8::FunctionCallbackInfo<v8::Value>& args); |
250 |
|
|
static void LoadSession(const v8::FunctionCallbackInfo<v8::Value>& args); |
251 |
|
|
static void IsSessionReused(const v8::FunctionCallbackInfo<v8::Value>& args); |
252 |
|
|
static void VerifyError(const v8::FunctionCallbackInfo<v8::Value>& args); |
253 |
|
|
static void GetCipher(const v8::FunctionCallbackInfo<v8::Value>& args); |
254 |
|
|
static void GetSharedSigalgs(const v8::FunctionCallbackInfo<v8::Value>& args); |
255 |
|
|
static void EndParser(const v8::FunctionCallbackInfo<v8::Value>& args); |
256 |
|
|
static void CertCbDone(const v8::FunctionCallbackInfo<v8::Value>& args); |
257 |
|
|
static void Renegotiate(const v8::FunctionCallbackInfo<v8::Value>& args); |
258 |
|
|
static void GetTLSTicket(const v8::FunctionCallbackInfo<v8::Value>& args); |
259 |
|
|
static void NewSessionDone(const v8::FunctionCallbackInfo<v8::Value>& args); |
260 |
|
|
static void SetOCSPResponse(const v8::FunctionCallbackInfo<v8::Value>& args); |
261 |
|
|
static void RequestOCSP(const v8::FunctionCallbackInfo<v8::Value>& args); |
262 |
|
|
static void GetEphemeralKeyInfo( |
263 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
264 |
|
|
static void GetProtocol(const v8::FunctionCallbackInfo<v8::Value>& args); |
265 |
|
|
|
266 |
|
|
#ifdef SSL_set_max_send_fragment |
267 |
|
|
static void SetMaxSendFragment( |
268 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
269 |
|
|
#endif // SSL_set_max_send_fragment |
270 |
|
|
|
271 |
|
|
static void GetALPNNegotiatedProto( |
272 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
273 |
|
|
static void SetALPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args); |
274 |
|
|
static int SelectALPNCallback(SSL* s, |
275 |
|
|
const unsigned char** out, |
276 |
|
|
unsigned char* outlen, |
277 |
|
|
const unsigned char* in, |
278 |
|
|
unsigned int inlen, |
279 |
|
|
void* arg); |
280 |
|
|
static int TLSExtStatusCallback(SSL* s, void* arg); |
281 |
|
|
static int SSLCertCallback(SSL* s, void* arg); |
282 |
|
|
|
283 |
|
|
void DestroySSL(); |
284 |
|
|
void WaitForCertCb(CertCb cb, void* arg); |
285 |
|
|
void SetSNIContext(SecureContext* sc); |
286 |
|
|
int SetCACerts(SecureContext* sc); |
287 |
|
|
|
288 |
|
2263 |
inline Environment* ssl_env() const { |
289 |
|
2263 |
return env_; |
290 |
|
|
} |
291 |
|
|
|
292 |
|
|
Environment* const env_; |
293 |
|
|
Kind kind_; |
294 |
|
|
SSLSessionPointer next_sess_; |
295 |
|
|
SSLPointer ssl_; |
296 |
|
|
bool session_callbacks_; |
297 |
|
|
bool awaiting_new_session_; |
298 |
|
|
|
299 |
|
|
// SSL_set_cert_cb |
300 |
|
|
CertCb cert_cb_; |
301 |
|
|
void* cert_cb_arg_; |
302 |
|
|
bool cert_cb_running_; |
303 |
|
|
|
304 |
|
|
ClientHelloParser hello_parser_; |
305 |
|
|
|
306 |
|
|
v8::Global<v8::ArrayBufferView> ocsp_response_; |
307 |
|
|
v8::Global<v8::Value> sni_context_; |
308 |
|
|
|
309 |
|
|
friend class SecureContext; |
310 |
|
|
}; |
311 |
|
|
|
312 |
|
|
// A helper class representing a read-only byte array. When deallocated, its |
313 |
|
|
// contents are zeroed. |
314 |
|
|
class ByteSource { |
315 |
|
|
public: |
316 |
|
1271 |
ByteSource() = default; |
317 |
|
|
ByteSource(ByteSource&& other); |
318 |
|
|
~ByteSource(); |
319 |
|
|
|
320 |
|
|
ByteSource& operator=(ByteSource&& other); |
321 |
|
|
|
322 |
|
|
const char* get() const; |
323 |
|
|
size_t size() const; |
324 |
|
|
|
325 |
|
|
static ByteSource FromStringOrBuffer(Environment* env, |
326 |
|
|
v8::Local<v8::Value> value); |
327 |
|
|
|
328 |
|
|
static ByteSource FromString(Environment* env, |
329 |
|
|
v8::Local<v8::String> str, |
330 |
|
|
bool ntc = false); |
331 |
|
|
|
332 |
|
|
static ByteSource FromBuffer(v8::Local<v8::Value> buffer, |
333 |
|
|
bool ntc = false); |
334 |
|
|
|
335 |
|
|
static ByteSource NullTerminatedCopy(Environment* env, |
336 |
|
|
v8::Local<v8::Value> value); |
337 |
|
|
|
338 |
|
|
static ByteSource FromSymmetricKeyObject(v8::Local<v8::Value> handle); |
339 |
|
|
|
340 |
|
|
ByteSource(const ByteSource&) = delete; |
341 |
|
|
ByteSource& operator=(const ByteSource&) = delete; |
342 |
|
|
|
343 |
|
|
private: |
344 |
|
|
const char* data_ = nullptr; |
345 |
|
|
char* allocated_data_ = nullptr; |
346 |
|
|
size_t size_ = 0; |
347 |
|
|
|
348 |
|
|
ByteSource(const char* data, char* allocated_data, size_t size); |
349 |
|
|
|
350 |
|
|
static ByteSource Allocated(char* data, size_t size); |
351 |
|
|
static ByteSource Foreign(const char* data, size_t size); |
352 |
|
|
}; |
353 |
|
|
|
354 |
|
|
enum PKEncodingType { |
355 |
|
|
// RSAPublicKey / RSAPrivateKey according to PKCS#1. |
356 |
|
|
kKeyEncodingPKCS1, |
357 |
|
|
// PrivateKeyInfo or EncryptedPrivateKeyInfo according to PKCS#8. |
358 |
|
|
kKeyEncodingPKCS8, |
359 |
|
|
// SubjectPublicKeyInfo according to X.509. |
360 |
|
|
kKeyEncodingSPKI, |
361 |
|
|
// ECPrivateKey according to SEC1. |
362 |
|
|
kKeyEncodingSEC1 |
363 |
|
|
}; |
364 |
|
|
|
365 |
|
|
enum PKFormatType { |
366 |
|
|
kKeyFormatDER, |
367 |
|
|
kKeyFormatPEM |
368 |
|
|
}; |
369 |
|
|
|
370 |
|
1304 |
struct AsymmetricKeyEncodingConfig { |
371 |
|
|
bool output_key_object_; |
372 |
|
|
PKFormatType format_; |
373 |
|
|
v8::Maybe<PKEncodingType> type_ = v8::Nothing<PKEncodingType>(); |
374 |
|
|
}; |
375 |
|
|
|
376 |
|
|
typedef AsymmetricKeyEncodingConfig PublicKeyEncodingConfig; |
377 |
|
|
|
378 |
|
7270 |
struct PrivateKeyEncodingConfig : public AsymmetricKeyEncodingConfig { |
379 |
|
|
const EVP_CIPHER* cipher_; |
380 |
|
|
ByteSource passphrase_; |
381 |
|
|
}; |
382 |
|
|
|
383 |
|
|
enum KeyType { |
384 |
|
|
kKeyTypeSecret, |
385 |
|
|
kKeyTypePublic, |
386 |
|
|
kKeyTypePrivate |
387 |
|
|
}; |
388 |
|
|
|
389 |
|
|
// This uses the built-in reference counter of OpenSSL to manage an EVP_PKEY |
390 |
|
|
// which is slightly more efficient than using a shared pointer and easier to |
391 |
|
|
// use. |
392 |
|
1533 |
class ManagedEVPPKey { |
393 |
|
|
public: |
394 |
|
64 |
ManagedEVPPKey() = default; |
395 |
|
|
explicit ManagedEVPPKey(EVPKeyPointer&& pkey); |
396 |
|
|
ManagedEVPPKey(const ManagedEVPPKey& that); |
397 |
|
|
ManagedEVPPKey& operator=(const ManagedEVPPKey& that); |
398 |
|
|
|
399 |
|
|
operator bool() const; |
400 |
|
|
EVP_PKEY* get() const; |
401 |
|
|
|
402 |
|
|
private: |
403 |
|
|
EVPKeyPointer pkey_; |
404 |
|
|
}; |
405 |
|
|
|
406 |
✗✓ |
128 |
class KeyObject : public BaseObject { |
407 |
|
|
public: |
408 |
|
|
static v8::Local<v8::Function> Initialize(Environment* env, |
409 |
|
|
v8::Local<v8::Object> target); |
410 |
|
|
|
411 |
|
|
static v8::MaybeLocal<v8::Object> Create(Environment* env, |
412 |
|
|
KeyType type, |
413 |
|
|
const ManagedEVPPKey& pkey); |
414 |
|
|
|
415 |
|
|
// TODO(tniessen): track the memory used by OpenSSL types |
416 |
|
|
SET_NO_MEMORY_INFO() |
417 |
|
|
SET_MEMORY_INFO_NAME(KeyObject) |
418 |
|
|
SET_SELF_SIZE(KeyObject) |
419 |
|
|
|
420 |
|
|
KeyType GetKeyType() const; |
421 |
|
|
|
422 |
|
|
// These functions allow unprotected access to the raw key material and should |
423 |
|
|
// only be used to implement cryptograohic operations requiring the key. |
424 |
|
|
ManagedEVPPKey GetAsymmetricKey() const; |
425 |
|
|
const char* GetSymmetricKey() const; |
426 |
|
|
size_t GetSymmetricKeySize() const; |
427 |
|
|
|
428 |
|
|
protected: |
429 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
430 |
|
|
|
431 |
|
|
static void Init(const v8::FunctionCallbackInfo<v8::Value>& args); |
432 |
|
|
void InitSecret(v8::Local<v8::ArrayBufferView> abv); |
433 |
|
|
void InitPublic(const ManagedEVPPKey& pkey); |
434 |
|
|
void InitPrivate(const ManagedEVPPKey& pkey); |
435 |
|
|
|
436 |
|
|
static void GetAsymmetricKeyType( |
437 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
438 |
|
|
v8::Local<v8::Value> GetAsymmetricKeyType() const; |
439 |
|
|
|
440 |
|
|
static void GetSymmetricKeySize( |
441 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
442 |
|
|
|
443 |
|
|
static void Export(const v8::FunctionCallbackInfo<v8::Value>& args); |
444 |
|
|
v8::Local<v8::Value> ExportSecretKey() const; |
445 |
|
|
v8::MaybeLocal<v8::Value> ExportPublicKey( |
446 |
|
|
const PublicKeyEncodingConfig& config) const; |
447 |
|
|
v8::MaybeLocal<v8::Value> ExportPrivateKey( |
448 |
|
|
const PrivateKeyEncodingConfig& config) const; |
449 |
|
|
|
450 |
|
64 |
KeyObject(Environment* env, |
451 |
|
|
v8::Local<v8::Object> wrap, |
452 |
|
|
KeyType key_type) |
453 |
|
|
: BaseObject(env, wrap), |
454 |
|
|
key_type_(key_type), |
455 |
|
64 |
symmetric_key_(nullptr, nullptr) { |
456 |
|
64 |
MakeWeak(); |
457 |
|
64 |
} |
458 |
|
|
|
459 |
|
|
private: |
460 |
|
|
const KeyType key_type_; |
461 |
|
|
std::unique_ptr<char, std::function<void(char*)>> symmetric_key_; |
462 |
|
|
unsigned int symmetric_key_len_; |
463 |
|
|
ManagedEVPPKey asymmetric_key_; |
464 |
|
|
}; |
465 |
|
|
|
466 |
✗✓ |
2514 |
class CipherBase : public BaseObject { |
467 |
|
|
public: |
468 |
|
|
static void Initialize(Environment* env, v8::Local<v8::Object> target); |
469 |
|
|
|
470 |
|
|
// TODO(joyeecheung): track the memory used by OpenSSL types |
471 |
|
|
SET_NO_MEMORY_INFO() |
472 |
|
|
SET_MEMORY_INFO_NAME(CipherBase) |
473 |
|
|
SET_SELF_SIZE(CipherBase) |
474 |
|
|
|
475 |
|
|
protected: |
476 |
|
|
enum CipherKind { |
477 |
|
|
kCipher, |
478 |
|
|
kDecipher |
479 |
|
|
}; |
480 |
|
|
enum UpdateResult { |
481 |
|
|
kSuccess, |
482 |
|
|
kErrorMessageSize, |
483 |
|
|
kErrorState |
484 |
|
|
}; |
485 |
|
|
enum AuthTagState { |
486 |
|
|
kAuthTagUnknown, |
487 |
|
|
kAuthTagKnown, |
488 |
|
|
kAuthTagPassedToOpenSSL |
489 |
|
|
}; |
490 |
|
|
static const unsigned kNoAuthTagLength = static_cast<unsigned>(-1); |
491 |
|
|
|
492 |
|
|
void CommonInit(const char* cipher_type, |
493 |
|
|
const EVP_CIPHER* cipher, |
494 |
|
|
const unsigned char* key, |
495 |
|
|
int key_len, |
496 |
|
|
const unsigned char* iv, |
497 |
|
|
int iv_len, |
498 |
|
|
unsigned int auth_tag_len); |
499 |
|
|
void Init(const char* cipher_type, |
500 |
|
|
const char* key_buf, |
501 |
|
|
int key_buf_len, |
502 |
|
|
unsigned int auth_tag_len); |
503 |
|
|
void InitIv(const char* cipher_type, |
504 |
|
|
const unsigned char* key, |
505 |
|
|
int key_len, |
506 |
|
|
const unsigned char* iv, |
507 |
|
|
int iv_len, |
508 |
|
|
unsigned int auth_tag_len); |
509 |
|
|
bool InitAuthenticated(const char* cipher_type, int iv_len, |
510 |
|
|
unsigned int auth_tag_len); |
511 |
|
|
bool CheckCCMMessageLength(int message_len); |
512 |
|
|
UpdateResult Update(const char* data, int len, AllocatedBuffer* out); |
513 |
|
|
bool Final(AllocatedBuffer* out); |
514 |
|
|
bool SetAutoPadding(bool auto_padding); |
515 |
|
|
|
516 |
|
|
bool IsAuthenticatedMode() const; |
517 |
|
|
bool SetAAD(const char* data, unsigned int len, int plaintext_len); |
518 |
|
|
bool MaybePassAuthTagToOpenSSL(); |
519 |
|
|
|
520 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
521 |
|
|
static void Init(const v8::FunctionCallbackInfo<v8::Value>& args); |
522 |
|
|
static void InitIv(const v8::FunctionCallbackInfo<v8::Value>& args); |
523 |
|
|
static void Update(const v8::FunctionCallbackInfo<v8::Value>& args); |
524 |
|
|
static void Final(const v8::FunctionCallbackInfo<v8::Value>& args); |
525 |
|
|
static void SetAutoPadding(const v8::FunctionCallbackInfo<v8::Value>& args); |
526 |
|
|
|
527 |
|
|
static void GetAuthTag(const v8::FunctionCallbackInfo<v8::Value>& args); |
528 |
|
|
static void SetAuthTag(const v8::FunctionCallbackInfo<v8::Value>& args); |
529 |
|
|
static void SetAAD(const v8::FunctionCallbackInfo<v8::Value>& args); |
530 |
|
|
|
531 |
|
1257 |
CipherBase(Environment* env, |
532 |
|
|
v8::Local<v8::Object> wrap, |
533 |
|
|
CipherKind kind) |
534 |
|
|
: BaseObject(env, wrap), |
535 |
|
|
ctx_(nullptr), |
536 |
|
|
kind_(kind), |
537 |
|
|
auth_tag_state_(kAuthTagUnknown), |
538 |
|
|
auth_tag_len_(kNoAuthTagLength), |
539 |
|
1257 |
pending_auth_failed_(false) { |
540 |
|
1257 |
MakeWeak(); |
541 |
|
1257 |
} |
542 |
|
|
|
543 |
|
|
private: |
544 |
|
|
DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> ctx_; |
545 |
|
|
const CipherKind kind_; |
546 |
|
|
AuthTagState auth_tag_state_; |
547 |
|
|
unsigned int auth_tag_len_; |
548 |
|
|
char auth_tag_[EVP_GCM_TLS_TAG_LEN]; |
549 |
|
|
bool pending_auth_failed_; |
550 |
|
|
int max_message_size_; |
551 |
|
|
}; |
552 |
|
|
|
553 |
✗✓ |
322 |
class Hmac : public BaseObject { |
554 |
|
|
public: |
555 |
|
|
static void Initialize(Environment* env, v8::Local<v8::Object> target); |
556 |
|
|
|
557 |
|
|
// TODO(joyeecheung): track the memory used by OpenSSL types |
558 |
|
|
SET_NO_MEMORY_INFO() |
559 |
|
|
SET_MEMORY_INFO_NAME(Hmac) |
560 |
|
|
SET_SELF_SIZE(Hmac) |
561 |
|
|
|
562 |
|
|
protected: |
563 |
|
|
void HmacInit(const char* hash_type, const char* key, int key_len); |
564 |
|
|
bool HmacUpdate(const char* data, int len); |
565 |
|
|
|
566 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
567 |
|
|
static void HmacInit(const v8::FunctionCallbackInfo<v8::Value>& args); |
568 |
|
|
static void HmacUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); |
569 |
|
|
static void HmacDigest(const v8::FunctionCallbackInfo<v8::Value>& args); |
570 |
|
|
|
571 |
|
161 |
Hmac(Environment* env, v8::Local<v8::Object> wrap) |
572 |
|
|
: BaseObject(env, wrap), |
573 |
|
161 |
ctx_(nullptr) { |
574 |
|
161 |
MakeWeak(); |
575 |
|
161 |
} |
576 |
|
|
|
577 |
|
|
private: |
578 |
|
|
DeleteFnPtr<HMAC_CTX, HMAC_CTX_free> ctx_; |
579 |
|
|
}; |
580 |
|
|
|
581 |
|
|
class Hash : public BaseObject { |
582 |
|
|
public: |
583 |
|
|
static void Initialize(Environment* env, v8::Local<v8::Object> target); |
584 |
|
|
|
585 |
|
|
// TODO(joyeecheung): track the memory used by OpenSSL types |
586 |
|
|
SET_NO_MEMORY_INFO() |
587 |
|
|
SET_MEMORY_INFO_NAME(Hash) |
588 |
|
|
SET_SELF_SIZE(Hash) |
589 |
|
|
|
590 |
|
|
bool HashInit(const char* hash_type, v8::Maybe<unsigned int> xof_md_len); |
591 |
|
|
bool HashUpdate(const char* data, int len); |
592 |
|
|
|
593 |
|
|
protected: |
594 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
595 |
|
|
static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); |
596 |
|
|
static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args); |
597 |
|
|
|
598 |
|
402704 |
Hash(Environment* env, v8::Local<v8::Object> wrap) |
599 |
|
|
: BaseObject(env, wrap), |
600 |
|
|
mdctx_(nullptr), |
601 |
|
|
has_md_(false), |
602 |
|
402704 |
md_value_(nullptr) { |
603 |
|
402704 |
MakeWeak(); |
604 |
|
402704 |
} |
605 |
|
|
|
606 |
|
1207845 |
~Hash() override { |
607 |
✓✓ |
402615 |
if (md_value_ != nullptr) |
608 |
|
402597 |
OPENSSL_clear_free(md_value_, md_len_); |
609 |
✗✓ |
805230 |
} |
610 |
|
|
|
611 |
|
|
private: |
612 |
|
|
EVPMDPointer mdctx_; |
613 |
|
|
bool has_md_; |
614 |
|
|
unsigned int md_len_; |
615 |
|
|
unsigned char* md_value_; |
616 |
|
|
}; |
617 |
|
|
|
618 |
✗✓ |
715 |
class SignBase : public BaseObject { |
619 |
|
|
public: |
620 |
|
|
typedef enum { |
621 |
|
|
kSignOk, |
622 |
|
|
kSignUnknownDigest, |
623 |
|
|
kSignInit, |
624 |
|
|
kSignNotInitialised, |
625 |
|
|
kSignUpdate, |
626 |
|
|
kSignPrivateKey, |
627 |
|
|
kSignPublicKey |
628 |
|
|
} Error; |
629 |
|
|
|
630 |
|
715 |
SignBase(Environment* env, v8::Local<v8::Object> wrap) |
631 |
|
715 |
: BaseObject(env, wrap) { |
632 |
|
715 |
} |
633 |
|
|
|
634 |
|
|
Error Init(const char* sign_type); |
635 |
|
|
Error Update(const char* data, int len); |
636 |
|
|
|
637 |
|
|
// TODO(joyeecheung): track the memory used by OpenSSL types |
638 |
|
|
SET_NO_MEMORY_INFO() |
639 |
|
|
SET_MEMORY_INFO_NAME(SignBase) |
640 |
|
|
SET_SELF_SIZE(SignBase) |
641 |
|
|
|
642 |
|
|
protected: |
643 |
|
|
void CheckThrow(Error error); |
644 |
|
|
|
645 |
|
|
EVPMDPointer mdctx_; |
646 |
|
|
}; |
647 |
|
|
|
648 |
✗✓ |
270 |
class Sign : public SignBase { |
649 |
|
|
public: |
650 |
|
|
static void Initialize(Environment* env, v8::Local<v8::Object> target); |
651 |
|
|
|
652 |
|
112 |
struct SignResult { |
653 |
|
|
Error error; |
654 |
|
|
AllocatedBuffer signature; |
655 |
|
|
|
656 |
|
112 |
explicit SignResult( |
657 |
|
|
Error err, |
658 |
|
|
AllocatedBuffer&& sig = AllocatedBuffer()) |
659 |
|
112 |
: error(err), signature(std::move(sig)) {} |
660 |
|
|
}; |
661 |
|
|
|
662 |
|
|
SignResult SignFinal( |
663 |
|
|
const ManagedEVPPKey& pkey, |
664 |
|
|
int padding, |
665 |
|
|
const v8::Maybe<int>& saltlen); |
666 |
|
|
|
667 |
|
|
protected: |
668 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
669 |
|
|
static void SignInit(const v8::FunctionCallbackInfo<v8::Value>& args); |
670 |
|
|
static void SignUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); |
671 |
|
|
static void SignFinal(const v8::FunctionCallbackInfo<v8::Value>& args); |
672 |
|
|
|
673 |
|
135 |
Sign(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) { |
674 |
|
135 |
MakeWeak(); |
675 |
|
135 |
} |
676 |
|
|
}; |
677 |
|
|
|
678 |
✗✓ |
1160 |
class Verify : public SignBase { |
679 |
|
|
public: |
680 |
|
|
static void Initialize(Environment* env, v8::Local<v8::Object> target); |
681 |
|
|
|
682 |
|
|
Error VerifyFinal(const ManagedEVPPKey& key, |
683 |
|
|
const char* sig, |
684 |
|
|
int siglen, |
685 |
|
|
int padding, |
686 |
|
|
const v8::Maybe<int>& saltlen, |
687 |
|
|
bool* verify_result); |
688 |
|
|
|
689 |
|
|
protected: |
690 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
691 |
|
|
static void VerifyInit(const v8::FunctionCallbackInfo<v8::Value>& args); |
692 |
|
|
static void VerifyUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); |
693 |
|
|
static void VerifyFinal(const v8::FunctionCallbackInfo<v8::Value>& args); |
694 |
|
|
|
695 |
|
580 |
Verify(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) { |
696 |
|
580 |
MakeWeak(); |
697 |
|
580 |
} |
698 |
|
|
}; |
699 |
|
|
|
700 |
|
|
class PublicKeyCipher { |
701 |
|
|
public: |
702 |
|
|
typedef int (*EVP_PKEY_cipher_init_t)(EVP_PKEY_CTX* ctx); |
703 |
|
|
typedef int (*EVP_PKEY_cipher_t)(EVP_PKEY_CTX* ctx, |
704 |
|
|
unsigned char* out, size_t* outlen, |
705 |
|
|
const unsigned char* in, size_t inlen); |
706 |
|
|
|
707 |
|
|
enum Operation { |
708 |
|
|
kPublic, |
709 |
|
|
kPrivate |
710 |
|
|
}; |
711 |
|
|
|
712 |
|
|
template <Operation operation, |
713 |
|
|
EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init, |
714 |
|
|
EVP_PKEY_cipher_t EVP_PKEY_cipher> |
715 |
|
|
static bool Cipher(Environment* env, |
716 |
|
|
const ManagedEVPPKey& pkey, |
717 |
|
|
int padding, |
718 |
|
|
const EVP_MD* digest, |
719 |
|
|
const void* oaep_label, |
720 |
|
|
size_t oaep_label_size, |
721 |
|
|
const unsigned char* data, |
722 |
|
|
int len, |
723 |
|
|
AllocatedBuffer* out); |
724 |
|
|
|
725 |
|
|
template <Operation operation, |
726 |
|
|
EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init, |
727 |
|
|
EVP_PKEY_cipher_t EVP_PKEY_cipher> |
728 |
|
|
static void Cipher(const v8::FunctionCallbackInfo<v8::Value>& args); |
729 |
|
|
}; |
730 |
|
|
|
731 |
✗✓ |
8124 |
class DiffieHellman : public BaseObject { |
732 |
|
|
public: |
733 |
|
|
static void Initialize(Environment* env, v8::Local<v8::Object> target); |
734 |
|
|
|
735 |
|
|
bool Init(int primeLength, int g); |
736 |
|
|
bool Init(const char* p, int p_len, int g); |
737 |
|
|
bool Init(const char* p, int p_len, const char* g, int g_len); |
738 |
|
|
|
739 |
|
|
protected: |
740 |
|
|
static void DiffieHellmanGroup( |
741 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
742 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
743 |
|
|
static void GenerateKeys(const v8::FunctionCallbackInfo<v8::Value>& args); |
744 |
|
|
static void GetPrime(const v8::FunctionCallbackInfo<v8::Value>& args); |
745 |
|
|
static void GetGenerator(const v8::FunctionCallbackInfo<v8::Value>& args); |
746 |
|
|
static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args); |
747 |
|
|
static void GetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args); |
748 |
|
|
static void ComputeSecret(const v8::FunctionCallbackInfo<v8::Value>& args); |
749 |
|
|
static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args); |
750 |
|
|
static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args); |
751 |
|
|
static void VerifyErrorGetter( |
752 |
|
|
const v8::FunctionCallbackInfo<v8::Value>& args); |
753 |
|
|
|
754 |
|
4062 |
DiffieHellman(Environment* env, v8::Local<v8::Object> wrap) |
755 |
|
|
: BaseObject(env, wrap), |
756 |
|
4062 |
verifyError_(0) { |
757 |
|
4062 |
MakeWeak(); |
758 |
|
4062 |
} |
759 |
|
|
|
760 |
|
|
// TODO(joyeecheung): track the memory used by OpenSSL types |
761 |
|
|
SET_NO_MEMORY_INFO() |
762 |
|
|
SET_MEMORY_INFO_NAME(DiffieHellman) |
763 |
|
|
SET_SELF_SIZE(DiffieHellman) |
764 |
|
|
|
765 |
|
|
private: |
766 |
|
|
static void GetField(const v8::FunctionCallbackInfo<v8::Value>& args, |
767 |
|
|
const BIGNUM* (*get_field)(const DH*), |
768 |
|
|
const char* err_if_null); |
769 |
|
|
static void SetKey(const v8::FunctionCallbackInfo<v8::Value>& args, |
770 |
|
|
int (*set_field)(DH*, BIGNUM*), const char* what); |
771 |
|
|
bool VerifyContext(); |
772 |
|
|
|
773 |
|
|
int verifyError_; |
774 |
|
|
DHPointer dh_; |
775 |
|
|
}; |
776 |
|
|
|
777 |
|
|
class ECDH : public BaseObject { |
778 |
|
|
public: |
779 |
|
30 |
~ECDH() override { |
780 |
|
10 |
group_ = nullptr; |
781 |
✗✓ |
20 |
} |
782 |
|
|
|
783 |
|
|
static void Initialize(Environment* env, v8::Local<v8::Object> target); |
784 |
|
|
static ECPointPointer BufferToPoint(Environment* env, |
785 |
|
|
const EC_GROUP* group, |
786 |
|
|
v8::Local<v8::Value> buf); |
787 |
|
|
|
788 |
|
|
// TODO(joyeecheung): track the memory used by OpenSSL types |
789 |
|
|
SET_NO_MEMORY_INFO() |
790 |
|
|
SET_MEMORY_INFO_NAME(ECDH) |
791 |
|
|
SET_SELF_SIZE(ECDH) |
792 |
|
|
|
793 |
|
|
protected: |
794 |
|
10 |
ECDH(Environment* env, v8::Local<v8::Object> wrap, ECKeyPointer&& key) |
795 |
|
|
: BaseObject(env, wrap), |
796 |
|
10 |
key_(std::move(key)), |
797 |
|
20 |
group_(EC_KEY_get0_group(key_.get())) { |
798 |
|
10 |
MakeWeak(); |
799 |
✗✓ |
10 |
CHECK_NOT_NULL(group_); |
800 |
|
10 |
} |
801 |
|
|
|
802 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
803 |
|
|
static void GenerateKeys(const v8::FunctionCallbackInfo<v8::Value>& args); |
804 |
|
|
static void ComputeSecret(const v8::FunctionCallbackInfo<v8::Value>& args); |
805 |
|
|
static void GetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args); |
806 |
|
|
static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args); |
807 |
|
|
static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args); |
808 |
|
|
static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args); |
809 |
|
|
|
810 |
|
|
bool IsKeyPairValid(); |
811 |
|
|
bool IsKeyValidForCurve(const BignumPointer& private_key); |
812 |
|
|
|
813 |
|
|
ECKeyPointer key_; |
814 |
|
|
const EC_GROUP* group_; |
815 |
|
|
}; |
816 |
|
|
|
817 |
|
|
bool EntropySource(unsigned char* buffer, size_t length); |
818 |
|
|
#ifndef OPENSSL_NO_ENGINE |
819 |
|
|
void SetEngine(const v8::FunctionCallbackInfo<v8::Value>& args); |
820 |
|
|
#endif // !OPENSSL_NO_ENGINE |
821 |
|
|
void InitCrypto(v8::Local<v8::Object> target); |
822 |
|
|
|
823 |
|
|
} // namespace crypto |
824 |
|
|
} // namespace node |
825 |
|
|
|
826 |
|
|
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
827 |
|
|
|
828 |
|
|
#endif // SRC_NODE_CRYPTO_H_ |