init project
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
import { FlattenedSign } from '../flattened/sign.js';
|
||||
import { unencodedPayload } from '../../lib/jws_sign.js';
|
||||
export class CompactSign {
|
||||
#flattened;
|
||||
#protectedHeader;
|
||||
constructor(payload) {
|
||||
this.#flattened = new FlattenedSign(payload);
|
||||
}
|
||||
setProtectedHeader(protectedHeader) {
|
||||
this.#flattened.setProtectedHeader(protectedHeader);
|
||||
this.#protectedHeader = protectedHeader;
|
||||
return this;
|
||||
}
|
||||
async sign(key, options) {
|
||||
if (unencodedPayload(this.#protectedHeader)) {
|
||||
throw new TypeError('use the flattened module for creating JWS with b64: false');
|
||||
}
|
||||
const jws = await this.#flattened.sign(key, options);
|
||||
return `${jws.protected}.${jws.payload}.${jws.signature}`;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { prepareVerify, verifyCompact } from '../../lib/jws_verify.js';
|
||||
export async function compactVerify(jws, key, options) {
|
||||
const verified = await verifyCompact(jws, prepareVerify(options), key);
|
||||
const result = { payload: verified.payload, protectedHeader: verified.parsedProt };
|
||||
if (typeof key === 'function') {
|
||||
return { ...result, key: verified.key };
|
||||
}
|
||||
return result;
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import { JWSInvalid } from '../../util/errors.js';
|
||||
import { createSignature } from '../../lib/jws_sign.js';
|
||||
import { assertNotSet } from '../../lib/helpers.js';
|
||||
export class FlattenedSign {
|
||||
#payload;
|
||||
#protectedHeader;
|
||||
#unprotectedHeader;
|
||||
constructor(payload) {
|
||||
if (!(payload instanceof Uint8Array)) {
|
||||
throw new TypeError('payload must be an instance of Uint8Array');
|
||||
}
|
||||
this.#payload = payload;
|
||||
}
|
||||
setProtectedHeader(protectedHeader) {
|
||||
assertNotSet(this.#protectedHeader, 'setProtectedHeader');
|
||||
this.#protectedHeader = protectedHeader;
|
||||
return this;
|
||||
}
|
||||
setUnprotectedHeader(unprotectedHeader) {
|
||||
assertNotSet(this.#unprotectedHeader, 'setUnprotectedHeader');
|
||||
this.#unprotectedHeader = unprotectedHeader;
|
||||
return this;
|
||||
}
|
||||
async sign(key, options) {
|
||||
if (!this.#protectedHeader && !this.#unprotectedHeader) {
|
||||
throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
|
||||
}
|
||||
const jws = await createSignature({
|
||||
payload: this.#payload,
|
||||
protectedHeader: this.#protectedHeader,
|
||||
unprotectedHeader: this.#unprotectedHeader,
|
||||
crit: options?.crit,
|
||||
}, key);
|
||||
if (this.#unprotectedHeader) {
|
||||
jws.header = this.#unprotectedHeader;
|
||||
}
|
||||
return jws;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { JWSInvalid } from '../../util/errors.js';
|
||||
import { isObject } from '../../lib/type_checks.js';
|
||||
import { prepareVerify, verifySignature, verifyResult } from '../../lib/jws_verify.js';
|
||||
export async function flattenedVerify(jws, key, options) {
|
||||
if (!isObject(jws)) {
|
||||
throw new JWSInvalid('Flattened JWS must be an object');
|
||||
}
|
||||
if (jws.protected === undefined && jws.header === undefined) {
|
||||
throw new JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
|
||||
}
|
||||
if (jws.protected !== undefined && typeof jws.protected !== 'string') {
|
||||
throw new JWSInvalid('JWS Protected Header incorrect type');
|
||||
}
|
||||
if (jws.payload === undefined) {
|
||||
throw new JWSInvalid('JWS Payload missing');
|
||||
}
|
||||
if (typeof jws.signature !== 'string') {
|
||||
throw new JWSInvalid('JWS Signature missing or incorrect type');
|
||||
}
|
||||
if (jws.header !== undefined && !isObject(jws.header)) {
|
||||
throw new JWSInvalid('JWS Unprotected Header incorrect type');
|
||||
}
|
||||
return verifyResult(jws, await verifySignature(jws, prepareVerify(options), key));
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
import { createSignature } from '../../lib/jws_sign.js';
|
||||
import { JWSInvalid } from '../../util/errors.js';
|
||||
import { assertNotSet } from '../../lib/helpers.js';
|
||||
class IndividualSignature {
|
||||
#parent;
|
||||
protectedHeader;
|
||||
unprotectedHeader;
|
||||
options;
|
||||
key;
|
||||
constructor(sig, key, options) {
|
||||
this.#parent = sig;
|
||||
this.key = key;
|
||||
this.options = options;
|
||||
}
|
||||
setProtectedHeader(protectedHeader) {
|
||||
assertNotSet(this.protectedHeader, 'setProtectedHeader');
|
||||
this.protectedHeader = protectedHeader;
|
||||
return this;
|
||||
}
|
||||
setUnprotectedHeader(unprotectedHeader) {
|
||||
assertNotSet(this.unprotectedHeader, 'setUnprotectedHeader');
|
||||
this.unprotectedHeader = unprotectedHeader;
|
||||
return this;
|
||||
}
|
||||
addSignature(...args) {
|
||||
return this.#parent.addSignature(...args);
|
||||
}
|
||||
sign(...args) {
|
||||
return this.#parent.sign(...args);
|
||||
}
|
||||
done() {
|
||||
return this.#parent;
|
||||
}
|
||||
}
|
||||
export class GeneralSign {
|
||||
#payload;
|
||||
#signatures = [];
|
||||
constructor(payload) {
|
||||
this.#payload = payload;
|
||||
}
|
||||
addSignature(key, options) {
|
||||
const signature = new IndividualSignature(this, key, options);
|
||||
this.#signatures.push(signature);
|
||||
return signature;
|
||||
}
|
||||
async sign() {
|
||||
if (!this.#signatures.length) {
|
||||
throw new JWSInvalid('at least one signature must be added');
|
||||
}
|
||||
if (!(this.#payload instanceof Uint8Array)) {
|
||||
throw new TypeError('payload must be an instance of Uint8Array');
|
||||
}
|
||||
const jws = {
|
||||
signatures: [],
|
||||
payload: '',
|
||||
};
|
||||
const encoded = {};
|
||||
for (let i = 0; i < this.#signatures.length; i++) {
|
||||
const signature = this.#signatures[i];
|
||||
if (!signature.protectedHeader && !signature.unprotectedHeader) {
|
||||
throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
|
||||
}
|
||||
const { payload, ...rest } = await createSignature({
|
||||
payload: this.#payload,
|
||||
protectedHeader: signature.protectedHeader,
|
||||
unprotectedHeader: signature.unprotectedHeader,
|
||||
crit: signature.options?.crit,
|
||||
encoded,
|
||||
}, signature.key);
|
||||
if (signature.unprotectedHeader) {
|
||||
rest.header = signature.unprotectedHeader;
|
||||
}
|
||||
if (i === 0) {
|
||||
jws.payload = payload;
|
||||
}
|
||||
else if (jws.payload !== payload) {
|
||||
throw new JWSInvalid('inconsistent use of JWS Unencoded Payload (RFC7797)');
|
||||
}
|
||||
jws.signatures.push(rest);
|
||||
}
|
||||
return jws;
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
import { prepareVerify, verifySignature, verifyResult } from '../../lib/jws_verify.js';
|
||||
import { JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';
|
||||
import { isObject } from '../../lib/type_checks.js';
|
||||
export async function generalVerify(jws, key, options) {
|
||||
if (!isObject(jws)) {
|
||||
throw new JWSInvalid('General JWS must be an object');
|
||||
}
|
||||
if (!Array.isArray(jws.signatures) || !jws.signatures.every(isObject)) {
|
||||
throw new JWSInvalid('JWS Signatures missing or incorrect type');
|
||||
}
|
||||
let shared;
|
||||
try {
|
||||
if (jws.payload === undefined)
|
||||
throw new Error();
|
||||
shared = prepareVerify(options);
|
||||
}
|
||||
catch {
|
||||
throw new JWSSignatureVerificationFailed();
|
||||
}
|
||||
for (const signature of jws.signatures) {
|
||||
try {
|
||||
if (signature.protected === undefined && signature.header === undefined)
|
||||
throw new Error();
|
||||
if (signature.protected !== undefined && typeof signature.protected !== 'string') {
|
||||
throw new Error();
|
||||
}
|
||||
if (typeof signature.signature !== 'string')
|
||||
throw new Error();
|
||||
if (signature.header !== undefined && !isObject(signature.header))
|
||||
throw new Error();
|
||||
return verifyResult(signature, await verifySignature({
|
||||
header: signature.header,
|
||||
payload: jws.payload,
|
||||
protected: signature.protected,
|
||||
signature: signature.signature,
|
||||
}, shared, key));
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
throw new JWSSignatureVerificationFailed();
|
||||
}
|
||||
Reference in New Issue
Block a user