Add some utilities to support SXNet extension also add support in DEF files
generator to typesafe stacks.
diff --git a/CHANGES b/CHANGES
index b331a7d..5c4fe66 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,10 @@
 
  Changes between 0.9.2b and 0.9.3
 
+  *) Various utility functions to handle SXNet extension. Modify mkdef.pl to
+     support typesafe stack.
+     [Steve Henson]
+
   *) Fix typo in SSL_[gs]et_options().
      [Nils Frostberg <nils@medcom.se>]
 
diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509v3/v3_lib.c
index 7abac29..f5dda42 100644
--- a/crypto/x509v3/v3_lib.c
+++ b/crypto/x509v3/v3_lib.c
@@ -71,11 +71,11 @@
 X509V3_EXT_METHOD *ext;
 {
 	if(!ext_list && !(ext_list = sk_new(ext_cmp))) {
-		X509V3err(X509V3_F_X509V3_ADD_EXT,ERR_R_MALLOC_FAILURE);
+		X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE);
 		return 0;
 	}
 	if(!sk_push(ext_list, (char *)ext)) {
-		X509V3err(X509V3_F_X509V3_ADD_EXT,ERR_R_MALLOC_FAILURE);
+		X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE);
 		return 0;
 	}
 	return 1;
diff --git a/crypto/x509v3/v3_sxnet.c b/crypto/x509v3/v3_sxnet.c
index 22c5aaa..443a574 100644
--- a/crypto/x509v3/v3_sxnet.c
+++ b/crypto/x509v3/v3_sxnet.c
@@ -65,8 +65,13 @@
 
 /* Support for Thawte strong extranet extension */
 
+#define SXNET_TEST
+
 #ifndef NOPROTO
 static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent);
+#ifdef SXNET_TEST
+static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *nval);
+#endif
 #else
 static int sxnet_i2r();
 #endif
@@ -78,7 +83,12 @@
 (X509V3_EXT_D2I)d2i_SXNET,
 i2d_SXNET,
 NULL, NULL,
-NULL, NULL,
+NULL, 
+#ifdef SXNET_TEST
+(X509V3_EXT_V2I)sxnet_v2i,
+#else
+NULL,
+#endif
 (X509V3_EXT_I2R)sxnet_i2r,
 NULL,
 NULL
@@ -114,8 +124,8 @@
 	SXNET *ret=NULL;
 	ASN1_CTX c;
 	M_ASN1_New_Malloc(ret, SXNET);
-	ret->version = NULL;
-	ret->ids = NULL;
+	M_ASN1_New(ret->version,ASN1_INTEGER_new);
+	M_ASN1_New(ret->ids,sk_new_null);
 	return (ret);
 	M_ASN1_New_Error(ASN1_F_SXNET_NEW);
 }
@@ -142,8 +152,6 @@
 	Free ((char *)a);
 }
 
-
-
 int i2d_SXNETID(a,pp)
 SXNETID *a;
 unsigned char **pp;
@@ -215,3 +223,158 @@
 	}
 	return 1;
 }
