susi-qemu 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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 +57 -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: 18a64bdd2b3618d6f588a9f78978c525c16da57551d281fe0d4fb1c0aa700c0a
4
+ data.tar.gz: 5589d13816af5f25b53e531a6dc2694ce4674806241bd886d0920beffc753018
5
5
  SHA512:
6
- metadata.gz: b0a6449ff120efabb18c973cb1e487820c3a24201588893f4539c77c4be95259bfcce544a757a6309868f8bd56d7d474947bd595108f1011781a7a2ade8908fe
7
- data.tar.gz: 0bbb251ecc0a459c197f55a57f16ba9fcd07e8d35393ee6f1882bb1dd7c1677cc48befd394949baaa8d8f7f7a0332d6d2078e3650a256acba3a553038cef1322
6
+ metadata.gz: 5289344c02a8784a34f41840071b3e6566e8cf0287bc04c12269f323f3c614988d9d4a525d84b0417149d84dbb8cd5bd7b38bc26342ad1508dc9f6a6596ce1a6
7
+ data.tar.gz: dd9cb9f118adc4266dc6828faf964d33b83b3b8e40957a132f4e650b7b25c03fabe5a654c6979f4e7bd5dd4465bfe87558a7f2eb07d9e5596000e9d816fff1e0
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;