- started to work on PuKDF stuff

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@258 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
okir 2002-03-04 10:33:35 +00:00
parent 25f15f0ba1
commit ffe5629e89
4 changed files with 293 additions and 16 deletions

View File

@ -53,10 +53,14 @@ EF PKCS15-PrKDF
Path 3F0050154402
ACL *=NEVER READ=NONE UPDATE=CHV2
EF PKCS15-CDF
EF PKCS15-PuKDF
Path 3F0050154403
ACL *=NEVER READ=NONE UPDATE=CHV2
EF PKCS15-CDF
Path 3F0050154404
ACL *=NEVER READ=NONE UPDATE=CHV2
# Private key files.
# GPK private key files will never let you read the private key
# part, so it's okay to set READ=NONE. What's more, we need

View File

@ -56,6 +56,10 @@ static int pkcs15_generate_key(struct sc_profile *);
static int pkcs15_generate_key_soft(struct sc_profile *,
unsigned int, unsigned int);
static int pkcs15_store_key(struct sc_profile *, EVP_PKEY *);
static int pkcs15_store_private_key(struct sc_profile *, EVP_PKEY *,
struct sc_pkcs15_id *);
static int pkcs15_store_public_key(struct sc_profile *, EVP_PKEY *,
struct sc_pkcs15_id *);
static int pkcs15_write(struct sc_profile *,
const char *name, pkcs15_encoder, int);
static int pkcs15_write_df(struct sc_profile *,
@ -162,6 +166,10 @@ main(int argc, char **argv)
fprintf(stderr, "No action specified.\n");
print_usage_and_die("pkcs15-init");
}
if (!opt_profile) {
fprintf(stderr, "No profile specified.\n");
print_usage_and_die("pkcs15-init");
}
/* When asked to init the card, read the profile first.
* This makes people writing new profiles happier because
@ -437,6 +445,17 @@ static int
pkcs15_store_key(struct sc_profile *profile, EVP_PKEY *pkey)
{
struct sc_pkcs15_id id;
if (pkcs15_store_private_key(profile, pkey, &id) < 0)
return -1;
/* XXX store public key */
return pkcs15_store_public_key(profile, pkey, &id);
}
static int
pkcs15_store_private_key(struct sc_profile *profile, EVP_PKEY *pkey,
struct sc_pkcs15_id *id)
{
struct sc_pkcs15_df *df;
struct prkey_info *pinfo;
unsigned int j;
@ -444,12 +463,15 @@ pkcs15_store_key(struct sc_profile *profile, EVP_PKEY *pkey)
if (opt_objectid == NULL)
fatal("No key ID specified; please use --id");
sc_pkcs15_format_id(opt_objectid, &id);
/* XXX: support special ID "new" to assign a new ID and
* create PK file info from template */
/* Find the private key file matching the given ID */
sc_pkcs15_format_id(opt_objectid, id);
for (pinfo = profile->prkey_list; pinfo; pinfo = pinfo->next) {
if (!strcasecmp(pinfo->ident, opt_objectid)
|| sc_pkcs15_compare_id(&id, &pinfo->pkcs15.id) == 1)
|| sc_pkcs15_compare_id(id, &pinfo->pkcs15.id) == 1)
break;
}
if (pinfo == NULL) {
@ -491,7 +513,62 @@ pkcs15_store_key(struct sc_profile *profile, EVP_PKEY *pkey)
for (j = 0; r >= 0 && j < df->count; j++)
r = pkcs15_write_df(profile, df, j);
printf("Successfully stored private key\n");
if (r >= 0)
printf("Successfully stored private key\n");
return r;
}
static int
pkcs15_store_public_key(struct sc_profile *profile, EVP_PKEY *pkey,
struct sc_pkcs15_id *id)
{
struct pubkey_info *pinfo;
struct sc_pkcs15_df *df;
unsigned char *data, *p;
size_t size;
RSA *rsa;
int r, j;
/* Find the private key file matching the given ID */
for (pinfo = profile->pubkey_list; pinfo; pinfo = pinfo->next) {
if (!strcasecmp(pinfo->ident, opt_objectid)
|| sc_pkcs15_compare_id(id, &pinfo->pkcs15.id) == 1)
break;
}
if (pinfo == NULL) {
error("Unable to find public key file\n");
return -1;
}
#ifdef notyet
if (pkey == NULL)
do_read_public_key(opt_keyfile, opt_format, &pkey);
#endif
r = SC_ERROR_NOT_SUPPORTED;
switch (pkey->type) {
case EVP_PKEY_RSA:
rsa = EVP_PKEY_get1_RSA(pkey);
size = i2d_RSAPublicKey(rsa, NULL);
data = p = malloc(size);
i2d_RSAPublicKey(rsa, &p);
break;
}
if (r < 0) {
error("Failed to store public key: %s", sc_strerror(r));
return r;
}
r = do_create_and_update_file(profile, pinfo->file->file, data, size);
free(data);
/* Now update the PrKDF */
df = &profile->p15_card->df[SC_PKCS15_PUKDF];
for (j = 0; r >= 0 && j < df->count; j++)
r = pkcs15_write_df(profile, df, j);
if (r >= 0)
printf("Successfully stored public key\n");
return r;
}

