More multibyte character support.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 25 Oct 1999 02:00:09 +0000 (02:00 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 25 Oct 1999 02:00:09 +0000 (02:00 +0000)
Functions to get keys from EVP_PKEY structures.

14 files changed:
crypto/asn1/Makefile.ssl
crypto/asn1/a_mbstr.c
crypto/asn1/a_strnid.c [new file with mode: 0644]
crypto/asn1/asn1.h
crypto/asn1/asn1_err.c
crypto/evp/evp.h
crypto/evp/evp_err.c
crypto/evp/p_lib.c
crypto/objects/obj_dat.h
crypto/objects/objects.h
crypto/pem/pem_lib.c
crypto/x509/x509name.c
doc/openssl.txt
util/libeay.num

index a1776d5..f3f9056 100644 (file)
@@ -35,7 +35,7 @@ LIBSRC=       a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.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 \
        f_enum.c a_hdr.c x_pkey.c a_bool.c x_exten.c \
-       asn1_par.c asn1_lib.c asn1_err.c a_meth.c a_bytes.c \
+       asn1_par.c asn1_lib.c asn1_err.c a_meth.c a_bytes.c a_strnid.c \
        evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c
 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 \
@@ -50,7 +50,7 @@ LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.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 \
        f_enum.o a_hdr.o x_pkey.o a_bool.o x_exten.o \
-       asn1_par.o asn1_lib.o asn1_err.o a_meth.o a_bytes.o \
+       asn1_par.o asn1_lib.o asn1_err.o a_meth.o a_bytes.o a_strnid.o \
        evp_asn1.o asn_pack.o p5_pbe.o p5_pbev2.o p8_pkey.o
 
 SRC= $(LIBSRC)
@@ -268,6 +268,13 @@ a_sign.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 a_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 a_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 a_sign.o: ../cryptlib.h
+a_strnid.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+a_strnid.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+a_strnid.o: ../../include/openssl/crypto.h ../../include/openssl/e_os.h
+a_strnid.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_strnid.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+a_strnid.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
+a_strnid.o: ../../include/openssl/stack.h ../cryptlib.h
 a_time.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 a_time.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 a_time.o: ../../include/openssl/crypto.h ../../include/openssl/e_os.h
index ce413ec..2fe658e 100644 (file)
@@ -57,6 +57,7 @@
  */
 
 #include <stdio.h>
+#include <ctype.h>
 #include "cryptlib.h"
 #include <openssl/asn1.h>
 
@@ -71,15 +72,42 @@ static int cpy_univ(unsigned long value, void *arg);
 static int cpy_utf8(unsigned long value, void *arg);
 static int is_printable(unsigned long value);
 
-/* This function takes a string in UTF8, ASCII or multibyte form and
+/* This is the default mask for the mbstring functions: it is designed
+ * to be a "safe" DirectoryString. Netscape messenger crashes when it
+ * receives a certificate containing a BMPString so by default we don't
+ * use them unless we have to.
+ */
+
+static long dirstring_mask = B_ASN1_PRINTABLESTRING
+                               | B_ASN1_T61STRING | B_ASN1_BMPSTRING;
+
+void ASN1_STRING_set_default_mask(unsigned long mask)
+{
+       dirstring_mask = mask;
+}
+
+unsigned long ASN1_STRING_get_default_mask(void)
+{
+       return dirstring_mask;
+}
+
+/* These functions take a string in UTF8, ASCII or multibyte form and
  * a mask of permissible ASN1 string types. It then works out the minimal
  * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
  * and creates a string of the correct type with the supplied data.
  * Yes this is horrible: it has to be :-(
+ * The 'ncopy' form checks minimum and maximum size limits too.
  */
 
 int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
-                      int inform, unsigned long mask)
+                                       int inform, unsigned long mask)
+{
+       return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
+}
+
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+                                       int inform, unsigned long mask, 
+                                       long minsize, long maxsize)
 {
        int str_type;
        int ret;
@@ -87,8 +115,10 @@ int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
        ASN1_STRING *dest;
        unsigned char *p;
        int nchar;
-       int (*cpyfunc)(unsigned long value, void *in_) = NULL;
+       unsigned char strbuf[32];
+       int (*cpyfunc)(unsigned long,void *) = NULL;
        if(len == -1) len = strlen((const char *)in);
+       if(!mask) mask = dirstring_mask;
 
        /* First do a string check and work out the number of characters */
        switch(inform) {
@@ -113,6 +143,7 @@ int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
 
                case MBSTRING_UTF8:
                nchar = 0;
+               /* This counts the characters and does utf8 syntax checking */
                ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
                if(ret < 0) {
                        ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
@@ -130,12 +161,27 @@ int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
                return -1;
        }
 
+       if(minsize && (nchar < minsize)) {
+               ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_SHORT);
+               sprintf(strbuf, "%ld", minsize);
+               ERR_add_error_data(2, "minsize=", strbuf);
+               return -1;
+       }
+
+       if(maxsize && (nchar > maxsize)) {
+               ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_LONG);
+               sprintf(strbuf, "%ld", maxsize);
+               ERR_add_error_data(2, "maxsize=", strbuf);
+               return -1;
+       }
+
        /* Now work out minimal type (if any) */
        if(traverse_string(in, len, inform, type_str, &mask) < 0) {
                ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_ILLEGAL_CHARACTERS);
                return -1;
        }
 
