Esempio n. 1
0
/* This will write the AttributeTypeAndValue field. The data must be already DER encoded.
 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
 * In all cases only one value is written.
 */
static int
_gnutls_x509_write_attribute(const char *given_oid,
			     ASN1_TYPE asn1_struct, const char *where,
			     const void *_data, int sizeof_data)
{
	char tmp[128];
	int result;

	/* write the data (value)
	 */

	_gnutls_str_cpy(tmp, sizeof(tmp), where);
	_gnutls_str_cat(tmp, sizeof(tmp), ".value");

	result = asn1_write_value(asn1_struct, tmp, _data, sizeof_data);
	if (result < 0) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	/* write the type
	 */
	_gnutls_str_cpy(tmp, sizeof(tmp), where);
	_gnutls_str_cat(tmp, sizeof(tmp), ".type");

	result = asn1_write_value(asn1_struct, tmp, given_oid, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	return 0;
}
Esempio n. 2
0
static int
write_new_general_name(ASN1_TYPE ext, const char *ext_name,
                       gnutls_x509_subject_alt_name_t type,
                       const void *data, unsigned int data_size)
{
    const char *str;
    int result;
    char name[128];

    result = asn1_write_value(ext, ext_name, "NEW", 1);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        return _gnutls_asn2err(result);
    }

    switch (type) {
    case GNUTLS_SAN_DNSNAME:
        str = "dNSName";
        break;
    case GNUTLS_SAN_RFC822NAME:
        str = "rfc822Name";
        break;
    case GNUTLS_SAN_URI:
        str = "uniformResourceIdentifier";
        break;
    case GNUTLS_SAN_IPADDRESS:
        str = "iPAddress";
        break;
    default:
        gnutls_assert();
        return GNUTLS_E_INTERNAL_ERROR;
    }

    if (ext_name[0] == 0) {	/* no dot */
        _gnutls_str_cpy(name, sizeof(name), "?LAST");
    } else {
        _gnutls_str_cpy(name, sizeof(name), ext_name);
        _gnutls_str_cat(name, sizeof(name), ".?LAST");
    }

    result = asn1_write_value(ext, name, str, 1);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        return _gnutls_asn2err(result);
    }

    _gnutls_str_cat(name, sizeof(name), ".");
    _gnutls_str_cat(name, sizeof(name), str);

    result = asn1_write_value(ext, name, data, data_size);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        asn1_delete_structure(&ext);
        return _gnutls_asn2err(result);
    }

    return 0;
}
Esempio n. 3
0
/*
 * This function writes and encodes the parameters for DSS or RSA keys.
 * This is the "signatureAlgorithm" fields.
 */
