001: package org.jacorb.security.sas;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 2002-2004 Gerald Brose
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import java.security.Provider;
024:
025: import org.ietf.jgss.GSSException;
026: import org.ietf.jgss.Oid;
027: import org.omg.CORBA.Any;
028: import org.omg.CORBA.ORB;
029: import org.omg.GSSUP.InitialContextToken;
030: import org.omg.GSSUP.InitialContextTokenHelper;
031: import org.omg.IOP.Codec;
032:
033: import sun.security.jgss.spi.GSSNameSpi;
034:
035: /**
036: * This is the GSS-API Sercurity Provider Interface (SPI) for the GSSUP Name
037: *
038: * @author David Robison
039: * @version $Id: GSSUPNameSpi.java,v 1.14 2004/05/07 13:08:29 david.robison Exp $
040: */
041:
042: public final class GSSUPNameSpi implements GSSNameSpi {
043: private static Oid mechOid;
044:
045: private Provider provider;
046: private Oid nameTypeOid;
047:
048: private InitialContextToken subject = null;
049:
050: static {
051: try {
052: mechOid = new Oid("2.23.130.1.1.1");
053: } catch (GSSException e) {
054: }
055: }
056:
057: public GSSUPNameSpi(Provider provider, Oid mechOid, byte[] name,
058: Oid nameTypeOid) {
059: this .provider = provider;
060: this .nameTypeOid = nameTypeOid;
061: //GSSUPNameSpi.mechOid = mechOid;
062:
063: // parse the name
064: /*
065: if (name.length > 0)
066: {
067: try
068: {
069: Any any =
070: ((GSSUPProvider)provider).getCodec().decode_value( name,
071: InitialContextTokenHelper.type());
072: subject = InitialContextTokenHelper.extract(any);
073: }
074: catch (Exception e)
075: {
076: // logger.error("Error creating GSSNameSpi: " + e);
077: subject = new InitialContextToken(new byte[0], new byte[0], new byte[0]);
078: }
079: }
080: else
081: {
082: subject = new InitialContextToken(new byte[0], new byte[0], new byte[0]);
083: }
084: */
085: }
086:
087: public static byte[] encode(ORB orb, Codec codec, String username,
088: String password, byte[] target_name) {
089: InitialContextToken subject = null;
090: try {
091: subject = new InitialContextToken(username
092: .getBytes("UTF-8"), password.getBytes("UTF-8"),
093: target_name);
094: } catch (java.io.UnsupportedEncodingException e) {
095: //should never happen
096: // logger.error("Error creating InitialContextToken: " + e);
097: return new byte[0];
098: }
099: byte[] out = null;
100: Any any = orb.create_any();
101: InitialContextTokenHelper.insert(any, subject);
102: try {
103: out = codec.encode_value(any);
104: } catch (Exception e) {
105: // logger.error("Error encoding for GSSNameSpi: " + e);
106: return new byte[0];
107: }
108:
109: byte[] mechOidArray = null;
110: try {
111: mechOidArray = mechOid.getDER();
112: } catch (org.ietf.jgss.GSSException e) {
113: // logger.error("Error retrieving mechOid DER: " + e);
114: return new byte[0];
115: }
116:
117: int length = out.length + mechOidArray.length;
118: byte[] encodedLength = null;
119:
120: if ((length >> 7) == 0) {
121: //length fits into 7 bit
122: encodedLength = new byte[] { (byte) 0x60, (byte) length };
123: } else if ((length >> 14) == 0) {
124: //length fits into 14 bit
125: encodedLength = new byte[] { (byte) 0x60,
126: (byte) ((length >> 7) | 0x80),
127: (byte) (length & 0x7F) };
128: } else if ((length >> 21) == 0) {
129: //length fits into 21 bit
130: encodedLength = new byte[] { (byte) 0x60,
131: (byte) ((length >> 14) | 0x80),
132: (byte) (((length >> 7) & 0x7F) | 0x80),
133: (byte) (length & 0x7F) };
134: } else if ((length >> 28) == 0) {
135: //length fits into 28 bit
136: encodedLength = new byte[] { (byte) 0x60,
137: (byte) ((length >> 21) | 0x80),
138: (byte) (((length >> 14) & 0x7F) | 0x80),
139: (byte) (((length >> 7) & 0x7F) | 0x80),
140: (byte) (length & 0x7F) };
141: } else {
142: //length fits into 32 bit
143: encodedLength = new byte[] { (byte) 0x60,
144: (byte) ((length >> 28) | 0x80),
145: (byte) (((length >> 21) & 0x7F) | 0x80),
146: (byte) (((length >> 14) & 0x7F) | 0x80),
147: (byte) (((length >> 7) & 0x7F) | 0x80),
148: (byte) (length & 0x7F) };
149: }
150:
151: byte[] completeContext = new byte[length + encodedLength.length];
152: System.arraycopy(encodedLength, 0, completeContext, 0,
153: encodedLength.length);
154: System.arraycopy(mechOidArray, 0, completeContext,
155: encodedLength.length, mechOidArray.length);
156: System.arraycopy(out, 0, completeContext, encodedLength.length
157: + mechOidArray.length, out.length);
158:
159: return completeContext;
160: }
161:
162: public static byte[] encode(ORB orb, Codec codec, String username,
163: char[] password, String target_name) {
164: return encode(orb, codec, username, new String(password),
165: target_name.getBytes());
166: }
167:
168: public static InitialContextToken decode(ORB orb, Codec codec,
169: byte[] gssToken) {
170: if (gssToken[0] != 0x60) {
171: // logger.error("GSSToken doesn't start with expected value '0x60'");
172: return null;
173: }
174:
175: //skip total size, the GSSToken already has the correct length
176:
177: //find first octet where the MSB is zero
178: int index = 1;
179: while (index < gssToken.length && (gssToken[index] & 0x80) == 1) {
180: ++index;
181: }
182:
183: if (index == gssToken.length) {
184: //end not found
185: // logger.error("GSSToken doesn't contain valid length");
186: return null;
187: }
188:
189: byte[] mechOidArray = null;
190: try {
191: mechOidArray = mechOid.getDER();
192: } catch (org.ietf.jgss.GSSException e) {
193: // logger.error("Error retrieving mechOid DER: " + e);
194: return null;
195: }
196:
197: //skip last octet of length
198: ++index;
199:
200: if ((index + mechOidArray.length) >= gssToken.length) {
201: // logger.error("GSSToken doesn't contain OID");
202: return null;
203: }
204:
205: for (int i = 0; i < mechOidArray.length; ++i) {
206: if (mechOidArray[i] != gssToken[index + i]) {
207: // logger.error("GSSToken doesn't contain GSSUPMechOID");
208: return null;
209: }
210: }
211:
212: //skip oid
213: index += mechOidArray.length;
214:
215: byte[] icToken = new byte[gssToken.length - index];
216: System.arraycopy(gssToken, index, icToken, 0, icToken.length);
217:
218: try {
219: Any any = codec.decode_value(icToken,
220: InitialContextTokenHelper.type());
221: return InitialContextTokenHelper.extract(any);
222: } catch (Exception e) {
223: // logger.error("Error decoding for GSSNameSpi: " + e);
224: }
225: //logger.error("Bailout - GSSUP");
226: return null;
227: }
228:
229: public Provider getProvider() {
230: return provider;
231: }
232:
233: public boolean equals(GSSNameSpi name) throws GSSException {
234: return subject.equals(((GSSUPNameSpi) name).subject);
235: }
236:
237: public byte[] export() throws GSSException {
238: throw new GSSException(GSSException.FAILURE,
239: GSSException.FAILURE, "Not Implemented");
240: /*
241: //System.out.println("GSSUPNameSpi.export");
242: Any any = ((GSSUPProvider)provider).getORB().create_any();
243: InitialContextTokenHelper.insert( any, subject );
244: byte[] out = new byte[0];
245: try
246: {
247: out = ((GSSUPProvider)provider).getCodec().encode_value( any );
248: }
249: catch (Exception e)
250: {
251: // logger.error("Error encoding for GSSNameSpi: " + e);
252: }
253: return out;
254: */
255: }
256:
257: public Oid getMechanism() {
258: return mechOid;
259: }
260:
261: public String toString() {
262: return null;
263: /*
264: Any any = ((GSSUPProvider)provider).getORB().create_any();
265: InitialContextTokenHelper.insert( any, subject );
266: byte[] out = new byte[0];
267: try
268: {
269: out = ((GSSUPProvider)provider).getCodec().encode_value( any );
270: }
271: catch (Exception e)
272: {
273: // logger.error("Error encoding for GSSNameSpi: " + e);
274: }
275: return new String(out);
276: */
277: }
278:
279: public Oid getStringNameType() {
280: return nameTypeOid;
281: }
282:
283: public boolean isAnonymousName() {
284: System.out.println("GSSUPNameSpi.isAnonymousName");
285: return false;
286: }
287: }
|