KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > iiop > csiv2 > CSIv2Util


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.iiop.csiv2;
23
24 import java.net.InetAddress JavaDoc;
25 import java.io.UnsupportedEncodingException JavaDoc;
26
27 import org.omg.CORBA.Any JavaDoc;
28 import org.omg.CORBA.BAD_PARAM JavaDoc;
29 import org.omg.CORBA.MARSHAL JavaDoc;
30 import org.omg.CORBA.ORB JavaDoc;
31
32 import org.omg.IOP.Codec JavaDoc;
33 import org.omg.IOP.CodecPackage.InvalidTypeForEncoding JavaDoc;
34 import org.omg.IOP.TaggedComponent JavaDoc;
35
36 import org.omg.CSI.ITTAnonymous;
37 import org.omg.CSI.ITTPrincipalName;
38 import org.omg.CSI.ITTX509CertChain;
39 import org.omg.CSI.ITTDistinguishedName;
40
41 import org.omg.CSIIOP.AS_ContextSec;
42 import org.omg.CSIIOP.CompoundSecMech;
43 import org.omg.CSIIOP.CompoundSecMechList;
44 import org.omg.CSIIOP.CompoundSecMechListHelper;
45 import org.omg.CSIIOP.Confidentiality;
46 import org.omg.CSIIOP.DetectMisordering;
47 import org.omg.CSIIOP.DetectReplay;
48 import org.omg.CSIIOP.EstablishTrustInClient;
49 import org.omg.CSIIOP.EstablishTrustInTarget;
50 import org.omg.CSIIOP.IdentityAssertion;
51 import org.omg.CSIIOP.Integrity;
52 import org.omg.CSIIOP.SAS_ContextSec;
53 import org.omg.CSIIOP.ServiceConfiguration;
54 import org.omg.CSIIOP.TAG_CSI_SEC_MECH_LIST;
55 import org.omg.CSIIOP.TAG_NULL_TAG;
56 import org.omg.CSIIOP.TAG_TLS_SEC_TRANS;
57 import org.omg.CSIIOP.TLS_SEC_TRANS;
58 import org.omg.CSIIOP.TLS_SEC_TRANSHelper;
59 import org.omg.CSIIOP.TransportAddress;
60
61 import org.omg.GSSUP.GSSUPMechOID;
62 import org.omg.GSSUP.InitialContextToken;
63 import org.omg.GSSUP.InitialContextTokenHelper;
64
65 import org.omg.PortableInterceptor.ClientRequestInfo JavaDoc;
66
67 import org.omg.SSLIOP.SSL;
68 import org.omg.SSLIOP.SSLHelper;
69 import org.omg.SSLIOP.TAG_SSL_SEC_TRANS;
70
71 import org.ietf.jgss.GSSException JavaDoc;
72 import org.ietf.jgss.Oid JavaDoc;
73
74 import org.jboss.metadata.IorSecurityConfigMetaData;
75 import org.jboss.metadata.IorSecurityConfigMetaData.TransportConfig;
76 import org.jboss.metadata.IorSecurityConfigMetaData.AsContext;
77 import org.jboss.metadata.IorSecurityConfigMetaData.SasContext;
78
79 import org.jboss.logging.Logger;
80
81 /**
82  * Helper class
83  *
84  * @author Dimitris.Andreadis@jboss.org
85  * @author Francisco Reverbel
86  * @author Stefan Neusatz Guilhen
87  * @version $Revision: 55119 $
88  */

