001: package org.bouncycastle.asn1.test;
002:
003: import org.bouncycastle.asn1.ASN1EncodableVector;
004: import org.bouncycastle.asn1.ASN1InputStream;
005: import org.bouncycastle.asn1.ASN1OutputStream;
006: import org.bouncycastle.asn1.DERInteger;
007: import org.bouncycastle.asn1.DERNull;
008: import org.bouncycastle.asn1.DERObject;
009: import org.bouncycastle.asn1.DEROctetString;
010: import org.bouncycastle.asn1.DERSequence;
011: import org.bouncycastle.asn1.oiw.ElGamalParameter;
012: import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
013: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
014: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
015: import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
016: import org.bouncycastle.asn1.x509.GeneralName;
017: import org.bouncycastle.asn1.x509.GeneralNames;
018: import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
019: import org.bouncycastle.asn1.x509.KeyUsage;
020: import org.bouncycastle.asn1.x509.RSAPublicKeyStructure;
021: import org.bouncycastle.asn1.x509.ReasonFlags;
022: import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
023: import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
024: import org.bouncycastle.asn1.x509.TBSCertList;
025: import org.bouncycastle.asn1.x509.TBSCertificateStructure;
026: import org.bouncycastle.asn1.x509.Time;
027: import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator;
028: import org.bouncycastle.asn1.x509.V2TBSCertListGenerator;
029: import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
030: import org.bouncycastle.asn1.x509.X509Extension;
031: import org.bouncycastle.asn1.x509.X509Extensions;
032: import org.bouncycastle.asn1.x509.X509Name;
033: import org.bouncycastle.util.Arrays;
034: import org.bouncycastle.util.encoders.Base64;
035: import org.bouncycastle.util.test.SimpleTest;
036:
037: import java.io.ByteArrayInputStream;
038: import java.io.ByteArrayOutputStream;
039: import java.io.IOException;
040: import java.math.BigInteger;
041: import java.util.Date;
042: import java.util.Hashtable;
043: import java.util.Vector;
044:
045: public class GenerationTest extends SimpleTest {
046: private byte[] v1Cert = Base64
047: .decode("MIGtAgEBMA0GCSqGSIb3DQEBBAUAMCUxCzAJBgNVBAMMAkFVMRYwFAYDVQQKDA1Cb"
048: + "3VuY3kgQ2FzdGxlMB4XDTcwMDEwMTAwMDAwMVoXDTcwMDEwMTAwMDAxMlowNjELMA"
049: + "kGA1UEAwwCQVUxFjAUBgNVBAoMDUJvdW5jeSBDYXN0bGUxDzANBgNVBAsMBlRlc3Q"
050: + "gMTAaMA0GCSqGSIb3DQEBAQUAAwkAMAYCAQECAQI=");
051:
052: private byte[] v3Cert = Base64
053: .decode("MIIBSKADAgECAgECMA0GCSqGSIb3DQEBBAUAMCUxCzAJBgNVBAMMAkFVMRYwFAYD"
054: + "VQQKDA1Cb3VuY3kgQ2FzdGxlMB4XDTcwMDEwMTAwMDAwMVoXDTcwMDEwMTAwMDAw"
055: + "MlowNjELMAkGA1UEAwwCQVUxFjAUBgNVBAoMDUJvdW5jeSBDYXN0bGUxDzANBgNV"
056: + "BAsMBlRlc3QgMjAYMBAGBisOBwIBATAGAgEBAgECAwQAAgEDo4GVMIGSMGEGA1Ud"
057: + "IwEB/wRXMFWAFDZPdpHPzKi7o8EJokkQU2uqCHRRoTqkODA2MQswCQYDVQQDDAJB"
058: + "VTEWMBQGA1UECgwNQm91bmN5IENhc3RsZTEPMA0GA1UECwwGVGVzdCAyggECMCAG"
059: + "A1UdDgEB/wQWBBQ2T3aRz8you6PBCaJJEFNrqgh0UTALBgNVHQ8EBAMCBBA=");
060:
061: private byte[] v3CertNullSubject = Base64
062: .decode("MIHGoAMCAQICAQIwDQYJKoZIhvcNAQEEBQAwJTELMAkGA1UEAwwCQVUxFjAUBgNVB"
063: + "AoMDUJvdW5jeSBDYXN0bGUwHhcNNzAwMTAxMDAwMDAxWhcNNzAwMTAxMDAwMDAyWj"
064: + "AAMBgwEAYGKw4HAgEBMAYCAQECAQIDBAACAQOjSjBIMEYGA1UdEQEB/wQ8MDqkODA"
065: + "2MQswCQYDVQQDDAJBVTEWMBQGA1UECgwNQm91bmN5IENhc3RsZTEPMA0GA1UECwwG"
066: + "VGVzdCAy");
067:
068: private byte[] v2CertList = Base64
069: .decode("MIIBRQIBATANBgkqhkiG9w0BAQUFADAlMQswCQYDVQQDDAJBVTEWMBQGA1UECgwN"
070: + "Qm91bmN5IENhc3RsZRcNNzAwMTAxMDAwMDAwWhcNNzAwMTAxMDAwMDAyWjAkMCIC"
071: + "AQEXDTcwMDEwMTAwMDAwMVowDjAMBgNVHRUEBQoDAIAAoIHFMIHCMGEGA1UdIwEB"
072: + "/wRXMFWAFDZPdpHPzKi7o8EJokkQU2uqCHRRoTqkODA2MQswCQYDVQQDDAJBVTEW"
073: + "MBQGA1UECgwNQm91bmN5IENhc3RsZTEPMA0GA1UECwwGVGVzdCAyggECMEMGA1Ud"
074: + "EgQ8MDqkODA2MQswCQYDVQQDDAJBVTEWMBQGA1UECgwNQm91bmN5IENhc3RsZTEP"
075: + "MA0GA1UECwwGVGVzdCAzMAoGA1UdFAQDAgEBMAwGA1UdHAEB/wQCMAA=");
076:
077: private void tbsV1CertGen() throws IOException {
078: V1TBSCertificateGenerator gen = new V1TBSCertificateGenerator();
079: Date startDate = new Date(1000);
080: Date endDate = new Date(12000);
081:
082: gen.setSerialNumber(new DERInteger(1));
083:
084: gen.setStartDate(new Time(startDate));
085: gen.setEndDate(new Time(endDate));
086:
087: gen.setIssuer(new X509Name("CN=AU,O=Bouncy Castle"));
088: gen.setSubject(new X509Name("CN=AU,O=Bouncy Castle,OU=Test 1"));
089:
090: gen.setSignature(new AlgorithmIdentifier(
091: PKCSObjectIdentifiers.md5WithRSAEncryption,
092: new DERNull()));
093:
094: SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
095: new AlgorithmIdentifier(
096: PKCSObjectIdentifiers.rsaEncryption,
097: new DERNull()), new RSAPublicKeyStructure(
098: BigInteger.valueOf(1), BigInteger.valueOf(2)));
099:
100: gen.setSubjectPublicKeyInfo(info);
101:
102: TBSCertificateStructure tbs = gen.generateTBSCertificate();
103: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
104: ASN1OutputStream aOut = new ASN1OutputStream(bOut);
105:
106: aOut.writeObject(tbs);
107:
108: if (!Arrays.areEqual(bOut.toByteArray(), v1Cert)) {
109: fail("failed v1 cert generation");
110: }
111:
112: //
113: // read back test
114: //
115: ASN1InputStream aIn = new ASN1InputStream(
116: new ByteArrayInputStream(v1Cert));
117: DERObject o = aIn.readObject();
118:
119: bOut = new ByteArrayOutputStream();
120: aOut = new ASN1OutputStream(bOut);
121:
122: aOut.writeObject(o);
123:
124: if (!Arrays.areEqual(bOut.toByteArray(), v1Cert)) {
125: fail("failed v1 cert read back test");
126: }
127: }
128:
129: private AuthorityKeyIdentifier createAuthorityKeyId(
130: SubjectPublicKeyInfo info, X509Name name, int sNumber) {
131: GeneralName genName = new GeneralName(name);
132: ASN1EncodableVector v = new ASN1EncodableVector();
133:
134: v.add(genName);
135:
136: return new AuthorityKeyIdentifier(info, new GeneralNames(
137: new DERSequence(v)), BigInteger.valueOf(sNumber));
138: }
139:
140: private void tbsV3CertGen() throws IOException {
141: V3TBSCertificateGenerator gen = new V3TBSCertificateGenerator();
142: Date startDate = new Date(1000);
143: Date endDate = new Date(2000);
144:
145: gen.setSerialNumber(new DERInteger(2));
146:
147: gen.setStartDate(new Time(startDate));
148: gen.setEndDate(new Time(endDate));
149:
150: gen.setIssuer(new X509Name("CN=AU,O=Bouncy Castle"));
151: gen.setSubject(new X509Name("CN=AU,O=Bouncy Castle,OU=Test 2"));
152:
153: gen.setSignature(new AlgorithmIdentifier(
154: PKCSObjectIdentifiers.md5WithRSAEncryption,
155: new DERNull()));
156:
157: SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
158: new AlgorithmIdentifier(
159: OIWObjectIdentifiers.elGamalAlgorithm,
160: new ElGamalParameter(BigInteger.valueOf(1),
161: BigInteger.valueOf(2))),
162: new DERInteger(3));
163:
164: gen.setSubjectPublicKeyInfo(info);
165:
166: //
167: // add extensions
168: //
169: Vector order = new Vector();
170: Hashtable extensions = new Hashtable();
171:
172: order.addElement(X509Extensions.AuthorityKeyIdentifier);
173: order.addElement(X509Extensions.SubjectKeyIdentifier);
174: order.addElement(X509Extensions.KeyUsage);
175:
176: extensions
177: .put(
178: X509Extensions.AuthorityKeyIdentifier,
179: new X509Extension(
180: true,
181: new DEROctetString(
182: createAuthorityKeyId(
183: info,
184: new X509Name(
185: "CN=AU,O=Bouncy Castle,OU=Test 2"),
186: 2))));
187: extensions.put(X509Extensions.SubjectKeyIdentifier,
188: new X509Extension(true, new DEROctetString(
189: new SubjectKeyIdentifier(info))));
190: extensions.put(X509Extensions.KeyUsage, new X509Extension(
191: false, new DEROctetString(new KeyUsage(
192: KeyUsage.dataEncipherment))));
193:
194: X509Extensions ex = new X509Extensions(order, extensions);
195:
196: gen.setExtensions(ex);
197:
198: TBSCertificateStructure tbs = gen.generateTBSCertificate();
199: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
200: ASN1OutputStream aOut = new ASN1OutputStream(bOut);
201:
202: aOut.writeObject(tbs);
203:
204: if (!Arrays.areEqual(bOut.toByteArray(), v3Cert)) {
205: fail("failed v3 cert generation");
206: }
207:
208: //
209: // read back test
210: //
211: ASN1InputStream aIn = new ASN1InputStream(
212: new ByteArrayInputStream(v3Cert));
213: DERObject o = aIn.readObject();
214:
215: bOut = new ByteArrayOutputStream();
216: aOut = new ASN1OutputStream(bOut);
217:
218: aOut.writeObject(o);
219:
220: if (!Arrays.areEqual(bOut.toByteArray(), v3Cert)) {
221: fail("failed v3 cert read back test");
222: }
223: }
224:
225: private void tbsV3CertGenWithNullSubject() throws IOException {
226: V3TBSCertificateGenerator gen = new V3TBSCertificateGenerator();
227: Date startDate = new Date(1000);
228: Date endDate = new Date(2000);
229:
230: gen.setSerialNumber(new DERInteger(2));
231:
232: gen.setStartDate(new Time(startDate));
233: gen.setEndDate(new Time(endDate));
234:
235: gen.setIssuer(new X509Name("CN=AU,O=Bouncy Castle"));
236:
237: gen.setSignature(new AlgorithmIdentifier(
238: PKCSObjectIdentifiers.md5WithRSAEncryption,
239: new DERNull()));
240:
241: SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
242: new AlgorithmIdentifier(
243: OIWObjectIdentifiers.elGamalAlgorithm,
244: new ElGamalParameter(BigInteger.valueOf(1),
245: BigInteger.valueOf(2))),
246: new DERInteger(3));
247:
248: gen.setSubjectPublicKeyInfo(info);
249:
250: try {
251: gen.generateTBSCertificate();
252: fail("null subject not caught!");
253: } catch (IllegalStateException e) {
254: if (!e
255: .getMessage()
256: .equals(
257: "not all mandatory fields set in V3 TBScertificate generator")) {
258: fail("unexpected exception", e);
259: }
260: }
261:
262: //
263: // add extensions
264: //
265: Vector order = new Vector();
266: Hashtable extensions = new Hashtable();
267:
268: order.addElement(X509Extensions.SubjectAlternativeName);
269:
270: extensions.put(X509Extensions.SubjectAlternativeName,
271: new X509Extension(true, new DEROctetString(
272: new GeneralNames(new GeneralName(new X509Name(
273: "CN=AU,O=Bouncy Castle,OU=Test 2"))))));
274:
275: X509Extensions ex = new X509Extensions(order, extensions);
276:
277: gen.setExtensions(ex);
278:
279: TBSCertificateStructure tbs = gen.generateTBSCertificate();
280: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
281: ASN1OutputStream aOut = new ASN1OutputStream(bOut);
282:
283: aOut.writeObject(tbs);
284:
285: if (!Arrays.areEqual(bOut.toByteArray(), v3CertNullSubject)) {
286: fail("failed v3 null sub cert generation");
287: }
288:
289: //
290: // read back test
291: //
292: ASN1InputStream aIn = new ASN1InputStream(
293: new ByteArrayInputStream(v3CertNullSubject));
294: DERObject o = aIn.readObject();
295:
296: bOut = new ByteArrayOutputStream();
297: aOut = new ASN1OutputStream(bOut);
298:
299: aOut.writeObject(o);
300:
301: if (!Arrays.areEqual(bOut.toByteArray(), v3CertNullSubject)) {
302: fail("failed v3 null sub cert read back test");
303: }
304: }
305:
306: private void tbsV2CertListGen() throws IOException {
307: V2TBSCertListGenerator gen = new V2TBSCertListGenerator();
308:
309: gen.setIssuer(new X509Name("CN=AU,O=Bouncy Castle"));
310:
311: gen.addCRLEntry(new DERInteger(1), new Time(new Date(1000)),
312: ReasonFlags.aACompromise);
313:
314: gen.setNextUpdate(new Time(new Date(2000)));
315:
316: gen.setThisUpdate(new Time(new Date(500)));
317:
318: gen.setSignature(new AlgorithmIdentifier(
319: PKCSObjectIdentifiers.sha1WithRSAEncryption,
320: new DERNull()));
321:
322: //
323: // extensions
324: //
325: Vector order = new Vector();
326: Hashtable extensions = new Hashtable();
327: SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
328: new AlgorithmIdentifier(
329: OIWObjectIdentifiers.elGamalAlgorithm,
330: new ElGamalParameter(BigInteger.valueOf(1),
331: BigInteger.valueOf(2))),
332: new DERInteger(3));
333:
334: order.addElement(X509Extensions.AuthorityKeyIdentifier);
335: order.addElement(X509Extensions.IssuerAlternativeName);
336: order.addElement(X509Extensions.CRLNumber);
337: order.addElement(X509Extensions.IssuingDistributionPoint);
338:
339: extensions
340: .put(
341: X509Extensions.AuthorityKeyIdentifier,
342: new X509Extension(
343: true,
344: new DEROctetString(
345: createAuthorityKeyId(
346: info,
347: new X509Name(
348: "CN=AU,O=Bouncy Castle,OU=Test 2"),
349: 2))));
350: extensions
351: .put(
352: X509Extensions.IssuerAlternativeName,
353: new X509Extension(
354: false,
355: new DEROctetString(
356: new GeneralNames(
357: new DERSequence(
358: new GeneralName(
359: new X509Name(
360: "CN=AU,O=Bouncy Castle,OU=Test 3")))))));
361: extensions.put(X509Extensions.CRLNumber, new X509Extension(
362: false, new DEROctetString(new DERInteger(1))));
363: extensions.put(X509Extensions.IssuingDistributionPoint,
364: new X509Extension(true,
365: new DEROctetString(
366: new IssuingDistributionPoint(
367: new DERSequence()))));
368:
369: X509Extensions ex = new X509Extensions(order, extensions);
370:
371: gen.setExtensions(ex);
372:
373: TBSCertList tbs = gen.generateTBSCertList();
374: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
375: ASN1OutputStream aOut = new ASN1OutputStream(bOut);
376:
377: aOut.writeObject(tbs);
378:
379: if (!Arrays.areEqual(bOut.toByteArray(), v2CertList)) {
380: fail("failed v2 cert list generation");
381: }
382:
383: //
384: // read back test
385: //
386: ASN1InputStream aIn = new ASN1InputStream(
387: new ByteArrayInputStream(v2CertList));
388: DERObject o = aIn.readObject();
389:
390: bOut = new ByteArrayOutputStream();
391: aOut = new ASN1OutputStream(bOut);
392:
393: aOut.writeObject(o);
394:
395: if (!Arrays.areEqual(bOut.toByteArray(), v2CertList)) {
396: fail("failed v2 cert list read back test");
397: }
398: }
399:
400: public void performTest() throws Exception {
401: tbsV1CertGen();
402: tbsV3CertGen();
403: tbsV3CertGenWithNullSubject();
404: tbsV2CertListGen();
405: }
406:
407: public String getName() {
408: return "Generation";
409: }
410:
411: public static void main(String[] args) {
412: runTest(new GenerationTest());
413: }
414: }
|