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