001: /*************************************************************************
002: * *
003: * EJBCA: The OpenSource Certificate Authority *
004: * *
005: * This software is free software; you can redistribute it and/or *
006: * modify it under the terms of the GNU Lesser General Public *
007: * License as published by the Free Software Foundation; either *
008: * version 2.1 of the License, or any later version. *
009: * *
010: * See terms of license at gnu.org. *
011: * *
012: *************************************************************************/package org.ejbca.core.model.authorization;
013:
014: import java.io.Serializable;
015: import java.security.cert.X509Certificate;
016: import java.util.regex.Pattern;
017:
018: import org.ejbca.util.CertTools;
019: import org.ejbca.util.StringTools;
020: import org.ejbca.util.dn.DNFieldExtractor;
021:
022: /**
023: * A class representing a admin entity. It can be set to match one admins dn or an entire organization by matching against o.
024: * The class main method is match() which takes a X509Certificate and tries to see if it fullfills set matching requirements.
025: *
026: * Matchwith constants points to which part of the certificate to match with.
027: * Matchtype constants tells under which contitions the match shall be performed.
028: *
029: * @author Philip Vendil
030: * @version $Id: AdminEntity.java,v 1.3 2007/01/03 14:34:10 anatom Exp $
031: */
032: public class AdminEntity implements Serializable, Comparable {
033: // Special Users. (Constants cannot have 0 value).
034: public static final int SPECIALADMIN_PUBLICWEBUSER = 2000;
035: public static final int SPECIALADMIN_CACOMMANDLINEADMIN = 2001;
036: public static final int SPECIALADMIN_RAADMIN = 2002;
037: public static final int SPECIALADMIN_BATCHCOMMANDLINEADMIN = 2003;
038: public static final int SPECIALADMIN_INTERNALUSER = 2004;
039: public static final int SPECIALADMIN_NOUSER = 2005;
040:
041: // Match type constants.
042: public static final int TYPE_EQUALCASE = 1000;
043: public static final int TYPE_EQUALCASEINS = 1001;
044: public static final int TYPE_NOT_EQUALCASE = 1002;
045: public static final int TYPE_NOT_EQUALCASEINS = 1003;
046:
047: // Match with constants.
048: // OBSERVE These constants is also used as a priority indicator for access rules.
049: // The higher values the higher priority.
050: public static final int WITH_COUNTRY = 1;
051: public static final int WITH_DOMAINCOMPONENT = 2;
052: public static final int WITH_STATE = 3;
053: public static final int WITH_LOCALE = 4;
054: public static final int WITH_ORGANIZATION = 5;
055: public static final int WITH_ORGANIZATIONUNIT = 6;
056: public static final int WITH_TITLE = 7;
057: public static final int WITH_COMMONNAME = 8;
058: public static final int WITH_UID = 9;
059: public static final int WITH_DNSERIALNUMBER = 10;
060: public static final int WITH_SERIALNUMBER = 11;
061:
062: private static final Pattern serialPattern = Pattern.compile(
063: "\\bSERIALNUMBER=", Pattern.CASE_INSENSITIVE);
064:
065: /** Creates a new instance of AdminEntity */
066: public AdminEntity(int matchwith, int matchtype, String matchvalue,
067: int caid) {
068: setMatchWith(matchwith);
069: setMatchType(matchtype);
070: setMatchValue(matchvalue);
071: this .caid = caid;
072: }
073:
074: public AdminEntity(int specialadmin) {
075: // FIXME this is a hack for now, to initialize explicitely attributes to some fixed values.
076: // I'm setting matchvalue to some arbitrary value as the schema does not support null
077: this (WITH_SERIALNUMBER, specialadmin, "UNUSED", 0);
078: }
079:
080: // Public methods.
081: /** Matches the given client X509Certificate to see if it matches it's requirements. */
082: public boolean match(AdminInformation admininformation) {
083: boolean returnvalue = false;
084:
085: if (admininformation.isSpecialUser()) {
086: if (this .matchtype == admininformation.getSpecialUser()) {
087: // There is a match of special admin return true;
088: returnvalue = true;
089: }
090: } else {
091: X509Certificate certificate = admininformation
092: .getX509Certificate();
093: String certstring = certificate.getSubjectDN().toString();
094: int admincaid = CertTools.getIssuerDN(certificate)
095: .hashCode(); // certificate.getIssuerDN().toString().hashCode();
096:
097: //String serialnumber = certificate.getSerialNumber().toString(16);
098: certstring = serialPattern.matcher(certstring).replaceAll(
099: "SN=");
100:
101: int parameter;
102: int size = 0;
103: String[] clientstrings = null;
104:
105: // First check that issuers match.
106: if (this .caid == admincaid) {
107: // Determine part of certificate to match with.
108: DNFieldExtractor dn = new DNFieldExtractor(certstring,
109: DNFieldExtractor.TYPE_SUBJECTDN);
110: if (matchwith == WITH_SERIALNUMBER) {
111: if (certificate != null) {
112: switch (matchtype) {
113: case TYPE_EQUALCASE:
114: case TYPE_EQUALCASEINS:
115: try {
116: returnvalue = (new java.math.BigInteger(
117: matchvalue, 16))
118: .equals(certificate
119: .getSerialNumber());
120: } catch (java.lang.NumberFormatException nfe) {
121: }
122: break;
123: case TYPE_NOT_EQUALCASE:
124: case TYPE_NOT_EQUALCASEINS:
125: try {
126: returnvalue = !(new java.math.BigInteger(
127: matchvalue, 16))
128: .equals(certificate
129: .getSerialNumber());
130: } catch (java.lang.NumberFormatException nfe) {
131: }
132: break;
133: default:
134: }
135: }
136: } else {
137: parameter = DNFieldExtractor.CN;
138: switch (matchwith) {
139: case WITH_COUNTRY:
140: parameter = DNFieldExtractor.C;
141: break;
142: case WITH_DOMAINCOMPONENT:
143: parameter = DNFieldExtractor.DC;
144: break;
145: case WITH_STATE:
146: parameter = DNFieldExtractor.L;
147: break;
148: case WITH_LOCALE:
149: parameter = DNFieldExtractor.ST;
150: break;
151: case WITH_ORGANIZATION:
152: parameter = DNFieldExtractor.O;
153: break;
154: case WITH_ORGANIZATIONUNIT:
155: parameter = DNFieldExtractor.OU;
156: break;
157: case WITH_TITLE:
158: parameter = DNFieldExtractor.T;
159: break;
160: case WITH_DNSERIALNUMBER:
161: parameter = DNFieldExtractor.SN;
162: break;
163: case WITH_COMMONNAME:
164: parameter = DNFieldExtractor.CN;
165: break;
166: case WITH_UID:
167: parameter = DNFieldExtractor.UID;
168: break;
169: default:
170: }
171: size = dn.getNumberOfFields(parameter);
172: clientstrings = new String[size];
173: for (int i = 0; i < size; i++) {
174: clientstrings[i] = dn.getField(parameter, i);
175: }
176:
177: // Determine how to match.
178: if (clientstrings != null) {
179: switch (matchtype) {
180: case TYPE_EQUALCASE:
181: for (int i = 0; i < size; i++) {
182: returnvalue = clientstrings[i]
183: .equals(matchvalue);
184: if (returnvalue)
185: break;
186: }
187: break;
188: case TYPE_EQUALCASEINS:
189: for (int i = 0; i < size; i++) {
190: returnvalue = clientstrings[i]
191: .equalsIgnoreCase(matchvalue);
192: if (returnvalue)
193: break;
194: }
195: break;
196: case TYPE_NOT_EQUALCASE:
197: for (int i = 0; i < size; i++) {
198: returnvalue = !clientstrings[i]
199: .equals(matchvalue);
200: if (returnvalue)
201: break;
202: }
203: break;
204: case TYPE_NOT_EQUALCASEINS:
205: for (int i = 0; i < size; i++) {
206: returnvalue = !clientstrings[i]
207: .equalsIgnoreCase(matchvalue);
208: if (returnvalue)
209: break;
210: }
211: break;
212: default:
213: }
214: }
215: }
216: }
217: }
218:
219: return returnvalue;
220: }
221:
222: // Methods to get and set the individual variables.
223: public int getMatchWith() {
224: return matchwith;
225: }
226:
227: public void setMatchWith(int matchwith) {
228: if (matchwith == AdminEntity.WITH_SERIALNUMBER) {
229: this .matchvalue = StringTools
230: .stripWhitespace(this .matchvalue);
231: }
232: this .matchwith = matchwith;
233: }
234:
235: public int getMatchType() {
236: return matchtype;
237: }
238:
239: public void setMatchType(int matchtype) {
240: this .matchtype = matchtype;
241: }
242:
243: public String getMatchValue() {
244: return matchvalue;
245: }
246:
247: public void setMatchValue(String matchvalue) {
248: if (this .matchwith == AdminEntity.WITH_SERIALNUMBER) {
249: this .matchvalue = StringTools.stripWhitespace(matchvalue);
250: } else
251: this .matchvalue = matchvalue;
252: }
253:
254: public int getSpecialUser() {
255: return this .matchtype;
256: }
257:
258: public void setSpecialUser(int specialadmin) {
259: this .matchtype = specialadmin;
260: }
261:
262: public boolean isSpecialUser() {
263: return this .matchtype >= 2000 && this .matchtype <= 2999;
264: }
265:
266: /** Method used by the access tree to determine the priority. The priority is the same as match with value. */
267: public int getPriority() {
268: return matchwith;
269: }
270:
271: public int compareTo(Object obj) {
272: return matchvalue
273: .compareTo(((AdminEntity) obj).getMatchValue());
274: }
275:
276: // Private methods.
277:
278: // Private fields.
279: private int matchwith;
280: private int matchtype;
281: private String matchvalue;
282: private int caid;
283:
284: }
|