Example #1
0
/**
 * gnutls_x509_dn_get_rdn_ava:
 * @dn: a pointer to DN
 * @irdn: index of RDN
 * @iava: index of AVA.
 * @ava: Pointer to structure which will hold output information.
 *
 * Get pointers to data within the DN. The format of the @ava structure
 * is shown below.
 *
 *  struct gnutls_x509_ava_st {
 *    gnutls_datum_t oid;
 *    gnutls_datum_t value;
 *    unsigned long value_tag;
 *  };
 *
 * The X.509 distinguished name is a sequence of sequences of strings
 * and this is what the @irdn and @iava indexes model.
 *
 * Note that @ava will contain pointers into the @dn structure which
 * in turns points to the original certificate. Thus you should not
 * modify any data or deallocate any of those.
 *
 * This is a low-level function that requires the caller to do the
 * value conversions when necessary (e.g. from UCS-2).
 *
 * Returns: Returns 0 on success, or an error code.
 **/
int
gnutls_x509_dn_get_rdn_ava(gnutls_x509_dn_t dn,
			   int irdn, int iava, gnutls_x509_ava_st * ava)
{
	ASN1_TYPE rdn, elem;
	ASN1_DATA_NODE vnode;
	long len;
	int lenlen, remlen, ret;
	char rbuf[MAX_NAME_SIZE];
	unsigned char cls;
	const unsigned char *ptr;

	iava++;
	irdn++;			/* 0->1, 1->2 etc */

	snprintf(rbuf, sizeof(rbuf), "rdnSequence.?%d.?%d", irdn, iava);
	rdn = asn1_find_node(dn->asn, rbuf);
	if (!rdn) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}

	snprintf(rbuf, sizeof(rbuf), "?%d.type", iava);
	elem = asn1_find_node(rdn, rbuf);
	if (!elem) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}

	ret = asn1_read_node_value(elem, &vnode);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}

	ava->oid.data = (void *) vnode.value;
	ava->oid.size = vnode.value_len;

	snprintf(rbuf, sizeof(rbuf), "?%d.value", iava);
	elem = asn1_find_node(rdn, rbuf);
	if (!elem) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}

	ret = asn1_read_node_value(elem, &vnode);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}
	/* The value still has the previous tag's length bytes, plus the
	 * current value's tag and length bytes. Decode them.
	 */

	ptr = vnode.value;
	remlen = vnode.value_len;
	len = asn1_get_length_der(ptr, remlen, &lenlen);
	if (len < 0) {
		gnutls_assert();
		return GNUTLS_E_ASN1_DER_ERROR;
	}

	ptr += lenlen;
	remlen -= lenlen;
	ret =
	    asn1_get_tag_der(ptr, remlen, &cls, &lenlen, &ava->value_tag);
	if (ret) {
		gnutls_assert();
		return _gnutls_asn2err(ret);
	}

	ptr += lenlen;
	remlen -= lenlen;

	{
		signed long tmp;

		tmp = asn1_get_length_der(ptr, remlen, &lenlen);
		if (tmp < 0) {
			gnutls_assert();
			return GNUTLS_E_ASN1_DER_ERROR;
		}
		ava->value.size = tmp;
	}
	ava->value.data = (void *) (ptr + lenlen);

	return 0;
}
Example #2
0
/**
 * asn1_print_structure:
 * @out: pointer to the output file (e.g. stdout).
 * @structure: pointer to the structure that you want to visit.
 * @name: an element of the structure
 * @mode: specify how much of the structure to print, can be
 *   %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
 *   %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
 *
 * Prints on the @out file descriptor the structure's tree starting
 * from the @name element inside the structure @structure.
 **/
