org.bouncycastle.cert.X509v2AttributeCertificateBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.bouncycastle.cert.X509v2AttributeCertificateBuilder.java

Source

package org.bouncycastle.cert;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.x509.AttCertIssuer;
import org.bouncycastle.asn1.x509.Attribute;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.V2AttributeCertificateInfoGenerator;
import org.bouncycastle.operator.ContentSigner;

/**
 * class to produce an X.509 Version 2 AttributeCertificate.
 */
public class X509v2AttributeCertificateBuilder {
    private V2AttributeCertificateInfoGenerator acInfoGen;
    private ExtensionsGenerator extGenerator;

    /**
     * Base constructor.
     *
     * @param holder holder certificate details
     * @param issuer issuer of this attribute certificate.
     * @param serialNumber serial number of this attribute certificate.
     * @param notBefore the date before which the certificate is not valid.
     * @param notAfter the date after which the certificate is not valid.
     */
    public X509v2AttributeCertificateBuilder(AttributeCertificateHolder holder, AttributeCertificateIssuer issuer,
            BigInteger serialNumber, Date notBefore, Date notAfter) {
        acInfoGen = new V2AttributeCertificateInfoGenerator();
        extGenerator = new ExtensionsGenerator();

        acInfoGen.setHolder(holder.holder);
        acInfoGen.setIssuer(AttCertIssuer.getInstance(issuer.form));
        acInfoGen.setSerialNumber(new ASN1Integer(serialNumber));
        acInfoGen.setStartDate(new ASN1GeneralizedTime(notBefore));
        acInfoGen.setEndDate(new ASN1GeneralizedTime(notAfter));
    }

    /**
     * Base constructor with locale for interpreting dates. You may need to use this constructor if the default locale
     * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
     *
     * @param holder holder certificate details
     * @param issuer issuer of this attribute certificate.
     * @param serialNumber serial number of this attribute certificate.
     * @param notBefore the date before which the certificate is not valid.
     * @param notAfter the date after which the certificate is not valid.
     * @param dateLocale locale to be used for date interpretation.
     */
    public X509v2AttributeCertificateBuilder(AttributeCertificateHolder holder, AttributeCertificateIssuer issuer,
            BigInteger serialNumber, Date notBefore, Date notAfter, Locale dateLocale) {
        acInfoGen = new V2AttributeCertificateInfoGenerator();
        extGenerator = new ExtensionsGenerator();

        acInfoGen.setHolder(holder.holder);
        acInfoGen.setIssuer(AttCertIssuer.getInstance(issuer.form));
        acInfoGen.setSerialNumber(new ASN1Integer(serialNumber));
        acInfoGen.setStartDate(new ASN1GeneralizedTime(notBefore, dateLocale));
        acInfoGen.setEndDate(new ASN1GeneralizedTime(notAfter, dateLocale));
    }

    /**
     * Create a builder for a version 2 attribute certificate, initialised with another certificate.
     *
     * @param template template certificate to base the new one on.
     */
    public X509v2AttributeCertificateBuilder(X509AttributeCertificateHolder template) {
        acInfoGen = new V2AttributeCertificateInfoGenerator();
        acInfoGen.setSerialNumber(new ASN1Integer(template.getSerialNumber()));
        acInfoGen.setIssuer(AttCertIssuer.getInstance(template.getIssuer().form));
        acInfoGen.setStartDate(new ASN1GeneralizedTime(template.getNotBefore()));
        acInfoGen.setEndDate(new ASN1GeneralizedTime(template.getNotAfter()));
        acInfoGen.setHolder(template.getHolder().holder);
        boolean[] uniqueID = template.getIssuerUniqueID();
        if (uniqueID != null) {
            acInfoGen.setIssuerUniqueID(CertUtils.booleanToBitString(uniqueID));
        }

        Attribute[] attr = template.getAttributes();

        for (int i = 0; i != attr.length; i++) {
            acInfoGen.addAttribute(attr[i]);
        }

        extGenerator = new ExtensionsGenerator();

        Extensions exts = template.getExtensions();

        for (Enumeration en = exts.oids(); en.hasMoreElements();) {
            extGenerator.addExtension(exts.getExtension((ASN1ObjectIdentifier) en.nextElement()));
        }
    }

    /**
     * Return if the extension indicated by OID is present.
     *
     * @param oid the OID for the extension of interest.
     * @return the Extension, or null if it is not present.
     */
    public boolean hasExtension(ASN1ObjectIdentifier oid) {
        return doGetExtension(oid) != null;
    }

    /**
     * Return the current value of the extension for OID.
     *
     * @param oid the OID for the extension we want to fetch.
     * @return true if a matching extension is present, false otherwise.
     */
    public Extension getExtension(ASN1ObjectIdentifier oid) {
        return doGetExtension(oid);
    }

    private Extension doGetExtension(ASN1ObjectIdentifier oid) {
        Extensions exts = extGenerator.generate();

        return exts.getExtension(oid);
    }

