More extension code. Incomplete support for subject and issuer alt
authorDr. Stephen Henson <steve@openssl.org>
Wed, 10 Feb 1999 01:12:59 +0000 (01:12 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 10 Feb 1999 01:12:59 +0000 (01:12 +0000)
name, issuer and authority key id. Change the i2v function parameters
and add an extra 'crl' parameter in the X509V3_CTX structure: guess
what that's for :-) Fix to ASN1 macro which messed up
IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED.

21 files changed:
CHANGES
apps/ca.c
apps/openssl.cnf
apps/req.c
crypto/asn1/Makefile.ssl
crypto/asn1/f_enum.c [new file with mode: 0644]
crypto/x509v3/Makefile.ssl
crypto/x509v3/v3_akey.c [new file with mode: 0644]
crypto/x509v3/v3_alt.c
crypto/x509v3/v3_bcons.c
crypto/x509v3/v3_bitst.c
crypto/x509v3/v3_conf.c
crypto/x509v3/v3_extku.c
crypto/x509v3/v3_lib.c
crypto/x509v3/v3_prn.c
crypto/x509v3/v3_skey.c [new file with mode: 0644]
crypto/x509v3/v3_utl.c
crypto/x509v3/v3err.c
crypto/x509v3/v3prin.c
crypto/x509v3/x509v3.err
crypto/x509v3/x509v3.h

diff --git a/CHANGES b/CHANGES
index 1564978..b4e9104 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,13 @@
 
  Changes between 0.9.1c and 0.9.2
 
+  *) More extension code. Incomplete support for subject and issuer alt
+     name, issuer and authority key id. Change the i2v function parameters
+     and add an extra 'crl' parameter in the X509V3_CTX structure: guess
+     what that's for :-) Fix to ASN1 macro which messed up
+     IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED.
+     [Steve Henson]
+
   *) Preliminary support for ENUMERATED type. This is largely copied from the
      INTEGER code.
      [Steve Henson]
