summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <>2010-08-27 13:20:16 +0000
committererdgeist <>2010-08-27 13:20:16 +0000
commitedad5cf6e2b7604204d6246be5fe6b6dd8532fa0 (patch)
treed47c713620fcaa097ea66c19b285bb8be62c2f03
parent6eb716f8db302dcf51113a7f8c99c18ebcb6b07e (diff)
Tidy up ssl code, move all ssl related stuff to vchat-ssl and clean up some wrinkles in cert verification
-rwxr-xr-xvchat-config.h3
-rwxr-xr-xvchat-protocol.c42
-rwxr-xr-xvchat-ssl.c144
-rwxr-xr-xvchat-ssl.h8
4 files changed, 41 insertions, 156 deletions
diff --git a/vchat-config.h b/vchat-config.h
index 3511c68..4409107 100755
--- a/vchat-config.h
+++ b/vchat-config.h
@@ -23,7 +23,6 @@
23#endif 23#endif
24 24
25/* configuration array with structure as defined in vchat.h */ 25/* configuration array with structure as defined in vchat.h */
26extern unsigned int ignssl;
27extern unsigned int usetime; 26extern unsigned int usetime;
28extern unsigned int hscroll; 27extern unsigned int hscroll;
29 28
@@ -41,7 +40,7 @@ static volatile configoption configoptions[] = {
41 {CF_LOGINSCRIPT, CO_STR, "loginscript","~/.vchat/loginscript", NULL, { NULL } }, 40 {CF_LOGINSCRIPT, CO_STR, "loginscript","~/.vchat/loginscript", NULL, { NULL } },
42 {CF_ENCODING, CO_STR, "encoding", NULL, NULL, { .pstr = &encoding }}, 41 {CF_ENCODING, CO_STR, "encoding", NULL, NULL, { .pstr = &encoding }},
43 {CF_USESSL, CO_INT, "usessl", (char *) 1, (char *)-1, { NULL } }, 42 {CF_USESSL, CO_INT, "usessl", (char *) 1, (char *)-1, { NULL } },
44 {CF_IGNSSL, CO_INT, "ignssl", (char *) 0, (char *)-1, { .pint = &ignssl } }, 43 {CF_IGNSSL, CO_INT, "ignssl", (char *) 0, (char *)-1, { NULL } },
45 {CF_USECERT, CO_INT, "usecert", (char *) 1, (char *)-1, { NULL } }, 44 {CF_USECERT, CO_INT, "usecert", (char *) 1, (char *)-1, { NULL } },
46 {CF_USETIME, CO_INT, "usetime", (char *) 1, (char *)-1, { .pint = &usetime } }, 45 {CF_USETIME, CO_INT, "usetime", (char *) 1, (char *)-1, { .pint = &usetime } },
47 {CF_USETOPIC, CO_INT, "usetopicbar",(char *) 1, (char *)-1, { NULL } }, 46 {CF_USETOPIC, CO_INT, "usetopicbar",(char *) 1, (char *)-1, { NULL } },
diff --git a/vchat-protocol.c b/vchat-protocol.c
index 700f6c7..ef035fe 100755
--- a/vchat-protocol.c
+++ b/vchat-protocol.c
@@ -70,7 +70,6 @@ static void pmnotsent (char *message);
70/* status-variable from vchat-client.c 70/* status-variable from vchat-client.c
71 * eventloop is done as long as this is true */ 71 * eventloop is done as long as this is true */
72extern int status; 72extern int status;
73int ignssl = 0;
74char *encoding; 73char *encoding;
75 74
76static int connect_socket( char *server, char *port ) { 75static int connect_socket( char *server, char *port ) {
@@ -107,9 +106,6 @@ vcconnect (char *server, char *port)
107 /* vchat connection x509 store */ 106 /* vchat connection x509 store */
108 vc_x509store_t vc_store; 107 vc_x509store_t vc_store;
109 108
110 /* SSL-context */
111 SSL_CTX *sslctx = NULL;
112
113 /* pointer to tilde-expanded certificate/keyfile-names */ 109 /* pointer to tilde-expanded certificate/keyfile-names */
114 char *certfile = NULL, *keyfile = NULL; 110 char *certfile = NULL, *keyfile = NULL;
115 111
@@ -164,10 +160,9 @@ vcconnect (char *server, char *port)
164 vc_x509store_set_pkeycb(&vc_store, (vc_askpass_cb_t)passprompt); 160 vc_x509store_set_pkeycb(&vc_store, (vc_askpass_cb_t)passprompt);
165 vc_x509store_setkeyfile(&vc_store, tildex); 161 vc_x509store_setkeyfile(&vc_store, tildex);
166 } 162 }
167 vc_x509store_setignssl(&vc_store, getintoption(CF_IGNSSL));
168 163
169 /* upgrade our plain BIO to ssl */ 164 /* upgrade our plain BIO to ssl */
170 if( vc_connect_ssl( &server_conn, &vc_store, &sslctx ) ) 165 if( vc_connect_ssl( &server_conn, &vc_store ) )
171 BIO_free_all( server_conn ); 166 BIO_free_all( server_conn );
172 } 167 }
173 168
@@ -279,7 +274,7 @@ topicinfo (char *message)
279{ 274{
280 char *channel = NULL, *topic = NULL; 275 char *channel = NULL, *topic = NULL;
281 int tmpchan = 0; 276 int tmpchan = 0;
282 277
283 /* search start of channel number */ 278 /* search start of channel number */
284 channel = strchr (message, ' '); 279 channel = strchr (message, ' ');
285 channel++; 280 channel++;
@@ -443,7 +438,7 @@ nickerr (char *message)
443 setstroption(CF_NICK,NULL); 438 setstroption(CF_NICK,NULL);
444 /* get new nick via vchat-ui.c */ 439 /* get new nick via vchat-ui.c */
445 nickprompt (); 440 nickprompt ();
446 441
447 /* form login message and send it to server */ 442 /* form login message and send it to server */
448 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", nick, getstroption (CF_FROM), getintoption (CF_CHANNEL)); 443 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", nick, getstroption (CF_FROM), getintoption (CF_CHANNEL));
449 networkoutput (tmpstr); 444 networkoutput (tmpstr);
@@ -455,8 +450,7 @@ nickerr (char *message)
455 * vars: %s - this users registered nick 450 * vars: %s - this users registered nick
456 * %s msg - server message */ 451 * %s msg - server message */
457static void 452static void
458login (char *message) 453login (char *message) {
459{
460 char *msg = NULL; 454 char *msg = NULL;
461 455
462 /* mutate message for output */ 456 /* mutate message for output */
@@ -465,23 +459,19 @@ login (char *message)
465 writecf (FS_SERV,&message[2]); 459 writecf (FS_SERV,&message[2]);
466 460
467 /* we don't know our nick? */ 461 /* we don't know our nick? */
468 if (!nick) 462 if (!nick) {
469 { 463 /* find message after nick */
470 /* find message after nick */ 464 msg = strchr (&message[4], ' ');
471 msg = strchr (&message[4], ' '); 465 if (msg) {
472 if (msg) 466 /* terminate string before message and copy nick */
473 { 467 msg[0] = '\0';
474 /* terminate string before message and copy nick */ 468 setstroption(CF_NICK,&message[4]);
475 msg[0] = '\0'; 469 } else {
476 setstroption(CF_NICK,&message[4]); 470 /* no string in servers message (huh?), ask user for nick */
477 } 471 nickprompt ();
478 else
479 {
480 /* no string in servers message (huh?), ask user for nick */
481 nickprompt ();
482 }
483 } 472 }
484 473 }
474
485 /* form login message and send it to server */ 475 /* form login message and send it to server */
486 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", nick, getstroption (CF_FROM), getintoption (CF_CHANNEL)); 476 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", nick, getstroption (CF_FROM), getintoption (CF_CHANNEL));
487 networkoutput (tmpstr); 477 networkoutput (tmpstr);
diff --git a/vchat-ssl.c b/vchat-ssl.c
index 1a1ff16..652ca09 100755
--- a/vchat-ssl.c
+++ b/vchat-ssl.c
@@ -27,13 +27,13 @@
27#include <openssl/x509v3.h> 27#include <openssl/x509v3.h>
28#include <openssl/conf.h> 28#include <openssl/conf.h>
29 29
30#include <readline/readline.h>
31
30#include "vchat.h" 32#include "vchat.h"
31#include "vchat-ssl.h" 33#include "vchat-ssl.h"
32 34
33char *vchat_ssl_version = "$Id$"; 35char *vchat_ssl_version = "$Id$";
34 36
35static int ignore_ssl;
36
37#define VC_CTX_ERR_EXIT(se, cx) do { \ 37#define VC_CTX_ERR_EXIT(se, cx) do { \
38 snprintf(tmpstr, TMPSTRSIZE, "CREATE CTX: %s", \ 38 snprintf(tmpstr, TMPSTRSIZE, "CREATE CTX: %s", \
39 ERR_error_string (ERR_get_error (), NULL)); \ 39 ERR_error_string (ERR_get_error (), NULL)); \
@@ -119,25 +119,16 @@ SSL_CTX * vc_create_sslctx( vc_x509store_t *vc_store )
119 return(ctx); 119 return(ctx);
120} 120}
121 121
122int vc_connect_ssl( BIO **conn, vc_x509store_t *vc_store, SSL_CTX **ctx) 122int vc_connect_ssl( BIO **conn, vc_x509store_t *vc_store )
123{ 123{
124 BIO *ssl_conn = NULL; 124 BIO *ssl_conn = NULL;
125 int _ctx = 0; 125 SSL_CTX * ctx = vc_create_sslctx(vc_store);
126 126
127 if(*ctx) { 127 if( !ctx )
128 CRYPTO_add( &((*ctx)->references), 1, CRYPTO_LOCK_SSL_CTX ); 128 return 1;
129 if( vc_store && vc_store != SSL_CTX_get_app_data(*ctx) ) {
130 SSL_CTX_set_cert_store(*ctx, vc_x509store_create(vc_store));
131 SSL_CTX_set_app_data(*ctx, vc_store);
132 }
133 } else {
134 *ctx = vc_create_sslctx(vc_store);
135 _ctx = 1;
136 }
137 129
138 ssl_conn = BIO_new_ssl(*ctx, 1); 130 ssl_conn = BIO_new_ssl(ctx, 1);
139 if(_ctx) 131 SSL_CTX_free(ctx);
140 SSL_CTX_free(*ctx);
141 132
142 if( ssl_conn ) { 133 if( ssl_conn ) {
143 BIO_push( ssl_conn, *conn ); 134 BIO_push( ssl_conn, *conn );
@@ -153,88 +144,6 @@ int vc_connect_ssl( BIO **conn, vc_x509store_t *vc_store, SSL_CTX **ctx)
153 return 1; 144 return 1;
154} 145}
155 146
156int vc_verify_cert_hostname(X509 *cert, char *host)
157{
158 int i = 0;
159 int j = 0;
160 int n = 0;
161 int extcount = 0;
162 int ok = 0;
163
164 X509_NAME *subj = NULL;
165 const char *extstr = NULL;
166 CONF_VALUE *nval = NULL;
167 const unsigned char *data = NULL;
168 X509_EXTENSION *ext = NULL;
169 X509V3_EXT_METHOD *meth = NULL;
170 STACK_OF(CONF_VALUE) *val = NULL;
171
172 char name[256];
173 memset(&name, 0, sizeof(name));
174
175 if((extcount = X509_get_ext_count(cert)) > 0) {
176
177 for(i=0; !ok && i < extcount; i++) {
178
179 meth = NULL;
180
181 ext = X509_get_ext(cert, i);
182 extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
183
184 if(!strcasecmp(extstr, "subjectAltName")) {
185
186 if( !(meth = X509V3_EXT_get(ext)) )
187 break;
188
189 if( !(meth->d2i) )
190 break;
191
192 data = ext->value->data;
193
194 val = meth->i2v(meth, meth->d2i(0, &data, ext->value->length), 0);
195 for( j=0, n=sk_CONF_VALUE_num(val); j<n; j++ ) {
196 nval = sk_CONF_VALUE_value(val, j);
197 if( !strcasecmp(nval->name, "DNS") &&
198 !strcasecmp(nval->value, host) ) {
199 ok = 1;
200 break;
201 }
202 }
203 }
204 }
205 }
206
207 if( !ok && (subj = X509_get_subject_name(cert)) &&
208 X509_NAME_get_text_by_NID(subj, NID_commonName,
209 name, sizeof(name)) > 0 ) {
210 name[sizeof(name)-1] = '\0';
211 if(!strcasecmp(name, host))
212 ok = 1;
213 }
214
215 //printf("[*] vc_verify_cert_hostname() return: %d\n", ok);
216 return(ok);
217}
218
219int vc_verify_cert(X509 *cert, vc_x509store_t *vc_store)
220{
221 int result = -1;
222 X509_STORE *store = NULL;
223 X509_STORE_CTX *ctx = NULL;
224
225 if( !(store = vc_x509store_create(vc_store)) )
226 return(result);
227
228 if( (ctx = X509_STORE_CTX_new()) != 0 ) {
229 if(X509_STORE_CTX_init(ctx, store, cert, 0) == 1)
230 result = (X509_verify_cert(ctx) == 1);
231 X509_STORE_CTX_free(ctx);
232 }
233
234 X509_STORE_free(store);
235 return(result);
236}
237
238#define VC_STORE_ERR_EXIT(s) do { \ 147#define VC_STORE_ERR_EXIT(s) do { \
239 fprintf(stderr, "[E] SSL_STORE: %s\n", ERR_error_string (ERR_get_error (), NULL)); \ 148 fprintf(stderr, "[E] SSL_STORE: %s\n", ERR_error_string (ERR_get_error (), NULL)); \
240 if(s) X509_STORE_free(s); \ 149 if(s) X509_STORE_free(s); \
@@ -300,7 +209,7 @@ int vc_verify_callback(int ok, X509_STORE_CTX *store)
300{ 209{
301 if(!ok) { 210 if(!ok) {
302 /* XXX handle action/abort */ 211 /* XXX handle action/abort */
303 if(!ignore_ssl) 212 if(!(ok=getintoption(CF_IGNSSL)))
304 snprintf(tmpstr, TMPSTRSIZE, "[SSL ERROR] %s", 213 snprintf(tmpstr, TMPSTRSIZE, "[SSL ERROR] %s",
305 X509_verify_cert_error_string(store->error)); 214 X509_verify_cert_error_string(store->error));
306 else 215 else
@@ -308,7 +217,6 @@ int vc_verify_callback(int ok, X509_STORE_CTX *store)
308 X509_verify_cert_error_string(store->error)); 217 X509_verify_cert_error_string(store->error));
309 218
310 writecf(FS_ERR, tmpstr); 219 writecf(FS_ERR, tmpstr);
311 ok = ignore_ssl;
312 } 220 }
313 return(ok); 221 return(ok);
314} 222}
@@ -318,12 +226,6 @@ void vc_x509store_setflags(vc_x509store_t *store, int flags)
318 store->flags |= flags; 226 store->flags |= flags;
319} 227}
320 228
321void vc_x509store_setignssl(vc_x509store_t *store, int ignore)
322{
323 store->ignore_ssl |= ignore;
324 ignore_ssl = ignore;
325}
326
327void vc_x509store_clearflags(vc_x509store_t *store, int flags) 229void vc_x509store_clearflags(vc_x509store_t *store, int flags)
328{ 230{
329 store->flags &= ~flags; 231 store->flags &= ~flags;
@@ -348,31 +250,31 @@ void vc_x509store_addcert(vc_x509store_t *store, X509 *cert)
348 250
349void vc_x509store_setcafile(vc_x509store_t *store, char *file) 251void vc_x509store_setcafile(vc_x509store_t *store, char *file)
350{ 252{
351 if( store->cafile) free(store->cafile); 253 free(store->cafile);
352 store->cafile = ( file ? strdup(file) : 0 ); 254 store->cafile = ( file ? strdup(file) : 0 );
353} 255}
354 256
355void vc_x509store_setcapath(vc_x509store_t *store, char *path) 257void vc_x509store_setcapath(vc_x509store_t *store, char *path)
356{ 258{
357 if( store->capath) free(store->capath); 259 free(store->capath);
358 store->capath = ( path ? strdup(path) : 0 ); 260 store->capath = ( path ? strdup(path) : 0 );
359} 261}
360 262
361void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) 263void vc_x509store_setcrlfile(vc_x509store_t *store, char *file)
362{ 264{
363 if( store->crlfile) free(store->crlfile); 265 free(store->crlfile);
364 store->crlfile = ( file ? strdup(file) : 0 ); 266 store->crlfile = ( file ? strdup(file) : 0 );
365} 267}
366 268
367void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) 269void vc_x509store_setkeyfile(vc_x509store_t *store, char *file)
368{ 270{
369 if( store->use_keyfile) free(store->use_keyfile); 271 free(store->use_keyfile);
370 store->use_keyfile = ( file ? strdup(file) : 0 ); 272 store->use_keyfile = ( file ? strdup(file) : 0 );
371} 273}
372 274
373void vc_x509store_setcertfile(vc_x509store_t *store, char *file) 275void vc_x509store_setcertfile(vc_x509store_t *store, char *file)
374{ 276{
375 if( store->use_certfile) free(store->use_certfile); 277 free(store->use_certfile);
376 store->use_certfile = ( file ? strdup(file) : 0 ); 278 store->use_certfile = ( file ? strdup(file) : 0 );
377} 279}
378 280
@@ -391,19 +293,17 @@ void vc_init_x509store(vc_x509store_t *s)
391 s->use_keyfile = NULL; 293 s->use_keyfile = NULL;
392 s->use_key = NULL; 294 s->use_key = NULL;
393 s->flags = 0; 295 s->flags = 0;
394 s->ignore_ssl = 0;
395} 296}
396 297
397void vc_cleanup_x509store(vc_x509store_t *s) 298void vc_cleanup_x509store(vc_x509store_t *s)
398{ 299{
399 if(s->cafile) free(s->cafile); 300 free(s->cafile);
400 if(s->capath) free(s->capath); 301 free(s->capath);
401 if(s->crlfile) free(s->crlfile); 302 free(s->crlfile);
402 if(s->use_certfile) free(s->use_certfile); 303 free(s->use_certfile);
403 if(s->use_keyfile) free(s->use_keyfile); 304 free(s->use_keyfile);
404 if(s->use_key) free(s->use_key); 305 free(s->use_key);
405 sk_X509_free(s->certs); 306 sk_X509_free(s->certs);
406 sk_X509_free(s->crls); 307 sk_X509_free(s->crls);
407 sk_X509_free(s->use_certs); 308 sk_X509_free(s->use_certs);
408 s->ignore_ssl = 0;
409} 309}
diff --git a/vchat-ssl.h b/vchat-ssl.h
index c745c97..baaa3c4 100755
--- a/vchat-ssl.h
+++ b/vchat-ssl.h
@@ -16,12 +16,11 @@ typedef struct {
16 char *use_keyfile; 16 char *use_keyfile;
17 EVP_PKEY *use_key; 17 EVP_PKEY *use_key;
18 int flags; 18 int flags;
19 int ignore_ssl;
20} vc_x509store_t; 19} vc_x509store_t;
21 20
22/* prototypes */ 21/* prototypes */
23 22
24int vc_connect_ssl(BIO **conn, vc_x509store_t *, SSL_CTX **); 23int vc_connect_ssl(BIO **conn, vc_x509store_t * );
25SSL_CTX * vc_create_sslctx( vc_x509store_t *); 24SSL_CTX * vc_create_sslctx( vc_x509store_t *);
26void vc_init_x509store(vc_x509store_t *); 25void vc_init_x509store(vc_x509store_t *);
27void vc_cleanup_x509store(vc_x509store_t *); 26void vc_cleanup_x509store(vc_x509store_t *);
@@ -34,15 +33,12 @@ void vc_x509store_addcert(vc_x509store_t *, X509 *);
34void vc_x509store_setcb(vc_x509store_t *, vc_x509verify_cb_t); 33void vc_x509store_setcb(vc_x509store_t *, vc_x509verify_cb_t);
35void vc_x509store_set_pkeycb(vc_x509store_t *, vc_askpass_cb_t); 34void vc_x509store_set_pkeycb(vc_x509store_t *, vc_askpass_cb_t);
36void vc_x509store_setflags(vc_x509store_t *, int); 35void vc_x509store_setflags(vc_x509store_t *, int);
37void vc_x509store_setignssl(vc_x509store_t *, int);
38void vc_x509store_clearflags(vc_x509store_t *, int); 36void vc_x509store_clearflags(vc_x509store_t *, int);
39int vc_verify_cert(X509 *, vc_x509store_t *);
40int vc_verify_cert_hostname(X509 *, char *);
41int vc_verify_callback(int, X509_STORE_CTX *); 37int vc_verify_callback(int, X509_STORE_CTX *);
42X509_STORE * vc_x509store_create(vc_x509store_t *); 38X509_STORE * vc_x509store_create(vc_x509store_t *);
43 39
44#define VC_X509S_NODEF_CAFILE 0x01 40#define VC_X509S_NODEF_CAFILE 0x01
45#define VC_X509S_NODEF_CAPATH 0x02 41#define VC_X509S_NODEF_CAPATH 0x02
46#define VC_X509S_USE_CERTIFICATE 0x04 42#define VC_X509S_USE_CERTIFICATE 0x04
47#define VC_X509S_SSL_VERIFY_NONE 0x10 43#define VC_X509S_SSL_VERIFY_NONE 0x10
48#define VC_X509S_SSL_VERIFY_PEER 0x20 44#define VC_X509S_SSL_VERIFY_PEER 0x20