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