Java tutorial
/* * Java Trust Project. * Copyright (C) 2011 FedICT. * Copyright (C) 2013-2014 e-Contract.be BVBA. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version * 3.0 as published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, see * http://www.gnu.org/licenses/. */ package test.integ.be.fedict.trust; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigInteger; import java.net.HttpURLConnection; import java.security.Security; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.http.impl.client.DefaultHttpClient; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.SignerId; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.tsp.TSPAlgorithms; import org.bouncycastle.tsp.TimeStampRequest; import org.bouncycastle.tsp.TimeStampRequestGenerator; import org.bouncycastle.tsp.TimeStampResponse; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.util.Selector; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; import org.junit.BeforeClass; import org.junit.Test; import be.fedict.trust.BelgianTrustValidatorFactory; import be.fedict.trust.TrustValidator; import be.fedict.trust.TrustValidatorDecorator; import be.fedict.trust.constraints.TSACertificateConstraint; import be.fedict.trust.repository.CertificateRepository; import be.fedict.trust.repository.MemoryCertificateRepository; public class TSATest { private static final Log LOG = LogFactory.getLog(TSATest.class); private static final String TSA_LOCATION = "http://tsa.belgium.be/connect"; @BeforeClass public static void setUp() { Security.addProvider(new BouncyCastleProvider()); } @Test public void testTSAViaJTrust() throws Exception { testTimestampServerTrust(TSA_LOCATION); } @Test public void testStarfieldTechTrust() throws Exception { testTimestampServerTrust("http://tsa.starfieldtech.com"); } private void testTimestampServerTrust(String tsaLocation) throws Exception { // setup TimeStampRequestGenerator requestGen = new TimeStampRequestGenerator(); requestGen.setCertReq(true); TimeStampRequest request = requestGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); byte[] requestData = request.getEncoded(); DefaultHttpClient httpClient = new DefaultHttpClient(); // HttpHost proxy = new HttpHost("proxy.yourict.net", 8080); // httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, // proxy); HttpPost postMethod = new HttpPost(tsaLocation); ContentType contentType = ContentType.create("application/timestamp-query"); HttpEntity requestEntity = new ByteArrayEntity(requestData, contentType); postMethod.addHeader("User-Agent", "jTrust TSP Client"); postMethod.setEntity(requestEntity); // operate long t0 = System.currentTimeMillis(); HttpResponse httpResponse = httpClient.execute(postMethod); StatusLine statusLine = httpResponse.getStatusLine(); int statusCode = statusLine.getStatusCode(); long t1 = System.currentTimeMillis(); LOG.debug("dt TSP: " + (t1 - t0) + " ms"); if (statusCode != HttpURLConnection.HTTP_OK) { LOG.error("Error contacting TSP server " + TSA_LOCATION); throw new Exception("Error contacting TSP server " + TSA_LOCATION); } HttpEntity httpEntity = httpResponse.getEntity(); TimeStampResponse tspResponse = new TimeStampResponse(httpEntity.getContent()); postMethod.releaseConnection(); TimeStampToken timeStampToken = tspResponse.getTimeStampToken(); SignerId signerId = timeStampToken.getSID(); Store certificatesStore = timeStampToken.getCertificates(); Collection<X509CertificateHolder> signerCollection = certificatesStore.getMatches(signerId); Iterator<X509CertificateHolder> signerCollectionIterator = signerCollection.iterator(); X509CertificateHolder signerCertificateHolder = signerCollectionIterator.next(); // TODO: check time-stamp token signature List<X509Certificate> certificateChain = getCertificateChain(signerCertificateHolder, certificatesStore); for (X509Certificate cert : certificateChain) { LOG.debug("certificate subject: " + cert.getSubjectX500Principal()); LOG.debug("certificate issuer: " + cert.getIssuerX500Principal()); } CertificateRepository certificateRepository = BelgianTrustValidatorFactory.createTSACertificateRepository(); TrustValidator trustValidator = new TrustValidator(certificateRepository); // NetworkConfig networkConfig = new NetworkConfig("proxy.yourict.net", // 8080); TrustValidatorDecorator trustValidatorDecorator = new TrustValidatorDecorator(null); trustValidatorDecorator.addDefaultTrustLinkerConfig(trustValidator); trustValidator.isTrusted(certificateChain); } @Test public void testTSA2013() throws Exception { LOG.debug("test TSA 2013"); InputStream inputStream = TSATest.class.getResourceAsStream("/Fedict-2013.txt"); byte[] data = IOUtils.toByteArray(inputStream); byte[] derData = Base64.decode(data); CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); Collection<X509Certificate> certificates = (Collection<X509Certificate>) certificateFactory .generateCertificates(new ByteArrayInputStream(derData)); List<X509Certificate> certificateChain = new LinkedList<>(); for (X509Certificate certificate : certificates) { certificateChain.add(0, certificate); } MemoryCertificateRepository certificateRepository = new MemoryCertificateRepository(); X509Certificate gsCert = (X509Certificate) certificateFactory .generateCertificate(TSATest.class.getResourceAsStream("/be/fedict/trust/roots/globalsign-be.crt")); certificateRepository.addTrustPoint(gsCert); TrustValidator trustValidator = new TrustValidator(certificateRepository); TrustValidatorDecorator trustValidatorDecorator = new TrustValidatorDecorator(null); trustValidatorDecorator.addDefaultTrustLinkerConfig(trustValidator); trustValidator.addCertificateConstrain(new TSACertificateConstraint()); trustValidator.isTrusted(certificateChain); } private X509Certificate loadCertificate(String pemResourceName) throws IOException, CertificateException { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); InputStream tsaCertInputStream = TSATest.class.getResourceAsStream(pemResourceName); PemReader pemReader = new PemReader(new InputStreamReader(tsaCertInputStream)); PemObject pemObject = pemReader.readPemObject(); X509Certificate certificate = (X509Certificate) certificateFactory .generateCertificate(new ByteArrayInputStream(pemObject.getContent())); pemReader.close(); return certificate; } @Test public void testTSA2014() throws Exception { LOG.debug("test TSA 2014"); List<X509Certificate> certificateChain = new LinkedList<>(); certificateChain.add(loadCertificate("/tsa2014/TimeStampingAuthority.pem")); certificateChain.add(loadCertificate("/tsa2014/Belgium ROOT CA 2.pem")); certificateChain.add(loadCertificate("/tsa2014/Cybertrust Global Root.pem")); certificateChain.add(loadCertificate("/tsa2014/Baltimore Cybertrust Root.pem")); CertificateRepository tsaCertificateRepository = BelgianTrustValidatorFactory .createTSACertificateRepository(); TrustValidator trustValidator = new TrustValidator(tsaCertificateRepository); TrustValidatorDecorator trustValidatorDecorator = new TrustValidatorDecorator(); trustValidatorDecorator.addDefaultTrustLinkerConfig(trustValidator); trustValidator.addCertificateConstrain(new TSACertificateConstraint()); trustValidator.isTrusted(certificateChain); } @Test public void testReadTSA2014() throws Exception { X509Certificate tsaCert = loadCertificate("/tsa2014/TimeStampingAuthority.pem"); LOG.debug("TSA cert: " + tsaCert); File tmpFile = File.createTempFile("tsa-2014-", ".der"); FileUtils.writeByteArrayToFile(tmpFile, tsaCert.getEncoded()); LOG.debug("TSA cert file: " + tmpFile.getAbsolutePath()); } @Test public void testTSA2014_2() throws Exception { LOG.debug("test TSA 2014"); List<X509Certificate> certificateChain = new LinkedList<>(); certificateChain.add(loadCertificate("/tsa2014/TimeStampingAuthority.pem")); certificateChain.add(loadCertificate("/tsa2014/Belgium ROOT CA 2.pem")); certificateChain.add(loadCertificate("/tsa2014/Cybertrust Global Root.pem")); certificateChain.add(loadCertificate("/tsa2014/Baltimore Cybertrust Root.pem")); TrustValidator trustValidator = BelgianTrustValidatorFactory.createTSATrustValidator(null); trustValidator.isTrusted(certificateChain); } private static List<X509Certificate> getCertificateChain(X509CertificateHolder certificateHolder, Store certificatesStore) throws CertificateException, IOException { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); List<X509Certificate> certificateChain = new LinkedList<>(); while (true) { X509Certificate certificate = (X509Certificate) certificateFactory .generateCertificate(new ByteArrayInputStream(certificateHolder.getEncoded())); certificateChain.add(certificate); LOG.debug("certificate: " + certificate.getSubjectX500Principal()); IssuerSelector issuerSelector = new IssuerSelector(certificateHolder); Collection<X509CertificateHolder> issuerCollection = certificatesStore.getMatches(issuerSelector); if (issuerCollection.isEmpty()) { break; } certificateHolder = issuerCollection.iterator().next(); } return certificateChain; } private static class IssuerSelector implements Selector { private final X500Name subject; private final boolean isSelfSigned; public IssuerSelector(X509CertificateHolder certificateHolder) { this.subject = certificateHolder.getIssuer(); this.isSelfSigned = certificateHolder.getSubject().equals(certificateHolder.getIssuer()); } @Override public boolean match(Object object) { if (false == object instanceof X509CertificateHolder) { return false; } X509CertificateHolder certificateHolder = (X509CertificateHolder) object; if (this.isSelfSigned) { return false; } return certificateHolder.getSubject().equals(this.subject); } @Override public Object clone() { return this; } } }