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 */ 020 package org.apache.directory.server.kerberos.shared.messages.value; 021 022 023 import java.nio.BufferOverflowException; 024 import java.nio.ByteBuffer; 025 026 import org.apache.directory.server.i18n.I18n; 027 import org.apache.directory.server.kerberos.shared.messages.value.types.PaDataType; 028 import org.apache.directory.shared.asn1.AbstractAsn1Object; 029 import org.apache.directory.shared.asn1.ber.tlv.TLV; 030 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; 031 import org.apache.directory.shared.asn1.ber.tlv.Value; 032 import org.apache.directory.shared.asn1.codec.EncoderException; 033 import org.apache.directory.shared.ldap.util.StringTools; 034 import org.slf4j.Logger; 035 import org.slf4j.LoggerFactory; 036 037 038 /** 039 * The Pre-Authentication data. Tha ASN.1 GRAMMAR IS : 040 * 041 * PA-DATA ::= SEQUENCE { 042 * -- NOTE: first tag is [1], not [0] 043 * padata-type [1] Int32, 044 * padata-value [2] OCTET STRING -- might be encoded AP-REQ 045 * } 046 * 047 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 048 * @version $Rev: 902575 $, $Date: 2010-01-24 15:38:06 +0100 (Sun, 24 Jan 2010) $ 049 */ 050 public class PaData extends AbstractAsn1Object 051 { 052 /** The logger */ 053 private static final Logger log = LoggerFactory.getLogger( PaData.class ); 054 055 /** Speedup for logs */ 056 private static final boolean IS_DEBUG = log.isDebugEnabled(); 057 058 /** The Pre-authentication type */ 059 private PaDataType paDataType; 060 061 /** The authentication data */ 062 private byte[] paDataValue; 063 064 // Storage for computed lengths 065 private transient int paDataTypeTagLength; 066 private transient int paDataValueTagLength; 067 private transient int preAuthenticationDataSeqLength; 068 069 070 /** 071 * Creates a new instance of PreAuthenticationData. 072 */ 073 public PaData() 074 { 075 } 076 077 078 /** 079 * Creates a new instance of PreAuthenticationData. 080 * 081 * @param paDataType 082 * @param paDataValue 083 */ 084 public PaData( PaDataType paDataType, byte[] paDataValue ) 085 { 086 this.paDataType = paDataType; 087 this.paDataValue = paDataValue; 088 } 089 090 091 /** 092 * Returns the {@link PaDataType}. 093 * 094 * @return The {@link PaDataType}. 095 */ 096 public PaDataType getPaDataType() 097 { 098 return paDataType; 099 } 100 101 102 /** 103 * Set the PA-DATA type 104 * 105 * @param paDataType The PA-DATA type 106 */ 107 public void setPaDataType( int paDataType ) 108 { 109 this.paDataType = PaDataType.getTypeByOrdinal( paDataType ); 110 } 111 112 113 /** 114 * Set the PA-DATA type 115 * 116 * @param paDataType The PA-DATA type 117 */ 118 public void setPaDataType( PaDataType paDataType ) 119 { 120 this.paDataType = paDataType; 121 } 122 123 124 /** 125 * Returns the raw bytes of the {@link PaData}. 126 * 127 * @return The raw bytes of the {@link PaData}. 128 */ 129 public byte[] getPaDataValue() 130 { 131 return paDataValue; 132 } 133 134 135 /** 136 * Set the PA-DATA value 137 * 138 * @param paDataValue The PA-DATA value 139 */ 140 public void setPaDataValue( byte[] paDataValue ) 141 { 142 this.paDataValue = paDataValue; 143 } 144 145 146 /** 147 * Compute the PreAuthenticationData length 148 * 149 * PreAuthenticationData : 150 * 151 * 0x30 L1 PreAuthenticationData sequence 152 * | 153 * +--> 0xA0 L2 padata-type tag 154 * | | 155 * | +--> 0x02 L2-1 padata-type (int) 156 * | 157 * +--> 0xA1 L3 padata-value tag 158 * | 159 * +--> 0x04 L3-1 padata-value (OCTET STRING) 160 * 161 * where L1 = L2 + lenght(0xA0) + length(L2) + 162 * L3 + lenght(0xA1) + length(L3) 163 * and 164 * L2 = L2-1 + length(0x02) + length( L2-1) 165 * L3 = L3-1 + length(0x04) + length( L3-1) 166 */ 167 public int computeLength() 168 { 169 // Compute the paDataType. The Length will always be contained in 1 byte 170 int paDataTypeLength = Value.getNbBytes( paDataType.getOrdinal() ); 171 paDataTypeTagLength = 1 + TLV.getNbBytes( paDataTypeLength ) + paDataTypeLength; 172 preAuthenticationDataSeqLength = 1 + TLV.getNbBytes( paDataTypeTagLength ) + paDataTypeTagLength; 173 174 // Compute the paDataValue 175 if ( paDataValue == null ) 176 { 177 paDataValueTagLength = 1 + 1; 178 } 179 else 180 { 181 paDataValueTagLength = 1 + TLV.getNbBytes( paDataValue.length ) + paDataValue.length; 182 } 183 184 // Compute the whole sequence length 185 preAuthenticationDataSeqLength += 1 + TLV.getNbBytes( paDataValueTagLength ) + paDataValueTagLength; 186 187 return 1 + TLV.getNbBytes( preAuthenticationDataSeqLength ) + preAuthenticationDataSeqLength; 188 189 } 190 191 192 /** 193 * Encode the PreAuthenticationData message to a PDU. 194 * 195 * PreAuthenticationData : 196 * 197 * 0x30 LL 198 * 0xA0 LL 199 * 0x02 0x01 padata-type 200 * 0xA1 LL 201 * 0x04 LL padata-value 202 * 203 * @param buffer The buffer where to put the PDU. It should have been allocated 204 * before, with the right size. 205 * @return The constructed PDU. 206 */ 207 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 208 { 209 if ( buffer == null ) 210 { 211 throw new EncoderException( I18n.err( I18n.ERR_148 ) ); 212 } 213 214 try 215 { 216 // The Checksum SEQ Tag 217 buffer.put( UniversalTag.SEQUENCE_TAG ); 218 buffer.put( TLV.getBytes( preAuthenticationDataSeqLength ) ); 219 220 // The cksumtype, first the tag, then the value 221 buffer.put( ( byte ) 0xA1 ); 222 buffer.put( TLV.getBytes( paDataTypeTagLength ) ); 223 Value.encode( buffer, paDataType.getOrdinal() ); 224 225 // The checksum, first the tag, then the value 226 buffer.put( ( byte ) 0xA2 ); 227 buffer.put( TLV.getBytes( paDataValueTagLength ) ); 228 Value.encode( buffer, paDataValue ); 229 } 230 catch ( BufferOverflowException boe ) 231 { 232 log.error( I18n.err( I18n.ERR_145, 1 + TLV.getNbBytes( preAuthenticationDataSeqLength ) 233 + preAuthenticationDataSeqLength, buffer.capacity() ) ); 234 throw new EncoderException( I18n.err( I18n.ERR_138 ) ); 235 } 236 237 if ( IS_DEBUG ) 238 { 239 log.debug( "PreAuthenticationData encoding : {}", StringTools.dumpBytes( buffer.array() ) ); 240 log.debug( "PreAuthenticationData initial value : {}", toString() ); 241 } 242 243 return buffer; 244 } 245 246 /** 247 * @see Object#toString() 248 */ 249 public String toString() 250 { 251 return toString( "" ); 252 } 253 254 255 /** 256 * @see Object#toString() 257 */ 258 public String toString( String tabs ) 259 { 260 StringBuilder sb = new StringBuilder(); 261 262 sb.append( tabs ).append( "PreAuthenticationData : {\n" ); 263 sb.append( tabs ).append( " padata-type: " ).append( paDataType ).append( '\n' ); 264 265 if ( paDataValue != null ) 266 { 267 sb.append( tabs + " padata-value:" ).append( StringTools.dumpBytes( paDataValue ) ).append( '\n' ); 268 } 269 270 sb.append( tabs + "}\n" ); 271 272 return sb.toString(); 273 } 274 }