Path: blob/main/components/gitpod-protocol/src/encryption/key-provider.ts
2500 views
/**1* Copyright (c) 2020 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/56import { injectable, inject } from "inversify";78export interface KeyMetadata {9name: string;10version: number;11}1213export interface Key {14metadata: KeyMetadata;15material: Buffer;16}1718export const KeyProvider = Symbol("KeyProvider");19export interface KeyProvider {20getPrimaryKey(): Key;21getKeyFor(metadata: KeyMetadata): Key;22}2324export type KeyConfig = KeyMetadata & {25/** base64 encoded */26material: string;27primary?: boolean;28};2930export const KeyProviderConfig = Symbol("KeyProviderConfig");31export interface KeyProviderConfig {32keys: KeyConfig[];33}3435@injectable()36export class KeyProviderImpl implements KeyProvider {37static loadKeyConfigFromJsonString(configStr: string): KeyConfig[] {38const keys = (JSON.parse(configStr) || []) as KeyConfig[];39if (!Array.isArray(keys) || keys.length < 0 || 1 !== keys.reduce((p, k) => (k.primary ? p + 1 : p), 0)) {40throw new Error("Invalid key config!");41}42return keys;43}4445constructor(@inject(KeyProviderConfig) protected readonly config: KeyProviderConfig) {}4647protected get keys() {48return this.config.keys;49}5051getPrimaryKey(): Key {52const primaryKey = this.keys.find((key) => !!key.primary);53if (!primaryKey) {54throw new Error("No primary encryption key found!");55}56return this.configToKey(primaryKey);57}5859getKeyFor(metadata: KeyMetadata): Key {60const key = this.keys.find((k) => k.name === metadata.name && k.version === metadata.version);61if (!key) {62throw new Error(`No key found for metadata ${metadata.name}/${metadata.version}`);63}64return this.configToKey(key);65}6667protected configToKey(config: KeyConfig): Key {68return {69metadata: {70name: config.name,71version: config.version,72},73material: Buffer.from(config.material, "base64"),74};75}76}777879