You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2007/09/24 12:18:45 UTC

svn commit: r578743 [6/12] - in /directory/apacheds/branches/apacheds-kerberos: kerberos-shared/ kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/ kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto...

Added: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KerberosRequestBody.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KerberosRequestBody.java?rev=578743&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KerberosRequestBody.java (added)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KerberosRequestBody.java Mon Sep 24 03:18:05 2007
@@ -0,0 +1,859 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.kerberos.shared.messages.value;
+
+
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.kerberos.KerberosPrincipal;
+
+import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
+import org.apache.directory.server.kerberos.shared.messages.components.Ticket;
+import org.apache.directory.server.kerberos.shared.messages.value.flags.KdcOptions;
+import org.apache.directory.shared.asn1.AbstractAsn1Object;
+import org.apache.directory.shared.asn1.ber.tlv.TLV;
+import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
+import org.apache.directory.shared.asn1.ber.tlv.Value;
+import org.apache.directory.shared.asn1.codec.EncoderException;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * The Request Body is used into KDC-REQ, which is either an AS-REQ or a TGS-REQ.
+ * 
+ * The ASN.1 grammar is the following :
+ * 
+ * KDC-REQ-BODY    ::= SEQUENCE {
+ *        kdc-options             [0] KDCOptions,
+ *        cname                   [1] PrincipalName OPTIONAL
+ *                                    -- Used only in AS-REQ --,
+ *        realm                   [2] Realm
+ *                                    -- Server's realm
+ *                                    -- Also client's in AS-REQ --,
+ *        sname                   [3] PrincipalName OPTIONAL,
+ *        from                    [4] KerberosTime OPTIONAL,
+ *        till                    [5] KerberosTime,
+ *        rtime                   [6] KerberosTime OPTIONAL,
+ *        nonce                   [7] UInt32,
+ *        etype                   [8] SEQUENCE OF Int32 -- EncryptionType
+ *                                    -- in preference order --,
+ *        addresses               [9] HostAddresses OPTIONAL,
+ *        enc-authorization-data  [10] EncryptedData OPTIONAL
+ *                                    -- AuthorizationData --,
+ *        additional-tickets      [11] SEQUENCE OF Ticket OPTIONAL
+ *                                        -- NOTE: not empty
+ * }
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 540371 $, $Date: 2007-05-22 02:00:43 +0200 (Tue, 22 May 2007) $
+ */
+public class KerberosRequestBody extends AbstractAsn1Object
+{
+    /** The logger */
+    private static final Logger log = LoggerFactory.getLogger( KerberosRequestBody.class );
+
+    /** Speedup for logs */
+    private static final boolean IS_DEBUG = log.isDebugEnabled();
+    
+    /** The options */
+    private KdcOptions kdcOptions;
+    
+    /** The client principalName */
+    private PrincipalName cName; //optional in TgsReq only
+    
+    /** The client KerberosPrincipal */
+    private KerberosPrincipal clientPrincipal;
+    
+    /** The server realm */ 
+    private String realm;
+    
+    /** A byte array to store the server realm */
+    private transient byte[] realmBytes;
+    
+    /** The server principal Name */
+    private PrincipalName sName; // optional
+    
+    /** The server kerberosPrincipal */
+    private KerberosPrincipal serverPrincipal;
+    
+    /** the desired starttime for the requested ticket */
+    private KerberosTime from; //optional
+    
+    /** the expiration date requested by the client */
+    private KerberosTime till;
+    
+    /** the requested renew-till time sent from a client to a KDC */
+    private KerberosTime rTime; //optional
+    
+    /** random number generated by the client */
+    private int nonce;
+    
+    /** the desired encryption algorithm to be used in the response */
+    private List<EncryptionType> eType;
+    
+    /** the addresses from which the requested ticket is to be valid */
+    private HostAddresses addresses; //optional
+    
+    /** encoding of the desired authorization-data encrypted */
+    private EncryptedData encAuthorizationData; //optional
+    
+    /** Additional tickets */
+    private List<Ticket> additionalTickets; //optional
+
+    // Storage for computed lengths
+    private transient int kdcOptionsTagLength;
+    private transient int kdcOptionsLength;
+    
+    private transient int cNameTagLength;
+    
+    private transient int realmTagLength;
+    
+    private transient int sNameTagLength;
+    
+    private transient int fromTagLength;
+    private transient int fromLength;
+
+    private transient int tillTagLength;
+    private transient int tillLength;
+
+    private transient int rTimeTagLength;
+    private transient int rTimeLength;
+
+    private transient int nonceTagLength;
+    
+    private transient int eTypeTagLength;
+    private transient int eTypeSeqLength;
+    
+    private transient int addressesTagLength;
+
+    private transient int encAuthorizationDataTagLength;
+    
+    private transient int additionalTicketsTagLength;
+    private transient int additionalTicketsSeqLength;
+
+    private transient int requestBodySeqLength;
+
+    
+    /**
+     * Creates a new instance of KerberosRequestBody.
+     **/
+    public KerberosRequestBody()
+    {
+        cName = null; // Optional
+        sName = null; // Optional
+        from = null; // Optional
+        rTime = null; // Optional
+        addresses = null; // Optional
+        encAuthorizationData = null; // Optional
+        additionalTickets = null; // Optional
+        eType = new ArrayList<EncryptionType>();
+    }
+    
+    /**
+     * Returns the additional {@link Ticket}s.
+     *
+     * @return The additional {@link Ticket}s.
+     */
+    public List<Ticket> getAdditionalTickets()
+    {
+        return additionalTickets;
+    }
+
+    /**
+     * Set the additional Tickets list
+     * @param additionalTickets The ticket list
+     */
+    public void setAdditionalTickets( List<Ticket> additionalTickets )
+    {
+        this.additionalTickets = additionalTickets;
+    }
+
+    /**
+     * Set the additional Tickets list
+     * @param additionalTickets The ticket list
+     */
+    public void addAdditionalTicket( Ticket additionalTicket )
+    {
+        if ( additionalTickets == null )
+        {
+            additionalTickets = new ArrayList<Ticket>();
+        }
+        
+        additionalTickets.add( additionalTicket );
+    }
+
+
+    /**
+     * Returns the {@link HostAddresses}.
+     *
+     * @return The {@link HostAddresses}.
+     */
+    public HostAddresses getAddresses()
+    {
+        return addresses;
+    }
+
+    /**
+     * Set the host addresses
+     * 
+     * @param addresses The host addresses structure
+     */
+    public void setAddresses( HostAddresses addresses )
+    {
+        this.addresses = addresses;
+    }
+
+
+    /**
+     * Returns the client {@link KerberosPrincipal}.
+     *
+     * @return The client {@link KerberosPrincipal}.
+     */
+    public KerberosPrincipal getClientPrincipal()
+    {
+        return clientPrincipal;
+    }
+    
+    
+    /**
+     * Set the client KerberosPrincipal 
+     * @param clientPrincipal the client KerberosPrincipal
+     */
+    public void setClientPrincipal( KerberosPrincipal clientPrincipal )
+    {
+        this.clientPrincipal = clientPrincipal;
+        
+        try
+        {
+            cName = new PrincipalName( clientPrincipal.getName(), clientPrincipal.getNameType() );
+        }
+        catch ( ParseException pe )
+        {
+            log.error( "The KerberosPrincipal is invalid : {}", clientPrincipal );
+            cName = null;
+        }
+    }
+
+
+    /**
+     * Returns the server {@link PrincipalName}.
+     *
+     * @return The server {@link PrincipalName}.
+     */
+    public PrincipalName getServerPrincipalName()
+    {
+        return sName;
+    }
+
+
+    /**
+     * Returns the server {@link KerberosPrincipal}.
+     *
+     * @return The server {@link KerberosPrincipal}.
+     */
+    public KerberosPrincipal getServerPrincipal()
+    {
+        return serverPrincipal;
+    }
+
+
+    /**
+     * Returns the encrypted {@link AuthorizationData} as {@link EncryptedData}.
+     *
+     * @return The encrypted {@link AuthorizationData} as {@link EncryptedData}.
+     */
+    public EncryptedData getEncAuthorizationData()
+    {
+        return encAuthorizationData;
+    }
+
+    /**
+     * Set the encrypted {@link AuthorizationData} as {@link EncryptedData}.
+     * @param encAuthorizationData the encrypted {@link AuthorizationData} as {@link EncryptedData}.
+     */
+    public void setEncAuthorizationData( EncryptedData encAuthorizationData )
+    {
+        this.encAuthorizationData = encAuthorizationData;
+    }
+
+
+    /**
+     * Returns the requested {@link EncryptionType}s.
+     *
+     * @return The requested {@link EncryptionType}s.
+     */
+    public List<EncryptionType> getEType()
+    {
+        return eType;
+    }
+
+
+    /**
+     * Returns the from {@link KerberosTime}.
+     *
+     * @return The from {@link KerberosTime}.
+     */
+    public KerberosTime getFrom()
+    {
+        return from;
+    }
+
+    /**
+     * Set the from date
+     * @param from The from date
+     */
+    public void setFrom( KerberosTime from )
+    {
+        this.from = from;
+    }
+
+
+    /**
+     * Returns the {@link KdcOptions}.
+     *
+     * @return The {@link KdcOptions}.
+     */
+    public KdcOptions getKdcOptions()
+    {
+        return kdcOptions;
+    }
+
+    /** 
+     * Set the KdcOptions
+     * @param kdcOptions The KdcOptions
+     */
+    public void setKdcOptions( KdcOptions kdcOptions )
+    {
+        this.kdcOptions = kdcOptions;
+    }
+    
+
+    /**
+     * Returns the nonce.
+     *
+     * @return The nonce.
+     */
+    public int getNonce()
+    {
+        return nonce;
+    }
+
+    /**
+     * Set the nonce
+     * @param nonce The nonce
+     */
+    public void setNonce( int nonce )
+    {
+        this.nonce = nonce;
+    }
+
+    /**
+     * Returns the renew-time {@link KerberosTime}.
+     *
+     * @return The renew-time {@link KerberosTime}.
+     */
+    public KerberosTime getRenewtime()
+    {
+        return rTime;
+    }
+
+    /**
+     * Set the renew-till time sent from a client to
+     * the KDC
+     * @param rtime the renew-till time sent from a client to
+     *  the KDC
+     */
+    public void setRenewtime( KerberosTime rtime )
+    {
+        this.rTime = rtime;
+    }
+
+    /**
+     * Returns the till {@link KerberosTime}.
+     *
+     * @return The till {@link KerberosTime}.
+     */
+    public KerberosTime getTill()
+    {
+        return till;
+    }
+
+    /**
+     * Set the expiration date requested by the client
+     * @param till Expiration date requested by the client
+     */
+    public void setTill( KerberosTime till )
+    {
+        this.till = till;
+    }
+
+    /**
+     * @return The client principalName
+     */
+    public PrincipalName getClientPrincipalName()
+    {
+        return cName;
+    }
+
+    /**
+     * Set the server PrincipalName
+     * @param name the server PrincipalName
+     */
+    public void setServerPrincipalName( PrincipalName sName )
+    {
+        this.sName = sName;
+        serverPrincipal = new KerberosPrincipal( sName.getNameComponent(), sName.getNameType().getOrdinal() );
+    }
+
+    /**
+     * Set the server {@link KerberosPrincipal}
+     * @param name the server {@link KerberosPrincipal}
+     */
+    public void setServerPrincipal( KerberosPrincipal serverPrincipal )
+    {
+        this.serverPrincipal = serverPrincipal;
+
+        try
+        {
+            sName = new PrincipalName( serverPrincipal.getName(), serverPrincipal.getNameType() );
+        }
+        catch ( ParseException pe )
+        {
+            log.error( "The KerberosPrincipal is invalid : {}", serverPrincipal );
+            sName = null;
+        }
+    }
+
+    /**
+     * @return The server realm
+     */
+    public String getRealm()
+    {
+        return realm;
+    }
+
+    /**
+     * Set the server realm
+     * @param realm The server realm
+     */
+    public void setRealm( String realm )
+    {
+        this.realm = realm;
+    }
+
+    /**
+     * Set the list of Encryption types
+     * @param type the list of Encryption types
+     */
+    public void setEncryptionType( List<EncryptionType> eType )
+    {
+        this.eType = eType;
+    }
+    
+    /**
+     * Add a new Encryption type to the eType list
+     * @param eType The EncryptionType to add
+     */
+    public void addEncryptionType( EncryptionType eType )
+    {
+        this.eType.add( eType );
+    }
+
+    /**
+     * Compute the KDC-REQ-BODY length
+     * 
+     * KerberosRequestBody :
+     * 
+     * 0x30 L1 KerberosRequestBody sequence
+     *  |
+     *  +--> 0xA0 L2 kdc-options tag
+     *  |     |
+     *  |     +--> 0x02 L2-1 kdc-options (BIT STRING)
+     *  |
+     *  +--> [0xA1 L3 cname tag
+     *  |     |
+     *  |     +--> 0x30 L3-1 cname (PrincipalName)] (optional)
+     *  |
+     *  +--> 0xA2 L4 realm tag
+     *  |     |
+     *  |     +--> 0x04 L4-1 realm (String)
+     *  |
+     *  +--> [0xA3 L5 sname tag
+     *  |     |
+     *  |     +--> 0x02 L5-1 sname (PrincipalName)] (optional)
+     *  |
+     *  +--> [0xA4 L6 from tag
+     *  |     |
+     *  |     +--> 0x02 L6-1 from (KerberosTime)] (optional)
+     *  |
+     *  +--> 0xA5 L7 till tag
+     *  |     |
+     *  |     +--> 0x02 L7-1 till (KerberosTime)
+     *  |
+     *  +--> [0xA6 L8 rtime tag
+     *  |     |
+     *  |     +--> 0x02 L8-1 kdc-options (KerberosTime)] (optional)
+     *  |
+     *  +--> 0xA7 L9 nonce tag
+     *  |     |
+     *  |     +--> 0x02 L9-1 nonce (int)
+     *  |
+     *  +--> 0xA8 L10 kdc-options tag
+     *  |     |
+     *  |     +--> 0x30 L10-1
+     *  |           |
+     *  |           +--> 0x02 L10-2 etype (int)
+     *  |           |
+     *  |           +--> ...
+     *  |           |
+     *  |           +--> 0x02 L10-N etype (int)
+     *  |
+     *  +--> [0xA9 L11 hostAdresses tag
+     *  |     |
+     *  |     +--> 0x30 L11-1 hostAdresses (HostAddresses)] (optional)
+     *  |
+     *  +--> [0xAA L12 enc-authorization-data tag
+     *  |     |
+     *  |     +--> 0x30 L12-1 enc-authorization-data (EncryptedData)] (optional)
+     *  |
+     *  +--> [0xAB L13 additional-tickets tag
+     *        |
+     *        +--> 0x30 L13-1 additional-tickets (Ticket)
+     *              |
+     *              +--> 0x61 L13-2 Ticket
+     *              |
+     *              +--> ...
+     *              |
+     *              +--> 0x61 L13-N Ticket](optional)
+     */
+    public int computeLength()
+    {
+        requestBodySeqLength = 0;
+
+        // Compute the kdc-options length
+        kdcOptionsLength = 1 + kdcOptions.getData().length;
+        kdcOptionsTagLength = 1 + TLV.getNbBytes( kdcOptionsLength ) + kdcOptionsLength;
+        requestBodySeqLength = 1 + TLV.getNbBytes( kdcOptionsTagLength ) + kdcOptionsTagLength; 
+
+        // Compute the clientPrincipalName if any
+        if ( cName != null )
+        {
+            cNameTagLength = cName.computeLength();
+            requestBodySeqLength += 1 + TLV.getNbBytes( cNameTagLength ) + cNameTagLength;
+        }
+        
+        // Compute the server Realm
+        realmBytes = StringTools.getBytesUtf8( realm );
+        realmTagLength = 1 + TLV.getNbBytes( realmBytes.length ) + realmBytes.length;
+        requestBodySeqLength += 1 + TLV.getNbBytes( realmTagLength ) + realmTagLength;
+        
+        // Compute the serverPrincipalName if any
+        if ( sName != null )
+        {
+            sNameTagLength = sName.computeLength();
+            requestBodySeqLength += 1 + TLV.getNbBytes( sNameTagLength ) + sNameTagLength;
+        }
+        
+        // Compute the from KerberosTime length, if any
+        if ( from != null )
+        {
+            fromLength = 15; 
+            fromTagLength = 1 + 1 + fromLength; 
+            
+            requestBodySeqLength += 
+                1 + TLV.getNbBytes( fromTagLength ) + fromTagLength;
+        }
+
+        // Compute the till KerberosTime length
+        tillLength = 15; 
+        tillTagLength = 1 + 1 + tillLength; 
+        
+        requestBodySeqLength += 
+            1 + TLV.getNbBytes( tillTagLength ) + tillTagLength;
+
+        // Compute the renew KerberosTime length, if any
+        if ( rTime != null )
+        {
+            rTimeLength = 15; 
+            rTimeTagLength = 1 + 1 + rTimeLength; 
+            
+            requestBodySeqLength += 
+                1 + TLV.getNbBytes( rTimeTagLength ) + rTimeTagLength;
+        }
+
+        // Compute the nonce length
+        int nonceLength = Value.getNbBytes( nonce );
+        nonceTagLength = 1 + TLV.getNbBytes( nonceLength ) + nonceLength;
+        requestBodySeqLength += 1 + TLV.getNbBytes( nonceTagLength ) + nonceTagLength;
+        
+        // Compute the EncryptionType length
+        if ( ( eType == null ) || ( eType.size() == 0 ) )
+        {
+            return -1;
+        }
+        
+        for ( EncryptionType type:eType )
+        {
+            int eTypeLength = Value.getNbBytes( type.getOrdinal() );
+            eTypeSeqLength += 1 + TLV.getNbBytes( eTypeLength ) + eTypeLength;
+        }
+        
+        eTypeTagLength = 1 +TLV.getNbBytes( eTypeSeqLength ) + eTypeSeqLength;
+        requestBodySeqLength += 1 + TLV.getNbBytes( eTypeTagLength ) + eTypeTagLength;
+        
+        // Compute the addresses length, if any
+        if ( addresses != null )
+        {
+            addressesTagLength = addresses.computeLength();
+            requestBodySeqLength += 1 + TLV.getNbBytes( addressesTagLength ) + addressesTagLength;
+        }
+        
+        // Compute the encAuthorizationData length
+        if ( encAuthorizationData != null )
+        {
+            encAuthorizationDataTagLength = encAuthorizationData.computeLength();
+            requestBodySeqLength += 1 + TLV.getNbBytes( encAuthorizationDataTagLength ) + encAuthorizationDataTagLength;
+        }
+        
+        if ( additionalTickets != null )
+        {
+            additionalTicketsSeqLength = 0;
+            
+            for ( Ticket ticket:additionalTickets )
+            {
+                additionalTicketsSeqLength += ticket.computeLength();
+            }
+            
+            additionalTicketsTagLength = 1 + TLV.getNbBytes( additionalTicketsSeqLength ) + additionalTicketsSeqLength;
+            requestBodySeqLength += 1 + TLV.getNbBytes( additionalTicketsTagLength ) + additionalTicketsTagLength;
+            
+        }
+        
+        // Compute the whole sequence length
+        return 1 + TLV.getNbBytes( requestBodySeqLength ) + requestBodySeqLength;
+    }
+    
+    /**
+     * Encode the KRB-REQ-BODY message to a PDU. 
+     * 
+     * KRB-REQ-BODY :
+     * 
+     * 0x30 LL
+     *   0xA0 LL 
+     *     0x03 LL kdc-options (BIT STRING)
+     *   [0xA1 LL
+     *     0x30 LL cname (PrincipalName) (optional)]
+     *   0xA2 LL
+     *     0x1B LL realm (KerberosString)
+     *   [0xA3 LL
+     *     0x30 LL sname (PrincipalName) (optional)]
+     *   [0xA4 LL
+     *     0x18 0x0F from (KerberosTime) (optional)]
+     *   0xA5 LL
+     *     0x18 0x0F till (KerberosTime)
+     *   [0xA6 LL
+     *     0x18 0x0F renew (KerberosTime) (optional)]
+     *   0xA7 LL
+     *     0x02 LL nounce (int)
+     *   0xA8 LL
+     *     0x30 LL
+     *       0x02 LL etype
+     *       ...
+     *       0x02 LL etype
+     *   [0xA9 LL
+     *     0x30 LL addresses (HostAddresses) (optional)]
+     *   [0xAA LL
+     *     0x30 LL enc-authorization-data (EncryptedData) (optional)]
+     *   [0xAB LL
+     *     0x30 LL additional-tickets
+     *       0x61 LL Ticket
+     *       ...
+     *       0x61 LL Ticket (optional)]
+     * 
+     * @param buffer The buffer where to put the PDU. It should have been allocated
+     * before, with the right size.
+     * @return The constructed PDU.
+     */
+    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
+    {
+        if ( buffer == null )
+        {
+            throw new EncoderException( "Cannot put a PDU in a null buffer !" );
+        }
+
+        try
+        {
+            // The RequestBody SEQ Tag
+            buffer.put( UniversalTag.SEQUENCE_TAG );
+            buffer.put( TLV.getBytes( requestBodySeqLength ) );
+
+            // The kdc-options, first the tag, then the value
+            buffer.put( ( byte ) 0xA0 );
+            buffer.put( TLV.getBytes( kdcOptionsTagLength ) );
+
+            Value.encode( buffer, kdcOptions );
+            
+            // The clientprincipalName, if any
+            if ( cName != null )
+            {
+                buffer.put( (byte)0xA1 );
+                buffer.put( TLV.getBytes( cNameTagLength ) );
+                cName.encode( buffer );
+            }
+            
+            // The server realm
+            buffer.put( (byte)0xA2 );
+            buffer.put( TLV.getBytes( realmTagLength ) );
+            
+            buffer.put( UniversalTag.GENERALIZED_STRING_TAG );
+            buffer.put( TLV.getBytes( realmBytes.length ) );
+            buffer.put( realmBytes );
+
+            // The serverprincipalName, if any
+            if ( sName != null )
+            {
+                buffer.put( (byte)0xA3 );
+                buffer.put( TLV.getBytes( sNameTagLength ) );
+                sName.encode( buffer );
+            }
+            
+            // The from KerberosTime Tag and value, if any
+            if ( from != null )
+            {
+                buffer.put( (byte)0xA4 );
+                buffer.put( TLV.getBytes( fromTagLength ) );
+                buffer.put( UniversalTag.GENERALIZED_TIME_TAG );
+                buffer.put( TLV.getBytes( fromLength ) );
+                buffer.put( StringTools.getBytesUtf8( from.toString() ) );
+            }
+            
+            // The till KerberosTime Tag and value, if any
+            buffer.put( (byte)0xA5 );
+            buffer.put( TLV.getBytes( tillTagLength ) );
+            buffer.put( UniversalTag.GENERALIZED_TIME_TAG );
+            buffer.put( TLV.getBytes( tillLength ) );
+            buffer.put( StringTools.getBytesUtf8( till.toString() ) );
+            
+            // The from KerberosTime Tag and value, if any
+            if ( rTime != null )
+            {
+                buffer.put( (byte)0xA6 );
+                buffer.put( TLV.getBytes( rTimeTagLength ) );
+                buffer.put( UniversalTag.GENERALIZED_TIME_TAG );
+                buffer.put( TLV.getBytes( rTimeLength ) );
+                buffer.put( StringTools.getBytesUtf8( rTime.toString() ) );
+            }
+            
+            // The nonce, first the tag, then the value
+            buffer.put( ( byte ) 0xA7 );
+            buffer.put( TLV.getBytes( nonceTagLength ) );
+            Value.encode( buffer, nonce );
+            
+            // The EncryptionTypes
+            if ( ( eType == null ) || ( eType.size() == 0 ) )
+            {
+                log.error( "We should have at least one encryption type" );
+                throw new EncoderException( "No encryptionType available" );
+            }
+            
+            // Fisrt, the tag
+            buffer.put( (byte)0xA8 );
+            buffer.put( TLV.getBytes( eTypeTagLength ) );
+            
+            // Then the sequence
+            buffer.put( (byte)0x30 );
+            buffer.put( TLV.getBytes( eTypeSeqLength ) );
+
+            // Now, the eTypes
+            for ( EncryptionType type:eType )
+            {
+                Value.encode( buffer, type.getOrdinal() );
+            }
+            
+            // The addresses
+            if ( addresses != null )
+            {
+                buffer.put( (byte)0xA9 );
+                buffer.put( TLV.getBytes( addressesTagLength ) );
+                addresses.encode( buffer );
+            }
+            
+            // The enc-authorization-data
+            if ( encAuthorizationData != null )
+            {
+                buffer.put( (byte)0xAA );
+                buffer.put( TLV.getBytes( encAuthorizationDataTagLength ) );
+                encAuthorizationData.encode( buffer );
+            }
+            
+            // The additional tickets
+            if ( additionalTickets != null )
+            {
+                buffer.put( (byte)0xAB );
+                buffer.put( TLV.getBytes( additionalTicketsTagLength ) );
+                
+                buffer.put( UniversalTag.SEQUENCE_TAG );
+                buffer.put( TLV.getBytes( additionalTicketsSeqLength ) );
+                
+                for ( Ticket ticket:additionalTickets )
+                {
+                    ticket.encode( buffer );
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            log.error(
+                "Cannot encode the KerberosRequestBody object, the PDU size is {} when only {} bytes has been allocated", 1
+                    + TLV.getNbBytes( requestBodySeqLength ) + requestBodySeqLength, buffer.capacity() );
+            throw new EncoderException( "The PDU buffer size is too small !" );
+        }
+
+        if ( IS_DEBUG )
+        {
+            log.debug( "KerberosRequestBody encoding : {}", StringTools.dumpBytes( buffer.array() ) );
+            log.debug( "KerberosRequestBody initial value : {}", toString() );
+        }
+
+        return buffer;
+    }
+    
+    /**
+     * @see Object#toString()
+     */
+    public String toString( String tabs )
+    {
+        return tabs + "NYI";
+    }
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        return toString( "" );
+    }
+}

Modified: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KerberosTime.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KerberosTime.java?rev=578743&r1=578742&r2=578743&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KerberosTime.java (original)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KerberosTime.java Mon Sep 24 03:18:05 2007
@@ -22,9 +22,13 @@
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.util.Calendar;
 import java.util.Date;
+import java.util.GregorianCalendar;
 import java.util.TimeZone;
 
+import org.apache.directory.shared.ldap.util.StringTools;
+
 
 /**
  * Implementation of the time object for Kerberos.
@@ -48,6 +52,7 @@
 
     private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
     private static final SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyyMMddHHmmss'Z'" );
+    private static final Calendar CALENDAR = new GregorianCalendar( UTC_TIME_ZONE );
 
     static
     {
@@ -95,13 +100,133 @@
      * @return The {@link KerberosTime}.
      * @throws ParseException
      */
-    public static KerberosTime getTime( String zuluTime ) throws ParseException
+    /*public static KerberosTime getTime( String zuluTime ) throws ParseException
     {
         Date date = null;
         synchronized ( dateFormat )
         {
             date = dateFormat.parse( zuluTime );
         }
+        return new KerberosTime( date );
+    }*/
+    
+    private static int[] DAYS_PER_MONTH = new int[]{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+    private static int FEBRUARY = 2;
+    
+    /**
+     * Parse a KerberosTime
+     * @param zuluTime The time to parse
+     * @return A valid KzerberosTime, containing the Date
+     * @exception ParseException If the time is not a KerberosTime
+     */
+    public static KerberosTime getTime( String zuluTime ) throws ParseException
+    {
+        Date date = null;
+        
+        if ( ( zuluTime == null ) || ( zuluTime.length() != 15 ) )
+        {
+            throw new ParseException( "Invalid KerberosTime : it should not be null", 0 );
+        }
+        
+        char[] zTime = zuluTime.toCharArray();
+
+        for ( int i = 0; i < zTime.length; i++ )
+        {
+            if ( !StringTools.isDigit( zTime[i] ) )
+            {
+                if ( ( i == 14 ) && ( ( zTime[i] == 'Z' ) || ( zTime[i] == 'z' ) ) )
+                {
+                    break;
+                }
+                else
+                {
+                    throw new ParseException( "Invalid KerberosTime", i );
+                }
+            }
+        }
+        
+        // compute the numbers
+        int year =  ( ( zTime[0] - '0' ) * 1000 ) +
+                    ( ( zTime[1] - '0' ) * 100 ) +
+                    ( ( zTime[2] - '0' ) * 10 ) +
+                    ( zTime[3] - '0' );
+        
+        int month = ( ( zTime[4] - '0' ) * 10 ) +
+                    ( zTime[5] - '0' );
+
+        int day =   ( ( zTime[6] - '0' ) * 10 ) +
+                    ( zTime[7] - '0' );
+
+        int hour =  ( ( zTime[8] - '0' ) * 10 ) +
+                    ( zTime[9] - '0' );
+
+        int min =   ( ( zTime[10] - '0' ) * 10 ) +
+                    ( zTime[11] - '0' );
+
+        int sec =   ( ( zTime[12] - '0' ) * 10 ) +
+                    ( zTime[13] - '0' );
+        
+        // Now test the values
+        if ( ( month == 0 ) || ( month > 12 ) ) 
+        {
+            throw new ParseException( "Invalid KerberosTime : month is invalid", 5 );
+        }
+
+        if ( day == 0 )
+        {
+            throw new ParseException( "Invalid KerberosTime : day is invalid", 7 );
+        }
+        
+        if ( month == FEBRUARY )
+        {
+            // Check for leap years
+            if ( ( year & 0x0003 ) == 0 )
+            {
+                // evey 400 years, we have a leap year, otherwise it's not
+                if ( year % 400 == 0 )
+                {
+                    if ( day > 29 )
+                    {
+                        throw new ParseException( "Invalid KerberosTime : day is invalid", 7 );
+                    }
+                }
+                else
+                {
+                    if ( day > 28 )
+                    {
+                        throw new ParseException( "Invalid KerberosTime : day is invalid for february", 7 );
+                    }
+                }
+            }
+            else
+            {
+                if ( day > 28 )
+                {
+                    // We don't have a leap year, so we should have only 28 days
+                    throw new ParseException( "Invalid KerberosTime : day is invalid for a non leap year", 7 );
+                }
+            }
+        }
+        else
+        {
+            if ( day > DAYS_PER_MONTH[month] )
+            {
+                throw new ParseException( "Invalid KerberosTime : day is invalid for this month", 7 );
+            }
+        }
+        
+        if ( ( hour > 23 ) || ( min > 59 ) || ( sec > 59 ) ) 
+        {
+            throw new ParseException( "Invalid KerberosTime : time is invalid", 9 );
+       }
+        
+        synchronized( CALENDAR )
+        {
+            CALENDAR.clear();
+            CALENDAR.set( year, month - 1, day, hour, min, sec );
+            date = CALENDAR.getTime();
+        }
+        
         return new KerberosTime( date );
     }
 

Modified: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KrbCredInfo.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KrbCredInfo.java?rev=578743&r1=578742&r2=578743&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KrbCredInfo.java (original)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/KrbCredInfo.java Mon Sep 24 03:18:05 2007
@@ -22,6 +22,8 @@
 
 import javax.security.auth.kerberos.KerberosPrincipal;
 
+import org.apache.directory.server.kerberos.shared.messages.value.flags.TicketFlags;
+
 
 /**
  * Kerberos credential information.

Modified: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/LastRequest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/LastRequest.java?rev=578743&r1=578742&r2=578743&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/LastRequest.java (original)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/LastRequest.java Mon Sep 24 03:18:05 2007
@@ -20,6 +20,9 @@
 package org.apache.directory.server.kerberos.shared.messages.value;
 
 
+import org.apache.directory.server.kerberos.shared.messages.value.types.LastRequestType;
+
+
 /**
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$

Modified: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/LastRequestEntry.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/LastRequestEntry.java?rev=578743&r1=578742&r2=578743&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/LastRequestEntry.java (original)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/LastRequestEntry.java Mon Sep 24 03:18:05 2007
@@ -20,6 +20,9 @@
 package org.apache.directory.server.kerberos.shared.messages.value;
 
 
+import org.apache.directory.server.kerberos.shared.messages.value.types.LastRequestType;
+
+
 /**
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$

Added: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PreAuthEncryptedTimestamp.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PreAuthEncryptedTimestamp.java?rev=578743&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PreAuthEncryptedTimestamp.java (added)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PreAuthEncryptedTimestamp.java Mon Sep 24 03:18:05 2007
@@ -0,0 +1,234 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.kerberos.shared.messages.value;
+
+
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+
+import org.apache.directory.server.kerberos.shared.KerberosUtils;
+import org.apache.directory.server.kerberos.shared.messages.Encodable;
+import org.apache.directory.shared.asn1.AbstractAsn1Object;
+import org.apache.directory.shared.asn1.ber.tlv.TLV;
+import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
+import org.apache.directory.shared.asn1.ber.tlv.Value;
+import org.apache.directory.shared.asn1.codec.EncoderException;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Pre-authentication encrypted timestamp.
+ * 
+ * The ASN.1 grammar is the following :
+ * 
+ * PA-ENC-TIMESTAMP        ::= EncryptedData -- PA-ENC-TS-ENC
+ * 
+ * PA-ENC-TS-ENC           ::= SEQUENCE {
+ *        patimestamp     [0] KerberosTime -- client's time --,
+ *        pausec          [1] Microseconds OPTIONAL
+ * }
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 540371 $, $Date: 2007-05-22 02:00:43 +0200 (Tue, 22 May 2007) $
+ */
+public class PreAuthEncryptedTimestamp extends AbstractAsn1Object implements Encodable
+{
+    /** The logger */
+    private static final Logger log = LoggerFactory.getLogger( PreAuthEncryptedTimestamp.class );
+
+    /** Speedup for logs */
+    private static final boolean IS_DEBUG = log.isDebugEnabled();
+
+    /** client's time */
+    private KerberosTime paTimestamp;
+    
+    /** Client's microseconds */
+    private int pausec; //optional
+
+    // Storage for computed lengths
+    private transient int preAuthEncryptedTimestampSeqLength;
+    
+    private transient int paTimestampTagLength;
+    private transient int paTimestampLength;
+    
+    private transient int pausecTagLength;
+
+    
+    /**
+     * Creates a new instance of EncryptedTimeStamp.
+     *
+     * @param timeStamp
+     * @param microSeconds
+     */
+    public PreAuthEncryptedTimestamp( KerberosTime paTimestamp, int pausec )
+    {
+        this.paTimestamp = paTimestamp;
+        this.pausec = pausec;
+    }
+
+
+    /**
+     * Returns the {@link KerberosTime}.
+     *
+     * @return The {@link KerberosTime}.
+     */
+    public KerberosTime getTimeStamp()
+    {
+        return paTimestamp;
+    }
+
+    /**
+     * Set the client timestamp
+     * @param paTimestamp The client timestamp
+     */
+    public void setTimestamp( KerberosTime paTimestamp )
+    {
+        this.paTimestamp = paTimestamp;
+    }
+
+
+    /**
+     * Returns the microseconds.
+     *
+     * @return The microseconds.
+     */
+    public int getMicroSeconds()
+    {
+        return pausec;
+    }
+
+
+    /**
+     * Set the client microseconds
+     * @param pausec The client microseconds
+     */
+    public void setPausec( int pausec )
+    {
+        this.pausec = pausec;
+    }
+    
+    /**
+     * Compute the PA-ENC-TS-ENC length
+     * 
+     * PA-ENC-TS-ENC :
+     * 
+     * 0x30 L1 PA-ENC-TS-ENC Seq
+     *  |
+     *  +--> 0xA0 L2 apatimestamp tag
+     *  |     |
+     *  |     +--> 0x18 L2-1 patimestamp (KerberosTime)
+     *  |
+     *  +--> [0xA1 L3 pausec tag
+     *        |
+     *        +--> 0x1B L3-1 pausec (optional)]
+     */
+    public int computeLength()
+    {
+        preAuthEncryptedTimestampSeqLength = 0;
+
+        // Compute the patimestamp length
+        paTimestampLength = 15; 
+        paTimestampTagLength = 1 + 1 + paTimestampLength;
+        
+        preAuthEncryptedTimestampSeqLength = 1 + TLV.getNbBytes( paTimestampTagLength ) + paTimestampTagLength;
+
+        // Compute the pausec length, if any
+        if ( pausec != KerberosUtils.NULL )
+        {
+            int pausecLength = Value.getNbBytes( pausec );
+            pausecTagLength = 1 + TLV.getNbBytes( pausecLength ) + pausecLength;
+            preAuthEncryptedTimestampSeqLength += 1 + TLV.getNbBytes( pausecTagLength ) + pausecTagLength;
+        }
+
+        // Compute the whole sequence length
+        return 1 + TLV.getNbBytes( preAuthEncryptedTimestampSeqLength ) + preAuthEncryptedTimestampSeqLength;
+    }
+    
+    /**
+     * Encode the PA-ENC-TS-ENC message to a PDU. 
+     * 
+     * PA-ENC-TS-ENC :
+     * 
+     * 0x30 LL
+     *   0xA0 0x11 
+     *     0x18 0x0F (KerberosTime)
+     *   [0xA1 LL
+     *     0x02 LL pausec (int)] (optional)
+     * 
+     * @param buffer The buffer where to put the PDU. It should have been allocated
+     * before, with the right size.
+     * @return The constructed PDU.
+     */
+    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
+    {
+        if ( buffer == null )
+        {
+            throw new EncoderException( "Cannot put a PDU in a null buffer !" );
+        }
+
+        try
+        {
+            // The PA-ENC-TS-ENC SEQ Tag
+            buffer.put( UniversalTag.SEQUENCE_TAG );
+            buffer.put( TLV.getBytes( preAuthEncryptedTimestampSeqLength ) );
+
+            // The patimestamp encoding, first the tag, then the value
+            buffer.put( ( byte ) 0xA0 );
+            buffer.put( TLV.getBytes( paTimestampTagLength ) );
+            buffer.put( UniversalTag.GENERALIZED_TIME_TAG );
+            buffer.put( TLV.getBytes( paTimestampLength ) );
+            buffer.put( StringTools.getBytesUtf8( paTimestamp.toString() ) );
+            
+            // Client millisecond encoding, if any
+            if ( pausec != KerberosUtils.NULL )
+            {
+                buffer.put( ( byte )0xA1 );
+                buffer.put( TLV.getBytes( pausecTagLength ) );
+                Value.encode( buffer, pausec );
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            log.error(
+                "Cannot encode the PA-ENC-TS-ENC object, the PDU size is {} when only {} bytes has been allocated", 1
+                    + TLV.getNbBytes( preAuthEncryptedTimestampSeqLength ) + preAuthEncryptedTimestampSeqLength, buffer.capacity() );
+            throw new EncoderException( "The PDU buffer size is too small !" );
+        }
+
+        if ( IS_DEBUG )
+        {
+            log.debug( "PA-ENC-TS-ENC encoding : {}", StringTools.dumpBytes( buffer.array() ) );
+            log.debug( "PA-ENC-TS-ENC initial value : {}", toString() );
+        }
+
+        return buffer;
+    }
+    
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        return "NYI";
+    }
+    
+}

Modified: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PreAuthenticationData.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PreAuthenticationData.java?rev=578743&r1=578742&r2=578743&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PreAuthenticationData.java (original)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PreAuthenticationData.java Mon Sep 24 03:18:05 2007
@@ -20,26 +20,62 @@
 package org.apache.directory.server.kerberos.shared.messages.value;
 
 
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+
+import org.apache.directory.server.kerberos.shared.messages.value.types.PreAuthenticationDataType;
+import org.apache.directory.shared.asn1.AbstractAsn1Object;
+import org.apache.directory.shared.asn1.ber.tlv.TLV;
+import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
+import org.apache.directory.shared.asn1.ber.tlv.Value;
+import org.apache.directory.shared.asn1.codec.EncoderException;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
 /**
+ * The Pre-Authentication data. Tha ASN.1 GRAMMAR IS :
+ * 
+ * PA-DATA         ::= SEQUENCE {
+ *         -- NOTE: first tag is [1], not [0]
+ *         padata-type     [1] Int32,
+ *         padata-value    [2] OCTET STRING -- might be encoded AP-REQ
+ * }
+ * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class PreAuthenticationData
+public class PreAuthenticationData extends AbstractAsn1Object
 {
-    private PreAuthenticationDataType dataType;
-    private byte[] dataValue;
+    /** The logger */
+    private static final Logger log = LoggerFactory.getLogger( PreAuthenticationData.class );
 
+    /** Speedup for logs */
+    private static final boolean IS_DEBUG = log.isDebugEnabled();
+
+    /** The Pre-authentication type */
+    private PreAuthenticationDataType paDataType;
+    
+    /** The authentication data */
+    private byte[] paDataValue;
+
+    // Storage for computed lengths
+    private transient int paDataTypeTagLength;
+    private transient int paDataValueTagLength;
+    private transient int preAuthenticationDataSeqLength;
+    
 
     /**
      * Creates a new instance of PreAuthenticationData.
      *
-     * @param dataType
+     * @param paDataType
      * @param dataValue
      */
-    public PreAuthenticationData( PreAuthenticationDataType dataType, byte[] dataValue )
+    public PreAuthenticationData( PreAuthenticationDataType paDataType, byte[] paDataValue )
     {
-        this.dataType = dataType;
-        this.dataValue = dataValue;
+        this.paDataType = paDataType;
+        this.paDataValue = paDataValue;
     }
 
 
@@ -50,7 +86,7 @@
      */
     public PreAuthenticationDataType getDataType()
     {
-        return dataType;
+        return paDataType;
     }
 
 
@@ -61,6 +97,135 @@
      */
     public byte[] getDataValue()
     {
-        return dataValue;
+        return paDataValue;
+    }
+    
+    /**
+     * Compute the PreAuthenticationData length
+     * 
+     * PreAuthenticationData :
+     * 
+     * 0x30 L1 PreAuthenticationData sequence
+     *  |
+     *  +--> 0xA0 L2 padata-type tag
+     *  |     |
+     *  |     +--> 0x02 L2-1 padata-type (int)
+     *  |
+     *  +--> 0xA1 L3 padata-value tag
+     *        |
+     *        +--> 0x04 L3-1 padata-value (OCTET STRING)
+     *        
+     *  where L1 = L2 + lenght(0xA0) + length(L2) +
+     *             L3 + lenght(0xA1) + length(L3) 
+     *  and
+     *  L2 = L2-1 + length(0x02) + length( L2-1) 
+     *  L3 = L3-1 + length(0x04) + length( L3-1) 
+     */
+    public int computeLength()
+    {
+        // Compute the paDataType. The Length will always be contained in 1 byte
+        int paDataTypeLength = Value.getNbBytes( paDataType.getOrdinal() );
+        paDataTypeTagLength = 1 + TLV.getNbBytes( paDataTypeLength ) + paDataTypeLength;
+        preAuthenticationDataSeqLength = 1 + TLV.getNbBytes( paDataTypeTagLength ) + paDataTypeTagLength;
+
+        // Compute the paDataValue
+        if ( paDataValue == null )
+        {
+            paDataValueTagLength = 1 + 1;
+        }
+        else
+        {
+            paDataValueTagLength = 1 + TLV.getNbBytes( paDataValue.length ) + paDataValue.length;
+        }
+
+        // Compute the whole sequence length
+        preAuthenticationDataSeqLength += 1 + TLV.getNbBytes( paDataValueTagLength ) + paDataValueTagLength;
+
+        return 1 + TLV.getNbBytes( preAuthenticationDataSeqLength ) + preAuthenticationDataSeqLength;
+
+    }
+
+
+    /**
+     * Encode the PreAuthenticationData message to a PDU. 
+     * 
+     * PreAuthenticationData :
+     * 
+     * 0x30 LL
+     *   0xA0 LL 
+     *     0x02 0x01 padata-type
+     *   0xA1 LL 
+     *     0x04 LL padata-value
+     * 
+     * @param buffer The buffer where to put the PDU. It should have been allocated
+     * before, with the right size.
+     * @return The constructed PDU.
+     */
+    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
+    {
+        if ( buffer == null )
+        {
+            throw new EncoderException( "Cannot put a PDU in a null buffer !" );
+        }
+
+        try
+        {
+            // The Checksum SEQ Tag
+            buffer.put( UniversalTag.SEQUENCE_TAG );
+            buffer.put( TLV.getBytes( preAuthenticationDataSeqLength ) );
+
+            // The cksumtype, first the tag, then the value
+            buffer.put( ( byte ) 0xA1 );
+            buffer.put( TLV.getBytes( paDataTypeTagLength ) );
+            Value.encode( buffer, paDataType.getOrdinal() );
+
+            // The checksum, first the tag, then the value
+            buffer.put( ( byte ) 0xA2 );
+            buffer.put( TLV.getBytes( paDataValueTagLength ) );
+            Value.encode( buffer, paDataValue );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            log.error( "Cannot encode the PreAuthenticationData object, the PDU size is {} when only {} bytes has been allocated", 1
+                + TLV.getNbBytes( preAuthenticationDataSeqLength ) + preAuthenticationDataSeqLength, buffer.capacity() );
+            throw new EncoderException( "The PDU buffer size is too small !" );
+        }
+
+        if ( IS_DEBUG )
+        {
+            log.debug( "PreAuthenticationData encoding : {}", StringTools.dumpBytes( buffer.array() ) );
+            log.debug( "PreAuthenticationData initial value : {}", toString() );
+        }
+
+        return buffer;
+    }
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        return toString( "" );
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString( String tabs )
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( tabs ).append( "PreAuthenticationData : {\n" );
+        sb.append( tabs ).append( "    padata-type: " ).append( paDataType ).append( '\n' );
+
+        if ( paDataValue != null )
+        {
+            sb.append( tabs + "    padata-value:" ).append( StringTools.dumpBytes( paDataValue ) ).append( '\n' );
+        }
+
+        sb.append( tabs + "}\n" );
+
+        return sb.toString();
     }
 }

