All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.openqa.selenium.server.security.CertificateGenerator Maven / Gradle / Ivy
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.openqa.selenium.server.security;
import com.google.common.base.Throwables;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.CRLDistPoint;
import org.bouncycastle.asn1.x509.DistributionPoint;
import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509Extension;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.openqa.selenium.io.IOUtils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import javax.security.auth.x500.X500Principal;
public class CertificateGenerator {
private static final String KEY_PURPOSE_BASE = "1.3.6.1.5.5.7.3";
private static final String SERVER_AUTH = KEY_PURPOSE_BASE + ".1";
private static final String CLIENT_AUTH = KEY_PURPOSE_BASE + ".2";
private static final String BOUNCY_CASTLE = "BC";
private static char[] SIGNING_PASSWORD = "password".toCharArray();
private static final AtomicLong serialSeed = new AtomicLong(new Date().getTime()/1000);
private final KeyAndCert caCert;
private final File serializedStore;
private final KeyPairGenerator pairGenerator;
public CertificateGenerator(File root) {
Security.addProvider(new BouncyCastleProvider());
serializedStore = new File(root, "cybervillainsCA.jks");
try {
pairGenerator = KeyPairGenerator.getInstance("RSA");
pairGenerator.initialize(1024);
caCert = readRootSigningCert();
} catch (NoSuchAlgorithmException e) {
throw Throwables.propagate(e);
}
}
public KeyAndCert generateCertificate(String hostname, String certificateRevocationList) {
X500Principal x500issuer = caCert.getCertificate().getIssuerX500Principal();
String subject = String.format(
"CN=%s, OU=Test, O=CyberVillainsCA, L=Seattle, S=Washington, C=US", hostname);
X500Principal x500subject = new X500Principal(subject);
Date begin = new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
Date end = new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(365));
KeyPair keypair = pairGenerator.generateKeyPair();
try {
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
(ASN1Sequence) new ASN1InputStream(
new ByteArrayInputStream(keypair.getPublic().getEncoded())).readObject());
X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(x500issuer,
BigInteger.valueOf(serialSeed.getAndIncrement()),
begin,
end, x500subject, keypair.getPublic());
builder.addExtension(X509Extension.basicConstraints, true, new BasicConstraints(false));
builder.addExtension(X509Extension.subjectKeyIdentifier, false, info);
AuthorityKeyIdentifier caIdentifier = new JcaX509ExtensionUtils()
.createAuthorityKeyIdentifier(caCert.getCertificate());
builder.addExtension(X509Extension.authorityKeyIdentifier, false, caIdentifier);
DERSequence typicalSSLServerExtendedKeyUsages = new DERSequence(new ASN1Encodable[]{
new DERObjectIdentifier(SERVER_AUTH),
new DERObjectIdentifier(CLIENT_AUTH),
});
builder.addExtension(X509Extension.extendedKeyUsage, false, typicalSSLServerExtendedKeyUsages);
if (certificateRevocationList != null) {
/* Safari on Windows requires a CRL and validates it */
DistributionPoint crl = new DistributionPoint(new DistributionPointName(
DistributionPointName.FULL_NAME, new GeneralName(
GeneralName.uniformResourceIdentifier, certificateRevocationList)), null, null);
builder.addExtension(
X509Extension.cRLDistributionPoints,
false,
new CRLDistPoint(new DistributionPoint[]{crl}));
}
ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BOUNCY_CASTLE)
.build(caCert.getPrivateKey());
X509CertificateHolder holder = builder.build(signer);
X509Certificate cert = new JcaX509CertificateConverter().setProvider(BOUNCY_CASTLE)
.getCertificate(holder);
return new KeyAndCert(keypair.getPrivate(), cert);
} catch(GeneralSecurityException e) {
throw Throwables.propagate(e);
} catch (IOException e) {
throw Throwables.propagate(e);
} catch (OperatorCreationException e) {
throw Throwables.propagate(e);
}
}
private KeyAndCert readRootSigningCert() {
InputStream is = null;
try {
KeyStore keystore = KeyStore.getInstance("JKS");
is = new FileInputStream(serializedStore);
keystore.load(is, SIGNING_PASSWORD);
X509Certificate caCert = (X509Certificate) keystore.getCertificate("signingCert");
PrivateKey caPrivateKey = (PrivateKey) keystore.getKey("signingCertPrivKey", SIGNING_PASSWORD);
return new KeyAndCert(caPrivateKey, caCert);
} catch (KeyStoreException e) {
throw Throwables.propagate(e);
} catch (CertificateException e) {
throw Throwables.propagate(e);
} catch (UnrecoverableKeyException e) {
throw Throwables.propagate(e);
} catch (NoSuchAlgorithmException e) {
throw Throwables.propagate(e);
} catch (FileNotFoundException e) {
throw Throwables.propagate(e);
} catch (IOException e) {
throw Throwables.propagate(e);
} finally {
IOUtils.closeQuietly(is);
}
}
}