Class MerkleTreeCertificateValidator
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(X509CertificateHolder, 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
invalid reference
ValidationParams.TrustedSubtreeMTCCosignerVerifierProvider until minCosignatures is met.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classA half-open range[start, end)of revoked certificate serial numbers, per Section 7.5 of the draft.static classRepresents a trusted subtree (typically a landmark subtree predistributed to the relying party).static classParameters supplied by the relying party for certificate validation. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringDotted-decimal form ofMTCObjectIdentifiers.id_alg_mtcProof, the signatureAlgorithm of an MTC certificate. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic byte[]computeEntryHash(byte[] tbsCertDer, byte[] extensionsWire, MerkleTreeHash hashFunc) Raw-DER variant ofcomputeEntryHash(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 ofcomputeEntryHash(byte[], byte[], MerkleTreeHash)with an empty extensions list.static byte[]computeEntryHash(org.bouncycastle.asn1.x509.TBSCertificate tbsCert, byte[] extensionsWire, MerkleTreeHash hashFunc) TBSCertificate variant ofcomputeEntryHash(X509CertificateHolder, byte[], MerkleTreeHash).static byte[]computeEntryHash(org.bouncycastle.asn1.x509.TBSCertificate tbsCert, MerkleTreeHash hashFunc) Convenience overload ofcomputeEntryHash(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 equivalentMerkleTreeCertEntryof typetbs_cert_entryand hashing per Section 5.2.1 / Section 7.2.static byte[]computeEntryHash(X509CertificateHolder certHolder, MerkleTreeHash hashFunc) Convenience overload ofcomputeEntryHash(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 booleanvalidateCertificate(X509CertificateHolder certHolder, MerkleTreeCertificateValidator.ValidationParams params) Validates a Merkle Tree certificate per Section 7.2.static voidwriteEntryHashInput(byte[] tbsCertDer, byte[] extensionsWire, MerkleTreeHash hashFunc, OutputStream out) Raw-DER variant ofwriteEntryHashInput(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 streamingContentSigner).static voidwriteEntryHashInput(org.bouncycastle.asn1.x509.TBSCertificate tbsCert, byte[] extensionsWire, MerkleTreeHash hashFunc, OutputStream out) TBSCertificate variant ofwriteEntryHashInput(X509CertificateHolder, byte[], MerkleTreeHash, OutputStream).static voidwriteEntryHashInput(X509CertificateHolder certHolder, byte[] extensionsWire, MerkleTreeHash hashFunc, OutputStream out) Streams the byte sequence thatcomputeEntryHash(X509CertificateHolder, MerkleTreeHash)hashes into the suppliedOutputStream.
-
Field Details
-
ID_ALG_MTC_PROOF
Dotted-decimal form ofMTCObjectIdentifiers.id_alg_mtcProof, the signatureAlgorithm of an MTC certificate.
-
-
Constructor Details
-
MerkleTreeCertificateValidator
public MerkleTreeCertificateValidator()
-
-
Method Details
-
validateCertificate
public static boolean validateCertificate(X509CertificateHolder certHolder, MerkleTreeCertificateValidator.ValidationParams params) throws IOException Validates a Merkle Tree certificate per Section 7.2. Always returnstrueon success; any validation failure is signalled as aSecurityException.- Parameters:
certHolder- the certificate to validateparams- validation parameters- Throws:
SecurityException- if the certificate is rejectedIllegalArgumentException- if the certificate is not a Merkle Tree certificateIOException- if the certificate cannot be parsed
-
computeEntryHash
public static byte[] computeEntryHash(X509CertificateHolder certHolder, MerkleTreeHash hashFunc) throws IOException Convenience overload ofcomputeEntryHash(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.- Throws:
IOException
-
computeEntryHash
public static byte[] computeEntryHash(org.bouncycastle.asn1.x509.TBSCertificate tbsCert, MerkleTreeHash hashFunc) throws IOException Convenience overload ofcomputeEntryHash(TBSCertificate, byte[], MerkleTreeHash)with an empty extensions list. Useful when the caller has aTBSCertificatein hand (for instance during issuance, before the signature is computed) and doesn't want to build a placeholderX509CertificateHoldersolely to satisfy the holder-based overload.- Throws:
IOException
-
computeEntryHash
public static byte[] computeEntryHash(byte[] tbsCertDer, MerkleTreeHash hashFunc) throws IOException Convenience overload ofcomputeEntryHash(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 streamingContentSigner) to avoid the parse + re-encode round trip viaTBSCertificate.- Throws:
IOException
-
computeSubtreeHash
public static byte[] computeSubtreeHash(byte[] tbsCertDer, byte[] inclusionProof, MerkleTreeHash hashFunc) throws IOException 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. Equivalent tohashFunc.hashNode(computeEntryHash(tbsCertDer, hashFunc), inclusionProof). The extensions list is empty.- Throws:
IOException
-
computeEntryHash
public static byte[] computeEntryHash(X509CertificateHolder certHolder, byte[] extensionsWire, MerkleTreeHash hashFunc) throws IOException Computes the entry hash for a certificate by transforming its TBSCertificate into the equivalentMerkleTreeCertEntryof typetbs_cert_entryand hashing per Section 5.2.1 / Section 7.2.The single-pass procedure (Section 7.2):
- Write the
extensionsfield from the MTCProof (the on-wire bytes including the 2-byte length prefix) to the hash. - Write the big-endian, two-byte
tbs_cert_entryvalue (0x0001). - Write the TBSCertificate contents octets up to
subjectPublicKeyInfo. - Write the
subjectPublicKeyInfo's algorithm field. - Write
0x04 L Hwhere L is the hash length and H is HASH(SPKI). - Write the remaining TBSCertificate contents octets.
- Finalize.
- Parameters:
extensionsWire- theextensions<0..2^16-1>field exactly as it appears at the start of the corresponding MTCProof (useMTCProof.getExtensionsWire())- Throws:
IOException
- Write the
-
computeEntryHash
public static byte[] computeEntryHash(org.bouncycastle.asn1.x509.TBSCertificate tbsCert, byte[] extensionsWire, MerkleTreeHash hashFunc) throws IOException TBSCertificate variant ofcomputeEntryHash(X509CertificateHolder, byte[], MerkleTreeHash). The hash depends only on the to-be-signed structure, so callers that haven't yet wrapped the TBSCertificate in a signedX509CertificateHoldercan compute the entry hash directly.- Throws:
IOException
-
computeEntryHash
public static byte[] computeEntryHash(byte[] tbsCertDer, byte[] extensionsWire, MerkleTreeHash hashFunc) throws IOException Raw-DER variant ofcomputeEntryHash(TBSCertificate, byte[], MerkleTreeHash)— skips the parse + re-encode round trip when the TBSCertificate is already in hand as DER bytes.- Throws:
IOException
-
writeEntryHashInput
public static void writeEntryHashInput(X509CertificateHolder certHolder, byte[] extensionsWire, MerkleTreeHash hashFunc, OutputStream out) throws IOException Streams the byte sequence thatcomputeEntryHash(X509CertificateHolder, MerkleTreeHash)hashes into the suppliedOutputStream. Equivalent in output to building aByteArrayOutputStreamand finishing withhashFunc.hashLeaf(baos.toByteArray()), but lets callers pipe the bytes directly into a streaming digest (e.g.org.bouncycastle.crypto.io.DigestOutputStreamorjava.security.DigestOutputStream) so theMerkleTreeCertEntrynever lives fully in memory.hashFuncis still required because Section 7.2's single-pass procedure (step 8) hashes the SubjectPublicKeyInfo separately viaMerkleTreeHash.hashRaw(byte[])and writes only its hash into the entry stream.- Parameters:
certHolder- the X.509 certificateextensionsWire- theMTCProof.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 byte0x00into a digest first, then pipingoutinto the same digest)out- destination for the streamed entry bytes- Throws:
IOException
-
writeEntryHashInput
public static void writeEntryHashInput(org.bouncycastle.asn1.x509.TBSCertificate tbsCert, byte[] extensionsWire, MerkleTreeHash hashFunc, OutputStream out) throws IOException TBSCertificate variant ofwriteEntryHashInput(X509CertificateHolder, byte[], MerkleTreeHash, OutputStream).- Throws:
IOException
-
writeEntryHashInput
public static void writeEntryHashInput(byte[] tbsCertDer, byte[] extensionsWire, MerkleTreeHash hashFunc, OutputStream out) throws IOException Raw-DER variant ofwriteEntryHashInput(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 streamingContentSigner).- Throws:
IOException
-
extractCaIdFromIssuer
public static byte[] extractCaIdFromIssuer(org.bouncycastle.asn1.x500.X500Name issuer) throws IOException Extracts the binary CA trust anchor ID from the issuer field of a Merkle Tree certificate. Per Section 5.1 of the draft the issuer name has a single RDN with a single attribute. For initial experimentation the attribute type isid_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.- Throws:
IOException
-