diff options
Diffstat (limited to 'repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java')
-rw-r--r-- | repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java new file mode 100644 index 00000000..cd446d09 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java @@ -0,0 +1,423 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cert; + +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigInteger; +import java.util.Date; +import java.util.Enumeration; +import java.util.Locale; + +import com.android.internal.org.bouncycastle.asn1.ASN1Encodable; +import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector; +import com.android.internal.org.bouncycastle.asn1.ASN1Encoding; +import com.android.internal.org.bouncycastle.asn1.ASN1Integer; +import com.android.internal.org.bouncycastle.asn1.ASN1Object; +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.DERBitString; +import com.android.internal.org.bouncycastle.asn1.DERSequence; +import com.android.internal.org.bouncycastle.asn1.x500.X500Name; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import com.android.internal.org.bouncycastle.asn1.x509.Certificate; +import com.android.internal.org.bouncycastle.asn1.x509.Extension; +import com.android.internal.org.bouncycastle.asn1.x509.Extensions; +import com.android.internal.org.bouncycastle.asn1.x509.ExtensionsGenerator; +import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificate; +import com.android.internal.org.bouncycastle.asn1.x509.Time; +import com.android.internal.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; +import com.android.internal.org.bouncycastle.operator.ContentSigner; + + +/** + * class to produce an X.509 Version 3 certificate. + * @hide This class is not part of the Android public SDK API + */ +public class X509v3CertificateBuilder +{ + private V3TBSCertificateGenerator tbsGen; + private ExtensionsGenerator extGenerator; + + /** + * Create a builder for a version 3 certificate. + * + * @param issuer the certificate issuer + * @param serial the certificate serial number + * @param notBefore the date before which the certificate is not valid + * @param notAfter the date after which the certificate is not valid + * @param subject the certificate subject + * @param publicKeyInfo the info structure for the public key to be associated with this certificate. + */ + public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) + { + this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo); + } + + /** + * Create a builder for a version 3 certificate. You may need to use this constructor if the default locale + * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations. + * + * @param issuer the certificate issuer + * @param serial the certificate serial number + * @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. + * @param subject the certificate subject + * @param publicKeyInfo the info structure for the public key to be associated with this certificate. + */ + public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, Locale dateLocale, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) + { + this(issuer, serial, new Time(notBefore, dateLocale), new Time(notAfter, dateLocale), subject, publicKeyInfo); + } + + /** + * Create a builder for a version 3 certificate. + * + * @param issuer the certificate issuer + * @param serial the certificate serial number + * @param notBefore the Time before which the certificate is not valid + * @param notAfter the Time after which the certificate is not valid + * @param subject the certificate subject + * @param publicKeyInfo the info structure for the public key to be associated with this certificate. + */ + public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) + { + tbsGen = new V3TBSCertificateGenerator(); + tbsGen.setSerialNumber(new ASN1Integer(serial)); + tbsGen.setIssuer(issuer); + tbsGen.setStartDate(notBefore); + tbsGen.setEndDate(notAfter); + tbsGen.setSubject(subject); + tbsGen.setSubjectPublicKeyInfo(publicKeyInfo); + + extGenerator = new ExtensionsGenerator(); + } + + /** + * Create a builder for a version 3 certificate, initialised with another certificate. + * + * @param template template certificate to base the new one on. + */ + public X509v3CertificateBuilder(X509CertificateHolder template) + { + tbsGen = new V3TBSCertificateGenerator(); + tbsGen.setSerialNumber(new ASN1Integer(template.getSerialNumber())); + tbsGen.setIssuer(template.getIssuer()); + tbsGen.setStartDate(new Time(template.getNotBefore())); + tbsGen.setEndDate(new Time(template.getNotAfter())); + tbsGen.setSubject(template.getSubject()); + tbsGen.setSubjectPublicKeyInfo(template.getSubjectPublicKeyInfo()); + + 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); + } + + /** + * Set the subjectUniqueID - note: it is very rare that it is correct to do this. + * + * @param uniqueID a boolean array representing the bits making up the subjectUniqueID. + * @return this builder object. + */ + public X509v3CertificateBuilder setSubjectUniqueID(boolean[] uniqueID) + { + tbsGen.setSubjectUniqueID(booleanToBitString(uniqueID)); + + return this; + } + + /** + * Set the issuerUniqueID - note: it is very rare that it is correct to do this. + * + * @param uniqueID a boolean array representing the bits making up the issuerUniqueID. + * @return this builder object. + */ + public X509v3CertificateBuilder setIssuerUniqueID(boolean[] uniqueID) + { + tbsGen.setIssuerUniqueID(booleanToBitString(uniqueID)); + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) + * + * @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 OID oid has already been used. + */ + public X509v3CertificateBuilder addExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + ASN1Encodable value) + throws CertIOException + { + try + { + extGenerator.addExtension(oid, isCritical, value); + } + catch (IOException e) + { + throw new CertIOException("cannot encode extension: " + e.getMessage(), e); + } + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3). + * + * @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 OID oid has already been used. + */ + public X509v3CertificateBuilder addExtension( + Extension extension) + throws CertIOException + { + extGenerator.addExtension(extension); + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) 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. + * @throws CertIOException if there is an issue with the new extension value. + * @throws IllegalArgumentException if the OID oid has already been allocated. + */ + public X509v3CertificateBuilder addExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + byte[] encodedValue) + throws CertIOException + { + extGenerator.addExtension(oid, isCritical, encodedValue); + + 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 X509v3CertificateBuilder 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 X509v3CertificateBuilder 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 X509v3CertificateBuilder 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 X509v3CertificateBuilder removeExtension(ASN1ObjectIdentifier oid) + { + extGenerator = CertUtils.doRemoveExtension(extGenerator, oid); + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) + * copying the extension value from another certificate. + * + * @param oid the OID defining the extension type. + * @param isCritical true if the copied extension is to be marked as critical, false otherwise. + * @param certHolder the holder for the certificate that the extension is to be copied from. + * @return this builder object. + */ + public X509v3CertificateBuilder copyAndAddExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + X509CertificateHolder certHolder) + { + Certificate cert = certHolder.toASN1Structure(); + + Extension extension = cert.getTBSCertificate().getExtensions().getExtension(oid); + + if (extension == null) + { + throw new NullPointerException("extension " + oid + " not present"); + } + + extGenerator.addExtension(oid, isCritical, extension.getExtnValue().getOctets()); + + return this; + } + + /** + * Generate an X.509 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 X509CertificateHolder build( + ContentSigner signer) + { + tbsGen.setSignature(signer.getAlgorithmIdentifier()); + + if (!extGenerator.isEmpty()) + { + tbsGen.setExtensions(extGenerator.generate()); + } + + try + { + TBSCertificate tbsCert = tbsGen.generateTBSCertificate(); + return new X509CertificateHolder(generateStructure(tbsCert, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCert))); + } + catch (IOException e) + { + throw new IllegalArgumentException("cannot produce certificate signature"); + } + } + + private static byte[] generateSig(ContentSigner signer, ASN1Object tbsObj) + throws IOException + { + OutputStream sOut = signer.getOutputStream(); + tbsObj.encodeTo(sOut, ASN1Encoding.DER); + sOut.close(); + + return signer.getSignature(); + } + + private static Certificate generateStructure(TBSCertificate tbsCert, AlgorithmIdentifier sigAlgId, byte[] signature) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(tbsCert); + v.add(sigAlgId); + v.add(new DERBitString(signature)); + + return Certificate.getInstance(new DERSequence(v)); + } + + static DERBitString booleanToBitString(boolean[] id) + { + byte[] bytes = new byte[(id.length + 7) / 8]; + + for (int i = 0; i != id.length; i++) + { + bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0; + } + + int pad = id.length % 8; + + if (pad == 0) + { + return new DERBitString(bytes); + } + else + { + return new DERBitString(bytes, 8 - pad); + } + } +}
\ No newline at end of file |