Yet another stack.
diff --git a/Configure b/Configure
index 565b2dc..b02026e 100755
--- a/Configure
+++ b/Configure
@@ -94,6 +94,7 @@
 "purify",	"purify gcc:-g -DPURIFY -Wall:(unknown):-lsocket -lnsl::::",
 "debug",	"gcc:-DBN_DEBUG -DREF_CHECK -DCRYPTO_MDEBUG -ggdb -g2 -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror:(unknown):-lefence::::",
 "debug-ben",	"gcc:-DBN_DEBUG -DREF_CHECK -DCRYPTO_MDEBUG -O2 -pedantic -Wall -Wshadow -Werror -pipe:(unknown):::::",
+"debug-ben-debug",	"gcc:-DBN_DEBUG -DREF_CHECK -DCRYPTO_MDEBUG -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe:(unknown):::::",
 "debug-ben-strict",	"gcc:-DBN_DEBUG -DREF_CHECK -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe:(unknown):::::",
 "debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall:(unknown)::BN_LLONG $x86_gcc_des $x86_gcc_opts:$x86_elf_asm",
 "dist",		"cc:-O:(unknown):::::",
diff --git a/apps/ca.c b/apps/ca.c
index 2fe6300..efcd817 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -1721,7 +1721,8 @@
 		/* Free the current entries if any, there should not
 		 * be any I belive */
 		if (ci->extensions != NULL)
-			sk_pop_free(ci->extensions,X509_EXTENSION_free);
+			sk_X509_EXTENSION_pop_free(ci->extensions,
+						   X509_EXTENSION_free);
 
 		ci->extensions = NULL;
 
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index 89ee3a7..b056b84 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -638,8 +638,8 @@
 			BIO_printf(out, ": ");
 		} else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
 
-		if(sk_num(attr->value.set)) {
-			av = (ASN1_TYPE *)sk_value(attr->value.set, 0);
+		if(sk_ASN1_TYPE_num(attr->value.set)) {
+			av = sk_ASN1_TYPE_value(attr->value.set, 0);
 			switch(av->type) {
 				case V_ASN1_BMPSTRING:
         			value = uni2asc(av->value.bmpstring->data,
diff --git a/crypto/asn1/asn1_mac.h b/crypto/asn1/asn1_mac.h
index 2689f22..6edbf06 100644
--- a/crypto/asn1/asn1_mac.h
+++ b/crypto/asn1/asn1_mac.h
@@ -175,6 +175,10 @@
 	if ((a != NULL) && (sk_num(a) != 0)) \
 		M_ASN1_I2D_put_SEQUENCE(a,f);
 
+#define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
+	if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+		M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
+
 #define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
 	if ((c.slen != 0) && \
 		(M_ASN1_next == \
@@ -206,6 +210,11 @@
 		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
 		{ M_ASN1_D2I_get_seq(r,func,free_func); }
 
+#define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
+		{ M_ASN1_D2I_get_seq_type(type,r,func,free_func); }
+
 #define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
 		M_ASN1_D2I_get_imp_set(r,func,free_func,\
 			x,V_ASN1_CONTEXT_SPECIFIC);
@@ -286,6 +295,32 @@
 		c.slen-=(c.p-c.q); \
 		}
 
+#define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
+	if ((c.slen != 0) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
+			free_func,b,V_ASN1_UNIVERSAL) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
 /* New macros */
 #define M_ASN1_New_Malloc(ret,type) \
 	if ((ret=(type *)Malloc(sizeof(type))) == NULL) \
@@ -329,6 +364,10 @@
 		if ((a != NULL) && (sk_num(a) != 0)) \
 			M_ASN1_I2D_len_SEQUENCE(a,f);
 
+#define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
+
 #define M_ASN1_I2D_len_IMP_SET(a,f,x) \
 		ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
 
@@ -383,6 +422,15 @@
 			ret+=ASN1_object_size(1,v,mtag); \
 			}
 
+#define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
+						 V_ASN1_UNIVERSAL, \
+						 IS_SEQUENCE); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
 /* Put Macros */
 #define M_ASN1_I2D_put(a,f)	f(a,&p)
 
@@ -457,6 +505,14 @@
 			i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
 			}
 
+#define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
+					       IS_SEQUENCE); \
+			}
+
 #define M_ASN1_I2D_seq_total() \
 		r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
 		if (pp == NULL) return(r); \
