Пример #1
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,
			       bigint_t * params, int params_size)
{
  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");

  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;
}
Пример #2
0
/**
 * gnutls_x509_crl_import - import a DER or PEM encoded CRL
 * @crl: The structure to store the parsed CRL.
 * @data: The DER or PEM encoded CRL.
 * @format: One of DER or PEM
 *
 * This function will convert the given DER or PEM encoded CRL
 * to the native #gnutls_x509_crl_t format. The output will be stored in 'crl'.
 *
 * If the CRL is PEM encoded it should have a header of "X509 CRL".
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_crl_import (gnutls_x509_crl_t crl,
			const gnutls_datum_t * data,
			gnutls_x509_crt_fmt_t format)
{
  int result = 0, need_free = 0;
  gnutls_datum_t _data;

  _data.data = data->data;
  _data.size = data->size;

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

  /* If the CRL is in PEM format then decode it
   */
  if (format == GNUTLS_X509_FMT_PEM)
    {
      opaque *out;

      result = _gnutls_fbase64_decode (PEM_CRL, data->data, data->size, &out);

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

      _data.data = out;
      _data.size = result;

      need_free = 1;
    }


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

  if (need_free)
    _gnutls_free_datum (&_data);

  return 0;

cleanup:
  if (need_free)
    _gnutls_free_datum (&_data);
  return result;
}
Пример #3
0
/**
 * gnutls_x509_crl_import:
 * @crl: The structure to store the parsed CRL.
 * @data: The DER or PEM encoded CRL.
 * @format: One of DER or PEM
 *
 * This function will convert the given DER or PEM encoded CRL
 * to the native #gnutls_x509_crl_t format. The output will be stored in 'crl'.
 *
 * If the CRL is PEM encoded it should have a header of "X509 CRL".
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_crl_import(gnutls_x509_crl_t crl,
		       const gnutls_datum_t * data,
		       gnutls_x509_crt_fmt_t format)
{
	int result = 0, need_free = 0;
	gnutls_datum_t _data;

	_data.data = data->data;
	_data.size = data->size;

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

	/* If the CRL is in PEM format then decode it
	 */
	if (format == GNUTLS_X509_FMT_PEM) {
		result =
		    _gnutls_fbase64_decode(PEM_CRL, data->data, data->size,
					   &_data);

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

		need_free = 1;
	}

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

	result = _gnutls_x509_get_raw_dn2(crl->crl, &_data,
					  "tbsCertList.issuer.rdnSequence",
					  &crl->raw_issuer_dn);
	if (result < 0) {
		gnutls_assert();
		goto cleanup;
	}

	if (need_free)
		_gnutls_free_datum(&_data);

	return 0;

      cleanup:
	if (need_free)
		_gnutls_free_datum(&_data);
	_gnutls_free_datum(&crl->raw_issuer_dn);
	return result;
}
Пример #4
0
/**
 * gnutls_pkcs7_get_crl_raw:
 * @pkcs7: should contain a #gnutls_pkcs7_t structure
 * @indx: contains the index of the crl to extract
 * @crl: the contents of the crl will be copied there (may be null)
 * @crl_size: should hold the size of the crl
 *
 * This function will return a crl of the PKCS7 or RFC2630 crl set.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.  If the provided buffer is not long enough,
 *   then @crl_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER is
 *   returned.  After the last crl has been read
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
 **/
int
gnutls_pkcs7_get_crl_raw(gnutls_pkcs7_t pkcs7,
			 int indx, void *crl, size_t * crl_size)
{
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
	int result;
	char root2[ASN1_MAX_NAME_SIZE];
	gnutls_datum_t tmp = { NULL, 0 };
	int start, end;

	if (pkcs7 == NULL || crl_size == NULL)
		return GNUTLS_E_INVALID_REQUEST;

	/* Step 1. decode the signed data.
	 */
	result = _decode_pkcs7_signed_data(pkcs7->pkcs7, &c2, &tmp);
	if (result < 0) {
		gnutls_assert();
		return result;
	}

	/* Step 2. Parse the CertificateSet 
	 */

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

	/* Get the raw CRL 
	 */
	result = asn1_der_decoding_startEnd(c2, tmp.data, tmp.size,
					    root2, &start, &end);

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

	end = end - start + 1;

	if ((unsigned) end > *crl_size) {
		*crl_size = end;
		result = GNUTLS_E_SHORT_MEMORY_BUFFER;
		goto cleanup;
	}

	if (crl)
		memcpy(crl, &tmp.data[start], end);

	*crl_size = end;

	result = 0;

      cleanup:
	_gnutls_free_datum(&tmp);
	if (c2)
		asn1_delete_structure(&c2);
	return result;
}
Пример #5
0
/* decodes the Dss-Sig-Value structure
 */
