public class MerkleTreeCertificateValidator
extends java.lang.Object
The validator stands in for the per-certificate signature verification
step of RFC 5280 path validation (Section 6.1.3 step (a)(1)) when the issuer
is a Merkle Tree CA. validateCertificate(org.bouncycastle.cert.X509CertificateHolder, org.bouncycastle.cert.plants.MerkleTreeCertificateValidator.ValidationParams) decodes the
MTCProof carried in the certificate's signatureValue,
recomputes the entry hash from the TBSCertificate, evaluates the inclusion
proof against the supplied MerkleTreeHash, and then either matches
the resulting subtree hash against a ValidationParams.TrustedSubtree
or counts valid cosignatures against the relying party's
MTCCosignerVerifierProvider until minCosignatures is met.
| Modifier and Type | Class and Description |
|---|---|
static class |
MerkleTreeCertificateValidator.RevokedRange
A half-open range
[start, end) of revoked certificate serial
numbers, per Section 7.5 of the draft. |
static class |
MerkleTreeCertificateValidator.TrustedSubtree
Represents a trusted subtree (typically a landmark subtree predistributed
to the relying party).
|
static class |
MerkleTreeCertificateValidator.ValidationParams
Parameters supplied by the relying party for certificate validation.
|
| Modifier and Type | Field and Description |
|---|---|
static java.lang.String |
ID_ALG_MTC_PROOF
Dotted-decimal form of
MTCObjectIdentifiers.id_alg_mtcProof, the signatureAlgorithm of an MTC certificate. |
| Constructor and Description |
|---|
MerkleTreeCertificateValidator() |
| Modifier and Type | Method and Description |
|---|---|
static byte[] |
computeEntryHash(byte[] tbsCertDer,
byte[] extensionsWire,
MerkleTreeHash hashFunc)
Raw-DER variant of
computeEntryHash(TBSCertificate, byte[], MerkleTreeHash) — skips
the parse + re-encode round trip when the TBSCertificate is already in
hand as DER bytes. |
static byte[] |
computeEntryHash(byte[] tbsCertDer,
MerkleTreeHash hashFunc)
Convenience overload of
computeEntryHash(byte[], byte[], MerkleTreeHash) with an empty
extensions list. |
static byte[] |
computeEntryHash(org.bouncycastle.asn1.x509.TBSCertificate tbsCert,
byte[] extensionsWire,
MerkleTreeHash hashFunc)
TBSCertificate variant of
computeEntryHash(X509CertificateHolder, byte[], MerkleTreeHash). |
static byte[] |
computeEntryHash(org.bouncycastle.asn1.x509.TBSCertificate tbsCert,
MerkleTreeHash hashFunc)
Convenience overload of
computeEntryHash(TBSCertificate, byte[], MerkleTreeHash) with an
empty extensions list. |
static byte[] |
computeEntryHash(X509CertificateHolder certHolder,
byte[] extensionsWire,
MerkleTreeHash hashFunc)
Computes the entry hash for a certificate by transforming its TBSCertificate
into the equivalent
MerkleTreeCertEntry of type tbs_cert_entry
and hashing per Section 5.2.1 / Section 7.2. |
static byte[] |
computeEntryHash(X509CertificateHolder certHolder,
MerkleTreeHash hashFunc)
Convenience overload of
computeEntryHash(X509CertificateHolder, byte[], MerkleTreeHash)
with an empty extensions list (the wire form is two zero bytes, the
uint16 length prefix). |
static byte[] |
computeSubtreeHash(byte[] tbsCertDer,
byte[] inclusionProof,
MerkleTreeHash hashFunc)
Combined "leaf hash + climb one level" for the simple case of a
size-two subtree
[0, 2) where the EE has exactly one sibling
leaf. |
static byte[] |
extractCaIdFromIssuer(org.bouncycastle.asn1.x500.X500Name issuer)
Extracts the binary CA trust anchor ID from the issuer field of a Merkle
Tree certificate.
|
static boolean |
validateCertificate(X509CertificateHolder certHolder,
MerkleTreeCertificateValidator.ValidationParams params)
Validates a Merkle Tree certificate per Section 7.2.
|
static void |
writeEntryHashInput(byte[] tbsCertDer,
byte[] extensionsWire,
MerkleTreeHash hashFunc,
java.io.OutputStream out)
Raw-DER variant of
writeEntryHashInput(TBSCertificate, byte[], MerkleTreeHash, OutputStream) —
skips the parse + re-encode round trip when the TBSCertificate is already
in hand as DER bytes (e.g. captured from a streaming
ContentSigner). |
static void |
writeEntryHashInput(org.bouncycastle.asn1.x509.TBSCertificate tbsCert,
byte[] extensionsWire,
MerkleTreeHash hashFunc,
java.io.OutputStream out)
TBSCertificate variant of
writeEntryHashInput(X509CertificateHolder, byte[], MerkleTreeHash, OutputStream). |
static void |
writeEntryHashInput(X509CertificateHolder certHolder,
byte[] extensionsWire,
MerkleTreeHash hashFunc,
java.io.OutputStream out)
Streams the byte sequence that
computeEntryHash(org.bouncycastle.cert.X509CertificateHolder, org.bouncycastle.cert.plants.MerkleTreeHash) hashes into the
supplied OutputStream. |
public static final java.lang.String ID_ALG_MTC_PROOF
MTCObjectIdentifiers.id_alg_mtcProof, the signatureAlgorithm of an MTC certificate.public static boolean validateCertificate(X509CertificateHolder certHolder, MerkleTreeCertificateValidator.ValidationParams params) throws java.io.IOException
true on success; any validation failure is signalled as a
SecurityException.certHolder - the certificate to validateparams - validation parametersjava.lang.SecurityException - if the certificate is rejectedjava.lang.IllegalArgumentException - if the certificate is not a Merkle Tree certificatejava.io.IOException - if the certificate cannot be parsedpublic static byte[] computeEntryHash(X509CertificateHolder certHolder, MerkleTreeHash hashFunc) throws java.io.IOException
computeEntryHash(X509CertificateHolder, byte[], MerkleTreeHash)
with an empty extensions list (the wire form is two zero bytes, the
uint16 length prefix). Use this when the certificate has no log-entry
extensions.java.io.IOExceptionpublic static byte[] computeEntryHash(org.bouncycastle.asn1.x509.TBSCertificate tbsCert,
MerkleTreeHash hashFunc)
throws java.io.IOException
computeEntryHash(TBSCertificate, byte[], MerkleTreeHash) with an
empty extensions list. Useful when the caller has a TBSCertificate
in hand (for instance during issuance, before the signature is computed)
and doesn't want to build a placeholder X509CertificateHolder
solely to satisfy the holder-based overload.java.io.IOExceptionpublic static byte[] computeEntryHash(byte[] tbsCertDer,
MerkleTreeHash hashFunc)
throws java.io.IOException
computeEntryHash(byte[], byte[], MerkleTreeHash) with an empty
extensions list. Use this when the DER encoding of the TBSCertificate is
already in hand (e.g. captured from a streaming
ContentSigner) to avoid the parse +
re-encode round trip via TBSCertificate.java.io.IOExceptionpublic static byte[] computeSubtreeHash(byte[] tbsCertDer,
byte[] inclusionProof,
MerkleTreeHash hashFunc)
throws java.io.IOException
[0, 2) where the EE has exactly one sibling
leaf. Equivalent to
hashFunc.hashNode(computeEntryHash(tbsCertDer, hashFunc), inclusionProof).
The extensions list is empty.java.io.IOExceptionpublic static byte[] computeEntryHash(X509CertificateHolder certHolder, byte[] extensionsWire, MerkleTreeHash hashFunc) throws java.io.IOException
MerkleTreeCertEntry of type tbs_cert_entry
and hashing per Section 5.2.1 / Section 7.2.
The single-pass procedure (Section 7.2):
extensions field from the MTCProof (the on-wire bytes
including the 2-byte length prefix) to the hash.tbs_cert_entry value (0x0001).subjectPublicKeyInfo.subjectPublicKeyInfo's algorithm field.0x04 L H where L is the hash length and H is HASH(SPKI).extensionsWire - the extensions<0..2^16-1> field exactly as it
appears at the start of the corresponding MTCProof
(use MTCProof.getExtensionsWire())java.io.IOExceptionpublic static byte[] computeEntryHash(org.bouncycastle.asn1.x509.TBSCertificate tbsCert,
byte[] extensionsWire,
MerkleTreeHash hashFunc)
throws java.io.IOException
computeEntryHash(X509CertificateHolder, byte[], MerkleTreeHash).
The hash depends only on the to-be-signed structure, so callers that
haven't yet wrapped the TBSCertificate in a signed
X509CertificateHolder can compute the entry hash directly.java.io.IOExceptionpublic static byte[] computeEntryHash(byte[] tbsCertDer,
byte[] extensionsWire,
MerkleTreeHash hashFunc)
throws java.io.IOException
computeEntryHash(TBSCertificate, byte[], MerkleTreeHash) — skips
the parse + re-encode round trip when the TBSCertificate is already in
hand as DER bytes.java.io.IOExceptionpublic static void writeEntryHashInput(X509CertificateHolder certHolder, byte[] extensionsWire, MerkleTreeHash hashFunc, java.io.OutputStream out) throws java.io.IOException
computeEntryHash(org.bouncycastle.cert.X509CertificateHolder, org.bouncycastle.cert.plants.MerkleTreeHash) hashes into the
supplied OutputStream. Equivalent in output to building a
ByteArrayOutputStream and finishing with
hashFunc.hashLeaf(baos.toByteArray()), but lets callers pipe the
bytes directly into a streaming digest (e.g.
org.bouncycastle.crypto.io.DigestOutputStream or
java.security.DigestOutputStream) so the MerkleTreeCertEntry
never lives fully in memory.
hashFunc is still required because Section 7.2's single-pass
procedure (step 8) hashes
the SubjectPublicKeyInfo separately via MerkleTreeHash.hashRaw(byte[])
and writes only its hash into the entry stream.
certHolder - the X.509 certificateextensionsWire - the MTCProof.getExtensionsWire() bytes
(or {0, 0} for an empty extensions list)hashFunc - hash function used for the SPKI hash; the caller
computes the leaf hash separately (typically by
feeding the leaf-tag byte 0x00 into a
digest first, then piping out into the
same digest)out - destination for the streamed entry bytesjava.io.IOExceptionpublic static void writeEntryHashInput(org.bouncycastle.asn1.x509.TBSCertificate tbsCert,
byte[] extensionsWire,
MerkleTreeHash hashFunc,
java.io.OutputStream out)
throws java.io.IOException
writeEntryHashInput(X509CertificateHolder, byte[], MerkleTreeHash, OutputStream).java.io.IOExceptionpublic static void writeEntryHashInput(byte[] tbsCertDer,
byte[] extensionsWire,
MerkleTreeHash hashFunc,
java.io.OutputStream out)
throws java.io.IOException
writeEntryHashInput(TBSCertificate, byte[], MerkleTreeHash, OutputStream) —
skips the parse + re-encode round trip when the TBSCertificate is already
in hand as DER bytes (e.g. captured from a streaming
ContentSigner).java.io.IOExceptionpublic static byte[] extractCaIdFromIssuer(org.bouncycastle.asn1.x500.X500Name issuer)
throws java.io.IOException
id_rdna_trustAnchorID (1.3.6.1.4.1.44363.47.1)
with a UTF8String value of the dotted-decimal trust anchor ID; for the
production encoding the value is a RELATIVE-OID. Both are accepted; the
return value is the binary trust anchor ID per Section 3 of
draft-ietf-tls-trust-anchor-ids.java.io.IOException