1/*
2   neon test suite
3   Copyright (C) 2002-2009, Joe Orton <joe@manyfish.co.uk>
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19*/
20
21#include "config.h"
22
23#include <sys/types.h>
24
25#include <sys/stat.h>
26
27#ifdef HAVE_STDLIB_H
28#include <stdlib.h>
29#endif
30#ifdef HAVE_UNISTD_H
31#include <unistd.h>
32#endif
33
34#include "ne_request.h"
35#include "ne_socket.h"
36#include "ne_ssl.h"
37#include "ne_auth.h"
38
39#include "tests.h"
40#include "child.h"
41#include "utils.h"
42
43#ifndef NE_HAVE_SSL
44/* this file shouldn't be built if SSL is not enabled. */
45#error SSL not supported
46#endif
47
48#include "ne_pkcs11.h"
49
50#define SERVER_CERT "server.cert"
51#define CA2_SERVER_CERT "ca2server.pem"
52#define CA_CERT "ca/cert.pem"
53
54#define P12_PASSPHRASE "foobar"
55
56#define SERVER_DNAME "Neon QA Dept, Neon Hackers Ltd, " \
57                     "Cambridge, Cambridgeshire, GB"
58#define CACERT_DNAME "Random Dept, Neosign, Oakland, California, US"
59
60static char *srcdir = ".";
61static char *server_key = NULL;
62
63static ne_ssl_certificate *def_ca_cert = NULL, *def_server_cert;
64static ne_ssl_client_cert *def_cli_cert;
65
66static char *nul_cn_fn;
67
68static int check_dname(const ne_ssl_dname *dn, const char *expected,
69                       const char *which);
70
71/* Arguments for running the SSL server */
72struct ssl_server_args {
73    char *cert; /* the server cert to present. */
74    const char *response; /* the response to send. */
75    int numreqs; /* number of request/responses to handle over the SSL connection. */
76
77    /* client cert handling: */
78    int require_cc; /* require a client cert if non-NULL */
79    const char *ca_list; /* file of CA certs to verify client cert against */
80    int fail_silently; /* exit with success if handshake fails */
81
82    /* session caching: */
83    int cache; /* use the session cache if non-zero */
84    struct ssl_session {
85        unsigned char id[128];
86        size_t len;
87    } session;
88    int count; /* internal use. */
89
90    int use_ssl2; /* force use of SSLv2 only */
91
92    const char *key;
93};
94
95/* default response string if args->response is NULL */
96#define DEF_RESP "HTTP/1.0 200 OK\r\nContent-Length: 0\r\n\r\n"
97
98/* An SSL server inna bun. */
99static int ssl_server(ne_socket *sock, void *userdata)
100{
101    struct ssl_server_args *args = userdata;
102    int ret;
103    char buf[BUFSIZ];
104    const char *key;
105    static ne_ssl_context *ctx = NULL;
106
107    if (ctx == NULL) {
108        ctx = ne_ssl_context_create(args->use_ssl2 ? NE_SSL_CTX_SERVERv2
109                                    : NE_SSL_CTX_SERVER);
110    }
111
112    ONV(ctx == NULL, ("could not create SSL context"));
113
114    key = args->key ? args->key : server_key;
115    NE_DEBUG(NE_DBG_HTTP, "SSL server init with keypair (%s, %s).\n",
116             args->cert, key);
117
118    ONV(ne_ssl_context_keypair(ctx, args->cert, key),
119        ("failed to load server keypair: ..."));
120
121    if (args->require_cc && !args->ca_list) {
122        args->ca_list = CA_CERT;
123    }
124
125    ne_ssl_context_set_verify(ctx, args->require_cc,
126                              args->ca_list, args->ca_list);
127
128    ret = ne_sock_accept_ssl(sock, ctx);
129    if (ret && args->fail_silently) {
130        return 0;
131    }
132    ONV(ret, ("SSL accept failed: %s", ne_sock_error(sock)));
133
134    args->count++;
135
136    /* loop handling requests: */
137    do {
138        const char *response = args->response ? args->response : DEF_RESP;
139
140        ret = ne_sock_read(sock, buf, BUFSIZ - 1);
141        if (ret == NE_SOCK_CLOSED)
142            return 0; /* connection closed by parent; give up. */
143        ONV(ret < 0, ("SSL read failed (%d): %s", ret,
144                      ne_sock_error(sock)));
145
146        buf[ret] = '\0';
147
148        NE_DEBUG(NE_DBG_HTTP, "Request over SSL was: [%s]\n", buf);
149
150        if (strstr(buf, "Proxy-Authorization:") != NULL) {
151            NE_DEBUG(NE_DBG_HTTP, "Got Proxy-Auth header over SSL!\n");
152            response = "HTTP/1.1 500 Client Leaks Credentials\r\n"
153                "Content-Length: 0\r\n" "\r\n";
154        }
155
156        ONV(ne_sock_fullwrite(sock, response, strlen(response)),
157            ("SSL write failed: %s", ne_sock_error(sock)));
158
159    } while (--args->numreqs > 0);
160
161
162    if (args->cache) {
163        unsigned char sessid[128];
164        size_t len = sizeof sessid;
165
166        ONN("could not retrieve session ID",
167            ne_sock_sessid(sock, sessid, &len));
168
169#ifdef NE_DEBUGGING
170        {
171            char *b64 = ne_base64(sessid, len);
172            NE_DEBUG(NE_DBG_SSL, "Session id retrieved (%d): [%s]\n",
173                     args->count, b64);
174            ne_free(b64);
175        }
176#endif
177
178        if (args->count == 1) {
179            /* save the session. */
180            memcpy(args->session.id, sessid, len);
181            args->session.len = len;
182        } else {
183            /* Compare with stored session. */
184            ONN("cached session not used",
185                args->session.len != len
186                || memcmp(args->session.id, sessid, len));
187        }
188    }
189
190    return 0;
191}
192
193/* serve_ssl wrapper which ignores server failure and always succeeds */
194static int fail_serve(ne_socket *sock, void *ud)
195{
196    struct ssl_server_args args = {0};
197    args.cert = ud;
198    ssl_server(sock, &args);
199    return OK;
200}
201
202#define DEFSESS  (ne_session_create("https", "localhost", 7777))
203
204/* Run a request in the given session. */
205static int any_ssl_request(ne_session *sess, server_fn fn, void *server_ud,
206			   char *ca_cert,
207			   ne_ssl_verify_fn verify_fn, void *verify_ud)
208{
209    int ret;
210
211    if (ca_cert) {
212        ne_ssl_certificate *ca = ne_ssl_cert_read(ca_cert);
213        ONV(ca == NULL, ("could not load CA cert `%s'", ca_cert));
214        ne_ssl_trust_cert(sess, ca);
215        ne_ssl_cert_free(ca);
216    }
217
218    CALL(spawn_server(7777, fn, server_ud));
219
220    if (verify_fn)
221	ne_ssl_set_verify(sess, verify_fn, verify_ud);
222
223    ret = any_request(sess, "/foo");
224
225    CALL(await_server());
226
227    ONREQ(ret);
228
229    return OK;
230}
231
232static int init(void)
233{
234    /* take srcdir as argv[1]. */
235    if (test_argc > 1) {
236	srcdir = test_argv[1];
237	server_key = ne_concat(srcdir, "/server.key", NULL);
238    } else {
239	server_key = "server.key";
240    }
241
242    if (ne_sock_init()) {
243	t_context("could not initialize socket/SSL library.");
244	return FAILHARD;
245    }
246
247    def_ca_cert = ne_ssl_cert_read(CA_CERT);
248    if (def_ca_cert == NULL) {
249        t_context("couldn't load CA cert %s", CA_CERT);
250        return FAILHARD;
251    }
252
253    def_server_cert = ne_ssl_cert_read(SERVER_CERT);
254    if (def_server_cert == NULL) {
255        t_context("couldn't load server cert %s", SERVER_CERT);
256        return FAILHARD;
257    }
258
259    /* tests for the encrypted client cert, client.p12 */
260    def_cli_cert = ne_ssl_clicert_read("client.p12");
261    if (def_cli_cert == NULL) {
262        t_context("could not load client.p12");
263        return FAILHARD;
264    }
265
266    if (!ne_ssl_clicert_encrypted(def_cli_cert)) {
267        ne_ssl_clicert_free(def_cli_cert);
268        def_cli_cert = NULL;
269        t_context("client.p12 is not encrypted!?");
270        return FAIL;
271    }
272
273    if (ne_ssl_clicert_decrypt(def_cli_cert, P12_PASSPHRASE)) {
274        ne_ssl_clicert_free(def_cli_cert);
275        def_cli_cert = NULL;
276        t_context("failed to decrypt client.p12");
277        return FAIL;
278    }
279
280    nul_cn_fn = ne_concat(srcdir, "/nulcn.pem", NULL);
281
282    return OK;
283}
284
285/* just check the result codes of loading server certs. */
286static int load_server_certs(void)
287{
288    ne_ssl_certificate *cert;
289
290    cert = ne_ssl_cert_read("Makefile");
291    ONN("invalid CA cert file loaded successfully", cert != NULL);
292
293    cert = ne_ssl_cert_read("nonesuch.pem");
294    ONN("non-existent 'nonesuch.pem' loaded successfully", cert != NULL);
295
296    cert = ne_ssl_cert_read("ssigned.pem");
297    ONN("could not load ssigned.pem", cert == NULL);
298    ne_ssl_cert_free(cert);
299
300    return OK;
301}
302
303static int trust_default_ca(void)
304{
305    ne_session *sess = DEFSESS;
306    ne_ssl_trust_default_ca(sess);
307    ne_session_destroy(sess);
308    return OK;
309}
310
311#define CC_NAME "Just A Neon Client Cert"
312
313/* Tests for loading client certificates */
314static int load_client_cert(void)
315{
316    ne_ssl_client_cert *cc;
317    const ne_ssl_certificate *cert;
318    const char *name;
319
320    cc = ne_ssl_clicert_read("client.p12");
321    ONN("could not load client.p12", cc == NULL);
322    ONN("client.p12 not encrypted!?", !ne_ssl_clicert_encrypted(cc));
323    name = ne_ssl_clicert_name(cc);
324    if (name == NULL) {
325        t_warning("no friendly name given");
326    } else {
327        ONV(strcmp(name, CC_NAME), ("friendly name was %s not %s", name, CC_NAME));
328    }
329    ONN("failed to decrypt", ne_ssl_clicert_decrypt(cc, P12_PASSPHRASE));
330    ne_ssl_clicert_free(cc);
331
332    cc = ne_ssl_clicert_read("client.p12");
333    ONN("decrypted client.p12 with incorrect password!?",
334        ne_ssl_clicert_decrypt(cc, "barfoo") == 0);
335    ne_ssl_clicert_free(cc);
336
337    /* tests for the unencrypted client cert, client2.p12 */
338    cc = ne_ssl_clicert_read("unclient.p12");
339    ONN("could not load unencrypted cert unclient.p12", cc == NULL);
340    ONN("unencrypted cert marked encrypted?", ne_ssl_clicert_encrypted(cc));
341    cert = ne_ssl_clicert_owner(cc);
342    ONN("client cert had no certificate", cert == NULL);
343    CALL(check_dname(ne_ssl_cert_subject(cert),
344                     "Neon Client Cert, Neon Hackers Ltd, "
345                     "Cambridge, Cambridgeshire, GB",
346                     "client cert subject"));
347    CALL(check_dname(ne_ssl_cert_issuer(cert), CACERT_DNAME,
348                     "client cert issuer"));
349    ne_ssl_clicert_free(cc);
350
351    /* test for ccert without a friendly name, noclient.p12 */
352    cc = ne_ssl_clicert_read("noclient.p12");
353    ONN("could not load noclient.p12", cc == NULL);
354    name = ne_ssl_clicert_name(cc);
355    ONV(name != NULL, ("noclient.p12 had friendly name `%s'", name));
356    ne_ssl_clicert_free(cc);
357
358    /* test for ccert with a bundled CA. */
359    cc = ne_ssl_clicert_read("clientca.p12");
360    ONN("could not load clientca.p12", cc == NULL);
361    ONN("encrypted cert marked unencrypted?", !ne_ssl_clicert_encrypted(cc));
362    ONN("could not decrypt clientca.p12",
363        ne_ssl_clicert_decrypt(cc, P12_PASSPHRASE));
364    ne_ssl_clicert_free(cc);
365
366    /* test for ccert without a private key, nkclient.p12 */
367    cc = ne_ssl_clicert_read("nkclient.p12");
368    ONN("did not fail to load clicert without pkey", cc != NULL);
369
370    /* test for ccert without a cert, ncclient.p12 */
371    cc = ne_ssl_clicert_read("ncclient.p12");
372    ONN("did not fail to load clicert without cert", cc != NULL);
373
374    /* tests for loading bogus files. */
375    cc = ne_ssl_clicert_read("Makefile");
376    ONN("loaded Makefile as client cert!?", cc != NULL);
377
378    /* test for loading nonexistent file. */
379    cc = ne_ssl_clicert_read("nosuch.pem");
380    ONN("loaded nonexistent file as client cert!?", cc != NULL);
381
382    return OK;
383}
384
385/* Test that 'cert', which is signed by CA_CERT, is accepted
386 * unconditionaly. */
387static int accept_signed_cert_for_hostname(char *cert, const char *hostname)
388{
389    ne_session *sess = ne_session_create("https", hostname, 7777);
390    struct ssl_server_args args = {cert, 0};
391    /* no verify callback needed. */
392    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL));
393    ne_session_destroy(sess);
394    return OK;
395}
396
397
398static int accept_signed_cert(char *cert)
399{
400    return accept_signed_cert_for_hostname(cert, "localhost");
401}
402
403static int simple(void)
404{
405    return accept_signed_cert(SERVER_CERT);
406}
407
408/* Test for SSL operation when server uses SSLv2 */
409static int simple_sslv2(void)
410{
411#ifdef HAVE_OPENSSL
412    return SKIP; /* this is breaking with current SSL. */
413#else
414    ne_session *sess = ne_session_create("https", "localhost", 7777);
415    struct ssl_server_args args = {SERVER_CERT, 0};
416    args.use_ssl2 = 1;
417
418    ne_set_session_flag(sess, NE_SESSFLAG_SSLv2, 1);
419    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL));
420    ne_session_destroy(sess);
421    return OK;
422#endif
423}
424
425/* Serves using HTTP/1.0 get-till-EOF semantics. */
426static int serve_eof(ne_socket *sock, void *ud)
427{
428    struct ssl_server_args args = {0};
429
430    args.cert = ud;
431    args.response = "HTTP/1.0 200 OK\r\n"
432        "Connection: close\r\n"
433        "\r\n"
434        "This is a response body, like it or not.";
435
436    return ssl_server(sock, &args);
437}
438
439/* Test read-til-EOF behaviour with SSL. */
440static int simple_eof(void)
441{
442    ne_session *sess = DEFSESS;
443
444    CALL(any_ssl_request(sess, serve_eof, SERVER_CERT, CA_CERT, NULL, NULL));
445    ne_session_destroy(sess);
446    return OK;
447}
448
449static int intermediary(void)
450{
451    ne_session *sess = DEFSESS;
452    struct ssl_server_args args = {CA2_SERVER_CERT, 0};
453    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL));
454    ne_session_destroy(sess);
455    return OK;
456}
457
458static int empty_truncated_eof(void)
459{
460    ne_session *sess = DEFSESS;
461    struct ssl_server_args args = {0};
462
463    args.cert = SERVER_CERT;
464    args.response = "HTTP/1.0 200 OK\r\n" "\r\n";
465
466    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL));
467
468    ne_session_destroy(sess);
469    return OK;
470}
471
472/* Server function which just sends a string then EOF. */
473static int just_serve_string(ne_socket *sock, void *userdata)
474{
475    const char *str = userdata;
476    server_send(sock, str, strlen(str));
477    return 0;
478}
479
480/* test for the SSL negotiation failing. */
481static int fail_not_ssl(void)
482{
483    ne_session *sess = DEFSESS;
484    int ret;
485
486    CALL(spawn_server(7777, just_serve_string, "Hello, world.\n"));
487    ret = any_request(sess, "/bar");
488    CALL(await_server());
489
490    ONN("request did not fail", ret != NE_ERROR);
491
492    ne_session_destroy(sess);
493    return OK;
494}
495
496/* Server callback which handles a CONNECT request. */
497static int tunnel_server(ne_socket *sock, void *ud)
498{
499    struct ssl_server_args *args = ud;
500
501    CALL(discard_request(sock));
502
503    SEND_STRING(sock, "HTTP/1.1 200 OK\r\nServer: serve_tunnel\r\n\r\n");
504
505    return ssl_server(sock, args);
506}
507
508static int wildcard_match(void)
509{
510    ne_session *sess;
511    struct ssl_server_args args = {"wildcard.cert", 0};
512
513    sess = ne_session_create("https", "anything.example.com", 443);
514    ne_session_proxy(sess, "localhost", 7777);
515
516    CALL(any_ssl_request(sess, tunnel_server, &args, CA_CERT, NULL, NULL));
517    ne_session_destroy(sess);
518
519    return OK;
520}
521
522static int wildcard_match_altname(void)
523{
524    ne_session *sess;
525    struct ssl_server_args args = {"altname9.cert", 0};
526
527    sess = ne_session_create("https", "anything.example.com", 443);
528    ne_session_proxy(sess, "localhost", 7777);
529
530    CALL(any_ssl_request(sess, tunnel_server, &args, CA_CERT, NULL, NULL));
531    ne_session_destroy(sess);
532
533    return OK;
534}
535
536/* Check that hostname comparisons are not cases-sensitive. */
537static int caseless_match(void)
538{
539    return accept_signed_cert("caseless.cert");
540}
541
542/* Test that the subjectAltName extension has precedence over the
543 * commonName attribute */
544static int subject_altname(void)
545{
546    return accept_signed_cert("altname1.cert");
547}
548
549/* tests for multiple altNames. */
550static int two_subject_altname(void)
551{
552    return accept_signed_cert("altname2.cert");
553}
554
555static int two_subject_altname2(void)
556{
557    return accept_signed_cert("altname3.cert");
558}
559
560/* Test that a subject altname with *only* an eMail entry is
561 * ignored, and the commonName is used instead. */
562static int notdns_altname(void)
563{
564    return accept_signed_cert("altname4.cert");
565}
566
567static int ipaddr_altname(void)
568{
569    return accept_signed_cert_for_hostname("altname5.cert", "127.0.0.1");
570}
571
572static int uri_altname(void)
573{
574    return accept_signed_cert_for_hostname("altname7.cert", "localhost");
575}
576
577/* test that the *most specific* commonName attribute is used. */
578static int multi_commonName(void)
579{
580    return accept_signed_cert("twocn.cert");
581}
582
583/* regression test for neon <= 0.23.4 where if commonName was the first
584 * RDN in the subject DN, it was ignored. */
585static int commonName_first(void)
586{
587    return accept_signed_cert("cnfirst.cert");
588}
589
590static int check_dname(const ne_ssl_dname *dn, const char *expected,
591                       const char *which)
592{
593    char *dname;
594
595    ONV(dn == NULL, ("certificate %s dname was NULL", which));
596
597    dname = ne_ssl_readable_dname(dn);
598
599    NE_DEBUG(NE_DBG_SSL, "Got dname `%s', expecting `%s'\n", dname, expected);
600
601    ONV(strcmp(dname, expected),
602        ("certificate %s dname was `%s' not `%s'", which, dname, expected));
603
604    ne_free(dname);
605
606    return 0;
607}
608
609/* Check that the readable subject issuer dnames of 'cert' match
610 * 'subject' and 'issuer' (if non-NULL). */
611static int check_cert_dnames(const ne_ssl_certificate *cert,
612                             const char *subject, const char *issuer)
613{
614    ONN("no server certificate presented", cert == NULL);
615    CALL(check_dname(ne_ssl_cert_subject(cert), subject, "subject"));
616    return issuer ? check_dname(ne_ssl_cert_issuer(cert), issuer, "issuer") : OK;
617}
618
619/* Verify callback which checks that the certificate presented has the
620 * predetermined subject and issuer DN (as per makekeys.sh). */
621static int check_cert(void *userdata, int fs, const ne_ssl_certificate *cert)
622{
623    int *ret = userdata;
624
625    if (check_cert_dnames(cert, SERVER_DNAME, CACERT_DNAME) == FAIL)
626        *ret = -1;
627    else
628        *ret = 1;
629
630    return 0;
631}
632
633/* Check that certificate attributes are passed correctly. */
634static int parse_cert(void)
635{
636    ne_session *sess = DEFSESS;
637    int ret = 0;
638    struct ssl_server_args args = {SERVER_CERT, 0};
639
640    /* don't give a CA cert; should force the verify callback to be
641     * used. */
642    CALL(any_ssl_request(sess, ssl_server, &args, NULL,
643			 check_cert, &ret));
644    ne_session_destroy(sess);
645
646    ONN("cert verification never called", ret == 0);
647
648    if (ret == -1)
649	return FAIL;
650
651    return OK;
652}
653
654#define WRONGCN_DNAME "Bad Hostname Department, Neon Hackers Ltd, " \
655    "Cambridge, Cambridgeshire, GB"
656
657/* Check the certificate chain presented against known dnames. */
658static int check_chain(void *userdata, int fs, const ne_ssl_certificate *cert)
659{
660    int *ret = userdata;
661
662    if (check_cert_dnames(cert, WRONGCN_DNAME, CACERT_DNAME) == FAIL) {
663        *ret = -1;
664        return 0;
665    }
666
667    cert = ne_ssl_cert_signedby(cert);
668    if (cert == NULL) {
669        t_context("no CA cert in chain");
670        *ret = -1;
671        return 0;
672    }
673
674    if (check_cert_dnames(cert, CACERT_DNAME, CACERT_DNAME) == FAIL) {
675        *ret = -1;
676        return 0;
677    }
678
679    *ret = 1;
680    return 0;
681}
682
683/* Check that certificate attributes are passed correctly. */
684static int parse_chain(void)
685{
686    ne_session *sess = DEFSESS;
687    int ret = 0;
688    struct ssl_server_args args = {"wrongcn.cert", 0};
689
690    args.ca_list = CA_CERT;
691
692    /* The cert is signed by the CA but has a CN mismatch, so will
693     * force the verification callback to be invoked. */
694    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT,
695			 check_chain, &ret));
696    ne_session_destroy(sess);
697
698    ONN("cert verification never called", ret == 0);
699
700    if (ret == -1)
701	return FAIL;
702
703    return OK;
704}
705
706
707static int count_vfy(void *userdata, int fs, const ne_ssl_certificate *c)
708{
709    int *count = userdata;
710    (*count)++;
711    return 0;
712}
713
714static int no_verify(void)
715{
716    ne_session *sess = DEFSESS;
717    int count = 0;
718    struct ssl_server_args args = {SERVER_CERT, 0};
719
720    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, count_vfy,
721			 &count));
722
723    ONN("verify callback called unnecessarily", count != 0);
724
725    ne_session_destroy(sess);
726
727    return OK;
728}
729
730static int cache_verify(void)
731{
732    ne_session *sess = DEFSESS;
733    int ret, count = 0;
734    struct ssl_server_args args = {SERVER_CERT, 0};
735
736    /* force verify cert. */
737    ret = any_ssl_request(sess, ssl_server, &args, NULL, count_vfy,
738			  &count);
739
740    CALL(spawn_server(7777, ssl_server, &args));
741    ret = any_request(sess, "/foo2");
742    CALL(await_server());
743
744    ONV(count != 1,
745	("verify callback result not cached: called %d times", count));
746
747    ne_session_destroy(sess);
748
749    return OK;
750}
751
752/* Copy failures into *userdata, and fail verification. */
753static int get_failures(void *userdata, int fs, const ne_ssl_certificate *c)
754{
755    int *out = userdata;
756    *out = fs;
757    return -1;
758}
759
760/* Helper function: run a request using the given self-signed server
761 * certificate, and expect the request to fail with the given
762 * verification failure flags. */
763static int fail_ssl_request_with_error2(char *cert, char *key, char *cacert,
764                                        const char *host, const char *fakehost,
765                                        const char *msg, int failures,
766                                        const char *errstr)
767{
768    ne_session *sess = ne_session_create("https", host, 7777);
769    int gotf = 0, ret;
770    struct ssl_server_args args = {0};
771    ne_sock_addr *addr;
772    const ne_inet_addr *list[1];
773
774    if (fakehost) {
775        addr = ne_addr_resolve(fakehost, 0);
776
777        ONV(ne_addr_result(addr),
778            ("fake hostname lookup failed for %s", fakehost));
779
780        list[0] = ne_addr_first(addr);
781
782        ne_set_addrlist(sess, list, 1);
783    }
784
785    args.cert = cert;
786    args.key = key;
787    args.fail_silently = 1;
788
789    ret = any_ssl_request(sess, ssl_server, &args, cacert,
790			  get_failures, &gotf);
791
792    ONV(gotf == 0,
793	("no error in verification callback; error string: %s",
794	 ne_get_error(sess)));
795
796    ONV(gotf & ~NE_SSL_FAILMASK,
797	("verification flags %x outside mask %x", gotf, NE_SSL_FAILMASK));
798
799    /* check the failure flags were as expected. */
800    ONV(failures != gotf,
801	("verification flags were %d not %d", gotf, failures));
802
803    /* and check that the request was failed too. */
804    ONV(ret == NE_OK, ("%s", msg));
805
806    ONV(errstr && strstr(ne_get_error(sess), errstr) == NULL,
807        ("unexpected failure message '%s', wanted '%s'",
808         ne_get_error(sess), errstr));
809
810    ne_session_destroy(sess);
811
812    return OK;
813}
814
815/* Helper function: run a request using the given self-signed server
816 * certificate, and expect the request to fail with the given
817 * verification failure flags. */
818static int fail_ssl_request_with_error(char *cert, char *cacert, const char *host,
819                                       const char *msg, int failures,
820                                       const char *errstr)
821{
822    return fail_ssl_request_with_error2(cert, NULL, cacert, host, NULL,
823                                        msg, failures, errstr);
824}
825
826
827/* Helper function: run a request using the given self-signed server
828 * certificate, and expect the request to fail with the given
829 * verification failure flags. */
830static int fail_ssl_request(char *cert, char *cacert, const char *host,
831			    const char *msg, int failures)
832{
833    return fail_ssl_request_with_error(cert, cacert, host, msg, failures,
834                                       NULL);
835}
836
837/* Note that the certs used for fail_* are mostly self-signed, so the
838 * cert is passed as CA cert and server cert to fail_ssl_request. */
839
840/* Check that a certificate with the incorrect commonName attribute is
841 * flagged as such. */
842static int fail_wrongCN(void)
843{
844    return fail_ssl_request_with_error("wrongcn.cert", "ca/cert.pem", "localhost",
845                                       "certificate with incorrect CN was accepted",
846                                       NE_SSL_IDMISMATCH,
847                                       "certificate issued for a different hostname");
848
849}
850
851#define SRCDIR(s) ne_concat(srcdir, "/" s, NULL)
852
853static int fail_nul_cn(void)
854{
855    char *key = SRCDIR("nulsrv.key"), *ca = SRCDIR("nulca.pem");
856    CALL(fail_ssl_request_with_error2(nul_cn_fn, key, ca,
857                                      "www.bank.com", "localhost",
858                                      "certificate with incorrect CN was accepted",
859                                      NE_SSL_IDMISMATCH,
860                                      "certificate issued for a different hostname"));
861    ne_free(key);
862    ne_free(ca);
863    return OK;
864}
865
866static int fail_nul_san(void)
867{
868    char *cert = SRCDIR("nulsan.pem"), *key = SRCDIR("nulsrv.key"),
869        *ca = SRCDIR("nulca.pem");
870    CALL(fail_ssl_request_with_error2(cert, key, ca,
871                                      "www.bank.com", "localhost",
872                                      "certificate with incorrect CN was accepted",
873                                      NE_SSL_IDMISMATCH,
874                                      "certificate issued for a different hostname"));
875    ne_free(cert);
876    ne_free(key);
877    ne_free(ca);
878    return OK;
879}
880
881/* Check that an expired certificate is flagged as such. */
882static int fail_expired(void)
883{
884    char *c = ne_concat(srcdir, "/expired.pem", NULL);
885    CALL(fail_ssl_request_with_error(c, c,  "localhost",
886                                     "expired certificate was accepted",
887                                     NE_SSL_EXPIRED,
888                                     "certificate has expired"));
889    ne_free(c);
890    return OK;
891}
892
893static int fail_notvalid(void)
894{
895    char *c = ne_concat(srcdir, "/notvalid.pem", NULL);
896    CALL(fail_ssl_request_with_error(c, c,  "localhost",
897                                     "not yet valid certificate was accepted",
898                                     NE_SSL_NOTYETVALID,
899                                     "certificate is not yet valid"));
900    ne_free(c);
901    return OK;
902}
903
904/* Check that a server cert with a random issuer and self-signed cert
905 * fail with UNTRUSTED. */
906static int fail_untrusted_ca(void)
907{
908    return fail_ssl_request_with_error("server.cert", NULL, "localhost",
909                                       "untrusted CA.", NE_SSL_UNTRUSTED,
910                                       "issuer is not trusted");
911}
912
913static int fail_self_signed(void)
914{
915    return fail_ssl_request("ssigned.pem", NULL,  "localhost",
916                            "self-signed cert", NE_SSL_UNTRUSTED);
917}
918
919/* Test for failure when a server cert is presented which has no
920 * commonName (and no alt names either). */
921static int fail_missing_CN(void)
922{
923    ne_session *sess = DEFSESS;
924
925    ONN("accepted server cert with missing commonName",
926        any_ssl_request(sess, fail_serve, "missingcn.cert", SERVER_CERT,
927                        NULL, NULL) == NE_OK);
928
929    ONV(strstr(ne_get_error(sess), "missing commonName") == NULL,
930        ("unexpected session error `%s'", ne_get_error(sess)));
931
932    ne_session_destroy(sess);
933    return OK;
934}
935
936/* test for a bad ipAddress altname */
937static int fail_bad_ipaltname(void)
938{
939    return fail_ssl_request("altname6.cert", CA_CERT, "127.0.0.1",
940                            "bad IP altname cert", NE_SSL_IDMISMATCH);
941}
942
943/* test for a ipAddress which matched against the hostname as per neon
944 * 0.24 behaviour. */
945static int fail_host_ipaltname(void)
946{
947    return fail_ssl_request("altname5.cert", CA_CERT, "localhost",
948                            "bad IP altname cert", NE_SSL_IDMISMATCH);
949}
950
951static int fail_bad_urialtname(void)
952{
953    return fail_ssl_request("altname8.cert", CA_CERT, "localhost",
954                            "bad URI altname cert", NE_SSL_IDMISMATCH);
955}
956
957static int fail_wildcard(void)
958{
959    return fail_ssl_request("altname9.cert", CA_CERT, "localhost",
960                            "subjaltname not honored", NE_SSL_IDMISMATCH);
961}
962
963static int fail_wildcard_ip(void)
964{
965    return fail_ssl_request("wildip.cert", CA_CERT, "127.0.0.1",
966                            "wildcard IP", NE_SSL_IDMISMATCH);
967}
968
969static int fail_ca_expired(void)
970{
971    return fail_ssl_request_with_error("ca1server.cert", "ca1/cert.pem",
972                                       "localhost", "issuer ca expired",
973                                       NE_SSL_BADCHAIN,
974                                       "bad certificate chain");
975}
976
977static int fail_ca_notyetvalid(void)
978{
979    return fail_ssl_request("ca3server.cert", "ca3/cert.pem", "localhost",
980                            "issuer ca not yet valid", NE_SSL_BADCHAIN);
981}
982
983/* Test that the SSL session is cached across connections. */
984static int session_cache(void)
985{
986    struct ssl_server_args args = {0};
987    ne_session *sess = ne_session_create("https", "localhost", 7777);
988
989    args.cert = SERVER_CERT;
990    args.cache = 1;
991
992    ne_ssl_trust_cert(sess, def_ca_cert);
993
994    /* have spawned server listen for several connections. */
995    CALL(spawn_server_repeat(7777, ssl_server, &args, 4));
996
997    ONREQ(any_request(sess, "/req1"));
998    ONREQ(any_request(sess, "/req2"));
999    ne_session_destroy(sess);
1000    /* server should still be waiting for connections: if not,
1001     * something went wrong. */
1002    ONN("error from child", dead_server());
1003    /* now get rid of it. */
1004    reap_server();
1005
1006    return OK;
1007}
1008
1009/* Callback for client_cert_provider; takes a c. cert as userdata and
1010 * registers it. */
1011static void ccert_provider(void *userdata, ne_session *sess,
1012                           const ne_ssl_dname *const *dns, int dncount)
1013{
1014    const ne_ssl_client_cert *cc = userdata;
1015    ne_ssl_set_clicert(sess, cc);
1016}
1017
1018/* Test that the on-demand client cert provider callback is used. */
1019static int client_cert_provided(void)
1020{
1021    ne_session *sess = DEFSESS;
1022    ne_ssl_client_cert *cc;
1023    struct ssl_server_args args = {SERVER_CERT, NULL};
1024
1025    args.require_cc = 1;
1026
1027    cc = ne_ssl_clicert_read("client.p12");
1028    ONN("could not load client.p12", cc == NULL);
1029    ONN("could not decrypt client.p12",
1030        ne_ssl_clicert_decrypt(cc, P12_PASSPHRASE));
1031
1032    ne_ssl_provide_clicert(sess, ccert_provider, cc);
1033    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT,
1034                         NULL, NULL));
1035
1036    ne_session_destroy(sess);
1037    ne_ssl_clicert_free(cc);
1038    return OK;
1039}
1040
1041#define DN_COUNT 5
1042
1043static void cc_check_dnames(void *userdata, ne_session *sess,
1044                            const ne_ssl_dname *const *dns, int dncount)
1045{
1046    int n, *ret = userdata;
1047    static const char *expected[DN_COUNT] = {
1048        CACERT_DNAME,
1049        "First Random CA, CAs Ltd., Lincoln, Lincolnshire, GB",
1050        "Second Random CA, CAs Ltd., Falmouth, Cornwall, GB",
1051        "Third Random CA, CAs Ltd., Ipswich, Suffolk, GB",
1052        "Fourth Random CA, CAs Ltd., Norwich, Norfolk, GB"
1053    };
1054
1055    ne_ssl_set_clicert(sess, def_cli_cert);
1056
1057    if (dncount != DN_COUNT) {
1058        t_context("dname count was %d not %d", dncount,
1059                  DN_COUNT);
1060        *ret = -1;
1061        return;
1062    }
1063
1064    for (n = 0; n < DN_COUNT; n++) {
1065        char which[5];
1066
1067        sprintf(which, "%d", n);
1068
1069        if (check_dname(dns[n], expected[n], which) == FAIL) {
1070            *ret = -1;
1071            return;
1072        }
1073    }
1074
1075    *ret = 1;
1076}
1077
1078/* Test for the list of acceptable dnames sent to the client. */
1079static int cc_provided_dnames(void)
1080{
1081    int check = 0;
1082    ne_session *sess = DEFSESS;
1083    struct ssl_server_args args = {SERVER_CERT, NULL};
1084
1085    args.require_cc = 1;
1086    args.ca_list = "calist.pem";
1087
1088    PRECOND(def_cli_cert);
1089
1090    ne_ssl_provide_clicert(sess, cc_check_dnames, &check);
1091
1092    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL));
1093
1094    ne_session_destroy(sess);
1095
1096    ONN("provider function not called", check == 0);
1097
1098    return (check == -1) ? FAIL : OK;
1099}
1100
1101/* Tests use of a client certificate. */
1102static int client_cert_pkcs12(void)
1103{
1104    ne_session *sess = DEFSESS;
1105    struct ssl_server_args args = {SERVER_CERT, NULL};
1106
1107    args.require_cc = 1;
1108
1109    PRECOND(def_cli_cert);
1110
1111    ne_ssl_set_clicert(sess, def_cli_cert);
1112    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL));
1113
1114    ne_session_destroy(sess);
1115    return OK;
1116}
1117
1118/* Test use of a PKCS#12 cert with an embedded CA cert - fails with <=
1119 * 0.28.3 in GnuTLS build. */
1120static int client_cert_ca(void)
1121{
1122    ne_session *sess = DEFSESS;
1123    struct ssl_server_args args = {SERVER_CERT, NULL};
1124    ne_ssl_client_cert *cc;
1125
1126    args.require_cc = 1;
1127
1128    cc = ne_ssl_clicert_read("clientca.p12");
1129    ONN("could not load clientca.p12", cc == NULL);
1130    ONN("encrypted cert marked unencrypted?", !ne_ssl_clicert_encrypted(cc));
1131    ONN("could not decrypt clientca.p12",
1132        ne_ssl_clicert_decrypt(cc, P12_PASSPHRASE));
1133
1134    ne_ssl_set_clicert(sess, cc);
1135    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL));
1136
1137    ne_ssl_clicert_free(cc);
1138
1139    ne_session_destroy(sess);
1140    return OK;
1141}
1142
1143/* Tests use of an unencrypted client certificate. */
1144static int ccert_unencrypted(void)
1145{
1146    ne_session *sess = DEFSESS;
1147    ne_ssl_client_cert *ccert;
1148    struct ssl_server_args args = {SERVER_CERT, NULL};
1149
1150    args.require_cc = 1;
1151
1152    ccert = ne_ssl_clicert_read("unclient.p12");
1153    ONN("could not load unclient.p12", ccert == NULL);
1154    ONN("unclient.p12 was encrypted", ne_ssl_clicert_encrypted(ccert));
1155
1156    ne_ssl_set_clicert(sess, ccert);
1157    CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL));
1158
1159    ne_ssl_clicert_free(ccert);
1160    ne_session_destroy(sess);
1161    return OK;
1162}
1163
1164#define NOCERT_MESSAGE "client certificate was requested"
1165
1166/* Tests for useful error message if a handshake fails where a client
1167 * cert was requested. */
1168static int no_client_cert(void)
1169{
1170    ne_session *sess = DEFSESS;
1171    struct ssl_server_args args = {SERVER_CERT, NULL};
1172    int ret;
1173
1174    args.require_cc = 1;
1175    args.fail_silently = 1;
1176
1177    ne_ssl_trust_cert(sess, def_ca_cert);
1178
1179    CALL(spawn_server(7777, ssl_server, &args));
1180
1181    ret = any_request(sess, "/failme");
1182
1183    ONV(ret != NE_ERROR,
1184        ("unexpected result %d: %s", ret, ne_get_error(sess)));
1185
1186    ONV(strstr(ne_get_error(sess), NOCERT_MESSAGE) == NULL,
1187        ("error message was '%s', missing '%s'",
1188         ne_get_error(sess), NOCERT_MESSAGE));
1189
1190    reap_server();
1191
1192    ne_session_destroy(sess);
1193    return OK;
1194}
1195
1196/* non-zero if a server auth header was received */
1197static int got_server_auth;
1198
1199/* Utility function which accepts the 'tunnel' header. */
1200static void tunnel_header(char *value)
1201{
1202    got_server_auth = 1;
1203}
1204
1205/* Server which acts as a proxy accepting a CONNECT request. */
1206static int serve_tunnel(ne_socket *sock, void *ud)
1207{
1208    struct ssl_server_args *args = ud;
1209
1210    /* check for a server auth function */
1211    want_header = "Authorization";
1212    got_header = tunnel_header;
1213    got_server_auth = 0;
1214
1215    /* give the plaintext tunnel reply, acting as the proxy */
1216    CALL(discard_request(sock));
1217
1218    if (got_server_auth) {
1219        SEND_STRING(sock, "HTTP/1.1 500 Leaked Server Auth Creds\r\n"
1220                    "Content-Length: 0\r\n" "Server: serve_tunnel\r\n\r\n");
1221        return 0;
1222    } else {
1223        SEND_STRING(sock, "HTTP/1.1 200 OK\r\nServer: serve_tunnel\r\n\r\n");
1224        return ssl_server(sock, args);
1225    }
1226}
1227
1228/* neon versions <= 0.21.2 segfault here because ne_sock_close would
1229 * be called twice on the socket after the server cert verification
1230 * fails. */
1231static int fail_tunnel(void)
1232{
1233    ne_session *sess = ne_session_create("https", "example.com", 443);
1234    struct ssl_server_args args = {SERVER_CERT, NULL};
1235
1236    ne_session_proxy(sess, "localhost", 7777);
1237
1238    ONN("server cert verification didn't fail",
1239	any_ssl_request(sess, serve_tunnel, &args, CA_CERT,
1240			NULL, NULL) != NE_ERROR);
1241
1242    ne_session_destroy(sess);
1243    return OK;
1244}
1245
1246static int proxy_tunnel(void)
1247{
1248    ne_session *sess = ne_session_create("https", "localhost", 443);
1249    struct ssl_server_args args = {SERVER_CERT, NULL};
1250
1251    ne_session_proxy(sess, "localhost", 7777);
1252
1253    /* CA cert is trusted, so no verify callback should be needed. */
1254    CALL(any_ssl_request(sess, serve_tunnel, &args, CA_CERT,
1255			 NULL, NULL));
1256
1257    ne_session_destroy(sess);
1258    return OK;
1259}
1260
1261#define RESP_0LENGTH "HTTP/1.1 200 OK\r\n" "Content-Length: 0\r\n" "\r\n"
1262
1263/* a tricky test which requires spawning a second server process in
1264 * time for a new connection after a 407. */
1265static int apt_post_send(ne_request *req, void *ud, const ne_status *st)
1266{
1267    int *code = ud;
1268    if (st->code == *code) {
1269        struct ssl_server_args args = {SERVER_CERT, NULL};
1270
1271        if (*code == 407) args.numreqs = 2;
1272        args.response = RESP_0LENGTH;
1273
1274        NE_DEBUG(NE_DBG_HTTP, "Got challenge, awaiting server...\n");
1275        CALL(await_server());
1276        NE_DEBUG(NE_DBG_HTTP, "Spawning proper tunnel server...\n");
1277        /* serve *two* 200 OK responses. */
1278        CALL(spawn_server(7777, serve_tunnel, &args));
1279        NE_DEBUG(NE_DBG_HTTP, "Spawned.\n");
1280    }
1281    return OK;
1282}
1283
1284static int apt_creds(void *userdata, const char *realm, int attempt,
1285                     char *username, char *password)
1286{
1287    strcpy(username, "foo");
1288    strcpy(password, "bar");
1289    return attempt;
1290}
1291
1292/* Test for using SSL over a CONNECT tunnel via a proxy server which
1293 * requires authentication.  Broke briefly between 0.23.x and
1294 * 0.24.0. */
1295static int auth_proxy_tunnel(void)
1296{
1297    ne_session *sess = ne_session_create("https", "localhost", 443);
1298    int ret, code = 407;
1299
1300    ne_session_proxy(sess, "localhost", 7777);
1301    ne_hook_post_send(sess, apt_post_send, &code);
1302    ne_set_proxy_auth(sess, apt_creds, NULL);
1303    ne_ssl_trust_cert(sess, def_ca_cert);
1304
1305    CALL(spawn_server(7777, single_serve_string,
1306                      "HTTP/1.0 407 I WANT MORE BISCUITS\r\n"
1307                      "Proxy-Authenticate: Basic realm=\"bigbluesea\"\r\n"
1308                      "Connection: close\r\n" "\r\n"));
1309
1310    /* run two requests over the tunnel. */
1311    ret = any_2xx_request(sess, "/foobar");
1312    if (!ret) ret = any_2xx_request(sess, "/foobar2");
1313    CALL(await_server());
1314    CALL(ret);
1315
1316    ne_session_destroy(sess);
1317    return 0;
1318}
1319
1320/* Regression test to check that server credentials aren't sent to the
1321 * proxy in a CONNECT request. */
1322static int auth_tunnel_creds(void)
1323{
1324    ne_session *sess = ne_session_create("https", "localhost", 443);
1325    int ret, code = 401;
1326    struct ssl_server_args args = {SERVER_CERT, 0};
1327
1328    ne_session_proxy(sess, "localhost", 7777);
1329    ne_hook_post_send(sess, apt_post_send, &code);
1330    ne_set_server_auth(sess, apt_creds, NULL);
1331    ne_ssl_trust_cert(sess, def_ca_cert);
1332
1333    args.response = "HTTP/1.1 401 I want a Shrubbery\r\n"
1334        "WWW-Authenticate: Basic realm=\"bigredocean\"\r\n"
1335        "Server: Python\r\n" "Content-Length: 0\r\n" "\r\n";
1336
1337    CALL(spawn_server(7777, serve_tunnel, &args));
1338    ret = any_2xx_request(sess, "/foobar");
1339    CALL(await_server());
1340    CALL(ret);
1341
1342    ne_session_destroy(sess);
1343    return OK;
1344}
1345
1346static int auth_tunnel_fail(void)
1347{
1348    ne_session *sess = ne_session_create("https", "localhost", 443);
1349    int ret;
1350
1351    CALL(spawn_server(7777, single_serve_string,
1352                      "HTTP/1.1 407 Nyaaaaah\r\n"
1353                      "Proxy-Authenticate: GaBoogle\r\n"
1354                      "Connection: close\r\n"
1355                      "\r\n"));
1356
1357    ne_session_proxy(sess, "localhost", 7777);
1358
1359    ne_set_proxy_auth(sess, apt_creds, NULL);
1360
1361    ret = any_request(sess, "/bar");
1362    ONV(ret != NE_PROXYAUTH, ("bad error code for tunnel failure: %d", ret));
1363
1364    ONV(strstr(ne_get_error(sess), "GaBoogle") == NULL,
1365        ("bad error string for tunnel failure: %s", ne_get_error(sess)));
1366
1367    ne_session_destroy(sess);
1368
1369    return await_server();
1370}
1371
1372/* compare against known digest of notvalid.pem.  Via:
1373 *   $ openssl x509 -fingerprint -sha1 -noout -in notvalid.pem */
1374#define THE_DIGEST "cf:5c:95:93:76:c6:3c:01:8b:62:" \
1375                   "b1:6f:f7:7f:42:32:ac:e6:69:1b"
1376
1377static int cert_fingerprint(void)
1378{
1379    char *fn = ne_concat(srcdir, "/notvalid.pem", NULL);
1380    ne_ssl_certificate *cert = ne_ssl_cert_read(fn);
1381    char digest[60];
1382
1383    ne_free(fn);
1384
1385    ONN("could not load notvalid.pem", cert == NULL);
1386
1387    ONN("failed to digest", ne_ssl_cert_digest(cert, digest));
1388    ne_ssl_cert_free(cert);
1389
1390    ONV(strcmp(digest, THE_DIGEST),
1391        ("digest was %s not %s", digest, THE_DIGEST));
1392
1393    return OK;
1394}
1395
1396/* verify that identity of certificate in filename 'fname' is 'identity' */
1397static int check_identity(const char *fname, const char *identity)
1398{
1399    ne_ssl_certificate *cert = ne_ssl_cert_read(fname);
1400    const char *id;
1401
1402    ONV(cert == NULL, ("could not read cert `%s'", fname));
1403
1404    id = ne_ssl_cert_identity(cert);
1405
1406    if (identity) {
1407        ONV(id == NULL, ("certificate `%s' had no identity", fname));
1408        ONV(strcmp(id, identity),
1409            ("certificate `%s' had identity `%s' not `%s'", fname,
1410             id, identity));
1411    } else {
1412        ONV(id != NULL, ("certificate `%s' had identity `%s' (expected none)",
1413                         fname, id));
1414    }
1415
1416    ne_ssl_cert_free(cert);
1417    return OK;
1418}
1419
1420/* check certificate identities. */
1421static int cert_identities(void)
1422{
1423    static const struct {
1424        const char *fname, *identity;
1425    } certs[] = {
1426        { "ssigned.pem", "localhost" },
1427        { "twocn.cert", "localhost" },
1428        { "altname1.cert", "localhost" },
1429        { "altname2.cert", "nohost.example.com" },
1430        { "altname4.cert", "localhost" },
1431        { "ca4.pem", "fourth.example.com" },
1432        { "altname8.cert", "http://nohost.example.com/" },
1433        { NULL, NULL }
1434    };
1435    int n;
1436
1437    for (n = 0; certs[n].fname != NULL; n++)
1438        CALL(check_identity(certs[n].fname, certs[n].identity));
1439
1440    return OK;
1441}
1442
1443static int nulcn_identity(void)
1444{
1445    ne_ssl_certificate *cert = ne_ssl_cert_read(nul_cn_fn);
1446    const char *id, *expected = "www.bank.com\\x00.badguy.com";
1447
1448    ONN("could not read nulcn.pem", cert == NULL);
1449
1450    id = ne_ssl_cert_identity(cert);
1451
1452    ONV(id != NULL
1453        && strcmp(id, expected) != 0,
1454        ("certificate `nulcn.pem' had identity `%s' not `%s'",
1455         id, expected));
1456
1457    ne_ssl_cert_free(cert);
1458    return OK;
1459}
1460
1461static int check_validity(const char *fname,
1462                          const char *from, const char *until)
1463{
1464    char actfrom[NE_SSL_VDATELEN], actuntil[NE_SSL_VDATELEN];
1465    ne_ssl_certificate *cert;
1466
1467    cert = ne_ssl_cert_read(fname);
1468    ONV(cert == NULL, ("could not load cert `%s'", fname));
1469
1470    /* cover all calling combos for nice coverage analysis */
1471    ne_ssl_cert_validity(cert, NULL, NULL);
1472    ne_ssl_cert_validity(cert, actfrom, NULL);
1473    ne_ssl_cert_validity(cert, NULL, actuntil);
1474    ne_ssl_cert_validity(cert, actfrom, actuntil);
1475
1476    ONV(strcmp(actfrom, from),
1477        ("%s: start time was `%s' not `%s'", fname, actfrom, from));
1478
1479    ONV(strcmp(actuntil, until),
1480        ("%s: end time was `%s' not `%s'", fname, actuntil, until));
1481
1482    ne_ssl_cert_free(cert);
1483    return OK;
1484}
1485
1486/* ceritificate validity times. */
1487static int cert_validity(void)
1488{
1489    char *cert = ne_concat(srcdir, "/expired.pem", NULL);
1490    CALL(check_validity(cert,
1491                        "Mon, 21 Jan 2002 20:39:04 GMT", "Thu, 31 Jan 2002 20:39:04 GMT"));
1492    ne_free(cert);
1493    cert = ne_concat(srcdir, "/notvalid.pem", NULL);
1494    CALL(check_validity(cert,
1495                        "Wed, 27 Dec 2023 20:40:29 GMT", "Thu, 28 Dec 2023 20:40:29 GMT"));
1496    ne_free(cert);
1497    return OK;
1498}
1499
1500/* dname comparisons. */
1501static int dname_compare(void)
1502{
1503    ne_ssl_certificate *ssigned;
1504    const ne_ssl_dname *dn1, *dn2;
1505
1506    dn1 = ne_ssl_cert_subject(def_server_cert);
1507    dn2 = ne_ssl_cert_subject(def_server_cert);
1508    ONN("identical subject names not equal", ne_ssl_dname_cmp(dn1, dn2) != 0);
1509
1510    dn2 = ne_ssl_cert_issuer(def_server_cert);
1511    ONN("issuer and subject names equal for signed cert",
1512        ne_ssl_dname_cmp(dn1, dn2) == 0);
1513
1514    dn1 = ne_ssl_cert_subject(def_ca_cert);
1515    ONN("issuer of signed cert not equal to subject of CA cert",
1516        ne_ssl_dname_cmp(dn1, dn2) != 0);
1517
1518    ssigned = ne_ssl_cert_read("ssigned.pem");
1519    ONN("could not load ssigned.pem", ssigned == NULL);
1520
1521    dn1 = ne_ssl_cert_subject(ssigned);
1522    dn2 = ne_ssl_cert_issuer(ssigned);
1523    ONN("issuer and subject names not equal for self-signed cert",
1524        ne_ssl_dname_cmp(dn1, dn2));
1525    ne_ssl_cert_free(ssigned);
1526
1527    return OK;
1528}
1529
1530/* The dname with the UTF-8 encoding of the Unicode string:
1531 * "H<LATIN SMALL LETTER E WITH GRAVE>llo World". */
1532#define I18N_DNAME "H\xc3\xa8llo World, Neon Hackers Ltd, Cambridge, Cambridgeshire, GB"
1533
1534/* N.B. t61subj.cert encodes an ISO-8859-1 string in a T61String
1535 * field, which is strictly wrong but the common usage. */
1536
1537/* tests for ne_ssl_readable_dname */
1538static int dname_readable(void)
1539{
1540    struct {
1541        const char *cert;
1542        const char *subjdn, *issuerdn;
1543    } ts[] = {
1544        { "justmail.cert", "blah@example.com", NULL },
1545        { "t61subj.cert", I18N_DNAME, NULL },
1546        { "bmpsubj.cert", I18N_DNAME, NULL },
1547        { "utf8subj.cert", I18N_DNAME, NULL },
1548        { "twoou.cert", "First OU Dept, Second OU Dept, Neon Hackers Ltd, "
1549          "Cambridge, Cambridgeshire, GB" }
1550    };
1551    size_t n;
1552
1553    for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) {
1554        ne_ssl_certificate *cert = ne_ssl_cert_read(ts[n].cert);
1555        ONV(cert == NULL, ("could not load cert %s", ts[n].cert));
1556        CALL(check_cert_dnames(cert, ts[n].subjdn, ts[n].issuerdn));
1557        ne_ssl_cert_free(cert);
1558    }
1559
1560    return OK;
1561}
1562
1563/* test cert comparisons */
1564static int cert_compare(void)
1565{
1566    ne_ssl_certificate *c1, *c2;
1567
1568    c1 = ne_ssl_cert_read("server.cert");
1569    c2 = ne_ssl_cert_read("server.cert");
1570    ONN("identical certs don't compare equal", ne_ssl_cert_cmp(c1, c2) != 0);
1571    ONN("identical certs don't compare equal", ne_ssl_cert_cmp(c2, c1) != 0);
1572    ne_ssl_cert_free(c2);
1573
1574    c2 = ne_ssl_cert_read("ssigned.pem");
1575    ONN("different certs don't compare different",
1576        ne_ssl_cert_cmp(c1, c2) == 0);
1577    ONN("different certs don't compare different",
1578        ne_ssl_cert_cmp(c2, c1) == 0);
1579    ne_ssl_cert_free(c2);
1580    ne_ssl_cert_free(c1);
1581
1582    return OK;
1583}
1584
1585/* Extract raw base64 string from a PEM file */
1586static int flatten_pem(const char *fname, char **out)
1587{
1588    FILE *fp = fopen(fname, "r");
1589    char buf[80];
1590    size_t outlen = 0;
1591    int ignore = 1;
1592
1593    ONV(fp == NULL, ("could not open %s", fname));
1594
1595    *out = NULL;
1596
1597    while (fgets(buf, sizeof buf, fp) != NULL) {
1598        size_t len = strlen(buf) - 1;
1599
1600        if (len < 1) continue;
1601
1602        /* look for the wrapper lines. */
1603        if (strncmp(buf, "-----", 5) == 0) {
1604            ignore = !ignore;
1605            continue;
1606        }
1607
1608        /* ignore until the first wrapper line */
1609        if (ignore) continue;
1610
1611        *out = realloc(*out, outlen + len + 1);
1612        memcpy(*out + outlen, buf, len);
1613        outlen += len;
1614    }
1615
1616    (*out)[outlen] = '\0';
1617    fclose(fp);
1618
1619    return OK;
1620}
1621
1622/* check export cert data 'actual' against expected data 'expected */
1623static int check_exported_data(const char *actual, const char *expected)
1624{
1625    ONN("could not export cert", actual == NULL);
1626
1627    ONN("export data contained newline",
1628        strchr(actual, '\r') || strchr(actual, '\n'));
1629
1630    ONV(strcmp(actual, expected), ("exported cert differed from expected:\n"
1631                                   "actual: %s\nexpected: %s",
1632                                   actual, expected));
1633    return OK;
1634}
1635
1636/* Test import and export of certificates.  The export format is PEM
1637 * without the line feeds and wrapping; compare against . */
1638static int import_export(void)
1639{
1640    char *expected, *actual;
1641    ne_ssl_certificate *cert, *imp;
1642
1643    CALL(flatten_pem("server.cert", &expected));
1644
1645    cert = ne_ssl_cert_read("server.cert");
1646    ONN("could not load server.cert", cert == NULL);
1647
1648    /* export the cert to and compare it with the PEM file */
1649    actual = ne_ssl_cert_export(cert);
1650    CALL(check_exported_data(actual, expected));
1651
1652    /* import the exported cert data, check it looks the same */
1653    imp = ne_ssl_cert_import(actual);
1654    ONN("failed to import exported cert", imp == NULL);
1655    ONN("imported cert was different to original",
1656        ne_ssl_cert_cmp(imp, cert));
1657
1658    /* re-export the imported cert and check that looks the same */
1659    ne_free(actual);
1660    actual = ne_ssl_cert_export(imp);
1661    CALL(check_exported_data(actual, expected));
1662    ne_ssl_cert_free(imp);
1663
1664    /* try importing from bogus data */
1665    imp = ne_ssl_cert_import("!!");
1666    ONN("imported bogus cert from bogus base64", imp != NULL);
1667    imp = ne_ssl_cert_import("aaaa");
1668    ONN("imported bogus cert from valid base64", imp != NULL);
1669
1670    ne_ssl_cert_free(cert);
1671    ne_free(actual);
1672    ne_free(expected);
1673    return OK;
1674}
1675
1676/* Test write/read */
1677static int read_write(void)
1678{
1679    ne_ssl_certificate *c1, *c2;
1680
1681    c1 = ne_ssl_cert_read("server.cert");
1682    ONN("could not load server.cert", c1 == NULL);
1683
1684    ONN("could not write output.pem", ne_ssl_cert_write(c1, "output.pem"));
1685
1686    ONN("wrote to nonexistent directory",
1687        ne_ssl_cert_write(c1, "nonesuch/output.pem") == 0);
1688
1689    c2 = ne_ssl_cert_read("output.pem");
1690    ONN("could not read output.pem", c2 == NULL);
1691
1692    ONN("read of output.pem differs from original",
1693        ne_ssl_cert_cmp(c2, c1));
1694
1695    ne_ssl_cert_free(c1);
1696    ne_ssl_cert_free(c2);
1697
1698    return OK;
1699}
1700
1701/* A verification callback which caches the passed cert. */
1702static int verify_cache(void *userdata, int fs,
1703                        const ne_ssl_certificate *cert)
1704{
1705    char **cache = userdata;
1706
1707    if (*cache == NULL) {
1708        *cache = ne_ssl_cert_export(cert);
1709        return 0;
1710    } else {
1711        return -1;
1712    }
1713}
1714
1715/* Test a common use of the SSL API; cache the server cert across
1716 * sessions. */
1717static int cache_cert(void)
1718{
1719    ne_session *sess = DEFSESS;
1720    char *cache = NULL;
1721    ne_ssl_certificate *cert;
1722    struct ssl_server_args args = {0};
1723
1724    args.cert = "ssigned.pem";
1725    args.cache = 1;
1726
1727    ONREQ(any_ssl_request(sess, ssl_server, &args, CA_CERT,
1728                          verify_cache, &cache));
1729    ne_session_destroy(sess);
1730
1731    ONN("no cert was cached", cache == NULL);
1732
1733    /* make a real cert */
1734    cert = ne_ssl_cert_import(cache);
1735    ONN("could not import cached cert", cert == NULL);
1736    ne_free(cache);
1737
1738    /* create a new session */
1739    sess = DEFSESS;
1740    /* trust the cert */
1741    ne_ssl_trust_cert(sess, cert);
1742    ne_ssl_cert_free(cert);
1743    /* now, the request should succeed without manual verification */
1744    ONREQ(any_ssl_request(sess, ssl_server, &args, CA_CERT,
1745                          NULL, NULL));
1746    ne_session_destroy(sess);
1747    return OK;
1748}
1749
1750static int nonssl_trust(void)
1751{
1752    ne_session *sess = ne_session_create("http", "www.example.com", 80);
1753
1754    ne_ssl_trust_cert(sess, def_ca_cert);
1755
1756    ne_session_destroy(sess);
1757
1758    return OK;
1759}
1760
1761/* PIN password provider callback. */
1762static int pkcs11_pin(void *userdata, int attempt,
1763                      const char *slot_descr, const char *token_label,
1764                      unsigned int flags, char *pin)
1765{
1766    char *sekrit = userdata;
1767
1768    NE_DEBUG(NE_DBG_SSL, "pkcs11: slot = [%s], token = [%s]\n",
1769             slot_descr, token_label);
1770
1771    if (attempt == 0) {
1772        strcpy(pin, sekrit);
1773        return 0;
1774    }
1775    else {
1776        return -1;
1777    }
1778}
1779
1780static int nss_pkcs11_test(const char *dbname)
1781{
1782    ne_session *sess = DEFSESS;
1783    struct ssl_server_args args = {SERVER_CERT, NULL};
1784    ne_ssl_pkcs11_provider *prov;
1785    int ret;
1786
1787    args.require_cc = 1;
1788
1789    if (access(dbname, R_OK|X_OK)) {
1790        t_warning("NSS required for PKCS#11 testing");
1791        return SKIP;
1792    }
1793
1794    ret = ne_ssl_pkcs11_nss_provider_init(&prov, "softokn3", dbname, NULL,
1795                                          NULL, NULL);
1796    if (ret) {
1797        if (ret == NE_PK11_NOTIMPL)
1798            t_context("pakchois library required for PKCS#11 support");
1799        else
1800            t_context("could not load NSS softokn3 PKCS#11 provider");
1801        return SKIP;
1802    }
1803
1804    ne_ssl_pkcs11_provider_pin(prov, pkcs11_pin, "foobar");
1805    ne_ssl_set_pkcs11_provider(sess, prov);
1806
1807    ret = any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL);
1808
1809    ne_session_destroy(sess);
1810    ne_ssl_pkcs11_provider_destroy(prov);
1811
1812    return ret;
1813}
1814
1815static int pkcs11(void)
1816{
1817    return nss_pkcs11_test("nssdb");
1818}
1819
1820static int pkcs11_dsa(void)
1821{
1822    return nss_pkcs11_test("nssdb-dsa");
1823}
1824
1825/* TODO: code paths still to test in cert verification:
1826 * - server cert changes between connections: Mozilla gives
1827 * a "bad MAC decode" error for this; can do better?
1828 * - server presents no certificate (using ADH ciphers)... can
1829 * only really happen if they mess with the SSL_CTX and enable
1830 * ADH cipher manually; but good to check the failure case is
1831 * safe.
1832 * From the SSL book:
1833 * - an early FIN should be returned as a possible truncation attack,
1834 * NOT just an NE_SOCK_CLOSED.
1835 * - unexpected close_notify is an error but not an attack.
1836 * - never attempt session resumption after any aborted connection.
1837 */
1838
1839ne_test tests[] = {
1840    T_LEAKY(init),
1841
1842    T(load_server_certs),
1843    T(trust_default_ca),
1844
1845    T(cert_fingerprint),
1846    T(cert_identities),
1847    T(cert_validity),
1848    T(cert_compare),
1849    T(dname_compare),
1850    T(dname_readable),
1851    T(import_export),
1852    T(read_write),
1853
1854    T(load_client_cert),
1855
1856    T(simple),
1857    T(simple_sslv2),
1858    T(simple_eof),
1859    T(empty_truncated_eof),
1860    T(fail_not_ssl),
1861    T(cache_cert),
1862    T(intermediary),
1863
1864    T(client_cert_pkcs12),
1865    T(ccert_unencrypted),
1866    T(client_cert_provided),
1867    T(cc_provided_dnames),
1868    T(no_client_cert),
1869    T(client_cert_ca),
1870
1871    T(parse_cert),
1872    T(parse_chain),
1873
1874    T(no_verify),
1875    T(cache_verify),
1876    T(wildcard_match),
1877    T(wildcard_match_altname),
1878    T(caseless_match),
1879
1880    T(subject_altname),
1881    T(two_subject_altname),
1882    T(two_subject_altname2),
1883    T(notdns_altname),
1884    T(ipaddr_altname),
1885    T(uri_altname),
1886
1887    T(multi_commonName),
1888    T(commonName_first),
1889
1890    T(fail_wrongCN),
1891    T(fail_expired),
1892    T(fail_notvalid),
1893    T(fail_untrusted_ca),
1894    T(fail_self_signed),
1895    T(fail_missing_CN),
1896    T(fail_host_ipaltname),
1897    T(fail_bad_ipaltname),
1898    T(fail_bad_urialtname),
1899    T(fail_wildcard),
1900    T(fail_wildcard_ip),
1901    T(fail_ca_notyetvalid),
1902    T(fail_ca_expired),
1903
1904    T(nulcn_identity),
1905    T(fail_nul_cn),
1906    T(fail_nul_san),
1907
1908    T(session_cache),
1909
1910    T(fail_tunnel),
1911    T(proxy_tunnel),
1912    T(auth_proxy_tunnel),
1913    T(auth_tunnel_creds),
1914    T(auth_tunnel_fail),
1915
1916    T(nonssl_trust),
1917
1918    T(pkcs11),
1919    T_XFAIL(pkcs11_dsa), /* unclear why this fails currently. */
1920
1921    T(NULL)
1922};
1923