Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
metadata.js166 linesDownload Raw Back to dist
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3    return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.Metadata = void 0;
7const canonical_json_1 = require("@tufjs/canonical-json");
8const util_1 = __importDefault(require("util"));
9const base_1 = require("./base");
10const error_1 = require("./error");
11const root_1 = require("./root");
12const signature_1 = require("./signature");
13const snapshot_1 = require("./snapshot");
14const targets_1 = require("./targets");
15const timestamp_1 = require("./timestamp");
16const utils_1 = require("./utils");
17/***
18 * A container for signed TUF metadata.
19 *
20 * Provides methods to convert to and from json, read and write to and
21 * from JSON and to create and verify metadata signatures.
22 *
23 * ``Metadata[T]`` is a generic container type where T can be any one type of
24 * [``Root``, ``Timestamp``, ``Snapshot``, ``Targets``]. The purpose of this
25 * is to allow static type checking of the signed attribute in code using
26 * Metadata::
27 *
28 * root_md = Metadata[Root].fromJSON("root.json")
29 * # root_md type is now Metadata[Root]. This means signed and its
30 * # attributes like consistent_snapshot are now statically typed and the
31 * # types can be verified by static type checkers and shown by IDEs
32 *
33 * Using a type constraint is not required but not doing so means T is not a
34 * specific type so static typing cannot happen. Note that the type constraint
35 * ``[Root]`` is not validated at runtime (as pure annotations are not available
36 * then).
37 *
38 * Apart from ``expires`` all of the arguments to the inner constructors have
39 * reasonable default values for new metadata.
40 */
41class Metadata {
42    signed;
43    signatures;
44    unrecognizedFields;
45    constructor(signed, signatures, unrecognizedFields) {
46        this.signed = signed;
47        this.signatures = signatures || {};
48        this.unrecognizedFields = unrecognizedFields || {};
49    }
50    sign(signer, append = true) {
51        const bytes = Buffer.from((0, canonical_json_1.canonicalize)(this.signed.toJSON()));
52        const signature = signer(bytes);
53        if (!append) {
54            this.signatures = {};
55        }
56        this.signatures[signature.keyID] = signature;
57    }
58    verifyDelegate(delegatedRole, delegatedMetadata) {
59        let role;
60        let keys = {};
61        switch (this.signed.type) {
62            case base_1.MetadataKind.Root:
63                keys = this.signed.keys;
64                role = this.signed.roles[delegatedRole];
65                break;
66            case base_1.MetadataKind.Targets:
67                if (!this.signed.delegations) {
68                    throw new error_1.ValueError(`No delegations found for ${delegatedRole}`);
69                }
70                keys = this.signed.delegations.keys;
71                if (this.signed.delegations.roles) {
72                    role = this.signed.delegations.roles[delegatedRole];
73                }
74                else if (this.signed.delegations.succinctRoles) {
75                    if (this.signed.delegations.succinctRoles.isDelegatedRole(delegatedRole)) {
76                        role = this.signed.delegations.succinctRoles;
77                    }
78                }
79                break;
80            default:
81                throw new TypeError('invalid metadata type');
82        }
83        if (!role) {
84            throw new error_1.ValueError(`no delegation found for ${delegatedRole}`);
85        }
86        const signingKeys = new Set();
87        role.keyIDs.forEach((keyID) => {
88            const key = keys[keyID];
89            // If we dont' have the key, continue checking other keys
90            if (!key) {
91                return;
92            }
93            try {
94                key.verifySignature(delegatedMetadata);
95                signingKeys.add(key.keyID);
96            }
97            catch (error) {
98                // continue
99            }
100        });
101        if (signingKeys.size < role.threshold) {
102            throw new error_1.UnsignedMetadataError(`${delegatedRole} was signed by ${signingKeys.size}/${role.threshold} keys`);
103        }
104    }
105    equals(other) {
106        if (!(other instanceof Metadata)) {
107            return false;
108        }
109        return (
110        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
111        this.signed.equals(other.signed) &&
112            util_1.default.isDeepStrictEqual(this.signatures, other.signatures) &&
113            util_1.default.isDeepStrictEqual(this.unrecognizedFields, other.unrecognizedFields));
114    }
115    toJSON() {
116        const signatures = Object.values(this.signatures).map((signature) => {
117            return signature.toJSON();
118        });
119        return {
120            signatures,
121            signed: this.signed.toJSON(),
122            ...this.unrecognizedFields,
123        };
124    }
125    static fromJSON(type, data) {
126        const { signed, signatures, ...rest } = data;
127        if (!utils_1.guard.isDefined(signed) || !utils_1.guard.isObject(signed)) {
128            throw new TypeError('signed is not defined');
129        }
130        if (type !== signed._type) {
131            throw new error_1.ValueError(`expected '${type}', got ${signed['_type']}`);
132        }
133        if (!utils_1.guard.isObjectArray(signatures)) {
134            throw new TypeError('signatures is not an array');
135        }
136        let signedObj;
137        switch (type) {
138            case base_1.MetadataKind.Root:
139                signedObj = root_1.Root.fromJSON(signed);
140                break;
141            case base_1.MetadataKind.Timestamp:
142                signedObj = timestamp_1.Timestamp.fromJSON(signed);
143                break;
144            case base_1.MetadataKind.Snapshot:
145                signedObj = snapshot_1.Snapshot.fromJSON(signed);
146                break;
147            case base_1.MetadataKind.Targets:
148                signedObj = targets_1.Targets.fromJSON(signed);
149                break;
150            default:
151                throw new TypeError('invalid metadata type');
152        }
153        const sigMap = {};
154        // Ensure that each signature is unique
155        signatures.forEach((sigData) => {
156            const sig = signature_1.Signature.fromJSON(sigData);
157            if (sigMap[sig.keyID]) {
158                throw new error_1.ValueError(`multiple signatures found for keyid: ${sig.keyID}`);
159            }
160            sigMap[sig.keyID] = sig;
161        });
162        return new Metadata(signedObj, sigMap, rest);
163    }
164}
165exports.Metadata = Metadata;
166 
codekingpro/portable-devtools · Team Ai