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

Use SHA3-512 #1594

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 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
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
import gov.hhs.cdc.trustedintermediary.etor.metadata.partner.PartnerMetadata;
import gov.hhs.cdc.trustedintermediary.etor.metadata.partner.PartnerMetadataMessageType;
import gov.hhs.cdc.trustedintermediary.etor.ruleengine.transformation.TransformationRuleEngine;
import gov.hhs.cdc.trustedintermediary.etor.utils.security.HashHelper;
import gov.hhs.cdc.trustedintermediary.wrappers.Logger;
import gov.hhs.cdc.trustedintermediary.wrappers.MetricMetadata;
import javax.inject.Inject;

/** The overall logic to receive, convert to OML, and subsequently send a lab order. */
public class SendOrderUseCase implements SendMessageUseCase<Order<?>> {
private static final SendOrderUseCase INSTANCE = new SendOrderUseCase();
private final HashHelper hashHelper = new HashHelper();
@Inject TransformationRuleEngine transformationEngine;
@Inject OrderSender sender;
@Inject MetricMetadata metadata;
Expand All @@ -29,10 +31,12 @@ public static SendOrderUseCase getInstance() {
public void convertAndSend(final Order<?> order, String receivedSubmissionId)
throws UnableToSendMessageException {

String hashedOrder = hashHelper.generateHash(order);

PartnerMetadata partnerMetadata =
new PartnerMetadata(
receivedSubmissionId,
String.valueOf(order.hashCode()),
hashedOrder,
PartnerMetadataMessageType.ORDER,
order.getSendingApplicationDetails(),
order.getSendingFacilityDetails(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
import gov.hhs.cdc.trustedintermediary.etor.metadata.partner.PartnerMetadata;
import gov.hhs.cdc.trustedintermediary.etor.metadata.partner.PartnerMetadataMessageType;
import gov.hhs.cdc.trustedintermediary.etor.ruleengine.transformation.TransformationRuleEngine;
import gov.hhs.cdc.trustedintermediary.etor.utils.security.HashHelper;
import gov.hhs.cdc.trustedintermediary.wrappers.Logger;
import javax.inject.Inject;

/** Use case for converting and sending a lab result message. */
public class SendResultUseCase implements SendMessageUseCase<Result<?>> {
private static final SendResultUseCase INSTANCE = new SendResultUseCase();
private final HashHelper hashHelper = new HashHelper();

@Inject TransformationRuleEngine transformationEngine;
@Inject ResultSender sender;
Expand All @@ -30,10 +32,12 @@ public static SendResultUseCase getInstance() {
public void convertAndSend(Result<?> result, String receivedSubmissionId)
throws UnableToSendMessageException {

String hashedResult = hashHelper.generateHash(result);

PartnerMetadata partnerMetadata =
new PartnerMetadata(
receivedSubmissionId,
String.valueOf(result.hashCode()),
hashedResult,
PartnerMetadataMessageType.RESULT,
result.getSendingApplicationDetails(),
result.getSendingFacilityDetails(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package gov.hhs.cdc.trustedintermediary.etor.utils.security;

import gov.hhs.cdc.trustedintermediary.wrappers.Logger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.HexFormat;
import javax.inject.Inject;

public class HashHelper implements SecureHash {
pluckyswan marked this conversation as resolved.
Show resolved Hide resolved
@Inject Logger logger;

@Override
public <T> String generateHash(T input) {
Fixed Show fixed Hide fixed
pluckyswan marked this conversation as resolved.
Show resolved Hide resolved
try {
MessageDigest digest = MessageDigest.getInstance("SHA3-512", "BC");
Fixed Show fixed Hide fixed
byte[] objBytes = input.toString().getBytes(StandardCharsets.UTF_8);
byte[] hashBytes = digest.digest(objBytes);
return HexFormat.of().formatHex(hashBytes);
} catch (NoSuchAlgorithmException e) {
logger.logError("Algorithm does not exist!", e);
throw new RuntimeException(e);
pluckyswan marked this conversation as resolved.
Show resolved Hide resolved
} catch (NoSuchProviderException e) {
logger.logError("Provider does not exist!", e);
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package gov.hhs.cdc.trustedintermediary.etor.utils.security;

import java.security.NoSuchAlgorithmException;

public interface SecureHash {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts about removing this interface? I feel that it could be removed since we aren't using any third-party libraries in the HashHelper implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel too strongly in either case. I think it could potentially be helpful if we wanted to use a third-party library in the future or expand on it.

<T> String generateHash(T hash) throws NoSuchAlgorithmException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package gov.hhs.cdc.trustedintermediary.etor.utils.security
import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext
import gov.hhs.cdc.trustedintermediary.etor.orders.Order
import gov.hhs.cdc.trustedintermediary.etor.results.Result
import gov.hhs.cdc.trustedintermediary.wrappers.Logger
import spock.lang.Specification

class HashHelperTest extends Specification {
def mockLogger = Mock(Logger)
def hashHelper = new HashHelper()

def setup() {
TestApplicationContext.reset()
TestApplicationContext.init()
TestApplicationContext.register(Logger, mockLogger)
TestApplicationContext.injectRegisteredImplementations()
}

def "generateHash generates hash for an order"() {
given:
def mockOrder = Mock(Order)

when:
String mockHash = hashHelper.generateHash(mockOrder)

then:
mockHash !== ""
0 * mockLogger.logError(_, _)
}

def "generateHash generates the same hash for the same object"() {
given:
def mockResult = Mock(Result)
def mockResult2 = mockResult

when:
String mockHash = hashHelper.generateHash(mockResult)
String mockHash2 = hashHelper.generateHash(mockResult2)

then:
mockHash !== ""
mockHash == mockHash2
0 * mockLogger.logError(_, _)
}
}
Loading