mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-08 06:03:47 +08:00
update
This commit is contained in:
@@ -13,7 +13,7 @@ AR= ar r
|
||||
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||
|
||||
GENERAL=Makefile README
|
||||
TEST=
|
||||
TEST=v3nametest.c
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
@@ -22,13 +22,13 @@ v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c v3_pku.c \
|
||||
v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \
|
||||
v3_ocsp.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c v3_pcia.c v3_pci.c \
|
||||
pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \
|
||||
v3_asid.c v3_addr.c
|
||||
v3_asid.c v3_addr.c v3_scts.c
|
||||
LIBOBJ= v3_bcons.o v3_bitst.o v3_conf.o v3_extku.o v3_ia5.o v3_lib.o \
|
||||
v3_prn.o v3_utl.o v3err.o v3_genn.o v3_alt.o v3_skey.o v3_akey.o v3_pku.o \
|
||||
v3_int.o v3_enum.o v3_sxnet.o v3_cpols.o v3_crld.o v3_purp.o v3_info.o \
|
||||
v3_ocsp.o v3_akeya.o v3_pmaps.o v3_pcons.o v3_ncons.o v3_pcia.o v3_pci.o \
|
||||
pcy_cache.o pcy_node.o pcy_data.o pcy_map.o pcy_tree.o pcy_lib.o \
|
||||
v3_asid.o v3_addr.o
|
||||
v3_asid.o v3_addr.o v3_scts.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
@@ -71,6 +71,8 @@ tests:
|
||||
lint:
|
||||
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||
|
||||
update: depend
|
||||
|
||||
depend:
|
||||
@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
|
||||
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
|
||||
@@ -533,6 +535,20 @@ v3_purp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||
v3_purp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||
v3_purp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
|
||||
v3_purp.o: ../cryptlib.h v3_purp.c
|
||||
v3_scts.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||
v3_scts.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
|
||||
v3_scts.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
|
||||
v3_scts.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
v3_scts.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||
v3_scts.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
v3_scts.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||
v3_scts.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
|
||||
v3_scts.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
v3_scts.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
|
||||
v3_scts.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||
v3_scts.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||
v3_scts.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
|
||||
v3_scts.o: ../cryptlib.h v3_scts.c
|
||||
v3_skey.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||
v3_skey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
|
||||
v3_skey.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* ext_dat.h */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -68,65 +69,68 @@ extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
|
||||
extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
|
||||
extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
|
||||
extern X509V3_EXT_METHOD v3_addr, v3_asid;
|
||||
extern X509V3_EXT_METHOD v3_ct_scts[];
|
||||
|
||||
/* This table will be searched using OBJ_bsearch so it *must* kept in
|
||||
* order of the ext_nid values.
|
||||
/*
|
||||
* This table will be searched using OBJ_bsearch so it *must* kept in order
|
||||
* of the ext_nid values.
|
||||
*/
|
||||
|
||||
static const X509V3_EXT_METHOD *standard_exts[] = {
|
||||
&v3_nscert,
|
||||
&v3_ns_ia5_list[0],
|
||||
&v3_ns_ia5_list[1],
|
||||
&v3_ns_ia5_list[2],
|
||||
&v3_ns_ia5_list[3],
|
||||
&v3_ns_ia5_list[4],
|
||||
&v3_ns_ia5_list[5],
|
||||
&v3_ns_ia5_list[6],
|
||||
&v3_skey_id,
|
||||
&v3_key_usage,
|
||||
&v3_pkey_usage_period,
|
||||
&v3_alt[0],
|
||||
&v3_alt[1],
|
||||
&v3_bcons,
|
||||
&v3_crl_num,
|
||||
&v3_cpols,
|
||||
&v3_akey_id,
|
||||
&v3_crld,
|
||||
&v3_ext_ku,
|
||||
&v3_delta_crl,
|
||||
&v3_crl_reason,
|
||||
&v3_nscert,
|
||||
&v3_ns_ia5_list[0],
|
||||
&v3_ns_ia5_list[1],
|
||||
&v3_ns_ia5_list[2],
|
||||
&v3_ns_ia5_list[3],
|
||||
&v3_ns_ia5_list[4],
|
||||
&v3_ns_ia5_list[5],
|
||||
&v3_ns_ia5_list[6],
|
||||
&v3_skey_id,
|
||||
&v3_key_usage,
|
||||
&v3_pkey_usage_period,
|
||||
&v3_alt[0],
|
||||
&v3_alt[1],
|
||||
&v3_bcons,
|
||||
&v3_crl_num,
|
||||
&v3_cpols,
|
||||
&v3_akey_id,
|
||||
&v3_crld,
|
||||
&v3_ext_ku,
|
||||
&v3_delta_crl,
|
||||
&v3_crl_reason,
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
&v3_crl_invdate,
|
||||
&v3_crl_invdate,
|
||||
#endif
|
||||
&v3_sxnet,
|
||||
&v3_info,
|
||||
&v3_sxnet,
|
||||
&v3_info,
|
||||
#ifndef OPENSSL_NO_RFC3779
|
||||
&v3_addr,
|
||||
&v3_asid,
|
||||
&v3_addr,
|
||||
&v3_asid,
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
&v3_ocsp_nonce,
|
||||
&v3_ocsp_crlid,
|
||||
&v3_ocsp_accresp,
|
||||
&v3_ocsp_nocheck,
|
||||
&v3_ocsp_acutoff,
|
||||
&v3_ocsp_serviceloc,
|
||||
&v3_ocsp_nonce,
|
||||
&v3_ocsp_crlid,
|
||||
&v3_ocsp_accresp,
|
||||
&v3_ocsp_nocheck,
|
||||
&v3_ocsp_acutoff,
|
||||
&v3_ocsp_serviceloc,
|
||||
#endif
|
||||
&v3_sinfo,
|
||||
&v3_policy_constraints,
|
||||
&v3_sinfo,
|
||||
&v3_policy_constraints,
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
&v3_crl_hold,
|
||||
&v3_crl_hold,
|
||||
#endif
|
||||
&v3_pci,
|
||||
&v3_name_constraints,
|
||||
&v3_policy_mappings,
|
||||
&v3_inhibit_anyp,
|
||||
&v3_idp,
|
||||
&v3_alt[2],
|
||||
&v3_freshest_crl,
|
||||
&v3_pci,
|
||||
&v3_name_constraints,
|
||||
&v3_policy_mappings,
|
||||
&v3_inhibit_anyp,
|
||||
&v3_idp,
|
||||
&v3_alt[2],
|
||||
&v3_freshest_crl,
|
||||
&v3_ct_scts[0],
|
||||
&v3_ct_scts[1],
|
||||
};
|
||||
|
||||
/* Number of standard extensions */
|
||||
|
||||
#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* pcy_cache.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2004.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -62,225 +63,207 @@
|
||||
|
||||
#include "pcy_int.h"
|
||||
|
||||
static int policy_data_cmp(const X509_POLICY_DATA * const *a,
|
||||
const X509_POLICY_DATA * const *b);
|
||||
static int policy_data_cmp(const X509_POLICY_DATA *const *a,
|
||||
const X509_POLICY_DATA *const *b);
|
||||
static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
|
||||
|
||||
/* Set cache entry according to CertificatePolicies extension.
|
||||
* Note: this destroys the passed CERTIFICATEPOLICIES structure.
|
||||
/*
|
||||
* Set cache entry according to CertificatePolicies extension. Note: this
|
||||
* destroys the passed CERTIFICATEPOLICIES structure.
|
||||
*/
|
||||
|
||||
static int policy_cache_create(X509 *x,
|
||||
CERTIFICATEPOLICIES *policies, int crit)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
X509_POLICY_CACHE *cache = x->policy_cache;
|
||||
X509_POLICY_DATA *data = NULL;
|
||||
POLICYINFO *policy;
|
||||
if (sk_POLICYINFO_num(policies) == 0)
|
||||
goto bad_policy;
|
||||
cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
|
||||
if (!cache->data)
|
||||
goto bad_policy;
|
||||
for (i = 0; i < sk_POLICYINFO_num(policies); i++)
|
||||
{
|
||||
policy = sk_POLICYINFO_value(policies, i);
|
||||
data = policy_data_new(policy, NULL, crit);
|
||||
if (!data)
|
||||
goto bad_policy;
|
||||
/* Duplicate policy OIDs are illegal: reject if matches
|
||||
* found.
|
||||
*/
|
||||
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
|
||||
{
|
||||
if (cache->anyPolicy)
|
||||
{
|
||||
ret = -1;
|
||||
goto bad_policy;
|
||||
}
|
||||
cache->anyPolicy = data;
|
||||
}
|
||||
else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1)
|
||||
{
|
||||
ret = -1;
|
||||
goto bad_policy;
|
||||
}
|
||||
else if (!sk_X509_POLICY_DATA_push(cache->data, data))
|
||||
goto bad_policy;
|
||||
data = NULL;
|
||||
}
|
||||
ret = 1;
|
||||
bad_policy:
|
||||
if (ret == -1)
|
||||
x->ex_flags |= EXFLAG_INVALID_POLICY;
|
||||
if (data)
|
||||
policy_data_free(data);
|
||||
sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
|
||||
if (ret <= 0)
|
||||
{
|
||||
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
|
||||
cache->data = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
CERTIFICATEPOLICIES *policies, int crit)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
X509_POLICY_CACHE *cache = x->policy_cache;
|
||||
X509_POLICY_DATA *data = NULL;
|
||||
POLICYINFO *policy;
|
||||
if (sk_POLICYINFO_num(policies) == 0)
|
||||
goto bad_policy;
|
||||
cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
|
||||
if (!cache->data)
|
||||
goto bad_policy;
|
||||
for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
|
||||
policy = sk_POLICYINFO_value(policies, i);
|
||||
data = policy_data_new(policy, NULL, crit);
|
||||
if (!data)
|
||||
goto bad_policy;
|
||||
/*
|
||||
* Duplicate policy OIDs are illegal: reject if matches found.
|
||||
*/
|
||||
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
|
||||
if (cache->anyPolicy) {
|
||||
ret = -1;
|
||||
goto bad_policy;
|
||||
}
|
||||
cache->anyPolicy = data;
|
||||
} else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) {
|
||||
ret = -1;
|
||||
goto bad_policy;
|
||||
} else if (!sk_X509_POLICY_DATA_push(cache->data, data))
|
||||
goto bad_policy;
|
||||
data = NULL;
|
||||
}
|
||||
ret = 1;
|
||||
bad_policy:
|
||||
if (ret == -1)
|
||||
x->ex_flags |= EXFLAG_INVALID_POLICY;
|
||||
if (data)
|
||||
policy_data_free(data);
|
||||
sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
|
||||
if (ret <= 0) {
|
||||
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
|
||||
cache->data = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int policy_cache_new(X509 *x)
|
||||
{
|
||||
X509_POLICY_CACHE *cache;
|
||||
ASN1_INTEGER *ext_any = NULL;
|
||||
POLICY_CONSTRAINTS *ext_pcons = NULL;
|
||||
CERTIFICATEPOLICIES *ext_cpols = NULL;
|
||||
POLICY_MAPPINGS *ext_pmaps = NULL;
|
||||
int i;
|
||||
cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
|
||||
if (!cache)
|
||||
return 0;
|
||||
cache->anyPolicy = NULL;
|
||||
cache->data = NULL;
|
||||
cache->any_skip = -1;
|
||||
cache->explicit_skip = -1;
|
||||
cache->map_skip = -1;
|
||||
{
|
||||
X509_POLICY_CACHE *cache;
|
||||
ASN1_INTEGER *ext_any = NULL;
|
||||
POLICY_CONSTRAINTS *ext_pcons = NULL;
|
||||
CERTIFICATEPOLICIES *ext_cpols = NULL;
|
||||
POLICY_MAPPINGS *ext_pmaps = NULL;
|
||||
int i;
|
||||
cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
|
||||
if (!cache)
|
||||
return 0;
|
||||
cache->anyPolicy = NULL;
|
||||
cache->data = NULL;
|
||||
cache->any_skip = -1;
|
||||
cache->explicit_skip = -1;
|
||||
cache->map_skip = -1;
|
||||
|
||||
x->policy_cache = cache;
|
||||
x->policy_cache = cache;
|
||||
|
||||
/* Handle requireExplicitPolicy *first*. Need to process this
|
||||
* even if we don't have any policies.
|
||||
*/
|
||||
ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
|
||||
/*
|
||||
* Handle requireExplicitPolicy *first*. Need to process this even if we
|
||||
* don't have any policies.
|
||||
*/
|
||||
ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
|
||||
|
||||
if (!ext_pcons)
|
||||
{
|
||||
if (i != -1)
|
||||
goto bad_cache;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ext_pcons->requireExplicitPolicy
|
||||
&& !ext_pcons->inhibitPolicyMapping)
|
||||
goto bad_cache;
|
||||
if (!policy_cache_set_int(&cache->explicit_skip,
|
||||
ext_pcons->requireExplicitPolicy))
|
||||
goto bad_cache;
|
||||
if (!policy_cache_set_int(&cache->map_skip,
|
||||
ext_pcons->inhibitPolicyMapping))
|
||||
goto bad_cache;
|
||||
}
|
||||
if (!ext_pcons) {
|
||||
if (i != -1)
|
||||
goto bad_cache;
|
||||
} else {
|
||||
if (!ext_pcons->requireExplicitPolicy
|
||||
&& !ext_pcons->inhibitPolicyMapping)
|
||||
goto bad_cache;
|
||||
if (!policy_cache_set_int(&cache->explicit_skip,
|
||||
ext_pcons->requireExplicitPolicy))
|
||||
goto bad_cache;
|
||||
if (!policy_cache_set_int(&cache->map_skip,
|
||||
ext_pcons->inhibitPolicyMapping))
|
||||
goto bad_cache;
|
||||
}
|
||||
|
||||
/* Process CertificatePolicies */
|
||||
/* Process CertificatePolicies */
|
||||
|
||||
ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
|
||||
/* If no CertificatePolicies extension or problem decoding then
|
||||
* there is no point continuing because the valid policies will be
|
||||
* NULL.
|
||||
*/
|
||||
if (!ext_cpols)
|
||||
{
|
||||
/* If not absent some problem with extension */
|
||||
if (i != -1)
|
||||
goto bad_cache;
|
||||
return 1;
|
||||
}
|
||||
ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
|
||||
/*
|
||||
* If no CertificatePolicies extension or problem decoding then there is
|
||||
* no point continuing because the valid policies will be NULL.
|
||||
*/
|
||||
if (!ext_cpols) {
|
||||
/* If not absent some problem with extension */
|
||||
if (i != -1)
|
||||
goto bad_cache;
|
||||
return 1;
|
||||
}
|
||||
|
||||
i = policy_cache_create(x, ext_cpols, i);
|
||||
i = policy_cache_create(x, ext_cpols, i);
|
||||
|
||||
/* NB: ext_cpols freed by policy_cache_set_policies */
|
||||
/* NB: ext_cpols freed by policy_cache_set_policies */
|
||||
|
||||
if (i <= 0)
|
||||
return i;
|
||||
if (i <= 0)
|
||||
return i;
|
||||
|
||||
ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
|
||||
ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
|
||||
|
||||
if (!ext_pmaps)
|
||||
{
|
||||
/* If not absent some problem with extension */
|
||||
if (i != -1)
|
||||
goto bad_cache;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = policy_cache_set_mapping(x, ext_pmaps);
|
||||
if (i <= 0)
|
||||
goto bad_cache;
|
||||
}
|
||||
if (!ext_pmaps) {
|
||||
/* If not absent some problem with extension */
|
||||
if (i != -1)
|
||||
goto bad_cache;
|
||||
} else {
|
||||
i = policy_cache_set_mapping(x, ext_pmaps);
|
||||
if (i <= 0)
|
||||
goto bad_cache;
|
||||
}
|
||||
|
||||
ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
|
||||
ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
|
||||
|
||||
if (!ext_any)
|
||||
{
|
||||
if (i != -1)
|
||||
goto bad_cache;
|
||||
}
|
||||
else if (!policy_cache_set_int(&cache->any_skip, ext_any))
|
||||
goto bad_cache;
|
||||
if (!ext_any) {
|
||||
if (i != -1)
|
||||
goto bad_cache;
|
||||
} else if (!policy_cache_set_int(&cache->any_skip, ext_any))
|
||||
goto bad_cache;
|
||||
|
||||
if (0)
|
||||
{
|
||||
bad_cache:
|
||||
x->ex_flags |= EXFLAG_INVALID_POLICY;
|
||||
}
|
||||
if (0) {
|
||||
bad_cache:
|
||||
x->ex_flags |= EXFLAG_INVALID_POLICY;
|
||||
}
|
||||
|
||||
if(ext_pcons)
|
||||
POLICY_CONSTRAINTS_free(ext_pcons);
|
||||
if (ext_pcons)
|
||||
POLICY_CONSTRAINTS_free(ext_pcons);
|
||||
|
||||
if (ext_any)
|
||||
ASN1_INTEGER_free(ext_any);
|
||||
if (ext_any)
|
||||
ASN1_INTEGER_free(ext_any);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void policy_cache_free(X509_POLICY_CACHE *cache)
|
||||
{
|
||||
if (!cache)
|
||||
return;
|
||||
if (cache->anyPolicy)
|
||||
policy_data_free(cache->anyPolicy);
|
||||
if (cache->data)
|
||||
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
|
||||
OPENSSL_free(cache);
|
||||
}
|
||||
{
|
||||
if (!cache)
|
||||
return;
|
||||
if (cache->anyPolicy)
|
||||
policy_data_free(cache->anyPolicy);
|
||||
if (cache->data)
|
||||
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
|
||||
OPENSSL_free(cache);
|
||||
}
|
||||
|
||||
const X509_POLICY_CACHE *policy_cache_set(X509 *x)
|
||||
{
|
||||
{
|
||||
|
||||
if (x->policy_cache == NULL)
|
||||
{
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509);
|
||||
policy_cache_new(x);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
|
||||
}
|
||||
if (x->policy_cache == NULL) {
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509);
|
||||
policy_cache_new(x);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
|
||||
}
|
||||
|
||||
return x->policy_cache;
|
||||
return x->policy_cache;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
|
||||
const ASN1_OBJECT *id)
|
||||
{
|
||||
int idx;
|
||||
X509_POLICY_DATA tmp;
|
||||
tmp.valid_policy = (ASN1_OBJECT *)id;
|
||||
idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
|
||||
if (idx == -1)
|
||||
return NULL;
|
||||
return sk_X509_POLICY_DATA_value(cache->data, idx);
|
||||
}
|
||||
const ASN1_OBJECT *id)
|
||||
{
|
||||
int idx;
|
||||
X509_POLICY_DATA tmp;
|
||||
tmp.valid_policy = (ASN1_OBJECT *)id;
|
||||
idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
|
||||
if (idx == -1)
|
||||
return NULL;
|
||||
return sk_X509_POLICY_DATA_value(cache->data, idx);
|
||||
}
|
||||
|
||||
static int policy_data_cmp(const X509_POLICY_DATA * const *a,
|
||||
const X509_POLICY_DATA * const *b)
|
||||
{
|
||||
return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
|
||||
}
|
||||
static int policy_data_cmp(const X509_POLICY_DATA *const *a,
|
||||
const X509_POLICY_DATA *const *b)
|
||||
{
|
||||
return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
|
||||
}
|
||||
|
||||
static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return 1;
|
||||
if (value->type == V_ASN1_NEG_INTEGER)
|
||||
return 0;
|
||||
*out = ASN1_INTEGER_get(value);
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if (value == NULL)
|
||||
return 1;
|
||||
if (value->type == V_ASN1_NEG_INTEGER)
|
||||
return 0;
|
||||
*out = ASN1_INTEGER_get(value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* pcy_data.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2004.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -65,71 +66,64 @@
|
||||
/* Policy Node routines */
|
||||
|
||||
void policy_data_free(X509_POLICY_DATA *data)
|
||||
{
|
||||
ASN1_OBJECT_free(data->valid_policy);
|
||||
/* Don't free qualifiers if shared */
|
||||
if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
|
||||
sk_POLICYQUALINFO_pop_free(data->qualifier_set,
|
||||
POLICYQUALINFO_free);
|
||||
sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
|
||||
OPENSSL_free(data);
|
||||
}
|
||||
{
|
||||
ASN1_OBJECT_free(data->valid_policy);
|
||||
/* Don't free qualifiers if shared */
|
||||
if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
|
||||
sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free);
|
||||
sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
|
||||
OPENSSL_free(data);
|
||||
}
|
||||
|
||||
/* Create a data based on an existing policy. If 'id' is NULL use the
|
||||
* oid in the policy, otherwise use 'id'. This behaviour covers the two
|
||||
* types of data in RFC3280: data with from a CertificatePolcies extension
|
||||
* and additional data with just the qualifiers of anyPolicy and ID from
|
||||
* another source.
|
||||
/*
|
||||
* Create a data based on an existing policy. If 'id' is NULL use the oid in
|
||||
* the policy, otherwise use 'id'. This behaviour covers the two types of
|
||||
* data in RFC3280: data with from a CertificatePolcies extension and
|
||||
* additional data with just the qualifiers of anyPolicy and ID from another
|
||||
* source.
|
||||
*/
|
||||
|
||||
X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
|
||||
const ASN1_OBJECT *cid, int crit)
|
||||
{
|
||||
X509_POLICY_DATA *ret;
|
||||
ASN1_OBJECT *id;
|
||||
if (!policy && !cid)
|
||||
return NULL;
|
||||
if (cid)
|
||||
{
|
||||
id = OBJ_dup(cid);
|
||||
if (!id)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
id = NULL;
|
||||
ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
|
||||
if (!ret->expected_policy_set)
|
||||
{
|
||||
OPENSSL_free(ret);
|
||||
if (id)
|
||||
ASN1_OBJECT_free(id);
|
||||
return NULL;
|
||||
}
|
||||
const ASN1_OBJECT *cid, int crit)
|
||||
{
|
||||
X509_POLICY_DATA *ret;
|
||||
ASN1_OBJECT *id;
|
||||
if (!policy && !cid)
|
||||
return NULL;
|
||||
if (cid) {
|
||||
id = OBJ_dup(cid);
|
||||
if (!id)
|
||||
return NULL;
|
||||
} else
|
||||
id = NULL;
|
||||
ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
|
||||
if (!ret->expected_policy_set) {
|
||||
OPENSSL_free(ret);
|
||||
if (id)
|
||||
ASN1_OBJECT_free(id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (crit)
|
||||
ret->flags = POLICY_DATA_FLAG_CRITICAL;
|
||||
else
|
||||
ret->flags = 0;
|
||||
if (crit)
|
||||
ret->flags = POLICY_DATA_FLAG_CRITICAL;
|
||||
else
|
||||
ret->flags = 0;
|
||||
|
||||
if (id)
|
||||
ret->valid_policy = id;
|
||||
else
|
||||
{
|
||||
ret->valid_policy = policy->policyid;
|
||||
policy->policyid = NULL;
|
||||
}
|
||||
if (id)
|
||||
ret->valid_policy = id;
|
||||
else {
|
||||
ret->valid_policy = policy->policyid;
|
||||
policy->policyid = NULL;
|
||||
}
|
||||
|
||||
if (policy)
|
||||
{
|
||||
ret->qualifier_set = policy->qualifiers;
|
||||
policy->qualifiers = NULL;
|
||||
}
|
||||
else
|
||||
ret->qualifier_set = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
if (policy) {
|
||||
ret->qualifier_set = policy->qualifiers;
|
||||
policy->qualifiers = NULL;
|
||||
} else
|
||||
ret->qualifier_set = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* pcy_int.h */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2004.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,121 +57,126 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
|
||||
|
||||
DECLARE_STACK_OF(X509_POLICY_DATA)
|
||||
|
||||
/* Internal structures */
|
||||
|
||||
/* This structure and the field names correspond to the Policy 'node' of
|
||||
* RFC3280. NB this structure contains no pointers to parent or child
|
||||
* data: X509_POLICY_NODE contains that. This means that the main policy data
|
||||
* can be kept static and cached with the certificate.
|
||||
/*
|
||||
* This structure and the field names correspond to the Policy 'node' of
|
||||
* RFC3280. NB this structure contains no pointers to parent or child data:
|
||||
* X509_POLICY_NODE contains that. This means that the main policy data can
|
||||
* be kept static and cached with the certificate.
|
||||
*/
|
||||
|
||||
struct X509_POLICY_DATA_st
|
||||
{
|
||||
unsigned int flags;
|
||||
/* Policy OID and qualifiers for this data */
|
||||
ASN1_OBJECT *valid_policy;
|
||||
STACK_OF(POLICYQUALINFO) *qualifier_set;
|
||||
STACK_OF(ASN1_OBJECT) *expected_policy_set;
|
||||
};
|
||||
struct X509_POLICY_DATA_st {
|
||||
unsigned int flags;
|
||||
/* Policy OID and qualifiers for this data */
|
||||
ASN1_OBJECT *valid_policy;
|
||||
STACK_OF(POLICYQUALINFO) *qualifier_set;
|
||||
STACK_OF(ASN1_OBJECT) *expected_policy_set;
|
||||
};
|
||||
|
||||
/* X509_POLICY_DATA flags values */
|
||||
|
||||
/* This flag indicates the structure has been mapped using a policy mapping
|
||||
* extension. If policy mapping is not active its references get deleted.
|
||||
/*
|
||||
* This flag indicates the structure has been mapped using a policy mapping
|
||||
* extension. If policy mapping is not active its references get deleted.
|
||||
*/
|
||||
|
||||
#define POLICY_DATA_FLAG_MAPPED 0x1
|
||||
#define POLICY_DATA_FLAG_MAPPED 0x1
|
||||
|
||||
/* This flag indicates the data doesn't correspond to a policy in Certificate
|
||||
/*
|
||||
* This flag indicates the data doesn't correspond to a policy in Certificate
|
||||
* Policies: it has been mapped to any policy.
|
||||
*/
|
||||
|
||||
#define POLICY_DATA_FLAG_MAPPED_ANY 0x2
|
||||
#define POLICY_DATA_FLAG_MAPPED_ANY 0x2
|
||||
|
||||
/* AND with flags to see if any mapping has occurred */
|
||||
|
||||
#define POLICY_DATA_FLAG_MAP_MASK 0x3
|
||||
#define POLICY_DATA_FLAG_MAP_MASK 0x3
|
||||
|
||||
/* qualifiers are shared and shouldn't be freed */
|
||||
|
||||
#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4
|
||||
#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4
|
||||
|
||||
/* Parent node is an extra node and should be freed */
|
||||
|
||||
#define POLICY_DATA_FLAG_EXTRA_NODE 0x8
|
||||
#define POLICY_DATA_FLAG_EXTRA_NODE 0x8
|
||||
|
||||
/* Corresponding CertificatePolicies is critical */
|
||||
|
||||
#define POLICY_DATA_FLAG_CRITICAL 0x10
|
||||
#define POLICY_DATA_FLAG_CRITICAL 0x10
|
||||
|
||||
/* This structure is cached with a certificate */
|
||||
|
||||
struct X509_POLICY_CACHE_st {
|
||||
/* anyPolicy data or NULL if no anyPolicy */
|
||||
X509_POLICY_DATA *anyPolicy;
|
||||
/* other policy data */
|
||||
STACK_OF(X509_POLICY_DATA) *data;
|
||||
/* If InhibitAnyPolicy present this is its value or -1 if absent. */
|
||||
long any_skip;
|
||||
/* If policyConstraints and requireExplicitPolicy present this is its
|
||||
* value or -1 if absent.
|
||||
*/
|
||||
long explicit_skip;
|
||||
/* If policyConstraints and policyMapping present this is its
|
||||
* value or -1 if absent.
|
||||
*/
|
||||
long map_skip;
|
||||
};
|
||||
/* anyPolicy data or NULL if no anyPolicy */
|
||||
X509_POLICY_DATA *anyPolicy;
|
||||
/* other policy data */
|
||||
STACK_OF(X509_POLICY_DATA) *data;
|
||||
/* If InhibitAnyPolicy present this is its value or -1 if absent. */
|
||||
long any_skip;
|
||||
/*
|
||||
* If policyConstraints and requireExplicitPolicy present this is its
|
||||
* value or -1 if absent.
|
||||
*/
|
||||
long explicit_skip;
|
||||
/*
|
||||
* If policyConstraints and policyMapping present this is its value or -1
|
||||
* if absent.
|
||||
*/
|
||||
long map_skip;
|
||||
};
|
||||
|
||||
/*#define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL*/
|
||||
/*
|
||||
* #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL
|
||||
*/
|
||||
|
||||
/* This structure represents the relationship between nodes */
|
||||
|
||||
struct X509_POLICY_NODE_st
|
||||
{
|
||||
/* node data this refers to */
|
||||
const X509_POLICY_DATA *data;
|
||||
/* Parent node */
|
||||
X509_POLICY_NODE *parent;
|
||||
/* Number of child nodes */
|
||||
int nchild;
|
||||
};
|
||||
struct X509_POLICY_NODE_st {
|
||||
/* node data this refers to */
|
||||
const X509_POLICY_DATA *data;
|
||||
/* Parent node */
|
||||
X509_POLICY_NODE *parent;
|
||||
/* Number of child nodes */
|
||||
int nchild;
|
||||
};
|
||||
|
||||
struct X509_POLICY_LEVEL_st
|
||||
{
|
||||
/* Cert for this level */
|
||||
X509 *cert;
|
||||
/* nodes at this level */
|
||||
STACK_OF(X509_POLICY_NODE) *nodes;
|
||||
/* anyPolicy node */
|
||||
X509_POLICY_NODE *anyPolicy;
|
||||
/* Extra data */
|
||||
/*STACK_OF(X509_POLICY_DATA) *extra_data;*/
|
||||
unsigned int flags;
|
||||
};
|
||||
struct X509_POLICY_LEVEL_st {
|
||||
/* Cert for this level */
|
||||
X509 *cert;
|
||||
/* nodes at this level */
|
||||
STACK_OF(X509_POLICY_NODE) *nodes;
|
||||
/* anyPolicy node */
|
||||
X509_POLICY_NODE *anyPolicy;
|
||||
/* Extra data */
|
||||
/*
|
||||
* STACK_OF(X509_POLICY_DATA) *extra_data;
|
||||
*/
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct X509_POLICY_TREE_st
|
||||
{
|
||||
/* This is the tree 'level' data */
|
||||
X509_POLICY_LEVEL *levels;
|
||||
int nlevel;
|
||||
/* Extra policy data when additional nodes (not from the certificate)
|
||||
* are required.
|
||||
*/
|
||||
STACK_OF(X509_POLICY_DATA) *extra_data;
|
||||
/* This is the authority constained policy set */
|
||||
STACK_OF(X509_POLICY_NODE) *auth_policies;
|
||||
STACK_OF(X509_POLICY_NODE) *user_policies;
|
||||
unsigned int flags;
|
||||
};
|
||||
struct X509_POLICY_TREE_st {
|
||||
/* This is the tree 'level' data */
|
||||
X509_POLICY_LEVEL *levels;
|
||||
int nlevel;
|
||||
/*
|
||||
* Extra policy data when additional nodes (not from the certificate) are
|
||||
* required.
|
||||
*/
|
||||
STACK_OF(X509_POLICY_DATA) *extra_data;
|
||||
/* This is the authority constained policy set */
|
||||
STACK_OF(X509_POLICY_NODE) *auth_policies;
|
||||
STACK_OF(X509_POLICY_NODE) *user_policies;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
/* Set if anyPolicy present in user policies */
|
||||
#define POLICY_FLAG_ANY_POLICY 0x2
|
||||
#define POLICY_FLAG_ANY_POLICY 0x2
|
||||
|
||||
/* Useful macros */
|
||||
|
||||
@@ -180,14 +186,13 @@ struct X509_POLICY_TREE_st
|
||||
/* Internal functions */
|
||||
|
||||
X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
|
||||
int crit);
|
||||
int crit);
|
||||
void policy_data_free(X509_POLICY_DATA *data);
|
||||
|
||||
X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
|
||||
const ASN1_OBJECT *id);
|
||||
const ASN1_OBJECT *id);
|
||||
int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
|
||||
|
||||
|
||||
STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
|
||||
|
||||
void policy_cache_init(void);
|
||||
@@ -195,18 +200,18 @@ void policy_cache_init(void);
|
||||
void policy_cache_free(X509_POLICY_CACHE *cache);
|
||||
|
||||
X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
|
||||
const X509_POLICY_NODE *parent,
|
||||
const ASN1_OBJECT *id);
|
||||
const X509_POLICY_NODE *parent,
|
||||
const ASN1_OBJECT *id);
|
||||
|
||||
X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
|
||||
const ASN1_OBJECT *id);
|
||||
const ASN1_OBJECT *id);
|
||||
|
||||
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
|
||||
const X509_POLICY_DATA *data,
|
||||
X509_POLICY_NODE *parent,
|
||||
X509_POLICY_TREE *tree);
|
||||
const X509_POLICY_DATA *data,
|
||||
X509_POLICY_NODE *parent,
|
||||
X509_POLICY_TREE *tree);
|
||||
void policy_node_free(X509_POLICY_NODE *node);
|
||||
int policy_node_match(const X509_POLICY_LEVEL *lvl,
|
||||
const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
|
||||
const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
|
||||
|
||||
const X509_POLICY_CACHE *policy_cache_set(X509 *x);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* pcy_lib.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2004.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
@@ -68,100 +68,100 @@
|
||||
/* X509_POLICY_TREE stuff */
|
||||
|
||||
int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
|
||||
{
|
||||
if (!tree)
|
||||
return 0;
|
||||
return tree->nlevel;
|
||||
}
|
||||
{
|
||||
if (!tree)
|
||||
return 0;
|
||||
return tree->nlevel;
|
||||
}
|
||||
|
||||
X509_POLICY_LEVEL *
|
||||
X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
|
||||
{
|
||||
if (!tree || (i < 0) || (i >= tree->nlevel))
|
||||
return NULL;
|
||||
return tree->levels + i;
|
||||
}
|
||||
X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
|
||||
int i)
|
||||
{
|
||||
if (!tree || (i < 0) || (i >= tree->nlevel))
|
||||
return NULL;
|
||||
return tree->levels + i;
|
||||
}
|
||||
|
||||
STACK_OF(X509_POLICY_NODE) *
|
||||
X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
|
||||
{
|
||||
if (!tree)
|
||||
return NULL;
|
||||
return tree->auth_policies;
|
||||
}
|
||||
STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
|
||||
X509_POLICY_TREE
|
||||
*tree)
|
||||
{
|
||||
if (!tree)
|
||||
return NULL;
|
||||
return tree->auth_policies;
|
||||
}
|
||||
|
||||
STACK_OF(X509_POLICY_NODE) *
|
||||
X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
|
||||
{
|
||||
if (!tree)
|
||||
return NULL;
|
||||
if (tree->flags & POLICY_FLAG_ANY_POLICY)
|
||||
return tree->auth_policies;
|
||||
else
|
||||
return tree->user_policies;
|
||||
}
|
||||
STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
|
||||
X509_POLICY_TREE
|
||||
*tree)
|
||||
{
|
||||
if (!tree)
|
||||
return NULL;
|
||||
if (tree->flags & POLICY_FLAG_ANY_POLICY)
|
||||
return tree->auth_policies;
|
||||
else
|
||||
return tree->user_policies;
|
||||
}
|
||||
|
||||
/* X509_POLICY_LEVEL stuff */
|
||||
|
||||
int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
|
||||
{
|
||||
int n;
|
||||
if (!level)
|
||||
return 0;
|
||||
if (level->anyPolicy)
|
||||
n = 1;
|
||||
else
|
||||
n = 0;
|
||||
if (level->nodes)
|
||||
n += sk_X509_POLICY_NODE_num(level->nodes);
|
||||
return n;
|
||||
}
|
||||
{
|
||||
int n;
|
||||
if (!level)
|
||||
return 0;
|
||||
if (level->anyPolicy)
|
||||
n = 1;
|
||||
else
|
||||
n = 0;
|
||||
if (level->nodes)
|
||||
n += sk_X509_POLICY_NODE_num(level->nodes);
|
||||
return n;
|
||||
}
|
||||
|
||||
X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
|
||||
{
|
||||
if (!level)
|
||||
return NULL;
|
||||
if (level->anyPolicy)
|
||||
{
|
||||
if (i == 0)
|
||||
return level->anyPolicy;
|
||||
i--;
|
||||
}
|
||||
return sk_X509_POLICY_NODE_value(level->nodes, i);
|
||||
}
|
||||
{
|
||||
if (!level)
|
||||
return NULL;
|
||||
if (level->anyPolicy) {
|
||||
if (i == 0)
|
||||
return level->anyPolicy;
|
||||
i--;
|
||||
}
|
||||
return sk_X509_POLICY_NODE_value(level->nodes, i);
|
||||
}
|
||||
|
||||
/* X509_POLICY_NODE stuff */
|
||||
|
||||
const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
|
||||
{
|
||||
if (!node)
|
||||
return NULL;
|
||||
return node->data->valid_policy;
|
||||
}
|
||||
{
|
||||
if (!node)
|
||||
return NULL;
|
||||
return node->data->valid_policy;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int X509_policy_node_get_critical(const X509_POLICY_NODE *node)
|
||||
{
|
||||
if (node_critical(node))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
if (node_critical(node))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
STACK_OF(POLICYQUALINFO) *
|
||||
X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
|
||||
{
|
||||
if (!node)
|
||||
return NULL;
|
||||
return node->data->qualifier_set;
|
||||
}
|
||||
|
||||
const X509_POLICY_NODE *
|
||||
X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
|
||||
{
|
||||
if (!node)
|
||||
return NULL;
|
||||
return node->parent;
|
||||
}
|
||||
|
||||
STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
|
||||
X509_POLICY_NODE
|
||||
*node)
|
||||
{
|
||||
if (!node)
|
||||
return NULL;
|
||||
return node->data->qualifier_set;
|
||||
}
|
||||
|
||||
const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
|
||||
*node)
|
||||
{
|
||||
if (!node)
|
||||
return NULL;
|
||||
return node->parent;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* pcy_map.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2004.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -62,71 +63,68 @@
|
||||
|
||||
#include "pcy_int.h"
|
||||
|
||||
/* Set policy mapping entries in cache.
|
||||
* Note: this modifies the passed POLICY_MAPPINGS structure
|
||||
/*
|
||||
* Set policy mapping entries in cache. Note: this modifies the passed
|
||||
* POLICY_MAPPINGS structure
|
||||
*/
|
||||
|
||||
int 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;
|
||||
}
|
||||
{
|
||||
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 = policy_cache_find_data(cache, map->issuerDomainPolicy);
|
||||
/* If we don't have anyPolicy can't map */
|
||||
if (!data && !cache->anyPolicy)
|
||||
continue;
|
||||
/* Attempt to find matching policy data */
|
||||
data = policy_cache_find_data(cache, map->issuerDomainPolicy);
|
||||
/* If we don't have anyPolicy can't map */
|
||||
if (!data && !cache->anyPolicy)
|
||||
continue;
|
||||
|
||||
/* Create a NODE from anyPolicy */
|
||||
if (!data)
|
||||
{
|
||||
data = policy_data_new(NULL, map->issuerDomainPolicy,
|
||||
cache->anyPolicy->flags
|
||||
& POLICY_DATA_FLAG_CRITICAL);
|
||||
if (!data)
|
||||
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))
|
||||
{
|
||||
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;
|
||||
/* Create a NODE from anyPolicy */
|
||||
if (!data) {
|
||||
data = policy_data_new(NULL, map->issuerDomainPolicy,
|
||||
cache->anyPolicy->flags
|
||||
& POLICY_DATA_FLAG_CRITICAL);
|
||||
if (!data)
|
||||
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)) {
|
||||
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:
|
||||
if (ret == -1)
|
||||
x->ex_flags |= EXFLAG_INVALID_POLICY;
|
||||
sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
|
||||
return ret;
|
||||
ret = 1;
|
||||
bad_mapping:
|
||||
if (ret == -1)
|
||||
x->ex_flags |= EXFLAG_INVALID_POLICY;
|
||||
sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
|
||||
return ret;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* pcy_node.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2004.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -62,136 +63,128 @@
|
||||
|
||||
#include "pcy_int.h"
|
||||
|
||||
static int node_cmp(const X509_POLICY_NODE * const *a,
|
||||
const X509_POLICY_NODE * const *b)
|
||||
{
|
||||
return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
|
||||
}
|
||||
static int node_cmp(const X509_POLICY_NODE *const *a,
|
||||
const X509_POLICY_NODE *const *b)
|
||||
{
|
||||
return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
|
||||
}
|
||||
|
||||
STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
|
||||
{
|
||||
return sk_X509_POLICY_NODE_new(node_cmp);
|
||||
}
|
||||
{
|
||||
return sk_X509_POLICY_NODE_new(node_cmp);
|
||||
}
|
||||
|
||||
X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
|
||||
const ASN1_OBJECT *id)
|
||||
{
|
||||
X509_POLICY_DATA n;
|
||||
X509_POLICY_NODE l;
|
||||
int idx;
|
||||
const ASN1_OBJECT *id)
|
||||
{
|
||||
X509_POLICY_DATA n;
|
||||
X509_POLICY_NODE l;
|
||||
int idx;
|
||||
|
||||
n.valid_policy = (ASN1_OBJECT *)id;
|
||||
l.data = &n;
|
||||
n.valid_policy = (ASN1_OBJECT *)id;
|
||||
l.data = &n;
|
||||
|
||||
idx = sk_X509_POLICY_NODE_find(nodes, &l);
|
||||
if (idx == -1)
|
||||
return NULL;
|
||||
idx = sk_X509_POLICY_NODE_find(nodes, &l);
|
||||
if (idx == -1)
|
||||
return NULL;
|
||||
|
||||
return sk_X509_POLICY_NODE_value(nodes, idx);
|
||||
return sk_X509_POLICY_NODE_value(nodes, idx);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
|
||||
const X509_POLICY_NODE *parent,
|
||||
const ASN1_OBJECT *id)
|
||||
{
|
||||
X509_POLICY_NODE *node;
|
||||
int i;
|
||||
for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
|
||||
{
|
||||
node = sk_X509_POLICY_NODE_value(level->nodes, i);
|
||||
if (node->parent == parent)
|
||||
{
|
||||
if (!OBJ_cmp(node->data->valid_policy, id))
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
const X509_POLICY_NODE *parent,
|
||||
const ASN1_OBJECT *id)
|
||||
{
|
||||
X509_POLICY_NODE *node;
|
||||
int i;
|
||||
for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
|
||||
node = sk_X509_POLICY_NODE_value(level->nodes, i);
|
||||
if (node->parent == parent) {
|
||||
if (!OBJ_cmp(node->data->valid_policy, id))
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
|
||||
const X509_POLICY_DATA *data,
|
||||
X509_POLICY_NODE *parent,
|
||||
X509_POLICY_TREE *tree)
|
||||
{
|
||||
X509_POLICY_NODE *node;
|
||||
node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
|
||||
if (!node)
|
||||
return NULL;
|
||||
node->data = data;
|
||||
node->parent = parent;
|
||||
node->nchild = 0;
|
||||
if (level)
|
||||
{
|
||||
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
|
||||
{
|
||||
if (level->anyPolicy)
|
||||
goto node_error;
|
||||
level->anyPolicy = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
const X509_POLICY_DATA *data,
|
||||
X509_POLICY_NODE *parent,
|
||||
X509_POLICY_TREE *tree)
|
||||
{
|
||||
X509_POLICY_NODE *node;
|
||||
node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
|
||||
if (!node)
|
||||
return NULL;
|
||||
node->data = data;
|
||||
node->parent = parent;
|
||||
node->nchild = 0;
|
||||
if (level) {
|
||||
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
|
||||
if (level->anyPolicy)
|
||||
goto node_error;
|
||||
level->anyPolicy = node;
|
||||
} else {
|
||||
|
||||
if (!level->nodes)
|
||||
level->nodes = policy_node_cmp_new();
|
||||
if (!level->nodes)
|
||||
goto node_error;
|
||||
if (!sk_X509_POLICY_NODE_push(level->nodes, node))
|
||||
goto node_error;
|
||||
}
|
||||
}
|
||||
if (!level->nodes)
|
||||
level->nodes = policy_node_cmp_new();
|
||||
if (!level->nodes)
|
||||
goto node_error;
|
||||
if (!sk_X509_POLICY_NODE_push(level->nodes, node))
|
||||
goto node_error;
|
||||
}
|
||||
}
|
||||
|
||||
if (tree)
|
||||
{
|
||||
if (!tree->extra_data)
|
||||
tree->extra_data = sk_X509_POLICY_DATA_new_null();
|
||||
if (!tree->extra_data)
|
||||
goto node_error;
|
||||
if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
|
||||
goto node_error;
|
||||
}
|
||||
if (tree) {
|
||||
if (!tree->extra_data)
|
||||
tree->extra_data = sk_X509_POLICY_DATA_new_null();
|
||||
if (!tree->extra_data)
|
||||
goto node_error;
|
||||
if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
|
||||
goto node_error;
|
||||
}
|
||||
|
||||
if (parent)
|
||||
parent->nchild++;
|
||||
if (parent)
|
||||
parent->nchild++;
|
||||
|
||||
return node;
|
||||
return node;
|
||||
|
||||
node_error:
|
||||
policy_node_free(node);
|
||||
return 0;
|
||||
node_error:
|
||||
policy_node_free(node);
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void policy_node_free(X509_POLICY_NODE *node)
|
||||
{
|
||||
OPENSSL_free(node);
|
||||
}
|
||||
{
|
||||
OPENSSL_free(node);
|
||||
}
|
||||
|
||||
/* See if a policy node matches a policy OID. If mapping enabled look through
|
||||
/*
|
||||
* See if a policy node matches a policy OID. If mapping enabled look through
|
||||
* expected policy set otherwise just valid policy.
|
||||
*/
|
||||
|
||||
int policy_node_match(const X509_POLICY_LEVEL *lvl,
|
||||
const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
|
||||
{
|
||||
int i;
|
||||
ASN1_OBJECT *policy_oid;
|
||||
const X509_POLICY_DATA *x = node->data;
|
||||
const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
|
||||
{
|
||||
int i;
|
||||
ASN1_OBJECT *policy_oid;
|
||||
const X509_POLICY_DATA *x = node->data;
|
||||
|
||||
if ( (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
|
||||
|| !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
|
||||
{
|
||||
if (!OBJ_cmp(x->valid_policy, oid))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP)
|
||||
|| !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) {
|
||||
if (!OBJ_cmp(x->valid_policy, oid))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
|
||||
{
|
||||
policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
|
||||
if (!OBJ_cmp(policy_oid, oid))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) {
|
||||
policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
|
||||
if (!OBJ_cmp(policy_oid, oid))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* tabtest.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,8 +57,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* Simple program to check the ext_dat.h is correct and print out
|
||||
* problems if it is not.
|
||||
/*
|
||||
* Simple program to check the ext_dat.h is correct and print out problems if
|
||||
* it is not.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -68,21 +70,23 @@
|
||||
|
||||
main()
|
||||
{
|
||||
int i, prev = -1, bad = 0;
|
||||
X509V3_EXT_METHOD **tmp;
|
||||
i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
|
||||
if(i != STANDARD_EXTENSION_COUNT)
|
||||
fprintf(stderr, "Extension number invalid expecting %d\n", i);
|
||||
tmp = standard_exts;
|
||||
for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
|
||||
if((*tmp)->ext_nid < prev) bad = 1;
|
||||
prev = (*tmp)->ext_nid;
|
||||
|
||||
}
|
||||
if(bad) {
|
||||
tmp = standard_exts;
|
||||
fprintf(stderr, "Extensions out of order!\n");
|
||||
for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
|
||||
printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
|
||||
} else fprintf(stderr, "Order OK\n");
|
||||
int i, prev = -1, bad = 0;
|
||||
X509V3_EXT_METHOD **tmp;
|
||||
i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
|
||||
if (i != STANDARD_EXTENSION_COUNT)
|
||||
fprintf(stderr, "Extension number invalid expecting %d\n", i);
|
||||
tmp = standard_exts;
|
||||
for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
|
||||
if ((*tmp)->ext_nid < prev)
|
||||
bad = 1;
|
||||
prev = (*tmp)->ext_nid;
|
||||
|
||||
}
|
||||
if (bad) {
|
||||
tmp = standard_exts;
|
||||
fprintf(stderr, "Extensions out of order!\n");
|
||||
for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
|
||||
printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
|
||||
} else
|
||||
fprintf(stderr, "Order OK\n");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_akey.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -64,43 +65,47 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
|
||||
AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist);
|
||||
AUTHORITY_KEYID *akeyid,
|
||||
STACK_OF(CONF_VALUE)
|
||||
*extlist);
|
||||
static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values);
|
||||
|
||||
const X509V3_EXT_METHOD v3_akey_id =
|
||||
{
|
||||
NID_authority_key_identifier,
|
||||
X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
(X509V3_EXT_I2V)i2v_AUTHORITY_KEYID,
|
||||
(X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
|
||||
0,0,
|
||||
NULL
|
||||
};
|
||||
const X509V3_EXT_METHOD v3_akey_id = {
|
||||
NID_authority_key_identifier,
|
||||
X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
(X509V3_EXT_I2V) i2v_AUTHORITY_KEYID,
|
||||
(X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
|
||||
0, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
|
||||
AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist)
|
||||
AUTHORITY_KEYID *akeyid,
|
||||
STACK_OF(CONF_VALUE)
|
||||
*extlist)
|
||||
{
|
||||
char *tmp;
|
||||
if(akeyid->keyid) {
|
||||
tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
|
||||
X509V3_add_value("keyid", tmp, &extlist);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
if(akeyid->issuer)
|
||||
extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
|
||||
if(akeyid->serial) {
|
||||
tmp = hex_to_string(akeyid->serial->data,
|
||||
akeyid->serial->length);
|
||||
X509V3_add_value("serial", tmp, &extlist);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
return extlist;
|
||||
char *tmp;
|
||||
if (akeyid->keyid) {
|
||||
tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
|
||||
X509V3_add_value("keyid", tmp, &extlist);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
if (akeyid->issuer)
|
||||
extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
|
||||
if (akeyid->serial) {
|
||||
tmp = hex_to_string(akeyid->serial->data, akeyid->serial->length);
|
||||
X509V3_add_value("serial", tmp, &extlist);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
return extlist;
|
||||
}
|
||||
|
||||
/* Currently two options:
|
||||
/*-
|
||||
* Currently two options:
|
||||
* keyid: use the issuers subject keyid, the value 'always' means its is
|
||||
* an error if the issuer certificate doesn't have a key id.
|
||||
* issuer: use the issuers cert issuer and serial number. The default is
|
||||
@@ -109,100 +114,92 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
|
||||
*/
|
||||
|
||||
static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
|
||||
{
|
||||
char keyid=0, issuer=0;
|
||||
int i;
|
||||
CONF_VALUE *cnf;
|
||||
ASN1_OCTET_STRING *ikeyid = NULL;
|
||||
X509_NAME *isname = NULL;
|
||||
GENERAL_NAMES * gens = NULL;
|
||||
GENERAL_NAME *gen = NULL;
|
||||
ASN1_INTEGER *serial = NULL;
|
||||
X509_EXTENSION *ext;
|
||||
X509 *cert;
|
||||
AUTHORITY_KEYID *akeyid;
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values)
|
||||
{
|
||||
char keyid = 0, issuer = 0;
|
||||
int i;
|
||||
CONF_VALUE *cnf;
|
||||
ASN1_OCTET_STRING *ikeyid = NULL;
|
||||
X509_NAME *isname = NULL;
|
||||
GENERAL_NAMES *gens = NULL;
|
||||
GENERAL_NAME *gen = NULL;
|
||||
ASN1_INTEGER *serial = NULL;
|
||||
X509_EXTENSION *ext;
|
||||
X509 *cert;
|
||||
AUTHORITY_KEYID *akeyid;
|
||||
|
||||
for(i = 0; i < sk_CONF_VALUE_num(values); i++)
|
||||
{
|
||||
cnf = sk_CONF_VALUE_value(values, i);
|
||||
if(!strcmp(cnf->name, "keyid"))
|
||||
{
|
||||
keyid = 1;
|
||||
if(cnf->value && !strcmp(cnf->value, "always"))
|
||||
keyid = 2;
|
||||
}
|
||||
else if(!strcmp(cnf->name, "issuer"))
|
||||
{
|
||||
issuer = 1;
|
||||
if(cnf->value && !strcmp(cnf->value, "always"))
|
||||
issuer = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNKNOWN_OPTION);
|
||||
ERR_add_error_data(2, "name=", cnf->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
|
||||
cnf = sk_CONF_VALUE_value(values, i);
|
||||
if (!strcmp(cnf->name, "keyid")) {
|
||||
keyid = 1;
|
||||
if (cnf->value && !strcmp(cnf->value, "always"))
|
||||
keyid = 2;
|
||||
} else if (!strcmp(cnf->name, "issuer")) {
|
||||
issuer = 1;
|
||||
if (cnf->value && !strcmp(cnf->value, "always"))
|
||||
issuer = 2;
|
||||
} else {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION);
|
||||
ERR_add_error_data(2, "name=", cnf->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ctx || !ctx->issuer_cert)
|
||||
{
|
||||
if(ctx && (ctx->flags==CTX_TEST))
|
||||
return AUTHORITY_KEYID_new();
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_NO_ISSUER_CERTIFICATE);
|
||||
return NULL;
|
||||
}
|
||||
if (!ctx || !ctx->issuer_cert) {
|
||||
if (ctx && (ctx->flags == CTX_TEST))
|
||||
return AUTHORITY_KEYID_new();
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,
|
||||
X509V3_R_NO_ISSUER_CERTIFICATE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cert = ctx->issuer_cert;
|
||||
cert = ctx->issuer_cert;
|
||||
|
||||
if(keyid)
|
||||
{
|
||||
i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
|
||||
if((i >= 0) && (ext = X509_get_ext(cert, i)))
|
||||
ikeyid = X509V3_EXT_d2i(ext);
|
||||
if(keyid==2 && !ikeyid)
|
||||
{
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (keyid) {
|
||||
i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
|
||||
if ((i >= 0) && (ext = X509_get_ext(cert, i)))
|
||||
ikeyid = X509V3_EXT_d2i(ext);
|
||||
if (keyid == 2 && !ikeyid) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,
|
||||
X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if((issuer && !ikeyid) || (issuer == 2))
|
||||
{
|
||||
isname = X509_NAME_dup(X509_get_issuer_name(cert));
|
||||
serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
|
||||
if(!isname || !serial)
|
||||
{
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if ((issuer && !ikeyid) || (issuer == 2)) {
|
||||
isname = X509_NAME_dup(X509_get_issuer_name(cert));
|
||||
serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
|
||||
if (!isname || !serial) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,
|
||||
X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(akeyid = AUTHORITY_KEYID_new())) goto err;
|
||||
if (!(akeyid = AUTHORITY_KEYID_new()))
|
||||
goto err;
|
||||
|
||||
if(isname)
|
||||
{
|
||||
if(!(gens = sk_GENERAL_NAME_new_null())
|
||||
|| !(gen = GENERAL_NAME_new())
|
||||
|| !sk_GENERAL_NAME_push(gens, gen))
|
||||
{
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
gen->type = GEN_DIRNAME;
|
||||
gen->d.dirn = isname;
|
||||
}
|
||||
if (isname) {
|
||||
if (!(gens = sk_GENERAL_NAME_new_null())
|
||||
|| !(gen = GENERAL_NAME_new())
|
||||
|| !sk_GENERAL_NAME_push(gens, gen)) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
gen->type = GEN_DIRNAME;
|
||||
gen->d.dirn = isname;
|
||||
}
|
||||
|
||||
akeyid->issuer = gens;
|
||||
akeyid->serial = serial;
|
||||
akeyid->keyid = ikeyid;
|
||||
akeyid->issuer = gens;
|
||||
akeyid->serial = serial;
|
||||
akeyid->keyid = ikeyid;
|
||||
|
||||
return akeyid;
|
||||
return akeyid;
|
||||
|
||||
err:
|
||||
X509_NAME_free(isname);
|
||||
M_ASN1_INTEGER_free(serial);
|
||||
M_ASN1_OCTET_STRING_free(ikeyid);
|
||||
return NULL;
|
||||
}
|
||||
X509_NAME_free(isname);
|
||||
M_ASN1_INTEGER_free(serial);
|
||||
M_ASN1_OCTET_STRING_free(ikeyid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_akey_asn1.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -64,9 +65,9 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
ASN1_SEQUENCE(AUTHORITY_KEYID) = {
|
||||
ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
|
||||
ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
|
||||
ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
|
||||
ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
|
||||
ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
|
||||
ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
|
||||
} ASN1_SEQUENCE_END(AUTHORITY_KEYID)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID)
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_bcons.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1.h>
|
||||
@@ -64,61 +64,69 @@
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist);
|
||||
static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
|
||||
static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
|
||||
BASIC_CONSTRAINTS *bcons,
|
||||
STACK_OF(CONF_VALUE)
|
||||
*extlist);
|
||||
static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values);
|
||||
|
||||
const X509V3_EXT_METHOD v3_bcons = {
|
||||
NID_basic_constraints, 0,
|
||||
ASN1_ITEM_ref(BASIC_CONSTRAINTS),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
(X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS,
|
||||
(X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
|
||||
NULL,NULL,
|
||||
NULL
|
||||
NID_basic_constraints, 0,
|
||||
ASN1_ITEM_ref(BASIC_CONSTRAINTS),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
(X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS,
|
||||
(X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
|
||||
NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
ASN1_SEQUENCE(BASIC_CONSTRAINTS) = {
|
||||
ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
|
||||
ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
|
||||
ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
|
||||
ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
|
||||
} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
|
||||
|
||||
|
||||
static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
|
||||
BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist)
|
||||
BASIC_CONSTRAINTS *bcons,
|
||||
STACK_OF(CONF_VALUE)
|
||||
*extlist)
|
||||
{
|
||||
X509V3_add_value_bool("CA", bcons->ca, &extlist);
|
||||
X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
|
||||
return extlist;
|
||||
X509V3_add_value_bool("CA", bcons->ca, &extlist);
|
||||
X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
|
||||
return extlist;
|
||||
}
|
||||
|
||||
static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values)
|
||||
{
|
||||
BASIC_CONSTRAINTS *bcons=NULL;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
if(!(bcons = BASIC_CONSTRAINTS_new())) {
|
||||
X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
|
||||
val = sk_CONF_VALUE_value(values, i);
|
||||
if(!strcmp(val->name, "CA")) {
|
||||
if(!X509V3_get_value_bool(val, &bcons->ca)) goto err;
|
||||
} else if(!strcmp(val->name, "pathlen")) {
|
||||
if(!X509V3_get_value_int(val, &bcons->pathlen)) goto err;
|
||||
} else {
|
||||
X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return bcons;
|
||||
err:
|
||||
BASIC_CONSTRAINTS_free(bcons);
|
||||
return NULL;
|
||||
BASIC_CONSTRAINTS *bcons = NULL;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
if (!(bcons = BASIC_CONSTRAINTS_new())) {
|
||||
X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
|
||||
val = sk_CONF_VALUE_value(values, i);
|
||||
if (!strcmp(val->name, "CA")) {
|
||||
if (!X509V3_get_value_bool(val, &bcons->ca))
|
||||
goto err;
|
||||
} else if (!strcmp(val->name, "pathlen")) {
|
||||
if (!X509V3_get_value_int(val, &bcons->pathlen))
|
||||
goto err;
|
||||
} else {
|
||||
X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return bcons;
|
||||
err:
|
||||
BASIC_CONSTRAINTS_free(bcons);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_bitst.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -62,80 +63,80 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static BIT_STRING_BITNAME ns_cert_type_table[] = {
|
||||
{0, "SSL Client", "client"},
|
||||
{1, "SSL Server", "server"},
|
||||
{2, "S/MIME", "email"},
|
||||
{3, "Object Signing", "objsign"},
|
||||
{4, "Unused", "reserved"},
|
||||
{5, "SSL CA", "sslCA"},
|
||||
{6, "S/MIME CA", "emailCA"},
|
||||
{7, "Object Signing CA", "objCA"},
|
||||
{-1, NULL, NULL}
|
||||
{0, "SSL Client", "client"},
|
||||
{1, "SSL Server", "server"},
|
||||
{2, "S/MIME", "email"},
|
||||
{3, "Object Signing", "objsign"},
|
||||
{4, "Unused", "reserved"},
|
||||
{5, "SSL CA", "sslCA"},
|
||||
{6, "S/MIME CA", "emailCA"},
|
||||
{7, "Object Signing CA", "objCA"},
|
||||
{-1, NULL, NULL}
|
||||
};
|
||||
|
||||
static BIT_STRING_BITNAME key_usage_type_table[] = {
|
||||
{0, "Digital Signature", "digitalSignature"},
|
||||
{1, "Non Repudiation", "nonRepudiation"},
|
||||
{2, "Key Encipherment", "keyEncipherment"},
|
||||
{3, "Data Encipherment", "dataEncipherment"},
|
||||
{4, "Key Agreement", "keyAgreement"},
|
||||
{5, "Certificate Sign", "keyCertSign"},
|
||||
{6, "CRL Sign", "cRLSign"},
|
||||
{7, "Encipher Only", "encipherOnly"},
|
||||
{8, "Decipher Only", "decipherOnly"},
|
||||
{-1, NULL, NULL}
|
||||
{0, "Digital Signature", "digitalSignature"},
|
||||
{1, "Non Repudiation", "nonRepudiation"},
|
||||
{2, "Key Encipherment", "keyEncipherment"},
|
||||
{3, "Data Encipherment", "dataEncipherment"},
|
||||
{4, "Key Agreement", "keyAgreement"},
|
||||
{5, "Certificate Sign", "keyCertSign"},
|
||||
{6, "CRL Sign", "cRLSign"},
|
||||
{7, "Encipher Only", "encipherOnly"},
|
||||
{8, "Decipher Only", "decipherOnly"},
|
||||
{-1, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const X509V3_EXT_METHOD v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
|
||||
const X509V3_EXT_METHOD v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table);
|
||||
const X509V3_EXT_METHOD v3_nscert =
|
||||
EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
|
||||
const X509V3_EXT_METHOD v3_key_usage =
|
||||
EXT_BITSTRING(NID_key_usage, key_usage_type_table);
|
||||
|
||||
STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
|
||||
ASN1_BIT_STRING *bits, STACK_OF(CONF_VALUE) *ret)
|
||||
ASN1_BIT_STRING *bits,
|
||||
STACK_OF(CONF_VALUE) *ret)
|
||||
{
|
||||
BIT_STRING_BITNAME *bnam;
|
||||
for(bnam =method->usr_data; bnam->lname; bnam++) {
|
||||
if(ASN1_BIT_STRING_get_bit(bits, bnam->bitnum))
|
||||
X509V3_add_value(bnam->lname, NULL, &ret);
|
||||
}
|
||||
return ret;
|
||||
BIT_STRING_BITNAME *bnam;
|
||||
for (bnam = method->usr_data; bnam->lname; bnam++) {
|
||||
if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum))
|
||||
X509V3_add_value(bnam->lname, NULL, &ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
CONF_VALUE *val;
|
||||
ASN1_BIT_STRING *bs;
|
||||
int i;
|
||||
BIT_STRING_BITNAME *bnam;
|
||||
if(!(bs = M_ASN1_BIT_STRING_new())) {
|
||||
X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
for(bnam = method->usr_data; bnam->lname; bnam++) {
|
||||
if(!strcmp(bnam->sname, val->name) ||
|
||||
!strcmp(bnam->lname, val->name) ) {
|
||||
if(!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
|
||||
X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
M_ASN1_BIT_STRING_free(bs);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!bnam->lname) {
|
||||
X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
|
||||
X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
|
||||
X509V3_conf_err(val);
|
||||
M_ASN1_BIT_STRING_free(bs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
|
||||
|
||||
ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
CONF_VALUE *val;
|
||||
ASN1_BIT_STRING *bs;
|
||||
int i;
|
||||
BIT_STRING_BITNAME *bnam;
|
||||
if (!(bs = M_ASN1_BIT_STRING_new())) {
|
||||
X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
for (bnam = method->usr_data; bnam->lname; bnam++) {
|
||||
if (!strcmp(bnam->sname, val->name) ||
|
||||
!strcmp(bnam->lname, val->name)) {
|
||||
if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
|
||||
X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
M_ASN1_BIT_STRING_free(bs);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bnam->lname) {
|
||||
X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
|
||||
X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
|
||||
X509V3_conf_err(val);
|
||||
M_ASN1_BIT_STRING_free(bs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_conf.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -57,8 +58,6 @@
|
||||
*/
|
||||
/* extension creation utilities */
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "cryptlib.h"
|
||||
@@ -68,458 +67,466 @@
|
||||
|
||||
static int v3_check_critical(char **value);
|
||||
static int v3_check_generic(char **value);
|
||||
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value);
|
||||
static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
|
||||
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
|
||||
int crit, char *value);
|
||||
static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
|
||||
int crit, int type,
|
||||
X509V3_CTX *ctx);
|
||||
static char *conf_lhash_get_string(void *db, char *section, char *value);
|
||||
static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section);
|
||||
static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
|
||||
int crit, void *ext_struc);
|
||||
static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
|
||||
static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
|
||||
int ext_nid, int crit, void *ext_struc);
|
||||
static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx,
|
||||
long *ext_len);
|
||||
/* CONF *conf: Config file */
|
||||
/* char *name: Name */
|
||||
/* char *value: Value */
|
||||
X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
|
||||
char *value)
|
||||
{
|
||||
int crit;
|
||||
int ext_type;
|
||||
X509_EXTENSION *ret;
|
||||
crit = v3_check_critical(&value);
|
||||
if ((ext_type = v3_check_generic(&value)))
|
||||
return v3_generic_extension(name, value, crit, ext_type, ctx);
|
||||
ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
|
||||
if (!ret)
|
||||
{
|
||||
X509V3err(X509V3_F_X509V3_EXT_NCONF,X509V3_R_ERROR_IN_EXTENSION);
|
||||
ERR_add_error_data(4,"name=", name, ", value=", value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
char *value)
|
||||
{
|
||||
int crit;
|
||||
int ext_type;
|
||||
X509_EXTENSION *ret;
|
||||
crit = v3_check_critical(&value);
|
||||
if ((ext_type = v3_check_generic(&value)))
|
||||
return v3_generic_extension(name, value, crit, ext_type, ctx);
|
||||
ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
|
||||
if (!ret) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_NCONF, X509V3_R_ERROR_IN_EXTENSION);
|
||||
ERR_add_error_data(4, "name=", name, ", value=", value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* CONF *conf: Config file */
|
||||
/* char *value: Value */
|
||||
X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
|
||||
char *value)
|
||||
{
|
||||
int crit;
|
||||
int ext_type;
|
||||
crit = v3_check_critical(&value);
|
||||
if ((ext_type = v3_check_generic(&value)))
|
||||
return v3_generic_extension(OBJ_nid2sn(ext_nid),
|
||||
value, crit, ext_type, ctx);
|
||||
return do_ext_nconf(conf, ctx, ext_nid, crit, value);
|
||||
}
|
||||
char *value)
|
||||
{
|
||||
int crit;
|
||||
int ext_type;
|
||||
crit = v3_check_critical(&value);
|
||||
if ((ext_type = v3_check_generic(&value)))
|
||||
return v3_generic_extension(OBJ_nid2sn(ext_nid),
|
||||
value, crit, ext_type, ctx);
|
||||
return do_ext_nconf(conf, ctx, ext_nid, crit, value);
|
||||
}
|
||||
|
||||
/* CONF *conf: Config file */
|
||||
/* char *value: Value */
|
||||
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
|
||||
int crit, char *value)
|
||||
{
|
||||
const X509V3_EXT_METHOD *method;
|
||||
X509_EXTENSION *ext;
|
||||
STACK_OF(CONF_VALUE) *nval;
|
||||
void *ext_struc;
|
||||
if (ext_nid == NID_undef)
|
||||
{
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION_NAME);
|
||||
return NULL;
|
||||
}
|
||||
if (!(method = X509V3_EXT_get_nid(ext_nid)))
|
||||
{
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION);
|
||||
return NULL;
|
||||
}
|
||||
/* Now get internal extension representation based on type */
|
||||
if (method->v2i)
|
||||
{
|
||||
if(*value == '@') nval = NCONF_get_section(conf, value + 1);
|
||||
else nval = X509V3_parse_list(value);
|
||||
if(sk_CONF_VALUE_num(nval) <= 0)
|
||||
{
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_INVALID_EXTENSION_STRING);
|
||||
ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
|
||||
return NULL;
|
||||
}
|
||||
ext_struc = method->v2i(method, ctx, nval);
|
||||
if(*value != '@') sk_CONF_VALUE_pop_free(nval,
|
||||
X509V3_conf_free);
|
||||
if(!ext_struc) return NULL;
|
||||
}
|
||||
else if(method->s2i)
|
||||
{
|
||||
if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;
|
||||
}
|
||||
else if(method->r2i)
|
||||
{
|
||||
if(!ctx->db || !ctx->db_meth)
|
||||
{
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_NO_CONFIG_DATABASE);
|
||||
return NULL;
|
||||
}
|
||||
if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
|
||||
ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
|
||||
return NULL;
|
||||
}
|
||||
int crit, char *value)
|
||||
{
|
||||
const X509V3_EXT_METHOD *method;
|
||||
X509_EXTENSION *ext;
|
||||
STACK_OF(CONF_VALUE) *nval;
|
||||
void *ext_struc;
|
||||
if (ext_nid == NID_undef) {
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION_NAME);
|
||||
return NULL;
|
||||
}
|
||||
if (!(method = X509V3_EXT_get_nid(ext_nid))) {
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION);
|
||||
return NULL;
|
||||
}
|
||||
/* Now get internal extension representation based on type */
|
||||
if (method->v2i) {
|
||||
if (*value == '@')
|
||||
nval = NCONF_get_section(conf, value + 1);
|
||||
else
|
||||
nval = X509V3_parse_list(value);
|
||||
if (sk_CONF_VALUE_num(nval) <= 0) {
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF,
|
||||
X509V3_R_INVALID_EXTENSION_STRING);
|
||||
ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=",
|
||||
value);
|
||||
return NULL;
|
||||
}
|
||||
ext_struc = method->v2i(method, ctx, nval);
|
||||
if (*value != '@')
|
||||
sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
|
||||
if (!ext_struc)
|
||||
return NULL;
|
||||
} else if (method->s2i) {
|
||||
if (!(ext_struc = method->s2i(method, ctx, value)))
|
||||
return NULL;
|
||||
} else if (method->r2i) {
|
||||
if (!ctx->db || !ctx->db_meth) {
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_NO_CONFIG_DATABASE);
|
||||
return NULL;
|
||||
}
|
||||
if (!(ext_struc = method->r2i(method, ctx, value)))
|
||||
return NULL;
|
||||
} else {
|
||||
X509V3err(X509V3_F_DO_EXT_NCONF,
|
||||
X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
|
||||
ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
|
||||
if(method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
|
||||
else method->ext_free(ext_struc);
|
||||
return ext;
|
||||
ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
|
||||
if (method->it)
|
||||
ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
|
||||
else
|
||||
method->ext_free(ext_struc);
|
||||
return ext;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
|
||||
int crit, void *ext_struc)
|
||||
{
|
||||
unsigned char *ext_der;
|
||||
int ext_len;
|
||||
ASN1_OCTET_STRING *ext_oct;
|
||||
X509_EXTENSION *ext;
|
||||
/* Convert internal representation to DER */
|
||||
if (method->it)
|
||||
{
|
||||
ext_der = NULL;
|
||||
ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
|
||||
if (ext_len < 0) goto merr;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char *p;
|
||||
ext_len = method->i2d(ext_struc, NULL);
|
||||
if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
|
||||
p = ext_der;
|
||||
method->i2d(ext_struc, &p);
|
||||
}
|
||||
if (!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
|
||||
ext_oct->data = ext_der;
|
||||
ext_oct->length = ext_len;
|
||||
static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
|
||||
int ext_nid, int crit, void *ext_struc)
|
||||
{
|
||||
unsigned char *ext_der;
|
||||
int ext_len;
|
||||
ASN1_OCTET_STRING *ext_oct;
|
||||
X509_EXTENSION *ext;
|
||||
/* Convert internal representation to DER */
|
||||
if (method->it) {
|
||||
ext_der = NULL;
|
||||
ext_len =
|
||||
ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
|
||||
if (ext_len < 0)
|
||||
goto merr;
|
||||
} else {
|
||||
unsigned char *p;
|
||||
ext_len = method->i2d(ext_struc, NULL);
|
||||
if (!(ext_der = OPENSSL_malloc(ext_len)))
|
||||
goto merr;
|
||||
p = ext_der;
|
||||
method->i2d(ext_struc, &p);
|
||||
}
|
||||
if (!(ext_oct = M_ASN1_OCTET_STRING_new()))
|
||||
goto merr;
|
||||
ext_oct->data = ext_der;
|
||||
ext_oct->length = ext_len;
|
||||
|
||||
ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
|
||||
if (!ext) goto merr;
|
||||
M_ASN1_OCTET_STRING_free(ext_oct);
|
||||
ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
|
||||
if (!ext)
|
||||
goto merr;
|
||||
M_ASN1_OCTET_STRING_free(ext_oct);
|
||||
|
||||
return ext;
|
||||
return ext;
|
||||
|
||||
merr:
|
||||
X509V3err(X509V3_F_DO_EXT_I2D,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
merr:
|
||||
X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Given an internal structure, nid and critical flag create an extension */
|
||||
|
||||
X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
|
||||
{
|
||||
const X509V3_EXT_METHOD *method;
|
||||
if (!(method = X509V3_EXT_get_nid(ext_nid))) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION);
|
||||
return NULL;
|
||||
}
|
||||
return do_ext_i2d(method, ext_nid, crit, ext_struc);
|
||||
{
|
||||
const X509V3_EXT_METHOD *method;
|
||||
if (!(method = X509V3_EXT_get_nid(ext_nid))) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_I2D, X509V3_R_UNKNOWN_EXTENSION);
|
||||
return NULL;
|
||||
}
|
||||
return do_ext_i2d(method, ext_nid, crit, ext_struc);
|
||||
}
|
||||
|
||||
/* Check the extension string for critical flag */
|
||||
static int v3_check_critical(char **value)
|
||||
{
|
||||
char *p = *value;
|
||||
if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0;
|
||||
p+=9;
|
||||
while(isspace((unsigned char)*p)) p++;
|
||||
*value = p;
|
||||
return 1;
|
||||
char *p = *value;
|
||||
if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
|
||||
return 0;
|
||||
p += 9;
|
||||
while (isspace((unsigned char)*p))
|
||||
p++;
|
||||
*value = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check extension string for generic extension and return the type */
|
||||
static int v3_check_generic(char **value)
|
||||
{
|
||||
int gen_type = 0;
|
||||
char *p = *value;
|
||||
if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4))
|
||||
{
|
||||
p+=4;
|
||||
gen_type = 1;
|
||||
}
|
||||
else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5))
|
||||
{
|
||||
p+=5;
|
||||
gen_type = 2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
int gen_type = 0;
|
||||
char *p = *value;
|
||||
if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) {
|
||||
p += 4;
|
||||
gen_type = 1;
|
||||
} else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) {
|
||||
p += 5;
|
||||
gen_type = 2;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
*value = p;
|
||||
return gen_type;
|
||||
while (isspace((unsigned char)*p))
|
||||
p++;
|
||||
*value = p;
|
||||
return gen_type;
|
||||
}
|
||||
|
||||
/* Create a generic extension: for now just handle DER type */
|
||||
static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
|
||||
int crit, int gen_type,
|
||||
X509V3_CTX *ctx)
|
||||
{
|
||||
unsigned char *ext_der=NULL;
|
||||
long ext_len;
|
||||
ASN1_OBJECT *obj=NULL;
|
||||
ASN1_OCTET_STRING *oct=NULL;
|
||||
X509_EXTENSION *extension=NULL;
|
||||
if (!(obj = OBJ_txt2obj(ext, 0)))
|
||||
{
|
||||
X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_NAME_ERROR);
|
||||
ERR_add_error_data(2, "name=", ext);
|
||||
goto err;
|
||||
}
|
||||
int crit, int gen_type,
|
||||
X509V3_CTX *ctx)
|
||||
{
|
||||
unsigned char *ext_der = NULL;
|
||||
long ext_len;
|
||||
ASN1_OBJECT *obj = NULL;
|
||||
ASN1_OCTET_STRING *oct = NULL;
|
||||
X509_EXTENSION *extension = NULL;
|
||||
if (!(obj = OBJ_txt2obj(ext, 0))) {
|
||||
X509V3err(X509V3_F_V3_GENERIC_EXTENSION,
|
||||
X509V3_R_EXTENSION_NAME_ERROR);
|
||||
ERR_add_error_data(2, "name=", ext);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (gen_type == 1)
|
||||
ext_der = string_to_hex(value, &ext_len);
|
||||
else if (gen_type == 2)
|
||||
ext_der = generic_asn1(value, ctx, &ext_len);
|
||||
if (gen_type == 1)
|
||||
ext_der = string_to_hex(value, &ext_len);
|
||||
else if (gen_type == 2)
|
||||
ext_der = generic_asn1(value, ctx, &ext_len);
|
||||
|
||||
if (ext_der == NULL)
|
||||
{
|
||||
X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_VALUE_ERROR);
|
||||
ERR_add_error_data(2, "value=", value);
|
||||
goto err;
|
||||
}
|
||||
if (ext_der == NULL) {
|
||||
X509V3err(X509V3_F_V3_GENERIC_EXTENSION,
|
||||
X509V3_R_EXTENSION_VALUE_ERROR);
|
||||
ERR_add_error_data(2, "value=", value);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(oct = M_ASN1_OCTET_STRING_new()))
|
||||
{
|
||||
X509V3err(X509V3_F_V3_GENERIC_EXTENSION,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!(oct = M_ASN1_OCTET_STRING_new())) {
|
||||
X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
oct->data = ext_der;
|
||||
oct->length = ext_len;
|
||||
ext_der = NULL;
|
||||
oct->data = ext_der;
|
||||
oct->length = ext_len;
|
||||
ext_der = NULL;
|
||||
|
||||
extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
|
||||
extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
|
||||
|
||||
err:
|
||||
ASN1_OBJECT_free(obj);
|
||||
M_ASN1_OCTET_STRING_free(oct);
|
||||
if(ext_der) OPENSSL_free(ext_der);
|
||||
return extension;
|
||||
err:
|
||||
ASN1_OBJECT_free(obj);
|
||||
M_ASN1_OCTET_STRING_free(oct);
|
||||
if (ext_der)
|
||||
OPENSSL_free(ext_der);
|
||||
return extension;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len)
|
||||
{
|
||||
ASN1_TYPE *typ;
|
||||
unsigned char *ext_der = NULL;
|
||||
typ = ASN1_generate_v3(value, ctx);
|
||||
if (typ == NULL)
|
||||
return NULL;
|
||||
*ext_len = i2d_ASN1_TYPE(typ, &ext_der);
|
||||
ASN1_TYPE_free(typ);
|
||||
return ext_der;
|
||||
}
|
||||
static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx,
|
||||
long *ext_len)
|
||||
{
|
||||
ASN1_TYPE *typ;
|
||||
unsigned char *ext_der = NULL;
|
||||
typ = ASN1_generate_v3(value, ctx);
|
||||
if (typ == NULL)
|
||||
return NULL;
|
||||
*ext_len = i2d_ASN1_TYPE(typ, &ext_der);
|
||||
ASN1_TYPE_free(typ);
|
||||
return ext_der;
|
||||
}
|
||||
|
||||
/* This is the main function: add a bunch of extensions based on a config file
|
||||
* section to an extension STACK.
|
||||
/*
|
||||
* This is the main function: add a bunch of extensions based on a config
|
||||
* file section to an extension STACK.
|
||||
*/
|
||||
|
||||
|
||||
int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
|
||||
STACK_OF(X509_EXTENSION) **sk)
|
||||
{
|
||||
X509_EXTENSION *ext;
|
||||
STACK_OF(CONF_VALUE) *nval;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
if (!(nval = NCONF_get_section(conf, section))) return 0;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++)
|
||||
{
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
|
||||
return 0;
|
||||
if (sk) X509v3_add_ext(sk, ext, -1);
|
||||
X509_EXTENSION_free(ext);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
STACK_OF(X509_EXTENSION) **sk)
|
||||
{
|
||||
X509_EXTENSION *ext;
|
||||
STACK_OF(CONF_VALUE) *nval;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
if (!(nval = NCONF_get_section(conf, section)))
|
||||
return 0;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
|
||||
return 0;
|
||||
if (sk)
|
||||
X509v3_add_ext(sk, ext, -1);
|
||||
X509_EXTENSION_free(ext);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Convenience functions to add extensions to a certificate, CRL and request */
|
||||
/*
|
||||
* Convenience functions to add extensions to a certificate, CRL and request
|
||||
*/
|
||||
|
||||
int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
|
||||
X509 *cert)
|
||||
{
|
||||
STACK_OF(X509_EXTENSION) **sk = NULL;
|
||||
if (cert)
|
||||
sk = &cert->cert_info->extensions;
|
||||
return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
|
||||
}
|
||||
X509 *cert)
|
||||
{
|
||||
STACK_OF(X509_EXTENSION) **sk = NULL;
|
||||
if (cert)
|
||||
sk = &cert->cert_info->extensions;
|
||||
return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
|
||||
}
|
||||
|
||||
/* Same as above but for a CRL */
|
||||
|
||||
int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
|
||||
X509_CRL *crl)
|
||||
{
|
||||
STACK_OF(X509_EXTENSION) **sk = NULL;
|
||||
if (crl)
|
||||
sk = &crl->crl->extensions;
|
||||
return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
|
||||
}
|
||||
X509_CRL *crl)
|
||||
{
|
||||
STACK_OF(X509_EXTENSION) **sk = NULL;
|
||||
if (crl)
|
||||
sk = &crl->crl->extensions;
|
||||
return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
|
||||
}
|
||||
|
||||
/* Add extensions to certificate request */
|
||||
|
||||
int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
|
||||
X509_REQ *req)
|
||||
{
|
||||
STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
|
||||
int i;
|
||||
if (req)
|
||||
sk = &extlist;
|
||||
i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
|
||||
if (!i || !sk)
|
||||
return i;
|
||||
i = X509_REQ_add_extensions(req, extlist);
|
||||
sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
|
||||
return i;
|
||||
}
|
||||
X509_REQ *req)
|
||||
{
|
||||
STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
|
||||
int i;
|
||||
if (req)
|
||||
sk = &extlist;
|
||||
i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
|
||||
if (!i || !sk)
|
||||
return i;
|
||||
i = X509_REQ_add_extensions(req, extlist);
|
||||
sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Config database functions */
|
||||
|
||||
char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
|
||||
{
|
||||
if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
|
||||
{
|
||||
X509V3err(X509V3_F_X509V3_GET_STRING,X509V3_R_OPERATION_NOT_DEFINED);
|
||||
return NULL;
|
||||
}
|
||||
if (ctx->db_meth->get_string)
|
||||
return ctx->db_meth->get_string(ctx->db, name, section);
|
||||
return NULL;
|
||||
}
|
||||
char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
|
||||
{
|
||||
if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) {
|
||||
X509V3err(X509V3_F_X509V3_GET_STRING, X509V3_R_OPERATION_NOT_DEFINED);
|
||||
return NULL;
|
||||
}
|
||||
if (ctx->db_meth->get_string)
|
||||
return ctx->db_meth->get_string(ctx->db, name, section);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
|
||||
{
|
||||
if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
|
||||
{
|
||||
X509V3err(X509V3_F_X509V3_GET_SECTION,X509V3_R_OPERATION_NOT_DEFINED);
|
||||
return NULL;
|
||||
}
|
||||
if (ctx->db_meth->get_section)
|
||||
return ctx->db_meth->get_section(ctx->db, section);
|
||||
return NULL;
|
||||
}
|
||||
STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section)
|
||||
{
|
||||
if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) {
|
||||
X509V3err(X509V3_F_X509V3_GET_SECTION,
|
||||
X509V3_R_OPERATION_NOT_DEFINED);
|
||||
return NULL;
|
||||
}
|
||||
if (ctx->db_meth->get_section)
|
||||
return ctx->db_meth->get_section(ctx->db, section);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void X509V3_string_free(X509V3_CTX *ctx, char *str)
|
||||
{
|
||||
if (!str) return;
|
||||
if (ctx->db_meth->free_string)
|
||||
ctx->db_meth->free_string(ctx->db, str);
|
||||
}
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
if (ctx->db_meth->free_string)
|
||||
ctx->db_meth->free_string(ctx->db, str);
|
||||
}
|
||||
|
||||
void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
|
||||
{
|
||||
if (!section) return;
|
||||
if (ctx->db_meth->free_section)
|
||||
ctx->db_meth->free_section(ctx->db, section);
|
||||
}
|
||||
{
|
||||
if (!section)
|
||||
return;
|
||||
if (ctx->db_meth->free_section)
|
||||
ctx->db_meth->free_section(ctx->db, section);
|
||||
}
|
||||
|
||||
static char *nconf_get_string(void *db, char *section, char *value)
|
||||
{
|
||||
return NCONF_get_string(db, section, value);
|
||||
}
|
||||
{
|
||||
return NCONF_get_string(db, section, value);
|
||||
}
|
||||
|
||||
static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
|
||||
{
|
||||
return NCONF_get_section(db, section);
|
||||
}
|
||||
{
|
||||
return NCONF_get_section(db, section);
|
||||
}
|
||||
|
||||
static X509V3_CONF_METHOD nconf_method = {
|
||||
nconf_get_string,
|
||||
nconf_get_section,
|
||||
NULL,
|
||||
NULL
|
||||
nconf_get_string,
|
||||
nconf_get_section,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
|
||||
{
|
||||
ctx->db_meth = &nconf_method;
|
||||
ctx->db = conf;
|
||||
}
|
||||
{
|
||||
ctx->db_meth = &nconf_method;
|
||||
ctx->db = conf;
|
||||
}
|
||||
|
||||
void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
|
||||
X509_CRL *crl, int flags)
|
||||
{
|
||||
ctx->issuer_cert = issuer;
|
||||
ctx->subject_cert = subj;
|
||||
ctx->crl = crl;
|
||||
ctx->subject_req = req;
|
||||
ctx->flags = flags;
|
||||
}
|
||||
X509_CRL *crl, int flags)
|
||||
{
|
||||
ctx->issuer_cert = issuer;
|
||||
ctx->subject_cert = subj;
|
||||
ctx->crl = crl;
|
||||
ctx->subject_req = req;
|
||||
ctx->flags = flags;
|
||||
}
|
||||
|
||||
/* Old conf compatibility functions */
|
||||
|
||||
X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
|
||||
char *name, char *value)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_nconf(&ctmp, ctx, name, value);
|
||||
}
|
||||
char *name, char *value)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_nconf(&ctmp, ctx, name, value);
|
||||
}
|
||||
|
||||
/* LHASH *conf: Config file */
|
||||
/* char *value: Value */
|
||||
X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
|
||||
int ext_nid, char *value)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
|
||||
}
|
||||
X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
|
||||
X509V3_CTX *ctx, int ext_nid, char *value)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
|
||||
}
|
||||
|
||||
static char *conf_lhash_get_string(void *db, char *section, char *value)
|
||||
{
|
||||
return CONF_get_string(db, section, value);
|
||||
}
|
||||
{
|
||||
return CONF_get_string(db, section, value);
|
||||
}
|
||||
|
||||
static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section)
|
||||
{
|
||||
return CONF_get_section(db, section);
|
||||
}
|
||||
{
|
||||
return CONF_get_section(db, section);
|
||||
}
|
||||
|
||||
static X509V3_CONF_METHOD conf_lhash_method = {
|
||||
conf_lhash_get_string,
|
||||
conf_lhash_get_section,
|
||||
NULL,
|
||||
NULL
|
||||
conf_lhash_get_string,
|
||||
conf_lhash_get_section,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
|
||||
{
|
||||
ctx->db_meth = &conf_lhash_method;
|
||||
ctx->db = lhash;
|
||||
}
|
||||
{
|
||||
ctx->db_meth = &conf_lhash_method;
|
||||
ctx->db = lhash;
|
||||
}
|
||||
|
||||
int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
|
||||
char *section, X509 *cert)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
|
||||
}
|
||||
char *section, X509 *cert)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
|
||||
}
|
||||
|
||||
/* Same as above but for a CRL */
|
||||
|
||||
int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
|
||||
char *section, X509_CRL *crl)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
|
||||
}
|
||||
char *section, X509_CRL *crl)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
|
||||
}
|
||||
|
||||
/* Add extensions to certificate request */
|
||||
|
||||
int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
|
||||
char *section, X509_REQ *req)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
|
||||
}
|
||||
char *section, X509_REQ *req)
|
||||
{
|
||||
CONF ctmp;
|
||||
CONF_set_nconf(&ctmp, conf);
|
||||
return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_cpols.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -67,35 +68,38 @@
|
||||
|
||||
/* Certificate policies extension support: this one is a bit complex... */
|
||||
|
||||
static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, int indent);
|
||||
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value);
|
||||
static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent);
|
||||
static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
|
||||
BIO *out, int indent);
|
||||
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *value);
|
||||
static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
|
||||
int indent);
|
||||
static void print_notice(BIO *out, USERNOTICE *notice, int indent);
|
||||
static POLICYINFO *policy_section(X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *polstrs, int ia5org);
|
||||
STACK_OF(CONF_VALUE) *polstrs, int ia5org);
|
||||
static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *unot, int ia5org);
|
||||
STACK_OF(CONF_VALUE) *unot, int ia5org);
|
||||
static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
|
||||
|
||||
const X509V3_EXT_METHOD v3_cpols = {
|
||||
NID_certificate_policies, 0,ASN1_ITEM_ref(CERTIFICATEPOLICIES),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,0,
|
||||
(X509V3_EXT_I2R)i2r_certpol,
|
||||
(X509V3_EXT_R2I)r2i_certpol,
|
||||
NULL
|
||||
NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
(X509V3_EXT_I2R)i2r_certpol,
|
||||
(X509V3_EXT_R2I)r2i_certpol,
|
||||
NULL
|
||||
};
|
||||
|
||||
ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
|
||||
ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
|
||||
ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
|
||||
|
||||
ASN1_SEQUENCE(POLICYINFO) = {
|
||||
ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
|
||||
ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
|
||||
ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
|
||||
ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
|
||||
} ASN1_SEQUENCE_END(POLICYINFO)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
|
||||
@@ -103,355 +107,381 @@ IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
|
||||
ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY);
|
||||
|
||||
ASN1_ADB(POLICYQUALINFO) = {
|
||||
ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
|
||||
ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
|
||||
ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
|
||||
ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
|
||||
} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL);
|
||||
|
||||
ASN1_SEQUENCE(POLICYQUALINFO) = {
|
||||
ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
|
||||
ASN1_ADB_OBJECT(POLICYQUALINFO)
|
||||
ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
|
||||
ASN1_ADB_OBJECT(POLICYQUALINFO)
|
||||
} ASN1_SEQUENCE_END(POLICYQUALINFO)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO)
|
||||
|
||||
ASN1_SEQUENCE(USERNOTICE) = {
|
||||
ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
|
||||
ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
|
||||
ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
|
||||
ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
|
||||
} ASN1_SEQUENCE_END(USERNOTICE)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE)
|
||||
|
||||
ASN1_SEQUENCE(NOTICEREF) = {
|
||||
ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
|
||||
ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
|
||||
ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
|
||||
ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
|
||||
} ASN1_SEQUENCE_END(NOTICEREF)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)
|
||||
|
||||
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *value)
|
||||
X509V3_CTX *ctx, char *value)
|
||||
{
|
||||
STACK_OF(POLICYINFO) *pols = NULL;
|
||||
char *pstr;
|
||||
POLICYINFO *pol;
|
||||
ASN1_OBJECT *pobj;
|
||||
STACK_OF(CONF_VALUE) *vals;
|
||||
CONF_VALUE *cnf;
|
||||
int i, ia5org;
|
||||
pols = sk_POLICYINFO_new_null();
|
||||
if (pols == NULL) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
vals = X509V3_parse_list(value);
|
||||
if (vals == NULL) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB);
|
||||
goto err;
|
||||
}
|
||||
ia5org = 0;
|
||||
for(i = 0; i < sk_CONF_VALUE_num(vals); i++) {
|
||||
cnf = sk_CONF_VALUE_value(vals, i);
|
||||
if(cnf->value || !cnf->name ) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_POLICY_IDENTIFIER);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
pstr = cnf->name;
|
||||
if(!strcmp(pstr,"ia5org")) {
|
||||
ia5org = 1;
|
||||
continue;
|
||||
} else if(*pstr == '@') {
|
||||
STACK_OF(CONF_VALUE) *polsect;
|
||||
polsect = X509V3_get_section(ctx, pstr + 1);
|
||||
if(!polsect) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_SECTION);
|
||||
STACK_OF(POLICYINFO) *pols = NULL;
|
||||
char *pstr;
|
||||
POLICYINFO *pol;
|
||||
ASN1_OBJECT *pobj;
|
||||
STACK_OF(CONF_VALUE) *vals;
|
||||
CONF_VALUE *cnf;
|
||||
int i, ia5org;
|
||||
pols = sk_POLICYINFO_new_null();
|
||||
if (pols == NULL) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
vals = X509V3_parse_list(value);
|
||||
if (vals == NULL) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB);
|
||||
goto err;
|
||||
}
|
||||
ia5org = 0;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
|
||||
cnf = sk_CONF_VALUE_value(vals, i);
|
||||
if (cnf->value || !cnf->name) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL,
|
||||
X509V3_R_INVALID_POLICY_IDENTIFIER);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
pstr = cnf->name;
|
||||
if (!strcmp(pstr, "ia5org")) {
|
||||
ia5org = 1;
|
||||
continue;
|
||||
} else if (*pstr == '@') {
|
||||
STACK_OF(CONF_VALUE) *polsect;
|
||||
polsect = X509V3_get_section(ctx, pstr + 1);
|
||||
if (!polsect) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL, X509V3_R_INVALID_SECTION);
|
||||
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
pol = policy_section(ctx, polsect, ia5org);
|
||||
X509V3_section_free(ctx, polsect);
|
||||
if(!pol) goto err;
|
||||
} else {
|
||||
if(!(pobj = OBJ_txt2obj(cnf->name, 0))) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
pol = POLICYINFO_new();
|
||||
pol->policyid = pobj;
|
||||
}
|
||||
if (!sk_POLICYINFO_push(pols, pol)){
|
||||
POLICYINFO_free(pol);
|
||||
X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
|
||||
return pols;
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
|
||||
sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
|
||||
return NULL;
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
pol = policy_section(ctx, polsect, ia5org);
|
||||
X509V3_section_free(ctx, polsect);
|
||||
if (!pol)
|
||||
goto err;
|
||||
} else {
|
||||
if (!(pobj = OBJ_txt2obj(cnf->name, 0))) {
|
||||
X509V3err(X509V3_F_R2I_CERTPOL,
|
||||
X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
pol = POLICYINFO_new();
|
||||
pol->policyid = pobj;
|
||||
}
|
||||
if (!sk_POLICYINFO_push(pols, pol)) {
|
||||
POLICYINFO_free(pol);
|
||||
X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
|
||||
return pols;
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
|
||||
sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static POLICYINFO *policy_section(X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *polstrs, int ia5org)
|
||||
STACK_OF(CONF_VALUE) *polstrs, int ia5org)
|
||||
{
|
||||
int i;
|
||||
CONF_VALUE *cnf;
|
||||
POLICYINFO *pol;
|
||||
POLICYQUALINFO *qual;
|
||||
if(!(pol = POLICYINFO_new())) goto merr;
|
||||
for(i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
|
||||
cnf = sk_CONF_VALUE_value(polstrs, i);
|
||||
if(!strcmp(cnf->name, "policyIdentifier")) {
|
||||
ASN1_OBJECT *pobj;
|
||||
if(!(pobj = OBJ_txt2obj(cnf->value, 0))) {
|
||||
X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
pol->policyid = pobj;
|
||||
int i;
|
||||
CONF_VALUE *cnf;
|
||||
POLICYINFO *pol;
|
||||
POLICYQUALINFO *qual;
|
||||
if (!(pol = POLICYINFO_new()))
|
||||
goto merr;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
|
||||
cnf = sk_CONF_VALUE_value(polstrs, i);
|
||||
if (!strcmp(cnf->name, "policyIdentifier")) {
|
||||
ASN1_OBJECT *pobj;
|
||||
if (!(pobj = OBJ_txt2obj(cnf->value, 0))) {
|
||||
X509V3err(X509V3_F_POLICY_SECTION,
|
||||
X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
pol->policyid = pobj;
|
||||
|
||||
} else if(!name_cmp(cnf->name, "CPS")) {
|
||||
if(!pol->qualifiers) pol->qualifiers =
|
||||
sk_POLICYQUALINFO_new_null();
|
||||
if(!(qual = POLICYQUALINFO_new())) goto merr;
|
||||
if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
|
||||
goto merr;
|
||||
qual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
|
||||
qual->d.cpsuri = M_ASN1_IA5STRING_new();
|
||||
if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
|
||||
strlen(cnf->value))) goto merr;
|
||||
} else if(!name_cmp(cnf->name, "userNotice")) {
|
||||
STACK_OF(CONF_VALUE) *unot;
|
||||
if(*cnf->value != '@') {
|
||||
X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_EXPECTED_A_SECTION_NAME);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
unot = X509V3_get_section(ctx, cnf->value + 1);
|
||||
if(!unot) {
|
||||
X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_SECTION);
|
||||
} else if (!name_cmp(cnf->name, "CPS")) {
|
||||
if (!pol->qualifiers)
|
||||
pol->qualifiers = sk_POLICYQUALINFO_new_null();
|
||||
if (!(qual = POLICYQUALINFO_new()))
|
||||
goto merr;
|
||||
if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
|
||||
goto merr;
|
||||
if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_cps))) {
|
||||
X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (!(qual->d.cpsuri = M_ASN1_IA5STRING_new()))
|
||||
goto merr;
|
||||
if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
|
||||
strlen(cnf->value)))
|
||||
goto merr;
|
||||
} else if (!name_cmp(cnf->name, "userNotice")) {
|
||||
STACK_OF(CONF_VALUE) *unot;
|
||||
if (*cnf->value != '@') {
|
||||
X509V3err(X509V3_F_POLICY_SECTION,
|
||||
X509V3_R_EXPECTED_A_SECTION_NAME);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
unot = X509V3_get_section(ctx, cnf->value + 1);
|
||||
if (!unot) {
|
||||
X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_SECTION);
|
||||
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
qual = notice_section(ctx, unot, ia5org);
|
||||
X509V3_section_free(ctx, unot);
|
||||
if(!qual) goto err;
|
||||
if(!pol->qualifiers) pol->qualifiers =
|
||||
sk_POLICYQUALINFO_new_null();
|
||||
if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
|
||||
goto merr;
|
||||
} else {
|
||||
X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OPTION);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
qual = notice_section(ctx, unot, ia5org);
|
||||
X509V3_section_free(ctx, unot);
|
||||
if (!qual)
|
||||
goto err;
|
||||
if (!pol->qualifiers)
|
||||
pol->qualifiers = sk_POLICYQUALINFO_new_null();
|
||||
if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
|
||||
goto merr;
|
||||
} else {
|
||||
X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_OPTION);
|
||||
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if(!pol->policyid) {
|
||||
X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_NO_POLICY_IDENTIFIER);
|
||||
goto err;
|
||||
}
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!pol->policyid) {
|
||||
X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_NO_POLICY_IDENTIFIER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return pol;
|
||||
return pol;
|
||||
|
||||
merr:
|
||||
X509V3err(X509V3_F_POLICY_SECTION,ERR_R_MALLOC_FAILURE);
|
||||
merr:
|
||||
X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
err:
|
||||
POLICYINFO_free(pol);
|
||||
return NULL;
|
||||
|
||||
err:
|
||||
POLICYINFO_free(pol);
|
||||
return NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *unot, int ia5org)
|
||||
STACK_OF(CONF_VALUE) *unot, int ia5org)
|
||||
{
|
||||
int i, ret;
|
||||
CONF_VALUE *cnf;
|
||||
USERNOTICE *not;
|
||||
POLICYQUALINFO *qual;
|
||||
if(!(qual = POLICYQUALINFO_new())) goto merr;
|
||||
qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
|
||||
if(!(not = USERNOTICE_new())) goto merr;
|
||||
qual->d.usernotice = not;
|
||||
for(i = 0; i < sk_CONF_VALUE_num(unot); i++) {
|
||||
cnf = sk_CONF_VALUE_value(unot, i);
|
||||
if(!strcmp(cnf->name, "explicitText")) {
|
||||
not->exptext = M_ASN1_VISIBLESTRING_new();
|
||||
if(!ASN1_STRING_set(not->exptext, cnf->value,
|
||||
strlen(cnf->value))) goto merr;
|
||||
} else if(!strcmp(cnf->name, "organization")) {
|
||||
NOTICEREF *nref;
|
||||
if(!not->noticeref) {
|
||||
if(!(nref = NOTICEREF_new())) goto merr;
|
||||
not->noticeref = nref;
|
||||
} else nref = not->noticeref;
|
||||
if(ia5org) nref->organization->type = V_ASN1_IA5STRING;
|
||||
else nref->organization->type = V_ASN1_VISIBLESTRING;
|
||||
if(!ASN1_STRING_set(nref->organization, cnf->value,
|
||||
strlen(cnf->value))) goto merr;
|
||||
} else if(!strcmp(cnf->name, "noticeNumbers")) {
|
||||
NOTICEREF *nref;
|
||||
STACK_OF(CONF_VALUE) *nos;
|
||||
if(!not->noticeref) {
|
||||
if(!(nref = NOTICEREF_new())) goto merr;
|
||||
not->noticeref = nref;
|
||||
} else nref = not->noticeref;
|
||||
nos = X509V3_parse_list(cnf->value);
|
||||
if(!nos || !sk_CONF_VALUE_num(nos)) {
|
||||
X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_NUMBERS);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
ret = nref_nos(nref->noticenos, nos);
|
||||
sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
|
||||
if (!ret)
|
||||
goto err;
|
||||
} else {
|
||||
X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_OPTION);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
int i, ret;
|
||||
CONF_VALUE *cnf;
|
||||
USERNOTICE *not;
|
||||
POLICYQUALINFO *qual;
|
||||
if (!(qual = POLICYQUALINFO_new()))
|
||||
goto merr;
|
||||
if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice))) {
|
||||
X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (!(not = USERNOTICE_new()))
|
||||
goto merr;
|
||||
qual->d.usernotice = not;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
|
||||
cnf = sk_CONF_VALUE_value(unot, i);
|
||||
if (!strcmp(cnf->name, "explicitText")) {
|
||||
if (!(not->exptext = M_ASN1_VISIBLESTRING_new()))
|
||||
goto merr;
|
||||
if (!ASN1_STRING_set(not->exptext, cnf->value,
|
||||
strlen(cnf->value)))
|
||||
goto merr;
|
||||
} else if (!strcmp(cnf->name, "organization")) {
|
||||
NOTICEREF *nref;
|
||||
if (!not->noticeref) {
|
||||
if (!(nref = NOTICEREF_new()))
|
||||
goto merr;
|
||||
not->noticeref = nref;
|
||||
} else
|
||||
nref = not->noticeref;
|
||||
if (ia5org)
|
||||
nref->organization->type = V_ASN1_IA5STRING;
|
||||
else
|
||||
nref->organization->type = V_ASN1_VISIBLESTRING;
|
||||
if (!ASN1_STRING_set(nref->organization, cnf->value,
|
||||
strlen(cnf->value)))
|
||||
goto merr;
|
||||
} else if (!strcmp(cnf->name, "noticeNumbers")) {
|
||||
NOTICEREF *nref;
|
||||
STACK_OF(CONF_VALUE) *nos;
|
||||
if (!not->noticeref) {
|
||||
if (!(nref = NOTICEREF_new()))
|
||||
goto merr;
|
||||
not->noticeref = nref;
|
||||
} else
|
||||
nref = not->noticeref;
|
||||
nos = X509V3_parse_list(cnf->value);
|
||||
if (!nos || !sk_CONF_VALUE_num(nos)) {
|
||||
X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_NUMBERS);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
ret = nref_nos(nref->noticenos, nos);
|
||||
sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
|
||||
if (!ret)
|
||||
goto err;
|
||||
} else {
|
||||
X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_OPTION);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if(not->noticeref &&
|
||||
(!not->noticeref->noticenos || !not->noticeref->organization)) {
|
||||
X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
|
||||
goto err;
|
||||
}
|
||||
if (not->noticeref &&
|
||||
(!not->noticeref->noticenos || !not->noticeref->organization)) {
|
||||
X509V3err(X509V3_F_NOTICE_SECTION,
|
||||
X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return qual;
|
||||
return qual;
|
||||
|
||||
merr:
|
||||
X509V3err(X509V3_F_NOTICE_SECTION,ERR_R_MALLOC_FAILURE);
|
||||
merr:
|
||||
X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
err:
|
||||
POLICYQUALINFO_free(qual);
|
||||
return NULL;
|
||||
err:
|
||||
POLICYQUALINFO_free(qual);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
|
||||
{
|
||||
CONF_VALUE *cnf;
|
||||
ASN1_INTEGER *aint;
|
||||
CONF_VALUE *cnf;
|
||||
ASN1_INTEGER *aint;
|
||||
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nos); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nos, i);
|
||||
if(!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
|
||||
X509V3err(X509V3_F_NREF_NOS,X509V3_R_INVALID_NUMBER);
|
||||
goto err;
|
||||
}
|
||||
if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
|
||||
}
|
||||
return 1;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nos); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nos, i);
|
||||
if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
|
||||
X509V3err(X509V3_F_NREF_NOS, X509V3_R_INVALID_NUMBER);
|
||||
goto err;
|
||||
}
|
||||
if (!sk_ASN1_INTEGER_push(nnums, aint))
|
||||
goto merr;
|
||||
}
|
||||
return 1;
|
||||
|
||||
merr:
|
||||
X509V3err(X509V3_F_NREF_NOS,ERR_R_MALLOC_FAILURE);
|
||||
merr:
|
||||
X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
err:
|
||||
sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
|
||||
return 0;
|
||||
err:
|
||||
sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
|
||||
BIO *out, int indent)
|
||||
BIO *out, int indent)
|
||||
{
|
||||
int i;
|
||||
POLICYINFO *pinfo;
|
||||
/* First print out the policy OIDs */
|
||||
for(i = 0; i < sk_POLICYINFO_num(pol); i++) {
|
||||
pinfo = sk_POLICYINFO_value(pol, i);
|
||||
BIO_printf(out, "%*sPolicy: ", indent, "");
|
||||
i2a_ASN1_OBJECT(out, pinfo->policyid);
|
||||
BIO_puts(out, "\n");
|
||||
if(pinfo->qualifiers)
|
||||
print_qualifiers(out, pinfo->qualifiers, indent + 2);
|
||||
}
|
||||
return 1;
|
||||
int i;
|
||||
POLICYINFO *pinfo;
|
||||
/* First print out the policy OIDs */
|
||||
for (i = 0; i < sk_POLICYINFO_num(pol); i++) {
|
||||
pinfo = sk_POLICYINFO_value(pol, i);
|
||||
BIO_printf(out, "%*sPolicy: ", indent, "");
|
||||
i2a_ASN1_OBJECT(out, pinfo->policyid);
|
||||
BIO_puts(out, "\n");
|
||||
if (pinfo->qualifiers)
|
||||
print_qualifiers(out, pinfo->qualifiers, indent + 2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
|
||||
int indent)
|
||||
int indent)
|
||||
{
|
||||
POLICYQUALINFO *qualinfo;
|
||||
int i;
|
||||
for(i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
|
||||
qualinfo = sk_POLICYQUALINFO_value(quals, i);
|
||||
switch(OBJ_obj2nid(qualinfo->pqualid))
|
||||
{
|
||||
case NID_id_qt_cps:
|
||||
BIO_printf(out, "%*sCPS: %s\n", indent, "",
|
||||
qualinfo->d.cpsuri->data);
|
||||
break;
|
||||
|
||||
case NID_id_qt_unotice:
|
||||
BIO_printf(out, "%*sUser Notice:\n", indent, "");
|
||||
print_notice(out, qualinfo->d.usernotice, indent + 2);
|
||||
break;
|
||||
POLICYQUALINFO *qualinfo;
|
||||
int i;
|
||||
for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
|
||||
qualinfo = sk_POLICYQUALINFO_value(quals, i);
|
||||
switch (OBJ_obj2nid(qualinfo->pqualid)) {
|
||||
case NID_id_qt_cps:
|
||||
BIO_printf(out, "%*sCPS: %s\n", indent, "",
|
||||
qualinfo->d.cpsuri->data);
|
||||
break;
|
||||
|
||||
default:
|
||||
BIO_printf(out, "%*sUnknown Qualifier: ",
|
||||
indent + 2, "");
|
||||
|
||||
i2a_ASN1_OBJECT(out, qualinfo->pqualid);
|
||||
BIO_puts(out, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
case NID_id_qt_unotice:
|
||||
BIO_printf(out, "%*sUser Notice:\n", indent, "");
|
||||
print_notice(out, qualinfo->d.usernotice, indent + 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, "");
|
||||
|
||||
i2a_ASN1_OBJECT(out, qualinfo->pqualid);
|
||||
BIO_puts(out, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void print_notice(BIO *out, USERNOTICE *notice, int indent)
|
||||
{
|
||||
int i;
|
||||
if(notice->noticeref) {
|
||||
NOTICEREF *ref;
|
||||
ref = notice->noticeref;
|
||||
BIO_printf(out, "%*sOrganization: %s\n", indent, "",
|
||||
ref->organization->data);
|
||||
BIO_printf(out, "%*sNumber%s: ", indent, "",
|
||||
sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
|
||||
for(i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
|
||||
ASN1_INTEGER *num;
|
||||
char *tmp;
|
||||
num = sk_ASN1_INTEGER_value(ref->noticenos, i);
|
||||
if(i) BIO_puts(out, ", ");
|
||||
tmp = i2s_ASN1_INTEGER(NULL, num);
|
||||
BIO_puts(out, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
if(notice->exptext)
|
||||
BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
|
||||
notice->exptext->data);
|
||||
int i;
|
||||
if (notice->noticeref) {
|
||||
NOTICEREF *ref;
|
||||
ref = notice->noticeref;
|
||||
BIO_printf(out, "%*sOrganization: %s\n", indent, "",
|
||||
ref->organization->data);
|
||||
BIO_printf(out, "%*sNumber%s: ", indent, "",
|
||||
sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
|
||||
for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
|
||||
ASN1_INTEGER *num;
|
||||
char *tmp;
|
||||
num = sk_ASN1_INTEGER_value(ref->noticenos, i);
|
||||
if (i)
|
||||
BIO_puts(out, ", ");
|
||||
tmp = i2s_ASN1_INTEGER(NULL, num);
|
||||
BIO_puts(out, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
if (notice->exptext)
|
||||
BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
|
||||
notice->exptext->data);
|
||||
}
|
||||
|
||||
void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
|
||||
{
|
||||
const X509_POLICY_DATA *dat = node->data;
|
||||
{
|
||||
const X509_POLICY_DATA *dat = node->data;
|
||||
|
||||
BIO_printf(out, "%*sPolicy: ", indent, "");
|
||||
|
||||
i2a_ASN1_OBJECT(out, dat->valid_policy);
|
||||
BIO_puts(out, "\n");
|
||||
BIO_printf(out, "%*s%s\n", indent + 2, "",
|
||||
node_data_critical(dat) ? "Critical" : "Non Critical");
|
||||
if (dat->qualifier_set)
|
||||
print_qualifiers(out, dat->qualifier_set, indent + 2);
|
||||
else
|
||||
BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
|
||||
}
|
||||
BIO_printf(out, "%*sPolicy: ", indent, "");
|
||||
|
||||
i2a_ASN1_OBJECT(out, dat->valid_policy);
|
||||
BIO_puts(out, "\n");
|
||||
BIO_printf(out, "%*s%s\n", indent + 2, "",
|
||||
node_data_critical(dat) ? "Critical" : "Non Critical");
|
||||
if (dat->qualifier_set)
|
||||
print_qualifiers(out, dat->qualifier_set, indent + 2);
|
||||
else
|
||||
BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_STACK_OF(X509_POLICY_NODE)
|
||||
IMPLEMENT_STACK_OF(X509_POLICY_DATA)
|
||||
|
||||
IMPLEMENT_STACK_OF(X509_POLICY_DATA)
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_crld.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -64,553 +65,498 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static void *v2i_crld(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
|
||||
static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
|
||||
int indent);
|
||||
int indent);
|
||||
|
||||
const X509V3_EXT_METHOD v3_crld =
|
||||
{
|
||||
NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,
|
||||
v2i_crld,
|
||||
i2r_crldp,0,
|
||||
NULL
|
||||
};
|
||||
const X509V3_EXT_METHOD v3_crld = {
|
||||
NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0,
|
||||
v2i_crld,
|
||||
i2r_crldp, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_freshest_crl =
|
||||
{
|
||||
NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,
|
||||
v2i_crld,
|
||||
i2r_crldp,0,
|
||||
NULL
|
||||
};
|
||||
const X509V3_EXT_METHOD v3_freshest_crl = {
|
||||
NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0,
|
||||
v2i_crld,
|
||||
i2r_crldp, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *gnsect;
|
||||
STACK_OF(GENERAL_NAME) *gens;
|
||||
if (*sect == '@')
|
||||
gnsect = X509V3_get_section(ctx, sect + 1);
|
||||
else
|
||||
gnsect = X509V3_parse_list(sect);
|
||||
if (!gnsect)
|
||||
{
|
||||
X509V3err(X509V3_F_GNAMES_FROM_SECTNAME,
|
||||
X509V3_R_SECTION_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
|
||||
if (*sect == '@')
|
||||
X509V3_section_free(ctx, gnsect);
|
||||
else
|
||||
sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
|
||||
return gens;
|
||||
}
|
||||
static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx,
|
||||
char *sect)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *gnsect;
|
||||
STACK_OF(GENERAL_NAME) *gens;
|
||||
if (*sect == '@')
|
||||
gnsect = X509V3_get_section(ctx, sect + 1);
|
||||
else
|
||||
gnsect = X509V3_parse_list(sect);
|
||||
if (!gnsect) {
|
||||
X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, X509V3_R_SECTION_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
|
||||
if (*sect == '@')
|
||||
X509V3_section_free(ctx, gnsect);
|
||||
else
|
||||
sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
|
||||
return gens;
|
||||
}
|
||||
|
||||
static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
|
||||
CONF_VALUE *cnf)
|
||||
{
|
||||
STACK_OF(GENERAL_NAME) *fnm = NULL;
|
||||
STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
|
||||
if (!strncmp(cnf->name, "fullname", 9))
|
||||
{
|
||||
fnm = gnames_from_sectname(ctx, cnf->value);
|
||||
if (!fnm)
|
||||
goto err;
|
||||
}
|
||||
else if (!strcmp(cnf->name, "relativename"))
|
||||
{
|
||||
int ret;
|
||||
STACK_OF(CONF_VALUE) *dnsect;
|
||||
X509_NAME *nm;
|
||||
nm = X509_NAME_new();
|
||||
if (!nm)
|
||||
return -1;
|
||||
dnsect = X509V3_get_section(ctx, cnf->value);
|
||||
if (!dnsect)
|
||||
{
|
||||
X509V3err(X509V3_F_SET_DIST_POINT_NAME,
|
||||
X509V3_R_SECTION_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
|
||||
X509V3_section_free(ctx, dnsect);
|
||||
rnm = nm->entries;
|
||||
nm->entries = NULL;
|
||||
X509_NAME_free(nm);
|
||||
if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
|
||||
goto err;
|
||||
/* Since its a name fragment can't have more than one
|
||||
* RDNSequence
|
||||
*/
|
||||
if (sk_X509_NAME_ENTRY_value(rnm,
|
||||
sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
|
||||
{
|
||||
X509V3err(X509V3_F_SET_DIST_POINT_NAME,
|
||||
X509V3_R_INVALID_MULTIPLE_RDNS);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
CONF_VALUE *cnf)
|
||||
{
|
||||
STACK_OF(GENERAL_NAME) *fnm = NULL;
|
||||
STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
|
||||
if (!strncmp(cnf->name, "fullname", 9)) {
|
||||
fnm = gnames_from_sectname(ctx, cnf->value);
|
||||
if (!fnm)
|
||||
goto err;
|
||||
} else if (!strcmp(cnf->name, "relativename")) {
|
||||
int ret;
|
||||
STACK_OF(CONF_VALUE) *dnsect;
|
||||
X509_NAME *nm;
|
||||
nm = X509_NAME_new();
|
||||
if (!nm)
|
||||
return -1;
|
||||
dnsect = X509V3_get_section(ctx, cnf->value);
|
||||
if (!dnsect) {
|
||||
X509V3err(X509V3_F_SET_DIST_POINT_NAME,
|
||||
X509V3_R_SECTION_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
|
||||
X509V3_section_free(ctx, dnsect);
|
||||
rnm = nm->entries;
|
||||
nm->entries = NULL;
|
||||
X509_NAME_free(nm);
|
||||
if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
|
||||
goto err;
|
||||
/*
|
||||
* Since its a name fragment can't have more than one RDNSequence
|
||||
*/
|
||||
if (sk_X509_NAME_ENTRY_value(rnm,
|
||||
sk_X509_NAME_ENTRY_num(rnm) - 1)->set) {
|
||||
X509V3err(X509V3_F_SET_DIST_POINT_NAME,
|
||||
X509V3_R_INVALID_MULTIPLE_RDNS);
|
||||
goto err;
|
||||
}
|
||||
} else
|
||||
return 0;
|
||||
|
||||
if (*pdp)
|
||||
{
|
||||
X509V3err(X509V3_F_SET_DIST_POINT_NAME,
|
||||
X509V3_R_DISTPOINT_ALREADY_SET);
|
||||
goto err;
|
||||
}
|
||||
if (*pdp) {
|
||||
X509V3err(X509V3_F_SET_DIST_POINT_NAME,
|
||||
X509V3_R_DISTPOINT_ALREADY_SET);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*pdp = DIST_POINT_NAME_new();
|
||||
if (!*pdp)
|
||||
goto err;
|
||||
if (fnm)
|
||||
{
|
||||
(*pdp)->type = 0;
|
||||
(*pdp)->name.fullname = fnm;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*pdp)->type = 1;
|
||||
(*pdp)->name.relativename = rnm;
|
||||
}
|
||||
*pdp = DIST_POINT_NAME_new();
|
||||
if (!*pdp)
|
||||
goto err;
|
||||
if (fnm) {
|
||||
(*pdp)->type = 0;
|
||||
(*pdp)->name.fullname = fnm;
|
||||
} else {
|
||||
(*pdp)->type = 1;
|
||||
(*pdp)->name.relativename = rnm;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
if (fnm)
|
||||
sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
|
||||
if (rnm)
|
||||
sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
|
||||
err:
|
||||
if (fnm)
|
||||
sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
|
||||
if (rnm)
|
||||
sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const BIT_STRING_BITNAME reason_flags[] = {
|
||||
{0, "Unused", "unused"},
|
||||
{1, "Key Compromise", "keyCompromise"},
|
||||
{2, "CA Compromise", "CACompromise"},
|
||||
{3, "Affiliation Changed", "affiliationChanged"},
|
||||
{4, "Superseded", "superseded"},
|
||||
{5, "Cessation Of Operation", "cessationOfOperation"},
|
||||
{6, "Certificate Hold", "certificateHold"},
|
||||
{7, "Privilege Withdrawn", "privilegeWithdrawn"},
|
||||
{8, "AA Compromise", "AACompromise"},
|
||||
{-1, NULL, NULL}
|
||||
{0, "Unused", "unused"},
|
||||
{1, "Key Compromise", "keyCompromise"},
|
||||
{2, "CA Compromise", "CACompromise"},
|
||||
{3, "Affiliation Changed", "affiliationChanged"},
|
||||
{4, "Superseded", "superseded"},
|
||||
{5, "Cessation Of Operation", "cessationOfOperation"},
|
||||
{6, "Certificate Hold", "certificateHold"},
|
||||
{7, "Privilege Withdrawn", "privilegeWithdrawn"},
|
||||
{8, "AA Compromise", "AACompromise"},
|
||||
{-1, NULL, NULL}
|
||||
};
|
||||
|
||||
static int set_reasons(ASN1_BIT_STRING **preas, char *value)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *rsk = NULL;
|
||||
const BIT_STRING_BITNAME *pbn;
|
||||
const char *bnam;
|
||||
int i, ret = 0;
|
||||
rsk = X509V3_parse_list(value);
|
||||
if (!rsk)
|
||||
return 0;
|
||||
if (*preas)
|
||||
return 0;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
|
||||
{
|
||||
bnam = sk_CONF_VALUE_value(rsk, i)->name;
|
||||
if (!*preas)
|
||||
{
|
||||
*preas = ASN1_BIT_STRING_new();
|
||||
if (!*preas)
|
||||
goto err;
|
||||
}
|
||||
for (pbn = reason_flags; pbn->lname; pbn++)
|
||||
{
|
||||
if (!strcmp(pbn->sname, bnam))
|
||||
{
|
||||
if (!ASN1_BIT_STRING_set_bit(*preas,
|
||||
pbn->bitnum, 1))
|
||||
goto err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pbn->lname)
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *rsk = NULL;
|
||||
const BIT_STRING_BITNAME *pbn;
|
||||
const char *bnam;
|
||||
int i, ret = 0;
|
||||
rsk = X509V3_parse_list(value);
|
||||
if (!rsk)
|
||||
return 0;
|
||||
if (*preas)
|
||||
return 0;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) {
|
||||
bnam = sk_CONF_VALUE_value(rsk, i)->name;
|
||||
if (!*preas) {
|
||||
*preas = ASN1_BIT_STRING_new();
|
||||
if (!*preas)
|
||||
goto err;
|
||||
}
|
||||
for (pbn = reason_flags; pbn->lname; pbn++) {
|
||||
if (!strcmp(pbn->sname, bnam)) {
|
||||
if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1))
|
||||
goto err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pbn->lname)
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
|
||||
return ret;
|
||||
}
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int print_reasons(BIO *out, const char *rname,
|
||||
ASN1_BIT_STRING *rflags, int indent)
|
||||
{
|
||||
int first = 1;
|
||||
const BIT_STRING_BITNAME *pbn;
|
||||
BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
|
||||
for (pbn = reason_flags; pbn->lname; pbn++)
|
||||
{
|
||||
if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
|
||||
{
|
||||
if (first)
|
||||
first = 0;
|
||||
else
|
||||
BIO_puts(out, ", ");
|
||||
BIO_puts(out, pbn->lname);
|
||||
}
|
||||
}
|
||||
if (first)
|
||||
BIO_puts(out, "<EMPTY>\n");
|
||||
else
|
||||
BIO_puts(out, "\n");
|
||||
return 1;
|
||||
}
|
||||
ASN1_BIT_STRING *rflags, int indent)
|
||||
{
|
||||
int first = 1;
|
||||
const BIT_STRING_BITNAME *pbn;
|
||||
BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
|
||||
for (pbn = reason_flags; pbn->lname; pbn++) {
|
||||
if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) {
|
||||
if (first)
|
||||
first = 0;
|
||||
else
|
||||
BIO_puts(out, ", ");
|
||||
BIO_puts(out, pbn->lname);
|
||||
}
|
||||
}
|
||||
if (first)
|
||||
BIO_puts(out, "<EMPTY>\n");
|
||||
else
|
||||
BIO_puts(out, "\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
int i;
|
||||
CONF_VALUE *cnf;
|
||||
DIST_POINT *point = NULL;
|
||||
point = DIST_POINT_new();
|
||||
if (!point)
|
||||
goto err;
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
|
||||
{
|
||||
int ret;
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
ret = set_dist_point_name(&point->distpoint, ctx, cnf);
|
||||
if (ret > 0)
|
||||
continue;
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
if (!strcmp(cnf->name, "reasons"))
|
||||
{
|
||||
if (!set_reasons(&point->reasons, cnf->value))
|
||||
goto err;
|
||||
}
|
||||
else if (!strcmp(cnf->name, "CRLissuer"))
|
||||
{
|
||||
point->CRLissuer =
|
||||
gnames_from_sectname(ctx, cnf->value);
|
||||
if (!point->CRLissuer)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
int i;
|
||||
CONF_VALUE *cnf;
|
||||
DIST_POINT *point = NULL;
|
||||
point = DIST_POINT_new();
|
||||
if (!point)
|
||||
goto err;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
int ret;
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
ret = set_dist_point_name(&point->distpoint, ctx, cnf);
|
||||
if (ret > 0)
|
||||
continue;
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
if (!strcmp(cnf->name, "reasons")) {
|
||||
if (!set_reasons(&point->reasons, cnf->value))
|
||||
goto err;
|
||||
} else if (!strcmp(cnf->name, "CRLissuer")) {
|
||||
point->CRLissuer = gnames_from_sectname(ctx, cnf->value);
|
||||
if (!point->CRLissuer)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return point;
|
||||
|
||||
return point;
|
||||
|
||||
err:
|
||||
if (point)
|
||||
DIST_POINT_free(point);
|
||||
return NULL;
|
||||
}
|
||||
err:
|
||||
if (point)
|
||||
DIST_POINT_free(point);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *v2i_crld(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
STACK_OF(DIST_POINT) *crld = NULL;
|
||||
GENERAL_NAMES *gens = NULL;
|
||||
GENERAL_NAME *gen = NULL;
|
||||
CONF_VALUE *cnf;
|
||||
int i;
|
||||
if(!(crld = sk_DIST_POINT_new_null())) goto merr;
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
DIST_POINT *point;
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if (!cnf->value)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *dpsect;
|
||||
dpsect = X509V3_get_section(ctx, cnf->name);
|
||||
if (!dpsect)
|
||||
goto err;
|
||||
point = crldp_from_section(ctx, dpsect);
|
||||
X509V3_section_free(ctx, dpsect);
|
||||
if (!point)
|
||||
goto err;
|
||||
if(!sk_DIST_POINT_push(crld, point))
|
||||
{
|
||||
DIST_POINT_free(point);
|
||||
goto merr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
|
||||
goto err;
|
||||
if(!(gens = GENERAL_NAMES_new()))
|
||||
goto merr;
|
||||
if(!sk_GENERAL_NAME_push(gens, gen))
|
||||
goto merr;
|
||||
gen = NULL;
|
||||
if(!(point = DIST_POINT_new()))
|
||||
goto merr;
|
||||
if(!sk_DIST_POINT_push(crld, point))
|
||||
{
|
||||
DIST_POINT_free(point);
|
||||
goto merr;
|
||||
}
|
||||
if(!(point->distpoint = DIST_POINT_NAME_new()))
|
||||
goto merr;
|
||||
point->distpoint->name.fullname = gens;
|
||||
point->distpoint->type = 0;
|
||||
gens = NULL;
|
||||
}
|
||||
}
|
||||
return crld;
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
STACK_OF(DIST_POINT) *crld = NULL;
|
||||
GENERAL_NAMES *gens = NULL;
|
||||
GENERAL_NAME *gen = NULL;
|
||||
CONF_VALUE *cnf;
|
||||
int i;
|
||||
if (!(crld = sk_DIST_POINT_new_null()))
|
||||
goto merr;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
DIST_POINT *point;
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if (!cnf->value) {
|
||||
STACK_OF(CONF_VALUE) *dpsect;
|
||||
dpsect = X509V3_get_section(ctx, cnf->name);
|
||||
if (!dpsect)
|
||||
goto err;
|
||||
point = crldp_from_section(ctx, dpsect);
|
||||
X509V3_section_free(ctx, dpsect);
|
||||
if (!point)
|
||||
goto err;
|
||||
if (!sk_DIST_POINT_push(crld, point)) {
|
||||
DIST_POINT_free(point);
|
||||
goto merr;
|
||||
}
|
||||
} else {
|
||||
if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
|
||||
goto err;
|
||||
if (!(gens = GENERAL_NAMES_new()))
|
||||
goto merr;
|
||||
if (!sk_GENERAL_NAME_push(gens, gen))
|
||||
goto merr;
|
||||
gen = NULL;
|
||||
if (!(point = DIST_POINT_new()))
|
||||
goto merr;
|
||||
if (!sk_DIST_POINT_push(crld, point)) {
|
||||
DIST_POINT_free(point);
|
||||
goto merr;
|
||||
}
|
||||
if (!(point->distpoint = DIST_POINT_NAME_new()))
|
||||
goto merr;
|
||||
point->distpoint->name.fullname = gens;
|
||||
point->distpoint->type = 0;
|
||||
gens = NULL;
|
||||
}
|
||||
}
|
||||
return crld;
|
||||
|
||||
merr:
|
||||
X509V3err(X509V3_F_V2I_CRLD,ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
GENERAL_NAME_free(gen);
|
||||
GENERAL_NAMES_free(gens);
|
||||
sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
|
||||
return NULL;
|
||||
merr:
|
||||
X509V3err(X509V3_F_V2I_CRLD, ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
GENERAL_NAME_free(gen);
|
||||
GENERAL_NAMES_free(gens);
|
||||
sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IMPLEMENT_STACK_OF(DIST_POINT)
|
||||
|
||||
IMPLEMENT_ASN1_SET_OF(DIST_POINT)
|
||||
|
||||
static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
void *exarg)
|
||||
{
|
||||
DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
|
||||
void *exarg)
|
||||
{
|
||||
DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
|
||||
|
||||
switch(operation)
|
||||
{
|
||||
case ASN1_OP_NEW_POST:
|
||||
dpn->dpname = NULL;
|
||||
break;
|
||||
switch (operation) {
|
||||
case ASN1_OP_NEW_POST:
|
||||
dpn->dpname = NULL;
|
||||
break;
|
||||
|
||||
case ASN1_OP_FREE_POST:
|
||||
if (dpn->dpname)
|
||||
X509_NAME_free(dpn->dpname);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case ASN1_OP_FREE_POST:
|
||||
if (dpn->dpname)
|
||||
X509_NAME_free(dpn->dpname);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
|
||||
ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
|
||||
ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
|
||||
ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
|
||||
ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
|
||||
} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
|
||||
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
|
||||
|
||||
ASN1_SEQUENCE(DIST_POINT) = {
|
||||
ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
|
||||
ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
|
||||
ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
|
||||
ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
|
||||
ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
|
||||
ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
|
||||
} ASN1_SEQUENCE_END(DIST_POINT)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
|
||||
ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
|
||||
ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
|
||||
|
||||
ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
|
||||
ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
|
||||
ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
|
||||
ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
|
||||
} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
|
||||
|
||||
static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
|
||||
int indent);
|
||||
int indent);
|
||||
static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval);
|
||||
STACK_OF(CONF_VALUE) *nval);
|
||||
|
||||
const X509V3_EXT_METHOD v3_idp =
|
||||
{
|
||||
NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
|
||||
ASN1_ITEM_ref(ISSUING_DIST_POINT),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,
|
||||
v2i_idp,
|
||||
i2r_idp,0,
|
||||
NULL
|
||||
};
|
||||
const X509V3_EXT_METHOD v3_idp = {
|
||||
NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
|
||||
ASN1_ITEM_ref(ISSUING_DIST_POINT),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0,
|
||||
v2i_idp,
|
||||
i2r_idp, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
ISSUING_DIST_POINT *idp = NULL;
|
||||
CONF_VALUE *cnf;
|
||||
char *name, *val;
|
||||
int i, ret;
|
||||
idp = ISSUING_DIST_POINT_new();
|
||||
if (!idp)
|
||||
goto merr;
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
|
||||
{
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
name = cnf->name;
|
||||
val = cnf->value;
|
||||
ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
|
||||
if (ret > 0)
|
||||
continue;
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
if (!strcmp(name, "onlyuser"))
|
||||
{
|
||||
if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
|
||||
goto err;
|
||||
}
|
||||
else if (!strcmp(name, "onlyCA"))
|
||||
{
|
||||
if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
|
||||
goto err;
|
||||
}
|
||||
else if (!strcmp(name, "onlyAA"))
|
||||
{
|
||||
if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
|
||||
goto err;
|
||||
}
|
||||
else if (!strcmp(name, "indirectCRL"))
|
||||
{
|
||||
if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
|
||||
goto err;
|
||||
}
|
||||
else if (!strcmp(name, "onlysomereasons"))
|
||||
{
|
||||
if (!set_reasons(&idp->onlysomereasons, val))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return idp;
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
ISSUING_DIST_POINT *idp = NULL;
|
||||
CONF_VALUE *cnf;
|
||||
char *name, *val;
|
||||
int i, ret;
|
||||
idp = ISSUING_DIST_POINT_new();
|
||||
if (!idp)
|
||||
goto merr;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
name = cnf->name;
|
||||
val = cnf->value;
|
||||
ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
|
||||
if (ret > 0)
|
||||
continue;
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
if (!strcmp(name, "onlyuser")) {
|
||||
if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
|
||||
goto err;
|
||||
} else if (!strcmp(name, "onlyCA")) {
|
||||
if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
|
||||
goto err;
|
||||
} else if (!strcmp(name, "onlyAA")) {
|
||||
if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
|
||||
goto err;
|
||||
} else if (!strcmp(name, "indirectCRL")) {
|
||||
if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
|
||||
goto err;
|
||||
} else if (!strcmp(name, "onlysomereasons")) {
|
||||
if (!set_reasons(&idp->onlysomereasons, val))
|
||||
goto err;
|
||||
} else {
|
||||
X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return idp;
|
||||
|
||||
merr:
|
||||
X509V3err(X509V3_F_V2I_IDP,ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
ISSUING_DIST_POINT_free(idp);
|
||||
return NULL;
|
||||
}
|
||||
merr:
|
||||
X509V3err(X509V3_F_V2I_IDP, ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
ISSUING_DIST_POINT_free(idp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
|
||||
{
|
||||
BIO_printf(out, "%*s", indent + 2, "");
|
||||
GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
|
||||
BIO_printf(out, "%*s", indent + 2, "");
|
||||
GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
|
||||
{
|
||||
if (dpn->type == 0)
|
||||
{
|
||||
BIO_printf(out, "%*sFull Name:\n", indent, "");
|
||||
print_gens(out, dpn->name.fullname, indent);
|
||||
}
|
||||
else
|
||||
{
|
||||
X509_NAME ntmp;
|
||||
ntmp.entries = dpn->name.relativename;
|
||||
BIO_printf(out, "%*sRelative Name:\n%*s",
|
||||
indent, "", indent + 2, "");
|
||||
X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if (dpn->type == 0) {
|
||||
BIO_printf(out, "%*sFull Name:\n", indent, "");
|
||||
print_gens(out, dpn->name.fullname, indent);
|
||||
} else {
|
||||
X509_NAME ntmp;
|
||||
ntmp.entries = dpn->name.relativename;
|
||||
BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, "");
|
||||
X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
|
||||
int indent)
|
||||
{
|
||||
ISSUING_DIST_POINT *idp = pidp;
|
||||
if (idp->distpoint)
|
||||
print_distpoint(out, idp->distpoint, indent);
|
||||
if (idp->onlyuser > 0)
|
||||
BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
|
||||
if (idp->onlyCA > 0)
|
||||
BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
|
||||
if (idp->indirectCRL > 0)
|
||||
BIO_printf(out, "%*sIndirect CRL\n", indent, "");
|
||||
if (idp->onlysomereasons)
|
||||
print_reasons(out, "Only Some Reasons",
|
||||
idp->onlysomereasons, indent);
|
||||
if (idp->onlyattr > 0)
|
||||
BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
|
||||
if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
|
||||
&& (idp->indirectCRL <= 0) && !idp->onlysomereasons
|
||||
&& (idp->onlyattr <= 0))
|
||||
BIO_printf(out, "%*s<EMPTY>\n", indent, "");
|
||||
|
||||
return 1;
|
||||
}
|
||||
int indent)
|
||||
{
|
||||
ISSUING_DIST_POINT *idp = pidp;
|
||||
if (idp->distpoint)
|
||||
print_distpoint(out, idp->distpoint, indent);
|
||||
if (idp->onlyuser > 0)
|
||||
BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
|
||||
if (idp->onlyCA > 0)
|
||||
BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
|
||||
if (idp->indirectCRL > 0)
|
||||
BIO_printf(out, "%*sIndirect CRL\n", indent, "");
|
||||
if (idp->onlysomereasons)
|
||||
print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent);
|
||||
if (idp->onlyattr > 0)
|
||||
BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
|
||||
if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
|
||||
&& (idp->indirectCRL <= 0) && !idp->onlysomereasons
|
||||
&& (idp->onlyattr <= 0))
|
||||
BIO_printf(out, "%*s<EMPTY>\n", indent, "");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
|
||||
int indent)
|
||||
{
|
||||
STACK_OF(DIST_POINT) *crld = pcrldp;
|
||||
DIST_POINT *point;
|
||||
int i;
|
||||
for(i = 0; i < sk_DIST_POINT_num(crld); i++)
|
||||
{
|
||||
BIO_puts(out, "\n");
|
||||
point = sk_DIST_POINT_value(crld, i);
|
||||
if(point->distpoint)
|
||||
print_distpoint(out, point->distpoint, indent);
|
||||
if(point->reasons)
|
||||
print_reasons(out, "Reasons", point->reasons,
|
||||
indent);
|
||||
if(point->CRLissuer)
|
||||
{
|
||||
BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
|
||||
print_gens(out, point->CRLissuer, indent);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int indent)
|
||||
{
|
||||
STACK_OF(DIST_POINT) *crld = pcrldp;
|
||||
DIST_POINT *point;
|
||||
int i;
|
||||
for (i = 0; i < sk_DIST_POINT_num(crld); i++) {
|
||||
BIO_puts(out, "\n");
|
||||
point = sk_DIST_POINT_value(crld, i);
|
||||
if (point->distpoint)
|
||||
print_distpoint(out, point->distpoint, indent);
|
||||
if (point->reasons)
|
||||
print_reasons(out, "Reasons", point->reasons, indent);
|
||||
if (point->CRLissuer) {
|
||||
BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
|
||||
print_gens(out, point->CRLissuer, indent);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
|
||||
{
|
||||
int i;
|
||||
STACK_OF(X509_NAME_ENTRY) *frag;
|
||||
X509_NAME_ENTRY *ne;
|
||||
if (!dpn || (dpn->type != 1))
|
||||
return 1;
|
||||
frag = dpn->name.relativename;
|
||||
dpn->dpname = X509_NAME_dup(iname);
|
||||
if (!dpn->dpname)
|
||||
return 0;
|
||||
for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
|
||||
{
|
||||
ne = sk_X509_NAME_ENTRY_value(frag, i);
|
||||
if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
|
||||
{
|
||||
X509_NAME_free(dpn->dpname);
|
||||
dpn->dpname = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* generate cached encoding of name */
|
||||
if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
|
||||
{
|
||||
X509_NAME_free(dpn->dpname);
|
||||
dpn->dpname = NULL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
int i;
|
||||
STACK_OF(X509_NAME_ENTRY) *frag;
|
||||
X509_NAME_ENTRY *ne;
|
||||
if (!dpn || (dpn->type != 1))
|
||||
return 1;
|
||||
frag = dpn->name.relativename;
|
||||
dpn->dpname = X509_NAME_dup(iname);
|
||||
if (!dpn->dpname)
|
||||
return 0;
|
||||
for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
|
||||
ne = sk_X509_NAME_ENTRY_value(frag, i);
|
||||
if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) {
|
||||
X509_NAME_free(dpn->dpname);
|
||||
dpn->dpname = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* generate cached encoding of name */
|
||||
if (i2d_X509_NAME(dpn->dpname, NULL) < 0) {
|
||||
X509_NAME_free(dpn->dpname);
|
||||
dpn->dpname = NULL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_enum.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -61,37 +62,39 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static ENUMERATED_NAMES crl_reasons[] = {
|
||||
{CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
|
||||
{CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
|
||||
{CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
|
||||
{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
|
||||
{CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
|
||||
{CRL_REASON_CESSATION_OF_OPERATION,
|
||||
"Cessation Of Operation", "cessationOfOperation"},
|
||||
{CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
|
||||
{CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
|
||||
{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
|
||||
{CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
|
||||
{-1, NULL, NULL}
|
||||
{CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
|
||||
{CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
|
||||
{CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
|
||||
{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed",
|
||||
"affiliationChanged"},
|
||||
{CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
|
||||
{CRL_REASON_CESSATION_OF_OPERATION,
|
||||
"Cessation Of Operation", "cessationOfOperation"},
|
||||
{CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
|
||||
{CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
|
||||
{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn",
|
||||
"privilegeWithdrawn"},
|
||||
{CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
|
||||
{-1, NULL, NULL}
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_crl_reason = {
|
||||
NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
|
||||
0,0,0,0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
|
||||
0,
|
||||
0,0,0,0,
|
||||
crl_reasons};
|
||||
const X509V3_EXT_METHOD v3_crl_reason = {
|
||||
NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
|
||||
0, 0, 0, 0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
crl_reasons
|
||||
};
|
||||
|
||||
|
||||
char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method,
|
||||
ASN1_ENUMERATED *e)
|
||||
char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e)
|
||||
{
|
||||
ENUMERATED_NAMES *enam;
|
||||
long strval;
|
||||
strval = ASN1_ENUMERATED_get(e);
|
||||
for(enam = method->usr_data; enam->lname; enam++) {
|
||||
if(strval == enam->bitnum) return BUF_strdup(enam->lname);
|
||||
}
|
||||
return i2s_ASN1_ENUMERATED(method, e);
|
||||
ENUMERATED_NAMES *enam;
|
||||
long strval;
|
||||
strval = ASN1_ENUMERATED_get(e);
|
||||
for (enam = method->usr_data; enam->lname; enam++) {
|
||||
if (strval == enam->bitnum)
|
||||
return BUF_strdup(enam->lname);
|
||||
}
|
||||
return i2s_ASN1_ENUMERATED(method, e);
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_extku.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1t.h>
|
||||
@@ -64,81 +64,86 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval);
|
||||
static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
|
||||
void *eku, STACK_OF(CONF_VALUE) *extlist);
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval);
|
||||
static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
|
||||
*method, void *eku, STACK_OF(CONF_VALUE)
|
||||
*extlist);
|
||||
|
||||
const X509V3_EXT_METHOD v3_ext_ku = {
|
||||
NID_ext_key_usage, 0,
|
||||
ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
i2v_EXTENDED_KEY_USAGE,
|
||||
v2i_EXTENDED_KEY_USAGE,
|
||||
0,0,
|
||||
NULL
|
||||
NID_ext_key_usage, 0,
|
||||
ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
i2v_EXTENDED_KEY_USAGE,
|
||||
v2i_EXTENDED_KEY_USAGE,
|
||||
0, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
|
||||
const X509V3_EXT_METHOD v3_ocsp_accresp = {
|
||||
NID_id_pkix_OCSP_acceptableResponses, 0,
|
||||
ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
i2v_EXTENDED_KEY_USAGE,
|
||||
v2i_EXTENDED_KEY_USAGE,
|
||||
0,0,
|
||||
NULL
|
||||
NID_id_pkix_OCSP_acceptableResponses, 0,
|
||||
ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
i2v_EXTENDED_KEY_USAGE,
|
||||
v2i_EXTENDED_KEY_USAGE,
|
||||
0, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
|
||||
ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
|
||||
ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
|
||||
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a,
|
||||
STACK_OF(CONF_VALUE) *ext_list)
|
||||
static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
|
||||
*method, void *a, STACK_OF(CONF_VALUE)
|
||||
*ext_list)
|
||||
{
|
||||
EXTENDED_KEY_USAGE *eku = a;
|
||||
int i;
|
||||
ASN1_OBJECT *obj;
|
||||
char obj_tmp[80];
|
||||
for(i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
|
||||
obj = sk_ASN1_OBJECT_value(eku, i);
|
||||
i2t_ASN1_OBJECT(obj_tmp, 80, obj);
|
||||
X509V3_add_value(NULL, obj_tmp, &ext_list);
|
||||
}
|
||||
return ext_list;
|
||||
EXTENDED_KEY_USAGE *eku = a;
|
||||
int i;
|
||||
ASN1_OBJECT *obj;
|
||||
char obj_tmp[80];
|
||||
for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
|
||||
obj = sk_ASN1_OBJECT_value(eku, i);
|
||||
i2t_ASN1_OBJECT(obj_tmp, 80, obj);
|
||||
X509V3_add_value(NULL, obj_tmp, &ext_list);
|
||||
}
|
||||
return ext_list;
|
||||
}
|
||||
|
||||
static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
EXTENDED_KEY_USAGE *extku;
|
||||
char *extval;
|
||||
ASN1_OBJECT *objtmp;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
EXTENDED_KEY_USAGE *extku;
|
||||
char *extval;
|
||||
ASN1_OBJECT *objtmp;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
|
||||
if(!(extku = sk_ASN1_OBJECT_new_null())) {
|
||||
X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (!(extku = sk_ASN1_OBJECT_new_null())) {
|
||||
X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if(val->value) extval = val->value;
|
||||
else extval = val->name;
|
||||
if(!(objtmp = OBJ_txt2obj(extval, 0))) {
|
||||
sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
|
||||
X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(val);
|
||||
return NULL;
|
||||
}
|
||||
sk_ASN1_OBJECT_push(extku, objtmp);
|
||||
}
|
||||
return extku;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (val->value)
|
||||
extval = val->value;
|
||||
else
|
||||
extval = val->name;
|
||||
if (!(objtmp = OBJ_txt2obj(extval, 0))) {
|
||||
sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
|
||||
X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE,
|
||||
X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(val);
|
||||
return NULL;
|
||||
}
|
||||
sk_ASN1_OBJECT_push(extku, objtmp);
|
||||
}
|
||||
return extku;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_genn.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1t.h>
|
||||
@@ -64,189 +64,187 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
ASN1_SEQUENCE(OTHERNAME) = {
|
||||
ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
|
||||
/* Maybe have a true ANY DEFINED BY later */
|
||||
ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
|
||||
ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
|
||||
/* Maybe have a true ANY DEFINED BY later */
|
||||
ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
|
||||
} ASN1_SEQUENCE_END(OTHERNAME)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
|
||||
|
||||
ASN1_SEQUENCE(EDIPARTYNAME) = {
|
||||
ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
|
||||
ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
|
||||
ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
|
||||
ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
|
||||
} ASN1_SEQUENCE_END(EDIPARTYNAME)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
|
||||
|
||||
ASN1_CHOICE(GENERAL_NAME) = {
|
||||
ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
|
||||
ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
|
||||
ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
|
||||
/* Don't decode this */
|
||||
ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
|
||||
/* X509_NAME is a CHOICE type so use EXPLICIT */
|
||||
ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
|
||||
ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
|
||||
ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
|
||||
ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
|
||||
ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
|
||||
ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
|
||||
ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
|
||||
ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
|
||||
/* Don't decode this */
|
||||
ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
|
||||
/* X509_NAME is a CHOICE type so use EXPLICIT */
|
||||
ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
|
||||
ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
|
||||
ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
|
||||
ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
|
||||
ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
|
||||
} ASN1_CHOICE_END(GENERAL_NAME)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
|
||||
ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
|
||||
ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
|
||||
|
||||
GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
|
||||
{
|
||||
return (GENERAL_NAME *) ASN1_dup((i2d_of_void *) i2d_GENERAL_NAME,
|
||||
(d2i_of_void *) d2i_GENERAL_NAME,
|
||||
(char *) a);
|
||||
}
|
||||
{
|
||||
return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME,
|
||||
(d2i_of_void *)d2i_GENERAL_NAME,
|
||||
(char *)a);
|
||||
}
|
||||
|
||||
/* Returns 0 if they are equal, != 0 otherwise. */
|
||||
int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
|
||||
{
|
||||
int result = -1;
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (!a || !b || a->type != b->type) return -1;
|
||||
switch(a->type)
|
||||
{
|
||||
case GEN_X400:
|
||||
case GEN_EDIPARTY:
|
||||
result = ASN1_TYPE_cmp(a->d.other, b->d.other);
|
||||
break;
|
||||
if (!a || !b || a->type != b->type)
|
||||
return -1;
|
||||
switch (a->type) {
|
||||
case GEN_X400:
|
||||
case GEN_EDIPARTY:
|
||||
result = ASN1_TYPE_cmp(a->d.other, b->d.other);
|
||||
break;
|
||||
|
||||
case GEN_OTHERNAME:
|
||||
result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
|
||||
break;
|
||||
case GEN_OTHERNAME:
|
||||
result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
|
||||
break;
|
||||
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
case GEN_URI:
|
||||
result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
|
||||
break;
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
case GEN_URI:
|
||||
result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
|
||||
break;
|
||||
|
||||
case GEN_DIRNAME:
|
||||
result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
|
||||
break;
|
||||
case GEN_DIRNAME:
|
||||
result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
|
||||
break;
|
||||
|
||||
case GEN_IPADD:
|
||||
result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
|
||||
break;
|
||||
|
||||
case GEN_RID:
|
||||
result = OBJ_cmp(a->d.rid, b->d.rid);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case GEN_IPADD:
|
||||
result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
|
||||
break;
|
||||
|
||||
case GEN_RID:
|
||||
result = OBJ_cmp(a->d.rid, b->d.rid);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns 0 if they are equal, != 0 otherwise. */
|
||||
int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
|
||||
{
|
||||
int result = -1;
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (!a || !b) return -1;
|
||||
/* Check their type first. */
|
||||
if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
|
||||
return result;
|
||||
/* Check the value. */
|
||||
result = ASN1_TYPE_cmp(a->value, b->value);
|
||||
return result;
|
||||
}
|
||||
if (!a || !b)
|
||||
return -1;
|
||||
/* Check their type first. */
|
||||
if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
|
||||
return result;
|
||||
/* Check the value. */
|
||||
result = ASN1_TYPE_cmp(a->value, b->value);
|
||||
return result;
|
||||
}
|
||||
|
||||
void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case GEN_X400:
|
||||
case GEN_EDIPARTY:
|
||||
a->d.other = value;
|
||||
break;
|
||||
{
|
||||
switch (type) {
|
||||
case GEN_X400:
|
||||
case GEN_EDIPARTY:
|
||||
a->d.other = value;
|
||||
break;
|
||||
|
||||
case GEN_OTHERNAME:
|
||||
a->d.otherName = value;
|
||||
break;
|
||||
case GEN_OTHERNAME:
|
||||
a->d.otherName = value;
|
||||
break;
|
||||
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
case GEN_URI:
|
||||
a->d.ia5 = value;
|
||||
break;
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
case GEN_URI:
|
||||
a->d.ia5 = value;
|
||||
break;
|
||||
|
||||
case GEN_DIRNAME:
|
||||
a->d.dirn = value;
|
||||
break;
|
||||
case GEN_DIRNAME:
|
||||
a->d.dirn = value;
|
||||
break;
|
||||
|
||||
case GEN_IPADD:
|
||||
a->d.ip = value;
|
||||
break;
|
||||
|
||||
case GEN_RID:
|
||||
a->d.rid = value;
|
||||
break;
|
||||
}
|
||||
a->type = type;
|
||||
}
|
||||
case GEN_IPADD:
|
||||
a->d.ip = value;
|
||||
break;
|
||||
|
||||
case GEN_RID:
|
||||
a->d.rid = value;
|
||||
break;
|
||||
}
|
||||
a->type = type;
|
||||
}
|
||||
|
||||
void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
|
||||
{
|
||||
if (ptype)
|
||||
*ptype = a->type;
|
||||
switch(a->type)
|
||||
{
|
||||
case GEN_X400:
|
||||
case GEN_EDIPARTY:
|
||||
return a->d.other;
|
||||
{
|
||||
if (ptype)
|
||||
*ptype = a->type;
|
||||
switch (a->type) {
|
||||
case GEN_X400:
|
||||
case GEN_EDIPARTY:
|
||||
return a->d.other;
|
||||
|
||||
case GEN_OTHERNAME:
|
||||
return a->d.otherName;
|
||||
case GEN_OTHERNAME:
|
||||
return a->d.otherName;
|
||||
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
case GEN_URI:
|
||||
return a->d.ia5;
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
case GEN_URI:
|
||||
return a->d.ia5;
|
||||
|
||||
case GEN_DIRNAME:
|
||||
return a->d.dirn;
|
||||
case GEN_DIRNAME:
|
||||
return a->d.dirn;
|
||||
|
||||
case GEN_IPADD:
|
||||
return a->d.ip;
|
||||
|
||||
case GEN_RID:
|
||||
return a->d.rid;
|
||||
case GEN_IPADD:
|
||||
return a->d.ip;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
case GEN_RID:
|
||||
return a->d.rid;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
|
||||
ASN1_OBJECT *oid, ASN1_TYPE *value)
|
||||
{
|
||||
OTHERNAME *oth;
|
||||
oth = OTHERNAME_new();
|
||||
if (!oth)
|
||||
return 0;
|
||||
oth->type_id = oid;
|
||||
oth->value = value;
|
||||
GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
|
||||
ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
|
||||
{
|
||||
if (gen->type != GEN_OTHERNAME)
|
||||
return 0;
|
||||
if (poid)
|
||||
*poid = gen->d.otherName->type_id;
|
||||
if (pvalue)
|
||||
*pvalue = gen->d.otherName->value;
|
||||
return 1;
|
||||
}
|
||||
ASN1_OBJECT *oid, ASN1_TYPE *value)
|
||||
{
|
||||
OTHERNAME *oth;
|
||||
oth = OTHERNAME_new();
|
||||
if (!oth)
|
||||
return 0;
|
||||
oth->type_id = oid;
|
||||
oth->value = value;
|
||||
GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
|
||||
ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
|
||||
{
|
||||
if (gen->type != GEN_OTHERNAME)
|
||||
return 0;
|
||||
if (poid)
|
||||
*poid = gen->d.otherName->type_id;
|
||||
if (pvalue)
|
||||
*pvalue = gen->d.otherName->value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_ia5.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,61 +57,63 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5);
|
||||
static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
|
||||
const X509V3_EXT_METHOD v3_ns_ia5_list[] = {
|
||||
EXT_IA5STRING(NID_netscape_base_url),
|
||||
EXT_IA5STRING(NID_netscape_revocation_url),
|
||||
EXT_IA5STRING(NID_netscape_ca_revocation_url),
|
||||
EXT_IA5STRING(NID_netscape_renewal_url),
|
||||
EXT_IA5STRING(NID_netscape_ca_policy_url),
|
||||
EXT_IA5STRING(NID_netscape_ssl_server_name),
|
||||
EXT_IA5STRING(NID_netscape_comment),
|
||||
EXT_END
|
||||
static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
|
||||
ASN1_IA5STRING *ia5);
|
||||
static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *str);
|
||||
const X509V3_EXT_METHOD v3_ns_ia5_list[] = {
|
||||
EXT_IA5STRING(NID_netscape_base_url),
|
||||
EXT_IA5STRING(NID_netscape_revocation_url),
|
||||
EXT_IA5STRING(NID_netscape_ca_revocation_url),
|
||||
EXT_IA5STRING(NID_netscape_renewal_url),
|
||||
EXT_IA5STRING(NID_netscape_ca_policy_url),
|
||||
EXT_IA5STRING(NID_netscape_ssl_server_name),
|
||||
EXT_IA5STRING(NID_netscape_comment),
|
||||
EXT_END
|
||||
};
|
||||
|
||||
|
||||
static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
|
||||
ASN1_IA5STRING *ia5)
|
||||
ASN1_IA5STRING *ia5)
|
||||
{
|
||||
char *tmp;
|
||||
if(!ia5 || !ia5->length) return NULL;
|
||||
if(!(tmp = OPENSSL_malloc(ia5->length + 1))) {
|
||||
X509V3err(X509V3_F_I2S_ASN1_IA5STRING,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(tmp, ia5->data, ia5->length);
|
||||
tmp[ia5->length] = 0;
|
||||
return tmp;
|
||||
char *tmp;
|
||||
if (!ia5 || !ia5->length)
|
||||
return NULL;
|
||||
if (!(tmp = OPENSSL_malloc(ia5->length + 1))) {
|
||||
X509V3err(X509V3_F_I2S_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(tmp, ia5->data, ia5->length);
|
||||
tmp[ia5->length] = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *str)
|
||||
X509V3_CTX *ctx, char *str)
|
||||
{
|
||||
ASN1_IA5STRING *ia5;
|
||||
if(!str) {
|
||||
X509V3err(X509V3_F_S2I_ASN1_IA5STRING,X509V3_R_INVALID_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
if(!(ia5 = M_ASN1_IA5STRING_new())) goto err;
|
||||
if(!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str,
|
||||
strlen(str))) {
|
||||
M_ASN1_IA5STRING_free(ia5);
|
||||
goto err;
|
||||
}
|
||||
ASN1_IA5STRING *ia5;
|
||||
if (!str) {
|
||||
X509V3err(X509V3_F_S2I_ASN1_IA5STRING,
|
||||
X509V3_R_INVALID_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
if (!(ia5 = M_ASN1_IA5STRING_new()))
|
||||
goto err;
|
||||
if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char *)str,
|
||||
strlen(str))) {
|
||||
M_ASN1_IA5STRING_free(ia5);
|
||||
goto err;
|
||||
}
|
||||
#ifdef CHARSET_EBCDIC
|
||||
ebcdic2ascii(ia5->data, ia5->data, ia5->length);
|
||||
#endif /*CHARSET_EBCDIC*/
|
||||
return ia5;
|
||||
err:
|
||||
X509V3err(X509V3_F_S2I_ASN1_IA5STRING,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
ebcdic2ascii(ia5->data, ia5->data, ia5->length);
|
||||
#endif /* CHARSET_EBCDIC */
|
||||
return ia5;
|
||||
err:
|
||||
X509V3err(X509V3_F_S2I_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_info.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -63,131 +64,147 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
|
||||
AUTHORITY_INFO_ACCESS *ainfo,
|
||||
STACK_OF(CONF_VALUE) *ret);
|
||||
static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
|
||||
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
|
||||
*method, AUTHORITY_INFO_ACCESS
|
||||
*ainfo, STACK_OF(CONF_VALUE)
|
||||
*ret);
|
||||
static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
|
||||
*method,
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE)
|
||||
*nval);
|
||||
|
||||
const X509V3_EXT_METHOD v3_info =
|
||||
{ NID_info_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
|
||||
(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
|
||||
0,0,
|
||||
NULL};
|
||||
const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE,
|
||||
ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
(X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
|
||||
(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
|
||||
0, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_sinfo =
|
||||
{ NID_sinfo_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
|
||||
(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
|
||||
0,0,
|
||||
NULL};
|
||||
const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE,
|
||||
ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
(X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
|
||||
(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
|
||||
0, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
|
||||
ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
|
||||
ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
|
||||
ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
|
||||
ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
|
||||
} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
|
||||
ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
|
||||
ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
|
||||
|
||||
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
|
||||
AUTHORITY_INFO_ACCESS *ainfo,
|
||||
STACK_OF(CONF_VALUE) *ret)
|
||||
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
|
||||
*method, AUTHORITY_INFO_ACCESS
|
||||
*ainfo, STACK_OF(CONF_VALUE)
|
||||
*ret)
|
||||
{
|
||||
ACCESS_DESCRIPTION *desc;
|
||||
int i,nlen;
|
||||
char objtmp[80], *ntmp;
|
||||
CONF_VALUE *vtmp;
|
||||
for(i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
|
||||
desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
|
||||
ret = i2v_GENERAL_NAME(method, desc->location, ret);
|
||||
if(!ret) break;
|
||||
vtmp = sk_CONF_VALUE_value(ret, i);
|
||||
i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
|
||||
nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
|
||||
ntmp = OPENSSL_malloc(nlen);
|
||||
if(!ntmp) {
|
||||
X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
BUF_strlcpy(ntmp, objtmp, nlen);
|
||||
BUF_strlcat(ntmp, " - ", nlen);
|
||||
BUF_strlcat(ntmp, vtmp->name, nlen);
|
||||
OPENSSL_free(vtmp->name);
|
||||
vtmp->name = ntmp;
|
||||
|
||||
}
|
||||
if(!ret) return sk_CONF_VALUE_new_null();
|
||||
return ret;
|
||||
ACCESS_DESCRIPTION *desc;
|
||||
int i, nlen;
|
||||
char objtmp[80], *ntmp;
|
||||
CONF_VALUE *vtmp;
|
||||
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
|
||||
desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
|
||||
ret = i2v_GENERAL_NAME(method, desc->location, ret);
|
||||
if (!ret)
|
||||
break;
|
||||
vtmp = sk_CONF_VALUE_value(ret, i);
|
||||
i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
|
||||
nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
|
||||
ntmp = OPENSSL_malloc(nlen);
|
||||
if (!ntmp) {
|
||||
X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
BUF_strlcpy(ntmp, objtmp, nlen);
|
||||
BUF_strlcat(ntmp, " - ", nlen);
|
||||
BUF_strlcat(ntmp, vtmp->name, nlen);
|
||||
OPENSSL_free(vtmp->name);
|
||||
vtmp->name = ntmp;
|
||||
|
||||
}
|
||||
if (!ret)
|
||||
return sk_CONF_VALUE_new_null();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
|
||||
static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
|
||||
*method,
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE)
|
||||
*nval)
|
||||
{
|
||||
AUTHORITY_INFO_ACCESS *ainfo = NULL;
|
||||
CONF_VALUE *cnf, ctmp;
|
||||
ACCESS_DESCRIPTION *acc;
|
||||
int i, objlen;
|
||||
char *objtmp, *ptmp;
|
||||
if(!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if(!(acc = ACCESS_DESCRIPTION_new())
|
||||
|| !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ptmp = strchr(cnf->name, ';');
|
||||
if(!ptmp) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,X509V3_R_INVALID_SYNTAX);
|
||||
goto err;
|
||||
}
|
||||
objlen = ptmp - cnf->name;
|
||||
ctmp.name = ptmp + 1;
|
||||
ctmp.value = cnf->value;
|
||||
if(!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
|
||||
goto err;
|
||||
if(!(objtmp = OPENSSL_malloc(objlen + 1))) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
strncpy(objtmp, cnf->name, objlen);
|
||||
objtmp[objlen] = 0;
|
||||
acc->method = OBJ_txt2obj(objtmp, 0);
|
||||
if(!acc->method) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,X509V3_R_BAD_OBJECT);
|
||||
ERR_add_error_data(2, "value=", objtmp);
|
||||
OPENSSL_free(objtmp);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_free(objtmp);
|
||||
AUTHORITY_INFO_ACCESS *ainfo = NULL;
|
||||
CONF_VALUE *cnf, ctmp;
|
||||
ACCESS_DESCRIPTION *acc;
|
||||
int i, objlen;
|
||||
char *objtmp, *ptmp;
|
||||
if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if (!(acc = ACCESS_DESCRIPTION_new())
|
||||
|| !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ptmp = strchr(cnf->name, ';');
|
||||
if (!ptmp) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
|
||||
X509V3_R_INVALID_SYNTAX);
|
||||
goto err;
|
||||
}
|
||||
objlen = ptmp - cnf->name;
|
||||
ctmp.name = ptmp + 1;
|
||||
ctmp.value = cnf->value;
|
||||
if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
|
||||
goto err;
|
||||
if (!(objtmp = OPENSSL_malloc(objlen + 1))) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
strncpy(objtmp, cnf->name, objlen);
|
||||
objtmp[objlen] = 0;
|
||||
acc->method = OBJ_txt2obj(objtmp, 0);
|
||||
if (!acc->method) {
|
||||
X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
|
||||
X509V3_R_BAD_OBJECT);
|
||||
ERR_add_error_data(2, "value=", objtmp);
|
||||
OPENSSL_free(objtmp);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_free(objtmp);
|
||||
|
||||
}
|
||||
return ainfo;
|
||||
err:
|
||||
sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
|
||||
return NULL;
|
||||
}
|
||||
return ainfo;
|
||||
err:
|
||||
sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a)
|
||||
{
|
||||
i2a_ASN1_OBJECT(bp, a->method);
|
||||
int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a)
|
||||
{
|
||||
i2a_ASN1_OBJECT(bp, a->method);
|
||||
#ifdef UNDEF
|
||||
i2a_GENERAL_NAME(bp, a->location);
|
||||
i2a_GENERAL_NAME(bp, a->location);
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_int.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -60,30 +61,32 @@
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
const X509V3_EXT_METHOD v3_crl_num = {
|
||||
NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
|
||||
0,0,0,0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
|
||||
0,
|
||||
0,0,0,0, NULL};
|
||||
const X509V3_EXT_METHOD v3_crl_num = {
|
||||
NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
|
||||
0, 0, 0, 0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
|
||||
0,
|
||||
0, 0, 0, 0, NULL
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_delta_crl = {
|
||||
NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
|
||||
0,0,0,0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
|
||||
0,
|
||||
0,0,0,0, NULL};
|
||||
|
||||
static void * s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value)
|
||||
{
|
||||
return s2i_ASN1_INTEGER(meth, value);
|
||||
}
|
||||
|
||||
const X509V3_EXT_METHOD v3_inhibit_anyp = {
|
||||
NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
|
||||
0,0,0,0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
|
||||
(X509V3_EXT_S2I)s2i_asn1_int,
|
||||
0,0,0,0, NULL};
|
||||
const X509V3_EXT_METHOD v3_delta_crl = {
|
||||
NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
|
||||
0, 0, 0, 0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
|
||||
0,
|
||||
0, 0, 0, 0, NULL
|
||||
};
|
||||
|
||||
static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx,
|
||||
char *value)
|
||||
{
|
||||
return s2i_ASN1_INTEGER(meth, value);
|
||||
}
|
||||
|
||||
const X509V3_EXT_METHOD v3_inhibit_anyp = {
|
||||
NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
|
||||
0, 0, 0, 0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
|
||||
(X509V3_EXT_S2I)s2i_asn1_int,
|
||||
0, 0, 0, 0, NULL
|
||||
};
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_lib.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -66,117 +67,153 @@
|
||||
|
||||
static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
|
||||
|
||||
static int ext_cmp(const X509V3_EXT_METHOD * const *a,
|
||||
const X509V3_EXT_METHOD * const *b);
|
||||
static int ext_cmp(const X509V3_EXT_METHOD *const *a,
|
||||
const X509V3_EXT_METHOD *const *b);
|
||||
static void ext_list_free(X509V3_EXT_METHOD *ext);
|
||||
|
||||
int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
|
||||
{
|
||||
if(!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if(!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ext_cmp(const X509V3_EXT_METHOD * const *a,
|
||||
const X509V3_EXT_METHOD * const *b)
|
||||
static int ext_cmp(const X509V3_EXT_METHOD *const *a,
|
||||
const X509V3_EXT_METHOD *const *b)
|
||||
{
|
||||
return ((*a)->ext_nid - (*b)->ext_nid);
|
||||
return ((*a)->ext_nid - (*b)->ext_nid);
|
||||
}
|
||||
|
||||
DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, const X509V3_EXT_METHOD *,
|
||||
ext);
|
||||
DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
|
||||
const X509V3_EXT_METHOD *, ext);
|
||||
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
|
||||
const X509V3_EXT_METHOD *, ext);
|
||||
const X509V3_EXT_METHOD *, ext);
|
||||
|
||||
const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
|
||||
{
|
||||
X509V3_EXT_METHOD tmp;
|
||||
const X509V3_EXT_METHOD *t = &tmp, * const *ret;
|
||||
int idx;
|
||||
if(nid < 0) return NULL;
|
||||
tmp.ext_nid = nid;
|
||||
ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
|
||||
if(ret) return *ret;
|
||||
if(!ext_list) return NULL;
|
||||
idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
|
||||
if(idx == -1) return NULL;
|
||||
return sk_X509V3_EXT_METHOD_value(ext_list, idx);
|
||||
X509V3_EXT_METHOD tmp;
|
||||
const X509V3_EXT_METHOD *t = &tmp, *const *ret;
|
||||
int idx;
|
||||
if (nid < 0)
|
||||
return NULL;
|
||||
tmp.ext_nid = nid;
|
||||
ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
|
||||
if (ret)
|
||||
return *ret;
|
||||
if (!ext_list)
|
||||
return NULL;
|
||||
idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
|
||||
if (idx == -1)
|
||||
return NULL;
|
||||
return sk_X509V3_EXT_METHOD_value(ext_list, idx);
|
||||
}
|
||||
|
||||
const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
|
||||
{
|
||||
int nid;
|
||||
if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL;
|
||||
return X509V3_EXT_get_nid(nid);
|
||||
int nid;
|
||||
if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
|
||||
return NULL;
|
||||
return X509V3_EXT_get_nid(nid);
|
||||
}
|
||||
|
||||
int X509V3_EXT_free(int nid, void *ext_data)
|
||||
{
|
||||
const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid);
|
||||
if (ext_method == NULL) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_FREE,
|
||||
X509V3_R_CANNOT_FIND_FREE_FUNCTION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ext_method->it != NULL)
|
||||
ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it));
|
||||
else if (ext_method->ext_free != NULL)
|
||||
ext_method->ext_free(ext_data);
|
||||
else {
|
||||
X509V3err(X509V3_F_X509V3_EXT_FREE,
|
||||
X509V3_R_CANNOT_FIND_FREE_FUNCTION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
|
||||
{
|
||||
for(;extlist->ext_nid!=-1;extlist++)
|
||||
if(!X509V3_EXT_add(extlist)) return 0;
|
||||
return 1;
|
||||
for (; extlist->ext_nid != -1; extlist++)
|
||||
if (!X509V3_EXT_add(extlist))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int X509V3_EXT_add_alias(int nid_to, int nid_from)
|
||||
{
|
||||
const X509V3_EXT_METHOD *ext;
|
||||
X509V3_EXT_METHOD *tmpext;
|
||||
const X509V3_EXT_METHOD *ext;
|
||||
X509V3_EXT_METHOD *tmpext;
|
||||
|
||||
if(!(ext = X509V3_EXT_get_nid(nid_from))) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,X509V3_R_EXTENSION_NOT_FOUND);
|
||||
return 0;
|
||||
}
|
||||
if(!(tmpext = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
*tmpext = *ext;
|
||||
tmpext->ext_nid = nid_to;
|
||||
tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
|
||||
return X509V3_EXT_add(tmpext);
|
||||
if (!(ext = X509V3_EXT_get_nid(nid_from))) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,
|
||||
X509V3_R_EXTENSION_NOT_FOUND);
|
||||
return 0;
|
||||
}
|
||||
if (!
|
||||
(tmpext =
|
||||
(X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
|
||||
X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
*tmpext = *ext;
|
||||
tmpext->ext_nid = nid_to;
|
||||
tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
|
||||
return X509V3_EXT_add(tmpext);
|
||||
}
|
||||
|
||||
void X509V3_EXT_cleanup(void)
|
||||
{
|
||||
sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
|
||||
ext_list = NULL;
|
||||
sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
|
||||
ext_list = NULL;
|
||||
}
|
||||
|
||||
static void ext_list_free(X509V3_EXT_METHOD *ext)
|
||||
{
|
||||
if(ext->ext_flags & X509V3_EXT_DYNAMIC) OPENSSL_free(ext);
|
||||
if (ext->ext_flags & X509V3_EXT_DYNAMIC)
|
||||
OPENSSL_free(ext);
|
||||
}
|
||||
|
||||
/* Legacy function: we don't need to add standard extensions
|
||||
* any more because they are now kept in ext_dat.h.
|
||||
/*
|
||||
* Legacy function: we don't need to add standard extensions any more because
|
||||
* they are now kept in ext_dat.h.
|
||||
*/
|
||||
|
||||
int X509V3_add_standard_extensions(void)
|
||||
{
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return an extension internal structure */
|
||||
|
||||
void *X509V3_EXT_d2i(X509_EXTENSION *ext)
|
||||
{
|
||||
const X509V3_EXT_METHOD *method;
|
||||
const unsigned char *p;
|
||||
const X509V3_EXT_METHOD *method;
|
||||
const unsigned char *p;
|
||||
|
||||
if(!(method = X509V3_EXT_get(ext))) return NULL;
|
||||
p = ext->value->data;
|
||||
if(method->it) return ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
|
||||
return method->d2i(NULL, &p, ext->value->length);
|
||||
if (!(method = X509V3_EXT_get(ext)))
|
||||
return NULL;
|
||||
p = ext->value->data;
|
||||
if (method->it)
|
||||
return ASN1_item_d2i(NULL, &p, ext->value->length,
|
||||
ASN1_ITEM_ptr(method->it));
|
||||
return method->d2i(NULL, &p, ext->value->length);
|
||||
}
|
||||
|
||||
/* Get critical flag and decoded version of extension from a NID.
|
||||
/*-
|
||||
* Get critical flag and decoded version of extension from a NID.
|
||||
* The "idx" variable returns the last found extension and can
|
||||
* be used to retrieve multiple extensions of the same NID.
|
||||
* However multiple extensions with the same NID is usually
|
||||
@@ -191,119 +228,136 @@ void *X509V3_EXT_d2i(X509_EXTENSION *ext)
|
||||
* -2 extension occurs more than once.
|
||||
*/
|
||||
|
||||
void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx)
|
||||
void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
|
||||
int *idx)
|
||||
{
|
||||
int lastpos, i;
|
||||
X509_EXTENSION *ex, *found_ex = NULL;
|
||||
if(!x) {
|
||||
if(idx) *idx = -1;
|
||||
if(crit) *crit = -1;
|
||||
return NULL;
|
||||
}
|
||||
if(idx) lastpos = *idx + 1;
|
||||
else lastpos = 0;
|
||||
if(lastpos < 0) lastpos = 0;
|
||||
for(i = lastpos; i < sk_X509_EXTENSION_num(x); i++)
|
||||
{
|
||||
ex = sk_X509_EXTENSION_value(x, i);
|
||||
if(OBJ_obj2nid(ex->object) == nid) {
|
||||
if(idx) {
|
||||
*idx = i;
|
||||
found_ex = ex;
|
||||
break;
|
||||
} else if(found_ex) {
|
||||
/* Found more than one */
|
||||
if(crit) *crit = -2;
|
||||
return NULL;
|
||||
}
|
||||
found_ex = ex;
|
||||
}
|
||||
}
|
||||
if(found_ex) {
|
||||
/* Found it */
|
||||
if(crit) *crit = X509_EXTENSION_get_critical(found_ex);
|
||||
return X509V3_EXT_d2i(found_ex);
|
||||
}
|
||||
int lastpos, i;
|
||||
X509_EXTENSION *ex, *found_ex = NULL;
|
||||
if (!x) {
|
||||
if (idx)
|
||||
*idx = -1;
|
||||
if (crit)
|
||||
*crit = -1;
|
||||
return NULL;
|
||||
}
|
||||
if (idx)
|
||||
lastpos = *idx + 1;
|
||||
else
|
||||
lastpos = 0;
|
||||
if (lastpos < 0)
|
||||
lastpos = 0;
|
||||
for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) {
|
||||
ex = sk_X509_EXTENSION_value(x, i);
|
||||
if (OBJ_obj2nid(ex->object) == nid) {
|
||||
if (idx) {
|
||||
*idx = i;
|
||||
found_ex = ex;
|
||||
break;
|
||||
} else if (found_ex) {
|
||||
/* Found more than one */
|
||||
if (crit)
|
||||
*crit = -2;
|
||||
return NULL;
|
||||
}
|
||||
found_ex = ex;
|
||||
}
|
||||
}
|
||||
if (found_ex) {
|
||||
/* Found it */
|
||||
if (crit)
|
||||
*crit = X509_EXTENSION_get_critical(found_ex);
|
||||
return X509V3_EXT_d2i(found_ex);
|
||||
}
|
||||
|
||||
/* Extension not found */
|
||||
if(idx) *idx = -1;
|
||||
if(crit) *crit = -1;
|
||||
return NULL;
|
||||
/* Extension not found */
|
||||
if (idx)
|
||||
*idx = -1;
|
||||
if (crit)
|
||||
*crit = -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This function is a general extension append, replace and delete utility.
|
||||
/*
|
||||
* This function is a general extension append, replace and delete utility.
|
||||
* The precise operation is governed by the 'flags' value. The 'crit' and
|
||||
* 'value' arguments (if relevant) are the extensions internal structure.
|
||||
*/
|
||||
|
||||
int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
|
||||
int crit, unsigned long flags)
|
||||
int crit, unsigned long flags)
|
||||
{
|
||||
int extidx = -1;
|
||||
int errcode;
|
||||
X509_EXTENSION *ext, *extmp;
|
||||
unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
|
||||
int extidx = -1;
|
||||
int errcode;
|
||||
X509_EXTENSION *ext, *extmp;
|
||||
unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
|
||||
|
||||
/* If appending we don't care if it exists, otherwise
|
||||
* look for existing extension.
|
||||
*/
|
||||
if(ext_op != X509V3_ADD_APPEND)
|
||||
extidx = X509v3_get_ext_by_NID(*x, nid, -1);
|
||||
/*
|
||||
* If appending we don't care if it exists, otherwise look for existing
|
||||
* extension.
|
||||
*/
|
||||
if (ext_op != X509V3_ADD_APPEND)
|
||||
extidx = X509v3_get_ext_by_NID(*x, nid, -1);
|
||||
|
||||
/* See if extension exists */
|
||||
if(extidx >= 0) {
|
||||
/* If keep existing, nothing to do */
|
||||
if(ext_op == X509V3_ADD_KEEP_EXISTING)
|
||||
return 1;
|
||||
/* If default then its an error */
|
||||
if(ext_op == X509V3_ADD_DEFAULT) {
|
||||
errcode = X509V3_R_EXTENSION_EXISTS;
|
||||
goto err;
|
||||
}
|
||||
/* If delete, just delete it */
|
||||
if(ext_op == X509V3_ADD_DELETE) {
|
||||
if(!sk_X509_EXTENSION_delete(*x, extidx)) return -1;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/* If replace existing or delete, error since
|
||||
* extension must exist
|
||||
*/
|
||||
if((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
|
||||
(ext_op == X509V3_ADD_DELETE)) {
|
||||
errcode = X509V3_R_EXTENSION_NOT_FOUND;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
/* See if extension exists */
|
||||
if (extidx >= 0) {
|
||||
/* If keep existing, nothing to do */
|
||||
if (ext_op == X509V3_ADD_KEEP_EXISTING)
|
||||
return 1;
|
||||
/* If default then its an error */
|
||||
if (ext_op == X509V3_ADD_DEFAULT) {
|
||||
errcode = X509V3_R_EXTENSION_EXISTS;
|
||||
goto err;
|
||||
}
|
||||
/* If delete, just delete it */
|
||||
if (ext_op == X509V3_ADD_DELETE) {
|
||||
if (!sk_X509_EXTENSION_delete(*x, extidx))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* If replace existing or delete, error since extension must exist
|
||||
*/
|
||||
if ((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
|
||||
(ext_op == X509V3_ADD_DELETE)) {
|
||||
errcode = X509V3_R_EXTENSION_NOT_FOUND;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we get this far then we have to create an extension:
|
||||
* could have some flags for alternative encoding schemes...
|
||||
*/
|
||||
/*
|
||||
* If we get this far then we have to create an extension: could have
|
||||
* some flags for alternative encoding schemes...
|
||||
*/
|
||||
|
||||
ext = X509V3_EXT_i2d(nid, crit, value);
|
||||
ext = X509V3_EXT_i2d(nid, crit, value);
|
||||
|
||||
if(!ext) {
|
||||
X509V3err(X509V3_F_X509V3_ADD1_I2D, X509V3_R_ERROR_CREATING_EXTENSION);
|
||||
return 0;
|
||||
}
|
||||
if (!ext) {
|
||||
X509V3err(X509V3_F_X509V3_ADD1_I2D,
|
||||
X509V3_R_ERROR_CREATING_EXTENSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If extension exists replace it.. */
|
||||
if(extidx >= 0) {
|
||||
extmp = sk_X509_EXTENSION_value(*x, extidx);
|
||||
X509_EXTENSION_free(extmp);
|
||||
if(!sk_X509_EXTENSION_set(*x, extidx, ext)) return -1;
|
||||
return 1;
|
||||
}
|
||||
/* If extension exists replace it.. */
|
||||
if (extidx >= 0) {
|
||||
extmp = sk_X509_EXTENSION_value(*x, extidx);
|
||||
X509_EXTENSION_free(extmp);
|
||||
if (!sk_X509_EXTENSION_set(*x, extidx, ext))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!*x && !(*x = sk_X509_EXTENSION_new_null())) return -1;
|
||||
if(!sk_X509_EXTENSION_push(*x, ext)) return -1;
|
||||
if (!*x && !(*x = sk_X509_EXTENSION_new_null()))
|
||||
return -1;
|
||||
if (!sk_X509_EXTENSION_push(*x, ext))
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
if(!(flags & X509V3_ADD_SILENT))
|
||||
X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode);
|
||||
return 0;
|
||||
err:
|
||||
if (!(flags & X509V3_ADD_SILENT))
|
||||
X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_STACK_OF(X509V3_EXT_METHOD)
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,6 @@
|
||||
/* v3_ncons.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1t.h>
|
||||
@@ -64,12 +64,13 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
|
||||
static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
void *a, BIO *bp, int ind);
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval);
|
||||
static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
|
||||
BIO *bp, int ind);
|
||||
static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
|
||||
STACK_OF(GENERAL_SUBTREE) *trees,
|
||||
BIO *bp, int ind, char *name);
|
||||
STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp,
|
||||
int ind, char *name);
|
||||
static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
|
||||
|
||||
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
|
||||
@@ -80,151 +81,136 @@ static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
|
||||
static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
|
||||
|
||||
const X509V3_EXT_METHOD v3_name_constraints = {
|
||||
NID_name_constraints, 0,
|
||||
ASN1_ITEM_ref(NAME_CONSTRAINTS),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0, v2i_NAME_CONSTRAINTS,
|
||||
i2r_NAME_CONSTRAINTS,0,
|
||||
NULL
|
||||
NID_name_constraints, 0,
|
||||
ASN1_ITEM_ref(NAME_CONSTRAINTS),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0, v2i_NAME_CONSTRAINTS,
|
||||
i2r_NAME_CONSTRAINTS, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
ASN1_SEQUENCE(GENERAL_SUBTREE) = {
|
||||
ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
|
||||
ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
|
||||
ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
|
||||
ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
|
||||
ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
|
||||
ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
|
||||
} ASN1_SEQUENCE_END(GENERAL_SUBTREE)
|
||||
|
||||
ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
|
||||
ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
|
||||
GENERAL_SUBTREE, 0),
|
||||
ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
|
||||
GENERAL_SUBTREE, 1),
|
||||
ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
|
||||
GENERAL_SUBTREE, 0),
|
||||
ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
|
||||
GENERAL_SUBTREE, 1),
|
||||
} ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
|
||||
|
||||
|
||||
|
||||
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
|
||||
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
|
||||
|
||||
static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
int i;
|
||||
CONF_VALUE tval, *val;
|
||||
STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
|
||||
NAME_CONSTRAINTS *ncons = NULL;
|
||||
GENERAL_SUBTREE *sub = NULL;
|
||||
ncons = NAME_CONSTRAINTS_new();
|
||||
if (!ncons)
|
||||
goto memerr;
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
|
||||
{
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (!strncmp(val->name, "permitted", 9) && val->name[9])
|
||||
{
|
||||
ptree = &ncons->permittedSubtrees;
|
||||
tval.name = val->name + 10;
|
||||
}
|
||||
else if (!strncmp(val->name, "excluded", 8) && val->name[8])
|
||||
{
|
||||
ptree = &ncons->excludedSubtrees;
|
||||
tval.name = val->name + 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
|
||||
goto err;
|
||||
}
|
||||
tval.value = val->value;
|
||||
sub = GENERAL_SUBTREE_new();
|
||||
if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
|
||||
goto err;
|
||||
if (!*ptree)
|
||||
*ptree = sk_GENERAL_SUBTREE_new_null();
|
||||
if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
|
||||
goto memerr;
|
||||
sub = NULL;
|
||||
}
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
int i;
|
||||
CONF_VALUE tval, *val;
|
||||
STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
|
||||
NAME_CONSTRAINTS *ncons = NULL;
|
||||
GENERAL_SUBTREE *sub = NULL;
|
||||
ncons = NAME_CONSTRAINTS_new();
|
||||
if (!ncons)
|
||||
goto memerr;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (!strncmp(val->name, "permitted", 9) && val->name[9]) {
|
||||
ptree = &ncons->permittedSubtrees;
|
||||
tval.name = val->name + 10;
|
||||
} else if (!strncmp(val->name, "excluded", 8) && val->name[8]) {
|
||||
ptree = &ncons->excludedSubtrees;
|
||||
tval.name = val->name + 9;
|
||||
} else {
|
||||
X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
|
||||
goto err;
|
||||
}
|
||||
tval.value = val->value;
|
||||
sub = GENERAL_SUBTREE_new();
|
||||
if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
|
||||
goto err;
|
||||
if (!*ptree)
|
||||
*ptree = sk_GENERAL_SUBTREE_new_null();
|
||||
if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
|
||||
goto memerr;
|
||||
sub = NULL;
|
||||
}
|
||||
|
||||
return ncons;
|
||||
return ncons;
|
||||
|
||||
memerr:
|
||||
X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
if (ncons)
|
||||
NAME_CONSTRAINTS_free(ncons);
|
||||
if (sub)
|
||||
GENERAL_SUBTREE_free(sub);
|
||||
memerr:
|
||||
X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
if (ncons)
|
||||
NAME_CONSTRAINTS_free(ncons);
|
||||
if (sub)
|
||||
GENERAL_SUBTREE_free(sub);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
|
||||
BIO *bp, int ind)
|
||||
{
|
||||
NAME_CONSTRAINTS *ncons = a;
|
||||
do_i2r_name_constraints(method, ncons->permittedSubtrees,
|
||||
bp, ind, "Permitted");
|
||||
do_i2r_name_constraints(method, ncons->excludedSubtrees,
|
||||
bp, ind, "Excluded");
|
||||
return 1;
|
||||
}
|
||||
BIO *bp, int ind)
|
||||
{
|
||||
NAME_CONSTRAINTS *ncons = a;
|
||||
do_i2r_name_constraints(method, ncons->permittedSubtrees,
|
||||
bp, ind, "Permitted");
|
||||
do_i2r_name_constraints(method, ncons->excludedSubtrees,
|
||||
bp, ind, "Excluded");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
|
||||
STACK_OF(GENERAL_SUBTREE) *trees,
|
||||
BIO *bp, int ind, char *name)
|
||||
{
|
||||
GENERAL_SUBTREE *tree;
|
||||
int i;
|
||||
if (sk_GENERAL_SUBTREE_num(trees) > 0)
|
||||
BIO_printf(bp, "%*s%s:\n", ind, "", name);
|
||||
for(i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++)
|
||||
{
|
||||
tree = sk_GENERAL_SUBTREE_value(trees, i);
|
||||
BIO_printf(bp, "%*s", ind + 2, "");
|
||||
if (tree->base->type == GEN_IPADD)
|
||||
print_nc_ipadd(bp, tree->base->d.ip);
|
||||
else
|
||||
GENERAL_NAME_print(bp, tree->base);
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
STACK_OF(GENERAL_SUBTREE) *trees,
|
||||
BIO *bp, int ind, char *name)
|
||||
{
|
||||
GENERAL_SUBTREE *tree;
|
||||
int i;
|
||||
if (sk_GENERAL_SUBTREE_num(trees) > 0)
|
||||
BIO_printf(bp, "%*s%s:\n", ind, "", name);
|
||||
for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) {
|
||||
tree = sk_GENERAL_SUBTREE_value(trees, i);
|
||||
BIO_printf(bp, "%*s", ind + 2, "");
|
||||
if (tree->base->type == GEN_IPADD)
|
||||
print_nc_ipadd(bp, tree->base->d.ip);
|
||||
else
|
||||
GENERAL_NAME_print(bp, tree->base);
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
|
||||
{
|
||||
int i, len;
|
||||
unsigned char *p;
|
||||
p = ip->data;
|
||||
len = ip->length;
|
||||
BIO_puts(bp, "IP:");
|
||||
if(len == 8)
|
||||
{
|
||||
BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
|
||||
p[0], p[1], p[2], p[3],
|
||||
p[4], p[5], p[6], p[7]);
|
||||
}
|
||||
else if(len == 32)
|
||||
{
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
BIO_printf(bp, "%X", p[0] << 8 | p[1]);
|
||||
p += 2;
|
||||
if (i == 7)
|
||||
BIO_puts(bp, "/");
|
||||
else if (i != 15)
|
||||
BIO_puts(bp, ":");
|
||||
}
|
||||
}
|
||||
else
|
||||
BIO_printf(bp, "IP Address:<invalid>");
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
int i, len;
|
||||
unsigned char *p;
|
||||
p = ip->data;
|
||||
len = ip->length;
|
||||
BIO_puts(bp, "IP:");
|
||||
if (len == 8) {
|
||||
BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||
} else if (len == 32) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
BIO_printf(bp, "%X", p[0] << 8 | p[1]);
|
||||
p += 2;
|
||||
if (i == 7)
|
||||
BIO_puts(bp, "/");
|
||||
else if (i != 15)
|
||||
BIO_puts(bp, ":");
|
||||
}
|
||||
} else
|
||||
BIO_printf(bp, "IP Address:<invalid>");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check a certificate conforms to a specified set of constraints.
|
||||
/*-
|
||||
* Check a certificate conforms to a specified set of constraints.
|
||||
* Return values:
|
||||
* X509_V_OK: All constraints obeyed.
|
||||
* X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
|
||||
@@ -233,273 +219,259 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
|
||||
* X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type.
|
||||
* X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
|
||||
* X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
|
||||
|
||||
*/
|
||||
|
||||
int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
|
||||
{
|
||||
int r, i;
|
||||
X509_NAME *nm;
|
||||
{
|
||||
int r, i;
|
||||
X509_NAME *nm;
|
||||
|
||||
nm = X509_get_subject_name(x);
|
||||
nm = X509_get_subject_name(x);
|
||||
|
||||
if (X509_NAME_entry_count(nm) > 0)
|
||||
{
|
||||
GENERAL_NAME gntmp;
|
||||
gntmp.type = GEN_DIRNAME;
|
||||
gntmp.d.directoryName = nm;
|
||||
if (X509_NAME_entry_count(nm) > 0) {
|
||||
GENERAL_NAME gntmp;
|
||||
gntmp.type = GEN_DIRNAME;
|
||||
gntmp.d.directoryName = nm;
|
||||
|
||||
r = nc_match(&gntmp, nc);
|
||||
r = nc_match(&gntmp, nc);
|
||||
|
||||
if (r != X509_V_OK)
|
||||
return r;
|
||||
if (r != X509_V_OK)
|
||||
return r;
|
||||
|
||||
gntmp.type = GEN_EMAIL;
|
||||
gntmp.type = GEN_EMAIL;
|
||||
|
||||
/* Process any email address attributes in subject name */
|
||||
|
||||
/* Process any email address attributes in subject name */
|
||||
for (i = -1;;) {
|
||||
X509_NAME_ENTRY *ne;
|
||||
i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i);
|
||||
if (i == -1)
|
||||
break;
|
||||
ne = X509_NAME_get_entry(nm, i);
|
||||
gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
|
||||
if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
|
||||
for (i = -1;;)
|
||||
{
|
||||
X509_NAME_ENTRY *ne;
|
||||
i = X509_NAME_get_index_by_NID(nm,
|
||||
NID_pkcs9_emailAddress,
|
||||
i);
|
||||
if (i == -1)
|
||||
break;
|
||||
ne = X509_NAME_get_entry(nm, i);
|
||||
gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
|
||||
if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
r = nc_match(&gntmp, nc);
|
||||
|
||||
r = nc_match(&gntmp, nc);
|
||||
if (r != X509_V_OK)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (r != X509_V_OK)
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++)
|
||||
{
|
||||
GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
|
||||
r = nc_match(gen, nc);
|
||||
if (r != X509_V_OK)
|
||||
return r;
|
||||
}
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) {
|
||||
GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
|
||||
r = nc_match(gen, nc);
|
||||
if (r != X509_V_OK)
|
||||
return r;
|
||||
}
|
||||
|
||||
return X509_V_OK;
|
||||
return X509_V_OK;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
|
||||
{
|
||||
GENERAL_SUBTREE *sub;
|
||||
int i, r, match = 0;
|
||||
{
|
||||
GENERAL_SUBTREE *sub;
|
||||
int i, r, match = 0;
|
||||
|
||||
/* Permitted subtrees: if any subtrees exist of matching the type
|
||||
* at least one subtree must match.
|
||||
*/
|
||||
/*
|
||||
* Permitted subtrees: if any subtrees exist of matching the type at
|
||||
* least one subtree must match.
|
||||
*/
|
||||
|
||||
for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++)
|
||||
{
|
||||
sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
|
||||
if (gen->type != sub->base->type)
|
||||
continue;
|
||||
if (sub->minimum || sub->maximum)
|
||||
return X509_V_ERR_SUBTREE_MINMAX;
|
||||
/* If we already have a match don't bother trying any more */
|
||||
if (match == 2)
|
||||
continue;
|
||||
if (match == 0)
|
||||
match = 1;
|
||||
r = nc_match_single(gen, sub->base);
|
||||
if (r == X509_V_OK)
|
||||
match = 2;
|
||||
else if (r != X509_V_ERR_PERMITTED_VIOLATION)
|
||||
return r;
|
||||
}
|
||||
for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
|
||||
sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
|
||||
if (gen->type != sub->base->type)
|
||||
continue;
|
||||
if (sub->minimum || sub->maximum)
|
||||
return X509_V_ERR_SUBTREE_MINMAX;
|
||||
/* If we already have a match don't bother trying any more */
|
||||
if (match == 2)
|
||||
continue;
|
||||
if (match == 0)
|
||||
match = 1;
|
||||
r = nc_match_single(gen, sub->base);
|
||||
if (r == X509_V_OK)
|
||||
match = 2;
|
||||
else if (r != X509_V_ERR_PERMITTED_VIOLATION)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (match == 1)
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
if (match == 1)
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
/* Excluded subtrees: must not match any of these */
|
||||
/* Excluded subtrees: must not match any of these */
|
||||
|
||||
for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++)
|
||||
{
|
||||
sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
|
||||
if (gen->type != sub->base->type)
|
||||
continue;
|
||||
if (sub->minimum || sub->maximum)
|
||||
return X509_V_ERR_SUBTREE_MINMAX;
|
||||
for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
|
||||
sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
|
||||
if (gen->type != sub->base->type)
|
||||
continue;
|
||||
if (sub->minimum || sub->maximum)
|
||||
return X509_V_ERR_SUBTREE_MINMAX;
|
||||
|
||||
r = nc_match_single(gen, sub->base);
|
||||
if (r == X509_V_OK)
|
||||
return X509_V_ERR_EXCLUDED_VIOLATION;
|
||||
else if (r != X509_V_ERR_PERMITTED_VIOLATION)
|
||||
return r;
|
||||
r = nc_match_single(gen, sub->base);
|
||||
if (r == X509_V_OK)
|
||||
return X509_V_ERR_EXCLUDED_VIOLATION;
|
||||
else if (r != X509_V_ERR_PERMITTED_VIOLATION)
|
||||
return r;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return X509_V_OK;
|
||||
return X509_V_OK;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
|
||||
{
|
||||
switch(base->type)
|
||||
{
|
||||
case GEN_DIRNAME:
|
||||
return nc_dn(gen->d.directoryName, base->d.directoryName);
|
||||
{
|
||||
switch (base->type) {
|
||||
case GEN_DIRNAME:
|
||||
return nc_dn(gen->d.directoryName, base->d.directoryName);
|
||||
|
||||
case GEN_DNS:
|
||||
return nc_dns(gen->d.dNSName, base->d.dNSName);
|
||||
case GEN_DNS:
|
||||
return nc_dns(gen->d.dNSName, base->d.dNSName);
|
||||
|
||||
case GEN_EMAIL:
|
||||
return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
|
||||
case GEN_EMAIL:
|
||||
return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
|
||||
|
||||
case GEN_URI:
|
||||
return nc_uri(gen->d.uniformResourceIdentifier,
|
||||
base->d.uniformResourceIdentifier);
|
||||
case GEN_URI:
|
||||
return nc_uri(gen->d.uniformResourceIdentifier,
|
||||
base->d.uniformResourceIdentifier);
|
||||
|
||||
default:
|
||||
return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
|
||||
}
|
||||
default:
|
||||
return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* directoryName name constraint matching.
|
||||
* The canonical encoding of X509_NAME makes this comparison easy. It is
|
||||
* matched if the subtree is a subset of the name.
|
||||
/*
|
||||
* directoryName name constraint matching. The canonical encoding of
|
||||
* X509_NAME makes this comparison easy. It is matched if the subtree is a
|
||||
* subset of the name.
|
||||
*/
|
||||
|
||||
static int nc_dn(X509_NAME *nm, X509_NAME *base)
|
||||
{
|
||||
/* Ensure canonical encodings are up to date. */
|
||||
if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
|
||||
return X509_V_ERR_OUT_OF_MEM;
|
||||
if (base->modified && i2d_X509_NAME(base, NULL) < 0)
|
||||
return X509_V_ERR_OUT_OF_MEM;
|
||||
if (base->canon_enclen > nm->canon_enclen)
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
return X509_V_OK;
|
||||
}
|
||||
{
|
||||
/* Ensure canonical encodings are up to date. */
|
||||
if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
|
||||
return X509_V_ERR_OUT_OF_MEM;
|
||||
if (base->modified && i2d_X509_NAME(base, NULL) < 0)
|
||||
return X509_V_ERR_OUT_OF_MEM;
|
||||
if (base->canon_enclen > nm->canon_enclen)
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
return X509_V_OK;
|
||||
}
|
||||
|
||||
static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
|
||||
{
|
||||
char *baseptr = (char *)base->data;
|
||||
char *dnsptr = (char *)dns->data;
|
||||
/* Empty matches everything */
|
||||
if (!*baseptr)
|
||||
return X509_V_OK;
|
||||
/* Otherwise can add zero or more components on the left so
|
||||
* compare RHS and if dns is longer and expect '.' as preceding
|
||||
* character.
|
||||
*/
|
||||
if (dns->length > base->length)
|
||||
{
|
||||
dnsptr += dns->length - base->length;
|
||||
if (dnsptr[-1] != '.')
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
{
|
||||
char *baseptr = (char *)base->data;
|
||||
char *dnsptr = (char *)dns->data;
|
||||
/* Empty matches everything */
|
||||
if (!*baseptr)
|
||||
return X509_V_OK;
|
||||
/*
|
||||
* Otherwise can add zero or more components on the left so compare RHS
|
||||
* and if dns is longer and expect '.' as preceding character.
|
||||
*/
|
||||
if (dns->length > base->length) {
|
||||
dnsptr += dns->length - base->length;
|
||||
if (*baseptr != '.' && dnsptr[-1] != '.')
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
|
||||
if (strcasecmp(baseptr, dnsptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
if (strcasecmp(baseptr, dnsptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
return X509_V_OK;
|
||||
return X509_V_OK;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
|
||||
{
|
||||
const char *baseptr = (char *)base->data;
|
||||
const char *emlptr = (char *)eml->data;
|
||||
{
|
||||
const char *baseptr = (char *)base->data;
|
||||
const char *emlptr = (char *)eml->data;
|
||||
|
||||
const char *baseat = strchr(baseptr, '@');
|
||||
const char *emlat = strchr(emlptr, '@');
|
||||
if (!emlat)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
/* Special case: inital '.' is RHS match */
|
||||
if (!baseat && (*baseptr == '.'))
|
||||
{
|
||||
if (eml->length > base->length)
|
||||
{
|
||||
emlptr += eml->length - base->length;
|
||||
if (!strcasecmp(baseptr, emlptr))
|
||||
return X509_V_OK;
|
||||
}
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
const char *baseat = strchr(baseptr, '@');
|
||||
const char *emlat = strchr(emlptr, '@');
|
||||
if (!emlat)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
/* Special case: inital '.' is RHS match */
|
||||
if (!baseat && (*baseptr == '.')) {
|
||||
if (eml->length > base->length) {
|
||||
emlptr += eml->length - base->length;
|
||||
if (!strcasecmp(baseptr, emlptr))
|
||||
return X509_V_OK;
|
||||
}
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
|
||||
/* If we have anything before '@' match local part */
|
||||
/* If we have anything before '@' match local part */
|
||||
|
||||
if (baseat)
|
||||
{
|
||||
if (baseat != baseptr)
|
||||
{
|
||||
if ((baseat - baseptr) != (emlat - emlptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
/* Case sensitive match of local part */
|
||||
if (strncmp(baseptr, emlptr, emlat - emlptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
/* Position base after '@' */
|
||||
baseptr = baseat + 1;
|
||||
}
|
||||
emlptr = emlat + 1;
|
||||
/* Just have hostname left to match: case insensitive */
|
||||
if (strcasecmp(baseptr, emlptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
if (baseat) {
|
||||
if (baseat != baseptr) {
|
||||
if ((baseat - baseptr) != (emlat - emlptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
/* Case sensitive match of local part */
|
||||
if (strncmp(baseptr, emlptr, emlat - emlptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
/* Position base after '@' */
|
||||
baseptr = baseat + 1;
|
||||
}
|
||||
emlptr = emlat + 1;
|
||||
/* Just have hostname left to match: case insensitive */
|
||||
if (strcasecmp(baseptr, emlptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
return X509_V_OK;
|
||||
return X509_V_OK;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
|
||||
{
|
||||
const char *baseptr = (char *)base->data;
|
||||
const char *hostptr = (char *)uri->data;
|
||||
const char *p = strchr(hostptr, ':');
|
||||
int hostlen;
|
||||
/* Check for foo:// and skip past it */
|
||||
if (!p || (p[1] != '/') || (p[2] != '/'))
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
hostptr = p + 3;
|
||||
{
|
||||
const char *baseptr = (char *)base->data;
|
||||
const char *hostptr = (char *)uri->data;
|
||||
const char *p = strchr(hostptr, ':');
|
||||
int hostlen;
|
||||
/* Check for foo:// and skip past it */
|
||||
if (!p || (p[1] != '/') || (p[2] != '/'))
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
hostptr = p + 3;
|
||||
|
||||
/* Determine length of hostname part of URI */
|
||||
/* Determine length of hostname part of URI */
|
||||
|
||||
/* Look for a port indicator as end of hostname first */
|
||||
/* Look for a port indicator as end of hostname first */
|
||||
|
||||
p = strchr(hostptr, ':');
|
||||
/* Otherwise look for trailing slash */
|
||||
if (!p)
|
||||
p = strchr(hostptr, '/');
|
||||
p = strchr(hostptr, ':');
|
||||
/* Otherwise look for trailing slash */
|
||||
if (!p)
|
||||
p = strchr(hostptr, '/');
|
||||
|
||||
if (!p)
|
||||
hostlen = strlen(hostptr);
|
||||
else
|
||||
hostlen = p - hostptr;
|
||||
if (!p)
|
||||
hostlen = strlen(hostptr);
|
||||
else
|
||||
hostlen = p - hostptr;
|
||||
|
||||
if (hostlen == 0)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
if (hostlen == 0)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
|
||||
/* Special case: inital '.' is RHS match */
|
||||
if (*baseptr == '.')
|
||||
{
|
||||
if (hostlen > base->length)
|
||||
{
|
||||
p = hostptr + hostlen - base->length;
|
||||
if (!strncasecmp(p, baseptr, base->length))
|
||||
return X509_V_OK;
|
||||
}
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
/* Special case: inital '.' is RHS match */
|
||||
if (*baseptr == '.') {
|
||||
if (hostlen > base->length) {
|
||||
p = hostptr + hostlen - base->length;
|
||||
if (!strncasecmp(p, baseptr, base->length))
|
||||
return X509_V_OK;
|
||||
}
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
|
||||
if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
if ((base->length != (int)hostlen)
|
||||
|| strncasecmp(hostptr, baseptr, hostlen))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
return X509_V_OK;
|
||||
return X509_V_OK;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_ocsp.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -58,232 +59,254 @@
|
||||
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/ocsp.h>
|
||||
#include <openssl/x509v3.h>
|
||||
# include <stdio.h>
|
||||
# include "cryptlib.h"
|
||||
# include <openssl/conf.h>
|
||||
# include <openssl/asn1.h>
|
||||
# include <openssl/ocsp.h>
|
||||
# include <openssl/x509v3.h>
|
||||
|
||||
/* OCSP extensions and a couple of CRL entry extensions
|
||||
/*
|
||||
* OCSP extensions and a couple of CRL entry extensions
|
||||
*/
|
||||
|
||||
static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
|
||||
BIO *out, int indent);
|
||||
BIO *out, int indent);
|
||||
static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
|
||||
BIO *out, int indent);
|
||||
BIO *out, int indent);
|
||||
static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
|
||||
int indent);
|
||||
int indent);
|
||||
|
||||
static void *ocsp_nonce_new(void);
|
||||
static int i2d_ocsp_nonce(void *a, unsigned char **pp);
|
||||
static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
|
||||
static void ocsp_nonce_free(void *a);
|
||||
static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
|
||||
BIO *out, int indent);
|
||||
BIO *out, int indent);
|
||||
|
||||
static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
|
||||
void *nocheck, BIO *out, int indent);
|
||||
static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
const char *str);
|
||||
void *nocheck, BIO *out, int indent);
|
||||
static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, const char *str);
|
||||
static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
|
||||
BIO *bp, int ind);
|
||||
BIO *bp, int ind);
|
||||
|
||||
const X509V3_EXT_METHOD v3_ocsp_crlid = {
|
||||
NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,0,
|
||||
i2r_ocsp_crlid,0,
|
||||
NULL
|
||||
NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
i2r_ocsp_crlid, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_ocsp_acutoff = {
|
||||
NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,0,
|
||||
i2r_ocsp_acutoff,0,
|
||||
NULL
|
||||
NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
i2r_ocsp_acutoff, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_crl_invdate = {
|
||||
NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,0,
|
||||
i2r_ocsp_acutoff,0,
|
||||
NULL
|
||||
NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
i2r_ocsp_acutoff, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_crl_hold = {
|
||||
NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,0,
|
||||
i2r_object,0,
|
||||
NULL
|
||||
NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
i2r_object, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_ocsp_nonce = {
|
||||
NID_id_pkix_OCSP_Nonce, 0, NULL,
|
||||
ocsp_nonce_new,
|
||||
ocsp_nonce_free,
|
||||
d2i_ocsp_nonce,
|
||||
i2d_ocsp_nonce,
|
||||
0,0,
|
||||
0,0,
|
||||
i2r_ocsp_nonce,0,
|
||||
NULL
|
||||
NID_id_pkix_OCSP_Nonce, 0, NULL,
|
||||
ocsp_nonce_new,
|
||||
ocsp_nonce_free,
|
||||
d2i_ocsp_nonce,
|
||||
i2d_ocsp_nonce,
|
||||
0, 0,
|
||||
0, 0,
|
||||
i2r_ocsp_nonce, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_ocsp_nocheck = {
|
||||
NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
|
||||
0,0,0,0,
|
||||
0,s2i_ocsp_nocheck,
|
||||
0,0,
|
||||
i2r_ocsp_nocheck,0,
|
||||
NULL
|
||||
NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
|
||||
0, 0, 0, 0,
|
||||
0, s2i_ocsp_nocheck,
|
||||
0, 0,
|
||||
i2r_ocsp_nocheck, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
const X509V3_EXT_METHOD v3_ocsp_serviceloc = {
|
||||
NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,0,
|
||||
i2r_ocsp_serviceloc,0,
|
||||
NULL
|
||||
NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
i2r_ocsp_serviceloc, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
|
||||
int ind)
|
||||
int ind)
|
||||
{
|
||||
OCSP_CRLID *a = in;
|
||||
if (a->crlUrl)
|
||||
{
|
||||
if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) goto err;
|
||||
if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0) goto err;
|
||||
}
|
||||
if (a->crlNum)
|
||||
{
|
||||
if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) goto err;
|
||||
if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0) goto err;
|
||||
}
|
||||
if (a->crlTime)
|
||||
{
|
||||
if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) goto err;
|
||||
if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0) goto err;
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
return 0;
|
||||
OCSP_CRLID *a = in;
|
||||
if (a->crlUrl) {
|
||||
if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0)
|
||||
goto err;
|
||||
if (!ASN1_STRING_print(bp, (ASN1_STRING *)a->crlUrl))
|
||||
goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (a->crlNum) {
|
||||
if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0)
|
||||
goto err;
|
||||
if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0)
|
||||
goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (a->crlTime) {
|
||||
if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0)
|
||||
goto err;
|
||||
if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime))
|
||||
goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto err;
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff,
|
||||
BIO *bp, int ind)
|
||||
BIO *bp, int ind)
|
||||
{
|
||||
if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
|
||||
if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0;
|
||||
return 1;
|
||||
if (BIO_printf(bp, "%*s", ind, "") <= 0)
|
||||
return 0;
|
||||
if (!ASN1_GENERALIZEDTIME_print(bp, cutoff))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
|
||||
int ind)
|
||||
int ind)
|
||||
{
|
||||
if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
|
||||
if(i2a_ASN1_OBJECT(bp, oid) <= 0) return 0;
|
||||
return 1;
|
||||
if (BIO_printf(bp, "%*s", ind, "") <= 0)
|
||||
return 0;
|
||||
if (i2a_ASN1_OBJECT(bp, oid) <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* OCSP nonce. This is needs special treatment because it doesn't have
|
||||
* an ASN1 encoding at all: it just contains arbitrary data.
|
||||
/*
|
||||
* OCSP nonce. This is needs special treatment because it doesn't have an
|
||||
* ASN1 encoding at all: it just contains arbitrary data.
|
||||
*/
|
||||
|
||||
static void *ocsp_nonce_new(void)
|
||||
{
|
||||
return ASN1_OCTET_STRING_new();
|
||||
return ASN1_OCTET_STRING_new();
|
||||
}
|
||||
|
||||
static int i2d_ocsp_nonce(void *a, unsigned char **pp)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = a;
|
||||
if(pp) {
|
||||
memcpy(*pp, os->data, os->length);
|
||||
*pp += os->length;
|
||||
}
|
||||
return os->length;
|
||||
ASN1_OCTET_STRING *os = a;
|
||||
if (pp) {
|
||||
memcpy(*pp, os->data, os->length);
|
||||
*pp += os->length;
|
||||
}
|
||||
return os->length;
|
||||
}
|
||||
|
||||
static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
|
||||
{
|
||||
ASN1_OCTET_STRING *os, **pos;
|
||||
pos = a;
|
||||
if(!pos || !*pos) os = ASN1_OCTET_STRING_new();
|
||||
else os = *pos;
|
||||
if(!ASN1_OCTET_STRING_set(os, *pp, length)) goto err;
|
||||
ASN1_OCTET_STRING *os, **pos;
|
||||
pos = a;
|
||||
if (!pos || !*pos)
|
||||
os = ASN1_OCTET_STRING_new();
|
||||
else
|
||||
os = *pos;
|
||||
if (!ASN1_OCTET_STRING_set(os, *pp, length))
|
||||
goto err;
|
||||
|
||||
*pp += length;
|
||||
*pp += length;
|
||||
|
||||
if(pos) *pos = os;
|
||||
return os;
|
||||
if (pos)
|
||||
*pos = os;
|
||||
return os;
|
||||
|
||||
err:
|
||||
if(os && (!pos || (*pos != os))) M_ASN1_OCTET_STRING_free(os);
|
||||
OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
err:
|
||||
if (os && (!pos || (*pos != os)))
|
||||
M_ASN1_OCTET_STRING_free(os);
|
||||
OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ocsp_nonce_free(void *a)
|
||||
{
|
||||
M_ASN1_OCTET_STRING_free(a);
|
||||
M_ASN1_OCTET_STRING_free(a);
|
||||
}
|
||||
|
||||
static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
|
||||
BIO *out, int indent)
|
||||
BIO *out, int indent)
|
||||
{
|
||||
if(BIO_printf(out, "%*s", indent, "") <= 0) return 0;
|
||||
if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0;
|
||||
return 1;
|
||||
if (BIO_printf(out, "%*s", indent, "") <= 0)
|
||||
return 0;
|
||||
if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Nocheck is just a single NULL. Don't print anything and always set it */
|
||||
|
||||
static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
|
||||
BIO *out, int indent)
|
||||
BIO *out, int indent)
|
||||
{
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
const char *str)
|
||||
static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, const char *str)
|
||||
{
|
||||
return ASN1_NULL_new();
|
||||
return ASN1_NULL_new();
|
||||
}
|
||||
|
||||
static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
|
||||
BIO *bp, int ind)
|
||||
{
|
||||
int i;
|
||||
OCSP_SERVICELOC *a = in;
|
||||
ACCESS_DESCRIPTION *ad;
|
||||
BIO *bp, int ind)
|
||||
{
|
||||
int i;
|
||||
OCSP_SERVICELOC *a = in;
|
||||
ACCESS_DESCRIPTION *ad;
|
||||
|
||||
if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) goto err;
|
||||
if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) goto err;
|
||||
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++)
|
||||
{
|
||||
ad = sk_ACCESS_DESCRIPTION_value(a->locator,i);
|
||||
if (BIO_printf(bp, "\n%*s", (2*ind), "") <= 0)
|
||||
goto err;
|
||||
if(i2a_ASN1_OBJECT(bp, ad->method) <= 0) goto err;
|
||||
if(BIO_puts(bp, " - ") <= 0) goto err;
|
||||
if(GENERAL_NAME_print(bp, ad->location) <= 0) goto err;
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0)
|
||||
goto err;
|
||||
if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0)
|
||||
goto err;
|
||||
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) {
|
||||
ad = sk_ACCESS_DESCRIPTION_value(a->locator, i);
|
||||
if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0)
|
||||
goto err;
|
||||
if (i2a_ASN1_OBJECT(bp, ad->method) <= 0)
|
||||
goto err;
|
||||
if (BIO_puts(bp, " - ") <= 0)
|
||||
goto err;
|
||||
if (GENERAL_NAME_print(bp, ad->location) <= 0)
|
||||
goto err;
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* Contributed to the OpenSSL Project 2004
|
||||
* by Richard Levitte (richard@levitte.org)
|
||||
/*
|
||||
* Contributed to the OpenSSL Project 2004 by Richard Levitte
|
||||
* (richard@levitte.org)
|
||||
*/
|
||||
/* Copyright (c) 2004 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
@@ -40,289 +41,277 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
|
||||
BIO *out, int indent);
|
||||
BIO *out, int indent);
|
||||
static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *str);
|
||||
X509V3_CTX *ctx, char *str);
|
||||
|
||||
const X509V3_EXT_METHOD v3_pci =
|
||||
{ NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
NULL, NULL,
|
||||
(X509V3_EXT_I2R)i2r_pci,
|
||||
(X509V3_EXT_R2I)r2i_pci,
|
||||
NULL,
|
||||
};
|
||||
{ NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
NULL, NULL,
|
||||
(X509V3_EXT_I2R)i2r_pci,
|
||||
(X509V3_EXT_R2I)r2i_pci,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
|
||||
BIO *out, int indent)
|
||||
{
|
||||
BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
|
||||
if (pci->pcPathLengthConstraint)
|
||||
i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
|
||||
else
|
||||
BIO_printf(out, "infinite");
|
||||
BIO_puts(out, "\n");
|
||||
BIO_printf(out, "%*sPolicy Language: ", indent, "");
|
||||
i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
|
||||
BIO_puts(out, "\n");
|
||||
if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
|
||||
BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
|
||||
pci->proxyPolicy->policy->data);
|
||||
return 1;
|
||||
}
|
||||
BIO *out, int indent)
|
||||
{
|
||||
BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
|
||||
if (pci->pcPathLengthConstraint)
|
||||
i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
|
||||
else
|
||||
BIO_printf(out, "infinite");
|
||||
BIO_puts(out, "\n");
|
||||
BIO_printf(out, "%*sPolicy Language: ", indent, "");
|
||||
i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
|
||||
BIO_puts(out, "\n");
|
||||
if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
|
||||
BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
|
||||
pci->proxyPolicy->policy->data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int process_pci_value(CONF_VALUE *val,
|
||||
ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
|
||||
ASN1_OCTET_STRING **policy)
|
||||
{
|
||||
int free_policy = 0;
|
||||
ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
|
||||
ASN1_OCTET_STRING **policy)
|
||||
{
|
||||
int free_policy = 0;
|
||||
|
||||
if (strcmp(val->name, "language") == 0)
|
||||
{
|
||||
if (*language)
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
if (!(*language = OBJ_txt2obj(val->value, 0)))
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (strcmp(val->name, "pathlen") == 0)
|
||||
{
|
||||
if (*pathlen)
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
if (!X509V3_get_value_int(val, pathlen))
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (strcmp(val->name, "policy") == 0)
|
||||
{
|
||||
unsigned char *tmp_data = NULL;
|
||||
long val_len;
|
||||
if (!*policy)
|
||||
{
|
||||
*policy = ASN1_OCTET_STRING_new();
|
||||
if (!*policy)
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
free_policy = 1;
|
||||
}
|
||||
if (strncmp(val->value, "hex:", 4) == 0)
|
||||
{
|
||||
unsigned char *tmp_data2 =
|
||||
string_to_hex(val->value + 4, &val_len);
|
||||
if (strcmp(val->name, "language") == 0) {
|
||||
if (*language) {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,
|
||||
X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
if (!(*language = OBJ_txt2obj(val->value, 0))) {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,
|
||||
X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
} else if (strcmp(val->name, "pathlen") == 0) {
|
||||
if (*pathlen) {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,
|
||||
X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
if (!X509V3_get_value_int(val, pathlen)) {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,
|
||||
X509V3_R_POLICY_PATH_LENGTH);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
} else if (strcmp(val->name, "policy") == 0) {
|
||||
unsigned char *tmp_data = NULL;
|
||||
long val_len;
|
||||
if (!*policy) {
|
||||
*policy = ASN1_OCTET_STRING_new();
|
||||
if (!*policy) {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
|
||||
X509V3_conf_err(val);
|
||||
return 0;
|
||||
}
|
||||
free_policy = 1;
|
||||
}
|
||||
if (strncmp(val->value, "hex:", 4) == 0) {
|
||||
unsigned char *tmp_data2 =
|
||||
string_to_hex(val->value + 4, &val_len);
|
||||
|
||||
if (!tmp_data2)
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_ILLEGAL_HEX_DIGIT);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
if (!tmp_data2) {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,
|
||||
X509V3_R_ILLEGAL_HEX_DIGIT);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
|
||||
tmp_data = OPENSSL_realloc((*policy)->data,
|
||||
(*policy)->length + val_len + 1);
|
||||
if (tmp_data)
|
||||
{
|
||||
(*policy)->data = tmp_data;
|
||||
memcpy(&(*policy)->data[(*policy)->length],
|
||||
tmp_data2, val_len);
|
||||
(*policy)->length += val_len;
|
||||
(*policy)->data[(*policy)->length] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENSSL_free(tmp_data2);
|
||||
/* realloc failure implies the original data space is b0rked too! */
|
||||
(*policy)->data = NULL;
|
||||
(*policy)->length = 0;
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_free(tmp_data2);
|
||||
}
|
||||
else if (strncmp(val->value, "file:", 5) == 0)
|
||||
{
|
||||
unsigned char buf[2048];
|
||||
int n;
|
||||
BIO *b = BIO_new_file(val->value + 5, "r");
|
||||
if (!b)
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
while((n = BIO_read(b, buf, sizeof(buf))) > 0
|
||||
|| (n == 0 && BIO_should_retry(b)))
|
||||
{
|
||||
if (!n) continue;
|
||||
tmp_data = OPENSSL_realloc((*policy)->data,
|
||||
(*policy)->length + val_len + 1);
|
||||
if (tmp_data) {
|
||||
(*policy)->data = tmp_data;
|
||||
memcpy(&(*policy)->data[(*policy)->length],
|
||||
tmp_data2, val_len);
|
||||
(*policy)->length += val_len;
|
||||
(*policy)->data[(*policy)->length] = '\0';
|
||||
} else {
|
||||
OPENSSL_free(tmp_data2);
|
||||
/*
|
||||
* realloc failure implies the original data space is b0rked
|
||||
* too!
|
||||
*/
|
||||
(*policy)->data = NULL;
|
||||
(*policy)->length = 0;
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_free(tmp_data2);
|
||||
} else if (strncmp(val->value, "file:", 5) == 0) {
|
||||
unsigned char buf[2048];
|
||||
int n;
|
||||
BIO *b = BIO_new_file(val->value + 5, "r");
|
||||
if (!b) {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
while ((n = BIO_read(b, buf, sizeof(buf))) > 0
|
||||
|| (n == 0 && BIO_should_retry(b))) {
|
||||
if (!n)
|
||||
continue;
|
||||
|
||||
tmp_data = OPENSSL_realloc((*policy)->data,
|
||||
(*policy)->length + n + 1);
|
||||
tmp_data = OPENSSL_realloc((*policy)->data,
|
||||
(*policy)->length + n + 1);
|
||||
|
||||
if (!tmp_data)
|
||||
break;
|
||||
if (!tmp_data)
|
||||
break;
|
||||
|
||||
(*policy)->data = tmp_data;
|
||||
memcpy(&(*policy)->data[(*policy)->length],
|
||||
buf, n);
|
||||
(*policy)->length += n;
|
||||
(*policy)->data[(*policy)->length] = '\0';
|
||||
}
|
||||
BIO_free_all(b);
|
||||
(*policy)->data = tmp_data;
|
||||
memcpy(&(*policy)->data[(*policy)->length], buf, n);
|
||||
(*policy)->length += n;
|
||||
(*policy)->data[(*policy)->length] = '\0';
|
||||
}
|
||||
BIO_free_all(b);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else if (strncmp(val->value, "text:", 5) == 0)
|
||||
{
|
||||
val_len = strlen(val->value + 5);
|
||||
tmp_data = OPENSSL_realloc((*policy)->data,
|
||||
(*policy)->length + val_len + 1);
|
||||
if (tmp_data)
|
||||
{
|
||||
(*policy)->data = tmp_data;
|
||||
memcpy(&(*policy)->data[(*policy)->length],
|
||||
val->value + 5, val_len);
|
||||
(*policy)->length += val_len;
|
||||
(*policy)->data[(*policy)->length] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* realloc failure implies the original data space is b0rked too! */
|
||||
(*policy)->data = NULL;
|
||||
(*policy)->length = 0;
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
if (!tmp_data)
|
||||
{
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
if (free_policy)
|
||||
{
|
||||
ASN1_OCTET_STRING_free(*policy);
|
||||
*policy = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (n < 0) {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
} else if (strncmp(val->value, "text:", 5) == 0) {
|
||||
val_len = strlen(val->value + 5);
|
||||
tmp_data = OPENSSL_realloc((*policy)->data,
|
||||
(*policy)->length + val_len + 1);
|
||||
if (tmp_data) {
|
||||
(*policy)->data = tmp_data;
|
||||
memcpy(&(*policy)->data[(*policy)->length],
|
||||
val->value + 5, val_len);
|
||||
(*policy)->length += val_len;
|
||||
(*policy)->data[(*policy)->length] = '\0';
|
||||
} else {
|
||||
/*
|
||||
* realloc failure implies the original data space is b0rked
|
||||
* too!
|
||||
*/
|
||||
(*policy)->data = NULL;
|
||||
(*policy)->length = 0;
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE,
|
||||
X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
if (!tmp_data) {
|
||||
X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
if (free_policy) {
|
||||
ASN1_OCTET_STRING_free(*policy);
|
||||
*policy = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *value)
|
||||
{
|
||||
PROXY_CERT_INFO_EXTENSION *pci = NULL;
|
||||
STACK_OF(CONF_VALUE) *vals;
|
||||
ASN1_OBJECT *language = NULL;
|
||||
ASN1_INTEGER *pathlen = NULL;
|
||||
ASN1_OCTET_STRING *policy = NULL;
|
||||
int i, j;
|
||||
X509V3_CTX *ctx, char *value)
|
||||
{
|
||||
PROXY_CERT_INFO_EXTENSION *pci = NULL;
|
||||
STACK_OF(CONF_VALUE) *vals;
|
||||
ASN1_OBJECT *language = NULL;
|
||||
ASN1_INTEGER *pathlen = NULL;
|
||||
ASN1_OCTET_STRING *policy = NULL;
|
||||
int i, j;
|
||||
|
||||
vals = X509V3_parse_list(value);
|
||||
for (i = 0; i < sk_CONF_VALUE_num(vals); i++)
|
||||
{
|
||||
CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
|
||||
if (!cnf->name || (*cnf->name != '@' && !cnf->value))
|
||||
{
|
||||
X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_PROXY_POLICY_SETTING);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
if (*cnf->name == '@')
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *sect;
|
||||
int success_p = 1;
|
||||
vals = X509V3_parse_list(value);
|
||||
for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
|
||||
CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
|
||||
if (!cnf->name || (*cnf->name != '@' && !cnf->value)) {
|
||||
X509V3err(X509V3_F_R2I_PCI,
|
||||
X509V3_R_INVALID_PROXY_POLICY_SETTING);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
if (*cnf->name == '@') {
|
||||
STACK_OF(CONF_VALUE) *sect;
|
||||
int success_p = 1;
|
||||
|
||||
sect = X509V3_get_section(ctx, cnf->name + 1);
|
||||
if (!sect)
|
||||
{
|
||||
X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_SECTION);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++)
|
||||
{
|
||||
success_p =
|
||||
process_pci_value(sk_CONF_VALUE_value(sect, j),
|
||||
&language, &pathlen, &policy);
|
||||
}
|
||||
X509V3_section_free(ctx, sect);
|
||||
if (!success_p)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!process_pci_value(cnf,
|
||||
&language, &pathlen, &policy))
|
||||
{
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
sect = X509V3_get_section(ctx, cnf->name + 1);
|
||||
if (!sect) {
|
||||
X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) {
|
||||
success_p =
|
||||
process_pci_value(sk_CONF_VALUE_value(sect, j),
|
||||
&language, &pathlen, &policy);
|
||||
}
|
||||
X509V3_section_free(ctx, sect);
|
||||
if (!success_p)
|
||||
goto err;
|
||||
} else {
|
||||
if (!process_pci_value(cnf, &language, &pathlen, &policy)) {
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Language is mandatory */
|
||||
if (!language)
|
||||
{
|
||||
X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
|
||||
goto err;
|
||||
}
|
||||
i = OBJ_obj2nid(language);
|
||||
if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy)
|
||||
{
|
||||
X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
|
||||
goto err;
|
||||
}
|
||||
/* Language is mandatory */
|
||||
if (!language) {
|
||||
X509V3err(X509V3_F_R2I_PCI,
|
||||
X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
|
||||
goto err;
|
||||
}
|
||||
i = OBJ_obj2nid(language);
|
||||
if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) {
|
||||
X509V3err(X509V3_F_R2I_PCI,
|
||||
X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
pci = PROXY_CERT_INFO_EXTENSION_new();
|
||||
if (!pci)
|
||||
{
|
||||
X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
pci = PROXY_CERT_INFO_EXTENSION_new();
|
||||
if (!pci) {
|
||||
X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
pci->proxyPolicy->policyLanguage = language; language = NULL;
|
||||
pci->proxyPolicy->policy = policy; policy = NULL;
|
||||
pci->pcPathLengthConstraint = pathlen; pathlen = NULL;
|
||||
goto end;
|
||||
err:
|
||||
if (language) { ASN1_OBJECT_free(language); language = NULL; }
|
||||
if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
|
||||
if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
|
||||
if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
|
||||
end:
|
||||
sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
|
||||
return pci;
|
||||
}
|
||||
pci->proxyPolicy->policyLanguage = language;
|
||||
language = NULL;
|
||||
pci->proxyPolicy->policy = policy;
|
||||
policy = NULL;
|
||||
pci->pcPathLengthConstraint = pathlen;
|
||||
pathlen = NULL;
|
||||
goto end;
|
||||
err:
|
||||
if (language) {
|
||||
ASN1_OBJECT_free(language);
|
||||
language = NULL;
|
||||
}
|
||||
if (pathlen) {
|
||||
ASN1_INTEGER_free(pathlen);
|
||||
pathlen = NULL;
|
||||
}
|
||||
if (policy) {
|
||||
ASN1_OCTET_STRING_free(policy);
|
||||
policy = NULL;
|
||||
}
|
||||
if (pci) {
|
||||
PROXY_CERT_INFO_EXTENSION_free(pci);
|
||||
pci = NULL;
|
||||
}
|
||||
end:
|
||||
sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
|
||||
return pci;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* Contributed to the OpenSSL Project 2004
|
||||
* by Richard Levitte (richard@levitte.org)
|
||||
/*
|
||||
* Contributed to the OpenSSL Project 2004 by Richard Levitte
|
||||
* (richard@levitte.org)
|
||||
*/
|
||||
/* Copyright (c) 2004 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
@@ -39,17 +40,17 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
ASN1_SEQUENCE(PROXY_POLICY) =
|
||||
{
|
||||
ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
|
||||
ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
|
||||
{
|
||||
ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
|
||||
ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(PROXY_POLICY)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY)
|
||||
|
||||
ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) =
|
||||
{
|
||||
ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
|
||||
ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
|
||||
{
|
||||
ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
|
||||
ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
|
||||
} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,6 @@
|
||||
/* v3_pcons.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1.h>
|
||||
@@ -64,77 +64,76 @@
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons,
|
||||
STACK_OF(CONF_VALUE) *extlist);
|
||||
static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD
|
||||
*method, void *bcons, STACK_OF(CONF_VALUE)
|
||||
*extlist);
|
||||
static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values);
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values);
|
||||
|
||||
const X509V3_EXT_METHOD v3_policy_constraints = {
|
||||
NID_policy_constraints, 0,
|
||||
ASN1_ITEM_ref(POLICY_CONSTRAINTS),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
i2v_POLICY_CONSTRAINTS,
|
||||
v2i_POLICY_CONSTRAINTS,
|
||||
NULL,NULL,
|
||||
NULL
|
||||
NID_policy_constraints, 0,
|
||||
ASN1_ITEM_ref(POLICY_CONSTRAINTS),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
i2v_POLICY_CONSTRAINTS,
|
||||
v2i_POLICY_CONSTRAINTS,
|
||||
NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
|
||||
ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
|
||||
ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
|
||||
ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
|
||||
ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
|
||||
} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS)
|
||||
|
||||
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
|
||||
|
||||
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
|
||||
STACK_OF(CONF_VALUE) *extlist)
|
||||
static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD
|
||||
*method, void *a, STACK_OF(CONF_VALUE)
|
||||
*extlist)
|
||||
{
|
||||
POLICY_CONSTRAINTS *pcons = a;
|
||||
X509V3_add_value_int("Require Explicit Policy",
|
||||
pcons->requireExplicitPolicy, &extlist);
|
||||
X509V3_add_value_int("Inhibit Policy Mapping",
|
||||
pcons->inhibitPolicyMapping, &extlist);
|
||||
return extlist;
|
||||
POLICY_CONSTRAINTS *pcons = a;
|
||||
X509V3_add_value_int("Require Explicit Policy",
|
||||
pcons->requireExplicitPolicy, &extlist);
|
||||
X509V3_add_value_int("Inhibit Policy Mapping",
|
||||
pcons->inhibitPolicyMapping, &extlist);
|
||||
return extlist;
|
||||
}
|
||||
|
||||
static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values)
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values)
|
||||
{
|
||||
POLICY_CONSTRAINTS *pcons=NULL;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
if(!(pcons = POLICY_CONSTRAINTS_new())) {
|
||||
X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
|
||||
val = sk_CONF_VALUE_value(values, i);
|
||||
if(!strcmp(val->name, "requireExplicitPolicy")) {
|
||||
if(!X509V3_get_value_int(val,
|
||||
&pcons->requireExplicitPolicy)) goto err;
|
||||
} else if(!strcmp(val->name, "inhibitPolicyMapping")) {
|
||||
if(!X509V3_get_value_int(val,
|
||||
&pcons->inhibitPolicyMapping)) goto err;
|
||||
} else {
|
||||
X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
|
||||
X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
|
||||
goto err;
|
||||
}
|
||||
POLICY_CONSTRAINTS *pcons = NULL;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
if (!(pcons = POLICY_CONSTRAINTS_new())) {
|
||||
X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
|
||||
val = sk_CONF_VALUE_value(values, i);
|
||||
if (!strcmp(val->name, "requireExplicitPolicy")) {
|
||||
if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy))
|
||||
goto err;
|
||||
} else if (!strcmp(val->name, "inhibitPolicyMapping")) {
|
||||
if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping))
|
||||
goto err;
|
||||
} else {
|
||||
X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
|
||||
X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS,
|
||||
X509V3_R_ILLEGAL_EMPTY_EXTENSION);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return pcons;
|
||||
err:
|
||||
POLICY_CONSTRAINTS_free(pcons);
|
||||
return NULL;
|
||||
return pcons;
|
||||
err:
|
||||
POLICY_CONSTRAINTS_free(pcons);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_pku.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -62,42 +63,47 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, BIO *out, int indent);
|
||||
static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
|
||||
PKEY_USAGE_PERIOD *usage, BIO *out,
|
||||
int indent);
|
||||
/*
|
||||
static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
|
||||
*/
|
||||
* static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
|
||||
* X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
|
||||
*/
|
||||
const X509V3_EXT_METHOD v3_pkey_usage_period = {
|
||||
NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
(X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
|
||||
NULL
|
||||
NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
(X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = {
|
||||
ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
|
||||
ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
|
||||
ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
|
||||
ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
|
||||
} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
|
||||
|
||||
static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
|
||||
PKEY_USAGE_PERIOD *usage, BIO *out, int indent)
|
||||
PKEY_USAGE_PERIOD *usage, BIO *out,
|
||||
int indent)
|
||||
{
|
||||
BIO_printf(out, "%*s", indent, "");
|
||||
if(usage->notBefore) {
|
||||
BIO_write(out, "Not Before: ", 12);
|
||||
ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
|
||||
if(usage->notAfter) BIO_write(out, ", ", 2);
|
||||
}
|
||||
if(usage->notAfter) {
|
||||
BIO_write(out, "Not After: ", 11);
|
||||
ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
|
||||
}
|
||||
return 1;
|
||||
BIO_printf(out, "%*s", indent, "");
|
||||
if (usage->notBefore) {
|
||||
BIO_write(out, "Not Before: ", 12);
|
||||
ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
|
||||
if (usage->notAfter)
|
||||
BIO_write(out, ", ", 2);
|
||||
}
|
||||
if (usage->notAfter) {
|
||||
BIO_write(out, "Not After: ", 11);
|
||||
ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values)
|
||||
X509V3_EXT_METHOD *method;
|
||||
X509V3_CTX *ctx;
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,6 @@
|
||||
/* v3_pmaps.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1t.h>
|
||||
@@ -64,92 +64,93 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps,
|
||||
STACK_OF(CONF_VALUE) *extlist);
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
|
||||
static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
|
||||
*method, void *pmps, STACK_OF(CONF_VALUE)
|
||||
*extlist);
|
||||
|
||||
const X509V3_EXT_METHOD v3_policy_mappings = {
|
||||
NID_policy_mappings, 0,
|
||||
ASN1_ITEM_ref(POLICY_MAPPINGS),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
i2v_POLICY_MAPPINGS,
|
||||
v2i_POLICY_MAPPINGS,
|
||||
0,0,
|
||||
NULL
|
||||
NID_policy_mappings, 0,
|
||||
ASN1_ITEM_ref(POLICY_MAPPINGS),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
i2v_POLICY_MAPPINGS,
|
||||
v2i_POLICY_MAPPINGS,
|
||||
0, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
ASN1_SEQUENCE(POLICY_MAPPING) = {
|
||||
ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
|
||||
ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
|
||||
ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
|
||||
ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
|
||||
} ASN1_SEQUENCE_END(POLICY_MAPPING)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
|
||||
POLICY_MAPPING)
|
||||
ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
|
||||
POLICY_MAPPING)
|
||||
ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
|
||||
|
||||
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
|
||||
|
||||
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
|
||||
STACK_OF(CONF_VALUE) *ext_list)
|
||||
static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
|
||||
*method, void *a, STACK_OF(CONF_VALUE)
|
||||
*ext_list)
|
||||
{
|
||||
POLICY_MAPPINGS *pmaps = a;
|
||||
POLICY_MAPPING *pmap;
|
||||
int i;
|
||||
char obj_tmp1[80];
|
||||
char obj_tmp2[80];
|
||||
for(i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
|
||||
pmap = sk_POLICY_MAPPING_value(pmaps, i);
|
||||
i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
|
||||
i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
|
||||
X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
|
||||
}
|
||||
return ext_list;
|
||||
POLICY_MAPPINGS *pmaps = a;
|
||||
POLICY_MAPPING *pmap;
|
||||
int i;
|
||||
char obj_tmp1[80];
|
||||
char obj_tmp2[80];
|
||||
for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
|
||||
pmap = sk_POLICY_MAPPING_value(pmaps, i);
|
||||
i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
|
||||
i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
|
||||
X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
|
||||
}
|
||||
return ext_list;
|
||||
}
|
||||
|
||||
static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
POLICY_MAPPINGS *pmaps;
|
||||
POLICY_MAPPING *pmap;
|
||||
ASN1_OBJECT *obj1, *obj2;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
POLICY_MAPPINGS *pmaps;
|
||||
POLICY_MAPPING *pmap;
|
||||
ASN1_OBJECT *obj1, *obj2;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
|
||||
if(!(pmaps = sk_POLICY_MAPPING_new_null())) {
|
||||
X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (!(pmaps = sk_POLICY_MAPPING_new_null())) {
|
||||
X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if(!val->value || !val->name) {
|
||||
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
|
||||
X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(val);
|
||||
return NULL;
|
||||
}
|
||||
obj1 = OBJ_txt2obj(val->name, 0);
|
||||
obj2 = OBJ_txt2obj(val->value, 0);
|
||||
if(!obj1 || !obj2) {
|
||||
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
|
||||
X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(val);
|
||||
return NULL;
|
||||
}
|
||||
pmap = POLICY_MAPPING_new();
|
||||
if (!pmap) {
|
||||
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
|
||||
X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
pmap->issuerDomainPolicy = obj1;
|
||||
pmap->subjectDomainPolicy = obj2;
|
||||
sk_POLICY_MAPPING_push(pmaps, pmap);
|
||||
}
|
||||
return pmaps;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (!val->value || !val->name) {
|
||||
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
|
||||
X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,
|
||||
X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(val);
|
||||
return NULL;
|
||||
}
|
||||
obj1 = OBJ_txt2obj(val->name, 0);
|
||||
obj2 = OBJ_txt2obj(val->value, 0);
|
||||
if (!obj1 || !obj2) {
|
||||
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
|
||||
X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,
|
||||
X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(val);
|
||||
return NULL;
|
||||
}
|
||||
pmap = POLICY_MAPPING_new();
|
||||
if (!pmap) {
|
||||
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
|
||||
X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
pmap->issuerDomainPolicy = obj1;
|
||||
pmap->subjectDomainPolicy = obj2;
|
||||
sk_POLICY_MAPPING_push(pmaps, pmap);
|
||||
}
|
||||
return pmaps;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_prn.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -64,171 +65,195 @@
|
||||
|
||||
/* Extension printing routines */
|
||||
|
||||
static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported);
|
||||
static int unknown_ext_print(BIO *out, X509_EXTENSION *ext,
|
||||
unsigned long flag, int indent, int supported);
|
||||
|
||||
/* Print out a name+value stack */
|
||||
|
||||
void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml)
|
||||
void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
|
||||
int ml)
|
||||
{
|
||||
int i;
|
||||
CONF_VALUE *nval;
|
||||
if(!val) return;
|
||||
if(!ml || !sk_CONF_VALUE_num(val)) {
|
||||
BIO_printf(out, "%*s", indent, "");
|
||||
if(!sk_CONF_VALUE_num(val)) BIO_puts(out, "<EMPTY>\n");
|
||||
}
|
||||
for(i = 0; i < sk_CONF_VALUE_num(val); i++) {
|
||||
if(ml) BIO_printf(out, "%*s", indent, "");
|
||||
else if(i > 0) BIO_printf(out, ", ");
|
||||
nval = sk_CONF_VALUE_value(val, i);
|
||||
if(!nval->name) BIO_puts(out, nval->value);
|
||||
else if(!nval->value) BIO_puts(out, nval->name);
|
||||
int i;
|
||||
CONF_VALUE *nval;
|
||||
if (!val)
|
||||
return;
|
||||
if (!ml || !sk_CONF_VALUE_num(val)) {
|
||||
BIO_printf(out, "%*s", indent, "");
|
||||
if (!sk_CONF_VALUE_num(val))
|
||||
BIO_puts(out, "<EMPTY>\n");
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(val); i++) {
|
||||
if (ml)
|
||||
BIO_printf(out, "%*s", indent, "");
|
||||
else if (i > 0)
|
||||
BIO_printf(out, ", ");
|
||||
nval = sk_CONF_VALUE_value(val, i);
|
||||
if (!nval->name)
|
||||
BIO_puts(out, nval->value);
|
||||
else if (!nval->value)
|
||||
BIO_puts(out, nval->name);
|
||||
#ifndef CHARSET_EBCDIC
|
||||
else BIO_printf(out, "%s:%s", nval->name, nval->value);
|
||||
else
|
||||
BIO_printf(out, "%s:%s", nval->name, nval->value);
|
||||
#else
|
||||
else {
|
||||
int len;
|
||||
char *tmp;
|
||||
len = strlen(nval->value)+1;
|
||||
tmp = OPENSSL_malloc(len);
|
||||
if (tmp)
|
||||
{
|
||||
ascii2ebcdic(tmp, nval->value, len);
|
||||
BIO_printf(out, "%s:%s", nval->name, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int len;
|
||||
char *tmp;
|
||||
len = strlen(nval->value) + 1;
|
||||
tmp = OPENSSL_malloc(len);
|
||||
if (tmp) {
|
||||
ascii2ebcdic(tmp, nval->value, len);
|
||||
BIO_printf(out, "%s:%s", nval->name, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(ml) BIO_puts(out, "\n");
|
||||
}
|
||||
if (ml)
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Main routine: print out a general extension */
|
||||
|
||||
int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent)
|
||||
int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
|
||||
int indent)
|
||||
{
|
||||
void *ext_str = NULL;
|
||||
char *value = NULL;
|
||||
const unsigned char *p;
|
||||
const X509V3_EXT_METHOD *method;
|
||||
STACK_OF(CONF_VALUE) *nval = NULL;
|
||||
int ok = 1;
|
||||
void *ext_str = NULL;
|
||||
char *value = NULL;
|
||||
const unsigned char *p;
|
||||
const X509V3_EXT_METHOD *method;
|
||||
STACK_OF(CONF_VALUE) *nval = NULL;
|
||||
int ok = 1;
|
||||
|
||||
if(!(method = X509V3_EXT_get(ext)))
|
||||
return unknown_ext_print(out, ext, flag, indent, 0);
|
||||
p = ext->value->data;
|
||||
if(method->it) ext_str = ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
|
||||
else ext_str = method->d2i(NULL, &p, ext->value->length);
|
||||
if (!(method = X509V3_EXT_get(ext)))
|
||||
return unknown_ext_print(out, ext, flag, indent, 0);
|
||||
p = ext->value->data;
|
||||
if (method->it)
|
||||
ext_str =
|
||||
ASN1_item_d2i(NULL, &p, ext->value->length,
|
||||
ASN1_ITEM_ptr(method->it));
|
||||
else
|
||||
ext_str = method->d2i(NULL, &p, ext->value->length);
|
||||
|
||||
if(!ext_str) return unknown_ext_print(out, ext, flag, indent, 1);
|
||||
if (!ext_str)
|
||||
return unknown_ext_print(out, ext, flag, indent, 1);
|
||||
|
||||
if(method->i2s) {
|
||||
if(!(value = method->i2s(method, ext_str))) {
|
||||
ok = 0;
|
||||
goto err;
|
||||
}
|
||||
if (method->i2s) {
|
||||
if (!(value = method->i2s(method, ext_str))) {
|
||||
ok = 0;
|
||||
goto err;
|
||||
}
|
||||
#ifndef CHARSET_EBCDIC
|
||||
BIO_printf(out, "%*s%s", indent, "", value);
|
||||
BIO_printf(out, "%*s%s", indent, "", value);
|
||||
#else
|
||||
{
|
||||
int len;
|
||||
char *tmp;
|
||||
len = strlen(value)+1;
|
||||
tmp = OPENSSL_malloc(len);
|
||||
if (tmp)
|
||||
{
|
||||
ascii2ebcdic(tmp, value, len);
|
||||
BIO_printf(out, "%*s%s", indent, "", tmp);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
}
|
||||
{
|
||||
int len;
|
||||
char *tmp;
|
||||
len = strlen(value) + 1;
|
||||
tmp = OPENSSL_malloc(len);
|
||||
if (tmp) {
|
||||
ascii2ebcdic(tmp, value, len);
|
||||
BIO_printf(out, "%*s%s", indent, "", tmp);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else if(method->i2v) {
|
||||
if(!(nval = method->i2v(method, ext_str, NULL))) {
|
||||
ok = 0;
|
||||
goto err;
|
||||
}
|
||||
X509V3_EXT_val_prn(out, nval, indent,
|
||||
method->ext_flags & X509V3_EXT_MULTILINE);
|
||||
} else if(method->i2r) {
|
||||
if(!method->i2r(method, ext_str, out, indent)) ok = 0;
|
||||
} else ok = 0;
|
||||
} else if (method->i2v) {
|
||||
if (!(nval = method->i2v(method, ext_str, NULL))) {
|
||||
ok = 0;
|
||||
goto err;
|
||||
}
|
||||
X509V3_EXT_val_prn(out, nval, indent,
|
||||
method->ext_flags & X509V3_EXT_MULTILINE);
|
||||
} else if (method->i2r) {
|
||||
if (!method->i2r(method, ext_str, out, indent))
|
||||
ok = 0;
|
||||
} else
|
||||
ok = 0;
|
||||
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
|
||||
if(value) OPENSSL_free(value);
|
||||
if(method->it) ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
|
||||
else method->ext_free(ext_str);
|
||||
return ok;
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
|
||||
if (value)
|
||||
OPENSSL_free(value);
|
||||
if (method->it)
|
||||
ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
|
||||
else
|
||||
method->ext_free(ext_str);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int X509V3_extensions_print(BIO *bp, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent)
|
||||
int X509V3_extensions_print(BIO *bp, char *title,
|
||||
STACK_OF(X509_EXTENSION) *exts,
|
||||
unsigned long flag, int indent)
|
||||
{
|
||||
int i, j;
|
||||
int i, j;
|
||||
|
||||
if(sk_X509_EXTENSION_num(exts) <= 0) return 1;
|
||||
if (sk_X509_EXTENSION_num(exts) <= 0)
|
||||
return 1;
|
||||
|
||||
if(title)
|
||||
{
|
||||
BIO_printf(bp,"%*s%s:\n",indent, "", title);
|
||||
indent += 4;
|
||||
}
|
||||
if (title) {
|
||||
BIO_printf(bp, "%*s%s:\n", indent, "", title);
|
||||
indent += 4;
|
||||
}
|
||||
|
||||
for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
X509_EXTENSION *ex;
|
||||
ex=sk_X509_EXTENSION_value(exts, i);
|
||||
if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0;
|
||||
obj=X509_EXTENSION_get_object(ex);
|
||||
i2a_ASN1_OBJECT(bp,obj);
|
||||
j=X509_EXTENSION_get_critical(ex);
|
||||
if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
|
||||
return 0;
|
||||
if(!X509V3_EXT_print(bp, ex, flag, indent + 4))
|
||||
{
|
||||
BIO_printf(bp, "%*s", indent + 4, "");
|
||||
M_ASN1_OCTET_STRING_print(bp,ex->value);
|
||||
}
|
||||
if (BIO_write(bp,"\n",1) <= 0) return 0;
|
||||
}
|
||||
return 1;
|
||||
for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
|
||||
ASN1_OBJECT *obj;
|
||||
X509_EXTENSION *ex;
|
||||
ex = sk_X509_EXTENSION_value(exts, i);
|
||||
if (indent && BIO_printf(bp, "%*s", indent, "") <= 0)
|
||||
return 0;
|
||||
obj = X509_EXTENSION_get_object(ex);
|
||||
i2a_ASN1_OBJECT(bp, obj);
|
||||
j = X509_EXTENSION_get_critical(ex);
|
||||
if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
|
||||
return 0;
|
||||
if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) {
|
||||
BIO_printf(bp, "%*s", indent + 4, "");
|
||||
M_ASN1_OCTET_STRING_print(bp, ex->value);
|
||||
}
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported)
|
||||
static int unknown_ext_print(BIO *out, X509_EXTENSION *ext,
|
||||
unsigned long flag, int indent, int supported)
|
||||
{
|
||||
switch(flag & X509V3_EXT_UNKNOWN_MASK) {
|
||||
switch (flag & X509V3_EXT_UNKNOWN_MASK) {
|
||||
|
||||
case X509V3_EXT_DEFAULT:
|
||||
return 0;
|
||||
case X509V3_EXT_DEFAULT:
|
||||
return 0;
|
||||
|
||||
case X509V3_EXT_ERROR_UNKNOWN:
|
||||
if(supported)
|
||||
BIO_printf(out, "%*s<Parse Error>", indent, "");
|
||||
else
|
||||
BIO_printf(out, "%*s<Not Supported>", indent, "");
|
||||
return 1;
|
||||
case X509V3_EXT_ERROR_UNKNOWN:
|
||||
if (supported)
|
||||
BIO_printf(out, "%*s<Parse Error>", indent, "");
|
||||
else
|
||||
BIO_printf(out, "%*s<Not Supported>", indent, "");
|
||||
return 1;
|
||||
|
||||
case X509V3_EXT_PARSE_UNKNOWN:
|
||||
return ASN1_parse_dump(out,
|
||||
ext->value->data, ext->value->length, indent, -1);
|
||||
case X509V3_EXT_DUMP_UNKNOWN:
|
||||
return BIO_dump_indent(out, (char *)ext->value->data, ext->value->length, indent);
|
||||
case X509V3_EXT_PARSE_UNKNOWN:
|
||||
return ASN1_parse_dump(out,
|
||||
ext->value->data, ext->value->length, indent,
|
||||
-1);
|
||||
case X509V3_EXT_DUMP_UNKNOWN:
|
||||
return BIO_dump_indent(out, (char *)ext->value->data,
|
||||
ext->value->length, indent);
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
|
||||
{
|
||||
BIO *bio_tmp;
|
||||
int ret;
|
||||
if(!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) return 0;
|
||||
ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
|
||||
BIO_free(bio_tmp);
|
||||
return ret;
|
||||
BIO *bio_tmp;
|
||||
int ret;
|
||||
if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE)))
|
||||
return 0;
|
||||
ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
|
||||
BIO_free(bio_tmp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
332
crypto/x509v3/v3_scts.c
Normal file
332
crypto/x509v3/v3_scts.c
Normal file
@@ -0,0 +1,332 @@
|
||||
/* v3_scts.c */
|
||||
/*
|
||||
* Written by Rob Stradling (rob@comodo.com) for the OpenSSL project 2014.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2014 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
/* Signature and hash algorithms from RFC 5246 */
|
||||
#define TLSEXT_hash_sha256 4
|
||||
|
||||
#define TLSEXT_signature_rsa 1
|
||||
#define TLSEXT_signature_ecdsa 3
|
||||
|
||||
|
||||
#define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \
|
||||
(((unsigned int)(c[1])) )),c+=2)
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
|
||||
# define SCT_TIMESTAMP unsigned __int64
|
||||
#elif defined(__arch64__)
|
||||
# define SCT_TIMESTAMP unsigned long
|
||||
#else
|
||||
# define SCT_TIMESTAMP unsigned long long
|
||||
#endif
|
||||
|
||||
#define n2l8(c,l) (l =((SCT_TIMESTAMP)(*((c)++)))<<56, \
|
||||
l|=((SCT_TIMESTAMP)(*((c)++)))<<48, \
|
||||
l|=((SCT_TIMESTAMP)(*((c)++)))<<40, \
|
||||
l|=((SCT_TIMESTAMP)(*((c)++)))<<32, \
|
||||
l|=((SCT_TIMESTAMP)(*((c)++)))<<24, \
|
||||
l|=((SCT_TIMESTAMP)(*((c)++)))<<16, \
|
||||
l|=((SCT_TIMESTAMP)(*((c)++)))<< 8, \
|
||||
l|=((SCT_TIMESTAMP)(*((c)++))))
|
||||
|
||||
typedef struct SCT_st {
|
||||
/* The encoded SCT */
|
||||
unsigned char *sct;
|
||||
unsigned short sctlen;
|
||||
/*
|
||||
* Components of the SCT. "logid", "ext" and "sig" point to addresses
|
||||
* inside "sct".
|
||||
*/
|
||||
unsigned char version;
|
||||
unsigned char *logid;
|
||||
unsigned short logidlen;
|
||||
SCT_TIMESTAMP timestamp;
|
||||
unsigned char *ext;
|
||||
unsigned short extlen;
|
||||
unsigned char hash_alg;
|
||||
unsigned char sig_alg;
|
||||
unsigned char *sig;
|
||||
unsigned short siglen;
|
||||
} SCT;
|
||||
|
||||
DECLARE_STACK_OF(SCT)
|
||||
|
||||
static void SCT_LIST_free(STACK_OF(SCT) *a);
|
||||
static STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a,
|
||||
const unsigned char **pp, long length);
|
||||
static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list,
|
||||
BIO *out, int indent);
|
||||
|
||||
const X509V3_EXT_METHOD v3_ct_scts[] = {
|
||||
{NID_ct_precert_scts, 0, NULL,
|
||||
0, (X509V3_EXT_FREE)SCT_LIST_free,
|
||||
(X509V3_EXT_D2I)d2i_SCT_LIST, 0,
|
||||
0, 0, 0, 0,
|
||||
(X509V3_EXT_I2R)i2r_SCT_LIST, 0,
|
||||
NULL},
|
||||
|
||||
{NID_ct_cert_scts, 0, NULL,
|
||||
0, (X509V3_EXT_FREE)SCT_LIST_free,
|
||||
(X509V3_EXT_D2I)d2i_SCT_LIST, 0,
|
||||
0, 0, 0, 0,
|
||||
(X509V3_EXT_I2R)i2r_SCT_LIST, 0,
|
||||
NULL},
|
||||
};
|
||||
|
||||
static void tls12_signature_print(BIO *out, const unsigned char hash_alg,
|
||||
const unsigned char sig_alg)
|
||||
{
|
||||
int nid = NID_undef;
|
||||
/* RFC6962 only permits two signature algorithms */
|
||||
if (hash_alg == TLSEXT_hash_sha256) {
|
||||
if (sig_alg == TLSEXT_signature_rsa)
|
||||
nid = NID_sha256WithRSAEncryption;
|
||||
else if (sig_alg == TLSEXT_signature_ecdsa)
|
||||
nid = NID_ecdsa_with_SHA256;
|
||||
}
|
||||
if (nid == NID_undef)
|
||||
BIO_printf(out, "%02X%02X", hash_alg, sig_alg);
|
||||
else
|
||||
BIO_printf(out, "%s", OBJ_nid2ln(nid));
|
||||
}
|
||||
|
||||
static void timestamp_print(BIO *out, SCT_TIMESTAMP timestamp)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME *gen;
|
||||
char genstr[20];
|
||||
gen = ASN1_GENERALIZEDTIME_new();
|
||||
ASN1_GENERALIZEDTIME_adj(gen, (time_t)0,
|
||||
(int)(timestamp / 86400000),
|
||||
(timestamp % 86400000) / 1000);
|
||||
/*
|
||||
* Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15
|
||||
* characters long with a final Z. Update it with fractional seconds.
|
||||
*/
|
||||
BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ",
|
||||
ASN1_STRING_data(gen), (unsigned int)(timestamp % 1000));
|
||||
ASN1_GENERALIZEDTIME_set_string(gen, genstr);
|
||||
ASN1_GENERALIZEDTIME_print(out, gen);
|
||||
ASN1_GENERALIZEDTIME_free(gen);
|
||||
}
|
||||
|
||||
static void SCT_free(SCT *sct)
|
||||
{
|
||||
if (sct) {
|
||||
if (sct->sct)
|
||||
OPENSSL_free(sct->sct);
|
||||
OPENSSL_free(sct);
|
||||
}
|
||||
}
|
||||
|
||||
static void SCT_LIST_free(STACK_OF(SCT) *a)
|
||||
{
|
||||
sk_SCT_pop_free(a, SCT_free);
|
||||
}
|
||||
|
||||
static STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a,
|
||||
const unsigned char **pp, long length)
|
||||
{
|
||||
ASN1_OCTET_STRING *oct = NULL;
|
||||
STACK_OF(SCT) *sk = NULL;
|
||||
SCT *sct;
|
||||
unsigned char *p, *p2;
|
||||
unsigned short listlen, sctlen = 0, fieldlen;
|
||||
|
||||
if (d2i_ASN1_OCTET_STRING(&oct, pp, length) == NULL)
|
||||
return NULL;
|
||||
if (oct->length < 2)
|
||||
goto done;
|
||||
p = oct->data;
|
||||
n2s(p, listlen);
|
||||
if (listlen != oct->length - 2)
|
||||
goto done;
|
||||
|
||||
if ((sk = sk_SCT_new_null()) == NULL)
|
||||
goto done;
|
||||
|
||||
while (listlen > 0) {
|
||||
if (listlen < 2)
|
||||
goto err;
|
||||
n2s(p, sctlen);
|
||||
listlen -= 2;
|
||||
|
||||
if ((sctlen < 1) || (sctlen > listlen))
|
||||
goto err;
|
||||
listlen -= sctlen;
|
||||
|
||||
sct = OPENSSL_malloc(sizeof(SCT));
|
||||
if (!sct)
|
||||
goto err;
|
||||
if (!sk_SCT_push(sk, sct)) {
|
||||
OPENSSL_free(sct);
|
||||
goto err;
|
||||
}
|
||||
|
||||
sct->sct = OPENSSL_malloc(sctlen);
|
||||
if (!sct->sct)
|
||||
goto err;
|
||||
memcpy(sct->sct, p, sctlen);
|
||||
sct->sctlen = sctlen;
|
||||
p += sctlen;
|
||||
p2 = sct->sct;
|
||||
|
||||
sct->version = *p2++;
|
||||
if (sct->version == 0) { /* SCT v1 */
|
||||
/*-
|
||||
* Fixed-length header:
|
||||
* struct {
|
||||
* (1 byte) Version sct_version;
|
||||
* (32 bytes) LogID id;
|
||||
* (8 bytes) uint64 timestamp;
|
||||
* (2 bytes + ?) CtExtensions extensions;
|
||||
*/
|
||||
if (sctlen < 43)
|
||||
goto err;
|
||||
sctlen -= 43;
|
||||
|
||||
sct->logid = p2;
|
||||
sct->logidlen = 32;
|
||||
p2 += 32;
|
||||
|
||||
n2l8(p2, sct->timestamp);
|
||||
|
||||
n2s(p2, fieldlen);
|
||||
if (sctlen < fieldlen)
|
||||
goto err;
|
||||
sct->ext = p2;
|
||||
sct->extlen = fieldlen;
|
||||
p2 += fieldlen;
|
||||
sctlen -= fieldlen;
|
||||
|
||||
/*-
|
||||
* digitally-signed struct header:
|
||||
* (1 byte) Hash algorithm
|
||||
* (1 byte) Signature algorithm
|
||||
* (2 bytes + ?) Signature
|
||||
*/
|
||||
if (sctlen < 4)
|
||||
goto err;
|
||||
sctlen -= 4;
|
||||
|
||||
sct->hash_alg = *p2++;
|
||||
sct->sig_alg = *p2++;
|
||||
n2s(p2, fieldlen);
|
||||
if (sctlen != fieldlen)
|
||||
goto err;
|
||||
sct->sig = p2;
|
||||
sct->siglen = fieldlen;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
ASN1_OCTET_STRING_free(oct);
|
||||
return sk;
|
||||
|
||||
err:
|
||||
SCT_LIST_free(sk);
|
||||
sk = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list,
|
||||
BIO *out, int indent)
|
||||
{
|
||||
SCT *sct;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sk_SCT_num(sct_list);) {
|
||||
sct = sk_SCT_value(sct_list, i);
|
||||
|
||||
BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, "");
|
||||
BIO_printf(out, "\n%*sVersion : ", indent + 4, "");
|
||||
|
||||
if (sct->version == 0) { /* SCT v1 */
|
||||
BIO_printf(out, "v1(0)");
|
||||
|
||||
BIO_printf(out, "\n%*sLog ID : ", indent + 4, "");
|
||||
BIO_hex_string(out, indent + 16, 16, sct->logid, sct->logidlen);
|
||||
|
||||
BIO_printf(out, "\n%*sTimestamp : ", indent + 4, "");
|
||||
timestamp_print(out, sct->timestamp);
|
||||
|
||||
BIO_printf(out, "\n%*sExtensions: ", indent + 4, "");
|
||||
if (sct->extlen == 0)
|
||||
BIO_printf(out, "none");
|
||||
else
|
||||
BIO_hex_string(out, indent + 16, 16, sct->ext, sct->extlen);
|
||||
|
||||
BIO_printf(out, "\n%*sSignature : ", indent + 4, "");
|
||||
tls12_signature_print(out, sct->hash_alg, sct->sig_alg);
|
||||
BIO_printf(out, "\n%*s ", indent + 4, "");
|
||||
BIO_hex_string(out, indent + 16, 16, sct->sig, sct->siglen);
|
||||
} else { /* Unknown version */
|
||||
|
||||
BIO_printf(out, "unknown\n%*s", indent + 16, "");
|
||||
BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sctlen);
|
||||
}
|
||||
|
||||
if (++i < sk_SCT_num(sct_list))
|
||||
BIO_printf(out, "\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
/* v3_skey.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,89 +57,94 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
|
||||
const X509V3_EXT_METHOD v3_skey_id = {
|
||||
NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
|
||||
0,0,0,0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
|
||||
(X509V3_EXT_S2I)s2i_skey_id,
|
||||
0,0,0,0,
|
||||
NULL};
|
||||
static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *str);
|
||||
const X509V3_EXT_METHOD v3_skey_id = {
|
||||
NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
|
||||
0, 0, 0, 0,
|
||||
(X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
|
||||
(X509V3_EXT_S2I)s2i_skey_id,
|
||||
0, 0, 0, 0,
|
||||
NULL
|
||||
};
|
||||
|
||||
char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
|
||||
ASN1_OCTET_STRING *oct)
|
||||
char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct)
|
||||
{
|
||||
return hex_to_string(oct->data, oct->length);
|
||||
return hex_to_string(oct->data, oct->length);
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *str)
|
||||
X509V3_CTX *ctx, char *str)
|
||||
{
|
||||
ASN1_OCTET_STRING *oct;
|
||||
long length;
|
||||
ASN1_OCTET_STRING *oct;
|
||||
long length;
|
||||
|
||||
if(!(oct = M_ASN1_OCTET_STRING_new())) {
|
||||
X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (!(oct = M_ASN1_OCTET_STRING_new())) {
|
||||
X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!(oct->data = string_to_hex(str, &length))) {
|
||||
M_ASN1_OCTET_STRING_free(oct);
|
||||
return NULL;
|
||||
}
|
||||
if (!(oct->data = string_to_hex(str, &length))) {
|
||||
M_ASN1_OCTET_STRING_free(oct);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oct->length = length;
|
||||
oct->length = length;
|
||||
|
||||
return oct;
|
||||
return oct;
|
||||
|
||||
}
|
||||
|
||||
static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *str)
|
||||
X509V3_CTX *ctx, char *str)
|
||||
{
|
||||
ASN1_OCTET_STRING *oct;
|
||||
ASN1_BIT_STRING *pk;
|
||||
unsigned char pkey_dig[EVP_MAX_MD_SIZE];
|
||||
unsigned int diglen;
|
||||
ASN1_OCTET_STRING *oct;
|
||||
ASN1_BIT_STRING *pk;
|
||||
unsigned char pkey_dig[EVP_MAX_MD_SIZE];
|
||||
unsigned int diglen;
|
||||
|
||||
if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
|
||||
if (strcmp(str, "hash"))
|
||||
return s2i_ASN1_OCTET_STRING(method, ctx, str);
|
||||
|
||||
if(!(oct = M_ASN1_OCTET_STRING_new())) {
|
||||
X509V3err(X509V3_F_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (!(oct = M_ASN1_OCTET_STRING_new())) {
|
||||
X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ctx && (ctx->flags == CTX_TEST)) return oct;
|
||||
if (ctx && (ctx->flags == CTX_TEST))
|
||||
return oct;
|
||||
|
||||
if(!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
|
||||
X509V3err(X509V3_F_S2I_SKEY_ID,X509V3_R_NO_PUBLIC_KEY);
|
||||
goto err;
|
||||
}
|
||||
if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
|
||||
X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if(ctx->subject_req)
|
||||
pk = ctx->subject_req->req_info->pubkey->public_key;
|
||||
else pk = ctx->subject_cert->cert_info->key->public_key;
|
||||
if (ctx->subject_req)
|
||||
pk = ctx->subject_req->req_info->pubkey->public_key;
|
||||
else
|
||||
pk = ctx->subject_cert->cert_info->key->public_key;
|
||||
|
||||
if(!pk) {
|
||||
X509V3err(X509V3_F_S2I_SKEY_ID,X509V3_R_NO_PUBLIC_KEY);
|
||||
goto err;
|
||||
}
|
||||
if (!pk) {
|
||||
X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL);
|
||||
if (!EVP_Digest
|
||||
(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL))
|
||||
goto err;
|
||||
|
||||
if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
|
||||
X509V3err(X509V3_F_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
|
||||
X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return oct;
|
||||
|
||||
err:
|
||||
M_ASN1_OCTET_STRING_free(oct);
|
||||
return NULL;
|
||||
return oct;
|
||||
|
||||
err:
|
||||
M_ASN1_OCTET_STRING_free(oct);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3_sxnet.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -67,196 +68,206 @@
|
||||
|
||||
#define SXNET_TEST
|
||||
|
||||
static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent);
|
||||
static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
|
||||
int indent);
|
||||
#ifdef SXNET_TEST
|
||||
static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval);
|
||||
static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval);
|
||||
#endif
|
||||
const X509V3_EXT_METHOD v3_sxnet = {
|
||||
NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
|
||||
0,0,0,0,
|
||||
0,0,
|
||||
0,
|
||||
NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
0,
|
||||
#ifdef SXNET_TEST
|
||||
(X509V3_EXT_V2I)sxnet_v2i,
|
||||
(X509V3_EXT_V2I)sxnet_v2i,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif
|
||||
(X509V3_EXT_I2R)sxnet_i2r,
|
||||
0,
|
||||
NULL
|
||||
(X509V3_EXT_I2R)sxnet_i2r,
|
||||
0,
|
||||
NULL
|
||||
};
|
||||
|
||||
ASN1_SEQUENCE(SXNETID) = {
|
||||
ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
|
||||
ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(SXNETID)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(SXNETID)
|
||||
|
||||
ASN1_SEQUENCE(SXNET) = {
|
||||
ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
|
||||
ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
|
||||
ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
|
||||
ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
|
||||
} ASN1_SEQUENCE_END(SXNET)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(SXNET)
|
||||
|
||||
static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
|
||||
int indent)
|
||||
int indent)
|
||||
{
|
||||
long v;
|
||||
char *tmp;
|
||||
SXNETID *id;
|
||||
int i;
|
||||
v = ASN1_INTEGER_get(sx->version);
|
||||
BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
|
||||
for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
|
||||
id = sk_SXNETID_value(sx->ids, i);
|
||||
tmp = i2s_ASN1_INTEGER(NULL, id->zone);
|
||||
BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
|
||||
OPENSSL_free(tmp);
|
||||
M_ASN1_OCTET_STRING_print(out, id->user);
|
||||
}
|
||||
return 1;
|
||||
long v;
|
||||
char *tmp;
|
||||
SXNETID *id;
|
||||
int i;
|
||||
v = ASN1_INTEGER_get(sx->version);
|
||||
BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
|
||||
for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
|
||||
id = sk_SXNETID_value(sx->ids, i);
|
||||
tmp = i2s_ASN1_INTEGER(NULL, id->zone);
|
||||
BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
|
||||
OPENSSL_free(tmp);
|
||||
M_ASN1_OCTET_STRING_print(out, id->user);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef SXNET_TEST
|
||||
|
||||
/* NBB: this is used for testing only. It should *not* be used for anything
|
||||
/*
|
||||
* NBB: this is used for testing only. It should *not* be used for anything
|
||||
* else because it will just take static IDs from the configuration file and
|
||||
* they should really be separate values for each user.
|
||||
*/
|
||||
|
||||
|
||||
static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
CONF_VALUE *cnf;
|
||||
SXNET *sx = NULL;
|
||||
int i;
|
||||
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if(!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
|
||||
return NULL;
|
||||
}
|
||||
return sx;
|
||||
CONF_VALUE *cnf;
|
||||
SXNET *sx = NULL;
|
||||
int i;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
|
||||
return NULL;
|
||||
}
|
||||
return sx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* Strong Extranet utility functions */
|
||||
|
||||
/* Add an id given the zone as an ASCII number */
|
||||
|
||||
int SXNET_add_id_asc(SXNET **psx, char *zone, char *user,
|
||||
int userlen)
|
||||
int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen)
|
||||
{
|
||||
ASN1_INTEGER *izone = NULL;
|
||||
if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
|
||||
return 0;
|
||||
}
|
||||
return SXNET_add_id_INTEGER(psx, izone, user, userlen);
|
||||
ASN1_INTEGER *izone = NULL;
|
||||
if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE);
|
||||
return 0;
|
||||
}
|
||||
return SXNET_add_id_INTEGER(psx, izone, user, userlen);
|
||||
}
|
||||
|
||||
/* Add an id given the zone as an unsigned long */
|
||||
|
||||
int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
|
||||
int userlen)
|
||||
int userlen)
|
||||
{
|
||||
ASN1_INTEGER *izone = NULL;
|
||||
if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_ULONG,ERR_R_MALLOC_FAILURE);
|
||||
M_ASN1_INTEGER_free(izone);
|
||||
return 0;
|
||||
}
|
||||
return SXNET_add_id_INTEGER(psx, izone, user, userlen);
|
||||
|
||||
ASN1_INTEGER *izone = NULL;
|
||||
if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE);
|
||||
M_ASN1_INTEGER_free(izone);
|
||||
return 0;
|
||||
}
|
||||
return SXNET_add_id_INTEGER(psx, izone, user, userlen);
|
||||
|
||||
}
|
||||
|
||||
/* Add an id given the zone as an ASN1_INTEGER.
|
||||
* Note this version uses the passed integer and doesn't make a copy so don't
|
||||
* free it up afterwards.
|
||||
/*
|
||||
* Add an id given the zone as an ASN1_INTEGER. Note this version uses the
|
||||
* passed integer and doesn't make a copy so don't free it up afterwards.
|
||||
*/
|
||||
|
||||
int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
|
||||
int userlen)
|
||||
int userlen)
|
||||
{
|
||||
SXNET *sx = NULL;
|
||||
SXNETID *id = NULL;
|
||||
if(!psx || !zone || !user) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_INVALID_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if(userlen == -1) userlen = strlen(user);
|
||||
if(userlen > 64) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_USER_TOO_LONG);
|
||||
return 0;
|
||||
}
|
||||
if(!*psx) {
|
||||
if(!(sx = SXNET_new())) goto err;
|
||||
if(!ASN1_INTEGER_set(sx->version, 0)) goto err;
|
||||
*psx = sx;
|
||||
} else sx = *psx;
|
||||
if(SXNET_get_id_INTEGER(sx, zone)) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_DUPLICATE_ZONE_ID);
|
||||
return 0;
|
||||
}
|
||||
SXNET *sx = NULL;
|
||||
SXNETID *id = NULL;
|
||||
if (!psx || !zone || !user) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,
|
||||
X509V3_R_INVALID_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (userlen == -1)
|
||||
userlen = strlen(user);
|
||||
if (userlen > 64) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_USER_TOO_LONG);
|
||||
return 0;
|
||||
}
|
||||
if (!*psx) {
|
||||
if (!(sx = SXNET_new()))
|
||||
goto err;
|
||||
if (!ASN1_INTEGER_set(sx->version, 0))
|
||||
goto err;
|
||||
*psx = sx;
|
||||
} else
|
||||
sx = *psx;
|
||||
if (SXNET_get_id_INTEGER(sx, zone)) {
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_DUPLICATE_ZONE_ID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!(id = SXNETID_new())) goto err;
|
||||
if(userlen == -1) userlen = strlen(user);
|
||||
|
||||
if(!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) goto err;
|
||||
if(!sk_SXNETID_push(sx->ids, id)) goto err;
|
||||
id->zone = zone;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,ERR_R_MALLOC_FAILURE);
|
||||
SXNETID_free(id);
|
||||
SXNET_free(sx);
|
||||
*psx = NULL;
|
||||
return 0;
|
||||
if (!(id = SXNETID_new()))
|
||||
goto err;
|
||||
if (userlen == -1)
|
||||
userlen = strlen(user);
|
||||
|
||||
if (!M_ASN1_OCTET_STRING_set(id->user, user, userlen))
|
||||
goto err;
|
||||
if (!sk_SXNETID_push(sx->ids, id))
|
||||
goto err;
|
||||
id->zone = zone;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE);
|
||||
SXNETID_free(id);
|
||||
SXNET_free(sx);
|
||||
*psx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
|
||||
{
|
||||
ASN1_INTEGER *izone = NULL;
|
||||
ASN1_OCTET_STRING *oct;
|
||||
if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
|
||||
X509V3err(X509V3_F_SXNET_GET_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
|
||||
return NULL;
|
||||
}
|
||||
oct = SXNET_get_id_INTEGER(sx, izone);
|
||||
M_ASN1_INTEGER_free(izone);
|
||||
return oct;
|
||||
ASN1_INTEGER *izone = NULL;
|
||||
ASN1_OCTET_STRING *oct;
|
||||
if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
|
||||
X509V3err(X509V3_F_SXNET_GET_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE);
|
||||
return NULL;
|
||||
}
|
||||
oct = SXNET_get_id_INTEGER(sx, izone);
|
||||
M_ASN1_INTEGER_free(izone);
|
||||
return oct;
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
|
||||
{
|
||||
ASN1_INTEGER *izone = NULL;
|
||||
ASN1_OCTET_STRING *oct;
|
||||
if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
|
||||
X509V3err(X509V3_F_SXNET_GET_ID_ULONG,ERR_R_MALLOC_FAILURE);
|
||||
M_ASN1_INTEGER_free(izone);
|
||||
return NULL;
|
||||
}
|
||||
oct = SXNET_get_id_INTEGER(sx, izone);
|
||||
M_ASN1_INTEGER_free(izone);
|
||||
return oct;
|
||||
ASN1_INTEGER *izone = NULL;
|
||||
ASN1_OCTET_STRING *oct;
|
||||
if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
|
||||
X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE);
|
||||
M_ASN1_INTEGER_free(izone);
|
||||
return NULL;
|
||||
}
|
||||
oct = SXNET_get_id_INTEGER(sx, izone);
|
||||
M_ASN1_INTEGER_free(izone);
|
||||
return oct;
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
|
||||
{
|
||||
SXNETID *id;
|
||||
int i;
|
||||
for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
|
||||
id = sk_SXNETID_value(sx->ids, i);
|
||||
if(!M_ASN1_INTEGER_cmp(id->zone, zone)) return id->user;
|
||||
}
|
||||
return NULL;
|
||||
SXNETID *id;
|
||||
int i;
|
||||
for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
|
||||
id = sk_SXNETID_value(sx->ids, i);
|
||||
if (!M_ASN1_INTEGER_cmp(id->zone, zone))
|
||||
return id->user;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IMPLEMENT_STACK_OF(SXNETID)
|
||||
|
||||
IMPLEMENT_ASN1_SET_OF(SXNETID)
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
/* v3conf.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1.h>
|
||||
@@ -68,60 +68,62 @@
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
LHASH *conf;
|
||||
X509 *cert;
|
||||
FILE *inf;
|
||||
char *conf_file;
|
||||
int i;
|
||||
int count;
|
||||
X509_EXTENSION *ext;
|
||||
X509V3_add_standard_extensions();
|
||||
ERR_load_crypto_strings();
|
||||
if(!argv[1]) {
|
||||
fprintf(stderr, "Usage: v3conf cert.pem [file.cnf]\n");
|
||||
exit(1);
|
||||
}
|
||||
conf_file = argv[2];
|
||||
if(!conf_file) conf_file = "test.cnf";
|
||||
conf = CONF_load(NULL, "test.cnf", NULL);
|
||||
if(!conf) {
|
||||
fprintf(stderr, "Error opening Config file %s\n", conf_file);
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
LHASH *conf;
|
||||
X509 *cert;
|
||||
FILE *inf;
|
||||
char *conf_file;
|
||||
int i;
|
||||
int count;
|
||||
X509_EXTENSION *ext;
|
||||
X509V3_add_standard_extensions();
|
||||
ERR_load_crypto_strings();
|
||||
if (!argv[1]) {
|
||||
fprintf(stderr, "Usage: v3conf cert.pem [file.cnf]\n");
|
||||
exit(1);
|
||||
}
|
||||
conf_file = argv[2];
|
||||
if (!conf_file)
|
||||
conf_file = "test.cnf";
|
||||
conf = CONF_load(NULL, "test.cnf", NULL);
|
||||
if (!conf) {
|
||||
fprintf(stderr, "Error opening Config file %s\n", conf_file);
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inf = fopen(argv[1], "r");
|
||||
if(!inf) {
|
||||
fprintf(stderr, "Can't open certificate file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
cert = PEM_read_X509(inf, NULL, NULL);
|
||||
if(!cert) {
|
||||
fprintf(stderr, "Error reading certificate file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
fclose(inf);
|
||||
inf = fopen(argv[1], "r");
|
||||
if (!inf) {
|
||||
fprintf(stderr, "Can't open certificate file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
cert = PEM_read_X509(inf, NULL, NULL);
|
||||
if (!cert) {
|
||||
fprintf(stderr, "Error reading certificate file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
fclose(inf);
|
||||
|
||||
sk_pop_free(cert->cert_info->extensions, X509_EXTENSION_free);
|
||||
cert->cert_info->extensions = NULL;
|
||||
sk_pop_free(cert->cert_info->extensions, X509_EXTENSION_free);
|
||||
cert->cert_info->extensions = NULL;
|
||||
|
||||
if(!X509V3_EXT_add_conf(conf, NULL, "test_section", cert)) {
|
||||
fprintf(stderr, "Error adding extensions\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (!X509V3_EXT_add_conf(conf, NULL, "test_section", cert)) {
|
||||
fprintf(stderr, "Error adding extensions\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
count = X509_get_ext_count(cert);
|
||||
printf("%d extensions\n", count);
|
||||
for(i = 0; i < count; i++) {
|
||||
ext = X509_get_ext(cert, i);
|
||||
printf("%s", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
|
||||
if(ext->critical) printf(",critical:\n");
|
||||
else printf(":\n");
|
||||
X509V3_EXT_print_fp(stdout, ext, 0, 0);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
return 0;
|
||||
count = X509_get_ext_count(cert);
|
||||
printf("%d extensions\n", count);
|
||||
for (i = 0; i < count; i++) {
|
||||
ext = X509_get_ext(cert, i);
|
||||
printf("%s", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
|
||||
if (ext->critical)
|
||||
printf(",critical:\n");
|
||||
else
|
||||
printf(":\n");
|
||||
X509V3_EXT_print_fp(stdout, ext, 0, 0);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/* crypto/x509v3/v3err.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -53,7 +53,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
|
||||
/*
|
||||
* NOTE: this file was auto generated by the mkerr.pl script: any changes
|
||||
* made to it will be overwritten when the script next updates this file,
|
||||
* only reason strings will be preserved.
|
||||
*/
|
||||
@@ -65,162 +66,184 @@
|
||||
/* BEGIN ERROR CODES */
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0)
|
||||
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason)
|
||||
# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0)
|
||||
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason)
|
||||
|
||||
static ERR_STRING_DATA X509V3_str_functs[]=
|
||||
{
|
||||
{ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "A2I_GENERAL_NAME"},
|
||||
{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE), "ASIDENTIFIERCHOICE_CANONIZE"},
|
||||
{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL), "ASIDENTIFIERCHOICE_IS_CANONICAL"},
|
||||
{ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"},
|
||||
{ERR_FUNC(X509V3_F_COPY_ISSUER), "COPY_ISSUER"},
|
||||
{ERR_FUNC(X509V3_F_DO_DIRNAME), "DO_DIRNAME"},
|
||||
{ERR_FUNC(X509V3_F_DO_EXT_CONF), "DO_EXT_CONF"},
|
||||
{ERR_FUNC(X509V3_F_DO_EXT_I2D), "DO_EXT_I2D"},
|
||||
{ERR_FUNC(X509V3_F_DO_EXT_NCONF), "DO_EXT_NCONF"},
|
||||
{ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"},
|
||||
{ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "GNAMES_FROM_SECTNAME"},
|
||||
{ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"},
|
||||
{ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"},
|
||||
{ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "I2S_ASN1_IA5STRING"},
|
||||
{ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"},
|
||||
{ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS), "I2V_AUTHORITY_INFO_ACCESS"},
|
||||
{ERR_FUNC(X509V3_F_NOTICE_SECTION), "NOTICE_SECTION"},
|
||||
{ERR_FUNC(X509V3_F_NREF_NOS), "NREF_NOS"},
|
||||
{ERR_FUNC(X509V3_F_POLICY_SECTION), "POLICY_SECTION"},
|
||||
{ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE), "PROCESS_PCI_VALUE"},
|
||||
{ERR_FUNC(X509V3_F_R2I_CERTPOL), "R2I_CERTPOL"},
|
||||
{ERR_FUNC(X509V3_F_R2I_PCI), "R2I_PCI"},
|
||||
{ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING), "S2I_ASN1_IA5STRING"},
|
||||
{ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER), "s2i_ASN1_INTEGER"},
|
||||
{ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"},
|
||||
{ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"},
|
||||
{ERR_FUNC(X509V3_F_S2I_SKEY_ID), "S2I_SKEY_ID"},
|
||||
{ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "SET_DIST_POINT_NAME"},
|
||||
{ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC), "SXNET_get_id_asc"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG), "SXNET_get_id_ulong"},
|
||||
{ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS), "V2I_ASIDENTIFIERS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING), "v2i_ASN1_BIT_STRING"},
|
||||
{ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS), "V2I_AUTHORITY_INFO_ACCESS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID), "V2I_AUTHORITY_KEYID"},
|
||||
{ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS), "V2I_BASIC_CONSTRAINTS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_CRLD), "V2I_CRLD"},
|
||||
{ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "V2I_EXTENDED_KEY_USAGE"},
|
||||
{ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"},
|
||||
{ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"},
|
||||
{ERR_FUNC(X509V3_F_V2I_IDP), "V2I_IDP"},
|
||||
{ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "V2I_IPADDRBLOCKS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "V2I_ISSUER_ALT"},
|
||||
{ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "V2I_NAME_CONSTRAINTS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "V2I_POLICY_CONSTRAINTS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "V2I_POLICY_MAPPINGS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "V2I_SUBJECT_ALT"},
|
||||
{ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL), "V3_ADDR_VALIDATE_PATH_INTERNAL"},
|
||||
{ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "V3_GENERIC_EXTENSION"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_ADD), "X509V3_EXT_add"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS), "X509V3_EXT_add_alias"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_CONF), "X509V3_EXT_conf"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_I2D), "X509V3_EXT_i2d"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_NCONF), "X509V3_EXT_nconf"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_GET_SECTION), "X509V3_get_section"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_GET_STRING), "X509V3_get_string"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL), "X509V3_get_value_bool"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_PARSE_LIST), "X509V3_parse_list"},
|
||||
{ERR_FUNC(X509V3_F_X509_PURPOSE_ADD), "X509_PURPOSE_add"},
|
||||
{ERR_FUNC(X509V3_F_X509_PURPOSE_SET), "X509_PURPOSE_set"},
|
||||
{0,NULL}
|
||||
};
|
||||
static ERR_STRING_DATA X509V3_str_functs[] = {
|
||||
{ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "a2i_GENERAL_NAME"},
|
||||
{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE),
|
||||
"ASIDENTIFIERCHOICE_CANONIZE"},
|
||||
{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL),
|
||||
"ASIDENTIFIERCHOICE_IS_CANONICAL"},
|
||||
{ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"},
|
||||
{ERR_FUNC(X509V3_F_COPY_ISSUER), "COPY_ISSUER"},
|
||||
{ERR_FUNC(X509V3_F_DO_DIRNAME), "DO_DIRNAME"},
|
||||
{ERR_FUNC(X509V3_F_DO_EXT_CONF), "DO_EXT_CONF"},
|
||||
{ERR_FUNC(X509V3_F_DO_EXT_I2D), "DO_EXT_I2D"},
|
||||
{ERR_FUNC(X509V3_F_DO_EXT_NCONF), "DO_EXT_NCONF"},
|
||||
{ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"},
|
||||
{ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "GNAMES_FROM_SECTNAME"},
|
||||
{ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"},
|
||||
{ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"},
|
||||
{ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "I2S_ASN1_IA5STRING"},
|
||||
{ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"},
|
||||
{ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS),
|
||||
"I2V_AUTHORITY_INFO_ACCESS"},
|
||||
{ERR_FUNC(X509V3_F_NOTICE_SECTION), "NOTICE_SECTION"},
|
||||
{ERR_FUNC(X509V3_F_NREF_NOS), "NREF_NOS"},
|
||||
{ERR_FUNC(X509V3_F_POLICY_SECTION), "POLICY_SECTION"},
|
||||
{ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE), "PROCESS_PCI_VALUE"},
|
||||
{ERR_FUNC(X509V3_F_R2I_CERTPOL), "R2I_CERTPOL"},
|
||||
{ERR_FUNC(X509V3_F_R2I_PCI), "R2I_PCI"},
|
||||
{ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING), "S2I_ASN1_IA5STRING"},
|
||||
{ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER), "s2i_ASN1_INTEGER"},
|
||||
{ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"},
|
||||
{ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"},
|
||||
{ERR_FUNC(X509V3_F_S2I_SKEY_ID), "S2I_SKEY_ID"},
|
||||
{ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "SET_DIST_POINT_NAME"},
|
||||
{ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC), "SXNET_get_id_asc"},
|
||||
{ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG), "SXNET_get_id_ulong"},
|
||||
{ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS), "V2I_ASIDENTIFIERS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING), "v2i_ASN1_BIT_STRING"},
|
||||
{ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS),
|
||||
"V2I_AUTHORITY_INFO_ACCESS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID), "V2I_AUTHORITY_KEYID"},
|
||||
{ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS), "V2I_BASIC_CONSTRAINTS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_CRLD), "V2I_CRLD"},
|
||||
{ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "V2I_EXTENDED_KEY_USAGE"},
|
||||
{ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"},
|
||||
{ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"},
|
||||
{ERR_FUNC(X509V3_F_V2I_IDP), "V2I_IDP"},
|
||||
{ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "V2I_IPADDRBLOCKS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "V2I_ISSUER_ALT"},
|
||||
{ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "V2I_NAME_CONSTRAINTS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "V2I_POLICY_CONSTRAINTS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "V2I_POLICY_MAPPINGS"},
|
||||
{ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "V2I_SUBJECT_ALT"},
|
||||
{ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL),
|
||||
"V3_ADDR_VALIDATE_PATH_INTERNAL"},
|
||||
{ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "V3_GENERIC_EXTENSION"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_ADD), "X509V3_EXT_add"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS), "X509V3_EXT_add_alias"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_CONF), "X509V3_EXT_conf"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_FREE), "X509V3_EXT_free"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_I2D), "X509V3_EXT_i2d"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_EXT_NCONF), "X509V3_EXT_nconf"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_GET_SECTION), "X509V3_get_section"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_GET_STRING), "X509V3_get_string"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL), "X509V3_get_value_bool"},
|
||||
{ERR_FUNC(X509V3_F_X509V3_PARSE_LIST), "X509V3_parse_list"},
|
||||
{ERR_FUNC(X509V3_F_X509_PURPOSE_ADD), "X509_PURPOSE_add"},
|
||||
{ERR_FUNC(X509V3_F_X509_PURPOSE_SET), "X509_PURPOSE_set"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA X509V3_str_reasons[]=
|
||||
{
|
||||
{ERR_REASON(X509V3_R_BAD_IP_ADDRESS) ,"bad ip address"},
|
||||
{ERR_REASON(X509V3_R_BAD_OBJECT) ,"bad object"},
|
||||
{ERR_REASON(X509V3_R_BN_DEC2BN_ERROR) ,"bn dec2bn error"},
|
||||
{ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),"bn to asn1 integer error"},
|
||||
{ERR_REASON(X509V3_R_DIRNAME_ERROR) ,"dirname error"},
|
||||
{ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET),"distpoint already set"},
|
||||
{ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID) ,"duplicate zone id"},
|
||||
{ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE),"error converting zone"},
|
||||
{ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),"error creating extension"},
|
||||
{ERR_REASON(X509V3_R_ERROR_IN_EXTENSION) ,"error in extension"},
|
||||
{ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME),"expected a section name"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_EXISTS) ,"extension exists"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR),"extension name error"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND),"extension not found"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED),"extension setting not supported"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR),"extension value error"},
|
||||
{ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION),"illegal empty extension"},
|
||||
{ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT) ,"illegal hex digit"},
|
||||
{ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),"incorrect policy syntax tag"},
|
||||
{ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS),"invalid multiple rdns"},
|
||||
{ERR_REASON(X509V3_R_INVALID_ASNUMBER) ,"invalid asnumber"},
|
||||
{ERR_REASON(X509V3_R_INVALID_ASRANGE) ,"invalid asrange"},
|
||||
{ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING),"invalid boolean string"},
|
||||
{ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING),"invalid extension string"},
|
||||
{ERR_REASON(X509V3_R_INVALID_INHERITANCE),"invalid inheritance"},
|
||||
{ERR_REASON(X509V3_R_INVALID_IPADDRESS) ,"invalid ipaddress"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NAME) ,"invalid name"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT),"invalid null argument"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NULL_NAME) ,"invalid null name"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NULL_VALUE) ,"invalid null value"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NUMBER) ,"invalid number"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NUMBERS) ,"invalid numbers"},
|
||||
{ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER),"invalid object identifier"},
|
||||
{ERR_REASON(X509V3_R_INVALID_OPTION) ,"invalid option"},
|
||||
{ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER),"invalid policy identifier"},
|
||||
{ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING),"invalid proxy policy setting"},
|
||||
{ERR_REASON(X509V3_R_INVALID_PURPOSE) ,"invalid purpose"},
|
||||
{ERR_REASON(X509V3_R_INVALID_SAFI) ,"invalid safi"},
|
||||
{ERR_REASON(X509V3_R_INVALID_SECTION) ,"invalid section"},
|
||||
{ERR_REASON(X509V3_R_INVALID_SYNTAX) ,"invalid syntax"},
|
||||
{ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR),"issuer decode error"},
|
||||
{ERR_REASON(X509V3_R_MISSING_VALUE) ,"missing value"},
|
||||
{ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS),"need organization and numbers"},
|
||||
{ERR_REASON(X509V3_R_NO_CONFIG_DATABASE) ,"no config database"},
|
||||
{ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE),"no issuer certificate"},
|
||||
{ERR_REASON(X509V3_R_NO_ISSUER_DETAILS) ,"no issuer details"},
|
||||
{ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER),"no policy identifier"},
|
||||
{ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED),"no proxy cert policy language defined"},
|
||||
{ERR_REASON(X509V3_R_NO_PUBLIC_KEY) ,"no public key"},
|
||||
{ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS) ,"no subject details"},
|
||||
{ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS),"odd number of digits"},
|
||||
{ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED),"operation not defined"},
|
||||
{ERR_REASON(X509V3_R_OTHERNAME_ERROR) ,"othername error"},
|
||||
{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED),"policy language already defined"},
|
||||
{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) ,"policy path length"},
|
||||
{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED),"policy path length already defined"},
|
||||
{ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED),"policy syntax not currently supported"},
|
||||
{ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY),"policy when proxy language requires no policy"},
|
||||
{ERR_REASON(X509V3_R_SECTION_NOT_FOUND) ,"section not found"},
|
||||
{ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS),"unable to get issuer details"},
|
||||
{ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID),"unable to get issuer keyid"},
|
||||
{ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT),"unknown bit string argument"},
|
||||
{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION) ,"unknown extension"},
|
||||
{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME),"unknown extension name"},
|
||||
{ERR_REASON(X509V3_R_UNKNOWN_OPTION) ,"unknown option"},
|
||||
{ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) ,"unsupported option"},
|
||||
{ERR_REASON(X509V3_R_UNSUPPORTED_TYPE) ,"unsupported type"},
|
||||
{ERR_REASON(X509V3_R_USER_TOO_LONG) ,"user too long"},
|
||||
{0,NULL}
|
||||
};
|
||||
static ERR_STRING_DATA X509V3_str_reasons[] = {
|
||||
{ERR_REASON(X509V3_R_BAD_IP_ADDRESS), "bad ip address"},
|
||||
{ERR_REASON(X509V3_R_BAD_OBJECT), "bad object"},
|
||||
{ERR_REASON(X509V3_R_BN_DEC2BN_ERROR), "bn dec2bn error"},
|
||||
{ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),
|
||||
"bn to asn1 integer error"},
|
||||
{ERR_REASON(X509V3_R_CANNOT_FIND_FREE_FUNCTION),
|
||||
"cannot find free function"},
|
||||
{ERR_REASON(X509V3_R_DIRNAME_ERROR), "dirname error"},
|
||||
{ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"},
|
||||
{ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID), "duplicate zone id"},
|
||||
{ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"},
|
||||
{ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),
|
||||
"error creating extension"},
|
||||
{ERR_REASON(X509V3_R_ERROR_IN_EXTENSION), "error in extension"},
|
||||
{ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_EXISTS), "extension exists"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED),
|
||||
"extension setting not supported"},
|
||||
{ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"},
|
||||
{ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"},
|
||||
{ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT), "illegal hex digit"},
|
||||
{ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),
|
||||
"incorrect policy syntax tag"},
|
||||
{ERR_REASON(X509V3_R_INVALID_ASNUMBER), "invalid asnumber"},
|
||||
{ERR_REASON(X509V3_R_INVALID_ASRANGE), "invalid asrange"},
|
||||
{ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"},
|
||||
{ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING),
|
||||
"invalid extension string"},
|
||||
{ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"},
|
||||
{ERR_REASON(X509V3_R_INVALID_IPADDRESS), "invalid ipaddress"},
|
||||
{ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NAME), "invalid name"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NULL_NAME), "invalid null name"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NULL_VALUE), "invalid null value"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NUMBER), "invalid number"},
|
||||
{ERR_REASON(X509V3_R_INVALID_NUMBERS), "invalid numbers"},
|
||||
{ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER),
|
||||
"invalid object identifier"},
|
||||
{ERR_REASON(X509V3_R_INVALID_OPTION), "invalid option"},
|
||||
{ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER),
|
||||
"invalid policy identifier"},
|
||||
{ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING),
|
||||
"invalid proxy policy setting"},
|
||||
{ERR_REASON(X509V3_R_INVALID_PURPOSE), "invalid purpose"},
|
||||
{ERR_REASON(X509V3_R_INVALID_SAFI), "invalid safi"},
|
||||
{ERR_REASON(X509V3_R_INVALID_SECTION), "invalid section"},
|
||||
{ERR_REASON(X509V3_R_INVALID_SYNTAX), "invalid syntax"},
|
||||
{ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"},
|
||||
{ERR_REASON(X509V3_R_MISSING_VALUE), "missing value"},
|
||||
{ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS),
|
||||
"need organization and numbers"},
|
||||
{ERR_REASON(X509V3_R_NO_CONFIG_DATABASE), "no config database"},
|
||||
{ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"},
|
||||
{ERR_REASON(X509V3_R_NO_ISSUER_DETAILS), "no issuer details"},
|
||||
{ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"},
|
||||
{ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED),
|
||||
"no proxy cert policy language defined"},
|
||||
{ERR_REASON(X509V3_R_NO_PUBLIC_KEY), "no public key"},
|
||||
{ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS), "no subject details"},
|
||||
{ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"},
|
||||
{ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"},
|
||||
{ERR_REASON(X509V3_R_OTHERNAME_ERROR), "othername error"},
|
||||
{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED),
|
||||
"policy language already defined"},
|
||||
{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH), "policy path length"},
|
||||
{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED),
|
||||
"policy path length already defined"},
|
||||
{ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED),
|
||||
"policy syntax not currently supported"},
|
||||
{ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY),
|
||||
"policy when proxy language requires no policy"},
|
||||
{ERR_REASON(X509V3_R_SECTION_NOT_FOUND), "section not found"},
|
||||
{ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS),
|
||||
"unable to get issuer details"},
|
||||
{ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID),
|
||||
"unable to get issuer keyid"},
|
||||
{ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT),
|
||||
"unknown bit string argument"},
|
||||
{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION), "unknown extension"},
|
||||
{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"},
|
||||
{ERR_REASON(X509V3_R_UNKNOWN_OPTION), "unknown option"},
|
||||
{ERR_REASON(X509V3_R_UNSUPPORTED_OPTION), "unsupported option"},
|
||||
{ERR_REASON(X509V3_R_UNSUPPORTED_TYPE), "unsupported type"},
|
||||
{ERR_REASON(X509V3_R_USER_TOO_LONG), "user too long"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void ERR_load_X509V3_strings(void)
|
||||
{
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL)
|
||||
{
|
||||
ERR_load_strings(0,X509V3_str_functs);
|
||||
ERR_load_strings(0,X509V3_str_reasons);
|
||||
}
|
||||
if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings(0, X509V3_str_functs);
|
||||
ERR_load_strings(0, X509V3_str_reasons);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
336
crypto/x509v3/v3nametest.c
Normal file
336
crypto/x509v3/v3nametest.c
Normal file
@@ -0,0 +1,336 @@
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include "../e_os.h"
|
||||
#include <string.h>
|
||||
|
||||
static const char *const names[] = {
|
||||
"a", "b", ".", "*", "@",
|
||||
".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
|
||||
"@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
|
||||
"*@example.com", "test@*.example.com", "example.com", "www.example.com",
|
||||
"test.www.example.com", "*.example.com", "*.www.example.com",
|
||||
"test.*.example.com", "www.*.com",
|
||||
".www.example.com", "*www.example.com",
|
||||
"example.net", "xn--rger-koa.example.com",
|
||||
"a.example.com", "b.example.com",
|
||||
"postmaster@example.com", "Postmaster@example.com",
|
||||
"postmaster@EXAMPLE.COM",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const exceptions[] = {
|
||||
"set CN: host: [*.example.com] matches [a.example.com]",
|
||||
"set CN: host: [*.example.com] matches [b.example.com]",
|
||||
"set CN: host: [*.example.com] matches [www.example.com]",
|
||||
"set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
|
||||
"set CN: host: [*.www.example.com] matches [test.www.example.com]",
|
||||
"set CN: host: [*.www.example.com] matches [.www.example.com]",
|
||||
"set CN: host: [*www.example.com] matches [www.example.com]",
|
||||
"set CN: host: [test.www.example.com] matches [.www.example.com]",
|
||||
"set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
|
||||
"set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
|
||||
"set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]",
|
||||
"set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
|
||||
"set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]",
|
||||
"set emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
|
||||
"set dnsName: host: [*.example.com] matches [www.example.com]",
|
||||
"set dnsName: host: [*.example.com] matches [a.example.com]",
|
||||
"set dnsName: host: [*.example.com] matches [b.example.com]",
|
||||
"set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
|
||||
"set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
|
||||
"set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
|
||||
"set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
|
||||
"set dnsName: host: [*.www.example.com] matches [.www.example.com]",
|
||||
"set dnsName: host: [*www.example.com] matches [www.example.com]",
|
||||
"set dnsName: host: [test.www.example.com] matches [.www.example.com]",
|
||||
"set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
|
||||
"set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
|
||||
"set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
|
||||
"set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int is_exception(const char *msg)
|
||||
{
|
||||
const char *const *p;
|
||||
for (p = exceptions; *p; ++p)
|
||||
if (strcmp(msg, *p) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_cn(X509 *crt, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
X509_NAME *n = NULL;
|
||||
va_list ap;
|
||||
va_start(ap, crt);
|
||||
n = X509_NAME_new();
|
||||
if (n == NULL)
|
||||
goto out;
|
||||
while (1) {
|
||||
int nid;
|
||||
const char *name;
|
||||
nid = va_arg(ap, int);
|
||||
if (nid == 0)
|
||||
break;
|
||||
name = va_arg(ap, const char *);
|
||||
if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
|
||||
(unsigned char *)name, -1, -1, 1))
|
||||
goto out;
|
||||
}
|
||||
if (!X509_set_subject_name(crt, n))
|
||||
goto out;
|
||||
ret = 1;
|
||||
out:
|
||||
X509_NAME_free(n);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
|
||||
X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
|
||||
int nid, int crit, ASN1_OCTET_STRING *data);
|
||||
int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
|
||||
*/
|
||||
|
||||
static int set_altname(X509 *crt, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
GENERAL_NAMES *gens = NULL;
|
||||
GENERAL_NAME *gen = NULL;
|
||||
ASN1_IA5STRING *ia5 = NULL;
|
||||
va_list ap;
|
||||
va_start(ap, crt);
|
||||
gens = sk_GENERAL_NAME_new_null();
|
||||
if (gens == NULL)
|
||||
goto out;
|
||||
while (1) {
|
||||
int type;
|
||||
const char *name;
|
||||
type = va_arg(ap, int);
|
||||
if (type == 0)
|
||||
break;
|
||||
name = va_arg(ap, const char *);
|
||||
|
||||
gen = GENERAL_NAME_new();
|
||||
if (gen == NULL)
|
||||
goto out;
|
||||
ia5 = ASN1_IA5STRING_new();
|
||||
if (ia5 == NULL)
|
||||
goto out;
|
||||
if (!ASN1_STRING_set(ia5, name, -1))
|
||||
goto out;
|
||||
switch (type) {
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
GENERAL_NAME_set0_value(gen, type, ia5);
|
||||
ia5 = NULL;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
sk_GENERAL_NAME_push(gens, gen);
|
||||
gen = NULL;
|
||||
}
|
||||
if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
|
||||
goto out;
|
||||
ret = 1;
|
||||
out:
|
||||
ASN1_IA5STRING_free(ia5);
|
||||
GENERAL_NAME_free(gen);
|
||||
GENERAL_NAMES_free(gens);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_cn1(X509 *crt, const char *name)
|
||||
{
|
||||
return set_cn(crt, NID_commonName, name, 0);
|
||||
}
|
||||
|
||||
static int set_cn_and_email(X509 *crt, const char *name)
|
||||
{
|
||||
return set_cn(crt, NID_commonName, name,
|
||||
NID_pkcs9_emailAddress, "dummy@example.com", 0);
|
||||
}
|
||||
|
||||
static int set_cn2(X509 *crt, const char *name)
|
||||
{
|
||||
return set_cn(crt, NID_commonName, "dummy value",
|
||||
NID_commonName, name, 0);
|
||||
}
|
||||
|
||||
static int set_cn3(X509 *crt, const char *name)
|
||||
{
|
||||
return set_cn(crt, NID_commonName, name,
|
||||
NID_commonName, "dummy value", 0);
|
||||
}
|
||||
|
||||
static int set_email1(X509 *crt, const char *name)
|
||||
{
|
||||
return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
|
||||
}
|
||||
|
||||
static int set_email2(X509 *crt, const char *name)
|
||||
{
|
||||
return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
|
||||
NID_pkcs9_emailAddress, name, 0);
|
||||
}
|
||||
|
||||
static int set_email3(X509 *crt, const char *name)
|
||||
{
|
||||
return set_cn(crt, NID_pkcs9_emailAddress, name,
|
||||
NID_pkcs9_emailAddress, "dummy@example.com", 0);
|
||||
}
|
||||
|
||||
static int set_email_and_cn(X509 *crt, const char *name)
|
||||
{
|
||||
return set_cn(crt, NID_pkcs9_emailAddress, name,
|
||||
NID_commonName, "www.example.org", 0);
|
||||
}
|
||||
|
||||
static int set_altname_dns(X509 *crt, const char *name)
|
||||
{
|
||||
return set_altname(crt, GEN_DNS, name, 0);
|
||||
}
|
||||
|
||||
static int set_altname_email(X509 *crt, const char *name)
|
||||
{
|
||||
return set_altname(crt, GEN_EMAIL, name, 0);
|
||||
}
|
||||
|
||||
struct set_name_fn {
|
||||
int (*fn) (X509 *, const char *);
|
||||
const char *name;
|
||||
int host;
|
||||
int email;
|
||||
};
|
||||
|
||||
static const struct set_name_fn name_fns[] = {
|
||||
{set_cn1, "set CN", 1, 0},
|
||||
{set_cn2, "set CN", 1, 0},
|
||||
{set_cn3, "set CN", 1, 0},
|
||||
{set_cn_and_email, "set CN", 1, 0},
|
||||
{set_email1, "set emailAddress", 0, 1},
|
||||
{set_email2, "set emailAddress", 0, 1},
|
||||
{set_email3, "set emailAddress", 0, 1},
|
||||
{set_email_and_cn, "set emailAddress", 0, 1},
|
||||
{set_altname_dns, "set dnsName", 1, 0},
|
||||
{set_altname_email, "set rfc822Name", 0, 1},
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
|
||||
static X509 *make_cert()
|
||||
{
|
||||
X509 *ret = NULL;
|
||||
X509 *crt = NULL;
|
||||
X509_NAME *issuer = NULL;
|
||||
crt = X509_new();
|
||||
if (crt == NULL)
|
||||
goto out;
|
||||
if (!X509_set_version(crt, 3))
|
||||
goto out;
|
||||
ret = crt;
|
||||
crt = NULL;
|
||||
out:
|
||||
X509_NAME_free(issuer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int errors;
|
||||
|
||||
static void check_message(const struct set_name_fn *fn, const char *op,
|
||||
const char *nameincert, int match, const char *name)
|
||||
{
|
||||
char msg[1024];
|
||||
if (match < 0)
|
||||
return;
|
||||
BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
|
||||
fn->name, op, nameincert,
|
||||
match ? "matches" : "does not match", name);
|
||||
if (is_exception(msg))
|
||||
return;
|
||||
puts(msg);
|
||||
++errors;
|
||||
}
|
||||
|
||||
static void run_cert(X509 *crt, const char *nameincert,
|
||||
const struct set_name_fn *fn)
|
||||
{
|
||||
const char *const *pname = names;
|
||||
while (*pname) {
|
||||
int samename = strcasecmp(nameincert, *pname) == 0;
|
||||
size_t namelen = strlen(*pname);
|
||||
char *name = malloc(namelen);
|
||||
int match, ret;
|
||||
memcpy(name, *pname, namelen);
|
||||
|
||||
ret = X509_check_host(crt, name, namelen, 0, NULL);
|
||||
match = -1;
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "internal error in X509_check_host");
|
||||
++errors;
|
||||
} else if (fn->host) {
|
||||
if (ret == 1 && !samename)
|
||||
match = 1;
|
||||
if (ret == 0 && samename)
|
||||
match = 0;
|
||||
} else if (ret == 1)
|
||||
match = 1;
|
||||
check_message(fn, "host", nameincert, match, *pname);
|
||||
|
||||
ret = X509_check_host(crt, name, namelen,
|
||||
X509_CHECK_FLAG_NO_WILDCARDS, NULL);
|
||||
match = -1;
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "internal error in X509_check_host");
|
||||
++errors;
|
||||
} else if (fn->host) {
|
||||
if (ret == 1 && !samename)
|
||||
match = 1;
|
||||
if (ret == 0 && samename)
|
||||
match = 0;
|
||||
} else if (ret == 1)
|
||||
match = 1;
|
||||
check_message(fn, "host-no-wildcards", nameincert, match, *pname);
|
||||
|
||||
ret = X509_check_email(crt, name, namelen, 0);
|
||||
match = -1;
|
||||
if (fn->email) {
|
||||
if (ret && !samename)
|
||||
match = 1;
|
||||
if (!ret && samename && strchr(nameincert, '@') != NULL)
|
||||
match = 0;
|
||||
} else if (ret)
|
||||
match = 1;
|
||||
check_message(fn, "email", nameincert, match, *pname);
|
||||
++pname;
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const struct set_name_fn *pfn = name_fns;
|
||||
while (pfn->name) {
|
||||
const char *const *pname = names;
|
||||
while (*pname) {
|
||||
X509 *crt = make_cert();
|
||||
if (crt == NULL) {
|
||||
fprintf(stderr, "make_cert failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (!pfn->fn(crt, *pname)) {
|
||||
fprintf(stderr, "X509 name setting failed\n");
|
||||
return 1;
|
||||
}
|
||||
run_cert(crt, *pname, pfn);
|
||||
X509_free(crt);
|
||||
++pname;
|
||||
}
|
||||
++pfn;
|
||||
}
|
||||
return errors > 0 ? 1 : 0;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
/* v3prin.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@@ -56,8 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/conf.h>
|
||||
@@ -66,34 +65,35 @@
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
X509 *cert;
|
||||
FILE *inf;
|
||||
int i, count;
|
||||
X509_EXTENSION *ext;
|
||||
X509V3_add_standard_extensions();
|
||||
ERR_load_crypto_strings();
|
||||
if(!argv[1]) {
|
||||
fprintf(stderr, "Usage v3prin cert.pem\n");
|
||||
exit(1);
|
||||
}
|
||||
if(!(inf = fopen(argv[1], "r"))) {
|
||||
fprintf(stderr, "Can't open %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
if(!(cert = PEM_read_X509(inf, NULL, NULL))) {
|
||||
fprintf(stderr, "Can't read certificate %s\n", argv[1]);
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
fclose(inf);
|
||||
count = X509_get_ext_count(cert);
|
||||
printf("%d extensions\n", count);
|
||||
for(i = 0; i < count; i++) {
|
||||
ext = X509_get_ext(cert, i);
|
||||
printf("%s\n", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
|
||||
if(!X509V3_EXT_print_fp(stdout, ext, 0, 0)) ERR_print_errors_fp(stderr);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
return 0;
|
||||
X509 *cert;
|
||||
FILE *inf;
|
||||
int i, count;
|
||||
X509_EXTENSION *ext;
|
||||
X509V3_add_standard_extensions();
|
||||
ERR_load_crypto_strings();
|
||||
if (!argv[1]) {
|
||||
fprintf(stderr, "Usage v3prin cert.pem\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!(inf = fopen(argv[1], "r"))) {
|
||||
fprintf(stderr, "Can't open %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
if (!(cert = PEM_read_X509(inf, NULL, NULL))) {
|
||||
fprintf(stderr, "Can't read certificate %s\n", argv[1]);
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
fclose(inf);
|
||||
count = X509_get_ext_count(cert);
|
||||
printf("%d extensions\n", count);
|
||||
for (i = 0; i < count; i++) {
|
||||
ext = X509_get_ext(cert, i);
|
||||
printf("%s\n", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
|
||||
if (!X509V3_EXT_print_fp(stdout, ext, 0, 0))
|
||||
ERR_print_errors_fp(stderr);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user