    /**
     * Add an attribute to the certification request we are building.
     *
     * @param attrType the OID giving the type of the attribute.
     * @param attrValue the ASN.1 structure that forms the value of the attribute.
     * @return this builder object.
     */
    public X509v2AttributeCertificateBuilder addAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue) {
        acInfoGen.addAttribute(new Attribute(attrType, new DERSet(attrValue)));

        return this;
    }

    /**
     * Add an attribute with multiple values to the certification request we are building.
     *
     * @param attrType the OID giving the type of the attribute.
     * @param attrValues an array of ASN.1 structures that form the value of the attribute.
     * @return this builder object.
     */
    public X509v2AttributeCertificateBuilder addAttribute(ASN1ObjectIdentifier attrType,
            ASN1Encodable[] attrValues) {
        acInfoGen.addAttribute(new Attribute(attrType, new DERSet(attrValues)));

        return this;
    }

    public void setIssuerUniqueId(boolean[] iui) {
        acInfoGen.setIssuerUniqueID(CertUtils.booleanToBitString(iui));
    }

    /**
     * Add a given extension field for the standard extensions tag made up of the passed in parameters.
     *
     * @param oid the OID defining the extension type.
     * @param isCritical true if the extension is critical, false otherwise.
     * @param value the ASN.1 structure that forms the extension's value.
     * @return this builder object.
     */
    public X509v2AttributeCertificateBuilder addExtension(ASN1ObjectIdentifier oid, boolean isCritical,
            ASN1Encodable value) throws CertIOException {
        CertUtils.addExtension(extGenerator, oid, isCritical, value);

        return this;
    }

    /**
     * Add a given extension field for the standard extensions using a byte encoding of the
     * extension value.
     *
     * @param oid the OID defining the extension type.
     * @param isCritical true if the extension is critical, false otherwise.
     * @param encodedValue a byte array representing the encoding of the extension value.
     * @return this builder object.
     */
    public X509v2AttributeCertificateBuilder addExtension(ASN1ObjectIdentifier oid, boolean isCritical,
            byte[] encodedValue) throws CertIOException {
        extGenerator.addExtension(oid, isCritical, encodedValue);

        return this;
    }

    /**
     * Add a given extension field for the standard extensions.
     *
     * @param extension the full extension value.
     * @return this builder object.
     */
    public X509v2AttributeCertificateBuilder addExtension(Extension extension) throws CertIOException {
        extGenerator.addExtension(extension);

        return this;
    }

    /**
     * Replace the extension field for the passed in extension's extension ID
     * with a new version.
     *
     * @param oid the OID defining the extension type.
     * @param isCritical true if the extension is critical, false otherwise.
     * @param value the ASN.1 structure that forms the extension's value.
     * @return this builder object.
     * @throws CertIOException if there is an issue with the new extension value.
     * @throws IllegalArgumentException if the extension to be replaced is not present.
     */
    public X509v2AttributeCertificateBuilder replaceExtension(ASN1ObjectIdentifier oid, boolean isCritical,
            ASN1Encodable value) throws CertIOException {
        try {
            extGenerator = CertUtils.doReplaceExtension(extGenerator,
                    new Extension(oid, isCritical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER)));
        } catch (IOException e) {
            throw new CertIOException("cannot encode extension: " + e.getMessage(), e);
        }

        return this;
    }

    /**
     * Replace the extension field for the passed in extension's extension ID
     * with a new version.
     *
     * @param extension the full extension value.
     * @return this builder object.
     * @throws CertIOException if there is an issue with the new extension value.
     * @throws IllegalArgumentException if the extension to be replaced is not present.
     */
    public X509v2AttributeCertificateBuilder replaceExtension(Extension extension) throws CertIOException {
        extGenerator = CertUtils.doReplaceExtension(extGenerator, extension);

        return this;
    }

    /**
     * Replace a given extension field for the standard extensions tag (tag 3) with the passed in
     * byte encoded extension value.
     *
     * @param oid the OID defining the extension type.
     * @param isCritical true if the extension is critical, false otherwise.
     * @param encodedValue a byte array representing the encoding of the extension value.
     * @return this builder object.
     * @throws CertIOException if there is an issue with the new extension value.
     * @throws IllegalArgumentException if the extension to be replaced is not present.
     */
    public X509v2AttributeCertificateBuilder replaceExtension(ASN1ObjectIdentifier oid, boolean isCritical,
            byte[] encodedValue) throws CertIOException {
        extGenerator = CertUtils.doReplaceExtension(extGenerator, new Extension(oid, isCritical, encodedValue));

        return this;
    }

    /**
     * Remove the extension indicated by OID.
     *
     * @param oid the OID of the extension to be removed.
     * @return this builder object.
     * @throws IllegalArgumentException if the extension to be removed is not present.
     */
    public X509v2AttributeCertificateBuilder removeExtension(ASN1ObjectIdentifier oid) {
        extGenerator = CertUtils.doRemoveExtension(extGenerator, oid);

        return this;
    }

    /**
      * Generate an X509 certificate, based on the current issuer and subject
      * using the passed in signer.
      *
      * @param signer the content signer to be used to generate the signature validating the certificate.
      * @return a holder containing the resulting signed certificate.
      */
    public X509AttributeCertificateHolder build(ContentSigner signer) {
        acInfoGen.setSignature(signer.getAlgorithmIdentifier());

        if (!extGenerator.isEmpty()) {
            acInfoGen.setExtensions(extGenerator.generate());
        }

        return CertUtils.generateFullAttrCert(signer, acInfoGen.generateAttributeCertificateInfo());
    }
}