⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl_lib.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
	CERT_PKEY *cpk;	int rsa_enc,rsa_tmp,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign;	int rsa_enc_export,dh_rsa_export,dh_dsa_export;	int rsa_tmp_export,dh_tmp_export,kl;	unsigned long mask,emask;	int have_ecc_cert, ecdh_ok, ecdsa_ok, ecc_pkey_size;#ifndef OPENSSL_NO_ECDH	int have_ecdh_tmp;#endif	X509 *x = NULL;	EVP_PKEY *ecc_pkey = NULL;	int signature_nid = 0;	if (c == NULL) return;	kl=SSL_C_EXPORT_PKEYLENGTH(cipher);#ifndef OPENSSL_NO_RSA	rsa_tmp=(c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);	rsa_tmp_export=(c->rsa_tmp_cb != NULL ||		(rsa_tmp && RSA_size(c->rsa_tmp)*8 <= kl));#else	rsa_tmp=rsa_tmp_export=0;#endif#ifndef OPENSSL_NO_DH	dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);	dh_tmp_export=(c->dh_tmp_cb != NULL ||		(dh_tmp && DH_size(c->dh_tmp)*8 <= kl));#else	dh_tmp=dh_tmp_export=0;#endif#ifndef OPENSSL_NO_ECDH	have_ecdh_tmp=(c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL);#endif	cpk= &(c->pkeys[SSL_PKEY_RSA_ENC]);	rsa_enc= (cpk->x509 != NULL && cpk->privatekey != NULL);	rsa_enc_export=(rsa_enc && EVP_PKEY_size(cpk->privatekey)*8 <= kl);	cpk= &(c->pkeys[SSL_PKEY_RSA_SIGN]);	rsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);	cpk= &(c->pkeys[SSL_PKEY_DSA_SIGN]);	dsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);	cpk= &(c->pkeys[SSL_PKEY_DH_RSA]);	dh_rsa=  (cpk->x509 != NULL && cpk->privatekey != NULL);	dh_rsa_export=(dh_rsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);	cpk= &(c->pkeys[SSL_PKEY_DH_DSA]);/* FIX THIS EAY EAY EAY */	dh_dsa=  (cpk->x509 != NULL && cpk->privatekey != NULL);	dh_dsa_export=(dh_dsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);	cpk= &(c->pkeys[SSL_PKEY_ECC]);	have_ecc_cert= (cpk->x509 != NULL && cpk->privatekey != NULL);	mask=0;	emask=0;#ifdef CIPHER_DEBUG	printf("rt=%d rte=%d dht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",		rsa_tmp,rsa_tmp_export,dh_tmp,		rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa);#endif	if (rsa_enc || (rsa_tmp && rsa_sign))		mask|=SSL_kRSA;	if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc)))		emask|=SSL_kRSA;#if 0	/* The match needs to be both kEDH and aRSA or aDSA, so don't worry */	if (	(dh_tmp || dh_rsa || dh_dsa) && 		(rsa_enc || rsa_sign || dsa_sign))		mask|=SSL_kEDH;	if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) &&		(rsa_enc || rsa_sign || dsa_sign))		emask|=SSL_kEDH;#endif	if (dh_tmp_export) 		emask|=SSL_kEDH;	if (dh_tmp)		mask|=SSL_kEDH;	if (dh_rsa) mask|=SSL_kDHr;	if (dh_rsa_export) emask|=SSL_kDHr;	if (dh_dsa) mask|=SSL_kDHd;	if (dh_dsa_export) emask|=SSL_kDHd;	if (rsa_enc || rsa_sign)		{		mask|=SSL_aRSA;		emask|=SSL_aRSA;		}	if (dsa_sign)		{		mask|=SSL_aDSS;		emask|=SSL_aDSS;		}	mask|=SSL_aNULL;	emask|=SSL_aNULL;#ifndef OPENSSL_NO_KRB5	mask|=SSL_kKRB5|SSL_aKRB5;	emask|=SSL_kKRB5|SSL_aKRB5;#endif	/* An ECC certificate may be usable for ECDH and/or	 * ECDSA cipher suites depending on the key usage extension.	 */	if (have_ecc_cert)		{                /* This call populates extension flags (ex_flags) */		x = (c->pkeys[SSL_PKEY_ECC]).x509;		X509_check_purpose(x, -1, 0);		ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ?		    (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1;		ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?		    (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;		ecc_pkey = X509_get_pubkey(x);		ecc_pkey_size = (ecc_pkey != NULL) ? 		    EVP_PKEY_bits(ecc_pkey) : 0;		EVP_PKEY_free(ecc_pkey);		if ((x->sig_alg) && (x->sig_alg->algorithm))			signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);#ifndef OPENSSL_NO_ECDH		if (ecdh_ok)			{			if ((signature_nid == NID_md5WithRSAEncryption) ||			    (signature_nid == NID_md4WithRSAEncryption) ||			    (signature_nid == NID_md2WithRSAEncryption))				{				mask|=SSL_kECDH|SSL_aRSA;				if (ecc_pkey_size <= 163)					emask|=SSL_kECDH|SSL_aRSA;				}			if (signature_nid == NID_ecdsa_with_SHA1)				{				mask|=SSL_kECDH|SSL_aECDSA;				if (ecc_pkey_size <= 163)					emask|=SSL_kECDH|SSL_aECDSA;				}			}#endif#ifndef OPENSSL_NO_ECDSA		if (ecdsa_ok)			{			mask|=SSL_aECDSA;			emask|=SSL_aECDSA;			}#endif		}#ifndef OPENSSL_NO_ECDH	if (have_ecdh_tmp)		{		mask|=SSL_kECDHE;		emask|=SSL_kECDHE;		}#endif	c->mask=mask;	c->export_mask=emask;	c->valid=1;	}/* This handy macro borrowed from crypto/x509v3/v3_purp.c */#define ku_reject(x, usage) \	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs)	{	unsigned long alg = cs->algorithms;	EVP_PKEY *pkey = NULL;	int keysize = 0;	int signature_nid = 0;	if (SSL_C_IS_EXPORT(cs))		{		/* ECDH key length in export ciphers must be <= 163 bits */		pkey = X509_get_pubkey(x);		if (pkey == NULL) return 0;		keysize = EVP_PKEY_bits(pkey);		EVP_PKEY_free(pkey);		if (keysize > 163) return 0;		}	/* This call populates the ex_flags field correctly */	X509_check_purpose(x, -1, 0);	if ((x->sig_alg) && (x->sig_alg->algorithm))		signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);	if (alg & SSL_kECDH) 		{		/* key usage, if present, must allow key agreement */		if (ku_reject(x, X509v3_KU_KEY_AGREEMENT))			{			return 0;			}		if (alg & SSL_aECDSA) 			{			/* signature alg must be ECDSA */			if (signature_nid != NID_ecdsa_with_SHA1)				{				return 0;				}			}		if (alg & SSL_aRSA)			{			/* signature alg must be RSA */			if ((signature_nid != NID_md5WithRSAEncryption) &&			    (signature_nid != NID_md4WithRSAEncryption) &&			    (signature_nid != NID_md2WithRSAEncryption))				{				return 0;				}			}		} 	else if (alg & SSL_aECDSA)		{		/* key usage, if present, must allow signing */		if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE))			{			return 0;			}		}	return 1;  /* all checks are ok */	}/* THIS NEEDS CLEANING UP */X509 *ssl_get_server_send_cert(SSL *s)	{	unsigned long alg,mask,kalg;	CERT *c;	int i,is_export;	c=s->cert;	ssl_set_cert_masks(c, s->s3->tmp.new_cipher);	alg=s->s3->tmp.new_cipher->algorithms;	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);	mask=is_export?c->export_mask:c->mask;	kalg=alg&(SSL_MKEY_MASK|SSL_AUTH_MASK);	if (kalg & SSL_kECDH)		{		/* we don't need to look at SSL_kECDHE 		 * since no certificate is needed for		 * anon ECDH and for authenticated		 * ECDHE, the check for the auth 		 * algorithm will set i correctly		 * NOTE: For ECDH-RSA, we need an ECC		 * not an RSA cert but for ECDHE-RSA		 * we need an RSA cert. Placing the		 * checks for SSL_kECDH before RSA		 * checks ensures the correct cert is chosen.		 */		i=SSL_PKEY_ECC;		}	else if (kalg & SSL_aECDSA)		{		i=SSL_PKEY_ECC;		}	else if (kalg & SSL_kDHr)		i=SSL_PKEY_DH_RSA;	else if (kalg & SSL_kDHd)		i=SSL_PKEY_DH_DSA;	else if (kalg & SSL_aDSS)		i=SSL_PKEY_DSA_SIGN;	else if (kalg & SSL_aRSA)		{		if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL)			i=SSL_PKEY_RSA_SIGN;		else			i=SSL_PKEY_RSA_ENC;		}	else if (kalg & SSL_aKRB5)		{		/* VRS something else here? */		return(NULL);		}	else /* if (kalg & SSL_aNULL) */		{		SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR);		return(NULL);		}	if (c->pkeys[i].x509 == NULL) return(NULL);	return(c->pkeys[i].x509);	}EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher)	{	unsigned long alg;	CERT *c;	alg=cipher->algorithms;	c=s->cert;	if ((alg & SSL_aDSS) &&		(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))		return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey);	else if (alg & SSL_aRSA)		{		if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)			return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey);		else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL)			return(c->pkeys[SSL_PKEY_RSA_ENC].privatekey);		else			return(NULL);		}	else if ((alg & SSL_aECDSA) &&	         (c->pkeys[SSL_PKEY_ECC].privatekey != NULL))		return(c->pkeys[SSL_PKEY_ECC].privatekey);	else /* if (alg & SSL_aNULL) */		{		SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);		return(NULL);		}	}void ssl_update_cache(SSL *s,int mode)	{	int i;	/* If the session_id_length is 0, we are not supposed to cache it,	 * and it would be rather hard to do anyway :-) */	if (s->session->session_id_length == 0) return;	i=s->ctx->session_cache_mode;	if ((i & mode) && (!s->hit)		&& ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)		    || SSL_CTX_add_session(s->ctx,s->session))		&& (s->ctx->new_session_cb != NULL))		{		CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION);		if (!s->ctx->new_session_cb(s,s->session))			SSL_SESSION_free(s->session);		}	/* auto flush every 255 connections */	if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) &&		((i & mode) == mode))		{		if (  (((mode & SSL_SESS_CACHE_CLIENT)			?s->ctx->stats.sess_connect_good			:s->ctx->stats.sess_accept_good) & 0xff) == 0xff)			{			SSL_CTX_flush_sessions(s->ctx,(unsigned long)time(NULL));			}		}	}SSL_METHOD *SSL_get_ssl_method(SSL *s)	{	return(s->method);	}int SSL_set_ssl_method(SSL *s,SSL_METHOD *meth)	{	int conn= -1;	int ret=1;	if (s->method != meth)		{		if (s->handshake_func != NULL)			conn=(s->handshake_func == s->method->ssl_connect);		if (s->method->version == meth->version)			s->method=meth;		else			{			s->method->ssl_free(s);			s->method=meth;			ret=s->method->ssl_new(s);			}		if (conn == 1)			s->handshake_func=meth->ssl_connect;		else if (conn == 0)			s->handshake_func=meth->ssl_accept;		}	return(ret);	}int SSL_get_error(const SSL *s,int i)	{	int reason;	unsigned long l;	BIO *bio;	if (i > 0) return(SSL_ERROR_NONE);	/* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake	 * etc, where we do encode the error */	if ((l=ERR_peek_error()) != 0)		{		if (ERR_GET_LIB(l) == ERR_LIB_SYS)			return(SSL_ERROR_SYSCALL);		else			return(SSL_ERROR_SSL);		}	if ((i < 0) && SSL_want_read(s))		{		bio=SSL_get_rbio(s);		if (BIO_should_read(bio))			return(SSL_ERROR_WANT_READ);		else if (BIO_should_write(bio))			/* This one doesn't make too much sense ... We never try			 * to write to the rbio, and an application program where			 * rbio and wbio are separate couldn't even know what it			 * should wait for.			 * However if we ever set s->rwstate incorrectly			 * (so that we have SSL_want_read(s) instead of			 * SSL_want_write(s)) and rbio and wbio *are* the same,			 * this test works around that bug; so it might be safer			 * to keep it. */			return(SSL_ERROR_WANT_WRITE);		else if (BIO_should_io_special(bio))			{			reason=BIO_get_retry_reason(bio);			if (reason == BIO_RR_CONNECT)				return(SSL_ERROR_WANT_CONNECT);			else if (reason == BIO_RR_ACCEPT)				return(SSL_ERROR_WANT_ACCEPT);			else				return(SSL_ERROR_SYSCALL); /* unknown */			}		}	if ((i < 0) && SSL_want_write(s))		{		bio=SSL_get_wbio(s);		if (BIO_should_write(bio))			return(SSL_ERROR_WANT_WRITE);		else if (BIO_should_read(bio))			/* See above (SSL_want_read(s) with BIO_should_write(bio)) */			return(SSL_ERROR_WANT_READ);		else if (BIO_should_io_special(bio))			{			reason=BIO_get_retry_reason(bio);			if (reason == BIO_RR_CONNECT)				return(SSL_ERROR_WANT_CONNECT);			else if (reason == BIO_RR_ACCEPT)				return(SSL_ERROR_WANT_ACCEPT);			else				return(SSL_ERROR_SYSCALL);			}		}	if ((i < 0) && SSL_want_x509_lookup(s))		{		return(SSL_ERROR_WANT_X509_LOOKUP);		}	if (i == 0)		{		if (s->version == SSL2_VERSION)			{			/* assume it is the socket being closed */			return(SSL_ERROR_ZERO_RETURN);			}		else			{			if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&				(s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY))				return(SSL_ERROR_ZERO_RETURN);			}		}	return(SSL_ERROR_SYSCALL);	}int SSL_do_handshake(SSL *s)	{	int ret=1;	if (s->handshake_func == NULL)		{		SSLerr(SSL_F_SSL_DO_HANDSHAKE,SSL_R_CONNECTION_TYPE_NOT_SET);		return(-1);		}	s->method->ssl_renegotiate_check(s);	if (SSL_in_init(s) || SSL_in_before(s))		{		ret=s->handshake_func(s);		}	return(ret);	}/* For the next 2 functions, SSL_clear() sets shutdown and so * one of these calls will reset it */void SSL_set_accept_state(SSL *s)	{	s->server=1;	s->shutdown=0;	s->state=SSL_ST_ACCEPT|SSL_ST_BEFORE;	s->handshake_func=s->method->ssl_accept;	/* clear the current cipher */	ssl_clear_cipher_ctx(s);	}void SSL_set_connect_state(SSL *s)	{	s->server=0;	s->shutdown=0;	s->state=SSL_ST_CONNECT|SSL_ST_BEFORE;	s->handshake_func=s->method->ssl_connect;	/* clear the current cipher */	ssl_clear_cipher_ctx(s);	}int ssl_undefined_function(SSL *s)	{	SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);	return(0);	}int ssl_undefined_void_function(void)	{

⌨️ 快捷键说明

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