summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c77
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
1145static int
1146ec_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
1145EC_KEY * 1184EC_KEY *
1146d2i_ECPrivateKey(EC_KEY **out_ec_key, const unsigned char **in, long len) 1185d2i_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;