示例#1
0
/* Decodes an RSA privateKey from a PKCS8 structure.
 */
static int
_decode_pkcs8_rsa_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
{
	int ret;
	gnutls_datum_t tmp = {NULL, 0};

	ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	pkey->key = _gnutls_privkey_decode_pkcs1_rsa_key(&tmp, pkey);
	_gnutls_free_key_datum(&tmp);

	if (pkey->key == NULL) {
		ret = GNUTLS_E_PK_INVALID_PRIVKEY;
		gnutls_assert();
		goto error;
	}

	ret = 0;

      error:
	return ret;
}
示例#2
0
/**
 * gnutls_x509_crl_get_signature_algorithm - returns the CRL's signature algorithm
 * @crl: should contain a #gnutls_x509_crl_t structure
 *
 * This function will return a value of the #gnutls_sign_algorithm_t
 * enumeration that is the signature algorithm.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_crl_get_signature_algorithm (gnutls_x509_crl_t crl)
{
  int result;
  gnutls_datum_t sa;

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

  /* Read the signature algorithm. Note that parameters are not
   * read. They will be read from the issuer's certificate if needed.
   */

  result =
    _gnutls_x509_read_value (crl->crl, "signatureAlgorithm.algorithm",
			     &sa, 0);

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

  result = _gnutls_x509_oid2sign_algorithm ((const char *) sa.data);

  _gnutls_free_datum (&sa);

  return result;
}
示例#3
0
static int
_parse_safe_contents (ASN1_TYPE sc, const char *sc_name,
		      gnutls_pkcs12_bag_t bag)
{
  gnutls_datum_t content = { NULL, 0 };
  int result;

  /* Step 1. Extract the content.
   */

  result = _gnutls_x509_read_value (sc, sc_name, &content, 1);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _pkcs12_decode_safe_contents (&content, bag);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  _gnutls_free_datum (&content);

  return 0;

cleanup:
  _gnutls_free_datum (&content);
  return result;
}
示例#4
0
int
_gnutls_decode_ber_rs_raw(const gnutls_datum_t * sig_value, gnutls_datum_t *r,
			  gnutls_datum_t *s)
{
	ASN1_TYPE sig;
	int result;

	if ((result =
	     asn1_create_element(_gnutls_get_gnutls_asn(),
				 "GNUTLS.DSASignatureValue",
				 &sig)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	result =
	    asn1_der_decoding(&sig, sig_value->data, sig_value->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&sig);
		return _gnutls_asn2err(result);
	}

	result = _gnutls_x509_read_value(sig, "r", r);
	if (result < 0) {
		gnutls_assert();
		asn1_delete_structure(&sig);
		return result;
	}

	result = _gnutls_x509_read_value(sig, "s", s);
	if (result < 0) {
		gnutls_assert();
		gnutls_free(r->data);
		asn1_delete_structure(&sig);
		return result;
	}

	asn1_delete_structure(&sig);

	return 0;
}
示例#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;

}
示例#6
0
static int
get_indx_extension(ASN1_TYPE asn, const char *root,
	      int indx, gnutls_datum_t * out)
{
	char name[ASN1_MAX_NAME_SIZE];
	int ret;

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

	snprintf(name, sizeof(name), "%s.?%u.extnValue", root, indx+1);

	ret = _gnutls_x509_read_value(asn, name, out);
	if (ret < 0)
		return gnutls_assert_val(ret);

	return 0;
}
示例#7
0
/* Decodes an ECC privateKey from a PKCS8 structure.
 */
static int
_decode_pkcs8_ecc_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
{
	int ret;
	gnutls_datum_t tmp = {NULL, 0};
	unsigned char oid[MAX_OID_SIZE];
	unsigned curve = GNUTLS_ECC_CURVE_INVALID;
	int len, result;

	/* openssl PKCS #8 files with ECC keys place the curve in
	 * privateKeyAlgorithm.parameters instead of the ECPrivateKey.parameters.
	 */
	len = sizeof(oid);
	result =
	    asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters",
			    oid, &len);
	if (result == ASN1_SUCCESS) {
		ret = _gnutls_x509_read_ecc_params(oid, len, &curve);
		if (ret < 0) {
			_gnutls_debug_log("PKCS#8: unknown curve OID %s\n", oid);
			curve = GNUTLS_ECC_CURVE_INVALID;
		}
	}

	ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _gnutls_privkey_decode_ecc_key(&pkey->key, &tmp, pkey, curve);
	_gnutls_free_key_datum(&tmp);

	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = 0;

      error:
	return ret;
}
示例#8
0
/* Decodes an RSA-PSS privateKey from a PKCS8 structure.
 */
