📄 ssltest.c
字号:
sr_num -= r; } } *s_time += (clock() - s_clock); } { /* "I/O" BETWEEN CLIENT AND SERVER. */ size_t r1, r2; BIO *io1 = server_io, *io2 = client_io; /* we use the non-copying interface for io1 * and the standard BIO_write/BIO_read interface for io2 */ static int prev_progress = 1; int progress = 0; /* io1 to io2 */ do { size_t num; int r; r1 = BIO_ctrl_pending(io1); r2 = BIO_ctrl_get_write_guarantee(io2); num = r1; if (r2 < num) num = r2; if (num) { char *dataptr; if (INT_MAX < num) /* yeah, right */ num = INT_MAX; r = BIO_nread(io1, &dataptr, (int)num); assert(r > 0); assert(r <= (int)num); /* possibly r < num (non-contiguous data) */ num = r; r = BIO_write(io2, dataptr, (int)num); if (r != (int)num) /* can't happen */ { fprintf(stderr, "ERROR: BIO_write could not write " "BIO_ctrl_get_write_guarantee() bytes"); goto err; } progress = 1; if (debug) printf((io1 == client_io) ? "C->S relaying: %d bytes\n" : "S->C relaying: %d bytes\n", (int)num); } } while (r1 && r2); /* io2 to io1 */ { size_t num; int r; r1 = BIO_ctrl_pending(io2); r2 = BIO_ctrl_get_read_request(io1); /* here we could use ..._get_write_guarantee instead of * ..._get_read_request, but by using the latter * we test restartability of the SSL implementation * more thoroughly */ num = r1; if (r2 < num) num = r2; if (num) { char *dataptr; if (INT_MAX < num) num = INT_MAX; if (num > 1) --num; /* test restartability even more thoroughly */ r = BIO_nwrite0(io1, &dataptr); assert(r > 0); if (r < (int)num) num = r; r = BIO_read(io2, dataptr, (int)num); if (r != (int)num) /* can't happen */ { fprintf(stderr, "ERROR: BIO_read could not read " "BIO_ctrl_pending() bytes"); goto err; } progress = 1; r = BIO_nwrite(io1, &dataptr, (int)num); if (r != (int)num) /* can't happen */ { fprintf(stderr, "ERROR: BIO_nwrite() did not accept " "BIO_nwrite0() bytes"); goto err; } if (debug) printf((io2 == client_io) ? "C->S relaying: %d bytes\n" : "S->C relaying: %d bytes\n", (int)num); } } /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */ if (!progress && !prev_progress) if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) { fprintf(stderr, "ERROR: got stuck\n"); if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0) { fprintf(stderr, "This can happen for SSL2 because " "CLIENT-FINISHED and SERVER-VERIFY are written \n" "concurrently ..."); if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0 && strncmp("2SSV", SSL_state_string(s_ssl), 4) == 0) { fprintf(stderr, " ok.\n"); goto end; } } fprintf(stderr, " ERROR.\n"); goto err; } prev_progress = progress; } } while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); if (verbose) print_details(c_ssl, "DONE via BIO pair: ");end: ret = 0; err: ERR_print_errors(bio_err); if (server) BIO_free(server); if (server_io) BIO_free(server_io); if (client) BIO_free(client); if (client_io) BIO_free(client_io); if (s_ssl_bio) BIO_free(s_ssl_bio); if (c_ssl_bio) BIO_free(c_ssl_bio); return ret; }#define W_READ 1#define W_WRITE 2#define C_DONE 1#define S_DONE 2int doit(SSL *s_ssl, SSL *c_ssl, long count) { MS_STATIC char cbuf[1024*8],sbuf[1024*8]; long cw_num=count,cr_num=count; long sw_num=count,sr_num=count; int ret=1; BIO *c_to_s=NULL; BIO *s_to_c=NULL; BIO *c_bio=NULL; BIO *s_bio=NULL; int c_r,c_w,s_r,s_w; int c_want,s_want; int i,j; int done=0; int c_write,s_write; int do_server=0,do_client=0; memset(cbuf,0,sizeof(cbuf)); memset(sbuf,0,sizeof(sbuf)); c_to_s=BIO_new(BIO_s_mem()); s_to_c=BIO_new(BIO_s_mem()); if ((s_to_c == NULL) || (c_to_s == NULL)) { ERR_print_errors(bio_err); goto err; } c_bio=BIO_new(BIO_f_ssl()); s_bio=BIO_new(BIO_f_ssl()); if ((c_bio == NULL) || (s_bio == NULL)) { ERR_print_errors(bio_err); goto err; } SSL_set_connect_state(c_ssl); SSL_set_bio(c_ssl,s_to_c,c_to_s); BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE); SSL_set_accept_state(s_ssl); SSL_set_bio(s_ssl,c_to_s,s_to_c); BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE); c_r=0; s_r=1; c_w=1; s_w=0; c_want=W_WRITE; s_want=0; c_write=1,s_write=0; /* We can always do writes */ for (;;) { do_server=0; do_client=0; i=(int)BIO_pending(s_bio); if ((i && s_r) || s_w) do_server=1; i=(int)BIO_pending(c_bio); if ((i && c_r) || c_w) do_client=1; if (do_server && debug) { if (SSL_in_init(s_ssl)) printf("server waiting in SSL_accept - %s\n", SSL_state_string_long(s_ssl));/* else if (s_write) printf("server:SSL_write()\n"); else printf("server:SSL_read()\n"); */ } if (do_client && debug) { if (SSL_in_init(c_ssl)) printf("client waiting in SSL_connect - %s\n", SSL_state_string_long(c_ssl));/* else if (c_write) printf("client:SSL_write()\n"); else printf("client:SSL_read()\n"); */ } if (!do_client && !do_server) { fprintf(stdout,"ERROR IN STARTUP\n"); ERR_print_errors(bio_err); break; } if (do_client && !(done & C_DONE)) { if (c_write) { j = (cw_num > (long)sizeof(cbuf)) ? (int)sizeof(cbuf) : (int)cw_num; i=BIO_write(c_bio,cbuf,j); if (i < 0) { c_r=0; c_w=0; if (BIO_should_retry(c_bio)) { if (BIO_should_read(c_bio)) c_r=1; if (BIO_should_write(c_bio)) c_w=1; } else { fprintf(stderr,"ERROR in CLIENT\n"); ERR_print_errors(bio_err); goto err; } } else if (i == 0) { fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); goto err; } else { if (debug) printf("client wrote %d\n",i); /* ok */ s_r=1; c_write=0; cw_num-=i; } } else { i=BIO_read(c_bio,cbuf,sizeof(cbuf)); if (i < 0) { c_r=0; c_w=0; if (BIO_should_retry(c_bio)) { if (BIO_should_read(c_bio)) c_r=1; if (BIO_should_write(c_bio)) c_w=1; } else { fprintf(stderr,"ERROR in CLIENT\n"); ERR_print_errors(bio_err); goto err; } } else if (i == 0) { fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); goto err; } else { if (debug) printf("client read %d\n",i); cr_num-=i; if (sw_num > 0) { s_write=1; s_w=1; } if (cr_num <= 0) { s_write=1; s_w=1; done=S_DONE|C_DONE; } } } } if (do_server && !(done & S_DONE)) { if (!s_write) { i=BIO_read(s_bio,sbuf,sizeof(cbuf)); if (i < 0) { s_r=0; s_w=0; if (BIO_should_retry(s_bio)) { if (BIO_should_read(s_bio)) s_r=1; if (BIO_should_write(s_bio)) s_w=1; } else { fprintf(stderr,"ERROR in SERVER\n"); ERR_print_errors(bio_err); goto err; } } else if (i == 0) { ERR_print_errors(bio_err); fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_read\n"); goto err; } else { if (debug) printf("server read %d\n",i); sr_num-=i; if (cw_num > 0) { c_write=1; c_w=1; } if (sr_num <= 0) { s_write=1; s_w=1; c_write=0; } } } else { j = (sw_num > (long)sizeof(sbuf)) ? (int)sizeof(sbuf) : (int)sw_num; i=BIO_write(s_bio,sbuf,j); if (i < 0) { s_r=0; s_w=0; if (BIO_should_retry(s_bio)) { if (BIO_should_read(s_bio)) s_r=1; if (BIO_should_write(s_bio)) s_w=1; } else { fprintf(stderr,"ERROR in SERVER\n"); ERR_print_errors(bio_err); goto err; } } else if (i == 0) { ERR_print_errors(bio_err); fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_write\n"); goto err; } else { if (debug) printf("server wrote %d\n",i); sw_num-=i; s_write=0; c_r=1; if (sw_num <= 0) done|=S_DONE; } } } if ((done & S_DONE) && (done & C_DONE)) break; } if (verbose) print_details(c_ssl, "DONE: "); ret=0;err: /* We have to set the BIO's to NULL otherwise they will be * OPENSSL_free()ed twice. Once when th s_ssl is SSL_free()ed and * again when c_ssl is SSL_free()ed. * This is a hack required because s_ssl and c_ssl are sharing the same * BIO structure and SSL_set_bio() and SSL_free() automatically * BIO_free non NULL entries. * You should not normally do this or be required to do this */ if (s_ssl != NULL) { s_ssl->rbio=NULL; s_ssl->wbio=NULL; } if (c_ssl != NULL) { c_ssl->rbio=NULL; c_ssl->wbio=NULL; } if (c_to_s != NULL) BIO_free(c_to_s); if (s_to_c != NULL) BIO_free(s_to_c); if (c_bio != NULL) BIO_free_all(c_bio); if (s_bio != NULL) BIO_free_all(s_bio); return(ret); }static int get_proxy_auth_ex_data_idx(void) { static volatile int idx = -1; if (idx < 0) { CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); if (idx < 0) { idx = X509_STORE_CTX_get_ex_new_index(0, "SSLtest for verify callback", NULL,NULL,NULL); } CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); } return idx; }static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) { char *s,buf[256]; s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf, sizeof buf); if (s != NULL) { if (ok) fprintf(stderr,"depth=%d %s\n", ctx->error_depth,buf); else { fprintf(stderr,"depth=%d error=%d %s\n", ctx->error_depth,ctx->error,buf); } } if (ok == 0) { fprintf(stderr,"Error string: %s\n", X509_verify_cert_error_string(ctx->error)); switch (ctx->error) { case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: fprintf(stderr," ... ignored.\n"); ok=1; } } if (ok == 1) { X509 *xs = ctx->current_cert;#if 0 X509 *xi = ctx->current_issuer;#endif if (xs->ex_flags & EXFLAG_PROXY) { unsigned int *letters = X509_STORE_CTX_get_ex_data(ctx, get_proxy_auth_ex_data_idx()); if (letters) { int found_any = 0; int i; PROXY_CERT_INFO_EXTENSION *pci = X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL); switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) { case NID_Independent: /* Completely meaningless in this program, as there's no way to grant explicit rights to a specific PrC. Basically, using id-ppl-Independent is the perfect way to grant no rights at all. */ fprintf(stderr, " Independent proxy certificate"); for (i = 0; i < 26; i++) letters[i] = 0; break; case NID_id_ppl_inheritAll: /* This is basically a NOP, we simply let the current rights stand as they are. */ fprintf(stderr, " Proxy certificate inherits all"); break; default: s = (char *) pci->proxyPolicy->policy->data; i = pci->proxyPolicy->policy->length; /* The algorithm works as follows: it is assumed that previous iterations or the initial granted rights has already set some elements of `letters'. What we need to do is to clear those that weren't granted by the current PrC as well. The easiest way to do this is to add 1 to all the elements whose letters are given with the current policy. That way, all elements that are set by the current policy and were already set by earlier policies and through the original grant of rights will get the value 2 or higher. The last thing to do is to sweep
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -