/*
* X509UtilsTest.java
*
* Created on Jun 30, 2008, 4:15:56 PM
*
* Description: .
*
* Copyright (C) Jan 19, 2010 reed.
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.texai.x509;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.UnrecoverableEntryException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateParsingException;
import org.texai.util.StringUtils;
import java.security.SecureRandom;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertPath;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.UUID;
import org.apache.log4j.Logger;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
//import sun.security.x509.X509CertImpl;
import static org.junit.Assert.*;
import org.texai.util.TexaiException;
import static org.texai.x509.X509Utils.isTrustedDevelopmentSystem;
/**
*
* @author reed
*/
public class X509UtilsTest {
/** the logger */
private static final Logger LOGGER = Logger.getLogger(X509UtilsTest.class);
public X509UtilsTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
X509Utils.logProviders();
X509Utils.logProviderCapabilities(X509Utils.BOUNCY_CASTLE_PROVIDER);
X509Utils.createTexaiRootKeyStore();
X509Utils.initializeInstallerKeyStore();
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
/**
* Test of initializeTrustore method of class X509Utils.
*/
@Test
public void testInitializeTrustore() {
LOGGER.info("initializeTrustore");
X509Utils.initializeTrustore();
verifyTruststoresPopulated();
}
/**
* Test of getTruststore method of class X509Utils.
*/
@Test
public void testGetTruststore() {
LOGGER.info("getTruststore");
final KeyStore truststore = X509Utils.getTruststore();
assertNotNull(truststore);
try {
assertTrue(truststore.containsAlias(X509Utils.TRUSTSTORE_ENTRY_ALIAS));
final X509Certificate rootX509Certificate = (X509Certificate) truststore.getCertificate(X509Utils.TRUSTSTORE_ENTRY_ALIAS);
LOGGER.info("rootX509Certificate from bytes...\n + " + X509Utils.getRootX509Certificate());
assertEquals(X509Utils.getRootX509Certificate(), rootX509Certificate);
} catch (KeyStoreException ex) {
fail(ex.getMessage());
}
X509Utils.logAliases(truststore);
}
/**
* Test of getRootKeyStorePassword method of class X509Utils.
*/
@Test
public void testGetRootKeyStorePassword() {
LOGGER.info("getRootKeyStorePassword");
final char[] rootKeyStorePassword = X509Utils.getRootKeyStorePassword();
if (rootKeyStorePassword != null) {
LOGGER.info("root keystore password: '" + new String(rootKeyStorePassword) + "'");
}
}
/**
* Test of isJCEUnlimitedStrengthPolicy method, of class X509Utils.
*/
@Test
public void testIsJCEUnlimitedStrengthPolicy() {
LOGGER.info("isJCEUnlimitedStrengthPolicy");
try {
if (X509Utils.isJCEUnlimitedStrengthPolicy()) {
LOGGER.info("JCE unlimited strength jurisdiction policy files are installed");
} else {
LOGGER.info("JCE unlimited strength jurisdiction policy files are not installed");
}
} catch (Exception ex) {
LOGGER.info(StringUtils.getStackTraceAsString(ex));
fail(ex.getMessage());
}
}
/**
* Test of getMaxAllowedKeyLength method, of class X509Utils.
*/
@Test
public void testGetMaxAllowedKeyLength() {
LOGGER.info("getMaxAllowedKeyLength");
try {
final int maxKeyLength = X509Utils.getMaxAllowedKeyLength();
LOGGER.info("maximum allowed key length: " + maxKeyLength);
if (maxKeyLength == Integer.MAX_VALUE) {
LOGGER.info("JCE unlimited strength jurisdiction policy files are installed");
}
} catch (NoSuchAlgorithmException ex) {
LOGGER.info(StringUtils.getStackTraceAsString(ex));
fail(ex.getMessage());
}
}
/**
* Test of generateRSAKeyPair2048 method, of class X509Utils.
*/
@Test
public void testGenerateRSAKeyPair() {
LOGGER.info("generateRSAKeyPair");
KeyPair result = null;
try {
result = X509Utils.generateRSAKeyPair2048();
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException ex) {
fail(ex.getMessage());
}
assertNotNull(result);
final PrivateKey privateKey = result.getPrivate();
assertNotNull(privateKey);
final PublicKey publicKey = result.getPublic();
assertNotNull(publicKey);
assertEquals("RSA", result.getPrivate().getAlgorithm());
assertEquals("RSA", result.getPublic().getAlgorithm());
assertEquals("PKCS#8", result.getPrivate().getFormat());
assertEquals("X.509", result.getPublic().getFormat());
}
/**
* Test of getNextSerialNumber method of class X509Utils.
*/
@Test
public void testGetNextSerialNumber() {
LOGGER.info("getNextSerialNumber");
try {
final BigInteger serialNumber1 = X509Utils.getNextSerialNumber();
LOGGER.info("serialNumber1: " + serialNumber1);
final BigInteger serialNumber2 = X509Utils.getNextSerialNumber();
LOGGER.info("serialNumber2: " + serialNumber2);
assertEquals(serialNumber1.add(BigInteger.ONE), serialNumber2);
} catch (IOException ex) {
fail(ex.getMessage());
}
}
/**
* Test of generateRootX509Certificate method, of class X509Utils.
*/
@Test
public void testGenerateRootX509Certificate() {
LOGGER.info("generateRootX509Certificate");
KeyPair keyPair;
try {
keyPair = X509Utils.generateRSAKeyPair3072();
X509Certificate rootX509Certificate = X509Utils.generateRootX509Certificate(keyPair);
LOGGER.info("root certificate:\n" + rootX509Certificate);
assertNotNull(rootX509Certificate);
assertTrue(rootX509Certificate.getIssuerDN().toString().contains("CN=texai.org, O=Texai Certification Authority"));
assertTrue(rootX509Certificate.getSubjectDN().toString().contains("CN=texai.org, O=Texai Certification Authority"));
assertEquals(X509Utils.DIGITAL_SIGNATURE_ALGORITHM, rootX509Certificate.getSigAlgName());
assertEquals(keyPair.getPublic(), rootX509Certificate.getPublicKey());
//assertTrue(X509CertImpl.isSelfIssued(rootX509Certificate));
assertTrue(rootX509Certificate.getSubjectX500Principal().toString().contains("UID="));
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | CertificateEncodingException | SignatureException | InvalidKeyException | IOException ex) {
fail(ex.getMessage());
}
}
/**
* Test of getRootX509Certificate method, of class X509Utils.
*/
@Test
public void testGetRootX509Certificate() {
LOGGER.info("getRootX509Certificate");
try {
X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
LOGGER.info("root certificate:\n" + rootX509Certificate);
assertNotNull(rootX509Certificate);
assertEquals("CN=texai.org, O=Texai Certification Authority, UID=ed6d6718-80de-4848-af43-fed7bdba3c36", rootX509Certificate.getIssuerDN().toString());
assertEquals("CN=texai.org, O=Texai Certification Authority, UID=ed6d6718-80de-4848-af43-fed7bdba3c36", rootX509Certificate.getSubjectDN().toString());
assertEquals(X509Utils.DIGITAL_SIGNATURE_ALGORITHM, rootX509Certificate.getSigAlgName());
} catch (Exception ex) {
fail(ex.getMessage());
}
}
/**
* Test of generateX509Certificate method, of class X509Utils.
*/
@Test
public void testGenerateX509Certificate() {
LOGGER.info("generateX509Certificate");
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
try {
X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
KeyPair keyPair = X509Utils.generateRSAKeyPair2048();
PublicKey publicKey = keyPair.getPublic();
PrivateKey certificateAuthorityPrivateKey = X509Utils.getRootPrivateKey();
LOGGER.info("root certificate (" + rootX509Certificate.getClass().getName() + "):\n" + rootX509Certificate);
X509Certificate x509Certificate
= X509Utils.generateX509Certificate(publicKey, certificateAuthorityPrivateKey, rootX509Certificate, "TestComponent");
LOGGER.info("generated certificate...\n" + x509Certificate);
assertNotNull(x509Certificate);
assertTrue(x509Certificate.getIssuerDN().toString().startsWith("CN=texai.org, O=Texai Certification Authority, UID="));
assertTrue(x509Certificate.getSubjectDN().toString().contains("CN=texai.org"));
assertTrue(!x509Certificate.getSubjectDN().toString().contains("O=Texai Certification Authority"));
assertEquals(X509Utils.DIGITAL_SIGNATURE_ALGORITHM, x509Certificate.getSigAlgName());
assertEquals(keyPair.getPublic(), x509Certificate.getPublicKey());
x509Certificate.verify(rootX509Certificate.getPublicKey());
LOGGER.info("principal: " + x509Certificate.getSubjectX500Principal().toString());
assertTrue(x509Certificate.getSubjectX500Principal().toString().contains("UID="));
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | SignatureException | InvalidKeyException | IOException | CertificateException ex) {
LOGGER.info(StringUtils.getStackTraceAsString(ex));
fail(ex.getMessage());
}
}
/**
* Test of generateX509CertificatePath method, of class X509Utils.
*/
@Test
public void testGenerateX509CertificatePath() {
LOGGER.info("generateX509CertificatePath");
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
try {
X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
KeyPair keyPair = X509Utils.generateRSAKeyPair2048();
PublicKey publicKey = keyPair.getPublic();
PrivateKey certificateAuthorityPrivateKey = X509Utils.getRootPrivateKey();
LOGGER.info("root certificate (" + rootX509Certificate.getClass().getName() + "):\n" + rootX509Certificate);
final CertPath certPath = X509Utils.generateX509CertificatePath(
publicKey,
certificateAuthorityPrivateKey,
rootX509Certificate, // issuerCertificate
X509Utils.generateCertPath(new ArrayList<>()), null); // issuerCertPath
assertEquals(1, certPath.getCertificates().size());
X509Certificate x509Certificate = (X509Certificate) certPath.getCertificates().get(0);
LOGGER.info("generated certificate...\n" + x509Certificate);
assertNotNull(x509Certificate);
assertTrue(x509Certificate.getIssuerDN().toString().startsWith("CN=texai.org, O=Texai Certification Authority, UID="));
assertTrue(x509Certificate.getSubjectDN().toString().contains("CN=texai.org"));
assertTrue(!x509Certificate.getSubjectDN().toString().contains("O=Texai Certification Authority"));
assertEquals(X509Utils.DIGITAL_SIGNATURE_ALGORITHM, x509Certificate.getSigAlgName());
assertEquals(keyPair.getPublic(), x509Certificate.getPublicKey());
x509Certificate.verify(rootX509Certificate.getPublicKey());
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | CertificateException | SignatureException | InvalidKeyException | IOException ex) {
LOGGER.info(StringUtils.getStackTraceAsString(ex));
fail(ex.getMessage());
}
}
/**
* Test of generateIntermediateX509Certificate method, of class X509Utils.
*/
@Test
public void testGenerateIntermediateX509Certificate() {
LOGGER.info("generateIntermediateX509Certificate");
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
try {
X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
final KeyPair keyPair = X509Utils.generateRSAKeyPair3072();
PublicKey publicKey = keyPair.getPublic();
PrivateKey certificateAuthorityPrivateKey = X509Utils.getRootPrivateKey();
X509Certificate intermediateX509Certificate
= X509Utils.generateIntermediateX509Certificate(publicKey, certificateAuthorityPrivateKey, rootX509Certificate, 0);
LOGGER.info("generated intermediate certificate:\n" + intermediateX509Certificate);
assertNotNull(intermediateX509Certificate);
LOGGER.info("intermediateX509Certificate.getIssuerDN(): " + intermediateX509Certificate.getIssuerDN().toString());
assertTrue(intermediateX509Certificate.getIssuerDN().toString().startsWith("CN=texai.org, O=Texai Certification Authority, UID="));
assertTrue(intermediateX509Certificate.getSubjectDN().toString().contains("CN=texai.org"));
assertTrue(!intermediateX509Certificate.getSubjectDN().toString().contains("O=Texai Certification Authority"));
assertEquals(X509Utils.DIGITAL_SIGNATURE_ALGORITHM, intermediateX509Certificate.getSigAlgName());
assertEquals(keyPair.getPublic(), intermediateX509Certificate.getPublicKey());
//assertFalse(X509CertImpl.isSelfIssued(intermediateX509Certificate));
intermediateX509Certificate.verify(rootX509Certificate.getPublicKey());
LOGGER.info("principal: " + intermediateX509Certificate.getSubjectX500Principal().toString());
assertTrue(intermediateX509Certificate.getSubjectX500Principal().toString().contains("UID="));
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | SignatureException | InvalidKeyException | IOException | CertificateException ex) {
fail(ex.getMessage());
}
}
/**
* Test of writeX509Certificate method and readX509Certificate method, of class X509Utils.
*/
@Test
public void testWriteX509Certificate() {
LOGGER.info("writeX509Certificate");
try {
X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
LOGGER.info("root certificate...\n" + rootX509Certificate);
assertNotNull(rootX509Certificate);
assertEquals(X509Utils.DIGITAL_SIGNATURE_ALGORITHM, rootX509Certificate.getSigAlgName());
X509Utils.writeX509Certificate(rootX509Certificate, "data/testRootCertificate.crt");
LOGGER.info("readX509Certificate");
InputStream certificateInputStream = new FileInputStream("data/testRootCertificate.crt");
X509Certificate rootX509Certificate1 = X509Utils.readX509Certificate(certificateInputStream);
assertNotNull(rootX509Certificate1);
assertEquals(X509Utils.DIGITAL_SIGNATURE_ALGORITHM, rootX509Certificate1.getSigAlgName());
assertEquals(rootX509Certificate, rootX509Certificate1);
} catch (IOException | CertificateException | NoSuchProviderException ex) {
fail(ex.getMessage());
}
}
/**
* Test of makeCanonicalX509Certificate method of class X509Utils.
*/
@Test
public void testMakeCanonicalX509Certificate() {
LOGGER.info("makeCanonicalX509Certificate");
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
try {
X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
KeyPair keyPair = X509Utils.generateRSAKeyPair2048();
PublicKey publicKey = keyPair.getPublic();
PrivateKey certificateAuthorityPrivateKey = X509Utils.getRootPrivateKey();
LOGGER.info("root certificate (" + rootX509Certificate.getClass().getName() + "):\n" + rootX509Certificate);
X509Certificate x509Certificate
= X509Utils.generateX509Certificate(publicKey, certificateAuthorityPrivateKey, rootX509Certificate, "TestComponent");
LOGGER.info("generated certificate...\n" + x509Certificate);
assertNotNull(x509Certificate);
assertTrue(x509Certificate.getIssuerDN().toString().startsWith("CN=texai.org, O=Texai Certification Authority, UID="));
assertTrue(x509Certificate.getSubjectDN().toString().contains("CN=texai.org"));
assertTrue(!x509Certificate.getSubjectDN().toString().contains("O=Texai Certification Authority"));
assertEquals(X509Utils.DIGITAL_SIGNATURE_ALGORITHM, x509Certificate.getSigAlgName());
assertEquals(keyPair.getPublic(), x509Certificate.getPublicKey());
x509Certificate.verify(rootX509Certificate.getPublicKey());
LOGGER.info("principal: " + x509Certificate.getSubjectX500Principal().toString());
assertTrue(x509Certificate.getSubjectX500Principal().toString().contains("UID="));
final X509Certificate canonicalX509Certificate = X509Utils.makeCanonicalX509Certificate(x509Certificate);
LOGGER.info("canonical certificate...\n" + canonicalX509Certificate);
assertTrue(canonicalX509Certificate.getIssuerDN().toString().startsWith("CN=texai.org, O=Texai Certification Authority, UID="));
assertTrue(canonicalX509Certificate.getSubjectDN().toString().contains("CN=texai.org"));
assertEquals(canonicalX509Certificate.getSubjectDN().toString(), x509Certificate.getSubjectDN().toString());
assertEquals(canonicalX509Certificate.getIssuerDN().toString(), x509Certificate.getIssuerDN().toString());
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | SignatureException | InvalidKeyException | IOException | CertificateException ex) {
LOGGER.info(StringUtils.getStackTraceAsString(ex));
fail(ex.getMessage());
}
}
/**
* Test of getX509SecurityInfo method of class X509Utils.
*/
@Test
public void testGetX509SecurityInfo() {
LOGGER.info("getX509SecurityInfo");
final String keyStoreFilePath;
if (X509Utils.isJCEUnlimitedStrengthPolicy()) {
keyStoreFilePath = "data/test-client-keystore.uber";
} else {
keyStoreFilePath = "data/test-client-keystore.jceks";
}
X509SecurityInfo x509SecurityInfo = X509Utils.getX509SecurityInfo(
keyStoreFilePath,
KeyStoreTestUtils.getClientKeyStorePassword(),
null); // alias
assertNotNull(x509SecurityInfo.getTrustStore());
if (X509Utils.isJCEUnlimitedStrengthPolicy()) {
assertEquals(X509Utils.BOUNCY_CASTLE_PROVIDER, x509SecurityInfo.getTrustStore().getProvider().getName());
assertEquals("UBER", x509SecurityInfo.getTrustStore().getType());
} else {
assertEquals("SunJCE", x509SecurityInfo.getTrustStore().getProvider().getName());
assertEquals("JCEKS", x509SecurityInfo.getTrustStore().getType());
}
assertTrue(x509SecurityInfo.getKeyManagers().length > 0);
}
/**
* Test of findOrCreateKeyStore method of class X509Utils.
*/
@Test
public void testFindOrCreateKeyStore() {
LOGGER.info("findOrCreateKeyStore");
final String filePath;
if (X509Utils.isJCEUnlimitedStrengthPolicy()) {
filePath = "data/keystore.uber";
} else {
filePath = "data/keystore.jceks";
}
final File keyStoreFile = new File(filePath);
if (keyStoreFile.exists()) {
final boolean isFileDeleted = keyStoreFile.delete();
if (!isFileDeleted) {
fail("keystore file not deleted: " + filePath);
}
}
KeyStore keyStore;
try {
keyStore = X509Utils.findOrCreateKeyStore(filePath, "password".toCharArray());
assertNotNull(keyStore);
assertEquals(0, keyStore.size());
if (X509Utils.isJCEUnlimitedStrengthPolicy()) {
assertEquals(X509Utils.BOUNCY_CASTLE_PROVIDER, keyStore.getProvider().getName());
assertEquals("UBER", keyStore.getType());
} else {
assertEquals("SunJCE", keyStore.getProvider().getName());
assertEquals("JCEKS", keyStore.getType());
}
assertTrue(keyStoreFile.exists());
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | NoSuchProviderException ex) {
fail(ex.getMessage());
}
}
/**
* Test of findOrCreatePKCS12KeyStore method of class X509Utils.
*/
@Test
public void testFindOrCreatePKCS12KeyStore() {
LOGGER.info("findOrCreatePKCS12KeyStore");
final String filePath;
filePath = "data/keystore.p12";
final File keyStoreFile = new File(filePath);
if (keyStoreFile.exists()) {
final boolean isFileDeleted = keyStoreFile.delete();
if (!isFileDeleted) {
fail("keystore file not deleted: " + filePath);
}
}
KeyStore keyStore;
try {
keyStore = X509Utils.findOrCreatePKCS12KeyStore(filePath, "password".toCharArray());
assertNotNull(keyStore);
assertEquals(0, keyStore.size());
if (X509Utils.isJCEUnlimitedStrengthPolicy()) {
assertEquals("BC", keyStore.getProvider().getName());
} else {
assertEquals("SunJSSE", keyStore.getProvider().getName());
}
assertEquals("pkcs12", keyStore.getType());
assertTrue(keyStoreFile.exists());
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | NoSuchProviderException ex) {
LOGGER.info(StringUtils.getStackTraceAsString(ex));
fail(ex.getMessage());
}
}
/**
* Test of addEntryToKeyStore method of class X509Utils.
*/
@Test
public void testAddEntryToKeyStore() {
LOGGER.info("addEntryToKeyStore");
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
// create a keystore
final String filePath;
if (X509Utils.isJCEUnlimitedStrengthPolicy()) {
filePath = "data/keystore.uber";
} else {
filePath = "data/keystore.jceks";
}
final File keyStoreFile = new File(filePath);
if (keyStoreFile.exists()) {
final boolean isFileDeleted = keyStoreFile.delete();
if (!isFileDeleted) {
fail("keystore file not deleted: " + filePath);
}
}
KeyStore keyStore;
try {
final char[] keyStorePassword = "password".toCharArray();
keyStore = X509Utils.findOrCreateKeyStore(filePath, keyStorePassword);
assertNotNull(keyStore);
assertEquals(0, keyStore.size());
assertTrue(keyStoreFile.exists());
// create a certificate path
X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
final PrivateKey certificateAuthorityPrivateKey = X509Utils.getRootPrivateKey();
KeyPair keyPair = X509Utils.generateRSAKeyPair2048();
PublicKey publicKey = keyPair.getPublic();
X509Certificate x509Certificate
= X509Utils.generateX509Certificate(publicKey, certificateAuthorityPrivateKey, rootX509Certificate, null);
x509Certificate.verify(rootX509Certificate.getPublicKey());
final List<Certificate> certificateList = new ArrayList<>();
certificateList.add(x509Certificate);
CertPath certPath = X509Utils.generateCertPath(certificateList);
// add the certificate path entry to the keystore
final String alias = X509Utils.getUUID(x509Certificate).toString();
final KeyStore keyStore1 = X509Utils.addEntryToKeyStore(
filePath,
keyStorePassword,
alias,
certPath,
keyPair.getPrivate());
assertNotNull(keyStore1);
assertEquals(1, keyStore1.size());
assertTrue(keyStore1.containsAlias(alias));
assertFalse(keyStore1.isCertificateEntry(alias));
assertTrue(keyStore1.isKeyEntry(alias));
assertTrue(keyStore1.getCertificate(alias) instanceof X509Certificate);
X509Certificate x509Certificate1 = (X509Certificate) keyStore1.getCertificate(alias);
assertEquals(x509Certificate, x509Certificate1);
assertEquals(alias, X509Utils.getUUID(x509Certificate1).toString());
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | NoSuchProviderException | InvalidAlgorithmParameterException | SignatureException | InvalidKeyException ex) {
LOGGER.info(StringUtils.getStackTraceAsString(ex));
fail(ex.getMessage());
}
}
/**
* Test of getUUID method of class X509Utils.
*/
@Test
public void testGetUUID() {
LOGGER.info("getUUID");
try {
final X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
LOGGER.info("root certificate: " + rootX509Certificate);
assertEquals("ed6d6718-80de-4848-af43-fed7bdba3c36", X509Utils.getUUID(rootX509Certificate).toString());
} catch (Exception ex) {
fail(ex.getMessage());
}
}
/**
* Test of copyKeyStoreUberToJceks method of class X509Utils.
*/
@Test
public void testCopyKeyStoreUberToJceks() {
LOGGER.info("copyKeyStoreUberToJceks");
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
final String uberKeyStorePath = "data/keystore.uber";
final char[] keyStorePassword = "password".toCharArray();
final String jceksKeyStorePath = "data/keystore-copy.jceks";
try {
X509Utils.copyKeyStoreUberToJceks(
uberKeyStorePath,
keyStorePassword,
jceksKeyStorePath,
keyStorePassword);
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | NoSuchProviderException | UnrecoverableEntryException ex) {
LOGGER.info(StringUtils.getStackTraceAsString(ex));
fail(ex.getMessage());
}
}
/**
* Test of generateX509SecurityInfo method of class X509Utils.
*/
@Test
public void testGenerateX509SecurityInfo() {
LOGGER.info("generateX509SecurityInfo");
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
try {
final KeyPair keyPair = X509Utils.generateRSAKeyPair2048();
final PrivateKey issuerPrivateKey = X509Utils.getRootPrivateKey();
final X509Certificate issuerCertificate = X509Utils.getRootX509Certificate();
final UUID uid = UUID.randomUUID();
final char[] keystorePassword = "my-password".toCharArray();
final boolean isJCEUnlimitedStrengthPolicy = true;
X509SecurityInfo x509SecurityInfo = X509Utils.generateX509SecurityInfo(
keyPair,
issuerPrivateKey,
issuerCertificate,
uid,
keystorePassword,
isJCEUnlimitedStrengthPolicy,
null); // domainComponent
assertNotNull(x509SecurityInfo.getCertPath());
assertNotNull(x509SecurityInfo.getKeyManagers());
assertNotNull(x509SecurityInfo.getKeyStore());
assertNotNull(x509SecurityInfo.getPrivateKey());
assertNotNull(x509SecurityInfo.getTrustStore());
assertNotNull(x509SecurityInfo.getX509Certificate());
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException ex) {
fail(ex.getMessage());
}
}
/**
* Test of validateCertificatePath method of class X509Utils.
*/
@Test
public void testValidateCertificatePath() {
LOGGER.info("validateCertificatePath");
// debug by setting -Djava.security.debug=certpath in the Texai POM
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
try {
X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
final PrivateKey certificateAuthorityPrivateKey = X509Utils.getRootPrivateKey();
// generate and validate an intermediate certificate
final KeyPair intermediateKeyPair = X509Utils.generateRSAKeyPair3072();
final PublicKey intermediatePublicKey = intermediateKeyPair.getPublic();
final PrivateKey intermediatePrivateKey = intermediateKeyPair.getPrivate();
final X509Certificate intermediateX509Certificate = X509Utils.generateIntermediateX509Certificate(
intermediatePublicKey,
certificateAuthorityPrivateKey,
rootX509Certificate,
0); // pathLengthConstraint
intermediateX509Certificate.verify(rootX509Certificate.getPublicKey());
// generate and validate an end-entity certificate
final KeyPair keyPair = X509Utils.generateRSAKeyPair2048();
final PublicKey publicKey = keyPair.getPublic();
final X509Certificate x509Certificate = X509Utils.generateX509Certificate(
publicKey,
intermediatePrivateKey,
intermediateX509Certificate,
null); // domainComponent
x509Certificate.verify(intermediateX509Certificate.getPublicKey());
// validate a certificate path consisting of three certificates: root, intermediate, and end-entity certificates
final List<Certificate> certificateList = new ArrayList<>();
LOGGER.info("validating path of length 3");
LOGGER.info("rootX509Certificate...\n" + rootX509Certificate);
LOGGER.info("intermediateX509Certificate...\n" + intermediateX509Certificate);
LOGGER.info("x509Certificate...\n" + x509Certificate);
certificateList.clear();
certificateList.add(x509Certificate);
certificateList.add(intermediateX509Certificate);
certificateList.add(rootX509Certificate);
final CertPath certPath = X509Utils.generateCertPath(certificateList);
X509Utils.validateCertificatePath(certPath);
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | SignatureException | InvalidKeyException | IOException | CertificateException | CertPathValidatorException ex) {
LOGGER.info(StringUtils.getStackTraceAsString(ex));
fail(ex.getMessage());
}
}
/**
* Test of initializeSecureRandom method of class X509Utils.
*/
@Test
public void testInitializeSecureRandom() {
LOGGER.info("initializeSecureRandom");
SecureRandom secureRandom = X509Utils.initializeSecureRandom("data/secure-random.ser");
assertNotNull(secureRandom);
assertTrue((new File("data/secure-random.ser")).exists());
secureRandom = X509Utils.initializeSecureRandom("data/secure-random.ser");
assertNotNull(secureRandom);
assertTrue((new File("data/secure-random.ser")).exists());
}
/**
* Test of hasKeyUsage method of class X509Utils.
*/
@Test
public void testHasKeyUsage() {
LOGGER.info("hasKeyUsage");
X509Certificate rootX509Certificate = X509Utils.getRootX509Certificate();
LOGGER.info("root certificate:\n" + rootX509Certificate);
LOGGER.info("root certificate class: " + rootX509Certificate.getClass().getName());
LOGGER.info("key usage bits: " + StringUtils.booleanArrayToBitString(rootX509Certificate.getKeyUsage()));
assertFalse(X509Utils.hasKeyUsage(rootX509Certificate, KeyUsage.digitalSignature));
assertFalse(X509Utils.hasKeyUsage(rootX509Certificate, KeyUsage.nonRepudiation));
assertFalse(X509Utils.hasKeyUsage(rootX509Certificate, KeyUsage.keyEncipherment));
assertFalse(X509Utils.hasKeyUsage(rootX509Certificate, KeyUsage.dataEncipherment));
assertFalse(X509Utils.hasKeyUsage(rootX509Certificate, KeyUsage.keyAgreement));
assertTrue(X509Utils.hasKeyUsage(rootX509Certificate, KeyUsage.keyCertSign));
assertTrue(X509Utils.hasKeyUsage(rootX509Certificate, KeyUsage.cRLSign));
assertFalse(X509Utils.hasKeyUsage(rootX509Certificate, KeyUsage.encipherOnly));
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
try {
KeyPair keyPair = X509Utils.generateRSAKeyPair3072();
PublicKey publicKey = keyPair.getPublic();
PrivateKey certificateAuthorityPrivateKey = X509Utils.getRootPrivateKey();
X509Certificate intermediateX509Certificate
= X509Utils.generateIntermediateX509Certificate(publicKey, certificateAuthorityPrivateKey, rootX509Certificate, 0);
LOGGER.info("generated intermediate certificate:\n" + intermediateX509Certificate);
assertFalse(X509Utils.hasKeyUsage(intermediateX509Certificate, KeyUsage.digitalSignature));
assertFalse(X509Utils.hasKeyUsage(intermediateX509Certificate, KeyUsage.nonRepudiation));
assertFalse(X509Utils.hasKeyUsage(intermediateX509Certificate, KeyUsage.keyEncipherment));
assertFalse(X509Utils.hasKeyUsage(intermediateX509Certificate, KeyUsage.dataEncipherment));
assertFalse(X509Utils.hasKeyUsage(intermediateX509Certificate, KeyUsage.keyAgreement));
assertTrue(X509Utils.hasKeyUsage(intermediateX509Certificate, KeyUsage.keyCertSign));
assertTrue(X509Utils.hasKeyUsage(intermediateX509Certificate, KeyUsage.cRLSign));
assertFalse(X509Utils.hasKeyUsage(intermediateX509Certificate, KeyUsage.encipherOnly));
keyPair = X509Utils.generateRSAKeyPair2048();
publicKey = keyPair.getPublic();
certificateAuthorityPrivateKey = X509Utils.getRootPrivateKey();
LOGGER.info("root certificate (" + rootX509Certificate.getClass().getName() + "):\n" + rootX509Certificate);
X509Certificate x509Certificate
= X509Utils.generateX509Certificate(publicKey, certificateAuthorityPrivateKey, rootX509Certificate, null);
LOGGER.info("generated certificate:\n" + x509Certificate);
assertTrue(X509Utils.hasKeyUsage(x509Certificate, KeyUsage.digitalSignature));
assertTrue(X509Utils.hasKeyUsage(x509Certificate, KeyUsage.nonRepudiation));
assertTrue(X509Utils.hasKeyUsage(x509Certificate, KeyUsage.keyEncipherment));
assertTrue(X509Utils.hasKeyUsage(x509Certificate, KeyUsage.dataEncipherment));
assertTrue(X509Utils.hasKeyUsage(x509Certificate, KeyUsage.keyAgreement));
assertTrue(X509Utils.hasKeyUsage(x509Certificate, KeyUsage.keyCertSign));
assertTrue(X509Utils.hasKeyUsage(x509Certificate, KeyUsage.cRLSign));
assertTrue(X509Utils.hasKeyUsage(x509Certificate, KeyUsage.encipherOnly));
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | CertificateParsingException | CertificateEncodingException | SignatureException | InvalidKeyException | IOException ex) {
fail(ex.getMessage());
}
}
/** Checks whether the trustores are populated. */
public void verifyTruststoresPopulated() {
if (!X509Utils.isTrustedDevelopmentSystem()) {
return;
}
try {
// truststore.uber
String truststorePath = "data/truststore.uber";
KeyStore truststore1 = X509Utils.findOrCreateKeyStore(truststorePath, X509Utils.TRUSTSTORE_PASSWORD);
Enumeration<String> aliases = truststore1.aliases();
int aliasCnt = 0;
while (aliases.hasMoreElements()) {
LOGGER.info(truststorePath + " uber trusted certificate alias: " + aliases.nextElement());
aliasCnt++;
}
if (aliasCnt == 0) {
fail();
}
// truststore.jceks
X509Utils.setIsJCEUnlimitedStrengthPolicy(false);
try {
truststorePath = "data/truststore.jceks";
truststore1 = X509Utils.findOrCreateKeyStore(truststorePath, X509Utils.TRUSTSTORE_PASSWORD);
aliases = truststore1.aliases();
aliasCnt = 0;
while (aliases.hasMoreElements()) {
LOGGER.info(truststorePath + " jceks trusted certificate alias: " + aliases.nextElement());
aliasCnt++;
}
if (aliasCnt == 0) {
fail();
}
// truststore.bks
truststorePath = "data/truststore.bks";
truststore1 = X509Utils.findOrCreateBKSKeyStore(truststorePath, X509Utils.TRUSTSTORE_PASSWORD);
aliases = truststore1.aliases();
aliasCnt = 0;
while (aliases.hasMoreElements()) {
LOGGER.info(truststorePath + " bks trusted certificate alias: " + aliases.nextElement());
aliasCnt++;
}
if (aliasCnt == 0) {
fail();
}
// truststore.jks
truststorePath = "data/truststore.jks";
truststore1 = X509Utils.findOrCreateJKSKeyStore(truststorePath, X509Utils.TRUSTSTORE_PASSWORD);
aliases = truststore1.aliases();
aliasCnt = 0;
while (aliases.hasMoreElements()) {
LOGGER.info(truststorePath + " jks trusted certificate alias: " + aliases.nextElement());
aliasCnt++;
}
if (aliasCnt == 0) {
fail();
}
// truststore.p12
truststorePath = "data/truststore.p12";
truststore1 = X509Utils.findOrCreatePKCS12KeyStore(truststorePath, X509Utils.TRUSTSTORE_PASSWORD);
aliases = truststore1.aliases();
aliasCnt = 0;
while (aliases.hasMoreElements()) {
LOGGER.info(truststorePath + " p12 trusted certificate alias: " + aliases.nextElement());
aliasCnt++;
}
if (aliasCnt == 0) {
fail();
}
} finally {
X509Utils.setIsJCEUnlimitedStrengthPolicy(true);
}
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | NoSuchProviderException ex) {
throw new TexaiException(ex);
}
assertTrue(!isTrustedDevelopmentSystem() || X509Utils.isJCEUnlimitedStrengthPolicy());
}
}