2018-12-09 13:58:57

by Vitaly Chikunov

[permalink] [raw]
Subject: [RFC PATCH] X.509: Parse public key parameters from x509 for akcipher

Some public key algorithms (like ECDSA) keep in parameters field
important data such as digest and curve OIDs (possibly more for
different ECDSA variants). Thus, just setting a public key (as
for RSA) is not enough.

Introduce set_params() callback for akcipher which will be used to
pass BER encoded parameters array, with additional argument of
algorithm OID.

This is done with the intent of adding support for EC-RDSA (ISO/IEC
14888-3:2018, RFC 7091, and basically ECDSA variant) public keys (which
will be finally used in IMA subsystem). Thus, also oid_registry.h is
updated.

Rationale:

- For such keys just setting public key without parameters is
meaningless, so it would be possible to add parameters in
crypto_akcipher_set_pub_key (and .set_pub_key) calls. But, this will
needlessly change API for RSA akcipher. Also, additional callback
making it possible to pass parameters after
crypto_akcipher_set_priv_key (and .set_priv_key) in the future.

- Algorithm OID is passed to be validated in .set_params callback,
otherwise, it could have the wrong value.

- Particular algorithm OIDs are checked in x509_note_params, (because
this is called from AlgorithmIdentifier (ASN.1) parser, which is
called multiple times, as it's used multiple times in X.509
certificate), to distinguish a public key call from a signature call.

Signed-off-by: Vitaly Chikunov <[email protected]>
---
crypto/asymmetric_keys/public_key.c | 16 +++++++++++++++
crypto/asymmetric_keys/x509.asn1 | 2 +-
crypto/asymmetric_keys/x509_cert_parser.c | 27 +++++++++++++++++++++++++
crypto/testmgr.c | 5 +++++
crypto/testmgr.h | 3 +++
include/crypto/akcipher.h | 33 +++++++++++++++++++++++++++++++
include/crypto/public_key.h | 4 ++++
include/linux/oid_registry.h | 6 ++++++
8 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index f5d85b47fcc6..3bc090b8adef 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -45,6 +45,7 @@ void public_key_free(struct public_key *key)
{
if (key) {
kfree(key->key);
+ kfree(key->params);
kfree(key);
}
}
@@ -124,6 +125,11 @@ static int software_key_query(const struct kernel_pkey_params *params,
if (ret < 0)
goto error_free_tfm;

+ ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+ pkey->paramlen);
+ if (ret)
+ goto error_free_tfm;
+
len = crypto_akcipher_maxsize(tfm);
info->key_size = len * 8;
info->max_data_size = len;
@@ -182,6 +188,11 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
if (ret)
goto error_free_req;

+ ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+ pkey->paramlen);
+ if (ret)
+ goto error_free_req;
+
sg_init_one(&in_sg, in, params->in_len);
sg_init_one(&out_sg, out, params->out_len);
akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
@@ -263,6 +274,11 @@ int public_key_verify_signature(const struct public_key *pkey,
if (ret)
goto error_free_req;

+ ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+ pkey->paramlen);
+ if (ret)
+ goto error_free_req;
+
ret = -ENOMEM;
outlen = crypto_akcipher_maxsize(tfm);
output = kmalloc(outlen, GFP_KERNEL);
diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
index aae0cde414e2..5c9f4e4a5231 100644
--- a/crypto/asymmetric_keys/x509.asn1
+++ b/crypto/asymmetric_keys/x509.asn1
@@ -22,7 +22,7 @@ CertificateSerialNumber ::= INTEGER

AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER ({ x509_note_OID }),
- parameters ANY OPTIONAL
+ parameters ANY OPTIONAL ({ x509_note_params })
}