index 07ef9eb..25e025d 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -690,9 +690,8 @@ bad:
 
                extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
                if(extensions) {
-
                        /* Check syntax of file */
-                       if(!X509V3_EXT_add_conf(conf, NULL, extensions, NULL)) {
+                       if(!X509V3_EXT_check_conf(conf, extensions)) {
                                BIO_printf(bio_err,
                                 "Error Loading extension section %s\n",
                                                                 extensions);
@@ -1669,6 +1668,7 @@ again2:
        /* Lets add the extensions, if there are any */
        if (ext_sect)
                {
+               X509V3_CTX ctx;
                if (ci->version == NULL)
                        if ((ci->version=ASN1_INTEGER_new()) == NULL)
                                goto err;
@@ -1681,7 +1681,13 @@ again2:
 
                ci->extensions = NULL;
 
-               if(!X509V3_EXT_add_conf(conf, NULL, ext_sect, ret)) goto err;
+               ctx.subject_cert = ret;
+               ctx.issuer_cert = x509;
+               ctx.subject_req = req;
+               ctx.crl = NULL;
+               ctx.flags = 0;
+
+               if(!X509V3_EXT_add_conf(conf, &ctx, ext_sect, ret)) goto err;
 
                }
 
index 27abc08..81dee57 100644 (file)
@@ -127,6 +127,7 @@ basicConstraints=CA:FALSE
 keyUsage = nonRepudiation, digitalSignature, keyEncipherment
 
 nsComment                      = "OpenSSL Generated Certificate"
+subjectKeyIdentifier=hash
 
 #nsCaRevocationUrl             = http://www.domain.dom/ca-crl.pem
 #nsBaseUrl
@@ -142,6 +143,10 @@ nsComment                  = "OpenSSL Generated Certificate"
 # It's a CA certificate
 basicConstraints = CA:true
 
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
 # This is what PKIX recommends but some broken software chokes on critical
 # extensions.
 #basicConstraints = critical,CA:true
index 3407cd0..b2c1bb2 100644 (file)
@@ -657,6 +657,8 @@ loop:
                        ext_ctx.issuer_cert = x509ss;
                        ext_ctx.subject_cert = x509ss;
                        ext_ctx.subject_req = NULL;
+                       ext_ctx.crl = NULL;
+                       ext_ctx.flags = 0;
 
                        /* Add extensions */
                        if(extensions && !X509V3_EXT_add_conf(req_conf, 
index 3cd2102..1c1ab3a 100644 (file)
@@ -34,7 +34,7 @@ LIBSRC=       a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
        p7_i_s.c p7_signi.c p7_signd.c p7_recip.c p7_enc_c.c p7_evp.c \
        p7_dgst.c p7_s_e.c p7_enc.c p7_lib.c \
        f_int.c f_string.c i2d_dhp.c i2d_dsap.c d2i_dhp.c d2i_dsap.c n_pkey.c \
-       a_hdr.c x_pkey.c a_bool.c x_exten.c \
+       f_enum.c a_hdr.c x_pkey.c a_bool.c x_exten.c \
        asn1_par.c asn1_lib.c $(ERRC).c a_meth.c a_bytes.c \
        evp_asn1.c
 LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
@@ -49,7 +49,7 @@ LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
        p7_i_s.o p7_signi.o p7_signd.o p7_recip.o p7_enc_c.o p7_evp.o \
        p7_dgst.o p7_s_e.o p7_enc.o p7_lib.o \
        f_int.o f_string.o i2d_dhp.o i2d_dsap.o d2i_dhp.o d2i_dsap.o n_pkey.o \
-       a_hdr.o x_pkey.o a_bool.o x_exten.o \
+       f_enum.o a_hdr.o x_pkey.o a_bool.o x_exten.o \
        asn1_par.o asn1_lib.o $(ERRC).o a_meth.o a_bytes.o \
        evp_asn1.o
 
diff --git a/crypto/asn1/f_enum.c b/crypto/asn1/f_enum.c
new file mode 100644 (file)
index 0000000..13b06f5
--- /dev/null
@@ -0,0 +1,213 @@
+/* crypto/asn1/f_enum.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "buffer.h"
+#include "x509.h"
+
+/* Based on a_int.c: equivalent ENUMERATED functions */
+
+int i2a_ASN1_ENUMERATED(bp, a)
+BIO *bp;
+ASN1_ENUMERATED *a;
+       {
+       int i,n=0;
+       static char *h="0123456789ABCDEF";
+       char buf[2];
+
+       if (a == NULL) return(0);
+
+       if (a->length == 0)
+               {
+               if (BIO_write(bp,"00",2) != 2) goto err;
+               n=2;
+               }
+       else
+               {
+               for (i=0; i<a->length; i++)
+                       {
+                       if ((i != 0) && (i%35 == 0))
+                               {
+                               if (BIO_write(bp,"\\\n",2) != 2) goto err;
+                               n+=2;
+                               }
+                       buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
+                       buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
+                       if (BIO_write(bp,buf,2) != 2) goto err;
+                       n+=2;
+                       }
+               }
+       return(n);
+err:
+       return(-1);
+       }
+
+int a2i_ASN1_ENUMERATED(bp,bs,buf,size)
+BIO *bp;
+ASN1_ENUMERATED *bs;
+char *buf;
+int size;
+       {
+       int ret=0;
+       int i,j,k,m,n,again,bufsize;
+       unsigned char *s=NULL,*sp;
+       unsigned char *bufp;
+       int num=0,slen=0,first=1;
+
+       bs->type=V_ASN1_ENUMERATED;
+
+       bufsize=BIO_gets(bp,buf,size);
+       for (;;)
+               {
+               if (bufsize < 1) goto err_sl;
+               i=bufsize;
+               if (buf[i-1] == '\n') buf[--i]='\0';
+               if (i == 0) goto err_sl;
+               if (buf[i-1] == '\r') buf[--i]='\0';
+               if (i == 0) goto err_sl;
+               again=(buf[i-1] == '\\');
+
+               for (j=0; j<i; j++)
+                       {
+                       if (!(  ((buf[j] >= '0') && (buf[j] <= '9')) ||
+                               ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+                               ((buf[j] >= 'A') && (buf[j] <= 'F'))))
+                               {
+                               i=j;
+                               break;
+                               }
+                       }
+               buf[i]='\0';
+               /* We have now cleared all the crap off the end of the
+                * line */
+               if (i < 2) goto err_sl;
+
+               bufp=(unsigned char *)buf;
+               if (first)
+                       {
+                       first=0;
+                       if ((bufp[0] == '0') && (buf[1] == '0'))
+                               {
+                               bufp+=2;
+                               i-=2;
+                               }
+                       }
+               k=0;
+               i-=again;
+               if (i%2 != 0)
+                       {
+                       ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_ODD_NUMBER_OF_CHARS);
+                       goto err;
+                       }
+               i/=2;
+               if (num+i > slen)
+                       {
+                       if (s == NULL)
+                               sp=(unsigned char *)Malloc(
+                                       (unsigned int)num+i*2);
+                       else
+                               sp=(unsigned char *)Realloc(s,
+                                       (unsigned int)num+i*2);
+                       if (sp == NULL)
+                               {
+                               ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
+                               if (s != NULL) Free((char *)s);
+                               goto err;
+                               }
+                       s=sp;
+                       slen=num+i*2;
+                       }
+               for (j=0; j<i; j++,k+=2)
+                       {
+                       for (n=0; n<2; n++)
+                               {
+                               m=bufp[k+n];
+                               if ((m >= '0') && (m <= '9'))
+                                       m-='0';
+                               else if ((m >= 'a') && (m <= 'f'))
+                                       m=m-'a'+10;
+                               else if ((m >= 'A') && (m <= 'F'))
+                                       m=m-'A'+10;
+                               else
+                                       {
+                                       ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_NON_HEX_CHARACTERS);
+                                       goto err;
+                                       }
+                               s[num+j]<<=4;
+                               s[num+j]|=m;
+                               }
+                       }
+               num+=i;
+               if (again)
+                       bufsize=BIO_gets(bp,buf,size);
+               else
+                       break;
+               }
+       bs->length=num;
+       bs->data=s;
+       ret=1;
+err:
+       if (0)
+               {
+err_sl:
+               ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_SHORT_LINE);
+               }
+       return(ret);
+       }
+
index 8675328..6e80ca8 100644 (file)
@@ -23,9 +23,9 @@ APPS=
 
 LIB=$(TOP)/libcrypto.a
 LIBSRC=        v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c \
-v3_lib.c v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c
+v3_lib.c v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.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_prn.o v3_utl.o v3err.o v3_genn.o v3_alt.o v3_skey.o v3_akey.o
 
 SRC= $(LIBSRC)
 
diff --git a/crypto/x509v3/v3_akey.c b/crypto/x509v3/v3_akey.c
new file mode 100644 (file)
index 0000000..e3b8460
--- /dev/null
@@ -0,0 +1,185 @@
+/* v3_akey.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).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pem.h>
+#include <asn1_mac.h>
+#include <err.h>
+#include <objects.h>
+#include <conf.h>
+#include "x509v3.h"
+
+#ifndef NOPROTO
+static STACK *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, AUTHORITY_KEYID *akeyid, STACK *extlist);
+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *values);
+
+#else
+
+static STACK *i2v_AUTHORITY_KEYID();
+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID();
+
+#endif
+
+X509V3_EXT_METHOD v3_akey_id = {
+NID_authority_key_identifier, 0,
+(X509V3_EXT_NEW)AUTHORITY_KEYID_new,
+AUTHORITY_KEYID_free,
+(X509V3_EXT_D2I)d2i_AUTHORITY_KEYID,
+i2d_AUTHORITY_KEYID,
+NULL, NULL,
+(X509V3_EXT_I2V)i2v_AUTHORITY_KEYID,
+(X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
+NULL,
+NULL
+};
+
+
+/*
+ * ASN1err(ASN1_F_AUTHORITY_KEYID_NEW,ERR_R_MALLOC_FAILURE);
+ * ASN1err(ASN1_F_D2I_AUTHORITY_KEYID,ERR_R_MALLOC_FAILURE);
+ */
+
+int i2d_AUTHORITY_KEYID(a,pp)
+AUTHORITY_KEYID *a;
+unsigned char **pp;
+{
+       M_ASN1_I2D_vars(a);
+
+       M_ASN1_I2D_len_IMP_opt (a->keyid, i2d_ASN1_OCTET_STRING);
+       M_ASN1_I2D_len_IMP_opt (a->issuer, i2d_GENERAL_NAMES);
+       M_ASN1_I2D_len_IMP_opt (a->serial, i2d_ASN1_INTEGER);
+
+       M_ASN1_I2D_seq_total();
+
+       M_ASN1_I2D_put_IMP_opt (a->keyid, i2d_ASN1_OCTET_STRING, 0);
+       M_ASN1_I2D_put_IMP_opt (a->issuer, i2d_GENERAL_NAMES, 1);
+       M_ASN1_I2D_put_IMP_opt (a->serial, i2d_ASN1_INTEGER, 2);
+
+       M_ASN1_I2D_finish();
+}
+
+AUTHORITY_KEYID *AUTHORITY_KEYID_new()
+{
+       AUTHORITY_KEYID *ret=NULL;
+       ASN1_CTX c;
+       M_ASN1_New_Malloc(ret, AUTHORITY_KEYID);
+       ret->keyid = NULL;
+       ret->issuer = NULL;
+       ret->serial = NULL;
+       return (ret);
+       M_ASN1_New_Error(ASN1_F_AUTHORITY_KEYID_NEW);
+}
+
+AUTHORITY_KEYID *d2i_AUTHORITY_KEYID(a,pp,length)
+AUTHORITY_KEYID **a;
+unsigned char **pp;
+long length;
+{
+       M_ASN1_D2I_vars(a,AUTHORITY_KEYID *,AUTHORITY_KEYID_new);
+       M_ASN1_D2I_Init();
+       M_ASN1_D2I_start_sequence();
+       M_ASN1_D2I_get_IMP_opt (ret->keyid, d2i_ASN1_OCTET_STRING, 0,
+                                                       V_ASN1_OCTET_STRING);
+       M_ASN1_D2I_get_IMP_opt (ret->issuer, d2i_GENERAL_NAMES, 1,
+                                                       V_ASN1_SEQUENCE);
+       M_ASN1_D2I_get_IMP_opt (ret->serial, d2i_ASN1_INTEGER, 2,
+                                                       V_ASN1_INTEGER);
+       M_ASN1_D2I_Finish(a, AUTHORITY_KEYID_free, ASN1_F_D2I_AUTHORITY_KEYID);
+}
+
+void AUTHORITY_KEYID_free(a)
+AUTHORITY_KEYID *a;
+{
+       if (a == NULL) return;
+       ASN1_OCTET_STRING_free(a->keyid);
+       sk_pop_free(a->issuer, GENERAL_NAME_free);
+       ASN1_INTEGER_free (a->serial);
+       Free ((char *)a);
+}
+
+static STACK *i2v_AUTHORITY_KEYID(method, akeyid, extlist)
+X509V3_EXT_METHOD *method;
+AUTHORITY_KEYID *akeyid;
+STACK *extlist;
+{
+       char *tmp;
+       if(akeyid->keyid) {
+               tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
+               X509V3_add_value("keyid", tmp, &extlist);
+               Free(tmp);
+       }
+       if(akeyid->issuer) 
+               extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
+       if(akeyid->serial) {
+               tmp = hex_to_string(akeyid->serial->data,
+                                                akeyid->serial->length);
+               X509V3_add_value("serial", tmp, &extlist);
+               Free(tmp);
+       }
+       return extlist;
+}
+
+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(method, ctx, values)
+X509V3_EXT_METHOD *method;
+X509V3_CTX *ctx;
+STACK *values;
+{
+return NULL;
+}
+
index 62d895d..4347c76 100644 (file)
 #include <conf.h>
 #include "x509v3.h"
 
-#ifndef NOPROTO
-static STACK *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, STACK *gen);
-/*static STACK *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *values);*/
-#endif
-
 X509V3_EXT_METHOD v3_alt[] = {
 { NID_subject_alt_name, 0,
 (X509V3_EXT_NEW)GENERAL_NAMES_new,
@@ -92,13 +87,14 @@ NULL, NULL},
 EXT_END
 };
 
-static STACK *i2v_GENERAL_NAMES(method, gens)
+STACK *i2v_GENERAL_NAMES(method, gens, ret)
 X509V3_EXT_METHOD *method;
 STACK *gens;
+STACK *ret;
 {
        int i;
-       STACK *ret = NULL;
        GENERAL_NAME *gen;
+       char oline[256];
        for(i = 0; i < sk_num(gens); i++) {
                gen = (GENERAL_NAME *)sk_value(gens, i);
                switch (gen->type)
@@ -127,6 +123,11 @@ STACK *gens;
                X509V3_add_value("URI",gen->d.ia5->data, &ret);
                 break;
 
+                case GEN_DIRNAME:
+               X509_NAME_oneline(gen->d.dirn, oline, 256);
+               X509V3_add_value("DirName",oline, &ret);
+                break;
+
                 case GEN_IPADD:
                X509V3_add_value("IP Address","<unsupported>", &ret);
                 break;
index f7ad3e8..87e5d00 100644 (file)
@@ -66,7 +66,7 @@
 #include "x509v3.h"
 
 #ifndef NOPROTO
-static STACK *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons);
+static STACK *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, STACK *extlist);
 static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *values);
 
 #else