89 public final class CSIv2Util
90 {
91    private static final Logger log = Logger.getLogger(CSIv2Util.class);
92
93    /** DER-encoded ASN.1 representation of the GSSUP mechanism OID. */
94    private static final byte[] gssUpMechOidArray = createGSSUPMechOID();
95
96    private CSIv2Util()
97    {
98       // static calls only
99
}
100
101    /**
102     * Make a deep copy of an IOP:TaggedComponent
103     **/

104    public static TaggedComponent JavaDoc createCopy(TaggedComponent JavaDoc tc)
105    {
106       TaggedComponent JavaDoc copy = null;
107
108       if( tc != null )
109       {
110          byte[] buf = new byte[tc.component_data.length];
111          System.arraycopy(tc.component_data, 0, buf, 0, tc.component_data.length);
112
113          copy = new TaggedComponent JavaDoc(tc.tag, buf);
114       }
115
116       return copy;
117    }
118
119    /**
120     * Return a top-level IOP::TaggedComponent to be stuffed into an IOR,
121     * containing an structure SSLIOP::SSL, tagged as TAG_SSL_SEC_TRANS.
122     *
123     * Should be called with non-null metadata, in which case we probably
124     * don't want to include security info in the IOR.
125     **/

126    public static TaggedComponent JavaDoc createSSLTaggedComponent(
127       IorSecurityConfigMetaData metadata,
128       Codec JavaDoc codec,
129       int sslPort,
130       ORB JavaDoc orb)
131    {
132       if( metadata == null )
133       {
134          log.debug("createSSLTaggedComponent() called with null metadata");
135          return null;
136       }
137
138       TaggedComponent JavaDoc tc = null;
139
140       try
141       {
142          int supports = createTargetSupports(metadata.getTransportConfig());
143          int requires = createTargetRequires(metadata.getTransportConfig());
144          SSL ssl = new SSL((short) supports, (short) requires, (short) sslPort);
145          Any JavaDoc any = orb.create_any();
146          SSLHelper.insert(any, ssl);
147          byte[] componentData = codec.encode_value(any);
148          tc = new TaggedComponent JavaDoc(TAG_SSL_SEC_TRANS.value, componentData);
149       }
150       catch(InvalidTypeForEncoding JavaDoc e)
151       {
152          log.warn("Caught unexcepted exception while encoding SSL component", e);
153          throw new RuntimeException JavaDoc(e);
154       }
155       return tc;
156    }
157
158    /**
159     * Return a top-level IOP:TaggedComponent to be stuffed into an IOR,
160     * containing a CSIIOP.CompoundSecMechList, tagged as TAG_CSI_SEC_MECH_LIST.
161     * Only one such component can exist inside an IOR.
162     *
163     * Should be called with non-null metadata, in which case we probably
164     * don't want to include security info in the IOR.
165     **/

166    public static TaggedComponent JavaDoc createSecurityTaggedComponent(
167       IorSecurityConfigMetaData metadata,
168       Codec JavaDoc codec,
169       int sslPort,
170       ORB JavaDoc orb
171       )
172    {
173       if( metadata == null )
174       {
175          log.debug("createSecurityTaggedComponent() called with null metadata");
176          return null;
177       }
178
179       TaggedComponent JavaDoc tc = null;
180       
181       // Get the the supported security mechanisms (just one :)
182
CompoundSecMech[] mechList =
183          createCompoundSecMechanisms(metadata, codec, sslPort, orb);
184          
185       // the above is wrapped into a CSIIOP.CompoundSecMechList
186
// structure, which is NOT a CompoundSecMech[] !!!
187
//
188
// We DONT support stateful/reusable security contexts (false)
189
CompoundSecMechList csmList = new CompoundSecMechList(false,
190          mechList);
191       // finally, the CompoundSecMechList must be encoded as a TaggedComponent
192
try
193       {
194          Any JavaDoc any = orb.create_any();
195
196          CompoundSecMechListHelper.insert(any, csmList);
197          byte[] b = codec.encode_value(any);
198
199          tc = new TaggedComponent JavaDoc(TAG_CSI_SEC_MECH_LIST.value, b);
200       }
201       catch(InvalidTypeForEncoding JavaDoc e)
202       {
203          log.warn("Caught unexcepted exception while encoding CompoundSecMechList", e);
204          throw new RuntimeException JavaDoc(e);
205       }
206
207       return tc;
208    }
209
210    /**
211     * Create a CSIIOP.CompoundSecMechanisms which is a sequence of
212     * CompoundSecMech. Here we only support one security mechanism.
213     **/

214    public static CompoundSecMech[] createCompoundSecMechanisms(
215       IorSecurityConfigMetaData metadata,
216       Codec JavaDoc codec,
217       int sslPort,
218       ORB JavaDoc orb
219       )
220    {
221       // Support just 1 security mechanism for now (and ever :)
222
CompoundSecMech[] csmList = new CompoundSecMech[1];
223       
224       // A CompoundSecMech contains:
225
// target_requires, transport_mech, as_context_mech, sas_context_mech
226

227       // The transport mechanism is an IOP.TaggedComponent itself
228
// to allow for arbitrary transport mechanisms be specified.
229
// This will configure SSL or none.
230
TaggedComponent JavaDoc transport_mech = createTransportMech(
231          metadata.getTransportConfig(), codec, sslPort, orb
232       );
233       
234       // Create AS Context
235
AS_ContextSec asContext = createAuthenticationServiceContext(metadata);
236       
237       // Create SAS Context
238
SAS_ContextSec sasContext = createSecureAttributeServiceContext(metadata);
239
240       // Create target_requires bit field (AssociationOption)
241
// can't read directly the transport_mech TaggedComponent
242
int target_requires =
243          createTargetRequires(metadata.getTransportConfig()) |
244          asContext.target_requires |
245          sasContext.target_requires;
246
247       // wrap it up
248
CompoundSecMech csm = new CompoundSecMech((short) target_requires,
249          transport_mech,
250          asContext,
251          sasContext);
252       // store it in csmList as the only security mechanism
253
csmList[0] = csm;
254
255       return csmList;
256    }
257
258    /**
259     * Create the Secure Attribute Service (SAS) context
260     * included in a CompoundSecMech definition
261     **/

262    public static SAS_ContextSec createSecureAttributeServiceContext(
263       IorSecurityConfigMetaData metadata
264       )
265    {
266       SAS_ContextSec context = null;
267       
268       // context contains
269
// target_supports, target_requires, privilige_authorities,
270
// supported_naming_mechanisms, supported_identity_types
271
int support = 0;
272       int require = 0;
273       ServiceConfiguration[] privilAuth = new ServiceConfiguration[0];
274       byte[][] supNamMechs = {};
275       int supIdenTypes = 0; // 0 means ITTAbsent
276

277       // the the SasContext metadata
278
SasContext sasMeta = metadata.getSasContext();
279       
280       // if no SAS context metadata, or caller propagation is not
281
// supported, we return with a more or less empty sas context
282
if( sasMeta == null || !sasMeta.isCallerPropagationSupported() )
283       {
284          context = new SAS_ContextSec((short) support,
285             (short) require,
286             privilAuth,
287             supNamMechs,
288             supIdenTypes);
289       }
290       else
291       {
292          support = IdentityAssertion.value;
293          
294          // supporting GSSUP (username/password) naming mechanism
295
byte[] upMech = createGSSUPMechOID();
296          supNamMechs = new byte[1][upMech.length];
297          System.arraycopy(upMech, 0, supNamMechs[0], 0, upMech.length);
298          
299          // since we support IdentityAssertion we need to specify
300
// supported identity types. CTS says we need them all
301
supIdenTypes = ITTAnonymous.value |
302             ITTPrincipalName.value |
303             ITTX509CertChain.value |
304             ITTDistinguishedName.value;
305          // wrap it up
306
context = new SAS_ContextSec((short) support,
307             (short) require,
308             privilAuth,
309             supNamMechs,
310             supIdenTypes);
311       }
312
313       return context;
314    }
315
316    /**
317     * Create the client Authentication Service (AS) context
318     * included in a CompoundSecMech definition.
319     **/

320    public static AS_ContextSec createAuthenticationServiceContext(
321       IorSecurityConfigMetaData metadata
322       )
323    {
324       AS_ContextSec context = null;
325       
326       // the content of the context
327
int support = EstablishTrustInClient.value; // per default support this
328
int require = 0;
329       byte[] clientAuthMech = {};
330       byte[] targetName = {};
331       
332       // get the AsContext metadata
333
AsContext asMeta = metadata.getAsContext();
334       
335       // if no AS context metatada exists, or authentication method
336
// "none" is specified, we can produce an empty AS context
337
if( asMeta == null || asMeta.getAuthMethod().equals(AsContext.AUTH_METHOD_NONE)
338          || asMeta.isRequired() == false )
339       {
340          // TODO: check if an empty AS context may contain a target name.
341
targetName = encodeGssExportedName(targetName);
342          
343          context = new AS_ContextSec((short) support,
344             (short) require,
345             clientAuthMech,
346             targetName);
347       }
348       else
349       {
350          // required depends on the metadata
351
if( asMeta.isRequired() )
352             require = EstablishTrustInClient.value;
353          
354          // we only support GSSUP authentication method
355
clientAuthMech = createGSSUPMechOID();
356          
357          // finally, encode the "realm" name as a CSI.GSS_NT_ExportedName.
358
// clientAuthMech should contain the DER encoded GSSUPMechOID
359
// at this point.
360
String JavaDoc realm = asMeta.getRealm();
361          targetName = createGSSExportedName(clientAuthMech, realm.getBytes());
362          
363          // wrap it up
364
context = new AS_ContextSec((short) support,
365             (short) require,
366             clientAuthMech,
367             targetName);
368       }
369
370       return context;
371    }
372
373    /**
374     * Create a transport mechanism TaggedComponent to be stuffed into a
375     * CompoundSecMech.
376     *
377     * If no TransportConfig metadata is specified, or ssl port is negative,
378     * or the specified metadata indicates that transport config is not supported,
379     * then a TAG_NULL_TAG (empty) TaggedComponent will be returned.
380     *
381     * Otherwise a CSIIOP.TLS_SEC_TRANS, tagged as TAG_TLS_SEC_TRANS will
382     * be returned, indicating support for TLS/SSL as a CSIv2 transport
383     * mechanism.
384     *
385     * Multiple TransportAddress may be included in the SSL info
386     * (host/port pairs), but we only include one.
387     **/

388    public static TaggedComponent JavaDoc createTransportMech(
389       TransportConfig tconfig,
390       Codec JavaDoc codec,
391       int sslPort,
392       ORB JavaDoc orb
393       )
394    {
395       TaggedComponent JavaDoc tc = null;
396       
397       // what we support and require as a target
398
int support = 0;
399       int require = 0;
400
401       if( tconfig != null )
402       {
403          require = createTargetRequires(tconfig);
404          support = createTargetSupports(tconfig);
405       }
406
407       if( tconfig == null || support == 0 || sslPort < 0 )
408       {
409          // no support for transport security
410
tc = new TaggedComponent JavaDoc(TAG_NULL_TAG.value, new byte[0]);
411       }
412       else
413       {
414          // my ip address
415
String JavaDoc host;
416          try
417          {
418             host = InetAddress.getLocalHost().getHostAddress();
419          }
420          catch(java.net.UnknownHostException JavaDoc e)
421          {
422             host = "127.0.0.1";
423          }
424          
425          // this will create only one transport address
426
TransportAddress[] taList = createTransportAddress(host, sslPort);
427
428          TLS_SEC_TRANS tst = new TLS_SEC_TRANS((short) support,
429             (short) require,
430             taList);
431
432          // The tricky part, we must encode TLS_SEC_TRANS into an octet sequence
433
try
434          {
435             Any JavaDoc any = orb.create_any();
436
437             TLS_SEC_TRANSHelper.insert(any, tst);
438             byte[] b = codec.encode_value(any);
439
440             tc = new TaggedComponent JavaDoc(TAG_TLS_SEC_TRANS.value, b);
441          }
442          catch(InvalidTypeForEncoding JavaDoc e)
443          {
444             log.warn("Caught unexcepted exception while encoding TLS_SEC_TRANS", e);
445             throw new RuntimeException JavaDoc(e);
446          }
447       }
448
449       return tc;
450    }
451
452    /**
453     * Create a TransportAddress[] with a single TransportAddress
454     **/

455    public static TransportAddress[] createTransportAddress(
456       String JavaDoc host, int port
457       )
458    {
459       // idl type is unsighned sort, so we need this trick
460
short short_port = (port > 32767) ? (short) (port - 65536) : (short) port;
461
462       TransportAddress ta = new TransportAddress(host, short_port);
463       TransportAddress[] taList = new TransportAddress[1];
464       taList[0] = ta;
465
466       return taList;
467    }
468
469    /**
470     * Create the AssociationOption for CompoundSecMech - target_requires
471     **/

472    public static int createTargetRequires(TransportConfig tc)
473    {
474       int requires = 0;
475
476       if( tc != null )
477       {
478          if( tc.getIntegrity().equals(TransportConfig.INTEGRITY_REQUIRED) )
479             requires = requires | Integrity.value;
480
481          if( tc.getConfidentiality().equals(TransportConfig.CONFIDENTIALITY_REQUIRED) )
482             requires = requires | Confidentiality.value;
483
484          if( tc.getDetectMisordering().equalsIgnoreCase(TransportConfig.DETECT_MISORDERING_REQUIRED) )
485             requires = requires | DetectMisordering.value;
486
487          if( tc.getDetectReplay().equalsIgnoreCase(TransportConfig.DETECT_REPLAY_REQUIRED) )
488             requires = requires | DetectReplay.value;
489
490          // no EstablishTrustInTarget required - client decides
491

492          if( tc.getEstablishTrustInClient().equals(TransportConfig.ESTABLISH_TRUST_IN_CLIENT_REQUIRED) )
493             requires = requires | EstablishTrustInClient.value;
494       }
495
496       return requires;
497    }
498
499    /**
500     * Create bitmask of what the target supports
501     **/

502    public static int createTargetSupports(TransportConfig tc)
503    {
504       int supports = 0;
505
506       if( tc != null )
507       {
508          if( !tc.getIntegrity().equals(TransportConfig.INTEGRITY_NONE) )
509             supports = supports | Integrity.value;
510
511          if( !tc.getConfidentiality().equals(TransportConfig.CONFIDENTIALITY_NONE) )
512             supports = supports | Confidentiality.value;
513
514          if( !tc.getDetectMisordering().equalsIgnoreCase(TransportConfig.DETECT_MISORDERING_NONE) )
515             supports = supports | DetectMisordering.value;
516
517          if( !tc.getDetectReplay().equalsIgnoreCase(TransportConfig.DETECT_REPLAY_NONE) )
518             supports = supports | DetectReplay.value;
519
520          if( !tc.getEstablishTrustInTarget().equals(TransportConfig.ESTABLISH_TRUST_IN_TARGET_NONE) )
521             supports = supports | EstablishTrustInTarget.value;
522
523          if( !tc.getEstablishTrustInClient().equals(TransportConfig.ESTABLISH_TRUST_IN_CLIENT_NONE) )
524             supports = supports | EstablishTrustInClient.value;
525       }
526
527       return supports;
528    }
529
530    /**
531     * Create an ASN.1, DER encoded representation for
532     * the GSSUP OID mechanism
533     **/

534    public static byte[] createGSSUPMechOID()
535    {
536       // kudos to org.ietf.jgss.Oid for the Oid utility
537
// need to strip the "oid:" part of the GSSUPMechOID first
538

539       byte[] retval = {};
540       try
541       {
542          Oid JavaDoc oid = new Oid JavaDoc(GSSUPMechOID.value.substring(4));
543          retval = oid.getDER();
544       }
545       catch(GSSException JavaDoc e)
546       {
547          log.warn("Caught exception while encoding GSSUPMechOID", e);
548       }
549       return retval;
550    }
551
552    /**
553     * Return an ASN.1, DER encoded representation for the GSSUP OID mechanism.
554     **/

555    public static byte[] gssUpMechOid()
556    {
557       return (byte[])gssUpMechOidArray.clone();
558    }
559    
560    /**
561     * Generate an exported name as specified in [RFC 2743], section 3.2
562     * copied below:
563     *
564     * 3.2: Mechanism-Independent Exported Name Object Format
565     *
566     * This section specifies a mechanism-independent level of encapsulating
567     * representation for names exported via the GSS_Export_name() call,
568     * including an object identifier representing the exporting mechanism.
569     * The format of names encapsulated via this representation shall be
570     * defined within individual mechanism drafts. The Object Identifier
571     * value to indicate names of this type is defined in Section 4.7 of
572     * this document.
573     *
574     * No name type OID is included in this mechanism-independent level of
575     * format definition, since (depending on individual mechanism
576     * specifications) the enclosed name may be implicitly typed or may be
577     * explicitly typed using a means other than OID encoding.
578     *
579     * The bytes within MECH_OID_LEN and NAME_LEN elements are represented
580     * most significant byte first (equivalently, in IP network byte order).
581     *
582     * Length Name Description
583     *
584     * 2 TOK_ID Token Identifier
585     * For exported name objects, this
586     * must be hex 04 01.
587     * 2 MECH_OID_LEN Length of the Mechanism OID
588     * MECH_OID_LEN MECH_OID Mechanism OID, in DER
589     * 4 NAME_LEN Length of name
590     * NAME_LEN NAME Exported name; format defined in
591     * applicable mechanism draft.
592     *
593     * A concrete example of the contents of an exported name object,
594     * derived from the Kerberos Version 5 mechanism, is as follows:
595     *
596     * 04 01 00 0B 06 09 2A 86 48 86 F7 12 01 02 02 hx xx xx xl pp qq ... zz
597     *
598     * ...
599     *
600     * @param oid the DER encoded OID
601     * @param name the name to be converted to GSSExportedName
602     **/

603    public static byte[] createGSSExportedName(byte[] oid, byte[] name)
604    {
605       int olen = oid.length;
606       int nlen = name.length;
607       
608       // size according to spec
609
int size = 2 + 2 + olen + 4 + nlen;
610     
611       // allocate space for the exported name
612
byte[] buf = new byte[size];
613       // index
614
int i = 0;
615       
616       // standard header
617
buf[i++] = 0x04;
618       buf[i++] = 0x01;
619       
620       // encode oid length
621
buf[i++] = (byte) (olen & 0xFF00);
622       buf[i++] = (byte) (olen & 0x00FF);
623       
624       // copy the oid in the exported name buffer
625
System.arraycopy(oid, 0, buf, i, olen);
626       i += olen;
627       
628       // encode the name length in the exported buffer
629
buf[i++] = (byte) (nlen & 0xFF000000);
630       buf[i++] = (byte) (nlen & 0x00FF0000);
631       buf[i++] = (byte) (nlen & 0x0000FF00);
632       buf[i++] = (byte) (nlen & 0x000000FF);
633
634       // finally, copy the name bytes
635
System.arraycopy(name, 0, buf, i, nlen);
636
637       // done
638
return buf;
639    }
640
641    /**
642     * ASN.1-encode an InitialContextToken as defined in RFC 2743, Section 3.1,
643     * "Mechanism-Independent Token Format", pp. 81-82. The encoded token
644     * contains the ASN.1 tag 0x60, followed by a token length (which is itself
645     * stored in a variable-lenght format and takes 1 to 5 bytes), the GSSUP
646     * mechanism identifier, and a mechanism-specific token, which in this
647     * case is a CDR encapsulation of the GSSUP InitialContextToken in the
648     * authToken parameter.
649     */

650    public static byte[] encodeInitialContextToken(InitialContextToken authToken,
651                                                   Codec JavaDoc codec)
652    {
653       byte[] out = null;
654       Any JavaDoc any = ORB.init().create_any();
655       InitialContextTokenHelper.insert(any, authToken);
656       try
657       {
658          out = codec.encode_value(any);
659       }
660       catch (Exception JavaDoc e)
661       {
662          // logger.error("Error encoding for GSSNameSpi: " + e);
663
return new byte[0];
664       }
665       
666       int length = out.length + gssUpMechOidArray.length;
667       int n;
668       
669       if (length < (1 << 7))
670          n = 0;
671       else if (length < (1 << 8))
672          n = 1;
673       else if (length < (1 << 16))
674          n = 2;
675       else if (length < (1 << 24))
676          n = 3;
677       else // if (length < (1 << 32))
678
n = 4;
679       
680       byte[] encodedToken = new byte[2 + n + length];
681       encodedToken[0] = 0x60;
682       
683       if (n == 0)
684          encodedToken[1] = (byte)length;
685       else
686       {
687          encodedToken[1] = (byte)(n | 0x80);
688          switch (n)
689          {
690          case 1:
691             encodedToken[2] = (byte)length;
692             break;
693          case 2:
694             encodedToken[2] = (byte)(length >> 8);
695             encodedToken[3] = (byte)length;
696             break;
697          case 3:
698             encodedToken[2] = (byte)(length >> 16);
699             encodedToken[3] = (byte)(length >> 8);
700             encodedToken[4] = (byte)length;
701             break;
702          default: // case 4:
703
encodedToken[2] = (byte)(length >> 24);
704             encodedToken[3] = (byte)(length >> 16);
705             encodedToken[4] = (byte)(length >> 8);
706             encodedToken[5] = (byte)length;
707          }
708       }
709       System.arraycopy(gssUpMechOidArray, 0,
710                        encodedToken, 2 + n,
711                        gssUpMechOidArray.length);
712       System.arraycopy(out, 0,
713                        encodedToken, 2 + n + gssUpMechOidArray.length,
714                        out.length);
715       
716       return encodedToken;
717    }
718    
719    /**
720     * Decodes an ASN.1-encoded InitialContextToken.
721     * See encodeInitialContextToken for a description of the encoded token
722     * format.
723     */

724    public static InitialContextToken decodeInitialContextToken(
725                                                          byte[] encodedToken,
726                                                          Codec JavaDoc codec)
727    {
728       if(encodedToken[0] != 0x60)
729          return null;
730       
731       int encodedLength = 0;
732       int n = 0;
733       
734       if(encodedToken[1] >= 0)
735          encodedLength = encodedToken[1];
736       else
737       {
738          n = encodedToken[1] & 0x7F;
739          for(int i = 1; i <= n; i++)
740             encodedLength += (encodedToken[1 + i] & 0xFF) << (n-i)*8;
741       }
742         
743       int length = encodedLength - gssUpMechOidArray.length;
744       byte[] encodedInitialContextToken = new byte[length];
745       
746       System.arraycopy(encodedToken, 2 + n + gssUpMechOidArray.length,
747                        encodedInitialContextToken, 0,
748                        length);
749       Any JavaDoc any = null;
750       try
751       {
752          any = codec.decode_value(encodedInitialContextToken,
753                                   InitialContextTokenHelper.type());
754       }
755       catch(Exception JavaDoc e)
756       {
757          return null;
758       }
759       
760       InitialContextToken contextToken =
761          InitialContextTokenHelper.extract(any);
762       
763       return contextToken;
764       
765    }
766
767    /**
768     * ASN.1-encodes a GSS exported name with the GSSUP mechanism OID.
769     * See createGSSExportedName for a description of the encoding format.
770     */

771    public static byte[] encodeGssExportedName(byte[] name)
772    {
773       return createGSSExportedName(gssUpMechOidArray, name);
774    }
775
776    /**
777     * Decodes a GSS exported name that has been encoded with the GSSUP
778     * mechanism OID. See createGSSExportedName for a description of the
779     * encoding format.
780     */

781    public static byte[] decodeGssExportedName(byte[] encodedName)
782    {
783       if(encodedName[0] != 0x04 || encodedName[1] != 0x01)
784          return null;
785       
786       int mechOidLength = (encodedName[2] & 0xFF) << 8; //MECH_OID_LEN
787
mechOidLength += (encodedName[3] & 0xFF); // MECH_OID_LEN
788

789       byte[] oidArray = new byte[mechOidLength];
790       System.arraycopy(encodedName, 4,
791                        oidArray, 0,
792                        mechOidLength);
793       
794       for(int i = 0; i < mechOidLength; i++)
795       {
796          if(gssUpMechOidArray[i] != oidArray[i])
797             return null;
798       }
799       
800       int offset = 4 + mechOidLength;
801       int nameLength = (encodedName[ offset] & 0xFF) << 24;
802       nameLength += (encodedName[++offset] & 0xFF) << 16;
803       nameLength += (encodedName[++offset] & 0xFF) << 8;
804       nameLength += (encodedName[++offset] & 0xFF);
805       
806       byte[] name = new byte[nameLength];
807       System.arraycopy(encodedName, ++offset,
808                        name, 0,
809                        nameLength);
810       
811       return name;
812    }
813    
814    /**
815     * Helper method to be called from a client request interceptor.
816     * The <code>ri</code> parameter refers to the current request.
817     * This method returns the first <code>CompoundSecMech</code>
818     * found in the target IOR such that
819     * <ul>
820     * <li>all <code>CompoundSecMech</code> requirements are satisfied
821     * by the options in the <code>clientSupports</code> parameter,
822     * and</li>
823     * <li>every requirement in the <code>clientRequires</code> parameter
824     * is satisfied by the <code>CompoundSecMech</code>.</li>
825     * </ul>
826     * The method returns null if the target IOR contains no
827     * <code>CompoundSecMech</code>s or if no
828     * matching <code>CompoundSecMech</code> is found.
829     *
830     * Since this method is intended to be called from a client request
831     * interceptor, it converts unexpected exceptions into <code>MARSHAL</code>
832     * exceptions.
833     */

834    public static CompoundSecMech getMatchingSecurityMech(ClientRequestInfo JavaDoc ri,
835       Codec JavaDoc codec,
836       short clientSupports,
837       short clientRequires)
838    {
839       CompoundSecMechList csmList = null;
840       try
841       {
842          TaggedComponent JavaDoc tc =
843             ri.get_effective_component(TAG_CSI_SEC_MECH_LIST.value);
844
845          Any JavaDoc any = codec.decode_value(tc.component_data,
846             CompoundSecMechListHelper.type());
847
848          csmList = CompoundSecMechListHelper.extract(any);
849          
850          // look for the first matching security mech
851
for(int i = 0; i < csmList.mechanism_list.length; i++)
852          {
853             CompoundSecMech securityMech = csmList.mechanism_list[i];
854             AS_ContextSec authConfig = securityMech.as_context_mech;
855
856             if( (EstablishTrustInTarget.value
857                & (clientRequires ^ authConfig.target_supports)
858                & ~authConfig.target_supports) != 0 )
859             {
860                // client requires EstablishTrustInTarget,
861
// but target does not support it:
862
continue; // skip this securityMech
863
}
864
865             if( (EstablishTrustInClient.value
866                & (authConfig.target_requires ^ clientSupports)
867                & ~clientSupports) != 0 )
868             {
869                // target requires EstablishTrustInClient,
870
// but client does not support it:
871
continue; // skip this securityMech
872
}
873
874             SAS_ContextSec identityConfig = securityMech.sas_context_mech;
875
876             if( (IdentityAssertion.value
877                & (identityConfig.target_requires ^ clientSupports)
878                & ~clientSupports) != 0 )
879             {
880                // target requires IdentityAssertion,
881
// but client does not support it:
882
continue; // skip this securityMech
883
}
884
885             // found matching securityMech
886
return securityMech;
887          }
888          // no matching securityMech was found
889
return null;
890       }
891       catch(BAD_PARAM JavaDoc e)
892       {
893          // no component with TAG_CSI_SEC_MECH_LIST was found
894
return null;
895       }
896       catch(org.omg.IOP.CodecPackage.TypeMismatch JavaDoc e)
897       {
898          // unexpected exception in codec.decode_value
899
throw new MARSHAL JavaDoc("Unexpected exception: " + e);
900       }
901       catch(org.omg.IOP.CodecPackage.FormatMismatch JavaDoc e)
902       {
903          // unexpected exception in codec.decode_value
904
throw new MARSHAL JavaDoc("Unexpected exception: " + e);
905       }
906    }
907
908    /** Generate a string representation of the CompoundSecMech
909     * @param securityMech - the CompoundSecMech to create the string for
910     * @param buffer - the buffer to write to
911     */

912    public static void toString(CompoundSecMech securityMech, StringBuffer JavaDoc buffer)
913    {
914       AS_ContextSec asMech = securityMech != null ? securityMech.as_context_mech : null;
915       SAS_ContextSec sasMech = securityMech != null ? securityMech.sas_context_mech : null;
916       if( securityMech != null )
917       {
918          buffer.append("CompoundSecMech[");
919          buffer.append("target_requires: ");
920          buffer.append(securityMech.target_requires);
921          if( asMech != null )
922          {
923             buffer.append("AS_ContextSec[");
924             
925             buffer.append("client_authentication_mech: ");
926             try
927             {
928                buffer.append(new String JavaDoc(asMech.client_authentication_mech, "UTF-8"));
929             }
930             catch(UnsupportedEncodingException JavaDoc e)
931             {
932                buffer.append(e.getMessage());
933             }
934             buffer.append(", target_name: ");
935             try
936             {
937                buffer.append(new String JavaDoc(asMech.target_name, "UTF-8"));
938             }
939             catch(UnsupportedEncodingException JavaDoc e)
940             {
941                buffer.append(e.getMessage());
942             }
943             buffer.append(", target_requires: ");
944             buffer.append(asMech.target_requires);
945             buffer.append(", target_supports: ");
946             buffer.append(asMech.target_supports);
947             buffer.append("]");
948          }
949          if( sasMech != null )
950          {
951             buffer.append("SAS_ContextSec[");
952             buffer.append("supported_identity_types: ");
953             buffer.append(sasMech.supported_identity_types);
954             buffer.append(", target_requires: ");
955             buffer.append(sasMech.target_requires);
956             buffer.append(", target_supports: ");
957             buffer.append(sasMech.target_supports);
958             buffer.append("]");
959          }
960          buffer.append("]");
961       }
962    }
963
964 }
965
Popular Tags