s3_clnt.c

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

C
1,741
字号
	s->s3->tmp.cert_req=0;	if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)		{		s->s3->tmp.reuse_message=1;		return(1);		}	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST)		{		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);		SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_WRONG_MESSAGE_TYPE);		goto err;		}	/* TLS does not like anon-DH with client cert */	if (s->version > SSL3_VERSION)		{		l=s->s3->tmp.new_cipher->algorithms;		if (l & SSL_aNULL)			{			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER);			goto err;			}		}	d=p=(unsigned char *)s->init_buf->data;	if ((ca_sk=sk_X509_NAME_new(ca_dn_cmp)) == NULL)		{		SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE);		goto err;		}	/* get the certificate types */	ctype_num= *(p++);	if (ctype_num > SSL3_CT_NUMBER)		ctype_num=SSL3_CT_NUMBER;	for (i=0; i<ctype_num; i++)		s->s3->tmp.ctype[i]= p[i];	p+=ctype_num;	/* get the CA RDNs */	n2s(p,llen);#if 0{FILE *out;out=fopen("/tmp/vsign.der","w");fwrite(p,1,llen,out);fclose(out);}#endif	if ((llen+ctype_num+2+1) != n)		{		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);		SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);		goto err;		}	for (nc=0; nc<llen; )		{		n2s(p,l);		if ((l+nc+2) > llen)			{			if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG))				goto cont; /* netscape bugs */			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_TOO_LONG);			goto err;			}		q=p;		if ((xn=d2i_X509_NAME(NULL,&q,l)) == NULL)			{			/* If netscape tolerance is on, ignore errors */			if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG)				goto cont;			else				{				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);				SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_ASN1_LIB);				goto err;				}			}		if (q != (p+l))			{			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_LENGTH_MISMATCH);			goto err;			}		if (!sk_X509_NAME_push(ca_sk,xn))			{			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE);			goto err;			}		p+=l;		nc+=l+2;		}	if (0)		{cont:		ERR_clear_error();		}	/* we should setup a certificate to return.... */	s->s3->tmp.cert_req=1;	s->s3->tmp.ctype_num=ctype_num;	if (s->s3->tmp.ca_names != NULL)		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);	s->s3->tmp.ca_names=ca_sk;	ca_sk=NULL;	ret=1;err:	if (ca_sk != NULL) sk_X509_NAME_pop_free(ca_sk,X509_NAME_free);	return(ret);	}static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b)	{	return(X509_NAME_cmp(*a,*b));	}static int ssl3_get_server_done(SSL *s)	{	int ok,ret=0;	long n;	n=ssl3_get_message(s,		SSL3_ST_CR_SRVR_DONE_A,		SSL3_ST_CR_SRVR_DONE_B,		SSL3_MT_SERVER_DONE,		30, /* should be very small, like 0 :-) */		&ok);	if (!ok) return((int)n);	if (n > 0)		{		/* should contain no data */		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);		SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_LENGTH_MISMATCH);		}	ret=1;	return(ret);	}static int ssl3_send_client_key_exchange(SSL *s)	{	unsigned char *p,*d;	int n;	unsigned long l;#ifndef NO_RSA	unsigned char *q;	EVP_PKEY *pkey=NULL;#endif	if (s->state == SSL3_ST_CW_KEY_EXCH_A)		{		d=(unsigned char *)s->init_buf->data;		p= &(d[4]);		l=s->s3->tmp.new_cipher->algorithms;#ifndef NO_RSA		if (l & SSL_kRSA)			{			RSA *rsa;			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];			if (s->session->sess_cert->peer_rsa_tmp != NULL)				rsa=s->session->sess_cert->peer_rsa_tmp;			else				{				pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);				if ((pkey == NULL) ||					(pkey->type != EVP_PKEY_RSA) ||					(pkey->pkey.rsa == NULL))					{					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR);					goto err;					}				rsa=pkey->pkey.rsa;				EVP_PKEY_free(pkey);				}							tmp_buf[0]=s->client_version>>8;			tmp_buf[1]=s->client_version&0xff;			if (RAND_bytes(&(tmp_buf[2]),SSL_MAX_MASTER_KEY_LENGTH-2) <= 0)					goto err;			s->session->master_key_length=SSL_MAX_MASTER_KEY_LENGTH;			q=p;			/* Fix buf for TLS and beyond */			if (s->version > SSL3_VERSION)				p+=2;			n=RSA_public_encrypt(SSL_MAX_MASTER_KEY_LENGTH,				tmp_buf,p,rsa,RSA_PKCS1_PADDING);#ifdef PKCS1_CHECK			if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++;			if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;#endif			if (n <= 0)				{				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT);				goto err;				}			/* Fix buf for TLS and beyond */			if (s->version > SSL3_VERSION)				{				s2n(n,q);				n+=2;				}			s->session->master_key_length=				s->method->ssl3_enc->generate_master_secret(s,					s->session->master_key,					tmp_buf,SSL_MAX_MASTER_KEY_LENGTH);			memset(tmp_buf,0,SSL_MAX_MASTER_KEY_LENGTH);			}		else#endif#ifndef NO_DH		if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))			{			DH *dh_srvr,*dh_clnt;			if (s->session->sess_cert->peer_dh_tmp != NULL)				dh_srvr=s->session->sess_cert->peer_dh_tmp;			else				{				/* we get them from the cert */				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);				goto err;				}						/* generate a new random key */			if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)				{				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);				goto err;				}			if (!DH_generate_key(dh_clnt))				{				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);				goto err;				}			/* use the 'p' output buffer for the DH key, but			 * make sure to clear it out afterwards */			n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);			if (n <= 0)				{				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);				goto err;				}			/* generate master key from the result */			s->session->master_key_length=				s->method->ssl3_enc->generate_master_secret(s,					s->session->master_key,p,n);			/* clean up */			memset(p,0,n);			/* send off the data */			n=BN_num_bytes(dh_clnt->pub_key);			s2n(n,p);			BN_bn2bin(dh_clnt->pub_key,p);			n+=2;			DH_free(dh_clnt);			/* perhaps clean things up a bit EAY EAY EAY EAY*/			}		else#endif			{			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);			SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR);			goto err;			}				*(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;		l2n3(n,d);		s->state=SSL3_ST_CW_KEY_EXCH_B;		/* number of bytes to write */		s->init_num=n+4;		s->init_off=0;		}	/* SSL3_ST_CW_KEY_EXCH_B */	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));err:	return(-1);	}static int ssl3_send_client_verify(SSL *s)	{	unsigned char *p,*d;	unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];	EVP_PKEY *pkey;#ifndef NO_RSA	unsigned u=0;#endif	unsigned long n;#ifndef NO_DSA	int j;#endif	if (s->state == SSL3_ST_CW_CERT_VRFY_A)		{		d=(unsigned char *)s->init_buf->data;		p= &(d[4]);		pkey=s->cert->key->privatekey;		s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2),			&(data[MD5_DIGEST_LENGTH]));#ifndef NO_RSA		if (pkey->type == EVP_PKEY_RSA)			{			s->method->ssl3_enc->cert_verify_mac(s,				&(s->s3->finish_dgst1),&(data[0]));			if (RSA_sign(NID_md5_sha1, data,					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,					&(p[2]), &u, pkey->pkey.rsa) <= 0 )				{				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);				goto err;				}			s2n(u,p);			n=u+2;			}		else#endif#ifndef NO_DSA			if (pkey->type == EVP_PKEY_DSA)			{			if (!DSA_sign(pkey->save_type,				&(data[MD5_DIGEST_LENGTH]),				SHA_DIGEST_LENGTH,&(p[2]),				(unsigned int *)&j,pkey->pkey.dsa))				{				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);				goto err;				}			s2n(j,p);			n=j+2;			}		else#endif			{			SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,SSL_R_INTERNAL_ERROR);			goto err;			}		*(d++)=SSL3_MT_CERTIFICATE_VERIFY;		l2n3(n,d);		s->init_num=(int)n+4;		s->init_off=0;		}	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));err:	return(-1);	}static int ssl3_send_client_certificate(SSL *s)	{	X509 *x509=NULL;	EVP_PKEY *pkey=NULL;	int i;	unsigned long l;	if (s->state ==	SSL3_ST_CW_CERT_A)		{		if ((s->cert == NULL) ||			(s->cert->key->x509 == NULL) ||			(s->cert->key->privatekey == NULL))			s->state=SSL3_ST_CW_CERT_B;		else			s->state=SSL3_ST_CW_CERT_C;		}	/* We need to get a client cert */	if (s->state == SSL3_ST_CW_CERT_B)		{		/* If we get an error, we need to		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);		 * We then get retied later */		i=0;		if (s->ctx->client_cert_cb != NULL)			i=s->ctx->client_cert_cb(s,&(x509),&(pkey));		if (i < 0)			{			s->rwstate=SSL_X509_LOOKUP;			return(-1);			}		s->rwstate=SSL_NOTHING;		if ((i == 1) && (pkey != NULL) && (x509 != NULL))			{			s->state=SSL3_ST_CW_CERT_B;			if (	!SSL_use_certificate(s,x509) ||				!SSL_use_PrivateKey(s,pkey))				i=0;			}		else if (i == 1)			{			i=0;			SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);			}		if (x509 != NULL) X509_free(x509);		if (pkey != NULL) EVP_PKEY_free(pkey);		if (i == 0)			{			if (s->version == SSL3_VERSION)				{				s->s3->tmp.cert_req=0;				ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);				return(1);				}			else				{				s->s3->tmp.cert_req=2;				}			}		/* Ok, we have a cert */		s->state=SSL3_ST_CW_CERT_C;		}	if (s->state == SSL3_ST_CW_CERT_C)		{		s->state=SSL3_ST_CW_CERT_D;		l=ssl3_output_cert_chain(s,			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);		s->init_num=(int)l;		s->init_off=0;		}	/* SSL3_ST_CW_CERT_D */	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));	}#define has_bits(i,m)	(((i)&(m)) == (m))static int ssl3_check_cert_and_algorithm(SSL *s)	{	int i,idx;	long algs;	EVP_PKEY *pkey=NULL;	SESS_CERT *sc;#ifndef NO_RSA	RSA *rsa;#endif#ifndef NO_DH	DH *dh;#endif	sc=s->session->sess_cert;	if (sc == NULL)		{		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_INTERNAL_ERROR);		goto err;		}	algs=s->s3->tmp.new_cipher->algorithms;	/* we don't have a certificate */	if (algs & (SSL_aDH|SSL_aNULL))		return(1);#ifndef NO_RSA	rsa=s->session->sess_cert->peer_rsa_tmp;#endif#ifndef NO_DH	dh=s->session->sess_cert->peer_dh_tmp;#endif	/* This is the passed certificate */	idx=sc->peer_cert_type;	pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509);	i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey);	EVP_PKEY_free(pkey);		/* Check that we have a certificate if we require one */	if ((algs & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN))		{		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_SIGNING_CERT);		goto f_err;		}#ifndef NO_DSA	else if ((algs & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN))		{		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DSA_SIGNING_CERT);		goto f_err;		}#endif#ifndef NO_RSA	if ((algs & SSL_kRSA) &&		!(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL)))		{		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT);		goto f_err;		}#endif#ifndef NO_DH	if ((algs & SSL_kEDH) &&		!(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL)))		{		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY);		goto f_err;		}	else if ((algs & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))		{		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT);		goto f_err;		}#ifndef NO_DSA	else if ((algs & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))		{		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT);		goto f_err;		}#endif#endif	if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))		{#ifndef NO_RSA		if (algs & SSL_kRSA)			{			if (rsa == NULL			    || RSA_size(rsa) > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))				{				SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_RSA_KEY);				goto f_err;				}			}		else#endif#ifndef NO_DH			if (algs & (SSL_kEDH|SSL_kDHr|SSL_kDHd))			    {			    if (dh == NULL				|| DH_size(dh) > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))				{				SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_DH_KEY);				goto f_err;				}			}		else#endif			{			SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);			goto f_err;			}		}	return(1);f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);err:	return(0);	}

⌨️ 快捷键说明

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