@confluentinc/schemaregistry
Version:
Node.js client for Confluent Schema Registry
133 lines (132 loc) • 4.42 kB
JavaScript
;
/**
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AesGcm = void 0;
exports.fromRawKey = fromRawKey;
const aead_1 = require("./aead");
const security_exception_1 = require("./exception/security_exception");
const Bytes = __importStar(require("./bytes"));
const Random = __importStar(require("./random"));
const Validators = __importStar(require("./validators"));
const crypto = __importStar(require("crypto"));
/**
* The only supported IV size.
*
*/
const IV_SIZE_IN_BYTES = 12;
/**
* The only supported tag size.
*
*/
const TAG_SIZE_IN_BITS = 128;
/**
* Implementation of AES-GCM.
*
*/
class AesGcm extends aead_1.Aead {
constructor(key) {
super();
this.key = key;
}
/**
*/
async encrypt(plaintext, associatedData) {
Validators.requireUint8Array(plaintext);
if (associatedData != null) {
Validators.requireUint8Array(associatedData);
}
const iv = Random.randBytes(IV_SIZE_IN_BYTES);
const alg = {
'name': 'AES-GCM',
'iv': iv,
'tagLength': TAG_SIZE_IN_BITS
};
if (associatedData) {
alg['additionalData'] = associatedData;
}
const ciphertext = await crypto.subtle.encrypt(alg, this.key, plaintext);
return Bytes.concat(iv, new Uint8Array(ciphertext));
}
/**
*/
async decrypt(ciphertext, associatedData) {
Validators.requireUint8Array(ciphertext);
if (ciphertext.length < IV_SIZE_IN_BYTES + TAG_SIZE_IN_BITS / 8) {
throw new security_exception_1.SecurityException('ciphertext too short');
}
if (associatedData != null) {
Validators.requireUint8Array(associatedData);
}
const iv = new Uint8Array(IV_SIZE_IN_BYTES);
iv.set(ciphertext.subarray(0, IV_SIZE_IN_BYTES));
const alg = {
'name': 'AES-GCM',
'iv': iv,
'tagLength': TAG_SIZE_IN_BITS
};
if (associatedData) {
alg['additionalData'] = associatedData;
}
try {
return new Uint8Array(await crypto.subtle.decrypt(alg, this.key, new Uint8Array(ciphertext.subarray(IV_SIZE_IN_BYTES))));
// Preserving old behavior when moving to
// https://www.typescriptlang.org/tsconfig#useUnknownInCatchVariables
// tslint:disable-next-line:no-any
}
catch (e) {
throw new security_exception_1.SecurityException(e.toString());
}
}
}
exports.AesGcm = AesGcm;
async function fromRawKey(key) {
Validators.requireUint8Array(key);
Validators.validateAesKeySize(key.length);
const webCryptoKey = await crypto.subtle.importKey(
/* format */
'raw', key,
/* keyData */
{ 'name': 'AES-GCM', 'length': key.length },
/* algo */
false,
/* extractable*/
['encrypt', 'decrypt']);
/* usage */
return new AesGcm(webCryptoKey);
}