Skip to content

Commit

Permalink
Fix checkpoint signature verification
Browse files Browse the repository at this point in the history
Signed-off-by: Appu Goundan <appu@google.com>
  • Loading branch information
loosebazooka committed Dec 3, 2024
1 parent f20f4db commit d2e8a8d
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 4 deletions.
4 changes: 2 additions & 2 deletions fuzzing/src/main/java/fuzzing/SignerVerifierFuzzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public static void fuzzerTestOneInput(FuzzedDataProvider data) {
byte[] signature1 = signer.sign(byteArray);
byte[] signature2 = signer.signDigest(byteArray);

verifier.verify(byteArray, signature1);
verifier.verifyDigest(byteArray, signature2);
var unused1 = verifier.verify(byteArray, signature1);
var unused2 = verifier.verifyDigest(byteArray, signature2);
} catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException e) {
// Known exception
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package dev.sigstore.encryption.signers;

import java.security.*;
import javax.annotation.CheckReturnValue;

/** A verifier helper that wraps common verification operations for use within this library. */
public interface Verifier {
Expand All @@ -30,6 +31,7 @@ public interface Verifier {
* @param signature the signature associated with the artifact
* @return true if the signature is valid, false otherwise
*/
@CheckReturnValue
boolean verify(byte[] artifact, byte[] signature)
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException;

Expand All @@ -41,6 +43,7 @@ boolean verify(byte[] artifact, byte[] signature)
* @param signature the signature associated with the artifact
* @return true if the signature is valid, false otherwise
*/
@CheckReturnValue
boolean verifyDigest(byte[] artifactDigest, byte[] signature)
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static Checkpoint from(String encoded) throws RekorParseException {
}

return ImmutableCheckpoint.builder()
.signedData(header + "\n")
.origin(origin)
.size(size)
.base64Hash(base64Hash)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ default Checkpoint parsedCheckpoint() throws RekorParseException {

@Value.Immutable
interface Checkpoint {
/** Signed portion of checkpoint. */
String getSignedData();

/** Unique identity for the log. */
String getOrigin();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import dev.sigstore.rekor.client.RekorEntry.Checkpoint;
import dev.sigstore.trustroot.SigstoreTrustedRoot;
import dev.sigstore.trustroot.TransparencyLog;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
Expand Down Expand Up @@ -163,9 +164,12 @@ private void verifyCheckpoint(RekorEntry entry, TransparencyLog tlog)
"Checkpoint key hint did not match provided log public key");
}
}
var signedData = checkpoint.getSignedData();
try {
Verifiers.newVerifier(tlog.getPublicKey().toJavaPublicKey())
.verifyDigest(inclusionRootHash, sig.getSignature());
if (!Verifiers.newVerifier(tlog.getPublicKey().toJavaPublicKey())
.verify(signedData.getBytes(StandardCharsets.UTF_8), sig.getSignature())) {
throw new RekorVerificationException("Checkpoint signature was invalid");
}
} catch (NoSuchAlgorithmException
| InvalidKeySpecException
| SignatureException
Expand Down
19 changes: 19 additions & 0 deletions sigstore-java/src/test/java/dev/sigstore/KeylessVerifierTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,25 @@ public void testVerify_mismatchedArtifactHash() throws Exception {
VerificationOptions.empty()));
}

@Test
public void testVerify_badCheckpointSignature() throws Exception {
var bundleFile =
Resources.toString(
Resources.getResource(
"dev/sigstore/samples/bundles/bundle-with-bad-checkpoint-signature.sigstore"),
StandardCharsets.UTF_8);
var artifact = Resources.getResource("dev/sigstore/samples/bundles/artifact.txt").getPath();

var verifier = KeylessVerifier.builder().sigstorePublicDefaults().build();
Assertions.assertThrows(
KeylessVerificationException.class,
() ->
verifier.verify(
Path.of(artifact),
Bundle.from(new StringReader(bundleFile)),
VerificationOptions.empty()));
}

@Test
public void testVerify_errorsOnDSSEBundle() throws Exception {
var bundleFile =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1", "verificationMaterial": {"x509CertificateChain": {"certificates": [{"rawBytes": "MIIIGTCCB5+gAwIBAgIUBPWs4OPN1kte0mUMGZrZ6ozMVRkwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwNzEyMTU1NjM1WhcNMjMwNzEyMTYwNjM1WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVr33uVAPA1SpA5w/mmBF9ariW8E7oizIQKqiYfxwSb1zftqZZX045y3tPbRkIWe+t7MUYliQknQ954rDDEASnKOCBr4wgga6MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUx2TNZkruHC2aCdyIXscI8N/8q2owHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wgaUGA1UdEQEB/wSBmjCBl4aBlGh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi8uZ2l0aHViL3dvcmtmbG93cy9leHRyZW1lbHktZGFuZ2Vyb3VzLW9pZGMtYmVhY29uLnltbEByZWZzL2hlYWRzL21haW4wOQYKKwYBBAGDvzABAQQraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTAfBgorBgEEAYO/MAECBBF3b3JrZmxvd19kaXNwYXRjaDA2BgorBgEEAYO/MAEDBChhZjc4NWI2ZDNiMGZhMGMwYWExMzA1ZmFlZTdjZTYwMzZlOGQ5MGM0MC0GCisGAQQBg78wAQQEH0V4dHJlbWVseSBkYW5nZXJvdXMgT0lEQyBiZWFjb24wSQYKKwYBBAGDvzABBQQ7c2lnc3RvcmUtY29uZm9ybWFuY2UvZXh0cmVtZWx5LWRhbmdlcm91cy1wdWJsaWMtb2lkYy1iZWFjb24wHQYKKwYBBAGDvzABBgQPcmVmcy9oZWFkcy9tYWluMDsGCisGAQQBg78wAQgELQwraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTCBpgYKKwYBBAGDvzABCQSBlwyBlGh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi8uZ2l0aHViL3dvcmtmbG93cy9leHRyZW1lbHktZGFuZ2Vyb3VzLW9pZGMtYmVhY29uLnltbEByZWZzL2hlYWRzL21haW4wOAYKKwYBBAGDvzABCgQqDChhZjc4NWI2ZDNiMGZhMGMwYWExMzA1ZmFlZTdjZTYwMzZlOGQ5MGM0MB0GCisGAQQBg78wAQsEDwwNZ2l0aHViLWhvc3RlZDBeBgorBgEEAYO/MAEMBFAMTmh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbjA4BgorBgEEAYO/MAENBCoMKGFmNzg1YjZkM2IwZmEwYzBhYTEzMDVmYWVlN2NlNjAzNmU4ZDkwYzQwHwYKKwYBBAGDvzABDgQRDA9yZWZzL2hlYWRzL21haW4wGQYKKwYBBAGDvzABDwQLDAk2MzI1OTY4OTcwNwYKKwYBBAGDvzABEAQpDCdodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUtY29uZm9ybWFuY2UwGQYKKwYBBAGDvzABEQQLDAkxMzE4MDQ1NjMwgaYGCisGAQQBg78wARIEgZcMgZRodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUtY29uZm9ybWFuY2UvZXh0cmVtZWx5LWRhbmdlcm91cy1wdWJsaWMtb2lkYy1iZWFjb24vLmdpdGh1Yi93b3JrZmxvd3MvZXh0cmVtZWx5LWRhbmdlcm91cy1vaWRjLWJlYWNvbi55bWxAcmVmcy9oZWFkcy9tYWluMDgGCisGAQQBg78wARMEKgwoYWY3ODViNmQzYjBmYTBjMGFhMTMwNWZhZWU3Y2U2MDM2ZThkOTBjNDAhBgorBgEEAYO/MAEUBBMMEXdvcmtmbG93X2Rpc3BhdGNoMIGBBgorBgEEAYO/MAEVBHMMcWh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi9hY3Rpb25zL3J1bnMvNTUzMzc0MTQ5Ny9hdHRlbXB0cy8xMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGJStGTCwAABAMARzBFAiBCA4jZQP4CwMiWoeS7WMW46QkI4e7OsNH3yVhf5wdBvgIhAPJYxdsi9NqOXVZsEUtCup8m1m/2zG39FTGlgE0MorDFMAoGCCqGSM49BAMDA2gAMGUCMEYWRwI5QJeOwNCuV4tnZ0n5QNlUlP0BtX5V2ZTQLqcQbWtneC7tLptiYgr0Z62UDQIxAO6ItXAH+sbZcsbj08xr3GApM6hjvyTAl39pS3Y3sZwAz8lfQDHNL4eALEo1heAYVg=="}]}, "tlogEntries": [{"logIndex": "27246492", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1689177396", "inclusionPromise": {"signedEntryTimestamp": "MEUCIQCvkqgP1sCP3BiNYQ+36o79yGXZP5CNeo7OmpmVT6kehgIgegEh0UlZwjMj2KEi/X0nm9cyq+vuG8uOGqG4i//nqgM="}, "inclusionProof": {"logIndex": "23083061", "rootHash": "dauhleYK4YyAdxwwDtR0l0KnSOWZdG2bwqHftlanvcI=", "treeSize": "23083062", "hashes": ["/vK4Da3g7ZhRgme8FxCi8QIBL7DSlwpSwyERyIV+uS8=", "k9N2htTx+7tA55tT0tiB/BO4uqaqSxqTV34ouZgCBWk=", "/ArdEa96pCZQOyrxyKhOHxd2HHEsXBldxS8p23CNIkk=", "5GQbI53IAmYSDjLtEjG0PNzp0hk2+W/eEkCbJlNqTKc=", "O86OnjaE1s+pcHWna1/xdeZ7ubCXgVmtV1f7nWlWYLI=", "Hj0TEef/bwMHB10DPoFLu5+RSLTGJ5YRaQWqwwVIp0s=", "aRtyVlt3GYDP4qaYrEAWqiGqcYDELxyk7Fl3icGXOoA=", "ZdynT2d4F3NFQNBurFDaZBoYMVRjbQjlTnSL1hL67+s=", "3VHoQOiS1wCTrX4dseLeo9UDNMc0XTYORE0i/Entn14=", "rXEsmEJN4PEoTU8US4qVtdIsGB1MCiRlGOepoiC99kM="], "checkpoint": {"envelope": "rekor.sigstore.dev - 2605736670972794746\n23083062\ndauhleYK4YyAdxwwDtR0l0KnSOWZdG2bwqHftlanvcI=\nTimestamp: 1689177396617352539\n\n\u2014 rekor.sigstore.dev wNI9ajBFAiBxaGyEtxkzZLkaCSEJqFuSS3dJjEZCNiyByVs1CNVQ8gIhAOoNnXtmMtTctV2oRnSRUZAo4EWUYPK/vBsqOzAU6TMs\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJhMGNmYzcxMjcxZDZlMjc4ZTU3Y2QzMzJmZjk1N2MzZjcwNDNmZGRhMzU0YzRjYmIxOTBhMzBkNTZlZmEwMWJmIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJRk9wYVhLV3Z2QkR3VGhEalRIWDd0RkY4bGlSb1N4TFpJc1Nlb1VNLzZENEFpQnhWOS9SblRNTXcxdDZubmlYMHJDdXdyZjhWaCtmZUxGdTk5bTRpciszeUE9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVbEhWRU5EUWpVclowRjNTVUpCWjBsVlFsQlhjelJQVUU0eGEzUmxNRzFWVFVkYWNsbzJiM3BOVmxKcmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcE5kMDU2UlhsTlZGVXhUbXBOTVZkb1kwNU5hazEzVG5wRmVVMVVXWGRPYWsweFYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZXY2pNemRWWkJVRUV4VTNCQk5YY3ZiVzFDUmpsaGNtbFhPRVUzYjJsNlNWRkxjV2tLV1daNGQxTmlNWHBtZEhGYVdsZ3dORFY1TTNSUVlsSnJTVmRsSzNRM1RWVlpiR2xSYTI1Uk9UVTBja1JFUlVGVGJrdFBRMEp5TkhkbloyRTJUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlY0TWxST0NscHJjblZJUXpKaFEyUjVTVmh6WTBrNFRpODRjVEp2ZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDJkaFZVZEJNVlZrUlZGRlFpOTNVMEp0YWtOQ2JEUmhRbXhIYURCa1NFSjZUMms0ZGxveWJEQmhTRlpwVEcxT2RtSlRPWHBoVjJSNlpFYzVlUXBhVXpGcVlqSTFiV0l6U25SWlZ6VnFXbE01YkdWSVVubGFWekZzWWtocmRGcEhSblZhTWxaNVlqTldla3hZUWpGWmJYaHdXWGt4ZG1GWFVtcE1WMHBzQ2xsWFRuWmlhVGgxV2pKc01HRklWbWxNTTJSMlkyMTBiV0pIT1ROamVUbHNaVWhTZVZwWE1XeGlTR3QwV2tkR2RWb3lWbmxpTTFaNlRGYzVjRnBIVFhRS1dXMVdhRmt5T1hWTWJteDBZa1ZDZVZwWFducE1NbWhzV1ZkU2Vrd3lNV2hoVnpSM1QxRlpTMHQzV1VKQ1FVZEVkbnBCUWtGUlVYSmhTRkl3WTBoTk5ncE1lVGt3WWpKMGJHSnBOV2haTTFKd1lqSTFla3h0WkhCa1IyZ3hXVzVXZWxwWVNtcGlNalV3V2xjMU1FeHRUblppVkVGbVFtZHZja0puUlVWQldVOHZDazFCUlVOQ1FrWXpZak5LY2xwdGVIWmtNVGxyWVZoT2QxbFlVbXBoUkVFeVFtZHZja0puUlVWQldVOHZUVUZGUkVKRGFHaGFhbU0wVGxkSk1scEVUbWtLVFVkYWFFMUhUWGRaVjBWNFRYcEJNVnB0Um14YVZHUnFXbFJaZDAxNldteFBSMUUxVFVkTk1FMURNRWREYVhOSFFWRlJRbWMzT0hkQlVWRkZTREJXTkFwa1NFcHNZbGRXYzJWVFFtdFpWelZ1V2xoS2RtUllUV2RVTUd4RlVYbENhVnBYUm1waU1qUjNVMUZaUzB0M1dVSkNRVWRFZG5wQlFrSlJVVGRqTW14dUNtTXpVblpqYlZWMFdUSTVkVnB0T1hsaVYwWjFXVEpWZGxwWWFEQmpiVlowV2xkNE5VeFhVbWhpYldSc1kyMDVNV041TVhka1YwcHpZVmROZEdJeWJHc0tXWGt4YVZwWFJtcGlNalIzU0ZGWlMwdDNXVUpDUVVkRWRucEJRa0puVVZCamJWWnRZM2s1YjFwWFJtdGplVGwwV1Zkc2RVMUVjMGREYVhOSFFWRlJRZ3BuTnpoM1FWRm5SVXhSZDNKaFNGSXdZMGhOTmt4NU9UQmlNblJzWW1rMWFGa3pVbkJpTWpWNlRHMWtjR1JIYURGWmJsWjZXbGhLYW1JeU5UQmFWelV3Q2t4dFRuWmlWRU5DY0dkWlMwdDNXVUpDUVVkRWRucEJRa05SVTBKc2QzbENiRWRvTUdSSVFucFBhVGgyV2pKc01HRklWbWxNYlU1MllsTTVlbUZYWkhvS1pFYzVlVnBUTVdwaU1qVnRZak5LZEZsWE5XcGFVemxzWlVoU2VWcFhNV3hpU0d0MFdrZEdkVm95Vm5saU0xWjZURmhDTVZsdGVIQlplVEYyWVZkU2FncE1WMHBzV1ZkT2RtSnBPSFZhTW13d1lVaFdhVXd6WkhaamJYUnRZa2M1TTJONU9XeGxTRko1V2xjeGJHSklhM1JhUjBaMVdqSldlV0l6Vm5wTVZ6bHdDbHBIVFhSWmJWWm9XVEk1ZFV4dWJIUmlSVUo1V2xkYWVrd3lhR3haVjFKNlRESXhhR0ZYTkhkUFFWbExTM2RaUWtKQlIwUjJla0ZDUTJkUmNVUkRhR2dLV21wak5FNVhTVEphUkU1cFRVZGFhRTFIVFhkWlYwVjRUWHBCTVZwdFJteGFWR1JxV2xSWmQwMTZXbXhQUjFFMVRVZE5NRTFDTUVkRGFYTkhRVkZSUWdwbk56aDNRVkZ6UlVSM2QwNWFNbXd3WVVoV2FVeFhhSFpqTTFKc1drUkNaVUpuYjNKQ1owVkZRVmxQTDAxQlJVMUNSa0ZOVkcxb01HUklRbnBQYVRoMkNsb3liREJoU0ZacFRHMU9kbUpUT1hwaFYyUjZaRWM1ZVZwVE1XcGlNalZ0WWpOS2RGbFhOV3BhVXpsc1pVaFNlVnBYTVd4aVNHdDBXa2RHZFZveVZua0tZak5XZWt4WVFqRlpiWGh3V1hreGRtRlhVbXBNVjBwc1dWZE9kbUpxUVRSQ1oyOXlRbWRGUlVGWlR5OU5RVVZPUWtOdlRVdEhSbTFPZW1jeFdXcGFhd3BOTWtsM1dtMUZkMWw2UW1oWlZFVjZUVVJXYlZsWFZteE9NazVzVG1wQmVrNXRWVFJhUkd0M1dYcFJkMGgzV1V0TGQxbENRa0ZIUkhaNlFVSkVaMUZTQ2tSQk9YbGFWMXA2VERKb2JGbFhVbnBNTWpGb1lWYzBkMGRSV1V0TGQxbENRa0ZIUkhaNlFVSkVkMUZNUkVGck1rMTZTVEZQVkZrMFQxUmpkMDUzV1VzS1MzZFpRa0pCUjBSMmVrRkNSVUZSY0VSRFpHOWtTRkozWTNwdmRrd3laSEJrUjJneFdXazFhbUl5TUhaak1teHVZek5TZG1OdFZYUlpNamwxV20wNWVRcGlWMFoxV1RKVmQwZFJXVXRMZDFsQ1FrRkhSSFo2UVVKRlVWRk1SRUZyZUUxNlJUUk5SRkV4VG1wTmQyZGhXVWREYVhOSFFWRlJRbWMzT0hkQlVrbEZDbWRhWTAxbldsSnZaRWhTZDJONmIzWk1NbVJ3WkVkb01WbHBOV3BpTWpCMll6SnNibU16VW5aamJWVjBXVEk1ZFZwdE9YbGlWMFoxV1RKVmRscFlhREFLWTIxV2RGcFhlRFZNVjFKb1ltMWtiR050T1RGamVURjNaRmRLYzJGWFRYUmlNbXhyV1hreGFWcFhSbXBpTWpSMlRHMWtjR1JIYURGWmFUa3pZak5LY2dwYWJYaDJaRE5OZGxwWWFEQmpiVlowV2xkNE5VeFhVbWhpYldSc1kyMDVNV041TVhaaFYxSnFURmRLYkZsWFRuWmlhVFUxWWxkNFFXTnRWbTFqZVRsdkNscFhSbXRqZVRsMFdWZHNkVTFFWjBkRGFYTkhRVkZSUW1jM09IZEJVazFGUzJkM2IxbFhXVE5QUkZacFRtMVJlbGxxUW0xWlZFSnFUVWRHYUUxVVRYY0tUbGRhYUZwWFZUTlpNbFV5VFVSTk1scFVhR3RQVkVKcVRrUkJhRUpuYjNKQ1owVkZRVmxQTDAxQlJWVkNRazFOUlZoa2RtTnRkRzFpUnpreldESlNjQXBqTTBKb1pFZE9iMDFKUjBKQ1oyOXlRbWRGUlVGWlR5OU5RVVZXUWtoTlRXTlhhREJrU0VKNlQyazRkbG95YkRCaFNGWnBURzFPZG1KVE9YcGhWMlI2Q21SSE9YbGFVekZxWWpJMWJXSXpTblJaVnpWcVdsTTViR1ZJVW5sYVZ6RnNZa2hyZEZwSFJuVmFNbFo1WWpOV2VreFlRakZaYlhod1dYa3hkbUZYVW1vS1RGZEtiRmxYVG5aaWFUbG9XVE5TY0dJeU5YcE1NMG94WW01TmRrNVVWWHBOZW1Nd1RWUlJOVTU1T1doa1NGSnNZbGhDTUdONU9IaE5TVWRMUW1kdmNncENaMFZGUVdSYU5VRm5VVU5DU0hkRlpXZENORUZJV1VFelZEQjNZWE5pU0VWVVNtcEhValJqYlZkak0wRnhTa3RZY21wbFVFc3pMMmcwY0hsblF6aHdDamR2TkVGQlFVZEtVM1JIVkVOM1FVRkNRVTFCVW5wQ1JrRnBRa05CTkdwYVVWQTBRM2ROYVZkdlpWTTNWMDFYTkRaUmEwazBaVGRQYzA1SU0zbFdhR1lLTlhka1FuWm5TV2hCVUVwWmVHUnphVGxPY1U5WVZscHpSVlYwUTNWd09HMHhiUzh5ZWtjek9VWlVSMnhuUlRCTmIzSkVSazFCYjBkRFEzRkhVMDAwT1FwQ1FVMUVRVEpuUVUxSFZVTk5SVmxYVW5kSk5WRktaVTkzVGtOMVZqUjBibG93YmpWUlRteFZiRkF3UW5SWU5WWXlXbFJSVEhGalVXSlhkRzVsUXpkMENreHdkR2xaWjNJd1dqWXlWVVJSU1hoQlR6WkpkRmhCU0N0ellscGpjMkpxTURoNGNqTkhRWEJOTm1ocWRubFVRV3d6T1hCVE0xa3pjMXAzUVhvNGJHWUtVVVJJVGt3MFpVRk1SVzh4YUdWQldWWm5QVDBLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}]}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "oM/HEnHW4njlfNMy/5V8P3BD/do1TEy7GQow1W76Ab8="}, "signature": "MEQCIFOpaXKWvvBDwThDjTHX7tFF8liRoSxLZIsSeoUM/6D4AiBxV9/RnTMMw1t6nniX0rCuwrf8Vh+feLFu99m4ir+3yA=="}}

0 comments on commit d2e8a8d

Please sign in to comment.