001package org.apache.commons.ssl.org.bouncycastle.asn1.isismtt.x509; 002 003import java.util.Enumeration; 004 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 009import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence; 010import org.apache.commons.ssl.org.bouncycastle.asn1.x509.GeneralName; 011 012/** 013 * Attribute to indicate admissions to certain professions. 014 * 015 * <pre> 016 * AdmissionSyntax ::= SEQUENCE 017 * { 018 * admissionAuthority GeneralName OPTIONAL, 019 * contentsOfAdmissions SEQUENCE OF Admissions 020 * } 021 * 022 * Admissions ::= SEQUENCE 023 * { 024 * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL 025 * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL 026 * professionInfos SEQUENCE OF ProfessionInfo 027 * } 028 * 029 * NamingAuthority ::= SEQUENCE 030 * { 031 * namingAuthorityId OBJECT IDENTIFIER OPTIONAL, 032 * namingAuthorityUrl IA5String OPTIONAL, 033 * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL 034 * } 035 * 036 * ProfessionInfo ::= SEQUENCE 037 * { 038 * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL, 039 * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)), 040 * professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL, 041 * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL, 042 * addProfessionInfo OCTET STRING OPTIONAL 043 * } 044 * </pre> 045 * <p> 046 * ISIS-MTT PROFILE: The relatively complex structure of AdmissionSyntax 047 * supports the following concepts and requirements: 048 * <ul> 049 * <li> External institutions (e.g. professional associations, chambers, unions, 050 * administrative bodies, companies, etc.), which are responsible for granting 051 * and verifying professional admissions, are indicated by means of the data 052 * field admissionAuthority. An admission authority is indicated by a 053 * GeneralName object. Here an X.501 directory name (distinguished name) can be 054 * indicated in the field directoryName, a URL address can be indicated in the 055 * field uniformResourceIdentifier, and an object identifier can be indicated in 056 * the field registeredId. 057 * <li> The names of authorities which are responsible for the administration of 058 * title registers are indicated in the data field namingAuthority. The name of 059 * the authority can be identified by an object identifier in the field 060 * namingAuthorityId, by means of a text string in the field 061 * namingAuthorityText, by means of a URL address in the field 062 * namingAuthorityUrl, or by a combination of them. For example, the text string 063 * can contain the name of the authority, the country and the name of the title 064 * register. The URL-option refers to a web page which contains lists with 065 * �officially� registered professions (text and possibly OID) as well as 066 * further information on these professions. Object identifiers for the 067 * component namingAuthorityId are grouped under the OID-branch 068 * id-isis-at-namingAuthorities and must be applied for. 069 * <li>See 070 * http://www.teletrust.de/anwend.asp?Id=30200&Sprache=E_&HomePG=0 for 071 * an application form and http://www.teletrust.de/links.asp?id=30220,11 072 * for an overview of registered naming authorities. 073 * <li> By means of the data type ProfessionInfo certain professions, 074 * specializations, disciplines, fields of activity, etc. are identified. A 075 * profession is represented by one or more text strings, resp. profession OIDs 076 * in the fields professionItems and professionOIDs and by a registration number 077 * in the field registrationNumber. An indication in text form must always be 078 * present, whereas the other indications are optional. The component 079 * addProfessionInfo may contain additional applicationspecific information in 080 * DER-encoded form. 081 * </ul> 082 * <p> 083 * By means of different namingAuthority-OIDs or profession OIDs hierarchies of 084 * professions, specializations, disciplines, fields of activity, etc. can be 085 * expressed. The issuing admission authority should always be indicated (field 086 * admissionAuthority), whenever a registration number is presented. Still, 087 * information on admissions can be given without indicating an admission or a 088 * naming authority by the exclusive use of the component professionItems. In 089 * this case the certification authority is responsible for the verification of 090 * the admission information. 091 * <p> 092 * This attribute is single-valued. Still, several admissions can be captured in 093 * the sequence structure of the component contentsOfAdmissions of 094 * AdmissionSyntax or in the component professionInfos of Admissions. The 095 * component admissionAuthority of AdmissionSyntax serves as default value for 096 * the component admissionAuthority of Admissions. Within the latter component 097 * the default value can be overwritten, in case that another authority is 098 * responsible. The component namingAuthority of Admissions serves as a default 099 * value for the component namingAuthority of ProfessionInfo. Within the latter 100 * component the default value can be overwritten, in case that another naming 101 * authority needs to be recorded. 102 * <p> 103 * The length of the string objects is limited to 128 characters. It is 104 * recommended to indicate a namingAuthorityURL in all issued attribute 105 * certificates. If a namingAuthorityURL is indicated, the field professionItems 106 * of ProfessionInfo should contain only registered titles. If the field 107 * professionOIDs exists, it has to contain the OIDs of the professions listed 108 * in professionItems in the same order. In general, the field professionInfos 109 * should contain only one entry, unless the admissions that are to be listed 110 * are logically connected (e.g. they have been issued under the same admission 111 * number). 112 * 113 * @see org.bouncycastle.asn1.isismtt.x509.Admissions 114 * @see org.bouncycastle.asn1.isismtt.x509.ProfessionInfo 115 * @see org.bouncycastle.asn1.isismtt.x509.NamingAuthority 116 */ 117public class AdmissionSyntax 118 extends ASN1Object 119{ 120 121 private GeneralName admissionAuthority; 122 123 private ASN1Sequence contentsOfAdmissions; 124 125 public static AdmissionSyntax getInstance(Object obj) 126 { 127 if (obj == null || obj instanceof AdmissionSyntax) 128 { 129 return (AdmissionSyntax)obj; 130 } 131 132 if (obj instanceof ASN1Sequence) 133 { 134 return new AdmissionSyntax((ASN1Sequence)obj); 135 } 136 137 throw new IllegalArgumentException("illegal object in getInstance: " 138 + obj.getClass().getName()); 139 } 140 141 /** 142 * Constructor from ASN1Sequence. 143 * <p> 144 * The sequence is of type ProcurationSyntax: 145 * <pre> 146 * AdmissionSyntax ::= SEQUENCE 147 * { 148 * admissionAuthority GeneralName OPTIONAL, 149 * contentsOfAdmissions SEQUENCE OF Admissions 150 * } 151 * 152 * Admissions ::= SEQUENCE 153 * { 154 * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL 155 * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL 156 * professionInfos SEQUENCE OF ProfessionInfo 157 * } 158 * 159 * NamingAuthority ::= SEQUENCE 160 * { 161 * namingAuthorityId OBJECT IDENTIFIER OPTIONAL, 162 * namingAuthorityUrl IA5String OPTIONAL, 163 * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL 164 * } 165 * 166 * ProfessionInfo ::= SEQUENCE 167 * { 168 * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL, 169 * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)), 170 * professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL, 171 * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL, 172 * addProfessionInfo OCTET STRING OPTIONAL 173 * } 174 * </pre> 175 * </p> 176 * @param seq The ASN.1 sequence. 177 */ 178 private AdmissionSyntax(ASN1Sequence seq) 179 { 180 switch (seq.size()) 181 { 182 case 1: 183 contentsOfAdmissions = DERSequence.getInstance(seq.getObjectAt(0)); 184 break; 185 case 2: 186 admissionAuthority = GeneralName.getInstance(seq.getObjectAt(0)); 187 contentsOfAdmissions = DERSequence.getInstance(seq.getObjectAt(1)); 188 break; 189 default: 190 throw new IllegalArgumentException("Bad sequence size: " + seq.size()); 191 } 192 } 193 194 /** 195 * Constructor from given details. 196 * 197 * @param admissionAuthority The admission authority. 198 * @param contentsOfAdmissions The admissions. 199 */ 200 public AdmissionSyntax(GeneralName admissionAuthority, ASN1Sequence contentsOfAdmissions) 201 { 202 this.admissionAuthority = admissionAuthority; 203 this.contentsOfAdmissions = contentsOfAdmissions; 204 } 205 206 /** 207 * Produce an object suitable for an ASN1OutputStream. 208 * <p> 209 * Returns: 210 * <pre> 211 * AdmissionSyntax ::= SEQUENCE 212 * { 213 * admissionAuthority GeneralName OPTIONAL, 214 * contentsOfAdmissions SEQUENCE OF Admissions 215 * } 216 * 217 * Admissions ::= SEQUENCE 218 * { 219 * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL 220 * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL 221 * professionInfos SEQUENCE OF ProfessionInfo 222 * } 223 * 224 * NamingAuthority ::= SEQUENCE 225 * { 226 * namingAuthorityId OBJECT IDENTIFIER OPTIONAL, 227 * namingAuthorityUrl IA5String OPTIONAL, 228 * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL 229 * } 230 * 231 * ProfessionInfo ::= SEQUENCE 232 * { 233 * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL, 234 * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)), 235 * professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL, 236 * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL, 237 * addProfessionInfo OCTET STRING OPTIONAL 238 * } 239 * </pre> 240 * 241 * @return a DERObject 242 */ 243 public ASN1Primitive toASN1Primitive() 244 { 245 ASN1EncodableVector vec = new ASN1EncodableVector(); 246 if (admissionAuthority != null) 247 { 248 vec.add(admissionAuthority); 249 } 250 vec.add(contentsOfAdmissions); 251 return new DERSequence(vec); 252 } 253 254 /** 255 * @return Returns the admissionAuthority if present, null otherwise. 256 */ 257 public GeneralName getAdmissionAuthority() 258 { 259 return admissionAuthority; 260 } 261 262 /** 263 * @return Returns the contentsOfAdmissions. 264 */ 265 public Admissions[] getContentsOfAdmissions() 266 { 267 Admissions[] admissions = new Admissions[contentsOfAdmissions.size()]; 268 int count = 0; 269 for (Enumeration e = contentsOfAdmissions.getObjects(); e.hasMoreElements();) 270 { 271 admissions[count++] = Admissions.getInstance(e.nextElement()); 272 } 273 return admissions; 274 } 275}