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.server.kerberos.shared.store; 021 022 023import java.text.ParseException; 024 025import javax.security.auth.kerberos.KerberosKey; 026import javax.security.auth.kerberos.KerberosPrincipal; 027 028import org.apache.directory.server.kerberos.shared.crypto.encryption.CipherTextHandler; 029import org.apache.directory.server.kerberos.shared.crypto.encryption.KeyUsage; 030import org.apache.directory.server.kerberos.shared.crypto.encryption.RandomKeyFactory; 031import org.apache.directory.shared.kerberos.KerberosConstants; 032import org.apache.directory.shared.kerberos.KerberosTime; 033import org.apache.directory.shared.kerberos.codec.types.EncryptionType; 034import org.apache.directory.shared.kerberos.codec.types.PrincipalNameType; 035import org.apache.directory.shared.kerberos.components.EncTicketPart; 036import org.apache.directory.shared.kerberos.components.EncryptedData; 037import org.apache.directory.shared.kerberos.components.EncryptionKey; 038import org.apache.directory.shared.kerberos.components.PrincipalName; 039import org.apache.directory.shared.kerberos.components.TransitedEncoding; 040import org.apache.directory.shared.kerberos.exceptions.KerberosException; 041import org.apache.directory.shared.kerberos.flags.TicketFlag; 042import org.apache.directory.shared.kerberos.flags.TicketFlags; 043import org.apache.directory.shared.kerberos.messages.Ticket; 044 045 046/** 047 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 048 */ 049public class TicketFactory 050{ 051 /** One day in milliseconds, used for default end time. */ 052 private static final int ONE_DAY = 86400000; 053 054 /** One week in milliseconds, used for default renewal period. */ 055 private static final int ONE_WEEK = 86400000 * 7; 056 057 private CipherTextHandler cipherTextHandler = new CipherTextHandler(); 058 059 060 /** 061 * Returns a server key derived from a server principal and server password. 062 * 063 * @param serverPrincipal 064 * @param serverPassword 065 * @return The server's {@link EncryptionKey}. 066 */ 067 public EncryptionKey getServerKey( KerberosPrincipal serverPrincipal, String serverPassword ) 068 { 069 KerberosKey serverKerberosKey = new KerberosKey( serverPrincipal, serverPassword.toCharArray(), "DES" ); 070 byte[] serverKeyBytes = serverKerberosKey.getEncoded(); 071 072 return new EncryptionKey( EncryptionType.DES_CBC_MD5, serverKeyBytes ); 073 } 074 075 076 /** 077 * Build the service ticket. The service ticket contains the session key generated 078 * by the KDC for the client and service to use. The service will unlock the 079 * authenticator with the session key from the ticket. The principal in the ticket 080 * must equal the authenticator client principal. 081 * 082 * If set in the AP Options, the Ticket can also be sealed with the session key. 083 * 084 * @param clientPrincipal 085 * @param serverPrincipal 086 * @param serverKey 087 * @return The {@link Ticket}. 088 * @throws KerberosException 089 */ 090 public Ticket getTicket( KerberosPrincipal clientPrincipal, KerberosPrincipal serverPrincipal, 091 EncryptionKey serverKey ) throws KerberosException, ParseException 092 { 093 EncTicketPart encTicketPart = new EncTicketPart(); 094 095 TicketFlags ticketFlags = new TicketFlags(); 096 ticketFlags.setFlag( TicketFlag.RENEWABLE ); 097 encTicketPart.setFlags( ticketFlags ); 098 099 EncryptionKey sessionKey = RandomKeyFactory.getRandomKey( EncryptionType.DES_CBC_MD5 ); 100 101 encTicketPart.setKey( sessionKey ); 102 encTicketPart.setCName( new PrincipalName( clientPrincipal.getName(), PrincipalNameType.KRB_NT_PRINCIPAL ) ); 103 encTicketPart.setTransited( new TransitedEncoding() ); 104 encTicketPart.setAuthTime( new KerberosTime() ); 105 106 long now = System.currentTimeMillis(); 107 KerberosTime endTime = new KerberosTime( now + ONE_DAY ); 108 encTicketPart.setEndTime( endTime ); 109 110 KerberosTime renewTill = new KerberosTime( now + ONE_WEEK ); 111 encTicketPart.setRenewTill( renewTill ); 112 113 EncryptedData encryptedTicketPart = cipherTextHandler.seal( serverKey, encTicketPart, 114 KeyUsage.AS_OR_TGS_REP_TICKET_WITH_SRVKEY ); 115 116 Ticket ticket = new Ticket(); 117 ticket.setTktVno( KerberosConstants.KERBEROS_V5 ); 118 ticket.setSName( new PrincipalName( serverPrincipal.getName(), PrincipalNameType.KRB_NT_PRINCIPAL ) ); 119 ticket.setRealm( serverPrincipal.getRealm() ); 120 ticket.setEncPart( encryptedTicketPart ); 121 122 return ticket; 123 } 124}