Commit 462f79ec authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

New function ASN1_mbstring_copy() to handle ASN1 string copying. Ultimately

this will be used to clear up the horrible DN mess.
parent 08e9c1af
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -4,6 +4,13 @@

 Changes between 0.9.4 and 0.9.5  [xx XXX 1999]

  *) New function ASN1_mbstring_copy() this copies a string in either
     ASCII, Unicode, Universal (4 bytes per character) or UTF8 format
     into an ASN1_STRING type. A mask of permissible types is passed
     and it chooses the "minimal" type to use or an error if not type
     is suitable.
     [Steve Henson]

  *) Add function equivalents to the various macros in asn1.h. The old
     macros are retained with an M_ prefix. Code inside the library can
     use the M_ macros. External code (including the openssl utility)
+9 −2
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ APPS=
LIB=$(TOP)/libcrypto.a
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_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 \
	d2i_r_pr.c i2d_r_pr.c d2i_r_pu.c i2d_r_pu.c \
@@ -39,7 +39,7 @@ LIBSRC= a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.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 \
	a_enum.o a_vis.o a_utf8.o a_sign.o a_digest.o a_verify.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 \
	d2i_r_pr.o i2d_r_pr.o d2i_r_pu.o i2d_r_pu.o \
@@ -209,6 +209,13 @@ a_int.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
a_int.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
a_int.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
a_int.o: ../cryptlib.h
a_mbstr.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
a_mbstr.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
a_mbstr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os.h
a_mbstr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
a_mbstr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
a_mbstr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
a_mbstr.o: ../cryptlib.h
a_meth.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
a_meth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
a_meth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os.h

crypto/asn1/a_mbstr.c

0 → 100644
+352 −0
Original line number Diff line number Diff line
/* a_mbstr.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/asn1.h>

static int traverse_string(unsigned char *p, int len, int inform,
		 int (*rfunc)(unsigned long value, void *in), void *arg);
static int in_utf8(unsigned long value, void *arg);
static int out_utf8(unsigned long value, void *arg);
static int type_str(unsigned long value, void *arg);
static int cpy_asc(unsigned long value, void *arg);
static int cpy_bmp(unsigned long value, void *arg);
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
 * 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 :-(
 */

int ASN1_mbstring_copy(ASN1_STRING **out, unsigned char *in, int len,
					int inform, unsigned long mask)
{
	int str_type;
	int ret;
	int outform, outlen;
	ASN1_STRING *dest;
	unsigned char *p;
	int nchar;
	int (*cpyfunc)(unsigned long value, void *in) = NULL;
	if(len == -1) len = strlen(in);

	/* First do a string check and work out the number of characters */
	switch(inform) {

		case MBSTRING_BMP:
		if(len & 1) {
			ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
					 ASN1_R_INVALID_BMPSTRING_LENGTH);
			return -1;
		}
		nchar = len >> 1;
		break;

		case MBSTRING_UNIV:
		if(len & 3) {
			ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
					 ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
			return -1;
		}
		nchar = len >> 2;
		break;

		case MBSTRING_UTF8:
		nchar = 0;
		ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
		if(ret < 0) {
			ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
						 ASN1_R_INVALID_UTF8STRING);
			return -1;
		}
		break;

		case MBSTRING_ASC:
		nchar = len;
		break;

		default:
		ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_UNKNOWN_FORMAT);
		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;
	else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
	else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
	else if(mask & B_ASN1_BMPSTRING) {
		str_type = V_ASN1_BMPSTRING;
		outform = MBSTRING_BMP;
	} else if(mask & B_ASN1_UNIVERSALSTRING) {
		str_type = V_ASN1_UNIVERSALSTRING;
		outform = MBSTRING_UNIV;
	} else {
		str_type = V_ASN1_UTF8STRING;
		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;
	}
	*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;
		}
		return str_type;
	} 

	/* Work out how much space the destination will need */
	switch(outform) {
		case MBSTRING_ASC:
		outlen = nchar;
		cpyfunc = cpy_asc;
		break;

		case MBSTRING_BMP:
		outlen = nchar << 1;
		cpyfunc = cpy_bmp;
		break;

		case MBSTRING_UNIV:
		outlen = nchar << 2;
		cpyfunc = cpy_univ;
		break;

		case MBSTRING_UTF8:
		outlen = 0;
		traverse_string(in, len, inform, out_utf8, &outlen);
		cpyfunc = cpy_utf8;
		break;
	}
	if(!(p = Malloc(outlen + 1))) {
		ASN1_STRING_free(dest);
		ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE);
		return -1;
	}
	dest->length = outlen;
	dest->data = p;
	p[outlen] = 0;
	traverse_string(in, len, inform, cpyfunc, &p);
	return str_type;	
}