void
asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
		      int mode)
{
  ASN1_TYPE p, root;
  int k, indent = 0, len, len2, len3;

  if (out == NULL)
    return;

  root = asn1_find_node (structure, name);

  if (root == NULL)
    return;

  p = root;
  while (p)
    {
      if (mode == ASN1_PRINT_ALL)
	{
	  for (k = 0; k < indent; k++)
	    fprintf (out, " ");
	  fprintf (out, "name:");
	  if (p->name)
	    fprintf (out, "%s  ", p->name);
	  else
	    fprintf (out, "NULL  ");
	}
      else
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_CONSTANT:
	    case TYPE_TAG:
	    case TYPE_SIZE:
	      break;
	    default:
	      for (k = 0; k < indent; k++)
		fprintf (out, " ");
	      fprintf (out, "name:");
	      if (p->name)
		fprintf (out, "%s  ", p->name);
	      else
		fprintf (out, "NULL  ");
	    }
	}

      if (mode != ASN1_PRINT_NAME)
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_CONSTANT:
	      if (mode == ASN1_PRINT_ALL)
		fprintf (out, "type:CONST");
	      break;
	    case TYPE_TAG:
	      if (mode == ASN1_PRINT_ALL)
		fprintf (out, "type:TAG");
	      break;
	    case TYPE_SIZE:
	      if (mode == ASN1_PRINT_ALL)
		fprintf (out, "type:SIZE");
	      break;
	    case TYPE_DEFAULT:
	      fprintf (out, "type:DEFAULT");
	      break;
	    case TYPE_NULL:
	      fprintf (out, "type:NULL");
	      break;
	    case TYPE_IDENTIFIER:
	      fprintf (out, "type:IDENTIFIER");
	      break;
	    case TYPE_INTEGER:
	      fprintf (out, "type:INTEGER");
	      break;
	    case TYPE_ENUMERATED:
	      fprintf (out, "type:ENUMERATED");
	      break;
	    case TYPE_TIME:
	      fprintf (out, "type:TIME");
	      break;
	    case TYPE_BOOLEAN:
	      fprintf (out, "type:BOOLEAN");
	      break;
	    case TYPE_SEQUENCE:
	      fprintf (out, "type:SEQUENCE");
	      break;
	    case TYPE_BIT_STRING:
	      fprintf (out, "type:BIT_STR");
	      break;
	    case TYPE_OCTET_STRING:
	      fprintf (out, "type:OCT_STR");
	      break;
	    case TYPE_GENERALSTRING:
	      fprintf (out, "type:GENERALSTRING");
	      break;
	    case TYPE_SEQUENCE_OF:
	      fprintf (out, "type:SEQ_OF");
	      break;
	    case TYPE_OBJECT_ID:
	      fprintf (out, "type:OBJ_ID");
	      break;
	    case TYPE_ANY:
	      fprintf (out, "type:ANY");
	      break;
	    case TYPE_SET:
	      fprintf (out, "type:SET");
	      break;
	    case TYPE_SET_OF:
	      fprintf (out, "type:SET_OF");
	      break;
	    case TYPE_CHOICE:
	      fprintf (out, "type:CHOICE");
	      break;
	    case TYPE_DEFINITIONS:
	      fprintf (out, "type:DEFINITIONS");
	      break;
	    default:
	      break;
	    }
	}

      if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_CONSTANT:
	      if (mode == ASN1_PRINT_ALL)
		if (p->value)
		  fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_TAG:
	      if (mode == ASN1_PRINT_ALL)
		if (p->value)
		  fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_SIZE:
	      if (mode == ASN1_PRINT_ALL)
		if (p->value)
		  fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_DEFAULT:
	      if (p->value)
		fprintf (out, "  value:%s", p->value);
	      else if (p->type & CONST_TRUE)
		fprintf (out, "  value:TRUE");
	      else if (p->type & CONST_FALSE)
		fprintf (out, "  value:FALSE");
	      break;
	    case TYPE_IDENTIFIER:
	      if (p->value)
		fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_INTEGER:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  fprintf (out, "  value:0x");
		  if (len > 0)
		    for (k = 0; k < len; k++)
		      fprintf (out, "%02x", (p->value)[k + len2]);
		}
	      break;
	    case TYPE_ENUMERATED:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  fprintf (out, "  value:0x");
		  if (len > 0)
		    for (k = 0; k < len; k++)
		      fprintf (out, "%02x", (p->value)[k + len2]);
		}
	      break;
	    case TYPE_TIME:
	      if (p->value)
		fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_BOOLEAN:
	      if (p->value)
		{
		  if (p->value[0] == 'T')
		    fprintf (out, "  value:TRUE");
		  else if (p->value[0] == 'F')
		    fprintf (out, "  value:FALSE");
		}
	      break;
	    case TYPE_BIT_STRING:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  if (len > 0)
		    {
		      fprintf (out, "  value(%i):",
			       (len - 1) * 8 - (p->value[len2]));
		      for (k = 1; k < len; k++)
			fprintf (out, "%02x", (p->value)[k + len2]);
		    }
		}
	      break;
	    case TYPE_OCTET_STRING:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  fprintf (out, "  value:");
		  if (len > 0)
		    for (k = 0; k < len; k++)
		      fprintf (out, "%02x", (p->value)[k + len2]);
		}
	      break;
	    case TYPE_GENERALSTRING:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  fprintf (out, "  value:");
		  if (len > 0)
		    for (k = 0; k < len; k++)
		      fprintf (out, "%02x", (p->value)[k + len2]);
		}
	      break;
	    case TYPE_OBJECT_ID:
	      if (p->value)
		fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_ANY:
	      if (p->value)
		{
		  len3 = -1;
		  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
		  fprintf (out, "  value:");
		  if (len2 > 0)
		    for (k = 0; k < len2; k++)
		      fprintf (out, "%02x", (p->value)[k + len3]);
		}
	      break;
	    case TYPE_SET:
	    case TYPE_SET_OF:
	    case TYPE_CHOICE:
	    case TYPE_DEFINITIONS:
	    case TYPE_SEQUENCE_OF:
	    case TYPE_SEQUENCE:
	    case TYPE_NULL:
	      break;
	    default:
	      break;
	    }
	}

      if (mode == ASN1_PRINT_ALL)
	{
	  if (p->type & 0x1FFFFF00)
	    {
	      fprintf (out, "  attr:");
	      if (p->type & CONST_UNIVERSAL)
		fprintf (out, "UNIVERSAL,");
	      if (p->type & CONST_PRIVATE)
		fprintf (out, "PRIVATE,");
	      if (p->type & CONST_APPLICATION)
		fprintf (out, "APPLICATION,");
	      if (p->type & CONST_EXPLICIT)
		fprintf (out, "EXPLICIT,");
	      if (p->type & CONST_IMPLICIT)
		fprintf (out, "IMPLICIT,");
	      if (p->type & CONST_TAG)
		fprintf (out, "TAG,");
	      if (p->type & CONST_DEFAULT)
		fprintf (out, "DEFAULT,");
	      if (p->type & CONST_TRUE)
		fprintf (out, "TRUE,");
	      if (p->type & CONST_FALSE)
		fprintf (out, "FALSE,");
	      if (p->type & CONST_LIST)
		fprintf (out, "LIST,");
	      if (p->type & CONST_MIN_MAX)
		fprintf (out, "MIN_MAX,");
	      if (p->type & CONST_OPTION)
		fprintf (out, "OPTION,");
	      if (p->type & CONST_1_PARAM)
		fprintf (out, "1_PARAM,");
	      if (p->type & CONST_SIZE)
		fprintf (out, "SIZE,");
	      if (p->type & CONST_DEFINED_BY)
		fprintf (out, "DEF_BY,");
	      if (p->type & CONST_GENERALIZED)
		fprintf (out, "GENERALIZED,");
	      if (p->type & CONST_UTC)
		fprintf (out, "UTC,");
	      if (p->type & CONST_SET)
		fprintf (out, "SET,");
	      if (p->type & CONST_NOT_USED)
		fprintf (out, "NOT_USED,");
	      if (p->type & CONST_ASSIGN)
		fprintf (out, "ASSIGNMENT,");
	    }
	}

      if (mode == ASN1_PRINT_ALL)
	{
	  fprintf (out, "\n");
	}
      else
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_CONSTANT:
	    case TYPE_TAG:
	    case TYPE_SIZE:
	      break;
	    default:
	      fprintf (out, "\n");
	    }
	}

      if (p->down)
	{
	  p = p->down;
	  indent += 2;
	}
      else if (p == root)
	{
	  p = NULL;
	  break;
	}
      else if (p->right)
	p = p->right;
      else
	{
	  while (1)
	    {
	      p = _asn1_find_up (p);
	      if (p == root)
		{
		  p = NULL;
		  break;
		}
	      indent -= 2;
	      if (p->right)
		{
		  p = p->right;
		  break;
		}
	    }
	}
    }
}
Example #3
0
int
main (int argc, char **argv)
{
  /* Test that values larger than long are rejected.  This has worked
     fine with all versions of libtasn1. */
  int verbose = 0;

  if (argc > 1)
    verbose = 1;

  {
    unsigned char der[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
    long l;
    int len;

    l = asn1_get_length_der (der, sizeof der, &len);

    if (l == -2L)
      {
	if (verbose)
	  puts ("OK: asn1_get_length_der bignum");
      }
    else
      {
	printf ("ERROR: asn1_get_length_der bignum (l %ld len %d)\n", l, len);
	return 1;
      }
  }

  /* Test that values larger than int but smaller than long are
     rejected.  This limitation was introduced with libtasn1 2.12. */
  if (LONG_MAX > INT_MAX)
    {
      unsigned long num = ((long) UINT_MAX) << 2;
      unsigned char der[20];
      int der_len;
      long l;
      int len;

      asn1_length_der (num, der, &der_len);

      l = asn1_get_length_der (der, der_len, &len);

      if (l == -2L)
	{
	  if (verbose)
	    puts ("OK: asn1_get_length_der intnum");
	}
      else
	{
	  printf ("ERROR: asn1_get_length_der intnum (l %ld len %d)\n", l,
		  len);
	  return 1;
	}
    }

  /* Test that values larger than would fit in the input string are
     rejected.  This problem was fixed in libtasn1 2.12. */
  {
    unsigned long num = 64;
    unsigned char der[20];
    int der_len;
    long l;
    int len;

    asn1_length_der (num, der, &der_len);

    der_len = sizeof (der);
    l = asn1_get_length_der (der, der_len, &len);

    if (l == -4L)
      {
	if (verbose)
	  puts ("OK: asn1_get_length_der overflow-small");
      }
    else
      {
	printf ("ERROR: asn1_get_length_der overflow-small (l %ld len %d)\n",
		l, len);
	return 1;
      }
  }

  /* Test that values larger than would fit in the input string are
     rejected.  This problem was fixed in libtasn1 2.12. */
  {
    unsigned long num = 1073741824;
    unsigned char der[20];
    int der_len;
    long l;
    int len;

    asn1_length_der (num, der, &der_len);

    der_len = sizeof (der);
    l = asn1_get_length_der (der, der_len, &len);

    if (l == -4L)
      {
	if (verbose)
	  puts ("OK: asn1_get_length_der overflow-large1");
      }
    else
      {
	printf ("ERROR: asn1_get_length_der overflow-large1 (l %ld len %d)\n",
		l, len);
	return 1;
      }
  }

  /* Test that values larger than would fit in the input string are
     rejected.  This problem was fixed in libtasn1 2.12. */
  {
    unsigned long num = 2147483649;
    unsigned char der[20];
    int der_len;
    long l;
    int len;

    asn1_length_der (num, der, &der_len);

    der_len = sizeof (der);
    l = asn1_get_length_der (der, der_len, &len);

    if (l == -2L)
      {
	if (verbose)
	  puts ("OK: asn1_get_length_der overflow-large2");
      }
    else
      {
	printf ("ERROR: asn1_get_length_der overflow-large2 (l %ld len %d)\n",
		l, len);
	return 1;
      }
  }

  return 0;
}