diff options
author | Brian Carlstrom <bdc@google.com> | 2013-01-28 18:13:59 -0800 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2013-01-29 14:25:20 -0800 |
commit | aea1f1224e7ad62991b68c485f086abcb289f82b (patch) | |
tree | 0680698559d75d295e856044f26fb9aef64e1b96 /patches | |
parent | 6c392aa76b14c3bc3bab3b0c1209d52febab621a (diff) | |
download | android_external_bouncycastle-aea1f1224e7ad62991b68c485f086abcb289f82b.tar.gz android_external_bouncycastle-aea1f1224e7ad62991b68c485f086abcb289f82b.tar.bz2 android_external_bouncycastle-aea1f1224e7ad62991b68c485f086abcb289f82b.zip |
Restore PBE Cipher wrap and unwrap support from upstream
Bug: https://code.google.com/p/android/issues/detail?id=41405
Change-Id: I9bf90613c510f753032110724b074d31ae76a1fb
Diffstat (limited to 'patches')
-rw-r--r-- | patches/CipherSpi-engineWrap.patch | 303 | ||||
-rw-r--r-- | patches/README | 11 |
2 files changed, 314 insertions, 0 deletions
diff --git a/patches/CipherSpi-engineWrap.patch b/patches/CipherSpi-engineWrap.patch new file mode 100644 index 0000000..1df8688 --- /dev/null +++ b/patches/CipherSpi-engineWrap.patch @@ -0,0 +1,303 @@ +--- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEBlockCipher.java 2012/04/05 10:57:52 1.31 ++++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEBlockCipher.java 2013/01/02 08:01:03 1.32 +@@ -5,9 +5,15 @@ + import java.security.InvalidKeyException; + import java.security.InvalidParameterException; + import java.security.Key; ++import java.security.KeyFactory; + import java.security.NoSuchAlgorithmException; ++import java.security.NoSuchProviderException; ++import java.security.PrivateKey; + import java.security.SecureRandom; + import java.security.spec.AlgorithmParameterSpec; ++import java.security.spec.InvalidKeySpecException; ++import java.security.spec.PKCS8EncodedKeySpec; ++import java.security.spec.X509EncodedKeySpec; + + import javax.crypto.BadPaddingException; + import javax.crypto.Cipher; +@@ -20,9 +26,11 @@ + import javax.crypto.spec.PBEParameterSpec; + // BEGIN android-removed + // import javax.crypto.spec.RC2ParameterSpec; + // import javax.crypto.spec.RC5ParameterSpec; + // END android-removed ++import javax.crypto.spec.SecretKeySpec; + ++import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; + import org.bouncycastle.crypto.BlockCipher; + import org.bouncycastle.crypto.BufferedBlockCipher; + import org.bouncycastle.crypto.CipherParameters; +@@ -739,6 +747,108 @@ + return "CCM".equals(modeName) || "EAX".equals(modeName) || "GCM".equals(modeName); + } + ++ protected byte[] engineWrap( ++ Key key) ++ throws IllegalBlockSizeException, InvalidKeyException ++ { ++ byte[] encoded = key.getEncoded(); ++ if (encoded == null) ++ { ++ throw new InvalidKeyException("Cannot wrap key, null encoding."); ++ } ++ ++ try ++ { ++ return engineDoFinal(encoded, 0, encoded.length); ++ } ++ catch (BadPaddingException e) ++ { ++ throw new IllegalBlockSizeException(e.getMessage()); ++ } ++ } ++ ++ protected Key engineUnwrap( ++ byte[] wrappedKey, ++ String wrappedKeyAlgorithm, ++ int wrappedKeyType) ++ throws InvalidKeyException ++ { ++ byte[] encoded; ++ try ++ { ++ encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); ++ } ++ catch (BadPaddingException e) ++ { ++ throw new InvalidKeyException(e.getMessage()); ++ } ++ catch (IllegalBlockSizeException e2) ++ { ++ throw new InvalidKeyException(e2.getMessage()); ++ } ++ ++ if (wrappedKeyType == Cipher.SECRET_KEY) ++ { ++ return new SecretKeySpec(encoded, wrappedKeyAlgorithm); ++ } ++ else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) ++ { ++ /* ++ * The caller doesn't know the algorithm as it is part of ++ * the encrypted data. ++ */ ++ try ++ { ++ PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); ++ ++ PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); ++ ++ if (privKey != null) ++ { ++ return privKey; ++ } ++ else ++ { ++ throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); ++ } ++ } ++ catch (Exception e) ++ { ++ throw new InvalidKeyException("Invalid key encoding."); ++ } ++ } ++ else ++ { ++ try ++ { ++ KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); ++ ++ if (wrappedKeyType == Cipher.PUBLIC_KEY) ++ { ++ return kf.generatePublic(new X509EncodedKeySpec(encoded)); ++ } ++ else if (wrappedKeyType == Cipher.PRIVATE_KEY) ++ { ++ return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); ++ } ++ } ++ catch (NoSuchProviderException e) ++ { ++ throw new InvalidKeyException("Unknown key type " + e.getMessage()); ++ } ++ catch (NoSuchAlgorithmException e) ++ { ++ throw new InvalidKeyException("Unknown key type " + e.getMessage()); ++ } ++ catch (InvalidKeySpecException e2) ++ { ++ throw new InvalidKeyException("Unknown key type " + e2.getMessage()); ++ } ++ ++ throw new InvalidKeyException("Unknown key type " + wrappedKeyType); ++ } ++ } ++ + /* + * The ciphers that inherit from us. + */ +--- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEStreamCipher.java 2011/08/25 06:17:08 1.15 ++++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEStreamCipher.java 2013/01/29 05:42:31 1.16 +@@ -4,11 +4,20 @@ + import java.security.InvalidAlgorithmParameterException; + import java.security.InvalidKeyException; + import java.security.Key; ++import java.security.KeyFactory; ++import java.security.NoSuchAlgorithmException; ++import java.security.NoSuchProviderException; ++import java.security.PrivateKey; + import java.security.SecureRandom; + import java.security.spec.AlgorithmParameterSpec; ++import java.security.spec.InvalidKeySpecException; ++import java.security.spec.PKCS8EncodedKeySpec; ++import java.security.spec.X509EncodedKeySpec; + ++import javax.crypto.BadPaddingException; + import javax.crypto.Cipher; + import javax.crypto.CipherSpi; ++import javax.crypto.IllegalBlockSizeException; + import javax.crypto.NoSuchPaddingException; + import javax.crypto.SecretKey; + import javax.crypto.ShortBufferException; +@@ -16,9 +25,11 @@ + import javax.crypto.spec.PBEParameterSpec; + // BEGIN android-removed + // import javax.crypto.spec.RC2ParameterSpec; + // import javax.crypto.spec.RC5ParameterSpec; + // END android-removed ++import javax.crypto.spec.SecretKeySpec; + ++import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; + import org.bouncycastle.crypto.BlockCipher; + import org.bouncycastle.crypto.CipherParameters; + import org.bouncycastle.crypto.DataLengthException; +@@ -339,7 +350,8 @@ + protected byte[] engineDoFinal( + byte[] input, + int inputOffset, +- int inputLen) ++ int inputLen) ++ throws BadPaddingException, IllegalBlockSizeException + { + if (inputLen != 0) + { +@@ -360,7 +372,8 @@ + int inputOffset, + int inputLen, + byte[] output, +- int outputOffset) ++ int outputOffset) ++ throws BadPaddingException + { + if (inputLen != 0) + { +@@ -372,6 +385,108 @@ + return inputLen; + } + ++ protected byte[] engineWrap( ++ Key key) ++ throws IllegalBlockSizeException, InvalidKeyException ++ { ++ byte[] encoded = key.getEncoded(); ++ if (encoded == null) ++ { ++ throw new InvalidKeyException("Cannot wrap key, null encoding."); ++ } ++ ++ try ++ { ++ return engineDoFinal(encoded, 0, encoded.length); ++ } ++ catch (BadPaddingException e) ++ { ++ throw new IllegalBlockSizeException(e.getMessage()); ++ } ++ } ++ ++ protected Key engineUnwrap( ++ byte[] wrappedKey, ++ String wrappedKeyAlgorithm, ++ int wrappedKeyType) ++ throws InvalidKeyException ++ { ++ byte[] encoded; ++ try ++ { ++ encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); ++ } ++ catch (BadPaddingException e) ++ { ++ throw new InvalidKeyException(e.getMessage()); ++ } ++ catch (IllegalBlockSizeException e2) ++ { ++ throw new InvalidKeyException(e2.getMessage()); ++ } ++ ++ if (wrappedKeyType == Cipher.SECRET_KEY) ++ { ++ return new SecretKeySpec(encoded, wrappedKeyAlgorithm); ++ } ++ else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) ++ { ++ /* ++ * The caller doesn't know the algorithm as it is part of ++ * the encrypted data. ++ */ ++ try ++ { ++ PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); ++ ++ PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); ++ ++ if (privKey != null) ++ { ++ return privKey; ++ } ++ else ++ { ++ throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); ++ } ++ } ++ catch (Exception e) ++ { ++ throw new InvalidKeyException("Invalid key encoding."); ++ } ++ } ++ else ++ { ++ try ++ { ++ KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); ++ ++ if (wrappedKeyType == Cipher.PUBLIC_KEY) ++ { ++ return kf.generatePublic(new X509EncodedKeySpec(encoded)); ++ } ++ else if (wrappedKeyType == Cipher.PRIVATE_KEY) ++ { ++ return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); ++ } ++ } ++ catch (NoSuchProviderException e) ++ { ++ throw new InvalidKeyException("Unknown key type " + e.getMessage()); ++ } ++ catch (NoSuchAlgorithmException e) ++ { ++ throw new InvalidKeyException("Unknown key type " + e.getMessage()); ++ } ++ catch (InvalidKeySpecException e2) ++ { ++ throw new InvalidKeyException("Unknown key type " + e2.getMessage()); ++ } ++ ++ throw new InvalidKeyException("Unknown key type " + wrappedKeyType); ++ } ++ } ++ + /* + * The ciphers that inherit from us. + */ diff --git a/patches/README b/patches/README index 0caaea9..b9c9181 100644 --- a/patches/README +++ b/patches/README @@ -48,3 +48,14 @@ patch against Bouncy Castle's bcpkix: The main differences involve: - removing algorithms not in our bcprov (MD2, MD4, SHA224, RIPEMD, GOST) - using the singleton DERNull.INSTANCE + + +CipherSpi-engineWrap.patch: + +Fixes from upstream BouncyCastle repository for: + https://code.google.com/p/android/issues/detail?id=41405 + +"added wrap/unwrap support back in." + http://www.bouncycastle.org/viewcvs/viewcvs.cgi/java/crypto/src/org/bouncycastle/jce/provider/JCEBlockCipher.java?r1=1.31&r2=1.32&view=patch +"fix for JCEStreamCipher PBE wrapping" + http://www.bouncycastle.org/viewcvs/viewcvs.cgi/java/crypto/src/org/bouncycastle/jce/provider/JCEStreamCipher.java?r1=1.15&r2=1.16&view=patch |