Search in sources :

Example 1 with GetDigestResult

use of com.amazonaws.services.qldb.model.GetDigestResult in project amazon-qldb-dmv-sample-java by aws-samples.

the class GetRevision method verifyRegistration.

/**
 * Verify each version of the registration for the given VIN.
 *
 * @param driver
 *              A QLDB driver.
 * @param ledgerName
 *              The ledger to get digest from.
 * @param vin
 *              VIN to query the revision history of a specific registration with.
 * @throws Exception if failed to verify digests.
 * @throws AssertionError if document revision verification failed.
 */
public static void verifyRegistration(final QldbDriver driver, final String ledgerName, final String vin) throws Exception {
    log.info(String.format("Let's verify the registration with VIN=%s, in ledger=%s.", vin, ledgerName));
    try {
        log.info("First, let's get a digest.");
        GetDigestResult digestResult = GetDigest.getDigest(ledgerName);
        ValueHolder digestTipAddress = digestResult.getDigestTipAddress();
        byte[] digestBytes = Verifier.convertByteBufferToByteArray(digestResult.getDigest());
        log.info("Got a ledger digest. Digest end address={}, digest={}.", QldbStringUtils.toUnredactedString(digestTipAddress), Verifier.toBase64(digestBytes));
        log.info(String.format("Next, let's query the registration with VIN=%s. " + "Then we can verify each version of the registration.", vin));
        List<IonStruct> documentsWithMetadataList = new ArrayList<>();
        driver.execute(txn -> {
            documentsWithMetadataList.addAll(queryRegistrationsByVin(txn, vin));
        });
        log.info("Registrations queried successfully!");
        log.info(String.format("Found %s revisions of the registration with VIN=%s.", documentsWithMetadataList.size(), vin));
        for (IonStruct ionStruct : documentsWithMetadataList) {
            QldbRevision document = QldbRevision.fromIon(ionStruct);
            log.info(String.format("Let's verify the document: %s", document));
            log.info("Let's get a proof for the document.");
            GetRevisionResult proofResult = getRevision(ledgerName, document.getMetadata().getId(), digestTipAddress, document.getBlockAddress());
            final IonValue proof = Constants.MAPPER.writeValueAsIonValue(proofResult.getProof());
            final IonReader reader = IonReaderBuilder.standard().build(proof);
            reader.next();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IonWriter writer = SYSTEM.newBinaryWriter(baos);
            writer.writeValue(reader);
            writer.close();
            baos.flush();
            baos.close();
            byte[] byteProof = baos.toByteArray();
            log.info(String.format("Got back a proof: %s", Verifier.toBase64(byteProof)));
            boolean verified = Verifier.verify(document.getHash(), digestBytes, proofResult.getProof().getIonText());
            if (!verified) {
                throw new AssertionError("Document revision is not verified!");
            } else {
                log.info("Success! The document is verified");
            }
            byte[] alteredDigest = Verifier.flipRandomBit(digestBytes);
            log.info(String.format("Flipping one bit in the digest and assert that the document is NOT verified. " + "The altered digest is: %s", Verifier.toBase64(alteredDigest)));
            verified = Verifier.verify(document.getHash(), alteredDigest, proofResult.getProof().getIonText());
            if (verified) {
                throw new AssertionError("Expected document to not be verified against altered digest.");
            } else {
                log.info("Success! As expected flipping a bit in the digest causes verification to fail.");
            }
            byte[] alteredDocumentHash = Verifier.flipRandomBit(document.getHash());
            log.info(String.format("Flipping one bit in the document's hash and assert that it is NOT verified. " + "The altered document hash is: %s.", Verifier.toBase64(alteredDocumentHash)));
            verified = Verifier.verify(alteredDocumentHash, digestBytes, proofResult.getProof().getIonText());
            if (verified) {
                throw new AssertionError("Expected altered document hash to not be verified against digest.");
            } else {
                log.info("Success! As expected flipping a bit in the document hash causes verification to fail.");
            }
        }
    } catch (Exception e) {
        log.error("Failed to verify digests.", e);
        throw e;
    }
    log.info(String.format("Finished verifying the registration with VIN=%s in ledger=%s.", vin, ledgerName));
}
Also used : IonValue(com.amazon.ion.IonValue) GetDigestResult(com.amazonaws.services.qldb.model.GetDigestResult) ArrayList(java.util.ArrayList) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ValueHolder(com.amazonaws.services.qldb.model.ValueHolder) IOException(java.io.IOException) IonStruct(com.amazon.ion.IonStruct) QldbRevision(software.amazon.qldb.tutorial.qldb.QldbRevision) IonReader(com.amazon.ion.IonReader) IonWriter(com.amazon.ion.IonWriter) GetRevisionResult(com.amazonaws.services.qldb.model.GetRevisionResult)

Example 2 with GetDigestResult

use of com.amazonaws.services.qldb.model.GetDigestResult in project amazon-qldb-dmv-sample-java by aws-samples.

