Skip to content

Commit 7149f5d

Browse files
davidbenskmcgrail
authored andcommitted
Make EVP_PKEY opaque.
While hiding 'type' isn't such a huge deal, accessing 'pkey' without a type check is very dangerous. The accessors are type-checked and avoid this problem. It also gets us slightly closer to not needing to utter CRYPTO_refcount_t in public headers, as we're currently not quite declaring it right. And it allows us to remove another union: https://boringssl-review.googlesource.com/c/boringssl/+/57106 This matches what upstream did in OpenSSL 1.1.0. Update-Note: Code that reaches into the EVP_PKEY struct will no longer compile, like in OpenSSL. I believe I've fixed all the cases. If I missed any, the fix is to switch code to accessors. EVP_PKEY_id(pkey) for pkey->type is the most common fix. AWS-LC: - macros in evp_extra_test.cc directly access `->pkey.kem_key`; "#include "../fipsmodule/evp/internal.h" was added to it. Change-Id: Ibe8d6b6cb8fbd141ea1cef0d02dc1ae3703e9469 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/57105 Auto-Submit: David Benjamin <[email protected]> Commit-Queue: David Benjamin <[email protected]> Reviewed-by: Bob Beck <[email protected]> (cherry picked from commit 890c201d4ac9c345c304d646365fe077cf2b60c1)
1 parent b3b4a45 commit 7149f5d

File tree

8 files changed

+45
-54
lines changed

8 files changed

+45
-54
lines changed

crypto/evp_extra/evp_extra_test.cc

+6-6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "../internal.h"
3636

3737
#include "../kem/internal.h"
38+
#include "../fipsmodule/evp/internal.h"
3839

3940

4041
// kExampleRSAKeyDER is an RSA private key in ASN.1, DER format. Of course, you
@@ -1756,7 +1757,7 @@ TEST_P(PerKEMTest, KeyGeneration) {
17561757

17571758
// ---- 3. Test getting raw keys and their size ----
17581759
size_t pk_len, sk_len;
1759-
1760+
17601761
// First getting the sizes only.
17611762
ASSERT_TRUE(EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &pk_len));
17621763
ASSERT_TRUE(EVP_PKEY_get_raw_private_key(pkey.get(), nullptr, &sk_len));
@@ -1958,7 +1959,7 @@ TEST_P(PerKEMTest, EndToEnd) {
19581959
// ---- 4. Alice/Bob: Bob -- ciphertext --> Alice ----
19591960
// Nothing to do here, we simply use |b_ct|.
19601961

1961-
// ---- 5. Alice: decapsulation ----
1962+
// ---- 5. Alice: decapsulation ----
19621963
std::vector<uint8_t> a_ss(ss_len); // The shared secret.
19631964
ASSERT_TRUE(EVP_PKEY_decapsulate(a_ctx.get(), a_ss.data(), &ss_len, b_ct.data(), ct_len));
19641965

@@ -1981,7 +1982,7 @@ TEST_P(PerKEMTest, EndToEnd) {
19811982
CMP_VEC_AND_PTR(vec, pkey->pkey.kem_key->secret_key, len)
19821983

19831984
TEST_P(PerKEMTest, RawKeyOperations) {
1984-
1985+
19851986
// ---- 1. Setup phase: generate a context and a key ----
19861987
// Create context of KEM type.
19871988
bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_KEM, nullptr));
@@ -2024,7 +2025,7 @@ TEST_P(PerKEMTest, RawKeyOperations) {
20242025

20252026
// ---- 4. Test creating new keys from raw data ----
20262027
int nid = GetParam().nid;
2027-
2028+
20282029
bssl::UniquePtr<EVP_PKEY> pkey_pk_new(EVP_PKEY_kem_new_raw_public_key(nid, pk.data(), pk_len));
20292030
bssl::UniquePtr<EVP_PKEY> pkey_sk_new(EVP_PKEY_kem_new_raw_secret_key(nid, sk.data(), sk_len));
20302031
bssl::UniquePtr<EVP_PKEY> pkey_new(EVP_PKEY_kem_new_raw_key(nid, pk.data(), pk_len, sk.data(), sk_len));
@@ -2208,7 +2209,7 @@ TEST_P(PerKEMTest, KAT) {
22082209
size_t ct_len = GetParam().ciphertext_len;
22092210
size_t ss_len = GetParam().shared_secret_len;
22102211

2211-
// Set randomness generation in deterministic mode.
2212+
// Set randomness generation in deterministic mode.
22122213
pq_custom_randombytes_use_deterministic_for_testing();
22132214
pq_custom_randombytes_init_for_testing(seed.data());
22142215

@@ -2234,4 +2235,3 @@ TEST_P(PerKEMTest, KAT) {
22342235
EXPECT_EQ(Bytes(ss_expected), Bytes(ss));
22352236
});
22362237
}
2237-

crypto/evp_extra/print.c

+11-11
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,11 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off,
181181
}
182182

