source: branches/2.3/security/ExpressoCert/src/br/gov/serpro/cert/Token.java @ 5024

Revision 5024, 9.3 KB checked in by rafaelraymundo, 13 years ago (diff)

Ticket #2256 - Token iKey 2032 não consegue acessar certificado do usuário.

Line 
1/*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
5
6package br.gov.serpro.cert;
7
8import br.gov.serpro.setup.Setup;
9import java.io.ByteArrayInputStream;
10import java.io.File;
11import java.io.IOException;
12import java.security.Provider;
13import java.security.ProviderException;
14import java.security.Security;
15import java.security.cert.CertificateFactory;
16import java.util.logging.Level;
17import java.util.logging.Logger;
18import java.security.cert.X509Certificate;
19import java.util.HashMap;
20import java.util.Map;
21import sun.security.pkcs11.wrapper.CK_ATTRIBUTE;
22import sun.security.pkcs11.wrapper.CK_C_INITIALIZE_ARGS;
23import sun.security.pkcs11.wrapper.Functions;
24import sun.security.pkcs11.wrapper.PKCS11;
25import sun.security.pkcs11.wrapper.PKCS11Exception;
26import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
27
28//TODO: Deal with wildcards for environments variables.
29
30/**
31 *
32 * @author esa
33 */
34class Token{
35
36    private final Setup setup;
37    private String name;
38    private String libraryPath;
39    private Provider tokenProvider;
40    private boolean registered = false;
41    private long slot;
42
43    static long CK_OBJECT_CLASS;
44    static long CK_OBJECT_HANDLE;
45
46    private Token(final Setup setup) {
47        this.setup = setup;
48    }
49
50    Token(String name, String libraryPath, final Setup setup){
51        this(setup);
52        this.setName(name);
53        this.setLibraryPath(libraryPath);
54    }
55
56    public boolean isRegistered() {
57        return this.registered;
58    }
59
60    public void setLibraryPath(String libraryPath) {
61        this.libraryPath = libraryPath;
62    }
63
64    public void setName(String name) {
65        this.name = name;
66    }
67
68    public String getName() {
69        return this.name;
70    }
71
72    public String getProviderName(){
73        return this.tokenProvider.getName();
74    }
75
76    protected void registerToken(long slot) throws IOException{
77
78        this.slot = slot;
79        String tokenConfiguration = new String("name = " + name + "_" + slot + "\n" +
80            "library = " + libraryPath + "\nslot = " + slot +
81            "\ndisabledMechanisms = {\n" + "CKM_SHA1_RSA_PKCS\n}" +
82            "\n");
83
84        try{
85            this.registered = false;
86            if (libraryExists()){
87                Provider pkcs11Provider = new sun.security.pkcs11.SunPKCS11(new ByteArrayInputStream(tokenConfiguration.getBytes()));
88                this.tokenProvider = pkcs11Provider;
89                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
90                    System.out.println("Adding provider: "+pkcs11Provider.getName());
91                    System.out.println("Provider info: " + pkcs11Provider.getInfo());
92                }
93                Security.addProvider(pkcs11Provider);
94                this.setName(this.tokenProvider.getName());
95                this.registered = true;
96            }
97        }
98        catch (ProviderException e){
99            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
100                e.printStackTrace();
101                System.out.println("Não foi possível inicializar o seguinte token: " + tokenConfiguration);
102            }
103        }
104    }
105
106    protected void unregisterToken(){
107        Security.removeProvider(this.tokenProvider.getName());
108        this.registered = false;
109    }
110
111    Map<String, String> getAliases() throws IOException{
112
113        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
114            System.out.println("Getting Aliases");
115        }
116
117        Map<String, String> aliases = new HashMap<String, String>();
118
119        CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
120        String functionList = "C_GetFunctionList";
121
122        initArgs.flags = CKF_OS_LOCKING_OK;
123
124        PKCS11 tmpPKCS11 = null;
125        try {
126            try {
127                tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, false);
128            } catch (IOException ex) {
129                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
130                    Logger.getLogger(TokenCollection.class.getName()).log(Level.SEVERE, null, ex);
131                }
132                throw ex;
133            }
134        } catch (PKCS11Exception e) {
135            try {
136                initArgs = null;
137                tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, true);
138            } catch (IOException ex) {
139                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
140                    Logger.getLogger(TokenCollection.class.getName()).log(Level.SEVERE, null, ex);
141                }
142            } catch (PKCS11Exception ex) {
143                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
144                    Logger.getLogger(TokenCollection.class.getName()).log(Level.SEVERE, null, ex);
145                }
146            }
147        }
148
149        try {
150            // cria sessão pública rw. com flag CKF_SERIAL_SESSION
151            long session = tmpPKCS11.C_OpenSession(this.slot, CKF_SERIAL_SESSION, null, null);
152
153            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
154                System.out.println("session number:  "+session);
155            }
156
157            // TODO: Verifica se está logado, senão loga usuário. Pede pin? ou recebe pin?
158
159            CK_ATTRIBUTE[] TEMPLATE_CERTIFICATE = {new CK_ATTRIBUTE(CKA_CLASS, CKO_CERTIFICATE)};
160            CK_ATTRIBUTE[] TEMPLATE_PKEY = {new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY)};
161            CK_ATTRIBUTE[] TEMPLATE_KEY_LABEL_ID = {new CK_ATTRIBUTE(CKA_LABEL), new CK_ATTRIBUTE(CKA_ID)};
162            CK_ATTRIBUTE[] TEMPLATE_CERT_LABEL_ID = {
163                new CK_ATTRIBUTE(CKA_LABEL),
164                new CK_ATTRIBUTE(CKA_ID),
165                new CK_ATTRIBUTE(CKA_VALUE)
166            };
167
168            tmpPKCS11.C_FindObjectsInit(session, TEMPLATE_CERTIFICATE);
169            long[] certs = tmpPKCS11.C_FindObjects(session, 20);
170
171            tmpPKCS11.C_FindObjectsFinal(session);
172
173            tmpPKCS11.C_FindObjectsInit(session, TEMPLATE_PKEY);
174            long[] keys = tmpPKCS11.C_FindObjects(session, 20);
175
176            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
177                System.out.println("Private Keys: "+keys.length);
178            }
179
180            for (long key : keys){
181                tmpPKCS11.C_GetAttributeValue(session, key, TEMPLATE_KEY_LABEL_ID);
182
183                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
184                    System.out.print("Private key ID: ");
185                    for (byte b : (byte [])TEMPLATE_KEY_LABEL_ID[1].pValue){
186                        System.out.print(b);
187                    }
188                    System.out.println();
189                    if (TEMPLATE_KEY_LABEL_ID[0].pValue != null)
190                    {
191                        System.out.println("Private key LABEL: "+new String((char [])TEMPLATE_KEY_LABEL_ID[0].pValue));
192                    }
193                    System.out.println("\nCerts:");
194                }
195
196                for (long cert : certs){
197                    tmpPKCS11.C_GetAttributeValue(session, cert, TEMPLATE_CERT_LABEL_ID);
198
199                    if (Functions.equals((byte [])TEMPLATE_KEY_LABEL_ID[1].pValue,
200                            (byte [])TEMPLATE_CERT_LABEL_ID[1].pValue)){
201                        if (TEMPLATE_CERT_LABEL_ID[0].pValue != null)
202                        {
203                            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
204                                System.out.println("Certificate LABEL: "+new String((char [])TEMPLATE_CERT_LABEL_ID[0].pValue));
205                            }
206                            ByteArrayInputStream in = new ByteArrayInputStream((byte [])TEMPLATE_CERT_LABEL_ID[2].pValue);
207                            CertificateFactory cf = CertificateFactory.getInstance("X.509");
208                            X509Certificate certObj = (X509Certificate)cf.generateCertificate(in);
209                            if (certObj.getBasicConstraints() == -1 ){
210                                aliases.put(new String((char [])TEMPLATE_CERT_LABEL_ID[0].pValue),
211                                        certObj.getSubjectX500Principal().getName());
212                            }
213                        }
214                    }
215
216                }
217                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
218                    System.out.println();
219                }
220            }
221
222            tmpPKCS11.C_CloseSession(session);
223
224        } catch (PKCS11Exception ex) {
225            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
226                Logger.getLogger(TokenCollection.class.getName()).log(Level.SEVERE, null, ex);
227            }
228        } catch (Throwable t) {
229            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
230                Logger.getLogger(TokenCollection.class.getName()).log(Level.SEVERE, null, t);
231            }
232        }
233
234        return aliases;
235
236    }
237
238    public boolean libraryExists(){
239
240        File libraryFile = new File(libraryPath);
241        if (libraryFile.exists()){
242            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
243                System.out.println("Arquivo " + libraryPath + " existe.");
244            }
245            return true;
246        }
247       
248        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
249            System.out.println("Biblioteca do Token/SmartCard " + name + " não foi encontrada: " + libraryPath);
250        }
251       
252        return false;
253    }
254   
255}
Note: See TracBrowser for help on using the repository browser.