susi-qemu 0.0.3 → 0.0.6

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/bin/susi +9 -4
  3. data/lib/disk.rb +7 -5
  4. data/lib/novnc/core/base64.js +104 -0
  5. data/lib/novnc/core/crypto/aes.js +178 -0
  6. data/lib/novnc/core/crypto/bigint.js +34 -0
  7. data/lib/novnc/core/crypto/crypto.js +90 -0
  8. data/lib/novnc/core/crypto/des.js +330 -0
  9. data/lib/novnc/core/crypto/dh.js +55 -0
  10. data/lib/novnc/core/crypto/md5.js +82 -0
  11. data/lib/novnc/core/crypto/rsa.js +132 -0
  12. data/lib/novnc/core/decoders/copyrect.js +27 -0
  13. data/lib/novnc/core/decoders/h264.js +321 -0
  14. data/lib/novnc/core/decoders/hextile.js +181 -0
  15. data/lib/novnc/core/decoders/jpeg.js +146 -0
  16. data/lib/novnc/core/decoders/raw.js +59 -0
  17. data/lib/novnc/core/decoders/rre.js +44 -0
  18. data/lib/novnc/core/decoders/tight.js +393 -0
  19. data/lib/novnc/core/decoders/tightpng.js +27 -0
  20. data/lib/novnc/core/decoders/zlib.js +51 -0
  21. data/lib/novnc/core/decoders/zrle.js +185 -0
  22. data/lib/novnc/core/deflator.js +84 -0
  23. data/lib/novnc/core/display.js +575 -0
  24. data/lib/novnc/core/encodings.js +53 -0
  25. data/lib/novnc/core/inflator.js +65 -0
  26. data/lib/novnc/core/input/domkeytable.js +311 -0
  27. data/lib/novnc/core/input/fixedkeys.js +129 -0
  28. data/lib/novnc/core/input/gesturehandler.js +567 -0
  29. data/lib/novnc/core/input/keyboard.js +294 -0
  30. data/lib/novnc/core/input/keysym.js +616 -0
  31. data/lib/novnc/core/input/keysymdef.js +688 -0
  32. data/lib/novnc/core/input/util.js +191 -0
  33. data/lib/novnc/core/input/vkeys.js +116 -0
  34. data/lib/novnc/core/input/xtscancodes.js +173 -0
  35. data/lib/novnc/core/ra2.js +312 -0
  36. data/lib/novnc/core/rfb.js +3257 -0
  37. data/lib/novnc/core/util/browser.js +172 -0
  38. data/lib/novnc/core/util/cursor.js +249 -0
  39. data/lib/novnc/core/util/element.js +32 -0
  40. data/lib/novnc/core/util/events.js +138 -0
  41. data/lib/novnc/core/util/eventtarget.js +35 -0
  42. data/lib/novnc/core/util/int.js +15 -0
  43. data/lib/novnc/core/util/logging.js +56 -0
  44. data/lib/novnc/core/util/strings.js +28 -0
  45. data/lib/novnc/core/websock.js +365 -0
  46. data/lib/novnc/screen.html +21 -0
  47. data/lib/novnc/vendor/pako/lib/utils/common.js +45 -0
  48. data/lib/novnc/vendor/pako/lib/zlib/adler32.js +27 -0
  49. data/lib/novnc/vendor/pako/lib/zlib/constants.js +47 -0
  50. data/lib/novnc/vendor/pako/lib/zlib/crc32.js +36 -0
  51. data/lib/novnc/vendor/pako/lib/zlib/deflate.js +1846 -0
  52. data/lib/novnc/vendor/pako/lib/zlib/gzheader.js +35 -0
  53. data/lib/novnc/vendor/pako/lib/zlib/inffast.js +324 -0
  54. data/lib/novnc/vendor/pako/lib/zlib/inflate.js +1527 -0
  55. data/lib/novnc/vendor/pako/lib/zlib/inftrees.js +322 -0
  56. data/lib/novnc/vendor/pako/lib/zlib/messages.js +11 -0
  57. data/lib/novnc/vendor/pako/lib/zlib/trees.js +1195 -0
  58. data/lib/novnc/vendor/pako/lib/zlib/zstream.js +24 -0
  59. data/lib/output.rb +11 -0
  60. data/lib/qmp.rb +6 -0
  61. data/lib/ssh.rb +3 -1
  62. data/lib/susi.rb +7 -6
  63. data/lib/version.rb +1 -1
  64. data/lib/vm.rb +36 -13
  65. data/lib/vnc.rb +34 -30
  66. metadata +85 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '040378a35425ae9289a4cfef45818da3001a1a8dc199ad5ef1725dfc809bb239'
