|
@@ -153,30 +153,29 @@ EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);
|
|
|
*/
|
|
|
int x509_get_sig_params(struct x509_certificate *cert)
|
|
|
{
|
|
|
+ struct public_key_signature *sig = cert->sig;
|
|
|
struct crypto_shash *tfm;
|
|
|
struct shash_desc *desc;
|
|
|
- size_t digest_size, desc_size;
|
|
|
- void *digest;
|
|
|
+ size_t desc_size;
|
|
|
int ret;
|
|
|
|
|
|
pr_devel("==>%s()\n", __func__);
|
|
|
|
|
|
if (cert->unsupported_crypto)
|
|
|
return -ENOPKG;
|
|
|
- if (cert->sig.s)
|
|
|
+ if (sig->s)
|
|
|
return 0;
|
|
|
|
|
|
- cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size,
|
|
|
- GFP_KERNEL);
|
|
|
- if (!cert->sig.s)
|
|
|
+ sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);
|
|
|
+ if (!sig->s)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- cert->sig.s_size = cert->raw_sig_size;
|
|
|
+ sig->s_size = cert->raw_sig_size;
|
|
|
|
|
|
/* Allocate the hashing algorithm we're going to need and find out how
|
|
|
* big the hash operational data will be.
|
|
|
*/
|
|
|
- tfm = crypto_alloc_shash(cert->sig.hash_algo, 0, 0);
|
|
|
+ tfm = crypto_alloc_shash(sig->hash_algo, 0, 0);
|
|
|
if (IS_ERR(tfm)) {
|
|
|
if (PTR_ERR(tfm) == -ENOENT) {
|
|
|
cert->unsupported_crypto = true;
|
|
@@ -186,29 +185,28 @@ int x509_get_sig_params(struct x509_certificate *cert)
|
|
|
}
|
|
|
|
|
|
desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
|
|
|
- digest_size = crypto_shash_digestsize(tfm);
|
|
|
+ sig->digest_size = crypto_shash_digestsize(tfm);
|
|
|
|
|
|
- /* We allocate the hash operational data storage on the end of the
|
|
|
- * digest storage space.
|
|
|
- */
|
|
|
ret = -ENOMEM;
|
|
|
- digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size,
|
|
|
- GFP_KERNEL);
|
|
|
- if (!digest)
|
|
|
+ sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
|
|
|
+ if (!sig->digest)
|
|
|
goto error;
|
|
|
|
|
|
- cert->sig.digest = digest;
|
|
|
- cert->sig.digest_size = digest_size;
|
|
|
+ desc = kzalloc(desc_size, GFP_KERNEL);
|
|
|
+ if (!desc)
|
|
|
+ goto error;
|
|
|
|
|
|
- desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));
|
|
|
desc->tfm = tfm;
|
|
|
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
|
|
|
|
|
|
ret = crypto_shash_init(desc);
|
|
|
if (ret < 0)
|
|
|
- goto error;
|
|
|
+ goto error_2;
|
|
|
might_sleep();
|
|
|
- ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, digest);
|
|
|
+ ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
|
|
|
+
|
|
|
+error_2:
|
|
|
+ kfree(desc);
|
|
|
error:
|
|
|
crypto_free_shash(tfm);
|
|
|
pr_devel("<==%s() = %d\n", __func__, ret);
|
|
@@ -230,7 +228,7 @@ int x509_check_signature(const struct public_key *pub,
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
|
|
|
- ret = public_key_verify_signature(pub, &cert->sig);
|
|
|
+ ret = public_key_verify_signature(pub, cert->sig);
|
|
|
if (ret == -ENOPKG)
|
|
|
cert->unsupported_crypto = true;
|
|
|
pr_debug("Cert Verification: %d\n", ret);
|
|
@@ -250,17 +248,18 @@ EXPORT_SYMBOL_GPL(x509_check_signature);
|
|
|
static int x509_validate_trust(struct x509_certificate *cert,
|
|
|
struct key *trust_keyring)
|
|
|
{
|
|
|
+ struct public_key_signature *sig = cert->sig;
|
|
|
struct key *key;
|
|
|
int ret = 1;
|
|
|
|
|
|
if (!trust_keyring)
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
- if (ca_keyid && !asymmetric_key_id_partial(cert->akid_skid, ca_keyid))
|
|
|
+ if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
|
|
|
return -EPERM;
|
|
|
|
|
|
key = x509_request_asymmetric_key(trust_keyring,
|
|
|
- cert->akid_id, cert->akid_skid,
|
|
|
+ sig->auth_ids[0], sig->auth_ids[1],
|
|
|
false);
|
|
|
if (!IS_ERR(key)) {
|
|
|
if (!use_builtin_keys
|
|
@@ -292,8 +291,8 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
|
|
|
pr_devel("Cert Subject: %s\n", cert->subject);
|
|
|
|
|
|
if (!cert->pub->pkey_algo ||
|
|
|
- !cert->sig.pkey_algo ||
|
|
|
- !cert->sig.hash_algo) {
|
|
|
+ !cert->sig->pkey_algo ||
|
|
|
+ !cert->sig->hash_algo) {
|
|
|
ret = -ENOPKG;
|
|
|
goto error_free_cert;
|
|
|
}
|
|
@@ -301,15 +300,15 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
|
|
|
pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);
|
|
|
pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);
|
|
|
pr_devel("Cert Signature: %s + %s\n",
|
|
|
- cert->sig.pkey_algo,
|
|
|
- cert->sig.hash_algo);
|
|
|
+ cert->sig->pkey_algo,
|
|
|
+ cert->sig->hash_algo);
|
|
|
|
|
|
cert->pub->id_type = "X509";
|
|
|
|
|
|
/* Check the signature on the key if it appears to be self-signed */
|
|
|
- if ((!cert->akid_skid && !cert->akid_id) ||
|
|
|
- asymmetric_key_id_same(cert->skid, cert->akid_skid) ||
|
|
|
- asymmetric_key_id_same(cert->id, cert->akid_id)) {
|
|
|
+ if ((!cert->sig->auth_ids[0] && !cert->sig->auth_ids[1]) ||
|
|
|
+ asymmetric_key_id_same(cert->skid, cert->sig->auth_ids[1]) ||
|
|
|
+ asymmetric_key_id_same(cert->id, cert->sig->auth_ids[0])) {
|
|
|
ret = x509_check_signature(cert->pub, cert); /* self-signed */
|
|
|
if (ret < 0)
|
|
|
goto error_free_cert;
|
|
@@ -353,6 +352,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
|
|
|
prep->payload.data[asym_subtype] = &public_key_subtype;
|
|
|
prep->payload.data[asym_key_ids] = kids;
|
|
|
prep->payload.data[asym_crypto] = cert->pub;
|
|
|
+ prep->payload.data[asym_auth] = cert->sig;
|
|
|
prep->description = desc;
|
|
|
prep->quotalen = 100;
|
|
|
|
|
@@ -360,6 +360,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
|
|
|
cert->pub = NULL;
|
|
|
cert->id = NULL;
|
|
|
cert->skid = NULL;
|
|
|
+ cert->sig = NULL;
|
|
|
desc = NULL;
|
|
|
ret = 0;
|
|
|
|