diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/audit.c | 1 | ||||
-rw-r--r-- | common/ksba-io-support.c | 107 | ||||
-rw-r--r-- | common/ksba-io-support.h | 1 | ||||
-rw-r--r-- | common/openpgp-oid.c | 26 | ||||
-rw-r--r-- | common/recsel.c | 3 | ||||
-rw-r--r-- | common/sexputil.c | 5 | ||||
-rw-r--r-- | common/status.c | 3 | ||||
-rw-r--r-- | common/tlv.c | 3 |
8 files changed, 137 insertions, 12 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/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/openpgp-oid.c b/common/openpgp-oid.c index f0460b068..510e09f4a 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)))); } 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/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; |