Merge pull request #960 from girirajsharma/master

Updated BC provider versions and deprecated CertificateUtil methods.
This commit is contained in:
Bill Burke 2015-02-10 17:55:45 -05:00
commit 40f2fb91bc
40 changed files with 202 additions and 85 deletions

View file

@ -28,7 +28,12 @@
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -73,6 +73,7 @@ public class PublishedRealmRepresentation {
try {
pemWriter.writeObject(publicKey);
pemWriter.flush();
pemWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}

View file

@ -1,66 +1,166 @@
package org.keycloak.util;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.x509.X509V1CertificateGenerator;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
import javax.security.auth.x500.X500Principal;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Date;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509ExtensionUtils;
import org.bouncycastle.cert.X509v1CertificateBuilder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
/**
* The Class CertificateUtils provides utility functions for generation of V1 and V3 {@link java.security.cert.X509Certificate}
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
* @author <a href="mailto:giriraj.sharma27@gmail.com">Giriraj Sharma</a>
* @version $Revision: 2 $
*/
public class CertificateUtils {
static {
BouncyIntegration.init();
}
public static X509Certificate generateV3Certificate(KeyPair keyPair, PrivateKey caPrivateKey, X509Certificate caCert, String subject) throws Exception {
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
X500Principal subjectName = new X500Principal("CN=" + subject);
/**
* Generates version 3 {@link java.security.cert.X509Certificate}.
*
* @param keyPair the key pair
* @param caPrivateKey the CA private key
* @param caCert the CA certificate
* @param subject the subject name
*
* @return the x509 certificate
*
* @throws Exception the exception
*/
public static X509Certificate generateV3Certificate(KeyPair keyPair, PrivateKey caPrivateKey, X509Certificate caCert,
String subject) throws Exception {
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
certGen.setSerialNumber(serialNumber);
certGen.setIssuerDN(caCert.getSubjectX500Principal());
certGen.setNotBefore(new Date(System.currentTimeMillis() - 100000));
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, 10);
certGen.setNotAfter(calendar.getTime());
certGen.setSubjectDN(subjectName);
certGen.setPublicKey(keyPair.getPublic());
certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
try {
X500Name subjectDN = new X500Name("CN=" + subject);
certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
new AuthorityKeyIdentifierStructure(caCert));
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
new SubjectKeyIdentifierStructure(keyPair.getPublic()));
// Serial Number
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
BigInteger serialNumber = BigInteger.valueOf(Math.abs(random.nextInt()));
X509Certificate cert = certGen.generate(caPrivateKey, "BC"); // note: private key of CA
return cert;
// Validity
Date notBefore = new Date(System.currentTimeMillis());
Date notAfter = new Date(System.currentTimeMillis() + (((1000L * 60 * 60 * 24 * 30)) * 12) * 3);
// SubjectPublicKeyInfo
SubjectPublicKeyInfo subjPubKeyInfo = new SubjectPublicKeyInfo(ASN1Sequence.getInstance(keyPair.getPublic()
.getEncoded()));
X509v3CertificateBuilder certGen = new X509v3CertificateBuilder(new X500Name(caCert.getSubjectDN().getName()),
serialNumber, notBefore, notAfter, subjectDN, subjPubKeyInfo);
DigestCalculator digCalc = new BcDigestCalculatorProvider()
.get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1));
X509ExtensionUtils x509ExtensionUtils = new X509ExtensionUtils(digCalc);
// Subject Key Identifier
certGen.addExtension(Extension.subjectKeyIdentifier, false,
x509ExtensionUtils.createSubjectKeyIdentifier(subjPubKeyInfo));
// Authority Key Identifier
certGen.addExtension(Extension.authorityKeyIdentifier, false,
x509ExtensionUtils.createAuthorityKeyIdentifier(subjPubKeyInfo));
// Key Usage
certGen.addExtension(Extension.keyUsage, false, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign
| KeyUsage.cRLSign));
// Extended Key Usage
KeyPurposeId[] EKU = new KeyPurposeId[2];
EKU[0] = KeyPurposeId.id_kp_emailProtection;
EKU[1] = KeyPurposeId.id_kp_serverAuth;
certGen.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(EKU));
// Basic Constraints
certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0));
// Content Signer
ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider("BC").build(caPrivateKey);
// Certificate
return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certGen.build(sigGen));
} catch (Exception e) {
throw new RuntimeException("Error creating X509v3Certificate.", e);
}
}
public static X509Certificate generateV1SelfSignedCertificate(KeyPair keyPair, String subject) throws Exception {
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
X500Principal subjectPrincipal = new X500Principal("CN=" + subject);
certGen.setSerialNumber(serialNumber);
certGen.setIssuerDN(subjectPrincipal);
certGen.setNotBefore(new Date(System.currentTimeMillis() - 100000));
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, 10);
certGen.setNotAfter(calendar.getTime());
certGen.setSubjectDN(subjectPrincipal);
certGen.setPublicKey(keyPair.getPublic());
certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
X509Certificate cert = certGen.generate(keyPair.getPrivate(), "BC");
return cert;
/**
* Generate version 1 self signed {@link java.security.cert.X509Certificate}..
*
* @param caKeyPair the CA key pair
* @param subject the subject name
*
* @return the x509 certificate
*
* @throws Exception the exception
*/
public static X509Certificate generateV1SelfSignedCertificate(KeyPair caKeyPair, String subject) throws Exception {
try {
X500Name subjectDN = new X500Name("CN=" + subject);
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
Date validityStartDate = new Date(System.currentTimeMillis() - 100000);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, 10);
Date validityEndDate = new Date(calendar.getTime().getTime());
SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(caKeyPair.getPublic().getEncoded());
X509v1CertificateBuilder builder = new X509v1CertificateBuilder(subjectDN, serialNumber, validityStartDate,
validityEndDate, subjectDN, subPubKeyInfo);
X509CertificateHolder holder = builder.build(createSigner(caKeyPair.getPrivate()));
return new JcaX509CertificateConverter().getCertificate(holder);
} catch (Exception e) {
throw new RuntimeException("Error creating X509v1Certificate.", e);
}
}
/**
* Creates the content signer for generation of Version 1 {@link java.security.cert.X509Certificate}.
*
* @param privateKey the private key
*
* @return the content signer
*/
public static ContentSigner createSigner(PrivateKey privateKey) {
try {
AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption");
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
return new BcRSAContentSignerBuilder(sigAlgId, digAlgId)
.build(PrivateKeyFactory.createKey(privateKey.getEncoded()));
} catch (Exception e) {
throw new RuntimeException("Could not create content signer.", e);
}
}
}

