| 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; |
| |
| /** |
| * <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. |
| * |
| * @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); |
| } |
| } |
| } |