@@ -145,11 +145,11 @@ BASIC_CONSTRAINTS *a;
        Free ((char *)a);
 }
 
-static STACK *i2v_BASIC_CONSTRAINTS(method, bcons)
+static STACK *i2v_BASIC_CONSTRAINTS(method, bcons, extlist)
 X509V3_EXT_METHOD *method;
 BASIC_CONSTRAINTS *bcons;
+STACK *extlist;
 {
-       STACK *extlist = NULL;
        X509V3_add_value_bool("CA", bcons->ca, &extlist);
        X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
        return extlist;
index 10ce8f0..3e5d0d9 100644 (file)
@@ -68,7 +68,7 @@
 #ifndef NOPROTO
 static ASN1_BIT_STRING *asn1_bit_string_new(void);
 static ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *nval);
-static STACK *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, ASN1_BIT_STRING *bits);
+static STACK *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, ASN1_BIT_STRING *bits, STACK *extlist);
 #else
 static ASN1_BIT_STRING *asn1_bit_string_new();
 static ASN1_BIT_STRING *v2i_ASN1_BIT_STRING();
@@ -110,12 +110,12 @@ static ASN1_BIT_STRING *asn1_bit_string_new()
        return ASN1_BIT_STRING_new();
 }
 
-static STACK *i2v_ASN1_BIT_STRING(method, bits)
+static STACK *i2v_ASN1_BIT_STRING(method, bits, ret)
 X509V3_EXT_METHOD *method;
 ASN1_BIT_STRING *bits;
