github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/tpm2/GeneratePolicyKey.cc (about)

     1  #include <stdio.h>
     2  #include <stdlib.h>
     3  #include <sys/types.h>
     4  #include <sys/stat.h>
     5  #include <fcntl.h>
     6  #include <unistd.h>
     7  #include <string.h>
     8  
     9  #include <openssl/rsa.h>
    10  #include <openssl_helpers.h>
    11  
    12  #include <tpm20.h>
    13  #include <tpm2_lib.h>
    14  #include <tpm2.pb.h>
    15  #include <gflags/gflags.h>
    16  
    17  //
    18  // Copyright 2015 Google Corporation, All Rights Reserved.
    19  //
    20  // Licensed under the Apache License, Version 2.0 (the "License");
    21  // you may not use this file except in compliance with the License.
    22  // You may obtain a copy of the License at
    23  //     http://www.apache.org/licenses/LICENSE-2.0
    24  // or in the the file LICENSE-2.0.txt in the top level sourcedirectory
    25  // Unless required by applicable law or agreed to in writing, software
    26  // distributed under the License is distributed on an "AS IS" BASIS,
    27  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    28  // See the License for the specific language governing permissions and
    29  // limitations under the License
    30  //
    31  // Portions of this code were derived TPM2.0-TSS published
    32  // by Intel under the license set forth in intel_license.txt
    33  // and downloaded on or about August 6, 2015.
    34  // Portions of this code were derived tboot published
    35  // by Intel under the license set forth in intel_license.txt
    36  // and downloaded on or about August 6, 2015.
    37  // Portions of this code were derived from the crypto utility
    38  // published by John Manferdelli under the Apache 2.0 license.
    39  // See github.com/jlmucb/crypto.
    40  // File: GeneratePolicyKey.cc
    41  
    42  
    43  // This program creates public/private key pair and produces a file containing
    44  // a protobuf consisting of the keypair.  It is usually the root of a Cloudproxy
    45  // policy domain.
    46  
    47  // Calling sequence
    48  //   GeneratePolicyKey.exe --algorithm="RSA" --modulus_size_in_bits=int32
    49  //      --key_name=input-file --cloudproxy_key_file=output-file 
    50  using std::string;
    51  
    52  
    53  #define CALLING_SEQUENCE "GeneratePolicyKey.exe --algorithm=\"RSA\" "\
    54  " --exponent=exponent --modulus_size_in_bits=int32" \
    55  "--signing_instructions=input-file --key_name=input-file " \
    56  "--cloudproxy_key_file=output-file\n"
    57  
    58  void PrintOptions() {
    59    printf(CALLING_SEQUENCE);
    60  }
    61  
    62  DEFINE_string(algorithm, "RSA", "signing algorithm");
    63  DEFINE_int32(modulus_size_in_bits, 2048, "modulus-size");
    64  DEFINE_int64(exponent, 0x010001ULL, "exponent");
    65  DEFINE_string(signing_instructions, "", "input-file-name");
    66  DEFINE_string(, "", "input-file-name");
    67  DEFINE_string(key_name, "", "key name");
    68  DEFINE_string(cloudproxy_key_file, "", "output-file-name");
    69  
    70  #ifndef GFLAGS_NS
    71  #define GFLAGS_NS google
    72  #endif
    73  
    74  #define MAXKEY_BUF 8192
    75  #define DEBUG
    76  
    77  int main(int an, char** av) {
    78    int ret_val = 0;
    79    RSA* rsa_key = nullptr;
    80    byte der_array_private[MAXKEY_BUF];
    81    byte* start_private = nullptr;
    82    byte* next_private = nullptr;
    83    int len_private;
    84    private_key_blob_message key_out;
    85    string output;
    86  
    87    printf("\nGeneratePolicyKey\n\n");
    88  
    89    GFLAGS_NS::ParseCommandLineFlags(&an, &av, true);
    90  
    91    if (FLAGS_algorithm != "RSA") {
    92      printf("Only RSA supported\n");
    93      ret_val = 1;
    94      goto done;
    95    }
    96    if (FLAGS_signing_instructions == "") {
    97      printf("No signing instructions\n");
    98      ret_val = 1;
    99      goto done;
   100    }
   101    if (FLAGS_key_name == "") {
   102      printf("No key name\n");
   103      ret_val = 1;
   104      goto done;
   105    }
   106    if (FLAGS_cloudproxy_key_file == "") {
   107      printf("No key file\n");
   108      ret_val = 1;
   109      goto done;
   110    }
   111  
   112    rsa_key = RSA_generate_key(FLAGS_modulus_size_in_bits, 
   113                               FLAGS_exponent, nullptr, nullptr);
   114    if (rsa_key == nullptr) {
   115      printf("Can't generate RSA key\n");
   116      ret_val = 1;
   117      goto done;
   118    }
   119    len_private = i2d_RSAPrivateKey(rsa_key, nullptr);
   120    start_private = der_array_private;
   121    next_private = der_array_private;
   122    i2d_RSAPrivateKey(rsa_key, (byte**)&next_private);
   123  
   124  #ifdef DEBUG
   125    printf("der encoded private key (%d): ", len_private);
   126    PrintBytes(len_private, start_private);
   127    printf("\n");
   128  #endif
   129  
   130    key_out.set_key_type("RSA");
   131    key_out.set_key_name(FLAGS_key_name);
   132    key_out.set_blob((const char*)start_private, len_private);
   133    if (!key_out.SerializeToString(&output)) {
   134      printf("Can't serialize output\n");
   135      ret_val = 1;
   136      goto done;
   137    }
   138    if (!WriteFileFromBlock(FLAGS_cloudproxy_key_file, output.size(),
   139                            (byte*)output.data())) {
   140      printf("Can't write output file\n");
   141      ret_val = 1;
   142    }
   143  
   144    // write it as protobuf too
   145    {
   146      rsa_private_key_message privateMsg;
   147      privateMsg.mutable_public_key()->set_bit_modulus_size(FLAGS_modulus_size_in_bits);
   148      byte exp_big_endian[4] = {0, 1, 0, 1};
   149      string e_b_e;
   150      e_b_e.assign((const char*)exp_big_endian, 4);
   151    
   152      privateMsg.mutable_public_key()->set_exponent(e_b_e);
   153      string* n = BN_to_bin(*rsa_key->n);
   154      string* d = BN_to_bin(*rsa_key->d);
   155      privateMsg.mutable_public_key()->set_modulus(*n);
   156      privateMsg.set_d(*d);
   157      if (rsa_key->p != nullptr) {
   158        string* p = BN_to_bin(*rsa_key->p);
   159        privateMsg.set_p(*p);
   160      }
   161      if (rsa_key->q != nullptr) {
   162        string* q = BN_to_bin(*rsa_key->q);
   163        privateMsg.set_q(*q);
   164      }
   165      string proto_out;
   166      if (!privateMsg.SerializeToString(&proto_out)) {
   167        printf("Can't serialize proto\n");
   168        goto done;
   169      }
   170      string proto_file_name;
   171      proto_file_name = FLAGS_cloudproxy_key_file + ".proto";
   172      if (!WriteFileFromBlock(proto_file_name, proto_out.size(),
   173                              (byte*)proto_out.data())) {
   174        printf("Can't write output file\n");
   175        ret_val = 1;
   176      }
   177    }
   178  
   179  done:
   180    return ret_val;
   181  }
   182