Modified: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PrincipalName.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PrincipalName.java?rev=578743&r1=578742&r2=578743&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PrincipalName.java (original)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/PrincipalName.java Mon Sep 24 03:18:05 2007
@@ -20,14 +20,98 @@
 package org.apache.directory.server.kerberos.shared.messages.value;
 
 
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.kerberos.KerberosPrincipal;
+
+import org.apache.directory.server.kerberos.shared.KerberosUtils;
+import org.apache.directory.server.kerberos.shared.messages.value.types.PrincipalNameType;
+import org.apache.directory.shared.asn1.AbstractAsn1Object;
+import org.apache.directory.shared.asn1.ber.tlv.TLV;
+import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
+import org.apache.directory.shared.asn1.ber.tlv.Value;
+import org.apache.directory.shared.asn1.codec.EncoderException;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
 /**
+ * A principal Name, componsed of a type and N names.
+ * 
+ * PrincipalName   ::= SEQUENCE {
+ *        name-type       [0] Int32,
+ *        name-string     [1] SEQUENCE OF KerberosString
+ * }
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class PrincipalName
+public class PrincipalName extends AbstractAsn1Object
 {
-    private String nameComponent;
-    private int nameType;
+    /** The logger */
+    private static final Logger log = LoggerFactory.getLogger( PrincipalName.class );
+
+    /** Speedup for logs */
+    private static final boolean IS_DEBUG = log.isDebugEnabled();
+
+    /** The type for this principal */
+    private PrincipalNameType nameType;
+
+    /** The principal name - we may have more than one - */
+    private List<String> nameString;
+    
+    /** The principal name as a byte[], for encoding purpose */
+    private transient List<byte[]> nameBytes;
+    
+    // Storage for computed lengths
+    private transient int principalNameSeqLength;
+    private transient int principalTypeTagLength;
+    private transient int principalTypeLength;
+    private transient int principalStringsTagLength;
+    private transient int principalStringsSeqLength;
+
+    /**
+     * Creates a new empty instance of PrincipalName.
+     *
+     * @param principal A Sun kerberosPrincipal instance
+     */
+    public PrincipalName()
+    {
+    }
+
+    /**
+     * Creates a new instance of PrincipalName, given a KerberosPrincipal.
+     * 
+     * We assume that a principal has only one type, even if there are
+     * more than one name component.
+     *
+     * @param principal A Sun kerberosPrincipal instance
+     */
+    public PrincipalName( KerberosPrincipal principal ) throws ParseException
+    {
+        nameString = KerberosUtils.getNames( principal );
+
+        this.nameType = PrincipalNameType.getTypeByOrdinal( principal.getNameType() );
+    }
+    
+    /**
+     * Creates a new instance of PrincipalName given a String and an 
+     * prinipal type.
+     * 
+     * @param nameString The name string, which can contains more than one nameComponent
+     * @param nameType The principal name
+     */
+    public PrincipalName( String nameString, PrincipalNameType nameType )  throws ParseException
+    {
+        this.nameString = KerberosUtils.getNames( nameString );
+        
+        this.nameType = nameType;
+    }
 
 
     /**
@@ -36,10 +120,11 @@
      * @param nameComponent
      * @param nameType
      */
