Skip to content

Commit

Permalink
KEYS: Move x509_request_asymmetric_key() to asymmetric_type.c
Browse files Browse the repository at this point in the history
Move x509_request_asymmetric_key() to asymmetric_type.c so that it can be
generalised.

Signed-off-by: David Howells <[email protected]>
  • Loading branch information
dhowells committed Apr 11, 2016
1 parent 5ac7eac commit 983023f
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 95 deletions.
89 changes: 89 additions & 0 deletions crypto/asymmetric_keys/asymmetric_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,95 @@ EXPORT_SYMBOL_GPL(key_being_used_for);
static LIST_HEAD(asymmetric_key_parsers);
static DECLARE_RWSEM(asymmetric_key_parsers_sem);

/**
* x509_request_asymmetric_key - Request a key by X.509 certificate params.
* @keyring: The keys to search.
* @id: The issuer & serialNumber to look for or NULL.
* @skid: The subjectKeyIdentifier to look for or NULL.
* @partial: Use partial match if true, exact if false.
*
* Find a key in the given keyring by identifier. The preferred identifier is
* the issuer + serialNumber and the fallback identifier is the
* subjectKeyIdentifier. If both are given, the lookup is by the former, but
* the latter must also match.
*/
struct key *x509_request_asymmetric_key(struct key *keyring,
const struct asymmetric_key_id *id,
const struct asymmetric_key_id *skid,
bool partial)
{
struct key *key;
key_ref_t ref;
const char *lookup;
char *req, *p;
int len;

if (id) {
lookup = id->data;
len = id->len;
} else {
lookup = skid->data;
len = skid->len;
}

/* Construct an identifier "id:<keyid>". */
p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);
if (!req)
return ERR_PTR(-ENOMEM);

if (partial) {
*p++ = 'i';
*p++ = 'd';
} else {
*p++ = 'e';
*p++ = 'x';
}
*p++ = ':';
p = bin2hex(p, lookup, len);
*p = 0;

pr_debug("Look up: \"%s\"\n", req);

ref = keyring_search(make_key_ref(keyring, 1),
&key_type_asymmetric, req);
if (IS_ERR(ref))
pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
kfree(req);

if (IS_ERR(ref)) {
switch (PTR_ERR(ref)) {
/* Hide some search errors */
case -EACCES:
case -ENOTDIR:
case -EAGAIN:
return ERR_PTR(-ENOKEY);
default:
return ERR_CAST(ref);
}
}

key = key_ref_to_ptr(ref);
if (id && skid) {
const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
if (!kids->id[1]) {
pr_debug("issuer+serial match, but expected SKID missing\n");
goto reject;
}
if (!asymmetric_key_id_same(skid, kids->id[1])) {
pr_debug("issuer+serial match, but SKID does not\n");
goto reject;
}
}

pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));
return key;

reject:
key_put(key);
return ERR_PTR(-EKEYREJECTED);
}
EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);

/**
* asymmetric_key_generate_id: Construct an asymmetric key ID
* @val_1: First binary blob
Expand Down
89 changes: 0 additions & 89 deletions crypto/asymmetric_keys/x509_public_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,95 +58,6 @@ static int __init ca_keys_setup(char *str)
__setup("ca_keys=", ca_keys_setup);
#endif

/**
* x509_request_asymmetric_key - Request a key by X.509 certificate params.
* @keyring: The keys to search.
* @id: The issuer & serialNumber to look for or NULL.
* @skid: The subjectKeyIdentifier to look for or NULL.
* @partial: Use partial match if true, exact if false.
*
* Find a key in the given keyring by identifier. The preferred identifier is
* the issuer + serialNumber and the fallback identifier is the
* subjectKeyIdentifier. If both are given, the lookup is by the former, but
* the latter must also match.
*/
struct key *x509_request_asymmetric_key(struct key *keyring,
const struct asymmetric_key_id *id,
const struct asymmetric_key_id *skid,
bool partial)
{
struct key *key;
key_ref_t ref;
const char *lookup;
char *req, *p;
int len;

if (id) {
lookup = id->data;
len = id->len;
} else {
lookup = skid->data;
len = skid->len;
}

/* Construct an identifier "id:<keyid>". */
p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);
if (!req)
return ERR_PTR(-ENOMEM);

if (partial) {
*p++ = 'i';
*p++ = 'd';
} else {
*p++ = 'e';
*p++ = 'x';
}
*p++ = ':';
p = bin2hex(p, lookup, len);
*p = 0;

pr_debug("Look up: \"%s\"\n", req);

ref = keyring_search(make_key_ref(keyring, 1),
&key_type_asymmetric, req);
if (IS_ERR(ref))
pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
kfree(req);

if (IS_ERR(ref)) {
switch (PTR_ERR(ref)) {
/* Hide some search errors */
case -EACCES:
case -ENOTDIR:
case -EAGAIN:
return ERR_PTR(-ENOKEY);
default:
return ERR_CAST(ref);
}
}

key = key_ref_to_ptr(ref);
if (id && skid) {
const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
if (!kids->id[1]) {
pr_debug("issuer+serial match, but expected SKID missing\n");
goto reject;
}
if (!asymmetric_key_id_same(skid, kids->id[1])) {
pr_debug("issuer+serial match, but SKID does not\n");
goto reject;
}
}

pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));
return key;

reject:
key_put(key);
return ERR_PTR(-EKEYREJECTED);
}
EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);

/*
* Set up the signature parameters in an X.509 certificate. This involves
* digesting the signed data and extracting the signature.
Expand Down
6 changes: 0 additions & 6 deletions include/crypto/public_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,6 @@ struct key;
extern int verify_signature(const struct key *key,
const struct public_key_signature *sig);

struct asymmetric_key_id;
extern struct key *x509_request_asymmetric_key(struct key *keyring,
const struct asymmetric_key_id *id,
const struct asymmetric_key_id *skid,
bool partial);

int public_key_verify_signature(const struct public_key *pkey,
const struct public_key_signature *sig);

Expand Down
5 changes: 5 additions & 0 deletions include/keys/asymmetric-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
return key->payload.data[asym_key_ids];
}

extern struct key *x509_request_asymmetric_key(struct key *keyring,
const struct asymmetric_key_id *id,
const struct asymmetric_key_id *skid,
bool partial);

/*
* The payload is at the discretion of the subtype.
*/
Expand Down

0 comments on commit 983023f

Please sign in to comment.