db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: Handle malloc failture in the buffer
CVE: CVE-2011-0064
Vulnerability description: The hb_buffer_ensure function in hb-buffer.c in HarfBuzz, as used in Pango 1.28.3, Firefox, and other products, does not verify that memory reallocations succeed, which allows remote attackers to cause a denial of service (NULL pointer dereference and application crash) or possibly execute arbitrary code via crafted OpenType font data that triggers use of an incorrect index.

Project: harfbuzz
File: hb-buffer.cc

 hb_buffer_ensure (hb_buffer_t *buffer, unsigned int size)
 {
  if (unlikely (size > buffer->allocated))
   {
    if (unlikely (buffer->in_error))
      return FALSE;

    unsigned int new_allocated = buffer->allocated;
    hb_internal_glyph_position_t *new_pos;
    hb_internal_glyph_info_t *new_info;
    bool separate_out;

    separate_out = buffer->out_info != buffer->info;

     while (size > new_allocated)
       new_allocated += (new_allocated >> 1) + 8;
 
    new_pos = (hb_internal_glyph_position_t *) realloc (buffer->pos, new_allocated * sizeof (buffer->pos[0]));
    new_info = (hb_internal_glyph_info_t *) realloc (buffer->info, new_allocated * sizeof (buffer->info[0]));
 
    if (unlikely (!new_pos || !new_info))
      buffer->in_error = TRUE;
 
    if (likely (new_pos))
      buffer->pos = new_pos;

    if (likely (new_info))
      buffer->info = new_info;

    buffer->out_info = separate_out ? (hb_internal_glyph_info_t *) buffer->pos : buffer->info;
    if (likely (!buffer->in_error))
      buffer->allocated = new_allocated;
   }

  return likely (!buffer->in_error);
 }

Project: harfbuzz
File: hb-buffer.cc

 hb_buffer_ensure_separate (hb_buffer_t *buffer, unsigned int size)
 {
  if (unlikely (!hb_buffer_ensure (buffer, size))) return FALSE;

   if (buffer->out_info == buffer->info)
   {
     assert (buffer->have_output);
 
     buffer->out_info = (hb_internal_glyph_info_t *) buffer->pos;
     memcpy (buffer->out_info, buffer->info, buffer->out_len * sizeof (buffer->out_info[0]));
   }

  return TRUE;
 }
Commit message: None
CVE: CVE-2017-9739
CWE: CWE-125
Vulnerability description: The Ins_JMPR function in base/ttinterp.c in Artifex Ghostscript GhostXPS 9.21 allows remote attackers to cause a denial of service (heap-based buffer over-read and application crash) or possibly have unspecified other impact via a crafted document.

Project: ghostscript

   static void  Ins_JMPR( INS_ARG )
   {
    if ( BOUNDS(CUR.IP + args[0], CUR.codeSize ) )
    {
      CUR.error = TT_Err_Invalid_Reference;
      return;
    }

     CUR.IP      += (Int)(args[0]);
     CUR.step_ins = FALSE;
     * allow for simple cases here by just checking the preceding byte.
     * Fonts with this problem are not uncommon.
     */
      CUR.IP -= 1;
  }
Commit message: None
CVE: CVE-2017-9610
CWE: CWE-125
Vulnerability description: The xps_load_sfnt_name function in xps/xpsfont.c in Artifex Ghostscript GhostXPS 9.21 allows remote attackers to cause a denial of service (heap-based buffer over-read and application crash) or possibly have unspecified other impact via a crafted document.

Project: ghostscript