+STACK *ret;
 {
        BIT_STRING_BITNAME *bnam;
-       STACK *ret = NULL;
        for(bnam =(BIT_STRING_BITNAME *)method->usr_data; bnam->lname; bnam++) {
                if(ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) 
                        X509V3_add_value(bnam->lname, NULL, &ret);
index afe2ae2..b97e793 100644 (file)
@@ -163,3 +163,11 @@ X509 *cert;
        return 1;
 }
 
+/* Just check syntax of config file as far as possible */
+int X509V3_EXT_check_conf(conf, section)
+LHASH *conf;
+char *section;
+{
+       static X509V3_CTX ctx_tst = { CTX_TEST, NULL, NULL, NULL, NULL };
+       return X509V3_EXT_add_conf(conf, &ctx_tst, section, NULL);
+}
index 8f22385..1c2d93f 100644 (file)
@@ -67,7 +67,7 @@
 
 #ifndef NOPROTO
 static STACK *v2i_ext_ku(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *nval);
-static STACK *i2v_ext_ku(X509V3_EXT_METHOD *method, STACK *eku);
+static STACK *i2v_ext_ku(X509V3_EXT_METHOD *method, STACK *eku, STACK *extlist);
 #else
 static STACK *v2i_ext_ku();
 static STACK *i2v_ext_ku();
@@ -117,14 +117,14 @@ long length;
 
 
 
-static STACK *i2v_ext_ku(method, eku)
+static STACK *i2v_ext_ku(method, eku, ext_list)
 X509V3_EXT_METHOD *method;
 STACK  *eku;
+STACK *ext_list;
 {
 int i;
 ASN1_OBJECT *obj;
 char obj_tmp[80];
-STACK *ext_list = NULL;
 for(i = 0; i < sk_num(eku); i++) {
        obj = (ASN1_OBJECT *)sk_value(eku, i);
        i2t_ASN1_OBJECT(obj_tmp, 80, obj);
index 1359fa3..3fb21fb 100644 (file)
@@ -108,7 +108,6 @@ X509_EXTENSION *ext;
        return X509V3_EXT_get_nid(nid);
 }
 
-extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku, v3_ns_ia5_list[],v3_alt[];
 
 int X509V3_EXT_add_list(extlist)
 X509V3_EXT_METHOD *extlist;
@@ -132,7 +131,7 @@ int nid_to, nid_from;
        }
        *tmpext = *ext;
        tmpext->ext_nid = nid_to;
-       tmpext->ext_flags = X509V3_EXT_DYNAMIC;
+       tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
        return 1;
 }
 
