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

📄 x509_vfy.c

📁 开源的ssl算法openssl,版本0.9.8H
💻 C
📖 第 1 页 / 共 3 页
字号:
				ctx->error_depth = i;				ctx->current_cert = x;				ok=cb(0,ctx);				if (!ok) goto end;				}			proxy_path_length++;			must_be_ca = 0;			}		else			must_be_ca = 1;		}	ok = 1; end:	return ok;#endif}static int check_trust(X509_STORE_CTX *ctx){#ifdef OPENSSL_NO_CHAIN_VERIFY	return 1;#else	int i, ok;	X509 *x;	int (*cb)(int xok,X509_STORE_CTX *xctx);	cb=ctx->verify_cb;/* For now just check the last certificate in the chain */	i = sk_X509_num(ctx->chain) - 1;	x = sk_X509_value(ctx->chain, i);	ok = X509_check_trust(x, ctx->param->trust, 0);	if (ok == X509_TRUST_TRUSTED)		return 1;	ctx->error_depth = i;	ctx->current_cert = x;	if (ok == X509_TRUST_REJECTED)		ctx->error = X509_V_ERR_CERT_REJECTED;	else		ctx->error = X509_V_ERR_CERT_UNTRUSTED;	ok = cb(0, ctx);	return ok;#endif}static int check_revocation(X509_STORE_CTX *ctx)	{	int i, last, ok;	if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))		return 1;	if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)		last = sk_X509_num(ctx->chain) - 1;	else		last = 0;	for(i = 0; i <= last; i++)		{		ctx->error_depth = i;		ok = check_cert(ctx);		if (!ok) return ok;		}	return 1;	}static int check_cert(X509_STORE_CTX *ctx)	{	X509_CRL *crl = NULL;	X509 *x;	int ok, cnum;	cnum = ctx->error_depth;	x = sk_X509_value(ctx->chain, cnum);	ctx->current_cert = x;	/* Try to retrieve relevant CRL */	ok = ctx->get_crl(ctx, &crl, x);	/* If error looking up CRL, nothing we can do except	 * notify callback	 */	if(!ok)		{		ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;		ok = ctx->verify_cb(0, ctx);		goto err;		}	ctx->current_crl = crl;	ok = ctx->check_crl(ctx, crl);	if (!ok) goto err;	ok = ctx->cert_crl(ctx, crl, x);	err:	ctx->current_crl = NULL;	X509_CRL_free(crl);	return ok;	}/* Check CRL times against values in X509_STORE_CTX */static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)	{	time_t *ptime;	int i;	ctx->current_crl = crl;	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)		ptime = &ctx->param->check_time;	else		ptime = NULL;	i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);	if (i == 0)		{		ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;		if (!notify || !ctx->verify_cb(0, ctx))			return 0;		}	if (i > 0)		{		ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;		if (!notify || !ctx->verify_cb(0, ctx))			return 0;		}	if(X509_CRL_get_nextUpdate(crl))		{		i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);		if (i == 0)			{			ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;			if (!notify || !ctx->verify_cb(0, ctx))				return 0;			}		if (i < 0)			{			ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;			if (!notify || !ctx->verify_cb(0, ctx))				return 0;			}		}	ctx->current_crl = NULL;	return 1;	}/* Lookup CRLs from the supplied list. Look for matching isser name * and validity. If we can't find a valid CRL return the last one * with matching name. This gives more meaningful error codes. Otherwise * we'd get a CRL not found error if a CRL existed with matching name but * was invalid. */static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl,			X509_NAME *nm, STACK_OF(X509_CRL) *crls)	{	int i;	X509_CRL *crl, *best_crl = NULL;	for (i = 0; i < sk_X509_CRL_num(crls); i++)		{		crl = sk_X509_CRL_value(crls, i);		if (X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))			continue;		if (check_crl_time(ctx, crl, 0))			{			*pcrl = crl;			CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509);			return 1;			}		best_crl = crl;		}	if (best_crl)		{		*pcrl = best_crl;		CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509);		}			return 0;	}/* Retrieve CRL corresponding to certificate: currently just a * subject lookup: maybe use AKID later... */static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x)	{	int ok;	X509_CRL *crl = NULL;	X509_OBJECT xobj;	X509_NAME *nm;	nm = X509_get_issuer_name(x);	ok = get_crl_sk(ctx, &crl, nm, ctx->crls);	if (ok)		{		*pcrl = crl;		return 1;		}	ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj);	if (!ok)		{		/* If we got a near match from get_crl_sk use that */		if (crl)			{			*pcrl = crl;			return 1;			}		return 0;		}	*pcrl = xobj.data.crl;	if (crl)		X509_CRL_free(crl);	return 1;	}/* Check CRL validity */static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)	{	X509 *issuer = NULL;	EVP_PKEY *ikey = NULL;	int ok = 0, chnum, cnum;	cnum = ctx->error_depth;	chnum = sk_X509_num(ctx->chain) - 1;	/* Find CRL issuer: if not last certificate then issuer	 * is next certificate in chain.	 */	if(cnum < chnum)		issuer = sk_X509_value(ctx->chain, cnum + 1);	else		{		issuer = sk_X509_value(ctx->chain, chnum);		/* If not self signed, can't check signature */		if(!ctx->check_issued(ctx, issuer, issuer))			{			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;			ok = ctx->verify_cb(0, ctx);			if(!ok) goto err;			}		}	if(issuer)		{		/* Check for cRLSign bit if keyUsage present */		if ((issuer->ex_flags & EXFLAG_KUSAGE) &&			!(issuer->ex_kusage & KU_CRL_SIGN))			{			ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;			ok = ctx->verify_cb(0, ctx);			if(!ok) goto err;			}		/* Attempt to get issuer certificate public key */		ikey = X509_get_pubkey(issuer);		if(!ikey)			{			ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;			ok = ctx->verify_cb(0, ctx);			if (!ok) goto err;			}		else			{			/* Verify CRL signature */			if(X509_CRL_verify(crl, ikey) <= 0)				{				ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE;				ok = ctx->verify_cb(0, ctx);				if (!ok) goto err;				}			}		}	ok = check_crl_time(ctx, crl, 1);	if (!ok)		goto err;	ok = 1;	err:	EVP_PKEY_free(ikey);	return ok;	}/* Check certificate against CRL */static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)	{	int idx, ok;	X509_REVOKED rtmp;	STACK_OF(X509_EXTENSION) *exts;	X509_EXTENSION *ext;	/* Look for serial number of certificate in CRL */	rtmp.serialNumber = X509_get_serialNumber(x);	/* Sort revoked into serial number order if not already sorted.	 * Do this under a lock to avoid race condition. 	 */	if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))		{		CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);		sk_X509_REVOKED_sort(crl->crl->revoked);		CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);		}	idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);	/* If found assume revoked: want something cleverer than	 * this to handle entry extensions in V2 CRLs.	 */	if(idx >= 0)		{		ctx->error = X509_V_ERR_CERT_REVOKED;		ok = ctx->verify_cb(0, ctx);		if (!ok) return 0;		}	if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)		return 1;	/* See if we have any critical CRL extensions: since we	 * currently don't handle any CRL extensions the CRL must be	 * rejected. 	 * This code accesses the X509_CRL structure directly: applications	 * shouldn't do this.	 */	exts = crl->crl->extensions;	for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)		{		ext = sk_X509_EXTENSION_value(exts, idx);		if (ext->critical > 0)			{			ctx->error =				X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;			ok = ctx->verify_cb(0, ctx);			if(!ok) return 0;			break;			}		}	return 1;	}static int check_policy(X509_STORE_CTX *ctx)	{	int ret;	ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,				ctx->param->policies, ctx->param->flags);	if (ret == 0)		{		X509err(X509_F_CHECK_POLICY,ERR_R_MALLOC_FAILURE);		return 0;		}	/* Invalid or inconsistent extensions */	if (ret == -1)		{		/* Locate certificates with bad extensions and notify		 * callback.		 */		X509 *x;		int i;		for (i = 1; i < sk_X509_num(ctx->chain); i++)			{			x = sk_X509_value(ctx->chain, i);			if (!(x->ex_flags & EXFLAG_INVALID_POLICY))				continue;			ctx->current_cert = x;			ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;			ret = ctx->verify_cb(0, ctx);			}		return 1;		}	if (ret == -2)		{		ctx->current_cert = NULL;		ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;		return ctx->verify_cb(0, ctx);		}	if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY)		{		ctx->current_cert = NULL;		ctx->error = X509_V_OK;		if (!ctx->verify_cb(2, ctx))			return 0;		}	return 1;	}static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)	{	time_t *ptime;	int i;	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)		ptime = &ctx->param->check_time;	else		ptime = NULL;	i=X509_cmp_time(X509_get_notBefore(x), ptime);	if (i == 0)		{		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;		ctx->current_cert=x;		if (!ctx->verify_cb(0, ctx))			return 0;		}	if (i > 0)		{		ctx->error=X509_V_ERR_CERT_NOT_YET_VALID;		ctx->current_cert=x;		if (!ctx->verify_cb(0, ctx))			return 0;		}	i=X509_cmp_time(X509_get_notAfter(x), ptime);	if (i == 0)		{		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;		ctx->current_cert=x;		if (!ctx->verify_cb(0, ctx))			return 0;		}	if (i < 0)		{		ctx->error=X509_V_ERR_CERT_HAS_EXPIRED;		ctx->current_cert=x;		if (!ctx->verify_cb(0, ctx))			return 0;		}	return 1;	}static int internal_verify(X509_STORE_CTX *ctx)	{	int ok=0,n;	X509 *xs,*xi;	EVP_PKEY *pkey=NULL;	int (*cb)(int xok,X509_STORE_CTX *xctx);	cb=ctx->verify_cb;	n=sk_X509_num(ctx->chain);	ctx->error_depth=n-1;	n--;	xi=sk_X509_value(ctx->chain,n);	if (ctx->check_issued(ctx, xi, xi))		xs=xi;	else		{		if (n <= 0)			{			ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;			ctx->current_cert=xi;			ok=cb(0,ctx);			goto end;			}		else			{			n--;			ctx->error_depth=n;			xs=sk_X509_value(ctx->chain,n);			}		}/*	ctx->error=0;  not needed */	while (n >= 0)		{		ctx->error_depth=n;		if (!xs->valid)			{			if ((pkey=X509_get_pubkey(xi)) == NULL)				{				ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;				ctx->current_cert=xi;				ok=(*cb)(0,ctx);				if (!ok) goto end;				}			else if (X509_verify(xs,pkey) <= 0)				/* XXX  For the final trusted self-signed cert,				 * this is a waste of time.  That check should				 * optional so that e.g. 'openssl x509' can be				 * used to detect invalid self-signatures, but				 * we don't verify again and again in SSL				 * handshakes and the like once the cert has				 * been declared trusted. */				{				ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;				ctx->current_cert=xs;				ok=(*cb)(0,ctx);				if (!ok)					{					EVP_PKEY_free(pkey);					goto end;					}				}			EVP_PKEY_free(pkey);			pkey=NULL;			}		xs->valid = 1;		ok = check_cert_time(ctx, xs);		if (!ok)			goto end;		/* The last error (if any) is still in the error value */		ctx->current_issuer=xi;		ctx->current_cert=xs;		ok=(*cb)(1,ctx);		if (!ok) goto end;		n--;		if (n >= 0)			{			xi=xs;			xs=sk_X509_value(ctx->chain,n);			}		}

⌨️ 快捷键说明

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