Skip to content

Commit e3b6a6f

Browse files
tniessenrefack
authored andcommitted
crypto: always accept certificates as public keys
PR-URL: nodejs#24234 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 6fbdcc2 commit e3b6a6f

File tree

2 files changed

+14
-19
lines changed

2 files changed

+14
-19
lines changed

doc/api/crypto.md

Lines changed: 2 additions & 0 deletions
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

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2737,8 +2737,7 @@ static ParsePublicKeyResult TryParsePublicKey(
27372737

27382738
static ParsePublicKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
27392739
const char* key_pem,
2740-
int key_pem_len,
2741-
bool allow_certificate) {
2740+
int key_pem_len) {
27422741
BIOPointer bp(BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len));
27432742
if (!bp)
27442743
return ParsePublicKeyResult::kParsePublicFailed;
@@ -2759,8 +2758,7 @@ static ParsePublicKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
27592758
[](const unsigned char** p, long l) { // NOLINT(runtime/int)
27602759
return d2i_PublicKey(EVP_PKEY_RSA, nullptr, p, l);
27612760
});
2762-
if (ret != ParsePublicKeyResult::kParsePublicNotRecognized ||
2763-
!allow_certificate)
2761+
if (ret != ParsePublicKeyResult::kParsePublicNotRecognized)
27642762
return ret;
27652763

27662764
// X.509 fallback.
@@ -2775,11 +2773,10 @@ static ParsePublicKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
27752773
static bool ParsePublicKey(EVPKeyPointer* pkey,
27762774
const PublicKeyEncodingConfig& config,
27772775
const char* key,
2778-
size_t key_len,
2779-
bool allow_certificate) {
2776+
size_t key_len) {
27802777
if (config.format_ == kKeyFormatPEM) {
27812778
ParsePublicKeyResult r =
2782-
ParsePublicKeyPEM(pkey, key, key_len, allow_certificate);
2779+
ParsePublicKeyPEM(pkey, key, key_len);
27832780
return r == ParsePublicKeyResult::kParsePublicOk;
27842781
} else {
27852782
CHECK_EQ(config.format_, kKeyFormatDER);
@@ -3029,15 +3026,14 @@ static PublicKeyEncodingConfig GetPublicKeyEncodingFromJs(
30293026
static ManagedEVPPKey GetPublicKeyFromJs(
30303027
const FunctionCallbackInfo<Value>& args,
30313028
unsigned int* offset,
3032-
bool allow_key_object,
3033-
bool allow_certificate) {
3029+
bool allow_key_object) {
30343030
if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
30353031
Environment* env = Environment::GetCurrent(args);
30363032
ByteSource key = ByteSource::FromStringOrBuffer(env, args[(*offset)++]);
30373033
PublicKeyEncodingConfig config =
30383034
GetPublicKeyEncodingFromJs(args, offset, kKeyContextInput);
30393035
EVPKeyPointer pkey;
3040-
ParsePublicKey(&pkey, config, key.get(), key.size(), allow_certificate);
3036+
ParsePublicKey(&pkey, config, key.get(), key.size());
30413037
if (!pkey)
30423038
ThrowCryptoError(env, ERR_get_error(), "Failed to read public key");
30433039
return ManagedEVPPKey(pkey.release());
@@ -3158,8 +3154,7 @@ static bool IsRSAPrivateKey(const unsigned char* data, size_t size) {
31583154
static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
31593155
const FunctionCallbackInfo<Value>& args,
31603156
unsigned int* offset,
3161-
bool allow_key_object,
3162-
bool allow_certificate) {
3157+
bool allow_key_object) {
31633158
if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
31643159
Environment* env = Environment::GetCurrent(args);
31653160
ByteSource data = ByteSource::FromStringOrBuffer(env, args[(*offset)++]);
@@ -3173,8 +3168,7 @@ static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
31733168
// For PEM, we can easily determine whether it is a public or private key
31743169
// by looking for the respective PEM tags.
31753170
ParsePublicKeyResult ret = ParsePublicKeyPEM(&pkey, data.get(),
3176-
data.size(),
3177-
allow_certificate);
3171+
data.size());
31783172
if (ret == ParsePublicKeyResult::kParsePublicNotRecognized) {
31793173
pkey = ParsePrivateKey(config, data.get(), data.size());
31803174
}
@@ -3199,8 +3193,7 @@ static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
31993193
}
32003194

32013195
if (is_public) {
3202-
ParsePublicKey(&pkey, config, data.get(), data.size(),
3203-
allow_certificate);
3196+
ParsePublicKey(&pkey, config, data.get(), data.size());
32043197
} else {
32053198
pkey = ParsePrivateKey(config, data.get(), data.size());
32063199
}
@@ -3413,7 +3406,7 @@ void KeyObject::Init(const FunctionCallbackInfo<Value>& args) {
34133406
CHECK_EQ(args.Length(), 3);
34143407

34153408
offset = 0;
3416-
pkey = GetPublicKeyFromJs(args, &offset, false, false);
3409+
pkey = GetPublicKeyFromJs(args, &offset, false);
34173410
if (!pkey)
34183411
return;
34193412
key->InitPublic(pkey);
@@ -4695,7 +4688,7 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
46954688
ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
46964689

46974690
unsigned int offset = 0;
4698-
ManagedEVPPKey pkey = GetPublicKeyFromJs(args, &offset, true, true);
4691+
ManagedEVPPKey pkey = GetPublicKeyFromJs(args, &offset, true);
46994692

47004693
char* hbuf = Buffer::Data(args[offset]);
47014694
ssize_t hlen = Buffer::Length(args[offset]);
@@ -4751,7 +4744,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
47514744
Environment* env = Environment::GetCurrent(args);
47524745

47534746
unsigned int offset = 0;
4754-
ManagedEVPPKey pkey = GetPublicOrPrivateKeyFromJs(args, &offset, true, true);
4747+
ManagedEVPPKey pkey = GetPublicOrPrivateKeyFromJs(args, &offset, true);
47554748
if (!pkey)
47564749
return;
47574750

0 commit comments

Comments
 (0)