xps_load_sfnt_name(xps_font_t *font, char *namep)
{
    byte *namedata;
    int offset, length;
    /*int format;*/
    int count, stringoffset;
    int found;
    int i, k;

    found = 0;
    strcpy(namep, "Unknown");

    offset = xps_find_sfnt_table(font, "name", &length);
    if (offset < 0 || length < 6)
    {
        gs_warn("cannot find name table");
         return;
     }
 
    /* validate the offset, and the data for the two
     * values we're about to read
     */
    if (offset + 6 > font->length)
    {
        gs_warn("name table byte offset invalid");
        return;
    }
     namedata = font->data + offset;
 
     /*format = u16(namedata + 0);*/
     count = u16(namedata + 2);
     stringoffset = u16(namedata + 4);
 
    if (stringoffset + offset > font->length
        || offset + 6 + count * 12 > font->length)
    {
        gs_warn("name table invalid");
        return;
    }

     if (length < 6 + (count * 12))
     {
         gs_warn("name table too short");
        {
            if (pid == 1 && eid == 0 && langid == 0) /* mac roman, english */
            {
                if (found < 3)
                {
                    memcpy(namep, namedata + stringoffset + offset, length);
                    namep[length] = 0;
                    found = 3;
                }
            }

            if (pid == 3 && eid == 1 && langid == 0x409) /* windows unicode ucs-2, US */
            {
                if (found < 2)
                {
                    unsigned char *s = namedata + stringoffset + offset;
                    int n = length / 2;
                    for (k = 0; k < n; k ++)
                    {
                        int c = u16(s + k * 2);
                        namep[k] = isprint(c) ? c : '?';
                    }
                    namep[k] = 0;
                    found = 2;
                }
            }

            if (pid == 3 && eid == 10 && langid == 0x409) /* windows unicode ucs-4, US */
            {
                if (found < 1)
                {
                    unsigned char *s = namedata + stringoffset + offset;
                    int n = length / 4;
                    for (k = 0; k < n; k ++)
                    {
                        int c = u32(s + k * 4);
                        namep[k] = isprint(c) ? c : '?';
                    }
                    namep[k] = 0;
                    found = 1;
                }
            }
        }
    }
}
Commit message: Fix for CVE-2015-0291

If a client renegotiates using an invalid signature algorithms extension
it will crash a server with a NULL pointer dereference.

Thanks to David Ramos of Stanford University for reporting this bug.

CVE-2015-0291

Reviewed-by: Tim Hudson <tjh@openssl.org>

Conflicts:
	ssl/t1_lib.c
CVE: CVE-2015-0291
CWE: NVD-CWE-Other
Vulnerability description: The sigalgs implementation in t1_lib.c in OpenSSL 1.0.2 before 1.0.2a allows remote attackers to cause a denial of service (NULL pointer dereference and daemon crash) by using an invalid signature_algorithms extension in the ClientHello message during a renegotiation.

Project: openssl

int tls1_set_server_sigalgs(SSL *s)
{
    int al;
    size_t i;
    /* Clear any shared sigtnature algorithms */
     if (s->cert->shared_sigalgs) {
         OPENSSL_free(s->cert->shared_sigalgs);
         s->cert->shared_sigalgs = NULL;
        s->cert->shared_sigalgslen = 0;
     }
     /* Clear certificate digests and validity flags */
     for (i = 0; i < SSL_PKEY_NUM; i++) {
        s->cert->pkeys[i].valid_flags = 0;
    }

    /* If sigalgs received process it. */
    if (s->cert->peer_sigalgs) {
        if (!tls1_process_sigalgs(s)) {
            SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
            al = SSL_AD_INTERNAL_ERROR;
            goto err;
        }
        /* Fatal error is no shared signature algorithms */
        if (!s->cert->shared_sigalgs) {
            SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
                   SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
            al = SSL_AD_ILLEGAL_PARAMETER;
            goto err;
        }
    } else
        ssl_cert_set_default_md(s->cert);
    return 1;
 err:
    ssl3_send_alert(s, SSL3_AL_FATAL, al);
    return 0;
}
Commit message: Fix crash in broken pdf (code < 0)

Found thanks to PDF provided by Joel Voss of Leviathan Security Group
CVE: CVE-2010-3704
CWE: CWE-20
Vulnerability description: The FoFiType1::parse function in fofi/FoFiType1.cc in the PDF parser in xpdf before 3.02pl5, poppler 0.8.7 and possibly other versions up to 0.15.1, kdegraphics, and possibly other products allows context-dependent attackers to cause a denial of service (crash) and possibly execute arbitrary code via a PDF file with a crafted PostScript Type1 font that contains a negative array index, which bypasses input validation and triggers memory corruption.