/* This function traverses a string and passes the value of each character
 * to an optional function along with a void * argument.
 */

static int traverse_string(unsigned char *p, int len, int inform,
		 int (*rfunc)(unsigned long value, void *in), void *arg)
{
	unsigned long value;
	int ret;
	while(len) {
		if(inform == MBSTRING_ASC) {
			value = *p++;
			len--;
		} else if(inform == MBSTRING_BMP) {
			value = *p++ << 8;
			value |= *p++;
			len -= 2;
		} else if(inform == MBSTRING_UNIV) {
			value = *p++ << 24;
			value |= *p++ << 16;
			value |= *p++ << 8;
			value |= *p++;
			len -= 4;
		} else {
			ret = UTF8_getc(p, len, &value);
			if(ret < 0) return -1;
			len -= ret;
			p += ret;
		}
		if(rfunc) {
			ret = rfunc(value, arg);
			if(ret <= 0) return ret;
		}
	}
	return 1;
}

/* Various utility functions for traverse_string */

/* Just count number of characters */

static int in_utf8(unsigned long value, void *arg)
{
	int *nchar;
	nchar = arg;
	(*nchar)++;
	return 1;
}

/* Determine size of output as a UTF8 String */

static int out_utf8(unsigned long value, void *arg)
{
	long *outlen;
	outlen = arg;
	*outlen += UTF8_putc(NULL, -1, value);
	return 1;
}

/* Determine the "type" of a string: check each character against a
 * supplied "mask".
 */

static int type_str(unsigned long value, void *arg)
{
	unsigned long types;
	types = *((unsigned long *)arg);
	if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
					types &= ~B_ASN1_PRINTABLESTRING;
	if((types & B_ASN1_IA5STRING) && (value > 127))
					types &= ~B_ASN1_IA5STRING;
	if((types & B_ASN1_T61STRING) && (value > 0xff))
					types &= ~B_ASN1_T61STRING;
	if((types & B_ASN1_BMPSTRING) && (value > 0xffff))
					types &= ~B_ASN1_BMPSTRING;
	if(!types) return -1;
	*((unsigned long *)arg) = types;
	return 1;
}

/* Copy one byte per character ASCII like strings */

static int cpy_asc(unsigned long value, void *arg)
{
	unsigned char **p, *q;
	p = arg;
	q = *p;
	*q = (unsigned char) value;
	(*p)++;
	return 1;
}

/* Copy two byte per character BMPStrings */

static int cpy_bmp(unsigned long value, void *arg)
{
	unsigned char **p, *q;
	p = arg;
	q = *p;
	*q++ = (unsigned char) ((value >> 8) & 0xff);
	*q = (unsigned char) (value & 0xff);
	*p += 2;
	return 1;
}

/* Copy four byte per character UniversalStrings */

static int cpy_univ(unsigned long value, void *arg)
{
	unsigned char **p, *q;
	p = arg;
	q = *p;
	*q++ = (unsigned char) ((value >> 24) & 0xff);
	*q++ = (unsigned char) ((value >> 16) & 0xff);
	*q++ = (unsigned char) ((value >> 8) & 0xff);
	*q = (unsigned char) (value & 0xff);
	*p += 4;
	return 1;
}

/* Copy to a UTF8String */

