diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/ec/ec_asn1.c | 77 |
1 files changed, 41 insertions, 36 deletions
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c index 5234d4380a..d6af3bdec5 100644 --- a/src/lib/libcrypto/ec/ec_asn1.c +++ b/src/lib/libcrypto/ec/ec_asn1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_asn1.c,v 1.91 2024/10/28 17:59:45 tb Exp $ */ | 1 | /* $OpenBSD: ec_asn1.c,v 1.92 2024/10/28 18:03:34 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Nils Larsch for the OpenSSL project. | 3 | * Written by Nils Larsch for the OpenSSL project. |
4 | */ | 4 | */ |
@@ -1142,6 +1142,45 @@ ec_key_set_private_key(EC_KEY *ec_key, const ASN1_OCTET_STRING *aos) | |||
1142 | return ret; | 1142 | return ret; |
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | static int | ||
1146 | ec_key_set_public_key(EC_KEY *ec_key, const ASN1_BIT_STRING *abs) | ||
1147 | { | ||
1148 | const EC_GROUP *group = ec_key->group; | ||
1149 | EC_POINT *pub_key = NULL; | ||
1150 | int ret = 0; | ||
1151 | |||
1152 | if (abs == NULL) { | ||
1153 | ec_key->enc_flag |= EC_PKEY_NO_PUBKEY; | ||
1154 | return eckey_compute_pubkey(ec_key); | ||
1155 | } | ||
1156 | |||
1157 | /* | ||
1158 | * Per SEC 1, C.3, the bit string representing the public key comes from | ||
1159 | * an octet string, therefore the unused bits octet must be 0x00. | ||
1160 | * XXX - move this check to a helper in a_bitstr.c? | ||
1161 | */ | ||
1162 | if ((abs->flags & ASN1_STRING_FLAG_BITS_LEFT) != 0 && | ||
1163 | (abs->flags & 0x07) != 0) | ||
1164 | goto err; | ||
1165 | |||
1166 | /* XXX - SEC 1, 2.3.4 does not allow hybrid encoding. */ | ||
1167 | if ((pub_key = EC_POINT_new(group)) == NULL) | ||
1168 | goto err; | ||
1169 | if (!EC_POINT_oct2point(group, pub_key, abs->data, abs->length, NULL)) | ||
1170 | goto err; | ||
1171 | if (!EC_KEY_set_public_key(ec_key, pub_key)) | ||
1172 | goto err; | ||
1173 | /* oct2point has ensured that to be compressed, uncompressed, or hybrid. */ | ||
1174 | ec_key->conv_form = abs->data[0] & ~1U; | ||
1175 | |||
1176 | ret = 1; | ||
1177 | |||
1178 | err: | ||
1179 | EC_POINT_free(pub_key); | ||
1180 | |||
1181 | return ret; | ||
1182 | } | ||
1183 | |||
1145 | EC_KEY * | 1184 | EC_KEY * |
1146 | d2i_ECPrivateKey(EC_KEY **out_ec_key, const unsigned char **in, long len) | 1185 | d2i_ECPrivateKey(EC_KEY **out_ec_key, const unsigned char **in, long len) |
1147 | { | 1186 | { |
@@ -1163,42 +1202,8 @@ d2i_ECPrivateKey(EC_KEY **out_ec_key, const unsigned char **in, long len) | |||
1163 | goto err; | 1202 | goto err; |
1164 | if (!ec_key_set_private_key(ec_key, ec_privatekey->privateKey)) | 1203 | if (!ec_key_set_private_key(ec_key, ec_privatekey->privateKey)) |
1165 | goto err; | 1204 | goto err; |
1166 | 1205 | if (!ec_key_set_public_key(ec_key, ec_privatekey->publicKey)) | |
1167 | if (ec_key->pub_key) | ||
1168 | EC_POINT_free(ec_key->pub_key); | ||
1169 | ec_key->pub_key = EC_POINT_new(ec_key->group); | ||
1170 | if (ec_key->pub_key == NULL) { | ||
1171 | ECerror(ERR_R_EC_LIB); | ||
1172 | goto err; | 1206 | goto err; |
1173 | } | ||
1174 | |||
1175 | if (ec_privatekey->publicKey) { | ||
1176 | const unsigned char *pub_oct; | ||
1177 | size_t pub_oct_len; | ||
1178 | |||
1179 | pub_oct = ASN1_STRING_data(ec_privatekey->publicKey); | ||
1180 | pub_oct_len = ASN1_STRING_length(ec_privatekey->publicKey); | ||
1181 | if (pub_oct == NULL || pub_oct_len <= 0) { | ||
1182 | ECerror(EC_R_BUFFER_TOO_SMALL); | ||
1183 | goto err; | ||
1184 | } | ||
1185 | |||
1186 | /* save the point conversion form */ | ||
1187 | ec_key->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01); | ||
1188 | if (!EC_POINT_oct2point(ec_key->group, ec_key->pub_key, | ||
1189 | pub_oct, pub_oct_len, NULL)) { | ||
1190 | ECerror(ERR_R_EC_LIB); | ||
1191 | goto err; | ||
1192 | } | ||
1193 | } else { | ||
1194 | if (!EC_POINT_mul(ec_key->group, ec_key->pub_key, ec_key->priv_key, | ||
1195 | NULL, NULL, NULL)) { | ||
1196 | ECerror(ERR_R_EC_LIB); | ||
1197 | goto err; | ||
1198 | } | ||
1199 | /* Remember the original private-key-only encoding. */ | ||
1200 | ec_key->enc_flag |= EC_PKEY_NO_PUBKEY; | ||
1201 | } | ||
1202 | 1207 | ||
1203 | EC_PRIVATEKEY_free(ec_privatekey); | 1208 | EC_PRIVATEKEY_free(ec_privatekey); |
1204 | ec_privatekey = NULL; | 1209 | ec_privatekey = NULL; |