06 Apr, 2016

2 commits

  • Make the determination of the trustworthiness of a key dependent on whether
    a key that can verify it is present in the supplied ring of trusted keys
    rather than whether or not the verifying key has KEY_FLAG_TRUSTED set.

    verify_pkcs7_signature() will return -ENOKEY if the PKCS#7 message trust
    chain cannot be verified.

    Signed-off-by: David Howells

    David Howells
     
  • Generalise system_verify_data() to provide access to internal content
    through a callback. This allows all the PKCS#7 stuff to be hidden inside
    this function and removed from the PE file parser and the PKCS#7 test key.

    If external content is not required, NULL should be passed as data to the
    function. If the callback is not required, that can be set to NULL.

    The function is now called verify_pkcs7_signature() to contrast with
    verify_pefile_signature() and the definitions of both have been moved into
    linux/verification.h along with the key_being_used_for enum.

    Signed-off-by: David Howells

    David Howells
     

04 Mar, 2016

1 commit


13 Aug, 2015

1 commit

  • A PKCS#7 or CMS message can have per-signature authenticated attributes
    that are digested as a lump and signed by the authorising key for that
    signature. If such attributes exist, the content digest isn't itself
    signed, but rather it is included in a special authattr which then
    contributes to the signature.

    Further, we already require the master message content type to be
    pkcs7_signedData - but there's also a separate content type for the data
    itself within the SignedData object and this must be repeated inside the
    authattrs for each signer [RFC2315 9.2, RFC5652 11.1].

    We should really validate the authattrs if they exist or forbid them
    entirely as appropriate. To this end:

    (1) Alter the PKCS#7 parser to reject any message that has more than one
    signature where at least one signature has authattrs and at least one
    that does not.

    (2) Validate authattrs if they are present and strongly restrict them.
    Only the following authattrs are permitted and all others are
    rejected:

    (a) contentType. This is checked to be an OID that matches the
    content type in the SignedData object.

    (b) messageDigest. This must match the crypto digest of the data.

    (c) signingTime. If present, we check that this is a valid, parseable
    UTCTime or GeneralTime and that the date it encodes fits within
    the validity window of the matching X.509 cert.

    (d) S/MIME capabilities. We don't check the contents.

    (e) Authenticode SP Opus Info. We don't check the contents.

    (f) Authenticode Statement Type. We don't check the contents.

    The message is rejected if (a) or (b) are missing. If the message is
    an Authenticode type, the message is rejected if (e) is missing; if
    not Authenticode, the message is rejected if (d) - (f) are present.

    The S/MIME capabilities authattr (d) unfortunately has to be allowed
    to support kernels already signed by the pesign program. This only
    affects kexec. sign-file suppresses them (CMS_NOSMIMECAP).

    The message is also rejected if an authattr is given more than once or
    if it contains more than one element in its set of values.

    (3) Add a parameter to pkcs7_verify() to select one of the following
    restrictions and pass in the appropriate option from the callers:

    (*) VERIFYING_MODULE_SIGNATURE

    This requires that the SignedData content type be pkcs7-data and
    forbids authattrs. sign-file sets CMS_NOATTR. We could be more
    flexible and permit authattrs optionally, but only permit minimal
    content.

    (*) VERIFYING_FIRMWARE_SIGNATURE

    This requires that the SignedData content type be pkcs7-data and
    requires authattrs. In future, this will require an attribute
    holding the target firmware name in addition to the minimal set.

    (*) VERIFYING_UNSPECIFIED_SIGNATURE

    This requires that the SignedData content type be pkcs7-data but
    allows either no authattrs or only permits the minimal set.

    (*) VERIFYING_KEXEC_PE_SIGNATURE

    This only supports the Authenticode SPC_INDIRECT_DATA content type
    and requires at least an SpcSpOpusInfo authattr in addition to the
    minimal set. It also permits an SPC_STATEMENT_TYPE authattr (and
    an S/MIME capabilities authattr because the pesign program doesn't
    remove these).

    (*) VERIFYING_KEY_SIGNATURE
    (*) VERIFYING_KEY_SELF_SIGNATURE

    These are invalid in this context but are included for later use
    when limiting the use of X.509 certs.

    (4) The pkcs7_test key type is given a module parameter to select between
    the above options for testing purposes. For example:

    echo 1 >/sys/module/pkcs7_test_key/parameters/usage
    keyctl padd pkcs7_test foo @s
    Signed-off-by: David Howells
    Reviewed-by: Marcel Holtmann
    Reviewed-by: David Woodhouse

    David Howells
     

03 Sep, 2014

1 commit

  • Relax the check on the length of the PKCS#7 cert as it appears that the PE
    file wrapper size gets rounded up to the nearest 8.

    The debugging output looks like this:

    PEFILE: ==> verify_pefile_signature()
    PEFILE: ==> pefile_parse_binary()
    PEFILE: checksum @ 110
    PEFILE: header size = 200
    PEFILE: cert = 968 @547be0 [68 09 00 00 00 02 02 00 30 82 09 56 ]
    PEFILE: sig wrapper = { 968, 200, 2 }
    PEFILE: Signature data not PKCS#7

    The wrapper is the first 8 bytes of the hex dump inside []. This indicates a
    length of 0x968 bytes, including the wrapper header - so 0x960 bytes of
    payload.

    The ASN.1 wrapper begins [ ... 30 82 09 56 ]. That indicates an object of size
    0x956 - a four byte discrepency, presumably just padding for alignment
    purposes.

    So we just check that the ASN.1 container is no bigger than the payload and
    reduce the recorded size appropriately.

    Whilst we're at it, allow shorter PKCS#7 objects that manage to squeeze within
    127 or 255 bytes. It's just about conceivable if no X.509 certs are included
    in the PKCS#7 message.

    Reported-by: Vivek Goyal
    Signed-off-by: David Howells
    Acked-by: Vivek Goyal
    Acked-by: Peter Jones
    Signed-off-by: James Morris

    David Howells
     

09 Jul, 2014

6 commits