If you review the online JSSE Reference Guide recently, you would found that in the section, Related Documentation, there is a new link to the just published document FIPS 140 Compliant Mode for SunJSSE
If you review the online JSSE Reference Guide recently, you would found that in the section, Related Documentation, there is a new link to the just published document FIPS 140 Compliant Mode for SunJSSE
Recently, I needed a tool to show the detailed PKCS11 slot information. Cryptoadm is a good utility to display cryptographic provider information for a system, but it does not show me the "ulMaxSessionCount" field, which was important to me at that time, I was eager to know what's the maximum number of sessions that can be opened with the token at one time by a single application. Google did not help this time, so I had to write a simple tool by myself.
Past the code here, maybe one day, it will save me a lot time when I need such a detailed slot info.
Compile the codes with:
$gcc cryinfo.c -o slotinfo -lpkcs11
Copy (or download), save, compile the source code bellow:
#include <stdio.h>
#include <security/cryptoki.h>
#include <security/pkcs11.h>
extern void dump_info();
int main(int argc, char **argv) {
CK_RV rv;
CK_MECHANISM mechanism = {CKM_RC4, NULL_PTR, 0L};
CK_SESSION_HANDLE hSession;
// initialize teh crypto library
rv = C_Initialize(NULL_PTR);
if (rv != CKR_OK) {
fprintf(stderr, "C_Initialize: Error = 0x%.8X\n", rv);
return -1;
}
dump_info();
rv = C_Finalize(NULL_PTR);
if (rv != CKR_OK) {
fprintf(stderr, "C_Finalize: Error = 0x%.8X\n", rv);
return -1;
}
}
void dump_info() {
CK_RV rv;
CK_SLOT_INFO slotInfo;
CK_TOKEN_INFO tokenInfo;
CK_ULONG ulSlotCount = 0;
CK_SLOT_ID_PTR pSlotList = NULL_PTR;
int i = 0;
rv = C_GetSlotList(0, NULL_PTR, &ulSlotCount);
if (rv != CKR_OK) {
fprintf(stderr, "C_GetSlotList: Error = 0x%.8X\n", rv);
return;
}
fprintf(stdout, "slotCount = %d\n", ulSlotCount);
pSlotList = malloc(ulSlotCount * sizeof(CK_SLOT_ID));
if (pSlotList == NULL) {
fprintf(stderr, "System error: unable to allocate memory");
return;
}
rv = C_GetSlotList(0, pSlotList, &ulSlotCount);
if (rv != CKR_OK) {
fprintf(stderr, "C_GetSlotList: Error = 0x%.8X\n", rv);
free(pSlotList);
return;
}
for (i = 0; i < ulSlotCount; i++) {
fprintf(stdout, "slot found: %d ----\n", pSlotList[i]);
rv = C_GetSlotInfo(pSlotList[i], &slotInfo);
if (rv != CKR_OK) {
fprintf(stderr, "C_GetSlotInfo: Error = 0x%.8X\n", rv);
free(pSlotList);
return;
}
fprintf(stdout, "slot description: %s\n", slotInfo.slotDescription);
fprintf(stdout, "slot manufacturer: %s\n", slotInfo.manufacturerID);
fprintf(stdout, "slot flags: 0x%.8X\n", slotInfo.flags);
fprintf(stdout, "slot hardwareVersion: %d.%d\n",
slotInfo.hardwareVersion.major, slotInfo.hardwareVersion.minor);
fprintf(stdout, "slot firmwareVersion: %d.%d\n",
slotInfo.firmwareVersion.major, slotInfo.firmwareVersion.minor);
rv = C_GetTokenInfo(pSlotList[i], &tokenInfo);
if (rv != CKR_OK) {
fprintf(stderr, "C_GetTokenInfo: Error = 0x%.8X\n", rv);
free(pSlotList);
return;
}
fprintf(stdout, "Token label: %s\n", tokenInfo.label);
fprintf(stdout, "Token manufacturer: %s\n", tokenInfo.manufacturerID);
fprintf(stdout, "Token model: %s\n", tokenInfo.model);
fprintf(stdout, "Token serial: %s\n", tokenInfo.serialNumber);
fprintf(stdout, "Token flags: 0x%.8X\n", tokenInfo.flags);
fprintf(stdout, "Token ulMaxSessionCount: %ld\n",
tokenInfo.ulMaxSessionCount);
fprintf(stdout, "Token ulSessionCount: %ld\n",
tokenInfo.ulSessionCount);
fprintf(stdout, "Token ulMaxRwSessionCount: %ld\n",
tokenInfo.ulMaxRwSessionCount);
fprintf(stdout, "Token ulRwSessionCount: %ld\n",
tokenInfo.ulRwSessionCount);
fprintf(stdout, "Token ulMaxPinLen: %ld\n", tokenInfo.ulMaxPinLen);
fprintf(stdout, "Token ulMinPinLen: %ld\n", tokenInfo.ulMinPinLen);
fprintf(stdout, "Token ulTotalPublicMemory: %ld\n",
tokenInfo.ulTotalPublicMemory);
fprintf(stdout, "Token ulFreePublicMemory: %ld\n",
tokenInfo.ulFreePublicMemory);
fprintf(stdout, "Token ulTotalPrivateMemory: %ld\n",
tokenInfo.ulTotalPrivateMemory);
fprintf(stdout, "Token ulFreePrivateMemory: %ld\n",
tokenInfo.ulFreePrivateMemory);
fprintf(stdout, "slot hardwareVersion: %d.%d\n",
tokenInfo.hardwareVersion.major, tokenInfo.hardwareVersion.minor);
fprintf(stdout, "slot firmwareVersion: %d.%d\n",
tokenInfo.firmwareVersion.major, tokenInfo.firmwareVersion.minor);
fprintf(stdout, "Token utcTime: %s\n", tokenInfo.utcTime);
fprintf(stdout, "\n");
}
free(pSlotList);
}
An aggregate of feeds, http://feeds.feedburner.com/influenceronsec, from Bruce Schneier, Alan Shimel, and more.
If a certificate is issued with a authority information access extension which indicates the OCSP access method and location, one can enable the default implementation of OCSP checker during building or validating a certification path.
Maybe you need to check your certificate firstly, in the purpose of making sure it includes a OCSP authority information access extension:
#${JAVA_HOME}/bin/keytool -printcert -v -file target.certYou are expected to see similar lines in the output:
#3: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
[accessMethod: 1.3.6.1.5.5.7.48.1
accessLocation: URIName: http://onsite-ocsp.verisign.com]
]
In the above output, "http://onsite-ocsp.verisign.com" indicates the location of the OCSP service.
If you find one of similar authority information access extension in your certificate path, you need to enable OCSP checker.
For Sun PKIX implementation, OCSP checking is not enabled by default for compatibility, note that enabling OCSP checking only has an effect if revocation checking has also been enabled. So, in order to enable OCSP checker, first of all, you need to active certificate revocation checking; then active OCSP checking. It is simple and straightforward, only needs a few lines.
PKIXParameters params = new PKIXParameters(anchors);
// Activate certificate revocation checking
params.setRevocationEnabled(true);
// Activate OCSP
Security.setProperty("ocsp.enable", "true");
After that above two configurations, the default Sun PKIX implementation will try to get certificate status from the OCSP service indicated in the authority information access extension. For the above example, "http://onsite-ocsp.verisign.com" is the OCSP service. The enabled Sun OCSP checker will send certificate status request to the service, get response, and analysis the status from the response, if the status is revoked or unknown, the target certificate would be rejected.
Here is a sample code I wrote help you test your certificates and OCSP service, hope it helps.
/**
* @author Xuelei Fan
*/
import java.io.*;
import java.net.SocketException;
import java.util.*;
import java.security.Security;
import java.security.cert.*;
public class AuthorizedResponderNoCheck {
static String selfSignedCertStr =
"-----BEGIN CERTIFICATE-----\n" +
// copy your trust anchor certificate here, in PEM format.
"-----END CERTIFICATE-----";
static String trusedCertStr =
"-----BEGIN CERTIFICATE-----\n" +
// copy your trusted enterprise certificate here, in PEM format.
"-----END CERTIFICATE-----";
static String issuerCertStr =
"-----BEGIN CERTIFICATE-----\n" +
// copy the intermediate CA certificate here, in PEM format.
"-----END CERTIFICATE-----";
static String targetCertStr =
"-----BEGIN CERTIFICATE-----\n" +
// copy the target certificate here, in PEM format.
"-----END CERTIFICATE-----";
private static CertPath generateCertificatePath()
throws CertificateException {
// generate certificate from cert strings
CertificateFactory cf = CertificateFactory.getInstance("X.509");
ByteArrayInputStream is =
new ByteArrayInputStream(issuerCertStr.getBytes());
Certificate issuerCert = cf.generateCertificate(is);
is = new ByteArrayInputStream(targetCertStr.getBytes());
Certificate targetCert = cf.generateCertificate(is);
is = new ByteArrayInputStream(trusedCertStr.getBytes());
Certificate trusedCert = cf.generateCertificate(is);
is.close();
// generate certification path
List list = Arrays.asList(new Certificate[] {
targetCert, issuerCert, trusedCert});
return cf.generateCertPath(list);
}
private static Set generateTrustAnchors()
throws CertificateException {
// generate certificate from cert string
CertificateFactory cf = CertificateFactory.getInstance("X.509");
ByteArrayInputStream is =
new ByteArrayInputStream(selfSignedCertStr.getBytes());
Certificate selfSignedCert = cf.generateCertificate(is);
is.close();
// generate a trust anchor
TrustAnchor anchor =
new TrustAnchor((X509Certificate)selfSignedCert, null);
return Collections.singleton(anchor);
}
public static void main(String args[]) throws Exception {
// if you work behind proxy, configure the proxy.
System.setProperty("http.proxyHost", "proxyhost");
System.setProperty("http.proxyPort", "proxyport");
CertPath path = generateCertificatePath();
Set anchors = generateTrustAnchors();
PKIXParameters params = new PKIXParameters(anchors);
// Activate certificate revocation checking
params.setRevocationEnabled(true);
// Activate OCSP
Security.setProperty("ocsp.enable", "true");
// Activate CRLDP
System.setProperty("com.sun.security.enableCRLDP", "true");
// Ensure that the ocsp.responderURL property is not set.
if (Security.getProperty("ocsp.responderURL") != null) {
throw new
Exception("The ocsp.responderURL property must not be set");
}
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
validator.validate(path, params);
}
}