summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2023-03-08 15:54:54 +0100
committerWerner Koch <wk@gnupg.org>2023-03-08 15:54:54 +0100
commitc1f6535f144dedfbf5507f850d4da5b61fd5ec74 (patch)
treecf70afb5db40891c2d7c94b4f087f80e7fc57ac4
parent76351c4877d60799a35afccd87037d5dd0871262 (diff)
downloadgpgme-c1f6535f144dedfbf5507f850d4da5b61fd5ec74.tar.gz
core: Also detect legacy X.509 v0 certificates.
* src/data-identify.c (basic_detection): Loose the detection of X.509 certs.
-rw-r--r--src/data-identify.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/src/data-identify.c b/src/data-identify.c
index 8e0295e7..6d2500d9 100644
--- a/src/data-identify.c
+++ b/src/data-identify.c
@@ -336,8 +336,10 @@ basic_detection (char *data, size_t datalen)
SEQUENCE SEQUENCE [0] INTEGER INTEGER SEQU
(tbs) (version) (s/n) (Algo)
- Thus we need to read at least 22 bytes, we add 2 bytes to cope with
- length headers stored with 4 bytes.
+ Thus we need to read at least 22 bytes, we add 2 bytes to cope
+ with length headers stored with 4 bytes. For a v0 certificate the
+ tag and the bersion are missin (they are implicit) - detect this
+ too as a cert becuase some root CA use this.
*/
@@ -357,24 +359,34 @@ basic_detection (char *data, size_t datalen)
{
if (parse_tlv (&s, &n, &ti))
goto try_pgp;
- if (!(ti.cls == ASN1_CLASS_CONTEXT && ti.tag == 0
- && ti.is_cons && ti.length == 3 && n >= ti.length))
- goto try_pgp;
+ if (ti.cls == ASN1_CLASS_CONTEXT && ti.tag == 0
+ && ti.is_cons && ti.length == 3 && n >= ti.length)
+ {
+ if (parse_tlv (&s, &n, &ti))
+ goto try_pgp;
+ if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
+ && !ti.is_cons && ti.length == 1 && n && (*s == 1 || *s == 2)))
+ goto try_pgp;
+ s++;
+ n--;
+ if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
+ && !ti.is_cons))
+ goto try_pgp;
+ /* Because the now following S/N may be larger than the sample
+ data we have, we stop parsing here and don't check for the
+ algorithm ID. */
+ return GPGME_DATA_TYPE_X509_CERT; /* regular cert. */
+ }
+ if (ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
+ && !ti.is_cons)
+ {
+ /* Because this S/N may be larger than the sample data we
+ have, we can't check that a SEQUENCE follows. */
+ return GPGME_DATA_TYPE_X509_CERT; /* v0 cert with implict tag. */
+ }
+
+ goto try_pgp;
- if (parse_tlv (&s, &n, &ti))
- goto try_pgp;
- if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
- && !ti.is_cons && ti.length == 1 && n && (*s == 1 || *s == 2)))
- goto try_pgp;
- s++;
- n--;
- if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
- && !ti.is_cons))
- goto try_pgp;
- /* Because the now following S/N may be larger than the sample
- data we have, we stop parsing here and don't check for the
- algorithm ID. */
- return GPGME_DATA_TYPE_X509_CERT;
}
if (ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
&& !ti.is_cons && ti.length == 1 && n && *s == 3)