int
_gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r,
		       bigint_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_int (sig, "r", r);
  if (result < 0)
    {
      gnutls_assert ();
      asn1_delete_structure (&sig);
      return result;
    }

  result = _gnutls_x509_read_int (sig, "s", s);
  if (result < 0)
    {
      gnutls_assert ();
      _gnutls_mpi_release (s);
      asn1_delete_structure (&sig);
      return result;
    }

  asn1_delete_structure (&sig);

  return 0;
}
Пример #6
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;
}
Пример #7
0
/**
 * gnutls_x509_crl_get_signature - Returns the CRL's signature
 * @crl: should contain a gnutls_x509_crl_t structure
 * @sig: a pointer where the signature part will be copied (may be null).
 * @sizeof_sig: initially holds the size of @sig
 *
 * This function will extract the signature field of a CRL.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value. and a negative value on error.
 **/
int
gnutls_x509_crl_get_signature (gnutls_x509_crl_t crl,
			       char *sig, size_t * sizeof_sig)
{
  int result;
  int bits;
  unsigned int len;

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

  bits = 0;
  result = asn1_read_value (crl->crl, "signature", NULL, &bits);
  if (result != ASN1_MEM_ERROR)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  if (bits % 8 != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_CERTIFICATE_ERROR;
    }

  len = bits / 8;

  if (*sizeof_sig < len)
    {
      *sizeof_sig = bits / 8;
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
    }

  result = asn1_read_value (crl->crl, "signature", sig, &len);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  return 0;
}
Пример #8
0
/*
 * some x509 certificate parsing functions that relate to MPI parameter
 * extraction. This reads the BIT STRING subjectPublicKey.
 * Returns 2 parameters (m,e).
 */
int
_gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params)
{
  int result;
  ASN1_TYPE spk = ASN1_TYPE_EMPTY;

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

  result = asn1_der_decoding (&spk, der, dersize, NULL);

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


  if ((result = _gnutls_x509_read_int (spk, "modulus", &params[0])) < 0)
    {
      gnutls_assert ();
      asn1_delete_structure (&spk);
      return GNUTLS_E_ASN1_GENERIC_ERROR;
    }

  if ((result = _gnutls_x509_read_int (spk, "publicExponent",
				       &params[1])) < 0)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&params[0]);
      asn1_delete_structure (&spk);
      return GNUTLS_E_ASN1_GENERIC_ERROR;
    }

  asn1_delete_structure (&spk);

  return 0;

}
Пример #9
0
/* Decodes an octet string. The etype specifies the string type.
 * The returned string is always null terminated (but null is not
 * included in size).
 */
