1 |
|
|
/* $OpenBSD: key.c,v 1.25 2007/03/05 20:11:40 moritz Exp $ */ |
2 |
|
|
/* |
3 |
|
|
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) |
4 |
|
|
* |
5 |
|
|
* Copyright (c) 2000-2001 Angelos D. Keromytis. |
6 |
|
|
* |
7 |
|
|
* Permission to use, copy, and modify this software with or without fee |
8 |
|
|
* is hereby granted, provided that this entire notice is included in |
9 |
|
|
* all copies of any software which is or includes a copy or |
10 |
|
|
* modification of this software. |
11 |
|
|
* You may use this code under the GNU public license if you so wish. Please |
12 |
|
|
* contribute changes back to the authors under this freer than GPL license |
13 |
|
|
* so that we may further the use of strong encryption without limitations to |
14 |
|
|
* all. |
15 |
|
|
* |
16 |
|
|
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR |
17 |
|
|
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY |
18 |
|
|
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE |
19 |
|
|
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR |
20 |
|
|
* PURPOSE. |
21 |
|
|
*/ |
22 |
|
|
|
23 |
|
|
#include <string.h> |
24 |
|
|
#include <stdlib.h> |
25 |
|
|
|
26 |
|
|
#include "key.h" |
27 |
|
|
#include "libcrypto.h" |
28 |
|
|
#include "log.h" |
29 |
|
|
#include "util.h" |
30 |
|
|
#include "x509.h" |
31 |
|
|
|
32 |
|
|
void |
33 |
|
|
key_free(int type, int private, void *key) |
34 |
|
|
{ |
35 |
|
|
switch (type) { |
36 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
37 |
|
|
free(key); |
38 |
|
|
break; |
39 |
|
|
case ISAKMP_KEY_RSA: |
40 |
|
|
RSA_free(key); |
41 |
|
|
break; |
42 |
|
|
case ISAKMP_KEY_NONE: |
43 |
|
|
default: |
44 |
|
|
log_error("key_free: unknown/unsupportedkey type %d", type); |
45 |
|
|
break; |
46 |
|
|
} |
47 |
|
|
} |
48 |
|
|
|
49 |
|
|
/* Convert from internal form to serialized */ |
50 |
|
|
void |
51 |
|
|
key_serialize(int type, int private, void *key, u_int8_t **data, |
52 |
|
|
size_t *datalenp) |
53 |
|
|
{ |
54 |
|
|
u_int8_t *p; |
55 |
|
|
size_t datalen; |
56 |
|
|
|
57 |
|
|
switch (type) { |
58 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
59 |
|
|
*datalenp = strlen((char *)key); |
60 |
|
|
*data = (u_int8_t *)strdup((char *)key); |
61 |
|
|
break; |
62 |
|
|
case ISAKMP_KEY_RSA: |
63 |
|
|
switch (private) { |
64 |
|
|
case ISAKMP_KEYTYPE_PUBLIC: |
65 |
|
|
datalen = i2d_RSAPublicKey((RSA *)key, NULL); |
66 |
|
|
*data = p = malloc(datalen); |
67 |
|
|
if (!p) { |
68 |
|
|
log_error("key_serialize: malloc (%lu) failed", |
69 |
|
|
(unsigned long)datalen); |
70 |
|
|
return; |
71 |
|
|
} |
72 |
|
|
*datalenp = i2d_RSAPublicKey((RSA *) key, &p); |
73 |
|
|
break; |
74 |
|
|
|
75 |
|
|
case ISAKMP_KEYTYPE_PRIVATE: |
76 |
|
|
datalen = i2d_RSAPrivateKey((RSA *)key, NULL); |
77 |
|
|
*data = p = malloc(datalen); |
78 |
|
|
if (!p) { |
79 |
|
|
log_error("key_serialize: malloc (%lu) failed", |
80 |
|
|
(unsigned long)datalen); |
81 |
|
|
return; |
82 |
|
|
} |
83 |
|
|
*datalenp = i2d_RSAPrivateKey((RSA *)key, &p); |
84 |
|
|
break; |
85 |
|
|
} |
86 |
|
|
break; |
87 |
|
|
default: |
88 |
|
|
log_error("key_serialize: unknown/unsupported key type %d", |
89 |
|
|
type); |
90 |
|
|
break; |
91 |
|
|
} |
92 |
|
|
} |
93 |
|
|
|
94 |
|
|
/* Convert from serialized to printable */ |
95 |
|
|
char * |
96 |
|
|
key_printable(int type, int private, u_int8_t *data, size_t datalen) |
97 |
|
|
{ |
98 |
|
|
switch (type) { |
99 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
100 |
|
|
return strdup((char *)data); |
101 |
|
|
|
102 |
|
|
case ISAKMP_KEY_RSA: |
103 |
|
|
return raw2hex(data, datalen); |
104 |
|
|
|
105 |
|
|
default: |
106 |
|
|
log_error("key_printable: unknown/unsupported key type %d", |
107 |
|
|
type); |
108 |
|
|
return 0; |
109 |
|
|
} |
110 |
|
|
} |
111 |
|
|
|
112 |
|
|
/* Convert from serialized to internal. */ |
113 |
|
|
void * |
114 |
|
|
key_internalize(int type, int private, u_int8_t *data, size_t datalen) |
115 |
|
|
{ |
116 |
|
|
switch (type) { |
117 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
118 |
|
|
return strdup((char *)data); |
119 |
|
|
case ISAKMP_KEY_RSA: |
120 |
|
|
switch (private) { |
121 |
|
|
#if OPENSSL_VERSION_NUMBER >= 0x00907000L |
122 |
|
|
case ISAKMP_KEYTYPE_PUBLIC: |
123 |
|
|
return d2i_RSAPublicKey(NULL, |
124 |
|
|
(const u_int8_t **)&data, datalen); |
125 |
|
|
case ISAKMP_KEYTYPE_PRIVATE: |
126 |
|
|
return d2i_RSAPrivateKey(NULL, |
127 |
|
|
(const u_int8_t **)&data, datalen); |
128 |
|
|
#else |
129 |
|
|
case ISAKMP_KEYTYPE_PUBLIC: |
130 |
|
|
return d2i_RSAPublicKey(NULL, &data, datalen); |
131 |
|
|
case ISAKMP_KEYTYPE_PRIVATE: |
132 |
|
|
return d2i_RSAPrivateKey(NULL, &data, datalen); |
133 |
|
|
#endif |
134 |
|
|
default: |
135 |
|
|
log_error("key_internalize: not public or private " |
136 |
|
|
"RSA key passed"); |
137 |
|
|
return 0; |
138 |
|
|
} |
139 |
|
|
break; |
140 |
|
|
default: |
141 |
|
|
log_error("key_internalize: unknown/unsupported key type %d", |
142 |
|
|
type); |
143 |
|
|
break; |
144 |
|
|
} |
145 |
|
|
|
146 |
|
|
return 0; |
147 |
|
|
} |
148 |
|
|
|
149 |
|
|
/* Convert from printable to serialized */ |
150 |
|
|
void |
151 |
|
|
key_from_printable(int type, int private, char *key, u_int8_t **data, |
152 |
|
|
u_int32_t *datalenp) |
153 |
|
|
{ |
154 |
|
|
u_int32_t datalen; |
155 |
|
|
|
156 |
|
|
switch (type) { |
157 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
158 |
|
|
*datalenp = strlen(key); |
159 |
|
|
*data = (u_int8_t *) strdup(key); |
160 |
|
|
break; |
161 |
|
|
|
162 |
|
|
case ISAKMP_KEY_RSA: |
163 |
|
|
datalen = (strlen(key) + 1) / 2; /* Round up, just in case */ |
164 |
|
|
*data = malloc(datalen); |
165 |
|
|
if (!*data) { |
166 |
|
|
log_error("key_from_printable: malloc (%d) failed", |
167 |
|
|
datalen); |
168 |
|
|
*datalenp = 0; |
169 |
|
|
return; |
170 |
|
|
} |
171 |
|
|
if (hex2raw(key, *data, datalen)) { |
172 |
|
|
log_error("key_from_printable: invalid hex key"); |
173 |
|
|
free(*data); |
174 |
|
|
*data = NULL; |
175 |
|
|
*datalenp = 0; |
176 |
|
|
return; |
177 |
|
|
} |
178 |
|
|
*datalenp = datalen; |
179 |
|
|
break; |
180 |
|
|
|
181 |
|
|
default: |
182 |
|
|
log_error("key_from_printable: " |
183 |
|
|
"unknown/unsupported key type %d", type); |
184 |
|
|
*data = NULL; |
185 |
|
|
*datalenp = 0; |
186 |
|
|
break; |
187 |
|
|
} |
188 |
|
|
} |