Hi,
there seem to be 2 problems:
- protect_certificates = false by default -> nasty security bug IMHO,
this is fixed in profile.c
PS: The flex.profile sets this value to true, but setting it to false
seems to work fine for me
(so I propose to remove it -> OK???)
- no reference to the user PIN is given with "pkcs15-init -X", which causes
sc_pkcs15_init_fixup_file() to set the corresponding ACs to NONE (!)
It looks rather nasty but I'm afraid of shacking it up so I just added
a reference
to the first user PIN in case it's not set -> comments?
Cheers,
Stef
Jean-Pierre Szikora wrote:
Hi,
Thanks to Yannick Leplard for analyzing and reporting this problem.
In onepin mode and when the first certificate is added to a SC by
itself (not through a PKCS12), the ACL of PKCS15-CDF (5015/4404) is
set to NONE... If the same certificate is added through a PKCS12, the
ACL is correctly set to CHV1. There is no problem with the others xDF.
This bug is present on MacOSX and on Linux (recent svn). And is not
card specific (present on SetCos and CryptoFlex).
A little script to reproduce the bug:
#!/bin/bash
openssl req -new -newkey rsa:1024 -nodes -x509 -keyout test.key -subj
/CN=JoTest -out test.pem
openssl pkcs12 -export -out test.p12 -passout pass:test -name JoTest
-inkey test.key -in test.pem
pkcs15-init -T -E
pkcs15-init -T -C -p pkcs15+onepin -l "Test" --pin 1234 --puk 1234
pkcs15-init -S test.key -l "Test" -a1 -i 50 --pin 1234
pkcs15-init -X test.pem -l "Test" -a1 -i 50 --pin 1234
#pkcs15-init -S test.p12 -f PKCS12 -a 1 --pin 1234 --passphrase test
opensc-explorer <<END
cd 5015
info 4404
quit
END
Cheers,
Jean-Pierre
Index: profile.c
===================================================================
--- profile.c (revision 2881)
+++ profile.c (working copy)
@@ -255,6 +255,7 @@
return NULL;
pro->p15_spec = p15card = sc_pkcs15_card_new();
+ pro->protect_certificates = 1;
pro->pkcs15.do_last_update = 1;
if (p15card) {
Index: pkcs15-lib.c
===================================================================
--- pkcs15-lib.c (revision 2881)
+++ pkcs15-lib.c (working copy)
@@ -1680,20 +1680,24 @@
if ((r = select_id(p15card, SC_PKCS15_TYPE_CERT, &args->id, NULL, NULL,
NULL)) < 0)
return r;
- /* If there is a private key corresponding to the ID given
- * by the user, make sure $PIN references the pin protecting
- * this key
- */
- if (args->id.len != 0
- && profile->protect_certificates
- && sc_pkcs15_find_prkey_by_id(p15card, &args->id, &object) == 0) {
- r = set_user_pin_from_authid(p15card, profile,
&object->auth_id);
- if (r < 0) {
- sc_error(p15card->card->ctx,
- "Failed to assign user pin reference "
- "(copied from private key auth_id)\n");
- return r;
+ if (profile->protect_certificates) {
+ /* If there is a private key corresponding to the ID given
+ * by the user, make sure $PIN references the pin protecting
+ * this key
+ */
+ r = -1;
+ if (args->id.len != 0
+ && sc_pkcs15_find_prkey_by_id(p15card, &args->id, &object) ==
0) {
+ r = set_user_pin_from_authid(p15card, profile,
&object->auth_id);
+ if (r < 0) {
+ sc_error(p15card->card->ctx,
+ "Failed to assign user pin
reference "
+ "(copied from private key
auth_id)\n");
+ return r;
+ }
}
+ if (r == -1) /* User pin ref not yet set */
+ set_user_pin_from_authid(p15card, profile, NULL);
}
object = sc_pkcs15init_new_object(SC_PKCS15_TYPE_CERT_X509, label,
NULL, NULL);
@@ -3098,7 +3102,9 @@
/*
* If the user specified an auth_id, select the corresponding
- * PIN entry and set the reference data
+ * PIN entry and set the reference data.
+ * If auth_id is NULL, then get the first user PIN found, this
+ * is usefull for the 'onepin' profile option.
*/
static int
set_user_pin_from_authid(struct sc_pkcs15_card *p15card,
@@ -3109,6 +3115,23 @@
struct sc_pkcs15_object *objp;
int r;
+ if (auth_id == NULL) {
+ int i;
+ struct sc_pkcs15_object *p15objects[5];
+ r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN,
p15objects, 5);
+ if (r < 0)
+ return r;
+ for (i = 0; i < r; i++) {
+ sc_pkcs15_pin_info_t *pininfo = (sc_pkcs15_pin_info_t
*) p15objects[i]->data;
+ if (!(pininfo->flags & SC_PKCS15_PIN_FLAG_SO_PIN)) {
+ auth_id = &pininfo->auth_id;
+ break;
+ }
+ }
+ if (i >= r)
+ return SC_ERROR_OBJECT_NOT_FOUND;
+ }
+
if (auth_id->len == 0)
return 0;
@@ -3408,6 +3431,51 @@
return sc_pkcs15init_fixup_acls(profile, file, &so_acl, &user_acl);
}
+static const char * acl_to_str(const sc_acl_entry_t *e)
+{
+ static char line[80], buf[10];
+ unsigned int acl;
+
+ if (e == NULL)
+ return "N/A";
+ line[0] = 0;
+ while (e != NULL) {
+ acl = e->method;
+
+ switch (acl) {
+ case SC_AC_UNKNOWN:
+ return "N/A";
+ case SC_AC_NEVER:
+ return "NEVR";
+ case SC_AC_NONE:
+ return "NONE";
+ case SC_AC_CHV:
+ strcpy(buf, "CHV");
+ if (e->key_ref != SC_AC_KEY_REF_NONE)
+ sprintf(buf + 3, "%d", e->key_ref);
+ break;
+ case SC_AC_TERM:
+ strcpy(buf, "TERM");
+ break;
+ case SC_AC_PRO:
+ strcpy(buf, "PROT");
+ break;
+ case SC_AC_AUT:
+ strcpy(buf, "AUTH");
+ if (e->key_ref != SC_AC_KEY_REF_NONE)
+ sprintf(buf + 4, "%d", e->key_ref);
+ break;
+ default:
+ strcpy(buf, "????");
+ break;
+ }
+ strcat(line, buf);
+ strcat(line, " ");
+ e = e->next;
+ }
+ line[strlen(line)-1] = 0; /* get rid of trailing space */
+ return line;
+}
/*
* Fix up a file's ACLs by replacing all occurrences of a symbolic
* PIN name with the real reference.
Index: flex.profile
===================================================================
--- flex.profile (revision 2881)
+++ flex.profile (working copy)
@@ -6,12 +6,6 @@
pin-encoding = ascii-numeric;
pin-pad-char = 0x00;
pin-domains = yes;
-
- # This profile does not PIN-protect certificates
- # stored on the card. If you enable this, you MUST
- # adjust the sizes of the pin-domain and key-dir DFs
- # accordingly.
- protect-certificates = no;
}
# Define reasonable limits for PINs and PUK
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel