Subject: Re: bug#50507: New function in Emacs GnuTLS implementation

From: Nikolaos Chatzikonstantinou <[email-masked]>
Date: Thu, 29 Sep 2022 09:44:09 -0400

On Thu, Sep 29, 2022 at 5:02 AM Robert Pluim <[email-masked]> wrote:
>
> >>>>> On Wed, 28 Sep 2022 23:09:46 -0400, Nikolaos Chatzikonstantinou <[email-masked]> said:
>
>     Nikolaos> From b11707c423773f6234746991222acd80ab3f708c Mon Sep 17 00:00:00 2001
>     Nikolaos> From: Nikolaos Chatzikonstantinou <[email-masked]>
>     Nikolaos> Date: Mon, 26 Sep 2022 11:08:18 -0400
>     Nikolaos> Subject: [PATCH] add :pass and :flags to gnutls-boot for :keylist
>
>     Nikolaos> +   corresponds to a GnuTLS C flag, the ORed result is to be passed to
>     Nikolaos> +   the function gnutls_certificate_set_x509_key_file2() as its last
>     Nikolaos> +   argument.
>     Nikolaos> +*/
>     Nikolaos> +static unsigned int
>     Nikolaos> +key_file2_aux (Lisp_Object flags)
>     Nikolaos> +{
>     Nikolaos> +  unsigned int rv = 0;
>     Nikolaos> +  Lisp_Object tail;
>     Nikolaos> +  for (tail = flags; CONSP (tail); tail = XCDR (tail))
>
> We have some convenience macros in lisp.h for traversing lists, one of
> which is FOR_EACH_TAIL. The reason to prefer it is that it will detect
> circular lists, which is good practice since this list will come from
> the user level, so it could be anything :-)

Good point. I opted for FOR_EACH_TAIL_SAFE, which seems even better
for this case. As documented in ChangeLog.3, it's the right one when
the operation is idempotent, which an OR of flags is. (repeated flags
do not alter the result.)

>     Nikolaos> +The :pass and :flags keys are ignored with old versions of GnuTLS, and
>     Nikolaos> +:flags is ignored if :pass is not specified.
>     Nikolaos> +
>
> Maybe mention that not specifying :flags or passing :flags nil means
> passing '0' to the GnuTLS function?

Yes, and on that note, I discovered two things. One, the value 0 is
special; it has meaning but it is not an enumeration constant. I
documented this appropriately. Two, the password may be NULL instead
of a string.

How can I differentiate between `:pass nil` and not specifying
`:pass`? I would like to do this because in the former case I'm
calling ...key_file2() and in the latter I'm calling the original
...key_file().

>     Nikolaos> +  DEFSYM (Qgnutls_pkcs_plain, "GNUTLS_PKCS_PLAIN");
<removed a few more such lines>
>     Nikolaos> +  DEFSYM (Qgnutls_pkcs_pbes2_gost_cpd, "GNUTLS_PKCS_PBES2_GOST_CPD");
>
> All this is kind of awkward, but apart from doing DEFVAR_LISP Iʼm not
> aware of how to define a lisp level symbol with a value (it would
> allow you to simplify `key_file2_aux', since you could just extract
> the values directly from the symbols).

I am now comparing against intern("GNUTLS_PKCS_PLAIN") and so on.

I will hold off the submission of the final patch until I figure out
the :pass issue that I mentioned above.

Regards,
Nikolaos Chatzikonstantinou