2021-03-04 18:54:22 +00:00
|
|
|
// Basically Macaroons [1] in a Dataspace context
|
|
|
|
//
|
|
|
|
// [1]: Birgisson, Arnar, Joe Gibbs Politz, Úlfar Erlingsson, Ankur
|
|
|
|
// Taly, Michael Vrable, and Mark Lentczner. “Macaroons: Cookies with
|
|
|
|
// Contextual Caveats for Decentralized Authorization in the Cloud.”
|
|
|
|
// In Network and Distributed System Security Symposium. San Diego,
|
|
|
|
// California: Internet Society, 2014.
|
|
|
|
|
2021-03-04 20:11:58 +00:00
|
|
|
import { mac } from './cryptography.js';
|
2021-03-11 20:56:35 +00:00
|
|
|
import { Bytes, decode, encode, is } from '@preserves/core';
|
|
|
|
import * as S from './gen/sturdy.js';
|
|
|
|
export * from './gen/sturdy.js';
|
2021-03-04 18:54:22 +00:00
|
|
|
|
2021-03-11 20:56:35 +00:00
|
|
|
export type SturdyValue = S._val;
|
2021-03-04 18:54:22 +00:00
|
|
|
|
|
|
|
export const KEY_LENGTH = 16; // 128 bits
|
|
|
|
|
2021-03-11 20:56:35 +00:00
|
|
|
export function pointerNotAllowed(): never {
|
|
|
|
throw new Error("Embedded Ref not permitted in SturdyRef");
|
|
|
|
}
|
|
|
|
|
2021-03-04 18:54:22 +00:00
|
|
|
export function sturdyEncode(v: SturdyValue): Bytes {
|
2021-03-11 20:56:35 +00:00
|
|
|
return encode<S._ptr>(v, {
|
2021-03-04 18:54:22 +00:00
|
|
|
canonical: true,
|
|
|
|
includeAnnotations: false,
|
2021-03-11 20:56:35 +00:00
|
|
|
encodePointer: pointerNotAllowed,
|
2021-03-04 21:08:49 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function sturdyDecode(bs: Bytes): SturdyValue {
|
2021-03-11 20:56:35 +00:00
|
|
|
return decode<S._ptr>(bs, {
|
2021-03-04 21:08:49 +00:00
|
|
|
includeAnnotations: false,
|
2021-03-11 20:56:35 +00:00
|
|
|
decodePointer: pointerNotAllowed,
|
2021-03-04 18:54:22 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-03-11 20:56:35 +00:00
|
|
|
export async function mint(oid: SturdyValue, secretKey: Bytes): Promise<S.SturdyRef> {
|
|
|
|
return S.SturdyRef(oid, [], await mac(secretKey, sturdyEncode(oid)));
|
2021-03-04 18:54:22 +00:00
|
|
|
}
|
|
|
|
|
2021-03-11 20:56:35 +00:00
|
|
|
export async function attenuate(r: S.SturdyRef, ... a: S.Attenuation): Promise<S.SturdyRef> {
|
|
|
|
return S.SturdyRef(
|
|
|
|
S.SturdyRef._.oid(r),
|
|
|
|
[... S.SturdyRef._.caveatChain(r), a],
|
|
|
|
await mac(S.SturdyRef._.sig(r), sturdyEncode(a))
|
2021-03-04 18:54:22 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-03-11 20:56:35 +00:00
|
|
|
export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise<boolean> {
|
|
|
|
const sig = await S.SturdyRef._.caveatChain(r).reduce(
|
2021-03-04 20:01:28 +00:00
|
|
|
async (sig, a) => mac(await sig, sturdyEncode(a)),
|
2021-03-11 20:56:35 +00:00
|
|
|
mac(secretKey, sturdyEncode(S.SturdyRef._.oid(r))));
|
|
|
|
return is(sig, S.SturdyRef._.sig(r));
|
2021-03-04 18:54:22 +00:00
|
|
|
}
|