- Rewrote large parts of pkcs15-init for greater flexibility, and with

an eye towards separating some of the stuff into a library that can
  be used by pkcs11.


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@267 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
okir 2002-03-06 17:49:47 +00:00
parent 4f0ce4228a
commit 2fda14ebf5
8 changed files with 1051 additions and 553 deletions

View File

@ -14,12 +14,6 @@ CardInfo
# creating files in the MF
Key PRO 0x0001 "=TEST KEYTEST KEY"
# This is the application DF
DF
Path 3F005015
AID A0:00:00:00:63:50:4B:43:53:2D:31:35
ACL *=NONE
# Note: many commands use the short file ID (i.e. the lower 5 bits
# of the FID) so you must be careful when picking FIDs for the
# public key and PIN files.
@ -27,83 +21,37 @@ DF
# Currently we do not support PIN files that can be updated
# by CHV2. Far too messy.
EF pinfile
Path 3F0050150000
FileID 0000
Structure 0x21 # GPK specific
RecordLength 8
Size 32
ACL *=NEVER
EF PKCS15-DIR
Path 3F002F00
ACL *=NONE
EF PKCS15-ODF
Path 3F0050155031
ACL *=NONE
EF PKCS15-TokenInfo
Path 3F0050155032
ACL *=NONE
EF PKCS15-AODF
Path 3F0050154401
ACL *=NEVER READ=NONE UPDATE=CHV2
EF PKCS15-PrKDF
Path 3F0050154402
ACL *=NEVER READ=NONE UPDATE=CHV2
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
# read access so we're able to update the file.
EF pk1
Path 3F005015000E
EF template-private-key
FileID 0006 # This is the base FileID
Structure 0x2C # GPK specific
ACL *=NEVER READ=NONE UPDATE=CHV2 WRITE=CHV2
EF pk2
Path 3F005015000F
Structure 0x2C # GPK specific
ACL *=NEVER READ=NONE UPDATE=CHV2 WRITE=CHV2
EF template-public-key
FileID 8000
Structure transparent
ACL *=NONE
# CVH1. 7 attempts for the PIN, and 3 for the PUK
# Reference 0x8 means "PIN0 in the local EFsc" in GPK parlance
PIN CHV1
File pinfile
Label "Authentication PIN"
Reference 0x8
Attempts 7 3
AuthID 01
# CVH2. 7 attempts for the PIN, and 3 for the PUK
# Reference 0xA means "PIN2 in the local EFsc" in GPK parlance
PIN CHV2
File pinfile
Label "Non-repudiation PIN"
Reference 0xA
Attempts 7 3
Offset 16
AuthID 02
PrivateKey AuthKey
Label "Authentication Key"
File pk1
ID 45
AuthID 01 # Requires CHV1
KeyUsage sign
PrivateKey SignKey
Label "Non-repudiation Key"
File pk2
ID 46
AuthID 02 # Requires CHV2
KeyUsage NonRepudiation

View File

