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}