+
        /* Now work out output format and string type */
        outform = MBSTRING_ASC;
        if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
@@ -152,15 +198,26 @@ int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
                outform = MBSTRING_UTF8;
        }
        if(!out) return str_type;
-       if(!(dest = ASN1_STRING_type_new(str_type))) {
-               ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ERR_R_MALLOC_FAILURE);
-               return -1;
+       if(*out) {
+               dest = *out;
+               if(dest->data) {
+                       dest->length = 0;
+                       Free(dest->data);
+                       dest->data = NULL;
+               }
+               dest->type = str_type;
+       } else {
+               dest = ASN1_STRING_type_new(str_type);
+               if(!dest) {
+                       ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
+                                                       ERR_R_MALLOC_FAILURE);
+                       return -1;
+               }
+               *out = dest;
        }
-       *out = dest;
        /* If both the same type just copy across */
        if(inform == outform) {
                if(!ASN1_STRING_set(dest, in, len)) {
-                       ASN1_STRING_free(dest);
                        ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE);
                        return -1;
                }
diff --git a/crypto/asn1/a_strnid.c b/crypto/asn1/a_strnid.c
new file mode 100644 (file)
index 0000000..520b118
--- /dev/null
@@ -0,0 +1,200 @@
+/* a_strnid.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 <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+
+
+static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
+static void st_free(ASN1_STRING_TABLE *tbl);
+static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b);
+
+/* The following function generates an ASN1_STRING based on limits in a table.
+ * Frequently the types and length of an ASN1_STRING are restricted by a 
+ * corresponding OID. For example certificates and certificate requests.
+ */
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
+                                       int inlen, int inform, int nid)
+{
+       ASN1_STRING_TABLE *tbl;
+       ASN1_STRING *str = NULL;
+       int ret;
+       if(!out) out = &str;
+       if(!stable) ASN1_STRING_TABLE_add_standard();
+       tbl = ASN1_STRING_TABLE_get(nid);
+       if(tbl) ret = ASN1_mbstring_ncopy(out, in, inlen, inform, tbl->mask,
+                                       tbl->minsize, tbl->maxsize);
+       else ret = ASN1_mbstring_copy(out, in, inlen, inform, 0);
+       if(ret <= 0) return NULL;
+       return str;
+}
+
+/* Now the tables and helper functions for the string table:
+ */
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+#define ub_name                                32768
+#define ub_common_name                 64
+#define ub_locality_name               128
+#define ub_state_name                  128
+#define ub_organization_name           64
+#define ub_organization_unit_name      64
+#define ub_title                       64
+#define ub_email_address               128
+
+static ASN1_STRING_TABLE tbl_standard[] = {
+{NID_name,                     1, ub_name, 0, 0},
+{NID_surname,                  1, ub_name, 0, 0},
+{NID_givenName,                        1, ub_name, 0, 0},
+{NID_initials,                 1, ub_name, 0, 0},
+{NID_commonName,               1, ub_common_name, 0, 0},
+{NID_localityName,             1, ub_locality_name, 0, 0},
+{NID_stateOrProvinceName,      1, ub_state_name, 0, 0},
+{NID_organizationName,         1, ub_organization_name, 0, 0},
+{NID_organizationalUnitName,   1, ub_organization_unit_name, 0, 0},
+{NID_dnQualifier,              -1, -1, B_ASN1_PRINTABLESTRING, 0},
+{NID_countryName,              2, 2, B_ASN1_PRINTABLESTRING, 0},
+{NID_pkcs9_emailAddress,       1, ub_email_address, B_ASN1_IA5STRING, 0},
+{NID_undef, 0, 0, 0, 0}
+};
+
+int ASN1_STRING_TABLE_add_standard(void)
+{
+       static int done = 0;
+       ASN1_STRING_TABLE *tmp;
+       if(done) return 1;
+       if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+       if(!stable) {
+               ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD_STANDARD,
+                                               ERR_R_MALLOC_FAILURE);
+               return 0;
+       }
+       for(tmp = tbl_standard; tmp->nid != NID_undef; tmp++) {
+               if(!sk_ASN1_STRING_TABLE_push(stable, tmp)) {
+                       ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD_STANDARD,
+                                                       ERR_R_MALLOC_FAILURE);
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b)
+{
+       return (*a)->nid - (*b)->nid;
+}
+
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
+{
+       int idx;
+       ASN1_STRING_TABLE fnd;
+       fnd.nid = nid;
+       idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
+       if(idx < 0) return NULL;
+       return sk_ASN1_STRING_TABLE_value(stable, idx);
+}
+       
+int ASN1_STRING_TABLE_add(int nid,
+                long minsize, long maxsize, unsigned long mask,
+                               unsigned long flags)
+{
+       ASN1_STRING_TABLE *tmp;
+       char new_nid = 0;
+       if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+       if(!stable) {
+               ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
+               return 0;
+       }
+       if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
+               tmp = Malloc(sizeof(ASN1_STRING_TABLE));
+               if(!tmp) {
+                       ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD,
+                                                       ERR_R_MALLOC_FAILURE);
+                       return 0;
+               }
+               tmp->flags = STABLE_FLAGS_MALLOC;
+               tmp->nid = nid;
+               new_nid = 1;
+       }
+       if(minsize != -1) tmp->minsize = minsize;
+       if(maxsize != -1) tmp->maxsize = maxsize;
+       tmp->mask = mask;
+       tmp->flags = flags & ~STABLE_FLAGS_MALLOC;
+       if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
+       return 1;
+}
+
+void ASN1_STRING_TABLE_cleanup(void)
+{
+       STACK_OF(ASN1_STRING_TABLE) *tmp;
+       tmp = stable;
+       stable = NULL;
+       sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
+}
+
+static void st_free(ASN1_STRING_TABLE *tbl)
+{
+       if(tbl->flags & STABLE_FLAGS_MALLOC) Free(tbl);
+}
+
+IMPLEMENT_STACK_OF(ASN1_STRING_TABLE)
index fb20073..2a7da6b 100644 (file)
@@ -130,10 +130,11 @@ extern "C" {
 #define B_ASN1_UTF8STRING      0x2000
 
 /* For use with ASN1_mbstring_copy() */
-#define MBSTRING_ASC           1
-#define MBSTRING_BMP           2
-#define MBSTRING_UNIV          3
-#define MBSTRING_UTF8          4
+#define MBSTRING_FLAG          0x1000
+#define MBSTRING_ASC           (MBSTRING_FLAG|1)
+#define MBSTRING_BMP           (MBSTRING_FLAG|2)
+#define MBSTRING_UNIV          (MBSTRING_FLAG|3)
+#define MBSTRING_UTF8          (MBSTRING_FLAG|4)
 
 #define DECLARE_ASN1_SET_OF(type) \
 int i2d_ASN1_SET_OF_##type(STACK_OF(type) *a,unsigned char **pp, \
@@ -206,6 +207,29 @@ typedef struct asn1_string_st
        long flags;
        } ASN1_STRING;
 