@@ -147,6 +146,9 @@ 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_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
+
 int X509V3_add_standard_extensions()
 {
        X509V3_EXT_add_list(v3_ns_ia5_list);
@@ -155,5 +157,7 @@ int X509V3_add_standard_extensions()
        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);
        return 1;
 }
index c975558..7da7056 100644 (file)
@@ -104,7 +104,7 @@ int flag;
                }
                BIO_printf(out, value);
        } else if(method->i2v) {
-               if(!(nval = method->i2v(method, ext_str))) {
+               if(!(nval = method->i2v(method, ext_str, NULL))) {
                        ok = 0;
                        goto err;
                }
diff --git a/crypto/x509v3/v3_skey.c b/crypto/x509v3/v3_skey.c
new file mode 100644 (file)
index 0000000..3994c79
--- /dev/null
@@ -0,0 +1,171 @@
+/* v3_skey.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).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <pem.h>
+#include <asn1_mac.h>
+#include <err.h>
+#include <objects.h>
+#include <conf.h>
+#include "x509v3.h"
+
+#ifndef NOPROTO
+static ASN1_OCTET_STRING *octet_string_new(void);
+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
+#else
+static ASN1_OCTET_STRING *s2i_skey_id();
+static ASN1_OCTET_STRING *octet_string_new();
+#endif
+
+X509V3_EXT_METHOD v3_skey_id = { 
+NID_subject_key_identifier, 0,
+(X509V3_EXT_NEW)octet_string_new, ASN1_STRING_free,
+(X509V3_EXT_D2I)d2i_ASN1_OCTET_STRING,
+i2d_ASN1_OCTET_STRING,
+(X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
+(X509V3_EXT_S2I)s2i_skey_id,
+NULL, NULL, NULL, NULL};
+
+
+static ASN1_OCTET_STRING *octet_string_new(void)
+{
+       return ASN1_OCTET_STRING_new();
+}
+
+char *i2s_ASN1_OCTET_STRING(method, oct)
+X509V3_EXT_METHOD *method;
+ASN1_OCTET_STRING *oct;
+{
+       return hex_to_string(oct->data, oct->length);
+}
+
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(method, ctx, str)
+X509V3_EXT_METHOD *method;
+X509V3_CTX *ctx;
+char *str;
+{
+       ASN1_OCTET_STRING *oct;
+       long length;
+
+       if(!(oct = ASN1_OCTET_STRING_new())) {
+               X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
+               return NULL;
+       }
+
+       if(!(oct->data = string_to_hex(str, &length))) {
+               ASN1_OCTET_STRING_free(oct);
+               return NULL;
+       }
+
+       oct->length = length;
+
+       return oct;
+
+}
+
+ASN1_OCTET_STRING *s2i_skey_id(method, ctx, str)
+X509V3_EXT_METHOD *method;
+X509V3_CTX *ctx;
+char *str;
+{
+       ASN1_OCTET_STRING *oct;
+       ASN1_BIT_STRING *pk;
+       unsigned char pkey_dig[EVP_MAX_MD_SIZE];
+       EVP_MD_CTX md;
+       int diglen;
+
+       if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
+
+       if(!(oct = ASN1_OCTET_STRING_new())) {
+               X509V3err(X509V3_F_S2I_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
+               return NULL;
+       }
+
+       if(ctx && (ctx->flags == CTX_TEST)) return oct;
+
+       if(!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
+               X509V3err(X509V3_F_S2I_ASN1_SKEY_ID,X509V3_R_NO_PUBLIC_KEY);
+               goto err;
+       }
+
+       if(ctx->subject_req) 
+               pk = ctx->subject_req->req_info->pubkey->public_key;
+       else pk = ctx->subject_cert->cert_info->key->public_key;
+
+       if(!pk) {
+               X509V3err(X509V3_F_S2I_ASN1_SKEY_ID,X509V3_R_NO_PUBLIC_KEY);
+               goto err;
+       }
+
+       EVP_DigestInit(&md, EVP_sha1());
+       EVP_DigestUpdate(&md, pk->data, pk->length);
+       EVP_DigestFinal(&md, pkey_dig, &diglen);
+
+       if(!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
+               X509V3err(X509V3_F_S2I_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
+               goto err;
+       }
+
+       return oct;
+       
+       err:
+       ASN1_OCTET_STRING_free(oct);
+       return NULL;
+}
index a9068a2..2c3a891 100644 (file)
@@ -310,3 +310,86 @@ char *name;
        if(!*p) return NULL;
        return p;
 }
+
+/* hex string utilities */
+
+/* Given a buffer of length 'len' return a Malloc'ed string with its
+ * hex representation
+ */
+
+char *hex_to_string(buffer, len)
+unsigned char *buffer;
+long len;
+{
+       char *tmp, *q;
+       unsigned char *p;
+       int i;
+       static char hexdig[] = "0123456789ABCDEF";
+       if(!buffer || !len) return NULL;
+       if(!(tmp = Malloc(len * 3 + 1))) {
+               X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE);
+               return NULL;
+       }
+       q = tmp;
+       for(i = 0, p = buffer; i < len; i++,p++) {
+               *q++ = hexdig[(*p >> 4) & 0xf];
+               *q++ = hexdig[*p & 0xf];
+               *q++ = ':';
+       }
+       q[-1] = 0;
+       return tmp;
+}
+
+/* Give a string of hex digits convert to
+ * a buffer
+ */
+
+unsigned char *string_to_hex(str, len)
+char *str;
+long *len;
+{
+       unsigned char *hexbuf, *q;
+       unsigned char ch, cl, *p;
+       if(!str) {
+               X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_INVALID_NULL_ARGUMENT);
+               return NULL;
+       }
+       if(!(hexbuf = Malloc(strlen(str) >> 1))) goto err;
+       for(p = (unsigned char *)str, q = hexbuf; *p;) {
+               ch = *p++;
+               if(ch == ':') continue;
+               cl = *p++;
+               if(!cl) {
+                       X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ODD_NUMBER_OF_DIGITS);
+                       Free(hexbuf);
+                       return NULL;
+               }
+               if(isupper(ch)) ch = tolower(ch);
+               if(isupper(cl)) cl = tolower(cl);
+
+               if((ch >= '0') && (ch <= '9')) ch -= '0';
+               else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10;
+               else goto badhex;
+
+               if((cl >= '0') && (cl <= '9')) cl -= '0';
+               else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10;
+               else goto badhex;
+
+               *q++ = (ch << 4) | cl;
+       }
+
+       if(len) *len = q - hexbuf;
+
+       return hexbuf;
+
+       err:
+       if(hexbuf) Free(hexbuf);
+       X509V3err(X509V3_F_STRING_TO_HEX,ERR_R_MALLOC_FAILURE);
+       return NULL;
+
+       badhex:
+       Free(hexbuf);
+       X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ILLEGAL_HEX_DIGIT);
+       return NULL;
+
+}
index b250953..3acf849 100644 (file)
 #ifndef NO_ERR
 static ERR_STRING_DATA X509V3_str_functs[]=
        {
+{ERR_PACK(0,X509V3_F_HEX_TO_STRING,0), "hex_to_string"},
 {ERR_PACK(0,X509V3_F_S2I_ASN1_IA5STRING,0),    "S2I_ASN1_IA5STRING"},
+{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_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"},
 {ERR_PACK(0,X509V3_F_V2I_EXT_KU,0),    "V2I_EXT_KU"},
 {ERR_PACK(0,X509V3_F_X509V3_ADD_EXT,0),        "X509V3_ADD_EXT"},
@@ -83,6 +89,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
 {X509V3_R_BN_TO_ASN1_INTEGER_ERROR       ,"bn to asn1 integer error"},
 {X509V3_R_EXTENSION_NOT_FOUND            ,"extension not found"},
 {X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED,"extension setting not supported"},
+{X509V3_R_ILLEGAL_HEX_DIGIT              ,"illegal hex digit"},
 {X509V3_R_INVALID_BOOLEAN_STRING         ,"invalid boolean string"},
 {X509V3_R_INVALID_EXTENSION_STRING       ,"invalid extension string"},
 {X509V3_R_INVALID_NAME                   ,"invalid name"},
@@ -90,6 +97,8 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
 {X509V3_R_INVALID_NULL_NAME              ,"invalid null name"},
 {X509V3_R_INVALID_NULL_VALUE             ,"invalid null value"},
 {X509V3_R_INVALID_OBJECT_IDENTIFIER      ,"invalid object identifier"},
+{X509V3_R_NO_PUBLIC_KEY                  ,"no public key"},
+{X509V3_R_ODD_NUMBER_OF_DIGITS           ,"odd number of digits"},
 {X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT    ,"unknown bit string argument"},
 {0,NULL},
        };
index 6475fb9..75e0cfb 100644 (file)
@@ -70,6 +70,7 @@ char **argv;
        int i, count;
        X509_EXTENSION *ext;
        X509V3_add_standard_extensions();
+       ERR_load_crypto_strings();
        if(!argv[1]) {
                fprintf(stderr, "Usage v3prin cert.pem\n");
                exit(1);
@@ -89,7 +90,7 @@ char **argv;
        for(i = 0; i < count; i++) {
                ext = X509_get_ext(cert, i);
                printf("%s\n", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
-               X509V3_EXT_print_fp(stdout, ext, 0);
+               if(!X509V3_EXT_print_fp(stdout, ext, 0)) ERR_print_errors_fp(stderr);
                printf("\n");
                
        }
index 8e58d44..52b95b8 100644 (file)
@@ -1,8 +1,14 @@
 /* Error codes for the X509V3 functions. */
 
 /* Function codes. */
+#define X509V3_F_HEX_TO_STRING                          111
 #define X509V3_F_S2I_ASN1_IA5STRING                     100
+#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_V2I_ASN1_BIT_STRING                    101
+#define X509V3_F_V2I_AUTHORITY_KEYID                    116
 #define X509V3_F_V2I_BASIC_CONSTRAINTS                  102
 #define X509V3_F_V2I_EXT_KU                             103
 #define X509V3_F_X509V3_ADD_EXT                                 104
@@ -18,6 +24,7 @@
 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR               101
 #define X509V3_R_EXTENSION_NOT_FOUND                    102
 #define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED        103
+#define X509V3_R_ILLEGAL_HEX_DIGIT                      113
 #define X509V3_R_INVALID_BOOLEAN_STRING                         104
 #define X509V3_R_INVALID_EXTENSION_STRING               105
 #define X509V3_R_INVALID_NAME                           106
@@ -25,4 +32,6 @@
 #define X509V3_R_INVALID_NULL_NAME                      108
 #define X509V3_R_INVALID_NULL_VALUE                     109
 #define X509V3_R_INVALID_OBJECT_IDENTIFIER              110
+#define X509V3_R_NO_PUBLIC_KEY                          114
+#define X509V3_R_ODD_NUMBER_OF_DIGITS                   112
 #define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT            111
index 3f056a4..ce230a3 100644 (file)
@@ -75,7 +75,7 @@ typedef char * (*X509V3_EXT_NEW)();
 typedef void (*X509V3_EXT_FREE)();
 typedef char * (*X509V3_EXT_D2I)();
 typedef int (*X509V3_EXT_I2D)();
-typedef STACK * (*X509V3_EXT_I2V)(struct v3_ext_method *method, char *ext);
+typedef STACK * (*X509V3_EXT_I2V)(struct v3_ext_method *method, char *ext, STACK *extlist);
 typedef char * (*X509V3_EXT_V2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, STACK *values);
 typedef char * (*X509V3_EXT_I2S)(struct v3_ext_method *method, char *ext);
 typedef char * (*X509V3_EXT_S2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, char *str);
@@ -105,11 +105,15 @@ X509V3_EXT_I2R i2r;
 char *usr_data;        /* Any extension specific data */
 };
 
+
 /* Context specific info */
 struct v3_ext_ctx {
+#define CTX_TEST 0x1
+int flags;
 X509 *issuer_cert;
 X509 *subject_cert;
 X509_REQ *subject_req;
+X509_CRL *crl;
 /* Maybe more here */
 };
 
@@ -118,6 +122,7 @@ typedef struct v3_ext_ctx X509V3_CTX;
 
 /* ext_flags values */
 #define X509V3_EXT_DYNAMIC 0x1
+#define X509V3_EXT_CTX_DEP 0x2
 
 typedef struct {
 int bitnum;
@@ -130,6 +135,12 @@ int ca;
 ASN1_INTEGER *pathlen;
 } BASIC_CONSTRAINTS;
 
+typedef struct {
+ASN1_OCTET_STRING *keyid;
+STACK *issuer;
+ASN1_INTEGER *serial;
+} AUTHORITY_KEYID;
+
 typedef struct {
 
 #define GEN_OTHERNAME  (0|V_ASN1_CONTEXT_SPECIFIC)
@@ -194,12 +205,19 @@ GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **a, unsigned char **pp, long length
 GENERAL_NAME *GENERAL_NAME_new(void);
 void GENERAL_NAME_free(GENERAL_NAME *a);
 
+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);
+void AUTHORITY_KEYID_free(AUTHORITY_KEYID *a);
+
 STACK *GENERAL_NAMES_new(void);
 void GENERAL_NAMES_free(STACK *a);
 STACK *d2i_GENERAL_NAMES(STACK **a, unsigned char **pp, long length);
 int i2d_GENERAL_NAMES(STACK *a, unsigned char **pp);
+STACK *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, STACK *gen, STACK *extlist);
 
-
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
 
 int i2d_ext_ku(STACK *a, unsigned char **pp);
 STACK *d2i_ext_ku(STACK **a, unsigned char **pp, long length);
@@ -211,6 +229,7 @@ void X509V3_conf_free(CONF_VALUE *val);
 X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, char *value);
 X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value);
 int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509 *cert);