static int cpy_utf8(unsigned long value, void *arg)
{
	unsigned char **p;
	int ret;
	p = arg;
	/* We already know there is enough room so pass 0xff as the length */
	ret = UTF8_putc(*p, 0xff, value);
	*p += ret;
	return 1;
}

/* Return 1 if the character is permitted in a PrintableString */
static int is_printable(unsigned long value)
{
	int ch;
	if(value > 0x7f) return 0;
	ch = (int) value;
	/* Note: we can't use 'isalnum' because certain accented 
	 * characters may count as alphanumeric in some environments.
	 */
	if((ch >= 'a') && (ch <= 'z')) return 1;
	if((ch >= 'A') && (ch <= 'Z')) return 1;
	if((ch >= '0') && (ch <= '9')) return 1;
	if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
	return 0;
}
+14 −0
Original line number Diff line number Diff line
@@ -129,6 +129,12 @@ extern "C" {
#define B_ASN1_UNKNOWN		0x1000
#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 DECLARE_ASN1_SET_OF(type) \
int i2d_ASN1_SET_OF_##type(STACK_OF(type) *a,unsigned char **pp, \
			   int (*func)(type *,unsigned char **), int ex_tag, \
@@ -712,6 +718,8 @@ 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);
int ASN1_mbstring_copy(ASN1_STRING **out, unsigned char *in, int len,
					int inform, unsigned long mask);

