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.components; 021 022 023import java.nio.BufferOverflowException; 024import java.nio.ByteBuffer; 025 026import org.apache.directory.api.asn1.Asn1Object; 027import org.apache.directory.api.asn1.EncoderException; 028import org.apache.directory.api.asn1.ber.tlv.BerValue; 029import org.apache.directory.api.asn1.ber.tlv.TLV; 030import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 031import org.apache.directory.api.util.Strings; 032import org.apache.directory.server.i18n.I18n; 033import org.apache.directory.shared.kerberos.KerberosConstants; 034import org.apache.directory.shared.kerberos.KerberosTime; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038 039/** 040 * The PaEncTsEnc structure is used to store a PA-ENC-TS-ENC associated to a type. 041 * 042 * The ASN.1 grammar is : 043 * <pre> 044 * PA-ENC-TS-ENC ::= SEQUENCE { 045 * patimestamp [0] KerberosTime -- client's time --, 046 * pausec [1] Microseconds OPTIONAL 047 * } 048 * </pre> 049 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 050 */ 051public class PaEncTsEnc implements Asn1Object 052{ 053 /** The logger */ 054 private static final Logger log = LoggerFactory.getLogger( PaEncTsEnc.class ); 055 056 /** Speedup for logs */ 057 private static final boolean IS_DEBUG = log.isDebugEnabled(); 058 059 /** The patimestamp */ 060 private KerberosTime patimestamp; 061 062 /** The pausec */ 063 private Integer pausec; 064 065 // Storage for computed lengths 066 private int paTimestampLength; 067 private int paUsecLength; 068 private int paEncTsEncLength; 069 070 071 /** 072 * Creates a new instance of PaEncTsEnc. 073 */ 074 public PaEncTsEnc() 075 { 076 } 077 078 079 /** 080 * Creates a new instance of PaEncTsEnc. 081 */ 082 public PaEncTsEnc( KerberosTime paTimestamp, int pausec ) 083 { 084 this.patimestamp = paTimestamp; 085 this.pausec = pausec; 086 } 087 088 089 /** 090 * Returns the patimestamp value. 091 * 092 * @return The patimestamp value. 093 */ 094 public KerberosTime getPaTimestamp() 095 { 096 return patimestamp; 097 } 098 099 100 /** 101 * Set the patimestamp. 102 * 103 * @param patimestamp The patimestamp value 104 */ 105 public void setPaTimestamp( KerberosTime patimestamp ) 106 { 107 this.patimestamp = patimestamp; 108 } 109 110 111 /** 112 * @return the pausec 113 */ 114 public int getPausec() 115 { 116 if ( pausec == null ) 117 { 118 return -1; 119 } 120 121 return pausec; 122 } 123 124 125 /** 126 * @param pausec the pausec to set 127 */ 128 public void setPausec( int pausec ) 129 { 130 this.pausec = pausec; 131 } 132 133 134 /** 135 * Compute the PA-ENC-TS-ENC length 136 * <pre> 137 * PA-ENC-TS-ENC : 138 * 139 * 0x30 L1 PA-ENC-TS-ENC sequence 140 * | 141 * +--> 0xA0 0x11 patimestamp tag 142 * | | 143 * | +--> 0x18 0x0F patimestamp value (KerberosTime) 144 * | 145 * +--> 0xA1 L2 pausec tag 146 * | 147 * +--> 0x02 L2-1 pausec (INTEGER) 148 * 149 * </pre> 150 */ 151 public int computeLength() 152 { 153 // The paTimestamp 154 paTimestampLength = 0x11; 155 156 paEncTsEncLength = 1 + TLV.getNbBytes( paTimestampLength ) + paTimestampLength; 157 158 // The pausec, if any 159 if ( pausec != null ) 160 { 161 int pausecLength = BerValue.getNbBytes( pausec ); 162 paUsecLength = 1 + TLV.getNbBytes( pausecLength ) + pausecLength; 163 paEncTsEncLength += 1 + TLV.getNbBytes( paUsecLength ) + paUsecLength; 164 } 165 166 // Compute the whole sequence length 167 return 1 + TLV.getNbBytes( paEncTsEncLength ) + paEncTsEncLength; 168 } 169 170 171 /** 172 * Encode the PA-ENC-TS-ENC message to a PDU. 173 * 174 * <pre> 175 * PA-ENC-TS-ENC : 176 * 177 * 0x30 LL 178 * 0xA0 0x11 179 * 0x18 0x0F patimestamp 180 * [0xA1 LL 181 * 0x02 LL pausec] 182 * </pre> 183 * @param buffer The buffer where to put the PDU. It should have been allocated 184 * before, with the right size. 185 * @return The constructed PDU. 186 */ 187 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 188 { 189 if ( buffer == null ) 190 { 191 throw new EncoderException( I18n.err( I18n.ERR_148 ) ); 192 } 193 194 try 195 { 196 // The PA-ENC-TS-ENC SEQ Tag 197 buffer.put( UniversalTag.SEQUENCE.getValue() ); 198 buffer.put( TLV.getBytes( paEncTsEncLength ) ); 199 200 // The patimestamp, first the tag, then the value 201 buffer.put( ( byte ) KerberosConstants.PA_ENC_TS_ENC_PA_TIMESTAMP_TAG ); 202 buffer.put( ( byte ) 0x11 ); 203 204 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 205 buffer.put( ( byte ) 0x0F ); 206 buffer.put( patimestamp.getBytes() ); 207 208 // The pausec, first the tag, then the value, if any 209 if ( pausec != null ) 210 { 211 buffer.put( ( byte ) KerberosConstants.PA_ENC_TS_ENC_PA_USEC_TAG ); 212 buffer.put( TLV.getBytes( paUsecLength ) ); 213 BerValue.encode( buffer, pausec ); 214 } 215 } 216 catch ( BufferOverflowException boe ) 217 { 218 log.error( I18n.err( I18n.ERR_140, 1 + TLV.getNbBytes( paEncTsEncLength ) + paEncTsEncLength, 219 buffer.capacity() ) ); 220 throw new EncoderException( I18n.err( I18n.ERR_138 ), boe ); 221 } 222 223 if ( IS_DEBUG ) 224 { 225 log.debug( "Checksum encoding : {}", Strings.dumpBytes( buffer.array() ) ); 226 log.debug( "Checksum initial value : {}", this ); 227 } 228 229 return buffer; 230 } 231 232 233 /** 234 * @see Object#toString() 235 */ 236 public String toString() 237 { 238 return toString( "" ); 239 } 240 241 242 /** 243 * @see Object#toString() 244 */ 245 public String toString( String tabs ) 246 { 247 StringBuilder sb = new StringBuilder(); 248 249 sb.append( tabs ).append( "PA-ENC-TS-ENC : {\n" ); 250 sb.append( tabs ).append( " patimestamp : " ).append( patimestamp ).append( '\n' ); 251 252 if ( pausec != null ) 253 { 254 sb.append( tabs + " pausec :" ).append( pausec ).append( '\n' ); 255 } 256 257 sb.append( tabs + "}\n" ); 258 259 return sb.toString(); 260 } 261}