From e88f1e6d6d3cf5605d526ee3c1f6378a024cb7b2 Mon Sep 17 00:00:00 2001 From: sujan kota Date: Tue, 17 Dec 2024 09:03:53 -0500 Subject: [PATCH] fix assertion hash --- .../io/opentdf/platform/sdk/Manifest.java | 5 ++-- .../java/io/opentdf/platform/sdk/TDF.java | 26 ++++++++----------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java b/sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java index 39a495f9..12e5f8a7 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java @@ -23,6 +23,7 @@ import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; import io.opentdf.platform.sdk.TDF.AssertionException; +import org.apache.commons.codec.binary.Hex; import org.erdtman.jcs.JsonCanonicalizer; import java.io.IOException; @@ -351,7 +352,7 @@ public int hashCode() { return Objects.hash(id, type, scope, appliesToState, statement, binding); } - public byte[] hash() throws IOException { + public String hash() throws IOException { MessageDigest digest; try { digest = MessageDigest.getInstance("SHA-256"); @@ -361,7 +362,7 @@ public byte[] hash() throws IOException { var assertionAsJson = gson.toJson(this); JsonCanonicalizer jc = new JsonCanonicalizer(assertionAsJson); - return digest.digest(jc.getEncodedUTF8()); + return Hex.encodeHexString(digest.digest(jc.getEncodedUTF8())); } // Sign the assertion with the given hash and signature using the key. diff --git a/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java b/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java index f1582488..f5e87083 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java @@ -417,7 +417,7 @@ private static byte[] calculateSignature(byte[] data, byte[] secret, Config.Inte public TDFObject createTDF(InputStream payload, OutputStream outputStream, Config.TDFConfig tdfConfig, SDK.KAS kas, AttributesServiceFutureStub attrService) - throws IOException, JOSEException, AutoConfigureException, InterruptedException, ExecutionException { + throws IOException, JOSEException, AutoConfigureException, InterruptedException, ExecutionException, DecoderException { if (tdfConfig.autoconfigure) { Autoconfigure.Granter granter = new Autoconfigure.Granter(new ArrayList<>()); @@ -532,7 +532,8 @@ public TDFObject createTDF(InputStream payload, assertion.statement = assertionConfig.statement; assertion.appliesToState = assertionConfig.appliesToState.toString(); - var assertionHash = assertion.hash(); + var assertionHashAsHex = assertion.hash(); + var assertionHash = Hex.decodeHex(assertionHashAsHex); byte[] completeHash = new byte[aggregateHash.size() + assertionHash.length]; System.arraycopy(aggregateHash.toByteArray(), 0, completeHash, 0, aggregateHash.size()); System.arraycopy(assertionHash, 0, completeHash, aggregateHash.size(), assertionHash.length); @@ -545,7 +546,7 @@ public TDFObject createTDF(InputStream payload, assertionSigningKey = assertionConfig.assertionKey; } var hashValues = new Manifest.Assertion.HashValues( - Base64.getEncoder().encodeToString(assertionHash), + assertionHashAsHex, encodedHash ); assertion.sign(hashValues, assertionSigningKey); @@ -707,7 +708,7 @@ public Reader loadTDF(SeekableByteChannel tdf, SDK.KAS kas, throw new SegmentSizeMismatch("mismatch encrypted segment size in manifest"); } - var aggregateSignatureBytes = aggregateHash.toByteArray(); + var aggregateHashByteArrayBytes = aggregateHash.toByteArray(); // Validate assertions for (var assertion : manifest.assertions) { // Skip assertion verification if disabled @@ -726,22 +727,17 @@ public Reader loadTDF(SeekableByteChannel tdf, SDK.KAS kas, } var hashValues = assertion.verify(assertionKey); - var assertionAsJson = gson.toJson(assertion); - JsonCanonicalizer jc = new JsonCanonicalizer(assertionAsJson); - var hashOfAssertion = digest.digest(jc.getEncodedUTF8()); - var assertionCompare = isLegacyTdf ? Hex.encodeHexString(hashOfAssertion) : Base64.getEncoder().encodeToString(hashOfAssertion); + var hashOfAssertionAsHex = assertion.hash(); - if (!Objects.equals(assertionCompare, hashValues.getAssertionHash())) { + if (!Objects.equals(hashOfAssertionAsHex, hashValues.getAssertionHash())) { throw new AssertionException("assertion hash mismatch", assertion.id); } - if (isLegacyTdf) { - hashOfAssertion = Hex.encodeHexString(hashOfAssertion).getBytes(); - } + var hashOfAssertion = Hex.decodeHex(hashOfAssertionAsHex); - var signature = new byte[aggregateSignatureBytes.length + hashOfAssertion.length]; - System.arraycopy(aggregateSignatureBytes, 0, signature, 0, aggregateSignatureBytes.length); - System.arraycopy(hashOfAssertion, 0, signature, aggregateSignatureBytes.length, hashOfAssertion.length); + var signature = new byte[aggregateHashByteArrayBytes.length + hashOfAssertion.length]; + System.arraycopy(aggregateHashByteArrayBytes, 0, signature, 0, aggregateHashByteArrayBytes.length); + System.arraycopy(hashOfAssertion, 0, signature, aggregateHashByteArrayBytes.length, hashOfAssertion.length); var encodeSignature = Base64.getEncoder().encodeToString(signature); if (!Objects.equals(encodeSignature, hashValues.getSignature())) {