List Info

Thread: OpenSSL: openssl/ CHANGES Configure openssl/apps/ ca.c openssl/c...




OpenSSL: openssl/ CHANGES Configure openssl/apps/ ca.c openssl/c...
user name
2006-11-27 14:18:07
  OpenSSL CVS Repository
  http://cvs.openssl.org/
 
____________________________________________________________
________________

  Server: cvs.openssl.org                  Name:   Ben
Laurie
  Root:   /v/openssl/cvs                   Email:  benopenssl.org
  Module: openssl                          Date:  
27-Nov-2006 15:18:07
  Branch: HEAD                             Handle:
2006112714175609

  Added files:
    openssl/crypto/x509v3   v3_addr.c v3_asid.c
  Modified files:
    openssl                 CHANGES Configure
    openssl/apps            ca.c
    openssl/crypto/asn1     x_x509.c
    openssl/crypto/stack    safestack.h
    openssl/crypto/x509     x509.h x509_txt.c x509_vfy.c
x509_vfy.h
    openssl/crypto/x509v3   Makefile ext_dat.h pcy_tree.c
v3_purp.c v3_utl.c
                            v3err.c x509v3.h

  Log:
    Add RFC 3779 support.

  Summary:
    Revision    Changes     Path
    1.1360      +3  -0      openssl/CHANGES
    1.545       +9  -0      openssl/Configure
    1.156       +1  -0      openssl/apps/ca.c
    1.27        +8  -0      openssl/crypto/asn1/x_x509.c
    1.54        +70 -0      openssl/crypto/stack/safestack.h
    1.151       +4  -0      openssl/crypto/x509/x509.h
    1.21        +2  -0      openssl/crypto/x509/x509_txt.c
    1.86        +8  -0      openssl/crypto/x509/x509_vfy.c
    1.63        +1  -0      openssl/crypto/x509/x509_vfy.h
    1.6         +33 -2      openssl/crypto/x509v3/Makefile
    1.19        +5  -0      openssl/crypto/x509v3/ext_dat.h
    1.7         +10 -0      openssl/crypto/x509v3/pcy_tree.c
    1.2         +1280 -0    openssl/crypto/x509v3/v3_addr.c
    1.2         +844 -0     openssl/crypto/x509v3/v3_asid.c
    1.38        +10 -0      openssl/crypto/x509v3/v3_purp.c
    1.35        +1  -2      openssl/crypto/x509v3/v3_utl.c
    1.40        +10 -0      openssl/crypto/x509v3/v3err.c
    1.110       +160 -0     openssl/crypto/x509v3/x509v3.h
 
____________________________________________________________
________________

  patch -p0 <<' .'
  Index: openssl/CHANGES
 
============================================================
================
  $ cvs diff -u -r1.1359 -r1.1360 CHANGES
  --- openssl/CHANGES	21 Nov 2006 21:29:34 -0000	1.1359
  +++ openssl/CHANGES	27 Nov 2006 14:17:56 -0000	1.1360
   -423,6 +423,9 
   
    Changes between 0.9.8d and 0.9.8e  [XX xxx XXXX]
   
  +  *) Add RFC 3779 support.
  +     [Rob Austein for ARIN, Ben Laurie]
  +
    Changes between 0.9.8c and 0.9.8d  [28 Sep 2006]
   
     *) Introduce limits to prevent malicious keys being
able to
   .
  patch -p0 <<' .'
  Index: openssl/Configure
 
============================================================
================
  $ cvs diff -u -r1.544 -r1.545 Configure
  --- openssl/Configure	23 Oct 2006 07:38:27 -0000	1.544
  +++ openssl/Configure	27 Nov 2006 14:17:57 -0000	1.545
   -579,6 +579,7 
   my $no_shared=0; # but "no-shared" is default
   my $zlib=1;      # but "no-zlib" is default
   my $no_krb5=0;   # but "no-krb5" is implied