/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -738,6 +746,7 @@ ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct);
#define ASN1_F_ASN1_I2D_FP				 110
#define ASN1_F_ASN1_INTEGER_SET				 111
#define ASN1_F_ASN1_INTEGER_TO_BN			 112
#define ASN1_F_ASN1_MBSTRING_COPY			 282
#define ASN1_F_ASN1_OBJECT_NEW				 113
#define ASN1_F_ASN1_PACK_STRING				 245
#define ASN1_F_ASN1_PBE_SET				 253
@@ -933,9 +942,13 @@ ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct);
#define ASN1_R_FIRST_NUM_TOO_LARGE			 119
#define ASN1_R_GENERALIZEDTIME_TOO_LONG			 153
#define ASN1_R_HEADER_TOO_LONG				 120
#define ASN1_R_ILLEGAL_CHARACTERS			 158
#define ASN1_R_INVALID_BMPSTRING_LENGTH			 159
#define ASN1_R_INVALID_DIGIT				 121
#define ASN1_R_INVALID_SEPARATOR			 122
#define ASN1_R_INVALID_TIME_FORMAT			 123
#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH		 160
#define ASN1_R_INVALID_UTF8STRING			 161
#define ASN1_R_IV_TOO_LARGE				 124
#define ASN1_R_LENGTH_ERROR				 125
#define ASN1_R_MISSING_SECOND_NUMBER			 126
@@ -953,6 +966,7 @@ ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct);
#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY			 138
#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY		 139
#define ASN1_R_UNKNOWN_ATTRIBUTE_TYPE			 140
#define ASN1_R_UNKNOWN_FORMAT				 162
#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM		 141
#define ASN1_R_UNKNOWN_OBJECT_TYPE			 142
#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE			 143
+8 −2
Original line number Diff line number Diff line
@@ -75,13 +75,14 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_ASN1_DUP,0),	"ASN1_dup"},
{ERR_PACK(0,ASN1_F_ASN1_ENUMERATED_SET,0),	"ASN1_ENUMERATED_set"},
{ERR_PACK(0,ASN1_F_ASN1_ENUMERATED_TO_BN,0),	"ASN1_ENUMERATED_to_BN"},
{ERR_PACK(0,ASN1_F_ASN1_GENERALIZEDTIME_NEW,0),	"ASN1_GENERALIZEDTIME_NEW"},
{ERR_PACK(0,ASN1_F_ASN1_GENERALIZEDTIME_NEW,0),	"ASN1_GENERALIZEDTIME_new"},
{ERR_PACK(0,ASN1_F_ASN1_GET_OBJECT,0),	"ASN1_get_object"},
{ERR_PACK(0,ASN1_F_ASN1_HEADER_NEW,0),	"ASN1_HEADER_new"},
{ERR_PACK(0,ASN1_F_ASN1_I2D_BIO,0),	"ASN1_i2d_bio"},
{ERR_PACK(0,ASN1_F_ASN1_I2D_FP,0),	"ASN1_i2d_fp"},
{ERR_PACK(0,ASN1_F_ASN1_INTEGER_SET,0),	"ASN1_INTEGER_set"},
{ERR_PACK(0,ASN1_F_ASN1_INTEGER_TO_BN,0),	"ASN1_INTEGER_to_BN"},
{ERR_PACK(0,ASN1_F_ASN1_MBSTRING_COPY,0),	"ASN1_mbstring_copy"},
{ERR_PACK(0,ASN1_F_ASN1_OBJECT_NEW,0),	"ASN1_OBJECT_new"},
{ERR_PACK(0,ASN1_F_ASN1_PACK_STRING,0),	"ASN1_pack_string"},
{ERR_PACK(0,ASN1_F_ASN1_PBE_SET,0),	"ASN1_PBE_SET"},
@@ -94,7 +95,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_ASN1_TYPE_GET_OCTETSTRING,0),	"ASN1_TYPE_get_octetstring"},
{ERR_PACK(0,ASN1_F_ASN1_TYPE_NEW,0),	"ASN1_TYPE_new"},
{ERR_PACK(0,ASN1_F_ASN1_UNPACK_STRING,0),	"ASN1_unpack_string"},
{ERR_PACK(0,ASN1_F_ASN1_UTCTIME_NEW,0),	"ASN1_UTCTIME_NEW"},
{ERR_PACK(0,ASN1_F_ASN1_UTCTIME_NEW,0),	"ASN1_UTCTIME_new"},
{ERR_PACK(0,ASN1_F_ASN1_VERIFY,0),	"ASN1_verify"},
{ERR_PACK(0,ASN1_F_AUTHORITY_KEYID_NEW,0),	"AUTHORITY_KEYID_new"},
{ERR_PACK(0,ASN1_F_BASIC_CONSTRAINTS_NEW,0),	"BASIC_CONSTRAINTS_new"},
@@ -280,9 +281,13 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ASN1_R_FIRST_NUM_TOO_LARGE              ,"first num too large"},
{ASN1_R_GENERALIZEDTIME_TOO_LONG         ,"generalizedtime too long"},
{ASN1_R_HEADER_TOO_LONG                  ,"header too long"},
{ASN1_R_ILLEGAL_CHARACTERS               ,"illegal characters"},
{ASN1_R_INVALID_BMPSTRING_LENGTH         ,"invalid bmpstring length"},
{ASN1_R_INVALID_DIGIT                    ,"invalid digit"},
{ASN1_R_INVALID_SEPARATOR                ,"invalid separator"},
{ASN1_R_INVALID_TIME_FORMAT              ,"invalid time format"},
{ASN1_R_INVALID_UNIVERSALSTRING_LENGTH   ,"invalid universalstring length"},
{ASN1_R_INVALID_UTF8STRING               ,"invalid utf8string"},
{ASN1_R_IV_TOO_LARGE                     ,"iv too large"},
{ASN1_R_LENGTH_ERROR                     ,"length error"},
{ASN1_R_MISSING_SECOND_NUMBER            ,"missing second number"},
@@ -300,6 +305,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ASN1_R_UNABLE_TO_DECODE_RSA_KEY         ,"unable to decode rsa key"},
{ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY ,"unable to decode rsa private key"},
{ASN1_R_UNKNOWN_ATTRIBUTE_TYPE           ,"unknown attribute type"},
{ASN1_R_UNKNOWN_FORMAT                   ,"unknown format"},
{ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM ,"unknown message digest algorithm"},
{ASN1_R_UNKNOWN_OBJECT_TYPE              ,"unknown object type"},
{ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE          ,"unknown public key type"},
Loading