-    public PrincipalName( String nameComponent, int nameType )
+    public PrincipalName( String nameString, int nameType ) throws ParseException
     {
-        this.nameComponent = nameComponent;
-        this.nameType = nameType;
+        this.nameString = KerberosUtils.getNames( nameString );
+        
+        this.nameType = PrincipalNameType.getTypeByOrdinal( nameType );
     }
 
 
@@ -48,19 +133,265 @@
      *
      * @return The type of the {@link PrincipalName}.
      */
-    public int getNameType()
+    public PrincipalNameType getNameType()
     {
         return nameType;
     }
-
+                    
+    /** 
+     * Set the Principal name Type
+     * @param nameType the Principal name Type
+     */
+    public void setNameType( PrincipalNameType nameType )
+    {
+        this.nameType = nameType;
+    }
 
     /**
      * Returns the name component.
      *
      * @return The name component.
      */
+    public List<String> getNameString()
+    {
+        return nameString;
+    }
+
+
     public String getNameComponent()
     {
-        return nameComponent;
+        if ( ( nameString != null ) || ( nameString.size() == 0 ) )
+        {
+            return "";
+        }
+        else
+        {
+            StringBuilder sb = new StringBuilder();
+            boolean isFirst = true;
+
+            for ( String name : nameString )
+            {
+                if ( isFirst )
+                {
+                    isFirst = false;
+                }
+                else
+                {
+                    sb.append( '/' );
+                }
+
+                sb.append( name );
+            }
+
+            return sb.toString();
+        }
+    }
+
+
+    /**
+     * Add a new name to the PrincipalName
+     * @param name The name to add
+     */
+    public void addNameString( String name )
+    {
+        if ( nameString == null )
+        {
+            nameString = new ArrayList<String>();
+        }
+
+        nameString.add( name );
+    }
+
+
+    /**
+     * Compute the PrincipalName length
+     * 
+     * PrincipalName :
+     * 
+     * 0x30 L1 PrincipalName sequence
+     *  |
+     *  +--> 0xA1 L2 name-type tag
+     *  |     |
+     *  |     +--> 0x02 L2-1 addressType (int)
+     *  |
+     *  +--> 0xA2 L3 name-string tag
+     *        |
+     *        +--> 0x30 L3-1 name-string (SEQUENCE OF KerberosString)
+     *              |
+     *              +--> 0x1B L4[1] value (KerberosString)
+     *              |
+     *              +--> 0x1B L4[2] value (KerberosString)
+     *              |
+     *              ...
+     *              |
+     *              +--> 0x1B L4[n] value (KerberosString)
+     */
+    public int computeLength()
+    {
+        // The principalName can't be empty.
+        principalTypeLength = Value.getNbBytes( nameType.getOrdinal() );
+        principalTypeTagLength = 1 + TLV.getNbBytes( principalTypeLength ) + principalTypeLength;
+        
+        principalNameSeqLength = 1 + TLV.getNbBytes( principalTypeTagLength ) + principalTypeTagLength;
+
+        // Compute the keyValue
+        if ( ( nameString == null ) || ( nameString.size() == 0 ) )
+        {
+            principalStringsSeqLength = 0;
+        }
+        else
+        {
+            principalStringsSeqLength = 0;
+            nameBytes = new ArrayList<byte[]>( nameString.size() );
+
+            for ( String name : nameString )
+            {
+                if ( name != null )
+                {
+                    byte[] bytes = StringTools.getBytesUtf8( name );
+                    nameBytes.add( bytes );
+                    principalStringsSeqLength += 1 + TLV.getNbBytes( bytes.length ) + bytes.length;
+                }
+                else
+                {
+                    nameBytes.add( StringTools.EMPTY_BYTES );
+                    principalStringsSeqLength += 1 + 1;
+                }
+            }
+        }
+
+        principalStringsTagLength = 1 + TLV.getNbBytes( principalStringsSeqLength ) + principalStringsSeqLength;
+        principalNameSeqLength += 1 + TLV.getNbBytes( principalStringsTagLength ) + principalStringsTagLength;
+
+        // Compute the whole sequence length
+        return 1 + TLV.getNbBytes( principalNameSeqLength ) + principalNameSeqLength;
+    }
+
+
+    /**
+     * Encode the PrincipalName message to a PDU. 
+     * 
+     * PrincipalName :
+     * 
+     * 0x30 LL
+     *   0xA0 LL 
+     *     0x02 0x01 name-type (integer)
+     *   0xA1 LL 
+     *     0x30 LL name-string (SEQUENCE OF KerberosString)
+     *       0x1B LL name-string[1]
+     *       0x1B LL name-string[2]
+     *       ...
+     *       0x1B LL name-string[n]
+     * 
+     * @param buffer The buffer where to put the PDU. It should have been allocated
+     * before, with the right size.
+     * @return The constructed PDU.
+     */
+    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
+    {
+        if ( buffer == null )
+        {
+            throw new EncoderException( "Cannot put a PDU in a null buffer !" );
+        }
+
+        try
+        {
+            // The PrincipalName SEQ Tag
+            buffer.put( UniversalTag.SEQUENCE_TAG );
+            buffer.put( TLV.getBytes( principalNameSeqLength ) );
+
+            // The name-type, first the tag, then the value
+            buffer.put( ( byte ) 0xA0 );
+            buffer.put( TLV.getBytes( principalTypeTagLength ) );
+            Value.encode( buffer, nameType.getOrdinal() );
+
+            // The name-string tag
+            buffer.put( ( byte ) 0xA1 );
+            buffer.put( TLV.getBytes( principalStringsTagLength ) );
+
+            // The name-string sequence
+            buffer.put( UniversalTag.SEQUENCE_TAG );
+
+            if ( ( nameString == null ) || ( nameString.size() == 0 ) )
+            {
+                buffer.put( ( byte ) 0x00 );
+            }
+            else
+            {
+                buffer.put( TLV.getBytes( principalStringsSeqLength ) );
+
+                // The kerberosStrings
+                for ( byte[] name : nameBytes )
+                {
+                    buffer.put( UniversalTag.GENERALIZED_STRING_TAG );
+
+                    if ( ( name == null ) || ( name.length == 0 ) )
+                    {
+                        buffer.put( ( byte ) 0x00 );
+                    }
+                    else
+                    {
+                        buffer.put( TLV.getBytes( name.length ) );
+                        buffer.put( name );
+                    }
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            log.error(
+                "Cannot encode the principalName object, the PDU size is {} when only {} bytes has been allocated", 1
+                    + TLV.getNbBytes( principalNameSeqLength ) + principalNameSeqLength, buffer.capacity() );
+            throw new EncoderException( "The PDU buffer size is too small !" );
+        }
+
+        if ( IS_DEBUG )
+        {
+            log.debug( "PrinipalName encoding : {}", StringTools.dumpBytes( buffer.array() ) );
+            log.debug( "PrinipalName initial value : {}", toString() );
+        }
+
+        return buffer;
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "PincipalName : {\n" );
+
+        sb.append( "    name-type: " ).append( nameType ).append( '\n' );
+
+        if ( ( nameString != null ) && ( nameString.size() != 0 ) )
+        {
+            sb.append( "    name-string : <" );
+            boolean isFirst = true;
+
+            for ( String name : nameString )
+            {
+                if ( isFirst )
+                {
+                    isFirst = false;
+                }
+                else
+                {
+                    sb.append( ", " );
+                }
+
+                sb.append( '\'' ).append( name ).append( '\'' );
+            }
+
+            sb.append( ">\n}" );
+        }
+        else
+        {
+            sb.append( "    no name-string\n}" );
+        }
+
+        return sb.toString();
     }
 }

