예제 #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;
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
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 */ );
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
0
파일: dn.c 프로젝트: uvbs/SupportCenter
/* 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;
}
예제 #8
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;

}
예제 #9
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;
}
예제 #10
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);
	}
}
예제 #11
0
파일: extensions.c 프로젝트: nobled/gnutls
/* 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;
}
예제 #12
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;
}
예제 #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;
}
예제 #14
0
파일: x509_b64.c 프로젝트: intgr/gnutls
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;
}
예제 #15
0
파일: x509_b64.c 프로젝트: intgr/gnutls
/* 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;
}
예제 #16
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;
}
예제 #17
0
/* Send the first key exchange message ( g, n, s) and append the verifier algorithm number 
 * Data is allocated by the caller, and should have data_size size.
 */
int
_gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data)
{
  int ret;
  uint8_t *data_n, *data_s;
  uint8_t *data_g;
  char *username;
  SRP_PWD_ENTRY *pwd_entry;
  srp_server_auth_info_t info;
  ssize_t data_size;
  size_t n_b, tmp_size;
  char buf[64];
  uint8_t *data_b;

  if ((ret =
       _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
			      sizeof (srp_server_auth_info_st), 1)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  info = _gnutls_get_auth_info (session);
  username = info->username;

  _gnutls_str_cpy (username, MAX_SRP_USERNAME,
		   session->security_parameters.extensions.srp_username);

  ret = _gnutls_srp_pwd_read_entry (session, username, &pwd_entry);

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

  /* copy from pwd_entry to local variables (actually in session) */
  tmp_size = pwd_entry->g.size;
  if (_gnutls_mpi_scan_nz (&G, pwd_entry->g.data, &tmp_size) < 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  tmp_size = pwd_entry->n.size;
  if (_gnutls_mpi_scan_nz (&N, pwd_entry->n.data, &tmp_size) < 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  tmp_size = pwd_entry->v.size;
  if (_gnutls_mpi_scan_nz (&V, pwd_entry->v.data, &tmp_size) < 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  /* Calculate:  B = (k*v + g^b) % N 
   */
  B = _gnutls_calc_srp_B (&_b, G, N, V);
  if (B == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  if (_gnutls_mpi_print (NULL, &n_b, B) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_PRINT_FAILED;
    }


  /* Allocate size to hold the N, g, s, B 
   */

  data_size = (pwd_entry->n.size + 2 + pwd_entry->g.size + 2 +
	       pwd_entry->salt.size + 1) + (n_b + 2);

  (*data) = gnutls_malloc (data_size);
  if ((*data) == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* copy N (mod n) 
   */
  data_n = *data;
  _gnutls_write_datum16 (data_n, pwd_entry->n);


  /* copy G (generator) to data 
   */
  data_g = &data_n[2 + pwd_entry->n.size];
  _gnutls_write_datum16 (data_g, pwd_entry->g);


  /* copy the salt 
   */
  data_s = &data_g[2 + pwd_entry->g.size];
  _gnutls_write_datum8 (data_s, pwd_entry->salt);


  /* Copy the B value
   */

  data_b = &data_s[1 + pwd_entry->salt.size];
  if (_gnutls_mpi_print (&data_b[2], &n_b, B) != 0) 
    {
      gnutls_assert();
      return GNUTLS_E_MPI_PRINT_FAILED;
    }

  _gnutls_write_uint16 (n_b, data_b);

  _gnutls_hard_log ("INT: SRP B[%d]: %s\n", n_b,
		    _gnutls_bin2hex (&data_b[2], n_b, buf, sizeof (buf)));

  _gnutls_srp_entry_free (pwd_entry);

  return data_size;
}
예제 #18
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;
}
예제 #19
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;

}
예제 #20
0
파일: mpi.c 프로젝트: 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;
}
예제 #21
0
/* This function will convert an attribute value, specified by the OID,
 * to a string. The result will be a null terminated string.
 *
 * res may be null. This will just return the res_size, needed to
 * hold the string.
 */
int
_gnutls_x509_oid_data2string (const char *oid, void *value,
                              int value_size, char *res, size_t * res_size)
{
  char str[MAX_STRING_LEN], tmpname[128];
  const char *ANAME = NULL;
  int CHOICE = -1, len = -1, result;
  ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
  char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";

  if (value == NULL || value_size <= 0 || res_size == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (_gnutls_x509_oid_data_printable (oid) == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ANAME = _gnutls_x509_oid2asn_string (oid);
  CHOICE = _gnutls_x509_oid_data_choice (oid);

  if (ANAME == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  if ((result =
       asn1_create_element (_gnutls_get_pkix (), ANAME,
                            &tmpasn)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  if ((result =
       asn1_der_decoding (&tmpasn, value, value_size,
                          asn1_err)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      _gnutls_debug_log ("asn1_der_decoding: %s:%s\n", str, asn1_err);
      asn1_delete_structure (&tmpasn);
      return _gnutls_asn2err (result);
    }

  /* If this is a choice then we read the choice. Otherwise it
   * is the value;
   */
  len = sizeof (str) - 1;
  if ((result = asn1_read_value (tmpasn, "", str, &len)) != ASN1_SUCCESS)
    {                           /* CHOICE */
      gnutls_assert ();
      asn1_delete_structure (&tmpasn);
      return _gnutls_asn2err (result);
    }

  if (CHOICE == 0)
    {
      str[len] = 0;

      /* Refuse to deal with strings containing NULs. */
      if (strlen (str) != len)
        return GNUTLS_E_ASN1_DER_ERROR;

      if (res)
        _gnutls_str_cpy (res, *res_size, str);
      *res_size = len;

      asn1_delete_structure (&tmpasn);
    }
  else
    {                           /* CHOICE */
      int non_printable = 0, teletex = 0;
      str[len] = 0;

      /* Note that we do not support strings other than
       * UTF-8 (thus ASCII as well).
       */
      if (strcmp (str, "printableString") != 0 &&
          strcmp (str, "ia5String") != 0 && strcmp (str, "utf8String") != 0)
        {
          non_printable = 1;
        }
      if (strcmp (str, "teletexString") == 0)
        teletex = 1;


      _gnutls_str_cpy (tmpname, sizeof (tmpname), str);

      len = sizeof (str) - 1;
      if ((result =
           asn1_read_value (tmpasn, tmpname, str, &len)) != ASN1_SUCCESS)
        {
          asn1_delete_structure (&tmpasn);
          return _gnutls_asn2err (result);
        }

      asn1_delete_structure (&tmpasn);

      if (teletex != 0)
        {
          int ascii = 0, i;
          /* HACK: if the teletex string contains only ascii
           * characters then treat it as printable.
           */
          for (i = 0; i < len; i++)
            if (!isascii (str[i]))
              ascii = 1;

          if (ascii == 0)
            non_printable = 0;
        }

      if (non_printable == 0)
        {
          str[len] = 0;

          /* Refuse to deal with strings containing NULs. */
          if (strlen (str) != len)
            return GNUTLS_E_ASN1_DER_ERROR;

          if (res)
            _gnutls_str_cpy (res, *res_size, str);
          *res_size = len;
        }
      else
        {
          result = _gnutls_x509_data2hex (str, len, res, res_size);
          if (result < 0)
            {
              gnutls_assert ();
              return result;
            }
        }
    }

  return 0;
}
예제 #22
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;
}
예제 #23
0
/* Send the first key exchange message ( g, n, s) and append the verifier algorithm number 
 * Data is allocated by the caller, and should have data_size size.
 */
int
_gnutls_gen_srp_server_kx(gnutls_session_t session,
			  gnutls_buffer_st * data)
{
	int ret;
	char *username;
	SRP_PWD_ENTRY *pwd_entry;
	srp_server_auth_info_t info;
	size_t tmp_size;
	extension_priv_data_t epriv;
	srp_ext_st *priv;

	ret =
	    _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SRP,
					 &epriv);
	if (ret < 0) {		/* peer didn't send a username */
		gnutls_assert();
		return GNUTLS_E_UNKNOWN_SRP_USERNAME;
	}
	priv = epriv;

	if ((ret =
	     _gnutls_auth_info_set(session, GNUTLS_CRD_SRP,
				   sizeof(srp_server_auth_info_st),
				   1)) < 0) {
		gnutls_assert();
		return ret;
	}

	info = _gnutls_get_auth_info(session, GNUTLS_CRD_SRP);
	if (info == NULL)
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

	username = info->username;

	_gnutls_str_cpy(username, MAX_USERNAME_SIZE, priv->username);

	ret = _gnutls_srp_pwd_read_entry(session, username, &pwd_entry);

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

	/* copy from pwd_entry to local variables (actually in session) */
	tmp_size = pwd_entry->g.size;
	if (_gnutls_mpi_init_scan_nz(&G, pwd_entry->g.data, tmp_size) < 0) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}

	tmp_size = pwd_entry->n.size;
	if (_gnutls_mpi_init_scan_nz(&N, pwd_entry->n.data, tmp_size) < 0) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}

	tmp_size = pwd_entry->v.size;
	if (_gnutls_mpi_init_scan_nz(&V, pwd_entry->v.data, tmp_size) < 0) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}

	/* Calculate:  B = (k*v + g^b) % N 
	 */
	B = _gnutls_calc_srp_B(&_b, G, N, V);
	if (B == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_MEMORY_ERROR;
		goto cleanup;
	}

	/* copy N (mod n) 
	 */
	ret =
	    _gnutls_buffer_append_data_prefix(data, 16, pwd_entry->n.data,
					      pwd_entry->n.size);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	/* copy G (generator) to data 
	 */
	ret =
	    _gnutls_buffer_append_data_prefix(data, 16, pwd_entry->g.data,
					      pwd_entry->g.size);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	/* copy the salt 
	 */
	ret =
	    _gnutls_buffer_append_data_prefix(data, 8,
					      pwd_entry->salt.data,
					      pwd_entry->salt.size);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	/* Copy the B value
	 */

	ret = _gnutls_buffer_append_mpi(data, 16, B, 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	_gnutls_mpi_log("SRP B: ", B);

	ret = data->length;

      cleanup:
	_gnutls_srp_entry_free(pwd_entry);
	return ret;
}
예제 #24
0
파일: extensions.c 프로젝트: nobled/gnutls
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;
}
예제 #25
0
static int write_complex_string(ASN1_TYPE asn_struct, const char *where,
				const struct oid_to_string *oentry,
				const uint8_t * data, size_t data_size)
{
	char tmp[128];
	ASN1_TYPE c2;
	int result;
	const char *string_type;
	unsigned int i;

	result =
	    asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc, &c2);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	tmp[0] = 0;

	string_type = "printableString";

	/* Check if the data is ASN.1 printable, and use
	 * the UTF8 string type if not.
	 */
	for (i = 0; i < data_size; i++) {
		if (!is_printable(data[i])) {
			string_type = "utf8String";
			break;
		}
	}

	/* if the type is a CHOICE then write the
	 * type we'll use.
	 */
	result = asn1_write_value(c2, "", string_type, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	_gnutls_str_cpy(tmp, sizeof(tmp), string_type);

	result = asn1_write_value(c2, tmp, data, data_size);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    _gnutls_x509_der_encode_and_copy(c2, "", asn_struct, where, 0);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	result = 0;

      error:
	asn1_delete_structure(&c2);
	return result;
}
예제 #26
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;
}
예제 #27
0
파일: sign.c 프로젝트: Chronic-Dev/gnutls
/*-
 * _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;
}
예제 #28
0
static int
decode_complex_string(const struct oid_to_string *oentry, void *value,
		      int value_size, gnutls_datum_t * out)
{
	char str[MAX_STRING_LEN], tmpname[128];
	int len = -1, result;
	ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
	char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
	unsigned int etype;
	gnutls_datum_t td = {NULL, 0};

	if (oentry->asn_desc == NULL) {
		gnutls_assert();
		return GNUTLS_E_INTERNAL_ERROR;
	}

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc,
				 &tmpasn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	if ((result =
	     asn1_der_decoding(&tmpasn, value, value_size,
			       asn1_err)) != ASN1_SUCCESS) {
		gnutls_assert();
		_gnutls_debug_log("asn1_der_decoding: %s\n", asn1_err);
		asn1_delete_structure(&tmpasn);
		return _gnutls_asn2err(result);
	}

	/* Read the type of choice.
	 */
	len = sizeof(str) - 1;
	if ((result = asn1_read_value(tmpasn, "", str, &len)) != ASN1_SUCCESS) {	/* CHOICE */
		gnutls_assert();
		asn1_delete_structure(&tmpasn);
		return _gnutls_asn2err(result);
	}

	str[len] = 0;

	/* We set the etype on the strings that may need
	 * some conversion to UTF-8. The INVALID flag indicates
	 * no conversion needed */
	if (strcmp(str, "teletexString") == 0)
		etype = ASN1_ETYPE_TELETEX_STRING;
	else if (strcmp(str, "bmpString") == 0)
		etype = ASN1_ETYPE_BMP_STRING;
	else if (strcmp(str, "universalString") == 0)
		etype = ASN1_ETYPE_UNIVERSAL_STRING;
	else
		etype = ASN1_ETYPE_INVALID;

	_gnutls_str_cpy(tmpname, sizeof(tmpname), str);

	result = _gnutls_x509_read_value(tmpasn, tmpname, &td);
	asn1_delete_structure(&tmpasn);
	if (result < 0)
		return gnutls_assert_val(result);

	if (etype != ASN1_ETYPE_INVALID) {
		result = make_printable_string(etype, &td, out);

		_gnutls_free_datum(&td);

		if (result < 0)
			return gnutls_assert_val(result);
	} else {
		out->data = td.data;
		out->size = td.size;
		/* _gnutls_x509_read_value always null terminates */
	}

	/* Refuse to deal with strings containing NULs. */
	if (strlen((void *) out->data) != (size_t) out->size) {
		_gnutls_free_datum(out);
		return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
	}

	return 0;
}
예제 #29
0
파일: pkcs12.c 프로젝트: Chronic-Dev/gnutls
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;
}
예제 #30
0
파일: extensions.c 프로젝트: nobled/gnutls
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);
    }
}