summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authortb <>2024-10-28 18:03:34 +0000
committertb <>2024-10-28 18:03:34 +0000
commitd5d0119ed0fce70c04b0e4f6e89e9f2a1e6b0137 (patch)
treebe4bf7fc72a8ab8178be601377e9690d8b2641d4 /src/lib
parent7fe8b6a60797c33d896cb1e34f152c4a7c2ac1a7 (diff)
downloadopenbsd-d5d0119ed0fce70c04b0e4f6e89e9f2a1e6b0137.tar.gz
openbsd-d5d0119ed0fce70c04b0e4f6e89e9f2a1e6b0137.tar.bz2
openbsd-d5d0119ed0fce70c04b0e4f6e89e9f2a1e6b0137.zip
d2i_ECPrivateKey: split public key setting into a helper
If the public key is not part of the ECPrivateKey, it needs to be computed. Rather than doing this ad hoc inline, use the function from the ameth that already does this. If it is present, decode it after checking that its unused bits octet is zero. Again use the dedicated setter API to honor an eventual EC_KEY_METHOD. There remains a gross bit reading the point point conversion form out of the first octet of the bit string. This will go away in a later commit. ok jsing
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;