- improved PKCS #15 generation
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@170 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
ee55164f07
commit
54e5d23e93
|
@ -397,7 +397,7 @@ static int encode_file_structure(struct sc_card *card, const struct sc_file *fil
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int flex_create_file(struct sc_card *card, const struct sc_file *file)
|
||||
static int flex_create_file(struct sc_card *card, struct sc_file *file)
|
||||
{
|
||||
u8 sbuf[18];
|
||||
size_t sendlen;
|
||||
|
|
|
@ -71,9 +71,9 @@ static int setec_init(struct sc_card *card)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int (*iso_create_file)(struct sc_card *card, const struct sc_file *file) = NULL;
|
||||
static int (*iso_create_file)(struct sc_card *card, struct sc_file *file) = NULL;
|
||||
|
||||
static int setec_create_file(struct sc_card *card, const struct sc_file *file)
|
||||
static int setec_create_file(struct sc_card *card, struct sc_file *file)
|
||||
{
|
||||
struct sc_file tmp;
|
||||
|
||||
|
|
|
@ -518,7 +518,7 @@ int sc_list_files(struct sc_card *card, u8 *buf, size_t buflen)
|
|||
SC_FUNC_RETURN(card->ctx, 1, r);
|
||||
}
|
||||
|
||||
int sc_create_file(struct sc_card *card, const struct sc_file *file)
|
||||
int sc_create_file(struct sc_card *card, struct sc_file *file)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
|
|
@ -444,7 +444,7 @@ static int construct_fci(const struct sc_file *file, u8 *out, size_t *outlen)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int iso7816_create_file(struct sc_card *card, const struct sc_file *file)
|
||||
static int iso7816_create_file(struct sc_card *card, struct sc_file *file)
|
||||
{
|
||||
int r;
|
||||
size_t len;
|
||||
|
|
|
@ -176,5 +176,5 @@ void sc_hex_dump(struct sc_context *ctx, const u8 *in, size_t count,
|
|||
|
||||
void sc_perror(struct sc_context *ctx, int error, const char *str)
|
||||
{
|
||||
error(ctx, "%s: %s\n", sc_strerror(error), str);
|
||||
error(ctx, "%s: %s\n", str, sc_strerror(error));
|
||||
}
|
||||
|
|
|
@ -248,6 +248,7 @@ int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card,
|
|||
int sc_pkcs15_create_cdf(struct sc_pkcs15_card *card,
|
||||
struct sc_file *file,
|
||||
const struct sc_pkcs15_cert_info **certs);
|
||||
int sc_pkcs15_create(struct sc_pkcs15_card *p15card, struct sc_card *card);
|
||||
|
||||
void sc_pkcs15_print_prkey_info(const struct sc_pkcs15_prkey_info *prkey);
|
||||
int sc_pkcs15_enum_private_keys(struct sc_pkcs15_card *card);
|
||||
|
@ -280,7 +281,8 @@ int sc_pkcs15_compare_id(const struct sc_pkcs15_id *id1,
|
|||
void sc_pkcs15_print_id(const struct sc_pkcs15_id *id);
|
||||
int sc_pkcs15_hex_string_to_id(const char *in, struct sc_pkcs15_id *out);
|
||||
int sc_pkcs15_add_object(struct sc_context *ctx, struct sc_pkcs15_df *df,
|
||||
int file_nr, struct sc_pkcs15_object *new_obj);
|
||||
int file_nr, int obj_type, const void *data,
|
||||
size_t data_size);
|
||||
extern const struct sc_pkcs15_defaults sc_pkcs15_card_table[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -323,7 +323,7 @@ struct sc_card_operations {
|
|||
/*
|
||||
* ISO 7816-9 functions
|
||||
*/
|
||||
int (*create_file)(struct sc_card *card, const struct sc_file *file);
|
||||
int (*create_file)(struct sc_card *card, struct sc_file *file);
|
||||
int (*delete_file)(struct sc_card *card, const struct sc_path *path);
|
||||
/* list_files: Enumerates all the files in the current DF, and
|
||||
* writes the corresponding file identifiers to <buf>. Returns
|
||||
|
@ -489,7 +489,7 @@ int sc_reset_retry_counter(struct sc_card *card, int ref, const u8 *puk,
|
|||
size_t puklen, const u8 *newref, size_t newlen);
|
||||
|
||||
/* ISO 7816-9 */
|
||||
int sc_create_file(struct sc_card *card, const struct sc_file *file);
|
||||
int sc_create_file(struct sc_card *card, struct sc_file *file);
|
||||
int sc_delete_file(struct sc_card *card, const struct sc_path *path);
|
||||
|
||||
inline int sc_file_valid(const struct sc_file *file);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* pkcs15-cert.c: PKCS#15 certificate functions
|
||||
* pkcs15-cert.c: PKCS #15 certificate functions
|
||||
*
|
||||
* Copyright (C) 2001 Juha Yrjölä <juha.yrjola@iki.fi>
|
||||
*
|
||||
|
@ -403,8 +403,7 @@ static int get_certs_from_file(struct sc_pkcs15_card *p15card,
|
|||
return r;
|
||||
bytes_left = r;
|
||||
do {
|
||||
struct sc_pkcs15_cert_info info, *infop;
|
||||
struct sc_pkcs15_object *objp;
|
||||
struct sc_pkcs15_cert_info info;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
r = parse_x509_cert_info(p15card->card->ctx,
|
||||
|
@ -413,23 +412,11 @@ static int get_certs_from_file(struct sc_pkcs15_card *p15card,
|
|||
break;
|
||||
if (r)
|
||||
return r;
|
||||
infop = malloc(sizeof(info));
|
||||
if (infop == NULL)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
memcpy(infop, &info, sizeof(info));
|
||||
objp = malloc(sizeof(struct sc_pkcs15_object));
|
||||
if (objp == NULL) {
|
||||
free(infop);
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
objp->type = SC_PKCS15_TYPE_CERT_X509;
|
||||
objp->data = infop;
|
||||
r = sc_pkcs15_add_object(p15card->card->ctx, df, file_nr, objp);
|
||||
if (r) {
|
||||
free(infop);
|
||||
free(objp);
|
||||
r = sc_pkcs15_add_object(p15card->card->ctx, df, file_nr,
|
||||
SC_PKCS15_TYPE_CERT_X509,
|
||||
&info, sizeof(info));
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
if (p15card->cert_count >= SC_PKCS15_MAX_PRKEYS)
|
||||
break;
|
||||
p15card->cert_info[p15card->cert_count] = info;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* pkcs15-prkey.c: PKCS#15 private key functions
|
||||
* pkcs15-prkey.c: PKCS #15 private key functions
|
||||
*
|
||||
* Copyright (C) 2001 Juha Yrjölä <juha.yrjola@iki.fi>
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* pkcs15.c: PKCS#15 general functions
|
||||
* pkcs15.c: PKCS #15 general functions
|
||||
*
|
||||
* Copyright (C) 2001 Juha Yrjölä <juha.yrjola@iki.fi>
|
||||
*
|
||||
|
@ -128,7 +128,9 @@ err:
|
|||
return;
|
||||
}
|
||||
|
||||
int encode_tokeninfo(struct sc_context *ctx, struct sc_pkcs15_card *card, u8 ** buf, size_t *buflen)
|
||||
int sc_pkcs15_encode_tokeninfo(struct sc_context *ctx,
|
||||
struct sc_pkcs15_card *card,
|
||||
u8 **buf, size_t *buflen)
|
||||
{
|
||||
int i, r;
|
||||
u8 serial[128];
|
||||
|
@ -178,23 +180,6 @@ int encode_tokeninfo(struct sc_context *ctx, struct sc_pkcs15_card *card, u8 **
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sc_pkcs15_create_tokeninfo(struct sc_card *card, struct sc_pkcs15_card *p15card)
|
||||
{
|
||||
int r;
|
||||
u8 *buf;
|
||||
size_t buflen;
|
||||
char line[10240];
|
||||
|
||||
r = encode_tokeninfo(card->ctx, p15card, &buf, &buflen);
|
||||
if (r) {
|
||||
error(card->ctx, "Error encoding EF(TokenInfo): %s\n", sc_strerror(r));
|
||||
return r;
|
||||
}
|
||||
sc_hex_dump(card->ctx, buf, buflen, line, sizeof(line));
|
||||
printf("%s\n", line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sc_asn1_entry c_asn1_ddo[] = {
|
||||
{ "oid", SC_ASN1_OBJECT, ASN1_OBJECT, 0, NULL },
|
||||
{ "odfPath", SC_ASN1_PATH, SC_ASN1_CONS | ASN1_SEQUENCE, SC_ASN1_OPTIONAL, NULL },
|
||||
|
@ -298,7 +283,7 @@ static int encode_dir(struct sc_context *ctx, struct sc_pkcs15_card *card, u8 **
|
|||
|
||||
/* FIXME: This should be done using sc_update_binary(),
|
||||
* and be generally wiser */
|
||||
int sc_pkcs15_create_dir(struct sc_card *card, struct sc_pkcs15_card *p15card)
|
||||
int sc_pkcs15_create_dir(struct sc_pkcs15_card *p15card, struct sc_card *card)
|
||||
{
|
||||
struct sc_path path;
|
||||
u8 *buf;
|
||||
|
@ -314,7 +299,7 @@ int sc_pkcs15_create_dir(struct sc_card *card, struct sc_pkcs15_card *p15card)
|
|||
SC_TEST_RET(card->ctx, r, "EF(DIR) encoding failed");
|
||||
sc_hex_dump(card->ctx, buf, bufsize, line, sizeof(line));
|
||||
free(buf);
|
||||
printf("%s", line);
|
||||
printf("DIR:\n%s", line);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -376,8 +361,9 @@ static int parse_odf(const u8 * buf, int buflen, struct sc_pkcs15_card *card)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int encode_odf(struct sc_context *ctx, struct sc_pkcs15_card *card,
|
||||
u8 **buf, size_t *buflen)
|
||||
static int sc_pkcs15_encode_odf(struct sc_context *ctx,
|
||||
struct sc_pkcs15_card *card,
|
||||
u8 **buf, size_t *buflen)
|
||||
{
|
||||
struct sc_path path;
|
||||
struct sc_asn1_entry asn1_obj_or_path[] = {
|
||||
|
@ -391,6 +377,10 @@ static int encode_odf(struct sc_context *ctx, struct sc_pkcs15_card *card,
|
|||
|
||||
for (i = 0; i < SC_PKCS15_DF_TYPE_COUNT; i++)
|
||||
df_count += card->df[i].count;
|
||||
if (df_count == 0) {
|
||||
error(ctx, "No DF's found.\n");
|
||||
return SC_ERROR_OBJECT_NOT_FOUND;
|
||||
}
|
||||
asn1_odf = malloc(sizeof(struct sc_asn1_entry) * (df_count + 1));
|
||||
if (asn1_odf == NULL) {
|
||||
r = SC_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -434,20 +424,6 @@ err:
|
|||
return r;
|
||||
}
|
||||
|
||||
int sc_pkcs15_create_odf(struct sc_card *card, struct sc_pkcs15_card *p15card)
|
||||
{
|
||||
u8 *buf;
|
||||
size_t buflen;
|
||||
char line[10240];
|
||||
int r;
|
||||
|
||||
r = encode_odf(card->ctx, p15card, &buf, &buflen);
|
||||
SC_TEST_RET(card->ctx, r, "ODF encoding failed");
|
||||
sc_hex_dump(card->ctx, buf, buflen, line, sizeof(line));
|
||||
printf("ODF:\n%s", line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sc_pkcs15_defaults * find_defaults(u8 *dir, int dirlen)
|
||||
{
|
||||
/* FIXME: CODEME */
|
||||
|
@ -619,18 +595,31 @@ int sc_pkcs15_unbind(struct sc_pkcs15_card *p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15_add_object(struct sc_context *ctx, struct sc_pkcs15_df *df,
|
||||
int file_nr, struct sc_pkcs15_object *obj)
|
||||
int file_nr, int obj_type, const void *data,
|
||||
size_t data_size)
|
||||
{
|
||||
struct sc_pkcs15_object *p = df->obj[file_nr];
|
||||
struct sc_pkcs15_object *newobj;
|
||||
|
||||
newobj = malloc(sizeof(struct sc_pkcs15_object));
|
||||
if (newobj == NULL)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
newobj->next = NULL;
|
||||
newobj->type = obj_type;
|
||||
newobj->data = malloc(data_size);
|
||||
if (newobj->data == NULL) {
|
||||
free(newobj);
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(newobj->data, data, data_size);
|
||||
|
||||
obj->next = NULL;
|
||||
if (p == NULL) {
|
||||
df->obj[file_nr] = obj;
|
||||
df->obj[file_nr] = newobj;
|
||||
return 0;
|
||||
}
|
||||
while (p->next != NULL)
|
||||
p = p->next;
|
||||
p->next = obj;
|
||||
p->next = newobj;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -644,7 +633,6 @@ int sc_pkcs15_encode_df(struct sc_pkcs15_card *p15card,
|
|||
size_t bufsize = 0, tmpsize;
|
||||
int r;
|
||||
const struct sc_pkcs15_object *obj = df->obj[file_no];
|
||||
char str[10240];
|
||||
int (* func)(struct sc_pkcs15_card *, const struct sc_pkcs15_object *obj,
|
||||
u8 **buf, size_t *bufsize) = NULL;
|
||||
switch (df->type) {
|
||||
|
@ -671,14 +659,66 @@ int sc_pkcs15_encode_df(struct sc_pkcs15_card *p15card,
|
|||
bufsize += tmpsize;
|
||||
obj = obj->next;
|
||||
}
|
||||
sc_hex_dump(p15card->card->ctx, buf, bufsize, str, sizeof(str));
|
||||
printf("DF:\n%s\n", str);
|
||||
*buf_out = buf;
|
||||
*bufsize_out = bufsize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sc_pkcs15_create(struct sc_pkcs15_card *p15card, struct sc_card *card)
|
||||
{
|
||||
int r, i;
|
||||
u8 *tokinf_buf = NULL, *odf_buf = NULL;
|
||||
size_t tokinf_size, odf_size;
|
||||
u8 line[10240];
|
||||
|
||||
r = sc_pkcs15_create_dir(p15card, card);
|
||||
SC_TEST_RET(card->ctx, r, "Error creating EF(DIR)\n");
|
||||
printf("Creating app DF\n");
|
||||
r = sc_pkcs15_encode_tokeninfo(card->ctx, p15card, &tokinf_buf, &tokinf_size);
|
||||
if (r) {
|
||||
sc_perror(card->ctx, r, "Error creating EF(TokenInfo)");
|
||||
goto err;
|
||||
}
|
||||
sc_hex_dump(card->ctx, tokinf_buf, tokinf_size, line, sizeof(line));
|
||||
printf("TokenInfo:\n%s\n", line);
|
||||
r = sc_pkcs15_encode_odf(card->ctx, p15card, &odf_buf, &odf_size);
|
||||
if (r) {
|
||||
sc_perror(card->ctx, r, "Error creating EF(ODF)");
|
||||
goto err;
|
||||
}
|
||||
sc_hex_dump(card->ctx, odf_buf, odf_size, line, sizeof(line));
|
||||
printf("ODF:\n%s\n", line);
|
||||
for (i = 0; i < SC_PKCS15_DF_TYPE_COUNT; i++) {
|
||||
struct sc_pkcs15_df *df = &p15card->df[i];
|
||||
int file_no;
|
||||
u8 *buf;
|
||||
size_t bufsize;
|
||||
|
||||
if (df->count == 0)
|
||||
continue;
|
||||
for (file_no = 0; file_no < df->count; file_no++) {
|
||||
r = sc_pkcs15_encode_df(p15card, df, file_no, &buf, &bufsize);
|
||||
if (r) {
|
||||
sc_perror(card->ctx, r, "Error encoding EF(xDF)");
|
||||
goto err;
|
||||
}
|
||||
if (buf != NULL) {
|
||||
sc_hex_dump(card->ctx, buf, bufsize, line, sizeof(line));
|
||||
printf("DF %d, file %d:\n%s\n", i, file_no, line);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
if (tokinf_buf)
|
||||
free(tokinf_buf);
|
||||
if (odf_buf)
|
||||
free(odf_buf);
|
||||
return r;
|
||||
}
|
||||
|
||||
int sc_pkcs15_compare_id(const struct sc_pkcs15_id *id1,
|
||||
const struct sc_pkcs15_id *id2)
|
||||
{
|
||||
|
|
|
@ -248,6 +248,7 @@ int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card,
|
|||
int sc_pkcs15_create_cdf(struct sc_pkcs15_card *card,
|
||||
struct sc_file *file,
|
||||
const struct sc_pkcs15_cert_info **certs);
|
||||
int sc_pkcs15_create(struct sc_pkcs15_card *p15card, struct sc_card *card);
|
||||
|
||||
void sc_pkcs15_print_prkey_info(const struct sc_pkcs15_prkey_info *prkey);
|
||||
int sc_pkcs15_enum_private_keys(struct sc_pkcs15_card *card);
|
||||
|
@ -280,7 +281,8 @@ int sc_pkcs15_compare_id(const struct sc_pkcs15_id *id1,
|
|||
void sc_pkcs15_print_id(const struct sc_pkcs15_id *id);
|
||||
int sc_pkcs15_hex_string_to_id(const char *in, struct sc_pkcs15_id *out);
|
||||
int sc_pkcs15_add_object(struct sc_context *ctx, struct sc_pkcs15_df *df,
|
||||
int file_nr, struct sc_pkcs15_object *new_obj);
|
||||
int file_nr, int obj_type, const void *data,
|
||||
size_t data_size);
|
||||
extern const struct sc_pkcs15_defaults sc_pkcs15_card_table[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -37,11 +37,14 @@ int sc_decipher(struct sc_card *card,
|
|||
if (crgram_len > 255)
|
||||
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
/* INS: 0x2A PERFORM SECURITY OPERATION
|
||||
* P1: 0x80 Resp: Plain value
|
||||
* P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x80, 0x86);
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof(rbuf); /* FIXME */
|
||||
|
||||
sbuf[0] = 0; /* padding indicator byte */ ;
|
||||
sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
|
||||
memcpy(sbuf + 1, crgram, crgram_len);
|
||||
apdu.data = sbuf;
|
||||
apdu.lc = crgram_len + 1;
|
||||
|
@ -71,6 +74,9 @@ int sc_compute_signature(struct sc_card *card,
|
|||
if (datalen > 255)
|
||||
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
/* INS: 0x2A PERFORM SECURITY OPERATION
|
||||
* P1: 0x9E Resp: Digital Signature
|
||||
* P2: 0x9A Cmd: Input for Digital Signature */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x9E,
|
||||
0x9A);
|
||||
apdu.resp = rbuf;
|
||||
|
|
Loading…
Reference in New Issue