unless "--with-krb5-..." is used
  +my $rfc3779=1;	 # but "no-rfc3779" is default
   my $no_asm=0;
   my $no_dso=0;
   my $no_gmp=0;
   -614,6 +615,7 
   		 "gmp"		  => "default",
                    "mdc2"           =>
"default",
                    "rc5"            =>
"default",
  +		 "rfc3779"	  => "default",
                    "shared"         =>
"default",
                    "zlib"           =>
"default",
                    "zlib-dynamic"   =>
"default"
   -901,6 +903,8 
   		{ $symlink = 0; }
   	elsif (/^sse2$/)
   		{ $no_sse2 = 1; }
  +	elsif (/^rfc3779$/)
  +		{ $rfc3779 = 0; }
   	else
   		{
   		my ($ALGO, $algo);
   -1137,6 +1141,11 
   		}
   	}
   
  +if ($rfc3779)
  +	{
  +	$openssl_other_defines.="#define
OPENSSL_RFC3779n";
  +	}
  +
   # You will find shlib_mark1 and shlib_mark2 explained in
Makefile.org
   my $shared_mark = "";
   if ($shared_target eq "")
   .
  patch -p0 <<' .'
  Index: openssl/apps/ca.c
 
============================================================
================
  $ cvs diff -u -r1.155 -r1.156 ca.c
  --- openssl/apps/ca.c	25 Jul 2006 17:39:37 -0000	1.155
  +++ openssl/apps/ca.c	27 Nov 2006 14:17:59 -0000	1.156
   -1525,6 +1525,7 
   	if (x509) X509_free(x509);
   	X509_CRL_free(crl);
   	NCONF_free(conf);
  +	NCONF_free(extconf);
   	OBJ_cleanup();
   	apps_shutdown();
   	OPENSSL_EXIT(ret);
   .
  patch -p0 <<' .'
  Index: openssl/crypto/asn1/x_x509.c
 
============================================================
================
  $ cvs diff -u -r1.26 -r1.27 x_x509.c
  --- openssl/crypto/asn1/x_x509.c	24 Jul 2006 12:39:21
-0000	1.26
  +++ openssl/crypto/asn1/x_x509.c	27 Nov 2006 14:18:00
-0000	1.27
   -95,6 +95,10 
   		ret->ex_pathlen = -1;
   		ret->skid = NULL;
   		ret->akid = NULL;
  +#ifdef OPENSSL_RFC3779
  +		ret->rfc3779_addr = NULL;
  +		ret->rfc3779_asid = NULL;
  +#endif
   		ret->aux = NULL;
   		ret->crldp = NULL;
   		CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret,
&ret->ex_data);
   -112,6 +116,10 
   		AUTHORITY_KEYID_free(ret->akid);
   		CRL_DIST_POINTS_free(ret->crldp);
   		policy_cache_free(ret->policy_cache);
  +#ifdef OPENSSL_RFC3779
  +		sk_IPAddressFamily_pop_free(ret->rfc3779_addr,
IPAddressFamily_free);
  +		ASIdentifiers_free(ret->rfc3779_asid);
  +#endif
   
   		if (ret->name != NULL) OPENSSL_free(ret->name);
   		break;
   .
  patch -p0 <<' .'
  Index: openssl/crypto/stack/safestack.h
 
============================================================
================
  $ cvs diff -u -r1.53 -r1.54 safestack.h
  --- openssl/crypto/stack/safestack.h	16 Nov 2006 00:19:38
-0000	1.53
  +++ openssl/crypto/stack/safestack.h	27 Nov 2006 14:18:01
-0000	1.54
   -297,6 +297,30 
   #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))
   
  +#ifdef OPENSSL_RFC3779
  +#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))
  +#endif /* def OPENSSL_RFC3779 */
  +
   #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))
   -781,6 +805,52 
   #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))
   
  +#ifdef OPENSSL_RFC3779
  +#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))
  +#endif /* def OPENSSL_RFC3779 */
  +
   #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))
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509/x509.h
 
