/** * gnutls_pkcs7_get_crl_count: * @pkcs7: should contain a gnutls_pkcs7_t structure * * This function will return the number of certifcates in the PKCS7 * or RFC2630 crl set. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_pkcs7_get_crl_count (gnutls_pkcs7_t pkcs7) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result, count; 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. Count the CertificateSet */ result = asn1_number_of_elements (c2, "crls", &count); asn1_delete_structure (&c2); if (result != ASN1_SUCCESS) { gnutls_assert (); return 0; /* no crls */ } return count; }
/** * 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; }
/** * 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_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; }
/** * gnutls_pkcs7_get_crt_raw: * @pkcs7: should contain a gnutls_pkcs7_t structure * @indx: contains the index of the certificate to extract * @certificate: the contents of the certificate will be copied * there (may be null) * @certificate_size: should hold the size of the certificate * * This function will return a certificate of the PKCS7 or RFC2630 * certificate set. * * After the last certificate has been read * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. If the provided buffer is not long enough, * then @certificate_size is updated and * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned. **/ int gnutls_pkcs7_get_crt_raw (gnutls_pkcs7_t pkcs7, int indx, void *certificate, size_t * certificate_size) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result, len; char root2[ASN1_MAX_NAME_SIZE]; char oid[MAX_OID_SIZE]; gnutls_datum_t tmp = { NULL, 0 }; if (certificate_size == NULL || pkcs7 == 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), "certificates.?%u", indx + 1); len = sizeof (oid) - 1; result = asn1_read_value (c2, root2, oid, &len); if (result == ASN1_VALUE_NOT_FOUND) { result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; goto cleanup; } if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* if 'Certificate' is the choice found: */ if (strcmp (oid, "certificate") == 0) { int start, end; 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 > *certificate_size) { *certificate_size = end; result = GNUTLS_E_SHORT_MEMORY_BUFFER; goto cleanup; } if (certificate) memcpy (certificate, &tmp.data[start], end); *certificate_size = end; result = 0; } else { result = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } cleanup: _gnutls_free_datum (&tmp); if (c2) asn1_delete_structure (&c2); return result; }