+#define STABLE_FLAGS_MALLOC    0x01
+
+typedef struct asn1_string_table_st {
+       int nid;
+       long minsize;
+       long maxsize;
+       unsigned long mask;
+       unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DECLARE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+#define ub_name                                32768
+#define ub_common_name                 64
+#define ub_locality_name               128
+#define ub_state_name                  128
+#define ub_organization_name           64
+#define ub_organization_unit_name      64
+#define ub_title                       64
+#define ub_email_address               128
+
 #ifndef DEBUG
 #define ASN1_INTEGER           ASN1_STRING
 #define ASN1_ENUMERATED                ASN1_STRING
@@ -718,8 +742,20 @@ unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf,
                                                                 int *len );
 void *ASN1_unpack_string(ASN1_STRING *oct, char *(*d2i)());
 ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+unsigned long ASN1_STRING_get_default_mask(void);
 int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
                                        int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+                                       int inform, unsigned long mask, 
+                                       long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, 
+               const unsigned char *in, int inlen, int inform, int nid);
+int ASN1_STRING_TABLE_add_standard(void);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+void ASN1_STRING_TABLE_cleanup(void);
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -754,6 +790,8 @@ int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
 #define ASN1_F_ASN1_SEQ_UNPACK                          247
 #define ASN1_F_ASN1_SIGN                                114
 #define ASN1_F_ASN1_STRING_NEW                          115