============================================================
================
  $ cvs diff -u -r1.150 -r1.151 x509.h
  --- openssl/crypto/x509/x509.h	16 Nov 2006 00:55:33
-0000	1.150
  +++ openssl/crypto/x509/x509.h	27 Nov 2006 14:18:02
-0000	1.151
   -291,6 +291,10 
   	AUTHORITY_KEYID *akid;
   	X509_POLICY_CACHE *policy_cache;
   	STACK_OF(DIST_POINT) *crldp;
  +#ifdef OPENSSL_RFC3779
  +	STACK_OF(IPAddressFamily) *rfc3779_addr;
  +	struct ASIdentifiers_st *rfc3779_asid;
  +#endif
   #ifndef OPENSSL_NO_SHA
   	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
   #endif
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509/x509_txt.c
 
============================================================
================
  $ cvs diff -u -r1.20 -r1.21 x509_txt.c
  --- openssl/crypto/x509/x509_txt.c	14 Sep 2006 17:25:01
-0000	1.20
  +++ openssl/crypto/x509/x509_txt.c	27 Nov 2006 14:18:02
-0000	1.21
   -166,6 +166,8 
   	return("Different CRL scope");
   	case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
   	return("Unsupported extension feature");
  + 	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);
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509/x509_vfy.c
 
============================================================
================
  $ cvs diff -u -r1.85 -r1.86 x509_vfy.c
  --- openssl/crypto/x509/x509_vfy.c	21 Sep 2006 12:42:15
-0000	1.85
  +++ openssl/crypto/x509/x509_vfy.c	27 Nov 2006 14:18:02
-0000	1.86
   -314,6 +314,14 
   		ok=internal_verify(ctx);
   	if(!ok) goto end;
   
  +#ifdef OPENSSL_RFC3779
  +	/* 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;
  +#endif
  +
   	/* If we get this far evaluate policies */
   	if (!bad_chain && (ctx->param->flags &
X509_V_FLAG_POLICY_CHECK))
   		ok = ctx->check_policy(ctx);
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509/x509_vfy.h
 
============================================================
================
  $ cvs diff -u -r1.62 -r1.63 x509_vfy.h
  --- openssl/crypto/x509/x509_vfy.h	17 Sep 2006 17:16:28
-0000	1.62
  +++ openssl/crypto/x509/x509_vfy.h	27 Nov 2006 14:18:02
-0000	1.63
   -339,6 +339,7 
   #define		X509_V_ERR_DIFFERENT_CRL_SCOPE			44
   #define		X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE	45
   
  +#define		X509_V_ERR_UNNESTED_RESOURCE			46
   
   /* The application is not happy */
   #define		X509_V_ERR_APPLICATION_VERIFICATION		50
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509v3/Makefile
 
============================================================
================
  $ cvs diff -u -r1.5 -r1.6 Makefile
  --- openssl/crypto/x509v3/Makefile	4 Feb 2006 01:45:56
-0000	1.5
  +++ openssl/crypto/x509v3/Makefile	27 Nov 2006 14:18:03
-0000	1.6
   -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
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509v3/ext_dat.h
 
============================================================
================
  $ cvs diff -u -r1.18 -r1.19 ext_dat.h
  --- openssl/crypto/x509v3/ext_dat.h	23 Jul 2005 23:33:06
-0000	1.18
  +++ openssl/crypto/x509v3/ext_dat.h	27 Nov 2006 14:18:03
-0000	1.19
   -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, v3_idp;
  +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,10 
   #endif
   &v3_sxnet,
   &v3_info,
  +#ifdef OPENSSL_RFC3779
  +&v3_addr,
  +&v3_asid,
  +#endif
   #ifndef OPENSSL_NO_OCSP
   &v3_ocsp_nonce,
   &v3_ocsp_crlid,
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509v3/pcy_tree.c
 