4
- data.tar.gz: 386be63f2c3a50fc99bd1c2d4e2850e605b04c1cfe50f86677bf6f1272896c00
3
+ metadata.gz: 4bc88655a9b5207f858886dacd6c466036b42747a3d382d2ea76b2feb0803d82
4
+ data.tar.gz: 98c59659a0aca9366eab87caef03a5cabcf756b9492905da41bcb6e288b6aec7
5
5
  SHA512:
6
- metadata.gz: b0a6449ff120efabb18c973cb1e487820c3a24201588893f4539c77c4be95259bfcce544a757a6309868f8bd56d7d474947bd595108f1011781a7a2ade8908fe
7
- data.tar.gz: 0bbb251ecc0a459c197f55a57f16ba9fcd07e8d35393ee6f1882bb1dd7c1677cc48befd394949baaa8d8f7f7a0332d6d2078e3650a256acba3a553038cef1322
6
+ metadata.gz: 3d9101294ba6ac775992dc889c4fe3b39591ddcb78d13665ab7368fcc3f9c7a8abd0a4b9753cae44feb76b204535cdd4df067f42289638835da032935c73e686
7
+ data.tar.gz: 65716f78fe4b5b4fa5a55aeaef70c7b2e462800d6c0f204c59e866e5ccf15224a42e0af96299e9392ade4d35e223625e05b6abe5e5678a608fd2b012c92a1450
data/bin/susi CHANGED
@@ -57,10 +57,13 @@ elsif ARGV[0] == 'ls'
57
57
  Susi::VM.ls
58
58
 
59
59
  # open VNC
60
- elsif ARGV[0] == 'vnc' &&
61
- ARGV[1].is_a?(String)
62
- vm_name = ARGV[2]
63
- Susi::VNC.open(vm_name)
60
+ elsif ARGV[0] == 'vnc'
61
+ if ARGV[1].is_a?(String)
62
+ vm_name = ARGV[1]
63
+ Susi::VNC.open(vm_name)
64
+ else
65
+ Susi::VNC.open(Susi::current_vm_name)
66
+ end
64
67
 
65
68
  # open SSH
66
69
  elsif ARGV[0] == 'ssh'
@@ -109,9 +112,11 @@ Usage:
109
112
  susi vm ls
110
113
 
111
114
  Open VNC
115
+ susi vnc
112
116
  susi vnc <vm_name>
113
117
 
114
118
  Open SSH
119
+ susi ssh
115
120
  susi ssh <vm_name>
116
121
 
117
122
  Download Debian netinstall ISO
data/lib/disk.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require_relative 'output'
2
+
1
3
  module Susi
2
4
  class Disk
3
5
  DEFAULT_IMG = "debian-12.7.0-amd64-netinst.iso"
@@ -16,7 +18,7 @@ module Susi
16
18
 
17
19
  url = "https://mirrors.tuna.tsinghua.edu.cn/debian-cd/current/amd64/iso-cd/#{DEFAULT_IMG}"
18
20
 
19
- puts "Downloading Debian netinstall ISO..."
21
+ Susi::debug "Downloading Debian netinstall ISO..."
20
22
 
21
23
  begin
22
24
  URI.open(url) do |remote_file|
@@ -24,13 +26,13 @@ module Susi
24
26
  local_file.write(remote_file.read)
25
27
  end
26
28
  end
27
- puts "Download completed successfully."
29
+ Susi::debug "Download completed successfully."
28
30
  rescue OpenURI::HTTPError => e
