Skip to content

Commit 755da03

Browse files
jasnellMylesBorins
authored andcommittedMar 4, 2020
src: add node_crypto_common and refactor
Two things in one on this commit: (a) For the QUIC implementation, we need to separate out various bits from node_crypto.cc to allow them to be reused. That's where this commit starts. (b) Quite a bit of the node_crypto.cc code was just messy in terms of it's organization and lack of error handling and use of Local vs. MaybeLocal. This cleans that up a bit and hopefully makes certain parts a bit more manageable also. Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: #32016 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
1 parent 1539928 commit 755da03

8 files changed

+1313
-611
lines changed
 

‎node.gyp

+2
Original file line numberDiff line numberDiff line change
@@ -822,9 +822,11 @@
822822
[ 'node_use_openssl=="true"', {
823823
'sources': [
824824
'src/node_crypto.cc',
825+
'src/node_crypto_common.cc',
825826
'src/node_crypto_bio.cc',
826827
'src/node_crypto_clienthello.cc',
827828
'src/node_crypto.h',
829+
'src/node_crypto_common.h',
828830
'src/node_crypto_bio.h',
829831
'src/node_crypto_clienthello.h',
830832
'src/node_crypto_clienthello-inl.h',

‎src/env.h

+2
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ constexpr size_t kFsStatsBufferLength =
206206
V(dest_string, "dest") \
207207
V(destroyed_string, "destroyed") \
208208
V(detached_string, "detached") \
209+
V(dh_string, "DH") \
209210
V(dns_a_string, "A") \
210211
V(dns_aaaa_string, "AAAA") \
211212
V(dns_cname_string, "CNAME") \
@@ -219,6 +220,7 @@ constexpr size_t kFsStatsBufferLength =
219220
V(done_string, "done") \
220221
V(dot_string, ".") \
221222
V(duration_string, "duration") \
223+
V(ecdh_string, "ECDH") \
222224
V(emit_warning_string, "emitWarning") \
223225
V(empty_object_string, "{}") \
224226
V(encoding_string, "encoding") \

‎src/node_crypto.cc

+27-610
Large diffs are not rendered by default.

‎src/node_crypto.h

+13
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class SecureContext final : public BaseObject {
9090

9191
static void Initialize(Environment* env, v8::Local<v8::Object> target);
9292

93+
SSL_CTX* operator*() const { return ctx_.get(); }
94+
9395
// TODO(joyeecheung): track the memory used by OpenSSL types
9496
SET_NO_MEMORY_INFO()
9597
SET_MEMORY_INFO_NAME(SecureContext)
@@ -779,6 +781,17 @@ void SetEngine(const v8::FunctionCallbackInfo<v8::Value>& args);
779781
#endif // !OPENSSL_NO_ENGINE
780782
void InitCrypto(v8::Local<v8::Object> target);
781783

784+
void ThrowCryptoError(Environment* env,
785+
unsigned long err, // NOLINT(runtime/int)
786+
const char* message = nullptr);
787+
788+
template <typename T>
789+
inline T* MallocOpenSSL(size_t count) {
790+
void* mem = OPENSSL_malloc(MultiplyWithOverflowCheck(count, sizeof(T)));
791+
CHECK_IMPLIES(mem == nullptr, count == 0);
792+
return static_cast<T*>(mem);
793+
}
794+
782795
} // namespace crypto
783796
} // namespace node
784797

‎src/node_crypto_common.cc

+1,110
Large diffs are not rendered by default.

‎src/node_crypto_common.h

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#ifndef SRC_NODE_CRYPTO_COMMON_H_
2+
#define SRC_NODE_CRYPTO_COMMON_H_
3+
4+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5+
6+
#include "env.h"
7+
#include "node_crypto.h"
8+
#include "v8.h"
9+
#include <openssl/ssl.h>
10+
#include <openssl/x509v3.h>
11+
12+
#include <string>
13+
#include <unordered_map>
14+
15+
namespace node {
16+
namespace crypto {
17+
18+
// OPENSSL_free is a macro, so we need a wrapper function.
19+
struct OpenSSLBufferDeleter {
20+
void operator()(char* pointer) const { OPENSSL_free(pointer); }
21+
};
22+
using OpenSSLBuffer = std::unique_ptr<char[], OpenSSLBufferDeleter>;
23+
24+
struct StackOfX509Deleter {
25+
void operator()(STACK_OF(X509)* p) const { sk_X509_pop_free(p, X509_free); }
26+
};
27+
using StackOfX509 = std::unique_ptr<STACK_OF(X509), StackOfX509Deleter>;
28+
29+
struct StackOfXASN1Deleter {
30+
void operator()(STACK_OF(ASN1_OBJECT)* p) const {
31+
sk_ASN1_OBJECT_pop_free(p, ASN1_OBJECT_free);
32+
}
33+
};
34+
using StackOfASN1 = std::unique_ptr<STACK_OF(ASN1_OBJECT), StackOfXASN1Deleter>;
35+
36+
int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer);
37+
38+
void LogSecret(
39+
const SSLPointer& ssl,
40+
const char* name,
41+
const unsigned char* secret,
42+
size_t secretlen);
43+
44+
bool SetALPN(const SSLPointer& ssl, const std::string& alpn);
45+
46+
bool SetALPN(const SSLPointer& ssl, v8::Local<v8::Value> alpn);
47+
48+
v8::MaybeLocal<v8::Value> GetSSLOCSPResponse(
49+
Environment* env,
50+
SSL* ssl,
51+
v8::Local<v8::Value> default_value);
52+
53+
bool SetTLSSession(
54+
const SSLPointer& ssl,
55+
const unsigned char* buf,
56+
size_t length);
57+
58+
bool SetTLSSession(
59+
const SSLPointer& ssl,
60+
const SSLSessionPointer& session);
61+
62+
SSLSessionPointer GetTLSSession(v8::Local<v8::Value> val);
63+
64+
SSLSessionPointer GetTLSSession(const unsigned char* buf, size_t length);
65+
66+
std::unordered_multimap<std::string, std::string>
67+
GetCertificateAltNames(X509* cert);
68+
69+
std::string GetCertificateCN(X509* cert);
70+
71+
long VerifyPeerCertificate( // NOLINT(runtime/int)
72+
const SSLPointer& ssl,
73+
long def = X509_V_ERR_UNSPECIFIED); // NOLINT(runtime/int)
74+
75+
int UseSNIContext(const SSLPointer& ssl, SecureContext* context);
76+
77+
const char* GetClientHelloALPN(const SSLPointer& ssl);
78+
79+
const char* GetClientHelloServerName(const SSLPointer& ssl);
80+
81+
const char* GetServerName(SSL* ssl);
82+
83+
v8::MaybeLocal<v8::Array> GetClientHelloCiphers(
84+
Environment* env,
85+
const SSLPointer& ssl);
86+
87+
bool SetGroups(SecureContext* sc, const char* groups);
88+
89+
const char* X509ErrorCode(long err); // NOLINT(runtime/int)
90+
91+
v8::MaybeLocal<v8::Value> GetValidationErrorReason(Environment* env, int err);
92+
93+
v8::MaybeLocal<v8::Value> GetValidationErrorCode(Environment* env, int err);
94+
95+
v8::MaybeLocal<v8::Value> GetCert(Environment* env, const SSLPointer& ssl);
96+
97+
v8::MaybeLocal<v8::Value> GetCipherName(
98+
Environment* env,
99+
const SSLPointer& ssl);
100+
101+
v8::MaybeLocal<v8::Value> GetCipherStandardName(
102+
Environment* env,
103+
const SSLPointer& ssl);
104+
105+
v8::MaybeLocal<v8::Value> GetCipherVersion(
106+
Environment* env,
107+
const SSLPointer& ssl);
108+
109+
v8::MaybeLocal<v8::Object> GetCipherInfo(
110+
Environment* env,
111+
const SSLPointer& ssl);
112+
113+
v8::MaybeLocal<v8::Object> GetEphemeralKey(
114+
Environment* env,
115+
const SSLPointer& ssl);
116+
117+
v8::MaybeLocal<v8::Value> GetPeerCert(
118+
Environment* env,
119+
const SSLPointer& ssl,
120+
bool abbreviated = false,
121+
bool is_server = false);
122+
123+
v8::MaybeLocal<v8::Object> ECPointToBuffer(
124+
Environment* env,
125+
const EC_GROUP* group,
126+
const EC_POINT* point,
127+
point_conversion_form_t form,
128+
const char** error);
129+
130+
v8::MaybeLocal<v8::Object> X509ToObject(
131+
Environment* env,
132+
X509* cert);
133+
134+
} // namespace crypto
135+
} // namespace node
136+
137+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
138+
139+
#endif // SRC_NODE_CRYPTO_COMMON_H_

‎src/string_bytes.cc

+11-1
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,11 @@ static void force_ascii(const char* src, char* dst, size_t len) {
587587
}
588588

589589

590-
static size_t hex_encode(const char* src, size_t slen, char* dst, size_t dlen) {
590+
size_t StringBytes::hex_encode(
591+
const char* src,
592+
size_t slen,
593+
char* dst,
594+
size_t dlen) {
591595
// We know how much we'll write, just make sure that there's space.
592596
CHECK(dlen >= slen * 2 &&
593597
"not enough space provided for hex encode");
@@ -603,6 +607,12 @@ static size_t hex_encode(const char* src, size_t slen, char* dst, size_t dlen) {
603607
return dlen;
604608
}
605609

610+
std::string StringBytes::hex_encode(const char* src, size_t slen) {
611+
size_t dlen = slen * 2;
612+
std::string dst(dlen, '\0');
613+
hex_encode(src, slen, &dst[0], dlen);
614+
return dst;
615+
}
606616

607617
#define CHECK_BUFLEN_IN_RANGE(len) \
608618
do { \

‎src/string_bytes.h

+9
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "v8.h"
3030
#include "env-inl.h"
3131

32+
#include <string>
33+
3234
namespace node {
3335

3436
class StringBytes {
@@ -97,6 +99,13 @@ class StringBytes {
9799
enum encoding encoding,
98100
v8::Local<v8::Value>* error);
99101

102+
static size_t hex_encode(const char* src,
103+
size_t slen,
104+
char* dst,
105+
size_t dlen);
106+
107+
static std::string hex_encode(const char* src, size_t slen);
108+
100109
private:
101110
static size_t WriteUCS2(v8::Isolate* isolate,
102111
char* buf,

0 commit comments

Comments
 (0)
Please sign in to comment.