summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2017-09-18 12:54:12 +0300
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2018-06-23 12:20:15 +0300
commit6b8051aeeb74efc28eadb344783ab0e79963198a (patch)
treea6f093275446c510b6cec61aa6d367b04445f8ae
parent9083bcd3babe035f04d7114f3f520e50aa6e9f79 (diff)
downloadgnutls-6b8051aeeb74efc28eadb344783ab0e79963198a.tar.gz
Support importing/exporting X.509 GOST public keys
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-rw-r--r--doc/Makefile.am6
-rw-r--r--doc/manpages/Makefile.am3
-rw-r--r--lib/includes/gnutls/abstract.h15
-rw-r--r--lib/includes/gnutls/x509.h5
-rw-r--r--lib/libgnutls.map3
-rw-r--r--lib/pubkey.c169
-rw-r--r--lib/x509/key_decode.c150
-rw-r--r--lib/x509/key_encode.c171
-rw-r--r--lib/x509/output.c63
-rw-r--r--lib/x509/x509.c53
-rw-r--r--lib/x509/x509_int.h4
-rw-r--r--symbols.last3
-rw-r--r--tests/cert-tests/Makefile.am9
-rw-r--r--tests/cert-tests/data/gost-cert-nogost.pem45
-rw-r--r--tests/cert-tests/data/gost-cert.pem16
-rw-r--r--tests/cert-tests/data/gost94-cert.pem33
-rwxr-xr-xtests/cert-tests/pem-decoding27
17 files changed, 772 insertions, 3 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
index f56ee101a5..68a2702227 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1700,6 +1700,8 @@ FUNCS += functions/gnutls_pubkey_export_ecc_raw2
FUNCS += functions/gnutls_pubkey_export_ecc_raw2.short
FUNCS += functions/gnutls_pubkey_export_ecc_x962
FUNCS += functions/gnutls_pubkey_export_ecc_x962.short
+FUNCS += functions/gnutls_pubkey_export_gost_raw2
+FUNCS += functions/gnutls_pubkey_export_gost_raw2.short
FUNCS += functions/gnutls_pubkey_export_rsa_raw
FUNCS += functions/gnutls_pubkey_export_rsa_raw.short
FUNCS += functions/gnutls_pubkey_export_rsa_raw2
@@ -1724,6 +1726,8 @@ FUNCS += functions/gnutls_pubkey_import_ecc_raw
FUNCS += functions/gnutls_pubkey_import_ecc_raw.short
FUNCS += functions/gnutls_pubkey_import_ecc_x962
FUNCS += functions/gnutls_pubkey_import_ecc_x962.short
+FUNCS += functions/gnutls_pubkey_import_gost_raw
+FUNCS += functions/gnutls_pubkey_import_gost_raw.short
FUNCS += functions/gnutls_pubkey_import_openpgp
FUNCS += functions/gnutls_pubkey_import_openpgp.short
FUNCS += functions/gnutls_pubkey_import_openpgp_raw
@@ -2386,6 +2390,8 @@ FUNCS += functions/gnutls_x509_crt_get_pk_dsa_raw
FUNCS += functions/gnutls_x509_crt_get_pk_dsa_raw.short
FUNCS += functions/gnutls_x509_crt_get_pk_ecc_raw
FUNCS += functions/gnutls_x509_crt_get_pk_ecc_raw.short
+FUNCS += functions/gnutls_x509_crt_get_pk_gost_raw
+FUNCS += functions/gnutls_x509_crt_get_pk_gost_raw.short
FUNCS += functions/gnutls_x509_crt_get_pk_oid
FUNCS += functions/gnutls_x509_crt_get_pk_oid.short
FUNCS += functions/gnutls_x509_crt_get_pk_rsa_raw
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index 5679518a29..c10719f4f6 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -645,6 +645,7 @@ APIMANS += gnutls_pubkey_export_dsa_raw2.3
APIMANS += gnutls_pubkey_export_ecc_raw.3
APIMANS += gnutls_pubkey_export_ecc_raw2.3
APIMANS += gnutls_pubkey_export_ecc_x962.3
+APIMANS += gnutls_pubkey_export_gost_raw2.3
APIMANS += gnutls_pubkey_export_rsa_raw.3
APIMANS += gnutls_pubkey_export_rsa_raw2.3
APIMANS += gnutls_pubkey_get_key_id.3
@@ -657,6 +658,7 @@ APIMANS += gnutls_pubkey_import.3
APIMANS += gnutls_pubkey_import_dsa_raw.3
APIMANS += gnutls_pubkey_import_ecc_raw.3
APIMANS += gnutls_pubkey_import_ecc_x962.3
+APIMANS += gnutls_pubkey_import_gost_raw.3
APIMANS += gnutls_pubkey_import_openpgp.3
APIMANS += gnutls_pubkey_import_openpgp_raw.3
APIMANS += gnutls_pubkey_import_pkcs11.3
@@ -988,6 +990,7 @@ APIMANS += gnutls_x509_crt_get_name_constraints.3
APIMANS += gnutls_x509_crt_get_pk_algorithm.3
APIMANS += gnutls_x509_crt_get_pk_dsa_raw.3
APIMANS += gnutls_x509_crt_get_pk_ecc_raw.3
+APIMANS += gnutls_x509_crt_get_pk_gost_raw.3
APIMANS += gnutls_x509_crt_get_pk_oid.3
APIMANS += gnutls_x509_crt_get_pk_rsa_raw.3
APIMANS += gnutls_x509_crt_get_policy.3
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index d3cd91b93c..bd947b7833 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -216,6 +216,13 @@ int gnutls_pubkey_export_ecc_raw2(gnutls_pubkey_t key,
gnutls_datum_t * x, gnutls_datum_t * y,
unsigned flags);
+int gnutls_pubkey_export_gost_raw2(gnutls_pubkey_t key,
+ gnutls_ecc_curve_t * curve,
+ gnutls_digest_algorithm_t * digest,
+ gnutls_gost_paramset_t * paramset,
+ gnutls_datum_t * x, gnutls_datum_t * y,
+ unsigned int flags);
+
#define gnutls_pubkey_get_pk_ecc_raw gnutls_pubkey_export_ecc_raw
int gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key,
gnutls_ecc_curve_t * curve,
@@ -277,6 +284,14 @@ gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key,
const gnutls_datum_t * y);
int
+gnutls_pubkey_import_gost_raw(gnutls_pubkey_t key,
+ gnutls_ecc_curve_t curve,
+ gnutls_digest_algorithm_t digest,
+ gnutls_gost_paramset_t paramset,
+ const gnutls_datum_t * x,
+ const gnutls_datum_t * y);
+
+int
gnutls_pubkey_encrypt_data(gnutls_pubkey_t key,
unsigned int flags,
const gnutls_datum_t * plaintext,
diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index fef901a101..ff6fa52822 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -455,6 +455,11 @@ int gnutls_x509_crt_get_pk_ecc_raw(gnutls_x509_crt_t crt,
gnutls_ecc_curve_t * curve,
gnutls_datum_t * x,
gnutls_datum_t * y);
+int gnutls_x509_crt_get_pk_gost_raw(gnutls_x509_crt_t crt,
+ gnutls_ecc_curve_t * curve,
+ gnutls_digest_algorithm_t * digest,
+ gnutls_gost_paramset_t *paramset,
+ gnutls_datum_t * x, gnutls_datum_t * y);
int gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,
unsigned int seq,
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 6d81cf8b9c..b1b6630ed9 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1226,6 +1226,9 @@ GNUTLS_3_6_3
gnutls_oid_to_gost_paramset;
gnutls_decode_gost_rs_value;
gnutls_encode_gost_rs_value;
+ gnutls_pubkey_export_gost_raw2;
+ gnutls_pubkey_import_gost_raw;
+ gnutls_x509_crt_get_pk_gost_raw;
} GNUTLS_3_6_2;
GNUTLS_FIPS140_3_4 {
diff --git a/lib/pubkey.c b/lib/pubkey.c
index d6d374b786..7c9b6da5f8 100644
--- a/lib/pubkey.c
+++ b/lib/pubkey.c
@@ -61,6 +61,9 @@ unsigned pubkey_to_bits(const gnutls_pk_params_st * params)
return _gnutls_mpi_get_nbits(params->params[DSA_P]);
case GNUTLS_PK_ECDSA:
case GNUTLS_PK_EDDSA_ED25519:
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
return gnutls_ecc_curve_get_size(params->curve) * 8;
default:
return 0;
@@ -313,6 +316,16 @@ gnutls_pubkey_get_preferred_hash_algorithm(gnutls_pubkey_t key,
ret = 0;
break;
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
+ if (hash)
+ *hash = _gnutls_gost_digest(key->params.algo);
+ if (mand)
+ *mand = 1;
+
+ ret = 0;
+ break;
case GNUTLS_PK_RSA_PSS:
if (mand && key->params.spki.rsa_pss_dig)
*mand = 1;
@@ -959,6 +972,82 @@ int gnutls_pubkey_export_ecc_x962(gnutls_pubkey_t key,
}
/**
+ * gnutls_pubkey_export_gost_raw2:
+ * @key: Holds the public key
+ * @curve: will hold the curve (may be %NULL)
+ * @digest: will hold the curve (may be %NULL)
+ * @paramset: will hold the parameters id (may be %NULL)
+ * @x: will hold x (may be %NULL)
+ * @y: will hold y (may be %NULL)
+ * @flags: flags from %gnutls_abstract_export_flags_t
+ *
+ * This function will export the GOST public key's parameters found in
+ * the given key. The new parameters will be allocated using
+ * gnutls_malloc() and will be stored in the appropriate datum.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
+ *
+ * Since: 3.6.3
+ **/
+int
+gnutls_pubkey_export_gost_raw2(gnutls_pubkey_t key,
+ gnutls_ecc_curve_t * curve,
+ gnutls_digest_algorithm_t * digest,
+ gnutls_gost_paramset_t * paramset,
+ gnutls_datum_t * x, gnutls_datum_t * y,
+ unsigned int flags)
+{
+ int ret;
+
+ mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
+
+ if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
+ dprint = _gnutls_mpi_dprint;
+
+ if (key == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ if (key->params.algo != GNUTLS_PK_GOST_01 &&
+ key->params.algo != GNUTLS_PK_GOST_12_256 &&
+ key->params.algo != GNUTLS_PK_GOST_12_512) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ if (curve)
+ *curve = key->params.curve;
+
+ if (digest)
+ *digest = _gnutls_gost_digest(key->params.algo);
+
+ if (paramset)
+ *paramset = key->params.gost_params;
+
+ /* X */
+ if (x) {
+ ret = dprint(key->params.params[GOST_X], x);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
+
+ /* Y */
+ if (y) {
+ ret = dprint(key->params.params[GOST_Y], y);
+ if (ret < 0) {
+ gnutls_assert();
+ _gnutls_free_datum(x);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/**
* gnutls_pubkey_import:
* @key: The public key.
* @data: The DER or PEM encoded certificate.
@@ -1435,6 +1524,80 @@ gnutls_pubkey_import_ecc_x962(gnutls_pubkey_t key,
}
/**
+ * gnutls_pubkey_import_gost_raw:
+ * @key: The structure to store the parsed key
+ * @curve: holds the curve
+ * @digest: holds the digest
+ * @paramset: holds the parameters id
+ * @x: holds the x
+ * @y: holds the y
+ *
+ * This function will convert the given GOST public key's parameters to a
+ * #gnutls_pubkey_t. The output will be stored in @key.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ *
+ * Since: 3.6.3
+ **/
+int
+gnutls_pubkey_import_gost_raw(gnutls_pubkey_t key,
+ gnutls_ecc_curve_t curve,
+ gnutls_digest_algorithm_t digest,
+ gnutls_gost_paramset_t paramset,
+ const gnutls_datum_t * x,
+ const gnutls_datum_t * y)
+{
+ int ret;
+ gnutls_pk_algorithm_t pk_algo;
+
+ if (key == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pk_algo = _gnutls_digest_gost(digest);
+ if (pk_algo == GNUTLS_PK_UNKNOWN)
+ return GNUTLS_E_ILLEGAL_PARAMETER;
+
+ if (paramset < 0) {
+ if (pk_algo == GNUTLS_PK_GOST_01)
+ paramset = GNUTLS_GOST_PARAMSET_CP_A;
+ else
+ paramset = GNUTLS_GOST_PARAMSET_TC26_Z;
+ }
+
+ gnutls_pk_params_release(&key->params);
+ gnutls_pk_params_init(&key->params);
+
+ key->params.curve = curve;
+ key->params.gost_params = paramset;
+
+ if (_gnutls_mpi_init_scan_nz
+ (&key->params.params[GOST_X], x->data, x->size)) {
+ gnutls_assert();
+ ret = GNUTLS_E_MPI_SCAN_FAILED;
+ goto cleanup;
+ }
+ key->params.params_nr++;
+
+ if (_gnutls_mpi_init_scan_nz
+ (&key->params.params[GOST_Y], y->data, y->size)) {
+ gnutls_assert();
+ ret = GNUTLS_E_MPI_SCAN_FAILED;
+ goto cleanup;
+ }
+ key->params.params_nr++;
+ key->params.algo = pk_algo;
+
+ return 0;
+
+ cleanup:
+ gnutls_pk_params_release(&key->params);
+ return ret;
+}
+
+/**
* gnutls_pubkey_import_dsa_raw:
* @key: The structure to store the parsed key
* @p: holds the p
@@ -1993,6 +2156,9 @@ pubkey_verify_hashed_data(const gnutls_sign_entry_st *se,
break;
case GNUTLS_PK_ECDSA:
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
case GNUTLS_PK_DSA:
if (dsa_verify_hashed_data
(se->pk, me, hash, signature, params, sign_params) != 0) {
@@ -2057,6 +2223,9 @@ pubkey_verify_data(const gnutls_sign_entry_st *se,
case GNUTLS_PK_EC:
case GNUTLS_PK_DSA:
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
if (dsa_verify_data
(se->pk, me, data, signature, params, sign_params) != 0) {
gnutls_assert();
diff --git a/lib/x509/key_decode.c b/lib/x509/key_decode.c
index a1bf82688a..b1df8aaab3 100644
--- a/lib/x509/key_decode.c
+++ b/lib/x509/key_decode.c
@@ -39,6 +39,8 @@ static int _gnutls_x509_read_ecc_pubkey(uint8_t * der, int dersize,
gnutls_pk_params_st * params);
static int _gnutls_x509_read_eddsa_pubkey(uint8_t * der, int dersize,
gnutls_pk_params_st * params);
+static int _gnutls_x509_read_gost_pubkey(uint8_t * der, int dersize,
+ gnutls_pk_params_st * params);
static int
_gnutls_x509_read_dsa_params(uint8_t * der, int dersize,
@@ -117,6 +119,47 @@ int _gnutls_x509_read_eddsa_pubkey(uint8_t * der, int dersize,
return _gnutls_set_datum(&params->raw_pub, der, dersize);
}
+/* Pubkey is a concatenation of X (in little endian) and Y (also LE)
+ * encoded into OCTET STRING. */
+static int
+_gnutls_x509_read_gost_pubkey(uint8_t * der, int dersize,
+ gnutls_pk_params_st * params)
+{
+ int ret;
+ int len;
+ bigint_t *x = &params->params[GOST_X];
+ bigint_t *y = &params->params[GOST_Y];
+
+ /* Quick and dirty parsing of OCTET STRING of 0x40 or 0x80 bytes */
+ if (dersize < 1 || der[0] != ASN1_TAG_OCTET_STRING) {
+ return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
+ }
+
+ der++;
+ dersize--;
+
+ ret = asn1_get_length_der(der, dersize, &len);
+ if (ret <= 0 || ret % 2 != 0 || dersize != len + ret) {
+ return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
+ }
+
+ der += len;
+ dersize -= len;
+
+ /* read data */
+ ret = _gnutls_mpi_init_scan_le(x, der, dersize / 2);
+ if (ret < 0)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ ret = _gnutls_mpi_init_scan_le(y, der + dersize / 2, dersize / 2);
+ if (ret < 0) {
+ _gnutls_mpi_release(y);
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
+ return 0;
+}
+
/* reads p,q and g
* from the certificate (subjectPublicKey BIT STRING).
* params[0-2]. It does NOT set params_nr.
@@ -387,6 +430,97 @@ _gnutls_x509_read_rsa_pss_params(uint8_t * der, int dersize,
return result;
}
+/* reads the curve from the certificate.
+ * It does NOT set params_nr.
+ */
+int
+_gnutls_x509_read_gost_params(uint8_t * der, int dersize,
+ gnutls_pk_params_st * params)
+{
+ int ret;
+ ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+ char oid[MAX_OID_SIZE];
+ int oid_size;
+ gnutls_ecc_curve_t curve;
+ int param;
+
+ if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.GOSTParameters",
+ &spk)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(ret);
+ }
+
+ ret = _asn1_strict_der_decode(&spk, der, dersize, NULL);
+
+ if (ret != ASN1_SUCCESS) {
+ gnutls_assert();
+ ret = _gnutls_asn2err(ret);
+ goto cleanup;
+ }
+
+ /* read the curve */
+ oid_size = sizeof(oid);
+ ret = asn1_read_value(spk, "publicKeyParamSet", oid, &oid_size);
+ if (ret != ASN1_SUCCESS) {
+ gnutls_assert();
+ ret = _gnutls_asn2err(ret);
+ goto cleanup;
+ }
+
+ curve = gnutls_oid_to_ecc_curve(oid);
+ if (curve == GNUTLS_ECC_CURVE_INVALID) {
+ _gnutls_debug_log("Curve %s is not supported\n", oid);
+ gnutls_assert();
+ ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
+ goto cleanup;
+ }
+
+ /* Read the digest */
+ oid_size = sizeof(oid);
+ ret = asn1_read_value(spk, "digestParamSet", oid, &oid_size);
+ if (ret != ASN1_SUCCESS) {
+ gnutls_assert();
+ ret = _gnutls_asn2err(ret);
+ goto cleanup;
+ }
+ /* For now ignore the OID: we use pk OID instead */
+
+ if (!strcmp(oid, HASH_OID_GOST_R_3411_94_CRYPTOPRO_PARAMS))
+ param = GNUTLS_GOST_PARAMSET_CP_A;
+ else
+ param = GNUTLS_GOST_PARAMSET_TC26_Z;
+
+ oid_size = sizeof(oid);
+ ret = asn1_read_value(spk, "encryptionParamSet", oid, &oid_size);
+ if (ret != ASN1_SUCCESS &&
+ ret != ASN1_ELEMENT_NOT_FOUND) {
+ gnutls_assert();
+ ret = _gnutls_asn2err(ret);
+ goto cleanup;
+ }
+
+ if (ret != ASN1_ELEMENT_NOT_FOUND)
+ param = gnutls_oid_to_gost_paramset(oid);
+
+ if (param < 0) {
+ gnutls_assert();
+ ret = param;
+ goto cleanup;
+ }
+
+ params->curve = curve;
+ params->gost_params = param;
+ ret = 0;
+
+ cleanup:
+
+ asn1_delete_structure(&spk);
+
+ return ret;
+
+}
+
/* This function must be called after _gnutls_x509_read_params()
*/
int _gnutls_x509_read_pubkey(gnutls_pk_algorithm_t algo, uint8_t * der,
@@ -423,6 +557,15 @@ int _gnutls_x509_read_pubkey(gnutls_pk_algorithm_t algo, uint8_t * der,
case GNUTLS_PK_EDDSA_ED25519:
ret = _gnutls_x509_read_eddsa_pubkey(der, dersize, params);
break;
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
+ ret = _gnutls_x509_read_gost_pubkey(der, dersize, params);
+ if (ret >= 0) {
+ params->algo = algo;
+ params->params_nr = GOST_PUBLIC_PARAMS;
+ }
+ break;
default:
ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
break;
@@ -446,6 +589,10 @@ int _gnutls_x509_read_pubkey_params(gnutls_pk_algorithm_t algo,
return _gnutls_x509_read_dsa_params(der, dersize, params);
case GNUTLS_PK_EC:
return _gnutls_x509_read_ecc_params(der, dersize, &params->curve);
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
+ return _gnutls_x509_read_gost_params(der, dersize, params);
default:
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
}
@@ -479,6 +626,9 @@ int _gnutls_x509_check_pubkey_params(gnutls_pk_params_st * params)
case GNUTLS_PK_DSA:
case GNUTLS_PK_ECDSA:
case GNUTLS_PK_EDDSA_ED25519:
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
return 0;
default:
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
diff --git a/lib/x509/key_encode.c b/lib/x509/key_encode.c
index 0f12975d18..7663300826 100644
--- a/lib/x509/key_encode.c
+++ b/lib/x509/key_encode.c
@@ -39,6 +39,10 @@ static int _gnutls_x509_write_dsa_params(gnutls_pk_params_st * params,
gnutls_datum_t * der);
static int _gnutls_x509_write_dsa_pubkey(gnutls_pk_params_st * params,
gnutls_datum_t * der);
+static int _gnutls_x509_write_gost_params(gnutls_pk_params_st * params,
+ gnutls_datum_t * der);
+static int _gnutls_x509_write_gost_pubkey(gnutls_pk_params_st * params,
+ gnutls_datum_t * der);
/*
* some x509 certificate functions that relate to MPI parameter
@@ -157,6 +161,78 @@ _gnutls_x509_write_eddsa_pubkey(gnutls_pk_params_st * params,
}
int
+_gnutls_x509_write_gost_pubkey(gnutls_pk_params_st * params,
+ gnutls_datum_t * der)
+{
+ bigint_t x, y;
+ int numlen;
+ int byte_size, ret;
+ size_t size;
+ int pos;
+
+ der->data = NULL;
+ der->size = 0;
+
+ if (params->params_nr < GOST_PUBLIC_PARAMS)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ x = params->params[GOST_X];
+ y = params->params[GOST_Y];
+ numlen = gnutls_ecc_curve_get_size(params->curve);
+
+ if (numlen == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ der->size = 1 + ASN1_MAX_LENGTH_SIZE + 2 * numlen;
+
+ der->data = gnutls_malloc(der->size);
+ if (der->data == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ memset(der->data, 0, der->size);
+
+ der->data[0] = ASN1_TAG_OCTET_STRING;
+ asn1_length_der(2 * numlen, &der->data[1], &pos);
+ pos += 1;
+
+ /* pad and store x */
+ byte_size = (_gnutls_mpi_get_nbits(x) + 7) / 8;
+ if (numlen < byte_size) {
+ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ goto cleanup;
+ }
+
+ size = numlen;
+ ret = _gnutls_mpi_print_le(x, &der->data[pos], &size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ /* pad and store y */
+ byte_size = (_gnutls_mpi_get_nbits(y) + 7) / 8;
+ if (numlen < byte_size) {
+ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ goto cleanup;
+ }
+
+ size = numlen;
+ ret = _gnutls_mpi_print_le(y, &der->data[pos + numlen], &size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ der->size = pos + 2 * numlen;
+
+ return 0;
+
+ cleanup:
+ _gnutls_free_datum(der);
+ return ret;
+}
+
+int
_gnutls_x509_write_pubkey_params(gnutls_pk_params_st * params,
gnutls_datum_t * der)
{
@@ -180,6 +256,10 @@ _gnutls_x509_write_pubkey_params(gnutls_pk_params_st * params,
der->size = 0;
return 0;
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
+ return _gnutls_x509_write_gost_params(params, der);
default:
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
}
@@ -199,6 +279,10 @@ _gnutls_x509_write_pubkey(gnutls_pk_params_st * params,
return _gnutls_x509_write_ecc_pubkey(params, der);
case GNUTLS_PK_EDDSA_ED25519:
return _gnutls_x509_write_eddsa_pubkey(params, der);
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
+ return _gnutls_x509_write_gost_pubkey(params, der);
default:
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
}
@@ -439,6 +523,93 @@ _gnutls_x509_write_rsa_pss_params(gnutls_x509_spki_st *params,
return result;
}
+static int
+_gnutls_x509_write_gost_params(gnutls_pk_params_st * params,
+ gnutls_datum_t * der)
+{
+ int result;
+ ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+ const char *oid;
+
+ der->data = NULL;
+ der->size = 0;
+
+ oid = gnutls_ecc_curve_get_oid(params->curve);
+ if (oid == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+
+ if ((result = asn1_create_element
+ (_gnutls_get_gnutls_asn(), "GNUTLS.GOSTParameters", &spk))
+ != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ if ((result =
+ asn1_write_value(spk, "publicKeyParamSet", oid,
+ 1)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ result = _gnutls_asn2err(result);
+ goto cleanup;
+ }
+
+ 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)
+ 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;
+ }
+
+ if ((result =
+ asn1_write_value(spk, "digestParamSet", oid,
+ 1)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ result = _gnutls_asn2err(result);
+ goto cleanup;
+ }
+
+ oid = gnutls_gost_paramset_get_oid(params->gost_params);
+ if (oid == NULL) {
+ gnutls_assert();
+ result = GNUTLS_E_INVALID_REQUEST;
+ goto cleanup;
+ }
+
+ if (params->algo == GNUTLS_PK_GOST_01) {
+ if (params->gost_params == GNUTLS_GOST_PARAMSET_CP_A)
+ oid = NULL;
+ } else {
+ if (params->gost_params == GNUTLS_GOST_PARAMSET_TC26_Z)
+ oid = NULL;
+ }
+
+ 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);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ asn1_delete_structure(&spk);
+ return result;
+}
+
/*
* This function writes the public parameters for DSS keys.
* Needs 1 parameter (y).
diff --git a/lib/x509/output.c b/lib/x509/output.c
index b9e183d37f..4fc37d6253 100644
--- a/lib/x509/output.c
+++ b/lib/x509/output.c
@@ -1404,6 +1404,60 @@ print_pubkey(gnutls_buffer_st * str, const char *key_name,
}
break;
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
+ {
+ gnutls_datum_t x, y;
+ gnutls_ecc_curve_t curve;
+ gnutls_digest_algorithm_t digest;
+ gnutls_gost_paramset_t param;
+
+ err =
+ gnutls_pubkey_export_gost_raw2(pubkey, &curve,
+ &digest,
+ &param,
+ &x, &y, 0);
+ if (err < 0)
+ addf(str, "error: get_pk_gost_raw: %s\n",
+ gnutls_strerror(err));
+ else {
+ addf(str, _("\t\tCurve:\t%s\n"),
+ gnutls_ecc_curve_get_name(curve));
+ addf(str, _("\t\tDigest:\t%s\n"),
+ gnutls_digest_get_name(digest));
+ addf(str, _("\t\tParamSet: %s\n"),
+ gnutls_gost_paramset_get_name(param));
+ if (format ==
+ GNUTLS_CRT_PRINT_FULL_NUMBERS) {
+ adds(str, _("\t\tX: "));
+ _gnutls_buffer_hexprint(str,
+ x.data,
+ x.size);
+ adds(str, "\n");
+ adds(str, _("\t\tY: "));
+ _gnutls_buffer_hexprint(str,
+ y.data,
+ y.size);
+ adds(str, "\n");
+ } else {
+ adds(str, _("\t\tX:\n"));
+ _gnutls_buffer_hexdump(str, x.data,
+ x.size,
+ "\t\t\t");
+ adds(str, _("\t\tY:\n"));
+ _gnutls_buffer_hexdump(str, y.data,
+ y.size,
+ "\t\t\t");
+ }
+
+ gnutls_free(x.data);
+ gnutls_free(y.data);
+
+ }
+ }
+ break;
+
default:
break;
}
@@ -1770,6 +1824,15 @@ static void print_keyid(gnutls_buffer_st * str, gnutls_x509_crt_t cert)
name = gnutls_ecc_curve_get_name(curve);
bits = 0;
+ } else if (IS_GOSTEC(err)) {
+ gnutls_ecc_curve_t curve;
+
+ err = gnutls_x509_crt_get_pk_gost_raw(cert, &curve, NULL, NULL, NULL, NULL);
+ if (err < 0)
+ return;
+
+ name = gnutls_ecc_curve_get_name(curve);
+ bits = 0;
} else {
name = gnutls_pk_get_name(err);
}
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 74040a4e9d..721a1a0a93 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -3523,6 +3523,59 @@ gnutls_x509_crt_get_pk_ecc_raw(gnutls_x509_crt_t crt,
}
/**
+ * gnutls_x509_crt_get_pk_gost_raw:
+ * @crt: Holds the certificate
+ * @curve: will hold the curve
+ * @paramset: will hold paramset
+ * @x: will hold x
+ * @y: will hold y
+ *
+ * This function will export the GOST public key's parameters found in
+ * the given certificate. The new parameters will be allocated using
+ * gnutls_malloc() and will be stored in the appropriate datum.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
+ *
+ * Since: 3.6.3
+ **/
+int
+gnutls_x509_crt_get_pk_gost_raw(gnutls_x509_crt_t crt,
+ gnutls_ecc_curve_t * curve,
+ gnutls_digest_algorithm_t * digest,
+ gnutls_gost_paramset_t *paramset,
+ gnutls_datum_t * x, gnutls_datum_t * y)
+{
+ int ret;
+ gnutls_pubkey_t pubkey;
+
+ if (crt == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ ret = gnutls_pubkey_init(&pubkey);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ ret = gnutls_pubkey_export_gost_raw2(pubkey, curve, digest,
+ paramset, x, y, 0);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ cleanup:
+ gnutls_pubkey_deinit(pubkey);
+ return ret;
+}
+
+/**
* gnutls_x509_crt_get_pk_dsa_raw:
* @crt: Holds the certificate
* @p: will hold the p
diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h
index 8f8733b358..a38ed8a3fc 100644
--- a/lib/x509/x509_int.h
+++ b/lib/x509/x509_int.h
@@ -262,6 +262,10 @@ int
_gnutls_x509_read_ecc_params(uint8_t * der, int dersize,
unsigned int *curve);
+int
+_gnutls_x509_read_gost_params(uint8_t * der, int dersize,
+ gnutls_pk_params_st * params);
+
int _gnutls_asn1_encode_privkey(ASN1_TYPE * c2,
gnutls_pk_params_st * params);
diff --git a/symbols.last b/symbols.last
index 9995f36d08..ac98a2a5fc 100644
--- a/symbols.last
+++ b/symbols.last
@@ -623,6 +623,7 @@ gnutls_pubkey_export_dsa_raw@GNUTLS_3_4
gnutls_pubkey_export_ecc_raw2@GNUTLS_3_6_0
gnutls_pubkey_export_ecc_raw@GNUTLS_3_4
gnutls_pubkey_export_ecc_x962@GNUTLS_3_4
+gnutls_pubkey_export_gost_raw2@GNUTLS_3_6_3
gnutls_pubkey_export_rsa_raw2@GNUTLS_3_6_0
gnutls_pubkey_export_rsa_raw@GNUTLS_3_4
gnutls_pubkey_get_key_id@GNUTLS_3_4
@@ -635,6 +636,7 @@ gnutls_pubkey_import@GNUTLS_3_4
gnutls_pubkey_import_dsa_raw@GNUTLS_3_4
gnutls_pubkey_import_ecc_raw@GNUTLS_3_4
gnutls_pubkey_import_ecc_x962@GNUTLS_3_4
+gnutls_pubkey_import_gost_raw@GNUTLS_3_6_3
gnutls_pubkey_import_openpgp@GNUTLS_3_4
gnutls_pubkey_import_openpgp_raw@GNUTLS_3_4
gnutls_pubkey_import_pkcs11@GNUTLS_3_4
@@ -980,6 +982,7 @@ gnutls_x509_crt_get_name_constraints@GNUTLS_3_4
gnutls_x509_crt_get_pk_algorithm@GNUTLS_3_4
gnutls_x509_crt_get_pk_dsa_raw@GNUTLS_3_4
gnutls_x509_crt_get_pk_ecc_raw@GNUTLS_3_4
+gnutls_x509_crt_get_pk_gost_raw@GNUTLS_3_6_3
gnutls_x509_crt_get_pk_oid@GNUTLS_3_4
gnutls_x509_crt_get_pk_rsa_raw@GNUTLS_3_4
gnutls_x509_crt_get_policy@GNUTLS_3_4
diff --git a/tests/cert-tests/Makefile.am b/tests/cert-tests/Makefile.am
index 150681e325..96b6d087cd 100644
--- a/tests/cert-tests/Makefile.am
+++ b/tests/cert-tests/Makefile.am
@@ -43,7 +43,8 @@ EXTRA_DIST = data/ca-no-pathlen.pem data/no-ca-or-pathlen.pem data/aki-cert.pem
data/template-krb5name.pem data/template-krb5name-full.pem data/template-test-ecc.key \
data/template-rsa-sha3-256.pem data/template-rsa-sha3-512.pem data/template-rsa-sha3-224.pem \
data/template-rsa-sha3-384.pem data/long-oids.pem \
- data/name-constraints-ip2.pem data/chain-md5.pem data/gost-cert.pem \
+ data/name-constraints-ip2.pem data/chain-md5.pem \
+ data/gost-cert.pem data/gost-cert-nogost.pem data/gost94-cert.pem \
templates/template-tlsfeature.tmpl data/userid.pem data/cert-with-crl.p12 \
data/template-tlsfeature.pem data/template-tlsfeature.csr \
templates/template-tlsfeature-crq.tmpl templates/arb-extensions.tmpl data/arb-extensions.pem \
@@ -141,5 +142,11 @@ if WINDOWS
TESTS_ENVIRONMENT += WINDOWS=1
endif
+if ENABLE_GOST
+TESTS_ENVIRONMENT += ENABLE_GOST=1
+else
+TESTS_ENVIRONMENT += ENABLE_GOST=0
+endif
+
distclean-local:
rm -rf tmp-* *.tmp
diff --git a/tests/cert-tests/data/gost-cert-nogost.pem b/tests/cert-tests/data/gost-cert-nogost.pem
new file mode 100644
index 0000000000..bf280349fd
--- /dev/null
+++ b/tests/cert-tests/data/gost-cert-nogost.pem
@@ -0,0 +1,45 @@
+X.509 Certificate Information:
+ Version: 3
+ Serial Number (hex): 011f
+ Issuer: CN=SuperPlat CA 01,OU=SuperPlat CA,O=SuperPlat,L=Moscow,ST=Russia,C=RU
+ Validity:
+ 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: GOST R 34.10-2001
+ Extensions:
+ Basic Constraints (not critical):
+ Certificate Authority (CA): FALSE
+ Unknown extension 2.16.840.1.113730.1.13 (not critical):
+ ASCII: ..OpenSSL Generated Certificate
+ Hexdump: 161d4f70656e53534c2047656e657261746564204365727469666963617465
+ Subject Key Identifier (not critical):
+ 43fe227895724f4e3a74f264e4fd0b800c082e03
+ Authority Key Identifier (not critical):
+ 9875a3b785c1641b23344d9bfbae0c2a256b44eb
+ Signature Algorithm: GOSTR341001
+ Signature:
+ 8f:37:24:fd:be:f0:37:d9:f3:1a:5c:31:5e:33:ef:35
+ 61:93:07:03:3d:4d:e8:2c:1b:39:a2:6c:d4:2f:85:35
+ b2:43:1d:ed:b5:15:45:c7:10:38:41:28:68:29:62:20
+ e6:92:8a:64:34:87:b8:b9:9f:ab:c8:04:6d:26:55:99
+Other Information:
+ Fingerprint:
+ sha1:621f34c4fdd7e93f9b8f18224ba0bcd1c63a4771
+ sha256:ac6ecf4e7a876edf3e61f538d6061353c2015bfbdf60370492f7404d7f09e13a
+
+-----BEGIN CERTIFICATE-----
+MIICXjCCAgugAwIBAgICAR8wCgYGKoUDAgIDBQAwdDELMAkGA1UEBhMCUlUxDzAN
+BgNVBAgMBlJ1c3NpYTEPMA0GA1UEBwwGTW9zY293MRIwEAYDVQQKDAlTdXBlclBs
+YXQxFTATBgNVBAsMDFN1cGVyUGxhdCBDQTEYMBYGA1UEAwwPU3VwZXJQbGF0IENB
+IDAxMB4XDTEyMDgxNzA2NDczNloXDTEzMDgxNzA2NDczNlowfDELMAkGA1UEBhMC
+UlUxDzANBgNVBAgMBlJ1c3NpYTEPMA0GA1UEBwwGTW9zY293MRIwEAYDVQQKDAlT
+dXBlclBsYXQxHDAaBgNVBAsME1N1cGVyUGxhdCBUZXJtaW5hbHMxGTAXBgNVBAMM
+EFN1cGVyVGVybTAwMDAwMDEwYzAcBgYqhQMCAhMwEgYHKoUDAgIjAQYHKoUDAgIe
+AQNDAARA69rbaWL2GSV1NVaWMSrWRX8d/frrwbVjJerPQKjyNeDYZxgSjTTp3dck
+6fQLx2OjQsu6n+vdyBPQex/iwbJBV6N7MHkwCQYDVR0TBAIwADAsBglghkgBhvhC
+AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFEP+
+IniVck9OOnTyZOT9C4AMCC4DMB8GA1UdIwQYMBaAFJh1o7eFwWQbIzRNm/uuDCol
+a0TrMAoGBiqFAwICAwUAA0EAjzck/b7wN9nzGlwxXjPvNWGTBwM9TegsGzmibNQv
+hTWyQx3ttRVFxxA4QShoKWIg5pKKZDSHuLmfq8gEbSZVmQ==
+-----END CERTIFICATE-----
diff --git a/tests/cert-tests/data/gost-cert.pem b/tests/cert-tests/data/gost-cert.pem
index bf280349fd..1501f83c4c 100644
--- a/tests/cert-tests/data/gost-cert.pem
+++ b/tests/cert-tests/data/gost-cert.pem
@@ -7,6 +7,17 @@ X.509 Certificate Information:
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: GOST R 34.10-2001
+ Algorithm Security Level: High (256 bits)
+ Curve: CryptoPro-A
+ Digest: GOSTR341194
+ ParamSet: CryptoPro-A
+ X:
+ 00:e0:35:f2:a8:40:cf:ea:25:63:b5:c1:eb:fa:fd:1d
+ 7f:45:d6:2a:31:96:56:35:75:25:19:f6:62:69:db:da
+ eb
+ Y:
+ 57:41:b2:c1:e2:1f:7b:d0:13:c8:dd:eb:9f:ba:cb:42
+ a3:63:c7:0b:f4:e9:24:d7:dd:e9:34:8d:12:18:67:d8
Extensions:
Basic Constraints (not critical):
Certificate Authority (CA): FALSE
@@ -27,6 +38,11 @@ Other Information:
Fingerprint:
sha1:621f34c4fdd7e93f9b8f18224ba0bcd1c63a4771
sha256:ac6ecf4e7a876edf3e61f538d6061353c2015bfbdf60370492f7404d7f09e13a
+ Public Key ID:
+ sha1:43757042dae9e9f5fa92cc2d2cbf4950f28a7bd0
+ sha256:cee4a59e7803bafb101af8e39e5355d7895e3b85e7616fe624d48f2c51e8bdbf
+ Public Key PIN:
+ pin-sha256:zuSlnngDuvsQGvjjnlNV14leO4XnYW/mJNSPLFHovb8=
-----BEGIN CERTIFICATE-----
MIICXjCCAgugAwIBAgICAR8wCgYGKoUDAgIDBQAwdDELMAkGA1UEBhMCUlUxDzAN
diff --git a/tests/cert-tests/data/gost94-cert.pem b/tests/cert-tests/data/gost94-cert.pem
new file mode 100644
index 0000000000..f4d63fb9d1
--- /dev/null
+++ b/tests/cert-tests/data/gost94-cert.pem
@@ -0,0 +1,33 @@
+X.509 Certificate Information:
+ Version: 1
+ Serial Number (hex): 230ee360469524cec70be494182e7eeb
+ Issuer: EMAIL=GostR3410-94@example.com,C=RU,O=CryptoPro,CN=GostR3410-94 example
+ Validity:
+ Not Before: Tue Aug 16 12:32:50 UTC 2005
+ Not After: Sun Aug 16 12:32:50 UTC 2015
+ Subject: EMAIL=GostR3410-94@example.com,C=RU,O=CryptoPro,CN=GostR3410-94 example
+ Subject Public Key Algorithm: 1.2.643.2.2.20
+ Signature Algorithm: 1.2.643.2.2.4
+ Signature:
+ 11:c7:08:7e:12:dc:02:f1:02:23:29:47:76:8f:47:2a
+ 81:83:50:e3:07:cc:f2:e4:31:23:89:42:c8:73:e1:de
+ 22:f7:85:f3:55:bd:94:ec:46:91:9c:67:ac:58:d7:05
+ 2a:a7:8c:b7:85:2a:01:75:85:f7:d7:38:03:fb:cd:43
+Other Information:
+ Fingerprint:
+ sha1:d43782a1f943a966f4ea1ac96bd048fe68d4d951
+ sha256:19260c765a2c820be3612dc0431c045d37570f8e4de58ba218f10a8eeb0d42d7
+
+-----BEGIN CERTIFICATE-----
+MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM
+FEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlwdG9Qcm8xCzAJBgNV
+BAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAtOTRAZXhhbXBsZS5jb20w
+HhcNMDUwODE2MTIzMjUwWhcNMTUwODE2MTIzMjUwWjBpMR0wGwYDVQQDDBRHb3N0
+UjM0MTAtOTQgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYDVQQGEwJS
+VTEnMCUGCSqGSIb3DQEJARYYR29zdFIzNDEwLTk0QGV4YW1wbGUuY29tMIGlMBwG
+BiqFAwICFDASBgcqhQMCAiACBgcqhQMCAh4BA4GEAASBgLuEZuF5nls02CyAfxOo
+GWZxV/6MVCUhR28wCyd3RpjG+0dVvrey85NsObVCNyaE4g0QiiQOHwxCTSs7ESuo
+v2Y5MlyUi8Go/htjEvYJJYfMdRv05YmKCYJo01x3pg+2kBATjeM+fJyR1qwNCCw+
+eMG1wra3Gqgqi0WBkzIydvp7MAgGBiqFAwICBANBABHHCH4S3ALxAiMpR3aPRyqB
+g1DjB8zy5DEjiULIc+HeIveF81W9lOxGkZxnrFjXBSqnjLeFKgF1hffXOAP7zUM=
+-----END CERTIFICATE-----
diff --git a/tests/cert-tests/pem-decoding b/tests/cert-tests/pem-decoding
index a31f412b48..0222ae72af 100755
--- a/tests/cert-tests/pem-decoding
+++ b/tests/cert-tests/pem-decoding
@@ -124,7 +124,13 @@ fi
#check whether the cert with GOST parameters is decoded as expected
-${VALGRIND} "${CERTTOOL}" --certificate-info --infile "${srcdir}/data/gost-cert.pem" >${TMPFILE}
+if test "${ENABLE_GOST}" = "1"; then
+ GOSTCERT="${srcdir}/data/gost-cert.pem"
+else
+ GOSTCERT="${srcdir}/data/gost-cert-nogost.pem"
+fi
+
+${VALGRIND} "${CERTTOOL}" --certificate-info --infile "${GOSTCERT}" >${TMPFILE}
rc=$?
if test "${rc}" != "0"; then
@@ -132,7 +138,7 @@ if test "${rc}" != "0"; then
exit ${rc}
fi
-${DIFF} -I 'Algorithm Security Level' ${TMPFILE} "${srcdir}/data/gost-cert.pem" || ${DIFF} -I 'Algorithm Security Level' --strip-trailing-cr "${TMPFILE}" "${srcdir}/data/gost-cert.pem"
+${DIFF} -u ${TMPFILE} "${GOSTCERT}" || ${DIFF} -u --strip-trailing-cr "${TMPFILE}" "${GOSTCERT}"
rc=$?
if test "${rc}" != "0"; then
@@ -140,6 +146,23 @@ if test "${rc}" != "0"; then
exit ${rc}
fi
+#check whether the cert with GOST 31.10/11-94 parameters is decoded as expected
+${VALGRIND} "${CERTTOOL}" --certificate-info --infile "${srcdir}/data/gost94-cert.pem" >${TMPFILE}
+rc=$?
+
+if test "${rc}" != "0"; then
+ echo "GOST94 cert decoding failed 1"
+ exit ${rc}
+fi
+
+${DIFF} -I 'Algorithm Security Level' ${TMPFILE} "${srcdir}/data/gost94-cert.pem" || ${DIFF} -I 'Algorithm Security Level' --strip-trailing-cr "${TMPFILE}" "${srcdir}/data/gost94-cert.pem"
+rc=$?
+
+if test "${rc}" != "0"; then
+ echo "GOST94 cert decoding failed 2"
+ exit ${rc}
+fi
+
${VALGRIND} "${CERTTOOL}" --certificate-info --infile "${srcdir}/data/multi-value-dn.pem" >${TMPFILE}
rc=$?