@casual-simulation/crypto 2.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/HashHelpers.js ADDED
@@ -0,0 +1,72 @@
1
+ import { sha256 } from 'hash.js';
2
+ import stringify from 'fast-json-stable-stringify';
3
+ import { randomBytes } from 'tweetnacl';
4
+ import { deriveKey } from './Encryption';
5
+ import { fromByteArray, toByteArray } from 'base64-js';
6
+ /**
7
+ * Calculates the SHA-256 hash of the given object.
8
+ * @param obj The object to calculate the hash of.
9
+ */
10
+ export function getHash(obj) {
11
+ const json = stringify(obj);
12
+ let sha = sha256();
13
+ sha.update(json);
14
+ return sha.digest('hex');
15
+ }
16
+ /**
17
+ * Calculates the SHA-256 hash of the given object and
18
+ * returns a byte buffer containing the hash.
19
+ * @param obj The object to hash.
20
+ */
21
+ export function getHashBuffer(obj) {
22
+ const json = stringify(obj);
23
+ let sha = sha256();
24
+ sha.update(json);
25
+ return Buffer.from(sha.digest());
26
+ }
27
+ /**
28
+ * Hashes the given password using scrypt and returns the result.
29
+ * @param password The password that should be hashed.
30
+ */
31
+ export function hashPassword(password) {
32
+ if (!password) {
33
+ throw new Error('Invalid password. Must not be null or undefined.');
34
+ }
35
+ const salt = randomBytes(16);
36
+ const textEncoder = new TextEncoder();
37
+ const passwordBytes = textEncoder.encode(password);
38
+ const hashBytes = deriveKey(passwordBytes, salt);
39
+ return `vP1.${fromByteArray(hashBytes.salt)}.${fromByteArray(hashBytes.hash)}`;
40
+ }
41
+ /**
42
+ * Verifies that the given password matches the given hash.
43
+ * @param password The password to check.
44
+ * @param hash The hash to check the password against.
45
+ */
46
+ export function verifyPassword(password, hash) {
47
+ if (!password) {
48
+ throw new Error('Invalid password. Must not be null or undefined.');
49
+ }
50
+ if (!hash) {
51
+ throw new Error('Invalid hash. Must not be null or undefined.');
52
+ }
53
+ if (!hash.startsWith('vP1.')) {
54
+ throw new Error('Invalid hash. Must start with "vP1."');
55
+ }
56
+ const withoutVersion = hash.slice('vP1.'.length);
57
+ let nextPeriod = withoutVersion.indexOf('.');
58
+ if (nextPeriod < 0) {
59
+ return false;
60
+ }
61
+ const saltBase64 = withoutVersion.slice(0, nextPeriod);
62
+ const hashBase64 = withoutVersion.slice(nextPeriod + 1);
63
+ if (hashBase64.length <= 0) {
64
+ return false;
65
+ }
66
+ const textEncoder = new TextEncoder();
67
+ const passwordBytes = textEncoder.encode(password);
68
+ const salt = toByteArray(saltBase64);
69
+ const hashBytes = deriveKey(passwordBytes, salt);
70
+ return fromByteArray(hashBytes.hash) === hashBase64;
71
+ }
72
+ //# sourceMappingURL=HashHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HashHelpers.js","sourceRoot":"","sources":["HashHelpers.ts"],"names":[],"mappings":"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"}
package/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Casual Simulation, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Crypto
2
+
3
+ [![npm (scoped)](https://img.shields.io/npm/v/@casual-simulation/crypto.svg)](https://www.npmjs.com/package/@casual-simulation/crypto)
4
+
5
+ A common set of crypto helpers.
6
+
7
+ Defines a common interface for crypto implementations between web browsers and Node.js. (Currently only signing/verification and SHA-256 hashing is implemented)
8
+
9
+ ## Installation
10
+
11
+ ```
12
+ npm install @casual-simulation/crypto
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```js
18
+ // ES6-style imports are required.
19
+ // If you are running in an environment that does not support ES Modules,
20
+ // then use Webpack or Babel to transpile to the format you want. (like CommonJS)
21
+ import { getHash, parsePublicPEMKey } from '@casual-simulation/crypto';
22
+
23
+ let myHash = getHash('Hello, World');
24
+
25
+ console.log('Hash: ', myHash);
26
+ // Hash: 03675ac53ff9cd1535ccc7dfcdfa2c458c5218371f418dc136f2d19ac1fbe8a5
27
+
28
+ let publicKeyPEM = `-----BEGIN PUBLIC KEY-----
29
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAryQICCl6NZ5gDKrnSztO
30
+ 3Hy8PEUcuyvg/ikC+VcIo2SFFSf18a3IMYldIugqqqZCs4/4uVW3sbdLs/6PfgdX
31
+ 7O9D22ZiFWHPYA2k2N744MNiCD1UE+tJyllUhSblK48bn+v1oZHCM0nYQ2NqUkvS
32
+ j+hwUU3RiWl7x3D2s9wSdNt7XUtW05a/FXehsPSiJfKvHJJnGOX0BgTvkLnkAOTd
33
+ OrUZ/wK69Dzu4IvrN4vs9Nes8vbwPa/ddZEzGR0cQMt0JBkhk9kU/qwqUseP1QRJ
34
+ 5I1jR4g8aYPL/ke9K35PxZWuDp3U0UPAZ3PjFAh+5T+fc7gzCs9dPzSHloruU+gl
35
+ FQIDAQAB
36
+ -----END PUBLIC KEY-----`;
37
+
38
+ let publicKeyBytes = parsePublicPEMKey(publicKeyPEM);
39
+ console.log(publicKeyBytes.byteLength);
40
+ ```
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The possible signature algorithm types.
3
+ */
4
+ export declare type SignatureAlgorithmType = ECDSA_SHA256_NISTP256;
5
+ /**
6
+ * Defines a signature algorithm that uses ECDSA Curve P-256 for signing and verification
7
+ * and SHA-256 for message integrity.
8
+ *
9
+ * Basically this gives us 2 things:
10
+ * 1. A digital signature. This means we can verify that only the party with the private key could have created a message.
11
+ * 2. A hash. This means we can verify that the data hasn't changed while in transit. This helps prevent chosen ciphertext attacks because
12
+ * it's supposed to catch any changes to the ciphertext before signature verification occurs.
13
+ */
14
+ export declare type ECDSA_SHA256_NISTP256 = 'ECDSA-SHA256-NISTP256';
15
+ //# sourceMappingURL=SignatureAlgorithm.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SignatureAlgorithm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignatureAlgorithm.js","sourceRoot":"","sources":["SignatureAlgorithm.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Creates a keypair that can be used for digitally signing data.
3
+ *
4
+ * The returned keypair contains a version number at the beginning which determines the format of the following data.
5
+ *
6
+ * v1 keypairs use ed25519.
7
+ * The output string is formatting as following with periods between the components:
8
+ * 1. The version number (vK1) - the K is for keypair
9
+ * 2. The base64 of the public key.
10
+ * 3. The base64 of the encrypted private key.
11
+ *
12
+ * @param password The password that should be used to encrypt the private key of the keypair.
13
+ */
14
+ export declare function keypair(password: string): string;
15
+ /**
16
+ * Creates a version 1 keypair that can be used for digitally signing data.
17
+ *
18
+ * The returned keypair contains a version number at the beginning which determines the format of the following data.
19
+ *
20
+ * v1 keypairs use ed25519.
21
+ * The output string is formatting as following with periods between the components:
22
+ * 1. The version number (vK1) - The K is for keypair
23
+ * 2. The base64 of the public key.
24
+ * 3. The base64 of the encrypted private key.
25
+ *
26
+ * @param password The password that should be used to encrypt the private key of the keypair.
27
+ */
28
+ export declare function keypairV1(password: string): string;
29
+ /**
30
+ * Creates a version 1 signature from the given keypair and returns the result.
31
+ *
32
+ * v1 signatures use ed25519.
33
+ * The output string is formatted as following with periods between the components:
34
+ * 1. The version number (vS1) - THe S is for signature.
35
+ * 2. The base64 of the signature.
36
+ *
37
+ * @param keypair The keypair to use.
38
+ * @param password The password that is used to decrypt the private key.
39
+ * @param data The data to sign.
40
+ */
41
+ export declare function sign(keypair: string, password: string, data: Uint8Array): string;
42
+ /**
43
+ * Creates a version 1 signature from the given keypair and returns the result.
44
+ *
45
+ * v1 signatures use ed25519.
46
+ * The output string is formatted as following with periods between the components:
47
+ * 1. The version number (vS1) - THe S is for signature.
48
+ * 2. The base64 of the signature.
49
+ *
50
+ * @param keypair The keypair to use.
51
+ * @param password The password that is used to decrypt the private key.
52
+ * @param data The data to sign.
53
+ */
54
+ export declare function signV1(keypair: string, password: string, data: Uint8Array): string;
55
+ /**
56
+ * Validates that the given signature was created by the given keypair for the given data.
57
+ * @param keypair The keypair.
58
+ * @param signature The signature to validate.
59
+ * @param data The data that was signed.
60
+ */
61
+ export declare function verify(keypair: string, signature: string, data: Uint8Array): boolean;
62
+ /**
63
+ * Validates a signature that was created by signV1().
64
+ * @param keypair The keypair that created the signature.
65
+ * @param signature The signature.
66
+ * @param data The data.
67
+ */
68
+ export declare function verifyV1(keypair: string, signature: string, data: Uint8Array): boolean;
69
+ //# sourceMappingURL=Signatures.d.ts.map
package/Signatures.js ADDED
@@ -0,0 +1,165 @@
1
+ import { sign as signImpl } from 'tweetnacl';
2
+ import { encrypt, decrypt } from './Encryption';
3
+ import { fromByteArray, toByteArray } from 'base64-js';
4
+ /**
5
+ * Creates a keypair that can be used for digitally signing data.
6
+ *
7
+ * The returned keypair contains a version number at the beginning which determines the format of the following data.
8
+ *
9
+ * v1 keypairs use ed25519.
10
+ * The output string is formatting as following with periods between the components:
11
+ * 1. The version number (vK1) - the K is for keypair
12
+ * 2. The base64 of the public key.
13
+ * 3. The base64 of the encrypted private key.
14
+ *
15
+ * @param password The password that should be used to encrypt the private key of the keypair.
16
+ */
17
+ export function keypair(password) {
18
+ return keypairV1(password);
19
+ }
20
+ /**
21
+ * Creates a version 1 keypair that can be used for digitally signing data.
22
+ *
23
+ * The returned keypair contains a version number at the beginning which determines the format of the following data.
24
+ *
25
+ * v1 keypairs use ed25519.
26
+ * The output string is formatting as following with periods between the components:
27
+ * 1. The version number (vK1) - The K is for keypair
28
+ * 2. The base64 of the public key.
29
+ * 3. The base64 of the encrypted private key.
30
+ *
31
+ * @param password The password that should be used to encrypt the private key of the keypair.
32
+ */
33
+ export function keypairV1(password) {
34
+ const pair = signImpl.keyPair();
35
+ const encryptedPrivateKey = encrypt(password, pair.secretKey);
36
+ const encoder = new TextEncoder();
37
+ const privateKeyBytes = encoder.encode(encryptedPrivateKey);
38
+ return `vK1.${fromByteArray(pair.publicKey)}.${fromByteArray(privateKeyBytes)}`;
39
+ }
40
+ /**
41
+ * Creates a version 1 signature from the given keypair and returns the result.
42
+ *
43
+ * v1 signatures use ed25519.
44
+ * The output string is formatted as following with periods between the components:
45
+ * 1. The version number (vS1) - THe S is for signature.
46
+ * 2. The base64 of the signature.
47
+ *
48
+ * @param keypair The keypair to use.
49
+ * @param password The password that is used to decrypt the private key.
50
+ * @param data The data to sign.
51
+ */
52
+ export function sign(keypair, password, data) {
53
+ if (!keypair) {
54
+ throw new Error('Invalid keypair. Must not be null or undefined.');
55
+ }
56
+ if (!password) {
57
+ throw new Error('Invalid password. Must not be null or undefined.');
58
+ }
59
+ if (keypair.startsWith('vK1.')) {
60
+ return signV1(keypair, password, data);
61
+ }
62
+ return null;
63
+ }
64
+ /**
65
+ * Creates a version 1 signature from the given keypair and returns the result.
66
+ *
67
+ * v1 signatures use ed25519.
68
+ * The output string is formatted as following with periods between the components:
69
+ * 1. The version number (vS1) - THe S is for signature.
70
+ * 2. The base64 of the signature.
71
+ *
72
+ * @param keypair The keypair to use.
73
+ * @param password The password that is used to decrypt the private key.
74
+ * @param data The data to sign.
75
+ */
76
+ export function signV1(keypair, password, data) {
77
+ if (!keypair) {
78
+ throw new Error('Invalid keypair. Must not be null or undefined.');
79
+ }
80
+ if (!password) {
81
+ throw new Error('Invalid password. Must not be null or undefined.');
82
+ }
83
+ if (!keypair.startsWith('vK1.')) {
84
+ throw new Error('Invalid keypair. Must start with "vK1."');
85
+ }
86
+ const [publicKey, privateKey] = decodeKeyV1(keypair);
87
+ if (!publicKey || !privateKey) {
88
+ throw new Error('Invalid keypair. Unable to be decoded.');
89
+ }
90
+ const decrypted = decrypt(password, privateKey);
91
+ if (!decrypted) {
92
+ throw new Error('Invalid keypair. Unable to decrypt the private key.');
93
+ }
94
+ const signature = signImpl.detached(data, decrypted);
95
+ return `vS1.${fromByteArray(signature)}`;
96
+ }
97
+ /**
98
+ * Validates that the given signature was created by the given keypair for the given data.
99
+ * @param keypair The keypair.
100
+ * @param signature The signature to validate.
101
+ * @param data The data that was signed.
102
+ */
103
+ export function verify(keypair, signature, data) {
104
+ if (!keypair) {
105
+ throw new Error('Invalid keypair. Must not be null or undefined.');
106
+ }
107
+ if (!signature) {
108
+ throw new Error('Invalid signature. Must not be null or undefined.');
109
+ }
110
+ const isV1Keypair = keypair.startsWith('vK1.');
111
+ const isV1Signature = signature.startsWith('vS1.');
112
+ if (isV1Keypair && isV1Signature) {
113
+ return verifyV1(keypair, signature, data);
114
+ }
115
+ else if (isV1Keypair || isV1Signature) {
116
+ throw new Error('Mismatched keypair and signature. They must have matching versions.');
117
+ }
118
+ return false;
119
+ }
120
+ /**
121
+ * Validates a signature that was created by signV1().
122
+ * @param keypair The keypair that created the signature.
123
+ * @param signature The signature.
124
+ * @param data The data.
125
+ */
126
+ export function verifyV1(keypair, signature, data) {
127
+ if (!keypair) {
128
+ throw new Error('Invalid keypair. Must not be null or undefined.');
129
+ }
130
+ if (!signature) {
131
+ throw new Error('Invalid signature. Must not be null or undefined.');
132
+ }
133
+ if (!keypair.startsWith('vK1')) {
134
+ throw new Error('Invalid keypair. Must start with "vK1."');
135
+ }
136
+ if (!signature.startsWith('vS1')) {
137
+ throw new Error('Invalid signature. Must start with "vS1."');
138
+ }
139
+ const [publicKey, privateKey] = decodeKeyV1(keypair);
140
+ if (!publicKey || !privateKey) {
141
+ throw new Error('Invalid keypair. Unable to be decoded.');
142
+ }
143
+ const signatureBytes = decodeSigV1(signature);
144
+ return signImpl.detached.verify(data, signatureBytes, publicKey);
145
+ }
146
+ function decodeKeyV1(keypair) {
147
+ const withoutVersion = keypair.slice('vK1.'.length);
148
+ let nextPeriod = withoutVersion.indexOf('.');
149
+ if (nextPeriod < 0) {
150
+ return [null, null];
151
+ }
152
+ const publicKeyBase64 = withoutVersion.slice(0, nextPeriod);
153
+ const withoutPublicKey = withoutVersion.slice(nextPeriod + 1);
154
+ const privateKeyBase64 = withoutPublicKey;
155
+ const publicKey = toByteArray(publicKeyBase64);
156
+ const privateKeyBytes = toByteArray(privateKeyBase64);
157
+ const decoder = new TextDecoder();
158
+ const privateKey = decoder.decode(privateKeyBytes);
159
+ return [publicKey, privateKey];
160
+ }
161
+ function decodeSigV1(signature) {
162
+ const signatureBase64 = signature.slice('vK1.'.length);
163
+ return toByteArray(signatureBase64);
164
+ }
165
+ //# sourceMappingURL=Signatures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Signatures.js","sourceRoot":"","sources":["Signatures.ts"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from './SignatureAlgorithm';
2
+ export * from './CryptoImpl';
3
+ export * from './utils';
4
+ export * from './HashHelpers';
5
+ export * from './Encryption';
6
+ export * from './Signatures';
7
+ //# sourceMappingURL=index.d.ts.map
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from './SignatureAlgorithm';
2
+ export * from './CryptoImpl';
3
+ export * from './utils';
4
+ export * from './HashHelpers';
5
+ export * from './Encryption';
6
+ export * from './Signatures';
7
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@casual-simulation/crypto",
3
+ "version": "2.0.12",
4
+ "description": "Crypto helpers used by AUX",
5
+ "keywords": [
6
+ "cryptography",
7
+ "crypto"
8
+ ],
9
+ "author": "Casual Simulation, Inc.",
10
+ "homepage": "https://github.com/casual-simulation/casualos",
11
+ "license": "MIT",
12
+ "main": "index.js",
13
+ "types": "index.d.ts",
14
+ "module": "index.js",
15
+ "directories": {
16
+ "lib": "."
17
+ },
18
+ "files": [
19
+ "/README.md",
20
+ "/LICENSE.txt",
21
+ "**/*.js",
22
+ "**/*.js.map",
23
+ "**/*.d.ts"
24
+ ],
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/casual-simulation/casualos.git"
28
+ },
29
+ "scripts": {
30
+ "watch": "tsc --watch",
31
+ "watch:player": "npm run watch",
32
+ "build": "echo \"Nothing to do.\"",
33
+ "build:docs": "typedoc --mode file --excludeNotExported --out ../../api-docs/crypto .",
34
+ "test": "jest",
35
+ "test:watch": "jest --watchAll"
36
+ },
37
+ "bugs": {
38
+ "url": "https://github.com/casual-simulation/casualos/issues"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "dependencies": {
44
+ "@types/scrypt-async": "^1.3.1",
45
+ "base64-js": "^1.3.0",
46
+ "hash.js": "1.1.7",
47
+ "scrypt-js": "3.0.1",
48
+ "tweetnacl": "1.0.3"
49
+ },
50
+ "gitHead": "82eaafa4ae9d432b2fdd61f645eedc3577dffc5d"
51
+ }
@@ -0,0 +1,21 @@
1
+ import { SigningCryptoImpl, PrivateCryptoKey, PublicCryptoKey, SigningCryptoKey } from '../CryptoImpl';
2
+ import { SignatureAlgorithmType } from '../SignatureAlgorithm';
3
+ export declare class TestCryptoImpl implements SigningCryptoImpl {
4
+ valid: boolean;
5
+ signature: ArrayBuffer;
6
+ algorithm: SignatureAlgorithmType;
7
+ constructor(algorithm: SignatureAlgorithmType);
8
+ supported(): boolean;
9
+ sign(key: PrivateCryptoKey, data: ArrayBuffer): Promise<ArrayBuffer>;
10
+ verify(key: PublicCryptoKey, signature: ArrayBuffer, data: ArrayBuffer): Promise<boolean>;
11
+ verifyBatch(key: PublicCryptoKey, signatures: ArrayBuffer[], datas: ArrayBuffer[]): Promise<boolean[]>;
12
+ exportKey(key: SigningCryptoKey): Promise<string>;
13
+ importPublicKey(key: string): Promise<PublicCryptoKey>;
14
+ importPrivateKey(key: string): Promise<PrivateCryptoKey>;
15
+ generateKeyPair(): Promise<[PublicCryptoKey, PrivateCryptoKey]>;
16
+ }
17
+ export declare class TestCryptoKey {
18
+ type: string;
19
+ constructor(type: string);
20
+ }
21
+ //# sourceMappingURL=TestCryptoImpl.d.ts.map
@@ -0,0 +1,57 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ export class TestCryptoImpl {
11
+ constructor(algorithm) {
12
+ this.valid = false;
13
+ this.signature = null;
14
+ this.algorithm = algorithm;
15
+ }
16
+ supported() {
17
+ return true;
18
+ }
19
+ sign(key, data) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ return this.signature || data.slice(0, 32);
22
+ });
23
+ }
24
+ verify(key, signature, data) {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ return this.valid;
27
+ });
28
+ }
29
+ verifyBatch(key, signatures, datas) {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ return signatures.map(s => this.valid);
32
+ });
33
+ }
34
+ exportKey(key) {
35
+ return Promise.resolve(key.type);
36
+ }
37
+ importPublicKey(key) {
38
+ return Promise.resolve(new TestCryptoKey(key));
39
+ }
40
+ importPrivateKey(key) {
41
+ return Promise.resolve(new TestCryptoKey(key));
42
+ }
43
+ generateKeyPair() {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ return [
46
+ new TestCryptoKey('public'),
47
+ new TestCryptoKey('private'),
48
+ ];
49
+ });
50
+ }
51
+ }
52
+ export class TestCryptoKey {
53
+ constructor(type) {
54
+ this.type = type;
55
+ }
56
+ }
57
+ //# sourceMappingURL=TestCryptoImpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestCryptoImpl.js","sourceRoot":"","sources":["TestCryptoImpl.ts"],"names":[],"mappings":";;;;;;;;;AAQA,MAAM,OAAO,cAAc;IAKvB,YAAY,SAAiC;QAJ7C,UAAK,GAAY,KAAK,CAAC;QACvB,cAAS,GAAgB,IAAI,CAAC;QAI1B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED,SAAS;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;IAEK,IAAI,CAAC,GAAqB,EAAE,IAAiB;;YAC/C,OAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/C,CAAC;KAAA;IAEK,MAAM,CACR,GAAoB,EACpB,SAAsB,EACtB,IAAiB;;YAEjB,OAAO,IAAI,CAAC,KAAK,CAAC;QACtB,CAAC;KAAA;IAEK,WAAW,CACb,GAAoB,EACpB,UAAyB,EACzB,KAAoB;;YAEpB,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC;KAAA;IAED,SAAS,CAAC,GAAqB;QAC3B,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,eAAe,CAAC,GAAW;QACvB,OAAO,OAAO,CAAC,OAAO,CAAkB,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,gBAAgB,CAAC,GAAW;QACxB,OAAO,OAAO,CAAC,OAAO,CAAmB,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC;IAEK,eAAe;;YACjB,OAAO;gBACc,IAAI,aAAa,CAAC,QAAQ,CAAC;gBAC1B,IAAI,aAAa,CAAC,SAAS,CAAC;aACjD,CAAC;QACN,CAAC;KAAA;CACJ;AAED,MAAM,OAAO,aAAa;IAGtB,YAAY,IAAY;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;CACJ"}
package/utils.d.ts ADDED
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The header that gets added to private keys formated as a PEM file.
3
+ */
4
+ export declare const PEM_PRIVATE_KEY_HEADER: string;
5
+ /**
6
+ * The footer that gets added to private keys formated as a PEM file.
7
+ */
8
+ export declare const PEM_PRIVATE_KEY_FOOTER: string;
9
+ /**
10
+ * The header that gets added to public keys formated as a PEM file.
11
+ */
12
+ export declare const PEM_PUBLIC_KEY_HEADER: string;
13
+ /**
14
+ * The footer that gets added to public keys formated as a PEM file.
15
+ */
16
+ export declare const PEM_PUBLIC_KEY_FOOTER: string;
17
+ /**
18
+ * Formats the given buffer as a PEM file for public keys.
19
+ * @param key The buffer that should be stored in the PEM file.
20
+ */
21
+ export declare function formatPublicPEMKey(key: ArrayBuffer): string;
22
+ /**
23
+ * Formats the given buffer as a PEM file for private keys.
24
+ * @param key The buffer that should be stored in the PEM file.
25
+ */
26
+ export declare function formatPrivatePEMKey(key: ArrayBuffer): string;
27
+ /**
28
+ * Formats the given buffer into PEM format.
29
+ * @param buffer The buffer to format.
30
+ * @param header The header to use.
31
+ * @param footer The footer to use.
32
+ */
33
+ export declare function formatPEM(buffer: ArrayBuffer, header: string, footer: string): string;
34
+ /**
35
+ * Parses the given private key PEM file into a buffer that contains just the key.
36
+ * @param pem The PEM file that represents the private key.
37
+ */
38
+ export declare function parsePrivatePEMKey(pem: string): ArrayBuffer;
39
+ /**
40
+ * Parses the given public key PEM file into a buffer that contains just the key.
41
+ * @param pem The PEM file that represents the public key.
42
+ */
43
+ export declare function parsePublicPEMKey(pem: string): ArrayBuffer;
44
+ /**
45
+ * Parses the given PEM file using the given header and footer strings.
46
+ * Returns an ArrayBuffer containing the bytes that were formatted into the PEM file.
47
+ *
48
+ * Note that this should probably not be used for PEM files other than the ones produced by
49
+ * formatPEM(). This is because PEM files can contain a lot of extra data that this implementation
50
+ * does not expect. For example, some PEM files can contain multiple keys and probably allow more whitespace.
51
+ *
52
+ * @param pem The PEM file to parse.
53
+ * @param header The header that we're expecting the file to have.
54
+ * @param footer The footer that we're expecting the file to have.
55
+ */
56
+ export declare function parsePEM(pem: string, header: string, footer: string): ArrayBuffer;
57
+ //# sourceMappingURL=utils.d.ts.map