package org.bouncycastle.asn1.cmc;

import java.io.IOException;
import java.math.BigInteger;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;

  CertificationRequest ::= SEQUENCE {
    certificationRequestInfo  SEQUENCE {
      version                   INTEGER,
      subject                   Name,
      subjectPublicKeyInfo      SEQUENCE {
         algorithm                 AlgorithmIdentifier,
         subjectPublicKey          BIT STRING },
      attributes                [0] IMPLICIT SET OF Attribute },
   signatureAlgorithm        AlgorithmIdentifier,
   signature                 BIT STRING
 }
/** * <pre> * CertificationRequest ::= SEQUENCE { * certificationRequestInfo SEQUENCE { * version INTEGER, * subject Name, * subjectPublicKeyInfo SEQUENCE { * algorithm AlgorithmIdentifier, * subjectPublicKey BIT STRING }, * attributes [0] IMPLICIT SET OF Attribute }, * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING * } * </pre> */
public class CertificationRequest extends ASN1Object { private static final ASN1Integer ZERO = new ASN1Integer(0); private final CertificationRequestInfo certificationRequestInfo; private final AlgorithmIdentifier signatureAlgorithm; private final DERBitString signature; public CertificationRequest( X500Name subject, AlgorithmIdentifier subjectPublicAlgorithm, DERBitString subjectPublicKey, ASN1Set attributes, AlgorithmIdentifier signatureAlgorithm, DERBitString signature) { this.certificationRequestInfo = new CertificationRequestInfo(subject, subjectPublicAlgorithm, subjectPublicKey, attributes); this.signatureAlgorithm = signatureAlgorithm; this.signature = signature; } private CertificationRequest(ASN1Sequence seq) { if (seq.size() != 3) { throw new IllegalArgumentException("incorrect sequence size"); } this.certificationRequestInfo = new CertificationRequestInfo(ASN1Sequence.getInstance(seq.getObjectAt(0))); this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); this.signature = DERBitString.getInstance(seq.getObjectAt(2)); } public static CertificationRequest getInstance(Object o) { if (o instanceof CertificationRequest) { return (CertificationRequest)o; } if (o != null) { return new CertificationRequest(ASN1Sequence.getInstance(o)); } return null; } public BigInteger getVersion() { return certificationRequestInfo.getVersion().getValue(); } public X500Name getSubject() { return certificationRequestInfo.getSubject(); } public ASN1Set getAttributes() { return certificationRequestInfo.getAttributes(); } public AlgorithmIdentifier getSubjectPublicKeyAlgorithm() { return AlgorithmIdentifier.getInstance(certificationRequestInfo.getSubjectPublicKeyInfo().getObjectAt(0)); } public DERBitString getSubjectPublicKey() { return DERBitString.getInstance(certificationRequestInfo.getSubjectPublicKeyInfo().getObjectAt(1)); }
If the public key is an encoded object this will return the ASN.1 primitives encoded - if the bitstring can't be decoded this routine throws an IOException.
Throws:
  • IOException – - if the bit string doesn't represent a DER encoded object.
Returns:the public key as an ASN.1 primitive.
/** * If the public key is an encoded object this will return the ASN.1 primitives encoded - if the bitstring * can't be decoded this routine throws an IOException. * * @exception IOException - if the bit string doesn't represent a DER encoded object. * @return the public key as an ASN.1 primitive. */
public ASN1Primitive parsePublicKey() throws IOException { return ASN1Primitive.fromByteArray(getSubjectPublicKey().getOctets()); } public AlgorithmIdentifier getSignatureAlgorithm() { return signatureAlgorithm; } public DERBitString getSignature() { return signature; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certificationRequestInfo); v.add(signatureAlgorithm); v.add(signature); return new DERSequence(v); } private class CertificationRequestInfo extends ASN1Object { private final ASN1Integer version; private final X500Name subject; private final ASN1Sequence subjectPublicKeyInfo; private final ASN1Set attributes; private CertificationRequestInfo( ASN1Sequence seq) { if (seq.size() != 4) { throw new IllegalArgumentException("incorrect sequence size for CertificationRequestInfo"); } version = ASN1Integer.getInstance(seq.getObjectAt(0)); subject = X500Name.getInstance(seq.getObjectAt(1)); subjectPublicKeyInfo = ASN1Sequence.getInstance(seq.getObjectAt(2)); if (subjectPublicKeyInfo.size() != 2) { throw new IllegalArgumentException("incorrect subjectPublicKeyInfo size for CertificationRequestInfo"); } ASN1TaggedObject tagobj = (ASN1TaggedObject)seq.getObjectAt(3); if (tagobj.getTagNo() != 0) { throw new IllegalArgumentException("incorrect tag number on attributes for CertificationRequestInfo"); } attributes = ASN1Set.getInstance(tagobj, false); } private CertificationRequestInfo(X500Name subject, AlgorithmIdentifier algorithm, DERBitString subjectPublicKey, ASN1Set attributes) { this.version = ZERO; this.subject = subject; this.subjectPublicKeyInfo = new DERSequence(new ASN1Encodable[] { algorithm, subjectPublicKey }); this.attributes = attributes; } private ASN1Integer getVersion() { return version; } private X500Name getSubject() { return subject; } private ASN1Sequence getSubjectPublicKeyInfo() { return subjectPublicKeyInfo; } private ASN1Set getAttributes() { return attributes; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(subject); v.add(subjectPublicKeyInfo); v.add(new DERTaggedObject(false, 0, attributes)); return new DERSequence(v); } } }