diff options
| author | erdgeist <> | 2007-06-27 21:59:32 +0000 | 
|---|---|---|
| committer | erdgeist <> | 2007-06-27 21:59:32 +0000 | 
| commit | 3c11bea99886b006ca499e1be6a3a17d225cedc7 (patch) | |
| tree | 687a3e0e762669af85c5858420856b49686795cd /vchat-ssl.c | |
| parent | d4861ca31f0406f5c49023bc2c3bc4cfa54e3693 (diff) | |
Introducing new ssl code
Diffstat (limited to 'vchat-ssl.c')
| -rwxr-xr-x | vchat-ssl.c | 467 | 
1 files changed, 467 insertions, 0 deletions
| diff --git a/vchat-ssl.c b/vchat-ssl.c new file mode 100755 index 0000000..5d68309 --- /dev/null +++ b/vchat-ssl.c | |||
| @@ -0,0 +1,467 @@ | |||
| 1 | /* | ||
| 2 | * vchat-client - alpha version | ||
| 3 | * vchat-ssl.c - handling of SSL connection and X509 certificate | ||
| 4 | * verification | ||
| 5 | * | ||
| 6 | * Copyright (C) 2007 Thorsten Schroeder <ths@berlin.ccc.de> | ||
| 7 | * | ||
| 8 | * This program is free software. It can be redistributed and/or modified, | ||
| 9 | * provided that this copyright notice is kept intact. This program is | ||
| 10 | * distributed in the hope that it will be useful, but without any warranty; | ||
| 11 | * without even the implied warranty of merchantability or fitness for a | ||
| 12 | * particular purpose. In no event shall the copyright holder be liable for | ||
| 13 | * any direct, indirect, incidental or special damages arising in any way out | ||
| 14 | * of the use of this software. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdio.h> | ||
| 19 | #include <stdlib.h> | ||
| 20 | #include <string.h> | ||
| 21 | |||
| 22 | #include <openssl/err.h> | ||
| 23 | #include <openssl/ssl.h> | ||
| 24 | #include <openssl/bio.h> | ||
| 25 | #include <openssl/evp.h> | ||
| 26 | #include <openssl/x509.h> | ||
| 27 | #include <openssl/x509v3.h> | ||
| 28 | #include <openssl/conf.h> | ||
| 29 | |||
| 30 | #include "vchat.h" | ||
| 31 | #include "vchat-ssl.h" | ||
| 32 | |||
| 33 | char *vchat_ssl_version = "$Id$"; | ||
| 34 | |||
| 35 | static int ignore_ssl; | ||
| 36 | |||
| 37 | #define VC_CTX_ERR_EXIT(se, cx) do { \ | ||
| 38 | snprintf(tmpstr, TMPSTRSIZE, "CREATE CTX: %s", \ | ||
| 39 | ERR_error_string (ERR_get_error (), NULL)); \ | ||
| 40 | writecf(FS_ERR, tmpstr); \ | ||
| 41 | if(se) X509_STORE_free(se); \ | ||
| 42 | if(cx) SSL_CTX_free(cx); \ | ||
| 43 | return(0); \ | ||
| 44 | } while(0) | ||
| 45 | |||
| 46 | #define VC_SETCERT_ERR_EXIT(se, cx, err) do { \ | ||
| 47 | snprintf(tmpstr, TMPSTRSIZE, "CREATE CTX: %s", err); \ | ||
| 48 | writecf(FS_ERR, tmpstr); \ | ||
| 49 | if(se) X509_STORE_free(se); \ | ||
| 50 | if(cx) SSL_CTX_free(cx); \ | ||
| 51 | return(NULL); \ | ||
| 52 | } while(0) | ||
| 53 | |||
| 54 | SSL_CTX * vc_create_sslctx( vc_x509store_t *vc_store ) | ||
| 55 | { | ||
| 56 | int i = 0; | ||
| 57 | int n = 0; | ||
| 58 | int flags = 0; | ||
| 59 | int r = 0; | ||
| 60 | SSL_CTX *ctx = NULL; | ||
| 61 | X509_STORE *store = NULL; | ||
| 62 | vc_x509verify_cb_t verify_callback = NULL; | ||
| 63 | |||
| 64 | if( !(ctx = SSL_CTX_new(SSLv3_method())) ) | ||
| 65 | VC_CTX_ERR_EXIT(store, ctx); | ||
| 66 | |||
| 67 | if( !(store = vc_x509store_create(vc_store)) ) | ||
| 68 | VC_CTX_ERR_EXIT(store, ctx); | ||
| 69 | |||
| 70 | SSL_CTX_set_cert_store(ctx, store); | ||
| 71 | store = NULL; | ||
| 72 | SSL_CTX_set_options(ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2); | ||
| 73 | SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); | ||
| 74 | |||
| 75 | SSL_CTX_set_verify_depth (ctx, 2); | ||
| 76 | |||
| 77 | if( !(verify_callback = vc_store->callback) ) | ||
| 78 | verify_callback = vc_verify_callback; | ||
| 79 | |||
| 80 | if( !(vc_store->flags & VC_X509S_SSL_VERIFY_MASK) ) { | ||
| 81 | writecf(FS_DBG, tmpstr); | ||
| 82 | flags = SSL_VERIFY_NONE; | ||
| 83 | } | ||
| 84 | else { | ||
| 85 | if(vc_store->flags & VC_X509S_SSL_VERIFY_PEER) | ||
| 86 | flags |= SSL_VERIFY_PEER; | ||
| 87 | if(vc_store->flags & VC_X509S_SSL_VERIFY_FAIL_IF_NO_PEER_CERT) | ||
| 88 | flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; | ||
| 89 | if(vc_store->flags & VC_X509S_SSL_VERIFY_CLIENT_ONCE) | ||
| 90 | flags |= SSL_VERIFY_CLIENT_ONCE; | ||
| 91 | } | ||
| 92 | |||
| 93 | SSL_CTX_set_verify(ctx, flags, verify_callback); | ||
| 94 | |||
| 95 | if(vc_store->flags & VC_X509S_USE_CERTIFICATE) { | ||
| 96 | if(vc_store->use_certfile) | ||
| 97 | SSL_CTX_use_certificate_chain_file(ctx, vc_store->use_certfile); | ||
| 98 | else { | ||
| 99 | SSL_CTX_use_certificate(ctx, | ||
| 100 | sk_X509_value(vc_store->use_certs, 0)); | ||
| 101 | for(i=0,n=sk_X509_num(vc_store->use_certs); i<n; i++) | ||
| 102 | SSL_CTX_add_extra_chain_cert(ctx, | ||
| 103 | sk_X509_value(vc_store->use_certs, i)); | ||
| 104 | } | ||
| 105 | |||
| 106 | SSL_CTX_set_default_passwd_cb(ctx, vc_store->askpass_callback); | ||
| 107 | |||
| 108 | if(vc_store->use_keyfile) { | ||
| 109 | r=SSL_CTX_use_PrivateKey_file(ctx, vc_store->use_keyfile, | ||
| 110 | SSL_FILETYPE_PEM); | ||
| 111 | } else if(vc_store->use_key) | ||
| 112 | r=SSL_CTX_use_PrivateKey(ctx, vc_store->use_key); | ||
| 113 | |||
| 114 | if(r!=1) | ||
| 115 | VC_SETCERT_ERR_EXIT(store, ctx, "Load private key failed"); | ||
| 116 | |||
| 117 | } | ||
| 118 | |||
| 119 | SSL_CTX_set_app_data(ctx, vc_store); | ||
| 120 | return(ctx); | ||
| 121 | } | ||
| 122 | |||
| 123 | #define VC_CONNSSL_ERR_EXIT(_cx, cx, cn) do { \ | ||
| 124 | snprintf(tmpstr, TMPSTRSIZE, "[SSL ERROR] %s", \ | ||
| 125 | ERR_error_string (ERR_get_error (), NULL)); \ | ||
| 126 | writecf(FS_ERR, tmpstr); \ | ||
| 127 | if(cn) BIO_free_all(cn); \ | ||
| 128 | if(*cx) SSL_CTX_free(*cx); \ | ||
| 129 | if(_cx) *cx = 0; \ | ||
| 130 | return(0); \ | ||
| 131 | } while(0) | ||
| 132 | |||
| 133 | BIO * vc_connect_ssl(char *host, int port, vc_x509store_t *vc_store, | ||
| 134 | SSL_CTX **ctx) | ||
| 135 | { | ||
| 136 | BIO *conn = NULL; | ||
| 137 | int _ctx = 0; | ||
| 138 | |||
| 139 | if(*ctx) { | ||
| 140 | CRYPTO_add( &((*ctx)->references), 1, CRYPTO_LOCK_SSL_CTX ); | ||
| 141 | if( vc_store && vc_store != SSL_CTX_get_app_data(*ctx) ) { | ||
| 142 | SSL_CTX_set_cert_store(*ctx, vc_x509store_create(vc_store)); | ||
| 143 | SSL_CTX_set_app_data(*ctx, vc_store); | ||
| 144 | } | ||
| 145 | } else { | ||
| 146 | *ctx = vc_create_sslctx(vc_store); | ||
| 147 | _ctx = 1; | ||
| 148 | } | ||
| 149 | |||
| 150 | if( !(conn = BIO_new_ssl_connect(*ctx)) ) | ||
| 151 | VC_CONNSSL_ERR_EXIT(_ctx, ctx, conn); | ||
| 152 | |||
| 153 | BIO_set_conn_hostname(conn, host); | ||
| 154 | BIO_set_conn_int_port(conn, &port); | ||
| 155 | |||
| 156 | fflush(stdout); | ||
| 157 | if(BIO_do_connect(conn) <= 0) | ||
| 158 | VC_CONNSSL_ERR_EXIT(_ctx, ctx, conn); | ||
| 159 | |||
| 160 | if(_ctx) | ||
| 161 | SSL_CTX_free(*ctx); | ||
| 162 | |||
| 163 | return(conn); | ||
| 164 | } | ||
| 165 | |||
| 166 | #define VC_CONN_ERR_EXIT(cn) do { \ | ||
| 167 | snprintf(tmpstr, TMPSTRSIZE, "[SSL ERROR] %s", \ | ||
| 168 | ERR_error_string(ERR_get_error(), NULL)); \ | ||
| 169 | if(ERR_get_error()) \ | ||
| 170 | writecf(FS_ERR, tmpstr); \ | ||
| 171 | if(cn) BIO_free_all(cn); \ | ||
| 172 | return(NULL); \ | ||
| 173 | } while(0) | ||
| 174 | |||
| 175 | #define VC_VERIFICATION_ERR_EXIT(cn, err) do { \ | ||
| 176 | snprintf(tmpstr, TMPSTRSIZE, \ | ||
| 177 | "[SSL ERROR] certificate verify failed: %s", err); \ | ||
| 178 | writecf(FS_ERR, tmpstr); \ | ||
| 179 | if(cn && !ignore_ssl) { BIO_free_all(cn); return(NULL); } \ | ||
| 180 | } while(0) | ||
| 181 | |||
| 182 | BIO * vc_connect( char *host, int port, int use_ssl, | ||
| 183 | vc_x509store_t *vc_store, SSL_CTX **ctx) | ||
| 184 | { | ||
| 185 | BIO *conn = NULL; | ||
| 186 | SSL *ssl = NULL; | ||
| 187 | |||
| 188 | if(use_ssl) { | ||
| 189 | if( !(conn = vc_connect_ssl(host, port, vc_store, ctx)) ) | ||
| 190 | VC_CONN_ERR_EXIT(conn); | ||
| 191 | |||
| 192 | |||
| 193 | BIO_get_ssl(conn, &ssl); | ||
| 194 | if(!vc_verify_cert_hostname(SSL_get_peer_certificate(ssl), host)) | ||
| 195 | VC_VERIFICATION_ERR_EXIT(conn, "Hostname does not match!"); | ||
| 196 | |||
| 197 | return(conn); | ||
| 198 | } | ||
| 199 | |||
| 200 | *ctx = 0; | ||
| 201 | |||
| 202 | if( !(conn = BIO_new_connect(host)) ) | ||
| 203 | VC_CONN_ERR_EXIT(conn); | ||
| 204 | |||
| 205 | BIO_set_conn_int_port(conn, &port); | ||
| 206 | |||
| 207 | if(BIO_do_connect(conn) <= 0) | ||
| 208 | VC_CONN_ERR_EXIT(conn); | ||
| 209 | |||
| 210 | return(conn); | ||
| 211 | } | ||
| 212 | |||
| 213 | int vc_verify_cert_hostname(X509 *cert, char *host) | ||
| 214 | { | ||
| 215 | |||
| 216 | int i = 0; | ||
| 217 | int j = 0; | ||
| 218 | int n = 0; | ||
| 219 | int extcount = 0; | ||
| 220 | int ok = 0; | ||
| 221 | |||
| 222 | X509_NAME *subj = NULL; | ||
| 223 | const char *extstr = NULL; | ||
| 224 | CONF_VALUE *nval = NULL; | ||
| 225 | unsigned char *data = NULL; | ||
| 226 | X509_EXTENSION *ext = NULL; | ||
| 227 | X509V3_EXT_METHOD *meth = NULL; | ||
| 228 | STACK_OF(CONF_VALUE) *val = NULL; | ||
| 229 | |||
| 230 | char name[256]; | ||
| 231 | memset(&name, 0, sizeof(name)); | ||
| 232 | |||
| 233 | if((extcount = X509_get_ext_count(cert)) > 0) { | ||
| 234 | |||
| 235 | for(i=0; !ok && i < extcount; i++) { | ||
| 236 | |||
| 237 | meth = NULL; | ||
| 238 | |||
| 239 | ext = X509_get_ext(cert, i); | ||
| 240 | extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); | ||
| 241 | |||
| 242 | if(!strcasecmp(extstr, "subjectAltName")) { | ||
| 243 | |||
| 244 | if( !(meth = X509V3_EXT_get(ext)) ) | ||
| 245 | break; | ||
| 246 | |||
| 247 | if( !(meth->d2i) ) | ||
| 248 | break; | ||
| 249 | |||
| 250 | data = ext->value->data; | ||
| 251 | |||
| 252 | val = meth->i2v(meth, meth->d2i(0, &data, ext->value->length), 0); | ||
| 253 | for( j=0, n=sk_CONF_VALUE_num(val); j<n; j++ ) { | ||
| 254 | nval = sk_CONF_VALUE_value(val, j); | ||
| 255 | if( !strcasecmp(nval->name, "DNS") && | ||
| 256 | !strcasecmp(nval->value, host) ) { | ||
| 257 | ok = 1; | ||
| 258 | break; | ||
| 259 | } | ||
| 260 | } | ||
| 261 | } | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | if( !ok && (subj = X509_get_subject_name(cert)) && | ||
| 266 | X509_NAME_get_text_by_NID(subj, NID_commonName, | ||
| 267 | name, sizeof(name)) > 0 ) { | ||
| 268 | name[sizeof(name)-1] = '\0'; | ||
| 269 | if(!strcasecmp(name, host)) | ||
| 270 | ok = 1; | ||
| 271 | } | ||
| 272 | |||
| 273 | //printf("[*] vc_verify_cert_hostname() return: %d\n", ok); | ||
| 274 | return(ok); | ||
| 275 | } | ||
| 276 | |||
| 277 | int vc_verify_cert(X509 *cert, vc_x509store_t *vc_store) | ||
| 278 | { | ||
| 279 | int result = -1; | ||
| 280 | X509_STORE *store = NULL; | ||
| 281 | X509_STORE_CTX *ctx = NULL; | ||
| 282 | |||
| 283 | if( !(store = vc_x509store_create(vc_store)) ) | ||
| 284 | return(result); | ||
| 285 | |||
| 286 | if( (ctx = X509_STORE_CTX_new()) != 0 ) { | ||
| 287 | if(X509_STORE_CTX_init(ctx, store, cert, 0) == 1) | ||
| 288 | result = (X509_verify_cert(ctx) == 1); | ||
| 289 | X509_STORE_CTX_free(ctx); | ||
| 290 | } | ||
| 291 | |||
| 292 | X509_STORE_free(store); | ||
| 293 | return(result); | ||
| 294 | } | ||
| 295 | |||
| 296 | #define VC_STORE_ERR_EXIT(s) do { \ | ||
| 297 | fprintf(stderr, "[E] SSL_STORE: %s\n", ERR_error_string (ERR_get_error (), NULL)); \ | ||
| 298 | if(s) X509_STORE_free(s); \ | ||
| 299 | return(0); \ | ||
| 300 | } while(0) | ||
| 301 | |||
| 302 | X509_STORE *vc_x509store_create(vc_x509store_t *vc_store) | ||
| 303 | { | ||
| 304 | int i = 0; | ||
| 305 | int n = 0; | ||
| 306 | X509_STORE *store = NULL; | ||
| 307 | X509_LOOKUP *lookup = NULL; | ||
| 308 | |||
| 309 | store = X509_STORE_new(); | ||
| 310 | |||
| 311 | if(vc_store->callback) | ||
| 312 | X509_STORE_set_verify_cb_func(store, vc_store->callback); | ||
| 313 | else | ||
| 314 | X509_STORE_set_verify_cb_func(store, vc_verify_callback); | ||
| 315 | |||
| 316 | if( !(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) ) | ||
| 317 | VC_STORE_ERR_EXIT(store); | ||
| 318 | |||
| 319 | if(!vc_store->cafile) { | ||
| 320 | if( !(vc_store->flags & VC_X509S_NODEF_CAFILE) ) | ||
| 321 | X509_LOOKUP_load_file(lookup, 0, X509_FILETYPE_DEFAULT); | ||
| 322 | } else if( !X509_LOOKUP_load_file(lookup, vc_store->cafile, | ||
| 323 | X509_FILETYPE_PEM) ) | ||
| 324 | VC_STORE_ERR_EXIT(store); | ||
| 325 | |||
| 326 | if(vc_store->crlfile) { | ||
| 327 | if( !X509_load_crl_file(lookup, vc_store->crlfile, | ||
| 328 | X509_FILETYPE_PEM) ) | ||
| 329 | VC_STORE_ERR_EXIT(store); | ||
| 330 | |||
| 331 | X509_STORE_set_flags( store, | ||
| 332 | X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL ); | ||
| 333 | } | ||
| 334 | |||
| 335 | if( !(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir())) ) | ||
| 336 | VC_STORE_ERR_EXIT(store); | ||
| 337 | |||
| 338 | if( !vc_store->capath ) { | ||
| 339 | if( !(vc_store->flags & VC_X509S_NODEF_CAPATH) ) | ||
| 340 | X509_LOOKUP_add_dir(lookup, 0, X509_FILETYPE_DEFAULT); | ||
| 341 | } else if( !X509_LOOKUP_add_dir(lookup, vc_store->capath, | ||
| 342 | X509_FILETYPE_PEM) ) | ||
| 343 | VC_STORE_ERR_EXIT(store); | ||
| 344 | |||
| 345 | for( i=0, n=sk_X509_num(vc_store->certs); i<n; i++) | ||
| 346 | if( !X509_STORE_add_cert(store, sk_X509_value(vc_store->certs, i)) ) | ||
| 347 | VC_STORE_ERR_EXIT(store); | ||
| 348 | |||
| 349 | for( i=0, n=sk_X509_CRL_num(vc_store->crls); i<n; i++) | ||
| 350 | if( !X509_STORE_add_crl(store, | ||
| 351 | sk_X509_CRL_value(vc_store->crls, i)) ) | ||
| 352 | VC_STORE_ERR_EXIT(store); | ||
| 353 | |||
| 354 | return(store); | ||
| 355 | } | ||
| 356 | |||
| 357 | int vc_verify_callback(int ok, X509_STORE_CTX *store) | ||
| 358 | { | ||
| 359 | if(!ok) { | ||
| 360 | /* XXX handle action/abort */ | ||
| 361 | if(!ignore_ssl) | ||
| 362 | snprintf(tmpstr, TMPSTRSIZE, "[SSL ERROR] %s", | ||
| 363 | X509_verify_cert_error_string(store->error)); | ||
| 364 | else | ||
| 365 | snprintf(tmpstr, TMPSTRSIZE, "[SSL ERROR] %s (ignored)", | ||
| 366 | X509_verify_cert_error_string(store->error)); | ||
| 367 | |||
| 368 | writecf(FS_ERR, tmpstr); | ||
| 369 | ok = ignore_ssl; | ||
| 370 | } | ||
| 371 | return(ok); | ||
| 372 | } | ||
| 373 | |||
| 374 | void vc_x509store_setflags(vc_x509store_t *store, int flags) | ||
| 375 | { | ||
| 376 | store->flags |= flags; | ||
| 377 | } | ||
| 378 | |||
| 379 | void vc_x509store_setignssl(vc_x509store_t *store, int ignore) | ||
| 380 | { | ||
| 381 | store->ignore_ssl |= ignore; | ||
| 382 | ignore_ssl = ignore; | ||
| 383 | } | ||
| 384 | |||
| 385 | void vc_x509store_clearflags(vc_x509store_t *store, int flags) | ||
| 386 | { | ||
| 387 | store->flags &= ~flags; | ||
| 388 | } | ||
| 389 | |||
| 390 | void vc_x509store_setcb(vc_x509store_t *store, | ||
| 391 | vc_x509verify_cb_t callback) | ||
| 392 | { | ||
| 393 | store->callback = callback; | ||
| 394 | } | ||
| 395 | |||
| 396 | void vc_x509store_set_pkeycb(vc_x509store_t *store, | ||
| 397 | vc_askpass_cb_t callback) | ||
| 398 | { | ||
| 399 | store->askpass_callback = callback; | ||
| 400 | } | ||
| 401 | |||
| 402 | void vc_x509store_addcert(vc_x509store_t *store, X509 *cert) | ||
| 403 | { | ||
| 404 | sk_X509_push(store->certs, cert); | ||
| 405 | } | ||
| 406 | |||
| 407 | void vc_x509store_setcafile(vc_x509store_t *store, char *file) | ||
| 408 | { | ||
| 409 | if( store->cafile) free(store->cafile); | ||
| 410 | store->cafile = ( file ? strdup(file) : 0 ); | ||
| 411 | } | ||
| 412 | |||
| 413 | void vc_x509store_setcapath(vc_x509store_t *store, char *path) | ||
| 414 | { | ||
| 415 | if( store->capath) free(store->capath); | ||
| 416 | store->capath = ( path ? strdup(path) : 0 ); | ||
| 417 | } | ||
| 418 | |||
| 419 | void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) | ||
| 420 | { | ||
| 421 | if( store->crlfile) free(store->crlfile); | ||
| 422 | store->crlfile = ( file ? strdup(file) : 0 ); | ||
| 423 | } | ||
| 424 | |||
| 425 | void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) | ||
| 426 | { | ||
| 427 | if( store->use_keyfile) free(store->use_keyfile); | ||
| 428 | store->use_keyfile = ( file ? strdup(file) : 0 ); | ||
| 429 | } | ||
| 430 | |||
| 431 | void vc_x509store_setcertfile(vc_x509store_t *store, char *file) | ||
| 432 | { | ||
| 433 | if( store->use_certfile) free(store->use_certfile); | ||
| 434 | store->use_certfile = ( file ? strdup(file) : 0 ); | ||
| 435 | } | ||
| 436 | |||
| 437 | |||
| 438 | void vc_init_x509store(vc_x509store_t *s) | ||
| 439 | { | ||
| 440 | s->cafile = NULL; | ||
| 441 | s->capath = NULL; | ||
| 442 | s->crlfile = NULL; | ||
| 443 | s->callback = NULL; | ||
| 444 | s->askpass_callback = NULL; | ||
| 445 | s->certs = sk_X509_new_null(); | ||
| 446 | s->crls = sk_X509_CRL_new_null(); | ||
| 447 | s->use_certfile = NULL; | ||
| 448 | s->use_certs = sk_X509_new_null(); | ||
| 449 | s->use_keyfile = NULL; | ||
| 450 | s->use_key = NULL; | ||
| 451 | s->flags = 0; | ||
| 452 | s->ignore_ssl = 0; | ||
| 453 | } | ||
| 454 | |||
| 455 | void vc_cleanup_x509store(vc_x509store_t *s) | ||
| 456 | { | ||
| 457 | if(s->cafile) free(s->cafile); | ||
| 458 | if(s->capath) free(s->capath); | ||
| 459 | if(s->crlfile) free(s->crlfile); | ||
| 460 | if(s->use_certfile) free(s->use_certfile); | ||
| 461 | if(s->use_keyfile) free(s->use_keyfile); | ||
| 462 | if(s->use_key) free(s->use_key); | ||
| 463 | sk_X509_free(s->certs); | ||
| 464 | sk_X509_free(s->crls); | ||
| 465 | sk_X509_free(s->use_certs); | ||
| 466 | s->ignore_ssl = 0; | ||
| 467 | } | ||