diff --git a/crypto/asn1/x_cinf.c b/crypto/asn1/x_cinf.c
index fb6122e..6f28092 100644
--- a/crypto/asn1/x_cinf.c
+++ b/crypto/asn1/x_cinf.c
@@ -74,7 +74,9 @@
 	M_ASN1_I2D_len(a->key,			i2d_X509_PUBKEY);
 	M_ASN1_I2D_len_IMP_opt(a->issuerUID,	i2d_ASN1_BIT_STRING);
 	M_ASN1_I2D_len_IMP_opt(a->subjectUID,	i2d_ASN1_BIT_STRING);
-	M_ASN1_I2D_len_EXP_SEQUENCE_opt(a->extensions,i2d_X509_EXTENSION,3,V_ASN1_SEQUENCE,v2);
+	M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(X509_EXTENSION,a->extensions,
+					     i2d_X509_EXTENSION,3,
+					     V_ASN1_SEQUENCE,v2);
 
 	M_ASN1_I2D_seq_total();
 
@@ -87,7 +89,9 @@
 	M_ASN1_I2D_put(a->key,			i2d_X509_PUBKEY);
 	M_ASN1_I2D_put_IMP_opt(a->issuerUID,	i2d_ASN1_BIT_STRING,1);
 	M_ASN1_I2D_put_IMP_opt(a->subjectUID,	i2d_ASN1_BIT_STRING,2);
-	M_ASN1_I2D_put_EXP_SEQUENCE_opt(a->extensions,i2d_X509_EXTENSION,3,V_ASN1_SEQUENCE,v2);
+	M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(X509_EXTENSION,a->extensions,
+					     i2d_X509_EXTENSION,3,
+					     V_ASN1_SEQUENCE,v2);
 
 	M_ASN1_I2D_finish();
 	}
@@ -147,11 +151,13 @@
 #endif
 		{
 		if (ret->extensions != NULL)
-			while (sk_num(ret->extensions))
-				X509_EXTENSION_free((X509_EXTENSION *)
-					sk_pop(ret->extensions));
-		M_ASN1_D2I_get_EXP_set_opt(ret->extensions,d2i_X509_EXTENSION,
-			X509_EXTENSION_free,3,V_ASN1_SEQUENCE);
+			while (sk_X509_EXTENSION_num(ret->extensions))
+				X509_EXTENSION_free(
+				      sk_X509_EXTENSION_pop(ret->extensions));
+		M_ASN1_D2I_get_EXP_set_opt_type(X509_EXTENSION,ret->extensions,
+						d2i_X509_EXTENSION,
+						X509_EXTENSION_free,3,
+						V_ASN1_SEQUENCE);
 		}
 	M_ASN1_D2I_Finish(a,X509_CINF_free,ASN1_F_D2I_X509_CINF);
 	}
@@ -188,7 +194,7 @@
 	X509_PUBKEY_free(a->key);
 	ASN1_BIT_STRING_free(a->issuerUID);
 	ASN1_BIT_STRING_free(a->subjectUID);
-	sk_pop_free(a->extensions,X509_EXTENSION_free);
-	Free((char *)a);
+	sk_X509_EXTENSION_pop_free(a->extensions,X509_EXTENSION_free);
+	Free(a);
 	}
 
diff --git a/crypto/asn1/x_crl.c b/crypto/asn1/x_crl.c
index 794e7a0..6d87edd 100644
--- a/crypto/asn1/x_crl.c
+++ b/crypto/asn1/x_crl.c
@@ -69,13 +69,15 @@
 
 	M_ASN1_I2D_len(a->serialNumber,i2d_ASN1_INTEGER);
 	M_ASN1_I2D_len(a->revocationDate,i2d_ASN1_TIME);