int
_gnutls_x509_decode_string(unsigned int etype,
			   const uint8_t * der, size_t der_size,
			   gnutls_datum_t * output, unsigned allow_ber)
{
	int ret;
	uint8_t *str;
	unsigned int str_size, len;
	gnutls_datum_t td;

	if (allow_ber)
		ret =
		    asn1_decode_simple_ber(etype, der, der_size, &str, &str_size, NULL);
	else
		ret =
		    asn1_decode_simple_der(etype, der, der_size, (const uint8_t**)&str, &str_size);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(ret);
		return ret;
	}

	td.size = str_size;
	td.data = gnutls_malloc(str_size + 1);
	if (td.data == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	memcpy(td.data, str, str_size);
	td.data[str_size] = 0;

	if (allow_ber)
		free(str);

	ret = make_printable_string(etype, &td, output);
	if (ret == GNUTLS_E_INVALID_REQUEST) {	/* unsupported etype */
		output->data = td.data;
		output->size = td.size;
		ret = 0;
	} else if (ret <= 0) {
		_gnutls_free_datum(&td);
	}

	/* Refuse to deal with strings containing NULs. */
	if (etype != ASN1_ETYPE_OCTET_STRING) {
		if (output->data)
			len = strlen((void *) output->data);
		else
			len = 0;

		if (len != (size_t) output->size) {
			_gnutls_free_datum(output);
			ret = gnutls_assert_val(GNUTLS_E_ASN1_EMBEDDED_NULL_IN_STRING);
		}
	}

	return ret;
}
Пример #10
0
static int
_get_authority_key_id(gnutls_x509_crl_t cert, ASN1_TYPE * c2,
		      unsigned int *critical)
{
	int ret;
	gnutls_datum_t id;

	*c2 = ASN1_TYPE_EMPTY;

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

	if ((ret =
	     _gnutls_x509_crl_get_extension(cert, "2.5.29.35", 0, &id,
					    critical)) < 0) {
		return gnutls_assert_val(ret);
	}

	if (id.size == 0 || id.data == NULL) {
		gnutls_assert();
		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
	}

	ret = asn1_create_element
	    (_gnutls_get_pkix(), "PKIX1.AuthorityKeyIdentifier", c2);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		_gnutls_free_datum(&id);
		return _gnutls_asn2err(ret);
	}

	ret = asn1_der_decoding(c2, id.data, id.size, NULL);
	_gnutls_free_datum(&id);

	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(c2);
		return _gnutls_asn2err(ret);
	}

	return 0;
}
Пример #11
0
/**
 * gnutls_pkcs7_import:
 * @pkcs7: The structure to store the parsed PKCS7.
 * @data: The DER or PEM encoded PKCS7.
 * @format: One of DER or PEM
 *
 * This function will convert the given DER or PEM encoded PKCS7 to
 * the native #gnutls_pkcs7_t format.  The output will be stored in
 * @pkcs7.
 *
 * If the PKCS7 is PEM encoded it should have a header of "PKCS7".
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs7_import (gnutls_pkcs7_t pkcs7, const gnutls_datum_t * data,
                     gnutls_x509_crt_fmt_t format)
{
  int result = 0, need_free = 0;
  gnutls_datum_t _data;

  if (pkcs7 == NULL)
    return GNUTLS_E_INVALID_REQUEST;

  _data.data = data->data;
  _data.size = data->size;

  /* If the PKCS7 is in PEM format then decode it
   */
  if (format == GNUTLS_X509_FMT_PEM)
    {
      uint8_t *out;

      result = _gnutls_fbase64_decode (PEM_PKCS7, data->data, data->size,
                                       &out);

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

      _data.data = out;
      _data.size = result;

      need_free = 1;
    }


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

  if (need_free)
    _gnutls_free_datum (&_data);

  return 0;

cleanup:
  if (need_free)
    _gnutls_free_datum (&_data);
  return result;
}
Пример #12
0
/* extract an INTEGER from the DER encoded extension
 */
int
_gnutls_x509_ext_extract_number (uint8_t * number,
                                 size_t * _nr_size,
                                 uint8_t * extnValue, int extnValueLen)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  int result;
  int nr_size = *_nr_size;

  /* here it doesn't matter so much that we use CertificateSerialNumber. It is equal
   * to using INTEGER.
   */
  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.CertificateSerialNumber",
        &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);
    }

  /* the default value of cA is false.
   */
  result = asn1_read_value (ext, "", number, &nr_size);
  if (result != ASN1_SUCCESS)
    result = _gnutls_asn2err (result);
  else
    result = 0;

  *_nr_size = nr_size;

  asn1_delete_structure (&ext);

  return result;
}
Пример #13
0
/* Here we only extract the KeyUsage field, from the DER encoded
 * extension.
 */
int
_gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage,
                                   uint8_t * extnValue, int extnValueLen)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  int len, result;
  uint8_t str[2];

  str[0] = str[1] = 0;
  *keyUsage = 0;

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.KeyUsage", &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);
    }

  len = sizeof (str);
  result = asn1_read_value (ext, "", str, &len);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return 0;
    }

  *keyUsage = str[0] | (str[1] << 8);

  asn1_delete_structure (&ext);

  return 0;
}
Пример #14
0
/*
 * some x509 certificate functions that relate to MPI parameter
 * setting. This writes the BIT STRING subjectPublicKey.
 * Needs 2 parameters (m,e).
 *
 * Allocates the space used to store the DER data.
 */
