1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
1 |
/*
|
2 |
* OpenVPN -- An application to securely tunnel IP networks
|
|
3 |
* over a single TCP/UDP port, with support for SSL/TLS-based
|
|
4 |
* session authentication and key exchange,
|
|
5 |
* packet encryption, packet authentication, and
|
|
6 |
* packet compression.
|
|
7 |
*
|
|
1.3.5
by Alberto Gonzalez Iniesta
Import upstream version 2.1.3 |
8 |
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
9 |
*
|
10 |
* This program is free software; you can redistribute it and/or modify
|
|
11 |
* it under the terms of the GNU General Public License version 2
|
|
12 |
* as published by the Free Software Foundation.
|
|
13 |
*
|
|
14 |
* This program is distributed in the hope that it will be useful,
|
|
15 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17 |
* GNU General Public License for more details.
|
|
18 |
*
|
|
19 |
* You should have received a copy of the GNU General Public License
|
|
20 |
* along with this program (see the file COPYING included with this
|
|
21 |
* distribution); if not, write to the Free Software Foundation, Inc.,
|
|
22 |
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
23 |
*/
|
|
24 |
||
25 |
#include "syshead.h" |
|
26 |
||
27 |
#if defined(ENABLE_PKCS11)
|
|
28 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
29 |
#include <pkcs11-helper-1.0/pkcs11h-certificate.h> |
30 |
#include <pkcs11-helper-1.0/pkcs11h-openssl.h> |
|
31 |
#include "basic.h" |
|
32 |
#include "error.h" |
|
33 |
#include "manage.h" |
|
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
34 |
#include "base64.h" |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
35 |
#include "pkcs11.h" |
36 |
||
37 |
static
|
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
38 |
time_t
|
39 |
__mytime (void) { |
|
40 |
return openvpn_time (NULL); |
|
41 |
}
|
|
42 |
||
43 |
#if !defined(_WIN32)
|
|
44 |
static
|
|
45 |
int
|
|
46 |
__mygettimeofday (struct timeval *tv) { |
|
47 |
return gettimeofday (tv, NULL); |
|
48 |
}
|
|
49 |
#endif
|
|
50 |
||
51 |
static
|
|
52 |
void
|
|
53 |
__mysleep (const unsigned long usec) { |
|
54 |
#if defined(_WIN32)
|
|
55 |
Sleep (usec/1000); |
|
56 |
#else
|
|
57 |
usleep (usec); |
|
58 |
#endif
|
|
59 |
}
|
|
60 |
||
61 |
||
62 |
static pkcs11h_engine_system_t s_pkcs11h_sys_engine = { |
|
63 |
malloc, |
|
64 |
free, |
|
65 |
__mytime, |
|
66 |
__mysleep, |
|
67 |
#if defined(_WIN32)
|
|
68 |
NULL
|
|
69 |
#else
|
|
70 |
__mygettimeofday
|
|
71 |
#endif
|
|
72 |
};
|
|
73 |
||
74 |
static
|
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
75 |
unsigned
|
76 |
_pkcs11_msg_pkcs112openvpn ( |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
77 |
const unsigned flags |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
78 |
) { |
79 |
unsigned openvpn_flags; |
|
80 |
||
81 |
switch (flags) { |
|
82 |
case PKCS11H_LOG_DEBUG2: |
|
83 |
openvpn_flags = D_PKCS11_DEBUG; |
|
84 |
break; |
|
85 |
case PKCS11H_LOG_DEBUG1: |
|
86 |
openvpn_flags = D_SHOW_PKCS11; |
|
87 |
break; |
|
88 |
case PKCS11H_LOG_INFO: |
|
89 |
openvpn_flags = M_INFO; |
|
90 |
break; |
|
91 |
case PKCS11H_LOG_WARN: |
|
92 |
openvpn_flags = M_WARN; |
|
93 |
break; |
|
94 |
case PKCS11H_LOG_ERROR: |
|
95 |
openvpn_flags = M_FATAL; |
|
96 |
break; |
|
97 |
default: |
|
98 |
openvpn_flags = M_FATAL; |
|
99 |
break; |
|
100 |
}
|
|
101 |
||
102 |
#if defined(ENABLE_PKCS11_FORCE_DEBUG)
|
|
103 |
openvpn_flags=M_INFO; |
|
104 |
#endif
|
|
105 |
||
106 |
return openvpn_flags; |
|
107 |
}
|
|
108 |
||
109 |
static
|
|
110 |
unsigned
|
|
111 |
_pkcs11_msg_openvpn2pkcs11 ( |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
112 |
const unsigned flags |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
113 |
) { |
114 |
unsigned pkcs11_flags; |
|
115 |
||
116 |
if ((flags & D_PKCS11_DEBUG) != 0) { |
|
117 |
pkcs11_flags = PKCS11H_LOG_DEBUG2; |
|
118 |
}
|
|
119 |
else if ((flags & D_SHOW_PKCS11) != 0) { |
|
120 |
pkcs11_flags = PKCS11H_LOG_DEBUG1; |
|
121 |
}
|
|
122 |
else if ((flags & M_INFO) != 0) { |
|
123 |
pkcs11_flags = PKCS11H_LOG_INFO; |
|
124 |
}
|
|
125 |
else if ((flags & M_WARN) != 0) { |
|
126 |
pkcs11_flags = PKCS11H_LOG_WARN; |
|
127 |
}
|
|
128 |
else if ((flags & M_FATAL) != 0) { |
|
129 |
pkcs11_flags = PKCS11H_LOG_ERROR; |
|
130 |
}
|
|
131 |
else { |
|
132 |
pkcs11_flags = PKCS11H_LOG_ERROR; |
|
133 |
}
|
|
134 |
||
135 |
#if defined(ENABLE_PKCS11_FORCE_DEBUG)
|
|
136 |
pkcs11_flags = PKCS11H_LOG_DEBUG2; |
|
137 |
#endif
|
|
138 |
||
139 |
return pkcs11_flags; |
|
140 |
}
|
|
141 |
||
142 |
static
|
|
143 |
void
|
|
144 |
_pkcs11_openvpn_log ( |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
145 |
void * const global_data, |
146 |
unsigned flags, |
|
147 |
const char * const szFormat, |
|
148 |
va_list args |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
149 |
) { |
150 |
char Buffer[10*1024]; |
|
1.3.1
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc19 |
151 |
|
152 |
(void)global_data; |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
153 |
|
154 |
vsnprintf (Buffer, sizeof (Buffer), szFormat, args); |
|
155 |
Buffer[sizeof (Buffer)-1] = 0; |
|
156 |
||
157 |
msg (_pkcs11_msg_pkcs112openvpn (flags), "%s", Buffer); |
|
158 |
}
|
|
159 |
||
160 |
static
|
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
161 |
PKCS11H_BOOL
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
162 |
_pkcs11_openvpn_token_prompt ( |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
163 |
void * const global_data, |
164 |
void * const user_data, |
|
165 |
const pkcs11h_token_id_t token, |
|
166 |
const unsigned retry |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
167 |
) { |
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
168 |
struct user_pass token_resp; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
169 |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
170 |
(void)global_data; |
171 |
(void)user_data; |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
172 |
(void)retry; |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
173 |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
174 |
ASSERT (token!=NULL); |
175 |
||
176 |
CLEAR (token_resp); |
|
177 |
token_resp.defined = false; |
|
178 |
token_resp.nocache = true; |
|
179 |
openvpn_snprintf ( |
|
180 |
token_resp.username, |
|
181 |
sizeof (token_resp.username), |
|
182 |
"Please insert %s token", |
|
183 |
token->label |
|
184 |
);
|
|
185 |
||
186 |
if ( |
|
187 |
!get_user_pass ( |
|
188 |
&token_resp, |
|
189 |
NULL, |
|
190 |
"token-insertion-request", |
|
191 |
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK|GET_USER_PASS_NOFATAL |
|
192 |
)
|
|
193 |
) { |
|
194 |
return false; |
|
195 |
}
|
|
196 |
else { |
|
197 |
return strcmp (token_resp.password, "ok") == 0; |
|
198 |
}
|
|
199 |
}
|
|
200 |
||
201 |
static
|
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
202 |
PKCS11H_BOOL
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
203 |
_pkcs11_openvpn_pin_prompt ( |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
204 |
void * const global_data, |
205 |
void * const user_data, |
|
206 |
const pkcs11h_token_id_t token, |
|
207 |
const unsigned retry, |
|
208 |
char * const pin, |
|
209 |
const size_t pin_max |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
210 |
) { |
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
211 |
struct user_pass token_pass; |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
212 |
char prompt[1024]; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
213 |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
214 |
(void)global_data; |
215 |
(void)user_data; |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
216 |
(void)retry; |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
217 |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
218 |
ASSERT (token!=NULL); |
219 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
220 |
openvpn_snprintf (prompt, sizeof (prompt), "%s token", token->label); |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
221 |
|
222 |
token_pass.defined = false; |
|
223 |
token_pass.nocache = true; |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
224 |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
225 |
if ( |
226 |
!get_user_pass ( |
|
227 |
&token_pass, |
|
228 |
NULL, |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
229 |
prompt, |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
230 |
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL |
231 |
)
|
|
232 |
) { |
|
233 |
return false; |
|
234 |
}
|
|
235 |
else { |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
236 |
strncpynt (pin, token_pass.password, pin_max); |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
237 |
purge_user_pass (&token_pass, true); |
238 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
239 |
if (strlen (pin) == 0) { |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
240 |
return false; |
241 |
}
|
|
242 |
else { |
|
243 |
return true; |
|
244 |
}
|
|
245 |
}
|
|
246 |
}
|
|
247 |
||
248 |
bool
|
|
249 |
pkcs11_initialize ( |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
250 |
const bool protected_auth, |
251 |
const int nPINCachePeriod |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
252 |
) { |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
253 |
CK_RV rv = CKR_FUNCTION_FAILED; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
254 |
|
255 |
dmsg ( |
|
256 |
D_PKCS11_DEBUG, |
|
257 |
"PKCS#11: pkcs11_initialize - entered"
|
|
258 |
);
|
|
259 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
260 |
if ((rv = pkcs11h_engine_setSystem (&s_pkcs11h_sys_engine)) != CKR_OK) { |
261 |
msg (M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
262 |
goto cleanup; |
|
263 |
}
|
|
264 |
||
265 |
if ((rv = pkcs11h_initialize ()) != CKR_OK) { |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
266 |
msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
267 |
goto cleanup; |
268 |
}
|
|
269 |
||
270 |
if ((rv = pkcs11h_setLogHook (_pkcs11_openvpn_log, NULL)) != CKR_OK) { |
|
271 |
msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
272 |
goto cleanup; |
|
273 |
}
|
|
274 |
||
275 |
pkcs11h_setLogLevel (_pkcs11_msg_openvpn2pkcs11 (get_debug_level ())); |
|
276 |
||
277 |
if ((rv = pkcs11h_setForkMode (TRUE)) != CKR_OK) { |
|
278 |
msg (M_FATAL, "PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
279 |
goto cleanup; |
|
280 |
}
|
|
281 |
||
282 |
if ((rv = pkcs11h_setTokenPromptHook (_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK) { |
|
283 |
msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
284 |
goto cleanup; |
|
285 |
}
|
|
286 |
||
287 |
if ((rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK) { |
|
288 |
msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
289 |
goto cleanup; |
|
290 |
}
|
|
291 |
||
292 |
if ((rv = pkcs11h_setProtectedAuthentication (protected_auth)) != CKR_OK) { |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
293 |
msg (M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
294 |
goto cleanup; |
295 |
}
|
|
296 |
||
297 |
if ((rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK) { |
|
298 |
msg (M_FATAL, "PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
299 |
goto cleanup; |
|
300 |
}
|
|
301 |
||
302 |
rv = CKR_OK; |
|
303 |
||
304 |
cleanup: |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
305 |
dmsg ( |
306 |
D_PKCS11_DEBUG, |
|
307 |
"PKCS#11: pkcs11_initialize - return %ld-'%s'", |
|
308 |
rv, |
|
309 |
pkcs11h_getMessage (rv) |
|
310 |
);
|
|
311 |
||
312 |
return rv == CKR_OK; |
|
313 |
}
|
|
314 |
||
315 |
void
|
|
316 |
pkcs11_terminate () { |
|
317 |
dmsg ( |
|
318 |
D_PKCS11_DEBUG, |
|
319 |
"PKCS#11: pkcs11_terminate - entered"
|
|
320 |
);
|
|
321 |
||
322 |
pkcs11h_terminate (); |
|
323 |
||
324 |
dmsg ( |
|
325 |
D_PKCS11_DEBUG, |
|
326 |
"PKCS#11: pkcs11_terminate - return"
|
|
327 |
);
|
|
328 |
}
|
|
329 |
||
330 |
void
|
|
331 |
pkcs11_forkFixup () { |
|
332 |
pkcs11h_forkFixup (); |
|
333 |
}
|
|
334 |
||
335 |
bool
|
|
336 |
pkcs11_addProvider ( |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
337 |
const char * const provider, |
338 |
const bool protected_auth, |
|
339 |
const unsigned private_mode, |
|
340 |
const bool cert_private |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
341 |
) { |
342 |
CK_RV rv = CKR_OK; |
|
343 |
||
344 |
ASSERT (provider!=NULL); |
|
345 |
||
346 |
dmsg ( |
|
347 |
D_PKCS11_DEBUG, |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
348 |
"PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x", |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
349 |
provider, |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
350 |
private_mode
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
351 |
);
|
352 |
||
353 |
msg ( |
|
354 |
M_INFO, |
|
355 |
"PKCS#11: Adding PKCS#11 provider '%s'", |
|
356 |
provider
|
|
357 |
);
|
|
358 |
||
359 |
if ( |
|
360 |
(rv = pkcs11h_addProvider ( |
|
361 |
provider, |
|
362 |
provider, |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
363 |
protected_auth, |
364 |
private_mode, |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
365 |
PKCS11H_SLOTEVENT_METHOD_AUTO, |
366 |
0, |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
367 |
cert_private
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
368 |
)) != CKR_OK |
369 |
) { |
|
370 |
msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv)); |
|
371 |
}
|
|
372 |
||
373 |
dmsg ( |
|
374 |
D_PKCS11_DEBUG, |
|
375 |
"PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'", |
|
376 |
rv, |
|
377 |
pkcs11h_getMessage (rv) |
|
378 |
);
|
|
379 |
||
380 |
return rv == CKR_OK; |
|
381 |
}
|
|
382 |
||
383 |
int
|
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
384 |
pkcs11_logout() { |
385 |
return pkcs11h_logout () == CKR_OK; |
|
386 |
}
|
|
387 |
||
388 |
int
|
|
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
389 |
pkcs11_management_id_count () { |
390 |
pkcs11h_certificate_id_list_t id_list = NULL; |
|
391 |
pkcs11h_certificate_id_list_t t = NULL; |
|
392 |
CK_RV rv = CKR_OK; |
|
393 |
int count = 0; |
|
394 |
||
395 |
dmsg ( |
|
396 |
D_PKCS11_DEBUG, |
|
397 |
"PKCS#11: pkcs11_management_id_count - entered"
|
|
398 |
);
|
|
399 |
||
400 |
if ( |
|
401 |
(rv = pkcs11h_certificate_enumCertificateIds ( |
|
402 |
PKCS11H_ENUM_METHOD_CACHE_EXIST, |
|
403 |
NULL, |
|
404 |
PKCS11H_PROMPT_MASK_ALLOW_ALL, |
|
405 |
NULL, |
|
406 |
&id_list |
|
407 |
)) != CKR_OK |
|
408 |
) { |
|
409 |
msg (M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
410 |
goto cleanup; |
|
411 |
}
|
|
412 |
||
413 |
for (count = 0, t = id_list; t != NULL; t = t->next) { |
|
414 |
count++; |
|
415 |
}
|
|
416 |
||
417 |
cleanup: |
|
418 |
||
419 |
if (id_list != NULL) { |
|
420 |
pkcs11h_certificate_freeCertificateIdList (id_list); |
|
421 |
id_list = NULL; |
|
422 |
}
|
|
423 |
||
424 |
dmsg ( |
|
425 |
D_PKCS11_DEBUG, |
|
426 |
"PKCS#11: pkcs11_management_id_count - return count=%d", |
|
427 |
count
|
|
428 |
);
|
|
429 |
||
430 |
return count; |
|
431 |
}
|
|
432 |
||
433 |
bool
|
|
434 |
pkcs11_management_id_get ( |
|
435 |
const int index, |
|
436 |
char ** id, |
|
437 |
char **base64 |
|
438 |
) { |
|
439 |
pkcs11h_certificate_id_list_t id_list = NULL; |
|
440 |
pkcs11h_certificate_id_list_t entry = NULL; |
|
1.1.10
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc9 |
441 |
#if 0 /* certificate_id seems to be unused -- JY */ |
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
442 |
pkcs11h_certificate_id_t certificate_id = NULL;
|
1.1.10
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc9 |
443 |
#endif
|
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
444 |
pkcs11h_certificate_t certificate = NULL; |
445 |
CK_RV rv = CKR_OK; |
|
1.3.1
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc19 |
446 |
unsigned char *certificate_blob = NULL; |
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
447 |
size_t certificate_blob_size = 0; |
448 |
size_t max; |
|
449 |
char *internal_id = NULL; |
|
450 |
char *internal_base64 = NULL; |
|
451 |
int count = 0; |
|
452 |
bool success = false; |
|
453 |
||
454 |
ASSERT (id!=NULL); |
|
455 |
ASSERT (base64!=NULL); |
|
456 |
||
457 |
dmsg ( |
|
458 |
D_PKCS11_DEBUG, |
|
459 |
"PKCS#11: pkcs11_management_id_get - entered index=%d", |
|
460 |
index
|
|
461 |
);
|
|
462 |
||
463 |
*id = NULL; |
|
464 |
*base64 = NULL; |
|
465 |
||
466 |
if ( |
|
467 |
(rv = pkcs11h_certificate_enumCertificateIds ( |
|
468 |
PKCS11H_ENUM_METHOD_CACHE_EXIST, |
|
469 |
NULL, |
|
470 |
PKCS11H_PROMPT_MASK_ALLOW_ALL, |
|
471 |
NULL, |
|
472 |
&id_list |
|
473 |
)) != CKR_OK |
|
474 |
) { |
|
475 |
msg (M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
476 |
goto cleanup; |
|
477 |
}
|
|
478 |
||
479 |
entry = id_list; |
|
480 |
count = 0; |
|
481 |
while (entry != NULL && count != index) { |
|
482 |
count++; |
|
483 |
entry = entry->next; |
|
484 |
}
|
|
485 |
||
486 |
if (entry == NULL) { |
|
487 |
dmsg ( |
|
488 |
D_PKCS11_DEBUG, |
|
489 |
"PKCS#11: pkcs11_management_id_get - no certificate at index=%d", |
|
490 |
index
|
|
491 |
);
|
|
492 |
goto cleanup; |
|
493 |
}
|
|
494 |
||
495 |
if ( |
|
496 |
(rv = pkcs11h_certificate_serializeCertificateId ( |
|
497 |
NULL, |
|
498 |
&max, |
|
499 |
entry->certificate_id |
|
500 |
)) != CKR_OK |
|
501 |
) { |
|
502 |
msg (M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
503 |
goto cleanup; |
|
504 |
}
|
|
505 |
||
506 |
if ((internal_id = (char *)malloc (max)) == NULL) { |
|
507 |
msg (M_FATAL, "PKCS#11: Cannot allocate memory"); |
|
508 |
goto cleanup; |
|
509 |
}
|
|
510 |
||
511 |
if ( |
|
512 |
(rv = pkcs11h_certificate_serializeCertificateId ( |
|
513 |
internal_id, |
|
514 |
&max, |
|
515 |
entry->certificate_id |
|
516 |
)) != CKR_OK |
|
517 |
) { |
|
518 |
msg (M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
519 |
goto cleanup; |
|
520 |
}
|
|
521 |
||
522 |
if ( |
|
523 |
(rv = pkcs11h_certificate_create ( |
|
524 |
entry->certificate_id, |
|
525 |
NULL, |
|
526 |
PKCS11H_PROMPT_MASK_ALLOW_ALL, |
|
527 |
PKCS11H_PIN_CACHE_INFINITE, |
|
528 |
&certificate |
|
529 |
)) != CKR_OK |
|
530 |
) { |
|
531 |
msg (M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
532 |
goto cleanup; |
|
533 |
}
|
|
534 |
||
535 |
if ( |
|
536 |
(rv = pkcs11h_certificate_getCertificateBlob ( |
|
537 |
certificate, |
|
538 |
NULL, |
|
539 |
&certificate_blob_size |
|
540 |
)) != CKR_OK |
|
541 |
) { |
|
542 |
msg (M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
543 |
goto cleanup; |
|
544 |
}
|
|
545 |
||
1.3.1
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc19 |
546 |
if ((certificate_blob = (unsigned char *)malloc (certificate_blob_size)) == NULL) { |
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
547 |
msg (M_FATAL, "PKCS#11: Cannot allocate memory"); |
548 |
goto cleanup; |
|
549 |
}
|
|
550 |
||
551 |
if ( |
|
552 |
(rv = pkcs11h_certificate_getCertificateBlob ( |
|
553 |
certificate, |
|
554 |
certificate_blob, |
|
555 |
&certificate_blob_size |
|
556 |
)) != CKR_OK |
|
557 |
) { |
|
558 |
msg (M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
559 |
goto cleanup; |
|
560 |
}
|
|
561 |
||
562 |
if (base64_encode (certificate_blob, certificate_blob_size, &internal_base64) == -1) { |
|
563 |
msg (M_WARN, "PKCS#11: Cannot encode certificate"); |
|
564 |
goto cleanup; |
|
565 |
}
|
|
566 |
||
567 |
*id = internal_id; |
|
568 |
internal_id = NULL; |
|
569 |
*base64 = internal_base64; |
|
570 |
internal_base64 = NULL; |
|
571 |
success = true; |
|
572 |
||
573 |
cleanup: |
|
574 |
||
575 |
if (id_list != NULL) { |
|
576 |
pkcs11h_certificate_freeCertificateIdList (id_list); |
|
577 |
id_list = NULL; |
|
578 |
}
|
|
579 |
||
580 |
if (internal_id != NULL) { |
|
581 |
free (internal_id); |
|
582 |
internal_id = NULL; |
|
583 |
}
|
|
584 |
||
585 |
if (internal_base64 != NULL) { |
|
586 |
free (internal_base64); |
|
587 |
internal_base64 = NULL; |
|
588 |
}
|
|
589 |
||
590 |
if (certificate_blob != NULL) { |
|
591 |
free (certificate_blob); |
|
592 |
certificate_blob = NULL; |
|
593 |
}
|
|
594 |
||
595 |
dmsg ( |
|
596 |
D_PKCS11_DEBUG, |
|
597 |
"PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'", |
|
598 |
success ? 1 : 0, |
|
599 |
*id |
|
600 |
);
|
|
601 |
||
602 |
return success; |
|
603 |
}
|
|
604 |
||
605 |
int
|
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
606 |
SSL_CTX_use_pkcs11 ( |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
607 |
SSL_CTX * const ssl_ctx, |
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
608 |
bool pkcs11_id_management, |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
609 |
const char * const pkcs11_id |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
610 |
) { |
611 |
X509 *x509 = NULL; |
|
612 |
RSA *rsa = NULL; |
|
613 |
pkcs11h_certificate_id_t certificate_id = NULL; |
|
614 |
pkcs11h_certificate_t certificate = NULL; |
|
615 |
pkcs11h_openssl_session_t openssl_session = NULL; |
|
616 |
CK_RV rv = CKR_OK; |
|
617 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
618 |
bool ok = false; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
619 |
|
620 |
ASSERT (ssl_ctx!=NULL); |
|
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
621 |
ASSERT (pkcs11_id_management || pkcs11_id!=NULL); |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
622 |
|
623 |
dmsg ( |
|
624 |
D_PKCS11_DEBUG, |
|
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
625 |
"PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'", |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
626 |
(void *)ssl_ctx, |
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
627 |
pkcs11_id_management ? 1 : 0, |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
628 |
pkcs11_id
|
629 |
);
|
|
630 |
||
1.1.9
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc8 |
631 |
if (pkcs11_id_management) { |
632 |
struct user_pass id_resp; |
|
633 |
||
634 |
CLEAR (id_resp); |
|
635 |
||
636 |
id_resp.defined = false; |
|
637 |
id_resp.nocache = true; |
|
638 |
openvpn_snprintf ( |
|
639 |
id_resp.username, |
|
640 |
sizeof (id_resp.username), |
|
641 |
"Please specify PKCS#11 id to use"
|
|
642 |
);
|
|
643 |
||
644 |
if ( |
|
645 |
!get_user_pass ( |
|
646 |
&id_resp, |
|
647 |
NULL, |
|
648 |
"pkcs11-id-request", |
|
649 |
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_STR|GET_USER_PASS_NOFATAL |
|
650 |
)
|
|
651 |
) { |
|
652 |
goto cleanup; |
|
653 |
}
|
|
654 |
||
655 |
if ( |
|
656 |
(rv = pkcs11h_certificate_deserializeCertificateId ( |
|
657 |
&certificate_id, |
|
658 |
id_resp.password |
|
659 |
)) != CKR_OK |
|
660 |
) { |
|
661 |
msg (M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
662 |
goto cleanup; |
|
663 |
}
|
|
664 |
}
|
|
665 |
else { |
|
666 |
if ( |
|
667 |
(rv = pkcs11h_certificate_deserializeCertificateId ( |
|
668 |
&certificate_id, |
|
669 |
pkcs11_id
|
|
670 |
)) != CKR_OK |
|
671 |
) { |
|
672 |
msg (M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
673 |
goto cleanup; |
|
674 |
}
|
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
675 |
}
|
676 |
||
677 |
if ( |
|
678 |
(rv = pkcs11h_certificate_create ( |
|
679 |
certificate_id, |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
680 |
NULL, |
681 |
PKCS11H_PROMPT_MASK_ALLOW_ALL, |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
682 |
PKCS11H_PIN_CACHE_INFINITE, |
683 |
&certificate |
|
684 |
)) != CKR_OK |
|
685 |
) { |
|
686 |
msg (M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
687 |
goto cleanup; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
688 |
}
|
689 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
690 |
if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL ) { |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
691 |
msg (M_WARN, "PKCS#11: Cannot initialize openssl session"); |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
692 |
goto cleanup; |
693 |
}
|
|
694 |
||
695 |
/*
|
|
696 |
* Will be released by openssl_session
|
|
697 |
*/
|
|
698 |
certificate = NULL; |
|
699 |
||
700 |
if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL) { |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
701 |
msg (M_WARN, "PKCS#11: Unable get rsa object"); |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
702 |
goto cleanup; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
703 |
}
|
704 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
705 |
if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) { |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
706 |
msg (M_WARN, "PKCS#11: Unable get certificate object"); |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
707 |
goto cleanup; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
708 |
}
|
709 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
710 |
if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)) { |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
711 |
msg (M_WARN, "PKCS#11: Cannot set private key for openssl"); |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
712 |
goto cleanup; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
713 |
}
|
714 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
715 |
if (!SSL_CTX_use_certificate (ssl_ctx, x509)) { |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
716 |
msg (M_WARN, "PKCS#11: Cannot set certificate for openssl"); |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
717 |
goto cleanup; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
718 |
}
|
719 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
720 |
ok = true; |
721 |
||
722 |
cleanup: |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
723 |
/*
|
724 |
* openssl objects have reference
|
|
725 |
* count, so release them
|
|
726 |
*/
|
|
727 |
||
728 |
if (x509 != NULL) { |
|
729 |
X509_free (x509); |
|
730 |
x509 = NULL; |
|
731 |
}
|
|
732 |
||
733 |
if (rsa != NULL) { |
|
734 |
RSA_free (rsa); |
|
735 |
rsa = NULL; |
|
736 |
}
|
|
737 |
||
738 |
if (certificate != NULL) { |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
739 |
pkcs11h_certificate_freeCertificate (certificate); |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
740 |
certificate = NULL; |
741 |
}
|
|
742 |
||
743 |
if (certificate_id != NULL) { |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
744 |
pkcs11h_certificate_freeCertificateId (certificate_id); |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
745 |
certificate_id = NULL; |
746 |
}
|
|
747 |
||
748 |
if (openssl_session != NULL) { |
|
749 |
pkcs11h_openssl_freeSession (openssl_session); |
|
750 |
openssl_session = NULL; |
|
751 |
}
|
|
752 |
||
753 |
dmsg ( |
|
754 |
D_PKCS11_DEBUG, |
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
755 |
"PKCS#11: SSL_CTX_use_pkcs11 - return ok=%d, rv=%ld", |
756 |
ok ? 1 : 0, |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
757 |
rv
|
758 |
);
|
|
759 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
760 |
return ok ? 1 : 0; |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
761 |
}
|
762 |
||
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
763 |
static
|
764 |
bool
|
|
765 |
_pkcs11_openvpn_show_pkcs11_ids_pin_prompt ( |
|
766 |
void * const global_data, |
|
767 |
void * const user_data, |
|
768 |
const pkcs11h_token_id_t token, |
|
769 |
const unsigned retry, |
|
770 |
char * const pin, |
|
771 |
const size_t pin_max |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
772 |
) { |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
773 |
struct gc_arena gc = gc_new (); |
774 |
struct buffer pass_prompt = alloc_buf_gc (128, &gc); |
|
775 |
||
776 |
(void)global_data; |
|
777 |
(void)user_data; |
|
778 |
(void)retry; |
|
779 |
||
780 |
ASSERT (token!=NULL); |
|
781 |
||
782 |
buf_printf (&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display); |
|
783 |
||
784 |
if (!get_console_input (BSTR (&pass_prompt), false, pin, pin_max)) { |
|
785 |
msg (M_FATAL, "Cannot read password from stdin"); |
|
786 |
}
|
|
787 |
||
788 |
gc_free (&gc); |
|
789 |
||
790 |
if (!strcmp (pin, "cancel")) { |
|
791 |
return FALSE; |
|
792 |
}
|
|
793 |
else { |
|
794 |
return TRUE; |
|
795 |
}
|
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
796 |
}
|
797 |
||
798 |
void
|
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
799 |
show_pkcs11_ids ( |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
800 |
const char * const provider, |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
801 |
bool cert_private |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
802 |
) { |
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
803 |
pkcs11h_certificate_id_list_t user_certificates = NULL; |
804 |
pkcs11h_certificate_id_list_t current = NULL; |
|
805 |
CK_RV rv = CKR_FUNCTION_FAILED; |
|
806 |
||
807 |
if ((rv = pkcs11h_initialize ()) != CKR_OK) { |
|
808 |
msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
809 |
goto cleanup; |
|
810 |
}
|
|
811 |
||
812 |
if ((rv = pkcs11h_setLogHook (_pkcs11_openvpn_log, NULL)) != CKR_OK) { |
|
813 |
msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
814 |
goto cleanup; |
|
815 |
}
|
|
816 |
||
817 |
pkcs11h_setLogLevel (_pkcs11_msg_openvpn2pkcs11 (get_debug_level ())); |
|
818 |
||
819 |
if ((rv = pkcs11h_setProtectedAuthentication (TRUE)) != CKR_OK) { |
|
820 |
msg (M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
821 |
goto cleanup; |
|
822 |
}
|
|
823 |
||
824 |
if ((rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK) { |
|
825 |
msg (M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
826 |
goto cleanup; |
|
827 |
}
|
|
828 |
||
829 |
if ( |
|
830 |
(rv = pkcs11h_addProvider ( |
|
831 |
provider, |
|
832 |
provider, |
|
833 |
TRUE, |
|
834 |
0, |
|
835 |
FALSE, |
|
836 |
0, |
|
837 |
cert_private ? TRUE : FALSE |
|
838 |
)) != CKR_OK |
|
839 |
) { |
|
840 |
msg (M_FATAL, "PKCS#11: Cannot add provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv)); |
|
841 |
goto cleanup; |
|
842 |
}
|
|
843 |
||
844 |
if ( |
|
845 |
(rv = pkcs11h_certificate_enumCertificateIds ( |
|
846 |
PKCS11H_ENUM_METHOD_CACHE_EXIST, |
|
847 |
NULL, |
|
848 |
PKCS11H_PROMPT_MASK_ALLOW_ALL, |
|
849 |
NULL, |
|
850 |
&user_certificates |
|
851 |
)) != CKR_OK |
|
852 |
) { |
|
853 |
msg (M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
854 |
goto cleanup; |
|
855 |
}
|
|
856 |
||
857 |
msg ( |
|
858 |
M_INFO|M_NOPREFIX|M_NOLF, |
|
859 |
(
|
|
860 |
"\n" |
|
861 |
"The following objects are available for use.\n" |
|
862 |
"Each object shown below may be used as parameter to\n" |
|
863 |
"--pkcs11-id option please remember to use single quote mark.\n" |
|
864 |
)
|
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
865 |
);
|
1.1.8
by Chuck Short
Import upstream version 2.1~rc7 |
866 |
for (current = user_certificates;current != NULL; current = current->next) { |
867 |
pkcs11h_certificate_t certificate = NULL; |
|
868 |
X509 *x509 = NULL; |
|
869 |
BIO *bio = NULL; |
|
870 |
char dn[1024] = {0}; |
|
871 |
char serial[1024] = {0}; |
|
872 |
char *ser = NULL; |
|
873 |
size_t ser_len = 0; |
|
874 |
int n; |
|
875 |
||
876 |
if ( |
|
877 |
(rv = pkcs11h_certificate_serializeCertificateId ( |
|
878 |
NULL, |
|
879 |
&ser_len, |
|
880 |
current->certificate_id |
|
881 |
)) != CKR_OK |
|
882 |
) { |
|
883 |
msg (M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
884 |
goto cleanup1; |
|
885 |
}
|
|
886 |
||
887 |
if ( |
|
888 |
rv == CKR_OK && |
|
889 |
(ser = (char *)malloc (ser_len)) == NULL |
|
890 |
) { |
|
891 |
msg (M_FATAL, "PKCS#11: Cannot allocate memory"); |
|
892 |
goto cleanup1; |
|
893 |
}
|
|
894 |
||
895 |
if ( |
|
896 |
(rv = pkcs11h_certificate_serializeCertificateId ( |
|
897 |
ser, |
|
898 |
&ser_len, |
|
899 |
current->certificate_id |
|
900 |
)) != CKR_OK |
|
901 |
) { |
|
902 |
msg (M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
903 |
goto cleanup1; |
|
904 |
}
|
|
905 |
||
906 |
if ( |
|
907 |
(rv = pkcs11h_certificate_create ( |
|
908 |
current->certificate_id, |
|
909 |
NULL, |
|
910 |
PKCS11H_PROMPT_MASK_ALLOW_ALL, |
|
911 |
PKCS11H_PIN_CACHE_INFINITE, |
|
912 |
&certificate |
|
913 |
))
|
|
914 |
) { |
|
915 |
msg (M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage (rv)); |
|
916 |
goto cleanup1; |
|
917 |
}
|
|
918 |
||
919 |
if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL) { |
|
920 |
msg (M_FATAL, "PKCS#11: Cannot get X509"); |
|
921 |
goto cleanup1; |
|
922 |
}
|
|
923 |
||
924 |
X509_NAME_oneline ( |
|
925 |
X509_get_subject_name (x509), |
|
926 |
dn, |
|
927 |
sizeof (dn) |
|
928 |
);
|
|
929 |
||
930 |
if ((bio = BIO_new (BIO_s_mem ())) == NULL) { |
|
931 |
msg (M_FATAL, "PKCS#11: Cannot create BIO"); |
|
932 |
goto cleanup1; |
|
933 |
}
|
|
934 |
||
935 |
i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509)); |
|
936 |
n = BIO_read (bio, serial, sizeof (serial)-1); |
|
937 |
if (n<0) { |
|
938 |
serial[0] = '\x0'; |
|
939 |
}
|
|
940 |
else { |
|
941 |
serial[n] = 0; |
|
942 |
}
|
|
943 |
||
944 |
msg ( |
|
945 |
M_INFO|M_NOPREFIX|M_NOLF, |
|
946 |
(
|
|
947 |
"\n" |
|
948 |
"Certificate\n" |
|
949 |
" DN: %s\n" |
|
950 |
" Serial: %s\n" |
|
951 |
" Serialized id: %s\n" |
|
952 |
),
|
|
953 |
dn, |
|
954 |
serial, |
|
955 |
ser
|
|
956 |
);
|
|
957 |
||
958 |
cleanup1: |
|
959 |
if (x509 != NULL) { |
|
960 |
X509_free (x509); |
|
961 |
x509 = NULL; |
|
962 |
}
|
|
963 |
||
964 |
if (certificate != NULL) { |
|
965 |
pkcs11h_certificate_freeCertificate (certificate); |
|
966 |
certificate = NULL; |
|
967 |
}
|
|
968 |
||
969 |
if (ser != NULL) { |
|
970 |
free (ser); |
|
971 |
ser = NULL; |
|
972 |
}
|
|
973 |
}
|
|
974 |
||
975 |
cleanup: |
|
976 |
if (user_certificates != NULL) { |
|
977 |
pkcs11h_certificate_freeCertificateIdList (user_certificates); |
|
978 |
user_certificates = NULL; |
|
979 |
}
|
|
980 |
||
981 |
pkcs11h_terminate (); |
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
982 |
}
|
983 |
||
984 |
#else
|
|
1.3.6
by Alberto Gonzalez Iniesta
Import upstream version 2.2.0 |
985 |
#ifdef _MSC_VER /* Dummy function needed to avoid empty file compiler warning in Microsoft VC */ |
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
986 |
static void dummy (void) {} |
1.3.6
by Alberto Gonzalez Iniesta
Import upstream version 2.2.0 |
987 |
#endif
|
1.1.7
by Alberto Gonzalez Iniesta
Import upstream version 2.1~rc4 |
988 |
#endif /* ENABLE_PKCS11 */ |