Skip to content

Commit 0ab4e67

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 341d72b commit 0ab4e67

File tree

6 files changed

+34
-37
lines changed

6 files changed

+34
-37
lines changed

ext/openssl/ossl_pkey.c

Lines changed: 29 additions & 4 deletions
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)
@@ -158,7 +158,7 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
158158
}
159159
#else
160160
EVP_PKEY *
161-
ossl_pkey_read_generic(BIO *bio, VALUE pass)
161+
ossl_pkey_read_generic(BIO *bio, VALUE pass, const char *input_type)
162162
{
163163
void *ppass = (void *)pass;
164164
EVP_PKEY *pkey;
@@ -183,6 +183,31 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
183183
goto out;
184184

185185
out:
186+
/* This is to mimic OSSL_DECODER_CTX's input_type parameter */
187+
if (pkey && input_type) {
188+
switch (EVP_PKEY_base_id(pkey)) {
189+
case EVP_PKEY_RSA:
190+
if (!strcmp(input_type, "RSA"))
191+
return pkey;
192+
break;
193+
case EVP_PKEY_DSA:
194+
if (!strcmp(input_type, "DSA"))
195+
return pkey;
196+
break;
197+
case EVP_PKEY_DH:
198+
if (!strcmp(input_type, "DH"))
199+
return pkey;
200+
break;
201+
#if !defined(OPENSSL_NO_EC)
202+
case EVP_PKEY_EC:
203+
if (!strcmp(input_type, "EC"))
204+
return pkey;
205+
break;
206+
#endif
207+
}
208+
EVP_PKEY_free(pkey);
209+
return NULL;
210+
}
186211
return pkey;
187212
}
188213
#endif
@@ -212,7 +237,7 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
212237

213238
rb_scan_args(argc, argv, "11", &data, &pass);
214239
bio = ossl_obj2bio(&data);
215-
pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass));
240+
pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass), NULL);
216241
BIO_free(bio);
217242
if (!pkey)
218243
ossl_raise(ePKeyError, "Could not parse PKey");

ext/openssl/ossl_pkey.h

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 8 deletions
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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
8989
#endif
9090
BIO *in = NULL;
9191
VALUE arg, pass;
92-
int type;
9392

9493
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
9594
if (pkey)
@@ -122,16 +121,10 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
122121
OSSL_BIO_reset(in);
123122
#endif
124123

125-
pkey = ossl_pkey_read_generic(in, pass);
124+
pkey = ossl_pkey_read_generic(in, pass, "DSA");
126125
BIO_free(in);
127126
if (!pkey)
128127
ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
129-
130-
type = EVP_PKEY_base_id(pkey);
131-
if (type != EVP_PKEY_DSA) {
132-
EVP_PKEY_free(pkey);
133-
rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
134-
}
135128
RTYPEDDATA_DATA(self) = pkey;
136129
return self;
137130

ext/openssl/ossl_pkey_ec.c

Lines changed: 1 addition & 8 deletions
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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
8282
#endif
8383
BIO *in = NULL;
8484
VALUE arg, pass;
85-
int type;
8685

8786
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
8887
if (pkey)
@@ -118,16 +117,10 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
118117
#endif
119118

120119
/* Use the generic routine */
121-
pkey = ossl_pkey_read_generic(in, pass);
120+
pkey = ossl_pkey_read_generic(in, pass, "RSA");
122121
BIO_free(in);
123122
if (!pkey)
124123
ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
125-
126-
type = EVP_PKEY_base_id(pkey);
127-
if (type != EVP_PKEY_RSA) {
128-
EVP_PKEY_free(pkey);
129-
rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
130-
}
131124
RTYPEDDATA_DATA(self) = pkey;
132125
return self;
133126

0 commit comments

Comments
 (0)