+
+#ifdef SXNET_TEST
+
+/* NBB: this is used for testing only. It should *not* be used for anything
+ * else because it will just take static IDs from the configuration file and
+ * they should really be separate values for each user.
+ */
+
+
+static SXNET * sxnet_v2i(method, ctx, nval)
+X509V3_EXT_METHOD *method;
+X509V3_CTX *ctx;
+STACK *nval;
+{
+	CONF_VALUE *cnf;
+	SXNET *sx = NULL;
+	int i;
+	for(i = 0; i < sk_num(nval); i++) {
+		cnf = (CONF_VALUE *)sk_value(nval, i);
+		if(!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
+								 return NULL;
+	}
+	return sx;
+}
+		
+	
+#endif
+
+/* Strong Extranet utility functions */
+
+/* Add an id given the zone as an ASCII number */
+
+int SXNET_add_id_asc(psx, zone, user, userlen)
+SXNET **psx;
+char *zone;
+unsigned char *user;
+int userlen;
+{
+	ASN1_INTEGER *izone = NULL;
+	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+		X509V3err(X509V3_F_SXNET_ADD_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
+		return 0;
+	}
+	return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+}
+
+/* Add an id given the zone as an unsigned long */
+
+int SXNET_add_id_ulong(psx, lzone, user, userlen)
+SXNET **psx;
+unsigned long lzone;
+unsigned char *user;
+int userlen;
+{
+	ASN1_INTEGER *izone = NULL;
+	if(!(izone = ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+		X509V3err(X509V3_F_SXNET_ADD_ID_ULONG,ERR_R_MALLOC_FAILURE);
+		ASN1_INTEGER_free(izone);
+		return 0;
+	}
+	return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+	
+}
+
+/* Add an id given the zone as an ASN1_INTEGER.
+ * Note this version uses the passed integer and doesn't make a copy so don't
+ * free it up afterwards.
+ */
+
+int SXNET_add_id_INTEGER(psx, zone, user, userlen)
+SXNET **psx;
+ASN1_INTEGER *zone;
+unsigned char *user;
+int userlen;
+{
+	SXNET *sx = NULL;
+	SXNETID *id = NULL;
+	if(!psx || !zone || !user) {
+		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_INVALID_NULL_ARGUMENT);
+		return 0;
+	}
+	if(userlen == -1) userlen = strlen(user);
+	if(userlen > 64) {
+		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_USER_TOO_LONG);
+		return 0;
+	}
+	if(!*psx) {
+		if(!(sx = SXNET_new())) goto err;
+		if(!ASN1_INTEGER_set(sx->version, 0)) goto err;
+		*psx = sx;
+	} else sx = *psx;
+	if(SXNET_get_id_INTEGER(sx, zone)) {
+		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_DUPLICATE_ZONE_ID);
+		return 0;
+	}
+
+	if(!(id = SXNETID_new())) goto err;
+	if(userlen == -1) userlen = strlen(user);
+		
+	if(!ASN1_OCTET_STRING_set(id->user, user, userlen)) goto err;
+	if(!sk_push(sx->ids, (char *)id)) goto err;
+	id->zone = zone;
+	return 1;
+	
+	err:
+	X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,ERR_R_MALLOC_FAILURE);
+	SXNETID_free(id);
+	SXNET_free(sx);
+	*psx = NULL;
+	return 0;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(sx, zone)
+SXNET *sx;
+char *zone;
+{
+	ASN1_INTEGER *izone = NULL;
+	ASN1_OCTET_STRING *oct;
+	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+		X509V3err(X509V3_F_SXNET_GET_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
+		return NULL;
+	}
+	oct = SXNET_get_id_INTEGER(sx, izone);
+	ASN1_INTEGER_free(oct);
+	return oct;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_ulong(sx, lzone)
+SXNET *sx;
+unsigned long lzone;
+{
+	ASN1_INTEGER *izone = NULL;
+	ASN1_OCTET_STRING *oct;
+	if(!(izone = ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+		X509V3err(X509V3_F_SXNET_GET_ID_ULONG,ERR_R_MALLOC_FAILURE);
+		ASN1_INTEGER_free(izone);
+		return NULL;
+	}
+	oct = SXNET_get_id_INTEGER(sx, izone);
+	ASN1_INTEGER_free(oct);
+	return oct;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(sx, zone)
+SXNET *sx;
+ASN1_INTEGER *zone;
+{
+	SXNETID *id;
+	int i;
+	for(i = 0; i < sk_num(sx->ids); i++) {
+		id = (SXNETID *)sk_value(sx->ids, i);
+		if(!ASN1_INTEGER_cmp(id->zone, zone)) return id->user;
+	}
+	return NULL;
+}
diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c
index 40b7810..cd53f35 100644
--- a/crypto/x509v3/v3_utl.c
+++ b/crypto/x509v3/v3_utl.c
@@ -151,6 +151,30 @@
 	return strtmp;
 }
 
+ASN1_INTEGER *s2i_ASN1_INTEGER(method, value)
+X509V3_EXT_METHOD *method;
+char *value;
+{
+	BIGNUM *bn = NULL;
+	ASN1_INTEGER *aint;
+	bn = BN_new();
+	if(!value) {
+		X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_INVALID_NULL_VALUE);
+		return 0;
+	}
+	if(!BN_dec2bn(&bn, value)) {
+		X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_DEC2BN_ERROR);
+		return 0;
+	}
+
+	if(!(aint = BN_to_ASN1_INTEGER(bn, NULL))) {
+		X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
+		return 0;
+	}
+	BN_free(bn);
+	return aint;
+}
+
 int X509V3_add_value_int(name, aint, extlist)
 char *name;
 ASN1_INTEGER *aint;
