diff --git a/lib/tdf3/src/models/key-access.ts b/lib/tdf3/src/models/key-access.ts index 90872e75..d93d067a 100644 --- a/lib/tdf3/src/models/key-access.ts +++ b/lib/tdf3/src/models/key-access.ts @@ -5,6 +5,8 @@ import { Policy } from './policy.js'; export type KeyAccessType = 'remote' | 'wrapped'; +export const schemaVersion = '1.0'; + export function isRemote(keyAccessJSON: KeyAccess | KeyAccessObject): boolean { return keyAccessJSON.type === 'remote'; } @@ -48,6 +50,7 @@ export class Wrapped { alg: 'HS256', hash: base64.encode(policyBinding), }, + schemaVersion, }; if (this.kid) { this.keyAccessObject.kid = this.kid; @@ -62,16 +65,69 @@ export class Wrapped { export type KeyAccess = Wrapped; +/** + * A KeyAccess object stores all information about how an object key OR one key split is stored. + */ export type KeyAccessObject = { - sid?: string; + /** + * Specifies how the key is stored. Possible Values: + * **wrapped**: The wrapped key is stored as part of the manifest. + * **remote**: [Unsupported] The wrapped key (see below) is stored remotely and is thus not part of the final TDF manifest. + */ type: KeyAccessType; + + /** + * A key split (or share) identifier. + * To allow sharing a key across several access domains, + * the KAO supports a 'Split Identifier'. + * To reconstruct such a key when encryptionInformation type is 'split', + * use the xor operation to combine one of each separate sid. + */ + sid?: string; + + /** + * A locator for a Key Access service capable of granting access to the wrapped key. + */ url: string; + + /** + * Additional information for the Key Access service to identify how to unwrap the key. + */ kid?: string; + + /** + * The protocol used to access the key. + */ protocol: 'kas'; + + /** + * The symmetric key used to encrypt the payload. + * It is encrypted using the public key of the KAS, + * then base64 encoded. + */ wrappedKey?: string; + + /** + * An object that contains a keyed hash that will provide cryptographic integrity on the policy object, + * such that it cannot be modified or copied to another TDF + * without invalidating the binding. + * Specifically, you would have to have access to the key in order to overwrite the policy. + */ policyBinding?: { alg: string; hash: string; }; + + /** + * Metadata associated with the TDF and the request. + * The contents of the metadata are freeform, + * and are used to pass information from the client to the KAS. + * The metadata stored here should not be used for primary access decisions. + */ encryptedMetadata?: string; + + /** + * Version information for the KAO format. + */ + schemaVersion?: string; }; diff --git a/lib/tests/web/roundtrip.test.ts b/lib/tests/web/roundtrip.test.ts index 6ca65c00..feaec2a7 100644 --- a/lib/tests/web/roundtrip.test.ts +++ b/lib/tests/web/roundtrip.test.ts @@ -33,7 +33,14 @@ describe('Local roundtrip Tests', () => { source: { type: 'chunker', location: fromString('hello world') }, }); const cipherManifest = await cipherTextStream.manifest; - expect(cipherManifest?.encryptionInformation?.keyAccess[0]?.url).to.equal(kasEndpoint); + const kao = cipherManifest?.encryptionInformation?.keyAccess[0]; + expect(kao).to.contain({ + url: kasEndpoint, + kid: 'r1', + type: 'wrapped', + protocol: 'kas', + schemaVersion: '1.0', + }); const cipherTextArray = new Uint8Array(await new Response(cipherTextStream).arrayBuffer()); const nanotdfParsed = await client.read({