Modified: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/TransitedEncoding.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/TransitedEncoding.java?rev=578743&r1=578742&r2=578743&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/TransitedEncoding.java (original)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/TransitedEncoding.java Mon Sep 24 03:18:05 2007
@@ -20,22 +20,63 @@
 package org.apache.directory.server.kerberos.shared.messages.value;
 
 
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+
+import org.apache.directory.server.kerberos.shared.messages.value.types.TransitedEncodingType;
+import org.apache.directory.shared.asn1.AbstractAsn1Object;
+import org.apache.directory.shared.asn1.ber.tlv.TLV;
+import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
+import org.apache.directory.shared.asn1.ber.tlv.Value;
+import org.apache.directory.shared.asn1.codec.EncoderException;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
 /**
+ * The TransitedEncoding structure.
+ * 
+ * The ASN.1 grammar is :
+ * 
+ * -- encoded Transited field
+ * TransitedEncoding       ::= SEQUENCE {
+ *         tr-type         [0] Int32 -- must be registered --,
+ *         contents        [1] OCTET STRING
+ * }
+ * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class TransitedEncoding
+public class TransitedEncoding extends AbstractAsn1Object
 {
-    private TransitedEncodingType type;
+    /** The logger */
+    private static final Logger log = LoggerFactory.getLogger( TransitedEncoding.class );
+
+    /** Speedup for logs */
+    private static final boolean IS_DEBUG = log.isDebugEnabled();
+
+    /** The transited type. One of :
+     * NULL
+     * DOMAIN_X500_COMPRESS
+     */
+    private TransitedEncodingType trType;
+
+    /** The transited data */
     private byte[] contents;
 
