This is an automated email from the ASF dual-hosted git repository.
bhaisaab pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/master by this push:
new c3ed1b3 CLOUDSTACK-9993: Have basic constraint in CA certificate
(#2286)
c3ed1b3 is described below
commit c3ed1b38e52b2b47578e7c3eecd4694360e97bfe
Author: Rohit Yadav <[email protected]>
AuthorDate: Wed Oct 11 17:41:37 2017 +0530
CLOUDSTACK-9993: Have basic constraint in CA certificate (#2286)
- Refactors V3 x509 cert generator to put basic constraint and key usage
extensions when CA cert is created
- Refactors root CA provider to use V3 generator to generate CA cert
Signed-off-by: Rohit Yadav <[email protected]>
---
.../cloudstack/ca/provider/RootCAProvider.java | 38 ++++++--------
.../ca/provider/RootCACustomTrustManagerTest.java | 5 +-
.../cloudstack/ca/provider/RootCAProviderTest.java | 2 +-
.../apache/cloudstack/ca/CABackgroundTaskTest.java | 3 +-
.../apache/cloudstack/ca/CAManagerImplTest.java | 4 +-
.../cloudstack/utils/security/CertUtils.java | 60 +++++++++++++---------
.../cloudstack/utils/security/CertUtilsTest.java | 4 +-
7 files changed, 61 insertions(+), 55 deletions(-)
diff --git
a/plugins/ca/root-ca/src/org/apache/cloudstack/ca/provider/RootCAProvider.java
b/plugins/ca/root-ca/src/org/apache/cloudstack/ca/provider/RootCAProvider.java
index f21cae3..93c8d9d 100644
---
a/plugins/ca/root-ca/src/org/apache/cloudstack/ca/provider/RootCAProvider.java
+++
b/plugins/ca/root-ca/src/org/apache/cloudstack/ca/provider/RootCAProvider.java
@@ -137,14 +137,9 @@ public final class RootCAProvider extends AdapterBase
implements CAProvider, Con
final KeyPair keyPair =
CertUtils.generateRandomKeyPair(CAManager.CertKeySize.value());
final X509Certificate clientCertificate =
CertUtils.generateV3Certificate(
- caCertificate,
- caKeyPair.getPrivate(),
- keyPair.getPublic(),
- subject,
- CAManager.CertSignatureAlgorithm.value(),
- validityDays,
- domainNames,
- ipAddresses);
+ caCertificate, caKeyPair, keyPair.getPublic(),
+ subject, CAManager.CertSignatureAlgorithm.value(),
+ validityDays, domainNames, ipAddresses);
return new Certificate(clientCertificate, keyPair.getPrivate(),
Collections.singletonList(caCertificate));
}
@@ -164,14 +159,11 @@ public final class RootCAProvider extends AdapterBase
implements CAProvider, Con
final PKCS10CertificationRequest request = new
PKCS10CertificationRequest(pemObject.getContent());
+ final String subject =
request.getCertificationRequestInfo().getSubject().toString();
final X509Certificate clientCertificate =
CertUtils.generateV3Certificate(
- caCertificate, caKeyPair.getPrivate(),
- request.getPublicKey(),
- request.getCertificationRequestInfo().getSubject().toString(),
- CAManager.CertSignatureAlgorithm.value(),
- validityDays,
- domainNames,
- ipAddresses);
+ caCertificate, caKeyPair, request.getPublicKey(),
+ subject, CAManager.CertSignatureAlgorithm.value(),
+ validityDays, domainNames, ipAddresses);
return new Certificate(clientCertificate, null,
Collections.singletonList(caCertificate));
}
@@ -257,6 +249,10 @@ public final class RootCAProvider extends AdapterBase
implements CAProvider, Con
/////////////// Root CA Config ///////////////////
//////////////////////////////////////////////////
+ private int getCaValidityDays() {
+ return 365 * caValidityYears;
+ }
+
private char[] findKeyStorePassphrase() {
char[] passphrase = KeyStoreUtils.defaultKeystorePassphrase;
final String configuredPassphrase =
DbProperties.getDbProperties().getProperty("db.cloud.keyStorePassphrase");
@@ -268,7 +264,7 @@ public final class RootCAProvider extends AdapterBase
implements CAProvider, Con
private boolean createManagementServerKeystore(final String
keyStoreFilePath, final char[] passphrase) {
final Certificate managementServerCertificate =
issueCertificate(Collections.singletonList(NetUtils.getHostName()),
- Collections.singletonList(NetUtils.getDefaultHostIp()),
caValidityYears * 365);
+ Collections.singletonList(NetUtils.getDefaultHostIp()),
getCaValidityDays());
if (managementServerCertificate == null ||
managementServerCertificate.getPrivateKey() == null) {
throw new CloudRuntimeException("Failed to generate certificate
and setup management server keystore");
}
@@ -347,12 +343,10 @@ public final class RootCAProvider extends AdapterBase
implements CAProvider, Con
}
try {
LOG.debug("Generating root CA certificate");
- final X509Certificate rootCaCertificate =
CertUtils.generateV1Certificate(
- caKeyPair,
- rootCAIssuerDN.value(),
- rootCAIssuerDN.value(),
- caValidityYears,
- CAManager.CertSignatureAlgorithm.value());
+ final X509Certificate rootCaCertificate =
CertUtils.generateV3Certificate(
+ null, caKeyPair, caKeyPair.getPublic(),
+ rootCAIssuerDN.value(),
CAManager.CertSignatureAlgorithm.value(),
+ getCaValidityDays(), null, null);
if (!configDao.update(rootCACertificate.key(),
rootCACertificate.category(),
CertUtils.x509CertificateToPem(rootCaCertificate))) {
LOG.error("Failed to update RootCA public/x509 certificate");
}
diff --git
a/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCACustomTrustManagerTest.java
b/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCACustomTrustManagerTest.java
index cab1941..8161d75 100644
---
a/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCACustomTrustManagerTest.java
+++
b/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCACustomTrustManagerTest.java
@@ -56,9 +56,8 @@ public class RootCACustomTrustManagerTest {
certMap.clear();
caKeypair = CertUtils.generateRandomKeyPair(1024);
clientKeypair = CertUtils.generateRandomKeyPair(1024);
- caCertificate = CertUtils.generateV1Certificate(caKeypair, "CN=ca",
"CN=ca", 1,
- "SHA256withRSA");
- expiredClientCertificate =
CertUtils.generateV3Certificate(caCertificate, caKeypair.getPrivate(),
clientKeypair.getPublic(),
+ caCertificate = CertUtils.generateV3Certificate(null, caKeypair,
caKeypair.getPublic(), "CN=ca", "SHA256withRSA", 365, null, null);
+ expiredClientCertificate =
CertUtils.generateV3Certificate(caCertificate, caKeypair,
clientKeypair.getPublic(),
"CN=cloudstack.apache.org", "SHA256withRSA", 0,
Collections.singletonList("cloudstack.apache.org"),
Collections.singletonList(clientIp));
}
diff --git
a/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCAProviderTest.java
b/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCAProviderTest.java
index 44e2bcf..d5d6428 100644
---
a/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCAProviderTest.java
+++
b/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCAProviderTest.java
@@ -66,7 +66,7 @@ public class RootCAProviderTest {
@Before
public void setUp() throws Exception {
caKeyPair = CertUtils.generateRandomKeyPair(1024);
- caCertificate = CertUtils.generateV1Certificate(caKeyPair, "CN=ca",
"CN=ca", 1, "SHA256withRSA");
+ caCertificate = CertUtils.generateV3Certificate(null, caKeyPair,
caKeyPair.getPublic(), "CN=ca", "SHA256withRSA", 365, null, null);
provider = new RootCAProvider();
diff --git a/server/test/org/apache/cloudstack/ca/CABackgroundTaskTest.java
b/server/test/org/apache/cloudstack/ca/CABackgroundTaskTest.java
index d2c800d..564bbe3 100644
--- a/server/test/org/apache/cloudstack/ca/CABackgroundTaskTest.java
+++ b/server/test/org/apache/cloudstack/ca/CABackgroundTaskTest.java
@@ -68,8 +68,7 @@ public class CABackgroundTaskTest {
host.setManagementServerId(ManagementServerNode.getManagementServerId());
task = new CAManagerImpl.CABackgroundTask(caManager, hostDao);
final KeyPair keypair = CertUtils.generateRandomKeyPair(1024);
- expiredCertificate = CertUtils.generateV1Certificate(keypair, "CN=ca",
"CN=ca", 0,
- "SHA256withRSA");
+ expiredCertificate = CertUtils.generateV3Certificate(null, keypair,
keypair.getPublic(), "CN=ca", "SHA256withRSA", 0, null, null);
Mockito.when(hostDao.findByIp(Mockito.anyString())).thenReturn(host);
Mockito.when(caManager.getActiveCertificatesMap()).thenReturn(certMap);
diff --git a/server/test/org/apache/cloudstack/ca/CAManagerImplTest.java
b/server/test/org/apache/cloudstack/ca/CAManagerImplTest.java
index 87e128c..14ecc97 100644
--- a/server/test/org/apache/cloudstack/ca/CAManagerImplTest.java
+++ b/server/test/org/apache/cloudstack/ca/CAManagerImplTest.java
@@ -21,6 +21,7 @@ package org.apache.cloudstack.ca;
import java.lang.reflect.Field;
import java.math.BigInteger;
+import java.security.KeyPair;
import java.security.cert.X509Certificate;
import java.util.Collections;
@@ -108,7 +109,8 @@ public class CAManagerImplTest {
public void testProvisionCertificate() throws Exception {
final Host host = Mockito.mock(Host.class);
Mockito.when(host.getPrivateIpAddress()).thenReturn("1.2.3.4");
- final X509Certificate certificate =
CertUtils.generateV1Certificate(CertUtils.generateRandomKeyPair(1024), "CN=ca",
"CN=ca", 1, "SHA256withRSA");
+ final KeyPair keyPair = CertUtils.generateRandomKeyPair(1024);
+ final X509Certificate certificate =
CertUtils.generateV3Certificate(null, keyPair, keyPair.getPublic(), "CN=ca",
"SHA256withRSA", 365, null, null);
Mockito.when(caProvider.issueCertificate(Mockito.anyString(),
Mockito.anyList(), Mockito.anyList(), Mockito.anyInt())).thenReturn(new
Certificate(certificate, null, Collections.singletonList(certificate)));
Mockito.when(agentManager.send(Mockito.anyLong(),
Mockito.any(SetupKeyStoreCommand.class))).thenReturn(new
SetupKeystoreAnswer("someCsr"));
Mockito.when(agentManager.reconnect(Mockito.anyLong())).thenReturn(true);
diff --git
a/utils/src/main/java/org/apache/cloudstack/utils/security/CertUtils.java
b/utils/src/main/java/org/apache/cloudstack/utils/security/CertUtils.java
index c2ef9ed..7e78362 100644
--- a/utils/src/main/java/org/apache/cloudstack/utils/security/CertUtils.java
+++ b/utils/src/main/java/org/apache/cloudstack/utils/security/CertUtils.java
@@ -48,9 +48,11 @@ import org.apache.log4j.Logger;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v1CertificateBuilder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
@@ -176,7 +178,7 @@ public class CertUtils {
}
public static X509Certificate generateV3Certificate(final X509Certificate
caCert,
- final PrivateKey
caPrivateKey,
+ final KeyPair
caKeyPair,
final PublicKey
clientPublicKey,
final String subject,
final String
signatureAlgorithm,
@@ -186,25 +188,34 @@ public class CertUtils {
final DateTime now = DateTime.now(DateTimeZone.UTC);
final BigInteger serial = generateRandomBigInt();
- final X509v3CertificateBuilder certBuilder = new
JcaX509v3CertificateBuilder(
- caCert,
- serial,
- now.minusHours(12).toDate(),
- now.plusDays(validityDays).toDate(),
- new X500Principal(subject),
- clientPublicKey);
-
final JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
+ final X509v3CertificateBuilder certBuilder;
+ if (caCert == null) {
+ // Generate CA certificate
+ certBuilder = new JcaX509v3CertificateBuilder(
+ new X500Name(subject),
+ serial,
+ now.minusHours(12).toDate(),
+ now.plusDays(validityDays).toDate(),
+ new X500Name(subject),
+ clientPublicKey);
+
+ certBuilder.addExtension(Extension.basicConstraints, true, new
BasicConstraints(true));
+ certBuilder.addExtension(Extension.keyUsage, true, new
KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign));
+ } else {
+ // Generate client certificate
+ certBuilder = new JcaX509v3CertificateBuilder(
+ caCert,
+ serial,
+ now.minusHours(12).toDate(),
+ now.plusDays(validityDays).toDate(),
+ new X500Principal(subject),
+ clientPublicKey);
+
+ certBuilder.addExtension(Extension.authorityKeyIdentifier, false,
extUtils.createAuthorityKeyIdentifier(caCert));
+ }
- certBuilder.addExtension(
- Extension.subjectKeyIdentifier,
- false,
- extUtils.createSubjectKeyIdentifier(clientPublicKey));
-
- certBuilder.addExtension(
- Extension.authorityKeyIdentifier,
- false,
- extUtils.createAuthorityKeyIdentifier(caCert));
+ certBuilder.addExtension(Extension.subjectKeyIdentifier, false,
extUtils.createSubjectKeyIdentifier(clientPublicKey));
final List<ASN1Encodable> subjectAlternativeNames = new
ArrayList<ASN1Encodable>();
if (publicIPAddresses != null) {
@@ -225,16 +236,17 @@ public class CertUtils {
}
if (subjectAlternativeNames.size() > 0) {
final GeneralNames subjectAltNames = GeneralNames.getInstance(new
DERSequence(subjectAlternativeNames.toArray(new ASN1Encodable[] {})));
- certBuilder.addExtension(
- Extension.subjectAlternativeName,
- false,
- subjectAltNames);
+ certBuilder.addExtension(Extension.subjectAlternativeName, false,
subjectAltNames);
}
- final ContentSigner signer = new
JcaContentSignerBuilder(signatureAlgorithm).setProvider("BC").build(caPrivateKey);
+ final ContentSigner signer = new
JcaContentSignerBuilder(signatureAlgorithm).setProvider("BC").build(caKeyPair.getPrivate());
final X509CertificateHolder certHolder = certBuilder.build(signer);
final X509Certificate cert = new
JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
- cert.verify(caCert.getPublicKey());
+ if (caCert != null) {
+ cert.verify(caCert.getPublicKey());
+ } else {
+ cert.verify(caKeyPair.getPublic());
+ }
return cert;
}
}
diff --git
a/utils/src/test/java/org/apache/cloudstack/utils/security/CertUtilsTest.java
b/utils/src/test/java/org/apache/cloudstack/utils/security/CertUtilsTest.java
index 406f604..1fed176 100644
---
a/utils/src/test/java/org/apache/cloudstack/utils/security/CertUtilsTest.java
+++
b/utils/src/test/java/org/apache/cloudstack/utils/security/CertUtilsTest.java
@@ -39,7 +39,7 @@ public class CertUtilsTest {
@Before
public void setUp() throws Exception {
caKeyPair = CertUtils.generateRandomKeyPair(1024);
- caCertificate = CertUtils.generateV1Certificate(caKeyPair, "CN=test",
"CN=test", 1, "SHA256WithRSAEncryption");
+ caCertificate = CertUtils.generateV3Certificate(null, caKeyPair,
caKeyPair.getPublic(), "CN=test", "SHA256WithRSAEncryption", 365, null, null);
}
@Test
@@ -93,7 +93,7 @@ public class CertUtilsTest {
final List<String> domainNames = Arrays.asList("domain1.com",
"www.2.domain2.com", "3.domain3.com");
final List<String> addressList = Arrays.asList("1.2.3.4",
"192.168.1.1", "2a02:120b:2c16:f6d0:d9df:8ebc:e44a:f181");
- final X509Certificate clientCert =
CertUtils.generateV3Certificate(caCertificate, caKeyPair.getPrivate(),
clientKeyPair.getPublic(),
+ final X509Certificate clientCert =
CertUtils.generateV3Certificate(caCertificate, caKeyPair,
clientKeyPair.getPublic(),
"CN=domain.example", "SHA256WithRSAEncryption", 10,
domainNames, addressList);
clientCert.verify(caKeyPair.getPublic());
--
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].