diff --git a/CHANGES b/CHANGES
index dfe126520c..bb47022107 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,26 @@
 
  Changes between 0.9.4 and 0.9.5  [xx XXX 1999]
 
+  *) Modify the way the V3 extension code looks up extensions. This now
+     works in a similar way to the object code: we have some "standard"
+     extensions in a static table which is searched with OBJ_bsearch()
+     and the application can add dynamic ones if needed. The file
+     crypto/x509v3/ext_dat.h now has the info: this file needs to be
+     updated whenever a new extension is added to the core code and kept
+     in ext_nid order. There is a simple program 'tabtest.c' which checks
+     this. New extensions are not added too often so this file can readily
+     be maintained manually.
+
+     There are two big advantages in doing things this way. The extensions
+     can be looked up immediately and no longer need to be "added" using
+     X509V3_add_standard_extensions(): this function now does nothing.
+     [Side note: I get *lots* of email saying the extension code doesn't
+      work because people forget to call this function]
+     Also no dynamic allocation is done unless new extensions are added:
+     so if we don't add custom extensions there is no need to call
+     X509V3_EXT_cleanup().
+     [Steve Henson]
+
   *) Modify enc utility's salting as follows: make salting the default. Add a
      magic header, so unsalted files fail gracefully instead of just decrypting
      to garbage. This is because not salting is a big security hole, so people
diff --git a/apps/ca.c b/apps/ca.c
index b5c6f92b87..89a73b666f 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -279,8 +279,6 @@ EF_ALIGNMENT=0;
 	key = NULL;
 	section = NULL;
 
-	X509V3_add_standard_extensions();
-
 	preserve=0;
 	msie_hack=0;
 	if (bio_err == NULL)
@@ -1239,7 +1237,6 @@ err:
 	X509_free(x509);
 	X509_CRL_free(crl);
 	CONF_free(conf);
-	X509V3_EXT_cleanup();
 	OBJ_cleanup();
 	EXIT(ret);
 	}
diff --git a/apps/crl.c b/apps/crl.c
index 9bab031c81..c73b35db74 100644
--- a/apps/crl.c
+++ b/apps/crl.c
@@ -200,7 +200,6 @@ bad:
 		}
 
 	ERR_load_crypto_strings();
-	X509V3_add_standard_extensions();
 	x=load_crl(infile,informat);
 	if (x == NULL) { goto end; }
 
@@ -318,7 +317,6 @@ end:
 		X509_STORE_CTX_cleanup(&ctx);
 		X509_STORE_free(store);
 	}
-	X509V3_EXT_cleanup();
 	EXIT(ret);
 	}
 
diff --git a/apps/req.c b/apps/req.c
index 59a38982b9..1c063ee3af 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -365,7 +365,6 @@ bad:
 		}
 
 	ERR_load_crypto_strings();
-	X509V3_add_standard_extensions();
 
 #ifndef MONOLITH
 	/* Lets load up our environment a little */
@@ -843,7 +842,6 @@ end:
 	EVP_PKEY_free(pkey);
 	X509_REQ_free(req);
 	X509_free(x509ss);
-	X509V3_EXT_cleanup();
 	OBJ_cleanup();
 	ASN1_STRING_TABLE_cleanup();
 #ifndef NO_DSA
diff --git a/crypto/x509v3/ext_dat.h b/crypto/x509v3/ext_dat.h
new file mode 100644
index 0000000000..c81f9a18b0
--- /dev/null
+++ b/crypto/x509v3/ext_dat.h
@@ -0,0 +1,97 @@
+/* ext_dat.h */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* This file contains a table of "standard" extensions */
+
+extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
+extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info;
+extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
+extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_cpols, v3_crld;
+
+/* This table will be searched using OBJ_bsearch so it *must* kept in
+ * order of the ext_nid values.
+ */
+
+static X509V3_EXT_METHOD *standard_exts[] = {
+&v3_nscert,
+&v3_ns_ia5_list[0],
+&v3_ns_ia5_list[1],
+&v3_ns_ia5_list[2],
+&v3_ns_ia5_list[3],
+&v3_ns_ia5_list[4],
+&v3_ns_ia5_list[5],
+&v3_ns_ia5_list[6],
+&v3_skey_id,
+&v3_key_usage,
+&v3_pkey_usage_period,
+&v3_alt[0],
+&v3_alt[1],
+&v3_bcons,
+&v3_crl_num,
+&v3_cpols,
+&v3_akey_id,
+&v3_crld,
+&v3_ext_ku,
+&v3_crl_reason,
+&v3_sxnet,
+&v3_info,
+};
+
+/* Number of standard extensions: keep up to date */
+
+#define STANDARD_EXTENSION_COUNT 22
+
diff --git a/crypto/x509v3/tabtest.c b/crypto/x509v3/tabtest.c
new file mode 100644
index 0000000000..dad0d38dd5
--- /dev/null
+++ b/crypto/x509v3/tabtest.c
@@ -0,0 +1,88 @@
+/* tabtest.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Simple program to check the ext_dat.h is correct and print out
+ * problems if it is not.
+ */
+
+#include <stdio.h>
+
+#include <openssl/x509v3.h>
+
+#include "ext_dat.h"
+
+main()
+{
+	int i, prev = -1, bad = 0;
+	X509V3_EXT_METHOD **tmp;
+	i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
+	if(i != STANDARD_EXTENSION_COUNT)
+		fprintf(stderr, "Extension number invalid expecting %d\n", i);
+	tmp = standard_exts;
+	for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
+		if((*tmp)->ext_nid < prev) bad = 1;
+		prev = (*tmp)->ext_nid;
+		
+	}
+	if(bad) {
+		tmp = standard_exts;
+		fprintf(stderr, "Extensions out of order!\n");
+		for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
+		printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
+	} else fprintf(stderr, "Order OK\n");
+}
diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c
index a530be2165..5ccd1e0e3d 100644
--- a/crypto/x509v3/v3_alt.c
+++ b/crypto/x509v3/v3_alt.c
@@ -84,7 +84,6 @@ NULL, NULL,
 (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
 (X509V3_EXT_V2I)v2i_issuer_alt,
 NULL, NULL, NULL},
