Allow additional information to be attached to a
authorDr. Stephen Henson <steve@openssl.org>
Thu, 4 Nov 1999 00:45:35 +0000 (00:45 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 4 Nov 1999 00:45:35 +0000 (00:45 +0000)
certificate: currently this includes trust settings
and a "friendly name".

19 files changed:
CHANGES
apps/x509.c
crypto/asn1/Makefile.ssl
crypto/asn1/a_mbstr.c
crypto/asn1/asn1.h
crypto/asn1/asn1_err.c
crypto/asn1/asn1_mac.h
crypto/asn1/t_bitst.c [new file with mode: 0644]
crypto/asn1/t_x509.c
crypto/asn1/t_x509a.c [new file with mode: 0644]
crypto/asn1/x_x509.c
crypto/asn1/x_x509a.c [new file with mode: 0644]
crypto/dsa/dsa_ossl.c
crypto/pem/pem.h
crypto/pem/pem_all.c
crypto/pem/pem_lib.c
crypto/x509/x509.h
crypto/x509v3/v3_purp.c
crypto/x509v3/x509v3.h

diff --git a/CHANGES b/CHANGES
index 5a017ce..ef3392c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,22 @@
 
  Changes between 0.9.4 and 0.9.5  [xx XXX 1999]
 
+  *) Extensive changes to support certificate auxiliary information.
+     This involves the use of X509_CERT_AUX structure and X509_AUX
+     functions. An X509_AUX function such as PEM_read_X509_AUX()
+     can still read in a certificate file in the usual way but it
+     will also read in any additional "auxiliary information". By
+     doing things this way a fair degree of compatability can be
+     retained: existing certificates can have this information added
+     using the new 'x509' options. 
+
+     Current auxiliary information includes an "alias" and some trust
+     settings. The trust settings will ultimately be used in enhanced
+     certificate chain verification routines: currently a certificate
+     can only be trusted if it is self signed and then it is trusted
+     for all purposes.
+     [Steve Henson]
+
   *) Fix assembler for Alpha (tested only on DEC OSF not Linux or *BSD).  The
      problem was that one of the replacement routines had not been working since
      SSLeay releases.  For now the offending routine has been replaced with
index d88eb56..a7f25f0 100644 (file)
@@ -102,8 +102,14 @@ static char *x509_usage[]={
 " -dates          - both Before and After dates\n",
 " -modulus        - print the RSA key modulus\n",
 " -fingerprint    - print the certificate fingerprint\n",
+" -alias          - output certificate alias\n",
 " -noout          - no certificate output\n",
-
+" -trustout       - output a \"trusted\" certificate\n",
+" -clrtrust       - clear all trusted purposes\n",
+" -clrnotrust     - clear all untrusted purposes\n",
+" -addtrust arg   - mark certificate as trusted for a given purpose\n",
+" -addnotrust arg - mark certificate as not trusted for a given purpose\n",
+" -setalias arg   - set certificate alias\n",
 " -days arg       - How long till expiry of a signed certificate - def 30 days\n",
 " -signkey arg    - self sign cert with arg\n",
 " -x509toreq      - output a certification request object\n",
@@ -146,11 +152,14 @@ int MAIN(int argc, char **argv)
        int i,num,badops=0;
        BIO *out=NULL;
        BIO *STDout=NULL;
+       STACK *trust = NULL, *notrust = NULL;
        int informat,outformat,keyformat,CAformat,CAkeyformat;
        char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
        char *CAkeyfile=NULL,*CAserial=NULL;
+       char *alias=NULL, *trstr=NULL;
        int text=0,serial=0,hash=0,subject=0,issuer=0,startdate=0,enddate=0;
        int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0;
+       int trustout=0,clrtrust=0,clrnotrust=0,aliasout=0;
        int C=0;
        int x509req=0,days=DEF_DAYS,modulus=0;
        int pprint = 0;
@@ -270,6 +279,44 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        CAserial= *(++argv);
                        }
+               else if (strcmp(*argv,"-addtrust") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       trstr= *(++argv);
+                       if(!X509_trust_set_bit_asc(NULL, trstr, 0)) {
+                               BIO_printf(bio_err,
+                                       "Unknown trust value %s\n", trstr);
+                               goto bad;
+                       }
+                       if(!trust) trust = sk_new_null();
+                       sk_push(trust, trstr);
+                       trustout = 1;
+                       }
+               else if (strcmp(*argv,"-addnotrust") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       trstr= *(++argv);
+                       if(!X509_notrust_set_bit_asc(NULL, trstr, 0)) {
+                               BIO_printf(bio_err,
+                                       "Unknown trust value %s\n", trstr);
+                               goto bad;
+                       }
+                       if(!notrust) notrust = sk_new_null();
+                       sk_push(notrust, trstr);
+                       trustout = 1;
+                       }
+               else if (strcmp(*argv,"-setalias") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       alias= *(++argv);
+                       trustout = 1;
+                       }
+               else if (strcmp(*argv,"-setalias") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       alias= *(++argv);
+                       trustout = 1;
+                       }
                else if (strcmp(*argv,"-C") == 0)
                        C= ++num;
                else if (strcmp(*argv,"-serial") == 0)
@@ -301,6 +348,14 @@ int MAIN(int argc, char **argv)
                        enddate= ++num;
                else if (strcmp(*argv,"-noout") == 0)
                        noout= ++num;
