1 13 14 package org.ejbca.core.protocol.xkms.client; 15 16 import java.io.FileInputStream ; 17 import java.security.KeyStore ; 18 import java.security.PrivateKey ; 19 import java.security.cert.Certificate ; 20 import java.security.cert.CertificateException ; 21 import java.security.cert.X509Certificate ; 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 27 import javax.xml.bind.JAXBElement; 28 29 import org.ejbca.core.protocol.xkms.common.XKMSConstants; 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_.ReissueRequestType; 40 import org.w3._2002._03.xkms_.ReissueResultType; 41 42 43 44 45 46 52 public class ReissueCommand 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_KEYSTORE = 1; 58 private static final int ARG_ALIAS = 2; 59 private static final int ARG_KEYSTOREPASSWORD = 3; 60 private static final int ARG_AUTHPASSWORD = 4; 61 private static final int ARG_ENCODING = 5; 62 private static final int ARG_OUTPUTPATH = 6; 63 64 65 66 71 public ReissueCommand(String [] args) { 72 super(args); 73 } 74 75 81 public void execute() throws IllegalAdminCommandException, ErrorAdminCommandException { 82 83 try { 84 85 if(args.length < 6 || args.length > 7){ 86 usage(); 87 System.exit(-1); 88 } 89 90 String keyPass = args[ARG_KEYSTOREPASSWORD]; 91 String authPass = args[ARG_AUTHPASSWORD]; 92 String alias = args[ARG_ALIAS]; 93 String encoding = useEncoding(args[ARG_ENCODING]); 94 95 KeyStore ks = readKeyStore(args[ARG_KEYSTORE],encoding, keyPass); 96 X509Certificate orgCert = (X509Certificate ) ks.getCertificate(alias); 97 98 String outputPath = ""; 99 if(args.length >= ARG_OUTPUTPATH +1){ 100 if(args[ARG_OUTPUTPATH] != null){ 101 outputPath = args[ARG_OUTPUTPATH] + "/"; 102 } 103 } 104 105 String reqId = genId(); 106 ReissueRequestType reissueRequestType = xKMSObjectFactory.createReissueRequestType(); 107 reissueRequestType.setId(reqId); 108 reissueRequestType.getRespondWith().add(XKMSConstants.RESPONDWITH_X509CHAIN); 109 110 String keyBindingId = "_" + orgCert.getSerialNumber().toString(); 111 X509DataType x509DataType = sigFactory.createX509DataType(); 112 x509DataType.getX509IssuerSerialOrX509SKIOrX509SubjectName().add(sigFactory.createX509DataTypeX509Certificate(orgCert.getEncoded())); 113 KeyInfoType keyInfoType = sigFactory.createKeyInfoType(); 114 keyInfoType.getContent().add(sigFactory.createX509Data(x509DataType)); 115 116 KeyBindingType keyBindingType = xKMSObjectFactory.createKeyBindingType(); 117 keyBindingType.setKeyInfo(keyInfoType); 118 keyBindingType.setId(keyBindingId); 119 reissueRequestType.setReissueKeyBinding(keyBindingType); 120 121 PrivateKey privateKey = (PrivateKey ) ks.getKey(alias, keyPass.toCharArray()); 122 ReissueResultType reissueResultType = getXKMSInvoker().reissue(reissueRequestType, clientCert, privateKey, authPass, privateKey, keyBindingId); 123 124 if(reissueResultType.getResultMajor().equals(XKMSConstants.RESULTMAJOR_SUCCESS) && 125 reissueResultType.getResultMinor() == null){ 126 127 if(reissueResultType.getKeyBinding().size() >0){ 128 KeyBindingType keyBinding = reissueResultType.getKeyBinding().get(0); 129 List certs = getCertsFromKeyBinding(keyBinding); 130 131 X509Certificate userCert = getUserCert(certs); 132 certs.remove(userCert); 133 134 createKeyStore(alias, userCert, certs,privateKey,keyPass,encoding,outputPath); 135 136 } 137 138 }else{ 139 displayRequestErrors(reissueResultType); 140 } 141 142 } catch (Exception e) { 143 throw new ErrorAdminCommandException(e); 144 } 145 } 146 147 private KeyStore readKeyStore(String keystorefilename, String encoding, String keyPass) { 148 KeyStore ks = null; 149 150 try { 151 if(encoding.equals(ENCODING_JKS)){ 152 ks = KeyStore.getInstance("JKS"); 153 ks.load(new FileInputStream (keystorefilename), keyPass.toCharArray()); 154 } 155 156 if(encoding.equals(ENCODING_P12)){ 157 ks = KeyStore.getInstance("PKCS12"); 158 ks.load(new FileInputStream (keystorefilename), keyPass.toCharArray()); 159 } 160 } catch (Exception e) { 161 getPrintStream().println("Error reading keystore " + keystorefilename + " from file : " + e.getMessage()); 162 usage(); 163 System.exit(-1); 164 } 165 166 167 return ks; 168 } 169 170 private X509Certificate getUserCert(Collection certs) { 171 X509Certificate retval = null; 172 Iterator iter = certs.iterator(); 173 while(iter.hasNext()){ 174 X509Certificate next = (X509Certificate ) iter.next(); 175 if(next.getBasicConstraints() == -1){ 176 retval = next; 177 break; 178 } 179 } 180 181 return retval; 182 } 183 184 private void createKeyStore(String alias, X509Certificate userCert, List caCerts, PrivateKey privKey, String password, String encoding, String outputPath) throws Exception { 185 boolean createJKS = false; 186 if(encoding.equals(ENCODING_JKS)){ 187 createJKS = true; 188 } 189 190 Certificate [] caChain = new Certificate [caCerts.size()]; 191 for(int i=0;i<caCerts.size();i++){ 192 caChain[i] = (Certificate ) caCerts.get(i); 193 } 194 195 KeyStore ks = null; 197 198 if (createJKS) { 199 ks = KeyTools.createJKS(alias, privKey, password, userCert, caChain); 200 } else { 201 ks = KeyTools.createP12(alias, privKey, userCert, caChain); 202 } 203 204 storeKeyStore(ks, alias, password, createJKS, false, outputPath); 205 206 } 207 208 209 210 private List getCertsFromKeyBinding(KeyBindingType keyBinding) throws CertificateException { 211 ArrayList retval = new ArrayList (); 212 213 JAXBElement<X509DataType> jAXBX509Data = (JAXBElement<X509DataType>) keyBinding.getKeyInfo().getContent().get(0); 214 Iterator iter2 = jAXBX509Data.getValue().getX509IssuerSerialOrX509SKIOrX509SubjectName().iterator(); 215 while(iter2.hasNext()){ 216 JAXBElement next = (JAXBElement) iter2.next(); 217 if(next.getName().getLocalPart().equals("X509Certificate")){ 218 byte[] encoded = (byte[]) next.getValue(); 219 X509Certificate nextCert = CertTools.getCertfromByteArray(encoded); 220 retval.add(nextCert); 221 } 222 } 223 224 return retval; 225 } 226 227 private void displayRequestErrors(ReissueResultType reissueResultType) { 228 if(reissueResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_NOMATCH)){ 229 getPrintStream().println("Error no user could be found for the given certiifcate."); 230 }else 231 if(reissueResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_NOAUTHENTICATION)){ 232 getPrintStream().println("Error password couldn't be verified"); 233 }else 234 if(reissueResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_REFUSED)){ 235 getPrintStream().println("The user doesn't seem to have the wrong status."); 236 }else{ 237 getPrintStream().println("Error occured during processing : " + reissueResultType.getResultMinor()); 238 } 239 } 240 241 242 243 247 private String useEncoding(String arg){ 248 249 if(arg.equalsIgnoreCase(ENCODING_P12)){ 250 return ENCODING_P12; 251 } 252 253 if(arg.equalsIgnoreCase(ENCODING_JKS)){ 254 return ENCODING_JKS; 255 } 256 257 getPrintStream().println("Illegal encoding (should be p12 or jks) : " + arg); 258 usage(); 259 System.exit(-1); 260 return null; 261 } 262 263 264 265 protected void usage() { 266 getPrintStream().println("Command used to reissue an existing certificate"); 267 getPrintStream().println("Usage : reissue <keystore> <alias> <keypass> <authenticationpassword> <p12|jks> <outputpath (optional)> \n\n"); 268 getPrintStream().println("Keystore is the p12 or jks about to be renewed.\n"); 269 getPrintStream().println("alias of the key in the keystore (use 'NOALIAS' for p12).\n"); 270 getPrintStream().println("keypass is the password to unlock the keystore.\n"); 271 getPrintStream().println("authenticationpassword is the password used to authenticate against the XKMS service.\n"); 272 getPrintStream().println("Use p12 or jks for encoding of the generated keystore.\n"); 273 getPrintStream().println("Outputpath specifies to which directory to write the new keystore to, current directory is used if omitted\n\n"); 274 getPrintStream().println("Example: reissue oldkey.p12 NOALIAS foo123 xkmspassword p12"); 275 getPrintStream().println("Generates a new keystore using the keys in the oldkey.p12"); 276 277 278 } 279 280 281 } 282 | Popular Tags |