X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fecdsa%2Fecs_asn1.c;h=07899150be55ad1f0308564a74dd4bc43b7889e9;hp=542a987bc26e78814e95ae6824fb2b0a75ab8ff9;hb=dde3e83129ecc3ca06a5c4d1698334c26ec4bd9e;hpb=4b71f63ac0de0df0ec321b0522a30e8d3e356760 diff --git a/crypto/ecdsa/ecs_asn1.c b/crypto/ecdsa/ecs_asn1.c index 542a987bc2..07899150be 100644 --- a/crypto/ecdsa/ecs_asn1.c +++ b/crypto/ecdsa/ecs_asn1.c @@ -59,31 +59,10 @@ #include #include -static point_conversion_form_t POINT_CONVERSION_FORM = POINT_CONVERSION_COMPRESSED; - -/* Override the default new methods */ -static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - if(operation == ASN1_OP_NEW_PRE) { - ECDSA_SIG *sig; - sig = OPENSSL_malloc(sizeof(ECDSA_SIG)); - if (sig == NULL) - { - ECDSAerr(ECDSA_F_SIG_CB, ERR_R_MALLOC_FAILURE); - return 0; - } - sig->r = NULL; - sig->s = NULL; - *pval = (ASN1_VALUE *)sig; - return 2; - } - return 1; -} - -ASN1_SEQUENCE_cb(ECDSA_SIG, sig_cb) = { +ASN1_SEQUENCE(ECDSA_SIG) = { ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM), ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM) -} ASN1_SEQUENCE_END_cb(ECDSA_SIG, ECDSA_SIG) +} ASN1_SEQUENCE_END(ECDSA_SIG) IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG) @@ -92,6 +71,8 @@ ASN1_SEQUENCE(X9_62_FIELDID) = { ASN1_SIMPLE(X9_62_FIELDID, parameters, ASN1_ANY) } ASN1_SEQUENCE_END(X9_62_FIELDID) +DECLARE_ASN1_FUNCTIONS_const(X9_62_FIELDID) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(X9_62_FIELDID, X9_62_FIELDID) IMPLEMENT_ASN1_FUNCTIONS_const(X9_62_FIELDID) ASN1_SEQUENCE(X9_62_CURVE) = { @@ -100,10 +81,12 @@ ASN1_SEQUENCE(X9_62_CURVE) = { ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) } ASN1_SEQUENCE_END(X9_62_CURVE) +DECLARE_ASN1_FUNCTIONS_const(X9_62_CURVE) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(X9_62_CURVE, X9_62_CURVE) IMPLEMENT_ASN1_FUNCTIONS_const(X9_62_CURVE) ASN1_SEQUENCE(X9_62_EC_PARAMETERS) = { - ASN1_OPT(X9_62_EC_PARAMETERS, version, ASN1_INTEGER), + ASN1_SIMPLE(X9_62_EC_PARAMETERS, version, ASN1_INTEGER), ASN1_SIMPLE(X9_62_EC_PARAMETERS, fieldID, X9_62_FIELDID), ASN1_SIMPLE(X9_62_EC_PARAMETERS, curve, X9_62_CURVE), ASN1_SIMPLE(X9_62_EC_PARAMETERS, base, ASN1_OCTET_STRING), @@ -111,6 +94,8 @@ ASN1_SEQUENCE(X9_62_EC_PARAMETERS) = { ASN1_SIMPLE(X9_62_EC_PARAMETERS, cofactor, ASN1_INTEGER) } ASN1_SEQUENCE_END(X9_62_EC_PARAMETERS) +DECLARE_ASN1_FUNCTIONS_const(X9_62_EC_PARAMETERS) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(X9_62_EC_PARAMETERS, X9_62_EC_PARAMETERS) IMPLEMENT_ASN1_FUNCTIONS_const(X9_62_EC_PARAMETERS) ASN1_CHOICE(EC_PARAMETERS) = { @@ -119,6 +104,8 @@ ASN1_CHOICE(EC_PARAMETERS) = { ASN1_SIMPLE(EC_PARAMETERS, value.implicitlyCA, ASN1_NULL) } ASN1_CHOICE_END(EC_PARAMETERS) +DECLARE_ASN1_FUNCTIONS_const(EC_PARAMETERS) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PARAMETERS, EC_PARAMETERS) IMPLEMENT_ASN1_FUNCTIONS_const(EC_PARAMETERS) ASN1_SEQUENCE(ECDSAPrivateKey) = { @@ -128,21 +115,11 @@ ASN1_SEQUENCE(ECDSAPrivateKey) = { ASN1_SIMPLE(ECDSAPrivateKey, priv_key, BIGNUM) } ASN1_SEQUENCE_END(ECDSAPrivateKey) +DECLARE_ASN1_FUNCTIONS_const(ECDSAPrivateKey) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSAPrivateKey, ecdsaPrivateKey) IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(ECDSAPrivateKey, ECDSAPrivateKey, ECDSAPrivateKey) IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSAPrivateKey, ECDSAPrivateKey, ecdsaPrivateKey) -ASN1_SEQUENCE(ecdsa_pub_internal) = { - ASN1_SIMPLE(ECDSAPrivateKey, pub_key, ASN1_OCTET_STRING), - ASN1_SIMPLE(ECDSAPrivateKey, parameters, EC_PARAMETERS), -} ASN1_SEQUENCE_END_name(ECDSAPrivateKey, ecdsa_pub_internal) - -ASN1_CHOICE(ECDSAPublicKey) = { - ASN1_SIMPLE(ECDSAPrivateKey, pub_key, ASN1_OCTET_STRING), - ASN1_EX_COMBINE(0, 0, ecdsa_pub_internal) -} ASN1_CHOICE_END_selector(ECDSAPrivateKey, ECDSAPublicKey, write_params) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSAPrivateKey, ECDSAPublicKey, ecdsaPublicKey) - X9_62_FIELDID *ECDSA_get_X9_62_FIELDID(const ECDSA *ecdsa, X9_62_FIELDID *field) { @@ -189,6 +166,7 @@ X9_62_CURVE *ECDSA_get_X9_62_CURVE(const ECDSA *ecdsa, X9_62_CURVE *curve) X9_62_CURVE *ret=NULL; BIGNUM *tmp1=NULL, *tmp2=NULL; unsigned char *buffer=NULL; + unsigned char char_buf = 0; if (!ecdsa || !ecdsa->group) OPENSSL_ECDSA_ABORT(ECDSA_R_MISSING_PARAMETERS) @@ -208,29 +186,38 @@ X9_62_CURVE *ECDSA_get_X9_62_CURVE(const ECDSA *ecdsa, X9_62_CURVE *curve) if (!EC_GROUP_get_curve_GFp(ecdsa->group, NULL, tmp1, tmp2, NULL)) OPENSSL_ECDSA_ABORT(ERR_R_EC_LIB) - if ((len1 = BN_num_bytes(tmp1)) == 0) - OPENSSL_ECDSA_ABORT(ECDSA_R_UNEXPECTED_PARAMETER_LENGTH) - if ((buffer = OPENSSL_malloc(len1)) == NULL) - OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE) - if ((len1 = BN_bn2bin(tmp1, buffer)) == 0) goto err; - if ((ret->a = M_ASN1_OCTET_STRING_new()) == NULL) - OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB) - if (!M_ASN1_OCTET_STRING_set(ret->a, buffer, len1)) + if ((ret->a = M_ASN1_OCTET_STRING_new()) == NULL || + (ret->b = M_ASN1_OCTET_STRING_new()) == NULL ) OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB) - if ((len2 = BN_num_bytes(tmp2)) == 0) - OPENSSL_ECDSA_ABORT(ECDSA_R_UNEXPECTED_PARAMETER_LENGTH) - if (len1 < len2) + len1 = BN_num_bytes(tmp1); + len2 = BN_num_bytes(tmp2); + + if ((buffer = OPENSSL_malloc(len1 > len2 ? len1 : len2)) == NULL) + OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE) + + if (len1 == 0) /* => a == 0 */ { - OPENSSL_free(buffer); - if ((buffer = OPENSSL_malloc(len2)) == NULL) - OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE) + if (!M_ASN1_OCTET_STRING_set(ret->a, &char_buf, 1)) + OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB) + } + else + { + if ((len1 = BN_bn2bin(tmp1, buffer)) == 0) goto err; + if (!M_ASN1_OCTET_STRING_set(ret->a, buffer, len1)) + OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB) + } + if (len2 == 0) /* => b == 0 */ + { + if (!M_ASN1_OCTET_STRING_set(ret->a, &char_buf, 1)) + OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB) + } + else + { + if ((len2 = BN_bn2bin(tmp2, buffer)) == 0) goto err; + if (!M_ASN1_OCTET_STRING_set(ret->b, buffer, len2)) + OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB) } - if ((len2 = BN_bn2bin(tmp2, buffer)) == 0) goto err; - if ((ret->b = M_ASN1_OCTET_STRING_new()) == NULL) - OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB) - if (!M_ASN1_OCTET_STRING_set(ret->b, buffer, len2)) - OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB) if (ecdsa->seed) { @@ -274,14 +261,9 @@ X9_62_EC_PARAMETERS *ECDSA_get_X9_62_EC_PARAMETERS(const ECDSA *ecdsa, X9_62_EC_ } else ret = param; - if (ecdsa->version == 1) - ret->version = NULL; - else - { - if (ret->version == NULL && (ret->version = ASN1_INTEGER_new()) == NULL) - OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE) - if (!ASN1_INTEGER_set(ret->version, (long)ecdsa->version)) goto err; - } + if (ret->version == NULL && (ret->version = ASN1_INTEGER_new()) == NULL) + OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE) + if (!ASN1_INTEGER_set(ret->version, (long)ecdsa->version)) goto err; if ((ret->fieldID = ECDSA_get_X9_62_FIELDID(ecdsa, ret->fieldID)) == NULL) OPENSSL_ECDSA_ABORT(ECDSA_R_ECDSA_GET_X9_62_FIELDID_FAILURE) if ((ret->curve = ECDSA_get_X9_62_CURVE(ecdsa, ret->curve)) == NULL) @@ -374,7 +356,7 @@ ECDSA *ECDSA_x9_62parameters2ecdsa(const X9_62_EC_PARAMETERS *params, EC { int ok=0, reason=ERR_R_EC_LIB, tmp; ECDSA *ret=NULL; - EC_METHOD *meth=NULL; + const EC_METHOD *meth=NULL; BIGNUM *tmp_1=NULL, *tmp_2=NULL, *tmp_3=NULL; EC_POINT *point=NULL; @@ -417,7 +399,7 @@ ECDSA *ECDSA_x9_62parameters2ecdsa(const X9_62_EC_PARAMETERS *params, EC else if (tmp == NID_X9_62_prime_field) { /* TODO : optimal method for the curve */ - (const EC_METHOD *)meth = EC_GFp_mont_method(); + meth = EC_GFp_mont_method(); if ((ret->group = EC_GROUP_new(meth)) == NULL) goto err; if (params->fieldID->parameters->type != V_ASN1_INTEGER) OPENSSL_ECDSA_ABORT(ECDSA_R_UNEXPECTED_ASN1_TYPE) @@ -439,9 +421,7 @@ ECDSA *ECDSA_x9_62parameters2ecdsa(const X9_62_EC_PARAMETERS *params, EC if ((point = EC_POINT_new(ret->group)) == NULL) goto err; } else OPENSSL_ECDSA_ABORT(ECDSA_R_WRONG_FIELD_IDENTIFIER) - /* FIXME!!! It seems like the comparison of data with 0 isn't the - intended thing. */ - if (params->curve->seed != NULL && params->curve->seed->data != 0) + if (params->curve->seed != NULL) { if (ret->seed != NULL) OPENSSL_free(ret->seed); @@ -583,7 +563,6 @@ ECDSA *d2i_ECDSAPrivateKey(ECDSA **a, const unsigned char **in, long len) if ((ret = ECDSA_ecparameters2ecdsa(priv_key->parameters, NULL)) == NULL) OPENSSL_ECDSA_ABORT(ECDSA_R_ECDSA_GET_FAILURE) ret->version = priv_key->version; - ret->write_params = priv_key->write_params; if (priv_key->priv_key) { if ((ret->priv_key = BN_dup(priv_key->priv_key)) == NULL) @@ -641,85 +620,58 @@ err: if (!ok) } -ECDSA *d2i_ECDSAPublicKey(ECDSA **a, const unsigned char **in, long len) +ECDSA *ECDSAPublicKey_set_octet_string(ECDSA **a, const unsigned char **in, long len) { - int reason=ERR_R_BN_LIB, ok=0, ecdsa_new=1; ECDSA *ret=NULL; - ECDSAPrivateKey *priv_key=NULL; - if (a && *a) + if (a == NULL || (*a) == NULL || (*a)->group == NULL) { - ecdsa_new = 0; - ret = *a; + /* sorry, but a EC_GROUP-structur is necessary + * to set the public key */ + ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ECDSA_R_MISSING_PARAMETERS); + return 0; } - else if ((ret = ECDSA_new()) == NULL) - OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE); - if ((priv_key = ECDSAPrivateKey_new()) == NULL) - OPENSSL_ECDSA_ABORT(ECDSA_R_ECDSAPRIVATEKEY_NEW_FAILURE) - if ((priv_key = d2i_ecdsaPublicKey(&priv_key, in, len)) == NULL) - OPENSSL_ECDSA_ABORT(ECDSA_R_D2I_ECDSA_PRIVATEKEY_FAILURE) - if (priv_key->write_params == 0) + ret = *a; + if (ret->pub_key == NULL && (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { - if (ecdsa_new || !ret->group) - OPENSSL_ECDSA_ABORT(ECDSA_R_MISSING_PARAMETERS) - if (ret->pub_key == NULL && (ret->pub_key = EC_POINT_new(ret->group)) == NULL) - OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE) - if (!EC_POINT_oct2point(ret->group, ret->pub_key, priv_key->pub_key->data, - priv_key->pub_key->length, NULL)) - OPENSSL_ECDSA_ABORT(ERR_R_EC_LIB) - } - else if (priv_key->write_params == 1) - { - if ((ret = ECDSA_ecparameters2ecdsa(priv_key->parameters, ret)) == NULL) - OPENSSL_ECDSA_ABORT(ECDSA_R_ECDSA_GET_FAILURE) - if (ret->pub_key == NULL && (ret->pub_key = EC_POINT_new(ret->group)) == NULL) - OPENSSL_ECDSA_ABORT(ERR_R_EC_LIB) - if (!EC_POINT_oct2point(ret->group, ret->pub_key, priv_key->pub_key->data, - priv_key->pub_key->length, NULL)) - OPENSSL_ECDSA_ABORT(ERR_R_EC_LIB) - } - else OPENSSL_ECDSA_ABORT(ECDSA_R_UNEXPECTED_PARAMETER) - ret->write_params = 1; - ok = 1; -err : if (!ok) + ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) { - if (ret && ecdsa_new) ECDSA_free(ret); - ret = NULL; - ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, reason); + ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ERR_R_EC_LIB); + return 0; } - if (priv_key) ECDSAPrivateKey_free(priv_key); - return(ret); + ECDSA_set_conversion_form(ret, (point_conversion_form_t)(*in[0] & ~0x01)); + return ret; } -int i2d_ECDSAPublicKey(ECDSA *a, unsigned char **out) +int ECDSAPublicKey_get_octet_string(ECDSA *a, unsigned char **out) { - int ret=0, reason=ERR_R_EC_LIB, ok=0; - unsigned char *buffer=NULL; - size_t buf_len=0; - ECDSAPrivateKey *priv_key=NULL; + size_t buf_len=0; if (a == NULL) - OPENSSL_ECDSA_ABORT(ECDSA_R_MISSING_PARAMETERS) - if ((priv_key = ECDSAPrivateKey_new()) == NULL) - OPENSSL_ECDSA_ABORT(ECDSA_R_ECDSAPRIVATEKEY_NEW_FAILURE) - if ((priv_key->parameters = ECDSA_get_EC_PARAMETERS(a, priv_key->parameters)) == NULL) - OPENSSL_ECDSA_ABORT(ECDSA_R_ECDSA_GET_X9_62_EC_PARAMETERS_FAILURE) - priv_key->version = a->version; - priv_key->write_params = a->write_params; - buf_len = EC_POINT_point2oct(a->group, a->pub_key, POINT_CONVERSION_FORM, NULL, 0, NULL); - if (!buf_len || (buffer = OPENSSL_malloc(buf_len)) == NULL) - OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE) - if (!EC_POINT_point2oct(a->group, a->pub_key, POINT_CONVERSION_FORM, - buffer, buf_len, NULL)) goto err; - if (!M_ASN1_OCTET_STRING_set(priv_key->pub_key, buffer, buf_len)) - OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB) - if ((ret = i2d_ecdsaPublicKey(priv_key, out)) == 0) - OPENSSL_ECDSA_ABORT(ECDSA_R_I2D_ECDSA_PUBLICKEY) - ok = 1; - -err: if (!ok) - ECDSAerr(ECDSA_F_I2D_ECDSAPUBLICKEY, reason); - if (buffer) OPENSSL_free(buffer); - if (priv_key) ECDSAPrivateKey_free(priv_key); - return(ok?ret:0); + { + ECDSAerr(ECDSA_F_I2D_ECDSAPUBLICKEY, ECDSA_R_MISSING_PARAMETERS); + return 0; + } + buf_len = EC_POINT_point2oct(a->group, a->pub_key, ECDSA_get_conversion_form(a), NULL, 0, NULL); + if (out == NULL || buf_len == 0) + /* out == NULL => just return the length of the octet string */ + return buf_len; + if (*out == NULL) + if ((*out = OPENSSL_malloc(buf_len)) == NULL) + { + ECDSAerr(ECDSA_F_I2D_ECDSAPUBLICKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!EC_POINT_point2oct(a->group, a->pub_key, ECDSA_get_conversion_form(a), + *out, buf_len, NULL)) + { + ECDSAerr(ECDSA_F_I2D_ECDSAPUBLICKEY, ERR_R_EC_LIB); + OPENSSL_free(*out); + *out = NULL; + return 0; + } + return buf_len; }