Exemplo n.º 1
0
/* Parses an X509 DN in the asn1_struct, and searches for the
 * given OID in the DN.
 *
 * If raw_flag == 0, the output will be encoded in the LDAP way. (#hex for non printable)
 * Otherwise the raw DER data are returned.
 *
 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
 * That is to point in the rndSequence.
 *
 * indx specifies which OID to return. Ie 0 means return the first specified
 * OID found, 1 the second etc.
 */
int
_gnutls_x509_parse_dn_oid (ASN1_TYPE asn1_struct,
			   const char *asn1_rdn_name,
			   const char *given_oid, int indx,
			   unsigned int raw_flag,
			   void *buf, size_t * sizeof_buf)
{
  int k2, k1, result;
  char tmpbuffer1[MAX_NAME_SIZE];
  char tmpbuffer2[MAX_NAME_SIZE];
  char tmpbuffer3[MAX_NAME_SIZE];
  opaque value[256];
  char oid[128];
  int len, printable;
  int i = 0;
  char *cbuf = buf;

  if (cbuf == NULL)
    *sizeof_buf = 0;
  else
    cbuf[0] = 0;

  k1 = 0;
  do
    {

      k1++;
      /* create a string like "tbsCertList.issuer.rdnSequence.?1"
       */
      if (asn1_rdn_name[0] != 0)
        snprintf( tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name, k1);
      else
        snprintf( tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);

      len = sizeof (value) - 1;
      result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);

      if (result == ASN1_ELEMENT_NOT_FOUND)
	{
	  gnutls_assert ();
	  break;
	}

      if (result != ASN1_VALUE_NOT_FOUND)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      k2 = 0;

      do
	{			/* Move to the attibute type and values
				 */
	  k2++;

          if (tmpbuffer1[0] != 0)
            snprintf( tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1, k2);
          else
            snprintf( tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);

	  /* Try to read the RelativeDistinguishedName attributes.
	   */

	  len = sizeof (value) - 1;
	  result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);

	  if (result == ASN1_ELEMENT_NOT_FOUND)
	    {
	      break;
	    }
	  if (result != ASN1_VALUE_NOT_FOUND)
	    {
	      gnutls_assert ();
	      result = _gnutls_asn2err (result);
	      goto cleanup;
	    }

	  /* Read the OID 
	   */
	  _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
	  _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");

	  len = sizeof (oid) - 1;
	  result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);

	  if (result == ASN1_ELEMENT_NOT_FOUND)
	    break;
	  else if (result != ASN1_SUCCESS)
	    {
	      gnutls_assert ();
	      result = _gnutls_asn2err (result);
	      goto cleanup;
	    }

	  if (strcmp (oid, given_oid) == 0 && indx == i++)
	    {			/* Found the OID */

	      /* Read the Value 
	       */
	      _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
	      _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");

	      len = *sizeof_buf;
	      result = asn1_read_value (asn1_struct, tmpbuffer3, buf, &len);

	      if (result != ASN1_SUCCESS)
		{
		  gnutls_assert ();
		  if (result == ASN1_MEM_ERROR)
		    *sizeof_buf = len;
		  result = _gnutls_asn2err (result);
		  goto cleanup;
		}

	      if (raw_flag != 0)
		{
		  if ((unsigned) len > *sizeof_buf)
		    {
		      *sizeof_buf = len;
		      result = GNUTLS_E_SHORT_MEMORY_BUFFER;
		      goto cleanup;
		    }
		  *sizeof_buf = len;

		  return 0;

		}
	      else
		{		/* parse data. raw_flag == 0 */
		  printable = _gnutls_x509_oid_data_printable (oid);

		  if (printable == 1)
		    result =
		      _gnutls_x509_oid_data2string (oid, buf, len,
						    cbuf, sizeof_buf);
		  else
		    result =
		      _gnutls_x509_data2hex (buf, len, cbuf, sizeof_buf);

		  if (result < 0)
		    {
		      gnutls_assert ();
		      goto cleanup;
		    }

		  return 0;

		}		/* raw_flag == 0 */
	    }
	}
      while (1);

    }
  while (1);

  gnutls_assert ();

  result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;

cleanup:
  return result;
}
Exemplo n.º 2
0
/* Parses an X509 DN in the asn1_struct, and puts the output into
 * the string buf. The output is an LDAP encoded DN.
 *
 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
 * That is to point in the rndSequence.
 */
