@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,508 @@
|
|
|
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 {TaskStatus} = require("./task_status");
|
|
11
|
+
const SwiftStreamService = require("./swift_stream_service");
|
|
12
|
+
|
|
13
|
+
const contract_abi = require('./pox_abi');
|
|
14
|
+
const image_registry_abi = require('./image_registry_abi');
|
|
15
|
+
const {sha256} = require("./etny_crypto");
|
|
16
|
+
|
|
17
|
+
class EtnyTrustedZone {
|
|
18
|
+
static debug = false;
|
|
19
|
+
|
|
20
|
+
constructor(swiftStreamClient) {
|
|
21
|
+
console.log('Initializing...');
|
|
22
|
+
this.version = 'v3';
|
|
23
|
+
this.swiftStreamService = swiftStreamClient;
|
|
24
|
+
this.etny_bucket = "etny-nodenithy-v3";
|
|
25
|
+
this.setInitializers();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
setInitializers() {
|
|
29
|
+
this.is_valid_client_data = true;
|
|
30
|
+
this.private_key_file = "/private/__ENCLAVE_NAME_TRUSTEDZONE__/key.pem";
|
|
31
|
+
this.cert_file = "/app/__ENCLAVE_NAME_TRUSTEDZONE__/cert.pem";
|
|
32
|
+
this.pub_cert_file = "/app/__ENCLAVE_NAME_TRUSTEDZONE__/app.pem";
|
|
33
|
+
this.payload = "payload.etny";
|
|
34
|
+
this.input = "input.txt";
|
|
35
|
+
this.result_file = "/app/result.txt";
|
|
36
|
+
this.transaction_file = "/app/transaction.txt";
|
|
37
|
+
this.smart_contract_address = "0x549A6E06BB2084100148D50F51CF77a3436C3Ae7 ";
|
|
38
|
+
this.image_registry_address = '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31';
|
|
39
|
+
this.chain_id = 8995;
|
|
40
|
+
this.web3_provider = "https://bloxberg.ethernity.cloud";
|
|
41
|
+
this.signed_tx_as_bytes = null;
|
|
42
|
+
this.client_challenge = "";
|
|
43
|
+
|
|
44
|
+
if (this.etny_mode === "TEST") {
|
|
45
|
+
this.private_key_file = "/private/key.pem";
|
|
46
|
+
this.cert_file = "/app/cert.pem";
|
|
47
|
+
this.payload = "./app/payload.js";
|
|
48
|
+
this.input = "./app/input.txt";
|
|
49
|
+
this.result_file = "./app/result.txt";
|
|
50
|
+
this.transaction_file = "./app/transaction.txt";
|
|
51
|
+
this.pub_cert_file = "./app/enclave_pub_cert.pem";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (this.etny_mode === "LOCAL_TEST") {
|
|
55
|
+
this.private_key_file = "./certs/key.pem";
|
|
56
|
+
this.cert_file = "./certs/cert.pem";
|
|
57
|
+
this.payload = "./app/payload.js";
|
|
58
|
+
this.input = "./app/input.txt";
|
|
59
|
+
this.result_file = "./app/result.txt";
|
|
60
|
+
this.transaction_file = "./app/transaction.txt";
|
|
61
|
+
this.pub_cert_file = "./app/enclave_pub_cert.pem";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async create() {
|
|
66
|
+
//overriding default values with those read from .env file
|
|
67
|
+
this.loadEnv();
|
|
68
|
+
this.printEnv();
|
|
69
|
+
await this.savePublicCert();
|
|
70
|
+
this.readClientChallenge();
|
|
71
|
+
this.generateNodeChallenge();
|
|
72
|
+
const wasAbleToDecode = this.decodeClientDataAndGenerateWallet();
|
|
73
|
+
|
|
74
|
+
//console.log(`wasAbleToDecode: ${wasAbleToDecode}`);
|
|
75
|
+
if (!wasAbleToDecode) {
|
|
76
|
+
console.log('Unable to decode client data, exiting.');
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
this.initWeb3();
|
|
80
|
+
if (this.etny_mode === "PRODUCTION") {
|
|
81
|
+
this.resetPrivateCertFile();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
loadEnv() {
|
|
88
|
+
if (process.env.ETNY_CHAIN_ID) {
|
|
89
|
+
this.chain_id = parseInt(process.env.ETNY_CHAIN_ID);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (process.env.ETNY_SMART_CONTRACT_ADDRESS) {
|
|
93
|
+
this.smart_contract_address = process.env.ETNY_SMART_CONTRACT_ADDRESS.trim();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (process.env.ETNY_WEB3_PROVIDER) {
|
|
97
|
+
this.web3_provider = process.env.ETNY_WEB3_PROVIDER.trim();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (process.env.ETNY_CLIENT_CHALLENGE) {
|
|
101
|
+
this.client_challenge = process.env.ETNY_CLIENT_CHALLENGE.trim();
|
|
102
|
+
}
|
|
103
|
+
if (process.env.ETNY_ORDER_ID) {
|
|
104
|
+
this.order_id = parseInt(process.env.ETNY_ORDER_ID);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
printEnv() {
|
|
109
|
+
console.log('CHAIN ID:', this.chain_id);
|
|
110
|
+
console.log('SMART CONTRACT ADDRESS:', this.smart_contract_address);
|
|
111
|
+
console.log('WEB3 PROVIDER:', this.web3_provider);
|
|
112
|
+
console.log('ENCRYPTED CHALLENGE:', this.client_challenge);
|
|
113
|
+
console.log('ORDER ID:', this.order_id);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
initWeb3() {
|
|
117
|
+
// Create an ethers.js provider connected to the Bloxberg network
|
|
118
|
+
this.w3 = new ethers.providers.JsonRpcProvider(this.web3_provider);
|
|
119
|
+
this.walletSigner = new ethers.Wallet(this.walletPrivateKey, this.w3);
|
|
120
|
+
// Create an instance of the contract using the ABI and address
|
|
121
|
+
this.etny = new ethers.Contract(this.smart_contract_address, contract_abi, this.w3);
|
|
122
|
+
this.etny_signer = new ethers.Contract(this.smart_contract_address, contract_abi, this.walletSigner);
|
|
123
|
+
this.image_registry = new ethers.Contract(this.image_registry_address, image_registry_abi, this.w3);
|
|
124
|
+
// this.image_registry_signer = new ethers.Contract(this.image_registry_address, image_registry_abi, this.walletSigner);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async readEnv() {
|
|
128
|
+
try {
|
|
129
|
+
console.log('Getting .env if exists...');
|
|
130
|
+
const envFile = await this.swiftStreamService.getFileContent(this.etny_bucket, ".env");
|
|
131
|
+
console.log("Env:", envFile);
|
|
132
|
+
console.log("Saving .env file...");
|
|
133
|
+
await fs.promises.writeFile('.env', envFile);
|
|
134
|
+
require('dotenv').config();
|
|
135
|
+
|
|
136
|
+
this.version = 'v3';
|
|
137
|
+
this.etny_mode = process.env.ETNY_MODE;
|
|
138
|
+
console.log(`ETNY Nodenithy [${this.version}] - running in ${this.etny_mode} MODE`);
|
|
139
|
+
//console.log(process.env);
|
|
140
|
+
|
|
141
|
+
return true;
|
|
142
|
+
} catch (e) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// convert client challenge
|
|
148
|
+
readClientChallenge() {
|
|
149
|
+
this.encrypted_tuple = etny_crypto.encryptedDataFromBase64Json(this.client_challenge);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
generateNodeChallenge(length = 20) {
|
|
153
|
+
const lowercaseOnly = [...Array(length)].map(() => Math.random().toString(36)[2]).join('');
|
|
154
|
+
//console.log('random challenge:', lowercaseOnly);
|
|
155
|
+
this.enclave_challenge = lowercaseOnly;
|
|
156
|
+
return this.enclave_challenge;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
decodeClientDataAndGenerateWallet() {
|
|
160
|
+
console.log('started decoding challenge...');
|
|
161
|
+
const decryptedResult = etny_crypto.decrypt(this.private_key_file, this.encrypted_tuple);
|
|
162
|
+
if (!decryptedResult) {
|
|
163
|
+
return false;
|
|
164
|
+
} else {
|
|
165
|
+
//console.log('decrypted_string = ', decryptedResult);
|
|
166
|
+
const [publicKey, privateKey] = getWalletAddress(decryptedResult, this.enclave_challenge);
|
|
167
|
+
this.wallet = publicKey;
|
|
168
|
+
this.walletPrivateKey = privateKey;
|
|
169
|
+
|
|
170
|
+
//console.log("wallet = ", this.wallet);
|
|
171
|
+
//console.log("private = ", this.walletPrivateKey);
|
|
172
|
+
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
extractSigner(message, signature) {
|
|
178
|
+
return ethers.utils.verifyMessage(message, signature);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async validateClientPayload(payload_data, input_data) {
|
|
182
|
+
if (this._metadata.payload_metadata_obj.checksum !== null) {
|
|
183
|
+
const payload_checksum = sha256(payload_data);
|
|
184
|
+
//console.log('payload checksum: ', payload_checksum, "===", this._metadata.payload_metadata_obj.checksum);
|
|
185
|
+
// check the wallet address that signed payload checksum is the one from order metadata
|
|
186
|
+
const payload_signer = this.extractSigner(payload_checksum, this._metadata.payload_metadata_obj.checksum);
|
|
187
|
+
//console.log("payload_signer", payload_signer);
|
|
188
|
+
//console.log("this._order_metadata.do_owner.toLowerCase()", this._order_metadata.do_owner.toLowerCase());
|
|
189
|
+
if (payload_signer.toLowerCase() !== this._order_metadata.do_owner.toLowerCase()) {
|
|
190
|
+
this.task_code = TaskStatus.PAYLOAD_CHECKSUM_ERROR;
|
|
191
|
+
this.task_result = 'PAYLOAD CHECKSUM DOESN\'T MATCH';
|
|
192
|
+
this.is_valid_client_data = false;
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (this._metadata.input_metadata_obj.checksum !== null) {
|
|
197
|
+
const input_checksum = sha256(input_data);
|
|
198
|
+
//console.log('input checksum: ', input_checksum, '===', this._metadata.input_metadata_obj.checksum);
|
|
199
|
+
// check the wallet address that signed input checksum is the one from order metadata
|
|
200
|
+
const input_signer = this.extractSigner(input_checksum, this._metadata.input_metadata_obj.checksum);
|
|
201
|
+
//console.log("input_signer", input_signer);
|
|
202
|
+
//console.log("this._order_metadata.do_owner.toLowerCase()", this._order_metadata.do_owner.toLowerCase());
|
|
203
|
+
if (input_signer.toLowerCase() !== this._order_metadata.do_owner.toLowerCase()) {
|
|
204
|
+
this.task_code = TaskStatus.INPUT_CHECKSUM_ERROR;
|
|
205
|
+
this.task_result = 'INPUT CHECKSUM DOESN\'T MATCH';
|
|
206
|
+
this.is_valid_client_data = false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
wait(timeout) {
|
|
212
|
+
return new Promise(resolve => {
|
|
213
|
+
setTimeout(resolve, timeout);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async waitForObjectInBucket(bucketName, objectName, timeout = 600) {
|
|
218
|
+
let i = 0;
|
|
219
|
+
console.log(`Checking if object ${objectName} exists in bucket ${bucketName}`);
|
|
220
|
+
while (true) {
|
|
221
|
+
await this.wait(1000);
|
|
222
|
+
i++;
|
|
223
|
+
if (i % 20 === 0)
|
|
224
|
+
console.log(`Checking if object ${objectName} exists in bucket ${bucketName}`);
|
|
225
|
+
if (i > timeout) {
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
const [status, result] = await this.swiftStreamService.isObjectInBucket(bucketName, objectName);
|
|
229
|
+
if (result) {
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
console.log('secure lock finished the execution');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async waitForTask() {
|
|
238
|
+
console.log('Waiting for payload and input');
|
|
239
|
+
await this.waitForObjectInBucket(this.etny_bucket, "result.txt.securelock");
|
|
240
|
+
this.task_result = await this.getFileContentAndDecrypt(this.etny_bucket, "result.txt.securelock");
|
|
241
|
+
this.task_code = await this.getFileContentAndDecrypt(this.etny_bucket, "result_code.txt.securelock");
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async getFileContentAndDecrypt(bucketName, objectName, isEmptyInput = false) {
|
|
245
|
+
try {
|
|
246
|
+
const encryptedBase64 = await this.swiftStreamService.getFileContent(bucketName, objectName);
|
|
247
|
+
console.log(`File ${objectName} downloaded from swift stream successfully`);
|
|
248
|
+
//console.log(encryptedBase64);
|
|
249
|
+
if (isEmptyInput) {
|
|
250
|
+
return encryptedBase64;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
console.log('Decrypting the file with private key:');
|
|
254
|
+
const encryptedTuple = etny_crypto.encryptedDataFromBase64Json(encryptedBase64);
|
|
255
|
+
//console.log('encryptedTuple: ', encryptedTuple);
|
|
256
|
+
const decryptedResult = etny_crypto.decrypt(this.private_key_file, encryptedTuple);
|
|
257
|
+
//console.log('decryptedResult: ', decryptedResult);
|
|
258
|
+
return decryptedResult;
|
|
259
|
+
} catch (e) {
|
|
260
|
+
console.log('Error:', e);
|
|
261
|
+
console.log(`Failed to get ${objectName} file`);
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async getSecureLockPublicKey() {
|
|
267
|
+
console.log('Getting the public key of the secure lock enclave');
|
|
268
|
+
let imageHash = this._metadata.image_hash;
|
|
269
|
+
console.log('Image Hash Secure lock:', imageHash);
|
|
270
|
+
if (EtnyTrustedZone.debug) {
|
|
271
|
+
imageHash = 'v3-hash-1';
|
|
272
|
+
}
|
|
273
|
+
this.secureLockPublicKey = await this.image_registry.getImageCertPublicKey(imageHash);
|
|
274
|
+
console.log('public key of the SecureLock enclave:', this.secureLockPublicKey)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async encryptFileAndPushToSwiftStream(fileData, fileName) {
|
|
278
|
+
try {
|
|
279
|
+
const encryptedInput = etny_crypto.encrypt(this.secureLockPublicKey, fileData);
|
|
280
|
+
const encryptedInputBase64 = etny_crypto.encryptedDataToBase64Json(encryptedInput);
|
|
281
|
+
|
|
282
|
+
// File name should end with the '.securelock' extension
|
|
283
|
+
fileName += '.securelock';
|
|
284
|
+
// const data = Buffer.from(encryptedInputBase64, 'utf8');
|
|
285
|
+
const status = this.swiftStreamService.putFileContent(this.etny_bucket, fileName, '', encryptedInputBase64);
|
|
286
|
+
if (status) {
|
|
287
|
+
console.log(`File ${fileName} encrypted and saved to swift stream successfully`);
|
|
288
|
+
}
|
|
289
|
+
} catch (e) {
|
|
290
|
+
console.log('encryptFileAndPushToSwiftStream:', e);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
checkIfIsEmptyInput() {
|
|
295
|
+
const empty_input_checksum = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
|
|
296
|
+
const input_signer = this.extractSigner(empty_input_checksum, this._metadata.input_metadata_obj.checksum);
|
|
297
|
+
return input_signer.toLowerCase() === this._order_metadata.do_owner.toLowerCase();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
async prepareContextForSecureLock() {
|
|
301
|
+
await this.getSecureLockPublicKey();
|
|
302
|
+
const payloadData = await this.getFileContentAndDecrypt(this.etny_bucket, 'payload.etny');
|
|
303
|
+
//console.log('payloadData:', payloadData);
|
|
304
|
+
//console.log('payloadDataChecksum:', sha256(payloadData));
|
|
305
|
+
const isEmptyInput = this.checkIfIsEmptyInput();
|
|
306
|
+
const inputData = await this.getFileContentAndDecrypt(this.etny_bucket, 'input.txt', isEmptyInput);
|
|
307
|
+
|
|
308
|
+
console.log('Validate client payload and input');
|
|
309
|
+
await this.validateClientPayload(payloadData, inputData);
|
|
310
|
+
if (this.is_valid_client_data) {
|
|
311
|
+
console.log('Client payload and input are valid');
|
|
312
|
+
} else {
|
|
313
|
+
console.log('Client payload and input are NOT valid');
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
console.log('Pushing payload.etny.securelock');
|
|
318
|
+
await this.encryptFileAndPushToSwiftStream(payloadData, this.payload);
|
|
319
|
+
console.log('Pushing input.txt.securelock');
|
|
320
|
+
await this.encryptFileAndPushToSwiftStream(inputData, this.input);
|
|
321
|
+
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
async getDORequestMetadata() {
|
|
326
|
+
const o_result = await this.etny.functions._getOrder(this.order_id);
|
|
327
|
+
const order = new Order(o_result, this.order_id);
|
|
328
|
+
//console.log('order', order);
|
|
329
|
+
this._order_metadata = order;
|
|
330
|
+
const o_metadata = await this.etny.functions._getDORequestMetadata(order.do_req);
|
|
331
|
+
//console.log('o_metadata', o_metadata);
|
|
332
|
+
this._metadata = new DOReqMetadata(o_metadata, order.do_req);
|
|
333
|
+
//console.log('metadata', this._metadata);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
resetPrivateCertFile() {
|
|
337
|
+
//console.log('Resetting the cert file');
|
|
338
|
+
try {
|
|
339
|
+
// const fd = fs.openSync(this.private_key_file, 'w+');
|
|
340
|
+
fs.truncate(this.private_key_file, 0, function () {
|
|
341
|
+
//console.log('Private certificate file was cleaned.')
|
|
342
|
+
});
|
|
343
|
+
// fs.closeSync(fd);
|
|
344
|
+
} catch (e) {
|
|
345
|
+
//console.log('Error while removing the private key file content', e);
|
|
346
|
+
}
|
|
347
|
+
const content = fs.readFileSync(this.private_key_file, 'utf8');
|
|
348
|
+
//console.log('cert file content', content, '##################');
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async savePublicCert() {
|
|
352
|
+
try {
|
|
353
|
+
const content = await fs.promises.readFile(this.cert_file, 'utf8');
|
|
354
|
+
await fs.promises.writeFile(this.pub_cert_file, content);
|
|
355
|
+
console.log(`Public certificate saved to ${this.pub_cert_file}`);
|
|
356
|
+
console.log(`PUBLIC_KEY:`);
|
|
357
|
+
console.log(content);
|
|
358
|
+
|
|
359
|
+
await this.swiftStreamService.putFileContent(this.etny_bucket, 'cert.pem', this.pub_cert_file);
|
|
360
|
+
} catch (err) {
|
|
361
|
+
console.error(err);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
buildResult() {
|
|
366
|
+
this.result = `${this.version}:${this.task_code}:${this.task_result_checksum}:${this.enclave_challenge}:`;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
getResultChecksum() {
|
|
370
|
+
this.task_result_checksum = etny_crypto.sha256(this.task_result);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
async buildTransaction() {
|
|
374
|
+
this.buildResult();
|
|
375
|
+
|
|
376
|
+
console.log(`adding result to order ${this.order_id}`);
|
|
377
|
+
|
|
378
|
+
// Call a method in the contract and get the encoded data
|
|
379
|
+
const args = [this.order_id, this.result];
|
|
380
|
+
const nonce = await this.walletSigner.getTransactionCount();
|
|
381
|
+
const tx = await this.etny_signer.populateTransaction._addResultToOrder(...args);
|
|
382
|
+
|
|
383
|
+
// Create a transaction object
|
|
384
|
+
const transaction = {
|
|
385
|
+
...tx,
|
|
386
|
+
nonce,
|
|
387
|
+
gasLimit: ethers.utils.hexlify(1000000),
|
|
388
|
+
gasPrice: ethers.utils.parseUnits('1', 'mwei')
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
// Sign the transaction and send it to the network
|
|
392
|
+
const signedTransaction = await this.walletSigner.signTransaction(transaction);
|
|
393
|
+
this.signed_tx_as_bytes = signedTransaction;
|
|
394
|
+
console.log(signedTransaction);
|
|
395
|
+
return signedTransaction;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
async saveTransaction() {
|
|
399
|
+
try {
|
|
400
|
+
const tx = await this.swiftStreamService.putFileContent(this.etny_bucket, 'transaction.txt', this.transaction_file, this.signed_tx_as_bytes);
|
|
401
|
+
//console.log(tx);
|
|
402
|
+
const result = await this.swiftStreamService.getFileContent(this.etny_bucket, 'transaction.txt');
|
|
403
|
+
//console.log('Getting file transaction.txt :', result);
|
|
404
|
+
} catch (e) {
|
|
405
|
+
console.log('Save transaction error: ', e);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
async saveResult() {
|
|
411
|
+
try {
|
|
412
|
+
console.log('Encrypting result with public key:', this._metadata.public_key);
|
|
413
|
+
const encrypted = etny_crypto.encryptWithPublicKey(this._metadata.public_key, this.task_result);
|
|
414
|
+
//console.log('Encrypted result:', encrypted.toString('hex'));
|
|
415
|
+
const result = await this.swiftStreamService.putFileContent(this.etny_bucket, 'result.txt', this.result_file, encrypted.toString('hex'));
|
|
416
|
+
//console.log('Save result put: ', result);
|
|
417
|
+
|
|
418
|
+
const result1 = await this.swiftStreamService.getFileContent(this.etny_bucket, 'result.txt');
|
|
419
|
+
//console.log('Getting file transaction.txt :', result1);
|
|
420
|
+
} catch (e) {
|
|
421
|
+
console.log('Save result error: ', e);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
async execute() {
|
|
426
|
+
await this.getDORequestMetadata();
|
|
427
|
+
console.log('Validating client payload and input...');
|
|
428
|
+
const isAllPrepared = await this.prepareContextForSecureLock();
|
|
429
|
+
if (!isAllPrepared) {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
await this.waitForTask();
|
|
433
|
+
console.log('TASK RESULT (code, data):', this.task_code, this.task_result);
|
|
434
|
+
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function initSwiftStreamClient() {
|
|
440
|
+
console.log('Initializing SwiftStream Service...');
|
|
441
|
+
const swiftStreamClient = new SwiftStreamService(
|
|
442
|
+
EtnyTrustedZone.debug ? "localhost" : "etny-swift-stream",
|
|
443
|
+
9000,
|
|
444
|
+
"swiftstreamadmin",
|
|
445
|
+
"swiftstreamadmin");
|
|
446
|
+
console.log('SwiftStream Service started.');
|
|
447
|
+
console.log('################################');
|
|
448
|
+
|
|
449
|
+
return swiftStreamClient;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
async function execute() {
|
|
453
|
+
console.log('########################################');
|
|
454
|
+
console.log('########################################');
|
|
455
|
+
console.log('########## [ETNY TrustedZone] ##########');
|
|
456
|
+
console.log('########################################');
|
|
457
|
+
console.log('########################################');
|
|
458
|
+
console.log('');
|
|
459
|
+
console.log('');
|
|
460
|
+
console.log('');
|
|
461
|
+
|
|
462
|
+
const swiftStreamClient = initSwiftStreamClient();
|
|
463
|
+
|
|
464
|
+
const app = new EtnyTrustedZone(swiftStreamClient);
|
|
465
|
+
|
|
466
|
+
const hasReadEnvFile = await app.readEnv();
|
|
467
|
+
if (!hasReadEnvFile && !EtnyTrustedZone.debug) {
|
|
468
|
+
console.log(`Failed reading .env file.`);
|
|
469
|
+
await app.savePublicCert();
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (process.env.ETNY_MODE === "PUBLIC_KEY") {
|
|
474
|
+
await app.savePublicCert();
|
|
475
|
+
} else {
|
|
476
|
+
console.log('Creating the application...');
|
|
477
|
+
const created = await app.create();
|
|
478
|
+
|
|
479
|
+
if (!created) {
|
|
480
|
+
console.log(`Failed at creation step, not able decoding input metadata, exiting.`);
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const wasExecuted = await app.execute();
|
|
485
|
+
if (!wasExecuted) {
|
|
486
|
+
console.log('Task execution failed!');
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
console.log('Generating task result checksum...');
|
|
491
|
+
app.getResultChecksum();
|
|
492
|
+
console.log('Building transaction...');
|
|
493
|
+
await app.buildTransaction();
|
|
494
|
+
console.log('Saving transaction...');
|
|
495
|
+
await app.saveTransaction();
|
|
496
|
+
console.log('Saving the result...');
|
|
497
|
+
await app.saveResult();
|
|
498
|
+
console.log('Finished process.');
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
(async () => {
|
|
503
|
+
try {
|
|
504
|
+
await execute();
|
|
505
|
+
} catch (e) {
|
|
506
|
+
console.log(e);
|
|
507
|
+
}
|
|
508
|
+
})();
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
const wallet = new ethers.Wallet(walletPrivate);
|
|
10
|
+
//console.log(wallet);
|
|
11
|
+
console.log('Enclave wallet address:', wallet.address);
|
|
12
|
+
return [wallet.address, walletPrivate];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function generateWalletFromPrivate(hash) {
|
|
16
|
+
return new ethers.Wallet(hash);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// const firstString = 'test';
|
|
20
|
+
// const secondString = 'test';
|
|
21
|
+
// const [addr, private] = getWalletAddress(firstString, secondString);
|
|
22
|
+
// console.log('account address =', addr); // 0xf63106856F7007A30025f0fFD5A534EA880878C3
|
|
23
|
+
// console.log('private =', private);
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
getWalletAddress,
|
|
27
|
+
generateWalletFromPrivate
|
|
28
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
FROM registry.ethernity.cloud:443/debuggingdelight/ethernity-cloud-sdk-registry/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
|
+
|
|
13
|
+
RUN mkdir binary-fs-dir
|
|
14
|
+
|
|
15
|
+
COPY src/* /etny-trustedzone/
|
|
16
|
+
COPY scripts/* /etny-trustedzone/
|
|
17
|
+
COPY src/trustedzone.js /etny-trustedzone/trustedzone.py
|
|
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.ethernity.cloud:443/debuggingdelight/ethernity-cloud-sdk-registry/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.ethernity.cloud:443/debuggingdelight/ethernity-cloud-sdk-registry/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 cp /usr/local/bin/node /usr/local/bin/python3
|
|
53
|
+
RUN scone-signer sign --key=/enclave-key.pem --env --production /usr/bin/node
|
|
54
|
+
RUN rm -rf /enclave-key.pem
|
|
55
|
+
|
|
56
|
+
#RUN scone cas attest scone-cas.cf 3061b9feb7fa67f3815336a085f629a13f04b0a1667c93b14ff35581dc8271e4 -GCS --only_for_testing-debug --only_for_testing-ignore-signer
|
|
57
|
+
RUN ls /usr/local/bin
|
|
58
|
+
ENTRYPOINT ["/usr/local/bin/node", "/etny-trustedzone/trustedzone.js"]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/bin/bash -v
|
|
2
|
+
|
|
3
|
+
cd /etny-trustedzone
|
|
4
|
+
ls
|
|
5
|
+
echo "####################"
|
|
6
|
+
cat .env
|
|
7
|
+
echo "####################"
|
|
8
|
+
|
|
9
|
+
echo "starting building binary-fs..."
|
|
10
|
+
EXEC=(scone binaryfs / /binary-fs-dir -v \
|
|
11
|
+
--include '/usr/local/bin/node' \
|
|
12
|
+
--include '/etny-trustedzone/*' \
|
|
13
|
+
--host-path=/etc/resolv.conf \
|
|
14
|
+
--host-path=/etc/hosts)
|
|
15
|
+
echo "finished building binary-fs..."
|
|
16
|
+
|
|
17
|
+
exec "${EXEC[@]}"
|
|
18
|
+
|
|
19
|
+
exit
|