+    // Storage for computed lengths
+    private transient int trTypeLength;
+    private transient int contentsLength;
+    private transient int transitedEncodingLength;
+
 
     /**
      * Creates a new instance of TransitedEncoding.
      */
     public TransitedEncoding()
     {
-        type = TransitedEncodingType.NULL;
+        trType = TransitedEncodingType.NULL;
         contents = new byte[0];
     }
 
@@ -46,9 +87,9 @@
      * @param type
      * @param contents
      */
-    public TransitedEncoding( TransitedEncodingType type, byte[] contents )
+    public TransitedEncoding( TransitedEncodingType trType, byte[] contents )
     {
-        this.type = type;
+        this.trType = trType;
         this.contents = contents;
     }
 
@@ -71,6 +112,125 @@
      */
     public TransitedEncodingType getType()
     {
-        return type;
+        return trType;
+    }
+
+
+    /**
+     * Compute the TransitedEncoding length
+     * 
+     * TransitedEncoding :
+     * 
+     * 0x30 L1 TransitedEncoding
+     *  |
+     *  +--> 0xA0 L2 trType tag
+     *  |     |
+     *  |     +--> 0x02 L2-1 trType (int)
+     *  |
+     *  +--> 0xA1 L3 contents tag
+     *        |
+     *        +--> 0x04 L3-1 contents (OCTET STRING)
+     *        
+     *  where L1 = L2 + lenght(0xA0) + length(L2) +
+     *             L3 + lenght(0xA1) + length(L3) 
+     *  and
+     *  L2 = L2-1 + length(0x02) + length( L2-1) 
+     *  L3 = L3-1 + length(0x04) + length( L3-1) 
+     */
+    public int computeLength()
+    {
+        // Compute the trType. The Length will always be contained in 1 byte
+        trTypeLength = 1 + 1 + Value.getNbBytes( trType.getOrdinal() );
+        transitedEncodingLength = 1 + TLV.getNbBytes( trTypeLength ) + trTypeLength;
+
+        // Compute the keyValue
+        if ( contents == null )
+        {
+            contentsLength = 1 + 1;
+        }
+        else
+        {
+            contentsLength = 1 + TLV.getNbBytes( contents.length ) + contents.length;
+        }
+
+        transitedEncodingLength += 1 + TLV.getNbBytes( contentsLength ) + contentsLength;
+
+        // Compute the whole sequence length
+        int transitedEncodingSeqLength = 1 + Value.getNbBytes( transitedEncodingLength ) + transitedEncodingLength;
+
+        return transitedEncodingSeqLength;
+
+    }
+
+
+    /**
+     * Encode the TransitedEncoding message to a PDU. 
+     * 
+     * TransitedEncoding :
+     * 
+     * 0x30 LL
+     *   0xA0 LL 
+     *     0x02 0x01 trType
+     *   0xA1 LL 
+     *     0x04 LL adData
+     * 
+     * @param buffer The buffer where to put the PDU. It should have been allocated
+     * before, with the right size.
+     * @return The constructed PDU.
+     */
+    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
+    {
+        if ( buffer == null )
+        {
+            throw new EncoderException( "Cannot put a PDU in a null buffer !" );
+        }
+
+        try
+        {
+            // The AuthorizationDataEntry SEQ Tag
+            buffer.put( UniversalTag.SEQUENCE_TAG );
+            buffer.put( TLV.getBytes( transitedEncodingLength ) );
+
+            // The tr-type, first the tag, then the value
+            buffer.put( ( byte ) 0xA0 );
+            buffer.put( TLV.getBytes( trTypeLength ) );
+            Value.encode( buffer, trType.getOrdinal() );
+
+            // The contents, first the tag, then the value
+            buffer.put( ( byte ) 0xA1 );
+            buffer.put( TLV.getBytes( contentsLength ) );
+            Value.encode( buffer, contents );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            log.error(
+                "Cannot encode the TransitedEncoding object, the PDU size is {} when only {} bytes has been allocated",
+                1 + TLV.getNbBytes( transitedEncodingLength ) + transitedEncodingLength, buffer.capacity() );
+            throw new EncoderException( "The PDU buffer size is too small !" );
+        }
+
+        if ( IS_DEBUG )
+        {
+            log.debug( "TransitedEncoding encoding : {}", StringTools.dumpBytes( buffer.array() ) );
+            log.debug( "TransitedEncoding initial value : {}", toString() );
+        }
+
+        return buffer;
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "TransitedEncoding : {\n" );
+        sb.append( "    tr-type: " ).append( trType ).append( '\n' );
+
+        sb.append( "    contents: " ).append( StringTools.dumpBytes( contents ) ).append( "\n}\n" );
+
+        return sb.toString();
     }
 }

