Hello, when dealing with accessing tokens from a Java application via OpenSC, I noticed that the Sun/ORACLE PKCS11-Java implementation is not always able to retrieve the certificate chain (stored on the token) for a key.
The objects on my token (Feitian PKI card) are: > Private RSA Key [Private Key] > Object Flags : [0x3], private, modifiable > Usage : [0x12E], decrypt, sign, signRecover, unwrap, derive > Access Flags : [0x0] > ModLength : 2048 > Key ref : 1 (0x1) > Native : yes > Path : 3f005015 > Auth ID : 01 > ID : 692b93bfd7d6f6dd86832f81d1b44adbe266f74d > GUID : {692b93bf-d7d6-f6dd-8683-2f81d1b44adb} > > X.509 Certificate [/C=DE/L=Entenhausen/O=Dagobert Duck > Enterprises/OU=Geldspeicher/CN=Dagobert Duck] > Object Flags : [0x2], modifiable > Authority : no > Path : 3f0050153100 > ID : 692b93bfd7d6f6dd86832f81d1b44adbe266f74d > GUID : {692b93bf-d7d6-f6dd-8683-2f81d1b44adb} > Encoded serial : 02 01 03 > > X.509 Certificate [/C=DE/O=Deutsche Zertifizierungsstelle/OU=PKI der > Deutschen Zertifizierungsstelle/CN=Deutsche Zertifizierungsstelle Root CA] > Object Flags : [0x2], modifiable > Authority : yes > Path : 3f0050153101 > ID : aff0e45b54ec084fdb987e76b655100963ca0be1 > GUID : {aff0e45b-54ec-084f-db98-7e76b6551009} > Encoded serial : 02 01 01 The certificate chain is: > 0: /C=DE/L=Entenhausen/O=Dagobert Duck > Enterprises/OU=Geldspeicher/CN=Dagobert Duck > 1: /C=DE/O=Deutsche Zertifizierungsstelle/OU=PKI der Deutschen > Zertifizierungsstelle/CN=Deutsche Zertifizierungsstelle Root CA Accessing the keystore on this token with the Java keytool utility yields: > Keystore type: PKCS11 > Keystore provider: SunPKCS11-OpenSC > > Your keystore contains 2 entries > > Alias name: /C=DE/L=Entenhausen/O=Dagobert Duck > Enterprises/OU=Geldspeicher/CN=Dagobert Duck > Entry type: PrivateKeyEntry > Certificate chain length: 1 > Certificate[1]: > Owner: CN=Dagobert Duck, OU=Geldspeicher, O=Dagobert Duck Enterprises, > L=Entenhausen, C=DE > Issuer: CN=Deutsche Zertifizierungsstelle Root CA, OU=PKI der Deutschen > Zertifizierungsstelle, O=Deutsche Zertifizierungsstelle, C=DE > Serial number: 3 > Valid from: Tue Jan 31 08:18:17 CET 2012 until: Tue Jan 31 08:18:17 CET 2017 > > Alias name: /C=DE/O=Deutsche Zertifizierungsstelle/OU=PKI der Deutschen > Zertifizierungsstelle/CN=Deutsche Zertifizierungsstelle Root CA > Entry type: trustedCertEntry > > Owner: CN=Deutsche Zertifizierungsstelle Root CA, OU=PKI der Deutschen > Zertifizierungsstelle, O=Deutsche Zertifizierungsstelle, C=DE > Issuer: CN=Deutsche Zertifizierungsstelle Root CA, OU=PKI der Deutschen > Zertifizierungsstelle, O=Deutsche Zertifizierungsstelle, C=DE > Serial number: 1 > Valid from: Mon Jan 30 11:03:09 CET 2012 until: Fri Jan 30 11:03:09 CET 2032 Note the length of certificate chain (1), since the root certificate is not included in the chain (but should be). I tracked down this problem to the function C_FindObjectsInit which should find a certificate with a given subject but does not always succeed. Finally I ended in framework-pkcs15.c where in function pkcs15_cert_cmp_attribute the search condition for CKA_ISSUER is dealt with specially. I expanded this code slightly to do also the same special check for CKA_SUBJECT. The patched code solves this problem: Now in Java the certificate chain gets identified correctly. Output of Java keytool utility: > Keystore type: PKCS11 > Keystore provider: SunPKCS11-OpenSC > > Your keystore contains 2 entries > > Alias name: /C=DE/L=Entenhausen/O=Dagobert Duck > Enterprises/OU=Geldspeicher/CN=Dagobert Duck > Entry type: PrivateKeyEntry > Certificate chain length: 2 > Certificate[1]: > Owner: CN=Dagobert Duck, OU=Geldspeicher, O=Dagobert Duck Enterprises, > L=Entenhausen, C=DE > Issuer: CN=Deutsche Zertifizierungsstelle Root CA, OU=PKI der Deutschen > Zertifizierungsstelle, O=Deutsche Zertifizierungsstelle, C=DE > Serial number: 3 > Valid from: Tue Jan 31 08:18:17 CET 2012 until: Tue Jan 31 08:18:17 CET 2017 > Certificate[2]: > Owner: CN=Deutsche Zertifizierungsstelle Root CA, OU=PKI der Deutschen > Zertifizierungsstelle, O=Deutsche Zertifizierungsstelle, C=DE > Issuer: CN=Deutsche Zertifizierungsstelle Root CA, OU=PKI der Deutschen > Zertifizierungsstelle, O=Deutsche Zertifizierungsstelle, C=DE > Serial number: 1 > Valid from: Mon Jan 30 11:03:09 CET 2012 until: Fri Jan 30 11:03:09 CET 2032 > > Alias name: /C=DE/O=Deutsche Zertifizierungsstelle/OU=PKI der Deutschen > Zertifizierungsstelle/CN=Deutsche Zertifizierungsstelle Root CA > Entry type: trustedCertEntry > > Owner: CN=Deutsche Zertifizierungsstelle Root CA, OU=PKI der Deutschen > Zertifizierungsstelle, O=Deutsche Zertifizierungsstelle, C=DE > Issuer: CN=Deutsche Zertifizierungsstelle Root CA, OU=PKI der Deutschen > Zertifizierungsstelle, O=Deutsche Zertifizierungsstelle, C=DE > Serial number: 1 > Valid from: Mon Jan 30 11:03:09 CET 2012 until: Fri Jan 30 11:03:09 CET 2032 Patch file is attached (works with current git version but also version 0.12.2 and 0.12.1). I would be glad if this could be included in the next OpenSC release. Best regards, Christian -- Dr. Christian Rank Rechenzentrum Universität Passau Bereich Netzwerk und Telekommunikation Innstr. 33 D-94032 Passau GERMANY Tel.: 0851/509-1838 Fax: 0851/509-1802 PGP public key see http://www.rz.uni-passau.de/mitarbeiter/rank
*** framework-pkcs15.c.orig 2012-01-31 11:13:39.000000000 +0100 --- framework-pkcs15.c 2012-01-31 11:14:48.000000000 +0100 *************** *** 2418,2423 **** --- 2418,2446 ---- && !memcmp(cert->cert_data->issuer, data, len)) return 1; break; + case CKA_SUBJECT: + if (check_cert_data_read(fw_data, cert) != 0) + break; + if (cert->cert_data->subject_len == 0) + break; + data = (u8 *) attr->pValue; + len = attr->ulValueLen; + /* SEQUENCE is tag 0x30, SET is 0x31 + * I know this code is icky, but hey... this is netscape + * we're dealing with :-) */ + if (cert->cert_data->subject[0] == 0x31 + && data[0] == 0x30 && len >= 2) { + /* skip the length byte(s) */ + len = (data[1] & 0x80)? (data[1] & 0x7F) : 0; + if (attr->ulValueLen < len + 2) + break; + data += len + 2; + len = attr->ulValueLen - len - 2; + } + if (len == cert->cert_data->subject_len + && !memcmp(cert->cert_data->subject, data, len)) + return 1; + break; default: return sc_pkcs11_any_cmp_attribute(session, object, attr); }
_______________________________________________ opensc-devel mailing list opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel