001package org.apache.commons.ssl.org.bouncycastle.asn1.isismtt.ocsp;
002
003import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
004import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
007import org.apache.commons.ssl.org.bouncycastle.asn1.DEROctetString;
008import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
009import org.apache.commons.ssl.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
010
011/**
012 * ISIS-MTT PROFILE: The responder may include this extension in a response to
013 * send the hash of the requested certificate to the responder. This hash is
014 * cryptographically bound to the certificate and serves as evidence that the
015 * certificate is known to the responder (i.e. it has been issued and is present
016 * in the directory). Hence, this extension is a means to provide a positive
017 * statement of availability as described in T8.[8]. As explained in T13.[1],
018 * clients may rely on this information to be able to validate signatures after
019 * the expiry of the corresponding certificate. Hence, clients MUST support this
020 * extension. If a positive statement of availability is to be delivered, this
021 * extension syntax and OID MUST be used.
022 * <pre>
023 *     CertHash ::= SEQUENCE {
024 *       hashAlgorithm AlgorithmIdentifier,
025 *       certificateHash OCTET STRING
026 *     }
027 * </pre>
028 */
029public class CertHash
030    extends ASN1Object
031{
032
033    private AlgorithmIdentifier hashAlgorithm;
034    private byte[] certificateHash;
035
036    public static CertHash getInstance(Object obj)
037    {
038        if (obj == null || obj instanceof CertHash)
039        {
040            return (CertHash)obj;
041        }
042
043        if (obj instanceof ASN1Sequence)
044        {
045            return new CertHash((ASN1Sequence)obj);
046        }
047
048        throw new IllegalArgumentException("illegal object in getInstance: "
049            + obj.getClass().getName());
050    }
051
052    /**
053     * Constructor from ASN1Sequence.
054     * <p>
055     * The sequence is of type CertHash:
056     * <pre>
057     *     CertHash ::= SEQUENCE {
058     *       hashAlgorithm AlgorithmIdentifier,
059     *       certificateHash OCTET STRING
060     *     }
061     * </pre>
062     * </p>
063     * @param seq The ASN.1 sequence.
064     */
065    private CertHash(ASN1Sequence seq)
066    {
067        if (seq.size() != 2)
068        {
069            throw new IllegalArgumentException("Bad sequence size: "
070                + seq.size());
071        }
072        hashAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0));
073        certificateHash = DEROctetString.getInstance(seq.getObjectAt(1)).getOctets();
074    }
075
076    /**
077     * Constructor from a given details.
078     *
079     * @param hashAlgorithm   The hash algorithm identifier.
080     * @param certificateHash The hash of the whole DER encoding of the certificate.
081     */
082    public CertHash(AlgorithmIdentifier hashAlgorithm, byte[] certificateHash)
083    {
084        this.hashAlgorithm = hashAlgorithm;
085        this.certificateHash = new byte[certificateHash.length];
086        System.arraycopy(certificateHash, 0, this.certificateHash, 0,
087            certificateHash.length);
088    }
089
090    public AlgorithmIdentifier getHashAlgorithm()
091    {
092        return hashAlgorithm;
093    }
094
095    public byte[] getCertificateHash()
096    {
097        return certificateHash;
098    }
099
100    /**
101     * Produce an object suitable for an ASN1OutputStream.
102     * <p>
103     * Returns:
104     * <pre>
105     *     CertHash ::= SEQUENCE {
106     *       hashAlgorithm AlgorithmIdentifier,
107     *       certificateHash OCTET STRING
108     *     }
109     * </pre>
110     *
111     * @return a DERObject
112     */
113    public ASN1Primitive toASN1Primitive()
114    {
115        ASN1EncodableVector vec = new ASN1EncodableVector();
116        vec.add(hashAlgorithm);
117        vec.add(new DEROctetString(certificateHash));
118        return new DERSequence(vec);
119    }
120}