KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > protocol > xkms > client > RecoverCommand


1 /*************************************************************************
2  * *
3  * EJBCA: The OpenSource Certificate Authority *
4  * *
5  * This software is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU Lesser General Public *
7  * License as published by the Free Software Foundation; either *
8  * version 2.1 of the License, or any later version. *
9  * *
10  * See terms of license at gnu.org. *
11  * *
12  *************************************************************************/

13  
14 package org.ejbca.core.protocol.xkms.client;
15
16 import java.security.KeyStore JavaDoc;
17 import java.security.PrivateKey JavaDoc;
18 import java.security.cert.Certificate JavaDoc;
19 import java.security.cert.CertificateException JavaDoc;
20 import java.security.cert.X509Certificate JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25
26 import javax.xml.bind.JAXBElement;
27
28 import org.ejbca.core.protocol.xkms.common.XKMSConstants;
29 import org.ejbca.core.protocol.xkms.common.XKMSUtil;
30 import org.ejbca.ui.cli.ErrorAdminCommandException;
31 import org.ejbca.ui.cli.IAdminCommand;
32 import org.ejbca.ui.cli.IllegalAdminCommandException;
33 import org.ejbca.util.CertTools;
34 import org.ejbca.util.KeyTools;
35 import org.w3._2000._09.xmldsig_.KeyInfoType;
36 import org.w3._2000._09.xmldsig_.X509DataType;
37 import org.w3._2002._03.xkms_.KeyBindingType;
38 import org.w3._2002._03.xkms_.ObjectFactory;
39 import org.w3._2002._03.xkms_.RecoverRequestType;
40 import org.w3._2002._03.xkms_.RecoverResultType;
41
42
43
44
45
46 /**
47  * Performes KRSS recover calls to an web service.
48  *
49  * @version $Id: RecoverCommand.java,v 1.1 2007/01/07 00:31:51 herrvendil Exp $
50  * @author Philip Vendil
51  */