int
_gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
                               gnutls_pk_algorithm_t pk_algorithm,
                               gnutls_digest_algorithm_t dig)
{
  int result;
  char name[128];
  const char *pk;

  _gnutls_str_cpy (name, sizeof (name), dst_name);
  _gnutls_str_cat (name, sizeof (name), ".algorithm");

  pk = _gnutls_x509_sign_to_oid (pk_algorithm, HASH2MAC (dig));
  if (pk == NULL)
    {
      gnutls_assert ();
      _gnutls_debug_log
        ("Cannot find OID for sign algorithm pk: %d dig: %d\n",
         (int) pk_algorithm, (int) dig);
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* write the OID.
   */
  result = asn1_write_value (dst, name, pk, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }


  _gnutls_str_cpy (name, sizeof (name), dst_name);
  _gnutls_str_cat (name, sizeof (name), ".parameters");

  if (pk_algorithm == GNUTLS_PK_RSA)
    result = asn1_write_value (dst, name, ASN1_NULL, ASN1_NULL_SIZE);
  else
    result = asn1_write_value (dst, name, NULL, 0);

  if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
    {
      /* Here we ignore the element not found error, since this
       * may have been disabled before.
       */
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  return 0;
}
Esempio n. 4
0
/* This will write the AttributeTypeAndValue field. The data must be already DER encoded.
 * 'multi' must be zero if writing an AttributeTypeAndValue, and 1 if Attribute.
 * In all cases only one value is written.
 */
int
_gnutls_x509_write_attribute (const char *given_oid,
			      ASN1_TYPE asn1_struct, const char *where,
			      const void *_data, int sizeof_data, int multi)
{
  char tmp[128];
  int result;

  /* write the data (value)
   */

  _gnutls_str_cpy (tmp, sizeof (tmp), where);
  _gnutls_str_cat (tmp, sizeof (tmp), ".value");

  if (multi != 0)
    {				/* if not writing an AttributeTypeAndValue, but an Attribute */
      _gnutls_str_cat (tmp, sizeof (tmp), "s");	/* values */

      result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  return _gnutls_asn2err (result);
	}

      _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");

    }

  result = asn1_write_value (asn1_struct, tmp, _data, sizeof_data);
  if (result < 0)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  /* write the type
   */
  _gnutls_str_cpy (tmp, sizeof (tmp), where);
  _gnutls_str_cat (tmp, sizeof (tmp), ".type");

  result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  return 0;
}
Esempio n. 5
0
/* Decodes an X.509 Attribute (if multi==1) or an AttributeTypeAndValue
 * otherwise.
 *
 * octet_string should be non-zero if we are to decode octet strings after
 * decoding.
 *
 * The output is allocated and stored in value.
 */
int
_gnutls_x509_decode_and_read_attribute(ASN1_TYPE asn1_struct,
				       const char *where, char *oid,
				       int oid_size,
				       gnutls_datum_t * value, int multi,
				       int octet_string)
{
	char tmpbuffer[128];
	int len, result;

	/* Read the OID 
	 */
	_gnutls_str_cpy(tmpbuffer, sizeof(tmpbuffer), where);
	_gnutls_str_cat(tmpbuffer, sizeof(tmpbuffer), ".type");

	len = oid_size - 1;
	result = asn1_read_value(asn1_struct, tmpbuffer, oid, &len);

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

	/* Read the Value 
	 */

	_gnutls_str_cpy(tmpbuffer, sizeof(tmpbuffer), where);
	_gnutls_str_cat(tmpbuffer, sizeof(tmpbuffer), ".value");

	if (multi)
		_gnutls_str_cat(tmpbuffer, sizeof(tmpbuffer), "s.?1");	/* .values.?1 */

	if (octet_string)
		result =
		    _gnutls_x509_read_string(asn1_struct, tmpbuffer, value,
					     ASN1_ETYPE_OCTET_STRING, 0);
	else
		result =
		    _gnutls_x509_read_value(asn1_struct, tmpbuffer, value);
	if (result < 0) {
		gnutls_assert();
		return result;
	}

	return 0;

}
Esempio n. 6
0
time_t
_gnutls_x509_get_time (ASN1_TYPE c2, const char *when)
{
  char ttime[MAX_TIME];
  char name[128];
  time_t c_time = (time_t) - 1;
  int len, result;

  _gnutls_str_cpy (name, sizeof (name), when);

  len = sizeof (ttime) - 1;
  if ((result = asn1_read_value (c2, name, ttime, &len)) < 0)
    {
      gnutls_assert ();
      return (time_t) (-1);
    }

  /* CHOICE */
  if (strcmp (ttime, "generalTime") == 0)
    {

      _gnutls_str_cat (name, sizeof (name), ".generalTime");
      len = sizeof (ttime) - 1;
      result = asn1_read_value (c2, name, ttime, &len);
      if (result == ASN1_SUCCESS)
        c_time = _gnutls_x509_generalTime2gtime (ttime);
    }
  else
    {                           /* UTCTIME */

      _gnutls_str_cat (name, sizeof (name), ".utcTime");
      len = sizeof (ttime) - 1;
      result = asn1_read_value (c2, name, ttime, &len);
      if (result == ASN1_SUCCESS)
        c_time = _gnutls_x509_utcTime2gtime (ttime);
    }

  /* We cannot handle dates after 2031 in 32 bit machines.
   * a time_t of 64bits has to be used.
   */

  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return (time_t) (-1);
    }
  return c_time;
}
Esempio n. 7
0
int
_gnutls_write_new_general_name(ASN1_TYPE ext, const char *ext_name,
		       gnutls_x509_subject_alt_name_t type,
		       const void *data, unsigned int data_size)
{
	int result;
	char name[128];

	result = asn1_write_value(ext, ext_name, "NEW", 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	if (ext_name[0] == 0) {	/* no dot */
		_gnutls_str_cpy(name, sizeof(name), "?LAST");
	} else {
		_gnutls_str_cpy(name, sizeof(name), ext_name);
		_gnutls_str_cat(name, sizeof(name), ".?LAST");
	}

	result = _gnutls_write_general_name(ext, name, type,
		data, data_size);
	if (result < 0) {
		gnutls_assert();
		return result;
	}

	return 0;
}
Esempio n. 8
0
/* Sets the time in time_t in the ASN1_TYPE given. Where should
 * be something like "tbsCertList.thisUpdate".
 */
int
_gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim)
{
  char str_time[MAX_TIME];
  char name[128];
  int result, len;

  _gnutls_str_cpy (name, sizeof (name), where);

  if ((result = asn1_write_value (c2, name, "utcTime", 1)) < 0)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  result = _gnutls_x509_gtime2utcTime (tim, str_time, sizeof (str_time));
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  _gnutls_str_cat (name, sizeof (name), ".utcTime");

  len = strlen (str_time);
  result = asn1_write_value (c2, name, str_time, len);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  return 0;
}
Esempio n. 9
0
/* This function will attempt to return the requested extension OID found in
 * the given X509v3 certificate. 
 *
 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
 * be returned.
 */
static int get_extension_oid(ASN1_TYPE asn, const char *root,
		  unsigned indx, void *oid, size_t * sizeof_oid)
{
	int k, result, len;
	char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
	char extnID[MAX_OID_SIZE];
	unsigned indx_counter = 0;

	k = 0;
	do {
		k++;

		snprintf(name, sizeof(name), "%s.?%u", root, k);

		_gnutls_str_cpy(name2, sizeof(name2), name);
		_gnutls_str_cat(name2, sizeof(name2), ".extnID");

		len = sizeof(extnID) - 1;
		result = asn1_read_value(asn, name2, extnID, &len);

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

		/* Handle Extension 
		 */
		if (indx == indx_counter++) {
			len = strlen(extnID) + 1;

			if (*sizeof_oid < (unsigned) len) {
				*sizeof_oid = len;
				gnutls_assert();
				return GNUTLS_E_SHORT_MEMORY_BUFFER;
			}

			memcpy(oid, extnID, len);
			*sizeof_oid = len - 1;

			return 0;
		}


	}
	while (1);

	if (result == ASN1_ELEMENT_NOT_FOUND) {
		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
	} else {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}
}
Esempio n. 10
0
void
_asnstr_append_name(char *name, size_t name_size, const char *part1,
		    const char *part2)
{
	if (part1[0] != 0) {
		_gnutls_str_cpy(name, name_size, part1);
		_gnutls_str_cat(name, name_size, part2);
	} else
		_gnutls_str_cpy(name, name_size,
				part2 + 1 /* remove initial dot */ );
}
Esempio n. 11
0
/* Overwrite the given extension (using the index)
 * index here starts from one.
 */
