Beispiel #1
0
/**
 * gnutls_pkcs12_set_bag:
 * @pkcs12: should contain a gnutls_pkcs12_t structure
 * @bag: An initialized bag
 *
 * This function will insert a Bag into the PKCS12 structure.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs12_set_bag (gnutls_pkcs12_t pkcs12, gnutls_pkcs12_bag_t bag)
{
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
  int result;
  int enc = 0, dum = 1;
  char null;

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

  /* Step 1. Check if the pkcs12 structure is empty. In that
   * case generate an empty PFX.
   */
  result = asn1_read_value (pkcs12->pkcs12, "authSafe.content", &null, &dum);
  if (result == ASN1_VALUE_NOT_FOUND)
    {
      result = create_empty_pfx (pkcs12->pkcs12);
      if (result < 0)
	{
	  gnutls_assert ();
	  return result;
	}
    }

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

  /* Step 3. Encode the bag elements into a SafeContents 
   * structure.
   */
  result = _pkcs12_encode_safe_contents (bag, &safe_cont, &enc);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe
   * structure.
   */
  result = asn1_write_value (c2, "", "NEW", 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if (enc)
    result = asn1_write_value (c2, "?LAST.contentType", ENC_DATA_OID, 1);
  else
    result = asn1_write_value (c2, "?LAST.contentType", DATA_OID, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if (enc)
    {
      /* Encrypted packets are written directly.
       */
      result =
	asn1_write_value (c2, "?LAST.content",
			  bag->element[0].data.data,
			  bag->element[0].data.size);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}
    }
  else
    {
      result =
	_gnutls_x509_der_encode_and_copy (safe_cont, "", c2,
					  "?LAST.content", 1);
      if (result < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}
    }

  asn1_delete_structure (&safe_cont);


  /* Step 5. Reencode and copy the AuthenticatedSafe into the pkcs12
   * structure.
   */
  result =
    _gnutls_x509_der_encode_and_copy (c2, "", pkcs12->pkcs12,
				      "authSafe.content", 1);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  asn1_delete_structure (&c2);

  return 0;

cleanup:
  asn1_delete_structure (&c2);
  asn1_delete_structure (&safe_cont);
  return result;
}
Beispiel #2
0
/**
 * gnutls_pkcs12_bag_encrypt:
 * @bag: The bag
 * @pass: The password used for encryption, must be ASCII
 * @flags: should be one of #gnutls_pkcs_encrypt_flags_t elements bitwise or'd
 *
 * This function will encrypt the given bag.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
 *   otherwise a negative error code is returned.
 **/
int
gnutls_pkcs12_bag_encrypt(gnutls_pkcs12_bag_t bag, const char *pass,
			  unsigned int flags)
{
	int ret;
	ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
	gnutls_datum_t der = { NULL, 0 };
	gnutls_datum_t enc = { NULL, 0 };
	schema_id id;

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

	if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	/* Encode the whole bag to a safe contents
	 * structure.
	 */
	ret = _pkcs12_encode_safe_contents(bag, &safe_cont, NULL);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	/* DER encode the SafeContents.
	 */
	ret = _gnutls_x509_der_encode(safe_cont, "", &der, 0);

	asn1_delete_structure(&safe_cont);

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

	if (flags & GNUTLS_PKCS_PLAIN) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	id = _gnutls_pkcs_flags_to_schema(flags);

	/* Now encrypt them.
	 */
	ret = _gnutls_pkcs7_encrypt_data(id, &der, pass, &enc);

	_gnutls_free_datum(&der);

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

	/* encryption succeeded. 
	 */

	_pkcs12_bag_free_data(bag);

	bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
	bag->element[0].data = enc;

	bag->bag_elements = 1;


	return 0;
}