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.
- checksums.yaml +4 -4
- data/bin/susi +9 -4
- data/lib/disk.rb +7 -5
- data/lib/novnc/core/base64.js +104 -0
- data/lib/novnc/core/crypto/aes.js +178 -0
- data/lib/novnc/core/crypto/bigint.js +34 -0
- data/lib/novnc/core/crypto/crypto.js +90 -0
- data/lib/novnc/core/crypto/des.js +330 -0
- data/lib/novnc/core/crypto/dh.js +55 -0
- data/lib/novnc/core/crypto/md5.js +82 -0
- data/lib/novnc/core/crypto/rsa.js +132 -0
- data/lib/novnc/core/decoders/copyrect.js +27 -0
- data/lib/novnc/core/decoders/h264.js +321 -0
- data/lib/novnc/core/decoders/hextile.js +181 -0
- data/lib/novnc/core/decoders/jpeg.js +146 -0
- data/lib/novnc/core/decoders/raw.js +59 -0
- data/lib/novnc/core/decoders/rre.js +44 -0
- data/lib/novnc/core/decoders/tight.js +393 -0
- data/lib/novnc/core/decoders/tightpng.js +27 -0
- data/lib/novnc/core/decoders/zlib.js +51 -0
- data/lib/novnc/core/decoders/zrle.js +185 -0
- data/lib/novnc/core/deflator.js +84 -0
- data/lib/novnc/core/display.js +575 -0
- data/lib/novnc/core/encodings.js +53 -0
- data/lib/novnc/core/inflator.js +65 -0
- data/lib/novnc/core/input/domkeytable.js +311 -0
- data/lib/novnc/core/input/fixedkeys.js +129 -0
- data/lib/novnc/core/input/gesturehandler.js +567 -0
- data/lib/novnc/core/input/keyboard.js +294 -0
- data/lib/novnc/core/input/keysym.js +616 -0
- data/lib/novnc/core/input/keysymdef.js +688 -0
- data/lib/novnc/core/input/util.js +191 -0
- data/lib/novnc/core/input/vkeys.js +116 -0
- data/lib/novnc/core/input/xtscancodes.js +173 -0
- data/lib/novnc/core/ra2.js +312 -0
- data/lib/novnc/core/rfb.js +3257 -0
- data/lib/novnc/core/util/browser.js +172 -0
- data/lib/novnc/core/util/cursor.js +249 -0
- data/lib/novnc/core/util/element.js +32 -0
- data/lib/novnc/core/util/events.js +138 -0
- data/lib/novnc/core/util/eventtarget.js +35 -0
- data/lib/novnc/core/util/int.js +15 -0
- data/lib/novnc/core/util/logging.js +56 -0
- data/lib/novnc/core/util/strings.js +28 -0
- data/lib/novnc/core/websock.js +365 -0
- data/lib/novnc/screen.html +21 -0
- data/lib/novnc/vendor/pako/lib/utils/common.js +45 -0
- data/lib/novnc/vendor/pako/lib/zlib/adler32.js +27 -0
- data/lib/novnc/vendor/pako/lib/zlib/constants.js +47 -0
- data/lib/novnc/vendor/pako/lib/zlib/crc32.js +36 -0
- data/lib/novnc/vendor/pako/lib/zlib/deflate.js +1846 -0
- data/lib/novnc/vendor/pako/lib/zlib/gzheader.js +35 -0
- data/lib/novnc/vendor/pako/lib/zlib/inffast.js +324 -0
- data/lib/novnc/vendor/pako/lib/zlib/inflate.js +1527 -0
- data/lib/novnc/vendor/pako/lib/zlib/inftrees.js +322 -0
- data/lib/novnc/vendor/pako/lib/zlib/messages.js +11 -0
- data/lib/novnc/vendor/pako/lib/zlib/trees.js +1195 -0
- data/lib/novnc/vendor/pako/lib/zlib/zstream.js +24 -0
- data/lib/output.rb +11 -0
- data/lib/qmp.rb +6 -0
- data/lib/ssh.rb +3 -1
- data/lib/susi.rb +7 -6
- data/lib/version.rb +1 -1
- data/lib/vm.rb +36 -13
- data/lib/vnc.rb +34 -30
- metadata +57 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18a64bdd2b3618d6f588a9f78978c525c16da57551d281fe0d4fb1c0aa700c0a
|
4
|
+
data.tar.gz: 5589d13816af5f25b53e531a6dc2694ce4674806241bd886d0920beffc753018
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
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
|
-
|
29
|
+
Susi::debug "Download completed successfully."
|
28
30
|
rescue OpenURI::HTTPError => e
|
29
|
-
|
31
|
+
Susi::debug "Error downloading the ISO: #{e.message}"
|
30
32
|
rescue SocketError => e
|
31
|
-
|
33
|
+
Susi::debug "Network error: #{e.message}"
|
32
34
|
rescue => e
|
33
|
-
|
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;
|