1 |
|
|
/* $OpenBSD: signature.c,v 1.26 2017/05/09 13:52:45 mestre Exp $ */ |
2 |
|
|
/* |
3 |
|
|
* The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu) |
4 |
|
|
* |
5 |
|
|
* This code was written by Angelos D. Keromytis in Philadelphia, PA, USA, |
6 |
|
|
* in April-May 1998 |
7 |
|
|
* |
8 |
|
|
* Copyright (C) 1998, 1999 by Angelos D. Keromytis. |
9 |
|
|
* |
10 |
|
|
* Permission to use, copy, and modify this software with or without fee |
11 |
|
|
* is hereby granted, provided that this entire notice is included in |
12 |
|
|
* all copies of any software which is or includes a copy or |
13 |
|
|
* modification of this software. |
14 |
|
|
* |
15 |
|
|
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR |
16 |
|
|
* IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO |
17 |
|
|
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE |
18 |
|
|
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR |
19 |
|
|
* PURPOSE. |
20 |
|
|
*/ |
21 |
|
|
|
22 |
|
|
/* |
23 |
|
|
* Support for X509 keys and signing added by Ben Laurie <ben@algroup.co.uk> |
24 |
|
|
* 3 May 1999 |
25 |
|
|
*/ |
26 |
|
|
|
27 |
|
|
#include <sys/types.h> |
28 |
|
|
|
29 |
|
|
#include <limits.h> |
30 |
|
|
#include <regex.h> |
31 |
|
|
#include <stdlib.h> |
32 |
|
|
#include <stdio.h> |
33 |
|
|
#include <string.h> |
34 |
|
|
|
35 |
|
|
#include <openssl/dsa.h> |
36 |
|
|
#include <openssl/md5.h> |
37 |
|
|
#include <openssl/pem.h> |
38 |
|
|
#include <openssl/rsa.h> |
39 |
|
|
#include <openssl/sha.h> |
40 |
|
|
#include <openssl/x509.h> |
41 |
|
|
|
42 |
|
|
#include "keynote.h" |
43 |
|
|
#include "assertion.h" |
44 |
|
|
#include "signature.h" |
45 |
|
|
|
46 |
|
|
static const char hextab[] = { |
47 |
|
|
'0', '1', '2', '3', '4', '5', '6', '7', |
48 |
|
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' |
49 |
|
|
}; |
50 |
|
|
|
51 |
|
|
/* |
52 |
|
|
* Actual conversion to hex. |
53 |
|
|
*/ |
54 |
|
|
static void |
55 |
|
|
bin2hex(unsigned char *data, unsigned char *buffer, int len) |
56 |
|
|
{ |
57 |
|
|
int off = 0; |
58 |
|
|
|
59 |
|
|
while(len > 0) |
60 |
|
|
{ |
61 |
|
|
buffer[off++] = hextab[*data >> 4]; |
62 |
|
|
buffer[off++] = hextab[*data & 0xF]; |
63 |
|
|
data++; |
64 |
|
|
len--; |
65 |
|
|
} |
66 |
|
|
} |
67 |
|
|
|
68 |
|
|
/* |
69 |
|
|
* Encode a binary string with hex encoding. Return 0 on success. |
70 |
|
|
*/ |
71 |
|
|
int |
72 |
|
|
kn_encode_hex(unsigned char *buf, char **dest, int len) |
73 |
|
|
{ |
74 |
|
|
keynote_errno = 0; |
75 |
|
|
if (dest == NULL) |
76 |
|
|
{ |
77 |
|
|
keynote_errno = ERROR_SYNTAX; |
78 |
|
|
return -1; |
79 |
|
|
} |
80 |
|
|
|
81 |
|
|
*dest = calloc(2 * len + 1, sizeof(char)); |
82 |
|
|
if (*dest == NULL) |
83 |
|
|
{ |
84 |
|
|
keynote_errno = ERROR_MEMORY; |
85 |
|
|
return -1; |
86 |
|
|
} |
87 |
|
|
|
88 |
|
|
bin2hex(buf, *dest, len); |
89 |
|
|
return 0; |
90 |
|
|
} |
91 |
|
|
|
92 |
|
|
/* |
93 |
|
|
* Decode a hex encoding. Return 0 on success. The second argument |
94 |
|
|
* will be half as large as the first. |
95 |
|
|
*/ |
96 |
|
|
int |
97 |
|
|
kn_decode_hex(char *hex, char **dest) |
98 |
|
|
{ |
99 |
|
|
int i, decodedlen; |
100 |
|
|
char ptr[3]; |
101 |
|
|
|
102 |
|
|
keynote_errno = 0; |
103 |
|
|
if (dest == NULL) |
104 |
|
|
{ |
105 |
|
|
keynote_errno = ERROR_SYNTAX; |
106 |
|
|
return -1; |
107 |
|
|
} |
108 |
|
|
|
109 |
|
|
if (strlen(hex) % 2) /* Should be even */ |
110 |
|
|
{ |
111 |
|
|
keynote_errno = ERROR_SYNTAX; |
112 |
|
|
return -1; |
113 |
|
|
} |
114 |
|
|
|
115 |
|
|
decodedlen = strlen(hex) / 2; |
116 |
|
|
*dest = calloc(decodedlen, sizeof(char)); |
117 |
|
|
if (*dest == NULL) |
118 |
|
|
{ |
119 |
|
|
keynote_errno = ERROR_MEMORY; |
120 |
|
|
return -1; |
121 |
|
|
} |
122 |
|
|
|
123 |
|
|
ptr[2] = '\0'; |
124 |
|
|
for (i = 0; i < decodedlen; i++) |
125 |
|
|
{ |
126 |
|
|
ptr[0] = hex[2 * i]; |
127 |
|
|
ptr[1] = hex[(2 * i) + 1]; |
128 |
|
|
(*dest)[i] = (unsigned char) strtoul(ptr, NULL, 16); |
129 |
|
|
} |
130 |
|
|
|
131 |
|
|
return 0; |
132 |
|
|
} |
133 |
|
|
|
134 |
|
|
void |
135 |
|
|
keynote_free_key(void *key, int type) |
136 |
|
|
{ |
137 |
|
|
if (key == NULL) |
138 |
|
|
return; |
139 |
|
|
|
140 |
|
|
/* DSA keys */ |
141 |
|
|
if (type == KEYNOTE_ALGORITHM_DSA) |
142 |
|
|
{ |
143 |
|
|
DSA_free(key); |
144 |
|
|
return; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
/* RSA keys */ |
148 |
|
|
if (type == KEYNOTE_ALGORITHM_RSA) |
149 |
|
|
{ |
150 |
|
|
RSA_free(key); |
151 |
|
|
return; |
152 |
|
|
} |
153 |
|
|
|
154 |
|
|
/* X509 keys */ |
155 |
|
|
if (type == KEYNOTE_ALGORITHM_X509) |
156 |
|
|
{ |
157 |
|
|
RSA_free(key); /* RSA-specific */ |
158 |
|
|
return; |
159 |
|
|
} |
160 |
|
|
|
161 |
|
|
/* BINARY keys */ |
162 |
|
|
if (type == KEYNOTE_ALGORITHM_BINARY) |
163 |
|
|
{ |
164 |
|
|
free(((struct keynote_binary *) key)->bn_key); |
165 |
|
|
free(key); |
166 |
|
|
return; |
167 |
|
|
} |
168 |
|
|
|
169 |
|
|
/* Catch-all case */ |
170 |
|
|
if (type == KEYNOTE_ALGORITHM_NONE) |
171 |
|
|
free(key); |
172 |
|
|
} |
173 |
|
|
|
174 |
|
|
/* |
175 |
|
|
* Map a signature to an algorithm. Return algorithm number (defined in |
176 |
|
|
* keynote.h), or KEYNOTE_ALGORITHM_NONE if unknown. |
177 |
|
|
* Also return in the second, third and fourth arguments the digest |
178 |
|
|
* algorithm, ASCII and internal encodings respectively. |
179 |
|
|
*/ |
180 |
|
|
static int |
181 |
|
|
keynote_get_sig_algorithm(char *sig, int *hash, int *enc, int *internal) |
182 |
|
|
{ |
183 |
|
|
if (sig == NULL) |
184 |
|
|
return KEYNOTE_ALGORITHM_NONE; |
185 |
|
|
|
186 |
|
|
if (!strncasecmp(SIG_DSA_SHA1_HEX, sig, SIG_DSA_SHA1_HEX_LEN)) |
187 |
|
|
{ |
188 |
|
|
*hash = KEYNOTE_HASH_SHA1; |
189 |
|
|
*enc = ENCODING_HEX; |
190 |
|
|
*internal = INTERNAL_ENC_ASN1; |
191 |
|
|
return KEYNOTE_ALGORITHM_DSA; |
192 |
|
|
} |
193 |
|
|
|
194 |
|
|
if (!strncasecmp(SIG_DSA_SHA1_BASE64, sig, SIG_DSA_SHA1_BASE64_LEN)) |
195 |
|
|
{ |
196 |
|
|
*hash = KEYNOTE_HASH_SHA1; |
197 |
|
|
*enc = ENCODING_BASE64; |
198 |
|
|
*internal = INTERNAL_ENC_ASN1; |
199 |
|
|
return KEYNOTE_ALGORITHM_DSA; |
200 |
|
|
} |
201 |
|
|
|
202 |
|
|
if (!strncasecmp(SIG_RSA_MD5_PKCS1_HEX, sig, SIG_RSA_MD5_PKCS1_HEX_LEN)) |
203 |
|
|
{ |
204 |
|
|
*hash = KEYNOTE_HASH_MD5; |
205 |
|
|
*enc = ENCODING_HEX; |
206 |
|
|
*internal = INTERNAL_ENC_PKCS1; |
207 |
|
|
return KEYNOTE_ALGORITHM_RSA; |
208 |
|
|
} |
209 |
|
|
|
210 |
|
|
if (!strncasecmp(SIG_RSA_SHA1_PKCS1_HEX, sig, SIG_RSA_SHA1_PKCS1_HEX_LEN)) |
211 |
|
|
{ |
212 |
|
|
*hash = KEYNOTE_HASH_SHA1; |
213 |
|
|
*enc = ENCODING_HEX; |
214 |
|
|
*internal = INTERNAL_ENC_PKCS1; |
215 |
|
|
return KEYNOTE_ALGORITHM_RSA; |
216 |
|
|
} |
217 |
|
|
|
218 |
|
|
if (!strncasecmp(SIG_RSA_MD5_PKCS1_BASE64, sig, |
219 |
|
|
SIG_RSA_MD5_PKCS1_BASE64_LEN)) |
220 |
|
|
{ |
221 |
|
|
*hash = KEYNOTE_HASH_MD5; |
222 |
|
|
*enc = ENCODING_BASE64; |
223 |
|
|
*internal = INTERNAL_ENC_PKCS1; |
224 |
|
|
return KEYNOTE_ALGORITHM_RSA; |
225 |
|
|
} |
226 |
|
|
|
227 |
|
|
if (!strncasecmp(SIG_RSA_SHA1_PKCS1_BASE64, sig, |
228 |
|
|
SIG_RSA_SHA1_PKCS1_BASE64_LEN)) |
229 |
|
|
{ |
230 |
|
|
*hash = KEYNOTE_HASH_SHA1; |
231 |
|
|
*enc = ENCODING_BASE64; |
232 |
|
|
*internal = INTERNAL_ENC_PKCS1; |
233 |
|
|
return KEYNOTE_ALGORITHM_RSA; |
234 |
|
|
} |
235 |
|
|
|
236 |
|
|
if (!strncasecmp(SIG_X509_SHA1_BASE64, sig, SIG_X509_SHA1_BASE64_LEN)) |
237 |
|
|
{ |
238 |
|
|
*hash = KEYNOTE_HASH_SHA1; |
239 |
|
|
*enc = ENCODING_BASE64; |
240 |
|
|
*internal = INTERNAL_ENC_ASN1; |
241 |
|
|
return KEYNOTE_ALGORITHM_X509; |
242 |
|
|
} |
243 |
|
|
|
244 |
|
|
if (!strncasecmp(SIG_X509_SHA1_HEX, sig, SIG_X509_SHA1_HEX_LEN)) |
245 |
|
|
{ |
246 |
|
|
*hash = KEYNOTE_HASH_SHA1; |
247 |
|
|
*enc = ENCODING_HEX; |
248 |
|
|
*internal = INTERNAL_ENC_ASN1; |
249 |
|
|
return KEYNOTE_ALGORITHM_X509; |
250 |
|
|
} |
251 |
|
|
|
252 |
|
|
*hash = KEYNOTE_HASH_NONE; |
253 |
|
|
*enc = ENCODING_NONE; |
254 |
|
|
*internal = INTERNAL_ENC_NONE; |
255 |
|
|
return KEYNOTE_ALGORITHM_NONE; |
256 |
|
|
} |
257 |
|
|
|
258 |
|
|
/* |
259 |
|
|
* Map a key to an algorithm. Return algorithm number (defined in |
260 |
|
|
* keynote.h), or KEYNOTE_ALGORITHM_NONE if unknown. |
261 |
|
|
* This latter is also a valid algorithm (for logical tags). Also return |
262 |
|
|
* in the second and third arguments the ASCII and internal encodings. |
263 |
|
|
*/ |
264 |
|
|
int |
265 |
|
|
keynote_get_key_algorithm(char *key, int *encoding, int *internalencoding) |
266 |
|
|
{ |
267 |
|
|
if (!strncasecmp(DSA_HEX, key, DSA_HEX_LEN)) |
268 |
|
|
{ |
269 |
|
|
*internalencoding = INTERNAL_ENC_ASN1; |
270 |
|
|
*encoding = ENCODING_HEX; |
271 |
|
|
return KEYNOTE_ALGORITHM_DSA; |
272 |
|
|
} |
273 |
|
|
|
274 |
|
|
if (!strncasecmp(DSA_BASE64, key, DSA_BASE64_LEN)) |
275 |
|
|
{ |
276 |
|
|
*internalencoding = INTERNAL_ENC_ASN1; |
277 |
|
|
*encoding = ENCODING_BASE64; |
278 |
|
|
return KEYNOTE_ALGORITHM_DSA; |
279 |
|
|
} |
280 |
|
|
|
281 |
|
|
if (!strncasecmp(RSA_PKCS1_HEX, key, RSA_PKCS1_HEX_LEN)) |
282 |
|
|
{ |
283 |
|
|
*internalencoding = INTERNAL_ENC_PKCS1; |
284 |
|
|
*encoding = ENCODING_HEX; |
285 |
|
|
return KEYNOTE_ALGORITHM_RSA; |
286 |
|
|
} |
287 |
|
|
|
288 |
|
|
if (!strncasecmp(RSA_PKCS1_BASE64, key, RSA_PKCS1_BASE64_LEN)) |
289 |
|
|
{ |
290 |
|
|
*internalencoding = INTERNAL_ENC_PKCS1; |
291 |
|
|
*encoding = ENCODING_BASE64; |
292 |
|
|
return KEYNOTE_ALGORITHM_RSA; |
293 |
|
|
} |
294 |
|
|
|
295 |
|
|
if (!strncasecmp(X509_BASE64, key, X509_BASE64_LEN)) |
296 |
|
|
{ |
297 |
|
|
*internalencoding = INTERNAL_ENC_ASN1; |
298 |
|
|
*encoding = ENCODING_BASE64; |
299 |
|
|
return KEYNOTE_ALGORITHM_X509; |
300 |
|
|
} |
301 |
|
|
|
302 |
|
|
if (!strncasecmp(X509_HEX, key, X509_HEX_LEN)) |
303 |
|
|
{ |
304 |
|
|
*internalencoding = INTERNAL_ENC_ASN1; |
305 |
|
|
*encoding = ENCODING_HEX; |
306 |
|
|
return KEYNOTE_ALGORITHM_X509; |
307 |
|
|
} |
308 |
|
|
|
309 |
|
|
if (!strncasecmp(BINARY_HEX, key, BINARY_HEX_LEN)) |
310 |
|
|
{ |
311 |
|
|
*internalencoding = INTERNAL_ENC_NONE; |
312 |
|
|
*encoding = ENCODING_HEX; |
313 |
|
|
return KEYNOTE_ALGORITHM_BINARY; |
314 |
|
|
} |
315 |
|
|
|
316 |
|
|
if (!strncasecmp(BINARY_BASE64, key, BINARY_BASE64_LEN)) |
317 |
|
|
{ |
318 |
|
|
*internalencoding = INTERNAL_ENC_NONE; |
319 |
|
|
*encoding = ENCODING_BASE64; |
320 |
|
|
return KEYNOTE_ALGORITHM_BINARY; |
321 |
|
|
} |
322 |
|
|
|
323 |
|
|
*internalencoding = INTERNAL_ENC_NONE; |
324 |
|
|
*encoding = ENCODING_NONE; |
325 |
|
|
return KEYNOTE_ALGORITHM_NONE; |
326 |
|
|
} |
327 |
|
|
|
328 |
|
|
/* |
329 |
|
|
* Same as keynote_get_key_algorithm(), only verify that this is |
330 |
|
|
* a private key (just look at the prefix). |
331 |
|
|
*/ |
332 |
|
|
static int |
333 |
|
|
keynote_get_private_key_algorithm(char *key, int *encoding, |
334 |
|
|
int *internalencoding) |
335 |
|
|
{ |
336 |
|
|
if (strncasecmp(KEYNOTE_PRIVATE_KEY_PREFIX, key, |
337 |
|
|
KEYNOTE_PRIVATE_KEY_PREFIX_LEN)) |
338 |
|
|
{ |
339 |
|
|
*internalencoding = INTERNAL_ENC_NONE; |
340 |
|
|
*encoding = ENCODING_NONE; |
341 |
|
|
return KEYNOTE_ALGORITHM_NONE; |
342 |
|
|
} |
343 |
|
|
|
344 |
|
|
return keynote_get_key_algorithm(key + KEYNOTE_PRIVATE_KEY_PREFIX_LEN, |
345 |
|
|
encoding, internalencoding); |
346 |
|
|
} |
347 |
|
|
|
348 |
|
|
/* |
349 |
|
|
* Decode a string to a key. Return 0 on success. |
350 |
|
|
*/ |
351 |
|
|
int |
352 |
|
|
kn_decode_key(struct keynote_deckey *dc, char *key, int keytype) |
353 |
|
|
{ |
354 |
|
|
void *kk = NULL; |
355 |
|
|
X509 *px509Cert; |
356 |
|
|
EVP_PKEY *pPublicKey; |
357 |
|
|
unsigned char *ptr = NULL, *decoded = NULL; |
358 |
|
|
int encoding, internalencoding; |
359 |
|
|
long len = 0; |
360 |
|
|
|
361 |
|
|
keynote_errno = 0; |
362 |
|
|
if (keytype == KEYNOTE_PRIVATE_KEY) |
363 |
|
|
dc->dec_algorithm = keynote_get_private_key_algorithm(key, &encoding, |
364 |
|
|
&internalencoding); |
365 |
|
|
else |
366 |
|
|
dc->dec_algorithm = keynote_get_key_algorithm(key, &encoding, |
367 |
|
|
&internalencoding); |
368 |
|
|
if (dc->dec_algorithm == KEYNOTE_ALGORITHM_NONE) |
369 |
|
|
{ |
370 |
|
|
if ((dc->dec_key = strdup(key)) == NULL) { |
371 |
|
|
keynote_errno = ERROR_MEMORY; |
372 |
|
|
return -1; |
373 |
|
|
} |
374 |
|
|
|
375 |
|
|
return 0; |
376 |
|
|
} |
377 |
|
|
|
378 |
|
|
key = strchr(key, ':'); /* Move forward, to the Encoding. We're guaranteed |
379 |
|
|
* to have a ':' character, since this is a key */ |
380 |
|
|
key++; |
381 |
|
|
|
382 |
|
|
/* Remove ASCII encoding */ |
383 |
|
|
switch (encoding) |
384 |
|
|
{ |
385 |
|
|
case ENCODING_NONE: |
386 |
|
|
break; |
387 |
|
|
|
388 |
|
|
case ENCODING_HEX: |
389 |
|
|
len = strlen(key) / 2; |
390 |
|
|
if (kn_decode_hex(key, (char **) &decoded) != 0) |
391 |
|
|
return -1; |
392 |
|
|
ptr = decoded; |
393 |
|
|
break; |
394 |
|
|
|
395 |
|
|
case ENCODING_BASE64: |
396 |
|
|
len = strlen(key); |
397 |
|
|
if (len % 4) /* Base64 encoding must be a multiple of 4 */ |
398 |
|
|
{ |
399 |
|
|
keynote_errno = ERROR_SYNTAX; |
400 |
|
|
return -1; |
401 |
|
|
} |
402 |
|
|
|
403 |
|
|
len = 3 * (len / 4); |
404 |
|
|
decoded = calloc(len, sizeof(unsigned char)); |
405 |
|
|
ptr = decoded; |
406 |
|
|
if (decoded == NULL) { |
407 |
|
|
keynote_errno = ERROR_MEMORY; |
408 |
|
|
return -1; |
409 |
|
|
} |
410 |
|
|
|
411 |
|
|
if ((len = kn_decode_base64(key, decoded, len)) == -1) |
412 |
|
|
return -1; |
413 |
|
|
break; |
414 |
|
|
|
415 |
|
|
case ENCODING_NATIVE: |
416 |
|
|
decoded = strdup(key); |
417 |
|
|
if (decoded == NULL) { |
418 |
|
|
keynote_errno = ERROR_MEMORY; |
419 |
|
|
return -1; |
420 |
|
|
} |
421 |
|
|
len = strlen(key); |
422 |
|
|
ptr = decoded; |
423 |
|
|
break; |
424 |
|
|
|
425 |
|
|
default: |
426 |
|
|
keynote_errno = ERROR_SYNTAX; |
427 |
|
|
return -1; |
428 |
|
|
} |
429 |
|
|
|
430 |
|
|
/* DSA-HEX */ |
431 |
|
|
if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_DSA) && |
432 |
|
|
(internalencoding == INTERNAL_ENC_ASN1)) |
433 |
|
|
{ |
434 |
|
|
dc->dec_key = DSA_new(); |
435 |
|
|
if (dc->dec_key == NULL) { |
436 |
|
|
keynote_errno = ERROR_MEMORY; |
437 |
|
|
return -1; |
438 |
|
|
} |
439 |
|
|
|
440 |
|
|
kk = dc->dec_key; |
441 |
|
|
if (keytype == KEYNOTE_PRIVATE_KEY) |
442 |
|
|
{ |
443 |
|
|
if (d2i_DSAPrivateKey((DSA **) &kk,(const unsigned char **) &decoded, len) == NULL) { |
444 |
|
|
free(ptr); |
445 |
|
|
DSA_free(kk); |
446 |
|
|
keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ |
447 |
|
|
return -1; |
448 |
|
|
} |
449 |
|
|
} |
450 |
|
|
else |
451 |
|
|
{ |
452 |
|
|
if (d2i_DSAPublicKey((DSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { |
453 |
|
|
free(ptr); |
454 |
|
|
DSA_free(kk); |
455 |
|
|
keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ |
456 |
|
|
return -1; |
457 |
|
|
} |
458 |
|
|
} |
459 |
|
|
|
460 |
|
|
free(ptr); |
461 |
|
|
|
462 |
|
|
return 0; |
463 |
|
|
} |
464 |
|
|
|
465 |
|
|
/* RSA-PKCS1-HEX */ |
466 |
|
|
if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_RSA) && |
467 |
|
|
(internalencoding == INTERNAL_ENC_PKCS1)) |
468 |
|
|
{ |
469 |
|
|
dc->dec_key = RSA_new(); |
470 |
|
|
if (dc->dec_key == NULL) { |
471 |
|
|
keynote_errno = ERROR_MEMORY; |
472 |
|
|
return -1; |
473 |
|
|
} |
474 |
|
|
|
475 |
|
|
kk = dc->dec_key; |
476 |
|
|
if (keytype == KEYNOTE_PRIVATE_KEY) |
477 |
|
|
{ |
478 |
|
|
if (d2i_RSAPrivateKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { |
479 |
|
|
free(ptr); |
480 |
|
|
RSA_free(kk); |
481 |
|
|
keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ |
482 |
|
|
return -1; |
483 |
|
|
} |
484 |
|
|
if (RSA_blinding_on((RSA *) kk, NULL) != 1) { |
485 |
|
|
free(ptr); |
486 |
|
|
RSA_free(kk); |
487 |
|
|
keynote_errno = ERROR_MEMORY; |
488 |
|
|
return -1; |
489 |
|
|
} |
490 |
|
|
} |
491 |
|
|
else |
492 |
|
|
{ |
493 |
|
|
if (d2i_RSAPublicKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { |
494 |
|
|
free(ptr); |
495 |
|
|
RSA_free(kk); |
496 |
|
|
keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ |
497 |
|
|
return -1; |
498 |
|
|
} |
499 |
|
|
} |
500 |
|
|
|
501 |
|
|
free(ptr); |
502 |
|
|
|
503 |
|
|
return 0; |
504 |
|
|
} |
505 |
|
|
|
506 |
|
|
/* X509 Cert */ |
507 |
|
|
if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_X509) && |
508 |
|
|
(internalencoding == INTERNAL_ENC_ASN1) && |
509 |
|
|
(keytype == KEYNOTE_PUBLIC_KEY)) |
510 |
|
|
{ |
511 |
|
|
if ((px509Cert = X509_new()) == NULL) { |
512 |
|
|
free(ptr); |
513 |
|
|
keynote_errno = ERROR_MEMORY; |
514 |
|
|
return -1; |
515 |
|
|
} |
516 |
|
|
|
517 |
|
|
if(d2i_X509(&px509Cert, (const unsigned char **)&decoded, len) == NULL) |
518 |
|
|
{ |
519 |
|
|
free(ptr); |
520 |
|
|
X509_free(px509Cert); |
521 |
|
|
keynote_errno = ERROR_SYNTAX; |
522 |
|
|
return -1; |
523 |
|
|
} |
524 |
|
|
|
525 |
|
|
if ((pPublicKey = X509_get_pubkey(px509Cert)) == NULL) { |
526 |
|
|
free(ptr); |
527 |
|
|
X509_free(px509Cert); |
528 |
|
|
keynote_errno = ERROR_SYNTAX; |
529 |
|
|
return -1; |
530 |
|
|
} |
531 |
|
|
|
532 |
|
|
/* RSA-specific */ |
533 |
|
|
dc->dec_key = pPublicKey->pkey.rsa; |
534 |
|
|
|
535 |
|
|
free(ptr); |
536 |
|
|
return 0; |
537 |
|
|
} |
538 |
|
|
|
539 |
|
|
/* BINARY keys */ |
540 |
|
|
if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_BINARY) && |
541 |
|
|
(internalencoding == INTERNAL_ENC_NONE)) |
542 |
|
|
{ |
543 |
|
|
dc->dec_key = calloc(1, sizeof(struct keynote_binary)); |
544 |
|
|
if (dc->dec_key == NULL) |
545 |
|
|
{ |
546 |
|
|
keynote_errno = ERROR_MEMORY; |
547 |
|
|
return -1; |
548 |
|
|
} |
549 |
|
|
|
550 |
|
|
((struct keynote_binary *) dc->dec_key)->bn_key = decoded; |
551 |
|
|
((struct keynote_binary *) dc->dec_key)->bn_len = len; |
552 |
|
|
return RESULT_TRUE; |
553 |
|
|
} |
554 |
|
|
|
555 |
|
|
/* Add support for more algorithms here */ |
556 |
|
|
|
557 |
|
|
free(ptr); |
558 |
|
|
|
559 |
|
|
/* This shouldn't ever be reached really */ |
560 |
|
|
keynote_errno = ERROR_SYNTAX; |
561 |
|
|
return -1; |
562 |
|
|
} |
563 |
|
|
|
564 |
|
|
/* |
565 |
|
|
* Compare two keys for equality. Return RESULT_TRUE if equal, |
566 |
|
|
* RESULT_FALSE otherwise. |
567 |
|
|
*/ |
568 |
|
|
int |
569 |
|
|
kn_keycompare(void *key1, void *key2, int algorithm) |
570 |
|
|
{ |
571 |
|
|
DSA *p1, *p2; |
572 |
|
|
RSA *p3, *p4; |
573 |
|
|
struct keynote_binary *bn1, *bn2; |
574 |
|
|
|
575 |
|
|
if (key1 == NULL || key2 == NULL) |
576 |
|
|
return RESULT_FALSE; |
577 |
|
|
|
578 |
|
|
switch (algorithm) |
579 |
|
|
{ |
580 |
|
|
case KEYNOTE_ALGORITHM_NONE: |
581 |
|
|
if (!strcmp(key1, key2)) |
582 |
|
|
return RESULT_TRUE; |
583 |
|
|
else |
584 |
|
|
return RESULT_FALSE; |
585 |
|
|
|
586 |
|
|
case KEYNOTE_ALGORITHM_DSA: |
587 |
|
|
p1 = (DSA *) key1; |
588 |
|
|
p2 = (DSA *) key2; |
589 |
|
|
if (!BN_cmp(p1->p, p2->p) && |
590 |
|
|
!BN_cmp(p1->q, p2->q) && |
591 |
|
|
!BN_cmp(p1->g, p2->g) && |
592 |
|
|
!BN_cmp(p1->pub_key, p2->pub_key)) |
593 |
|
|
return RESULT_TRUE; |
594 |
|
|
else |
595 |
|
|
return RESULT_FALSE; |
596 |
|
|
|
597 |
|
|
case KEYNOTE_ALGORITHM_X509: |
598 |
|
|
p3 = (RSA *) key1; |
599 |
|
|
p4 = (RSA *) key2; |
600 |
|
|
if (!BN_cmp(p3->n, p4->n) && |
601 |
|
|
!BN_cmp(p3->e, p4->e)) |
602 |
|
|
return RESULT_TRUE; |
603 |
|
|
else |
604 |
|
|
return RESULT_FALSE; |
605 |
|
|
|
606 |
|
|
case KEYNOTE_ALGORITHM_RSA: |
607 |
|
|
p3 = (RSA *) key1; |
608 |
|
|
p4 = (RSA *) key2; |
609 |
|
|
if (!BN_cmp(p3->n, p4->n) && |
610 |
|
|
!BN_cmp(p3->e, p4->e)) |
611 |
|
|
return RESULT_TRUE; |
612 |
|
|
else |
613 |
|
|
return RESULT_FALSE; |
614 |
|
|
|
615 |
|
|
case KEYNOTE_ALGORITHM_ELGAMAL: |
616 |
|
|
/* Not supported yet */ |
617 |
|
|
return RESULT_FALSE; |
618 |
|
|
|
619 |
|
|
case KEYNOTE_ALGORITHM_PGP: |
620 |
|
|
/* Not supported yet */ |
621 |
|
|
return RESULT_FALSE; |
622 |
|
|
|
623 |
|
|
case KEYNOTE_ALGORITHM_BINARY: |
624 |
|
|
bn1 = (struct keynote_binary *) key1; |
625 |
|
|
bn2 = (struct keynote_binary *) key2; |
626 |
|
|
if ((bn1->bn_len == bn2->bn_len) && |
627 |
|
|
!memcmp(bn1->bn_key, bn2->bn_key, bn1->bn_len)) |
628 |
|
|
return RESULT_TRUE; |
629 |
|
|
else |
630 |
|
|
return RESULT_FALSE; |
631 |
|
|
|
632 |
|
|
default: |
633 |
|
|
return RESULT_FALSE; |
634 |
|
|
} |
635 |
|
|
} |
636 |
|
|
|
637 |
|
|
/* |
638 |
|
|
* Verify the signature on an assertion; return SIGRESULT_TRUE is |
639 |
|
|
* success, SIGRESULT_FALSE otherwise. |
640 |
|
|
*/ |
641 |
|
|
int |
642 |
|
|
keynote_sigverify_assertion(struct assertion *as) |
643 |
|
|
{ |
644 |
|
|
int hashtype, enc, intenc, alg = KEYNOTE_ALGORITHM_NONE, hashlen = 0; |
645 |
|
|
unsigned char *sig, *decoded = NULL, *ptr; |
646 |
|
|
unsigned char res2[20]; |
647 |
|
|
SHA_CTX shscontext; |
648 |
|
|
MD5_CTX md5context; |
649 |
|
|
int len = 0; |
650 |
|
|
DSA *dsa; |
651 |
|
|
RSA *rsa; |
652 |
|
|
if (as->as_signature == NULL || |
653 |
|
|
as->as_startofsignature == NULL || |
654 |
|
|
as->as_allbutsignature == NULL || |
655 |
|
|
as->as_allbutsignature - as->as_startofsignature <= 0) |
656 |
|
|
return SIGRESULT_FALSE; |
657 |
|
|
|
658 |
|
|
alg = keynote_get_sig_algorithm(as->as_signature, &hashtype, &enc, |
659 |
|
|
&intenc); |
660 |
|
|
if (alg == KEYNOTE_ALGORITHM_NONE) |
661 |
|
|
return SIGRESULT_FALSE; |
662 |
|
|
|
663 |
|
|
/* Check for matching algorithms */ |
664 |
|
|
if ((alg != as->as_signeralgorithm) && |
665 |
|
|
!((alg == KEYNOTE_ALGORITHM_RSA) && |
666 |
|
|
(as->as_signeralgorithm == KEYNOTE_ALGORITHM_X509)) && |
667 |
|
|
!((alg == KEYNOTE_ALGORITHM_X509) && |
668 |
|
|
(as->as_signeralgorithm == KEYNOTE_ALGORITHM_RSA))) |
669 |
|
|
return SIGRESULT_FALSE; |
670 |
|
|
|
671 |
|
|
sig = strchr(as->as_signature, ':'); /* Move forward to the Encoding. We |
672 |
|
|
* are guaranteed to have a ':' |
673 |
|
|
* character, since this is a valid |
674 |
|
|
* signature */ |
675 |
|
|
sig++; |
676 |
|
|
|
677 |
|
|
switch (hashtype) |
678 |
|
|
{ |
679 |
|
|
case KEYNOTE_HASH_SHA1: |
680 |
|
|
hashlen = 20; |
681 |
|
|
memset(res2, 0, hashlen); |
682 |
|
|
SHA1_Init(&shscontext); |
683 |
|
|
SHA1_Update(&shscontext, as->as_startofsignature, |
684 |
|
|
as->as_allbutsignature - as->as_startofsignature); |
685 |
|
|
SHA1_Update(&shscontext, as->as_signature, |
686 |
|
|
(char *) sig - as->as_signature); |
687 |
|
|
SHA1_Final(res2, &shscontext); |
688 |
|
|
break; |
689 |
|
|
|
690 |
|
|
case KEYNOTE_HASH_MD5: |
691 |
|
|
hashlen = 16; |
692 |
|
|
memset(res2, 0, hashlen); |
693 |
|
|
MD5_Init(&md5context); |
694 |
|
|
MD5_Update(&md5context, as->as_startofsignature, |
695 |
|
|
as->as_allbutsignature - as->as_startofsignature); |
696 |
|
|
MD5_Update(&md5context, as->as_signature, |
697 |
|
|
(char *) sig - as->as_signature); |
698 |
|
|
MD5_Final(res2, &md5context); |
699 |
|
|
break; |
700 |
|
|
|
701 |
|
|
case KEYNOTE_HASH_NONE: |
702 |
|
|
break; |
703 |
|
|
} |
704 |
|
|
|
705 |
|
|
/* Remove ASCII encoding */ |
706 |
|
|
switch (enc) |
707 |
|
|
{ |
708 |
|
|
case ENCODING_NONE: |
709 |
|
|
ptr = NULL; |
710 |
|
|
break; |
711 |
|
|
|
712 |
|
|
case ENCODING_HEX: |
713 |
|
|
len = strlen(sig) / 2; |
714 |
|
|
if (kn_decode_hex(sig, (char **) &decoded) != 0) |
715 |
|
|
return -1; |
716 |
|
|
ptr = decoded; |
717 |
|
|
break; |
718 |
|
|
|
719 |
|
|
case ENCODING_BASE64: |
720 |
|
|
len = strlen(sig); |
721 |
|
|
if (len % 4) /* Base64 encoding must be a multiple of 4 */ |
722 |
|
|
{ |
723 |
|
|
keynote_errno = ERROR_SYNTAX; |
724 |
|
|
return -1; |
725 |
|
|
} |
726 |
|
|
|
727 |
|
|
len = 3 * (len / 4); |
728 |
|
|
decoded = calloc(len, sizeof(unsigned char)); |
729 |
|
|
ptr = decoded; |
730 |
|
|
if (decoded == NULL) { |
731 |
|
|
keynote_errno = ERROR_MEMORY; |
732 |
|
|
return -1; |
733 |
|
|
} |
734 |
|
|
|
735 |
|
|
len = kn_decode_base64(sig, decoded, len); |
736 |
|
|
if ((len == -1) || (len == 0) || (len == 1)) |
737 |
|
|
return -1; |
738 |
|
|
break; |
739 |
|
|
|
740 |
|
|
case ENCODING_NATIVE: |
741 |
|
|
|
742 |
|
|
if ((decoded = strdup(sig)) == NULL) { |
743 |
|
|
keynote_errno = ERROR_MEMORY; |
744 |
|
|
return -1; |
745 |
|
|
} |
746 |
|
|
len = strlen(sig); |
747 |
|
|
ptr = decoded; |
748 |
|
|
break; |
749 |
|
|
|
750 |
|
|
default: |
751 |
|
|
keynote_errno = ERROR_SYNTAX; |
752 |
|
|
return -1; |
753 |
|
|
} |
754 |
|
|
|
755 |
|
|
/* DSA */ |
756 |
|
|
if ((alg == KEYNOTE_ALGORITHM_DSA) && (intenc == INTERNAL_ENC_ASN1)) |
757 |
|
|
{ |
758 |
|
|
dsa = (DSA *) as->as_authorizer; |
759 |
|
|
if (DSA_verify(0, res2, hashlen, decoded, len, dsa) == 1) { |
760 |
|
|
free(ptr); |
761 |
|
|
return SIGRESULT_TRUE; |
762 |
|
|
} |
763 |
|
|
} |
764 |
|
|
else /* RSA */ |
765 |
|
|
if ((alg == KEYNOTE_ALGORITHM_RSA) && (intenc == INTERNAL_ENC_PKCS1)) |
766 |
|
|
{ |
767 |
|
|
rsa = (RSA *) as->as_authorizer; |
768 |
|
|
if (RSA_verify_ASN1_OCTET_STRING(RSA_PKCS1_PADDING, res2, hashlen, |
769 |
|
|
decoded, len, rsa) == 1) { |
770 |
|
|
free(ptr); |
771 |
|
|
return SIGRESULT_TRUE; |
772 |
|
|
} |
773 |
|
|
} |
774 |
|
|
else |
775 |
|
|
if ((alg == KEYNOTE_ALGORITHM_X509) && (intenc == INTERNAL_ENC_ASN1)) |
776 |
|
|
{ |
777 |
|
|
/* RSA-specific */ |
778 |
|
|
rsa = (RSA *) as->as_authorizer; |
779 |
|
|
if (RSA_verify(NID_shaWithRSAEncryption, res2, hashlen, decoded, |
780 |
|
|
len, rsa) == 1) { |
781 |
|
|
free(ptr); |
782 |
|
|
return SIGRESULT_TRUE; |
783 |
|
|
} |
784 |
|
|
} |
785 |
|
|
|
786 |
|
|
/* Handle more algorithms here */ |
787 |
|
|
|
788 |
|
|
free(ptr); |
789 |
|
|
|
790 |
|
|
return SIGRESULT_FALSE; |
791 |
|
|
} |
792 |
|
|
|
793 |
|
|
/* |
794 |
|
|
* Sign an assertion. |
795 |
|
|
*/ |
796 |
|
|
static char * |
797 |
|
|
keynote_sign_assertion(struct assertion *as, char *sigalg, void *key, |
798 |
|
|
int keyalg, int verifyflag) |
799 |
|
|
{ |
800 |
|
|
int slen, i, hashlen = 0, hashtype, alg, encoding, internalenc; |
801 |
|
|
unsigned char *sig = NULL, *finalbuf = NULL; |
802 |
|
|
unsigned char res2[LARGEST_HASH_SIZE], *sbuf = NULL; |
803 |
|
|
BIO *biokey = NULL; |
804 |
|
|
DSA *dsa = NULL; |
805 |
|
|
RSA *rsa = NULL; |
806 |
|
|
SHA_CTX shscontext; |
807 |
|
|
MD5_CTX md5context; |
808 |
|
|
int len; |
809 |
|
|
|
810 |
|
|
if (as->as_signature_string_s == NULL || |
811 |
|
|
as->as_startofsignature == NULL || |
812 |
|
|
as->as_allbutsignature == NULL || |
813 |
|
|
as->as_allbutsignature - as->as_startofsignature <= 0 || |
814 |
|
|
as->as_authorizer == NULL || |
815 |
|
|
key == NULL || |
816 |
|
|
as->as_signeralgorithm == KEYNOTE_ALGORITHM_NONE) |
817 |
|
|
{ |
818 |
|
|
keynote_errno = ERROR_SYNTAX; |
819 |
|
|
return NULL; |
820 |
|
|
} |
821 |
|
|
|
822 |
|
|
alg = keynote_get_sig_algorithm(sigalg, &hashtype, &encoding, |
823 |
|
|
&internalenc); |
824 |
|
|
if (((alg != as->as_signeralgorithm) && |
825 |
|
|
!((alg == KEYNOTE_ALGORITHM_RSA) && |
826 |
|
|
(as->as_signeralgorithm == KEYNOTE_ALGORITHM_X509)) && |
827 |
|
|
!((alg == KEYNOTE_ALGORITHM_X509) && |
828 |
|
|
(as->as_signeralgorithm == KEYNOTE_ALGORITHM_RSA))) || |
829 |
|
|
((alg != keyalg) && |
830 |
|
|
!((alg == KEYNOTE_ALGORITHM_RSA) && |
831 |
|
|
(keyalg == KEYNOTE_ALGORITHM_X509)) && |
832 |
|
|
!((alg == KEYNOTE_ALGORITHM_X509) && |
833 |
|
|
(keyalg == KEYNOTE_ALGORITHM_RSA)))) |
834 |
|
|
{ |
835 |
|
|
keynote_errno = ERROR_SYNTAX; |
836 |
|
|
return NULL; |
837 |
|
|
} |
838 |
|
|
|
839 |
|
|
sig = strchr(sigalg, ':'); |
840 |
|
|
if (sig == NULL) |
841 |
|
|
{ |
842 |
|
|
keynote_errno = ERROR_SYNTAX; |
843 |
|
|
return NULL; |
844 |
|
|
} |
845 |
|
|
|
846 |
|
|
sig++; |
847 |
|
|
|
848 |
|
|
switch (hashtype) |
849 |
|
|
{ |
850 |
|
|
case KEYNOTE_HASH_SHA1: |
851 |
|
|
hashlen = 20; |
852 |
|
|
memset(res2, 0, hashlen); |
853 |
|
|
SHA1_Init(&shscontext); |
854 |
|
|
SHA1_Update(&shscontext, as->as_startofsignature, |
855 |
|
|
as->as_allbutsignature - as->as_startofsignature); |
856 |
|
|
SHA1_Update(&shscontext, sigalg, (char *) sig - sigalg); |
857 |
|
|
SHA1_Final(res2, &shscontext); |
858 |
|
|
break; |
859 |
|
|
|
860 |
|
|
case KEYNOTE_HASH_MD5: |
861 |
|
|
hashlen = 16; |
862 |
|
|
memset(res2, 0, hashlen); |
863 |
|
|
MD5_Init(&md5context); |
864 |
|
|
MD5_Update(&md5context, as->as_startofsignature, |
865 |
|
|
as->as_allbutsignature - as->as_startofsignature); |
866 |
|
|
MD5_Update(&md5context, sigalg, (char *) sig - sigalg); |
867 |
|
|
MD5_Final(res2, &md5context); |
868 |
|
|
break; |
869 |
|
|
|
870 |
|
|
case KEYNOTE_HASH_NONE: |
871 |
|
|
break; |
872 |
|
|
} |
873 |
|
|
|
874 |
|
|
if ((alg == KEYNOTE_ALGORITHM_DSA) && |
875 |
|
|
(hashtype == KEYNOTE_HASH_SHA1) && |
876 |
|
|
(internalenc == INTERNAL_ENC_ASN1) && |
877 |
|
|
((encoding == ENCODING_HEX) || (encoding == ENCODING_BASE64))) |
878 |
|
|
{ |
879 |
|
|
dsa = (DSA *) key; |
880 |
|
|
sbuf = calloc(DSA_size(dsa), sizeof(unsigned char)); |
881 |
|
|
if (sbuf == NULL) |
882 |
|
|
{ |
883 |
|
|
keynote_errno = ERROR_MEMORY; |
884 |
|
|
return NULL; |
885 |
|
|
} |
886 |
|
|
|
887 |
|
|
if (DSA_sign(0, res2, hashlen, sbuf, &slen, dsa) <= 0) |
888 |
|
|
{ |
889 |
|
|
free(sbuf); |
890 |
|
|
keynote_errno = ERROR_SYNTAX; |
891 |
|
|
return NULL; |
892 |
|
|
} |
893 |
|
|
} |
894 |
|
|
else |
895 |
|
|
if ((alg == KEYNOTE_ALGORITHM_RSA) && |
896 |
|
|
((hashtype == KEYNOTE_HASH_SHA1) || |
897 |
|
|
(hashtype == KEYNOTE_HASH_MD5)) && |
898 |
|
|
(internalenc == INTERNAL_ENC_PKCS1) && |
899 |
|
|
((encoding == ENCODING_HEX) || (encoding == ENCODING_BASE64))) |
900 |
|
|
{ |
901 |
|
|
rsa = (RSA *) key; |
902 |
|
|
sbuf = calloc(RSA_size(rsa), sizeof(unsigned char)); |
903 |
|
|
if (sbuf == NULL) |
904 |
|
|
{ |
905 |
|
|
keynote_errno = ERROR_MEMORY; |
906 |
|
|
return NULL; |
907 |
|
|
} |
908 |
|
|
|
909 |
|
|
if (RSA_sign_ASN1_OCTET_STRING(RSA_PKCS1_PADDING, res2, hashlen, |
910 |
|
|
sbuf, &slen, rsa) <= 0) |
911 |
|
|
{ |
912 |
|
|
free(sbuf); |
913 |
|
|
keynote_errno = ERROR_SYNTAX; |
914 |
|
|
return NULL; |
915 |
|
|
} |
916 |
|
|
} |
917 |
|
|
else |
918 |
|
|
if ((alg == KEYNOTE_ALGORITHM_X509) && |
919 |
|
|
(hashtype == KEYNOTE_HASH_SHA1) && |
920 |
|
|
(internalenc == INTERNAL_ENC_ASN1)) |
921 |
|
|
{ |
922 |
|
|
if ((biokey = BIO_new(BIO_s_mem())) == NULL) |
923 |
|
|
{ |
924 |
|
|
keynote_errno = ERROR_SYNTAX; |
925 |
|
|
return NULL; |
926 |
|
|
} |
927 |
|
|
|
928 |
|
|
if (BIO_write(biokey, key, strlen(key) + 1) <= 0) |
929 |
|
|
{ |
930 |
|
|
BIO_free(biokey); |
931 |
|
|
keynote_errno = ERROR_SYNTAX; |
932 |
|
|
return NULL; |
933 |
|
|
} |
934 |
|
|
|
935 |
|
|
/* RSA-specific */ |
936 |
|
|
rsa = (RSA *) PEM_read_bio_RSAPrivateKey(biokey, NULL, NULL, NULL); |
937 |
|
|
if (rsa == NULL) |
938 |
|
|
{ |
939 |
|
|
BIO_free(biokey); |
940 |
|
|
keynote_errno = ERROR_SYNTAX; |
941 |
|
|
return NULL; |
942 |
|
|
} |
943 |
|
|
|
944 |
|
|
sbuf = calloc(RSA_size(rsa), sizeof(char)); |
945 |
|
|
if (sbuf == NULL) |
946 |
|
|
{ |
947 |
|
|
BIO_free(biokey); |
948 |
|
|
RSA_free(rsa); |
949 |
|
|
keynote_errno = ERROR_MEMORY; |
950 |
|
|
return NULL; |
951 |
|
|
} |
952 |
|
|
|
953 |
|
|
if (RSA_sign(NID_shaWithRSAEncryption, res2, hashlen, sbuf, &slen, |
954 |
|
|
rsa) <= 0) |
955 |
|
|
{ |
956 |
|
|
BIO_free(biokey); |
957 |
|
|
RSA_free(rsa); |
958 |
|
|
free(sbuf); |
959 |
|
|
keynote_errno = ERROR_SIGN_FAILURE; |
960 |
|
|
return NULL; |
961 |
|
|
} |
962 |
|
|
|
963 |
|
|
BIO_free(biokey); |
964 |
|
|
RSA_free(rsa); |
965 |
|
|
} |
966 |
|
|
else /* Other algorithms here */ |
967 |
|
|
{ |
968 |
|
|
keynote_errno = ERROR_SYNTAX; |
969 |
|
|
return NULL; |
970 |
|
|
} |
971 |
|
|
|
972 |
|
|
/* ASCII encoding */ |
973 |
|
|
switch (encoding) |
974 |
|
|
{ |
975 |
|
|
case ENCODING_HEX: |
976 |
|
|
i = kn_encode_hex(sbuf, (char **) &finalbuf, slen); |
977 |
|
|
free(sbuf); |
978 |
|
|
if (i != 0) |
979 |
|
|
return NULL; |
980 |
|
|
break; |
981 |
|
|
|
982 |
|
|
case ENCODING_BASE64: |
983 |
|
|
finalbuf = calloc(2 * slen, sizeof(unsigned char)); |
984 |
|
|
if (finalbuf == NULL) |
985 |
|
|
{ |
986 |
|
|
keynote_errno = ERROR_MEMORY; |
987 |
|
|
free(sbuf); |
988 |
|
|
return NULL; |
989 |
|
|
} |
990 |
|
|
|
991 |
|
|
slen = kn_encode_base64(sbuf, slen, finalbuf, 2 * slen); |
992 |
|
|
free(sbuf); |
993 |
|
|
if (slen == -1) { |
994 |
|
|
free(finalbuf); |
995 |
|
|
return NULL; |
996 |
|
|
} |
997 |
|
|
break; |
998 |
|
|
|
999 |
|
|
default: |
1000 |
|
|
free(sbuf); |
1001 |
|
|
keynote_errno = ERROR_SYNTAX; |
1002 |
|
|
return NULL; |
1003 |
|
|
} |
1004 |
|
|
|
1005 |
|
|
/* Replace as->as_signature */ |
1006 |
|
|
len = strlen(sigalg) + strlen(finalbuf) + 1; |
1007 |
|
|
as->as_signature = calloc(len, sizeof(char)); |
1008 |
|
|
if (as->as_signature == NULL) |
1009 |
|
|
{ |
1010 |
|
|
free(finalbuf); |
1011 |
|
|
keynote_errno = ERROR_MEMORY; |
1012 |
|
|
return NULL; |
1013 |
|
|
} |
1014 |
|
|
|
1015 |
|
|
/* Concatenate algorithm name and signature value */ |
1016 |
|
|
snprintf(as->as_signature, len, "%s%s", sigalg, finalbuf); |
1017 |
|
|
free(finalbuf); |
1018 |
|
|
finalbuf = as->as_signature; |
1019 |
|
|
|
1020 |
|
|
/* Verify the newly-created signature if requested */ |
1021 |
|
|
if (verifyflag) |
1022 |
|
|
{ |
1023 |
|
|
/* Do the signature verification */ |
1024 |
|
|
if (keynote_sigverify_assertion(as) != SIGRESULT_TRUE) |
1025 |
|
|
{ |
1026 |
|
|
as->as_signature = NULL; |
1027 |
|
|
free(finalbuf); |
1028 |
|
|
if (keynote_errno == 0) |
1029 |
|
|
keynote_errno = ERROR_SYNTAX; |
1030 |
|
|
return NULL; |
1031 |
|
|
} |
1032 |
|
|
|
1033 |
|
|
as->as_signature = NULL; |
1034 |
|
|
} |
1035 |
|
|
else |
1036 |
|
|
as->as_signature = NULL; |
1037 |
|
|
|
1038 |
|
|
/* Everything ok */ |
1039 |
|
|
return (char *) finalbuf; |
1040 |
|
|
} |
1041 |
|
|
|
1042 |
|
|
/* |
1043 |
|
|
* Verify the signature on an assertion. |
1044 |
|
|
*/ |
1045 |
|
|
int |
1046 |
|
|
kn_verify_assertion(char *buf, int len) |
1047 |
|
|
{ |
1048 |
|
|
struct assertion *as; |
1049 |
|
|
int res; |
1050 |
|
|
|
1051 |
|
|
keynote_errno = 0; |
1052 |
|
|
as = keynote_parse_assertion(buf, len, ASSERT_FLAG_SIGVER); |
1053 |
|
|
if (as == NULL) |
1054 |
|
|
return -1; |
1055 |
|
|
|
1056 |
|
|
res = keynote_sigverify_assertion(as); |
1057 |
|
|
keynote_free_assertion(as); |
1058 |
|
|
return res; |
1059 |
|
|
} |
1060 |
|
|
|
1061 |
|
|
/* |
1062 |
|
|
* Produce the signature for an assertion. |
1063 |
|
|
*/ |
1064 |
|
|
char * |
1065 |
|
|
kn_sign_assertion(char *buf, int buflen, char *key, char *sigalg, int vflag) |
1066 |
|
|
{ |
1067 |
|
|
int i, alg, hashtype, encoding, internalenc; |
1068 |
|
|
struct keynote_deckey dc; |
1069 |
|
|
struct assertion *as; |
1070 |
|
|
char *s, *sig; |
1071 |
|
|
|
1072 |
|
|
keynote_errno = 0; |
1073 |
|
|
s = NULL; |
1074 |
|
|
|
1075 |
|
|
if (sigalg == NULL || buf == NULL || key == NULL) |
1076 |
|
|
{ |
1077 |
|
|
keynote_errno = ERROR_NOTFOUND; |
1078 |
|
|
return NULL; |
1079 |
|
|
} |
1080 |
|
|
|
1081 |
|
|
if (sigalg[0] == '\0' || sigalg[strlen(sigalg) - 1] != ':') |
1082 |
|
|
{ |
1083 |
|
|
keynote_errno = ERROR_SYNTAX; |
1084 |
|
|
return NULL; |
1085 |
|
|
} |
1086 |
|
|
|
1087 |
|
|
/* We're using a different format for X509 private keys, so... */ |
1088 |
|
|
alg = keynote_get_sig_algorithm(sigalg, &hashtype, &encoding, |
1089 |
|
|
&internalenc); |
1090 |
|
|
if (alg != KEYNOTE_ALGORITHM_X509) |
1091 |
|
|
{ |
1092 |
|
|
/* Parse the private key */ |
1093 |
|
|
s = keynote_get_private_key(key); |
1094 |
|
|
if (s == NULL) |
1095 |
|
|
return NULL; |
1096 |
|
|
|
1097 |
|
|
/* Decode private key */ |
1098 |
|
|
i = kn_decode_key(&dc, s, KEYNOTE_PRIVATE_KEY); |
1099 |
|
|
if (i == -1) |
1100 |
|
|
{ |
1101 |
|
|
free(s); |
1102 |
|
|
return NULL; |
1103 |
|
|
} |
1104 |
|
|
} |
1105 |
|
|
else /* X509 private key */ |
1106 |
|
|
{ |
1107 |
|
|
dc.dec_key = key; |
1108 |
|
|
dc.dec_algorithm = alg; |
1109 |
|
|
} |
1110 |
|
|
|
1111 |
|
|
as = keynote_parse_assertion(buf, buflen, ASSERT_FLAG_SIGGEN); |
1112 |
|
|
if (as == NULL) |
1113 |
|
|
{ |
1114 |
|
|
if (alg != KEYNOTE_ALGORITHM_X509) |
1115 |
|
|
{ |
1116 |
|
|
keynote_free_key(dc.dec_key, dc.dec_algorithm); |
1117 |
|
|
free(s); |
1118 |
|
|
} |
1119 |
|
|
return NULL; |
1120 |
|
|
} |
1121 |
|
|
|
1122 |
|
|
sig = keynote_sign_assertion(as, sigalg, dc.dec_key, dc.dec_algorithm, |
1123 |
|
|
vflag); |
1124 |
|
|
if (alg != KEYNOTE_ALGORITHM_X509) |
1125 |
|
|
keynote_free_key(dc.dec_key, dc.dec_algorithm); |
1126 |
|
|
keynote_free_assertion(as); |
1127 |
|
|
if (s != NULL) |
1128 |
|
|
free(s); |
1129 |
|
|
return sig; |
1130 |
|
|
} |
1131 |
|
|
|
1132 |
|
|
/* |
1133 |
|
|
* ASCII-encode a key. |
1134 |
|
|
*/ |
1135 |
|
|
char * |
1136 |
|
|
kn_encode_key(struct keynote_deckey *dc, int iencoding, |
1137 |
|
|
int encoding, int keytype) |
1138 |
|
|
{ |
1139 |
|
|
char *foo, *ptr; |
1140 |
|
|
DSA *dsa; |
1141 |
|
|
RSA *rsa; |
1142 |
|
|
int i; |
1143 |
|
|
struct keynote_binary *bn; |
1144 |
|
|
char *s; |
1145 |
|
|
|
1146 |
|
|
keynote_errno = 0; |
1147 |
|
|
if (dc == NULL || dc->dec_key == NULL) |
1148 |
|
|
{ |
1149 |
|
|
keynote_errno = ERROR_NOTFOUND; |
1150 |
|
|
return NULL; |
1151 |
|
|
} |
1152 |
|
|
|
1153 |
|
|
/* DSA keys */ |
1154 |
|
|
if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_DSA) && |
1155 |
|
|
(iencoding == INTERNAL_ENC_ASN1) && |
1156 |
|
|
((encoding == ENCODING_HEX) || (encoding == ENCODING_BASE64))) |
1157 |
|
|
{ |
1158 |
|
|
dsa = (DSA *) dc->dec_key; |
1159 |
|
|
if (keytype == KEYNOTE_PUBLIC_KEY) |
1160 |
|
|
i = i2d_DSAPublicKey(dsa, NULL); |
1161 |
|
|
else |
1162 |
|
|
i = i2d_DSAPrivateKey(dsa, NULL); |
1163 |
|
|
|
1164 |
|
|
if (i <= 0) |
1165 |
|
|
{ |
1166 |
|
|
keynote_errno = ERROR_SYNTAX; |
1167 |
|
|
return NULL; |
1168 |
|
|
} |
1169 |
|
|
|
1170 |
|
|
ptr = foo = calloc(i, sizeof(char)); |
1171 |
|
|
if (foo == NULL) |
1172 |
|
|
{ |
1173 |
|
|
keynote_errno = ERROR_MEMORY; |
1174 |
|
|
return NULL; |
1175 |
|
|
} |
1176 |
|
|
|
1177 |
|
|
dsa->write_params = 1; |
1178 |
|
|
if (keytype == KEYNOTE_PUBLIC_KEY) |
1179 |
|
|
i2d_DSAPublicKey(dsa, (unsigned char **) &foo); |
1180 |
|
|
else |
1181 |
|
|
i2d_DSAPrivateKey(dsa, (unsigned char **) &foo); |
1182 |
|
|
|
1183 |
|
|
if (encoding == ENCODING_HEX) |
1184 |
|
|
{ |
1185 |
|
|
if (kn_encode_hex(ptr, &s, i) != 0) |
1186 |
|
|
{ |
1187 |
|
|
free(ptr); |
1188 |
|
|
return NULL; |
1189 |
|
|
} |
1190 |
|
|
|
1191 |
|
|
free(ptr); |
1192 |
|
|
return s; |
1193 |
|
|
} |
1194 |
|
|
else |
1195 |
|
|
if (encoding == ENCODING_BASE64) |
1196 |
|
|
{ |
1197 |
|
|
s = calloc(2 * i, sizeof(char)); |
1198 |
|
|
if (s == NULL) |
1199 |
|
|
{ |
1200 |
|
|
free(ptr); |
1201 |
|
|
keynote_errno = ERROR_MEMORY; |
1202 |
|
|
return NULL; |
1203 |
|
|
} |
1204 |
|
|
|
1205 |
|
|
if (kn_encode_base64(ptr, i, s, 2 * i) == -1) |
1206 |
|
|
{ |
1207 |
|
|
free(s); |
1208 |
|
|
free(ptr); |
1209 |
|
|
return NULL; |
1210 |
|
|
} |
1211 |
|
|
|
1212 |
|
|
free(ptr); |
1213 |
|
|
return s; |
1214 |
|
|
} |
1215 |
|
|
} |
1216 |
|
|
|
1217 |
|
|
/* RSA keys */ |
1218 |
|
|
if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_RSA) && |
1219 |
|
|
(iencoding == INTERNAL_ENC_PKCS1) && |
1220 |
|
|
((encoding == ENCODING_HEX) || (encoding == ENCODING_BASE64))) |
1221 |
|
|
{ |
1222 |
|
|
rsa = (RSA *) dc->dec_key; |
1223 |
|
|
if (keytype == KEYNOTE_PUBLIC_KEY) |
1224 |
|
|
i = i2d_RSAPublicKey(rsa, NULL); |
1225 |
|
|
else |
1226 |
|
|
i = i2d_RSAPrivateKey(rsa, NULL); |
1227 |
|
|
|
1228 |
|
|
if (i <= 0) |
1229 |
|
|
{ |
1230 |
|
|
keynote_errno = ERROR_SYNTAX; |
1231 |
|
|
return NULL; |
1232 |
|
|
} |
1233 |
|
|
|
1234 |
|
|
ptr = foo = calloc(i, sizeof(char)); |
1235 |
|
|
if (foo == NULL) |
1236 |
|
|
{ |
1237 |
|
|
keynote_errno = ERROR_MEMORY; |
1238 |
|
|
return NULL; |
1239 |
|
|
} |
1240 |
|
|
|
1241 |
|
|
if (keytype == KEYNOTE_PUBLIC_KEY) |
1242 |
|
|
i2d_RSAPublicKey(rsa, (unsigned char **) &foo); |
1243 |
|
|
else |
1244 |
|
|
i2d_RSAPrivateKey(rsa, (unsigned char **) &foo); |
1245 |
|
|
|
1246 |
|
|
if (encoding == ENCODING_HEX) |
1247 |
|
|
{ |
1248 |
|
|
if (kn_encode_hex(ptr, &s, i) != 0) |
1249 |
|
|
{ |
1250 |
|
|
free(ptr); |
1251 |
|
|
return NULL; |
1252 |
|
|
} |
1253 |
|
|
|
1254 |
|
|
free(ptr); |
1255 |
|
|
return s; |
1256 |
|
|
} |
1257 |
|
|
else |
1258 |
|
|
if (encoding == ENCODING_BASE64) |
1259 |
|
|
{ |
1260 |
|
|
s = calloc(2 * i, sizeof(char)); |
1261 |
|
|
if (s == NULL) |
1262 |
|
|
{ |
1263 |
|
|
free(ptr); |
1264 |
|
|
keynote_errno = ERROR_MEMORY; |
1265 |
|
|
return NULL; |
1266 |
|
|
} |
1267 |
|
|
|
1268 |
|
|
if (kn_encode_base64(ptr, i, s, 2 * i) == -1) |
1269 |
|
|
{ |
1270 |
|
|
free(s); |
1271 |
|
|
free(ptr); |
1272 |
|
|
return NULL; |
1273 |
|
|
} |
1274 |
|
|
|
1275 |
|
|
free(ptr); |
1276 |
|
|
return s; |
1277 |
|
|
} |
1278 |
|
|
} |
1279 |
|
|
|
1280 |
|
|
/* BINARY keys */ |
1281 |
|
|
if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_BINARY) && |
1282 |
|
|
(iencoding == INTERNAL_ENC_NONE) && |
1283 |
|
|
((encoding == ENCODING_HEX) || (encoding == ENCODING_BASE64))) |
1284 |
|
|
{ |
1285 |
|
|
bn = (struct keynote_binary *) dc->dec_key; |
1286 |
|
|
|
1287 |
|
|
if (encoding == ENCODING_HEX) |
1288 |
|
|
{ |
1289 |
|
|
if (kn_encode_hex(bn->bn_key, &s, bn->bn_len) != 0) |
1290 |
|
|
return NULL; |
1291 |
|
|
|
1292 |
|
|
return s; |
1293 |
|
|
} |
1294 |
|
|
else |
1295 |
|
|
if (encoding == ENCODING_BASE64) |
1296 |
|
|
{ |
1297 |
|
|
s = calloc(2 * bn->bn_len, sizeof(char)); |
1298 |
|
|
if (s == NULL) |
1299 |
|
|
{ |
1300 |
|
|
keynote_errno = ERROR_MEMORY; |
1301 |
|
|
return NULL; |
1302 |
|
|
} |
1303 |
|
|
|
1304 |
|
|
if (kn_encode_base64(bn->bn_key, bn->bn_len, s, |
1305 |
|
|
2 * bn->bn_len) == -1) |
1306 |
|
|
{ |
1307 |
|
|
free(s); |
1308 |
|
|
return NULL; |
1309 |
|
|
} |
1310 |
|
|
|
1311 |
|
|
return s; |
1312 |
|
|
} |
1313 |
|
|
} |
1314 |
|
|
|
1315 |
|
|
keynote_errno = ERROR_NOTFOUND; |
1316 |
|
|
return NULL; |
1317 |
|
|
} |