summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/ec/ec_ameth.c231
1 files changed, 139 insertions, 92 deletions
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c
index f2ad5f60c6..258daec127 100644
--- a/src/lib/libcrypto/ec/ec_ameth.c
+++ b/src/lib/libcrypto/ec/ec_ameth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_ameth.c,v 1.43 2023/08/21 09:52:30 tb Exp $ */ 1/* $OpenBSD: ec_ameth.c,v 1.44 2023/09/24 07:58:31 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006. 3 * project 2006.
4 */ 4 */
@@ -87,38 +87,136 @@ eckey_param_free(int ptype, void *pval)
87} 87}
88 88
89static int 89static int
90eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) 90eckey_get_curve_name(const EC_KEY *eckey, int *nid)
91{ 91{
92 const EC_GROUP *group; 92 const EC_GROUP *group;
93 int nid; 93
94 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { 94 *nid = NID_undef;
95
96 if ((group = EC_KEY_get0_group(eckey)) == NULL) {
95 ECerror(EC_R_MISSING_PARAMETERS); 97 ECerror(EC_R_MISSING_PARAMETERS);
96 return 0; 98 return 0;
97 } 99 }
98 if (EC_GROUP_get_asn1_flag(group) && 100 if (EC_GROUP_get_asn1_flag(group) != 0)
99 (nid = EC_GROUP_get_curve_name(group))) { 101 *nid = EC_GROUP_get_curve_name(group);
100 /* we have a 'named curve' => just set the OID */ 102
101 *ppval = OBJ_nid2obj(nid); 103 return 1;
102 *pptype = V_ASN1_OBJECT; 104}
103 } else { 105
104 /* explicit parameters */ 106static int
105 ASN1_STRING *pstr = NULL; 107eckey_to_explicit_params(EC_KEY *eckey, void **out_val)
106 pstr = ASN1_STRING_new(); 108{
107 if (!pstr) 109 ASN1_STRING *astr = NULL;
108 return 0; 110 unsigned char *params = NULL;
109 pstr->length = i2d_ECParameters(ec_key, &pstr->data); 111 int params_len = 0;
110 if (pstr->length <= 0) { 112 int ret = 0;
111 ASN1_STRING_free(pstr); 113
112 ECerror(ERR_R_EC_LIB); 114 *out_val = NULL;
113 return 0; 115
114 } 116 if ((params_len = i2d_ECParameters(eckey, &params)) <= 0) {
115 *ppval = pstr; 117 ECerror(ERR_R_EC_LIB);
116 *pptype = V_ASN1_SEQUENCE; 118 params_len = 0;
119 goto err;
120 }
121
122 if ((astr = ASN1_STRING_new()) == NULL)
123 goto err;
124 ASN1_STRING_set0(astr, params, params_len);
125 params = NULL;
126 params_len = 0;
127
128 *out_val = astr;
129 astr = NULL;
130
131 ret = 1;
132
133 err:
134 freezero(params, params_len);
135 ASN1_STRING_free(astr);
136
137 return ret;
138}
139
140static int
141eckey_from_explicit_params(const ASN1_STRING *astr, EC_KEY **out_eckey)
142{
143 const unsigned char *params = astr->data;
144 int params_len = astr->length;
145
146 EC_KEY_free(*out_eckey);
147 if ((*out_eckey = d2i_ECParameters(NULL, &params, params_len)) == NULL) {
148 ECerror(EC_R_DECODE_ERROR);
149 return 0;
117 } 150 }
151
152 return 1;
153}
154
155static int
156eckey_to_object(const EC_KEY *eckey, void **out_val)
157{
158 int nid = NID_undef;
159
160 *out_val = NULL;
161
162 if (!eckey_get_curve_name(eckey, &nid))
163 return 0;
164 if ((*out_val = OBJ_nid2obj(nid)) == NULL)
165 return 0;
166
118 return 1; 167 return 1;
119} 168}
120 169
121static int 170static int
171eckey_from_object(const ASN1_OBJECT *aobj, EC_KEY **out_eckey)
172{
173 int nid;
174
175 *out_eckey = NULL;
176
177 if ((nid = OBJ_obj2nid(aobj)) == NID_undef)
178 return 0;
179 if ((*out_eckey = EC_KEY_new_by_curve_name(nid)) == NULL)
180 return 0;
181
182 return 1;
183}
184
185static int
186eckey_to_params(EC_KEY *eckey, int *out_type, void **out_val)
187{
188 int nid;
189
190 *out_type = NID_undef;
191 *out_val = NULL;
192
193 if (!eckey_get_curve_name(eckey, &nid))
194 return 0;
195
196 if (nid == NID_undef) {
197 *out_type = V_ASN1_SEQUENCE;
198 return eckey_to_explicit_params(eckey, out_val);
199 } else {
200 *out_type = V_ASN1_OBJECT;
201 return eckey_to_object(eckey, out_val);
202 }
203}
204
205static int
206eckey_from_params(int ptype, const void *pval, EC_KEY **out_eckey)
207{
208 *out_eckey = NULL;
209
210 if (ptype == V_ASN1_SEQUENCE)
211 return eckey_from_explicit_params(pval, out_eckey);
212 if (ptype == V_ASN1_OBJECT)
213 return eckey_from_object(pval, out_eckey);
214
215 ECerror(EC_R_DECODE_ERROR);
216 return 0;
217}
218
219static int
122eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 220eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
123{ 221{
124 EC_KEY *eckey = pkey->pkey.ec; 222 EC_KEY *eckey = pkey->pkey.ec;
@@ -129,7 +227,7 @@ eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
129 int key_len = 0; 227 int key_len = 0;
130 int ret = 0; 228 int ret = 0;
131 229
132 if (!eckey_param2type(&ptype, &pval, eckey)) { 230 if (!eckey_to_params(eckey, &ptype, &pval)) {
133 ECerror(ERR_R_EC_LIB); 231 ECerror(ERR_R_EC_LIB);
134 goto err; 232 goto err;
135 } 233 }
@@ -154,54 +252,6 @@ eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
154 return ret; 252 return ret;
155} 253}
156 254
157static EC_KEY *
158eckey_type2param(int ptype, const void *pval)
159{
160 EC_GROUP *group = NULL;
161 EC_KEY *eckey = NULL;
162
163 if (ptype == V_ASN1_SEQUENCE) {
164 const ASN1_STRING *pstr = pval;
165 const unsigned char *pm = NULL;
166 int pmlen;
167
168 pm = pstr->data;
169 pmlen = pstr->length;
170 if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
171 ECerror(EC_R_DECODE_ERROR);
172 goto ecerr;
173 }
174 } else if (ptype == V_ASN1_OBJECT) {
175 const ASN1_OBJECT *poid = pval;
176
177 /*
178 * type == V_ASN1_OBJECT => the parameters are given by an
179 * asn1 OID
180 */
181 if ((eckey = EC_KEY_new()) == NULL) {
182 ECerror(ERR_R_MALLOC_FAILURE);
183 goto ecerr;
184 }
185 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
186 if (group == NULL)
187 goto ecerr;
188 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
189 if (EC_KEY_set_group(eckey, group) == 0)
190 goto ecerr;
191 } else {
192 ECerror(EC_R_DECODE_ERROR);
193 goto ecerr;
194 }
195
196 EC_GROUP_free(group);
197 return eckey;
198
199 ecerr:
200 EC_KEY_free(eckey);
201 EC_GROUP_free(group);
202 return NULL;
203}
204
205static int 255static int
206eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) 256eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
207{ 257{
@@ -210,29 +260,29 @@ eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
210 int ptype, pklen; 260 int ptype, pklen;
211 EC_KEY *eckey = NULL; 261 EC_KEY *eckey = NULL;
212 X509_ALGOR *palg; 262 X509_ALGOR *palg;
263 int ret = 0;
213 264
214 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 265 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
215 return 0; 266 goto err;
216 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 267 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
217 268
218 eckey = eckey_type2param(ptype, pval); 269 if (!eckey_from_params(ptype, pval, &eckey))
270 goto err;
219 271
220 if (!eckey) {
221 ECerror(ERR_R_EC_LIB);
222 return 0;
223 }
224 /* We have parameters now set public key */
225 if (!o2i_ECPublicKey(&eckey, &p, pklen)) { 272 if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
226 ECerror(EC_R_DECODE_ERROR); 273 ECerror(EC_R_DECODE_ERROR);
227 goto ecerr; 274 goto err;
228 } 275 }
229 EVP_PKEY_assign_EC_KEY(pkey, eckey); 276 if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
230 return 1; 277 goto err;
278 eckey = NULL;
231 279
232 ecerr: 280 ret = 1;
233 if (eckey) 281
234 EC_KEY_free(eckey); 282 err:
235 return 0; 283 EC_KEY_free(eckey);
284
285 return ret;
236} 286}
237 287
238static int 288static int
@@ -263,9 +313,7 @@ eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
263 return 0; 313 return 0;
264 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 314 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
265 315
266 eckey = eckey_type2param(ptype, pval); 316 if (!eckey_from_params(ptype, pval, &eckey))
267
268 if (!eckey)
269 goto ecliberr; 317 goto ecliberr;
270 318
271 /* We have parameters now set private key */ 319 /* We have parameters now set private key */
@@ -331,7 +379,7 @@ eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
331 379
332 flags = EC_KEY_get_enc_flags(eckey); 380 flags = EC_KEY_get_enc_flags(eckey);
333 381
334 if (!eckey_param2type(&ptype, &pval, eckey)) { 382 if (!eckey_to_params(eckey, &ptype, &pval)) {
335 ECerror(EC_R_DECODE_ERROR); 383 ECerror(EC_R_DECODE_ERROR);
336 goto err; 384 goto err;
337 } 385 }
@@ -685,8 +733,7 @@ ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg,
685 if (!EC_KEY_set_group(ecpeer, grp)) 733 if (!EC_KEY_set_group(ecpeer, grp))
686 goto err; 734 goto err;
687 } else { 735 } else {
688 ecpeer = eckey_type2param(atype, aval); 736 if (!eckey_from_params(atype, aval, &ecpeer))
689 if (!ecpeer)
690 goto err; 737 goto err;
691 } 738 }
692 739