+#define ASN1_F_ASN1_STRING_TABLE_ADD                    283
+#define ASN1_F_ASN1_STRING_TABLE_ADD_STANDARD           284
 #define ASN1_F_ASN1_STRING_TYPE_NEW                     116
 #define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING            117
 #define ASN1_F_ASN1_TYPE_GET_OCTETSTRING                118
@@ -959,6 +997,7 @@ int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
 #define ASN1_R_PRIVATE_KEY_HEADER_MISSING               131
 #define ASN1_R_SECOND_NUMBER_TOO_LARGE                  132
 #define ASN1_R_SHORT_LINE                               133
+#define ASN1_R_STRING_TOO_LONG                          163
 #define ASN1_R_STRING_TOO_SHORT                                 134
 #define ASN1_R_TAG_VALUE_TOO_HIGH                       135
 #define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 136
index f1a142d..3b1fb7b 100644 (file)
@@ -90,6 +90,8 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_PACK(0,ASN1_F_ASN1_SEQ_UNPACK,0), "ASN1_seq_unpack"},
 {ERR_PACK(0,ASN1_F_ASN1_SIGN,0),       "ASN1_sign"},
 {ERR_PACK(0,ASN1_F_ASN1_STRING_NEW,0), "ASN1_STRING_new"},
+{ERR_PACK(0,ASN1_F_ASN1_STRING_TABLE_ADD,0),   "ASN1_STRING_TABLE_ADD"},
+{ERR_PACK(0,ASN1_F_ASN1_STRING_TABLE_ADD_STANDARD,0),  "ASN1_STRING_TABLE_add_standard"},
 {ERR_PACK(0,ASN1_F_ASN1_STRING_TYPE_NEW,0),    "ASN1_STRING_type_new"},
 {ERR_PACK(0,ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,0),   "ASN1_TYPE_get_int_octetstring"},
 {ERR_PACK(0,ASN1_F_ASN1_TYPE_GET_OCTETSTRING,0),       "ASN1_TYPE_get_octetstring"},
