blob: 27630832cd051d598dc5fc146646bb73fbc05afc [file] [log] [blame]
package org.bouncycastle.cert.cmp.test;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Date;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.cmp.CertConfirmContent;
import org.bouncycastle.asn1.cmp.CertRepMessage;
import org.bouncycastle.asn1.cmp.PKIBody;
import org.bouncycastle.asn1.cmp.PKIMessage;
import org.bouncycastle.asn1.crmf.CertReqMessages;
import org.bouncycastle.asn1.crmf.CertReqMsg;
import org.bouncycastle.asn1.crmf.ProofOfPossession;
import org.bouncycastle.asn1.crmf.SubsequentMessage;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.cert.CertException;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.cmp.CertificateConfirmationContent;
import org.bouncycastle.cert.cmp.CertificateConfirmationContentBuilder;
import org.bouncycastle.cert.cmp.CertificateStatus;
import org.bouncycastle.cert.cmp.GeneralPKIMessage;
import org.bouncycastle.cert.cmp.ProtectedPKIMessage;
import org.bouncycastle.cert.cmp.ProtectedPKIMessageBuilder;
import org.bouncycastle.cert.crmf.CertificateRequestMessage;
import org.bouncycastle.cert.crmf.CertificateRequestMessageBuilder;
import org.bouncycastle.cert.crmf.PKMACBuilder;
import org.bouncycastle.cert.crmf.jcajce.JcaCertificateRequestMessageBuilder;
import org.bouncycastle.cert.crmf.jcajce.JcePKMACValuesCalculator;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.ContentVerifierProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.io.Streams;
public class AllTests
extends TestCase
{
private static final byte[] TEST_DATA = "Hello world!".getBytes();
private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
private static final String TEST_DATA_HOME = "bc.test.data.home";
/*
*
* INFRASTRUCTURE
*
*/
public AllTests(String name)
{
super(name);
}
public static void main(String args[])
{
junit.textui.TestRunner.run(AllTests.class);
}
public static Test suite()
{
return new TestSuite(AllTests.class);
}
public void setUp()
{
Security.addProvider(new BouncyCastleProvider());
}
public void tearDown()
{
}
public void testProtectedMessage()
throws Exception
{
KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
kGen.initialize(512);
KeyPair kp = kGen.generateKeyPair();
X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test");
GeneralName sender = new GeneralName(new X500Name("CN=Sender"));
GeneralName recipient = new GeneralName(new X500Name("CN=Recip"));
ContentSigner signer = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(kp.getPrivate());
ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient)
.setBody(new PKIBody(PKIBody.TYPE_INIT_REP, CertRepMessage.getInstance(new DERSequence(new DERSequence()))))
.addCMPCertificate(cert)
.build(signer);
X509Certificate jcaCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(message.getCertificates()[0]);
ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaCert.getPublicKey());
assertTrue(message.verify(verifierProvider));
assertEquals(sender, message.getHeader().getSender());
assertEquals(recipient, message.getHeader().getRecipient());
}
public void testMacProtectedMessage()
throws Exception
{
KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
kGen.initialize(512);
KeyPair kp = kGen.generateKeyPair();
X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test");
GeneralName sender = new GeneralName(new X500Name("CN=Sender"));
GeneralName recipient = new GeneralName(new X500Name("CN=Recip"));
ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient)
.setBody(new PKIBody(PKIBody.TYPE_INIT_REP, CertRepMessage.getInstance(new DERSequence(new DERSequence()))))
.addCMPCertificate(cert)
.build(new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)).build("secret".toCharArray()));
PKMACBuilder pkMacBuilder = new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC));
assertTrue(message.verify(pkMacBuilder, "secret".toCharArray()));
assertEquals(sender, message.getHeader().getSender());
assertEquals(recipient, message.getHeader().getRecipient());
}
public void testConfirmationMessage()
throws Exception
{
KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
kGen.initialize(512);
KeyPair kp = kGen.generateKeyPair();
X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test");
GeneralName sender = new GeneralName(new X500Name("CN=Sender"));
GeneralName recipient = new GeneralName(new X500Name("CN=Recip"));
CertificateConfirmationContent content = new CertificateConfirmationContentBuilder()
.addAcceptedCertificate(cert, BigInteger.valueOf(1))
.build(new JcaDigestCalculatorProviderBuilder().build());
ContentSigner signer = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(kp.getPrivate());
ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient)
.setBody(new PKIBody(PKIBody.TYPE_CERT_CONFIRM, content.toASN1Structure()))
.addCMPCertificate(cert)
.build(signer);
X509Certificate jcaCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(message.getCertificates()[0]);
ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaCert.getPublicKey());
assertTrue(message.verify(verifierProvider));
assertEquals(sender, message.getHeader().getSender());
assertEquals(recipient, message.getHeader().getRecipient());
content = new CertificateConfirmationContent(CertConfirmContent.getInstance(message.getBody().getContent()));
CertificateStatus[] statusList = content.getStatusMessages();
assertEquals(1, statusList.length);
assertTrue(statusList[0].isVerified(cert, new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()));
}
public void testSampleCr()
throws Exception
{
PKIMessage msg = loadMessage("sample_cr.der");
ProtectedPKIMessage procMsg = new ProtectedPKIMessage(new GeneralPKIMessage(msg));
assertTrue(procMsg.verify(new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)), "TopSecret1234".toCharArray()));
}
public void testSubsequentMessage()
throws Exception
{
KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
kGen.initialize(512);
KeyPair kp = kGen.generateKeyPair();
X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test");
ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").setProvider(BC).build(
kp.getPrivate());
GeneralName user = new GeneralName(new X500Name("CN=Test"));
CertificateRequestMessageBuilder builder = new JcaCertificateRequestMessageBuilder(
BigInteger.valueOf(1)).setPublicKey(kp.getPublic()).setProofOfPossessionSubsequentMessage(
SubsequentMessage.encrCert);
ProtectedPKIMessage certRequestMsg = new ProtectedPKIMessageBuilder(user,
user).setTransactionID(new byte[] { 1, 2, 3, 4, 5 }).setBody(
new PKIBody(PKIBody.TYPE_KEY_UPDATE_REQ, new CertReqMessages(builder.build().toASN1Structure()))).addCMPCertificate(
cert).build(signer);
ProtectedPKIMessage msg = new ProtectedPKIMessage(new GeneralPKIMessage(certRequestMsg.toASN1Structure().getEncoded()));
CertReqMessages reqMsgs = CertReqMessages.getInstance(msg.getBody().getContent());
CertReqMsg reqMsg = reqMsgs.toCertReqMsgArray()[0];
assertEquals(ProofOfPossession.TYPE_KEY_ENCIPHERMENT, reqMsg.getPopo().getType());
}
public void testNotBeforeNotAfter()
throws Exception
{
KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
kGen.initialize(512);
KeyPair kp = kGen.generateKeyPair();
doNotBeforeNotAfterTest(kp, new Date(0L), new Date(60000L));
doNotBeforeNotAfterTest(kp, null, new Date(60000L));
doNotBeforeNotAfterTest(kp, new Date(0L), null);
}
private void doNotBeforeNotAfterTest(KeyPair kp, Date notBefore, Date notAfter)
throws Exception
{
CertificateRequestMessageBuilder builder = new JcaCertificateRequestMessageBuilder(
BigInteger.valueOf(1)).setPublicKey(kp.getPublic()).setProofOfPossessionSubsequentMessage(
SubsequentMessage.encrCert);
builder.setValidity(notBefore, notAfter);
CertificateRequestMessage message = builder.build();
if (notBefore != null)
{
assertEquals(notBefore.getTime(), message.getCertTemplate().getValidity().getNotBefore().getDate().getTime());
}
else
{
assertNull(message.getCertTemplate().getValidity().getNotBefore());
}
if (notAfter != null)
{
assertEquals(notAfter.getTime(), message.getCertTemplate().getValidity().getNotAfter().getDate().getTime());
}
else
{
assertNull(message.getCertTemplate().getValidity().getNotAfter());
}
}
private static X509CertificateHolder makeV3Certificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN)
throws GeneralSecurityException, IOException, OperatorCreationException, CertException
{
PublicKey subPub = subKP.getPublic();
PrivateKey issPriv = issKP.getPrivate();
PublicKey issPub = issKP.getPublic();
X509v3CertificateBuilder v1CertGen = new JcaX509v3CertificateBuilder(
new X500Name(_issDN),
BigInteger.valueOf(System.currentTimeMillis()),
new Date(System.currentTimeMillis()),
new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)),
new X500Name(_subDN),
subPub);
ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(issPriv);
X509CertificateHolder certHolder = v1CertGen.build(signer);
ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(BC).build(issPub);
assertTrue(certHolder.isSignatureValid(verifier));
return certHolder;
}
private static PKIMessage loadMessage(String name)
{
String dataHome = System.getProperty(TEST_DATA_HOME);
if (dataHome == null)
{
throw new IllegalStateException(TEST_DATA_HOME + " property not set");
}
try
{
return PKIMessage.getInstance(ASN1Primitive.fromByteArray(Streams.readAll(new FileInputStream(dataHome + "/cmp/" + name))));
}
catch (IOException e)
{
throw new RuntimeException(e.toString());
}
}
}