blob: d1768292abdc985bd65a9b5c3b505e6712802b20 [file] [log] [blame]
Gaurav Shahbf6c4a72010-03-05 10:58:48 -08001#include <tpm_keychain_common.h>
2#include "tpm_keychain.h"
3
4#include <openssl/bio.h>
5#include <openssl/bn.h>
6#include <openssl/evp.h>
7#include <openssl/pem.h>
8#include <openssl/rsa.h>
9#include <openssl/err.h>
10
11static const char Base64[] =
12 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
13static const char Pad64 = '=';
14
15static int
16custom_b64_ntop(unsigned char const *src, size_t srclength,
17 unsigned char *target, size_t targsize)
18{
19 size_t datalength = 0;
20 unsigned char input[3];
21 unsigned char output[4];
22 int i;
23
24 while (2 < srclength) {
25 input[0] = *src++;
26 input[1] = *src++;
27 input[2] = *src++;
28 srclength -= 3;
29
30 output[0] = input[0] >> 2;
31 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
32 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
33 output[3] = input[2] & 0x3f;
34
35 if (datalength + 4 > targsize) {
36 return -1;
37 }
38
39 target[datalength++] = Base64[output[0]];
40 target[datalength++] = Base64[output[1]];
41 target[datalength++] = Base64[output[2]];
42 target[datalength++] = Base64[output[3]];
43 }
44
45 if (0 != srclength) {
46
47 input[0] = input[1] = input[2] = '\0';
48
49 for (i = 0; i < srclength; i++) {
50 input[i] = *src++;
51 }
52
53 output[0] = input[0] >> 2;
54 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
55 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
56
57 if (datalength + 4 > targsize) {
58 return -1;
59 }
60
61 target[datalength++] = Base64[output[0]];
62 target[datalength++] = Base64[output[1]];
63
64 if (srclength == 1) {
65 target[datalength++] = Pad64;
66 } else {
67 target[datalength++] = Base64[output[2]];
68 }
69
70 target[datalength++] = Pad64;
71 }
72
73 if (datalength >= targsize) {
74 return -1;
75 }
76
77 target[datalength] = '\0';
78
79 return datalength;
80}
81
82void
83dump_rsa_ssh(RSA* rsa, char* uuid_string)
84{
85 unsigned char *p;
86 unsigned char sshbuf[8192];
87 unsigned char bigebuf[8192] = { 0 };
88 unsigned int len = 0;
89 unsigned int nb;
90 int bige;
91 int hbit = 1;
92 BIGNUM* B;
93
94 if (!rsa) {
95 return;
96 }
97
98 p = sshbuf;
99
100 len = strlen("ssh-rsa");
101 p[0] = len >> 24;
102 p[1] = len >> 16;
103 p[2] = len >> 8;
104 p[3] = len;
105 p += 4;
106 memcpy(p, "ssh-rsa", len);
107 p += len;
108
109 B = rsa->e;
110 if (B->neg) {
111 return;
112 }
113
114 if (BN_is_zero(B)) {
115 p[0] = 0 >> 24;
116 p[1] = 0 >> 16;
117 p[2] = 0 >> 8;
118 p[3] = 0;
119 p += 4;
120 goto GO_N;
121 }
122
123 if ((nb = BN_num_bytes(B) + 1) < 2) {
124 return;
125 }
126
127 bigebuf[0] = '\0';
128 bige = BN_bn2bin(B, bigebuf + 1);
129 if (nb != (bige + 1)) {
130 return;
131 }
132 if (*(bigebuf + 1) & 128) {
133 hbit = 0;
134 }
135 p[0] = (nb - hbit) >> 24;
136 p[1] = (nb - hbit) >> 16;
137 p[2] = (nb - hbit) >> 8;
138 p[3] = (nb - hbit);
139 p += 4;
140 memcpy(p, bigebuf + hbit, nb - hbit);
141 p += nb - hbit;
142
143GO_N:
144 hbit = 1;
145 B = rsa->n;
146 bigebuf[0] = '\0';
147 if (B->neg) {
148 return;
149 }
150
151 if (BN_is_zero(B)) {
152 p[0] = 0 >> 24;
153 p[1] = 0 >> 16;
154 p[2] = 0 >> 8;
155 p[3] = 0;
156 p += 4;
157 goto OUT;
158 }
159
160 if ((nb = BN_num_bytes(B) + 1) < 2) {
161 return;
162 }
163
164 bige = BN_bn2bin(B, bigebuf + 1);
165 if (nb != (bige + 1)) {
166 return;
167 }
168 if (*(bigebuf + 1) & 128) {
169 hbit = 0;
170 }
171 p[0] = (nb - hbit) >> 24;
172 p[1] = (nb - hbit) >> 16;
173 p[2] = (nb - hbit) >> 8;
174 p[3] = (nb - hbit);
175 p += 4;
176 memcpy(p, bigebuf + hbit, nb - hbit);
177 p += nb - hbit;
178
179OUT:
180 len = (p - sshbuf) / (sizeof(unsigned char));
181 if ((nb = custom_b64_ntop(sshbuf, len, bigebuf, (len << 1))) > 0) {
182 TKC_stdout("# %s %s\n", TKC_SSH_UUID_TAG, uuid_string);
183 TKC_stdout("%s %s\n", "ssh-rsa", bigebuf);
184 }
185
186 return;
187}
188
189const char* unparse_key_usage(uint32_t kusage)
190{
191 switch (kusage) {
192 case TSS_KEYUSAGE_BIND:
193 return "bind";
194 case TSS_KEYUSAGE_IDENTITY:
195 return "identity";
196 case TSS_KEYUSAGE_LEGACY:
197 return "bind,signing,ssh";
198 break;
199 case TSS_KEYUSAGE_SIGN:
200 return "signing,ssh";
201 case TSS_KEYUSAGE_MIGRATE:
202 return "migrate";
203 case TSS_KEYUSAGE_STORAGE:
204 return "storage";
205 case TSS_KEYUSAGE_AUTHCHANGE:
206 return "authchange";
207 }
208
209 return "unknown";
210}
211
212uint32_t
213parse_key_type(const char* ktype)
214{
215 if (ktype == NULL) {
216 return TKC_KEY_TYPE_NONE;
217 }
218
219 if (!strcmp(ktype, "ssh")) {
220 return TKC_KEY_TYPE_SSH;
221 }
222
223 if (!strcmp(ktype, "sign") || !strcmp(ktype, "signing")) {
224 return TKC_KEY_TYPE_SIGNING;
225 }
226
227 if (!strcmp(ktype, "bind") || !strcmp(ktype, "binding")) {
228 return TKC_KEY_TYPE_BIND;
229 }
230
231 if (!strcmp(ktype, "storage")) {
232 return TKC_KEY_TYPE_STORAGE;
233 }
234
235 if (!strcmp(ktype, "legacy")) {
236 return TKC_KEY_TYPE_LEGACY;
237 }
238
239 if (!strcmp(ktype, "default")) {
240 return TKC_KEY_TYPE_LEGACY;
241 }
242
243 return TKC_KEY_TYPE_NONE;
244}