Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix javadoc and parameter name and add warning to FHIRUtil.getRandomKey #1394

Merged
merged 2 commits into from
Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions fhir-model/src/main/java/com/ibm/fhir/model/util/FHIRUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public class FHIRUtil {
public static final com.ibm.fhir.model.type.String STRING_DATA_ABSENT_REASON_UNKNOWN = com.ibm.fhir.model.type.String.builder()
.extension(DATA_ABSENT_REASON_UNKNOWN)
.build();
@Deprecated
private static final SecureRandom RANDOM = new SecureRandom();
private static final JsonBuilderFactory BUILDER_FACTORY = Json.createBuilderFactory(null);
private static final Logger log = Logger.getLogger(FHIRUtil.class.getName());
Expand Down Expand Up @@ -570,19 +571,21 @@ public static boolean isFailure(IssueSeverity severity) {
}

/**
* Generate a random AES key or 32 byte value encoded as a Base64 string.
* Generate a random key using the passed algorithm or, if that algorithm isn't supported, a random 32 byte value.
* In either case, the resulting value is encoded as a Base64 string before returning.
*
* @return
* @return a base64-encoded random key string
* @deprecated we plan to remove this from FHIRUtil in a future release
*/
public static String getRandomKey(String key) {
KeyGenerator keyGen;
@Deprecated
public static String getRandomKey(String algorithm) {
try {
keyGen = KeyGenerator.getInstance(key);
KeyGenerator keyGen = KeyGenerator.getInstance(algorithm);
keyGen.init(256);
return Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
} catch (NoSuchAlgorithmException e) {
log.warning("Algorithm '" + algorithm + "' is not supported; using SecureRandom instead");
byte[] buffer = new byte[32];
RANDOM.setSeed(System.currentTimeMillis());
RANDOM.nextBytes(buffer);
return Base64.getEncoder().encodeToString(buffer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.crypto.KeyGenerator;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
Expand Down Expand Up @@ -57,6 +60,7 @@
public class BulkDataClient {
private static final String CLASSNAME = BulkDataClient.class.getName();
private static final Logger log = Logger.getLogger(CLASSNAME);
private static final SecureRandom RANDOM = new SecureRandom();

// @formatter:off
private static final DateTimeFormatter DATE_TIME_PARSER_FORMATTER =
Expand Down Expand Up @@ -182,7 +186,7 @@ public String submitExport(Instant since, List<String> types, Map<String, String

// Use AES to get a long RandomKey to use for the paths so that they cannot be guessed,
// replacing '/' with '_' to avoid potential issues with the S3 API
builder.cosBucketPathPrefix(FHIRUtil.getRandomKey("AES").replaceAll("/", "_"));
builder.cosBucketPathPrefix(getRandomKey("AES").replaceAll("/", "_"));

// Export Type - FHIR
switch (exportType) {
Expand Down Expand Up @@ -616,7 +620,7 @@ public String submitImport(String inputFormat, String inputSource, List<Input> i
builder.fhirStorageType(storageDetail);

// Fetch a string generated from random 32 bytes
builder.cosBucketPathPrefix(FHIRUtil.getRandomKey("AES"));
builder.cosBucketPathPrefix(getRandomKey("AES"));

String fhirTenant = FHIRRequestContext.get().getTenantId();
builder.fhirTenant(fhirTenant);
Expand Down Expand Up @@ -644,4 +648,23 @@ public String submitImport(String inputFormat, String inputSource, List<Input> i
return baseUri + "/$bulkdata-status?job="
+ BulkDataExportUtil.encryptBatchJobId(jobId, BulkDataConstants.BATCHJOBID_ENCRYPTION_KEY);
}

/**
* Generate a random key using the passed algorithm or, if that algorithm isn't supported, a random 32 byte value.
* In either case, the resulting value is encoded as a Base64 string before returning.
*
* @return a base64-encoded random key string
*/
private static String getRandomKey(String algorithm) {
try {
KeyGenerator keyGen = KeyGenerator.getInstance(algorithm);
keyGen.init(256);
return Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
} catch (NoSuchAlgorithmException e) {
log.warning("Algorithm '" + algorithm + "' is not supported; using SecureRandom instead");
byte[] buffer = new byte[32];
RANDOM.nextBytes(buffer);
return Base64.getEncoder().encodeToString(buffer);
}
}
}