@ -97,11 +97,7 @@ gpk_update_pins(struct sc_card *card, struct pin_info *info)
blk[3] = ~cks;
}
/* FIXME: we shouldn't have to know about the offset shift
* here. Implement a gpk_update_binary function that just
* shifts the offset if required.
*/
r = sc_update_binary(card, info->file_offset/4, buffer, npins * 8, 0);
r = sc_update_binary(card, info->file_offset, buffer, npins * 8, 0);
return r < 0;
}
@ -139,13 +135,13 @@ gpk_store_pin(struct sc_profile *profile, struct sc_card *card,
}
/* Now create the file */
if ((r = do_create_file(profile, pinfile)) < 0)
if ((r = sc_pkcs15init_create_file(profile, pinfile)) < 0)
goto out;
/* If messing with the PIN file requires any sort of
* authentication, send it to the card now */
if ((r = sc_select_file(card, &pinfile->path, NULL)) < 0
|| (r = do_verify_authinfo(profile, pinfile, SC_AC_OP_UPDATE)) < 0)
|| (r = sc_pkcs15init_authenticate(profile, pinfile, SC_AC_OP_UPDATE)) < 0)
goto out;
r = gpk_update_pins(card, info);
@ -158,16 +154,24 @@ static int
gpk_lock_pinfile(struct sc_profile *profile, struct sc_card *card,
struct sc_file *pinfile)
{
struct sc_path path;
struct sc_file *parent = NULL;
int r;
/* If the UPDATE AC should be NEVER, set the AC now */
if ((r = do_select_parent(profile, pinfile, &parent)) != 0
|| (r = do_verify_authinfo(profile, parent, SC_AC_OP_LOCK)) != 0)
goto out;
r = gpk_lock(card, pinfile, SC_AC_OP_UPDATE);
out: if (parent)
sc_file_free(parent);
/* Select the parent DF */
path = pinfile->path;
if (path.len >= 2)
path.len -= 2;
if (path.len == 0)
sc_format_path("3F00", &path);
if ((r = sc_select_file(card, &path, &parent)) < 0)
return r;
/* Present PINs etc as necessary */
if (!(r = sc_pkcs15init_authenticate(profile, parent, SC_AC_OP_LOCK)))
r = gpk_lock(card, pinfile, SC_AC_OP_UPDATE);
sc_file_free(parent);
return r;
}
@ -220,7 +224,7 @@ gpk_init_app(struct sc_profile *profile, struct sc_card *card)
* in the application DF, create that file first */
/* Create the application DF */
if (do_create_file(profile, profile->df_info.file))
if (sc_pkcs15init_create_file(profile, profile->df_info.file))
return 1;
/* Store CHV2 */
@ -247,6 +251,82 @@ gpk_init_app(struct sc_profile *profile, struct sc_card *card)
return 0;
}
/*
* Allocate a file
*/
static int
gpk_allocate_file(struct sc_profile *profile, struct sc_card *card,
unsigned int type, unsigned int num,
struct sc_file **out)
{
struct file_info *templ;
struct sc_file *file;
struct sc_path *p;
char name[64], *tag, *desc;
desc = tag = NULL;
while (1) {
switch (type) {
case SC_PKCS15_TYPE_PRKEY_RSA:
desc = "RSA private key";
tag = "private-key";
break;
case SC_PKCS15_TYPE_PUBKEY_RSA:
desc = "RSA public key";
tag = "public-key";
break;
#ifdef SC_PKCS15_TYPE_PRKEY_DSA
case SC_PKCS15_TYPE_PRKEY_RSA:
desc = "RSA private key";
tag = "data";
break;
case SC_PKCS15_TYPE_PUBKEY_RSA:
desc = "RSA public key";
tag = "data";
break;
#endif
case SC_PKCS15_TYPE_CERT:
desc = "certificate";
tag = "data";
break;
case SC_PKCS15_TYPE_DATA_OBJECT:
desc = "data object";
tag = "data";
break;
}
if (tag)
break;
/* If this is a specific type such as
* SC_PKCS15_TYPE_CERT_FOOBAR, fall back to
* the generic class (SC_PKCS15_TYPE_CERT)
*/
if (!(type & ~SC_PKCS15_TYPE_CLASS_MASK)) {
error("File type not supported by card driver");
return SC_ERROR_INVALID_ARGUMENTS;
}
type &= SC_PKCS15_TYPE_CLASS_MASK;
}
snprintf(name, sizeof(name), "template-%s", tag);
if (!(templ = sc_profile_find_file(profile, name))) {
error("Profile doesn't define %s template (%s)\n",
desc, name);
return SC_ERROR_NOT_SUPPORTED;
}
/* Now construct file from template */
sc_file_dup(&file, templ->file);
file->id += num;
p = &file->path;
*p = profile->df_info.file->path;
p->value[p->len++] = file->id >> 8;
p->value[p->len++] = file->id;
*out = file;
return 0;
}
/*
* GPK public/private key file handling is hideous.
* 600 lines of coke sweat and tears...
@ -282,7 +362,7 @@ gpk_pkfile_create(struct sc_profile *profile, struct sc_card *card,
r = sc_select_file(card, &file->path, &found);
card->ctx->log_errors = 1;
if (r == SC_ERROR_FILE_NOT_FOUND) {
r = do_create_file(profile, file);
r = sc_pkcs15init_create_file(profile, file);
if (r >= 0)
r = sc_select_file(card, &file->path, &found);
} else {
@ -290,7 +370,7 @@ gpk_pkfile_create(struct sc_profile *profile, struct sc_card *card,
}
if (r >= 0)
r = do_verify_authinfo(profile, file, SC_AC_OP_UPDATE);
r = sc_pkcs15init_authenticate(profile, file, SC_AC_OP_UPDATE);
if (found)
sc_file_free(found);
@ -761,14 +841,14 @@ gpk_store_pk(struct sc_profile *profile, struct sc_card *card,
*/
static int
gpk_store_rsa_key(struct sc_profile *profile, struct sc_card *card,
struct prkey_info *info, RSA *rsa)
struct sc_key_template *info, RSA *rsa)
{
struct pkdata data;
int r;
if ((r = gpk_encode_rsa_key(rsa, &data, info->pkcs15.usage)) < 0)
if ((r = gpk_encode_rsa_key(rsa, &data, info->pkcs15.priv.usage)) < 0)
return r;
return gpk_store_pk(profile, card, info->file->file, &data, info->key_acl);
return gpk_store_pk(profile, card, info->file, &data, info->key_acl);
}
/*
@ -776,14 +856,14 @@ gpk_store_rsa_key(struct sc_profile *profile, struct sc_card *card,
*/
static int
gpk_store_dsa_key(struct sc_profile *profile, struct sc_card *card,
struct prkey_info *info, DSA *dsa)
struct sc_key_template *info, DSA *dsa)
{
struct pkdata data;
int r;
if ((r = gpk_encode_dsa_key(dsa, &data, info->pkcs15.usage)) < 0)
if ((r = gpk_encode_dsa_key(dsa, &data, info->pkcs15.priv.usage)) < 0)
return r;
return gpk_store_pk(profile, card, info->file->file, &data, info->key_acl);
return gpk_store_pk(profile, card, info->file, &data, info->key_acl);
}
#ifdef notdef
@ -810,6 +890,7 @@ bind_gpk_operations(struct pkcs15_init_operations *ops)
{
ops->erase_card = gpk_erase_card;
ops->init_app = gpk_init_app;
ops->allocate_file = gpk_allocate_file;
ops->store_rsa = gpk_store_rsa_key;
ops->store_dsa = gpk_store_dsa_key;
}

