1 /*
2 neon SSL/TLS support using GNU TLS
3 Copyright (C) 2002-2008, Joe Orton <joe@manyfish.co.uk>
4 Copyright (C) 2004, Aleix Conchillo Flaque <aleix@member.fsf.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA
20 */
21
22 #include "config.h"
23
24 #include <sys/types.h>
25
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #endif
29
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <errno.h>
34
35 #include <gnutls/gnutls.h>
36 #include <gnutls/pkcs12.h>
37
38 #ifdef NE_HAVE_TS_SSL
39 #include <errno.h>
40 #include <pthread.h>
41 #include <gcrypt.h>
42 GCRY_THREAD_OPTION_PTHREAD_IMPL;
43 #else
44 #include <gcrypt.h>
45 #endif
46
47 #ifdef HAVE_ICONV
48 #include <iconv.h>
49 #endif
50
51 #include "ne_ssl.h"
52 #include "ne_string.h"
53 #include "ne_session.h"
54 #include "ne_internal.h"
55
56 #include "ne_private.h"
57 #include "ne_privssl.h"
58
59 struct ne_ssl_dname_s {
60 int subject; /* non-zero if this is the subject DN object */
61 gnutls_x509_crt cert;
62 };
63
64 struct ne_ssl_certificate_s {
65 ne_ssl_dname subj_dn, issuer_dn;
66 gnutls_x509_crt subject;
67 ne_ssl_certificate *issuer;
68 char *identity;
69 };
70
71 struct ne_ssl_client_cert_s {
72 gnutls_pkcs12 p12;
73 int decrypted; /* non-zero if successfully decrypted. */
74 int keyless;
75 ne_ssl_certificate cert;
76 gnutls_x509_privkey pkey;
77 char *friendly_name;
78 };
79
80 /* Returns the highest used index in subject (or issuer) DN of
81 * certificate CERT for OID, or -1 if no RDNs are present in the DN
82 * using that OID. */
oid_find_highest_index(gnutls_x509_crt cert,int subject,const char * oid)83 static int oid_find_highest_index(gnutls_x509_crt cert, int subject, const char *oid)
84 {
85 int ret, idx = -1;
86
87 do {
88 size_t len = 0;
89
90 if (subject)
91 ret = gnutls_x509_crt_get_dn_by_oid(cert, oid, ++idx, 0,
92 NULL, &len);
93 else
94 ret = gnutls_x509_crt_get_issuer_dn_by_oid(cert, oid, ++idx, 0,
95 NULL, &len);
96 } while (ret == GNUTLS_E_SHORT_MEMORY_BUFFER);
97
98 return idx - 1;
99 }
100
101 #ifdef HAVE_GNUTLS_X509_DN_GET_RDN_AVA
102 /* New-style RDN handling introduced in GnuTLS 1.7.x. */
103
104 #ifdef HAVE_ICONV
convert_dirstring(ne_buffer * buf,const char * charset,gnutls_datum * data)105 static void convert_dirstring(ne_buffer *buf, const char *charset,
106 gnutls_datum *data)
107 {
108 iconv_t id = iconv_open("UTF-8", charset);
109 size_t inlen = data->size, outlen = buf->length - buf->used;
110 char *inbuf = (char *)data->data;
111 char *outbuf = buf->data + buf->used - 1;
112
113 if (id == (iconv_t)-1) {
114 char err[128], err2[128];
115
116 ne_snprintf(err, sizeof err, "[unprintable in %s: %s]",
117 charset, ne_strerror(errno, err2, sizeof err2));
118 ne_buffer_zappend(buf, err);
119 return;
120 }
121
122 ne_buffer_grow(buf, buf->used + 64);
123
124 while (inlen && outlen
125 && iconv(id, &inbuf, &inlen, &outbuf, &outlen) == 0)
126 ;
127
128 iconv_close(id);
129 buf->used += buf->length - buf->used - outlen;
130 buf->data[buf->used - 1] = '\0';
131 }
132 #endif
133
134 /* From section 11.13 of the Dubuisson ASN.1 bible: */
135 #define TAG_UTF8 (12)
136 #define TAG_PRINTABLE (19)
137 #define TAG_T61 (20)
138 #define TAG_IA5 (22)
139 #define TAG_VISIBLE (26)
140 #define TAG_UNIVERSAL (28)
141 #define TAG_BMP (30)
142
append_dirstring(ne_buffer * buf,gnutls_datum * data,unsigned long tag)143 static void append_dirstring(ne_buffer *buf, gnutls_datum *data, unsigned long tag)
144 {
145 switch (tag) {
146 case TAG_UTF8:
147 case TAG_IA5:
148 case TAG_PRINTABLE:
149 case TAG_VISIBLE:
150 ne_buffer_append(buf, (char *)data->data, data->size);
151 break;
152 #ifdef HAVE_ICONV
153 case TAG_T61:
154 convert_dirstring(buf, "ISO-8859-1", data);
155 break;
156 case TAG_BMP:
157 convert_dirstring(buf, "UCS-2BE", data);
158 break;
159 #endif
160 default: {
161 char tmp[128];
162 ne_snprintf(tmp, sizeof tmp, _("[unprintable:#%lu]"), tag);
163 ne_buffer_zappend(buf, tmp);
164 } break;
165 }
166 }
167
168 /* OIDs to not include in readable DNs by default: */
169 #define OID_emailAddress "1.2.840.113549.1.9.1"
170 #define OID_commonName "2.5.4.3"
171
172 #define CMPOID(a,o) ((a)->oid.size == sizeof(o) \
173 && memcmp((a)->oid.data, o, strlen(o)) == 0)
174
ne_ssl_readable_dname(const ne_ssl_dname * name)175 char *ne_ssl_readable_dname(const ne_ssl_dname *name)
176 {
177 gnutls_x509_dn_t dn;
178 int ret, rdn = 0, flag = 0;
179 ne_buffer *buf;
180 gnutls_x509_ava_st val;
181
182 if (name->subject)
183 ret = gnutls_x509_crt_get_subject(name->cert, &dn);
184 else
185 ret = gnutls_x509_crt_get_issuer(name->cert, &dn);
186
187 if (ret)
188 return ne_strdup(_("[unprintable]"));
189
190 buf = ne_buffer_create();
191
192 /* Find the highest rdn... */
193 while (gnutls_x509_dn_get_rdn_ava(dn, rdn++, 0, &val) == 0)
194 ;
195
196 /* ..then iterate back to the first: */
197 while (--rdn >= 0) {
198 int ava = 0;
199
200 /* Iterate through all AVAs for multivalued AVAs; better than
201 * ne_openssl can do! */
202 do {
203 ret = gnutls_x509_dn_get_rdn_ava(dn, rdn, ava, &val);
204
205 /* If the *only* attribute to append is the common name or
206 * email address, use it; otherwise skip those
207 * attributes. */
208 if (ret == 0 && val.value.size > 0
209 && ((!CMPOID(&val, OID_emailAddress)
210 && !CMPOID(&val, OID_commonName))
211 || (buf->used == 1 && rdn == 0))) {
212 flag = 1;
213 if (buf->used > 1) ne_buffer_append(buf, ", ", 2);
214
215 append_dirstring(buf, &val.value, val.value_tag);
216 }
217
218 ava++;
219 } while (ret == 0);
220 }
221
222 return ne_buffer_finish(buf);
223 }
224
225 #else /* !HAVE_GNUTLS_X509_DN_GET_RDN_AVA */
226
227 /* Appends the value of RDN with given oid from certitifcate x5
228 * subject (if subject is non-zero), or issuer DN to buffer 'buf': */
append_rdn(ne_buffer * buf,gnutls_x509_crt x5,int subject,const char * oid)229 static void append_rdn(ne_buffer *buf, gnutls_x509_crt x5, int subject, const char *oid)
230 {
231 int idx, top, ret;
232 char rdn[50];
233
234 top = oid_find_highest_index(x5, subject, oid);
235
236 for (idx = top; idx >= 0; idx--) {
237 size_t rdnlen = sizeof rdn;
238
239 if (subject)
240 ret = gnutls_x509_crt_get_dn_by_oid(x5, oid, idx, 0, rdn, &rdnlen);
241 else
242 ret = gnutls_x509_crt_get_issuer_dn_by_oid(x5, oid, idx, 0, rdn, &rdnlen);
243
244 if (ret < 0)
245 return;
246
247 if (buf->used > 1) {
248 ne_buffer_append(buf, ", ", 2);
249 }
250
251 ne_buffer_append(buf, rdn, rdnlen);
252 }
253 }
254
ne_ssl_readable_dname(const ne_ssl_dname * name)255 char *ne_ssl_readable_dname(const ne_ssl_dname *name)
256 {
257 ne_buffer *buf = ne_buffer_create();
258 int ret, idx = 0;
259
260 do {
261 char oid[32] = {0};
262 size_t oidlen = sizeof oid;
263
264 ret = name->subject
265 ? gnutls_x509_crt_get_dn_oid(name->cert, idx, oid, &oidlen)
266 : gnutls_x509_crt_get_issuer_dn_oid(name->cert, idx, oid, &oidlen);
267
268 if (ret == 0) {
269 append_rdn(buf, name->cert, name->subject, oid);
270 idx++;
271 }
272 } while (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
273
274 return ne_buffer_finish(buf);
275 }
276 #endif /* HAVE_GNUTLS_X509_DN_GET_RDN_AVA */
277
ne_ssl_dname_cmp(const ne_ssl_dname * dn1,const ne_ssl_dname * dn2)278 int ne_ssl_dname_cmp(const ne_ssl_dname *dn1, const ne_ssl_dname *dn2)
279 {
280 char c1[1024], c2[1024];
281 size_t s1 = sizeof c1, s2 = sizeof c2;
282 int ret;
283
284 if (dn1->subject)
285 ret = gnutls_x509_crt_get_dn(dn1->cert, c1, &s1);
286 else
287 ret = gnutls_x509_crt_get_issuer_dn(dn1->cert, c1, &s1);
288 if (ret)
289 return 1;
290
291 if (dn2->subject)
292 ret = gnutls_x509_crt_get_dn(dn2->cert, c2, &s2);
293 else
294 ret = gnutls_x509_crt_get_issuer_dn(dn2->cert, c2, &s2);
295 if (ret)
296 return -1;
297
298 if (s1 != s2)
299 return s2 - s1;
300
301 return memcmp(c1, c2, s1);
302 }
303
ne_ssl_clicert_free(ne_ssl_client_cert * cc)304 void ne_ssl_clicert_free(ne_ssl_client_cert *cc)
305 {
306 if (cc->p12)
307 gnutls_pkcs12_deinit(cc->p12);
308 if (cc->decrypted) {
309 if (cc->cert.identity) ne_free(cc->cert.identity);
310 if (cc->pkey) gnutls_x509_privkey_deinit(cc->pkey);
311 if (cc->cert.subject) gnutls_x509_crt_deinit(cc->cert.subject);
312 }
313 if (cc->friendly_name) ne_free(cc->friendly_name);
314 ne_free(cc);
315 }
316
ne_ssl_cert_validity_time(const ne_ssl_certificate * cert,time_t * from,time_t * until)317 void ne_ssl_cert_validity_time(const ne_ssl_certificate *cert,
318 time_t *from, time_t *until)
319 {
320 if (from) {
321 *from = gnutls_x509_crt_get_activation_time(cert->subject);
322 }
323 if (until) {
324 *until = gnutls_x509_crt_get_expiration_time(cert->subject);
325 }
326 }
327
328 /* Return non-zero if hostname from certificate (cn) matches hostname
329 * used for session (hostname). (Wildcard matching is no longer
330 * mandated by RFC3280, but certs are deployed which use wildcards) */
match_hostname(char * cn,const char * hostname)331 static int match_hostname(char *cn, const char *hostname)
332 {
333 const char *dot;
334 dot = strchr(hostname, '.');
335 if (dot == NULL) {
336 char *pnt = strchr(cn, '.');
337 /* hostname is not fully-qualified; unqualify the cn. */
338 if (pnt != NULL) {
339 *pnt = '\0';
340 }
341 }
342 else if (strncmp(cn, "*.", 2) == 0) {
343 hostname = dot + 1;
344 cn += 2;
345 }
346 return !ne_strcasecmp(cn, hostname);
347 }
348
349 /* Check certificate identity. Returns zero if identity matches; 1 if
350 * identity does not match, or <0 if the certificate had no identity.
351 * If 'identity' is non-NULL, store the malloc-allocated identity in
352 * *identity. If 'server' is non-NULL, it must be the network address
353 * of the server in use, and identity must be NULL. */
check_identity(const ne_uri * server,gnutls_x509_crt cert,char ** identity)354 static int check_identity(const ne_uri *server, gnutls_x509_crt cert,
355 char **identity)
356 {
357 char name[255];
358 unsigned int critical;
359 int ret, seq = 0;
360 int match = 0, found = 0;
361 size_t len;
362 const char *hostname;
363
364 hostname = server ? server->host : "";
365
366 do {
367 len = sizeof name - 1;
368 ret = gnutls_x509_crt_get_subject_alt_name(cert, seq, name, &len,
369 &critical);
370 switch (ret) {
371 case GNUTLS_SAN_DNSNAME:
372 name[len] = '\0';
373 if (identity && !found) *identity = ne_strdup(name);
374 match = match_hostname(name, hostname);
375 found = 1;
376 break;
377 case GNUTLS_SAN_IPADDRESS: {
378 ne_inet_addr *ia;
379 if (len == 4)
380 ia = ne_iaddr_make(ne_iaddr_ipv4, (unsigned char *)name);
381 else if (len == 16)
382 ia = ne_iaddr_make(ne_iaddr_ipv6, (unsigned char *)name);
383 else
384 ia = NULL;
385 if (ia) {
386 char buf[128];
387
388 match = strcmp(hostname,
389 ne_iaddr_print(ia, buf, sizeof buf)) == 0;
390 if (identity) *identity = ne_strdup(buf);
391 found = 1;
392 ne_iaddr_free(ia);
393 } else {
394 NE_DEBUG(NE_DBG_SSL, "iPAddress name with unsupported "
395 "address type (length %" NE_FMT_SIZE_T "), skipped.\n",
396 len);
397 }
398 } break;
399 case GNUTLS_SAN_URI: {
400 ne_uri uri;
401
402 name[len] = '\0';
403
404 if (ne_uri_parse(name, &uri) == 0 && uri.host && uri.scheme) {
405 ne_uri tmp;
406
407 if (identity && !found) *identity = ne_strdup(name);
408 found = 1;
409
410 if (server) {
411 /* For comparison purposes, all that matters is
412 * host, scheme and port; ignore the rest. */
413 memset(&tmp, 0, sizeof tmp);
414 tmp.host = uri.host;
415 tmp.scheme = uri.scheme;
416 tmp.port = uri.port;
417
418 match = ne_uri_cmp(server, &tmp) == 0;
419 }
420 }
421
422 ne_uri_free(&uri);
423 } break;
424
425 default:
426 break;
427 }
428 seq++;
429 } while (!match && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
430
431 /* Check against the commonName if no DNS alt. names were found,
432 * as per RFC3280. */
433 if (!found) {
434 seq = oid_find_highest_index(cert, 1, GNUTLS_OID_X520_COMMON_NAME);
435
436 if (seq >= 0) {
437 len = sizeof name;
438 name[0] = '\0';
439 ret = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME,
440 seq, 0, name, &len);
441 if (ret == 0) {
442 if (identity) *identity = ne_strdup(name);
443 match = match_hostname(name, hostname);
444 }
445 } else {
446 return -1;
447 }
448 }
449
450 if (*hostname)
451 NE_DEBUG(NE_DBG_SSL, "ssl: Identity match for '%s': %s\n", hostname,
452 match ? "good" : "bad");
453
454 return match ? 0 : 1;
455 }
456
457 /* Populate an ne_ssl_certificate structure from an X509 object. */
populate_cert(ne_ssl_certificate * cert,gnutls_x509_crt x5)458 static ne_ssl_certificate *populate_cert(ne_ssl_certificate *cert,
459 gnutls_x509_crt x5)
460 {
461 cert->subj_dn.cert = x5;
462 cert->subj_dn.subject = 1;
463 cert->issuer_dn.cert = x5;
464 cert->issuer_dn.subject = 0;
465 cert->issuer = NULL;
466 cert->subject = x5;
467 cert->identity = NULL;
468 check_identity(NULL, x5, &cert->identity);
469 return cert;
470 }
471
472 /* Returns a copy certificate of certificate SRC. */
x509_crt_copy(gnutls_x509_crt src)473 static gnutls_x509_crt x509_crt_copy(gnutls_x509_crt src)
474 {
475 int ret;
476 size_t size;
477 gnutls_datum tmp;
478 gnutls_x509_crt dest;
479
480 if (gnutls_x509_crt_init(&dest) != 0) {
481 return NULL;
482 }
483
484 if (gnutls_x509_crt_export(src, GNUTLS_X509_FMT_DER, NULL, &size)
485 != GNUTLS_E_SHORT_MEMORY_BUFFER) {
486 gnutls_x509_crt_deinit(dest);
487 return NULL;
488 }
489
490 tmp.data = ne_malloc(size);
491 ret = gnutls_x509_crt_export(src, GNUTLS_X509_FMT_DER, tmp.data, &size);
492 if (ret == 0) {
493 tmp.size = size;
494 ret = gnutls_x509_crt_import(dest, &tmp, GNUTLS_X509_FMT_DER);
495 }
496
497 if (ret) {
498 gnutls_x509_crt_deinit(dest);
499 dest = NULL;
500 }
501
502 ne_free(tmp.data);
503 return dest;
504 }
505
506 /* Duplicate a client certificate, which must be in the decrypted state. */
dup_client_cert(const ne_ssl_client_cert * cc)507 static ne_ssl_client_cert *dup_client_cert(const ne_ssl_client_cert *cc)
508 {
509 int ret;
510 ne_ssl_client_cert *newcc = ne_calloc(sizeof *newcc);
511
512 newcc->decrypted = 1;
513
514 if (cc->keyless) {
515 newcc->keyless = 1;
516 }
517 else {
518 ret = gnutls_x509_privkey_init(&newcc->pkey);
519 if (ret != 0) goto dup_error;
520
521 ret = gnutls_x509_privkey_cpy(newcc->pkey, cc->pkey);
522 if (ret != 0) goto dup_error;
523 }
524
525 newcc->cert.subject = x509_crt_copy(cc->cert.subject);
526 if (!newcc->cert.subject) goto dup_error;
527
528 if (cc->friendly_name) newcc->friendly_name = ne_strdup(cc->friendly_name);
529
530 populate_cert(&newcc->cert, newcc->cert.subject);
531 return newcc;
532
533 dup_error:
534 if (newcc->pkey) gnutls_x509_privkey_deinit(newcc->pkey);
535 if (newcc->cert.subject) gnutls_x509_crt_deinit(newcc->cert.subject);
536 ne_free(newcc);
537 return NULL;
538 }
539
540 /* Callback invoked when the SSL server requests a client certificate. */
provide_client_cert(gnutls_session session,const gnutls_datum * req_ca_rdn,int nreqs,const gnutls_pk_algorithm * sign_algos,int sign_algos_length,gnutls_retr_st * st)541 static int provide_client_cert(gnutls_session session,
542 const gnutls_datum *req_ca_rdn, int nreqs,
543 const gnutls_pk_algorithm *sign_algos,
544 int sign_algos_length, gnutls_retr_st *st)
545 {
546 ne_session *sess = gnutls_session_get_ptr(session);
547
548 if (!sess) {
549 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
550 }
551
552 if (!sess->client_cert && sess->ssl_provide_fn) {
553 /* The dname array cannot be converted without better dname
554 * support from GNUTLS. */
555 sess->ssl_provide_fn(sess->ssl_provide_ud, sess,
556 NULL, 0);
557 }
558
559 NE_DEBUG(NE_DBG_SSL, "In client cert provider callback.\n");
560
561 if (sess->client_cert) {
562 gnutls_certificate_type type = gnutls_certificate_type_get(session);
563 if (type == GNUTLS_CRT_X509) {
564 NE_DEBUG(NE_DBG_SSL, "Supplying client certificate.\n");
565
566 st->type = type;
567 st->ncerts = 1;
568 st->cert.x509 = &sess->client_cert->cert.subject;
569 st->key.x509 = sess->client_cert->pkey;
570
571 /* tell GNU TLS not to deallocate the certs. */
572 st->deinit_all = 0;
573 } else {
574 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
575 }
576 } else {
577 NE_DEBUG(NE_DBG_SSL, "No client certificate supplied.\n");
578 return GNUTLS_E_NO_CERTIFICATE_FOUND;
579 }
580
581 return 0;
582 }
583
ne_ssl_set_clicert(ne_session * sess,const ne_ssl_client_cert * cc)584 void ne_ssl_set_clicert(ne_session *sess, const ne_ssl_client_cert *cc)
585 {
586 sess->client_cert = dup_client_cert(cc);
587 }
588
ne_ssl_context_create(int flags)589 ne_ssl_context *ne_ssl_context_create(int flags)
590 {
591 ne_ssl_context *ctx = ne_calloc(sizeof *ctx);
592 gnutls_certificate_allocate_credentials(&ctx->cred);
593 if (flags == NE_SSL_CTX_CLIENT) {
594 gnutls_certificate_client_set_retrieve_function(ctx->cred,
595 provide_client_cert);
596 }
597 return ctx;
598 }
599
ne_ssl_context_keypair(ne_ssl_context * ctx,const char * cert,const char * key)600 int ne_ssl_context_keypair(ne_ssl_context *ctx,
601 const char *cert, const char *key)
602 {
603 gnutls_certificate_set_x509_key_file(ctx->cred, cert, key,
604 GNUTLS_X509_FMT_PEM);
605 return 0;
606 }
607
ne_ssl_context_set_verify(ne_ssl_context * ctx,int required,const char * ca_names,const char * verify_cas)608 int ne_ssl_context_set_verify(ne_ssl_context *ctx, int required,
609 const char *ca_names, const char *verify_cas)
610 {
611 ctx->verify = required;
612 if (verify_cas) {
613 gnutls_certificate_set_x509_trust_file(ctx->cred, verify_cas,
614 GNUTLS_X509_FMT_PEM);
615 }
616 /* gnutls_certificate_send_x509_rdn_sequence in gnutls >= 1.2 can
617 * be used to *suppress* sending the CA names, but not control it,
618 * it seems. */
619 return 0;
620 }
621
ne_ssl_context_set_flag(ne_ssl_context * ctx,int flag,int value)622 void ne_ssl_context_set_flag(ne_ssl_context *ctx, int flag, int value)
623 {
624 /* SSLv2 not supported. */
625 }
626
ne_ssl_context_destroy(ne_ssl_context * ctx)627 void ne_ssl_context_destroy(ne_ssl_context *ctx)
628 {
629 gnutls_certificate_free_credentials(ctx->cred);
630 if (ctx->cache.client.data) {
631 ne_free(ctx->cache.client.data);
632 } else if (ctx->cache.server.key.data) {
633 gnutls_free(ctx->cache.server.key.data);
634 gnutls_free(ctx->cache.server.data.data);
635 }
636 ne_free(ctx);
637 }
638
639 /* Return the certificate chain sent by the peer, or NULL on error. */
make_peers_chain(gnutls_session sock)640 static ne_ssl_certificate *make_peers_chain(gnutls_session sock)
641 {
642 ne_ssl_certificate *current = NULL, *top = NULL;
643 const gnutls_datum *certs;
644 unsigned int n, count;
645
646 certs = gnutls_certificate_get_peers(sock, &count);
647 if (!certs) {
648 return NULL;
649 }
650
651 for (n = 0; n < count; n++) {
652 ne_ssl_certificate *cert;
653 gnutls_x509_crt x5;
654
655 if (gnutls_x509_crt_init(&x5) ||
656 gnutls_x509_crt_import(x5, &certs[n], GNUTLS_X509_FMT_DER)) {
657 ne_ssl_cert_free(top);
658 return NULL;
659 }
660
661 cert = populate_cert(ne_malloc(sizeof *cert), x5);
662
663 if (top == NULL) {
664 current = top = cert;
665 } else {
666 current->issuer = cert;
667 current = cert;
668 }
669 }
670
671 return top;
672 }
673
674 /* Verifies an SSL server certificate. */
check_certificate(ne_session * sess,gnutls_session sock,ne_ssl_certificate * chain)675 static int check_certificate(ne_session *sess, gnutls_session sock,
676 ne_ssl_certificate *chain)
677 {
678 time_t before, after, now = time(NULL);
679 int ret, failures = 0;
680 ne_uri server;
681
682 before = gnutls_x509_crt_get_activation_time(chain->subject);
683 after = gnutls_x509_crt_get_expiration_time(chain->subject);
684
685 if (now < before)
686 failures |= NE_SSL_NOTYETVALID;
687 else if (now > after)
688 failures |= NE_SSL_EXPIRED;
689
690 memset(&server, 0, sizeof server);
691 ne_fill_server_uri(sess, &server);
692 ret = check_identity(&server, chain->subject, NULL);
693 ne_uri_free(&server);
694
695 if (ret < 0) {
696 ne_set_error(sess, _("Server certificate was missing commonName "
697 "attribute in subject name"));
698 return NE_ERROR;
699 } else if (ret > 0) {
700 failures |= NE_SSL_IDMISMATCH;
701 }
702
703 if (gnutls_certificate_verify_peers(sock)) {
704 failures |= NE_SSL_UNTRUSTED;
705 }
706
707 NE_DEBUG(NE_DBG_SSL, "Failures = %d\n", failures);
708
709 if (failures == 0) {
710 ret = NE_OK;
711 } else {
712 ne__ssl_set_verify_err(sess, failures);
713 ret = NE_ERROR;
714 if (sess->ssl_verify_fn
715 && sess->ssl_verify_fn(sess->ssl_verify_ud, failures, chain) == 0)
716 ret = NE_OK;
717 }
718
719 return ret;
720 }
721
722 /* Negotiate an SSL connection. */
ne__negotiate_ssl(ne_session * sess)723 int ne__negotiate_ssl(ne_session *sess)
724 {
725 ne_ssl_context *const ctx = sess->ssl_context;
726 ne_ssl_certificate *chain;
727 gnutls_session sock;
728
729 NE_DEBUG(NE_DBG_SSL, "Negotiating SSL connection.\n");
730
731 /* Pass through the hostname if SNI is enabled. */
732 ctx->hostname =
733 sess->flags[NE_SESSFLAG_TLS_SNI] ? sess->server.hostname : NULL;
734
735 if (ne_sock_connect_ssl(sess->socket, ctx, sess)) {
736 ne_set_error(sess, _("SSL negotiation failed: %s"),
737 ne_sock_error(sess->socket));
738 return NE_ERROR;
739 }
740
741 sock = ne__sock_sslsock(sess->socket);
742
743 chain = make_peers_chain(sock);
744 if (chain == NULL) {
745 ne_set_error(sess, _("Server did not send certificate chain"));
746 return NE_ERROR;
747 }
748
749 if (sess->server_cert && ne_ssl_cert_cmp(sess->server_cert, chain) == 0) {
750 /* Same cert as last time; presume OK. This is not optimal as
751 * make_peers_chain() has already gone through and done the
752 * expensive DER parsing stuff for the whole chain by now. */
753 ne_ssl_cert_free(chain);
754 return NE_OK;
755 }
756
757 if (check_certificate(sess, sock, chain)) {
758 ne_ssl_cert_free(chain);
759 return NE_ERROR;
760 }
761
762 sess->server_cert = chain;
763
764 return NE_OK;
765 }
766
ne_ssl_cert_issuer(const ne_ssl_certificate * cert)767 const ne_ssl_dname *ne_ssl_cert_issuer(const ne_ssl_certificate *cert)
768 {
769 return &cert->issuer_dn;
770 }
771
ne_ssl_cert_subject(const ne_ssl_certificate * cert)772 const ne_ssl_dname *ne_ssl_cert_subject(const ne_ssl_certificate *cert)
773 {
774 return &cert->subj_dn;
775 }
776
ne_ssl_cert_signedby(const ne_ssl_certificate * cert)777 const ne_ssl_certificate *ne_ssl_cert_signedby(const ne_ssl_certificate *cert)
778 {
779 return cert->issuer;
780 }
781
ne_ssl_cert_identity(const ne_ssl_certificate * cert)782 const char *ne_ssl_cert_identity(const ne_ssl_certificate *cert)
783 {
784 return cert->identity;
785 }
786
ne_ssl_context_trustcert(ne_ssl_context * ctx,const ne_ssl_certificate * cert)787 void ne_ssl_context_trustcert(ne_ssl_context *ctx, const ne_ssl_certificate *cert)
788 {
789 gnutls_x509_crt certs = cert->subject;
790 gnutls_certificate_set_x509_trust(ctx->cred, &certs, 1);
791 }
792
ne_ssl_trust_default_ca(ne_session * sess)793 void ne_ssl_trust_default_ca(ne_session *sess)
794 {
795 #ifdef NE_SSL_CA_BUNDLE
796 gnutls_certificate_set_x509_trust_file(sess->ssl_context->cred,
797 NE_SSL_CA_BUNDLE,
798 GNUTLS_X509_FMT_PEM);
799 #endif
800 }
801
802 /* Read the contents of file FILENAME into *DATUM. */
read_to_datum(const char * filename,gnutls_datum * datum)803 static int read_to_datum(const char *filename, gnutls_datum *datum)
804 {
805 FILE *f = fopen(filename, "r");
806 ne_buffer *buf;
807 char tmp[4192];
808 size_t len;
809
810 if (!f) {
811 return -1;
812 }
813
814 buf = ne_buffer_ncreate(8192);
815 while ((len = fread(tmp, 1, sizeof tmp, f)) > 0) {
816 ne_buffer_append(buf, tmp, len);
817 }
818
819 if (!feof(f)) {
820 fclose(f);
821 ne_buffer_destroy(buf);
822 return -1;
823 }
824
825 fclose(f);
826
827 datum->size = ne_buffer_size(buf);
828 datum->data = (unsigned char *)ne_buffer_finish(buf);
829 return 0;
830 }
831
832 /* Parses a PKCS#12 structure and loads the certificate, private key
833 * and friendly name if possible. Returns zero on success, non-zero
834 * on error. */
pkcs12_parse(gnutls_pkcs12 p12,gnutls_x509_privkey * pkey,gnutls_x509_crt * x5,char ** friendly_name,const char * password)835 static int pkcs12_parse(gnutls_pkcs12 p12, gnutls_x509_privkey *pkey,
836 gnutls_x509_crt *x5, char **friendly_name,
837 const char *password)
838 {
839 gnutls_pkcs12_bag bag = NULL;
840 int i, j, ret = 0;
841
842 for (i = 0; ret == 0; ++i) {
843 if (bag) gnutls_pkcs12_bag_deinit(bag);
844
845 ret = gnutls_pkcs12_bag_init(&bag);
846 if (ret < 0) continue;
847
848 ret = gnutls_pkcs12_get_bag(p12, i, bag);
849 if (ret < 0) continue;
850
851 gnutls_pkcs12_bag_decrypt(bag, password);
852
853 for (j = 0; ret == 0 && j < gnutls_pkcs12_bag_get_count(bag); ++j) {
854 gnutls_pkcs12_bag_type type;
855 gnutls_datum data;
856
857 if (friendly_name && *friendly_name == NULL) {
858 char *name = NULL;
859 gnutls_pkcs12_bag_get_friendly_name(bag, j, &name);
860 if (name) {
861 if (name[0] == '.') name++; /* weird GnuTLS bug? */
862 *friendly_name = ne_strdup(name);
863 }
864 }
865
866 type = gnutls_pkcs12_bag_get_type(bag, j);
867 switch (type) {
868 case GNUTLS_BAG_PKCS8_KEY:
869 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
870 gnutls_x509_privkey_init(pkey);
871
872 ret = gnutls_pkcs12_bag_get_data(bag, j, &data);
873 if (ret < 0) continue;
874
875 ret = gnutls_x509_privkey_import_pkcs8(*pkey, &data,
876 GNUTLS_X509_FMT_DER,
877 password,
878 0);
879 if (ret < 0) continue;
880 break;
881 case GNUTLS_BAG_CERTIFICATE:
882 gnutls_x509_crt_init(x5);
883
884 ret = gnutls_pkcs12_bag_get_data(bag, j, &data);
885 if (ret < 0) continue;
886
887 ret = gnutls_x509_crt_import(*x5, &data, GNUTLS_X509_FMT_DER);
888 if (ret < 0) continue;
889
890 break;
891 default:
892 break;
893 }
894 }
895 }
896
897 /* Make sure last bag is freed */
898 if (bag) gnutls_pkcs12_bag_deinit(bag);
899
900 /* Free in case of error */
901 if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
902 if (*x5) gnutls_x509_crt_deinit(*x5);
903 if (*pkey) gnutls_x509_privkey_deinit(*pkey);
904 if (friendly_name && *friendly_name) ne_free(*friendly_name);
905 }
906
907 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) ret = 0;
908 return ret;
909 }
910
ne_ssl_clicert_read(const char * filename)911 ne_ssl_client_cert *ne_ssl_clicert_read(const char *filename)
912 {
913 int ret;
914 gnutls_datum data;
915 gnutls_pkcs12 p12;
916 ne_ssl_client_cert *cc;
917 char *friendly_name = NULL;
918 gnutls_x509_crt cert = NULL;
919 gnutls_x509_privkey pkey = NULL;
920
921 if (read_to_datum(filename, &data))
922 return NULL;
923
924 if (gnutls_pkcs12_init(&p12) != 0) {
925 return NULL;
926 }
927
928 ret = gnutls_pkcs12_import(p12, &data, GNUTLS_X509_FMT_DER, 0);
929 ne_free(data.data);
930 if (ret < 0) {
931 gnutls_pkcs12_deinit(p12);
932 return NULL;
933 }
934
935 if (gnutls_pkcs12_verify_mac(p12, "") == 0) {
936 if (pkcs12_parse(p12, &pkey, &cert, &friendly_name, "") != 0
937 || !cert || !pkey) {
938 gnutls_pkcs12_deinit(p12);
939 return NULL;
940 }
941
942 cc = ne_calloc(sizeof *cc);
943 cc->pkey = pkey;
944 cc->decrypted = 1;
945 cc->friendly_name = friendly_name;
946 populate_cert(&cc->cert, cert);
947 gnutls_pkcs12_deinit(p12);
948 cc->p12 = NULL;
949 return cc;
950 } else {
951 /* TODO: calling pkcs12_parse() here to find the friendly_name
952 * seems to break horribly. */
953 cc = ne_calloc(sizeof *cc);
954 cc->p12 = p12;
955 return cc;
956 }
957 }
958
ne__ssl_clicert_exkey_import(const unsigned char * der,size_t der_len)959 ne_ssl_client_cert *ne__ssl_clicert_exkey_import(const unsigned char *der,
960 size_t der_len)
961 {
962 ne_ssl_client_cert *cc;
963 gnutls_x509_crt x5;
964 gnutls_datum datum;
965
966 datum.data = (unsigned char *)der;
967 datum.size = der_len;
968
969 if (gnutls_x509_crt_init(&x5)
970 || gnutls_x509_crt_import(x5, &datum, GNUTLS_X509_FMT_DER)) {
971 NE_DEBUG(NE_DBG_SSL, "ssl: crt_import failed.\n");
972 return NULL;
973 }
974
975 cc = ne_calloc(sizeof *cc);
976 cc->keyless = 1;
977 cc->decrypted = 1;
978 populate_cert(&cc->cert, x5);
979
980 return cc;
981 }
982
ne_ssl_clicert_encrypted(const ne_ssl_client_cert * cc)983 int ne_ssl_clicert_encrypted(const ne_ssl_client_cert *cc)
984 {
985 return !cc->decrypted;
986 }
987
ne_ssl_clicert_decrypt(ne_ssl_client_cert * cc,const char * password)988 int ne_ssl_clicert_decrypt(ne_ssl_client_cert *cc, const char *password)
989 {
990 int ret;
991 gnutls_x509_crt cert = NULL;
992 gnutls_x509_privkey pkey = NULL;
993
994 if (gnutls_pkcs12_verify_mac(cc->p12, password) != 0) {
995 return -1;
996 }
997
998 ret = pkcs12_parse(cc->p12, &pkey, &cert, NULL, password);
999 if (ret < 0)
1000 return ret;
1001
1002 if (!cert || (!pkey && !cc->keyless)) {
1003 if (cert) gnutls_x509_crt_deinit(cert);
1004 if (pkey) gnutls_x509_privkey_deinit(pkey);
1005 return -1;
1006 }
1007
1008 gnutls_pkcs12_deinit(cc->p12);
1009 populate_cert(&cc->cert, cert);
1010 cc->pkey = pkey;
1011 cc->decrypted = 1;
1012 cc->p12 = NULL;
1013 return 0;
1014 }
1015
ne_ssl_clicert_owner(const ne_ssl_client_cert * cc)1016 const ne_ssl_certificate *ne_ssl_clicert_owner(const ne_ssl_client_cert *cc)
1017 {
1018 return &cc->cert;
1019 }
1020
ne_ssl_clicert_name(const ne_ssl_client_cert * ccert)1021 const char *ne_ssl_clicert_name(const ne_ssl_client_cert *ccert)
1022 {
1023 return ccert->friendly_name;
1024 }
1025
ne_ssl_cert_read(const char * filename)1026 ne_ssl_certificate *ne_ssl_cert_read(const char *filename)
1027 {
1028 int ret;
1029 gnutls_datum data;
1030 gnutls_x509_crt x5;
1031
1032 if (read_to_datum(filename, &data))
1033 return NULL;
1034
1035 if (gnutls_x509_crt_init(&x5) != 0)
1036 return NULL;
1037
1038 ret = gnutls_x509_crt_import(x5, &data, GNUTLS_X509_FMT_PEM);
1039 ne_free(data.data);
1040 if (ret < 0) {
1041 gnutls_x509_crt_deinit(x5);
1042 return NULL;
1043 }
1044
1045 return populate_cert(ne_calloc(sizeof(struct ne_ssl_certificate_s)), x5);
1046 }
1047
ne_ssl_cert_write(const ne_ssl_certificate * cert,const char * filename)1048 int ne_ssl_cert_write(const ne_ssl_certificate *cert, const char *filename)
1049 {
1050 unsigned char buffer[10*1024];
1051 size_t len = sizeof buffer;
1052
1053 FILE *fp = fopen(filename, "w");
1054
1055 if (fp == NULL) return -1;
1056
1057 if (gnutls_x509_crt_export(cert->subject, GNUTLS_X509_FMT_PEM, buffer,
1058 &len) < 0) {
1059 fclose(fp);
1060 return -1;
1061 }
1062
1063 if (fwrite(buffer, len, 1, fp) != 1) {
1064 fclose(fp);
1065 return -1;
1066 }
1067
1068 if (fclose(fp) != 0)
1069 return -1;
1070
1071 return 0;
1072 }
1073
ne_ssl_cert_free(ne_ssl_certificate * cert)1074 void ne_ssl_cert_free(ne_ssl_certificate *cert)
1075 {
1076 gnutls_x509_crt_deinit(cert->subject);
1077 if (cert->identity) ne_free(cert->identity);
1078 if (cert->issuer) ne_ssl_cert_free(cert->issuer);
1079 ne_free(cert);
1080 }
1081
ne_ssl_cert_cmp(const ne_ssl_certificate * c1,const ne_ssl_certificate * c2)1082 int ne_ssl_cert_cmp(const ne_ssl_certificate *c1, const ne_ssl_certificate *c2)
1083 {
1084 char digest1[NE_SSL_DIGESTLEN], digest2[NE_SSL_DIGESTLEN];
1085
1086 if (ne_ssl_cert_digest(c1, digest1) || ne_ssl_cert_digest(c2, digest2)) {
1087 return -1;
1088 }
1089
1090 return strcmp(digest1, digest2);
1091 }
1092
1093 /* The certificate import/export format is the base64 encoding of the
1094 * raw DER; PEM without the newlines and wrapping. */
1095
ne_ssl_cert_import(const char * data)1096 ne_ssl_certificate *ne_ssl_cert_import(const char *data)
1097 {
1098 int ret;
1099 size_t len;
1100 unsigned char *der;
1101 gnutls_datum buffer = { NULL, 0 };
1102 gnutls_x509_crt x5;
1103
1104 if (gnutls_x509_crt_init(&x5) != 0)
1105 return NULL;
1106
1107 /* decode the base64 to get the raw DER representation */
1108 len = ne_unbase64(data, &der);
1109 if (len == 0) return NULL;
1110
1111 buffer.data = der;
1112 buffer.size = len;
1113
1114 ret = gnutls_x509_crt_import(x5, &buffer, GNUTLS_X509_FMT_DER);
1115 ne_free(der);
1116
1117 if (ret < 0) {
1118 gnutls_x509_crt_deinit(x5);
1119 return NULL;
1120 }
1121
1122 return populate_cert(ne_calloc(sizeof(struct ne_ssl_certificate_s)), x5);
1123 }
1124
ne_ssl_cert_export(const ne_ssl_certificate * cert)1125 char *ne_ssl_cert_export(const ne_ssl_certificate *cert)
1126 {
1127 unsigned char *der;
1128 size_t len = 0;
1129 char *ret;
1130
1131 /* find the length of the DER encoding. */
1132 if (gnutls_x509_crt_export(cert->subject, GNUTLS_X509_FMT_DER, NULL, &len) !=
1133 GNUTLS_E_SHORT_MEMORY_BUFFER) {
1134 return NULL;
1135 }
1136
1137 der = ne_malloc(len);
1138 if (gnutls_x509_crt_export(cert->subject, GNUTLS_X509_FMT_DER, der, &len)) {
1139 ne_free(der);
1140 return NULL;
1141 }
1142
1143 ret = ne_base64(der, len);
1144 ne_free(der);
1145 return ret;
1146 }
1147
ne_ssl_cert_digest(const ne_ssl_certificate * cert,char * digest)1148 int ne_ssl_cert_digest(const ne_ssl_certificate *cert, char *digest)
1149 {
1150 char sha1[20], *p;
1151 int j;
1152 size_t len = sizeof sha1;
1153
1154 if (gnutls_x509_crt_get_fingerprint(cert->subject, GNUTLS_DIG_SHA,
1155 sha1, &len) < 0)
1156 return -1;
1157
1158 for (j = 0, p = digest; j < 20; j++) {
1159 *p++ = NE_HEX2ASC((sha1[j] >> 4) & 0x0f);
1160 *p++ = NE_HEX2ASC(sha1[j] & 0x0f);
1161 *p++ = ':';
1162 }
1163
1164 *--p = '\0';
1165 return 0;
1166 }
1167
ne__ssl_init(void)1168 int ne__ssl_init(void)
1169 {
1170 #ifdef NE_HAVE_TS_SSL
1171 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
1172 #endif
1173 gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1174 return gnutls_global_init();
1175 }
1176
ne__ssl_exit(void)1177 void ne__ssl_exit(void)
1178 {
1179 /* No way to unregister the thread callbacks. Doomed. */
1180 #if LIBGNUTLS_VERSION_MAJOR > 1 || LIBGNUTLS_VERSION_MINOR > 3 \
1181 || (LIBGNUTLS_VERSION_MINOR == 3 && LIBGNUTLS_VERSION_PATCH >= 3)
1182 /* It's safe to call gnutls_global_deinit() here only with
1183 * gnutls >= 1.3., since older versions don't refcount and
1184 * doing so would prevent any other use of gnutls within
1185 * the process. */
1186 gnutls_global_deinit();
1187 #endif
1188 }
1189