int
_gnutls_x509_write_rsa_params (bigint_t * params, int params_size,
			       gnutls_datum_t * der)
{
  int result;
  ASN1_TYPE spk = ASN1_TYPE_EMPTY;

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

  if (params_size < 2)
    {
      gnutls_assert ();
      result = GNUTLS_E_INVALID_REQUEST;
      goto cleanup;
    }

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

  result = _gnutls_x509_write_int (spk, "modulus", params[0], 1);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _gnutls_x509_write_int (spk, "publicExponent", params[1], 1);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _gnutls_x509_der_encode (spk, "", der, 0);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  asn1_delete_structure (&spk);
  return 0;

cleanup:
  asn1_delete_structure (&spk);

  return result;
}
Пример #15
0
/**
 * gnutls_pkcs12_import:
 * @pkcs12: The structure to store the parsed PKCS12.
 * @data: The DER or PEM encoded PKCS12.
 * @format: One of DER or PEM
 * @flags: an ORed sequence of gnutls_privkey_pkcs8_flags
 *
 * This function will convert the given DER or PEM encoded PKCS12
 * to the native gnutls_pkcs12_t format. The output will be stored in 'pkcs12'.
 *
 * If the PKCS12 is PEM encoded it should have a header of "PKCS12".
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs12_import (gnutls_pkcs12_t pkcs12,
                      const gnutls_datum_t * data,
                      gnutls_x509_crt_fmt_t format, unsigned int flags)
{
  int result = 0, need_free = 0;
  gnutls_datum_t _data;
  char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE];

  _data.data = data->data;
  _data.size = data->size;

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

  /* If the PKCS12 is in PEM format then decode it
   */
  if (format == GNUTLS_X509_FMT_PEM)
    {
      result = _gnutls_fbase64_decode (PEM_PKCS12, data->data, data->size,
                                       &_data);

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

      need_free = 1;
    }

  result =
    asn1_der_decoding (&pkcs12->pkcs12, _data.data, _data.size, error_str);
  if (result != ASN1_SUCCESS)
    {
      result = _gnutls_asn2err (result);
      _gnutls_debug_log ("DER error: %s\n", error_str);
      gnutls_assert ();
      goto cleanup;
    }

  if (need_free)
    _gnutls_free_datum (&_data);

  return 0;

cleanup:
  if (need_free)
    _gnutls_free_datum (&_data);
  return result;
}
Пример #16
0
/* this function reads an integer
 * from asn1 structs. Combines the read and mpi_scan
 * steps.
 */
int
_gnutls_x509_read_int (ASN1_TYPE node, const char *value, bigint_t * ret_mpi)
{
  int result;
  opaque *tmpstr = NULL;
  int tmpstr_size;

  tmpstr_size = 0;
  result = asn1_read_value (node, value, NULL, &tmpstr_size);
  if (result != ASN1_MEM_ERROR)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  tmpstr = gnutls_malloc (tmpstr_size);
  if (tmpstr == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  result = asn1_read_value (node, value, tmpstr, &tmpstr_size);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      gnutls_free (tmpstr);
      return _gnutls_asn2err (result);
    }

  result = _gnutls_mpi_scan (ret_mpi, tmpstr, tmpstr_size);
  gnutls_free (tmpstr);

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

  return 0;
}
Пример #17
0
/*
 * This function writes the parameters for DSS keys.
 * Needs 3 parameters (p,q,g).
 *
 * Allocates the space used to store the DER data.
 */