+               else if (strcmp(*argv,"-trustout") == 0)
+                       trustout= 1;
+               else if (strcmp(*argv,"-clrtrust") == 0)
+                       clrtrust= ++num;
+               else if (strcmp(*argv,"-clrnotrust") == 0)
+                       clrnotrust= ++num;
+               else if (strcmp(*argv,"-alias") == 0)
+                       aliasout= ++num;
                else if (strcmp(*argv,"-CAcreateserial") == 0)
                        CA_createserial= ++num;
                else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
@@ -494,6 +549,27 @@ bad:
                        }
                }
 
+       if(alias) X509_alias_set(x, (unsigned char *)alias, -1);
+
+       if(clrtrust) X509_trust_set_bit(x, -1, 0);
+       if(clrnotrust) X509_notrust_set_bit(x, -1, 0);
+
+       if(trust) {
+               for(i = 0; i < sk_num(trust); i++) {
+                       trstr = sk_value(trust, i);
+                       X509_trust_set_bit_asc(x, trstr, 1);
+               }
+               sk_free(trust);
+       }
+
+       if(notrust) {
+               for(i = 0; i < sk_num(notrust); i++) {
+                       trstr = sk_value(notrust, i);
+                       X509_notrust_set_bit_asc(x, trstr, 1);
+               }
+               sk_free(notrust);
+       }
+
        if (num)
                {
                for (i=1; i<=num; i++)
@@ -516,6 +592,13 @@ bad:
                                i2a_ASN1_INTEGER(STDout,x->cert_info->serialNumber);
                                BIO_printf(STDout,"\n");
                                }
+                       else if (aliasout == i)
+                               {
+                               unsigned char *alstr;
+                               alstr = X509_alias_get(x, NULL);
+                               if(alstr) BIO_printf(STDout,"%s\n", alstr);
+                               else BIO_puts(STDout,"<No Alias>\n");
+                               }
                        else if (hash == i)
                                {
                                BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
@@ -726,9 +809,10 @@ bad:
 
        if      (outformat == FORMAT_ASN1)
                i=i2d_X509_bio(out,x);
-       else if (outformat == FORMAT_PEM)
-               i=PEM_write_bio_X509(out,x);
-       else if (outformat == FORMAT_NETSCAPE)
+       else if (outformat == FORMAT_PEM) {
+               if(trustout) i=PEM_write_bio_X509_AUX(out,x);
+               else i=PEM_write_bio_X509(out,x);
+       } else if (outformat == FORMAT_NETSCAPE)
                {
                ASN1_HEADER ah;
                ASN1_OCTET_STRING os;
@@ -1070,7 +1154,7 @@ static X509 *load_cert(char *file, int format)
                ah->data=NULL;
                }
        else if (format == FORMAT_PEM)
-               x=PEM_read_bio_X509(cert,NULL,NULL,NULL);
+               x=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL);
        else    {
                BIO_printf(bio_err,"bad input format specified for input cert\n");
                goto end;
index f3f9056..ccdba3c 100644 (file)
@@ -26,11 +26,11 @@ LIBSRC=     a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
        a_print.c a_type.c a_set.c a_dup.c a_d2i_fp.c a_i2d_fp.c a_bmp.c \
        a_enum.c a_vis.c a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c \
        x_algor.c x_val.c x_pubkey.c x_sig.c x_req.c x_attrib.c \
-       x_name.c x_cinf.c x_x509.c x_crl.c x_info.c x_spki.c nsseq.c \
+       x_name.c x_cinf.c x_x509.c x_x509a.c x_crl.c x_info.c x_spki.c nsseq.c \
        d2i_r_pr.c i2d_r_pr.c d2i_r_pu.c i2d_r_pu.c \
        d2i_s_pr.c i2d_s_pr.c d2i_s_pu.c i2d_s_pu.c \
        d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\
-       t_req.c t_x509.c t_crl.c t_pkey.c t_spki.c \
+       t_req.c t_x509.c t_x509a.c t_crl.c t_pkey.c t_spki.c t_bitst.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 \
@@ -41,11 +41,11 @@ LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
        a_print.o a_type.o a_set.o a_dup.o a_d2i_fp.o a_i2d_fp.o a_bmp.o \
        a_enum.o a_vis.o a_utf8.o a_sign.o a_digest.o a_verify.o a_mbstr.o \
        x_algor.o x_val.o x_pubkey.o x_sig.o x_req.o x_attrib.o \
-       x_name.o x_cinf.o x_x509.o x_crl.o x_info.o x_spki.o nsseq.o \
+       x_name.o x_cinf.o x_x509.o x_x509a.o x_crl.o x_info.o x_spki.o nsseq.o \
        d2i_r_pr.o i2d_r_pr.o d2i_r_pu.o i2d_r_pu.o \
        d2i_s_pr.o i2d_s_pr.o d2i_s_pu.o i2d_s_pu.o \
        d2i_pu.o d2i_pr.o i2d_pu.o i2d_pr.o \
-       t_req.o t_x509.o t_crl.o t_pkey.o t_spki.o \
+       t_req.o t_x509.o t_x509a.o t_crl.o t_pkey.o t_spki.o t_bitst.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 \
@@ -804,6 +804,24 @@ p8_pkey.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
 p8_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 p8_pkey.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
 p8_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h
+t_bitst.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+t_bitst.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+t_bitst.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+t_bitst.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+t_bitst.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+t_bitst.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
+t_bitst.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+t_bitst.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+t_bitst.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+t_bitst.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+t_bitst.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+t_bitst.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h
+t_bitst.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+t_bitst.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
+t_bitst.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+t_bitst.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+t_bitst.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+t_bitst.o: ../../include/openssl/x509v3.h ../cryptlib.h
 t_crl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 t_crl.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
 t_crl.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
@@ -882,6 +900,23 @@ t_x509.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 t_x509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 t_x509.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 t_x509.o: ../../include/openssl/x509v3.h ../cryptlib.h
+t_x509a.o: ../../include/openssl/asn1.h ../../include/openssl/asn1_mac.h
+t_x509a.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
+t_x509a.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+t_x509a.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
+t_x509a.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+t_x509a.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
+t_x509a.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+t_x509a.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+t_x509a.o: ../../include/openssl/md2.h ../../include/openssl/md5.h
+t_x509a.o: ../../include/openssl/mdc2.h ../../include/openssl/objects.h
+t_x509a.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+t_x509a.o: ../../include/openssl/pkcs7.h ../../include/openssl/rc2.h
+t_x509a.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
+t_x509a.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
+t_x509a.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+t_x509a.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
+t_x509a.o: ../../include/openssl/x509_vfy.h ../cryptlib.h
 x_algor.o: ../../include/openssl/asn1.h ../../include/openssl/asn1_mac.h
 x_algor.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
 x_algor.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
@@ -1122,3 +1157,20 @@ x_x509.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
 x_x509.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 x_x509.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
 x_x509.o: ../../include/openssl/x509_vfy.h ../cryptlib.h
+x_x509a.o: ../../include/openssl/asn1.h ../../include/openssl/asn1_mac.h
+x_x509a.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
+x_x509a.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+x_x509a.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
+x_x509a.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+x_x509a.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
+x_x509a.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+x_x509a.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+x_x509a.o: ../../include/openssl/md2.h ../../include/openssl/md5.h
+x_x509a.o: ../../include/openssl/mdc2.h ../../include/openssl/objects.h
+x_x509a.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_x509a.o: ../../include/openssl/pkcs7.h ../../include/openssl/rc2.h
+x_x509a.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
+x_x509a.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
+x_x509a.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_x509a.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
+x_x509a.o: ../../include/openssl/x509_vfy.h ../cryptlib.h
index 9e7c7c3..bc9cb14 100644 (file)
@@ -144,7 +144,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
        ASN1_STRING *dest;
        unsigned char *p;
        int nchar;
-       unsigned char strbuf[32];
+       char strbuf[32];
        int (*cpyfunc)(unsigned long,void *) = NULL;
        if(len == -1) len = strlen((const char *)in);
        if(!mask) mask = dirstring_mask;
index 8c42101..7fb9d23 100644 (file)
@@ -311,6 +311,14 @@ typedef struct asn1_header_st
        ASN1_METHOD *meth;
        } ASN1_HEADER;
 
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+       int bitnum;
+       const char *lname;
+       const char *sname;
+} BIT_STRING_BITNAME;
+
+
 #define M_ASN1_STRING_length(x)        ((x)->length)
 #define M_ASN1_STRING_length_set(x, n) ((x)->length = (n))
 #define M_ASN1_STRING_type(x)  ((x)->type)
