package org.bouncycastle.test.est;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.TrustAnchor;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.security.cert.X509Certificate;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator;
import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class ESTTestUtils
{
private static Map algIds = new HashMap();
static
{
algIds.put("GOST3411withGOST3410", new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94));
algIds.put("SHA1withRSA", new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption, DERNull.INSTANCE));
algIds.put("SHA256withRSA", new AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption, DERNull.INSTANCE));
algIds.put("ECDSA", new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa_with_sha1));
algIds.put("SHA256WITHECDSA", new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA256));
}
public static void ensureProvider()
{
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastleJsseProvider());
}
// public static void ensureProvider(String name)
// {
// Provider[] pp = Security.getProviders();
// for (Provider p : pp)
// {
// if (p.getName().equals(name))
// {
// return;
// }
// }
//
// if (name.equals(BouncyCastleProvider.PROVIDER_NAME))
// {
// Security.addProvider(new BouncyCastleProvider());
// }
// else if (name.equals(BouncyCastleJsseProvider.PROVIDER_NAME))
// {
// Security.addProvider(new BouncyCastleJsseProvider());
// }
// else
// {
// throw new IllegalArgumentException("Unknown provider " + name + " perhaps you need to add it here.");
// }
// }
/**
* Convert (X509CertificateHolder, X509Certificate, javax X509Certificate) to trust anchors.
* Constraints are set null.
*
* @param oo
* @return
* @throws Exception
*/
public static Set<TrustAnchor> toTrustAnchor(Object... oo)
throws Exception
{
CertificateFactory fac = CertificateFactory.getInstance("X509");
HashSet<TrustAnchor> out = new HashSet<TrustAnchor>();
for (Object o : oo)
{
if (o instanceof X509CertificateHolder)
{
out.add(new TrustAnchor((java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509CertificateHolder)o).getEncoded())), null));
}
else if (o instanceof javax.security.cert.X509Certificate)
{
out.add(new TrustAnchor((java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509Certificate)o).getEncoded())), null));
}
else if (o instanceof java.security.cert.X509Certificate)
{
out.add(new TrustAnchor((java.security.cert.X509Certificate)o, null));
}
else if (o instanceof TrustAnchor)
{
out.add((TrustAnchor)o);
}
else
{
throw new IllegalArgumentException("Could not convert " + o.getClass().getName() + " to X509Certificate");
}
}
return out;
}
public static List<java.security.cert.X509Certificate> toCertList(X509Certificate[] certs)
throws Exception
{
CertificateFactory fac = CertificateFactory.getInstance("X509");
ArrayList<java.security.cert.X509Certificate> c = new ArrayList<java.security.cert.X509Certificate>();
for (X509Certificate cc : certs)
{
c.add((java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(cc.getEncoded())));
}
return c;
}
public static List<java.security.cert.X509Certificate> toCertList(Object[] certs)
throws Exception
{
CertificateFactory fac = CertificateFactory.getInstance("X509");
ArrayList<java.security.cert.X509Certificate> c = new ArrayList<java.security.cert.X509Certificate>();
for (Object cc : certs)
{
c.add(toJavaX509Certificate(cc));
}
return c;
}
public static java.security.cert.X509Certificate toJavaX509Certificate(Object o)
throws Exception
{
CertificateFactory fac = CertificateFactory.getInstance("X509");
if (o instanceof X509CertificateHolder)
{
return (java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509CertificateHolder)o).getEncoded()));
}
else if (o instanceof X509Certificate)
{
return (java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509Certificate)o).getEncoded()));
}
else if (o instanceof java.security.cert.X509Certificate)
{
return (java.security.cert.X509Certificate)o;
}
throw new IllegalArgumentException("Object not X509CertificateHolder, javax..X509Certificate or java...X509Certificate");
}
public static void runJUnit(Class c)
throws Exception
{
JUnitCore junit = new JUnitCore();
Result result = junit.run(c);
if (!result.wasSuccessful())
{
StringWriter sw = new StringWriter();
for (Failure f : result.getFailures())
{
sw.write(f.toString());
sw.write('\n');
}
throw new Exception("Tests failed: " + sw.toString());
}
}
/**
* @param sigName signing algorithm
* @param subjectDN Subject of the certificate.
* @param subjectPublicKeyInfo Public key of the subject.
* @param issuerDN Issuer of the certificate.
* @param issuerPrivateKey The issuer private key.
* @param serialNumber Serial number.
* @return A (java) X509Certificate.
* @throws Exception
*/
public static java.security.cert.X509Certificate createASignedCert(
String sigName,
X500Name subjectDN,
SubjectPublicKeyInfo subjectPublicKeyInfo,
X500Name issuerDN,
PrivateKey issuerPrivateKey,
long serialNumber,
ASN1EncodableVector purposes,
KeyUsage usage
)
throws Exception
{
// SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()));
long time = System.currentTimeMillis();
ExtensionsGenerator extGenerator = new ExtensionsGenerator();
if (usage != null)
{
extGenerator.addExtension(Extension.keyUsage, false, usage);
}
if (purposes != null)
{
extGenerator.addExtension(Extension.extendedKeyUsage, false, new DERSequence(purposes));
}
V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator();
certGen.setSerialNumber(new ASN1Integer(serialNumber));
certGen.setIssuer(issuerDN);
certGen.setSubject(subjectDN);
certGen.setStartDate(new Time(new Date(time - 24 * 60 * 60000)));
certGen.setEndDate(new Time(new Date(time + 30 * 60 * 60000)));
certGen.setSignature((AlgorithmIdentifier)algIds.get(sigName));
certGen.setSubjectPublicKeyInfo(subjectPublicKeyInfo);
certGen.setExtensions(extGenerator.generate());
TBSCertificate tbsCert = certGen.generateTBSCertificate();
Signature sig = Signature.getInstance(sigName, "BC");
sig.initSign(issuerPrivateKey);
sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER));
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(tbsCert);
v.add((AlgorithmIdentifier)algIds.get(sigName));
v.add(new DERBitString(sig.sign()));
return (java.security.cert.X509Certificate)
CertificateFactory.getInstance("X.509", "BC")
.generateCertificate(
new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER)
));
}
/**
* @param sigName signing algorithm
* @param subjectDN Subject of the certificate.
* @param subjectPublicKeyInfo Public key of the subject.
* @param issuerPrivateKey The issuer private key.
* @param serialNumber Serial number.
* @return A (java) X509Certificate.
* @throws Exception
*/
public static java.security.cert.X509Certificate createSelfsignedCert(
String sigName,
X500Name subjectDN,
SubjectPublicKeyInfo subjectPublicKeyInfo,
PrivateKey issuerPrivateKey,
long serialNumber
)
throws Exception
{
// SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()));
long time = System.currentTimeMillis();
V1TBSCertificateGenerator certGen = new V1TBSCertificateGenerator();
certGen.setSerialNumber(new ASN1Integer(serialNumber));
certGen.setIssuer(subjectDN);
certGen.setSubject(subjectDN);
certGen.setStartDate(new Time(new Date(time - 24 * 60 * 60000)));
certGen.setEndDate(new Time(new Date(time + 30 * 60 * 60000)));
certGen.setSignature((AlgorithmIdentifier)algIds.get(sigName));
certGen.setSubjectPublicKeyInfo(subjectPublicKeyInfo);
TBSCertificate tbsCert = certGen.generateTBSCertificate();
Signature sig = Signature.getInstance(sigName, "BC");
sig.initSign(issuerPrivateKey);
sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER));
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(tbsCert);
v.add((AlgorithmIdentifier)algIds.get(sigName));
v.add(new DERBitString(sig.sign()));
return (java.security.cert.X509Certificate)
CertificateFactory.getInstance("X.509", "BC")
.generateCertificate(
new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER)
));
}
public static PrivateKey readPemPrivateKeyPKCS8DER(File path, String alg)
throws Exception
{
int l = (int)path.length();
byte[] der = new byte[l];
DataInputStream din = new DataInputStream(new FileInputStream(path));
din.readFully(der);
din.close();
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(der);
KeyFactory kf = KeyFactory.getInstance(alg, "BC");
return kf.generatePrivate(ks);
}
public static PrivateKey readPemPrivateKey(File path, String alg)
throws Exception
{
FileReader fr = new FileReader(path);
PemReader reader = new PemReader(fr);
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(reader.readPemObject().getContent());
reader.close();
KeyFactory kf = KeyFactory.getInstance(alg, "BC");
return kf.generatePrivate(ks);
}
public static X509CertificateHolder readPemCertificate(File path)
throws Exception
{
FileReader fr = new FileReader(path);
PemReader reader = new PemReader(fr);
X509CertificateHolder fromFile = new X509CertificateHolder(reader.readPemObject().getContent());
reader.close();
fr.close();
return fromFile;
}
public static Object[] readPemCertificates(File path)
throws Exception
{
ArrayList<Object> certs = new ArrayList<Object>();
FileReader fr = new FileReader(path);
PemReader reader = new PemReader(fr);
PemObject o;
while((o = reader.readPemObject()) != null )
{
certs.add(new X509CertificateHolder(o.getContent()));
}
reader.close();
fr.close();
return certs.toArray(new Object[certs.size()]);
}
public static Object[] readCertAndKey(File path)
throws Exception
{
Object[] out = new Object[2];
FileReader fr = new FileReader(path);
PemReader reader = new PemReader(fr);
out[0] = toJavaX509Certificate(new X509CertificateHolder(reader.readPemObject().getContent()));
out[1] = new PKCS8EncodedKeySpec(reader.readPemObject().getContent());
reader.close();
fr.close();
return out;
}
public static String readToString(File f)
throws IOException
{
StringWriter sw = new StringWriter();
FileReader fr = new FileReader(f);
char[] b = new char[8192];
int i;
while ((i = fr.read(b)) > -1)
{
sw.write(b, 0, i);
}
fr.close();
sw.close();
return sw.toString();
}
public static X509Certificate toJavaxX509Certificate(Object o)
throws Exception
{
if (o instanceof byte[])
{
return X509Certificate.getInstance((byte[])o);
}
else if (o instanceof java.security.cert.Certificate)
{
return X509Certificate.getInstance(new ByteArrayInputStream(((Certificate)o).getEncoded()));
}
else if (o instanceof X509CertificateHolder)
{
return X509Certificate.getInstance(((X509CertificateHolder)o).getEncoded());
}
else
{
throw new IllegalArgumentException("Unable to convert certificate");
}
}
}