]> www.wagner.pp.ru Git - openssl-gost/engine.git/blobdiff - gost_ameth.c
Merge branch 'update-codeql-analysis' of https://github.com/levitte/engine into levit...
[openssl-gost/engine.git] / gost_ameth.c
index 92319e74c55ae3a85edde2484e30e0647d472e0e..d3ba81526932352a3c0312a8d21b2fc21856ca3f 100644 (file)
@@ -43,6 +43,7 @@ static int pkey_bits_gost(const EVP_PKEY *pk)
 
     switch (EVP_PKEY_base_id(pk)) {
     case NID_id_GostR3410_2001:
+    case NID_id_GostR3410_2001DH:
     case NID_id_GostR3410_2012_256:
         return 256;
     case NID_id_GostR3410_2012_512:
@@ -87,6 +88,7 @@ static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
        }
         break;
     case NID_id_GostR3410_2001:
+    case NID_id_GostR3410_2001DH:
         pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key_ptr));
         gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
         break;
@@ -127,6 +129,7 @@ static int gost_decode_nid_params(EVP_PKEY *pkey, int pkey_nid, int param_nid)
     case NID_id_GostR3410_2012_256:
     case NID_id_GostR3410_2012_512:
     case NID_id_GostR3410_2001:
+    case NID_id_GostR3410_2001DH:
         if (!key_ptr) {
             key_ptr = EC_KEY_new();
             if (!EVP_PKEY_assign(pkey, pkey_nid, key_ptr)) {
@@ -186,6 +189,7 @@ static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv)
     case NID_id_GostR3410_2012_512:
     case NID_id_GostR3410_2012_256:
     case NID_id_GostR3410_2001:
+    case NID_id_GostR3410_2001DH:
         {
             EC_KEY *ec = EVP_PKEY_get0(pkey);
             if (!ec) {
@@ -210,6 +214,7 @@ BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey)
     case NID_id_GostR3410_2012_512:
     case NID_id_GostR3410_2012_256:
     case NID_id_GostR3410_2001:
+    case NID_id_GostR3410_2001DH:
         {
             EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
             if (ec)
@@ -224,7 +229,7 @@ BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey)
  * GOST CMS processing functions
  */
 /* FIXME reaarange declarations */
-static int pub_decode_gost_ec(EVP_PKEY *pk, X509_PUBKEY *pub);
+static int pub_decode_gost_ec(EVP_PKEY *pk, const X509_PUBKEY *pub);
 
 static int gost_cms_set_kari_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
 {
@@ -340,6 +345,8 @@ static int gost_cms_set_ktri_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *
                        gctx->cipher_nid = NID_magma_ctr;
                        break;
 
+               case NID_id_GostR3410_2001:
+               case NID_id_GostR3410_2001DH:
                case NID_id_GostR3410_2012_256:
                case NID_id_GostR3410_2012_512:
                        gctx->cipher_nid = NID_id_Gost28147_89;
@@ -367,6 +374,42 @@ static int gost_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
        GOSTerr(GOST_F_GOST_CMS_SET_SHARED_INFO, GOST_R_UNSUPPORTED_RECIPIENT_INFO);
        return 0;
 }
+
+static ASN1_STRING *gost_encode_cms_params(int ka_nid)
+{
+       ASN1_STRING *ret = NULL;
+       ASN1_STRING *params = ASN1_STRING_new();
+
+       /* It's a hack. We have only one OID here, so we can use
+        * GOST_KEY_PARAMS which is a sequence of 3 OIDs,
+        * the 1st one is mandatory and the rest are optional */
+       GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
+
+       if (params == NULL || gkp == NULL) {
+                 GOSTerr(GOST_F_GOST_ENCODE_CMS_PARAMS, ERR_R_MALLOC_FAILURE);
+                       goto end;
+       }
+
+       gkp->key_params = OBJ_nid2obj(ka_nid);
+       params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
+
+       if (params->length < 0) {
+                 GOSTerr(GOST_F_GOST_ENCODE_CMS_PARAMS, ERR_R_MALLOC_FAILURE);
+                       goto end;
+       }
+
+       params->type = V_ASN1_SEQUENCE;
+       ret = params;
+
+end:
+       GOST_KEY_PARAMS_free(gkp);
+
+       if (ret == NULL)
+               ASN1_STRING_free(params);
+
+       return ret;
+}
+
 /*
  * Control function
  */
@@ -383,6 +426,7 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
         md_nid = NID_id_GostR3411_2012_256;
         break;
     case NID_id_GostR3410_2001:
+    case NID_id_GostR3410_2001DH:
     case NID_id_GostR3410_94:
         md_nid = NID_id_GostR3411_94;
         break;
@@ -423,14 +467,44 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
 #ifndef OPENSSL_NO_CMS
     case ASN1_PKEY_CTRL_CMS_ENVELOPE:
         if (arg1 == 0) {
-            ASN1_STRING *params = encode_gost_algor_params(pkey);
-            if (!params) {
-                return -1;
-            }
-            CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL,
-                                             NULL, &alg1);
-            X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_id(pkey)),
-                            V_ASN1_SEQUENCE, params);
+          EVP_PKEY_CTX *pctx;
+          CMS_RecipientInfo *ri = arg2;
+
+          struct gost_pmeth_data *gctx = NULL;
+          ASN1_STRING *params = NULL;
+
+          pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+          if (!pctx)
+            return 0;
+
+          gctx = EVP_PKEY_CTX_get_data(pctx);
+
+          switch (gctx->cipher_nid) {
+            case NID_magma_ctr:
+            case NID_kuznyechik_ctr:
+              {
+                int ka_nid;
+
+                nid = (gctx->cipher_nid == NID_magma_ctr) ? NID_magma_kexp15 :
+                  NID_kuznyechik_kexp15;
+
+                ka_nid = (EVP_PKEY_base_id(pkey) == NID_id_GostR3410_2012_256) ?
+                  NID_id_tc26_agreement_gost_3410_2012_256 : NID_id_tc26_agreement_gost_3410_2012_512;
+
+                params = gost_encode_cms_params(ka_nid);
+              }
+              break;
+            default:
+                params = encode_gost_algor_params(pkey);
+              break;
+          }
+
+          if (params == NULL)
+              return -1;
+
+          CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL,
+              NULL, &alg1);
+          X509_ALGOR_set0(alg1, OBJ_nid2obj(nid), V_ASN1_SEQUENCE, params);
         } else {
           EVP_PKEY_CTX *pctx;
           CMS_RecipientInfo *ri = arg2;
@@ -445,10 +519,12 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
         *(int *)arg2 = CMS_RECIPINFO_TRANS;
         return 1;
        case ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED:
-                       if (arg1 == CMS_RECIPINFO_AGREE || arg1 == CMS_RECIPINFO_TRANS)
-                               return 1;
+                       if (arg1 == CMS_RECIPINFO_AGREE || arg1 == CMS_RECIPINFO_TRANS) {
+          *(int *)arg2 = 1;
+                                 return 1;
+      }
                        else
-                               return 0;
+                                 return 0;
                        break;
 #endif
 #endif
@@ -826,7 +902,7 @@ static int param_cmp_gost_ec(const EVP_PKEY *a, const EVP_PKEY *b)
 }
 
 /* ---------- Public key functions * --------------------------------------*/
