KickJava   Java API By Example, From Geeks To Geeks.

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


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.KeyPair JavaDoc;
17 import java.security.KeyStore JavaDoc;
18 import java.security.PrivateKey JavaDoc;
19 import java.security.cert.Certificate JavaDoc;
20 import java.security.cert.CertificateException JavaDoc;
21 import java.security.cert.X509Certificate JavaDoc;
22 import java.security.interfaces.RSAPublicKey JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27
28 import javax.xml.bind.JAXBElement;
29
30 import org.ejbca.core.protocol.xkms.common.XKMSConstants;
31 import org.ejbca.core.protocol.xkms.common.XKMSUtil;
32 import org.ejbca.ui.cli.ErrorAdminCommandException;
33 import org.ejbca.ui.cli.IAdminCommand;
34 import org.ejbca.ui.cli.IllegalAdminCommandException;
35 import org.ejbca.util.CertTools;
36 import org.ejbca.util.KeyTools;
37 import org.w3._2000._09.xmldsig_.KeyInfoType;
38 import org.w3._2000._09.xmldsig_.RSAKeyValueType;
39 import org.w3._2000._09.xmldsig_.X509DataType;
40 import org.w3._2002._03.xkms_.KeyBindingType;
41 import org.w3._2002._03.xkms_.ObjectFactory;
42 import org.w3._2002._03.xkms_.PrototypeKeyBindingType;
43 import org.w3._2002._03.xkms_.RegisterRequestType;
44 import org.w3._2002._03.xkms_.RegisterResultType;
45 import org.w3._2002._03.xkms_.UseKeyWithType;
46
47
48
49
50
51 /**
52  * Performes KRSS registre calls to an web service.
53  *
54  * @version $Id: RegisterCommand.java,v 1.1.2.2 2007/08/01 15:15:04 jeklund Exp $
55  * @author Philip Vendil
56  */