-	M_ASN1_I2D_len_SEQUENCE_opt(a->extensions,i2d_X509_EXTENSION);
+	M_ASN1_I2D_len_SEQUENCE_opt_type(X509_EXTENSION,a->extensions,
+					 i2d_X509_EXTENSION);
 
 	M_ASN1_I2D_seq_total();
 
 	M_ASN1_I2D_put(a->serialNumber,i2d_ASN1_INTEGER);
 	M_ASN1_I2D_put(a->revocationDate,i2d_ASN1_TIME);
-	M_ASN1_I2D_put_SEQUENCE_opt(a->extensions,i2d_X509_EXTENSION);
+	M_ASN1_I2D_put_SEQUENCE_opt_type(X509_EXTENSION,a->extensions,
+					 i2d_X509_EXTENSION);
 
 	M_ASN1_I2D_finish();
 	}
@@ -89,8 +91,8 @@
 	M_ASN1_D2I_start_sequence();
 	M_ASN1_D2I_get(ret->serialNumber,d2i_ASN1_INTEGER);
 	M_ASN1_D2I_get(ret->revocationDate,d2i_ASN1_TIME);
-	M_ASN1_D2I_get_seq_opt(ret->extensions,d2i_X509_EXTENSION,
-		X509_EXTENSION_free);
+	M_ASN1_D2I_get_seq_opt_type(X509_EXTENSION,ret->extensions,
+				    d2i_X509_EXTENSION,X509_EXTENSION_free);
 	M_ASN1_D2I_Finish(a,X509_REVOKED_free,ASN1_F_D2I_X509_REVOKED);
 	}
 
@@ -113,8 +115,9 @@
 	if (a->nextUpdate != NULL)
 		{ M_ASN1_I2D_len(a->nextUpdate,i2d_ASN1_TIME); }
 	M_ASN1_I2D_len_SEQUENCE_opt(a->revoked,i2d_X509_REVOKED);
-	M_ASN1_I2D_len_EXP_SEQUENCE_opt(a->extensions,i2d_X509_EXTENSION,0,
-		V_ASN1_SEQUENCE,v1);
+	M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(X509_EXTENSION,a->extensions,
+					     i2d_X509_EXTENSION,0,
+					     V_ASN1_SEQUENCE,v1);
 
 	M_ASN1_I2D_seq_total();
 
@@ -128,8 +131,9 @@
 	if (a->nextUpdate != NULL)
 		{ M_ASN1_I2D_put(a->nextUpdate,i2d_ASN1_UTCTIME); }
 	M_ASN1_I2D_put_SEQUENCE_opt(a->revoked,i2d_X509_REVOKED);
-	M_ASN1_I2D_put_EXP_SEQUENCE_opt(a->extensions,i2d_X509_EXTENSION,0,
-		V_ASN1_SEQUENCE,v1);
+	M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(X509_EXTENSION,a->extensions,
+					     i2d_X509_EXTENSION,0,
+					     V_ASN1_SEQUENCE,v1);
 
 	M_ASN1_I2D_finish();
 	}
@@ -185,13 +189,15 @@
 		{
 		if (ret->extensions != NULL)
 			{
-			while (sk_num(ret->extensions))
-				X509_EXTENSION_free((X509_EXTENSION *)
-				sk_pop(ret->extensions));
+			while (sk_X509_EXTENSION_num(ret->extensions))
+				X509_EXTENSION_free(
+				sk_X509_EXTENSION_pop(ret->extensions));
 			}
 			
-		M_ASN1_D2I_get_EXP_set_opt(ret->extensions,d2i_X509_EXTENSION,
-			X509_EXTENSION_free,0,V_ASN1_SEQUENCE);
+		M_ASN1_D2I_get_EXP_set_opt_type(X509_EXTENSION,ret->extensions,
+						d2i_X509_EXTENSION,
+						X509_EXTENSION_free,0,
+						V_ASN1_SEQUENCE);
 		}
 
 	M_ASN1_D2I_Finish(a,X509_CRL_INFO_free,ASN1_F_D2I_X509_CRL_INFO);