static int
_decode_pkcs8_rsa_pss_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
{
	int ret;
	gnutls_datum_t tmp = {NULL, 0};
	gnutls_x509_spki_st params;

	memset(&params, 0, sizeof(params));

	ret = _gnutls_x509_read_value(pkcs8_asn,
				      "privateKeyAlgorithm.parameters", &tmp);
	if (ret < 0) {
		if (ret == GNUTLS_E_ASN1_VALUE_NOT_FOUND || ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
			goto skip_params;

		gnutls_assert();
		goto error;
	}

	ret = _gnutls_x509_read_rsa_pss_params(tmp.data, tmp.size, &params);
	_gnutls_free_key_datum(&tmp);

	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

 skip_params:
	ret = _decode_pkcs8_rsa_key(pkcs8_asn, pkey);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	pkey->params.algo = GNUTLS_PK_RSA_PSS;
	memcpy(&pkey->params.spki, &params, sizeof(gnutls_x509_spki_st));

	ret = 0;

      error:
	return ret;
}
示例#9
0
/*-
 * gnutls_x509_get_signature_algorithm:
 * @src: should contain an ASN1_TYPE structure
 * @src_name: the description of the signature field
 *
 * This function will return a value of the #gnutls_sign_algorithm_t
 * enumeration that is the signature algorithm that has been used to
 * sign this certificate.
 *
 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
 *   error.
 -*/
int
_gnutls_x509_get_signature_algorithm(ASN1_TYPE src, const char *src_name)
{
	int result;
	gnutls_datum_t sa;

	/* Read the signature algorithm. Note that parameters are not
	 * read. They will be read from the issuer's certificate if needed.
	 */
	result = _gnutls_x509_read_value(src, src_name, &sa);

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

	result = _gnutls_x509_oid2sign_algorithm((char *) sa.data);

	_gnutls_free_datum(&sa);

	return result;
}
示例#10
0
/* Decodes the SafeContents, and puts the output in
 * the given bag. 
 */
int
_pkcs12_decode_safe_contents (const gnutls_datum_t * content,
			      gnutls_pkcs12_bag_t bag)
{
  char oid[MAX_OID_SIZE], root[ASN1_MAX_NAME_SIZE];
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  int len, result;
  int bag_type;
  gnutls_datum_t attr_val;
  int count = 0, i, attributes, j;
  size_t size;

  /* Step 1. Extract the SEQUENCE.
   */

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
	&c2)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  result = asn1_der_decoding (&c2, content->data, content->size, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Count the number of bags
   */
  result = asn1_number_of_elements (c2, "", &count);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  bag->bag_elements = MIN (MAX_BAG_ELEMENTS, count);

  for (i = 0; i < bag->bag_elements; i++)
    {

      snprintf (root, sizeof (root), "?%u.bagId", i + 1);

      len = sizeof (oid);
      result = asn1_read_value (c2, root, oid, &len);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      /* Read the Bag type
       */
      bag_type = oid2bag (oid);

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

      /* Read the Bag Value
       */

      snprintf (root, sizeof (root), "?%u.bagValue", i + 1);

      result = _gnutls_x509_read_value (c2, root, &bag->element[i].data, 0);
      if (result < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}

      if (bag_type == GNUTLS_BAG_CERTIFICATE || bag_type == GNUTLS_BAG_CRL
	  || bag_type == GNUTLS_BAG_SECRET)
	{
	  gnutls_datum_t tmp = bag->element[i].data;

	  result =
	    _pkcs12_decode_crt_bag (bag_type, &tmp, &bag->element[i].data);
	  if (result < 0)
	    {
	      gnutls_assert ();
	      goto cleanup;
	    }

	  _gnutls_free_datum (&tmp);
	}

      /* read the bag attributes
       */
      snprintf (root, sizeof (root), "?%u.bagAttributes", i + 1);

      result = asn1_number_of_elements (c2, root, &attributes);
      if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      if (attributes < 0)
	attributes = 1;

      if (result != ASN1_ELEMENT_NOT_FOUND)
	for (j = 0; j < attributes; j++)
	  {

	    snprintf (root, sizeof (root), "?%u.bagAttributes.?%u", i + 1,
		      j + 1);

	    result =
	      _gnutls_x509_decode_and_read_attribute (c2, root, oid,
						      sizeof (oid), &attr_val,
						      1, 0);

	    if (result < 0)
	      {
		gnutls_assert ();
		continue;	/* continue in case we find some known attributes */
	      }

	    if (strcmp (oid, KEY_ID_OID) == 0)
	      {
		size = attr_val.size;

		result =
		  _gnutls_x509_decode_octet_string (NULL, attr_val.data, size,
						    attr_val.data, &size);
		attr_val.size = size;
		if (result < 0)
		  {
		    _gnutls_free_datum (&attr_val);
		    gnutls_assert ();
		    _gnutls_x509_log
		      ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
		    continue;
		  }
		bag->element[i].local_key_id = attr_val;
	      }
	    else if (strcmp (oid, FRIENDLY_NAME_OID) == 0)
	      {
		size = attr_val.size;
		result =
		  _gnutls_x509_decode_octet_string ("BMPString",
						    attr_val.data, size,
						    attr_val.data, &size);
		attr_val.size = size;
		if (result < 0)
		  {
		    _gnutls_free_datum (&attr_val);
		    gnutls_assert ();
		    _gnutls_x509_log
		      ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
		    continue;
		  }
		bag->element[i].friendly_name =
		  ucs2_to_ascii (attr_val.data, attr_val.size);
	      }
	    else
	      {
		_gnutls_free_datum (&attr_val);
		_gnutls_x509_log
		  ("Unknown PKCS12 Bag Attribute OID '%s'\n", oid);
	      }
	  }


      bag->element[i].type = bag_type;

    }

  asn1_delete_structure (&c2);


  return 0;

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

}
示例#11
0
/* Converts an ECC key to
 * an internal structure (gnutls_private_key)
 */
ASN1_TYPE
_gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key,
                                      gnutls_x509_privkey_t pkey)
{
  int ret;
  ASN1_TYPE pkey_asn;
  unsigned int version;
  char oid[MAX_OID_SIZE];
  int oid_size;
  gnutls_datum out;

  gnutls_pk_params_init(&pkey->params);

  if ((ret =
       asn1_create_element (_gnutls_get_gnutls_asn (),
                            "GNUTLS.ECPrivateKey",
                            &pkey_asn)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return NULL;
    }

  ret = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
  if (ret != ASN1_SUCCESS)
    {
      gnutls_assert ();
      goto error;
    }

  ret = _gnutls_x509_read_uint (pkey_asn, "Version", &version);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }

  if (version != 1)
    {
      _gnutls_debug_log("ECC private key version %u is not supported\n", version);
      gnutls_assert();
      goto error;
    }

  /* read the curve */
  oid_size = sizeof(oid);
  ret = asn1_read_value(pkey_asn, "parameters.namedCurve", oid, &oid_size);
  if (ret != ASN1_SUCCESS)
    {
      gnutls_assert ();
      goto error;
    }
    
  pkey->params.flags = _gnutls_oid_to_ecc_curve(oid);
  if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID)
    {
      _gnutls_debug_log("Curve %s is not supported\n", oid);
      gnutls_assert();
      goto error;
    }
    
  ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }

  /* read the public key */
  ret = _gnutls_x509_read_value(pkey_asn, "publicKey", &out, 2);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }

  ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[ECC_X],
                                         &pkey->params.params[ECC_Y]);
  
  _gnutls_free_datum(&out);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }
  pkey->params.params_nr += 2;

  /* read the private key */
  ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[ECC_K]);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }
  pkey->params.params_nr ++;

  return pkey_asn;