Project: poppler

void FoFiType1::parse() {
  char *line, *line1, *p, *p2;
  char buf[256];
  char c;
  int n, code, i, j;
  char *tokptr;

  for (i = 1, line = (char *)file;
       i <= 100 && line && (!name || !encoding);
       ++i) {

    if (!name && !strncmp(line, "/FontName", 9)) {
      strncpy(buf, line, 255);
      buf[255] = '\0';
      if ((p = strchr(buf+9, '/')) &&
	  (p = strtok_r(p+1, " \t\n\r", &tokptr))) {
	name = copyString(p);
      }
      line = getNextLine(line);

    } else if (!encoding &&
	       !strncmp(line, "/Encoding StandardEncoding def", 30)) {
      encoding = fofiType1StandardEncoding;
    } else if (!encoding &&
	       !strncmp(line, "/Encoding 256 array", 19)) {
      encoding = (char **)gmallocn(256, sizeof(char *));
      for (j = 0; j < 256; ++j) {
	encoding[j] = NULL;
      }
      for (j = 0, line = getNextLine(line);
	   j < 300 && line && (line1 = getNextLine(line));
	   ++j, line = line1) {
	if ((n = line1 - line) > 255) {
	  error(-1, "FoFiType1::parse a line has more than 255 characters, we don't support this");
	  n = 255;
	}
	strncpy(buf, line, n);
	buf[n] = '\0';
	for (p = buf; *p == ' ' || *p == '\t'; ++p) ;
	if (!strncmp(p, "dup", 3)) {
	  for (p += 3; *p == ' ' || *p == '\t'; ++p) ;
	  for (p2 = p; *p2 >= '0' && *p2 <= '9'; ++p2) ;
	  if (*p2) {
	    c = *p2; // store it so we can recover it after atoi
	    *p2 = '\0'; // terminate p so atoi works
	    code = atoi(p);
	    *p2 = c;
	    if (code == 8 && *p2 == '#') {
	      code = 0;
	      for (++p2; *p2 >= '0' && *p2 <= '7'; ++p2) {
		code = code * 8 + (*p2 - '0');
 		code = code * 8 + (*p2 - '0');
 	      }
 	    }
	    if (likely(code < 256 && code >= 0)) {
 	      for (p = p2; *p == ' ' || *p == '\t'; ++p) ;
 	      if (*p == '/') {
 		++p;
		c = *p2; // store it so we can recover it after copyString
		*p2 = '\0'; // terminate p so copyString works
		encoding[code] = copyString(p);
		*p2 = c;
		p = p2;
		for (; *p == ' ' || *p == '\t'; ++p); // eat spaces between string and put
		if (!strncmp(p, "put", 3)) {
		  for (p += 3; *p == ' ' || *p == '\t' || *p == '\n' || *p == '\r'; ++p);
		  if (*p)
		  {
		    line1 = &line[p - buf];
		  }
		} else {
		  error(-1, "FoFiType1::parse no put after dup");
		}
	      }
	    }
	  }
	} else {
	  if (strtok_r(buf, " \t", &tokptr) &&
	      (p = strtok_r(NULL, " \t\n\r", &tokptr)) && !strcmp(p, "def")) {
	    break;
	  }
	}
      }

    } else {
      line = getNextLine(line);
    }
  }

  parsed = gTrue;
}
Commit message: Avoid overflow in MDC2_Update()

Thanks to Shi Lei for reporting this issue.

CVE-2016-6303

Reviewed-by: Matt Caswell <matt@openssl.org>
CVE: CVE-2016-6303
CWE: CWE-787
Vulnerability description: Integer overflow in the MDC2_Update function in crypto/mdc2/mdc2dgst.c in OpenSSL before 1.1.0 allows remote attackers to cause a denial of service (out-of-bounds write and application crash) or possibly have unspecified other impact via unknown vectors.

Project: openssl

