update types

This commit is contained in:
microshine 2022-05-24 15:05:52 +03:00
parent 181477c574
commit 5a5412ecd3
26 changed files with 83 additions and 74 deletions

View File

@ -2,25 +2,6 @@ import * as types from "@peculiar/webcrypto-types";
import { OperationError } from "../errors";
import { CryptoKey } from "../crypto_key";
import { ProviderCrypto } from "../provider";
import { BufferSource } from "pvtsutils";
export interface DesKeyAlgorithm extends types.KeyAlgorithm {
length: number;
}
export interface DesParams extends types.Algorithm {
iv: BufferSource;
}
export interface DesKeyGenParams extends types.Algorithm {
length: number;
}
export interface DesDerivedKeyParams extends types.Algorithm {
length: number;
}
export interface DesImportParams extends types.Algorithm { }
export abstract class DesProvider extends ProviderCrypto {
@ -41,7 +22,7 @@ export abstract class DesProvider extends ProviderCrypto {
}
}
public override checkGenerateKeyParams(algorithm: DesKeyGenParams) {
public override checkGenerateKeyParams(algorithm: types.DesKeyGenParams) {
// length
this.checkRequiredProperty(algorithm, "length");
if (typeof algorithm.length !== "number") {
@ -52,14 +33,14 @@ export abstract class DesProvider extends ProviderCrypto {
}
}
public override checkDerivedKeyParams(algorithm: DesDerivedKeyParams) {
public override checkDerivedKeyParams(algorithm: types.DesDerivedKeyParams) {
this.checkGenerateKeyParams(algorithm);
}
public abstract override onGenerateKey(algorithm: DesKeyGenParams, extractable: boolean, keyUsages: types.KeyUsage[], ...args: any[]): Promise<CryptoKey>;
public abstract override onGenerateKey(algorithm: types.DesKeyGenParams, extractable: boolean, keyUsages: types.KeyUsage[], ...args: any[]): Promise<CryptoKey>;
public abstract override onExportKey(format: types.KeyFormat, key: CryptoKey, ...args: any[]): Promise<types.JsonWebKey | ArrayBuffer>;
public abstract override onImportKey(format: types.KeyFormat, keyData: types.JsonWebKey | ArrayBuffer, algorithm: DesImportParams, extractable: boolean, keyUsages: types.KeyUsage[], ...args: any[]): Promise<CryptoKey>;
public abstract override onEncrypt(algorithm: DesParams, key: CryptoKey, data: ArrayBuffer, ...args: any[]): Promise<ArrayBuffer>;
public abstract override onDecrypt(algorithm: DesParams, key: CryptoKey, data: ArrayBuffer, ...args: any[]): Promise<ArrayBuffer>;
public abstract override onImportKey(format: types.KeyFormat, keyData: types.JsonWebKey | ArrayBuffer, algorithm: types.DesImportParams, extractable: boolean, keyUsages: types.KeyUsage[], ...args: any[]): Promise<CryptoKey>;
public abstract override onEncrypt(algorithm: types.DesParams, key: CryptoKey, data: ArrayBuffer, ...args: any[]): Promise<ArrayBuffer>;
public abstract override onDecrypt(algorithm: types.DesParams, key: CryptoKey, data: ArrayBuffer, ...args: any[]): Promise<ArrayBuffer>;
}

View File

@ -1,7 +1,7 @@
import { CryptoError } from "./crypto";
export class RequiredPropertyError extends CryptoError {
constructor(propName: string) {
super(`${propName}: Missing required property`);
constructor(propName: string, target?: string) {
super(`${propName}: Missing required property${target ? ` in ${target}` : ""}`);
}
}

View File

@ -1,7 +1,7 @@
import * as types from "@peculiar/webcrypto-types";
import { BufferSourceConverter } from "pvtsutils";
import { AlgorithmError, CryptoError, OperationError, RequiredPropertyError, UnsupportedOperationError } from "./errors";
import { isJWK } from "./utils";
import { assertJWK } from "./utils";
export interface IProviderCheckOptions {
keyUsage?: boolean;
@ -256,9 +256,7 @@ export abstract class ProviderCrypto {
throw new TypeError("keyData: Cannot be empty on empty on key importing");
}
if (format === "jwk") {
if (!isJWK(keyData)) {
throw new TypeError("keyData: Is not JsonWebToken");
}
assertJWK(keyData, "keyData");
} else if (!BufferSourceConverter.isBufferSource(keyData)) {
throw new TypeError("keyData: Is not ArrayBufferView or ArrayBuffer");
}

View File

@ -1,26 +1,19 @@
import { ProviderCrypto } from "../provider";
import * as types from "@peculiar/webcrypto-types";
export interface ShakeParams extends types.Algorithm {
/**
* Output length in bytes
*/
length?: number;
}
export abstract class ShakeProvider extends ProviderCrypto {
public usages = [];
public defaultLength = 0;
public override digest(algorithm: types.Algorithm, data: ArrayBuffer, ...args: any[]): Promise<ArrayBuffer>;
public override digest(algorithm: types.ShakeParams, data: ArrayBuffer, ...args: any[]): Promise<ArrayBuffer>;
public override digest(...args: any[]): Promise<ArrayBuffer> {
args[0] = { length: this.defaultLength, ...args[0] };
return super.digest.apply(this, args as unknown as any);
}
public override checkDigest(algorithm: ShakeParams, data: ArrayBuffer): void {
public override checkDigest(algorithm: types.ShakeParams, data: ArrayBuffer): void {
super.checkDigest(algorithm, data);
const length = algorithm.length || 0;
@ -32,6 +25,6 @@ export abstract class ShakeProvider extends ProviderCrypto {
}
}
public abstract override onDigest(algorithm: Required<ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer>;
public abstract override onDigest(algorithm: Required<types.ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer>;
}

View File

@ -23,7 +23,7 @@ export class SubtleCrypto implements types.SubtleCrypto {
return "SubtleCrypto";
}
public async digest(algorithm: types.AlgorithmIdentifier, data: BufferSource, ...args: any[]): Promise<ArrayBuffer>;
public async digest(algorithm: types.AlgorithmIdentifier | types.ShakeParams, data: BufferSource, ...args: any[]): Promise<ArrayBuffer>;
public async digest(...args: any[]): Promise<ArrayBuffer> {
this.checkRequiredArguments(args, 2, "digest");
const [algorithm, data, ...params] = args;
@ -52,7 +52,7 @@ export class SubtleCrypto implements types.SubtleCrypto {
return result;
}
public async sign(algorithm: types.AlgorithmIdentifier, key: types.CryptoKey, data: BufferSource, ...args: any[]): Promise<ArrayBuffer>;
public async sign(algorithm: types.SignAlgorithms, key: types.CryptoKey, data: BufferSource, ...args: any[]): Promise<ArrayBuffer>;
public async sign(...args: any[]): Promise<ArrayBuffer> {
this.checkRequiredArguments(args, 3, "sign");
const [algorithm, key, data, ...params] = args;
@ -67,7 +67,7 @@ export class SubtleCrypto implements types.SubtleCrypto {
return result;
}
public async verify(algorithm: types.AlgorithmIdentifier, key: types.CryptoKey, signature: BufferSource, data: BufferSource, ...args: any[]): Promise<boolean>;
public async verify(algorithm: types.SignAlgorithms, key: types.CryptoKey, signature: BufferSource, data: BufferSource, ...args: any[]): Promise<boolean>;
public async verify(...args: any[]): Promise<boolean> {
this.checkRequiredArguments(args, 4, "verify");
const [algorithm, key, signature, data, ...params] = args;

View File

@ -1,5 +1,11 @@
import * as types from "@peculiar/webcrypto-types";
export function isJWK(data: any): data is types.JsonWebKey {
return typeof data === "object" && "kty" in data;
export function isJWK(data: unknown): data is types.JsonWebKey {
return !!(data && typeof data === "object" && "kty" in data);
}
export function assertJWK(data: unknown, paramName: string): asserts data is types.JsonWebKey {
if (!isJWK(data)) {
throw new TypeError(`${paramName}: is not JsonWebKey`);
}
}

View File

@ -7,19 +7,19 @@ class DesTestProvider extends core.DesProvider {
public ivSize = 8;
public name = "DES-TEST";
public onGenerateKey(algorithm: import("../src/des").DesKeyGenParams, extractable: boolean, keyUsages: types.KeyUsage[]): Promise<core.CryptoKey> {
public onGenerateKey(algorithm: types.DesKeyGenParams, extractable: boolean, keyUsages: types.KeyUsage[]): Promise<core.CryptoKey> {
throw new Error("Method not implemented.");
}
public onExportKey(format: types.KeyFormat, key: core.CryptoKey): Promise<types.JsonWebKey | ArrayBuffer> {
throw new Error("Method not implemented.");
}
public onImportKey(format: types.KeyFormat, keyData: types.JsonWebKey | ArrayBuffer, algorithm: import("../src/des").DesImportParams, extractable: boolean, keyUsages: types.KeyUsage[]): Promise<core.CryptoKey> {
public onImportKey(format: types.KeyFormat, keyData: types.JsonWebKey | ArrayBuffer, algorithm: types.DesImportParams, extractable: boolean, keyUsages: types.KeyUsage[]): Promise<core.CryptoKey> {
throw new Error("Method not implemented.");
}
public onEncrypt(algorithm: import("../src/des").DesParams, key: core.CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer> {
public onEncrypt(algorithm: types.DesParams, key: core.CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer> {
throw new Error("Method not implemented.");
}
public onDecrypt(algorithm: import("../src/des").DesParams, key: core.CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer> {
public onDecrypt(algorithm: types.DesParams, key: core.CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer> {
throw new Error("Method not implemented.");
}
}

View File

@ -3,13 +3,13 @@ import * as core from "@peculiar/webcrypto-core";
import * as types from "@peculiar/webcrypto-types";
class TestShake128Provider extends core.Shake128Provider {
public async onDigest(algorithm: Required<core.ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer> {
public async onDigest(algorithm: Required<types.ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer> {
return new ArrayBuffer(algorithm.length);
}
}
class TestShake256Provider extends core.Shake256Provider {
public async onDigest(algorithm: Required<core.ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer> {
public async onDigest(algorithm: Required<types.ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer> {
return new ArrayBuffer(algorithm.length);
}
}

View File

@ -50,7 +50,7 @@ export class DesCrypto {
return key;
}
public static async encrypt(algorithm: core.DesParams, key: DesCryptoKey, data: Uint8Array): Promise<ArrayBuffer> {
public static async encrypt(algorithm: types.DesParams, key: DesCryptoKey, data: Uint8Array): Promise<ArrayBuffer> {
switch (algorithm.name.toUpperCase()) {
case "DES-CBC":
return this.encryptDesCBC(algorithm, key, Buffer.from(data));
@ -61,7 +61,7 @@ export class DesCrypto {
}
}
public static async decrypt(algorithm: core.DesParams, key: CryptoKey, data: Uint8Array): Promise<ArrayBuffer> {
public static async decrypt(algorithm: types.DesParams, key: CryptoKey, data: Uint8Array): Promise<ArrayBuffer> {
if (!(key instanceof DesCryptoKey)) {
throw new Error("key: Is not DesCryptoKey");
}
@ -76,7 +76,7 @@ export class DesCrypto {
}
}
public static async encryptDesCBC(algorithm: core.DesParams, key: DesCryptoKey, data: Buffer) {
public static async encryptDesCBC(algorithm: types.DesParams, key: DesCryptoKey, data: Buffer) {
const cipher = crypto.createCipheriv(`des-cbc`, key.data, new Uint8Array(algorithm.iv as ArrayBuffer));
let enc = cipher.update(data);
enc = Buffer.concat([enc, cipher.final()]);
@ -84,14 +84,14 @@ export class DesCrypto {
return res;
}
public static async decryptDesCBC(algorithm: core.DesParams, key: DesCryptoKey, data: Buffer) {
public static async decryptDesCBC(algorithm: types.DesParams, key: DesCryptoKey, data: Buffer) {
const decipher = crypto.createDecipheriv(`des-cbc`, key.data, new Uint8Array(algorithm.iv as ArrayBuffer));
let dec = decipher.update(data);
dec = Buffer.concat([dec, decipher.final()]);
return new Uint8Array(dec).buffer;
}
public static async encryptDesEDE3CBC(algorithm: core.DesParams, key: DesCryptoKey, data: Buffer) {
public static async encryptDesEDE3CBC(algorithm: types.DesParams, key: DesCryptoKey, data: Buffer) {
const cipher = crypto.createCipheriv(`des-ede3-cbc`, key.data, Buffer.from(algorithm.iv as ArrayBuffer));
let enc = cipher.update(data);
enc = Buffer.concat([enc, cipher.final()]);
@ -99,7 +99,7 @@ export class DesCrypto {
return res;
}
public static async decryptDesEDE3CBC(algorithm: core.DesParams, key: DesCryptoKey, data: Buffer) {
public static async decryptDesEDE3CBC(algorithm: types.DesParams, key: DesCryptoKey, data: Buffer) {
const decipher = crypto.createDecipheriv(`des-ede3-cbc`, key.data, new Uint8Array(algorithm.iv as ArrayBuffer));
let dec = decipher.update(data);
dec = Buffer.concat([dec, decipher.final()]);

View File

@ -5,7 +5,7 @@ import { setCryptoKey, getCryptoKey } from "../storage";
import { DesCrypto } from "./crypto";
import { DesCryptoKey } from "./key";
export type DesCbcParams = core.DesParams;
export type DesCbcParams = types.DesParams;
export class DesCbcProvider extends core.DesProvider {
@ -13,7 +13,7 @@ export class DesCbcProvider extends core.DesProvider {
public ivSize = 8;
public name = "DES-CBC";
public async onGenerateKey(algorithm: core.DesKeyGenParams, extractable: boolean, keyUsages: types.KeyUsage[]): Promise<core.CryptoKey> {
public async onGenerateKey(algorithm: types.DesKeyGenParams, extractable: boolean, keyUsages: types.KeyUsage[]): Promise<core.CryptoKey> {
const key = await DesCrypto.generateKey(
{
name: this.name,

View File

@ -5,7 +5,7 @@ import { setCryptoKey, getCryptoKey } from "../storage";
import { DesCrypto } from "./crypto";
import { DesCryptoKey } from "./key";
export type DesEde3CbcParams = core.DesParams;
export type DesEde3CbcParams = types.DesParams;
export class DesEde3CbcProvider extends core.DesProvider {
@ -13,7 +13,7 @@ export class DesEde3CbcProvider extends core.DesProvider {
public ivSize = 8;
public name = "DES-EDE3-CBC";
public async onGenerateKey(algorithm: core.DesKeyGenParams, extractable: boolean, keyUsages: types.KeyUsage[]): Promise<core.CryptoKey> {
public async onGenerateKey(algorithm: types.DesKeyGenParams, extractable: boolean, keyUsages: types.KeyUsage[]): Promise<core.CryptoKey> {
const key = await DesCrypto.generateKey(
{
name: this.name,

View File

@ -1,13 +1,14 @@
import { JsonProp } from "@peculiar/json-schema";
import * as jsonSchema from "@peculiar/json-schema";
import * as core from "@peculiar/webcrypto-core";
import * as types from "@peculiar/webcrypto-types";
import { JsonBase64UrlConverter } from "../../converters";
import { SymmetricKey } from "../../keys";
export class DesCryptoKey extends SymmetricKey {
public override algorithm!: core.DesKeyAlgorithm;
public override algorithm!: types.DesKeyAlgorithm;
@JsonProp({ name: "k", converter: JsonBase64UrlConverter })
@jsonSchema.JsonProp({ name: "k", converter: JsonBase64UrlConverter })
public override data!: Buffer;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment

View File

@ -1,9 +1,9 @@
import * as crypto from "crypto";
import * as core from "@peculiar/webcrypto-core";
import * as types from "@peculiar/webcrypto-types";
export class ShakeCrypto {
public static digest(algorithm: Required<core.ShakeParams>, data: ArrayBuffer) {
public static digest(algorithm: Required<types.ShakeParams>, data: ArrayBuffer) {
const hash = crypto.createHash(algorithm.name.toLowerCase(), { outputLength: algorithm.length })
.update(Buffer.from(data)).digest();

View File

@ -1,9 +1,10 @@
import * as core from "@peculiar/webcrypto-core";
import * as types from "@peculiar/webcrypto-types";
import { ShakeCrypto } from "./crypto";
export class Shake128Provider extends core.Shake128Provider {
public override async onDigest(algorithm: Required<core.ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer> {
public override async onDigest(algorithm: Required<types.ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer> {
return ShakeCrypto.digest(algorithm, data);
}

View File

@ -1,9 +1,10 @@
import * as core from "@peculiar/webcrypto-core";
import * as types from "@peculiar/webcrypto-types";
import { ShakeCrypto } from "./crypto";
export class Shake256Provider extends core.Shake256Provider {
public override async onDigest(algorithm: Required<core.ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer> {
public override async onDigest(algorithm: Required<types.ShakeParams>, data: ArrayBuffer): Promise<ArrayBuffer> {
return ShakeCrypto.digest(algorithm, data);
}

View File

@ -239,7 +239,7 @@ context("Crypto", () => {
});
it("128 byte length", async () => {
const hash = await crypto.subtle.digest({ name: "shake128", length: 128 } as core.ShakeParams, data);
const hash = await crypto.subtle.digest({ name: "shake128", length: 128 } as types.ShakeParams, data);
assert.strictEqual(Buffer.from(hash).toString("hex"), "ae3bdcf04986a8e7ddd99ac948254693fc32ca6ce3ed278c0c54127f072ba21e977d76aa76cab8f85f61c3e1fb7dab42c6b96d39f96fbd8cdcba7121e28cc97bb51f277a00398f99a9e6f11d027473cbffb3ac4ce444e2e8284caeca4e62f725d340fa3519eec7ca3eb4188607c26b0ecdf3750beba8882d6f2b734960cca914");
});
@ -255,7 +255,7 @@ context("Crypto", () => {
});
it("256 byte length", async () => {
const hash = await crypto.subtle.digest({ name: "shake256", length: 256 } as core.ShakeParams, data);
const hash = await crypto.subtle.digest({ name: "shake256", length: 256 } as types.ShakeParams, data);
assert.strictEqual(Buffer.from(hash).toString("hex"), "be15253026b9a85e01ae54b1939284e8e514fbdad2a3bd5c1c0f437e60548e262dd68c2a2f932847f9610eeb51f8ba1a180ca878c788e900d899538d45c9c4a6f1bf10d8502a7ccbd9fd540bd856591000700e10130673ef970ffb788afe08426648a216d032733b71e85f128f1ed9e4c8bd910b5000e8c381afb45735680eaf7cb5bf1ae4265ee0822dfe6a9426ff21e309398df57cbf5861f5947f3d261e2d4517ff0d1be988e7014a09c4312d37010cf0e47468c1cf832e6a61e9d9fe3b67e6ab265cb6d95ad7a1f863d71e0e6ed5cd17d568b86e99d84bdb970a580f551017b501ae6761d2d6de76a64385dc10f27d18c2564a6bfbfb1e3f335010bebdf8");
});

View File

@ -195,6 +195,9 @@ export interface CryptoKey {
readonly usages: KeyUsage[];
}
export type DigestAlgorithms = AlgorithmIdentifier | ShakeParams;
export type SignAlgorithms = AlgorithmIdentifier | RsaPssParams | EcdsaParams;
/**
* This Web Crypto API export interface provides a number of low-level cryptographic functions.
* It is accessed via the Crypto.subtle properties available in a window context (via Window.crypto).
@ -205,7 +208,7 @@ export interface SubtleCrypto {
decrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise<any>;
deriveBits(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, length: number): Promise<ArrayBuffer>;
deriveKey(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, derivedKey: AlgorithmIdentifier | AesDerivedKeyParams | HmacImportParams | HkdfParams | Pbkdf2Params, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
digest(algorithm: AlgorithmIdentifier, data: BufferSource): Promise<ArrayBuffer>;
digest(algorithm: DigestAlgorithms, data: BufferSource): Promise<ArrayBuffer>;
encrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise<any>;
exportKey(format: "jwk", key: CryptoKey): Promise<JsonWebKey>;
exportKey(format: Exclude<KeyFormat, "jwk">, key: CryptoKey): Promise<ArrayBuffer>;
@ -216,9 +219,9 @@ export interface SubtleCrypto {
importKey(format: "jwk", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
importKey(format: Exclude<KeyFormat, "jwk">, keyData: BufferSource, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
importKey(format: KeyFormat, keyData: BufferSource | JsonWebKey, algorithm: AlgorithmIdentifier, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
sign(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;
sign(algorithm: SignAlgorithms, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;
unwrapKey(format: KeyFormat, wrappedKey: BufferSource, unwrappingKey: CryptoKey, unwrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, unwrappedKeyAlgorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
verify(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, signature: BufferSource, data: BufferSource): Promise<boolean>;
verify(algorithm: SignAlgorithms, key: CryptoKey, signature: BufferSource, data: BufferSource): Promise<boolean>;
wrapKey(format: KeyFormat, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams): Promise<ArrayBuffer>;
}
@ -380,3 +383,28 @@ export type PreparedHashedAlgorithm<T extends Algorithm = Algorithm> = Omit<T, "
export interface AesCmacParams extends Algorithm {
length: number;
}
export interface ShakeParams extends Algorithm {
/**
* Output length in bytes
*/
length?: number;
}
export interface DesKeyAlgorithm extends KeyAlgorithm {
length: number;
}
export interface DesParams extends Algorithm {
iv: BufferSource;
}
export interface DesKeyGenParams extends Algorithm {
length: number;
}
export interface DesDerivedKeyParams extends Algorithm {
length: number;
}
export interface DesImportParams extends Algorithm { }