Skip to content

Commit 70e7ec6

Browse files
committedJan 30, 2020
crypto: expose certificate decoding function
Format is the same as: - https://nodejs.org/api/tls.html#tls_tlssocket_getcertificate
1 parent 38aa315 commit 70e7ec6

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed
 

‎lib/crypto.js

+12
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ const pendingDeprecation = getOptionValue('--pending-deprecation');
4444
const { fipsMode } = internalBinding('config');
4545
const fipsForced = getOptionValue('--force-fips');
4646
const { getFipsCrypto, setFipsCrypto } = internalBinding('crypto');
47+
const { parseX509 } = internalBinding('crypto');
48+
const {
49+
isArrayBufferView,
50+
} = require('internal/util/types');
4751
const {
4852
randomBytes,
4953
randomFill,
@@ -150,6 +154,13 @@ function createVerify(algorithm, options) {
150154
return new Verify(algorithm, options);
151155
}
152156

157+
function parseCert(cert) {
158+
if (!isArrayBufferView(cert)) {
159+
throw new ERR_INVALID_ARG_TYPE('cert', 'ArrayBufferView', buf);
160+
}
161+
return parseX509(cert);
162+
}
163+
153164
module.exports = {
154165
// Methods
155166
createCipheriv,
@@ -190,6 +201,7 @@ module.exports = {
190201
setFips: !fipsMode ? setFipsDisabled :
191202
fipsForced ? setFipsForced : setFipsCrypto,
192203
verify: verifyOneShot,
204+
parseCert,
193205

194206
// Classes
195207
Certificate,

‎src/node_crypto.cc

+35-1
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,6 @@ static void IsExtraRootCertsFileLoaded(
11451145
return args.GetReturnValue().Set(extra_root_certs_loaded);
11461146
}
11471147

1148-
11491148
void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
11501149
SecureContext* sc;
11511150
ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
@@ -2176,6 +2175,39 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
21762175
}
21772176

21782177

2178+
static void ParseX509(const FunctionCallbackInfo<Value>& args) {
2179+
Environment* env = Environment::GetCurrent(args);
2180+
2181+
CHECK(args[0]->IsArrayBufferView());
2182+
ArrayBufferViewContents<unsigned char> buf(args[0].As<ArrayBufferView>());
2183+
const unsigned char* data = buf.data();
2184+
unsigned data_len = buf.length();
2185+
2186+
ClearErrorOnReturn clear_error_on_return;
2187+
BIOPointer bio(LoadBIO(env, args[0]));
2188+
if (!bio)
2189+
return ThrowCryptoError(env, ERR_get_error());
2190+
2191+
X509Pointer pem(PEM_read_bio_X509_AUX(
2192+
bio.get(), nullptr, NoPasswordCallback, nullptr));
2193+
2194+
if (!pem) {
2195+
// Try as DER, but return the original PEM failure if it isn't DER.
2196+
MarkPopErrorOnReturn mark_here;
2197+
2198+
X509Pointer der(d2i_X509(nullptr, &data, data_len));
2199+
if (der) {
2200+
args.GetReturnValue().Set(X509ToObject(env, der.get()));
2201+
}
2202+
}
2203+
if (!pem) {
2204+
return ThrowCryptoError(env, ERR_get_error());
2205+
}
2206+
2207+
args.GetReturnValue().Set(X509ToObject(env, pem.get()));
2208+
}
2209+
2210+
21792211
static Local<Object> AddIssuerChainToObject(X509Pointer* cert,
21802212
Local<Object> object,
21812213
StackOfX509&& peer_certs,
@@ -7358,6 +7390,8 @@ void Initialize(Local<Object> target,
73587390
// Exposed for testing purposes only.
73597391
env->SetMethodNoSideEffect(target, "isExtraRootCertsFileLoaded",
73607392
IsExtraRootCertsFileLoaded);
7393+
env->SetMethodNoSideEffect(target, "parseX509",
7394+
ParseX509);
73617395

73627396
env->SetMethodNoSideEffect(target, "ECDHConvertKey", ConvertKey);
73637397
#ifndef OPENSSL_NO_ENGINE

0 commit comments

Comments
 (0)