Commit c6718437 authored by Dr. Matthias St. Pierre's avatar Dr. Matthias St. Pierre
Browse files

a_strex.c: prevent out of bound read in do_buf()



which is used for ASN1_STRING_print_ex*() and X509_NAME_print_ex*().

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6105)
parent 6ebb49f3
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ static int do_buf(unsigned char *buf, int buflen,
                  int type, unsigned short flags, char *quotes, char_io *io_ch,
                  void *arg)
{
    int i, outlen, len;
    int i, outlen, len, charwidth;
    unsigned short orflags;
    unsigned char *p, *q;
    unsigned long c;
@@ -147,12 +147,32 @@ static int do_buf(unsigned char *buf, int buflen,
    p = buf;
    q = buf + buflen;
    outlen = 0;
    charwidth = type & BUF_TYPE_WIDTH_MASK;

    switch (charwidth) {
    case 4:
        if (buflen & 3) {
            ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
            return -1;
        }
        break;
    case 2:
        if (buflen & 1) {
            ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_BMPSTRING_LENGTH);
            return -1;
        }
        break;
    default:
        break;
    }

    while (p != q) {
        if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
            orflags = CHARTYPE_FIRST_ESC_2253;
        else
            orflags = 0;
        switch (type & BUF_TYPE_WIDTH_MASK) {

        switch (charwidth) {
        case 4:
            c = ((unsigned long)*p++) << 24;
            c |= ((unsigned long)*p++) << 16;
@@ -173,6 +193,7 @@ static int do_buf(unsigned char *buf, int buflen,
            i = UTF8_getc(p, buflen, &c);
            if (i < 0)
                return -1;      /* Invalid UTF8String */
            buflen -= i;
            p += i;
            break;
        default:
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ static const ERR_STRING_DATA ASN1_str_functs[] = {
     "d2i_AutoPrivateKey"},
    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_PRIVATEKEY, 0), "d2i_PrivateKey"},
    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_PUBLICKEY, 0), "d2i_PublicKey"},
    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_BUF, 0), "do_buf"},
    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_CREATE, 0), "do_create"},
    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_DUMP, 0), "do_dump"},
    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_TCREATE, 0), "do_tcreate"},
+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ ASN1_F_D2I_ASN1_UINTEGER:150:d2i_ASN1_UINTEGER
ASN1_F_D2I_AUTOPRIVATEKEY:207:d2i_AutoPrivateKey
ASN1_F_D2I_PRIVATEKEY:154:d2i_PrivateKey
ASN1_F_D2I_PUBLICKEY:155:d2i_PublicKey
ASN1_F_DO_BUF:142:do_buf
ASN1_F_DO_CREATE:124:do_create
ASN1_F_DO_DUMP:125:do_dump
ASN1_F_DO_TCREATE:222:do_tcreate
+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ int ERR_load_ASN1_strings(void);
# define ASN1_F_D2I_AUTOPRIVATEKEY                        207
# define ASN1_F_D2I_PRIVATEKEY                            154
# define ASN1_F_D2I_PUBLICKEY                             155
# define ASN1_F_DO_BUF                                    142
# define ASN1_F_DO_CREATE                                 124
# define ASN1_F_DO_DUMP                                   125
# define ASN1_F_DO_TCREATE                                222