error:
  asn1_delete_structure (&pkey_asn);
  gnutls_pk_params_release (&pkey->params);
  return NULL;

}
示例#12
0
文件: pkcs12.c 项目: gnutls/gnutls
/**
 * gnutls_pkcs12_mac_info:
 * @pkcs12: A pkcs12 type
 * @mac: the MAC algorithm used as %gnutls_mac_algorithm_t
 * @salt: the salt used for string to key (if non-NULL then @salt_size initially holds its size)
 * @salt_size: string to key salt size
 * @iter_count: string to key iteration count
 * @oid: if non-NULL it will contain an allocated null-terminated variable with the OID
 *
 * This function will provide information on the MAC algorithm used
 * in a PKCS #12 structure. If the structure algorithms
 * are unknown the code %GNUTLS_E_UNKNOWN_HASH_ALGORITHM will be returned,
 * and only @oid, will be set. That is, @oid will be set on structures
 * with a MAC whether supported or not. It must be deinitialized using gnutls_free().
 * The other variables are only set on supported structures.
 *
 * Returns: %GNUTLS_E_INVALID_REQUEST if the provided structure doesn't contain a MAC,
 *  %GNUTLS_E_UNKNOWN_HASH_ALGORITHM if the structure's MAC isn't supported, or
 *  another negative error code in case of a failure. Zero on success.
 **/