static int
_gnutls_x509_write_dsa_params(gnutls_pk_params_st * params,
                              gnutls_datum_t * der)
{
    int result;
    ASN1_TYPE spk = ASN1_TYPE_EMPTY;

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

    if (params->params_nr < DSA_PUBLIC_PARAMS - 1) {
        gnutls_assert();
        result = GNUTLS_E_INVALID_REQUEST;
        goto cleanup;
    }

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

    result = _gnutls_x509_write_int(spk, "p", params->params[0], 1);
    if (result < 0) {
        gnutls_assert();
        goto cleanup;
    }

    result = _gnutls_x509_write_int(spk, "q", params->params[1], 1);
    if (result < 0) {
        gnutls_assert();
        goto cleanup;
    }

    result = _gnutls_x509_write_int(spk, "g", params->params[2], 1);
    if (result < 0) {
        gnutls_assert();
        goto cleanup;
    }

    result = _gnutls_x509_der_encode(spk, "", der, 0);
    if (result < 0) {
        gnutls_assert();
        goto cleanup;
    }

    result = 0;

cleanup:
    asn1_delete_structure(&spk);
    return result;
}
Пример #18
0
int
_gnutls_x509_get_dn(ASN1_TYPE asn1_struct,
		    const char *asn1_rdn_name, gnutls_datum_t * dn,
		    unsigned flags)
{
	gnutls_buffer_st out_str;
	int i, k1, result;

	_gnutls_buffer_init(&out_str);

	result = asn1_number_of_elements(asn1_struct, asn1_rdn_name, &k1);
	if (result != ASN1_SUCCESS) {
		if (result == ASN1_ELEMENT_NOT_FOUND || result == ASN1_VALUE_NOT_FOUND) {
			result = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
		} else {
			gnutls_assert();
			result = _gnutls_asn2err(result);
		}
		goto cleanup;
	}

	if (k1 == 0) {
		gnutls_assert();
		result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
		goto cleanup;
	}

	if (flags & GNUTLS_X509_DN_FLAG_COMPAT) {
		for (i=0;i<k1;i++) {
			result = append_elements(asn1_struct, asn1_rdn_name, &out_str, i+1, (i==(k1-1))?1:0);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
		}
	} else {
		while (k1 > 0) {
			result = append_elements(asn1_struct, asn1_rdn_name, &out_str, k1, k1==1?1:0);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
			k1--;
		}
	}

	return _gnutls_buffer_to_datum(&out_str, dn, 1);

 cleanup:
	_gnutls_buffer_clear(&out_str);
	return result;

}
Пример #19
0
/**
  * gnutls_x509_rdn_get - This function parses an RDN sequence and returns a string
  * @idn: should contain a DER encoded RDN sequence
  * @buf: a pointer to a structure to hold the peer's name
  * @sizeof_buf: holds the size of @buf
  *
  * This function will return the name of the given RDN sequence.  The
  * name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in
  * RFC2253.
  *
  * If the provided buffer is not long enough, returns
  * GNUTLS_E_SHORT_MEMORY_BUFFER and *sizeof_buf will be updated.  On
  * success 0 is returned.
  *
  **/
int
gnutls_x509_rdn_get (const gnutls_datum_t * idn,
		     char *buf, size_t * sizeof_buf)
{
  int result;
  ASN1_TYPE dn = ASN1_TYPE_EMPTY;

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

  if (buf)
    buf[0] = 0;


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

  result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
  if (result != ASN1_SUCCESS)
    {
      /* couldn't decode DER */
      gnutls_assert ();
      asn1_delete_structure (&dn);
      return _gnutls_asn2err (result);
    }

  result = _gnutls_x509_parse_dn (dn, "rdnSequence", buf, sizeof_buf);

  asn1_delete_structure (&dn);
  return result;

}
Пример #20
0
/**
 * gnutls_x509_crt_set_private_key_usage_period:
 * @crt: a certificate of type #gnutls_x509_crt_t
 * @activation: The activation time
 * @expiration: The expiration time
 *
 * This function will set the private key usage period extension (2.5.29.16).
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_crt_set_private_key_usage_period(gnutls_x509_crt_t crt,
					     time_t activation,
					     time_t expiration)
{
	int result;
	gnutls_datum_t der_data;
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;

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

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

	result = _gnutls_x509_set_time(c2, "notBefore", activation, 1);
	if (result < 0) {
		gnutls_assert();
		goto cleanup;
	}

	result = _gnutls_x509_set_time(c2, "notAfter", expiration, 1);
	if (result < 0) {
		gnutls_assert();
		goto cleanup;
	}

	result = _gnutls_x509_der_encode(c2, "", &der_data, 0);
	if (result < 0) {
		gnutls_assert();
		goto cleanup;
	}

	result = _gnutls_x509_crt_set_extension(crt, "2.5.29.16",
						&der_data, 0);

	_gnutls_free_datum(&der_data);

	crt->use_extensions = 1;

      cleanup:
	asn1_delete_structure(&c2);

	return result;
}
Пример #21
0
/**
  * gnutls_x509_crq_sign2 - This function will sign a Certificate request with a key
  * @crq: should contain a gnutls_x509_crq_t structure
  * @key: holds a private key
  * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
  * @flags: must be 0
  *
  * This function will sign the certificate request with a private key.
  * This must be the same key as the one used in gnutls_x509_crt_set_key() since a
  * certificate request is self signed.
  *
  * This must be the last step in a certificate request generation since all
  * the previously set parameters are now signed.
  *
  * Returns 0 on success.
  *
  **/
