Пример #1
0
static int check_for_decrypted(const gnutls_datum_t *der)
{
	int result;
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;

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

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

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

}
Пример #2
0
/**
 * gnutls_x509_rdn_get_oid:
 * @idn: should contain a DER encoded RDN sequence
 * @indx: Indicates which OID to return. Use 0 for the first one.
 * @buf: a pointer to a structure to hold the peer's name OID
 * @buf_size: holds the size of @buf
 *
 * This function will return the specified Object identifier, of the
 * RDN sequence.
 *
 * 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.
 *
 * Since: 2.4.0
 **/
int
gnutls_x509_rdn_get_oid(const gnutls_datum_t * idn,
			int indx, void *buf, size_t * buf_size)
{
	int result;
	ASN1_TYPE dn = ASN1_TYPE_EMPTY;

	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_get_dn_oid(dn, "rdnSequence", indx, buf,
				    buf_size);

	asn1_delete_structure(&dn);
	return result;
}
Пример #3
0
/* generate the SubjectKeyID in a DER encoded extension
 */
int
_gnutls_x509_ext_gen_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.SubjectKeyIdentifier", &ext);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        return _gnutls_asn2err(result);
    }

    result = asn1_write_value(ext, "", id, id_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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
0
/**
 * gnutls_x509_rdn_get2:
 * @idn: should contain a DER encoded RDN sequence
 * @buf: a pointer to a structure to hold the peer's name
 * @buf_size: holds the size of @buf
 * @flags: 
 *
 * 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
 * RFC4514.
 *
 * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
 * format will match the format output by previous to 3.5.6 versions of GnuTLS
 * which was not not fully RFC4514-compliant.
 *
 * 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_get2(const gnutls_datum_t * idn,
		     gnutls_datum_t *str, unsigned flags)
{
	int result;
	ASN1_TYPE dn = ASN1_TYPE_EMPTY;

	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_get_dn(dn, "rdnSequence", str, flags);

	asn1_delete_structure(&dn);
	return result;

}
Пример #7
0
/* Encodes and public key parameters into a
 * subjectPublicKeyInfo structure and stores it in der.
 */
int
_gnutls_x509_encode_PKI_params (gnutls_datum_t *der,
                                gnutls_pk_algorithm_t
                                pk_algorithm, gnutls_pk_params_st * params)
{
  int ret;
  ASN1_TYPE tmp;

  ret = asn1_create_element (_gnutls_get_pkix (),
                                "PKIX1.Certificate", &tmp);
  if (ret != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (ret);
    }
    
  ret = _gnutls_x509_encode_and_copy_PKI_params (tmp,
                                         "tbsCertificate.subjectPublicKeyInfo",
                                         pk_algorithm, params);
  if (ret != ASN1_SUCCESS)
    {
      gnutls_assert ();
      ret = _gnutls_asn2err (ret);
      goto cleanup;
    }

  ret = _gnutls_x509_der_encode(tmp, "tbsCertificate.subjectPublicKeyInfo", der, 0);

cleanup:
  asn1_delete_structure (&tmp);

  return ret;
}
Пример #8
0
/* Writes the value of the datum in the given ASN1_TYPE. If str is non
 * (0) it encodes it as OCTET STRING.
 */
int
_gnutls_x509_write_value (ASN1_TYPE c, const char *root,
                          const gnutls_datum_t * data, int str)
{
  int result;
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  gnutls_datum_t val = { NULL, 0 };

  if (str)
    {
      /* Convert it to OCTET STRING
       */
      if ((result = asn1_create_element
           (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
        {
          gnutls_assert ();
          result = _gnutls_asn2err (result);
          goto cleanup;
        }

      result = asn1_write_value (c2, "", data->data, data->size);
      if (result != ASN1_SUCCESS)
        {
          gnutls_assert ();
          result = _gnutls_asn2err (result);
          goto cleanup;
        }

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

    }
  else
    {
      val.data = data->data;
      val.size = data->size;
    }

  /* Write the data.
   */
  result = asn1_write_value (c, root, val.data, val.size);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  result = 0;

cleanup:
  asn1_delete_structure (&c2);
  if (val.data != data->data)
    _gnutls_free_datum (&val);
  return result;
}
Пример #9
0
/* generate the proxyCertInfo in a DER encoded extension
 */
int
_gnutls_x509_ext_gen_proxyCertInfo(int pathLenConstraint,
                                   const char *policyLanguage,
                                   const char *policy,
                                   size_t sizeof_policy,
                                   gnutls_datum_t * der_ext)
{
    ASN1_TYPE ext = ASN1_TYPE_EMPTY;
    int result;

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

    if (pathLenConstraint < 0) {
        result =
            asn1_write_value(ext, "pCPathLenConstraint", NULL, 0);
        if (result != ASN1_SUCCESS)
            result = _gnutls_asn2err(result);
    } else
        result =
            _gnutls_x509_write_uint32(ext, "pCPathLenConstraint",
                                      pathLenConstraint);
    if (result < 0) {
        gnutls_assert();
        asn1_delete_structure(&ext);
        return result;
    }

    result = asn1_write_value(ext, "proxyPolicy.policyLanguage",
                              policyLanguage, 1);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        asn1_delete_structure(&ext);
        return _gnutls_asn2err(result);
    }

    result = asn1_write_value(ext, "proxyPolicy.policy",
                              policy, sizeof_policy);
    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;
}
Пример #10
0
/* generate the basicConstraints in a DER encoded extension
 * Use 0 or 1 (TRUE) for CA.
 * Use negative error codes for pathLenConstraint to indicate that the field
 * should not be present, >= 0 to indicate set values.
 */
int
_gnutls_x509_ext_gen_basicConstraints (int CA,
                                       int pathLenConstraint,
                                       gnutls_datum_t * der_ext)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  const char *str;
  int result;

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

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

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

  if (pathLenConstraint < 0)
    {
      result = asn1_write_value (ext, "pathLenConstraint", NULL, 0);
      if (result < 0)
        result = _gnutls_asn2err (result);
    }
  else
    result = _gnutls_x509_write_uint32 (ext, "pathLenConstraint",
                                        pathLenConstraint);
  if (result < 0)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return result;
    }

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

  asn1_delete_structure (&ext);

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

  return 0;
}
Пример #11
0
/*-
  * gnutls_x509_extract_dn - This function parses an RDN sequence
  * @idn: should contain a DER encoded RDN sequence
  * @rdn: a pointer to a structure to hold the name
  *
  * This function will return the name of the given RDN sequence.
  * The name will be returned as a gnutls_x509_dn structure.
  * Returns a negative error code in case of an error.
  *
  -*/
int
gnutls_x509_extract_dn (const gnutls_datum_t * idn, gnutls_x509_dn * rdn)
{
  ASN1_TYPE dn = ASN1_TYPE_EMPTY;
  int result;
  size_t len;

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

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

  memset (rdn, 0, sizeof (gnutls_x509_dn));

  len = sizeof (rdn->country);
  _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_COUNTRY_NAME, 0, 0,
			     rdn->country, &len);

  len = sizeof (rdn->organization);
  _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
			     0, rdn->organization, &len);

  len = sizeof (rdn->organizational_unit_name);
  _gnutls_x509_parse_dn_oid (dn, "",
			     GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
			     0, rdn->organizational_unit_name, &len);

  len = sizeof (rdn->common_name);
  _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_COMMON_NAME, 0, 0,
			     rdn->common_name, &len);

  len = sizeof (rdn->locality_name);
  _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_LOCALITY_NAME, 0, 0,
			     rdn->locality_name, &len);

  len = sizeof (rdn->state_or_province_name);
  _gnutls_x509_parse_dn_oid (dn, "",
			     GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, 0,
			     rdn->state_or_province_name, &len);

  len = sizeof (rdn->email);
  _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_PKCS9_EMAIL, 0, 0,
			     rdn->email, &len);

  asn1_delete_structure (&dn);

  return 0;
}
Пример #12
0
/* Creates an empty PFX structure for the PKCS12 structure.
 */