int
gnutls_pkcs12_mac_info(gnutls_pkcs12_t pkcs12, unsigned int *mac,
	void *salt, unsigned int *salt_size, unsigned int *iter_count, char **oid)
{
	int ret;
	gnutls_datum_t tmp = { NULL, 0 }, dsalt = {
	NULL, 0};
	gnutls_mac_algorithm_t algo;

	if (oid)
		*oid = NULL;

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

	ret =
	    _gnutls_x509_read_value(pkcs12->pkcs12, "macData.mac.digestAlgorithm.algorithm",
				    &tmp);
	if (ret < 0) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if (oid) {
		*oid = (char*)tmp.data;
	}

	algo = gnutls_oid_to_digest((char*)tmp.data);
	if (algo == GNUTLS_MAC_UNKNOWN || mac_to_entry(algo) == NULL) {
		gnutls_assert();
		return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
	}

	if (oid) {
		tmp.data = NULL;
	}

	if (mac) {
		*mac = algo;
	}

	if (iter_count) {
		ret =
		    _gnutls_x509_read_uint(pkcs12->pkcs12, "macData.iterations",
				   iter_count);
		if (ret < 0) {
			*iter_count = 1;	/* the default */
		}
	}

	if (salt) {
		/* Read the salt from the structure.
		 */
		ret =
		    _gnutls_x509_read_null_value(pkcs12->pkcs12, "macData.macSalt",
					    &dsalt);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		if (*salt_size >= (unsigned)dsalt.size) {
			*salt_size = dsalt.size;
			if (dsalt.size > 0)
				memcpy(salt, dsalt.data, dsalt.size);
		} else {
			*salt_size = dsalt.size;
			ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
			goto cleanup;
		}
	}

	ret = 0;
 cleanup:
	_gnutls_free_datum(&tmp);
	_gnutls_free_datum(&dsalt);
	return ret;

}
示例#13
0
/* Extracts DSA and RSA parameters from a certificate.
 */