int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len)
{
    size_t i, j;
 
     i = c->num;
     if (i != 0) {
        if (len < MDC2_BLOCK - i) {
             /* partial block */
             memcpy(&(c->data[i]), in, len);
             c->num += (int)len;
            return 1;
        } else {
            /* filled one */
            j = MDC2_BLOCK - i;
            memcpy(&(c->data[i]), in, j);
            len -= j;
            in += j;
            c->num = 0;
            mdc2_body(c, &(c->data[0]), MDC2_BLOCK);
        }
    }
    i = len & ~((size_t)MDC2_BLOCK - 1);
    if (i > 0)
        mdc2_body(c, in, i);
    j = len - i;
    if (j > 0) {
        memcpy(&(c->data[0]), &(in[i]), j);
        c->num = (int)j;
    }
    return 1;
}
Commit message: None
CVE: CVE-2016-6263
CWE: CWE-125
Vulnerability description: The stringprep_utf8_nfkc_normalize function in lib/nfkc.c in libidn before 1.33 allows context-dependent attackers to cause a denial of service (out-of-bounds read and crash) via crafted UTF-8 data.

Project: savannah

 stringprep_utf8_nfkc_normalize (const char *str, ssize_t len)
 {
  size_t n;

  if (len < 0)
    n = strlen (str);
  else
    n = len;

  if (u8_check ((const uint8_t *) str, n))
    return NULL;

   return g_utf8_normalize (str, len, G_NORMALIZE_NFKC);
 }
Commit message: None
CVE: CVE-2014-6269
CWE: CWE-189
Vulnerability description: Multiple integer overflows in the http_request_forward_body function in proto_http.c in HAProxy 1.5-dev23 before 1.5.4 allow remote attackers to cause a denial of service (crash) via a large stream of data, which triggers a buffer overflow and an out-of-bounds read.

Project: haproxy

static void si_conn_send(struct connection *conn)
{
	struct stream_interface *si = conn->owner;
	struct channel *chn = si->ob;
	int ret;

        if (chn->pipe && conn->xprt->snd_pipe) {
                ret = conn->xprt->snd_pipe(conn, chn->pipe);
                if (ret > 0)
                       chn->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
 
                if (!chn->pipe->data) {
                        put_pipe(chn->pipe);
			chn->pipe = NULL;
		}

		if (conn->flags & CO_FL_ERROR)
			return;
	}

	/* At this point, the pipe is empty, but we may still have data pending
	 * in the normal buffer.
	 */
	if (!chn->buf->o)
		return;

	/* when we're here, we already know that there is no spliced
	 * data left, and that there are sendable buffered data.
	 */
	if (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_WR_SH | CO_FL_DATA_WR_SH | CO_FL_WAIT_DATA | CO_FL_HANDSHAKE))) {
		/* check if we want to inform the kernel that we're interested in
		 * sending more data after this call. We want this if :
		 *  - we're about to close after this last send and want to merge
		 *    the ongoing FIN with the last segment.
		 *  - we know we can't send everything at once and must get back
		 *    here because of unaligned data
		 *  - there is still a finite amount of data to forward
		 * The test is arranged so that the most common case does only 2
		 * tests.
		 */
		unsigned int send_flag = 0;

		if ((!(chn->flags & (CF_NEVER_WAIT|CF_SEND_DONTWAIT)) &&
		     ((chn->to_forward && chn->to_forward != CHN_INFINITE_FORWARD) ||
		      (chn->flags & CF_EXPECT_MORE))) ||
		    ((chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW))
			send_flag |= CO_SFL_MSG_MORE;

		if (chn->flags & CF_STREAMER)
			send_flag |= CO_SFL_STREAMER;
 
                ret = conn->xprt->snd_buf(conn, chn->buf, send_flag);
                if (ret > 0) {
                       chn->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
 
                        if (!chn->buf->o) {
                                /* Always clear both flags once everything has been sent, they're one-shot */
				chn->flags &= ~(CF_EXPECT_MORE | CF_SEND_DONTWAIT);
			}

			/* if some data remain in the buffer, it's only because the
			 * system buffers are full, we will try next time.
			 */
		}
	}

	return;
}
Commit message: None
CVE: CVE-2016-4356
CWE: CWE-119
Vulnerability description: The append_utf8_value function in the DN decoder (dn.c) in Libksba before 1.3.3 allows remote attackers to cause a denial of service (out-of-bounds read) by clearing the high bit of the byte after invalid utf-8 encoded data.

