diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java index d280ed5adaf..f0a5bab4c4a 100644 --- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java +++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java @@ -32,7 +32,6 @@ 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; @@ -147,11 +146,11 @@ public class SAML2AuthManagerImpl extends AdapterBase implements SAML2AuthManage try { KeyPair keyPair = CertUtils.generateRandomKeyPair(4096); _ksDao.save(SAMLPluginConstants.SAMLSP_KEYPAIR, - CertUtils.privateKeyToPem(keyPair.getPrivate()), - CertUtils.publicKeyToPem(keyPair.getPublic()), "samlsp-keypair"); + SAMLUtils.encodePrivateKey(keyPair.getPrivate()), + SAMLUtils.encodePublicKey(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 (final NoSuchProviderException | NoSuchAlgorithmException | IOException e) { + } catch (final NoSuchProviderException | NoSuchAlgorithmException e) { s_logger.error("Unable to create and save SAML keypair, due to: ", e); } } @@ -166,19 +165,8 @@ public class SAML2AuthManagerImpl extends AdapterBase implements SAML2AuthManage KeyPair spKeyPair = null; X509Certificate spX509Key = null; if (keyStoreVO != null) { - - 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); - } + final PrivateKey privateKey = SAMLUtils.decodePrivateKey(keyStoreVO.getCertificate()); + final PublicKey publicKey = SAMLUtils.decodePublicKey(keyStoreVO.getKey()); if (privateKey != null && publicKey != null) { spKeyPair = new KeyPair(publicKey, privateKey); KeystoreVO x509VO = _ksDao.findByName(SAMLPluginConstants.SAMLSP_X509CERT); diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLUtils.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLUtils.java index 364ef86103f..5b00d4733b6 100644 --- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLUtils.java +++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLUtils.java @@ -28,15 +28,20 @@ import java.math.BigInteger; import java.net.URLEncoder; import java.nio.charset.Charset; import java.security.InvalidKeyException; +import java.security.KeyFactory; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; +import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; import java.util.List; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; @@ -264,12 +269,6 @@ public class SAMLUtils { return url; } - public static X509Certificate generateRandomX509Certificate(KeyPair keyPair) throws NoSuchAlgorithmException, NoSuchProviderException, CertificateException, SignatureException, InvalidKeyException, OperatorCreationException { - return CertUtils.generateV1Certificate(keyPair, - "CN=ApacheCloudStack", "CN=ApacheCloudStack", - 3, "SHA256WithRSA"); - } - public static void setupSamlUserCookies(final LoginCmdResponse loginResponse, final HttpServletResponse resp) throws IOException { resp.addCookie(new Cookie("userid", URLEncoder.encode(loginResponse.getUserId(), HttpUtils.UTF_8))); resp.addCookie(new Cookie("domainid", URLEncoder.encode(loginResponse.getDomainId(), HttpUtils.UTF_8))); @@ -284,4 +283,82 @@ public class SAMLUtils { resp.addHeader("SET-COOKIE", String.format("%s=%s;HttpOnly", ApiConstants.SESSIONKEY, loginResponse.getSessionKey())); } + /** + * Returns base64 encoded PublicKey + * @param key PublicKey + * @return public key encoded string + */ + public static String encodePublicKey(PublicKey key) { + try { + KeyFactory keyFactory = CertUtils.getKeyFactory(); + if (keyFactory == null) return null; + X509EncodedKeySpec spec = keyFactory.getKeySpec(key, X509EncodedKeySpec.class); + return new String(org.bouncycastle.util.encoders.Base64.encode(spec.getEncoded()), Charset.forName("UTF-8")); + } catch (InvalidKeySpecException e) { + s_logger.error("Unable to create KeyFactory:" + e.getMessage()); + } + return null; + } + + /** + * Returns base64 encoded PrivateKey + * @param key PrivateKey + * @return privatekey encoded string + */ + public static String encodePrivateKey(PrivateKey key) { + try { + KeyFactory keyFactory = CertUtils.getKeyFactory(); + if (keyFactory == null) return null; + PKCS8EncodedKeySpec spec = keyFactory.getKeySpec(key, + PKCS8EncodedKeySpec.class); + return new String(org.bouncycastle.util.encoders.Base64.encode(spec.getEncoded()), Charset.forName("UTF-8")); + } catch (InvalidKeySpecException e) { + s_logger.error("Unable to create KeyFactory:" + e.getMessage()); + } + return null; + } + + /** + * Decodes base64 encoded public key to PublicKey + * @param publicKey encoded public key string + * @return returns PublicKey + */ + public static PublicKey decodePublicKey(String publicKey) { + byte[] sigBytes = org.bouncycastle.util.encoders.Base64.decode(publicKey); + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes); + KeyFactory keyFactory = CertUtils.getKeyFactory(); + if (keyFactory == null) + return null; + try { + return keyFactory.generatePublic(x509KeySpec); + } catch (InvalidKeySpecException e) { + s_logger.error("Unable to create PrivateKey from privateKey string:" + e.getMessage()); + } + return null; + } + + /** + * Decodes base64 encoded private key to PrivateKey + * @param privateKey encoded private key string + * @return returns PrivateKey + */ + public static PrivateKey decodePrivateKey(String privateKey) { + byte[] sigBytes = org.bouncycastle.util.encoders.Base64.decode(privateKey); + PKCS8EncodedKeySpec pkscs8KeySpec = new PKCS8EncodedKeySpec(sigBytes); + KeyFactory keyFactory = CertUtils.getKeyFactory(); + if (keyFactory == null) + return null; + try { + return keyFactory.generatePrivate(pkscs8KeySpec); + } catch (InvalidKeySpecException e) { + s_logger.error("Unable to create PrivateKey from privateKey string:" + e.getMessage()); + } + return null; + } + + public static X509Certificate generateRandomX509Certificate(KeyPair keyPair) throws NoSuchAlgorithmException, NoSuchProviderException, CertificateException, SignatureException, InvalidKeyException, OperatorCreationException { + return CertUtils.generateV1Certificate(keyPair, + "CN=ApacheCloudStack", "CN=ApacheCloudStack", + 3, "SHA256WithRSA"); + } } diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAMLUtilsTest.java b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAMLUtilsTest.java index 4986d7a2b31..47841347d67 100644 --- a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAMLUtilsTest.java +++ b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAMLUtilsTest.java @@ -64,12 +64,14 @@ public class SAMLUtilsTest extends TestCase { public void testX509Helpers() throws Exception { KeyPair keyPair = CertUtils.generateRandomKeyPair(4096); - String privateKeyString = CertUtils.privateKeyToPem(keyPair.getPrivate()); - String publicKeyString = CertUtils.publicKeyToPem(keyPair.getPublic()); + String privateKeyString = SAMLUtils.encodePrivateKey(keyPair.getPrivate()); + String publicKeyString = SAMLUtils.encodePublicKey(keyPair.getPublic()); - PrivateKey privateKey = CertUtils.pemToPrivateKey(privateKeyString); - PublicKey publicKey = CertUtils.pemToPublicKey(publicKeyString); + PrivateKey privateKey = SAMLUtils.decodePrivateKey(privateKeyString); + PublicKey publicKey = SAMLUtils.decodePublicKey(publicKeyString); + assertNotNull(privateKey); + assertNotNull(publicKey); assertTrue(privateKey.equals(keyPair.getPrivate())); assertTrue(publicKey.equals(keyPair.getPublic())); } diff --git a/ui/index.html b/ui/index.html index b94e8e5ad01..5003f00b369 100644 --- a/ui/index.html +++ b/ui/index.html @@ -1881,7 +1881,6 @@ -