github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/tpm2/SelfSignPolicyCert.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/err.h> 10 #include <openssl/rand.h> 11 #include <openssl/ssl.h> 12 #include <openssl/rsa.h> 13 #include <openssl_helpers.h> 14 15 #include <tpm20.h> 16 #include <tpm2_lib.h> 17 #include <tpm2.pb.h> 18 #include <gflags/gflags.h> 19 20 // 21 // Copyright 2015 Google Corporation, All Rights Reserved. 22 // 23 // Licensed under the Apache License, Version 2.0 (the "License"); 24 // you may not use this file except in compliance with the License. 25 // You may obtain a copy of the License at 26 // http://www.apache.org/licenses/LICENSE-2.0 27 // or in the the file LICENSE-2.0.txt in the top level sourcedirectory 28 // Unless required by applicable law or agreed to in writing, software 29 // distributed under the License is distributed on an "AS IS" BASIS, 30 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 // See the License for the specific language governing permissions and 32 // limitations under the License 33 // 34 // Portions of this code were derived TPM2.0-TSS 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 tboot published 38 // by Intel under the license set forth in intel_license.txt 39 // and downloaded on or about August 6, 2015. 40 // Portions of this code were derived from the crypto utility 41 // published by John Manferdelli under the Apache 2.0 license. 42 // See github.com/jlmucb/crypto. 43 // File: SelfSignPolicyCert.cc 44 45 46 // Calling sequence 47 // SelfSignPolicyCert.exe --signing_instructions=input-file 48 // --key_file=input-file --policy_identifier=name --cert_file=output-file 49 50 using std::string; 51 52 // This program signs the policy key using the policy key. 53 // The policy_identifier identifies the policy domain. 54 55 DEFINE_string(signing_instructions_file, "", "signing_instructions"); 56 DEFINE_string(key_file, "", "key_input"); 57 DEFINE_string(policy_identifier, "", "text to identify policy domain"); 58 DEFINE_string(cert_file, "cert_file", "cert output file"); 59 60 #ifndef GFLAGS_NS 61 #define GFLAGS_NS google 62 #endif 63 64 #define MAX_BUF_SIZE 8192 65 66 void PrintOptions() { 67 printf("Calling sequence: SelfSignPolicyCert.exe "\ 68 "--signing_instructions_file=input-file "\ 69 "--key_file=input-file --policy_identifier=name --cert_file=output-file\n"); 70 } 71 72 int main(int an, char** av) { 73 int ret_val = 0; 74 75 printf("\nSelfSignPolicyCert\n\n"); 76 77 GFLAGS_NS::ParseCommandLineFlags(&an, &av, true); 78 if (FLAGS_signing_instructions_file == "") { 79 printf("You must specify a signing instructions file \n"); 80 PrintOptions(); 81 return 1; 82 } 83 if (FLAGS_key_file == "") { 84 printf("key_file is empty\n"); 85 return 1; 86 } 87 if (FLAGS_policy_identifier == "") { 88 printf("policy_identifier is empty\n"); 89 return 1; 90 } 91 92 int in_size = MAX_BUF_SIZE; 93 byte in_buf[MAX_BUF_SIZE]; 94 95 string input; 96 signing_instructions_message signing_message; 97 if (!ReadFileIntoBlock(FLAGS_signing_instructions_file, &in_size, 98 in_buf)) { 99 printf("Can't read signing instructions %s\n", 100 FLAGS_signing_instructions_file.c_str()); 101 return 1; 102 } 103 input.assign((const char*)in_buf, in_size); 104 if (!signing_message.ParseFromString(input)) { 105 printf("Can't parse signing instructions\n"); 106 return 1; 107 } 108 printf("issuer: %s, duration: %ld, purpose: %s, hash: %s\n", 109 signing_message.issuer().c_str(), (long)signing_message.duration(), 110 signing_message.purpose().c_str(), signing_message.hash_alg().c_str()); 111 112 if (!signing_message.can_sign()) { 113 printf("Signing is invalid\n"); 114 return 1; 115 } 116 printf("\nGot signing instructions\n"); 117 118 in_size = MAX_BUF_SIZE; 119 private_key_blob_message private_key; 120 if (!ReadFileIntoBlock(FLAGS_key_file, &in_size, in_buf)) { 121 printf("Can't read private key\n"); 122 return 1; 123 } 124 input.assign((const char*)in_buf, in_size); 125 if (!private_key.ParseFromString(input)) { 126 printf("Can't parse private key\n"); 127 return 1; 128 } 129 130 printf("Key type: %s\n", private_key.key_type().c_str()); 131 printf("Key name: %s\n", private_key.key_name().c_str()); 132 string the_blob = private_key.blob(); 133 PrintBytes(the_blob.size(), (byte*)the_blob.data()); 134 const byte* p = (byte*)the_blob.data(); 135 RSA* signing_key = d2i_RSAPrivateKey(nullptr, &p, the_blob.size()); 136 if (signing_key == nullptr) { 137 printf("Can't translate private key\n"); 138 return 1; 139 } 140 printf("\nGot signing key\n"); 141 142 // fill x509_cert_request_parameters_message 143 x509_cert_request_parameters_message req_message; 144 req_message.set_common_name(FLAGS_policy_identifier); 145 req_message.mutable_key()->set_key_type("RSA"); 146 string* mod = BN_to_bin(*signing_key->n); 147 if (mod == nullptr) { 148 printf("Can't get private key modulus\n"); 149 return 1; 150 } 151 req_message.mutable_key()->mutable_rsa_key()->set_bit_modulus_size( 152 BN_num_bits(signing_key->n)); 153 uint64_t expIn = 0x10001ULL; 154 uint64_t expOut; 155 ChangeEndian64((uint64_t*)&expIn, (uint64_t*)(&expOut)); 156 157 req_message.mutable_key()->mutable_rsa_key()->set_exponent( 158 (const char*)&expOut, sizeof(uint64_t)); 159 req_message.mutable_key()->mutable_rsa_key()->set_modulus( 160 mod->data(), mod->size()); 161 printf("\ncert request\n"); 162 print_cert_request_message(req_message); printf("\n\n"); 163 printf("\nGenerating request\n"); 164 165 X509_REQ* req = X509_REQ_new(); 166 X509_REQ_set_version(req, 2); 167 // TODO(jlm): sign and verify request later 168 if (!GenerateX509CertificateRequest(req_message, false, req)) { 169 printf("Can't generate x509 request\n"); 170 return 1; 171 } 172 printf("Generated certificate request\n"); 173 174 // sign it 175 X509* cert = X509_new(); 176 if (!SignX509Certificate(signing_key, true, signing_message, nullptr, 177 req, false, cert)) { 178 printf("Can't sign x509 request\n"); 179 return 1; 180 } 181 printf("message signed\n"); 182 183 byte* out = nullptr; 184 int size = i2d_X509(cert, &out); 185 string output; 186 output.assign((const char*)out, size); 187 if (!WriteFileFromBlock(FLAGS_cert_file, output.size(), 188 (byte*)output.data())) { 189 printf("Can't write cert\n"); 190 return 1; 191 } 192 return ret_val; 193 } 194