diff --git a/core/pom.xml b/core/pom.xml index 76c5c4b5ae..7deabf3752 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -51,8 +51,7 @@ org.bouncycastle - bcprov-jdk16 - 1.46 + bcpkix-jdk15on aopalliance diff --git a/core/src/main/java/org/jclouds/crypto/Pems.java b/core/src/main/java/org/jclouds/crypto/Pems.java index 92ed90b014..607b03c7bf 100644 --- a/core/src/main/java/org/jclouds/crypto/Pems.java +++ b/core/src/main/java/org/jclouds/crypto/Pems.java @@ -18,13 +18,17 @@ */ package org.jclouds.crypto; +import static com.google.common.base.Charsets.US_ASCII; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Throwables.propagate; +import static com.google.common.io.Closeables.closeQuietly; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.StringReader; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; @@ -40,7 +44,7 @@ import java.security.spec.X509EncodedKeySpec; import java.util.Map; import org.bouncycastle.asn1.ASN1OutputStream; -import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure; +import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; import org.jclouds.crypto.Pems.PemProcessor.ResultParser; @@ -52,7 +56,6 @@ import org.jclouds.javax.annotation.Nullable; import com.google.common.annotations.Beta; import com.google.common.base.Joiner; import com.google.common.base.Splitter; -import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; import com.google.common.io.InputSupplier; @@ -89,23 +92,21 @@ public class Pems { @Override public T getResult() { + PemReader reader = new PemReader(new StringReader(new String(out.toByteArray(), US_ASCII))); try { - PemReader reader = new PemReader(new InputStreamReader(new ByteArrayInputStream(out.toByteArray()))); PemObject pem = reader.readPemObject(); byte[] bytes = pem.getContent(); - // Bouncycastle removes the BEGIN and the markers when reading the - // PEM object + // Bouncycastle removes the BEGIN and the markers when reading the PEM object String beginMarker = "-----BEGIN " + pem.getType() + "-----"; - if (parsers.containsKey(beginMarker)) { - return parsers.get(beginMarker).parseResult(bytes); - } else { - throw new IOException(String.format("Invalid PEM file: no parsers for marker %s in %s", beginMarker, - parsers.keySet())); - } + checkState(parsers.containsKey(beginMarker), "Invalid PEM file: no parsers for marker %s in %s", + beginMarker, parsers.keySet()); + return parsers.get(beginMarker).parseResult(bytes); } catch (IOException e) { - throw new RuntimeException(e); + throw propagate(e); + } finally { + closeQuietly(reader); } } } @@ -178,7 +179,7 @@ public class Pems { try { return privateKeySpec(InputSuppliers.of(pem)); } catch (IOException e) { - throw Throwables.propagate(e); + throw propagate(e); } } @@ -327,7 +328,7 @@ public class Pems { // TODO find a way to do this without using bouncycastle public static byte[] getEncoded(RSAPrivateCrtKey key) { - RSAPrivateKeyStructure keyStruct = new RSAPrivateKeyStructure(key.getModulus(), key.getPublicExponent(), + RSAPrivateKey keyStruct = new RSAPrivateKey(key.getModulus(), key.getPublicExponent(), key.getPrivateExponent(), key.getPrimeP(), key.getPrimeQ(), key.getPrimeExponentP(), key.getPrimeExponentQ(), key.getCrtCoefficient()); @@ -338,7 +339,7 @@ public class Pems { aOut.writeObject(keyStruct); aOut.close(); } catch (IOException e) { - Throwables.propagate(e); + throw propagate(e); } return bOut.toByteArray(); diff --git a/core/src/main/java/org/jclouds/crypto/SshKeys.java b/core/src/main/java/org/jclouds/crypto/SshKeys.java index 8c9abc41ce..ab8fa84128 100644 --- a/core/src/main/java/org/jclouds/crypto/SshKeys.java +++ b/core/src/main/java/org/jclouds/crypto/SshKeys.java @@ -51,7 +51,6 @@ import org.jclouds.util.Strings2; import com.google.common.annotations.Beta; import com.google.common.base.Joiner; import com.google.common.base.Splitter; -import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.Iterables; @@ -80,8 +79,7 @@ public class SshKeys { try { return publicKeySpecFromOpenSSH(InputSuppliers.of(idRsaPub)); } catch (IOException e) { - propagate(e); - return null; + throw propagate(e); } } @@ -142,8 +140,7 @@ public class SshKeys { try { return generate(KeyPairGenerator.getInstance("RSA"), new SecureRandom()); } catch (NoSuchAlgorithmException e) { - propagate(e); - return null; + throw propagate(e); } } @@ -167,7 +164,7 @@ public class SshKeys { pemFormatWriter.writeObject(key); pemFormatWriter.close(); } catch (IOException e) { - Throwables.propagate(e); + throw propagate(e); } return stringWriter.toString(); // TODO: understand why pem isn't passing testCanGenerate where keys are @@ -292,11 +289,9 @@ public class SshKeys { .getEncoded())))); return sha1; } catch (InvalidKeySpecException e) { - propagate(e); - return null; + throw propagate(e); } catch (NoSuchAlgorithmException e) { - propagate(e); - return null; + throw propagate(e); } } @@ -340,8 +335,7 @@ public class SshKeys { writeLengthFirst(modulus.toByteArray(), out); return out.toByteArray(); } catch (IOException e) { - propagate(e); - return null; + throw propagate(e); } } diff --git a/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPrivateKeySpec.java b/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPrivateKeySpec.java index ea4557d0cd..e496d92b0c 100644 --- a/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPrivateKeySpec.java +++ b/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPrivateKeySpec.java @@ -24,9 +24,7 @@ import java.math.BigInteger; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPrivateKeySpec; -import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure; +import org.bouncycastle.asn1.pkcs.RSAPrivateKey; /** * PKCS#1 encoded private key spec. @@ -44,7 +42,7 @@ public class PKCS1EncodedPrivateKeySpec { * DER encoded octet stream * @throws IOException */ - public PKCS1EncodedPrivateKeySpec(final byte[] keyBytes) throws IOException { + public PKCS1EncodedPrivateKeySpec(final byte[] keyBytes) { decode(keyBytes); } @@ -63,9 +61,8 @@ public class PKCS1EncodedPrivateKeySpec { * @param keyBytes * Encoded PKCS#1 rsa key. */ - private void decode(final byte[] keyBytes) throws IOException { - ASN1Sequence seq = (ASN1Sequence) ASN1Object.fromByteArray(keyBytes); - RSAPrivateKeyStructure rsa = new RSAPrivateKeyStructure(seq); + private void decode(final byte[] keyBytes) { + RSAPrivateKey rsa = RSAPrivateKey.getInstance(keyBytes); BigInteger mod = rsa.getModulus(); BigInteger pubExp = rsa.getPublicExponent(); diff --git a/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPublicKeySpec.java b/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPublicKeySpec.java index c9f1cf15e8..47ac084718 100644 --- a/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPublicKeySpec.java +++ b/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPublicKeySpec.java @@ -22,9 +22,8 @@ package org.jclouds.crypto.pem; import java.io.IOException; import java.security.spec.RSAPublicKeySpec; -import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.x509.RSAPublicKeyStructure; +import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** @@ -69,18 +68,18 @@ public class PKCS1EncodedPublicKeySpec { * Encoded PKCS#1 rsa key. */ private void decode(final byte[] keyBytes) throws IOException { - RSAPublicKeyStructure pks = null; - ASN1Sequence seq = (ASN1Sequence) ASN1Object.fromByteArray(keyBytes); + RSAPublicKey pks = null; + ASN1Sequence seq = ASN1Sequence.getInstance(keyBytes); try { // Try to parse the public key normally. If the algorithm is not // present in the encoded key, an IllegalArgumentException will be // raised. SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(seq); - pks = new RSAPublicKeyStructure((ASN1Sequence) info.getPublicKey()); + pks = RSAPublicKey.getInstance(info.parsePublicKey()); } catch (IllegalArgumentException ex) { // If the algorithm is not found in the encoded key, try to extract // just the modulus and the public exponent to build the public key. - pks = new RSAPublicKeyStructure(seq); + pks = RSAPublicKey.getInstance(seq); } keySpec = new RSAPublicKeySpec(pks.getModulus(), pks.getPublicExponent()); } diff --git a/core/src/test/java/org/jclouds/crypto/PemsTest.java b/core/src/test/java/org/jclouds/crypto/PemsTest.java index 664eaf89dc..492f9febfe 100644 --- a/core/src/test/java/org/jclouds/crypto/PemsTest.java +++ b/core/src/test/java/org/jclouds/crypto/PemsTest.java @@ -56,12 +56,12 @@ public class PemsTest { private static final String CERTIFICATE = "-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n"; - @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = "^Invalid PEM file: no parsers for marker -----BEGIN FOO PRIVATE KEY----- .*") + @Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "^Invalid PEM file: no parsers for marker -----BEGIN FOO PRIVATE KEY----- .*") public void testPrivateKeySpecFromPemWithInvalidMarker() throws IOException { Pems.privateKeySpec(Payloads.newStringPayload(INVALID_PRIVATE_KEY)); } - @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = "^Invalid PEM file: no parsers for marker -----BEGIN FOO PUBLIC KEY----- .*") + @Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "^Invalid PEM file: no parsers for marker -----BEGIN FOO PUBLIC KEY----- .*") public void testPublicKeySpecFromPemWithInvalidMarker() throws IOException { Pems.publicKeySpec(Payloads.newStringPayload(INVALID_PUBLIC_KEY)); } diff --git a/drivers/bouncycastle/pom.xml b/drivers/bouncycastle/pom.xml index 4b916ba328..29625c3325 100644 --- a/drivers/bouncycastle/pom.xml +++ b/drivers/bouncycastle/pom.xml @@ -63,9 +63,7 @@ org.bouncycastle - bcprov-jdk16 - 1.46 - compile + bcpkix-jdk15on diff --git a/project/pom.xml b/project/pom.xml index 6e86a3c471..eee7c0b7b9 100644 --- a/project/pom.xml +++ b/project/pom.xml @@ -204,6 +204,11 @@ + + org.bouncycastle + bcpkix-jdk15on + 1.47 + com.jcraft jsch @@ -385,6 +390,9 @@ CreateInternetService-options-test.xml .gitattributes OSGI-OPT/bnd.bnd + + META-INF/BCKEY.DSA + META-INF/BCKEY.SF true