183183
static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
184-
return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
184+
return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), indent, 0);
185185
}
186186

187187
static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
188-
return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
188+
return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), indent, 1);
189189
}
190190

191191

@@ -225,15 +225,15 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
225225
}
226226

227227
static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
228-
return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
228+
return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 0);
229229
}
230230

231231
static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
232-
return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
232+
return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 1);
233233
}
234234

235235
static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
236-
return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
236+
return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 2);
237237
}
238238

239239

@@ -293,16 +293,16 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
293293
}
294294

295295
static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
296-
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
296+
return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), indent, 0);
297297
}
298298

299299
static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
300-
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
300+
return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), indent, 1);
301301
}
302302

303303

304304
static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
305-
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
305+
return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), indent, 2);
306306
}
307307

308308

@@ -354,7 +354,7 @@ static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
354354

355355
int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
356356
ASN1_PCTX *pctx) {
357-
EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
357+
EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
358358
if (method != NULL && method->pub_print != NULL) {
359359
return method->pub_print(out, pkey, indent);
360360
}
@@ -363,7 +363,7 @@ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
363363

364364
int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
365365
ASN1_PCTX *pctx) {
366-
EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
366+
EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
367367
if (method != NULL && method->priv_print != NULL) {
368368
return method->priv_print(out, pkey, indent);
369369
}
@@ -372,7 +372,7 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
372372

373373
int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
374374
ASN1_PCTX *pctx) {
375-
EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
375+
EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
376376
if (method != NULL && method->param_print != NULL) {
377377
return method->param_print(out, pkey, indent);
378378
}

crypto/fipsmodule/evp/internal.h

+20
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,26 @@ struct evp_pkey_asn1_method_st {
123123
void (*pkey_free)(EVP_PKEY *pkey);
124124
}; // EVP_PKEY_ASN1_METHOD
125125

126+
struct evp_pkey_st {
127+
CRYPTO_refcount_t references;
128+
129+
// type contains one of the EVP_PKEY_* values or NID_undef and determines
130+
// which element (if any) of the |pkey| union is valid.
131+
int type;
132+
133+
union {
134+
void *ptr;
135+
RSA *rsa;
136+
DSA *dsa;
137+
DH *dh;
138+
EC_KEY *ec;
139+
KEM_KEY *kem_key;
140+
} pkey;
141+
142+
// ameth contains a pointer to a method table that contains many ASN.1
143+
// methods for the key type.
144+
const EVP_PKEY_ASN1_METHOD *ameth;
145+
} /* EVP_PKEY */;
126146

127147
#define EVP_PKEY_OP_UNDEFINED 0
128148
#define EVP_PKEY_OP_KEYGEN (1 << 2)

crypto/x509/i2d_pr.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@
6565
int i2d_PrivateKey(const EVP_PKEY *a, uint8_t **pp) {
6666
switch (EVP_PKEY_id(a)) {
6767
case EVP_PKEY_RSA:
68-
return i2d_RSAPrivateKey(a->pkey.rsa, pp);
68+
return i2d_RSAPrivateKey(EVP_PKEY_get0_RSA(a), pp);
6969
case EVP_PKEY_EC:
70-
return i2d_ECPrivateKey(a->pkey.ec, pp);
70+
return i2d_ECPrivateKey(EVP_PKEY_get0_EC_KEY(a), pp);
7171
case EVP_PKEY_DSA:
72-
return i2d_DSAPrivateKey(a->pkey.dsa, pp);
72+
return i2d_DSAPrivateKey(EVP_PKEY_get0_DSA(a), pp);
7373
default:
7474
// Although this file is in crypto/x509 for layering reasons, it emits
7575
// an error code from ASN1 for OpenSSL compatibility.

crypto/x509/x509_req.c

+1-6
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,10 @@ int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) {
9999
OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
100100
break;
101101
case -2:
102-
if (k->type == EVP_PKEY_EC) {
102+
if (EVP_PKEY_id(k) == EVP_PKEY_EC) {
103103
OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
104104
break;
105105
}
106-
if (k->type == EVP_PKEY_DH) {
107-
// No idea
108-
OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY);
109-
break;
110-
}
111106
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
112107
}
113108

include/openssl/evp.h

+1-25
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ OPENSSL_EXPORT int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx /* IN */,
754754
// provide large enough |shared_secret| buffer.
755755
//
756756
// It returns one on success or zero on error.
757-
OPENSSL_EXPORT int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx /* IN */,
757+
OPENSSL_EXPORT int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx /* IN */,
758758
uint8_t *shared_secret /* OUT */,
759759
size_t *shared_secret_len /* OUT */,
760760
uint8_t *ciphertext /* IN */,
@@ -1156,30 +1156,6 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx,
11561156
ERR_put_error(ERR_LIB_EVP, 0, reason, __FILE__, __LINE__)
11571157

11581158

1159-
// Private structures.
1160-
1161-
struct evp_pkey_st {
1162-
CRYPTO_refcount_t references;
1163-
1164-
// type contains one of the EVP_PKEY_* values or NID_undef and determines
1165-
// which element (if any) of the |pkey| union is valid.
1166-
int type;
1167-
1168-
union {
1169-
void *ptr;
1170-
RSA *rsa;
1171-
DSA *dsa;
1172-
DH *dh;
1173-
EC_KEY *ec;
1174-
KEM_KEY *kem_key;
1175-
} pkey;
1176-
1177-
// ameth contains a pointer to a method table that contains many ASN.1
1178-
// methods for the key type.
1179-
const EVP_PKEY_ASN1_METHOD *ameth;
1180-
}; // EVP_PKEY
1181-
1182-
11831159
#if defined(__cplusplus)
11841160
} // extern C
11851161

ssl/ssl_cert.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -237,14 +237,14 @@ static enum leaf_cert_and_privkey_result_t check_leaf_cert_and_privkey(
237237
return leaf_cert_and_privkey_error;
238238
}
239239

240-
if (!ssl_is_key_type_supported(pubkey->type)) {
240+
if (!ssl_is_key_type_supported(EVP_PKEY_id(pubkey.get()))) {
241241
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
242242
return leaf_cert_and_privkey_error;
243243
}
244244

245245
// An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA
246246
// certificates, so sanity-check the key usage extension.
247-
if (pubkey->type == EVP_PKEY_EC &&
247+
if (EVP_PKEY_id(pubkey.get()) == EVP_PKEY_EC &&
248248
!ssl_cert_check_key_usage(&cert_cbs, key_usage_digital_signature)) {
249249
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
250250
return leaf_cert_and_privkey_error;

ssl/ssl_privkey.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ bool ssl_is_key_type_supported(int key_type) {
7777
}
7878

7979
static bool ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) {
80-
if (!ssl_is_key_type_supported(pkey->type)) {
80+
if (!ssl_is_key_type_supported(EVP_PKEY_id(pkey))) {
8181
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
8282
return false;
8383
}

0 commit comments

Comments
 (0)