int
gnutls_x509_crq_sign2 (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key,
                       gnutls_digest_algorithm_t dig, unsigned int flags)
{
    int result;
    gnutls_datum_t signature;

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

    /* Step 1. Self sign the request.
     */
    result =
        _gnutls_x509_sign_tbs (crq->crq, "certificationRequestInfo",
                               dig, key, &signature);

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

    /* Step 2. write the signature (bits)
     */
    result =
        asn1_write_value (crq->crq, "signature", signature.data,
                          signature.size * 8);

    _gnutls_free_datum (&signature);

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

    /* Step 3. Write the signatureAlgorithm field.
     */
    result = _gnutls_x509_write_sig_params (crq->crq, "signatureAlgorithm",
                                            key->pk_algorithm, dig, key->params,
                                            key->params_size);
    if (result < 0)
    {
        gnutls_assert ();
        return result;
    }

    return 0;
}
Пример #22
0
/* generate the AuthorityKeyID in a DER encoded extension
 */
int
_gnutls_x509_ext_gen_auth_key_id (const void *id, size_t id_size,
                                  gnutls_datum_t * der_ext)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  int result;

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

  result = asn1_write_value (ext, "keyIdentifier", id, id_size);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return _gnutls_asn2err (result);
    }

  asn1_write_value (ext, "authorityCertIssuer", NULL, 0);
  asn1_write_value (ext, "authorityCertSerialNumber", NULL, 0);

  result = _gnutls_x509_der_encode (ext, "", der_ext, 0);

  asn1_delete_structure (&ext);

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

  return 0;
}
Пример #23
0
/* Writes the specified integer into the specified node.
 */
int
_gnutls_x509_write_int (ASN1_TYPE node, const char *value, bigint_t mpi,
                        int lz)
{
  opaque *tmpstr;
  size_t s_len;
  int result;

  s_len = 0;
  if (lz)
    result = _gnutls_mpi_print_lz (mpi, NULL, &s_len);
  else
    result = _gnutls_mpi_print (mpi, NULL, &s_len);

  if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
    {
      gnutls_assert ();
      return result;
    }

  tmpstr = gnutls_malloc (s_len);
  if (tmpstr == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  if (lz)
    result = _gnutls_mpi_print_lz (mpi, tmpstr, &s_len);
  else
    result = _gnutls_mpi_print (mpi, tmpstr, &s_len);

  if (result != 0)
    {
      gnutls_assert ();
      gnutls_free (tmpstr);
      return GNUTLS_E_MPI_PRINT_FAILED;
    }

  result = asn1_write_value (node, value, tmpstr, s_len);

  gnutls_free (tmpstr);

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

  return 0;
}
Пример #24
0
Файл: pkcs7.c Проект: ares89/vlc
/**
 * gnutls_pkcs7_delete_crl:
 * @pkcs7: should contain a #gnutls_pkcs7_t structure
 * @indx: the index of the crl to delete
 *
 * This function will delete a crl from a PKCS7 or RFC2630 crl set.
 * Index starts from 0. Returns 0 on success.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs7_delete_crl (gnutls_pkcs7_t pkcs7, int indx)
{
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  int result;
  char root2[ASN1_MAX_NAME_SIZE];

  if (pkcs7 == NULL)
    return GNUTLS_E_INVALID_REQUEST;

  /* Step 1. Decode the signed data.
   */
  result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  /* Step 2. Delete the crl.
   */

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

  result = asn1_write_value (c2, root2, NULL, 0);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Step 3. Replace the old content with the new
   */
  result =
    _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  asn1_delete_structure (&c2);

  return 0;

cleanup:
  if (c2)
    asn1_delete_structure (&c2);
  return result;
}
Пример #25
0
/* encodes the Dss-Sig-Value structure
 */
