1 /* $NetBSD: ssl-bozo.c,v 1.2 2007/10/17 18:48:01 tls Exp $ */ 2 3 /* $eterna: ssl-bozo.c,v 1.6 2006/05/17 08:19:10 mrg Exp $ */ 4 5 /* 6 * Copyright (c) 1997-2006 Matthew R. Green 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer and 16 * dedication in the documentation and/or other materials provided 17 * with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 */ 34 35 /* this code implements SSL for bozohttpd */ 36 37 #ifndef NO_SSL_SUPPORT 38 39 #include <unistd.h> 40 41 #include <openssl/ssl.h> 42 #include <openssl/err.h> 43 44 #include "bozohttpd.h" 45 46 static SSL_CTX *ssl_context; 47 static SSL_METHOD *ssl_method; 48 static SSL *bozossl; 49 static char *certificate_file; 50 static char *privatekey_file; 51 52 static int ssl_printf(const char *, ...); 53 static ssize_t ssl_read(int, void *, size_t); 54 static ssize_t ssl_write(int, const void *, size_t); 55 static int ssl_flush(FILE *); 56 57 void 58 ssl_init(void) 59 { 60 if (!certificate_file) 61 return; 62 SSL_library_init(); 63 SSL_load_error_strings(); 64 65 ssl_method = SSLv23_server_method(); 66 ssl_context = SSL_CTX_new(ssl_method); 67 68 /* XXX we need to learn how to check the SSL stack for more info */ 69 if (ssl_context == NULL) 70 error(1, "SSL context initialization failed."); 71 72 SSL_CTX_use_certificate_file(ssl_context, certificate_file, 73 SSL_FILETYPE_PEM); 74 SSL_CTX_use_PrivateKey_file(ssl_context, privatekey_file, 75 SSL_FILETYPE_PEM); 76 77 /* check consistency of key vs certificate */ 78 if (!SSL_CTX_check_private_key(ssl_context)) 79 error(1, "check private key failed"); 80 } 81 82 void 83 ssl_accept() 84 { 85 if (ssl_context) { 86 bozossl = SSL_new(ssl_context); /* XXX global sucks */ 87 SSL_set_rfd(bozossl, 0); 88 SSL_set_wfd(bozossl, 1); 89 SSL_accept(bozossl); 90 } 91 } 92 93 void 94 ssl_destroy() 95 { 96 if (bozossl) 97 SSL_free(bozossl); 98 } 99 100 void 101 ssl_set_opts(char *cert, char *priv) 102 { 103 certificate_file = cert; 104 privatekey_file = priv; 105 debug((DEBUG_NORMAL, "using cert/priv files: %s & %s", certificate_file, 106 privatekey_file)); 107 if (Iflag_set == 0) 108 Iflag = "https"; 109 bozoprintf = ssl_printf; 110 bozoread = ssl_read; 111 bozowrite = ssl_write; 112 bozoflush = ssl_flush; 113 } 114 115 static int 116 ssl_printf(const char * fmt, ...) 117 { 118 int nbytes; 119 char *buf; 120 va_list ap; 121 122 /* XXX we need more elegant/proper handling of SSL_write return */ 123 va_start(ap, fmt); 124 if ((nbytes = vasprintf(&buf, fmt, ap)) != -1) 125 SSL_write(bozossl, buf, nbytes); 126 va_end(ap); 127 128 return nbytes; 129 } 130 131 static ssize_t 132 ssl_read(int fd, void *buf, size_t nbytes) 133 { 134 ssize_t rbytes; 135 136 /* XXX we need elegant/proper handling of SSL_read return */ 137 rbytes = (ssize_t)SSL_read(bozossl, buf, nbytes); 138 if (1 > rbytes) { 139 if (SSL_get_error(bozossl, rbytes) == SSL_ERROR_WANT_READ) 140 warning("SSL_ERROR_WANT_READ"); 141 else 142 warning("SSL_ERROR OTHER"); 143 } 144 145 return rbytes; 146 } 147 148 static ssize_t 149 ssl_write(int fd, const void *buf, size_t nbytes) 150 { 151 ssize_t wbytes; 152 153 /* XXX we need elegant/proper handling of SSL_write return */ 154 wbytes = (ssize_t)SSL_write(bozossl, buf, nbytes); 155 156 return wbytes; 157 } 158 159 static int 160 ssl_flush(FILE *fp) 161 { 162 /* nothing to see here, move right along */ 163 return 0; 164 } 165 #endif /* NO_SSL_SUPPORT */ 166