1 13 14 package org.ejbca.core.model.ca.catoken; 15 16 import java.security.KeyPair ; 17 import java.security.KeyStore ; 18 import java.security.PrivateKey ; 19 import java.security.PublicKey ; 20 import java.security.cert.Certificate ; 21 import java.security.cert.X509Certificate ; 22 import java.security.interfaces.RSAPublicKey ; 23 import java.util.Enumeration ; 24 import java.util.HashMap ; 25 26 import javax.naming.InitialContext ; 27 28 import org.apache.log4j.Logger; 29 import org.bouncycastle.jce.ECNamedCurveTable; 30 import org.bouncycastle.jce.interfaces.ECPrivateKey; 31 import org.bouncycastle.jce.interfaces.ECPublicKey; 32 import org.ejbca.core.ejb.ServiceLocator; 33 import org.ejbca.core.model.InternalResources; 34 import org.ejbca.core.model.SecConst; 35 import org.ejbca.core.model.ca.caadmin.IllegalKeyStoreException; 36 import org.ejbca.util.Base64; 37 import org.ejbca.util.CertTools; 38 import org.ejbca.util.KeyTools; 39 40 45 public class SoftCAToken extends CAToken implements java.io.Serializable { 46 47 48 private static final Logger log = Logger.getLogger(SoftCAToken.class); 49 50 private static final InternalResources intres = InternalResources.getInstance(); 51 52 55 public static final float LATEST_VERSION = 3; 56 57 private static final String PROVIDER = "BC"; 58 59 private PrivateKey privateSignKey = null; 60 private PrivateKey privateDecKey = null; 61 private PublicKey publicSignKey = null; 62 private PublicKey publicEncKey = null; 63 private Certificate encCert = null; 64 65 private static final String PRIVATESIGNKEYALIAS = "privatesignkeyalias"; 66 private static final String PRIVATEDECKEYALIAS = "privatedeckeyalias"; 67 68 protected static final String SIGNKEYSPEC = "SIGNKEYSPEC"; 69 protected static final String ENCKEYSPEC = "ENCKEYSPEC"; 70 protected static final String SIGNKEYALGORITHM = "SIGNKEYALGORITHM"; 71 protected static final String ENCKEYALGORITHM = "ENCKEYALGORITHM"; 72 protected static final String KEYSTORE = "KEYSTORE"; 73 74 75 protected static final String KEYALGORITHM = "KEYALGORITHM"; 76 77 protected static final String KEYSIZE = "KEYSIZE"; 78 79 public SoftCAToken(){ 80 data = new HashMap (); 81 data.put(CATOKENTYPE, new Integer (CATokenInfo.CATOKENTYPE_P12)); 82 data.put(VERSION, new Float (LATEST_VERSION)); 83 } 84 85 public SoftCAToken(HashMap data) throws IllegalArgumentException , IllegalKeyStoreException { 86 loadData(data); 87 if(data.get(KEYSTORE) != null){ 88 String keystorepass = ServiceLocator.getInstance().getString("java:comp/env/keyStorePass"); 90 if (keystorepass == null) 91 throw new IllegalArgumentException ("Missing keyStorePass property."); 92 try { 93 KeyStore keystore=KeyStore.getInstance("PKCS12", "BC"); 94 keystore.load(new java.io.ByteArrayInputStream (Base64.decode(((String ) data.get(KEYSTORE)).getBytes())),keystorepass.toCharArray()); 95 96 this.privateSignKey = (PrivateKey ) keystore.getKey(PRIVATESIGNKEYALIAS, null); 97 this.privateDecKey = (PrivateKey ) keystore.getKey(PRIVATEDECKEYALIAS, null); 98 99 this.publicSignKey = keystore.getCertificateChain(PRIVATESIGNKEYALIAS)[0].getPublicKey(); 100 this.encCert = keystore.getCertificateChain(PRIVATEDECKEYALIAS)[0]; 101 this.publicEncKey = this.encCert.getPublicKey(); 102 103 } catch (Exception e) { 104 throw new IllegalKeyStoreException(e); 105 } 106 107 data.put(CATOKENTYPE, new Integer (CATokenInfo.CATOKENTYPE_P12)); 108 } 109 } 110 111 114 public void generateKeys(CATokenInfo catokeninfo) throws Exception { 115 116 String keystorepass = ServiceLocator.getInstance().getString("java:comp/env/keyStorePass"); 118 SoftCATokenInfo info = (SoftCATokenInfo) catokeninfo; 120 String signkeyspec = info.getSignKeySpec(); 121 KeyStore keystore = KeyStore.getInstance("PKCS12", "BC"); 122 keystore.load(null, null); 123 124 KeyPair signkeys = KeyTools.genKeys(signkeyspec, info.getSignKeyAlgorithm()); 126 Certificate [] certchain = new Certificate [1]; 128 certchain[0] = CertTools.genSelfCert("CN=dummy", 36500, null, signkeys.getPrivate(), signkeys.getPublic(), info.getSignatureAlgorithm(), true); 129 130 keystore.setKeyEntry(PRIVATESIGNKEYALIAS,signkeys.getPrivate(),null, certchain); 131 132 String enckeyspec = info.getEncKeySpec(); 135 KeyPair enckeys = KeyTools.genKeys(enckeyspec, info.getEncKeyAlgorithm()); 136 certchain[0] = CertTools.genSelfCert("CN=dummy2", 36500, null, enckeys.getPrivate(), enckeys.getPublic(), info.getEncryptionAlgorithm(), true); 138 this.encCert = certchain[0]; 139 keystore.setKeyEntry(PRIVATEDECKEYALIAS,enckeys.getPrivate(),null,certchain); 140 java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream (); 141 keystore.store(baos, keystorepass.toCharArray()); 142 data.put(KEYSTORE, new String (Base64.encode(baos.toByteArray()))); 143 data.put(SIGNKEYSPEC, signkeyspec); 144 data.put(SIGNKEYALGORITHM, info.getSignKeyAlgorithm()); 145 data.put(SIGNATUREALGORITHM, info.getSignatureAlgorithm()); 146 data.put(ENCKEYSPEC, enckeyspec); 147 data.put(ENCKEYALGORITHM, info.getEncKeyAlgorithm()); 148 data.put(ENCRYPTIONALGORITHM, info.getEncryptionAlgorithm()); 149 this.publicSignKey = signkeys.getPublic(); 151 this.privateSignKey = signkeys.getPrivate(); 152 153 this.publicEncKey = enckeys.getPublic(); 154 this.privateDecKey = enckeys.getPrivate(); 155 } 156 157 161 public void importKeysFromP12(PrivateKey p12privatekey, PublicKey p12publickey, PrivateKey p12PrivateEncryptionKey, 162 PublicKey p12PublicEncryptionKey, Certificate [] caSignatureCertChain) throws Exception { 163 InitialContext ictx = new InitialContext (); 165 String keystorepass = (String ) ictx.lookup("java:comp/env/keyStorePass"); 166 if (keystorepass == null) 167 throw new IllegalArgumentException ("Missing keyStorePass property."); 168 169 KeyStore keystore = KeyStore.getInstance("PKCS12", "BC"); 171 keystore.load(null,null); 172 173 String certSignatureAlgorithm = ((X509Certificate ) caSignatureCertChain[0]).getSigAlgName(); 175 String signatureAlgorithm = null; 176 String keyAlg = null; 177 if ( p12publickey instanceof RSAPublicKey ) { 178 keyAlg = CATokenInfo.KEYALGORITHM_RSA; 179 if (certSignatureAlgorithm.indexOf("256") == -1) { 180 signatureAlgorithm = CATokenInfo.SIGALG_SHA1_WITH_RSA; 181 } else { 182 signatureAlgorithm = CATokenInfo.SIGALG_SHA256_WITH_RSA; 183 } 184 } else { 185 keyAlg = CATokenInfo.KEYALGORITHM_ECDSA; 186 if (certSignatureAlgorithm.indexOf("256") == -1) { 187 signatureAlgorithm = CATokenInfo.SIGALG_SHA1_WITH_ECDSA; 188 } else { 189 signatureAlgorithm = CATokenInfo.SIGALG_SHA256_WITH_ECDSA; 190 } 191 } 192 193 String keyspec = null; 195 if ( p12publickey instanceof RSAPublicKey ) { 196 keyspec = Integer.toString( ((RSAPublicKey ) p12publickey).getModulus().bitLength() ); 197 log.debug("KeySize="+keyspec); 198 } else { 199 Enumeration en = ECNamedCurveTable.getNames(); 200 while ( en.hasMoreElements() ) { 201 String currentCurveName = (String ) en.nextElement(); 202 if ( (ECNamedCurveTable.getParameterSpec(currentCurveName)).getCurve().equals( ((ECPrivateKey) p12privatekey).getParameters().getCurve() ) ) { 203 keyspec = currentCurveName; 204 break; 205 } 206 } 207 208 if ( keyspec==null ) { 209 keyspec = "unknown"; 210 } 211 p12privatekey = (ECPrivateKey) p12privatekey; 212 p12publickey = (ECPublicKey) p12publickey; 213 log.debug("ECName="+keyspec); 214 } 215 keystore.setKeyEntry(PRIVATESIGNKEYALIAS, p12privatekey, null, caSignatureCertChain); 216 data.put(SIGNKEYSPEC, keyspec); 217 data.put(SIGNKEYALGORITHM, keyAlg); 218 data.put(SIGNATUREALGORITHM, signatureAlgorithm); 219 220 String encryptionSignatureAlgorithm = signatureAlgorithm; 223 keyAlg = CATokenInfo.KEYALGORITHM_RSA; 224 keyspec = "2048"; 225 if ( signatureAlgorithm.equals(CATokenInfo.SIGALG_SHA256_WITH_ECDSA) ) { 226 encryptionSignatureAlgorithm = CATokenInfo.SIGALG_SHA256_WITH_RSA; 227 } else if ( signatureAlgorithm.equals(CATokenInfo.SIGALG_SHA1_WITH_ECDSA) ) { 228 encryptionSignatureAlgorithm = CATokenInfo.SIGALG_SHA1_WITH_RSA; 229 } 230 KeyPair enckeys = null; 231 if ( p12PublicEncryptionKey == null || p12PrivateEncryptionKey == null ) { 232 enckeys = KeyTools.genKeys(keyspec, keyAlg); 233 } 234 else { 235 enckeys = new KeyPair (p12PublicEncryptionKey, p12PrivateEncryptionKey); 236 } 237 Certificate [] certchain = new Certificate [1]; 239 certchain[0] = CertTools.genSelfCert("CN=dummy2", 36500, null, enckeys.getPrivate(), enckeys.getPublic(), encryptionSignatureAlgorithm, true); 240 this.encCert = certchain[0]; 241 keystore.setKeyEntry(PRIVATEDECKEYALIAS,enckeys.getPrivate(),null,certchain); 242 243 java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream (); 244 keystore.store(baos, keystorepass.toCharArray()); 245 data.put(KEYSTORE, new String (Base64.encode(baos.toByteArray()))); 246 data.put(ENCKEYSPEC, keyspec); 247 data.put(ENCKEYALGORITHM, keyAlg); 248 data.put(ENCRYPTIONALGORITHM, encryptionSignatureAlgorithm); 249 250 this.publicSignKey = p12publickey; 252 this.privateSignKey = p12privatekey; 253 254 this.publicEncKey = enckeys.getPublic(); 255 this.privateDecKey = enckeys.getPrivate(); 256 } 257 258 public CATokenInfo getCATokenInfo(){ 259 SoftCATokenInfo info = new SoftCATokenInfo(); 260 261 info.setSignKeySpec((String ) data.get(SIGNKEYSPEC)); 262 info.setSignKeyAlgorithm((String ) data.get(SIGNKEYALGORITHM)); 263 info.setSignatureAlgorithm((String ) data.get(SIGNATUREALGORITHM)); 264 265 info.setEncKeySpec((String ) data.get(ENCKEYSPEC)); 266 info.setEncKeyAlgorithm((String ) data.get(ENCKEYALGORITHM)); 267 info.setEncryptionAlgorithm((String ) data.get(ENCRYPTIONALGORITHM)); 268 269 return info; 270 } 271 272 275 public void updateCATokenInfo(CATokenInfo catokeninfo){ 276 } 278 279 284 public PrivateKey getPrivateKey(int purpose){ 285 if(purpose == SecConst.CAKEYPURPOSE_KEYENCRYPT) 286 return this.privateDecKey; 287 288 return privateSignKey; 289 } 290 291 296 public PublicKey getPublicKey(int purpose){ 297 if(purpose == SecConst.CAKEYPURPOSE_KEYENCRYPT) 298 return this.publicEncKey; 299 300 return publicSignKey; 301 } 302 303 304 308 public String getProvider(){ 309 return PROVIDER; 310 } 311 312 313 public float getLatestVersion(){ 314 return LATEST_VERSION; 315 } 316 317 318 319 public void upgrade(){ 320 if(Float.compare(LATEST_VERSION, getVersion()) != 0) { 321 String msg = intres.getLocalizedMessage("catoken.upgradesoft", new Float (getVersion())); 323 log.info(msg); 324 if(data.get(SIGNKEYALGORITHM) == null) { 325 String oldKeyAlg = (String )data.get(KEYALGORITHM); 326 data.put(SIGNKEYALGORITHM, oldKeyAlg); 327 data.put(ENCKEYALGORITHM, oldKeyAlg); 328 } 329 if(data.get(SIGNKEYSPEC) == null) { 330 Integer oldKeySize = ((Integer ) data.get(KEYSIZE)); 331 data.put(SIGNKEYSPEC, oldKeySize.toString()); 332 data.put(ENCKEYSPEC, oldKeySize.toString()); 333 } 334 if(data.get(ENCRYPTIONALGORITHM) == null) { 335 String signAlg = (String )data.get(SIGNATUREALGORITHM); 336 data.put(ENCRYPTIONALGORITHM, signAlg); 337 } 338 339 data.put(VERSION, new Float (LATEST_VERSION)); 340 } 341 } 342 343 348 public void activate(String authenticationcode) throws CATokenAuthenticationFailedException, CATokenOfflineException { 349 } 351 352 355 public boolean deactivate() { 356 return true; 358 } 359 360 361 } 362 363 | Popular Tags |