static int
get_mpis (int pk_algorithm, ASN1_TYPE asn, const char *root,
	  bigint_t * params, int *params_size)
{
  int result;
  char name[256];
  gnutls_datum tmp = { NULL, 0 };

  /* Read the algorithm's parameters
   */
  snprintf (name, sizeof (name), "%s.subjectPublicKey", root);
  result = _gnutls_x509_read_value (asn, name, &tmp, 2);

  if (result < 0)
    {
      gnutls_assert ();
      fprintf (stderr, "name: %s\n", name);
      return result;
    }

  switch (pk_algorithm)
    {
    case GNUTLS_PK_RSA:
      /* params[0] is the modulus,
       * params[1] is the exponent
       */
      if (*params_size < RSA_PUBLIC_PARAMS)
	{
	  gnutls_assert ();
	  /* internal error. Increase the bigint_ts in params */
	  result = GNUTLS_E_INTERNAL_ERROR;
	  goto error;
	}

      if ((result =
	   _gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0)
	{
	  gnutls_assert ();
	  goto error;
	}
      *params_size = RSA_PUBLIC_PARAMS;

      break;
    case GNUTLS_PK_DSA:
      /* params[0] is p,
       * params[1] is q,
       * params[2] is q,
       * params[3] is pub.
       */

      if (*params_size < DSA_PUBLIC_PARAMS)
	{
	  gnutls_assert ();
	  /* internal error. Increase the bigint_ts in params */
	  result = GNUTLS_E_INTERNAL_ERROR;
	  goto error;
	}

      if ((result =
	   _gnutls_x509_read_dsa_pubkey (tmp.data, tmp.size, params)) < 0)
	{
	  gnutls_assert ();
	  goto error;
	}

      /* Now read the parameters
       */
      _gnutls_free_datum (&tmp);

      snprintf (name, sizeof (name), "%s.algorithm.parameters", root);
      result = _gnutls_x509_read_value (asn, name, &tmp, 0);

      /* FIXME: If the parameters are not included in the certificate
       * then the issuer's parameters should be used. This is not
       * done yet.
       */

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

      if ((result =
	   _gnutls_x509_read_dsa_params (tmp.data, tmp.size, params)) < 0)
	{
	  gnutls_assert ();
	  goto error;
	}
      *params_size = DSA_PUBLIC_PARAMS;

      break;

    default:
      /* other types like DH
       * currently not supported
       */
      gnutls_assert ();
      result = GNUTLS_E_X509_CERTIFICATE_ERROR;
      goto error;
    }

  result = 0;

error:
  _gnutls_free_datum (&tmp);
  return result;
}
示例#14
0
文件: mpi.c 项目: bf4/pidgin-mac
/* Extracts DSA and RSA parameters from a certificate.
 */
int
_gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
			   bigint_t * params, int *params_size)
{
  int result;
  int pk_algorithm;
  gnutls_datum tmp = { NULL, 0 };

  /* Read the algorithm's OID
   */
  pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL);

  /* Read the algorithm's parameters
   */
  result = _gnutls_x509_read_value (cert->cert,
				    "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
				    &tmp, 2);

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

  switch (pk_algorithm)
    {
    case GNUTLS_PK_RSA:
      /* params[0] is the modulus,
       * params[1] is the exponent
       */
      if (*params_size < RSA_PUBLIC_PARAMS)
	{
	  gnutls_assert ();
	  /* internal error. Increase the bigint_ts in params */
	  result = GNUTLS_E_INTERNAL_ERROR;
	  goto error;
	}

      if ((result =
	   _gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0)
	{
	  gnutls_assert ();
	  goto error;
	}
      *params_size = RSA_PUBLIC_PARAMS;

      break;
    case GNUTLS_PK_DSA:
      /* params[0] is p,
       * params[1] is q,
       * params[2] is q,
       * params[3] is pub.
       */

      if (*params_size < DSA_PUBLIC_PARAMS)
	{
	  gnutls_assert ();
	  /* internal error. Increase the bigint_ts in params */
	  result = GNUTLS_E_INTERNAL_ERROR;
	  goto error;
	}

      if ((result =
	   _gnutls_x509_read_dsa_pubkey (tmp.data, tmp.size, params)) < 0)
	{
	  gnutls_assert ();
	  goto error;
	}

      /* Now read the parameters
       */
      _gnutls_free_datum (&tmp);

      result = _gnutls_x509_read_value (cert->cert,
					"tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",
					&tmp, 0);

      /* FIXME: If the parameters are not included in the certificate
       * then the issuer's parameters should be used. This is not
       * done yet.
       */

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

      if ((result =
	   _gnutls_x509_read_dsa_params (tmp.data, tmp.size, params)) < 0)
	{
	  gnutls_assert ();
	  goto error;
	}
      *params_size = DSA_PUBLIC_PARAMS;

      break;

    default:
      /* other types like DH
       * currently not supported
       */
      gnutls_assert ();
      result = GNUTLS_E_X509_CERTIFICATE_ERROR;
      goto error;
    }

  result = 0;

error:
  _gnutls_free_datum (&tmp);
  return result;
}
示例#15
0
static int append_elements(ASN1_TYPE asn1_struct, const char *asn1_rdn_name, gnutls_buffer_st *str, int k1, unsigned last)
{
	int k2, result, max_k2;
	int len;
	uint8_t value[MAX_STRING_LEN];
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	const char *ldap_desc;
	char oid[MAX_OID_SIZE];
	gnutls_datum_t td = { NULL, 0 };
	gnutls_datum_t tvd = { NULL, 0 };

	/* 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_VALUE_NOT_FOUND && result != ASN1_SUCCESS) { /* expected */
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	k2 = 0;

	result = asn1_number_of_elements(asn1_struct, tmpbuffer1, &max_k2);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	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 && result != ASN1_SUCCESS) { /* expected */
			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( str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
#define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( str, x,y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
		/*   The encodings of adjoining RelativeDistinguishedNames are separated
		 *   by a comma character (',' ASCII 44).
		 */

		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);

		/*   Where there is a multi-valued RDN, the outputs from adjoining
		 *   AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
		 *   character.
		 */
		if (k2 < max_k2) {
			STR_APPEND("+");
		} else if (!last) {
			STR_APPEND(",");
		}
	}
	while (1);

	result = 0;

 cleanup:
	_gnutls_free_datum(&td);
	_gnutls_free_datum(&tvd);
	return result;
}
示例#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
/* extract the proxyCertInfo from the DER encoded extension
 */