Project: gnupg

append_utf8_value (const unsigned char *value, size_t length,
                   struct stringbuf *sb)
{
  unsigned char tmp[6];
  const unsigned char *s;
  size_t n;
  int i, nmore;

  if (length && (*value == ' ' || *value == '#'))
    {
      tmp[0] = '\\';
      tmp[1] = *value;
      put_stringbuf_mem (sb, tmp, 2);
      value++;
      length--;
    }
  if (length && value[length-1] == ' ')
    {
      tmp[0] = '\\';
      tmp[1] = ' ';
      put_stringbuf_mem (sb, tmp, 2);
       length--;
     }
 
   for (s=value, n=0;;)
     {
       for (value = s; n < length && !(*s & 0x80); n++, s++)
      for (value = s; n < length && !(*s & 0x80); n++, s++)
        ;
         append_quoted (sb, value, s-value, 0);
       if (n==length)
         return; /* ready */
      if (!(*s & 0x80))
        nmore = 0; /* Not expected here: high bit not set.  */
      else if ( (*s & 0xe0) == 0xc0 ) /* 110x xxxx */
         nmore = 1;
       else if ( (*s & 0xf0) == 0xe0 ) /* 1110 xxxx */
         nmore = 2;
      else if ( (*s & 0xf8) == 0xf0 ) /* 1111 0xxx */
        nmore = 3;
      else if ( (*s & 0xfc) == 0xf8 ) /* 1111 10xx */
         nmore = 4;
       else if ( (*s & 0xfe) == 0xfc ) /* 1111 110x */
         nmore = 5;
      else /* Invalid encoding */
        nmore = 0;
 
      if (!nmore)
         {
          /* Encoding error:  We quote the bad byte.  */
          snprintf (tmp, sizeof tmp, "\\%02X", *s);
          put_stringbuf_mem (sb, tmp, 3);
          s++; n++;
        }
      else
        {
          if (n+nmore > length)
            nmore = length - n; /* Oops, encoding to short */

          tmp[0] = *s++; n++;
          for (i=1; i <= nmore; i++)
            {
              if ( (*s & 0xc0) != 0x80)
                break; /* Invalid encoding - let the next cycle detect this. */
              tmp[i] = *s++;
              n++;
            }
          put_stringbuf_mem (sb, tmp, i);
         }
     }
 }
Commit message: vrend: fix a leak in context create internal

Create a context more than once causes memory leak issue.
Juest return if the context exists.

Signed-off-by: Li Qiang <liq3ea@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
CVE: CVE-2016-10163
CWE: CWE-399
Vulnerability description: Memory leak in the vrend_renderer_context_create_internal function in vrend_decode.c in virglrenderer before 0.6.0 allows local guest OS users to cause a denial of service (host memory consumption) by repeatedly creating a decode context.

Project: virglrenderer

void vrend_renderer_context_create_internal(uint32_t handle, uint32_t nlen,
                                            const char *debug_name)
{
   struct vrend_decode_ctx *dctx;

    if (handle >= VREND_MAX_CTX)
       return;
 
   dctx = dec_ctx[handle];
   if (dctx)
      return;

    dctx = malloc(sizeof(struct vrend_decode_ctx));
    if (!dctx)
       return;
      return;
   }
Commit message: CVE-2016-0798: avoid memory leak in SRP

The SRP user database lookup method SRP_VBASE_get_by_user had confusing
memory management semantics; the returned pointer was sometimes newly
allocated, and sometimes owned by the callee. The calling code has no
way of distinguishing these two cases.

Specifically, SRP servers that configure a secret seed to hide valid
login information are vulnerable to a memory leak: an attacker
connecting with an invalid username can cause a memory leak of around
300 bytes per connection.

Servers that do not configure SRP, or configure SRP but do not configure
a seed are not vulnerable.

In Apache, the seed directive is known as SSLSRPUnknownUserSeed.