@@ -298,6 +300,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ASN1_R_PRIVATE_KEY_HEADER_MISSING       ,"private key header missing"},
 {ASN1_R_SECOND_NUMBER_TOO_LARGE          ,"second number too large"},
 {ASN1_R_SHORT_LINE                       ,"short line"},
+{ASN1_R_STRING_TOO_LONG                  ,"string too long"},
 {ASN1_R_STRING_TOO_SHORT                 ,"string too short"},
 {ASN1_R_TAG_VALUE_TOO_HIGH               ,"tag value too high"},
 {ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD,"the asn1 object identifier is not known for this md"},
index 95ead04..f249dae 100644 (file)
@@ -612,6 +612,9 @@ int         EVP_PKEY_type(int type);
 int            EVP_PKEY_bits(EVP_PKEY *pkey);
 int            EVP_PKEY_size(EVP_PKEY *pkey);
 int            EVP_PKEY_assign(EVP_PKEY *pkey,int type,char *key);
+RSA *          EVP_PKEY_get_RSA(EVP_PKEY *pkey);
+DSA *          EVP_PKEY_get_DSA(EVP_PKEY *pkey);
+DH *           EVP_PKEY_get_DH(EVP_PKEY *pkey);
 EVP_PKEY *     EVP_PKEY_new(void);
 void           EVP_PKEY_free(EVP_PKEY *pkey);
 EVP_PKEY *     d2i_PublicKey(int type,EVP_PKEY **a, unsigned char **pp,
@@ -676,6 +679,9 @@ void EVP_PBE_cleanup(void);
 #define EVP_F_EVP_PKEY_COPY_PARAMETERS                  103
 #define EVP_F_EVP_PKEY_DECRYPT                          104
 #define EVP_F_EVP_PKEY_ENCRYPT                          105
+#define EVP_F_EVP_PKEY_GET_DH                           119
+#define EVP_F_EVP_PKEY_GET_DSA                          120
+#define EVP_F_EVP_PKEY_GET_RSA                          121
 #define EVP_F_EVP_PKEY_NEW                              106
 #define EVP_F_EVP_SIGNFINAL                             107
 #define EVP_F_EVP_VERIFYFINAL                           108
@@ -692,6 +698,9 @@ void EVP_PBE_cleanup(void);
 #define EVP_R_DIFFERENT_KEY_TYPES                       101
 #define EVP_R_ENCODE_ERROR                              115
 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR                  119
+#define EVP_R_EXPECTING_AN_RSA_KEY                      127
+#define EVP_R_EXPECTING_A_DH_KEY                        128
+#define EVP_R_EXPECTING_A_DSA_KEY                       129
 #define EVP_R_INPUT_NOT_INITIALIZED                     111
 #define EVP_R_IV_TOO_LARGE                              102
 #define EVP_R_KEYGEN_FAILURE                            120
index c61cc92..7d21938 100644 (file)
@@ -77,6 +77,9 @@ static ERR_STRING_DATA EVP_str_functs[]=
 {ERR_PACK(0,EVP_F_EVP_PKEY_COPY_PARAMETERS,0), "EVP_PKEY_copy_parameters"},
 {ERR_PACK(0,EVP_F_EVP_PKEY_DECRYPT,0), "EVP_PKEY_decrypt"},
 {ERR_PACK(0,EVP_F_EVP_PKEY_ENCRYPT,0), "EVP_PKEY_encrypt"},
+{ERR_PACK(0,EVP_F_EVP_PKEY_GET_DH,0),  "EVP_PKEY_get_DH"},
+{ERR_PACK(0,EVP_F_EVP_PKEY_GET_DSA,0), "EVP_PKEY_get_DSA"},
+{ERR_PACK(0,EVP_F_EVP_PKEY_GET_RSA,0), "EVP_PKEY_get_RSA"},
 {ERR_PACK(0,EVP_F_EVP_PKEY_NEW,0),     "EVP_PKEY_new"},
 {ERR_PACK(0,EVP_F_EVP_SIGNFINAL,0),    "EVP_SignFinal"},
 {ERR_PACK(0,EVP_F_EVP_VERIFYFINAL,0),  "EVP_VerifyFinal"},
@@ -96,6 +99,9 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {EVP_R_DIFFERENT_KEY_TYPES               ,"different key types"},
 {EVP_R_ENCODE_ERROR                      ,"encode error"},
 {EVP_R_EVP_PBE_CIPHERINIT_ERROR          ,"evp pbe cipherinit error"},
+{EVP_R_EXPECTING_AN_RSA_KEY              ,"expecting an rsa key"},
+{EVP_R_EXPECTING_A_DH_KEY                ,"expecting a dh key"},
+{EVP_R_EXPECTING_A_DSA_KEY               ,"expecting a dsa key"},
 {EVP_R_INPUT_NOT_INITIALIZED             ,"input not initialized"},
 {EVP_R_IV_TOO_LARGE                      ,"iv too large"},
 {EVP_R_KEYGEN_FAILURE                    ,"keygen failure"},
index 3422b77..dba0852 100644 (file)
@@ -205,6 +205,42 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key)
        return(1);
        }
 
