1 package org.bouncycastle.asn1.pkcs; 2 3 import org.bouncycastle.asn1.ASN1EncodableVector; 4 import org.bouncycastle.asn1.ASN1Integer; 5 import org.bouncycastle.asn1.ASN1Object; 6 import org.bouncycastle.asn1.ASN1Primitive; 7 import org.bouncycastle.asn1.ASN1Sequence; 8 import org.bouncycastle.asn1.ASN1Set; 9 import org.bouncycastle.asn1.DERSequence; 10 import org.bouncycastle.asn1.DERTaggedObject; 11 import org.bouncycastle.asn1.x500.X500Name; 12 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 13 import org.bouncycastle.asn1.x509.X509Name; 14 15 /** 16 * PKCS10 CertificationRequestInfo object. 17 * <pre> 18 * CertificationRequestInfo ::= SEQUENCE { 19 * version INTEGER { v1(0) } (v1,...), 20 * subject Name, 21 * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, 22 * attributes [0] Attributes{{ CRIAttributes }} 23 * } 24 * 25 * Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }} 26 * 27 * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE { 28 * type ATTRIBUTE.&id({IOSet}), 29 * values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type}) 30 * } 31 * </pre> 32 */ 33 public class CertificationRequestInfo 34 extends ASN1Object 35 { 36 ASN1Integer version = new ASN1Integer(0); 37 X500Name subject; 38 SubjectPublicKeyInfo subjectPKInfo; 39 ASN1Set attributes = null; 40 getInstance( Object obj)41 public static CertificationRequestInfo getInstance( 42 Object obj) 43 { 44 if (obj instanceof CertificationRequestInfo) 45 { 46 return (CertificationRequestInfo)obj; 47 } 48 else if (obj != null) 49 { 50 return new CertificationRequestInfo(ASN1Sequence.getInstance(obj)); 51 } 52 53 return null; 54 } 55 56 /** 57 * Basic constructor. 58 * <p> 59 * Note: Early on a lot of CAs would only accept messages with attributes missing. As the ASN.1 def shows 60 * the attributes field is not optional so should always at least contain an empty set. If a fully compliant 61 * request is required, pass in an empty set, the class will otherwise interpret a null as it should 62 * encode the request with the field missing. 63 * </p> 64 * 65 * @param subject subject to be associated with the public key 66 * @param pkInfo public key to be associated with subject 67 * @param attributes any attributes to be associated with the request. 68 */ CertificationRequestInfo( X500Name subject, SubjectPublicKeyInfo pkInfo, ASN1Set attributes)69 public CertificationRequestInfo( 70 X500Name subject, 71 SubjectPublicKeyInfo pkInfo, 72 ASN1Set attributes) 73 { 74 if ((subject == null) || (pkInfo == null)) 75 { 76 throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); 77 } 78 79 this.subject = subject; 80 this.subjectPKInfo = pkInfo; 81 this.attributes = attributes; 82 } 83 84 /** 85 * @deprecated use X500Name method. 86 */ CertificationRequestInfo( X509Name subject, SubjectPublicKeyInfo pkInfo, ASN1Set attributes)87 public CertificationRequestInfo( 88 X509Name subject, 89 SubjectPublicKeyInfo pkInfo, 90 ASN1Set attributes) 91 { 92 if ((subject == null) || (pkInfo == null)) 93 { 94 throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); 95 } 96 97 this.subject = X500Name.getInstance(subject.toASN1Primitive()); 98 this.subjectPKInfo = pkInfo; 99 this.attributes = attributes; 100 } 101 102 /** 103 * @deprecated use getInstance(). 104 */ CertificationRequestInfo( ASN1Sequence seq)105 public CertificationRequestInfo( 106 ASN1Sequence seq) 107 { 108 version = (ASN1Integer)seq.getObjectAt(0); 109 110 subject = X500Name.getInstance(seq.getObjectAt(1)); 111 subjectPKInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(2)); 112 113 // 114 // some CertificationRequestInfo objects seem to treat this field 115 // as optional. 116 // 117 if (seq.size() > 3) 118 { 119 DERTaggedObject tagobj = (DERTaggedObject)seq.getObjectAt(3); 120 attributes = ASN1Set.getInstance(tagobj, false); 121 } 122 123 if ((subject == null) || (version == null) || (subjectPKInfo == null)) 124 { 125 throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); 126 } 127 } 128 getVersion()129 public ASN1Integer getVersion() 130 { 131 return version; 132 } 133 getSubject()134 public X500Name getSubject() 135 { 136 return subject; 137 } 138 getSubjectPublicKeyInfo()139 public SubjectPublicKeyInfo getSubjectPublicKeyInfo() 140 { 141 return subjectPKInfo; 142 } 143 getAttributes()144 public ASN1Set getAttributes() 145 { 146 return attributes; 147 } 148 toASN1Primitive()149 public ASN1Primitive toASN1Primitive() 150 { 151 ASN1EncodableVector v = new ASN1EncodableVector(); 152 153 v.add(version); 154 v.add(subject); 155 v.add(subjectPKInfo); 156 157 if (attributes != null) 158 { 159 v.add(new DERTaggedObject(false, 0, attributes)); 160 } 161 162 return new DERSequence(v); 163 } 164 } 165