s3_clnt.c

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

C
1,741
字号
			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SSL3_SESSION_ID_TOO_SHORT);			goto f_err;			}		}	if (j != 0 && j == s->session->session_id_length	    && memcmp(p,s->session->session_id,j) == 0)	    {	    if(s->sid_ctx_length != s->session->sid_ctx_length	       || memcmp(s->session->sid_ctx,s->sid_ctx,s->sid_ctx_length))		{		al=SSL_AD_ILLEGAL_PARAMETER;		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);		goto f_err;		}	    s->hit=1;	    }	else	/* a miss or crap from the other end */		{		/* If we were trying for session-id reuse, make a new		 * SSL_SESSION so we don't stuff up other people */		s->hit=0;		if (s->session->session_id_length > 0)			{			if (!ssl_get_new_session(s,0))				{				al=SSL_AD_INTERNAL_ERROR;				goto f_err;				}			}		s->session->session_id_length=j;		memcpy(s->session->session_id,p,j); /* j could be 0 */		}	p+=j;	c=ssl_get_cipher_by_char(s,p);	if (c == NULL)		{		/* unknown cipher */		al=SSL_AD_ILLEGAL_PARAMETER;		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED);		goto f_err;		}	p+=ssl_put_cipher_by_char(s,NULL,NULL);	sk=ssl_get_ciphers_by_id(s);	i=sk_SSL_CIPHER_find(sk,c);	if (i < 0)		{		/* we did not say we would use this cipher */		al=SSL_AD_ILLEGAL_PARAMETER;		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);		goto f_err;		}	if (s->hit && (s->session->cipher != c))		{		if (!(s->options &			SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG))			{			al=SSL_AD_ILLEGAL_PARAMETER;			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);			goto f_err;			}		}	s->s3->tmp.new_cipher=c;	/* lets get the compression algorithm */	/* COMPRESSION */	j= *(p++);	if (j == 0)		comp=NULL;	else		comp=ssl3_comp_find(s->ctx->comp_methods,j);		if ((j != 0) && (comp == NULL))		{		al=SSL_AD_ILLEGAL_PARAMETER;		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);		goto f_err;		}	else		{		s->s3->tmp.new_compression=comp;		}	if (p != (d+n))		{		/* wrong packet length */		al=SSL_AD_DECODE_ERROR;		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH);		goto err;		}	return(1);f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,al);err:	return(-1);	}static int ssl3_get_server_certificate(SSL *s)	{	int al,i,ok,ret= -1;	unsigned long n,nc,llen,l;	X509 *x=NULL;	unsigned char *p,*d,*q;	STACK_OF(X509) *sk=NULL;	SESS_CERT *sc;	EVP_PKEY *pkey=NULL;	n=ssl3_get_message(s,		SSL3_ST_CR_CERT_A,		SSL3_ST_CR_CERT_B,		-1,#if defined(MSDOS) && !defined(WIN32)		1024*30, /* 30k max cert list :-) */#else		1024*100, /* 100k max cert list :-) */#endif		&ok);	if (!ok) return((int)n);	if (s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE)		{		s->s3->tmp.reuse_message=1;		return(1);		}	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE)		{		al=SSL_AD_UNEXPECTED_MESSAGE;		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_BAD_MESSAGE_TYPE);		goto f_err;		}	d=p=(unsigned char *)s->init_buf->data;	if ((sk=sk_X509_new_null()) == NULL)		{		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE);		goto err;		}	n2l3(p,llen);	if (llen+3 != n)		{		al=SSL_AD_DECODE_ERROR;		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_LENGTH_MISMATCH);		goto f_err;		}	for (nc=0; nc<llen; )		{		n2l3(p,l);		if ((l+nc+3) > llen)			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);			goto f_err;			}		q=p;		x=d2i_X509(NULL,&q,l);		if (x == NULL)			{			al=SSL_AD_BAD_CERTIFICATE;			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_ASN1_LIB);			goto f_err;			}		if (q != (p+l))			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);			goto f_err;			}		if (!sk_X509_push(sk,x))			{			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE);			goto err;			}		x=NULL;		nc+=l+3;		p=q;		}	i=ssl_verify_cert_chain(s,sk);	if ((s->verify_mode != SSL_VERIFY_NONE) && (!i))		{		al=ssl_verify_alarm_type(s->verify_result);		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);		goto f_err; 		}	ERR_clear_error(); /* but we keep s->verify_result */	sc=ssl_sess_cert_new();	if (sc == NULL) goto err;	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);	s->session->sess_cert=sc;	sc->cert_chain=sk;	/* Inconsistency alert: cert_chain does include the peer's	 * certificate, which we don't include in s3_srvr.c */	x=sk_X509_value(sk,0);	sk=NULL;	pkey=X509_get_pubkey(x);	if ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))		{		x=NULL;		al=SSL3_AL_FATAL;		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);		goto f_err;		}	i=ssl_cert_type(x,pkey);	if (i < 0)		{		x=NULL;		al=SSL3_AL_FATAL;		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_UNKNOWN_CERTIFICATE_TYPE);		goto f_err;		}	sc->peer_cert_type=i;	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);	if (sc->peer_pkeys[i].x509 != NULL) /* Why would this ever happen?										 * We just created sc a couple of										 * lines ago. */		X509_free(sc->peer_pkeys[i].x509);	sc->peer_pkeys[i].x509=x;	sc->peer_key= &(sc->peer_pkeys[i]);	if (s->session->peer != NULL)		X509_free(s->session->peer);	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);	s->session->peer=x;	x=NULL;	ret=1;	if (0)		{f_err:		ssl3_send_alert(s,SSL3_AL_FATAL,al);		}err:	EVP_PKEY_free(pkey);	X509_free(x);	sk_X509_pop_free(sk,X509_free);	return(ret);	}static int ssl3_get_key_exchange(SSL *s)	{#ifndef NO_RSA	unsigned char *q,md_buf[EVP_MAX_MD_SIZE*2];#endif	EVP_MD_CTX md_ctx;	unsigned char *param,*p;	int al,i,j,param_len,ok;	long n,alg;	EVP_PKEY *pkey=NULL;#ifndef NO_RSA	RSA *rsa=NULL;#endif#ifndef NO_DH	DH *dh=NULL;#endif	n=ssl3_get_message(s,		SSL3_ST_CR_KEY_EXCH_A,		SSL3_ST_CR_KEY_EXCH_B,		-1,		1024*8, /* ?? */		&ok);	if (!ok) return((int)n);	if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)		{		s->s3->tmp.reuse_message=1;		return(1);		}	param=p=(unsigned char *)s->init_buf->data;	if (s->session->sess_cert != NULL)		{#ifndef NO_RSA		if (s->session->sess_cert->peer_rsa_tmp != NULL)			{			RSA_free(s->session->sess_cert->peer_rsa_tmp);			s->session->sess_cert->peer_rsa_tmp=NULL;			}#endif#ifndef NO_DH		if (s->session->sess_cert->peer_dh_tmp)			{			DH_free(s->session->sess_cert->peer_dh_tmp);			s->session->sess_cert->peer_dh_tmp=NULL;			}#endif		}	else		{		s->session->sess_cert=ssl_sess_cert_new();		}	param_len=0;	alg=s->s3->tmp.new_cipher->algorithms;#ifndef NO_RSA	if (alg & SSL_kRSA)		{		if ((rsa=RSA_new()) == NULL)			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);			goto err;			}		n2s(p,i);		param_len=i+2;		if (param_len > n)			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH);			goto f_err;			}		if (!(rsa->n=BN_bin2bn(p,i,rsa->n)))			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);			goto err;			}		p+=i;		n2s(p,i);		param_len+=i+2;		if (param_len > n)			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH);			goto f_err;			}		if (!(rsa->e=BN_bin2bn(p,i,rsa->e)))			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);			goto err;			}		p+=i;		n-=param_len;		/* this should be because we are using an export cipher */		if (alg & SSL_aRSA)			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);		else			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR);			goto err;			}		s->session->sess_cert->peer_rsa_tmp=rsa;		rsa=NULL;		}#else /* NO_RSA */	if (0)		;#endif#ifndef NO_DH	else if (alg & SSL_kEDH)		{		if ((dh=DH_new()) == NULL)			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_DH_LIB);			goto err;			}		n2s(p,i);		param_len=i+2;		if (param_len > n)			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH);			goto f_err;			}		if (!(dh->p=BN_bin2bn(p,i,NULL)))			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);			goto err;			}		p+=i;		n2s(p,i);		param_len+=i+2;		if (param_len > n)			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH);			goto f_err;			}		if (!(dh->g=BN_bin2bn(p,i,NULL)))			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);			goto err;			}		p+=i;		n2s(p,i);		param_len+=i+2;		if (param_len > n)			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH);			goto f_err;			}		if (!(dh->pub_key=BN_bin2bn(p,i,NULL)))			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);			goto err;			}		p+=i;		n-=param_len;#ifndef NO_RSA		if (alg & SSL_aRSA)			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);#else		if (0)			;#endif#ifndef NO_DSA		else if (alg & SSL_aDSS)			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);#endif		/* else anonymous DH, so no certificate or pkey. */		s->session->sess_cert->peer_dh_tmp=dh;		dh=NULL;		}	else if ((alg & SSL_kDHr) || (alg & SSL_kDHd))		{		al=SSL_AD_ILLEGAL_PARAMETER;		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER);		goto f_err;		}#endif /* !NO_DH */	if (alg & SSL_aFZA)		{		al=SSL_AD_HANDSHAKE_FAILURE;		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER);		goto f_err;		}	/* p points to the next byte, there are 'n' bytes left */	/* if it was signed, check the signature */	if (pkey != NULL)		{		n2s(p,i);		n-=2;		j=EVP_PKEY_size(pkey);		if ((i != n) || (n > j) || (n <= 0))			{			/* wrong packet length */			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH);			goto f_err;			}#ifndef NO_RSA		if (pkey->type == EVP_PKEY_RSA)			{			int num;			j=0;			q=md_buf;			for (num=2; num > 0; num--)				{				EVP_DigestInit(&md_ctx,(num == 2)					?s->ctx->md5:s->ctx->sha1);				EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);				EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);				EVP_DigestUpdate(&md_ctx,param,param_len);				EVP_DigestFinal(&md_ctx,q,(unsigned int *)&i);				q+=i;				j+=i;				}			i=RSA_verify(NID_md5_sha1, md_buf, j, p, n,								pkey->pkey.rsa);			if (i < 0)				{				al=SSL_AD_DECRYPT_ERROR;				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT);				goto f_err;				}			if (i == 0)				{				/* bad signature */				al=SSL_AD_DECRYPT_ERROR;				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);				goto f_err;				}			}		else#endif#ifndef NO_DSA			if (pkey->type == EVP_PKEY_DSA)			{			/* lets do DSS */			EVP_VerifyInit(&md_ctx,EVP_dss1());			EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);			EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);			EVP_VerifyUpdate(&md_ctx,param,param_len);			if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey))				{				/* bad signature */				al=SSL_AD_DECRYPT_ERROR;				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);				goto f_err;				}			}		else#endif			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR);			goto err;			}		}	else		{		/* still data left over */		if (!(alg & SSL_aNULL))			{			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR);			goto err;			}		if (n != 0)			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE);			goto f_err;			}		}	EVP_PKEY_free(pkey);	return(1);f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,al);err:	EVP_PKEY_free(pkey);#ifndef NO_RSA	if (rsa != NULL)		RSA_free(rsa);#endif#ifndef NO_DH	if (dh != NULL)		DH_free(dh);#endif	return(-1);	}static int ssl3_get_certificate_request(SSL *s)	{	int ok,ret=0;	unsigned long n,nc,l;	unsigned int llen,ctype_num,i;	X509_NAME *xn=NULL;	unsigned char *p,*d,*q;	STACK_OF(X509_NAME) *ca_sk=NULL;	n=ssl3_get_message(s,		SSL3_ST_CR_CERT_REQ_A,		SSL3_ST_CR_CERT_REQ_B,		-1,#if defined(MSDOS) && !defined(WIN32)		1024*30,  /* 30k max cert list :-) */#else		1024*100, /* 100k max cert list :-) */#endif		&ok);	if (!ok) return((int)n);

⌨️ 快捷键说明

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