- Implemented keep-public-key and sc_pkcs15init_remove_object as
suggested by Victor Tarasov. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1710 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
13bf8814ef
commit
30e04cef59
|
@ -95,6 +95,8 @@ static int sc_pkcs15init_add_object(struct sc_pkcs15_card *,
|
|||
struct sc_profile *profile,
|
||||
unsigned int df_type,
|
||||
struct sc_pkcs15_object *);
|
||||
static int sc_pkcs15init_remove_object(sc_pkcs15_card_t *,
|
||||
sc_profile_t *, sc_pkcs15_object_t *);
|
||||
static int sc_pkcs15init_map_usage(unsigned long, int);
|
||||
static int set_so_pin_from_card(struct sc_pkcs15_card *,
|
||||
struct sc_profile *);
|
||||
|
@ -1315,6 +1317,17 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card,
|
|||
&args->der_encoded, &cert_info->path);
|
||||
}
|
||||
|
||||
/* Remove the corresponding public key object, if it exists. */
|
||||
if (r >= 0 && !profile->keep_public_key) {
|
||||
sc_pkcs15_object_t *puk = NULL;
|
||||
|
||||
r = sc_pkcs15_find_pubkey_by_id(p15card, &cert_info->id, &puk);
|
||||
if (r == 0)
|
||||
r = sc_pkcs15init_remove_object(p15card, profile, puk);
|
||||
else if (r == SC_ERROR_OBJECT_NOT_FOUND)
|
||||
r = 0;
|
||||
}
|
||||
|
||||
/* Now update the CDF */
|
||||
if (r >= 0)
|
||||
r = sc_pkcs15init_add_object(p15card, profile,
|
||||
|
@ -1928,6 +1941,70 @@ sc_pkcs15init_update_odf(struct sc_pkcs15_card *p15card,
|
|||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update any PKCS15 DF file (except ODF and DIR)
|
||||
*/
|
||||
static int
|
||||
sc_pkcs15init_update_any_df(sc_pkcs15_card_t *p15card,
|
||||
sc_profile_t *profile,
|
||||
sc_pkcs15_df_t *df,
|
||||
int is_new)
|
||||
{
|
||||
struct sc_card *card = p15card->card;
|
||||
sc_file_t *file = df->file, *pfile = NULL;
|
||||
u8 *buf = NULL;
|
||||
size_t bufsize;
|
||||
int update_odf = is_new, r = 0;
|
||||
|
||||
if (!sc_profile_get_file_by_path(profile, &df->path, &pfile))
|
||||
file = pfile;
|
||||
|
||||
r = sc_pkcs15_encode_df(card->ctx, p15card, df, &buf, &bufsize);
|
||||
if (r >= 0) {
|
||||
r = sc_pkcs15init_update_file(profile, card,
|
||||
file, buf, bufsize);
|
||||
|
||||
#if 0
|
||||
/* If the DF is empty, delete it and remove
|
||||
* the corresponding entry from the ODF
|
||||
*
|
||||
* XXX Before enabling this we should make this a
|
||||
* profile option, because not all cards allow
|
||||
* arbitrary removal of files.
|
||||
*/
|
||||
if (bufsize == 0) {
|
||||
sc_pkcs15_remove_df(p15card, df);
|
||||
sc_file_free(card, df->path);
|
||||
update_odf = 1;
|
||||
} else
|
||||
#endif
|
||||
|
||||
/* For better performance and robustness, we want
|
||||
* to note which portion of the file actually
|
||||
* contains valid data.
|
||||
*
|
||||
* This is particularly useful if we store certificates
|
||||
* directly in the CDF - we may want to make the CDF
|
||||
* fairly big, without having to read the entire file
|
||||
* every time we parse the CDF.
|
||||
*/
|
||||
if (profile->pkcs15.encode_df_length) {
|
||||
df->path.count = bufsize;
|
||||
df->path.index = 0;
|
||||
update_odf = 1;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
if (pfile)
|
||||
sc_file_free(pfile);
|
||||
|
||||
/* Now update the ODF if we have to */
|
||||
if (r >= 0 && update_odf)
|
||||
r = sc_pkcs15init_update_odf(p15card, profile);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an object to one of the pkcs15 directory files.
|
||||
*/
|
||||
|
@ -1939,15 +2016,15 @@ sc_pkcs15init_add_object(struct sc_pkcs15_card *p15card,
|
|||
{
|
||||
struct sc_pkcs15_df *df;
|
||||
struct sc_card *card = p15card->card;
|
||||
struct sc_file *file = NULL, *pfile;
|
||||
u8 *buf = NULL;
|
||||
size_t bufsize;
|
||||
int update_odf = 0, r = 0;
|
||||
struct sc_file *file = NULL;
|
||||
int is_new = 0, r = 0;
|
||||
|
||||
sc_debug(card->ctx, "called, DF %u obj %p\n", df_type, object);
|
||||
|
||||
df = find_df_by_type(p15card, df_type);
|
||||
if (df == NULL) {
|
||||
if (df != NULL) {
|
||||
file = df->file;
|
||||
} else {
|
||||
file = profile->df[df_type];
|
||||
if (file == NULL) {
|
||||
sc_error(card->ctx,
|
||||
|
@ -1958,7 +2035,7 @@ sc_pkcs15init_add_object(struct sc_pkcs15_card *p15card,
|
|||
sc_pkcs15_add_df(p15card, df_type, &file->path, file);
|
||||
df = find_df_by_type(p15card, df_type);
|
||||
assert(df != NULL);
|
||||
update_odf = 1;
|
||||
is_new = 1;
|
||||
|
||||
/* Mark the df as enumerated, so libopensc doesn't try
|
||||
* to load the file at a most inconvenient moment */
|
||||
|
@ -1977,6 +2054,8 @@ sc_pkcs15init_add_object(struct sc_pkcs15_card *p15card,
|
|||
assert(object->df == df);
|
||||
}
|
||||
|
||||
return sc_pkcs15init_update_any_df(p15card, profile, df, is_new);
|
||||
#if 0
|
||||
if (!sc_profile_get_file_by_path(profile, &df->path, &pfile))
|
||||
file = pfile;
|
||||
|
||||
|
@ -1988,7 +2067,7 @@ sc_pkcs15init_add_object(struct sc_pkcs15_card *p15card,
|
|||
* to note which portion of the file actually
|
||||
* contains valid data.
|
||||
*
|
||||
* This is paticularly useful if we store certificates
|
||||
* This is particularly useful if we store certificates
|
||||
* directly in the CDF - we may want to make the CDF
|
||||
* fairly big, without having to read the entire file
|
||||
* every time we parse the CDF.
|
||||
|
@ -2007,6 +2086,42 @@ sc_pkcs15init_add_object(struct sc_pkcs15_card *p15card,
|
|||
if (r >= 0 && update_odf)
|
||||
r = sc_pkcs15init_update_odf(p15card, profile);
|
||||
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
sc_pkcs15init_remove_object(sc_pkcs15_card_t *p15card,
|
||||
sc_profile_t *profile, sc_pkcs15_object_t *obj)
|
||||
{
|
||||
sc_card_t *card = p15card->card;
|
||||
struct sc_pkcs15_df *df;
|
||||
sc_path_t path;
|
||||
int r = 0;
|
||||
|
||||
path = ((struct sc_pkcs15_pubkey_info *)obj->data)->path;
|
||||
|
||||
/* Get the DF we're part of. If there's no DF, fine, we haven't
|
||||
* been added yet. */
|
||||
if ((df = obj->df) == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef notyet
|
||||
if (profile->ops->ext_remove_data
|
||||
&& (r = profile->ops->ext_remove_data(profile, card, obj)))
|
||||
return r;
|
||||
#endif
|
||||
|
||||
/* Unlink the object and update the DF */
|
||||
sc_pkcs15_remove_object(p15card, obj);
|
||||
if ((r = sc_pkcs15init_update_any_df(p15card, profile, df, 0)) < 0)
|
||||
return r;
|
||||
|
||||
/* XXX Dangerous - the object indicated by path may be the
|
||||
* application DF. This isn't true for the Oberthur, but
|
||||
* it may be for others. */
|
||||
r = sc_delete_file(card, &path);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -2506,8 +2621,14 @@ sc_pkcs15init_update_file(struct sc_profile *profile, struct sc_card *card,
|
|||
r = sc_update_binary(card, 0, (const u8 *) data, datalen, 0);
|
||||
|
||||
if (info->size > datalen) {
|
||||
/* XXX zero out the rest of the file - we may have shrunk
|
||||
/* zero out the rest of the file - we may have shrunk
|
||||
* the file contents */
|
||||
size_t pad_len = info->size - datalen;
|
||||
|
||||
data = calloc(1, pad_len);
|
||||
r = sc_update_binary(card, datalen,
|
||||
(const u8 *) data, pad_len, 0);
|
||||
free(data);
|
||||
}
|
||||
|
||||
sc_file_free(info);
|
||||
|
|
|
@ -271,6 +271,7 @@ sc_profile_new()
|
|||
pro->pin_encoding = 0x01;
|
||||
pro->pin_minlen = 4;
|
||||
pro->pin_maxlen = 8;
|
||||
pro->keep_public_key = 1;
|
||||
|
||||
return pro;
|
||||
}
|
||||
|
@ -682,6 +683,12 @@ do_protect_certificates(struct state *cur, int argc, char **argv)
|
|||
return get_bool(cur, argv[0], &cur->profile->protect_certificates);
|
||||
}
|
||||
|
||||
static int
|
||||
do_keep_public_key(struct state *cur, int argc, char **argv)
|
||||
{
|
||||
return get_bool(cur, argv[0], &cur->profile->keep_public_key);
|
||||
}
|
||||
|
||||
static int
|
||||
do_card_label(struct state *cur, int argc, char **argv)
|
||||
{
|
||||
|
@ -1362,6 +1369,7 @@ static struct command ci_commands[] = {
|
|||
{ "protect-certificates", 1, 1, do_protect_certificates },
|
||||
{ "label", 1, 1, do_card_label },
|
||||
{ "manufacturer", 1, 1, do_card_manufacturer},
|
||||
{ "keep-public-key", 1, 1, do_keep_public_key },
|
||||
|
||||
{ NULL, 0, 0, NULL }
|
||||
};
|
||||
|
|
|
@ -107,6 +107,7 @@ struct sc_profile {
|
|||
unsigned int rsa_access_flags;
|
||||
unsigned int dsa_access_flags;
|
||||
unsigned int protect_certificates;
|
||||
unsigned int keep_public_key;
|
||||
|
||||
struct {
|
||||
unsigned int direct_certificates;
|
||||
|
|
Loading…
Reference in New Issue