pkcs15: Expose the map_usage() function from CAC to other pkcs15 emulators
This commit is contained in:
parent
5e1bfe0acc
commit
2882c93ec1
|
@ -84,89 +84,6 @@ static const char * cac_get_name(int type)
|
|||
return ("CAC");
|
||||
}
|
||||
|
||||
/*
|
||||
* These could move to a helper file for other cards that wish to use usage as a way of getting flags
|
||||
*/
|
||||
|
||||
/* Only certain usages are valid for a given algorithm, return all the usages that the algorithm supports so we
|
||||
* can use it as a filter for all the public and private key usages */
|
||||
static unsigned int
|
||||
cac_alg_flags_from_algorithm(int algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
case SC_ALGORITHM_RSA:
|
||||
return SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP |
|
||||
SC_PKCS15_PRKEY_USAGE_VERIFY | SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER |
|
||||
SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP |
|
||||
SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER |
|
||||
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
case SC_ALGORITHM_DSA:
|
||||
return SC_PKCS15_PRKEY_USAGE_VERIFY| SC_PKCS15_PRKEY_USAGE_SIGN |
|
||||
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
#ifdef SC_ALGORITHM_DH
|
||||
case SC_ALGORITHM_DH:
|
||||
return SC_PKCS15_PRKEY_USAGE_DERIVE ;
|
||||
#endif
|
||||
case SC_ALGORITHM_EC:
|
||||
return SC_PKCS15_PRKEY_USAGE_DERIVE | SC_PKCS15_PRKEY_USAGE_VERIFY|
|
||||
SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
case SC_ALGORITHM_GOSTR3410:
|
||||
return SC_PKCS15_PRKEY_USAGE_DERIVE | SC_PKCS15_PRKEY_USAGE_VERIFY|
|
||||
SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* These are the cert key usage bits that map to various PKCS #11 (and thus PKCS #15) flags */
|
||||
#define CAC_X509_USAGE_SIGNATURE \
|
||||
(SC_X509_DIGITAL_SIGNATURE | \
|
||||
SC_X509_NON_REPUDIATION | \
|
||||
SC_X509_KEY_CERT_SIGN | \
|
||||
SC_X509_CRL_SIGN)
|
||||
#define CAC_X509_USAGE_DERIVE \
|
||||
SC_X509_KEY_AGREEMENT
|
||||
#define CAC_X509_USAGE_UNWRAP \
|
||||
(SC_X509_KEY_ENCIPHERMENT | \
|
||||
SC_X509_KEY_AGREEMENT)
|
||||
#define CAC_X509_USAGE_DECRYPT \
|
||||
(SC_X509_DATA_ENCIPHERMENT | \
|
||||
SC_X509_ENCIPHER_ONLY)
|
||||
#define CAC_X509_USAGE_NONREPUDIATION \
|
||||
SC_X509_NON_REPUDIATION
|
||||
|
||||
/* map a cert usage and algorithm to public and private key usages */
|
||||
static int
|
||||
cac_map_usage(unsigned int cert_usage, int algorithm, unsigned int *pub_usage_ptr, unsigned int *pr_usage_ptr, int allow_nonrepudiation)
|
||||
{
|
||||
unsigned int pub_usage = 0, pr_usage = 0;
|
||||
unsigned int alg_flags = cac_alg_flags_from_algorithm(algorithm);
|
||||
|
||||
if (cert_usage & CAC_X509_USAGE_SIGNATURE) {
|
||||
pub_usage |= SC_PKCS15_PRKEY_USAGE_VERIFY|SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER;
|
||||
pr_usage |= SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_SIGNRECOVER;
|
||||
}
|
||||
if (cert_usage & CAC_X509_USAGE_DERIVE) {
|
||||
pub_usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
|
||||
pr_usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
|
||||
}
|
||||
if (cert_usage & (CAC_X509_USAGE_DECRYPT|CAC_X509_USAGE_UNWRAP)) {
|
||||
pub_usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT;
|
||||
pr_usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT;
|
||||
}
|
||||
if (allow_nonrepudiation && (cert_usage & CAC_X509_USAGE_NONREPUDIATION)) {
|
||||
pub_usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
pr_usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
}
|
||||
/* filter usages algorithm */
|
||||
if (pub_usage_ptr) {
|
||||
*pub_usage_ptr = pub_usage & alg_flags;
|
||||
}
|
||||
if (pr_usage_ptr) {
|
||||
*pr_usage_ptr = pr_usage & alg_flags;
|
||||
}
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card)
|
||||
{
|
||||
static const pindata pins[] = {
|
||||
|
@ -409,7 +326,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card)
|
|||
if (r < 0) {
|
||||
usage = 0xd9ULL; /* basic default usage */
|
||||
}
|
||||
cac_map_usage(usage, cert_out->key->algorithm, &pubkey_info.usage, &prkey_info.usage, 1);
|
||||
sc_pkcs15_map_usage(usage, cert_out->key->algorithm, &pubkey_info.usage, &prkey_info.usage, 1);
|
||||
sc_log(card->ctx, "cert %s: cert_usage=0x%x, pub_usage=0x%x priv_usage=0x%x\n",
|
||||
sc_dump_hex(cert_info.id.value, cert_info.id.len),
|
||||
usage, pubkey_info.usage, prkey_info.usage);
|
||||
|
|
|
@ -257,6 +257,8 @@ sc_pkcs15_get_extension(struct sc_context *ctx, struct sc_pkcs15_cert *cert,
|
|||
{ NULL, 0, 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
for (next_ext = cert->extensions, next_ext_len = cert->extensions_len; next_ext_len; ) {
|
||||
/* unwrap the set and point to the next ava */
|
||||
ext = sc_asn1_skip_tag(ctx, &next_ext, &next_ext_len,
|
||||
|
@ -324,6 +326,8 @@ sc_pkcs15_get_bitstring_extension(struct sc_context *ctx,
|
|||
{ NULL, 0, 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
r = sc_pkcs15_get_extension(ctx, cert, type, &bit_string, &bit_string_len, is_critical);
|
||||
LOG_TEST_RET(ctx, r, "Get extension error");
|
||||
|
||||
|
@ -550,6 +554,88 @@ sc_pkcs15_encode_cdf_entry(sc_context_t *ctx, const struct sc_pkcs15_object *obj
|
|||
return r;
|
||||
}
|
||||
|
||||
/* Only certain usages are valid for a given algorithm, return all the usages
|
||||
* that the algorithm supports so we can use it as a filter for all
|
||||
* the public and private key usages
|
||||
*/
|
||||
static unsigned int
|
||||
sc_pkcs15_alg_flags_from_algorithm(int algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
case SC_ALGORITHM_RSA:
|
||||
return SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP |
|
||||
SC_PKCS15_PRKEY_USAGE_VERIFY | SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER |
|
||||
SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP |
|
||||
SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER |
|
||||
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
case SC_ALGORITHM_DSA:
|
||||
return SC_PKCS15_PRKEY_USAGE_VERIFY| SC_PKCS15_PRKEY_USAGE_SIGN |
|
||||
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
#ifdef SC_ALGORITHM_DH
|
||||
case SC_ALGORITHM_DH:
|
||||
return SC_PKCS15_PRKEY_USAGE_DERIVE ;
|
||||
#endif
|
||||
case SC_ALGORITHM_EC:
|
||||
return SC_PKCS15_PRKEY_USAGE_DERIVE | SC_PKCS15_PRKEY_USAGE_VERIFY|
|
||||
SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
case SC_ALGORITHM_GOSTR3410:
|
||||
return SC_PKCS15_PRKEY_USAGE_DERIVE | SC_PKCS15_PRKEY_USAGE_VERIFY|
|
||||
SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* These are the cert key usage bits that map to various PKCS #11 (and thus PKCS #15) flags */
|
||||
#define SC_PKCS15_X509_USAGE_SIGNATURE \
|
||||
(SC_X509_DIGITAL_SIGNATURE | \
|
||||
SC_X509_NON_REPUDIATION | \
|
||||
SC_X509_KEY_CERT_SIGN | \
|
||||
SC_X509_CRL_SIGN)
|
||||
#define SC_PKCS15_X509_USAGE_DERIVE \
|
||||
SC_X509_KEY_AGREEMENT
|
||||
#define SC_PKCS15_X509_USAGE_UNWRAP \
|
||||
(SC_X509_KEY_ENCIPHERMENT | \
|
||||
SC_X509_KEY_AGREEMENT)
|
||||
#define SC_PKCS15_X509_USAGE_DECRYPT \
|
||||
(SC_X509_DATA_ENCIPHERMENT | \
|
||||
SC_X509_ENCIPHER_ONLY)
|
||||
#define SC_PKCS15_X509_USAGE_NONREPUDIATION \
|
||||
SC_X509_NON_REPUDIATION
|
||||
|
||||
/* map a cert usage and algorithm to public and private key usages */
|
||||
int
|
||||
sc_pkcs15_map_usage(unsigned int cert_usage, int algorithm,
|
||||
unsigned int *pub_usage_ptr, unsigned int *pr_usage_ptr,
|
||||
int allow_nonrepudiation)
|
||||
{
|
||||
unsigned int pub_usage = 0, pr_usage = 0;
|
||||
unsigned int alg_flags = sc_pkcs15_alg_flags_from_algorithm(algorithm);
|
||||
|
||||
if (cert_usage & SC_PKCS15_X509_USAGE_SIGNATURE) {
|
||||
pub_usage |= SC_PKCS15_PRKEY_USAGE_VERIFY|SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER;
|
||||
pr_usage |= SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_SIGNRECOVER;
|
||||
}
|
||||
if (cert_usage & SC_PKCS15_X509_USAGE_DERIVE) {
|
||||
pub_usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
|
||||
pr_usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
|
||||
}
|
||||
if (cert_usage & (SC_PKCS15_X509_USAGE_DECRYPT|SC_PKCS15_X509_USAGE_UNWRAP)) {
|
||||
pub_usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT;
|
||||
pr_usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT;
|
||||
}
|
||||
if (allow_nonrepudiation && (cert_usage & SC_PKCS15_X509_USAGE_NONREPUDIATION)) {
|
||||
pub_usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
pr_usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
}
|
||||
/* filter usages algorithm */
|
||||
if (pub_usage_ptr) {
|
||||
*pub_usage_ptr = pub_usage & alg_flags;
|
||||
}
|
||||
if (pr_usage_ptr) {
|
||||
*pr_usage_ptr = pr_usage & alg_flags;
|
||||
}
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert)
|
||||
|
|
|
@ -754,6 +754,9 @@ int sc_pkcs15_get_name_from_dn(struct sc_context *ctx,
|
|||
const u8 *dn, size_t dn_len,
|
||||
const struct sc_object_id *type,
|
||||
u8 **name, size_t *name_len);
|
||||
int sc_pkcs15_map_usage(unsigned int cert_usage, int algorithm,
|
||||
unsigned int *pub_usage_ptr, unsigned int *pr_usage_ptr,
|
||||
int allow_nonrepudiation);
|
||||
int sc_pkcs15_get_extension(struct sc_context *ctx,
|
||||
struct sc_pkcs15_cert *cert,
|
||||
const struct sc_object_id *type,
|
||||
|
|
Loading…
Reference in New Issue