You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2012/07/19 20:50:15 UTC

svn commit: r1363472 - in /db/derby/code/branches/10.9: ./ java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java

Author: rhillegas
Date: Thu Jul 19 18:50:14 2012
New Revision: 1363472

URL: http://svn.apache.org/viewvc?rev=1363472&view=rev
Log:
DERBY-5622: Port 1356749 from trunk to 10.9 branch.

Modified:
    db/derby/code/branches/10.9/   (props changed)
    db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java

Propchange: db/derby/code/branches/10.9/
------------------------------------------------------------------------------
  Merged /db/derby/code/trunk:r1356749

Modified: db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java?rev=1363472&r1=1363471&r2=1363472&view=diff
==============================================================================
--- db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java (original)
+++ db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java Thu Jul 19 18:50:14 2012
@@ -340,7 +340,7 @@ public final class JCECipherFactory impl
 		// strictly alphanumeric and the number of total possible keys a little
 		// bigger.
 		int IVlen = BLOCK_LENGTH;
-		
+
 		byte[] iv = null;
 		if(cryptoAlgorithmShort.equals(AES))
 		{
@@ -732,8 +732,8 @@ public final class JCECipherFactory impl
 
 		int checkKey = digest(generatedKey);
 
-		if (checkKey != verifyKey)
-			throw StandardException.newException(errorState);
+        if (checkKey != verifyKey)
+        { throw StandardException.newException(errorState); }
 
 		// if encodedKeyLength is not defined, then either it is an old version with no support for different
 		// key sizes and padding except for defaults
@@ -790,9 +790,15 @@ public final class JCECipherFactory impl
 		byte[] IV = generateIV(generatedKey);
 
 		if (!((JCECipherProvider) verify).verifyIV(IV))
-			throw StandardException.newException(SQLState.WRONG_BOOT_PASSWORD);
-
+		{ throw StandardException.newException(SQLState.WRONG_BOOT_PASSWORD); }
 
+        // DERBY-5622:
+        // if we survive those two quick checks, verify that the generated key is still correct
+        // by using it to decrypt something encrypted by the original generated key
+        CipherProvider  newDecrypter = createNewCipher
+            ( DECRYPT, generateKey( generatedKey ), IV );
+        vetCipherProviders( newDecrypter, verify, SQLState.WRONG_BOOT_PASSWORD );
+        
 		// Make the new key.  The generated key is unchanged, only the
 		// encrypted key is changed.
 		String newkey = saveSecretKey(generatedKey, newBPAscii);
@@ -803,6 +809,44 @@ public final class JCECipherFactory impl
 		return saveSecretKey(generatedKey, newBPAscii);
 	}
 
+    /**
+     * <p>
+     * Verify that a decrypter matches an encrypter. Raises an exception if they don't.
+     * The verification is performed by encrypting a block of text and checking that
+     * it decrypts to the same block.
+     * </p>
+     */
+    private void    vetCipherProviders
+        ( CipherProvider decrypter, CipherProvider encrypter, String sqlState )
+        throws StandardException
+    {
+        int     clearTextLength = 1024;
+        int     byteSize = 256;
+        byte[]  clearText = new byte[ clearTextLength ];
+        byte[]  cipherText = new byte[ clearTextLength ];
+        byte[]  unencryptedText = new byte[ clearTextLength ];
+
+        for ( int i = 0; i < clearTextLength; i++ ) { clearText[ i ] = (byte) (i % byteSize); }
+
+        int     bytesEncrypted = encrypter.encrypt
+            ( clearText, 0, clearTextLength, cipherText, 0 );
+        int     bytesDecrypted = decrypter.decrypt
+            ( cipherText, 0, bytesEncrypted, unencryptedText, 0 );
+
+        if ( (bytesEncrypted != clearTextLength) || (bytesDecrypted != clearTextLength) )
+        {
+            throw StandardException.newException( sqlState );
+        }
+
+        for ( int i = 0; i < clearTextLength; i++ )
+        {
+            if ( clearText[ i ] != unencryptedText[ i ] )
+            {
+                throw StandardException.newException( sqlState );
+            }
+        }
+    }
+
 	/**
 	 	perform actions with privileges enabled.
 	 */