68 lines
2.2 KiB
JavaScript
68 lines
2.2 KiB
JavaScript
|
import { FlattenedSign } from '../flattened/sign.js';
|
||
|
import { JWSInvalid } from '../../util/errors.js';
|
||
|
class IndividualSignature {
|
||
|
constructor(sig, key, options) {
|
||
|
this.parent = sig;
|
||
|
this.key = key;
|
||
|
this.options = options;
|
||
|
}
|
||
|
setProtectedHeader(protectedHeader) {
|
||
|
if (this.protectedHeader) {
|
||
|
throw new TypeError('setProtectedHeader can only be called once');
|
||
|
}
|
||
|
this.protectedHeader = protectedHeader;
|
||
|
return this;
|
||
|
}
|
||
|
setUnprotectedHeader(unprotectedHeader) {
|
||
|
if (this.unprotectedHeader) {
|
||
|
throw new TypeError('setUnprotectedHeader can only be called once');
|
||
|
}
|
||
|
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 {
|
||
|
constructor(payload) {
|
||
|
this._signatures = [];
|
||
|
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');
|
||
|
}
|
||
|
const jws = {
|
||
|
signatures: [],
|
||
|
payload: '',
|
||
|
};
|
||
|
for (let i = 0; i < this._signatures.length; i++) {
|
||
|
const signature = this._signatures[i];
|
||
|
const flattened = new FlattenedSign(this._payload);
|
||
|
flattened.setProtectedHeader(signature.protectedHeader);
|
||
|
flattened.setUnprotectedHeader(signature.unprotectedHeader);
|
||
|
const { payload, ...rest } = await flattened.sign(signature.key, signature.options);
|
||
|
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;
|
||
|
}
|
||
|
}
|