+int X509V3_EXT_check_conf(LHASH *conf, char *section);
 int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
 int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
 #endif
@@ -227,6 +246,9 @@ X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
 int X509V3_add_standard_extensions(void);
 STACK *X509V3_parse_list(char *line);
 
+char *hex_to_string(unsigned char *buffer, long len);
+unsigned char *string_to_hex(char *str, long *len);
+
 int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag);
 int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag);
 
@@ -247,6 +269,10 @@ STACK *GENERAL_NAMES_new():
 void GENERAL_NAMES_free():
 STACK *d2i_GENERAL_NAMES();
 int i2d_GENERAL_NAMES();
+STACK *i2v_GENERAL_NAMES();
+
+char *i2s_ASN1_OCTET_STRING();
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING();
 
 int i2d_ext_ku();
 STACK *d2i_ext_ku();
@@ -258,6 +284,7 @@ void X509V3_conf_free();
 X509_EXTENSION *X509V3_EXT_conf_nid();
 X509_EXTENSION *X509V3_EXT_conf();
 int X509V3_EXT_add_conf();
+int X509V3_EXT_check_conf();
 int X509V3_get_value_bool();
 int X509V3_get_value_int();
 #endif
@@ -274,6 +301,9 @@ X509V3_EXT_METHOD *X509V3_EXT_get_nid();
 int X509V3_add_standard_extensions();
 STACK *X509V3_parse_list();
 
