I have a SafeNet eToken 5100 USB Token with PDF Digital Signing Certificate on it. I configured a windows and mac system to use it and I succeeded in manually signing PDF files with its certificate on both machines. Thus the certificate works as intended.
I shipped the token to my web host company and they placed it on my Linux (CentOS) server. I installed SafeNet Authentication Client on the server.
Now I'm attempting to use iText to apply the signature. I'm following code sample 4.2 from this excellent book: http://itextpdf.com/book/digitalsignatures. My code is:
String config = "name = eToken5100_20130805\n" +
"library = /usr/lib64/libeTPkcs11.so\n" +
"slot = 0"; // create a dynamic conf file
ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes());
Provider providerPKCS11 = new SunPKCS11(bais);
Security.addProvider(providerPKCS11);
System.out.println(providerPKCS11.getName());
BouncyCastleProvider providerBC = new BouncyCastleProvider();
Security.addProvider(providerBC);
KeyStore ks = KeyStore.getInstance("PKCS11", providerPKCS11);
ks.load(null, K.PASS_TOKEN);
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey)ks.getKey(alias, K.PASS_TOKEN);
Certificate[] chain = ks.getCertificateChain(alias);
OcspClient ocspClient = new OcspClientBouncyCastle();
TSAClient tsaClient = null;
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = (X509Certificate)chain[i];
String tsaUrl = CertificateUtil.getTSAURL(cert);
if (tsaUrl != null) {
tsaClient = new TSAClientBouncyCastle(tsaUrl);
break;
}
}
List<CrlClient> crlList = new ArrayList<CrlClient>();
crlList.add(new CrlClientOnline(chain));
sign(userFile, userFile_signed, chain, pk, DigestAlgorithms.SHA256, providerPKCS11.getName(),
CryptoStandard.CMS, "Test", "Ghent", crlList, ocspClient, tsaClient, 0);
when I run this code, it generates the following runtime error:
stack trace: java.security.KeyStoreException: PKCS11 not found
Caused by: java.security.NoSuchAlgorithmException: no such algorithm:
PKCS11 for provider SunPKCS11-eToken5100_20130805
This link indicates that the wrong keystore type might generate this error. I checked my ~glassfish/java/jdk7u25/jdk1.7.0_25/jre/lib/security/java.security
file and it uses a keystore of jks
. However, changing it to PKCS11
causes my GlassFish server not to restart. So I kept it as jks
.
QUESTION 1: Could this cause the problem? If so, how to resolve?
QUESTION 2: I just made up the name eToken5100_20130805
in the java code above... but does this name need to match some other name somewhere? (the Java code above is the only place I entered this name).
QUESTION 3: I know the library is correct, but how do I determine the slot number? I have manually entered slots 0 through 6 (just guessing) and they each produced the same error shown above. Further, if I enter slot numbers 7 through 10, a PKCS11Exception CKR_SLOT_ID_INVALID is thrown each time.
I don't know much about this topic, but I tried to determine the slot number various ways:
(A) I'm not sure if the following syntax is correct:
# keytool -v -list -keystore NONE -storetype PKCS11 -providername SunPKCS11-eToken5100_20130805 -J-Djava.security.debug=sunpkcs11,pkcs11
but it returns this output:
keytool error: java.security.NoSuchProviderException: no such provider: SunPKCS11-eToken5100_20130805
java.security.NoSuchProviderException: no such provider: SunPKCS11-eToken5100_20130805
at sun.security.jca.GetInstance.getService(GetInstance.java:83)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
at java.security.Security.getImpl(Security.java:698)
at java.security.KeyStore.getInstance(KeyStore.java:661)
at sun.security.tools.KeyTool.doCommands(KeyTool.java:765)
at sun.security.tools.KeyTool.run(KeyTool.java:340)
at sun.security.tools.KeyTool.main(KeyTool.java:333)
(B) I also tried to use modutil to find the slot number:
# modutil -list -dbdir $HOME/.mozilla/firefox/*.default
but I'm not sure what it means when it returns the following:
winscard_clnt.c:420:SCardEstablishContextTH() Your pcscd is too old and does not support CMD_VERSION
winscard_clnt.c:420:SCardEstablishContextTH() Your pcscd is too old and does not support CMD_VERSION
Listing of PKCS #11 Modules
-----------------------------------------------------------
1. NSS Internal PKCS #11 Module
slots: 2 slots attached
status: loaded
slot: NSS Internal Cryptographic Services
token: NSS Generic Crypto Services
slot: NSS User Private Key and Certificate Services
token: NSS Certificate DB
2. eToken
library name: libeTPkcs11.so
slots: 6 slots attached
status: loaded
slot:
token:
slot:
token:
slot:
token:
slot:
token:
slot:
token:
slot:
token:
(C) Lastly, I tried to run
# pkcs11-tool --module /usr/lib64/libeTPkcs11.so --list-slots
but this requires to first install openSC to obtain the pkcs11-tool. When I attempt to install using: # yum install opensc.x86_64
, it gives the following error:
Transaction Check Error:
file /usr/lib64/libpcsclite.so.1.0.0 from install of pcsc-lite-libs-1.5.2-13.el6_4.x86_64
conflicts with file from package libpcsclite1-1.4.0-9.el6.x86_64`
and I can't figure out how to overcome this error.
I could use some help navigating these unfamiliar errors, to understand what the problem is, then how to resolve it. Does it appear the slot number is indeed incorrect (can slot numbers be large, like, 31310? So far I'm assuming they're single digit...), or something else?
---------- UPDATE ----------
My linux machine had a package installed for libpcsclite1
that caused the error described above. I uninstalled SafeNet Auth Client (SAC), removed this package, installed pcsc-lite (using yum), and re-installed the standard SAC. I also installed opensc using yum so I can use pkcs11-tool. I can now see the slot using:
# pkcs11-tool --module /usr/lib64/libeToken.so -L
Available slots:
Slot 0 (0x0): AKS xxxx 00 00
token label: my label
token manuf: SafeNet, Inc.
token model: eToken
token flags: rng, login required, PIN initialized, token initialized, other flags=0x200
serial num : xxxxxxx
Slot 1 (0x1):
(empty)
Slot 2 (0x2):
(empty)
Slot 3 (0x3):
(empty)
Slot 4 (0x4):
(empty)
Slot 5 (0x5):
(empty)
Now I can run everything without generating runtime errors. However, the resulting PDF file displays "At least one signature is invalid". [update: my mistake, I was looking at the wrong file. The signed PDF file shows a valid signature.]