View file

@ -26,7 +26,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>

View file

@ -48,7 +48,7 @@
</module-def>
<module-def name="org.bouncycastle">
<maven-resource group="org.bouncycastle" artifact="bcprov-jdk16"/>
<maven-resource group="org.bouncycastle" artifact="bcprov-jdk15on"/>
</module-def>
<module-def name="org.jboss.aesh">

View file

@ -59,7 +59,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.core</groupId>

View file

@ -29,7 +29,7 @@
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -40,7 +40,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -26,7 +26,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View file

@ -41,7 +41,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -52,7 +52,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -56,7 +56,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -71,7 +71,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -57,7 +57,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -16,7 +16,7 @@
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -45,7 +45,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -62,7 +62,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -63,7 +63,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -75,7 +75,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -41,7 +41,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -51,7 +51,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -21,7 +21,12 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -88,6 +88,7 @@ public final class KeycloakModelUtils {
try {
pemWriter.writeObject(key);
pemWriter.flush();
pemWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
@ -101,6 +102,7 @@ public final class KeycloakModelUtils {
try {
pemWriter.writeObject(certificate);
pemWriter.flush();
pemWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}

View file

@ -16,7 +16,7 @@
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -16,7 +16,7 @@
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -17,7 +17,7 @@
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

14
pom.xml
View file

@ -14,7 +14,8 @@
<properties>
<aesh.version>0.33.12</aesh.version>
<base64.version>2.3.8</base64.version>
<bouncycastle.version>1.46</bouncycastle.version>
<bouncycastle.crypto.version>1.50</bouncycastle.crypto.version>
<bouncycastle.mail.version>1.46</bouncycastle.mail.version>
<jackson.version>1.9.9</jackson.version>
<keycloak.apache.httpcomponents.version>4.2.1</keycloak.apache.httpcomponents.version>
<resteasy.version>2.3.7.Final</resteasy.version>
@ -132,13 +133,18 @@
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>${bouncycastle.version}</version>
<artifactId>bcprov-jdk15on</artifactId>
<version>${bouncycastle.crypto.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>${bouncycastle.crypto.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk16</artifactId>
<version>${bouncycastle.version}</version>
<version>${bouncycastle.mail.version}</version>
</dependency>
<dependency>
<groupId>net.iharder</groupId>

View file

@ -17,7 +17,7 @@
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>

View file

@ -45,7 +45,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>

View file

@ -1,6 +1,6 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -11,12 +11,12 @@
<artifactId>keycloak-services</artifactId>
<name>Keycloak REST Services</name>
<description/>
<description />
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -27,10 +27,8 @@ import java.io.InputStream;
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.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.List;

View file

@ -107,7 +107,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View file

@ -101,7 +101,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View file

@ -101,7 +101,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View file

@ -101,7 +101,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View file

@ -75,7 +75,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>

View file

@ -106,7 +106,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View file

@ -100,7 +100,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View file

@ -101,7 +101,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View file

@ -100,7 +100,7 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>