@@ -531,6 +539,13 @@ int                ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
 int            ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
 int            ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
 
+#ifdef HEADER_BIO_H
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+                               BIT_STRING_BITNAME *tbl, int indent);
+#endif
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+                               BIT_STRING_BITNAME *tbl);
 
 int            i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
 int            d2i_ASN1_BOOLEAN(int *a,unsigned char **pp,long length);
@@ -870,6 +885,7 @@ void ASN1_STRING_TABLE_cleanup(void);
 #define ASN1_F_D2I_X509                                         159
 #define ASN1_F_D2I_X509_ALGOR                           160
 #define ASN1_F_D2I_X509_ATTRIBUTE                       161
+#define ASN1_F_D2I_X509_CERT_AUX                        285
 #define ASN1_F_D2I_X509_CINF                            162
 #define ASN1_F_D2I_X509_CRL                             163
 #define ASN1_F_D2I_X509_CRL_INFO                        164
@@ -933,6 +949,7 @@ void ASN1_STRING_TABLE_cleanup(void);
 #define ASN1_F_USERNOTICE_NEW                           275
 #define ASN1_F_X509_ALGOR_NEW                           202
 #define ASN1_F_X509_ATTRIBUTE_NEW                       203
+#define ASN1_F_X509_CERT_AUX_NEW                        286
 #define ASN1_F_X509_CINF_NEW                            204
 #define ASN1_F_X509_CRL_INFO_NEW                        205
 #define ASN1_F_X509_CRL_NEW                             206
index 3b1fb7b..a577daf 100644 (file)
@@ -169,6 +169,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_PACK(0,ASN1_F_D2I_X509,0),        "d2i_X509"},
 {ERR_PACK(0,ASN1_F_D2I_X509_ALGOR,0),  "d2i_X509_ALGOR"},
 {ERR_PACK(0,ASN1_F_D2I_X509_ATTRIBUTE,0),      "d2i_X509_ATTRIBUTE"},
