001: package org.bouncycastle.voms;
002:
003: import org.bouncycastle.asn1.ASN1OctetString;
004: import org.bouncycastle.asn1.ASN1Sequence;
005: import org.bouncycastle.asn1.DERIA5String;
006: import org.bouncycastle.asn1.x509.GeneralName;
007: import org.bouncycastle.asn1.x509.IetfAttrSyntax;
008: import org.bouncycastle.x509.X509Attribute;
009: import org.bouncycastle.x509.X509AttributeCertificate;
010:
011: import java.util.List;
012: import java.util.Vector;
013:
014: /**
015: * Representation of the authorization information (VO, server address
016: * and list of Fully Qualified Attribute Names, or FQANs) contained in
017: * a VOMS attribute certificate.
018: */
019: public class VOMSAttribute {
020:
021: /**
022: * The ASN.1 object identifier for VOMS attributes
023: */
024: public static final String VOMS_ATTR_OID = "1.3.6.1.4.1.8005.100.100.4";
025: private X509AttributeCertificate myAC;
026: private String myHostPort;
027: private String myVo;
028: private Vector myStringList = new Vector();
029: private Vector myFQANs = new Vector();
030:
031: /**
032: * Parses the contents of an attribute certificate.<br>
033: * <b>NOTE:</b> Cryptographic signatures, time stamps etc. will <b>not</b> be checked.
034: *
035: * @param ac the attribute certificate to parse for VOMS attributes
036: */
037: public VOMSAttribute(X509AttributeCertificate ac) {
038: if (ac == null) {
039: throw new IllegalArgumentException(
040: "VOMSAttribute: AttributeCertificate is NULL");
041: }
042:
043: myAC = ac;
044:
045: X509Attribute[] l = ac.getAttributes(VOMS_ATTR_OID);
046:
047: if (l == null) {
048: return;
049: }
050:
051: try {
052: for (int i = 0; i != l.length; i++) {
053: IetfAttrSyntax attr = new IetfAttrSyntax(
054: (ASN1Sequence) l[i].getValues()[0]);
055:
056: // policyAuthority is on the format <vo>/<host>:<port>
057: String url = ((DERIA5String) GeneralName.getInstance(
058: ((ASN1Sequence) attr.getPolicyAuthority()
059: .getDERObject()).getObjectAt(0))
060: .getName()).getString();
061: int idx = url.indexOf("://");
062:
063: if ((idx < 0) || (idx == (url.length() - 1))) {
064: throw new IllegalArgumentException(
065: "Bad encoding of VOMS policyAuthority : ["
066: + url + "]");
067: }
068:
069: myVo = url.substring(0, idx);
070: myHostPort = url.substring(idx + 3);
071:
072: if (attr.getValueType() != IetfAttrSyntax.VALUE_OCTETS) {
073: throw new IllegalArgumentException(
074: "VOMS attribute values are not encoded as octet strings, policyAuthority = "
075: + url);
076: }
077:
078: ASN1OctetString[] values = (ASN1OctetString[]) attr
079: .getValues();
080: for (int j = 0; j != values.length; j++) {
081: String fqan = new String(values[j].getOctets());
082: FQAN f = new FQAN(fqan);
083:
084: if (!myStringList.contains(fqan)
085: && fqan.startsWith("/" + myVo + "/")) {
086: myStringList.add(fqan);
087: myFQANs.add(f);
088: }
089: }
090: }
091: } catch (IllegalArgumentException ie) {
092: throw ie;
093: } catch (Exception e) {
094: throw new IllegalArgumentException(
095: "Badly encoded VOMS extension in AC issued by "
096: + ac.getIssuer());
097: }
098: }
099:
100: /**
101: * @return The AttributeCertificate containing the VOMS information
102: */
103: public X509AttributeCertificate getAC() {
104: return myAC;
105: }
106:
107: /**
108: * @return List of String of the VOMS fully qualified
109: * attributes names (FQANs):<br>
110: * <code>/vo[/group[/group2...]][/Role=[role]][/Capability=capability]</code>
111: */
112: public List getFullyQualifiedAttributes() {
113: return myStringList;
114: }
115:
116: /**
117: * @return List of FQAN of the VOMS fully qualified
118: * attributes names (FQANs)
119: * @see #FQAN
120: */
121: public List getListOfFQAN() {
122: return myFQANs;
123: }
124:
125: /**
126: * Returns the address of the issuing VOMS server, on the form <code><host>:<port></code>
127: * @return String
128: */
129: public String getHostPort() {
130: return myHostPort;
131: }
132:
133: /**
134: * Returns the VO name
135: * @return
136: */
137: public String getVO() {
138: return myVo;
139: }
140:
141: public String toString() {
142: return "VO :" + myVo + "\n" + "HostPort:" + myHostPort
143: + "\n" + "FQANs :" + myFQANs;
144: }
145:
146: /**
147: * Inner class providing a container of the group,role,capability
148: * information triplet in an FQAN.
149: */
150: public class FQAN {
151: String fqan;
152: String group;
153: String role;
154: String capability;
155:
156: public FQAN(String fqan) {
157: this .fqan = fqan;
158: }
159:
160: public FQAN(String group, String role, String capability) {
161: this .group = group;
162: this .role = role;
163: this .capability = capability;
164: }
165:
166: public String getFQAN() {
167: if (fqan != null) {
168: return fqan;
169: }
170:
171: fqan = group
172: + "/Role="
173: + ((role != null) ? role : "")
174: + ((capability != null) ? ("/Capability=" + capability)
175: : "");
176:
177: return fqan;
178: }
179:
180: protected void split() {
181: int len = fqan.length();
182: int i = fqan.indexOf("/Role=");
183:
184: if (i < 0) {
185: return;
186: }
187:
188: group = fqan.substring(0, i);
189:
190: int j = fqan.indexOf("/Capability=", i + 6);
191: String s = (j < 0) ? fqan.substring(i + 6) : fqan
192: .substring(i + 6, j);
193: role = (s.length() == 0) ? null : s;
194: s = (j < 0) ? null : fqan.substring(j + 12);
195: capability = ((s == null) || (s.length() == 0)) ? null : s;
196: }
197:
198: public String getGroup() {
199: if ((group == null) && (fqan != null)) {
200: split();
201: }
202:
203: return group;
204: }
205:
206: public String getRole() {
207: if ((group == null) && (fqan != null)) {
208: split();
209: }
210:
211: return role;
212: }
213:
214: public String getCapability() {
215: if ((group == null) && (fqan != null)) {
216: split();
217: }
218:
219: return capability;
220: }
221:
222: public String toString() {
223: return getFQAN();
224: }
225: }
226: }
|