utils: add methods to save and load public and private keys Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com>
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a66127df Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a66127df Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a66127df Branch: refs/heads/master Commit: a66127dfb12476d098dfbdcc12dbc0beb29c92ee Parents: f144081 Author: Rohit Yadav <rohit.ya...@shapeblue.com> Authored: Fri Sep 12 15:40:49 2014 +0200 Committer: Rohit Yadav <rohit.ya...@shapeblue.com> Committed: Fri Sep 12 15:40:49 2014 +0200 ---------------------------------------------------------------------- .../apache/cloudstack/utils/auth/SAMLUtils.java | 69 ++++++++++++++++++++ .../cloudstack/utils/auth/SAMLUtilsTest.java | 18 +++++ 2 files changed, 87 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a66127df/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java ---------------------------------------------------------------------- diff --git a/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java b/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java index 55c2ee2..82e840a 100644 --- a/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java +++ b/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java @@ -72,17 +72,22 @@ import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.net.URLEncoder; import java.security.InvalidKeyException; +import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; +import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; import java.util.Date; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; @@ -220,6 +225,70 @@ public class SAMLUtils { return URLEncoder.encode(Base64.encodeBytes(signature.sign(), Base64.DONT_BREAK_LINES), HttpUtils.UTF_8); } + public static KeyFactory getKeyFactory() { + KeyFactory keyFactory = null; + try { + Security.addProvider(new BouncyCastleProvider()); + keyFactory = KeyFactory.getInstance("RSA", "BC"); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + s_logger.error("Unable to create KeyFactory:" + e.getMessage()); + } + return keyFactory; + } + + public static String savePublicKey(PublicKey key) { + try { + KeyFactory keyFactory = SAMLUtils.getKeyFactory(); + if (keyFactory == null) return null; + X509EncodedKeySpec spec = keyFactory.getKeySpec(key, X509EncodedKeySpec.class); + return new String(org.bouncycastle.util.encoders.Base64.encode(spec.getEncoded())); + } catch (InvalidKeySpecException e) { + s_logger.error("Unable to create KeyFactory:" + e.getMessage()); + } + return null; + } + + public static String savePrivateKey(PrivateKey key) { + try { + KeyFactory keyFactory = SAMLUtils.getKeyFactory(); + if (keyFactory == null) return null; + PKCS8EncodedKeySpec spec = keyFactory.getKeySpec(key, + PKCS8EncodedKeySpec.class); + return new String(org.bouncycastle.util.encoders.Base64.encode(spec.getEncoded())); + } catch (InvalidKeySpecException e) { + s_logger.error("Unable to create KeyFactory:" + e.getMessage()); + } + return null; + } + + public static PublicKey loadPublicKey(String publicKey) { + byte[] sigBytes = org.bouncycastle.util.encoders.Base64.decode(publicKey); + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes); + KeyFactory keyFact = SAMLUtils.getKeyFactory(); + if (keyFact == null) + return null; + try { + return keyFact.generatePublic(x509KeySpec); + } catch (InvalidKeySpecException e) { + s_logger.error("Unable to create PrivateKey from privateKey string:" + e.getMessage()); + } + return null; + } + + public static PrivateKey loadPrivateKey(String privateKey) { + byte[] sigBytes = org.bouncycastle.util.encoders.Base64.decode(privateKey); + PKCS8EncodedKeySpec pkscs8KeySpec = new PKCS8EncodedKeySpec(sigBytes); + KeyFactory keyFact = SAMLUtils.getKeyFactory(); + if (keyFact == null) + return null; + try { + return keyFact.generatePrivate(pkscs8KeySpec); + } catch (InvalidKeySpecException e) { + s_logger.error("Unable to create PrivateKey from privateKey string:" + e.getMessage()); + } + return null; + } + public static KeyPair generateRandomKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException { Security.addProvider(new BouncyCastleProvider()); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC"); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a66127df/utils/test/org/apache/cloudstack/utils/auth/SAMLUtilsTest.java ---------------------------------------------------------------------- diff --git a/utils/test/org/apache/cloudstack/utils/auth/SAMLUtilsTest.java b/utils/test/org/apache/cloudstack/utils/auth/SAMLUtilsTest.java index f7aaeae..85be2ef 100644 --- a/utils/test/org/apache/cloudstack/utils/auth/SAMLUtilsTest.java +++ b/utils/test/org/apache/cloudstack/utils/auth/SAMLUtilsTest.java @@ -26,6 +26,10 @@ import org.opensaml.saml2.core.LogoutRequest; import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.core.impl.NameIDBuilder; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; + public class SAMLUtilsTest extends TestCase { @Test @@ -64,4 +68,18 @@ public class SAMLUtilsTest extends TestCase { assertEquals(req.getNameID().getValue(), nameIdString); assertEquals(req.getSessionIndexes().get(0).getSessionIndex(), sessionIndex); } + + @Test + public void testX509Helpers() throws Exception { + KeyPair keyPair = SAMLUtils.generateRandomKeyPair(); + + String privateKeyString = SAMLUtils.savePrivateKey(keyPair.getPrivate()); + String publicKeyString = SAMLUtils.savePublicKey(keyPair.getPublic()); + + PrivateKey privateKey = SAMLUtils.loadPrivateKey(privateKeyString); + PublicKey publicKey = SAMLUtils.loadPublicKey(publicKeyString); + + assertTrue(privateKey.equals(keyPair.getPrivate())); + assertTrue(publicKey.equals(keyPair.getPublic())); + } } \ No newline at end of file