aboutsummaryrefslogtreecommitdiffstats
path: root/sm
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2026-05-07 15:58:41 +0200
committerWerner Koch <[email protected]>2026-05-07 15:59:11 +0200
commita2134cac903ff66ca6c9fb5baa4bddc019378cbe (patch)
treed6878e703eb72035650bdccfedd3bc372b0cd753 /sm
parentcommon: Add new function strlist_pop_try. (diff)
downloadgnupg-a2134cac903ff66ca6c9fb5baa4bddc019378cbe.tar.gz
gnupg-a2134cac903ff66ca6c9fb5baa4bddc019378cbe.zip
gpgsm: New server command SETATTR.
* sm/gpgsm.h (opt): Move 'attributes' to ... (struct server_control_s): ... here. * sm/gpgsm.c (opt_attributes): New. (main): Store value for --attribute in new var. (gpgsm_init_default_ctrl): Set new member attribute from opt_attributes. (gpgsm_deinit_default_ctrl): Free new member. * sm/server.c (cmd_setattr): New. * sm/sign.c (gpgsm_sign): Use ctrl->attributes instead of the fomer opt.attribute. -- GnuPG-bug-id: 4537
Diffstat (limited to 'sm')
-rw-r--r--sm/gpgsm.c7
-rw-r--r--sm/gpgsm.h24
-rw-r--r--sm/server.c64
-rw-r--r--sm/sign.c2
4 files changed, 83 insertions, 14 deletions
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index ca0092db6..bd0f7b89e 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -551,6 +551,9 @@ static int default_include_certs = DEFAULT_INCLUDE_CERTS;
/* Whether the chain mode shall be used for validation. */
static int default_validation_model;
+/* The collected --attributes values from the command line. */
+static strlist_t opt_attributes;
+
/* Counter used to convey data from deinit_ctrl to gpgsm_exit. */
static unsigned int parent_cache_stats;
@@ -1521,7 +1524,7 @@ main ( int argc, char **argv)
case oAuthenticode: opt.authenticode = 1; break;
case oAttribute:
- add_to_strlist (&opt.attributes, pargs.r.ret_str);
+ add_to_strlist (&opt_attributes, pargs.r.ret_str);
break;
case oNoAutostart: opt.autostart = 0; break;
@@ -2417,6 +2420,7 @@ gpgsm_exit (int rc)
void
gpgsm_init_default_ctrl (struct server_control_s *ctrl)
{
+ ctrl->attributes = strlist_copy (opt_attributes);
ctrl->include_certs = default_include_certs;
ctrl->use_ocsp = opt.enable_ocsp;
ctrl->validation_model = default_validation_model;
@@ -2437,6 +2441,7 @@ gpgsm_deinit_default_ctrl (ctrl_t ctrl)
gpgsm_flush_keyinfo_cache (ctrl);
xfree (ctrl->revocation_reason);
ctrl->revocation_reason = NULL;
+ FREE_STRLIST (ctrl->attributes);
n = 0;
while (ctrl->parent_cert_cache)
{
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index bb47021ee..db193ca5d 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -172,18 +172,6 @@ struct
/* Enable creation of authenticode signatures. */
int authenticode;
- /* A list of extra attributes put into a signed data object. For a
- * signed each attribute each string has the format:
- * <oid>:s:<hex_or_filename>
- * and for an unsigned attribute
- * <oid>:u:<hex_or_filename>
- * The OID is in the usual dotted decimal for. The HEX_OR_FILENAME
- * is either a list of hex digits or a filename with the DER encoded
- * value. A filename is detected by the presence of a slash in the
- * HEX_OR_FILENAME. The actual value needs to be encoded as a SET OF
- * attribute values. */
- strlist_t attributes;
-
/* The list of --assert-signer option values. Note: The values are
* modified to uppercase if they represent a fingerrint */
strlist_t assert_signer_list;
@@ -321,6 +309,18 @@ struct server_control_s
gnupg_isotime_t revoked_at;
char *revocation_reason;
+ /* A list of extra attributes put into a signed data object. For a
+ * signed each attribute each string has the format:
+ * <oid>:s:<hex_or_filename>
+ * and for an unsigned attribute
+ * <oid>:u:<hex_or_filename>
+ * The OID is in the usual dotted decimal form. The HEX_OR_FILENAME
+ * is either a list of hex digits or a filename with the DER encoded
+ * value. A filename is detected by the presence of a slash in the
+ * HEX_OR_FILENAME. The actual value needs to be DER encoded and
+ * multiple values are concatenated w/o an outer container. */
+ strlist_t attributes;
+
/* The cache used to find the parent cert. */
cert_cache_item_t parent_cert_cache;
diff --git a/sm/server.c b/sm/server.c
index b83410f0c..d434347b6 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -629,6 +629,69 @@ cmd_verify (assuan_context_t ctx, char *line)
}
+static const char hlp_setattr[] =
+ "SETATTR [--append|--clear] <string>\n"
+ "\n"
+ "The client may use this command to setup attributes to be included\n"
+ "in the signature. For details see the CLI option --attributes. This\n"
+ "command can be used several times to include different attributes. With\n"
+ "--append, <string> is appended to the string provided by the previous\n"
+ "SETATTR command. With --clear, the list of attributes is cleared\n"
+ "including those copied from the configuration file or the CLI; the\n"
+ "collected attributes are not cleared by a RESET or SIGN command.";
+static gpg_error_t
+cmd_setattr (assuan_context_t ctx, char *line)
+{
+ ctrl_t ctrl = assuan_get_pointer (ctx);
+ int append, clear;
+ gpg_error_t err;
+
+ append = has_option (line, "--append");
+ clear = has_option (line, "--clear");
+
+ line = skip_options (line);
+
+ if (clear)
+ FREE_STRLIST (ctrl->attributes);
+
+ if (!*line)
+ return 0; /* No value given - ignore. */
+
+ /* Note that we ignore append if no attributes are already set. */
+ /* We should do a syntax check on the finished attributes but that
+ * would require the use of a "--more" option which is more
+ * cumbersome for the client side. Maybe a --check option can be
+ * implemented but it in the end it is easier to wait for the
+ * outcome of the SIGN command. */
+ if (append && ctrl->attributes)
+ {
+ char *tmp, *tmp2;
+
+ err = gpg_error (strlist_pop_try (&ctrl->attributes, &tmp));
+ if (!err)
+ {
+ tmp2 = strconcat (tmp, line, NULL);
+ if (!tmp2)
+ err = gpg_error_from_syserror ();
+ else if (!add_to_strlist_try (&ctrl->attributes, tmp2))
+ err = gpg_error_from_syserror ();
+
+ xfree (tmp);
+ xfree (tmp2);
+ }
+ }
+ else
+ {
+ if (!add_to_strlist_try (&ctrl->attributes, line))
+ err = out_of_core ();
+ else
+ err = 0;
+ }
+
+ return err;
+}
+
+
static const char hlp_sign[] =
"SIGN [--detached]\n"
"\n"
@@ -1380,6 +1443,7 @@ register_commands (assuan_context_t ctx)
{ "ENCRYPT", cmd_encrypt, hlp_encrypt },
{ "DECRYPT", cmd_decrypt, hlp_decrypt },
{ "VERIFY", cmd_verify, hlp_verify },
+ { "SETATTR", cmd_setattr, hlp_setattr },
{ "SIGN", cmd_sign, hlp_sign },
{ "IMPORT", cmd_import, hlp_import },
{ "EXPORT", cmd_export, hlp_export },
diff --git a/sm/sign.c b/sm/sign.c
index 1551efe6e..09f1a93e2 100644
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -974,7 +974,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
{
strlist_t sl;
- for (sl = opt.attributes; sl; sl = sl->next)
+ for (sl = ctrl->attributes; sl; sl = sl->next)
if ((err = add_signed_attribute (cms, sl->d)))
goto leave;
}