[git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-422-gd455543
by Werner Koch
cvs at cvs.gnupg.org
Sat Dec 7 23:11:23 CET 2013
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".
The branch, master has been updated
via d4555433b6e422fa69a85cae99961f513e55d82b (commit)
via 405021cb6d4e470337302c65dec5bc91491a89c1 (commit)
via 4cf2c65fe15173c8d68a141a01b34fc1fb9080b7 (commit)
from 5917ce34e3b3eac4c15f62577e4723974024f818 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit d4555433b6e422fa69a85cae99961f513e55d82b
Author: Werner Koch <wk at gnupg.org>
Date: Tue Oct 22 14:26:53 2013 +0200
sexp: Allow long names and white space in gcry_sexp_extract_param.
* src/sexp.c (_gcry_sexp_vextract_param): Skip white space. Support
long parameter names.
* tests/tsexp.c (check_extract_param): Add test cases for long parameter
names and white space.
Signed-off-by: Werner Koch <wk at gnupg.org>
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index 91168a8..927634f 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -4145,10 +4145,10 @@ likely want to use @code{GCRYMPI_FMT_USG}.
@w{const char *@var{path}}, @
@w{const char *@var{list}}, ...)
-Extract parameters from an S-expression using a list of single letter
-parameter names. The names of these parameters are specified in
-LIST. Some special characters may be given to control the
-conversion:
+Extract parameters from an S-expression using a list of parameter
+names. The names of these parameters are specified in LIST. White
+space between the parameter names are ignored. Some special characters
+may be given to control the conversion:
@table @samp
@item +
@@ -4162,21 +4162,25 @@ computations; see @code{gcry_mpi_get_opaque} for details.
@item &
Switch to buffer descriptor mode. See below for details.
@item ?
-If immediately following a parameter letter, that parameter is
-considered optional.
+If immediately following a parameter letter (no white space allowed),
+that parameter is considered optional.
@end table
+In general parameter names are single letters. To use a string for a
+parameter name, enclose the name in single quotes.
+
Unless in buffer descriptor mode for each parameter name a pointer to
an @code{gcry_mpi_t} variable is expected finally followed by a @code{NULL}.
For example
@example
- _gcry_sexp_extract_param (key, NULL, "n/x+ed",
- &mpi_n, &mpi_x, &mpi_e, NULL)
+ _gcry_sexp_extract_param (key, NULL, "n/x+e d-'foo'",
+ &mpi_n, &mpi_x, &mpi_e, &mpi_foo, NULL)
@end example
stores the parameter 'n' from @var{key} as an unsigned MPI into
- at var{mpi_n}, the parameter 'x' as an opaque MPI into @var{mpi_x}, and
-the parameter 'e' again as an unsigned MPI into @var{mpi_e}.
+ at var{mpi_n}, the parameter 'x' as an opaque MPI into @var{mpi_x}, the
+parameter 'e' again as an unsigned MPI into @var{mpi_e}, and the
+parameter 'foo' as a signed MPI.
@var{path} is an optional string used to locate a token. The
exclamation mark separated tokens are used via
diff --git a/src/sexp.c b/src/sexp.c
index 16def5b..7ff4c0a 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -2113,10 +2113,9 @@ _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
}
-/* Extract MPIs from an s-expression using a list of one letter
- * parameters. The names of these parameters are given by the string
- * LIST. Some special characters may be given to control the
- * conversion:
+/* Extract MPIs from an s-expression using a list of parameters. The
+ * names of these parameters are given by the string LIST. Some
+ * special characters may be given to control the conversion:
*
* + :: Switch to unsigned integer format (default).
* - :: Switch to standard signed format.
@@ -2124,6 +2123,9 @@ _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
* & :: Switch to buffer descriptor mode - see below.
* ? :: The previous parameter is optional.
*
+ * In general parameter names are single letters. To use a string for
+ * a parameter name, enclose the name in single quotes.
+ *
* Unless in gcry_buffer_t mode for each parameter name a pointer to
* an MPI variable is expected and finally a NULL is expected.
* Example:
@@ -2158,7 +2160,7 @@ _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
const char *list, va_list arg_ptr)
{
gpg_err_code_t rc;
- const char *s;
+ const char *s, *s2;
gcry_mpi_t *array[20];
char arrayisdesc[20];
int idx;
@@ -2173,10 +2175,23 @@ _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
was found. */
for (s=list, idx=0; *s && idx < DIM (array); s++)
{
- if (*s == '&' || *s == '+' || *s == '-' || *s == '/' || *s == '?' )
+ if (*s == '&' || *s == '+' || *s == '-' || *s == '/' || *s == '?')
+ ;
+ else if (whitespacep (s))
;
else
{
+ if (*s == '\'')
+ {
+ s++;
+ s2 = strchr (s, '\'');
+ if (!s2 || s2 == s)
+ {
+ /* Closing quote not found or empty string. */
+ return GPG_ERR_SYNTAX;
+ }
+ s = s2;
+ }
array[idx] = va_arg (arg_ptr, gcry_mpi_t *);
if (!array[idx])
return GPG_ERR_MISSING_VALUE; /* NULL pointer given. */
@@ -2221,11 +2236,29 @@ _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
{
if (*s == '&' || *s == '+' || *s == '-' || *s == '/')
mode = *s;
+ else if (whitespacep (s))
+ ;
else if (*s == '?')
; /* Only used via lookahead. */
else
{
- l1 = _gcry_sexp_find_token (sexp, s, 1);
+ if (*s == '\'')
+ {
+ /* Find closing quote, find token, set S to closing quote. */
+ s++;
+ s2 = strchr (s, '\'');
+ if (!s2 || s2 == s)
+ {
+ /* Closing quote not found or empty string. */
+ rc = GPG_ERR_SYNTAX;
+ goto cleanup;
+ }
+ l1 = _gcry_sexp_find_token (sexp, s, s2 - s);
+ s = s2;
+ }
+ else
+ l1 = _gcry_sexp_find_token (sexp, s, 1);
+
if (!l1 && s[1] == '?')
{
/* Optional element not found. */
diff --git a/tests/tsexp.c b/tests/tsexp.c
index afa79ff..2f6ad8f 100644
--- a/tests/tsexp.c
+++ b/tests/tsexp.c
@@ -684,6 +684,18 @@ check_extract_param (void)
{
sample1,
NULL,
+ "pab'gnq", 7,
+ GPG_ERR_SYNTAX
+ },
+ {
+ sample1,
+ NULL,
+ "pab''gnq", 7,
+ GPG_ERR_SYNTAX
+ },
+ {
+ sample1,
+ NULL,
"pabgnqd", 7,
0,
sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
@@ -692,6 +704,14 @@ check_extract_param (void)
{
sample1,
NULL,
+ " pab\tg nq\nd ", 7,
+ 0,
+ sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
+ sample1_qx, sample1_d
+ },
+ {
+ sample1,
+ NULL,
"abg", 3,
0,
sample1_ax, sample1_bx, sample1_gx
@@ -699,6 +719,13 @@ check_extract_param (void)
{
sample1,
NULL,
+ "ab'g'", 3,
+ 0,
+ sample1_ax, sample1_bx, sample1_gx
+ },
+ {
+ sample1,
+ NULL,
"x?abg", 4,
0,
NULL, sample1_ax, sample1_bx, sample1_gx
@@ -967,6 +994,50 @@ check_extract_param (void)
}
gcry_sexp_release (sxp);
+
+ info ("checking gcry_sexp_extract_param long name\n");
+
+ memset (ioarray, 0, sizeof ioarray);
+ memset (mpis, 0, sizeof mpis);
+
+ err = gcry_sexp_new (&sxp, sample1, 0, 1);
+ if (err)
+ die ("converting string to sexp failed: %s", gpg_strerror (err));
+
+ err = gcry_sexp_extract_param (sxp, "key-data!private-key",
+ "&'curve'+p",
+ ioarray+0, mpis+0, NULL);
+ if (err)
+ fail ("gcry_sexp_extract_param long name failed: %s", gpg_strerror (err));
+
+ if (!ioarray[0].data)
+ fail ("gcry_sexp_extract_param long name failed: no curve");
+ else if (ioarray[0].size != 7)
+ fail ("gcry_sexp_extract_param long name failed: curve has wrong size");
+ else if (ioarray[0].len != 7)
+ fail ("gcry_sexp_extract_param long name failed: curve has wrong length");
+ else if (ioarray[0].off)
+ fail ("gcry_sexp_extract_param long name failed: curve has OFF set");
+ else if (strncmp (ioarray[0].data, "Ed25519", 7))
+ {
+ fail ("gcry_sexp_extract_param long name failed: curve mismatch");
+ gcry_log_debug ("expected: %s\n", "Ed25519");
+ gcry_log_debug (" got: %.*s\n", (int)ioarray[0].len, ioarray[0].data);
+ }
+
+ if (!mpis[0])
+ fail ("gcry_sexp_extract_param long name failed: p not returned");
+ else if (cmp_mpihex (mpis[0], sample1_p))
+ {
+ fail ("gcry_sexp_extract_param long name failed: p mismatch");
+ gcry_log_debug ("expected: %s\n", sample1_p);
+ gcry_log_debugmpi (" got", mpis[0]);
+ }
+
+ gcry_mpi_release (mpis[0]);
+
+ gcry_sexp_release (sxp);
+
}
commit 405021cb6d4e470337302c65dec5bc91491a89c1
Author: Werner Koch <wk at gnupg.org>
Date: Tue Oct 22 14:26:53 2013 +0200
ecc: Merge partly duplicated code.
* cipher/ecc-eddsa.c (_gcry_ecc_eddsa_sign): Factor A hashing out to ...
(_gcry_ecc_eddsa_compute_h_d): new function.
* cipher/ecc-misc.c (_gcry_ecc_compute_public): Use new function.
(reverse_buffer): Remove.
Signed-off-by: Werner Koch <wk at gnupg.org>
diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h
index dc4a9d0..c407c74 100644
--- a/cipher/ecc-common.h
+++ b/cipher/ecc-common.h
@@ -115,6 +115,8 @@ gpg_err_code_t _gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx,
mpi_point_t result,
unsigned char **r_encpk,
unsigned int *r_encpklen);
+gpg_err_code_t _gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest,
+ gcry_mpi_t d, mpi_ec_t ec);
gpg_err_code_t _gcry_ecc_eddsa_genkey (ECC_secret_key *sk,
elliptic_curve_t *E,
diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c
index 12cdea0..17c1f73 100644
--- a/cipher/ecc-eddsa.c
+++ b/cipher/ecc-eddsa.c
@@ -368,6 +368,71 @@ _gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result,
}
+/* Compute the A value as used by EdDSA. The caller needs to provide
+ the context EC and the actual secret D as an MPI. The function
+ returns a newly allocated 64 byte buffer at r_digest; the first 32
+ bytes represent the A value. NULL is returned on error and NULL
+ stored at R_DIGEST. */
+gpg_err_code_t
+_gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest,
+ gcry_mpi_t d, mpi_ec_t ec)
+{
+ gpg_err_code_t rc;
+ unsigned char *rawmpi = NULL;
+ unsigned int rawmpilen;
+ unsigned char *digest;
+ gcry_buffer_t hvec[2];
+ int hashalgo, b;
+
+ *r_digest = NULL;
+
+ hashalgo = GCRY_MD_SHA512;
+ if (hashalgo != GCRY_MD_SHA512)
+ return GPG_ERR_DIGEST_ALGO;
+
+ b = (ec->nbits+7)/8;
+ if (b != 256/8)
+ return GPG_ERR_INTERNAL; /* We only support 256 bit. */
+
+ /* Note that we clear DIGEST so we can use it as input to left pad
+ the key with zeroes for hashing. */
+ digest = gcry_calloc_secure (2, b);
+ if (!digest)
+ return gpg_err_code_from_syserror ();
+
+ memset (hvec, 0, sizeof hvec);
+
+ rawmpi = _gcry_mpi_get_buffer (d, 0, &rawmpilen, NULL);
+ if (!rawmpi)
+ {
+ gcry_free (digest);
+ return gpg_err_code_from_syserror ();
+ }
+
+ hvec[0].data = digest;
+ hvec[0].off = 0;
+ hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
+ hvec[1].data = rawmpi;
+ hvec[1].off = 0;
+ hvec[1].len = rawmpilen;
+ rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
+ gcry_free (rawmpi);
+ if (rc)
+ {
+ gcry_free (digest);
+ return rc;
+ }
+
+ /* Compute the A value. */
+ reverse_buffer (digest, 32); /* Only the first half of the hash. */
+ digest[0] = (digest[0] & 0x7f) | 0x40;
+ digest[31] &= 0xf8;
+
+ *r_digest = digest;
+ return 0;
+}
+
+
/* Ed25519 version of the key generation. */
gpg_err_code_t
_gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
@@ -480,8 +545,6 @@ _gcry_ecc_eddsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
if (!mpi_is_opaque (input))
return GPG_ERR_INV_DATA;
- if (hashalgo != GCRY_MD_SHA512)
- return GPG_ERR_DIGEST_ALGO;
/* Initialize some helpers. */
point_init (&I);
@@ -496,36 +559,9 @@ _gcry_ecc_eddsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
if (b != 256/8)
return GPG_ERR_INTERNAL; /* We only support 256 bit. */
- digest = gcry_calloc_secure (2, b);
- if (!digest)
- {
- rc = gpg_err_code_from_syserror ();
- goto leave;
- }
-
- /* Hash the secret key. We clear DIGEST so we can use it as input
- to left pad the key with zeroes for hashing. */
- rawmpi = _gcry_mpi_get_buffer (skey->d, 0, &rawmpilen, NULL);
- if (!rawmpi)
- {
- rc = gpg_err_code_from_syserror ();
- goto leave;
- }
- hvec[0].data = digest;
- hvec[0].off = 0;
- hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
- hvec[1].data = rawmpi;
- hvec[1].off = 0;
- hvec[1].len = rawmpilen;
- rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
- gcry_free (rawmpi); rawmpi = NULL;
+ rc = _gcry_ecc_eddsa_compute_h_d (&digest, skey->d, ctx);
if (rc)
goto leave;
-
- /* Compute the A value (this modifies DIGEST). */
- reverse_buffer (digest, 32); /* Only the first half of the hash. */
- digest[0] = (digest[0] & 0x7f) | 0x40;
- digest[31] &= 0xf8;
_gcry_mpi_set_buffer (a, digest, 32, 0);
/* Compute the public key if it has not been supplied as optional
diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c
index 26c9e8d..ae3e4f0 100644
--- a/cipher/ecc-misc.c
+++ b/cipher/ecc-misc.c
@@ -236,20 +236,6 @@ _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value)
}
-static void
-reverse_buffer (unsigned char *buffer, unsigned int length)
-{
- unsigned int tmp, i;
-
- for (i=0; i < length/2; i++)
- {
- tmp = buffer[i];
- buffer[i] = buffer[length-1-i];
- buffer[length-1-i] = tmp;
- }
-}
-
-
/* Compute the public key from the the context EC. Obviously a
requirement is that the secret key is available in EC. On success
Q is returned; on error NULL. If Q is NULL a newly allocated point
@@ -259,8 +245,6 @@ mpi_point_t
_gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec,
mpi_point_t G, gcry_mpi_t d)
{
- int rc;
-
if (!G)
G = ec->G;
if (!d)
@@ -275,41 +259,11 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec,
&& (ec->flags & PUBKEY_FLAG_EDDSA))
{
gcry_mpi_t a;
- unsigned char *rawmpi = NULL;
- unsigned int rawmpilen;
unsigned char *digest;
- gcry_buffer_t hvec[2];
- int b = (ec->nbits+7)/8;
-
- gcry_assert (b >= 32);
- digest = gcry_calloc_secure (2, b);
- if (!digest)
- return NULL;
- memset (hvec, 0, sizeof hvec);
- rawmpi = _gcry_mpi_get_buffer (d, 0, &rawmpilen, NULL);
- if (!rawmpi)
+ if (_gcry_ecc_eddsa_compute_h_d (&digest, d, ec))
return NULL;
- memset (digest, 0, b);
- hvec[0].data = digest;
- hvec[0].off = 0;
- hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
- hvec[1].data = rawmpi;
- hvec[1].off = 0;
- hvec[1].len = rawmpilen;
- /* FIXME: Put and take the hash algo from the context. */
- rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, digest, hvec, 2);
- gcry_free (rawmpi);
- if (rc)
- {
- gcry_free (digest);
- return NULL;
- }
- /* Compute the A value. */
- reverse_buffer (digest, 32); /* Only the first half of the hash. */
- digest[0] = (digest[0] & 0x7f) | 0x40;
- digest[31] &= 0xf8;
a = mpi_snew (0);
_gcry_mpi_set_buffer (a, digest, 32, 0);
gcry_free (digest);
commit 4cf2c65fe15173c8d68a141a01b34fc1fb9080b7
Author: Werner Koch <wk at gnupg.org>
Date: Tue Oct 22 14:26:53 2013 +0200
ecc: Remove unused internal function.
* src/cipher-proto.h (gcry_pk_spec): Remove get_param.
* cipher/ecc-curves.c (_gcry_ecc_get_param_sexp): Merge in code from
_gcry_ecc_get_param.
(_gcry_ecc_get_param): Remove.
* cipher/ecc.c (_gcry_pubkey_spec_ecc): Remove _gcry_ecc_get_param.
Signed-off-by: Werner Koch <wk at gnupg.org>
diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h
index 1ee1d39..dc4a9d0 100644
--- a/cipher/ecc-common.h
+++ b/cipher/ecc-common.h
@@ -80,8 +80,7 @@ gpg_err_code_t _gcry_ecc_update_curve_param (const char *name,
const char *_gcry_ecc_get_curve (gcry_sexp_t keyparms,
int iterator,
unsigned int *r_nbits);
-gcry_err_code_t _gcry_ecc_get_param (const char *name, gcry_mpi_t *pkey);
-gcry_sexp_t _gcry_ecc_get_param_sexp (const char *name);
+gcry_sexp_t _gcry_ecc_get_param_sexp (const char *name);
/*-- ecc-misc.c --*/
void _gcry_ecc_curve_free (elliptic_curve_t *E);
diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
index 8125f24..85ebdd3 100644
--- a/cipher/ecc-curves.c
+++ b/cipher/ecc-curves.c
@@ -926,20 +926,21 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
}
-/* Return the parameters of the curve NAME in an MPI array. */
-gcry_err_code_t
-_gcry_ecc_get_param (const char *name, gcry_mpi_t *pkey)
+/* Return the parameters of the curve NAME as an S-expression. */
+gcry_sexp_t
+_gcry_ecc_get_param_sexp (const char *name)
{
- gpg_err_code_t err;
unsigned int nbits;
elliptic_curve_t E;
mpi_ec_t ctx;
gcry_mpi_t g_x, g_y;
+ gcry_mpi_t pkey[6];
+ gcry_sexp_t result;
+ int i;
memset (&E, 0, sizeof E);
- err = _gcry_ecc_fill_in_curve (0, name, &E, &nbits);
- if (err)
- return err;
+ if (_gcry_ecc_fill_in_curve (0, name, &E, &nbits))
+ return NULL;
g_x = mpi_new (0);
g_y = mpi_new (0);
@@ -962,21 +963,6 @@ _gcry_ecc_get_param (const char *name, gcry_mpi_t *pkey)
mpi_free (g_x);
mpi_free (g_y);
- return 0;
-}
-
-
-/* Return the parameters of the curve NAME as an S-expression. */
-gcry_sexp_t
-_gcry_ecc_get_param_sexp (const char *name)
-{
- gcry_mpi_t pkey[6];
- gcry_sexp_t result;
- int i;
-
- if (_gcry_ecc_get_param (name, pkey))
- return NULL;
-
if (sexp_build (&result, NULL,
"(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))",
pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]))
diff --git a/cipher/ecc.c b/cipher/ecc.c
index a7de254..e3c49ce 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -1755,7 +1755,6 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecc =
ecc_get_nbits,
run_selftests,
compute_keygrip,
- _gcry_ecc_get_param,
_gcry_ecc_get_curve,
_gcry_ecc_get_param_sexp
};
diff --git a/src/cipher-proto.h b/src/cipher-proto.h
index 11c2862..0955ef5 100644
--- a/src/cipher-proto.h
+++ b/src/cipher-proto.h
@@ -84,10 +84,6 @@ typedef unsigned (*gcry_pk_get_nbits_t) (gcry_sexp_t keyparms);
typedef gpg_err_code_t (*pk_comp_keygrip_t) (gcry_md_hd_t md,
gcry_sexp_t keyparm);
-/* The type used to query ECC curve parameters. */
-typedef gcry_err_code_t (*pk_get_param_t) (const char *name,
- gcry_mpi_t *pkey);
-
/* The type used to query an ECC curve name. */
typedef const char *(*pk_get_curve_t)(gcry_sexp_t keyparms, int iterator,
unsigned int *r_nbits);
@@ -121,7 +117,6 @@ typedef struct gcry_pk_spec
gcry_pk_get_nbits_t get_nbits;
selftest_func_t selftest;
pk_comp_keygrip_t comp_keygrip;
- pk_get_param_t get_param;
pk_get_curve_t get_curve;
pk_get_curve_param_t get_curve_param;
} gcry_pk_spec_t;
-----------------------------------------------------------------------
Summary of changes:
cipher/ecc-common.h | 5 +--
cipher/ecc-curves.c | 30 +++++-----------
cipher/ecc-eddsa.c | 96 +++++++++++++++++++++++++++++++++++----------------
cipher/ecc-misc.c | 48 +-------------------------
cipher/ecc.c | 1 -
doc/gcrypt.texi | 24 +++++++------
src/cipher-proto.h | 5 ---
src/sexp.c | 47 +++++++++++++++++++++----
tests/tsexp.c | 71 +++++++++++++++++++++++++++++++++++++
9 files changed, 203 insertions(+), 124 deletions(-)
hooks/post-receive
--
The GNU crypto library
http://git.gnupg.org
_______________________________________________
Gnupg-commits mailing list
Gnupg-commits at gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-commits
More information about the Gcrypt-devel
mailing list