aboutsummaryrefslogtreecommitdiff
path: root/openssl
diff options
context:
space:
mode:
Diffstat (limited to 'openssl')
-rw-r--r--openssl/Makefile2
-rw-r--r--openssl/patch-rpki-openssl-0.9.82656
2 files changed, 1 insertions, 2657 deletions
diff --git a/openssl/Makefile b/openssl/Makefile
index c81fac46..552d4dcb 100644
--- a/openssl/Makefile
+++ b/openssl/Makefile
@@ -11,7 +11,7 @@ clean:
cd tests; ${MAKE} $@
openssl-${VERSION}/Makefile: openssl-${VERSION}/config
- cd openssl-${VERSION}; PERL=/usr/bin/perl ./config enable-rfc3779 no-dso
+ cd openssl-${VERSION}; PERL=/usr/bin/perl ./config enable-rfc3779 enable-cms no-dso
openssl-${VERSION}/config: openssl-${VERSION}.tar.gz
gzip -c -d openssl-${VERSION}.tar.gz | tar -xf -
diff --git a/openssl/patch-rpki-openssl-0.9.8 b/openssl/patch-rpki-openssl-0.9.8
deleted file mode 100644
index eed46ba6..00000000
--- a/openssl/patch-rpki-openssl-0.9.8
+++ /dev/null
@@ -1,2656 +0,0 @@
-$URL$
-$Id$
-
-This is a patch against the OpenSSL 0.9.8 branch. It was originally
-developed for 0.9.8b, but applies unchanged against 0.9.8c and 0.9.8d.
-If you run FreeBSD, you can just drop this patch into
-/usr/ports/security/openssl/files-beta/ and build build the port to
-add RPKI functionality to OpenSSL.
-
-Index: crypto/stack/safestack.h
-===================================================================
---- crypto/stack/safestack.h (.../vendor/0.9.8b) (revision 251)
-+++ crypto/stack/safestack.h (.../trunk) (revision 251)
-@@ -234,6 +234,28 @@
- #define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
- #define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
-
-+#define sk_ASIdOrRange_new(st) SKM_sk_new(ASIdOrRange, (st))
-+#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
-+#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
-+#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
-+#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
-+#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
-+#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
-+#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
-+#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
-+#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
-+#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
-+#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
-+#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
-+#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
-+#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
-+#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
-+#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
-+#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
-+#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
-+#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
-+#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
-+
- #define sk_ASN1_GENERALSTRING_new(st) SKM_sk_new(ASN1_GENERALSTRING, (st))
- #define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
- #define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
-@@ -608,6 +630,50 @@
- #define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
- #define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
-
-+#define sk_IPAddressFamily_new(st) SKM_sk_new(IPAddressFamily, (st))
-+#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
-+#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
-+#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
-+#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
-+#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
-+#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
-+#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
-+#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
-+#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
-+#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
-+#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
-+#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
-+#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
-+#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
-+#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
-+#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
-+#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
-+#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
-+#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
-+#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
-+
-+#define sk_IPAddressOrRange_new(st) SKM_sk_new(IPAddressOrRange, (st))
-+#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
-+#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
-+#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
-+#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
-+#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
-+#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
-+#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
-+#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
-+#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
-+#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
-+#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
-+#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
-+#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
-+#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
-+#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
-+#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
-+#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
-+#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
-+#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
-+#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
-+
- #define sk_KRB5_APREQBODY_new(st) SKM_sk_new(KRB5_APREQBODY, (st))
- #define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
- #define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
-
-Index: crypto/x509v3/v3_purp.c
-===================================================================
---- crypto/x509v3/v3_purp.c (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509v3/v3_purp.c (.../trunk) (revision 251)
-@@ -285,7 +285,10 @@
- NID_key_usage, /* 83 */
- NID_subject_alt_name, /* 85 */
- NID_basic_constraints, /* 87 */
-+ NID_certificate_policies, /* 89 */
- NID_ext_key_usage, /* 126 */
-+ NID_sbgp_ipAddrBlock, /* 290 */
-+ NID_sbgp_autonomousSysNum, /* 291 */
- NID_proxyCertInfo /* 661 */
- };
-
-@@ -410,6 +413,9 @@
- }
- x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
- x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
-+ x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
-+ x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
-+ NULL, NULL);
- for (i = 0; i < X509_get_ext_count(x); i++)
- {
- ex = X509_get_ext(x, i);
-Index: crypto/x509v3/v3_utl.c
-===================================================================
---- crypto/x509v3/v3_utl.c (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509v3/v3_utl.c (.../trunk) (revision 251)
-@@ -71,7 +71,6 @@
- static void str_free(void *str);
- static int append_ia5(STACK **sk, ASN1_IA5STRING *email);
-
--static int a2i_ipadd(unsigned char *ipout, const char *ipasc);
- static int ipv4_from_asc(unsigned char *v4, const char *in);
- static int ipv6_from_asc(unsigned char *v6, const char *in);
- static int ipv6_cb(const char *elem, int len, void *usr);
-@@ -615,7 +614,7 @@
- }
-
-
--static int a2i_ipadd(unsigned char *ipout, const char *ipasc)
-+int a2i_ipadd(unsigned char *ipout, const char *ipasc)
- {
- /* If string contains a ':' assume IPv6 */
-
-Index: crypto/x509v3/x509v3.h
-===================================================================
---- crypto/x509v3/x509v3.h (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509v3/x509v3.h (.../trunk) (revision 251)
-@@ -620,11 +620,143 @@
-
- ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
- ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
-+int a2i_ipadd(unsigned char *ipout, const char *ipasc);
- int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
- unsigned long chtype);
-
- void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
-
-+/*
-+ * [sra] Begin RFC 3779 stuff
-+ *
-+ * The following definitions and declarations will need to be merged
-+ * into the the rest of this file more cleanly. Right now they're
-+ * organized as a unit to make it easier to see what I've added.
-+ */
-+
-+typedef struct ASRange_st {
-+ ASN1_INTEGER *min, *max;
-+} ASRange;
-+
-+#define ASIdOrRange_id 0
-+#define ASIdOrRange_range 1
-+
-+typedef struct ASIdOrRange_st {
-+ int type;
-+ union {
-+ ASN1_INTEGER *id;
-+ ASRange *range;
-+ } u;
-+} ASIdOrRange;
-+
-+typedef STACK_OF(ASIdOrRange) ASIdOrRanges;
-+DECLARE_STACK_OF(ASIdOrRange)
-+
-+#define ASIdentifierChoice_inherit 0
-+#define ASIdentifierChoice_asIdsOrRanges 1
-+
-+typedef struct ASIdentifierChoice_st {
-+ int type;
-+ union {
-+ ASN1_NULL *inherit;
-+ ASIdOrRanges *asIdsOrRanges;
-+ } u;
-+} ASIdentifierChoice;
-+
-+typedef struct ASIdentifiers_st {
-+ ASIdentifierChoice *asnum, *rdi;
-+} ASIdentifiers;
-+
-+DECLARE_ASN1_FUNCTIONS(ASRange)
-+DECLARE_ASN1_FUNCTIONS(ASIdOrRange)
-+DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice)
-+DECLARE_ASN1_FUNCTIONS(ASIdentifiers)
-+
-+
-+typedef struct IPAddressRange_st {
-+ ASN1_BIT_STRING *min, *max;
-+} IPAddressRange;
-+
-+#define IPAddressOrRange_addressPrefix 0
-+#define IPAddressOrRange_addressRange 1
-+
-+typedef struct IPAddressOrRange_st {
-+ int type;
-+ union {
-+ ASN1_BIT_STRING *addressPrefix;
-+ IPAddressRange *addressRange;
-+ } u;
-+} IPAddressOrRange;
-+
-+typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges;
-+DECLARE_STACK_OF(IPAddressOrRange)
-+
-+#define IPAddressChoice_inherit 0
-+#define IPAddressChoice_addressesOrRanges 1
-+
-+typedef struct IPAddressChoice_st {
-+ int type;
-+ union {
-+ ASN1_NULL *inherit;
-+ IPAddressOrRanges *addressesOrRanges;
-+ } u;
-+} IPAddressChoice;
-+
-+typedef struct IPAddressFamily_st {
-+ ASN1_OCTET_STRING *addressFamily;
-+ IPAddressChoice *ipAddressChoice;
-+} IPAddressFamily;
-+
-+typedef STACK_OF(IPAddressFamily) IPAddrBlocks;
-+DECLARE_STACK_OF(IPAddressFamily)
-+
-+DECLARE_ASN1_FUNCTIONS(IPAddressRange)
-+DECLARE_ASN1_FUNCTIONS(IPAddressOrRange)
-+DECLARE_ASN1_FUNCTIONS(IPAddressChoice)
-+DECLARE_ASN1_FUNCTIONS(IPAddressFamily)
-+
-+/*
-+ * AFI values, assigned by IANA. It'd be nice to make the AFI
-+ * handling code totally generic, but there are too many little things
-+ * that would need to be defined for other address families for it to
-+ * be worth the trouble.
-+ */
-+
-+#define IANA_AFI_IPV4 1
-+#define IANA_AFI_IPV6 2
-+
-+/*
-+ * Canonical forms.
-+ */
-+int v3_asid_is_canonical(ASIdentifiers *asid);
-+int v3_addr_is_canonical(IPAddrBlocks *addr);
-+int v3_asid_canonize(ASIdentifiers *asid);
-+int v3_addr_canonize(IPAddrBlocks *addr);
-+
-+/*
-+ * Tests for inheritance and containment.
-+ */
-+int v3_asid_inherits(ASIdentifiers *asid);
-+int v3_addr_inherits(IPAddrBlocks *addr);
-+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b);
-+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b);
-+
-+/*
-+ * Check whether RFC 3779 extensions nest properly in chains.
-+ */
-+int v3_asid_validate_path(X509_STORE_CTX *);
-+int v3_addr_validate_path(X509_STORE_CTX *);
-+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
-+ ASIdentifiers *ext,
-+ int allow_inheritance);
-+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
-+ IPAddrBlocks *ext,
-+ int allow_inheritance);
-+
-+/*
-+ * [sra] End RFC 3779 stuff
-+ */
-+
- /* BEGIN ERROR CODES */
- /* The following lines are auto generated by the script mkerr.pl. Any changes
- * made after this point may be overwritten when the script is next run.
-@@ -634,6 +766,8 @@
- /* Error codes for the X509V3 functions. */
-
- /* Function codes. */
-+#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 156
-+#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 157
- #define X509V3_F_COPY_EMAIL 122
- #define X509V3_F_COPY_ISSUER 123
- #define X509V3_F_DO_DIRNAME 144
-@@ -663,6 +797,7 @@
- #define X509V3_F_SXNET_ADD_ID_ULONG 127
- #define X509V3_F_SXNET_GET_ID_ASC 128
- #define X509V3_F_SXNET_GET_ID_ULONG 129
-+#define X509V3_F_V2I_ASIDENTIFIERS 158
- #define X509V3_F_V2I_ASN1_BIT_STRING 101
- #define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139
- #define X509V3_F_V2I_AUTHORITY_KEYID 119
-@@ -671,11 +806,13 @@
- #define X509V3_F_V2I_EXTENDED_KEY_USAGE 103
- #define X509V3_F_V2I_GENERAL_NAMES 118
- #define X509V3_F_V2I_GENERAL_NAME_EX 117
-+#define X509V3_F_V2I_IPADDRBLOCKS 159
- #define X509V3_F_V2I_ISSUER_ALT 153
- #define X509V3_F_V2I_NAME_CONSTRAINTS 147
- #define X509V3_F_V2I_POLICY_CONSTRAINTS 146
- #define X509V3_F_V2I_POLICY_MAPPINGS 145
- #define X509V3_F_V2I_SUBJECT_ALT 154
-+#define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160
- #define X509V3_F_V3_GENERIC_EXTENSION 116
- #define X509V3_F_X509V3_ADD1_I2D 140
- #define X509V3_F_X509V3_ADD_VALUE 105
-@@ -710,8 +847,12 @@
- #define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151
- #define X509V3_R_ILLEGAL_HEX_DIGIT 113
- #define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152
-+#define X509V3_R_INVALID_ASNUMBER 160
-+#define X509V3_R_INVALID_ASRANGE 161
- #define X509V3_R_INVALID_BOOLEAN_STRING 104
- #define X509V3_R_INVALID_EXTENSION_STRING 105
-+#define X509V3_R_INVALID_INHERITANCE 162
-+#define X509V3_R_INVALID_IPADDRESS 163
- #define X509V3_R_INVALID_NAME 106
- #define X509V3_R_INVALID_NULL_ARGUMENT 107
- #define X509V3_R_INVALID_NULL_NAME 108
-@@ -723,6 +864,7 @@
- #define X509V3_R_INVALID_POLICY_IDENTIFIER 134
- #define X509V3_R_INVALID_PROXY_POLICY_SETTING 153
- #define X509V3_R_INVALID_PURPOSE 146
-+#define X509V3_R_INVALID_SAFI 164
- #define X509V3_R_INVALID_SECTION 135
- #define X509V3_R_INVALID_SYNTAX 143
- #define X509V3_R_ISSUER_DECODE_ERROR 126
-Index: crypto/x509v3/v3_asid.c
-===================================================================
---- crypto/x509v3/v3_asid.c (.../vendor/0.9.8b) (revision 0)
-+++ crypto/x509v3/v3_asid.c (.../trunk) (revision 251)
-@@ -0,0 +1,778 @@
-+/*
-+ * Copyright (C) 2006 American Registry for Internet Numbers ("ARIN")
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH
-+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-+ * AND FITNESS. IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT,
-+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+/* $Id$ */
-+
-+/*
-+ * Implementation of RFC 3779 section 3.2.
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <assert.h>
-+#include "cryptlib.h"
-+#include <openssl/conf.h>
-+#include <openssl/asn1.h>
-+#include <openssl/asn1t.h>
-+#include <openssl/x509v3.h>
-+#include <openssl/x509.h>
-+#include <openssl/bn.h>
-+
-+/*
-+ * OpenSSL ASN.1 template translation of RFC 3779 3.2.3.
-+ */
-+
-+ASN1_SEQUENCE(ASRange) = {
-+ ASN1_SIMPLE(ASRange, min, ASN1_INTEGER),
-+ ASN1_SIMPLE(ASRange, max, ASN1_INTEGER)
-+} ASN1_SEQUENCE_END(ASRange)
-+
-+ASN1_CHOICE(ASIdOrRange) = {
-+ ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER),
-+ ASN1_SIMPLE(ASIdOrRange, u.range, ASRange)
-+} ASN1_CHOICE_END(ASIdOrRange)
-+
-+ASN1_CHOICE(ASIdentifierChoice) = {
-+ ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL),
-+ ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange)
-+} ASN1_CHOICE_END(ASIdentifierChoice)
-+
-+ASN1_SEQUENCE(ASIdentifiers) = {
-+ ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0),
-+ ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1)
-+} ASN1_SEQUENCE_END(ASIdentifiers)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(ASRange)
-+IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange)
-+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice)
-+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers)
-+
-+/*
-+ * i2r method for an ASIdentifierChoice.
-+ */
-+static int i2r_ASIdentifierChoice(BIO *out,
-+ ASIdentifierChoice *choice,
-+ int indent,
-+ const char *msg)
-+{
-+ int i;
-+ char *s;
-+ if (choice == NULL)
-+ return 1;
-+ BIO_printf(out, "%*s%s:\n", indent, "", msg);
-+ switch (choice->type) {
-+ case ASIdentifierChoice_inherit:
-+ BIO_printf(out, "%*sinherit\n", indent + 2, "");
-+ break;
-+ case ASIdentifierChoice_asIdsOrRanges:
-+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) {
-+ ASIdOrRange *aor = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
-+ switch (aor->type) {
-+ case ASIdOrRange_id:
-+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL)
-+ return 0;
-+ BIO_printf(out, "%*s%s\n", indent + 2, "", s);
-+ OPENSSL_free(s);
-+ break;
-+ case ASIdOrRange_range:
-+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL)
-+ return 0;
-+ BIO_printf(out, "%*s%s-", indent + 2, "", s);
-+ OPENSSL_free(s);
-+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL)
-+ return 0;
-+ BIO_printf(out, "%s\n", s);
-+ OPENSSL_free(s);
-+ break;
-+ default:
-+ return 0;
-+ }
-+ }
-+ break;
-+ default:
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+/*
-+ * i2r method for an ASIdentifier extension.
-+ */
-+static int i2r_ASIdentifiers(X509V3_EXT_METHOD *method,
-+ void *ext,
-+ BIO *out,
-+ int indent)
-+{
-+ ASIdentifiers *asid = ext;
-+ return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
-+ "Autonomous System Numbers") &&
-+ i2r_ASIdentifierChoice(out, asid->rdi, indent,
-+ "Routing Domain Identifiers"));
-+}
-+
-+/*
-+ * Comparision function for "stack" sorting.
-+ */
-+static int ASIdOrRange_cmp(const ASIdOrRange * const *a_,
-+ const ASIdOrRange * const *b_)
-+{
-+ const ASIdOrRange *a = *a_, *b = *b_;
-+
-+ assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
-+ (a->type == ASIdOrRange_range && a->u.range != NULL &&
-+ a->u.range->min != NULL && a->u.range->max != NULL));
-+
-+ assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
-+ (b->type == ASIdOrRange_range && b->u.range != NULL &&
-+ b->u.range->min != NULL && b->u.range->max != NULL));
-+
-+ if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
-+ return ASN1_INTEGER_cmp(a->u.id, b->u.id);
-+
-+ if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
-+ int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
-+ return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max);
-+ }
-+
-+ if (a->type == ASIdOrRange_id)
-+ return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
-+ else
-+ return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
-+}
-+
-+/*
-+ * Some of the following helper routines might want to become globals
-+ * eventually.
-+ */
-+
-+/*
-+ * Add an inherit element to an ASIdentifierChoice.
-+ */
-+static int asid_add_inherit(ASIdentifierChoice **choice)
-+{
-+ if (*choice == NULL) {
-+ if ((*choice = ASIdentifierChoice_new()) == NULL)
-+ return 0;
-+ assert((*choice)->u.inherit == NULL);
-+ if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
-+ return 0;
-+ (*choice)->type = ASIdentifierChoice_inherit;
-+ }
-+ return (*choice)->type == ASIdentifierChoice_inherit;
-+}
-+
-+/*
-+ * Add an ID or range to an ASIdentifierChoice.
-+ */
-+static int asid_add_id_or_range(ASIdentifierChoice **choice,
-+ ASN1_INTEGER *min,
-+ ASN1_INTEGER *max)
-+{
-+ ASIdOrRange *aor;
-+ if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
-+ return 0;
-+ if (*choice == NULL) {
-+ if ((*choice = ASIdentifierChoice_new()) == NULL)
-+ return 0;
-+ assert((*choice)->u.asIdsOrRanges == NULL);
-+ (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
-+ if ((*choice)->u.asIdsOrRanges == NULL)
-+ return 0;
-+ (*choice)->type = ASIdentifierChoice_asIdsOrRanges;
-+ }
-+ if ((aor = ASIdOrRange_new()) == NULL)
-+ return 0;
-+ if (max == NULL) {
-+ aor->type = ASIdOrRange_id;
-+ aor->u.id = min;
-+ } else {
-+ aor->type = ASIdOrRange_range;
-+ if ((aor->u.range = ASRange_new()) == NULL)
-+ goto err;
-+ ASN1_INTEGER_free(aor->u.range->min);
-+ aor->u.range->min = min;
-+ ASN1_INTEGER_free(aor->u.range->max);
-+ aor->u.range->max = max;
-+ }
-+ if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
-+ goto err;
-+ return 1;
-+
-+ err:
-+ ASIdOrRange_free(aor);
-+ return 0;
-+}
-+
-+/*
-+ * Extract min and max values from an ASIdOrRange.
-+ */
-+static void extract_min_max(ASIdOrRange *aor,
-+ ASN1_INTEGER **min,
-+ ASN1_INTEGER **max)
-+{
-+ assert(aor != NULL && min != NULL && max != NULL);
-+ switch (aor->type) {
-+ case ASIdOrRange_id:
-+ *min = aor->u.id;
-+ *max = aor->u.id;
-+ return;
-+ case ASIdOrRange_range:
-+ *min = aor->u.range->min;
-+ *max = aor->u.range->max;
-+ return;
-+ }
-+}
-+
-+/*
-+ * Check whether an ASIdentifierChoice is in canonical form.
-+ */
-+static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
-+{
-+ ASN1_INTEGER *a_max_plus_one = NULL;
-+ BIGNUM *bn = NULL;
-+ int i, ret = 0;
-+
-+ /*
-+ * Empty element or inheritance is canonical.
-+ */
-+ if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
-+ return 1;
-+
-+ /*
-+ * If not a list, or if empty list, it's broken.
-+ */
-+ if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
-+ sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
-+ return 0;
-+
-+ /*
-+ * It's a list, check it.
-+ */
-+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
-+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
-+ ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
-+ ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
-+
-+ extract_min_max(a, &a_min, &a_max);
-+ extract_min_max(b, &b_min, &b_max);
-+
-+ /*
-+ * Punt misordered list, overlapping start, or inverted range.
-+ */
-+ if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
-+ ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
-+ ASN1_INTEGER_cmp(b_min, b_max) > 0)
-+ goto done;
-+
-+ /*
-+ * Calculate a_max + 1 to check for adjacency.
-+ */
-+ if ((bn == NULL && (bn = BN_new()) == NULL) ||
-+ ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
-+ !BN_add_word(bn, 1) ||
-+ (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
-+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL,
-+ ERR_R_MALLOC_FAILURE);
-+ goto done;
-+ }
-+
-+ /*
-+ * Punt if adjacent or overlapping.
-+ */
-+ if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
-+ goto done;
-+ }
-+
-+ ret = 1;
-+
-+ done:
-+ ASN1_INTEGER_free(a_max_plus_one);
-+ BN_free(bn);
-+ return ret;
-+}
-+
-+/*
-+ * Check whether an ASIdentifier extension is in canonical form.
-+ */
-+int v3_asid_is_canonical(ASIdentifiers *asid)
-+{
-+ return (asid == NULL ||
-+ (ASIdentifierChoice_is_canonical(asid->asnum) ||
-+ ASIdentifierChoice_is_canonical(asid->rdi)));
-+}
-+
-+/*
-+ * Whack an ASIdentifierChoice into canonical form.
-+ */
-+static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
-+{
-+ ASN1_INTEGER *a_max_plus_one = NULL;
-+ BIGNUM *bn = NULL;
-+ int i, ret = 0;
-+
-+ /*
-+ * Nothing to do for empty element or inheritance.
-+ */
-+ if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
-+ return 1;
-+
-+ /*
-+ * We have a list. Sort it.
-+ */
-+ assert(choice->type == ASIdentifierChoice_asIdsOrRanges);
-+ sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
-+
-+ /*
-+ * Now check for errors and suboptimal encoding, rejecting the
-+ * former and fixing the latter.
-+ */
-+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
-+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
-+ ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
-+ ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
-+
-+ extract_min_max(a, &a_min, &a_max);
-+ extract_min_max(b, &b_min, &b_max);
-+
-+ /*
-+ * Make sure we're properly sorted (paranoia).
-+ */
-+ assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
-+
-+ /*
-+ * Check for overlaps.
-+ */
-+ if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
-+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
-+ X509V3_R_EXTENSION_VALUE_ERROR);
-+ goto done;
-+ }
-+
-+ /*
-+ * Calculate a_max + 1 to check for adjacency.
-+ */
-+ if ((bn == NULL && (bn = BN_new()) == NULL) ||
-+ ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
-+ !BN_add_word(bn, 1) ||
-+ (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
-+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE);
-+ goto done;
-+ }
-+
-+ /*
-+ * If a and b are adjacent, merge them.
-+ */
-+ if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
-+ ASRange *r;
-+ switch (a->type) {
-+ case ASIdOrRange_id:
-+ if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) {
-+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
-+ ERR_R_MALLOC_FAILURE);
-+ goto done;
-+ }
-+ r->min = a_min;
-+ r->max = b_max;
-+ a->type = ASIdOrRange_range;
-+ a->u.range = r;
-+ break;
-+ case ASIdOrRange_range:
-+ ASN1_INTEGER_free(a->u.range->max);
-+ a->u.range->max = b_max;
-+ break;
-+ }
-+ switch (b->type) {
-+ case ASIdOrRange_id:
-+ b->u.id = NULL;
-+ break;
-+ case ASIdOrRange_range:
-+ b->u.range->max = NULL;
-+ break;
-+ }
-+ ASIdOrRange_free(b);
-+ sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
-+ i--;
-+ continue;
-+ }
-+ }
-+
-+ assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
-+
-+ ret = 1;
-+
-+ done:
-+ ASN1_INTEGER_free(a_max_plus_one);
-+ BN_free(bn);
-+ return ret;
-+}
-+
-+/*
-+ * Whack an ASIdentifier extension into canonical form.
-+ */
-+int v3_asid_canonize(ASIdentifiers *asid)
-+{
-+ return (asid == NULL ||
-+ (ASIdentifierChoice_canonize(asid->asnum) &&
-+ ASIdentifierChoice_canonize(asid->rdi)));
-+}
-+
-+/*
-+ * v2i method for an ASIdentifier extension.
-+ */
-+static void *v2i_ASIdentifiers(struct v3_ext_method *method,
-+ struct v3_ext_ctx *ctx,
-+ STACK_OF(CONF_VALUE) *values)
-+{
-+ ASIdentifiers *asid = NULL;
-+ int i;
-+
-+ if ((asid = ASIdentifiers_new()) == NULL) {
-+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
-+ return NULL;
-+ }
-+
-+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
-+ CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
-+ ASIdentifierChoice **choice;
-+ ASN1_INTEGER *min = NULL, *max = NULL;
-+ int i1, i2, i3, is_range;
-+
-+ /*
-+ * Figure out whether this is an AS or an RDI.
-+ */
-+ if ( !name_cmp(val->name, "AS")) {
-+ choice = &asid->asnum;
-+ } else if (!name_cmp(val->name, "RDI")) {
-+ choice = &asid->rdi;
-+ } else {
-+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_NAME_ERROR);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+
-+ /*
-+ * Handle inheritance.
-+ */
-+ if (!strcmp(val->value, "inherit")) {
-+ if (asid_add_inherit(choice))
-+ continue;
-+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_INHERITANCE);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+
-+ /*
-+ * Number, range, or mistake, pick it apart and figure out which.
-+ */
-+ i1 = strspn(val->value, "0123456789");
-+ if (val->value[i1] == '\0') {
-+ is_range = 0;
-+ } else {
-+ is_range = 1;
-+ i2 = i1 + strspn(val->value + i1, " \t");
-+ if (val->value[i2] != '-') {
-+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASNUMBER);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+ i2++;
-+ i2 = i2 + strspn(val->value + i2, " \t");
-+ i3 = i2 + strspn(val->value + i2, "0123456789");
-+ if (val->value[i3] != '\0') {
-+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASRANGE);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+ }
-+
-+ /*
-+ * Syntax is ok, read and add it.
-+ */
-+ if (!is_range) {
-+ if (!X509V3_get_value_int(val, &min)) {
-+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ } else {
-+ char *s = BUF_strdup(val->value);
-+ if (s == NULL) {
-+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ s[i1] = '\0';
-+ min = s2i_ASN1_INTEGER(NULL, s);
-+ max = s2i_ASN1_INTEGER(NULL, s + i2);
-+ OPENSSL_free(s);
-+ if (min == NULL || max == NULL) {
-+ ASN1_INTEGER_free(min);
-+ ASN1_INTEGER_free(max);
-+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ }
-+ if (!asid_add_id_or_range(choice, min, max)) {
-+ ASN1_INTEGER_free(min);
-+ ASN1_INTEGER_free(max);
-+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ }
-+
-+ /*
-+ * Canonize the result, then we're done.
-+ */
-+ if (!v3_asid_canonize(asid))
-+ goto err;
-+ return asid;
-+
-+ err:
-+ ASIdentifiers_free(asid);
-+ return NULL;
-+}
-+
-+/*
-+ * OpenSSL dispatch.
-+ */
-+X509V3_EXT_METHOD v3_asid = {
-+ NID_sbgp_autonomousSysNum, /* nid */
-+ 0, /* flags */
-+ ASN1_ITEM_ref(ASIdentifiers), /* template */
-+ 0, 0, 0, 0, /* old functions, ignored */
-+ 0, /* i2s */
-+ 0, /* s2i */
-+ 0, /* i2v */
-+ v2i_ASIdentifiers, /* v2i */
-+ i2r_ASIdentifiers, /* i2r */
-+ 0, /* r2i */
-+ NULL /* extension-specific data */
-+};
-+
-+/*
-+ * Figure out whether extension uses inheritance.
-+ */
-+int v3_asid_inherits(ASIdentifiers *asid)
-+{
-+ return (asid != NULL &&
-+ ((asid->asnum != NULL &&
-+ asid->asnum->type == ASIdentifierChoice_inherit) ||
-+ (asid->rdi != NULL &&
-+ asid->rdi->type == ASIdentifierChoice_inherit)));
-+}
-+
-+/*
-+ * Figure out whether parent contains child.
-+ */
-+static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
-+{
-+ ASN1_INTEGER *p_min, *p_max, *c_min, *c_max;
-+ int p, c;
-+
-+ if (child == NULL || parent == child)
-+ return 1;
-+ if (parent == NULL)
-+ return 0;
-+
-+ p = 0;
-+ for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
-+ extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max);
-+ for (;; p++) {
-+ if (p >= sk_ASIdOrRange_num(parent))
-+ return 0;
-+ extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max);
-+ if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
-+ continue;
-+ if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
-+ return 0;
-+ break;
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+/*
-+ * Test whether a is a subet of b.
-+ */
-+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b)
-+{
-+ return (a == NULL ||
-+ a == b ||
-+ (b != NULL &&
-+ !v3_asid_inherits(a) &&
-+ !v3_asid_inherits(b) &&
-+ asid_contains(b->asnum->u.asIdsOrRanges,
-+ a->asnum->u.asIdsOrRanges) &&
-+ asid_contains(b->rdi->u.asIdsOrRanges,
-+ a->rdi->u.asIdsOrRanges)));
-+}
-+
-+/*
-+ * Validation error handling via callback.
-+ */
-+#define validation_err(_err_) \
-+ do { \
-+ if (ctx != NULL) { \
-+ ctx->error = _err_; \
-+ ctx->error_depth = i; \
-+ ctx->current_cert = x; \
-+ ret = ctx->verify_cb(0, ctx); \
-+ } else { \
-+ ret = 0; \
-+ } \
-+ if (!ret) \
-+ goto done; \
-+ } while (0)
-+
-+/*
-+ * Core code for RFC 3779 3.3 path validation.
-+ */
-+static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx,
-+ STACK_OF(X509) *chain,
-+ ASIdentifiers *ext)
-+{
-+ ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
-+ int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
-+ X509 *x;
-+
-+ assert(chain != NULL && sk_X509_num(chain) > 0);
-+ assert(ctx != NULL || ext != NULL);
-+ assert(ctx == NULL || ctx->verify_cb != NULL);
-+
-+ /*
-+ * Figure out where to start. If we don't have an extension to
-+ * check, we're done. Otherwise, check canonical form and
-+ * set up for walking up the chain.
-+ */
-+ if (ext != NULL) {
-+ i = -1;
-+ } else {
-+ i = 0;
-+ x = sk_X509_value(chain, i);
-+ assert(x != NULL);
-+ if ((ext = x->rfc3779_asid) == NULL)
-+ goto done;
-+ }
-+ if (!v3_asid_is_canonical(ext))
-+ validation_err(X509_V_ERR_INVALID_EXTENSION);
-+ if (ext->asnum != NULL) {
-+ switch (ext->asnum->type) {
-+ case ASIdentifierChoice_inherit:
-+ inherit_as = 1;
-+ break;
-+ case ASIdentifierChoice_asIdsOrRanges:
-+ child_as = ext->asnum->u.asIdsOrRanges;
-+ break;
-+ }
-+ }
-+ if (ext->rdi != NULL) {
-+ switch (ext->rdi->type) {
-+ case ASIdentifierChoice_inherit:
-+ inherit_rdi = 1;
-+ break;
-+ case ASIdentifierChoice_asIdsOrRanges:
-+ child_rdi = ext->rdi->u.asIdsOrRanges;
-+ break;
-+ }
-+ }
-+
-+ /*
-+ * Now walk up the chain. Extensions must be in canonical form, no
-+ * cert may list resources that its parent doesn't list.
-+ */
-+ for (i++; i < sk_X509_num(chain); i++) {
-+ x = sk_X509_value(chain, i);
-+ assert(x != NULL);
-+ if (x->rfc3779_asid == NULL) {
-+ if (child_as != NULL || child_rdi != NULL)
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ continue;
-+ }
-+ if (!v3_asid_is_canonical(x->rfc3779_asid))
-+ validation_err(X509_V_ERR_INVALID_EXTENSION);
-+ if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ child_as = NULL;
-+ inherit_as = 0;
-+ }
-+ if (x->rfc3779_asid->asnum != NULL &&
-+ x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) {
-+ if (inherit_as ||
-+ asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as)) {
-+ child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
-+ inherit_as = 0;
-+ } else {
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ }
-+ }
-+ if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ child_rdi = NULL;
-+ inherit_rdi = 0;
-+ }
-+ if (x->rfc3779_asid->rdi != NULL &&
-+ x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
-+ if (inherit_rdi ||
-+ asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) {
-+ child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
-+ inherit_rdi = 0;
-+ } else {
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ }
-+ }
-+ }
-+
-+ /*
-+ * Trust anchor can't inherit.
-+ */
-+ if (x->rfc3779_asid != NULL) {
-+ if (x->rfc3779_asid->asnum != NULL &&
-+ x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ if (x->rfc3779_asid->rdi != NULL &&
-+ x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ }
-+
-+ done:
-+ return ret;
-+}
-+
-+#undef validation_err
-+
-+/*
-+ * RFC 3779 3.3 path validation -- called from X509_verify_cert().
-+ */
-+int v3_asid_validate_path(X509_STORE_CTX *ctx)
-+{
-+ return v3_asid_validate_path_internal(ctx, ctx->chain, NULL);
-+}
-+
-+/*
-+ * RFC 3779 3.3 path validation of an extension.
-+ * Test whether chain covers extension.
-+ */
-+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
-+ ASIdentifiers *ext,
-+ int allow_inheritance)
-+{
-+ if (ext == NULL)
-+ return 1;
-+ if (chain == NULL || sk_X509_num(chain) == 0)
-+ return 0;
-+ if (!allow_inheritance && v3_asid_inherits(ext))
-+ return 0;
-+ return v3_asid_validate_path_internal(NULL, chain, ext);
-+}
-
-Index: crypto/x509v3/Makefile
-===================================================================
---- crypto/x509v3/Makefile (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509v3/Makefile (.../trunk) (revision 251)
-@@ -21,12 +21,14 @@
- 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
-+pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \
-+v3_asid.c v3_addr.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
-+pcy_cache.o pcy_node.o pcy_data.o pcy_map.o pcy_tree.o pcy_lib.o \
-+v3_asid.o v3_addr.o
-
- SRC= $(LIBSRC)
-
-@@ -166,6 +168,20 @@
- pcy_tree.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
- pcy_tree.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
- pcy_tree.o: ../cryptlib.h pcy_int.h pcy_tree.c
-+v3_addr.o: ../../e_os.h ../../include/openssl/asn1.h
-+v3_addr.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-+v3_addr.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-+v3_addr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-+v3_addr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-+v3_addr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-+v3_addr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-+v3_addr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-+v3_addr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-+v3_addr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-+v3_addr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-+v3_addr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-+v3_addr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-+v3_addr.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_addr.c
- v3_akey.o: ../../e_os.h ../../include/openssl/asn1.h
- v3_akey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
- v3_akey.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-@@ -208,6 +224,21 @@
- v3_alt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
- v3_alt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
- v3_alt.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_alt.c
-+v3_asid.o: ../../e_os.h ../../include/openssl/asn1.h
-+v3_asid.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-+v3_asid.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-+v3_asid.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-+v3_asid.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-+v3_asid.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-+v3_asid.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-+v3_asid.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-+v3_asid.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-+v3_asid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-+v3_asid.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-+v3_asid.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-+v3_asid.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-+v3_asid.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-+v3_asid.o: ../cryptlib.h v3_asid.c
- v3_bcons.o: ../../e_os.h ../../include/openssl/asn1.h
- v3_bcons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
- v3_bcons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-Index: crypto/x509v3/v3err.c
-===================================================================
---- crypto/x509v3/v3err.c (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509v3/v3err.c (.../trunk) (revision 251)
-@@ -70,6 +70,8 @@
-
- static ERR_STRING_DATA X509V3_str_functs[]=
- {
-+{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"},
-@@ -99,6 +101,7 @@
- {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"},
-@@ -107,11 +110,13 @@
- {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_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"},
-@@ -149,8 +154,12 @@
- {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_NAME) ,"invalid name"},
- {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT),"invalid null argument"},
- {ERR_REASON(X509V3_R_INVALID_NULL_NAME) ,"invalid null name"},
-@@ -162,6 +171,7 @@
- {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"},
-Index: crypto/x509v3/pcy_tree.c
-===================================================================
---- crypto/x509v3/pcy_tree.c (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509v3/pcy_tree.c (.../trunk) (revision 251)
-@@ -628,6 +628,16 @@
- /* Tree OK: continue */
-
- case 1:
-+ if (!tree)
-+ /*
-+ * tree_init() returns success and a null tree
-+ * if it's just looking at a trust anchor.
-+ * I'm not sure that returning success here is
-+ * correct, but I'm sure that reporting this
-+ * as an internal error which our caller
-+ * interprets as a malloc failure is wrong.
-+ */
-+ return 1;
- break;
- }
-
-Index: crypto/x509v3/v3_addr.c
-===================================================================
---- crypto/x509v3/v3_addr.c (.../vendor/0.9.8b) (revision 0)
-+++ crypto/x509v3/v3_addr.c (.../trunk) (revision 251)
-@@ -0,0 +1,1214 @@
-+/*
-+ * Copyright (C) 2006 American Registry for Internet Numbers ("ARIN")
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH
-+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-+ * AND FITNESS. IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT,
-+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+/* $Id$ */
-+
-+/*
-+ * Implementation of RFC 3779 section 2.2.
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <assert.h>
-+#include "cryptlib.h"
-+#include <openssl/conf.h>
-+#include <openssl/asn1.h>
-+#include <openssl/asn1t.h>
-+#include <openssl/x509v3.h>
-+
-+/*
-+ * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
-+ */
-+
-+ASN1_SEQUENCE(IPAddressRange) = {
-+ ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
-+ ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
-+} ASN1_SEQUENCE_END(IPAddressRange)
-+
-+ASN1_CHOICE(IPAddressOrRange) = {
-+ ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
-+ ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange)
-+} ASN1_CHOICE_END(IPAddressOrRange)
-+
-+ASN1_CHOICE(IPAddressChoice) = {
-+ ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL),
-+ ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
-+} ASN1_CHOICE_END(IPAddressChoice)
-+
-+ASN1_SEQUENCE(IPAddressFamily) = {
-+ ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING),
-+ ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
-+} ASN1_SEQUENCE_END(IPAddressFamily)
-+
-+ASN1_ITEM_TEMPLATE(IPAddrBlocks) =
-+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
-+ IPAddrBlocks, IPAddressFamily)
-+ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
-+IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
-+IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
-+IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
-+
-+/*
-+ * How much buffer space do we need for a raw address?
-+ */
-+#define ADDR_RAW_BUF_LEN 16
-+
-+/*
-+ * What's the address length associated with this AFI?
-+ */
-+static int length_from_afi(const unsigned afi)
-+{
-+ switch (afi) {
-+ case IANA_AFI_IPV4:
-+ return 4;
-+ case IANA_AFI_IPV6:
-+ return 16;
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/*
-+ * Extract the AFI from an IPAddressFamily.
-+ */
-+static unsigned afi_from_addressfamily(const IPAddressFamily *f)
-+{
-+ return (f != NULL && f->addressFamily != NULL && f->addressFamily->data
-+ ? ((f->addressFamily->data[0] << 8) |
-+ (f->addressFamily->data[1]))
-+ : 0);
-+}
-+
-+/*
-+ * Expand the bitstring form of an address into a raw byte array.
-+ * At the moment this is coded for simplicity, not speed.
-+ */
-+static void addr_expand(unsigned char *addr,
-+ const ASN1_BIT_STRING *bs,
-+ const int length,
-+ const unsigned char fill)
-+{
-+ assert(bs->length >= 0 && bs->length <= length);
-+ if (bs->length > 0) {
-+ memcpy(addr, bs->data, bs->length);
-+ if ((bs->flags & 7) != 0) {
-+ unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
-+ if (fill == 0)
-+ addr[bs->length - 1] &= ~mask;
-+ else
-+ addr[bs->length - 1] |= mask;
-+ }
-+ }
-+ memset(addr + bs->length, fill, length - bs->length);
-+}
-+
-+/*
-+ * Extract the prefix length from a bitstring.
-+ */
-+#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
-+
-+/*
-+ * i2r handler for one address bitstring.
-+ */
-+static int i2r_address(BIO *out,
-+ const unsigned afi,
-+ const unsigned char fill,
-+ const ASN1_BIT_STRING *bs)
-+{
-+ unsigned char addr[ADDR_RAW_BUF_LEN];
-+ int i, n;
-+
-+ switch (afi) {
-+ case IANA_AFI_IPV4:
-+ addr_expand(addr, bs, 4, fill);
-+ BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
-+ break;
-+ case IANA_AFI_IPV6:
-+ addr_expand(addr, bs, 16, fill);
-+ for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
-+ ;
-+ for (i = 0; i < n; i += 2)
-+ BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));
-+ if (i < 16)
-+ BIO_puts(out, ":");
-+ break;
-+ default:
-+ for (i = 0; i < bs->length; i++)
-+ BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
-+ BIO_printf(out, "[%d]", (int) (bs->flags & 7));
-+ break;
-+ }
-+ return 1;
-+}
-+
-+/*
-+ * i2r handler for a sequence of addresses and ranges.
-+ */
-+static int i2r_IPAddressOrRanges(BIO *out,
-+ const int indent,
-+ const IPAddressOrRanges *aors,
-+ const unsigned afi)
-+{
-+ int i;
-+ for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
-+ const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
-+ BIO_printf(out, "%*s", indent, "");
-+ switch (aor->type) {
-+ case IPAddressOrRange_addressPrefix:
-+ if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
-+ return 0;
-+ BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
-+ continue;
-+ case IPAddressOrRange_addressRange:
-+ if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
-+ return 0;
-+ BIO_puts(out, "-");
-+ if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
-+ return 0;
-+ BIO_puts(out, "\n");
-+ continue;
-+ }
-+ }
-+ return 1;
-+}
-+
-+/*
-+ * i2r handler for an IPAddrBlocks extension.
-+ */
-+static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method,
-+ void *ext,
-+ BIO *out,
-+ int indent)
-+{
-+ const IPAddrBlocks *addr = ext;
-+ int i;
-+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
-+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
-+ const unsigned afi = afi_from_addressfamily(f);
-+ switch (afi) {
-+ case IANA_AFI_IPV4:
-+ BIO_printf(out, "%*sIPv4", indent, "");
-+ break;
-+ case IANA_AFI_IPV6:
-+ BIO_printf(out, "%*sIPv6", indent, "");
-+ break;
-+ default:
-+ BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
-+ break;
-+ }
-+ if (f->addressFamily->length > 2) {
-+ switch (f->addressFamily->data[2]) {
-+ case 1:
-+ BIO_puts(out, " (Unicast)");
-+ break;
-+ case 2:
-+ BIO_puts(out, " (Multicast)");
-+ break;
-+ case 3:
-+ BIO_puts(out, " (Unicast/Multicast)");
-+ break;
-+ case 4:
-+ BIO_puts(out, " (MPLS)");
-+ break;
-+ case 64:
-+ BIO_puts(out, " (Tunnel)");
-+ break;
-+ case 65:
-+ BIO_puts(out, " (VPLS)");
-+ break;
-+ case 66:
-+ BIO_puts(out, " (BGP MDT)");
-+ break;
-+ case 128:
-+ BIO_puts(out, " (MPLS-labeled VPN)");
-+ break;
-+ default:
-+ BIO_printf(out, " (Unknown SAFI %u)",
-+ (unsigned) f->addressFamily->data[2]);
-+ break;
-+ }
-+ }
-+ switch (f->ipAddressChoice->type) {
-+ case IPAddressChoice_inherit:
-+ BIO_puts(out, ": inherit\n");
-+ break;
-+ case IPAddressChoice_addressesOrRanges:
-+ BIO_puts(out, ":\n");
-+ if (!i2r_IPAddressOrRanges(out,
-+ indent + 2,
-+ f->ipAddressChoice->u.addressesOrRanges,
-+ afi))
-+ return 0;
-+ break;
-+ }
-+ }
-+ return 1;
-+}
-+
-+/*
-+ * Sort comparison function for a sequence of IPAddressOrRange
-+ * elements.
-+ */
-+static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
-+ const IPAddressOrRange *b,
-+ const int length)
-+{
-+ unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
-+ int prefixlen_a, prefixlen_b;
-+ int r;
-+
-+ switch (a->type) {
-+ case IPAddressOrRange_addressPrefix:
-+ addr_expand(addr_a, a->u.addressPrefix, length, 0x00);
-+ prefixlen_a = addr_prefixlen(a->u.addressPrefix);
-+ break;
-+ case IPAddressOrRange_addressRange:
-+ addr_expand(addr_a, a->u.addressRange->min, length, 0x00);
-+ prefixlen_a = length * 8;
-+ break;
-+ }
-+
-+ switch (b->type) {
-+ case IPAddressOrRange_addressPrefix:
-+ addr_expand(addr_b, b->u.addressPrefix, length, 0x00);
-+ prefixlen_b = addr_prefixlen(b->u.addressPrefix);
-+ break;
-+ case IPAddressOrRange_addressRange:
-+ addr_expand(addr_b, b->u.addressRange->min, length, 0x00);
-+ prefixlen_b = length * 8;
-+ break;
-+ }
-+
-+ if ((r = memcmp(addr_a, addr_b, length)) != 0)
-+ return r;
-+ else
-+ return prefixlen_a - prefixlen_b;
-+}
-+
-+/*
-+ * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
-+ * comparision routines are only allowed two arguments.
-+ */
-+static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
-+ const IPAddressOrRange * const *b)
-+{
-+ return IPAddressOrRange_cmp(*a, *b, 4);
-+}
-+
-+/*
-+ * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
-+ * comparision routines are only allowed two arguments.
-+ */
-+static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
-+ const IPAddressOrRange * const *b)
-+{
-+ return IPAddressOrRange_cmp(*a, *b, 16);
-+}
-+
-+/*
-+ * Calculate whether a range collapses to a prefix.
-+ * See last paragraph of RFC 3779 2.2.3.7.
-+ */
-+static int range_should_be_prefix(const unsigned char *min,
-+ const unsigned char *max,
-+ const int length)
-+{
-+ unsigned char mask;
-+ int i, j;
-+
-+ for (i = 0; i < length && min[i] == max[i]; i++)
-+ ;
-+ for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
-+ ;
-+ if (i < j)
-+ return -1;
-+ if (i > j)
-+ return i * 8;
-+ mask = min[i] ^ max[i];
-+ switch (mask) {
-+ case 0x01: j = 7; break;
-+ case 0x03: j = 6; break;
-+ case 0x07: j = 5; break;
-+ case 0x0F: j = 4; break;
-+ case 0x1F: j = 3; break;
-+ case 0x3F: j = 2; break;
-+ case 0x7F: j = 1; break;
-+ default: return -1;
-+ }
-+ if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
-+ return -1;
-+ else
-+ return i * 8 + j;
-+}
-+
-+/*
-+ * Construct a prefix.
-+ */
-+static int make_addressPrefix(IPAddressOrRange **result,
-+ unsigned char *addr,
-+ const int prefixlen)
-+{
-+ int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
-+ IPAddressOrRange *aor = IPAddressOrRange_new();
-+
-+ if (aor == NULL)
-+ return 0;
-+ aor->type = IPAddressOrRange_addressPrefix;
-+ if (aor->u.addressPrefix == NULL &&
-+ (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
-+ goto err;
-+ if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
-+ goto err;
-+ aor->u.addressPrefix->flags &= ~7;
-+ aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+ if (bitlen > 0) {
-+ aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
-+ aor->u.addressPrefix->flags |= 8 - bitlen;
-+ }
-+
-+ *result = aor;
-+ return 1;
-+
-+ err:
-+ IPAddressOrRange_free(aor);
-+ return 0;
-+}
-+
-+/*
-+ * Construct a range. If it can be expressed as a prefix,
-+ * return a prefix instead. Doing this here simplifies
-+ * the rest of the code considerably.
-+ */
-+static int make_addressRange(IPAddressOrRange **result,
-+ unsigned char *min,
-+ unsigned char *max,
-+ const int length)
-+{
-+ IPAddressOrRange *aor;
-+ int i, prefixlen;
-+
-+ if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
-+ return make_addressPrefix(result, min, prefixlen);
-+
-+ if ((aor = IPAddressOrRange_new()) == NULL)
-+ return 0;
-+ aor->type = IPAddressOrRange_addressRange;
-+ assert(aor->u.addressRange == NULL);
-+ if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
-+ goto err;
-+ if (aor->u.addressRange->min == NULL &&
-+ (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
-+ goto err;
-+ if (aor->u.addressRange->max == NULL &&
-+ (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
-+ goto err;
-+
-+ for (i = length; i > 0 && min[i - 1] == 0x00; --i)
-+ ;
-+ if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
-+ goto err;
-+ aor->u.addressRange->min->flags &= ~7;
-+ aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+ if (i > 0) {
-+ unsigned char b = min[i - 1];
-+ int j = 1;
-+ while ((b & (0xFFU >> j)) != 0)
-+ ++j;
-+ aor->u.addressRange->min->flags |= 8 - j;
-+ }
-+
-+ for (i = length; i > 0 && max[i - 1] == 0xFF; --i)
-+ ;
-+ if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
-+ goto err;
-+ aor->u.addressRange->max->flags &= ~7;
-+ aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+ if (i > 0) {
-+ unsigned char b = max[i - 1];
-+ int j = 1;
-+ while ((b & (0xFFU >> j)) != (0xFFU >> j))
-+ ++j;
-+ aor->u.addressRange->max->flags |= 8 - j;
-+ }
-+
-+ *result = aor;
-+ return 1;
-+
-+ err:
-+ IPAddressOrRange_free(aor);
-+ return 0;
-+}
-+
-+/*
-+ * Construct a new address family or find an existing one.
-+ */
-+static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
-+ const unsigned afi,
-+ const unsigned *safi)
-+{
-+ IPAddressFamily *f;
-+ unsigned char key[3];
-+ unsigned keylen;
-+ int i;
-+
-+ key[0] = (afi >> 8) & 0xFF;
-+ key[1] = afi & 0xFF;
-+ if (safi != NULL) {
-+ key[2] = *safi & 0xFF;
-+ keylen = 3;
-+ } else {
-+ keylen = 2;
-+ }
-+
-+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
-+ f = sk_IPAddressFamily_value(addr, i);
-+ assert(f->addressFamily->data != NULL);
-+ if (f->addressFamily->length == keylen &&
-+ !memcmp(f->addressFamily->data, key, keylen))
-+ return f;
-+ }
-+
-+ if ((f = IPAddressFamily_new()) == NULL)
-+ goto err;
-+ if (f->ipAddressChoice == NULL &&
-+ (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
-+ goto err;
-+ if (f->addressFamily == NULL &&
-+ (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
-+ goto err;
-+ if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
-+ goto err;
-+ if (!sk_IPAddressFamily_push(addr, f))
-+ goto err;
-+
-+ return f;
-+
-+ err:
-+ IPAddressFamily_free(f);
-+ return NULL;
-+}
-+
-+/*
-+ * Add an inheritance element.
-+ */
-+static int addr_add_inherit(IPAddrBlocks *addr,
-+ const unsigned afi,
-+ const unsigned *safi)
-+{
-+ IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
-+ if (f == NULL ||
-+ f->ipAddressChoice == NULL ||
-+ (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
-+ f->ipAddressChoice->u.addressesOrRanges != NULL))
-+ return 0;
-+ if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
-+ f->ipAddressChoice->u.inherit != NULL)
-+ return 1;
-+ if (f->ipAddressChoice->u.inherit == NULL &&
-+ (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
-+ return 0;
-+ f->ipAddressChoice->type = IPAddressChoice_inherit;
-+ return 1;
-+}
-+
-+/*
-+ * Construct an IPAddressOrRange sequence, or return an existing one.
-+ */
-+static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
-+ const unsigned afi,
-+ const unsigned *safi)
-+{
-+ IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
-+ IPAddressOrRanges *aors = NULL;
-+
-+ if (f == NULL ||
-+ f->ipAddressChoice == NULL ||
-+ (f->ipAddressChoice->type == IPAddressChoice_inherit &&
-+ f->ipAddressChoice->u.inherit != NULL))
-+ return NULL;
-+ if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
-+ aors = f->ipAddressChoice->u.addressesOrRanges;
-+ if (aors != NULL)
-+ return aors;
-+ if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
-+ return NULL;
-+ switch (afi) {
-+ case IANA_AFI_IPV4:
-+ sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
-+ break;
-+ case IANA_AFI_IPV6:
-+ sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
-+ break;
-+ }
-+ f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
-+ f->ipAddressChoice->u.addressesOrRanges = aors;
-+ return aors;
-+}
-+
-+/*
-+ * Add a prefix.
-+ */
-+static int addr_add_prefix(IPAddrBlocks *addr,
-+ const unsigned afi,
-+ const unsigned *safi,
-+ unsigned char *a,
-+ const int prefixlen)
-+{
-+ IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
-+ IPAddressOrRange *aor;
-+ if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
-+ return 0;
-+ if (sk_IPAddressOrRange_push(aors, aor))
-+ return 1;
-+ IPAddressOrRange_free(aor);
-+ return 0;
-+}
-+
-+/*
-+ * Add a range.
-+ */
-+static int addr_add_range(IPAddrBlocks *addr,
-+ const unsigned afi,
-+ const unsigned *safi,
-+ unsigned char *min,
-+ unsigned char *max)
-+{
-+ IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
-+ IPAddressOrRange *aor;
-+ int length = length_from_afi(afi);
-+ if (aors == NULL)
-+ return 0;
-+ if (!make_addressRange(&aor, min, max, length))
-+ return 0;
-+ if (sk_IPAddressOrRange_push(aors, aor))
-+ return 1;
-+ IPAddressOrRange_free(aor);
-+ return 0;
-+}
-+
-+/*
-+ * Extract min and max values from an IPAddressOrRange.
-+ */
-+static void extract_min_max(IPAddressOrRange *aor,
-+ unsigned char *min,
-+ unsigned char *max,
-+ int length)
-+{
-+ assert(aor != NULL && min != NULL && max != NULL);
-+ switch (aor->type) {
-+ case IPAddressOrRange_addressPrefix:
-+ addr_expand(min, aor->u.addressPrefix, length, 0x00);
-+ addr_expand(max, aor->u.addressPrefix, length, 0xFF);
-+ return;
-+ case IPAddressOrRange_addressRange:
-+ addr_expand(min, aor->u.addressRange->min, length, 0x00);
-+ addr_expand(max, aor->u.addressRange->max, length, 0xFF);
-+ return;
-+ }
-+}
-+
-+/*
-+ * Sort comparision function for a sequence of IPAddressFamily.
-+ *
-+ * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
-+ * the ordering: I can read it as meaning that IPv6 without a SAFI
-+ * comes before IPv4 with a SAFI, which seems pretty weird. The
-+ * examples in appendix B suggest that the author intended the
-+ * null-SAFI rule to apply only within a single AFI, which is what I
-+ * would have expected and is what the following code implements.
-+ */
-+static int IPAddressFamily_cmp(const IPAddressFamily * const *a_,
-+ const IPAddressFamily * const *b_)
-+{
-+ const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
-+ const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
-+ int len = (( a->length <= b->length) ? a->length : b->length);
-+ int cmp = memcmp(a->data, b->data, len);
-+ return cmp ? cmp : a->length - b->length;
-+}
-+
-+/*
-+ * Check whether an IPAddrBLocks is in canonical form.
-+ */
-+int v3_addr_is_canonical(IPAddrBlocks *addr)
-+{
-+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
-+ unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
-+ IPAddressOrRanges *aors;
-+ int i, j, k;
-+
-+ /*
-+ * Empty extension is cannonical.
-+ */
-+ if (addr == NULL)
-+ return 1;
-+
-+ /*
-+ * Check whether the top-level list is in order.
-+ */
-+ for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
-+ const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
-+ const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
-+ if (IPAddressFamily_cmp(&a, &b) >= 0)
-+ return 0;
-+ }
-+
-+ /*
-+ * Top level's ok, now check each address family.
-+ */
-+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
-+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
-+ int length = length_from_afi(afi_from_addressfamily(f));
-+
-+ /*
-+ * Inheritance is canonical. Anything other than inheritance or
-+ * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
-+ */
-+ if (f == NULL || f->ipAddressChoice == NULL)
-+ return 0;
-+ switch (f->ipAddressChoice->type) {
-+ case IPAddressChoice_inherit:
-+ continue;
-+ case IPAddressChoice_addressesOrRanges:
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ /*
-+ * It's an IPAddressOrRanges sequence, check it.
-+ */
-+ aors = f->ipAddressChoice->u.addressesOrRanges;
-+ if (sk_IPAddressOrRange_num(aors) == 0)
-+ return 0;
-+ for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
-+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
-+ IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
-+
-+ extract_min_max(a, a_min, a_max, length);
-+ extract_min_max(b, b_min, b_max, length);
-+
-+ /*
-+ * Punt misordered list, overlapping start, or inverted range.
-+ */
-+ if (memcmp(a_min, b_min, length) >= 0 ||
-+ memcmp(a_min, a_max, length) > 0 ||
-+ memcmp(b_min, b_max, length) > 0)
-+ return 0;
-+
-+ /*
-+ * Punt if adjacent or overlapping. Check for adjacency by
-+ * subtracting one from b_min first.
-+ */
-+ for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)
-+ ;
-+ if (memcmp(a_max, b_min, length) >= 0)
-+ return 0;
-+
-+ /*
-+ * Check for range that should be expressed as a prefix.
-+ */
-+ if (a->type == IPAddressOrRange_addressRange &&
-+ range_should_be_prefix(a_min, a_max, length) >= 0)
-+ return 0;
-+ }
-+
-+ /*
-+ * Check final range to see if it should be a prefix.
-+ */
-+ j = sk_IPAddressOrRange_num(aors) - 1;
-+ {
-+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
-+ if (a->type == IPAddressOrRange_addressRange) {
-+ extract_min_max(a, a_min, a_max, length);
-+ if (range_should_be_prefix(a_min, a_max, length) >= 0)
-+ return 0;
-+ }
-+ }
-+ }
-+
-+ /*
-+ * If we made it through all that, we're happy.
-+ */
-+ return 1;
-+}
-+
-+/*
-+ * Whack an IPAddressOrRanges into canonical form.
-+ */
-+static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
-+ const unsigned afi)
-+{
-+ int i, j, length = length_from_afi(afi);
-+
-+ /*
-+ * Sort the IPAddressOrRanges sequence.
-+ */
-+ sk_IPAddressOrRange_sort(aors);
-+
-+ /*
-+ * Clean up representation issues, punt on duplicates or overlaps.
-+ */
-+ for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
-+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
-+ IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
-+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
-+ unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
-+
-+ extract_min_max(a, a_min, a_max, length);
-+ extract_min_max(b, b_min, b_max, length);
-+
-+ /*
-+ * Punt overlaps.
-+ */
-+ if (memcmp(a_max, b_min, length) >= 0)
-+ return 0;
-+
-+ /*
-+ * Merge if a and b are adjacent. We check for
-+ * adjacency by subtracting one from b_min first.
-+ */
-+ for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)
-+ ;
-+ if (memcmp(a_max, b_min, length) == 0) {
-+ IPAddressOrRange *merged;
-+ if (!make_addressRange(&merged, a_min, b_max, length))
-+ return 0;
-+ sk_IPAddressOrRange_set(aors, i, merged);
-+ sk_IPAddressOrRange_delete(aors, i + 1);
-+ IPAddressOrRange_free(a);
-+ IPAddressOrRange_free(b);
-+ --i;
-+ continue;
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+/*
-+ * Whack an IPAddrBlocks extension into canonical form.
-+ */
-+int v3_addr_canonize(IPAddrBlocks *addr)
-+{
-+ int i;
-+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
-+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
-+ if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
-+ !IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges,
-+ afi_from_addressfamily(f)))
-+ return 0;
-+ }
-+ sk_IPAddressFamily_sort(addr);
-+ assert(v3_addr_is_canonical(addr));
-+ return 1;
-+}
-+
-+/*
-+ * v2i handler for the IPAddrBlocks extension.
-+ */
-+static void *v2i_IPAddrBlocks(struct v3_ext_method *method,
-+ struct v3_ext_ctx *ctx,
-+ STACK_OF(CONF_VALUE) *values)
-+{
-+ static const char v4addr_chars[] = "0123456789.";
-+ static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
-+ IPAddrBlocks *addr = NULL;
-+ char *s = NULL, *t;
-+ int i;
-+
-+ if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
-+ return NULL;
-+ }
-+
-+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
-+ CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
-+ unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
-+ unsigned afi, *safi = NULL, safi_;
-+ const char *addr_chars;
-+ int prefixlen, i1, i2, delim, length;
-+
-+ if ( !name_cmp(val->name, "IPv4")) {
-+ afi = IANA_AFI_IPV4;
-+ } else if (!name_cmp(val->name, "IPv6")) {
-+ afi = IANA_AFI_IPV6;
-+ } else if (!name_cmp(val->name, "IPv4-SAFI")) {
-+ afi = IANA_AFI_IPV4;
-+ safi = &safi_;
-+ } else if (!name_cmp(val->name, "IPv6-SAFI")) {
-+ afi = IANA_AFI_IPV6;
-+ safi = &safi_;
-+ } else {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+
-+ switch (afi) {
-+ case IANA_AFI_IPV4:
-+ addr_chars = v4addr_chars;
-+ break;
-+ case IANA_AFI_IPV6:
-+ addr_chars = v6addr_chars;
-+ break;
-+ }
-+
-+ length = length_from_afi(afi);
-+
-+ /*
-+ * Handle SAFI, if any, and strdup() so we can null-terminate
-+ * the other input values.
-+ */
-+ if (safi != NULL) {
-+ *safi = strtoul(val->value, &t, 0);
-+ t += strspn(t, " \t");
-+ if (*safi > 0xFF || *t++ != ':') {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+ t += strspn(t, " \t");
-+ s = strdup(t);
-+ } else {
-+ s = strdup(val->value);
-+ }
-+ if (s == NULL) {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /*
-+ * Check for inheritance. Not worth additional complexity to
-+ * optimize this (seldom-used) case.
-+ */
-+ if (!strcmp(s, "inherit")) {
-+ if (!addr_add_inherit(addr, afi, safi)) {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+ OPENSSL_free(s);
-+ s = NULL;
-+ continue;
-+ }
-+
-+ i1 = strspn(s, addr_chars);
-+ i2 = i1 + strspn(s + i1, " \t");
-+ delim = s[i2++];
-+ s[i1] = '\0';
-+
-+ if (a2i_ipadd(min, s) != length) {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+
-+ switch (delim) {
-+ case '/':
-+ prefixlen = (int) strtoul(s + i2, &t, 10);
-+ if (t == s + i2 || *t != '\0') {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+ if (!addr_add_prefix(addr, afi, safi, min, prefixlen)) {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ break;
-+ case '-':
-+ i1 = i2 + strspn(s + i2, " \t");
-+ i2 = i1 + strspn(s + i1, addr_chars);
-+ if (i1 == i2 || s[i2] != '\0') {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+ if (a2i_ipadd(max, s + i1) != length) {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+ if (!addr_add_range(addr, afi, safi, min, max)) {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ break;
-+ case '\0':
-+ if (!addr_add_prefix(addr, afi, safi, min, length * 8)) {
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ break;
-+ default:
-+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
-+ X509V3_conf_err(val);
-+ goto err;
-+ }
-+
-+ OPENSSL_free(s);
-+ s = NULL;
-+ }
-+
-+ /*
-+ * Canonize the result, then we're done.
-+ */
-+ if (!v3_addr_canonize(addr))
-+ goto err;
-+ return addr;
-+
-+ err:
-+ OPENSSL_free(s);
-+ sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
-+ return NULL;
-+}
-+
-+/*
-+ * OpenSSL dispatch
-+ */
-+X509V3_EXT_METHOD v3_addr = {
-+ NID_sbgp_ipAddrBlock, /* nid */
-+ 0, /* flags */
-+ ASN1_ITEM_ref(IPAddrBlocks), /* template */
-+ 0, 0, 0, 0, /* old functions, ignored */
-+ 0, /* i2s */
-+ 0, /* s2i */
-+ 0, /* i2v */
-+ v2i_IPAddrBlocks, /* v2i */
-+ i2r_IPAddrBlocks, /* i2r */
-+ 0, /* r2i */
-+ NULL /* extension-specific data */
-+};
-+
-+/*
-+ * Figure out whether extension sues inheritance.
-+ */
-+int v3_addr_inherits(IPAddrBlocks *addr)
-+{
-+ int i;
-+ if (addr == NULL)
-+ return 0;
-+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
-+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
-+ if (f->ipAddressChoice->type == IPAddressChoice_inherit)
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Figure out whether parent contains child.
-+ */
-+static int addr_contains(IPAddressOrRanges *parent,
-+ IPAddressOrRanges *child,
-+ int length)
-+{
-+ unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
-+ unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
-+ int p, c;
-+
-+ if (child == NULL || parent == child)
-+ return 1;
-+ if (parent == NULL)
-+ return 0;
-+
-+ p = 0;
-+ for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
-+ extract_min_max(sk_IPAddressOrRange_value(child, c),
-+ c_min, c_max, length);
-+ for (;; p++) {
-+ if (p >= sk_IPAddressOrRange_num(parent))
-+ return 0;
-+ extract_min_max(sk_IPAddressOrRange_value(parent, p),
-+ p_min, p_max, length);
-+ if (memcmp(p_max, c_max, length) < 0)
-+ continue;
-+ if (memcmp(p_min, c_min, length) > 0)
-+ return 0;
-+ break;
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+/*
-+ * Test whether a is a subset of b.
-+ */
-+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
-+{
-+ int i;
-+ if (a == NULL || a == b)
-+ return 1;
-+ if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
-+ return 0;
-+ sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
-+ for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
-+ IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
-+ int j = sk_IPAddressFamily_find(b, fa);
-+ IPAddressFamily *fb = sk_IPAddressFamily_value(b, j);
-+ if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges,
-+ fa->ipAddressChoice->u.addressesOrRanges,
-+ length_from_afi(afi_from_addressfamily(fb))))
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+/*
-+ * Validation error handling via callback.
-+ */
-+#define validation_err(_err_) \
-+ do { \
-+ if (ctx != NULL) { \
-+ ctx->error = _err_; \
-+ ctx->error_depth = i; \
-+ ctx->current_cert = x; \
-+ ret = ctx->verify_cb(0, ctx); \
-+ } else { \
-+ ret = 0; \
-+ } \
-+ if (!ret) \
-+ goto done; \
-+ } while (0)
-+
-+/*
-+ * Core code for RFC 3779 2.3 path validation.
-+ */
-+static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
-+ STACK_OF(X509) *chain,
-+ IPAddrBlocks *ext)
-+{
-+ IPAddrBlocks *child = NULL;
-+ int i, j, ret = 1;
-+ X509 *x;
-+
-+ assert(chain != NULL && sk_X509_num(chain) > 0);
-+ assert(ctx != NULL || ext != NULL);
-+ assert(ctx == NULL || ctx->verify_cb != NULL);
-+
-+ /*
-+ * Figure out where to start. If we don't have an extension to
-+ * check, we're done. Otherwise, check canonical form and
-+ * set up for walking up the chain.
-+ */
-+ if (ext != NULL) {
-+ i = -1;
-+ } else {
-+ i = 0;
-+ x = sk_X509_value(chain, i);
-+ assert(x != NULL);
-+ if ((ext = x->rfc3779_addr) == NULL)
-+ goto done;
-+ }
-+ if (!v3_addr_is_canonical(ext))
-+ validation_err(X509_V_ERR_INVALID_EXTENSION);
-+ sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
-+ if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
-+ X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
-+ ret = 0;
-+ goto done;
-+ }
-+
-+ /*
-+ * Now walk up the chain. No cert may list resources that its
-+ * parent doesn't list.
-+ */
-+ for (i++; i < sk_X509_num(chain); i++) {
-+ x = sk_X509_value(chain, i);
-+ assert(x != NULL);
-+ if (!v3_addr_is_canonical(x->rfc3779_addr))
-+ validation_err(X509_V_ERR_INVALID_EXTENSION);
-+ if (x->rfc3779_addr == NULL) {
-+ for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
-+ IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
-+ if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ break;
-+ }
-+ }
-+ continue;
-+ }
-+ sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
-+ for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
-+ IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
-+ int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
-+ IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k);
-+ if (fp == NULL) {
-+ if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ break;
-+ }
-+ continue;
-+ }
-+ if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
-+ if (fc->ipAddressChoice->type == IPAddressChoice_inherit ||
-+ addr_contains(fp->ipAddressChoice->u.addressesOrRanges,
-+ fc->ipAddressChoice->u.addressesOrRanges,
-+ length_from_afi(afi_from_addressfamily(fc))))
-+ sk_IPAddressFamily_set(child, j, fp);
-+ else
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ }
-+ }
-+ }
-+
-+ /*
-+ * Trust anchor can't inherit.
-+ */
-+ if (x->rfc3779_addr != NULL) {
-+ for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
-+ IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j);
-+ if (fp->ipAddressChoice->type == IPAddressChoice_inherit &&
-+ sk_IPAddressFamily_find(child, fp) >= 0)
-+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
-+ }
-+ }
-+
-+ done:
-+ sk_IPAddressFamily_free(child);
-+ return ret;
-+}
-+
-+#undef validation_err
-+
-+/*
-+ * RFC 3779 2.3 path validation -- called from X509_verify_cert().
-+ */
-+int v3_addr_validate_path(X509_STORE_CTX *ctx)
-+{
-+ return v3_addr_validate_path_internal(ctx, ctx->chain, NULL);
-+}
-+
-+/*
-+ * RFC 3779 2.3 path validation of an extension.
-+ * Test whether chain covers extension.
-+ */
-+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
-+ IPAddrBlocks *ext,
-+ int allow_inheritance)
-+{
-+ if (ext == NULL)
-+ return 1;
-+ if (chain == NULL || sk_X509_num(chain) == 0)
-+ return 0;
-+ if (!allow_inheritance && v3_addr_inherits(ext))
-+ return 0;
-+ return v3_addr_validate_path_internal(NULL, chain, ext);
-+}
-
-Index: crypto/x509v3/ext_dat.h
-===================================================================
---- crypto/x509v3/ext_dat.h (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509v3/ext_dat.h (.../trunk) (revision 251)
-@@ -67,6 +67,7 @@
- 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;
-+extern X509V3_EXT_METHOD v3_addr, v3_asid;
-
- /* This table will be searched using OBJ_bsearch so it *must* kept in
- * order of the ext_nid values.
-@@ -99,6 +100,8 @@
- #endif
- &v3_sxnet,
- &v3_info,
-+&v3_addr,
-+&v3_asid,
- #ifndef OPENSSL_NO_OCSP
- &v3_ocsp_nonce,
- &v3_ocsp_crlid,
-
-Index: crypto/asn1/x_x509.c
-===================================================================
---- crypto/asn1/x_x509.c (.../vendor/0.9.8b) (revision 251)
-+++ crypto/asn1/x_x509.c (.../trunk) (revision 251)
-@@ -94,6 +94,8 @@
- ret->ex_pathlen = -1;
- ret->skid = NULL;
- ret->akid = NULL;
-+ ret->rfc3779_addr = NULL;
-+ ret->rfc3779_asid = NULL;
- ret->aux = NULL;
- CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
- break;
-@@ -109,6 +111,8 @@
- ASN1_OCTET_STRING_free(ret->skid);
- AUTHORITY_KEYID_free(ret->akid);
- policy_cache_free(ret->policy_cache);
-+ sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
-+ ASIdentifiers_free(ret->rfc3779_asid);
-
- if (ret->name != NULL) OPENSSL_free(ret->name);
- break;
-
-Index: crypto/x509/x509_vfy.h
-===================================================================
---- crypto/x509/x509_vfy.h (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509/x509_vfy.h (.../trunk) (revision 251)
-@@ -331,6 +331,7 @@
- #define X509_V_ERR_INVALID_POLICY_EXTENSION 42
- #define X509_V_ERR_NO_EXPLICIT_POLICY 43
-
-+#define X509_V_ERR_UNNESTED_RESOURCE 44
-
- /* The application is not happy */
- #define X509_V_ERR_APPLICATION_VERIFICATION 50
-Index: crypto/x509/x509_txt.c
-===================================================================
---- crypto/x509/x509_txt.c (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509/x509_txt.c (.../trunk) (revision 251)
-@@ -162,6 +162,8 @@
- return("invalid or inconsistent certificate policy extension");
- case X509_V_ERR_NO_EXPLICIT_POLICY:
- return("no explicit policy");
-+ case X509_V_ERR_UNNESTED_RESOURCE:
-+ return("RFC 3779 resource not subset of parent's resources");
- default:
- BIO_snprintf(buf,sizeof buf,"error number %ld",n);
- return(buf);
-Index: crypto/x509/x509.h
-===================================================================
---- crypto/x509/x509.h (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509/x509.h (.../trunk) (revision 251)
-@@ -288,6 +288,8 @@
- ASN1_OCTET_STRING *skid;
- struct AUTHORITY_KEYID_st *akid;
- X509_POLICY_CACHE *policy_cache;
-+ STACK_OF(IPAddressFamily) *rfc3779_addr;
-+ struct ASIdentifiers_st *rfc3779_asid;
- #ifndef OPENSSL_NO_SHA
- unsigned char sha1_hash[SHA_DIGEST_LENGTH];
- #endif
-Index: crypto/x509/x509_vfy.c
-===================================================================
---- crypto/x509/x509_vfy.c (.../vendor/0.9.8b) (revision 251)
-+++ crypto/x509/x509_vfy.c (.../trunk) (revision 251)
-@@ -312,6 +312,12 @@
- ok=internal_verify(ctx);
- if(!ok) goto end;
-
-+ /* RFC 3779 path validation, now that CRL check has been done */
-+ ok = v3_asid_validate_path(ctx);
-+ if (!ok) goto end;
-+ ok = v3_addr_validate_path(ctx);
-+ if (!ok) goto end;
-+
- /* If we get this far evaluate policies */
- if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
- ok = ctx->check_policy(ctx);
-
-Index: util/libeay.num
-===================================================================
---- util/libeay.num (.../vendor/0.9.8b) (revision 251)
-+++ util/libeay.num (.../trunk) (revision 251)
-@@ -3380,3 +3380,64 @@
- X509_VERIFY_PARAM_get_flags 3781 EXIST::FUNCTION:
- EVP_CIPHER_CTX_new 3782 EXIST::FUNCTION:
- EVP_CIPHER_CTX_free 3783 EXIST::FUNCTION:
-+ASIdentifiers_free 3784 EXIST::FUNCTION:
-+i2d_ASIdOrRange 3785 EXIST::FUNCTION:
-+IPAddressChoice_free 3786 EXIST::FUNCTION:
-+IPAddressOrRange_it 3787 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
-+IPAddressOrRange_it 3787 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
-+ASIdentifiers_it 3788 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
-+ASIdentifiers_it 3788 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
-+IPAddressChoice_it 3789 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
-+IPAddressChoice_it 3789 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
-+d2i_ASRange 3790 EXIST::FUNCTION:
-+IPAddressRange_free 3791 EXIST::FUNCTION:
-+IPAddressRange_new 3792 EXIST::FUNCTION:
-+ASIdOrRange_new 3793 EXIST::FUNCTION:
-+i2d_ASRange 3794 EXIST::FUNCTION:
-+IPAddressRange_it 3795 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
-+IPAddressRange_it 3795 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
-+IPAddressChoice_new 3796 EXIST::FUNCTION:
-+ASIdentifierChoice_new 3797 EXIST::FUNCTION:
-+ASRange_free 3798 EXIST::FUNCTION:
-+IPAddressFamily_free 3799 EXIST::FUNCTION:
-+i2d_IPAddressFamily 3800 EXIST::FUNCTION:
-+IPAddressOrRange_new 3801 EXIST::FUNCTION:
-+d2i_IPAddressRange 3802 EXIST::FUNCTION:
-+IPAddressOrRange_free 3803 EXIST::FUNCTION:
-+d2i_IPAddressFamily 3804 EXIST::FUNCTION:
-+i2d_ASIdentifierChoice 3805 EXIST::FUNCTION:
-+ASRange_it 3806 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
-+ASRange_it 3806 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
-+d2i_ASIdentifiers 3807 EXIST::FUNCTION:
-+ASRange_new 3808 EXIST::FUNCTION:
-+d2i_IPAddressChoice 3809 EXIST::FUNCTION:
-+i2d_IPAddressOrRange 3810 EXIST::FUNCTION:
-+ASIdOrRange_it 3811 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
-+ASIdOrRange_it 3811 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
-+i2d_IPAddressChoice 3812 EXIST::FUNCTION:
-+ASIdentifiers_new 3813 EXIST::FUNCTION:
-+IPAddressFamily_new 3814 EXIST::FUNCTION:
-+i2d_IPAddressRange 3815 EXIST::FUNCTION:
-+IPAddressFamily_it 3816 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
-+IPAddressFamily_it 3816 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
-+d2i_IPAddressOrRange 3817 EXIST::FUNCTION:
-+ASIdentifierChoice_it 3818 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
-+ASIdentifierChoice_it 3818 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
-+d2i_ASIdentifierChoice 3819 EXIST::FUNCTION:
-+ASIdOrRange_free 3820 EXIST::FUNCTION:
-+ASIdentifierChoice_free 3821 EXIST::FUNCTION:
-+d2i_ASIdOrRange 3822 EXIST::FUNCTION:
-+i2d_ASIdentifiers 3823 EXIST::FUNCTION:
-+v3_addr_validate_path 3824 EXIST::FUNCTION:
-+v3_asid_validate_path 3825 EXIST::FUNCTION:
-+a2i_ipadd 3826 EXIST::FUNCTION:
-+v3_asid_is_canonical 3827 EXIST::FUNCTION:
-+v3_addr_validate_resource_set 3828 EXIST::FUNCTION:
-+v3_asid_canonize 3829 EXIST::FUNCTION:
-+v3_asid_validate_resource_set 3830 EXIST::FUNCTION:
-+v3_addr_is_canonical 3831 EXIST::FUNCTION:
-+v3_addr_canonize 3832 EXIST::FUNCTION:
-+v3_addr_inherits 3833 EXIST::FUNCTION:
-+v3_addr_subset 3834 EXIST::FUNCTION:
-+v3_asid_subset 3835 EXIST::FUNCTION:
-+v3_asid_inherits 3836 EXIST::FUNCTION:
-