001: package org.bouncycastle.cms.test;
002:
003: import org.bouncycastle.asn1.ASN1InputStream;
004: import org.bouncycastle.asn1.ASN1Sequence;
005: import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
006: import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
007: import org.bouncycastle.asn1.x509.BasicConstraints;
008: import org.bouncycastle.asn1.x509.CRLReason;
009: import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
010: import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
011: import org.bouncycastle.asn1.x509.X509Extensions;
012: import org.bouncycastle.asn1.x509.X509Name;
013: import org.bouncycastle.jce.ECGOST3410NamedCurveTable;
014: import org.bouncycastle.jce.X509Principal;
015: import org.bouncycastle.jce.provider.BouncyCastleProvider;
016: import org.bouncycastle.jce.spec.GOST3410ParameterSpec;
017: import org.bouncycastle.util.encoders.Base64;
018: import org.bouncycastle.x509.X509AttributeCertificate;
019: import org.bouncycastle.x509.X509StreamParser;
020: import org.bouncycastle.x509.X509V2CRLGenerator;
021: import org.bouncycastle.x509.X509V3CertificateGenerator;
022: import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
023:
024: import javax.crypto.KeyGenerator;
025: import javax.crypto.SecretKey;
026: import java.io.ByteArrayInputStream;
027: import java.io.ByteArrayOutputStream;
028: import java.io.IOException;
029: import java.io.InputStream;
030: import java.math.BigInteger;
031: import java.security.GeneralSecurityException;
032: import java.security.KeyPair;
033: import java.security.KeyPairGenerator;
034: import java.security.PrivateKey;
035: import java.security.PublicKey;
036: import java.security.SecureRandom;
037: import java.security.cert.X509CRL;
038: import java.security.cert.X509Certificate;
039: import java.security.interfaces.RSAPublicKey;
040: import java.security.spec.DSAParameterSpec;
041: import java.util.Date;
042:
043: public class CMSTestUtil {
044:
045: public static SecureRandom rand;
046: public static KeyPairGenerator kpg;
047: public static KeyPairGenerator gostKpg;
048: public static KeyPairGenerator dsaKpg;
049: public static KeyPairGenerator ecGostKpg;
050: public static KeyPairGenerator ecDsaKpg;
051: public static KeyGenerator aes192kg;
052: public static KeyGenerator desede128kg;
053: public static KeyGenerator desede192kg;
054: public static KeyGenerator rc240kg;
055: public static KeyGenerator rc264kg;
056: public static KeyGenerator rc2128kg;
057: public static KeyGenerator aesKg;
058: public static KeyGenerator seedKg;
059: public static KeyGenerator camelliaKg;
060: public static BigInteger serialNumber;
061:
062: public static final boolean DEBUG = true;
063:
064: private static byte[] attrCert = Base64
065: .decode("MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2"
066: + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS"
067: + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2"
068: + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0"
069: + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn"
070: + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw"
071: + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY"
072: + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs"
073: + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K"
074: + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0"
075: + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j"
076: + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw"
077: + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg"
078: + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl"
079: + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt"
080: + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0"
081: + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8"
082: + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl"
083: + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ"
084: + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct"
085: + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3"
086: + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1"
087: + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy"
088: + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6"
089: + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov"
090: + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz"
091: + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0"
092: + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46"
093: + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+"
094: + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y"
095: + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv"
096: + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0"
097: + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph"
098: + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj"
099: + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+"
100: + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA"
101: + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr"
102: + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3"
103: + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv");
104:
105: static {
106: try {
107: java.security.Security
108: .addProvider(new BouncyCastleProvider());
109:
110: rand = new SecureRandom();
111:
112: kpg = KeyPairGenerator.getInstance("RSA", "BC");
113: kpg.initialize(1024, rand);
114:
115: gostKpg = KeyPairGenerator.getInstance("GOST3410", "BC");
116: GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(
117: CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A
118: .getId());
119:
120: gostKpg.initialize(gost3410P, new SecureRandom());
121:
122: dsaKpg = KeyPairGenerator.getInstance("DSA", "BC");
123: DSAParameterSpec dsaSpec = new DSAParameterSpec(
124: new BigInteger(
125: "7434410770759874867539421675728577177024889699586189000788950934679315164676852047058354758883833299702695428196962057871264685291775577130504050839126673"),
126: new BigInteger(
127: "1138656671590261728308283492178581223478058193247"),
128: new BigInteger(
129: "4182906737723181805517018315469082619513954319976782448649747742951189003482834321192692620856488639629011570381138542789803819092529658402611668375788410"));
130:
131: dsaKpg.initialize(dsaSpec, new SecureRandom());
132:
133: ecGostKpg = KeyPairGenerator
134: .getInstance("ECGOST3410", "BC");
135: ecGostKpg.initialize(ECGOST3410NamedCurveTable
136: .getParameterSpec("GostR3410-2001-CryptoPro-A"),
137: new SecureRandom());
138:
139: ecDsaKpg = KeyPairGenerator.getInstance("ECDSA", "BC");
140: ecDsaKpg.initialize(239, new SecureRandom());
141:
142: aes192kg = KeyGenerator.getInstance("AES", "BC");
143: aes192kg.init(192, rand);
144:
145: desede128kg = KeyGenerator.getInstance("DESEDE", "BC");
146: desede128kg.init(112, rand);
147:
148: desede192kg = KeyGenerator.getInstance("DESEDE", "BC");
149: desede192kg.init(168, rand);
150:
151: rc240kg = KeyGenerator.getInstance("RC2", "BC");
152: rc240kg.init(40, rand);
153:
154: rc264kg = KeyGenerator.getInstance("RC2", "BC");
155: rc264kg.init(64, rand);
156:
157: rc2128kg = KeyGenerator.getInstance("RC2", "BC");
158: rc2128kg.init(128, rand);
159:
160: aesKg = KeyGenerator.getInstance("AES", "BC");
161:
162: seedKg = KeyGenerator.getInstance("SEED", "BC");
163:
164: camelliaKg = KeyGenerator.getInstance("Camellia", "BC");
165:
166: serialNumber = new BigInteger("1");
167: } catch (Exception ex) {
168: throw new RuntimeException(ex.toString());
169: }
170: }
171:
172: public static String dumpBase64(byte[] data) {
173: StringBuffer buf = new StringBuffer();
174:
175: data = Base64.encode(data);
176:
177: for (int i = 0; i < data.length; i += 64) {
178: if (i + 64 < data.length) {
179: buf.append(new String(data, i, 64));
180: } else {
181: buf.append(new String(data, i, data.length - i));
182: }
183: buf.append('\n');
184: }
185:
186: return buf.toString();
187: }
188:
189: public static X509AttributeCertificate getAttributeCertificate()
190: throws Exception {
191: X509StreamParser parser = X509StreamParser.getInstance(
192: "AttributeCertificate", "BC");
193:
194: parser.init(CMSTestUtil.attrCert);
195:
196: return (X509AttributeCertificate) parser.read();
197: }
198:
199: public static KeyPair makeKeyPair() {
200: return kpg.generateKeyPair();
201: }
202:
203: public static KeyPair makeGostKeyPair() {
204: return gostKpg.generateKeyPair();
205: }
206:
207: public static KeyPair makeDsaKeyPair() {
208: return dsaKpg.generateKeyPair();
209: }
210:
211: public static KeyPair makeEcDsaKeyPair() {
212: return ecDsaKpg.generateKeyPair();
213: }
214:
215: public static KeyPair makeEcGostKeyPair() {
216: return ecGostKpg.generateKeyPair();
217: }
218:
219: public static SecretKey makeDesede128Key() {
220: return desede128kg.generateKey();
221: }
222:
223: public static SecretKey makeAES192Key() {
224: return aes192kg.generateKey();
225: }
226:
227: public static SecretKey makeDesede192Key() {
228: return desede192kg.generateKey();
229: }
230:
231: public static SecretKey makeRC240Key() {
232: return rc240kg.generateKey();
233: }
234:
235: public static SecretKey makeRC264Key() {
236: return rc264kg.generateKey();
237: }
238:
239: public static SecretKey makeRC2128Key() {
240: return rc2128kg.generateKey();
241: }
242:
243: public static SecretKey makeSEEDKey() {
244: return seedKg.generateKey();
245: }
246:
247: public static SecretKey makeAESKey(int keySize) {
248: aesKg.init(keySize);
249: return aesKg.generateKey();
250: }
251:
252: public static SecretKey makeCamelliaKey(int keySize) {
253: camelliaKg.init(keySize);
254: return camelliaKg.generateKey();
255: }
256:
257: public static X509Certificate makeCertificate(KeyPair _subKP,
258: String _subDN, KeyPair _issKP, String _issDN)
259: throws GeneralSecurityException, IOException {
260:
261: return makeCertificate(_subKP, _subDN, _issKP, _issDN, false);
262: }
263:
264: public static X509Certificate makeCACertificate(KeyPair _subKP,
265: String _subDN, KeyPair _issKP, String _issDN)
266: throws GeneralSecurityException, IOException {
267:
268: return makeCertificate(_subKP, _subDN, _issKP, _issDN, true);
269: }
270:
271: public static X509Certificate makeCertificate(KeyPair subKP,
272: String _subDN, KeyPair issKP, String _issDN, boolean _ca)
273: throws GeneralSecurityException, IOException {
274:
275: PublicKey subPub = subKP.getPublic();
276: PrivateKey issPriv = issKP.getPrivate();
277: PublicKey issPub = issKP.getPublic();
278:
279: X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
280:
281: v3CertGen.reset();
282: v3CertGen.setSerialNumber(allocateSerialNumber());
283: v3CertGen.setIssuerDN(new X509Name(_issDN));
284: v3CertGen.setNotBefore(new Date(System.currentTimeMillis()));
285: v3CertGen.setNotAfter(new Date(System.currentTimeMillis()
286: + (1000L * 60 * 60 * 24 * 100)));
287: v3CertGen.setSubjectDN(new X509Name(_subDN));
288: v3CertGen.setPublicKey(subPub);
289:
290: if (issPub instanceof RSAPublicKey) {
291: v3CertGen.setSignatureAlgorithm("SHA1WithRSA");
292: } else if (issPub.getAlgorithm().equals("DSA")) {
293: v3CertGen.setSignatureAlgorithm("SHA1withDSA");
294: } else if (issPub.getAlgorithm().equals("ECDSA")) {
295: v3CertGen.setSignatureAlgorithm("SHA1withECDSA");
296: } else if (issPub.getAlgorithm().equals("ECGOST3410")) {
297: v3CertGen.setSignatureAlgorithm("GOST3411withECGOST3410");
298: } else {
299: v3CertGen.setSignatureAlgorithm("GOST3411WithGOST3410");
300: }
301:
302: v3CertGen.addExtension(X509Extensions.SubjectKeyIdentifier,
303: false, createSubjectKeyId(subPub));
304:
305: v3CertGen.addExtension(X509Extensions.AuthorityKeyIdentifier,
306: false, createAuthorityKeyId(issPub));
307:
308: v3CertGen.addExtension(X509Extensions.BasicConstraints, false,
309: new BasicConstraints(_ca));
310:
311: X509Certificate _cert = v3CertGen.generate(issPriv);
312:
313: _cert.checkValidity(new Date());
314: _cert.verify(issPub);
315:
316: return _cert;
317: }
318:
319: public static X509CRL makeCrl(KeyPair pair) throws Exception {
320: X509V2CRLGenerator crlGen = new X509V2CRLGenerator();
321: Date now = new Date();
322:
323: crlGen.setIssuerDN(new X509Principal("CN=Test CA"));
324:
325: crlGen.setThisUpdate(now);
326: crlGen.setNextUpdate(new Date(now.getTime() + 100000));
327: crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
328:
329: crlGen.addCRLEntry(BigInteger.ONE, now,
330: CRLReason.privilegeWithdrawn);
331:
332: crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier,
333: false, new AuthorityKeyIdentifierStructure(pair
334: .getPublic()));
335:
336: return crlGen.generate(pair.getPrivate(), "BC");
337: }
338:
339: /*
340: *
341: * INTERNAL METHODS
342: *
343: */
344:
345: private static AuthorityKeyIdentifier createAuthorityKeyId(
346: PublicKey _pubKey) throws IOException {
347:
348: ByteArrayInputStream _bais = new ByteArrayInputStream(_pubKey
349: .getEncoded());
350: SubjectPublicKeyInfo _info = new SubjectPublicKeyInfo(
351: (ASN1Sequence) new ASN1InputStream(_bais).readObject());
352:
353: return new AuthorityKeyIdentifier(_info);
354: }
355:
356: private static SubjectKeyIdentifier createSubjectKeyId(
357: PublicKey _pubKey) throws IOException {
358:
359: ByteArrayInputStream _bais = new ByteArrayInputStream(_pubKey
360: .getEncoded());
361: SubjectPublicKeyInfo _info = new SubjectPublicKeyInfo(
362: (ASN1Sequence) new ASN1InputStream(_bais).readObject());
363: return new SubjectKeyIdentifier(_info);
364: }
365:
366: private static BigInteger allocateSerialNumber() {
367: BigInteger _tmp = serialNumber;
368: serialNumber = serialNumber.add(BigInteger.ONE);
369: return _tmp;
370: }
371:
372: public static byte[] streamToByteArray(InputStream in)
373: throws IOException {
374: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
375: int ch;
376:
377: while ((ch = in.read()) >= 0) {
378: bOut.write(ch);
379: }
380:
381: return bOut.toByteArray();
382: }
383: }
|