57 public class RegisterCommand extends XKMSCLIBaseCommand implements IAdminCommand{
58
59     private ObjectFactory xKMSObjectFactory = new ObjectFactory();
60     private org.w3._2000._09.xmldsig_.ObjectFactory sigFactory = new org.w3._2000._09.xmldsig_.ObjectFactory();
61     
62     private static final int ARG_DN = 1;
63     private static final int ARG_PASSWORD = 2;
64     private static final int ARG_REVOCATIONCODEID = 3;
65     private static final int ARG_KEYSIZE = 4;
66     private static final int ARG_ENCODING = 5;
67     private static final int ARG_OUTPUTPATH = 6;
68         
69    
70     
71     /**
72      * Creates a new instance of RaAddUserCommand
73      *
74      * @param args command line arguments
75      */

76     public RegisterCommand(String JavaDoc[] args) {
77         super(args);
78     }
79
80     /**
81      * Runs the command
82      *
83      * @throws IllegalAdminCommandException Error in command args
84      * @throws ErrorAdminCommandException Error running command
85      */

86     public void execute() throws IllegalAdminCommandException, ErrorAdminCommandException {
87         
88         try {
89            
90             if(args.length < 6 || args.length > 7){
91                 usage();
92                 System.exit(-1);
93             }
94             
95             String JavaDoc subjectDN = args[ARG_DN];
96             String JavaDoc password = args[ARG_PASSWORD];
97             
98             String JavaDoc revocationCodeId = args[ARG_REVOCATIONCODEID];
99                         
100             String JavaDoc encoding = useEncoding(args[ARG_ENCODING]);
101             
102             int keySize = getKeySize(args[ARG_KEYSIZE]);
103             
104             
105             String JavaDoc outputPath = "";
106             if(args.length >= ARG_OUTPUTPATH +1){
107                 if(args[ARG_OUTPUTPATH] != null){
108                   outputPath = args[ARG_OUTPUTPATH] + "/";
109                 }
110             }
111
112             KeyPair JavaDoc genKeys = null;
113             if(keySize != 0){
114               genKeys = KeyTools.genKeys(Integer.toString(keySize), "RSA");
115             }
116             
117             String JavaDoc keyBindingId = genId();
118             PrototypeKeyBindingType prototypeKeyBinding = xKMSObjectFactory.createPrototypeKeyBindingType();
119             prototypeKeyBinding.setId(keyBindingId);
120             UseKeyWithType useKeyWithType = xKMSObjectFactory.createUseKeyWithType();
121             useKeyWithType.setApplication(XKMSConstants.USEKEYWITH_PKIX);
122             useKeyWithType.setIdentifier(subjectDN);
123             prototypeKeyBinding.getUseKeyWith().add(useKeyWithType);
124             
125             if(revocationCodeId != null && !revocationCodeId.equalsIgnoreCase("NULL")){
126                 byte[] first = XKMSUtil.getSecretKeyFromPassphrase(revocationCodeId, true,20, XKMSUtil.KEY_REVOCATIONCODEIDENTIFIER_PASS1).getEncoded();
127                 byte[] second = XKMSUtil.getSecretKeyFromPassphrase(new String JavaDoc(first,"ISO8859-1"), false,20, XKMSUtil.KEY_REVOCATIONCODEIDENTIFIER_PASS2).getEncoded();
128                 prototypeKeyBinding.setRevocationCodeIdentifier(second);
129             }
130             
131             String JavaDoc reqId = genId();
132             RegisterRequestType registerRequestType = xKMSObjectFactory.createRegisterRequestType();
133             registerRequestType.setId(reqId);
134             registerRequestType.getRespondWith().add(XKMSConstants.RESPONDWITH_X509CHAIN);
135             if(keySize == 0){
136               registerRequestType.getRespondWith().add(XKMSConstants.RESPONDWITH_PRIVATEKEY);
137             }
138             registerRequestType.setPrototypeKeyBinding(prototypeKeyBinding);
139             
140             RegisterResultType registerResultType = null;
141             if(genKeys == null){
142                 registerResultType = getXKMSInvoker().register(registerRequestType, clientCert, privateKey, password, null, keyBindingId);
143             }else{
144                 KeyInfoType keyInfoType = sigFactory.createKeyInfoType();
145                 RSAKeyValueType rsaKeyValueType = sigFactory.createRSAKeyValueType();
146                 rsaKeyValueType.setExponent(((RSAPublicKey JavaDoc) genKeys.getPublic()).getPublicExponent().toByteArray());
147                 rsaKeyValueType.setModulus(((RSAPublicKey JavaDoc) genKeys.getPublic()).getModulus().toByteArray());
148                 JAXBElement<RSAKeyValueType> rsaKeyValue = sigFactory.createRSAKeyValue(rsaKeyValueType);
149                 keyInfoType.getContent().add(rsaKeyValue);
150                 
151                 prototypeKeyBinding.setKeyInfo(keyInfoType);
152                 
153                 registerResultType = getXKMSInvoker().register(registerRequestType, clientCert, privateKey, password, genKeys.getPrivate(), keyBindingId);
154             }
155             
156             if(registerResultType.getResultMajor().equals(XKMSConstants.RESULTMAJOR_SUCCESS) &&
157                registerResultType.getResultMinor() == null){
158             
159                 if(registerResultType.getKeyBinding().size() >0){
160                     KeyBindingType keyBinding = registerResultType.getKeyBinding().get(0);
161                     List JavaDoc certs = getCertsFromKeyBinding(keyBinding);
162                       
163                     X509Certificate JavaDoc userCert = getUserCert(certs);
164                     certs.remove(userCert);
165                     
166                     if(registerResultType.getPrivateKey() != null){
167                         PrivateKey JavaDoc serverKey = XKMSUtil.getPrivateKeyFromEncryptedXML(registerResultType.getPrivateKey(), password);
168                         createKeyStore(userCert, certs, serverKey,password,encoding,outputPath);
169                     }else{
170                         createKeyStore(userCert, certs,genKeys.getPrivate(),password,encoding,outputPath);
171                     }
172
173                 }
174    
175             }else{
176                 displayRequestErrors(registerResultType);
177             }
178     
179         } catch (Exception JavaDoc e) {
180             throw new ErrorAdminCommandException(e);
181         }
182     }
183
184     private X509Certificate JavaDoc getUserCert(Collection JavaDoc certs) {
185         X509Certificate JavaDoc retval = null;
186         Iterator JavaDoc iter = certs.iterator();
187         while(iter.hasNext()){
188             X509Certificate JavaDoc next = (X509Certificate JavaDoc) iter.next();
189             if(next.getBasicConstraints() == -1){
190                 retval = next;
191                 break;
192             }
193         }
194         
195         return retval;
196     }
197
198     private void createKeyStore(X509Certificate JavaDoc userCert, List JavaDoc caCerts, PrivateKey JavaDoc privKey, String JavaDoc password, String JavaDoc encoding, String JavaDoc outputPath) throws Exception JavaDoc {
199         boolean createJKS = false;
200         boolean createPEM = false;
201         if(encoding.equals(ENCODING_JKS)){
202             createJKS = true;
203         }
204         if(encoding.equals(ENCODING_PEM)){
205             createPEM = true;
206         }
207         
208         String JavaDoc alias = getAlias(userCert);
209         
210         Certificate JavaDoc[] caChain = new Certificate JavaDoc[caCerts.size()];
211         for(int i=0;i<caCerts.size();i++){
212             caChain[i] = (Certificate JavaDoc) caCerts.get(i);
213         }
214         
215         // Store keys and certificates in keystore.
216
KeyStore JavaDoc ks = null;
217
218         if (createJKS) {
219             ks = KeyTools.createJKS(alias, privKey, password, userCert, caChain);
220         } else {
221             ks = KeyTools.createP12(alias, privKey, userCert, caChain);
222         }
223
224         storeKeyStore(ks, alias, password, createJKS, createPEM, outputPath);
225         
226     }
227
228     private String JavaDoc getAlias(X509Certificate JavaDoc userCert) {
229         String JavaDoc alias = CertTools.getPartFromDN(CertTools.getSubjectDN(userCert), "CN");
230         if (alias == null) alias = "myKey";
231         return alias;
232     }
233
234     private List JavaDoc getCertsFromKeyBinding(KeyBindingType keyBinding) throws CertificateException JavaDoc {
235         ArrayList JavaDoc retval = new ArrayList JavaDoc();
236         
237         JAXBElement<X509DataType> jAXBX509Data = (JAXBElement<X509DataType>) keyBinding.getKeyInfo().getContent().get(0);
238         Iterator JavaDoc iter2 = jAXBX509Data.getValue().getX509IssuerSerialOrX509SKIOrX509SubjectName().iterator();
239         while(iter2.hasNext()){
240             JAXBElement next = (JAXBElement) iter2.next();
241             if(next.getName().getLocalPart().equals("X509Certificate")){
242               byte[] encoded = (byte[]) next.getValue();
243               X509Certificate JavaDoc nextCert = CertTools.getCertfromByteArray(encoded);
244               retval.add(nextCert);
245             }
246         }
247         
248         return retval;
249     }
250
251     private void displayRequestErrors(RegisterResultType registerResultType) {
252         if(registerResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_NOMATCH)){
253             getPrintStream().println("Error no user with given subjectDN could be found");
254         }else
255             if(registerResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_NOAUTHENTICATION)){
256                 getPrintStream().println("Error password couldn't be verified");
257             }else
258                 if(registerResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_REFUSED)){
259                     getPrintStream().println("The user doesn't seem to have the wrong status.");
260                 }else{
261                     getPrintStream().println("Error occured during processing : " + registerResultType.getResultMinor());
262                 }
263     }
264
265     private int getKeySize(String JavaDoc keySize) {
266         int retval =0;
267         try{
268            if(!keySize.equalsIgnoreCase("NOGEN")){
269              retval = Integer.parseInt(keySize);
270              
271              if(retval != 512 && retval != 1024 && retval != 2048 && retval != 4096){
272                 getPrintStream().println("Illegal keysize : should be a number of 512, 1024, 2048, 4096 or 'NOGEN': " + keySize);
273                 usage();
274                 System.exit(-1);
275              }
276            }
277            
278            
279         }catch(NumberFormatException JavaDoc e){
280             getPrintStream().println("Illegal keysize : should be a number or 'NOGEN': " + keySize);
281             usage();
282             System.exit(-1);
283         }
284         return retval;
285     }
286
287     
288     /**
289      * Returns the encoding that the data should be written in
290      * @return
291      */