+#ifndef NO_RSA
+RSA *EVP_PKEY_get_RSA(EVP_PKEY *pkey)
+       {
+       if(pkey->type != EVP_PKEY_RSA) {
+               EVPerr(EVP_F_EVP_PKEY_GET_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+               return NULL;
+       }
+       CRYPTO_add(&pkey->pkey.rsa->references, 1, CRYPTO_LOCK_RSA);
+       return pkey->pkey.rsa;
+}
+#endif
+
+#ifndef NO_DSA
+DSA *EVP_PKEY_get_DSA(EVP_PKEY *pkey)
+       {
+       if(pkey->type != EVP_PKEY_DSA) {
+               EVPerr(EVP_F_EVP_PKEY_GET_DSA, EVP_R_EXPECTING_A_DSA_KEY);
+               return NULL;
+       }
+       CRYPTO_add(&pkey->pkey.rsa->references, 1, CRYPTO_LOCK_DSA);
+       return pkey->pkey.dsa;
+}
+#endif
+
+#ifndef NO_DH
+DH *EVP_PKEY_get_DH(EVP_PKEY *pkey)
+       {
+       if(pkey->type != EVP_PKEY_DH) {
+               EVPerr(EVP_F_EVP_PKEY_GET_DH, EVP_R_EXPECTING_A_DH_KEY);
+               return NULL;
+       }
+       CRYPTO_add(&pkey->pkey.dh->references, 1, CRYPTO_LOCK_DH);
+       return pkey->pkey.dh;
+}
+#endif
+
 int EVP_PKEY_type(int type)
        {
        switch (type)
index f0bc597..88a8995 100644 (file)
  * perl obj_dat.pl objects.h obj_dat.h
  */
 
-#define NUM_NID 173
-#define NUM_SN 121
-#define NUM_LN 169
-#define NUM_OBJ 144
+#define NUM_NID 175
+#define NUM_SN 123
+#define NUM_LN 171
+#define NUM_OBJ 146
 
-static unsigned char lvalues[1005]={
+static unsigned char lvalues[1011]={
 0x00,                                        /* [  0] OBJ_undef */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  1] OBJ_rsadsi */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  7] OBJ_pkcs */
@@ -211,6 +211,8 @@ static unsigned char lvalues[1005]={
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [976] OBJ_pbeWithSHA1AndDES_CBC */
 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [985] OBJ_ms_ext_req */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [995] OBJ_ext_req */
+0x55,0x04,0x29,                              /* [1004] OBJ_name */
+0x55,0x04,0x2E,                              /* [1007] OBJ_dnQualifier */
 };
 
 static ASN1_OBJECT nid_objs[NUM_NID]={
@@ -456,6 +458,8 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
 {"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10,
        &(lvalues[985]),0},
 {"extReq","Extension Request",NID_ext_req,9,&(lvalues[995]),0},
+{"name","name",NID_name,3,&(lvalues[1004]),0},
+{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1007]),0},
 };
 
 static ASN1_OBJECT *sn_objs[NUM_SN]={
@@ -547,6 +551,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
 &(nid_objs[103]),/* "crlDistributionPoints" */
 &(nid_objs[88]),/* "crlNumber" */
 &(nid_objs[140]),/* "deltaCRL" */
+&(nid_objs[174]),/* "dnQualifier" */
 &(nid_objs[132]),/* "emailProtection" */
 &(nid_objs[172]),/* "extReq" */
 &(nid_objs[126]),/* "extendedKeyUsage" */
@@ -563,6 +568,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
 &(nid_objs[138]),/* "msEFS" */
 &(nid_objs[171]),/* "msExtReq" */
 &(nid_objs[137]),/* "msSGC" */
+&(nid_objs[173]),/* "name" */
 &(nid_objs[72]),/* "nsBaseUrl" */
 &(nid_objs[76]),/* "nsCaPolicyUrl" */
 &(nid_objs[74]),/* "nsCaRevocationUrl" */
@@ -661,6 +667,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[107]),/* "description" */
 &(nid_objs[80]),/* "desx-cbc" */
 &(nid_objs[28]),/* "dhKeyAgreement" */
