Skip to content

Commit 41d0807

Browse files
committed
pkey: give input_type to OSSL_DECODER_CTX
DER encoding may be ambiguous because it doesn't contain information about the key type or format. For example, DHParameters and RSAPublicKey look identical on the DER encoding, which is a SEQUENCE with two INTEGER inside.
1 parent dd2fdd5 commit 41d0807

File tree

6 files changed

+34
-37
lines changed

6 files changed

+34
-37
lines changed

ext/openssl/ossl_pkey.c

+29-4
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,14 @@ ossl_pkey_new(EVP_PKEY *pkey)
8383
# include <openssl/decoder.h>
8484

8585
EVP_PKEY *
86-
ossl_pkey_read_generic(BIO *bio, VALUE pass)
86+
ossl_pkey_read_generic(BIO *bio, VALUE pass, const char *input_type)
8787
{
8888
void *ppass = (void *)pass;
8989
OSSL_DECODER_CTX *dctx;
9090
EVP_PKEY *pkey = NULL;
9191
int pos = 0, pos2;
9292

93-
dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, NULL, 0, NULL, NULL);
93+
dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, input_type, 0, NULL, NULL);
9494
if (!dctx)
9595
goto out;
9696
if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb, ppass) != 1)
@@ -119,7 +119,7 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
119119
}
120120
#else
121121
EVP_PKEY *
122-
ossl_pkey_read_generic(BIO *bio, VALUE pass)
122+
ossl_pkey_read_generic(BIO *bio, VALUE pass, const char *input_type)
123123
{
124124
void *ppass = (void *)pass;
125125
EVP_PKEY *pkey;
@@ -144,6 +144,31 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
144144
goto out;
145145

146146
out:
147+
/* This is to mimic OSSL_DECODER_CTX's input_type parameter */
148+
if (pkey && input_type) {
149+
switch (EVP_PKEY_base_id(pkey)) {
150+
case EVP_PKEY_RSA:
151+
if (!strcmp(input_type, "RSA"))
152+
return pkey;
153+
break;
154+
case EVP_PKEY_DSA:
155+
if (!strcmp(input_type, "DSA"))
156+
return pkey;
157+
break;
158+
case EVP_PKEY_DH:
159+
if (!strcmp(input_type, "DH"))
160+
return pkey;
161+
break;
162+
#if !defined(OPENSSL_NO_EC)
163+
case EVP_PKEY_EC:
164+
if (!strcmp(input_type, "EC"))
165+
return pkey;
166+
break;
167+
#endif
168+
}
169+
EVP_PKEY_free(pkey);
170+
return NULL;
171+
}
147172
return pkey;
148173
}
149174
#endif
@@ -173,7 +198,7 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
173198

174199
rb_scan_args(argc, argv, "11", &data, &pass);
175200
bio = ossl_obj2bio(&data);
176-
pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass));
201+
pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass), NULL);
177202
BIO_free(bio);
178203
if (!pkey)
179204
ossl_raise(ePKeyError, "Could not parse PKey");

ext/openssl/ossl_pkey.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ extern const rb_data_type_t ossl_evp_pkey_type;
2929
/* Takes ownership of the EVP_PKEY */
3030
VALUE ossl_pkey_new(EVP_PKEY *);
3131
void ossl_pkey_check_public_key(const EVP_PKEY *);
32-
EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE);
32+
EVP_PKEY *ossl_pkey_read_generic(BIO *bio, VALUE pass, const char *input_type);
3333
EVP_PKEY *GetPKeyPtr(VALUE);
3434
EVP_PKEY *DupPKeyPtr(VALUE);
3535
EVP_PKEY *GetPrivPKeyPtr(VALUE);

ext/openssl/ossl_pkey_dh.c

+1-8
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ static VALUE
7373
ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
7474
{
7575
EVP_PKEY *pkey;
76-
int type;
7776
#ifndef OSSL_HAVE_PROVIDER
7877
DH *dh;
7978
#endif
@@ -110,16 +109,10 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
110109
OSSL_BIO_reset(in);
111110
#endif
112111

113-
pkey = ossl_pkey_read_generic(in, Qnil);
112+
pkey = ossl_pkey_read_generic(in, Qnil, "DH");
114113
BIO_free(in);
115114
if (!pkey)
116115
ossl_raise(eDHError, "could not parse pkey");
117-
118-
type = EVP_PKEY_base_id(pkey);
119-
if (type != EVP_PKEY_DH) {
120-
EVP_PKEY_free(pkey);
121-
rb_raise(eDHError, "incorrect pkey type: %s", OBJ_nid2sn(type));
122-
}
123116
RTYPEDDATA_DATA(self) = pkey;
124117
return self;
125118

ext/openssl/ossl_pkey_dsa.c

+1-8
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
8787
DSA *dsa;
8888
BIO *in = NULL;
8989
VALUE arg, pass;
90-
int type;
9190

9291
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
9392
if (pkey)
@@ -114,16 +113,10 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
114113
goto legacy;
115114
OSSL_BIO_reset(in);
116115

117-
pkey = ossl_pkey_read_generic(in, pass);
116+
pkey = ossl_pkey_read_generic(in, pass, "DSA");
118117
BIO_free(in);
119118
if (!pkey)
120119
ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
121-
122-
type = EVP_PKEY_base_id(pkey);
123-
if (type != EVP_PKEY_DSA) {
124-
EVP_PKEY_free(pkey);
125-
rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
126-
}
127120
RTYPEDDATA_DATA(self) = pkey;
128121
return self;
129122

ext/openssl/ossl_pkey_ec.c

+1-8
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
142142
EC_KEY *ec;
143143
BIO *in;
144144
VALUE arg, pass;
145-
int type;
146145

147146
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
148147
if (pkey)
@@ -163,19 +162,13 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
163162
arg = ossl_to_der_if_possible(arg);
164163
in = ossl_obj2bio(&arg);
165164

166-
pkey = ossl_pkey_read_generic(in, pass);
165+
pkey = ossl_pkey_read_generic(in, pass, "EC");
167166
BIO_free(in);
168167
if (!pkey) {
169168
ossl_clear_error();
170169
ec = ec_key_new_from_group(arg);
171170
goto legacy;
172171
}
173-
174-
type = EVP_PKEY_base_id(pkey);
175-
if (type != EVP_PKEY_EC) {
176-
EVP_PKEY_free(pkey);
177-
rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
178-
}
179172
RTYPEDDATA_DATA(self) = pkey;
180173
return self;
181174

ext/openssl/ossl_pkey_rsa.c

+1-8
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
8080
RSA *rsa;
8181
BIO *in = NULL;
8282
VALUE arg, pass;
83-
int type;
8483

8584
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
8685
if (pkey)
@@ -110,16 +109,10 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
110109
OSSL_BIO_reset(in);
111110

112111
/* Use the generic routine */
113-
pkey = ossl_pkey_read_generic(in, pass);
112+
pkey = ossl_pkey_read_generic(in, pass, "RSA");
114113
BIO_free(in);
115114
if (!pkey)
116115
ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
117-
118-
type = EVP_PKEY_base_id(pkey);
119-
if (type != EVP_PKEY_RSA) {
120-
EVP_PKEY_free(pkey);
121-
rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
122-
}
123116
RTYPEDDATA_DATA(self) = pkey;
124117
return self;
125118

0 commit comments

Comments
 (0)