Class MerkleTreeCertificateValidator

    • Field Detail

      • ID_ALG_MTC_PROOF

        public static final java.lang.String ID_ALG_MTC_PROOF
        Dotted-decimal form of MTCObjectIdentifiers.id_alg_mtcProof, the signatureAlgorithm of an MTC certificate.
    • Constructor Detail

      • MerkleTreeCertificateValidator

        public MerkleTreeCertificateValidator()
    • Method Detail

      • validateCertificate

        public static boolean validateCertificate​(X509CertificateHolder certHolder,
                                                  MerkleTreeCertificateValidator.ValidationParams params)
                                           throws java.io.IOException
        Validates a Merkle Tree certificate per Section 7.2. Always returns true on success; any validation failure is signalled as a SecurityException.
        Parameters:
        certHolder - the certificate to validate
        params - validation parameters
        Throws:
        java.lang.SecurityException - if the certificate is rejected
        java.lang.IllegalArgumentException - if the certificate is not a Merkle Tree certificate
        java.io.IOException - if the certificate cannot be parsed
      • computeEntryHash

        public static byte[] computeEntryHash​(org.bouncycastle.asn1.x509.TBSCertificate tbsCert,
                                              MerkleTreeHash hashFunc)
                                       throws java.io.IOException
        Convenience overload of 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.
        Throws:
        java.io.IOException
      • computeEntryHash

        public static byte[] computeEntryHash​(byte[] tbsCertDer,
                                              MerkleTreeHash hashFunc)
                                       throws java.io.IOException
        Convenience overload of 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.
        Throws:
        java.io.IOException
      • computeSubtreeHash

        public static byte[] computeSubtreeHash​(byte[] tbsCertDer,
                                                byte[] inclusionProof,
                                                MerkleTreeHash hashFunc)
                                         throws java.io.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 to hashFunc.hashNode(computeEntryHash(tbsCertDer, hashFunc), inclusionProof). The extensions list is empty.
        Throws:
        java.io.IOException
      • computeEntryHash

        public static byte[] computeEntryHash​(X509CertificateHolder certHolder,
                                              byte[] extensionsWire,
                                              MerkleTreeHash hashFunc)
                                       throws java.io.IOException
        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.

        The single-pass procedure (Section 7.2):

        1. Write the extensions field from the MTCProof (the on-wire bytes including the 2-byte length prefix) to the hash.
        2. Write the big-endian, two-byte tbs_cert_entry value (0x0001).
        3. Write the TBSCertificate contents octets up to subjectPublicKeyInfo.
        4. Write the subjectPublicKeyInfo's algorithm field.
        5. Write 0x04 L H where L is the hash length and H is HASH(SPKI).
        6. Write the remaining TBSCertificate contents octets.
        7. Finalize.
        Parameters:
        extensionsWire - the extensions<0..2^16-1> field exactly as it appears at the start of the corresponding MTCProof (use MTCProof.getExtensionsWire())
        Throws:
        java.io.IOException
      • computeEntryHash

        public static byte[] computeEntryHash​(byte[] tbsCertDer,
                                              byte[] extensionsWire,
                                              MerkleTreeHash hashFunc)
                                       throws java.io.IOException
        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.
        Throws:
        java.io.IOException
      • writeEntryHashInput

        public static void writeEntryHashInput​(X509CertificateHolder certHolder,
                                               byte[] extensionsWire,
                                               MerkleTreeHash hashFunc,
                                               java.io.OutputStream out)
                                        throws java.io.IOException
        Streams the byte sequence that 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.

        Parameters:
        certHolder - the X.509 certificate
        extensionsWire - 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 bytes
        Throws:
        java.io.IOException
      • extractCaIdFromIssuer

        public static byte[] extractCaIdFromIssuer​(org.bouncycastle.asn1.x500.X500Name issuer)
                                            throws java.io.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 is 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.
        Throws:
        java.io.IOException