org.jboss.iiop.csiv2.CSIv2Util Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.iiop.csiv2;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.Oid;
import org.jboss.logging.Logger;
import org.jboss.metadata.IorSecurityConfigMetaData;
import org.jboss.metadata.IorSecurityConfigMetaData.AsContext;
import org.jboss.metadata.IorSecurityConfigMetaData.SasContext;
import org.jboss.metadata.IorSecurityConfigMetaData.TransportConfig;
import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.ORB;
import org.omg.CSI.ITTAnonymous;
import org.omg.CSI.ITTDistinguishedName;
import org.omg.CSI.ITTPrincipalName;
import org.omg.CSI.ITTX509CertChain;
import org.omg.CSIIOP.AS_ContextSec;
import org.omg.CSIIOP.CompoundSecMech;
import org.omg.CSIIOP.CompoundSecMechList;
import org.omg.CSIIOP.CompoundSecMechListHelper;
import org.omg.CSIIOP.Confidentiality;
import org.omg.CSIIOP.DetectMisordering;
import org.omg.CSIIOP.DetectReplay;
import org.omg.CSIIOP.EstablishTrustInClient;
import org.omg.CSIIOP.EstablishTrustInTarget;
import org.omg.CSIIOP.IdentityAssertion;
import org.omg.CSIIOP.Integrity;
import org.omg.CSIIOP.SAS_ContextSec;
import org.omg.CSIIOP.ServiceConfiguration;
import org.omg.CSIIOP.TAG_CSI_SEC_MECH_LIST;
import org.omg.CSIIOP.TAG_NULL_TAG;
import org.omg.CSIIOP.TAG_TLS_SEC_TRANS;
import org.omg.CSIIOP.TLS_SEC_TRANS;
import org.omg.CSIIOP.TLS_SEC_TRANSHelper;
import org.omg.CSIIOP.TransportAddress;
import org.omg.GSSUP.GSSUPMechOID;
import org.omg.GSSUP.InitialContextToken;
import org.omg.GSSUP.InitialContextTokenHelper;
import org.omg.IOP.Codec;
import org.omg.IOP.TaggedComponent;
import org.omg.IOP.CodecPackage.InvalidTypeForEncoding;
import org.omg.PortableInterceptor.ClientRequestInfo;
import org.omg.SSLIOP.SSL;
import org.omg.SSLIOP.SSLHelper;
import org.omg.SSLIOP.TAG_SSL_SEC_TRANS;
/**
* Helper class
*
* @author [email protected]
* @author Francisco Reverbel
* @author Stefan Neusatz Guilhen
* @version $Revision: 64028 $
*/
public final class CSIv2Util
{
private static final Logger log = Logger.getLogger(CSIv2Util.class);
/** DER-encoded ASN.1 representation of the GSSUP mechanism OID. */
private static final byte[] gssUpMechOidArray = createGSSUPMechOID();
private CSIv2Util()
{
// static calls only
}
/**
* Make a deep copy of an IOP:TaggedComponent
**/
public static TaggedComponent createCopy(TaggedComponent tc)
{
TaggedComponent copy = null;
if( tc != null )
{
byte[] buf = new byte[tc.component_data.length];
System.arraycopy(tc.component_data, 0, buf, 0, tc.component_data.length);
copy = new TaggedComponent(tc.tag, buf);
}
return copy;
}
/**
* Return a top-level IOP::TaggedComponent to be stuffed into an IOR,
* containing an structure SSLIOP::SSL, tagged as TAG_SSL_SEC_TRANS.
*
* Should be called with non-null metadata, in which case we probably
* don't want to include security info in the IOR.
**/
public static TaggedComponent createSSLTaggedComponent(
IorSecurityConfigMetaData metadata,
Codec codec,
int sslPort,
ORB orb)
{
if( metadata == null )
{
log.debug("createSSLTaggedComponent() called with null metadata");
return null;
}
TaggedComponent tc = null;
try
{
int supports = createTargetSupports(metadata.getTransportConfig());
int requires = createTargetRequires(metadata.getTransportConfig());
SSL ssl = new SSL((short) supports, (short) requires, (short) sslPort);
Any any = orb.create_any();
SSLHelper.insert(any, ssl);
byte[] componentData = codec.encode_value(any);
tc = new TaggedComponent(TAG_SSL_SEC_TRANS.value, componentData);
}
catch(InvalidTypeForEncoding e)
{
log.warn("Caught unexcepted exception while encoding SSL component", e);
throw new RuntimeException(e);
}
return tc;
}
/**
* Return a top-level IOP:TaggedComponent to be stuffed into an IOR,
* containing a CSIIOP.CompoundSecMechList, tagged as TAG_CSI_SEC_MECH_LIST.
* Only one such component can exist inside an IOR.
*
* Should be called with non-null metadata, in which case we probably
* don't want to include security info in the IOR.
**/
public static TaggedComponent createSecurityTaggedComponent(
IorSecurityConfigMetaData metadata,
Codec codec,
int sslPort,
ORB orb
)
{
if( metadata == null )
{
log.debug("createSecurityTaggedComponent() called with null metadata");
return null;
}
TaggedComponent tc = null;
// Get the the supported security mechanisms (just one :)
CompoundSecMech[] mechList =
createCompoundSecMechanisms(metadata, codec, sslPort, orb);
// the above is wrapped into a CSIIOP.CompoundSecMechList
// structure, which is NOT a CompoundSecMech[] !!!
//
// We DONT support stateful/reusable security contexts (false)
CompoundSecMechList csmList = new CompoundSecMechList(false,
mechList);
// finally, the CompoundSecMechList must be encoded as a TaggedComponent
try
{
Any any = orb.create_any();
CompoundSecMechListHelper.insert(any, csmList);
byte[] b = codec.encode_value(any);
tc = new TaggedComponent(TAG_CSI_SEC_MECH_LIST.value, b);
}
catch(InvalidTypeForEncoding e)
{
log.warn("Caught unexcepted exception while encoding CompoundSecMechList", e);
throw new RuntimeException(e);
}
return tc;
}
/**
* Create a CSIIOP.CompoundSecMechanisms which is a sequence of
* CompoundSecMech. Here we only support one security mechanism.
**/
public static CompoundSecMech[] createCompoundSecMechanisms(
IorSecurityConfigMetaData metadata,
Codec codec,
int sslPort,
ORB orb
)
{
// Support just 1 security mechanism for now (and ever :)
CompoundSecMech[] csmList = new CompoundSecMech[1];
// A CompoundSecMech contains:
// target_requires, transport_mech, as_context_mech, sas_context_mech
// The transport mechanism is an IOP.TaggedComponent itself
// to allow for arbitrary transport mechanisms be specified.
// This will configure SSL or none.
TaggedComponent transport_mech = createTransportMech(
metadata.getTransportConfig(), codec, sslPort, orb
);
// Create AS Context
AS_ContextSec asContext = createAuthenticationServiceContext(metadata);
// Create SAS Context
SAS_ContextSec sasContext = createSecureAttributeServiceContext(metadata);
// Create target_requires bit field (AssociationOption)
// can't read directly the transport_mech TaggedComponent
int target_requires =
createTargetRequires(metadata.getTransportConfig()) |
asContext.target_requires |
sasContext.target_requires;
// wrap it up
CompoundSecMech csm = new CompoundSecMech((short) target_requires,
transport_mech,
asContext,
sasContext);
// store it in csmList as the only security mechanism
csmList[0] = csm;
return csmList;
}
/**
* Create the Secure Attribute Service (SAS) context
* included in a CompoundSecMech definition
**/
public static SAS_ContextSec createSecureAttributeServiceContext(
IorSecurityConfigMetaData metadata
)
{
SAS_ContextSec context = null;
// context contains
// target_supports, target_requires, privilige_authorities,
// supported_naming_mechanisms, supported_identity_types
int support = 0;
int require = 0;
ServiceConfiguration[] privilAuth = new ServiceConfiguration[0];
byte[][] supNamMechs = {};
int supIdenTypes = 0; // 0 means ITTAbsent
// the the SasContext metadata
SasContext sasMeta = metadata.getSasContext();
// if no SAS context metadata, or caller propagation is not
// supported, we return with a more or less empty sas context
if( sasMeta == null || !sasMeta.isCallerPropagationSupported() )
{
context = new SAS_ContextSec((short) support,
(short) require,
privilAuth,
supNamMechs,
supIdenTypes);
}
else
{
support = IdentityAssertion.value;
// supporting GSSUP (username/password) naming mechanism
byte[] upMech = createGSSUPMechOID();
supNamMechs = new byte[1][upMech.length];
System.arraycopy(upMech, 0, supNamMechs[0], 0, upMech.length);
// since we support IdentityAssertion we need to specify
// supported identity types. CTS says we need them all
supIdenTypes = ITTAnonymous.value |
ITTPrincipalName.value |
ITTX509CertChain.value |
ITTDistinguishedName.value;
// wrap it up
context = new SAS_ContextSec((short) support,
(short) require,
privilAuth,
supNamMechs,
supIdenTypes);
}
return context;
}
/**
* Create the client Authentication Service (AS) context
* included in a CompoundSecMech definition.
**/
public static AS_ContextSec createAuthenticationServiceContext(
IorSecurityConfigMetaData metadata
)
{
AS_ContextSec context = null;
// the content of the context
int support = 0;
int require = 0;
byte[] clientAuthMech = {};
byte[] targetName = {};
// get the AsContext metadata
AsContext asMeta = metadata.getAsContext();
// if no AS context metatada exists, or authentication method
// "none" is specified, we can produce an empty AS context
if( asMeta == null || asMeta.getAuthMethod().equals(AsContext.AUTH_METHOD_NONE)
/*|| asMeta.isRequired() == false*/ )
{
context = new AS_ContextSec((short) support,
(short) require,
clientAuthMech,
targetName);
}
else
{
// we do support
support = EstablishTrustInClient.value;
// required depends on the metadata
if( asMeta.isRequired() )
require = EstablishTrustInClient.value;
// we only support GSSUP authentication method
clientAuthMech = createGSSUPMechOID();
// finally, encode the "realm" name as a CSI.GSS_NT_ExportedName.
// clientAuthMech should contain the DER encoded GSSUPMechOID
// at this point.
String realm = asMeta.getRealm();
targetName = createGSSExportedName(clientAuthMech, realm.getBytes());
// wrap it up
context = new AS_ContextSec((short) support,
(short) require,
clientAuthMech,
targetName);
}
return context;
}
/**
* Create a transport mechanism TaggedComponent to be stuffed into a
* CompoundSecMech.
*
* If no TransportConfig metadata is specified, or ssl port is negative,
* or the specified metadata indicates that transport config is not supported,
* then a TAG_NULL_TAG (empty) TaggedComponent will be returned.
*
* Otherwise a CSIIOP.TLS_SEC_TRANS, tagged as TAG_TLS_SEC_TRANS will
* be returned, indicating support for TLS/SSL as a CSIv2 transport
* mechanism.
*
* Multiple TransportAddress may be included in the SSL info
* (host/port pairs), but we only include one.
**/
public static TaggedComponent createTransportMech(
TransportConfig tconfig,
Codec codec,
int sslPort,
ORB orb
)
{
TaggedComponent tc = null;
// what we support and require as a target
int support = 0;
int require = 0;
if( tconfig != null )
{
require = createTargetRequires(tconfig);
support = createTargetSupports(tconfig);
}
if( tconfig == null || support == 0 || sslPort < 0 )
{
// no support for transport security
tc = new TaggedComponent(TAG_NULL_TAG.value, new byte[0]);
}
else
{
// my ip address
String host;
try
{
host = InetAddress.getLocalHost().getHostAddress();
}
catch(java.net.UnknownHostException e)
{
host = "127.0.0.1";
}
// this will create only one transport address
TransportAddress[] taList = createTransportAddress(host, sslPort);
TLS_SEC_TRANS tst = new TLS_SEC_TRANS((short) support,
(short) require,
taList);
// The tricky part, we must encode TLS_SEC_TRANS into an octet sequence
try
{
Any any = orb.create_any();
TLS_SEC_TRANSHelper.insert(any, tst);
byte[] b = codec.encode_value(any);
tc = new TaggedComponent(TAG_TLS_SEC_TRANS.value, b);
}
catch(InvalidTypeForEncoding e)
{
log.warn("Caught unexcepted exception while encoding TLS_SEC_TRANS", e);
throw new RuntimeException(e);
}
}
return tc;
}
/**
* Create a TransportAddress[] with a single TransportAddress
**/
public static TransportAddress[] createTransportAddress(
String host, int port
)
{
// idl type is unsighned sort, so we need this trick
short short_port = (port > 32767) ? (short) (port - 65536) : (short) port;
TransportAddress ta = new TransportAddress(host, short_port);
TransportAddress[] taList = new TransportAddress[1];
taList[0] = ta;
return taList;
}
/**
* Create the AssociationOption for CompoundSecMech - target_requires
**/
public static int createTargetRequires(TransportConfig tc)
{
int requires = 0;
if( tc != null )
{
if( tc.getIntegrity().equals(TransportConfig.INTEGRITY_REQUIRED) )
requires = requires | Integrity.value;
if( tc.getConfidentiality().equals(TransportConfig.CONFIDENTIALITY_REQUIRED) )
requires = requires | Confidentiality.value;
if( tc.getDetectMisordering().equalsIgnoreCase(TransportConfig.DETECT_MISORDERING_REQUIRED) )
requires = requires | DetectMisordering.value;
if( tc.getDetectReplay().equalsIgnoreCase(TransportConfig.DETECT_REPLAY_REQUIRED) )
requires = requires | DetectReplay.value;
// no EstablishTrustInTarget required - client decides
if( tc.getEstablishTrustInClient().equals(TransportConfig.ESTABLISH_TRUST_IN_CLIENT_REQUIRED) )
requires = requires | EstablishTrustInClient.value;
}
return requires;
}
/**
* Create bitmask of what the target supports
**/
public static int createTargetSupports(TransportConfig tc)
{
int supports = 0;
if( tc != null )
{
if( !tc.getIntegrity().equals(TransportConfig.INTEGRITY_NONE) )
supports = supports | Integrity.value;
if( !tc.getConfidentiality().equals(TransportConfig.CONFIDENTIALITY_NONE) )
supports = supports | Confidentiality.value;
if( !tc.getDetectMisordering().equalsIgnoreCase(TransportConfig.DETECT_MISORDERING_NONE) )
supports = supports | DetectMisordering.value;
if( !tc.getDetectReplay().equalsIgnoreCase(TransportConfig.DETECT_REPLAY_NONE) )
supports = supports | DetectReplay.value;
if( !tc.getEstablishTrustInTarget().equals(TransportConfig.ESTABLISH_TRUST_IN_TARGET_NONE) )
supports = supports | EstablishTrustInTarget.value;
if( !tc.getEstablishTrustInClient().equals(TransportConfig.ESTABLISH_TRUST_IN_CLIENT_NONE) )
supports = supports | EstablishTrustInClient.value;
}
return supports;
}
/**
* Create an ASN.1, DER encoded representation for
* the GSSUP OID mechanism
**/
public static byte[] createGSSUPMechOID()
{
// kudos to org.ietf.jgss.Oid for the Oid utility
// need to strip the "oid:" part of the GSSUPMechOID first
byte[] retval = {};
try
{
Oid oid = new Oid(GSSUPMechOID.value.substring(4));
retval = oid.getDER();
}
catch(GSSException e)
{
log.warn("Caught exception while encoding GSSUPMechOID", e);
}
return retval;
}
/**
* Return an ASN.1, DER encoded representation for the GSSUP OID mechanism.
**/
public static byte[] gssUpMechOid()
{
return (byte[])gssUpMechOidArray.clone();
}
/**
* Generate an exported name as specified in [RFC 2743], section 3.2
* copied below:
*
* 3.2: Mechanism-Independent Exported Name Object Format
*
* This section specifies a mechanism-independent level of encapsulating
* representation for names exported via the GSS_Export_name() call,
* including an object identifier representing the exporting mechanism.
* The format of names encapsulated via this representation shall be
* defined within individual mechanism drafts. The Object Identifier
* value to indicate names of this type is defined in Section 4.7 of
* this document.
*
* No name type OID is included in this mechanism-independent level of
* format definition, since (depending on individual mechanism
* specifications) the enclosed name may be implicitly typed or may be
* explicitly typed using a means other than OID encoding.
*
* The bytes within MECH_OID_LEN and NAME_LEN elements are represented
* most significant byte first (equivalently, in IP network byte order).
*
* Length Name Description
*
* 2 TOK_ID Token Identifier
* For exported name objects, this
* must be hex 04 01.
* 2 MECH_OID_LEN Length of the Mechanism OID
* MECH_OID_LEN MECH_OID Mechanism OID, in DER
* 4 NAME_LEN Length of name
* NAME_LEN NAME Exported name; format defined in
* applicable mechanism draft.
*
* A concrete example of the contents of an exported name object,
* derived from the Kerberos Version 5 mechanism, is as follows:
*
* 04 01 00 0B 06 09 2A 86 48 86 F7 12 01 02 02 hx xx xx xl pp qq ... zz
*
* ...
*
* @param oid the DER encoded OID
* @param name the name to be converted to GSSExportedName
**/
public static byte[] createGSSExportedName(byte[] oid, byte[] name)
{
int olen = oid.length;
int nlen = name.length;
// size according to spec
int size = 2 + 2 + olen + 4 + nlen;
// allocate space for the exported name
byte[] buf = new byte[size];
// index
int i = 0;
// standard header
buf[i++] = 0x04;
buf[i++] = 0x01;
// encode oid length
buf[i++] = (byte) (olen & 0xFF00);
buf[i++] = (byte) (olen & 0x00FF);
// copy the oid in the exported name buffer
System.arraycopy(oid, 0, buf, i, olen);
i += olen;
// encode the name length in the exported buffer
buf[i++] = (byte) (nlen & 0xFF000000);
buf[i++] = (byte) (nlen & 0x00FF0000);
buf[i++] = (byte) (nlen & 0x0000FF00);
buf[i++] = (byte) (nlen & 0x000000FF);
// finally, copy the name bytes
System.arraycopy(name, 0, buf, i, nlen);
// done
return buf;
}
/**
* ASN.1-encode an InitialContextToken as defined in RFC 2743, Section 3.1,
* "Mechanism-Independent Token Format", pp. 81-82. The encoded token
* contains the ASN.1 tag 0x60, followed by a token length (which is itself
* stored in a variable-lenght format and takes 1 to 5 bytes), the GSSUP
* mechanism identifier, and a mechanism-specific token, which in this
* case is a CDR encapsulation of the GSSUP InitialContextToken in the
* authToken parameter.
*/
public static byte[] encodeInitialContextToken(InitialContextToken authToken,
Codec codec)
{
byte[] out = null;
Any any = ORB.init().create_any();
InitialContextTokenHelper.insert(any, authToken);
try
{
out = codec.encode_value(any);
}
catch (Exception e)
{
// logger.error("Error encoding for GSSNameSpi: " + e);
return new byte[0];
}
int length = out.length + gssUpMechOidArray.length;
int n;
if (length < (1 << 7))
n = 0;
else if (length < (1 << 8))
n = 1;
else if (length < (1 << 16))
n = 2;
else if (length < (1 << 24))
n = 3;
else // if (length < (1 << 32))
n = 4;
byte[] encodedToken = new byte[2 + n + length];
encodedToken[0] = 0x60;
if (n == 0)
encodedToken[1] = (byte)length;
else
{
encodedToken[1] = (byte)(n | 0x80);
switch (n)
{
case 1:
encodedToken[2] = (byte)length;
break;
case 2:
encodedToken[2] = (byte)(length >> 8);
encodedToken[3] = (byte)length;
break;
case 3:
encodedToken[2] = (byte)(length >> 16);
encodedToken[3] = (byte)(length >> 8);
encodedToken[4] = (byte)length;
break;
default: // case 4:
encodedToken[2] = (byte)(length >> 24);
encodedToken[3] = (byte)(length >> 16);
encodedToken[4] = (byte)(length >> 8);
encodedToken[5] = (byte)length;
}
}
System.arraycopy(gssUpMechOidArray, 0,
encodedToken, 2 + n,
gssUpMechOidArray.length);
System.arraycopy(out, 0,
encodedToken, 2 + n + gssUpMechOidArray.length,
out.length);
return encodedToken;
}
/**
* Decodes an ASN.1-encoded InitialContextToken.
* See encodeInitialContextToken for a description of the encoded token
* format.
*/
public static InitialContextToken decodeInitialContextToken(
byte[] encodedToken,
Codec codec)
{
if(encodedToken[0] != 0x60)
return null;
int encodedLength = 0;
int n = 0;
if(encodedToken[1] >= 0)
encodedLength = encodedToken[1];
else
{
n = encodedToken[1] & 0x7F;
for(int i = 1; i <= n; i++)
encodedLength += (encodedToken[1 + i] & 0xFF) << (n-i)*8;
}
int length = encodedLength - gssUpMechOidArray.length;
byte[] encodedInitialContextToken = new byte[length];
System.arraycopy(encodedToken, 2 + n + gssUpMechOidArray.length,
encodedInitialContextToken, 0,
length);
Any any = null;
try
{
any = codec.decode_value(encodedInitialContextToken,
InitialContextTokenHelper.type());
}
catch(Exception e)
{
return null;
}
InitialContextToken contextToken =
InitialContextTokenHelper.extract(any);
return contextToken;
}
/**
* ASN.1-encodes a GSS exported name with the GSSUP mechanism OID.
* See createGSSExportedName for a description of the encoding format.
*/
public static byte[] encodeGssExportedName(byte[] name)
{
return createGSSExportedName(gssUpMechOidArray, name);
}
/**
* Decodes a GSS exported name that has been encoded with the GSSUP
* mechanism OID. See createGSSExportedName for a description of the
* encoding format.
*/
public static byte[] decodeGssExportedName(byte[] encodedName)
{
if(encodedName[0] != 0x04 || encodedName[1] != 0x01)
return null;
int mechOidLength = (encodedName[2] & 0xFF) << 8; //MECH_OID_LEN
mechOidLength += (encodedName[3] & 0xFF); // MECH_OID_LEN
byte[] oidArray = new byte[mechOidLength];
System.arraycopy(encodedName, 4,
oidArray, 0,
mechOidLength);
for(int i = 0; i < mechOidLength; i++)
{
if(gssUpMechOidArray[i] != oidArray[i])
return null;
}
int offset = 4 + mechOidLength;
int nameLength = (encodedName[ offset] & 0xFF) << 24;
nameLength += (encodedName[++offset] & 0xFF) << 16;
nameLength += (encodedName[++offset] & 0xFF) << 8;
nameLength += (encodedName[++offset] & 0xFF);
byte[] name = new byte[nameLength];
System.arraycopy(encodedName, ++offset,
name, 0,
nameLength);
return name;
}
/**
* Helper method to be called from a client request interceptor.
* The ri
parameter refers to the current request.
* This method returns the first CompoundSecMech
* found in the target IOR such that
*
* - all
CompoundSecMech
requirements are satisfied
* by the options in the clientSupports
parameter,
* and
* - every requirement in the
clientRequires
parameter
* is satisfied by the CompoundSecMech
.
*
* The method returns null if the target IOR contains no
* CompoundSecMech
s or if no
* matching CompoundSecMech
is found.
*
* Since this method is intended to be called from a client request
* interceptor, it converts unexpected exceptions into MARSHAL
* exceptions.
*/
public static CompoundSecMech getMatchingSecurityMech(ClientRequestInfo ri,
Codec codec,
short clientSupports,
short clientRequires)
{
CompoundSecMechList csmList = null;
try
{
TaggedComponent tc =
ri.get_effective_component(TAG_CSI_SEC_MECH_LIST.value);
Any any = codec.decode_value(tc.component_data,
CompoundSecMechListHelper.type());
csmList = CompoundSecMechListHelper.extract(any);
// look for the first matching security mech
for(int i = 0; i < csmList.mechanism_list.length; i++)
{
CompoundSecMech securityMech = csmList.mechanism_list[i];
AS_ContextSec authConfig = securityMech.as_context_mech;
if( (EstablishTrustInTarget.value
& (clientRequires ^ authConfig.target_supports)
& ~authConfig.target_supports) != 0 )
{
// client requires EstablishTrustInTarget,
// but target does not support it:
continue; // skip this securityMech
}
if( (EstablishTrustInClient.value
& (authConfig.target_requires ^ clientSupports)
& ~clientSupports) != 0 )
{
// target requires EstablishTrustInClient,
// but client does not support it:
continue; // skip this securityMech
}
SAS_ContextSec identityConfig = securityMech.sas_context_mech;
if( (IdentityAssertion.value
& (identityConfig.target_requires ^ clientSupports)
& ~clientSupports) != 0 )
{
// target requires IdentityAssertion,
// but client does not support it:
continue; // skip this securityMech
}
// found matching securityMech
return securityMech;
}
// no matching securityMech was found
return null;
}
catch(BAD_PARAM e)
{
// no component with TAG_CSI_SEC_MECH_LIST was found
return null;
}
catch(org.omg.IOP.CodecPackage.TypeMismatch e)
{
// unexpected exception in codec.decode_value
throw new MARSHAL("Unexpected exception: " + e);
}
catch(org.omg.IOP.CodecPackage.FormatMismatch e)
{
// unexpected exception in codec.decode_value
throw new MARSHAL("Unexpected exception: " + e);
}
}
/** Generate a string representation of the CompoundSecMech
* @param securityMech - the CompoundSecMech to create the string for
* @param buffer - the buffer to write to
*/
public static void toString(CompoundSecMech securityMech, StringBuffer buffer)
{
AS_ContextSec asMech = securityMech != null ? securityMech.as_context_mech : null;
SAS_ContextSec sasMech = securityMech != null ? securityMech.sas_context_mech : null;
if( securityMech != null )
{
buffer.append("CompoundSecMech[");
buffer.append("target_requires: ");
buffer.append(securityMech.target_requires);
if( asMech != null )
{
buffer.append("AS_ContextSec[");
buffer.append("client_authentication_mech: ");
try
{
buffer.append(new String(asMech.client_authentication_mech, "UTF-8"));
}
catch(UnsupportedEncodingException e)
{
buffer.append(e.getMessage());
}
buffer.append(", target_name: ");
try
{
buffer.append(new String(asMech.target_name, "UTF-8"));
}
catch(UnsupportedEncodingException e)
{
buffer.append(e.getMessage());
}
buffer.append(", target_requires: ");
buffer.append(asMech.target_requires);
buffer.append(", target_supports: ");
buffer.append(asMech.target_supports);
buffer.append("]");
}
if( sasMech != null )
{
buffer.append("SAS_ContextSec[");
buffer.append("supported_identity_types: ");
buffer.append(sasMech.supported_identity_types);
buffer.append(", target_requires: ");
buffer.append(sasMech.target_requires);
buffer.append(", target_supports: ");
buffer.append(sasMech.target_supports);
buffer.append("]");
}
buffer.append("]");
}
}
}