157b253502c94cd7cb6622c22423287225b4b657dKenny Rootpackage org.bouncycastle.cert;
257b253502c94cd7cb6622c22423287225b4b657dKenny Root
357b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport java.math.BigInteger;
457b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport java.util.Date;
557b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport java.util.Locale;
657b253502c94cd7cb6622c22423287225b4b657dKenny Root
757b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.ASN1Encodable;
857b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.ASN1Integer;
957b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.ASN1ObjectIdentifier;
1057b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.x500.X500Name;
1157b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.x509.Certificate;
1257b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.x509.Extension;
1357b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.x509.ExtensionsGenerator;
1457b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
1557b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.x509.Time;
1657b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
1757b253502c94cd7cb6622c22423287225b4b657dKenny Rootimport org.bouncycastle.operator.ContentSigner;
1857b253502c94cd7cb6622c22423287225b4b657dKenny Root
1957b253502c94cd7cb6622c22423287225b4b657dKenny Root
2057b253502c94cd7cb6622c22423287225b4b657dKenny Root/**
2157b253502c94cd7cb6622c22423287225b4b657dKenny Root * class to produce an X.509 Version 3 certificate.
2257b253502c94cd7cb6622c22423287225b4b657dKenny Root */
2357b253502c94cd7cb6622c22423287225b4b657dKenny Rootpublic class X509v3CertificateBuilder
2457b253502c94cd7cb6622c22423287225b4b657dKenny Root{
2557b253502c94cd7cb6622c22423287225b4b657dKenny Root    private V3TBSCertificateGenerator   tbsGen;
2657b253502c94cd7cb6622c22423287225b4b657dKenny Root    private ExtensionsGenerator extGenerator;
2757b253502c94cd7cb6622c22423287225b4b657dKenny Root
2857b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
2957b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Create a builder for a version 3 certificate.
3057b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
3157b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param issuer the certificate issuer
3257b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param serial the certificate serial number
3357b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param notBefore the date before which the certificate is not valid
3457b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param notAfter the date after which the certificate is not valid
3557b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param subject the certificate subject
3657b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param publicKeyInfo the info structure for the public key to be associated with this certificate.
3757b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
3857b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
3957b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
4057b253502c94cd7cb6622c22423287225b4b657dKenny Root        this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
4157b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
4257b253502c94cd7cb6622c22423287225b4b657dKenny Root
4357b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
4457b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Create a builder for a version 3 certificate. You may need to use this constructor if the default locale
4557b253502c94cd7cb6622c22423287225b4b657dKenny Root     * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations.
4657b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
4757b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param issuer the certificate issuer
4857b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param serial the certificate serial number
4957b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param notBefore the date before which the certificate is not valid
5057b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param notAfter the date after which the certificate is not valid
5157b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param dateLocale locale to be used for date interpretation.
5257b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param subject the certificate subject
5357b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param publicKeyInfo the info structure for the public key to be associated with this certificate.
5457b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
5557b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, Locale dateLocale, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
5657b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
5757b253502c94cd7cb6622c22423287225b4b657dKenny Root        this(issuer, serial, new Time(notBefore, dateLocale), new Time(notAfter, dateLocale), subject, publicKeyInfo);
5857b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
5957b253502c94cd7cb6622c22423287225b4b657dKenny Root
6057b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
6157b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Create a builder for a version 3 certificate.
6257b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
6357b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param issuer the certificate issuer
6457b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param serial the certificate serial number
6557b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param notBefore the Time before which the certificate is not valid
6657b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param notAfter the Time after which the certificate is not valid
6757b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param subject the certificate subject
6857b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param publicKeyInfo the info structure for the public key to be associated with this certificate.
6957b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
7057b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
7157b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
7257b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen = new V3TBSCertificateGenerator();
7357b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen.setSerialNumber(new ASN1Integer(serial));
7457b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen.setIssuer(issuer);
7557b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen.setStartDate(notBefore);
7657b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen.setEndDate(notAfter);
7757b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen.setSubject(subject);
7857b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen.setSubjectPublicKeyInfo(publicKeyInfo);
7957b253502c94cd7cb6622c22423287225b4b657dKenny Root
8057b253502c94cd7cb6622c22423287225b4b657dKenny Root        extGenerator = new ExtensionsGenerator();
8157b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
8257b253502c94cd7cb6622c22423287225b4b657dKenny Root
8357b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
8457b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Set the subjectUniqueID - note: it is very rare that it is correct to do this.
8557b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
8657b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param uniqueID a boolean array representing the bits making up the subjectUniqueID.
8757b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @return this builder object.
8857b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
8957b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509v3CertificateBuilder setSubjectUniqueID(boolean[] uniqueID)
9057b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
9157b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen.setSubjectUniqueID(CertUtils.booleanToBitString(uniqueID));
9257b253502c94cd7cb6622c22423287225b4b657dKenny Root
9357b253502c94cd7cb6622c22423287225b4b657dKenny Root        return this;
9457b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
9557b253502c94cd7cb6622c22423287225b4b657dKenny Root
9657b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
9757b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Set the issuerUniqueID - note: it is very rare that it is correct to do this.
9857b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
9957b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param uniqueID a boolean array representing the bits making up the issuerUniqueID.
10057b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @return this builder object.
10157b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
10257b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509v3CertificateBuilder setIssuerUniqueID(boolean[] uniqueID)
10357b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
10457b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen.setIssuerUniqueID(CertUtils.booleanToBitString(uniqueID));
10557b253502c94cd7cb6622c22423287225b4b657dKenny Root
10657b253502c94cd7cb6622c22423287225b4b657dKenny Root        return this;
10757b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
10857b253502c94cd7cb6622c22423287225b4b657dKenny Root
10957b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
11057b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Add a given extension field for the standard extensions tag (tag 3)
11157b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
11257b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param oid the OID defining the extension type.
11357b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param isCritical true if the extension is critical, false otherwise.
11457b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param value the ASN.1 structure that forms the extension's value.
11557b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @return this builder object.
11657b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
11757b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509v3CertificateBuilder addExtension(
11857b253502c94cd7cb6622c22423287225b4b657dKenny Root        ASN1ObjectIdentifier oid,
11957b253502c94cd7cb6622c22423287225b4b657dKenny Root        boolean isCritical,
12057b253502c94cd7cb6622c22423287225b4b657dKenny Root        ASN1Encodable value)
12157b253502c94cd7cb6622c22423287225b4b657dKenny Root        throws CertIOException
12257b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
12357b253502c94cd7cb6622c22423287225b4b657dKenny Root        CertUtils.addExtension(extGenerator, oid, isCritical, value);
12457b253502c94cd7cb6622c22423287225b4b657dKenny Root
12557b253502c94cd7cb6622c22423287225b4b657dKenny Root        return this;
12657b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
12757b253502c94cd7cb6622c22423287225b4b657dKenny Root
12857b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
12957b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Add a given extension field for the standard extensions tag (tag 3).
13057b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
13157b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param extension the full extension value.
13257b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @return this builder object.
13357b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
13457b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509v3CertificateBuilder addExtension(
13557b253502c94cd7cb6622c22423287225b4b657dKenny Root        Extension extension)
13657b253502c94cd7cb6622c22423287225b4b657dKenny Root        throws CertIOException
13757b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
13857b253502c94cd7cb6622c22423287225b4b657dKenny Root        extGenerator.addExtension(extension);
13957b253502c94cd7cb6622c22423287225b4b657dKenny Root
14057b253502c94cd7cb6622c22423287225b4b657dKenny Root        return this;
14157b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
14257b253502c94cd7cb6622c22423287225b4b657dKenny Root
14357b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
14457b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
14557b253502c94cd7cb6622c22423287225b4b657dKenny Root     * extension value.
14657b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
14757b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param oid the OID defining the extension type.
14857b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param isCritical true if the extension is critical, false otherwise.
14957b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param encodedValue a byte array representing the encoding of the extension value.
15057b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @return this builder object.
15157b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
15257b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509v3CertificateBuilder addExtension(
15357b253502c94cd7cb6622c22423287225b4b657dKenny Root        ASN1ObjectIdentifier oid,
15457b253502c94cd7cb6622c22423287225b4b657dKenny Root        boolean isCritical,
15557b253502c94cd7cb6622c22423287225b4b657dKenny Root        byte[] encodedValue)
15657b253502c94cd7cb6622c22423287225b4b657dKenny Root        throws CertIOException
15757b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
15857b253502c94cd7cb6622c22423287225b4b657dKenny Root        extGenerator.addExtension(oid, isCritical, encodedValue);
15957b253502c94cd7cb6622c22423287225b4b657dKenny Root
16057b253502c94cd7cb6622c22423287225b4b657dKenny Root        return this;
16157b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
16257b253502c94cd7cb6622c22423287225b4b657dKenny Root
16357b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
16457b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Add a given extension field for the standard extensions tag (tag 3)
16557b253502c94cd7cb6622c22423287225b4b657dKenny Root     * copying the extension value from another certificate.
16657b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
16757b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param oid the OID defining the extension type.
16857b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param isCritical true if the copied extension is to be marked as critical, false otherwise.
16957b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param certHolder the holder for the certificate that the extension is to be copied from.
17057b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @return this builder object.
17157b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
17257b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509v3CertificateBuilder copyAndAddExtension(
17357b253502c94cd7cb6622c22423287225b4b657dKenny Root        ASN1ObjectIdentifier oid,
17457b253502c94cd7cb6622c22423287225b4b657dKenny Root        boolean isCritical,
17557b253502c94cd7cb6622c22423287225b4b657dKenny Root        X509CertificateHolder certHolder)
17657b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
17757b253502c94cd7cb6622c22423287225b4b657dKenny Root        Certificate cert = certHolder.toASN1Structure();
17857b253502c94cd7cb6622c22423287225b4b657dKenny Root
17957b253502c94cd7cb6622c22423287225b4b657dKenny Root        Extension extension = cert.getTBSCertificate().getExtensions().getExtension(oid);
18057b253502c94cd7cb6622c22423287225b4b657dKenny Root
18157b253502c94cd7cb6622c22423287225b4b657dKenny Root        if (extension == null)
18257b253502c94cd7cb6622c22423287225b4b657dKenny Root        {
18357b253502c94cd7cb6622c22423287225b4b657dKenny Root            throw new NullPointerException("extension " + oid + " not present");
18457b253502c94cd7cb6622c22423287225b4b657dKenny Root        }
18557b253502c94cd7cb6622c22423287225b4b657dKenny Root
18657b253502c94cd7cb6622c22423287225b4b657dKenny Root        extGenerator.addExtension(oid, isCritical, extension.getExtnValue().getOctets());
18757b253502c94cd7cb6622c22423287225b4b657dKenny Root
18857b253502c94cd7cb6622c22423287225b4b657dKenny Root        return this;
18957b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
19057b253502c94cd7cb6622c22423287225b4b657dKenny Root
19157b253502c94cd7cb6622c22423287225b4b657dKenny Root    /**
19257b253502c94cd7cb6622c22423287225b4b657dKenny Root     * Generate an X.509 certificate, based on the current issuer and subject
19357b253502c94cd7cb6622c22423287225b4b657dKenny Root     * using the passed in signer.
19457b253502c94cd7cb6622c22423287225b4b657dKenny Root     *
19557b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @param signer the content signer to be used to generate the signature validating the certificate.
19657b253502c94cd7cb6622c22423287225b4b657dKenny Root     * @return a holder containing the resulting signed certificate.
19757b253502c94cd7cb6622c22423287225b4b657dKenny Root     */
19857b253502c94cd7cb6622c22423287225b4b657dKenny Root    public X509CertificateHolder build(
19957b253502c94cd7cb6622c22423287225b4b657dKenny Root        ContentSigner signer)
20057b253502c94cd7cb6622c22423287225b4b657dKenny Root    {
20157b253502c94cd7cb6622c22423287225b4b657dKenny Root        tbsGen.setSignature(signer.getAlgorithmIdentifier());
20257b253502c94cd7cb6622c22423287225b4b657dKenny Root
20357b253502c94cd7cb6622c22423287225b4b657dKenny Root        if (!extGenerator.isEmpty())
20457b253502c94cd7cb6622c22423287225b4b657dKenny Root        {
20557b253502c94cd7cb6622c22423287225b4b657dKenny Root            tbsGen.setExtensions(extGenerator.generate());
20657b253502c94cd7cb6622c22423287225b4b657dKenny Root        }
20757b253502c94cd7cb6622c22423287225b4b657dKenny Root
20857b253502c94cd7cb6622c22423287225b4b657dKenny Root        return CertUtils.generateFullCert(signer, tbsGen.generateTBSCertificate());
20957b253502c94cd7cb6622c22423287225b4b657dKenny Root    }
21057b253502c94cd7cb6622c22423287225b4b657dKenny Root}