Added: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/AbstractKerberosFlags.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/AbstractKerberosFlags.java?rev=578743&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/AbstractKerberosFlags.java (added)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/AbstractKerberosFlags.java Mon Sep 24 03:18:05 2007
@@ -0,0 +1,226 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.kerberos.shared.messages.value.flags;
+
+import org.apache.directory.shared.asn1.primitives.BitString;
+
+/**
+ * An implementation of a BitString for any KerberosFlags. The different values
+ * are stored in an int, as there can't be more than 32 flags (TicketFlag).
+ * 
+ * Some basic operations are implemented in this abstract class, like those
+ * manipulating flags.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 540371 $, $Date: 2007-05-22 02:00:43 +0200 (Tue, 22 May 2007) $
+ */
+public abstract class AbstractKerberosFlags extends BitString implements KerberosFlags
+{
+    /** The associated value */
+    protected int value;
+    
+    /**
+     * Standard constructor, which create a BitString containing 32 bits
+     */
+    public AbstractKerberosFlags()
+    {
+        super( 32 );
+    }
+
+    /**
+     * Standard constructor, taking a byte array
+     */
+    public AbstractKerberosFlags( byte[] flags )
+    {
+        super( flags );
+    }
+    
+    /**
+     * A static method to get the bayte array representation of an int
+     * @return The byte array for a list of flags.
+     */
+    public static byte[] getBytes( int flags )
+    {
+        return new byte[]{
+                (byte)( flags >>> 24), 
+                (byte)( ( flags >> 16 ) & 0x00ff ), 
+                (byte)( ( flags >> 8 ) & 0x00ff ), 
+                (byte)( flags & 0x00ff ) };
+    }
+    
+    /**
+     * @return The byte array for a KerberosFlags
+     */
+    public byte[] getBytes()
+    {
+        return getData();
+        /*new byte[]{
+                (byte)( value >>> 24), 
+                (byte)( ( value >> 16 ) & 0x00ff ), 
+                (byte)( ( value >> 8 ) & 0x00ff ), 
+                (byte)( value & 0x00ff ) };*/
+    }
+
+    /**
+     * Returns the int value associated with the flags
+     */
+    public int getIntValue()
+    {
+        return value;
+    }
+    
+    
+    
+    /**
+     * Check if a flag is set
+     * @param flags The flags to test
+     * @param flag The flag to check
+     * @return True if the flag is set in the list of flags
+     */
+    public static boolean isFlagSet( int flags, int flag )
+    {
+        return ( flags & ( 1 << flag) ) != 0;
+    }
+    
+    /**
+     * Check if a flag is set
+     * @param flags The flags to test
+     * @param flag The flag to check
+     * @return True if the flag is set in the list of flags
+     */
+    /*public static boolean isFlagSet( int flags, KerberosFlag flag )
+    {
+        return ( flags & ( 1 << flag.getOrdinal() ) ) != 0;
+    }*/
+    
+    /**
+     * Check if a flag is set for the actual value
+     * 
+     * @param flag The flag to check
+     * @return True if the flag is set in the list of flags
+     */
+    public boolean isFlagSet( KerberosFlag flag )
+    {
+        return ( value & ( 1 << flag.getOrdinal() ) ) != 0;
+    }
+    
+    /**
+     * Check if a flag is set
+     * @param flags The flags to test
+     * @return True if the flag is set in the list of flags
+     */
+    public boolean isFlagSet( int flag )
+    {
+        return ( flag & ( 1 << value ) ) != 0;
+    }
+    
+    /**
+     * Set a flag in a list of flags
+     * 
+     * @param flags The list of flags
+     * @param flag The flag to set
+     */
+    /*public static int setFlag( int flags, KerberosFlag flag )
+    {
+        flags |= 1 << flag.getOrdinal();
+        return flags;
+    }*/
+    
+    /**
+     * Set a flag in a list of flags
+     * 
+     * @param flag The flag to set
+     */
+    public void setFlag( KerberosFlag flag )
+    {
+        value |= 1 << flag.getOrdinal();
+        setBit( flag.getOrdinal() );
+    }
+    
+    /**
+     * Set a flag in a list of flags
+     * 
+     * @param flag The flag to set
+     */
+    public void setFlag( int flag )
+    {
+        value |= 1 << flag;
+        setBit( flag );
+    }
+    
+    
+    /**
+     * Modify a byte array to an integer value
+     * @param value The 4 bytes byte array to transform.
+     * @return The int which contains the bytes value.
+     */
+    public void setFlags( byte[] bytes )
+    {
+        if ( (bytes== null ) || ( bytes.length != 4 ) )
+        {
+            value = -1;
+        }
+        
+        value = ( bytes[0] << 24 ) + ( bytes[1] << 16 ) + ( bytes[2] << 8 ) + bytes[3];
+        setData( bytes );
+    }
+    
+    /**
+     * clear a flag in a list of flags
+     * 
+     * @param flags The list of flags
+     * @param flag The flag to set
+     */
+    /*public static void clearFlag( int flags, KerberosFlag flag )
+    {
+        flags &= ~( 1 << flag.getOrdinal() );
+    }*/
+
+    /**
+     * clear a flag in a list of flags
+     * 
+     * @param flag The flag to set
+     */
+    public void clearFlag( KerberosFlag flag )
+    {
+        value &= ~( 1 << flag.getOrdinal() );
+        clearBit( flag.getOrdinal() );
+    }
+    
+    /**
+     * clear a flag in a list of flags
+     * 
+     * @param flag The flag to set
+     */
+    public void clearFlag( int flag )
+    {
+        value &= ~( 1 << flag );
+        clearBit( flag );
+    }
+    
+    /**
+     * @return The hex value for this flag, in its position.
+     * For instance, getting the flag 5 will return 0x0000 0010 
+     */
+    public int getHexValue()
+    {
+        return 1 << value;
+    }
+}

