1 |
|
|
/* $OpenBSD: key.c,v 1.26 2017/02/03 08:23:46 guenther 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 <netinet/in.h> |
24 |
|
|
#include <string.h> |
25 |
|
|
#include <stdlib.h> |
26 |
|
|
|
27 |
|
|
#include "key.h" |
28 |
|
|
#include "libcrypto.h" |
29 |
|
|
#include "log.h" |
30 |
|
|
#include "util.h" |
31 |
|
|
#include "x509.h" |
32 |
|
|
|
33 |
|
|
void |
34 |
|
|
key_free(int type, int private, void *key) |
35 |
|
|
{ |
36 |
|
|
switch (type) { |
37 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
38 |
|
|
free(key); |
39 |
|
|
break; |
40 |
|
|
case ISAKMP_KEY_RSA: |
41 |
|
|
RSA_free(key); |
42 |
|
|
break; |
43 |
|
|
case ISAKMP_KEY_NONE: |
44 |
|
|
default: |
45 |
|
|
log_error("key_free: unknown/unsupportedkey type %d", type); |
46 |
|
|
break; |
47 |
|
|
} |
48 |
|
|
} |
49 |
|
|
|
50 |
|
|
/* Convert from internal form to serialized */ |
51 |
|
|
void |
52 |
|
|
key_serialize(int type, int private, void *key, u_int8_t **data, |
53 |
|
|
size_t *datalenp) |
54 |
|
|
{ |
55 |
|
|
u_int8_t *p; |
56 |
|
|
size_t datalen; |
57 |
|
|
|
58 |
|
|
switch (type) { |
59 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
60 |
|
|
*datalenp = strlen((char *)key); |
61 |
|
|
*data = (u_int8_t *)strdup((char *)key); |
62 |
|
|
break; |
63 |
|
|
case ISAKMP_KEY_RSA: |
64 |
|
|
switch (private) { |
65 |
|
|
case ISAKMP_KEYTYPE_PUBLIC: |
66 |
|
|
datalen = i2d_RSAPublicKey((RSA *)key, NULL); |
67 |
|
|
*data = p = malloc(datalen); |
68 |
|
|
if (!p) { |
69 |
|
|
log_error("key_serialize: malloc (%lu) failed", |
70 |
|
|
(unsigned long)datalen); |
71 |
|
|
return; |
72 |
|
|
} |
73 |
|
|
*datalenp = i2d_RSAPublicKey((RSA *) key, &p); |
74 |
|
|
break; |
75 |
|
|
|
76 |
|
|
case ISAKMP_KEYTYPE_PRIVATE: |
77 |
|
|
datalen = i2d_RSAPrivateKey((RSA *)key, NULL); |
78 |
|
|
*data = p = malloc(datalen); |
79 |
|
|
if (!p) { |
80 |
|
|
log_error("key_serialize: malloc (%lu) failed", |
81 |
|
|
(unsigned long)datalen); |
82 |
|
|
return; |
83 |
|
|
} |
84 |
|
|
*datalenp = i2d_RSAPrivateKey((RSA *)key, &p); |
85 |
|
|
break; |
86 |
|
|
} |
87 |
|
|
break; |
88 |
|
|
default: |
89 |
|
|
log_error("key_serialize: unknown/unsupported key type %d", |
90 |
|
|
type); |
91 |
|
|
break; |
92 |
|
|
} |
93 |
|
|
} |
94 |
|
|
|
95 |
|
|
/* Convert from serialized to printable */ |
96 |
|
|
char * |
97 |
|
|
key_printable(int type, int private, u_int8_t *data, size_t datalen) |
98 |
|
|
{ |
99 |
|
|
switch (type) { |
100 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
101 |
|
|
return strdup((char *)data); |
102 |
|
|
|
103 |
|
|
case ISAKMP_KEY_RSA: |
104 |
|
|
return raw2hex(data, datalen); |
105 |
|
|
|
106 |
|
|
default: |
107 |
|
|
log_error("key_printable: unknown/unsupported key type %d", |
108 |
|
|
type); |
109 |
|
|
return 0; |
110 |
|
|
} |
111 |
|
|
} |
112 |
|
|
|
113 |
|
|
/* Convert from serialized to internal. */ |
114 |
|
|
void * |
115 |
|
|
key_internalize(int type, int private, u_int8_t *data, size_t datalen) |
116 |
|
|
{ |
117 |
|
|
switch (type) { |
118 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
119 |
|
|
return strdup((char *)data); |
120 |
|
|
case ISAKMP_KEY_RSA: |
121 |
|
|
switch (private) { |
122 |
|
|
#if OPENSSL_VERSION_NUMBER >= 0x00907000L |
123 |
|
|
case ISAKMP_KEYTYPE_PUBLIC: |
124 |
|
|
return d2i_RSAPublicKey(NULL, |
125 |
|
|
(const u_int8_t **)&data, datalen); |
126 |
|
|
case ISAKMP_KEYTYPE_PRIVATE: |
127 |
|
|
return d2i_RSAPrivateKey(NULL, |
128 |
|
|
(const u_int8_t **)&data, datalen); |
129 |
|
|
#else |
130 |
|
|
case ISAKMP_KEYTYPE_PUBLIC: |
131 |
|
|
return d2i_RSAPublicKey(NULL, &data, datalen); |
132 |
|
|
case ISAKMP_KEYTYPE_PRIVATE: |
133 |
|
|
return d2i_RSAPrivateKey(NULL, &data, datalen); |
134 |
|
|
#endif |
135 |
|
|
default: |
136 |
|
|
log_error("key_internalize: not public or private " |
137 |
|
|
"RSA key passed"); |
138 |
|
|
return 0; |
139 |
|
|
} |
140 |
|
|
break; |
141 |
|
|
default: |
142 |
|
|
log_error("key_internalize: unknown/unsupported key type %d", |
143 |
|
|
type); |
144 |
|
|
break; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
return 0; |
148 |
|
|
} |
149 |
|
|
|
150 |
|
|
/* Convert from printable to serialized */ |
151 |
|
|
void |
152 |
|
|
key_from_printable(int type, int private, char *key, u_int8_t **data, |
153 |
|
|
u_int32_t *datalenp) |
154 |
|
|
{ |
155 |
|
|
u_int32_t datalen; |
156 |
|
|
|
157 |
|
|
switch (type) { |
158 |
|
|
case ISAKMP_KEY_PASSPHRASE: |
159 |
|
|
*datalenp = strlen(key); |
160 |
|
|
*data = (u_int8_t *) strdup(key); |
161 |
|
|
break; |
162 |
|
|
|
163 |
|
|
case ISAKMP_KEY_RSA: |
164 |
|
|
datalen = (strlen(key) + 1) / 2; /* Round up, just in case */ |
165 |
|
|
*data = malloc(datalen); |
166 |
|
|
if (!*data) { |
167 |
|
|
log_error("key_from_printable: malloc (%d) failed", |
168 |
|
|
datalen); |
169 |
|
|
*datalenp = 0; |
170 |
|
|
return; |
171 |
|
|
} |
172 |
|
|
if (hex2raw(key, *data, datalen)) { |
173 |
|
|
log_error("key_from_printable: invalid hex key"); |
174 |
|
|
free(*data); |
175 |
|
|
*data = NULL; |
176 |
|
|
*datalenp = 0; |
177 |
|
|
return; |
178 |
|
|
} |
179 |
|
|
*datalenp = datalen; |
180 |
|
|
break; |
181 |
|
|
|
182 |
|
|
default: |
183 |
|
|
log_error("key_from_printable: " |
184 |
|
|
"unknown/unsupported key type %d", type); |
185 |
|
|
*data = NULL; |
186 |
|
|
*datalenp = 0; |
187 |
|
|
break; |
188 |
|
|
} |
189 |
|
|
} |