Add control to retrieve signature MD.
[openssl.git] / crypto / ec / ec_pmeth.c
index f433076ca121800ed16439d49351a8785afac8ef..4110d5e4f0c867ed8887fbd29bb7bda891fc8145 100644 (file)
@@ -188,7 +188,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
 
        pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
 
 
        pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
 
-       /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is
+       /* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
         * not an error, the result is truncated.
         */
 
         * not an error, the result is truncated.
         */
 
@@ -219,8 +219,18 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
                dctx->gen_group = group;
                return 1;
 
                dctx->gen_group = group;
                return 1;
 
+               case EVP_PKEY_CTRL_EC_PARAM_ENC:
+               if (!dctx->gen_group)
+                       {
+                       ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
+                       return 0;
+                       }
+               EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
+               return 1;
+
                case EVP_PKEY_CTRL_MD:
                if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
                case EVP_PKEY_CTRL_MD:
                if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+                   EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
                    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
                    EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
                    EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
                    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
                    EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
                    EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
@@ -232,6 +242,10 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
                dctx->md = p2;
                return 1;
 
                dctx->md = p2;
                return 1;
 
+               case EVP_PKEY_CTRL_GET_MD:
+               *(const EVP_MD **)p2 = dctx->md;
+               return 1;
+
                case EVP_PKEY_CTRL_PEER_KEY:
                /* Default behaviour is OK */
                case EVP_PKEY_CTRL_DIGESTINIT:
                case EVP_PKEY_CTRL_PEER_KEY:
                /* Default behaviour is OK */
                case EVP_PKEY_CTRL_DIGESTINIT:
@@ -251,7 +265,9 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
        if (!strcmp(type, "ec_paramgen_curve"))
                {
                int nid;
        if (!strcmp(type, "ec_paramgen_curve"))
                {
                int nid;
-               nid = OBJ_sn2nid(value);
+               nid = EC_curve_nist2nid(value);
+               if (nid == NID_undef)
+                       nid = OBJ_sn2nid(value);
                if (nid == NID_undef)
                        nid = OBJ_ln2nid(value);
                if (nid == NID_undef)
                if (nid == NID_undef)
                        nid = OBJ_ln2nid(value);
                if (nid == NID_undef)
@@ -261,6 +277,18 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
                        }
                return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
                }
                        }
                return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
                }
+       else if (!strcmp(type, "ec_param_enc"))
+               {
+               int param_enc;
+               if (!strcmp(value, "explicit"))
+                       param_enc = 0;
+               else if (!strcmp(value, "named_curve"))
+                       param_enc = OPENSSL_EC_NAMED_CURVE;
+               else
+                       return -2;
+               return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
+               }
+                       
        return -2;
        }
 
        return -2;
        }
 
@@ -288,7 +316,8 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
 static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        {
        EC_KEY *ec = NULL;
 static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        {
        EC_KEY *ec = NULL;
-       if (ctx->pkey == NULL)
+       EC_PKEY_CTX *dctx = ctx->data;
+       if (ctx->pkey == NULL && dctx->gen_group == NULL)
                {
                ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
                return 0;
                {
                ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
                return 0;
@@ -297,9 +326,17 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        if (!ec)
                return 0;
        EVP_PKEY_assign_EC_KEY(pkey, ec);
        if (!ec)
                return 0;
        EVP_PKEY_assign_EC_KEY(pkey, ec);
-       /* Note: if error return, pkey is freed by parent routine */
-       if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
-               return 0;
+       if (ctx->pkey)
+               {
+               /* Note: if error return, pkey is freed by parent routine */
+               if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+                       return 0;
+               }
+       else
+               {
+               if (!EC_KEY_set_group(ec, dctx->gen_group))
+                       return 0;
+               }
        return EC_KEY_generate_key(pkey->pkey.ec);
        }
 
        return EC_KEY_generate_key(pkey->pkey.ec);
        }