@@ -253,7 +259,7 @@
 	M_ASN1_New(ret->lastUpdate,ASN1_UTCTIME_new);
 	ret->nextUpdate=NULL;
 	M_ASN1_New(ret->revoked,sk_new_null);
-	M_ASN1_New(ret->extensions,sk_new_null);
+	M_ASN1_New(ret->extensions,sk_X509_EXTENSION_new_null);
 	ret->revoked->comp=(int (*)())X509_REVOKED_cmp;
 	return(ret);
 	M_ASN1_New_Error(ASN1_F_X509_CRL_INFO_NEW);
@@ -278,8 +284,8 @@
 	if (a == NULL) return;
 	ASN1_INTEGER_free(a->serialNumber);
 	ASN1_UTCTIME_free(a->revocationDate);
-	sk_pop_free(a->extensions,X509_EXTENSION_free);
-	Free((char *)a);
+	sk_X509_EXTENSION_pop_free(a->extensions,X509_EXTENSION_free);
+	Free(a);
 	}
 
 void X509_CRL_INFO_free(X509_CRL_INFO *a)
@@ -292,8 +298,8 @@
 	if (a->nextUpdate)
 		ASN1_UTCTIME_free(a->nextUpdate);
 	sk_pop_free(a->revoked,X509_REVOKED_free);
-	sk_pop_free(a->extensions,X509_EXTENSION_free);
-	Free((char *)a);
+	sk_X509_EXTENSION_pop_free(a->extensions,X509_EXTENSION_free);
+	Free(a);
 	}
 
 void X509_CRL_free(X509_CRL *a)
@@ -318,7 +324,7 @@
 	X509_CRL_INFO_free(a->crl);
 	X509_ALGOR_free(a->sig_alg);
 	ASN1_BIT_STRING_free(a->signature);
-	Free((char *)a);
+	Free(a);
 	}
 
 static int X509_REVOKED_cmp(X509_REVOKED **a, X509_REVOKED **b)
diff --git a/crypto/stack/safestack.h b/crypto/stack/safestack.h
index 37f68b9..154468e 100644
--- a/crypto/stack/safestack.h
+++ b/crypto/stack/safestack.h
@@ -67,8 +67,8 @@
 STACK_OF(type) *sk_##type##_new(int (*cmp)(type **,type **)); \
 STACK_OF(type) *sk_##type##_new_null(void); \
 void sk_##type##_free(STACK_OF(type) *sk); \
-int sk_##type##_num(STACK_OF(type) *sk); \
-type *sk_##type##_value(STACK_OF(type) *sk,int n); \
+int sk_##type##_num(const STACK_OF(type) *sk); \
+type *sk_##type##_value(const STACK_OF(type) *sk,int n); \
 type *sk_##type##_set(STACK_OF(type) *sk,int n,type *v); \
 void sk_##type##_zero(STACK_OF(type) *sk); \
 int sk_##type##_push(STACK_OF(type) *sk,type *v); \
@@ -89,9 +89,9 @@
     { return (STACK_OF(type) *)sk_new_null(); } \
 void sk_##type##_free(STACK_OF(type) *sk) \
     { sk_free((STACK *)sk); } \
-int sk_##type##_num(STACK_OF(type) *sk) \
-    { return sk_num((STACK *)sk); } \
-type *sk_##type##_value(STACK_OF(type) *sk,int n) \
+int sk_##type##_num(const STACK_OF(type) *sk) \
+    { return sk_num((const STACK *)sk); } \
+type *sk_##type##_value(const STACK_OF(type) *sk,int n) \
     { return (type *)sk_value((STACK *)sk,n); } \
 type *sk_##type##_set(STACK_OF(type) *sk,int n,type *v) \
     { return (type *)(sk_value((STACK *)sk,n)=(char *)v); } \
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index 02f7b2f..43ce3cf 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -167,6 +167,9 @@
 	void (*ex_free)();		/* clear argp stuff */
 	} X509_EXTENSION;
 
