Skip to content

Commit

Permalink
CLOUDSTACK-9993: Bountycastle upgrade
Browse files Browse the repository at this point in the history
- Upgrades bountycastle version and uses newer classes
- Refactors SAMLUtil to use new CertUtils

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
  • Loading branch information
rohityadavcloud committed Aug 18, 2017
1 parent b5daace commit 2a67c3c
Show file tree
Hide file tree
Showing 19 changed files with 253 additions and 283 deletions.
1 change: 1 addition & 0 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@
<webAppConfig>
<contextPath>/client</contextPath>
<extraClasspath>${project.build.directory}/utilities/scripts/db/;${project.build.directory}/utilities/scripts/db/db/</extraClasspath>
<webInfIncludeJarPattern>.*/cloud.*jar$|.*/classes/.*</webInfIncludeJarPattern>
</webAppConfig>

<systemProperties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import java.security.Security;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
Expand Down Expand Up @@ -65,6 +64,7 @@
import org.apache.log4j.Logger;
import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

Expand Down Expand Up @@ -132,7 +132,7 @@ public final class RootCAProvider extends AdapterBase implements CAProvider, Con
/////////////// Root CA Private Methods ///////////////////
///////////////////////////////////////////////////////////

private Certificate generateCertificate(final List<String> domainNames, final List<String> ipAddresses, final int validityDays) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, CertificateException, SignatureException, IOException {
private Certificate generateCertificate(final List<String> domainNames, final List<String> ipAddresses, final int validityDays) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, CertificateException, SignatureException, IOException, OperatorCreationException {
if (domainNames == null || domainNames.size() < 1 || Strings.isNullOrEmpty(domainNames.get(0))) {
throw new CloudRuntimeException("No domain name is specified, cannot generate certificate");
}
Expand All @@ -151,7 +151,7 @@ private Certificate generateCertificate(final List<String> domainNames, final Li
return new Certificate(clientCertificate, keyPair.getPrivate(), Collections.singletonList(caCertificate));
}

private Certificate generateCertificateUsingCsr(final String csr, final List<String> domainNames, final List<String> ipAddresses, final int validityDays) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, CertificateException, SignatureException, IOException {
private Certificate generateCertificateUsingCsr(final String csr, final List<String> domainNames, final List<String> ipAddresses, final int validityDays) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, CertificateException, SignatureException, IOException, OperatorCreationException {
PemObject pemObject = null;

try {
Expand Down Expand Up @@ -197,7 +197,7 @@ public List<X509Certificate> getCaCertificate() {
public Certificate issueCertificate(final List<String> domainNames, final List<String> ipAddresses, final int validityDays) {
try {
return generateCertificate(domainNames, ipAddresses, validityDays);
} catch (final CertificateException | IOException | SignatureException | NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException e) {
} catch (final CertificateException | IOException | SignatureException | NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException | OperatorCreationException e) {
LOG.error("Failed to create client certificate, due to: ", e);
throw new CloudRuntimeException("Failed to generate certificate due to:" + e.getMessage());
}
Expand All @@ -207,7 +207,7 @@ public Certificate issueCertificate(final List<String> domainNames, final List<S
public Certificate issueCertificate(final String csr, final List<String> domainNames, final List<String> ipAddresses, final int validityDays) {
try {
return generateCertificateUsingCsr(csr, domainNames, ipAddresses, validityDays);
} catch (final CertificateException | IOException | SignatureException | NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException e) {
} catch (final CertificateException | IOException | SignatureException | NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException | OperatorCreationException e) {
LOG.error("Failed to generate certificate from CSR: ", e);
throw new CloudRuntimeException("Failed to generate certificate using CSR due to:" + e.getMessage());
}
Expand Down Expand Up @@ -470,7 +470,7 @@ private boolean saveNewRootCACertificate() {
if (!configDao.update(rootCACertificate.key(), rootCACertificate.category(), CertUtils.x509CertificateToPem(rootCaCertificate))) {
LOG.error("Failed to update RootCA public/x509 certificate");
}
} catch (final NoSuchAlgorithmException | NoSuchProviderException | CertificateEncodingException | SignatureException | InvalidKeyException | IOException e) {
} catch (final CertificateException | NoSuchAlgorithmException | NoSuchProviderException | SignatureException | InvalidKeyException | OperatorCreationException | IOException e) {
LOG.error("Failed to generate RootCA certificate from private/public keys due to exception:", e);
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,34 @@
// under the License.
package org.apache.cloudstack.saml;

import com.cloud.domain.Domain;
import com.cloud.user.DomainManager;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.component.AdapterBase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.inject.Inject;
import javax.xml.stream.FactoryConfigurationError;

import org.apache.cloudstack.api.command.AuthorizeSAMLSSOCmd;
import org.apache.cloudstack.api.command.GetServiceProviderMetaDataCmd;
import org.apache.cloudstack.api.command.ListAndSwitchSAMLAccountCmd;
Expand All @@ -34,9 +55,11 @@
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.security.keystore.KeystoreDao;
import org.apache.cloudstack.framework.security.keystore.KeystoreVO;
import org.apache.cloudstack.utils.security.CertUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.log4j.Logger;
import org.bouncycastle.operator.OperatorCreationException;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.metadata.ContactPerson;
Expand All @@ -61,32 +84,13 @@
import org.opensaml.xml.security.keyinfo.KeyInfoHelper;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import javax.xml.stream.FactoryConfigurationError;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import com.cloud.domain.Domain;
import com.cloud.user.DomainManager;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.component.AdapterBase;

@Component
public class SAML2AuthManagerImpl extends AdapterBase implements SAML2AuthManager, Configurable {
Expand Down Expand Up @@ -141,12 +145,14 @@ protected boolean initSP() {
KeystoreVO keyStoreVO = _ksDao.findByName(SAMLPluginConstants.SAMLSP_KEYPAIR);
if (keyStoreVO == null) {
try {
KeyPair keyPair = SAMLUtils.generateRandomKeyPair();
_ksDao.save(SAMLPluginConstants.SAMLSP_KEYPAIR, SAMLUtils.savePrivateKey(keyPair.getPrivate()), SAMLUtils.savePublicKey(keyPair.getPublic()), "samlsp-keypair");
KeyPair keyPair = CertUtils.generateRandomKeyPair(4096);
_ksDao.save(SAMLPluginConstants.SAMLSP_KEYPAIR,
CertUtils.privateKeyToPem(keyPair.getPrivate()),
CertUtils.publicKeyToPem(keyPair.getPublic()), "samlsp-keypair");
keyStoreVO = _ksDao.findByName(SAMLPluginConstants.SAMLSP_KEYPAIR);
s_logger.info("No SAML keystore found, created and saved a new Service Provider keypair");
} catch (NoSuchProviderException | NoSuchAlgorithmException e) {
s_logger.error("Unable to create and save SAML keypair: " + e.toString());
} catch (final NoSuchProviderException | NoSuchAlgorithmException | IOException e) {
s_logger.error("Unable to create and save SAML keypair, due to: ", e);
}
}

Expand All @@ -160,8 +166,19 @@ protected boolean initSP() {
KeyPair spKeyPair = null;
X509Certificate spX509Key = null;
if (keyStoreVO != null) {
PrivateKey privateKey = SAMLUtils.loadPrivateKey(keyStoreVO.getCertificate());
PublicKey publicKey = SAMLUtils.loadPublicKey(keyStoreVO.getKey());

PrivateKey privateKey = null;
try {
privateKey = CertUtils.pemToPrivateKey(keyStoreVO.getCertificate());
} catch (final InvalidKeySpecException | IOException e) {
s_logger.error("Failed to read private key, due to error: ", e);
}
PublicKey publicKey = null;
try {
publicKey = CertUtils.pemToPublicKey(keyStoreVO.getKey());
} catch (final InvalidKeySpecException | IOException e) {
s_logger.error("Failed to read public key, due to error: ", e);
}
if (privateKey != null && publicKey != null) {
spKeyPair = new KeyPair(publicKey, privateKey);
KeystoreVO x509VO = _ksDao.findByName(SAMLPluginConstants.SAMLSP_X509CERT);
Expand All @@ -174,8 +191,8 @@ protected boolean initSP() {
out.flush();
_ksDao.save(SAMLPluginConstants.SAMLSP_X509CERT, Base64.encodeBase64String(bos.toByteArray()), "", "samlsp-x509cert");
bos.close();
} catch (NoSuchAlgorithmException | NoSuchProviderException | CertificateEncodingException | SignatureException | InvalidKeyException | IOException e) {
s_logger.error("SAML Plugin won't be able to use X509 signed authentication");
} catch (final NoSuchAlgorithmException | NoSuchProviderException | CertificateException | SignatureException | InvalidKeyException | IOException | OperatorCreationException e) {
s_logger.error("SAML plugin won't be able to use X509 signed authentication", e);
}
} else {
try {
Expand Down
Loading

0 comments on commit 2a67c3c

Please sign in to comment.