0001: package org.bouncycastle.cms.test;
0002:
0003: import junit.framework.Test;
0004: import junit.framework.TestCase;
0005: import junit.framework.TestSuite;
0006: import org.bouncycastle.asn1.ASN1OctetString;
0007: import org.bouncycastle.asn1.DERObjectIdentifier;
0008: import org.bouncycastle.asn1.DEROctetString;
0009: import org.bouncycastle.asn1.DERSet;
0010: import org.bouncycastle.asn1.cms.Attribute;
0011: import org.bouncycastle.asn1.cms.AttributeTable;
0012: import org.bouncycastle.asn1.cms.CMSAttributes;
0013: import org.bouncycastle.cms.CMSAttributeTableGenerator;
0014: import org.bouncycastle.cms.CMSProcessable;
0015: import org.bouncycastle.cms.CMSProcessableByteArray;
0016: import org.bouncycastle.cms.CMSSignedData;
0017: import org.bouncycastle.cms.CMSSignedDataGenerator;
0018: import org.bouncycastle.cms.CMSSignedDataParser;
0019: import org.bouncycastle.cms.CMSSignedDataStreamGenerator;
0020: import org.bouncycastle.cms.CMSTypedStream;
0021: import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator;
0022: import org.bouncycastle.cms.SignerInformation;
0023: import org.bouncycastle.cms.SignerInformationStore;
0024: import org.bouncycastle.mail.smime.SMIMESignedGenerator;
0025: import org.bouncycastle.util.encoders.Base64;
0026: import org.bouncycastle.x509.X509AttributeCertificate;
0027: import org.bouncycastle.x509.X509CollectionStoreParameters;
0028: import org.bouncycastle.x509.X509Store;
0029:
0030: import java.io.BufferedOutputStream;
0031: import java.io.ByteArrayInputStream;
0032: import java.io.ByteArrayOutputStream;
0033: import java.io.OutputStream;
0034: import java.security.KeyPair;
0035: import java.security.MessageDigest;
0036: import java.security.cert.CertStore;
0037: import java.security.cert.CollectionCertStoreParameters;
0038: import java.security.cert.X509CRL;
0039: import java.security.cert.X509Certificate;
0040: import java.util.ArrayList;
0041: import java.util.Collection;
0042: import java.util.Collections;
0043: import java.util.Hashtable;
0044: import java.util.Iterator;
0045: import java.util.List;
0046: import java.util.Map;
0047:
0048: public class SignedDataStreamTest extends TestCase {
0049: private static final String TEST_MESSAGE = "Hello World!";
0050: private static String _signDN;
0051: private static KeyPair _signKP;
0052: private static X509Certificate _signCert;
0053:
0054: private static String _origDN;
0055: private static KeyPair _origKP;
0056: private static X509Certificate _origCert;
0057:
0058: private static String _reciDN;
0059: private static KeyPair _reciKP;
0060: private static X509Certificate _reciCert;
0061:
0062: private static KeyPair _origDsaKP;
0063: private static X509Certificate _origDsaCert;
0064:
0065: private static X509CRL _signCrl;
0066: private static X509CRL _origCrl;
0067:
0068: private static boolean _initialised = false;
0069:
0070: public SignedDataStreamTest(String name) {
0071: super (name);
0072: }
0073:
0074: private static void init() throws Exception {
0075: if (!_initialised) {
0076: _initialised = true;
0077:
0078: _signDN = "O=Bouncy Castle, C=AU";
0079: _signKP = CMSTestUtil.makeKeyPair();
0080: _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN,
0081: _signKP, _signDN);
0082:
0083: _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU";
0084: _origKP = CMSTestUtil.makeKeyPair();
0085: _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN,
0086: _signKP, _signDN);
0087:
0088: _origDsaKP = CMSTestUtil.makeDsaKeyPair();
0089: _origDsaCert = CMSTestUtil.makeCertificate(_origDsaKP,
0090: _origDN, _signKP, _signDN);
0091:
0092: _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
0093: _reciKP = CMSTestUtil.makeKeyPair();
0094: _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN,
0095: _signKP, _signDN);
0096:
0097: _signCrl = CMSTestUtil.makeCrl(_signKP);
0098: _origCrl = CMSTestUtil.makeCrl(_origKP);
0099: }
0100: }
0101:
0102: private void verifySignatures(CMSSignedDataParser sp,
0103: byte[] contentDigest) throws Exception {
0104: CertStore certStore = sp.getCertificatesAndCRLs("Collection",
0105: "BC");
0106: SignerInformationStore signers = sp.getSignerInfos();
0107:
0108: Collection c = signers.getSigners();
0109: Iterator it = c.iterator();
0110:
0111: while (it.hasNext()) {
0112: SignerInformation signer = (SignerInformation) it.next();
0113: Collection certCollection = certStore
0114: .getCertificates(signer.getSID());
0115:
0116: Iterator certIt = certCollection.iterator();
0117: X509Certificate cert = (X509Certificate) certIt.next();
0118:
0119: assertEquals(true, signer.verify(cert, "BC"));
0120:
0121: if (contentDigest != null) {
0122: assertTrue(MessageDigest.isEqual(contentDigest, signer
0123: .getContentDigest()));
0124: }
0125: }
0126:
0127: Collection certColl = certStore.getCertificates(null);
0128: Collection crlColl = certStore.getCRLs(null);
0129:
0130: assertEquals(certColl.size(), sp.getCertificates("Collection",
0131: "BC").getMatches(null).size());
0132: assertEquals(crlColl.size(), sp.getCRLs("Collection", "BC")
0133: .getMatches(null).size());
0134: }
0135:
0136: private void verifySignatures(CMSSignedDataParser sp)
0137: throws Exception {
0138: verifySignatures(sp, null);
0139: }
0140:
0141: private void verifyEncodedData(ByteArrayOutputStream bOut)
0142: throws Exception {
0143: CMSSignedDataParser sp;
0144: sp = new CMSSignedDataParser(bOut.toByteArray());
0145:
0146: sp.getSignedContent().drain();
0147:
0148: verifySignatures(sp);
0149:
0150: sp.close();
0151: }
0152:
0153: public void testSha1EncapsulatedSignature() throws Exception {
0154: byte[] encapSigData = Base64
0155: .decode("MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEH"
0156: + "AaCAJIAEDEhlbGxvIFdvcmxkIQAAAAAAAKCCBGIwggINMIIBdqADAgECAgEF"
0157: + "MA0GCSqGSIb3DQEBBAUAMCUxFjAUBgNVBAoTDUJvdW5jeSBDYXN0bGUxCzAJ"
0158: + "BgNVBAYTAkFVMB4XDTA1MDgwNzA2MjU1OVoXDTA1MTExNTA2MjU1OVowJTEW"
0159: + "MBQGA1UEChMNQm91bmN5IENhc3RsZTELMAkGA1UEBhMCQVUwgZ8wDQYJKoZI"
0160: + "hvcNAQEBBQADgY0AMIGJAoGBAI1fZGgH9wgC3QiK6yluH6DlLDkXkxYYL+Qf"
0161: + "nVRszJVYl0LIxZdpb7WEbVpO8fwtEgFtoDsOdxyqh3dTBv+L7NVD/v46kdPt"
0162: + "xVkSNHRbutJVY8Xn4/TC/CDngqtbpbniMO8n0GiB6vs94gBT20M34j96O2IF"
0163: + "73feNHP+x8PkJ+dNAgMBAAGjTTBLMB0GA1UdDgQWBBQ3XUfEE6+D+t+LIJgK"
0164: + "ESSUE58eyzAfBgNVHSMEGDAWgBQ3XUfEE6+D+t+LIJgKESSUE58eyzAJBgNV"
0165: + "HRMEAjAAMA0GCSqGSIb3DQEBBAUAA4GBAFK3r1stYOeXYJOlOyNGDTWEhZ+a"
0166: + "OYdFeFaS6c+InjotHuFLAy+QsS8PslE48zYNFEqYygGfLhZDLlSnJ/LAUTqF"
0167: + "01vlp+Bgn/JYiJazwi5WiiOTf7Th6eNjHFKXS3hfSGPNPIOjvicAp3ce3ehs"
0168: + "uK0MxgLAaxievzhFfJcGSUMDMIICTTCCAbagAwIBAgIBBzANBgkqhkiG9w0B"
0169: + "AQQFADAlMRYwFAYDVQQKEw1Cb3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVTAe"
0170: + "Fw0wNTA4MDcwNjI1NTlaFw0wNTExMTUwNjI1NTlaMGUxGDAWBgNVBAMTD0Vy"
0171: + "aWMgSC4gRWNoaWRuYTEkMCIGCSqGSIb3DQEJARYVZXJpY0Bib3VuY3ljYXN0"
0172: + "bGUub3JnMRYwFAYDVQQKEw1Cb3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVTCB"
0173: + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAgHCJyfwV6/V3kqSu2SOU2E/K"
0174: + "I+N0XohCMUaxPLLNtNBZ3ijxwaV6JGFz7siTgZD/OGfzir/eZimkt+L1iXQn"
0175: + "OAB+ZChivKvHtX+dFFC7Vq+E4Uy0Ftqc/wrGxE6DHb5BR0hprKH8wlDS8wSP"
0176: + "zxovgk4nH0ffUZOoDSuUgjh3gG8CAwEAAaNNMEswHQYDVR0OBBYEFLfY/4EG"
0177: + "mYrvJa7Cky+K9BJ7YmERMB8GA1UdIwQYMBaAFDddR8QTr4P634sgmAoRJJQT"
0178: + "nx7LMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEEBQADgYEADIOmpMd6UHdMjkyc"
0179: + "mIE1yiwfClCsGhCK9FigTg6U1G2FmkBwJIMWBlkeH15uvepsAncsgK+Cn3Zr"
0180: + "dZMb022mwtTJDtcaOM+SNeuCnjdowZ4i71Hf68siPm6sMlZkhz49rA0Yidoo"
0181: + "WuzYOO+dggzwDsMldSsvsDo/ARyCGOulDOAxggEvMIIBKwIBATAqMCUxFjAU"
0182: + "BgNVBAoTDUJvdW5jeSBDYXN0bGUxCzAJBgNVBAYTAkFVAgEHMAkGBSsOAwIa"
0183: + "BQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEP"
0184: + "Fw0wNTA4MDcwNjI1NTlaMCMGCSqGSIb3DQEJBDEWBBQu973mCM5UBOl9XwQv"
0185: + "lfifHCMocTANBgkqhkiG9w0BAQEFAASBgGxnBl2qozYKLgZ0ygqSFgWcRGl1"
0186: + "LgNuE587LtO+EKkgoc3aFqEdjXlAyP8K7naRsvWnFrsB6pUpnrgI9Z8ZSKv8"
0187: + "98IlpsSSJ0jBlEb4gzzavwcBpYbr2ryOtDcF+kYmKIpScglyyoLzm+KPXOoT"
0188: + "n7MsJMoKN3Kd2Vzh6s10PFgeAAAAAAAA");
0189:
0190: CMSSignedDataParser sp = new CMSSignedDataParser(encapSigData);
0191:
0192: sp.getSignedContent().drain();
0193:
0194: verifySignatures(sp);
0195: }
0196:
0197: public void testSHA1WithRSANoAttributes() throws Exception {
0198: List certList = new ArrayList();
0199: CMSProcessable msg = new CMSProcessableByteArray(TEST_MESSAGE
0200: .getBytes());
0201:
0202: certList.add(_origCert);
0203: certList.add(_signCert);
0204:
0205: CertStore certs = CertStore.getInstance("Collection",
0206: new CollectionCertStoreParameters(certList), "BC");
0207:
0208: CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
0209:
0210: gen.addSigner(_origKP.getPrivate(), _origCert,
0211: CMSSignedDataGenerator.DIGEST_SHA1);
0212:
0213: gen.addCertificatesAndCRLs(certs);
0214:
0215: CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA,
0216: msg, false, "BC", false);
0217:
0218: CMSSignedDataParser sp = new CMSSignedDataParser(
0219: new CMSTypedStream(new ByteArrayInputStream(
0220: TEST_MESSAGE.getBytes())), s.getEncoded());
0221:
0222: sp.getSignedContent().drain();
0223:
0224: //
0225: // compute expected content digest
0226: //
0227: MessageDigest md = MessageDigest.getInstance("SHA1", "BC");
0228:
0229: verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes()));
0230: }
0231:
0232: public void testDSANoAttributes() throws Exception {
0233: List certList = new ArrayList();
0234: CMSProcessable msg = new CMSProcessableByteArray(TEST_MESSAGE
0235: .getBytes());
0236:
0237: certList.add(_origDsaCert);
0238: certList.add(_signCert);
0239:
0240: CertStore certs = CertStore.getInstance("Collection",
0241: new CollectionCertStoreParameters(certList), "BC");
0242:
0243: CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
0244:
0245: gen.addSigner(_origDsaKP.getPrivate(), _origDsaCert,
0246: CMSSignedDataGenerator.DIGEST_SHA1);
0247:
0248: gen.addCertificatesAndCRLs(certs);
0249:
0250: CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA,
0251: msg, false, "BC", false);
0252:
0253: CMSSignedDataParser sp = new CMSSignedDataParser(
0254: new CMSTypedStream(new ByteArrayInputStream(
0255: TEST_MESSAGE.getBytes())), s.getEncoded());
0256:
0257: sp.getSignedContent().drain();
0258:
0259: //
0260: // compute expected content digest
0261: //
0262: MessageDigest md = MessageDigest.getInstance("SHA1", "BC");
0263:
0264: verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes()));
0265: }
0266:
0267: public void testSHA1WithRSA() throws Exception {
0268: List certList = new ArrayList();
0269: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0270:
0271: certList.add(_origCert);
0272: certList.add(_signCert);
0273:
0274: certList.add(_signCrl);
0275: certList.add(_origCrl);
0276:
0277: CertStore certsAndCrls = CertStore.getInstance("Collection",
0278: new CollectionCertStoreParameters(certList), "BC");
0279:
0280: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0281:
0282: gen.addSigner(_origKP.getPrivate(), _origCert,
0283: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0284:
0285: gen.addCertificatesAndCRLs(certsAndCrls);
0286:
0287: OutputStream sigOut = gen.open(bOut);
0288:
0289: sigOut.write(TEST_MESSAGE.getBytes());
0290:
0291: sigOut.close();
0292:
0293: CMSSignedDataParser sp = new CMSSignedDataParser(
0294: new CMSTypedStream(new ByteArrayInputStream(
0295: TEST_MESSAGE.getBytes())), bOut.toByteArray());
0296:
0297: sp.getSignedContent().drain();
0298:
0299: //
0300: // compute expected content digest
0301: //
0302: MessageDigest md = MessageDigest.getInstance("SHA1", "BC");
0303:
0304: verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes()));
0305:
0306: //
0307: // try using existing signer
0308: //
0309: gen = new CMSSignedDataStreamGenerator();
0310:
0311: gen.addSigners(sp.getSignerInfos());
0312:
0313: gen.addCertificatesAndCRLs(sp.getCertificatesAndCRLs(
0314: "Collection", "BC"));
0315:
0316: bOut.reset();
0317:
0318: sigOut = gen.open(bOut, true);
0319:
0320: sigOut.write(TEST_MESSAGE.getBytes());
0321:
0322: sigOut.close();
0323:
0324: verifyEncodedData(bOut);
0325:
0326: //
0327: // look for the CRLs
0328: //
0329: Collection col = certsAndCrls.getCRLs(null);
0330:
0331: assertEquals(2, col.size());
0332: assertTrue(col.contains(_signCrl));
0333: assertTrue(col.contains(_origCrl));
0334: }
0335:
0336: public void testSHA1WithRSANonData() throws Exception {
0337: List certList = new ArrayList();
0338: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0339:
0340: certList.add(_origCert);
0341: certList.add(_signCert);
0342:
0343: certList.add(_signCrl);
0344: certList.add(_origCrl);
0345:
0346: CertStore certsAndCrls = CertStore.getInstance("Collection",
0347: new CollectionCertStoreParameters(certList), "BC");
0348:
0349: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0350:
0351: gen.addSigner(_origKP.getPrivate(), _origCert,
0352: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0353:
0354: gen.addCertificatesAndCRLs(certsAndCrls);
0355:
0356: OutputStream sigOut = gen.open(bOut, "1.2.3.4", true);
0357:
0358: sigOut.write(TEST_MESSAGE.getBytes());
0359:
0360: sigOut.close();
0361:
0362: CMSSignedDataParser sp = new CMSSignedDataParser(bOut
0363: .toByteArray());
0364:
0365: CMSTypedStream stream = sp.getSignedContent();
0366:
0367: assertEquals("1.2.3.4", stream.getContentType());
0368:
0369: stream.drain();
0370:
0371: //
0372: // compute expected content digest
0373: //
0374: MessageDigest md = MessageDigest.getInstance("SHA1", "BC");
0375:
0376: verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes()));
0377: }
0378:
0379: public void testSHA1AndMD5WithRSA() throws Exception {
0380: List certList = new ArrayList();
0381: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0382:
0383: certList.add(_origCert);
0384: certList.add(_signCert);
0385:
0386: CertStore certs = CertStore.getInstance("Collection",
0387: new CollectionCertStoreParameters(certList), "BC");
0388:
0389: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0390:
0391: gen.addSigner(_origKP.getPrivate(), _origCert,
0392: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0393: gen.addSigner(_origKP.getPrivate(), _origCert,
0394: CMSSignedDataStreamGenerator.DIGEST_MD5, "BC");
0395:
0396: gen.addCertificatesAndCRLs(certs);
0397:
0398: OutputStream sigOut = gen.open(bOut);
0399:
0400: sigOut.write(TEST_MESSAGE.getBytes());
0401:
0402: sigOut.close();
0403:
0404: CMSSignedDataParser sp = new CMSSignedDataParser(
0405: new CMSTypedStream(new ByteArrayInputStream(
0406: TEST_MESSAGE.getBytes())), bOut.toByteArray());
0407:
0408: sp.getSignedContent().drain();
0409:
0410: verifySignatures(sp);
0411: }
0412:
0413: public void testSHA1WithRSAEncapsulatedBufferedStream()
0414: throws Exception {
0415: List certList = new ArrayList();
0416: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0417:
0418: certList.add(_origCert);
0419: certList.add(_signCert);
0420:
0421: CertStore certs = CertStore.getInstance("Collection",
0422: new CollectionCertStoreParameters(certList), "BC");
0423:
0424: //
0425: // find unbuffered length
0426: //
0427: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0428:
0429: gen.addSigner(_origKP.getPrivate(), _origCert,
0430: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0431:
0432: gen.addCertificatesAndCRLs(certs);
0433:
0434: OutputStream sigOut = gen.open(bOut, true);
0435:
0436: for (int i = 0; i != 2000; i++) {
0437: sigOut.write(i & 0xff);
0438: }
0439:
0440: sigOut.close();
0441:
0442: CMSSignedDataParser sp = new CMSSignedDataParser(bOut
0443: .toByteArray());
0444:
0445: sp.getSignedContent().drain();
0446:
0447: verifySignatures(sp);
0448:
0449: int unbufferedLength = bOut.toByteArray().length;
0450:
0451: //
0452: // find buffered length
0453: //
0454: bOut = new ByteArrayOutputStream();
0455:
0456: gen = new CMSSignedDataStreamGenerator();
0457:
0458: gen.addSigner(_origKP.getPrivate(), _origCert,
0459: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0460:
0461: gen.addCertificatesAndCRLs(certs);
0462:
0463: sigOut = gen.open(bOut, true);
0464:
0465: BufferedOutputStream bfOut = new BufferedOutputStream(sigOut,
0466: 300);
0467:
0468: for (int i = 0; i != 2000; i++) {
0469: bfOut.write(i & 0xff);
0470: }
0471:
0472: bfOut.close();
0473:
0474: verifyEncodedData(bOut);
0475:
0476: assertTrue(bOut.toByteArray().length < unbufferedLength);
0477: }
0478:
0479: public void testSHA1WithRSAEncapsulatedBuffered() throws Exception {
0480: List certList = new ArrayList();
0481: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0482:
0483: certList.add(_origCert);
0484: certList.add(_signCert);
0485:
0486: CertStore certs = CertStore.getInstance("Collection",
0487: new CollectionCertStoreParameters(certList), "BC");
0488:
0489: //
0490: // find unbuffered length
0491: //
0492: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0493:
0494: gen.addSigner(_origKP.getPrivate(), _origCert,
0495: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0496:
0497: gen.addCertificatesAndCRLs(certs);
0498:
0499: OutputStream sigOut = gen.open(bOut, true);
0500:
0501: for (int i = 0; i != 2000; i++) {
0502: sigOut.write(i & 0xff);
0503: }
0504:
0505: sigOut.close();
0506:
0507: CMSSignedDataParser sp = new CMSSignedDataParser(bOut
0508: .toByteArray());
0509:
0510: sp.getSignedContent().drain();
0511:
0512: verifySignatures(sp);
0513:
0514: int unbufferedLength = bOut.toByteArray().length;
0515:
0516: //
0517: // find buffered length
0518: //
0519: bOut = new ByteArrayOutputStream();
0520:
0521: gen = new CMSSignedDataStreamGenerator();
0522:
0523: gen.setBufferSize(300);
0524:
0525: gen.addSigner(_origKP.getPrivate(), _origCert,
0526: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0527:
0528: gen.addCertificatesAndCRLs(certs);
0529:
0530: sigOut = gen.open(bOut, true);
0531:
0532: for (int i = 0; i != 2000; i++) {
0533: sigOut.write(i & 0xff);
0534: }
0535:
0536: sigOut.close();
0537:
0538: verifyEncodedData(bOut);
0539:
0540: assertTrue(bOut.toByteArray().length < unbufferedLength);
0541: }
0542:
0543: public void testSHA1WithRSAEncapsulated() throws Exception {
0544: List certList = new ArrayList();
0545: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0546:
0547: certList.add(_origCert);
0548: certList.add(_signCert);
0549:
0550: CertStore certs = CertStore.getInstance("Collection",
0551: new CollectionCertStoreParameters(certList), "BC");
0552:
0553: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0554:
0555: gen.addSigner(_origKP.getPrivate(), _origCert,
0556: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0557:
0558: gen.addCertificatesAndCRLs(certs);
0559:
0560: OutputStream sigOut = gen.open(bOut, true);
0561:
0562: sigOut.write(TEST_MESSAGE.getBytes());
0563:
0564: sigOut.close();
0565:
0566: CMSSignedDataParser sp = new CMSSignedDataParser(bOut
0567: .toByteArray());
0568:
0569: sp.getSignedContent().drain();
0570:
0571: verifySignatures(sp);
0572:
0573: byte[] contentDigest = (byte[]) gen.getGeneratedDigests().get(
0574: SMIMESignedGenerator.DIGEST_SHA1);
0575:
0576: AttributeTable table = ((SignerInformation) sp.getSignerInfos()
0577: .getSigners().iterator().next()).getSignedAttributes();
0578: Attribute hash = table.get(CMSAttributes.messageDigest);
0579:
0580: assertTrue(MessageDigest.isEqual(contentDigest,
0581: ((ASN1OctetString) hash.getAttrValues().getObjectAt(0))
0582: .getOctets()));
0583:
0584: //
0585: // try using existing signer
0586: //
0587: gen = new CMSSignedDataStreamGenerator();
0588:
0589: gen.addSigners(sp.getSignerInfos());
0590:
0591: gen.addCertificatesAndCRLs(sp.getCertificatesAndCRLs(
0592: "Collection", "BC"));
0593:
0594: bOut.reset();
0595:
0596: sigOut = gen.open(bOut, true);
0597:
0598: sigOut.write(TEST_MESSAGE.getBytes());
0599:
0600: sigOut.close();
0601:
0602: CMSSignedData sd = new CMSSignedData(
0603: new CMSProcessableByteArray(TEST_MESSAGE.getBytes()),
0604: bOut.toByteArray());
0605:
0606: assertEquals(1, sd.getSignerInfos().getSigners().size());
0607:
0608: verifyEncodedData(bOut);
0609: }
0610:
0611: public void testAttributeGenerators() throws Exception {
0612: final DERObjectIdentifier dummyOid1 = new DERObjectIdentifier(
0613: "1.2.3");
0614: final DERObjectIdentifier dummyOid2 = new DERObjectIdentifier(
0615: "1.2.3.4");
0616: List certList = new ArrayList();
0617: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0618:
0619: certList.add(_origCert);
0620: certList.add(_signCert);
0621:
0622: CertStore certs = CertStore.getInstance("Collection",
0623: new CollectionCertStoreParameters(certList), "BC");
0624:
0625: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0626:
0627: CMSAttributeTableGenerator signedGen = new DefaultSignedAttributeTableGenerator() {
0628: public AttributeTable getAttributes(Map parameters) {
0629: Hashtable table = createStandardAttributeTable(parameters);
0630:
0631: DEROctetString val = new DEROctetString(
0632: (byte[]) parameters
0633: .get(CMSAttributeTableGenerator.DIGEST));
0634: Attribute attr = new Attribute(dummyOid1, new DERSet(
0635: val));
0636:
0637: table.put(attr.getAttrType(), attr);
0638:
0639: return new AttributeTable(table);
0640: }
0641: };
0642:
0643: CMSAttributeTableGenerator unsignedGen = new CMSAttributeTableGenerator() {
0644: public AttributeTable getAttributes(Map parameters) {
0645: DEROctetString val = new DEROctetString(
0646: (byte[]) parameters
0647: .get(CMSAttributeTableGenerator.SIGNATURE));
0648: Attribute attr = new Attribute(dummyOid2, new DERSet(
0649: val));
0650:
0651: return new AttributeTable(new DERSet(attr));
0652: }
0653: };
0654:
0655: gen.addSigner(_origKP.getPrivate(), _origCert,
0656: CMSSignedDataStreamGenerator.DIGEST_SHA1, signedGen,
0657: unsignedGen, "BC");
0658:
0659: gen.addCertificatesAndCRLs(certs);
0660:
0661: OutputStream sigOut = gen.open(bOut, true);
0662:
0663: sigOut.write(TEST_MESSAGE.getBytes());
0664:
0665: sigOut.close();
0666:
0667: CMSSignedDataParser sp = new CMSSignedDataParser(bOut
0668: .toByteArray());
0669:
0670: sp.getSignedContent().drain();
0671:
0672: verifySignatures(sp);
0673:
0674: //
0675: // check attributes
0676: //
0677: SignerInformationStore signers = sp.getSignerInfos();
0678:
0679: Collection c = signers.getSigners();
0680: Iterator it = c.iterator();
0681:
0682: while (it.hasNext()) {
0683: SignerInformation signer = (SignerInformation) it.next();
0684: checkAttribute(signer.getContentDigest(), signer
0685: .getSignedAttributes().get(dummyOid1));
0686: checkAttribute(signer.getSignature(), signer
0687: .getUnsignedAttributes().get(dummyOid2));
0688: }
0689: }
0690:
0691: private void checkAttribute(byte[] expected, Attribute attr) {
0692: DEROctetString value = (DEROctetString) attr.getAttrValues()
0693: .getObjectAt(0);
0694:
0695: assertEquals(new DEROctetString(expected), value);
0696: }
0697:
0698: public void testWithAttributeCertificate() throws Exception {
0699: List certList = new ArrayList();
0700:
0701: certList.add(_signCert);
0702:
0703: CertStore certs = CertStore.getInstance("Collection",
0704: new CollectionCertStoreParameters(certList), "BC");
0705:
0706: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0707:
0708: gen.addSigner(_origKP.getPrivate(), _origCert,
0709: CMSSignedDataGenerator.DIGEST_SHA1, "BC");
0710:
0711: gen.addCertificatesAndCRLs(certs);
0712:
0713: X509AttributeCertificate attrCert = CMSTestUtil
0714: .getAttributeCertificate();
0715:
0716: X509Store store = X509Store.getInstance(
0717: "AttributeCertificate/Collection",
0718: new X509CollectionStoreParameters(Collections
0719: .singleton(attrCert)), "BC");
0720:
0721: gen.addAttributeCertificates(store);
0722:
0723: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0724:
0725: OutputStream sigOut = gen.open(bOut, true);
0726:
0727: sigOut.write(TEST_MESSAGE.getBytes());
0728:
0729: sigOut.close();
0730:
0731: CMSSignedDataParser sp = new CMSSignedDataParser(bOut
0732: .toByteArray());
0733:
0734: sp.getSignedContent().drain();
0735:
0736: assertEquals(4, sp.getVersion());
0737:
0738: store = sp.getAttributeCertificates("Collection", "BC");
0739:
0740: Collection coll = store.getMatches(null);
0741:
0742: assertEquals(1, coll.size());
0743:
0744: assertTrue(coll.contains(attrCert));
0745: }
0746:
0747: public void testSignerStoreReplacement() throws Exception {
0748: List certList = new ArrayList();
0749: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0750: byte[] data = TEST_MESSAGE.getBytes();
0751:
0752: certList.add(_origCert);
0753: certList.add(_signCert);
0754:
0755: CertStore certs = CertStore.getInstance("Collection",
0756: new CollectionCertStoreParameters(certList), "BC");
0757:
0758: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0759:
0760: gen.addSigner(_origKP.getPrivate(), _origCert,
0761: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0762:
0763: gen.addCertificatesAndCRLs(certs);
0764:
0765: OutputStream sigOut = gen.open(bOut, false);
0766:
0767: sigOut.write(data);
0768:
0769: sigOut.close();
0770:
0771: //
0772: // create new Signer
0773: //
0774: ByteArrayInputStream original = new ByteArrayInputStream(bOut
0775: .toByteArray());
0776:
0777: bOut.reset();
0778:
0779: gen = new CMSSignedDataStreamGenerator();
0780:
0781: gen.addSigner(_origKP.getPrivate(), _origCert,
0782: CMSSignedDataStreamGenerator.DIGEST_SHA224, "BC");
0783:
0784: gen.addCertificatesAndCRLs(certs);
0785:
0786: sigOut = gen.open(bOut);
0787:
0788: sigOut.write(data);
0789:
0790: sigOut.close();
0791:
0792: CMSSignedData sd = new CMSSignedData(bOut.toByteArray());
0793:
0794: //
0795: // replace signer
0796: //
0797: ByteArrayOutputStream newOut = new ByteArrayOutputStream();
0798:
0799: CMSSignedDataParser.replaceSigners(original, sd
0800: .getSignerInfos(), newOut);
0801:
0802: sd = new CMSSignedData(new CMSProcessableByteArray(data),
0803: newOut.toByteArray());
0804: SignerInformation signer = (SignerInformation) sd
0805: .getSignerInfos().getSigners().iterator().next();
0806:
0807: assertEquals(signer.getDigestAlgOID(),
0808: CMSSignedDataStreamGenerator.DIGEST_SHA224);
0809:
0810: CMSSignedDataParser sp = new CMSSignedDataParser(
0811: new CMSTypedStream(new ByteArrayInputStream(data)),
0812: newOut.toByteArray());
0813:
0814: sp.getSignedContent().drain();
0815:
0816: verifySignatures(sp);
0817: }
0818:
0819: public void testEncapsulatedSignerStoreReplacement()
0820: throws Exception {
0821: List certList = new ArrayList();
0822: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0823:
0824: certList.add(_origCert);
0825: certList.add(_signCert);
0826:
0827: CertStore certs = CertStore.getInstance("Collection",
0828: new CollectionCertStoreParameters(certList), "BC");
0829:
0830: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0831:
0832: gen.addSigner(_origKP.getPrivate(), _origCert,
0833: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0834:
0835: gen.addCertificatesAndCRLs(certs);
0836:
0837: OutputStream sigOut = gen.open(bOut, true);
0838:
0839: sigOut.write(TEST_MESSAGE.getBytes());
0840:
0841: sigOut.close();
0842:
0843: //
0844: // create new Signer
0845: //
0846: ByteArrayInputStream original = new ByteArrayInputStream(bOut
0847: .toByteArray());
0848:
0849: bOut.reset();
0850:
0851: gen = new CMSSignedDataStreamGenerator();
0852:
0853: gen.addSigner(_origKP.getPrivate(), _origCert,
0854: CMSSignedDataStreamGenerator.DIGEST_SHA224, "BC");
0855:
0856: gen.addCertificatesAndCRLs(certs);
0857:
0858: sigOut = gen.open(bOut, true);
0859:
0860: sigOut.write(TEST_MESSAGE.getBytes());
0861:
0862: sigOut.close();
0863:
0864: CMSSignedData sd = new CMSSignedData(bOut.toByteArray());
0865:
0866: //
0867: // replace signer
0868: //
0869: ByteArrayOutputStream newOut = new ByteArrayOutputStream();
0870:
0871: CMSSignedDataParser.replaceSigners(original, sd
0872: .getSignerInfos(), newOut);
0873:
0874: sd = new CMSSignedData(newOut.toByteArray());
0875: SignerInformation signer = (SignerInformation) sd
0876: .getSignerInfos().getSigners().iterator().next();
0877:
0878: assertEquals(signer.getDigestAlgOID(),
0879: CMSSignedDataStreamGenerator.DIGEST_SHA224);
0880:
0881: CMSSignedDataParser sp = new CMSSignedDataParser(newOut
0882: .toByteArray());
0883:
0884: sp.getSignedContent().drain();
0885:
0886: verifySignatures(sp);
0887: }
0888:
0889: public void testCertStoreReplacement() throws Exception {
0890: List certList = new ArrayList();
0891: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0892: byte[] data = TEST_MESSAGE.getBytes();
0893:
0894: certList.add(_origDsaCert);
0895:
0896: CertStore certs = CertStore.getInstance("Collection",
0897: new CollectionCertStoreParameters(certList), "BC");
0898:
0899: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0900:
0901: gen.addSigner(_origKP.getPrivate(), _origCert,
0902: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0903:
0904: gen.addCertificatesAndCRLs(certs);
0905:
0906: OutputStream sigOut = gen.open(bOut);
0907:
0908: sigOut.write(data);
0909:
0910: sigOut.close();
0911:
0912: //
0913: // create new certstore with the right certificates
0914: //
0915: certList = new ArrayList();
0916: certList.add(_origCert);
0917: certList.add(_signCert);
0918:
0919: certs = CertStore.getInstance("Collection",
0920: new CollectionCertStoreParameters(certList), "BC");
0921:
0922: //
0923: // replace certs
0924: //
0925: ByteArrayInputStream original = new ByteArrayInputStream(bOut
0926: .toByteArray());
0927: ByteArrayOutputStream newOut = new ByteArrayOutputStream();
0928:
0929: CMSSignedDataParser.replaceCertificatesAndCRLs(original, certs,
0930: newOut);
0931:
0932: CMSSignedDataParser sp = new CMSSignedDataParser(
0933: new CMSTypedStream(new ByteArrayInputStream(data)),
0934: newOut.toByteArray());
0935:
0936: sp.getSignedContent().drain();
0937:
0938: verifySignatures(sp);
0939: }
0940:
0941: public void testEncapsulatedCertStoreReplacement() throws Exception {
0942: List certList = new ArrayList();
0943: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0944:
0945: certList.add(_origDsaCert);
0946:
0947: CertStore certs = CertStore.getInstance("Collection",
0948: new CollectionCertStoreParameters(certList), "BC");
0949:
0950: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
0951:
0952: gen.addSigner(_origKP.getPrivate(), _origCert,
0953: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
0954:
0955: gen.addCertificatesAndCRLs(certs);
0956:
0957: OutputStream sigOut = gen.open(bOut, true);
0958:
0959: sigOut.write(TEST_MESSAGE.getBytes());
0960:
0961: sigOut.close();
0962:
0963: //
0964: // create new certstore with the right certificates
0965: //
0966: certList = new ArrayList();
0967: certList.add(_origCert);
0968: certList.add(_signCert);
0969:
0970: certs = CertStore.getInstance("Collection",
0971: new CollectionCertStoreParameters(certList), "BC");
0972:
0973: //
0974: // replace certs
0975: //
0976: ByteArrayInputStream original = new ByteArrayInputStream(bOut
0977: .toByteArray());
0978: ByteArrayOutputStream newOut = new ByteArrayOutputStream();
0979:
0980: CMSSignedDataParser.replaceCertificatesAndCRLs(original, certs,
0981: newOut);
0982:
0983: CMSSignedDataParser sp = new CMSSignedDataParser(newOut
0984: .toByteArray());
0985:
0986: sp.getSignedContent().drain();
0987:
0988: verifySignatures(sp);
0989: }
0990:
0991: public void testCertOrdering1() throws Exception {
0992: List certList = new ArrayList();
0993: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0994:
0995: certList.add(_origCert);
0996: certList.add(_signCert);
0997:
0998: CertStore certs = CertStore.getInstance("Collection",
0999: new CollectionCertStoreParameters(certList), "BC");
1000:
1001: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
1002:
1003: gen.addSigner(_origKP.getPrivate(), _origCert,
1004: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
1005:
1006: gen.addCertificatesAndCRLs(certs);
1007:
1008: OutputStream sigOut = gen.open(bOut, true);
1009:
1010: sigOut.write(TEST_MESSAGE.getBytes());
1011:
1012: sigOut.close();
1013:
1014: CMSSignedDataParser sp = new CMSSignedDataParser(bOut
1015: .toByteArray());
1016:
1017: sp.getSignedContent().drain();
1018: certs = sp.getCertificatesAndCRLs("Collection", "BC");
1019: Iterator it = certs.getCertificates(null).iterator();
1020:
1021: assertEquals(_origCert, it.next());
1022: assertEquals(_signCert, it.next());
1023: }
1024:
1025: public void testCertOrdering2() throws Exception {
1026: List certList = new ArrayList();
1027: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
1028:
1029: certList.add(_signCert);
1030: certList.add(_origCert);
1031:
1032: CertStore certs = CertStore.getInstance("Collection",
1033: new CollectionCertStoreParameters(certList), "BC");
1034:
1035: CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
1036:
1037: gen.addSigner(_origKP.getPrivate(), _origCert,
1038: CMSSignedDataStreamGenerator.DIGEST_SHA1, "BC");
1039:
1040: gen.addCertificatesAndCRLs(certs);
1041:
1042: OutputStream sigOut = gen.open(bOut, true);
1043:
1044: sigOut.write(TEST_MESSAGE.getBytes());
1045:
1046: sigOut.close();
1047:
1048: CMSSignedDataParser sp = new CMSSignedDataParser(bOut
1049: .toByteArray());
1050:
1051: sp.getSignedContent().drain();
1052: certs = sp.getCertificatesAndCRLs("Collection", "BC");
1053: Iterator it = certs.getCertificates(null).iterator();
1054:
1055: assertEquals(_signCert, it.next());
1056: assertEquals(_origCert, it.next());
1057: }
1058:
1059: public static Test suite() throws Exception {
1060: init();
1061:
1062: return new CMSTestSetup(new TestSuite(
1063: SignedDataStreamTest.class));
1064: }
1065: }
|