]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
lib: implement support for updated GOST PublicKeyParameters
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Wed, 25 Sep 2019 15:13:37 +0000 (18:13 +0300)
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Sun, 6 Oct 2019 16:32:05 +0000 (19:32 +0300)
Recomendation for standardization R 1323565.1.023-2018 has made changes
to PublicKeyParameters for GOST R 34.10-2012 keys. It has removed
encryptionParamSet (since now S-BOX is basically fixed as TC26-Z) and
made digestParamSet OPTIONAL (as it can be concluded from public key
OID). Implement these requirements.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
lib/gnutls.asn
lib/gnutls_asn1_tab.c
lib/x509/key_decode.c
lib/x509/key_encode.c

index 209577b70ca36a02bef7ddf6c81eb7df28d0521c..3e6b67ea568282d043a044316d64f3122fe78d0f 100644 (file)
@@ -123,6 +123,11 @@ RSAPSSParameters ::= SEQUENCE {
 
 -- GOST R 34.10
 GOSTParameters ::= SEQUENCE {
+   publicKeyParamSet  OBJECT IDENTIFIER,
+   digestParamSet     OBJECT IDENTIFIER OPTIONAL
+}
+
+GOSTParametersOld ::= SEQUENCE {
    publicKeyParamSet  OBJECT IDENTIFIER,
    digestParamSet     OBJECT IDENTIFIER,
    encryptionParamSet OBJECT IDENTIFIER OPTIONAL
index 86d621eb66297e47806265a968eac2e097397a71..018db87394d1ece7b679b664bf6cfdd9a8794c60 100644 (file)
@@ -91,6 +91,9 @@ const asn1_static_node gnutls_asn1_tab[] = {
   { NULL, 2056, "3"},
   { "GOSTParameters", 1610612741, NULL },
   { "publicKeyParamSet", 1073741836, NULL },
+  { "digestParamSet", 16396, NULL },
+  { "GOSTParametersOld", 1610612741, NULL },
+  { "publicKeyParamSet", 1073741836, NULL },
   { "digestParamSet", 1073741836, NULL },
   { "encryptionParamSet", 16396, NULL },
   { "GOSTPrivateKey", 1073741831, NULL },
index 00f1950acbb75c1fd188010277a58513fe70526e..e42f5e09621dbc636c9f74bfd1ba549ab91139fd 100644 (file)
@@ -453,6 +453,8 @@ _gnutls_x509_read_gost_params(uint8_t * der, int dersize,
        gnutls_gost_paramset_t param;
 
        if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
+                                      algo == GNUTLS_PK_GOST_01 ?
+                                      "GNUTLS.GOSTParametersOld" :
                                       "GNUTLS.GOSTParameters",
                                       &spk)) != ASN1_SUCCESS) {
                gnutls_assert();
@@ -487,7 +489,8 @@ _gnutls_x509_read_gost_params(uint8_t * der, int dersize,
        /* Read the digest */
        oid_size = sizeof(oid);
        ret = asn1_read_value(spk, "digestParamSet", oid, &oid_size);
-       if (ret != ASN1_SUCCESS) {
+       if (ret != ASN1_SUCCESS &&
+           ret != ASN1_ELEMENT_NOT_FOUND) {
                gnutls_assert();
                ret = _gnutls_asn2err(ret);
                goto cleanup;
index 5cd6763cd075d6f8ab4adaafe28f6fe5333b93c3..9035ea17064d6fdb7335050ab44f1395946529f1 100644 (file)
@@ -540,7 +540,10 @@ _gnutls_x509_write_gost_params(gnutls_pk_params_st * params,
 
 
        if ((result = asn1_create_element
-            (_gnutls_get_gnutls_asn(), "GNUTLS.GOSTParameters", &spk))
+            (_gnutls_get_gnutls_asn(),
+             params->algo == GNUTLS_PK_GOST_01 ?
+             "GNUTLS.GOSTParametersOld" :
+             "GNUTLS.GOSTParameters", &spk))
            != ASN1_SUCCESS) {
                gnutls_assert();
                return _gnutls_asn2err(result);
@@ -554,21 +557,22 @@ _gnutls_x509_write_gost_params(gnutls_pk_params_st * params,
                goto cleanup;
        }
 
+       /* For compatibility per R 1323565.1.023—2018 provide digest OID only
+        * for GOST-2001 keys or GOST-2012 keys with CryptoPro curves. Do not
+        * set this optional paramter for TC26 curves */
        if (params->algo == GNUTLS_PK_GOST_01)
                oid = HASH_OID_GOST_R_3411_94_CRYPTOPRO_PARAMS;
-       else if (params->algo == GNUTLS_PK_GOST_12_256)
+       else if (params->algo == GNUTLS_PK_GOST_12_256 &&
+                (params->curve == GNUTLS_ECC_CURVE_GOST256CPA ||
+                 params->curve == GNUTLS_ECC_CURVE_GOST256CPB ||
+                 params->curve == GNUTLS_ECC_CURVE_GOST256CPC ||
+                 params->curve == GNUTLS_ECC_CURVE_GOST256CPXA ||
+                 params->curve == GNUTLS_ECC_CURVE_GOST256CPXB))
                oid = HASH_OID_STREEBOG_256;
-       else if (params->algo == GNUTLS_PK_GOST_12_512)
-               oid = HASH_OID_STREEBOG_512;
-       else {
-               gnutls_assert();
-               result = GNUTLS_E_INVALID_REQUEST;
-               goto cleanup;
-       }
+       else
+               oid = NULL;
 
-       if ((result =
-            asn1_write_value(spk, "digestParamSet", oid,
-                             1)) != ASN1_SUCCESS) {
+       if ((result = asn1_write_value(spk, "digestParamSet", oid, oid ? 1 : 0)) != ASN1_SUCCESS) {
                gnutls_assert();
                result = _gnutls_asn2err(result);
                goto cleanup;
@@ -581,15 +585,17 @@ _gnutls_x509_write_gost_params(gnutls_pk_params_st * params,
                goto cleanup;
        }
 
-       if (params->gost_params == _gnutls_gost_paramset_default(params->algo))
-               oid = NULL;
+       if (params->algo == GNUTLS_PK_GOST_01) {
+               if (params->gost_params == _gnutls_gost_paramset_default(params->algo))
+                       oid = NULL;
 
-       if ((result =
-            asn1_write_value(spk, "encryptionParamSet", oid,
-                             oid ? 1 : 0)) != ASN1_SUCCESS) {
-               gnutls_assert();
-               result = _gnutls_asn2err(result);
-               goto cleanup;
+               if ((result =
+                    asn1_write_value(spk, "encryptionParamSet", oid,
+                                     oid ? 1 : 0)) != ASN1_SUCCESS) {
+                       gnutls_assert();
+                       result = _gnutls_asn2err(result);
+                       goto cleanup;
+               }
        }
 
        result = _gnutls_x509_der_encode(spk, "", der, 0);