52 public class RecoverCommand extends XKMSCLIBaseCommand implements IAdminCommand{
53
54     private ObjectFactory xKMSObjectFactory = new ObjectFactory();
55     private org.w3._2000._09.xmldsig_.ObjectFactory sigFactory = new org.w3._2000._09.xmldsig_.ObjectFactory();
56     
57     private static final int ARG_CERT = 1;
58     private static final int ARG_CERTENCODING = 2;
59     private static final int ARG_PASSWORD = 3;
60     private static final int ARG_ENCODING = 4;
61     private static final int ARG_OUTPUTPATH = 5;
62         
63    
64     
65     /**
66      * Creates a new instance of RaAddUserCommand
67      *
68      * @param args command line arguments
69      */

70     public RecoverCommand(String JavaDoc[] args) {
71         super(args);
72     }
73
74     /**
75      * Runs the command
76      *
77      * @throws IllegalAdminCommandException Error in command args
78      * @throws ErrorAdminCommandException Error running command
79      */

80     public void execute() throws IllegalAdminCommandException, ErrorAdminCommandException {
81         
82         try {
83            
84             if(args.length < 5 || args.length > 6){
85                 usage();
86                 System.exit(-1);
87             }
88   
89             String JavaDoc certEncoding = getCertEncoding(args[ARG_CERTENCODING]);
90             X509Certificate JavaDoc orgCert = getCert(args[ARG_CERT],certEncoding);
91             String JavaDoc password = args[ARG_PASSWORD];
92                                                 
93             String JavaDoc encoding = useEncoding(args[ARG_ENCODING]);
94          
95             String JavaDoc outputPath = "";
96             if(args.length >= ARG_OUTPUTPATH +1){
97                 if(args[ARG_OUTPUTPATH] != null){
98                   outputPath = args[ARG_OUTPUTPATH] + "/";
99                 }
100             }
101
102             String JavaDoc reqId = genId();
103             RecoverRequestType recoverRequestType = xKMSObjectFactory.createRecoverRequestType();
104             recoverRequestType.setId(reqId);
105             recoverRequestType.getRespondWith().add(XKMSConstants.RESPONDWITH_X509CHAIN);
106             recoverRequestType.getRespondWith().add(XKMSConstants.RESPONDWITH_PRIVATEKEY);
107             
108             X509DataType x509DataType = sigFactory.createX509DataType();
109             x509DataType.getX509IssuerSerialOrX509SKIOrX509SubjectName().add(sigFactory.createX509DataTypeX509Certificate(orgCert.getEncoded()));
110             KeyInfoType keyInfoType = sigFactory.createKeyInfoType();
111             keyInfoType.getContent().add(sigFactory.createX509Data(x509DataType));
112             
113             String JavaDoc keyBindingId = "_" + orgCert.getSerialNumber().toString();
114             KeyBindingType keyBindingType = xKMSObjectFactory.createKeyBindingType();
115             keyBindingType.setKeyInfo(keyInfoType);
116             keyBindingType.setId(keyBindingId);
117             recoverRequestType.setRecoverKeyBinding(keyBindingType);
118             
119            
120             
121             RecoverResultType recoverResultType = getXKMSInvoker().recover(recoverRequestType, clientCert, privateKey, password, keyBindingId);
122
123             
124             if(recoverResultType.getResultMajor().equals(XKMSConstants.RESULTMAJOR_SUCCESS) &&
125                recoverResultType.getResultMinor() == null){
126             
127                 if(recoverResultType.getKeyBinding().size() >0){
128                     KeyBindingType keyBinding = recoverResultType.getKeyBinding().get(0);
129                     List JavaDoc certs = getCertsFromKeyBinding(keyBinding);
130                       
131                     X509Certificate JavaDoc userCert = getUserCert(certs);
132                     certs.remove(userCert);
133                     
134                     if(recoverResultType.getPrivateKey() != null){
135                         PrivateKey JavaDoc serverKey = XKMSUtil.getPrivateKeyFromEncryptedXML(recoverResultType.getPrivateKey(), password);
136                         createKeyStore(userCert, certs, serverKey,password,encoding,outputPath);
137                     }else{
138                         getPrintStream().println("Error: Response didn't contain any private key");
139                         System.exit(-1);
140                     }
141
142                 }
143    
144             }else{
145                 displayRequestErrors(recoverResultType);
146             }
147     
148         } catch (Exception JavaDoc e) {
149             throw new ErrorAdminCommandException(e);
150         }
151     }
152
153     private X509Certificate JavaDoc getCert(String JavaDoc filename, String JavaDoc certEncoding) {
154         X509Certificate JavaDoc retval = null;
155         
156         if(certEncoding.equals(ENCODING_PEM)){
157             try {
158                 Collection JavaDoc certs = CertTools.getCertsFromPEM(filename);
159                 if(certs.size() > 0){
160                     retval = (X509Certificate JavaDoc) certs.iterator().next();
161                 }
162             } catch (Exception JavaDoc e) {}
163
164         }
165         if(certEncoding.equals(ENCODING_DER)){
166             try {
167                 byte[] certdata = loadCert(filename);
168                 retval = CertTools.getCertfromByteArray(certdata);
169             } catch (CertificateException JavaDoc e) {
170             }
171         }
172         
173         if(retval == null){
174             getPrintStream().println("Error couldn't decode certificate " + filename);
175             usage();
176             System.exit(-1);
177         }
178         
179         return retval;
180     }
181
182     private String JavaDoc getCertEncoding(String JavaDoc arg) {
183         if(arg.equalsIgnoreCase(ENCODING_PEM)){
184             return ENCODING_PEM;
185         }
186         
187         if(arg.equalsIgnoreCase(ENCODING_DER)){
188             return ENCODING_DER;
189         }
190         
191         getPrintStream().println("Illegal cert encoding(should be pem, der) : " + arg);
192         usage();
193         System.exit(-1);
194         return null;
195     }
196
197     private X509Certificate JavaDoc getUserCert(Collection JavaDoc certs) {
198         X509Certificate JavaDoc retval = null;
199         Iterator JavaDoc iter = certs.iterator();
200         while(iter.hasNext()){
201             X509Certificate JavaDoc next = (X509Certificate JavaDoc) iter.next();
202             if(next.getBasicConstraints() == -1){
203                 retval = next;
204                 break;
205             }
206         }
207         
208         return retval;
209     }
210
211     private void createKeyStore(X509Certificate JavaDoc userCert, List JavaDoc caCerts, PrivateKey JavaDoc privKey, String JavaDoc password, String JavaDoc encoding, String JavaDoc outputPath) throws Exception JavaDoc {
212         boolean createJKS = false;
213         boolean createPEM = false;
214         if(encoding.equals(ENCODING_JKS)){
215             createJKS = true;
216         }
217         if(encoding.equals(ENCODING_PEM)){
218             createPEM = true;
219         }
220         
221         String JavaDoc alias = getAlias(userCert);
222         
223         Certificate JavaDoc[] caChain = new Certificate JavaDoc[caCerts.size()];
224         for(int i=0;i<caCerts.size();i++){
225             caChain[i] = (Certificate JavaDoc) caCerts.get(i);
226         }
227         
228         // Store keys and certificates in keystore.
229
KeyStore JavaDoc ks = null;
230
231         if (createJKS) {
232             ks = KeyTools.createJKS(alias, privKey, password, userCert, caChain);
233         } else {
234             ks = KeyTools.createP12(alias, privKey, userCert, caChain);
235         }
236
237         storeKeyStore(ks, alias, password, createJKS, createPEM, outputPath);
238         
239     }
240
241     private String JavaDoc getAlias(X509Certificate JavaDoc userCert) {
242         String JavaDoc alias = CertTools.getPartFromDN(CertTools.getSubjectDN(userCert), "CN");
243         if (alias == null) alias = "myKey";
244         return alias;
245     }
246
247     private List JavaDoc getCertsFromKeyBinding(KeyBindingType keyBinding) throws CertificateException JavaDoc {
248         ArrayList JavaDoc retval = new ArrayList JavaDoc();
249         
250         JAXBElement<X509DataType> jAXBX509Data = (JAXBElement<X509DataType>) keyBinding.getKeyInfo().getContent().get(0);
251         Iterator JavaDoc iter2 = jAXBX509Data.getValue().getX509IssuerSerialOrX509SKIOrX509SubjectName().iterator();
252         while(iter2.hasNext()){
253             JAXBElement next = (JAXBElement) iter2.next();
254             if(next.getName().getLocalPart().equals("X509Certificate")){
255               byte[] encoded = (byte[]) next.getValue();
256               X509Certificate JavaDoc nextCert = CertTools.getCertfromByteArray(encoded);
257               retval.add(nextCert);
258             }
259         }
260         
261         return retval;
262     }
263
264     private void displayRequestErrors(RecoverResultType recoverResultType) {
265         if(recoverResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_NOMATCH)){
266             getPrintStream().println("Error no user with given certificate could be found");
267         }else
268             if(recoverResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_NOAUTHENTICATION)){
269                 getPrintStream().println("Error password couldn't be verified");
270             }else
271                 if(recoverResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_REFUSED)){
272                     getPrintStream().println("The user doesn't seem to have the wrong status.");
273                 }else{
274                     getPrintStream().println("Error occured during processing : " + recoverResultType.getResultMinor());
275                 }
276     }
277
278     
279     /**
280      * Returns the encoding that the data should be written in
281      * @return
282      */