File diff suppressed because it is too large Load Diff

View File

@ -7,23 +7,44 @@
#ifndef PKCS15_INIT_H
#define PKCS15_INIT_H
#include <openssl/evp.h>
#include "profile.h"
struct pkcs15_init_operations {
int (*erase_card)(struct sc_profile *, struct sc_card *);
int (*init_app)(struct sc_profile *, struct sc_card *);
int (*allocate_file)(struct sc_profile *, struct sc_card *,
unsigned int, unsigned int, struct sc_file **out);
int (*store_rsa)(struct sc_profile *, struct sc_card *,
struct prkey_info *, RSA *);
struct sc_key_template *, RSA *);
int (*store_dsa)(struct sc_profile *, struct sc_card *,
struct prkey_info *, DSA *);
struct sc_key_template *, DSA *);
};
extern int do_create_file(struct sc_profile *, struct sc_file *);
extern int do_create_and_update_file(struct sc_profile *,
struct sc_pkcs15init_keyargs {
struct sc_pkcs15_id id;
const char * label;
const char * template_name;
/* For key generation */
unsigned char onboard_keygen;
unsigned int algorithm;
unsigned int keybits;
EVP_PKEY * pkey;
};
extern int sc_pkcs15init_add_app(struct sc_card *,
struct sc_profile *);
extern int sc_pkcs15init_generate_key(struct sc_pkcs15_card *,
struct sc_profile *,
struct sc_pkcs15init_keyargs *);
extern int sc_pkcs15init_create_file(struct sc_profile *,
struct sc_file *);
extern int sc_pkcs15init_update_file(struct sc_profile *,
struct sc_file *, void *, unsigned int);
extern int do_select_parent(struct sc_profile *, struct sc_file *,
struct sc_file **);
extern int do_verify_authinfo(struct sc_profile *, struct sc_file *, int);
extern int sc_pkcs15init_authenticate(struct sc_profile *,
struct sc_file *, int);
/* Card specific stuff */
extern void bind_gpk_operations(struct pkcs15_init_operations *);

View File

@ -82,7 +82,8 @@ static int miocos_init_app(struct sc_profile *profile, struct sc_card *card)
*/
static int miocos_store_rsa_key(struct sc_profile *profile,
struct sc_card *card,
struct prkey_info *info, RSA *rsa)
struct sc_key_template *info,
RSA *rsa)
{
return 0;
}

76
src/tools/pkcs15.profile Normal file
View File

