001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.shared.kerberos.messages; 021 022 023import java.nio.BufferOverflowException; 024import java.nio.ByteBuffer; 025 026import org.apache.directory.api.asn1.EncoderException; 027import org.apache.directory.api.asn1.ber.tlv.BerValue; 028import org.apache.directory.api.asn1.ber.tlv.TLV; 029import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 030import org.apache.directory.api.util.Strings; 031import org.apache.directory.server.i18n.I18n; 032import org.apache.directory.shared.kerberos.KerberosConstants; 033import org.apache.directory.shared.kerberos.KerberosMessageType; 034import org.apache.directory.shared.kerberos.components.EncryptedData; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038 039/** 040 * AP-REP message. 041 * It will store the object described by the ASN.1 grammar : 042 * <pre> 043 * AP-REP ::= [APPLICATION 15] SEQUENCE { 044 * pvno [0] INTEGER (5), 045 * msg-type [1] INTEGER (15), 046 * enc-part [2] <EncryptedData> -- EncAPRepPart 047 * } 048 * </pre> 049 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 050 */ 051public class ApRep extends KerberosMessage 052{ 053 /** The logger */ 054 private static final Logger LOG = LoggerFactory.getLogger( ApRep.class ); 055 056 /** Speedup for logs */ 057 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 058 059 /** The encryptedData, an encrypted EncAPRepPart */ 060 private EncryptedData encPart; 061 062 // Storage for computed lengths 063 private int pvnoLength; 064 private int msgTypeLength; 065 private int encPartLength; 066 private int apRepLength; 067 private int apRepSeqLength; 068 069 070 /** 071 * Creates a new instance of AP-REP. 072 */ 073 public ApRep() 074 { 075 super( KerberosMessageType.AP_REP ); 076 } 077 078 079 /** 080 * Returns the {@link EncryptedData}. 081 * 082 * @return The {@link EncryptedData}. 083 */ 084 public EncryptedData getEncPart() 085 { 086 return encPart; 087 } 088 089 090 /** 091 * Sets the {@link EncryptedData}. 092 * 093 * @param encPart The encrypted part 094 */ 095 public void setEncPart( EncryptedData encPart ) 096 { 097 this.encPart = encPart; 098 } 099 100 101 /** 102 * Compute the AP-REP length 103 * <pre> 104 * AP-REP : 105 * 106 * 0x6F L1 AP-REP message 107 * | 108 * +--> 0x30 L2 109 * | 110 * +--> 0xA0 0x03 111 * | | 112 * | +--> 0x02 0x01 0x05 pvno 113 * | 114 * +--> 0xA1 0x03 115 * | | 116 * | +--> 0x02 0x01 0x0E msg-type 117 * | 118 * +--> 0xA2 L3 119 * | 120 * +--> 0x30 L3-1 enc-part 121 * 122 * </pre> 123 */ 124 public int computeLength() 125 { 126 // Compute the PVNO length. 127 pvnoLength = 1 + 1 + BerValue.getNbBytes( getProtocolVersionNumber() ); 128 129 // Compute the msg-type length 130 msgTypeLength = 1 + 1 + BerValue.getNbBytes( getMessageType().getValue() ); 131 132 // Compute the enc-part length 133 encPartLength = encPart.computeLength(); 134 135 // Compute the sequence size 136 apRepLength = 137 1 + TLV.getNbBytes( pvnoLength ) + pvnoLength + 138 1 + TLV.getNbBytes( msgTypeLength ) + msgTypeLength + 139 1 + TLV.getNbBytes( encPartLength ) + encPartLength; 140 141 apRepSeqLength = 1 + TLV.getNbBytes( apRepLength ) + apRepLength; 142 143 return 1 + TLV.getNbBytes( apRepSeqLength ) + apRepSeqLength; 144 } 145 146 147 /** 148 * Encode the AP-REP component 149 * 150 * @param buffer The buffer containing the encoded result 151 * @return The encoded component 152 * @throws EncoderException If the encoding failed 153 */ 154 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 155 { 156 if ( buffer == null ) 157 { 158 buffer = ByteBuffer.allocate( computeLength() ); 159 } 160 161 try 162 { 163 // The AP-REP Tag 164 buffer.put( ( byte ) KerberosConstants.AP_REP_TAG ); 165 buffer.put( TLV.getBytes( apRepSeqLength ) ); 166 167 // The AP-REP SEQ Tag 168 buffer.put( UniversalTag.SEQUENCE.getValue() ); 169 buffer.put( TLV.getBytes( apRepLength ) ); 170 171 // The PVNO ------------------------------------------------------- 172 // The tag 173 buffer.put( ( byte ) KerberosConstants.AP_REP_PVNO_TAG ); 174 buffer.put( TLV.getBytes( pvnoLength ) ); 175 176 // The value 177 BerValue.encode( buffer, getProtocolVersionNumber() ); 178 179 // The msg-type --------------------------------------------------- 180 // The tag 181 buffer.put( ( byte ) KerberosConstants.AP_REP_MSG_TYPE_TAG ); 182 buffer.put( TLV.getBytes( msgTypeLength ) ); 183 184 // The value 185 BerValue.encode( buffer, getMessageType().getValue() ); 186 187 // The enc-part --------------------------------------------------- 188 // The tag 189 buffer.put( ( byte ) KerberosConstants.AP_REP_ENC_PART_TAG ); 190 buffer.put( TLV.getBytes( encPartLength ) ); 191 192 // The value 193 encPart.encode( buffer ); 194 } 195 catch ( BufferOverflowException boe ) 196 { 197 LOG.error( I18n.err( I18n.ERR_137, 1 + TLV.getNbBytes( apRepLength ) + apRepLength, 198 buffer.capacity() ) ); 199 throw new EncoderException( I18n.err( I18n.ERR_138 ), boe ); 200 } 201 202 if ( IS_DEBUG ) 203 { 204 LOG.debug( "AP-REP encoding : {}", Strings.dumpBytes( buffer.array() ) ); 205 LOG.debug( "AP-REP initial value : {}", this ); 206 } 207 208 return buffer; 209 } 210 211 212 /** 213 * @see Object#toString() 214 */ 215 public String toString() 216 { 217 StringBuilder sb = new StringBuilder(); 218 219 sb.append( "AP-REP :\n" ); 220 sb.append( " pvno : " ).append( getProtocolVersionNumber() ).append( "\n" ); 221 sb.append( " msg-type : " ).append( getMessageType() ).append( "\n" ); 222 sb.append( " enc-part : " ).append( encPart ).append( "\n" ); 223 224 return sb.toString(); 225 } 226}