Name ::= SEQUENCE OF RelativeDistinguishedName
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 991f4d735a4e..16d8936d143b 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -26,6 +26,9 @@ struct x509_parse_context {
const void *cert_start; /* Start of cert content */
const void *key; /* Key data */
size_t key_size; /* Size of key data */
+ const void *params; /* Key parameters */
+ size_t params_size; /* Size of key parameters */
+ enum OID key_algo; /* Public key algorithm */
enum OID last_oid; /* Last OID encountered */
enum OID algo_oid; /* Algorithm OID */
unsigned char nr_mpi; /* Number of MPIs stored */
@@ -109,6 +112,13 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)

cert->pub->keylen = ctx->key_size;

+ cert->pub->params = kmemdup(ctx->params, ctx->params_size, GFP_KERNEL);
+ if (!cert->pub->params)
+ goto error_decode;
+
+ cert->pub->paramlen = ctx->params_size;
+ cert->pub->algo = ctx->key_algo;
+
/* Grab the signature bits */
ret = x509_get_sig_params(cert);
if (ret < 0)
@@ -401,6 +411,23 @@ int x509_note_subject(void *context, size_t hdrlen,
}

/*
+ * Extract parameters for particular keys
+ */
+int x509_note_params(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ if (ctx->last_oid != OID_gost2012PublicKey256 &&
+ ctx->last_oid != OID_gost2012PublicKey512)
+ return 0;
+ ctx->params = value;
+ ctx->params_size = vlen;
+ return 0;
+}
+
+/*
* Extract the data for the public key algorithm
*/
int x509_extract_key_data(void *context, size_t hdrlen,
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 0f684a414acb..a030526a6609 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -2257,6 +2257,11 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
if (err)
goto free_req;

+ err = crypto_akcipher_set_params(tfm, vecs->algo, vecs->params,
+ vecs->param_len);
+ if (err)
+ goto free_req;
+
err = -ENOMEM;
out_len_max = crypto_akcipher_maxsize(tfm);
outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index e7e56a8febbc..9855da080eaf 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -124,13 +124,16 @@ struct drbg_testvec {

struct akcipher_testvec {
const unsigned char *key;
+ const unsigned char *params;
const unsigned char *m;
const unsigned char *c;
unsigned int key_len;
+ unsigned int param_len;
unsigned int m_size;
unsigned int c_size;
bool public_key_vec;
bool siggen_sigver_test;
+ enum OID algo;
};

struct kpp_testvec {
diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index afac71119396..d6aba84ed2c4 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -13,6 +13,7 @@
#ifndef _CRYPTO_AKCIPHER_H
#define _CRYPTO_AKCIPHER_H
#include <linux/crypto.h>
+#include <linux/oid_registry.h>

/**
* struct akcipher_request - public key request
@@ -73,6 +74,9 @@ struct crypto_akcipher {
* @set_priv_key: Function invokes the algorithm specific set private key
* function, which knows how to decode and interpret
* the BER encoded private key
+ * @set_params: Function invokes the algorithm specific set parameters
+ * function, which knows how to decode and interpret
+ * the BER encoded public key
* @max_size: Function returns dest buffer size required for a given key.
* @init: Initialize the cryptographic transformation object.
* This function is used to initialize the cryptographic
@@ -98,6 +102,8 @@ struct akcipher_alg {
unsigned int keylen);
int (*set_priv_key)(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen);
+ int (*set_params)(struct crypto_akcipher *tfm, enum OID algo,
+ const void *params, unsigned int paramlen);
unsigned int (*max_size)(struct crypto_akcipher *tfm);
int (*init)(struct crypto_akcipher *tfm);
void (*exit)(struct crypto_akcipher *tfm);
@@ -452,4 +458,31 @@ static inline int crypto_akcipher_set_priv_key(struct crypto_akcipher *tfm,

return alg->set_priv_key(tfm, key, keylen);
}
+
+/**
+ * crypto_akcipher_set_params() - Invoke set parameters operation
+ *
+ * Function invokes the algorithm specific set parameters function, which
+ * knows how to decode and interpret the encoded parameters
+ *
+ * @tfm: tfm handle
+ * @algo: OID of the key algorithm
+ * @params: BER encoded key parameters
+ * @paramlen: length of the parameters
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_akcipher_set_params(struct crypto_akcipher *tfm,
+ enum OID algo,
+ const void *params,
+ unsigned int paramlen)
+{
+ struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+ if (alg->set_params)
+ return alg->set_params(tfm, algo, params, paramlen);
+ if (!params || !paramlen)
+ return 0;
+ return -ENOTSUPP;
+}
#endif
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index be626eac9113..712fe1214b5f 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -15,6 +15,7 @@
#define _LINUX_PUBLIC_KEY_H

#include <linux/keyctl.h>
+#include <linux/oid_registry.h>

/*
* Cryptographic data for the public-key subtype of the asymmetric key type.
@@ -25,6 +26,9 @@
struct public_key {
void *key;
u32 keylen;
+ enum OID algo;
+ void *params;
+ u32 paramlen;
bool key_is_private;
const char *id_type;
const char *pkey_algo;
diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
index d2fa9ca42e9a..e2e323fd4826 100644
--- a/include/linux/oid_registry.h
+++ b/include/linux/oid_registry.h
@@ -93,6 +93,12 @@ enum OID {
OID_authorityKeyIdentifier, /* 2.5.29.35 */
OID_extKeyUsage, /* 2.5.29.37 */

+ /* EC-RDSA */
+ OID_gost2012PublicKey256, /* 1.2.643.7.1.1.1.1 */
+ OID_gost2012PublicKey512, /* 1.2.643.7.1.1.1.2 */
+ OID_gost2012Signature256, /* 1.2.643.7.1.1.3.2 */
+ OID_gost2012Signature512, /* 1.2.643.7.1.1.3.3 */
+
OID__NR
};

--
2.11.0



2018-12-10 23:23:42

by Vitaly Chikunov

[permalink] [raw]
Subject: Re: [RFC PATCH] X.509: Parse public key parameters from x509 for akcipher

On Sun, Dec 09, 2018 at 04:55:48PM +0300, Vitaly Chikunov wrote:
> Some public key algorithms (like ECDSA) keep in parameters field
> important data such as digest and curve OIDs (possibly more for
> different ECDSA variants). Thus, just setting a public key (as
> for RSA) is not enough.
>
> Introduce set_params() callback for akcipher which will be used to
> pass BER encoded parameters array, with additional argument of
> algorithm OID.
>
> This is done with the intent of adding support for EC-RDSA (ISO/IEC
> 14888-3:2018, RFC 7091, and basically ECDSA variant) public keys (which
> will be finally used in IMA subsystem). Thus, also oid_registry.h is
> updated.
>
> Rationale:
>
> - For such keys just setting public key without parameters is
> meaningless, so it would be possible to add parameters in
> crypto_akcipher_set_pub_key (and .set_pub_key) calls. But, this will
> needlessly change API for RSA akcipher. Also, additional callback
> making it possible to pass parameters after
> crypto_akcipher_set_priv_key (and .set_priv_key) in the future.
>
> - Algorithm OID is passed to be validated in .set_params callback,
> otherwise, it could have the wrong value.
>
> - Particular algorithm OIDs are checked in x509_note_params, (because
> this is called from AlgorithmIdentifier (ASN.1) parser, which is
> called multiple times, as it's used multiple times in X.509
> certificate), to distinguish a public key call from a signature call.
>
> Signed-off-by: Vitaly Chikunov <[email protected]>
> ---
> crypto/asymmetric_keys/public_key.c | 16 +++++++++++++++
> crypto/asymmetric_keys/x509.asn1 | 2 +-
> crypto/asymmetric_keys/x509_cert_parser.c | 27 +++++++++++++++++++++++++
> crypto/testmgr.c | 5 +++++
> crypto/testmgr.h | 3 +++
> include/crypto/akcipher.h | 33 +++++++++++++++++++++++++++++++
> include/crypto/public_key.h | 4 ++++
> include/linux/oid_registry.h | 6 ++++++
> 8 files changed, 95 insertions(+), 1 deletion(-)
>
> diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
> index f5d85b47fcc6..3bc090b8adef 100644
> --- a/crypto/asymmetric_keys/public_key.c
> +++ b/crypto/asymmetric_keys/public_key.c
> @@ -45,6 +45,7 @@ void public_key_free(struct public_key *key)
> {
> if (key) {
> kfree(key->key);
> + kfree(key->params);
> kfree(key);
> }
> }
> @@ -124,6 +125,11 @@ static int software_key_query(const struct kernel_pkey_params *params,
> if (ret < 0)
> goto error_free_tfm;
>
> + ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
> + pkey->paramlen);
> + if (ret)
> + goto error_free_tfm;
> +
> len = crypto_akcipher_maxsize(tfm);
> info->key_size = len * 8;
> info->max_data_size = len;
> @@ -182,6 +188,11 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
> if (ret)
> goto error_free_req;
>
> + ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
> + pkey->paramlen);
> + if (ret)
> + goto error_free_req;
> +
> sg_init_one(&in_sg, in, params->in_len);
> sg_init_one(&out_sg, out, params->out_len);
> akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
> @@ -263,6 +274,11 @@ int public_key_verify_signature(const struct public_key *pkey,
> if (ret)
> goto error_free_req;
>
> + ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
> + pkey->paramlen);
> + if (ret)
> + goto error_free_req;
> +
> ret = -ENOMEM;
> outlen = crypto_akcipher_maxsize(tfm);
> output = kmalloc(outlen, GFP_KERNEL);
> diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
> index aae0cde414e2..5c9f4e4a5231 100644
> --- a/crypto/asymmetric_keys/x509.asn1
> +++ b/crypto/asymmetric_keys/x509.asn1
> @@ -22,7 +22,7 @@ CertificateSerialNumber ::= INTEGER
>
> AlgorithmIdentifier ::= SEQUENCE {
> algorithm OBJECT IDENTIFIER ({ x509_note_OID }),
> - parameters ANY OPTIONAL
> + parameters ANY OPTIONAL ({ x509_note_params })
> }
>
> Name ::= SEQUENCE OF RelativeDistinguishedName
> diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
> index 991f4d735a4e..16d8936d143b 100644
> --- a/crypto/asymmetric_keys/x509_cert_parser.c
> +++ b/crypto/asymmetric_keys/x509_cert_parser.c
> @@ -26,6 +26,9 @@ struct x509_parse_context {
> const void *cert_start; /* Start of cert content */
> const void *key; /* Key data */
> size_t key_size; /* Size of key data */
> + const void *params; /* Key parameters */
> + size_t params_size; /* Size of key parameters */
> + enum OID key_algo; /* Public key algorithm */
> enum OID last_oid; /* Last OID encountered */
> enum OID algo_oid; /* Algorithm OID */
> unsigned char nr_mpi; /* Number of MPIs stored */
> @@ -109,6 +112,13 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
>
> cert->pub->keylen = ctx->key_size;
>
> + cert->pub->params = kmemdup(ctx->params, ctx->params_size, GFP_KERNEL);
> + if (!cert->pub->params)
> + goto error_decode;
> +
> + cert->pub->paramlen = ctx->params_size;
> + cert->pub->algo = ctx->key_algo;
> +
> /* Grab the signature bits */
> ret = x509_get_sig_params(cert);
> if (ret < 0)
> @@ -401,6 +411,23 @@ int x509_note_subject(void *context, size_t hdrlen,
> }
>
> /*
> + * Extract parameters for particular keys
> + */
> +int x509_note_params(void *context, size_t hdrlen,
> + unsigned char tag,
> + const void *value, size_t vlen)
> +{
> + struct x509_parse_context *ctx = context;
> +
> + if (ctx->last_oid != OID_gost2012PublicKey256 &&
> + ctx->last_oid != OID_gost2012PublicKey512)
> + return 0;
> + ctx->params = value;
> + ctx->params_size = vlen;
> + return 0;
> +}
> +
> +/*
> * Extract the data for the public key algorithm
> */
> int x509_extract_key_data(void *context, size_t hdrlen,

Missed one hunk, which set ctx->key_algo:

@@ -436,16 +449,21 @@ int x509_extract_key_data(void *context, size_t hdrlen,
{
struct x509_parse_context *ctx = context;

- if (ctx->last_oid != OID_rsaEncryption)
+ ctx->key_algo = ctx->last_oid;
+ if (ctx->last_oid == OID_rsaEncryption)
+ ctx->cert->pub->pkey_algo = "rsa";
+ else if (ctx->last_oid == OID_gost2012PublicKey256 ||
+ ctx->last_oid == OID_gost2012PublicKey512)
+ ctx->cert->pub->pkey_algo = "ecrdsa";
+ else
return -ENOPKG;

- ctx->cert->pub->pkey_algo = "rsa";
-
/* Discard the BIT STRING metadata */
if (vlen < 1 || *(const u8 *)value != 0)
return -EBADMSG;
ctx->key = value + 1;
ctx->key_size = vlen - 1;
+
return 0;
}

> diff --git a/crypto/testmgr.c b/crypto/testmgr.c
> index 0f684a414acb..a030526a6609 100644
> --- a/crypto/testmgr.c
> +++ b/crypto/testmgr.c
> @@ -2257,6 +2257,11 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
> if (err)
> goto free_req;
>
> + err = crypto_akcipher_set_params(tfm, vecs->algo, vecs->params,
> + vecs->param_len);
> + if (err)
> + goto free_req;
> +
> err = -ENOMEM;
> out_len_max = crypto_akcipher_maxsize(tfm);
> outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
> diff --git a/crypto/testmgr.h b/crypto/testmgr.h
> index e7e56a8febbc..9855da080eaf 100644
> --- a/crypto/testmgr.h
> +++ b/crypto/testmgr.h
> @@ -124,13 +124,16 @@ struct drbg_testvec {
>
> struct akcipher_testvec {
> const unsigned char *key;
> + const unsigned char *params;
> const unsigned char *m;
> const unsigned char *c;
> unsigned int key_len;
> + unsigned int param_len;
> unsigned int m_size;
> unsigned int c_size;
> bool public_key_vec;
> bool siggen_sigver_test;
> + enum OID algo;
> };
>
> struct kpp_testvec {
> diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
> index afac71119396..d6aba84ed2c4 100644
> --- a/include/crypto/akcipher.h
> +++ b/include/crypto/akcipher.h
> @@ -13,6 +13,7 @@
> #ifndef _CRYPTO_AKCIPHER_H
> #define _CRYPTO_AKCIPHER_H
> #include <linux/crypto.h>
> +#include <linux/oid_registry.h>
>
> /**
> * struct akcipher_request - public key request
> @@ -73,6 +74,9 @@ struct crypto_akcipher {
> * @set_priv_key: Function invokes the algorithm specific set private key
> * function, which knows how to decode and interpret
> * the BER encoded private key
> + * @set_params: Function invokes the algorithm specific set parameters
> + * function, which knows how to decode and interpret
> + * the BER encoded public key
> * @max_size: Function returns dest buffer size required for a given key.
> * @init: Initialize the cryptographic transformation object.
> * This function is used to initialize the cryptographic
> @@ -98,6 +102,8 @@ struct akcipher_alg {
> unsigned int keylen);
> int (*set_priv_key)(struct crypto_akcipher *tfm, const void *key,
> unsigned int keylen);
> + int (*set_params)(struct crypto_akcipher *tfm, enum OID algo,
> + const void *params, unsigned int paramlen);
> unsigned int (*max_size)(struct crypto_akcipher *tfm);
> int (*init)(struct crypto_akcipher *tfm);
> void (*exit)(struct crypto_akcipher *tfm);
> @@ -452,4 +458,31 @@ static inline int crypto_akcipher_set_priv_key(struct crypto_akcipher *tfm,
>
> return alg->set_priv_key(tfm, key, keylen);
> }
> +
> +/**
> + * crypto_akcipher_set_params() - Invoke set parameters operation
> + *
> + * Function invokes the algorithm specific set parameters function, which
> + * knows how to decode and interpret the encoded parameters
> + *
> + * @tfm: tfm handle
> + * @algo: OID of the key algorithm
> + * @params: BER encoded key parameters
> + * @paramlen: length of the parameters
> + *
> + * Return: zero on success; error code in case of error
> + */
> +static inline int crypto_akcipher_set_params(struct crypto_akcipher *tfm,
> + enum OID algo,
> + const void *params,
> + unsigned int paramlen)
> +{
> + struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
> +
> + if (alg->set_params)
> + return alg->set_params(tfm, algo, params, paramlen);
> + if (!params || !paramlen)
> + return 0;
> + return -ENOTSUPP;
> +}
> #endif
> diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
> index be626eac9113..712fe1214b5f 100644
> --- a/include/crypto/public_key.h
> +++ b/include/crypto/public_key.h
> @@ -15,6 +15,7 @@
> #define _LINUX_PUBLIC_KEY_H
>
> #include <linux/keyctl.h>
> +#include <linux/oid_registry.h>
>
> /*
> * Cryptographic data for the public-key subtype of the asymmetric key type.
> @@ -25,6 +26,9 @@
> struct public_key {
> void *key;
> u32 keylen;
> + enum OID algo;
> + void *params;
> + u32 paramlen;
> bool key_is_private;
> const char *id_type;
> const char *pkey_algo;
> diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
> index d2fa9ca42e9a..e2e323fd4826 100644
> --- a/include/linux/oid_registry.h
> +++ b/include/linux/oid_registry.h
> @@ -93,6 +93,12 @@ enum OID {
> OID_authorityKeyIdentifier, /* 2.5.29.35 */
> OID_extKeyUsage, /* 2.5.29.37 */
>
> + /* EC-RDSA */
> + OID_gost2012PublicKey256, /* 1.2.643.7.1.1.1.1 */
> + OID_gost2012PublicKey512, /* 1.2.643.7.1.1.1.2 */
> + OID_gost2012Signature256, /* 1.2.643.7.1.1.3.2 */
> + OID_gost2012Signature512, /* 1.2.643.7.1.1.3.3 */
> +
> OID__NR
> };
>
> --
> 2.11.0

2018-12-13 10:15:23

by Herbert Xu

[permalink] [raw]
Subject: Re: [RFC PATCH] X.509: Parse public key parameters from x509 for akcipher

Vitaly Chikunov <[email protected]> wrote:
> Some public key algorithms (like ECDSA) keep in parameters field
> important data such as digest and curve OIDs (possibly more for
> different ECDSA variants). Thus, just setting a public key (as
> for RSA) is not enough.
>
> Introduce set_params() callback for akcipher which will be used to
> pass BER encoded parameters array, with additional argument of
> algorithm OID.
>
> This is done with the intent of adding support for EC-RDSA (ISO/IEC
> 14888-3:2018, RFC 7091, and basically ECDSA variant) public keys (which
> will be finally used in IMA subsystem). Thus, also oid_registry.h is
> updated.
>
> Rationale:
>
> - For such keys just setting public key without parameters is
> meaningless, so it would be possible to add parameters in
> crypto_akcipher_set_pub_key (and .set_pub_key) calls. But, this will
> needlessly change API for RSA akcipher. Also, additional callback
> making it possible to pass parameters after
> crypto_akcipher_set_priv_key (and .set_priv_key) in the future.
>
> - Algorithm OID is passed to be validated in .set_params callback,
> otherwise, it could have the wrong value.
>
> - Particular algorithm OIDs are checked in x509_note_params, (because
> this is called from AlgorithmIdentifier (ASN.1) parser, which is
> called multiple times, as it's used multiple times in X.509
> certificate), to distinguish a public key call from a signature call.
>
> Signed-off-by: Vitaly Chikunov <[email protected]>

Please post this with a patch that actually uses the set_params
callback.

Thanks,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt