Browse Source

Better CLI for key generation

Ian Goldberg 1 year ago
parent
commit
194af2f062
1 changed files with 136 additions and 25 deletions
  1. 136 25
      App/App.cpp

+ 136 - 25
App/App.cpp

@@ -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;
 }
 }