@sd-jwt/core 0.3.2-next.97 → 0.3.2-next.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +24 -6
- package/dist/index.mjs +25 -7
- package/package.json +6 -6
- package/src/index.ts +8 -1
- package/src/kbjwt.ts +20 -4
- package/src/test/index.spec.ts +38 -6
- package/src/test/kbjwt.spec.ts +111 -45
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _sd_jwt_types from '@sd-jwt/types';
|
|
2
|
-
import { Base64urlString, Signer, Verifier, kbHeader, kbPayload, SDJWTCompact, Hasher, DisclosureFrame, HasherAndAlg, SaltGenerator, SDJWTConfig, KBOptions } from '@sd-jwt/types';
|
|
2
|
+
import { Base64urlString, Signer, Verifier, kbHeader, kbPayload, KbVerifier, JwtPayload, SDJWTCompact, Hasher, DisclosureFrame, HasherAndAlg, SaltGenerator, SDJWTConfig, KBOptions } from '@sd-jwt/types';
|
|
3
3
|
import { Disclosure } from '@sd-jwt/utils';
|
|
4
4
|
|
|
5
5
|
type JwtData<Header extends Record<string, unknown>, Payload extends Record<string, unknown>> = {
|
|
@@ -29,7 +29,10 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
declare class KBJwt<Header extends kbHeader = kbHeader, Payload extends kbPayload = kbPayload> extends Jwt<Header, Payload> {
|
|
32
|
-
|
|
32
|
+
verifyKB(values: {
|
|
33
|
+
verifier: KbVerifier;
|
|
34
|
+
payload: JwtPayload;
|
|
35
|
+
}): Promise<{
|
|
33
36
|
payload: Payload;
|
|
34
37
|
header: Header;
|
|
35
38
|
}>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _sd_jwt_types from '@sd-jwt/types';
|
|
2
|
-
import { Base64urlString, Signer, Verifier, kbHeader, kbPayload, SDJWTCompact, Hasher, DisclosureFrame, HasherAndAlg, SaltGenerator, SDJWTConfig, KBOptions } from '@sd-jwt/types';
|
|
2
|
+
import { Base64urlString, Signer, Verifier, kbHeader, kbPayload, KbVerifier, JwtPayload, SDJWTCompact, Hasher, DisclosureFrame, HasherAndAlg, SaltGenerator, SDJWTConfig, KBOptions } from '@sd-jwt/types';
|
|
3
3
|
import { Disclosure } from '@sd-jwt/utils';
|
|
4
4
|
|
|
5
5
|
type JwtData<Header extends Record<string, unknown>, Payload extends Record<string, unknown>> = {
|
|
@@ -29,7 +29,10 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
declare class KBJwt<Header extends kbHeader = kbHeader, Payload extends kbPayload = kbPayload> extends Jwt<Header, Payload> {
|
|
32
|
-
|
|
32
|
+
verifyKB(values: {
|
|
33
|
+
verifier: KbVerifier;
|
|
34
|
+
payload: JwtPayload;
|
|
35
|
+
}): Promise<{
|
|
33
36
|
payload: Payload;
|
|
34
37
|
header: Header;
|
|
35
38
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -5,10 +5,8 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
9
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
9
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
-
var __reflectGet = Reflect.get;
|
|
12
10
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
11
|
var __spreadValues = (a, b) => {
|
|
14
12
|
for (var prop in b || (b = {}))
|
|
@@ -35,7 +33,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
35
33
|
return to;
|
|
36
34
|
};
|
|
37
35
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
|
-
var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
|
|
39
36
|
var __async = (__this, __arguments, generator) => {
|
|
40
37
|
return new Promise((resolve, reject) => {
|
|
41
38
|
var fulfilled = (value) => {
|
|
@@ -145,14 +142,29 @@ var Jwt = class _Jwt {
|
|
|
145
142
|
var import_utils2 = require("@sd-jwt/utils");
|
|
146
143
|
var KBJwt = class _KBJwt extends Jwt {
|
|
147
144
|
// Checking the validity of the key binding jwt
|
|
148
|
-
|
|
145
|
+
// the type unknown is not good, but we don't know at this point how to get the public key of the signer, this is defined in the kbVerifier
|
|
146
|
+
verifyKB(values) {
|
|
149
147
|
return __async(this, null, function* () {
|
|
150
148
|
var _a, _b, _c, _d, _e, _f;
|
|
151
149
|
if (!((_a = this.header) == null ? void 0 : _a.alg) || !this.header.typ || !((_b = this.payload) == null ? void 0 : _b.iat) || !((_c = this.payload) == null ? void 0 : _c.aud) || !((_d = this.payload) == null ? void 0 : _d.nonce) || // this is for backward compatibility with version 06
|
|
152
150
|
!(((_e = this.payload) == null ? void 0 : _e.sd_hash) || ((_f = this.payload) == null ? void 0 : _f._sd_hash))) {
|
|
153
151
|
throw new import_utils2.SDJWTException("Invalid Key Binding Jwt");
|
|
154
152
|
}
|
|
155
|
-
|
|
153
|
+
if (!this.header || !this.payload || !this.signature) {
|
|
154
|
+
throw new import_utils2.SDJWTException("Verify Error: Invalid JWT");
|
|
155
|
+
}
|
|
156
|
+
const header = (0, import_utils2.Base64urlEncode)(JSON.stringify(this.header));
|
|
157
|
+
const payload = (0, import_utils2.Base64urlEncode)(JSON.stringify(this.payload));
|
|
158
|
+
const data = `${header}.${payload}`;
|
|
159
|
+
const verified = yield values.verifier(
|
|
160
|
+
data,
|
|
161
|
+
this.signature,
|
|
162
|
+
values.payload
|
|
163
|
+
);
|
|
164
|
+
if (!verified) {
|
|
165
|
+
throw new import_utils2.SDJWTException("Verify Error: Invalid JWT Signature");
|
|
166
|
+
}
|
|
167
|
+
return { payload: this.payload, header: this.header };
|
|
156
168
|
});
|
|
157
169
|
}
|
|
158
170
|
// This function is for creating KBJwt object for verify properly
|
|
@@ -557,7 +569,13 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
557
569
|
if (!this.userConfig.kbVerifier) {
|
|
558
570
|
throw new import_utils5.SDJWTException("Key Binding Verifier not found");
|
|
559
571
|
}
|
|
560
|
-
const kb = yield sdjwt.kbJwt.
|
|
572
|
+
const kb = yield sdjwt.kbJwt.verifyKB({
|
|
573
|
+
verifier: this.userConfig.kbVerifier,
|
|
574
|
+
payload
|
|
575
|
+
});
|
|
576
|
+
if (!kb) {
|
|
577
|
+
throw new Error("signature is not valid");
|
|
578
|
+
}
|
|
561
579
|
const sdHashfromKb = kb.payload.sd_hash;
|
|
562
580
|
const sdjwtWithoutKb = new SDJwt({
|
|
563
581
|
jwt: sdjwt.jwt,
|
package/dist/index.mjs
CHANGED
|
@@ -2,10 +2,8 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
-
var __reflectGet = Reflect.get;
|
|
9
7
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
10
8
|
var __spreadValues = (a, b) => {
|
|
11
9
|
for (var prop in b || (b = {}))
|
|
@@ -19,7 +17,6 @@ var __spreadValues = (a, b) => {
|
|
|
19
17
|
return a;
|
|
20
18
|
};
|
|
21
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
22
|
-
var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
|
|
23
20
|
var __async = (__this, __arguments, generator) => {
|
|
24
21
|
return new Promise((resolve, reject) => {
|
|
25
22
|
var fulfilled = (value) => {
|
|
@@ -115,17 +112,32 @@ var Jwt = class _Jwt {
|
|
|
115
112
|
};
|
|
116
113
|
|
|
117
114
|
// src/kbjwt.ts
|
|
118
|
-
import { SDJWTException as SDJWTException2 } from "@sd-jwt/utils";
|
|
115
|
+
import { Base64urlEncode as Base64urlEncode2, SDJWTException as SDJWTException2 } from "@sd-jwt/utils";
|
|
119
116
|
var KBJwt = class _KBJwt extends Jwt {
|
|
120
117
|
// Checking the validity of the key binding jwt
|
|
121
|
-
|
|
118
|
+
// the type unknown is not good, but we don't know at this point how to get the public key of the signer, this is defined in the kbVerifier
|
|
119
|
+
verifyKB(values) {
|
|
122
120
|
return __async(this, null, function* () {
|
|
123
121
|
var _a, _b, _c, _d, _e, _f;
|
|
124
122
|
if (!((_a = this.header) == null ? void 0 : _a.alg) || !this.header.typ || !((_b = this.payload) == null ? void 0 : _b.iat) || !((_c = this.payload) == null ? void 0 : _c.aud) || !((_d = this.payload) == null ? void 0 : _d.nonce) || // this is for backward compatibility with version 06
|
|
125
123
|
!(((_e = this.payload) == null ? void 0 : _e.sd_hash) || ((_f = this.payload) == null ? void 0 : _f._sd_hash))) {
|
|
126
124
|
throw new SDJWTException2("Invalid Key Binding Jwt");
|
|
127
125
|
}
|
|
128
|
-
|
|
126
|
+
if (!this.header || !this.payload || !this.signature) {
|
|
127
|
+
throw new SDJWTException2("Verify Error: Invalid JWT");
|
|
128
|
+
}
|
|
129
|
+
const header = Base64urlEncode2(JSON.stringify(this.header));
|
|
130
|
+
const payload = Base64urlEncode2(JSON.stringify(this.payload));
|
|
131
|
+
const data = `${header}.${payload}`;
|
|
132
|
+
const verified = yield values.verifier(
|
|
133
|
+
data,
|
|
134
|
+
this.signature,
|
|
135
|
+
values.payload
|
|
136
|
+
);
|
|
137
|
+
if (!verified) {
|
|
138
|
+
throw new SDJWTException2("Verify Error: Invalid JWT Signature");
|
|
139
|
+
}
|
|
140
|
+
return { payload: this.payload, header: this.header };
|
|
129
141
|
});
|
|
130
142
|
}
|
|
131
143
|
// This function is for creating KBJwt object for verify properly
|
|
@@ -537,7 +549,13 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
537
549
|
if (!this.userConfig.kbVerifier) {
|
|
538
550
|
throw new SDJWTException4("Key Binding Verifier not found");
|
|
539
551
|
}
|
|
540
|
-
const kb = yield sdjwt.kbJwt.
|
|
552
|
+
const kb = yield sdjwt.kbJwt.verifyKB({
|
|
553
|
+
verifier: this.userConfig.kbVerifier,
|
|
554
|
+
payload
|
|
555
|
+
});
|
|
556
|
+
if (!kb) {
|
|
557
|
+
throw new Error("signature is not valid");
|
|
558
|
+
}
|
|
541
559
|
const sdHashfromKb = kb.payload.sd_hash;
|
|
542
560
|
const sdjwtWithoutKb = new SDJwt({
|
|
543
561
|
jwt: sdjwt.jwt,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sd-jwt/core",
|
|
3
|
-
"version": "0.3.2-next.
|
|
3
|
+
"version": "0.3.2-next.99+94f33f1",
|
|
4
4
|
"description": "sd-jwt draft 7 implementation in typescript",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
},
|
|
39
39
|
"license": "Apache-2.0",
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@sd-jwt/crypto-nodejs": "0.3.2-next.
|
|
41
|
+
"@sd-jwt/crypto-nodejs": "0.3.2-next.99+94f33f1"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@sd-jwt/decode": "0.3.2-next.
|
|
45
|
-
"@sd-jwt/types": "0.3.2-next.
|
|
46
|
-
"@sd-jwt/utils": "0.3.2-next.
|
|
44
|
+
"@sd-jwt/decode": "0.3.2-next.99+94f33f1",
|
|
45
|
+
"@sd-jwt/types": "0.3.2-next.99+94f33f1",
|
|
46
|
+
"@sd-jwt/utils": "0.3.2-next.99+94f33f1"
|
|
47
47
|
},
|
|
48
48
|
"publishConfig": {
|
|
49
49
|
"access": "public"
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"esm"
|
|
62
62
|
]
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "94f33f1931393345ad1d0977adad67d407615607"
|
|
65
65
|
}
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
SDJWTConfig,
|
|
12
12
|
} from '@sd-jwt/types';
|
|
13
13
|
import { getSDAlgAndPayload } from '@sd-jwt/decode';
|
|
14
|
+
import { JwtPayload } from '@sd-jwt/types';
|
|
14
15
|
|
|
15
16
|
export * from './sdjwt';
|
|
16
17
|
export * from './kbjwt';
|
|
@@ -212,7 +213,13 @@ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
212
213
|
if (!this.userConfig.kbVerifier) {
|
|
213
214
|
throw new SDJWTException('Key Binding Verifier not found');
|
|
214
215
|
}
|
|
215
|
-
const kb = await sdjwt.kbJwt.
|
|
216
|
+
const kb = await sdjwt.kbJwt.verifyKB({
|
|
217
|
+
verifier: this.userConfig.kbVerifier,
|
|
218
|
+
payload: payload as JwtPayload,
|
|
219
|
+
});
|
|
220
|
+
if (!kb) {
|
|
221
|
+
throw new Error('signature is not valid');
|
|
222
|
+
}
|
|
216
223
|
const sdHashfromKb = kb.payload.sd_hash;
|
|
217
224
|
const sdjwtWithoutKb = new SDJwt({
|
|
218
225
|
jwt: sdjwt.jwt,
|
package/src/kbjwt.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { SDJWTException } from '@sd-jwt/utils';
|
|
1
|
+
import { Base64urlEncode, SDJWTException } from '@sd-jwt/utils';
|
|
2
2
|
import { Jwt } from './jwt';
|
|
3
|
-
import {
|
|
3
|
+
import { JwtPayload, kbHeader, kbPayload, KbVerifier } from '@sd-jwt/types';
|
|
4
4
|
|
|
5
5
|
export class KBJwt<
|
|
6
6
|
Header extends kbHeader = kbHeader,
|
|
7
7
|
Payload extends kbPayload = kbPayload,
|
|
8
8
|
> extends Jwt<Header, Payload> {
|
|
9
9
|
// Checking the validity of the key binding jwt
|
|
10
|
-
public
|
|
10
|
+
// the type unknown is not good, but we don't know at this point how to get the public key of the signer, this is defined in the kbVerifier
|
|
11
|
+
public async verifyKB(values: { verifier: KbVerifier; payload: JwtPayload }) {
|
|
11
12
|
if (
|
|
12
13
|
!this.header?.alg ||
|
|
13
14
|
!this.header.typ ||
|
|
@@ -22,7 +23,22 @@ export class KBJwt<
|
|
|
22
23
|
) {
|
|
23
24
|
throw new SDJWTException('Invalid Key Binding Jwt');
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
+
if (!this.header || !this.payload || !this.signature) {
|
|
27
|
+
throw new SDJWTException('Verify Error: Invalid JWT');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const header = Base64urlEncode(JSON.stringify(this.header));
|
|
31
|
+
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
32
|
+
const data = `${header}.${payload}`;
|
|
33
|
+
const verified = await values.verifier(
|
|
34
|
+
data,
|
|
35
|
+
this.signature,
|
|
36
|
+
values.payload,
|
|
37
|
+
);
|
|
38
|
+
if (!verified) {
|
|
39
|
+
throw new SDJWTException('Verify Error: Invalid JWT Signature');
|
|
40
|
+
}
|
|
41
|
+
return { payload: this.payload, header: this.header };
|
|
26
42
|
}
|
|
27
43
|
|
|
28
44
|
// This function is for creating KBJwt object for verify properly
|
package/src/test/index.spec.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { SDJwtInstance, SdJwtPayload } from '../index';
|
|
2
2
|
import { Signer, Verifier } from '@sd-jwt/types';
|
|
3
|
-
import Crypto from 'node:crypto';
|
|
3
|
+
import Crypto, { KeyLike } from 'node:crypto';
|
|
4
4
|
import { describe, expect, test } from 'vitest';
|
|
5
5
|
import { digest, generateSalt } from '@sd-jwt/crypto-nodejs';
|
|
6
|
+
import { KbVerifier, JwtPayload } from '@sd-jwt/types';
|
|
7
|
+
import { importJWK, exportJWK, JWK } from 'jose';
|
|
6
8
|
|
|
7
9
|
export const createSignerVerifier = () => {
|
|
8
10
|
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
@@ -181,23 +183,53 @@ describe('index', () => {
|
|
|
181
183
|
|
|
182
184
|
test('verify with kbJwt', async () => {
|
|
183
185
|
const { signer, verifier } = createSignerVerifier();
|
|
186
|
+
|
|
187
|
+
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
188
|
+
|
|
189
|
+
//TODO: maybe we can pass a minial class of the jwt to pass the token
|
|
190
|
+
const kbVerifier: KbVerifier = async (
|
|
191
|
+
data: string,
|
|
192
|
+
sig: string,
|
|
193
|
+
payload: JwtPayload,
|
|
194
|
+
) => {
|
|
195
|
+
let publicKey: JsonWebKey;
|
|
196
|
+
if (payload.cnf) {
|
|
197
|
+
// use the key from the cnf
|
|
198
|
+
publicKey = payload.cnf.jwk;
|
|
199
|
+
} else {
|
|
200
|
+
throw Error('key binding not supported');
|
|
201
|
+
}
|
|
202
|
+
// get the key of the holder to verify the signature
|
|
203
|
+
return Crypto.verify(
|
|
204
|
+
null,
|
|
205
|
+
Buffer.from(data),
|
|
206
|
+
(await importJWK(publicKey as JWK, 'EdDSA')) as KeyLike,
|
|
207
|
+
Buffer.from(sig, 'base64url'),
|
|
208
|
+
);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const kbSigner = (data: string) => {
|
|
212
|
+
const sig = Crypto.sign(null, Buffer.from(data), privateKey);
|
|
213
|
+
return Buffer.from(sig).toString('base64url');
|
|
214
|
+
};
|
|
215
|
+
|
|
184
216
|
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
185
217
|
signer,
|
|
186
218
|
signAlg: 'EdDSA',
|
|
187
219
|
verifier,
|
|
188
220
|
hasher: digest,
|
|
189
221
|
saltGenerator: generateSalt,
|
|
190
|
-
kbSigner:
|
|
191
|
-
kbVerifier:
|
|
222
|
+
kbSigner: kbSigner,
|
|
223
|
+
kbVerifier: kbVerifier,
|
|
192
224
|
kbSignAlg: 'EdDSA',
|
|
193
225
|
});
|
|
194
|
-
|
|
195
226
|
const credential = await sdjwt.issue(
|
|
196
227
|
{
|
|
197
228
|
foo: 'bar',
|
|
198
|
-
iss: 'Issuer',
|
|
199
229
|
iat: new Date().getTime(),
|
|
200
|
-
|
|
230
|
+
cnf: {
|
|
231
|
+
jwk: await exportJWK(publicKey),
|
|
232
|
+
},
|
|
201
233
|
},
|
|
202
234
|
{
|
|
203
235
|
_sd: ['foo'],
|
package/src/test/kbjwt.spec.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { SDJWTException } from '@sd-jwt/utils';
|
|
2
2
|
import { KBJwt } from '../kbjwt';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
JwtPayload,
|
|
5
|
+
KB_JWT_TYP,
|
|
6
|
+
KbVerifier,
|
|
7
|
+
Signer,
|
|
8
|
+
Verifier,
|
|
9
|
+
} from '@sd-jwt/types';
|
|
10
|
+
import Crypto, { KeyLike } from 'node:crypto';
|
|
5
11
|
import { describe, expect, test } from 'vitest';
|
|
12
|
+
import { JWK, exportJWK, importJWK } from 'jose';
|
|
6
13
|
|
|
7
14
|
describe('KB JWT', () => {
|
|
8
15
|
test('create', async () => {
|
|
@@ -69,11 +76,27 @@ describe('KB JWT', () => {
|
|
|
69
76
|
const sig = Crypto.sign(null, Buffer.from(data), privateKey);
|
|
70
77
|
return Buffer.from(sig).toString('base64url');
|
|
71
78
|
};
|
|
72
|
-
|
|
79
|
+
|
|
80
|
+
const payload = {
|
|
81
|
+
cnf: {
|
|
82
|
+
jwk: await exportJWK(publicKey),
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const testVerifier: KbVerifier = async (
|
|
87
|
+
data: string,
|
|
88
|
+
sig: string,
|
|
89
|
+
payload: JwtPayload,
|
|
90
|
+
) => {
|
|
91
|
+
expect(payload).toStrictEqual(payload);
|
|
92
|
+
expect(payload.cnf?.jwk).toBeDefined();
|
|
93
|
+
|
|
94
|
+
const publicKey = payload.cnf?.jwk;
|
|
95
|
+
|
|
73
96
|
return Crypto.verify(
|
|
74
97
|
null,
|
|
75
98
|
Buffer.from(data),
|
|
76
|
-
publicKey,
|
|
99
|
+
(await importJWK(publicKey as JWK, 'EdDSA')) as KeyLike,
|
|
77
100
|
Buffer.from(sig, 'base64url'),
|
|
78
101
|
);
|
|
79
102
|
};
|
|
@@ -91,7 +114,10 @@ describe('KB JWT', () => {
|
|
|
91
114
|
});
|
|
92
115
|
const encodedKbJwt = await kbJwt.sign(testSigner);
|
|
93
116
|
const decoded = KBJwt.fromKBEncode(encodedKbJwt);
|
|
94
|
-
const verified = await decoded.
|
|
117
|
+
const verified = await decoded.verifyKB({
|
|
118
|
+
verifier: testVerifier,
|
|
119
|
+
payload,
|
|
120
|
+
});
|
|
95
121
|
expect(verified).toStrictEqual({
|
|
96
122
|
header: {
|
|
97
123
|
typ: KB_JWT_TYP,
|
|
@@ -112,11 +138,26 @@ describe('KB JWT', () => {
|
|
|
112
138
|
const sig = Crypto.sign(null, Buffer.from(data), privateKey);
|
|
113
139
|
return Buffer.from(sig).toString('base64url');
|
|
114
140
|
};
|
|
115
|
-
|
|
141
|
+
|
|
142
|
+
const payload = {
|
|
143
|
+
cnf: {
|
|
144
|
+
jwk: await exportJWK(publicKey),
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
const testVerifier: KbVerifier = async (
|
|
148
|
+
data: string,
|
|
149
|
+
sig: string,
|
|
150
|
+
payload: JwtPayload,
|
|
151
|
+
) => {
|
|
152
|
+
expect(payload).toStrictEqual(payload);
|
|
153
|
+
expect(payload.cnf?.jwk).toBeDefined();
|
|
154
|
+
|
|
155
|
+
const publicKey = payload.cnf?.jwk;
|
|
156
|
+
|
|
116
157
|
return Crypto.verify(
|
|
117
158
|
null,
|
|
118
159
|
Buffer.from(data),
|
|
119
|
-
publicKey,
|
|
160
|
+
(await importJWK(publicKey as JWK, 'EdDSA')) as KeyLike,
|
|
120
161
|
Buffer.from(sig, 'base64url'),
|
|
121
162
|
);
|
|
122
163
|
};
|
|
@@ -136,26 +177,34 @@ describe('KB JWT', () => {
|
|
|
136
177
|
const encodedKbJwt = await kbJwt.sign(testSigner);
|
|
137
178
|
const decoded = KBJwt.fromKBEncode(encodedKbJwt);
|
|
138
179
|
try {
|
|
139
|
-
await decoded.
|
|
180
|
+
await decoded.verifyKB({ verifier: testVerifier, payload });
|
|
140
181
|
} catch (e: unknown) {
|
|
141
182
|
const error = e as SDJWTException;
|
|
142
183
|
expect(error.message).toBe('Invalid Key Binding Jwt');
|
|
143
184
|
}
|
|
144
185
|
});
|
|
145
186
|
|
|
146
|
-
test('verify with
|
|
187
|
+
test('verify failed with verifier return false', async () => {
|
|
147
188
|
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
148
189
|
const testSigner: Signer = async (data: string) => {
|
|
149
190
|
const sig = Crypto.sign(null, Buffer.from(data), privateKey);
|
|
150
191
|
return Buffer.from(sig).toString('base64url');
|
|
151
192
|
};
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
193
|
+
|
|
194
|
+
const payload = {
|
|
195
|
+
cnf: {
|
|
196
|
+
jwk: await exportJWK(publicKey),
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
const testVerifier: KbVerifier = async (
|
|
200
|
+
data: string,
|
|
201
|
+
sig: string,
|
|
202
|
+
payload: JwtPayload,
|
|
203
|
+
) => {
|
|
204
|
+
expect(payload).toStrictEqual(payload);
|
|
205
|
+
expect(payload.cnf?.jwk).toBeDefined();
|
|
206
|
+
|
|
207
|
+
return false;
|
|
159
208
|
};
|
|
160
209
|
|
|
161
210
|
const kbJwt = new KBJwt({
|
|
@@ -170,37 +219,37 @@ describe('KB JWT', () => {
|
|
|
170
219
|
sd_hash: 'hash',
|
|
171
220
|
},
|
|
172
221
|
});
|
|
173
|
-
|
|
174
222
|
const encodedKbJwt = await kbJwt.sign(testSigner);
|
|
175
223
|
const decoded = KBJwt.fromKBEncode(encodedKbJwt);
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
payload: {
|
|
183
|
-
iat: 1,
|
|
184
|
-
aud: 'aud',
|
|
185
|
-
nonce: 'nonce',
|
|
186
|
-
sd_hash: 'hash',
|
|
187
|
-
},
|
|
188
|
-
});
|
|
224
|
+
try {
|
|
225
|
+
await decoded.verifyKB({ verifier: testVerifier, payload });
|
|
226
|
+
} catch (e: unknown) {
|
|
227
|
+
const error = e as SDJWTException;
|
|
228
|
+
expect(error.message).toBe('Verify Error: Invalid JWT Signature');
|
|
229
|
+
}
|
|
189
230
|
});
|
|
190
231
|
|
|
191
|
-
test('verify failed with
|
|
232
|
+
test('verify failed with invalid jwt', async () => {
|
|
192
233
|
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
193
234
|
const testSigner: Signer = async (data: string) => {
|
|
194
235
|
const sig = Crypto.sign(null, Buffer.from(data), privateKey);
|
|
195
236
|
return Buffer.from(sig).toString('base64url');
|
|
196
237
|
};
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
238
|
+
|
|
239
|
+
const payload = {
|
|
240
|
+
cnf: {
|
|
241
|
+
jwk: await exportJWK(publicKey),
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
const testVerifier: KbVerifier = async (
|
|
245
|
+
data: string,
|
|
246
|
+
sig: string,
|
|
247
|
+
payload: JwtPayload,
|
|
248
|
+
) => {
|
|
249
|
+
expect(payload).toStrictEqual(payload);
|
|
250
|
+
expect(payload.cnf?.jwk).toBeDefined();
|
|
251
|
+
|
|
252
|
+
return false;
|
|
204
253
|
};
|
|
205
254
|
|
|
206
255
|
const kbJwt = new KBJwt({
|
|
@@ -212,17 +261,17 @@ describe('KB JWT', () => {
|
|
|
212
261
|
iat: 1,
|
|
213
262
|
aud: 'aud',
|
|
214
263
|
nonce: 'nonce',
|
|
215
|
-
sd_hash: '',
|
|
264
|
+
sd_hash: 'hash',
|
|
216
265
|
},
|
|
217
266
|
});
|
|
218
|
-
|
|
219
267
|
const encodedKbJwt = await kbJwt.sign(testSigner);
|
|
220
268
|
const decoded = KBJwt.fromKBEncode(encodedKbJwt);
|
|
269
|
+
decoded.signature = undefined;
|
|
221
270
|
try {
|
|
222
|
-
await decoded.
|
|
271
|
+
await decoded.verifyKB({ verifier: testVerifier, payload });
|
|
223
272
|
} catch (e: unknown) {
|
|
224
273
|
const error = e as SDJWTException;
|
|
225
|
-
expect(error.message).toBe('
|
|
274
|
+
expect(error.message).toBe('Verify Error: Invalid JWT');
|
|
226
275
|
}
|
|
227
276
|
});
|
|
228
277
|
|
|
@@ -232,11 +281,25 @@ describe('KB JWT', () => {
|
|
|
232
281
|
const sig = Crypto.sign(null, Buffer.from(data), privateKey);
|
|
233
282
|
return Buffer.from(sig).toString('base64url');
|
|
234
283
|
};
|
|
235
|
-
const
|
|
284
|
+
const payload = {
|
|
285
|
+
cnf: {
|
|
286
|
+
jwk: await exportJWK(publicKey),
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
const testVerifier: KbVerifier = async (
|
|
290
|
+
data: string,
|
|
291
|
+
sig: string,
|
|
292
|
+
payload: JwtPayload,
|
|
293
|
+
) => {
|
|
294
|
+
expect(payload).toStrictEqual(payload);
|
|
295
|
+
expect(payload.cnf?.jwk).toBeDefined();
|
|
296
|
+
|
|
297
|
+
const publicKey = payload.cnf?.jwk;
|
|
298
|
+
|
|
236
299
|
return Crypto.verify(
|
|
237
300
|
null,
|
|
238
301
|
Buffer.from(data),
|
|
239
|
-
publicKey,
|
|
302
|
+
(await importJWK(publicKey as JWK, 'EdDSA')) as KeyLike,
|
|
240
303
|
Buffer.from(sig, 'base64url'),
|
|
241
304
|
);
|
|
242
305
|
};
|
|
@@ -258,7 +321,10 @@ describe('KB JWT', () => {
|
|
|
258
321
|
|
|
259
322
|
const encodedKbJwt = await kbJwt.sign(testSigner);
|
|
260
323
|
const decoded = KBJwt.fromKBEncode(encodedKbJwt);
|
|
261
|
-
const verified = await decoded.
|
|
324
|
+
const verified = await decoded.verifyKB({
|
|
325
|
+
verifier: testVerifier,
|
|
326
|
+
payload,
|
|
327
|
+
});
|
|
262
328
|
expect(verified).toStrictEqual({
|
|
263
329
|
header: {
|
|
264
330
|
typ: KB_JWT_TYP,
|