To mitigate the memory leak, the seed handling in SRP_VBASE_get_by_user
is now disabled even if the user has configured a seed.

Applications are advised to migrate to SRP_VBASE_get1_by_user. However,
note that OpenSSL makes no strong guarantees about the
indistinguishability of valid and invalid logins. In particular,
computations are currently not carried out in constant time.

Reviewed-by: Rich Salz <rsalz@openssl.org>
CVE: CVE-2016-0798
CWE: CWE-399
Vulnerability description: Memory leak in the SRP_VBASE_get_by_user implementation in OpenSSL 1.0.1 before 1.0.1s and 1.0.2 before 1.0.2g allows remote attackers to cause a denial of service (memory consumption) by providing an invalid username in a connection attempt, related to apps/s_server.c and crypto/srp/srp_vfy.c.

Project: openssl

static void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
 {
     if (user_pwd == NULL)
         return;
    BN_free(user_pwd->s);
    BN_clear_free(user_pwd->v);
    OPENSSL_free(user_pwd->id);
    OPENSSL_free(user_pwd->info);
    OPENSSL_free(user_pwd);
}
Commit message: glx: check request length before swapping

Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
Signed-off-by: Julien Cristau <jcristau@debian.org>
CVE: CVE-2010-4818
CWE: CWE-20
Vulnerability description: The GLX extension in X.Org xserver 1.7.7 allows remote authenticated users to cause a denial of service (server crash) and possibly execute arbitrary code via (1) a crafted request that triggers a client swap in glx/glxcmdsswap.c; or (2) a crafted length or (3) a negative value in the screen field in a request to glx/glxcmds.c.

Project: xserver

 int __glXDispSwap_CreateContext(__GLXclientState *cl, GLbyte *pc)
 {
    ClientPtr client = cl->client;
     xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
     __GLX_DECLARE_SWAP_VARIABLES;
 
    REQUEST_SIZE_MATCH(xGLXCreateContextReq);

     __GLX_SWAP_SHORT(&req->length);
     __GLX_SWAP_INT(&req->context);
     __GLX_SWAP_INT(&req->visual);
    return __glXDisp_CreateContext(cl, pc);
}
Commit message: Limit ASN.1 constructed types recursive definition depth

Constructed types with a recursive definition (such as can be found in
PKCS7) could eventually exceed the stack given malicious input with
excessive recursion. Therefore we limit the stack depth.

CVE-2018-0739

Credit to OSSFuzz for finding this issue.

Reviewed-by: Rich Salz <rsalz@openssl.org>
CVE: CVE-2018-0739
CWE: CWE-400
Vulnerability description: Constructed ASN.1 types with a recursive definition (such as can be found in PKCS7) could eventually exceed the stack given malicious input with excessive recursion. This could result in a Denial Of Service attack. There are no such structures used within SSL/TLS that come from untrusted sources so this is considered safe. Fixed in OpenSSL 1.1.0h (Affected 1.1.0-1.1.0g). Fixed in OpenSSL 1.0.2o (Affected 1.0.2b-1.0.2n).

Project: openssl

static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
 static int asn1_template_ex_d2i(ASN1_VALUE **pval,
                                 const unsigned char **in, long len,
                                 const ASN1_TEMPLATE *tt, char opt,
                                ASN1_TLC *ctx, int depth);
 static int asn1_template_noexp_d2i(ASN1_VALUE **val,
                                    const unsigned char **in, long len,
                                    const ASN1_TEMPLATE *tt, char opt,
                                   ASN1_TLC *ctx, int depth);
 static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
                                  const unsigned char **in, long len,
                                  const ASN1_ITEM *it,
    /* tags  4- 7 */
    B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,
    /* tags  8-11 */
    B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
    /* tags 12-15 */
    B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
    /* tags 16-19 */
    B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING,
    /* tags 20-22 */
    B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING,
    /* tags 23-24 */
    B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,
    /* tags 25-27 */
    B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING,
    /* tags 28-31 */
    B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN,
};

unsigned long ASN1_tag2bit(int tag)
{