int
_gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value,
			  const gnutls_datum_t * r,
			  const 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_write_value(sig, "r", r->data, r->size);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&sig);
		return _gnutls_asn2err(result);
	}

	result = asn1_write_value(sig, "s", s->data, s->size);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&sig);
		return _gnutls_asn2err(result);
	}

	result = _gnutls_x509_der_encode(sig, "", sig_value, 0);
	asn1_delete_structure(&sig);

	if (result < 0)
		return gnutls_assert_val(result);

	return 0;
}
Пример #26
0
int
_gnutls_x509_read_der_int (opaque * der, int dersize, bigint_t * out)
{
  int result;
  ASN1_TYPE spk = ASN1_TYPE_EMPTY;

  /* == INTEGER */
  if ((result = asn1_create_element
       (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey",
	&spk)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  result = asn1_der_decoding (&spk, der, dersize, NULL);

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

  /* Read Y */

  if ((result = _gnutls_x509_read_int (spk, "", out)) < 0)
    {
      gnutls_assert ();
      asn1_delete_structure (&spk);
      return _gnutls_asn2err (result);
    }

  asn1_delete_structure (&spk);

  return 0;

}
Пример #27
0
/**
 * gnutls_x509_rdn_get_by_oid:
 * @idn: should contain a DER encoded RDN sequence
 * @oid: an Object Identifier
 * @indx: In case multiple same OIDs exist in the RDN indicates which
 *   to send. Use 0 for the first one.
 * @raw_flag: If non-zero then the raw DER data are returned.
 * @buf: a pointer to a structure to hold the peer's name
 * @buf_size: holds the size of @buf
 *
 * This function will return the name of the given Object identifier,
 * of the RDN sequence.  The name will be encoded using the rules
 * from RFC4514.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or
 * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@buf_size is
 * updated if the provided buffer is not long enough, otherwise a
 * negative error value.
 **/
int
gnutls_x509_rdn_get_by_oid(const gnutls_datum_t * idn, const char *oid,
			   int indx, unsigned int raw_flag,
			   void *buf, size_t * buf_size)
{
	int result;
	ASN1_TYPE dn = ASN1_TYPE_EMPTY;
	gnutls_datum_t td;

	if (buf_size == 0) {
		return GNUTLS_E_INVALID_REQUEST;
	}

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

	result = _asn1_strict_der_decode(&dn, idn->data, idn->size, NULL);
	if (result != ASN1_SUCCESS) {
		/* couldn't decode DER */
		gnutls_assert();
		asn1_delete_structure(&dn);
		return _gnutls_asn2err(result);
	}

	result =
	    _gnutls_x509_parse_dn_oid(dn, "rdnSequence", oid, indx,
				      raw_flag, &td);

	asn1_delete_structure(&dn);
	if (result < 0)
		return gnutls_assert_val(result);

	return _gnutls_strdatum_to_buf(&td, buf, buf_size);
}
Пример #28
0
/* Converts a PKCS #8 key to
 * an internal structure (gnutls_private_key)
 * (normally a PKCS #1 encoded RSA key)
 */
static int
pkcs8_key_decode(const gnutls_datum_t * raw_key,
		 const char *password, gnutls_x509_privkey_t pkey,
		 unsigned int decrypt)
{
	int result;
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    _asn1_strict_der_decode(&pkcs8_asn, raw_key->data, raw_key->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	if (decrypt)
		result =
		    pkcs8_key_decrypt(raw_key, pkcs8_asn, password, pkey);
	else
		result = 0;

      error:
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;

}
Пример #29
0
/* generate the keyUsage in a DER encoded extension
 * Use an ORed SEQUENCE of GNUTLS_KEY_* for usage.
 */
int
_gnutls_x509_ext_gen_keyUsage (uint16_t usage, gnutls_datum_t * der_ext)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  int result;
  uint8_t str[2];

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

  str[0] = usage & 0xff;
  str[1] = usage >> 8;

  result = asn1_write_value (ext, "", str, 9);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return _gnutls_asn2err (result);
    }

  result = _gnutls_x509_der_encode (ext, "", der_ext, 0);

  asn1_delete_structure (&ext);

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

  return 0;
}
Пример #30
0
/* generate an INTEGER in a DER encoded extension
 */
int
_gnutls_x509_ext_gen_number (const uint8_t * number, size_t nr_size,
                             gnutls_datum_t * der_ext)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  int result;

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

  result = asn1_write_value (ext, "", number, nr_size);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return _gnutls_asn2err (result);
    }

  result = _gnutls_x509_der_encode (ext, "", der_ext, 0);

  asn1_delete_structure (&ext);

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

  return 0;
}