destination file or directory.</para>
<variablelist>
+ <varlistentry>
+ <term><option>--comment</option></term>
+ <listitem><para>Add identifying comments to PEM bundle output files
+ before each certificate.</para></listitem>
+ </varlistentry>
<varlistentry>
<term><option>--filter=<what></option></term>
<listitem><para>Specifies what certificates to export.
return label;
}
+
+char *
+p11_extract_info_comment (p11_extract_info *ex,
+ bool first)
+{
+ char *comment;
+ char *label;
+
+ if (!(ex->flags & P11_EXTRACT_COMMENT))
+ return NULL;
+
+ label = extract_label (ex);
+ if (!asprintf (&comment, "%s# %s\n",
+ first ? "" : "\n",
+ label ? label : ""))
+ return_val_if_reached (NULL);
+
+ free (label);
+ return comment;
+}
{
p11_save_file *file;
p11_buffer buf;
+ char *comment;
bool ret = true;
size_t length;
+ bool first;
CK_RV rv;
char *pem;
if (!file)
return false;
+ first = true;
while ((rv = p11_kit_iter_next (iter)) == CKR_OK) {
p11_buffer_init (&buf, 1024);
pem = p11_pem_write (buf.data, buf.len, "TRUSTED CERTIFICATE", &length);
return_val_if_fail (pem != NULL, false);
- ret = p11_save_write (file, pem, length);
+ comment = p11_extract_info_comment (ex, first);
+ first = false;
+
+ ret = p11_save_write (file, comment, -1) &&
+ p11_save_write (file, pem, length);
+
free (pem);
+ free (comment);
}
p11_buffer_uninit (&buf);
p11_extract_pem_bundle (P11KitIter *iter,
p11_extract_info *ex)
{
+ char *comment;
p11_save_file *file;
bool ret = true;
+ bool first = true;
size_t length;
CK_RV rv;
char *pem;
pem = p11_pem_write (ex->cert_der, ex->cert_len, "CERTIFICATE", &length);
return_val_if_fail (pem != NULL, false);
- p11_debug ("writing 'CERTIFICATE' PEM block of size %lu", (unsigned long)length);
- ret = p11_save_write (file, pem, length);
+ comment = p11_extract_info_comment (ex, first);
+ first = false;
+
+ ret = p11_save_write (file, comment, -1) &&
+ p11_save_write (file, pem, length);
+
+ free (comment);
free (pem);
if (!ret)
opt_filter = 1000,
opt_purpose,
opt_format,
+ opt_comment,
};
struct option options[] = {
{ "format", required_argument, NULL, opt_format },
{ "purpose", required_argument, NULL, opt_purpose },
{ "overwrite", no_argument, NULL, opt_overwrite },
+ { "comment", no_argument, NULL, opt_comment },
{ "verbose", no_argument, NULL, opt_verbose },
{ "quiet", no_argument, NULL, opt_quiet },
{ "help", no_argument, NULL, opt_help },
"usage"
},
{ opt_overwrite, "overwrite output file or directory" },
+ { opt_comment, "add comments to bundles if possible" },
{ opt_verbose, "show verbose debug output", },
{ opt_quiet, "supress command output", },
{ 0 },
case opt_overwrite:
ex.flags |= P11_SAVE_OVERWRITE;
break;
+ case opt_comment:
+ ex.flags |= P11_EXTRACT_COMMENT;
+ break;
case opt_filter:
if (!filter_argument (optarg, &uri, &match))
return 2;
#include "iter.h"
#include "pkcs11.h"
+enum {
+ /* These overlap with the flags in save.h, so start higher */
+ P11_EXTRACT_COMMENT = 1 << 10,
+};
+
typedef struct {
p11_dict *asn1_defs;
p11_dict *limit_to_purposes;
char * p11_extract_info_filename (p11_extract_info *ex);
+char * p11_extract_info_comment (p11_extract_info *ex,
+ bool first);
+
typedef bool (* p11_extract_func) (P11KitIter *iter,
p11_extract_info *ex);
p11_extract_info_cleanup (&ex);
}
+static void
+test_comment_for_label (CuTest *tc)
+{
+ CK_ATTRIBUTE label = { CKA_LABEL, "The Label!", 10 };
+ p11_extract_info ex;
+ char *comment;
+
+ p11_extract_info_init (&ex);
+
+ ex.flags = P11_EXTRACT_COMMENT;
+ ex.attrs = p11_attrs_build (NULL, &label, NULL);
+
+ comment = p11_extract_info_comment (&ex, true);
+ CuAssertStrEquals (tc, "# The Label!\n", comment);
+ free (comment);
+
+ comment = p11_extract_info_comment (&ex, false);
+ CuAssertStrEquals (tc, "\n# The Label!\n", comment);
+ free (comment);
+
+ p11_extract_info_cleanup (&ex);
+}
+
+static void
+test_comment_not_enabled (CuTest *tc)
+{
+ CK_ATTRIBUTE label = { CKA_LABEL, "The Label!", 10 };
+ p11_extract_info ex;
+ char *comment;
+
+ p11_extract_info_init (&ex);
+
+ ex.attrs = p11_attrs_build (NULL, &label, NULL);
+
+ comment = p11_extract_info_comment (&ex, true);
+ CuAssertPtrEquals (tc, NULL, comment);
+
+ comment = p11_extract_info_comment (&ex, false);
+ CuAssertPtrEquals (tc, NULL, comment);
+
+ p11_extract_info_cleanup (&ex);
+}
+
struct {
CK_FUNCTION_LIST module;
P11KitIter *iter;
SUITE_ADD_TEST (suite, test_file_name_for_label);
SUITE_ADD_TEST (suite, test_file_name_for_class);
+ SUITE_ADD_TEST (suite, test_comment_for_label);
+ SUITE_ADD_TEST (suite, test_comment_not_enabled);
SUITE_ADD_TEST (suite, test_info_simple_certificate);
SUITE_ADD_TEST (suite, test_info_limit_purposes);
SUITE_ADD_TEST (suite, test_info_invalid_purposes);