Skip to content

Commit e6c1e8d

Browse files
tniessenMylesBorins
authored andcommitted
crypto: always accept certificates as public keys
PR-URL: #24234 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 3b53df0 commit e6c1e8d

File tree

2 files changed

+14
-19
lines changed

2 files changed

+14
-19
lines changed

doc/api/crypto.md

+2
Original file line numberDiff line numberDiff line change
@@ -1831,6 +1831,8 @@ Creates and returns a new key object containing a public key. If `key` is a
18311831
string or `Buffer`, `format` is assumed to be `'pem'`; otherwise, `key`
18321832
must be an object with the properties described above.
18331833

1834+
If the format is `'pem'`, the `'key'` may also be an X.509 certificate.
1835+
18341836
### crypto.createSecretKey(key)
18351837
<!-- YAML
18361838
added: REPLACEME

src/node_crypto.cc

+12-19
Original file line numberDiff line numberDiff line change
@@ -2710,8 +2710,7 @@ static ParsePublicKeyResult TryParsePublicKey(
27102710

27112711
static ParsePublicKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
27122712
const char* key_pem,
2713-
int key_pem_len,
2714-
bool allow_certificate) {
2713+
int key_pem_len) {
27152714
BIOPointer bp(BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len));
27162715
if (!bp)
27172716
return ParsePublicKeyResult::kParsePublicFailed;
@@ -2732,8 +2731,7 @@ static ParsePublicKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
27322731
[](const unsigned char** p, long l) { // NOLINT(runtime/int)
27332732
return d2i_PublicKey(EVP_PKEY_RSA, nullptr, p, l);
27342733
});
2735-
if (ret != ParsePublicKeyResult::kParsePublicNotRecognized ||
2736-
!allow_certificate)
2734+
if (ret != ParsePublicKeyResult::kParsePublicNotRecognized)
27372735
return ret;
27382736

27392737
// X.509 fallback.
@@ -2748,11 +2746,10 @@ static ParsePublicKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
27482746
static bool ParsePublicKey(EVPKeyPointer* pkey,
27492747
const PublicKeyEncodingConfig& config,
27502748
const char* key,
2751-
size_t key_len,
2752-
bool allow_certificate) {
2749+
size_t key_len) {
27532750
if (config.format_ == kKeyFormatPEM) {
27542751
ParsePublicKeyResult r =
2755-
ParsePublicKeyPEM(pkey, key, key_len, allow_certificate);
2752+
ParsePublicKeyPEM(pkey, key, key_len);
27562753
return r == ParsePublicKeyResult::kParsePublicOk;
27572754
} else {
27582755
CHECK_EQ(config.format_, kKeyFormatDER);
@@ -3002,15 +2999,14 @@ static PublicKeyEncodingConfig GetPublicKeyEncodingFromJs(
30022999
static ManagedEVPPKey GetPublicKeyFromJs(
30033000
const FunctionCallbackInfo<Value>& args,
30043001
unsigned int* offset,
3005-
bool allow_key_object,
3006-
bool allow_certificate) {
3002+
bool allow_key_object) {
30073003
if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
30083004
Environment* env = Environment::GetCurrent(args);
30093005
ByteSource key = ByteSource::FromStringOrBuffer(env, args[(*offset)++]);
30103006
PublicKeyEncodingConfig config =
30113007
GetPublicKeyEncodingFromJs(args, offset, kKeyContextInput);
30123008
EVPKeyPointer pkey;
3013-
ParsePublicKey(&pkey, config, key.get(), key.size(), allow_certificate);
3009+
ParsePublicKey(&pkey, config, key.get(), key.size());
30143010
if (!pkey)
30153011
ThrowCryptoError(env, ERR_get_error(), "Failed to read public key");
30163012
return ManagedEVPPKey(pkey.release());
@@ -3131,8 +3127,7 @@ static bool IsRSAPrivateKey(const unsigned char* data, size_t size) {
31313127
static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
31323128
const FunctionCallbackInfo<Value>& args,
31333129
unsigned int* offset,
3134-
bool allow_key_object,
3135-
bool allow_certificate) {
3130+
bool allow_key_object) {
31363131
if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
31373132
Environment* env = Environment::GetCurrent(args);
31383133
ByteSource data = ByteSource::FromStringOrBuffer(env, args[(*offset)++]);
@@ -3146,8 +3141,7 @@ static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
31463141
// For PEM, we can easily determine whether it is a public or private key
31473142
// by looking for the respective PEM tags.
31483143
ParsePublicKeyResult ret = ParsePublicKeyPEM(&pkey, data.get(),
3149-
data.size(),
3150-
allow_certificate);
3144+
data.size());
31513145
if (ret == ParsePublicKeyResult::kParsePublicNotRecognized) {
31523146
pkey = ParsePrivateKey(config, data.get(), data.size());
31533147
}
@@ -3172,8 +3166,7 @@ static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
31723166
}
31733167

31743168
if (is_public) {
3175-
ParsePublicKey(&pkey, config, data.get(), data.size(),
3176-
allow_certificate);
3169+
ParsePublicKey(&pkey, config, data.get(), data.size());
31773170
} else {
31783171
pkey = ParsePrivateKey(config, data.get(), data.size());
31793172
}
@@ -3386,7 +3379,7 @@ void KeyObject::Init(const FunctionCallbackInfo<Value>& args) {
33863379
CHECK_EQ(args.Length(), 3);
33873380

33883381
offset = 0;
3389-
pkey = GetPublicKeyFromJs(args, &offset, false, false);
3382+
pkey = GetPublicKeyFromJs(args, &offset, false);
33903383
if (!pkey)
33913384
return;
33923385
key->InitPublic(pkey);
@@ -4668,7 +4661,7 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
46684661
ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
46694662

46704663
unsigned int offset = 0;
4671-
ManagedEVPPKey pkey = GetPublicKeyFromJs(args, &offset, true, true);
4664+
ManagedEVPPKey pkey = GetPublicKeyFromJs(args, &offset, true);
46724665

46734666
char* hbuf = Buffer::Data(args[offset]);
46744667
ssize_t hlen = Buffer::Length(args[offset]);
@@ -4724,7 +4717,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
47244717
Environment* env = Environment::GetCurrent(args);
47254718

47264719
unsigned int offset = 0;
4727-
ManagedEVPPKey pkey = GetPublicOrPrivateKeyFromJs(args, &offset, true, true);
4720+
ManagedEVPPKey pkey = GetPublicOrPrivateKeyFromJs(args, &offset, true);
47284721
if (!pkey)
47294722
return;
47304723

0 commit comments

Comments
 (0)