PKCS#7: Check content type and versions
authorDavid Howells <dhowells@redhat.com>
Mon, 20 Jul 2015 20:16:31 +0000 (21:16 +0100)
committerDavid Howells <dhowells@redhat.com>
Wed, 12 Aug 2015 16:01:00 +0000 (17:01 +0100)
We only support PKCS#7 signed-data [RFC2315 sec 9] content at the top level,
so reject anything else.  Further, check that the version numbers in
SignedData and SignerInfo are 1 in both cases.

Note that we don't restrict the inner content type.  In the PKCS#7 code we
don't parse the data attached there, but merely verify the signature over
it.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-By: David Woodhouse <David.Woodhouse@intel.com>
crypto/asymmetric_keys/pkcs7.asn1
crypto/asymmetric_keys/pkcs7_parser.c

index a5a14ef..0550443 100644 (file)
@@ -1,12 +1,12 @@
 PKCS7ContentInfo ::= SEQUENCE {
-       contentType     ContentType,
+       contentType     ContentType ({ pkcs7_check_content_type }),
        content         [0] EXPLICIT SignedData OPTIONAL
 }
 
 ContentType ::= OBJECT IDENTIFIER ({ pkcs7_note_OID })
 
 SignedData ::= SEQUENCE {
-       version                 INTEGER,
+       version                 INTEGER ({ pkcs7_note_signeddata_version }),
        digestAlgorithms        DigestAlgorithmIdentifiers,
        contentInfo             ContentInfo,
        certificates            CHOICE {
@@ -68,7 +68,7 @@ SignerInfos ::= CHOICE {
 }
 
 SignerInfo ::= SEQUENCE {
-       version                 INTEGER,
+       version                 INTEGER ({ pkcs7_note_signerinfo_version }),
        issuerAndSerialNumber   IssuerAndSerialNumber,
        digestAlgorithm         DigestAlgorithmIdentifier ({ pkcs7_sig_note_digest_algo }),
        authenticatedAttributes CHOICE {
index 3bd5a1e..ab427f0 100644 (file)
@@ -225,6 +225,79 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
        return 0;
 }
 
+/*
+ * We only support signed data [RFC2315 sec 9].
+ */
+int pkcs7_check_content_type(void *context, size_t hdrlen,
+                            unsigned char tag,
+                            const void *value, size_t vlen)
+{
+       struct pkcs7_parse_context *ctx = context;
+
+       if (ctx->last_oid != OID_signed_data) {
+               pr_warn("Only support pkcs7_signedData type\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * Note the SignedData version
+ */
+int pkcs7_note_signeddata_version(void *context, size_t hdrlen,
+                                 unsigned char tag,
+                                 const void *value, size_t vlen)
+{
+       unsigned version;
+
+       if (vlen != 1)
+               goto unsupported;
+
+       version = *(const u8 *)value;
+       switch (version) {
+       case 1:
+               /* PKCS#7 SignedData [RFC2315 sec 9.1] */
+               break;
+       default:
+               goto unsupported;
+       }
+
+       return 0;
+
+unsupported:
+       pr_warn("Unsupported SignedData version\n");
+       return -EINVAL;
+}
+
+/*
+ * Note the SignerInfo version
+ */
+int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
+                                 unsigned char tag,
+                                 const void *value, size_t vlen)
+{
+       unsigned version;
+
+       if (vlen != 1)
+               goto unsupported;
+
+       version = *(const u8 *)value;
+       switch (version) {
+       case 1:
+               /* PKCS#7 SignerInfo [RFC2315 sec 9.2] */
+               break;
+       default:
+               goto unsupported;
+       }
+
+       return 0;
+
+unsupported:
+       pr_warn("Unsupported SignerInfo version\n");
+       return -EINVAL;
+}
+
 /*
  * Extract a certificate and store it in the context.
  */
@@ -326,7 +399,7 @@ int pkcs7_sig_note_authenticated_attr(void *context, size_t hdrlen,
 }
 
 /*
- * Note the set of auth attributes for digestion purposes [RFC2315 9.3]
+ * Note the set of auth attributes for digestion purposes [RFC2315 sec 9.3]
  */
 int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen,
                                    unsigned char tag,