-EXT_END
 };
 
 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509v3/v3_lib.c
index d6aeaabccd..1ed79e48e2 100644
--- a/crypto/x509v3/v3_lib.c
+++ b/crypto/x509v3/v3_lib.c
@@ -62,6 +62,8 @@
 #include <openssl/conf.h>
 #include <openssl/x509v3.h>
 
+#include "ext_dat.h"
+
 static STACK *ext_list = NULL;
 
 static int ext_cmp(X509V3_EXT_METHOD **a, X509V3_EXT_METHOD **b);
@@ -87,10 +89,15 @@ static int ext_cmp(X509V3_EXT_METHOD **a, X509V3_EXT_METHOD **b)
 
 X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
 {
-	X509V3_EXT_METHOD tmp;
+	X509V3_EXT_METHOD tmp, *t = &tmp, **ret;
 	int idx;
+	if(nid < 0) return NULL;
 	tmp.ext_nid = nid;
-	if(!ext_list || (tmp.ext_nid < 0) ) return NULL;
+	ret = (X509V3_EXT_METHOD **) OBJ_bsearch((char *)&t,
+			(char *)standard_exts, STANDARD_EXTENSION_COUNT,
+			sizeof(X509V3_EXT_METHOD *), (int (*)())ext_cmp);
+	if(ret) return *ret;
+	if(!ext_list) return NULL;
 	idx = sk_find(ext_list, (char *)&tmp);
 	if(idx == -1) return NULL;
 	return (X509V3_EXT_METHOD *)sk_value(ext_list, idx);
@@ -128,13 +135,10 @@ int X509V3_EXT_add_alias(int nid_to, int nid_from)
 	return 1;
 }
 
-static int added_exts = 0;
-
 void X509V3_EXT_cleanup(void)
 {
 	sk_pop_free(ext_list, ext_list_free);
 	ext_list = NULL;
-	added_exts = 0;
 }
 
 static void ext_list_free(X509V3_EXT_METHOD *ext)
@@ -142,31 +146,12 @@ static void ext_list_free(X509V3_EXT_METHOD *ext)
 	if(ext->ext_flags & X509V3_EXT_DYNAMIC) Free(ext);
 }
 
-extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
-extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info;
-extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
-
-extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_cpols, v3_crld;
+/* Legacy function: we don't need to add standard extensions
+ * any more because they are now kept in ext_dat.h.
+ */
 
 int X509V3_add_standard_extensions(void)
 {
-	if(added_exts) return 1;
-	X509V3_EXT_add_list(v3_ns_ia5_list);
-	X509V3_EXT_add_list(v3_alt);
-	X509V3_EXT_add(&v3_bcons);
-	X509V3_EXT_add(&v3_nscert);
-	X509V3_EXT_add(&v3_key_usage);
-	X509V3_EXT_add(&v3_ext_ku);
-	X509V3_EXT_add(&v3_skey_id);
-	X509V3_EXT_add(&v3_akey_id);
-	X509V3_EXT_add(&v3_pkey_usage_period);
-	X509V3_EXT_add(&v3_crl_num);
-	X509V3_EXT_add(&v3_sxnet);
-	X509V3_EXT_add(&v3_info);
-	X509V3_EXT_add(&v3_crl_reason);
-	X509V3_EXT_add(&v3_cpols);
-	X509V3_EXT_add(&v3_crld);
-	added_exts = 1;
 	return 1;
 }