Skip to content

Commit f41f8e5

Browse files
test: Add SpotBugs (#35)
* test: Add SpotBugs, minor changes to comply with SpotBugs
1 parent 7668baa commit f41f8e5

16 files changed

+161
-22
lines changed

.github/workflows/ci-test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020
aws-region: us-west-2
2121

2222
- uses: actions/checkout@v3
23+
- name: Run SpotBugs
24+
run: mvn -B -ntp com.github.spotbugs:spotbugs-maven-plugin:check
2325
# run all test cases
2426
- name: Run S3EC Test Cases
2527
run: |

pom.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@
7474
<optional>true</optional>
7575
</dependency>
7676

77+
<dependency>
78+
<groupId>net.jcip</groupId>
79+
<artifactId>jcip-annotations</artifactId>
80+
<version>1.0</version>
81+
<optional>true</optional>
82+
</dependency>
83+
84+
<dependency>
85+
<groupId>com.github.spotbugs</groupId>
86+
<artifactId>spotbugs-annotations</artifactId>
87+
<version>4.7.3</version>
88+
<optional>true</optional>
89+
</dependency>
90+
7791
<!-- Test Dependencies -->
7892
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
7993
<dependency>

src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package software.amazon.encryption.s3;
22

3+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4+
35
import java.security.KeyPair;
46
import java.util.Map;
57
import java.util.function.Consumer;
68
import javax.crypto.SecretKey;
9+
710
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
811
import software.amazon.awssdk.awscore.exception.AwsServiceException;
912
import software.amazon.awssdk.core.exception.SdkClientException;
@@ -122,6 +125,11 @@ public static class Builder {
122125

123126
private Builder() {}
124127

128+
/**
129+
* Note that this does NOT create a defensive clone of S3Client. Any modifications made to the wrapped
130+
* S3Client will be reflected in this Builder.
131+
*/
132+
@SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "Pass mutability into wrapping client")
125133
public Builder wrappedClient(S3Client wrappedClient) {
126134
this._wrappedClient = wrappedClient;
127135
return this;

src/main/java/software/amazon/encryption/s3/internal/BufferedAesGcmContentStrategy.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package software.amazon.encryption.s3.internal;
22

3+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4+
35
import java.io.ByteArrayInputStream;
46
import java.io.IOException;
57
import java.io.InputStream;
68
import java.security.InvalidAlgorithmParameterException;
79
import java.security.InvalidKeyException;
810
import java.security.NoSuchAlgorithmException;
911
import java.security.SecureRandom;
12+
1013
import javax.crypto.BadPaddingException;
1114
import javax.crypto.Cipher;
1215
import javax.crypto.IllegalBlockSizeException;
@@ -27,8 +30,8 @@
2730
public class BufferedAesGcmContentStrategy implements ContentEncryptionStrategy, ContentDecryptionStrategy {
2831

2932
// 64MiB ought to be enough for most usecases
30-
private final long BUFFERED_MAX_CONTENT_LENGTH_MiB = 64;
31-
private final long BUFFERED_MAX_CONTENT_LENGTH_BYTES = 1024 * 1024 * BUFFERED_MAX_CONTENT_LENGTH_MiB;
33+
private static final long BUFFERED_MAX_CONTENT_LENGTH_MiB = 64;
34+
private static final long BUFFERED_MAX_CONTENT_LENGTH_BYTES = 1024 * 1024 * BUFFERED_MAX_CONTENT_LENGTH_MiB;
3235

3336
final private SecureRandom _secureRandom;
3437

@@ -116,6 +119,11 @@ public static class Builder {
116119

117120
private Builder() {}
118121

122+
/**
123+
* Note that this does NOT create a defensive copy of the SecureRandom object. Any modifications to the
124+
* object will be reflected in this Builder.
125+
*/
126+
@SuppressFBWarnings(value = "EI_EXPOSE_REP")
119127
public Builder secureRandom(SecureRandom secureRandom) {
120128
_secureRandom = secureRandom;
121129
return this;

src/main/java/software/amazon/encryption/s3/internal/ContentMetadata.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package software.amazon.encryption.s3.internal;
22

3+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4+
35
import java.util.Collections;
46
import java.util.Map;
7+
58
import software.amazon.encryption.s3.algorithms.AlgorithmSuite;
69
import software.amazon.encryption.s3.materials.EncryptedDataKey;
710

@@ -45,12 +48,21 @@ public String encryptedDataKeyAlgorithm() {
4548
return _encryptedDataKeyAlgorithm;
4649
}
4750

51+
/**
52+
* Note that the underlying implementation uses a Collections.unmodifiableMap which is
53+
* immutable.
54+
*/
55+
@SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "False positive; underlying"
56+
+ " implementation is immutable")
4857
public Map<String, String> encryptedDataKeyContext() {
4958
return _encryptedDataKeyContext;
5059
}
5160

5261
public byte[] contentNonce() {
53-
return _contentNonce;
62+
if (_contentNonce == null) {
63+
return null;
64+
}
65+
return _contentNonce.clone();
5466
}
5567

5668
public String contentCipher() {

src/main/java/software/amazon/encryption/s3/internal/ContentMetadataStrategy.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public PutObjectRequest encodeMetadata(EncryptionMaterials materials,
5656
EncryptedContent encryptedContent, PutObjectRequest request) {
5757
Map<String,String> metadata = new HashMap<>(request.metadata());
5858
EncryptedDataKey edk = materials.encryptedDataKeys().get(0);
59-
metadata.put(MetadataKeyConstants.ENCRYPTED_DATA_KEY_V2, ENCODER.encodeToString(edk.ciphertext()));
59+
metadata.put(MetadataKeyConstants.ENCRYPTED_DATA_KEY_V2, ENCODER.encodeToString(edk.encryptedDatakey()));
6060
metadata.put(MetadataKeyConstants.CONTENT_NONCE, ENCODER.encodeToString(encryptedContent.nonce));
6161
metadata.put(MetadataKeyConstants.CONTENT_CIPHER, materials.algorithmSuite().cipherName());
6262
metadata.put(MetadataKeyConstants.CONTENT_CIPHER_TAG_LENGTH, Integer.toString(materials.algorithmSuite().cipherTagLengthBits()));
@@ -135,7 +135,7 @@ private static ContentMetadata readFromMap(Map<String, String> metadata) {
135135

136136
// Build encrypted data key
137137
EncryptedDataKey edk = EncryptedDataKey.builder()
138-
.ciphertext(edkCiphertext)
138+
.encryptedDataKey(edkCiphertext)
139139
.keyProviderId(keyProviderId)
140140
.keyProviderInfo(keyProviderInfo.getBytes(StandardCharsets.UTF_8))
141141
.build();

src/main/java/software/amazon/encryption/s3/internal/GetEncryptedObjectPipeline.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package software.amazon.encryption.s3.internal;
22

3+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4+
35
import java.io.ByteArrayInputStream;
46
import java.io.IOException;
57
import java.io.InputStream;
@@ -106,6 +108,11 @@ public static class Builder {
106108

107109
private Builder() {}
108110

111+
/**
112+
* Note that this does NOT create a defensive clone of S3Client. Any modifications made to the wrapped
113+
* S3Client will be reflected in this Builder.
114+
*/
115+
@SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "Pass mutability into wrapping client")
109116
public Builder s3Client(S3Client s3Client) {
110117
this._s3Client = s3Client;
111118
return this;

src/main/java/software/amazon/encryption/s3/internal/PutEncryptedObjectPipeline.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package software.amazon.encryption.s3.internal;
22

3+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4+
35
import java.io.IOException;
46

57
import software.amazon.awssdk.core.sync.RequestBody;
@@ -60,6 +62,11 @@ public static class Builder {
6062

6163
private Builder() {}
6264

65+
/**
66+
* Note that this does NOT create a defensive clone of S3Client. Any modifications made to the wrapped
67+
* S3Client will be reflected in this Builder.
68+
*/
69+
@SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "Pass mutability into wrapping client")
6370
public Builder s3Client(S3Client s3Client) {
6471
this._s3Client = s3Client;
6572
return this;

src/main/java/software/amazon/encryption/s3/materials/DecryptMaterialsRequest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package software.amazon.encryption.s3.materials;
22

3+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4+
35
import java.util.Collections;
46
import java.util.List;
57
import java.util.Map;
8+
69
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
710
import software.amazon.encryption.s3.algorithms.AlgorithmSuite;
811

@@ -34,10 +37,22 @@ public AlgorithmSuite algorithmSuite() {
3437
return _algorithmSuite;
3538
}
3639

40+
/**
41+
* Note that the underlying implementation uses a Collections.unmodifiableList which is
42+
* immutable.
43+
*/
44+
@SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "False positive; underlying"
45+
+ " implementation is immutable")
3746
public List<EncryptedDataKey> encryptedDataKeys() {
3847
return _encryptedDataKeys;
3948
}
4049

50+
/**
51+
* Note that the underlying implementation uses a Collections.unmodifiableMap which is
52+
* immutable.
53+
*/
54+
@SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "False positive; underlying"
55+
+ " implementation is immutable")
4156
public Map<String, String> encryptionContext() {
4257
return _encryptionContext;
4358
}

src/main/java/software/amazon/encryption/s3/materials/DecryptionMaterials.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package software.amazon.encryption.s3.materials;
22

3+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4+
35
import java.util.Collections;
46
import java.util.Map;
7+
58
import javax.crypto.SecretKey;
69
import javax.crypto.spec.SecretKeySpec;
10+
711
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
812
import software.amazon.encryption.s3.algorithms.AlgorithmSuite;
913

@@ -43,12 +47,21 @@ public AlgorithmSuite algorithmSuite() {
4347
return _algorithmSuite;
4448
}
4549

50+
/**
51+
* Note that the underlying implementation uses a Collections.unmodifiableMap which is
52+
* immutable.
53+
*/
54+
@SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "False positive; underlying"
55+
+ " implementation is immutable")
4656
public Map<String, String> encryptionContext() {
4757
return _encryptionContext;
4858
}
4959

5060
public byte[] plaintextDataKey() {
51-
return _plaintextDataKey;
61+
if (_plaintextDataKey == null) {
62+
return null;
63+
}
64+
return _plaintextDataKey.clone();
5265
}
5366

5467
public SecretKey dataKey() {

0 commit comments

Comments
 (0)