int
_gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint,
                                        char **policyLanguage,
                                        char **policy,
                                        size_t * sizeof_policy,
                                        uint8_t * extnValue, int extnValueLen)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  int result;
  gnutls_datum_t value;

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.ProxyCertInfo", &ext)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return _gnutls_asn2err (result);
    }

  if (pathLenConstraint)
    {
      result = _gnutls_x509_read_uint (ext, "pCPathLenConstraint",
                                       (unsigned int*)pathLenConstraint);
      if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
        *pathLenConstraint = -1;
      else if (result != GNUTLS_E_SUCCESS)
        {
          asn1_delete_structure (&ext);
          return _gnutls_asn2err (result);
        }
    }

  result = _gnutls_x509_read_value (ext, "proxyPolicy.policyLanguage",
                                    &value);
  if (result < 0)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return result;
    }

  if (policyLanguage)
    *policyLanguage = gnutls_strdup ((char*)value.data);

  result = _gnutls_x509_read_value (ext, "proxyPolicy.policy", &value);
  if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
    {
      if (policy)
        *policy = NULL;
      if (sizeof_policy)
        *sizeof_policy = 0;
    }
  else if (result < 0)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return result;
    }
  else
    {
      if (policy)
        *policy = (char*)value.data;
      if (sizeof_policy)
        *sizeof_policy = value.size;
    }

  asn1_delete_structure (&ext);

  return 0;
}
示例#18
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;
}
示例#19
0
int
_pkcs12_decode_crt_bag (gnutls_pkcs12_bag_type_t type,
			const gnutls_datum_t * in, gnutls_datum_t * out)
{
  int ret;
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;

  if (type == GNUTLS_BAG_CERTIFICATE)
    {
      if ((ret = asn1_create_element (_gnutls_get_pkix (),
				      "PKIX1.pkcs-12-CertBag",
				      &c2)) != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  ret = _gnutls_asn2err (ret);
	  goto cleanup;
	}

      ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
      if (ret != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  ret = _gnutls_asn2err (ret);
	  goto cleanup;
	}

      ret = _gnutls_x509_read_value (c2, "certValue", out, 1);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}

    }
  else
    {				/* CRL */
      if ((ret = asn1_create_element (_gnutls_get_pkix (),
				      "PKIX1.pkcs-12-CRLBag",
				      &c2)) != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  ret = _gnutls_asn2err (ret);
	  goto cleanup;
	}

      ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
      if (ret != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  ret = _gnutls_asn2err (ret);
	  goto cleanup;
	}

      ret = _gnutls_x509_read_value (c2, "crlValue", out, 1);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}
    }

  asn1_delete_structure (&c2);

  return 0;


cleanup:

  asn1_delete_structure (&c2);
  return ret;
}
示例#20
0
/**
 * gnutls_pkcs12_get_bag:
 * @pkcs12: should contain a gnutls_pkcs12_t structure
 * @indx: contains the index of the bag to extract
 * @bag: An initialized bag, where the contents of the bag will be copied
 *
 * This function will return a Bag from the PKCS12 structure.
 *
 * After the last Bag has been read
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs12_get_bag (gnutls_pkcs12_t pkcs12,
		       int indx, gnutls_pkcs12_bag_t bag)
{
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  int result, len;
  char root2[ASN1_MAX_NAME_SIZE];
  char oid[MAX_OID_SIZE];

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

  /* Step 1. decode the data.
   */
  result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  /* Step 2. Parse the AuthenticatedSafe
   */

  snprintf (root2, sizeof (root2), "?%u.contentType", indx + 1);

  len = sizeof (oid) - 1;
  result = asn1_read_value (c2, root2, oid, &len);

  if (result == ASN1_ELEMENT_NOT_FOUND)
    {
      result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
      goto cleanup;
    }

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

  /* Not encrypted Bag
   */

  snprintf (root2, sizeof (root2), "?%u.content", indx + 1);

  if (strcmp (oid, DATA_OID) == 0)
    {
      result = _parse_safe_contents (c2, root2, bag);
      goto cleanup;
    }

  /* ENC_DATA_OID needs decryption */

  bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
  bag->bag_elements = 1;

  result = _gnutls_x509_read_value (c2, root2, &bag->element[0].data, 0);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = 0;

