[gcr: 2/5] gcr: add support for parsing GOST public keys/certificates



commit 9f0659c7e5f858a3298a7e6a9bff8c490f713b66
Author: Dmitry Baryshkov <dbaryshkov gmail com>
Date:   Wed Jan 29 20:23:28 2020 +0300

    gcr: add support for parsing GOST public keys/certificates
    
    Add support for parsing certificates/public keys according to RFC 4491
    and draft-deremin-4491-bis.
    
    Signed-off-by: Dmitry Baryshkov <dbaryshkov gmail com>

 egg/egg-oid.c                |  7 ++++++
 egg/pk.asn                   | 13 ++++++++++
 egg/pk.asn.h                 |  9 ++++++-
 gcr/gcr-oids.list            | 20 +++++++++++++++
 gcr/gcr-subject-public-key.c | 58 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 106 insertions(+), 1 deletion(-)
---
diff --git a/egg/egg-oid.c b/egg/egg-oid.c
index e604846..d0e7207 100644
--- a/egg/egg-oid.c
+++ b/egg/egg-oid.c
@@ -109,6 +109,13 @@ static OidInfo oid_info[] = {
        { 0, "1.2.840.10045.4.3.3", "sha384WithECDSA", N_("SHA384 with ECDSA"), 0 },
        { 0, "1.2.840.10045.4.3.4", "sha512WithECDSA", N_("SHA512 with ECDSA"), 0 },
 
+       { 0, "1.2.643.2.2.3", "gostR3411-94-with-gostR3410-2001", N_("GOST R 34.11-94 with GOST R 
34.10-2001"), 0 },
+       { 0, "1.2.643.2.2.19", "gostr3410-2001", N_("GOST R 34.10-2001"), 0 },
+       { 0, "1.2.643.7.1.1.1.1", "gost-3410-2012-256", N_("GOST R 34.10-2012 256-bit curve"), 0 },
+       { 0, "1.2.643.7.1.1.1.2", "gost-3410-2012-512", N_("GOST R 34.10-2012 512-bit curve"), 0 },
+       { 0, "1.2.643.7.1.1.3.2", "signwithdigest-gost-3410-2012-256", N_("GOST R 34.11-2012/256 with GOST R 
34.10-2012 256-bit curve"), 0 },
+       { 0, "1.2.643.7.1.1.3.3", "signwithdigest-gost-3410-2012-512", N_("GOST R 34.11-2012/512 with GOST R 
34.10-2012 512-bit curve"), 0 },
+
        /* Extended Key Usages */
        { 0, "1.3.6.1.5.5.7.3.1", NULL, N_("Server Authentication"), 0 },
        { 0, "1.3.6.1.5.5.7.3.2", NULL, N_("Client Authentication"), 0 },
diff --git a/egg/pk.asn b/egg/pk.asn
index de0a74a..56bd6ea 100644
--- a/egg/pk.asn
+++ b/egg/pk.asn
@@ -125,4 +125,17 @@ ECPrivateKey ::= SEQUENCE {
   publicKey  [1] BIT STRING OPTIONAL
 }
 
+-- The GOST public key parameters, defined by RFC 4491
+
+GostR3410-2001-PublicKeyParameters ::= SEQUENCE {
+  publicKeyParamSet OBJECT IDENTIFIER,
+  digestParamSet OBJECT IDENTIFIER,
+  encryptionParamSet OBJECT IDENTIFIER OPTIONAL
+}
+
+GostR3410-2012-PublicKeyParameters ::= SEQUENCE {
+  publicKeyParamSet OBJECT IDENTIFIER,
+  digestParamSet OBJECT IDENTIFIER OPTIONAL
+}
+
 END
diff --git a/egg/pk.asn.h b/egg/pk.asn.h
index e0f8125..95b9d50 100644
--- a/egg/pk.asn.h
+++ b/egg/pk.asn.h
@@ -70,7 +70,7 @@ const asn1_static_node pk_asn1_tab[] = {
   { "ECPoint", 1073741831, NULL },
   { "ECParameters", 1610612754, NULL },
   { "namedCurve", 12, NULL },
-  { "ECPrivateKey", 536870917, NULL },
+  { "ECPrivateKey", 1610612741, NULL },
   { "version", 1610874883, NULL },
   { "ecPrivkeyVer1", 1, "1"},
   { "privateKey", 1073741831, NULL },
@@ -78,5 +78,12 @@ const asn1_static_node pk_asn1_tab[] = {
   { NULL, 2056, "0"},
   { "publicKey", 536895494, NULL },
   { NULL, 2056, "1"},
+  { "GostR3410-2001-PublicKeyParameters", 1610612741, NULL },
+  { "publicKeyParamSet", 1073741836, NULL },
+  { "digestParamSet", 1073741836, NULL },
+  { "encryptionParamSet", 16396, NULL },
+  { "GostR3410-2012-PublicKeyParameters", 536870917, NULL },
+  { "publicKeyParamSet", 1073741836, NULL },
+  { "digestParamSet", 16396, NULL },
   { NULL, 0, NULL }
 };
diff --git a/gcr/gcr-oids.list b/gcr/gcr-oids.list
index cf94dba..d8c827e 100644
--- a/gcr/gcr-oids.list
+++ b/gcr/gcr-oids.list
@@ -46,3 +46,23 @@ EC_SECT409R1                 1.3.132.0.37
 EC_SECP521R1                   1.3.132.0.35
 EC_SECP571K1                   1.3.132.0.38
 EC_SECT571R1                   1.3.132.0.39
+
+GOSTR3410_2001                 1.2.643.2.2.19
+GOSTR3410_2012_256             1.2.643.7.1.1.1.1
+GOSTR3410_2012_512             1.2.643.7.1.1.1.2
+
+GOSTR3410_TEST                 1.2.643.2.2.35.0
+GOSTR3410_CRYPTOPRO_A          1.2.643.2.2.35.1
+GOSTR3410_CRYPTOPRO_B          1.2.643.2.2.35.2
+GOSTR3410_CRYPTOPRO_C          1.2.643.2.2.35.3
+GOSTR3410_CRYPTOPRO_XCHA       1.2.643.2.2.36.0
+GOSTR3410_CRYPTOPRO_XCHB       1.2.643.2.2.36.1
+
+GOSTR3410_GC256A               1.2.643.7.1.2.1.1.1
+GOSTR3410_GC256B               1.2.643.7.1.2.1.1.2
+GOSTR3410_GC256C               1.2.643.7.1.2.1.1.3
+GOSTR3410_GC256D               1.2.643.7.1.2.1.1.4
+GOSTR3410_512_TEST             1.2.643.7.1.2.1.2.0
+GOSTR3410_GC512A               1.2.643.7.1.2.1.2.1
+GOSTR3410_GC512B               1.2.643.7.1.2.1.2.2
+GOSTR3410_GC512C               1.2.643.7.1.2.1.2.3
diff --git a/gcr/gcr-subject-public-key.c b/gcr/gcr-subject-public-key.c
index 1621d95..bc07de4 100644
--- a/gcr/gcr-subject-public-key.c
+++ b/gcr/gcr-subject-public-key.c
@@ -1019,6 +1019,55 @@ calculate_ec_params_size (GNode *params)
        return size;
 }
 
+static guint
+gost_curve_size (GNode *params)
+{
+       GQuark oid;
+       guint size;
+
+       oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (params, "publicKeyParamSet", NULL));
+       if (oid == GCR_OID_GOSTR3410_TEST ||
+           oid == GCR_OID_GOSTR3410_CRYPTOPRO_A ||
+           oid == GCR_OID_GOSTR3410_CRYPTOPRO_B ||
+           oid == GCR_OID_GOSTR3410_CRYPTOPRO_C ||
+           oid == GCR_OID_GOSTR3410_CRYPTOPRO_XCHA ||
+           oid == GCR_OID_GOSTR3410_CRYPTOPRO_XCHB ||
+           oid == GCR_OID_GOSTR3410_GC256A ||
+           oid == GCR_OID_GOSTR3410_GC256B ||
+           oid == GCR_OID_GOSTR3410_GC256C ||
+           oid == GCR_OID_GOSTR3410_GC256D)
+               size = 256;
+       else if (oid == GCR_OID_GOSTR3410_512_TEST ||
+                oid == GCR_OID_GOSTR3410_GC512A ||
+                oid == GCR_OID_GOSTR3410_GC512B ||
+                oid == GCR_OID_GOSTR3410_GC512C)
+               size = 512;
+       else {
+               g_message ("unsupported curve: %s", g_quark_to_string (oid));
+               size = 0;
+       }
+       return size;
+
+}
+
+static guint
+calculate_gost_params_size (GNode *params, gboolean gost2012)
+{
+       GNode *asn;
+       guint size;
+
+       asn = egg_asn1x_get_any_as (params, pk_asn1_tab,
+                                   gost2012 ?
+                                   "GostR3410-2012-PublicKeyParameters" :
+                                   "GostR3410-2001-PublicKeyParameters");
+       g_return_val_if_fail (asn, 0);
+
+       size = gost_curve_size (asn);
+       egg_asn1x_destroy (asn);
+
+       return size;
+}
+
 static guint
 attributes_ec_params_size (GckAttributes *attrs)
 {
@@ -1075,6 +1124,15 @@ _gcr_subject_public_key_calculate_size (GNode *subject_public_key)
                params = egg_asn1x_node (subject_public_key, "algorithm", "parameters", NULL);
                key_size = calculate_ec_params_size (params);
 
+       } else if (oid == GCR_OID_GOSTR3410_2001) {
+               params = egg_asn1x_node (subject_public_key, "algorithm", "parameters", NULL);
+               key_size = calculate_gost_params_size (params, FALSE);
+
+       } else if (oid == GCR_OID_GOSTR3410_2012_256 ||
+                  oid == GCR_OID_GOSTR3410_2012_512) {
+               params = egg_asn1x_node (subject_public_key, "algorithm", "parameters", NULL);
+               key_size = calculate_gost_params_size (params, TRUE);
+
        } else {
                g_message ("unsupported key algorithm: %s", g_quark_to_string (oid));
        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]