fix implicit declarations
[rofl0r-ixchat.git] / src / common / ssl.c
blob8ce8b98cc5a0a977af13fe928abdfc6d3fac9d4c
1 /*
2 * ssl.c v0.0.3
3 * Copyright (C) 2000 -- DaP <profeta@freemail.c3.hu>
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 #include <openssl/ssl.h> /* SSL_() */
21 #include <openssl/err.h> /* ERR_() */
22 #include <time.h> /* asctime() */
23 #include <string.h> /* strncpy() */
24 #include "ssl.h" /* struct cert_info */
25 #include "inet.h"
26 #include "util.h"
28 #ifndef MIN
29 #define MIN(a, b) (a < b ? a : b)
30 #endif
32 /* If openssl was built without ec */
33 #ifndef SSL_OP_SINGLE_ECDH_USE
34 #define SSL_OP_SINGLE_ECDH_USE 0
35 #endif
37 /* globals */
38 static struct chiper_info chiper_info; /* static buffer for _SSL_get_cipher_info() */
39 static char err_buf[256]; /* generic error buffer */
42 /* +++++ Internal functions +++++ */
44 static void
45 __SSL_fill_err_buf (char *funcname)
47 int err;
48 char buf[256];
51 err = ERR_get_error ();
52 ERR_error_string (err, buf);
53 snprintf (err_buf, sizeof (err_buf), "%s: %s (%d)\n", funcname, buf, err);
57 static void
58 __SSL_critical_error (char *funcname)
60 __SSL_fill_err_buf (funcname);
61 fprintf (stderr, "%s\n", err_buf);
63 exit (1);
66 /* +++++ SSL functions +++++ */
68 SSL_CTX *
69 _SSL_context_init (void (*info_cb_func))
71 SSL_CTX *ctx;
73 SSLeay_add_ssl_algorithms ();
74 SSL_load_error_strings ();
75 ctx = SSL_CTX_new (SSLv23_client_method ());
77 SSL_CTX_set_session_cache_mode (ctx, SSL_SESS_CACHE_BOTH);
78 SSL_CTX_set_timeout (ctx, 300);
79 SSL_CTX_set_options (ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3
80 |SSL_OP_NO_COMPRESSION
81 |SSL_OP_SINGLE_DH_USE|SSL_OP_SINGLE_ECDH_USE
82 |SSL_OP_NO_TICKET
83 |SSL_OP_CIPHER_SERVER_PREFERENCE);
85 /* used in SSL_connect(), SSL_accept() */
86 SSL_CTX_set_info_callback (ctx, info_cb_func);
88 return(ctx);
91 static void
92 ASN1_TIME_snprintf (char *buf, int buf_len, ASN1_TIME * tm)
94 char *expires = NULL;
95 BIO *inMem = BIO_new (BIO_s_mem ());
97 ASN1_TIME_print (inMem, tm);
98 BIO_get_mem_data (inMem, &expires);
99 buf[0] = 0;
100 if (expires != NULL)
102 /* expires is not \0 terminated */
103 safe_strcpy (buf, expires, MIN(24, buf_len));
105 BIO_free (inMem);
109 static void
110 broke_oneline (char *oneline, char *parray[])
112 char *pt, *ppt;
113 int i;
116 i = 0;
117 ppt = pt = oneline + 1;
118 while ((pt = strchr (pt, '/')))
120 *pt = 0;
121 parray[i++] = ppt;
122 ppt = ++pt;
124 parray[i++] = ppt;
125 parray[i] = NULL;
130 FIXME: Master-Key, Extensions, CA bits
131 (openssl x509 -text -in servcert.pem)
134 _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl)
136 X509 *peer_cert;
137 EVP_PKEY *peer_pkey;
138 /* EVP_PKEY *ca_pkey; */
139 /* EVP_PKEY *tmp_pkey; */
140 char notBefore[64];
141 char notAfter[64];
142 int alg;
143 int sign_alg;
146 if (!(peer_cert = SSL_get_peer_certificate (ssl)))
147 return (1); /* FATAL? */
149 X509_NAME_oneline (X509_get_subject_name (peer_cert), cert_info->subject,
150 sizeof (cert_info->subject));
151 X509_NAME_oneline (X509_get_issuer_name (peer_cert), cert_info->issuer,
152 sizeof (cert_info->issuer));
153 broke_oneline (cert_info->subject, cert_info->subject_word);
154 broke_oneline (cert_info->issuer, cert_info->issuer_word);
156 alg = OBJ_obj2nid (peer_cert->cert_info->key->algor->algorithm);
157 sign_alg = OBJ_obj2nid (peer_cert->sig_alg->algorithm);
158 ASN1_TIME_snprintf (notBefore, sizeof (notBefore),
159 X509_get_notBefore (peer_cert));
160 ASN1_TIME_snprintf (notAfter, sizeof (notAfter),
161 X509_get_notAfter (peer_cert));
163 peer_pkey = X509_get_pubkey (peer_cert);
165 safe_strcpy (cert_info->algorithm,
166 (alg == NID_undef) ? "Unknown" : OBJ_nid2ln (alg),
167 sizeof (cert_info->algorithm));
168 cert_info->algorithm_bits = EVP_PKEY_bits (peer_pkey);
169 safe_strcpy (cert_info->sign_algorithm,
170 (sign_alg == NID_undef) ? "Unknown" : OBJ_nid2ln (sign_alg),
171 sizeof (cert_info->sign_algorithm));
172 /* EVP_PKEY_bits(ca_pkey)); */
173 cert_info->sign_algorithm_bits = 0;
174 safe_strcpy (cert_info->notbefore, notBefore, sizeof (cert_info->notbefore));
175 safe_strcpy (cert_info->notafter, notAfter, sizeof (cert_info->notafter));
177 EVP_PKEY_free (peer_pkey);
179 /* SSL_SESSION_print_fp(stdout, SSL_get_session(ssl)); */
181 if (ssl->session->sess_cert->peer_rsa_tmp) {
182 tmp_pkey = EVP_PKEY_new();
183 EVP_PKEY_assign_RSA(tmp_pkey, ssl->session->sess_cert->peer_rsa_tmp);
184 cert_info->rsa_tmp_bits = EVP_PKEY_bits (tmp_pkey);
185 EVP_PKEY_free(tmp_pkey);
186 } else
187 fprintf(stderr, "REMOTE SIDE DOESN'T PROVIDES ->peer_rsa_tmp\n");
189 cert_info->rsa_tmp_bits = 0;
191 X509_free (peer_cert);
193 return (0);
197 struct chiper_info *
198 _SSL_get_cipher_info (SSL * ssl)
200 SSL_CIPHER *c;
203 c = SSL_get_current_cipher (ssl);
204 safe_strcpy (chiper_info.version, SSL_CIPHER_get_version (c),
205 sizeof (chiper_info.version));
206 safe_strcpy (chiper_info.chiper, SSL_CIPHER_get_name (c),
207 sizeof (chiper_info.chiper));
208 SSL_CIPHER_get_bits (c, &chiper_info.chiper_bits);
210 return (&chiper_info);
215 _SSL_send (SSL * ssl, char *buf, int len)
217 int num;
220 num = SSL_write (ssl, buf, len);
222 switch (SSL_get_error (ssl, num))
224 case SSL_ERROR_SSL: /* setup errno! */
225 /* ??? */
226 __SSL_fill_err_buf ("SSL_write");
227 fprintf (stderr, "%s\n", err_buf);
228 break;
229 case SSL_ERROR_SYSCALL:
230 /* ??? */
231 perror ("SSL_write/write");
232 break;
233 case SSL_ERROR_ZERO_RETURN:
234 /* fprintf(stderr, "SSL closed on write\n"); */
235 break;
238 return (num);
243 _SSL_recv (SSL * ssl, char *buf, int len)
245 int num;
248 num = SSL_read (ssl, buf, len);
250 switch (SSL_get_error (ssl, num))
252 case SSL_ERROR_SSL:
253 /* ??? */
254 __SSL_fill_err_buf ("SSL_read");
255 fprintf (stderr, "%s\n", err_buf);
256 break;
257 case SSL_ERROR_SYSCALL:
258 /* ??? */
259 if (!would_block ())
260 perror ("SSL_read/read");
261 break;
262 case SSL_ERROR_ZERO_RETURN:
263 /* fprintf(stdeerr, "SSL closed on read\n"); */
264 break;
267 return (num);
271 SSL *
272 _SSL_socket (SSL_CTX *ctx, int sd)
274 SSL *ssl;
277 if (!(ssl = SSL_new (ctx)))
278 /* FATAL */
279 __SSL_critical_error ("SSL_new");
281 SSL_set_fd (ssl, sd);
282 if (ctx->method == SSLv23_client_method())
283 SSL_set_connect_state (ssl);
284 else
285 SSL_set_accept_state(ssl);
287 return (ssl);
291 char *
292 _SSL_set_verify (SSL_CTX *ctx, void *verify_callback, char *cacert)
294 if (!SSL_CTX_set_default_verify_paths (ctx))
296 __SSL_fill_err_buf ("SSL_CTX_set_default_verify_paths");
297 return (err_buf);
300 if (cacert)
302 if (!SSL_CTX_load_verify_locations (ctx, cacert, NULL))
304 __SSL_fill_err_buf ("SSL_CTX_load_verify_locations");
305 return (err_buf);
309 SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER, verify_callback);
311 return (NULL);
315 void
316 _SSL_close (SSL * ssl)
318 SSL_set_shutdown (ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
319 SSL_free (ssl);
320 ERR_remove_state (0); /* free state buffer */