alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (GSSUtils.java)

This example Glassfish source code file (GSSUtils.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

attempting, bar, gss_nt_export_name_oid, gssup_mech_oid, io, ioexception, ioexception, log, logging, mech, mechanism, objectidentifier, objectidentifier, oid, oid, string, string

The Glassfish GSSUtils.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.enterprise.iiop.security;

import java.io.IOException;
import java.io.InputStream;
import sun.security.util.ObjectIdentifier;
import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream;

import com.sun.corba.ee.org.omg.GSSUP.GSSUPMechOID;
import com.sun.corba.ee.org.omg.CSI.GSS_NT_Export_Name_OID;
import com.sun.corba.ee.org.omg.CSI.GSS_NT_Scoped_Username_OID;
 
import java.util.logging.*;
import com.sun.logging.*;

/*
 * @author    Sekhar Vajjhala 
 * (Almost complete rewrite of an old version)
 *         
 */

public class GSSUtils 
{
    private static final java.util.logging.Logger _logger =
       LogDomains.getLogger(GSSUtils.class, LogDomains.CORBA_LOGGER);

    public static final ObjectIdentifier GSSUP_MECH_OID;

    public static final ObjectIdentifier GSS_NT_EXPORT_NAME_OID;

    /* GSS_NT_SCOPED_USERNAME_OID is currently not used by this class. It is
     * defined here for the sake of completeness.
     */
    public static final ObjectIdentifier GSS_NT_SCOPED_USERNAME_OID;
    
    private static byte[] mech;

    static {

        int i ; // index
        ObjectIdentifier x = null;
        
        /* Construct an ObjectIdentifer by extracting each OID */
      
        try {
            i = GSSUPMechOID.value.indexOf(':');
            x = new ObjectIdentifier( GSSUPMechOID.value.substring(i+1));
	} catch(IOException e) {
            x = null;
            _logger.log(Level.SEVERE,"iiop.IOexception",e);
	}
        GSSUP_MECH_OID = x;
         
        try {
            i = GSS_NT_Export_Name_OID.value.indexOf(':');
            x = new ObjectIdentifier( GSS_NT_Export_Name_OID.value.substring(i+1));
	} catch(IOException e) {
            x = null;
                _logger.log(Level.SEVERE,"iiop.IOexception",e);
	}
        GSS_NT_EXPORT_NAME_OID = x;
        
        try {
            i = GSS_NT_Scoped_Username_OID.value.indexOf(':');
            x = new ObjectIdentifier( GSS_NT_Scoped_Username_OID.value.substring(i+1));
	} catch(IOException e) {
            x = null;
                _logger.log(Level.SEVERE,"iiop.IOexception",e);
	}
        GSS_NT_SCOPED_USERNAME_OID = x;

        try {
	    if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"GSSUP_MECH_OID: " + dumpHex(getDER(GSSUP_MECH_OID)));
		_logger.log(Level.FINE,"GSS_NT_EXPORT_NAME_OID: " + dumpHex(getDER(GSS_NT_EXPORT_NAME_OID)));
		_logger.log(Level.FINE,"GSS_NT_SCOPED_USERNAME_OID: " + dumpHex(getDER(GSS_NT_SCOPED_USERNAME_OID)));
	    }
	} catch(IOException e) {
                _logger.log(Level.SEVERE,"iiop.IOexception",e);
	}
        
        try {
	    mech = GSSUtils.getDER(GSSUtils.GSSUP_MECH_OID);
	} catch(IOException io) {
	    mech = null;
	}
    }

    // Dumps the hex values in the given byte array
    public static String dumpHex( byte[] octets ) {
	StringBuffer result = new StringBuffer( "" );
	for( int i = 0; i < octets.length; i++ ) {
	    if( (i != 0) && ((i % 16) == 0) ) result.append( "\n    " );
	    int b = octets[i];
	    if( b < 0 ) b = 256 + b;
	    String hex = Integer.toHexString( b );
	    if( hex.length() == 1 ) {
		hex = "0" + hex;
	    }
	    result.append( hex + " " );
	}

	return result.toString();
    }

    /* Import the exported name from the mechanism independent 
     * exported name.
     */
     
    public static byte[] importName(ObjectIdentifier oid, byte[] externalName)
	throws IOException
    {
	    if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Attempting to import mechanism independent name");
		_logger.log(Level.FINE,dumpHex(externalName));
	}

	IOException e = new IOException("Invalid Name");

	if (externalName[0] != 0x04)
	    throw e;

        if (externalName[1] != 0x01)
	    throw e;

	int mechoidlen = (((int)externalName[2]) << 8)+ (externalName[3] & 0xff);

        if(_logger.isLoggable(Level.FINE)) 
		_logger.log(Level.FINE,"Mech OID length = " + mechoidlen);
	if (externalName.length < (4 + mechoidlen + 4))
	    throw e;

        /* get the mechanism OID and verify it is the same as oid
         * passed as an argument.
         */

        byte[] deroid = new byte[mechoidlen];
	System.arraycopy(externalName, 4, deroid, 0, mechoidlen);
        ObjectIdentifier oid1 = getOID(deroid);
        if  ( ! oid1.equals(oid) )
            throw e;

        int pos = 4 + mechoidlen;

	int namelen =   (((int) externalName[pos])   << 24) 
                      + (((int) externalName[pos+1]) << 16) 
                      + (((int) externalName[pos+2]) << 8)
                      + (((int) externalName[pos+3]));

        pos += 4; // start of the mechanism specific exported name

        if (externalName.length != (4 + mechoidlen + 4 + namelen))
	    throw e;

        byte[] name = new byte[externalName.length - pos];
        System.arraycopy(externalName, pos, name, 0, externalName.length - pos);
        if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Mechanism specific name:");
		_logger.log(Level.FINE,dumpHex(name));
		_logger.log(Level.FINE,"Successfully imported mechanism independent name");
	}
	return name;
    }

    /* verify if exportedName is of object ObjectIdentifier.*/
     
    public static boolean verifyMechOID(ObjectIdentifier oid, byte[] externalName)
	throws IOException
    {
        if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Attempting to verify mechanism independent name");
		_logger.log(Level.FINE,dumpHex(externalName));
	}

	IOException e = new IOException("Invalid Name");

	if (externalName[0] != 0x04)
	    throw e;

        if (externalName[1] != 0x01)
	    throw e;

	int mechoidlen = (((int)externalName[2]) << 8)+ (externalName[3] & 0xff);

	    if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Mech OID length = " + mechoidlen);
            }
	if (externalName.length < (4 + mechoidlen + 4))
	    throw e;

        /* get the mechanism OID and verify it is the same as oid
         * passed as an argument.
         */

        byte[] deroid = new byte[mechoidlen];
	System.arraycopy(externalName, 4, deroid, 0, mechoidlen);
        ObjectIdentifier oid1 = getOID(deroid);
        if  ( ! oid1.equals(oid) )
            return false;
        else
            return true;
    }


    /*
     *  Generate an exported name as specified in [RFC 2743]
     *  section 3.2, "Mechanism-Independent Exported Name Object Format". 
     *  For convenience, the format of the exported name is reproduced here
     *  from [RFC2743] :
     * 
     *  Format:
     *  Bytes
     *  2          0x04 0x01
     *  2          mech OID length (len)
     *  len        mech OID's DER value
     *  4          exported name len
     *  name len   exported name
     *
     */

    public static byte[] createExportedName(ObjectIdentifier oid, byte[] extName)
	throws IOException
    {
	byte[] oidDER = getDER(oid);
	int tokensize =  2 + 2 + oidDER.length + 4 + extName.length;

	byte[] token = new byte[tokensize];

        // construct the Exported Name 
        int pos = 0;

        token[0] = 0x04;
        token[1] = 0x01;
        token[2] = (byte)(oidDER.length & 0xFF00);
        token[3] = (byte)(oidDER.length & 0x00FF);

        pos = 4;
        System.arraycopy(oidDER, 0, token, pos, oidDER.length);
        pos += oidDER.length;

        int namelen = extName.length;

        token[pos++] = (byte)(namelen & 0xFF000000);
        token[pos++] = (byte)(namelen & 0x00FF0000);
        token[pos++] = (byte)(namelen & 0x0000FF00);
        token[pos++] = (byte)(namelen & 0x000000FF);

        System.arraycopy(extName, 0, token, pos, namelen);

        return token;
    }

    /*
     * Return the DER representation of an ObjectIdentifier.
     * The DER representation is as follows:
     *   
     *    0x06            --  Tag for OBJECT IDENTIFIER
     *    derOID.length   --  length in octets of OID
     *    DER value of OID -- written as specified byte the DER representation
     *                        for an ObjectIdentifier.
     */

    public static byte[] getDER(ObjectIdentifier id) 
	throws IOException
    {
        if(_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE,"Returning OID in DER format");
            _logger.log(Level.FINE,"    OID = " + id.toString());
        }
	DerOutputStream dos = new DerOutputStream();
	dos.putOID(id);
	byte[] oid = dos.toByteArray();
        if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"    DER OID: " + dumpHex(oid));
        }
	return oid;
    }

    /*
     * Return the OID corresponding to an OID represented in DER format
     * as follows:
     *
     *    0x06            --  Tag for OBJECT IDENTIFIER
     *    derOID.length   --  length in octets of OID
     *    DER value of OID -- written as specified byte the DER representation
     *                        for an ObjectIdentifier.
     */

     public static ObjectIdentifier getOID(byte[] derOID)
         throws IOException
     {
         DerInputStream dis = new DerInputStream(derOID);
         ObjectIdentifier oid = dis.getOID();

         /* Note: getOID() method call generates an IOException
          *       if derOID contains any malformed data
          */
         return oid;
     }


    /*
     * Construct a mechanism level independent token as specified in section
     * 3.1, [RFC 2743]. This consists of a token tag followed byte a mechanism
     * specific token. The format - here for convenience - is as follows:
     *
     *  Token Tag                      Description
     *
     *     0x60                       | Tag for [APPLICATION 0] SEQUENCE
     *     <token-length-octets>      |
     *     0x06                       | Along with the next two entries
     *     <object-identifier-length> | is a DER encoding of an object 
     *     <object-identifier-octets> | identifier
     * 
     *  Mechanism specific token      | format defined by the mechanism itself
     *                                  outside of RFC 2743.
     */

    public static byte[] createMechIndToken(ObjectIdentifier mechoid, byte mechtok[])
	throws IOException 
    {
	byte [] deroid = getDER(mechoid);

        byte [] token = new byte[  1  // for 0x60
                                 + getDERLengthSize(deroid.length+mechtok.length)
				 + deroid.length
                                 + mechtok.length];
        if(_logger.isLoggable(Level.FINE)){
            _logger.log(Level.FINE,"Going to create a mechanism independent token");
        }
	int index=0;

	token[index++] = 0x60;

	index = writeDERLength(token, index, deroid.length + mechtok.length);

        System.arraycopy(deroid, 0, token, index, deroid.length);

	index += deroid.length;
	System.arraycopy(mechtok, 0, token, index, mechtok.length);

        if(_logger.isLoggable(Level.FINE)){
            _logger.log(Level.FINE,"Mechanism independent token created: ");
            _logger.log(Level.FINE,dumpHex(token));
        }
	return token;
    }

    /*
     * Retrieve a mechanism specific token from a mechanism independent token.
     * The format of a mechanism independent token is specified in section
     * 3.1, [RFC 2743].
     */

    public static byte[] getMechToken(ObjectIdentifier oid, byte[] token) {

	byte[] mechtoken = null;
	    if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Received mechanism independent token: ");
		_logger.log(Level.FINE,dumpHex(token));
	}

	try {
	    int index      = verifyTokenHeader(oid, token);
	    int mechtoklen = token.length - index;
	    mechtoken      = new byte[mechtoklen];
            System.arraycopy(token, index, mechtoken, 0, mechtoklen);
	    if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Mechanism specific token : ");
		_logger.log(Level.FINE,dumpHex(mechtoken));
	    }
	} catch(IOException e) {
            _logger.log(Level.SEVERE,"iiop.IOexception",e);
	}
	return mechtoken;
    }


   /* Verfies the header of a mechanism independent token. The header must
    * be as specified in RFC 2743, section 3.1. The header must contain
    * an object identifier specified by the first parameter.
    *
    * If the header is well formed, then the starting position of the
    * mechanism specific token within the token is returned.
    * 
    * If the header is mal formed, then an exception is thrown.
    */

    private static int verifyTokenHeader(ObjectIdentifier oid, byte [] token)
	throws IOException
    {
	int index=0;
        if(_logger.isLoggable(Level.FINE)){
            _logger.log(Level.FINE,"Attempting to verify tokenheader in the mechanism independent token.");
        }
        // verify header
	if (token[index++] != 0x60) 
	    throw new IOException("Defective Token");

        int toklen = readDERLength(token, index); // derOID length + token length

        if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Mech OID length + Mech specific length = " + toklen);
        }
        index += getDERLengthSize(toklen);
        if(_logger.isLoggable(Level.FINE)){
		_logger.log(Level.FINE,"Mechanism OID index : " + index);
        }

        if (token[index] != 0x06) 
	    throw new IOException("Defective Token");

        byte[] buf = new byte[ token.length - index ];

	System.arraycopy(token, index, buf, 0, token.length - index);

        ObjectIdentifier mechoid = getOID(buf);

        if(_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE,"Comparing mech OID in token with the expected mech OID");
            _logger.log(Level.FINE,"mech OID: " + dumpHex(getDER(mechoid)));
            _logger.log(Level.FINE,"expected mech OID: " + dumpHex(getDER(oid)));
	}

        if ( ! mechoid.equals(oid)) {
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE,"mech OID in token does not match expected mech OID");
            }
            throw new IOException("Defective token");
        }
        int mechoidlen = getDER(oid).length;

        if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Mechanism specific token index : " + index + mechoidlen);
		_logger.log(Level.FINE,"Successfully verified header in the mechanism independent token.");
	}
        return (index + mechoidlen); // starting position of mech specific token
    }

    static int getDERLengthSize(int length)
    {
	if (length < (1<<7))
	    return (1);
	else if (length < (1<<8))
	    return (2);
	else if (length < (1<<16))
	    return (3);
	else if (length < (1<<24))
	    return (4);
	else
	    return (5);
    }

    static int writeDERLength(byte [] token, int index, int length)
    {
	if (length < (1<<7)) {
	    token[index++] = (byte)length;
	} else {
	    token[index++] = (byte)(getDERLengthSize(length)+127);
	    if (length >= (1<<24))
		token[index++] = (byte)(length>>24);
	    if (length >= (1<<16))
		token[index++] = (byte)((length>>16)&0xff);
	    if (length >= (1<<8))
		token[index++] = (byte)((length>>8)&0xff);
	    token[index++] = (byte)(length&0xff);
	}
	return (index);
    }

    static int readDERLength(byte[] token, int index)
    {
	byte sf;
        int ret = 0;
        int nooctets;

	sf = token[index++];

	if ((sf & 0x80) == 0x80) { // value > 128
	    // bit 8 is 1 ; bits 0-7 of first bye is the number of octets
	    nooctets = (sf & 0x7f) ; // remove the 8th bit
            for (; nooctets != 0; nooctets--)
                ret = (ret<<8) + (token[index++] & 0x00FF);
	} else 
            ret = sf;
  
	return(ret);
    }
    
   /**
     * Return the ASN.1 encoded representation of a GSS mechanism identifier.
     * Currently only the GSSUP Mechanism is supported.
     */
    public static byte[] getMechanism() {
        return mech;
    }


    public static void main(String[] args) {
	try {
            byte[] len = new byte[3];
            len[0] = (byte) 0x82;
            len[1] = (byte) 0x01;
            len[2] = (byte) 0xd3;
	    if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Length byte array : " + dumpHex(len));
		_logger.log(Level.FINE," Der length = " + readDERLength(len,0));
	    }
	    String name = "default";
	    byte[] externalName = createExportedName(GSSUtils.GSSUP_MECH_OID, name.getBytes());
	    byte[] m = importName(GSSUtils.GSSUP_MECH_OID, externalName);
	    if(_logger.isLoggable(Level.FINE))
                _logger.log(Level.FINE,"BAR:" + new String(m));
	    String msg = "dummy_gss_export_sec_context" ;
	    byte[] foo = createMechIndToken(GSSUtils.GSSUP_MECH_OID, msg.getBytes());
	    if(_logger.isLoggable(Level.FINE))
                _logger.log(Level.FINE,"FOO:" + dumpHex(foo));
	    byte[] msg1 = getMechToken(GSSUtils.GSSUP_MECH_OID, foo); 
	    if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE,"BAR:" + dumpHex(msg1));
	        _logger.log(Level.FINE,"BAR string: " + new String(msg1));
	    }
	} catch(Exception e) {
                _logger.log(Level.SEVERE,"iiop.name_exception",e);
	}
    }

}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish GSSUtils.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.