292     private String JavaDoc useEncoding(String JavaDoc arg){
293         if(arg.equalsIgnoreCase(ENCODING_PEM)){
294             return ENCODING_PEM;
295         }
296         
297         if(arg.equalsIgnoreCase(ENCODING_P12)){
298             return ENCODING_P12;
299         }
300         
301         if(arg.equalsIgnoreCase(ENCODING_JKS)){
302             return ENCODING_JKS;
303         }
304         
305         getPrintStream().println("Illegal encoding (should be pem, p12 or jks) : " + arg);
306         usage();
307         System.exit(-1);
308         return null;
309     }
310
311
312     
313     protected void usage() {
314         getPrintStream().println("Command used to register for a certificate");
315         getPrintStream().println("Usage : register <subjectDN> <password> <revocationCodeIdentifier> <keySize> <pem|p12|jks> <outputpath (optional)> \n\n");
316         getPrintStream().println("The revocationCodeIdentifier is a passphrase or 'NULL' if it isn't used.\n");
317         getPrintStream().println("keySize of the generated RSA keys, are only used for client generated keys, use 'NOGEN' othervise.\n");
318         getPrintStream().println("Use pem, p12 or jks for encoding of the generated keystore.\n");
319         getPrintStream().println("Outputpath specifies to which directory to write the keystore to, current directory is used if omitted\n\n");
320         getPrintStream().println("Example: register \"CN=Test Testarson,O=someorg\" \"foo123\" \"My passphrase\" 2048 pem");
321         getPrintStream().println("Issues a certificate to to \"CN=Test Testarson,O=someorg\" and writes it in PEM encoding in the current directory");
322         
323                         
324     }
325
326
327 }
328
Popular Tags