Latest update.
This commit is contained in:
+147
-12
@@ -13,6 +13,9 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/objects.h>
|
||||
#include "internal/nelem.h"
|
||||
#include "internal/asn1_dsa.h"
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
|
||||
int EC_GROUP_get_basis_type(const EC_GROUP *group)
|
||||
{
|
||||
@@ -446,6 +449,7 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
|
||||
unsigned char *buffer = NULL;
|
||||
const EC_POINT *point = NULL;
|
||||
point_conversion_form_t form;
|
||||
ASN1_INTEGER *orig;
|
||||
|
||||
if (params == NULL) {
|
||||
if ((ret = ECPARAMETERS_new()) == NULL) {
|
||||
@@ -496,8 +500,9 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
|
||||
ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
|
||||
ret->order = BN_to_ASN1_INTEGER(tmp, orig = ret->order);
|
||||
if (ret->order == NULL) {
|
||||
ret->order = orig;
|
||||
ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -505,8 +510,9 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
|
||||
/* set the cofactor (optional) */
|
||||
tmp = EC_GROUP_get0_cofactor(group);
|
||||
if (tmp != NULL) {
|
||||
ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
|
||||
ret->cofactor = BN_to_ASN1_INTEGER(tmp, orig = ret->cofactor);
|
||||
if (ret->cofactor == NULL) {
|
||||
ret->cofactor = orig;
|
||||
ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -568,10 +574,12 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
|
||||
EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
|
||||
{
|
||||
int ok = 0, tmp;
|
||||
EC_GROUP *ret = NULL;
|
||||
EC_GROUP *ret = NULL, *dup = NULL;
|
||||
BIGNUM *p = NULL, *a = NULL, *b = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
long field_bits;
|
||||
int curve_name = NID_undef;
|
||||
BN_CTX *ctx = NULL;
|
||||
|
||||
if (!params->fieldID || !params->fieldID->fieldType ||
|
||||
!params->fieldID->p.ptr) {
|
||||
@@ -789,18 +797,79 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the explicit parameters group just created matches one of the
|
||||
* built-in curves.
|
||||
*
|
||||
* We create a copy of the group just built, so that we can remove optional
|
||||
* fields for the lookup: we do this to avoid the possibility that one of
|
||||
* the optional parameters is used to force the library into using a less
|
||||
* performant and less secure EC_METHOD instead of the specialized one.
|
||||
* In any case, `seed` is not really used in any computation, while a
|
||||
* cofactor different from the one in the built-in table is just
|
||||
* mathematically wrong anyway and should not be used.
|
||||
*/
|
||||
if ((ctx = BN_CTX_new()) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if ((dup = EC_GROUP_dup(ret)) == NULL
|
||||
|| EC_GROUP_set_seed(dup, NULL, 0) != 1
|
||||
|| !EC_GROUP_set_generator(dup, point, a, NULL)) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if ((curve_name = ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
|
||||
/*
|
||||
* The input explicit parameters successfully matched one of the
|
||||
* built-in curves: often for built-in curves we have specialized
|
||||
* methods with better performance and hardening.
|
||||
*
|
||||
* In this case we replace the `EC_GROUP` created through explicit
|
||||
* parameters with one created from a named group.
|
||||
*/
|
||||
EC_GROUP *named_group = NULL;
|
||||
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
/*
|
||||
* NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for
|
||||
* the same curve, we prefer the SECP nid when matching explicit
|
||||
* parameters as that is associated with a specialized EC_METHOD.
|
||||
*/
|
||||
if (curve_name == NID_wap_wsg_idm_ecid_wtls12)
|
||||
curve_name = NID_secp224r1;
|
||||
#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
|
||||
|
||||
if ((named_group = EC_GROUP_new_by_curve_name(curve_name)) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
EC_GROUP_free(ret);
|
||||
ret = named_group;
|
||||
|
||||
/*
|
||||
* Set the flag so that EC_GROUPs created from explicit parameters are
|
||||
* serialized using explicit parameters by default.
|
||||
*/
|
||||
EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE);
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
if (!ok) {
|
||||
EC_GROUP_clear_free(ret);
|
||||
EC_GROUP_free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
EC_GROUP_free(dup);
|
||||
|
||||
BN_free(p);
|
||||
BN_free(a);
|
||||
BN_free(b);
|
||||
EC_POINT_free(point);
|
||||
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -861,7 +930,7 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
|
||||
}
|
||||
|
||||
if (a) {
|
||||
EC_GROUP_clear_free(*a);
|
||||
EC_GROUP_free(*a);
|
||||
*a = group;
|
||||
}
|
||||
|
||||
@@ -909,7 +978,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
|
||||
ret = *a;
|
||||
|
||||
if (priv_key->parameters) {
|
||||
EC_GROUP_clear_free(ret->group);
|
||||
EC_GROUP_free(ret->group);
|
||||
ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters);
|
||||
}
|
||||
|
||||
@@ -1137,14 +1206,10 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out)
|
||||
return buf_len;
|
||||
}
|
||||
|
||||
ASN1_SEQUENCE(ECDSA_SIG) = {
|
||||
ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
|
||||
ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
|
||||
} static_ASN1_SEQUENCE_END(ECDSA_SIG)
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(ECDSA_SIG)
|
||||
DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECDSA_SIG, ECDSA_SIG)
|
||||
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG)
|
||||
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
ECDSA_SIG *ECDSA_SIG_new(void)
|
||||
{
|
||||
@@ -1163,6 +1228,74 @@ void ECDSA_SIG_free(ECDSA_SIG *sig)
|
||||
OPENSSL_free(sig);
|
||||
}
|
||||
|
||||
ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **psig, const unsigned char **ppin, long len)
|
||||
{
|
||||
ECDSA_SIG *sig;
|
||||
|
||||
if (len < 0)
|
||||
return NULL;
|
||||
if (psig != NULL && *psig != NULL) {
|
||||
sig = *psig;
|
||||
} else {
|
||||
sig = ECDSA_SIG_new();
|
||||
if (sig == NULL)
|
||||
return NULL;
|
||||
}
|
||||
if (sig->r == NULL)
|
||||
sig->r = BN_new();
|
||||
if (sig->s == NULL)
|
||||
sig->s = BN_new();
|
||||
if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) {
|
||||
if (psig == NULL || *psig == NULL)
|
||||
ECDSA_SIG_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
if (psig != NULL && *psig == NULL)
|
||||
*psig = sig;
|
||||
return sig;
|
||||
}
|
||||
|
||||
int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **ppout)
|
||||
{
|
||||
BUF_MEM *buf = NULL;
|
||||
size_t encoded_len;
|
||||
WPACKET pkt;
|
||||
|
||||
if (ppout == NULL) {
|
||||
if (!WPACKET_init_null(&pkt, 0))
|
||||
return -1;
|
||||
} else if (*ppout == NULL) {
|
||||
if ((buf = BUF_MEM_new()) == NULL
|
||||
|| !WPACKET_init_len(&pkt, buf, 0)) {
|
||||
BUF_MEM_free(buf);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!encode_der_dsa_sig(&pkt, sig->r, sig->s)
|
||||
|| !WPACKET_get_total_written(&pkt, &encoded_len)
|
||||
|| !WPACKET_finish(&pkt)) {
|
||||
BUF_MEM_free(buf);
|
||||
WPACKET_cleanup(&pkt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ppout != NULL) {
|
||||
if (*ppout == NULL) {
|
||||
*ppout = (unsigned char *)buf->data;
|
||||
buf->data = NULL;
|
||||
BUF_MEM_free(buf);
|
||||
} else {
|
||||
*ppout += encoded_len;
|
||||
}
|
||||
}
|
||||
|
||||
return (int)encoded_len;
|
||||
}
|
||||
|
||||
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
|
||||
{
|
||||
if (pr != NULL)
|
||||
@@ -1192,6 +1325,7 @@ int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
int ECDSA_size(const EC_KEY *r)
|
||||
{
|
||||
int ret, i;
|
||||
@@ -1219,3 +1353,4 @@ int ECDSA_size(const EC_KEY *r)
|
||||
ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user