cleanup:
  if (c2)
    asn1_delete_structure (&c2);
  return result;
}
示例#21
0
文件: krb5.c 项目: GostCrypt/GnuTLS
static int principal_to_str(ASN1_TYPE c2, gnutls_buffer_st * str)
{
	gnutls_datum_t realm = { NULL, 0 };
	gnutls_datum_t component = { NULL, 0 };
	unsigned char name_type[2];
	int ret, result, len;
	unsigned i;
	char val[128];

	ret = _gnutls_x509_read_value(c2, "realm", &realm);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	len = sizeof(name_type);
	result =
	    asn1_read_value(c2, "principalName.name-type", name_type, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

	if (len != 1
	    || (name_type[0] != 1 && name_type[0] != 2 && name_type[0] != 10)) {
		ret = GNUTLS_E_INVALID_REQUEST;
		goto cleanup;
	}

	for (i = 0;; i++) {
		snprintf(val, sizeof(val), "principalName.name-string.?%u",
			 i + 1);
		ret = _gnutls_x509_read_value(c2, val, &component);
		if (ret == GNUTLS_E_ASN1_VALUE_NOT_FOUND
		    || ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
			break;
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		if (i > 0) {
			ret = _gnutls_buffer_append_data(str, "/", 1);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}
		}

		ret =
		    _gnutls_buffer_append_data(str, component.data,
					       component.size);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		_gnutls_free_datum(&component);
	}

	ret = _gnutls_buffer_append_data(str, "@", 1);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_buffer_append_data(str, realm.data, realm.size);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = 0;
 cleanup:
	_gnutls_free_datum(&component);
	gnutls_free(realm.data);
	return ret;
}
示例#22
0
/* Decodes an DSA privateKey and params from a PKCS8 structure.
 */
static int
_decode_pkcs8_dsa_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
{
	int ret;
	gnutls_datum_t tmp = {NULL, 0};

	gnutls_pk_params_init(&pkey->params);

	ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret =
	    _gnutls_x509_read_der_int(tmp.data, tmp.size,
				      &pkey->params.params[4]);
	_gnutls_free_key_datum(&tmp);

	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret =
	    _gnutls_x509_read_value(pkcs8_asn,
				    "privateKeyAlgorithm.parameters",
				    &tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret =
	    _gnutls_x509_read_pubkey_params(GNUTLS_PK_DSA, tmp.data,
					    tmp.size, &pkey->params);
	_gnutls_free_datum(&tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (_gnutls_mpi_cmp_ui(pkey->params.params[0], 0) == 0) {
		gnutls_assert();
		ret = GNUTLS_E_ILLEGAL_PARAMETER;
		goto error;
	}

	/* the public key can be generated as g^x mod p */
	ret = _gnutls_mpi_init(&pkey->params.params[3]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _gnutls_mpi_powm(pkey->params.params[3], pkey->params.params[2],
			 pkey->params.params[4], pkey->params.params[0]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	pkey->params.algo = GNUTLS_PK_DSA;
	pkey->params.params_nr = DSA_PRIVATE_PARAMS;

	ret =
	    _gnutls_asn1_encode_privkey(&pkey->key,
					&pkey->params);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	return 0;

 error:
	if (pkey->params.params_nr != DSA_PRIVATE_PARAMS)
		_gnutls_mpi_release(&pkey->params.params[4]);
	return ret;
}
示例#23
0
/* Decodes a GOST privateKey from a PKCS8 structure.
 */
static int
_decode_pkcs8_gost_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey,
		       gnutls_pk_algorithm_t algo)
{
	int ret;
	gnutls_datum_t tmp;
	unsigned char oid[3 * MAX_OID_SIZE]; /* GOST parameters can have 3 OIDs at most */
	int len, result;

	gnutls_pk_params_init(&pkey->params);

	len = sizeof(oid);
	result = asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters",
				 oid, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = GNUTLS_E_PARSING_ERROR;
		goto error;
	} else {
		ret = _gnutls_x509_read_gost_params(oid, len, &pkey->params, algo);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	}

	/* Will be fixed later by pk_fixup */
	ret = _gnutls_mpi_init(&pkey->params.params[GOST_X]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	ret = _gnutls_mpi_init(&pkey->params.params[GOST_Y]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	_gnutls_mpi_set_ui(pkey->params.params[GOST_X], 0);
	_gnutls_mpi_set_ui(pkey->params.params[GOST_Y], 0);

	ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _privkey_decode_gost_key(&tmp, pkey);
	_gnutls_free_key_datum(&tmp);

	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	pkey->params.algo = algo;

	return 0;

error:
	gnutls_pk_params_clear(&pkey->params);
	gnutls_pk_params_release(&pkey->params);

	return ret;
}
示例#24
0
/* Decodes the PKCS #12 auth_safe, and returns the allocated raw data,
 * which holds them. Returns an ASN1_TYPE of authenticatedSafe.
 */
static int
_decode_pkcs12_auth_safe (ASN1_TYPE pkcs12, ASN1_TYPE * authen_safe,
			  gnutls_datum_t * raw)
{
  char oid[MAX_OID_SIZE];
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  gnutls_datum_t auth_safe = { NULL, 0 };
  int len, result;
  char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE];

  len = sizeof (oid) - 1;
  result = asn1_read_value (pkcs12, "authSafe.contentType", oid, &len);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  if (strcmp (oid, DATA_OID) != 0)
    {
      gnutls_assert ();
      _gnutls_x509_log ("Unknown PKCS12 Content OID '%s'\n", oid);
      return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
    }

  /* Step 1. Read the content data
   */

  result =
    _gnutls_x509_read_value (pkcs12, "authSafe.content", &auth_safe, 1);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  /* Step 2. Extract the authenticatedSafe.
   */

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
	&c2)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  result = asn1_der_decoding (&c2, auth_safe.data, auth_safe.size, error_str);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      _gnutls_x509_log ("DER error: %s\n", error_str);
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if (raw == NULL)
    {
      _gnutls_free_datum (&auth_safe);
    }
  else
    {
      raw->data = auth_safe.data;
      raw->size = auth_safe.size;
    }

  if (authen_safe)
    *authen_safe = c2;
  else
    asn1_delete_structure (&c2);

  return 0;

cleanup:
  if (c2)
    asn1_delete_structure (&c2);
  _gnutls_free_datum (&auth_safe);
  return result;
}
示例#25
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);
    }
}
示例#26
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;

}
示例#27
0
/**
 * gnutls_pkcs12_verify_mac:
 * @pkcs12: should contain a gnutls_pkcs12_t structure
 * @pass: The password for the MAC
 *
 * This function will verify the MAC for the PKCS12 structure.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12, const char *pass)
{
  opaque key[20];
  int result;
  unsigned int iter;
  int len;
  digest_hd_st td1;
  gnutls_datum_t tmp = { NULL, 0 }, salt =
  {
  NULL, 0};
  opaque sha_mac[20];
  opaque sha_mac_orig[20];

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

  /* read the iterations
   */

  result =
    _gnutls_x509_read_uint (pkcs12->pkcs12, "macData.iterations", &iter);
  if (result < 0)
    {
      iter = 1;			/* the default */
    }


  /* Read the salt from the structure.
   */
  result =
    _gnutls_x509_read_value (pkcs12->pkcs12, "macData.macSalt", &salt, 0);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Generate the key.
   */
  result = _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt.data, salt.size,
					 iter, pass, sizeof (key), key);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  _gnutls_free_datum (&salt);

  /* Get the data to be MACed
   */
  result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  /* MAC the data
   */
  result = _gnutls_hmac_init (&td1, GNUTLS_MAC_SHA1, key, sizeof (key));
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  _gnutls_hmac (&td1, tmp.data, tmp.size);
  _gnutls_free_datum (&tmp);

  _gnutls_hmac_deinit (&td1, sha_mac);

  len = sizeof (sha_mac_orig);
  result =
    asn1_read_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac_orig,
		     &len);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if (memcmp (sha_mac_orig, sha_mac, sizeof (sha_mac)) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MAC_VERIFY_FAILED;
    }

  return 0;

