From d7a0d1a128322de62cbee2157589ddcd36f20a03 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 21 Oct 2016 04:00:21 +0300 Subject: Add declarations to support GOST public keys Signed-off-by: Dmitry Eremin-Solenikov --- doc/Makefile.am | 1 + lib/algorithms.h | 4 ++++ lib/algorithms/publickey.c | 6 +++++- lib/algorithms/secparams.c | 4 ++-- lib/crypto-backend.h | 13 ++++++++++++- lib/includes/gnutls/gnutls.h.in | 27 ++++++++++++++++++++++++++- lib/pk.c | 1 + lib/x509/common.h | 2 ++ tests/cert-tests/data/gost-cert.pem | 2 +- tests/privkey-keygen.c | 6 ++++++ 10 files changed, 60 insertions(+), 6 deletions(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index e35e92ffd0..b38b1e84eb 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -552,6 +552,7 @@ ENUMS += enums/gnutls_ecc_curve_t ENUMS += enums/gnutls_ext_flags_t ENUMS += enums/gnutls_ext_parse_type_t ENUMS += enums/gnutls_fips_mode_t +ENUMS += enums/gnutls_gost_paramset_t ENUMS += enums/gnutls_group_t ENUMS += enums/gnutls_handshake_description_t ENUMS += enums/gnutls_init_flags_t diff --git a/lib/algorithms.h b/lib/algorithms.h index 468a0c8e96..fead2c2ed6 100644 --- a/lib/algorithms.h +++ b/lib/algorithms.h @@ -34,6 +34,10 @@ #define GNUTLS_FALLBACK_SCSV_MAJOR 0x56 #define GNUTLS_FALLBACK_SCSV_MINOR 0x00 +#define IS_GOSTEC(x) (((x)==GNUTLS_PK_GOST_01) || \ + ((x)==GNUTLS_PK_GOST_12_256)|| \ + ((x)==GNUTLS_PK_GOST_12_512)) + #define IS_EC(x) (((x)==GNUTLS_PK_ECDSA)||((x)==GNUTLS_PK_ECDH_X25519)||((x)==GNUTLS_PK_EDDSA_ED25519)) #define SIG_SEM_PRE_TLS12 (1<<1) diff --git a/lib/algorithms/publickey.c b/lib/algorithms/publickey.c index 677b969c96..0346520b7b 100644 --- a/lib/algorithms/publickey.c +++ b/lib/algorithms/publickey.c @@ -126,7 +126,11 @@ static const gnutls_pk_entry pk_algorithms[] = { .curve = GNUTLS_ECC_CURVE_INVALID }, /* some other broken certificates set RSA with SHA1 as an indicator of RSA */ { .name = "DSA", .oid = PK_DSA_OID, .id = GNUTLS_PK_DSA, .curve = GNUTLS_ECC_CURVE_INVALID }, - { .name = "GOST R 34.10-2001", .oid = PK_GOST_R3410_2001_OID, .id = GNUTLS_PK_UNKNOWN, + { .name = "GOST R 34.10-2012-512", .oid = PK_GOST_R3410_2012_512_OID, .id = GNUTLS_PK_GOST_12_512, + .curve = GNUTLS_ECC_CURVE_INVALID }, + { .name = "GOST R 34.10-2012-256", .oid = PK_GOST_R3410_2012_256_OID, .id = GNUTLS_PK_GOST_12_256, + .curve = GNUTLS_ECC_CURVE_INVALID }, + { .name = "GOST R 34.10-2001", .oid = PK_GOST_R3410_2001_OID, .id = GNUTLS_PK_GOST_01, .curve = GNUTLS_ECC_CURVE_INVALID }, { .name = "GOST R 34.10-94", .oid = PK_GOST_R3410_94_OID, .id = GNUTLS_PK_UNKNOWN, .curve = GNUTLS_ECC_CURVE_INVALID }, diff --git a/lib/algorithms/secparams.c b/lib/algorithms/secparams.c index ec4e5e3ee4..47dc2aa8d1 100644 --- a/lib/algorithms/secparams.c +++ b/lib/algorithms/secparams.c @@ -88,7 +88,7 @@ gnutls_sec_param_to_pk_bits(gnutls_pk_algorithm_t algo, if (p->sec_param == param) { if (algo == GNUTLS_PK_DSA) ret = p->dsa_bits; - else if (IS_EC(algo)) + else if (IS_EC(algo)||IS_GOSTEC(algo)) ret = p->ecc_bits; else ret = p->pk_bits; break; @@ -202,7 +202,7 @@ gnutls_pk_bits_to_sec_param(gnutls_pk_algorithm_t algo, unsigned int bits) if (bits == 0) return GNUTLS_SEC_PARAM_UNKNOWN; - if (IS_EC(algo)) { + if (IS_EC(algo)||IS_GOSTEC(algo)) { GNUTLS_SEC_PARAM_LOOP( if (p->ecc_bits > bits) { break; diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h index 2930f055f5..e410af03e3 100644 --- a/lib/crypto-backend.h +++ b/lib/crypto-backend.h @@ -193,7 +193,8 @@ typedef struct { unsigned int params_nr; /* the number of parameters */ unsigned int pkflags; /* gnutls_pk_flag_t */ unsigned int qbits; /* GNUTLS_PK_DH */ - gnutls_ecc_curve_t curve; /* GNUTLS_PK_EC, GNUTLS_PK_ED25519 */ + gnutls_ecc_curve_t curve; /* GNUTLS_PK_EC, GNUTLS_PK_ED25519, GNUTLS_PK_GOST* */ + gnutls_gost_paramset_t gost_params; /* GNUTLS_PK_GOST_* */ gnutls_datum_t raw_pub; /* used by x25519 */ gnutls_datum_t raw_priv; @@ -230,6 +231,7 @@ void gnutls_pk_params_init(gnutls_pk_params_st * p); #define DH_PUBLIC_PARAMS 4 #define RSA_PUBLIC_PARAMS 2 #define ECC_PUBLIC_PARAMS 2 +#define GOST_PUBLIC_PARAMS 2 #define MAX_PRIV_PARAMS_SIZE GNUTLS_MAX_PK_PARAMS /* ok for RSA and DSA */ @@ -239,6 +241,7 @@ void gnutls_pk_params_init(gnutls_pk_params_st * p); #define DH_PRIVATE_PARAMS 5 #define RSA_PRIVATE_PARAMS 8 #define ECC_PRIVATE_PARAMS 3 +#define GOST_PRIVATE_PARAMS 3 #if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0 #error INCREASE MAX_PRIV_PARAMS @@ -248,6 +251,10 @@ void gnutls_pk_params_init(gnutls_pk_params_st * p); #error INCREASE MAX_PRIV_PARAMS #endif +#if MAX_PRIV_PARAMS_SIZE - GOST_PRIVATE_PARAMS < 0 +#error INCREASE MAX_PRIV_PARAMS +#endif + #if MAX_PRIV_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0 #error INCREASE MAX_PRIV_PARAMS #endif @@ -292,6 +299,10 @@ void gnutls_pk_params_init(gnutls_pk_params_st * p); #define ECC_Y 1 #define ECC_K 2 +#define GOST_X 0 +#define GOST_Y 1 +#define GOST_K 2 + #define DSA_P 0 #define DSA_Q 1 #define DSA_G 2 diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index d80716dfdb..e95879a543 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -768,6 +768,9 @@ typedef enum gnutls_certificate_print_formats { * @GNUTLS_PK_ECDSA: Elliptic curve algorithm. These parameters are compatible with the ECDSA and ECDH algorithm. * @GNUTLS_PK_ECDH_X25519: Elliptic curve algorithm, restricted to ECDH as per rfc7748. * @GNUTLS_PK_EDDSA_ED25519: Edwards curve Digital signature algorithm. Used with SHA512 on signatures. + * @GNUTLS_PK_GOST_01: GOST R 34.10-2001 algorithm per rfc5832. + * @GNUTLS_PK_GOST_12_256: GOST R 34.10-2012 algorithm, 256-bit key per rfc7091. + * @GNUTLS_PK_GOST_12_512: GOST R 34.10-2012 algorithm, 512-bit key per rfc7091. * * Enumeration of different public-key algorithms. */ @@ -780,7 +783,10 @@ typedef enum { GNUTLS_PK_ECDH_X25519 = 5, GNUTLS_PK_RSA_PSS = 6, GNUTLS_PK_EDDSA_ED25519 = 7, - GNUTLS_PK_MAX = GNUTLS_PK_EDDSA_ED25519 + GNUTLS_PK_GOST_01 = 8, + GNUTLS_PK_GOST_12_256 = 9, + GNUTLS_PK_GOST_12_512 = 10, + GNUTLS_PK_MAX = GNUTLS_PK_GOST_12_512 } gnutls_pk_algorithm_t; @@ -1005,6 +1011,25 @@ typedef enum { GNUTLS_CB_TLS_UNIQUE } gnutls_channel_binding_t; +/** + * gnutls_gost_paramset_t: + * @GNUTLS_GOST_PARAMSET_UNKNOWN: Unknown/default parameter set + * @GNUTLS_GOST_PARAMSET_TC26_Z: Specified by TC26, see rfc7836 + * @GNUTLS_GOST_PARAMSET_CP_A: CryptoPro-A, see rfc4357 + * @GNUTLS_GOST_PARAMSET_CP_B: CryptoPro-B, see rfc4357 + * @GNUTLS_GOST_PARAMSET_CP_C: CryptoPro-C, see rfc4357 + * @GNUTLS_GOST_PARAMSET_CP_D: CryptoPro-D, see rfc4357 + * + * Enumeration of different GOST 28147 parameter sets. + */ +typedef enum { + GNUTLS_GOST_PARAMSET_UNKNOWN = 0, + GNUTLS_GOST_PARAMSET_TC26_Z, + GNUTLS_GOST_PARAMSET_CP_A, + GNUTLS_GOST_PARAMSET_CP_B, + GNUTLS_GOST_PARAMSET_CP_C, + GNUTLS_GOST_PARAMSET_CP_D +} gnutls_gost_paramset_t; /* If you want to change this, then also change the define in * gnutls_int.h, and recompile. diff --git a/lib/pk.c b/lib/pk.c index 3014396bc0..888cd64280 100644 --- a/lib/pk.c +++ b/lib/pk.c @@ -310,6 +310,7 @@ int _gnutls_pk_params_copy(gnutls_pk_params_st * dst, dst->pkflags = src->pkflags; dst->curve = src->curve; + dst->gost_params = src->gost_params; dst->qbits = src->qbits; dst->algo = src->algo; diff --git a/lib/x509/common.h b/lib/x509/common.h index 1a27666076..b7ce879e10 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -56,6 +56,8 @@ #define PK_DSA_OID "1.2.840.10040.4.1" #define PK_GOST_R3410_94_OID "1.2.643.2.2.20" #define PK_GOST_R3410_2001_OID "1.2.643.2.2.19" +#define PK_GOST_R3410_2012_256_OID "1.2.643.7.1.1.1.1" +#define PK_GOST_R3410_2012_512_OID "1.2.643.7.1.1.1.2" /* signature OIDs */ diff --git a/tests/cert-tests/data/gost-cert.pem b/tests/cert-tests/data/gost-cert.pem index edcdb9e8a6..8e6a5203e4 100644 --- a/tests/cert-tests/data/gost-cert.pem +++ b/tests/cert-tests/data/gost-cert.pem @@ -6,7 +6,7 @@ X.509 Certificate Information: Not Before: Fri Aug 17 06:47:36 UTC 2012 Not After: Sat Aug 17 06:47:36 UTC 2013 Subject: CN=SuperTerm0000001,OU=SuperPlat Terminals,O=SuperPlat,L=Moscow,ST=Russia,C=RU - Subject Public Key Algorithm: 1.2.643.2.2.19 + Subject Public Key Algorithm: GOST R 34.10-2001 Extensions: Basic Constraints (not critical): Certificate Authority (CA): FALSE diff --git a/tests/privkey-keygen.c b/tests/privkey-keygen.c index 885cf58e57..7762938dcf 100644 --- a/tests/privkey-keygen.c +++ b/tests/privkey-keygen.c @@ -119,6 +119,12 @@ void doit(void) algorithm == GNUTLS_PK_ECDH_X25519) continue; + /* Unsupported for now */ + if (algorithm == GNUTLS_PK_GOST_01 || + algorithm == GNUTLS_PK_GOST_12_256 || + algorithm == GNUTLS_PK_GOST_12_512) + continue; + ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) { fail("gnutls_x509_privkey_init: %d\n", -- cgit v1.2.1