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

Revision 5179, 10.7 KB checked in by rafaelraymundo, 12 years ago (diff)

Ticket #2307 - Erro ao tentar logar com cadastrar certificado digital.

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