static int
create_empty_pfx (ASN1_TYPE pkcs12)
{
  uint8_t three = 3;
  int result;
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;

  /* Use version 3
   */
  result = asn1_write_value (pkcs12, "version", &three, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Write the content type of the data
   */
  result = asn1_write_value (pkcs12, "authSafe.contentType", DATA_OID, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Check if the authenticatedSafe content is empty, and encode a
   * null one in that case.
   */

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

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

  return 0;

cleanup:
  asn1_delete_structure (&c2);
  return result;

}
Пример #13
0
/* Convert the given name to GeneralNames in a DER encoded extension.
 * This is the same as subject alternative name.
 */
int
_gnutls_x509_ext_gen_subject_alt_name (gnutls_x509_subject_alt_name_t
                                       type, const void *data,
                                       unsigned int data_size,
                                       gnutls_datum_t * prev_der_ext,
                                       gnutls_datum_t * der_ext)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  int result;

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

  if (prev_der_ext != NULL && prev_der_ext->data != NULL
      && prev_der_ext->size != 0)
    {
      result =
        asn1_der_decoding (&ext, prev_der_ext->data, prev_der_ext->size,
                           NULL);

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

  result = write_new_general_name (ext, "", type, data, data_size);
  if (result < 0)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return result;
    }

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

  asn1_delete_structure (&ext);

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

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

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

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

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

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

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

  result = 0;

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

  return result;
}
Пример #15
0
/* extract the basicConstraints from the DER encoded extension
 */
int
_gnutls_x509_ext_extract_basicConstraints (unsigned int *CA,
                                           int *pathLenConstraint,
                                           uint8_t * extnValue,
                                           int extnValueLen)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  char str[128];
  int len, result;

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &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, "pathLenConstraint",
                                       (unsigned int*)pathLenConstraint);
      if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
        *pathLenConstraint = -1;
      else if (result != GNUTLS_E_SUCCESS)
        {
          gnutls_assert ();
          asn1_delete_structure (&ext);
          return _gnutls_asn2err (result);
        }
    }

  /* the default value of cA is false.
   */
  len = sizeof (str) - 1;
  result = asn1_read_value (ext, "cA", str, &len);
  if (result == ASN1_SUCCESS && strcmp (str, "TRUE") == 0)
    *CA = 1;
  else
    *CA = 0;

  asn1_delete_structure (&ext);

  return 0;
}
Пример #16
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;
}
Пример #17
0
static int encode_user_notice(const gnutls_datum_t * txt,
			      gnutls_datum_t * der_data)
{
	int result;
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;

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

	/* delete noticeRef */
	result = asn1_write_value(c2, "noticeRef", NULL, 0);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result = asn1_write_value(c2, "explicitText", "utf8String", 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    asn1_write_value(c2, "explicitText.utf8String", txt->data,
			     txt->size);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

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

	result = 0;

      error:
	asn1_delete_structure(&c2);
	return result;

}
Пример #18
0
/**
 * gnutls_x509_dn_init:
 * @dn: the object to be initialized
 *
 * This function initializes a #gnutls_x509_dn_t structure.
 *
 * The object returned must be deallocated using
 * gnutls_x509_dn_deinit().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 2.4.0
 **/
int gnutls_x509_dn_init(gnutls_x509_dn_t * dn)
{
	int result;
	ASN1_TYPE tmpdn = ASN1_TYPE_EMPTY;

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

	*dn = tmpdn;

	return 0;
}
Пример #19
0
/**
 * gnutls_x509_dn_init:
 * @dn: the object to be initialized
 *
 * This function initializes a #gnutls_x509_dn_t type.
 *
 * The object returned must be deallocated using
 * gnutls_x509_dn_deinit().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 2.4.0
 **/
int gnutls_x509_dn_init(gnutls_x509_dn_t * dn)
{
	int result;

	*dn = gnutls_calloc(1, sizeof(gnutls_x509_dn_st));

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

	return 0;
}
Пример #20
0
/**
 * gnutls_x509_crl_init:
 * @crl: The structure to be initialized
 *
 * This function will initialize a CRL structure. CRL stands for
 * Certificate Revocation List. A revocation list usually contains
 * lists of certificate serial numbers that have been revoked by an
 * Authority. The revocation lists are always signed with the
 * authority's private key.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int gnutls_x509_crl_init(gnutls_x509_crl_t * crl)
{
	*crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int));

	if (*crl) {
		int result = asn1_create_element(_gnutls_get_pkix(),
						 "PKIX1.CertificateList",
						 &(*crl)->crl);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			gnutls_free(*crl);
			return _gnutls_asn2err(result);
		}
		return 0;	/* success */
	}
	return GNUTLS_E_MEMORY_ERROR;
}
Пример #21
0
/**
 * gnutls_pkcs12_init:
 * @pkcs12: The structure to be initialized
 *
 * This function will initialize a PKCS12 structure. PKCS12 structures
 * usually contain lists of X.509 Certificates and X.509 Certificate
 * revocation lists.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12)
{
	*pkcs12 = gnutls_calloc(1, sizeof(gnutls_pkcs12_int));

	if (*pkcs12) {
		int result = asn1_create_element(_gnutls_get_pkix(),
						 "PKIX1.pkcs-12-PFX",
						 &(*pkcs12)->pkcs12);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			gnutls_free(*pkcs12);
			return _gnutls_asn2err(result);
		}
		return 0;	/* success */
	}
	return GNUTLS_E_MEMORY_ERROR;
}
Пример #22
0
static int pkcs12_reinit(gnutls_pkcs12_t pkcs12)
{
int result;

	if (pkcs12->pkcs12)
		asn1_delete_structure(&pkcs12->pkcs12);

	result = asn1_create_element(_gnutls_get_pkix(),
					 "PKIX1.pkcs-12-PFX",
					 &pkcs12->pkcs12);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	return 0;
}
Пример #23
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;
}
Пример #24
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;
}
Пример #25
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;
}
Пример #26
0
static int crl_reinit(gnutls_x509_crl_t crl)
{
int result;

	if (crl->crl)
		asn1_delete_structure(&crl->crl);

	result = asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.CertificateList",
				 &crl->crl);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}
	crl->rcache = NULL;
	crl->rcache_idx = 0;
	crl->raw_issuer_dn.size = 0;

	return 0;
}
Пример #27
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;

}
Пример #28
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);
}
Пример #29
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;

}
Пример #30
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;
}