static int
overwrite_extension (ASN1_TYPE asn, const char *root, unsigned int indx,
                     const gnutls_datum_t * ext_data, unsigned int critical)
{
  char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
  const char *str;
  int result;

  if (root[0] != 0)
    snprintf (name, sizeof (name), "%s.?%u", root, indx);
  else
    snprintf (name, sizeof (name), "?%u", indx);

  if (critical == 0)
    str = "FALSE";
  else
    str = "TRUE";

  _gnutls_str_cpy (name2, sizeof (name2), name);
  _gnutls_str_cat (name2, sizeof (name2), ".critical");

  result = asn1_write_value (asn, name2, str, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  _gnutls_str_cpy (name2, sizeof (name2), name);
  _gnutls_str_cat (name2, sizeof (name2), ".extnValue");

  result = _gnutls_x509_write_value (asn, name2, ext_data);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  return 0;
}
Esempio n. 12
0
/* Decodes an octet string. Leave string_type null for a normal
 * octet string. Otherwise put something like BMPString, PrintableString
 * etc.
 */
int
_gnutls_x509_decode_octet_string (const char *string_type,
                                  const opaque * der, size_t der_size,
                                  opaque * output, size_t * output_size)
{
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  int result, tmp_output_size;
  char strname[64];

  if (string_type == NULL)
    _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.pkcs-7-Data");
  else
    {
      _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.");
      _gnutls_str_cat (strname, sizeof (strname), string_type);
    }

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), strname, &c2)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  result = asn1_der_decoding (&c2, der, der_size, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  tmp_output_size = *output_size;
  result = asn1_read_value (c2, "", output, &tmp_output_size);
  *output_size = tmp_output_size;

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

  result = 0;

cleanup:
  if (c2)
    asn1_delete_structure (&c2);

  return result;
}
Esempio n. 13
0
/* Sets the time in time_t in the ASN1_TYPE given. Where should
 * be something like "tbsCertList.thisUpdate".
 */
int
_gnutls_x509_set_time(ASN1_TYPE c2, const char *where, time_t tim,
		      int nochoice)
{
	char str_time[MAX_TIME];
	char name[128];
	int result, len;

	if (nochoice != 0) {
		result =
		    gtime2generalTime(tim, str_time, sizeof(str_time));
		if (result < 0)
			return gnutls_assert_val(result);
		len = strlen(str_time);
		result = asn1_write_value(c2, where, str_time, len);
		if (result != ASN1_SUCCESS)
			return gnutls_assert_val(_gnutls_asn2err(result));

		return 0;
	}

	_gnutls_str_cpy(name, sizeof(name), where);

	if ((result = asn1_write_value(c2, name, "generalTime", 1)) < 0) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	result = gtime2generalTime(tim, str_time, sizeof(str_time));
	if (result < 0) {
		gnutls_assert();
		return result;
	}

	_gnutls_str_cat(name, sizeof(name), ".generalTime");

	len = strlen(str_time);
	result = asn1_write_value(c2, name, str_time, len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	return 0;
}
Esempio n. 14
0
/* Converts a data string to an LDAP rfc2253 hex string
 * something like '#01020304'
 */
int
_gnutls_x509_data2hex (const opaque * data, size_t data_size,
                       opaque * out, size_t * sizeof_out)
{
  char *res;
  char escaped[MAX_STRING_LEN];
  unsigned int size;

  if (2 * data_size + 1 > MAX_STRING_LEN)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  res = _gnutls_bin2hex (data, data_size, escaped, sizeof (escaped), NULL);
  if (!res)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  size = strlen (res) + 1;
  if (size + 1 > *sizeof_out)
    {
      *sizeof_out = size;
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
    }
  *sizeof_out = size;           /* -1 for the null +1 for the '#' */

  if (out)
    {
      out[0] = '#';
      out[1] = 0;
      _gnutls_str_cat (out, *sizeof_out, res);
    }

  return 0;
}
Esempio n. 15
0
static int
text_encode (void *data, FILE * in, FILE * out)
{
  const char *s;
  char buf[2048];

  if (!in || !out)
    return CDK_Inv_Value;

  /* FIXME: This code does not work for very long lines. */
  while (!feof (in))
    {
      /* give space for trim_string \r\n */
      s = fgets (buf, DIM (buf) - 3, in);
      if (!s)
        break;
      _cdk_trim_string (buf);
      _gnutls_str_cat (buf, sizeof(buf), "\r\n");
      fwrite (buf, 1, strlen (buf), out);
    }

  return 0;
}
Esempio n. 16
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;
}
Esempio n. 17
0
File: mpi.c Progetto: bf4/pidgin-mac
/*
 * This function writes and encodes the parameters for DSS or RSA keys.
 * This is the "signatureAlgorithm" fields.
 */
