add ECDSA_size to ec_asn1.c
[openssl.git] / crypto / ec / ec_asn1.c
index ebafc10de7aa38b26d143eaede1adb4caa4cea3f..99d081440cdb078b3dae600850ba7b8432ccd84b 100644 (file)
@@ -204,7 +204,7 @@ ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
         ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
         ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
         ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
-} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
+} static_ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
 
 DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
@@ -221,7 +221,7 @@ ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
         ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
         ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
         ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
-} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
+} static_ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
 
 DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
@@ -236,13 +236,13 @@ ASN1_ADB(X9_62_FIELDID) = {
 ASN1_SEQUENCE(X9_62_FIELDID) = {
         ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
         ASN1_ADB_OBJECT(X9_62_FIELDID)
-} ASN1_SEQUENCE_END(X9_62_FIELDID)
+} static_ASN1_SEQUENCE_END(X9_62_FIELDID)
 
 ASN1_SEQUENCE(X9_62_CURVE) = {
         ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
         ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
         ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
-} ASN1_SEQUENCE_END(X9_62_CURVE)
+} static_ASN1_SEQUENCE_END(X9_62_CURVE)
 
 ASN1_SEQUENCE(ECPARAMETERS) = {
         ASN1_SIMPLE(ECPARAMETERS, version, LONG),
@@ -251,7 +251,7 @@ ASN1_SEQUENCE(ECPARAMETERS) = {
         ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
         ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
         ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
-} ASN1_SEQUENCE_END(ECPARAMETERS)
+} static_ASN1_SEQUENCE_END(ECPARAMETERS)
 
 DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
@@ -260,7 +260,7 @@ ASN1_CHOICE(ECPKPARAMETERS) = {
         ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
         ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
         ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
-} ASN1_CHOICE_END(ECPKPARAMETERS)
+} static_ASN1_CHOICE_END(ECPKPARAMETERS)
 
 DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
 DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
@@ -271,7 +271,7 @@ ASN1_SEQUENCE(EC_PRIVATEKEY) = {
         ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
         ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
         ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
-} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
+} static_ASN1_SEQUENCE_END(EC_PRIVATEKEY)
 
 DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
 DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
@@ -383,7 +383,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
                 goto err;
 
             char_two->p.tpBasis = ASN1_INTEGER_new();
-            if (!char_two->p.tpBasis) {
+            if (char_two->p.tpBasis == NULL) {
                 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
                 goto err;
             }
@@ -398,7 +398,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
                 goto err;
 
             char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
-            if (!char_two->p.ppBasis) {
+            if (char_two->p.ppBasis == NULL) {
                 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
                 goto err;
             }
@@ -411,7 +411,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
 
             /* for ONB the parameters are (asn1) NULL */
             char_two->p.onBasis = ASN1_NULL_new();
-            if (!char_two->p.onBasis) {
+            if (char_two->p.onBasis == NULL) {
                 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
                 goto err;
             }
@@ -951,8 +951,9 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
 {
     EC_GROUP *group = NULL;
     ECPKPARAMETERS *params = NULL;
+    const unsigned char *p = *in;
 
-    if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
+    if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) {
         ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
         ECPKPARAMETERS_free(params);
         return NULL;
@@ -970,6 +971,7 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
     }
 
     ECPKPARAMETERS_free(params);
+    *in = p;
     return (group);
 }
 
@@ -996,8 +998,9 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
 {
     EC_KEY *ret = NULL;
     EC_PRIVATEKEY *priv_key = NULL;
+    const unsigned char *p = *in;
 
-    if ((priv_key = d2i_EC_PRIVATEKEY(NULL, in, len)) == NULL) {
+    if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) {
         ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
         return NULL;
     }
@@ -1023,6 +1026,12 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
     ret->version = priv_key->version;
 
     if (priv_key->privateKey) {
+        if (ret->priv_key == NULL)
+            ret->priv_key = BN_secure_new();
+        if (ret->priv_key == NULL) {
+            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
         ret->priv_key = BN_bin2bn(ASN1_STRING_data(priv_key->privateKey),
                                   ASN1_STRING_length(priv_key->privateKey),
                                   ret->priv_key);
@@ -1075,6 +1084,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
     if (a)
         *a = ret;
     EC_PRIVATEKEY_free(priv_key);
+    *in = p;
     return (ret);
 
  err:
@@ -1292,3 +1302,54 @@ int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
         *out += buf_len;
     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_const(ECDSA_SIG)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
+IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG)
+
+void ECDSA_SIG_get0(BIGNUM **pr, BIGNUM **ps, ECDSA_SIG *sig)
+{
+    if (pr)
+        *pr = sig->r;
+    if (ps)
+        *ps = sig->s;
+}
+
+int ECDSA_size(const EC_KEY *r)
+{
+    int ret, i;
+    ASN1_INTEGER bs;
+    BIGNUM *order = NULL;
+    unsigned char buf[4];
+    const EC_GROUP *group;
+
+    if (r == NULL)
+        return 0;
+    group = EC_KEY_get0_group(r);
+    if (group == NULL)
+        return 0;
+
+    if ((order = BN_new()) == NULL)
+        return 0;
+    if (!EC_GROUP_get_order(group, order, NULL)) {
+        BN_clear_free(order);
+        return 0;
+    }
+    i = BN_num_bits(order);
+    bs.length = (i + 7) / 8;
+    bs.data = buf;
+    bs.type = V_ASN1_INTEGER;
+    /* If the top bit is set the asn1 encoding is 1 larger. */
+    buf[0] = 0xff;
+
+    i = i2d_ASN1_INTEGER(&bs, NULL);
+    i += i;                     /* r and s */
+    ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
+    BN_clear_free(order);
+    return (ret);
+}