1 /* KerberosTicket.java -- a kerberos ticket
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.security.auth.kerberos;
41 import gnu.classpath.NotImplementedException;
43 import java.io.Serializable;
44 import java.net.InetAddress;
45 import java.util.Date;
47 import javax.crypto.SecretKey;
48 import javax.security.auth.DestroyFailedException;
49 import javax.security.auth.Destroyable;
50 import javax.security.auth.RefreshFailedException;
51 import javax.security.auth.Refreshable;
54 * This class represents a Kerberos ticket. See the Kerberos
55 * authentication RFC for more information:
56 * <a href="http://www.ietf.org/rfc/rfc1510.txt">RFC 1510</a>.
60 public class KerberosTicket
61 implements Destroyable, Serializable, Refreshable
63 private static final long serialVersionUID = 7395334370157380539L;
65 // Indices of the various flags. From the kerberos spec.
66 // We only list the ones we use.
67 private static final int FORWARDABLE = 1;
68 private static final int FORWARDED = 2;
69 private static final int PROXIABLE = 3;
70 private static final int PROXY = 4;
71 private static final int POSTDATED = 6;
72 private static final int RENEWABLE = 8;
73 private static final int INITIAL = 9;
74 private static final int NUM_FLAGS = 12;
76 private byte[] asn1Encoding;
77 private KeyImpl sessionKey;
78 private boolean[] flags;
79 private Date authTime;
80 private Date startTime;
82 private Date renewTill;
83 private KerberosPrincipal client;
84 private KerberosPrincipal server;
85 private InetAddress[] clientAddresses;
88 * Create a new ticket given all the facts about it.
90 * Note that flags may be null or "short"; any flags not specified
91 * will be taken to be false.
93 * If the key is not renewable, then renewTill may be null.
95 * If authTime is null, then it is taken to be the same as startTime.
97 * If clientAddresses is null, then the ticket can be used anywhere.
99 * @param asn1Encoding the contents of the ticket, as ASN1
100 * @param client the client principal
101 * @param server the server principal
102 * @param key the contents of the session key
103 * @param type the type of the key
104 * @param flags an array of flags, as specified by the RFC
105 * @param authTime when the client was authenticated
106 * @param startTime starting time at which the ticket is valid
107 * @param endTime ending time, after which the ticket is invalid
108 * @param renewTill for a rewewable ticket, the time before which it must
110 * @param clientAddresses a possibly-null array of addresses where this
113 public KerberosTicket(byte[] asn1Encoding, KerberosPrincipal client,
114 KerberosPrincipal server, byte[] key, int type,
115 boolean[] flags, Date authTime, Date startTime,
116 Date endTime, Date renewTill,
117 InetAddress[] clientAddresses)
119 this.asn1Encoding = (byte[]) asn1Encoding.clone();
120 this.sessionKey = new KeyImpl(key, type);
121 this.flags = new boolean[NUM_FLAGS];
123 System.arraycopy(flags, 0, this.flags, 0,
124 Math.min(flags.length, NUM_FLAGS));
125 this.flags = (boolean[]) flags.clone();
126 this.authTime = (Date) authTime.clone();
127 this.startTime = (Date) ((startTime == null)
128 ? authTime : startTime).clone();
129 this.endTime = (Date) endTime.clone();
130 this.renewTill = (Date) renewTill.clone();
131 this.client = client;
132 this.server = server;
133 this.clientAddresses = (clientAddresses == null
135 : (InetAddress[]) clientAddresses.clone());
139 * Destroy this ticket. This discards secret information. After this
140 * method is called, other methods will throw IllegalStateException.
142 public void destroy() throws DestroyFailedException
144 if (sessionKey == null)
145 throw new DestroyFailedException("already destroyed");
151 * Return true if this ticket has been destroyed.
153 public boolean isDestroyed()
155 return sessionKey == null;
159 * Return true if the ticket is currently valid. This is true if
160 * the system time is between the ticket's start and end times.
162 public boolean isCurrent()
164 long now = System.currentTimeMillis();
165 return startTime.getTime() <= now && now <= endTime.getTime();
169 * If the ticket is renewable, and the renewal time has not yet elapsed,
170 * attempt to renew the ticket.
171 * @throws RefreshFailedException if the renewal fails for any reason
173 public void refresh() throws RefreshFailedException, NotImplementedException
176 throw new RefreshFailedException("not renewable");
177 if (renewTill != null
178 && System.currentTimeMillis() >= renewTill.getTime())
179 throw new RefreshFailedException("renewal time elapsed");
180 // FIXME: must contact the KDC.
181 // Use the java.security.krb5.kdc property...
182 throw new RefreshFailedException("not implemented");
186 * Return the client principal for this ticket.
188 public final KerberosPrincipal getClient()
194 * Return the server principal for this ticket.
196 public final KerberosPrincipal getServer()
202 * Return true if this ticket is forwardable.
204 public final boolean isForwardable()
206 return flags[FORWARDABLE];
210 * Return true if this ticket has been forwarded.
212 public final boolean isForwarded()
214 return flags[FORWARDED];
218 * Return true if this ticket is proxiable.
220 public final boolean isProxiable()
222 return flags[PROXIABLE];
226 * Return true if this ticket is a proxy ticket.
228 public final boolean isProxy()
234 * Return true if this ticket was post-dated.
236 public final boolean isPostdated()
238 return flags[POSTDATED];
242 * Return true if this ticket is renewable.
244 public final boolean isRenewable()
246 return flags[RENEWABLE];
250 * Return true if this ticket was granted by an application
251 * server, and not via a ticket-granting ticket.
253 public final boolean isInitial()
255 return flags[INITIAL];
259 * Return the flags for this ticket as a boolean array.
260 * See the RFC to understand what the different entries mean.
262 public final boolean[] getFlags()
264 return (boolean[]) flags.clone();
268 * Return the authentication time for this ticket.
270 public final Date getAuthTime()
272 return (Date) authTime.clone();
276 * Return the start time for this ticket.
278 public final Date getStartTime()
280 return (Date) startTime.clone();
284 * Return the end time for this ticket.
286 public final Date getEndTime()
288 return (Date) endTime.clone();
292 * Return the renewal time for this ticket. For a non-renewable
293 * ticket, this will return null.
295 public final Date getRenewTill()
297 return flags[RENEWABLE] ? ((Date) renewTill.clone()) : null;
301 * Return the allowable client addresses for this ticket. This will
302 * return null if the ticket can be used anywhere.
304 public final InetAddress[] getClientAddresses()
306 return (clientAddresses == null
308 : (InetAddress[]) clientAddresses.clone());
312 * Return the encoded form of this ticket.
314 public final byte[] getEncoded()
317 return (byte[]) sessionKey.key.clone();
321 * Return the secret key associated with this ticket.
323 public final SecretKey getSessionKey()
329 private void checkDestroyed()
331 if (sessionKey == null)
332 throw new IllegalStateException("key is destroyed");
335 public String toString()
337 return getClass().getName() +
338 "[client=" + client +
339 ",server=" + server +
340 ",sessionKey=" + sessionKey +
342 ",authTime=" + authTime +
343 ",startTime= " + startTime +
344 ",endTime=" + endTime +
345 ",renewTill=" + renewTill +
346 ",clientAddresses=" + clientAddresses +
352 * Returns the type of the session key in accordance with
353 * RFC1510. This usually corresponds to the encryption
354 * algorithm used by the key, though more than one algorithm
355 * may use the same key type (e.g. DES with different checksum
356 * mechanisms and chaining modes). Negative values are reserved
357 * for local use. Non-negative values are for officially assigned
358 * type fields. The RFC defines:
361 * <li>0 — null</li>
362 * <li>1 — DES (in CBC mode with either MD4 or MD5 checksums)</li>
365 * @return the type of session key used by this ticket.
367 public final int getSessionKeyType()
369 return sessionKey.type;