diff options
Diffstat (limited to 'src/lib/libcrypto/ec/ec_ameth.c')
| -rw-r--r-- | src/lib/libcrypto/ec/ec_ameth.c | 231 |
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 | ||
| 89 | static int | 89 | static int |
| 90 | eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) | 90 | eckey_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 */ | 106 | static int |
| 105 | ASN1_STRING *pstr = NULL; | 107 | eckey_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, ¶ms)) <= 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 | |||
| 140 | static int | ||
| 141 | eckey_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, ¶ms, params_len)) == NULL) { | ||
| 148 | ECerror(EC_R_DECODE_ERROR); | ||
| 149 | return 0; | ||
| 117 | } | 150 | } |
| 151 | |||
| 152 | return 1; | ||
| 153 | } | ||
| 154 | |||
| 155 | static int | ||
| 156 | eckey_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 | ||
| 121 | static int | 170 | static int |
| 171 | eckey_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 | |||
| 185 | static int | ||
| 186 | eckey_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 | |||
| 205 | static int | ||
| 206 | eckey_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 | |||
| 219 | static int | ||
| 122 | eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) | 220 | eckey_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 | ||
| 157 | static EC_KEY * | ||
| 158 | eckey_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 | |||
| 205 | static int | 255 | static int |
| 206 | eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) | 256 | eckey_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 | ||
| 238 | static int | 288 | static 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 | ||
