initial commit; it works
[psslcertgen.git] / src / fuckme.c
blob7a4c4217bdedda7dd4798894e44aa8e421010ade
1 #ifndef _GNU_SOURCE
2 # define _GNU_SOURCE
3 #endif
4 #include <ctype.h>
5 #include <signal.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
11 #include "libpolarssl/config.h"
12 #include "libpolarssl/entropy.h"
13 #include "libpolarssl/ctr_drbg.h"
14 #include "libpolarssl/certs.h"
15 #include "libpolarssl/x509.h"
16 #include "libpolarssl/x509write.h"
17 #include "libpolarssl/ssl.h"
18 #include "libpolarssl/net.h"
19 #include "libpolarssl/timing.h"
20 #include "libpolarssl/rsa.h"
22 #include "xstrbuf.h"
25 #define DEBUG_LEVEL 0
27 #define KEY_SIZE (1024)
28 //#define KEY_SIZE (128)
29 #define EXPONENT (65537)
32 #define HTTP_RESPONSE \
33 "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
34 "<h2>PolarSSL Test Server</h2>\r\n" \
35 "<p>Successful connection using: %s</p>\r\n"
38 static void my_debug (void *ctx, int level, const char *str) {
39 if (level < DEBUG_LEVEL) {
40 fprintf((FILE *)ctx, "%s", str);
41 fflush((FILE *)ctx);
46 static int gen_cert (const char *hostname, x509_cert *srvcert, rsa_context *rsa) {
47 x509_raw graw;
48 //509_cert gcert;
49 char *hbuf = malloc(strlen(hostname)+8192);
50 int res;
53 fprintf(stderr, "SSL: generating the RSA key [%d-bit]...\n", KEY_SIZE);
54 rsa_init(&rsa_key, RSA_PKCS_V15, 0);
55 if ((ret = rsa_gen_key(&rsa_key, ctr_drbg_random, &ctr_drbg, KEY_SIZE, EXPONENT)) != 0) {
56 fprintf(stderr, "FUCKED: rsa_gen_key returned %d\n", ret);
57 goto exit;
62 sprintf(hbuf, "certs/key.%s.pem", hostname);
63 res = x509write_keyfile(rsa, hbuf, X509_OUTPUT_PEM);
64 if (res != 0) { fprintf(stderr, "SHIT: x509write_keyfile=%d\n", res); }
66 x509write_init_raw(&graw);
68 fprintf(stderr, "SSL: generating the certificate...\n");
69 sprintf(hbuf, "CN=%s", hostname);
71 fprintf(stderr, "SSL: x509write_add_pubkey()\n");
72 res = x509write_add_pubkey(&graw, rsa);
73 if (res != 0) { fprintf(stderr, "SHIT: x509write_add_pubkey=%d\n", res); goto error; }
75 fprintf(stderr, "SSL: x509write_copy_issuer()\n");
76 res = x509write_copy_issuer(&graw, srvcert);
77 if (res != 0) { fprintf(stderr, "SHIT: x509write_copy_issuer=%d\n", res); goto error; }
79 fprintf(stderr, "SSL: x509write_add_subject()\n");
80 res = x509write_add_subject(&graw, (unsigned char *)hbuf);
81 if (res != 0) { fprintf(stderr, "SHIT: x509write_add_subject=%d\n", res); goto error; }
83 fprintf(stderr, "SSL: x509write_add_validity()\n");
84 res = x509write_add_validity(&graw, (unsigned char *)"2013-01-01 12:00:00", (unsigned char *)"2014-01-01 12:00:00");
85 if (res != 0) { fprintf(stderr, "SHIT: x509write_add_validity=%d\n", res); goto error; }
87 //fprintf(stderr, "SSL: x509write_create_selfsign()\n");
88 //res = x509write_create_selfsign(&graw, rsa);
89 //if (res != 0) { fprintf(stderr, "SHIT: x509write_create_selfsign=%d\n", res); goto error; }
91 fprintf(stderr, "SSL: x509write_create_sign()\n");
92 res = x509write_create_sign(&graw, rsa);
93 if (res != 0) { fprintf(stderr, "SHIT: x509write_create_sign=%d\n", res); goto error; }
96 fprintf(stderr, "SSL: x509parse_crt_der()\n");
97 res = x509parse_crt_der(&gcert, (const unsigned char *)graw.raw.data, graw.raw.len);
98 if (res != 0) { fprintf(stderr, "SHIT: x509parse_crt_der=%d\n", res); goto error; }
101 sprintf(hbuf, "certs/cert.%s.pem", hostname);
102 fprintf(stderr, "SSL: x509write_crtfile()\n");
103 res = x509write_crtfile(&graw, hbuf, X509_OUTPUT_PEM);
104 if (res != 0) { fprintf(stderr, "SHIT: x509write_crtfile=%d\n", res); goto error; }
106 fprintf(stderr, "SSL: x509write_free_raw()\n");
107 x509write_free_raw(&graw);
108 //res = x509write_crtfile(&gcert, hbuf, X509_OUTPUT_PEM);
109 //if (res != 0) { fprintf(stderr, "SHIT: x509write_crtfile=%d\n", res); }
111 //x509write_init_raw( &cert );
112 //x509write_add_pubkey( &cert, rsa );
113 //x509write_add_subject( &cert, "CN='localhost'" );
114 //x509write_add_validity( &cert, "2007-09-06 17:00:32", "2010-09-06 17:00:32" );
115 //x509write_create_selfsign( &cert, rsa );
116 //x509write_crtfile( &cert, "cert.der", X509_OUTPUT_DER );
117 //x509write_crtfile( &cert, "cert.pem", X509_OUTPUT_PEM );
118 //x509write_free_raw( &cert );
119 return 0;
120 error:
121 free(hbuf);
122 x509write_free_raw(&graw);
123 return -1;
127 int main (int argc, char *argv[]) {
128 int ret, len;
129 int listen_fd;
130 int client_fd = -1;
131 unsigned char buf[1024], *wpos;
132 const char *pers = "fuckme";
134 entropy_context entropy;
135 ctr_drbg_context ctr_drbg;
136 x509_cert srvcert;
137 rsa_context rsa;
138 ssl_context ssl;
140 signal(SIGCHLD, SIG_IGN);
142 entropy_init(&entropy);
143 if ((ret = ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, (const unsigned char *)pers, strlen(pers))) != 0) {
144 fprintf(stderr, "FUCKED: ctr_drbg_init returned %d\n", ret);
145 goto exit;
148 rsa_init(&rsa, RSA_PKCS_V15, 0);
149 ret = x509parse_keyfile(&rsa, "certs/key.pem", NULL);
150 if (ret != 0) {
151 fprintf(stderr, "FUCKED: x509parse_key returned %d\n", ret);
152 goto exit;
155 memset(&srvcert, 0, sizeof(srvcert));
156 ret = x509parse_crtfile(&srvcert, "certs/cert.pem");
157 if (ret != 0) {
158 fprintf(stderr, "FUCKED: x509parse_crt returned %d\n", ret);
159 goto exit;
161 fprintf(stderr, "cert.pem loaded\n");
163 if (access("certs/cert.localhost.pem", R_OK) != 0) {
164 if (gen_cert("localhost", &srvcert, &rsa) != 0) {
165 fprintf(stderr, "FUCKED: can't generate certificate for localhost!\n");
166 goto exit;
170 ret = x509parse_crtfile(&srvcert, "certs/cert.localhost.pem");
171 if (ret != 0) {
172 fprintf(stderr, "FUCKED: x509parse_crt returned %d\n", ret);
173 goto exit;
175 fprintf(stderr, "cert.localhost.pem loaded\n");
177 if ((ret = pssl_net_bind(&listen_fd, NULL, 4433)) != 0) {
178 fprintf(stderr, "FUCKED: pssl_net_bind returned %d\n", ret);
179 goto exit;
182 for (;;) {
183 pid_t pid;
184 xstrbuf_t hdrs;
186 memset(&ssl, 0, sizeof(ssl));
187 if ((ret = pssl_net_accept(listen_fd, &client_fd, NULL)) != 0) {
188 fprintf(stderr, "FUCKED: pssl_net_accept returned %d\n", ret);
189 goto exit;
191 pid = fork();
192 if (pid < 0) {
193 fprintf(stderr, "FUCKED: fork returned %d\n", pid);
194 goto exit;
196 if (pid != 0) {
197 // parent
198 if ((ret = ctr_drbg_reseed(&ctr_drbg, (const unsigned char *)"parent", 6)) != 0) {
199 fprintf(stderr, "FUCKED: ctr_drbg_reseed returned %d\n", ret);
200 goto exit;
202 close(client_fd);
203 continue;
205 // child
206 close(listen_fd);
208 if ((ret = ctr_drbg_reseed(&ctr_drbg, (const unsigned char *)"child", 5)) != 0) {
209 fprintf(stderr, "FUCKED: ctr_drbg_reseed returned %d\n", ret);
210 goto exit;
212 if ((ret = ssl_init(&ssl)) != 0) {
213 fprintf(stderr, "FUCKED: ssl_init returned %d\n\n", ret);
214 goto exit;
216 ssl_set_endpoint(&ssl, SSL_IS_SERVER);
217 ssl_set_authmode(&ssl, SSL_VERIFY_NONE);
218 ssl_set_rng(&ssl, ctr_drbg_random, &ctr_drbg);
219 ssl_set_dbg(&ssl, my_debug, stdout);
220 ssl_set_bio(&ssl, pssl_net_recv, &client_fd, pssl_net_send, &client_fd);
221 if (srvcert.next == NULL) {
222 fprintf(stderr, "SSL: we DON'T have two certificates!\n");
223 goto exit;
225 ssl_set_ca_chain(&ssl, &srvcert, NULL, NULL);
226 ssl_set_own_cert(&ssl, srvcert.next, &rsa);
228 fprintf(stderr, "SSL: performing handshake...\n");
229 while ((ret = ssl_handshake(&ssl)) != 0) {
230 if (ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) {
231 fprintf(stderr, "FUCKED: ssl_handshake returned %d\n", ret);
232 goto exit;
236 fprintf(stderr, "SSL: reading headers from client...\n");
237 xstrbuf_init(&hdrs);
238 for (;;) {
239 char c;
240 ret = ssl_read(&ssl, (void *)&c, 1);
241 if (ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE) continue;
242 if (ret <= 0) {
243 switch (ret) {
244 case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
245 fprintf(stderr, "SSL: connection was closed gracefully\n");
246 break;
247 case POLARSSL_ERR_NET_CONN_RESET:
248 fprintf(stderr, "SSL: connection was reset by peer\n");
249 break;
250 default:
251 fprintf(stderr, "SSL: ssl_read returned %d\n", ret);
252 break;
254 break;
256 xstrbuf_addc(&hdrs, c);
257 if (hdrs.used >= 2 && hdrs.data[hdrs.used-1] == '\n') {
258 if (hdrs.data[hdrs.used-2] == '\n') break; // headers complete
259 if (hdrs.data[hdrs.used-2] == '\r' && hdrs.used >= 3 && hdrs.data[hdrs.used-3] == '\n') break; // headers complete
262 fprintf(stderr, "=== HEADERS ===\n%s===\n", hdrs.data);
263 xstrbuf_free(&hdrs);
265 fprintf(stderr, "SSL: writing to client...\n");
266 len = sprintf((char *)buf, HTTP_RESPONSE, ssl_get_ciphersuite(&ssl));
267 wpos = buf;
268 while (len > 0) {
269 while ((ret = ssl_write(&ssl, wpos, len)) <= 0) {
270 if (ret == POLARSSL_ERR_NET_CONN_RESET) {
271 fprintf(stderr, "SSL: peer closed the connection\n");
272 goto exit;
274 if (ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) {
275 fprintf(stderr, "SSL: ssl_write returned %d\n", ret);
276 goto exit;
279 len -= ret;
280 wpos += ret;
282 ssl_close_notify(&ssl);
283 goto exit;
285 exit:
286 pssl_net_close(client_fd);
287 x509_free(&srvcert);
288 rsa_free(&rsa);
289 ssl_free(&ssl);
291 return ret;