aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/audit.c1
-rw-r--r--common/comopt.c2
-rw-r--r--common/comopt.h8
-rw-r--r--common/homedir.c38
-rw-r--r--common/ksba-io-support.c107
-rw-r--r--common/ksba-io-support.h1
-rw-r--r--common/name-value.c14
-rw-r--r--common/name-value.h3
-rw-r--r--common/openpgp-oid.c47
-rw-r--r--common/recsel.c3
-rw-r--r--common/sexputil.c5
-rw-r--r--common/status.c3
-rw-r--r--common/status.h1
-rw-r--r--common/tlv.c3
14 files changed, 204 insertions, 32 deletions
diff --git a/common/audit.c b/common/audit.c
index 803523c94..ae0d45216 100644
--- a/common/audit.c
+++ b/common/audit.c
@@ -1109,6 +1109,7 @@ proc_type_verify (audit_ctx_t ctx)
case GPG_ERR_CERT_REVOKED: ok = "bad"; break;
case GPG_ERR_NOT_ENABLED: ok = "disabled"; break;
case GPG_ERR_NO_CRL_KNOWN:
+ case GPG_ERR_INV_CRL_OBJ:
ok = _("no CRL found for certificate");
break;
case GPG_ERR_CRL_TOO_OLD:
diff --git a/common/comopt.c b/common/comopt.c
index 470cdac61..1cfd581b1 100644
--- a/common/comopt.c
+++ b/common/comopt.c
@@ -60,6 +60,8 @@ static gpgrt_opt_t opts[] = {
};
+struct gnupg_comopt_s comopt = {NULL};
+
/* Parse the common options in the homedir and etc. This needs to be
* called after the gpgrt config directories are set. MODULE_ID is one of
diff --git a/common/comopt.h b/common/comopt.h
index 7947f35b3..9236afc6b 100644
--- a/common/comopt.h
+++ b/common/comopt.h
@@ -35,14 +35,16 @@
/* Common options for all GnuPG components. */
-EXTERN_UNLESS_MAIN_MODULE
-struct
+struct gnupg_comopt_s
{
char *logfile; /* Socket used by daemons for logging. */
int use_keyboxd; /* Use the keyboxd as storage backend. */
int no_autostart; /* Do not start gpg-agent. */
char *keyboxd_program; /* Use this as keyboxd program. */
-} comopt;
+};
+
+
+extern struct gnupg_comopt_s comopt;
gpg_error_t parse_comopt (int module_id, int verbose);
diff --git a/common/homedir.c b/common/homedir.c
index 67bbde8f1..091964fc1 100644
--- a/common/homedir.c
+++ b/common/homedir.c
@@ -789,8 +789,42 @@ gnupg_maybe_make_homedir (const char *fname, int quiet)
if (gnupg_mkdir (fname, "-rwx"))
log_fatal ( _("can't create directory '%s': %s\n"),
fname, strerror(errno) );
- else if (!quiet )
- log_info ( _("directory '%s' created\n"), fname );
+ else
+ {
+ estream_t fp;
+ char *fcommon;
+
+ if (!quiet )
+ log_info ( _("directory '%s' created\n"), fname );
+
+#ifdef BUILD_WITH_KEYBOXD
+ /* A new default homedir has been created. Now create a
+ * common.conf. */
+ fcommon = make_filename (fname, "common.conf", NULL);
+ fp = es_fopen (fcommon, "wx,mode=-rw-r");
+ if (!fp)
+ {
+ log_info (_("error creating '%s': %s\n"), fcommon,
+ gpg_strerror (gpg_error_from_syserror ()));
+ }
+ else
+ {
+ if (es_fputs ("use-keyboxd\n", fp) == EOF)
+ {
+ log_info (_("error writing to '%s': %s\n"), fcommon,
+ gpg_strerror (es_ferror (fp)
+ ? gpg_error_from_syserror ()
+ : gpg_error (GPG_ERR_EOF)));
+ es_fclose (fp);
+ }
+ else if (es_fclose (fp))
+ {
+ log_info (_("error closing '%s': %s\n"), fcommon,
+ gpg_strerror (gpg_error_from_syserror ()));
+ }
+ }
+#endif /* BUILD_WITH_KEYBOXD */
+ }
}
}
diff --git a/common/ksba-io-support.c b/common/ksba-io-support.c
index 2832a4f3d..a279b67ad 100644
--- a/common/ksba-io-support.c
+++ b/common/ksba-io-support.c
@@ -40,6 +40,7 @@
#include "util.h"
#include "i18n.h"
+#include "tlv.h"
#include "ksba-io-support.h"
@@ -65,6 +66,12 @@ struct reader_cb_parm_s
int autodetect; /* Try to detect the input encoding. */
int assume_pem; /* Assume input encoding is PEM. */
int assume_base64; /* Assume input is base64 encoded. */
+ int strip_zeroes; /* Expect a SEQUENCE followed by zero padding. */
+ /* 1 = check state; 2 = reading; 3 = checking */
+ /* for zeroes. */
+ int use_maxread; /* If true read not more than MAXREAD. */
+ unsigned int maxread; /* # of bytes left to read. */
+ off_t nzeroes; /* Number of padding zeroes red. */
int identified;
int is_pem;
@@ -390,6 +397,55 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
}
+/* Read up to 10 bytes to test whether the data consist of a sequence;
+ * if that is true, set the limited flag and record the length of the
+ * entire sequence in PARM. Unget everything then. Return true if we
+ * have a sequence with a fixed length. */
+static int
+starts_with_sequence (struct reader_cb_parm_s *parm)
+{
+ gpg_error_t err;
+ unsigned char peekbuf[10];
+ int npeeked, c;
+ int found = 0;
+ const unsigned char *p;
+ size_t n, objlen, hdrlen;
+ int class, tag, constructed, ndef;
+
+ for (npeeked=0; npeeked < sizeof peekbuf; npeeked++)
+ {
+ c = es_getc (parm->fp);
+ if (c == EOF)
+ goto leave;
+ peekbuf[npeeked] = c;
+ }
+ /* Enough to check for a sequence. */
+
+ p = peekbuf;
+ n = npeeked;
+ err = parse_ber_header (&p, &n, &class, &tag, &constructed,
+ &ndef, &objlen, &hdrlen);
+ if (err)
+ {
+ log_debug ("%s: error parsing data: %s\n", __func__, gpg_strerror (err));
+ goto leave;
+ }
+
+ if (class == CLASS_UNIVERSAL && constructed && tag == TAG_SEQUENCE && !ndef)
+ {
+ /* We need to add 1 due to the way we implement the limit. */
+ parm->maxread = objlen + hdrlen + 1;
+ if (!(parm->maxread < objlen + hdrlen) && parm->maxread)
+ parm->use_maxread = 1;
+ found = 1;
+ }
+
+ leave:
+ while (npeeked)
+ es_ungetc (peekbuf[--npeeked], parm->fp);
+ return found;
+}
+
static int
simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
@@ -402,9 +458,55 @@ simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
if (!buffer)
return -1; /* not supported */
+ restart:
+ if (parm->strip_zeroes)
+ {
+ if (parm->strip_zeroes == 1)
+ {
+ if (starts_with_sequence (parm))
+ parm->strip_zeroes = 2; /* Found fixed length sequence. */
+ else
+ parm->strip_zeroes = 0; /* Disable zero padding check. */
+ }
+ else if (parm->strip_zeroes == 3)
+ {
+ /* Limit reached - check that only zeroes follow. */
+ while (!(c = es_getc (parm->fp)))
+ parm->nzeroes++;
+ if (c == EOF)
+ { /* only zeroes found. Reset zero padding engine and
+ * return EOF. */
+ parm->strip_zeroes = 0;
+ parm->eof_seen = 1;
+ return -1;
+ }
+ /* Not only zeroes. Reset engine and continue. */
+ parm->strip_zeroes = 0;
+ }
+ }
+
for (n=0; n < count; n++)
{
- c = es_getc (parm->fp);
+ if (parm->use_maxread && !--parm->maxread)
+ {
+ parm->use_maxread = 0;
+ if (parm->strip_zeroes)
+ {
+ parm->strip_zeroes = 3;
+ parm->nzeroes = 0;
+ if (n)
+ goto leave; /* Return what we already got. */
+ goto restart; /* Immediately check for trailing zeroes. */
+ }
+ }
+
+ if (parm->nzeroes)
+ {
+ parm->nzeroes--;
+ c = 0;
+ }
+ else
+ c = es_getc (parm->fp);
if (c == EOF)
{
parm->eof_seen = 1;
@@ -417,6 +519,7 @@ simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
*(byte *)buffer++ = c;
}
+ leave:
*nread = n;
return 0;
}
@@ -575,6 +678,7 @@ base64_finish_write (struct writer_cb_parm_s *parm)
* GNUPG_KSBA_IO_MULTIPEM - The reader expects that the caller uses
* ksba_reader_clear after EOF until no more
* objects were found.
+ * GNUPG_KSBA_IO_STRIP - Strip zero padding from some CMS objects.
*
* Note that the PEM flag has a higher priority than the BASE64 flag
* which in turn has a gight priority than the AUTODETECT flag.
@@ -592,6 +696,7 @@ gnupg_ksba_create_reader (gnupg_ksba_io_t *ctx,
if (!*ctx)
return out_of_core ();
(*ctx)->u.rparm.allow_multi_pem = !!(flags & GNUPG_KSBA_IO_MULTIPEM);
+ (*ctx)->u.rparm.strip_zeroes = !!(flags & GNUPG_KSBA_IO_STRIP);
rc = ksba_reader_new (&r);
if (rc)
diff --git a/common/ksba-io-support.h b/common/ksba-io-support.h
index e33e0ed74..02e541b16 100644
--- a/common/ksba-io-support.h
+++ b/common/ksba-io-support.h
@@ -36,6 +36,7 @@
#define GNUPG_KSBA_IO_BASE64 2 /* Plain Base64 format. */
#define GNUPG_KSBA_IO_AUTODETECT 4 /* Try to autodetect the format. */
#define GNUPG_KSBA_IO_MULTIPEM 8 /* Allow more than one PEM chunk. */
+#define GNUPG_KSBA_IO_STRIP 16 /* Strip off zero padding. */
/* Context object. */
diff --git a/common/name-value.c b/common/name-value.c
index d1d0a3f6f..67429e47f 100644
--- a/common/name-value.c
+++ b/common/name-value.c
@@ -608,13 +608,14 @@ nvc_get_string (nvc_t nvc, const char *name)
}
-/* Return true if NAME exists and its value is true; that is either
- * "yes", "true", or a decimal value unequal to 0. */
+/* Return true (ie. a non-zero value) if NAME exists and its value is
+ * true; that is either "yes", "true", or a decimal value unequal to 0. */
int
nvc_get_boolean (nvc_t nvc, const char *name)
{
nve_t item;
const char *s;
+ int n;
if (!nvc)
return 0;
@@ -622,9 +623,12 @@ nvc_get_boolean (nvc_t nvc, const char *name)
if (!item)
return 0;
s = nve_value (item);
- if (s && (atoi (s)
- || !ascii_strcasecmp (s, "yes")
- || !ascii_strcasecmp (s, "true")))
+ if (!s)
+ return 0;
+ n = atoi (s);
+ if (n)
+ return n;
+ if (!ascii_strcasecmp (s, "yes") || !ascii_strcasecmp (s, "true"))
return 1;
return 0;
}
diff --git a/common/name-value.h b/common/name-value.h
index cf854e04d..504b5d0f0 100644
--- a/common/name-value.h
+++ b/common/name-value.h
@@ -75,7 +75,8 @@ nve_t nve_next_value (nve_t entry, const char *name);
/* Return the string for the first entry in NVC with NAME or NULL. */
const char *nvc_get_string (nvc_t nvc, const char *name);
-/* Return a boolean value for the first entry in NVC with NAME. */
+/* Return a boolean value (zero or non-zero) for the first entry in
+ * NVC with NAME. */
int nvc_get_boolean (nvc_t nvc, const char *name);
diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c
index f0460b068..493054950 100644
--- a/common/openpgp-oid.c
+++ b/common/openpgp-oid.c
@@ -48,6 +48,8 @@ static struct {
{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519", PUBKEY_ALGO_ECDH },
{ "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519", PUBKEY_ALGO_EDDSA },
+ { "Curve25519", "1.3.101.110", 255, "cv25519", PUBKEY_ALGO_ECDH },
+ { "Ed25519", "1.3.101.112", 255, "ed25519", PUBKEY_ALGO_EDDSA },
{ "X448", "1.3.101.111", 448, "cv448", PUBKEY_ALGO_ECDH },
{ "Ed448", "1.3.101.113", 456, "ed448", PUBKEY_ALGO_EDDSA },
@@ -65,13 +67,17 @@ static struct {
};
-/* The OID for Curve Ed25519 in OpenPGP format. */
+/* The OID for Curve Ed25519 in OpenPGP format. The shorter v5
+ * variant may only be used with v5 keys. */
static const char oid_ed25519[] =
{ 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01 };
+static const char oid_ed25519_v5[] = { 0x03, 0x2b, 0x65, 0x70 };
-/* The OID for Curve25519 in OpenPGP format. */
+/* The OID for Curve25519 in OpenPGP format. The shorter v5
+ * variant may only be used with v5 keys. */
static const char oid_cv25519[] =
{ 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 };
+static const char oid_cv25519_v5[] = { 0x03, 0x2b, 0x65, 0x6e };
/* The OID for X448 in OpenPGP format. */
/*
@@ -321,8 +327,12 @@ openpgp_oid_to_str (gcry_mpi_t a)
int
openpgp_oidbuf_is_ed25519 (const void *buf, size_t len)
{
- return (buf && len == DIM (oid_ed25519)
- && !memcmp (buf, oid_ed25519, DIM (oid_ed25519)));
+ if (!buf)
+ return 0;
+ return ((len == DIM (oid_ed25519)
+ && !memcmp (buf, oid_ed25519, DIM (oid_ed25519)))
+ || (len == DIM (oid_ed25519_v5)
+ && !memcmp (buf, oid_ed25519_v5, DIM (oid_ed25519_v5))));
}
@@ -345,8 +355,12 @@ openpgp_oid_is_ed25519 (gcry_mpi_t a)
int
openpgp_oidbuf_is_cv25519 (const void *buf, size_t len)
{
- return (buf && len == DIM (oid_cv25519)
- && !memcmp (buf, oid_cv25519, DIM (oid_cv25519)));
+ if (!buf)
+ return 0;
+ return ((len == DIM (oid_cv25519)
+ && !memcmp (buf, oid_cv25519, DIM (oid_cv25519)))
+ || (len == DIM (oid_cv25519_v5)
+ && !memcmp (buf, oid_cv25519_v5, DIM (oid_cv25519_v5))));
}
@@ -430,8 +444,9 @@ openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo)
if (name)
{
for (i=0; oidtable[i].name; i++)
- if (!strcmp (oidtable[i].name, name)
- || (oidtable[i].alias && !strcmp (oidtable[i].alias, name)))
+ if (!ascii_strcasecmp (oidtable[i].name, name)
+ || (oidtable[i].alias
+ && !ascii_strcasecmp (oidtable[i].alias, name)))
{
oidstr = oidtable[i].oidstr;
nbits = oidtable[i].nbits;
@@ -443,7 +458,7 @@ openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo)
/* If not found assume the input is already an OID and check
whether we support it. */
for (i=0; oidtable[i].name; i++)
- if (!strcmp (name, oidtable[i].oidstr))
+ if (!ascii_strcasecmp (name, oidtable[i].oidstr))
{
oidstr = oidtable[i].oidstr;
nbits = oidtable[i].nbits;
@@ -492,9 +507,10 @@ openpgp_oid_or_name_to_curve (const char *oidname, int canon)
return NULL;
for (i=0; oidtable[i].name; i++)
- if (!strcmp (oidtable[i].oidstr, oidname)
- || !strcmp (oidtable[i].name, oidname)
- || (oidtable[i].alias &&!strcmp (oidtable[i].alias, oidname)))
+ if (!ascii_strcasecmp (oidtable[i].oidstr, oidname)
+ || !ascii_strcasecmp (oidtable[i].name, oidname)
+ || (oidtable[i].alias
+ && !ascii_strcasecmp (oidtable[i].alias, oidname)))
return !canon && oidtable[i].alias? oidtable[i].alias : oidtable[i].name;
return NULL;
@@ -556,8 +572,9 @@ openpgp_is_curve_supported (const char *name, int *r_algo,
*r_nbits = 0;
for (idx = 0; idx < DIM (oidtable) && oidtable[idx].name; idx++)
{
- if ((!strcmp (name, oidtable[idx].name)
- || (oidtable[idx].alias && !strcmp (name, (oidtable[idx].alias))))
+ if ((!ascii_strcasecmp (name, oidtable[idx].name)
+ || (oidtable[idx].alias
+ && !ascii_strcasecmp (name, (oidtable[idx].alias))))
&& curve_supported_p (oidtable[idx].name))
{
if (r_algo)
@@ -659,7 +676,7 @@ get_keyalgo_string (enum gcry_pk_algos algo,
{
if (keyalgo_strings[i].algo == algo
&& keyalgo_strings[i].curve && curve
- && !strcmp (keyalgo_strings[i].curve, curve))
+ && !ascii_strcasecmp (keyalgo_strings[i].curve, curve))
return keyalgo_strings[i].name;
}
diff --git a/common/recsel.c b/common/recsel.c
index 60da4d3c9..ea0858c84 100644
--- a/common/recsel.c
+++ b/common/recsel.c
@@ -174,6 +174,7 @@ find_next_lc (char *string)
* -c The string match in this part is done case-sensitive.
* -t Do not trim leading and trailing spaces from VALUE.
* Note that a space after <op> is here required.
+ * -r RFU: String match uses a regular expression
*
* For example four calls to recsel_parse_expr() with these values for
* EXPR
@@ -192,7 +193,7 @@ find_next_lc (char *string)
*
* The caller must pass the address of a selector variable to this
* function and initialize the value of the function to NULL before
- * the first call. recset_release needs to be called to free the
+ * the first call. recsel_release needs to be called to free the
* selector.
*/
gpg_error_t
diff --git a/common/sexputil.c b/common/sexputil.c
index b7ddea8fc..29fe508b6 100644
--- a/common/sexputil.c
+++ b/common/sexputil.c
@@ -536,7 +536,8 @@ get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
return err;
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
return err;
- if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
+ if (!tok || !((toklen == 10 && !memcmp ("public-key", tok, toklen))
+ || (toklen == 11 && !memcmp ("private-key", tok, toklen))))
return gpg_error (GPG_ERR_BAD_PUBKEY);
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
return err;
@@ -1075,6 +1076,8 @@ pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid)
l1 = gcry_sexp_find_token (s_pkey, "public-key", 0);
if (!l1)
+ l1 = gcry_sexp_find_token (s_pkey, "private-key", 0);
+ if (!l1)
return xtrystrdup ("E_no_key");
{
gcry_sexp_t l_tmp = gcry_sexp_cadr (l1);
diff --git a/common/status.c b/common/status.c
index b752c12c6..b7dc1de39 100644
--- a/common/status.c
+++ b/common/status.c
@@ -158,7 +158,8 @@ get_inv_recpsgnr_code (gpg_error_t err)
case GPG_ERR_WRONG_KEY_USAGE: errstr = "3"; break;
case GPG_ERR_CERT_REVOKED: errstr = "4"; break;
case GPG_ERR_CERT_EXPIRED: errstr = "5"; break;
- case GPG_ERR_NO_CRL_KNOWN: errstr = "6"; break;
+ case GPG_ERR_NO_CRL_KNOWN:
+ case GPG_ERR_INV_CRL_OBJ: errstr = "6"; break;
case GPG_ERR_CRL_TOO_OLD: errstr = "7"; break;
case GPG_ERR_NO_POLICY_MATCH: errstr = "8"; break;
diff --git a/common/status.h b/common/status.h
index 0c481d247..e4cf23ee1 100644
--- a/common/status.h
+++ b/common/status.h
@@ -53,6 +53,7 @@ enum
STATUS_NEED_PASSPHRASE,
STATUS_VALIDSIG,
+ STATUS_ASSERT_SIGNER,
STATUS_SIG_ID,
STATUS_ENC_TO,
STATUS_NODATA,
diff --git a/common/tlv.c b/common/tlv.c
index 9618d04cb..4cc1dc7cf 100644
--- a/common/tlv.c
+++ b/common/tlv.c
@@ -156,8 +156,7 @@ gpg_error_t
parse_ber_header (unsigned char const **buffer, size_t *size,
int *r_class, int *r_tag,
int *r_constructed, int *r_ndef,
- size_t *r_length, size_t *r_nhdr)
-{
+ size_t *r_length, size_t *r_nhdr){
int c;
unsigned long tag;
const unsigned char *buf = *buffer;