eu.europa.ec.markt.dss.validation.certificate.CertificateAndContext.java Source code

Java tutorial

Introduction

Here is the source code for eu.europa.ec.markt.dss.validation.certificate.CertificateAndContext.java

Source

/*
 * DSS - Digital Signature Services
 *
 * Copyright (C) 2011 European Commission, Directorate-General Internal Market and Services (DG MARKT), B-1049 Bruxelles/Brussel
 *
 * Developed by: 2011 ARHS Developments S.A. (rue Nicolas Bov 2B, L-1253 Luxembourg) http://www.arhs-developments.com
 *
 * This file is part of the "DSS - Digital Signature Services" project.
 *
 * "DSS - Digital Signature Services" is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the
 * License, or (at your option) any later version.
 *
 * DSS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * "DSS - Digital Signature Services".  If not, see <http://www.gnu.org/licenses/>.
 */

package eu.europa.ec.markt.dss.validation.certificate;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.DERObject;
import org.bouncycastle.asn1.DEROctetString;

import eu.europa.ec.markt.dss.CertificateIdentifier;
import eu.europa.ec.markt.dss.OID;
import eu.europa.ec.markt.dss.adapter.X509CertificateAdapter;

/**
 * A certificate comes from a certain context (Trusted List, CertStore, Signature) and has some properties
 * 
 * 
 * @version $Revision: 2228 $ - $Date: 2013-06-13 16:13:21 +0200 (jeu., 13 juin 2013) $
 */

@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
public class CertificateAndContext {
    @XmlJavaTypeAdapter(X509CertificateAdapter.class)
    private X509Certificate certificate;
    @XmlElement
    private CertificateSourceType certificateSource;
    @XmlTransient
    private Serializable context;

    private boolean signatureOk = false;
    private String signatureAlgorithm;

    public String getSignatureAlgorithm() {
        return signatureAlgorithm;
    }

    public void setSignatureAlgorithm(String algorithm) {

        signatureAlgorithm = algorithm;
    }

    public void setSignatureIsValid() {

        signatureOk = true;
    }

    public boolean isSignatureOk() {

        return signatureOk;
    }

    /**
     * 
     * The default constructor for CertificateAndContext.
     */
    public CertificateAndContext() {
    }

    /**
     * Create a CertificateAndContext wrapping the provided X509Certificate The default constructor for
     * CertificateAndContext.
     * 
     * @param cert
     */
    public CertificateAndContext(X509Certificate cert) {
        this(cert, null);
    }

    /**
     * 
     * The default constructor for CertificateAndContext.
     * 
     * @param cert
     * @param context
     */
    public CertificateAndContext(X509Certificate cert, Serializable context) {
        this.certificate = cert;
        this.context = context;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        CertificateAndContext other = (CertificateAndContext) obj;
        if (certificate == null) {
            if (other.certificate != null) {
                return false;
            }
        } else if (!certificate.equals(other.certificate)) {
            return false;
        }
        return true;
    }

    /**
     * Get the X509 Certificate
     * 
     * @return
     */
    public X509Certificate getCertificate() {
        return certificate;
    }

    /**
     * Get information about the source of the Certificate (TRUSTED_LIST, TRUST_STORE, ...)
     * 
     * @return
     */
    public CertificateSourceType getCertificateSource() {
        return certificateSource;
    }

    /**
     * Get information about the context from which the certificate is fetched
     * 
     * @return
     */
    public Serializable getContext() {
        return context;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((certificate == null) ? 0 : certificate.hashCode());
        return result;
    }

    /**
     * Set the X509 Certificate
     * 
     * @param certificate
     */
    public void setCertificate(X509Certificate certificate) {
        this.certificate = certificate;
    }

    /**
     * Set information bout the source of the Certificate (TRUSTED_LIST, TRUST_STORE, ...)
     * 
     * @param certificateSource
     */
    public void setCertificateSource(CertificateSourceType certificateSource) {
        this.certificateSource = certificateSource;
    }

    /**
     * Set information about the context from which the certificate if fetched
     * 
     * @param context
     */
    public void setContext(Serializable context) {
        this.context = context;
    }

    /**
     * Indicates that a X509Certificates corresponding private key is used by an authority to sign OCSP-Responses.<br>
     * http://www.ietf.org/rfc/rfc3280.txt <br>
     * {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) keyPurpose(3)
     * ocspSigning(9)}<br>
     * OID: 1.3.6.1.5.5.7.3.9
     * 
     * @return
     */
    public boolean isOCSPSigning() {

        try {

            List<String> keyPurposes = certificate.getExtendedKeyUsage();
            if (keyPurposes != null && keyPurposes.contains(OID._1_3_6_1_5_5_7_3_9.getName())) {

                return true;
            }
        } catch (CertificateParsingException e) {

            // LOG.warning(e.getMessage());
        }
        // Responder's certificate not valid for signing OCSP responses.
        return false;
    }

    /**
     * Indicates if the revocation data should be checked for an OCSP signing certificate.<br>
     * http://www.ietf.org/rfc/rfc2560.txt?number=2560<br>
     * A CA may specify that an OCSP client can trust a responder for the lifetime of the responder's certificate. The CA
     * does so by including the extension id-pkix-ocsp-nocheck. This SHOULD be a non-critical extension. The value of the
     * extension should be NULL.
     * 
     * @return
     */
    public boolean has_id_pkix_ocsp_nocheck_extension() {

        byte[] extensionValue = certificate.getExtensionValue(OID._1_3_6_1_5_5_7_48_1_5.getName());
        try {

            if (extensionValue != null) {

                DERObject derObject = toDERObject(extensionValue);
                if (derObject instanceof DEROctetString) {

                    DEROctetString derOctetString = (DEROctetString) derObject;
                    byte[] data = derOctetString.getOctets();
                    return data.length == 0;
                }
            }
        } catch (Exception e) {

        }
        return false;
    }

    /**
     * 
     * @param data
     * @return
     * @throws IOException
     */
    private DERObject toDERObject(byte[] data) throws IOException {

        ByteArrayInputStream inStream = new ByteArrayInputStream(data);
        ASN1InputStream asnInputStream = new ASN1InputStream(inStream);
        DERObject object = asnInputStream.readObject();
        asnInputStream.close();
        return object;
    }

    @Override
    public String toString() {

        StringBuffer out = new StringBuffer();
        out.append("CertificateAndContext[").append(CertificateIdentifier.getId(certificate)).append("<--")
                .append(certificate.getIssuerX500Principal()).append(", source=").append(certificateSource)
                .append(", serial=" + certificate.getSerialNumber()).append("]");
        return out.toString();
    }
}