[java-support] branch master updated: OSJ-285: Ensure that Closeable instances are actually closed after use

Brent Putman putmanb at georgetown.edu
Wed Feb 12 23:04:55 EST 2020


This is an automated email from the git hooks/post-receive script.

putmanb pushed a commit to branch master
in repository java-support.

View the commit online:
http://git.shibboleth.net/view/?p=java-support.git;a=commit;h=00062c7b31d1f50419f7debc89ad0e6049e5f5ac

The following commit(s) were added to refs/heads/master by this push:
       new  00062c7   OSJ-285: Ensure that Closeable instances are actually closed after use
00062c7 is described below

commit 00062c7b31d1f50419f7debc89ad0e6049e5f5ac
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Wed Feb 12 23:04:53 2020 -0500

    OSJ-285: Ensure that Closeable instances are actually closed after use
---
 .../java/support/security/DataSealer.java          | 132 +++++++++++----------
 .../security/impl/BasicKeystoreKeyStrategy.java    |  22 ++--
 2 files changed, 79 insertions(+), 75 deletions(-)

diff --git a/src/main/java/net/shibboleth/utilities/java/support/security/DataSealer.java b/src/main/java/net/shibboleth/utilities/java/support/security/DataSealer.java
index 61da28e..7d61a4c 100644
--- a/src/main/java/net/shibboleth/utilities/java/support/security/DataSealer.java
+++ b/src/main/java/net/shibboleth/utilities/java/support/security/DataSealer.java
@@ -204,38 +204,39 @@ public class DataSealer extends AbstractInitializableComponent {
         try {
             final byte[] in = decoder.decode(wrapped.getBytes(StandardCharsets.UTF_8));
 
-            final ByteArrayInputStream inputByteStream = new ByteArrayInputStream(in);
-            final DataInputStream inputDataStream = new DataInputStream(inputByteStream);
-            
-            // Extract alias of key, and load if necessary.
-            final String keyAlias = inputDataStream.readUTF();
-            log.trace("Data was encrypted by key named '{}'", keyAlias);
-            if (keyUsed != null) {
-                keyUsed.append(keyAlias);
+            // Note: we don't technically need try-with-resources here b/c BAIS close() is a no-op
+            // and DIS close() just calls close() on the wrapped stream. But do for consistency.
+            try (final DataInputStream inputDataStream = new DataInputStream(new ByteArrayInputStream(in)) ){
+                // Extract alias of key, and load if necessary.
+                final String keyAlias = inputDataStream.readUTF();
+                log.trace("Data was encrypted by key named '{}'", keyAlias);
+                if (keyUsed != null) {
+                    keyUsed.append(keyAlias);
+                }
+                final SecretKey key = keyStrategy.getKey(keyAlias);
+
+                final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+
+                // Load the IV.
+                final int ivSize = cipher.getBlockSize();
+                final byte[] iv = new byte[ivSize];
+                inputDataStream.readFully(iv);
+
+                final GCMParameterSpec params = new GCMParameterSpec(128, iv);
+                cipher.init(Cipher.DECRYPT_MODE, key, params);
+                cipher.updateAAD(keyAlias.getBytes());
+
+                // Data can't be any bigger than the original minus IV.
+                final byte[] data = new byte[in.length - ivSize];
+                final int dataSize = inputDataStream.read(data);
+
+                final byte[] plaintext = new byte[cipher.getOutputSize(dataSize)];
+                final int outputLen = cipher.update(data, 0, dataSize, plaintext, 0);
+                cipher.doFinal(plaintext, outputLen);
+
+                // Pass the plaintext into the subroutine for processing.
+                return extractAndCheckDecryptedData(plaintext);
             }
-            final SecretKey key = keyStrategy.getKey(keyAlias);
-            
-            final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
-            
-            // Load the IV.
-            final int ivSize = cipher.getBlockSize();
-            final byte[] iv = new byte[ivSize];
-            inputDataStream.readFully(iv);
-            
-            final GCMParameterSpec params = new GCMParameterSpec(128, iv);
-            cipher.init(Cipher.DECRYPT_MODE, key, params);
-            cipher.updateAAD(keyAlias.getBytes());
-            
-            // Data can't be any bigger than the original minus IV.
-            final byte[] data = new byte[in.length - ivSize];
-            final int dataSize = inputDataStream.read(data);
-            
-            final byte[] plaintext = new byte[cipher.getOutputSize(dataSize)];
-            final int outputLen = cipher.update(data, 0, dataSize, plaintext, 0);
-            cipher.doFinal(plaintext, outputLen);
-            
-            // Pass the plaintext into the subroutine for processing.
-            return extractAndCheckDecryptedData(plaintext);
 
         } catch (final KeyNotFoundException e) {
             if (keyUsed != null) {
@@ -264,10 +265,8 @@ public class DataSealer extends AbstractInitializableComponent {
     @Nonnull private String extractAndCheckDecryptedData(@Nonnull @NotEmpty final byte[] decryptedBytes)
             throws DataSealerException {
         
-        try {
-            final ByteArrayInputStream byteStream = new ByteArrayInputStream(decryptedBytes);
-            final GZIPInputStream compressedData = new GZIPInputStream(byteStream);
-            final DataInputStream dataInputStream = new DataInputStream(compressedData);
+        try (final DataInputStream dataInputStream =
+                new DataInputStream(new GZIPInputStream(new ByteArrayInputStream(decryptedBytes)))) {
 
             final long decodedExpirationTime = dataInputStream.readLong();
             if (System.currentTimeMillis() > decodedExpirationTime) {
@@ -332,41 +331,44 @@ public class DataSealer extends AbstractInitializableComponent {
             cipher.init(Cipher.ENCRYPT_MODE, defaultKey.getSecond(), params);
             cipher.updateAAD(defaultKey.getFirst().getBytes());
 
-            final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
-            final GZIPOutputStream compressedStream = new GZIPOutputStream(byteStream);
-            final DataOutputStream dataStream = new DataOutputStream(compressedStream);
+            try (final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+                    final GZIPOutputStream compressedStream = new GZIPOutputStream(byteStream);
+                    final DataOutputStream dataStream = new DataOutputStream(compressedStream)) {
 
-            dataStream.writeLong(exp.toEpochMilli());
-            
-            int count = 0;
-            int start = 0;
-            final int dataLength = data.length();
-            while (start < dataLength) {
-                dataStream.writeUTF(data.substring(start, start + Math.min(dataLength - start, CHUNK_SIZE)));
-                start += Math.min(dataLength - start, CHUNK_SIZE);
-                log.trace("Wrote chunk #{} to output stream", ++count);
-            }
+                dataStream.writeLong(exp.toEpochMilli());
+
+                int count = 0;
+                int start = 0;
+                final int dataLength = data.length();
+                while (start < dataLength) {
+                    dataStream.writeUTF(data.substring(start, start + Math.min(dataLength - start, CHUNK_SIZE)));
+                    start += Math.min(dataLength - start, CHUNK_SIZE);
+                    log.trace("Wrote chunk #{} to output stream", ++count);
+                }
 
-            dataStream.flush();
-            compressedStream.flush();
-            compressedStream.finish();
-            byteStream.flush();
+                dataStream.flush();
+                compressedStream.flush();
+                compressedStream.finish();
+                byteStream.flush();
 
-            final byte[] plaintext = byteStream.toByteArray();
-            
-            final byte[] encryptedData = new byte[cipher.getOutputSize(plaintext.length)];
-            int outputLen = cipher.update(plaintext, 0, plaintext.length, encryptedData, 0);
-            outputLen += cipher.doFinal(encryptedData, outputLen);
+                final byte[] plaintext = byteStream.toByteArray();
 
-            final ByteArrayOutputStream finalByteStream = new ByteArrayOutputStream();
-            final DataOutputStream finalDataStream = new DataOutputStream(finalByteStream);
-            finalDataStream.writeUTF(defaultKey.getFirst());
-            finalDataStream.write(iv);
-            finalDataStream.write(encryptedData, 0, outputLen);
-            finalDataStream.flush();
-            finalByteStream.flush();
+                final byte[] encryptedData = new byte[cipher.getOutputSize(plaintext.length)];
+                int outputLen = cipher.update(plaintext, 0, plaintext.length, encryptedData, 0);
+                outputLen += cipher.doFinal(encryptedData, outputLen);
 
-            return new String(encoder.encode(finalByteStream.toByteArray()), StandardCharsets.UTF_8);
+                try (final ByteArrayOutputStream finalByteStream = new ByteArrayOutputStream();
+                        final DataOutputStream finalDataStream = new DataOutputStream(finalByteStream)) {
+
+                    finalDataStream.writeUTF(defaultKey.getFirst());
+                    finalDataStream.write(iv);
+                    finalDataStream.write(encryptedData, 0, outputLen);
+                    finalDataStream.flush();
+                    finalByteStream.flush();
+
+                    return new String(encoder.encode(finalByteStream.toByteArray()), StandardCharsets.UTF_8);
+                }
+            }
 
         } catch (final Exception e) {
             log.error("Exception wrapping data: {}", e.getMessage());
diff --git a/src/main/java/net/shibboleth/utilities/java/support/security/impl/BasicKeystoreKeyStrategy.java b/src/main/java/net/shibboleth/utilities/java/support/security/impl/BasicKeystoreKeyStrategy.java
index 984d765..b81de3d 100644
--- a/src/main/java/net/shibboleth/utilities/java/support/security/impl/BasicKeystoreKeyStrategy.java
+++ b/src/main/java/net/shibboleth/utilities/java/support/security/impl/BasicKeystoreKeyStrategy.java
@@ -314,17 +314,19 @@ public class BasicKeystoreKeyStrategy extends AbstractInitializableComponent imp
         
         try {
             final KeyStore ks = KeyStore.getInstance(keystoreType);
-            ks.load(keystoreResource.getInputStream(), keystorePassword.toCharArray());
-
-            final Key loadedKey = ks.getKey(name, keyPassword.toCharArray());
-            if (loadedKey == null) {
-                log.info("Key '{}' not found", name);
-                throw new KeyNotFoundException("Key was not present in keystore");
-            } else if (!(loadedKey instanceof SecretKey)) {
-                log.error("Key '{}' is not a symmetric key", name);
-                throw new KeyException("Key was of incorrect type");
+            try (final InputStream ksResourceStream = keystoreResource.getInputStream()) {
+                ks.load(ksResourceStream, keystorePassword.toCharArray());
+
+                final Key loadedKey = ks.getKey(name, keyPassword.toCharArray());
+                if (loadedKey == null) {
+                    log.info("Key '{}' not found", name);
+                    throw new KeyNotFoundException("Key was not present in keystore");
+                } else if (!(loadedKey instanceof SecretKey)) {
+                    log.error("Key '{}' is not a symmetric key", name);
+                    throw new KeyException("Key was of incorrect type");
+                }
+                return (SecretKey) loadedKey;
             }
-            return (SecretKey) loadedKey;
         } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException
                     | IOException | UnrecoverableKeyException e) {
             log.error("Error loading key named '{}': {}", name, e.getMessage());

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list