summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2018-11-13 02:48:05 +0300
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2018-11-16 03:36:27 +0300
commitde73ec9f11e58992cf3dc4c825f37e92e118c52a (patch)
tree8ded7393e98b4824d23a37c3aca8aac9aaa37803
parent057ed9e277cec22714111a7a16482c57f26bc8af (diff)
downloadgnutls-de73ec9f11e58992cf3dc4c825f37e92e118c52a.tar.gz
pkcs8: support GOST keys without encapsulation
Add support for yet another representation of GOST private keys: LE-formatted number encoded into pkcs-8-PrivateKeyInfo.privateKey without any additional encapsulation. Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-rw-r--r--lib/x509/privkey_pkcs8.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c
index 56be84bfe4..049d2fb7ed 100644
--- a/lib/x509/privkey_pkcs8.c
+++ b/lib/x509/privkey_pkcs8.c
@@ -1136,10 +1136,29 @@ _privkey_decode_gost_key(const gnutls_datum_t * raw_key,
gnutls_x509_privkey_t pkey)
{
int ret;
+ int ecc_size = gnutls_ecc_curve_get_size(pkey->params.curve);
- if (raw_key->data[0] == ASN1_TAG_INTEGER) {
+ /* Just to be sure here */
+ if (ecc_size <= 0) {
+ gnutls_assert();
+ ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
+ goto error;
+ }
+
+ /* Private key form described in R 50.1.112-2016.
+ * Private key can come up as masked value concatenated with several masks.
+ * each part is of ecc_size bytes. Key will be unmasked in pk_fixup */
+ if (raw_key->size % ecc_size == 0) {
+ ret = _gnutls_mpi_init_scan_le(&pkey->params.params[GOST_K],
+ raw_key->data, raw_key->size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
+ } else if (raw_key->data[0] == ASN1_TAG_INTEGER) {
ASN1_TYPE pkey_asn;
+ /* Very old format: INTEGER packed in OCTET STRING */
if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
"GNUTLS.GOSTPrivateKeyOld",
&pkey_asn)) != ASN1_SUCCESS) {
@@ -1169,6 +1188,7 @@ _privkey_decode_gost_key(const gnutls_datum_t * raw_key,
} else if (raw_key->data[0] == ASN1_TAG_OCTET_STRING) {
ASN1_TYPE pkey_asn;
+ /* format: OCTET STRING packed in OCTET STRING */
if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
"GNUTLS.GOSTPrivateKey",
&pkey_asn)) != ASN1_SUCCESS) {
@@ -1195,7 +1215,7 @@ _privkey_decode_gost_key(const gnutls_datum_t * raw_key,
goto error;
}
asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
- } else { /* Custom but also used format, no encap */
+ } else {
gnutls_assert();
ret = GNUTLS_E_PARSING_ERROR;
goto error;