Added: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/ApOption.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/ApOption.java?rev=578743&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/ApOption.java (added)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/ApOption.java Mon Sep 24 03:18:05 2007
@@ -0,0 +1,75 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.kerberos.shared.messages.value.flags;
+
+/**
+ * An enum to describe all the ApOption possible values.
+ * 
+ *  APOptions       ::= KerberosFlags
+ *           -- reserved(0),
+ *           -- use-session-key(1),
+ *           -- mutual-required(2)
+ *
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 540371 $, $Date: 2007-05-22 02:00:43 +0200 (Tue, 22 May 2007) $
+ */
+public enum ApOption implements KerberosFlag
+{
+    /**
+     * AP Request option - reserved
+     */
+    RESERVED(0),
+
+    /**
+     * AP Request option - use session key
+     */
+    USE_SESSION_KEY(1),
+
+    /**
+     * AP Request option - mutual authentication required
+     */
+    MUTUAL_REQUIRED(2),
+
+    /**
+     * AP Request option - maximum value
+     */
+    MAX_VALUE(32);
+
+
+    // The interned value.
+    private int value;
+    
+    /**
+     * Class constructor
+     */
+    private ApOption( int value )
+    {
+        this.value = value;
+    }
+    
+    /**
+     * @return The ordinal value associated with this flag
+     */
+    public int getOrdinal()
+    {
+        return value;
+    }
+}