============================================================
================
  $ cvs diff -u -r1.6 -r1.7 pcy_tree.c
  --- openssl/crypto/x509v3/pcy_tree.c	5 Oct 2006 21:59:50
-0000	1.6
  +++ openssl/crypto/x509v3/pcy_tree.c	27 Nov 2006 14:18:03
-0000	1.7
   -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;
   		}
   
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509v3/v3_addr.c
 
============================================================
================
  $ cvs diff -u -r0 -r1.2 v3_addr.c
  --- /dev/null	2006-11-27 15:17:34 +0100
  +++ v3_addr.c	2006-11-27 15:18:05 +0100
   -0,0 +1,1280 
  +/*
  + * Contributed to the OpenSSL Project by the American
Registry for
  + * Internet Numbers ("ARIN").
  + */
  +/*
============================================================
========
  + * Copyright (c) 2006 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/)&
quot;
  + *
  + * 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
  + *    licensingOpenSSL.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/)&
quot;
  + *
  + * 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
  + * (eaycryptsoft.com).  This product includes software
written by Tim
  + * Hudson (tjhcryptsoft.com).
  + */
  +
  +/*
  + * 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>
  +
  +#ifdef OPENSSL_RFC3779
  +
  +/*
  + * 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.
  + */
  +unsigned v3_addr_get_afi(const IPAddressFamily *f)
  +{
  +  return ((f != NULL &&
  +	   f->addressFamily != NULL &&
  +	   f->addressFamily->data != NULL)
  +	  ? ((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, "/%dn",
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 = v3_addr_get_afi(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, ": inheritn");
  +      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 = 0, prefixlen_b = 0;
  +  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.
  + */
  +int v3_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.
  + */
  +int v3_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.
  + */
  +int v3_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;
  +  }
  +}
  +
  +/*
  + * Public wrapper for extract_min_max().
  + */
  +int v3_addr_get_range(IPAddressOrRange *aor,
  +		      const unsigned afi,
  +		      unsigned char *min,
  +		      unsigned char *max,
  +		      const int length)
  +{
  +  int afi_length = length_from_afi(afi);
  +  if (aor == NULL || min == NULL || max == NULL ||
  +      afi_length == 0 || length < afi_length ||
  +      (aor->type != IPAddressOrRange_addressPrefix
&&
  +       aor->type != IPAddressOrRange_addressRange))
  +    return 0;
  +  extract_min_max(aor, min, max, afi_length);
  +  return afi_length;
  +}
  +
  +/*
  + * 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(v3_addr_get_afi(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.ad
dressesOrRanges,
  +				    v3_addr_get_afi(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 (!v3_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] = '';
  +
  +    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 != '') {
  +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
X509V3_R_EXTENSION_VALUE_ERROR);
  +	X509V3_conf_err(val);
  +	goto err;
  +      }
  +      if (!v3_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] != '') {
  +	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 (!v3_addr_add_range(addr, afi, safi, min, max))
{
  +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
ERR_R_MALLOC_FAILURE);
  +	goto err;
  +      }
  +      break;
  +    case '':
  +      if (!v3_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.addressesOrRang
es, 
  +		       fa->ipAddressChoice->u.addressesOrRanges,
  +		       length_from_afi(v3_addr_get_afi(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;
  +    x = NULL;
  +  } 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(v3_addr_get_afi(fc))))
  +	  sk_IPAddressFamily_set(child, j, fp);
  +	else
  +	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
  +      }
  +    }
  +  }
  +
  +  /*
  +   * Trust anchor can't inherit.
  +   */
  +  assert(x != NULL);
  +  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);
  +}
  +
  +#endif /* OPENSSL_RFC3779 */
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509v3/v3_asid.c
 
