8043071: Expose session key and KRB_CRED through extended GSS-API

Reviewed-by: mullan
This commit is contained in:
Weijun Wang 2014-07-19 10:20:42 +08:00
parent f697e160a1
commit bfa19ebfbc
12 changed files with 814 additions and 296 deletions

View File

@ -36,33 +36,7 @@ import org.ietf.jgss.*;
public interface ExtendedGSSContext extends GSSContext {
/**
* Return the mechanism-specific attribute associated with {@code type}.
* <br><br>
* For each supported attribute type, the type for the output are
* defined below.
* <ol>
* <li>{@code KRB5_GET_TKT_FLAGS}:
* the returned object is a boolean array for the service ticket flags,
* which is long enough to contain all true bits. This means if
* the user wants to get the <em>n</em>'th bit but the length of the
* returned array is less than <em>n</em>, it is regarded as false.
* <li>{@code KRB5_GET_SESSION_KEY}:
* the returned object is an instance of {@link java.security.Key},
* which has the following properties:
* <ul>
* <li>Algorithm: enctype as a string, where
* enctype is defined in RFC 3961, section 8.
* <li>Format: "RAW"
* <li>Encoded form: the raw key bytes, not in any ASN.1 encoding
* </ul>
* <li>{@code KRB5_GET_AUTHZ_DATA}:
* the returned object is an array of
* {@link com.sun.security.jgss.AuthorizationDataEntry}, or null if the
* optional field is missing in the service ticket.
* <li>{@code KRB5_GET_AUTHTIME}:
* the returned object is a String object in the standard KerberosTime
* format defined in RFC 4120 5.2.3
* </ol>
*
* <p>
* If there is a security manager, an {@link InquireSecContextPermission}
* with the name {@code type.mech} must be granted. Otherwise, this could
* result in a {@link SecurityException}.<p>
@ -97,6 +71,7 @@ public interface ExtendedGSSContext extends GSSContext {
* @throws SecurityException if a security manager exists and a proper
* {@link InquireSecContextPermission} is not granted.
* @see InquireSecContextPermission
* @see InquireType
*/
public Object inquireSecContext(InquireType type)
throws GSSException;

View File

@ -32,13 +32,38 @@ package com.sun.security.jgss;
@jdk.Exported
public enum InquireType {
/**
* Attribute type for retrieving the session key of an
* established Kerberos 5 security context.
* Attribute type for retrieving the session key of an established
* Kerberos 5 security context. The returned object is an instance of
* {@link java.security.Key}, which has the following properties:
* <ul>
* <li>Algorithm: enctype as a string, where
* enctype is defined in RFC 3961, section 8.
* <li>Format: "RAW"
* <li>Encoded form: the raw key bytes, not in any ASN.1 encoding
* </ul>
* @deprecated as of 1.9, replaced by {@link #KRB5_GET_SESSION_KEY_EX}
* which returns an instance of
* {@link sun.security.jgss.krb5.Krb5Context.EncryptionKey}
* that implements the {@link javax.crypto.SecretKey} interface and
* has similar methods with {@link javax.security.auth.kerberos.KerberosKey}.
*/
@Deprecated
KRB5_GET_SESSION_KEY,
/**
* Attribute type for retrieving the session key of an
* established Kerberos 5 security context. The return value is an
* instance of {@link javax.security.auth.kerberos.EncryptionKey}.
*
* @since 1.9
*/
KRB5_GET_SESSION_KEY_EX,
/**
* Attribute type for retrieving the service ticket flags of an
* established Kerberos 5 security context.
* established Kerberos 5 security context. The returned object is
* a boolean array for the service ticket flags, which is long enough
* to contain all true bits. This means if the user wants to get the
* <em>n</em>'th bit but the length of the returned array is less than
* <em>n</em>, it is regarded as false.
*/
KRB5_GET_TKT_FLAGS,
/**
@ -49,7 +74,17 @@ public enum InquireType {
KRB5_GET_AUTHZ_DATA,
/**
* Attribute type for retrieving the authtime in the service ticket
* of an established Kerberos 5 security context.
* of an established Kerberos 5 security context. The returned object
* is a String object in the standard KerberosTime format defined in
* RFC 4120 Section 5.2.3.
*/
KRB5_GET_AUTHTIME
KRB5_GET_AUTHTIME,
/**
* Attribute type for retrieving the KRB_CRED message that an initiator
* is about to send to an acceptor. The return type is an instance of
* {@link javax.security.auth.kerberos.KerberosCredMessage}.
*
* @since 1.9
*/
KRB5_GET_KRB_CRED,
}

View File

@ -0,0 +1,208 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.security.auth.kerberos;
import java.util.Arrays;
import java.util.Objects;
import javax.crypto.SecretKey;
import javax.security.auth.DestroyFailedException;
/**
* This class encapsulates an EncryptionKey used in Kerberos.<p>
*
* An EncryptionKey is defined in Section 4.2.9 of the Kerberos Protocol
* Specification (<a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>) as:
* <pre>
* EncryptionKey ::= SEQUENCE {
* keytype [0] Int32 -- actually encryption type --,
* keyvalue [1] OCTET STRING
* }
* </pre>
* The key material of an {@code EncryptionKey} is defined as the value
* of the {@code keyValue} above.<p>
*
* @since 1.9
*/
public final class EncryptionKey implements SecretKey {
private static final long serialVersionUID = 9L;
/**
* {@code KeyImpl} is serialized by writing out the ASN.1 encoded bytes
* of the encryption key.
*
* @serial
*/
final private KeyImpl key;
private transient boolean destroyed = false;
/**
* Constructs a {@code EncryptionKey} from the given bytes and
* the key type.
* <p>
* The contents of the byte array are copied; subsequent modification of
* the byte array does not affect the newly created key.
*
* @param keyBytes the key material for the key
* @param keyType the key type for the key as defined by the
* Kerberos protocol specification.
* @throws NullPointerException if keyBytes is null
*/
public EncryptionKey(byte[] keyBytes, int keyType) {
key = new KeyImpl(Objects.requireNonNull(keyBytes), keyType);
}
/**
* Returns the key type for this key.
*
* @return the key type.
* @throws IllegalStateException if the key is destroyed
*/
public int getKeyType() {
// KeyImpl already checked if destroyed
return key.getKeyType();
}
/*
* Methods from java.security.Key
*/
/**
* Returns the standard algorithm name for this key. The algorithm names
* are the encryption type string defined on the IANA
* <a href="https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml#kerberos-parameters-1">Kerberos Encryption Type Numbers</a>
* page.
* <p>
* This method can return the following value not defined on the IANA page:
* <ol>
* <li>none: for etype equal to 0</li>
* <li>unknown: for etype greater than 0 but unsupported by
* the implementation</li>
* <li>private: for etype smaller than 0</li>
* </ol>
*
* @return the name of the algorithm associated with this key.
* @throws IllegalStateException if the key is destroyed
*/
@Override
public String getAlgorithm() {
// KeyImpl already checked if destroyed
return key.getAlgorithm();
}
/**
* Returns the name of the encoding format for this key.
*
* @return the String "RAW"
* @throws IllegalStateException if the key is destroyed
*/
@Override
public String getFormat() {
// KeyImpl already checked if destroyed
return key.getFormat();
}
/**
* Returns the key material of this key.
*
* @return a newly allocated byte array that contains the key material
* @throws IllegalStateException if the key is destroyed
*/
@Override
public byte[] getEncoded() {
// KeyImpl already checked if destroyed
return key.getEncoded();
}
/**
* Destroys this key by clearing out the key material of this key.
*
* @throws DestroyFailedException if some error occurs while destorying
* this key.
*/
@Override
public void destroy() throws DestroyFailedException {
if (!destroyed) {
key.destroy();
destroyed = true;
}
}
@Override
public boolean isDestroyed() {
return destroyed;
}
@Override
public String toString() {
if (destroyed) {
return "Destroyed EncryptionKey";
}
return "key " + key.toString();
}
@Override
public int hashCode() {
int result = 17;
if (isDestroyed()) {
return result;
}
result = 37 * result + Arrays.hashCode(getEncoded());
return 37 * result + getKeyType();
}
/**
* Compares the specified Object with this key for equality.
* Returns true if the given object is also a
* {@code EncryptionKey} and the two
* {@code EncryptionKey} instances are equivalent.
*
* @param other the Object to compare to
* @return true if the specified object is equal to this EncryptionKey,
* false otherwise. NOTE: Returns false if either of the EncryptionKey
* objects has been destroyed.
*/
@Override
public boolean equals(Object other) {
if (other == this)
return true;
if (! (other instanceof EncryptionKey)) {
return false;
}
EncryptionKey otherKey = ((EncryptionKey) other);
if (isDestroyed() || otherKey.isDestroyed()) {
return false;
}
return getKeyType() == otherKey.getKeyType()
&& Arrays.equals(getEncoded(), otherKey.getEncoded());
}
}

View File

@ -0,0 +1,171 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.security.auth.kerberos;
import javax.security.auth.Destroyable;
import java.util.Arrays;
import java.util.Base64;
import java.util.Objects;
/**
* This class encapsulates a Kerberos 5 KRB_CRED message which can be used to
* send Kerberos credentials from one principal to another.<p>
*
* A KRB_CRED message is defined in Section 5.8.1 of the Kerberos Protocol
* Specification (<a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>) as:
* <pre>
* KRB-CRED ::= [APPLICATION 22] SEQUENCE {
* pvno [0] INTEGER (5),
* msg-type [1] INTEGER (22),
* tickets [2] SEQUENCE OF Ticket,
* enc-part [3] EncryptedData -- EncKrbCredPart
* }
* </pre><p>
*
* @since 1.9
*/
public final class KerberosCredMessage implements Destroyable {
final private KerberosPrincipal sender;
final private KerberosPrincipal recipient;
final private byte[] message;
private boolean destroyed = false;
/**
* Constructs a {@code KerberosCredMessage} object.
* <p>
* The contents of the {@code message} argument are copied; subsequent
* modification of the byte array does not affect the newly created object.
*
* @param sender the sender of the message
* @param recipient the recipient of the message
* @param message the DER encoded KRB_CRED message
* @throws NullPointerException if any of sender, recipient
* or message is null
*/
public KerberosCredMessage(KerberosPrincipal sender,
KerberosPrincipal recipient,
byte[] message) {
this.sender = Objects.requireNonNull(sender);
this.recipient = Objects.requireNonNull(recipient);
this.message = Objects.requireNonNull(message).clone();
}
/**
* Returns the DER encoded form of the KRB_CRED message.
*
* @return a newly allocated byte array that contains the encoded form
* @throws IllegalStateException if the object is destroyed
*/
public byte[] getEncoded() {
if (destroyed) {
throw new IllegalStateException("This object is no longer valid");
}
return message.clone();
}
/**
* Returns the sender of this message.
*
* @return the sender
* @throws IllegalStateException if the object is destroyed
*/
public KerberosPrincipal getSender() {
if (destroyed) {
throw new IllegalStateException("This object is no longer valid");
}
return sender;
}
/**
* Returns the recipient of this message.
*
* @return the recipient
* @throws IllegalStateException if the object is destroyed
*/
public KerberosPrincipal getRecipient() {
if (destroyed) {
throw new IllegalStateException("This object is no longer valid");
}
return recipient;
}
/**
* Destroys this object by clearing out the message.
*/
@Override
public void destroy() {
if (!destroyed) {
Arrays.fill(message, (byte)0);
destroyed = true;
}
}
@Override
public boolean isDestroyed() {
return destroyed;
}
@Override
public String toString() {
if (destroyed) {
return "Destroyed KerberosCredMessage";
} else {
return "KRB_CRED from " + sender + " to " + recipient + ":\n"
+ Base64.getUrlEncoder().encodeToString(message);
}
}
@Override
public int hashCode() {
if (isDestroyed()) {
return -1;
} else {
return Objects.hash(sender, recipient, Arrays.hashCode(message));
}
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (! (other instanceof KerberosCredMessage)) {
return false;
}
KerberosCredMessage otherMessage = ((KerberosCredMessage) other);
if (isDestroyed() || otherMessage.isDestroyed()) {
return false;
}
return Objects.equals(sender, otherMessage.sender)
&& Objects.equals(recipient, otherMessage.recipient)
&& Arrays.equals(message, otherMessage.message);
}
}

View File

@ -27,13 +27,27 @@ package javax.security.auth.kerberos;
import java.util.Arrays;
import javax.crypto.SecretKey;
import javax.security.auth.Destroyable;
import javax.security.auth.DestroyFailedException;
/**
* This class encapsulates a long term secret key for a Kerberos
* principal.<p>
*
* A {@code KerberosKey} object includes an EncryptionKey, a
* {@link KerberosPrincipal} as its owner, and the version number
* of the key.<p>
*
* An EncryptionKey is defined in Section 4.2.9 of the Kerberos Protocol
* Specification (<a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>) as:
* <pre>
* EncryptionKey ::= SEQUENCE {
* keytype [0] Int32 -- actually encryption type --,
* keyvalue [1] OCTET STRING
* }
* </pre>
* The key material of a {@code KerberosKey} is defined as the value
* of the {@code keyValue} above.<p>
*
* All Kerberos JAAS login modules that obtain a principal's password and
* generate the secret key from it should use this class.
* Sometimes, such as when authenticating a server in
@ -70,7 +84,7 @@ import javax.security.auth.DestroyFailedException;
* @author Mayank Upadhyay
* @since 1.4
*/
public class KerberosKey implements SecretKey, Destroyable {
public class KerberosKey implements SecretKey {
private static final long serialVersionUID = -4625402278148246993L;
@ -89,15 +103,8 @@ public class KerberosKey implements SecretKey, Destroyable {
private final int versionNum;
/**
* {@code KeyImpl} is serialized by writing out the ASN1 Encoded bytes
* {@code KeyImpl} is serialized by writing out the ASN.1 encoded bytes
* of the encryption key.
* The ASN1 encoding is defined in RFC4120 and as follows:
* <pre>
* EncryptionKey ::= SEQUENCE {
* keytype [0] Int32 -- actually encryption type --,
* keyvalue [1] OCTET STRING
* }
* </pre>
*
* @serial
*/
@ -111,7 +118,7 @@ public class KerberosKey implements SecretKey, Destroyable {
* key information from a Kerberos "keytab".
*
* @param principal the principal that this secret key belongs to
* @param keyBytes the raw bytes for the secret key
* @param keyBytes the key material for the secret key
* @param keyType the key type for the secret key as defined by the
* Kerberos protocol specification.
* @param versionNum the version number of this secret key
@ -153,10 +160,12 @@ public class KerberosKey implements SecretKey, Destroyable {
* Returns the principal that this key belongs to.
*
* @return the principal this key belongs to.
* @throws IllegalStateException if the key is destroyed
*/
public final KerberosPrincipal getPrincipal() {
if (destroyed)
if (destroyed) {
throw new IllegalStateException("This key is no longer valid");
}
return principal;
}
@ -164,10 +173,12 @@ public class KerberosKey implements SecretKey, Destroyable {
* Returns the key version number.
*
* @return the key version number.
* @throws IllegalStateException if the key is destroyed
*/
public final int getVersionNumber() {
if (destroyed)
if (destroyed) {
throw new IllegalStateException("This key is no longer valid");
}
return versionNum;
}
@ -175,10 +186,10 @@ public class KerberosKey implements SecretKey, Destroyable {
* Returns the key type for this long-term key.
*
* @return the key type.
* @throws IllegalStateException if the key is destroyed
*/
public final int getKeyType() {
if (destroyed)
throw new IllegalStateException("This key is no longer valid");
// KeyImpl already checked if destroyed
return key.getKeyType();
}
@ -201,10 +212,10 @@ public class KerberosKey implements SecretKey, Destroyable {
* </ol>
*
* @return the name of the algorithm associated with this key.
* @throws IllegalStateException if the key is destroyed
*/
public final String getAlgorithm() {
if (destroyed)
throw new IllegalStateException("This key is no longer valid");
// KeyImpl already checked if destroyed
return key.getAlgorithm();
}
@ -212,10 +223,10 @@ public class KerberosKey implements SecretKey, Destroyable {
* Returns the name of the encoding format for this secret key.
*
* @return the String "RAW"
* @throws IllegalStateException if the key is destroyed
*/
public final String getFormat() {
if (destroyed)
throw new IllegalStateException("This key is no longer valid");
// KeyImpl already checked if destroyed
return key.getFormat();
}
@ -223,16 +234,15 @@ public class KerberosKey implements SecretKey, Destroyable {
* Returns the key material of this secret key.
*
* @return the key material
* @throws IllegalStateException if the key is destroyed
*/
public final byte[] getEncoded() {
if (destroyed)
throw new IllegalStateException("This key is no longer valid");
// KeyImpl already checked if destroyed
return key.getEncoded();
}
/**
* Destroys this key. A call to any of its other methods after this
* will cause an IllegalStateException to be thrown.
* Destroys this key by clearing out the key material of this secret key.
*
* @throws DestroyFailedException if some error occurs while destorying
* this key.
@ -253,9 +263,9 @@ public class KerberosKey implements SecretKey, Destroyable {
public String toString() {
if (destroyed) {
return "Destroyed Principal";
return "Destroyed KerberosKey";
}
return "Kerberos Principal " + principal.toString() +
return "Kerberos Principal " + principal +
"Key Version " + versionNum +
"key " + key.toString();
}
@ -293,8 +303,9 @@ public class KerberosKey implements SecretKey, Destroyable {
*/
public boolean equals(Object other) {
if (other == this)
if (other == this) {
return true;
}
if (! (other instanceof KerberosKey)) {
return false;

View File

@ -35,9 +35,6 @@ import javax.security.auth.Destroyable;
import javax.security.auth.RefreshFailedException;
import javax.security.auth.DestroyFailedException;
import sun.misc.HexDumpEncoder;
import sun.security.krb5.EncryptionKey;
import sun.security.krb5.Asn1Exception;
import sun.security.util.*;
/**
* This class encapsulates a Kerberos ticket and associated
@ -253,9 +250,10 @@ public class KerberosTicket implements Destroyable, Refreshable,
Date endTime,
Date renewTill,
InetAddress[] clientAddresses) {
if (sessionKey == null)
throw new IllegalArgumentException("Session key for ticket"
+ " cannot be null");
if (sessionKey == null) {
throw new IllegalArgumentException("Session key for ticket"
+ " cannot be null");
}
init(asn1Encoding, client, server,
new KeyImpl(sessionKey, keyType), flags, authTime,
startTime, endTime, renewTill, clientAddresses);
@ -271,41 +269,46 @@ public class KerberosTicket implements Destroyable, Refreshable,
Date endTime,
Date renewTill,
InetAddress[] clientAddresses) {
if (asn1Encoding == null)
throw new IllegalArgumentException("ASN.1 encoding of ticket"
+ " cannot be null");
if (asn1Encoding == null) {
throw new IllegalArgumentException("ASN.1 encoding of ticket"
+ " cannot be null");
}
this.asn1Encoding = asn1Encoding.clone();
if (client == null)
throw new IllegalArgumentException("Client name in ticket"
+ " cannot be null");
if (client == null) {
throw new IllegalArgumentException("Client name in ticket"
+ " cannot be null");
}
this.client = client;
if (server == null)
throw new IllegalArgumentException("Server name in ticket"
+ " cannot be null");
if (server == null) {
throw new IllegalArgumentException("Server name in ticket"
+ " cannot be null");
}
this.server = server;
// Caller needs to make sure `sessionKey` will not be null
this.sessionKey = sessionKey;
if (flags != null) {
if (flags.length >= NUM_FLAGS)
this.flags = flags.clone();
else {
if (flags.length >= NUM_FLAGS) {
this.flags = flags.clone();
} else {
this.flags = new boolean[NUM_FLAGS];
// Fill in whatever we have
for (int i = 0; i < flags.length; i++)
for (int i = 0; i < flags.length; i++) {
this.flags[i] = flags[i];
}
}
} else
this.flags = new boolean[NUM_FLAGS];
} else {
this.flags = new boolean[NUM_FLAGS];
}
if (this.flags[RENEWABLE_TICKET_FLAG]) {
if (renewTill == null)
throw new IllegalArgumentException("The renewable period "
if (renewTill == null) {
throw new IllegalArgumentException("The renewable period "
+ "end time cannot be null for renewable tickets.");
}
this.renewTill = new Date(renewTill.getTime());
}
@ -318,13 +321,15 @@ public class KerberosTicket implements Destroyable, Refreshable,
this.startTime = this.authTime;
}
if (endTime == null)
throw new IllegalArgumentException("End time for ticket validity"
+ " cannot be null");
if (endTime == null) {
throw new IllegalArgumentException("End time for ticket validity"
+ " cannot be null");
}
this.endTime = new Date(endTime.getTime());
if (clientAddresses != null)
this.clientAddresses = clientAddresses.clone();
if (clientAddresses != null) {
this.clientAddresses = clientAddresses.clone();
}
}
/**
@ -346,14 +351,17 @@ public class KerberosTicket implements Destroyable, Refreshable,
}
/**
* Returns the session key associated with this ticket.
* Returns the session key associated with this ticket. The return value
* is always a {@link EncryptionKey} object.
*
* @return the session key.
*/
public final SecretKey getSessionKey() {
if (destroyed)
if (destroyed) {
throw new IllegalStateException("This ticket is no longer valid");
return sessionKey;
}
return new EncryptionKey(
sessionKey.getEncoded(), sessionKey.getKeyType());
}
/**
@ -366,8 +374,9 @@ public class KerberosTicket implements Destroyable, Refreshable,
* @see #getSessionKey()
*/
public final int getSessionKeyType() {
if (destroyed)
if (destroyed) {
throw new IllegalStateException("This ticket is no longer valid");
}
return sessionKey.getKeyType();
}
@ -508,8 +517,9 @@ public class KerberosTicket implements Destroyable, Refreshable,
* @return an ASN.1 encoding of the entire ticket.
*/
public final byte[] getEncoded() {
if (destroyed)
if (destroyed) {
throw new IllegalStateException("This ticket is no longer valid");
}
return asn1Encoding.clone();
}
@ -539,16 +549,17 @@ public class KerberosTicket implements Destroyable, Refreshable,
*/
public void refresh() throws RefreshFailedException {
if (destroyed)
if (destroyed) {
throw new RefreshFailedException("A destroyed ticket "
+ "cannot be renewd.");
if (!isRenewable())
+ "cannot be renewd.");
}
if (!isRenewable()) {
throw new RefreshFailedException("This ticket is not renewable");
if (System.currentTimeMillis() > getRenewTill().getTime())
}
if (System.currentTimeMillis() > getRenewTill().getTime()) {
throw new RefreshFailedException("This ticket is past "
+ "its last renewal time.");
+ "its last renewal time.");
}
Throwable e = null;
sun.security.krb5.Credentials krb5Creds = null;
@ -634,8 +645,9 @@ public class KerberosTicket implements Destroyable, Refreshable,
}
public String toString() {
if (destroyed)
throw new IllegalStateException("This ticket is no longer valid");
if (destroyed) {
return "Destroyed KerberosTicket";
}
StringBuilder caddrString = new StringBuilder();
if (clientAddresses != null) {
for (int i = 0; i < clientAddresses.length; i++) {
@ -715,8 +727,9 @@ public class KerberosTicket implements Destroyable, Refreshable,
*/
public boolean equals(Object other) {
if (other == this)
if (other == this) {
return true;
}
if (! (other instanceof KerberosTicket)) {
return false;
@ -731,7 +744,7 @@ public class KerberosTicket implements Destroyable, Refreshable,
!endTime.equals(otherTicket.getEndTime()) ||
!server.equals(otherTicket.getServer()) ||
!client.equals(otherTicket.getClient()) ||
!sessionKey.equals(otherTicket.getSessionKey()) ||
!sessionKey.equals(otherTicket.sessionKey) ||
!Arrays.equals(clientAddresses, otherTicket.getClientAddresses()) ||
!Arrays.equals(flags, otherTicket.getFlags())) {
return false;
@ -739,35 +752,41 @@ public class KerberosTicket implements Destroyable, Refreshable,
// authTime may be null
if (authTime == null) {
if (otherTicket.getAuthTime() != null)
if (otherTicket.getAuthTime() != null) {
return false;
}
} else {
if (!authTime.equals(otherTicket.getAuthTime()))
if (!authTime.equals(otherTicket.getAuthTime())) {
return false;
}
}
// startTime may be null
if (startTime == null) {
if (otherTicket.getStartTime() != null)
if (otherTicket.getStartTime() != null) {
return false;
}
} else {
if (!startTime.equals(otherTicket.getStartTime()))
if (!startTime.equals(otherTicket.getStartTime())) {
return false;
}
}
if (renewTill == null) {
if (otherTicket.getRenewTill() != null)
if (otherTicket.getRenewTill() != null) {
return false;
}
} else {
if (!renewTill.equals(otherTicket.getRenewTill()))
if (!renewTill.equals(otherTicket.getRenewTill())) {
return false;
}
}
return true;
}
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
throws IOException, ClassNotFoundException {
s.defaultReadObject();
if (sessionKey == null) {
throw new InvalidObjectException("Session key cannot be null");

View File

@ -40,11 +40,13 @@ import java.security.Provider;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.Key;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import javax.crypto.Cipher;
import java.security.PrivilegedExceptionAction;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.*;
import javax.security.auth.kerberos.ServicePermission;
import javax.security.auth.kerberos.KerberosCredMessage;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KerberosTicket;
import sun.security.krb5.internal.Ticket;
/**
@ -118,6 +120,7 @@ class Krb5Context implements GSSContextSpi {
// XXX See if the required info from these can be extracted and
// stored elsewhere
private Credentials tgt;
private Credentials serviceCreds;
private KrbApReq apReq;
Ticket serviceTicket;
@ -616,7 +619,6 @@ class Krb5Context implements GSSContextSpi {
"No TGT available");
}
myName = (Krb5NameElement) myCred.getName();
Credentials tgt;
final Krb5ProxyCredential second;
if (myCred instanceof Krb5InitCredential) {
second = null;
@ -750,7 +752,6 @@ class Krb5Context implements GSSContextSpi {
// No need to write anything;
// just validate the incoming token
new AcceptSecContextToken(this, serviceCreds, apReq, is);
serviceCreds = null;
apReq = null;
state = STATE_DONE;
} else {
@ -1304,6 +1305,9 @@ class Krb5Context implements GSSContextSpi {
public final void dispose() throws GSSException {
state = STATE_DELETED;
delegatedCred = null;
tgt = null;
serviceCreds = null;
key = null;
}
public final Provider getProvider() {
@ -1424,6 +1428,9 @@ class Krb5Context implements GSSContextSpi {
switch (type) {
case KRB5_GET_SESSION_KEY:
return new KerberosSessionKey(key);
case KRB5_GET_SESSION_KEY_EX:
return new javax.security.auth.kerberos.EncryptionKey(
key.getBytes(), key.getEType());
case KRB5_GET_TKT_FLAGS:
return tktFlags.clone();
case KRB5_GET_AUTHZ_DATA:
@ -1435,6 +1442,26 @@ class Krb5Context implements GSSContextSpi {
}
case KRB5_GET_AUTHTIME:
return authTime;
case KRB5_GET_KRB_CRED:
if (!isInitiator()) {
throw new GSSException(GSSException.UNAVAILABLE, -1,
"KRB_CRED not available on acceptor side.");
}
KerberosPrincipal sender = new KerberosPrincipal(
myName.getKrb5PrincipalName().getName());
KerberosPrincipal recipient = new KerberosPrincipal(
peerName.getKrb5PrincipalName().getName());
try {
byte[] krbCred = new KrbCred(tgt, serviceCreds, key)
.getMessage();
return new KerberosCredMessage(
sender, recipient, krbCred);
} catch (KrbException | IOException e) {
GSSException gsse = new GSSException(GSSException.UNAVAILABLE, -1,
"KRB_CRED not generated correctly.");
gsse.initCause(e);
throw gsse;
}
}
throw new GSSException(GSSException.UNAVAILABLE, -1,
"Inquire type not supported.");
@ -1456,4 +1483,5 @@ class Krb5Context implements GSSContextSpi {
public void setAuthzData(com.sun.security.jgss.AuthorizationDataEntry[] authzData) {
this.authzData = authzData;
}
}

View File

@ -33,9 +33,7 @@
import java.net.InetAddress;
import java.util.Date;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.*;
public class KerberosHashEqualsTest {
public static void main(String[] args) throws Exception {
@ -66,28 +64,67 @@ public class KerberosHashEqualsTest {
k2.destroy();
checkNotSame(k1, k2);
// destroyed keys doesn't equal to each other
checkNotSame(k2, k1);
checkSame(k2, k2);
k1.destroy();
checkNotSame(k1, k2);
// Destroyed key has string and hashCode
k1.toString(); k1.hashCode();
// a little different
k1 = new KerberosKey(newKP("A"), "pass".getBytes(), 1, 1);
k2 = new KerberosKey(newKP("B"), "pass".getBytes(), 1, 1);
checkNotSame(k1, k2);
k2 = new KerberosKey(newKP("A"), "ssap".getBytes(), 1, 1);
checkNotSame(k1, k2);
k2 = new KerberosKey(newKP("A"), "pass".getBytes(), 2, 1);
checkNotSame(k1, k2);
k2 = new KerberosKey(newKP("A"), "pass".getBytes(), 1, 2);
checkNotSame(k1, k2);
// Null
k1 = new KerberosKey(null, "pass".getBytes(), 1, 2);
checkNotSame(k1, k2); // null to non-null
k2 = new KerberosKey(null, "pass".getBytes(), 1, 2);
checkSame(k1, k2); // null to null
// Even key with null principal has a string and hashCode
k1.toString(); k1.hashCode();
checkNotSame(k1, "Another Object");
EncryptionKey e1, e2;
e1 = new EncryptionKey("pass".getBytes(), 1);
e2 = new EncryptionKey("pass".getBytes(), 1);
checkSame(e1, e1); // me to me
checkSame(e1, e2); // same
e2.destroy();
checkNotSame(e1, e2);
checkNotSame(e2, e1);
checkSame(e2, e2);
e1.destroy();
checkNotSame(e1, e2);
// Destroyed key has string and hashCode
e1.toString(); e1.hashCode();
// a little different
e1 = new EncryptionKey("pass".getBytes(), 1);
e2 = new EncryptionKey("ssap".getBytes(), 1);
checkNotSame(e1, e2);
e2 = new EncryptionKey("pass".getBytes(), 2);
checkNotSame(e1, e2);
checkNotSame(e1, "Another Object");
KerberosTicket t1, t2;
t1 = new KerberosTicket("asn1".getBytes(), newKP("client"), newKP("server"), "pass".getBytes(), 1, new boolean[] {true, true}, new Date(0), new Date(0), new Date(0), new Date(0), null);
t2 = new KerberosTicket("asn1".getBytes(), newKP("client"), newKP("server"), "pass".getBytes(), 1, new boolean[] {true, true}, new Date(0), new Date(0), new Date(0), new Date(0), null);
@ -120,6 +157,7 @@ public class KerberosHashEqualsTest {
t2.destroy();
checkNotSame(t1, t2);
t2.hashCode(); t2.toString();
// destroyed tickets doesn't equal to each other
checkNotSame(t2, t1);
@ -130,6 +168,37 @@ public class KerberosHashEqualsTest {
checkNotSame(t1, t2); // renewtill is useful
checkNotSame(t1, "Another Object");
KerberosCredMessage m1, m2;
m1 = new KerberosCredMessage(newKP("C"), newKP("S"), "message".getBytes());
m2 = new KerberosCredMessage(newKP("C"), newKP("S"), "message".getBytes());
checkSame(m1, m1); // me to me
checkSame(m1, m2); // same
m2.destroy();
checkNotSame(m1, m2);
checkNotSame(m2, m1);
checkSame(m2, m2);
m1.destroy();
checkNotSame(m1, m2);
// Destroyed message has string and hashCode
m1.toString(); m1.hashCode();
// a little different
m1 = new KerberosCredMessage(newKP("C"), newKP("S"), "message".getBytes());
m2 = new KerberosCredMessage(newKP("A"), newKP("S"), "message".getBytes());
checkNotSame(m1, m2);
m2 = new KerberosCredMessage(newKP("C"), newKP("B"), "message".getBytes());
checkNotSame(m1, m2);
m1 = new KerberosCredMessage(newKP("C"), newKP("S"), "hello".getBytes());
checkNotSame(m1, m2);
checkNotSame(m1, "Another Object");
System.out.println("Good!");
}

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8043071
* @summary Expose session key and KRB_CRED through extended GSS-API
*/
import javax.security.auth.kerberos.*;
import java.util.function.Supplier;
public class KerberosNullsAndDestroyTest {
public static void main(String[] args) throws Exception {
KerberosPrincipal c = new KerberosPrincipal("me@HERE");
KerberosPrincipal s = new KerberosPrincipal("you@THERE");
// These object constructions should throw NullPointerException
checkNPE(() -> new KerberosKey(c, null, 17, 1));
checkNPE(() -> new EncryptionKey(null, 17));
checkNPE(() -> new KerberosCredMessage(null, s, new byte[1]));
checkNPE(() -> new KerberosCredMessage(c, null, new byte[1]));
checkNPE(() -> new KerberosCredMessage(c, s, null));
KerberosKey k1 = new KerberosKey(c, new byte[16], 17, 1);
EncryptionKey k2 = new EncryptionKey(new byte[16], 17);
KerberosCredMessage m = new KerberosCredMessage(c, s, new byte[1]);
// These get calls should throw IllegalStateException
k1.destroy();
checkISE(() -> k1.getAlgorithm());
checkISE(() -> k1.getEncoded());
checkISE(() -> k1.getFormat());
checkISE(() -> k1.getKeyType());
checkISE(() -> k1.getPrincipal());
checkISE(() -> k1.getVersionNumber());
k2.destroy();
checkISE(() -> k2.getAlgorithm());
checkISE(() -> k2.getEncoded());
checkISE(() -> k2.getFormat());
checkISE(() -> k2.getKeyType());
m.destroy();
checkISE(() -> m.getSender());
checkISE(() -> m.getRecipient());
checkISE(() -> m.getEncoded());
}
static void checkNPE(Supplier<?> f) throws Exception {
check(f, NullPointerException.class);
}
static void checkISE(Supplier<?> f) throws Exception {
check(f, IllegalStateException.class);
}
static void check(Supplier<?> f, Class<? extends Exception> type) throws Exception {
try {
f.get();
} catch (Exception e) {
if (e.getClass() != type) {
throw e;
} else {
return;
}
}
throw new Exception("Should fail");
}
}

View File

@ -26,9 +26,11 @@ import java.security.Key;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosCredMessage;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.login.LoginContext;
@ -86,7 +88,6 @@ public class Context {
/**
* Using the delegated credentials from a previous acceptor
* @param c
*/
public Context delegated() throws Exception {
Context out = new Context();
@ -177,7 +178,6 @@ public class Context {
/**
* Logins with username/keytab as an existing Subject. The
* same subject can be used multiple times to simulate multiple logins.
* @param s existing subject
*/
public static Context fromUserKtab(
String user, String ktab, boolean storeKey) throws Exception {
@ -411,6 +411,12 @@ public class Context {
Key k = (Key)ex.inquireSecContext(
InquireType.KRB5_GET_SESSION_KEY);
if (k == null) {
throw new Exception("(Old) Session key cannot be null");
}
System.out.println("(Old) Session key is: " + k);
Key k2 = (Key)ex.inquireSecContext(
InquireType.KRB5_GET_SESSION_KEY_EX);
if (k2 == null) {
throw new Exception("Session key cannot be null");
}
System.out.println("Session key is: " + k);
@ -431,6 +437,19 @@ public class Context {
InquireType.KRB5_GET_AUTHZ_DATA);
System.out.println("AuthzData is: " + Arrays.toString(ad));
}
try {
KerberosCredMessage tok = (KerberosCredMessage)ex.inquireSecContext(
InquireType.KRB5_GET_KRB_CRED);
System.out.println("KRB_CRED is " +
(tok == null?"not ":"") + "available");
if (tok != null) {
System.out.println("From " + tok.getSender() + " to "
+ tok.getRecipient());
System.out.println(Base64.getEncoder().encodeToString(tok.getEncoded()));
}
} catch (Exception e) {
System.out.println("KRB_CRED is not available: " + e);
}
}
}
}

View File

@ -1,174 +0,0 @@
/*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4641821
* @run main/othervm KerberosHashEqualsTest
* @summary hashCode() and equals() for KerberosKey and KerberosTicket
*/
import java.net.InetAddress;
import java.util.Date;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KerberosTicket;
public class KerberosHashEqualsTest {
public static void main(String[] args) throws Exception {
new OneKDC(null);
new KerberosHashEqualsTest().check();
}
void checkSame(Object o1, Object o2) {
if(!o1.equals(o2)) {
throw new RuntimeException("equals() fails");
}
if(o1.hashCode() != o2.hashCode()) {
throw new RuntimeException("hashCode() not same");
}
}
void checkNotSame(Object o1, Object o2) {
if(o1.equals(o2)) {
throw new RuntimeException("equals() succeeds");
}
}
void check() throws Exception {
// The key part:
// new KerberosKey(principal, bytes, keyType, version)
KerberosKey k1, k2;
KerberosPrincipal CLIENT = new KerberosPrincipal("client");
KerberosPrincipal SERVER = new KerberosPrincipal("server");
byte[] PASS = "pass".getBytes();
k1 = new KerberosKey(CLIENT, PASS, 1, 1);
k2 = new KerberosKey(CLIENT, PASS, 1, 1);
checkSame(k1, k1); // me is me
checkSame(k1, k2); // same
// A destroyed key doesn't equal to any key
k2.destroy();
checkNotSame(k1, k2);
checkNotSame(k2, k1);
k1.destroy();
checkNotSame(k1, k2); // even if they are both destroyed
checkNotSame(k2, k1);
checkSame(k2, k2);
// a little difference means not equal
k1 = new KerberosKey(CLIENT, PASS, 1, 1);
k2 = new KerberosKey(SERVER, PASS, 1, 1);
checkNotSame(k1, k2); // Different principal name
k2 = new KerberosKey(CLIENT, "ssap".getBytes(), 1, 1);
checkNotSame(k1, k2); // Different password
k2 = new KerberosKey(CLIENT, PASS, 2, 1);
checkNotSame(k1, k2); // Different keytype
k2 = new KerberosKey(CLIENT, PASS, 1, 2);
checkNotSame(k1, k2); // Different version
k2 = new KerberosKey(null, PASS, 1, 2);
checkNotSame(k1, k2); // null is not non-null
k1 = new KerberosKey(null, PASS, 1, 2);
checkSame(k1, k2); // null is null
checkNotSame(k1, "Another Object");
// The ticket part:
// new KerberosTicket(asn1 bytes, client, server, session key, type, flags,
// auth, start, end, renewUntil times, address)
KerberosTicket t1, t2;
byte[] ASN1 = "asn1".getBytes();
boolean[] FORWARDABLE = new boolean[] {true, true};
boolean[] ALLTRUE = new boolean[] {true, true, true, true, true, true, true, true, true, true};
Date D0 = new Date(0);
t1 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, FORWARDABLE, D0, D0, D0, D0, null);
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, FORWARDABLE, D0, D0, D0, D0, null);
checkSame(t1, t1);
checkSame(t1, t2);
// destroyed tickets doesn't equal to each other
t1.destroy();
checkNotSame(t1, t2);
checkNotSame(t2, t1);
t2.destroy();
checkNotSame(t1, t2); // even if they are both destroyed
checkNotSame(t2, t1);
checkSame(t2, t2); // unless they are the same object
// a little difference means not equal
t1 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, FORWARDABLE, D0, D0, D0, D0, null);
t2 = new KerberosTicket("asn11".getBytes(), CLIENT, SERVER, PASS, 1, FORWARDABLE, D0, D0, D0, D0, null);
checkNotSame(t1, t2); // Different ASN1 encoding
t2 = new KerberosTicket(ASN1, new KerberosPrincipal("client1"), SERVER, PASS, 1, FORWARDABLE, D0, D0, D0, D0, null);
checkNotSame(t1, t2); // Different client
t2 = new KerberosTicket(ASN1, CLIENT, new KerberosPrincipal("server1"), PASS, 1, FORWARDABLE, D0, D0, D0, D0, null);
checkNotSame(t1, t2); // Different server
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, "pass1".getBytes(), 1, FORWARDABLE, D0, D0, D0, D0, null);
checkNotSame(t1, t2); // Different session key
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 2, FORWARDABLE, D0, D0, D0, D0, null);
checkNotSame(t1, t2); // Different key type
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, new boolean[] {true, false}, D0, D0, D0, D0, null);
checkNotSame(t1, t2); // Different flags, not FORWARDABLE
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, FORWARDABLE, new Date(1), D0, D0, D0, null);
checkNotSame(t1, t2); // Different authtime
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, FORWARDABLE, D0, new Date(1), D0, D0, null);
checkNotSame(t1, t2); // Different starttime
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, FORWARDABLE, D0, D0, new Date(1), D0, null);
checkNotSame(t1, t2); // Different endtime
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, FORWARDABLE, D0, D0, D0, D0, new InetAddress[2]);
checkNotSame(t1, t2); // Different client addresses
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, FORWARDABLE, D0, D0, D0, new Date(1), null);
t1 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, FORWARDABLE, D0, D0, D0, new Date(2), null);
checkSame(t1, t2); // renewtill is ignored when RENEWABLE ticket flag is not set.
t2 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, ALLTRUE, D0, D0, D0, new Date(1), null);
t1 = new KerberosTicket(ASN1, CLIENT, SERVER, PASS, 1, ALLTRUE, D0, D0, D0, new Date(2), null);
checkNotSame(t1, t2); // renewtill is used when RENEWABLE is set.
checkNotSame(t1, "Another Object");
System.out.println("Good!");
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8043071
* @summary Expose session key and KRB_CRED through extended GSS-API
* @compile -XDignore.symbol.file NewInquireTypes.java
* @run main/othervm NewInquireTypes
*/
import com.sun.security.jgss.InquireType;
import sun.security.jgss.GSSUtil;
import sun.security.krb5.internal.KRBCred;
import sun.security.krb5.internal.crypto.KeyUsage;
import javax.security.auth.kerberos.KerberosCredMessage;
import javax.security.auth.kerberos.EncryptionKey;
public class NewInquireTypes {
public static void main(String[] args) throws Exception {
new OneKDC(null).writeJAASConf();
Context c, s;
c = Context.fromJAAS("client");
s = Context.fromJAAS("server");
c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
Context.handshake(c, s);
EncryptionKey key = (EncryptionKey)
c.x().inquireSecContext(InquireType.KRB5_GET_SESSION_KEY_EX);
KerberosCredMessage cred = (KerberosCredMessage)
c.x().inquireSecContext(InquireType.KRB5_GET_KRB_CRED);
// Confirm the KRB_CRED message is encrypted with the session key.
new KRBCred(cred.getEncoded()).encPart.decrypt(
new sun.security.krb5.EncryptionKey(key.getKeyType(), key.getEncoded()),
KeyUsage.KU_ENC_KRB_CRED_PART);
}
}