X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Fa_mbstr.c;h=8c38e19963b83a5fb9ef4e9a3cbf7b7699e1160d;hp=ddb27980696f84b789a54660136e7d36521bfac6;hb=ee7fb55e88545e683b91e6fd0d661c13b4719529;hpb=75ebbd9aa411c5b8b19ded6ace2b34181566b56a diff --git a/crypto/asn1/a_mbstr.c b/crypto/asn1/a_mbstr.c index ddb2798069..8c38e19963 100644 --- a/crypto/asn1/a_mbstr.c +++ b/crypto/asn1/a_mbstr.c @@ -1,4 +1,3 @@ -/* a_mbstr.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -59,7 +58,7 @@ #include #include -#include "cryptlib.h" +#include "internal/cryptlib.h" #include static int traverse_string(const unsigned char *p, int len, int inform, @@ -72,13 +71,14 @@ 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_numeric(unsigned long value); static int is_printable(unsigned long value); /* * 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 + * (using the order Numeric < 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. */ @@ -169,7 +169,9 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, /* Now work out output format and string type */ outform = MBSTRING_ASC; - if (mask & B_ASN1_PRINTABLESTRING) + if (mask & B_ASN1_NUMERICSTRING) + str_type = V_ASN1_NUMERICSTRING; + else if (mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING; else if (mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING; @@ -197,7 +199,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, } else { free_out = 1; dest = ASN1_STRING_type_new(str_type); - if (!dest) { + if (dest == NULL) { ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); return -1; } @@ -320,6 +322,8 @@ static int type_str(unsigned long value, void *arg) { unsigned long types; types = *((unsigned long *)arg); + if ((types & B_ASN1_NUMERICSTRING) && !is_numeric(value)) + types &= ~B_ASN1_NUMERICSTRING; if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value)) types &= ~B_ASN1_PRINTABLESTRING; if ((types & B_ASN1_IA5STRING) && (value > 127)) @@ -419,3 +423,22 @@ static int is_printable(unsigned long value) #endif /* CHARSET_EBCDIC */ return 0; } + +/* Return 1 if the character is a digit or space */ +static int is_numeric(unsigned long value) +{ + int ch; + if (value > 0x7f) + return 0; + ch = (int)value; +#ifndef CHARSET_EBCDIC + if (!isdigit(ch) && ch != ' ') + return 0; +#else + if (ch > os_toascii['9']) + return 0; + if (ch < os_toascii['0'] && ch != os_toascii[' ']) + return 0; +#endif + return 1; +}