int
_gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
			       gnutls_pk_algorithm_t pk_algorithm,
			       gnutls_digest_algorithm_t dig,
			       bigint_t * params, int params_size)
{
  gnutls_datum_t der;
  int result;
  char name[128];
  const char *pk;

  _gnutls_str_cpy (name, sizeof (name), dst_name);
  _gnutls_str_cat (name, sizeof (name), ".algorithm");

  pk = _gnutls_x509_sign_to_oid (pk_algorithm, HASH2MAC (dig));
  if (pk == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* write the OID.
   */
  result = asn1_write_value (dst, name, pk, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }


  _gnutls_str_cpy (name, sizeof (name), dst_name);
  _gnutls_str_cat (name, sizeof (name), ".parameters");

  if (pk_algorithm == GNUTLS_PK_DSA)
    {
      result = _gnutls_x509_write_dsa_params (params, params_size, &der);
      if (result < 0)
	{
	  gnutls_assert ();
	  return result;
	}

      result = asn1_write_value (dst, name, der.data, der.size);
      _gnutls_free_datum (&der);

      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  return _gnutls_asn2err (result);
	}
    }
  else
    {				/* RSA */
      result = asn1_write_value (dst, name, NULL, 0);

      if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
	{
	  /* Here we ignore the element not found error, since this
	   * may have been disabled before.
	   */
	  gnutls_assert ();
	  return _gnutls_asn2err (result);
	}
    }

  return 0;
}
Esempio n. 18
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, gnutls_datum_t * out)
{
	int k2, k1, result;
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	gnutls_datum_t td;
	uint8_t value[256];
	char oid[MAX_OID_SIZE];
	int len;
	int i = 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");

				result =
				    _gnutls_x509_read_value(asn1_struct,
							    tmpbuffer3,
							    &td);
				if (result < 0) {
					gnutls_assert();
					goto cleanup;
				}

				if (raw_flag != 0) {
					out->data = td.data;
					out->size = td.size;
					return 0;

				} else {	/* parse data. raw_flag == 0 */
					result =
					    _gnutls_x509_dn_to_string(oid,
								      td.
								      data,
								      td.
								      size,
								      out);

					_gnutls_free_datum(&td);
					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;
}
Esempio n. 19
0
/* Sets an X509 DN in the asn1_struct, and puts the given OID in the DN.
 * The input is assumed to be raw data.
 *
 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer".
 * That is to point before the rndSequence.
 *
 */
int
_gnutls_x509_set_dn_oid(ASN1_TYPE asn1_struct,
			const char *asn1_name, const char *given_oid,
			int raw_flag, const char *name, int sizeof_name)
{
	int result;
	char tmp[ASN1_MAX_NAME_SIZE], asn1_rdn_name[ASN1_MAX_NAME_SIZE];

	if (sizeof_name == 0 || name == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	/* create the rdnSequence
	 */
	result =
	    asn1_write_value(asn1_struct, asn1_name, "rdnSequence", 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	_gnutls_str_cpy(asn1_rdn_name, sizeof(asn1_rdn_name), asn1_name);
	_gnutls_str_cat(asn1_rdn_name, sizeof(asn1_rdn_name),
			".rdnSequence");

	/* create a new element 
	 */
	result = asn1_write_value(asn1_struct, asn1_rdn_name, "NEW", 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	_gnutls_str_cpy(tmp, sizeof(tmp), asn1_rdn_name);
	_gnutls_str_cat(tmp, sizeof(tmp), ".?LAST");

	/* create the set with only one element
	 */
	result = asn1_write_value(asn1_struct, tmp, "NEW", 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}


	/* Encode and write the data
	 */
	_gnutls_str_cpy(tmp, sizeof(tmp), asn1_rdn_name);
	_gnutls_str_cat(tmp, sizeof(tmp), ".?LAST.?LAST");

	if (!raw_flag) {
		result =
		    _gnutls_x509_encode_and_write_attribute(given_oid,
							    asn1_struct,
							    tmp, name,
							    sizeof_name,
							    0);
	} else {
		result =
		    _gnutls_x509_write_attribute(given_oid, asn1_struct,
						 tmp, name, sizeof_name);
	}

	if (result < 0) {
		gnutls_assert();
		return result;
	}

	return 0;
}
Esempio n. 20
0
int
get_extension (ASN1_TYPE asn, const char *root,
               const char *extension_id, int indx,
               gnutls_datum_t * ret, unsigned int *_critical)
{
  int k, result, len;
  char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
  char str[1024];
  char str_critical[10];
  int critical = 0;
  char extnID[128];
  gnutls_datum_t value;
  int indx_counter = 0;

  ret->data = NULL;
  ret->size = 0;

  k = 0;
  do
    {
      k++;

      snprintf (name, sizeof (name), "%s.?%u", root, k);

      len = sizeof (str) - 1;
      result = asn1_read_value (asn, name, str, &len);

      /* move to next
       */

      if (result == ASN1_ELEMENT_NOT_FOUND)
        {
          break;
        }

      do
        {

          _gnutls_str_cpy (name2, sizeof (name2), name);
          _gnutls_str_cat (name2, sizeof (name2), ".extnID");

          len = sizeof (extnID) - 1;
          result = asn1_read_value (asn, name2, extnID, &len);

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

          /* Handle Extension 
           */
          if (strcmp (extnID, extension_id) == 0 && indx == indx_counter++)
            {
              /* extension was found 
               */

              /* read the critical status.
               */
              _gnutls_str_cpy (name2, sizeof (name2), name);
              _gnutls_str_cat (name2, sizeof (name2), ".critical");

              len = sizeof (str_critical);
              result = asn1_read_value (asn, name2, str_critical, &len);

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

              if (str_critical[0] == 'T')
                critical = 1;
              else
                critical = 0;

              /* read the value.
               */
              _gnutls_str_cpy (name2, sizeof (name2), name);
              _gnutls_str_cat (name2, sizeof (name2), ".extnValue");

              result = _gnutls_x509_read_value (asn, name2, &value);
              if (result < 0)
                {
                  gnutls_assert ();
                  return result;
                }

              ret->data = value.data;
              ret->size = value.size;

              if (_critical)
                *_critical = critical;

              return 0;
            }


        }
      while (0);
    }
  while (1);

  if (result == ASN1_ELEMENT_NOT_FOUND)
    {
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    }
  else
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }
}
Esempio n. 21
0
int
_gnutls_x509_get_dn(ASN1_TYPE asn1_struct,
		    const char *asn1_rdn_name, gnutls_datum_t * dn)
{
	gnutls_buffer_st out_str;
	int k2, k1, result;
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	uint8_t value[MAX_STRING_LEN];
	gnutls_datum_t td = { NULL, 0 }, tvd = {
	NULL, 0};
	const char *ldap_desc;
	char oid[MAX_OID_SIZE];
	int len;

	_gnutls_buffer_init(&out_str);

	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) {
			if (k1 == 1) {
				gnutls_assert();
				result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
				goto cleanup;
			}
			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 =
			    _gnutls_x509_read_value(asn1_struct,
						    tmpbuffer3, &tvd);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
#define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( &out_str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
#define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( &out_str, x,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 =
			    gnutls_x509_dn_oid_name(oid,
						    GNUTLS_X509_DN_OID_RETURN_OID);

			STR_APPEND(ldap_desc);
			STR_APPEND("=");

			result =
			    _gnutls_x509_dn_to_string(oid, tvd.data,
						      tvd.size, &td);
			if (result < 0) {
				gnutls_assert();
				_gnutls_debug_log
				    ("Cannot parse OID: '%s' with value '%s'\n",
				     oid, _gnutls_bin2hex(tvd.data,
							  tvd.size,
							  tmpbuffer3,
							  sizeof
							  (tmpbuffer3),
							  NULL));
				goto cleanup;
			}

			DATA_APPEND(td.data, td.size);
			_gnutls_free_datum(&td);
			_gnutls_free_datum(&tvd);
		}
		while (1);
	}
	while (1);

	result = _gnutls_buffer_to_datum(&out_str, dn, 1);
	if (result < 0)
		gnutls_assert();

	goto cleanup1;

      cleanup:
	_gnutls_buffer_clear(&out_str);
      cleanup1:
	_gnutls_free_datum(&td);
	_gnutls_free_datum(&tvd);
	return result;

}
Esempio n. 22
0
/*-
 * _gnutls_x509_pkix_sign - This function will sign a CRL or a certificate with a key
 * @src: should contain an ASN1_TYPE
 * @issuer: is the certificate of the certificate issuer
 * @issuer_key: holds the issuer's private key
 *
 * This function will sign a CRL or a certificate with the issuer's private key, and
 * will copy the issuer's information into the CRL or certificate.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value.
 -*/
int
_gnutls_x509_pkix_sign (ASN1_TYPE src, const char *src_name,
			gnutls_digest_algorithm_t dig,
			gnutls_x509_crt_t issuer,
			gnutls_x509_privkey_t issuer_key)
{
  int result;
  gnutls_datum_t signature;
  char name[128];

  /* Step 1. Copy the issuer's name into the certificate.
   */
  _gnutls_str_cpy (name, sizeof (name), src_name);
  _gnutls_str_cat (name, sizeof (name), ".issuer");

  result = asn1_copy_node (src, name, issuer->cert, "tbsCertificate.subject");
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  /* Step 1.5. Write the signature stuff in the tbsCertificate.
   */
  _gnutls_str_cpy (name, sizeof (name), src_name);
  _gnutls_str_cat (name, sizeof (name), ".signature");

  result = _gnutls_x509_write_sig_params (src, name,
					  issuer_key->pk_algorithm, dig,
					  issuer_key->params,
					  issuer_key->params_size);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  /* Step 2. Sign the certificate.
   */
  result = _gnutls_x509_sign_tbs (src, src_name, dig, issuer_key, &signature);

  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  /* write the signature (bits)
   */
  result =
    asn1_write_value (src, "signature", signature.data, signature.size * 8);

  _gnutls_free_datum (&signature);

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

  /* Step 3. Move up and write the AlgorithmIdentifier, which is also
   * the same. 
   */

  result = _gnutls_x509_write_sig_params (src, "signatureAlgorithm",
					  issuer_key->pk_algorithm, dig,
					  issuer_key->params,
					  issuer_key->params_size);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  return 0;
}
Esempio n. 23
0
/* This function is like write. But it does not return -1 on error.
 * It does return gnutls_errno instead.
 *
 * In case of E_AGAIN and E_INTERRUPTED errors, you must call gnutls_write_flush(),
 * until it returns ok (0).
 *
 * We need to push exactly the data in n, since we cannot send less
 * data. In TLS the peer must receive the whole packet in order
 * to decrypt and verify the integrity.
 *
 */
ssize_t
_gnutls_io_write_buffered (gnutls_session_t session,
                           const void *iptr, size_t n)
{
    size_t left;
    unsigned j, x, sum = 0;
    ssize_t retval, i;
    const opaque *ptr;
    int ret;
    gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;

    /* to know where the procedure was interrupted.
     */
    session->internals.direction = 1;

    ptr = iptr;

    /* In case the previous write was interrupted, check if the
     * iptr != NULL and we have data in the buffer.
     * If this is true then return an error.
     */
    if (session->internals.record_send_buffer.length > 0 && iptr != NULL)
    {
        gnutls_assert ();
        return GNUTLS_E_INVALID_REQUEST;
    }

    /* If data in the buffer exist
     */
    if (iptr == NULL)
    {
        /* checking is handled above */
        ret =
            _gnutls_buffer_get (&session->internals.record_send_buffer, &ptr, &n);
        if (ret < 0)
        {
            gnutls_assert ();
            return ret;
        }

        _gnutls_write_log
        ("WRITE: Restoring old write. (%d bytes to send)\n", n);
    }

    _gnutls_write_log ("WRITE: Will write %d bytes to %d.\n", n, fd);

    i = 0;
    left = n;
    while (left > 0)
    {

        if (session->internals._gnutls_push_func == NULL)
            i = send (GNUTLS_POINTER_TO_INT(fd), &ptr[n - left], left, 0);
        else
            i = session->internals._gnutls_push_func (fd, &ptr[n - left], left);

        if (i == -1)
        {
            if (errno == EAGAIN || errno == EINTR)
            {
                session->internals.record_send_buffer_prev_size += n - left;

                retval =
                    _gnutls_buffer_insert (&session->internals.
                                           record_send_buffer,
                                           &ptr[n - left], left);
                if (retval < 0)
                {
                    gnutls_assert ();
                    return retval;
                }

                _gnutls_write_log
                ("WRITE: Interrupted. Stored %d bytes to buffer. Already sent %d bytes.\n",
                 left, n - left);

                retval = RET (errno);

                return retval;
            }
            else
            {
                gnutls_assert ();
                return GNUTLS_E_PUSH_ERROR;
            }
        }
        left -= i;


        if (_gnutls_log_level >= 7)
        {
            char line[128];
            char tmp[16];


            _gnutls_write_log
            ("WRITE: wrote %d bytes to %d. Left %d bytes. Total %d bytes.\n",
             i, fd, left, n);
            for (x = 0; x < (unsigned) ((i) / 16) + 1; x++)
            {
                line[0] = 0;

                if (sum > n - left)
                    break;

                sprintf (tmp, "%.4x - ", x);
                _gnutls_str_cat (line, sizeof (line), tmp);

                for (j = 0; j < 16; j++)
                {
                    if (sum < n - left)
                    {
                        sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
                        _gnutls_str_cat (line, sizeof (line), tmp);
                    }
                    else
                        break;
                }
                _gnutls_write_log ("%s\n", line);
            }
        }
    }

    retval = n + session->internals.record_send_buffer_prev_size;

    session->internals.record_send_buffer.length = 0;
    session->internals.record_send_buffer_prev_size = 0;

    return retval;

}
Esempio n. 24
0
/* This function is like read. But it does not return -1 on error.
 * It does return gnutls_errno instead.
 *
 * Flags are only used if the default recv() function is being used.
 */
static ssize_t
_gnutls_read (gnutls_session_t session, void *iptr,
              size_t sizeOfPtr, int flags)
{
    size_t left;
    ssize_t i = 0;
    char *ptr = iptr;
    unsigned j, x, sum = 0;
    gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;

    session->internals.direction = 0;

    left = sizeOfPtr;
    while (left > 0)
    {

        if (session->internals._gnutls_pull_func == NULL)
            i = recv (GNUTLS_POINTER_TO_INT(fd), &ptr[sizeOfPtr - left],
                      left, flags);
        else
            i = session->internals._gnutls_pull_func (fd,
                    &ptr[sizeOfPtr -
                         left], left);

        if (i < 0)
        {
            _gnutls_read_log ("READ: %d returned from %d, errno=%d\n", i,
                              fd, errno);

            if (errno == EAGAIN || errno == EINTR)
            {
                if (sizeOfPtr - left > 0)
                {

                    _gnutls_read_log ("READ: returning %d bytes from %d\n",
                                      sizeOfPtr - left, fd);

                    goto finish;
                }
                gnutls_assert ();

                return RET (errno);
            }
            else
            {
                gnutls_assert ();
                return GNUTLS_E_PULL_ERROR;
            }
        }
        else
        {

            _gnutls_read_log ("READ: Got %d bytes from %d\n", i, fd);

            if (i == 0)
                break;		/* EOF */
        }

        left -= i;

    }

finish:

    if (_gnutls_log_level >= 7)
    {
        char line[128];
        char tmp[16];


        _gnutls_read_log ("READ: read %d bytes from %d\n",
                          (sizeOfPtr - left), fd);

        for (x = 0; x < ((sizeOfPtr - left) / 16) + 1; x++)
        {
            line[0] = 0;

            sprintf (tmp, "%.4x - ", x);
            _gnutls_str_cat (line, sizeof (line), tmp);

            for (j = 0; j < 16; j++)
            {
                if (sum < (sizeOfPtr - left))
                {
                    sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
                    _gnutls_str_cat (line, sizeof (line), tmp);
                }
            }
            _gnutls_read_log ("%s\n", line);
        }
    }

    return (sizeOfPtr - left);
}
Esempio n. 25
0
int
_gnutls_fbase64_decode (const char *header, const uint8_t * data,
                        size_t data_size, gnutls_datum_t* result)
{
  int ret;
  static const char top[] = "-----BEGIN ";
  static const char bottom[] = "-----END ";
  uint8_t *rdata, *kdata;
  int rdata_size;
  char pem_header[128];

  _gnutls_str_cpy (pem_header, sizeof (pem_header), top);
  if (header != NULL)
    _gnutls_str_cat (pem_header, sizeof (pem_header), header);

  rdata = memmem (data, data_size, pem_header, strlen (pem_header));

  if (rdata == NULL)
    {
      gnutls_assert ();
      _gnutls_debug_log ("Could not find '%s'\n", pem_header);
      return GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR;
    }

  data_size -= (unsigned long int) rdata - (unsigned long int) data;

  if (data_size < 4 + strlen (bottom))
    {
      gnutls_assert ();
      return GNUTLS_E_BASE64_DECODING_ERROR;
    }

  kdata = memmem (rdata + 1, data_size - 1, ENDSTR, sizeof (ENDSTR) - 1);
  /* allow CR as well.
   */
  if (kdata == NULL)
    {
      gnutls_assert ();
      _gnutls_debug_log ("Could not find '%s'\n", ENDSTR);
      return GNUTLS_E_BASE64_DECODING_ERROR;
    }
  data_size -= strlen (ENDSTR);
  data_size -= (unsigned long int) kdata - (unsigned long int) rdata;

  rdata = kdata + strlen (ENDSTR);

  /* position is now after the ---BEGIN--- headers */

  kdata = memmem (rdata, data_size, bottom, strlen (bottom));
  if (kdata == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_BASE64_DECODING_ERROR;
    }

  /* position of kdata is before the ----END--- footer 
   */
  rdata_size = (unsigned long int) kdata - (unsigned long int) rdata;

  if (rdata_size < 4)
    {
      gnutls_assert ();
      return GNUTLS_E_BASE64_DECODING_ERROR;
    }

  if ((ret = _gnutls_base64_decode (rdata, rdata_size, result)) < 0)
    {
      gnutls_assert ();
      return GNUTLS_E_BASE64_DECODING_ERROR;
    }

  return ret;
}
Esempio n. 26
0
int
set_extension (ASN1_TYPE asn, const char *root,
               const char *ext_id,
               const gnutls_datum_t * ext_data, unsigned int critical)
{
  int result;
  int k, len;
  char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
  char extnID[128];

  /* Find the index of the given extension.
   */
  k = 0;
  do
    {
      k++;

      if (root[0] != 0)
        snprintf (name, sizeof (name), "%s.?%u", root, k);
      else
        snprintf (name, sizeof (name), "?%u", k);

      len = sizeof (extnID) - 1;
      result = asn1_read_value (asn, name, extnID, &len);

      /* move to next
       */

      if (result == ASN1_ELEMENT_NOT_FOUND)
        {
          break;
        }

      do
        {

          _gnutls_str_cpy (name2, sizeof (name2), name);
          _gnutls_str_cat (name2, sizeof (name2), ".extnID");

          len = sizeof (extnID) - 1;
          result = asn1_read_value (asn, name2, extnID, &len);

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

          /* Handle Extension 
           */
          if (strcmp (extnID, ext_id) == 0)
            {
              /* extension was found 
               */
              return overwrite_extension (asn, root, k, ext_data, critical);
            }


        }
      while (0);
    }
  while (1);

  if (result == ASN1_ELEMENT_NOT_FOUND)
    {
      return add_extension (asn, root, ext_id, ext_data, critical);
    }
  else
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }


  return 0;
}
Esempio n. 27
0
/* encodes data and puts the result into result (locally allocated)
 * The result_size (including the null terminator) is the return value.
 */