+{ERR_PACK(0,ASN1_F_D2I_X509_CERT_AUX,0),       "d2i_X509_CERT_AUX"},
 {ERR_PACK(0,ASN1_F_D2I_X509_CINF,0),   "d2i_X509_CINF"},
 {ERR_PACK(0,ASN1_F_D2I_X509_CRL,0),    "d2i_X509_CRL"},
 {ERR_PACK(0,ASN1_F_D2I_X509_CRL_INFO,0),       "d2i_X509_CRL_INFO"},
@@ -232,6 +233,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_PACK(0,ASN1_F_USERNOTICE_NEW,0),  "USERNOTICE_new"},
 {ERR_PACK(0,ASN1_F_X509_ALGOR_NEW,0),  "X509_ALGOR_new"},
 {ERR_PACK(0,ASN1_F_X509_ATTRIBUTE_NEW,0),      "X509_ATTRIBUTE_new"},
+{ERR_PACK(0,ASN1_F_X509_CERT_AUX_NEW,0),       "X509_CERT_AUX_new"},
 {ERR_PACK(0,ASN1_F_X509_CINF_NEW,0),   "X509_CINF_new"},
 {ERR_PACK(0,ASN1_F_X509_CRL_INFO_NEW,0),       "X509_CRL_INFO_new"},
 {ERR_PACK(0,ASN1_F_X509_CRL_NEW,0),    "X509_CRL_new"},
index 93f9c51..a9026d7 100644 (file)
@@ -106,6 +106,20 @@ err:\
 #define M_ASN1_D2I_start_sequence() \
        if (!asn1_GetSequence(&c,&length)) \
                { c.line=__LINE__; goto err; }
+/* Begin reading ASN1 without a surrounding sequence */
+#define M_ASN1_D2I_begin() \
+       c.slen = length;
+
+/* End reading ASN1 with no check on length */
+#define M_ASN1_D2I_Finish_nolen() \
+       *pp=c.p; \
+       if (a != NULL) (*a)=ret; \
+       return(ret); \
+err:\
+       ASN1_MAC_H_err((e),c.error,c.line); \
+       asn1_add_error(*pp,(int)(c.q- *pp)); \
+       if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
+       return(NULL)
 
 #define M_ASN1_D2I_end_sequence() \
        (((c.inf&1) == 0)?(c.slen <= 0): \
diff --git a/crypto/asn1/t_bitst.c b/crypto/asn1/t_bitst.c
new file mode 100644 (file)
index 0000000..8ee789f
--- /dev/null
@@ -0,0 +1,99 @@
+/* t_bitst.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 "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+                               BIT_STRING_BITNAME *tbl, int indent)
+{
+       BIT_STRING_BITNAME *bnam;
+       char first = 1;
+       BIO_printf(out, "%*s", indent, "");
+       for(bnam = tbl; bnam->lname; bnam++) {
+               if(ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
+                       if(!first) BIO_puts(out, ", ");
+                       BIO_puts(out, bnam->lname);
+                       first = 0;
+               }
+       }
+       BIO_puts(out, "\n");
+       return 1;
+}
+
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+                               BIT_STRING_BITNAME *tbl)
+{
+       int bitnum;
+       bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
+       if(bitnum < 0) return 0;
+       if(bs) ASN1_BIT_STRING_set_bit(bs, bitnum, value);
+       return 1;
+}
+
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
+{
+       BIT_STRING_BITNAME *bnam;
+       for(bnam = tbl; bnam->lname; bnam++) {
+               if(!strcmp(bnam->sname, name) ||
+                       !strcmp(bnam->lname, name) ) return bnam->bitnum;
+       }
+       return -1;
+}
index 0e2727e..bf6a797 100644 (file)
@@ -219,6 +219,7 @@ int X509_print(BIO *bp, X509 *x)
                        ((i+1) == n)?"":":") <= 0) goto err;
                }
        if (BIO_write(bp,"\n",1) != 1) goto err;
+       if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
        ret=1;
 err:
        if (str != NULL) ASN1_STRING_free(str);
diff --git a/crypto/asn1/t_x509a.c b/crypto/asn1/t_x509a.c
new file mode 100644 (file)
index 0000000..26d03f5
--- /dev/null
@@ -0,0 +1,138 @@
+/* t_x509a.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 "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
+
+/* X509_CERT_AUX and string set routines
+ */
+
+static BIT_STRING_BITNAME tbits[] = {
+{X509_TRUST_ALL, "All Purposes", "all"},
+{X509_TRUST_SSL_CLIENT, "SSL client", "sslclient"},
+{X509_TRUST_SSL_SERVER, "SSL server", "sslserver"},
+{X509_TRUST_EMAIL, "S/MIME email", "email"},
+{X509_TRUST_OBJECT_SIGN, "Object Signing", "objsign"},
+{-1, NULL, NULL}
+};
+
+int X509_trust_set_bit_asc(X509 *x, char *str, int value)
+{
+       int bitnum;
+       bitnum = ASN1_BIT_STRING_num_asc(str, tbits);
+       if(bitnum < 0) return 0;
+       if(x) return X509_trust_set_bit(x, bitnum, value);
+       return 1;
+}
+
+int X509_notrust_set_bit_asc(X509 *x, char *str, int value)
+{
+       int bitnum;
+       bitnum = ASN1_BIT_STRING_num_asc(str, tbits);
+       if(bitnum < 0) return 0;
+       if(x) return X509_notrust_set_bit(x, bitnum, value);
+       return 1;
+}
+
+
+int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
+{
+       char oidstr[80], first;
+       int i;
+       if(!aux) return 1;
+       if(aux->trust) {
+               BIO_printf(out, "%*sTrusted for:\n", indent, "");
+               ASN1_BIT_STRING_name_print(out, aux->trust, tbits, indent + 2);
+       } else BIO_printf(out, "%*sNo Trust Settings\n", indent + 2, "");
+       if(aux->notrust) {
+               BIO_printf(out, "%*sUntrusted for:\n", indent, "");
+               ASN1_BIT_STRING_name_print(out, aux->notrust, tbits, indent + 2);
+       } else BIO_printf(out, "%*sNo Untrusted Settings\n", indent + 2, "");
+       if(aux->othertrust) {
+               first = 1;
+               BIO_printf(out, "%*sOther Trusted Uses:\n%*s",
+                                               indent, "", indent + 2, "");
+               for(i = 0; i < sk_ASN1_OBJECT_num(aux->othertrust); i++) {
+                       if(!first) BIO_puts(out, ", ");
+                       else first = 0;
+                       OBJ_obj2txt(oidstr, 80,
+                               sk_ASN1_OBJECT_value(aux->othertrust, i), 0);
+                       BIO_puts(out, oidstr);
+               }
+               BIO_puts(out, "\n");
+       }
+       if(aux->othernotrust) {
+               first = 1;
+               BIO_printf(out, "%*sOther Untrusted Uses:\n%*s",
+                                               indent, "", indent + 2, "");
+               for(i = 0; i < sk_ASN1_OBJECT_num(aux->othernotrust); i++) {
+                       if(!first) BIO_puts(out, ", ");
+                       else first = 0;
+                       OBJ_obj2txt(oidstr, 80,
+                               sk_ASN1_OBJECT_value(aux->othernotrust, i), 0);
+                       BIO_puts(out, oidstr);
+               }
+               BIO_puts(out, "\n");
+       }
+       if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "",
+                                                       aux->alias->data);
+       return 1;
+}
index 3352c61..ee32130 100644 (file)
@@ -118,6 +118,7 @@ X509 *X509_new(void)
        ret->valid=0;
        ret->ex_flags = 0;
        ret->name=NULL;
