/* Provenance: openssl/openssl ossl_policy_cache_set_mapping (fixed). * repo: openssl/openssl * commit: 7725e7bfe6f2ce8146b6552b44e0d226be7638e7 * parent: 9a5c884999a55595e376083b3a165515c8123049 * commit_url: https://github.com/openssl/openssl/commit/7725e7bfe6f2ce8146b6552b44e0d226be7638e7 * cve: CVE-2022-3996 * license: Apache-2.0 * function: ossl_policy_cache_set_mapping * relpath: crypto/x509/pcy_map.c */ int ossl_policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) { POLICY_MAPPING *map; X509_POLICY_DATA *data; X509_POLICY_CACHE *cache = x->policy_cache; int i; int ret = 0; if (sk_POLICY_MAPPING_num(maps) == 0) { ret = -1; goto bad_mapping; } for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) { map = sk_POLICY_MAPPING_value(maps, i); /* Reject if map to or from anyPolicy */ if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) { ret = -1; goto bad_mapping; } /* Attempt to find matching policy data */ data = ossl_policy_cache_find_data(cache, map->issuerDomainPolicy); /* If we don't have anyPolicy can't map */ if (data == NULL && !cache->anyPolicy) continue; /* Create a NODE from anyPolicy */ if (data == NULL) { data = ossl_policy_data_new(NULL, map->issuerDomainPolicy, cache->anyPolicy->flags & POLICY_DATA_FLAG_CRITICAL); if (data == NULL) goto bad_mapping; data->qualifier_set = cache->anyPolicy->qualifier_set; /* * map->issuerDomainPolicy = NULL; */ data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; if (!sk_X509_POLICY_DATA_push(cache->data, data)) { ossl_policy_data_free(data); goto bad_mapping; } } else data->flags |= POLICY_DATA_FLAG_MAPPED; if (!sk_ASN1_OBJECT_push(data->expected_policy_set, map->subjectDomainPolicy)) goto bad_mapping; map->subjectDomainPolicy = NULL; } ret = 1; bad_mapping: sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); return ret; }