============================================================
================
  $ cvs diff -u -r0 -r1.2 v3_asid.c
  --- /dev/null	2006-11-27 15:17:34 +0100
  +++ v3_asid.c	2006-11-27 15:18:06 +0100
   -0,0 +1,844 
  +/*
  + * Contributed to the OpenSSL Project by the American
Registry for
  + * Internet Numbers ("ARIN").
  + */
  +/*
============================================================
========
  + * Copyright (c) 2006 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/)&
quot;
  + *
  + * 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
  + *    licensingOpenSSL.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/)&
quot;
  + *
  + * 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
  + * (eaycryptsoft.com).  This product includes software
written by Tim
  + * Hudson (tjhcryptsoft.com).
  + */
  +
  +/*
  + * 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>
  +
  +#ifdef OPENSSL_RFC3779
  +
  +/*
  + * 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, "%*sinheritn", 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%sn", 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, "%sn", 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"));
  +}
  +
  +/*
  + * Sort comparision function for a sequence of
ASIdOrRange elements.
  + */
  +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);
  +}
  +
  +/*
  + * Add an inherit element.
  + */
  +int v3_asid_add_inherit(ASIdentifiers *asid, int which)
  +{
  +  ASIdentifierChoice **choice;
  +  if (asid == NULL)
  +    return 0;
  +  switch (which) {
  +  case V3_ASID_ASNUM:
  +    choice = &asid->asnum;
  +    break;
  +  case V3_ASID_RDI:
  +    choice = &asid->rdi;
  +    break;
  +  default:
  +    return 0;
  +  }
  +  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.
  + */
  +int v3_asid_add_id_or_range(ASIdentifiers *asid,
  +			    int which,
  +			    ASN1_INTEGER *min,
  +			    ASN1_INTEGER *max)
  +{
  +  ASIdentifierChoice **choice;
  +  ASIdOrRange *aor;
  +  if (asid == NULL)
  +    return 0;
  +  switch (which) {
  +  case V3_ASID_ASNUM:
  +    choice = &asid->asnum;
  +    break;
  +  case V3_ASID_RDI:
  +    choice = &asid->rdi;
  +    break;
  +  default:
  +    return 0;
  +  }
  +  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);
  +    ASN1_INTEGER *min = NULL, *max = NULL;
  +    int i1, i2, i3, is_range, which;
  +
  +    /*
  +     * Figure out whether this is an AS or an RDI.
  +     */
  +    if (       !name_cmp(val->name, "AS")) {
  +      which = V3_ASID_ASNUM;
  +    } else if (!name_cmp(val->name, "RDI"))
{
  +      which = V3_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 (v3_asid_add_inherit(asid, which))
  +	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] == '') {
  +      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] != '') {
  +	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] = '';
  +      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 (!v3_asid_add_id_or_range(asid, which, 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;
  +    x = NULL;
  +  } 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.asIdsOrRang
es, 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.
  +   */
  +  assert(x != NULL);
  +  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);
  +}
  +
  +#endif /* OPENSSL_RFC3779 */
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509v3/v3_purp.c
 
============================================================
================
  $ cvs diff -u -r1.37 -r1.38 v3_purp.c
  --- openssl/crypto/x509v3/v3_purp.c	14 Sep 2006 17:25:02
-0000	1.37
  +++ openssl/crypto/x509v3/v3_purp.c	27 Nov 2006 14:18:05
