Skip to content

Commit

Permalink
feat(core): Adds kao.schemaVersion (#416)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmihalcik-virtru authored Jan 24, 2025
1 parent 11ad526 commit 7925669
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
58 changes: 57 additions & 1 deletion lib/tdf3/src/models/key-access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
Expand Down Expand Up @@ -48,6 +50,7 @@ export class Wrapped {
alg: 'HS256',
hash: base64.encode(policyBinding),
},
schemaVersion,
};
if (this.kid) {
this.keyAccessObject.kid = this.kid;
Expand All @@ -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;
};
9 changes: 8 additions & 1 deletion lib/tests/web/roundtrip.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down

0 comments on commit 7925669

Please sign in to comment.