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