1 package se.anatom.ejbca.protocol; 2 3 import java.io.IOException ; 4 import java.security.InvalidAlgorithmParameterException ; 5 import java.security.InvalidKeyException ; 6 import java.security.KeyPair ; 7 import java.security.NoSuchAlgorithmException ; 8 import java.security.NoSuchProviderException ; 9 import java.security.SecureRandom ; 10 import java.security.SignatureException ; 11 import java.security.cert.CertStore ; 12 import java.security.cert.CertStoreException ; 13 import java.security.cert.CertificateEncodingException ; 14 import java.security.cert.CollectionCertStoreParameters ; 15 import java.security.cert.X509Certificate ; 16 import java.util.ArrayList ; 17 import java.util.Hashtable ; 18 19 import org.apache.log4j.Logger; 20 import org.bouncycastle.asn1.ASN1EncodableVector; 21 import org.bouncycastle.asn1.DERObjectIdentifier; 22 import org.bouncycastle.asn1.DEROctetString; 23 import org.bouncycastle.asn1.DERPrintableString; 24 import org.bouncycastle.asn1.DERSequence; 25 import org.bouncycastle.asn1.DERSet; 26 import org.bouncycastle.asn1.DERUTF8String; 27 import org.bouncycastle.asn1.cms.Attribute; 28 import org.bouncycastle.asn1.cms.AttributeTable; 29 import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; 30 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 31 import org.bouncycastle.asn1.smime.SMIMECapability; 32 import org.bouncycastle.asn1.x509.X509Name; 33 import org.bouncycastle.cms.CMSEnvelopedData; 34 import org.bouncycastle.cms.CMSEnvelopedDataGenerator; 35 import org.bouncycastle.cms.CMSException; 36 import org.bouncycastle.cms.CMSProcessable; 37 import org.bouncycastle.cms.CMSProcessableByteArray; 38 import org.bouncycastle.cms.CMSSignedData; 39 import org.bouncycastle.cms.CMSSignedDataGenerator; 40 import org.bouncycastle.cms.CMSSignedGenerator; 41 import org.bouncycastle.jce.PKCS10CertificationRequest; 42 import org.ejbca.core.model.ca.catoken.CATokenConstants; 43 import org.ejbca.core.model.ca.catoken.CATokenInfo; 44 import org.ejbca.core.protocol.ScepRequestMessage; 45 import org.ejbca.core.protocol.ScepResponseMessage; 46 import org.ejbca.util.Base64; 47 import org.ejbca.util.CertTools; 48 import org.ejbca.util.KeyTools; 49 50 51 public class ScepRequestGenerator { 52 private static Logger log = Logger.getLogger(ScepResponseMessage.class); 53 54 private X509Certificate cert = null; 55 private X509Certificate cacert = null; 56 private String reqdn = null; 57 private KeyPair keys = null; 58 private String digestOid = CMSSignedGenerator.DIGEST_SHA1; 59 private PKCS10CertificationRequest p10request; 60 String keyspec = "1024"; 61 private String senderNonce = null; 62 private String transactionId = null; 63 64 public void setKeySpec(String spec) { 65 this.keyspec = spec; 66 } 67 public void setKeys(KeyPair myKeys) { 68 this.keys = myKeys; 69 } 70 public void setDigestOid(String oid) { 71 digestOid = oid; 72 } 73 75 public String getSenderNonce() { 76 return senderNonce; 77 } 78 public String getTransactionId() { 79 return transactionId; 80 } 81 public byte[] generateCrlReq(String dn, X509Certificate ca) throws NoSuchAlgorithmException , NoSuchProviderException , InvalidKeyException , SignatureException , IOException , CMSException, InvalidAlgorithmParameterException , CertStoreException , CertificateEncodingException , IllegalStateException { 82 this.cacert = ca; 83 this.reqdn = dn; 84 X509Name name = CertTools.stringToBcX509Name(cacert.getIssuerDN().getName()); 85 IssuerAndSerialNumber ias = new IssuerAndSerialNumber(name, cacert.getSerialNumber()); 86 cert = CertTools.genSelfCert(reqdn,24*60*60*1000,null,keys.getPrivate(),keys.getPublic(),CATokenInfo.SIGALG_SHA1_WITH_RSA,false); 88 89 byte[] msg = wrap(ias.getEncoded(), "22"); 91 return msg; 92 } 93 public byte[] generateCertReq(String dn, String password, X509Certificate ca) throws NoSuchAlgorithmException , NoSuchProviderException , InvalidKeyException , SignatureException , IOException , CMSException, InvalidAlgorithmParameterException , CertStoreException , CertificateEncodingException , IllegalStateException { 94 this.cacert = ca; 95 this.reqdn = dn; 96 if (keys == null) { 98 keys = KeyTools.genKeys(keyspec, CATokenConstants.KEYALGORITHM_RSA); 99 } 100 101 ASN1EncodableVector vec = new ASN1EncodableVector(); 109 vec.add(PKCSObjectIdentifiers.pkcs_9_at_challengePassword); 110 ASN1EncodableVector values = new ASN1EncodableVector(); 111 values.add(new DERUTF8String(password)); 112 vec.add(new DERSet(values)); 113 ASN1EncodableVector v = new ASN1EncodableVector(); 114 v.add(new DERSequence(vec)); 115 DERSet set = new DERSet(v); 116 p10request = new PKCS10CertificationRequest("SHA1WithRSA", 118 CertTools.stringToBcX509Name(reqdn), keys.getPublic(), set, keys.getPrivate()); 119 120 cert = CertTools.genSelfCert(reqdn,24*60*60*1000,null,keys.getPrivate(),keys.getPublic(),CATokenInfo.SIGALG_SHA1_WITH_RSA,false); 122 123 byte[] msg = wrap(p10request.getEncoded(), "19"); 125 return msg; 126 } 127 128 private CMSEnvelopedData envelope(CMSProcessable envThis) throws NoSuchAlgorithmException , NoSuchProviderException , CMSException { 129 CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); 130 edGen.addKeyTransRecipient(cacert); 132 CMSEnvelopedData ed = edGen.generate(envThis, SMIMECapability.dES_CBC.getId(), "BC"); 133 return ed; 134 } 135 private CMSSignedData sign(CMSProcessable signThis, String messageType) throws NoSuchAlgorithmException , NoSuchProviderException , CMSException, IOException , InvalidAlgorithmParameterException , CertStoreException { 136 CMSSignedDataGenerator gen1 = new CMSSignedDataGenerator(); 137 138 Hashtable attributes = new Hashtable (); 140 DERObjectIdentifier oid; 141 Attribute attr; 142 DERSet value; 143 144 oid = new DERObjectIdentifier(ScepRequestMessage.id_messageType); 146 value = new DERSet(new DERPrintableString(messageType)); 147 attr = new Attribute(oid, value); 148 attributes.put(attr.getAttrType(), attr); 149 150 byte[] digest = CertTools.generateMD5Fingerprint(cert.getPublicKey().getEncoded()); 152 transactionId = new String (Base64.encode(digest)); 153 oid = new DERObjectIdentifier(ScepRequestMessage.id_transId); 154 value = new DERSet(new DERPrintableString(Base64.encode(digest))); 155 attr = new Attribute(oid, value); 156 attributes.put(attr.getAttrType(), attr); 157 158 byte[] nonce = new byte[16]; 160 SecureRandom randomSource = SecureRandom.getInstance("SHA1PRNG"); 161 randomSource.nextBytes(nonce); 162 senderNonce = new String (Base64.encode(nonce)); 163 if (nonce != null) { 164 oid = new DERObjectIdentifier(ScepRequestMessage.id_senderNonce); 165 log.debug("Added senderNonce: " + senderNonce); 166 value = new DERSet(new DEROctetString(nonce)); 167 attr = new Attribute(oid, value); 168 attributes.put(attr.getAttrType(), attr); 169 } 170 171 ArrayList certList = new ArrayList (); 173 certList.add(cert); 174 CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters (certList), "BC"); 175 gen1.addCertificatesAndCRLs(certs); 176 gen1.addSigner(keys.getPrivate(), cert, digestOid, 177 new AttributeTable(attributes), null); 178 CMSSignedData s = gen1.generate(signThis, true, "BC"); 180 return s; 181 } 182 private byte[] wrap(byte[] envBytes, String messageType) throws IOException , NoSuchAlgorithmException , NoSuchProviderException , CMSException, InvalidAlgorithmParameterException , CertStoreException { 183 184 CMSEnvelopedData ed = envelope(new CMSProcessableByteArray(envBytes)); 188 log.debug("Enveloped data is " + ed.getEncoded().length + " bytes long"); 189 CMSProcessable msg = new CMSProcessableByteArray(ed.getEncoded()); 190 CMSSignedData s = sign(msg, messageType); 194 195 byte[] ret = s.getEncoded(); 196 return ret; 197 198 } 199 } 200 | Popular Tags |