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.apache.directory.shared.kerberos.flags.TicketFlags; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039 040/** 041 * Base class for encrypted parts of KDC responses. 042 * 043 * The ASN.1 grammar for this structure is : 044 * <pre> 045 * EncKDCRepPart ::= SEQUENCE { 046 * key [0] EncryptionKey, 047 * last-req [1] LastReq, 048 * nonce [2] UInt32, 049 * key-expiration [3] KerberosTime OPTIONAL, 050 * flags [4] TicketFlags, 051 * authtime [5] KerberosTime, 052 * starttime [6] KerberosTime OPTIONAL, 053 * endtime [7] KerberosTime, 054 * renew-till [8] KerberosTime OPTIONAL, 055 * srealm [9] Realm, 056 * sname [10] PrincipalName, 057 * caddr [11] HostAddresses OPTIONAL 058 * } 059 * </pre> 060 * 061 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 062 */ 063public class EncKdcRepPart implements Asn1Object 064{ 065 /** The logger */ 066 private static final Logger log = LoggerFactory.getLogger( EncKdcRepPart.class ); 067 068 /** Speedup for logs */ 069 private static final boolean IS_DEBUG = log.isDebugEnabled(); 070 071 /** The encryption key */ 072 private EncryptionKey key; 073 074 /** The time of the last request */ 075 private LastReq lastReq; 076 077 /** The nonce */ 078 private int nonce; 079 080 /** The KeyExpiration */ 081 private KerberosTime keyExpiration; //optional 082 083 /** The Ticket flags */ 084 private TicketFlags flags = new TicketFlags(); 085 086 /** The initial Authentication time */ 087 private KerberosTime authTime; 088 089 /** The ticket's start time */ 090 private KerberosTime startTime; //optional 091 092 /** The Ticket expiration time */ 093 private KerberosTime endTime; 094 095 /** Maximum endtime in a renewal */ 096 private KerberosTime renewTill; //optional 097 098 /** The server's realm */ 099 private String srealm; 100 101 /** The server's principal */ 102 private PrincipalName sname; 103 104 /** The client addresses */ 105 private HostAddresses caddr; //optional 106 107 // Storage for computed lengths 108 private int keyLength; 109 private int lastReqLength; 110 private int nonceLength; 111 private int flagsLength; 112 private byte[] srealmBytes; 113 private int srealmLength; 114 private int snameLength; 115 private int caddrLength; 116 private int encKdcRepPartSeqLength; 117 118 119 /** 120 * Creates a new instance of EncKdcRepPart. 121 */ 122 public EncKdcRepPart() 123 { 124 } 125 126 127 /** 128 * Returns the auth {@link KerberosTime}. 129 * 130 * @return The auth {@link KerberosTime}. 131 */ 132 public KerberosTime getAuthTime() 133 { 134 return authTime; 135 } 136 137 138 /** 139 * Sets the auth {@link KerberosTime}. 140 * 141 * @param time 142 */ 143 public void setAuthTime( KerberosTime time ) 144 { 145 authTime = time; 146 } 147 148 149 /** 150 * Returns the client {@link HostAddresses}. 151 * 152 * @return The client {@link HostAddresses}. 153 */ 154 public HostAddresses getClientAddresses() 155 { 156 return caddr; 157 } 158 159 160 /** 161 * Sets the client {@link HostAddresses}. 162 * 163 * @param caddr The client addresses 164 */ 165 public void setClientAddresses( HostAddresses caddr ) 166 { 167 this.caddr = caddr; 168 } 169 170 171 /** 172 * Returns the end {@link KerberosTime}. 173 * 174 * @return The end {@link KerberosTime}. 175 */ 176 public KerberosTime getEndTime() 177 { 178 return endTime; 179 } 180 181 182 /** 183 * Sets the end {@link KerberosTime}. 184 * 185 * @param time 186 */ 187 public void setEndTime( KerberosTime time ) 188 { 189 endTime = time; 190 } 191 192 193 /** 194 * Returns the {@link TicketFlags}. 195 * 196 * @return The {@link TicketFlags}. 197 */ 198 public TicketFlags getFlags() 199 { 200 return flags; 201 } 202 203 204 /** 205 * Sets the {@link TicketFlags}. 206 * 207 * @param flags 208 */ 209 public void setFlags( TicketFlags flags ) 210 { 211 this.flags = flags; 212 } 213 214 215 /** 216 * Returns the {@link EncryptionKey}. 217 * 218 * @return The {@link EncryptionKey}. 219 */ 220 public EncryptionKey getKey() 221 { 222 return key; 223 } 224 225 226 /** 227 * Sets the {@link EncryptionKey}. 228 * 229 * @param key 230 */ 231 public void setKey( EncryptionKey key ) 232 { 233 this.key = key; 234 } 235 236 237 /** 238 * Returns the key expiration {@link KerberosTime}. 239 * 240 * @return The key expiration {@link KerberosTime}. 241 */ 242 public KerberosTime getKeyExpiration() 243 { 244 return keyExpiration; 245 } 246 247 248 /** 249 * Sets the key expiration {@link KerberosTime}. 250 * 251 * @param expiration 252 */ 253 public void setKeyExpiration( KerberosTime expiration ) 254 { 255 keyExpiration = expiration; 256 } 257 258 259 /** 260 * Returns the {@link LastReq}. 261 * 262 * @return The {@link LastReq}. 263 */ 264 public LastReq getLastReq() 265 { 266 return lastReq; 267 } 268 269 270 /** 271 * Sets the {@link LastReq}. 272 * 273 * @param lastReq The LastReq to set 274 */ 275 public void setLastReq( LastReq lastReq ) 276 { 277 this.lastReq = lastReq; 278 } 279 280 281 /** 282 * Returns the nonce. 283 * 284 * @return The nonce. 285 */ 286 public int getNonce() 287 { 288 return nonce; 289 } 290 291 292 /** 293 * Sets the nonce. 294 * 295 * @param nonce 296 */ 297 public void setNonce( int nonce ) 298 { 299 this.nonce = nonce; 300 } 301 302 303 /** 304 * Returns the renew till {@link KerberosTime}. 305 * 306 * @return The renew till {@link KerberosTime}. 307 */ 308 public KerberosTime getRenewTill() 309 { 310 return renewTill; 311 } 312 313 314 /** 315 * Sets the renew till {@link KerberosTime}. 316 * 317 * @param till 318 */ 319 public void setRenewTill( KerberosTime till ) 320 { 321 renewTill = till; 322 } 323 324 325 /** 326 * Returns the server {@link PrincipalName}. 327 * 328 * @return The server {@link PrincipalName}. 329 */ 330 public PrincipalName getSName() 331 { 332 return sname; 333 } 334 335 336 /** 337 * Sets the server {@link PrincipalName}. 338 * 339 * @param sname The server PrincipalName 340 */ 341 public void setSName( PrincipalName sname ) 342 { 343 this.sname = sname; 344 } 345 346 347 /** 348 * Returns the server realm. 349 * 350 * @return The server realm. 351 */ 352 public String getSRealm() 353 { 354 return srealm; 355 } 356 357 358 /** 359 * Sets the server realm. 360 * 361 * @param srealm The server realm 362 */ 363 public void setSRealm( String srealm ) 364 { 365 this.srealm = srealm; 366 } 367 368 369 /** 370 * Returns the start {@link KerberosTime}. 371 * 372 * @return The start {@link KerberosTime}. 373 */ 374 public KerberosTime getStartTime() 375 { 376 return startTime; 377 } 378 379 380 /** 381 * Sets the start {@link KerberosTime}. 382 * 383 * @param time he start time to set 384 */ 385 public void setStartTime( KerberosTime time ) 386 { 387 startTime = time; 388 } 389 390 391 /** 392 * Compute the EncKdcRepPart length 393 * <pre> 394 * EncKdcRepPart : 395 * 396 * 0x30 L1 EncKdcRepPart sequence 397 * | 398 * +--> 0xA0 L2 key tag 399 * | | 400 * | +--> 0x30 L2-1 key ( EncryptionKey) 401 * | 402 * +--> 0xA1 L3 last-req tag 403 * | | 404 * | +--> 0x30 L3-1 last-req ( LastReq ) 405 * | 406 * +--> 0xA2 L4 nonce tag 407 * | | 408 * | +--> 0x02 L4-1 nonce (Int) 409 * | 410 * [+--> 0xA3 0x11 key-expiration tag] 411 * | | 412 * | +--> 0x18 0x0F key-expiration ( KerberosTime ) 413 * | 414 * +--> 0xA4 0x07 flags tag 415 * | | 416 * | +--> 0x03 0x05 flags ( TicketFlags ) 417 * | 418 * +--> 0xA5 0x11 authtime tag 419 * | | 420 * | +--> 0x18 0x0F authtime ( KerberosTime ) 421 * | 422 * [+--> 0xA6 0x11 starttime tag] 423 * | | 424 * | +--> 0x18 0x0F starttime ( KerberosTime ) 425 * | 426 * +--> 0xA7 0x11 endtime tag 427 * | | 428 * | +--> 0x18 0x0F endtime ( KerberosTime ) 429 * | 430 * [+--> 0xA8 0x11 renew-till tag] 431 * | | 432 * | +--> 0x18 0x0F renew-till ( KerberosTime ) 433 * | 434 * +--> 0xA9 L5 srealm tag 435 * | | 436 * | +--> 0x1B L5-1 srealm ( KerberosString ) 437 * | 438 * +--> 0xAA L6 sname tag 439 * | | 440 * | +--> 0x30 L6-1 sname ( PrincipalName ) 441 * | 442 * [+--> 0xAB L7 caddr tag] 443 * | 444 * +--> 0x30 L7-1 caddr ( HostAddresses ) 445 * </pre> 446 */ 447 public int computeLength() 448 { 449 // The key 450 keyLength = key.computeLength(); 451 encKdcRepPartSeqLength = 1 + TLV.getNbBytes( keyLength ) + keyLength; 452 453 // The last-req 454 lastReqLength = lastReq.computeLength(); 455 encKdcRepPartSeqLength += 1 + TLV.getNbBytes( lastReqLength ) + lastReqLength; 456 457 // The nonce 458 nonceLength = BerValue.getNbBytes( nonce ); 459 nonceLength = 1 + TLV.getNbBytes( nonceLength ) + nonceLength; 460 encKdcRepPartSeqLength += 1 + TLV.getNbBytes( nonceLength ) + nonceLength; 461 462 // The keyExpiration 463 if ( keyExpiration != null ) 464 { 465 encKdcRepPartSeqLength += 1 + 1 + 0x11; 466 } 467 468 // The flags 469 flagsLength = 1 + 1 + 5; 470 encKdcRepPartSeqLength += 1 + TLV.getNbBytes( flagsLength ) + flagsLength; 471 472 // The authtime 473 encKdcRepPartSeqLength += 1 + 1 + 0x11; 474 475 // The starttime, if any 476 if ( startTime != null ) 477 { 478 encKdcRepPartSeqLength += 1 + 1 + 0x11; 479 } 480 481 // The endtime 482 encKdcRepPartSeqLength += 1 + 1 + 0x11; 483 484 // The renew-till, if any 485 if ( renewTill != null ) 486 { 487 encKdcRepPartSeqLength += 1 + 1 + 0x11; 488 } 489 490 // The srealm 491 srealmBytes = Strings.getBytesUtf8( srealm ); 492 srealmLength = 1 + TLV.getNbBytes( srealmBytes.length ) + srealmBytes.length; 493 encKdcRepPartSeqLength += 1 + TLV.getNbBytes( srealmLength ) + srealmLength; 494 495 // The sname 496 snameLength = sname.computeLength(); 497 encKdcRepPartSeqLength += 1 + TLV.getNbBytes( snameLength ) + snameLength; 498 499 // The caddr if any 500 if ( caddr != null ) 501 { 502 caddrLength = caddr.computeLength(); 503 encKdcRepPartSeqLength += 1 + TLV.getNbBytes( caddrLength ) + caddrLength; 504 } 505 506 return 1 + TLV.getNbBytes( encKdcRepPartSeqLength ) + encKdcRepPartSeqLength; 507 } 508 509 510 /** 511 * Encode the EncKdcRepPart message to a PDU. 512 * 513 * @param buffer The buffer where to put the PDU. It should have been allocated 514 * before, with the right size. 515 * @return The constructed PDU. 516 */ 517 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 518 { 519 if ( buffer == null ) 520 { 521 throw new EncoderException( I18n.err( I18n.ERR_148 ) ); 522 } 523 524 try 525 { 526 // The EncKdcRepPart sequence 527 buffer.put( UniversalTag.SEQUENCE.getValue() ); 528 buffer.put( TLV.getBytes( encKdcRepPartSeqLength ) ); 529 530 // The Key 531 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_KEY_TAG ); 532 buffer.put( TLV.getBytes( keyLength ) ); 533 key.encode( buffer ); 534 535 // The LastReq 536 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_LAST_REQ_TAG ); 537 buffer.put( TLV.getBytes( lastReqLength ) ); 538 lastReq.encode( buffer ); 539 540 // The nonce 541 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_NONCE_TAG ); 542 buffer.put( TLV.getBytes( nonceLength ) ); 543 BerValue.encode( buffer, nonce ); 544 545 // The key-expiration, if any 546 if ( keyExpiration != null ) 547 { 548 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_KEY_EXPIRATION_TAG ); 549 buffer.put( TLV.getBytes( 0x11 ) ); 550 551 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 552 buffer.put( ( byte ) 0x0F ); 553 buffer.put( keyExpiration.getBytes() ); 554 } 555 556 // The flags 557 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_FLAGS_TAG ); 558 buffer.put( TLV.getBytes( 0x07 ) ); 559 BerValue.encode( buffer, flags ); 560 561 // The authtime 562 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_AUTH_TIME_TAG ); 563 buffer.put( TLV.getBytes( 0x11 ) ); 564 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 565 buffer.put( ( byte ) 0x0F ); 566 buffer.put( authTime.getBytes() ); 567 568 // The starttime if any 569 if ( startTime != null ) 570 { 571 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_START_TIME_TAG ); 572 buffer.put( TLV.getBytes( 0x11 ) ); 573 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 574 buffer.put( ( byte ) 0x0F ); 575 buffer.put( startTime.getBytes() ); 576 } 577 578 // The endtime 579 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_END_TIME_TAG ); 580 buffer.put( TLV.getBytes( 0x11 ) ); 581 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 582 buffer.put( ( byte ) 0x0F ); 583 buffer.put( endTime.getBytes() ); 584 585 // The renew-till if any 586 if ( renewTill != null ) 587 { 588 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_RENEW_TILL_TAG ); 589 buffer.put( TLV.getBytes( 0x11 ) ); 590 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 591 buffer.put( ( byte ) 0x0F ); 592 buffer.put( renewTill.getBytes() ); 593 } 594 595 // The srealm 596 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_SREALM_TAG ); 597 buffer.put( TLV.getBytes( srealmLength ) ); 598 buffer.put( UniversalTag.GENERAL_STRING.getValue() ); 599 buffer.put( TLV.getBytes( srealmBytes.length ) ); 600 buffer.put( srealmBytes ); 601 602 // The sname 603 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_SNAME_TAG ); 604 buffer.put( TLV.getBytes( snameLength ) ); 605 sname.encode( buffer ); 606 607 // The caddr if any 608 if ( caddr != null ) 609 { 610 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_CADDR_TAG ); 611 buffer.put( TLV.getBytes( caddrLength ) ); 612 caddr.encode( buffer ); 613 } 614 } 615 catch ( BufferOverflowException boe ) 616 { 617 log.error( I18n.err( I18n.ERR_140, 1 + TLV.getNbBytes( 0 ) + 0, 618 buffer.capacity() ) ); 619 throw new EncoderException( I18n.err( I18n.ERR_138 ), boe ); 620 } 621 622 if ( IS_DEBUG ) 623 { 624 log.debug( "EncKdcRepPart encoding : {}", Strings.dumpBytes( buffer.array() ) ); 625 log.debug( "EncKdcRepPart initial value : {}", this ); 626 } 627 628 return buffer; 629 } 630 631 632 /** 633 * @see Object#toString() 634 */ 635 public String toString() 636 { 637 StringBuilder sb = new StringBuilder(); 638 639 sb.append( "EncKdcRepPart : \n" ); 640 sb.append( " key : " ).append( key ).append( "\n" ); 641 sb.append( " last-req : " ).append( lastReq ).append( "\n" ); 642 sb.append( " nonce : " ).append( nonce ).append( "\n" ); 643 644 if ( keyExpiration != null ) 645 { 646 sb.append( " key-expiration : " ).append( keyExpiration ).append( "\n" ); 647 } 648 649 sb.append( " flags : " ).append( flags ).append( "\n" ); 650 sb.append( " authtime : " ).append( authTime ).append( "\n" ); 651 652 if ( startTime != null ) 653 { 654 sb.append( " starttime : " ).append( startTime ).append( "\n" ); 655 } 656 657 sb.append( " endtime : " ).append( endTime ).append( "\n" ); 658 659 if ( renewTill != null ) 660 { 661 sb.append( " renew-till : " ).append( renewTill ).append( "\n" ); 662 } 663 664 sb.append( " srealm : " ).append( srealm ).append( "\n" ); 665 sb.append( " sname : " ).append( sname ).append( "\n" ); 666 667 if ( caddr != null ) 668 { 669 sb.append( " caddr : " ).append( caddr ).append( "\n" ); 670 } 671 672 return sb.toString(); 673 } 674}