]> www.wagner.pp.ru Git - openssl-gost/engine.git/blobdiff - gost_ameth.c
Fix Coverity #305799
[openssl-gost/engine.git] / gost_ameth.c
index 92319e74c55ae3a85edde2484e30e0647d472e0e..2582d633c83a1114027622c0cd96c46e883238d5 100644 (file)
@@ -224,7 +224,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 +340,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 +369,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
  */
@@ -423,14 +461,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 +513,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 +896,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 +973,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);