[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