blob: 2538e569d78a52d3c2e0cd9ff5b96ade9cecb8fd [file] [log] [blame]
/*
* 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.shared.kerberos.components;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import org.apache.directory.api.asn1.Asn1Object;
import org.apache.directory.api.asn1.EncoderException;
import org.apache.directory.api.asn1.ber.tlv.BerValue;
import org.apache.directory.api.asn1.ber.tlv.TLV;
import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
import org.apache.directory.api.util.Strings;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.shared.kerberos.KerberosConstants;
import org.apache.directory.shared.kerberos.KerberosTime;
import org.apache.directory.shared.kerberos.flags.TicketFlag;
import org.apache.directory.shared.kerberos.flags.TicketFlags;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* EncTicketPart ::= [APPLICATION 3] SEQUENCE {
* flags [0] TicketFlags,
* key [1] EncryptionKey,
* crealm [2] Realm,
* cname [3] PrincipalName,
* transited [4] TransitedEncoding,
* authtime [5] KerberosTime,
* starttime [6] KerberosTime OPTIONAL,
* endtime [7] KerberosTime,
* renew-till [8] KerberosTime OPTIONAL,
* caddr [9] HostAddresses OPTIONAL,
* authorization-data [10] AuthorizationData OPTIONAL
* }
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class EncTicketPart implements Asn1Object
{
/** The logger */
private static final Logger log = LoggerFactory.getLogger( EncTicketPart.class );
/** Speedup for logs */
private static final boolean IS_DEBUG = log.isDebugEnabled();
/** the ticket's flags */
private TicketFlags flags = new TicketFlags();
/** the encryption key */
private EncryptionKey key;
/** the client's realm */
private String cRealm;
/** client's principal */
private PrincipalName cName;
/** field containing list of transited realm names */
private TransitedEncoding transited;
/** time of initial authentication */
private KerberosTime authTime;
/** time after which ticket is valid */
private KerberosTime startTime;
/** ticket's expiry time */
private KerberosTime endTime;
/** the maximum endtime that may be included in a renewal */
private KerberosTime renewtill;
/** the addresses from which this ticket can be used */
private HostAddresses clientAddresses;
/** the authorization data */
private AuthorizationData authorizationData;
private int flagsLen;
private int keyLen;
private int cRealmLen;
private byte[] cRealmBytes;
private int cNameLen;
private int transitedLen;
private int authTimeLen;
private byte[] authTimeBytes;
private int startTimeLen;
private byte[] startTimeBytes;
private int endTimeLen;
private byte[] endTimeBytes;
private int renewtillLen;
private byte[] renewtillBytes;
private int clientAddressesLen;
private int authzDataLen;
private int encTikcetPartSeqLen;
private int encTikcetPartLen;
/**
* compute length for EncTicketPart:
* <pre>
* 0x63 L1 EncTicketPart tag
* |
* +--&gt; 0x30 L1-2 EncTicketPart seq
* |
* +--&gt; 0xA0 L2 flags tag
* | |
* | +--&gt; 0x03 L2-2 flags (BitString)
* |
* +--&gt; 0xA1 L3 key tag
* | |
* | +--&gt; 0x30 L3-2 key (EncryptionKey)
* |
* +--&gt; 0xA2 L4 crealm tag
* | |
* | +--&gt; 0x1B L4-2 crealm (Realm)
* |
* +--&gt; 0xA3 L5 cname tag
* | |
* | +--&gt; 0x30 L5-2 cname (PrincipalName)
* |
* +--&gt; 0xA4 L6 transited tag
* | |
* | +--&gt; 0x30 L6-2 transited (TransitedEncoding)
* |
* +--&gt; 0xA5 0x11 authtime tag
* | |
* | +--&gt; 0x18 0x0F authtime (KerberosTime)
* |
* +--&gt; [0xA6 0x11 starttime tag
* | |
* | +--&gt; 0x18 0x0F starttime (KerberosTime)]
* |
* +--&gt; 0xA7 0x11 endtime tag
* | |
* | +--&gt; 0x18 0x0F endtime (KerberosTime)
* |
* +--&gt; [0xA8 0x11 renewtill tag
* | |
* | +--&gt; 0x18 0x0F renewtill (KerberosTime)]
* |
* +--&gt; [0xA9 L7 caddr tag
* | |
* | +--&gt; 0x30 L7-2 caddre (HostAddresses)]
* |
* +--&gt; [0xAA L8 authorization-data tag
* |
* +--&gt; 0x30 L8-2 authorization-data (AuthorizationData)]
* </pre>
*
*/
@Override
public int computeLength()
{
flagsLen = flags.getData().length;
flagsLen = 1 + TLV.getNbBytes( flagsLen ) + flagsLen;
encTikcetPartSeqLen = 1 + TLV.getNbBytes( flagsLen ) + flagsLen;
keyLen = key.computeLength();
encTikcetPartSeqLen += 1 + TLV.getNbBytes( keyLen ) + keyLen;
cRealmBytes = Strings.getBytesUtf8( cRealm );
cRealmLen = 1 + TLV.getNbBytes( cRealmBytes.length ) + cRealmBytes.length;
encTikcetPartSeqLen += 1 + TLV.getNbBytes( cRealmLen ) + cRealmLen;
cNameLen = cName.computeLength();
encTikcetPartSeqLen += 1 + TLV.getNbBytes( cNameLen ) + cNameLen;
transitedLen = transited.computeLength();
encTikcetPartSeqLen += 1 + TLV.getNbBytes( transitedLen ) + transitedLen;
authTimeBytes = authTime.getBytes();
authTimeLen = 1 + TLV.getNbBytes( authTimeBytes.length ) + authTimeBytes.length;
encTikcetPartSeqLen += 1 + TLV.getNbBytes( authTimeLen ) + authTimeLen;
if ( startTime != null )
{
startTimeBytes = startTime.getBytes();
startTimeLen = 1 + TLV.getNbBytes( startTimeBytes.length ) + startTimeBytes.length;
encTikcetPartSeqLen += 1 + TLV.getNbBytes( startTimeLen ) + startTimeLen;
}
endTimeBytes = endTime.getBytes();
endTimeLen = 1 + TLV.getNbBytes( endTimeBytes.length ) + endTimeBytes.length;
encTikcetPartSeqLen += 1 + TLV.getNbBytes( endTimeLen ) + endTimeLen;
if ( renewtill != null )
{
renewtillBytes = renewtill.getBytes();
renewtillLen = 1 + TLV.getNbBytes( renewtillBytes.length ) + renewtillBytes.length;
encTikcetPartSeqLen += 1 + TLV.getNbBytes( renewtillLen ) + renewtillLen;
}
if ( clientAddresses != null )
{
clientAddressesLen = clientAddresses.computeLength();
encTikcetPartSeqLen += 1 + TLV.getNbBytes( clientAddressesLen ) + clientAddressesLen;
}
if ( authorizationData != null )
{
authzDataLen = authorizationData.computeLength();
encTikcetPartSeqLen += 1 + TLV.getNbBytes( authzDataLen ) + authzDataLen;
}
encTikcetPartLen = 1 + TLV.getNbBytes( encTikcetPartSeqLen ) + encTikcetPartSeqLen;
return 1 + TLV.getNbBytes( encTikcetPartLen ) + encTikcetPartLen;
}
public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
{
if ( buffer == null )
{
throw new EncoderException( I18n.err( I18n.ERR_148 ) );
}
try
{
// EncTicketPart application tag and length
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_TAG );
buffer.put( TLV.getBytes( encTikcetPartLen ) );
// EncTicketPart sequence tag and length
buffer.put( UniversalTag.SEQUENCE.getValue() );
buffer.put( TLV.getBytes( encTikcetPartSeqLen ) );
// flags tag and int value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_FLAGS_TAG );
buffer.put( TLV.getBytes( flagsLen ) );
BerValue.encode( buffer, flags );
// key tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_KEY_TAG );
buffer.put( TLV.getBytes( keyLen ) );
key.encode( buffer );
// crealm tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_CREALM_TAG );
buffer.put( TLV.getBytes( cRealmLen ) );
buffer.put( UniversalTag.GENERAL_STRING.getValue() );
buffer.put( TLV.getBytes( cRealmBytes.length ) );
buffer.put( cRealmBytes );
// cname tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_CNAME_TAG );
buffer.put( TLV.getBytes( cNameLen ) );
cName.encode( buffer );
// transited tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_TRANSITED_TAG );
buffer.put( TLV.getBytes( transitedLen ) );
transited.encode( buffer );
// authtime tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_AUTHTIME_TAG );
buffer.put( TLV.getBytes( authTimeLen ) );
buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
buffer.put( ( byte ) 0x0F );
buffer.put( authTimeBytes );
if ( startTime != null )
{
// strattime tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_STARTTIME_TAG );
buffer.put( TLV.getBytes( startTimeLen ) );
buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
buffer.put( ( byte ) 0x0F );
buffer.put( startTimeBytes );
}
// endtime tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_ENDTIME_TAG );
buffer.put( TLV.getBytes( endTimeLen ) );
buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
buffer.put( ( byte ) 0x0F );
buffer.put( endTimeBytes );
if ( renewtill != null )
{
// renewtill tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_RENEWTILL_TAG );
buffer.put( TLV.getBytes( renewtillLen ) );
buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
buffer.put( ( byte ) 0x0F );
buffer.put( renewtillBytes );
}
if ( clientAddresses != null )
{
// caddr tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_CADDR_TAG );
buffer.put( TLV.getBytes( clientAddressesLen ) );
clientAddresses.encode( buffer );
}
if ( authorizationData != null )
{
// authorization-data tag and value
buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_AUTHORIZATION_DATA_TAG );
buffer.put( TLV.getBytes( authzDataLen ) );
authorizationData.encode( buffer );
}
}
catch ( BufferOverflowException boe )
{
log.error( I18n.err( I18n.ERR_742_CANNOT_ENCODE_ENC_TICKET_PART, 1 + TLV.getNbBytes( encTikcetPartLen )
+ encTikcetPartLen, buffer.capacity() ) );
throw new EncoderException( I18n.err( I18n.ERR_138 ), boe );
}
if ( IS_DEBUG )
{
log.debug( "EncTicketPart encoding : {}", Strings.dumpBytes( buffer.array() ) );
log.debug( "EncTicketPart initial value : {}", this );
}
return buffer;
}
/**
* @return the flags
*/
public TicketFlags getFlags()
{
return flags;
}
/**
* @param flags the flags to set
*/
public void setFlags( TicketFlags flags )
{
this.flags = flags;
}
/**
* @return the key
*/
public EncryptionKey getKey()
{
return key;
}
/**
* @param key the key to set
*/
public void setKey( EncryptionKey key )
{
this.key = key;
}
/**
* @return the cRealm
*/
public String getCRealm()
{
return cRealm;
}
/**
* @param cRealm the cRealm to set
*/
public void setCRealm( String cRealm )
{
this.cRealm = cRealm;
}
/**
* @return the cName
*/
public PrincipalName getCName()
{
return cName;
}
/**
* @param cName the cName to set
*/
public void setCName( PrincipalName cName )
{
this.cName = cName;
}
/**
* @return the transited
*/
public TransitedEncoding getTransited()
{
return transited;
}
/**
* @param transited the transited to set
*/
public void setTransited( TransitedEncoding transited )
{
this.transited = transited;
}
/**
* @return the authTime
*/
public KerberosTime getAuthTime()
{
return authTime;
}
/**
* @param authTime the authTime to set
*/
public void setAuthTime( KerberosTime authTime )
{
this.authTime = authTime;
}
/**
* @return the startTime
*/
public KerberosTime getStartTime()
{
return startTime;
}
/**
* @param startTime the startTime to set
*/
public void setStartTime( KerberosTime startTime )
{
this.startTime = startTime;
}
/**
* @return the endTime
*/
public KerberosTime getEndTime()
{
return endTime;
}
/**
* @param endTime the endTime to set
*/
public void setEndTime( KerberosTime endTime )
{
this.endTime = endTime;
}
/**
* @return the renewtill
*/
public KerberosTime getRenewTill()
{
return renewtill;
}
/**
* @param renewtill the renewtill to set
*/
public void setRenewTill( KerberosTime renewtill )
{
this.renewtill = renewtill;
}
/**
* @return the clientAddresses
*/
public HostAddresses getClientAddresses()
{
return clientAddresses;
}
/**
* @param clientAddresses the clientAddresses to set
*/
public void setClientAddresses( HostAddresses clientAddresses )
{
this.clientAddresses = clientAddresses;
}
/**
* @return the authzData
*/
public AuthorizationData getAuthorizationData()
{
return authorizationData;
}
/**
* @param authzData the authzData to set
*/
public void setAuthorizationData( AuthorizationData authzData )
{
this.authorizationData = authzData;
}
/**
* adds the given flag to the already existing flags.
* If no flags exist then creates a new TicketFlags object then sets this flag
* and assigns the TicketFlags to this ticket part
*
* @param flag the flag to be set
*/
public void setFlag( TicketFlag flag )
{
if ( flags == null )
{
flags = new TicketFlags();
}
flags.setFlag( flag.getValue() );
}
/**
* @see Object#toString()
*/
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( "EncTicketPart : {\n" );
sb.append( " flags: " ).append( flags ).append( '\n' );
sb.append( " key: " ).append( key ).append( '\n' );
sb.append( " cRealm: " ).append( cRealm ).append( '\n' );
sb.append( " cName: " ).append( cName ).append( '\n' );
sb.append( " transited: " ).append( transited ).append( '\n' );
sb.append( " authTime: " ).append( authTime ).append( '\n' );
if ( startTime != null )
{
sb.append( " startTime: " ).append( startTime ).append( '\n' );
}
sb.append( " endTime: " ).append( endTime ).append( '\n' );
if ( renewtill != null )
{
sb.append( " renewtill: " ).append( renewtill ).append( '\n' );
}
if ( clientAddresses != null )
{
sb.append( " clientAddresses: " ).append( clientAddresses ).append( '\n' );
}
if ( authorizationData != null )
{
sb.append( " authzData: " ).append( authorizationData ).append( '\n' );
}
sb.append( "}\n" );
return sb.toString();
}
}