int
_gnutls_x509_parse_dn (ASN1_TYPE asn1_struct,
		       const char *asn1_rdn_name, char *buf,
		       size_t * sizeof_buf)
{
  gnutls_string out_str;
  int k2, k1, result;
  char tmpbuffer1[MAX_NAME_SIZE];
  char tmpbuffer2[MAX_NAME_SIZE];
  char tmpbuffer3[MAX_NAME_SIZE];
  opaque value[MAX_STRING_LEN], *value2 = NULL;
  char *escaped = NULL;
  const char *ldap_desc;
  char oid[128];
  int len, printable;
  char *string = NULL;
  size_t sizeof_string, sizeof_escaped;

  if (sizeof_buf == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (buf)
    buf[0] = 0;
  else
    *sizeof_buf = 0;

  _gnutls_string_init (&out_str, gnutls_malloc, gnutls_realloc, gnutls_free);

  k1 = 0;
  do
    {

      k1++;
      /* create a string like "tbsCertList.issuer.rdnSequence.?1"
       */
      if (asn1_rdn_name[0]!=0)
        snprintf( tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name, k1);
      else
        snprintf( tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
      
      len = sizeof (value) - 1;
      result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);

      if (result == ASN1_ELEMENT_NOT_FOUND)
	{
	  break;
	}

      if (result != ASN1_VALUE_NOT_FOUND)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      k2 = 0;

      do
	{			/* Move to the attibute type and values
				 */
	  k2++;

          if (tmpbuffer1[0] != 0)
  	    snprintf( tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1, k2);
          else
  	    snprintf( tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);

	  /* Try to read the RelativeDistinguishedName attributes.
	   */

	  len = sizeof (value) - 1;
	  result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);

	  if (result == ASN1_ELEMENT_NOT_FOUND)
	    break;
	  if (result != ASN1_VALUE_NOT_FOUND)
	    {
	      gnutls_assert ();
	      result = _gnutls_asn2err (result);
	      goto cleanup;
	    }

	  /* Read the OID 
	   */
	  _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
	  _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");

	  len = sizeof (oid) - 1;
	  result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);

	  if (result == ASN1_ELEMENT_NOT_FOUND)
	    break;
	  else if (result != ASN1_SUCCESS)
	    {
	      gnutls_assert ();
	      result = _gnutls_asn2err (result);
	      goto cleanup;
	    }

	  /* Read the Value 
	   */
	  _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
	  _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");

	  len = 0;
	  result = asn1_read_value (asn1_struct, tmpbuffer3, NULL, &len);

	  value2 = gnutls_malloc (len);
	  if (value2 == NULL)
	    {
	      gnutls_assert ();
	      result = GNUTLS_E_MEMORY_ERROR;
	      goto cleanup;
	    }

	  result = asn1_read_value (asn1_struct, tmpbuffer3, value2, &len);

	  if (result != ASN1_SUCCESS)
	    {
	      gnutls_assert ();
	      result = _gnutls_asn2err (result);
	      goto cleanup;
	    }
#define STR_APPEND(y) if ((result=_gnutls_string_append_str( &out_str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
	  /*   The encodings of adjoining RelativeDistinguishedNames are separated
	   *   by a comma character (',' ASCII 44).
	   */

	  /*   Where there is a multi-valued RDN, the outputs from adjoining
	   *   AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
	   *   character.
	   */
	  if (k1 != 1)
	    {			/* the first time do not append a comma */
	      if (k2 != 1)
		{		/* adjoining multi-value RDN */
		  STR_APPEND ("+");
		}
	      else
		{
		  STR_APPEND (",");
		}
	    }

	  ldap_desc = oid2ldap_string (oid);
	  printable = _gnutls_x509_oid_data_printable (oid);

	  sizeof_escaped = 2 * len + 1;

	  escaped = gnutls_malloc (sizeof_escaped);
	  if (escaped == NULL)
	    {
	      gnutls_assert ();
	      result = GNUTLS_E_MEMORY_ERROR;
	      goto cleanup;
	    }

	  sizeof_string = 2 * len + 2;	/* in case it is not printable */

	  string = gnutls_malloc (sizeof_string);
	  if (string == NULL)
	    {
	      gnutls_assert ();
	      result = GNUTLS_E_MEMORY_ERROR;
	      goto cleanup;
	    }

	  STR_APPEND (ldap_desc);
	  STR_APPEND ("=");
	  if (printable)
	    result =
	      _gnutls_x509_oid_data2string (oid,
					    value2, len,
					    string, &sizeof_string);
	  else
	    result =
	      _gnutls_x509_data2hex (value2, len, string, &sizeof_string);

	  if (result < 0)
	    {
	      gnutls_assert ();
	      _gnutls_x509_log
		("Found OID: '%s' with value '%s'\n",
		 oid, _gnutls_bin2hex (value2, len, escaped, sizeof_escaped));
	      goto cleanup;
	    }
	  STR_APPEND (str_escape (string, escaped, sizeof_escaped));
	  gnutls_free (string);
	  string = NULL;

	  gnutls_free (escaped);
	  escaped = NULL;
	  gnutls_free (value2);
	  value2 = NULL;

	}
      while (1);

    }
  while (1);

  if (out_str.length >= (unsigned int) *sizeof_buf)
    {
      gnutls_assert ();
      *sizeof_buf = out_str.length + 1;
      result = GNUTLS_E_SHORT_MEMORY_BUFFER;
      goto cleanup;
    }

  if (buf)
    {
      memcpy (buf, out_str.data, out_str.length);
      buf[out_str.length] = 0;
    }
  *sizeof_buf = out_str.length;

  result = 0;

