Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Java PKCS#11 to read DoD Common Access Card

Tags:

java

pkcs#11

cac

I have researched on how to use Sun PKCS#11 api to access a DoD CAC and possibly use the CAC to access (read-only) Active Directory. My problem has been, what I have found in most cases will make a reference to some code, but never shows the referenced code. I have found the following code, but gives an error. Does anyone know of any code examples or clear documentation for using PKCS11 for CACs? Or an API solution which might work?

import java.io.*;
import java.util.*;
import java.security.cert.CertificateException;
import java.security.KeyStoreException;
import java.security.cert.X509Certificate;
import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;


public class SmartCard {
    public static void main(String[] args) throws Exception {
        try {
            String configName = "pkcs11.properties";
            Provider p = new sun.security.pkcs11.SunPKCS11(configName);
            Security.addProvider(p);
            Console c = System.console();
            char[] pin = c.readPassword("Enter your PIN: ");
            KeyStore cac = null;
            cac = KeyStore.getInstance("PKCS11");
            cac.load(null, pin);
            showInfoAboutCAC(cac);
        }
        catch(Exception ex) {
            ex.printStackTrace();
            System.exit(0);
        }
    }
    public static void showInfoAboutCAC(KeyStore ks) throws KeyStoreException, CertificateException {
        Enumeration<String> aliases = ks.aliases();
        while(aliases.hasMoreElements()) {
            String alias = aliases.nextElement();
            X509Certificate[] cchain = (X509Certificate[]) ks.getCertificateChain(alias);
            System.out.println("Certificate Chain for " + alias);
            for(int i = 0; i < cchain.length; i++) {
                System.out.println(" -SubjectDN: " + cchain[i].getSubjectDN());
                System.out.println(" -IssuerDN: " + cchain[i].getIssuerDN());
            }
        }
    }
}

java.security.ProviderException: Initialization failed
        at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:374)
        at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:103)
        at smartcard.SmartCard.main(SmartCard.java:21)
Caused by: java.io.IOException: The specified procedure could not be found.

        at sun.security.pkcs11.wrapper.PKCS11.connect(Native Method)
        at sun.security.pkcs11.wrapper.PKCS11.<init>(PKCS11.java:137)
        at sun.security.pkcs11.wrapper.PKCS11.getInstance(PKCS11.java:150)
        at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:312)
        ... 2 more
like image 966
Donninet Avatar asked Nov 12 '22 05:11

Donninet


1 Answers

The properties file does exist, and is in the same directory as the application. And as far as I can tell, Java has access to the file.

If it helps, here's the contents of the file:

name=SmartCard
library=C:/Program Files/Java/jre7/bin/j2pkcs11.dll
like image 98
Donninet Avatar answered Nov 14 '22 21:11

Donninet