+       ret->aux=NULL;
        M_ASN1_New(ret->cert_info,X509_CINF_new);
        M_ASN1_New(ret->sig_alg,X509_ALGOR_new);
        M_ASN1_New(ret->signature,M_ASN1_BIT_STRING_new);
@@ -149,6 +150,7 @@ void X509_free(X509 *a)
        X509_CINF_free(a->cert_info);
        X509_ALGOR_free(a->sig_alg);
        M_ASN1_BIT_STRING_free(a->signature);
+       X509_CERT_AUX_free(a->aux);
 
        if (a->name != NULL) Free(a->name);
        Free((char *)a);
@@ -172,3 +174,37 @@ char *X509_get_ex_data(X509 *r, int idx)
        return(CRYPTO_get_ex_data(&r->ex_data,idx));
        }
 
+/* X509_AUX ASN1 routines. X509_AUX is the name given to
+ * a certificate with extra info tagged on the end. Since these
+ * functions set how a certificate is trusted they should only
+ * be used when the certificate comes from a reliable source
+ * such as local storage.
+ *
+ */
+
+X509 *d2i_X509_AUX(X509 **a, unsigned char **pp, long length)
+{
+       unsigned char *q;
+       X509 *ret;
+       /* Save start position */
+       q = *pp;
+       ret = d2i_X509(a, pp, length);
+       /* If certificate unreadable then forget it */
+       if(!ret) return NULL;
+       /* update length */
+       length -= *pp - q;
+       if(!length) return ret;
+       if(!d2i_X509_CERT_AUX(&ret->aux, pp, length)) goto err;
+       return ret;
+       err:
+       X509_free(ret);
+       return NULL;
+}
+
+int i2d_X509_AUX(X509 *a, unsigned char **pp)
+{
+       int length;
+       length = i2d_X509(a, pp);
+       if(a) length += i2d_X509_CERT_AUX(a->aux, pp);
+       return length;
+}
diff --git a/crypto/asn1/x_x509a.c b/crypto/asn1/x_x509a.c
new file mode 100644 (file)
index 0000000..4b1f448
--- /dev/null
@@ -0,0 +1,218 @@
+/* a_x509a.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 "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
+
+/* X509_CERT_AUX routines. These are used to encode additional
+ * user modifiable data about a certificate. This data is
+ * appended to the X509 encoding when the *_X509_AUX routines
+ * are used. This means that the "traditional" X509 routines
+ * will simply ignore the extra data. 
+ */
+
+static X509_CERT_AUX *aux_get(X509 *x);
+
+X509_CERT_AUX *d2i_X509_CERT_AUX(X509_CERT_AUX **a, unsigned char **pp, long length)
+{
+       M_ASN1_D2I_vars(a, X509_CERT_AUX *, X509_CERT_AUX_new);
+       
+       M_ASN1_D2I_Init();
+       M_ASN1_D2I_start_sequence();
+
+       M_ASN1_D2I_get_opt(ret->trust, d2i_ASN1_BIT_STRING,
+                                                       V_ASN1_BIT_STRING);
+       M_ASN1_D2I_get_IMP_opt(ret->notrust, d2i_ASN1_BIT_STRING,0,
+                                                       V_ASN1_BIT_STRING);
+
+       M_ASN1_D2I_get_seq_opt_type(ASN1_OBJECT, ret->othertrust,
+                                       d2i_ASN1_OBJECT, ASN1_OBJECT_free);
+       M_ASN1_D2I_get_IMP_set_opt_type(ASN1_OBJECT, ret->othernotrust,
+                                       d2i_ASN1_OBJECT, ASN1_OBJECT_free, 1);
+       M_ASN1_D2I_get_opt(ret->alias, d2i_ASN1_UTF8STRING, V_ASN1_UTF8STRING);
+       M_ASN1_D2I_get_opt(ret->other, d2i_ASN1_TYPE, V_ASN1_SEQUENCE);
+
+       M_ASN1_D2I_Finish(a, X509_CERT_AUX_free, ASN1_F_D2I_X509_CERT_AUX);
+}
+
+X509_CERT_AUX *X509_CERT_AUX_new()
+{
+       X509_CERT_AUX *ret = NULL;
+       ASN1_CTX c;
+       M_ASN1_New_Malloc(ret, X509_CERT_AUX);
+       ret->trust = NULL;
+       ret->notrust = NULL;
+       ret->othertrust = NULL;
+       ret->othernotrust = NULL;
+       ret->alias = NULL;
+       ret->other = NULL;
+       return(ret);
+       M_ASN1_New_Error(ASN1_F_X509_CERT_AUX_NEW);
+}
+
+void X509_CERT_AUX_free(X509_CERT_AUX *a)
+{
+       if(a == NULL) return;
+       ASN1_BIT_STRING_free(a->trust);
+       ASN1_BIT_STRING_free(a->notrust);
+       sk_ASN1_OBJECT_pop_free(a->othertrust, ASN1_OBJECT_free);
+       sk_ASN1_OBJECT_pop_free(a->othernotrust, ASN1_OBJECT_free);
+       ASN1_UTF8STRING_free(a->alias);
+       ASN1_TYPE_free(a->other);
+}
+
+int i2d_X509_CERT_AUX(X509_CERT_AUX *a, unsigned char **pp)
+{
+       M_ASN1_I2D_vars(a);
+
+       M_ASN1_I2D_len(a->trust, i2d_ASN1_BIT_STRING);  
+       M_ASN1_I2D_len_IMP_opt(a->notrust, i2d_ASN1_BIT_STRING);
+
+       M_ASN1_I2D_len_SEQUENCE_opt_type(ASN1_OBJECT, a->othertrust, i2d_ASN1_OBJECT);
+       M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(ASN1_OBJECT, a->othernotrust, i2d_ASN1_OBJECT, 1);
+
+       M_ASN1_I2D_len(a->alias, i2d_ASN1_UTF8STRING);
+       M_ASN1_I2D_len(a->other, i2d_ASN1_TYPE);
+
+       M_ASN1_I2D_seq_total();
+
+       M_ASN1_I2D_put(a->trust, i2d_ASN1_BIT_STRING);  
+       M_ASN1_I2D_put_IMP_opt(a->notrust, i2d_ASN1_BIT_STRING, 0);
+
+       M_ASN1_I2D_put_SEQUENCE_opt_type(ASN1_OBJECT, a->othertrust, i2d_ASN1_OBJECT);
+       M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(ASN1_OBJECT, a->othernotrust, i2d_ASN1_OBJECT, 1);
+
+       M_ASN1_I2D_put(a->alias, i2d_ASN1_UTF8STRING);
+       M_ASN1_I2D_put(a->other, i2d_ASN1_TYPE);
+
+       M_ASN1_I2D_finish();
+}
+
+static X509_CERT_AUX *aux_get(X509 *x)
+{
+       if(!x) return NULL;
+       if(!x->aux && !(x->aux = X509_CERT_AUX_new())) return NULL;
+       return x->aux;
+}
+
+int X509_alias_set(X509 *x, unsigned char *name, int len)
+{
+       X509_CERT_AUX *aux;
+       if(!(aux = aux_get(x))) return 0;
+       if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0;
+       return ASN1_STRING_set(aux->alias, name, len);
+}
+
+unsigned char *X509_alias_get(X509 *x, int *len)
+{
+       if(!x->aux || !x->aux->alias) return NULL;
+       if(len) *len = x->aux->alias->length;
+       return x->aux->alias->data;
+}
+
+int X509_trust_set_bit(X509 *x, int bit, int value)
+{
+       X509_CERT_AUX *aux;
+       if(bit == -1) {
+               if(x->aux && x->aux->trust) {
+                       ASN1_BIT_STRING_free(x->aux->trust);
+                       x->aux->trust = NULL;
+               }
+               return 1;
+       }
+       if(!(aux = aux_get(x))) return 0;
+       if(!aux->trust && !(aux->trust = ASN1_BIT_STRING_new())) return 0;
+       return ASN1_BIT_STRING_set_bit(aux->trust, bit, value);
+}
+
+int X509_notrust_set_bit(X509 *x, int bit, int value)
+{
+       X509_CERT_AUX *aux;
+       if(bit == -1) {
+               if(x->aux && x->aux->notrust) {
+                       ASN1_BIT_STRING_free(x->aux->notrust);
+                       x->aux->notrust = NULL;
+               }
+               return 1;
+       }
+       if(!(aux = aux_get(x))) return 0;
+       if(!aux->notrust && !(aux->notrust = ASN1_BIT_STRING_new())) return 0;
+       return ASN1_BIT_STRING_set_bit(aux->notrust, bit, value);
+}
+
+int X509_add_trust_object(X509 *x, ASN1_OBJECT *obj)
+{
+       X509_CERT_AUX *aux;
+       if(!(aux = aux_get(x))) return 0;
+       if(!aux->othertrust
+               && !(aux->othertrust = sk_ASN1_OBJECT_new_null())) return 0;
+       return sk_ASN1_OBJECT_push(aux->othertrust, obj);
+}
+
+int X509_add_notrust_object(X509 *x, ASN1_OBJECT *obj)
+{
+       X509_CERT_AUX *aux;
+       if(!(aux = aux_get(x))) return 0;
+       if(!aux->othernotrust
+               && !(aux->othernotrust = sk_ASN1_OBJECT_new_null())) return 0;
+       return sk_ASN1_OBJECT_push(aux->othernotrust, obj);
+}
+
index 74a84b6..b51cf6a 100644 (file)
@@ -66,7 +66,7 @@
 #include <openssl/asn1.h>
 
 static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
