@ethernity-cloud/sdk-js 1.1.0
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/LICENSE +661 -0
- package/README.md +185 -0
- package/build.js +22 -0
- package/init.js +301 -0
- package/nodenithy/build/las/Dockerfile +5 -0
- package/nodenithy/build/securelock/Dockerfile.tmpl +65 -0
- package/nodenithy/build/securelock/scripts/binary-fs-build.sh +28 -0
- package/nodenithy/build/securelock/src/.env +3 -0
- package/nodenithy/build/securelock/src/etny_crypto.js +201 -0
- package/nodenithy/build/securelock/src/etny_exec.js +65 -0
- package/nodenithy/build/securelock/src/image_registry_abi.js +808 -0
- package/nodenithy/build/securelock/src/models.js +261 -0
- package/nodenithy/build/securelock/src/package.json +40 -0
- package/nodenithy/build/securelock/src/pox_abi.js +1491 -0
- package/nodenithy/build/securelock/src/securelock.js.tmpl +421 -0
- package/nodenithy/build/securelock/src/swift_stream_service.js +147 -0
- package/nodenithy/build/securelock/src/task_status.js +15 -0
- package/nodenithy/build/securelock/src/wallet.js +29 -0
- package/nodenithy/build/squash/Dockerfile +7 -0
- package/nodenithy/build/trustedzone/Dockerfile.tmpl +57 -0
- package/nodenithy/build/trustedzone/scripts/binary-fs-build.sh +22 -0
- package/nodenithy/build/trustedzone/src/.env +3 -0
- package/nodenithy/build/trustedzone/src/etny_crypto.js +202 -0
- package/nodenithy/build/trustedzone/src/etny_exec.js +54 -0
- package/nodenithy/build/trustedzone/src/image_registry_abi.js +808 -0
- package/nodenithy/build/trustedzone/src/models.js +261 -0
- package/nodenithy/build/trustedzone/src/package.json +40 -0
- package/nodenithy/build/trustedzone/src/pox_abi.js +1491 -0
- package/nodenithy/build/trustedzone/src/swift_stream_service.js +147 -0
- package/nodenithy/build/trustedzone/src/task_status.js +15 -0
- package/nodenithy/build/trustedzone/src/test.js +44 -0
- package/nodenithy/build/trustedzone/src/trustedzone.js.tmpl +508 -0
- package/nodenithy/build/trustedzone/src/wallet.js +28 -0
- package/nodenithy/build/validator/Dockerfile +58 -0
- package/nodenithy/build/validator/package-lock.json +6 -0
- package/nodenithy/build/validator/scripts/binary-fs-build.sh +19 -0
- package/nodenithy/build/validator/src/.env +3 -0
- package/nodenithy/build/validator/src/cert.pem +5 -0
- package/nodenithy/build/validator/src/etny_crypto.js +204 -0
- package/nodenithy/build/validator/src/etny_exec.js +52 -0
- package/nodenithy/build/validator/src/image_registry_abi.js +808 -0
- package/nodenithy/build/validator/src/key.pem +6 -0
- package/nodenithy/build/validator/src/models.js +261 -0
- package/nodenithy/build/validator/src/package-lock.json +2498 -0
- package/nodenithy/build/validator/src/package.json +40 -0
- package/nodenithy/build/validator/src/pox_abi.js +1491 -0
- package/nodenithy/build/validator/src/swift_stream_service.js +147 -0
- package/nodenithy/build/validator/src/task_status.js +15 -0
- package/nodenithy/build/validator/src/test.js +44 -0
- package/nodenithy/build/validator/src/trustedzone.js +613 -0
- package/nodenithy/build/validator/src/validator_abi.js +834 -0
- package/nodenithy/build/validator/src/wallet.js +28 -0
- package/nodenithy/build.js +184 -0
- package/nodenithy/build.mjs +179 -0
- package/nodenithy/build.sh +161 -0
- package/nodenithy/ipfs.js +135 -0
- package/nodenithy/ipfs.mjs +551 -0
- package/nodenithy/public/favicon.ico +0 -0
- package/nodenithy/public/index.html +43 -0
- package/nodenithy/public/logo192.png +0 -0
- package/nodenithy/public/logo512.png +0 -0
- package/nodenithy/public/manifest.json +25 -0
- package/nodenithy/public/robots.txt +3 -0
- package/nodenithy/run/__pycache__/swift_stream_service.cpython-312.pyc +0 -0
- package/nodenithy/run/app/input.txt +4 -0
- package/nodenithy/run/app/payload.js +4 -0
- package/nodenithy/run/docker-compose-final.yml.tmpl +65 -0
- package/nodenithy/run/docker-compose-swift-stream.yml +17 -0
- package/nodenithy/run/docker-compose.yml.tmpl +76 -0
- package/nodenithy/run/etny-securelock-test.yaml.tpl +46 -0
- package/nodenithy/run/etny-trustedzone-test.yaml.tpl +45 -0
- package/nodenithy/run/git.sh +22 -0
- package/nodenithy/run/image_registry.abi +1 -0
- package/nodenithy/run/image_registry.js +372 -0
- package/nodenithy/run/image_registry.py +327 -0
- package/nodenithy/run/image_registry_runner.py +71 -0
- package/nodenithy/run/ipfs.sh +58 -0
- package/nodenithy/run/ipfs_pre.sh +75 -0
- package/nodenithy/run/public_key_service.js +90 -0
- package/nodenithy/run/public_key_service.py +107 -0
- package/nodenithy/run/swift_stream_service.py +212 -0
- package/nodenithy/run/swiftstream.py +37 -0
- package/nodenithy/run/swiftstream1.py +27 -0
- package/nodenithy/run.js +538 -0
- package/nodenithy/run.sh +277 -0
- package/nodenithy/scripts/build-ipfs-upload.sh +23 -0
- package/nodenithy/scripts/build.sh +40 -0
- package/nodenithy/scripts/ipfs-daemon.sh +7 -0
- package/nodenithy/scripts/run.sh +50 -0
- package/nodenithy/src/App.css +57 -0
- package/nodenithy/src/ec_helloworld_example.js +64 -0
- package/nodenithy/src/index.css +13 -0
- package/nodenithy/src/index.js +17 -0
- package/nodenithy/src/preStart.js +45 -0
- package/nodenithy/src/preStart.mjs +57 -0
- package/nodenithy/src/reportWebVitals.js +13 -0
- package/nodenithy/src/serverless/backend.js +5 -0
- package/package.json +48 -0
- package/postinstall.js +34 -0
- package/publish.js +126 -0
- package/pynithy/build/docker-compose.yml +68 -0
- package/pynithy/build/las/Dockerfile +11 -0
- package/pynithy/build/las/src/etny_entrypoint.sh +6 -0
- package/pynithy/build/las/src/las_entrypoint.sh +26 -0
- package/pynithy/build/scripts/binary-fs-build.sh +28 -0
- package/pynithy/build/securelock/Dockerfile.tmpl +78 -0
- package/pynithy/build/securelock/scripts/binary-fs-build.sh +41 -0
- package/pynithy/build/securelock/src/app/.env +5 -0
- package/pynithy/build/securelock/src/app/cert1-ca1-clean.crt +10 -0
- package/pynithy/build/securelock/src/app/cert1-ca1-clean.key +6 -0
- package/pynithy/build/securelock/src/app/enclave_pub_cert.pem +10 -0
- package/pynithy/build/securelock/src/app/input.txt +1 -0
- package/pynithy/build/securelock/src/app/payload.py +25 -0
- package/pynithy/build/securelock/src/app/public-cert-clean.pem +10 -0
- package/pynithy/build/securelock/src/app/result.txt +1 -0
- package/pynithy/build/securelock/src/app/transaction.txt +1 -0
- package/pynithy/build/securelock/src/etny_crypto.py +167 -0
- package/pynithy/build/securelock/src/etny_exec.py +79 -0
- package/pynithy/build/securelock/src/image_registry.abi +1 -0
- package/pynithy/build/securelock/src/key_generation.py +17 -0
- package/pynithy/build/securelock/src/models.py +176 -0
- package/pynithy/build/securelock/src/pox.abi +1489 -0
- package/pynithy/build/securelock/src/securelock.py.tmpl +411 -0
- package/pynithy/build/securelock/src/swift_stream_service.py +186 -0
- package/pynithy/build/trustedzone/Dockerfile.tmpl +56 -0
- package/pynithy/build/trustedzone/scripts/binary-fs-build.sh +32 -0
- package/pynithy/build/trustedzone/src/app/.env +5 -0
- package/pynithy/build/trustedzone/src/app/cert1-ca1-clean.crt +10 -0
- package/pynithy/build/trustedzone/src/app/cert1-ca1-clean.key +6 -0
- package/pynithy/build/trustedzone/src/app/enclave_pub_cert.pem +10 -0
- package/pynithy/build/trustedzone/src/app/input.txt +1 -0
- package/pynithy/build/trustedzone/src/app/payload.py +25 -0
- package/pynithy/build/trustedzone/src/app/public-cert-clean.pem +10 -0
- package/pynithy/build/trustedzone/src/app/result.txt +1 -0
- package/pynithy/build/trustedzone/src/app/securelock.crt +10 -0
- package/pynithy/build/trustedzone/src/app/transaction.txt +1 -0
- package/pynithy/build/trustedzone/src/app/trustedzone.crt +10 -0
- package/pynithy/build/trustedzone/src/etny_crypto.py +188 -0
- package/pynithy/build/trustedzone/src/etny_exec.py +56 -0
- package/pynithy/build/trustedzone/src/formatter.py +42 -0
- package/pynithy/build/trustedzone/src/image_registry.abi +1 -0
- package/pynithy/build/trustedzone/src/key_generation.py +17 -0
- package/pynithy/build/trustedzone/src/models.py +176 -0
- package/pynithy/build/trustedzone/src/pox.abi +1489 -0
- package/pynithy/build/trustedzone/src/swift_stream_service.py +186 -0
- package/pynithy/build/trustedzone/src/trustedzone.py.tmpl +460 -0
- package/pynithy/build.mjs +179 -0
- package/pynithy/docker-compose.yml +0 -0
- package/pynithy/ipfs.mjs +244 -0
- package/pynithy/public/favicon.ico +0 -0
- package/pynithy/public/index.html +43 -0
- package/pynithy/public/logo192.png +0 -0
- package/pynithy/public/logo512.png +0 -0
- package/pynithy/public/manifest.json +25 -0
- package/pynithy/public/robots.txt +3 -0
- package/pynithy/run/certs/cert.pem +31 -0
- package/pynithy/run/certs/challenge.crt +10 -0
- package/pynithy/run/certs/key.pem +52 -0
- package/pynithy/run/docker-compose-final.yml +59 -0
- package/pynithy/run/docker-compose-final.yml.tmpl +59 -0
- package/pynithy/run/docker-compose-swift-stream.yml +27 -0
- package/pynithy/run/docker-compose-swift-stream.yml.tmpl +27 -0
- package/pynithy/run/docker-compose.yml +55 -0
- package/pynithy/run/docker-compose.yml.tmpl +55 -0
- package/pynithy/run/etny-pynity-test.yaml.tpl +46 -0
- package/pynithy/run/etny-securelock-test.yaml.tpl +46 -0
- package/pynithy/run/etny-trustedzone-test.yaml.tpl +46 -0
- package/pynithy/run/git.sh +22 -0
- package/pynithy/run/image_registry.abi +1 -0
- package/pynithy/run/image_registry.js +372 -0
- package/pynithy/run/image_registry.py +139 -0
- package/pynithy/run/image_registry_runner.py +45 -0
- package/pynithy/run/ipfs.sh +89 -0
- package/pynithy/run/public_key_service.js +90 -0
- package/pynithy/run/swiftstream.py +28 -0
- package/pynithy/run.js +538 -0
- package/pynithy/src/App.css +57 -0
- package/pynithy/src/ec_helloworld_example.js +64 -0
- package/pynithy/src/index.css +13 -0
- package/pynithy/src/index.js +17 -0
- package/pynithy/src/preStart.mjs +57 -0
- package/pynithy/src/reportWebVitals.js +13 -0
- package/pynithy/src/serverless/__init__.py +0 -0
- package/pynithy/src/serverless/backend.py +2 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
require('dotenv').config();
|
|
2
|
+
require('dotenv').config({path: './app/.env'});
|
|
3
|
+
require('dotenv').config({path: '/app/.env'});
|
|
4
|
+
|
|
5
|
+
const ethers = require('ethers');
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const etny_crypto = require("./etny_crypto");
|
|
8
|
+
const {DOReqMetadata, Order} = require("./models");
|
|
9
|
+
const {getWalletAddress} = require("./wallet");
|
|
10
|
+
const {executeTask} = require("./etny_exec");
|
|
11
|
+
const {TaskStatus} = require("./task_status");
|
|
12
|
+
const SwiftStreamService = require("./swift_stream_service");
|
|
13
|
+
|
|
14
|
+
const contract_abi = require('./pox_abi');
|
|
15
|
+
const image_registry_abi = require('./image_registry_abi');
|
|
16
|
+
const {sha256} = require("./etny_crypto");
|
|
17
|
+
|
|
18
|
+
class EtnySecureLock {
|
|
19
|
+
static debug = false;
|
|
20
|
+
|
|
21
|
+
constructor(swiftStreamClient) {
|
|
22
|
+
console.log('Initializing...');
|
|
23
|
+
this.version = 'v3';
|
|
24
|
+
this.swiftStreamService = swiftStreamClient;
|
|
25
|
+
this.etny_bucket = "__BUCKET_NAME__";
|
|
26
|
+
this.setInitializers();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setInitializers() {
|
|
30
|
+
this.is_valid_client_data = true;
|
|
31
|
+
this.key_file = "/private/__ENCLAVE_NAME_SECURELOCK__/key.pem";
|
|
32
|
+
this.cert_file = "/app/__ENCLAVE_NAME_SECURELOCK__/cert.pem";
|
|
33
|
+
this.pub_cert_file = "/app/__ENCLAVE_NAME_SECURELOCK__/enclave_pub_cert.pem";
|
|
34
|
+
this.payload = "payload.etny.securelock";
|
|
35
|
+
this.input = "input.txt.securelock";
|
|
36
|
+
this.result_file = "/app/result.txt";
|
|
37
|
+
this.transaction_file = "/app/transaction.txt";
|
|
38
|
+
this.smart_contract_address = "__SMART_CONTRACT_ADDRESS__";
|
|
39
|
+
this.image_registry_address = '__IMAGE_REGISTRY_ADDRESS__';
|
|
40
|
+
this.chain_id = __CHAIN_ID__;
|
|
41
|
+
this.web3_provider = "__RPC_URL__";
|
|
42
|
+
this.signed_tx_as_bytes = null;
|
|
43
|
+
this.client_challenge = "";
|
|
44
|
+
|
|
45
|
+
if (this.etny_mode === "TEST") {
|
|
46
|
+
this.key_file = "/private/key.pem";
|
|
47
|
+
this.cert_file = "/app/cert.pem";
|
|
48
|
+
this.payload = "./app/payload.js";
|
|
49
|
+
this.input = "./app/input.txt";
|
|
50
|
+
this.result_file = "./app/result.txt";
|
|
51
|
+
this.transaction_file = "./app/transaction.txt";
|
|
52
|
+
this.pub_cert_file = "./app/enclave_pub_cert.pem";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (this.etny_mode === "LOCAL_TEST") {
|
|
56
|
+
this.key_file = "./certs/key.pem";
|
|
57
|
+
this.cert_file = "./certs/cert.pem";
|
|
58
|
+
this.payload = "./app/payload.js";
|
|
59
|
+
this.input = "./app/input.txt";
|
|
60
|
+
this.result_file = "./app/result.txt";
|
|
61
|
+
this.transaction_file = "./app/transaction.txt";
|
|
62
|
+
this.pub_cert_file = "./app/enclave_pub_cert.pem";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async create() {
|
|
67
|
+
//overriding default values with those read from .env file
|
|
68
|
+
this.loadEnv();
|
|
69
|
+
this.printEnv();
|
|
70
|
+
await this.savePublicCert();
|
|
71
|
+
this.initWeb3();
|
|
72
|
+
if (this.etny_mode === "PRODUCTION") {
|
|
73
|
+
this.resetPrivateCertFile();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
loadEnv() {
|
|
80
|
+
if (process.env.ETNY_CHAIN_ID) {
|
|
81
|
+
this.chain_id = parseInt(process.env.ETNY_CHAIN_ID);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (process.env.ETNY_SMART_CONTRACT_ADDRESS) {
|
|
85
|
+
this.smart_contract_address = process.env.ETNY_SMART_CONTRACT_ADDRESS.trim();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (process.env.ETNY_WEB3_PROVIDER) {
|
|
89
|
+
this.web3_provider = process.env.ETNY_WEB3_PROVIDER.trim();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (process.env.ETNY_CLIENT_CHALLENGE) {
|
|
93
|
+
this.client_challenge = process.env.ETNY_CLIENT_CHALLENGE.trim();
|
|
94
|
+
}
|
|
95
|
+
if (process.env.ETNY_ORDER_ID) {
|
|
96
|
+
this.order_id = parseInt(process.env.ETNY_ORDER_ID);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
printEnv() {
|
|
101
|
+
console.log('CHAIN ID:', this.chain_id);
|
|
102
|
+
console.log('SMART CONTRACT ADDRESS:', this.smart_contract_address);
|
|
103
|
+
console.log('WEB3 PROVIDER:', this.web3_provider);
|
|
104
|
+
console.log('ENCRYPTED CHALLENGE:', this.client_challenge);
|
|
105
|
+
console.log('ORDER ID:', this.order_id);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
initWeb3() {
|
|
109
|
+
// Create an ethers.js provider connected to the Bloxberg network
|
|
110
|
+
this.w3 = new ethers.providers.JsonRpcProvider(this.web3_provider);
|
|
111
|
+
// Create an instance of the contract using the ABI and address
|
|
112
|
+
this.etny = new ethers.Contract(this.smart_contract_address, contract_abi, this.w3);
|
|
113
|
+
this.image_registry = new ethers.Contract(this.image_registry_address, image_registry_abi, this.w3);
|
|
114
|
+
// this.iamge_registry_signer = new ethers.Contract(this.image_registry_address, image_registry_abi.abi, this.walletSigner);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async readEnv() {
|
|
118
|
+
try {
|
|
119
|
+
console.log('Getting .env if exists...');
|
|
120
|
+
const envFile = await this.swiftStreamService.getFileContent(this.etny_bucket, ".env");
|
|
121
|
+
console.log("Env:", envFile);
|
|
122
|
+
console.log("Saving .env file...");
|
|
123
|
+
await fs.promises.writeFile('.env', envFile);
|
|
124
|
+
require('dotenv').config();
|
|
125
|
+
|
|
126
|
+
this.version = 'v3';
|
|
127
|
+
this.etny_mode = process.env.ETNY_MODE;
|
|
128
|
+
console.log(`ETNY Nodenithy [${this.version}] - running in ${this.etny_mode} MODE`);
|
|
129
|
+
//console.log(process.env);
|
|
130
|
+
|
|
131
|
+
return true;
|
|
132
|
+
} catch (e) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
extractSigner(message, signature) {
|
|
138
|
+
try {
|
|
139
|
+
return ethers.utils.verifyMessage(message, signature);
|
|
140
|
+
} catch (e) {
|
|
141
|
+
console.log('extractSigner:', e)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async validateClientPayload(payload_data, input_data) {
|
|
146
|
+
await this.getDORequestMetadata();
|
|
147
|
+
if (this._metadata.payload_metadata_obj.checksum !== null) {
|
|
148
|
+
try {
|
|
149
|
+
const payload_checksum = sha256(payload_data);
|
|
150
|
+
//console.log('payload checksum: ', payload_checksum, "===", this._metadata.payload_metadata_obj.checksum);
|
|
151
|
+
// check the wallet address that signed payload checksum is the one from order metadata
|
|
152
|
+
const payload_signer = this.extractSigner(payload_checksum, this._metadata.payload_metadata_obj.checksum);
|
|
153
|
+
//console.log("payload_signer", payload_signer);
|
|
154
|
+
//console.log("this._order_metadata.do_owner.toLowerCase()", this._order_metadata.do_owner.toLowerCase());
|
|
155
|
+
if (payload_signer.toLowerCase() !== this._order_metadata.do_owner.toLowerCase()) {
|
|
156
|
+
this.task_code = TaskStatus.PAYLOAD_CHECKSUM_ERROR;
|
|
157
|
+
this.task_result = 'PAYLOAD CHECKSUM DOESN\'T MATCH';
|
|
158
|
+
this.is_valid_client_data = false;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
} catch (e) {
|
|
162
|
+
console.log(e);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
}
|
|
166
|
+
if (this._metadata.input_metadata_obj.checksum !== null) {
|
|
167
|
+
try {
|
|
168
|
+
const input_checksum = sha256(input_data);
|
|
169
|
+
//console.log('input checksum: ', input_checksum, '===', this._metadata.input_metadata_obj.checksum);
|
|
170
|
+
// check the wallet address that signed input checksum is the one from order metadata
|
|
171
|
+
const input_signer = this.extractSigner(input_checksum, this._metadata.input_metadata_obj.checksum);
|
|
172
|
+
//console.log("input_signer", input_signer);
|
|
173
|
+
//console.log("this._order_metadata.do_owner.toLowerCase()", this._order_metadata.do_owner.toLowerCase());
|
|
174
|
+
if (input_signer.toLowerCase() !== this._order_metadata.do_owner.toLowerCase()) {
|
|
175
|
+
this.task_code = TaskStatus.INPUT_CHECKSUM_ERROR;
|
|
176
|
+
this.task_result = 'INPUT CHECKSUM DOESN\'T MATCH';
|
|
177
|
+
this.is_valid_client_data = false;
|
|
178
|
+
}
|
|
179
|
+
} catch (e) {
|
|
180
|
+
console.log(e);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
wait(timeout) {
|
|
186
|
+
return new Promise(resolve => {
|
|
187
|
+
setTimeout(resolve, timeout);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async waitForObjectInBucket(bucketName, objectName, timeout = 600) {
|
|
192
|
+
let i = 0;
|
|
193
|
+
console.log(`Checking if object ${objectName} exists in bucket ${bucketName}`);
|
|
194
|
+
while (true) {
|
|
195
|
+
await this.wait(1000);
|
|
196
|
+
i++;
|
|
197
|
+
if (i % 20 === 0)
|
|
198
|
+
console.log(`Checking if object ${objectName} exists in bucket ${bucketName}`);
|
|
199
|
+
if (i > timeout) {
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
const [status, result] = await this.swiftStreamService.isObjectInBucket(bucketName, objectName);
|
|
203
|
+
if (result) {
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
console.log('TrustedZone finished the execution');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async waitForPayloadAndInput() {
|
|
212
|
+
console.log('Waiting for payload and input');
|
|
213
|
+
await this.waitForObjectInBucket(this.etny_bucket, this.payload);
|
|
214
|
+
await this.waitForObjectInBucket(this.etny_bucket, this.input);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async getFileContentAndDecrypt(bucketName, objectName) {
|
|
218
|
+
try {
|
|
219
|
+
const encryptedBase64 = await this.swiftStreamService.getFileContent(bucketName, objectName);
|
|
220
|
+
|
|
221
|
+
const encryptedTuple = etny_crypto.encryptedDataFromBase64Json(encryptedBase64);
|
|
222
|
+
const decryptedResult = etny_crypto.decrypt(this.key_file, encryptedTuple);
|
|
223
|
+
return decryptedResult.toString();
|
|
224
|
+
} catch (e) {
|
|
225
|
+
console.log(`Failed to get ${objectName} file`);
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async getTrustedZonePublicKey() {
|
|
231
|
+
try {
|
|
232
|
+
console.log('Getting the public key of the trusted zone enclave');
|
|
233
|
+
let imageHash = this._metadata.image_hash;
|
|
234
|
+
console.log('imageHash:', imageHash);
|
|
235
|
+
if (EtnySecureLock.debug) {
|
|
236
|
+
imageHash = 'v3-hash-1';
|
|
237
|
+
}
|
|
238
|
+
this.trustedZonePublicKey = await this.image_registry.getTrustedZoneImageCertPublicKey(imageHash);
|
|
239
|
+
console.log('Public key of the TrustedZone enclave from smart contract:', this.trustedZonePublicKey);
|
|
240
|
+
} catch (e) {
|
|
241
|
+
console.log('getTrustedZonePublicKey', e);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async getLatestTrustedZoneImageCertPublicKey() {
|
|
246
|
+
try {
|
|
247
|
+
console.log('Getting the public key of the trusted zone enclave');
|
|
248
|
+
this.trustedZonePublicKey = (await this.image_registry.getLatestTrustedZoneImageCertPublicKey("__TRUSTED_ZONE_IMAGE__", 'v3'))[1];
|
|
249
|
+
console.log('Public key of the TrustedZone enclave from smart contract:', this.trustedZonePublicKey);
|
|
250
|
+
} catch (e) {
|
|
251
|
+
console.log('getLatestTrustedZoneImageCertPublicKey', e);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async encryptFileAndPushToSwiftStream(fileData, fileName) {
|
|
256
|
+
try {
|
|
257
|
+
console.log(`Started saving file ${fileName}.securelock...`);
|
|
258
|
+
const encryptedInput = etny_crypto.encrypt(this.trustedZonePublicKey, fileData);
|
|
259
|
+
const encryptedInputBase64 = etny_crypto.encryptedDataToBase64Json(encryptedInput);
|
|
260
|
+
|
|
261
|
+
// File name should end with the '.securelock' extension
|
|
262
|
+
fileName += '.securelock';
|
|
263
|
+
// const data = Buffer.from(encryptedInputBase64, 'utf8');
|
|
264
|
+
const status = this.swiftStreamService.putFileContent(this.etny_bucket, fileName, '', encryptedInputBase64);
|
|
265
|
+
if (status) {
|
|
266
|
+
console.log(`File ${fileName} encrypted and saved to swift stream successfully`);
|
|
267
|
+
}
|
|
268
|
+
} catch (e) {
|
|
269
|
+
console.log('encryptFileAndPushToSwiftStream', e);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
async getDORequestMetadata() {
|
|
274
|
+
const o_result = await this.etny.functions._getOrder(this.order_id);
|
|
275
|
+
const order = new Order(o_result, this.order_id);
|
|
276
|
+
//console.log('order', order);
|
|
277
|
+
this._order_metadata = order;
|
|
278
|
+
const o_metadata = await this.etny.functions._getDORequestMetadata(order.do_req);
|
|
279
|
+
this._metadata = new DOReqMetadata(o_metadata, order.do_req);
|
|
280
|
+
//console.log('metadata', this._metadata);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
resetPrivateCertFile() {
|
|
284
|
+
//console.log('Resetting the cert file');
|
|
285
|
+
try {
|
|
286
|
+
// const fd = fs.openSync(this.private_key_file, 'w+');
|
|
287
|
+
fs.truncate(this.key_file, 0, function () {
|
|
288
|
+
//console.log('Private certificate file was cleaned.')
|
|
289
|
+
});
|
|
290
|
+
// fs.closeSync(fd);
|
|
291
|
+
} catch (e) {
|
|
292
|
+
//console.log('Error while removing the private key file content', e);
|
|
293
|
+
}
|
|
294
|
+
const content = fs.readFileSync(this.key_file, 'utf8');
|
|
295
|
+
//console.log('cert file content', content, '##################');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async savePublicCert() {
|
|
299
|
+
try {
|
|
300
|
+
const content = await fs.promises.readFile(this.cert_file, 'utf8');
|
|
301
|
+
await fs.promises.writeFile(this.pub_cert_file, content);
|
|
302
|
+
//console.log(`Public certificate saved to ${this.pub_cert_file}`);
|
|
303
|
+
console.log(`PUBLIC_KEY:`);
|
|
304
|
+
console.log(content);
|
|
305
|
+
|
|
306
|
+
await this.swiftStreamService.putFileContent(this.etny_bucket, 'cert.pem', this.pub_cert_file);
|
|
307
|
+
} catch (err) {
|
|
308
|
+
console.error(err);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
async saveResult() {
|
|
313
|
+
try {
|
|
314
|
+
await this.getLatestTrustedZoneImageCertPublicKey();
|
|
315
|
+
await this.encryptFileAndPushToSwiftStream(this.task_result, 'result.txt');
|
|
316
|
+
await this.encryptFileAndPushToSwiftStream(this.task_code.toString(), 'result_code.txt');
|
|
317
|
+
|
|
318
|
+
const encrypted = etny_crypto.encryptWithPublicKey(this._metadata.public_key, this.task_result);
|
|
319
|
+
//console.log('Encrypted result:', encrypted.toString('hex'));
|
|
320
|
+
const result = await this.swiftStreamService.putFileContent(this.etny_bucket, 'result.txt', this.result_file, encrypted.toString('hex'));
|
|
321
|
+
//console.log('Save result put: ', result);
|
|
322
|
+
} catch (e) {
|
|
323
|
+
console.log('Save result: ', e);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
async execute() {
|
|
328
|
+
const payload_data = await this.getFileContentAndDecrypt(this.etny_bucket, this.payload);
|
|
329
|
+
const input_data = await this.getFileContentAndDecrypt(this.etny_bucket, this.input);
|
|
330
|
+
console.log('Validating client payload and input...');
|
|
331
|
+
await this.validateClientPayload(payload_data, input_data);
|
|
332
|
+
|
|
333
|
+
if (this.is_valid_client_data) {
|
|
334
|
+
console.log('Client payload and input are valid');
|
|
335
|
+
} else {
|
|
336
|
+
console.log('Client payload and input are NOT valid');
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const task_result = executeTask(payload_data, input_data);
|
|
341
|
+
console.log('TASK RESULT (code, data):', task_result);
|
|
342
|
+
this.task_code = task_result[0];
|
|
343
|
+
this.task_result = task_result[1];
|
|
344
|
+
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function initSwiftStreamClient() {
|
|
351
|
+
console.log('Initializing SwiftStream Service...');
|
|
352
|
+
const swiftStreamClient = new SwiftStreamService(
|
|
353
|
+
EtnySecureLock.debug ? "localhost" : "etny-swift-stream",
|
|
354
|
+
9000,
|
|
355
|
+
"swiftstreamadmin",
|
|
356
|
+
"swiftstreamadmin");
|
|
357
|
+
console.log('SwiftStream Service started.');
|
|
358
|
+
console.log('################################');
|
|
359
|
+
|
|
360
|
+
return swiftStreamClient;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
async function execute() {
|
|
364
|
+
console.log('########################################');
|
|
365
|
+
console.log('########################################');
|
|
366
|
+
console.log('########## [ETNY SecureLock] ##########');
|
|
367
|
+
console.log('########################################');
|
|
368
|
+
console.log('########################################');
|
|
369
|
+
console.log('');
|
|
370
|
+
console.log('');
|
|
371
|
+
console.log('');
|
|
372
|
+
|
|
373
|
+
const swiftStreamClient = initSwiftStreamClient();
|
|
374
|
+
|
|
375
|
+
const app = new EtnySecureLock(swiftStreamClient);
|
|
376
|
+
|
|
377
|
+
const hasReadEnvFile = await app.readEnv();
|
|
378
|
+
if (!hasReadEnvFile && !EtnySecureLock.debug) {
|
|
379
|
+
console.log(`Failed reading .env file.`);
|
|
380
|
+
await app.savePublicCert();
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (process.env.ETNY_MODE === "PUBLIC_KEY") {
|
|
385
|
+
await app.savePublicCert();
|
|
386
|
+
} else {
|
|
387
|
+
console.log('Creating the application...');
|
|
388
|
+
const created = await app.create();
|
|
389
|
+
|
|
390
|
+
if (!created) {
|
|
391
|
+
console.log(`Failed at creation step, not able decoding input metadata, exiting.`);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
console.log('Waiting for payload and input to be downloaded...');
|
|
396
|
+
await app.waitForPayloadAndInput();
|
|
397
|
+
|
|
398
|
+
if (app.is_valid_client_data) {
|
|
399
|
+
console.log('Executing client code...');
|
|
400
|
+
const wasExecuted = await app.execute();
|
|
401
|
+
if (!wasExecuted) {
|
|
402
|
+
console.log('Failed execution of SecureLock enclave.')
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
} else {
|
|
406
|
+
console.log(`Failed client payload and input validation, ${app.task_result}, exiting.`);
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
await app.saveResult();
|
|
411
|
+
console.log('Finished process.');
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
(async () => {
|
|
416
|
+
try {
|
|
417
|
+
await execute();
|
|
418
|
+
} catch (e) {
|
|
419
|
+
console.log(e);
|
|
420
|
+
}
|
|
421
|
+
})();
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
const Minio = require('minio');
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
class SwiftStreamService {
|
|
4
|
+
constructor(endpoint, port, accessKey, secretKey) {
|
|
5
|
+
this.client = new Minio.Client({
|
|
6
|
+
endPoint: endpoint,
|
|
7
|
+
port: port,
|
|
8
|
+
accessKey: accessKey,
|
|
9
|
+
secretKey: secretKey,
|
|
10
|
+
useSSL: false,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
createBucket(bucketName) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
this.client.bucketExists(bucketName, (err, exists) => {
|
|
17
|
+
if (err) {
|
|
18
|
+
return reject(err);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!exists) {
|
|
22
|
+
this.client.makeBucket(bucketName, (err) => {
|
|
23
|
+
if (err) {
|
|
24
|
+
reject(err);
|
|
25
|
+
} else {
|
|
26
|
+
resolve(`Bucket ${bucketName} successfully created!`);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
} else {
|
|
30
|
+
resolve(`Bucket ${bucketName} already exists!`);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getFileContentBytes(bucketName, fileName) {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
const chunks = [];
|
|
39
|
+
this.client.getObject(bucketName, fileName, (err, dataStream) => {
|
|
40
|
+
if (err) {
|
|
41
|
+
return reject(err);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
dataStream.on('data', (chunk) => {
|
|
45
|
+
chunks.push(chunk);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
dataStream.on('end', () => {
|
|
49
|
+
const fileData = Buffer.concat(chunks);
|
|
50
|
+
resolve(fileData);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
dataStream.on('error', (err) => {
|
|
54
|
+
reject(err);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getFileContent(bucketName, fileName) {
|
|
61
|
+
return this.getFileContentBytes(bucketName, fileName)
|
|
62
|
+
.then((fileData) => {
|
|
63
|
+
return fileData.toString('utf-8');
|
|
64
|
+
})
|
|
65
|
+
.catch((err) => {
|
|
66
|
+
throw err;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
putFileContent(bucketName, objectName, objectPath, objectData = null) {
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
|
+
this.client.bucketExists(bucketName, (err, exists) => {
|
|
73
|
+
if (err) {
|
|
74
|
+
return reject(err);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!exists) {
|
|
78
|
+
this.createBucket(bucketName)
|
|
79
|
+
.then(() => {
|
|
80
|
+
if (objectData) {
|
|
81
|
+
this.client.putObject(bucketName, objectName, objectData, (err) => {
|
|
82
|
+
if (err) {
|
|
83
|
+
reject(err);
|
|
84
|
+
} else {
|
|
85
|
+
resolve(`${objectName} is successfully uploaded to bucket ${bucketName}.`);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
} else {
|
|
89
|
+
const fileStat = fs.statSync(objectPath);
|
|
90
|
+
const fileStream = fs.createReadStream(objectPath);
|
|
91
|
+
|
|
92
|
+
this.client.putObject(bucketName, objectName, fileStream, fileStat.size, (err) => {
|
|
93
|
+
if (err) {
|
|
94
|
+
reject(err);
|
|
95
|
+
} else {
|
|
96
|
+
resolve(`${objectName} is successfully uploaded to bucket ${bucketName}.`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
.catch((err) => {
|
|
102
|
+
reject(err);
|
|
103
|
+
});
|
|
104
|
+
} else {
|
|
105
|
+
if (objectData) {
|
|
106
|
+
this.client.putObject(bucketName, objectName, objectData, (err) => {
|
|
107
|
+
if (err) {
|
|
108
|
+
reject(err);
|
|
109
|
+
} else {
|
|
110
|
+
resolve(`${objectName} is successfully uploaded to bucket ${bucketName}.`);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
} else {
|
|
114
|
+
const fileStat = fs.statSync(objectPath);
|
|
115
|
+
const fileStream = fs.createReadStream(objectPath);
|
|
116
|
+
|
|
117
|
+
this.client.putObject(bucketName, objectName, fileStream, fileStat.size, (err) => {
|
|
118
|
+
if (err) {
|
|
119
|
+
reject(err);
|
|
120
|
+
} else {
|
|
121
|
+
resolve(`${objectName} is successfully uploaded to bucket ${bucketName}.`);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
isObjectInBucket(bucketName, objectName) {
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
this.client.statObject(bucketName, objectName, (err, stat) => {
|
|
133
|
+
if (err && err.code === 'NotFound') {
|
|
134
|
+
resolve([stat, false]);
|
|
135
|
+
} else if (err) {
|
|
136
|
+
reject(err);
|
|
137
|
+
} else {
|
|
138
|
+
// resolve(`Object ${objectName} exists inside ${bucketName}.`);
|
|
139
|
+
resolve([stat, true]);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
module.exports = SwiftStreamService;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class TaskStatus {
|
|
2
|
+
static SUCCESS = 0;
|
|
3
|
+
static SYSTEM_ERROR = 1;
|
|
4
|
+
static KEY_ERROR = 2;
|
|
5
|
+
static SYNTAX_WARNING = 3;
|
|
6
|
+
static BASE_EXCEPTION = 4;
|
|
7
|
+
static PAYLOAD_NOT_DEFINED = 5;
|
|
8
|
+
static PAYLOAD_CHECKSUM_ERROR = 6;
|
|
9
|
+
static INPUT_CHECKSUM_ERROR = 7;
|
|
10
|
+
static EVAL_ERROR = 8;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
TaskStatus,
|
|
15
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const ethers = require('ethers');
|
|
2
|
+
const {sha256} = require('./etny_crypto');
|
|
3
|
+
|
|
4
|
+
function getWalletAddress(clientChallenge, enclaveChallenge) {
|
|
5
|
+
const encoded = clientChallenge + enclaveChallenge;
|
|
6
|
+
//console.log(encoded);
|
|
7
|
+
const walletPrivate = sha256(sha256(encoded));
|
|
8
|
+
//console.log(`0x${walletPrivate}`);
|
|
9
|
+
|
|
10
|
+
const wallet = new ethers.Wallet(walletPrivate);
|
|
11
|
+
//console.log(wallet);
|
|
12
|
+
console.log('Enclave wallet address:', wallet.address);
|
|
13
|
+
return [wallet.address, walletPrivate];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function generateWalletFromPrivate(hash) {
|
|
17
|
+
return new ethers.Wallet(hash);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// const firstString = 'test';
|
|
21
|
+
// const secondString = 'test';
|
|
22
|
+
// const [addr, private] = getWalletAddress(firstString, secondString);
|
|
23
|
+
// console.log('account address =', addr); // 0xf63106856F7007A30025f0fFD5A534EA880878C3
|
|
24
|
+
// console.log('private =', private);
|
|
25
|
+
|
|
26
|
+
module.exports = {
|
|
27
|
+
getWalletAddress,
|
|
28
|
+
generateWalletFromPrivate
|
|
29
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
FROM registry.scontain.com:5050/ethernity/node:16.13.1-alpine3.15-scone5.8-production as release
|
|
2
|
+
|
|
3
|
+
RUN apk update
|
|
4
|
+
|
|
5
|
+
RUN cd /
|
|
6
|
+
|
|
7
|
+
RUN apk add bash
|
|
8
|
+
|
|
9
|
+
ENV SCONE_MODE=SIM
|
|
10
|
+
ENV SCONE_HEAP=256M
|
|
11
|
+
ENV SCONE_LOG=DEBUG
|
|
12
|
+
ENV ENCLAVE_NAME_TRUSTEDZONE=etny-nodenithy
|
|
13
|
+
|
|
14
|
+
RUN mkdir binary-fs-dir
|
|
15
|
+
|
|
16
|
+
COPY src/* /etny-trustedzone/
|
|
17
|
+
COPY scripts/* /etny-trustedzone/
|
|
18
|
+
|
|
19
|
+
WORKDIR /etny-trustedzone
|
|
20
|
+
RUN pwd
|
|
21
|
+
RUN npm install
|
|
22
|
+
RUN ls
|
|
23
|
+
|
|
24
|
+
WORKDIR /
|
|
25
|
+
|
|
26
|
+
RUN ["chmod", "+x", "etny-trustedzone/binary-fs-build.sh"]
|
|
27
|
+
RUN etny-trustedzone/binary-fs-build.sh
|
|
28
|
+
|
|
29
|
+
FROM registry.scontain.com:5050/sconecuratedimages/crosscompilers as build
|
|
30
|
+
|
|
31
|
+
COPY --from=release /binary-fs-dir /.
|
|
32
|
+
|
|
33
|
+
RUN scone gcc ./binary_fs_blob.s ./libbinary_fs_template.a -shared -o /libbinary-fs.so
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
FROM registry.scontain.com:5050/ethernity/node:16.13.1-alpine3.15-scone5.8-production
|
|
37
|
+
|
|
38
|
+
COPY --from=build /libbinary-fs.so /lib/libbinary-fs.so
|
|
39
|
+
#
|
|
40
|
+
|
|
41
|
+
RUN apk update
|
|
42
|
+
|
|
43
|
+
RUN apk add openssl
|
|
44
|
+
|
|
45
|
+
RUN openssl genrsa -3 -out /enclave-key.pem 3072
|
|
46
|
+
|
|
47
|
+
ENV SCONE_LOG=info
|
|
48
|
+
ENV SCONE_HEAP=256M
|
|
49
|
+
ENV SCONE_ALLOW_DLOPEN=1
|
|
50
|
+
ENV SCONE_EXTENSIONS_PATH=/lib/libbinary-fs.so
|
|
51
|
+
|
|
52
|
+
# RUN scone-signer sign --key=/enclave-key.pem --env --production /usr/bin/node
|
|
53
|
+
RUN rm -rf /enclave-key.pem
|
|
54
|
+
|
|
55
|
+
#RUN scone cas attest scone-cas.cf 3061b9feb7fa67f3815336a085f629a13f04b0a1667c93b14ff35581dc8271e4 -GCS --only_for_testing-debug --only_for_testing-ignore-signer
|
|
56
|
+
RUN ls /usr/local/bin
|
|
57
|
+
ENTRYPOINT ["/usr/local/bin/node", "/etny-trustedzone/trustedzone.js"]
|