ssltest.c

来自「一个用于点对点传输加密的工具包源码」· C语言 代码 · 共 1,371 行 · 第 1/3 页

C
1,371
字号
		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;	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))					?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))?					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 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,256);	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)		{		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:			ok=1;			}		}	return(ok);	}#ifndef NO_RSAstatic RSA *rsa_tmp=NULL;static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)	{	if (rsa_tmp == NULL)		{		BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);		(void)BIO_flush(bio_err);		rsa_tmp=RSA_generate_key(keylength,RSA_F4,NULL,NULL);		BIO_printf(bio_err,"\n");		(void)BIO_flush(bio_err);		}	return(rsa_tmp);	}static void free_tmp_rsa(void)	{	if (rsa_tmp != NULL)		{		RSA_free(rsa_tmp);		rsa_tmp = NULL;		}	}#endif#ifndef NO_DH/* These DH parameters have been generated as follows: *    $ openssl dhparam -C -noout 512 *    $ openssl dhparam -C -noout 1024 *    $ openssl dhparam -C -noout -dsaparam 1024 * (The third function has been renamed to avoid name conflicts.) */DH *get_dh512()	{	static unsigned char dh512_p[]={		0xCB,0xC8,0xE1,0x86,0xD0,0x1F,0x94,0x17,0xA6,0x99,0xF0,0xC6,		0x1F,0x0D,0xAC,0xB6,0x25,0x3E,0x06,0x39,0xCA,0x72,0x04,0xB0,		0x6E,0xDA,0xC0,0x61,0xE6,0x7A,0x77,0x25,0xE8,0x3B,0xB9,0x5F,		0x9A,0xB6,0xB5,0xFE,0x99,0x0B,0xA1,0x93,0x4E,0x35,0x33,0xB8,		0xE1,0xF1,0x13,0x4F,0x59,0x1A,0xD2,0x57,0xC0,0x26,0x21,0x33,		0x02,0xC5,0xAE,0x23,		};	static unsigned char dh512_g[]={		0x02,		};	DH *dh;	if ((dh=DH_new()) == NULL) return(NULL);	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);	if ((dh->p == NULL) || (dh->g == NULL))		{ DH_free(dh); return(NULL); }	return(dh);	}DH *get_dh1024()	{	static unsigned char dh1024_p[]={		0xF8,0x81,0x89,0x7D,0x14,0x24,0xC5,0xD1,0xE6,0xF7,0xBF,0x3A,		0xE4,0x90,0xF4,0xFC,0x73,0xFB,0x34,0xB5,0xFA,0x4C,0x56,0xA2,		0xEA,0xA7,0xE9,0xC0,0xC0,0xCE,0x89,0xE1,0xFA,0x63,0x3F,0xB0,		0x6B,0x32,0x66,0xF1,0xD1,0x7B,0xB0,0x00,0x8F,0xCA,0x87,0xC2,		0xAE,0x98,0x89,0x26,0x17,0xC2,0x05,0xD2,0xEC,0x08,0xD0,0x8C,		0xFF,0x17,0x52,0x8C,0xC5,0x07,0x93,0x03,0xB1,0xF6,0x2F,0xB8,		0x1C,0x52,0x47,0x27,0x1B,0xDB,0xD1,0x8D,0x9D,0x69,0x1D,0x52,		0x4B,0x32,0x81,0xAA,0x7F,0x00,0xC8,0xDC,0xE6,0xD9,0xCC,0xC1,		0x11,0x2D,0x37,0x34,0x6C,0xEA,0x02,0x97,0x4B,0x0E,0xBB,0xB1,		0x71,0x33,0x09,0x15,0xFD,0xDD,0x23,0x87,0x07,0x5E,0x89,0xAB,		0x6B,0x7C,0x5F,0xEC,0xA6,0x24,0xDC,0x53,		};	static unsigned char dh1024_g[]={		0x02,		};	DH *dh;	if ((dh=DH_new()) == NULL) return(NULL);	dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);	dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);	if ((dh->p == NULL) || (dh->g == NULL))		{ DH_free(dh); return(NULL); }	return(dh);	}DH *get_dh1024dsa()	{	static unsigned char dh1024_p[]={		0xC8,0x00,0xF7,0x08,0x07,0x89,0x4D,0x90,0x53,0xF3,0xD5,0x00,		0x21,0x1B,0xF7,0x31,0xA6,0xA2,0xDA,0x23,0x9A,0xC7,0x87,0x19,		0x3B,0x47,0xB6,0x8C,0x04,0x6F,0xFF,0xC6,0x9B,0xB8,0x65,0xD2,		0xC2,0x5F,0x31,0x83,0x4A,0xA7,0x5F,0x2F,0x88,0x38,0xB6,0x55,		0xCF,0xD9,0x87,0x6D,0x6F,0x9F,0xDA,0xAC,0xA6,0x48,0xAF,0xFC,		0x33,0x84,0x37,0x5B,0x82,0x4A,0x31,0x5D,0xE7,0xBD,0x52,0x97,		0xA1,0x77,0xBF,0x10,0x9E,0x37,0xEA,0x64,0xFA,0xCA,0x28,0x8D,		0x9D,0x3B,0xD2,0x6E,0x09,0x5C,0x68,0xC7,0x45,0x90,0xFD,0xBB,		0x70,0xC9,0x3A,0xBB,0xDF,0xD4,0x21,0x0F,0xC4,0x6A,0x3C,0xF6,		0x61,0xCF,0x3F,0xD6,0x13,0xF1,0x5F,0xBC,0xCF,0xBC,0x26,0x9E,		0xBC,0x0B,0xBD,0xAB,0x5D,0xC9,0x54,0x39,		};	static unsigned char dh1024_g[]={		0x3B,0x40,0x86,0xE7,0xF3,0x6C,0xDE,0x67,0x1C,0xCC,0x80,0x05,		0x5A,0xDF,0xFE,0xBD,0x20,0x27,0x74,0x6C,0x24,0xC9,0x03,0xF3,		0xE1,0x8D,0xC3,0x7D,0x98,0x27,0x40,0x08,0xB8,0x8C,0x6A,0xE9,		0xBB,0x1A,0x3A,0xD6,0x86,0x83,0x5E,0x72,0x41,0xCE,0x85,0x3C,		0xD2,0xB3,0xFC,0x13,0xCE,0x37,0x81,0x9E,0x4C,0x1C,0x7B,0x65,		0xD3,0xE6,0xA6,0x00,0xF5,0x5A,0x95,0x43,0x5E,0x81,0xCF,0x60,		0xA2,0x23,0xFC,0x36,0xA7,0x5D,0x7A,0x4C,0x06,0x91,0x6E,0xF6,		0x57,0xEE,0x36,0xCB,0x06,0xEA,0xF5,0x3D,0x95,0x49,0xCB,0xA7,		0xDD,0x81,0xDF,0x80,0x09,0x4A,0x97,0x4D,0xA8,0x22,0x72,0xA1,		0x7F,0xC4,0x70,0x56,0x70,0xE8,0x20,0x10,0x18,0x8F,0x2E,0x60,		0x07,0xE7,0x68,0x1A,0x82,0x5D,0x32,0xA2,		};	DH *dh;	if ((dh=DH_new()) == NULL) return(NULL);	dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);	dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);	if ((dh->p == NULL) || (dh->g == NULL))		{ DH_free(dh); return(NULL); }	dh->length = 160;	return(dh);	}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?