@ -0,0 +1,76 @@
#
# PKCS15 profile, generic information.
# This profile is loaded before any card specific profile.
#
# This is the DIR file
EF PKCS15-DIR
Path 3F002F00
Size 128
ACL *=NONE
# This is the application DF
DF
Path 3F005015
AID A0:00:00:00:63:50:4B:43:53:2D:31:35
ACL *=NONE
EF PKCS15-ODF
FileID 5031
Size 256
ACL *=NONE
EF PKCS15-TokenInfo
FileID 5032
ACL *=NONE
EF PKCS15-AODF
FileID 4401
Size 256
ACL *=NEVER READ=NONE UPDATE=CHV2
EF PKCS15-PrKDF
FileID 4402
Size 512
ACL *=NEVER READ=NONE UPDATE=CHV2
EF PKCS15-PuKDF
FileID 4403
Size 512
ACL *=NEVER READ=NONE UPDATE=CHV2
EF PKCS15-CDF
FileID 4404
Size 512
ACL *=NEVER READ=NONE UPDATE=CHV2
# Generic PIN information
PIN CHV1
Label "Authentication PIN"
AuthID 01
PIN CHV2
Label "Non-repudiation PIN"
AuthID 02
PrivateKey AuthKey
Label "Authentication Key"
ID 45
AuthID 01 # Requires CHV1
KeyUsage sign
PrivateKey SignKey
Label "Non-repudiation Key"
ID 46
AuthID 02 # Requires CHV2
KeyUsage NonRepudiation
PublicKey AuthKey
Label "Authentication Key"
ID 45
KeyUsage sign
PublicKey SignKey
Label "Non-repudiation Key"
ID 46
KeyUsage NonRepudiation

View File