29
- puts "Error downloading the ISO: #{e.message}"
31
+ Susi::debug "Error downloading the ISO: #{e.message}"
30
32
  rescue SocketError => e
31
- puts "Network error: #{e.message}"
33
+ Susi::debug "Network error: #{e.message}"
32
34
  rescue => e
33
- puts "An unexpected error occurred: #{e.message}"
35
+ Susi::debug "An unexpected error occurred: #{e.message}"
34
36
  end
35
37
  end
36
38
 
@@ -0,0 +1,104 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ // From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
6
+
7
+ import * as Log from './util/logging.js';
8
+
9
+ export default {
10
+ /* Convert data (an array of integers) to a Base64 string. */
11
+ toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
12
+ base64Pad: '=',
13
+
14
+ encode(data) {
15
+ "use strict";
16
+ let result = '';
17
+ const length = data.length;
18
+ const lengthpad = (length % 3);
19
+ // Convert every three bytes to 4 ascii characters.
20
+
21
+ for (let i = 0; i < (length - 2); i += 3) {
22
+ result += this.toBase64Table[data[i] >> 2];
23
+ result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
24
+ result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
25
+ result += this.toBase64Table[data[i + 2] & 0x3f];
26
+ }
27
+
28
+ // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
29
+ const j = length - lengthpad;
30
+ if (lengthpad === 2) {
31
+ result += this.toBase64Table[data[j] >> 2];
32
+ result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
33
+ result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
34
+ result += this.toBase64Table[64];
35
+ } else if (lengthpad === 1) {
36
+ result += this.toBase64Table[data[j] >> 2];
37
+ result += this.toBase64Table[(data[j] & 0x03) << 4];
38
+ result += this.toBase64Table[64];
39
+ result += this.toBase64Table[64];
40
+ }
41
+
42
+ return result;
43
+ },
44
+
45
+ /* Convert Base64 data to a string */
46
+ /* eslint-disable comma-spacing */
47
+ toBinaryTable: [
48
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
49
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
50
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
51
+ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
52
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
53
+ 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
54
+ -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
55
+ 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
56
+ ],
57
+ /* eslint-enable comma-spacing */
58
+
59
+ decode(data, offset = 0) {
60
+ let dataLength = data.indexOf('=') - offset;
61
+ if (dataLength < 0) { dataLength = data.length - offset; }
62
+
63
+ /* Every four characters is 3 resulting numbers */
64
+ const resultLength = (dataLength >> 2) * 3 + Math.floor((dataLength % 4) / 1.5);
65
+ const result = new Array(resultLength);
66
+
67
+ // Convert one by one.
68
+
69
+ let leftbits = 0; // number of bits decoded, but yet to be appended
70
+ let leftdata = 0; // bits decoded, but yet to be appended
71
+ for (let idx = 0, i = offset; i < data.length; i++) {
72
+ const c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
73
+ const padding = (data.charAt(i) === this.base64Pad);
74
+ // Skip illegal characters and whitespace
75
+ if (c === -1) {
76
+ Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
77
+ continue;
78
+ }
79
+
80
+ // Collect data into leftdata, update bitcount
81
+ leftdata = (leftdata << 6) | c;
82
+ leftbits += 6;
83
+
84
+ // If we have 8 or more bits, append 8 bits to the result
85
+ if (leftbits >= 8) {
86
+ leftbits -= 8;
87
+ // Append if not padding.
88
+ if (!padding) {
89
+ result[idx++] = (leftdata >> leftbits) & 0xff;
90
+ }
91
+ leftdata &= (1 << leftbits) - 1;
92
+ }
93
+ }
94
+
95
+ // If there are any bits left, the base64 string was corrupted
96
+ if (leftbits) {
97
+ const err = new Error('Corrupted base64 string');
98
+ err.name = 'Base64-Error';
99
+ throw err;
100
+ }
101
+
102
+ return result;
103
+ }
104
+ }; /* End of Base64 namespace */
@@ -0,0 +1,178 @@
1
+ export class AESECBCipher {
2
+ constructor() {
3
+ this._key = null;
4
+ }
5
+
6
+ get algorithm() {
7
+ return { name: "AES-ECB" };
8
+ }
9
+
10
+ static async importKey(key, _algorithm, extractable, keyUsages) {
11
+ const cipher = new AESECBCipher;
12
+ await cipher._importKey(key, extractable, keyUsages);
13
+ return cipher;
14
+ }
15
+
16
+ async _importKey(key, extractable, keyUsages) {
17
+ this._key = await window.crypto.subtle.importKey(
18
+ "raw", key, {name: "AES-CBC"}, extractable, keyUsages);
19
+ }
20
+
21
+ async encrypt(_algorithm, plaintext) {
22
+ const x = new Uint8Array(plaintext);
23
+ if (x.length % 16 !== 0 || this._key === null) {
24
+ return null;
25
+ }
26
+ const n = x.length / 16;
27
+ for (let i = 0; i < n; i++) {
28
+ const y = new Uint8Array(await window.crypto.subtle.encrypt({
29
+ name: "AES-CBC",
30
+ iv: new Uint8Array(16),
31
+ }, this._key, x.slice(i * 16, i * 16 + 16))).slice(0, 16);
32
+ x.set(y, i * 16);
33
+ }
34
+ return x;
35
+ }
36
+ }
37
+
38
+ export class AESEAXCipher {
39
+ constructor() {
40
+ this._rawKey = null;
41
+ this._ctrKey = null;
42
+ this._cbcKey = null;
43
+ this._zeroBlock = new Uint8Array(16);
44
+ this._prefixBlock0 = this._zeroBlock;
45
+ this._prefixBlock1 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
46
+ this._prefixBlock2 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]);
47
+ }
48
+
49
+ get algorithm() {
50
+ return { name: "AES-EAX" };
51
+ }
52
+
53
+ async _encryptBlock(block) {
54
+ const encrypted = await window.crypto.subtle.encrypt({
55
+ name: "AES-CBC",
56
+ iv: this._zeroBlock,
57
+ }, this._cbcKey, block);
58
+ return new Uint8Array(encrypted).slice(0, 16);
59
+ }
60
+
61
+ async _initCMAC() {
62
+ const k1 = await this._encryptBlock(this._zeroBlock);
63
+ const k2 = new Uint8Array(16);
64
+ const v = k1[0] >>> 6;
65
+ for (let i = 0; i < 15; i++) {
66
+ k2[i] = (k1[i + 1] >> 6) | (k1[i] << 2);
67
+ k1[i] = (k1[i + 1] >> 7) | (k1[i] << 1);
68
+ }
69
+ const lut = [0x0, 0x87, 0x0e, 0x89];
70
+ k2[14] ^= v >>> 1;
71
+ k2[15] = (k1[15] << 2) ^ lut[v];
72
+ k1[15] = (k1[15] << 1) ^ lut[v >> 1];
73
+ this._k1 = k1;
74
+ this._k2 = k2;
75
+ }
76
+
77
+ async _encryptCTR(data, counter) {
78
+ const encrypted = await window.crypto.subtle.encrypt({
79
+ name: "AES-CTR",
80
+ counter: counter,
81
+ length: 128
82
+ }, this._ctrKey, data);
83
+ return new Uint8Array(encrypted);
84
+ }
85
+
86
+ async _decryptCTR(data, counter) {
87
+ const decrypted = await window.crypto.subtle.decrypt({
88
+ name: "AES-CTR",
89
+ counter: counter,
90
+ length: 128
91
+ }, this._ctrKey, data);
92
+ return new Uint8Array(decrypted);
93
+ }
94
+
95
+ async _computeCMAC(data, prefixBlock) {
96
+ if (prefixBlock.length !== 16) {
97
+ return null;
98
+ }
99
+ const n = Math.floor(data.length / 16);
100
+ const m = Math.ceil(data.length / 16);
101
+ const r = data.length - n * 16;
102
+ const cbcData = new Uint8Array((m + 1) * 16);
103
+ cbcData.set(prefixBlock);
104
+ cbcData.set(data, 16);
105
+ if (r === 0) {
106
+ for (let i = 0; i < 16; i++) {
107
+ cbcData[n * 16 + i] ^= this._k1[i];
108
+ }
109
+ } else {
110
+ cbcData[(n + 1) * 16 + r] = 0x80;
111
+ for (let i = 0; i < 16; i++) {
112
+ cbcData[(n + 1) * 16 + i] ^= this._k2[i];
113
+ }
114
+ }
115
+ let cbcEncrypted = await window.crypto.subtle.encrypt({
116
+ name: "AES-CBC",
117
+ iv: this._zeroBlock,
118
+ }, this._cbcKey, cbcData);
119
+
120
+ cbcEncrypted = new Uint8Array(cbcEncrypted);
121
+ const mac = cbcEncrypted.slice(cbcEncrypted.length - 32, cbcEncrypted.length - 16);
122
+ return mac;
123
+ }
124
+
125
+ static async importKey(key, _algorithm, _extractable, _keyUsages) {
126
+ const cipher = new AESEAXCipher;
127
+ await cipher._importKey(key);
128
+ return cipher;
129
+ }
130
+
131
+ async _importKey(key) {
132
+ this._rawKey = key;
133
+ this._ctrKey = await window.crypto.subtle.importKey(
134
+ "raw", key, {name: "AES-CTR"}, false, ["encrypt", "decrypt"]);
135
+ this._cbcKey = await window.crypto.subtle.importKey(
136
+ "raw", key, {name: "AES-CBC"}, false, ["encrypt"]);
137
+ await this._initCMAC();
138
+ }
139
+
140
+ async encrypt(algorithm, message) {
141
+ const ad = algorithm.additionalData;
142
+ const nonce = algorithm.iv;
143
+ const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0);
144
+ const encrypted = await this._encryptCTR(message, nCMAC);
145
+ const adCMAC = await this._computeCMAC(ad, this._prefixBlock1);
146
+ const mac = await this._computeCMAC(encrypted, this._prefixBlock2);
147
+ for (let i = 0; i < 16; i++) {
148
+ mac[i] ^= nCMAC[i] ^ adCMAC[i];
149
+ }
150
+ const res = new Uint8Array(16 + encrypted.length);
151
+ res.set(encrypted);
152
+ res.set(mac, encrypted.length);
153
+ return res;
154
+ }
155
+
156
+ async decrypt(algorithm, data) {
157
+ const encrypted = data.slice(0, data.length - 16);
158
+ const ad = algorithm.additionalData;
159
+ const nonce = algorithm.iv;
160
+ const mac = data.slice(data.length - 16);
161
+ const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0);
162
+ const adCMAC = await this._computeCMAC(ad, this._prefixBlock1);
163
+ const computedMac = await this._computeCMAC(encrypted, this._prefixBlock2);
164
+ for (let i = 0; i < 16; i++) {
165
+ computedMac[i] ^= nCMAC[i] ^ adCMAC[i];
166
+ }
167
+ if (computedMac.length !== mac.length) {
168
+ return null;
169
+ }
170
+ for (let i = 0; i < mac.length; i++) {
171
+ if (computedMac[i] !== mac[i]) {
172
+ return null;
173
+ }
174
+ }
175
+ const res = await this._decryptCTR(encrypted, nCMAC);
176
+ return res;
177
+ }
178
+ }
@@ -0,0 +1,34 @@
1
+ export function modPow(b, e, m) {
2
+ let r = 1n;
3
+ b = b % m;
4
+ while (e > 0n) {
5
+ if ((e & 1n) === 1n) {
6
+ r = (r * b) % m;
7
+ }
8
+ e = e >> 1n;
9
+ b = (b * b) % m;
10
+ }
11
+ return r;
12
+ }
13
+
14
+ export function bigIntToU8Array(bigint, padLength=0) {
15
+ let hex = bigint.toString(16);
16
+ if (padLength === 0) {
17
+ padLength = Math.ceil(hex.length / 2);
18
+ }
19
+ hex = hex.padStart(padLength * 2, '0');
20
+ const length = hex.length / 2;
21
+ const arr = new Uint8Array(length);
22
+ for (let i = 0; i < length; i++) {
23
+ arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
24
+ }
25
+ return arr;
26
+ }
27
+
28
+ export function u8ArrayToBigInt(arr) {
29
+ let hex = '0x';
30
+ for (let i = 0; i < arr.length; i++) {
31
+ hex += arr[i].toString(16).padStart(2, '0');
32
+ }
33
+ return BigInt(hex);
34
+ }
@@ -0,0 +1,90 @@
1
+ import { AESECBCipher, AESEAXCipher } from "./aes.js";
2
+ import { DESCBCCipher, DESECBCipher } from "./des.js";
3
+ import { RSACipher } from "./rsa.js";
4
+ import { DHCipher } from "./dh.js";
5
+ import { MD5 } from "./md5.js";
6
+
7
+ // A single interface for the cryptographic algorithms not supported by SubtleCrypto.
8
+ // Both synchronous and asynchronous implmentations are allowed.
9
+ class LegacyCrypto {
10
+ constructor() {
11
+ this._algorithms = {
12
+ "AES-ECB": AESECBCipher,
13
+ "AES-EAX": AESEAXCipher,
14
+ "DES-ECB": DESECBCipher,
15
+ "DES-CBC": DESCBCCipher,
16
+ "RSA-PKCS1-v1_5": RSACipher,
17
+ "DH": DHCipher,
18
+ "MD5": MD5,
19
+ };
20
+ }
21
+
22
+ encrypt(algorithm, key, data) {
23
+ if (key.algorithm.name !== algorithm.name) {
24
+ throw new Error("algorithm does not match");
25
+ }
26
+ if (typeof key.encrypt !== "function") {
27
+ throw new Error("key does not support encryption");
28
+ }
29
+ return key.encrypt(algorithm, data);
30
+ }
31
+
32
+ decrypt(algorithm, key, data) {
33
+ if (key.algorithm.name !== algorithm.name) {
34
+ throw new Error("algorithm does not match");
35
+ }
36
+ if (typeof key.decrypt !== "function") {
37
+ throw new Error("key does not support encryption");
38
+ }
39
+ return key.decrypt(algorithm, data);
40
+ }
41
+
42
+ importKey(format, keyData, algorithm, extractable, keyUsages) {
43
+ if (format !== "raw") {
44
+ throw new Error("key format is not supported");
45
+ }
46
+ const alg = this._algorithms[algorithm.name];
47
+ if (typeof alg === "undefined" || typeof alg.importKey !== "function") {
48
+ throw new Error("algorithm is not supported");
49
+ }
50
+ return alg.importKey(keyData, algorithm, extractable, keyUsages);
51
+ }
52
+
53
+ generateKey(algorithm, extractable, keyUsages) {
54
+ const alg = this._algorithms[algorithm.name];
55
+ if (typeof alg === "undefined" || typeof alg.generateKey !== "function") {
56
+ throw new Error("algorithm is not supported");
57
+ }
58
+ return alg.generateKey(algorithm, extractable, keyUsages);
59
+ }
60
+
61
+ exportKey(format, key) {
62
+ if (format !== "raw") {
63
+ throw new Error("key format is not supported");
64
+ }
65
+ if (typeof key.exportKey !== "function") {
66
+ throw new Error("key does not support exportKey");
67
+ }
68
+ return key.exportKey();
69
+ }
70
+
71
+ digest(algorithm, data) {
72
+ const alg = this._algorithms[algorithm];
73
+ if (typeof alg !== "function") {
74
+ throw new Error("algorithm is not supported");
75
+ }
76
+ return alg(data);
77
+ }
78
+
79
+ deriveBits(algorithm, key, length) {
80
+ if (key.algorithm.name !== algorithm.name) {
81
+ throw new Error("algorithm does not match");
82
+ }
83
+ if (typeof key.deriveBits !== "function") {
84
+ throw new Error("key does not support deriveBits");
85
+ }
86
+ return key.deriveBits(algorithm, length);
87
+ }
88
+ }
89
+
90
+ export default new LegacyCrypto;