+&(nid_objs[174]),/* "dnQualifier" */
 &(nid_objs[116]),/* "dsaEncryption" */
 &(nid_objs[67]),/* "dsaEncryption-old" */
 &(nid_objs[66]),/* "dsaWithSHA" */
@@ -688,6 +695,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[95]),/* "mdc2" */
 &(nid_objs[96]),/* "mdc2withRSA" */
 &(nid_objs[51]),/* "messageDigest" */
+&(nid_objs[173]),/* "name" */
 &(nid_objs[17]),/* "organizationName" */
 &(nid_objs[18]),/* "organizationalUnitName" */
 &(nid_objs[ 9]),/* "pbeWithMD2AndDES-CBC" */
@@ -770,9 +778,11 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
 &(nid_objs[18]),/* OBJ_organizationalUnitName       2 5 4 11 */
 &(nid_objs[106]),/* OBJ_title                        2 5 4 12 */
 &(nid_objs[107]),/* OBJ_description                  2 5 4 13 */
+&(nid_objs[173]),/* OBJ_name                         2 5 4 41 */
 &(nid_objs[99]),/* OBJ_givenName                    2 5 4 42 */
 &(nid_objs[101]),/* OBJ_initials                     2 5 4 43 */
 &(nid_objs[102]),/* OBJ_uniqueIdentifier             2 5 4 45 */
+&(nid_objs[174]),/* OBJ_dnQualifier                  2 5 4 46 */
 &(nid_objs[82]),/* OBJ_subject_key_identifier       2 5 29 14 */
 &(nid_objs[83]),/* OBJ_key_usage                    2 5 29 15 */
 &(nid_objs[84]),/* OBJ_private_key_usage_period     2 5 29 16 */
