/* * Copyright (c) 2011-2012 ICM Uniwersytet Warszawski All rights reserved. * See LICENCE.txt file for licensing information. */ package eu.emi.security.authn.x509.proxy; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.StringReader; import java.io.StringWriter; import java.math.BigInteger; import java.security.PrivateKey; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509v2AttributeCertificateBuilder; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.openssl.jcajce.JcaPEMWriter; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.junit.Test; import eu.emi.security.authn.x509.ValidationResult; import eu.emi.security.authn.x509.X509CertChainValidator; import eu.emi.security.authn.x509.X509Credential; import eu.emi.security.authn.x509.helpers.proxy.ProxyACExtension; import eu.emi.security.authn.x509.impl.CertificateUtils; import eu.emi.security.authn.x509.impl.CertificateUtils.Encoding; import eu.emi.security.authn.x509.impl.CertificateUtilsTest; import eu.emi.security.authn.x509.impl.DirectoryCertChainValidator; import eu.emi.security.authn.x509.impl.KeyAndCertCredential; import eu.emi.security.authn.x509.impl.KeystoreCertChainValidator; import eu.emi.security.authn.x509.impl.KeystoreCredential; import eu.emi.security.authn.x509.impl.PEMCredential; import eu.emi.security.authn.x509.impl.TestSSLHelpers; import org.junit.Assert; public class ProxyGenerationTest { /** * Tests whether deserialization from PEM loaded CSR works and whether a proxy generated from CSR has a * different serial then the previous one. It is also tested if limited flag works on RFC proxies. * @throws Exception */ @Test public void testCSRDeserializationLoading() throws Exception { X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); ProxyCertificateOptions param = new ProxyCertificateOptions(credential.getCertificateChain()); param.setLimited(true); ProxyCertificate proxy1 = ProxyGenerator.generate(param, credential.getKey()); X509Certificate[] certs = proxy1.getCertificateChain(); ProxyCertificateOptions options = new ProxyCertificateOptions(certs); options.setLimited(true); ProxyCSR proxyCsr = ProxyCSRGenerator.generate(options); PKCS10CertificationRequest req = proxyCsr.getCSR(); StringWriter stringWriter = new StringWriter(); JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter); pemWriter.writeObject(req); pemWriter.close(); String certRequest = stringWriter.toString(); PEMParser pemReader = new PEMParser(new StringReader(certRequest)); PKCS10CertificationRequest req2; try { req2 = (PKCS10CertificationRequest) pemReader.readObject(); } finally { pemReader.close(); } ProxyCSRInfo info2 = new ProxyCSRInfo(req2); assertEquals(new ProxyPolicy(ProxyPolicy.LIMITED_PROXY_OID), info2.getPolicy()); assertEquals(ProxyType.RFC3820, info2.getProxyType()); ProxyRequestOptions proxy2Param = new ProxyRequestOptions(certs, req2); X509Certificate[] proxy2 = ProxyGenerator.generate(proxy2Param, credential.getKey()); String[] avas = proxy2[0].getSubjectX500Principal().getName().split(","); String[] cn1 = avas[0].split("="); String[] cn2 = avas[1].split("="); assertNotSame(cn1[1], cn2[1]); } /** * Basic generation of the CSR and proxy from CSR. * @FunctionalTest(id="func:proxy-delegate", description="Generates a proxy CSR, then a proxy from this CSR.") * @throws Exception */ @Test public void testGenerateWithCSR() throws Exception { System.out.println("Running func:proxy-delegate functional test"); X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); PrivateKey privateKey = credential.getKey(); Certificate c[] = credential.getCertificateChain(); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions csrParam = new ProxyCertificateOptions(chain); csrParam.setType(ProxyType.LEGACY); ProxyCSR csr = ProxyCSRGenerator.generate(csrParam); ProxyRequestOptions proxyParam = new ProxyRequestOptions(chain, csr.getCSR()); ProxyCSRInfo csrInfo = new ProxyCSRInfo(csr.getCSR()); proxyParam.setType(csrInfo.getProxyType()); X509Certificate[] proxy = ProxyGenerator.generate(proxyParam, privateKey); JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); assertEquals(converter.getPublicKey(csr.getCSR().getSubjectPublicKeyInfo()), proxy[0].getPublicKey()); assertTrue(proxy[0].getSubjectX500Principal().equals(new X500Principal("CN=proxy, CN=PDPTest Server, O=Testing Organization, L=Testing City, C=EU"))); assertTrue(new ProxyChainInfo(proxy).getProxyType().equals(ProxyChainType.LEGACY)); X509Certificate eec = ProxyUtils.getEndUserCertificate(proxy); assertEquals(chain[0], eec); X500Principal eep = ProxyUtils.getOriginalUserDN(proxy); assertEquals(chain[0].getSubjectX500Principal(), eep); assertTrue(proxy[0].getCriticalExtensionOIDs().contains("2.5.29.15")); } /** * Checks if a proxy can be generated with unlimited proxy length */ @Test public void unlimitedProxyIsGenerated() throws Exception { X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); PrivateKey privateKey = credential.getKey(); Certificate c[] = credential.getCertificateChain(); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions csrParam = new ProxyCertificateOptions(chain); csrParam.setProxyPathLimit(BaseProxyCertificateOptions.UNLIMITED_PROXY_LENGTH); ProxyCSR csr = ProxyCSRGenerator.generate(csrParam); assertThat(new ProxyCSRInfo(csr.getCSR()).getProxyPathLimit(), is(Integer.MAX_VALUE)); ProxyRequestOptions proxyParam = new ProxyRequestOptions(chain, csr.getCSR()); ProxyCSRInfo csrInfo = new ProxyCSRInfo(csr.getCSR()); proxyParam.setType(csrInfo.getProxyType()); proxyParam.setProxyPathLimit(BaseProxyCertificateOptions.UNLIMITED_PROXY_LENGTH); X509Certificate[] proxy = ProxyGenerator.generate(proxyParam, privateKey); assertThat(new ProxyChainInfo(proxy).getRemainingPathLimit(), is(Integer.MAX_VALUE - 1)); } /** * Checks if a proxy can be generated with limited proxy length */ @Test public void limitedProxyIsGenerated() throws Exception { X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); PrivateKey privateKey = credential.getKey(); Certificate c[] = credential.getCertificateChain(); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions csrParam = new ProxyCertificateOptions(chain); csrParam.setProxyPathLimit(3); csrParam.setType(ProxyType.RFC3820); ProxyCSR csr = ProxyCSRGenerator.generate(csrParam); assertThat(new ProxyCSRInfo(csr.getCSR()).getProxyPathLimit(), is(3)); ProxyRequestOptions proxyParam = new ProxyRequestOptions(chain, csr.getCSR()); ProxyCSRInfo csrInfo = new ProxyCSRInfo(csr.getCSR()); proxyParam.setType(csrInfo.getProxyType()); proxyParam.setProxyPathLimit(3); X509Certificate[] proxy = ProxyGenerator.generate(proxyParam, privateKey); assertThat(new ProxyChainInfo(proxy).getRemainingPathLimit(), is(3)); } @Test public void testCSRAttributes() throws Exception { X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); Certificate c[] = credential.getKeyStore().getCertificateChain(credential.getKeyAlias()); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions csrParam = new ProxyCertificateOptions(chain); PrivateKey privateKey = (PrivateKey) credential.getKeyStore().getKey( credential.getKeyAlias(), credential.getKeyPassword()); csrParam.setPublicKey(chain[0].getPublicKey()); csrParam.setSerialNumber(new BigInteger("1234567")); csrParam.setType(ProxyType.RFC3820); // csrParam.setPolicy(new ProxyPolicy(ProxyPolicy.INDEPENDENT_POLICY_OID)); csrParam.setPolicy(new ProxyPolicy(ProxyPolicy.LIMITED_PROXY_OID)); csrParam.setProxyPathLimit(11); csrParam.setProxyTracingIssuer("http://tracing.issuer.example.net"); csrParam.setProxyTracingSubject("http://tracing.subject.example.net"); csrParam.setSAMLAssertion("<fake>saml assertion</fake>"); csrParam.setSourceRestrictionExcludedAddresses(new byte[][] {{(byte)192,(byte)168,12,0, (byte)255,(byte)255,(byte)255,0}}); csrParam.setSourceRestrictionPermittedAddresses(new String[] {"192.168.0.0/16"}); csrParam.setTargetRestrictionExcludedAddresses(new byte[][] {{(byte)192,(byte)168,13,0, (byte)255,(byte)255,(byte)255,0}}); csrParam.setTargetRestrictionPermittedAddresses(new String[] {"192.168.0.0/16", "10.0.0.0/8"}); try { ProxyCSRGenerator.generate(csrParam); fail("Should get IAException"); } catch (IllegalArgumentException e) { //OK } ProxyCSR csr = ProxyCSRGenerator.generate(csrParam, privateKey); ProxyCSRInfo info = new ProxyCSRInfo(csr.getCSR()); JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); assertEquals(chain[0].getPublicKey(), converter.getPublicKey(csr.getCSR().getSubjectPublicKeyInfo())); assertEquals(ProxyType.RFC3820, info.getProxyType()); byte[] subject = csr.getCSR().getSubject().getEncoded(); X500Principal p = new X500Principal(subject); assertTrue(p.getName().contains("CN=1234567")); //assertEquals(new ProxyPolicy(ProxyPolicy.INDEPENDENT_POLICY_OID), info.getPolicy()); assertEquals(new ProxyPolicy(ProxyPolicy.LIMITED_PROXY_OID), info.getPolicy()); assertEquals(11, (int)info.getProxyPathLimit()); assertEquals("http://tracing.issuer.example.net", info.getProxyTracingIssuer()); assertEquals("http://tracing.subject.example.net", info.getProxyTracingSubject()); assertEquals("<fake>saml assertion</fake>", info.getSAMLExtension()); assertArrayEquals(new String[][] {{"192.168.0.0/16"}, {"192.168.12.0/24"}}, info.getProxySourceRestrictions()); assertArrayEquals(new String[][] {{"192.168.0.0/16", "10.0.0.0/8"}, {"192.168.13.0/24"}}, info.getProxyTargetRestrictions()); } /** @FunctionalTest(id="func:proxy-make", description="Generates a proxy from a local cert+priv key," + " setting all possible parameters.") */ @Test public void testWithChainInfo() throws Exception { System.out.println("Running func:proxy-make functional test"); X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); Certificate c[] = credential.getKeyStore().getCertificateChain(credential.getKeyAlias()); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions param = new ProxyCertificateOptions(chain); PrivateKey privateKey = (PrivateKey) credential.getKeyStore().getKey( credential.getKeyAlias(), credential.getKeyPassword()); //yep - in reality privKey will be different but here we don't care. AttributeCertificate ac = generateAC(chain[0].getSubjectX500Principal().getName(), privateKey); byte[] origIssuer = ac.getAcinfo().getIssuer().getEncoded(); param.setAttributeCertificates(new AttributeCertificate[] {ac}); param.setSerialNumber(new BigInteger("1234567")); param.setType(ProxyType.DRAFT_RFC); param.setPolicy(new ProxyPolicy(ProxyPolicy.LIMITED_PROXY_OID)); param.setProxyPathLimit(11); param.setProxyTracingIssuer("http://tracing.issuer.example.net"); param.setProxyTracingSubject("http://tracing.subject.example.net"); param.setSAMLAssertion("<fake>saml assertion</fake>"); param.setSourceRestrictionPermittedAddresses(new byte[][] {{(byte)192,(byte)168,12,0, (byte)255,(byte)255,(byte)255,0}}); param.setSourceRestrictionExcludedAddresses(new String[] {"192.168.13.0/24"}); param.setTargetRestrictionPermittedAddresses(new byte[][] {{(byte)192,(byte)168,0,0, (byte)255,(byte)255,0,0}}); param.setTargetRestrictionExcludedAddresses(new String[] {"192.168.3.0/24", "192.168.14.0/24"}); ProxyCertificate proxy1 = ProxyGenerator.generate(param, privateKey); ProxyChainInfo chainInfo = new ProxyChainInfo(proxy1.getCertificateChain()); assertNotNull(chainInfo.getAttributeCertificateExtensions()[0]); assertEquals(1, chainInfo.getAttributeCertificateExtensions()[0].length); byte[] issuerRaw = chainInfo.getAttributeCertificateExtensions()[0][0].getAcinfo(). getIssuer().getEncoded(); assertArrayEquals(origIssuer, issuerRaw); assertEquals(0, chainInfo.getFirstProxyPosition()); assertEquals(new ProxyPolicy(ProxyPolicy.LIMITED_PROXY_OID), chainInfo.getPolicy()[0]); assertEquals(11, chainInfo.getRemainingPathLimit()); assertEquals(ProxyChainType.DRAFT_RFC, chainInfo.getProxyType()); assertTrue(chainInfo.isLimited()); assertEquals(new BigInteger("1234567"), chainInfo.getSerialNumbers()[0]); assertEquals("http://tracing.issuer.example.net", chainInfo.getProxyTracingIssuers()[0]); assertEquals("http://tracing.subject.example.net", chainInfo.getProxyTracingSubjects()[0]); assertEquals("<fake>saml assertion</fake>", chainInfo.getSAMLExtensions()[0]); assertArrayEquals(new byte[][][] {{{(byte)192,(byte)168,12,0, (byte)255,(byte)255,(byte)255,0}}, {{(byte)192,(byte)168,13,(byte)0, (byte)255,(byte)255,(byte)255,(byte)0}}}, chainInfo.getProxySourceRestrictions()); assertArrayEquals(new byte[][][] {{{(byte)192,(byte)168,0,0,(byte)255,(byte)255,0,0}}, {{(byte)192,(byte)168,3,0, (byte)255,(byte)255,(byte)255,0}, {(byte)192,(byte)168,14,0, (byte)255,(byte)255,(byte)255,0}}}, chainInfo.getProxyTargetRestrictions()); assertTrue(chainInfo.isHostAllowedAsSource(new byte[] {(byte)192,(byte)168,12,20})); assertFalse(chainInfo.isHostAllowedAsSource(new byte[] {(byte)192,(byte)168,13,(byte)129})); assertTrue(chainInfo.isHostAllowedAsTarget(new byte[] {(byte)192,(byte)168,1,1})); assertFalse(chainInfo.isHostAllowedAsTarget(new byte[] {(byte)192,(byte)168,14,1})); assertFalse(chainInfo.isHostAllowedAsTarget(new byte[] {(byte)192,(byte)168,3,13})); } private AttributeCertificate generateAC(String subject, PrivateKey privateKey) throws OperatorCreationException { AttributeCertificateIssuer issuer = new AttributeCertificateIssuer( new X500Name("CN=fake VOMS,C=IT")); AttributeCertificateHolder holder = new AttributeCertificateHolder( new X500Name(subject)); X509v2AttributeCertificateBuilder builder = new X509v2AttributeCertificateBuilder( holder, issuer, new BigInteger("123"), new Date(), new Date()); ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").build(privateKey); X509AttributeCertificateHolder acHolder = builder.build(signer); return acHolder.toASN1Structure(); } @Test public void testCSRForLegacy() throws Exception { X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); Certificate c[] = credential.getKeyStore().getCertificateChain(credential.getKeyAlias()); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions csrParam = new ProxyCertificateOptions(chain); csrParam.setType(ProxyType.LEGACY); csrParam.setLimited(true); ProxyCSR csr = ProxyCSRGenerator.generate(csrParam); ProxyCSRInfo info = new ProxyCSRInfo(csr.getCSR()); assertEquals(ProxyType.LEGACY, info.getProxyType()); assertEquals(true, info.isLimited()); } /** * Tests whether default key size of the proxy is correct: 1024 bit for * proxies valid for less then 10 days and 2048 for longer ones. * @throws Exception */ @Test public void testDefaultKeysize() throws Exception { X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); PrivateKey privateKey = credential.getKey(); X509Certificate chain[] = credential.getCertificateChain(); ProxyCertificateOptions param = new ProxyCertificateOptions(chain); assertEquals(param.getKeyLength(), 1024); assertTrue(param.getLifetime() < ProxyCertificateOptions.LONG_PROXY); ProxyCertificate proxy1 = ProxyGenerator.generate(param, privateKey); int bitLength = ((RSAPublicKey)proxy1.getCertificateChain()[0].getPublicKey()). getModulus().bitLength(); assertEquals(1024, bitLength); param.setLifetime(3600000); ProxyCertificate proxy2 = ProxyGenerator.generate(param, privateKey); int bitLength2 = ((RSAPublicKey)proxy2.getCertificateChain()[0].getPublicKey()). getModulus().bitLength(); assertEquals(2048, bitLength2); } /** * This test tests performs for an EEC cert with each of SHA-2 digests (224, 256, 384, 512), * creates a proxy (should have the same digest alg), * test an SSL connection with such EEC and finally tests an SSL connection * with the generated proxy. * @FunctionalTest(id="func:cli-srv-sha2", * description="Tests whether connections using " + * "all sorts of certificates with SHA-2 digests work") * @throws Exception */ @Test public void testSha2Proxy() throws Exception { System.out.println("Running func:cli-srv-sha2 functional test"); testSha2Proxy("keystore-sha224.pem", "1.2.840.113549.1.1.14", "SHA224withRSA"); testSha2Proxy("keystore-sha256.pem", "SHA256withRSA"); testSha2Proxy("keystore-sha384.pem", "SHA384withRSA"); testSha2Proxy("keystore-sha512.pem", "SHA512withRSA"); } private void testSha2Proxy(String fileName, String... algName) throws Exception { X509Credential credential = new PEMCredential("src/test/resources/test-pems/"+fileName, "qwerty".toCharArray()); PrivateKey privateKey = (PrivateKey) credential.getKeyStore().getKey( credential.getKeyAlias(), credential.getKeyPassword()); Certificate c[] = credential.getKeyStore().getCertificateChain(credential.getKeyAlias()); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions param = new ProxyCertificateOptions(chain); ProxyCertificate proxy1 = ProxyGenerator.generate(param, privateKey); X509Certificate proxy = proxy1.getCertificateChain()[0]; Set<String> validNames = new HashSet<String>(); Collections.addAll(validNames, algName); assertTrue(proxy.getSigAlgName(), validNames.contains(proxy.getSigAlgName())); X509CertChainValidator v = new DirectoryCertChainValidator( Collections.singletonList("src/test/resources/rollover/openssl-trustdir/77ab7b18.0"), Encoding.PEM, -1, 100, null); TestSSLHelpers sslHelperTest = new TestSSLHelpers(); sslHelperTest.testClientServer(true, credential, v); X509Credential proxyCredential = new KeyAndCertCredential(proxy1.getPrivateKey(), proxy1.getCertificateChain()); sslHelperTest.testClientServer(true, proxyCredential, v); } /** * Tests generation of proxy cert with generic extensions set */ @Test public void addACExtTest() throws Exception { System.out.println("Running func:proxy-make-withCustomExt functional test"); X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); Certificate c[] = credential.getKeyStore().getCertificateChain(credential.getKeyAlias()); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions param = new ProxyCertificateOptions(chain); PrivateKey privateKey = (PrivateKey) credential.getKeyStore().getKey( credential.getKeyAlias(), credential.getKeyPassword()); AttributeCertificate ac = generateAC(chain[0].getSubjectX500Principal().getName(), privateKey); ProxyACExtension extValue = new ProxyACExtension(new AttributeCertificate[] {ac}); CertificateExtension ce = new CertificateExtension(ProxyACExtension.AC_OID, extValue, false); param.addExtension(ce); ProxyGenerator.generate(param, privateKey); } /** * Tests generation of proxy cert with different KeyUsage settings */ @Test public void keyUsageTest() throws Exception { X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); Certificate c[] = credential.getKeyStore().getCertificateChain(credential.getKeyAlias()); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions param = new ProxyCertificateOptions(chain); PrivateKey privateKey = (PrivateKey) credential.getKeyStore().getKey( credential.getKeyAlias(), credential.getKeyPassword()); //the input chain [0] has dsig, nonRep, keyEnc and dataEnc set //the input chain [1] has dsig, nonRep, KeyCertSig, CrlSig set //the chain[1] is CA cert, so its KU should be ignored. // default settings means - copy the effective mask -> should get dsig, nonRep, keyEnc and dataEnc ProxyCertificate pc1 = ProxyGenerator.generate(param, privateKey); boolean[] ku1 = pc1.getCertificateChain()[0].getKeyUsage(); assertTrue(ku1[0]); assertTrue(ku1[1]); assertTrue(ku1[2]); assertTrue(ku1[3]); assertFalse(ku1[4]); assertFalse(ku1[5]); assertFalse(ku1[6]); assertFalse(ku1[7]); //now set the KU mask -> should get dsig and keyEnc only param.setProxyKeyUsageMask(KeyUsage.keyAgreement | KeyUsage.digitalSignature | KeyUsage.keyEncipherment); ProxyCertificate pc2 = ProxyGenerator.generate(param, privateKey); boolean[] ku2 = pc2.getCertificateChain()[0].getKeyUsage(); assertTrue(ku2[0]); assertFalse(ku2[1]); assertTrue(ku2[2]); assertFalse(ku2[3]); assertFalse(ku2[4]); assertFalse(ku2[5]); assertFalse(ku2[6]); assertFalse(ku2[7]); //now test extending the chain with proxy, with default settings. CA cert is ignored, so should get // the same KU as above ProxyCertificateOptions param2 = new ProxyCertificateOptions(pc2.getCertificateChain()); ProxyCertificate pc3 = ProxyGenerator.generate(param2, privateKey); boolean[] ku3 = pc3.getCertificateChain()[0].getKeyUsage(); assertTrue(ku3[0]); assertFalse(ku3[1]); assertTrue(ku3[2]); assertFalse(ku3[3]); assertFalse(ku3[4]); assertFalse(ku3[5]); assertFalse(ku3[6]); assertFalse(ku3[7]); } /** * Tests generation of proxy cert with long lifetime and stretching of the limits */ @Test public void testLifetime() throws Exception { System.out.println("Running regression:proxy-time-overflow test"); X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); Certificate c[] = credential.getKeyStore().getCertificateChain(credential.getKeyAlias()); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions param = new ProxyCertificateOptions(chain); param.setLifetime(Integer.MAX_VALUE, TimeUnit.SECONDS); PrivateKey privateKey = (PrivateKey) credential.getKeyStore().getKey( credential.getKeyAlias(), credential.getKeyPassword()); //be careful - certificate dates have 1s precision. So add/remove 1001 ms. Date end = new Date(((long)Integer.MAX_VALUE)*1000L+System.currentTimeMillis()-1001); ProxyCertificate pc = ProxyGenerator.generate(param, privateKey); Date notAfter = pc.getCertificateChain()[0].getNotAfter(); Date endPlus = new Date(((long)Integer.MAX_VALUE)*1000L+System.currentTimeMillis()+1001); System.out.println("Got: " + notAfter.getTime()); System.out.println("Should be earlier: " + end.getTime()); System.out.println("Should be later: " + endPlus.getTime()); assertTrue(notAfter.after(end)); assertTrue(notAfter.before(endPlus)); KeystoreCertChainValidator validator = new KeystoreCertChainValidator("src/test/resources/truststore-1.jks", CertificateUtilsTest.KS_P, "JKS", -1); ValidationResult res = validator.validate(pc.getCertificateChain()); System.out.println(res); Assert.assertTrue(res.isValid()); param.setLifetime(0, TimeUnit.SECONDS); pc = ProxyGenerator.generate(param, privateKey); Thread.sleep(1500); res = validator.validate(pc.getCertificateChain()); System.out.println(res); Assert.assertTrue(res.isValid()); Date vstart = new Date(); vstart.setTime(12345000L); Date vend = new Date(); vend.setTime(12346000L); param.setValidityBounds(vstart, vend); pc = ProxyGenerator.generate(param, privateKey); Assert.assertEquals(vstart, pc.getCertificateChain()[0].getNotBefore()); Assert.assertEquals(vend, pc.getCertificateChain()[0].getNotAfter()); res = validator.validate(pc.getCertificateChain()); System.out.println(res); Assert.assertFalse(res.isValid()); } /** * Creates a legacy proxy. Then uses the chain with a proxy to create another one. * Verifies is the 2nd proxy has its type correctly set. * <p> * The 2nd proxy is created using two methods: with CSR and without to simulate local * generation of subsequent proxy (for whatever reasons) * @throws Exception */ @Test public void testProxyChainGeneration() throws Exception { X509Credential credential = new KeystoreCredential("src/test/resources/keystore-1.jks", CertificateUtilsTest.KS_P, CertificateUtilsTest.KS_P, "mykey", "JKS"); Certificate c[] = credential.getKeyStore().getCertificateChain(credential.getKeyAlias()); X509Certificate chain[] = CertificateUtils.convertToX509Chain(c); ProxyCertificateOptions pc1Param = new ProxyCertificateOptions(chain); pc1Param.setType(ProxyType.LEGACY); pc1Param.setLimited(true); ProxyCertificate pc1 = ProxyGenerator.generate(pc1Param, credential.getKey()); ProxyChainInfo pc1i = new ProxyChainInfo(pc1.getCertificateChain()); assertEquals(ProxyChainType.LEGACY, pc1i.getProxyType()); assertEquals(true, pc1i.isLimited()); ProxyCertificateOptions pc2Param = new ProxyCertificateOptions(pc1.getCertificateChain()); ProxyCSR certReq = ProxyCSRGenerator.generate(pc2Param); ProxyRequestOptions pc2ReqParam = new ProxyRequestOptions(pc1.getCertificateChain(), certReq.getCSR()); X509Certificate[] pc2 = ProxyGenerator.generate(pc2ReqParam, credential.getKey()); ProxyChainInfo pc2i = new ProxyChainInfo(pc2); assertEquals(ProxyChainType.LEGACY, pc2i.getProxyType()); assertEquals(true, pc2i.isLimited()); ProxyCertificateOptions pc2LocalParam = new ProxyCertificateOptions(pc1.getCertificateChain()); ProxyCertificate pc2Local = ProxyGenerator.generate(pc2LocalParam, credential.getKey()); ProxyChainInfo pc2Locali = new ProxyChainInfo(pc2Local.getCertificateChain()); assertEquals(ProxyChainType.LEGACY, pc2Locali.getProxyType()); assertEquals(true, pc2Locali.isLimited()); assertTrue(pc2Local.getCertificateChain()[0].getCriticalExtensionOIDs().contains("2.5.29.15")); } }