OpenPGP: Accept authentication key for S/MIME decrypting.

The card contains only 1 certificate, which can be used for encrypting.
But this certificate is bound with authentication key, so when decrypting,
the authentication key will be presented to check.
This commit allows to bypass the check in driver. However, it is not enough.
The users have to import the same key to "Encryption key" to help the card find
right key to work.

OpenPGP: Add log and comments.

OpenPGP: Pretend to select dummy files.
Some files are needed by pkcs15init, but not exist in OpenPGP card.
We pretend to know these dummy files to make pkcs15init successful.

Compilation error on windows:
when declaring array use explicit size, add pkcs15-openpgp.obj in Makefile.mak
This commit is contained in:
Nguyễn Hồng Quân 2012-07-17 20:24:42 +07:00 committed by Viktor Tarasov
parent 241bfded4d
commit e34866f188
4 changed files with 32 additions and 13 deletions

View File

@ -922,10 +922,12 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret)
* The "11001101"is defined in sc_pkcs15emu_get_df() function, pkcs15-sync.c file. */
sc_format_path("11001101", &dummy_path);
if (sc_compare_path(path, &dummy_path)) {
*ret = sc_file_new();
/* One use case of this dummy file is after writing certificate in pkcs15init.
* So we set its size to be the same as max certificate size the card supports. */
(*ret)->size = priv->max_cert_size;
if (ret != NULL) {
*ret = sc_file_new();
/* One use case of this dummy file is after writing certificate in pkcs15init.
* So we set its size to be the same as max certificate size the card supports. */
(*ret)->size = priv->max_cert_size;
}
priv->current = NULL;
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
@ -940,6 +942,20 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret)
unsigned int id = bebytes2ushort(path->value + n);
int r = pgp_get_blob(card, blob, id, &blob);
/* This file ID is refered when importing key&certificate via pkcs15init, like above.
* We pretend to successfully find this inexistent file. */
if (id == 0x4402 || id == 0x5f48) {
priv->current = NULL;
if (ret == NULL)
/* No need to return file */
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
/* Else, need to return file */
*ret = sc_file_new();
(*ret)->size = priv->max_cert_size;
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
if (r < 0) { /* failure */
priv->current = NULL;
LOG_FUNC_RETURN(card->ctx, r);
@ -1272,8 +1288,10 @@ pgp_set_security_env(sc_card_t *card,
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
"passing file references not supported");
sc_log(card->ctx, "Key ref %d", env->key_ref[0]);
switch (env->operation) {
case SC_SEC_OPERATION_SIGN:
sc_log(card->ctx, "Operation: Sign.");
if (env->key_ref[0] != 0x00 && env->key_ref[0] != 0x02) {
LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED,
"Key reference not compatible with "
@ -1281,7 +1299,9 @@ pgp_set_security_env(sc_card_t *card,
}
break;
case SC_SEC_OPERATION_DECIPHER:
if (env->key_ref[0] != 0x01) {
sc_log(card->ctx, "Operation: Decipher.");
/* We allow key ref 2 (auth key) to be used for deciphering */
if (env->key_ref[0] != 0x01 && env->key_ref[0] != 0x02) {
LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED,
"Key reference not compatible with "
"requested usage");
@ -1376,11 +1396,11 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen,
switch (env->key_ref[0]) {
case 0x01: /* Decryption key */
case 0x02: /* authentication key */
/* PSO DECIPHER */
sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0x86);
break;
case 0x00: /* signature key */
case 0x02: /* authentication key */
default:
free(temp);
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
@ -1474,7 +1494,7 @@ static int pgp_store_creationtime(sc_card_t *card, u8 key_id, time_t *outtime)
int r;
time_t createtime = 0;
const size_t timestrlen = 64;
char timestring[timestrlen + 1];
char timestring[65];
u8 buf[4];
LOG_FUNC_CALLED(card->ctx);
@ -1904,7 +1924,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info
const size_t max_prtem_len = 7*(1 + 3); /* 7 components */
/* 1 for tag name (91, 92... 97)
* 3 for storing length */
u8 pritemplate[max_prtem_len];
u8 pritemplate[7*(1 + 3)];
size_t tpl_len = 0; /* Actual size of pritemplate */
/* Concatenation of key data */
u8 kdata[3 + 256 + 256 + 512]; /* Exponent is stored in 3 bytes

View File

@ -95,7 +95,7 @@ typedef struct _pgp_key_cfg {
static const pgp_key_cfg_t key_cfg[3] = {
{ "Signature key", "B601", 1, PGP_SIG_PRKEY_USAGE, PGP_SIG_PUBKEY_USAGE },
{ "Encryption key", "B801", 2, PGP_ENC_PRKEY_USAGE, PGP_ENC_PUBKEY_USAGE },
{ "Authentication key", "A401", 2, PGP_AUTH_PRKEY_USAGE, PGP_AUTH_PUBKEY_USAGE }
{ "Authentication key", "A401", 2, PGP_AUTH_PRKEY_USAGE | PGP_ENC_PRKEY_USAGE, PGP_AUTH_PUBKEY_USAGE | PGP_ENC_PUBKEY_USAGE }
};

View File

@ -9,7 +9,7 @@ OBJECTS = pkcs15-lib.obj profile.obj \
pkcs15-muscle.obj pkcs15-asepcos.obj pkcs15-rutoken.obj \
pkcs15-entersafe.obj pkcs15-rtecp.obj pkcs15-westcos.obj \
pkcs15-myeid.obj pkcs15-authentic.obj pkcs15-iasecc.obj \
pkcs15-epass2003.obj
pkcs15-epass2003.obj pkcs15-openpgp.obj
all: $(TARGET)

View File

@ -311,8 +311,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_openpgp_operations = {
NULL /* sanity_check */
};
struct sc_pkcs15init_operations *
sc_pkcs15init_get_openpgp_ops(void)
struct sc_pkcs15init_operations *sc_pkcs15init_get_openpgp_ops(void)
{
return &sc_pkcs15init_openpgp_operations;
}
}