-static int pub_decode_gost_ec(EVP_PKEY *pk, X509_PUBKEY *pub)
+static int pub_decode_gost_ec(EVP_PKEY *pk, const X509_PUBKEY *pub)
 {
     X509_ALGOR *palg = NULL;
     const unsigned char *pubkey_buf = NULL;
@@ -903,11 +979,14 @@ static int pub_encode_gost_ec(X509_PUBKEY *pub, const EVP_PKEY *pk)
     pval = params;
 
     order = BN_new();
-    if (!order) {
+    if (order == NULL || EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL) == 0) {
         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE);
         goto err;
     }
-    EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL);
+    if (EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL) == 0) {
+        GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     pub_key = EC_KEY_get0_public_key(ec);
     if (!pub_key) {
         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, GOST_R_PUBLIC_KEY_UNDEFINED);
@@ -986,6 +1065,7 @@ static int pkey_size_gost(const EVP_PKEY *pk)
     switch (EVP_PKEY_base_id(pk)) {
     case NID_id_GostR3410_94:
     case NID_id_GostR3410_2001:
+    case NID_id_GostR3410_2001DH:
     case NID_id_GostR3410_2012_256:
         return 64;
     case NID_id_GostR3410_2012_512:
@@ -1080,6 +1160,7 @@ int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth,
         return 0;
     switch (nid) {
     case NID_id_GostR3410_2001:
+    case NID_id_GostR3410_2001DH:
         EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost_ec);
         EVP_PKEY_asn1_set_private(*ameth,
                                   priv_decode_gost, priv_encode_gost,