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 | } |