@@ -183,7 +207,7 @@
 		return 1;
 	}
 	err:
-	X509V3err(X509V3_F_X509V3_VALUE_GET_BOOL,X509V3_R_INVALID_BOOLEAN_STRING);
+	X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,X509V3_R_INVALID_BOOLEAN_STRING);
 	X509V3_conf_err(value);
 	return 0;
 }
@@ -192,25 +216,12 @@
 CONF_VALUE *value;
 ASN1_INTEGER **aint;
 {
-	BIGNUM *bn = NULL;
-	bn = BN_new();
-	if(!value->value) {
-		X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_INVALID_NULL_VALUE);
+	ASN1_INTEGER *itmp;
+	if(!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
 		X509V3_conf_err(value);
 		return 0;
 	}
-	if(!BN_dec2bn(&bn, value->value)) {
-		X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_BN_DEC2BN_ERROR);
-		X509V3_conf_err(value);
-		return 0;
-	}
-
-	if(!(*aint = BN_to_ASN1_INTEGER(bn, NULL))) {
-		X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
-		X509V3_conf_err(value);
-		return 0;
-	}
-	BN_free(bn);
+	*aint = itmp;
 	return 1;
 }
 
diff --git a/crypto/x509v3/v3err.c b/crypto/x509v3/v3err.c
index ecf50c7..ac7ac48 100644
--- a/crypto/x509v3/v3err.c
+++ b/crypto/x509v3/v3err.c
@@ -70,10 +70,16 @@
 {ERR_PACK(0,X509V3_F_I2S_ASN1_ENUMERATED,0),	"i2s_ASN1_ENUMERATED"},
 {ERR_PACK(0,X509V3_F_I2S_ASN1_INTEGER,0),	"i2s_ASN1_INTEGER"},
 {ERR_PACK(0,X509V3_F_S2I_ASN1_IA5STRING,0),	"S2I_ASN1_IA5STRING"},
+{ERR_PACK(0,X509V3_F_S2I_ASN1_INTEGER,0),	"s2i_ASN1_INTEGER"},
 {ERR_PACK(0,X509V3_F_S2I_ASN1_OCTET_STRING,0),	"s2i_ASN1_OCTET_STRING"},
 {ERR_PACK(0,X509V3_F_S2I_ASN1_SKEY_ID,0),	"S2I_ASN1_SKEY_ID"},
 {ERR_PACK(0,X509V3_F_S2I_S2I_SKEY_ID,0),	"S2I_S2I_SKEY_ID"},
 {ERR_PACK(0,X509V3_F_STRING_TO_HEX,0),	"string_to_hex"},
+{ERR_PACK(0,X509V3_F_SXNET_ADD_ASC,0),	"SXNET_ADD_ASC"},
+{ERR_PACK(0,X509V3_F_SXNET_ADD_ID_INTEGER,0),	"SXNET_add_id_INTEGER"},
+{ERR_PACK(0,X509V3_F_SXNET_ADD_ID_ULONG,0),	"SXNET_add_id_ulong"},
+{ERR_PACK(0,X509V3_F_SXNET_GET_ID_ASC,0),	"SXNET_get_id_asc"},
+{ERR_PACK(0,X509V3_F_SXNET_GET_ID_ULONG,0),	"SXNET_get_id_ulong"},
 {ERR_PACK(0,X509V3_F_V2I_ASN1_BIT_STRING,0),	"V2I_ASN1_BIT_STRING"},
 {ERR_PACK(0,X509V3_F_V2I_AUTHORITY_KEYID,0),	"V2I_AUTHORITY_KEYID"},
 {ERR_PACK(0,X509V3_F_V2I_BASIC_CONSTRAINTS,0),	"V2I_BASIC_CONSTRAINTS"},
