Skip to content

Latest commit

 

History

History
2141 lines (1840 loc) · 53.7 KB

openssl.c

File metadata and controls

2141 lines (1840 loc) · 53.7 KB
 
1
2
3
/*
* OpenConnect (SSL + DTLS) VPN client
*
Jan 26, 2015
Jan 26, 2015
4
* Copyright © 2008-2015 Intel Corporation.
5
6
7
8
9
10
11
12
13
14
15
16
17
*
* Author: David Woodhouse <dwmw2@infradead.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
Jul 1, 2014
Jul 1, 2014
18
19
#include <config.h>
May 29, 2012
May 29, 2012
20
#include <errno.h>
Sep 19, 2013
Sep 19, 2013
21
#include <string.h>
Jun 11, 2012
Jun 11, 2012
22
#include <sys/types.h>
Jun 1, 2012
Jun 1, 2012
23
#include <ctype.h>
May 29, 2012
May 29, 2012
24
Feb 6, 2014
Feb 6, 2014
25
26
#include "openconnect-internal.h"
Mar 30, 2020
Mar 30, 2020
27
#include <openssl/crypto.h>
May 29, 2012
May 29, 2012
28
29
30
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/engine.h>
31
#include <openssl/evp.h>
May 29, 2012
May 29, 2012
32
#include <openssl/rand.h>
May 29, 2012
May 29, 2012
33
34
35
36
#include <openssl/pkcs12.h>
#include <openssl/x509v3.h>
#include <openssl/x509.h>
#include <openssl/bio.h>
Feb 16, 2015
Feb 16, 2015
37
38
#include <openssl/ui.h>
#include <openssl/rsa.h>
Aug 31, 2016
Aug 31, 2016
40
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dec 2, 2015
Dec 2, 2015
41
#define X509_up_ref(x) CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509)
Aug 19, 2016
Aug 19, 2016
42
#define X509_get0_notAfter(x) X509_get_notAfter(x)
Jul 8, 2016
Jul 8, 2016
43
44
45
46
47
#define EVP_MD_CTX_new EVP_MD_CTX_create
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
#define X509_STORE_CTX_get0_chain(ctx) ((ctx)->chain)
#define X509_STORE_CTX_get0_untrusted(ctx) ((ctx)->untrusted)
#define X509_STORE_CTX_get0_cert(ctx) ((ctx)->cert)
Jul 25, 2016
Jul 25, 2016
48
49
50
typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer,
X509_STORE_CTX *ctx, X509 *x);
#define X509_STORE_CTX_get_get_issuer(ctx) ((ctx)->get_issuer)
Jul 8, 2016
Jul 8, 2016
51
52
#endif
Mar 27, 2020
Mar 27, 2020
53
54
55
56
57
static char tls_library_version[32] = "";
const char *openconnect_get_tls_library_version()
{
if (!*tls_library_version) {
Mar 30, 2020
Mar 30, 2020
58
59
strncpy(tls_library_version, SSLeay_version(SSLEAY_VERSION), sizeof(tls_library_version));
tls_library_version[sizeof(tls_library_version)-1]='\0';
Mar 27, 2020
Mar 27, 2020
60
61
62
63
}
return tls_library_version;
}
64
65
int openconnect_sha1(unsigned char *result, void *data, int len)
{
Jul 8, 2016
Jul 8, 2016
66
67
68
69
EVP_MD_CTX *c = EVP_MD_CTX_new();
if (!c)
return -ENOMEM;
Mar 10, 2013
Mar 10, 2013
71
EVP_Digest(data, len, result, NULL, EVP_sha1(), NULL);
Jul 8, 2016
Jul 8, 2016
72
EVP_MD_CTX_free(c);
Mar 10, 2013
Mar 10, 2013
74
return 0;
May 29, 2012
May 29, 2012
76
Dec 13, 2016
Dec 13, 2016
77
78
79
80
81
82
83
84
85
86
87
88
89
int openconnect_sha256(unsigned char *result, void *data, int len)
{
EVP_MD_CTX *c = EVP_MD_CTX_new();
if (!c)
return -ENOMEM;
EVP_Digest(data, len, result, NULL, EVP_sha256(), NULL);
EVP_MD_CTX_free(c);
return 0;
}
Jun 19, 2014
Jun 19, 2014
90
91
int openconnect_md5(unsigned char *result, void *data, int len)
{
Jul 8, 2016
Jul 8, 2016
92
93
94
95
EVP_MD_CTX *c = EVP_MD_CTX_new();
if (!c)
return -ENOMEM;
Jun 19, 2014
Jun 19, 2014
96
97
EVP_Digest(data, len, result, NULL, EVP_md5(), NULL);
Jul 8, 2016
Jul 8, 2016
98
EVP_MD_CTX_free(c);
Jun 19, 2014
Jun 19, 2014
99
100
101
102
return 0;
}
Nov 3, 2014
Nov 3, 2014
103
104
int openconnect_get_peer_cert_DER(struct openconnect_info *vpninfo,
unsigned char **buf)
May 29, 2012
May 29, 2012
105
106
107
108
109
{
BIO *bp = BIO_new(BIO_s_mem());
BUF_MEM *certinfo;
size_t l;
Nov 3, 2014
Nov 3, 2014
110
if (!i2d_X509_bio(bp, vpninfo->peer_cert)) {
May 29, 2012
May 29, 2012
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
BIO_free(bp);
return -EIO;
}
BIO_get_mem_ptr(bp, &certinfo);
l = certinfo->length;
*buf = malloc(l);
if (!*buf) {
BIO_free(bp);
return -ENOMEM;
}
memcpy(*buf, certinfo->data, l);
BIO_free(bp);
return l;
}
May 29, 2012
May 29, 2012
126
127
128
129
130
131
132
int openconnect_random(void *bytes, int len)
{
if (RAND_bytes(bytes, len) != 1)
return -EIO;
return 0;
}
May 29, 2012
May 29, 2012
133
134
135
136
/* Helper functions for reading/writing lines over SSL.
We could use cURL for the HTTP stuff, but it's overkill */
Sep 10, 2016
Sep 10, 2016
137
static int _openconnect_openssl_write(SSL *ssl, int fd, struct openconnect_info *vpninfo, char *buf, size_t len)
May 29, 2012
May 29, 2012
138
139
140
141
{
size_t orig_len = len;
while (len) {
Sep 10, 2016
Sep 10, 2016
142
int done = SSL_write(ssl, buf, len);
May 29, 2012
May 29, 2012
143
144
145
146
if (done > 0)
len -= done;
else {
Sep 10, 2016
Sep 10, 2016
147
int err = SSL_get_error(ssl, done);
May 29, 2012
May 29, 2012
148
fd_set wr_set, rd_set;
Sep 10, 2016
Sep 10, 2016
149
int maxfd = fd;
May 29, 2012
May 29, 2012
150
151
152
FD_ZERO(&wr_set);
FD_ZERO(&rd_set);
Mar 10, 2013
Mar 10, 2013
153
May 29, 2012
May 29, 2012
154
if (err == SSL_ERROR_WANT_READ)
Sep 10, 2016
Sep 10, 2016
155
FD_SET(fd, &rd_set);
May 29, 2012
May 29, 2012
156
else if (err == SSL_ERROR_WANT_WRITE)
Sep 10, 2016
Sep 10, 2016
157
FD_SET(fd, &wr_set);
May 29, 2012
May 29, 2012
158
else {
Oct 27, 2012
Oct 27, 2012
159
vpn_progress(vpninfo, PRG_ERR, _("Failed to write to SSL socket\n"));
May 29, 2012
May 29, 2012
160
161
162
openconnect_report_ssl_errors(vpninfo);
return -EIO;
}
Jan 15, 2014
Jan 15, 2014
163
cmd_fd_set(vpninfo, &rd_set, &maxfd);
May 29, 2012
May 29, 2012
164
select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
Jan 15, 2014
Jan 15, 2014
165
if (is_cancel_pending(vpninfo, &rd_set)) {
May 29, 2012
May 29, 2012
166
167
168
169
170
171
172
173
vpn_progress(vpninfo, PRG_ERR, _("SSL write cancelled\n"));
return -EINTR;
}
}
}
return orig_len;
}
Sep 10, 2016
Sep 10, 2016
174
static int openconnect_openssl_write(struct openconnect_info *vpninfo, char *buf, size_t len)
May 29, 2012
May 29, 2012
175
{
Sep 10, 2016
Sep 10, 2016
176
177
return _openconnect_openssl_write(vpninfo->https_ssl, vpninfo->ssl_fd, vpninfo, buf, len);
}
May 29, 2012
May 29, 2012
178
Sep 10, 2016
Sep 10, 2016
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
int openconnect_dtls_write(struct openconnect_info *vpninfo, void *buf, size_t len)
{
return _openconnect_openssl_write(vpninfo->dtls_ssl, vpninfo->dtls_fd, vpninfo, buf, len);
}
/* set ms to zero for no timeout */
static int _openconnect_openssl_read(SSL *ssl, int fd, struct openconnect_info *vpninfo, char *buf, size_t len, unsigned ms)
{
int done, ret;
struct timeval timeout, *tv = NULL;
if (ms) {
timeout.tv_sec = ms/1000;
timeout.tv_usec = (ms%1000)*1000;
tv = &timeout;
}
while ((done = SSL_read(ssl, buf, len)) == -1) {
int err = SSL_get_error(ssl, done);
May 29, 2012
May 29, 2012
198
fd_set wr_set, rd_set;
Sep 10, 2016
Sep 10, 2016
199
int maxfd = fd;
May 29, 2012
May 29, 2012
200
201
202
FD_ZERO(&wr_set);
FD_ZERO(&rd_set);
Mar 10, 2013
Mar 10, 2013
203
May 29, 2012
May 29, 2012
204
if (err == SSL_ERROR_WANT_READ)
Sep 10, 2016
Sep 10, 2016
205
FD_SET(fd, &rd_set);
May 29, 2012
May 29, 2012
206
else if (err == SSL_ERROR_WANT_WRITE)
Sep 10, 2016
Sep 10, 2016
207
FD_SET(fd, &wr_set);
May 29, 2012
May 29, 2012
208
else {
Nov 5, 2012
Nov 5, 2012
209
vpn_progress(vpninfo, PRG_ERR, _("Failed to read from SSL socket\n"));
May 29, 2012
May 29, 2012
210
211
212
openconnect_report_ssl_errors(vpninfo);
return -EIO;
}
Jan 15, 2014
Jan 15, 2014
213
cmd_fd_set(vpninfo, &rd_set, &maxfd);
Sep 10, 2016
Sep 10, 2016
214
ret = select(maxfd + 1, &rd_set, &wr_set, NULL, tv);
Jan 15, 2014
Jan 15, 2014
215
if (is_cancel_pending(vpninfo, &rd_set)) {
May 29, 2012
May 29, 2012
216
217
218
vpn_progress(vpninfo, PRG_ERR, _("SSL read cancelled\n"));
return -EINTR;
}
Sep 10, 2016
Sep 10, 2016
219
220
221
222
if (ret == 0) {
return -ETIMEDOUT;
}
May 29, 2012
May 29, 2012
223
224
225
226
}
return done;
}
Sep 10, 2016
Sep 10, 2016
227
228
229
230
231
232
233
234
235
236
static int openconnect_openssl_read(struct openconnect_info *vpninfo, char *buf, size_t len)
{
return _openconnect_openssl_read(vpninfo->https_ssl, vpninfo->ssl_fd, vpninfo, buf, len, 0);
}
int openconnect_dtls_read(struct openconnect_info *vpninfo, void *buf, size_t len, unsigned ms)
{
return _openconnect_openssl_read(vpninfo->dtls_ssl, vpninfo->dtls_fd, vpninfo, buf, len, ms);
}
Jun 18, 2014
Jun 18, 2014
237
static int openconnect_openssl_gets(struct openconnect_info *vpninfo, char *buf, size_t len)
May 29, 2012
May 29, 2012
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
{
int i = 0;
int ret;
if (len < 2)
return -EINVAL;
while (1) {
ret = SSL_read(vpninfo->https_ssl, buf + i, 1);
if (ret == 1) {
if (buf[i] == '\n') {
buf[i] = 0;
if (i && buf[i-1] == '\r') {
buf[i-1] = 0;
i--;
}
return i;
}
i++;
if (i >= len - 1) {
buf[i] = 0;
return i;
}
} else {
fd_set rd_set, wr_set;
int maxfd = vpninfo->ssl_fd;
Mar 10, 2013
Mar 10, 2013
265
May 29, 2012
May 29, 2012
266
267
FD_ZERO(&rd_set);
FD_ZERO(&wr_set);
Mar 10, 2013
Mar 10, 2013
268
May 29, 2012
May 29, 2012
269
270
271
272
273
274
275
276
277
278
279
ret = SSL_get_error(vpninfo->https_ssl, ret);
if (ret == SSL_ERROR_WANT_READ)
FD_SET(vpninfo->ssl_fd, &rd_set);
else if (ret == SSL_ERROR_WANT_WRITE)
FD_SET(vpninfo->ssl_fd, &wr_set);
else {
vpn_progress(vpninfo, PRG_ERR, _("Failed to read from SSL socket\n"));
openconnect_report_ssl_errors(vpninfo);
ret = -EIO;
break;
}
Jan 15, 2014
Jan 15, 2014
280
cmd_fd_set(vpninfo, &rd_set, &maxfd);
May 29, 2012
May 29, 2012
281
select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
Jan 15, 2014
Jan 15, 2014
282
if (is_cancel_pending(vpninfo, &rd_set)) {
May 29, 2012
May 29, 2012
283
284
285
286
287
288
289
290
291
292
vpn_progress(vpninfo, PRG_ERR, _("SSL read cancelled\n"));
ret = -EINTR;
break;
}
}
}
buf[i] = 0;
return i ?: ret;
}
Jan 26, 2015
Jan 26, 2015
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
int ssl_nonblock_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
{
int len, ret;
len = SSL_read(vpninfo->https_ssl, buf, maxlen);
if (len > 0)
return len;
ret = SSL_get_error(vpninfo->https_ssl, len);
if (ret == SSL_ERROR_SYSCALL || ret == SSL_ERROR_ZERO_RETURN) {
vpn_progress(vpninfo, PRG_ERR,
_("SSL read error %d (server probably closed connection); reconnecting.\n"),
ret);
return -EIO;
}
return 0;
}
int ssl_nonblock_write(struct openconnect_info *vpninfo, void *buf, int buflen)
{
int ret;
ret = SSL_write(vpninfo->https_ssl, buf, buflen);
if (ret > 0)
return ret;
ret = SSL_get_error(vpninfo->https_ssl, ret);
switch (ret) {
case SSL_ERROR_WANT_WRITE:
/* Waiting for the socket to become writable -- it's
probably stalled, and/or the buffers are full */
monitor_write_fd(vpninfo, ssl);
case SSL_ERROR_WANT_READ:
return 0;
default:
vpn_progress(vpninfo, PRG_ERR, _("SSL_write failed: %d\n"), ret);
openconnect_report_ssl_errors(vpninfo);
return -1;
}
}
Jun 7, 2012
Jun 7, 2012
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/* UI handling. All this just to handle the PIN callback from the TPM ENGINE,
and turn it into a call to our ->process_auth_form function */
struct ui_data {
struct openconnect_info *vpninfo;
struct oc_form_opt **last_opt;
struct oc_auth_form form;
};
struct ui_form_opt {
struct oc_form_opt opt;
UI_STRING *uis;
};
Oct 23, 2015
Oct 23, 2015
349
#ifdef HAVE_ENGINE
Jun 7, 2012
Jun 7, 2012
350
351
static int ui_open(UI *ui)
{
Oct 12, 2018
Oct 12, 2018
352
struct openconnect_info *vpninfo = UI_get0_user_data(ui);
Jun 7, 2012
Jun 7, 2012
353
354
355
356
struct ui_data *ui_data;
if (!vpninfo || !vpninfo->process_auth_form)
return 0;
Mar 10, 2013
Mar 10, 2013
357
Jun 7, 2012
Jun 7, 2012
358
359
360
361
362
363
364
ui_data = malloc(sizeof(*ui_data));
if (!ui_data)
return 0;
memset(ui_data, 0, sizeof(*ui_data));
ui_data->last_opt = &ui_data->form.opts;
ui_data->vpninfo = vpninfo;
Jun 13, 2012
Jun 13, 2012
365
ui_data->form.auth_id = (char *)"openssl_ui";
Oct 12, 2018
Oct 12, 2018
366
Jun 7, 2012
Jun 7, 2012
367
368
369
370
371
372
373
374
375
376
UI_add_user_data(ui, ui_data);
return 1;
}
static int ui_write(UI *ui, UI_STRING *uis)
{
struct ui_data *ui_data = UI_get0_user_data(ui);
struct ui_form_opt *opt;
Mar 10, 2013
Mar 10, 2013
377
switch (UI_get_string_type(uis)) {
Jun 7, 2012
Jun 7, 2012
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
case UIT_ERROR:
ui_data->form.error = (char *)UI_get0_output_string(uis);
break;
case UIT_INFO:
ui_data->form.message = (char *)UI_get0_output_string(uis);
break;
case UIT_PROMPT:
opt = malloc(sizeof(*opt));
if (!opt)
return 1;
memset(opt, 0, sizeof(*opt));
opt->uis = uis;
opt->opt.label = opt->opt.name = (char *)UI_get0_output_string(uis);
if (UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO)
opt->opt.type = OC_FORM_OPT_TEXT;
else
opt->opt.type = OC_FORM_OPT_PASSWORD;
*(ui_data->last_opt) = &opt->opt;
ui_data->last_opt = &opt->opt.next;
break;
default:
Oct 30, 2014
Oct 30, 2014
400
401
402
vpn_progress(ui_data->vpninfo, PRG_ERR,
_("Unhandled SSL UI request type %d\n"),
UI_get_string_type(uis));
Jun 7, 2012
Jun 7, 2012
403
404
405
406
407
408
409
410
411
412
413
414
return 0;
}
return 1;
}
static int ui_flush(UI *ui)
{
struct ui_data *ui_data = UI_get0_user_data(ui);
struct openconnect_info *vpninfo = ui_data->vpninfo;
struct ui_form_opt *opt;
int ret;
Jan 15, 2014
Jan 15, 2014
415
ret = process_auth_form(vpninfo, &ui_data->form);
Jun 7, 2012
Jun 7, 2012
416
417
418
419
420
if (ret)
return 0;
for (opt = (struct ui_form_opt *)ui_data->form.opts; opt;
opt = (struct ui_form_opt *)opt->opt.next) {
Oct 12, 2014
Oct 12, 2014
421
422
if (opt->opt._value && opt->uis)
UI_set_result(ui, opt->uis, opt->opt._value);
Jun 7, 2012
Jun 7, 2012
423
424
425
426
427
428
429
430
431
432
433
434
}
return 1;
}
static int ui_close(UI *ui)
{
struct ui_data *ui_data = UI_get0_user_data(ui);
struct ui_form_opt *opt, *next_opt;
opt = (struct ui_form_opt *)ui_data->form.opts;
while (opt) {
next_opt = (struct ui_form_opt *)opt->opt.next;
Oct 12, 2014
Oct 12, 2014
435
436
if (opt->opt._value)
free(opt->opt._value);
Jun 7, 2012
Jun 7, 2012
437
438
439
440
441
442
443
444
445
free(opt);
opt = next_opt;
}
free(ui_data);
UI_add_user_data(ui, NULL);
return 1;
}
Oct 12, 2018
Oct 12, 2018
446
static UI_METHOD *create_openssl_ui(void)
Jun 7, 2012
Jun 7, 2012
447
448
449
450
451
452
453
454
455
456
457
{
UI_METHOD *ui_method = UI_create_method((char *)"AnyConnect VPN UI");
/* Set up a UI method of our own for password/passphrase requests */
UI_method_set_opener(ui_method, ui_open);
UI_method_set_writer(ui_method, ui_write);
UI_method_set_flusher(ui_method, ui_flush);
UI_method_set_closer(ui_method, ui_close);
return ui_method;
}
Oct 23, 2015
Oct 23, 2015
458
#endif
Jun 7, 2012
Jun 7, 2012
459
May 29, 2012
May 29, 2012
460
461
462
static int pem_pw_cb(char *buf, int len, int w, void *v)
{
struct openconnect_info *vpninfo = v;
Jun 5, 2012
Jun 5, 2012
463
464
char *pass = NULL;
int plen;
May 29, 2012
May 29, 2012
465
Jun 5, 2012
Jun 5, 2012
466
467
468
if (vpninfo->cert_password) {
pass = vpninfo->cert_password;
vpninfo->cert_password = NULL;
Jun 13, 2012
Jun 13, 2012
469
470
} else if (request_passphrase(vpninfo, "openconnect_pem",
&pass, _("Enter PEM pass phrase:")))
Jun 5, 2012
Jun 5, 2012
471
472
473
return -1;
plen = strlen(pass);
May 29, 2012
May 29, 2012
474
Jun 5, 2012
Jun 5, 2012
475
if (len <= plen) {
May 29, 2012
May 29, 2012
476
vpn_progress(vpninfo, PRG_ERR,
Jun 5, 2012
Jun 5, 2012
477
478
_("PEM password too long (%d >= %d)\n"),
plen, len);
Dec 21, 2018
Dec 21, 2018
479
free_pass(&pass);
May 29, 2012
May 29, 2012
480
481
return -1;
}
Jun 5, 2012
Jun 5, 2012
482
483
memcpy(buf, pass, plen+1);
Dec 21, 2018
Dec 21, 2018
484
free_pass(&pass);
Jun 5, 2012
Jun 5, 2012
485
return plen;
May 29, 2012
May 29, 2012
486
487
}
Jul 31, 2014
Jul 31, 2014
488
489
490
491
492
493
static int install_extra_certs(struct openconnect_info *vpninfo, const char *source,
STACK_OF(X509) *ca)
{
X509 *cert = vpninfo->cert_x509;
int i;
Aug 27, 2016
Aug 27, 2016
494
495
if (!cert)
return -EINVAL;
Jul 31, 2014
Jul 31, 2014
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
next:
for (i = 0; i < sk_X509_num(ca); i++) {
X509 *cert2 = sk_X509_value(ca, i);
if (X509_check_issued(cert2, cert) == X509_V_OK) {
char buf[200];
if (cert2 == cert)
break;
if (X509_check_issued(cert2, cert2) == X509_V_OK)
break;
X509_NAME_oneline(X509_get_subject_name(cert2),
buf, sizeof(buf));
vpn_progress(vpninfo, PRG_DEBUG,
_("Extra cert from %s: '%s'\n"), source, buf);
Dec 2, 2015
Dec 2, 2015
511
X509_up_ref(cert2);
Jul 31, 2014
Jul 31, 2014
512
513
514
515
516
517
518
519
520
521
SSL_CTX_add_extra_chain_cert(vpninfo->https_ctx, cert2);
cert = cert2;
goto next;
}
}
sk_X509_pop_free(ca, X509_free);
return 0;
}
May 29, 2012
May 29, 2012
522
523
524
525
526
527
static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12)
{
EVP_PKEY *pkey = NULL;
X509 *cert = NULL;
STACK_OF(X509) *ca;
int ret = 0;
Jun 4, 2012
Jun 4, 2012
528
char *pass;
May 29, 2012
May 29, 2012
529
Jun 4, 2012
Jun 4, 2012
530
531
pass = vpninfo->cert_password;
vpninfo->cert_password = NULL;
May 29, 2012
May 29, 2012
532
533
534
535
536
537
retrypass:
/* We do this every time round the loop, to work around a bug in
OpenSSL < 1.0.0-beta2 -- where the stack at *ca will be freed
when PKCS12_parse() returns an error, but *ca is left pointing
to the freed memory. */
ca = NULL;
Jun 4, 2012
Jun 4, 2012
538
if (!PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
May 29, 2012
May 29, 2012
539
540
541
542
543
unsigned long err = ERR_peek_error();
if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 &&
ERR_GET_FUNC(err) == PKCS12_F_PKCS12_PARSE &&
ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) {
Mar 31, 2014
Mar 31, 2014
544
545
546
if (pass)
vpn_progress(vpninfo, PRG_ERR,
_("Failed to decrypt PKCS#12 certificate file\n"));
Dec 21, 2018
Dec 21, 2018
547
free_pass(&pass);
Mar 31, 2014
Mar 31, 2014
548
549
550
551
552
553
if (request_passphrase(vpninfo, "openconnect_pkcs12", &pass,
_("Enter PKCS#12 pass phrase:")) < 0) {
PKCS12_free(p12);
return -EINVAL;
}
May 29, 2012
May 29, 2012
554
555
556
goto retrypass;
}
Mar 31, 2014
Mar 31, 2014
557
558
openconnect_report_ssl_errors(vpninfo);
May 29, 2012
May 29, 2012
559
560
561
vpn_progress(vpninfo, PRG_ERR,
_("Parse PKCS#12 failed (see above errors)\n"));
PKCS12_free(p12);
Dec 21, 2018
Dec 21, 2018
562
free_pass(&pass);
May 29, 2012
May 29, 2012
563
564
return -EINVAL;
}
Dec 21, 2018
Dec 21, 2018
565
free_pass(&pass);
May 29, 2012
May 29, 2012
566
if (cert) {
Jun 11, 2012
Jun 11, 2012
567
char buf[200];
May 29, 2012
May 29, 2012
568
569
vpninfo->cert_x509 = cert;
SSL_CTX_use_certificate(vpninfo->https_ctx, cert);
Jun 11, 2012
Jun 11, 2012
570
571
572
X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
vpn_progress(vpninfo, PRG_INFO,
_("Using client certificate '%s'\n"), buf);
May 29, 2012
May 29, 2012
573
574
} else {
vpn_progress(vpninfo, PRG_ERR,
Aug 27, 2016
Aug 27, 2016
575
_("PKCS#12 contained no certificate!\n"));
May 29, 2012
May 29, 2012
576
577
578
579
ret = -EINVAL;
}
if (pkey) {
Oct 7, 2019
Oct 7, 2019
580
581
582
583
584
585
if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, pkey)) {
vpn_progress(vpninfo, PRG_ERR,
_("Loading private key failed\n"));
openconnect_report_ssl_errors(vpninfo);
ret = -EINVAL;
}
May 29, 2012
May 29, 2012
586
587
588
EVP_PKEY_free(pkey);
} else {
vpn_progress(vpninfo, PRG_ERR,
Aug 27, 2016
Aug 27, 2016
589
_("PKCS#12 contained no private key!\n"));
May 29, 2012
May 29, 2012
590
591
592
ret = -EINVAL;
}
Jul 31, 2014
Jul 31, 2014
593
594
if (ca)
install_extra_certs(vpninfo, _("PKCS#12"), ca);
May 29, 2012
May 29, 2012
595
596
597
598
599
600
PKCS12_free(p12);
return ret;
}
#ifdef HAVE_ENGINE
Sep 27, 2018
Sep 27, 2018
601
602
static int load_tpm_certificate(struct openconnect_info *vpninfo,
const char *engine)
May 29, 2012
May 29, 2012
603
604
605
{
ENGINE *e;
EVP_PKEY *key;
Jun 7, 2012
Jun 7, 2012
606
UI_METHOD *meth = NULL;
Jun 12, 2012
Jun 12, 2012
607
608
int ret = 0;
May 29, 2012
May 29, 2012
609
610
ENGINE_load_builtin_engines();
Sep 27, 2018
Sep 27, 2018
611
e = ENGINE_by_id(engine);
Oct 13, 2018
Oct 13, 2018
612
613
614
615
if (!e && !strcmp(engine, "tpm2")) {
ERR_clear_error();
e = ENGINE_by_id("tpm2tss");
}
May 29, 2012
May 29, 2012
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
if (!e) {
vpn_progress(vpninfo, PRG_ERR, _("Can't load TPM engine.\n"));
openconnect_report_ssl_errors(vpninfo);
return -EINVAL;
}
if (!ENGINE_init(e) || !ENGINE_set_default_RSA(e) ||
!ENGINE_set_default_RAND(e)) {
vpn_progress(vpninfo, PRG_ERR, _("Failed to init TPM engine\n"));
openconnect_report_ssl_errors(vpninfo);
ENGINE_free(e);
return -EINVAL;
}
if (vpninfo->cert_password) {
if (!ENGINE_ctrl_cmd(e, "PIN", strlen(vpninfo->cert_password),
vpninfo->cert_password, NULL, 0)) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to set TPM SRK password\n"));
openconnect_report_ssl_errors(vpninfo);
}
Dec 21, 2018
Dec 21, 2018
636
free_pass(&vpninfo->cert_password);
May 29, 2012
May 29, 2012
637
}
Oct 12, 2018
Oct 12, 2018
638
639
640
641
642
/* Provide our own UI method to handle the PIN callback. */
meth = create_openssl_ui();
key = ENGINE_load_private_key(e, vpninfo->sslkey, meth, vpninfo);
Jun 7, 2012
Jun 7, 2012
643
644
if (meth)
UI_destroy_method(meth);
May 29, 2012
May 29, 2012
645
646
647
648
if (!key) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to load TPM private key\n"));
openconnect_report_ssl_errors(vpninfo);
Jun 12, 2012
Jun 12, 2012
649
650
ret = -EINVAL;
goto out;
May 29, 2012
May 29, 2012
651
652
653
654
}
if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
vpn_progress(vpninfo, PRG_ERR, _("Add key from TPM failed\n"));
openconnect_report_ssl_errors(vpninfo);
Jun 12, 2012
Jun 12, 2012
655
ret = -EINVAL;
May 29, 2012
May 29, 2012
656
}
Jun 12, 2012
Jun 12, 2012
657
658
659
660
661
EVP_PKEY_free(key);
out:
ENGINE_finish(e);
ENGINE_free(e);
return ret;
May 29, 2012
May 29, 2012
662
663
}
#else
Sep 27, 2018
Sep 27, 2018
664
665
static int load_tpm_certificate(struct openconnect_info *vpninfo,
const char *engine)
May 29, 2012
May 29, 2012
666
667
668
669
670
671
672
{
vpn_progress(vpninfo, PRG_ERR,
_("This version of OpenConnect was built without TPM support\n"));
return -EINVAL;
}
#endif
Jul 31, 2014
Jul 31, 2014
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
/* This is a reimplementation of SSL_CTX_use_certificate_chain_file().
* We do this for three reasons:
*
* - Firstly, we have no way to obtain the primary X509 certificate
* after SSL_CTX_use_certificate_chain_file() has loaded it, and we
* need to inspect it to check for expiry and report its name etc.
* So in the past we've opened the cert file again and read the cert
* again in a reload_pem_cert() function which was a partial
* reimplementation anyway.
*
* - Secondly, on Windows, OpenSSL only partially handles UTF-8 filenames.
* Specifically, BIO_new_file() will convert UTF-8 to UTF-16 and attempt
* to use _wfopen() to open the file, but BIO_read_filename() will not.
* It is BIO_read_filename() which the SSL_CTX_*_file functions use, and
* thus they don't work with UTF-8 file names. This is filed as RT#3479:
* http://rt.openssl.org/Ticket/Display.html?id=3479
*
* - Finally, and least importantly, it does actually matter which supporting
* certs we offer on the wire because of RT#1942. Doing this for ourselves
* allows us to explicitly print the supporting certs that we're using,
* which may assist in diagnosing problems.
*/
static int load_cert_chain_file(struct openconnect_info *vpninfo)
May 29, 2012
May 29, 2012
696
{
Jul 31, 2014
Jul 31, 2014
697
BIO *b;
Aug 3, 2014
Aug 3, 2014
698
FILE *f = openconnect_fopen_utf8(vpninfo, vpninfo->cert, "rb");
Jul 31, 2014
Jul 31, 2014
699
STACK_OF(X509) *extra_certs = NULL;
Jun 11, 2012
Jun 11, 2012
700
char buf[200];
May 29, 2012
May 29, 2012
701
Jul 31, 2014
Jul 31, 2014
702
703
704
705
706
707
if (!f) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to open certificate file %s: %s\n"),
vpninfo->cert, strerror(errno));
return -ENOENT;
}
May 29, 2012
May 29, 2012
708
Jul 31, 2014
Jul 31, 2014
709
710
711
b = BIO_new_fp(f, 1);
if (!b) {
fclose(f);
May 29, 2012
May 29, 2012
712
713
err:
vpn_progress(vpninfo, PRG_ERR,
Jul 31, 2014
Jul 31, 2014
714
_("Loading certificate failed\n"));
May 29, 2012
May 29, 2012
715
716
717
718
openconnect_report_ssl_errors(vpninfo);
return -EIO;
}
vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, NULL, NULL);
Jul 31, 2014
Jul 31, 2014
719
720
if (!vpninfo->cert_x509) {
BIO_free(b);
May 29, 2012
May 29, 2012
721
goto err;
Jul 31, 2014
Jul 31, 2014
722
}
May 29, 2012
May 29, 2012
723
Jun 11, 2012
Jun 11, 2012
724
725
726
727
X509_NAME_oneline(X509_get_subject_name(vpninfo->cert_x509), buf, sizeof(buf));
vpn_progress(vpninfo, PRG_INFO,
_("Using client certificate '%s'\n"), buf);
Jul 31, 2014
Jul 31, 2014
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
if (!SSL_CTX_use_certificate(vpninfo->https_ctx, vpninfo->cert_x509)) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to install certificate in OpenSSL context\n"));
openconnect_report_ssl_errors(vpninfo);
BIO_free(b);
return -EIO;
}
while (1) {
X509 *x = PEM_read_bio_X509(b, NULL, NULL, NULL);
if (!x) {
unsigned long err = ERR_peek_last_error();
if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
ERR_clear_error();
else
goto err_extra;
break;
}
if (!extra_certs)
extra_certs = sk_X509_new_null();
if (!extra_certs) {
err_extra:
vpn_progress(vpninfo, PRG_ERR,
_("Failed to process all supporting certs. Trying anyway...\n"));
openconnect_report_ssl_errors(vpninfo);
X509_free(x);
/* It might work without... */
break;
}
if (!sk_X509_push(extra_certs, x))
goto err_extra;
}
BIO_free(b);
if (extra_certs)
install_extra_certs(vpninfo, _("PEM file"), extra_certs);
May 29, 2012
May 29, 2012
767
768
769
return 0;
}
Jun 15, 2012
Jun 15, 2012
770
771
772
#ifdef ANDROID_KEYSTORE
static BIO *BIO_from_keystore(struct openconnect_info *vpninfo, const char *item)
{
Jun 17, 2012
Jun 17, 2012
773
unsigned char *content;
Jun 15, 2012
Jun 15, 2012
774
775
776
777
778
779
780
781
782
783
BIO *b;
int len;
const char *p = item + 9;
/* Skip first two slashes if the user has given it as
keystore://foo ... */
if (*p == '/')
p++;
if (*p == '/')
p++;
Jun 17, 2012
Jun 17, 2012
784
785
786
len = keystore_fetch(p, &content);
if (len < 0) {
Jun 15, 2012
Jun 15, 2012
787
vpn_progress(vpninfo, PRG_ERR,
Jun 17, 2012
Jun 17, 2012
788
789
_("Failed to load item '%s' from keystore: %s\n"),
p, keystore_strerror(len));
Jun 15, 2012
Jun 15, 2012
790
791
792
793
794
795
return NULL;
}
if (!(b = BIO_new(BIO_s_mem())) || BIO_write(b, content, len) != len) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to create BIO for keystore item '%s'\n"),
p);
Jun 17, 2012
Jun 17, 2012
796
free(content);
Jun 15, 2012
Jun 15, 2012
797
798
799
BIO_free(b);
return NULL;
}
Jun 17, 2012
Jun 17, 2012
800
free(content);
Jun 15, 2012
Jun 15, 2012
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
return b;
}
#endif
static int is_pem_password_error(struct openconnect_info *vpninfo)
{
unsigned long err = ERR_peek_error();
openconnect_report_ssl_errors(vpninfo);
#ifndef EVP_F_EVP_DECRYPTFINAL_EX
#define EVP_F_EVP_DECRYPTFINAL_EX EVP_F_EVP_DECRYPTFINAL
#endif
/* If the user fat-fingered the passphrase, try again */
if (ERR_GET_LIB(err) == ERR_LIB_EVP &&
ERR_GET_FUNC(err) == EVP_F_EVP_DECRYPTFINAL_EX &&
ERR_GET_REASON(err) == EVP_R_BAD_DECRYPT) {
vpn_progress(vpninfo, PRG_ERR,
_("Loading private key failed (wrong passphrase?)\n"));
Jun 15, 2012
Jun 15, 2012
820
ERR_clear_error();
Jun 15, 2012
Jun 15, 2012
821
822
823
824
825
826
827
828
return 1;
}
vpn_progress(vpninfo, PRG_ERR,
_("Loading private key failed (see above errors)\n"));
return 0;
}
May 29, 2012
May 29, 2012
829
830
static int load_certificate(struct openconnect_info *vpninfo)
{
Aug 24, 2016
Aug 24, 2016
831
EVP_PKEY *key;
Aug 17, 2014
Aug 17, 2014
832
833
FILE *f;
char buf[256];
Sep 6, 2016
Sep 6, 2016
834
int ret;
Aug 17, 2014
Aug 17, 2014
835
Dec 17, 2014
Dec 17, 2014
836
837
838
839
840
if (!strncmp(vpninfo->cert, "pkcs11:", 7)) {
int ret = load_pkcs11_certificate(vpninfo);
if (ret)
return ret;
goto got_cert;
Jun 11, 2012
Jun 11, 2012
841
}
Mar 10, 2013
Mar 10, 2013
842
Jun 13, 2014
Jun 13, 2014
843
vpn_progress(vpninfo, PRG_DEBUG,
May 29, 2012
May 29, 2012
844
845
_("Using certificate file %s\n"), vpninfo->cert);
Aug 17, 2014
Aug 17, 2014
846
if (strncmp(vpninfo->cert, "keystore:", 9)) {
May 29, 2012
May 29, 2012
847
848
PKCS12 *p12;
Aug 3, 2014
Aug 3, 2014
849
f = openconnect_fopen_utf8(vpninfo, vpninfo->cert, "rb");
May 29, 2012
May 29, 2012
850
851
852
853
854
855
856
857
858
859
860
if (!f) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to open certificate file %s: %s\n"),
vpninfo->cert, strerror(errno));
return -ENOENT;
}
p12 = d2i_PKCS12_fp(f, NULL);
fclose(f);
if (p12)
return load_pkcs12_certificate(vpninfo, p12);
Aug 17, 2014
Aug 17, 2014
861
/* Not PKCS#12. Clear error and fall through to see if it's a PEM file... */
May 29, 2012
May 29, 2012
862
863
864
865
ERR_clear_error();
}
/* It's PEM or TPM now, and either way we need to load the plain cert: */
Jun 15, 2012
Jun 15, 2012
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
#ifdef ANDROID_KEYSTORE
if (!strncmp(vpninfo->cert, "keystore:", 9)) {
BIO *b = BIO_from_keystore(vpninfo, vpninfo->cert);
if (!b)
return -EINVAL;
vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, pem_pw_cb, vpninfo);
BIO_free(b);
if (!vpninfo->cert_x509) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to load X509 certificate from keystore\n"));
openconnect_report_ssl_errors(vpninfo);
return -EINVAL;
}
if (!SSL_CTX_use_certificate(vpninfo->https_ctx, vpninfo->cert_x509)) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to use X509 certificate from keystore\n"));
openconnect_report_ssl_errors(vpninfo);
X509_free(vpninfo->cert_x509);
vpninfo->cert_x509 = NULL;
return -EINVAL;
}
} else
#endif /* ANDROID_KEYSTORE */
{
Jul 31, 2014
Jul 31, 2014
890
891
892
int ret = load_cert_chain_file(vpninfo);
if (ret)
return ret;
May 29, 2012
May 29, 2012
893
}
Dec 17, 2014
Dec 17, 2014
894
895
got_cert:
Jun 15, 2012
Jun 15, 2012
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
#ifdef ANDROID_KEYSTORE
if (!strncmp(vpninfo->sslkey, "keystore:", 9)) {
BIO *b;
again_android:
b = BIO_from_keystore(vpninfo, vpninfo->sslkey);
if (!b)
return -EINVAL;
key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, vpninfo);
BIO_free(b);
if (!key) {
if (is_pem_password_error(vpninfo))
goto again_android;
return -EINVAL;
}
if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to use private key from keystore\n"));
EVP_PKEY_free(key);
X509_free(vpninfo->cert_x509);
vpninfo->cert_x509 = NULL;
return -EINVAL;
}
Aug 24, 2016
Aug 24, 2016
919
EVP_PKEY_free(key);
Jun 15, 2012
Jun 15, 2012
920
921
return 0;
}
Mar 11, 2013
Mar 11, 2013
922
#endif /* ANDROID_KEYSTORE */
Dec 17, 2014
Dec 17, 2014
923
924
if (!strncmp(vpninfo->sslkey, "pkcs11:", 7))
return load_pkcs11_key(vpninfo);
May 29, 2012
May 29, 2012
925
Aug 17, 2014
Aug 17, 2014
926
927
f = openconnect_fopen_utf8(vpninfo, vpninfo->sslkey, "rb");
if (!f) {
Aug 17, 2014
Aug 17, 2014
928
vpn_progress(vpninfo, PRG_ERR,
Aug 17, 2014
Aug 17, 2014
929
_("Failed to open private key file %s: %s\n"),
Aug 23, 2016
Aug 23, 2016
930
vpninfo->sslkey, strerror(errno));
Aug 17, 2014
Aug 17, 2014
931
return -ENOENT;
May 29, 2012
May 29, 2012
932
933
}
Aug 17, 2014
Aug 17, 2014
934
935
936
buf[255] = 0;
while (fgets(buf, 255, f)) {
if (!strcmp(buf, "-----BEGIN TSS KEY BLOB-----\n")) {
Jul 31, 2014
Jul 31, 2014
937
fclose(f);
Sep 27, 2018
Sep 27, 2018
938
return load_tpm_certificate(vpninfo, "tpm");
Oct 12, 2018
Oct 12, 2018
939
940
} else if (!strcmp(buf, "-----BEGIN TSS2 KEY BLOB-----\n") ||
!strcmp(buf, "-----BEGIN TSS2 PRIVATE KEY-----\n")) {
Sep 27, 2018
Sep 27, 2018
941
942
fclose(f);
return load_tpm_certificate(vpninfo, "tpm2");
Aug 17, 2014
Aug 17, 2014
943
944
} else if (!strcmp(buf, "-----BEGIN RSA PRIVATE KEY-----\n") ||
!strcmp(buf, "-----BEGIN DSA PRIVATE KEY-----\n") ||
Aug 31, 2016
Aug 31, 2016
945
!strcmp(buf, "-----BEGIN EC PRIVATE KEY-----\n") ||
Aug 17, 2014
Aug 17, 2014
946
947
948
949
950
951
952
953
954
!strcmp(buf, "-----BEGIN ENCRYPTED PRIVATE KEY-----\n") ||
!strcmp(buf, "-----BEGIN PRIVATE KEY-----\n")) {
BIO *b = BIO_new_fp(f, BIO_CLOSE);
if (!b) {
fclose(f);
vpn_progress(vpninfo, PRG_ERR,
_("Loading private key failed\n"));
openconnect_report_ssl_errors(vpninfo);
Oct 7, 2019
Oct 7, 2019
955
return -EINVAL;
Aug 17, 2014
Aug 17, 2014
956
957
958
}
again:
fseek(f, 0, SEEK_SET);
Aug 24, 2016
Aug 24, 2016
959
key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, vpninfo);
Aug 17, 2014
Aug 17, 2014
960
961
962
963
964
965
if (!key) {
if (is_pem_password_error(vpninfo))
goto again;
BIO_free(b);
return -EINVAL;
}
Sep 6, 2016
Sep 6, 2016
966
967
968
969
970
971
972
ret = 0;
if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
vpn_progress(vpninfo, PRG_ERR,
_("Loading private key failed\n"));
openconnect_report_ssl_errors(vpninfo);
ret = -EINVAL;
}
Aug 24, 2016
Aug 24, 2016
973
EVP_PKEY_free(key);
Jul 31, 2014
Jul 31, 2014
974
BIO_free(b);
Sep 6, 2016
Sep 6, 2016
975
return ret;
Jul 31, 2014
Jul 31, 2014
976
}
May 29, 2012
May 29, 2012
977
}
Aug 17, 2014
Aug 17, 2014
978
Aug 24, 2016
Aug 24, 2016
979
980
981
982
983
984
985
986
/* Not PEM? Try DER... */
fseek(f, 0, SEEK_SET);
/* This will catch PKCS#1 and unencrypted PKCS#8
* (except in OpenSSL 0.9.8 where it doesn't handle
* the latter but nobody cares about 0.9.8 any more. */
key = d2i_PrivateKey_fp(f, NULL);
if (key) {
Sep 6, 2016
Sep 6, 2016
987
988
989
990
991
992
993
ret = 0;
if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
vpn_progress(vpninfo, PRG_ERR,
_("Loading private key failed\n"));
openconnect_report_ssl_errors(vpninfo);
ret = -EINVAL;
}
Aug 24, 2016
Aug 24, 2016
994
995
EVP_PKEY_free(key);
fclose(f);
Sep 6, 2016
Sep 6, 2016
996
return ret;
Aug 24, 2016
Aug 24, 2016
997
998
999
1000
} else {
/* Encrypted PKCS#8 DER */
X509_SIG *p8;