index e2587a8..bbbef90 100644 (file)
@@ -902,6 +902,16 @@ extern "C" {
 #define NID_ext_req                    172
 #define OBJ_ext_req                    OBJ_pkcs9,14L
 
+#define SN_name                                "name"
+#define LN_name                                "name"
+#define NID_name                       173
+#define OBJ_name                       OBJ_X509,41L
+
+#define SN_dnQualifier                 "dnQualifier"
+#define LN_dnQualifier                 "dnQualifier"
+#define NID_dnQualifier                        174
+#define OBJ_dnQualifier                        OBJ_X509,46L
+
 #include <openssl/bio.h>
 #include <openssl/asn1.h>
 
index 90f0201..3c86a23 100644 (file)
@@ -179,7 +179,12 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x,
 
        for (;;)
                {
-               if (!PEM_read_bio(bp,&nm,&header,&data,&len)) return(NULL);
+               if (!PEM_read_bio(bp,&nm,&header,&data,&len)) {
+                       if(ERR_GET_REASON(ERR_peek_error()) ==
+                               PEM_R_NO_START_LINE)
+                               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)) ||
index 2a422be..64c1315 100644 (file)
@@ -267,7 +267,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
                goto err;
        if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len))
                goto err;
-       
+
        if ((ne != NULL) && (*ne == NULL)) *ne=ret;
        return(ret);
 err:
@@ -294,6 +294,10 @@ int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
        int i;
 
        if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0);
+       if(type & MBSTRING_FLAG) 
+               return ASN1_STRING_set_by_NID(&ne->value, bytes,
+                                               len, type,
+                                       OBJ_obj2nid(ne->object)) ? 1 : 0;
        if (len < 0) len=strlen((char *)bytes);
        i=ASN1_STRING_set(ne->value,bytes,len);
        if (!i) return(0);
index 2a84be4..08e2476 100644 (file)
@@ -345,6 +345,11 @@ use, in particular some usages may only work for selected CAs. Don't for example
 expect just including msSGC or nsSGC will automatically mean that a certificate
 can be used for SGC ("step up" encryption) otherwise anyone could use it.
 
+Examples:
+
+extendedKeyUsage=critical,codeSigning,1.2.3.4
+extendedKeyUsage=nsSGC,msSGC
+
 Subject Key Identifier.
 
 This is really a string extension and can take two possible values. Either
index dc32e9b..6bdee9c 100755 (executable)
@@ -1963,3 +1963,32 @@ i2d_DSAPublicKey_bio                    1987
 ASN1_STRING_length_set                  1988
 DIRECTORYSTRING_new                     1989
 ASN1_mbstring_copy                      1990
+sk_ASN1_STRING_TABLE_value              1991
+sk_ASN1_STRING_TABLE_pop                1992
+sk_ASN1_STRING_TABLE_num                1993
+sk_ASN1_STRING_TABLE_delete_ptr         1994
+sk_ASN1_STRING_TABLE_sort               1995
+ASN1_STRING_set_by_NID                  1996
+sk_ASN1_STRING_TABLE_pop_free           1997
+sk_ASN1_STRING_TABLE_unshift            1998
+ASN1_STRING_TABLE_cleanup               1999
+ASN1_STRING_set_default_mask            2000
+sk_ASN1_STRING_TABLE_insert             2001
+sk_ASN1_STRING_TABLE_free               2002
+sk_ASN1_STRING_TABLE_set                2003
+ASN1_STRING_TABLE_add_standard          2004
+sk_ASN1_STRING_TABLE_set_cmp_func       2005
+ASN1_STRING_get_default_mask            2006
+ASN1_STRING_TABLE_get                   2007
+sk_ASN1_STRING_TABLE_delete             2008
+sk_ASN1_STRING_TABLE_zero               2009
+sk_ASN1_STRING_TABLE_shift              2010
+sk_ASN1_STRING_TABLE_new_null           2011
+sk_ASN1_STRING_TABLE_push               2012
+sk_ASN1_STRING_TABLE_dup                2013
+ASN1_mbstring_ncopy                     2014
+sk_ASN1_STRING_TABLE_find               2015
+sk_ASN1_STRING_TABLE_new                2016
+EVP_PKEY_get_RSA                        2017
+EVP_PKEY_get_DH                         2018
+EVP_PKEY_get_DSA                        2019