@@ -81,13 +87,12 @@
 {ERR_PACK(0,X509V3_F_V2I_GENERAL_NAME,0),	"v2i_GENERAL_NAME"},
 {ERR_PACK(0,X509V3_F_V2I_GENERAL_NAMES,0),	"v2i_GENERAL_NAMES"},
 {ERR_PACK(0,X509V3_F_V3_GENERIC_EXTENSION,0),	"V3_GENERIC_EXTENSION"},
-{ERR_PACK(0,X509V3_F_X509V3_ADD_EXT,0),	"X509V3_ADD_EXT"},
+{ERR_PACK(0,X509V3_F_X509V3_EXT_ADD,0),	"X509V3_EXT_add"},
 {ERR_PACK(0,X509V3_F_X509V3_ADD_VALUE,0),	"X509V3_add_value"},
 {ERR_PACK(0,X509V3_F_X509V3_EXT_ADD_ALIAS,0),	"X509V3_EXT_add_alias"},
 {ERR_PACK(0,X509V3_F_X509V3_EXT_CONF,0),	"X509V3_EXT_conf"},
-{ERR_PACK(0,X509V3_F_X509V3_GET_VALUE_INT,0),	"X509V3_get_value_int"},
 {ERR_PACK(0,X509V3_F_X509V3_PARSE_LIST,0),	"X509V3_parse_list"},
-{ERR_PACK(0,X509V3_F_X509V3_VALUE_GET_BOOL,0),	"X509V3_VALUE_GET_BOOL"},
+{ERR_PACK(0,X509V3_F_X509V3_GET_VALUE_BOOL,0),	"X509V3_get_value_bool"},
 {0,NULL},
 	};
 
@@ -97,6 +102,8 @@
 {X509V3_R_BAD_OBJECT                     ,"bad object"},
 {X509V3_R_BN_DEC2BN_ERROR                ,"bn dec2bn error"},
 {X509V3_R_BN_TO_ASN1_INTEGER_ERROR       ,"bn to asn1 integer error"},
+{X509V3_R_DUPLICATE_ZONE_ID              ,"duplicate zone id"},
+{X509V3_R_ERROR_CONVERTING_ZONE          ,"error converting zone"},
 {X509V3_R_ERROR_IN_EXTENSION             ,"error in extension"},
 {X509V3_R_EXTENSION_NAME_ERROR           ,"extension name error"},
 {X509V3_R_EXTENSION_NOT_FOUND            ,"extension not found"},
@@ -124,6 +131,7 @@
 {X509V3_R_UNKNOWN_EXTENSION_NAME         ,"unknown extension name"},
 {X509V3_R_UNKNOWN_OPTION                 ,"unknown option"},
 {X509V3_R_UNSUPPORTED_OPTION             ,"unsupported option"},
+{X509V3_R_USER_TOO_LONG                  ,"user too long"},
 {0,NULL},
 	};
 
diff --git a/crypto/x509v3/x509v3.err b/crypto/x509v3/x509v3.err
index 0f1d948..9358d44 100644
--- a/crypto/x509v3/x509v3.err
+++ b/crypto/x509v3/x509v3.err
@@ -8,10 +8,16 @@
 #define X509V3_F_I2S_ASN1_ENUMERATED			 121
 #define X509V3_F_I2S_ASN1_INTEGER			 120
 #define X509V3_F_S2I_ASN1_IA5STRING			 100
+#define X509V3_F_S2I_ASN1_INTEGER			 108
 #define X509V3_F_S2I_ASN1_OCTET_STRING			 112
 #define X509V3_F_S2I_ASN1_SKEY_ID			 114
 #define X509V3_F_S2I_S2I_SKEY_ID			 115
 #define X509V3_F_STRING_TO_HEX				 113
+#define X509V3_F_SXNET_ADD_ASC				 125
+#define X509V3_F_SXNET_ADD_ID_INTEGER			 126
+#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_ASN1_BIT_STRING			 101
 #define X509V3_F_V2I_AUTHORITY_KEYID			 119
 #define X509V3_F_V2I_BASIC_CONSTRAINTS			 102
@@ -19,19 +25,20 @@
 #define X509V3_F_V2I_GENERAL_NAME			 117
 #define X509V3_F_V2I_GENERAL_NAMES			 118
 #define X509V3_F_V3_GENERIC_EXTENSION			 116