283     private String JavaDoc useEncoding(String JavaDoc arg){
284         if(arg.equalsIgnoreCase(ENCODING_PEM)){
285             return ENCODING_PEM;
286         }
287         
288         if(arg.equalsIgnoreCase(ENCODING_P12)){
289             return ENCODING_P12;
290         }
291         
292         if(arg.equalsIgnoreCase(ENCODING_JKS)){
293             return ENCODING_JKS;
294         }
295         
296         getPrintStream().println("Illegal encoding (should be pem, p12 or jks) : " + arg);
297         usage();
298         System.exit(-1);
299         return null;
300     }
301
302
303     
304     protected void usage() {
305         getPrintStream().println("Command used to recover the private key of a certificate");
306         getPrintStream().println("Usage : recover <cert file name> <cert encoding (der|pem)> <password> <keystore encoding pem|p12|jks> <outputpath (optional)> \n\n");
307         getPrintStream().println("Certificate encoding of the certificate about to recover key for, PEM and DER supported.\n");
308         getPrintStream().println("Password used to authenticate to the XKMS service.\n");
309         getPrintStream().println("Use pem, p12 or jks for encoding of the generated keystore.\n");
310         getPrintStream().println("Outputpath specifies to which directory to write the keystore to, current directory is used if omitted\n\n");
311         getPrintStream().println("Example: recover lostcert.pem pem \"foo123\" pem");
312         getPrintStream().println("Recovers the key to the lostcert.pem certificate and writes it in PEM encoding in the current directory");
313         
314                         
315     }
316
317
318 }
319
Popular Tags