"use strict";
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.raw2der = exports.der2raw = void 0;
/* WebCrypto expects the ECDSA signature to be "raw" formated.
 * e.g. concat(r,s) where r and s are padded to key length bytes.
 * The AWS Encryption SDK expects the signature to be DER encoded.
 * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/message-format.html#footer-structure
 */
// @ts-ignore
const asn1_js_1 = __importDefault(require("asn1.js"));
const concat_buffers_1 = require("./concat_buffers");
const material_management_1 = require("@aws-crypto/material-management");
// https://tools.ietf.org/html/rfc3279#section-2.2.2
const ECDSASignature = asn1_js_1.default.define('ECDSASignature', function () {
    this.seq().obj(this.key('r').int(), this.key('s').int());
});
// Map the ECDSA Curve to key lengths
const keyLengthBytes = Object.freeze({
    'P-256': 32,
    'P-384': 48,
});
/**
 * WebCrypto subtle.verify expect the signature to be "raw" formated e.g. concat(r,s)
 * where r and s are padded to the key length in bytes.
 *
 * @param derSignature [Uint8Array] The DER formated signature from an Encryption SDK formated blob
 * @param suite [WebCryptoAlgorithmSuite] The Algorithm suite used to create the signature
 * @returns Uint8Array The raw formated signature (r,s) used to verify in WebCrypto
 */
function der2raw(derSignature, { signatureCurve }) {
    /* Precondition: Do not attempt to RAW format if the suite does not support signing. */
    if (!signatureCurve)
        throw new Error('AlgorithmSuite does not support signing');
    const _keyLengthBytes = keyLengthBytes[signatureCurve];
    // A little more portable than Buffer.from, but not much
    const { r, s } = ECDSASignature.decode(new asn1_js_1.default.bignum.BN(derSignature).toArrayLike(Buffer), 'der');
    const rLength = r.byteLength();
    const sLength = s.byteLength();
    return (0, concat_buffers_1.concatBuffers)(new Uint8Array(_keyLengthBytes - rLength), r.toArrayLike(Uint8Array), new Uint8Array(_keyLengthBytes - sLength), s.toArrayLike(Uint8Array));
}
exports.der2raw = der2raw;
/**
 * WebCrypto subtle.sign returns the signature "raw" formated e.g. concat(r,s)
 * where r and s are padded to the key length in bytes.
 * The Encryption SDK expects the signature to be DER encoded.
 *
 * @param rawSignature [Uint8Array] The "raw" formated signature from WebCrypto subtle.sign
 * @param suite [WebCryptoAlgorithmSuite] The Algorithm suite used to create the signature
 * @returns Uint8Array The DER formated signature
 */
function raw2der(rawSignature, { signatureCurve }) {
    /* Precondition: Do not attempt to DER format if the suite does not support signing. */
    if (!signatureCurve)
        throw new Error('AlgorithmSuite does not support signing');
    const { byteLength } = rawSignature;
    const _keyLengthBytes = keyLengthBytes[signatureCurve];
    /* Precondition: The total raw signature length is twice the key length bytes. */
    (0, material_management_1.needs)(byteLength === 2 * _keyLengthBytes, 'Malformed signature.');
    /* A little more portable than Buffer.from, but not much.
     * DER encoding stores integers as signed values.
     * This means if the first bit is a 1,
     * the value will be interpreted as negative.
     * So an extra byte needs to be added on.
     * This is a problem because "raw" encoding is just r|s.
     * Without this "extra logic" a given DER signature `sig` *may*
     * raw2der(der2raw(sig)) !== sig
     * see: https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 8.3
     * All of this means that s and r **MUST** be passed as BN,
     * and NOT bytes.
     * Otherwise you need to interpret this padding yourself.
     */
    const r = new asn1_js_1.default.bignum.BN(rawSignature.slice(0, _keyLengthBytes));
    const s = new asn1_js_1.default.bignum.BN(rawSignature.slice(_keyLengthBytes));
    return ECDSASignature.encode({ r, s }, 'der');
}
exports.raw2der = raw2der;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNkc2Ffc2lnbmF0dXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VjZHNhX3NpZ25hdHVyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsb0VBQW9FO0FBQ3BFLHNDQUFzQzs7Ozs7O0FBRXRDOzs7O0dBSUc7QUFFSCxhQUFhO0FBQ2Isc0RBQXlCO0FBQ3pCLHFEQUFnRDtBQUNoRCx5RUFJd0M7QUFFeEMsb0RBQW9EO0FBQ3BELE1BQU0sY0FBYyxHQUFHLGlCQUFHLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFO0lBQ2xELElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUE7QUFDMUQsQ0FBQyxDQUFDLENBQUE7QUFFRixxQ0FBcUM7QUFDckMsTUFBTSxjQUFjLEdBQTRDLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDNUUsT0FBTyxFQUFFLEVBQUU7SUFDWCxPQUFPLEVBQUUsRUFBRTtDQUNaLENBQUMsQ0FBQTtBQUVGOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixPQUFPLENBQ3JCLFlBQXdCLEVBQ3hCLEVBQUUsY0FBYyxFQUEyQjtJQUUzQyx1RkFBdUY7SUFDdkYsSUFBSSxDQUFDLGNBQWM7UUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFBO0lBRTVELE1BQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUV0RCx3REFBd0Q7SUFDeEQsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxjQUFjLENBQUMsTUFBTSxDQUNwQyxJQUFJLGlCQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEVBQ25ELEtBQUssQ0FDTixDQUFBO0lBRUQsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFBO0lBQzlCLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQTtJQUU5QixPQUFPLElBQUEsOEJBQWEsRUFDbEIsSUFBSSxVQUFVLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxFQUN6QyxDQUFDLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxFQUN6QixJQUFJLFVBQVUsQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDLEVBQ3pDLENBQUMsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQzFCLENBQUE7QUFDSCxDQUFDO0FBekJELDBCQXlCQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBZ0IsT0FBTyxDQUNyQixZQUF3QixFQUN4QixFQUFFLGNBQWMsRUFBMkI7SUFFM0MsdUZBQXVGO0lBQ3ZGLElBQUksQ0FBQyxjQUFjO1FBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMseUNBQXlDLENBQUMsQ0FBQTtJQUU1RCxNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsWUFBWSxDQUFBO0lBRW5DLE1BQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUV0RCxpRkFBaUY7SUFDakYsSUFBQSwyQkFBSyxFQUFDLFVBQVUsS0FBSyxDQUFDLEdBQUcsZUFBZSxFQUFFLHNCQUFzQixDQUFDLENBQUE7SUFFakU7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsTUFBTSxDQUFDLEdBQUcsSUFBSSxpQkFBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQTtJQUNuRSxNQUFNLENBQUMsR0FBRyxJQUFJLGlCQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUE7SUFFaEUsT0FBTyxjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFBO0FBQy9DLENBQUM7QUFoQ0QsMEJBZ0NDIn0=