diff --git a/applet/src/main/java/com/dangerousthings/aliro/CredentialStore.java b/applet/src/main/java/com/dangerousthings/aliro/CredentialStore.java index 2e015f4..d047bcb 100644 --- a/applet/src/main/java/com/dangerousthings/aliro/CredentialStore.java +++ b/applet/src/main/java/com/dangerousthings/aliro/CredentialStore.java @@ -36,7 +36,7 @@ final class CredentialStore { /** Stable field order for AMD-H Element serialization. Append-only — * never reorder or remove without bumping the package version and * writing an explicit migration step in the new ELF's onRestore. */ - static final byte FIELD_VERSION = 1; + static final byte FIELD_VERSION = 2; /** Publish-point read by AliroApplet/StepUpApplet via {@link #get()}. * PersonalizationApplet owns the actual instance; this is just an alias @@ -57,6 +57,7 @@ final class CredentialStore { private final byte[] accessDocument; private short accessDocumentLen; private boolean accessDocumentFinalized; + private boolean accessDocumentVerified; private boolean committed; @@ -202,6 +203,14 @@ final class CredentialStore { return accessDocumentFinalized; } + void markAccessDocumentVerified() { + accessDocumentVerified = true; + } + + boolean isAccessDocumentVerified() { + return accessDocumentVerified; + } + short getAccessDocumentLen() { return accessDocumentLen; } @@ -223,6 +232,7 @@ final class CredentialStore { sink.write(credentialPubKeySet); sink.write(readerPubKeySet); sink.write(accessDocumentFinalized); + sink.write(accessDocumentVerified); sink.write(accessDocumentLen); sink.write(credentialPrivKey); sink.write(credentialPubKey); @@ -246,6 +256,7 @@ final class CredentialStore { s.credentialPubKeySet = src.readBoolean(); s.readerPubKeySet = src.readBoolean(); s.accessDocumentFinalized = src.readBoolean(); + s.accessDocumentVerified = src.readBoolean(); s.accessDocumentLen = src.readShort(); byte[] a; a = src.readByteArray(); @@ -307,6 +318,7 @@ final class CredentialStore { readerPubKeySet = false; accessDocumentLen = 0; accessDocumentFinalized = false; + accessDocumentVerified = false; committed = false; } } diff --git a/applet/src/test/java/com/dangerousthings/aliro/CredentialStoreSerializationTest.java b/applet/src/test/java/com/dangerousthings/aliro/CredentialStoreSerializationTest.java index cf14835..39a127a 100644 --- a/applet/src/test/java/com/dangerousthings/aliro/CredentialStoreSerializationTest.java +++ b/applet/src/test/java/com/dangerousthings/aliro/CredentialStoreSerializationTest.java @@ -81,6 +81,20 @@ class CredentialStoreSerializationTest { assertFalse(restored.hasAccessDocument()); } + @Test + void accessDocumentVerifiedRoundTripsThroughSerialize() { + CredentialStore s1 = CredentialStore.bootstrap(); + s1.resetForTesting(); + s1.markAccessDocumentVerified(); + + RecordingSink buf = new RecordingSink(); + s1.writeTo(buf); + CredentialStore s2 = CredentialStore.readFrom(buf.toSource()); + + assertTrue(s2.isAccessDocumentVerified(), + "verified flag must survive serialize/deserialize round-trip"); + } + /** * Forges a payload with a bogus FIELD_VERSION byte and asserts that * {@link CredentialStore#readFrom} rejects it with @@ -91,7 +105,7 @@ class CredentialStoreSerializationTest { @Test void readFromRejectsWrongFieldVersion() { RecordingSink buf = new RecordingSink(); - buf.write((byte) 0x7F); // != FIELD_VERSION (== 1) + buf.write((byte) 0x7F); // != FIELD_VERSION ISOException ex = assertThrows(ISOException.class, () -> CredentialStore.readFrom(buf.toSource()));