View File

@ -34,7 +34,14 @@ struct command {
int (*func)(int, char **);
};
enum { PARSE_HEADER, PARSE_FILE, PARSE_CARDINFO, PARSE_PIN, PARSE_PRKEY };
enum {
PARSE_HEADER,
PARSE_FILE,
PARSE_CARDINFO,
PARSE_PIN,
PARSE_PRKEY,
PARSE_PUBKEY
};
static struct parser_info {
const char * filename;
unsigned int lineno;
@ -43,6 +50,7 @@ static struct parser_info {
struct file_info * cur_file;
struct pin_info * cur_pin;
struct prkey_info * cur_prkey;
struct pubkey_info * cur_pubkey;
} parser;
struct map {
@ -132,9 +140,9 @@ static struct map keyUsageNames[] = {
};
static struct map keyAccessFlags[] = {
{ "SENSITIVE", 0x01 },
{ "EXTRACT", 0x02 },
{ "EXTRACTABLE", 0x02 },
{ "ALWAYSSENSITIVE", 0x04 },
{ "NEVEREXTRACT", 0x08 },
{ "NEVEREXTRACTABLE", 0x08 },
{ "LOCAL", 0x10 },
{ 0, 0 }
};
@ -201,6 +209,9 @@ sc_profile_init(struct sc_profile *pro)
/* Assume card does RSA natively, but no DSA */
pro->rsa_access_flags = 0x1D;
pro->dsa_access_flags = 0x12;
pro->pin_encoding = 0x01;
pro->pin_minlen = 4;
pro->pin_maxlen = 8;
}
int
@ -373,7 +384,8 @@ sc_profile_build_pkcs15(struct sc_profile *pro)
{
struct sc_pkcs15_card *p15card;
struct pin_info *pi;
struct prkey_info *ki;
struct prkey_info *prk;
struct pubkey_info *puk;
int res = 0;
p15card = pro->p15_card;
@ -381,6 +393,8 @@ sc_profile_build_pkcs15(struct sc_profile *pro)
warn("No CDF defined in profile");
if (p15card->df[SC_PKCS15_PRKDF].count == 0)
warn("No PrKDF defined in profile");
if (p15card->df[SC_PKCS15_PUKDF].count == 0)
warn("No PuKDF defined in profile");
/* First, build AODF contents */
if (p15card->df[SC_PKCS15_AODF].count == 0)
@ -395,15 +409,27 @@ sc_profile_build_pkcs15(struct sc_profile *pro)
}
/* Loop over all private keys and add them to the PrKDF */
for (ki = pro->prkey_list; ki && !res; ki = ki->next) {
if (!ki->file)
fatal("No file for private key \"%s\"\n", ki->ident);
memcpy(&ki->pkcs15.path, &ki->file->file->path,
for (prk = pro->prkey_list; prk && !res; prk = prk->next) {
if (!prk->file)
fatal("No file for private key \"%s\"\n", prk->ident);
memcpy(&prk->pkcs15.path, &prk->file->file->path,
sizeof(struct sc_path));
res = sc_pkcs15_add_object(p15card,
&p15card->df[SC_PKCS15_PRKDF],
ki->file->pkcs15.fileno,
&ki->pkcs15_obj);
prk->file->pkcs15.fileno,
&prk->pkcs15_obj);
}
/* Loop over all public keys and add them to the PrKDF */
for (puk = pro->pubkey_list; puk && !res; puk = puk->next) {
if (!puk->file)
fatal("No file for public key \"%s\"\n", puk->ident);
memcpy(&puk->pkcs15.path, &puk->file->file->path,
sizeof(struct sc_path));
res = sc_pkcs15_add_object(p15card,
&p15card->df[SC_PKCS15_PUKDF],
puk->file->pkcs15.fileno,
&puk->pkcs15_obj);
}
return res;
@ -469,6 +495,13 @@ do_minpinlength(int argc, char **argv)
return get_uint(argv[0], &parser.profile->pin_minlen);
}
static int
do_default_pin_type(int argc, char **argv)
{
return map_str2int(argv[0],
&parser.profile->pin_encoding, pinTypeNames);
}
static int
do_card_label(int argc, char **argv)
{
@ -737,7 +770,7 @@ do_pin(int argc, char **argv)
pi->ident = strdup(name);
pi->id = id;
pi->attempt[0] = 2;
pi->pkcs15.type = 1;
pi->pkcs15.type = pro->pin_encoding;
pi->pkcs15.flags = 0x32;
pi->pkcs15.min_length = pro->pin_minlen;
pi->pkcs15.stored_length = pro->pin_maxlen;
@ -953,11 +986,139 @@ do_prkey_reference(int argc, char **argv)
return get_uint(argv[0], (unsigned int *) &ki->key_reference);
}
static int
do_pubkey(int argc, char **argv)
{
struct sc_profile *pro = parser.profile;
struct pubkey_info *ki, **tail;
if ((ki = sc_profile_find_pubkey(pro, argv[0])) != NULL)
goto out;
ki = calloc(1, sizeof(*ki));
ki->ident = strdup(argv[0]);
/* We initialize the modulus length at 1024 to make sure
* the PrKDF is big enough.
* This value will be overwritten later when the keys are
* loaded into the card. */
ki->pkcs15.modulus_length = 1024;
ki->pkcs15.access_flags = pro->rsa_access_flags;
ki->pkcs15_obj.type = SC_PKCS15_TYPE_PRKEY_RSA;
ki->pkcs15_obj.data = &ki->pkcs15;
for (tail = &pro->pubkey_list; *tail; tail = &(*tail)->next)
;
*tail = ki;
out: parser.cur_pubkey = ki;
parser.section = PARSE_PUBKEY;
return 0;
}
static int
do_pubkey_file(int argc, char **argv)
{
struct file_info *fi;
const char *name = argv[0];
if (!(fi = sc_profile_find_file(parser.profile, name))) {
parse_error("unknown private key file \"%s\"\n", name);
return 1;
}
parser.cur_pubkey->file = fi;
return 0;
}
static int
do_pubkey_index(int argc, char **argv)
{
return get_uint(argv[0], &parser.cur_pubkey->index);
}
static int
do_pubkey_algorithm(int argc, char **argv)
{
struct pubkey_info *ki = parser.cur_pubkey;
if (map_str2int(argv[0], &ki->pkcs15_obj.type, algorithmNames))
return 1;
switch (ki->pkcs15_obj.type) {
case SC_PKCS15_TYPE_PRKEY_RSA:
ki->pkcs15.access_flags = parser.profile->rsa_access_flags;
break;
#ifdef SC_PKCS15_TYPE_PRKEY_DSA
case SC_PKCS15_TYPE_PRKEY_DSA:
ki->pkcs15.access_flags = parser.profile->dsa_access_flags;
break;
#endif
}
return 0;
}
static int
do_pubkey_label(int argc, char **argv)
{
strcpy(parser.cur_pubkey->pkcs15_obj.label, argv[0]);
return 0;
}
static int
do_pubkey_id(int argc, char **argv)
{
sc_pkcs15_format_id(argv[0], &parser.cur_pubkey->pkcs15.id);
return 0;
}
static int
do_pubkey_authid(int argc, char **argv)
{
sc_pkcs15_format_id(argv[0], &parser.cur_pubkey->pkcs15_obj.auth_id);
return 0;
}
static int
do_pubkey_usage(int argc, char **argv)
{
struct sc_pkcs15_pubkey_info *ki = &parser.cur_pubkey->pkcs15;
if (map_str2int(argv[0], &ki->usage, keyUsageNames)) {
parse_error("Bad key usage \"%s\"", argv[0]);
return 1;
}
return 0;
}
static int
do_pubkey_access_flags(int argc, char **argv)
{
struct sc_pkcs15_pubkey_info *ki = &parser.cur_pubkey->pkcs15;
unsigned int access;
ki->access_flags = 0;
while (argc--) {
if (map_str2int(argv[0], &access, keyAccessFlags))
return 1;
ki->access_flags |= access;
}
return 0;
}
static int
do_pubkey_reference(int argc, char **argv)
{
struct sc_pkcs15_pubkey_info *ki = &parser.cur_pubkey->pkcs15;
return get_uint(argv[0], (unsigned int *) &ki->key_reference);
}
static struct command commands[] = {
{ "CardInfo", -1, 0, 0, do_cardinfo },
{ "Driver", PARSE_CARDINFO, 1, 1, do_card_driver },
{ "MaxPinLength", PARSE_CARDINFO, 1, 1, do_maxpinlength },
{ "MinPinLength", PARSE_CARDINFO, 1, 1, do_minpinlength },
{ "PinEncoding", PARSE_CARDINFO, 1, 1, do_default_pin_type },
{ "Key", PARSE_CARDINFO, 3, 3, do_key },
{ "Label", PARSE_CARDINFO, 1, 1, do_card_label },
{ "Manufacturer", PARSE_CARDINFO, 1, 1, do_card_manufacturer},
@ -975,7 +1136,7 @@ static struct command commands[] = {
{ "File", PARSE_PIN, 1, 1, do_pin_file },
{ "Offset", PARSE_PIN, 1, 1, do_pin_offset },
{ "Attempts", PARSE_PIN, 1, 2, do_pin_attempts },
{ "Type", PARSE_PIN, 1, 1, do_pin_type },
{ "Encoding", PARSE_PIN, 1, 1, do_pin_type },
{ "Reference", PARSE_PIN, 1, 1, do_pin_reference},
{ "AuthID", PARSE_PIN, 1, 1, do_pin_authid },
{ "Label", PARSE_PIN, 1, 1, do_pin_label },
@ -989,6 +1150,16 @@ static struct command commands[] = {
{ "KeyUsage", PARSE_PRKEY, 1, 1, do_prkey_usage },
{ "AccessFlags", PARSE_PRKEY, 1, -1, do_prkey_access_flags },
{ "Reference", PARSE_PRKEY, 1, 1, do_prkey_reference },
{ "PublicKey", -1, 1, 1, do_pubkey },
{ "Label", PARSE_PUBKEY, 1, 1, do_pubkey_label },
{ "Algorithm", PARSE_PUBKEY, 1, 1, do_pubkey_algorithm},
{ "File", PARSE_PUBKEY, 1, 1, do_pubkey_file },
{ "Index", PARSE_PUBKEY, 1, 1, do_pubkey_index },
{ "ID", PARSE_PUBKEY, 1, 1, do_pubkey_id },
{ "AuthID", PARSE_PUBKEY, 1, 1, do_pubkey_authid },
{ "KeyUsage", PARSE_PUBKEY, 1, 1, do_pubkey_usage },
{ "AccessFlags", PARSE_PUBKEY, 1, -1, do_pubkey_access_flags },
{ "Reference", PARSE_PUBKEY, 1, 1, do_pubkey_reference },
#if 0
#endif
@ -1097,6 +1268,18 @@ sc_profile_find_prkey(struct sc_profile *pro, const char *ident)
return NULL;
}
struct pubkey_info *
sc_profile_find_pubkey(struct sc_profile *pro, const char *ident)
{
struct pubkey_info *ki;
for (ki = pro->pubkey_list; ki; ki = ki->next) {
if (!strcasecmp(ki->ident, ident))
return ki;
}
return NULL;
}
char *
next_word(char **cp)
{

View File

@ -61,6 +61,16 @@ struct prkey_info {
struct sc_pkcs15_prkey_info pkcs15;
};
struct pubkey_info {
char * ident;
struct pubkey_info * next;
struct file_info * file;
unsigned int index; /* translates to file offset */
struct sc_pkcs15_object pkcs15_obj;
struct sc_pkcs15_pubkey_info pkcs15;
};
struct sc_profile {
char * driver;
@ -70,10 +80,12 @@ struct sc_profile {
struct pin_info * pin_list;
struct auth_info * auth_list;
struct prkey_info * prkey_list;
struct pubkey_info * pubkey_list;
unsigned int pin_maxlen;
unsigned int pin_minlen;
unsigned int pin_pad_char;
unsigned int pin_encoding;
unsigned int rsa_access_flags;
unsigned int dsa_access_flags;
@ -92,6 +104,7 @@ struct file_info *sc_profile_find_file(struct sc_profile *, const char *);
struct file_info *sc_profile_file_info(struct sc_profile *, struct sc_file *);
struct pin_info *sc_profile_find_pin(struct sc_profile *, const char *);
struct prkey_info *sc_profile_find_prkey(struct sc_profile *, const char *);
struct pubkey_info *sc_profile_find_pubkey(struct sc_profile *, const char *);
struct auth_info *sc_profile_find_key(struct sc_profile *,
unsigned int, unsigned int);