-#define X509V3_F_X509V3_ADD_EXT				 104
+#define X509V3_F_X509V3_EXT_ADD				 104
 #define X509V3_F_X509V3_ADD_VALUE			 105
 #define X509V3_F_X509V3_EXT_ADD_ALIAS			 106
 #define X509V3_F_X509V3_EXT_CONF			 107
-#define X509V3_F_X509V3_GET_VALUE_INT			 108
 #define X509V3_F_X509V3_PARSE_LIST			 109
-#define X509V3_F_X509V3_VALUE_GET_BOOL			 110
+#define X509V3_F_X509V3_GET_VALUE_BOOL			 110
 
 /* Reason codes. */
 #define X509V3_R_BAD_IP_ADDRESS				 118
 #define X509V3_R_BAD_OBJECT				 119
 #define X509V3_R_BN_DEC2BN_ERROR			 100
 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR		 101
+#define X509V3_R_DUPLICATE_ZONE_ID			 133
+#define X509V3_R_ERROR_CONVERTING_ZONE			 131
 #define X509V3_R_ERROR_IN_EXTENSION			 128
 #define X509V3_R_EXTENSION_NAME_ERROR			 115
 #define X509V3_R_EXTENSION_NOT_FOUND			 102
@@ -59,3 +66,4 @@
 #define X509V3_R_UNKNOWN_EXTENSION_NAME			 130
 #define X509V3_R_UNKNOWN_OPTION				 120
 #define X509V3_R_UNSUPPORTED_OPTION			 117
+#define X509V3_R_USER_TOO_LONG				 132
diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h
index 6b65056..081a86b 100644
--- a/crypto/x509v3/x509v3.h
+++ b/crypto/x509v3/x509v3.h
@@ -235,6 +235,14 @@
 SXNETID *SXNETID_new(void);
 void SXNETID_free(SXNETID *a);
 
+int SXNET_add_id_asc(SXNET **psx, char *zone, unsigned char *user, int userlen); 
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, unsigned char *user, int userlen); 
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, unsigned char *user, int userlen); 
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone);
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone);
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone);
+
 int i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **pp);
 AUTHORITY_KEYID *d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, unsigned char **pp, long length);
 AUTHORITY_KEYID *AUTHORITY_KEYID_new(void);
@@ -276,6 +284,7 @@
 int X509V3_add_value_bool(char *name, int asn1_bool, STACK **extlist);
 int X509V3_add_value_int( char *name, ASN1_INTEGER *aint, STACK **extlist);
 char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
+ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
 char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
 char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
 int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
@@ -319,6 +328,12 @@
 SXNETID *d2i_SXNETID();
 SXNETID *SXNETID_new();
 void SXNETID_free();
+int SXNET_add_id_asc();
+int SXNET_add_id_ulong();
+int SXNET_add_id_INTEGER();
+ASN1_OCTET_STRING *SXNET_get_id_asc();
+ASN1_OCTET_STRING *SXNET_get_id_ulong();
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER();
 
 int i2d_AUTHORITY_KEYID();
 AUTHORITY_KEYID *d2i_AUTHORITY_KEYID();
@@ -359,6 +374,7 @@
 int X509V3_add_value_bool();
 int X509V3_add_value_int();
 char *i2s_ASN1_INTEGER();
+ASN1_INTEGER * s2i_ASN1_INTEGER();
 char * i2s_ASN1_ENUMERATED();
 char * i2s_ASN1_ENUMERATED_TABLE();
 int X509V3_EXT_add();
@@ -391,10 +407,16 @@
 #define X509V3_F_I2S_ASN1_ENUMERATED			 121
 #define X509V3_F_I2S_ASN1_INTEGER			 120
 #define X509V3_F_S2I_ASN1_IA5STRING			 100
+#define X509V3_F_S2I_ASN1_INTEGER			 108
 #define X509V3_F_S2I_ASN1_OCTET_STRING			 112
 #define X509V3_F_S2I_ASN1_SKEY_ID			 114
 #define X509V3_F_S2I_S2I_SKEY_ID			 115
 #define X509V3_F_STRING_TO_HEX				 113
