/** * 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; }
/** * 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; }