-
Notifications
You must be signed in to change notification settings - Fork 8
/
possession-challenge.ts
51 lines (46 loc) · 1.66 KB
/
possession-challenge.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import { Certificate } from "@ndn/keychain";
import { LLSign, Name, Signer } from "@ndn/packet";
import { Encoder } from "@ndn/tlv";
import type { ParameterKV } from "../packet/mod";
import type { ClientChallenge, ClientChallengeContext } from "./challenge";
/** The "possession" challenge where client must present an existing certificate. */
export class ClientPossessionChallenge implements ClientChallenge {
public readonly challengeId = "possession";
private readonly llSign: LLSign;
/**
* Constructor.
* @param cert existing certificate, typically issued by another CA.
* @param pvt private key corresponding to `cert`.
* This is preferably a low-level signer, but can also accept a high-level signer
* that unconditionally signs the input regardless of the packet name.
*/
constructor(private readonly cert: Certificate, pvt: LLSign | Signer) {
if (typeof pvt === "function") {
this.llSign = pvt;
} else {
this.llSign = async (input: Uint8Array) => {
const pkt = {
name: new Name(),
sigValue: new Uint8Array(),
[LLSign.OP]: async (llSign: LLSign) => {
pkt.sigValue = await llSign(input);
},
};
await pvt.sign(pkt);
return pkt.sigValue;
};
}
}
public async start(): Promise<ParameterKV> {
return {
"issued-cert": Encoder.encode(this.cert.data),
};
}
public async next({ parameters: { nonce } }: ClientChallengeContext): Promise<ParameterKV> {
if (!nonce || nonce.byteLength < 16) {
throw new Error("nonce missing");
}
const proof = await this.llSign(nonce);
return { proof };
}
}