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

📄 x509v3.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (hdr.tag != 3) {		wpa_printf(MSG_DEBUG, "X509: Ignored unexpected "			   "Context-Specific tag %d in optional "			   "tbsCertificate fields", hdr.tag);		return 0;	}	/* extensions      [3]  EXPLICIT Extensions OPTIONAL */	if (cert->version != X509_CERT_V3) {		wpa_printf(MSG_DEBUG, "X509: X.509%d certificate and "			   "Extensions data which are only allowed for "			   "version 3", cert->version + 1);		return -1;	}	if (x509_parse_extensions(cert, hdr.payload, hdr.length) < 0)		return -1;	pos = hdr.payload + hdr.length;	if (pos < end) {		wpa_hexdump(MSG_DEBUG,			    "X509: Ignored extra tbsCertificate data",			    pos, end - pos);	}	return 0;}static int x509_rsadsi_oid(struct asn1_oid *oid){	return oid->len >= 4 &&		oid->oid[0] == 1 /* iso */ &&		oid->oid[1] == 2 /* member-body */ &&		oid->oid[2] == 840 /* us */ &&		oid->oid[3] == 113549 /* rsadsi */;}static int x509_pkcs_oid(struct asn1_oid *oid){	return oid->len >= 5 &&		x509_rsadsi_oid(oid) &&		oid->oid[4] == 1 /* pkcs */;}static int x509_digest_oid(struct asn1_oid *oid){	return oid->len >= 5 &&		x509_rsadsi_oid(oid) &&		oid->oid[4] == 2 /* digestAlgorithm */;}static int x509_sha1_oid(struct asn1_oid *oid){	return oid->len == 6 &&		oid->oid[0] == 1 /* iso */ &&		oid->oid[1] == 3 /* identified-organization */ &&		oid->oid[2] == 14 /* oiw */ &&		oid->oid[3] == 3 /* secsig */ &&		oid->oid[4] == 2 /* algorithms */ &&		oid->oid[5] == 26 /* id-sha1 */;}/** * x509_certificate_parse - Parse a X.509 certificate in DER format * @buf: Pointer to the X.509 certificate in DER format * @len: Buffer length * Returns: Pointer to the parsed certificate or %NULL on failure * * Caller is responsible for freeing the returned certificate by calling * x509_certificate_free(). */struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len){	struct asn1_hdr hdr;	const u8 *pos, *end, *hash_start;	struct x509_certificate *cert;	cert = os_zalloc(sizeof(*cert) + len);	if (cert == NULL)		return NULL;	os_memcpy(cert + 1, buf, len);	cert->cert_start = (u8 *) (cert + 1);	cert->cert_len = len;	pos = buf;	end = buf + len;	/* RFC 3280 - X.509 v3 certificate / ASN.1 DER */	/* Certificate ::= SEQUENCE */	if (asn1_get_next(pos, len, &hdr) < 0 ||	    hdr.class != ASN1_CLASS_UNIVERSAL ||	    hdr.tag != ASN1_TAG_SEQUENCE) {		wpa_printf(MSG_DEBUG, "X509: Certificate did not start with "			   "a valid SEQUENCE - found class %d tag 0x%x",			   hdr.class, hdr.tag);		x509_certificate_free(cert);		return NULL;	}	pos = hdr.payload;	if (pos + hdr.length > end) {		x509_certificate_free(cert);		return NULL;	}	if (pos + hdr.length < end) {		wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER "			    "encoded certificate",			    pos + hdr.length, end - pos + hdr.length);		end = pos + hdr.length;	}	hash_start = pos;	cert->tbs_cert_start = cert->cert_start + (hash_start - buf);	if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) {		x509_certificate_free(cert);		return NULL;	}	cert->tbs_cert_len = pos - hash_start;	/* signatureAlgorithm AlgorithmIdentifier */	if (x509_parse_algorithm_identifier(pos, end - pos,					    &cert->signature_alg, &pos)) {		x509_certificate_free(cert);		return NULL;	}	/* signatureValue BIT STRING */	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||	    hdr.class != ASN1_CLASS_UNIVERSAL ||	    hdr.tag != ASN1_TAG_BITSTRING) {		wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING "			   "(signatureValue) - found class %d tag 0x%x",			   hdr.class, hdr.tag);		x509_certificate_free(cert);		return NULL;	}	if (hdr.length < 1) {		x509_certificate_free(cert);		return NULL;	}	pos = hdr.payload;	if (*pos) {		wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits",			   *pos);		/* PKCS #1 v1.5 10.2.1:		 * It is an error if the length in bits of the signature S is		 * not a multiple of eight.		 */		x509_certificate_free(cert);		return NULL;	}	os_free(cert->sign_value);	cert->sign_value = os_malloc(hdr.length - 1);	if (cert->sign_value == NULL) {		wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "			   "signatureValue");		x509_certificate_free(cert);		return NULL;	}	os_memcpy(cert->sign_value, pos + 1, hdr.length - 1);	cert->sign_value_len = hdr.length - 1;	wpa_hexdump(MSG_MSGDUMP, "X509: signature",		    cert->sign_value, cert->sign_value_len);	return cert;}/** * x509_certificate_check_signature - Verify certificate signature * @issuer: Issuer certificate * @cert: Certificate to be verified * Returns: 0 if cert has a valid signature that was signed by the issuer, * -1 if not */int x509_certificate_check_signature(struct x509_certificate *issuer,				     struct x509_certificate *cert){	struct crypto_public_key *pk;	u8 *data;	const u8 *pos, *end, *next, *da_end;	size_t data_len;	struct asn1_hdr hdr;	struct asn1_oid oid;	u8 hash[20];	size_t hash_len;	if (!x509_pkcs_oid(&cert->signature.oid) ||	    cert->signature.oid.len != 7 ||	    cert->signature.oid.oid[5] != 1 /* pkcs-1 */) {		wpa_printf(MSG_DEBUG, "X509: Unrecognized signature "			   "algorithm");		return -1;	}	pk = crypto_public_key_import(issuer->public_key,				      issuer->public_key_len);	if (pk == NULL)		return -1;	data_len = cert->sign_value_len;	data = os_malloc(data_len);	if (data == NULL) {		crypto_public_key_free(pk);		return -1;	}	if (crypto_public_key_decrypt_pkcs1(pk, cert->sign_value,					    cert->sign_value_len, data,					    &data_len) < 0) {		wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature");		crypto_public_key_free(pk);		os_free(data);		return -1;	}	crypto_public_key_free(pk);	wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len);	/*	 * PKCS #1 v1.5, 10.1.2:	 *	 * DigestInfo ::= SEQUENCE {	 *     digestAlgorithm DigestAlgorithmIdentifier,	 *     digest Digest	 * }	 *	 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier	 *	 * Digest ::= OCTET STRING	 *	 */	if (asn1_get_next(data, data_len, &hdr) < 0 ||	    hdr.class != ASN1_CLASS_UNIVERSAL ||	    hdr.tag != ASN1_TAG_SEQUENCE) {		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "			   "(DigestInfo) - found class %d tag 0x%x",			   hdr.class, hdr.tag);		os_free(data);		return -1;	}	pos = hdr.payload;	end = pos + hdr.length;	/*	 * X.509:	 * AlgorithmIdentifier ::= SEQUENCE {	 *     algorithm            OBJECT IDENTIFIER,	 *     parameters           ANY DEFINED BY algorithm OPTIONAL	 * }	 */	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||	    hdr.class != ASN1_CLASS_UNIVERSAL ||	    hdr.tag != ASN1_TAG_SEQUENCE) {		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "			   "(AlgorithmIdentifier) - found class %d tag 0x%x",			   hdr.class, hdr.tag);		os_free(data);		return -1;	}	da_end = hdr.payload + hdr.length;	if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {		wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm");		os_free(data);		return -1;	}	if (x509_sha1_oid(&oid)) {		if (cert->signature.oid.oid[6] !=		    5 /* sha-1WithRSAEncryption */) {			wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 "				   "does not match with certificate "				   "signatureAlgorithm (%lu)",				   cert->signature.oid.oid[6]);			os_free(data);			return -1;		}		goto skip_digest_oid;	}	if (!x509_digest_oid(&oid)) {		wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm");		os_free(data);		return -1;	}	switch (oid.oid[5]) {	case 5: /* md5 */		if (cert->signature.oid.oid[6] != 4 /* md5WithRSAEncryption */)		{			wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does "				   "not match with certificate "				   "signatureAlgorithm (%lu)",				   cert->signature.oid.oid[6]);			os_free(data);			return -1;		}		break;	case 2: /* md2 */	case 4: /* md4 */	default:		wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm "			   "(%lu)", oid.oid[5]);		os_free(data);		return -1;	}skip_digest_oid:	/* Digest ::= OCTET STRING */	pos = da_end;	end = data + data_len;	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||	    hdr.class != ASN1_CLASS_UNIVERSAL ||	    hdr.tag != ASN1_TAG_OCTETSTRING) {		wpa_printf(MSG_DEBUG, "X509: Expected OCTETSTRING "			   "(Digest) - found class %d tag 0x%x",			   hdr.class, hdr.tag);		os_free(data);		return -1;	}	wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest",		    hdr.payload, hdr.length);	switch (cert->signature.oid.oid[6]) {	case 4: /* md5WithRSAEncryption */		md5_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len,			   hash);		hash_len = 16;		wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)",			    hash, hash_len);		break;	case 5: /* sha-1WithRSAEncryption */		sha1_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len,			    hash);		hash_len = 20;		wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)",			    hash, hash_len);		break;	case 2: /* md2WithRSAEncryption */	case 11: /* sha256WithRSAEncryption */	case 12: /* sha384WithRSAEncryption */	case 13: /* sha512WithRSAEncryption */	default:		wpa_printf(MSG_INFO, "X509: Unsupported certificate signature "			   "algorithm (%lu)", cert->signature.oid.oid[6]);		os_free(data);		return -1;	}	if (hdr.length != hash_len ||	    os_memcmp(hdr.payload, hash, hdr.length) != 0) {		wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "			   "with calculated tbsCertificate hash");		os_free(data);		return -1;	}	os_free(data);	wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with "		   "calculated tbsCertificate hash");	return 0;}static int x509_valid_issuer(const struct x509_certificate *cert){	if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) &&	    !cert->ca) {		wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an "			   "issuer");		return -1;	}	if (cert->version == X509_CERT_V3 &&	    !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {		wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "			   "include BasicConstraints extension");		return -1;	}	if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&	    !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {		wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "			   "keyCertSign bit in Key Usage");		return -1;	}	return 0;}/** * x509_certificate_chain_validate - Validate X.509 certificate chain * @trusted: List of trusted certificates * @chain: Certificate chain to be validated (first chain must be issued by * signed by the second certificate in the chain and so on) * @reason: Buffer for returning failure reason (X509_VALIDATE_*) * Returns: 0 if chain is valid, -1 if not */int x509_certificate_chain_validate(struct x509_certificate *trusted,				    struct x509_certificate *chain,				    int *reason){	long unsigned idx;	int chain_trusted = 0;	struct x509_certificate *cert, *trust;	char buf[128];	struct os_time now;	*reason = X509_VALIDATE_OK;	wpa_printf(MSG_DEBUG, "X509: Validate certificate chain");	os_get_time(&now);	for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {		x509_name_string(&cert->subject, buf, sizeof(buf)); 		wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);		if (chain_trusted)			continue;		if ((unsigned long) now.sec <		    (unsigned long) cert->not_before ||		    (unsigned long) now.sec >		    (unsigned long) cert->not_after) {			wpa_printf(MSG_INFO, "X509: Certificate not valid "				   "(now=%lu not_before=%lu not_after=%lu)",				   now.sec, cert->not_before, cert->not_after);			*reason = X509_VALIDATE_CERTIFICATE_EXPIRED;			return -1;		}		if (cert->next) {			if (x509_name_compare(&cert->issuer,					      &cert->next->subject) != 0) {				wpa_printf(MSG_DEBUG, "X509: Certificate "					   "chain issuer name mismatch");				*reason = X509_VALIDATE_CERTIFICATE_UNKNOWN;				return -1;			}			if (x509_valid_issuer(cert->next) < 0) {				*reason = X509_VALIDATE_BAD_CERTIFICATE;				return -1;			}			if ((cert->next->extensions_present &			     X509_EXT_PATH_LEN_CONSTRAINT) &&			    idx > cert->next->path_len_constraint) {				wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"					   " not met (idx=%lu issuer "					   "pathLenConstraint=%lu)", idx,					   cert->next->path_len_constraint);				*reason = X509_VALIDATE_BAD_CERTIFICATE;				return -1;			}			if (x509_certificate_check_signature(cert->next, cert)			    < 0) {				wpa_printf(MSG_DEBUG, "X509: Invalid "					   "certificate signature within "					   "chain");				*reason = X509_VALIDATE_BAD_CERTIFICATE;				return -1;			}		}		for (trust = trusted; trust; trust = trust->next) {			if (x509_name_compare(&cert->issuer, &trust->subject)			    == 0)				break;		}		if (trust) {			wpa_printf(MSG_DEBUG, "X509: Found issuer from the "				   "list of trusted certificates");			if (x509_valid_issuer(trust) < 0) {				*reason = X509_VALIDATE_BAD_CERTIFICATE;				return -1;			}			if (x509_certificate_check_signature(trust, cert) < 0)			{				wpa_printf(MSG_DEBUG, "X509: Invalid "					   "certificate signature");				*reason = X509_VALIDATE_BAD_CERTIFICATE;				return -1;			}			wpa_printf(MSG_DEBUG, "X509: Trusted certificate "				   "found to complete the chain");			chain_trusted = 1;		}	}	if (!chain_trusted) {		wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers "			   "from the list of trusted certificates");		if (trusted) {			*reason = X509_VALIDATE_UNKNOWN_CA;			return -1;		}		wpa_printf(MSG_DEBUG, "X509: Certificate chain validation "			   "disabled - ignore unknown CA issue");	}	wpa_printf(MSG_DEBUG, "X509: Certificate chain valid");	return 0;}/** * x509_certificate_get_subject - Get a certificate based on Subject name * @chain: Certificate chain to search through * @name: Subject name to search for * Returns: Pointer to the certificate with the given Subject name or * %NULL on failure */struct x509_certificate *x509_certificate_get_subject(struct x509_certificate *chain,			     struct x509_name *name){	struct x509_certificate *cert;	for (cert = chain; cert; cert = cert->next) {		if (x509_name_compare(&cert->subject, name) == 0)			return cert;	}	return NULL;}/** * x509_certificate_self_signed - Is the certificate self-signed? * @cert: Certificate * Returns: 1 if certificate is self-signed, 0 if not */int x509_certificate_self_signed(struct x509_certificate *cert){	return x509_name_compare(&cert->issuer, &cert->subject) == 0;}#endif /* CONFIG_INTERNAL_X509 */

⌨️ 快捷键说明

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