Handle platform certificates that only provide a single property
The spec states that the PlatformProperties field of the
PlatformConfiguration attribute should be a sequence of key value pairs.
However, it seems that if there's only a single property present, it's
sometimes being stored as a bare key value pair rather than a sequence
with a single entry. Work around that.
A number of the struct definitions had broken tag definitions, which
meant some parsing was working by accident and some parsing was entirely
broken. Fixing this uncovered some additional issues (a mixture of
incorrect definitions and platform certificates that violate the spec),
so this is all cleaned up as well.
Attribute certificates are generally using RSA-SHA1 or RSA-SHA256
signatures, so include those. In addition, the CA signing restrictions
imposed for general purpose certificates don't apply here - drop that
restriction from certificate signature validation.
Using the length of a digest to infer the hash algorithm is somewhat
fragile - if we end up with multiple hash algorithms that share the same
digest length, things will break. Instead, pass more complete digest
information through to relevant functions and figure things out by
mapping the TPM hash algorithm to the appropriate Golang type.
Crypto agile logs may contain digest types that we don't currently
handle. However, we still need to know how long each digest is in order
to read over the appropriate amount of the buffer. This information is
provided to us as part of the spec header - make use of it rather than
hardcoding the set of digests and lengths we know about.
golint current generates complaints:
var oidTpmIdLabel should be oidTpmIDLabel
var oidTcgPlatformManufacturerIdV2 should be oidTcgPlatformManufacturerIDV2
var oidTcgPlatformConfigUri should be oidTcgPlatformConfigURI
Update names to satisfy golint.
The following commands were run to generate this change:
gopls rename -w attributecert.go:44:2 oidTpmIDLabel
gopls rename -w attributecert.go:54:2 oidTcgPlatformManufacturerIDV2
gopls rename -w attributecert.go:55:2 oidTcgPlatformConfigURI
gopls rename -w attributecert.go:163:6 authKeyID
gopls rename -w attributecert.go:164:2 ID
gopls rename -w attributecert.go:171:2 ID
gopls rename -w attributecert.go:178:2 ID
gopls rename -w attributecert.go:210:2 BaseCertificateID
gopls rename -w attributecert.go:232:2 ID
gopls rename -w attributecert.go:304:2 ID
gopls rename -w attributecert.go:309:2 ID
gopls rename -w attributecert.go:390:2 ComponentManufacturerID
sed -i 's/Uri/URI/g' attributecert.go
git clean -f
Updates #131
Platform certificates are defined as RFC5755 attribute certificates with
various additional attributes and extensions defined in the TCG Platform
Certificate Profile. Add support for parsing them, derived from
crypto/x509. Include some test certificates and verify we parse them.
@brandonweeks detected another case of the "make([]T, untrustedValue)"
pattern, which would allow an attacker to cause the parser to allocate
an unbounded amount of memory.
Fix this by reading one algorithm at a time instead of pre-allocating a
slice of algorithms.
A go-fuzz target for the ParseEventLog function. It has been tested
with go-fuzz and go-fuzz + libFuzzer.
oss-fuzz requires a statically built fuzzer binary, so `gofuzz` build
tags are added to avoid building files that depend on go-tspi. A mock
tpm_other.go file is also included to satisfy the `platformTPM`
interface.