|
@@ -1,23 +1,34 @@
|
|
#include <cstdio>
|
|
#include <cstdio>
|
|
|
|
+#include <cstring>
|
|
|
|
|
|
#include "sgx_urts.h"
|
|
#include "sgx_urts.h"
|
|
#include "sgx_tcrypto.h"
|
|
#include "sgx_tcrypto.h"
|
|
#include "sgx_tseal.h"
|
|
#include "sgx_tseal.h"
|
|
#include "Untrusted.hpp"
|
|
#include "Untrusted.hpp"
|
|
|
|
|
|
-static void dump(const char *label, void *p, size_t len)
|
|
|
|
|
|
+static bool hexdump(FILE *outf, const char *label, void *p, size_t len)
|
|
{
|
|
{
|
|
unsigned char *pc = (unsigned char *)p;
|
|
unsigned char *pc = (unsigned char *)p;
|
|
if (label) {
|
|
if (label) {
|
|
- printf("%s: ", label);
|
|
|
|
|
|
+ if (fprintf(outf, "%s: ", label) < 0) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
for (size_t i=0; i<len; ++i) {
|
|
for (size_t i=0; i<len; ++i) {
|
|
- printf("%02x", pc[i]);
|
|
|
|
|
|
+ if (fprintf(outf, "%02x", pc[i]) < 0) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- printf("\n");
|
|
|
|
|
|
+ if (fprintf(outf, "\n") < 0) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
-static void genkey()
|
|
|
|
|
|
+// Generate a new public/private keypair, and save the sealed private
|
|
|
|
+// key and the public key to the given filenames (overwriting if they're
|
|
|
|
+// already there). Return true on success, false on failure.
|
|
|
|
+static bool genkey(const char *sealedprivkeyfile, const char *pubkeyfile)
|
|
{
|
|
{
|
|
size_t sealedprivsize =
|
|
size_t sealedprivsize =
|
|
sizeof(sgx_sealed_data_t) + sizeof(sgx_ec256_private_t) + 19;
|
|
sizeof(sgx_sealed_data_t) + sizeof(sgx_ec256_private_t) + 19;
|
|
@@ -28,19 +39,48 @@ static void genkey()
|
|
|
|
|
|
ecall_identity_key_new(&pubkey, sealedprivkey);
|
|
ecall_identity_key_new(&pubkey, sealedprivkey);
|
|
|
|
|
|
- dump("Pubkey", &pubkey, sizeof(pubkey));
|
|
|
|
- printf("Saving sealed private key\n");
|
|
|
|
-
|
|
|
|
- sgx_destroy_enclave(global_eid);
|
|
|
|
-
|
|
|
|
- FILE *sprivf = fopen("privkey.seal", "wb");
|
|
|
|
- fwrite(sealedprivkey, sealedprivsize, 1, sprivf);
|
|
|
|
- fclose(sprivf);
|
|
|
|
|
|
+ printf("Generating and saving public key and sealed private key\n");
|
|
|
|
|
|
|
|
+ FILE *sprivf = fopen(sealedprivkeyfile, "wb");
|
|
|
|
+ if (!sprivf) {
|
|
|
|
+ free(sealedprivkey);
|
|
|
|
+ perror("Sealed privkey write failed");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (fwrite(sealedprivkey, sealedprivsize, 1, sprivf) != 1) {
|
|
|
|
+ fclose(sprivf);
|
|
|
|
+ free(sealedprivkey);
|
|
|
|
+ perror("Sealed privkey write failed");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
free(sealedprivkey);
|
|
free(sealedprivkey);
|
|
|
|
+ if (fclose(sprivf)) {
|
|
|
|
+ perror("Sealed privkey write failed");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ FILE *pubf = fopen(pubkeyfile, "wb");
|
|
|
|
+ if (!pubf) {
|
|
|
|
+ perror("Pubkey write failed");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (!hexdump(pubf, NULL, &pubkey, sizeof(pubkey))) {
|
|
|
|
+ fclose(pubf);
|
|
|
|
+ perror("Pubkey write failed");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (fclose(pubf)) {
|
|
|
|
+ perror("Pubkey write failed");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ hexdump(stdout, "Pubkey", &pubkey, sizeof(pubkey));
|
|
|
|
+
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
-static void loadkey(FILE *sprivf)
|
|
|
|
|
|
+// Try to load a sealed private key from sprivf. If successful, save
|
|
|
|
+// the public key to pubkeyfile (if non-NULL), overwriting if already
|
|
|
|
+// present. Return true on success, false on failure.
|
|
|
|
+static bool loadkey(FILE *sprivf, const char *pubkeyfile)
|
|
{
|
|
{
|
|
size_t sealedprivsize =
|
|
size_t sealedprivsize =
|
|
sizeof(sgx_sealed_data_t) + sizeof(sgx_ec256_private_t) + 19;
|
|
sizeof(sgx_sealed_data_t) + sizeof(sgx_ec256_private_t) + 19;
|
|
@@ -50,21 +90,46 @@ static void loadkey(FILE *sprivf)
|
|
(sgx_sealed_data_t *)malloc(sealedprivsize);
|
|
(sgx_sealed_data_t *)malloc(sealedprivsize);
|
|
|
|
|
|
if (fread(sealedprivkey, sealedprivsize, 1, sprivf) != 1) {
|
|
if (fread(sealedprivkey, sealedprivsize, 1, sprivf) != 1) {
|
|
- fprintf(stderr, "Could not read privkey.seal file\n");
|
|
|
|
- exit(1);
|
|
|
|
|
|
+ fprintf(stderr, "Could not read sealed privkey file\n");
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
bool res = ecall_identity_key_load(&pubkey, sealedprivkey);
|
|
bool res = ecall_identity_key_load(&pubkey, sealedprivkey);
|
|
|
|
+ free(sealedprivkey);
|
|
|
|
|
|
if (!res) {
|
|
if (!res) {
|
|
fprintf(stderr, "Key load failed\n");
|
|
fprintf(stderr, "Key load failed\n");
|
|
- exit(1);
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
printf("Loaded sealed private key\n");
|
|
printf("Loaded sealed private key\n");
|
|
- dump("Pubkey", &pubkey, sizeof(pubkey));
|
|
|
|
|
|
+ if (pubkeyfile) {
|
|
|
|
+ FILE *pubf = fopen(pubkeyfile, "wb");
|
|
|
|
+ if (!pubf) {
|
|
|
|
+ perror("Pubkey write failed");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (!hexdump(pubf, NULL, &pubkey, sizeof(pubkey))) {
|
|
|
|
+ fclose(pubf);
|
|
|
|
+ perror("Pubkey write failed");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (fclose(pubf)) {
|
|
|
|
+ perror("Pubkey write failed");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ hexdump(stdout, "Pubkey", &pubkey, sizeof(pubkey));
|
|
|
|
|
|
- free(sealedprivkey);
|
|
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void usage(const char *argv0)
|
|
|
|
+{
|
|
|
|
+ fprintf(stderr, "Usage: %s --gen sealedprivkeyfile pubkeyfile\n",
|
|
|
|
+ argv0);
|
|
|
|
+ fprintf(stderr, "or %s sealedprivkeyfile configfile myname\n",
|
|
|
|
+ argv0);
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
int main(int argc, char **argv)
|
|
@@ -73,13 +138,59 @@ int main(int argc, char **argv)
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
- FILE *sprivf = fopen("privkey.seal", "rb");
|
|
|
|
- if (sprivf) {
|
|
|
|
- loadkey(sprivf);
|
|
|
|
- fclose(sprivf);
|
|
|
|
- } else {
|
|
|
|
- genkey();
|
|
|
|
|
|
+ // --gen sealedprivkeyfile pubkeyfile
|
|
|
|
+ // If sealedprivkeyfile exists and is valid, regenerate the
|
|
|
|
+ // pubkeyfile (overwriting if there was already one there).
|
|
|
|
+ // Otherwise, generate and write a new sealedprivkeyfile and
|
|
|
|
+ // pubkeyfile (again overwriting if needed).
|
|
|
|
+ if (argc > 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 != 4) {
|
|
|
|
+ usage(argv[0]);
|
|
|
|
+ exit(1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const char *sealedprivkeyfile = argv[1];
|
|
|
|
+ const char *configile = argv[2];
|
|
|
|
+ const char *myname = argv[3];
|
|
|
|
+
|
|
|
|
+ // 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);
|
|
|
|
+
|
|
|
|
+ sgx_destroy_enclave(global_eid);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|