cleanup:
  gnutls_free (value2);
  gnutls_free (string);
  gnutls_free (escaped);
  _gnutls_string_clear (&out_str);
  return result;
}
Exemplo n.º 3
0
/* Parses an Attribute list in the asn1_struct, and searches for the
 * given OID. The index indicates the attribute value to be returned.
 *
 * If raw==0 only printable data are returned, or GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE.
 *
 * asn1_attr_name must be a string in the form "certificationRequestInfo.attributes"
 *
 */
static int
parse_attribute (ASN1_TYPE asn1_struct,
                 const char *attr_name, const char *given_oid, int indx,
                 int raw, char *buf, size_t * sizeof_buf)
{
    int k1, result;
    char tmpbuffer1[MAX_NAME_SIZE];
    char tmpbuffer3[MAX_NAME_SIZE];
    char value[200];
    char oid[128];
    int len, printable;

    if (*sizeof_buf == 0)
    {
        gnutls_assert ();
        return GNUTLS_E_INVALID_REQUEST;
    }

    buf[0] = 0;

    k1 = 0;
    do
    {

        k1++;
        /* create a string like "attribute.?1"
         */
        if (attr_name[0] != 0)
            snprintf( tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", attr_name, k1);
        else
            snprintf( tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);

        len = sizeof (value) - 1;
        result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);

        if (result == ASN1_ELEMENT_NOT_FOUND)
        {
            gnutls_assert ();
            break;
        }

        if (result != ASN1_VALUE_NOT_FOUND)
        {
            gnutls_assert ();
            result = _gnutls_asn2err (result);
            goto cleanup;
        }

        /* Move to the attibute type and values
         */
        /* Read the OID
         */
        _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer1);
        _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");

        len = sizeof (oid) - 1;
        result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);

        if (result == ASN1_ELEMENT_NOT_FOUND)
            break;
        else if (result != ASN1_SUCCESS)
        {
            gnutls_assert ();
            result = _gnutls_asn2err (result);
            goto cleanup;
        }

        if (strcmp (oid, given_oid) == 0)
        {   /* Found the OID */

            /* Read the Value
             */
            snprintf( tmpbuffer3, sizeof (tmpbuffer3), "%s.values.?%u", tmpbuffer1, indx+1);

            len = sizeof (value) - 1;
            result = asn1_read_value (asn1_struct, tmpbuffer3, value, &len);

            if (result != ASN1_SUCCESS)
            {
                gnutls_assert ();
                result = _gnutls_asn2err (result);
                goto cleanup;
            }

            if (raw == 0)
            {
                printable = _gnutls_x509_oid_data_printable (oid);
                if (printable == 1)
                {
                    if ((result =
                                _gnutls_x509_oid_data2string
                                (oid, value, len, buf, sizeof_buf)) < 0)
                    {
                        gnutls_assert ();
                        goto cleanup;
                    }
                    return 0;
                }
                else
                {
                    gnutls_assert ();
                    return GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE;
                }
            }
            else
            {   /* raw!=0 */
                if (*sizeof_buf > (size_t) len && buf != NULL)
                {
                    *sizeof_buf = len;
                    memcpy (buf, value, len);

                    return 0;
                }
                else
                {
                    *sizeof_buf = len;
                    gnutls_assert ();
                    return GNUTLS_E_SHORT_MEMORY_BUFFER;
                }
            }
        }

    }
    while (1);

    gnutls_assert ();

    result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;

cleanup:
    return result;
}