org.bouncycastle.cert.CertUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcpkix-debug-jdk18on Show documentation
Show all versions of bcpkix-debug-jdk18on Show documentation
The Bouncy Castle Java APIs for CMS, PKCS, EAC, TSP, CMP, CRMF, OCSP, and certificate generation. This jar contains APIs for JDK 1.8 and up. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs.
The newest version!
package org.bouncycastle.cert;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.AttributeCertificate;
import org.bouncycastle.asn1.x509.AttributeCertificateInfo;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.CertificateList;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.TBSCertList;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.util.Properties;
class CertUtils
{
private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet());
private static List EMPTY_LIST = Collections.unmodifiableList(new ArrayList());
static ASN1Primitive parseNonEmptyASN1(byte[] encoding)
throws IOException
{
ASN1Primitive p = ASN1Primitive.fromByteArray(encoding);
if (p == null)
{
throw new IOException("no content found");
}
return p;
}
static X509CertificateHolder generateFullCert(ContentSigner signer, TBSCertificate tbsCert)
{
try
{
return new X509CertificateHolder(generateStructure(tbsCert, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCert)));
}
catch (IOException e)
{
throw new IllegalStateException("cannot produce certificate signature");
}
}
static X509AttributeCertificateHolder generateFullAttrCert(ContentSigner signer, AttributeCertificateInfo attrInfo)
{
try
{
return new X509AttributeCertificateHolder(generateAttrStructure(attrInfo, signer.getAlgorithmIdentifier(), generateSig(signer, attrInfo)));
}
catch (IOException e)
{
throw new IllegalStateException("cannot produce attribute certificate signature");
}
}
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));
}
private static AttributeCertificate generateAttrStructure(AttributeCertificateInfo attrInfo, AlgorithmIdentifier sigAlgId, byte[] signature)
{
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(attrInfo);
v.add(sigAlgId);
v.add(new DERBitString(signature));
return AttributeCertificate.getInstance(new DERSequence(v));
}
private static CertificateList generateCRLStructure(TBSCertList tbsCertList, AlgorithmIdentifier sigAlgId, byte[] signature)
{
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(tbsCertList);
v.add(sigAlgId);
v.add(new DERBitString(signature));
return CertificateList.getInstance(new DERSequence(v));
}
static Set getCriticalExtensionOIDs(Extensions extensions)
{
if (extensions == null)
{
return EMPTY_SET;
}
return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getCriticalExtensionOIDs())));
}
static Set getNonCriticalExtensionOIDs(Extensions extensions)
{
if (extensions == null)
{
return EMPTY_SET;
}
// TODO: should probably produce a set that imposes correct ordering
return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getNonCriticalExtensionOIDs())));
}
static List getExtensionOIDs(Extensions extensions)
{
if (extensions == null)
{
return EMPTY_LIST;
}
return Collections.unmodifiableList(Arrays.asList(extensions.getExtensionOIDs()));
}
static void addExtension(ExtensionsGenerator extGenerator, 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);
}
}
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);
}
}
static boolean[] bitStringToBoolean(ASN1BitString bitString)
{
if (bitString != null)
{
byte[] bytes = bitString.getBytes();
boolean[] boolId = new boolean[bytes.length * 8 - bitString.getPadBits()];
for (int i = 0; i != boolId.length; i++)
{
boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
}
return boolId;
}
return null;
}
static Date recoverDate(ASN1GeneralizedTime time)
{
try
{
return time.getDate();
}
catch (ParseException e)
{
throw new IllegalStateException("unable to recover date: " + e.getMessage());
}
}
static boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
{
if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
{
return false;
}
if (Properties.isOverrideSet("org.bouncycastle.x509.allow_absent_equiv_NULL"))
{
if (id1.getParameters() == null)
{
if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
{
return false;
}
return true;
}
if (id2.getParameters() == null)
{
if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
{
return false;
}
return true;
}
}
if (id1.getParameters() != null)
{
return id1.getParameters().equals(id2.getParameters());
}
if (id2.getParameters() != null)
{
return id2.getParameters().equals(id1.getParameters());
}
return true;
}
static ExtensionsGenerator doReplaceExtension(ExtensionsGenerator extGenerator, Extension ext)
{
boolean isReplaced = false;
Extensions exts = extGenerator.generate();
extGenerator = new ExtensionsGenerator();
for (Enumeration en = exts.oids(); en.hasMoreElements(); )
{
ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
if (extOid.equals(ext.getExtnId()))
{
isReplaced = true;
extGenerator.addExtension(ext);
}
else
{
extGenerator.addExtension(exts.getExtension(extOid));
}
}
if (!isReplaced)
{
throw new IllegalArgumentException("replace - original extension (OID = " + ext.getExtnId() + ") not found");
}
return extGenerator;
}
static ExtensionsGenerator doRemoveExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid)
{
boolean isRemoved = false;
Extensions exts = extGenerator.generate();
extGenerator = new ExtensionsGenerator();
for (Enumeration en = exts.oids(); en.hasMoreElements(); )
{
ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
if (extOid.equals(oid))
{
isRemoved = true;
}
else
{
extGenerator.addExtension(exts.getExtension(extOid));
}
}
if (!isRemoved)
{
throw new IllegalArgumentException("remove - extension (OID = " + oid + ") not found");
}
return extGenerator;
}
private static byte[] generateSig(ContentSigner signer, ASN1Object tbsObj)
throws IOException
{
OutputStream sOut = signer.getOutputStream();
tbsObj.encodeTo(sOut, ASN1Encoding.DER);
sOut.close();
return signer.getSignature();
}
static ASN1TaggedObject trimExtensions(int tagNo, Extensions exts)
{
ASN1Sequence extSeq = ASN1Sequence.getInstance(exts.toASN1Primitive());
ASN1EncodableVector extV = new ASN1EncodableVector();
for (int i = 0; i != extSeq.size(); i++)
{
ASN1Sequence ext = ASN1Sequence.getInstance(extSeq.getObjectAt(i));
if (!Extension.altSignatureValue.equals(ext.getObjectAt(0)))
{
extV.add(ext);
}
}
return new DERTaggedObject(true, tagNo, new DERSequence(extV));
}
}