return _gnutls_buffer_to_datum(&str, out, 1);
}
-/**
- * gnutls_pkcs7_crt_print:
- * @pkcs7: The PKCS7 struct to be printed
- * @format: Indicate the format to use
- * @out: Newly allocated datum with null terminated string.
- *
- * This function will pretty print a signed PKCS #7 structure, suitable for
- * display to a human.
- *
- * Currently the supported formats are %GNUTLS_CRT_PRINT_FULL and
- * %GNUTLS_CRT_PRINT_COMPACT.
- *
- * The output @out needs to be deallocated using gnutls_free().
- *
- * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
- * negative error value.
- **/
-int gnutls_pkcs7_print(gnutls_pkcs7_t pkcs7,
- gnutls_certificate_print_formats_t format,
- gnutls_datum_t * out)
+static void _gnutls_pkcs7_print_signed(gnutls_pkcs7_t pkcs7,
+ gnutls_certificate_print_formats_t format,
+ gnutls_buffer_st * str)
{
int count, ret, i;
gnutls_pkcs7_signature_info_st info;
- gnutls_buffer_st str;
- const char *oid;
-
- _gnutls_buffer_init(&str);
-
- /* For backwards compatibility with structures using the default OID,
- * we don't print the eContent Type explicitly */
- oid = gnutls_pkcs7_get_embedded_data_oid(pkcs7);
- if (oid) {
- if (strcmp(oid, DATA_OID) != 0
- && strcmp(oid, DIGESTED_DATA_OID) != 0) {
- addf(&str, "eContent Type: %s\n", oid);
- }
- }
for (i = 0;; i++) {
if (i == 0)
- addf(&str, "Signers:\n");
+ addf(str, "Signers:\n");
ret = gnutls_pkcs7_get_signature_info(pkcs7, i, &info);
if (ret < 0)
break;
- print_pkcs7_info(&info, &str, format);
+ print_pkcs7_info(&info, str, format);
gnutls_pkcs7_signature_info_deinit(&info);
}
count = gnutls_pkcs7_get_crt_count(pkcs7);
if (count > 0) {
- addf(&str, "Number of certificates: %u\n\n",
+ addf(str, "Number of certificates: %u\n\n",
count);
for (i = 0; i < count; i++) {
ret =
gnutls_pkcs7_get_crt_raw2(pkcs7, i, &data);
if (ret < 0) {
- addf(&str,
+ addf(str,
"Error: cannot print certificate %d\n",
i);
continue;
continue;
}
- adds(&str, (char*)b64.data);
- adds(&str, "\n");
+ adds(str, (char*)b64.data);
+ adds(str, "\n");
gnutls_free(b64.data);
gnutls_free(data.data);
}
count = gnutls_pkcs7_get_crl_count(pkcs7);
if (count > 0) {
- addf(&str, "Number of CRLs: %u\n\n", count);
+ addf(str, "Number of CRLs: %u\n\n", count);
for (i = 0; i < count; i++) {
ret =
gnutls_pkcs7_get_crl_raw2(pkcs7, i, &data);
if (ret < 0) {
- addf(&str,
+ addf(str,
"Error: cannot print certificate %d\n",
i);
continue;
continue;
}
- adds(&str, (char*)b64.data);
- adds(&str, "\n");
+ adds(str, (char*)b64.data);
+ adds(str, "\n");
gnutls_free(b64.data);
gnutls_free(data.data);
}
}
}
+}
+
+/**
+ * gnutls_pkcs7_print:
+ * @pkcs7: The PKCS7 struct to be printed
+ * @format: Indicate the format to use
+ * @out: Newly allocated datum with null terminated string.
+ *
+ * This function will pretty print a signed PKCS #7 structure, suitable for
+ * display to a human.
+ *
+ * Currently the supported formats are %GNUTLS_CRT_PRINT_FULL and
+ * %GNUTLS_CRT_PRINT_COMPACT.
+ *
+ * The output @out needs to be deallocated using gnutls_free().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ **/
+int gnutls_pkcs7_print(gnutls_pkcs7_t pkcs7,
+ gnutls_certificate_print_formats_t format,
+ gnutls_datum_t * out)
+{
+ gnutls_buffer_st str;
+ const char *oid;
+
+ _gnutls_buffer_init(&str);
+
+ /* For backwards compatibility with structures using the default OID,
+ * we don't print the eContent Type explicitly */
+ oid = gnutls_pkcs7_get_embedded_data_oid(pkcs7);
+ if (oid) {
+ if (strcmp(oid, DATA_OID) != 0
+ && strcmp(oid, DIGESTED_DATA_OID) != 0) {
+ addf(&str, "eContent Type: %s\n", oid);
+ }
+ }
+
+ /* For backwards compatibility don't print anything for Signed-data
+ * files. Print type for all other files */
+ switch (pkcs7->type) {
+ case GNUTLS_PKCS7_DATA:
+ adds(&str, "Content Type: Data\n");
+ addf(&str, "Embedded size: %d octets\n\n", pkcs7->der_encap_data.size);
+ break;
+ case GNUTLS_PKCS7_SIGNED:
+ _gnutls_pkcs7_print_signed(pkcs7, format, &str);
+ break;
+ default:
+ adds(&str, "Unsupported PKCS#7 Content Type\n");
+ break;
+ }
return _gnutls_buffer_to_datum(&str, out, 1);
}
char oid[MAX_OID_SIZE];
gnutls_datum_t tmp = { NULL, 0 };
- if (pkcs7 == NULL)
+ if (pkcs7 == NULL || pkcs7->type != GNUTLS_PKCS7_SIGNED)
return GNUTLS_E_INVALID_REQUEST;
/* Step 2. Parse the CertificateSet
{
int ret, count;
- if (pkcs7 == NULL)
+ if (pkcs7 == NULL || pkcs7->type != GNUTLS_PKCS7_SIGNED)
return GNUTLS_E_INVALID_REQUEST;
ret =
gnutls_datum_t tmp = { NULL, 0 };
unsigned i;
- if (pkcs7 == NULL)
+ if (pkcs7 == NULL || pkcs7->type != GNUTLS_PKCS7_SIGNED)
return GNUTLS_E_INVALID_REQUEST;
memset(info, 0, sizeof(*info));
memset(&info, 0, sizeof(info));
- if (pkcs7 == NULL)
+ if (pkcs7 == NULL || pkcs7->type != GNUTLS_PKCS7_SIGNED)
return GNUTLS_E_INVALID_REQUEST;
ret =
memset(&info, 0, sizeof(info));
- if (pkcs7 == NULL)
+ if (pkcs7 == NULL || pkcs7->type != GNUTLS_PKCS7_SIGNED)
return GNUTLS_E_INVALID_REQUEST;
ret =
/* Creates an empty signed data structure in the pkcs7
* structure and returns a handle to the signed data.
*/
-static int create_empty_signed_data(asn1_node pkcs7, asn1_node * sdata)
+static int create_empty_signed_data(gnutls_pkcs7_t pkcs7)
{
int result;
- *sdata = NULL;
+ pkcs7->content_data = NULL;
if ((result = asn1_create_element
(_gnutls_get_pkix(), "PKIX1.pkcs-7-SignedData",
- sdata)) != ASN1_SUCCESS) {
+ &pkcs7->content_data)) != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
goto cleanup;
/* Use version 1
*/
- result = asn1_write_value(*sdata, "version", &one, 1);
+ result = asn1_write_value(pkcs7->content_data, "version", &one, 1);
if (result != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
/* id-data */
result =
- asn1_write_value(*sdata, "encapContentInfo.eContentType",
+ asn1_write_value(pkcs7->content_data, "encapContentInfo.eContentType",
DIGESTED_DATA_OID, 1);
if (result != ASN1_SUCCESS) {
gnutls_assert();
goto cleanup;
}
- result = asn1_write_value(*sdata, "encapContentInfo.eContent", NULL, 0);
+ result = asn1_write_value(pkcs7->content_data, "encapContentInfo.eContent", NULL, 0);
if (result != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
goto cleanup;
}
+ pkcs7->type = GNUTLS_PKCS7_SIGNED;
+
/* Add no certificates.
*/
return 0;
cleanup:
- asn1_delete_structure(sdata);
+ asn1_delete_structure(&pkcs7->content_data);
+ pkcs7->type = GNUTLS_PKCS7_UNINITIALIZED;
return result;
}
* signedData.
*/
result =
- create_empty_signed_data(pkcs7->pkcs7, &pkcs7->content_data);
+ create_empty_signed_data(pkcs7);
if (result < 0) {
gnutls_assert();
return result;
}
}
+ if (pkcs7->type != GNUTLS_PKCS7_SIGNED)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
/* Step 2. Append the new certificate.
*/
int result;
char root2[MAX_NAME_SIZE];
- if (pkcs7 == NULL)
+ if (pkcs7 == NULL || pkcs7->type != GNUTLS_PKCS7_SIGNED)
return GNUTLS_E_INVALID_REQUEST;
/* Step 2. Delete the certificate.
gnutls_datum_t tmp = { NULL, 0 };
int start, end;
- if (pkcs7 == NULL || crl == NULL)
+ if (pkcs7 == NULL || pkcs7->type != GNUTLS_PKCS7_SIGNED || crl == NULL)
return GNUTLS_E_INVALID_REQUEST;
result = _gnutls_x509_read_value(pkcs7->pkcs7, "content", &tmp);
* signedData.
*/
result =
- create_empty_signed_data(pkcs7->pkcs7, &pkcs7->content_data);
+ create_empty_signed_data(pkcs7);
if (result < 0) {
gnutls_assert();
return result;
}
}
+ if (pkcs7->type != GNUTLS_PKCS7_SIGNED)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+
/* Step 2. Append the new crl.
*/
int result;
char root2[MAX_NAME_SIZE];
- if (pkcs7 == NULL)
+ if (pkcs7 == NULL || pkcs7->type != GNUTLS_PKCS7_SIGNED)
return GNUTLS_E_INVALID_REQUEST;
/* Delete the crl.
if (pkcs7 == NULL || me == NULL)
return GNUTLS_E_INVALID_REQUEST;
+ if (pkcs7->type != GNUTLS_PKCS7_SIGNED)
+ asn1_delete_structure(&pkcs7->content_data);
+
if (pkcs7->content_data == NULL) {
result =
asn1_create_element(_gnutls_get_pkix(),
(void)asn1_write_value(pkcs7->content_data,
"encapContentInfo.eContent", NULL, 0);
}
+ pkcs7->type = GNUTLS_PKCS7_SIGNED;
}
result = asn1_write_value(pkcs7->content_data, "version", &one, 1);
{
int result;
+ if (pkcs7->content_data)
+ asn1_delete_structure(&pkcs7->content_data);
+
+ _gnutls_free_datum(&pkcs7->der_encap_data);
+
asn1_delete_structure(&pkcs7->pkcs7);
result = asn1_create_element(_gnutls_get_pkix(),
return result;
}
+ pkcs7->type = GNUTLS_PKCS7_UNINITIALIZED;
+
return 0;
}
gnutls_free(pkcs7);
}
+static int _gnutls_pkcs7_decode_plain_data(gnutls_pkcs7_t pkcs7)
+{
+ asn1_node c2;
+ int result;
+ gnutls_datum_t tmp = {NULL, 0};
+
+ if ((result = asn1_create_element
+ (_gnutls_get_pkix(), "PKIX1.pkcs-7-Data",
+ &c2)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ /* the Data has been created, so decode it.
+ */
+ result = _gnutls_x509_read_value(pkcs7->pkcs7, "content", &tmp);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ result = asn1_der_decoding(&c2, tmp.data, tmp.size, NULL);
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ result = _gnutls_asn2err(result);
+ goto cleanup;
+ }
+
+ result = _gnutls_x509_read_value(c2, "", &pkcs7->der_encap_data);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ strcpy(pkcs7->encap_data_oid, DATA_OID);
+
+ pkcs7->content_data = c2;
+ gnutls_free(tmp.data);
+
+ return 0;
+
+ cleanup:
+ gnutls_free(tmp.data);
+ if (c2)
+ asn1_delete_structure(&c2);
+ return result;
+}
+
/**
* gnutls_pkcs7_import:
* @pkcs7: The data to store the parsed PKCS7.
return _gnutls_asn2err(result);
}
- if (strcmp(data_oid, SIGNED_DATA_OID) != 0) {
+ if (strcmp(data_oid, DATA_OID) == 0) {
+ pkcs7->type = GNUTLS_PKCS7_DATA;
+ result = _gnutls_pkcs7_decode_plain_data(pkcs7);
+ } else if (strcmp(data_oid, SIGNED_DATA_OID) == 0) {
+ pkcs7->type = GNUTLS_PKCS7_SIGNED;
+ result = _gnutls_pkcs7_decode_signed_data(pkcs7);
+ } else {
gnutls_assert();
_gnutls_debug_log("Unknown PKCS7 Content OID '%s'\n", pkcs7->encap_data_oid);
return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
}
- /* Decode the signed data.
- */
- result = _gnutls_pkcs7_decode_signed_data(pkcs7);
if (result < 0) {
gnutls_assert();
goto cleanup;
int result;
int count;
+ if (pkcs7->type != GNUTLS_PKCS7_SIGNED)
+ return;
+
/* disable the optional fields */
result = asn1_number_of_elements(pkcs7->content_data, "crls", &count);
if (result != ASN1_SUCCESS || count == 0) {
static int reencode(gnutls_pkcs7_t pkcs7)
{
int result;
+ const char *oid;
if (pkcs7->content_data != NULL) {
disable_opt_fields(pkcs7);
return gnutls_assert_val(result);
}
+ switch (pkcs7->type) {
+ case GNUTLS_PKCS7_DATA:
+ oid = DATA_OID;
+ break;
+ case GNUTLS_PKCS7_SIGNED:
+ oid = SIGNED_DATA_OID;
+ break;
+ default:
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ }
+
/* Write the content type of the signed data
*/
- result =
- asn1_write_value(pkcs7->pkcs7, "contentType",
- SIGNED_DATA_OID, 1);
+ result = asn1_write_value(pkcs7->pkcs7, "contentType", oid, 1);
if (result != ASN1_SUCCESS) {
gnutls_assert();
return _gnutls_asn2err(result);
asn1_node crq;
} gnutls_x509_crq_int;
+typedef enum {
+ GNUTLS_PKCS7_UNINITIALIZED = 0,
+ GNUTLS_PKCS7_DATA = 1,
+ GNUTLS_PKCS7_SIGNED = 2,
+} gnutls_pkcs7_content_type_t;
+
typedef struct gnutls_pkcs7_attrs_st {
char *oid;
gnutls_datum_t data;
typedef struct gnutls_pkcs7_int {
asn1_node pkcs7;
+ gnutls_pkcs7_content_type_t type;
+
char encap_data_oid[MAX_OID_SIZE];
gnutls_datum_t der_encap_data;
data/cert-with-non-digits-time-ca.pem data/cert-with-non-digits-time.pem \
data/chain-512-leaf.pem data/chain-512-subca.pem data/chain-512-ca.pem \
templates/template-no-ca-honor.tmpl templates/template-no-ca-explicit.tmpl \
+ data/rfc4134-3.1.der data/rfc4134-3.1.der.out \
+ data/rfc4134-3.2.der data/rfc4134-3.2.der.out \
data/crq-cert-no-ca-explicit.pem data/crq-cert-no-ca-honor.pem data/commonName.cer \
templates/simple-policy.tmpl data/simple-policy.pem
--- /dev/null
+Content Type: Data
+Embedded size: 28 octets
+-----BEGIN PKCS7-----
+MCsGCSqGSIb3DQEHAaAeBBxUaGlzIGlzIHNvbWUgc2FtcGxlIGNvbnRlbnQu
+-----END PKCS7-----
--- /dev/null
+0+\ 6 *\86H\86÷\r\ 1\a\ 1 \1e\ 4\1cThis is some sample content.
\ No newline at end of file
--- /dev/null
+Content Type: Data
+Embedded size: 28 octets
+-----BEGIN PKCS7-----
+MCsGCSqGSIb3DQEHAaAeBBxUaGlzIGlzIHNvbWUgc2FtcGxlIGNvbnRlbnQu
+-----END PKCS7-----
GOST_P7B=""
fi
-for FILE in single-ca.p7b full.p7b openssl.p7b openssl-keyid.p7b $GOST_P7B; do
+for FILE in single-ca.p7b full.p7b openssl.p7b openssl-keyid.p7b rfc4134-3.1.der rfc4134-3.2.der $GOST_P7B; do
${VALGRIND} "${CERTTOOL}" --inder --p7-info --infile "${srcdir}/data/${FILE}"|grep -v "Signing time" >"${OUTFILE}"
rc=$?