From: Douglas E Engert Date: Wed, 25 Mar 2015 23:52:28 +0000 (+0000) Subject: Ensure EC private keys retain leading zeros X-Git-Tag: OpenSSL_1_1_0-pre1~1363 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=30cd4ff294252c4b6a4b69cbef6a5b4117705d22;p=oweals%2Fopenssl.git Ensure EC private keys retain leading zeros RFC5915 requires the use of the I2OSP primitive as defined in RFC3447 for storing an EC Private Key. This converts the private key into an OCTETSTRING and retains any leading zeros. This commit ensures that those leading zeros are present if required. Reviewed-by: Andy Polyakov --- diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index 9bba26ed7e..97c590691d 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -1110,7 +1110,7 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) { int ret = 0, ok = 0; unsigned char *buffer = NULL; - size_t buf_len = 0, tmp_len; + size_t buf_len = 0, tmp_len, bn_len; EC_PRIVATEKEY *priv_key = NULL; if (a == NULL || a->group == NULL || a->priv_key == NULL || @@ -1126,18 +1126,32 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) priv_key->version = a->version; - buf_len = (size_t)BN_num_bytes(a->priv_key); + bn_len = (size_t)BN_num_bytes(a->priv_key); + + /* Octetstring may need leading zeros if BN is to short */ + + buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8; + + if (bn_len > buf_len) { + ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); + goto err; + } + buffer = OPENSSL_malloc(buf_len); if (buffer == NULL) { ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); goto err; } - if (!BN_bn2bin(a->priv_key, buffer)) { + if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) { ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); goto err; } + if (buf_len - bn_len > 0) { + memset(buffer, 0, buf_len - bn_len); + } + if (!ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); goto err;