int
_gnutls_fbase64_encode (const char *msg, const uint8_t * data,
                        size_t data_size, gnutls_datum_t * result)
{
  int tmp;
  unsigned int i;
  char tmpres[66];
  uint8_t *ptr;
  char top[80];
  char bottom[80];
  size_t size, max, bytes;
  int pos, top_len, bottom_len;

  if (msg == NULL || strlen(msg) > 50)
    {
      gnutls_assert ();
      return GNUTLS_E_BASE64_ENCODING_ERROR;
    }

  _gnutls_str_cpy (top, sizeof(top), "-----BEGIN ");
  _gnutls_str_cat (top, sizeof(top), msg);
  _gnutls_str_cat (top, sizeof(top), "-----\n");

  _gnutls_str_cpy (bottom, sizeof(bottom), "-----END ");
  _gnutls_str_cat (bottom, sizeof(bottom), msg);
  _gnutls_str_cat (bottom, sizeof(bottom), "-----\n");

  top_len = strlen (top);
  bottom_len = strlen (bottom);

  max = B64FSIZE (top_len+bottom_len, data_size);

  result->data = gnutls_malloc (max + 1);
  if (result->data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  bytes = pos = 0;
  INCR (bytes, top_len, max);
  pos = top_len;

  memcpy (result->data, top, top_len);

  for (i = 0; i < data_size; i += 48)
    {
      if (data_size - i < 48)
        tmp = data_size - i;
      else
        tmp = 48;

      base64_encode ((void*)&data[i], tmp, tmpres, sizeof(tmpres));
      size = strlen(tmpres);

      INCR (bytes, size+1, max);
      ptr = &result->data[pos];

      memcpy(ptr, tmpres, size);
      ptr += size;
      *ptr++ = '\n';

      pos += size + 1;
    }

  INCR (bytes, bottom_len, max);

  memcpy (&result->data[bytes - bottom_len], bottom, bottom_len);
  result->data[bytes] = 0;
  result->size = bytes;

  return max + 1;
}
Esempio n. 28
0
/* Parses an X509 DN in the asn1_struct, and returns the requested
 * DN OID.
 *
 * 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_get_dn_oid(ASN1_TYPE asn1_struct,
			const char *asn1_rdn_name,
			int indx, void *_oid, size_t * sizeof_oid)
{
	int k2, k1, result;
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	char value[256];
	char oid[MAX_OID_SIZE];
	int len;
	int i = 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 (indx == i++) {	/* Found the OID */

				len = strlen(oid) + 1;

				if (*sizeof_oid < (unsigned) len) {
					*sizeof_oid = len;
					gnutls_assert();
					return
					    GNUTLS_E_SHORT_MEMORY_BUFFER;
				}

				memcpy(_oid, oid, len);
				*sizeof_oid = len - 1;

				return 0;
			}
		}
		while (1);

	}
	while (1);

	gnutls_assert();

	result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;

      cleanup:
	return result;
}
Esempio n. 29
0
static int
write_attributes (gnutls_pkcs12_bag_t bag, int elem,
		  ASN1_TYPE c2, const char *where)
{
  int result;
  char root[128];

  /* If the bag attributes are empty, then write
   * nothing to the attribute field.
   */
  if (bag->element[elem].friendly_name == NULL &&
      bag->element[elem].local_key_id.data == NULL)
    {
      /* no attributes
       */
      result = asn1_write_value (c2, where, NULL, 0);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  return _gnutls_asn2err (result);
	}

      return 0;
    }

  if (bag->element[elem].local_key_id.data != NULL)
    {

      /* Add a new Attribute
       */
      result = asn1_write_value (c2, where, "NEW", 1);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  return _gnutls_asn2err (result);
	}

      _gnutls_str_cpy (root, sizeof (root), where);
      _gnutls_str_cat (root, sizeof (root), ".?LAST");

      result =
	_gnutls_x509_encode_and_write_attribute (KEY_ID_OID, c2, root,
						 bag->
						 element[elem].local_key_id.
						 data,
						 bag->
						 element[elem].local_key_id.
						 size, 1);
      if (result < 0)
	{
	  gnutls_assert ();
	  return result;
	}
    }

  if (bag->element[elem].friendly_name != NULL)
    {
      opaque *name;
      int size, i;
      const char *p;

      /* Add a new Attribute
       */
      result = asn1_write_value (c2, where, "NEW", 1);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  return _gnutls_asn2err (result);
	}

      /* convert name to BMPString
       */
      size = strlen (bag->element[elem].friendly_name) * 2;
      name = gnutls_malloc (size);

      if (name == NULL)
	{
	  gnutls_assert ();
	  return GNUTLS_E_MEMORY_ERROR;
	}

      p = bag->element[elem].friendly_name;
      for (i = 0; i < size; i += 2)
	{
	  name[i] = 0;
	  name[i + 1] = *p;
	  p++;
	}

      _gnutls_str_cpy (root, sizeof (root), where);
      _gnutls_str_cat (root, sizeof (root), ".?LAST");

      result =
	_gnutls_x509_encode_and_write_attribute (FRIENDLY_NAME_OID, c2,
						 root, name, size, 1);

      gnutls_free (name);

      if (result < 0)
	{
	  gnutls_assert ();
	  return result;
	}
    }

  return 0;
}
Esempio n. 30
0
/* This will encode and write the AttributeTypeAndValue field.
 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
 * In all cases only one value is written.
 */