Added: directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/ApOptions.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/ApOptions.java?rev=578743&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/ApOptions.java (added)
+++ directory/apacheds/branches/apacheds-kerberos/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/flags/ApOptions.java Mon Sep 24 03:18:05 2007
@@ -0,0 +1,107 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.kerberos.shared.messages.value.flags;
+
+
+/**
+ * An abstract class where are implemented the common methods described in
+ * the interface
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 540371 $, $Date: 2007-05-22 02:00:43 +0200 (Tue, 22 May 2007) $
+ */
+public class ApOptions extends AbstractKerberosFlags
+{
+    public static final long serialVersionUID = 1L;
+
+    /**
+      * Basic constructor of a ApOptions BitString
+      */
+     public ApOptions()
+     {
+         super();
+     }
+     
+     /**
+      * Constructor of a ApOptions BitString with an int value
+      */
+     public ApOptions( int flags )
+     {
+         super( getBytes( flags ) );
+     }
+     
+     /**
+      * Basic constructor of a ApOptions BitString with a byte array
+      */
+     public ApOptions( byte[] flags )
+     {
+         super( flags );
+     }
+     
+     /**
+      * AP Option flag - the client requires mutual authentication
+      */
+     public boolean isMutualRequired()
+     {
+        return isFlagSet( ApOption.MUTUAL_REQUIRED );
+     }
+
+     /**
+      * AP Option flag - Reserved for future use
+      */
+     public boolean isReserved()
+     {
+        return isFlagSet( ApOption.RESERVED );
+     }
+
+     /**
+      * AP Option flag - the ticket the client is presenting to a 
+      * server is encrypted in the session key from the server's TGT
+      */
+     public boolean isUseSessionKey()
+     {
+        return isFlagSet( ApOption.USE_SESSION_KEY );
+     }
+
+     /**
+     * Converts the object to a printable string.
+     */
+    public String toString()
+    {
+        StringBuilder result = new StringBuilder();
+
+        if ( isFlagSet( ApOption.RESERVED ) )
+        {
+            result.append( "RESERVED(0) " );
+        }
+
+        if ( isFlagSet( ApOption.USE_SESSION_KEY ) )
+        {
+            result.append( "USE_SESSION_KEY(1) " );
+        }
+
+        if ( isFlagSet( ApOption.MUTUAL_REQUIRED ) )
+        {
+            result.append( "MUTUAL_REQUIRED(2) " );
+        }
+
+        return result.toString().trim();
+    }
+}