+#define X509V3_F_SXNET_ADD_ASC				 125
+#define X509V3_F_SXNET_ADD_ID_INTEGER			 126
+#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_ASN1_BIT_STRING			 101
 #define X509V3_F_V2I_AUTHORITY_KEYID			 119
 #define X509V3_F_V2I_BASIC_CONSTRAINTS			 102
@@ -402,19 +424,20 @@
 #define X509V3_F_V2I_GENERAL_NAME			 117
 #define X509V3_F_V2I_GENERAL_NAMES			 118
 #define X509V3_F_V3_GENERIC_EXTENSION			 116
-#define X509V3_F_X509V3_ADD_EXT				 104
+#define X509V3_F_X509V3_EXT_ADD				 104
 #define X509V3_F_X509V3_ADD_VALUE			 105
 #define X509V3_F_X509V3_EXT_ADD_ALIAS			 106
 #define X509V3_F_X509V3_EXT_CONF			 107
-#define X509V3_F_X509V3_GET_VALUE_INT			 108
 #define X509V3_F_X509V3_PARSE_LIST			 109
-#define X509V3_F_X509V3_VALUE_GET_BOOL			 110
+#define X509V3_F_X509V3_GET_VALUE_BOOL			 110
 
 /* Reason codes. */
 #define X509V3_R_BAD_IP_ADDRESS				 118
 #define X509V3_R_BAD_OBJECT				 119
 #define X509V3_R_BN_DEC2BN_ERROR			 100
 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR		 101
+#define X509V3_R_DUPLICATE_ZONE_ID			 133
+#define X509V3_R_ERROR_CONVERTING_ZONE			 131
 #define X509V3_R_ERROR_IN_EXTENSION			 128
 #define X509V3_R_EXTENSION_NAME_ERROR			 115
 #define X509V3_R_EXTENSION_NOT_FOUND			 102
@@ -442,6 +465,7 @@
 #define X509V3_R_UNKNOWN_EXTENSION_NAME			 130
 #define X509V3_R_UNKNOWN_OPTION				 120
 #define X509V3_R_UNSUPPORTED_OPTION			 117
+#define X509V3_R_USER_TOO_LONG				 132
  
 #ifdef  __cplusplus
 }
diff --git a/util/mkdef.pl b/util/mkdef.pl
index a8e5ab5..4eafcc4 100755
--- a/util/mkdef.pl
+++ b/util/mkdef.pl
@@ -11,6 +11,8 @@
 
 $W32=1;
 $NT=0;
+# Set this to make typesafe STACK definitions appear in DEF
+$safe_stack_def = 1;
 foreach (@ARGV)
 	{
 	$W32=1 if $_ eq "32";
@@ -179,7 +181,33 @@
 			$t=undef;
 			if (/^extern .*;$/)
 				{ $t=&do_extern($name,$_); }
-			elsif (	($tag{'NOPROTO'} == 1) &&
+			elsif ($safe_stack_def &&
+				/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/)
+				{
+				push(@ret,"sk_${1}_new");
+				push(@ret,"sk_${1}_new_null");
+				push(@ret,"sk_${1}_free");
+				push(@ret,"sk_${1}_num");
+				push(@ret,"sk_${1}_value");
+				push(@ret,"sk_${1}_set");
+				push(@ret,"sk_${1}_zero");
+				push(@ret,"sk_${1}_push");
+			#	push(@ret,"sk_${1}_pop");
+				push(@ret,"sk_${1}_find");
+				push(@ret,"sk_${1}_delete");
+				push(@ret,"sk_${1}_delete_ptr");
+				push(@ret,"sk_${1}_set_cmp_func");
+				push(@ret,"sk_${1}_dup");
+				push(@ret,"sk_${1}_pop_free");
+				push(@ret,"sk_${1}_shift");
+				}
+			elsif ($safe_stack_def &&
+				/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/)
+				{
+				push(@ret,"d2i_ASN1_SET_OF_${1}");
+				push(@ret,"i2d_ASN1_SET_OF_${1}");
+				}
+			elsif (($tag{'NOPROTO'} == 1) &&
 				($tag{'FreeBSD'} != 1) &&
 				(($W32 && ($tag{'WIN16'} != 1)) ||
 				 (!$W32 && ($tag{'WIN16'} != -1))) &&