the class GetBlock method verifyBlock.

public static void verifyBlock(String ledgerName, BlockAddress blockAddress) throws Exception {
    log.info("Lets verify blocks for ledger with name={}.", ledgerName);
    try {
        log.info("First, let's get a digest");
        GetDigestResult digestResult = GetDigest.getDigest(ledgerName);
        BlockAddress tipBlockAddress = Constants.MAPPER.readValue(digestResult.getDigestTipAddress().getIonText(), BlockAddress.class);
        ValueHolder digestTipAddress = digestResult.getDigestTipAddress();
        byte[] digestBytes = Verifier.convertByteBufferToByteArray(digestResult.getDigest());
        log.info("Got a ledger digest. Digest end address={}, digest={}.", QldbStringUtils.toUnredactedString(digestTipAddress), Verifier.toBase64(digestBytes));
        GetBlockResult getBlockResult = getBlockWithProof(ledgerName, blockAddress, tipBlockAddress);
        JournalBlock block = Constants.MAPPER.readValue(getBlockResult.getBlock().getIonText(), JournalBlock.class);
        boolean verified = Verifier.verify(block.getBlockHash(), digestBytes, getBlockResult.getProof().getIonText());
        if (!verified) {
            throw new AssertionError("Block is not verified!");
        } else {
            log.info("Success! The block is verified.");
        }
        byte[] alteredDigest = Verifier.flipRandomBit(digestBytes);
        log.info("Let's try flipping one bit in the digest and assert that the block is NOT verified. " + "The altered digest is: {}.", Verifier.toBase64(alteredDigest));
        verified = Verifier.verify(block.getBlockHash(), alteredDigest, getBlockResult.getProof().getIonText());
        if (verified) {
            throw new AssertionError("Expected block to not be verified against altered digest.");
        } else {
            log.info("Success! As expected flipping a bit in the digest causes verification to fail.");
        }
        byte[] alteredBlockHash = Verifier.flipRandomBit(block.getBlockHash());
        log.info("Let's try flipping one bit in the block's hash and assert that the block is NOT " + "verified. The altered block hash is: {}.", Verifier.toBase64(alteredBlockHash));
        verified = Verifier.verify(alteredBlockHash, digestBytes, getBlockResult.getProof().getIonText());
        if (verified) {
            throw new AssertionError("Expected altered block hash to not be verified against digest.");
        } else {
            log.info("Success! As expected flipping a bit in the block hash causes verification to fail.");
        }
    } catch (Exception e) {
        log.error("Failed to verify blocks in the ledger with name={}.", ledgerName, e);
        throw e;
    }
}
Also used : BlockAddress(software.amazon.qldb.tutorial.qldb.BlockAddress) GetDigestResult(com.amazonaws.services.qldb.model.GetDigestResult) GetBlockResult(com.amazonaws.services.qldb.model.GetBlockResult) ValueHolder(com.amazonaws.services.qldb.model.ValueHolder) JournalBlock(software.amazon.qldb.tutorial.qldb.JournalBlock) IOException(java.io.IOException)

Example 3 with GetDigestResult

use of com.amazonaws.services.qldb.model.GetDigestResult in project amazon-qldb-dmv-sample-java by aws-samples.

the class GetDigest method getDigest.

/**
 * Get the digest for the specified ledger.
 *
 * @param ledgerName
 *              The ledger to get digest from.
 * @return {@link GetDigestResult}.
 */
public static GetDigestResult getDigest(final String ledgerName) {
    log.info("Let's get the current digest of the ledger named {}.", ledgerName);
    GetDigestRequest request = new GetDigestRequest().withName(ledgerName);
    GetDigestResult result = client.getDigest(request);
    log.info("Success. LedgerDigest: {}.", QldbStringUtils.toUnredactedString(result));
    return result;
}
Also used : GetDigestResult(com.amazonaws.services.qldb.model.GetDigestResult) GetDigestRequest(com.amazonaws.services.qldb.model.GetDigestRequest)

Aggregations

GetDigestResult (com.amazonaws.services.qldb.model.GetDigestResult)3 ValueHolder (com.amazonaws.services.qldb.model.ValueHolder)2 IOException (java.io.IOException)2 IonReader (com.amazon.ion.IonReader)1 IonStruct (com.amazon.ion.IonStruct)1 IonValue (com.amazon.ion.IonValue)1 IonWriter (com.amazon.ion.IonWriter)1 GetBlockResult (com.amazonaws.services.qldb.model.GetBlockResult)1 GetDigestRequest (com.amazonaws.services.qldb.model.GetDigestRequest)1 GetRevisionResult (com.amazonaws.services.qldb.model.GetRevisionResult)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 ArrayList (java.util.ArrayList)1 BlockAddress (software.amazon.qldb.tutorial.qldb.BlockAddress)1 JournalBlock (software.amazon.qldb.tutorial.qldb.JournalBlock)1 QldbRevision (software.amazon.qldb.tutorial.qldb.QldbRevision)1