host_key.c revision 47b593d84920479ae5955fcc6664635328376a10
1d183644564ec27c106a3eb1931f565fae167a058Randall Spangler/* Copyright (c) 2010 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#define OPENSSL_NO_SHA
11d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <openssl/engine.h>
12d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <openssl/pem.h>
13d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <openssl/rsa.h>
14abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson#include <openssl/x509.h>
15d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
16d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <stdio.h>
17d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <stdlib.h>
18d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <unistd.h>
19d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
20d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "host_key.h"
21d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
22d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "cryptolib.h"
23d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler#include "host_misc.h"
24d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "utility.h"
25d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "vboot_common.h"
26d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
27d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
28a08b5c9d032be485fe6e2790c23e8c9bb9fca2adBill RichardsonVbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm) {
29d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
30d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  VbPrivateKey* key;
31d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  RSA* rsa_key;
32d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  FILE* f;
33d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
34d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (algorithm >= kNumAlgorithms) {
35abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("%s() called with invalid algorithm!\n", __FUNCTION__));
36d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return NULL;
37d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  }
38d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
39d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  /* Read private key */
40d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  f = fopen(filename, "r");
41d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (!f) {
42abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("%s(): Couldn't open key file: %s\n", __FUNCTION__, filename));
43d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return NULL;
44d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  }
45d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);
46d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  fclose(f);
47d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (!rsa_key) {
48abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("%s(): Couldn't read private key from file: %s\n", __FUNCTION__,
49abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson             filename));
50d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return NULL;
51d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  }
52d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
53d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  /* Store key and algorithm in our struct */
54d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  key = (VbPrivateKey*)Malloc(sizeof(VbPrivateKey));
55d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (!key) {
56d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    RSA_free(rsa_key);
57d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return NULL;
58d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  }
59d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  key->rsa_private_key = rsa_key;
60d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  key->algorithm = algorithm;
61d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
62d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  /* Return the key */
63d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  return key;
64d183644564ec27c106a3eb1931f565fae167a058Randall Spangler}
65d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
66d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
67d183644564ec27c106a3eb1931f565fae167a058Randall Spanglervoid PrivateKeyFree(VbPrivateKey* key) {
68d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (!key)
69d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return;
70d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (key->rsa_private_key)
71d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    RSA_free(key->rsa_private_key);
72d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  Free(key);
73d183644564ec27c106a3eb1931f565fae167a058Randall Spangler}
74d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
75d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
76abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson/* Write a private key to a file in .vbprivk format. */
77abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardsonint PrivateKeyWrite(const char* filename, const VbPrivateKey* key) {
78abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  uint8_t *outbuf = 0;
79abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  int buflen;
80abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  FILE *f;
81abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
82abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  buflen = i2d_RSAPrivateKey(key->rsa_private_key, &outbuf);
83abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  if (buflen <= 0) {
84abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    error("Unable to write private key buffer\n");
85abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    return 1;
86abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  }
87abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
88abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  f = fopen(filename, "wb");
89abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  if (!f) {
90abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    error("Unable to open file %s\n", filename);
91abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    Free(outbuf);
92abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    return 1;
93abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  }
94abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
95abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  if (1 != fwrite(&key->algorithm, sizeof(key->algorithm), 1, f)) {
96abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    error("Unable to write to file %s\n", filename);
97abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    fclose(f);
98abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    Free(outbuf);
99abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    unlink(filename);  /* Delete any partial file */
100abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  }
101abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
102abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  if (1 != fwrite(outbuf, buflen, 1, f)) {
103abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    error("Unable to write to file %s\n", filename);
104abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    fclose(f);
105abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    unlink(filename);  /* Delete any partial file */
106abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    Free(outbuf);
107abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  }
108abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
109abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  fclose(f);
110abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  Free(outbuf);
111abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  return 0;
112abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson}
113abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
114abf055045802cb06c57ff2d7b187736bdcb3b138Bill RichardsonVbPrivateKey* PrivateKeyRead(const char* filename) {
115abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  VbPrivateKey *key;
116abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  uint64_t filelen = 0;
117abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  uint8_t *buffer;
118abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  const unsigned char *start;
11947b593d84920479ae5955fcc6664635328376a10Gaurav Shah
120abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  buffer = ReadFile(filename, &filelen);
121abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  if (!buffer) {
122abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    error("unable to read from file %s\n", filename);
123abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    return 0;
124abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  }
125abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
126abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  key = (VbPrivateKey*)Malloc(sizeof(VbPrivateKey));
127abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  if (!key) {
128abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    error("Unable to allocate VbPrivateKey\n");
129abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    Free(buffer);
130abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    return 0;
131abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  }
132abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
133abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  key->algorithm = *(typeof(key->algorithm) *)buffer;
134abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  start = buffer + sizeof(key->algorithm);
135abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
136abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  key->rsa_private_key = d2i_RSAPrivateKey(0, &start,
137abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson                                           filelen - sizeof(key->algorithm));
138abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
139abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  if (!key->rsa_private_key) {
140abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    error("Unable to parse RSA private key\n");
141abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    Free(buffer);
142abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    Free(key);
143abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    return 0;
144abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  }
145abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
146abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  Free(buffer);
147abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson  return key;
148abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson}
149abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
150abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson
151d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler/* Allocate a new public key with space for a [key_size] byte key. */
152d183644564ec27c106a3eb1931f565fae167a058Randall SpanglerVbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm,
153d183644564ec27c106a3eb1931f565fae167a058Randall Spangler                            uint64_t version) {
154d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  VbPublicKey* key = (VbPublicKey*)Malloc(sizeof(VbPublicKey) + key_size);
155d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (!key)
156d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return NULL;
157d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
158d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  key->algorithm = algorithm;
159d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  key->key_version = version;
160d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  key->key_size = key_size;
161d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  key->key_offset = sizeof(VbPublicKey);
162d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  return key;
163d183644564ec27c106a3eb1931f565fae167a058Randall Spangler}
164d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
165d55c64537245abca67a66fde5874b7f4a6cdc556Randall SpanglerVbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm,
166d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler                               uint64_t version) {
167d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  VbPublicKey* key;
168d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  uint8_t* key_data;
169d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  uint64_t key_size;
17047b593d84920479ae5955fcc6664635328376a10Gaurav Shah  int expected_key_size;
171d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
172d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (algorithm >= kNumAlgorithms) {
173abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("PublicKeyReadKeyb() called with invalid algorithm!\n"));
174d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return NULL;
175d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  }
176d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (version > 0xFFFF) {
177d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    /* Currently, TPM only supports 16-bit version */
178abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("PublicKeyReadKeyb() called with invalid version!\n"));
179d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return NULL;
180d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  }
181d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
182d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  key_data = ReadFile(filename, &key_size);
183d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (!key_data)
184d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return NULL;
185d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
18647b593d84920479ae5955fcc6664635328376a10Gaurav Shah  if (!RSAProcessedKeySize(algorithm, &expected_key_size) ||
18747b593d84920479ae5955fcc6664635328376a10Gaurav Shah      expected_key_size != key_size) {
188abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("PublicKeyReadKeyb() wrong key size for algorithm\n"));
189d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    Free(key_data);
190d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    return NULL;
191d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  }
192d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
193d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  key = PublicKeyAlloc(key_size, algorithm, version);
194d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  if (!key) {
195d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    Free(key_data);
196d183644564ec27c106a3eb1931f565fae167a058Randall Spangler    return NULL;
197d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  }
198d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  Memcpy(GetPublicKeyData(key), key_data, key_size);
199d183644564ec27c106a3eb1931f565fae167a058Randall Spangler
200d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  Free(key_data);
201d183644564ec27c106a3eb1931f565fae167a058Randall Spangler  return key;
202d183644564ec27c106a3eb1931f565fae167a058Randall Spangler}
203d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
204d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
205d55c64537245abca67a66fde5874b7f4a6cdc556Randall SpanglerVbPublicKey* PublicKeyRead(const char* filename) {
206d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  VbPublicKey* key;
207d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  uint64_t file_size;
20847b593d84920479ae5955fcc6664635328376a10Gaurav Shah  int key_size;
209d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
210d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  key = (VbPublicKey*)ReadFile(filename, &file_size);
211d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  if (!key)
212d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    return NULL;
213d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
214d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  do {
215d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    /* Sanity-check key data */
216d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    if (0 != VerifyPublicKeyInside(key, file_size, key)) {
217abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson      VBDEBUG(("PublicKeyRead() not a VbPublicKey\n"));
218d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler      break;
219d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    }
220d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    if (key->algorithm >= kNumAlgorithms) {
221abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson      VBDEBUG(("PublicKeyRead() invalid algorithm\n"));
222d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler      break;
223d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    }
224d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    if (key->key_version > 0xFFFF) {
225abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson      VBDEBUG(("PublicKeyRead() invalid version\n"));
226d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler      break;  /* Currently, TPM only supports 16-bit version */
227d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    }
22847b593d84920479ae5955fcc6664635328376a10Gaurav Shah    if (!RSAProcessedKeySize(key->algorithm, &key_size) ||
22947b593d84920479ae5955fcc6664635328376a10Gaurav Shah        key_size != key->key_size) {
230abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson      VBDEBUG(("PublicKeyRead() wrong key size for algorithm\n"));
231d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler      break;
232d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    }
233d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
234d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    /* Success */
235d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    return key;
236d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
237d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  } while(0);
238d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
239d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  /* Error */
240d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  Free(key);
241d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  return NULL;
242d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler}
243d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
244d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spanglerint PublicKeyWrite(const char* filename, const VbPublicKey* key) {
2456a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  VbPublicKey* kcopy;
2466a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  int rv;
247d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
2486a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  /* Copy the key, so its data is contiguous with the header */
2496a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  kcopy = PublicKeyAlloc(key->key_size, 0, 0);
2506a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  if (!kcopy)
2516a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler    return 1;
2526a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  if (0 != PublicKeyCopy(kcopy, key)) {
253d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    Free(kcopy);
2546a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler    return 1;
2556a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  }
256d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
2576a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  /* Write the copy, then free it */
2586a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  rv = WriteFile(filename, kcopy, kcopy->key_offset + kcopy->key_size);
2596a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  Free(kcopy);
260d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  return rv;
261d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler}
262