#include #include #include #include #include #include "sgx_urts.h" #include "sgx_tcrypto.h" #include "sgx_tseal.h" #include "Untrusted.hpp" #include "config.hpp" #include "net.hpp" #include "start.hpp" static bool hexdump(FILE *outf, const char *label, void *p, size_t len) { unsigned char *pc = (unsigned char *)p; if (label) { if (fprintf(outf, "%s: ", label) < 0) { return false; } } for (size_t i=0; i 1 && !strcmp(argv[1], "--gen")) { if (argc != 4) { usage(argv[0]); exit(1); } const char *sealedprivkeyfile = argv[2]; const char *pubkeyfile = argv[3]; FILE *sprivf = fopen(sealedprivkeyfile, "rb"); if (sprivf && loadkey(sprivf, pubkeyfile)) { // We successfully used an existing sealedprivkeyfile fclose(sprivf); return 0; } if (sprivf) { fclose(sprivf); } // Generate a new keypair if (genkey(sealedprivkeyfile, pubkeyfile)) { return 0; } // Something went wrong exit(1); } if (argc < 3) { usage(argv[0]); exit(1); } const char *sealedprivkeyfile = argv[1]; std::string myname(argv[2]); // Read the config.json from the first line of stdin. We have to do // this before outputting anything to avoid potential deadlock with // the launch program. std::string configstr; std::getline(std::cin, configstr); // Load the sealed private key FILE *sprivf = fopen(sealedprivkeyfile, "rb"); if (!sprivf) { perror("Cannot read sealed private key file"); exit(1); } if (!loadkey(sprivf, NULL)) { fprintf(stderr, "Could not load sealed private key\n"); exit(1); } fclose(sprivf); Config config; if (!config_parse(config, configstr, myname)) { exit(1); } boost::asio::io_context io_context; // The NetIO will keep a (const) reference to the config NetIO netio(io_context, config); // Queue up the actual work boost::asio::post(io_context, [&]{ start(netio, argc, argv); }); // Start another thread; one will perform the work and the other // will execute the async_write handlers boost::thread t([&]{io_context.run();}); io_context.run(); t.join(); // All done sgx_destroy_enclave(global_eid); return 0; }