int
_gnutls_x509_encode_and_write_attribute(const char *given_oid,
					ASN1_TYPE asn1_struct,
					const char *where,
					const void *_data,
					int data_size, int multi)
{
	const uint8_t *data = _data;
	char tmp[128];
	int result;
	const struct oid_to_string *oentry;

	oentry = get_oid_entry(given_oid);
	if (oentry == NULL) {
		gnutls_assert();
		_gnutls_debug_log("Cannot find OID: %s\n", given_oid);
		return GNUTLS_E_X509_UNSUPPORTED_OID;
	}

	/* write the data (value)
	 */

	_gnutls_str_cpy(tmp, sizeof(tmp), where);
	_gnutls_str_cat(tmp, sizeof(tmp), ".value");

	if (multi != 0) {	/* if not writing an AttributeTypeAndValue, but an Attribute */
		_gnutls_str_cat(tmp, sizeof(tmp), "s");	/* values */

		result = asn1_write_value(asn1_struct, tmp, "NEW", 1);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto error;
		}

		_gnutls_str_cat(tmp, sizeof(tmp), ".?LAST");
	}

	if (oentry->asn_desc != NULL) {	/* write a complex string API */
		result =
		    write_complex_string(asn1_struct, tmp, oentry, data,
					 data_size);
		if (result < 0)
			return gnutls_assert_val(result);
	} else {		/* write a simple string */

		gnutls_datum_t td;

		td.data = (void *) data;
		td.size = data_size;
		result =
		    _gnutls_x509_write_string(asn1_struct, tmp, &td,
					      oentry->etype);
		if (result < 0) {
			gnutls_assert();
			goto error;
		}
	}

	/* write the type
	 */
	_gnutls_str_cpy(tmp, sizeof(tmp), where);
	_gnutls_str_cat(tmp, sizeof(tmp), ".type");

	result = asn1_write_value(asn1_struct, tmp, given_oid, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result = 0;

      error:
	return result;
}