132a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 2d183644564ec27c106a3eb1931f565fae167a058Randall Spangler * Use of this source code is governed by a BSD-style license that can be 3d183644564ec27c106a3eb1931f565fae167a058Randall Spangler * found in the LICENSE file. 4d183644564ec27c106a3eb1931f565fae167a058Randall Spangler * 5d183644564ec27c106a3eb1931f565fae167a058Randall Spangler * Host functions for keys. 6d183644564ec27c106a3eb1931f565fae167a058Randall Spangler */ 7d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 8d183644564ec27c106a3eb1931f565fae167a058Randall Spangler/* TODO: change all 'return 0', 'return 1' into meaningful return codes */ 9d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 10d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <openssl/pem.h> 11d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 12d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <stdio.h> 13d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <stdlib.h> 14d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <unistd.h> 15d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 16d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "cryptolib.h" 1732a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler#include "host_common.h" 1832a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler#include "host_key.h" 19d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler#include "host_misc.h" 20d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "vboot_common.h" 21d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 22d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 23a08b5c9d032be485fe6e2790c23e8c9bb9fca2adBill RichardsonVbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm) { 24d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 25d183644564ec27c106a3eb1931f565fae167a058Randall Spangler VbPrivateKey* key; 26d183644564ec27c106a3eb1931f565fae167a058Randall Spangler RSA* rsa_key; 27d183644564ec27c106a3eb1931f565fae167a058Randall Spangler FILE* f; 28d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 29d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (algorithm >= kNumAlgorithms) { 30abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson VBDEBUG(("%s() called with invalid algorithm!\n", __FUNCTION__)); 31d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return NULL; 32d183644564ec27c106a3eb1931f565fae167a058Randall Spangler } 33d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 34d183644564ec27c106a3eb1931f565fae167a058Randall Spangler /* Read private key */ 35d183644564ec27c106a3eb1931f565fae167a058Randall Spangler f = fopen(filename, "r"); 36d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (!f) { 37abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson VBDEBUG(("%s(): Couldn't open key file: %s\n", __FUNCTION__, filename)); 38d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return NULL; 39d183644564ec27c106a3eb1931f565fae167a058Randall Spangler } 40d183644564ec27c106a3eb1931f565fae167a058Randall Spangler rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); 41d183644564ec27c106a3eb1931f565fae167a058Randall Spangler fclose(f); 42d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (!rsa_key) { 43abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson VBDEBUG(("%s(): Couldn't read private key from file: %s\n", __FUNCTION__, 44abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson filename)); 45d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return NULL; 46d183644564ec27c106a3eb1931f565fae167a058Randall Spangler } 47d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 48d183644564ec27c106a3eb1931f565fae167a058Randall Spangler /* Store key and algorithm in our struct */ 4932a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler key = (VbPrivateKey*)malloc(sizeof(VbPrivateKey)); 50d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (!key) { 51d183644564ec27c106a3eb1931f565fae167a058Randall Spangler RSA_free(rsa_key); 52d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return NULL; 53d183644564ec27c106a3eb1931f565fae167a058Randall Spangler } 54d183644564ec27c106a3eb1931f565fae167a058Randall Spangler key->rsa_private_key = rsa_key; 55d183644564ec27c106a3eb1931f565fae167a058Randall Spangler key->algorithm = algorithm; 56d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 57d183644564ec27c106a3eb1931f565fae167a058Randall Spangler /* Return the key */ 58d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return key; 59d183644564ec27c106a3eb1931f565fae167a058Randall Spangler} 60d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 61d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 62d183644564ec27c106a3eb1931f565fae167a058Randall Spanglervoid PrivateKeyFree(VbPrivateKey* key) { 63d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (!key) 64d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return; 65d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (key->rsa_private_key) 66d183644564ec27c106a3eb1931f565fae167a058Randall Spangler RSA_free(key->rsa_private_key); 6732a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(key); 68d183644564ec27c106a3eb1931f565fae167a058Randall Spangler} 69d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 70d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 71abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson/* Write a private key to a file in .vbprivk format. */ 72abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardsonint PrivateKeyWrite(const char* filename, const VbPrivateKey* key) { 73abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson uint8_t *outbuf = 0; 74abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson int buflen; 75abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson FILE *f; 76abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 77abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson buflen = i2d_RSAPrivateKey(key->rsa_private_key, &outbuf); 78abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson if (buflen <= 0) { 7932a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler VbExError("Unable to write private key buffer\n"); 80abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson return 1; 81abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson } 82abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 83abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson f = fopen(filename, "wb"); 84abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson if (!f) { 8532a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler VbExError("Unable to open file %s\n", filename); 8632a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(outbuf); 87abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson return 1; 88abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson } 89abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 90abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson if (1 != fwrite(&key->algorithm, sizeof(key->algorithm), 1, f)) { 9132a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler VbExError("Unable to write to file %s\n", filename); 92abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson fclose(f); 9332a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(outbuf); 94abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson unlink(filename); /* Delete any partial file */ 95abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson } 96abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 97abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson if (1 != fwrite(outbuf, buflen, 1, f)) { 9832a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler VbExError("Unable to write to file %s\n", filename); 99abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson fclose(f); 100abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson unlink(filename); /* Delete any partial file */ 10132a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(outbuf); 102abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson } 103abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 104abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson fclose(f); 10532a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(outbuf); 106abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson return 0; 107abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson} 108abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 109abf055045802cb06c57ff2d7b187736bdcb3b138Bill RichardsonVbPrivateKey* PrivateKeyRead(const char* filename) { 110abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson VbPrivateKey *key; 111abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson uint64_t filelen = 0; 112abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson uint8_t *buffer; 113abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson const unsigned char *start; 11447b593d84920479ae5955fcc6664635328376a10Gaurav Shah 115abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson buffer = ReadFile(filename, &filelen); 116abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson if (!buffer) { 11732a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler VbExError("unable to read from file %s\n", filename); 118abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson return 0; 119abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson } 120abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 12132a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler key = (VbPrivateKey*)malloc(sizeof(VbPrivateKey)); 122abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson if (!key) { 12332a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler VbExError("Unable to allocate VbPrivateKey\n"); 12432a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(buffer); 125abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson return 0; 126abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson } 127abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 128abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson key->algorithm = *(typeof(key->algorithm) *)buffer; 129abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson start = buffer + sizeof(key->algorithm); 130abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 131abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson key->rsa_private_key = d2i_RSAPrivateKey(0, &start, 132abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson filelen - sizeof(key->algorithm)); 133abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 134abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson if (!key->rsa_private_key) { 13532a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler VbExError("Unable to parse RSA private key\n"); 13632a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(buffer); 13732a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(key); 138abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson return 0; 139abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson } 140abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 14132a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(buffer); 142abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson return key; 143abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson} 144abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 145abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson 146d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler/* Allocate a new public key with space for a [key_size] byte key. */ 147d183644564ec27c106a3eb1931f565fae167a058Randall SpanglerVbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm, 148d183644564ec27c106a3eb1931f565fae167a058Randall Spangler uint64_t version) { 14932a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler VbPublicKey* key = (VbPublicKey*)malloc(sizeof(VbPublicKey) + key_size); 150d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (!key) 151d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return NULL; 152d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 153d183644564ec27c106a3eb1931f565fae167a058Randall Spangler key->algorithm = algorithm; 154d183644564ec27c106a3eb1931f565fae167a058Randall Spangler key->key_version = version; 155d183644564ec27c106a3eb1931f565fae167a058Randall Spangler key->key_size = key_size; 156d183644564ec27c106a3eb1931f565fae167a058Randall Spangler key->key_offset = sizeof(VbPublicKey); 157d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return key; 158d183644564ec27c106a3eb1931f565fae167a058Randall Spangler} 159d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 160d55c64537245abca67a66fde5874b7f4a6cdc556Randall SpanglerVbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm, 161d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler uint64_t version) { 162d183644564ec27c106a3eb1931f565fae167a058Randall Spangler VbPublicKey* key; 163d183644564ec27c106a3eb1931f565fae167a058Randall Spangler uint8_t* key_data; 164d183644564ec27c106a3eb1931f565fae167a058Randall Spangler uint64_t key_size; 165d583a30a7c3bd369f82c0428666c7a708d5341d5Gaurav Shah uint64_t expected_key_size; 166d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 167d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (algorithm >= kNumAlgorithms) { 168abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson VBDEBUG(("PublicKeyReadKeyb() called with invalid algorithm!\n")); 169d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return NULL; 170d183644564ec27c106a3eb1931f565fae167a058Randall Spangler } 171d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (version > 0xFFFF) { 172d183644564ec27c106a3eb1931f565fae167a058Randall Spangler /* Currently, TPM only supports 16-bit version */ 173abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson VBDEBUG(("PublicKeyReadKeyb() called with invalid version!\n")); 174d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return NULL; 175d183644564ec27c106a3eb1931f565fae167a058Randall Spangler } 176d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 177d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler key_data = ReadFile(filename, &key_size); 178d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (!key_data) 179d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return NULL; 180d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 18147b593d84920479ae5955fcc6664635328376a10Gaurav Shah if (!RSAProcessedKeySize(algorithm, &expected_key_size) || 18247b593d84920479ae5955fcc6664635328376a10Gaurav Shah expected_key_size != key_size) { 183abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson VBDEBUG(("PublicKeyReadKeyb() wrong key size for algorithm\n")); 18432a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(key_data); 185d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler return NULL; 186d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler } 187d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 188d183644564ec27c106a3eb1931f565fae167a058Randall Spangler key = PublicKeyAlloc(key_size, algorithm, version); 189d183644564ec27c106a3eb1931f565fae167a058Randall Spangler if (!key) { 19032a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(key_data); 191d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return NULL; 192d183644564ec27c106a3eb1931f565fae167a058Randall Spangler } 193d183644564ec27c106a3eb1931f565fae167a058Randall Spangler Memcpy(GetPublicKeyData(key), key_data, key_size); 194d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 19532a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(key_data); 196d183644564ec27c106a3eb1931f565fae167a058Randall Spangler return key; 197d183644564ec27c106a3eb1931f565fae167a058Randall Spangler} 198d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler 199d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler 200f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardsonint PublicKeyLooksOkay(VbPublicKey *key, uint64_t file_size) 201f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson{ 202f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson uint64_t key_size; 203f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson 204f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson /* Sanity-check key data */ 205f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson if (0 != VerifyPublicKeyInside(key, file_size, key)) { 206f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson VBDEBUG(("PublicKeyRead() not a VbPublicKey\n")); 207f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson return 0; 208f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson } 209f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson if (key->algorithm >= kNumAlgorithms) { 210f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson VBDEBUG(("PublicKeyRead() invalid algorithm\n")); 211f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson return 0; 212f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson } 213f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson if (key->key_version > 0xFFFF) { 214f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson VBDEBUG(("PublicKeyRead() invalid version\n")); 215f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson return 0; /* Currently, TPM only supports 16-bit version */ 216f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson } 217f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson if (!RSAProcessedKeySize(key->algorithm, &key_size) || 218f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson key_size != key->key_size) { 219f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson VBDEBUG(("PublicKeyRead() wrong key size for algorithm\n")); 220f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson return 0; 221f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson } 222f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson 223f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson /* Success */ 224f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson return 1; 225f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson} 226f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson 227f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson 228f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson 229d55c64537245abca67a66fde5874b7f4a6cdc556Randall SpanglerVbPublicKey* PublicKeyRead(const char* filename) { 230d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler VbPublicKey* key; 231d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler uint64_t file_size; 232d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler 233d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler key = (VbPublicKey*)ReadFile(filename, &file_size); 234d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler if (!key) 235d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler return NULL; 236d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler 237f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson if (PublicKeyLooksOkay(key, file_size)) 238f16ed878799cc7cf11545c36d6f332c76d612260Bill Richardson return key; 239d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler 240d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler /* Error */ 24132a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(key); 242d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler return NULL; 243d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler} 244d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler 245d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spanglerint PublicKeyWrite(const char* filename, const VbPublicKey* key) { 2466a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler VbPublicKey* kcopy; 2476a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler int rv; 248d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler 2496a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler /* Copy the key, so its data is contiguous with the header */ 2506a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler kcopy = PublicKeyAlloc(key->key_size, 0, 0); 2516a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler if (!kcopy) 2526a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler return 1; 2536a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler if (0 != PublicKeyCopy(kcopy, key)) { 25432a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(kcopy); 2556a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler return 1; 2566a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler } 257d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler 2586a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler /* Write the copy, then free it */ 2596a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler rv = WriteFile(filename, kcopy, kcopy->key_offset + kcopy->key_size); 26032a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler free(kcopy); 261d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler return rv; 262d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler} 263