+char *hex_to_string();
+unsigned char *string_to_hex();
+
 int X509V3_EXT_print();
 int X509V3_EXT_print_fp();
 #endif
@@ -282,8 +312,14 @@ int X509V3_EXT_print_fp();
 /* Error codes for the X509V3 functions. */
 
 /* Function codes. */
+#define X509V3_F_HEX_TO_STRING                          111
 #define X509V3_F_S2I_ASN1_IA5STRING                     100
+#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_V2I_ASN1_BIT_STRING                    101
+#define X509V3_F_V2I_AUTHORITY_KEYID                    116
 #define X509V3_F_V2I_BASIC_CONSTRAINTS                  102
 #define X509V3_F_V2I_EXT_KU                             103
 #define X509V3_F_X509V3_ADD_EXT                                 104
@@ -299,6 +335,7 @@ int X509V3_EXT_print_fp();
 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR               101
 #define X509V3_R_EXTENSION_NOT_FOUND                    102
 #define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED        103
+#define X509V3_R_ILLEGAL_HEX_DIGIT                      113
 #define X509V3_R_INVALID_BOOLEAN_STRING                         104
 #define X509V3_R_INVALID_EXTENSION_STRING               105
 #define X509V3_R_INVALID_NAME                           106
@@ -306,6 +343,8 @@ int X509V3_EXT_print_fp();
 #define X509V3_R_INVALID_NULL_NAME                      108
 #define X509V3_R_INVALID_NULL_VALUE                     109
 #define X509V3_R_INVALID_OBJECT_IDENTIFIER              110
+#define X509V3_R_NO_PUBLIC_KEY                          114
+#define X509V3_R_ODD_NUMBER_OF_DIGITS                   112
 #define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT            111
  
 #ifdef  __cplusplus