@ -27,6 +27,10 @@
#include "util.h"
#include "profile.h"
#define DEF_PRKEY_RSA_ACCESS 0x1D
#define DEF_PRKEY_DSA_ACCESS 0x12
#define DEF_PUBKEY_ACCESS 0x12
struct command {
const char * name;
int section;
@ -42,17 +46,18 @@ enum {
PARSE_PRKEY,
PARSE_PUBKEY
};
static struct parser_info {
const char * filename;
unsigned int lineno;
struct sc_profile * profile;
int section;
struct file_info * cur_file;
struct pin_info * cur_pin;
struct prkey_info * cur_prkey;
struct pubkey_info * cur_pubkey;
} parser;
static struct file_info * cur_file;
static struct pin_info * cur_pin;
static struct sc_key_template * cur_key;
struct map {
const char * name;
unsigned int val;
@ -147,6 +152,7 @@ static struct map keyAccessFlags[] = {
{ 0, 0 }
};
static const char *sc_profile_locate(const char *);
static int process(int, char **);
static char * next_word(char **p);
static int get_authid(const char *, unsigned int *, unsigned int *);
@ -207,8 +213,8 @@ 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->rsa_access_flags = DEF_PRKEY_RSA_ACCESS;
pro->dsa_access_flags = DEF_PRKEY_DSA_ACCESS;
pro->pin_encoding = 0x01;
pro->pin_minlen = 4;
pro->pin_maxlen = 8;
@ -221,6 +227,8 @@ sc_profile_load(struct sc_profile *pro, const char *filename)
int res = 0;
FILE *fp;
if (!(filename = sc_profile_locate(filename)))
return 1;
if ((fp = fopen(filename, "r")) == NULL) {
perror(filename);
exit(1);
@ -249,6 +257,40 @@ sc_profile_load(struct sc_profile *pro, const char *filename)
return res;
}
static const char *
sc_profile_locate(const char *name)
{
static char path[1024];
/* Unchanged name? */
if (access(name, R_OK) == 0)
return name;
/* Name with suffix tagged onto it? */
snprintf(path, sizeof(path), "%s.%s", name, SC_PKCS15_PROFILE_SUFFIX);
if (access(path, R_OK) == 0)
return path;
/* If it's got slashes, don't mess with it any further */
if (strchr(path, '/'))
return path;
/* Try directory */
snprintf(path, sizeof(path), "%s/%s",
SC_PKCS15_PROFILE_DIRECTORY, name);
if (access(path, R_OK) == 0)
return path;
snprintf(path, sizeof(path), "%s/%s.%s",
SC_PKCS15_PROFILE_DIRECTORY, name,
SC_PKCS15_PROFILE_SUFFIX);
if (access(path, R_OK) == 0)
return path;
error("profile \"%s\" not found\n", name);
return NULL;
}
/*
* Fix up a file's ACL references
*/
@ -314,7 +356,6 @@ sc_profile_finish(struct sc_profile *pro)
{
struct file_info *fi;
struct pin_info *pi;
struct prkey_info *pk;
int res = 0;
/* Loop over all PINs and make sure they're sane */
@ -337,55 +378,17 @@ sc_profile_finish(struct sc_profile *pro)
fix_file_acls(pro, pro->mf_info.file);
fix_file_acls(pro, pro->df_info.file);
/* Make sure all private keys are sane */
for (pk = pro->prkey_list; pk; pk = pk->next) {
struct sc_pkcs15_id *id;
if (!pk->file) {
error("No File given for private key %s", pk->ident);
res = 1;
}
if (!pk->pkcs15_obj.auth_id.len) {
error("No auth_id set for private key %s", pk->ident);
res = 1;
}
if (!pk->pkcs15.id.len) {
error("No key ID set for private key %s", pk->ident);
res = 1;
}
if (!pk->pkcs15.usage) {
error("No keyUsage specified for private key %s",
pk->ident);
res = 1;
}
pk->pkcs15.path = pk->file->file->path;
/* Set up the key ACL */
id = &pk->pkcs15_obj.auth_id;
for (pi = pro->pin_list; pi; pi = pi->next) {
if (sc_pkcs15_compare_id(&pi->pkcs15.auth_id, id) == 1)
break;
}
if (pi == NULL) {
error("Invalid or no AuthID on private key %s",
pk->ident);
res = 1;
}
pk->key_acl = calloc(1, sizeof(struct sc_acl_entry));
pk->key_acl->method = SC_AC_CHV;
pk->key_acl->key_ref = pi->pkcs15.reference;
}
return res;
}
#if 0
int
sc_profile_build_pkcs15(struct sc_profile *pro)
{
struct sc_pkcs15_card *p15card;
struct pin_info *pi;
struct prkey_info *prk;
struct pubkey_info *puk;
struct sc_key_template *prk;
struct sc_key_template *puk;
int res = 0;
p15card = pro->p15_card;
@ -434,12 +437,13 @@ sc_profile_build_pkcs15(struct sc_profile *pro)
return res;
}
#endif
static int
do_cardinfo(int argc, char **argv)
{
parser.section = PARSE_CARDINFO;
parser.cur_file = NULL;
cur_file = NULL;
return 0;
}
@ -546,8 +550,8 @@ static int
do_mf(int argc, char **argv)
{
parser.section = PARSE_FILE;
parser.cur_file = &parser.profile->mf_info;
parser.cur_file->ident = strdup("MF");
cur_file = &parser.profile->mf_info;
cur_file->ident = strdup("MF");
return 0;
}
@ -555,8 +559,8 @@ static int
do_df(int argc, char **argv)
{
parser.section = PARSE_FILE;
parser.cur_file = &parser.profile->df_info;
parser.cur_file->ident = strdup("App DF");
cur_file = &parser.profile->df_info;
cur_file->ident = strdup("App DF");
return 0;
}
@ -594,20 +598,11 @@ do_ef(int argc, char **argv)
file = init_file(SC_FILE_TYPE_WORKING_EF);
#endif
} else {
struct sc_pkcs15_df *df;
if (map_str2int(name+7, &df_type, pkcs15DfNames))
return 1;
df = &pro->p15_card->df[df_type];
if (df->count >= SC_PKCS15_MAX_DFS) {
parse_error("Too many EF(%s) files\n", name + 7);
return 1;
}
info->pkcs15.type = df_type;
info->pkcs15.fileno = df->count;
file = (struct sc_file *) calloc(1, sizeof(*file));
df->file[df->count++] = file;
pro->df[df_type] = file;
}
assert(file);
@ -619,14 +614,14 @@ do_ef(int argc, char **argv)
info->next = parser.profile->ef_list;
parser.profile->ef_list = info;
out: parser.cur_file = info;
out: cur_file = info;
return 0;
}
static int
do_path(int argc, char **argv)
{
struct sc_file *file = parser.cur_file->file;
struct sc_file *file = cur_file->file;
struct sc_path *path = &file->path;
/* sc_format_path doesn't return an error indication
@ -641,6 +636,38 @@ do_path(int argc, char **argv)
return 0;
}
static int
do_fileid(int argc, char **argv)
{
struct sc_profile *profile = parser.profile;
struct sc_file *file = cur_file->file,
*df = profile->df_info.file;
struct sc_path temp, *path = &file->path;
/* sc_format_path doesn't return an error indication
* when it's unable to parse the path */
sc_format_path(argv[0], &temp);
if (temp.len != 2) {
parse_error("Invalid file ID length\n");
return 1;
}
if (df->path.len == 0) {
parse_error("No path set for Application DF\n");
return 1;
}
if (df->path.len + 2 > sizeof(df->path)) {
parse_error("File path too long\n");
return 1;
}
*path = df->path;
memcpy(path->value + path->len, temp.value, 2);
path->len += 2;
file->id = (path->value[path->len-2] << 8)
| path->value[path->len-1];
return 0;
}
static int
do_structure(int argc, char **argv)
{
@ -648,7 +675,7 @@ do_structure(int argc, char **argv)
if (map_str2int(argv[0], &ef_structure, efTypeNames))
return 1;
parser.cur_file->file->ef_structure = ef_structure;
cur_file->file->ef_structure = ef_structure;
return 0;
}
@ -659,7 +686,7 @@ do_size(int argc, char **argv)
if (get_uint(argv[0], &size))
return 1;
parser.cur_file->file->size = size;
cur_file->file->size = size;
return 0;
}
@ -670,14 +697,14 @@ do_reclength(int argc, char **argv)
if (get_uint(argv[0], &reclength))
return 1;
parser.cur_file->file->record_length = reclength;
cur_file->file->record_length = reclength;
return 0;
}
static int
do_aid(int argc, char **argv)
{
struct sc_file *file = parser.cur_file->file;
struct sc_file *file = cur_file->file;
const char *name = argv[0];
unsigned int len;
int res = 0;
@ -708,7 +735,7 @@ do_aid(int argc, char **argv)
static int
do_acl(int argc, char **argv)
{
struct sc_file *file = parser.cur_file->file;
struct sc_file *file = cur_file->file;
char *oper = 0, *what = 0;
while (argc--) {
@ -765,8 +792,7 @@ do_pin(int argc, char **argv)
return 1;
}
pi = (struct pin_info *) malloc(sizeof(*pi));
memset(pi, 0, sizeof(*pi));
pi = (struct pin_info *) calloc(1, sizeof(*pi));
pi->ident = strdup(name);
pi->id = id;
pi->attempt[0] = 2;
@ -785,7 +811,7 @@ do_pin(int argc, char **argv)
;
*tail = pi;
out: parser.cur_pin = pi;
out: cur_pin = pi;
return 0;
}
@ -799,20 +825,20 @@ do_pin_file(int argc, char **argv)
parse_error("unknown PIN file \"%s\"\n", name);
return 1;
}
parser.cur_pin->file = fi;
cur_pin->file = fi;
return 0;
}
static int
do_pin_offset(int argc, char **argv)
{
return get_uint(argv[0], &parser.cur_pin->file_offset);
return get_uint(argv[0], &cur_pin->file_offset);
}
static int
do_pin_attempts(int argc, char **argv)
{
struct pin_info *pi = parser.cur_pin;
struct pin_info *pi = cur_pin;
int i;
memset(pi->attempt, 0, sizeof(pi->attempt));
@ -830,7 +856,7 @@ do_pin_type(int argc, char **argv)
if (map_str2int(argv[0], &type, pinTypeNames))
return 1;
parser.cur_pin->pkcs15.type = type;
cur_pin->pkcs15.type = type;
return 0;
}
@ -841,21 +867,21 @@ do_pin_reference(int argc, char **argv)
if (get_uint(argv[0], &reference))
return 1;
parser.cur_pin->pkcs15.reference = reference;
cur_pin->pkcs15.reference = reference;
return 0;
}
static int
do_pin_authid(int argc, char **argv)
{
sc_pkcs15_format_id(argv[0], &parser.cur_pin->pkcs15.auth_id);
sc_pkcs15_format_id(argv[0], &cur_pin->pkcs15.auth_id);
return 0;
}
static int
do_pin_label(int argc, char **argv)
{
strcpy(parser.cur_pin->pkcs15_obj.label, argv[0]);
strcpy(cur_pin->pkcs15_obj.label, argv[0]);
return 0;
}
@ -863,9 +889,9 @@ static int
do_prkey(int argc, char **argv)
{
struct sc_profile *pro = parser.profile;
struct prkey_info *ki, **tail;
struct sc_key_template *ki, **tail;
if ((ki = sc_profile_find_prkey(pro, argv[0])) != NULL)
if ((ki = sc_profile_find_private_key(pro, argv[0])) != NULL)
goto out;
ki = calloc(1, sizeof(*ki));
@ -875,8 +901,8 @@ do_prkey(int argc, char **argv)
* 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.priv.modulus_length = 1024;
ki->pkcs15.priv.access_flags = pro->rsa_access_flags;
ki->pkcs15_obj.type = SC_PKCS15_TYPE_PRKEY_RSA;
ki->pkcs15_obj.data = &ki->pkcs15;
@ -885,8 +911,8 @@ do_prkey(int argc, char **argv)
;
*tail = ki;
out: parser.cur_prkey = ki;
parser.section = PARSE_PRKEY;
out: parser.section = PARSE_PRKEY;
cur_key = ki;
return 0;
}
@ -900,30 +926,30 @@ do_prkey_file(int argc, char **argv)
parse_error("unknown private key file \"%s\"\n", name);
return 1;
}
parser.cur_prkey->file = fi;
cur_key->file = fi->file;
return 0;
}
static int
do_prkey_index(int argc, char **argv)
{
return get_uint(argv[0], &parser.cur_prkey->index);
return get_uint(argv[0], &cur_key->index);
}
static int
do_prkey_algorithm(int argc, char **argv)
{
struct prkey_info *ki = parser.cur_prkey;
struct sc_key_template *ki = cur_key;
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;
ki->pkcs15.priv.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;
ki->pkcs15.priv.access_flags = parser.profile->dsa_access_flags;
break;
#endif
}
@ -933,28 +959,28 @@ do_prkey_algorithm(int argc, char **argv)
static int
do_prkey_label(int argc, char **argv)
{
strcpy(parser.cur_prkey->pkcs15_obj.label, argv[0]);
strcpy(cur_key->pkcs15_obj.label, argv[0]);
return 0;
}
static int
do_prkey_id(int argc, char **argv)
{
sc_pkcs15_format_id(argv[0], &parser.cur_prkey->pkcs15.id);
sc_pkcs15_format_id(argv[0], &cur_key->pkcs15.priv.id);
return 0;
}
static int
do_prkey_authid(int argc, char **argv)
{
sc_pkcs15_format_id(argv[0], &parser.cur_prkey->pkcs15_obj.auth_id);
sc_pkcs15_format_id(argv[0], &cur_key->pkcs15_obj.auth_id);
return 0;
}
static int
do_prkey_usage(int argc, char **argv)
{
struct sc_pkcs15_prkey_info *ki = &parser.cur_prkey->pkcs15;
struct sc_pkcs15_prkey_info *ki = &cur_key->pkcs15.priv;
if (map_str2int(argv[0], &ki->usage, keyUsageNames)) {
parse_error("Bad key usage \"%s\"", argv[0]);
@ -966,7 +992,7 @@ do_prkey_usage(int argc, char **argv)
static int
do_prkey_access_flags(int argc, char **argv)
{
struct sc_pkcs15_prkey_info *ki = &parser.cur_prkey->pkcs15;
struct sc_pkcs15_prkey_info *ki = &cur_key->pkcs15.priv;
unsigned int access;
ki->access_flags = 0;
@ -981,7 +1007,7 @@ do_prkey_access_flags(int argc, char **argv)
static int
do_prkey_reference(int argc, char **argv)
{
struct sc_pkcs15_prkey_info *ki = &parser.cur_prkey->pkcs15;
struct sc_pkcs15_prkey_info *ki = &cur_key->pkcs15.priv;
return get_uint(argv[0], (unsigned int *) &ki->key_reference);
}
@ -990,9 +1016,9 @@ static int
do_pubkey(int argc, char **argv)
{
struct sc_profile *pro = parser.profile;
struct pubkey_info *ki, **tail;
struct sc_key_template *ki, **tail;
if ((ki = sc_profile_find_pubkey(pro, argv[0])) != NULL)
if ((ki = sc_profile_find_public_key(pro, argv[0])) != NULL)
goto out;
ki = calloc(1, sizeof(*ki));
@ -1002,8 +1028,8 @@ do_pubkey(int argc, char **argv)
* 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.pub.modulus_length = 1024;
ki->pkcs15.pub.access_flags = pro->rsa_access_flags;
ki->pkcs15_obj.type = SC_PKCS15_TYPE_PRKEY_RSA;
ki->pkcs15_obj.data = &ki->pkcs15;
@ -1012,7 +1038,7 @@ do_pubkey(int argc, char **argv)
;
*tail = ki;
out: parser.cur_pubkey = ki;
out: cur_key = ki;
parser.section = PARSE_PUBKEY;
return 0;
}
@ -1027,61 +1053,52 @@ do_pubkey_file(int argc, char **argv)
parse_error("unknown private key file \"%s\"\n", name);
return 1;
}
parser.cur_pubkey->file = fi;
cur_key->file = fi->file;
return 0;
}
static int
do_pubkey_index(int argc, char **argv)
{
return get_uint(argv[0], &parser.cur_pubkey->index);
return get_uint(argv[0], &cur_key->index);
}
static int
do_pubkey_algorithm(int argc, char **argv)
{
struct pubkey_info *ki = parser.cur_pubkey;
struct sc_key_template *ki = cur_key;
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
}
ki->pkcs15.pub.access_flags = DEF_PUBKEY_ACCESS;
return 0;
}
static int
do_pubkey_label(int argc, char **argv)
{
strcpy(parser.cur_pubkey->pkcs15_obj.label, argv[0]);
strcpy(cur_key->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);
sc_pkcs15_format_id(argv[0], &cur_key->pkcs15.pub.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);
sc_pkcs15_format_id(argv[0], &cur_key->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;
struct sc_pkcs15_pubkey_info *ki = &cur_key->pkcs15.pub;
if (map_str2int(argv[0], &ki->usage, keyUsageNames)) {
parse_error("Bad key usage \"%s\"", argv[0]);
@ -1093,7 +1110,7 @@ do_pubkey_usage(int argc, char **argv)
static int
do_pubkey_access_flags(int argc, char **argv)
{
struct sc_pkcs15_pubkey_info *ki = &parser.cur_pubkey->pkcs15;
struct sc_pkcs15_pubkey_info *ki = &cur_key->pkcs15.pub;
unsigned int access;
ki->access_flags = 0;
@ -1108,7 +1125,7 @@ do_pubkey_access_flags(int argc, char **argv)
static int
do_pubkey_reference(int argc, char **argv)
{
struct sc_pkcs15_pubkey_info *ki = &parser.cur_pubkey->pkcs15;
struct sc_pkcs15_pubkey_info *ki = &cur_key->pkcs15.pub;
return get_uint(argv[0], (unsigned int *) &ki->key_reference);
}
@ -1127,6 +1144,7 @@ static struct command commands[] = {
{ "DF", -1, 0, 0, do_df },
{ "EF", -1, 1, 1, do_ef },
{ "Path", PARSE_FILE, 1, 1, do_path },
{ "FileID", PARSE_FILE, 1, 1, do_fileid },
{ "Structure", PARSE_FILE, 1, 1, do_structure },
{ "Size", PARSE_FILE, 1, 1, do_size },
{ "RecordLength", PARSE_FILE, 1, 1, do_reclength },
@ -1256,10 +1274,10 @@ sc_profile_find_key(struct sc_profile *pro,
return NULL;
}
struct prkey_info *
sc_profile_find_prkey(struct sc_profile *pro, const char *ident)
struct sc_key_template *
sc_profile_find_private_key(struct sc_profile *pro, const char *ident)
{
struct prkey_info *ki;
struct sc_key_template *ki;
for (ki = pro->prkey_list; ki; ki = ki->next) {
if (!strcasecmp(ki->ident, ident))
@ -1268,10 +1286,10 @@ 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 sc_key_template *
sc_profile_find_public_key(struct sc_profile *pro, const char *ident)
{
struct pubkey_info *ki;
struct sc_key_template *ki;
for (ki = pro->pubkey_list; ki; ki = ki->next) {
if (!strcasecmp(ki->ident, ident))

View File

@ -11,6 +11,13 @@
#include <openssl/dsa.h>
#include "opensc-pkcs15.h"
#ifndef SC_PKCS15_PROFILE_DIRECTORY
#define SC_PKCS15_PROFILE_DIRECTORY "/usr/lib/opensc/profiles"
#endif
#ifndef SC_PKCS15_PROFILE_SUFFIX
#define SC_PKCS15_PROFILE_SUFFIX "profile"
#endif
struct auth_info {
struct auth_info * next;
unsigned int type; /* CHV, AUT, PRO */
@ -26,10 +33,12 @@ struct file_info {
struct sc_file * file;
/* PKCS15 book-keeping info */
/*
struct {
unsigned int fileno;
unsigned int type;
} pkcs15;
*/
};
/* For now, we assume the PUK always resides
@ -50,37 +59,34 @@ struct pin_info {
char * secret[2];
};
struct prkey_info {
struct sc_key_template {
char * ident;
struct prkey_info * next;
struct file_info * file;
struct sc_key_template *next;
//struct file_info * file;
struct sc_file * file;
unsigned int index; /* translates to file offset */
struct sc_acl_entry * key_acl;/* PINs for key usage */
struct sc_pkcs15_object pkcs15_obj;
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;
union {
struct sc_pkcs15_prkey_info priv;
struct sc_pkcs15_pubkey_info pub;
} pkcs15;
};
struct sc_profile {
char * driver;
struct pkcs15_init_operations *ops;
struct file_info mf_info;
struct file_info df_info;
struct file_info * ef_list;
struct sc_file * df[SC_PKCS15_DF_TYPE_COUNT];
struct pin_info * pin_list;
struct auth_info * auth_list;
struct prkey_info * prkey_list;
struct pubkey_info * pubkey_list;
struct sc_key_template *prkey_list;
struct sc_key_template *pubkey_list;
unsigned int pin_maxlen;
unsigned int pin_minlen;
@ -103,8 +109,9 @@ int sc_profile_build_pkcs15(struct sc_profile *);
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 sc_key_template *sc_profile_find_private_key(struct sc_profile *,
const char *);
struct sc_key_template *sc_profile_find_public_key(struct sc_profile *, const char *);
struct auth_info *sc_profile_find_key(struct sc_profile *,
unsigned int, unsigned int);