s3_enc.c

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

C
584
字号
	s->s3->tmp.new_sym_enc=c;	s->s3->tmp.new_hash=hash;	s->s3->tmp.new_compression=comp;	num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);	num*=2;	ssl3_cleanup_key_block(s);	if ((p=OPENSSL_malloc(num)) == NULL)		goto err;	s->s3->tmp.key_block_length=num;	s->s3->tmp.key_block=p;	ssl3_generate_key_block(s,p,num);	return(1);err:	SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);	return(0);	}void ssl3_cleanup_key_block(SSL *s)	{	if (s->s3->tmp.key_block != NULL)		{		memset(s->s3->tmp.key_block,0,			s->s3->tmp.key_block_length);		OPENSSL_free(s->s3->tmp.key_block);		s->s3->tmp.key_block=NULL;		}	s->s3->tmp.key_block_length=0;	}int ssl3_enc(SSL *s, int send)	{	SSL3_RECORD *rec;	EVP_CIPHER_CTX *ds;	unsigned long l;	int bs,i;	const EVP_CIPHER *enc;	if (send)		{		ds=s->enc_write_ctx;		rec= &(s->s3->wrec);		if (s->enc_write_ctx == NULL)			enc=NULL;		else			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);		}	else		{		ds=s->enc_read_ctx;		rec= &(s->s3->rrec);		if (s->enc_read_ctx == NULL)			enc=NULL;		else			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);		}	if ((s->session == NULL) || (ds == NULL) ||		(enc == NULL))		{		memcpy(rec->data,rec->input,rec->length);		rec->input=rec->data;		}	else		{		l=rec->length;		bs=EVP_CIPHER_block_size(ds->cipher);		/* COMPRESS */		/* This should be using (bs-1) and bs instead of 7 and 8 */		if ((bs != 1) && send)			{			i=bs-((int)l%bs);			/* we need to add 'i-1' padding bytes */			l+=i;			rec->length+=i;			rec->input[l-1]=(i-1);			}		EVP_Cipher(ds,rec->data,rec->input,l);		if ((bs != 1) && !send)			{			i=rec->data[l-1]+1;			if (i > bs)				{				SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPT_ERROR);				return(0);				}			rec->length-=i;			}		}	return(1);	}void ssl3_init_finished_mac(SSL *s)	{	EVP_DigestInit(&(s->s3->finish_dgst1),s->ctx->md5);	EVP_DigestInit(&(s->s3->finish_dgst2),s->ctx->sha1);	}void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)	{	EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len);	EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len);	}int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p)	{	return(ssl3_handshake_mac(s,ctx,NULL,0,p));	}int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2,	     const char *sender, int len, unsigned char *p)	{	int ret;	ret=ssl3_handshake_mac(s,ctx1,sender,len,p);	p+=ret;	ret+=ssl3_handshake_mac(s,ctx2,sender,len,p);	return(ret);	}static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,	     const char *sender, int len, unsigned char *p)	{	unsigned int ret;	int npad,n;	unsigned int i;	unsigned char md_buf[EVP_MAX_MD_SIZE];	EVP_MD_CTX ctx;	EVP_MD_CTX_copy(&ctx,in_ctx);	n=EVP_MD_CTX_size(&ctx);	npad=(48/n)*n;	if (sender != NULL)		EVP_DigestUpdate(&ctx,sender,len);	EVP_DigestUpdate(&ctx,s->session->master_key,		s->session->master_key_length);	EVP_DigestUpdate(&ctx,ssl3_pad_1,npad);	EVP_DigestFinal(&ctx,md_buf,&i);	EVP_DigestInit(&ctx,EVP_MD_CTX_md(&ctx));	EVP_DigestUpdate(&ctx,s->session->master_key,		s->session->master_key_length);	EVP_DigestUpdate(&ctx,ssl3_pad_2,npad);	EVP_DigestUpdate(&ctx,md_buf,i);	EVP_DigestFinal(&ctx,p,&ret);	memset(&ctx,0,sizeof(EVP_MD_CTX));	return((int)ret);	}int ssl3_mac(SSL *ssl, unsigned char *md, int send)	{	SSL3_RECORD *rec;	unsigned char *mac_sec,*seq;	EVP_MD_CTX md_ctx;	const EVP_MD *hash;	unsigned char *p,rec_char;	unsigned int md_size;	int npad,i;	if (send)		{		rec= &(ssl->s3->wrec);		mac_sec= &(ssl->s3->write_mac_secret[0]);		seq= &(ssl->s3->write_sequence[0]);		hash=ssl->write_hash;		}	else		{		rec= &(ssl->s3->rrec);		mac_sec= &(ssl->s3->read_mac_secret[0]);		seq= &(ssl->s3->read_sequence[0]);		hash=ssl->read_hash;		}	md_size=EVP_MD_size(hash);	npad=(48/md_size)*md_size;	/* Chop the digest off the end :-) */	EVP_DigestInit(  &md_ctx,hash);	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);	EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);	EVP_DigestUpdate(&md_ctx,seq,8);	rec_char=rec->type;	EVP_DigestUpdate(&md_ctx,&rec_char,1);	p=md;	s2n(rec->length,p);	EVP_DigestUpdate(&md_ctx,md,2);	EVP_DigestUpdate(&md_ctx,rec->input,rec->length);	EVP_DigestFinal( &md_ctx,md,NULL);	EVP_DigestInit(  &md_ctx,hash);	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);	EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);	EVP_DigestUpdate(&md_ctx,md,md_size);	EVP_DigestFinal( &md_ctx,md,&md_size);	for (i=7; i>=0; i--)		if (++seq[i]) break; 	return(md_size);	}int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,	     int len)	{	static const unsigned char *salt[3]={#ifndef CHARSET_EBCDIC		(const unsigned char *)"A",		(const unsigned char *)"BB",		(const unsigned char *)"CCC",#else		(const unsigned char *)"\x41",		(const unsigned char *)"\x42\x42",		(const unsigned char *)"\x43\x43\x43",#endif		};	unsigned char buf[EVP_MAX_MD_SIZE];	EVP_MD_CTX ctx;	int i,ret=0;	unsigned int n;	for (i=0; i<3; i++)		{		EVP_DigestInit(&ctx,s->ctx->sha1);		EVP_DigestUpdate(&ctx,salt[i],strlen((const char *)salt[i]));		EVP_DigestUpdate(&ctx,p,len);		EVP_DigestUpdate(&ctx,&(s->s3->client_random[0]),			SSL3_RANDOM_SIZE);		EVP_DigestUpdate(&ctx,&(s->s3->server_random[0]),			SSL3_RANDOM_SIZE);		EVP_DigestFinal(&ctx,buf,&n);		EVP_DigestInit(&ctx,s->ctx->md5);		EVP_DigestUpdate(&ctx,p,len);		EVP_DigestUpdate(&ctx,buf,n);		EVP_DigestFinal(&ctx,out,&n);		out+=n;		ret+=n;		}	return(ret);	}int ssl3_alert_code(int code)	{	switch (code)		{	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);	case SSL_AD_DECRYPTION_FAILED:	return(SSL3_AD_BAD_RECORD_MAC);	case SSL_AD_RECORD_OVERFLOW:	return(SSL3_AD_BAD_RECORD_MAC);	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);	case SSL_AD_NO_CERTIFICATE:	return(SSL3_AD_NO_CERTIFICATE);	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);	case SSL_AD_UNKNOWN_CA:		return(SSL3_AD_BAD_CERTIFICATE);	case SSL_AD_ACCESS_DENIED:	return(SSL3_AD_HANDSHAKE_FAILURE);	case SSL_AD_DECODE_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);	case SSL_AD_DECRYPT_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);	case SSL_AD_EXPORT_RESTRICTION:	return(SSL3_AD_HANDSHAKE_FAILURE);	case SSL_AD_PROTOCOL_VERSION:	return(SSL3_AD_HANDSHAKE_FAILURE);	case SSL_AD_INSUFFICIENT_SECURITY:return(SSL3_AD_HANDSHAKE_FAILURE);	case SSL_AD_INTERNAL_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);	case SSL_AD_USER_CANCELLED:	return(SSL3_AD_HANDSHAKE_FAILURE);	case SSL_AD_NO_RENEGOTIATION:	return(-1); /* Don't send it :-) */	default:			return(-1);		}	}

⌨️ 快捷键说明

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