+DECLARE_STACK_OF(X509_EXTENSION)
+DECLARE_ASN1_SET_OF(X509_EXTENSION)
+
 /* a sequence of these are used */
 typedef struct x509_attributes_st
 	{
@@ -211,7 +214,7 @@
 	X509_PUBKEY *key;
 	ASN1_BIT_STRING *issuerUID;		/* [ 1 ] optional in v2 */
 	ASN1_BIT_STRING *subjectUID;		/* [ 2 ] optional in v2 */
-	STACK /* X509_EXTENSION */ *extensions;	/* [ 3 ] optional in v3 */
+	STACK_OF(X509_EXTENSION) *extensions;	/* [ 3 ] optional in v3 */
 	} X509_CINF;
 
 typedef struct x509_st
@@ -231,7 +234,7 @@
 	{
 	ASN1_INTEGER *serialNumber;
 	ASN1_UTCTIME *revocationDate;
-	STACK /* optional X509_EXTENSION */ *extensions;
+	STACK_OF(X509_EXTENSION) /* optional */ *extensions;
 	int sequence; /* load sequence */
 	} X509_REVOKED;
 
@@ -243,7 +246,7 @@
 	ASN1_UTCTIME *lastUpdate;
 	ASN1_UTCTIME *nextUpdate;
 	STACK /* X509_REVOKED */ *revoked;
-	STACK /* [0] X509_EXTENSION */ *extensions;
+	STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
 	} X509_CRL_INFO;
 
 typedef struct X509_crl_st
@@ -810,13 +813,17 @@
 ASN1_OBJECT *	X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
 ASN1_STRING *	X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
 
-int		X509v3_get_ext_count(STACK *x);
-int		X509v3_get_ext_by_NID(STACK *x, int nid, int lastpos);
-int		X509v3_get_ext_by_OBJ(STACK *x,ASN1_OBJECT *obj,int lastpos);
-int		X509v3_get_ext_by_critical(STACK *x, int crit, int lastpos);
-X509_EXTENSION *X509v3_get_ext(STACK *x, int loc);
-X509_EXTENSION *X509v3_delete_ext(STACK *x, int loc);
-STACK *		X509v3_add_ext(STACK **x, X509_EXTENSION *ex, int loc);
+int		X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+int		X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+				      int nid, int lastpos);
+int		X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+				      ASN1_OBJECT *obj,int lastpos);
+int		X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+					   int crit, int lastpos);
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+					 X509_EXTENSION *ex, int loc);
 
 int		X509_get_ext_count(X509 *x);
 int		X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
diff --git a/crypto/x509/x509_ext.c b/crypto/x509/x509_ext.c
index 6fbab00..f8565a6 100644
--- a/crypto/x509/x509_ext.c
+++ b/crypto/x509/x509_ext.c
@@ -170,3 +170,5 @@
 	return(X509v3_add_ext(&(x->extensions),ex,loc) != NULL);
 	}
 
+IMPLEMENT_STACK_OF(X509_EXTENSION)
+IMPLEMENT_ASN1_SET_OF(X509_EXTENSION)
diff --git a/crypto/x509/x509_v3.c b/crypto/x509/x509_v3.c
index 18193c3..dd2f9f1 100644
--- a/crypto/x509/x509_v3.c
+++ b/crypto/x509/x509_v3.c
@@ -64,13 +64,14 @@
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 
-int X509v3_get_ext_count(STACK *x)
+int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
 	{
 	if (x == NULL) return(0);
-	return(sk_num(x));
+	return(sk_X509_EXTENSION_num(x));
 	}
 
-int X509v3_get_ext_by_NID(STACK *x, int nid, int lastpos)
+int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
+			  int lastpos)
 	{
 	ASN1_OBJECT *obj;
 
@@ -79,7 +80,8 @@
 	return(X509v3_get_ext_by_OBJ(x,obj,lastpos));
 	}
 
