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
[email protected]
http://www.opensc-project.org/mailman/listinfo/opensc-devel