-int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
 static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
                  DSA *dsa);
 static int dsa_init(DSA *dsa);
@@ -161,7 +161,7 @@ err:
        return(ret);
        }
 
-int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
        {
        BN_CTX *ctx;
        BIGNUM k,*kinv=NULL,*r=NULL;
index 1b0c8a0..ce2c1a3 100644 (file)
@@ -103,6 +103,7 @@ extern "C" {
 
 #define PEM_STRING_X509_OLD    "X509 CERTIFICATE"
 #define PEM_STRING_X509                "CERTIFICATE"
+#define PEM_STRING_X509_TRUSTED        "TRUSTED CERTIFICATE"
 #define PEM_STRING_X509_REQ_OLD        "NEW CERTIFICATE REQUEST"
 #define PEM_STRING_X509_REQ    "CERTIFICATE REQUEST"
 #define PEM_STRING_X509_CRL    "X509 CRL"
@@ -529,6 +530,8 @@ void        PEM_dek_info(char *buf, const char *type, int len, char *str);
 
 DECLARE_PEM_rw(X509, X509)
 
+DECLARE_PEM_rw(X509_AUX, X509)
+
 DECLARE_PEM_rw(X509_REQ, X509_REQ)
 
 DECLARE_PEM_rw(X509_CRL, X509_CRL)
index b5857e0..80f4037 100644 (file)
@@ -67,6 +67,8 @@
 
 IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509)
 
+IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX)
+
 IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
 
 IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
