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

📄 v3_purp.c

📁 开源的ssl算法openssl,版本0.9.8H
💻 C
📖 第 1 页 / 共 2 页
字号:
	if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {		if(bs->ca) x->ex_flags |= EXFLAG_CA;		if(bs->pathlen) {			if((bs->pathlen->type == V_ASN1_NEG_INTEGER)						|| !bs->ca) {				x->ex_flags |= EXFLAG_INVALID;				x->ex_pathlen = 0;			} else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);		} else x->ex_pathlen = -1;		BASIC_CONSTRAINTS_free(bs);		x->ex_flags |= EXFLAG_BCONS;	}	/* Handle proxy certificates */	if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {		if (x->ex_flags & EXFLAG_CA		    || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0		    || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) {			x->ex_flags |= EXFLAG_INVALID;		}		if (pci->pcPathLengthConstraint) {			x->ex_pcpathlen =				ASN1_INTEGER_get(pci->pcPathLengthConstraint);		} else x->ex_pcpathlen = -1;		PROXY_CERT_INFO_EXTENSION_free(pci);		x->ex_flags |= EXFLAG_PROXY;	}	/* Handle key usage */	if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {		if(usage->length > 0) {			x->ex_kusage = usage->data[0];			if(usage->length > 1) 				x->ex_kusage |= usage->data[1] << 8;		} else x->ex_kusage = 0;		x->ex_flags |= EXFLAG_KUSAGE;		ASN1_BIT_STRING_free(usage);	}	x->ex_xkusage = 0;	if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {		x->ex_flags |= EXFLAG_XKUSAGE;		for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {			switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) {				case NID_server_auth:				x->ex_xkusage |= XKU_SSL_SERVER;				break;				case NID_client_auth:				x->ex_xkusage |= XKU_SSL_CLIENT;				break;				case NID_email_protect:				x->ex_xkusage |= XKU_SMIME;				break;				case NID_code_sign:				x->ex_xkusage |= XKU_CODE_SIGN;				break;				case NID_ms_sgc:				case NID_ns_sgc:				x->ex_xkusage |= XKU_SGC;				break;				case NID_OCSP_sign:				x->ex_xkusage |= XKU_OCSP_SIGN;				break;				case NID_time_stamp:				x->ex_xkusage |= XKU_TIMESTAMP;				break;				case NID_dvcs:				x->ex_xkusage |= XKU_DVCS;				break;			}		}		sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);	}	if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {		if(ns->length > 0) x->ex_nscert = ns->data[0];		else x->ex_nscert = 0;		x->ex_flags |= EXFLAG_NSCERT;		ASN1_BIT_STRING_free(ns);	}	x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);	x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);#ifndef OPENSSL_NO_RFC3779	x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);	x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,					  NULL, NULL);#endif	for (i = 0; i < X509_get_ext_count(x); i++)		{		ex = X509_get_ext(x, i);		if (!X509_EXTENSION_get_critical(ex))			continue;		if (!X509_supported_extension(ex))			{			x->ex_flags |= EXFLAG_CRITICAL;			break;			}		}	x->ex_flags |= EXFLAG_SET;}/* CA checks common to all purposes * return codes: * 0 not a CA * 1 is a CA * 2 basicConstraints absent so "maybe" a CA * 3 basicConstraints absent but self signed V1. * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. */#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)#define ku_reject(x, usage) \	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))#define xku_reject(x, usage) \	(((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))#define ns_reject(x, usage) \	(((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))static int check_ca(const X509 *x){	/* keyUsage if present should allow cert signing */	if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0;	if(x->ex_flags & EXFLAG_BCONS) {		if(x->ex_flags & EXFLAG_CA) return 1;		/* If basicConstraints says not a CA then say so */		else return 0;	} else {		/* we support V1 roots for...  uh, I don't really know why. */		if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3;		/* If key usage present it must have certSign so tolerate it */		else if (x->ex_flags & EXFLAG_KUSAGE) return 4;		/* Older certificates could have Netscape-specific CA types */		else if (x->ex_flags & EXFLAG_NSCERT			 && x->ex_nscert & NS_ANY_CA) return 5;		/* can this still be regarded a CA certificate?  I doubt it */		return 0;	}}int X509_check_ca(X509 *x){	if(!(x->ex_flags & EXFLAG_SET)) {		CRYPTO_w_lock(CRYPTO_LOCK_X509);		x509v3_cache_extensions(x);		CRYPTO_w_unlock(CRYPTO_LOCK_X509);	}	return check_ca(x);}/* Check SSL CA: common checks for SSL client and server */static int check_ssl_ca(const X509 *x){	int ca_ret;	ca_ret = check_ca(x);	if(!ca_ret) return 0;	/* check nsCertType if present */	if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret;	else return 0;}static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca){	if(xku_reject(x,XKU_SSL_CLIENT)) return 0;	if(ca) return check_ssl_ca(x);	/* We need to do digital signatures with it */	if(ku_reject(x,KU_DIGITAL_SIGNATURE)) return 0;	/* nsCertType if present should allow SSL client use */		if(ns_reject(x, NS_SSL_CLIENT)) return 0;	return 1;}static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca){	if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0;	if(ca) return check_ssl_ca(x);	if(ns_reject(x, NS_SSL_SERVER)) return 0;	/* Now as for keyUsage: we'll at least need to sign OR encipher */	if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT)) return 0;		return 1;}static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca){	int ret;	ret = check_purpose_ssl_server(xp, x, ca);	if(!ret || ca) return ret;	/* We need to encipher or Netscape complains */	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;	return ret;}/* common S/MIME checks */static int purpose_smime(const X509 *x, int ca){	if(xku_reject(x,XKU_SMIME)) return 0;	if(ca) {		int ca_ret;		ca_ret = check_ca(x);		if(!ca_ret) return 0;		/* check nsCertType if present */		if(ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret;		else return 0;	}	if(x->ex_flags & EXFLAG_NSCERT) {		if(x->ex_nscert & NS_SMIME) return 1;		/* Workaround for some buggy certificates */		if(x->ex_nscert & NS_SSL_CLIENT) return 2;		return 0;	}	return 1;}static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca){	int ret;	ret = purpose_smime(x, ca);	if(!ret || ca) return ret;	if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) return 0;	return ret;}static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca){	int ret;	ret = purpose_smime(x, ca);	if(!ret || ca) return ret;	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;	return ret;}static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca){	if(ca) {		int ca_ret;		if((ca_ret = check_ca(x)) != 2) return ca_ret;		else return 0;	}	if(ku_reject(x, KU_CRL_SIGN)) return 0;	return 1;}/* OCSP helper: this is *not* a full OCSP check. It just checks that * each CA is valid. Additional checks must be made on the chain. */static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca){	/* Must be a valid CA.  Should we really support the "I don't know"	   value (2)? */	if(ca) return check_ca(x);	/* leaf certificate is checked in OCSP_verify() */	return 1;}static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca){	return 1;}/* Various checks to see if one certificate issued the second. * This can be used to prune a set of possible issuer certificates * which have been looked up using some simple method such as by * subject name. * These are: * 1. Check issuer_name(subject) == subject_name(issuer) * 2. If akid(subject) exists check it matches issuer * 3. If key_usage(issuer) exists check it supports certificate signing * returns 0 for OK, positive for reason for mismatch, reasons match * codes for X509_verify_cert() */int X509_check_issued(X509 *issuer, X509 *subject){	if(X509_NAME_cmp(X509_get_subject_name(issuer),			X509_get_issuer_name(subject)))				return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;	x509v3_cache_extensions(issuer);	x509v3_cache_extensions(subject);	if(subject->akid) {		/* Check key ids (if present) */		if(subject->akid->keyid && issuer->skid &&		 ASN1_OCTET_STRING_cmp(subject->akid->keyid, issuer->skid) )				return X509_V_ERR_AKID_SKID_MISMATCH;		/* Check serial number */		if(subject->akid->serial &&			ASN1_INTEGER_cmp(X509_get_serialNumber(issuer),						subject->akid->serial))				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;		/* Check issuer name */		if(subject->akid->issuer) {			/* Ugh, for some peculiar reason AKID includes			 * SEQUENCE OF GeneralName. So look for a DirName.			 * There may be more than one but we only take any			 * notice of the first.			 */			GENERAL_NAMES *gens;			GENERAL_NAME *gen;			X509_NAME *nm = NULL;			int i;			gens = subject->akid->issuer;			for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) {				gen = sk_GENERAL_NAME_value(gens, i);				if(gen->type == GEN_DIRNAME) {					nm = gen->d.dirn;					break;				}			}			if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;		}	}	if(subject->ex_flags & EXFLAG_PROXY)		{		if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))			return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;		}	else if(ku_reject(issuer, KU_KEY_CERT_SIGN))		return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;	return X509_V_OK;}

⌨️ 快捷键说明

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