-int X509v3_get_ext_by_OBJ(STACK *sk, ASN1_OBJECT *obj, int lastpos)
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, ASN1_OBJECT *obj,
+			  int lastpos)
 	{
 	int n;
 	X509_EXTENSION *ex;
@@ -88,17 +90,18 @@
 	lastpos++;
 	if (lastpos < 0)
 		lastpos=0;
-	n=sk_num(sk);
+	n=sk_X509_EXTENSION_num(sk);
 	for ( ; lastpos < n; lastpos++)
 		{
-		ex=(X509_EXTENSION *)sk_value(sk,lastpos);
+		ex=sk_X509_EXTENSION_value(sk,lastpos);
 		if (OBJ_cmp(ex->object,obj) == 0)
 			return(lastpos);
 		}
 	return(-1);
 	}
 
-int X509v3_get_ext_by_critical(STACK *sk, int crit, int lastpos)
+int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
+			       int lastpos)
 	{
 	int n;
 	X509_EXTENSION *ex;
@@ -107,10 +110,10 @@
 	lastpos++;
 	if (lastpos < 0)
 		lastpos=0;
-	n=sk_num(sk);
+	n=sk_X509_EXTENSION_num(sk);
 	for ( ; lastpos < n; lastpos++)
 		{
-		ex=(X509_EXTENSION *)sk_value(sk,lastpos);
+		ex=sk_X509_EXTENSION_value(sk,lastpos);
 		if (	(ex->critical && crit) ||
 			(!ex->critical && !crit))
 			return(lastpos);
@@ -118,45 +121,46 @@
 	return(-1);
 	}
 
-X509_EXTENSION *X509v3_get_ext(STACK *x, int loc)
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
 	{
-	if ((x == NULL) || (sk_num(x) <= loc) || (loc < 0))
-		return(NULL);
+	if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
+		return NULL;
 	else
-		return((X509_EXTENSION *)sk_value(x,loc));
+		return sk_X509_EXTENSION_value(x,loc);
 	}
 
-X509_EXTENSION *X509v3_delete_ext(STACK *x, int loc)
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
 	{
 	X509_EXTENSION *ret;
 
-	if ((x == NULL) || (sk_num(x) <= loc) || (loc < 0))
+	if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
 		return(NULL);
-	ret=(X509_EXTENSION *)sk_delete(x,loc);
+	ret=sk_X509_EXTENSION_delete(x,loc);
 	return(ret);
 	}
 
-STACK *X509v3_add_ext(STACK **x, X509_EXTENSION *ex, int loc)
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+					 X509_EXTENSION *ex, int loc)
 	{
 	X509_EXTENSION *new_ex=NULL;
 	int n;
-	STACK *sk=NULL;
+	STACK_OF(X509_EXTENSION) *sk=NULL;
 
 	if ((x != NULL) && (*x == NULL))
 		{
-		if ((sk=sk_new_null()) == NULL)
+		if ((sk=sk_X509_EXTENSION_new_null()) == NULL)
 			goto err;
 		}
 	else
 		sk= *x;
 
-	n=sk_num(sk);
+	n=sk_X509_EXTENSION_num(sk);
 	if (loc > n) loc=n;
 	else if (loc < 0) loc=n;
 
 	if ((new_ex=X509_EXTENSION_dup(ex)) == NULL)
 		goto err2;
-	if (!sk_insert(sk,(char *)new_ex,loc))
+	if (!sk_X509_EXTENSION_insert(sk,new_ex,loc))
 		goto err;
 	if ((x != NULL) && (*x == NULL))
 		*x=sk;
@@ -165,7 +169,7 @@
 	X509err(X509_F_X509V3_ADD_EXT,ERR_R_MALLOC_FAILURE);
 err2:
 	if (new_ex != NULL) X509_EXTENSION_free(new_ex);
-	if (sk != NULL) sk_free(sk);
+	if (sk != NULL) sk_X509_EXTENSION_free(sk);
 	return(NULL);
 	}