index 3c86a23..a4ea212 100644 (file)
@@ -75,6 +75,7 @@ const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT;
 
 static int def_callback(char *buf, int num, int w, void *userdata);
 static int load_iv(unsigned char **fromp,unsigned char *to, int num);
+static int check_pem(const char *nm, const char *name);
 
 static int def_callback(char *buf, int num, int w, void *userdata)
        {
@@ -168,6 +169,43 @@ char *PEM_ASN1_read(char *(*d2i)(), const char *name, FILE *fp, char **x,
        }
 #endif
 
+static int check_pem(const char *nm, const char *name)
+{
+       /* Normal matching nm and name */
+       if (!strcmp(nm,name)) return 1;
+
+       /* Make PEM_STRING_EVP_PKEY match any private key */
+
+       if(!strcmp(nm,PEM_STRING_PKCS8) &&
+               !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
+
+       if(!strcmp(nm,PEM_STRING_PKCS8INF) &&
+                !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
+
+       if(!strcmp(nm,PEM_STRING_RSA) &&
+               !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
+
+       if(!strcmp(nm,PEM_STRING_DSA) &&
+                !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
+
+       /* Permit older strings */
+
+       if(!strcmp(nm,PEM_STRING_X509_OLD) &&
+               !strcmp(name,PEM_STRING_X509)) return 1;
+
+       if(!strcmp(nm,PEM_STRING_X509_REQ_OLD) &&
+               !strcmp(name,PEM_STRING_X509_REQ)) return 1;
+
+       /* Allow normal certs to be read as trusted certs */
+       if(!strcmp(nm,PEM_STRING_X509) &&
+               !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
+
+       if(!strcmp(nm,PEM_STRING_X509_OLD) &&
+               !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
+
+       return 0;
+}
+
 char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x,
             pem_password_cb *cb, void *u)
        {
@@ -185,21 +223,7 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x,
                                ERR_add_error_data(2, "Expecting: ", name);
                        return(NULL);
                }
-               if (    (strcmp(nm,name) == 0) ||
-                       ((strcmp(nm,PEM_STRING_RSA) == 0) &&
-                        (strcmp(name,PEM_STRING_EVP_PKEY) == 0)) ||
-                       ((strcmp(nm,PEM_STRING_DSA) == 0) &&
-                        (strcmp(name,PEM_STRING_EVP_PKEY) == 0)) ||
-                       ((strcmp(nm,PEM_STRING_PKCS8) == 0) &&
-                        (strcmp(name,PEM_STRING_EVP_PKEY) == 0)) ||
-                       ((strcmp(nm,PEM_STRING_PKCS8INF) == 0) &&
-                        (strcmp(name,PEM_STRING_EVP_PKEY) == 0)) ||
-                       ((strcmp(nm,PEM_STRING_X509_OLD) == 0) &&
-                        (strcmp(name,PEM_STRING_X509) == 0)) ||
-                       ((strcmp(nm,PEM_STRING_X509_REQ_OLD) == 0) &&
-                        (strcmp(name,PEM_STRING_X509_REQ) == 0)) 
-                       )
-                       break;
+               if(check_pem(nm, name)) break;
                Free(nm);
                Free(header);
                Free(data);
index 6091ffd..a6e61cf 100644 (file)
@@ -230,6 +230,30 @@ typedef struct x509_cinf_st
        STACK_OF(X509_EXTENSION) *extensions;   /* [ 3 ] optional in v3 */
        } X509_CINF;
 
+/* This stuff is certificate "auxiliary info"
+ * it contains details which are useful in certificate
+ * stores and databases. When used this is tagged onto
+ * the end of the certificate itself
+ */
+
+/* Bit values for trust/notrust */
+
+#define X509_TRUST_ALL                 0
+#define X509_TRUST_SSL_CLIENT          1
+#define X509_TRUST_SSL_SERVER          2
+#define X509_TRUST_EMAIL               3
+#define X509_TRUST_OBJECT_SIGN         4
+
+typedef struct x509_cert_aux_st
+       {
+       ASN1_BIT_STRING *trust;                 /* trusted uses */
+       ASN1_BIT_STRING *notrust;               /* rejected uses */
+       STACK_OF(ASN1_OBJECT) *othertrust;      /* extra uses */
+       STACK_OF(ASN1_OBJECT) *othernotrust;    /* extra rejected uses */
+       ASN1_UTF8STRING *alias;                 /* "friendly name" */
+       ASN1_TYPE *other;                       /* other unspecified info */
+       } X509_CERT_AUX;
+
 typedef struct x509_st
        {
        X509_CINF *cert_info;
@@ -245,6 +269,7 @@ typedef struct x509_st
        unsigned long ex_kusage;
        unsigned long ex_xkusage;
        unsigned long ex_nscert;
+       X509_CERT_AUX *aux;
        } X509;
 
 DECLARE_STACK_OF(X509)
@@ -735,6 +760,23 @@ int X509_get_ex_new_index(long argl, char *argp, int (*new_func)(),
             int (*dup_func)(), void (*free_func)());
 int X509_set_ex_data(X509 *r, int idx, char *arg);
 char *X509_get_ex_data(X509 *r, int idx);
+int            i2d_X509_AUX(X509 *a,unsigned char **pp);
+X509 *         d2i_X509_AUX(X509 **a,unsigned char **pp,long length);
+
+X509_CERT_AUX *        X509_CERT_AUX_new(void);
+void           X509_CERT_AUX_free(X509_CERT_AUX *a);
+int            i2d_X509_CERT_AUX(X509_CERT_AUX *a,unsigned char **pp);
+X509_CERT_AUX *        d2i_X509_CERT_AUX(X509_CERT_AUX **a,unsigned char **pp,
+                                                               long length);
+int X509_alias_set(X509 *x, unsigned char *name, int len);
+unsigned char * X509_alias_get(X509 *x, int *len);
+int X509_trust_set_bit(X509 *x, int bit, int value);
+int X509_notrust_set_bit(X509 *x, int bit, int value);
+int X509_add_trust_object(X509 *x, ASN1_OBJECT *obj);
+int X509_add_notrust_object(X509 *x, ASN1_OBJECT *obj);
+
+int X509_trust_set_bit_asc(X509 *x, char *str, int value);
+int X509_notrust_set_bit_asc(X509 *x, char *str, int value);
 
 X509_REVOKED * X509_REVOKED_new(void);
 void           X509_REVOKED_free(X509_REVOKED *a);
@@ -840,6 +882,7 @@ int         X509_REQ_print_fp(FILE *bp,X509_REQ *req);
 #ifdef HEADER_BIO_H
 int            X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
 int            X509_print(BIO *bp,X509 *x);
+int            X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent);
 int            X509_CRL_print(BIO *bp,X509_CRL *x);
 int            X509_REQ_print(BIO *bp,X509_REQ *req);
 #endif
index f2565e7..d7e561e 100644 (file)
@@ -62,7 +62,7 @@
 
 
 static int x509_purpose_get_idx(int id);
-void x509v3_cache_extensions(X509 *x);
+static void x509v3_cache_extensions(X509 *x);
 
 static int ca_check(X509 *x);
 static int check_purpose_ssl_client(X509_PURPOSE *xp, X509 *x, int ca);
@@ -109,7 +109,7 @@ int X509_check_purpose(X509 *x, int id, int ca)
        return pt->check_purpose(pt, x,ca);
 }
                        
-       
+
 
 
 static int x509_purpose_get_idx(int id)
@@ -191,7 +191,7 @@ char *X509_PURPOSE_get_name(X509_PURPOSE *xp)
        return xp->purpose_name;
 }
 
-void x509v3_cache_extensions(X509 *x)
+static void x509v3_cache_extensions(X509 *x)
 {
        BASIC_CONSTRAINTS *bs;
        ASN1_BIT_STRING *usage;
index 2e2756f..d082133 100644 (file)
@@ -136,12 +136,6 @@ typedef struct v3_ext_ctx X509V3_CTX;
 #define X509V3_EXT_CTX_DEP     0x2
 #define X509V3_EXT_MULTILINE   0x4
 
-typedef struct BIT_STRING_BITNAME_st {
-int bitnum;
-const char *lname;
-const char *sname;
-} BIT_STRING_BITNAME;
-
 typedef BIT_STRING_BITNAME ENUMERATED_NAMES;
 
 typedef struct BASIC_CONSTRAINTS_st {