diff options
Diffstat (limited to 'vchat-ssl.c')
-rwxr-xr-x | vchat-ssl.c | 144 |
1 files changed, 22 insertions, 122 deletions
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 | ||
33 | char *vchat_ssl_version = "$Id$"; | 35 | char *vchat_ssl_version = "$Id$"; |
34 | 36 | ||
35 | static 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 | ||
122 | int vc_connect_ssl( BIO **conn, vc_x509store_t *vc_store, SSL_CTX **ctx) | 122 | int 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 | ||
156 | int 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 | |||
219 | int 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 | ||
321 | void vc_x509store_setignssl(vc_x509store_t *store, int ignore) | ||
322 | { | ||
323 | store->ignore_ssl |= ignore; | ||
324 | ignore_ssl = ignore; | ||
325 | } | ||
326 | |||
327 | void vc_x509store_clearflags(vc_x509store_t *store, int flags) | 229 | void 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 | ||
349 | void vc_x509store_setcafile(vc_x509store_t *store, char *file) | 251 | void 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 | ||
355 | void vc_x509store_setcapath(vc_x509store_t *store, char *path) | 257 | void 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 | ||
361 | void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) | 263 | void 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 | ||
367 | void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) | 269 | void 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 | ||
373 | void vc_x509store_setcertfile(vc_x509store_t *store, char *file) | 275 | void 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 | ||
397 | void vc_cleanup_x509store(vc_x509store_t *s) | 298 | void 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 | } |