cleanup:
  _gnutls_free_datum (&tmp);
  _gnutls_free_datum (&salt);
  return result;
}
示例#28
0
/* Converts an ECC key to
 * an internal structure (gnutls_private_key)
 */
int
_gnutls_privkey_decode_ecc_key(ASN1_TYPE* pkey_asn, const gnutls_datum_t * raw_key,
			       gnutls_x509_privkey_t pkey, gnutls_ecc_curve_t curve)
{
	int ret;
	unsigned int version;
	char oid[MAX_OID_SIZE];
	int oid_size;
	gnutls_datum out;

	gnutls_pk_params_init(&pkey->params);

	pkey->params.algo = GNUTLS_PK_EC;
	if ((ret =
	     asn1_create_element(_gnutls_get_gnutls_asn(),
				 "GNUTLS.ECPrivateKey",
				 pkey_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(ret);
	}

	ret =
	    asn1_der_decoding(pkey_asn, raw_key->data, raw_key->size,
			      NULL);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(ret);
		goto error;
	}

	ret = _gnutls_x509_read_uint(*pkey_asn, "Version", &version);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (version != 1) {
		_gnutls_debug_log
		    ("ECC private key version %u is not supported\n",
		     version);
		gnutls_assert();
		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
		goto error;
	}

	/* read the curve */
	if (curve == GNUTLS_ECC_CURVE_INVALID) {
		oid_size = sizeof(oid);
		ret =
		    asn1_read_value(*pkey_asn, "parameters.namedCurve", oid,
			    &oid_size);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		pkey->params.flags = _gnutls_oid_to_ecc_curve(oid);

		if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID) {
			_gnutls_debug_log("Curve %s is not supported\n", oid);
			gnutls_assert();
			ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
			goto error;
		}
	} else {
		pkey->params.flags = curve;
	}


	/* read the public key */
	ret = _gnutls_x509_read_value(*pkey_asn, "publicKey", &out);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret =
	    _gnutls_ecc_ansi_x963_import(out.data, out.size,
					 &pkey->params.params[ECC_X],
					 &pkey->params.params[ECC_Y]);

	_gnutls_free_datum(&out);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr += 2;

	/* read the private key */
	ret =
	    _gnutls_x509_read_key_int(*pkey_asn, "privateKey",
				  &pkey->params.params[ECC_K]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	return 0;

      error:
	asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	gnutls_pk_params_clear(&pkey->params);
	gnutls_pk_params_release(&pkey->params);
	return ret;

}