-0000	1.38
   -287,7 +287,12 
           	NID_key_usage,		/* 83 */
   		NID_subject_alt_name,	/* 85 */
   		NID_basic_constraints,	/* 87 */
  +		NID_certificate_policies, /* 89 */
           	NID_ext_key_usage,	/* 126 */
  +#ifdef OPENSSL_RFC3779
  +		NID_sbgp_ipAddrBlock,	/* 290 */
  +		NID_sbgp_autonomousSysNum, /* 291 */
  +#endif
   		NID_proxyCertInfo	/* 661 */
   	};
   
   -413,6 +418,11 
   	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->crldp = X509_get_ext_d2i(x,
NID_crl_distribution_points, NULL, NULL);
  +#ifdef OPENSSL_RFC3779
  + 	x->rfc3779_addr =X509_get_ext_d2i(x,
NID_sbgp_ipAddrBlock, NULL, NULL);
  + 	x->rfc3779_asid =X509_get_ext_d2i(x,
NID_sbgp_autonomousSysNum,
  + 					  NULL, NULL);
  +#endif
   	for (i = 0; i < X509_get_ext_count(x); i++)
   		{
   		ex = X509_get_ext(x, i);
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509v3/v3_utl.c
 
============================================================
================
  $ cvs diff -u -r1.34 -r1.35 v3_utl.c
  --- openssl/crypto/x509v3/v3_utl.c	6 Mar 2006 17:58:25
-0000	1.34
  +++ openssl/crypto/x509v3/v3_utl.c	27 Nov 2006 14:18:05
-0000	1.35
   -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 */
   
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509v3/v3err.c
 
============================================================
================
  $ cvs diff -u -r1.39 -r1.40 v3err.c
  --- openssl/crypto/x509v3/v3err.c	21 Nov 2006 21:29:43
-0000	1.39
  +++ openssl/crypto/x509v3/v3err.c	27 Nov 2006 14:18:05
-0000	1.40
   -70,6 +70,8 
   
   static ERR_STRING_DATA X509V3_str_functs[]=
   	{
 
+{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE),	"ASID
ENTIFIERCHOICE_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"},
   -101,6 +103,7 
  
{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG),	"SXNET_add_id_u
long"},
  
{ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC),	"SXNET_get_id_asc
"},
  
{ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG),	"SXNET_get_id_u
long"},
 
+{ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS),	"V2I_ASIDENTIFI
ERS"},
  
{ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING),	"v2i_ASN1_BIT_
STRING"},
  
{ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS),	"V2I_AUT
HORITY_INFO_ACCESS"},
  
{ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID),	"V2I_AUTHORITY
_KEYID"},
   -110,11 +113,13 
  
{ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES),	"v2i_GENERAL_NAM
ES"},
  
{ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX),	"v2i_GENERAL_N
AME_ex"},
   {ERR_FUNC(X509V3_F_V2I_IDP),	"V2I_IDP"},
 
+{ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS),	"V2I_IPADDRBLOCK
S"},
  
{ERR_FUNC(X509V3_F_V2I_ISSUER_ALT),	"V2I_ISSUER_ALT&quo
t;},
  
{ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS),	"V2I_NAME_CON
STRAINTS"},
  
{ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS),	"V2I_POLICY
_CONSTRAINTS"},
  
{ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS),	"V2I_POLICY_MA
PPINGS"},
  
{ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT),	"V2I_SUBJECT_ALT&q
uot;},
 
+{ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL),	"V
3_ADDR_VALIDATE_PATH_INTERNAL"},
  
{ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION),	"V3_GENERIC_E
XTENSION"},
  
{ERR_FUNC(X509V3_F_X509V3_ADD1_I2D),	"X509V3_add1_i2d&q
uot;},
  
{ERR_FUNC(X509V3_F_X509V3_ADD_VALUE),	"X509V3_add_value
"},
   -154,8 +159,12 
   {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT)  ,"illegal
hex digit"},
  
{ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),"inco
rrect policy syntax tag"},
   {ERR_REASON(X509V3_R_INVAID_MULTIPLE_RDNS),"invaid
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"},
   -167,6 +176,7 
  
{ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER),"invali
d policy identifier"},
  
{ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING),"inv
alid 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"},
   .
  patch -p0 <<' .'
  Index: openssl/crypto/x509v3/x509v3.h
 
============================================================
================
  $ cvs diff -u -r1.109 -r1.110 x509v3.h
  --- openssl/crypto/x509v3/x509v3.h	14 Sep 2006 17:25:02
-0000	1.109
  +++ openssl/crypto/x509v3/x509v3.h	27 Nov 2006 14:18:05
-0000	1.110
   -652,11 +652,161 
   
   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);
   
  +#ifdef OPENSSL_RFC3779
  +
  +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)
  +
  +/*
  + * API tag for elements of the ASIdentifer SEQUENCE.
  + */
  +#define	V3_ASID_ASNUM	0
  +#define	V3_ASID_RDI	1
  +
  +/*
  + * 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
  +
  +/*
  + * Utilities to construct and extract values from RFC3779
extensions,
  + * since some of the encodings (particularly for IP
address prefixes
  + * and ranges) are a bit tedious to work with directly.
  + */
  +int v3_asid_add_inherit(ASIdentifiers *asid, int which);
  +int v3_asid_add_id_or_range(ASIdentifiers *asid, int
which,
  +			    ASN1_INTEGER *min, ASN1_INTEGER *max);
  +int v3_addr_add_inherit(IPAddrBlocks *addr,
  +			const unsigned afi, const unsigned *safi);
  +int v3_addr_add_prefix(IPAddrBlocks *addr,
  +		       const unsigned afi, const unsigned *safi,
  +		       unsigned char *a, const int prefixlen);
  +int v3_addr_add_range(IPAddrBlocks *addr,
  +		      const unsigned afi, const unsigned *safi,
  +		      unsigned char *min, unsigned char *max);
  +unsigned v3_addr_get_afi(const IPAddressFamily *f);
  +int v3_addr_get_range(IPAddressOrRange *aor, const
unsigned afi,
  +		      unsigned char *min, unsigned char *max,
  +		      const int length);
  +
  +/*
  + * 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);
  +
  +#endif /* OPENSSL_RFC3779 */
  +
   /* 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.
   -666,6 +816,8 
   /* Error codes for the X509V3 functions. */
   
   /* Function codes. */
  +#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE		 161
  +#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL	 162
   #define X509V3_F_COPY_EMAIL				 122
   #define X509V3_F_COPY_ISSUER				 123
   #define X509V3_F_DO_DIRNAME				 144
   -697,6 +849,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			 163
   #define X509V3_F_V2I_ASN1_BIT_STRING			 101
   #define X509V3_F_V2I_AUTHORITY_INFO_ACCESS		 139
   #define X509V3_F_V2I_AUTHORITY_KEYID			 119
   -706,11 +859,13 
   #define X509V3_F_V2I_GENERAL_NAMES			 118
   #define X509V3_F_V2I_GENERAL_NAME_EX			 117
   #define X509V3_F_V2I_IDP				 157
  +#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
   -747,8 +902,12 
   #define X509V3_R_ILLEGAL_HEX_DIGIT			 113
   #define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG		 152
   #define X509V3_R_INVAID_MULTIPLE_RDNS			 161
  +#define X509V3_R_INVALID_ASNUMBER			 162
  +#define X509V3_R_INVALID_ASRANGE			 163
   #define X509V3_R_INVALID_BOOLEAN_STRING			 104
   #define X509V3_R_INVALID_EXTENSION_STRING		 105
  +#define X509V3_R_INVALID_INHERITANCE			 165
  +#define X509V3_R_INVALID_IPADDRESS			 166
   #define X509V3_R_INVALID_NAME				 106
   #define X509V3_R_INVALID_NULL_ARGUMENT			 107
   #define X509V3_R_INVALID_NULL_NAME			 108
   -760,6 +919,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
   .
____________________________________________________________
__________
OpenSSL Project                                 http://www.openssl.org
CVS Repository Commit List                    
openssl-cvsopenssl.org
Automated List Manager                          
majordomoopenssl.org
[1]

about | contact  Other archives ( Real Estate discussion Medical topics )