/* 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; }
/** * 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; }
/** * 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; }
static int write_complex_string(ASN1_TYPE asn_struct, const char *where, const struct oid_to_string *oentry, const uint8_t * data, size_t data_size) { char tmp[128]; ASN1_TYPE c2; int result; const char *string_type; unsigned int i; result = asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc, &c2); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } tmp[0] = 0; string_type = "printableString"; /* Check if the data is ASN.1 printable, and use * the UTF8 string type if not. */ for (i = 0; i < data_size; i++) { if (!is_printable(data[i])) { string_type = "utf8String"; break; } } /* if the type is a CHOICE then write the * type we'll use. */ result = asn1_write_value(c2, "", string_type, 1); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } _gnutls_str_cpy(tmp, sizeof(tmp), string_type); result = asn1_write_value(c2, tmp, data, data_size); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } result = _gnutls_x509_der_encode_and_copy(c2, "", asn_struct, where, 0); if (result < 0) { gnutls_assert(); goto error; } result = 0; error: asn1_delete_structure(&c2); return result; }
/* This will encode and write the AttributeTypeAndValue field. * 'multi' must be zero if writing an AttributeTypeAndValue, and 1 if Attribute. * In all cases only one value is written. */ int _gnutls_x509_encode_and_write_attribute (const char *given_oid, ASN1_TYPE asn1_struct, const char *where, const void *_data, int sizeof_data, int multi) { const char *val_name; const opaque *data = _data; char tmp[128]; ASN1_TYPE c2; int result; /* Find how to encode the data. */ val_name = asn1_find_structure_from_oid (_gnutls_get_pkix (), given_oid); if (val_name == NULL) { gnutls_assert (); return GNUTLS_E_X509_UNSUPPORTED_OID; } _gnutls_str_cpy (tmp, sizeof (tmp), "PKIX1."); _gnutls_str_cat (tmp, sizeof (tmp), val_name); result = asn1_create_element (_gnutls_get_pkix (), tmp, &c2); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } tmp[0] = 0; if ((result = _gnutls_x509_oid_data_choice (given_oid)) > 0) { char *string_type; int i; string_type = "printableString"; /* Check if the data is plain ascii, and use * the UTF8 string type if not. */ for (i = 0; i < sizeof_data; i++) { if (!isascii (data[i])) { string_type = "utf8String"; break; } } /* if the type is a CHOICE then write the * type we'll use. */ result = asn1_write_value (c2, "", string_type, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&c2); return _gnutls_asn2err (result); } _gnutls_str_cpy (tmp, sizeof (tmp), string_type); } result = asn1_write_value (c2, tmp, data, sizeof_data); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&c2); return _gnutls_asn2err (result); } /* write the data (value) */ _gnutls_str_cpy (tmp, sizeof (tmp), where); _gnutls_str_cat (tmp, sizeof (tmp), ".value"); if (multi != 0) { /* if not writing an AttributeTypeAndValue, but an Attribute */ _gnutls_str_cat (tmp, sizeof (tmp), "s"); /* values */ result = asn1_write_value (asn1_struct, tmp, "NEW", 1); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST"); } result = _gnutls_x509_der_encode_and_copy (c2, "", asn1_struct, tmp, 0); if (result < 0) { gnutls_assert (); return result; } /* write the type */ _gnutls_str_cpy (tmp, sizeof (tmp), where); _gnutls_str_cat (tmp, sizeof (tmp), ".type"); result = asn1_write_value (asn1_struct, tmp, given_oid, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } return 0; }
/** * gnutls_pkcs7_set_crl_raw: * @pkcs7: should contain a #gnutls_pkcs7_t structure * @crl: the DER encoded crl to be added * * This function will add a crl to the PKCS7 or RFC2630 crl set. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_pkcs7_set_crl_raw (gnutls_pkcs7_t pkcs7, const gnutls_datum_t * crl) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result; 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 && result != GNUTLS_E_ASN1_VALUE_NOT_FOUND) { gnutls_assert (); return result; } /* If the signed data are uninitialized * then create them. */ if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND) { /* The pkcs7 structure is new, so create the * signedData. */ result = create_empty_signed_data (pkcs7->pkcs7, &c2); if (result < 0) { gnutls_assert (); return result; } } /* Step 2. Append the new crl. */ result = asn1_write_value (c2, "crls", "NEW", 1); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = asn1_write_value (c2, "crls.?LAST", crl->data, crl->size); 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; }