feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
41
jdkSrc/jdk8/sun/security/krb5/Asn1Exception.java
Normal file
41
jdkSrc/jdk8/sun/security/krb5/Asn1Exception.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
public class Asn1Exception extends KrbException {
|
||||
|
||||
private static final long serialVersionUID = 8291288984575084132L;
|
||||
|
||||
public Asn1Exception(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
}
|
||||
340
jdkSrc/jdk8/sun/security/krb5/Checksum.java
Normal file
340
jdkSrc/jdk8/sun/security/krb5/Checksum.java
Normal file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import java.util.Arrays;
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* This class encapsulates the concept of a Kerberos checksum.
|
||||
*/
|
||||
public class Checksum {
|
||||
|
||||
private int cksumType;
|
||||
private byte[] checksum;
|
||||
|
||||
// ----------------------------------------------+-------------+-----------
|
||||
// Checksum type |sumtype |checksum
|
||||
// |value | size
|
||||
// ----------------------------------------------+-------------+-----------
|
||||
public static final int CKSUMTYPE_NULL = 0; // 0
|
||||
public static final int CKSUMTYPE_CRC32 = 1; // 4
|
||||
public static final int CKSUMTYPE_RSA_MD4 = 2; // 16
|
||||
public static final int CKSUMTYPE_RSA_MD4_DES = 3; // 24
|
||||
public static final int CKSUMTYPE_DES_MAC = 4; // 16
|
||||
public static final int CKSUMTYPE_DES_MAC_K = 5; // 8
|
||||
public static final int CKSUMTYPE_RSA_MD4_DES_K = 6; // 16
|
||||
public static final int CKSUMTYPE_RSA_MD5 = 7; // 16
|
||||
public static final int CKSUMTYPE_RSA_MD5_DES = 8; // 24
|
||||
|
||||
// draft-ietf-krb-wg-crypto-07.txt
|
||||
public static final int CKSUMTYPE_HMAC_SHA1_DES3_KD = 12; // 20
|
||||
|
||||
// draft-raeburn-krb-rijndael-krb-07.txt
|
||||
public static final int CKSUMTYPE_HMAC_SHA1_96_AES128 = 15; // 96
|
||||
public static final int CKSUMTYPE_HMAC_SHA1_96_AES256 = 16; // 96
|
||||
|
||||
// draft-brezak-win2k-krb-rc4-hmac-04.txt
|
||||
public static final int CKSUMTYPE_HMAC_MD5_ARCFOUR = -138;
|
||||
|
||||
// default checksum type, -1 if not set
|
||||
static int CKSUMTYPE_DEFAULT;
|
||||
static int SAFECKSUMTYPE_DEFAULT;
|
||||
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
static {
|
||||
initStatic();
|
||||
}
|
||||
|
||||
public static void initStatic() {
|
||||
String temp = null;
|
||||
Config cfg = null;
|
||||
try {
|
||||
cfg = Config.getInstance();
|
||||
temp = cfg.get("libdefaults", "default_checksum");
|
||||
if (temp != null) {
|
||||
CKSUMTYPE_DEFAULT = Config.getType(temp);
|
||||
} else {
|
||||
CKSUMTYPE_DEFAULT = -1;
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Exception in getting default checksum "+
|
||||
"value from the configuration. " +
|
||||
"No default checksum set.");
|
||||
exc.printStackTrace();
|
||||
}
|
||||
CKSUMTYPE_DEFAULT = -1;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
temp = cfg.get("libdefaults", "safe_checksum_type");
|
||||
if (temp != null)
|
||||
{
|
||||
SAFECKSUMTYPE_DEFAULT = Config.getType(temp);
|
||||
} else {
|
||||
SAFECKSUMTYPE_DEFAULT = -1;
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Exception in getting safe default " +
|
||||
"checksum value " +
|
||||
"from the configuration Setting. " +
|
||||
"No safe default checksum set.");
|
||||
exc.printStackTrace();
|
||||
}
|
||||
SAFECKSUMTYPE_DEFAULT = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new Checksum using the raw data and type.
|
||||
*
|
||||
* This constructor is only used by Authenticator Checksum
|
||||
* {@link sun.security.jgss.krb5.InitialToken.OverloadedChecksum}
|
||||
* where the checksum type must be 0x8003
|
||||
* (see https://tools.ietf.org/html/rfc4121#section-4.1.1)
|
||||
* and checksum field/value is used to convey service flags,
|
||||
* channel bindings, and optional delegation information.
|
||||
* This special type does NOT have a {@link CksumType} and has its
|
||||
* own calculating and verification rules. It does has the same
|
||||
* ASN.1 encoding though.
|
||||
*
|
||||
* @param data the byte array of checksum.
|
||||
* @param new_cksumType the type of checksum.
|
||||
*/
|
||||
public Checksum(byte[] data, int new_cksumType) {
|
||||
cksumType = new_cksumType;
|
||||
checksum = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new Checksum by calculating over the data using
|
||||
* the specified checksum type. If the checksum is unkeyed, key
|
||||
* and usage are ignored.
|
||||
*
|
||||
* @param new_cksumType the type of checksum. If set to -1, the
|
||||
* {@linkplain EType#checksumType() mandatory checksum type}
|
||||
* for the encryption type of {@code key} will be used
|
||||
* @param data the data that needs to be performed a checksum calculation on
|
||||
* @param key the key used by a keyed checksum
|
||||
* @param usage the usage used by a keyed checksum
|
||||
*/
|
||||
public Checksum(int new_cksumType, byte[] data,
|
||||
EncryptionKey key, int usage)
|
||||
throws KdcErrException, KrbApErrException, KrbCryptoException {
|
||||
if (new_cksumType == -1) {
|
||||
cksumType = EType.getInstance(key.getEType()).checksumType();
|
||||
} else {
|
||||
cksumType = new_cksumType;
|
||||
}
|
||||
checksum = CksumType.getInstance(cksumType).calculateChecksum(
|
||||
data, data.length, key.getBytes(), usage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the keyed checksum over the data passed in.
|
||||
*/
|
||||
public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, int usage)
|
||||
throws KdcErrException, KrbApErrException, KrbCryptoException {
|
||||
CksumType cksumEngine = CksumType.getInstance(cksumType);
|
||||
if (!cksumEngine.isKeyed()) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
|
||||
} else {
|
||||
return cksumEngine.verifyChecksum(
|
||||
data, data.length, key.getBytes(), checksum, usage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies the checksum over the data passed in. The checksum might
|
||||
* be a keyed or not.
|
||||
*
|
||||
* =============== ATTENTION! Use with care ==================
|
||||
* According to https://tools.ietf.org/html/rfc3961#section-6.1,
|
||||
* An unkeyed checksum should only be used "in limited circumstances
|
||||
* where the lack of a key does not provide a window for an attack,
|
||||
* preferably as part of an encrypted message".
|
||||
*/
|
||||
public boolean verifyAnyChecksum(byte[] data, EncryptionKey key, int usage)
|
||||
throws KdcErrException, KrbCryptoException {
|
||||
return CksumType.getInstance(cksumType).verifyChecksum(
|
||||
data, data.length, key.getBytes(), checksum, usage);
|
||||
}
|
||||
|
||||
boolean isEqual(Checksum cksum) throws KdcErrException {
|
||||
if (cksumType != cksum.cksumType) {
|
||||
return false;
|
||||
}
|
||||
return CksumType.isChecksumEqual(checksum, cksum.checksum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of Checksum from an ASN.1 encoded representation.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1
|
||||
* encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
public Checksum(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der;
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x00) {
|
||||
cksumType = der.getData().getBigInteger().intValue();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x01) {
|
||||
checksum = der.getData().getOctetString();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
if (encoding.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a Checksum object.
|
||||
* <pre>{@code
|
||||
* Checksum ::= SEQUENCE {
|
||||
* cksumtype [0] Int32,
|
||||
* checksum [1] OCTET STRING
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
* @return byte array of enocded Checksum.
|
||||
* @exception Asn1Exception if an error occurs while decoding an
|
||||
* ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading
|
||||
* encoded data.
|
||||
*
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(cksumType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte)0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putOctetString(checksum);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte)0x01), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a checksum object from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception if an error occurs while decoding an
|
||||
* ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading
|
||||
* encoded data.
|
||||
* @param data the Der input stream value, which contains one or more
|
||||
* marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicates if this data field is optional
|
||||
* @return an instance of Checksum.
|
||||
*
|
||||
*/
|
||||
public static Checksum parse(DerInputStream data,
|
||||
byte explicitTag, boolean optional)
|
||||
throws Asn1Exception, IOException {
|
||||
|
||||
if ((optional) &&
|
||||
(((byte)data.peekByte() & (byte)0x1F) != explicitTag)) {
|
||||
return null;
|
||||
}
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
} else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new Checksum(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw bytes of the checksum, not in ASN.1 encoded form.
|
||||
*/
|
||||
public final byte[] getBytes() {
|
||||
return checksum;
|
||||
}
|
||||
|
||||
public final int getType() {
|
||||
return cksumType;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof Checksum)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return isEqual((Checksum)obj);
|
||||
} catch (KdcErrException kee) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
int result = 17;
|
||||
result = 37 * result + cksumType;
|
||||
if (checksum != null) {
|
||||
result = 37 * result + Arrays.hashCode(checksum);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
1348
jdkSrc/jdk8/sun/security/krb5/Config.java
Normal file
1348
jdkSrc/jdk8/sun/security/krb5/Config.java
Normal file
File diff suppressed because it is too large
Load Diff
55
jdkSrc/jdk8/sun/security/krb5/Confounder.java
Normal file
55
jdkSrc/jdk8/sun/security/krb5/Confounder.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2007, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public final class Confounder {
|
||||
private static SecureRandom srand = new SecureRandom();
|
||||
|
||||
private Confounder() { // not instantiable
|
||||
}
|
||||
|
||||
public static byte[] bytes(int size) {
|
||||
byte[] data = new byte[size];
|
||||
srand.nextBytes(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public static int intValue() {
|
||||
return srand.nextInt();
|
||||
}
|
||||
|
||||
public static long longValue() {
|
||||
return srand.nextLong();
|
||||
}
|
||||
}
|
||||
585
jdkSrc/jdk8/sun/security/krb5/Credentials.java
Normal file
585
jdkSrc/jdk8/sun/security/krb5/Credentials.java
Normal file
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.ccache.CredentialsCache;
|
||||
import sun.security.krb5.internal.crypto.EType;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* This class encapsulates the concept of a Kerberos service
|
||||
* credential. That includes a Kerberos ticket and an associated
|
||||
* session key.
|
||||
*/
|
||||
public class Credentials {
|
||||
|
||||
Ticket ticket;
|
||||
PrincipalName client;
|
||||
PrincipalName clientAlias;
|
||||
PrincipalName server;
|
||||
PrincipalName serverAlias;
|
||||
EncryptionKey key;
|
||||
TicketFlags flags;
|
||||
KerberosTime authTime;
|
||||
KerberosTime startTime;
|
||||
KerberosTime endTime;
|
||||
KerberosTime renewTill;
|
||||
HostAddresses cAddr;
|
||||
AuthorizationData authzData;
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
private static CredentialsCache cache;
|
||||
static boolean alreadyLoaded = false;
|
||||
private static boolean alreadyTried = false;
|
||||
|
||||
private Credentials proxy = null;
|
||||
|
||||
public Credentials getProxy() {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public Credentials setProxy(Credentials proxy) {
|
||||
this.proxy = proxy;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Read native ticket with session key type in the given list
|
||||
private static native Credentials acquireDefaultNativeCreds(int[] eTypes);
|
||||
|
||||
public Credentials(Ticket new_ticket,
|
||||
PrincipalName new_client,
|
||||
PrincipalName new_client_alias,
|
||||
PrincipalName new_server,
|
||||
PrincipalName new_server_alias,
|
||||
EncryptionKey new_key,
|
||||
TicketFlags new_flags,
|
||||
KerberosTime authTime,
|
||||
KerberosTime new_startTime,
|
||||
KerberosTime new_endTime,
|
||||
KerberosTime renewTill,
|
||||
HostAddresses cAddr,
|
||||
AuthorizationData authzData) {
|
||||
this(new_ticket, new_client, new_client_alias, new_server,
|
||||
new_server_alias, new_key, new_flags, authTime,
|
||||
new_startTime, new_endTime, renewTill, cAddr);
|
||||
this.authzData = authzData;
|
||||
}
|
||||
|
||||
public Credentials(Ticket new_ticket,
|
||||
PrincipalName new_client,
|
||||
PrincipalName new_client_alias,
|
||||
PrincipalName new_server,
|
||||
PrincipalName new_server_alias,
|
||||
EncryptionKey new_key,
|
||||
TicketFlags new_flags,
|
||||
KerberosTime authTime,
|
||||
KerberosTime new_startTime,
|
||||
KerberosTime new_endTime,
|
||||
KerberosTime renewTill,
|
||||
HostAddresses cAddr) {
|
||||
ticket = new_ticket;
|
||||
client = new_client;
|
||||
clientAlias = new_client_alias;
|
||||
server = new_server;
|
||||
serverAlias = new_server_alias;
|
||||
key = new_key;
|
||||
flags = new_flags;
|
||||
this.authTime = authTime;
|
||||
startTime = new_startTime;
|
||||
endTime = new_endTime;
|
||||
this.renewTill = renewTill;
|
||||
this.cAddr = cAddr;
|
||||
}
|
||||
|
||||
public Credentials(byte[] encoding,
|
||||
String client,
|
||||
String clientAlias,
|
||||
String server,
|
||||
String serverAlias,
|
||||
byte[] keyBytes,
|
||||
int keyType,
|
||||
boolean[] flags,
|
||||
Date authTime,
|
||||
Date startTime,
|
||||
Date endTime,
|
||||
Date renewTill,
|
||||
InetAddress[] cAddrs) throws KrbException, IOException {
|
||||
this(new Ticket(encoding),
|
||||
new PrincipalName(client, PrincipalName.KRB_NT_PRINCIPAL),
|
||||
(clientAlias == null? null : new PrincipalName(clientAlias,
|
||||
PrincipalName.KRB_NT_PRINCIPAL)),
|
||||
new PrincipalName(server, PrincipalName.KRB_NT_SRV_INST),
|
||||
(serverAlias == null? null : new PrincipalName(serverAlias,
|
||||
PrincipalName.KRB_NT_SRV_INST)),
|
||||
new EncryptionKey(keyType, keyBytes),
|
||||
(flags == null? null: new TicketFlags(flags)),
|
||||
(authTime == null? null: new KerberosTime(authTime)),
|
||||
(startTime == null? null: new KerberosTime(startTime)),
|
||||
(endTime == null? null: new KerberosTime(endTime)),
|
||||
(renewTill == null? null: new KerberosTime(renewTill)),
|
||||
null); // caddrs are in the encoding at this point
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires a service ticket for the specified service
|
||||
* principal. If the service ticket is not already available, it
|
||||
* obtains a new one from the KDC.
|
||||
*/
|
||||
/*
|
||||
public Credentials(Credentials tgt, PrincipalName service)
|
||||
throws KrbException {
|
||||
}
|
||||
*/
|
||||
|
||||
public final PrincipalName getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public final PrincipalName getClientAlias() {
|
||||
return clientAlias;
|
||||
}
|
||||
|
||||
public final PrincipalName getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public final PrincipalName getServerAlias() {
|
||||
return serverAlias;
|
||||
}
|
||||
|
||||
public final EncryptionKey getSessionKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public final Date getAuthTime() {
|
||||
if (authTime != null) {
|
||||
return authTime.toDate();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public final Date getStartTime() {
|
||||
if (startTime != null)
|
||||
{
|
||||
return startTime.toDate();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Date getEndTime() {
|
||||
if (endTime != null)
|
||||
{
|
||||
return endTime.toDate();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Date getRenewTill() {
|
||||
if (renewTill != null)
|
||||
{
|
||||
return renewTill.toDate();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final boolean[] getFlags() {
|
||||
if (flags == null) // Can be in a KRB-CRED
|
||||
return null;
|
||||
return flags.toBooleanArray();
|
||||
}
|
||||
|
||||
public final InetAddress[] getClientAddresses() {
|
||||
|
||||
if (cAddr == null)
|
||||
return null;
|
||||
|
||||
return cAddr.getInetAddresses();
|
||||
}
|
||||
|
||||
public final byte[] getEncoded() {
|
||||
byte[] retVal = null;
|
||||
try {
|
||||
retVal = ticket.asn1Encode();
|
||||
} catch (Asn1Exception e) {
|
||||
if (DEBUG)
|
||||
System.out.println(e);
|
||||
} catch (IOException ioe) {
|
||||
if (DEBUG)
|
||||
System.out.println(ioe);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public boolean isForwardable() {
|
||||
return flags.get(Krb5.TKT_OPTS_FORWARDABLE);
|
||||
}
|
||||
|
||||
public boolean isRenewable() {
|
||||
return flags.get(Krb5.TKT_OPTS_RENEWABLE);
|
||||
}
|
||||
|
||||
public Ticket getTicket() {
|
||||
return ticket;
|
||||
}
|
||||
|
||||
public TicketFlags getTicketFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public AuthorizationData getAuthzData() {
|
||||
return authzData;
|
||||
}
|
||||
/**
|
||||
* Checks if the service ticket returned by the KDC has the OK-AS-DELEGATE
|
||||
* flag set
|
||||
* @return true if OK-AS_DELEGATE flag is set, otherwise, return false.
|
||||
*/
|
||||
public boolean checkDelegate() {
|
||||
return flags.get(Krb5.TKT_OPTS_DELEGATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset TKT_OPTS_DELEGATE to false, called at credentials acquirement
|
||||
* when one of the cross-realm TGTs does not have the OK-AS-DELEGATE
|
||||
* flag set. This info must be preservable and restorable through
|
||||
* the Krb5Util.credsToTicket/ticketToCreds() methods so that even if
|
||||
* the service ticket is cached it still remembers the cross-realm
|
||||
* authentication result.
|
||||
*/
|
||||
public void resetDelegate() {
|
||||
flags.set(Krb5.TKT_OPTS_DELEGATE, false);
|
||||
}
|
||||
|
||||
public Credentials renew() throws KrbException, IOException {
|
||||
KDCOptions options = new KDCOptions();
|
||||
options.set(KDCOptions.RENEW, true);
|
||||
/*
|
||||
* Added here to pass KrbKdcRep.check:73
|
||||
*/
|
||||
options.set(KDCOptions.RENEWABLE, true);
|
||||
|
||||
return new KrbTgsReq(options,
|
||||
this,
|
||||
server,
|
||||
serverAlias,
|
||||
null, // from
|
||||
null, // till
|
||||
null, // rtime
|
||||
null, // eTypes
|
||||
cAddr,
|
||||
null,
|
||||
null,
|
||||
null).sendAndGetCreds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a TGT for the given client principal from a ticket cache.
|
||||
*
|
||||
* @param princ the client principal. A value of null means that the
|
||||
* default principal name in the credentials cache will be used.
|
||||
* @param ticketCache the path to the tickets file. A value
|
||||
* of null will be accepted to indicate that the default
|
||||
* path should be searched
|
||||
* @return the TGT credentials or null if none were found. If the tgt
|
||||
* expired, it is the responsibility of the caller to determine this.
|
||||
*/
|
||||
public static Credentials acquireTGTFromCache(PrincipalName princ,
|
||||
String ticketCache)
|
||||
throws KrbException, IOException {
|
||||
|
||||
if (ticketCache == null) {
|
||||
// The default ticket cache on Windows and Mac is not a file.
|
||||
String os = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("os.name"));
|
||||
if (os.toUpperCase(Locale.ENGLISH).startsWith("WINDOWS") ||
|
||||
os.toUpperCase(Locale.ENGLISH).contains("OS X")) {
|
||||
Credentials creds = acquireDefaultCreds();
|
||||
if (creds == null) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Found no TGT's in LSA");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (princ != null) {
|
||||
if (creds.getClient().equals(princ)) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Obtained TGT from LSA: "
|
||||
+ creds);
|
||||
}
|
||||
return creds;
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> LSA contains TGT for "
|
||||
+ creds.getClient()
|
||||
+ " not "
|
||||
+ princ);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Obtained TGT from LSA: "
|
||||
+ creds);
|
||||
}
|
||||
return creds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the appropriate cache. If ticketCache is null, it is the
|
||||
* default cache otherwise it is the cache filename contained in it.
|
||||
*/
|
||||
CredentialsCache ccache =
|
||||
CredentialsCache.getInstance(princ, ticketCache);
|
||||
|
||||
if (ccache == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Credentials tgtCred = ccache.getInitialCreds();
|
||||
|
||||
if (tgtCred == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (EType.isSupported(tgtCred.key.getEType())) {
|
||||
return tgtCred;
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.println(
|
||||
">>> unsupported key type found the default TGT: " +
|
||||
tgtCred.key.getEType());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires default credentials.
|
||||
* <br>The possible locations for default credentials cache is searched in
|
||||
* the following order:
|
||||
* <ol>
|
||||
* <li> The directory and cache file name specified by "KRB5CCNAME" system.
|
||||
* property.
|
||||
* <li> The directory and cache file name specified by "KRB5CCNAME"
|
||||
* environment variable.
|
||||
* <li> A cache file named krb5cc_{user.name} at {user.home} directory.
|
||||
* </ol>
|
||||
* @return a <code>KrbCreds</code> object if the credential is found,
|
||||
* otherwise return null.
|
||||
*/
|
||||
|
||||
// this method is intentionally changed to not check if the caller's
|
||||
// principal name matches cache file's principal name.
|
||||
// It assumes that the GSS call has
|
||||
// the privilege to access the default cache file.
|
||||
|
||||
// This method is only called on Windows and Mac OS X, the native
|
||||
// acquireDefaultNativeCreds is also available on these platforms.
|
||||
public static synchronized Credentials acquireDefaultCreds() {
|
||||
Credentials result = null;
|
||||
|
||||
if (cache == null) {
|
||||
cache = CredentialsCache.getInstance();
|
||||
}
|
||||
if (cache != null) {
|
||||
Credentials temp = cache.getInitialCreds();
|
||||
if (temp != null) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KrbCreds found the default ticket"
|
||||
+ " granting ticket in credential cache.");
|
||||
}
|
||||
if (EType.isSupported(temp.key.getEType())) {
|
||||
result = temp;
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.println(
|
||||
">>> unsupported key type found the default TGT: " +
|
||||
temp.key.getEType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result == null) {
|
||||
// Doesn't seem to be a default cache on this system or
|
||||
// TGT has unsupported encryption type
|
||||
|
||||
if (!alreadyTried) {
|
||||
// See if there's any native code to load
|
||||
try {
|
||||
ensureLoaded();
|
||||
} catch (Exception e) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Can not load credentials cache");
|
||||
e.printStackTrace();
|
||||
}
|
||||
alreadyTried = true;
|
||||
}
|
||||
}
|
||||
if (alreadyLoaded) {
|
||||
// There is some native code
|
||||
if (DEBUG) {
|
||||
System.out.println(">> Acquire default native Credentials");
|
||||
}
|
||||
try {
|
||||
result = acquireDefaultNativeCreds(
|
||||
EType.getDefaults("default_tkt_enctypes"));
|
||||
} catch (KrbException ke) {
|
||||
// when there is no default_tkt_enctypes.
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires credentials for a specified service using initial credential.
|
||||
* When the service has a different realm
|
||||
* from the initial credential, we do cross-realm authentication
|
||||
* - first, we use the current credential to get
|
||||
* a cross-realm credential from the local KDC, then use that
|
||||
* cross-realm credential to request service credential
|
||||
* from the foreigh KDC.
|
||||
*
|
||||
* @param service the name of service principal using format
|
||||
* components@realm
|
||||
* @param ccreds client's initial credential.
|
||||
* @exception IOException if an error occurs in reading the credentials
|
||||
* cache
|
||||
* @exception KrbException if an error occurs specific to Kerberos
|
||||
* @return a <code>Credentials</code> object.
|
||||
*/
|
||||
|
||||
public static Credentials acquireServiceCreds(String service,
|
||||
Credentials ccreds)
|
||||
throws KrbException, IOException {
|
||||
return CredentialsUtil.acquireServiceCreds(service, ccreds);
|
||||
}
|
||||
|
||||
public static Credentials acquireS4U2selfCreds(PrincipalName user,
|
||||
Credentials ccreds) throws KrbException, IOException {
|
||||
return CredentialsUtil.acquireS4U2selfCreds(user, ccreds);
|
||||
}
|
||||
|
||||
public static Credentials acquireS4U2proxyCreds(String service,
|
||||
Ticket second, PrincipalName client, Credentials ccreds)
|
||||
throws KrbException, IOException {
|
||||
return CredentialsUtil.acquireS4U2proxyCreds(
|
||||
service, second, client, ccreds);
|
||||
}
|
||||
|
||||
public CredentialsCache getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints out debug info.
|
||||
*/
|
||||
public static void printDebug(Credentials c) {
|
||||
System.out.println(">>> DEBUG: ----Credentials----");
|
||||
System.out.println("\tclient: " + c.client.toString());
|
||||
if (c.clientAlias != null)
|
||||
System.out.println("\tclient alias: " + c.clientAlias.toString());
|
||||
System.out.println("\tserver: " + c.server.toString());
|
||||
if (c.serverAlias != null)
|
||||
System.out.println("\tserver alias: " + c.serverAlias.toString());
|
||||
System.out.println("\tticket: sname: " + c.ticket.sname.toString());
|
||||
if (c.startTime != null) {
|
||||
System.out.println("\tstartTime: " + c.startTime.getTime());
|
||||
}
|
||||
System.out.println("\tendTime: " + c.endTime.getTime());
|
||||
System.out.println(" ----Credentials end----");
|
||||
}
|
||||
|
||||
|
||||
static void ensureLoaded() {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void> () {
|
||||
public Void run() {
|
||||
if (System.getProperty("os.name").contains("OS X")) {
|
||||
System.loadLibrary("osxkrb5");
|
||||
} else {
|
||||
System.loadLibrary("w2k_lsa_auth");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
alreadyLoaded = true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer("Credentials:");
|
||||
buffer.append( "\n client=").append(client);
|
||||
if (clientAlias != null)
|
||||
buffer.append( "\n clientAlias=").append(clientAlias);
|
||||
buffer.append( "\n server=").append(server);
|
||||
if (serverAlias != null)
|
||||
buffer.append( "\n serverAlias=").append(serverAlias);
|
||||
if (authTime != null) {
|
||||
buffer.append("\n authTime=").append(authTime);
|
||||
}
|
||||
if (startTime != null) {
|
||||
buffer.append("\n startTime=").append(startTime);
|
||||
}
|
||||
buffer.append( "\n endTime=").append(endTime);
|
||||
buffer.append( "\n renewTill=").append(renewTill);
|
||||
buffer.append( "\n flags=").append(flags);
|
||||
buffer.append( "\nEType (skey)=").append(key.getEType());
|
||||
buffer.append( "\n (tkt key)=").append(ticket.encPart.eType);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public sun.security.krb5.internal.ccache.Credentials toCCacheCreds() {
|
||||
return new sun.security.krb5.internal.ccache.Credentials(
|
||||
getClient(), getServer(),
|
||||
getSessionKey(),
|
||||
date2kt(getAuthTime()),
|
||||
date2kt(getStartTime()),
|
||||
date2kt(getEndTime()),
|
||||
date2kt(getRenewTill()),
|
||||
false,
|
||||
flags,
|
||||
new HostAddresses(getClientAddresses()),
|
||||
getAuthzData(),
|
||||
getTicket(),
|
||||
null);
|
||||
}
|
||||
|
||||
private static KerberosTime date2kt(Date d) {
|
||||
return d == null ? null : new KerberosTime(d);
|
||||
}
|
||||
}
|
||||
380
jdkSrc/jdk8/sun/security/krb5/EncryptedData.java
Normal file
380
jdkSrc/jdk8/sun/security/krb5/EncryptedData.java
Normal file
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* This class encapsulates Kerberos encrypted data. It allows
|
||||
* callers access to both the ASN.1 encoded form of the EncryptedData
|
||||
* type as well as the raw cipher text.
|
||||
*/
|
||||
|
||||
public class EncryptedData implements Cloneable {
|
||||
int eType;
|
||||
Integer kvno; // optional
|
||||
byte[] cipher;
|
||||
byte[] plain; // not part of ASN.1 encoding
|
||||
|
||||
// ----------------+-----------+----------+----------------+---------------
|
||||
// Encryption type |etype value|block size|minimum pad size|confounder size
|
||||
// ----------------+-----------+----------+----------------+---------------
|
||||
public static final int
|
||||
ETYPE_NULL = 0; // 1 0 0
|
||||
public static final int
|
||||
ETYPE_DES_CBC_CRC = 1; // 8 4 8
|
||||
public static final int
|
||||
ETYPE_DES_CBC_MD4 = 2; // 8 0 8
|
||||
public static final int
|
||||
ETYPE_DES_CBC_MD5 = 3; // 8 0 8
|
||||
|
||||
// draft-brezak-win2k-krb-rc4-hmac-04.txt
|
||||
public static final int
|
||||
ETYPE_ARCFOUR_HMAC = 23; // 1
|
||||
// NOTE: the exportable RC4-HMAC is not supported;
|
||||
// it is no longer a usable encryption type
|
||||
public static final int
|
||||
ETYPE_ARCFOUR_HMAC_EXP = 24; // 1
|
||||
|
||||
// draft-ietf-krb-wg-crypto-07.txt
|
||||
public static final int
|
||||
ETYPE_DES3_CBC_HMAC_SHA1_KD = 16; // 8 0 8
|
||||
|
||||
// draft-raeburn-krb-rijndael-krb-07.txt
|
||||
public static final int
|
||||
ETYPE_AES128_CTS_HMAC_SHA1_96 = 17; // 16 0 16
|
||||
public static final int
|
||||
ETYPE_AES256_CTS_HMAC_SHA1_96 = 18; // 16 0 16
|
||||
|
||||
/* used by self */
|
||||
private EncryptedData() {
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
EncryptedData new_encryptedData = new EncryptedData();
|
||||
new_encryptedData.eType = eType;
|
||||
if (kvno != null) {
|
||||
new_encryptedData.kvno = new Integer(kvno.intValue());
|
||||
}
|
||||
if (cipher != null) {
|
||||
new_encryptedData.cipher = new byte[cipher.length];
|
||||
System.arraycopy(cipher, 0, new_encryptedData.cipher,
|
||||
0, cipher.length);
|
||||
}
|
||||
return new_encryptedData;
|
||||
}
|
||||
|
||||
// Used in JSSE (com.sun.net.ssl.internal.KerberosPreMasterSecret)
|
||||
public EncryptedData(
|
||||
int new_eType,
|
||||
Integer new_kvno,
|
||||
byte[] new_cipher) {
|
||||
eType = new_eType;
|
||||
kvno = new_kvno;
|
||||
cipher = new_cipher;
|
||||
}
|
||||
|
||||
/*
|
||||
// Not used.
|
||||
public EncryptedData(
|
||||
EncryptionKey key,
|
||||
byte[] plaintext)
|
||||
throws KdcErrException, KrbCryptoException {
|
||||
EType etypeEngine = EType.getInstance(key.getEType());
|
||||
cipher = etypeEngine.encrypt(plaintext, key.getBytes());
|
||||
eType = key.getEType();
|
||||
kvno = key.getKeyVersionNumber();
|
||||
}
|
||||
*/
|
||||
|
||||
// used in KrbApRep, KrbApReq, KrbAsReq, KrbCred, KrbPriv
|
||||
// Used in JSSE (com.sun.net.ssl.internal.KerberosPreMasterSecret)
|
||||
public EncryptedData(
|
||||
EncryptionKey key,
|
||||
byte[] plaintext,
|
||||
int usage)
|
||||
throws KdcErrException, KrbCryptoException {
|
||||
EType etypeEngine = EType.getInstance(key.getEType());
|
||||
cipher = etypeEngine.encrypt(plaintext, key.getBytes(), usage);
|
||||
eType = key.getEType();
|
||||
kvno = key.getKeyVersionNumber();
|
||||
}
|
||||
|
||||
/*
|
||||
// Not used.
|
||||
public EncryptedData(
|
||||
EncryptionKey key,
|
||||
byte[] ivec,
|
||||
byte[] plaintext)
|
||||
throws KdcErrException, KrbCryptoException {
|
||||
EType etypeEngine = EType.getInstance(key.getEType());
|
||||
cipher = etypeEngine.encrypt(plaintext, key.getBytes(), ivec);
|
||||
eType = key.getEType();
|
||||
kvno = key.getKeyVersionNumber();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// Not used.
|
||||
EncryptedData(
|
||||
StringBuffer password,
|
||||
byte[] plaintext)
|
||||
throws KdcErrException, KrbCryptoException {
|
||||
EncryptionKey key = new EncryptionKey(password);
|
||||
EType etypeEngine = EType.getInstance(key.getEType());
|
||||
cipher = etypeEngine.encrypt(plaintext, key.getBytes());
|
||||
eType = key.getEType();
|
||||
kvno = key.getKeyVersionNumber();
|
||||
}
|
||||
*/
|
||||
public byte[] decrypt(
|
||||
EncryptionKey key, int usage)
|
||||
throws KdcErrException, KrbApErrException, KrbCryptoException {
|
||||
if (eType != key.getEType()) {
|
||||
throw new KrbCryptoException(
|
||||
"EncryptedData is encrypted using keytype " +
|
||||
EType.toString(eType) +
|
||||
" but decryption key is of type " +
|
||||
EType.toString(key.getEType()));
|
||||
}
|
||||
|
||||
EType etypeEngine = EType.getInstance(eType);
|
||||
plain = etypeEngine.decrypt(cipher, key.getBytes(), usage);
|
||||
// The service ticket will be used in S4U2proxy request. Therefore
|
||||
// the raw ticket is still needed.
|
||||
//cipher = null;
|
||||
return etypeEngine.decryptedData(plain);
|
||||
}
|
||||
|
||||
/*
|
||||
// currently destructive on cipher
|
||||
// Not used.
|
||||
public byte[] decrypt(
|
||||
EncryptionKey key,
|
||||
byte[] ivec, int usage)
|
||||
throws KdcErrException, KrbApErrException, KrbCryptoException {
|
||||
// XXX check for matching eType and kvno here
|
||||
EType etypeEngine = EType.getInstance(eType);
|
||||
plain = etypeEngine.decrypt(cipher, key.getBytes(), ivec, usage);
|
||||
cipher = null;
|
||||
return etypeEngine.decryptedData(plain);
|
||||
}
|
||||
|
||||
// currently destructive on cipher
|
||||
// Not used.
|
||||
byte[] decrypt(StringBuffer password)
|
||||
throws KdcErrException, KrbApErrException, KrbCryptoException {
|
||||
EncryptionKey key = new EncryptionKey(password);
|
||||
// XXX check for matching eType here
|
||||
EType etypeEngine = EType.getInstance(eType);
|
||||
plain = etypeEngine.decrypt(cipher, key.getBytes());
|
||||
cipher = null;
|
||||
return etypeEngine.decryptedData(plain);
|
||||
}
|
||||
*/
|
||||
|
||||
private byte[] decryptedData() throws KdcErrException {
|
||||
if (plain != null) {
|
||||
EType etypeEngine = EType.getInstance(eType);
|
||||
return etypeEngine.decryptedData(plain);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of EncryptedData type.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an
|
||||
* ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded
|
||||
* data.
|
||||
*
|
||||
*/
|
||||
/* Used by self */
|
||||
private EncryptedData(DerValue encoding)
|
||||
throws Asn1Exception, IOException {
|
||||
|
||||
DerValue der = null;
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x00) {
|
||||
eType = (der.getData().getBigInteger()).intValue();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
if ((encoding.getData().peekByte() & 0x1F) == 1) {
|
||||
der = encoding.getData().getDerValue();
|
||||
int i = (der.getData().getBigInteger()).intValue();
|
||||
kvno = new Integer(i);
|
||||
} else {
|
||||
kvno = null;
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x02) {
|
||||
cipher = der.getData().getOctetString();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if (encoding.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ASN.1 encoded EncryptedData type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* EncryptedData ::= SEQUENCE {
|
||||
* etype [0] Int32 -- EncryptionType --,
|
||||
* kvno [1] UInt32 OPTIONAL,
|
||||
* cipher [2] OCTET STRING -- ciphertext
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*
|
||||
* @return byte array of encoded EncryptedData object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an
|
||||
* ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading
|
||||
* encoded data.
|
||||
*
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(this.eType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte)0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
if (kvno != null) {
|
||||
// encode as an unsigned integer (UInt32)
|
||||
temp.putInteger(BigInteger.valueOf(this.kvno.longValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte)0x01), temp);
|
||||
temp = new DerOutputStream();
|
||||
}
|
||||
temp.putOctetString(this.cipher);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
(byte)0x02), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) an EncryptedData from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @param data the Der input stream value, which contains one or more
|
||||
* marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicate if this data field is optional
|
||||
* @exception Asn1Exception if an error occurs while decoding an
|
||||
* ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading
|
||||
* encoded data.
|
||||
* @return an instance of EncryptedData.
|
||||
*
|
||||
*/
|
||||
public static EncryptedData parse(DerInputStream data,
|
||||
byte explicitTag,
|
||||
boolean optional)
|
||||
throws Asn1Exception, IOException {
|
||||
if ((optional) &&
|
||||
(((byte)data.peekByte() & (byte)0x1F) != explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
} else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new EncryptedData(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset asn.1 data stream after decryption, remove redundant bytes.
|
||||
* @param data the decrypted data from decrypt().
|
||||
* @return the reset byte array which holds exactly one asn1 datum
|
||||
* including its tag and length.
|
||||
*
|
||||
*/
|
||||
public byte[] reset(byte[] data) {
|
||||
byte[] bytes = null;
|
||||
// for asn.1 encoded data, we use length field to
|
||||
// determine the data length and remove redundant paddings.
|
||||
if ((data[1] & 0xFF) < 128) {
|
||||
bytes = new byte[data[1] + 2];
|
||||
System.arraycopy(data, 0, bytes, 0, data[1] + 2);
|
||||
} else {
|
||||
if ((data[1] & 0xFF) > 128) {
|
||||
int len = data[1] & (byte)0x7F;
|
||||
int result = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
result |= (data[i + 2] & 0xFF) << (8 * (len - i - 1));
|
||||
}
|
||||
bytes = new byte[result + len + 2];
|
||||
System.arraycopy(data, 0, bytes, 0, result + len + 2);
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public int getEType() {
|
||||
return eType;
|
||||
}
|
||||
|
||||
public Integer getKeyVersionNumber() {
|
||||
return kvno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw cipher text bytes, not in ASN.1 encoding.
|
||||
*/
|
||||
public byte[] getBytes() {
|
||||
return cipher;
|
||||
}
|
||||
}
|
||||
572
jdkSrc/jdk8/sun/security/krb5/EncryptionKey.java
Normal file
572
jdkSrc/jdk8/sun/security/krb5/EncryptionKey.java
Normal file
@@ -0,0 +1,572 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.jgss.krb5.Krb5Util;
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Arrays;
|
||||
import sun.security.krb5.internal.ktab.KeyTab;
|
||||
import sun.security.krb5.internal.ccache.CCacheOutputStream;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import javax.crypto.spec.DESedeKeySpec;
|
||||
|
||||
/**
|
||||
* This class encapsulates the concept of an EncryptionKey. An encryption
|
||||
* key is defined in RFC 4120 as:
|
||||
*
|
||||
* EncryptionKey ::= SEQUENCE {
|
||||
* keytype [0] Int32 -- actually encryption type --,
|
||||
* keyvalue [1] OCTET STRING
|
||||
* }
|
||||
*
|
||||
* keytype
|
||||
* This field specifies the encryption type of the encryption key
|
||||
* that follows in the keyvalue field. Although its name is
|
||||
* "keytype", it actually specifies an encryption type. Previously,
|
||||
* multiple cryptosystems that performed encryption differently but
|
||||
* were capable of using keys with the same characteristics were
|
||||
* permitted to share an assigned number to designate the type of
|
||||
* key; this usage is now deprecated.
|
||||
*
|
||||
* keyvalue
|
||||
* This field contains the key itself, encoded as an octet string.
|
||||
*/
|
||||
|
||||
public class EncryptionKey
|
||||
implements Cloneable {
|
||||
|
||||
public static final EncryptionKey NULL_KEY =
|
||||
new EncryptionKey(new byte[] {}, EncryptedData.ETYPE_NULL, null);
|
||||
|
||||
private int keyType;
|
||||
private byte[] keyValue;
|
||||
private Integer kvno; // not part of ASN1 encoding;
|
||||
|
||||
private static final boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public synchronized int getEType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
public final Integer getKeyVersionNumber() {
|
||||
return kvno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw key bytes, not in any ASN.1 encoding.
|
||||
*/
|
||||
public final byte[] getBytes() {
|
||||
// This method cannot be called outside sun.security, hence no
|
||||
// cloning. getEncoded() calls this method.
|
||||
return keyValue;
|
||||
}
|
||||
|
||||
public synchronized Object clone() {
|
||||
return new EncryptionKey(keyValue, keyType, kvno);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains all versions of the secret key of the principal from a
|
||||
* keytab.
|
||||
*
|
||||
* @param princ the principal whose secret key is desired
|
||||
* @param keytab the path to the keytab file. A value of null
|
||||
* will be accepted to indicate that the default path should be
|
||||
* searched.
|
||||
* @return an array of secret keys or null if none were found.
|
||||
*/
|
||||
public static EncryptionKey[] acquireSecretKeys(PrincipalName princ,
|
||||
String keytab) {
|
||||
|
||||
if (princ == null)
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot have null pricipal name to look in keytab.");
|
||||
|
||||
// KeyTab getInstance(keytab) will call KeyTab.getInstance()
|
||||
// if keytab is null
|
||||
KeyTab ktab = KeyTab.getInstance(keytab);
|
||||
return ktab.readServiceKeys(princ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a key for a given etype of a principal with possible new salt
|
||||
* and s2kparams
|
||||
* @param cname NOT null
|
||||
* @param password NOT null
|
||||
* @param etype
|
||||
* @param snp can be NULL
|
||||
* @return never null
|
||||
*/
|
||||
public static EncryptionKey acquireSecretKey(PrincipalName cname,
|
||||
char[] password, int etype, PAData.SaltAndParams snp)
|
||||
throws KrbException {
|
||||
String salt;
|
||||
byte[] s2kparams;
|
||||
if (snp != null) {
|
||||
salt = snp.salt != null ? snp.salt : cname.getSalt();
|
||||
s2kparams = snp.params;
|
||||
} else {
|
||||
salt = cname.getSalt();
|
||||
s2kparams = null;
|
||||
}
|
||||
return acquireSecretKey(password, salt, etype, s2kparams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a key for a given etype with salt and optional s2kparams
|
||||
* @param password NOT null
|
||||
* @param salt NOT null
|
||||
* @param etype
|
||||
* @param s2kparams can be NULL
|
||||
* @return never null
|
||||
*/
|
||||
public static EncryptionKey acquireSecretKey(char[] password,
|
||||
String salt, int etype, byte[] s2kparams)
|
||||
throws KrbException {
|
||||
|
||||
return new EncryptionKey(
|
||||
stringToKey(password, salt, s2kparams, etype),
|
||||
etype, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a list of keys using the given principal and password.
|
||||
* Construct a key for each configured etype.
|
||||
* Caller is responsible for clearing password.
|
||||
*/
|
||||
/*
|
||||
* Usually, when keyType is decoded from ASN.1 it will contain a
|
||||
* value indicating what the algorithm to be used is. However, when
|
||||
* converting from a password to a key for the AS-EXCHANGE, this
|
||||
* keyType will not be available. Use builtin list of default etypes
|
||||
* as the default in that case. If default_tkt_enctypes was set in
|
||||
* the libdefaults of krb5.conf, then use that sequence.
|
||||
*/
|
||||
public static EncryptionKey[] acquireSecretKeys(char[] password,
|
||||
String salt) throws KrbException {
|
||||
|
||||
int[] etypes = EType.getDefaults("default_tkt_enctypes");
|
||||
|
||||
EncryptionKey[] encKeys = new EncryptionKey[etypes.length];
|
||||
for (int i = 0; i < etypes.length; i++) {
|
||||
if (EType.isSupported(etypes[i])) {
|
||||
encKeys[i] = new EncryptionKey(
|
||||
stringToKey(password, salt, null, etypes[i]),
|
||||
etypes[i], null);
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.println("Encryption Type " +
|
||||
EType.toString(etypes[i]) +
|
||||
" is not supported/enabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
return encKeys;
|
||||
}
|
||||
|
||||
// Used in Krb5AcceptCredential, self
|
||||
public EncryptionKey(byte[] keyValue,
|
||||
int keyType,
|
||||
Integer kvno) {
|
||||
|
||||
if (keyValue != null) {
|
||||
this.keyValue = new byte[keyValue.length];
|
||||
System.arraycopy(keyValue, 0, this.keyValue, 0, keyValue.length);
|
||||
} else {
|
||||
throw new IllegalArgumentException("EncryptionKey: " +
|
||||
"Key bytes cannot be null!");
|
||||
}
|
||||
this.keyType = keyType;
|
||||
this.kvno = kvno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an EncryptionKey by using the specified key type and key
|
||||
* value. It is used to recover the key when retrieving data from
|
||||
* credential cache file.
|
||||
*
|
||||
*/
|
||||
// Used in JSSE (KerberosWrapper), Credentials,
|
||||
// javax.security.auth.kerberos.KeyImpl
|
||||
public EncryptionKey(int keyType,
|
||||
byte[] keyValue) {
|
||||
this(keyValue, keyType, null);
|
||||
}
|
||||
|
||||
private static byte[] stringToKey(char[] password, String salt,
|
||||
byte[] s2kparams, int keyType) throws KrbCryptoException {
|
||||
|
||||
char[] slt = salt.toCharArray();
|
||||
char[] pwsalt = new char[password.length + slt.length];
|
||||
System.arraycopy(password, 0, pwsalt, 0, password.length);
|
||||
System.arraycopy(slt, 0, pwsalt, password.length, slt.length);
|
||||
Arrays.fill(slt, '0');
|
||||
|
||||
try {
|
||||
switch (keyType) {
|
||||
case EncryptedData.ETYPE_DES_CBC_CRC:
|
||||
case EncryptedData.ETYPE_DES_CBC_MD5:
|
||||
return Des.string_to_key_bytes(pwsalt);
|
||||
|
||||
case EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD:
|
||||
return Des3.stringToKey(pwsalt);
|
||||
|
||||
case EncryptedData.ETYPE_ARCFOUR_HMAC:
|
||||
return ArcFourHmac.stringToKey(password);
|
||||
|
||||
case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
|
||||
return Aes128.stringToKey(password, salt, s2kparams);
|
||||
|
||||
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
|
||||
return Aes256.stringToKey(password, salt, s2kparams);
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("encryption type " +
|
||||
EType.toString(keyType) + " not supported");
|
||||
}
|
||||
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
} finally {
|
||||
Arrays.fill(pwsalt, '0');
|
||||
}
|
||||
}
|
||||
|
||||
// Used in javax.security.auth.kerberos.KeyImpl
|
||||
public EncryptionKey(char[] password,
|
||||
String salt,
|
||||
String algorithm) throws KrbCryptoException {
|
||||
|
||||
if (algorithm == null || algorithm.equalsIgnoreCase("DES")) {
|
||||
keyType = EncryptedData.ETYPE_DES_CBC_MD5;
|
||||
} else if (algorithm.equalsIgnoreCase("DESede")) {
|
||||
keyType = EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD;
|
||||
} else if (algorithm.equalsIgnoreCase("AES128")) {
|
||||
keyType = EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96;
|
||||
} else if (algorithm.equalsIgnoreCase("ArcFourHmac")) {
|
||||
keyType = EncryptedData.ETYPE_ARCFOUR_HMAC;
|
||||
} else if (algorithm.equalsIgnoreCase("AES256")) {
|
||||
keyType = EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96;
|
||||
// validate if AES256 is enabled
|
||||
if (!EType.isSupported(keyType)) {
|
||||
throw new IllegalArgumentException("Algorithm " + algorithm +
|
||||
" not enabled");
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Algorithm " + algorithm +
|
||||
" not supported");
|
||||
}
|
||||
|
||||
keyValue = stringToKey(password, salt, null, keyType);
|
||||
kvno = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a sub-sessionkey from a given session key.
|
||||
*
|
||||
* Used in AcceptSecContextToken and KrbApReq by acceptor- and initiator-
|
||||
* side respectively.
|
||||
*/
|
||||
public EncryptionKey(EncryptionKey key) throws KrbCryptoException {
|
||||
// generate random sub-session key
|
||||
keyValue = Confounder.bytes(key.keyValue.length);
|
||||
for (int i = 0; i < keyValue.length; i++) {
|
||||
keyValue[i] ^= key.keyValue[i];
|
||||
}
|
||||
keyType = key.keyType;
|
||||
|
||||
// check for key parity and weak keys
|
||||
try {
|
||||
// check for DES key
|
||||
if ((keyType == EncryptedData.ETYPE_DES_CBC_MD5) ||
|
||||
(keyType == EncryptedData.ETYPE_DES_CBC_CRC)) {
|
||||
// fix DES key parity
|
||||
if (!DESKeySpec.isParityAdjusted(keyValue, 0)) {
|
||||
keyValue = Des.set_parity(keyValue);
|
||||
}
|
||||
// check for weak key
|
||||
if (DESKeySpec.isWeak(keyValue, 0)) {
|
||||
keyValue[7] = (byte)(keyValue[7] ^ 0xF0);
|
||||
}
|
||||
}
|
||||
// check for 3DES key
|
||||
if (keyType == EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD) {
|
||||
// fix 3DES key parity
|
||||
if (!DESedeKeySpec.isParityAdjusted(keyValue, 0)) {
|
||||
keyValue = Des3.parityFix(keyValue);
|
||||
}
|
||||
// check for weak keys
|
||||
byte[] oneKey = new byte[8];
|
||||
for (int i=0; i<keyValue.length; i+=8) {
|
||||
System.arraycopy(keyValue, i, oneKey, 0, 8);
|
||||
if (DESKeySpec.isWeak(oneKey, 0)) {
|
||||
keyValue[i+7] = (byte)(keyValue[i+7] ^ 0xF0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of EncryptionKey type.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1
|
||||
* encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded
|
||||
* data.
|
||||
*
|
||||
*
|
||||
*/
|
||||
// Used in javax.security.auth.kerberos.KeyImpl
|
||||
public EncryptionKey(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der;
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x00) {
|
||||
keyType = der.getData().getBigInteger().intValue();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x01) {
|
||||
keyValue = der.getData().getOctetString();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ASN.1 encoding of this EncryptionKey.
|
||||
*
|
||||
* <pre>{@code
|
||||
* EncryptionKey ::= SEQUENCE {
|
||||
* keytype[0] INTEGER,
|
||||
* keyvalue[1] OCTET STRING }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*
|
||||
* @return byte array of encoded EncryptionKey object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1
|
||||
* encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded
|
||||
* data.
|
||||
*
|
||||
*/
|
||||
public synchronized byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(keyType);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
(byte)0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putOctetString(keyValue);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
(byte)0x01), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
public synchronized void destroy() {
|
||||
if (keyValue != null)
|
||||
for (int i = 0; i < keyValue.length; i++)
|
||||
keyValue[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) an Encryption key from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @param data the Der input stream value, which contains one or more
|
||||
* marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicate if this data field is optional
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1
|
||||
* encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded
|
||||
* data.
|
||||
* @return an instance of EncryptionKey.
|
||||
*
|
||||
*/
|
||||
public static EncryptionKey parse(DerInputStream data, byte
|
||||
explicitTag, boolean optional) throws
|
||||
Asn1Exception, IOException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F) !=
|
||||
explicitTag)) {
|
||||
return null;
|
||||
}
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
} else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new EncryptionKey(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes key value in FCC format to a <code>CCacheOutputStream</code>.
|
||||
*
|
||||
* @param cos a <code>CCacheOutputStream</code> to be written to.
|
||||
* @exception IOException if an I/O exception occurs.
|
||||
* @see sun.security.krb5.internal.ccache.CCacheOutputStream
|
||||
*
|
||||
*/
|
||||
public synchronized void writeKey(CCacheOutputStream cos)
|
||||
throws IOException {
|
||||
|
||||
cos.write16(keyType);
|
||||
// we use KRB5_FCC_FVNO_3
|
||||
cos.write16(keyType); // key type is recorded twice.
|
||||
cos.write32(keyValue.length);
|
||||
for (int i = 0; i < keyValue.length; i++) {
|
||||
cos.write8(keyValue[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new String("EncryptionKey: keyType=" + keyType
|
||||
+ ", kvno=" + kvno + ", " + Krb5Util.keyInfo(keyValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a key with given etype
|
||||
*/
|
||||
public static EncryptionKey findKey(int etype, EncryptionKey[] keys)
|
||||
throws KrbException {
|
||||
return findKey(etype, null, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a kvno matches another kvno. Used in the method
|
||||
* findKey(type, kvno, keys). Always returns true if either input
|
||||
* is null or zero, in case any side does not have kvno info available.
|
||||
*
|
||||
* Note: zero is included because N/A is not a legal value for kvno
|
||||
* in javax.security.auth.kerberos.KerberosKey. Therefore, the info
|
||||
* that the kvno is N/A might be lost when converting between this
|
||||
* class and KerberosKey.
|
||||
*/
|
||||
private static boolean versionMatches(Integer v1, Integer v2) {
|
||||
if (v1 == null || v1 == 0 || v2 == null || v2 == 0) {
|
||||
return true;
|
||||
}
|
||||
return v1.equals(v2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a key with given etype and kvno
|
||||
* @param kvno if null, return any (first?) key
|
||||
*/
|
||||
public static EncryptionKey findKey(int etype, Integer kvno, EncryptionKey[] keys)
|
||||
throws KrbException {
|
||||
|
||||
// check if encryption type is supported
|
||||
if (!EType.isSupported(etype)) {
|
||||
throw new KrbException("Encryption type " +
|
||||
EType.toString(etype) + " is not supported/enabled");
|
||||
}
|
||||
|
||||
int ktype;
|
||||
boolean etypeFound = false;
|
||||
|
||||
// When no matched kvno is found, returns tke key of the same
|
||||
// etype with the highest kvno
|
||||
int kvno_found = 0;
|
||||
EncryptionKey key_found = null;
|
||||
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
ktype = keys[i].getEType();
|
||||
if (EType.isSupported(ktype)) {
|
||||
Integer kv = keys[i].getKeyVersionNumber();
|
||||
if (etype == ktype) {
|
||||
etypeFound = true;
|
||||
if (versionMatches(kvno, kv)) {
|
||||
return keys[i];
|
||||
} else if (kv > kvno_found) {
|
||||
// kv is not null
|
||||
key_found = keys[i];
|
||||
kvno_found = kv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Key not found.
|
||||
// allow DES key to be used for the DES etypes
|
||||
if ((etype == EncryptedData.ETYPE_DES_CBC_CRC ||
|
||||
etype == EncryptedData.ETYPE_DES_CBC_MD5)) {
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
ktype = keys[i].getEType();
|
||||
if (ktype == EncryptedData.ETYPE_DES_CBC_CRC ||
|
||||
ktype == EncryptedData.ETYPE_DES_CBC_MD5) {
|
||||
Integer kv = keys[i].getKeyVersionNumber();
|
||||
etypeFound = true;
|
||||
if (versionMatches(kvno, kv)) {
|
||||
return new EncryptionKey(etype, keys[i].getBytes());
|
||||
} else if (kv > kvno_found) {
|
||||
key_found = new EncryptionKey(etype, keys[i].getBytes());
|
||||
kvno_found = kv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (etypeFound) {
|
||||
return key_found;
|
||||
// For compatibility, will not fail here.
|
||||
//throw new KrbException(Krb5.KRB_AP_ERR_BADKEYVER);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2019, 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 sun.security.krb5;
|
||||
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
import javax.security.auth.kerberos.KerberosTicket;
|
||||
import javax.security.auth.kerberos.KeyTab;
|
||||
|
||||
/**
|
||||
* An unsafe tunnel to get non-public access to classes in the
|
||||
* javax.security.auth.kerberos package.
|
||||
*/
|
||||
public interface JavaxSecurityAuthKerberosAccess {
|
||||
/**
|
||||
* Returns a snapshot to the backing keytab
|
||||
*/
|
||||
public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot(
|
||||
KeyTab ktab);
|
||||
|
||||
public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t);
|
||||
|
||||
public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a);
|
||||
|
||||
public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t);
|
||||
|
||||
public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a);
|
||||
|
||||
/**
|
||||
* Returns the proxy for a KerberosTicket.
|
||||
*/
|
||||
public KerberosTicket kerberosTicketGetProxy(KerberosTicket t);
|
||||
|
||||
/**
|
||||
* Sets the proxy for a KerberosTicket.
|
||||
*/
|
||||
public void kerberosTicketSetProxy(KerberosTicket t, KerberosTicket p);
|
||||
}
|
||||
555
jdkSrc/jdk8/sun/security/krb5/KdcComm.java
Normal file
555
jdkSrc/jdk8/sun/security/krb5/KdcComm.java
Normal file
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.Security;
|
||||
import java.util.Locale;
|
||||
import sun.security.krb5.internal.Krb5;
|
||||
import sun.security.krb5.internal.NetClient;
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.StringTokenizer;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import sun.security.krb5.internal.KRBError;
|
||||
|
||||
/**
|
||||
* KDC-REQ/KDC-REP communication. No more base class for KrbAsReq and
|
||||
* KrbTgsReq. This class is now communication only.
|
||||
*/
|
||||
public final class KdcComm {
|
||||
|
||||
// The following settings can be configured in [libdefaults]
|
||||
// section of krb5.conf, which are global for all realms. Each of
|
||||
// them can also be defined in a realm, which overrides value here.
|
||||
|
||||
/**
|
||||
* max retry time for a single KDC, default Krb5.KDC_RETRY_LIMIT (3)
|
||||
*/
|
||||
private static int defaultKdcRetryLimit;
|
||||
/**
|
||||
* timeout requesting a ticket from KDC, in millisec, default 30 sec
|
||||
*/
|
||||
private static int defaultKdcTimeout;
|
||||
/**
|
||||
* max UDP packet size, default unlimited (-1)
|
||||
*/
|
||||
private static int defaultUdpPrefLimit;
|
||||
|
||||
private static final boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
private static final String BAD_POLICY_KEY = "krb5.kdc.bad.policy";
|
||||
|
||||
/**
|
||||
* What to do when a KDC is unavailable, specified in the
|
||||
* java.security file with key krb5.kdc.bad.policy.
|
||||
* Possible values can be TRY_LAST or TRY_LESS. Reloaded when refreshed.
|
||||
*/
|
||||
private enum BpType {
|
||||
NONE, TRY_LAST, TRY_LESS
|
||||
}
|
||||
private static int tryLessMaxRetries = 1;
|
||||
private static int tryLessTimeout = 5000;
|
||||
|
||||
private static BpType badPolicy;
|
||||
|
||||
static {
|
||||
initStatic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read global settings
|
||||
*/
|
||||
public static void initStatic() {
|
||||
String value = AccessController.doPrivileged(
|
||||
new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return Security.getProperty(BAD_POLICY_KEY);
|
||||
}
|
||||
});
|
||||
if (value != null) {
|
||||
value = value.toLowerCase(Locale.ENGLISH);
|
||||
String[] ss = value.split(":");
|
||||
if ("tryless".equals(ss[0])) {
|
||||
if (ss.length > 1) {
|
||||
String[] params = ss[1].split(",");
|
||||
try {
|
||||
int tmp0 = Integer.parseInt(params[0]);
|
||||
if (params.length > 1) {
|
||||
tryLessTimeout = Integer.parseInt(params[1]);
|
||||
}
|
||||
// Assign here in case of exception at params[1]
|
||||
tryLessMaxRetries = tmp0;
|
||||
} catch (NumberFormatException nfe) {
|
||||
// Ignored. Please note that tryLess is recognized and
|
||||
// used, parameters using default values
|
||||
if (DEBUG) {
|
||||
System.out.println("Invalid " + BAD_POLICY_KEY +
|
||||
" parameter for tryLess: " +
|
||||
value + ", use default");
|
||||
}
|
||||
}
|
||||
}
|
||||
badPolicy = BpType.TRY_LESS;
|
||||
} else if ("trylast".equals(ss[0])) {
|
||||
badPolicy = BpType.TRY_LAST;
|
||||
} else {
|
||||
badPolicy = BpType.NONE;
|
||||
}
|
||||
} else {
|
||||
badPolicy = BpType.NONE;
|
||||
}
|
||||
|
||||
|
||||
int timeout = -1;
|
||||
int max_retries = -1;
|
||||
int udp_pref_limit = -1;
|
||||
|
||||
try {
|
||||
Config cfg = Config.getInstance();
|
||||
String temp = cfg.get("libdefaults", "kdc_timeout");
|
||||
timeout = parseTimeString(temp);
|
||||
|
||||
temp = cfg.get("libdefaults", "max_retries");
|
||||
max_retries = parsePositiveIntString(temp);
|
||||
temp = cfg.get("libdefaults", "udp_preference_limit");
|
||||
udp_pref_limit = parsePositiveIntString(temp);
|
||||
} catch (Exception exc) {
|
||||
// ignore any exceptions; use default values
|
||||
if (DEBUG) {
|
||||
System.out.println ("Exception in getting KDC communication " +
|
||||
"settings, using default value " +
|
||||
exc.getMessage());
|
||||
}
|
||||
}
|
||||
defaultKdcTimeout = timeout > 0 ? timeout : 30*1000; // 30 seconds
|
||||
defaultKdcRetryLimit =
|
||||
max_retries > 0 ? max_retries : Krb5.KDC_RETRY_LIMIT;
|
||||
|
||||
if (udp_pref_limit < 0) {
|
||||
defaultUdpPrefLimit = Krb5.KDC_DEFAULT_UDP_PREF_LIMIT;
|
||||
} else if (udp_pref_limit > Krb5.KDC_HARD_UDP_LIMIT) {
|
||||
defaultUdpPrefLimit = Krb5.KDC_HARD_UDP_LIMIT;
|
||||
} else {
|
||||
defaultUdpPrefLimit = udp_pref_limit;
|
||||
}
|
||||
|
||||
KdcAccessibility.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* The instance fields
|
||||
*/
|
||||
private String realm;
|
||||
|
||||
public KdcComm(String realm) throws KrbException {
|
||||
if (realm == null) {
|
||||
realm = Config.getInstance().getDefaultRealm();
|
||||
if (realm == null) {
|
||||
throw new KrbException(Krb5.KRB_ERR_GENERIC,
|
||||
"Cannot find default realm");
|
||||
}
|
||||
}
|
||||
this.realm = realm;
|
||||
}
|
||||
|
||||
public byte[] send(byte[] obuf)
|
||||
throws IOException, KrbException {
|
||||
int udpPrefLimit = getRealmSpecificValue(
|
||||
realm, "udp_preference_limit", defaultUdpPrefLimit);
|
||||
|
||||
boolean useTCP = (udpPrefLimit > 0 &&
|
||||
(obuf != null && obuf.length > udpPrefLimit));
|
||||
|
||||
return send(obuf, useTCP);
|
||||
}
|
||||
|
||||
private byte[] send(byte[] obuf, boolean useTCP)
|
||||
throws IOException, KrbException {
|
||||
|
||||
if (obuf == null)
|
||||
return null;
|
||||
Config cfg = Config.getInstance();
|
||||
|
||||
if (realm == null) {
|
||||
realm = cfg.getDefaultRealm();
|
||||
if (realm == null) {
|
||||
throw new KrbException(Krb5.KRB_ERR_GENERIC,
|
||||
"Cannot find default realm");
|
||||
}
|
||||
}
|
||||
|
||||
String kdcList = cfg.getKDCList(realm);
|
||||
if (kdcList == null) {
|
||||
throw new KrbException("Cannot get kdc for realm " + realm);
|
||||
}
|
||||
// tempKdc may include the port number also
|
||||
Iterator<String> tempKdc = KdcAccessibility.list(kdcList).iterator();
|
||||
if (!tempKdc.hasNext()) {
|
||||
throw new KrbException("Cannot get kdc for realm " + realm);
|
||||
}
|
||||
byte[] ibuf = null;
|
||||
try {
|
||||
ibuf = sendIfPossible(obuf, tempKdc.next(), useTCP);
|
||||
} catch(Exception first) {
|
||||
boolean ok = false;
|
||||
while(tempKdc.hasNext()) {
|
||||
try {
|
||||
ibuf = sendIfPossible(obuf, tempKdc.next(), useTCP);
|
||||
ok = true;
|
||||
break;
|
||||
} catch(Exception ignore) {}
|
||||
}
|
||||
if (!ok) throw first;
|
||||
}
|
||||
if (ibuf == null) {
|
||||
throw new IOException("Cannot get a KDC reply");
|
||||
}
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
// send the AS Request to the specified KDC
|
||||
// failover to using TCP if useTCP is not set and response is too big
|
||||
private byte[] sendIfPossible(byte[] obuf, String tempKdc, boolean useTCP)
|
||||
throws IOException, KrbException {
|
||||
|
||||
try {
|
||||
byte[] ibuf = send(obuf, tempKdc, useTCP);
|
||||
KRBError ke = null;
|
||||
try {
|
||||
ke = new KRBError(ibuf);
|
||||
} catch (Exception e) {
|
||||
// OK
|
||||
}
|
||||
if (ke != null && ke.getErrorCode() ==
|
||||
Krb5.KRB_ERR_RESPONSE_TOO_BIG) {
|
||||
ibuf = send(obuf, tempKdc, true);
|
||||
}
|
||||
KdcAccessibility.removeBad(tempKdc);
|
||||
return ibuf;
|
||||
} catch(Exception e) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KrbKdcReq send: error trying " +
|
||||
tempKdc);
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
KdcAccessibility.addBad(tempKdc);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// send the AS Request to the specified KDC
|
||||
|
||||
private byte[] send(byte[] obuf, String tempKdc, boolean useTCP)
|
||||
throws IOException, KrbException {
|
||||
|
||||
if (obuf == null)
|
||||
return null;
|
||||
|
||||
int port = Krb5.KDC_INET_DEFAULT_PORT;
|
||||
int retries = getRealmSpecificValue(
|
||||
realm, "max_retries", defaultKdcRetryLimit);
|
||||
int timeout = getRealmSpecificValue(
|
||||
realm, "kdc_timeout", defaultKdcTimeout);
|
||||
if (badPolicy == BpType.TRY_LESS &&
|
||||
KdcAccessibility.isBad(tempKdc)) {
|
||||
if (retries > tryLessMaxRetries) {
|
||||
retries = tryLessMaxRetries; // less retries
|
||||
}
|
||||
if (timeout > tryLessTimeout) {
|
||||
timeout = tryLessTimeout; // less time
|
||||
}
|
||||
}
|
||||
|
||||
String kdc = null;
|
||||
String portStr = null;
|
||||
|
||||
if (tempKdc.charAt(0) == '[') { // Explicit IPv6 in []
|
||||
int pos = tempKdc.indexOf(']', 1);
|
||||
if (pos == -1) {
|
||||
throw new IOException("Illegal KDC: " + tempKdc);
|
||||
}
|
||||
kdc = tempKdc.substring(1, pos);
|
||||
if (pos != tempKdc.length() - 1) { // with port number
|
||||
if (tempKdc.charAt(pos+1) != ':') {
|
||||
throw new IOException("Illegal KDC: " + tempKdc);
|
||||
}
|
||||
portStr = tempKdc.substring(pos+2);
|
||||
}
|
||||
} else {
|
||||
int colon = tempKdc.indexOf(':');
|
||||
if (colon == -1) { // Hostname or IPv4 host only
|
||||
kdc = tempKdc;
|
||||
} else {
|
||||
int nextColon = tempKdc.indexOf(':', colon+1);
|
||||
if (nextColon > 0) { // >=2 ":", IPv6 with no port
|
||||
kdc = tempKdc;
|
||||
} else { // 1 ":", hostname or IPv4 with port
|
||||
kdc = tempKdc.substring(0, colon);
|
||||
portStr = tempKdc.substring(colon+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (portStr != null) {
|
||||
int tempPort = parsePositiveIntString(portStr);
|
||||
if (tempPort > 0)
|
||||
port = tempPort;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KrbKdcReq send: kdc=" + kdc
|
||||
+ (useTCP ? " TCP:":" UDP:")
|
||||
+ port + ", timeout="
|
||||
+ timeout
|
||||
+ ", number of retries ="
|
||||
+ retries
|
||||
+ ", #bytes=" + obuf.length);
|
||||
}
|
||||
|
||||
KdcCommunication kdcCommunication =
|
||||
new KdcCommunication(kdc, port, useTCP, timeout, retries, obuf);
|
||||
try {
|
||||
byte[] ibuf = AccessController.doPrivileged(kdcCommunication);
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KrbKdcReq send: #bytes read="
|
||||
+ (ibuf != null ? ibuf.length : 0));
|
||||
}
|
||||
return ibuf;
|
||||
} catch (PrivilegedActionException e) {
|
||||
Exception wrappedException = e.getException();
|
||||
if (wrappedException instanceof IOException) {
|
||||
throw (IOException) wrappedException;
|
||||
} else {
|
||||
throw (KrbException) wrappedException;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class KdcCommunication
|
||||
implements PrivilegedExceptionAction<byte[]> {
|
||||
|
||||
private String kdc;
|
||||
private int port;
|
||||
private boolean useTCP;
|
||||
private int timeout;
|
||||
private int retries;
|
||||
private byte[] obuf;
|
||||
|
||||
public KdcCommunication(String kdc, int port, boolean useTCP,
|
||||
int timeout, int retries, byte[] obuf) {
|
||||
this.kdc = kdc;
|
||||
this.port = port;
|
||||
this.useTCP = useTCP;
|
||||
this.timeout = timeout;
|
||||
this.retries = retries;
|
||||
this.obuf = obuf;
|
||||
}
|
||||
|
||||
// The caller only casts IOException and KrbException so don't
|
||||
// add any new ones!
|
||||
|
||||
public byte[] run() throws IOException, KrbException {
|
||||
|
||||
byte[] ibuf = null;
|
||||
|
||||
for (int i=1; i <= retries; i++) {
|
||||
String proto = useTCP?"TCP":"UDP";
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KDCCommunication: kdc=" + kdc
|
||||
+ " " + proto + ":"
|
||||
+ port + ", timeout="
|
||||
+ timeout
|
||||
+ ",Attempt =" + i
|
||||
+ ", #bytes=" + obuf.length);
|
||||
}
|
||||
try (NetClient kdcClient = NetClient.getInstance(
|
||||
proto, kdc, port, timeout)) {
|
||||
kdcClient.send(obuf);
|
||||
ibuf = kdcClient.receive();
|
||||
break;
|
||||
} catch (SocketTimeoutException se) {
|
||||
if (DEBUG) {
|
||||
System.out.println ("SocketTimeOutException with " +
|
||||
"attempt: " + i);
|
||||
}
|
||||
if (i == retries) {
|
||||
ibuf = null;
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ibuf;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a time value string. If it ends with "s", parses as seconds.
|
||||
* Otherwise, parses as milliseconds.
|
||||
* @param s the time string
|
||||
* @return the integer value in milliseconds, or -1 if input is null or
|
||||
* has an invalid format
|
||||
*/
|
||||
private static int parseTimeString(String s) {
|
||||
if (s == null) {
|
||||
return -1;
|
||||
}
|
||||
if (s.endsWith("s")) {
|
||||
int seconds = parsePositiveIntString(s.substring(0, s.length()-1));
|
||||
return (seconds < 0) ? -1 : (seconds*1000);
|
||||
} else {
|
||||
return parsePositiveIntString(s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns krb5.conf setting of {@code key} for a specific realm,
|
||||
* which can be:
|
||||
* 1. defined in the sub-stanza for the given realm inside [realms], or
|
||||
* 2. defined in [libdefaults], or
|
||||
* 3. defValue
|
||||
* @param realm the given realm in which the setting is requested. Returns
|
||||
* the global setting if null
|
||||
* @param key the key for the setting
|
||||
* @param defValue default value
|
||||
* @return a value for the key
|
||||
*/
|
||||
private int getRealmSpecificValue(String realm, String key, int defValue) {
|
||||
int v = defValue;
|
||||
|
||||
if (realm == null) return v;
|
||||
|
||||
int temp = -1;
|
||||
try {
|
||||
String value =
|
||||
Config.getInstance().get("realms", realm, key);
|
||||
if (key.equals("kdc_timeout")) {
|
||||
temp = parseTimeString(value);
|
||||
} else {
|
||||
temp = parsePositiveIntString(value);
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
// Ignored, defValue will be picked up
|
||||
}
|
||||
|
||||
if (temp > 0) v = temp;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
private static int parsePositiveIntString(String intString) {
|
||||
if (intString == null)
|
||||
return -1;
|
||||
|
||||
int ret = -1;
|
||||
|
||||
try {
|
||||
ret = Integer.parseInt(intString);
|
||||
} catch (Exception exc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret >= 0)
|
||||
return ret;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maintains a KDC accessible list. Unavailable KDCs are put into a
|
||||
* blacklist, when a KDC in the blacklist is available, it's removed
|
||||
* from there. No insertion order in the blacklist.
|
||||
*
|
||||
* There are two methods to deal with KDCs in the blacklist. 1. Only try
|
||||
* them when there's no KDC not on the blacklist. 2. Still try them, but
|
||||
* with lesser number of retries and smaller timeout value.
|
||||
*/
|
||||
static class KdcAccessibility {
|
||||
// Known bad KDCs
|
||||
private static Set<String> bads = new HashSet<>();
|
||||
|
||||
private static synchronized void addBad(String kdc) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KdcAccessibility: add " + kdc);
|
||||
}
|
||||
bads.add(kdc);
|
||||
}
|
||||
|
||||
private static synchronized void removeBad(String kdc) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KdcAccessibility: remove " + kdc);
|
||||
}
|
||||
bads.remove(kdc);
|
||||
}
|
||||
|
||||
private static synchronized boolean isBad(String kdc) {
|
||||
return bads.contains(kdc);
|
||||
}
|
||||
|
||||
private static synchronized void reset() {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KdcAccessibility: reset");
|
||||
}
|
||||
bads.clear();
|
||||
}
|
||||
|
||||
// Returns a preferred KDC list by putting the bad ones at the end
|
||||
private static synchronized List<String> list(String kdcList) {
|
||||
StringTokenizer st = new StringTokenizer(kdcList);
|
||||
List<String> list = new ArrayList<>();
|
||||
if (badPolicy == BpType.TRY_LAST) {
|
||||
List<String> badkdcs = new ArrayList<>();
|
||||
while (st.hasMoreTokens()) {
|
||||
String t = st.nextToken();
|
||||
if (bads.contains(t)) badkdcs.add(t);
|
||||
else list.add(t);
|
||||
}
|
||||
// Bad KDCs are put at last
|
||||
list.addAll(badkdcs);
|
||||
} else {
|
||||
// All KDCs are returned in their original order,
|
||||
// This include TRY_LESS and NONE
|
||||
while (st.hasMoreTokens()) {
|
||||
list.add(st.nextToken());
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
jdkSrc/jdk8/sun/security/krb5/KerberosSecrets.java
Normal file
46
jdkSrc/jdk8/sun/security/krb5/KerberosSecrets.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 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. 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 sun.security.krb5;
|
||||
|
||||
import javax.security.auth.kerberos.KeyTab;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
public class KerberosSecrets {
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private static JavaxSecurityAuthKerberosAccess javaxSecurityAuthKerberosAccess;
|
||||
|
||||
public static void setJavaxSecurityAuthKerberosAccess
|
||||
(JavaxSecurityAuthKerberosAccess jsaka) {
|
||||
javaxSecurityAuthKerberosAccess = jsaka;
|
||||
}
|
||||
|
||||
public static JavaxSecurityAuthKerberosAccess
|
||||
getJavaxSecurityAuthKerberosAccess() {
|
||||
if (javaxSecurityAuthKerberosAccess == null)
|
||||
unsafe.ensureClassInitialized(KeyTab.class);
|
||||
return javaxSecurityAuthKerberosAccess;
|
||||
}
|
||||
}
|
||||
198
jdkSrc/jdk8/sun/security/krb5/KrbApRep.java
Normal file
198
jdkSrc/jdk8/sun/security/krb5/KrbApRep.java
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class encapsulates a KRB-AP-REP sent from the service to the
|
||||
* client.
|
||||
*/
|
||||
public class KrbApRep {
|
||||
private byte[] obuf;
|
||||
private byte[] ibuf;
|
||||
private EncAPRepPart encPart; // although in plain text
|
||||
private APRep apRepMessg;
|
||||
|
||||
/**
|
||||
* Constructs a KRB-AP-REP to send to a client.
|
||||
* @throws KrbException
|
||||
* @throws IOException
|
||||
*/
|
||||
// Used in AcceptSecContextToken
|
||||
public KrbApRep(KrbApReq incomingReq,
|
||||
boolean useSeqNumber,
|
||||
EncryptionKey subKey)
|
||||
throws KrbException, IOException {
|
||||
|
||||
SeqNumber seqNum = new LocalSeqNumber();
|
||||
|
||||
init(incomingReq, subKey, seqNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KRB-AP-REQ from the bytes received from a service.
|
||||
* @throws KrbException
|
||||
* @throws IOException
|
||||
*/
|
||||
// Used in AcceptSecContextToken
|
||||
public KrbApRep(byte[] message, Credentials tgtCreds,
|
||||
KrbApReq outgoingReq) throws KrbException, IOException {
|
||||
this(message, tgtCreds);
|
||||
authenticate(outgoingReq);
|
||||
}
|
||||
|
||||
private void init(KrbApReq apReq,
|
||||
EncryptionKey subKey,
|
||||
SeqNumber seqNumber)
|
||||
throws KrbException, IOException {
|
||||
createMessage(
|
||||
apReq.getCreds().key,
|
||||
apReq.getCtime(),
|
||||
apReq.cusec(),
|
||||
subKey,
|
||||
seqNumber);
|
||||
obuf = apRepMessg.asn1Encode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a KrbApRep object.
|
||||
* @param msg a byte array of reply message.
|
||||
* @param tgs_creds client's credential.
|
||||
* @exception KrbException
|
||||
* @exception IOException
|
||||
*/
|
||||
private KrbApRep(byte[] msg, Credentials tgs_creds)
|
||||
throws KrbException, IOException {
|
||||
this(new DerValue(msg), tgs_creds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KrbApRep object.
|
||||
* @param msg a byte array of reply message.
|
||||
* @param tgs_creds client's credential.
|
||||
* @exception KrbException
|
||||
* @exception IOException
|
||||
*/
|
||||
private KrbApRep(DerValue encoding, Credentials tgs_creds)
|
||||
throws KrbException, IOException {
|
||||
APRep rep = null;
|
||||
try {
|
||||
rep = new APRep(encoding);
|
||||
} catch (Asn1Exception e) {
|
||||
rep = null;
|
||||
KRBError err = new KRBError(encoding);
|
||||
String errStr = err.getErrorString();
|
||||
String eText;
|
||||
if (errStr.charAt(errStr.length() - 1) == 0)
|
||||
eText = errStr.substring(0, errStr.length() - 1);
|
||||
else
|
||||
eText = errStr;
|
||||
KrbException ke = new KrbException(err.getErrorCode(), eText);
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
|
||||
byte[] temp = rep.encPart.decrypt(tgs_creds.key,
|
||||
KeyUsage.KU_ENC_AP_REP_PART);
|
||||
byte[] enc_ap_rep_part = rep.encPart.reset(temp);
|
||||
|
||||
encoding = new DerValue(enc_ap_rep_part);
|
||||
encPart = new EncAPRepPart(encoding);
|
||||
}
|
||||
|
||||
private void authenticate(KrbApReq apReq)
|
||||
throws KrbException, IOException {
|
||||
if (encPart.ctime.getSeconds() != apReq.getCtime().getSeconds() ||
|
||||
encPart.cusec != apReq.getCtime().getMicroSeconds())
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MUT_FAIL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the optional subkey stored in
|
||||
* this message. Returns null if none is stored.
|
||||
*/
|
||||
public EncryptionKey getSubKey() {
|
||||
// XXX Can encPart be null
|
||||
return encPart.getSubKey();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the optional sequence number stored in the
|
||||
* this message. Returns null if none is stored.
|
||||
*/
|
||||
public Integer getSeqNumber() {
|
||||
// XXX Can encPart be null
|
||||
return encPart.getSeqNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ASN.1 encoding that should be sent to the peer.
|
||||
*/
|
||||
public byte[] getMessage() {
|
||||
return obuf;
|
||||
}
|
||||
|
||||
private void createMessage(
|
||||
EncryptionKey key,
|
||||
KerberosTime ctime,
|
||||
int cusec,
|
||||
EncryptionKey subKey,
|
||||
SeqNumber seqNumber)
|
||||
throws Asn1Exception, IOException,
|
||||
KdcErrException, KrbCryptoException {
|
||||
|
||||
Integer seqno = null;
|
||||
|
||||
if (seqNumber != null)
|
||||
seqno = new Integer(seqNumber.current());
|
||||
|
||||
encPart = new EncAPRepPart(ctime,
|
||||
cusec,
|
||||
subKey,
|
||||
seqno);
|
||||
|
||||
byte[] encPartEncoding = encPart.asn1Encode();
|
||||
|
||||
EncryptedData encEncPart = new EncryptedData(key, encPartEncoding,
|
||||
KeyUsage.KU_ENC_AP_REP_PART);
|
||||
|
||||
apRepMessg = new APRep(encEncPart);
|
||||
}
|
||||
|
||||
}
|
||||
517
jdkSrc/jdk8/sun/security/krb5/KrbApReq.java
Normal file
517
jdkSrc/jdk8/sun/security/krb5/KrbApReq.java
Normal file
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import sun.security.jgss.krb5.Krb5AcceptCredential;
|
||||
import java.net.InetAddress;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import sun.security.krb5.internal.rcache.AuthTimeWithHash;
|
||||
|
||||
/**
|
||||
* This class encapsulates a KRB-AP-REQ that a client sends to a
|
||||
* server for authentication.
|
||||
*/
|
||||
public class KrbApReq {
|
||||
|
||||
private byte[] obuf;
|
||||
private KerberosTime ctime;
|
||||
private int cusec;
|
||||
private Authenticator authenticator;
|
||||
private Credentials creds;
|
||||
private APReq apReqMessg;
|
||||
|
||||
// Used by acceptor side
|
||||
private static ReplayCache rcache = ReplayCache.getInstance();
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
private static final char[] hexConst = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
/**
|
||||
* Constructs an AP-REQ message to send to the peer.
|
||||
* @param tgsCred the <code>Credentials</code> to be used to construct the
|
||||
* AP Request protocol message.
|
||||
* @param mutualRequired Whether mutual authentication is required
|
||||
* @param useSubKey Whether the subkey is to be used to protect this
|
||||
* specific application session. If this is not set then the
|
||||
* session key from the ticket will be used.
|
||||
* @throws KrbException for any Kerberos protocol specific error
|
||||
* @throws IOException for any IO related errors
|
||||
* (e.g. socket operations)
|
||||
*/
|
||||
/*
|
||||
// Not Used
|
||||
public KrbApReq(Credentials tgsCred,
|
||||
boolean mutualRequired,
|
||||
boolean useSubKey,
|
||||
boolean useSeqNumber) throws Asn1Exception,
|
||||
KrbCryptoException, KrbException, IOException {
|
||||
|
||||
this(tgsCred, mutualRequired, useSubKey, useSeqNumber, null);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs an AP-REQ message to send to the peer.
|
||||
* @param tgsCred the <code>Credentials</code> to be used to construct the
|
||||
* AP Request protocol message.
|
||||
* @param mutualRequired Whether mutual authentication is required
|
||||
* @param useSubKey Whether the subkey is to be used to protect this
|
||||
* specific application session. If this is not set then the
|
||||
* session key from the ticket will be used.
|
||||
* @param cksum checksum of the the application data that accompanies
|
||||
* the KRB_AP_REQ.
|
||||
* @throws KrbException for any Kerberos protocol specific error
|
||||
* @throws IOException for any IO related errors
|
||||
* (e.g. socket operations)
|
||||
*/
|
||||
// Used in InitSecContextToken
|
||||
public KrbApReq(Credentials tgsCred,
|
||||
boolean mutualRequired,
|
||||
boolean useSubKey,
|
||||
boolean useSeqNumber,
|
||||
Checksum cksum) throws Asn1Exception,
|
||||
KrbCryptoException, KrbException, IOException {
|
||||
|
||||
APOptions apOptions = (mutualRequired?
|
||||
new APOptions(Krb5.AP_OPTS_MUTUAL_REQUIRED):
|
||||
new APOptions());
|
||||
if (DEBUG)
|
||||
System.out.println(">>> KrbApReq: APOptions are " + apOptions);
|
||||
|
||||
EncryptionKey subKey = (useSubKey?
|
||||
new EncryptionKey(tgsCred.getSessionKey()):
|
||||
null);
|
||||
|
||||
SeqNumber seqNum = new LocalSeqNumber();
|
||||
|
||||
init(apOptions,
|
||||
tgsCred,
|
||||
cksum,
|
||||
subKey,
|
||||
seqNum,
|
||||
null, // AuthorizationData authzData
|
||||
KeyUsage.KU_AP_REQ_AUTHENTICATOR);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an AP-REQ message from the bytes received from the
|
||||
* peer.
|
||||
* @param message The message received from the peer
|
||||
* @param cred <code>KrbAcceptCredential</code> containing keys to decrypt
|
||||
* the message; key selected will depend on etype used to encrypt data
|
||||
* @throws KrbException for any Kerberos protocol specific error
|
||||
* @throws IOException for any IO related errors
|
||||
* (e.g. socket operations)
|
||||
*/
|
||||
// Used in InitSecContextToken (for AP_REQ and not TGS REQ)
|
||||
public KrbApReq(byte[] message,
|
||||
Krb5AcceptCredential cred,
|
||||
InetAddress initiator)
|
||||
throws KrbException, IOException {
|
||||
obuf = message;
|
||||
if (apReqMessg == null)
|
||||
decode();
|
||||
authenticate(cred, initiator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an AP-REQ message from the bytes received from the
|
||||
* peer.
|
||||
* @param value The <code>DerValue</code> that contains the
|
||||
* DER enoded AP-REQ protocol message
|
||||
* @param keys <code>EncrtyptionKey</code>s to decrypt the message;
|
||||
*
|
||||
* @throws KrbException for any Kerberos protocol specific error
|
||||
* @throws IOException for any IO related errors
|
||||
* (e.g. socket operations)
|
||||
*/
|
||||
/*
|
||||
public KrbApReq(DerValue value, EncryptionKey[] key, InetAddress initiator)
|
||||
throws KrbException, IOException {
|
||||
obuf = value.toByteArray();
|
||||
if (apReqMessg == null)
|
||||
decode(value);
|
||||
authenticate(keys, initiator);
|
||||
}
|
||||
|
||||
KrbApReq(APOptions options,
|
||||
Credentials tgs_creds,
|
||||
Checksum cksum,
|
||||
EncryptionKey subKey,
|
||||
SeqNumber seqNumber,
|
||||
AuthorizationData authorizationData)
|
||||
throws KrbException, IOException {
|
||||
init(options, tgs_creds, cksum, subKey, seqNumber, authorizationData);
|
||||
}
|
||||
*/
|
||||
|
||||
/** used by KrbTgsReq **/
|
||||
KrbApReq(APOptions apOptions,
|
||||
Ticket ticket,
|
||||
EncryptionKey key,
|
||||
PrincipalName cname,
|
||||
Checksum cksum,
|
||||
KerberosTime ctime,
|
||||
EncryptionKey subKey,
|
||||
SeqNumber seqNumber,
|
||||
AuthorizationData authorizationData)
|
||||
throws Asn1Exception, IOException,
|
||||
KdcErrException, KrbCryptoException {
|
||||
|
||||
init(apOptions, ticket, key, cname,
|
||||
cksum, ctime, subKey, seqNumber, authorizationData,
|
||||
KeyUsage.KU_PA_TGS_REQ_AUTHENTICATOR);
|
||||
|
||||
}
|
||||
|
||||
private void init(APOptions options,
|
||||
Credentials tgs_creds,
|
||||
Checksum cksum,
|
||||
EncryptionKey subKey,
|
||||
SeqNumber seqNumber,
|
||||
AuthorizationData authorizationData,
|
||||
int usage)
|
||||
throws KrbException, IOException {
|
||||
|
||||
ctime = KerberosTime.now();
|
||||
init(options,
|
||||
tgs_creds.ticket,
|
||||
tgs_creds.key,
|
||||
tgs_creds.client,
|
||||
cksum,
|
||||
ctime,
|
||||
subKey,
|
||||
seqNumber,
|
||||
authorizationData,
|
||||
usage);
|
||||
}
|
||||
|
||||
private void init(APOptions apOptions,
|
||||
Ticket ticket,
|
||||
EncryptionKey key,
|
||||
PrincipalName cname,
|
||||
Checksum cksum,
|
||||
KerberosTime ctime,
|
||||
EncryptionKey subKey,
|
||||
SeqNumber seqNumber,
|
||||
AuthorizationData authorizationData,
|
||||
int usage)
|
||||
throws Asn1Exception, IOException,
|
||||
KdcErrException, KrbCryptoException {
|
||||
|
||||
createMessage(apOptions, ticket, key, cname,
|
||||
cksum, ctime, subKey, seqNumber, authorizationData,
|
||||
usage);
|
||||
obuf = apReqMessg.asn1Encode();
|
||||
}
|
||||
|
||||
|
||||
void decode() throws KrbException, IOException {
|
||||
DerValue encoding = new DerValue(obuf);
|
||||
decode(encoding);
|
||||
}
|
||||
|
||||
void decode(DerValue encoding) throws KrbException, IOException {
|
||||
apReqMessg = null;
|
||||
try {
|
||||
apReqMessg = new APReq(encoding);
|
||||
} catch (Asn1Exception e) {
|
||||
apReqMessg = null;
|
||||
KRBError err = new KRBError(encoding);
|
||||
String errStr = err.getErrorString();
|
||||
String eText;
|
||||
if (errStr.charAt(errStr.length() - 1) == 0)
|
||||
eText = errStr.substring(0, errStr.length() - 1);
|
||||
else
|
||||
eText = errStr;
|
||||
KrbException ke = new KrbException(err.getErrorCode(), eText);
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
private void authenticate(Krb5AcceptCredential cred, InetAddress initiator)
|
||||
throws KrbException, IOException {
|
||||
int encPartKeyType = apReqMessg.ticket.encPart.getEType();
|
||||
Integer kvno = apReqMessg.ticket.encPart.getKeyVersionNumber();
|
||||
EncryptionKey[] keys = cred.getKrb5EncryptionKeys(apReqMessg.ticket.sname);
|
||||
EncryptionKey dkey = EncryptionKey.findKey(encPartKeyType, kvno, keys);
|
||||
|
||||
if (dkey == null) {
|
||||
throw new KrbException(Krb5.API_INVALID_ARG,
|
||||
"Cannot find key of appropriate type to decrypt AP REP - " +
|
||||
EType.toString(encPartKeyType));
|
||||
}
|
||||
|
||||
byte[] bytes = apReqMessg.ticket.encPart.decrypt(dkey,
|
||||
KeyUsage.KU_TICKET);
|
||||
byte[] temp = apReqMessg.ticket.encPart.reset(bytes);
|
||||
EncTicketPart enc_ticketPart = new EncTicketPart(temp);
|
||||
|
||||
checkPermittedEType(enc_ticketPart.key.getEType());
|
||||
|
||||
byte[] bytes2 = apReqMessg.authenticator.decrypt(enc_ticketPart.key,
|
||||
KeyUsage.KU_AP_REQ_AUTHENTICATOR);
|
||||
byte[] temp2 = apReqMessg.authenticator.reset(bytes2);
|
||||
authenticator = new Authenticator(temp2);
|
||||
ctime = authenticator.ctime;
|
||||
cusec = authenticator.cusec;
|
||||
authenticator.ctime =
|
||||
authenticator.ctime.withMicroSeconds(authenticator.cusec);
|
||||
|
||||
if (!authenticator.cname.equals(enc_ticketPart.cname)) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADMATCH);
|
||||
}
|
||||
|
||||
if (!authenticator.ctime.inClockSkew())
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
|
||||
|
||||
String alg = AuthTimeWithHash.DEFAULT_HASH_ALG;
|
||||
byte[] hash;
|
||||
try {
|
||||
hash = MessageDigest.getInstance(AuthTimeWithHash.realAlg(alg))
|
||||
.digest(apReqMessg.authenticator.cipher);
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
throw new AssertionError("Impossible " + alg);
|
||||
}
|
||||
|
||||
char[] h = new char[hash.length * 2];
|
||||
for (int i=0; i<hash.length; i++) {
|
||||
h[2*i] = hexConst[(hash[i]&0xff)>>4];
|
||||
h[2*i+1] = hexConst[hash[i]&0xf];
|
||||
}
|
||||
AuthTimeWithHash time = new AuthTimeWithHash(
|
||||
authenticator.cname.toString(),
|
||||
apReqMessg.ticket.sname.toString(),
|
||||
authenticator.ctime.getSeconds(),
|
||||
authenticator.cusec,
|
||||
alg,
|
||||
new String(h));
|
||||
rcache.checkAndStore(KerberosTime.now(), time);
|
||||
|
||||
if (initiator != null) {
|
||||
// sender host address
|
||||
HostAddress sender = new HostAddress(initiator);
|
||||
if (enc_ticketPart.caddr != null
|
||||
&& !enc_ticketPart.caddr.inList(sender)) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KrbApReq: initiator is "
|
||||
+ sender.getInetAddress()
|
||||
+ ", but caddr is "
|
||||
+ Arrays.toString(
|
||||
enc_ticketPart.caddr.getInetAddresses()));
|
||||
}
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADADDR);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX check for repeated authenticator
|
||||
// if found
|
||||
// throw new KrbApErrException(Krb5.KRB_AP_ERR_REPEAT);
|
||||
// else
|
||||
// save authenticator to check for later
|
||||
|
||||
KerberosTime now = KerberosTime.now();
|
||||
|
||||
if ((enc_ticketPart.starttime != null &&
|
||||
enc_ticketPart.starttime.greaterThanWRTClockSkew(now)) ||
|
||||
enc_ticketPart.flags.get(Krb5.TKT_OPTS_INVALID))
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_TKT_NYV);
|
||||
|
||||
// if the current time is later than end time by more
|
||||
// than the allowable clock skew, throws ticket expired exception.
|
||||
if (enc_ticketPart.endtime != null &&
|
||||
now.greaterThanWRTClockSkew(enc_ticketPart.endtime)) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_TKT_EXPIRED);
|
||||
}
|
||||
|
||||
creds = new Credentials(
|
||||
apReqMessg.ticket,
|
||||
authenticator.cname,
|
||||
null,
|
||||
apReqMessg.ticket.sname,
|
||||
null,
|
||||
enc_ticketPart.key,
|
||||
enc_ticketPart.flags,
|
||||
enc_ticketPart.authtime,
|
||||
enc_ticketPart.starttime,
|
||||
enc_ticketPart.endtime,
|
||||
enc_ticketPart.renewTill,
|
||||
enc_ticketPart.caddr,
|
||||
enc_ticketPart.authorizationData);
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KrbApReq: authenticate succeed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the credentials that are contained in the ticket that
|
||||
* is part of this this AP-REP.
|
||||
*/
|
||||
public Credentials getCreds() {
|
||||
return creds;
|
||||
}
|
||||
|
||||
KerberosTime getCtime() {
|
||||
if (ctime != null)
|
||||
return ctime;
|
||||
return authenticator.ctime;
|
||||
}
|
||||
|
||||
int cusec() {
|
||||
return cusec;
|
||||
}
|
||||
|
||||
APOptions getAPOptions() throws KrbException, IOException {
|
||||
if (apReqMessg == null)
|
||||
decode();
|
||||
if (apReqMessg != null)
|
||||
return apReqMessg.apOptions;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if mutual authentication is required and hence an
|
||||
* AP-REP will need to be generated.
|
||||
* @throws KrbException
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean getMutualAuthRequired() throws KrbException, IOException {
|
||||
if (apReqMessg == null)
|
||||
decode();
|
||||
if (apReqMessg != null)
|
||||
return apReqMessg.apOptions.get(Krb5.AP_OPTS_MUTUAL_REQUIRED);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean useSessionKey() throws KrbException, IOException {
|
||||
if (apReqMessg == null)
|
||||
decode();
|
||||
if (apReqMessg != null)
|
||||
return apReqMessg.apOptions.get(Krb5.AP_OPTS_USE_SESSION_KEY);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the optional subkey stored in the Authenticator for
|
||||
* this message. Returns null if none is stored.
|
||||
*/
|
||||
public EncryptionKey getSubKey() {
|
||||
// XXX Can authenticator be null
|
||||
return authenticator.getSubKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the optional sequence number stored in the
|
||||
* Authenticator for this message. Returns null if none is
|
||||
* stored.
|
||||
*/
|
||||
public Integer getSeqNumber() {
|
||||
// XXX Can authenticator be null
|
||||
return authenticator.getSeqNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the optional Checksum stored in the
|
||||
* Authenticator for this message. Returns null if none is
|
||||
* stored.
|
||||
*/
|
||||
public Checksum getChecksum() {
|
||||
return authenticator.getChecksum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ASN.1 encoding that should be sent to the peer.
|
||||
*/
|
||||
public byte[] getMessage() {
|
||||
return obuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the principal name of the client that generated this
|
||||
* message.
|
||||
*/
|
||||
public PrincipalName getClient() {
|
||||
return creds.getClient();
|
||||
}
|
||||
|
||||
private void createMessage(APOptions apOptions,
|
||||
Ticket ticket,
|
||||
EncryptionKey key,
|
||||
PrincipalName cname,
|
||||
Checksum cksum,
|
||||
KerberosTime ctime,
|
||||
EncryptionKey subKey,
|
||||
SeqNumber seqNumber,
|
||||
AuthorizationData authorizationData,
|
||||
int usage)
|
||||
throws Asn1Exception, IOException,
|
||||
KdcErrException, KrbCryptoException {
|
||||
|
||||
Integer seqno = null;
|
||||
|
||||
if (seqNumber != null)
|
||||
seqno = new Integer(seqNumber.current());
|
||||
|
||||
authenticator =
|
||||
new Authenticator(cname,
|
||||
cksum,
|
||||
ctime.getMicroSeconds(),
|
||||
ctime,
|
||||
subKey,
|
||||
seqno,
|
||||
authorizationData);
|
||||
|
||||
byte[] temp = authenticator.asn1Encode();
|
||||
|
||||
EncryptedData encAuthenticator =
|
||||
new EncryptedData(key, temp, usage);
|
||||
|
||||
apReqMessg =
|
||||
new APReq(apOptions, ticket, encAuthenticator);
|
||||
}
|
||||
|
||||
// Check that key is one of the permitted types
|
||||
private static void checkPermittedEType(int target) throws KrbException {
|
||||
int[] etypes = EType.getDefaults("permitted_enctypes");
|
||||
if (!EType.isSupported(target, etypes)) {
|
||||
throw new KrbException(EType.toString(target) +
|
||||
" encryption type not in permitted_enctypes list");
|
||||
}
|
||||
}
|
||||
}
|
||||
115
jdkSrc/jdk8/sun/security/krb5/KrbAppMessage.java
Normal file
115
jdkSrc/jdk8/sun/security/krb5/KrbAppMessage.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
abstract class KrbAppMessage {
|
||||
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
/**
|
||||
* Common checks for KRB-PRIV and KRB-SAFE
|
||||
*/
|
||||
void check(KerberosTime packetTimestamp,
|
||||
Integer packetUsec,
|
||||
Integer packetSeqNumber,
|
||||
HostAddress packetSAddress,
|
||||
HostAddress packetRAddress,
|
||||
SeqNumber seqNumber,
|
||||
HostAddress sAddress,
|
||||
HostAddress rAddress,
|
||||
boolean timestampRequired,
|
||||
boolean seqNumberRequired,
|
||||
PrincipalName packetPrincipal)
|
||||
throws KrbApErrException {
|
||||
|
||||
if (!Krb5.AP_EMPTY_ADDRESSES_ALLOWED || sAddress != null) {
|
||||
if (packetSAddress == null || sAddress == null ||
|
||||
!packetSAddress.equals(sAddress)) {
|
||||
if (DEBUG && packetSAddress == null) {
|
||||
System.out.println("packetSAddress is null");
|
||||
}
|
||||
if (DEBUG && sAddress == null) {
|
||||
System.out.println("sAddress is null");
|
||||
}
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADADDR);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Krb5.AP_EMPTY_ADDRESSES_ALLOWED || rAddress != null) {
|
||||
if (packetRAddress == null || rAddress == null ||
|
||||
!packetRAddress.equals(rAddress))
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADADDR);
|
||||
}
|
||||
|
||||
if (packetTimestamp != null) {
|
||||
if (packetUsec != null) {
|
||||
packetTimestamp =
|
||||
packetTimestamp.withMicroSeconds(packetUsec.intValue());
|
||||
}
|
||||
if (!packetTimestamp.inClockSkew()) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
|
||||
}
|
||||
} else {
|
||||
if (timestampRequired) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX check replay cache
|
||||
// if (rcache.repeated(packetTimestamp, packetUsec, packetSAddress))
|
||||
// throw new KrbApErrException(Krb5.KRB_AP_ERR_REPEAT);
|
||||
|
||||
// XXX consider moving up to api level
|
||||
if (seqNumber == null && seqNumberRequired == true)
|
||||
throw new KrbApErrException(Krb5.API_INVALID_ARG);
|
||||
|
||||
if (packetSeqNumber != null && seqNumber != null) {
|
||||
if (packetSeqNumber.intValue() != seqNumber.current())
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADORDER);
|
||||
// should be done only when no more exceptions are possible
|
||||
seqNumber.step();
|
||||
} else {
|
||||
if (seqNumberRequired) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADORDER);
|
||||
}
|
||||
}
|
||||
|
||||
// Must not be relaxed, per RFC 4120
|
||||
if (packetTimestamp == null && packetSeqNumber == null)
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
|
||||
// XXX check replay cache
|
||||
// rcache.save_identifier(packetTimestamp, packetUsec, packetSAddress,
|
||||
// packetPrincipal, pcaketRealm);
|
||||
}
|
||||
|
||||
}
|
||||
191
jdkSrc/jdk8/sun/security/krb5/KrbAsRep.java
Normal file
191
jdkSrc/jdk8/sun/security/krb5/KrbAsRep.java
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
import sun.security.krb5.internal.crypto.EType;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import javax.security.auth.kerberos.KeyTab;
|
||||
import sun.security.jgss.krb5.Krb5Util;
|
||||
|
||||
/**
|
||||
* This class encapsulates a AS-REP message that the KDC sends to the
|
||||
* client.
|
||||
*/
|
||||
class KrbAsRep extends KrbKdcRep {
|
||||
|
||||
private ASRep rep; // The AS-REP message
|
||||
private Credentials creds; // The Credentials provide by the AS-REP
|
||||
// message, created by initiator after calling
|
||||
// the decrypt() method
|
||||
|
||||
private boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
KrbAsRep(byte[] ibuf) throws
|
||||
KrbException, Asn1Exception, IOException {
|
||||
DerValue encoding = new DerValue(ibuf);
|
||||
try {
|
||||
rep = new ASRep(encoding);
|
||||
} catch (Asn1Exception e) {
|
||||
rep = null;
|
||||
KRBError err = new KRBError(encoding);
|
||||
String errStr = err.getErrorString();
|
||||
String eText = null; // pick up text sent by the server (if any)
|
||||
|
||||
if (errStr != null && errStr.length() > 0) {
|
||||
if (errStr.charAt(errStr.length() - 1) == 0)
|
||||
eText = errStr.substring(0, errStr.length() - 1);
|
||||
else
|
||||
eText = errStr;
|
||||
}
|
||||
KrbException ke;
|
||||
if (eText == null) {
|
||||
// no text sent from server
|
||||
ke = new KrbException(err);
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.println("KRBError received: " + eText);
|
||||
}
|
||||
// override default text with server text
|
||||
ke = new KrbException(err, eText);
|
||||
}
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
// KrbAsReqBuilder need to read back the PA for key generation
|
||||
PAData[] getPA() {
|
||||
return rep.pAData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by KrbAsReqBuilder to resolve a AS-REP message using a keytab.
|
||||
* @param ktab the keytab, not null
|
||||
* @param asReq the original AS-REQ sent, used to validate AS-REP
|
||||
* @param cname the user principal name, used to locate keys in ktab
|
||||
*/
|
||||
void decryptUsingKeyTab(KeyTab ktab, KrbAsReq asReq, PrincipalName cname)
|
||||
throws KrbException, Asn1Exception, IOException {
|
||||
EncryptionKey dkey = null;
|
||||
int encPartKeyType = rep.encPart.getEType();
|
||||
Integer encPartKvno = rep.encPart.kvno;
|
||||
try {
|
||||
dkey = EncryptionKey.findKey(encPartKeyType, encPartKvno,
|
||||
Krb5Util.keysFromJavaxKeyTab(ktab, cname));
|
||||
} catch (KrbException ke) {
|
||||
if (ke.returnCode() == Krb5.KRB_AP_ERR_BADKEYVER) {
|
||||
// Fallback to no kvno. In some cases, keytab is generated
|
||||
// not by sysadmin but Java's ktab command
|
||||
dkey = EncryptionKey.findKey(encPartKeyType,
|
||||
Krb5Util.keysFromJavaxKeyTab(ktab, cname));
|
||||
}
|
||||
}
|
||||
if (dkey == null) {
|
||||
throw new KrbException(Krb5.API_INVALID_ARG,
|
||||
"Cannot find key for type/kvno to decrypt AS REP - " +
|
||||
EType.toString(encPartKeyType) + "/" + encPartKvno);
|
||||
}
|
||||
decrypt(dkey, asReq, cname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by KrbAsReqBuilder to resolve a AS-REP message using a password.
|
||||
* @param password user provided password. not null
|
||||
* @param asReq the original AS-REQ sent, used to validate AS-REP
|
||||
* @param cname the user principal name, used to provide salt
|
||||
*/
|
||||
void decryptUsingPassword(char[] password,
|
||||
KrbAsReq asReq, PrincipalName cname)
|
||||
throws KrbException, Asn1Exception, IOException {
|
||||
int encPartKeyType = rep.encPart.getEType();
|
||||
EncryptionKey dkey = EncryptionKey.acquireSecretKey(
|
||||
cname,
|
||||
password,
|
||||
encPartKeyType,
|
||||
PAData.getSaltAndParams(encPartKeyType, rep.pAData));
|
||||
decrypt(dkey, asReq, cname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts encrypted content inside AS-REP. Called by initiator.
|
||||
* @param dkey the decryption key to use
|
||||
* @param asReq the original AS-REQ sent, used to validate AS-REP
|
||||
*/
|
||||
private void decrypt(EncryptionKey dkey, KrbAsReq asReq,
|
||||
PrincipalName cname)
|
||||
throws KrbException, Asn1Exception, IOException {
|
||||
byte[] enc_as_rep_bytes = rep.encPart.decrypt(dkey,
|
||||
KeyUsage.KU_ENC_AS_REP_PART);
|
||||
byte[] enc_as_rep_part = rep.encPart.reset(enc_as_rep_bytes);
|
||||
|
||||
DerValue encoding = new DerValue(enc_as_rep_part);
|
||||
EncASRepPart enc_part = new EncASRepPart(encoding);
|
||||
rep.encKDCRepPart = enc_part;
|
||||
|
||||
ASReq req = asReq.getMessage();
|
||||
check(true, req, rep, dkey);
|
||||
|
||||
PrincipalName clientAlias = cname;
|
||||
if (clientAlias.equals(rep.cname))
|
||||
clientAlias = null;
|
||||
|
||||
creds = new Credentials(
|
||||
rep.ticket,
|
||||
rep.cname,
|
||||
clientAlias,
|
||||
enc_part.sname,
|
||||
null, // No server alias expected in a TGT
|
||||
enc_part.key,
|
||||
enc_part.flags,
|
||||
enc_part.authtime,
|
||||
enc_part.starttime,
|
||||
enc_part.endtime,
|
||||
enc_part.renewTill,
|
||||
enc_part.caddr);
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KrbAsRep cons in KrbAsReq.getReply " +
|
||||
req.reqBody.cname.getNameString());
|
||||
}
|
||||
}
|
||||
|
||||
Credentials getCreds() {
|
||||
return Objects.requireNonNull(creds, "Creds not available yet.");
|
||||
}
|
||||
|
||||
sun.security.krb5.internal.ccache.Credentials getCCreds() {
|
||||
return new sun.security.krb5.internal.ccache.Credentials(rep);
|
||||
}
|
||||
}
|
||||
178
jdkSrc/jdk8/sun/security/krb5/KrbAsReq.java
Normal file
178
jdkSrc/jdk8/sun/security/krb5/KrbAsReq.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.Nonce;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class encapsulates the KRB-AS-REQ message that the client
|
||||
* sends to the KDC.
|
||||
*/
|
||||
public class KrbAsReq {
|
||||
private ASReq asReqMessg;
|
||||
|
||||
private boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
/**
|
||||
* Constructs an AS-REQ message.
|
||||
*/
|
||||
// Can be null? has default?
|
||||
public KrbAsReq(EncryptionKey pakey, // ok
|
||||
KDCOptions options, // ok, new KDCOptions()
|
||||
PrincipalName cname, // NO and must have realm
|
||||
PrincipalName sname, // ok, krgtgt@CREALM
|
||||
KerberosTime from, // ok
|
||||
KerberosTime till, // ok, will use
|
||||
KerberosTime rtime, // ok
|
||||
int[] eTypes, // NO
|
||||
HostAddresses addresses, // ok
|
||||
PAData[] extraPAs // ok
|
||||
)
|
||||
throws KrbException, IOException {
|
||||
|
||||
if (options == null) {
|
||||
options = new KDCOptions();
|
||||
}
|
||||
// check if they are valid arguments. The optional fields should be
|
||||
// consistent with settings in KDCOptions. Mar 17 2000
|
||||
if (options.get(KDCOptions.FORWARDED) ||
|
||||
options.get(KDCOptions.PROXY) ||
|
||||
options.get(KDCOptions.ENC_TKT_IN_SKEY) ||
|
||||
options.get(KDCOptions.RENEW) ||
|
||||
options.get(KDCOptions.VALIDATE)) {
|
||||
// this option is only specified in a request to the
|
||||
// ticket-granting server
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
}
|
||||
if (options.get(KDCOptions.POSTDATED)) {
|
||||
// if (from == null)
|
||||
// throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
} else {
|
||||
if (from != null) from = null;
|
||||
}
|
||||
|
||||
PAData[] paData = null;
|
||||
if (pakey != null) {
|
||||
PAEncTSEnc ts = new PAEncTSEnc();
|
||||
byte[] temp = ts.asn1Encode();
|
||||
EncryptedData encTs = new EncryptedData(pakey, temp,
|
||||
KeyUsage.KU_PA_ENC_TS);
|
||||
paData = new PAData[1];
|
||||
paData[0] = new PAData( Krb5.PA_ENC_TIMESTAMP,
|
||||
encTs.asn1Encode());
|
||||
}
|
||||
if (extraPAs != null && extraPAs.length > 0) {
|
||||
if (paData == null) {
|
||||
paData = new PAData[extraPAs.length];
|
||||
} else {
|
||||
paData = Arrays.copyOf(paData, paData.length + extraPAs.length);
|
||||
}
|
||||
System.arraycopy(extraPAs, 0, paData,
|
||||
paData.length - extraPAs.length, extraPAs.length);
|
||||
}
|
||||
|
||||
if (cname.getRealm() == null) {
|
||||
throw new RealmException(Krb5.REALM_NULL,
|
||||
"default realm not specified ");
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KrbAsReq creating message");
|
||||
}
|
||||
|
||||
Config cfg = Config.getInstance();
|
||||
|
||||
// check to use addresses in tickets
|
||||
if (addresses == null && cfg.useAddresses()) {
|
||||
addresses = HostAddresses.getLocalAddresses();
|
||||
}
|
||||
|
||||
if (sname == null) {
|
||||
String realm = cname.getRealmAsString();
|
||||
sname = PrincipalName.tgsService(realm, realm);
|
||||
}
|
||||
|
||||
if (till == null) {
|
||||
String d = cfg.get("libdefaults", "ticket_lifetime");
|
||||
if (d != null) {
|
||||
till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
|
||||
} else {
|
||||
till = new KerberosTime(0); // Choose KDC maximum allowed
|
||||
}
|
||||
}
|
||||
|
||||
if (rtime == null) {
|
||||
String d = cfg.get("libdefaults", "renew_lifetime");
|
||||
if (d != null) {
|
||||
rtime = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
|
||||
}
|
||||
}
|
||||
|
||||
if (rtime != null) {
|
||||
options.set(KDCOptions.RENEWABLE, true);
|
||||
if (till.greaterThan(rtime)) {
|
||||
rtime = till;
|
||||
}
|
||||
}
|
||||
|
||||
// enc-authorization-data and additional-tickets never in AS-REQ
|
||||
KDCReqBody kdc_req_body = new KDCReqBody(options,
|
||||
cname,
|
||||
sname,
|
||||
from,
|
||||
till,
|
||||
rtime,
|
||||
Nonce.value(),
|
||||
eTypes,
|
||||
addresses,
|
||||
null,
|
||||
null);
|
||||
|
||||
asReqMessg = new ASReq(
|
||||
paData,
|
||||
kdc_req_body);
|
||||
}
|
||||
|
||||
byte[] encoding() throws IOException, Asn1Exception {
|
||||
return asReqMessg.asn1Encode();
|
||||
}
|
||||
|
||||
// Used by KrbAsRep to validate AS-REP
|
||||
ASReq getMessage() {
|
||||
return asReqMessg;
|
||||
}
|
||||
}
|
||||
538
jdkSrc/jdk8/sun/security/krb5/KrbAsReqBuilder.java
Normal file
538
jdkSrc/jdk8/sun/security/krb5/KrbAsReqBuilder.java
Normal file
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2020, 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 sun.security.krb5;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import javax.security.auth.kerberos.KeyTab;
|
||||
import sun.security.jgss.krb5.Krb5Util;
|
||||
import sun.security.krb5.internal.HostAddresses;
|
||||
import sun.security.krb5.internal.KDCOptions;
|
||||
import sun.security.krb5.internal.KRBError;
|
||||
import sun.security.krb5.internal.KerberosTime;
|
||||
import sun.security.krb5.internal.Krb5;
|
||||
import sun.security.krb5.internal.PAData;
|
||||
import sun.security.krb5.internal.crypto.EType;
|
||||
|
||||
/**
|
||||
* A manager class for AS-REQ communications.
|
||||
*
|
||||
* This class does:
|
||||
* 1. Gather information to create AS-REQ
|
||||
* 2. Create and send AS-REQ
|
||||
* 3. Receive AS-REP and KRB-ERROR (-KRB_ERR_RESPONSE_TOO_BIG) and parse them
|
||||
* 4. Emit credentials and secret keys (for JAAS storeKey=true with password)
|
||||
*
|
||||
* This class does not:
|
||||
* 1. Deal with real communications (KdcComm does it, and TGS-REQ)
|
||||
* a. Name of KDCs for a realm
|
||||
* b. Server availability, timeout, UDP or TCP
|
||||
* d. KRB_ERR_RESPONSE_TOO_BIG
|
||||
* 2. Stores its own copy of password, this means:
|
||||
* a. Do not change/wipe it before Builder finish
|
||||
* b. Builder will not wipe it for you
|
||||
*
|
||||
* With this class:
|
||||
* 1. KrbAsReq has only one constructor
|
||||
* 2. Krb5LoginModule and Kinit call a single builder
|
||||
* 3. Better handling of sensitive info
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
|
||||
public final class KrbAsReqBuilder {
|
||||
|
||||
// Common data for AS-REQ fields
|
||||
private KDCOptions options;
|
||||
private PrincipalName cname;
|
||||
private PrincipalName refCname; // May be changed by referrals
|
||||
private PrincipalName sname;
|
||||
private KerberosTime from;
|
||||
private KerberosTime till;
|
||||
private KerberosTime rtime;
|
||||
private HostAddresses addresses;
|
||||
|
||||
// Secret source: can't be changed once assigned, only one (of the two
|
||||
// sources) can be set to non-null
|
||||
private final char[] password;
|
||||
private final KeyTab ktab;
|
||||
|
||||
// Used to create a ENC-TIMESTAMP in the 2nd AS-REQ
|
||||
private PAData[] paList; // PA-DATA from both KRB-ERROR and AS-REP.
|
||||
// Used by getKeys() only.
|
||||
// Only AS-REP should be enough per RFC,
|
||||
// combined in case etypes are different.
|
||||
|
||||
// The generated and received:
|
||||
private KrbAsReq req;
|
||||
private KrbAsRep rep;
|
||||
|
||||
private static enum State {
|
||||
INIT, // Initialized, can still add more initialization info
|
||||
REQ_OK, // AS-REQ performed
|
||||
DESTROYED, // Destroyed, not usable anymore
|
||||
}
|
||||
private State state;
|
||||
|
||||
// Called by other constructors
|
||||
private void init(PrincipalName cname)
|
||||
throws KrbException {
|
||||
this.cname = cname;
|
||||
this.refCname = cname;
|
||||
state = State.INIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a builder to be used by {@code cname} with existing keys.
|
||||
*
|
||||
* @param cname the client of the AS-REQ. Must not be null. Might have no
|
||||
* realm, where default realm will be used. This realm will be the target
|
||||
* realm for AS-REQ. I believe a client should only get initial TGT from
|
||||
* its own realm.
|
||||
* @param ktab must not be null. If empty, might be quite useless.
|
||||
* This argument will neither be modified nor stored by the method.
|
||||
* @throws KrbException
|
||||
*/
|
||||
public KrbAsReqBuilder(PrincipalName cname, KeyTab ktab)
|
||||
throws KrbException {
|
||||
init(cname);
|
||||
this.ktab = ktab;
|
||||
this.password = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a builder to be used by {@code cname} with a known password.
|
||||
*
|
||||
* @param cname the client of the AS-REQ. Must not be null. Might have no
|
||||
* realm, where default realm will be used. This realm will be the target
|
||||
* realm for AS-REQ. I believe a client should only get initial TGT from
|
||||
* its own realm.
|
||||
* @param pass must not be null. This argument will neither be modified
|
||||
* nor stored by the method.
|
||||
* @throws KrbException
|
||||
*/
|
||||
public KrbAsReqBuilder(PrincipalName cname, char[] pass)
|
||||
throws KrbException {
|
||||
init(cname);
|
||||
this.password = pass.clone();
|
||||
this.ktab = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an array of secret keys for the client. This is used when
|
||||
* the client supplies password but need keys to act as an acceptor. For
|
||||
* an initiator, it must be called after AS-REQ is performed (state is OK).
|
||||
* For an acceptor, it can be called when this KrbAsReqBuilder object is
|
||||
* constructed (state is INIT).
|
||||
* @param isInitiator if the caller is an initiator
|
||||
* @return generated keys from password. PA-DATA from server might be used.
|
||||
* All "default_tkt_enctypes" keys will be generated, Never null.
|
||||
* @throws IllegalStateException if not constructed from a password
|
||||
* @throws KrbException
|
||||
*/
|
||||
public EncryptionKey[] getKeys(boolean isInitiator) throws KrbException {
|
||||
checkState(isInitiator?State.REQ_OK:State.INIT, "Cannot get keys");
|
||||
if (password != null) {
|
||||
int[] eTypes = EType.getDefaults("default_tkt_enctypes");
|
||||
EncryptionKey[] result = new EncryptionKey[eTypes.length];
|
||||
|
||||
/*
|
||||
* Returns an array of keys. Before KrbAsReqBuilder, all etypes
|
||||
* use the same salt which is either the default one or a new salt
|
||||
* coming from PA-DATA. After KrbAsReqBuilder, each etype uses its
|
||||
* own new salt from PA-DATA. For an etype with no PA-DATA new salt
|
||||
* at all, what salt should it use?
|
||||
*
|
||||
* Commonly, the stored keys are only to be used by an acceptor to
|
||||
* decrypt service ticket in AP-REQ. Most impls only allow keys
|
||||
* from a keytab on acceptor, but unfortunately (?) Java supports
|
||||
* acceptor using password. In this case, if the service ticket is
|
||||
* encrypted using an etype which we don't have PA-DATA new salt,
|
||||
* using the default salt might be wrong (say, case-insensitive
|
||||
* user name). Instead, we would use the new salt of another etype.
|
||||
*/
|
||||
|
||||
String salt = null; // the saved new salt
|
||||
try {
|
||||
for (int i=0; i<eTypes.length; i++) {
|
||||
// First round, only calculate those have a PA entry
|
||||
PAData.SaltAndParams snp =
|
||||
PAData.getSaltAndParams(eTypes[i], paList);
|
||||
if (snp != null) {
|
||||
// Never uses a salt for rc4-hmac, it does not use
|
||||
// a salt at all
|
||||
if (eTypes[i] != EncryptedData.ETYPE_ARCFOUR_HMAC &&
|
||||
snp.salt != null) {
|
||||
salt = snp.salt;
|
||||
}
|
||||
result[i] = EncryptionKey.acquireSecretKey(cname,
|
||||
password,
|
||||
eTypes[i],
|
||||
snp);
|
||||
}
|
||||
}
|
||||
// No new salt from PA, maybe empty, maybe only rc4-hmac
|
||||
if (salt == null) salt = cname.getSalt();
|
||||
for (int i=0; i<eTypes.length; i++) {
|
||||
// Second round, calculate those with no PA entry
|
||||
if (result[i] == null) {
|
||||
result[i] = EncryptionKey.acquireSecretKey(password,
|
||||
salt,
|
||||
eTypes[i],
|
||||
null);
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
KrbException ke = new KrbException(Krb5.ASN1_PARSE_ERROR);
|
||||
ke.initCause(ioe);
|
||||
throw ke;
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new IllegalStateException("Required password not provided");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or clears options. If cleared, default options will be used
|
||||
* at creation time.
|
||||
* @param options
|
||||
*/
|
||||
public void setOptions(KDCOptions options) {
|
||||
checkState(State.INIT, "Cannot specify options");
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public void setTill(KerberosTime till) {
|
||||
checkState(State.INIT, "Cannot specify till");
|
||||
this.till = till;
|
||||
}
|
||||
|
||||
public void setRTime(KerberosTime rtime) {
|
||||
checkState(State.INIT, "Cannot specify rtime");
|
||||
this.rtime = rtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or clears target. If cleared, KrbAsReq might choose krbtgt
|
||||
* for cname realm
|
||||
* @param sname
|
||||
*/
|
||||
public void setTarget(PrincipalName sname) {
|
||||
checkState(State.INIT, "Cannot specify target");
|
||||
this.sname = sname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or clears addresses. KrbAsReq might add some if empty
|
||||
* field not allowed
|
||||
* @param addresses
|
||||
*/
|
||||
public void setAddresses(HostAddresses addresses) {
|
||||
checkState(State.INIT, "Cannot specify addresses");
|
||||
this.addresses = addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a KrbAsReq object from all info fed above. Normally this method
|
||||
* will be called twice: initial AS-REQ and second with pakey
|
||||
* @param key null (initial AS-REQ) or pakey (with preauth)
|
||||
* @return the KrbAsReq object
|
||||
* @throws KrbException
|
||||
* @throws IOException
|
||||
*/
|
||||
private KrbAsReq build(EncryptionKey key, ReferralsState referralsState)
|
||||
throws KrbException, IOException {
|
||||
PAData[] extraPAs = null;
|
||||
int[] eTypes;
|
||||
if (password != null) {
|
||||
eTypes = EType.getDefaults("default_tkt_enctypes");
|
||||
} else {
|
||||
EncryptionKey[] ks = Krb5Util.keysFromJavaxKeyTab(ktab, cname);
|
||||
eTypes = EType.getDefaults("default_tkt_enctypes",
|
||||
ks);
|
||||
for (EncryptionKey k: ks) k.destroy();
|
||||
}
|
||||
options = (options == null) ? new KDCOptions() : options;
|
||||
if (referralsState.isEnabled()) {
|
||||
if (referralsState.sendCanonicalize()) {
|
||||
options.set(KDCOptions.CANONICALIZE, true);
|
||||
}
|
||||
extraPAs = new PAData[]{ new PAData(Krb5.PA_REQ_ENC_PA_REP,
|
||||
new byte[]{}) };
|
||||
} else {
|
||||
options.set(KDCOptions.CANONICALIZE, false);
|
||||
}
|
||||
return new KrbAsReq(key,
|
||||
options,
|
||||
refCname,
|
||||
sname,
|
||||
from,
|
||||
till,
|
||||
rtime,
|
||||
eTypes,
|
||||
addresses,
|
||||
extraPAs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses AS-REP, decrypts enc-part, retrieves ticket and session key
|
||||
* @throws KrbException
|
||||
* @throws Asn1Exception
|
||||
* @throws IOException
|
||||
*/
|
||||
private KrbAsReqBuilder resolve()
|
||||
throws KrbException, Asn1Exception, IOException {
|
||||
if (ktab != null) {
|
||||
rep.decryptUsingKeyTab(ktab, req, cname);
|
||||
} else {
|
||||
rep.decryptUsingPassword(password, req, cname);
|
||||
}
|
||||
if (rep.getPA() != null) {
|
||||
if (paList == null || paList.length == 0) {
|
||||
paList = rep.getPA();
|
||||
} else {
|
||||
int extraLen = rep.getPA().length;
|
||||
if (extraLen > 0) {
|
||||
int oldLen = paList.length;
|
||||
paList = Arrays.copyOf(paList, paList.length + extraLen);
|
||||
System.arraycopy(rep.getPA(), 0, paList, oldLen, extraLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Communication until AS-REP or non preauth-related KRB-ERROR received
|
||||
* @throws KrbException
|
||||
* @throws IOException
|
||||
*/
|
||||
private KrbAsReqBuilder send() throws KrbException, IOException {
|
||||
boolean preAuthFailedOnce = false;
|
||||
KdcComm comm = null;
|
||||
EncryptionKey pakey = null;
|
||||
ReferralsState referralsState = new ReferralsState(this);
|
||||
while (true) {
|
||||
if (referralsState.refreshComm()) {
|
||||
comm = new KdcComm(refCname.getRealmAsString());
|
||||
}
|
||||
try {
|
||||
req = build(pakey, referralsState);
|
||||
rep = new KrbAsRep(comm.send(req.encoding()));
|
||||
return this;
|
||||
} catch (KrbException ke) {
|
||||
if (!preAuthFailedOnce && (
|
||||
ke.returnCode() == Krb5.KDC_ERR_PREAUTH_FAILED ||
|
||||
ke.returnCode() == Krb5.KDC_ERR_PREAUTH_REQUIRED)) {
|
||||
if (Krb5.DEBUG) {
|
||||
System.out.println("KrbAsReqBuilder: " +
|
||||
"PREAUTH FAILED/REQ, re-send AS-REQ");
|
||||
}
|
||||
preAuthFailedOnce = true;
|
||||
KRBError kerr = ke.getError();
|
||||
int paEType = PAData.getPreferredEType(kerr.getPA(),
|
||||
EType.getDefaults("default_tkt_enctypes")[0]);
|
||||
if (password == null) {
|
||||
EncryptionKey[] ks = Krb5Util.keysFromJavaxKeyTab(ktab, cname);
|
||||
pakey = EncryptionKey.findKey(paEType, ks);
|
||||
if (pakey != null) pakey = (EncryptionKey)pakey.clone();
|
||||
for (EncryptionKey k: ks) k.destroy();
|
||||
} else {
|
||||
pakey = EncryptionKey.acquireSecretKey(cname,
|
||||
password,
|
||||
paEType,
|
||||
PAData.getSaltAndParams(
|
||||
paEType, kerr.getPA()));
|
||||
}
|
||||
paList = kerr.getPA(); // Update current paList
|
||||
} else {
|
||||
if (referralsState.handleError(ke)) {
|
||||
pakey = null;
|
||||
preAuthFailedOnce = false;
|
||||
continue;
|
||||
}
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class ReferralsState {
|
||||
private static boolean canonicalizeConfig;
|
||||
private boolean enabled;
|
||||
private boolean sendCanonicalize;
|
||||
private boolean isEnterpriseCname;
|
||||
private int count;
|
||||
private boolean refreshComm;
|
||||
private KrbAsReqBuilder reqBuilder;
|
||||
|
||||
static {
|
||||
initStatic();
|
||||
}
|
||||
|
||||
// Config may be refreshed while running so the setting
|
||||
// value may need to be updated. See Config::refresh.
|
||||
static void initStatic() {
|
||||
canonicalizeConfig = false;
|
||||
try {
|
||||
canonicalizeConfig = Config.getInstance()
|
||||
.getBooleanObject("libdefaults", "canonicalize") ==
|
||||
Boolean.TRUE;
|
||||
} catch (KrbException e) {
|
||||
if (Krb5.DEBUG) {
|
||||
System.out.println("Exception in getting canonicalize," +
|
||||
" using default value " +
|
||||
Boolean.valueOf(canonicalizeConfig) + ": " +
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReferralsState(KrbAsReqBuilder reqBuilder) throws KrbException {
|
||||
this.reqBuilder = reqBuilder;
|
||||
sendCanonicalize = canonicalizeConfig;
|
||||
isEnterpriseCname = reqBuilder.refCname.getNameType() ==
|
||||
PrincipalName.KRB_NT_ENTERPRISE;
|
||||
updateStatus();
|
||||
if (!enabled && isEnterpriseCname) {
|
||||
throw new KrbException("NT-ENTERPRISE principals only" +
|
||||
" allowed when referrals are enabled.");
|
||||
}
|
||||
refreshComm = true;
|
||||
}
|
||||
|
||||
private void updateStatus() {
|
||||
enabled = !Config.DISABLE_REFERRALS &&
|
||||
(isEnterpriseCname || sendCanonicalize);
|
||||
}
|
||||
|
||||
boolean handleError(KrbException ke) throws RealmException {
|
||||
if (enabled) {
|
||||
if (ke.returnCode() == Krb5.KRB_ERR_WRONG_REALM) {
|
||||
Realm referredRealm = ke.getError().getClientRealm();
|
||||
if (referredRealm != null &&
|
||||
!referredRealm.toString().isEmpty() &&
|
||||
count < Config.MAX_REFERRALS) {
|
||||
// A valid referral was received while referrals
|
||||
// were enabled. Change the cname realm to the referred
|
||||
// realm and set refreshComm to send a new request.
|
||||
reqBuilder.refCname = new PrincipalName(
|
||||
reqBuilder.refCname.getNameType(),
|
||||
reqBuilder.refCname.getNameStrings(),
|
||||
referredRealm);
|
||||
refreshComm = true;
|
||||
count++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (count < Config.MAX_REFERRALS && sendCanonicalize) {
|
||||
if (Krb5.DEBUG) {
|
||||
System.out.println("KrbAsReqBuilder: AS-REQ failed." +
|
||||
" Retrying with CANONICALIZE false.");
|
||||
}
|
||||
|
||||
// Server returned an unexpected error with
|
||||
// CANONICALIZE true. Retry with false.
|
||||
sendCanonicalize = false;
|
||||
|
||||
// Setting CANONICALIZE to false may imply that referrals
|
||||
// are now disabled (if cname is not of NT-ENTERPRISE type).
|
||||
updateStatus();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean refreshComm() {
|
||||
boolean retRefreshComm = refreshComm;
|
||||
refreshComm = false;
|
||||
return retRefreshComm;
|
||||
}
|
||||
|
||||
boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
boolean sendCanonicalize() {
|
||||
return sendCanonicalize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs AS-REQ send and AS-REP receive.
|
||||
* Maybe a state is needed here, to divide prepare process and getCreds.
|
||||
* @throws KrbException
|
||||
* @throws Asn1Exception
|
||||
* @throws IOException
|
||||
*/
|
||||
public KrbAsReqBuilder action()
|
||||
throws KrbException, Asn1Exception, IOException {
|
||||
checkState(State.INIT, "Cannot call action");
|
||||
state = State.REQ_OK;
|
||||
return send().resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Credentials object after action
|
||||
*/
|
||||
public Credentials getCreds() {
|
||||
checkState(State.REQ_OK, "Cannot retrieve creds");
|
||||
return rep.getCreds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets another type of Credentials after action
|
||||
*/
|
||||
public sun.security.krb5.internal.ccache.Credentials getCCreds() {
|
||||
checkState(State.REQ_OK, "Cannot retrieve CCreds");
|
||||
return rep.getCCreds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the object and clears keys and password info.
|
||||
*/
|
||||
public void destroy() {
|
||||
state = State.DESTROYED;
|
||||
if (password != null) {
|
||||
Arrays.fill(password, (char)0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current state is the specified one.
|
||||
* @param st the expected state
|
||||
* @param msg error message if state is not correct
|
||||
* @throws IllegalStateException if state is not correct
|
||||
*/
|
||||
private void checkState(State st, String msg) {
|
||||
if (state != st) {
|
||||
throw new IllegalStateException(msg + " at " + st + " state");
|
||||
}
|
||||
}
|
||||
}
|
||||
174
jdkSrc/jdk8/sun/security/krb5/KrbCred.java
Normal file
174
jdkSrc/jdk8/sun/security/krb5/KrbCred.java
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* This class encapsulates the KRB-CRED message that a client uses to
|
||||
* send its delegated credentials to a server.
|
||||
*
|
||||
* Supports delegation of one ticket only.
|
||||
* @author Mayank Upadhyay
|
||||
*/
|
||||
public class KrbCred {
|
||||
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
private byte[] obuf = null;
|
||||
private KRBCred credMessg = null;
|
||||
private Ticket ticket = null;
|
||||
private EncKrbCredPart encPart = null;
|
||||
private Credentials creds = null;
|
||||
private KerberosTime timeStamp = null;
|
||||
|
||||
// Used in InitialToken with null key
|
||||
public KrbCred(Credentials tgt,
|
||||
Credentials serviceTicket,
|
||||
EncryptionKey key)
|
||||
throws KrbException, IOException {
|
||||
|
||||
PrincipalName client = tgt.getClient();
|
||||
PrincipalName tgService = tgt.getServer();
|
||||
if (!serviceTicket.getClient().equals(client))
|
||||
throw new KrbException(Krb5.KRB_ERR_GENERIC,
|
||||
"Client principal does not match");
|
||||
|
||||
// XXX Check Windows flag OK-TO-FORWARD-TO
|
||||
|
||||
// Invoke TGS-REQ to get a forwarded TGT for the peer
|
||||
|
||||
KDCOptions options = new KDCOptions();
|
||||
options.set(KDCOptions.FORWARDED, true);
|
||||
options.set(KDCOptions.FORWARDABLE, true);
|
||||
|
||||
KrbTgsReq tgsReq = new KrbTgsReq(options, tgt, tgService,
|
||||
null, null, null, null, null,
|
||||
null, // No easy way to get addresses right
|
||||
null, null, null);
|
||||
credMessg = createMessage(tgsReq.sendAndGetCreds(), key);
|
||||
|
||||
obuf = credMessg.asn1Encode();
|
||||
}
|
||||
|
||||
KRBCred createMessage(Credentials delegatedCreds, EncryptionKey key)
|
||||
throws KrbException, IOException {
|
||||
|
||||
EncryptionKey sessionKey
|
||||
= delegatedCreds.getSessionKey();
|
||||
PrincipalName princ = delegatedCreds.getClient();
|
||||
PrincipalName tgService = delegatedCreds.getServer();
|
||||
|
||||
KrbCredInfo credInfo = new KrbCredInfo(sessionKey,
|
||||
princ, delegatedCreds.flags, delegatedCreds.authTime,
|
||||
delegatedCreds.startTime, delegatedCreds.endTime,
|
||||
delegatedCreds.renewTill, tgService,
|
||||
delegatedCreds.cAddr);
|
||||
|
||||
timeStamp = KerberosTime.now();
|
||||
KrbCredInfo[] credInfos = {credInfo};
|
||||
EncKrbCredPart encPart =
|
||||
new EncKrbCredPart(credInfos,
|
||||
timeStamp, null, null, null, null);
|
||||
|
||||
EncryptedData encEncPart = new EncryptedData(key,
|
||||
encPart.asn1Encode(), KeyUsage.KU_ENC_KRB_CRED_PART);
|
||||
|
||||
Ticket[] tickets = {delegatedCreds.ticket};
|
||||
|
||||
credMessg = new KRBCred(tickets, encEncPart);
|
||||
|
||||
return credMessg;
|
||||
}
|
||||
|
||||
// Used in InitialToken, NULL_KEY might be used
|
||||
public KrbCred(byte[] asn1Message, EncryptionKey key)
|
||||
throws KrbException, IOException {
|
||||
|
||||
credMessg = new KRBCred(asn1Message);
|
||||
|
||||
ticket = credMessg.tickets[0];
|
||||
|
||||
if (credMessg.encPart.getEType() == 0) {
|
||||
key = EncryptionKey.NULL_KEY;
|
||||
}
|
||||
byte[] temp = credMessg.encPart.decrypt(key,
|
||||
KeyUsage.KU_ENC_KRB_CRED_PART);
|
||||
byte[] plainText = credMessg.encPart.reset(temp);
|
||||
DerValue encoding = new DerValue(plainText);
|
||||
EncKrbCredPart encPart = new EncKrbCredPart(encoding);
|
||||
|
||||
timeStamp = encPart.timeStamp;
|
||||
|
||||
KrbCredInfo credInfo = encPart.ticketInfo[0];
|
||||
EncryptionKey credInfoKey = credInfo.key;
|
||||
PrincipalName pname = credInfo.pname;
|
||||
TicketFlags flags = credInfo.flags;
|
||||
KerberosTime authtime = credInfo.authtime;
|
||||
KerberosTime starttime = credInfo.starttime;
|
||||
KerberosTime endtime = credInfo.endtime;
|
||||
KerberosTime renewTill = credInfo.renewTill;
|
||||
PrincipalName sname = credInfo.sname;
|
||||
HostAddresses caddr = credInfo.caddr;
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>Delegated Creds have pname=" + pname
|
||||
+ " sname=" + sname
|
||||
+ " authtime=" + authtime
|
||||
+ " starttime=" + starttime
|
||||
+ " endtime=" + endtime
|
||||
+ "renewTill=" + renewTill);
|
||||
}
|
||||
creds = new Credentials(ticket, pname, null, sname, null, credInfoKey,
|
||||
flags, authtime, starttime, endtime, renewTill, caddr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the delegated credentials from the peer.
|
||||
*/
|
||||
public Credentials[] getDelegatedCreds() {
|
||||
|
||||
Credentials[] allCreds = {creds};
|
||||
return allCreds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ASN.1 encoding that should be sent to the peer.
|
||||
*/
|
||||
public byte[] getMessage() {
|
||||
return obuf;
|
||||
}
|
||||
}
|
||||
45
jdkSrc/jdk8/sun/security/krb5/KrbCryptoException.java
Normal file
45
jdkSrc/jdk8/sun/security/krb5/KrbCryptoException.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
/**
|
||||
* KrbCryptoExceptoin is a wrapper exception for exceptions thrown by JCE.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public class KrbCryptoException extends KrbException {
|
||||
|
||||
private static final long serialVersionUID = -1657367919979982250L;
|
||||
|
||||
public KrbCryptoException (String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
159
jdkSrc/jdk8/sun/security/krb5/KrbException.java
Normal file
159
jdkSrc/jdk8/sun/security/krb5/KrbException.java
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.Krb5;
|
||||
import sun.security.krb5.internal.KRBError;
|
||||
|
||||
public class KrbException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -4993302876451928596L;
|
||||
|
||||
private int returnCode;
|
||||
private KRBError error;
|
||||
|
||||
public KrbException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public KrbException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public KrbException(int i) {
|
||||
returnCode = i;
|
||||
}
|
||||
|
||||
public KrbException(int i, String s) {
|
||||
this(s);
|
||||
returnCode = i;
|
||||
}
|
||||
|
||||
public KrbException(KRBError e) {
|
||||
returnCode = e.getErrorCode();
|
||||
error = e;
|
||||
}
|
||||
|
||||
public KrbException(KRBError e, String s) {
|
||||
this(s);
|
||||
returnCode = e.getErrorCode();
|
||||
error = e;
|
||||
}
|
||||
|
||||
public KRBError getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
public int returnCode() {
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
public String returnCodeSymbol() {
|
||||
return returnCodeSymbol(returnCode);
|
||||
}
|
||||
|
||||
public static String returnCodeSymbol(int i) {
|
||||
return "not yet implemented";
|
||||
}
|
||||
|
||||
public String returnCodeMessage() {
|
||||
return Krb5.getErrorMessage(returnCode);
|
||||
}
|
||||
|
||||
public static String errorMessage(int i) {
|
||||
return Krb5.getErrorMessage(i);
|
||||
}
|
||||
|
||||
|
||||
public String krbErrorMessage() {
|
||||
StringBuffer strbuf = new StringBuffer("krb_error " + returnCode);
|
||||
String msg = getMessage();
|
||||
if (msg != null) {
|
||||
strbuf.append(" ");
|
||||
strbuf.append(msg);
|
||||
}
|
||||
return strbuf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns messages like:
|
||||
* "Integrity check on decrypted field failed (31) - \
|
||||
* Could not decrypt service ticket"
|
||||
* If the error code is 0 then the first half is skipped.
|
||||
*/
|
||||
public String getMessage() {
|
||||
StringBuffer message = new StringBuffer();
|
||||
int returnCode = returnCode();
|
||||
if (returnCode != 0) {
|
||||
message.append(returnCodeMessage());
|
||||
message.append(" (").append(returnCode()).append(')');
|
||||
}
|
||||
String consMessage = super.getMessage();
|
||||
if (consMessage != null && consMessage.length() != 0) {
|
||||
if (returnCode != 0)
|
||||
message.append(" - ");
|
||||
message.append(consMessage);
|
||||
}
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ("KrbException: " + getMessage());
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
int result = 17;
|
||||
result = 37 * result + returnCode;
|
||||
if (error != null) {
|
||||
result = 37 * result + error.hashCode();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof KrbException)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KrbException other = (KrbException)obj;
|
||||
if (returnCode != other.returnCode) {
|
||||
return false;
|
||||
}
|
||||
return (error == null)?(other.error == null):
|
||||
(error.equals(other.error));
|
||||
}
|
||||
}
|
||||
189
jdkSrc/jdk8/sun/security/krb5/KrbKdcRep.java
Normal file
189
jdkSrc/jdk8/sun/security/krb5/KrbKdcRep.java
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
import sun.security.util.DerInputStream;
|
||||
|
||||
abstract class KrbKdcRep {
|
||||
|
||||
static void check(
|
||||
boolean isAsReq,
|
||||
KDCReq req,
|
||||
KDCRep rep,
|
||||
EncryptionKey replyKey
|
||||
) throws KrbApErrException {
|
||||
|
||||
// cname change in AS-REP is allowed only if the client
|
||||
// sent CANONICALIZE or an NT-ENTERPRISE cname in the request, and the
|
||||
// server supports RFC 6806 - Section 11 FAST scheme (ENC-PA-REP flag).
|
||||
if (isAsReq && !req.reqBody.cname.equals(rep.cname) &&
|
||||
((!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&
|
||||
req.reqBody.cname.getNameType() !=
|
||||
PrincipalName.KRB_NT_ENTERPRISE) ||
|
||||
!rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) {
|
||||
rep.encKDCRepPart.key.destroy();
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
|
||||
// sname change in TGS-REP is allowed only if client
|
||||
// sent CANONICALIZE and new sname is a referral of
|
||||
// the form krbtgt/TO-REALM.COM@FROM-REALM.COM.
|
||||
if (!req.reqBody.sname.equals(rep.encKDCRepPart.sname)) {
|
||||
String[] snameStrings = rep.encKDCRepPart.sname.getNameStrings();
|
||||
if (isAsReq || !req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||
|
||||
snameStrings == null || snameStrings.length != 2 ||
|
||||
!snameStrings[0].equals(PrincipalName.TGS_DEFAULT_SRV_NAME) ||
|
||||
!rep.encKDCRepPart.sname.getRealmString().equals(
|
||||
req.reqBody.sname.getRealmString())) {
|
||||
rep.encKDCRepPart.key.destroy();
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
if (req.reqBody.getNonce() != rep.encKDCRepPart.nonce) {
|
||||
rep.encKDCRepPart.key.destroy();
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
|
||||
if (
|
||||
((req.reqBody.addresses != null && rep.encKDCRepPart.caddr != null) &&
|
||||
!req.reqBody.addresses.equals(rep.encKDCRepPart.caddr))) {
|
||||
rep.encKDCRepPart.key.destroy();
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
|
||||
// We allow KDC to return a non-forwardable ticket if request has -f
|
||||
for (int i = 2; i < 6; i++) {
|
||||
if (req.reqBody.kdcOptions.get(i) !=
|
||||
rep.encKDCRepPart.flags.get(i)) {
|
||||
if (Krb5.DEBUG) {
|
||||
System.out.println("> KrbKdcRep.check: at #" + i
|
||||
+ ". request for " + req.reqBody.kdcOptions.get(i)
|
||||
+ ", received " + rep.encKDCRepPart.flags.get(i));
|
||||
}
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
// Reply to a renewable request should be renewable, but if request does
|
||||
// not contain renewable, KDC is free to issue a renewable ticket (for
|
||||
// example, if ticket_lifetime is too big).
|
||||
if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE) &&
|
||||
!rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
|
||||
if ((req.reqBody.from == null) || req.reqBody.from.isZero()) {
|
||||
// verify this is allowed
|
||||
if ((rep.encKDCRepPart.starttime != null) &&
|
||||
!rep.encKDCRepPart.starttime.inClockSkew()) {
|
||||
rep.encKDCRepPart.key.destroy();
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
|
||||
}
|
||||
}
|
||||
|
||||
if ((req.reqBody.from != null) && !req.reqBody.from.isZero()) {
|
||||
// verify this is allowed
|
||||
if ((rep.encKDCRepPart.starttime != null) &&
|
||||
!req.reqBody.from.equals(rep.encKDCRepPart.starttime)) {
|
||||
rep.encKDCRepPart.key.destroy();
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
if (!req.reqBody.till.isZero() &&
|
||||
rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {
|
||||
rep.encKDCRepPart.key.destroy();
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
|
||||
// RFC 6806 - Section 11 mechanism check
|
||||
// The availability of the ENC-PA-REP flag in the KDC response is
|
||||
// mandatory on some cases (see Krb5.TKT_OPTS_ENC_PA_REP check above).
|
||||
if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP)) {
|
||||
boolean reqPaReqEncPaRep = false;
|
||||
boolean repPaReqEncPaRepValid = false;
|
||||
|
||||
if (req.pAData != null) {
|
||||
for (PAData pa : req.pAData) {
|
||||
if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
|
||||
// The KDC supports RFC 6806 and ENC-PA-REP was sent in
|
||||
// the request (AS-REQ). A valid checksum is now required.
|
||||
reqPaReqEncPaRep = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rep.encKDCRepPart.pAData != null) {
|
||||
for (PAData pa : rep.encKDCRepPart.pAData) {
|
||||
if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
|
||||
try {
|
||||
Checksum repCksum = new Checksum(
|
||||
new DerInputStream(
|
||||
pa.getValue()).getDerValue());
|
||||
// The checksum is inside encKDCRepPart so we don't
|
||||
// care if it's keyed or not.
|
||||
repPaReqEncPaRepValid =
|
||||
repCksum.verifyAnyChecksum(
|
||||
req.asn1Encode(), replyKey,
|
||||
KeyUsage.KU_AS_REQ);
|
||||
} catch (Exception e) {
|
||||
if (Krb5.DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reqPaReqEncPaRep && !repPaReqEncPaRepValid) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE)) {
|
||||
if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero()) {
|
||||
// verify this is required
|
||||
if ((rep.encKDCRepPart.renewTill == null) ||
|
||||
rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime)
|
||||
) {
|
||||
rep.encKDCRepPart.key.destroy();
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
178
jdkSrc/jdk8/sun/security/krb5/KrbPriv.java
Normal file
178
jdkSrc/jdk8/sun/security/krb5/KrbPriv.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/** XXX This class does not appear to be used. **/
|
||||
|
||||
class KrbPriv extends KrbAppMessage {
|
||||
private byte[] obuf;
|
||||
private byte[] userData;
|
||||
|
||||
private KrbPriv(byte[] userData,
|
||||
Credentials creds,
|
||||
EncryptionKey subKey,
|
||||
KerberosTime timestamp,
|
||||
SeqNumber seqNumber,
|
||||
HostAddress saddr,
|
||||
HostAddress raddr
|
||||
) throws KrbException, IOException {
|
||||
EncryptionKey reqKey = null;
|
||||
if (subKey != null)
|
||||
reqKey = subKey;
|
||||
else
|
||||
reqKey = creds.key;
|
||||
|
||||
obuf = mk_priv(
|
||||
userData,
|
||||
reqKey,
|
||||
timestamp,
|
||||
seqNumber,
|
||||
saddr,
|
||||
raddr
|
||||
);
|
||||
}
|
||||
|
||||
private KrbPriv(byte[] msg,
|
||||
Credentials creds,
|
||||
EncryptionKey subKey,
|
||||
SeqNumber seqNumber,
|
||||
HostAddress saddr,
|
||||
HostAddress raddr,
|
||||
boolean timestampRequired,
|
||||
boolean seqNumberRequired
|
||||
) throws KrbException, IOException {
|
||||
|
||||
KRBPriv krb_priv = new KRBPriv(msg);
|
||||
EncryptionKey reqKey = null;
|
||||
if (subKey != null)
|
||||
reqKey = subKey;
|
||||
else
|
||||
reqKey = creds.key;
|
||||
userData = rd_priv(krb_priv,
|
||||
reqKey,
|
||||
seqNumber,
|
||||
saddr,
|
||||
raddr,
|
||||
timestampRequired,
|
||||
seqNumberRequired,
|
||||
creds.client
|
||||
);
|
||||
}
|
||||
|
||||
public byte[] getMessage() throws KrbException {
|
||||
return obuf;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return userData;
|
||||
}
|
||||
|
||||
private byte[] mk_priv(byte[] userData,
|
||||
EncryptionKey key,
|
||||
KerberosTime timestamp,
|
||||
SeqNumber seqNumber,
|
||||
HostAddress sAddress,
|
||||
HostAddress rAddress
|
||||
) throws Asn1Exception, IOException,
|
||||
KdcErrException, KrbCryptoException {
|
||||
|
||||
Integer usec = null;
|
||||
Integer seqno = null;
|
||||
|
||||
if (timestamp != null)
|
||||
usec = new Integer(timestamp.getMicroSeconds());
|
||||
|
||||
if (seqNumber != null) {
|
||||
seqno = new Integer(seqNumber.current());
|
||||
seqNumber.step();
|
||||
}
|
||||
|
||||
EncKrbPrivPart unenc_encKrbPrivPart =
|
||||
new EncKrbPrivPart(userData,
|
||||
timestamp,
|
||||
usec,
|
||||
seqno,
|
||||
sAddress,
|
||||
rAddress
|
||||
);
|
||||
|
||||
byte[] temp = unenc_encKrbPrivPart.asn1Encode();
|
||||
|
||||
EncryptedData encKrbPrivPart =
|
||||
new EncryptedData(key, temp,
|
||||
KeyUsage.KU_ENC_KRB_PRIV_PART);
|
||||
|
||||
KRBPriv krb_priv = new KRBPriv(encKrbPrivPart);
|
||||
|
||||
temp = krb_priv.asn1Encode();
|
||||
|
||||
return krb_priv.asn1Encode();
|
||||
}
|
||||
|
||||
private byte[] rd_priv(KRBPriv krb_priv,
|
||||
EncryptionKey key,
|
||||
SeqNumber seqNumber,
|
||||
HostAddress sAddress,
|
||||
HostAddress rAddress,
|
||||
boolean timestampRequired,
|
||||
boolean seqNumberRequired,
|
||||
PrincipalName cname
|
||||
) throws Asn1Exception, KdcErrException,
|
||||
KrbApErrException, IOException, KrbCryptoException {
|
||||
|
||||
byte[] bytes = krb_priv.encPart.decrypt(key,
|
||||
KeyUsage.KU_ENC_KRB_PRIV_PART);
|
||||
byte[] temp = krb_priv.encPart.reset(bytes);
|
||||
DerValue ref = new DerValue(temp);
|
||||
EncKrbPrivPart enc_part = new EncKrbPrivPart(ref);
|
||||
|
||||
check(enc_part.timestamp,
|
||||
enc_part.usec,
|
||||
enc_part.seqNumber,
|
||||
enc_part.sAddress,
|
||||
enc_part.rAddress,
|
||||
seqNumber,
|
||||
sAddress,
|
||||
rAddress,
|
||||
timestampRequired,
|
||||
seqNumberRequired,
|
||||
cname
|
||||
);
|
||||
|
||||
return enc_part.userData;
|
||||
}
|
||||
}
|
||||
183
jdkSrc/jdk8/sun/security/krb5/KrbSafe.java
Normal file
183
jdkSrc/jdk8/sun/security/krb5/KrbSafe.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.EncryptionKey;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import java.io.IOException;
|
||||
|
||||
class KrbSafe extends KrbAppMessage {
|
||||
|
||||
private byte[] obuf;
|
||||
private byte[] userData;
|
||||
|
||||
public KrbSafe(byte[] userData,
|
||||
Credentials creds,
|
||||
EncryptionKey subKey,
|
||||
KerberosTime timestamp,
|
||||
SeqNumber seqNumber,
|
||||
HostAddress saddr,
|
||||
HostAddress raddr
|
||||
) throws KrbException, IOException {
|
||||
EncryptionKey reqKey = null;
|
||||
if (subKey != null)
|
||||
reqKey = subKey;
|
||||
else
|
||||
reqKey = creds.key;
|
||||
|
||||
obuf = mk_safe(userData,
|
||||
reqKey,
|
||||
timestamp,
|
||||
seqNumber,
|
||||
saddr,
|
||||
raddr
|
||||
);
|
||||
}
|
||||
|
||||
public KrbSafe(byte[] msg,
|
||||
Credentials creds,
|
||||
EncryptionKey subKey,
|
||||
SeqNumber seqNumber,
|
||||
HostAddress saddr,
|
||||
HostAddress raddr,
|
||||
boolean timestampRequired,
|
||||
boolean seqNumberRequired
|
||||
) throws KrbException, IOException {
|
||||
|
||||
KRBSafe krb_safe = new KRBSafe(msg);
|
||||
|
||||
EncryptionKey reqKey = null;
|
||||
if (subKey != null)
|
||||
reqKey = subKey;
|
||||
else
|
||||
reqKey = creds.key;
|
||||
|
||||
userData = rd_safe(
|
||||
krb_safe,
|
||||
reqKey,
|
||||
seqNumber,
|
||||
saddr,
|
||||
raddr,
|
||||
timestampRequired,
|
||||
seqNumberRequired,
|
||||
creds.client
|
||||
);
|
||||
}
|
||||
|
||||
public byte[] getMessage() {
|
||||
return obuf;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return userData;
|
||||
}
|
||||
|
||||
private byte[] mk_safe(byte[] userData,
|
||||
EncryptionKey key,
|
||||
KerberosTime timestamp,
|
||||
SeqNumber seqNumber,
|
||||
HostAddress sAddress,
|
||||
HostAddress rAddress
|
||||
) throws Asn1Exception, IOException, KdcErrException,
|
||||
KrbApErrException, KrbCryptoException {
|
||||
|
||||
Integer usec = null;
|
||||
Integer seqno = null;
|
||||
|
||||
if (timestamp != null)
|
||||
usec = new Integer(timestamp.getMicroSeconds());
|
||||
|
||||
if (seqNumber != null) {
|
||||
seqno = new Integer(seqNumber.current());
|
||||
seqNumber.step();
|
||||
}
|
||||
|
||||
KRBSafeBody krb_safeBody =
|
||||
new KRBSafeBody(userData,
|
||||
timestamp,
|
||||
usec,
|
||||
seqno,
|
||||
sAddress,
|
||||
rAddress
|
||||
);
|
||||
|
||||
byte[] temp = krb_safeBody.asn1Encode();
|
||||
Checksum cksum = new Checksum(
|
||||
Checksum.SAFECKSUMTYPE_DEFAULT,
|
||||
temp,
|
||||
key,
|
||||
KeyUsage.KU_KRB_SAFE_CKSUM
|
||||
);
|
||||
|
||||
KRBSafe krb_safe = new KRBSafe(krb_safeBody, cksum);
|
||||
|
||||
temp = krb_safe.asn1Encode();
|
||||
|
||||
return krb_safe.asn1Encode();
|
||||
}
|
||||
|
||||
private byte[] rd_safe(KRBSafe krb_safe,
|
||||
EncryptionKey key,
|
||||
SeqNumber seqNumber,
|
||||
HostAddress sAddress,
|
||||
HostAddress rAddress,
|
||||
boolean timestampRequired,
|
||||
boolean seqNumberRequired,
|
||||
PrincipalName cname
|
||||
) throws Asn1Exception, KdcErrException,
|
||||
KrbApErrException, IOException, KrbCryptoException {
|
||||
|
||||
byte[] temp = krb_safe.safeBody.asn1Encode();
|
||||
|
||||
if (!krb_safe.cksum.verifyKeyedChecksum(temp, key,
|
||||
KeyUsage.KU_KRB_SAFE_CKSUM)) {
|
||||
throw new KrbApErrException(
|
||||
Krb5.KRB_AP_ERR_MODIFIED);
|
||||
}
|
||||
|
||||
check(krb_safe.safeBody.timestamp,
|
||||
krb_safe.safeBody.usec,
|
||||
krb_safe.safeBody.seqNumber,
|
||||
krb_safe.safeBody.sAddress,
|
||||
krb_safe.safeBody.rAddress,
|
||||
seqNumber,
|
||||
sAddress,
|
||||
rAddress,
|
||||
timestampRequired,
|
||||
seqNumberRequired,
|
||||
cname
|
||||
);
|
||||
|
||||
return krb_safe.safeBody.userData;
|
||||
}
|
||||
}
|
||||
338
jdkSrc/jdk8/sun/security/krb5/KrbServiceLocator.java
Normal file
338
jdkSrc/jdk8/sun/security/krb5/KrbServiceLocator.java
Normal file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 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. 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 sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.Krb5;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Random;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.spi.NamingManager;
|
||||
|
||||
/**
|
||||
* This class discovers the location of Kerberos services by querying DNS,
|
||||
* as defined in RFC 4120.
|
||||
*
|
||||
* @author Seema Malkani
|
||||
* @since 1.7
|
||||
*/
|
||||
|
||||
class KrbServiceLocator {
|
||||
|
||||
private static final String SRV_RR = "SRV";
|
||||
private static final String[] SRV_RR_ATTR = new String[] {SRV_RR};
|
||||
|
||||
private static final String SRV_TXT = "TXT";
|
||||
private static final String[] SRV_TXT_ATTR = new String[] {SRV_TXT};
|
||||
|
||||
private static final Random random = new Random();
|
||||
|
||||
private static final boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
private KrbServiceLocator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the KERBEROS service for a given domain.
|
||||
* Queries DNS for a list of KERBEROS Service Text Records (TXT) for a
|
||||
* given domain name.
|
||||
* Information on the mapping of DNS hostnames and domain names
|
||||
* to Kerberos realms is stored using DNS TXT records
|
||||
*
|
||||
* @param realmName A string realm name.
|
||||
* @return An ordered list of hostports for the Kerberos service or null if
|
||||
* the service has not been located.
|
||||
*/
|
||||
static String[] getKerberosService(String realmName) {
|
||||
|
||||
// search realm in SRV TXT records
|
||||
String dnsUrl = "dns:///_kerberos." + realmName;
|
||||
String[] records = null;
|
||||
try {
|
||||
// Create the DNS context using NamingManager rather than using
|
||||
// the initial context constructor. This avoids having the initial
|
||||
// context constructor call itself (when processing the URL
|
||||
// argument in the getAttributes call).
|
||||
Context ctx = NamingManager.getURLContext("dns", new Hashtable<>(0));
|
||||
if (!(ctx instanceof DirContext)) {
|
||||
return null; // cannot create a DNS context
|
||||
}
|
||||
Attributes attrs = null;
|
||||
try {
|
||||
// both connect and accept are needed since DNS is thru UDP
|
||||
attrs = AccessController.doPrivileged(
|
||||
(PrivilegedExceptionAction<Attributes>)
|
||||
() -> ((DirContext)ctx).getAttributes(
|
||||
dnsUrl, SRV_TXT_ATTR),
|
||||
null,
|
||||
new java.net.SocketPermission("*", "connect,accept"));
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (NamingException)e.getCause();
|
||||
}
|
||||
Attribute attr;
|
||||
|
||||
if (attrs != null && ((attr = attrs.get(SRV_TXT)) != null)) {
|
||||
int numValues = attr.size();
|
||||
int numRecords = 0;
|
||||
String[] txtRecords = new String[numValues];
|
||||
|
||||
// gather the text records
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (i < numValues) {
|
||||
try {
|
||||
txtRecords[j] = (String)attr.get(i);
|
||||
j++;
|
||||
} catch (Exception e) {
|
||||
// ignore bad value
|
||||
}
|
||||
i++;
|
||||
}
|
||||
numRecords = j;
|
||||
|
||||
// trim
|
||||
if (numRecords < numValues) {
|
||||
String[] trimmed = new String[numRecords];
|
||||
System.arraycopy(txtRecords, 0, trimmed, 0, numRecords);
|
||||
records = trimmed;
|
||||
} else {
|
||||
records = txtRecords;
|
||||
}
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
// ignore
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the KERBEROS service for a given domain.
|
||||
* Queries DNS for a list of KERBEROS Service Location Records (SRV) for a
|
||||
* given domain name.
|
||||
*
|
||||
* @param realmName A string realm name.
|
||||
* @param protocol the protocol string, can be "_udp" or "_tcp"
|
||||
* @return An ordered list of hostports for the Kerberos service or null if
|
||||
* the service has not been located.
|
||||
*/
|
||||
static String[] getKerberosService(String realmName, String protocol) {
|
||||
|
||||
String dnsUrl = "dns:///_kerberos." + protocol + "." + realmName;
|
||||
String[] hostports = null;
|
||||
|
||||
try {
|
||||
// Create the DNS context using NamingManager rather than using
|
||||
// the initial context constructor. This avoids having the initial
|
||||
// context constructor call itself (when processing the URL
|
||||
// argument in the getAttributes call).
|
||||
Context ctx = NamingManager.getURLContext("dns", new Hashtable<>(0));
|
||||
if (!(ctx instanceof DirContext)) {
|
||||
return null; // cannot create a DNS context
|
||||
}
|
||||
|
||||
Attributes attrs = null;
|
||||
try {
|
||||
// both connect and accept are needed since DNS is thru UDP
|
||||
attrs = AccessController.doPrivileged(
|
||||
(PrivilegedExceptionAction<Attributes>)
|
||||
() -> ((DirContext)ctx).getAttributes(
|
||||
dnsUrl, SRV_RR_ATTR),
|
||||
null,
|
||||
new java.net.SocketPermission("*", "connect,accept"));
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (NamingException)e.getCause();
|
||||
}
|
||||
|
||||
Attribute attr;
|
||||
|
||||
if (attrs != null && ((attr = attrs.get(SRV_RR)) != null)) {
|
||||
int numValues = attr.size();
|
||||
int numRecords = 0;
|
||||
SrvRecord[] srvRecords = new SrvRecord[numValues];
|
||||
|
||||
// create the service records
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (i < numValues) {
|
||||
try {
|
||||
srvRecords[j] = new SrvRecord((String) attr.get(i));
|
||||
j++;
|
||||
} catch (Exception e) {
|
||||
// ignore bad value
|
||||
}
|
||||
i++;
|
||||
}
|
||||
numRecords = j;
|
||||
|
||||
// trim
|
||||
if (numRecords < numValues) {
|
||||
SrvRecord[] trimmed = new SrvRecord[numRecords];
|
||||
System.arraycopy(srvRecords, 0, trimmed, 0, numRecords);
|
||||
srvRecords = trimmed;
|
||||
}
|
||||
|
||||
// Sort the service records in ascending order of their
|
||||
// priority value. For records with equal priority, move
|
||||
// those with weight 0 to the top of the list.
|
||||
if (numRecords > 1) {
|
||||
Arrays.sort(srvRecords);
|
||||
}
|
||||
|
||||
// extract the host and port number from each service record
|
||||
hostports = extractHostports(srvRecords);
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
// e.printStackTrace();
|
||||
// ignore
|
||||
}
|
||||
return hostports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract hosts and port numbers from a list of SRV records.
|
||||
* An array of hostports is returned or null if none were found.
|
||||
*/
|
||||
private static String[] extractHostports(SrvRecord[] srvRecords) {
|
||||
String[] hostports = null;
|
||||
|
||||
int head = 0;
|
||||
int tail = 0;
|
||||
int sublistLength = 0;
|
||||
int k = 0;
|
||||
for (int i = 0; i < srvRecords.length; i++) {
|
||||
if (hostports == null) {
|
||||
hostports = new String[srvRecords.length];
|
||||
}
|
||||
// find the head and tail of the list of records having the same
|
||||
// priority value.
|
||||
head = i;
|
||||
while (i < srvRecords.length - 1 &&
|
||||
srvRecords[i].priority == srvRecords[i + 1].priority) {
|
||||
i++;
|
||||
}
|
||||
tail = i;
|
||||
|
||||
// select hostports from the sublist
|
||||
sublistLength = (tail - head) + 1;
|
||||
for (int j = 0; j < sublistLength; j++) {
|
||||
hostports[k++] = selectHostport(srvRecords, head, tail);
|
||||
}
|
||||
}
|
||||
return hostports;
|
||||
}
|
||||
|
||||
/*
|
||||
* Randomly select a service record in the range [head, tail] and return
|
||||
* its hostport value. Follows the algorithm in RFC 2782.
|
||||
*/
|
||||
private static String selectHostport(SrvRecord[] srvRecords, int head,
|
||||
int tail) {
|
||||
if (head == tail) {
|
||||
return srvRecords[head].hostport;
|
||||
}
|
||||
|
||||
// compute the running sum for records between head and tail
|
||||
int sum = 0;
|
||||
for (int i = head; i <= tail; i++) {
|
||||
if (srvRecords[i] != null) {
|
||||
sum += srvRecords[i].weight;
|
||||
srvRecords[i].sum = sum;
|
||||
}
|
||||
}
|
||||
String hostport = null;
|
||||
|
||||
// If all records have zero weight, select first available one;
|
||||
// otherwise, randomly select a record according to its weight
|
||||
int target = (sum == 0 ? 0 : random.nextInt(sum + 1));
|
||||
for (int i = head; i <= tail; i++) {
|
||||
if (srvRecords[i] != null && srvRecords[i].sum >= target) {
|
||||
hostport = srvRecords[i].hostport;
|
||||
srvRecords[i] = null; // make this record unavailable
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hostport;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class holds a DNS service (SRV) record.
|
||||
* See http://www.ietf.org/rfc/rfc2782.txt
|
||||
*/
|
||||
|
||||
static class SrvRecord implements Comparable<SrvRecord> {
|
||||
|
||||
int priority;
|
||||
int weight;
|
||||
int sum;
|
||||
String hostport;
|
||||
|
||||
/**
|
||||
* Creates a service record object from a string record.
|
||||
* DNS supplies the string record in the following format:
|
||||
* <pre>
|
||||
* <Priority> " " <Weight> " " <Port> " " <Host>
|
||||
* </pre>
|
||||
*/
|
||||
SrvRecord(String srvRecord) throws Exception {
|
||||
StringTokenizer tokenizer = new StringTokenizer(srvRecord, " ");
|
||||
String port;
|
||||
|
||||
if (tokenizer.countTokens() == 4) {
|
||||
priority = Integer.parseInt(tokenizer.nextToken());
|
||||
weight = Integer.parseInt(tokenizer.nextToken());
|
||||
port = tokenizer.nextToken();
|
||||
hostport = tokenizer.nextToken() + ":" + port;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort records in ascending order of priority value. For records with
|
||||
* equal priority move those with weight 0 to the top of the list.
|
||||
*/
|
||||
public int compareTo(SrvRecord that) {
|
||||
if (priority > that.priority) {
|
||||
return 1; // this > that
|
||||
} else if (priority < that.priority) {
|
||||
return -1; // this < that
|
||||
} else if (weight == 0 && that.weight != 0) {
|
||||
return -1; // this < that
|
||||
} else if (weight != 0 && that.weight == 0) {
|
||||
return 1; // this > that
|
||||
} else {
|
||||
return 0; // this == that
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
144
jdkSrc/jdk8/sun/security/krb5/KrbTgsRep.java
Normal file
144
jdkSrc/jdk8/sun/security/krb5/KrbTgsRep.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class encapsulates a TGS-REP that is sent from the KDC to the
|
||||
* Kerberos client.
|
||||
*/
|
||||
public class KrbTgsRep extends KrbKdcRep {
|
||||
private TGSRep rep;
|
||||
private Credentials creds;
|
||||
private Ticket secondTicket;
|
||||
private static final boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
KrbTgsRep(byte[] ibuf, KrbTgsReq tgsReq)
|
||||
throws KrbException, IOException {
|
||||
DerValue ref = new DerValue(ibuf);
|
||||
TGSReq req = tgsReq.getMessage();
|
||||
TGSRep rep = null;
|
||||
try {
|
||||
rep = new TGSRep(ref);
|
||||
} catch (Asn1Exception e) {
|
||||
rep = null;
|
||||
KRBError err = new KRBError(ref);
|
||||
String errStr = err.getErrorString();
|
||||
String eText = null; // pick up text sent by the server (if any)
|
||||
if (errStr != null && errStr.length() > 0) {
|
||||
if (errStr.charAt(errStr.length() - 1) == 0)
|
||||
eText = errStr.substring(0, errStr.length() - 1);
|
||||
else
|
||||
eText = errStr;
|
||||
}
|
||||
KrbException ke;
|
||||
if (eText == null) {
|
||||
// no text sent from server
|
||||
ke = new KrbException(err.getErrorCode());
|
||||
} else {
|
||||
// override default text with server text
|
||||
ke = new KrbException(err.getErrorCode(), eText);
|
||||
}
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
byte[] enc_tgs_rep_bytes = rep.encPart.decrypt(tgsReq.tgsReqKey,
|
||||
tgsReq.usedSubkey() ? KeyUsage.KU_ENC_TGS_REP_PART_SUBKEY :
|
||||
KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY);
|
||||
|
||||
byte[] enc_tgs_rep_part = rep.encPart.reset(enc_tgs_rep_bytes);
|
||||
ref = new DerValue(enc_tgs_rep_part);
|
||||
EncTGSRepPart enc_part = new EncTGSRepPart(ref);
|
||||
rep.encKDCRepPart = enc_part;
|
||||
|
||||
check(false, req, rep, tgsReq.tgsReqKey);
|
||||
|
||||
PrincipalName serverAlias = tgsReq.getServerAlias();
|
||||
if (serverAlias != null) {
|
||||
PrincipalName repSname = enc_part.sname;
|
||||
if (serverAlias.equals(repSname) ||
|
||||
isReferralSname(repSname)) {
|
||||
serverAlias = null;
|
||||
}
|
||||
}
|
||||
|
||||
PrincipalName clientAlias = null;
|
||||
if (rep.cname.equals(req.reqBody.cname)) {
|
||||
// Only propagate the client alias if it is not an
|
||||
// impersonation ticket (S4U2Self or S4U2Proxy).
|
||||
clientAlias = tgsReq.getClientAlias();
|
||||
}
|
||||
|
||||
this.creds = new Credentials(rep.ticket,
|
||||
rep.cname,
|
||||
clientAlias,
|
||||
enc_part.sname,
|
||||
serverAlias,
|
||||
enc_part.key,
|
||||
enc_part.flags,
|
||||
enc_part.authtime,
|
||||
enc_part.starttime,
|
||||
enc_part.endtime,
|
||||
enc_part.renewTill,
|
||||
enc_part.caddr
|
||||
);
|
||||
this.rep = rep;
|
||||
this.secondTicket = tgsReq.getSecondTicket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the credentials that were contained in this KRB-TGS-REP.
|
||||
*/
|
||||
public Credentials getCreds() {
|
||||
return creds;
|
||||
}
|
||||
|
||||
sun.security.krb5.internal.ccache.Credentials setCredentials() {
|
||||
return new sun.security.krb5.internal.ccache.Credentials(rep, secondTicket);
|
||||
}
|
||||
|
||||
private static boolean isReferralSname(PrincipalName sname) {
|
||||
if (sname != null) {
|
||||
String[] snameStrings = sname.getNameStrings();
|
||||
if (snameStrings.length == 2 &&
|
||||
snameStrings[0].equals(
|
||||
PrincipalName.TGS_DEFAULT_SRV_NAME)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
374
jdkSrc/jdk8/sun/security/krb5/KrbTgsReq.java
Normal file
374
jdkSrc/jdk8/sun/security/krb5/KrbTgsReq.java
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class encapsulates a Kerberos TGS-REQ that is sent from the
|
||||
* client to the KDC.
|
||||
*/
|
||||
public class KrbTgsReq {
|
||||
|
||||
private PrincipalName princName;
|
||||
private PrincipalName clientAlias;
|
||||
private PrincipalName servName;
|
||||
private PrincipalName serverAlias;
|
||||
private TGSReq tgsReqMessg;
|
||||
private KerberosTime ctime;
|
||||
private Ticket secondTicket = null;
|
||||
private boolean useSubkey = false;
|
||||
EncryptionKey tgsReqKey;
|
||||
|
||||
private static final boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
private byte[] obuf;
|
||||
private byte[] ibuf;
|
||||
|
||||
// Used in CredentialsUtil
|
||||
public KrbTgsReq(KDCOptions options, Credentials asCreds,
|
||||
PrincipalName cname, PrincipalName clientAlias,
|
||||
PrincipalName sname, PrincipalName serverAlias,
|
||||
Ticket[] additionalTickets, PAData[] extraPAs)
|
||||
throws KrbException, IOException {
|
||||
this(options,
|
||||
asCreds,
|
||||
cname,
|
||||
clientAlias,
|
||||
sname,
|
||||
serverAlias,
|
||||
null, // KerberosTime from
|
||||
null, // KerberosTime till
|
||||
null, // KerberosTime rtime
|
||||
null, // int[] eTypes
|
||||
null, // HostAddresses addresses
|
||||
null, // AuthorizationData authorizationData
|
||||
additionalTickets,
|
||||
null, // EncryptionKey subKey
|
||||
extraPAs);
|
||||
}
|
||||
|
||||
// Called by Credentials, KrbCred
|
||||
KrbTgsReq(
|
||||
KDCOptions options,
|
||||
Credentials asCreds,
|
||||
PrincipalName sname,
|
||||
PrincipalName serverAlias,
|
||||
KerberosTime from,
|
||||
KerberosTime till,
|
||||
KerberosTime rtime,
|
||||
int[] eTypes,
|
||||
HostAddresses addresses,
|
||||
AuthorizationData authorizationData,
|
||||
Ticket[] additionalTickets,
|
||||
EncryptionKey subKey) throws KrbException, IOException {
|
||||
this(options, asCreds, asCreds.getClient(), asCreds.getClientAlias(),
|
||||
sname, serverAlias, from, till, rtime, eTypes,
|
||||
addresses, authorizationData, additionalTickets, subKey, null);
|
||||
}
|
||||
|
||||
private KrbTgsReq(
|
||||
KDCOptions options,
|
||||
Credentials asCreds,
|
||||
PrincipalName cname,
|
||||
PrincipalName clientAlias,
|
||||
PrincipalName sname,
|
||||
PrincipalName serverAlias,
|
||||
KerberosTime from,
|
||||
KerberosTime till,
|
||||
KerberosTime rtime,
|
||||
int[] eTypes,
|
||||
HostAddresses addresses,
|
||||
AuthorizationData authorizationData,
|
||||
Ticket[] additionalTickets,
|
||||
EncryptionKey subKey,
|
||||
PAData[] extraPAs) throws KrbException, IOException {
|
||||
|
||||
princName = cname;
|
||||
this.clientAlias = clientAlias;
|
||||
servName = sname;
|
||||
this.serverAlias = serverAlias;
|
||||
ctime = KerberosTime.now();
|
||||
|
||||
// check if they are valid arguments. The optional fields
|
||||
// should be consistent with settings in KDCOptions.
|
||||
|
||||
if (options.get(KDCOptions.FORWARDABLE) &&
|
||||
(!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) {
|
||||
options.set(KDCOptions.FORWARDABLE, false);
|
||||
}
|
||||
if (options.get(KDCOptions.FORWARDED)) {
|
||||
if (!(asCreds.flags.get(KDCOptions.FORWARDABLE)))
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
}
|
||||
if (options.get(KDCOptions.PROXIABLE) &&
|
||||
(!(asCreds.flags.get(Krb5.TKT_OPTS_PROXIABLE)))) {
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
}
|
||||
if (options.get(KDCOptions.PROXY)) {
|
||||
if (!(asCreds.flags.get(KDCOptions.PROXIABLE)))
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
}
|
||||
if (options.get(KDCOptions.ALLOW_POSTDATE) &&
|
||||
(!(asCreds.flags.get(Krb5.TKT_OPTS_MAY_POSTDATE)))) {
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
}
|
||||
if (options.get(KDCOptions.RENEWABLE) &&
|
||||
(!(asCreds.flags.get(Krb5.TKT_OPTS_RENEWABLE)))) {
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
}
|
||||
|
||||
if (options.get(KDCOptions.POSTDATED)) {
|
||||
if (!(asCreds.flags.get(KDCOptions.POSTDATED)))
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
} else {
|
||||
if (from != null) from = null;
|
||||
}
|
||||
if (options.get(KDCOptions.RENEWABLE)) {
|
||||
if (!(asCreds.flags.get(KDCOptions.RENEWABLE)))
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
} else {
|
||||
if (rtime != null) rtime = null;
|
||||
}
|
||||
if (options.get(KDCOptions.ENC_TKT_IN_SKEY) || options.get(KDCOptions.CNAME_IN_ADDL_TKT)) {
|
||||
if (additionalTickets == null)
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
|
||||
// in TGS_REQ there could be more than one additional
|
||||
// tickets, but in file-based credential cache,
|
||||
// there is only one additional ticket field.
|
||||
secondTicket = additionalTickets[0];
|
||||
} else {
|
||||
if (additionalTickets != null)
|
||||
additionalTickets = null;
|
||||
}
|
||||
|
||||
tgsReqMessg = createRequest(
|
||||
options,
|
||||
asCreds.ticket,
|
||||
asCreds.key,
|
||||
ctime,
|
||||
princName,
|
||||
servName,
|
||||
from,
|
||||
till,
|
||||
rtime,
|
||||
eTypes,
|
||||
addresses,
|
||||
authorizationData,
|
||||
additionalTickets,
|
||||
subKey,
|
||||
extraPAs);
|
||||
obuf = tgsReqMessg.asn1Encode();
|
||||
|
||||
// XXX We need to revisit this to see if can't move it
|
||||
// up such that FORWARDED flag set in the options
|
||||
// is included in the marshaled request.
|
||||
/*
|
||||
* If this is based on a forwarded ticket, record that in the
|
||||
* options, because the returned TgsRep will contain the
|
||||
* FORWARDED flag set.
|
||||
*/
|
||||
if (asCreds.flags.get(KDCOptions.FORWARDED))
|
||||
options.set(KDCOptions.FORWARDED, true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a TGS request to the realm of the target.
|
||||
* @throws KrbException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void send() throws IOException, KrbException {
|
||||
String realmStr = null;
|
||||
if (servName != null)
|
||||
realmStr = servName.getRealmString();
|
||||
KdcComm comm = new KdcComm(realmStr);
|
||||
ibuf = comm.send(obuf);
|
||||
}
|
||||
|
||||
public KrbTgsRep getReply()
|
||||
throws KrbException, IOException {
|
||||
return new KrbTgsRep(ibuf, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the request, waits for a reply, and returns the Credentials.
|
||||
* Used in Credentials, KrbCred, and internal/CredentialsUtil.
|
||||
*/
|
||||
public Credentials sendAndGetCreds() throws IOException, KrbException {
|
||||
KrbTgsRep tgs_rep = null;
|
||||
String kdc = null;
|
||||
send();
|
||||
tgs_rep = getReply();
|
||||
return tgs_rep.getCreds();
|
||||
}
|
||||
|
||||
KerberosTime getCtime() {
|
||||
return ctime;
|
||||
}
|
||||
|
||||
private TGSReq createRequest(
|
||||
KDCOptions kdc_options,
|
||||
Ticket ticket,
|
||||
EncryptionKey key,
|
||||
KerberosTime ctime,
|
||||
PrincipalName cname,
|
||||
PrincipalName sname,
|
||||
KerberosTime from,
|
||||
KerberosTime till,
|
||||
KerberosTime rtime,
|
||||
int[] eTypes,
|
||||
HostAddresses addresses,
|
||||
AuthorizationData authorizationData,
|
||||
Ticket[] additionalTickets,
|
||||
EncryptionKey subKey,
|
||||
PAData[] extraPAs)
|
||||
throws IOException, KrbException, UnknownHostException {
|
||||
KerberosTime req_till = null;
|
||||
if (till == null) {
|
||||
String d = Config.getInstance().get("libdefaults", "ticket_lifetime");
|
||||
if (d != null) {
|
||||
req_till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
|
||||
} else {
|
||||
req_till = new KerberosTime(0); // Choose KDC maximum allowed
|
||||
}
|
||||
} else {
|
||||
req_till = till;
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 4120, Section 5.4.2.
|
||||
* For KRB_TGS_REP, the ciphertext is encrypted in the
|
||||
* sub-session key from the Authenticator, or if absent,
|
||||
* the session key from the ticket-granting ticket used
|
||||
* in the request.
|
||||
*
|
||||
* To support this, use tgsReqKey to remember which key to use.
|
||||
*/
|
||||
tgsReqKey = key;
|
||||
|
||||
int[] req_eTypes = null;
|
||||
if (eTypes == null) {
|
||||
req_eTypes = EType.getDefaults("default_tgs_enctypes");
|
||||
} else {
|
||||
req_eTypes = eTypes;
|
||||
}
|
||||
|
||||
EncryptionKey reqKey = null;
|
||||
EncryptedData encAuthorizationData = null;
|
||||
if (authorizationData != null) {
|
||||
byte[] ad = authorizationData.asn1Encode();
|
||||
if (subKey != null) {
|
||||
reqKey = subKey;
|
||||
tgsReqKey = subKey; // Key to use to decrypt reply
|
||||
useSubkey = true;
|
||||
encAuthorizationData = new EncryptedData(reqKey, ad,
|
||||
KeyUsage.KU_TGS_REQ_AUTH_DATA_SUBKEY);
|
||||
} else
|
||||
encAuthorizationData = new EncryptedData(key, ad,
|
||||
KeyUsage.KU_TGS_REQ_AUTH_DATA_SESSKEY);
|
||||
}
|
||||
|
||||
KDCReqBody reqBody = new KDCReqBody(
|
||||
kdc_options,
|
||||
cname,
|
||||
sname,
|
||||
from,
|
||||
req_till,
|
||||
rtime,
|
||||
Nonce.value(),
|
||||
req_eTypes,
|
||||
addresses,
|
||||
encAuthorizationData,
|
||||
additionalTickets);
|
||||
|
||||
byte[] temp = reqBody.asn1Encode(Krb5.KRB_TGS_REQ);
|
||||
// if the checksum type is one of the keyed checksum types,
|
||||
// use session key.
|
||||
Checksum cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
|
||||
KeyUsage.KU_PA_TGS_REQ_CKSUM);
|
||||
|
||||
// Usage will be KeyUsage.KU_PA_TGS_REQ_AUTHENTICATOR
|
||||
|
||||
byte[] tgs_ap_req = new KrbApReq(
|
||||
new APOptions(),
|
||||
ticket,
|
||||
key,
|
||||
cname,
|
||||
cksum,
|
||||
ctime,
|
||||
reqKey,
|
||||
null,
|
||||
null).getMessage();
|
||||
|
||||
PAData tgsPAData = new PAData(Krb5.PA_TGS_REQ, tgs_ap_req);
|
||||
PAData[] pa;
|
||||
if (extraPAs != null) {
|
||||
pa = Arrays.copyOf(extraPAs, extraPAs.length + 1);
|
||||
pa[extraPAs.length] = tgsPAData;
|
||||
} else {
|
||||
pa = new PAData[] {tgsPAData};
|
||||
}
|
||||
return new TGSReq(pa, reqBody);
|
||||
}
|
||||
|
||||
TGSReq getMessage() {
|
||||
return tgsReqMessg;
|
||||
}
|
||||
|
||||
Ticket getSecondTicket() {
|
||||
return secondTicket;
|
||||
}
|
||||
|
||||
PrincipalName getClientAlias() {
|
||||
return clientAlias;
|
||||
}
|
||||
|
||||
PrincipalName getServerAlias() {
|
||||
return serverAlias;
|
||||
}
|
||||
|
||||
private static void debug(String message) {
|
||||
// System.err.println(">>> KrbTgsReq: " + message);
|
||||
}
|
||||
|
||||
boolean usedSubkey() {
|
||||
return useSubkey;
|
||||
}
|
||||
|
||||
}
|
||||
706
jdkSrc/jdk8/sun/security/krb5/PrincipalName.java
Normal file
706
jdkSrc/jdk8/sun/security/krb5/PrincipalName.java
Normal file
@@ -0,0 +1,706 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.util.*;
|
||||
import java.net.*;
|
||||
import java.util.Vector;
|
||||
import java.util.Locale;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import sun.security.krb5.internal.ccache.CCacheOutputStream;
|
||||
import sun.security.krb5.internal.util.KerberosString;
|
||||
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 PrincipalName type and its realm in a single class.
|
||||
* <pre>{@code
|
||||
* Realm ::= KerberosString
|
||||
*
|
||||
* PrincipalName ::= SEQUENCE {
|
||||
* name-type [0] Int32,
|
||||
* name-string [1] SEQUENCE OF KerberosString
|
||||
* }
|
||||
* }</pre>
|
||||
* This class is immutable.
|
||||
* @see Realm
|
||||
*/
|
||||
public class PrincipalName implements Cloneable {
|
||||
|
||||
//name types
|
||||
|
||||
/**
|
||||
* Name type not known
|
||||
*/
|
||||
public static final int KRB_NT_UNKNOWN = 0;
|
||||
|
||||
/**
|
||||
* Just the name of the principal as in DCE, or for users
|
||||
*/
|
||||
public static final int KRB_NT_PRINCIPAL = 1;
|
||||
|
||||
/**
|
||||
* Service and other unique instance (krbtgt)
|
||||
*/
|
||||
public static final int KRB_NT_SRV_INST = 2;
|
||||
|
||||
/**
|
||||
* Service with host name as instance (telnet, rcommands)
|
||||
*/
|
||||
public static final int KRB_NT_SRV_HST = 3;
|
||||
|
||||
/**
|
||||
* Service with host as remaining components
|
||||
*/
|
||||
public static final int KRB_NT_SRV_XHST = 4;
|
||||
|
||||
/**
|
||||
* Unique ID
|
||||
*/
|
||||
public static final int KRB_NT_UID = 5;
|
||||
|
||||
/**
|
||||
* Enterprise name (alias)
|
||||
*/
|
||||
public static final int KRB_NT_ENTERPRISE = 10;
|
||||
|
||||
/**
|
||||
* TGS Name
|
||||
*/
|
||||
public static final String TGS_DEFAULT_SRV_NAME = "krbtgt";
|
||||
public static final int TGS_DEFAULT_NT = KRB_NT_SRV_INST;
|
||||
|
||||
public static final char NAME_COMPONENT_SEPARATOR = '/';
|
||||
public static final char NAME_REALM_SEPARATOR = '@';
|
||||
public static final char REALM_COMPONENT_SEPARATOR = '.';
|
||||
|
||||
public static final String NAME_COMPONENT_SEPARATOR_STR = "/";
|
||||
public static final String NAME_REALM_SEPARATOR_STR = "@";
|
||||
public static final String REALM_COMPONENT_SEPARATOR_STR = ".";
|
||||
|
||||
// Instance fields.
|
||||
|
||||
/**
|
||||
* The name type, from PrincipalName's name-type field.
|
||||
*/
|
||||
private final int nameType;
|
||||
|
||||
/**
|
||||
* The name strings, from PrincipalName's name-strings field. This field
|
||||
* must be neither null nor empty. Each entry of it must also be neither
|
||||
* null nor empty. Make sure to clone the field when it's passed in or out.
|
||||
*/
|
||||
private final String[] nameStrings;
|
||||
|
||||
/**
|
||||
* The realm this principal belongs to.
|
||||
*/
|
||||
private final Realm nameRealm; // not null
|
||||
|
||||
|
||||
/**
|
||||
* When constructing a PrincipalName, whether the realm is included in
|
||||
* the input, or deduced from default realm or domain-realm mapping.
|
||||
*/
|
||||
private final boolean realmDeduced;
|
||||
|
||||
// cached default salt, not used in clone
|
||||
private transient String salt = null;
|
||||
|
||||
// There are 3 basic constructors. All other constructors must call them.
|
||||
// All basic constructors must call validateNameStrings.
|
||||
// 1. From name components
|
||||
// 2. From name
|
||||
// 3. From DER encoding
|
||||
|
||||
/**
|
||||
* Creates a PrincipalName.
|
||||
*/
|
||||
public PrincipalName(int nameType, String[] nameStrings, Realm nameRealm) {
|
||||
if (nameRealm == null) {
|
||||
throw new IllegalArgumentException("Null realm not allowed");
|
||||
}
|
||||
validateNameStrings(nameStrings);
|
||||
this.nameType = nameType;
|
||||
this.nameStrings = nameStrings.clone();
|
||||
this.nameRealm = nameRealm;
|
||||
this.realmDeduced = false;
|
||||
}
|
||||
|
||||
// This method is called by Windows NativeCred.c
|
||||
public PrincipalName(String[] nameParts, String realm) throws RealmException {
|
||||
this(KRB_NT_UNKNOWN, nameParts, new Realm(realm));
|
||||
}
|
||||
|
||||
// Validate a nameStrings argument
|
||||
private static void validateNameStrings(String[] ns) {
|
||||
if (ns == null) {
|
||||
throw new IllegalArgumentException("Null nameStrings not allowed");
|
||||
}
|
||||
if (ns.length == 0) {
|
||||
throw new IllegalArgumentException("Empty nameStrings not allowed");
|
||||
}
|
||||
for (String s: ns) {
|
||||
if (s == null) {
|
||||
throw new IllegalArgumentException("Null nameString not allowed");
|
||||
}
|
||||
if (s.isEmpty()) {
|
||||
throw new IllegalArgumentException("Empty nameString not allowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
try {
|
||||
PrincipalName pName = (PrincipalName) super.clone();
|
||||
UNSAFE.putObject(this, NAME_STRINGS_OFFSET, nameStrings.clone());
|
||||
return pName;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new AssertionError("Should never happen");
|
||||
}
|
||||
}
|
||||
|
||||
private static final long NAME_STRINGS_OFFSET;
|
||||
private static final sun.misc.Unsafe UNSAFE;
|
||||
static {
|
||||
try {
|
||||
sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
|
||||
NAME_STRINGS_OFFSET = unsafe.objectFieldOffset(
|
||||
PrincipalName.class.getDeclaredField("nameStrings"));
|
||||
UNSAFE = unsafe;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o instanceof PrincipalName) {
|
||||
PrincipalName other = (PrincipalName)o;
|
||||
return nameRealm.equals(other.nameRealm) &&
|
||||
Arrays.equals(nameStrings, other.nameStrings);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ASN.1 encoding of the
|
||||
* <pre>{@code
|
||||
* PrincipalName ::= SEQUENCE {
|
||||
* name-type [0] Int32,
|
||||
* name-string [1] SEQUENCE OF KerberosString
|
||||
* }
|
||||
*
|
||||
* KerberosString ::= GeneralString (IA5String)
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*
|
||||
* @param encoding DER-encoded PrincipalName (without Realm)
|
||||
* @param realm the realm for this name
|
||||
* @exception Asn1Exception if an error occurs while decoding
|
||||
* an ASN1 encoded data.
|
||||
* @exception Asn1Exception if there is an ASN1 encoding error
|
||||
* @exception IOException if an I/O error occurs
|
||||
* @exception IllegalArgumentException if encoding is null
|
||||
* reading encoded data.
|
||||
*/
|
||||
public PrincipalName(DerValue encoding, Realm realm)
|
||||
throws Asn1Exception, IOException {
|
||||
if (realm == null) {
|
||||
throw new IllegalArgumentException("Null realm not allowed");
|
||||
}
|
||||
realmDeduced = false;
|
||||
nameRealm = realm;
|
||||
DerValue der;
|
||||
if (encoding == null) {
|
||||
throw new IllegalArgumentException("Null encoding not allowed");
|
||||
}
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x00) {
|
||||
BigInteger bint = der.getData().getBigInteger();
|
||||
nameType = bint.intValue();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x01F) == 0x01) {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
if (subDer.getTag() != DerValue.tag_SequenceOf) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
Vector<String> v = new Vector<>();
|
||||
DerValue subSubDer;
|
||||
while(subDer.getData().available() > 0) {
|
||||
subSubDer = subDer.getData().getDerValue();
|
||||
String namePart = new KerberosString(subSubDer).toString();
|
||||
v.addElement(namePart);
|
||||
}
|
||||
nameStrings = new String[v.size()];
|
||||
v.copyInto(nameStrings);
|
||||
validateNameStrings(nameStrings);
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a <code>PrincipalName</code> from a DER
|
||||
* input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @param data the Der input stream value, which contains one or
|
||||
* more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicate if this data field is optional
|
||||
* @param realm the realm for the name
|
||||
* @return an instance of <code>PrincipalName</code>, or null if the
|
||||
* field is optional and missing.
|
||||
*/
|
||||
public static PrincipalName parse(DerInputStream data,
|
||||
byte explicitTag, boolean
|
||||
optional,
|
||||
Realm realm)
|
||||
throws Asn1Exception, IOException, RealmException {
|
||||
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F) !=
|
||||
explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
} else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
if (realm == null) {
|
||||
realm = Realm.getDefault();
|
||||
}
|
||||
return new PrincipalName(subDer, realm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// XXX Error checkin consistent with MIT krb5_parse_name
|
||||
// Code repetition, realm parsed again by class Realm
|
||||
private static String[] parseName(String name) {
|
||||
|
||||
Vector<String> tempStrings = new Vector<>();
|
||||
String temp = name;
|
||||
int i = 0;
|
||||
int componentStart = 0;
|
||||
String component;
|
||||
|
||||
while (i < temp.length()) {
|
||||
if (temp.charAt(i) == NAME_COMPONENT_SEPARATOR) {
|
||||
/*
|
||||
* If this separator is escaped then don't treat it
|
||||
* as a separator
|
||||
*/
|
||||
if (i > 0 && temp.charAt(i - 1) == '\\') {
|
||||
temp = temp.substring(0, i - 1) +
|
||||
temp.substring(i, temp.length());
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if (componentStart <= i) {
|
||||
component = temp.substring(componentStart, i);
|
||||
tempStrings.addElement(component);
|
||||
}
|
||||
componentStart = i + 1;
|
||||
}
|
||||
} else {
|
||||
if (temp.charAt(i) == NAME_REALM_SEPARATOR) {
|
||||
/*
|
||||
* If this separator is escaped then don't treat it
|
||||
* as a separator
|
||||
*/
|
||||
if (i > 0 && temp.charAt(i - 1) == '\\') {
|
||||
temp = temp.substring(0, i - 1) +
|
||||
temp.substring(i, temp.length());
|
||||
continue;
|
||||
} else {
|
||||
if (componentStart < i) {
|
||||
component = temp.substring(componentStart, i);
|
||||
tempStrings.addElement(component);
|
||||
}
|
||||
componentStart = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == temp.length()) {
|
||||
component = temp.substring(componentStart, i);
|
||||
tempStrings.addElement(component);
|
||||
}
|
||||
|
||||
String[] result = new String[tempStrings.size()];
|
||||
tempStrings.copyInto(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PrincipalName from a string.
|
||||
* @param name the name
|
||||
* @param type the type
|
||||
* @param realm the realm, null if not known. Note that when realm is not
|
||||
* null, it will be always used even if there is a realm part in name. When
|
||||
* realm is null, will read realm part from name, or try to map a realm
|
||||
* (for KRB_NT_SRV_HST), or use the default realm, or fail
|
||||
* @throws RealmException
|
||||
*/
|
||||
public PrincipalName(String name, int type, String realm)
|
||||
throws RealmException {
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException("Null name not allowed");
|
||||
}
|
||||
String[] nameParts = parseName(name);
|
||||
validateNameStrings(nameParts);
|
||||
if (realm == null) {
|
||||
realm = Realm.parseRealmAtSeparator(name);
|
||||
}
|
||||
|
||||
// No realm info from parameter and string, must deduce later
|
||||
realmDeduced = realm == null;
|
||||
|
||||
switch (type) {
|
||||
case KRB_NT_SRV_HST:
|
||||
if (nameParts.length >= 2) {
|
||||
String hostName = nameParts[1];
|
||||
try {
|
||||
// RFC4120 does not recommend canonicalizing a hostname.
|
||||
// However, for compatibility reason, we will try
|
||||
// canonicalize it and see if the output looks better.
|
||||
|
||||
String canonicalized = (InetAddress.getByName(hostName)).
|
||||
getCanonicalHostName();
|
||||
|
||||
// Looks if canonicalized is a longer format of hostName,
|
||||
// we accept cases like
|
||||
// bunny -> bunny.rabbit.hole
|
||||
if (canonicalized.toLowerCase(Locale.ENGLISH).startsWith(
|
||||
hostName.toLowerCase(Locale.ENGLISH)+".")) {
|
||||
hostName = canonicalized;
|
||||
}
|
||||
} catch (UnknownHostException | SecurityException e) {
|
||||
// not canonicalized or no permission to do so, use old
|
||||
}
|
||||
if (hostName.endsWith(".")) {
|
||||
hostName = hostName.substring(0, hostName.length() - 1);
|
||||
}
|
||||
nameParts[1] = hostName.toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
nameStrings = nameParts;
|
||||
nameType = type;
|
||||
|
||||
if (realm != null) {
|
||||
nameRealm = new Realm(realm);
|
||||
} else {
|
||||
// We will try to get realm name from the mapping in
|
||||
// the configuration. If it is not specified
|
||||
// we will use the default realm. This nametype does
|
||||
// not allow a realm to be specified. The name string must of
|
||||
// the form service@host and this is internally changed into
|
||||
// service/host by Kerberos
|
||||
String mapRealm = mapHostToRealm(nameParts[1]);
|
||||
if (mapRealm != null) {
|
||||
nameRealm = new Realm(mapRealm);
|
||||
} else {
|
||||
nameRealm = Realm.getDefault();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KRB_NT_UNKNOWN:
|
||||
case KRB_NT_PRINCIPAL:
|
||||
case KRB_NT_SRV_INST:
|
||||
case KRB_NT_SRV_XHST:
|
||||
case KRB_NT_UID:
|
||||
case KRB_NT_ENTERPRISE:
|
||||
nameStrings = nameParts;
|
||||
nameType = type;
|
||||
if (realm != null) {
|
||||
nameRealm = new Realm(realm);
|
||||
} else {
|
||||
nameRealm = Realm.getDefault();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Illegal name type");
|
||||
}
|
||||
}
|
||||
|
||||
public PrincipalName(String name, int type) throws RealmException {
|
||||
this(name, type, (String)null);
|
||||
}
|
||||
|
||||
public PrincipalName(String name) throws RealmException {
|
||||
this(name, KRB_NT_UNKNOWN);
|
||||
}
|
||||
|
||||
public PrincipalName(String name, String realm) throws RealmException {
|
||||
this(name, KRB_NT_UNKNOWN, realm);
|
||||
}
|
||||
|
||||
public static PrincipalName tgsService(String r1, String r2)
|
||||
throws KrbException {
|
||||
return new PrincipalName(PrincipalName.KRB_NT_SRV_INST,
|
||||
new String[] {PrincipalName.TGS_DEFAULT_SRV_NAME, r1},
|
||||
new Realm(r2));
|
||||
}
|
||||
|
||||
public String getRealmAsString() {
|
||||
return getRealmString();
|
||||
}
|
||||
|
||||
public String getPrincipalNameAsString() {
|
||||
StringBuffer temp = new StringBuffer(nameStrings[0]);
|
||||
for (int i = 1; i < nameStrings.length; i++)
|
||||
temp.append(nameStrings[i]);
|
||||
return temp.toString();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
public int getNameType() {
|
||||
return nameType;
|
||||
}
|
||||
|
||||
public String[] getNameStrings() {
|
||||
return nameStrings.clone();
|
||||
}
|
||||
|
||||
public byte[][] toByteArray() {
|
||||
byte[][] result = new byte[nameStrings.length][];
|
||||
for (int i = 0; i < nameStrings.length; i++) {
|
||||
result[i] = new byte[nameStrings[i].length()];
|
||||
result[i] = nameStrings[i].getBytes();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getRealmString() {
|
||||
return nameRealm.toString();
|
||||
}
|
||||
|
||||
public Realm getRealm() {
|
||||
return nameRealm;
|
||||
}
|
||||
|
||||
public String getSalt() {
|
||||
if (salt == null) {
|
||||
StringBuffer salt = new StringBuffer();
|
||||
salt.append(nameRealm.toString());
|
||||
for (int i = 0; i < nameStrings.length; i++) {
|
||||
salt.append(nameStrings[i]);
|
||||
}
|
||||
return salt.toString();
|
||||
}
|
||||
return salt;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer str = new StringBuffer();
|
||||
for (int i = 0; i < nameStrings.length; i++) {
|
||||
if (i > 0)
|
||||
str.append("/");
|
||||
String n = nameStrings[i];
|
||||
n = n.replace("@", "\\@");
|
||||
str.append(n);
|
||||
}
|
||||
str.append("@");
|
||||
str.append(nameRealm.toString());
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public String getNameString() {
|
||||
StringBuffer str = new StringBuffer();
|
||||
for (int i = 0; i < nameStrings.length; i++) {
|
||||
if (i > 0)
|
||||
str.append("/");
|
||||
str.append(nameStrings[i]);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a <code>PrincipalName</code> object. Note that only the type and
|
||||
* names are encoded. To encode the realm, call getRealm().asn1Encode().
|
||||
* @return the byte array of the encoded PrncipalName object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
BigInteger bint = BigInteger.valueOf(this.nameType);
|
||||
temp.putInteger(bint);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
DerValue der[] = new DerValue[nameStrings.length];
|
||||
for (int i = 0; i < nameStrings.length; i++) {
|
||||
der[i] = new KerberosString(nameStrings[i]).toDerValue();
|
||||
}
|
||||
temp.putSequence(der);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if two <code>PrincipalName</code> objects have identical values in their corresponding data fields.
|
||||
*
|
||||
* @param pname the other <code>PrincipalName</code> object.
|
||||
* @return true if two have identical values, otherwise, return false.
|
||||
*/
|
||||
// It is used in <code>sun.security.krb5.internal.ccache</code> package.
|
||||
public boolean match(PrincipalName pname) {
|
||||
boolean matched = true;
|
||||
//name type is just a hint, no two names can be the same ignoring name type.
|
||||
// if (this.nameType != pname.nameType) {
|
||||
// matched = false;
|
||||
// }
|
||||
if ((this.nameRealm != null) && (pname.nameRealm != null)) {
|
||||
if (!(this.nameRealm.toString().equalsIgnoreCase(pname.nameRealm.toString()))) {
|
||||
matched = false;
|
||||
}
|
||||
}
|
||||
if (this.nameStrings.length != pname.nameStrings.length) {
|
||||
matched = false;
|
||||
} else {
|
||||
for (int i = 0; i < this.nameStrings.length; i++) {
|
||||
if (!(this.nameStrings[i].equalsIgnoreCase(pname.nameStrings[i]))) {
|
||||
matched = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data field values of <code>PrincipalName</code> in FCC format to an output stream.
|
||||
*
|
||||
* @param cos a <code>CCacheOutputStream</code> for writing data.
|
||||
* @exception IOException if an I/O exception occurs.
|
||||
* @see sun.security.krb5.internal.ccache.CCacheOutputStream
|
||||
*/
|
||||
public void writePrincipal(CCacheOutputStream cos) throws IOException {
|
||||
cos.write32(nameType);
|
||||
cos.write32(nameStrings.length);
|
||||
byte[] realmBytes = null;
|
||||
realmBytes = nameRealm.toString().getBytes();
|
||||
cos.write32(realmBytes.length);
|
||||
cos.write(realmBytes, 0, realmBytes.length);
|
||||
byte[] bytes = null;
|
||||
for (int i = 0; i < nameStrings.length; i++) {
|
||||
bytes = nameStrings[i].getBytes();
|
||||
cos.write32(bytes.length);
|
||||
cos.write(bytes, 0, bytes.length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance component of a name.
|
||||
* In a multi-component name such as a KRB_NT_SRV_INST
|
||||
* name, the second component is returned.
|
||||
* Null is returned if there are not two or more
|
||||
* components in the name.
|
||||
*
|
||||
* @return instance component of a multi-component name.
|
||||
*/
|
||||
public String getInstanceComponent()
|
||||
{
|
||||
if (nameStrings != null && nameStrings.length >= 2)
|
||||
{
|
||||
return new String(nameStrings[1]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String mapHostToRealm(String name) {
|
||||
String result = null;
|
||||
try {
|
||||
String subname = null;
|
||||
Config c = Config.getInstance();
|
||||
if ((result = c.get("domain_realm", name)) != null)
|
||||
return result;
|
||||
else {
|
||||
for (int i = 1; i < name.length(); i++) {
|
||||
if ((name.charAt(i) == '.') && (i != name.length() - 1)) { //mapping could be .ibm.com = AUSTIN.IBM.COM
|
||||
subname = name.substring(i);
|
||||
result = c.get("domain_realm", subname);
|
||||
if (result != null) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
subname = name.substring(i + 1); //or mapping could be ibm.com = AUSTIN.IBM.COM
|
||||
result = c.get("domain_realm", subname);
|
||||
if (result != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (KrbException e) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isRealmDeduced() {
|
||||
return realmDeduced;
|
||||
}
|
||||
}
|
||||
418
jdkSrc/jdk8/sun/security/krb5/Realm.java
Normal file
418
jdkSrc/jdk8/sun/security/krb5/Realm.java
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import sun.security.krb5.internal.Krb5;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.krb5.internal.util.KerberosString;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 Realm type.
|
||||
*
|
||||
* {@code Realm ::= GeneralString}
|
||||
*
|
||||
* This class is immutable.
|
||||
*/
|
||||
public class Realm implements Cloneable {
|
||||
|
||||
public static final boolean AUTODEDUCEREALM =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetBooleanAction(
|
||||
"sun.security.krb5.autodeducerealm"));
|
||||
|
||||
private final String realm; // not null nor empty
|
||||
|
||||
public Realm(String name) throws RealmException {
|
||||
realm = parseRealm(name);
|
||||
}
|
||||
|
||||
public static Realm getDefault() throws RealmException {
|
||||
try {
|
||||
return new Realm(Config.getInstance().getDefaultRealm());
|
||||
} catch (RealmException re) {
|
||||
throw re;
|
||||
} catch (KrbException ke) {
|
||||
throw new RealmException(ke);
|
||||
}
|
||||
}
|
||||
|
||||
// Immutable class, no need to clone
|
||||
public Object clone() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Realm)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Realm that = (Realm)obj;
|
||||
return this.realm.equals(that.realm);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return realm.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Realm object.
|
||||
* @param encoding a Der-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
*/
|
||||
public Realm(DerValue encoding)
|
||||
throws Asn1Exception, RealmException, IOException {
|
||||
if (encoding == null) {
|
||||
throw new IllegalArgumentException("encoding can not be null");
|
||||
}
|
||||
realm = new KerberosString(encoding).toString();
|
||||
if (realm == null || realm.length() == 0)
|
||||
throw new RealmException(Krb5.REALM_NULL);
|
||||
if (!isValidRealmString(realm))
|
||||
throw new RealmException(Krb5.REALM_ILLCHAR);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
// Extract realm from a string like dummy@REALM
|
||||
public static String parseRealmAtSeparator(String name)
|
||||
throws RealmException {
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException
|
||||
("null input name is not allowed");
|
||||
}
|
||||
String temp = new String(name);
|
||||
String result = null;
|
||||
int i = 0;
|
||||
while (i < temp.length()) {
|
||||
if (temp.charAt(i) == PrincipalName.NAME_REALM_SEPARATOR) {
|
||||
if (i == 0 || temp.charAt(i - 1) != '\\') {
|
||||
if (i + 1 < temp.length()) {
|
||||
result = temp.substring(i + 1, temp.length());
|
||||
} else {
|
||||
throw new IllegalArgumentException
|
||||
("empty realm part not allowed");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (result != null) {
|
||||
if (result.length() == 0)
|
||||
throw new RealmException(Krb5.REALM_NULL);
|
||||
if (!isValidRealmString(result))
|
||||
throw new RealmException(Krb5.REALM_ILLCHAR);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String parseRealmComponent(String name) {
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException
|
||||
("null input name is not allowed");
|
||||
}
|
||||
String temp = new String(name);
|
||||
String result = null;
|
||||
int i = 0;
|
||||
while (i < temp.length()) {
|
||||
if (temp.charAt(i) == PrincipalName.REALM_COMPONENT_SEPARATOR) {
|
||||
if (i == 0 || temp.charAt(i - 1) != '\\') {
|
||||
if (i + 1 < temp.length())
|
||||
result = temp.substring(i + 1, temp.length());
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected static String parseRealm(String name) throws RealmException {
|
||||
String result = parseRealmAtSeparator(name);
|
||||
if (result == null)
|
||||
result = name;
|
||||
if (result == null || result.length() == 0)
|
||||
throw new RealmException(Krb5.REALM_NULL);
|
||||
if (!isValidRealmString(result))
|
||||
throw new RealmException(Krb5.REALM_ILLCHAR);
|
||||
return result;
|
||||
}
|
||||
|
||||
// This is protected because the definition of a realm
|
||||
// string is fixed
|
||||
protected static boolean isValidRealmString(String name) {
|
||||
if (name == null)
|
||||
return false;
|
||||
if (name.length() == 0)
|
||||
return false;
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
if (name.charAt(i) == '/' ||
|
||||
name.charAt(i) == '\0') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a Realm object.
|
||||
* @return the byte array of encoded KrbCredInfo object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.putDerValue(new KerberosString(this.realm).toDerValue());
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a realm from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicate if this data field is optional
|
||||
* @return an instance of Realm.
|
||||
*
|
||||
*/
|
||||
public static Realm parse(DerInputStream data, byte explicitTag, boolean optional)
|
||||
throws Asn1Exception, IOException, RealmException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag)) {
|
||||
return null;
|
||||
}
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
} else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new Realm(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of realms that may be traversed to obtain
|
||||
* a TGT from the initiating realm cRealm to the target realm
|
||||
* sRealm.
|
||||
* <br>
|
||||
* This method would read [capaths] to create a path, or generate a
|
||||
* hierarchical path if [capaths] does not contain a sub-stanza for cRealm
|
||||
* or the sub-stanza does not contain a tag for sRealm.
|
||||
* <br>
|
||||
* The returned list would never be null, and it always contains
|
||||
* cRealm as the head entry. sRealm is not included as the tail.
|
||||
*
|
||||
* @param cRealm the initiating realm, not null
|
||||
* @param sRealm the target realm, not null, not equals to cRealm
|
||||
* @return array of realms including at least cRealm as the first
|
||||
* element
|
||||
*/
|
||||
public static String[] getRealmsList(String cRealm, String sRealm) {
|
||||
try {
|
||||
// Try [capaths]
|
||||
return parseCapaths(cRealm, sRealm);
|
||||
} catch (KrbException ke) {
|
||||
// Now assume the realms are organized hierarchically.
|
||||
return parseHierarchy(cRealm, sRealm);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the [capaths] stanza of the configuration file for a
|
||||
* list of realms to traverse to obtain credentials from the
|
||||
* initiating realm cRealm to the target realm sRealm.
|
||||
*
|
||||
* For a given client realm C there is a tag C in [capaths] whose
|
||||
* subtag S has a value which is a (possibly partial) path from C
|
||||
* to S. When the path is partial, it contains only the tail of the
|
||||
* full path. Values of other subtags will be used to build the full
|
||||
* path. The value "." means a direct path from C to S. If realm S
|
||||
* does not appear as a subtag, there is no path defined here.
|
||||
*
|
||||
* The implementation ignores all values which equals to C or S, or
|
||||
* a "." in multiple values, or any duplicated realm names.
|
||||
*
|
||||
* When a path value has more than two realms, they can be specified
|
||||
* with multiple key-value pairs each having a single value, but the
|
||||
* order must not change.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* [capaths]
|
||||
* TIVOLI.COM = {
|
||||
* IBM.COM = IBM_LDAPCENTRAL.COM MOONLITE.ORG
|
||||
* IBM_LDAPCENTRAL.COM = LDAPCENTRAL.NET
|
||||
* LDAPCENTRAL.NET = .
|
||||
* }
|
||||
*
|
||||
* TIVOLI.COM has a direct path to LDAPCENTRAL.NET, which has a direct
|
||||
* path to IBM_LDAPCENTRAL.COM. It also has a partial path to IBM.COM
|
||||
* being "IBM_LDAPCENTRAL.COM MOONLITE.ORG". Merging these info together,
|
||||
* a full path from TIVOLI.COM to IBM.COM will be
|
||||
*
|
||||
* TIVOLI.COM -> LDAPCENTRAL.NET -> IBM_LDAPCENTRAL.COM
|
||||
* -> IBM_LDAPCENTRAL.COM -> MOONLITE.ORG
|
||||
*
|
||||
* Please note the sRealm IBM.COM does not appear in the path.
|
||||
*
|
||||
* @param cRealm the initiating realm
|
||||
* @param sRealm the target realm, not the same as cRealm
|
||||
* @returns array of realms including at least cRealm as the first
|
||||
* element
|
||||
* @throws KrbException if the config does not contain a sub-stanza
|
||||
* for cRealm in [capaths] or the sub-stanza does not contain
|
||||
* sRealm as a tag
|
||||
*/
|
||||
private static String[] parseCapaths(String cRealm, String sRealm)
|
||||
throws KrbException {
|
||||
|
||||
// This line could throw a KrbException
|
||||
Config cfg = Config.getInstance();
|
||||
|
||||
if (!cfg.exists("capaths", cRealm, sRealm)) {
|
||||
throw new KrbException("No conf");
|
||||
}
|
||||
|
||||
LinkedList<String> path = new LinkedList<>();
|
||||
|
||||
String head = sRealm;
|
||||
while (true) {
|
||||
String value = cfg.getAll("capaths", cRealm, head);
|
||||
if (value == null) {
|
||||
break;
|
||||
}
|
||||
String[] more = value.split("\\s+");
|
||||
boolean changed = false;
|
||||
for (int i=more.length-1; i>=0; i--) {
|
||||
if (path.contains(more[i])
|
||||
|| more[i].equals(".")
|
||||
|| more[i].equals(cRealm)
|
||||
|| more[i].equals(sRealm)
|
||||
|| more[i].equals(head)) {
|
||||
// Ignore invalid values
|
||||
continue;
|
||||
}
|
||||
changed = true;
|
||||
path.addFirst(more[i]);
|
||||
}
|
||||
if (!changed) break;
|
||||
head = path.getFirst();
|
||||
}
|
||||
path.addFirst(cRealm);
|
||||
return path.toArray(new String[path.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a list of realm that can be traversed
|
||||
* to obtain credentials from the initiating realm cRealm
|
||||
* for a service in the target realm sRealm.
|
||||
* @param cRealm the initiating realm
|
||||
* @param sRealm the target realm, not the same as cRealm
|
||||
* @return array of realms including cRealm as the first element
|
||||
*/
|
||||
private static String[] parseHierarchy(String cRealm, String sRealm) {
|
||||
|
||||
String[] cComponents = cRealm.split("\\.");
|
||||
String[] sComponents = sRealm.split("\\.");
|
||||
|
||||
int cPos = cComponents.length;
|
||||
int sPos = sComponents.length;
|
||||
|
||||
boolean hasCommon = false;
|
||||
for (sPos--, cPos--; sPos >=0 && cPos >= 0 &&
|
||||
sComponents[sPos].equals(cComponents[cPos]);
|
||||
sPos--, cPos--) {
|
||||
hasCommon = true;
|
||||
}
|
||||
|
||||
// For those with common components:
|
||||
// length pos
|
||||
// SITES1.SALES.EXAMPLE.COM 4 1
|
||||
// EVERYWHERE.EXAMPLE.COM 3 0
|
||||
|
||||
// For those without common components:
|
||||
// length pos
|
||||
// DEVEL.EXAMPLE.COM 3 2
|
||||
// PROD.EXAMPLE.ORG 3 2
|
||||
|
||||
LinkedList<String> path = new LinkedList<>();
|
||||
|
||||
// Un-common ones for client side
|
||||
for (int i=0; i<=cPos; i++) {
|
||||
path.addLast(subStringFrom(cComponents, i));
|
||||
}
|
||||
|
||||
// Common one
|
||||
if (hasCommon) {
|
||||
path.addLast(subStringFrom(cComponents, cPos+1));
|
||||
}
|
||||
|
||||
// Un-common ones for server side
|
||||
for (int i=sPos; i>=0; i--) {
|
||||
path.addLast(subStringFrom(sComponents, i));
|
||||
}
|
||||
|
||||
// Remove sRealm from path. Note that it might be added at last loop
|
||||
// or as a common component, if sRealm is a parent of cRealm
|
||||
path.removeLast();
|
||||
|
||||
return path.toArray(new String[path.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a realm name using components from the given position.
|
||||
* For example, subStringFrom({"A", "B", "C"}, 1) is "B.C".
|
||||
*/
|
||||
private static String subStringFrom(String[] components, int from) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i=from; i<components.length; i++) {
|
||||
if (sb.length() != 0) sb.append('.');
|
||||
sb.append(components[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
53
jdkSrc/jdk8/sun/security/krb5/RealmException.java
Normal file
53
jdkSrc/jdk8/sun/security/krb5/RealmException.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
public class RealmException extends KrbException {
|
||||
|
||||
private static final long serialVersionUID = -9100385213693792864L;
|
||||
|
||||
public RealmException(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
public RealmException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public RealmException(int i, String s) {
|
||||
super(i,s);
|
||||
}
|
||||
|
||||
public RealmException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
144
jdkSrc/jdk8/sun/security/krb5/SCDynamicStoreConfig.java
Normal file
144
jdkSrc/jdk8/sun/security/krb5/SCDynamicStoreConfig.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, 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 sun.security.krb5;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
public class SCDynamicStoreConfig {
|
||||
private static native void installNotificationCallback();
|
||||
private static native Hashtable<String, Object> getKerberosConfig();
|
||||
private static boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;
|
||||
|
||||
static {
|
||||
boolean isMac = java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Boolean>() {
|
||||
public Boolean run() {
|
||||
String osname = System.getProperty("os.name");
|
||||
if (osname.contains("OS X")) {
|
||||
System.loadLibrary("osx");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (isMac) installNotificationCallback();
|
||||
}
|
||||
|
||||
private static Vector<String> unwrapHost(
|
||||
Collection<Hashtable<String, String>> c) {
|
||||
Vector<String> vector = new Vector<String>();
|
||||
for (Hashtable<String, String> m : c) {
|
||||
vector.add(m.get("host"));
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
/**
|
||||
* convertRealmConfigs: Maps the Object graph that we get from JNI to the
|
||||
* object graph that Config expects. Also the items inside the kdc array
|
||||
* are wrapped inside Hashtables
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Hashtable<String, Object>
|
||||
convertRealmConfigs(Hashtable<String, ?> configs) {
|
||||
Hashtable<String, Object> realmsTable = new Hashtable<String, Object>();
|
||||
|
||||
for (String realm : configs.keySet()) {
|
||||
// get the kdc
|
||||
Hashtable<String, Collection<?>> map =
|
||||
(Hashtable<String, Collection<?>>) configs.get(realm);
|
||||
Hashtable<String, Vector<String>> realmMap =
|
||||
new Hashtable<String, Vector<String>>();
|
||||
|
||||
// put the kdc into the realmMap
|
||||
Collection<Hashtable<String, String>> kdc =
|
||||
(Collection<Hashtable<String, String>>) map.get("kdc");
|
||||
if (kdc != null) realmMap.put("kdc", unwrapHost(kdc));
|
||||
|
||||
// put the admin server into the realmMap
|
||||
Collection<Hashtable<String, String>> kadmin =
|
||||
(Collection<Hashtable<String, String>>) map.get("kadmin");
|
||||
if (kadmin != null) realmMap.put("admin_server", unwrapHost(kadmin));
|
||||
|
||||
// add the full entry to the realmTable
|
||||
realmsTable.put(realm, realmMap);
|
||||
}
|
||||
|
||||
return realmsTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls down to JNI to get the raw Kerberos Config and maps the object
|
||||
* graph to the one that Kerberos Config in Java expects
|
||||
*
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Hashtable<String, Object> getConfig() throws IOException {
|
||||
Hashtable<String, Object> stanzaTable = getKerberosConfig();
|
||||
if (stanzaTable == null) {
|
||||
throw new IOException(
|
||||
"Could not load configuration from SCDynamicStore");
|
||||
}
|
||||
if (DEBUG) System.out.println("Raw map from JNI: " + stanzaTable);
|
||||
return convertNativeConfig(stanzaTable);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Hashtable<String, Object> convertNativeConfig(
|
||||
Hashtable<String, Object> stanzaTable) {
|
||||
// convert SCDynamicStore realm structure to Java realm structure
|
||||
Hashtable<String, ?> realms =
|
||||
(Hashtable<String, ?>) stanzaTable.get("realms");
|
||||
if (realms != null) {
|
||||
stanzaTable.remove("realms");
|
||||
Hashtable<String, Object> realmsTable = convertRealmConfigs(realms);
|
||||
stanzaTable.put("realms", realmsTable);
|
||||
}
|
||||
WrapAllStringInVector(stanzaTable);
|
||||
if (DEBUG) System.out.println("stanzaTable : " + stanzaTable);
|
||||
return stanzaTable;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void WrapAllStringInVector(
|
||||
Hashtable<String, Object> stanzaTable) {
|
||||
for (String s: stanzaTable.keySet()) {
|
||||
Object v = stanzaTable.get(s);
|
||||
if (v instanceof Hashtable) {
|
||||
WrapAllStringInVector((Hashtable<String,Object>)v);
|
||||
} else if (v instanceof String) {
|
||||
Vector<String> vec = new Vector<>();
|
||||
vec.add((String)v);
|
||||
stanzaTable.put(s, vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
110
jdkSrc/jdk8/sun/security/krb5/internal/APOptions.java
Normal file
110
jdkSrc/jdk8/sun/security/krb5/internal/APOptions.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.internal.util.KerberosFlags;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 APOptions type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* APOptions ::= KerberosFlags
|
||||
* -- reserved(0),
|
||||
* -- use-session-key(1),
|
||||
* -- mutual-required(2)
|
||||
*
|
||||
* KerberosFlags ::= BIT STRING (SIZE (32..MAX))
|
||||
* -- minimum number of bits shall be sent,
|
||||
* -- but no fewer than 32
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class APOptions extends KerberosFlags {
|
||||
public APOptions() {
|
||||
super(Krb5.AP_OPTS_MAX + 1);
|
||||
}
|
||||
|
||||
public APOptions(int oneBit) throws Asn1Exception {
|
||||
super(Krb5.AP_OPTS_MAX + 1);
|
||||
set(oneBit, true);
|
||||
}
|
||||
public APOptions(int size, byte[] data) throws Asn1Exception {
|
||||
super(size, data);
|
||||
if ((size > data.length * BITS_PER_UNIT) || (size > Krb5.AP_OPTS_MAX + 1)) {
|
||||
throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
public APOptions(boolean[] data) throws Asn1Exception {
|
||||
super(data);
|
||||
if (data.length > Krb5.AP_OPTS_MAX + 1) {
|
||||
throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
public APOptions(DerValue encoding) throws IOException, Asn1Exception {
|
||||
this(encoding.getUnalignedBitString(true).toBooleanArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) an APOptions from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicate if this data field is optional.
|
||||
* @return an instance of APOptions.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
public static APOptions parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
} else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new APOptions(subDer);
|
||||
}
|
||||
}
|
||||
}
|
||||
141
jdkSrc/jdk8/sun/security/krb5/internal/APRep.java
Normal file
141
jdkSrc/jdk8/sun/security/krb5/internal/APRep.java
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 AP-REP type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* AP-REP ::= [APPLICATION 15] SEQUENCE {
|
||||
* pvno [0] INTEGER (5),
|
||||
* msg-type [1] INTEGER (15),
|
||||
* enc-part [2] EncryptedData -- EncAPRepPart
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class APRep {
|
||||
|
||||
public int pvno;
|
||||
public int msgType;
|
||||
public EncryptedData encPart;
|
||||
|
||||
public APRep(EncryptedData new_encPart) {
|
||||
pvno = Krb5.PVNO;
|
||||
msgType = Krb5.KRB_AP_REP;
|
||||
encPart = new_encPart;
|
||||
}
|
||||
|
||||
public APRep(byte[] data) throws Asn1Exception,
|
||||
KrbApErrException, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public APRep(DerValue encoding) throws Asn1Exception,
|
||||
KrbApErrException, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an APRep object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception KrbApErrException if the value read from the DER-encoded data
|
||||
* stream does not match the pre-defined value.
|
||||
*/
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
KrbApErrException, IOException {
|
||||
|
||||
if (((encoding.getTag() & (byte) (0x1F)) != Krb5.KRB_AP_REP)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
DerValue der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
pvno = subDer.getData().getBigInteger().intValue();
|
||||
if (pvno != Krb5.PVNO) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x01) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
msgType = subDer.getData().getBigInteger().intValue();
|
||||
if (msgType != Krb5.KRB_AP_REP) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
|
||||
}
|
||||
encPart = EncryptedData.parse(der.getData(), (byte) 0x02, false);
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an APRep object.
|
||||
* @return byte array of encoded APRep object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(pvno));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(msgType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), encPart.asn1Encode());
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
DerOutputStream aprep = new DerOutputStream();
|
||||
aprep.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x0F), temp);
|
||||
return aprep.toByteArray();
|
||||
}
|
||||
}
|
||||
151
jdkSrc/jdk8/sun/security/krb5/internal/APReq.java
Normal file
151
jdkSrc/jdk8/sun/security/krb5/internal/APReq.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 AP-REQ type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* AP-REQ ::= [APPLICATION 14] SEQUENCE {
|
||||
* pvno [0] INTEGER (5),
|
||||
* msg-type [1] INTEGER (14),
|
||||
* ap-options [2] APOptions,
|
||||
* ticket [3] Ticket,
|
||||
* authenticator [4] EncryptedData -- Authenticator
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class APReq {
|
||||
|
||||
public int pvno;
|
||||
public int msgType;
|
||||
public APOptions apOptions;
|
||||
public Ticket ticket;
|
||||
public EncryptedData authenticator;
|
||||
|
||||
public APReq(
|
||||
APOptions new_apOptions,
|
||||
Ticket new_ticket,
|
||||
EncryptedData new_authenticator) {
|
||||
pvno = Krb5.PVNO;
|
||||
msgType = Krb5.KRB_AP_REQ;
|
||||
apOptions = new_apOptions;
|
||||
ticket = new_ticket;
|
||||
authenticator = new_authenticator;
|
||||
}
|
||||
|
||||
public APReq(byte[] data) throws Asn1Exception, IOException, KrbApErrException, RealmException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public APReq(DerValue encoding) throws Asn1Exception, IOException, KrbApErrException, RealmException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an APReq object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
*/
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
IOException, KrbApErrException, RealmException {
|
||||
DerValue der, subDer;
|
||||
if (((encoding.getTag() & (byte) 0x1F) != Krb5.KRB_AP_REQ)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
pvno = subDer.getData().getBigInteger().intValue();
|
||||
if (pvno != Krb5.PVNO) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x01) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
msgType = subDer.getData().getBigInteger().intValue();
|
||||
if (msgType != Krb5.KRB_AP_REQ) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
|
||||
}
|
||||
apOptions = APOptions.parse(der.getData(), (byte) 0x02, false);
|
||||
ticket = Ticket.parse(der.getData(), (byte) 0x03, false);
|
||||
authenticator = EncryptedData.parse(der.getData(), (byte) 0x04, false);
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an APReq object.
|
||||
* @return byte array of encoded APReq object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(pvno));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(msgType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), apOptions.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), ticket.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), authenticator.asn1Encode());
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
DerOutputStream apreq = new DerOutputStream();
|
||||
apreq.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x0E), temp);
|
||||
return apreq.toByteArray();
|
||||
}
|
||||
}
|
||||
66
jdkSrc/jdk8/sun/security/krb5/internal/ASRep.java
Normal file
66
jdkSrc/jdk8/sun/security/krb5/internal/ASRep.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.Realm;
|
||||
import sun.security.krb5.RealmException;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ASRep extends KDCRep {
|
||||
|
||||
public ASRep(
|
||||
PAData[] new_pAData,
|
||||
PrincipalName new_cname,
|
||||
Ticket new_ticket,
|
||||
EncryptedData new_encPart) throws IOException {
|
||||
super(new_pAData, new_cname, new_ticket,
|
||||
new_encPart, Krb5.KRB_AS_REP);
|
||||
}
|
||||
|
||||
public ASRep(byte[] data) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public ASRep(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(encoding, Krb5.KRB_AS_REP);
|
||||
}
|
||||
}
|
||||
54
jdkSrc/jdk8/sun/security/krb5/internal/ASReq.java
Normal file
54
jdkSrc/jdk8/sun/security/krb5/internal/ASReq.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ASReq extends KDCReq {
|
||||
|
||||
public ASReq(PAData[] new_pAData, KDCReqBody new_reqBody) throws IOException {
|
||||
super(new_pAData, new_reqBody, Krb5.KRB_AS_REQ);
|
||||
}
|
||||
|
||||
public ASReq(byte[] data) throws Asn1Exception, KrbException, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public ASReq(DerValue encoding) throws Asn1Exception, KrbException, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
private void init(DerValue encoding) throws Asn1Exception, IOException, KrbException {
|
||||
super.init(encoding, Krb5.KRB_AS_REQ);
|
||||
}
|
||||
}
|
||||
52
jdkSrc/jdk8/sun/security/krb5/internal/AuthContext.java
Normal file
52
jdkSrc/jdk8/sun/security/krb5/internal/AuthContext.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.EncryptionKey;
|
||||
import java.util.BitSet;
|
||||
|
||||
public class AuthContext {
|
||||
public HostAddress remoteAddress;
|
||||
public int remotePort;
|
||||
public HostAddress localAddress;
|
||||
public int localPort;
|
||||
public EncryptionKey keyBlock;
|
||||
public EncryptionKey localSubkey;
|
||||
public EncryptionKey remoteSubkey;
|
||||
public BitSet authContextFlags;
|
||||
public int remoteSeqNumber;
|
||||
public int localSeqNumber;
|
||||
public Authenticator authenticator;
|
||||
public int reqCksumType;
|
||||
public int safeCksumType;
|
||||
public byte[] initializationVector;
|
||||
//public ReplayCache replayCache;
|
||||
};
|
||||
221
jdkSrc/jdk8/sun/security/krb5/internal/Authenticator.java
Normal file
221
jdkSrc/jdk8/sun/security/krb5/internal/Authenticator.java
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 Authenticator type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* Authenticator ::= [APPLICATION 2] SEQUENCE {
|
||||
* authenticator-vno [0] INTEGER (5),
|
||||
* crealm [1] Realm,
|
||||
* cname [2] PrincipalName,
|
||||
* cksum [3] Checksum OPTIONAL,
|
||||
* cusec [4] Microseconds,
|
||||
* ctime [5] KerberosTime,
|
||||
* subkey [6] EncryptionKey OPTIONAL,
|
||||
* seq-number [7] UInt32 OPTIONAL,
|
||||
* authorization-data [8] AuthorizationData OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class Authenticator {
|
||||
|
||||
public int authenticator_vno;
|
||||
public PrincipalName cname;
|
||||
Checksum cksum; //optional
|
||||
public int cusec;
|
||||
public KerberosTime ctime;
|
||||
EncryptionKey subKey; //optional
|
||||
Integer seqNumber; //optional
|
||||
public AuthorizationData authorizationData; //optional
|
||||
|
||||
public Authenticator(
|
||||
PrincipalName new_cname,
|
||||
Checksum new_cksum,
|
||||
int new_cusec,
|
||||
KerberosTime new_ctime,
|
||||
EncryptionKey new_subKey,
|
||||
Integer new_seqNumber,
|
||||
AuthorizationData new_authorizationData) {
|
||||
authenticator_vno = Krb5.AUTHNETICATOR_VNO;
|
||||
cname = new_cname;
|
||||
cksum = new_cksum;
|
||||
cusec = new_cusec;
|
||||
ctime = new_ctime;
|
||||
subKey = new_subKey;
|
||||
seqNumber = new_seqNumber;
|
||||
authorizationData = new_authorizationData;
|
||||
}
|
||||
|
||||
public Authenticator(byte[] data)
|
||||
throws Asn1Exception, IOException, KrbApErrException, RealmException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public Authenticator(DerValue encoding)
|
||||
throws Asn1Exception, IOException, KrbApErrException, RealmException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an Authenticator object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception KrbApErrException if the value read from the DER-encoded data
|
||||
* stream does not match the pre-defined value.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
*/
|
||||
private void init(DerValue encoding)
|
||||
throws Asn1Exception, IOException, KrbApErrException, RealmException {
|
||||
DerValue der, subDer;
|
||||
//may not be the correct error code for a tag
|
||||
//mismatch on an encrypted structure
|
||||
if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x02)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
authenticator_vno = subDer.getData().getBigInteger().intValue();
|
||||
if (authenticator_vno != 5) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
}
|
||||
Realm crealm = Realm.parse(der.getData(), (byte) 0x01, false);
|
||||
cname = PrincipalName.parse(der.getData(), (byte) 0x02, false, crealm);
|
||||
cksum = Checksum.parse(der.getData(), (byte) 0x03, true);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) == 0x04) {
|
||||
cusec = subDer.getData().getBigInteger().intValue();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
ctime = KerberosTime.parse(der.getData(), (byte) 0x05, false);
|
||||
if (der.getData().available() > 0) {
|
||||
subKey = EncryptionKey.parse(der.getData(), (byte) 0x06, true);
|
||||
} else {
|
||||
subKey = null;
|
||||
seqNumber = null;
|
||||
authorizationData = null;
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
if ((der.getData().peekByte() & 0x1F) == 0x07) {
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x07) {
|
||||
seqNumber = new Integer(subDer.getData().getBigInteger().intValue());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
seqNumber = null;
|
||||
authorizationData = null;
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
authorizationData = AuthorizationData.parse(der.getData(), (byte) 0x08, true);
|
||||
} else {
|
||||
authorizationData = null;
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an Authenticator object.
|
||||
* @return byte array of encoded Authenticator object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
Vector<DerValue> v = new Vector<>();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(authenticator_vno));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp.toByteArray()));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), cname.getRealm().asn1Encode()));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), cname.asn1Encode()));
|
||||
if (cksum != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), cksum.asn1Encode()));
|
||||
}
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(cusec));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), temp.toByteArray()));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x05), ctime.asn1Encode()));
|
||||
if (subKey != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x06), subKey.asn1Encode()));
|
||||
}
|
||||
if (seqNumber != null) {
|
||||
temp = new DerOutputStream();
|
||||
// encode as an unsigned integer (UInt32)
|
||||
temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x07), temp.toByteArray()));
|
||||
}
|
||||
if (authorizationData != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x08), authorizationData.asn1Encode()));
|
||||
}
|
||||
DerValue der[] = new DerValue[v.size()];
|
||||
v.copyInto(der);
|
||||
temp = new DerOutputStream();
|
||||
temp.putSequence(der);
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x02), temp);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public final Checksum getChecksum() {
|
||||
return cksum;
|
||||
}
|
||||
|
||||
public final Integer getSeqNumber() {
|
||||
return seqNumber;
|
||||
}
|
||||
|
||||
public final EncryptionKey getSubKey() {
|
||||
return subKey;
|
||||
}
|
||||
}
|
||||
184
jdkSrc/jdk8/sun/security/krb5/internal/AuthorizationData.java
Normal file
184
jdkSrc/jdk8/sun/security/krb5/internal/AuthorizationData.java
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import sun.security.krb5.internal.ccache.CCacheOutputStream;
|
||||
|
||||
/**
|
||||
* In RFC4120, the ASN.1 AuthorizationData is defined as:
|
||||
*
|
||||
* AuthorizationData ::= SEQUENCE OF SEQUENCE {
|
||||
* ad-type [0] Int32,
|
||||
* ad-data [1] OCTET STRING
|
||||
* }
|
||||
*
|
||||
* Here, two classes are used to implement it and they can be represented as follows:
|
||||
*
|
||||
* AuthorizationData ::= SEQUENCE OF AuthorizationDataEntry
|
||||
* AuthorizationDataEntry ::= SEQUENCE {
|
||||
* ad-type[0] Int32,
|
||||
* ad-data[1] OCTET STRING
|
||||
* }
|
||||
*/
|
||||
public class AuthorizationData implements Cloneable {
|
||||
|
||||
private AuthorizationDataEntry[] entry = null;
|
||||
|
||||
private AuthorizationData() {
|
||||
}
|
||||
|
||||
public AuthorizationData(AuthorizationDataEntry[] new_entries)
|
||||
throws IOException {
|
||||
if (new_entries != null) {
|
||||
entry = new AuthorizationDataEntry[new_entries.length];
|
||||
for (int i = 0; i < new_entries.length; i++) {
|
||||
if (new_entries[i] == null) {
|
||||
throw new IOException("Cannot create an AuthorizationData");
|
||||
} else {
|
||||
entry[i] = (AuthorizationDataEntry) new_entries[i].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AuthorizationData(AuthorizationDataEntry new_entry) {
|
||||
entry = new AuthorizationDataEntry[1];
|
||||
entry[0] = new_entry;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
AuthorizationData new_authorizationData =
|
||||
new AuthorizationData();
|
||||
if (entry != null) {
|
||||
new_authorizationData.entry =
|
||||
new AuthorizationDataEntry[entry.length];
|
||||
for (int i = 0; i < entry.length; i++) {
|
||||
new_authorizationData.entry[i] =
|
||||
(AuthorizationDataEntry) entry[i].clone();
|
||||
}
|
||||
}
|
||||
return new_authorizationData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>AuthorizationData,</code> instance.
|
||||
* @param der a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public AuthorizationData(DerValue der) throws Asn1Exception, IOException {
|
||||
Vector<AuthorizationDataEntry> v = new Vector<>();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
while (der.getData().available() > 0) {
|
||||
v.addElement(new AuthorizationDataEntry(der.getData().getDerValue()));
|
||||
}
|
||||
if (v.size() > 0) {
|
||||
entry = new AuthorizationDataEntry[v.size()];
|
||||
v.copyInto(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an <code>AuthorizationData</code> object.
|
||||
* @return byte array of encoded <code>AuthorizationData</code> object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerValue der[] = new DerValue[entry.length];
|
||||
for (int i = 0; i < entry.length; i++) {
|
||||
der[i] = new DerValue(entry[i].asn1Encode());
|
||||
}
|
||||
bytes.putSequence(der);
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) an <code>AuthorizationData</code> object from a DER input stream.
|
||||
* This form of parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicates if this data field is optional
|
||||
* @return an instance of AuthorizationData.
|
||||
*
|
||||
*/
|
||||
public static AuthorizationData parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
|
||||
if ((optional) && (((byte) data.peekByte() & (byte) 0x1F) != explicitTag)) {
|
||||
return null;
|
||||
}
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte) 0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
} else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new AuthorizationData(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes <code>AuthorizationData</code> data fields to a output stream.
|
||||
*
|
||||
* @param cos a <code>CCacheOutputStream</code> to be written to.
|
||||
* @exception IOException if an I/O exception occurs.
|
||||
*/
|
||||
public void writeAuth(CCacheOutputStream cos) throws IOException {
|
||||
for (int i = 0; i < entry.length; i++) {
|
||||
entry[i].writeEntry(cos);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String retVal = "AuthorizationData:\n";
|
||||
for (int i = 0; i < entry.length; i++) {
|
||||
retVal += entry[i].toString();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return entry.length;
|
||||
}
|
||||
|
||||
public AuthorizationDataEntry item(int i) {
|
||||
return (AuthorizationDataEntry)entry[i].clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.internal.ccache.CCacheOutputStream;
|
||||
|
||||
public class AuthorizationDataEntry implements Cloneable {
|
||||
|
||||
public int adType;
|
||||
public byte[] adData;
|
||||
|
||||
private AuthorizationDataEntry() {
|
||||
}
|
||||
|
||||
public AuthorizationDataEntry(
|
||||
int new_adType,
|
||||
byte[] new_adData) {
|
||||
adType = new_adType;
|
||||
adData = new_adData;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
AuthorizationDataEntry new_authorizationDataEntry =
|
||||
new AuthorizationDataEntry();
|
||||
new_authorizationDataEntry.adType = adType;
|
||||
if (adData != null) {
|
||||
new_authorizationDataEntry.adData = new byte[adData.length];
|
||||
System.arraycopy(adData, 0,
|
||||
new_authorizationDataEntry.adData, 0, adData.length);
|
||||
}
|
||||
return new_authorizationDataEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of AuthorizationDataEntry.
|
||||
* @param encoding a single DER-encoded value.
|
||||
*/
|
||||
public AuthorizationDataEntry(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der;
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte) 0x1F) == (byte) 0x00) {
|
||||
adType = der.getData().getBigInteger().intValue();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte) 0x1F) == (byte) 0x01) {
|
||||
adData = der.getData().getOctetString();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if (encoding.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an AuthorizationDataEntry object.
|
||||
* @return byte array of encoded AuthorizationDataEntry object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(adType);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putOctetString(adData);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the entry's data fields in FCC format to an output stream.
|
||||
*
|
||||
* @param cos a <code>CCacheOutputStream</code>.
|
||||
* @exception IOException if an I/O exception occurs.
|
||||
*/
|
||||
public void writeEntry(CCacheOutputStream cos) throws IOException {
|
||||
cos.write16(adType);
|
||||
cos.write32(adData.length);
|
||||
cos.write(adData, 0, adData.length);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ("adType=" + adType + " adData.length=" + adData.length);
|
||||
}
|
||||
}
|
||||
561
jdkSrc/jdk8/sun/security/krb5/internal/CredentialsUtil.java
Normal file
561
jdkSrc/jdk8/sun/security/krb5/internal/CredentialsUtil.java
Normal file
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2021, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class is a utility that contains much of the TGS-Exchange
|
||||
* protocol. It is used by ../Credentials.java for service ticket
|
||||
* acquisition in both the normal and the x-realm case.
|
||||
*/
|
||||
public class CredentialsUtil {
|
||||
|
||||
private static boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;
|
||||
|
||||
private static enum S4U2Type {
|
||||
NONE, SELF, PROXY
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by a middle server to acquire credentials on behalf of a
|
||||
* user to itself using the S4U2self extension.
|
||||
* @param user the user to impersonate
|
||||
* @param ccreds the TGT of the middle service
|
||||
* @return the new creds (cname=user, sname=middle)
|
||||
*/
|
||||
public static Credentials acquireS4U2selfCreds(PrincipalName user,
|
||||
Credentials ccreds) throws KrbException, IOException {
|
||||
if (!ccreds.isForwardable()) {
|
||||
throw new KrbException("S4U2self needs a FORWARDABLE ticket");
|
||||
}
|
||||
PrincipalName sname = ccreds.getClient();
|
||||
String uRealm = user.getRealmString();
|
||||
String localRealm = ccreds.getClient().getRealmString();
|
||||
if (!uRealm.equals(localRealm)) {
|
||||
// Referrals will be required because the middle service
|
||||
// and the user impersonated are on different realms.
|
||||
if (Config.DISABLE_REFERRALS) {
|
||||
throw new KrbException("Cross-realm S4U2Self request not" +
|
||||
" possible when referrals are disabled.");
|
||||
}
|
||||
if (ccreds.getClientAlias() != null) {
|
||||
// If the name was canonicalized, the user pick
|
||||
// has preference. This gives the possibility of
|
||||
// using FQDNs that KDCs may use to return referrals.
|
||||
// I.e.: a SVC/host.realm-2.com@REALM-1.COM name
|
||||
// may be used by REALM-1.COM KDC to return a
|
||||
// referral to REALM-2.COM.
|
||||
sname = ccreds.getClientAlias();
|
||||
}
|
||||
sname = new PrincipalName(sname.getNameType(),
|
||||
sname.getNameStrings(), new Realm(uRealm));
|
||||
}
|
||||
Credentials creds = serviceCreds(
|
||||
KDCOptions.with(KDCOptions.FORWARDABLE),
|
||||
ccreds, ccreds.getClient(), sname, user,
|
||||
null, new PAData[] {
|
||||
new PAData(Krb5.PA_FOR_USER,
|
||||
new PAForUserEnc(user,
|
||||
ccreds.getSessionKey()).asn1Encode()),
|
||||
new PAData(Krb5.PA_PAC_OPTIONS,
|
||||
new PaPacOptions()
|
||||
.setResourceBasedConstrainedDelegation(true)
|
||||
.setClaims(true)
|
||||
.asn1Encode())
|
||||
}, S4U2Type.SELF);
|
||||
if (!creds.getClient().equals(user)) {
|
||||
throw new KrbException("S4U2self request not honored by KDC");
|
||||
}
|
||||
if (!creds.isForwardable()) {
|
||||
throw new KrbException("S4U2self ticket must be FORWARDABLE");
|
||||
}
|
||||
return creds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by a middle server to acquire a service ticket to a backend
|
||||
* server using the S4U2proxy extension.
|
||||
* @param backend the name of the backend service
|
||||
* @param second the client's service ticket to the middle server
|
||||
* @param ccreds the TGT of the middle server
|
||||
* @return the creds (cname=client, sname=backend)
|
||||
*/
|
||||
public static Credentials acquireS4U2proxyCreds(
|
||||
String backend, Ticket second,
|
||||
PrincipalName client, Credentials ccreds)
|
||||
throws KrbException, IOException {
|
||||
PrincipalName backendPrincipal = new PrincipalName(backend);
|
||||
String backendRealm = backendPrincipal.getRealmString();
|
||||
String localRealm = ccreds.getClient().getRealmString();
|
||||
if (!backendRealm.equals(localRealm)) {
|
||||
// The middle service and the backend service are on
|
||||
// different realms, so referrals will be required.
|
||||
if (Config.DISABLE_REFERRALS) {
|
||||
throw new KrbException("Cross-realm S4U2Proxy request not" +
|
||||
" possible when referrals are disabled.");
|
||||
}
|
||||
backendPrincipal = new PrincipalName(
|
||||
backendPrincipal.getNameType(),
|
||||
backendPrincipal.getNameStrings(),
|
||||
new Realm(localRealm));
|
||||
}
|
||||
Credentials creds = serviceCreds(KDCOptions.with(
|
||||
KDCOptions.CNAME_IN_ADDL_TKT, KDCOptions.FORWARDABLE),
|
||||
ccreds, ccreds.getClient(), backendPrincipal, null,
|
||||
new Ticket[] {second}, new PAData[] {
|
||||
new PAData(Krb5.PA_PAC_OPTIONS,
|
||||
new PaPacOptions()
|
||||
.setResourceBasedConstrainedDelegation(true)
|
||||
.setClaims(true)
|
||||
.asn1Encode())
|
||||
}, S4U2Type.PROXY);
|
||||
if (!creds.getClient().equals(client)) {
|
||||
throw new KrbException("S4U2proxy request not honored by KDC");
|
||||
}
|
||||
return creds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires credentials for a specified service using initial
|
||||
* credential. When the service has a different realm from the initial
|
||||
* credential, we do cross-realm authentication - first, we use the
|
||||
* current credential to get a cross-realm credential from the local KDC,
|
||||
* then use that cross-realm credential to request service credential
|
||||
* from the foreign KDC.
|
||||
*
|
||||
* @param service the name of service principal
|
||||
* @param ccreds client's initial credential
|
||||
*/
|
||||
public static Credentials acquireServiceCreds(
|
||||
String service, Credentials ccreds)
|
||||
throws KrbException, IOException {
|
||||
PrincipalName sname = new PrincipalName(service,
|
||||
PrincipalName.KRB_NT_UNKNOWN);
|
||||
return serviceCreds(sname, ccreds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a TGT to another realm
|
||||
* @param localRealm this realm
|
||||
* @param serviceRealm the other realm, cannot equals to localRealm
|
||||
* @param ccreds TGT in this realm
|
||||
* @param okAsDelegate an [out] argument to receive the okAsDelegate
|
||||
* property. True only if all realms allow delegation.
|
||||
* @return the TGT for the other realm, null if cannot find a path
|
||||
* @throws KrbException if something goes wrong
|
||||
*/
|
||||
private static Credentials getTGTforRealm(String localRealm,
|
||||
String serviceRealm, Credentials ccreds, boolean[] okAsDelegate)
|
||||
throws KrbException {
|
||||
|
||||
// Get a list of realms to traverse
|
||||
String[] realms = Realm.getRealmsList(localRealm, serviceRealm);
|
||||
|
||||
int i = 0, k = 0;
|
||||
Credentials cTgt = null, newTgt = null, theTgt = null;
|
||||
PrincipalName tempService = null;
|
||||
String newTgtRealm = null;
|
||||
|
||||
okAsDelegate[0] = true;
|
||||
for (cTgt = ccreds, i = 0; i < realms.length;) {
|
||||
tempService = PrincipalName.tgsService(serviceRealm, realms[i]);
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(
|
||||
">>> Credentials acquireServiceCreds: main loop: ["
|
||||
+ i +"] tempService=" + tempService);
|
||||
}
|
||||
|
||||
try {
|
||||
newTgt = serviceCreds(tempService, cTgt);
|
||||
} catch (Exception exc) {
|
||||
newTgt = null;
|
||||
}
|
||||
|
||||
if (newTgt == null) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Credentials acquireServiceCreds: "
|
||||
+ "no tgt; searching thru capath");
|
||||
}
|
||||
|
||||
/*
|
||||
* No tgt found. Let's go thru the realms list one by one.
|
||||
*/
|
||||
for (newTgt = null, k = i+1;
|
||||
newTgt == null && k < realms.length; k++) {
|
||||
tempService = PrincipalName.tgsService(realms[k], realms[i]);
|
||||
if (DEBUG) {
|
||||
System.out.println(
|
||||
">>> Credentials acquireServiceCreds: "
|
||||
+ "inner loop: [" + k
|
||||
+ "] tempService=" + tempService);
|
||||
}
|
||||
try {
|
||||
newTgt = serviceCreds(tempService, cTgt);
|
||||
} catch (Exception exc) {
|
||||
newTgt = null;
|
||||
}
|
||||
}
|
||||
} // Ends 'if (newTgt == null)'
|
||||
|
||||
if (newTgt == null) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Credentials acquireServiceCreds: "
|
||||
+ "no tgt; cannot get creds");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a tgt. It may or may not be for the target.
|
||||
* If it's for the target realm, we're done looking for a tgt.
|
||||
*/
|
||||
newTgtRealm = newTgt.getServer().getInstanceComponent();
|
||||
if (okAsDelegate[0] && !newTgt.checkDelegate()) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Credentials acquireServiceCreds: " +
|
||||
"global OK-AS-DELEGATE turned off at " +
|
||||
newTgt.getServer());
|
||||
}
|
||||
okAsDelegate[0] = false;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Credentials acquireServiceCreds: "
|
||||
+ "got tgt");
|
||||
}
|
||||
|
||||
if (newTgtRealm.equals(serviceRealm)) {
|
||||
/* We got the right tgt */
|
||||
theTgt = newTgt;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* The new tgt is not for the target realm.
|
||||
* See if the realm of the new tgt is in the list of realms
|
||||
* and continue looking from there.
|
||||
*/
|
||||
for (k = i+1; k < realms.length; k++) {
|
||||
if (newTgtRealm.equals(realms[k])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (k < realms.length) {
|
||||
/*
|
||||
* (re)set the counter so we start looking
|
||||
* from the realm we just obtained a tgt for.
|
||||
*/
|
||||
i = k;
|
||||
cTgt = newTgt;
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Credentials acquireServiceCreds: "
|
||||
+ "continuing with main loop counter reset to " + i);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* The new tgt's realm is not in the hierarchy of realms.
|
||||
* It's probably not safe to get a tgt from
|
||||
* a tgs that is outside the known list of realms.
|
||||
* Give up now.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
} // Ends outermost/main 'for' loop
|
||||
|
||||
return theTgt;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method does the real job to request the service credential.
|
||||
*/
|
||||
private static Credentials serviceCreds(
|
||||
PrincipalName service, Credentials ccreds)
|
||||
throws KrbException, IOException {
|
||||
return serviceCreds(new KDCOptions(), ccreds,
|
||||
ccreds.getClient(), service, null, null,
|
||||
null, S4U2Type.NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtains credentials for a service (TGS).
|
||||
* Cross-realm referrals are handled if enabled. A fallback scheme
|
||||
* without cross-realm referrals supports is used in case of server
|
||||
* error to maintain backward compatibility.
|
||||
*/
|
||||
private static Credentials serviceCreds(
|
||||
KDCOptions options, Credentials asCreds,
|
||||
PrincipalName cname, PrincipalName sname,
|
||||
PrincipalName user, Ticket[] additionalTickets,
|
||||
PAData[] extraPAs, S4U2Type s4u2Type)
|
||||
throws KrbException, IOException {
|
||||
if (!Config.DISABLE_REFERRALS) {
|
||||
try {
|
||||
return serviceCredsReferrals(options, asCreds, cname, sname,
|
||||
s4u2Type, user, additionalTickets, extraPAs);
|
||||
} catch (KrbException e) {
|
||||
// Server may raise an error if CANONICALIZE is true.
|
||||
// Try CANONICALIZE false.
|
||||
}
|
||||
}
|
||||
return serviceCredsSingle(options, asCreds, cname,
|
||||
asCreds.getClientAlias(), sname, sname, s4u2Type,
|
||||
user, additionalTickets, extraPAs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtains credentials for a service (TGS).
|
||||
* May handle and follow cross-realm referrals as defined by RFC 6806.
|
||||
*/
|
||||
private static Credentials serviceCredsReferrals(
|
||||
KDCOptions options, Credentials asCreds,
|
||||
PrincipalName cname, PrincipalName sname,
|
||||
S4U2Type s4u2Type, PrincipalName user,
|
||||
Ticket[] additionalTickets, PAData[] extraPAs)
|
||||
throws KrbException, IOException {
|
||||
options = new KDCOptions(options.toBooleanArray());
|
||||
options.set(KDCOptions.CANONICALIZE, true);
|
||||
PrincipalName cSname = sname;
|
||||
PrincipalName refSname = sname; // May change with referrals
|
||||
Credentials creds = null;
|
||||
boolean isReferral = false;
|
||||
List<String> referrals = new LinkedList<>();
|
||||
PrincipalName clientAlias = asCreds.getClientAlias();
|
||||
while (referrals.size() <= Config.MAX_REFERRALS) {
|
||||
ReferralsCache.ReferralCacheEntry ref =
|
||||
ReferralsCache.get(cname, sname, user,
|
||||
additionalTickets, refSname.getRealmString());
|
||||
String toRealm = null;
|
||||
if (ref == null) {
|
||||
creds = serviceCredsSingle(options, asCreds, cname,
|
||||
clientAlias, refSname, cSname, s4u2Type,
|
||||
user, additionalTickets, extraPAs);
|
||||
PrincipalName server = creds.getServer();
|
||||
if (!refSname.equals(server)) {
|
||||
String[] serverNameStrings = server.getNameStrings();
|
||||
if (serverNameStrings.length == 2 &&
|
||||
serverNameStrings[0].equals(
|
||||
PrincipalName.TGS_DEFAULT_SRV_NAME) &&
|
||||
!refSname.getRealmAsString().equals(
|
||||
serverNameStrings[1])) {
|
||||
// Server Name (sname) has the following format:
|
||||
// krbtgt/TO-REALM.COM@FROM-REALM.COM
|
||||
ReferralsCache.put(cname, sname, user,
|
||||
additionalTickets, server.getRealmString(),
|
||||
serverNameStrings[1], creds);
|
||||
toRealm = serverNameStrings[1];
|
||||
isReferral = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
creds = ref.getCreds();
|
||||
toRealm = ref.getToRealm();
|
||||
isReferral = true;
|
||||
}
|
||||
if (isReferral) {
|
||||
if (s4u2Type == S4U2Type.PROXY) {
|
||||
Credentials[] credsInOut =
|
||||
new Credentials[] {creds, null};
|
||||
toRealm = handleS4U2ProxyReferral(asCreds,
|
||||
credsInOut, sname);
|
||||
creds = credsInOut[0];
|
||||
if (additionalTickets == null ||
|
||||
additionalTickets.length == 0 ||
|
||||
credsInOut[1] == null) {
|
||||
throw new KrbException("Additional tickets expected" +
|
||||
" for S4U2Proxy.");
|
||||
}
|
||||
additionalTickets[0] = credsInOut[1].getTicket();
|
||||
} else if (s4u2Type == S4U2Type.SELF) {
|
||||
handleS4U2SelfReferral(extraPAs, user, creds);
|
||||
}
|
||||
if (referrals.contains(toRealm)) {
|
||||
// Referrals loop detected
|
||||
return null;
|
||||
}
|
||||
asCreds = creds;
|
||||
refSname = new PrincipalName(refSname.getNameString(),
|
||||
refSname.getNameType(), toRealm);
|
||||
referrals.add(toRealm);
|
||||
isReferral = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return creds;
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtains credentials for a service (TGS).
|
||||
* If the service realm is different than the one in the TGT, a new TGT for
|
||||
* the service realm is obtained first (see getTGTforRealm call). This is
|
||||
* not expected when following cross-realm referrals because the referral
|
||||
* TGT realm matches the service realm.
|
||||
*/
|
||||
private static Credentials serviceCredsSingle(
|
||||
KDCOptions options, Credentials asCreds,
|
||||
PrincipalName cname, PrincipalName clientAlias,
|
||||
PrincipalName refSname, PrincipalName sname,
|
||||
S4U2Type s4u2Type, PrincipalName user,
|
||||
Ticket[] additionalTickets, PAData[] extraPAs)
|
||||
throws KrbException, IOException {
|
||||
Credentials theCreds = null;
|
||||
boolean[] okAsDelegate = new boolean[]{true};
|
||||
String[] serverAsCredsNames = asCreds.getServer().getNameStrings();
|
||||
String tgtRealm = serverAsCredsNames[1];
|
||||
String serviceRealm = refSname.getRealmString();
|
||||
if (!serviceRealm.equals(tgtRealm)) {
|
||||
// This is a cross-realm service request
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> serviceCredsSingle:" +
|
||||
" cross-realm authentication");
|
||||
System.out.println(">>> serviceCredsSingle:" +
|
||||
" obtaining credentials from " + tgtRealm +
|
||||
" to " + serviceRealm);
|
||||
}
|
||||
Credentials newTgt = getTGTforRealm(tgtRealm, serviceRealm,
|
||||
asCreds, okAsDelegate);
|
||||
if (newTgt == null) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
|
||||
"No service creds");
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Cross-realm TGT Credentials" +
|
||||
" serviceCredsSingle: ");
|
||||
Credentials.printDebug(newTgt);
|
||||
}
|
||||
if (s4u2Type == S4U2Type.SELF) {
|
||||
handleS4U2SelfReferral(extraPAs, user, newTgt);
|
||||
}
|
||||
asCreds = newTgt;
|
||||
cname = asCreds.getClient();
|
||||
} else if (DEBUG) {
|
||||
System.out.println(">>> Credentials serviceCredsSingle:" +
|
||||
" same realm");
|
||||
}
|
||||
KrbTgsReq req = new KrbTgsReq(options, asCreds, cname, clientAlias,
|
||||
refSname, sname, additionalTickets, extraPAs);
|
||||
theCreds = req.sendAndGetCreds();
|
||||
if (theCreds != null) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> TGS credentials serviceCredsSingle:");
|
||||
Credentials.printDebug(theCreds);
|
||||
}
|
||||
if (!okAsDelegate[0]) {
|
||||
theCreds.resetDelegate();
|
||||
}
|
||||
}
|
||||
return theCreds;
|
||||
}
|
||||
|
||||
/**
|
||||
* PA-FOR-USER may need to be regenerated if credentials
|
||||
* change. This may happen when obtaining a TGT for a
|
||||
* different realm or when using a referral TGT.
|
||||
*/
|
||||
private static void handleS4U2SelfReferral(PAData[] pas,
|
||||
PrincipalName user, Credentials newCreds)
|
||||
throws Asn1Exception, KrbException, IOException {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Handling S4U2Self referral");
|
||||
}
|
||||
for (int i = 0; i < pas.length; i++) {
|
||||
PAData pa = pas[i];
|
||||
if (pa.getType() == Krb5.PA_FOR_USER) {
|
||||
pas[i] = new PAData(Krb5.PA_FOR_USER,
|
||||
new PAForUserEnc(user,
|
||||
newCreds.getSessionKey()).asn1Encode());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called after receiving the first realm referral for
|
||||
* a S4U2Proxy request. The credentials and tickets needed for the
|
||||
* final S4U2Proxy request (in the referrals chain) are returned.
|
||||
*
|
||||
* Referrals are handled as described by MS-SFU (section 3.1.5.2.2
|
||||
* Receives Referral).
|
||||
*
|
||||
* @param asCreds middle service credentials used for the first S4U2Proxy
|
||||
* request
|
||||
* @param credsInOut (in/out parameter):
|
||||
* * input: first S4U2Proxy referral TGT received, null
|
||||
* * output: referral TGT for final S4U2Proxy service request,
|
||||
* client referral TGT for final S4U2Proxy service request
|
||||
* (to be sent as additional-ticket)
|
||||
* @param sname the backend service name
|
||||
* @param additionalTickets (out parameter): the additional ticket for the
|
||||
* last S4U2Proxy request is returned
|
||||
* @return the backend realm for the last S4U2Proxy request
|
||||
*/
|
||||
private static String handleS4U2ProxyReferral(Credentials asCreds,
|
||||
Credentials[] credsInOut, PrincipalName sname)
|
||||
throws KrbException, IOException {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> Handling S4U2Proxy referral");
|
||||
}
|
||||
Credentials refTGT = null;
|
||||
// Get a credential for the middle service to the backend so we know
|
||||
// the backend realm, as described in MS-SFU (section 3.1.5.2.2).
|
||||
Credentials middleSvcCredsInBackendRealm =
|
||||
serviceCreds(sname, asCreds);
|
||||
String backendRealm =
|
||||
middleSvcCredsInBackendRealm.getServer().getRealmString();
|
||||
String toRealm = credsInOut[0].getServer().getNameStrings()[1];
|
||||
if (!toRealm.equals(backendRealm)) {
|
||||
// More than 1 hop. Follow the referrals chain and obtain a
|
||||
// TGT for the backend realm.
|
||||
refTGT = getTGTforRealm(toRealm, backendRealm, credsInOut[0],
|
||||
new boolean[1]);
|
||||
} else {
|
||||
// There was only 1 hop. The referral TGT received is already
|
||||
// for the backend realm.
|
||||
refTGT = credsInOut[0];
|
||||
}
|
||||
credsInOut[0] = getTGTforRealm(asCreds.getClient().getRealmString(),
|
||||
backendRealm, asCreds, new boolean[1]);
|
||||
credsInOut[1] = refTGT;
|
||||
return backendRealm;
|
||||
}
|
||||
}
|
||||
154
jdkSrc/jdk8/sun/security/krb5/internal/ETypeInfo.java
Normal file
154
jdkSrc/jdk8/sun/security/krb5/internal/ETypeInfo.java
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2009, 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 sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.io.IOException;
|
||||
import sun.security.krb5.internal.util.KerberosString;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 ETYPE-INFO-ENTRY type.
|
||||
*
|
||||
* ETYPE-INFO-ENTRY ::= SEQUENCE {
|
||||
* etype [0] Int32,
|
||||
* salt [1] OCTET STRING OPTIONAL
|
||||
* }
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class ETypeInfo {
|
||||
|
||||
private int etype;
|
||||
private String salt = null;
|
||||
|
||||
private static final byte TAG_TYPE = 0;
|
||||
private static final byte TAG_VALUE = 1;
|
||||
|
||||
private ETypeInfo() {
|
||||
}
|
||||
|
||||
public ETypeInfo(int etype, String salt) {
|
||||
this.etype = etype;
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new ETypeInfo(etype, salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ETypeInfo object.
|
||||
* @param encoding a DER-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an
|
||||
* ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public ETypeInfo(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der = null;
|
||||
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
// etype
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x00) {
|
||||
this.etype = der.getData().getBigInteger().intValue();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
|
||||
// salt
|
||||
if (encoding.getData().available() > 0) {
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x01) {
|
||||
byte[] saltBytes = der.getData().getOctetString();
|
||||
|
||||
// Although salt is defined as an OCTET STRING, it's the
|
||||
// encoding from of a string. As RFC 4120 says:
|
||||
//
|
||||
// "The salt, ..., is also completely unspecified with respect
|
||||
// to character set and is probably locale-specific".
|
||||
//
|
||||
// It's known that this field is using the same encoding as
|
||||
// KerberosString in most implementations.
|
||||
|
||||
if (KerberosString.MSNAME) {
|
||||
this.salt = new String(saltBytes, "UTF8");
|
||||
} else {
|
||||
this.salt = new String(saltBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this object to an OutputStream.
|
||||
*
|
||||
* @return byte array of the encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception Asn1Exception on encoding errors.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
|
||||
temp.putInteger(etype);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
TAG_TYPE), temp);
|
||||
|
||||
if (salt != null) {
|
||||
temp = new DerOutputStream();
|
||||
if (KerberosString.MSNAME) {
|
||||
temp.putOctetString(salt.getBytes("UTF8"));
|
||||
} else {
|
||||
temp.putOctetString(salt.getBytes());
|
||||
}
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
TAG_VALUE), temp);
|
||||
}
|
||||
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
// accessor methods
|
||||
public int getEType() {
|
||||
return etype;
|
||||
}
|
||||
|
||||
public String getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
}
|
||||
168
jdkSrc/jdk8/sun/security/krb5/internal/ETypeInfo2.java
Normal file
168
jdkSrc/jdk8/sun/security/krb5/internal/ETypeInfo2.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2009, 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 sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.io.IOException;
|
||||
import sun.security.krb5.internal.util.KerberosString;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 ETYPE-INFO-ENTRY type.
|
||||
*
|
||||
* ETYPE-INFO2-ENTRY ::= SEQUENCE {
|
||||
* etype [0] Int32,
|
||||
* salt [1] KerberosString OPTIONAL,
|
||||
* s2kparams [2] OCTET STRING OPTIONAL
|
||||
* }
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class ETypeInfo2 {
|
||||
|
||||
private int etype;
|
||||
private String saltStr = null;
|
||||
private byte[] s2kparams = null;
|
||||
|
||||
private static final byte TAG_TYPE = 0;
|
||||
private static final byte TAG_VALUE1 = 1;
|
||||
private static final byte TAG_VALUE2 = 2;
|
||||
|
||||
private ETypeInfo2() {
|
||||
}
|
||||
|
||||
public ETypeInfo2(int etype, String salt, byte[] s2kparams) {
|
||||
this.etype = etype;
|
||||
this.saltStr = salt;
|
||||
if (s2kparams != null) {
|
||||
this.s2kparams = s2kparams.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
ETypeInfo2 etypeInfo2 = new ETypeInfo2();
|
||||
etypeInfo2.etype = etype;
|
||||
etypeInfo2.saltStr = saltStr;
|
||||
if (s2kparams != null) {
|
||||
etypeInfo2.s2kparams = new byte[s2kparams.length];
|
||||
System.arraycopy(s2kparams, 0, etypeInfo2.s2kparams,
|
||||
0, s2kparams.length);
|
||||
}
|
||||
return etypeInfo2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ETypeInfo2 object.
|
||||
* @param encoding a DER-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an
|
||||
* ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public ETypeInfo2(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der = null;
|
||||
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
// etype
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x00) {
|
||||
this.etype = der.getData().getBigInteger().intValue();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
|
||||
// salt
|
||||
if (encoding.getData().available() > 0) {
|
||||
if ((encoding.getData().peekByte() & 0x1F) == 0x01) {
|
||||
der = encoding.getData().getDerValue();
|
||||
this.saltStr = new KerberosString(
|
||||
der.getData().getDerValue()).toString();
|
||||
}
|
||||
}
|
||||
|
||||
// s2kparams
|
||||
if (encoding.getData().available() > 0) {
|
||||
if ((encoding.getData().peekByte() & 0x1F) == 0x02) {
|
||||
der = encoding.getData().getDerValue();
|
||||
this.s2kparams = der.getData().getOctetString();
|
||||
}
|
||||
}
|
||||
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this object to an OutputStream.
|
||||
*
|
||||
* @return byte array of the encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception Asn1Exception on encoding errors.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
|
||||
temp.putInteger(etype);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
TAG_TYPE), temp);
|
||||
|
||||
if (saltStr != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putDerValue(new KerberosString(saltStr).toDerValue());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
TAG_VALUE1), temp);
|
||||
}
|
||||
if (s2kparams != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putOctetString(s2kparams);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
TAG_VALUE2), temp);
|
||||
}
|
||||
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
// accessor methods
|
||||
public int getEType() {
|
||||
return etype;
|
||||
}
|
||||
|
||||
public String getSalt() {
|
||||
return saltStr;
|
||||
}
|
||||
|
||||
public byte[] getParams() {
|
||||
return ((s2kparams == null) ? null : s2kparams.clone());
|
||||
}
|
||||
|
||||
}
|
||||
171
jdkSrc/jdk8/sun/security/krb5/internal/EncAPRepPart.java
Normal file
171
jdkSrc/jdk8/sun/security/krb5/internal/EncAPRepPart.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 EncAPRepPart type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
|
||||
* ctime [0] KerberosTime,
|
||||
* cusec [1] Microseconds,
|
||||
* subkey [2] EncryptionKey OPTIONAL,
|
||||
* seq-number [3] UInt32 OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class EncAPRepPart {
|
||||
|
||||
public KerberosTime ctime;
|
||||
public int cusec;
|
||||
EncryptionKey subKey; //optional
|
||||
Integer seqNumber; //optional
|
||||
|
||||
public EncAPRepPart(
|
||||
KerberosTime new_ctime,
|
||||
int new_cusec,
|
||||
EncryptionKey new_subKey,
|
||||
Integer new_seqNumber) {
|
||||
ctime = new_ctime;
|
||||
cusec = new_cusec;
|
||||
subKey = new_subKey;
|
||||
seqNumber = new_seqNumber;
|
||||
}
|
||||
|
||||
public EncAPRepPart(byte[] data)
|
||||
throws Asn1Exception, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public EncAPRepPart(DerValue encoding)
|
||||
throws Asn1Exception, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an EncaPRepPart object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
private void init(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der, subDer;
|
||||
if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1B)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
ctime = KerberosTime.parse(der.getData(), (byte) 0x00, true);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x01) {
|
||||
cusec = subDer.getData().getBigInteger().intValue();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
subKey = EncryptionKey.parse(der.getData(), (byte) 0x02, true);
|
||||
} else {
|
||||
subKey = null;
|
||||
seqNumber = null;
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) != 0x03) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
seqNumber = new Integer(subDer.getData().getBigInteger().intValue());
|
||||
} else {
|
||||
seqNumber = null;
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an EncAPRepPart object.
|
||||
* @return byte array of encoded EncAPRepPart object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
Vector<DerValue> v = new Vector<>();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x00), ctime.asn1Encode()));
|
||||
temp.putInteger(BigInteger.valueOf(cusec));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x01), temp.toByteArray()));
|
||||
if (subKey != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x02), subKey.asn1Encode()));
|
||||
}
|
||||
if (seqNumber != null) {
|
||||
temp = new DerOutputStream();
|
||||
// encode as an unsigned integer (UInt32)
|
||||
temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x03), temp.toByteArray()));
|
||||
}
|
||||
DerValue der[] = new DerValue[v.size()];
|
||||
v.copyInto(der);
|
||||
temp = new DerOutputStream();
|
||||
temp.putSequence(der);
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.write(DerValue.createTag(DerValue.TAG_APPLICATION,
|
||||
true, (byte) 0x1B), temp);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public final EncryptionKey getSubKey() {
|
||||
return subKey;
|
||||
}
|
||||
|
||||
public final Integer getSeqNumber() {
|
||||
return seqNumber;
|
||||
}
|
||||
}
|
||||
90
jdkSrc/jdk8/sun/security/krb5/internal/EncASRepPart.java
Normal file
90
jdkSrc/jdk8/sun/security/krb5/internal/EncASRepPart.java
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class EncASRepPart extends EncKDCRepPart {
|
||||
|
||||
public EncASRepPart(
|
||||
EncryptionKey new_key,
|
||||
LastReq new_lastReq,
|
||||
int new_nonce,
|
||||
KerberosTime new_keyExpiration,
|
||||
TicketFlags new_flags,
|
||||
KerberosTime new_authtime,
|
||||
KerberosTime new_starttime,
|
||||
KerberosTime new_endtime,
|
||||
KerberosTime new_renewTill,
|
||||
PrincipalName new_sname,
|
||||
HostAddresses new_caddr,
|
||||
PAData[] new_pAData) {
|
||||
super(
|
||||
new_key,
|
||||
new_lastReq,
|
||||
new_nonce,
|
||||
new_keyExpiration,
|
||||
new_flags,
|
||||
new_authtime,
|
||||
new_starttime,
|
||||
new_endtime,
|
||||
new_renewTill,
|
||||
new_sname,
|
||||
new_caddr,
|
||||
new_pAData,
|
||||
Krb5.KRB_ENC_AS_REP_PART
|
||||
);
|
||||
//may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic
|
||||
//behavior of other implementaions, instead of above
|
||||
}
|
||||
|
||||
public EncASRepPart(byte[] data) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public EncASRepPart(DerValue encoding) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(encoding, Krb5.KRB_ENC_AS_REP_PART);
|
||||
}
|
||||
|
||||
public byte[] asn1Encode() throws Asn1Exception,
|
||||
IOException {
|
||||
return asn1Encode(Krb5.KRB_ENC_AS_REP_PART);
|
||||
}
|
||||
}
|
||||
241
jdkSrc/jdk8/sun/security/krb5/internal/EncKDCRepPart.java
Normal file
241
jdkSrc/jdk8/sun/security/krb5/internal/EncKDCRepPart.java
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 EncKDCRepPart type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* EncKDCRepPart ::= SEQUENCE {
|
||||
* key [0] EncryptionKey,
|
||||
* last-req [1] LastReq,
|
||||
* nonce [2] UInt32,
|
||||
* key-expiration [3] KerberosTime OPTIONAL,
|
||||
* flags [4] TicketFlags,
|
||||
* authtime [5] KerberosTime,
|
||||
* starttime [6] KerberosTime OPTIONAL,
|
||||
* endtime [7] KerberosTime,
|
||||
* renew-till [8] KerberosTime OPTIONAL,
|
||||
* srealm [9] Realm,
|
||||
* sname [10] PrincipalName,
|
||||
* caddr [11] HostAddresses OPTIONAL,
|
||||
* encrypted-pa-data [12] SEQUENCE OF PA-DATA OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class EncKDCRepPart {
|
||||
|
||||
public EncryptionKey key;
|
||||
public LastReq lastReq;
|
||||
public int nonce;
|
||||
public KerberosTime keyExpiration; //optional
|
||||
public TicketFlags flags;
|
||||
public KerberosTime authtime;
|
||||
public KerberosTime starttime; //optional
|
||||
public KerberosTime endtime;
|
||||
public KerberosTime renewTill; //optional
|
||||
public PrincipalName sname;
|
||||
public HostAddresses caddr; //optional
|
||||
public PAData[] pAData; //optional
|
||||
public int msgType; //not included in sequence
|
||||
|
||||
public EncKDCRepPart(
|
||||
EncryptionKey new_key,
|
||||
LastReq new_lastReq,
|
||||
int new_nonce,
|
||||
KerberosTime new_keyExpiration,
|
||||
TicketFlags new_flags,
|
||||
KerberosTime new_authtime,
|
||||
KerberosTime new_starttime,
|
||||
KerberosTime new_endtime,
|
||||
KerberosTime new_renewTill,
|
||||
PrincipalName new_sname,
|
||||
HostAddresses new_caddr,
|
||||
PAData[] new_pAData,
|
||||
int new_msgType) {
|
||||
key = new_key;
|
||||
lastReq = new_lastReq;
|
||||
nonce = new_nonce;
|
||||
keyExpiration = new_keyExpiration;
|
||||
flags = new_flags;
|
||||
authtime = new_authtime;
|
||||
starttime = new_starttime;
|
||||
endtime = new_endtime;
|
||||
renewTill = new_renewTill;
|
||||
sname = new_sname;
|
||||
caddr = new_caddr;
|
||||
pAData = new_pAData;
|
||||
msgType = new_msgType;
|
||||
}
|
||||
|
||||
public EncKDCRepPart() {
|
||||
}
|
||||
|
||||
public EncKDCRepPart(byte[] data, int rep_type)
|
||||
throws Asn1Exception, IOException, RealmException {
|
||||
init(new DerValue(data), rep_type);
|
||||
}
|
||||
|
||||
public EncKDCRepPart(DerValue encoding, int rep_type)
|
||||
throws Asn1Exception, IOException, RealmException {
|
||||
init(encoding, rep_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an EncKDCRepPart object.
|
||||
*
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @param rep_type type of the encrypted reply message.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception RealmException if an error occurs while decoding an Realm object.
|
||||
*/
|
||||
protected void init(DerValue encoding, int rep_type)
|
||||
throws Asn1Exception, IOException, RealmException {
|
||||
DerValue der, subDer;
|
||||
//implementations return the incorrect tag value, so
|
||||
//we don't use the above line; instead we use the following
|
||||
msgType = (encoding.getTag() & (byte) 0x1F);
|
||||
if (msgType != Krb5.KRB_ENC_AS_REP_PART &&
|
||||
msgType != Krb5.KRB_ENC_TGS_REP_PART) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
key = EncryptionKey.parse(der.getData(), (byte) 0x00, false);
|
||||
lastReq = LastReq.parse(der.getData(), (byte) 0x01, false);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x02) {
|
||||
nonce = subDer.getData().getBigInteger().intValue();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
keyExpiration = KerberosTime.parse(der.getData(), (byte) 0x03, true);
|
||||
flags = TicketFlags.parse(der.getData(), (byte) 0x04, false);
|
||||
authtime = KerberosTime.parse(der.getData(), (byte) 0x05, false);
|
||||
starttime = KerberosTime.parse(der.getData(), (byte) 0x06, true);
|
||||
endtime = KerberosTime.parse(der.getData(), (byte) 0x07, false);
|
||||
renewTill = KerberosTime.parse(der.getData(), (byte) 0x08, true);
|
||||
Realm srealm = Realm.parse(der.getData(), (byte) 0x09, false);
|
||||
sname = PrincipalName.parse(der.getData(), (byte) 0x0A, false, srealm);
|
||||
if (der.getData().available() > 0) {
|
||||
caddr = HostAddresses.parse(der.getData(), (byte) 0x0B, true);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
pAData = PAData.parseSequence(der.getData(), (byte) 0x0C, true);
|
||||
}
|
||||
// We observe extra data from MSAD
|
||||
/*if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an EncKDCRepPart object.
|
||||
* @param rep_type type of encrypted reply message.
|
||||
* @return byte array of encoded EncKDCRepPart object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode(int rep_type) throws Asn1Exception,
|
||||
IOException {
|
||||
DerOutputStream bytes;
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x00), key.asn1Encode());
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x01), lastReq.asn1Encode());
|
||||
temp.putInteger(BigInteger.valueOf(nonce));
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x02), temp);
|
||||
|
||||
if (keyExpiration != null) {
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x03), keyExpiration.asn1Encode());
|
||||
}
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x04), flags.asn1Encode());
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x05), authtime.asn1Encode());
|
||||
if (starttime != null) {
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x06), starttime.asn1Encode());
|
||||
}
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x07), endtime.asn1Encode());
|
||||
if (renewTill != null) {
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x08), renewTill.asn1Encode());
|
||||
}
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x09), sname.getRealm().asn1Encode());
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x0A), sname.asn1Encode());
|
||||
if (caddr != null) {
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x0B), caddr.asn1Encode());
|
||||
}
|
||||
if (pAData != null && pAData.length > 0) {
|
||||
temp = new DerOutputStream();
|
||||
for (int i = 0; i < pAData.length; i++) {
|
||||
temp.write(pAData[i].asn1Encode());
|
||||
}
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.tag_SequenceOf, temp);
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x0C), bytes);
|
||||
}
|
||||
//should use the rep_type to build the encoding
|
||||
//but other implementations do not; it is ignored and
|
||||
//the cached msgType is used instead
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, out);
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
|
||||
true, (byte) msgType), temp);
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
}
|
||||
215
jdkSrc/jdk8/sun/security/krb5/internal/EncKrbCredPart.java
Normal file
215
jdkSrc/jdk8/sun/security/krb5/internal/EncKrbCredPart.java
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.RealmException;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 EncKrbCredPart type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
|
||||
* ticket-info [0] SEQUENCE OF KrbCredInfo,
|
||||
* nonce [1] UInt32 OPTIONAL,
|
||||
* timestamp [2] KerberosTime OPTIONAL,
|
||||
* usec [3] Microseconds OPTIONAL,
|
||||
* s-address [4] HostAddress OPTIONAL,
|
||||
* r-address [5] HostAddress OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class EncKrbCredPart {
|
||||
|
||||
public KrbCredInfo[] ticketInfo = null;
|
||||
public KerberosTime timeStamp; //optional
|
||||
private Integer nonce; //optional
|
||||
private Integer usec; //optional
|
||||
private HostAddress sAddress; //optional
|
||||
private HostAddresses rAddress; //optional
|
||||
|
||||
public EncKrbCredPart(
|
||||
KrbCredInfo[] new_ticketInfo,
|
||||
KerberosTime new_timeStamp,
|
||||
Integer new_usec,
|
||||
Integer new_nonce,
|
||||
HostAddress new_sAddress,
|
||||
HostAddresses new_rAddress) throws IOException {
|
||||
if (new_ticketInfo != null) {
|
||||
ticketInfo = new KrbCredInfo[new_ticketInfo.length];
|
||||
for (int i = 0; i < new_ticketInfo.length; i++) {
|
||||
if (new_ticketInfo[i] == null) {
|
||||
throw new IOException("Cannot create a EncKrbCredPart");
|
||||
} else {
|
||||
ticketInfo[i] = (KrbCredInfo) new_ticketInfo[i].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
timeStamp = new_timeStamp;
|
||||
usec = new_usec;
|
||||
nonce = new_nonce;
|
||||
sAddress = new_sAddress;
|
||||
rAddress = new_rAddress;
|
||||
}
|
||||
|
||||
public EncKrbCredPart(byte[] data) throws Asn1Exception,
|
||||
IOException, RealmException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public EncKrbCredPart(DerValue encoding) throws Asn1Exception,
|
||||
IOException, RealmException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an EncKrbCredPart object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
*/
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
IOException, RealmException {
|
||||
DerValue der, subDer;
|
||||
//may not be the correct error code for a tag
|
||||
//mismatch on an encrypted structure
|
||||
nonce = null;
|
||||
timeStamp = null;
|
||||
usec = null;
|
||||
sAddress = null;
|
||||
rAddress = null;
|
||||
if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1D)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x00) {
|
||||
DerValue derValues[] = subDer.getData().getSequence(1);
|
||||
ticketInfo = new KrbCredInfo[derValues.length];
|
||||
for (int i = 0; i < derValues.length; i++) {
|
||||
ticketInfo[i] = new KrbCredInfo(derValues[i]);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x01) {
|
||||
subDer = der.getData().getDerValue();
|
||||
nonce = new Integer(subDer.getData().getBigInteger().intValue());
|
||||
}
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
timeStamp = KerberosTime.parse(der.getData(), (byte) 0x02, true);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x03) {
|
||||
subDer = der.getData().getDerValue();
|
||||
usec = new Integer(subDer.getData().getBigInteger().intValue());
|
||||
}
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
sAddress = HostAddress.parse(der.getData(), (byte) 0x04, true);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
rAddress = HostAddresses.parse(der.getData(), (byte) 0x05, true);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an EncKrbCredPart object.
|
||||
* @return byte array of encoded EncKrbCredPart object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
DerValue[] tickets = new DerValue[ticketInfo.length];
|
||||
for (int i = 0; i < ticketInfo.length; i++) {
|
||||
tickets[i] = new DerValue(ticketInfo[i].asn1Encode());
|
||||
}
|
||||
temp.putSequence(tickets);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x00), temp);
|
||||
|
||||
if (nonce != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(nonce.intValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x01), temp);
|
||||
}
|
||||
if (timeStamp != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x02), timeStamp.asn1Encode());
|
||||
}
|
||||
if (usec != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(usec.intValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x03), temp);
|
||||
}
|
||||
if (sAddress != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x04), sAddress.asn1Encode());
|
||||
}
|
||||
if (rAddress != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x05), rAddress.asn1Encode());
|
||||
}
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
|
||||
true, (byte) 0x1D), temp);
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
}
|
||||
173
jdkSrc/jdk8/sun/security/krb5/internal/EncKrbPrivPart.java
Normal file
173
jdkSrc/jdk8/sun/security/krb5/internal/EncKrbPrivPart.java
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 EncKrbPrivPart type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
|
||||
* user-data [0] OCTET STRING,
|
||||
* timestamp [1] KerberosTime OPTIONAL,
|
||||
* usec [2] Microseconds OPTIONAL,
|
||||
* seq-number [3] UInt32 OPTIONAL,
|
||||
* s-address [4] HostAddress -- sender's addr --,
|
||||
* r-address [5] HostAddress OPTIONAL -- recip's addr
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class EncKrbPrivPart {
|
||||
|
||||
public byte[] userData = null;
|
||||
public KerberosTime timestamp; //optional
|
||||
public Integer usec; //optional
|
||||
public Integer seqNumber; //optional
|
||||
public HostAddress sAddress; //optional
|
||||
public HostAddress rAddress; //optional
|
||||
|
||||
public EncKrbPrivPart(
|
||||
byte[] new_userData,
|
||||
KerberosTime new_timestamp,
|
||||
Integer new_usec,
|
||||
Integer new_seqNumber,
|
||||
HostAddress new_sAddress,
|
||||
HostAddress new_rAddress) {
|
||||
if (new_userData != null) {
|
||||
userData = new_userData.clone();
|
||||
}
|
||||
timestamp = new_timestamp;
|
||||
usec = new_usec;
|
||||
seqNumber = new_seqNumber;
|
||||
sAddress = new_sAddress;
|
||||
rAddress = new_rAddress;
|
||||
}
|
||||
|
||||
public EncKrbPrivPart(byte[] data) throws Asn1Exception, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public EncKrbPrivPart(DerValue encoding) throws Asn1Exception, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an EncKrbPrivPart object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
private void init(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der, subDer;
|
||||
if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1C)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x00) {
|
||||
userData = subDer.getData().getOctetString();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
timestamp = KerberosTime.parse(der.getData(), (byte) 0x01, true);
|
||||
if ((der.getData().peekByte() & 0x1F) == 0x02) {
|
||||
subDer = der.getData().getDerValue();
|
||||
usec = new Integer(subDer.getData().getBigInteger().intValue());
|
||||
} else {
|
||||
usec = null;
|
||||
}
|
||||
if ((der.getData().peekByte() & 0x1F) == 0x03) {
|
||||
subDer = der.getData().getDerValue();
|
||||
seqNumber = new Integer(subDer.getData().getBigInteger().intValue());
|
||||
} else {
|
||||
seqNumber = null;
|
||||
}
|
||||
sAddress = HostAddress.parse(der.getData(), (byte) 0x04, false);
|
||||
if (der.getData().available() > 0) {
|
||||
rAddress = HostAddress.parse(der.getData(), (byte) 0x05, true);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an EncKrbPrivPart object.
|
||||
* @return byte array of encoded EncKrbPrivPart object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
|
||||
temp.putOctetString(userData);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp);
|
||||
if (timestamp != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), timestamp.asn1Encode());
|
||||
}
|
||||
if (usec != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(usec.intValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), temp);
|
||||
}
|
||||
if (seqNumber != null) {
|
||||
temp = new DerOutputStream();
|
||||
// encode as an unsigned integer (UInt32)
|
||||
temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), temp);
|
||||
}
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), sAddress.asn1Encode());
|
||||
if (rAddress != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x05), rAddress.asn1Encode());
|
||||
}
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x1C), temp);
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
}
|
||||
86
jdkSrc/jdk8/sun/security/krb5/internal/EncTGSRepPart.java
Normal file
86
jdkSrc/jdk8/sun/security/krb5/internal/EncTGSRepPart.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class EncTGSRepPart extends EncKDCRepPart {
|
||||
|
||||
public EncTGSRepPart(
|
||||
EncryptionKey new_key,
|
||||
LastReq new_lastReq,
|
||||
int new_nonce,
|
||||
KerberosTime new_keyExpiration,
|
||||
TicketFlags new_flags,
|
||||
KerberosTime new_authtime,
|
||||
KerberosTime new_starttime,
|
||||
KerberosTime new_endtime,
|
||||
KerberosTime new_renewTill,
|
||||
PrincipalName new_sname,
|
||||
HostAddresses new_caddr,
|
||||
PAData[] new_pAData) {
|
||||
super(
|
||||
new_key,
|
||||
new_lastReq,
|
||||
new_nonce,
|
||||
new_keyExpiration,
|
||||
new_flags,
|
||||
new_authtime,
|
||||
new_starttime,
|
||||
new_endtime,
|
||||
new_renewTill,
|
||||
new_sname,
|
||||
new_caddr,
|
||||
new_pAData,
|
||||
Krb5.KRB_ENC_TGS_REP_PART);
|
||||
}
|
||||
|
||||
public EncTGSRepPart(byte[] data) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public EncTGSRepPart(DerValue encoding) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(encoding, Krb5.KRB_ENC_TGS_REP_PART);
|
||||
}
|
||||
|
||||
public byte[] asn1Encode() throws Asn1Exception,
|
||||
IOException {
|
||||
return asn1Encode(Krb5.KRB_ENC_TGS_REP_PART);
|
||||
}
|
||||
}
|
||||
220
jdkSrc/jdk8/sun/security/krb5/internal/EncTicketPart.java
Normal file
220
jdkSrc/jdk8/sun/security/krb5/internal/EncTicketPart.java
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 EncTicketPart type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* EncTicketPart ::= [APPLICATION 3] SEQUENCE {
|
||||
* flags [0] TicketFlags,
|
||||
* key [1] EncryptionKey,
|
||||
* crealm [2] Realm,
|
||||
* cname [3] PrincipalName,
|
||||
* transited [4] TransitedEncoding,
|
||||
* authtime [5] KerberosTime,
|
||||
* starttime [6] KerberosTime OPTIONAL,
|
||||
* endtime [7] KerberosTime,
|
||||
* renew-till [8] KerberosTime OPTIONAL,
|
||||
* caddr [9] HostAddresses OPTIONAL,
|
||||
* authorization-data [10] AuthorizationData OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class EncTicketPart {
|
||||
|
||||
public TicketFlags flags;
|
||||
public EncryptionKey key;
|
||||
public PrincipalName cname;
|
||||
public TransitedEncoding transited;
|
||||
public KerberosTime authtime;
|
||||
public KerberosTime starttime; //optional
|
||||
public KerberosTime endtime;
|
||||
public KerberosTime renewTill; //optional
|
||||
public HostAddresses caddr; //optional
|
||||
public AuthorizationData authorizationData; //optional
|
||||
|
||||
public EncTicketPart(
|
||||
TicketFlags new_flags,
|
||||
EncryptionKey new_key,
|
||||
PrincipalName new_cname,
|
||||
TransitedEncoding new_transited,
|
||||
KerberosTime new_authtime,
|
||||
KerberosTime new_starttime,
|
||||
KerberosTime new_endtime,
|
||||
KerberosTime new_renewTill,
|
||||
HostAddresses new_caddr,
|
||||
AuthorizationData new_authorizationData) {
|
||||
flags = new_flags;
|
||||
key = new_key;
|
||||
cname = new_cname;
|
||||
transited = new_transited;
|
||||
authtime = new_authtime;
|
||||
starttime = new_starttime;
|
||||
endtime = new_endtime;
|
||||
renewTill = new_renewTill;
|
||||
caddr = new_caddr;
|
||||
authorizationData = new_authorizationData;
|
||||
}
|
||||
|
||||
public EncTicketPart(byte[] data)
|
||||
throws Asn1Exception, KrbException, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public EncTicketPart(DerValue encoding)
|
||||
throws Asn1Exception, KrbException, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an EncTicketPart object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
*/
|
||||
private static String getHexBytes(byte[] bytes, int len)
|
||||
throws IOException {
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < len; i++) {
|
||||
|
||||
int b1 = (bytes[i] >> 4) & 0x0f;
|
||||
int b2 = bytes[i] & 0x0f;
|
||||
|
||||
sb.append(Integer.toHexString(b1));
|
||||
sb.append(Integer.toHexString(b2));
|
||||
sb.append(' ');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void init(DerValue encoding)
|
||||
throws Asn1Exception, IOException, RealmException {
|
||||
DerValue der, subDer;
|
||||
|
||||
renewTill = null;
|
||||
caddr = null;
|
||||
authorizationData = null;
|
||||
if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x03)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
flags = TicketFlags.parse(der.getData(), (byte) 0x00, false);
|
||||
key = EncryptionKey.parse(der.getData(), (byte) 0x01, false);
|
||||
Realm crealm = Realm.parse(der.getData(), (byte) 0x02, false);
|
||||
cname = PrincipalName.parse(der.getData(), (byte) 0x03, false, crealm);
|
||||
transited = TransitedEncoding.parse(der.getData(), (byte) 0x04, false);
|
||||
authtime = KerberosTime.parse(der.getData(), (byte) 0x05, false);
|
||||
starttime = KerberosTime.parse(der.getData(), (byte) 0x06, true);
|
||||
endtime = KerberosTime.parse(der.getData(), (byte) 0x07, false);
|
||||
if (der.getData().available() > 0) {
|
||||
renewTill = KerberosTime.parse(der.getData(), (byte) 0x08, true);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
caddr = HostAddresses.parse(der.getData(), (byte) 0x09, true);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
authorizationData = AuthorizationData.parse(der.getData(), (byte) 0x0A, true);
|
||||
}
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an EncTicketPart object.
|
||||
* @return byte array of encoded EncTicketPart object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x00), flags.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x01), key.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x02), cname.getRealm().asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x03), cname.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x04), transited.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x05), authtime.asn1Encode());
|
||||
if (starttime != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x06), starttime.asn1Encode());
|
||||
}
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x07), endtime.asn1Encode());
|
||||
|
||||
if (renewTill != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x08), renewTill.asn1Encode());
|
||||
}
|
||||
|
||||
if (caddr != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x09), caddr.asn1Encode());
|
||||
}
|
||||
|
||||
if (authorizationData != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x0A), authorizationData.asn1Encode());
|
||||
}
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
|
||||
true, (byte) 0x03), temp);
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
}
|
||||
306
jdkSrc/jdk8/sun/security/krb5/internal/HostAddress.java
Normal file
306
jdkSrc/jdk8/sun/security/krb5/internal/HostAddress.java
Normal file
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2006, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.Config;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.util.*;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 HostAddress type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* HostAddress ::= SEQUENCE {
|
||||
* addr-type [0] Int32,
|
||||
* address [1] OCTET STRING
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class HostAddress implements Cloneable {
|
||||
int addrType;
|
||||
byte[] address = null;
|
||||
|
||||
private static InetAddress localInetAddress; //caches local inet address
|
||||
private static final boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;
|
||||
private volatile int hashCode = 0;
|
||||
|
||||
private HostAddress(int dummy) {}
|
||||
|
||||
public Object clone() {
|
||||
HostAddress new_hostAddress = new HostAddress(0);
|
||||
new_hostAddress.addrType = addrType;
|
||||
if (address != null) {
|
||||
new_hostAddress.address = address.clone();
|
||||
}
|
||||
return new_hostAddress;
|
||||
}
|
||||
|
||||
|
||||
public int hashCode() {
|
||||
if (hashCode == 0) {
|
||||
int result = 17;
|
||||
result = 37*result + addrType;
|
||||
if (address != null) {
|
||||
for (int i=0; i < address.length; i++) {
|
||||
result = 37*result + address[i];
|
||||
}
|
||||
}
|
||||
hashCode = result;
|
||||
}
|
||||
return hashCode;
|
||||
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof HostAddress)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HostAddress h = (HostAddress)obj;
|
||||
if (addrType != h.addrType ||
|
||||
(address != null && h.address == null) ||
|
||||
(address == null && h.address != null))
|
||||
return false;
|
||||
if (address != null && h.address != null) {
|
||||
if (address.length != h.address.length)
|
||||
return false;
|
||||
for (int i = 0; i < address.length; i++)
|
||||
if (address[i] != h.address[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static synchronized InetAddress getLocalInetAddress()
|
||||
throws UnknownHostException {
|
||||
|
||||
if (localInetAddress == null) {
|
||||
localInetAddress = InetAddress.getLocalHost();
|
||||
}
|
||||
if (localInetAddress == null) {
|
||||
throw new UnknownHostException();
|
||||
}
|
||||
return (localInetAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the InetAddress of this HostAddress.
|
||||
* @return the IP address for this specified host.
|
||||
* @exception UnknownHostException if no IP address for the host could be found.
|
||||
*
|
||||
*/
|
||||
public InetAddress getInetAddress() throws UnknownHostException {
|
||||
// the type of internet addresses is 2.
|
||||
if (addrType == Krb5.ADDRTYPE_INET ||
|
||||
addrType == Krb5.ADDRTYPE_INET6) {
|
||||
return (InetAddress.getByAddress(address));
|
||||
} else {
|
||||
// if it is other type (ISO address, XNS address, etc)
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private int getAddrType(InetAddress inetAddress) {
|
||||
int addressType = 0;
|
||||
if (inetAddress instanceof Inet4Address)
|
||||
addressType = Krb5.ADDRTYPE_INET;
|
||||
else if (inetAddress instanceof Inet6Address)
|
||||
addressType = Krb5.ADDRTYPE_INET6;
|
||||
return (addressType);
|
||||
}
|
||||
|
||||
// implicit default not in Config.java
|
||||
public HostAddress() throws UnknownHostException {
|
||||
InetAddress inetAddress = getLocalInetAddress();
|
||||
addrType = getAddrType(inetAddress);
|
||||
address = inetAddress.getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HostAddress from the specified address and address type.
|
||||
*
|
||||
* @param new_addrType the value of the address type which matches the defined
|
||||
* address family constants in the Berkeley Standard
|
||||
* Distributions of Unix.
|
||||
* @param new_address network address.
|
||||
* @exception KrbApErrException if address type and address length do not match defined value.
|
||||
*
|
||||
*/
|
||||
public HostAddress(int new_addrType, byte[] new_address)
|
||||
throws KrbApErrException, UnknownHostException {
|
||||
switch(new_addrType) {
|
||||
case Krb5.ADDRTYPE_INET: //Internet address
|
||||
if (new_address.length != 4)
|
||||
throw new KrbApErrException(0, "Invalid Internet address");
|
||||
break;
|
||||
case Krb5.ADDRTYPE_CHAOS:
|
||||
if (new_address.length != 2) //CHAOSnet address
|
||||
throw new KrbApErrException(0, "Invalid CHAOSnet address");
|
||||
break;
|
||||
case Krb5.ADDRTYPE_ISO: // ISO address
|
||||
break;
|
||||
case Krb5.ADDRTYPE_IPX: // XNS address
|
||||
if (new_address.length != 6)
|
||||
throw new KrbApErrException(0, "Invalid XNS address");
|
||||
break;
|
||||
case Krb5.ADDRTYPE_APPLETALK: //AppleTalk DDP address
|
||||
if (new_address.length != 3)
|
||||
throw new KrbApErrException(0, "Invalid DDP address");
|
||||
break;
|
||||
case Krb5.ADDRTYPE_DECNET: //DECnet Phase IV address
|
||||
if (new_address.length != 2)
|
||||
throw new KrbApErrException(0, "Invalid DECnet Phase IV address");
|
||||
break;
|
||||
case Krb5.ADDRTYPE_INET6: //Internet IPv6 address
|
||||
if (new_address.length != 16)
|
||||
throw new KrbApErrException(0, "Invalid Internet IPv6 address");
|
||||
break;
|
||||
}
|
||||
|
||||
addrType = new_addrType;
|
||||
if (new_address != null) {
|
||||
address = new_address.clone();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (addrType == Krb5.ADDRTYPE_INET ||
|
||||
addrType == Krb5.ADDRTYPE_INET6) {
|
||||
System.out.println("Host address is " +
|
||||
InetAddress.getByAddress(address));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HostAddress(InetAddress inetAddress) {
|
||||
addrType = getAddrType(inetAddress);
|
||||
address = inetAddress.getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a host address from a single DER-encoded value.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
public HostAddress(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x00) {
|
||||
addrType = der.getData().getBigInteger().intValue();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x01) {
|
||||
address = der.getData().getOctetString();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a HostAddress object.
|
||||
* @return a byte array of encoded HostAddress object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(this.addrType);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putOctetString(address);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses (unmarshal) a host address from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicates if this data field is optional
|
||||
* @return an instance of HostAddress.
|
||||
*
|
||||
*/
|
||||
public static HostAddress parse(DerInputStream data, byte explicitTag,
|
||||
boolean optional)
|
||||
throws Asn1Exception, IOException{
|
||||
if ((optional) &&
|
||||
(((byte)data.peekByte() & (byte)0x1F) != explicitTag)) {
|
||||
return null;
|
||||
}
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new HostAddress(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Arrays.toString(address));
|
||||
sb.append('(').append(addrType).append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
346
jdkSrc/jdk8/sun/security/krb5/internal/HostAddresses.java
Normal file
346
jdkSrc/jdk8/sun/security/krb5/internal/HostAddresses.java
Normal file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.Config;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.KrbException;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.util.*;
|
||||
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
import sun.security.krb5.internal.ccache.CCacheOutputStream;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 HostAddresses type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* HostAddresses -- NOTE: subtly different from rfc1510,
|
||||
* -- but has a value mapping and encodes the same
|
||||
* ::= SEQUENCE OF HostAddress
|
||||
*
|
||||
* HostAddress ::= SEQUENCE {
|
||||
* addr-type [0] Int32,
|
||||
* address [1] OCTET STRING
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class HostAddresses implements Cloneable {
|
||||
private static boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;
|
||||
private HostAddress[] addresses = null;
|
||||
private volatile int hashCode = 0;
|
||||
|
||||
public HostAddresses(HostAddress[] new_addresses) throws IOException {
|
||||
if (new_addresses != null) {
|
||||
addresses = new HostAddress[new_addresses.length];
|
||||
for (int i = 0; i < new_addresses.length; i++) {
|
||||
if (new_addresses[i] == null) {
|
||||
throw new IOException("Cannot create a HostAddress");
|
||||
} else {
|
||||
addresses[i] = (HostAddress)new_addresses[i].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HostAddresses() throws UnknownHostException {
|
||||
addresses = new HostAddress[1];
|
||||
addresses[0] = new HostAddress();
|
||||
}
|
||||
|
||||
private HostAddresses(int dummy) {}
|
||||
|
||||
public HostAddresses(PrincipalName serverPrincipal)
|
||||
throws UnknownHostException, KrbException {
|
||||
|
||||
String[] components = serverPrincipal.getNameStrings();
|
||||
|
||||
if (serverPrincipal.getNameType() != PrincipalName.KRB_NT_SRV_HST ||
|
||||
components.length < 2)
|
||||
throw new KrbException(Krb5.KRB_ERR_GENERIC, "Bad name");
|
||||
|
||||
String host = components[1];
|
||||
InetAddress addr[] = InetAddress.getAllByName(host);
|
||||
HostAddress hAddrs[] = new HostAddress[addr.length];
|
||||
|
||||
for (int i = 0; i < addr.length; i++) {
|
||||
hAddrs[i] = new HostAddress(addr[i]);
|
||||
}
|
||||
|
||||
addresses = hAddrs;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
HostAddresses new_hostAddresses = new HostAddresses(0);
|
||||
if (addresses != null) {
|
||||
new_hostAddresses.addresses = new HostAddress[addresses.length];
|
||||
for (int i = 0; i < addresses.length; i++) {
|
||||
new_hostAddresses.addresses[i] =
|
||||
(HostAddress)addresses[i].clone();
|
||||
}
|
||||
}
|
||||
return new_hostAddresses;
|
||||
}
|
||||
|
||||
public boolean inList(HostAddress addr) {
|
||||
if (addresses != null) {
|
||||
for (int i = 0; i < addresses.length; i++)
|
||||
if (addresses[i].equals(addr))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (hashCode == 0) {
|
||||
int result = 17;
|
||||
if (addresses != null) {
|
||||
for (int i=0; i < addresses.length; i++) {
|
||||
result = 37*result + addresses[i].hashCode();
|
||||
}
|
||||
}
|
||||
hashCode = result;
|
||||
}
|
||||
return hashCode;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof HostAddresses)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HostAddresses addrs = (HostAddresses)obj;
|
||||
if ((addresses == null && addrs.addresses != null) ||
|
||||
(addresses != null && addrs.addresses == null))
|
||||
return false;
|
||||
if (addresses != null && addrs.addresses != null) {
|
||||
if (addresses.length != addrs.addresses.length)
|
||||
return false;
|
||||
for (int i = 0; i < addresses.length; i++)
|
||||
if (!addresses[i].equals(addrs.addresses[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>HostAddresses</code> object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an
|
||||
* ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading
|
||||
* encoded data.
|
||||
*/
|
||||
public HostAddresses(DerValue encoding)
|
||||
throws Asn1Exception, IOException {
|
||||
Vector<HostAddress> tempAddresses = new Vector<>();
|
||||
DerValue der = null;
|
||||
while (encoding.getData().available() > 0) {
|
||||
der = encoding.getData().getDerValue();
|
||||
tempAddresses.addElement(new HostAddress(der));
|
||||
}
|
||||
if (tempAddresses.size() > 0) {
|
||||
addresses = new HostAddress[tempAddresses.size()];
|
||||
tempAddresses.copyInto(addresses);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encodes a <code>HostAddresses</code> object.
|
||||
* @return byte array of encoded <code>HostAddresses</code> object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an
|
||||
* ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading
|
||||
* encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
|
||||
if (addresses != null && addresses.length > 0) {
|
||||
for (int i = 0; i < addresses.length; i++)
|
||||
bytes.write(addresses[i].asn1Encode());
|
||||
}
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a <code>HostAddresses</code> from a DER input stream.
|
||||
* This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception if an Asn1Exception occurs.
|
||||
* @param data the Der input stream value, which contains one or more
|
||||
* marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicates if this data field is optional.
|
||||
* @return an instance of <code>HostAddresses</code>.
|
||||
*/
|
||||
public static HostAddresses parse(DerInputStream data,
|
||||
byte explicitTag, boolean optional)
|
||||
throws Asn1Exception, IOException {
|
||||
if ((optional) &&
|
||||
(((byte)data.peekByte() & (byte)0x1F) != explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
} else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new HostAddresses(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data field values in <code>HostAddresses</code> in FCC
|
||||
* format to a <code>CCacheOutputStream</code>.
|
||||
*
|
||||
* @param cos a <code>CCacheOutputStream</code> to be written to.
|
||||
* @exception IOException if an I/O exception occurs.
|
||||
* @see sun.security.krb5.internal.ccache.CCacheOutputStream
|
||||
*/
|
||||
|
||||
public void writeAddrs(CCacheOutputStream cos) throws IOException {
|
||||
if (addresses == null || addresses.length == 0) {
|
||||
cos.write32(0);
|
||||
return;
|
||||
}
|
||||
cos.write32(addresses.length);
|
||||
for (int i = 0; i < addresses.length; i++) {
|
||||
cos.write16(addresses[i].addrType);
|
||||
cos.write32(addresses[i].address.length);
|
||||
cos.write(addresses[i].address, 0,
|
||||
addresses[i].address.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public InetAddress[] getInetAddresses() {
|
||||
|
||||
if (addresses == null || addresses.length == 0)
|
||||
return null;
|
||||
|
||||
ArrayList<InetAddress> ipAddrs = new ArrayList<>(addresses.length);
|
||||
|
||||
for (int i = 0; i < addresses.length; i++) {
|
||||
try {
|
||||
if ((addresses[i].addrType == Krb5.ADDRTYPE_INET) ||
|
||||
(addresses[i].addrType == Krb5.ADDRTYPE_INET6)) {
|
||||
ipAddrs.add(addresses[i].getInetAddress());
|
||||
}
|
||||
} catch (java.net.UnknownHostException e) {
|
||||
// Should not happen since IP address given
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
InetAddress[] retVal = new InetAddress[ipAddrs.size()];
|
||||
return ipAddrs.toArray(retVal);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the IP addresses of the local host.
|
||||
*/
|
||||
public static HostAddresses getLocalAddresses() throws IOException
|
||||
{
|
||||
Set<InetAddress> all = new LinkedHashSet<>();
|
||||
try {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KrbKdcReq local addresses are:");
|
||||
}
|
||||
String extra = Config.getInstance().getAll(
|
||||
"libdefaults", "extra_addresses");
|
||||
if (extra != null) {
|
||||
for (String s: extra.split("\\s+")) {
|
||||
all.add(InetAddress.getByName(s));
|
||||
if (DEBUG) {
|
||||
System.out.println(" extra_addresses: "
|
||||
+ InetAddress.getByName(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (NetworkInterface ni:
|
||||
Collections.list(NetworkInterface.getNetworkInterfaces())) {
|
||||
if (DEBUG) {
|
||||
System.out.println(" NetworkInterface " + ni + ":");
|
||||
System.out.println(" "
|
||||
+ Collections.list(ni.getInetAddresses()));
|
||||
}
|
||||
all.addAll(Collections.list(ni.getInetAddresses()));
|
||||
}
|
||||
return new HostAddresses(all.toArray(new InetAddress[all.size()]));
|
||||
} catch (Exception exc) {
|
||||
throw new IOException(exc.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HostAddresses instance from the supplied list
|
||||
* of InetAddresses.
|
||||
*/
|
||||
public HostAddresses(InetAddress[] inetAddresses)
|
||||
{
|
||||
if (inetAddresses == null)
|
||||
{
|
||||
addresses = null;
|
||||
return;
|
||||
}
|
||||
|
||||
addresses = new HostAddress[inetAddresses.length];
|
||||
for (int i = 0; i < inetAddresses.length; i++)
|
||||
addresses[i] = new HostAddress(inetAddresses[i]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Arrays.toString(addresses);
|
||||
}
|
||||
}
|
||||
332
jdkSrc/jdk8/sun/security/krb5/internal/KDCOptions.java
Normal file
332
jdkSrc/jdk8/sun/security/krb5/internal/KDCOptions.java
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.Config;
|
||||
import sun.security.krb5.KrbException;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.internal.util.KerberosFlags;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KDCOptions type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KDCOptions ::= KerberosFlags
|
||||
* -- reserved(0),
|
||||
* -- forwardable(1),
|
||||
* -- forwarded(2),
|
||||
* -- proxiable(3),
|
||||
* -- proxy(4),
|
||||
* -- allow-postdate(5),
|
||||
* -- postdated(6),
|
||||
* -- unused7(7),
|
||||
* -- renewable(8),
|
||||
* -- unused9(9),
|
||||
* -- unused10(10),
|
||||
* -- opt-hardware-auth(11),
|
||||
* -- unused12(12),
|
||||
* -- unused13(13),
|
||||
* -- 15 is reserved for canonicalize
|
||||
* -- unused15(15),
|
||||
* -- 26 was unused in 1510
|
||||
* -- disable-transited-check(26),
|
||||
* -- renewable-ok(27),
|
||||
* -- enc-tkt-in-skey(28),
|
||||
* -- renew(30),
|
||||
* -- validate(31)
|
||||
*
|
||||
* KerberosFlags ::= BIT STRING (SIZE (32..MAX))
|
||||
* -- minimum number of bits shall be sent,
|
||||
* -- but no fewer than 32
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*
|
||||
* <p>
|
||||
* This class appears as data field in the initial request(KRB_AS_REQ)
|
||||
* or subsequent request(KRB_TGS_REQ) to the KDC and indicates the flags
|
||||
* that the client wants to set on the tickets.
|
||||
*
|
||||
* The optional bits are:
|
||||
* <UL>
|
||||
* <LI>KDCOptions.RESERVED
|
||||
* <LI>KDCOptions.FORWARDABLE
|
||||
* <LI>KDCOptions.FORWARDED
|
||||
* <LI>KDCOptions.PROXIABLE
|
||||
* <LI>KDCOptions.PROXY
|
||||
* <LI>KDCOptions.ALLOW_POSTDATE
|
||||
* <LI>KDCOptions.POSTDATED
|
||||
* <LI>KDCOptions.RENEWABLE
|
||||
* <LI>KDCOptions.RENEWABLE_OK
|
||||
* <LI>KDCOptions.ENC_TKT_IN_SKEY
|
||||
* <LI>KDCOptions.RENEW
|
||||
* <LI>KDCOptions.VALIDATE
|
||||
* </UL>
|
||||
* <p> Various checks must be made before honoring an option. The restrictions
|
||||
* on the use of some options are as follows:
|
||||
* <ol>
|
||||
* <li> FORWARDABLE, FORWARDED, PROXIABLE, RENEWABLE options may be set in
|
||||
* subsequent request only if the ticket_granting ticket on which it is based has
|
||||
* the same options (FORWARDABLE, FORWARDED, PROXIABLE, RENEWABLE) set.
|
||||
* <li> ALLOW_POSTDATE may be set in subsequent request only if the
|
||||
* ticket-granting ticket on which it is based also has its MAY_POSTDATE flag set.
|
||||
* <li> POSTDATED may be set in subsequent request only if the
|
||||
* ticket-granting ticket on which it is based also has its MAY_POSTDATE flag set.
|
||||
* <li> RENEWABLE or RENEW may be set in subsequent request only if the
|
||||
* ticket-granting ticket on which it is based also has its RENEWABLE flag set.
|
||||
* <li> POXY may be set in subsequent request only if the ticket-granting ticket
|
||||
* on which it is based also has its PROXIABLE flag set, and the address(es) of
|
||||
* the host from which the resulting ticket is to be valid should be included
|
||||
* in the addresses field of the request.
|
||||
* <li>FORWARDED, PROXY, ENC_TKT_IN_SKEY, RENEW, VALIDATE are used only in
|
||||
* subsequent requests.
|
||||
* </ol>
|
||||
*/
|
||||
|
||||
public class KDCOptions extends KerberosFlags {
|
||||
|
||||
private static final int KDC_OPT_PROXIABLE = 0x10000000;
|
||||
private static final int KDC_OPT_RENEWABLE_OK = 0x00000010;
|
||||
private static final int KDC_OPT_FORWARDABLE = 0x40000000;
|
||||
|
||||
|
||||
// KDC Options
|
||||
|
||||
public static final int RESERVED = 0;
|
||||
public static final int FORWARDABLE = 1;
|
||||
public static final int FORWARDED = 2;
|
||||
public static final int PROXIABLE = 3;
|
||||
public static final int PROXY = 4;
|
||||
public static final int ALLOW_POSTDATE = 5;
|
||||
public static final int POSTDATED = 6;
|
||||
public static final int UNUSED7 = 7;
|
||||
public static final int RENEWABLE = 8;
|
||||
public static final int UNUSED9 = 9;
|
||||
public static final int UNUSED10 = 10;
|
||||
public static final int UNUSED11 = 11;
|
||||
public static final int CNAME_IN_ADDL_TKT = 14;
|
||||
public static final int CANONICALIZE = 15;
|
||||
public static final int RENEWABLE_OK = 27;
|
||||
public static final int ENC_TKT_IN_SKEY = 28;
|
||||
public static final int RENEW = 30;
|
||||
public static final int VALIDATE = 31;
|
||||
|
||||
private static final String[] names = {
|
||||
"RESERVED", //0
|
||||
"FORWARDABLE", //1;
|
||||
"FORWARDED", //2;
|
||||
"PROXIABLE", //3;
|
||||
"PROXY", //4;
|
||||
"ALLOW_POSTDATE", //5;
|
||||
"POSTDATED", //6;
|
||||
"UNUSED7", //7;
|
||||
"RENEWABLE", //8;
|
||||
"UNUSED9", //9;
|
||||
"UNUSED10", //10;
|
||||
"UNUSED11", //11;
|
||||
null,null,
|
||||
"CNAME_IN_ADDL_TKT",//14;
|
||||
"CANONICALIZE", //15;
|
||||
null,null,null,null,null,null,null,null,null,null,null,
|
||||
"RENEWABLE_OK", //27;
|
||||
"ENC_TKT_IN_SKEY", //28;
|
||||
null,
|
||||
"RENEW", //30;
|
||||
"VALIDATE", //31;
|
||||
};
|
||||
|
||||
private boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public static KDCOptions with(int... flags) {
|
||||
KDCOptions options = new KDCOptions();
|
||||
for (int flag: flags) {
|
||||
options.set(flag, true);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
public KDCOptions() {
|
||||
super(Krb5.KDC_OPTS_MAX + 1);
|
||||
setDefault();
|
||||
}
|
||||
|
||||
public KDCOptions(int size, byte[] data) throws Asn1Exception {
|
||||
super(size, data);
|
||||
if ((size > data.length * BITS_PER_UNIT) || (size > Krb5.KDC_OPTS_MAX + 1))
|
||||
throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KDCOptions from the specified bit settings.
|
||||
*
|
||||
* @param data the bits to be set for the KDCOptions.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1
|
||||
* encoded data.
|
||||
*
|
||||
*/
|
||||
public KDCOptions(boolean[] data) throws Asn1Exception {
|
||||
super(data);
|
||||
if (data.length > Krb5.KDC_OPTS_MAX + 1) {
|
||||
throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
public KDCOptions(DerValue encoding) throws Asn1Exception, IOException {
|
||||
this(encoding.getUnalignedBitString(true).toBooleanArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KDCOptions from the passed bit settings.
|
||||
*
|
||||
* @param options the bits to be set for the KDCOptions.
|
||||
*
|
||||
*/
|
||||
public KDCOptions(byte[] options) {
|
||||
super(options.length * BITS_PER_UNIT, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a KDCOptions from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @param data the Der input stream value, which contains one or more
|
||||
* marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicate if this data field is optional
|
||||
* @return an instance of KDCOptions.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
|
||||
public static KDCOptions parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
} else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new KDCOptions(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value(true/false) for one of the <code>KDCOptions</code>.
|
||||
*
|
||||
* @param option an option bit.
|
||||
* @param value true if the option is selected, false if the option is not selected.
|
||||
* @exception ArrayIndexOutOfBoundsException if array index out of bound occurs.
|
||||
* @see sun.security.krb5.internal.Krb5
|
||||
*/
|
||||
public void set(int option, boolean value) throws ArrayIndexOutOfBoundsException {
|
||||
super.set(option, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value(true/false) for one of the <code>KDCOptions</code>.
|
||||
*
|
||||
* @param option an option bit.
|
||||
* @return value true if the option is selected, false if the option is not selected.
|
||||
* @exception ArrayIndexOutOfBoundsException if array index out of bound occurs.
|
||||
* @see sun.security.krb5.internal.Krb5
|
||||
*/
|
||||
|
||||
public boolean get(int option) throws ArrayIndexOutOfBoundsException {
|
||||
return super.get(option);
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("KDCOptions: ");
|
||||
for (int i=0; i<Krb5.KDC_OPTS_MAX+1; i++) {
|
||||
if (get(i)) {
|
||||
if (names[i] != null) {
|
||||
sb.append(names[i]).append(",");
|
||||
} else {
|
||||
sb.append(i).append(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void setDefault() {
|
||||
try {
|
||||
|
||||
Config config = Config.getInstance();
|
||||
|
||||
// If key not present, returns Integer.MIN_VALUE, which is
|
||||
// almost all zero.
|
||||
|
||||
int options = config.getIntValue("libdefaults",
|
||||
"kdc_default_options");
|
||||
|
||||
if ((options & KDC_OPT_RENEWABLE_OK) == KDC_OPT_RENEWABLE_OK) {
|
||||
set(RENEWABLE_OK, true);
|
||||
} else {
|
||||
if (config.getBooleanObject("libdefaults", "renewable") == Boolean.TRUE) {
|
||||
set(RENEWABLE_OK, true);
|
||||
}
|
||||
}
|
||||
if ((options & KDC_OPT_PROXIABLE) == KDC_OPT_PROXIABLE) {
|
||||
set(PROXIABLE, true);
|
||||
} else {
|
||||
if (config.getBooleanObject("libdefaults", "proxiable") == Boolean.TRUE) {
|
||||
set(PROXIABLE, true);
|
||||
}
|
||||
}
|
||||
|
||||
if ((options & KDC_OPT_FORWARDABLE) == KDC_OPT_FORWARDABLE) {
|
||||
set(FORWARDABLE, true);
|
||||
} else {
|
||||
if (config.getBooleanObject("libdefaults", "forwardable") == Boolean.TRUE) {
|
||||
set(FORWARDABLE, true);
|
||||
}
|
||||
}
|
||||
} catch (KrbException e) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Exception in getting default values for " +
|
||||
"KDC Options from the configuration ");
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
223
jdkSrc/jdk8/sun/security/krb5/internal/KDCRep.java
Normal file
223
jdkSrc/jdk8/sun/security/krb5/internal/KDCRep.java
Normal file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KDC-REP type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KDC-REP ::= SEQUENCE {
|
||||
* pvno [0] INTEGER (5),
|
||||
* msg-type [1] INTEGER (11 -- AS -- | 13 -- TGS --),
|
||||
* padata [2] SEQUENCE OF PA-DATA OPTIONAL
|
||||
* -- NOTE: not empty --,
|
||||
* crealm [3] Realm,
|
||||
* cname [4] PrincipalName,
|
||||
* ticket [5] Ticket,
|
||||
* enc-part [6] EncryptedData
|
||||
* -- EncASRepPart or EncTGSRepPart,
|
||||
* -- as appropriate
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class KDCRep {
|
||||
|
||||
public PrincipalName cname;
|
||||
public Ticket ticket;
|
||||
public EncryptedData encPart;
|
||||
public EncKDCRepPart encKDCRepPart; //not part of ASN.1 encoding
|
||||
private int pvno;
|
||||
private int msgType;
|
||||
public PAData[] pAData = null; //optional
|
||||
private boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public KDCRep(
|
||||
PAData[] new_pAData,
|
||||
PrincipalName new_cname,
|
||||
Ticket new_ticket,
|
||||
EncryptedData new_encPart,
|
||||
int req_type) throws IOException {
|
||||
pvno = Krb5.PVNO;
|
||||
msgType = req_type;
|
||||
if (new_pAData != null) {
|
||||
pAData = new PAData[new_pAData.length];
|
||||
for (int i = 0; i < new_pAData.length; i++) {
|
||||
if (new_pAData[i] == null) {
|
||||
throw new IOException("Cannot create a KDCRep");
|
||||
} else {
|
||||
pAData[i] = (PAData) new_pAData[i].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
cname = new_cname;
|
||||
ticket = new_ticket;
|
||||
encPart = new_encPart;
|
||||
}
|
||||
|
||||
public KDCRep() {
|
||||
}
|
||||
|
||||
public KDCRep(byte[] data, int req_type) throws Asn1Exception,
|
||||
KrbApErrException, RealmException, IOException {
|
||||
init(new DerValue(data), req_type);
|
||||
}
|
||||
|
||||
public KDCRep(DerValue encoding, int req_type) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(encoding, req_type);
|
||||
}
|
||||
|
||||
/*
|
||||
// Not used? Don't know what keyusage to use here %%%
|
||||
public void decrypt(EncryptionKey key) throws Asn1Exception,
|
||||
IOException, KrbException, RealmException {
|
||||
encKDCRepPart = new EncKDCRepPart(encPart.decrypt(key), msgType);
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* Initializes an KDCRep object.
|
||||
*
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @param req_type reply message type.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception RealmException if an error occurs while constructing
|
||||
* a Realm object from DER-encoded data.
|
||||
* @exception KrbApErrException if the value read from the DER-encoded
|
||||
* data stream does not match the pre-defined value.
|
||||
*
|
||||
*/
|
||||
protected void init(DerValue encoding, int req_type)
|
||||
throws Asn1Exception, RealmException, IOException,
|
||||
KrbApErrException {
|
||||
DerValue der, subDer;
|
||||
if ((encoding.getTag() & 0x1F) != req_type) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KDCRep: init() " +
|
||||
"encoding tag is " +
|
||||
encoding.getTag() +
|
||||
" req type is " + req_type);
|
||||
}
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) == 0x00) {
|
||||
pvno = subDer.getData().getBigInteger().intValue();
|
||||
if (pvno != Krb5.PVNO) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) == 0x01) {
|
||||
msgType = subDer.getData().getBigInteger().intValue();
|
||||
if (msgType != req_type) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if ((der.getData().peekByte() & 0x1F) == 0x02) {
|
||||
subDer = der.getData().getDerValue();
|
||||
DerValue[] padata = subDer.getData().getSequence(1);
|
||||
pAData = new PAData[padata.length];
|
||||
for (int i = 0; i < padata.length; i++) {
|
||||
pAData[i] = new PAData(padata[i]);
|
||||
}
|
||||
} else {
|
||||
pAData = null;
|
||||
}
|
||||
Realm crealm = Realm.parse(der.getData(), (byte) 0x03, false);
|
||||
cname = PrincipalName.parse(der.getData(), (byte) 0x04, false, crealm);
|
||||
ticket = Ticket.parse(der.getData(), (byte) 0x05, false);
|
||||
encPart = EncryptedData.parse(der.getData(), (byte) 0x06, false);
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this object to a byte array.
|
||||
* @return byte array of encoded APReq object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(pvno));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(msgType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x01), temp);
|
||||
if (pAData != null && pAData.length > 0) {
|
||||
DerOutputStream padata_stream = new DerOutputStream();
|
||||
for (int i = 0; i < pAData.length; i++) {
|
||||
padata_stream.write(pAData[i].asn1Encode());
|
||||
}
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_SequenceOf, padata_stream);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x02), temp);
|
||||
}
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x03), cname.getRealm().asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x04), cname.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x05), ticket.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x06), encPart.asn1Encode());
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
}
|
||||
199
jdkSrc/jdk8/sun/security/krb5/internal/KDCReq.java
Normal file
199
jdkSrc/jdk8/sun/security/krb5/internal/KDCReq.java
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import java.util.Vector;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KRB_KDC_REQ type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KDC-REQ ::= SEQUENCE {
|
||||
* -- NOTE: first tag is [1], not [0]
|
||||
* pvno [1] INTEGER (5) ,
|
||||
* msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --),
|
||||
* padata [3] SEQUENCE OF PA-DATA OPTIONAL
|
||||
* -- NOTE: not empty --,
|
||||
* req-body [4] KDC-REQ-BODY
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class KDCReq {
|
||||
|
||||
public KDCReqBody reqBody;
|
||||
public PAData[] pAData = null; //optional
|
||||
private int pvno;
|
||||
private int msgType;
|
||||
|
||||
public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody,
|
||||
int req_type) throws IOException {
|
||||
pvno = Krb5.PVNO;
|
||||
msgType = req_type;
|
||||
if (new_pAData != null) {
|
||||
pAData = new PAData[new_pAData.length];
|
||||
for (int i = 0; i < new_pAData.length; i++) {
|
||||
if (new_pAData[i] == null) {
|
||||
throw new IOException("Cannot create a KDCRep");
|
||||
} else {
|
||||
pAData[i] = (PAData) new_pAData[i].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
reqBody = new_reqBody;
|
||||
}
|
||||
|
||||
public KDCReq() {
|
||||
}
|
||||
|
||||
public KDCReq(byte[] data, int req_type) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(new DerValue(data), req_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an KDCReq object from a DerValue object and asn1 type.
|
||||
*
|
||||
* @param der a DER value of an KDCReq object.
|
||||
* @param req_type a encoded asn1 type value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception KrbErrException
|
||||
*/
|
||||
public KDCReq(DerValue der, int req_type) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(der, req_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a KDCReq object from a DerValue. The DER encoding
|
||||
* must be in the format specified by the KRB_KDC_REQ ASN.1 notation.
|
||||
*
|
||||
* @param encoding a DER-encoded KDCReq object.
|
||||
* @param req_type an int indicating whether it's KRB_AS_REQ or KRB_TGS_REQ type
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception KrbException if an error occurs while constructing a Realm object,
|
||||
* or a Krb object from DER-encoded data.
|
||||
*/
|
||||
protected void init(DerValue encoding, int req_type) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
DerValue der, subDer;
|
||||
BigInteger bint;
|
||||
if ((encoding.getTag() & 0x1F) != req_type) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x01F) == 0x01) {
|
||||
bint = subDer.getData().getBigInteger();
|
||||
this.pvno = bint.intValue();
|
||||
if (this.pvno != Krb5.PVNO) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x01F) == 0x02) {
|
||||
bint = subDer.getData().getBigInteger();
|
||||
this.msgType = bint.intValue();
|
||||
if (this.msgType != req_type) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
pAData = PAData.parseSequence(der.getData(), (byte) 0x03, true);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x01F) == 0x04) {
|
||||
DerValue subsubDer = subDer.getData().getDerValue();
|
||||
reqBody = new KDCReqBody(subsubDer, msgType);
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this object to a byte array.
|
||||
*
|
||||
* @return an byte array of encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream temp, bytes, out;
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(pvno));
|
||||
out = new DerOutputStream();
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x01), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(msgType));
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x02), temp);
|
||||
if (pAData != null && pAData.length > 0) {
|
||||
temp = new DerOutputStream();
|
||||
for (int i = 0; i < pAData.length; i++) {
|
||||
temp.write(pAData[i].asn1Encode());
|
||||
}
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.tag_SequenceOf, temp);
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x03), bytes);
|
||||
}
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x04), reqBody.asn1Encode(msgType));
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.tag_Sequence, out);
|
||||
out = new DerOutputStream();
|
||||
out.write(DerValue.createTag(DerValue.TAG_APPLICATION,
|
||||
true, (byte) msgType), bytes);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public byte[] asn1EncodeReqBody() throws Asn1Exception, IOException {
|
||||
return reqBody.asn1Encode(msgType);
|
||||
}
|
||||
}
|
||||
282
jdkSrc/jdk8/sun/security/krb5/internal/KDCReqBody.java
Normal file
282
jdkSrc/jdk8/sun/security/krb5/internal/KDCReqBody.java
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KDC-REQ-BODY type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KDC-REQ-BODY ::= SEQUENCE {
|
||||
* kdc-options [0] KDCOptions,
|
||||
* cname [1] PrincipalName OPTIONAL
|
||||
* -- Used only in AS-REQ --,
|
||||
* realm [2] Realm
|
||||
* -- Server's realm
|
||||
* -- Also client's in AS-REQ --,
|
||||
* sname [3] PrincipalName OPTIONAL,
|
||||
* from [4] KerberosTime OPTIONAL,
|
||||
* till [5] KerberosTime,
|
||||
* rtime [6] KerberosTime OPTIONAL,
|
||||
* nonce [7] UInt32,
|
||||
* etype [8] SEQUENCE OF Int32 -- EncryptionType
|
||||
* -- in preference order --,
|
||||
* addresses [9] HostAddresses OPTIONAL,
|
||||
* enc-authorization-data [10] EncryptedData OPTIONAL
|
||||
* -- AuthorizationData --,
|
||||
* additional-tickets [11] SEQUENCE OF Ticket OPTIONAL
|
||||
* -- NOTE: not empty
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class KDCReqBody {
|
||||
public KDCOptions kdcOptions;
|
||||
public PrincipalName cname; //optional in ASReq only
|
||||
public PrincipalName sname; //optional
|
||||
public KerberosTime from; //optional
|
||||
public KerberosTime till;
|
||||
public KerberosTime rtime; //optional
|
||||
public HostAddresses addresses; //optional
|
||||
|
||||
private int nonce;
|
||||
private int[] eType = null; //a sequence; not optional
|
||||
private EncryptedData encAuthorizationData; //optional
|
||||
private Ticket[] additionalTickets; //optional
|
||||
|
||||
public KDCReqBody(
|
||||
KDCOptions new_kdcOptions,
|
||||
PrincipalName new_cname, //optional in ASReq only
|
||||
PrincipalName new_sname, //optional
|
||||
KerberosTime new_from, //optional
|
||||
KerberosTime new_till,
|
||||
KerberosTime new_rtime, //optional
|
||||
int new_nonce,
|
||||
int[] new_eType, //a sequence; not optional
|
||||
HostAddresses new_addresses, //optional
|
||||
EncryptedData new_encAuthorizationData, //optional
|
||||
Ticket[] new_additionalTickets //optional
|
||||
) throws IOException {
|
||||
kdcOptions = new_kdcOptions;
|
||||
cname = new_cname;
|
||||
sname = new_sname;
|
||||
from = new_from;
|
||||
till = new_till;
|
||||
rtime = new_rtime;
|
||||
nonce = new_nonce;
|
||||
if (new_eType != null) {
|
||||
eType = new_eType.clone();
|
||||
}
|
||||
addresses = new_addresses;
|
||||
encAuthorizationData = new_encAuthorizationData;
|
||||
if (new_additionalTickets != null) {
|
||||
additionalTickets = new Ticket[new_additionalTickets.length];
|
||||
for (int i = 0; i < new_additionalTickets.length; i++) {
|
||||
if (new_additionalTickets[i] == null) {
|
||||
throw new IOException("Cannot create a KDCReqBody");
|
||||
} else {
|
||||
additionalTickets[i] = (Ticket)new_additionalTickets[i].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KDCReqBody object.
|
||||
* @param encoding a DER-encoded data.
|
||||
* @param msgType an int indicating whether it's KRB_AS_REQ or KRB_TGS_REQ type.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception RealmException if an error occurs while constructing a Realm object from the encoded data.
|
||||
*
|
||||
*/
|
||||
public KDCReqBody(DerValue encoding, int msgType)
|
||||
throws Asn1Exception, RealmException, KrbException, IOException {
|
||||
DerValue der, subDer;
|
||||
addresses = null;
|
||||
encAuthorizationData = null;
|
||||
additionalTickets = null;
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
kdcOptions = KDCOptions.parse(encoding.getData(), (byte)0x00, false);
|
||||
|
||||
// cname only appears in AS-REQ and it shares the realm field with
|
||||
// sname. This is the only place where realm comes after the name.
|
||||
// We first give cname a fake realm and reassign it the correct
|
||||
// realm after the realm field is read.
|
||||
cname = PrincipalName.parse(encoding.getData(), (byte)0x01, true,
|
||||
new Realm("PLACEHOLDER"));
|
||||
if ((msgType != Krb5.KRB_AS_REQ) && (cname != null)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
Realm realm = Realm.parse(encoding.getData(), (byte)0x02, false);
|
||||
if (cname != null) {
|
||||
cname = new PrincipalName(
|
||||
cname.getNameType(), cname.getNameStrings(), realm);
|
||||
}
|
||||
sname = PrincipalName.parse(encoding.getData(), (byte)0x03, true, realm);
|
||||
from = KerberosTime.parse(encoding.getData(), (byte)0x04, true);
|
||||
till = KerberosTime.parse(encoding.getData(), (byte)0x05, false);
|
||||
rtime = KerberosTime.parse(encoding.getData(), (byte)0x06, true);
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x07) {
|
||||
nonce = der.getData().getBigInteger().intValue();
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
Vector<Integer> v = new Vector<>();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x08) {
|
||||
subDer = der.getData().getDerValue();
|
||||
|
||||
if (subDer.getTag() == DerValue.tag_SequenceOf) {
|
||||
while(subDer.getData().available() > 0) {
|
||||
v.addElement(subDer.getData().getBigInteger().intValue());
|
||||
}
|
||||
eType = new int[v.size()];
|
||||
for (int i = 0; i < v.size(); i++) {
|
||||
eType[i] = v.elementAt(i);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if (encoding.getData().available() > 0) {
|
||||
addresses = HostAddresses.parse(encoding.getData(), (byte)0x09, true);
|
||||
}
|
||||
if (encoding.getData().available() > 0) {
|
||||
encAuthorizationData = EncryptedData.parse(encoding.getData(), (byte)0x0A, true);
|
||||
}
|
||||
if (encoding.getData().available() > 0) {
|
||||
Vector<Ticket> tempTickets = new Vector<>();
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & (byte)0x1F) == (byte)0x0B) {
|
||||
subDer = der.getData().getDerValue();
|
||||
if (subDer.getTag() == DerValue.tag_SequenceOf) {
|
||||
while (subDer.getData().available() > 0) {
|
||||
tempTickets.addElement(new Ticket(subDer.getData().getDerValue()));
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if (tempTickets.size() > 0) {
|
||||
additionalTickets = new Ticket[tempTickets.size()];
|
||||
tempTickets.copyInto(additionalTickets);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
if (encoding.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this object to an OutputStream.
|
||||
*
|
||||
* @return an byte array of encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*
|
||||
*/
|
||||
public byte[] asn1Encode(int msgType) throws Asn1Exception, IOException {
|
||||
Vector<DerValue> v = new Vector<>();
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), kdcOptions.asn1Encode()));
|
||||
if (msgType == Krb5.KRB_AS_REQ) {
|
||||
if (cname != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), cname.asn1Encode()));
|
||||
}
|
||||
}
|
||||
if (sname != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), sname.getRealm().asn1Encode()));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), sname.asn1Encode()));
|
||||
} else if (cname != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), cname.getRealm().asn1Encode()));
|
||||
}
|
||||
if (from != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), from.asn1Encode()));
|
||||
}
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), till.asn1Encode()));
|
||||
if (rtime != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), rtime.asn1Encode()));
|
||||
}
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(nonce));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), temp.toByteArray()));
|
||||
//revisit, if empty eType sequences are allowed
|
||||
temp = new DerOutputStream();
|
||||
for (int i = 0; i < eType.length; i++) {
|
||||
temp.putInteger(BigInteger.valueOf(eType[i]));
|
||||
}
|
||||
DerOutputStream eTypetemp = new DerOutputStream();
|
||||
eTypetemp.write(DerValue.tag_SequenceOf, temp);
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), eTypetemp.toByteArray()));
|
||||
if (addresses != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), addresses.asn1Encode()));
|
||||
}
|
||||
if (encAuthorizationData != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), encAuthorizationData.asn1Encode()));
|
||||
}
|
||||
if (additionalTickets != null && additionalTickets.length > 0) {
|
||||
temp = new DerOutputStream();
|
||||
for (int i = 0; i < additionalTickets.length; i++) {
|
||||
temp.write(additionalTickets[i].asn1Encode());
|
||||
}
|
||||
DerOutputStream ticketsTemp = new DerOutputStream();
|
||||
ticketsTemp.write(DerValue.tag_SequenceOf, temp);
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0B), ticketsTemp.toByteArray()));
|
||||
}
|
||||
DerValue der[] = new DerValue[v.size()];
|
||||
v.copyInto(der);
|
||||
temp = new DerOutputStream();
|
||||
temp.putSequence(der);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
public int getNonce() {
|
||||
return nonce;
|
||||
}
|
||||
}
|
||||
189
jdkSrc/jdk8/sun/security/krb5/internal/KRBCred.java
Normal file
189
jdkSrc/jdk8/sun/security/krb5/internal/KRBCred.java
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.RealmException;
|
||||
import sun.security.util.*;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 Authenticator type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* 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>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
public class KRBCred {
|
||||
|
||||
public Ticket[] tickets = null;
|
||||
public EncryptedData encPart;
|
||||
private int pvno;
|
||||
private int msgType;
|
||||
|
||||
public KRBCred(Ticket[] new_tickets, EncryptedData new_encPart) throws IOException {
|
||||
pvno = Krb5.PVNO;
|
||||
msgType = Krb5.KRB_CRED;
|
||||
if (new_tickets != null) {
|
||||
tickets = new Ticket[new_tickets.length];
|
||||
for (int i = 0; i < new_tickets.length; i++) {
|
||||
if (new_tickets[i] == null) {
|
||||
throw new IOException("Cannot create a KRBCred");
|
||||
} else {
|
||||
tickets[i] = (Ticket) new_tickets[i].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
encPart = new_encPart;
|
||||
}
|
||||
|
||||
public KRBCred(byte[] data) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public KRBCred(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an KRBCred object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception KrbApErrException if the value read from the DER-encoded data
|
||||
* stream does not match the pre-defined value.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
*/
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x16)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
DerValue der, subDer;
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) == 0x00) {
|
||||
pvno = subDer.getData().getBigInteger().intValue();
|
||||
if (pvno != Krb5.PVNO) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) == 0x01) {
|
||||
msgType = subDer.getData().getBigInteger().intValue();
|
||||
if (msgType != Krb5.KRB_CRED) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) == 0x02) {
|
||||
DerValue subsubDer = subDer.getData().getDerValue();
|
||||
if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
Vector<Ticket> v = new Vector<>();
|
||||
while (subsubDer.getData().available() > 0) {
|
||||
v.addElement(new Ticket(subsubDer.getData().getDerValue()));
|
||||
}
|
||||
if (v.size() > 0) {
|
||||
tickets = new Ticket[v.size()];
|
||||
v.copyInto(tickets);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
encPart = EncryptedData.parse(der.getData(), (byte) 0x03, false);
|
||||
|
||||
if (der.getData().available() > 0) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an KRBCred object.
|
||||
* @return the data of encoded EncAPRepPart object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream temp, bytes, out;
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(pvno));
|
||||
out = new DerOutputStream();
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(msgType));
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x01), temp);
|
||||
temp = new DerOutputStream();
|
||||
for (int i = 0; i < tickets.length; i++) {
|
||||
temp.write(tickets[i].asn1Encode());
|
||||
}
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.tag_SequenceOf, temp);
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x02), bytes);
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte) 0x03), encPart.asn1Encode());
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.tag_Sequence, out);
|
||||
out = new DerOutputStream();
|
||||
out.write(DerValue.createTag(DerValue.TAG_APPLICATION,
|
||||
true, (byte) 0x16), bytes);
|
||||
return out.toByteArray();
|
||||
}
|
||||
}
|
||||
532
jdkSrc/jdk8/sun/security/krb5/internal/KRBError.java
Normal file
532
jdkSrc/jdk8/sun/security/krb5/internal/KRBError.java
Normal file
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.Checksum;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.Realm;
|
||||
import sun.security.krb5.RealmException;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import sun.security.krb5.internal.util.KerberosString;
|
||||
/**
|
||||
* Implements the ASN.1 KRBError type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
|
||||
* pvno [0] INTEGER (5),
|
||||
* msg-type [1] INTEGER (30),
|
||||
* ctime [2] KerberosTime OPTIONAL,
|
||||
* cusec [3] Microseconds OPTIONAL,
|
||||
* stime [4] KerberosTime,
|
||||
* susec [5] Microseconds,
|
||||
* error-code [6] Int32,
|
||||
* crealm [7] Realm OPTIONAL,
|
||||
* cname [8] PrincipalName OPTIONAL,
|
||||
* realm [9] Realm -- service realm --,
|
||||
* sname [10] PrincipalName -- service name --,
|
||||
* e-text [11] KerberosString OPTIONAL,
|
||||
* e-data [12] OCTET STRING OPTIONAL
|
||||
* }
|
||||
*
|
||||
* METHOD-DATA ::= SEQUENCE OF PA-DATA
|
||||
*
|
||||
* TYPED-DATA ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
|
||||
* data-type [0] Int32,
|
||||
* data-value [1] OCTET STRING OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class KRBError implements java.io.Serializable {
|
||||
static final long serialVersionUID = 3643809337475284503L;
|
||||
|
||||
private int pvno;
|
||||
private int msgType;
|
||||
private KerberosTime cTime; //optional
|
||||
private Integer cuSec; //optional
|
||||
private KerberosTime sTime;
|
||||
private Integer suSec;
|
||||
private int errorCode;
|
||||
private Realm crealm; //optional
|
||||
private PrincipalName cname; //optional
|
||||
private PrincipalName sname;
|
||||
private String eText; //optional
|
||||
private byte[] eData; //optional
|
||||
private Checksum eCksum; //optional
|
||||
|
||||
private PAData[] pa; // PA-DATA in eData
|
||||
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
private void readObject(ObjectInputStream is)
|
||||
throws IOException, ClassNotFoundException {
|
||||
try {
|
||||
init(new DerValue((byte[])is.readObject()));
|
||||
parseEData(eData);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream os)
|
||||
throws IOException {
|
||||
try {
|
||||
os.writeObject(asn1Encode());
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public KRBError(
|
||||
APOptions new_apOptions,
|
||||
KerberosTime new_cTime,
|
||||
Integer new_cuSec,
|
||||
KerberosTime new_sTime,
|
||||
Integer new_suSec,
|
||||
int new_errorCode,
|
||||
PrincipalName new_cname,
|
||||
PrincipalName new_sname,
|
||||
String new_eText,
|
||||
byte[] new_eData
|
||||
) throws IOException, Asn1Exception {
|
||||
pvno = Krb5.PVNO;
|
||||
msgType = Krb5.KRB_ERROR;
|
||||
cTime = new_cTime;
|
||||
cuSec = new_cuSec;
|
||||
sTime = new_sTime;
|
||||
suSec = new_suSec;
|
||||
errorCode = new_errorCode;
|
||||
crealm = new_cname != null ? new_cname.getRealm() : null;
|
||||
cname = new_cname;
|
||||
sname = new_sname;
|
||||
eText = new_eText;
|
||||
eData = new_eData;
|
||||
|
||||
parseEData(eData);
|
||||
}
|
||||
|
||||
public KRBError(
|
||||
APOptions new_apOptions,
|
||||
KerberosTime new_cTime,
|
||||
Integer new_cuSec,
|
||||
KerberosTime new_sTime,
|
||||
Integer new_suSec,
|
||||
int new_errorCode,
|
||||
PrincipalName new_cname,
|
||||
PrincipalName new_sname,
|
||||
String new_eText,
|
||||
byte[] new_eData,
|
||||
Checksum new_eCksum
|
||||
) throws IOException, Asn1Exception {
|
||||
pvno = Krb5.PVNO;
|
||||
msgType = Krb5.KRB_ERROR;
|
||||
cTime = new_cTime;
|
||||
cuSec = new_cuSec;
|
||||
sTime = new_sTime;
|
||||
suSec = new_suSec;
|
||||
errorCode = new_errorCode;
|
||||
crealm = new_cname != null ? new_cname.getRealm() : null;
|
||||
cname = new_cname;
|
||||
sname = new_sname;
|
||||
eText = new_eText;
|
||||
eData = new_eData;
|
||||
eCksum = new_eCksum;
|
||||
|
||||
parseEData(eData);
|
||||
}
|
||||
|
||||
public KRBError(byte[] data) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(new DerValue(data));
|
||||
parseEData(eData);
|
||||
}
|
||||
|
||||
public KRBError(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(encoding);
|
||||
showDebug();
|
||||
parseEData(eData);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attention:
|
||||
*
|
||||
* According to RFC 4120, e-data field in a KRB-ERROR message is
|
||||
* a METHOD-DATA when errorCode is KDC_ERR_PREAUTH_REQUIRED,
|
||||
* and application-specific otherwise (The RFC suggests using
|
||||
* TYPED-DATA).
|
||||
*
|
||||
* Hence, the ideal procedure to parse e-data should look like:
|
||||
*
|
||||
* if (errorCode is KDC_ERR_PREAUTH_REQUIRED) {
|
||||
* parse as METHOD-DATA
|
||||
* } else {
|
||||
* try parsing as TYPED-DATA
|
||||
* }
|
||||
*
|
||||
* Unfortunately, we know that some implementations also use the
|
||||
* METHOD-DATA format for errorcode KDC_ERR_PREAUTH_FAILED, and
|
||||
* do not use the TYPED-DATA for other errorcodes (say,
|
||||
* KDC_ERR_CLIENT_REVOKED).
|
||||
*/
|
||||
|
||||
// parse the edata field
|
||||
private void parseEData(byte[] data) throws IOException {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to parse eData as METHOD-DATA for both errorcodes.
|
||||
if (errorCode == Krb5.KDC_ERR_PREAUTH_REQUIRED
|
||||
|| errorCode == Krb5.KDC_ERR_PREAUTH_FAILED) {
|
||||
try {
|
||||
// RFC 4120 does not guarantee that eData is METHOD-DATA when
|
||||
// errorCode is KDC_ERR_PREAUTH_FAILED. Therefore, the parse
|
||||
// may fail.
|
||||
parsePAData(data);
|
||||
} catch (Exception e) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Unable to parse eData field of KRB-ERROR:\n" +
|
||||
new sun.misc.HexDumpEncoder().encodeBuffer(data));
|
||||
}
|
||||
IOException ioe = new IOException(
|
||||
"Unable to parse eData field of KRB-ERROR");
|
||||
ioe.initCause(e);
|
||||
throw ioe;
|
||||
}
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.println("Unknown eData field of KRB-ERROR:\n" +
|
||||
new sun.misc.HexDumpEncoder().encodeBuffer(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try parsing the data as a sequence of PA-DATA.
|
||||
* @param data the data block
|
||||
*/
|
||||
private void parsePAData(byte[] data)
|
||||
throws IOException, Asn1Exception {
|
||||
DerValue derPA = new DerValue(data);
|
||||
List<PAData> paList = new ArrayList<>();
|
||||
while (derPA.data.available() > 0) {
|
||||
// read the PA-DATA
|
||||
DerValue tmp = derPA.data.getDerValue();
|
||||
PAData pa_data = new PAData(tmp);
|
||||
paList.add(pa_data);
|
||||
if (DEBUG) {
|
||||
System.out.println(pa_data);
|
||||
}
|
||||
}
|
||||
pa = paList.toArray(new PAData[paList.size()]);
|
||||
}
|
||||
|
||||
public final Realm getClientRealm() {
|
||||
return crealm;
|
||||
}
|
||||
|
||||
public final KerberosTime getServerTime() {
|
||||
return sTime;
|
||||
}
|
||||
|
||||
public final KerberosTime getClientTime() {
|
||||
return cTime;
|
||||
}
|
||||
|
||||
public final Integer getServerMicroSeconds() {
|
||||
return suSec;
|
||||
}
|
||||
|
||||
public final Integer getClientMicroSeconds() {
|
||||
return cuSec;
|
||||
}
|
||||
|
||||
public final int getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
// access pre-auth info
|
||||
public final PAData[] getPA() {
|
||||
return pa;
|
||||
}
|
||||
|
||||
public final String getErrorString() {
|
||||
return eText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a KRBError object.
|
||||
* @param encoding a DER-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception KrbApErrException if the value read from the DER-encoded data
|
||||
* stream does not match the pre-defined value.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
*/
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
DerValue der, subDer;
|
||||
if (((encoding.getTag() & (byte)0x1F) != (byte)0x1E)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte)0x1F) == (byte)0x00) {
|
||||
|
||||
pvno = subDer.getData().getBigInteger().intValue();
|
||||
if (pvno != Krb5.PVNO)
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte)0x1F) == (byte)0x01) {
|
||||
msgType = subDer.getData().getBigInteger().intValue();
|
||||
if (msgType != Krb5.KRB_ERROR) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
cTime = KerberosTime.parse(der.getData(), (byte)0x02, true);
|
||||
if ((der.getData().peekByte() & 0x1F) == 0x03) {
|
||||
subDer = der.getData().getDerValue();
|
||||
cuSec = new Integer(subDer.getData().getBigInteger().intValue());
|
||||
}
|
||||
else cuSec = null;
|
||||
sTime = KerberosTime.parse(der.getData(), (byte)0x04, false);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte)0x1F) == (byte)0x05) {
|
||||
suSec = new Integer (subDer.getData().getBigInteger().intValue());
|
||||
}
|
||||
else throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte)0x1F) == (byte)0x06) {
|
||||
errorCode = subDer.getData().getBigInteger().intValue();
|
||||
}
|
||||
else throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
crealm = Realm.parse(der.getData(), (byte)0x07, true);
|
||||
cname = PrincipalName.parse(der.getData(), (byte)0x08, true, crealm);
|
||||
Realm realm = Realm.parse(der.getData(), (byte)0x09, false);
|
||||
sname = PrincipalName.parse(der.getData(), (byte)0x0A, false, realm);
|
||||
eText = null;
|
||||
eData = null;
|
||||
eCksum = null;
|
||||
if (der.getData().available() >0) {
|
||||
if ((der.getData().peekByte() & 0x1F) == 0x0B) {
|
||||
subDer = der.getData().getDerValue();
|
||||
eText = new KerberosString(subDer.getData().getDerValue())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
if (der.getData().available() >0) {
|
||||
if ((der.getData().peekByte() & 0x1F) == 0x0C) {
|
||||
subDer = der.getData().getDerValue();
|
||||
eData = subDer.getData().getOctetString();
|
||||
}
|
||||
}
|
||||
if (der.getData().available() >0) {
|
||||
eCksum = Checksum.parse(der.getData(), (byte)0x0D, true);
|
||||
}
|
||||
if (der.getData().available() >0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* For debug use only
|
||||
*/
|
||||
private void showDebug() {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>KRBError:");
|
||||
if (cTime != null)
|
||||
System.out.println("\t cTime is " + cTime.toDate().toString() + " " + cTime.toDate().getTime());
|
||||
if (cuSec != null) {
|
||||
System.out.println("\t cuSec is " + cuSec.intValue());
|
||||
}
|
||||
|
||||
System.out.println("\t sTime is " + sTime.toDate().toString
|
||||
() + " " + sTime.toDate().getTime());
|
||||
System.out.println("\t suSec is " + suSec);
|
||||
System.out.println("\t error code is " + errorCode);
|
||||
System.out.println("\t error Message is " + Krb5.getErrorMessage(errorCode));
|
||||
if (crealm != null) {
|
||||
System.out.println("\t crealm is " + crealm.toString());
|
||||
}
|
||||
if (cname != null) {
|
||||
System.out.println("\t cname is " + cname.toString());
|
||||
}
|
||||
if (sname != null) {
|
||||
System.out.println("\t sname is " + sname.toString());
|
||||
}
|
||||
if (eData != null) {
|
||||
System.out.println("\t eData provided.");
|
||||
}
|
||||
if (eCksum != null) {
|
||||
System.out.println("\t checksum provided.");
|
||||
}
|
||||
System.out.println("\t msgType is " + msgType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an KRBError object.
|
||||
* @return the byte array of encoded KRBError object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
|
||||
temp.putInteger(BigInteger.valueOf(pvno));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(msgType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
|
||||
|
||||
if (cTime != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), cTime.asn1Encode());
|
||||
}
|
||||
if (cuSec != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(cuSec.intValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp);
|
||||
}
|
||||
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), sTime.asn1Encode());
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(suSec.intValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(errorCode));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), temp);
|
||||
|
||||
if (crealm != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), crealm.asn1Encode());
|
||||
}
|
||||
if (cname != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), cname.asn1Encode());
|
||||
}
|
||||
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), sname.getRealm().asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), sname.asn1Encode());
|
||||
|
||||
if (eText != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putDerValue(new KerberosString(eText).toDerValue());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0B), temp);
|
||||
}
|
||||
if (eData != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putOctetString(eData);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0C), temp);
|
||||
}
|
||||
if (eCksum != null) {
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0D), eCksum.asn1Encode());
|
||||
}
|
||||
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1E), temp);
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof KRBError)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KRBError other = (KRBError)obj;
|
||||
return pvno == other.pvno &&
|
||||
msgType == other.msgType &&
|
||||
isEqual(cTime, other.cTime) &&
|
||||
isEqual(cuSec, other.cuSec) &&
|
||||
isEqual(sTime, other.sTime) &&
|
||||
isEqual(suSec, other.suSec) &&
|
||||
errorCode == other.errorCode &&
|
||||
isEqual(crealm, other.crealm) &&
|
||||
isEqual(cname, other.cname) &&
|
||||
isEqual(sname, other.sname) &&
|
||||
isEqual(eText, other.eText) &&
|
||||
java.util.Arrays.equals(eData, other.eData) &&
|
||||
isEqual(eCksum, other.eCksum);
|
||||
}
|
||||
|
||||
private static boolean isEqual(Object a, Object b) {
|
||||
return (a == null)?(b == null):(a.equals(b));
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
int result = 17;
|
||||
result = 37 * result + pvno;
|
||||
result = 37 * result + msgType;
|
||||
if (cTime != null) result = 37 * result + cTime.hashCode();
|
||||
if (cuSec != null) result = 37 * result + cuSec.hashCode();
|
||||
if (sTime != null) result = 37 * result + sTime.hashCode();
|
||||
if (suSec != null) result = 37 * result + suSec.hashCode();
|
||||
result = 37 * result + errorCode;
|
||||
if (crealm != null) result = 37 * result + crealm.hashCode();
|
||||
if (cname != null) result = 37 * result + cname.hashCode();
|
||||
if (sname != null) result = 37 * result + sname.hashCode();
|
||||
if (eText != null) result = 37 * result + eText.hashCode();
|
||||
result = 37 * result + Arrays.hashCode(eData);
|
||||
if (eCksum != null) result = 37 * result + eCksum.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
143
jdkSrc/jdk8/sun/security/krb5/internal/KRBPriv.java
Normal file
143
jdkSrc/jdk8/sun/security/krb5/internal/KRBPriv.java
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KRB-PRIV type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
|
||||
* pvno [0] INTEGER (5),
|
||||
* msg-type [1] INTEGER (21),
|
||||
* -- NOTE: there is no [2] tag
|
||||
* enc-part [3] EncryptedData -- EncKrbPrivPart
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class KRBPriv {
|
||||
public int pvno;
|
||||
public int msgType;
|
||||
public EncryptedData encPart;
|
||||
|
||||
public KRBPriv(EncryptedData new_encPart) {
|
||||
pvno = Krb5.PVNO;
|
||||
msgType = Krb5.KRB_PRIV;
|
||||
encPart = new_encPart;
|
||||
}
|
||||
|
||||
public KRBPriv(byte[] data) throws Asn1Exception,
|
||||
KrbApErrException, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public KRBPriv(DerValue encoding) throws Asn1Exception,
|
||||
KrbApErrException, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes an KRBPriv object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception KrbApErrException if the value read from the DER-encoded data
|
||||
* stream does not match the pre-defined value.
|
||||
*/
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
KrbApErrException, IOException {
|
||||
DerValue der, subDer;
|
||||
if (((encoding.getTag() & (byte)0x1F) != (byte)0x15)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true))
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) == 0x00) {
|
||||
pvno = subDer.getData().getBigInteger().intValue();
|
||||
if (pvno != Krb5.PVNO) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) == 0x01) {
|
||||
msgType = subDer.getData().getBigInteger().intValue();
|
||||
if (msgType != Krb5.KRB_PRIV)
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
encPart = EncryptedData.parse(der.getData(), (byte)0x03, false);
|
||||
if (der.getData().available() >0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an KRBPriv object.
|
||||
* @return byte array of encoded EncAPRepPart object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream temp, bytes;
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(pvno));
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(msgType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), encPart.asn1Encode());
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x15), temp);
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
146
jdkSrc/jdk8/sun/security/krb5/internal/KRBSafe.java
Normal file
146
jdkSrc/jdk8/sun/security/krb5/internal/KRBSafe.java
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.Checksum;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.RealmException;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KRBSafe type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
|
||||
* pvno [0] INTEGER (5),
|
||||
* msg-type [1] INTEGER (20),
|
||||
* safe-body [2] KRB-SAFE-BODY,
|
||||
* cksum [3] Checksum
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specifications available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class KRBSafe {
|
||||
public int pvno;
|
||||
public int msgType;
|
||||
public KRBSafeBody safeBody;
|
||||
public Checksum cksum;
|
||||
|
||||
public KRBSafe(KRBSafeBody new_safeBody, Checksum new_cksum) {
|
||||
pvno = Krb5.PVNO;
|
||||
msgType = Krb5.KRB_SAFE;
|
||||
safeBody = new_safeBody;
|
||||
cksum = new_cksum;
|
||||
}
|
||||
|
||||
public KRBSafe(byte[] data) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public KRBSafe(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an KRBSafe object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
* @exception KrbApErrException if the value read from the DER-encoded data
|
||||
* stream does not match the pre-defined value.
|
||||
*/
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
DerValue der, subDer;
|
||||
if (((encoding.getTag() & (byte)0x1F) != (byte)0x14)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true))
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) == 0x00) {
|
||||
pvno = subDer.getData().getBigInteger().intValue();
|
||||
if (pvno != Krb5.PVNO)
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & 0x1F) == 0x01) {
|
||||
msgType = subDer.getData().getBigInteger().intValue();
|
||||
if (msgType != Krb5.KRB_SAFE)
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
|
||||
}
|
||||
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
safeBody = KRBSafeBody.parse(der.getData(), (byte)0x02, false);
|
||||
cksum = Checksum.parse(der.getData(), (byte)0x03, false);
|
||||
if (der.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an KRBSafe object.
|
||||
* @return byte array of encoded KRBSafe object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(pvno));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(msgType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), safeBody.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), cksum.asn1Encode());
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x14), temp);
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
}
|
||||
177
jdkSrc/jdk8/sun/security/krb5/internal/KRBSafeBody.java
Normal file
177
jdkSrc/jdk8/sun/security/krb5/internal/KRBSafeBody.java
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KRBSafeBody type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KRB-SAFE-BODY ::= SEQUENCE {
|
||||
* user-data [0] OCTET STRING,
|
||||
* timestamp [1] KerberosTime OPTIONAL,
|
||||
* usec [2] Microseconds OPTIONAL,
|
||||
* seq-number [3] UInt32 OPTIONAL,
|
||||
* s-address [4] HostAddress,
|
||||
* r-address [5] HostAddress OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class KRBSafeBody {
|
||||
public byte[] userData = null;
|
||||
public KerberosTime timestamp; //optional
|
||||
public Integer usec; //optional
|
||||
public Integer seqNumber; //optional
|
||||
public HostAddress sAddress;
|
||||
public HostAddress rAddress; //optional
|
||||
|
||||
public KRBSafeBody(
|
||||
byte[] new_userData,
|
||||
KerberosTime new_timestamp,
|
||||
Integer new_usec,
|
||||
Integer new_seqNumber,
|
||||
HostAddress new_sAddress,
|
||||
HostAddress new_rAddress
|
||||
) {
|
||||
if (new_userData != null) {
|
||||
userData = new_userData.clone();
|
||||
}
|
||||
timestamp = new_timestamp;
|
||||
usec = new_usec;
|
||||
seqNumber = new_seqNumber;
|
||||
sAddress = new_sAddress;
|
||||
rAddress = new_rAddress;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a KRBSafeBody object.
|
||||
* @param encoding a Der-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public KRBSafeBody(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der;
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x00) {
|
||||
userData = der.getData().getOctetString();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
timestamp = KerberosTime.parse(encoding.getData(), (byte)0x01, true);
|
||||
if ((encoding.getData().peekByte() & 0x1F) == 0x02) {
|
||||
der = encoding.getData().getDerValue();
|
||||
usec = new Integer(der.getData().getBigInteger().intValue());
|
||||
}
|
||||
if ((encoding.getData().peekByte() & 0x1F) == 0x03) {
|
||||
der = encoding.getData().getDerValue();
|
||||
seqNumber = new Integer(der.getData().getBigInteger().intValue());
|
||||
}
|
||||
sAddress = HostAddress.parse(encoding.getData(), (byte)0x04, false);
|
||||
if (encoding.getData().available() > 0)
|
||||
rAddress = HostAddress.parse(encoding.getData(), (byte)0x05, true);
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an KRBSafeBody object.
|
||||
* @return the byte array of encoded KRBSafeBody object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putOctetString(userData);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
if (timestamp != null)
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), timestamp.asn1Encode());
|
||||
if (usec != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(usec.intValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp);
|
||||
}
|
||||
if (seqNumber != null) {
|
||||
temp = new DerOutputStream();
|
||||
// encode as an unsigned integer (UInt32)
|
||||
temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp);
|
||||
}
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), sAddress.asn1Encode());
|
||||
if (rAddress != null)
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a KRBSafeBody from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicates if this data field is optional
|
||||
* @return an instance of KRBSafeBody.
|
||||
*
|
||||
*/
|
||||
public static KRBSafeBody parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F))
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new KRBSafeBody(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
45
jdkSrc/jdk8/sun/security/krb5/internal/KdcErrException.java
Normal file
45
jdkSrc/jdk8/sun/security/krb5/internal/KdcErrException.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
public class KdcErrException extends sun.security.krb5.KrbException {
|
||||
|
||||
private static final long serialVersionUID = -8788186031117310306L;
|
||||
|
||||
public KdcErrException(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
public KdcErrException(int i, String s) {
|
||||
super(i, s);
|
||||
}
|
||||
}
|
||||
315
jdkSrc/jdk8/sun/security/krb5/internal/KerberosTime.java
Normal file
315
jdkSrc/jdk8/sun/security/krb5/internal/KerberosTime.java
Normal file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.Config;
|
||||
import sun.security.krb5.KrbException;
|
||||
import sun.security.util.DerInputStream;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KerberosTime type. This is an immutable class.
|
||||
*
|
||||
* {@code KerberosTime ::= GeneralizedTime} -- with no fractional seconds
|
||||
*
|
||||
* The timestamps used in Kerberos are encoded as GeneralizedTimes. A
|
||||
* KerberosTime value shall not include any fractional portions of the
|
||||
* seconds. As required by the DER, it further shall not include any
|
||||
* separators, and it shall specify the UTC time zone (Z).
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*
|
||||
* The implementation also includes the microseconds info so that the
|
||||
* same class can be used as a precise timestamp in Authenticator etc.
|
||||
*/
|
||||
|
||||
public class KerberosTime {
|
||||
|
||||
private final long kerberosTime; // milliseconds since epoch, Date.getTime()
|
||||
private final int microSeconds; // last 3 digits of the real microsecond
|
||||
|
||||
// The time when this class is loaded. Used in setNow()
|
||||
private static long initMilli = System.currentTimeMillis();
|
||||
private static long initMicro = System.nanoTime() / 1000;
|
||||
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
// Do not make this public. It's a little confusing that micro
|
||||
// is only the last 3 digits of microsecond.
|
||||
private KerberosTime(long time, int micro) {
|
||||
kerberosTime = time;
|
||||
microSeconds = micro;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a KerberosTime object from milliseconds since epoch.
|
||||
*/
|
||||
public KerberosTime(long time) {
|
||||
this(time, 0);
|
||||
}
|
||||
|
||||
// This constructor is used in the native code
|
||||
// src/windows/native/sun/security/krb5/NativeCreds.c
|
||||
public KerberosTime(String time) throws Asn1Exception {
|
||||
this(toKerberosTime(time), 0);
|
||||
}
|
||||
|
||||
private static long toKerberosTime(String time) throws Asn1Exception {
|
||||
// ASN.1 GeneralizedTime format:
|
||||
|
||||
// "19700101000000Z"
|
||||
// | | | | | | |
|
||||
// 0 4 6 8 | | |
|
||||
// 10 | |
|
||||
// 12 |
|
||||
// 14
|
||||
|
||||
if (time.length() != 15)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_TIMEFORMAT);
|
||||
if (time.charAt(14) != 'Z')
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_TIMEFORMAT);
|
||||
int year = Integer.parseInt(time.substring(0, 4));
|
||||
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||
calendar.clear(); // so that millisecond is zero
|
||||
calendar.set(year,
|
||||
Integer.parseInt(time.substring(4, 6)) - 1,
|
||||
Integer.parseInt(time.substring(6, 8)),
|
||||
Integer.parseInt(time.substring(8, 10)),
|
||||
Integer.parseInt(time.substring(10, 12)),
|
||||
Integer.parseInt(time.substring(12, 14)));
|
||||
return calendar.getTimeInMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a KerberosTime object from a Date object.
|
||||
*/
|
||||
public KerberosTime(Date time) {
|
||||
this(time.getTime(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a KerberosTime object from an Instant object
|
||||
*/
|
||||
public KerberosTime(Instant instant) {
|
||||
this(instant.getEpochSecond()*1000 + instant.getNano()/1000000L,
|
||||
instant.getNano()/1000%1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a KerberosTime object for now. It uses System.nanoTime()
|
||||
* to get a more precise time than "new Date()".
|
||||
*/
|
||||
public static KerberosTime now() {
|
||||
long newMilli = System.currentTimeMillis();
|
||||
long newMicro = System.nanoTime() / 1000;
|
||||
long microElapsed = newMicro - initMicro;
|
||||
long calcMilli = initMilli + microElapsed/1000;
|
||||
if (calcMilli - newMilli > 100 || newMilli - calcMilli > 100) {
|
||||
if (DEBUG) {
|
||||
System.out.println("System time adjusted");
|
||||
}
|
||||
initMilli = newMilli;
|
||||
initMicro = newMicro;
|
||||
return new KerberosTime(newMilli, 0);
|
||||
} else {
|
||||
return new KerberosTime(calcMilli, (int)(microElapsed % 1000));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of KerberosTime object.
|
||||
* @return a string representation of this object.
|
||||
*/
|
||||
public String toGeneralizedTimeString() {
|
||||
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||
calendar.clear();
|
||||
|
||||
calendar.setTimeInMillis(kerberosTime);
|
||||
return String.format("%04d%02d%02d%02d%02d%02dZ",
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH) + 1,
|
||||
calendar.get(Calendar.DAY_OF_MONTH),
|
||||
calendar.get(Calendar.HOUR_OF_DAY),
|
||||
calendar.get(Calendar.MINUTE),
|
||||
calendar.get(Calendar.SECOND));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this object to a byte array.
|
||||
* @return a byte array of encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.putGeneralizedTime(this.toDate());
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return kerberosTime;
|
||||
}
|
||||
|
||||
public Date toDate() {
|
||||
return new Date(kerberosTime);
|
||||
}
|
||||
|
||||
public int getMicroSeconds() {
|
||||
Long temp_long = new Long((kerberosTime % 1000L) * 1000L);
|
||||
return temp_long.intValue() + microSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new KerberosTime object with the original seconds
|
||||
* and the given microseconds.
|
||||
*/
|
||||
public KerberosTime withMicroSeconds(int usec) {
|
||||
return new KerberosTime(
|
||||
kerberosTime - kerberosTime%1000L + usec/1000L,
|
||||
usec%1000);
|
||||
}
|
||||
|
||||
private boolean inClockSkew(int clockSkew) {
|
||||
return java.lang.Math.abs(kerberosTime - System.currentTimeMillis())
|
||||
<= clockSkew * 1000L;
|
||||
}
|
||||
|
||||
public boolean inClockSkew() {
|
||||
return inClockSkew(getDefaultSkew());
|
||||
}
|
||||
|
||||
public boolean greaterThanWRTClockSkew(KerberosTime time, int clockSkew) {
|
||||
if ((kerberosTime - time.kerberosTime) > clockSkew * 1000L)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean greaterThanWRTClockSkew(KerberosTime time) {
|
||||
return greaterThanWRTClockSkew(time, getDefaultSkew());
|
||||
}
|
||||
|
||||
public boolean greaterThan(KerberosTime time) {
|
||||
return kerberosTime > time.kerberosTime ||
|
||||
kerberosTime == time.kerberosTime &&
|
||||
microSeconds > time.microSeconds;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof KerberosTime)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return kerberosTime == ((KerberosTime)obj).kerberosTime &&
|
||||
microSeconds == ((KerberosTime)obj).microSeconds;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = 37 * 17 + (int)(kerberosTime ^ (kerberosTime >>> 32));
|
||||
return result * 17 + microSeconds;
|
||||
}
|
||||
|
||||
public boolean isZero() {
|
||||
return kerberosTime == 0 && microSeconds == 0;
|
||||
}
|
||||
|
||||
public int getSeconds() {
|
||||
Long temp_long = new Long(kerberosTime / 1000L);
|
||||
return temp_long.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a kerberostime from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @param data the Der input stream value, which contains
|
||||
* one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicates if this data field is optional
|
||||
* @return an instance of KerberosTime.
|
||||
*
|
||||
*/
|
||||
public static KerberosTime parse(
|
||||
DerInputStream data, byte explicitTag, boolean optional)
|
||||
throws Asn1Exception, IOException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F)!= explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
Date temp = subDer.getGeneralizedTime();
|
||||
return new KerberosTime(temp.getTime(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDefaultSkew() {
|
||||
int tdiff = Krb5.DEFAULT_ALLOWABLE_CLOCKSKEW;
|
||||
try {
|
||||
if ((tdiff = Config.getInstance().getIntValue(
|
||||
"libdefaults", "clockskew"))
|
||||
== Integer.MIN_VALUE) { //value is not defined
|
||||
tdiff = Krb5.DEFAULT_ALLOWABLE_CLOCKSKEW;
|
||||
}
|
||||
} catch (KrbException e) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Exception in getting clockskew from " +
|
||||
"Configuration " +
|
||||
"using default value " +
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
return tdiff;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return toGeneralizedTimeString();
|
||||
}
|
||||
}
|
||||
399
jdkSrc/jdk8/sun/security/krb5/internal/Krb5.java
Normal file
399
jdkSrc/jdk8/sun/security/krb5/internal/Krb5.java
Normal file
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
// Constants and other defined values from RFC 4120
|
||||
|
||||
public class Krb5 {
|
||||
|
||||
//Recommended KDC values
|
||||
public static final int DEFAULT_ALLOWABLE_CLOCKSKEW = 5 * 60; //5 minutes
|
||||
public static final int DEFAULT_MINIMUM_LIFETIME = 5 * 60; //5 minutes
|
||||
public static final int DEFAULT_MAXIMUM_RENEWABLE_LIFETIME = 7 * 24 * 60 * 60; //1 week
|
||||
public static final int DEFAULT_MAXIMUM_TICKET_LIFETIME = 24 * 60 * 60; //1 day
|
||||
public static final boolean DEFAULT_FORWARDABLE_ALLOWED = true;
|
||||
public static final boolean DEFAULT_PROXIABLE_ALLOWED = true;
|
||||
public static final boolean DEFAULT_POSTDATE_ALLOWED = true;
|
||||
public static final boolean DEFAULT_RENEWABLE_ALLOWED = true;
|
||||
public static final boolean AP_EMPTY_ADDRESSES_ALLOWED = true;
|
||||
|
||||
//AP_REQ Options
|
||||
|
||||
public static final int AP_OPTS_RESERVED = 0;
|
||||
public static final int AP_OPTS_USE_SESSION_KEY = 1;
|
||||
public static final int AP_OPTS_MUTUAL_REQUIRED = 2;
|
||||
public static final int AP_OPTS_MAX = 31;
|
||||
|
||||
//Ticket Flags
|
||||
|
||||
public static final int TKT_OPTS_RESERVED = 0;
|
||||
public static final int TKT_OPTS_FORWARDABLE = 1;
|
||||
public static final int TKT_OPTS_FORWARDED = 2;
|
||||
public static final int TKT_OPTS_PROXIABLE = 3;
|
||||
public static final int TKT_OPTS_PROXY = 4;
|
||||
public static final int TKT_OPTS_MAY_POSTDATE = 5;
|
||||
public static final int TKT_OPTS_POSTDATED = 6;
|
||||
public static final int TKT_OPTS_INVALID = 7;
|
||||
public static final int TKT_OPTS_RENEWABLE = 8;
|
||||
public static final int TKT_OPTS_INITIAL = 9;
|
||||
public static final int TKT_OPTS_PRE_AUTHENT = 10;
|
||||
public static final int TKT_OPTS_HW_AUTHENT = 11;
|
||||
public static final int TKT_OPTS_DELEGATE = 13;
|
||||
public static final int TKT_OPTS_ENC_PA_REP = 15;
|
||||
public static final int TKT_OPTS_MAX = 31;
|
||||
|
||||
// KDC Options
|
||||
// (option values defined in KDCOptions.java)
|
||||
public static final int KDC_OPTS_MAX = 31;
|
||||
|
||||
// KerberosFlags
|
||||
public static final int KRB_FLAGS_MAX = 31;
|
||||
|
||||
//Last Request types
|
||||
|
||||
public static final int LRTYPE_NONE = 0;
|
||||
public static final int LRTYPE_TIME_OF_INITIAL_TGT = 1;
|
||||
public static final int LRTYPE_TIME_OF_INITIAL_REQ = 2;
|
||||
public static final int LRTYPE_TIME_OF_NEWEST_TGT = 3;
|
||||
public static final int LRTYPE_TIME_OF_LAST_RENEWAL = 4;
|
||||
public static final int LRTYPE_TIME_OF_LAST_REQ = 5;
|
||||
|
||||
//Host address lengths
|
||||
|
||||
public static final int ADDR_LEN_INET = 4;
|
||||
public static final int ADDR_LEN_CHAOS = 2;
|
||||
public static final int ADDR_LEN_OSI = 0; //means variable
|
||||
public static final int ADDR_LEN_XNS = 6;
|
||||
public static final int ADDR_LEN_APPLETALK = 3;
|
||||
public static final int ADDR_LEN_DECNET = 2;
|
||||
|
||||
//Host address types
|
||||
|
||||
public static final int ADDRTYPE_UNIX = 1; // Local
|
||||
public static final int ADDRTYPE_INET = 2; // Internet
|
||||
public static final int ADDRTYPE_IMPLINK = 3; // Arpanet
|
||||
public static final int ADDRTYPE_PUP = 4; // PUP
|
||||
public static final int ADDRTYPE_CHAOS = 5; // CHAOS
|
||||
public static final int ADDRTYPE_XNS = 6; // XEROX Network Services
|
||||
public static final int ADDRTYPE_IPX = 6; // IPX
|
||||
public static final int ADDRTYPE_ISO = 7; // ISO
|
||||
public static final int ADDRTYPE_ECMA = 8; // European Computer Manufacturers
|
||||
public static final int ADDRTYPE_DATAKIT = 9; // Datakit
|
||||
public static final int ADDRTYPE_CCITT = 10; // CCITT
|
||||
public static final int ADDRTYPE_SNA = 11; // SNA
|
||||
public static final int ADDRTYPE_DECNET = 12; // DECnet
|
||||
public static final int ADDRTYPE_DLI = 13; // Direct Data Link Interface
|
||||
public static final int ADDRTYPE_LAT = 14; // LAT
|
||||
public static final int ADDRTYPE_HYLINK = 15; // NSC Hyperchannel
|
||||
public static final int ADDRTYPE_APPLETALK = 16; // AppleTalk
|
||||
public static final int ADDRTYPE_NETBIOS = 17; // NetBios
|
||||
public static final int ADDRTYPE_VOICEVIEW = 18; // VoiceView
|
||||
public static final int ADDRTYPE_FIREFOX = 19; // Firefox
|
||||
public static final int ADDRTYPE_BAN = 21; // Banyan
|
||||
public static final int ADDRTYPE_ATM = 22; // ATM
|
||||
public static final int ADDRTYPE_INET6 = 24; // Internet Protocol V6
|
||||
|
||||
//IP Transport UDP Port for KDC Messages
|
||||
|
||||
public static final int KDC_INET_DEFAULT_PORT = 88;
|
||||
|
||||
// number of retries before giving up
|
||||
|
||||
public static final int KDC_RETRY_LIMIT = 3;
|
||||
public static final int KDC_DEFAULT_UDP_PREF_LIMIT = 1465;
|
||||
public static final int KDC_HARD_UDP_LIMIT = 32700;
|
||||
|
||||
//OSI authentication mechanism OID
|
||||
|
||||
//public static final int[] OSI_AUTH_MECH_TYPE = { /*iso*/ 1, /*org*/ 3,
|
||||
// /*dod*/ 5, /*internet*/ 1, /*security*/ 5, /*kerberosv5*/ 2 };
|
||||
|
||||
//Protocol constants and associated values
|
||||
|
||||
//Key Types
|
||||
public static final int KEYTYPE_NULL = 0;
|
||||
public static final int KEYTYPE_DES = 1;
|
||||
|
||||
public static final int KEYTYPE_DES3 = 2;
|
||||
public static final int KEYTYPE_AES = 3;
|
||||
public static final int KEYTYPE_ARCFOUR_HMAC = 4;
|
||||
|
||||
|
||||
//----------------------------------------+-----------------
|
||||
// padata type |padata-type value
|
||||
//----------------------------------------+-----------------
|
||||
public static final int PA_TGS_REQ = 1;
|
||||
public static final int PA_ENC_TIMESTAMP = 2;
|
||||
public static final int PA_PW_SALT = 3;
|
||||
|
||||
// new preauth types
|
||||
public static final int PA_ETYPE_INFO = 11;
|
||||
public static final int PA_ETYPE_INFO2 = 19;
|
||||
|
||||
// S4U2user info
|
||||
public static final int PA_FOR_USER = 129;
|
||||
public static final int PA_PAC_OPTIONS = 167;
|
||||
|
||||
// FAST (RFC 6806)
|
||||
public static final int PA_REQ_ENC_PA_REP = 149;
|
||||
|
||||
//-------------------------------+-------------
|
||||
//authorization data type |ad-type value
|
||||
//-------------------------------+-------------
|
||||
//reserved values 0-63
|
||||
public static final int OSF_DCE = 64;
|
||||
public static final int SESAME = 65;
|
||||
|
||||
//----------------------------------------------+-----------------
|
||||
//alternate authentication type |method-type value
|
||||
//----------------------------------------------+-----------------
|
||||
// reserved values 0-63
|
||||
public static final int ATT_CHALLENGE_RESPONSE = 64;
|
||||
|
||||
//--------------------------------------------+-------------
|
||||
//transited encoding type |tr-type value
|
||||
//--------------------------------------------+-------------
|
||||
public static final int DOMAIN_X500_COMPRESS = 1;
|
||||
// reserved values all others
|
||||
|
||||
//----------------------------+-------+-----------------------------------------
|
||||
// Label |Value |Meaning
|
||||
//----------------------------+-------+-----------------------------------------
|
||||
public static final int PVNO = 5; // current Kerberos protocol version number
|
||||
public static final int AUTHNETICATOR_VNO = 5; // current authenticator version number
|
||||
public static final int TICKET_VNO = 5; // current ticket version number
|
||||
|
||||
//message types
|
||||
|
||||
// there are several message sub-components not included here
|
||||
public static final int KRB_AS_REQ = 10; //Request for initial authentication
|
||||
public static final int KRB_AS_REP = 11; //Response to KRB_AS_REQ request
|
||||
public static final int KRB_TGS_REQ = 12; //Request for authentication based on TGT
|
||||
public static final int KRB_TGS_REP = 13; //Response to KRB_TGS_REQ request
|
||||
public static final int KRB_AP_REQ = 14; //application request to server
|
||||
public static final int KRB_AP_REP = 15; //Response to KRB_AP_REQ_MUTUAL
|
||||
public static final int KRB_SAFE = 20; //Safe (checksummed) application message
|
||||
public static final int KRB_PRIV = 21; //Private (encrypted) application message
|
||||
public static final int KRB_CRED = 22; //Private (encrypted) message to forward credentials
|
||||
public static final int KRB_ERROR = 30; //Error response
|
||||
|
||||
//message component types
|
||||
|
||||
public static final int KRB_TKT = 1; //Ticket
|
||||
public static final int KRB_AUTHENTICATOR = 2; //Authenticator
|
||||
public static final int KRB_ENC_TKT_PART = 3; //Encrypted ticket part
|
||||
public static final int KRB_ENC_AS_REP_PART = 25; //Encrypted initial authentication part
|
||||
public static final int KRB_ENC_TGS_REP_PART = 26; //Encrypted TGS request part
|
||||
public static final int KRB_ENC_AP_REP_PART = 27; //Encrypted application request part
|
||||
public static final int KRB_ENC_KRB_PRIV_PART = 28; //Encrypted application message part
|
||||
public static final int KRB_ENC_KRB_CRED_PART = 29; //Encrypted credentials forward part
|
||||
|
||||
|
||||
//error codes
|
||||
|
||||
public static final int KDC_ERR_NONE = 0; //No error
|
||||
public static final int KDC_ERR_NAME_EXP = 1; //Client's entry in database expired
|
||||
public static final int KDC_ERR_SERVICE_EXP = 2; //Server's entry in database has expired
|
||||
public static final int KDC_ERR_BAD_PVNO = 3; //Requested protocol version number not supported
|
||||
public static final int KDC_ERR_C_OLD_MAST_KVNO = 4; //Client's key encrypted in old master key
|
||||
public static final int KDC_ERR_S_OLD_MAST_KVNO = 5; //Server's key encrypted in old master key
|
||||
public static final int KDC_ERR_C_PRINCIPAL_UNKNOWN = 6; //Client not found in Kerberos database
|
||||
public static final int KDC_ERR_S_PRINCIPAL_UNKNOWN = 7; //Server not found in Kerberos database
|
||||
public static final int KDC_ERR_PRINCIPAL_NOT_UNIQUE = 8; //Multiple principal entries in database
|
||||
public static final int KDC_ERR_NULL_KEY = 9; //The client or server has a null key
|
||||
public static final int KDC_ERR_CANNOT_POSTDATE = 10; //Ticket not eligible for postdating
|
||||
public static final int KDC_ERR_NEVER_VALID = 11; //Requested start time is later than end time
|
||||
public static final int KDC_ERR_POLICY = 12; //KDC policy rejects request
|
||||
public static final int KDC_ERR_BADOPTION = 13; //KDC cannot accommodate requested option
|
||||
public static final int KDC_ERR_ETYPE_NOSUPP = 14; //KDC has no support for encryption type
|
||||
public static final int KDC_ERR_SUMTYPE_NOSUPP = 15; //KDC has no support for checksum type
|
||||
public static final int KDC_ERR_PADATA_TYPE_NOSUPP = 16; //KDC has no support for padata type
|
||||
public static final int KDC_ERR_TRTYPE_NOSUPP = 17; //KDC has no support for transited type
|
||||
public static final int KDC_ERR_CLIENT_REVOKED = 18; //Clients credentials have been revoked
|
||||
public static final int KDC_ERR_SERVICE_REVOKED = 19; //Credentials for server have been revoked
|
||||
public static final int KDC_ERR_TGT_REVOKED = 20; //TGT has been revoked
|
||||
public static final int KDC_ERR_CLIENT_NOTYET = 21; //Client not yet valid - try again later
|
||||
public static final int KDC_ERR_SERVICE_NOTYET = 22; //Server not yet valid - try again later
|
||||
public static final int KDC_ERR_KEY_EXPIRED = 23; //Password has expired - change password to reset
|
||||
public static final int KDC_ERR_PREAUTH_FAILED = 24; //Pre-authentication information was invalid
|
||||
public static final int KDC_ERR_PREAUTH_REQUIRED = 25; //Additional pre-authentication required
|
||||
public static final int KRB_AP_ERR_BAD_INTEGRITY = 31; //Integrity check on decrypted field failed
|
||||
public static final int KRB_AP_ERR_TKT_EXPIRED = 32; //Ticket expired
|
||||
public static final int KRB_AP_ERR_TKT_NYV = 33; //Ticket not yet valid
|
||||
public static final int KRB_AP_ERR_REPEAT = 34; //Request is a replay
|
||||
public static final int KRB_AP_ERR_NOT_US = 35; //The ticket isn't for us
|
||||
public static final int KRB_AP_ERR_BADMATCH = 36; //Ticket and authenticator don't match
|
||||
public static final int KRB_AP_ERR_SKEW = 37; //Clock skew too great
|
||||
public static final int KRB_AP_ERR_BADADDR = 38; //Incorrect net address
|
||||
public static final int KRB_AP_ERR_BADVERSION = 39; //Protocol version mismatch
|
||||
public static final int KRB_AP_ERR_MSG_TYPE = 40; //Invalid msg type
|
||||
public static final int KRB_AP_ERR_MODIFIED = 41; //Message stream modified
|
||||
public static final int KRB_AP_ERR_BADORDER = 42; //Message out of order
|
||||
public static final int KRB_AP_ERR_BADKEYVER = 44; //Specified version of key is not available
|
||||
public static final int KRB_AP_ERR_NOKEY = 45; //Service key not available
|
||||
public static final int KRB_AP_ERR_MUT_FAIL = 46; //Mutual authentication failed
|
||||
public static final int KRB_AP_ERR_BADDIRECTION = 47; //Incorrect message direction
|
||||
public static final int KRB_AP_ERR_METHOD = 48; //Alternative authentication method required
|
||||
public static final int KRB_AP_ERR_BADSEQ = 49; //Incorrect sequence number in message
|
||||
public static final int KRB_AP_ERR_INAPP_CKSUM = 50; //Inappropriate type of checksum in message
|
||||
public static final int KRB_ERR_RESPONSE_TOO_BIG = 52; //Response too big for UDP, retry with TCP
|
||||
public static final int KRB_ERR_GENERIC = 60; //Generic error (description in e-text)
|
||||
public static final int KRB_ERR_FIELD_TOOLONG = 61; //Field is too long for this implementation
|
||||
public static final int KRB_ERR_WRONG_REALM = 68; //Wrong realm
|
||||
public static final int KRB_CRYPTO_NOT_SUPPORT = 100; //Client does not support this crypto type
|
||||
public static final int KRB_AP_ERR_NOREALM = 62;
|
||||
public static final int KRB_AP_ERR_GEN_CRED = 63;
|
||||
// public static final int KRB_AP_ERR_CKSUM_NOKEY =101; //Lack of the key to generate the checksum
|
||||
// error codes specific to this implementation
|
||||
public static final int KRB_AP_ERR_REQ_OPTIONS = 101; //Invalid TGS_REQ
|
||||
public static final int API_INVALID_ARG = 400; //Invalid argument
|
||||
|
||||
public static final int BITSTRING_SIZE_INVALID = 500; //BitString size does not match input byte array
|
||||
public static final int BITSTRING_INDEX_OUT_OF_BOUNDS = 501; //BitString bit index does not fall within size
|
||||
public static final int BITSTRING_BAD_LENGTH = 502; //BitString length is wrong for the expected type
|
||||
|
||||
public static final int REALM_ILLCHAR = 600; //Illegal character in realm name; one of: '/', ':', '\0'
|
||||
public static final int REALM_NULL = 601; //Null realm name
|
||||
|
||||
public static final int ASN1_BAD_TIMEFORMAT = 900; //Input not in GeneralizedTime format
|
||||
public static final int ASN1_MISSING_FIELD = 901; //Structure is missing a required field
|
||||
public static final int ASN1_MISPLACED_FIELD = 902; //Unexpected field number
|
||||
public static final int ASN1_TYPE_MISMATCH = 903; //Type numbers are inconsistent
|
||||
public static final int ASN1_OVERFLOW = 904; //Value too large
|
||||
public static final int ASN1_OVERRUN = 905; //Encoding ended unexpectedly
|
||||
public static final int ASN1_BAD_ID = 906; //Identifier doesn't match expected value
|
||||
public static final int ASN1_BAD_LENGTH = 907; //Length doesn't match expected value
|
||||
public static final int ASN1_BAD_FORMAT = 908; //Badly-formatted encoding
|
||||
public static final int ASN1_PARSE_ERROR = 909; //Parse error
|
||||
public static final int ASN1_BAD_CLASS = 910; //Bad class number
|
||||
public static final int ASN1_BAD_TYPE = 911; //Bad type number
|
||||
public static final int ASN1_BAD_TAG = 912; //Bad tag number
|
||||
public static final int ASN1_UNSUPPORTED_TYPE = 913; //Unsupported ASN.1 type encountered
|
||||
public static final int ASN1_CANNOT_ENCODE = 914; //Encoding failed due to invalid parameter(s)
|
||||
|
||||
private static Hashtable<Integer,String> errMsgList;
|
||||
|
||||
public static String getErrorMessage(int i) {
|
||||
return errMsgList.get(i);
|
||||
}
|
||||
|
||||
|
||||
public static final boolean DEBUG =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetBooleanAction("sun.security.krb5.debug"));
|
||||
|
||||
static {
|
||||
errMsgList = new Hashtable<Integer,String> ();
|
||||
errMsgList.put(KDC_ERR_NONE, "No error");
|
||||
errMsgList.put(KDC_ERR_NAME_EXP, "Client's entry in database expired");
|
||||
errMsgList.put(KDC_ERR_SERVICE_EXP, "Server's entry in database has expired");
|
||||
errMsgList.put(KDC_ERR_BAD_PVNO, "Requested protocol version number not supported");
|
||||
errMsgList.put(KDC_ERR_C_OLD_MAST_KVNO, "Client's key encrypted in old master key");
|
||||
errMsgList.put(KDC_ERR_S_OLD_MAST_KVNO, "Server's key encrypted in old master key");
|
||||
errMsgList.put(KDC_ERR_C_PRINCIPAL_UNKNOWN, "Client not found in Kerberos database");
|
||||
errMsgList.put(KDC_ERR_S_PRINCIPAL_UNKNOWN, "Server not found in Kerberos database");
|
||||
errMsgList.put(KDC_ERR_PRINCIPAL_NOT_UNIQUE, "Multiple principal entries in database");
|
||||
errMsgList.put(KDC_ERR_NULL_KEY, "The client or server has a null key");
|
||||
errMsgList.put(KDC_ERR_CANNOT_POSTDATE, "Ticket not eligible for postdating");
|
||||
errMsgList.put(KDC_ERR_NEVER_VALID, "Requested start time is later than end time");
|
||||
errMsgList.put(KDC_ERR_POLICY, "KDC policy rejects request");
|
||||
errMsgList.put(KDC_ERR_BADOPTION, "KDC cannot accommodate requested option");
|
||||
errMsgList.put(KDC_ERR_ETYPE_NOSUPP, "KDC has no support for encryption type");
|
||||
errMsgList.put(KDC_ERR_SUMTYPE_NOSUPP, "KDC has no support for checksum type");
|
||||
errMsgList.put(KDC_ERR_PADATA_TYPE_NOSUPP, "KDC has no support for padata type");
|
||||
errMsgList.put(KDC_ERR_TRTYPE_NOSUPP, "KDC has no support for transited type");
|
||||
errMsgList.put(KDC_ERR_CLIENT_REVOKED, "Clients credentials have been revoked");
|
||||
errMsgList.put(KDC_ERR_SERVICE_REVOKED, "Credentials for server have been revoked");
|
||||
errMsgList.put(KDC_ERR_TGT_REVOKED, "TGT has been revoked");
|
||||
errMsgList.put(KDC_ERR_CLIENT_NOTYET, "Client not yet valid - try again later");
|
||||
errMsgList.put(KDC_ERR_SERVICE_NOTYET, "Server not yet valid - try again later");
|
||||
errMsgList.put(KDC_ERR_KEY_EXPIRED, "Password has expired - change password to reset");
|
||||
errMsgList.put(KDC_ERR_PREAUTH_FAILED, "Pre-authentication information was invalid");
|
||||
errMsgList.put(KDC_ERR_PREAUTH_REQUIRED, "Additional pre-authentication required");
|
||||
errMsgList.put(KRB_AP_ERR_BAD_INTEGRITY, "Integrity check on decrypted field failed");
|
||||
errMsgList.put(KRB_AP_ERR_TKT_EXPIRED, "Ticket expired");
|
||||
errMsgList.put(KRB_AP_ERR_TKT_NYV, "Ticket not yet valid");
|
||||
errMsgList.put(KRB_AP_ERR_REPEAT, "Request is a replay");
|
||||
errMsgList.put(KRB_AP_ERR_NOT_US, "The ticket isn't for us");
|
||||
errMsgList.put(KRB_AP_ERR_BADMATCH, "Ticket and authenticator don't match");
|
||||
errMsgList.put(KRB_AP_ERR_SKEW, "Clock skew too great");
|
||||
errMsgList.put(KRB_AP_ERR_BADADDR, "Incorrect net address");
|
||||
errMsgList.put(KRB_AP_ERR_BADVERSION, "Protocol version mismatch");
|
||||
errMsgList.put(KRB_AP_ERR_MSG_TYPE, "Invalid msg type");
|
||||
errMsgList.put(KRB_AP_ERR_MODIFIED, "Message stream modified");
|
||||
errMsgList.put(KRB_AP_ERR_BADORDER, "Message out of order");
|
||||
errMsgList.put(KRB_AP_ERR_BADKEYVER, "Specified version of key is not available");
|
||||
errMsgList.put(KRB_AP_ERR_NOKEY, "Service key not available");
|
||||
errMsgList.put(KRB_AP_ERR_MUT_FAIL, "Mutual authentication failed");
|
||||
errMsgList.put(KRB_AP_ERR_BADDIRECTION, "Incorrect message direction");
|
||||
errMsgList.put(KRB_AP_ERR_METHOD, "Alternative authentication method required");
|
||||
errMsgList.put(KRB_AP_ERR_BADSEQ, "Incorrect sequence number in message");
|
||||
errMsgList.put(KRB_AP_ERR_INAPP_CKSUM, "Inappropriate type of checksum in message");
|
||||
errMsgList.put(KRB_ERR_RESPONSE_TOO_BIG, "Response too big for UDP, retry with TCP");
|
||||
errMsgList.put(KRB_ERR_GENERIC, "Generic error (description in e-text)");
|
||||
errMsgList.put(KRB_ERR_FIELD_TOOLONG, "Field is too long for this implementation");
|
||||
errMsgList.put(KRB_AP_ERR_NOREALM, "Realm name not available"); //used in setDefaultCreds() in sun.security.krb5.Credentials
|
||||
|
||||
// error messages specific to this implementation
|
||||
|
||||
errMsgList.put(API_INVALID_ARG, "Invalid argument");
|
||||
|
||||
errMsgList.put(BITSTRING_SIZE_INVALID, "BitString size does not match input byte array");
|
||||
errMsgList.put(BITSTRING_INDEX_OUT_OF_BOUNDS, "BitString bit index does not fall within size");
|
||||
errMsgList.put(BITSTRING_BAD_LENGTH, "BitString length is wrong for the expected type");
|
||||
|
||||
errMsgList.put(REALM_ILLCHAR, "Illegal character in realm name; one of: '/', ':', '\0'");
|
||||
errMsgList.put(REALM_NULL, "Null realm name");
|
||||
|
||||
errMsgList.put(ASN1_BAD_TIMEFORMAT, "Input not in GeneralizedTime format");
|
||||
errMsgList.put(ASN1_MISSING_FIELD, "Structure is missing a required field");
|
||||
errMsgList.put(ASN1_MISPLACED_FIELD, "Unexpected field number");
|
||||
errMsgList.put(ASN1_TYPE_MISMATCH, "Type numbers are inconsistent");
|
||||
errMsgList.put(ASN1_OVERFLOW, "Value too large");
|
||||
errMsgList.put(ASN1_OVERRUN, "Encoding ended unexpectedly");
|
||||
errMsgList.put(ASN1_BAD_ID, "Identifier doesn't match expected value");
|
||||
errMsgList.put(ASN1_BAD_LENGTH, "Length doesn't match expected value");
|
||||
errMsgList.put(ASN1_BAD_FORMAT, "Badly-formatted encoding");
|
||||
errMsgList.put(ASN1_PARSE_ERROR, "Parse error");
|
||||
errMsgList.put(ASN1_BAD_CLASS, "Bad class number");
|
||||
errMsgList.put(ASN1_BAD_TYPE, "Bad type number");
|
||||
errMsgList.put(ASN1_BAD_TAG, "Bad tag number");
|
||||
errMsgList.put(ASN1_UNSUPPORTED_TYPE, "Unsupported ASN.1 type encountered");
|
||||
errMsgList.put(ASN1_CANNOT_ENCODE, "Encoding failed due to invalid parameter(s)");
|
||||
errMsgList.put(KRB_CRYPTO_NOT_SUPPORT, "Client has no support for crypto type");
|
||||
errMsgList.put(KRB_AP_ERR_REQ_OPTIONS, "Invalid option setting in ticket request.");
|
||||
errMsgList.put(KRB_AP_ERR_GEN_CRED, "Fail to create credential.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2003, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
public class KrbApErrException extends sun.security.krb5.KrbException {
|
||||
|
||||
private static final long serialVersionUID = 7545264413323118315L;
|
||||
|
||||
public KrbApErrException(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
public KrbApErrException(int i, String s) {
|
||||
super(i, s);
|
||||
}
|
||||
|
||||
}
|
||||
201
jdkSrc/jdk8/sun/security/krb5/internal/KrbCredInfo.java
Normal file
201
jdkSrc/jdk8/sun/security/krb5/internal/KrbCredInfo.java
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KrbCredInfo type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KrbCredInfo ::= SEQUENCE {
|
||||
* key [0] EncryptionKey,
|
||||
* prealm [1] Realm OPTIONAL,
|
||||
* pname [2] PrincipalName OPTIONAL,
|
||||
* flags [3] TicketFlags OPTIONAL,
|
||||
* authtime [4] KerberosTime OPTIONAL,
|
||||
* starttime [5] KerberosTime OPTIONAL,
|
||||
* endtime [6] KerberosTime OPTIONAL,
|
||||
* renew-till [7] KerberosTime OPTIONAL,
|
||||
* srealm [8] Realm OPTIONAL,
|
||||
* sname [9] PrincipalName OPTIONAL,
|
||||
* caddr [10] HostAddresses OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class KrbCredInfo {
|
||||
public EncryptionKey key;
|
||||
public PrincipalName pname; //optional
|
||||
public TicketFlags flags; //optional
|
||||
public KerberosTime authtime; //optional
|
||||
public KerberosTime starttime; //optional
|
||||
public KerberosTime endtime; //optional
|
||||
public KerberosTime renewTill; //optional
|
||||
public PrincipalName sname; //optional
|
||||
public HostAddresses caddr; //optional
|
||||
|
||||
private KrbCredInfo() {
|
||||
}
|
||||
|
||||
public KrbCredInfo(
|
||||
EncryptionKey new_key,
|
||||
PrincipalName new_pname,
|
||||
TicketFlags new_flags,
|
||||
KerberosTime new_authtime,
|
||||
KerberosTime new_starttime,
|
||||
KerberosTime new_endtime,
|
||||
KerberosTime new_renewTill,
|
||||
PrincipalName new_sname,
|
||||
HostAddresses new_caddr
|
||||
) {
|
||||
key = new_key;
|
||||
pname = new_pname;
|
||||
flags = new_flags;
|
||||
authtime = new_authtime;
|
||||
starttime = new_starttime;
|
||||
endtime = new_endtime;
|
||||
renewTill = new_renewTill;
|
||||
sname = new_sname;
|
||||
caddr = new_caddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KrbCredInfo object.
|
||||
* @param encoding a Der-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
*/
|
||||
public KrbCredInfo(DerValue encoding)
|
||||
throws Asn1Exception, IOException, RealmException{
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
pname = null;
|
||||
flags = null;
|
||||
authtime = null;
|
||||
starttime = null;
|
||||
endtime = null;
|
||||
renewTill = null;
|
||||
sname = null;
|
||||
caddr = null;
|
||||
key = EncryptionKey.parse(encoding.getData(), (byte)0x00, false);
|
||||
Realm prealm = null, srealm = null;
|
||||
if (encoding.getData().available() > 0)
|
||||
prealm = Realm.parse(encoding.getData(), (byte)0x01, true);
|
||||
if (encoding.getData().available() > 0)
|
||||
pname = PrincipalName.parse(encoding.getData(), (byte)0x02, true, prealm);
|
||||
if (encoding.getData().available() > 0)
|
||||
flags = TicketFlags.parse(encoding.getData(), (byte)0x03, true);
|
||||
if (encoding.getData().available() > 0)
|
||||
authtime = KerberosTime.parse(encoding.getData(), (byte)0x04, true);
|
||||
if (encoding.getData().available() > 0)
|
||||
starttime = KerberosTime.parse(encoding.getData(), (byte)0x05, true);
|
||||
if (encoding.getData().available() > 0)
|
||||
endtime = KerberosTime.parse(encoding.getData(), (byte)0x06, true);
|
||||
if (encoding.getData().available() > 0)
|
||||
renewTill = KerberosTime.parse(encoding.getData(), (byte)0x07, true);
|
||||
if (encoding.getData().available() > 0)
|
||||
srealm = Realm.parse(encoding.getData(), (byte)0x08, true);
|
||||
if (encoding.getData().available() > 0)
|
||||
sname = PrincipalName.parse(encoding.getData(), (byte)0x09, true, srealm);
|
||||
if (encoding.getData().available() > 0)
|
||||
caddr = HostAddresses.parse(encoding.getData(), (byte)0x0A, true);
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an KrbCredInfo object.
|
||||
* @return the byte array of encoded KrbCredInfo object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
Vector<DerValue> v = new Vector<>();
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), key.asn1Encode()));
|
||||
if (pname != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), pname.getRealm().asn1Encode()));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), pname.asn1Encode()));
|
||||
}
|
||||
if (flags != null)
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), flags.asn1Encode()));
|
||||
if (authtime != null)
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authtime.asn1Encode()));
|
||||
if (starttime != null)
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), starttime.asn1Encode()));
|
||||
if (endtime != null)
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), endtime.asn1Encode()));
|
||||
if (renewTill != null)
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), renewTill.asn1Encode()));
|
||||
if (sname != null) {
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), sname.getRealm().asn1Encode()));
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), sname.asn1Encode()));
|
||||
}
|
||||
if (caddr != null)
|
||||
v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), caddr.asn1Encode()));
|
||||
DerValue der[] = new DerValue[v.size()];
|
||||
v.copyInto(der);
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.putSequence(der);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
KrbCredInfo kcred = new KrbCredInfo();
|
||||
kcred.key = (EncryptionKey)key.clone();
|
||||
// optional fields
|
||||
if (pname != null)
|
||||
kcred.pname = (PrincipalName)pname.clone();
|
||||
if (flags != null)
|
||||
kcred.flags = (TicketFlags)flags.clone();
|
||||
kcred.authtime = authtime;
|
||||
kcred.starttime = starttime;
|
||||
kcred.endtime = endtime;
|
||||
kcred.renewTill = renewTill;
|
||||
if (sname != null)
|
||||
kcred.sname = (PrincipalName)sname.clone();
|
||||
if (caddr != null)
|
||||
kcred.caddr = (HostAddresses)caddr.clone();
|
||||
return kcred;
|
||||
}
|
||||
|
||||
}
|
||||
45
jdkSrc/jdk8/sun/security/krb5/internal/KrbErrException.java
Normal file
45
jdkSrc/jdk8/sun/security/krb5/internal/KrbErrException.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
public class KrbErrException extends sun.security.krb5.KrbException {
|
||||
|
||||
private static final long serialVersionUID = 2186533836785448317L;
|
||||
|
||||
public KrbErrException(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
public KrbErrException(int i, String s) {
|
||||
super(i, s);
|
||||
}
|
||||
|
||||
}
|
||||
137
jdkSrc/jdk8/sun/security/krb5/internal/LastReq.java
Normal file
137
jdkSrc/jdk8/sun/security/krb5/internal/LastReq.java
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 LastReq type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* LastReq ::= SEQUENCE OF SEQUENCE {
|
||||
* lr-type [0] Int32,
|
||||
* lr-value [1] KerberosTime
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class LastReq {
|
||||
private LastReqEntry[] entry = null;
|
||||
|
||||
public LastReq(LastReqEntry[] entries) throws IOException {
|
||||
if (entries != null) {
|
||||
entry = new LastReqEntry[entries.length];
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i] == null) {
|
||||
throw new IOException("Cannot create a LastReqEntry");
|
||||
} else {
|
||||
entry[i] = (LastReqEntry)entries[i].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a LastReq object.
|
||||
* @param encoding a Der-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
|
||||
public LastReq(DerValue encoding) throws Asn1Exception, IOException {
|
||||
Vector<LastReqEntry> v= new Vector<>();
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
while (encoding.getData().available() > 0) {
|
||||
v.addElement(new LastReqEntry(encoding.getData().getDerValue()));
|
||||
}
|
||||
if (v.size() > 0) {
|
||||
entry = new LastReqEntry[v.size()];
|
||||
v.copyInto(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an LastReq object.
|
||||
* @return the byte array of encoded LastReq object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
if (entry != null && entry.length > 0) {
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
for (int i = 0; i < entry.length; i++)
|
||||
temp.write(entry[i].asn1Encode());
|
||||
bytes.write(DerValue.tag_Sequence, temp);
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a last request from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicates if this data field is optional
|
||||
* @return an instance of LastReq.
|
||||
*
|
||||
*/
|
||||
|
||||
public static LastReq parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new LastReq(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
96
jdkSrc/jdk8/sun/security/krb5/internal/LastReqEntry.java
Normal file
96
jdkSrc/jdk8/sun/security/krb5/internal/LastReqEntry.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LastReqEntry {
|
||||
private int lrType;
|
||||
private KerberosTime lrValue;
|
||||
|
||||
private LastReqEntry() {
|
||||
}
|
||||
|
||||
public LastReqEntry(int Type, KerberosTime time){
|
||||
lrType = Type;
|
||||
lrValue = time;
|
||||
// XXX check the type and time.
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a LastReqEntry object.
|
||||
* @param encoding a Der-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public LastReqEntry(DerValue encoding) throws Asn1Exception, IOException {
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
DerValue der;
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x00){
|
||||
lrType = der.getData().getBigInteger().intValue();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
|
||||
lrValue = KerberosTime.parse(encoding.getData(), (byte)0x01, false);
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an LastReqEntry object.
|
||||
* @return the byte array of encoded LastReqEntry object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(lrType);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), lrValue.asn1Encode());
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
LastReqEntry newEntry = new LastReqEntry();
|
||||
newEntry.lrType = lrType;
|
||||
newEntry.lrValue = lrValue;
|
||||
return newEntry;
|
||||
}
|
||||
}
|
||||
89
jdkSrc/jdk8/sun/security/krb5/internal/LocalSeqNumber.java
Normal file
89
jdkSrc/jdk8/sun/security/krb5/internal/LocalSeqNumber.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.Confounder;
|
||||
|
||||
public class LocalSeqNumber implements SeqNumber {
|
||||
private int lastSeqNumber;
|
||||
|
||||
public LocalSeqNumber() {
|
||||
randInit();
|
||||
}
|
||||
|
||||
public LocalSeqNumber(int start) {
|
||||
init(start);
|
||||
}
|
||||
|
||||
public LocalSeqNumber(Integer start) {
|
||||
init(start.intValue());
|
||||
}
|
||||
|
||||
public synchronized void randInit() {
|
||||
/*
|
||||
* Sequence numbers fall in the range 0 through 2^32 - 1 and wrap
|
||||
* to zero following the value 2^32 - 1.
|
||||
* Previous implementations used signed sequence numbers.
|
||||
* Workaround implementation incompatibilities by not generating
|
||||
* initial sequence numbers greater than 2^30, as done
|
||||
* in MIT distribution.
|
||||
*/
|
||||
// get the random confounder
|
||||
byte[] data = Confounder.bytes(4);
|
||||
data[0] = (byte)(data[0] & 0x3f);
|
||||
int result = ((data[3] & 0xff) |
|
||||
((data[2] & 0xff) << 8) |
|
||||
((data[1] & 0xff) << 16) |
|
||||
((data[0] & 0xff) << 24));
|
||||
if (result == 0) {
|
||||
result = 1;
|
||||
}
|
||||
lastSeqNumber = result;
|
||||
}
|
||||
|
||||
public synchronized void init(int start) {
|
||||
lastSeqNumber = start;
|
||||
}
|
||||
|
||||
public synchronized int current() {
|
||||
return lastSeqNumber;
|
||||
}
|
||||
|
||||
public synchronized int next() {
|
||||
return lastSeqNumber + 1;
|
||||
}
|
||||
|
||||
public synchronized int step() {
|
||||
return ++lastSeqNumber;
|
||||
}
|
||||
|
||||
}
|
||||
91
jdkSrc/jdk8/sun/security/krb5/internal/LoginOptions.java
Normal file
91
jdkSrc/jdk8/sun/security/krb5/internal/LoginOptions.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KDCOptions type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* KDCOptions ::= KerberosFlags
|
||||
* -- reserved(0),
|
||||
* -- forwardable(1),
|
||||
* -- forwarded(2),
|
||||
* -- proxiable(3),
|
||||
* -- proxy(4),
|
||||
* -- allow-postdate(5),
|
||||
* -- postdated(6),
|
||||
* -- unused7(7),
|
||||
* -- renewable(8),
|
||||
* -- unused9(9),
|
||||
* -- unused10(10),
|
||||
* -- opt-hardware-auth(11),
|
||||
* -- unused12(12),
|
||||
* -- unused13(13),
|
||||
* -- 15 is reserved for canonicalize
|
||||
* -- unused15(15),
|
||||
* -- 26 was unused in 1510
|
||||
* -- disable-transited-check(26),
|
||||
* -- renewable-ok(27),
|
||||
* -- enc-tkt-in-skey(28),
|
||||
* -- renew(30),
|
||||
* -- validate(31)
|
||||
*
|
||||
* KerberosFlags ::= BIT STRING (SIZE (32..MAX))
|
||||
* -- minimum number of bits shall be sent,
|
||||
* -- but no fewer than 32
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class LoginOptions extends KDCOptions {
|
||||
|
||||
// Login Options
|
||||
|
||||
public static final int RESERVED = 0;
|
||||
public static final int FORWARDABLE = 1;
|
||||
public static final int PROXIABLE = 3;
|
||||
public static final int ALLOW_POSTDATE = 5;
|
||||
public static final int RENEWABLE = 8;
|
||||
public static final int RENEWABLE_OK = 27;
|
||||
public static final int ENC_TKT_IN_SKEY = 28;
|
||||
public static final int RENEW = 30;
|
||||
public static final int VALIDATE = 31;
|
||||
public static final int MAX = 31;
|
||||
|
||||
}
|
||||
111
jdkSrc/jdk8/sun/security/krb5/internal/MethodData.java
Normal file
111
jdkSrc/jdk8/sun/security/krb5/internal/MethodData.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 EncKrbPrivPart type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* METHOD-DATA ::= SEQUENCE {
|
||||
* method-type[0] INTEGER,
|
||||
* method-data[1] OCTET STRING OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
public class MethodData {
|
||||
private int methodType;
|
||||
private byte[] methodData = null; //optional
|
||||
|
||||
public MethodData(int type, byte[] data) {
|
||||
methodType = type;
|
||||
if (data != null) {
|
||||
methodData = data.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a MethodData object.
|
||||
* @param encoding a Der-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public MethodData(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der;
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x00) {
|
||||
BigInteger bint = der.getData().getBigInteger();
|
||||
methodType = bint.intValue();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
if (encoding.getData().available() > 0) {
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x01) {
|
||||
methodData = der.getData().getOctetString();
|
||||
}
|
||||
else throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an MethodData object.
|
||||
* @return the byte array of encoded MethodData object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(methodType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
if (methodData != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putOctetString(methodData);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
|
||||
}
|
||||
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
224
jdkSrc/jdk8/sun/security/krb5/internal/NetClient.java
Normal file
224
jdkSrc/jdk8/sun/security/krb5/internal/NetClient.java
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.misc.IOUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
public abstract class NetClient implements AutoCloseable {
|
||||
public static NetClient getInstance(String protocol, String hostname, int port,
|
||||
int timeout) throws IOException {
|
||||
if (protocol.equals("TCP")) {
|
||||
return new TCPClient(hostname, port, timeout);
|
||||
} else {
|
||||
return new UDPClient(hostname, port, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public void send(byte[] data) throws IOException;
|
||||
abstract public byte[] receive() throws IOException;
|
||||
abstract public void close() throws IOException;
|
||||
}
|
||||
|
||||
class TCPClient extends NetClient {
|
||||
|
||||
private Socket tcpSocket;
|
||||
private BufferedOutputStream out;
|
||||
private BufferedInputStream in;
|
||||
|
||||
TCPClient(String hostname, int port, int timeout)
|
||||
throws IOException {
|
||||
tcpSocket = new Socket();
|
||||
tcpSocket.connect(new InetSocketAddress(hostname, port), timeout);
|
||||
out = new BufferedOutputStream(tcpSocket.getOutputStream());
|
||||
in = new BufferedInputStream(tcpSocket.getInputStream());
|
||||
tcpSocket.setSoTimeout(timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(byte[] data) throws IOException {
|
||||
byte[] lenField = new byte[4];
|
||||
intToNetworkByteOrder(data.length, lenField, 0, 4);
|
||||
out.write(lenField);
|
||||
|
||||
out.write(data);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] receive() throws IOException {
|
||||
byte[] lenField = new byte[4];
|
||||
int count = readFully(lenField, 4);
|
||||
|
||||
if (count != 4) {
|
||||
if (Krb5.DEBUG) {
|
||||
System.out.println(
|
||||
">>>DEBUG: TCPClient could not read length field");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
int len = networkByteOrderToInt(lenField, 0, 4);
|
||||
if (Krb5.DEBUG) {
|
||||
System.out.println(
|
||||
">>>DEBUG: TCPClient reading " + len + " bytes");
|
||||
}
|
||||
if (len <= 0) {
|
||||
if (Krb5.DEBUG) {
|
||||
System.out.println(
|
||||
">>>DEBUG: TCPClient zero or negative length field: "+len);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return IOUtils.readExactlyNBytes(in, len);
|
||||
} catch (IOException ioe) {
|
||||
if (Krb5.DEBUG) {
|
||||
System.out.println(
|
||||
">>>DEBUG: TCPClient could not read complete packet (" +
|
||||
len + "/" + count + ")");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
tcpSocket.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read requested number of bytes before returning.
|
||||
* @return The number of bytes actually read; -1 if none read
|
||||
*/
|
||||
private int readFully(byte[] inBuf, int total) throws IOException {
|
||||
int count, pos = 0;
|
||||
|
||||
while (total > 0) {
|
||||
count = in.read(inBuf, pos, total);
|
||||
|
||||
if (count == -1) {
|
||||
return (pos == 0? -1 : pos);
|
||||
}
|
||||
pos += count;
|
||||
total -= count;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the integer represented by 4 bytes in network byte order.
|
||||
*/
|
||||
private static int networkByteOrderToInt(byte[] buf, int start,
|
||||
int count) {
|
||||
if (count > 4) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot handle more than 4 bytes");
|
||||
}
|
||||
|
||||
int answer = 0;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
answer <<= 8;
|
||||
answer |= ((int)buf[start+i] & 0xff);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes an integer into 4 bytes in network byte order in the buffer
|
||||
* supplied.
|
||||
*/
|
||||
private static void intToNetworkByteOrder(int num, byte[] buf,
|
||||
int start, int count) {
|
||||
if (count > 4) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot handle more than 4 bytes");
|
||||
}
|
||||
|
||||
for (int i = count-1; i >= 0; i--) {
|
||||
buf[start+i] = (byte)(num & 0xff);
|
||||
num >>>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UDPClient extends NetClient {
|
||||
InetAddress iaddr;
|
||||
int iport;
|
||||
int bufSize = 65507;
|
||||
DatagramSocket dgSocket;
|
||||
DatagramPacket dgPacketIn;
|
||||
|
||||
UDPClient(String hostname, int port, int timeout)
|
||||
throws UnknownHostException, SocketException {
|
||||
iaddr = InetAddress.getByName(hostname);
|
||||
iport = port;
|
||||
dgSocket = new DatagramSocket();
|
||||
dgSocket.setSoTimeout(timeout);
|
||||
dgSocket.connect(iaddr, iport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(byte[] data) throws IOException {
|
||||
DatagramPacket dgPacketOut = new DatagramPacket(data, data.length,
|
||||
iaddr, iport);
|
||||
dgSocket.send(dgPacketOut);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] receive() throws IOException {
|
||||
byte ibuf[] = new byte[bufSize];
|
||||
dgPacketIn = new DatagramPacket(ibuf, ibuf.length);
|
||||
try {
|
||||
dgSocket.receive(dgPacketIn);
|
||||
}
|
||||
catch (SocketException e) {
|
||||
if (e instanceof PortUnreachableException) {
|
||||
throw e;
|
||||
}
|
||||
dgSocket.receive(dgPacketIn);
|
||||
}
|
||||
byte[] data = new byte[dgPacketIn.getLength()];
|
||||
System.arraycopy(dgPacketIn.getData(), 0, data, 0,
|
||||
dgPacketIn.getLength());
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
dgSocket.close();
|
||||
}
|
||||
}
|
||||
367
jdkSrc/jdk8/sun/security/krb5/internal/PAData.java
Normal file
367
jdkSrc/jdk8/sun/security/krb5/internal/PAData.java
Normal file
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.internal.crypto.EType;
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
|
||||
import sun.security.krb5.internal.util.KerberosString;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 PA-DATA type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* PA-DATA ::= SEQUENCE {
|
||||
* -- NOTE: first tag is [1], not [0]
|
||||
* padata-type [1] Int32,
|
||||
* padata-value [2] OCTET STRING -- might be encoded AP-REQ
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class PAData {
|
||||
private int pADataType;
|
||||
private byte[] pADataValue = null;
|
||||
private static final byte TAG_PATYPE = 1;
|
||||
private static final byte TAG_PAVALUE = 2;
|
||||
|
||||
private PAData() {
|
||||
}
|
||||
|
||||
public PAData(int new_pADataType, byte[] new_pADataValue) {
|
||||
pADataType = new_pADataType;
|
||||
if (new_pADataValue != null) {
|
||||
pADataValue = new_pADataValue.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
PAData new_pAData = new PAData();
|
||||
new_pAData.pADataType = pADataType;
|
||||
if (pADataValue != null) {
|
||||
new_pAData.pADataValue = new byte[pADataValue.length];
|
||||
System.arraycopy(pADataValue, 0, new_pAData.pADataValue,
|
||||
0, pADataValue.length);
|
||||
}
|
||||
return new_pAData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PAData object.
|
||||
* @param encoding a Der-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public PAData(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der = null;
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x01) {
|
||||
this.pADataType = der.getData().getBigInteger().intValue();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x02) {
|
||||
this.pADataValue = der.getData().getOctetString();
|
||||
}
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this object to an OutputStream.
|
||||
*
|
||||
* @return byte array of the encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception Asn1Exception on encoding errors.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
|
||||
temp.putInteger(pADataType);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_PATYPE), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putOctetString(pADataValue);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_PAVALUE), temp);
|
||||
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
// accessor methods
|
||||
public int getType() {
|
||||
return pADataType;
|
||||
}
|
||||
|
||||
public byte[] getValue() {
|
||||
return ((pADataValue == null) ? null : pADataValue.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a PAData from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception if an Asn1Exception occurs.
|
||||
* @param data the Der input stream value, which contains one or more
|
||||
* marshaled values.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicates if this data field is optional.
|
||||
* @return an array of PAData.
|
||||
*/
|
||||
public static PAData[] parseSequence(DerInputStream data,
|
||||
byte explicitTag, boolean optional)
|
||||
throws Asn1Exception, IOException {
|
||||
if ((optional) &&
|
||||
(((byte)data.peekByte() & (byte)0x1F) != explicitTag))
|
||||
return null;
|
||||
DerValue subDer = data.getDerValue();
|
||||
DerValue subsubDer = subDer.getData().getDerValue();
|
||||
if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
Vector<PAData> v = new Vector<>();
|
||||
while (subsubDer.getData().available() > 0) {
|
||||
v.addElement(new PAData(subsubDer.getData().getDerValue()));
|
||||
}
|
||||
if (v.size() > 0) {
|
||||
PAData[] pas = new PAData[v.size()];
|
||||
v.copyInto(pas);
|
||||
return pas;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the preferred etype from the PAData array.
|
||||
* <ol>
|
||||
* <li>ETYPE-INFO2-ENTRY with unknown s2kparams ignored</li>
|
||||
* <li>ETYPE-INFO2 preferred to ETYPE-INFO</li>
|
||||
* <li>Multiple entries for same etype in one PA-DATA, use the first one.</li>
|
||||
* <li>Multiple PA-DATA with same type, choose the last one.</li>
|
||||
* </ol>
|
||||
* (This is useful when PA-DATAs from KRB-ERROR and AS-REP are combined).
|
||||
*
|
||||
* @return the etype, or defaultEType if not enough info
|
||||
* @throws Asn1Exception|IOException if there is an encoding error
|
||||
*/
|
||||
public static int getPreferredEType(PAData[] pas, int defaultEType)
|
||||
throws IOException, Asn1Exception {
|
||||
|
||||
if (pas == null) return defaultEType;
|
||||
|
||||
DerValue d = null, d2 = null;
|
||||
for (PAData p: pas) {
|
||||
if (p.getValue() == null) continue;
|
||||
switch (p.getType()) {
|
||||
case Krb5.PA_ETYPE_INFO:
|
||||
d = new DerValue(p.getValue());
|
||||
break;
|
||||
case Krb5.PA_ETYPE_INFO2:
|
||||
d2 = new DerValue(p.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d2 != null) {
|
||||
while (d2.data.available() > 0) {
|
||||
DerValue value = d2.data.getDerValue();
|
||||
ETypeInfo2 tmp = new ETypeInfo2(value);
|
||||
if (EType.isNewer(tmp.getEType()) || tmp.getParams() == null) {
|
||||
// we don't support non-null s2kparams for old etypes
|
||||
return tmp.getEType();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d != null) {
|
||||
while (d.data.available() > 0) {
|
||||
DerValue value = d.data.getDerValue();
|
||||
ETypeInfo tmp = new ETypeInfo(value);
|
||||
return tmp.getEType();
|
||||
}
|
||||
}
|
||||
return defaultEType;
|
||||
}
|
||||
|
||||
/**
|
||||
* A place to store a pair of salt and s2kparams.
|
||||
* An empty salt is changed to null, to be interoperable
|
||||
* with Windows 2000 server. This is in fact not correct.
|
||||
*/
|
||||
public static class SaltAndParams {
|
||||
public final String salt;
|
||||
public final byte[] params;
|
||||
public SaltAndParams(String s, byte[] p) {
|
||||
if (s != null && s.isEmpty()) s = null;
|
||||
this.salt = s;
|
||||
this.params = p;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches salt and s2kparams value for eType in a series of PA-DATAs.
|
||||
* 1. ETYPE-INFO2-ENTRY with unknown s2kparams ignored
|
||||
* 2. PA-ETYPE-INFO2 preferred to PA-ETYPE-INFO preferred to PA-PW-SALT.
|
||||
* 3. multiple entries for same etype in one PA-DATA, use the first one.
|
||||
* 4. Multiple PA-DATA with same type, choose the last one
|
||||
* (This is useful when PA-DATAs from KRB-ERROR and AS-REP are combined).
|
||||
* @return salt and s2kparams. can be null if not found
|
||||
*/
|
||||
public static SaltAndParams getSaltAndParams(int eType, PAData[] pas)
|
||||
throws Asn1Exception, IOException {
|
||||
|
||||
if (pas == null) return null;
|
||||
|
||||
DerValue d = null, d2 = null;
|
||||
String paPwSalt = null;
|
||||
|
||||
for (PAData p: pas) {
|
||||
if (p.getValue() == null) continue;
|
||||
switch (p.getType()) {
|
||||
case Krb5.PA_PW_SALT:
|
||||
paPwSalt = new String(p.getValue(),
|
||||
KerberosString.MSNAME?"UTF8":"8859_1");
|
||||
break;
|
||||
case Krb5.PA_ETYPE_INFO:
|
||||
d = new DerValue(p.getValue());
|
||||
break;
|
||||
case Krb5.PA_ETYPE_INFO2:
|
||||
d2 = new DerValue(p.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d2 != null) {
|
||||
while (d2.data.available() > 0) {
|
||||
DerValue value = d2.data.getDerValue();
|
||||
ETypeInfo2 tmp = new ETypeInfo2(value);
|
||||
if (tmp.getEType() == eType &&
|
||||
(EType.isNewer(eType) || tmp.getParams() == null)) {
|
||||
// we don't support non-null s2kparams for old etypes
|
||||
return new SaltAndParams(tmp.getSalt(), tmp.getParams());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d != null) {
|
||||
while (d.data.available() > 0) {
|
||||
DerValue value = d.data.getDerValue();
|
||||
ETypeInfo tmp = new ETypeInfo(value);
|
||||
if (tmp.getEType() == eType) {
|
||||
return new SaltAndParams(tmp.getSalt(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paPwSalt != null) {
|
||||
return new SaltAndParams(paPwSalt, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(">>>Pre-Authentication Data:\n\t PA-DATA type = ")
|
||||
.append(pADataType).append('\n');
|
||||
|
||||
switch(pADataType) {
|
||||
case Krb5.PA_ENC_TIMESTAMP:
|
||||
sb.append("\t PA-ENC-TIMESTAMP");
|
||||
break;
|
||||
case Krb5.PA_ETYPE_INFO:
|
||||
if (pADataValue != null) {
|
||||
try {
|
||||
DerValue der = new DerValue(pADataValue);
|
||||
while (der.data.available() > 0) {
|
||||
DerValue value = der.data.getDerValue();
|
||||
ETypeInfo info = new ETypeInfo(value);
|
||||
sb.append("\t PA-ETYPE-INFO etype = ")
|
||||
.append(info.getEType())
|
||||
.append(", salt = ")
|
||||
.append(info.getSalt())
|
||||
.append('\n');
|
||||
}
|
||||
} catch (IOException|Asn1Exception e) {
|
||||
sb.append("\t <Unparseable PA-ETYPE-INFO>\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Krb5.PA_ETYPE_INFO2:
|
||||
if (pADataValue != null) {
|
||||
try {
|
||||
DerValue der = new DerValue(pADataValue);
|
||||
while (der.data.available() > 0) {
|
||||
DerValue value = der.data.getDerValue();
|
||||
ETypeInfo2 info2 = new ETypeInfo2(value);
|
||||
sb.append("\t PA-ETYPE-INFO2 etype = ")
|
||||
.append(info2.getEType())
|
||||
.append(", salt = ")
|
||||
.append(info2.getSalt())
|
||||
.append(", s2kparams = ");
|
||||
byte[] s2kparams = info2.getParams();
|
||||
if (s2kparams == null) {
|
||||
sb.append("null\n");
|
||||
} else if (s2kparams.length == 0) {
|
||||
sb.append("empty\n");
|
||||
} else {
|
||||
sb.append(new sun.misc.HexDumpEncoder()
|
||||
.encodeBuffer(s2kparams));
|
||||
}
|
||||
}
|
||||
} catch (IOException|Asn1Exception e) {
|
||||
sb.append("\t <Unparseable PA-ETYPE-INFO>\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Krb5.PA_FOR_USER:
|
||||
sb.append("\t PA-FOR-USER\n");
|
||||
break;
|
||||
default:
|
||||
// Unknown Pre-auth type
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
116
jdkSrc/jdk8/sun/security/krb5/internal/PAEncTSEnc.java
Normal file
116
jdkSrc/jdk8/sun/security/krb5/internal/PAEncTSEnc.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 PAEncTSEnc type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* PA-ENC-TS-ENC ::= SEQUENCE {
|
||||
* patimestamp [0] KerberosTime -- client's time --,
|
||||
* pausec [1] Microseconds OPTIONAL
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class PAEncTSEnc {
|
||||
public KerberosTime pATimeStamp;
|
||||
public Integer pAUSec; //optional
|
||||
|
||||
public PAEncTSEnc(
|
||||
KerberosTime new_pATimeStamp,
|
||||
Integer new_pAUSec
|
||||
) {
|
||||
pATimeStamp = new_pATimeStamp;
|
||||
pAUSec = new_pAUSec;
|
||||
}
|
||||
|
||||
public PAEncTSEnc() {
|
||||
KerberosTime now = KerberosTime.now();
|
||||
pATimeStamp = now;
|
||||
pAUSec = new Integer(now.getMicroSeconds());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PAEncTSEnc object.
|
||||
* @param encoding a Der-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public PAEncTSEnc(DerValue encoding) throws Asn1Exception, IOException {
|
||||
DerValue der;
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
pATimeStamp = KerberosTime.parse(encoding.getData(), (byte)0x00, false);
|
||||
if (encoding.getData().available() > 0) {
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x01) {
|
||||
pAUSec = new Integer(der.getData().getBigInteger().intValue());
|
||||
}
|
||||
else throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encodes a PAEncTSEnc object.
|
||||
* @return the byte array of encoded PAEncTSEnc object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), pATimeStamp.asn1Encode());
|
||||
if (pAUSec != null) {
|
||||
temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(pAUSec.intValue()));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
|
||||
}
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
}
|
||||
195
jdkSrc/jdk8/sun/security/krb5/internal/PAForUserEnc.java
Normal file
195
jdkSrc/jdk8/sun/security/krb5/internal/PAForUserEnc.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2019, 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 sun.security.krb5.internal;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
import sun.security.krb5.internal.util.KerberosString;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 PA-FOR-USER type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* padata-type ::= PA-FOR-USER
|
||||
* -- value 129
|
||||
* padata-value ::= EncryptedData
|
||||
* -- PA-FOR-USER-ENC
|
||||
* PA-FOR-USER-ENC ::= SEQUENCE {
|
||||
* userName[0] PrincipalName,
|
||||
* userRealm[1] Realm,
|
||||
* cksum[2] Checksum,
|
||||
* auth-package[3] KerberosString
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects MS-SFU.
|
||||
*/
|
||||
|
||||
public class PAForUserEnc {
|
||||
final public PrincipalName name;
|
||||
final private EncryptionKey key;
|
||||
final public static String AUTH_PACKAGE = "Kerberos";
|
||||
|
||||
public PAForUserEnc(PrincipalName name, EncryptionKey key) {
|
||||
this.name = name;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PA-FOR-USER object from a DER encoding.
|
||||
* @param encoding the input object
|
||||
* @param key the key to verify the checksum inside encoding
|
||||
* @throws KrbException if the verification fails.
|
||||
* Note: this method is now only used by test KDC, therefore
|
||||
* the verification is ignored (at the moment).
|
||||
*/
|
||||
public PAForUserEnc(DerValue encoding, EncryptionKey key)
|
||||
throws Asn1Exception, KrbException, IOException {
|
||||
DerValue der = null;
|
||||
this.key = key;
|
||||
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
// Realm after name? Quite abnormal.
|
||||
PrincipalName tmpName = null;
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x00) {
|
||||
try {
|
||||
tmpName = new PrincipalName(der.getData().getDerValue(),
|
||||
new Realm("PLACEHOLDER"));
|
||||
} catch (RealmException re) {
|
||||
// Impossible
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x01) {
|
||||
try {
|
||||
Realm realm = new Realm(der.getData().getDerValue());
|
||||
name = new PrincipalName(
|
||||
tmpName.getNameType(), tmpName.getNameStrings(), realm);
|
||||
} catch (RealmException re) {
|
||||
throw new IOException(re);
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x02) {
|
||||
// Deal with the checksum
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x03) {
|
||||
String authPackage = new KerberosString(der.getData().getDerValue()).toString();
|
||||
if (!authPackage.equalsIgnoreCase(AUTH_PACKAGE)) {
|
||||
throw new IOException("Incorrect auth-package");
|
||||
}
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
if (encoding.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), name.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), name.getRealm().asn1Encode());
|
||||
|
||||
try {
|
||||
// MS-SFU 2.2.1: use hmac-md5 checksum regardless of key type
|
||||
Checksum cks = new Checksum(
|
||||
Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR,
|
||||
getS4UByteArray(),
|
||||
key,
|
||||
KeyUsage.KU_PA_FOR_USER_ENC_CKSUM);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), cks.asn1Encode());
|
||||
} catch (KrbException ke) {
|
||||
throw new IOException(ke);
|
||||
}
|
||||
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putDerValue(new KerberosString(AUTH_PACKAGE).toDerValue());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp);
|
||||
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns S4UByteArray, the block to calculate checksum inside a
|
||||
* PA-FOR-USER-ENC data structure. It includes:
|
||||
* 1. userName.name-type encoded as a 4-byte integer in little endian
|
||||
* byte order
|
||||
* 2. all string values in the sequence of strings contained in the
|
||||
* userName.name-string field
|
||||
* 3. the string value of the userRealm field
|
||||
* 4. the string value of auth-package field
|
||||
*/
|
||||
public byte[] getS4UByteArray() {
|
||||
try {
|
||||
ByteArrayOutputStream ba = new ByteArrayOutputStream();
|
||||
ba.write(new byte[4]);
|
||||
for (String s: name.getNameStrings()) {
|
||||
ba.write(s.getBytes("UTF-8"));
|
||||
}
|
||||
ba.write(name.getRealm().toString().getBytes("UTF-8"));
|
||||
ba.write(AUTH_PACKAGE.getBytes("UTF-8"));
|
||||
byte[] output = ba.toByteArray();
|
||||
int pnType = name.getNameType();
|
||||
output[0] = (byte)(pnType & 0xff);
|
||||
output[1] = (byte)((pnType>>8) & 0xff);
|
||||
output[2] = (byte)((pnType>>16) & 0xff);
|
||||
output[3] = (byte)((pnType>>24) & 0xff);
|
||||
return output;
|
||||
} catch (IOException ioe) {
|
||||
// not possible
|
||||
throw new AssertionError("Cannot write ByteArrayOutputStream", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
public PrincipalName getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "PA-FOR-USER: " + name;
|
||||
}
|
||||
}
|
||||
185
jdkSrc/jdk8/sun/security/krb5/internal/PaPacOptions.java
Normal file
185
jdkSrc/jdk8/sun/security/krb5/internal/PaPacOptions.java
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Red Hat, Inc.
|
||||
* 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 sun.security.krb5.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.internal.util.KerberosFlags;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 PA-PAC-OPTIONS type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* PA-PAC-OPTIONS ::= SEQUENCE {
|
||||
* KerberosFlags
|
||||
* -- Claims (0)
|
||||
* -- Branch Aware (1)
|
||||
* -- Forward to Full DC (2)
|
||||
* }
|
||||
* Note: KerberosFlags ::= BIT STRING (SIZE (32..MAX))
|
||||
* -- minimum number of bits shall be sent, but no fewer than 32
|
||||
*
|
||||
* PA-PAC-OPTIONS ::= KerberosFlags
|
||||
* -- resource-based constrained delegation (3)
|
||||
* }</pre>
|
||||
*
|
||||
* This definition reflects MS-KILE (section 2.2.10)
|
||||
* and MS-SFU (section 2.2.5).
|
||||
*/
|
||||
|
||||
public class PaPacOptions {
|
||||
|
||||
private static final int CLAIMS = 0;
|
||||
private static final int BRANCH_AWARE = 1;
|
||||
private static final int FORWARD_TO_FULL_DC = 2;
|
||||
private static final int RESOURCE_BASED_CONSTRAINED_DELEGATION = 3;
|
||||
|
||||
private KerberosFlags flags;
|
||||
|
||||
public PaPacOptions() {
|
||||
this.flags = new KerberosFlags(Krb5.AP_OPTS_MAX + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PA-PAC-OPTIONS object from a DER encoding.
|
||||
* @param encoding the ASN.1 encoded input
|
||||
* @throws Asn1Exception if invalid DER
|
||||
* @throws IOException if there is an error reading the DER value
|
||||
*/
|
||||
public PaPacOptions(DerValue encoding) throws Asn1Exception, IOException {
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
DerValue der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x00) {
|
||||
flags = new KDCOptions(
|
||||
der.getData().getDerValue());
|
||||
} else {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the claims flag
|
||||
* @param value whether the claims flag is set or not
|
||||
* @return the same PaPacOptions instance
|
||||
*/
|
||||
public PaPacOptions setClaims(boolean value) {
|
||||
flags.set(CLAIMS, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the claims flag
|
||||
* @return the claims flag value
|
||||
*/
|
||||
public boolean getClaims() {
|
||||
return flags.get(CLAIMS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the branch-aware flag
|
||||
* @param value whether the branch-aware flag is set or not
|
||||
* @return the same PaPacOptions instance
|
||||
*/
|
||||
public PaPacOptions setBranchAware(boolean value) {
|
||||
flags.set(BRANCH_AWARE, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the branch-aware flag
|
||||
* @return the branch-aware flag value
|
||||
*/
|
||||
public boolean getBranchAware() {
|
||||
return flags.get(BRANCH_AWARE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the forward-to-full-DC flag
|
||||
* @param value whether the forward-to-full-DC flag is set or not
|
||||
* @return the same PaPacOptions instance
|
||||
*/
|
||||
public PaPacOptions setForwardToFullDC(boolean value) {
|
||||
flags.set(FORWARD_TO_FULL_DC, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the forward-to-full-DC flag
|
||||
* @return the forward-to-full-DC flag value
|
||||
*/
|
||||
public boolean getForwardToFullDC() {
|
||||
return flags.get(FORWARD_TO_FULL_DC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the resource-based-constrained-delegation flag
|
||||
* @param value whether the resource-based-constrained-delegation
|
||||
* is set or not
|
||||
* @return the same PaPacOptions instance
|
||||
*/
|
||||
public PaPacOptions setResourceBasedConstrainedDelegation(boolean value) {
|
||||
flags.set(RESOURCE_BASED_CONSTRAINED_DELEGATION, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the resource-based-constrained-delegation flag
|
||||
* @return the resource-based-constrained-delegation flag value
|
||||
*/
|
||||
public boolean getResourceBasedConstrainedDelegation() {
|
||||
return flags.get(RESOURCE_BASED_CONSTRAINED_DELEGATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this PaPacOptions instance.
|
||||
* @return an ASN.1 encoded PaPacOptions byte array
|
||||
* @throws IOException if an I/O error occurs while encoding this
|
||||
* PaPacOptions instance
|
||||
*/
|
||||
public byte[] asn1Encode() throws IOException {
|
||||
byte[] bytes = null;
|
||||
try(DerOutputStream temp = new DerOutputStream()) {
|
||||
temp.write(
|
||||
DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00),
|
||||
flags.asn1Encode());
|
||||
bytes = temp.toByteArray();
|
||||
}
|
||||
try(DerOutputStream temp = new DerOutputStream()) {
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return flags.toString();
|
||||
}
|
||||
}
|
||||
185
jdkSrc/jdk8/sun/security/krb5/internal/ReferralsCache.java
Normal file
185
jdkSrc/jdk8/sun/security/krb5/internal/ReferralsCache.java
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Red Hat, Inc.
|
||||
* 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 sun.security.krb5.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
|
||||
import sun.security.krb5.Credentials;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
|
||||
/*
|
||||
* ReferralsCache class implements a cache scheme for referral TGTs as
|
||||
* described in RFC 6806 - 10. Caching Information. The goal is to optimize
|
||||
* resources (such as network traffic) when a client requests credentials for a
|
||||
* service principal to a given KDC. If a referral TGT was previously received,
|
||||
* cached information is used instead of issuing a new query. Once a referral
|
||||
* TGT expires, the corresponding referral entry in the cache is removed.
|
||||
*/
|
||||
final class ReferralsCache {
|
||||
|
||||
private static Map<ReferralCacheKey, Map<String, ReferralCacheEntry>>
|
||||
referralsMap = new HashMap<>();
|
||||
|
||||
static private final class ReferralCacheKey {
|
||||
private PrincipalName cname;
|
||||
private PrincipalName sname;
|
||||
private PrincipalName user; // S4U2Self only
|
||||
private byte[] userSvcTicketEnc; // S4U2Proxy only
|
||||
ReferralCacheKey (PrincipalName cname, PrincipalName sname,
|
||||
PrincipalName user, Ticket userSvcTicket) {
|
||||
this.cname = cname;
|
||||
this.sname = sname;
|
||||
this.user = user;
|
||||
if (userSvcTicket != null && userSvcTicket.encPart != null) {
|
||||
byte[] userSvcTicketEnc = userSvcTicket.encPart.getBytes();
|
||||
if (userSvcTicketEnc.length > 0) {
|
||||
this.userSvcTicketEnc = userSvcTicketEnc;
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof ReferralCacheKey))
|
||||
return false;
|
||||
ReferralCacheKey that = (ReferralCacheKey)other;
|
||||
return cname.equals(that.cname) &&
|
||||
sname.equals(that.sname) &&
|
||||
Objects.equals(user, that.user) &&
|
||||
Arrays.equals(userSvcTicketEnc, that.userSvcTicketEnc);
|
||||
}
|
||||
public int hashCode() {
|
||||
return cname.hashCode() + sname.hashCode() +
|
||||
Objects.hashCode(user) +
|
||||
Arrays.hashCode(userSvcTicketEnc);
|
||||
}
|
||||
}
|
||||
|
||||
static final class ReferralCacheEntry {
|
||||
private final Credentials creds;
|
||||
private final String toRealm;
|
||||
ReferralCacheEntry(Credentials creds, String toRealm) {
|
||||
this.creds = creds;
|
||||
this.toRealm = toRealm;
|
||||
}
|
||||
Credentials getCreds() {
|
||||
return creds;
|
||||
}
|
||||
String getToRealm() {
|
||||
return toRealm;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a new referral entry to the cache, including: client principal,
|
||||
* service principal, user principal (S4U2Self only), client service
|
||||
* ticket (S4U2Proxy only), source KDC realm, destination KDC realm and
|
||||
* referral TGT.
|
||||
*
|
||||
* If a loop is generated when adding the new referral, the first hop is
|
||||
* automatically removed. For example, let's assume that adding a
|
||||
* REALM-3.COM -> REALM-1.COM referral generates the following loop:
|
||||
* REALM-1.COM -> REALM-2.COM -> REALM-3.COM -> REALM-1.COM. Then,
|
||||
* REALM-1.COM -> REALM-2.COM referral entry is removed from the cache.
|
||||
*/
|
||||
static synchronized void put(PrincipalName cname, PrincipalName service,
|
||||
PrincipalName user, Ticket[] userSvcTickets, String fromRealm,
|
||||
String toRealm, Credentials creds) {
|
||||
Ticket userSvcTicket = (userSvcTickets != null ?
|
||||
userSvcTickets[0] : null);
|
||||
ReferralCacheKey k = new ReferralCacheKey(cname, service,
|
||||
user, userSvcTicket);
|
||||
pruneExpired(k);
|
||||
if (creds.getEndTime().before(new Date())) {
|
||||
return;
|
||||
}
|
||||
Map<String, ReferralCacheEntry> entries = referralsMap.get(k);
|
||||
if (entries == null) {
|
||||
entries = new HashMap<String, ReferralCacheEntry>();
|
||||
referralsMap.put(k, entries);
|
||||
}
|
||||
entries.remove(fromRealm);
|
||||
ReferralCacheEntry newEntry = new ReferralCacheEntry(creds, toRealm);
|
||||
entries.put(fromRealm, newEntry);
|
||||
|
||||
// Remove loops within the cache
|
||||
ReferralCacheEntry current = newEntry;
|
||||
List<ReferralCacheEntry> seen = new LinkedList<>();
|
||||
while (current != null) {
|
||||
if (seen.contains(current)) {
|
||||
// Loop found. Remove the first referral to cut the loop.
|
||||
entries.remove(newEntry.getToRealm());
|
||||
break;
|
||||
}
|
||||
seen.add(current);
|
||||
current = entries.get(current.getToRealm());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtain a referral entry from the cache given a client principal,
|
||||
* a service principal, a user principal (S4U2Self only), a client
|
||||
* service ticket (S4U2Proxy only) and a source KDC realm.
|
||||
*/
|
||||
static synchronized ReferralCacheEntry get(PrincipalName cname,
|
||||
PrincipalName service, PrincipalName user,
|
||||
Ticket[] userSvcTickets, String fromRealm) {
|
||||
Ticket userSvcTicket = (userSvcTickets != null ?
|
||||
userSvcTickets[0] : null);
|
||||
ReferralCacheKey k = new ReferralCacheKey(cname, service,
|
||||
user, userSvcTicket);
|
||||
pruneExpired(k);
|
||||
Map<String, ReferralCacheEntry> entries = referralsMap.get(k);
|
||||
if (entries != null) {
|
||||
ReferralCacheEntry toRef = entries.get(fromRealm);
|
||||
if (toRef != null) {
|
||||
return toRef;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove referral entries from the cache when referral TGTs expire.
|
||||
*/
|
||||
private static void pruneExpired(ReferralCacheKey k) {
|
||||
Date now = new Date();
|
||||
Map<String, ReferralCacheEntry> entries = referralsMap.get(k);
|
||||
if (entries != null) {
|
||||
for (Entry<String, ReferralCacheEntry> mapEntry :
|
||||
entries.entrySet()) {
|
||||
if (mapEntry.getValue().getCreds().getEndTime().before(now)) {
|
||||
entries.remove(mapEntry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
jdkSrc/jdk8/sun/security/krb5/internal/ReplayCache.java
Normal file
72
jdkSrc/jdk8/sun/security/krb5/internal/ReplayCache.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 sun.security.krb5.internal;
|
||||
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.security.krb5.internal.rcache.AuthTimeWithHash;
|
||||
import sun.security.krb5.internal.rcache.MemoryCache;
|
||||
import sun.security.krb5.internal.rcache.DflCache;
|
||||
|
||||
import java.security.AccessController;
|
||||
|
||||
/**
|
||||
* Models the replay cache of an acceptor as described in
|
||||
* RFC 4120 3.2.3.
|
||||
* @since 1.8
|
||||
*/
|
||||
public abstract class ReplayCache {
|
||||
public static ReplayCache getInstance(String type) {
|
||||
if (type == null) {
|
||||
return new MemoryCache();
|
||||
} else if (type.equals("dfl") || type.startsWith("dfl:")) {
|
||||
return new DflCache(type);
|
||||
} else if (type.equals("none")) {
|
||||
return new ReplayCache() {
|
||||
@Override
|
||||
public void checkAndStore(KerberosTime currTime, AuthTimeWithHash time)
|
||||
throws KrbApErrException {
|
||||
// no check at all
|
||||
}
|
||||
};
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown type: " + type);
|
||||
}
|
||||
}
|
||||
public static ReplayCache getInstance() {
|
||||
String type = AccessController.doPrivileged(
|
||||
new GetPropertyAction("sun.security.krb5.rcache"));
|
||||
return getInstance(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts or rejects an AuthTime.
|
||||
* @param currTime the current time
|
||||
* @param time AuthTimeWithHash object calculated from authenticator
|
||||
* @throws KrbApErrException if the authenticator is a replay
|
||||
*/
|
||||
public abstract void checkAndStore(KerberosTime currTime, AuthTimeWithHash time)
|
||||
throws KrbApErrException;
|
||||
}
|
||||
40
jdkSrc/jdk8/sun/security/krb5/internal/SeqNumber.java
Normal file
40
jdkSrc/jdk8/sun/security/krb5/internal/SeqNumber.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
|
||||
public interface SeqNumber {
|
||||
public void randInit();
|
||||
public void init(int start);
|
||||
public int current();
|
||||
public int next();
|
||||
public int step();
|
||||
}
|
||||
68
jdkSrc/jdk8/sun/security/krb5/internal/TGSRep.java
Normal file
68
jdkSrc/jdk8/sun/security/krb5/internal/TGSRep.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.Realm;
|
||||
import sun.security.krb5.RealmException;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class TGSRep extends KDCRep {
|
||||
|
||||
public TGSRep(
|
||||
PAData[] new_pAData,
|
||||
PrincipalName new_cname,
|
||||
Ticket new_ticket,
|
||||
EncryptedData new_encPart
|
||||
) throws IOException {
|
||||
super(new_pAData, new_cname, new_ticket,
|
||||
new_encPart, Krb5.KRB_TGS_REP);
|
||||
}
|
||||
|
||||
public TGSRep(byte[] data) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public TGSRep(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(encoding, Krb5.KRB_TGS_REP);
|
||||
}
|
||||
|
||||
}
|
||||
58
jdkSrc/jdk8/sun/security/krb5/internal/TGSReq.java
Normal file
58
jdkSrc/jdk8/sun/security/krb5/internal/TGSReq.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class TGSReq extends KDCReq {
|
||||
|
||||
public TGSReq(PAData[] new_pAData, KDCReqBody new_reqBody) throws IOException {
|
||||
super(new_pAData, new_reqBody, Krb5.KRB_TGS_REQ);
|
||||
}
|
||||
|
||||
public TGSReq(byte[] data) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public TGSReq(DerValue encoding) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
IOException, KrbException {
|
||||
init(encoding, Krb5.KRB_TGS_REQ);
|
||||
}
|
||||
|
||||
}
|
||||
176
jdkSrc/jdk8/sun/security/krb5/internal/Ticket.java
Normal file
176
jdkSrc/jdk8/sun/security/krb5/internal/Ticket.java
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.Realm;
|
||||
import sun.security.krb5.RealmException;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 Ticket type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* Ticket ::= [APPLICATION 1] SEQUENCE {
|
||||
* tkt-vno [0] INTEGER (5),
|
||||
* realm [1] Realm,
|
||||
* sname [2] PrincipalName,
|
||||
* enc-part [3] EncryptedData -- EncTicketPart
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class Ticket implements Cloneable {
|
||||
public int tkt_vno;
|
||||
public PrincipalName sname;
|
||||
public EncryptedData encPart;
|
||||
|
||||
private Ticket() {
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
Ticket new_ticket = new Ticket();
|
||||
new_ticket.sname = (PrincipalName)sname.clone();
|
||||
new_ticket.encPart = (EncryptedData)encPart.clone();
|
||||
new_ticket.tkt_vno = tkt_vno;
|
||||
return new_ticket;
|
||||
}
|
||||
|
||||
public Ticket(
|
||||
PrincipalName new_sname,
|
||||
EncryptedData new_encPart
|
||||
) {
|
||||
tkt_vno = Krb5.TICKET_VNO;
|
||||
sname = new_sname;
|
||||
encPart = new_encPart;
|
||||
}
|
||||
|
||||
public Ticket(byte[] data) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(new DerValue(data));
|
||||
}
|
||||
|
||||
public Ticket(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
init(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a Ticket object.
|
||||
* @param encoding a single DER-encoded value.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
* @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value.
|
||||
* @exception RealmException if an error occurs while parsing a Realm object.
|
||||
*/
|
||||
|
||||
private void init(DerValue encoding) throws Asn1Exception,
|
||||
RealmException, KrbApErrException, IOException {
|
||||
DerValue der;
|
||||
DerValue subDer;
|
||||
if (((encoding.getTag() & (byte)0x1F) != Krb5.KRB_TKT)
|
||||
|| (encoding.isApplication() != true)
|
||||
|| (encoding.isConstructed() != true))
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
der = encoding.getData().getDerValue();
|
||||
if (der.getTag() != DerValue.tag_Sequence)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
subDer = der.getData().getDerValue();
|
||||
if ((subDer.getTag() & (byte)0x1F) != (byte)0x00)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
tkt_vno = subDer.getData().getBigInteger().intValue();
|
||||
if (tkt_vno != Krb5.TICKET_VNO)
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
|
||||
Realm srealm = Realm.parse(der.getData(), (byte)0x01, false);
|
||||
sname = PrincipalName.parse(der.getData(), (byte)0x02, false, srealm);
|
||||
encPart = EncryptedData.parse(der.getData(), (byte)0x03, false);
|
||||
if (der.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a Ticket object.
|
||||
* @return byte array of encoded ticket object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
DerValue der[] = new DerValue[4];
|
||||
temp.putInteger(BigInteger.valueOf(tkt_vno));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), sname.getRealm().asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), sname.asn1Encode());
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), encPart.asn1Encode());
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
DerOutputStream ticket = new DerOutputStream();
|
||||
ticket.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x01), temp);
|
||||
return ticket.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a Ticket from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicate if this data field is optional
|
||||
* @return an instance of Ticket.
|
||||
*/
|
||||
public static Ticket parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException, RealmException, KrbApErrException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F)!= explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new Ticket(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
194
jdkSrc/jdk8/sun/security/krb5/internal/TicketFlags.java
Normal file
194
jdkSrc/jdk8/sun/security/krb5/internal/TicketFlags.java
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.internal.util.KerberosFlags;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1TicketFlags type.
|
||||
*
|
||||
* TicketFlags ::= BIT STRING
|
||||
* {
|
||||
* reserved(0),
|
||||
* forwardable(1),
|
||||
* forwarded(2),
|
||||
* proxiable(3),
|
||||
* proxy(4),
|
||||
* may-postdate(5),
|
||||
* postdated(6),
|
||||
* invalid(7),
|
||||
* renewable(8),
|
||||
* initial(9),
|
||||
* pre-authent(10),
|
||||
* hw-authent(11),
|
||||
* enc-pa-rep(15)
|
||||
* }
|
||||
*/
|
||||
public class TicketFlags extends KerberosFlags {
|
||||
public TicketFlags() {
|
||||
super(Krb5.TKT_OPTS_MAX + 1);
|
||||
}
|
||||
|
||||
public TicketFlags (boolean[] flags) throws Asn1Exception {
|
||||
super(flags);
|
||||
if (flags.length > Krb5.TKT_OPTS_MAX + 1) {
|
||||
throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
public TicketFlags(int size, byte[] data) throws Asn1Exception {
|
||||
super(size, data);
|
||||
if ((size > data.length * BITS_PER_UNIT) || (size > Krb5.TKT_OPTS_MAX + 1))
|
||||
throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
|
||||
}
|
||||
|
||||
public TicketFlags(DerValue encoding) throws IOException, Asn1Exception {
|
||||
this(encoding.getUnalignedBitString(true).toBooleanArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a ticket flag from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicate if this data field is optional
|
||||
* @return an instance of TicketFlags.
|
||||
*
|
||||
*/
|
||||
public static TicketFlags parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new TicketFlags(subDer);
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
try {
|
||||
return new TicketFlags(this.toBooleanArray());
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean match(LoginOptions options) {
|
||||
boolean matched = false;
|
||||
//We currently only consider if forwardable renewable and proxiable are match
|
||||
if (this.get(Krb5.TKT_OPTS_FORWARDABLE) == (options.get(KDCOptions.FORWARDABLE))) {
|
||||
if (this.get(Krb5.TKT_OPTS_PROXIABLE) == (options.get(KDCOptions.PROXIABLE))) {
|
||||
if (this.get(Krb5.TKT_OPTS_RENEWABLE) == (options.get(KDCOptions.RENEWABLE))) {
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
public boolean match(TicketFlags flags) {
|
||||
boolean matched = true;
|
||||
for (int i = 0; i <= Krb5.TKT_OPTS_MAX; i++) {
|
||||
if (this.get(i) != flags.get(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the string representative of ticket flags.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
boolean[] flags = toBooleanArray();
|
||||
for (int i = 0; i < flags.length; i++) {
|
||||
if (flags[i] == true) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
sb.append("RESERVED;");
|
||||
break;
|
||||
case 1:
|
||||
sb.append("FORWARDABLE;");
|
||||
break;
|
||||
case 2:
|
||||
sb.append("FORWARDED;");
|
||||
break;
|
||||
case 3:
|
||||
sb.append("PROXIABLE;");
|
||||
break;
|
||||
case 4:
|
||||
sb.append("PROXY;");
|
||||
break;
|
||||
case 5:
|
||||
sb.append("MAY-POSTDATE;");
|
||||
break;
|
||||
case 6:
|
||||
sb.append("POSTDATED;");
|
||||
break;
|
||||
case 7:
|
||||
sb.append("INVALID;");
|
||||
break;
|
||||
case 8:
|
||||
sb.append("RENEWABLE;");
|
||||
break;
|
||||
case 9:
|
||||
sb.append("INITIAL;");
|
||||
break;
|
||||
case 10:
|
||||
sb.append("PRE-AUTHENT;");
|
||||
break;
|
||||
case 11:
|
||||
sb.append("HW-AUTHENT;");
|
||||
break;
|
||||
case 15:
|
||||
sb.append("ENC-PA-REP;");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
String result = sb.toString();
|
||||
if (result.length() > 0) {
|
||||
result = result.substring(0, result.length() - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
136
jdkSrc/jdk8/sun/security/krb5/internal/TransitedEncoding.java
Normal file
136
jdkSrc/jdk8/sun/security/krb5/internal/TransitedEncoding.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 TransitedEncoding type.
|
||||
*
|
||||
* <pre>{@code
|
||||
* TransitedEncoding ::= SEQUENCE {
|
||||
* tr-type [0] Int32 -- must be registered --,
|
||||
* contents [1] OCTET STRING
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This definition reflects the Network Working Group RFC 4120
|
||||
* specification available at
|
||||
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
|
||||
* http://www.ietf.org/rfc/rfc4120.txt</a>.
|
||||
*/
|
||||
|
||||
public class TransitedEncoding {
|
||||
public int trType;
|
||||
public byte[] contents;
|
||||
|
||||
public TransitedEncoding(int type, byte[] cont) {
|
||||
trType = type;
|
||||
contents = cont;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a TransitedEncoding object.
|
||||
* @param encoding a Der-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
|
||||
public TransitedEncoding(DerValue encoding) throws Asn1Exception, IOException {
|
||||
if (encoding.getTag() != DerValue.tag_Sequence) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
DerValue der;
|
||||
der = encoding.getData().getDerValue();
|
||||
if ((der.getTag() & 0x1F) == 0x00) {
|
||||
trType = der.getData().getBigInteger().intValue();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
der = encoding.getData().getDerValue();
|
||||
|
||||
if ((der.getTag() & 0x1F) == 0x01) {
|
||||
contents = der.getData().getOctetString();
|
||||
}
|
||||
else
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
if (der.getData().available() > 0)
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a TransitedEncoding object.
|
||||
* @return the byte array of the encoded TransitedEncoding object.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public byte[] asn1Encode() throws Asn1Exception, IOException {
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putInteger(BigInteger.valueOf(trType));
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.putOctetString(contents);
|
||||
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
|
||||
temp = new DerOutputStream();
|
||||
temp.write(DerValue.tag_Sequence, bytes);
|
||||
return temp.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a TransitedEncoding object from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicate if this data field is optional
|
||||
* @return an instance of TransitedEncoding.
|
||||
*
|
||||
*/
|
||||
public static TransitedEncoding parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
if (explicitTag != (der.getTag() & (byte)0x1F)) {
|
||||
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
|
||||
}
|
||||
else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new TransitedEncoding(subDer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import sun.misc.IOUtils;
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.util.KrbDataInputStream;
|
||||
|
||||
/**
|
||||
* This class extends KrbDataInputStream. It is used for parsing FCC-format
|
||||
* data from file to memory.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*
|
||||
*/
|
||||
public class CCacheInputStream extends KrbDataInputStream implements FileCCacheConstants {
|
||||
|
||||
/*
|
||||
* FCC version 2 contains type information for principals. FCC
|
||||
* version 1 does not.
|
||||
*
|
||||
* FCC version 3 contains keyblock encryption type information, and is
|
||||
* architecture independent. Previous versions are not.
|
||||
*
|
||||
* The code will accept version 1, 2, and 3 ccaches, and depending
|
||||
* what KRB5_FCC_DEFAULT_FVNO is set to, it will create version 1, 2,
|
||||
* or 3 FCC caches.
|
||||
*
|
||||
* The default credentials cache should be type 3 for now (see
|
||||
* init_ctx.c).
|
||||
*/
|
||||
/* V4 of the credentials cache format allows for header tags */
|
||||
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public CCacheInputStream(InputStream is){
|
||||
super(is);
|
||||
}
|
||||
|
||||
/* Read tag field introduced in KRB5_FCC_FVNO_4 */
|
||||
// this needs to be public for Kinit.
|
||||
public Tag readTag() throws IOException {
|
||||
char[] buf = new char[1024];
|
||||
int len;
|
||||
int tag = -1;
|
||||
int taglen;
|
||||
Integer time_offset = null;
|
||||
Integer usec_offset = null;
|
||||
|
||||
len = read(2);
|
||||
if (len < 0) {
|
||||
throw new IOException("stop.");
|
||||
}
|
||||
if (len > buf.length) {
|
||||
throw new IOException("Invalid tag length.");
|
||||
}
|
||||
while (len > 0) {
|
||||
tag = read(2);
|
||||
taglen = read(2);
|
||||
switch (tag) {
|
||||
case FCC_TAG_DELTATIME:
|
||||
time_offset = new Integer(read(4));
|
||||
usec_offset = new Integer(read(4));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
len = len - (4 + taglen);
|
||||
}
|
||||
return new Tag(len, tag, time_offset, usec_offset);
|
||||
}
|
||||
/*
|
||||
* In file-based credential cache, the realm name is stored as part of
|
||||
* principal name at the first place.
|
||||
*/
|
||||
// made public for KinitOptions to call directly
|
||||
public PrincipalName readPrincipal(int version) throws IOException, RealmException {
|
||||
int type, length, namelength, kret;
|
||||
String[] pname = null;
|
||||
String realm;
|
||||
/* Read principal type */
|
||||
if (version == KRB5_FCC_FVNO_1) {
|
||||
type = KRB5_NT_UNKNOWN;
|
||||
} else {
|
||||
type = read(4);
|
||||
}
|
||||
length = readLength4();
|
||||
List<String> result = new ArrayList<String>();
|
||||
/*
|
||||
* DCE includes the principal's realm in the count; the new format
|
||||
* does not.
|
||||
*/
|
||||
if (version == KRB5_FCC_FVNO_1)
|
||||
length--;
|
||||
for (int i = 0; i <= length; i++) {
|
||||
namelength = readLength4();
|
||||
byte[] bytes = IOUtils.readExactlyNBytes(this, namelength);
|
||||
result.add(new String(bytes));
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
throw new IOException("No realm or principal");
|
||||
}
|
||||
if (isRealm(result.get(0))) {
|
||||
realm = result.remove(0);
|
||||
if (result.isEmpty()) {
|
||||
throw new IOException("No principal name components");
|
||||
}
|
||||
return new PrincipalName(
|
||||
type,
|
||||
result.toArray(new String[result.size()]),
|
||||
new Realm(realm));
|
||||
}
|
||||
try {
|
||||
return new PrincipalName(
|
||||
type,
|
||||
result.toArray(new String[result.size()]),
|
||||
Realm.getDefault());
|
||||
} catch (RealmException re) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In practice, a realm is named by uppercasing the DNS domain name. we currently
|
||||
* rely on this to determine if the string within the principal identifier is realm
|
||||
* name.
|
||||
*
|
||||
*/
|
||||
boolean isRealm(String str) {
|
||||
try {
|
||||
Realm r = new Realm(str);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
StringTokenizer st = new StringTokenizer(str, ".");
|
||||
String s;
|
||||
while (st.hasMoreTokens()) {
|
||||
s = st.nextToken();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
if (s.charAt(i) >= 141) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
EncryptionKey readKey(int version) throws IOException {
|
||||
int keyType, keyLen;
|
||||
keyType = read(2);
|
||||
if (version == KRB5_FCC_FVNO_3)
|
||||
read(2); /* keytype recorded twice in fvno 3 */
|
||||
keyLen = readLength4();
|
||||
byte[] bytes = IOUtils.readExactlyNBytes(this, keyLen);
|
||||
return new EncryptionKey(bytes, keyType, new Integer(version));
|
||||
}
|
||||
|
||||
long[] readTimes() throws IOException {
|
||||
long[] times = new long[4];
|
||||
times[0] = (long)read(4) * 1000;
|
||||
times[1] = (long)read(4) * 1000;
|
||||
times[2] = (long)read(4) * 1000;
|
||||
times[3] = (long)read(4) * 1000;
|
||||
return times;
|
||||
}
|
||||
|
||||
boolean readskey() throws IOException {
|
||||
if (read() == 0) {
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
|
||||
HostAddress[] readAddr() throws IOException, KrbApErrException {
|
||||
int numAddrs, addrType, addrLength;
|
||||
numAddrs = readLength4();
|
||||
if (numAddrs > 0) {
|
||||
List<HostAddress> addrs = new ArrayList<>();
|
||||
for (int i = 0; i < numAddrs; i++) {
|
||||
addrType = read(2);
|
||||
addrLength = readLength4();
|
||||
if (!(addrLength == 4 || addrLength == 16)) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Incorrect address format.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
byte[] result = new byte[addrLength];
|
||||
for (int j = 0; j < addrLength; j++)
|
||||
result[j] = (byte)read(1);
|
||||
addrs.add(new HostAddress(addrType, result));
|
||||
}
|
||||
return addrs.toArray(new HostAddress[addrs.size()]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
AuthorizationDataEntry[] readAuth() throws IOException {
|
||||
int num, adtype, adlength;
|
||||
num = readLength4();
|
||||
if (num > 0) {
|
||||
List<AuthorizationDataEntry> auData = new ArrayList<>();
|
||||
byte[] data = null;
|
||||
for (int i = 0; i < num; i++) {
|
||||
adtype = read(2);
|
||||
adlength = readLength4();
|
||||
data = IOUtils.readExactlyNBytes(this, adlength);
|
||||
auData.add(new AuthorizationDataEntry(adtype, data));
|
||||
}
|
||||
return auData.toArray(new AuthorizationDataEntry[auData.size()]);
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
byte[] readData() throws IOException {
|
||||
int length;
|
||||
length = readLength4();
|
||||
if (length == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return IOUtils.readExactlyNBytes(this, length);
|
||||
}
|
||||
}
|
||||
|
||||
boolean[] readFlags() throws IOException {
|
||||
boolean[] flags = new boolean[Krb5.TKT_OPTS_MAX+1];
|
||||
int ticketFlags;
|
||||
ticketFlags = read(4);
|
||||
if ((ticketFlags & 0x40000000) == TKT_FLG_FORWARDABLE)
|
||||
flags[1] = true;
|
||||
if ((ticketFlags & 0x20000000) == TKT_FLG_FORWARDED)
|
||||
flags[2] = true;
|
||||
if ((ticketFlags & 0x10000000) == TKT_FLG_PROXIABLE)
|
||||
flags[3] = true;
|
||||
if ((ticketFlags & 0x08000000) == TKT_FLG_PROXY)
|
||||
flags[4] = true;
|
||||
if ((ticketFlags & 0x04000000) == TKT_FLG_MAY_POSTDATE)
|
||||
flags[5] = true;
|
||||
if ((ticketFlags & 0x02000000) == TKT_FLG_POSTDATED)
|
||||
flags[6] = true;
|
||||
if ((ticketFlags & 0x01000000) == TKT_FLG_INVALID)
|
||||
flags[7] = true;
|
||||
if ((ticketFlags & 0x00800000) == TKT_FLG_RENEWABLE)
|
||||
flags[8] = true;
|
||||
if ((ticketFlags & 0x00400000) == TKT_FLG_INITIAL)
|
||||
flags[9] = true;
|
||||
if ((ticketFlags & 0x00200000) == TKT_FLG_PRE_AUTH)
|
||||
flags[10] = true;
|
||||
if ((ticketFlags & 0x00100000) == TKT_FLG_HW_AUTH)
|
||||
flags[11] = true;
|
||||
if (DEBUG) {
|
||||
String msg = ">>> CCacheInputStream: readFlags() ";
|
||||
if (flags[1] == true) {
|
||||
msg += " FORWARDABLE;";
|
||||
}
|
||||
if (flags[2] == true) {
|
||||
msg += " FORWARDED;";
|
||||
}
|
||||
if (flags[3] == true) {
|
||||
msg += " PROXIABLE;";
|
||||
}
|
||||
if (flags[4] == true) {
|
||||
msg += " PROXY;";
|
||||
}
|
||||
if (flags[5] == true) {
|
||||
msg += " MAY_POSTDATE;";
|
||||
}
|
||||
if (flags[6] == true) {
|
||||
msg += " POSTDATED;";
|
||||
}
|
||||
if (flags[7] == true) {
|
||||
msg += " INVALID;";
|
||||
}
|
||||
if (flags[8] == true) {
|
||||
msg += " RENEWABLE;";
|
||||
}
|
||||
|
||||
if (flags[9] == true) {
|
||||
msg += " INITIAL;";
|
||||
}
|
||||
if (flags[10] == true) {
|
||||
msg += " PRE_AUTH;";
|
||||
}
|
||||
if (flags[11] == true) {
|
||||
msg += " HW_AUTH;";
|
||||
}
|
||||
System.out.println(msg);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next cred or config entry in stream.
|
||||
* @return the next cred or config entry, null if data unparseable.
|
||||
*
|
||||
* When data is unparseable, this method makes sure the correct number of
|
||||
* bytes are consumed so it's safe to start reading the next element.
|
||||
*/
|
||||
Object readCred(int version) throws IOException,RealmException, KrbApErrException, Asn1Exception {
|
||||
PrincipalName cpname = null;
|
||||
try {
|
||||
cpname = readPrincipal(version);
|
||||
} catch (Exception e) {
|
||||
// Do not return here. All data for this cred should be fully
|
||||
// consumed so that we can read the next one.
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> client principal is " + cpname);
|
||||
}
|
||||
PrincipalName spname = null;
|
||||
try {
|
||||
spname = readPrincipal(version);
|
||||
} catch (Exception e) {
|
||||
// same as above
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> server principal is " + spname);
|
||||
}
|
||||
EncryptionKey key = readKey(version);
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> key type: " + key.getEType());
|
||||
}
|
||||
long times[] = readTimes();
|
||||
KerberosTime authtime = new KerberosTime(times[0]);
|
||||
KerberosTime starttime =
|
||||
(times[1]==0) ? null : new KerberosTime(times[1]);
|
||||
KerberosTime endtime = new KerberosTime(times[2]);
|
||||
KerberosTime renewTill =
|
||||
(times[3]==0) ? null : new KerberosTime(times[3]);
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> auth time: " + authtime.toDate().toString());
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> start time: " +
|
||||
((starttime==null)?"null":starttime.toDate().toString()));
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> end time: " + endtime.toDate().toString());
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> renew_till time: " +
|
||||
((renewTill==null)?"null":renewTill.toDate().toString()));
|
||||
}
|
||||
boolean skey = readskey();
|
||||
boolean flags[] = readFlags();
|
||||
TicketFlags tFlags = new TicketFlags(flags);
|
||||
HostAddress addr[] = readAddr();
|
||||
HostAddresses addrs = null;
|
||||
if (addr != null) {
|
||||
addrs = new HostAddresses(addr);
|
||||
}
|
||||
AuthorizationDataEntry[] auDataEntry = readAuth();
|
||||
AuthorizationData auData = null;
|
||||
if (auDataEntry != null) {
|
||||
auData = new AuthorizationData(auDataEntry);
|
||||
}
|
||||
byte[] ticketData = readData();
|
||||
byte[] ticketData2 = readData();
|
||||
|
||||
// Skip this cred if either cpname or spname isn't created.
|
||||
if (cpname == null || spname == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (spname.getRealmString().equals("X-CACHECONF:")) {
|
||||
String[] nameParts = spname.getNameStrings();
|
||||
if (nameParts[0].equals("krb5_ccache_conf_data")) {
|
||||
return new CredentialsCache.ConfigEntry(nameParts[1],
|
||||
nameParts.length > 2 ? new PrincipalName(nameParts[2]) : null,
|
||||
ticketData);
|
||||
}
|
||||
}
|
||||
return new Credentials(cpname, spname, key, authtime, starttime,
|
||||
endtime, renewTill, skey, tFlags,
|
||||
addrs, auData,
|
||||
ticketData != null ? new Ticket(ticketData) : null,
|
||||
ticketData2 != null ? new Ticket(ticketData2) : null);
|
||||
} catch (Exception e) { // If any of new Ticket(*) fails.
|
||||
if (DEBUG) {
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import sun.security.krb5.internal.util.KrbDataOutputStream;
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
/**
|
||||
* This class implements a buffered output stream. It provides functions to write FCC-format data to a disk file.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*
|
||||
*/
|
||||
public class CCacheOutputStream extends KrbDataOutputStream implements FileCCacheConstants {
|
||||
public CCacheOutputStream(OutputStream os) {
|
||||
super(os);
|
||||
}
|
||||
|
||||
public void writeHeader(PrincipalName p, int version) throws IOException {
|
||||
write((version & 0xff00) >> 8);
|
||||
write(version & 0x00ff);
|
||||
p.writePrincipal(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a credentials in FCC format to this cache output stream.
|
||||
*
|
||||
* @param creds the credentials to be written to the output stream.
|
||||
* @exception IOException if an I/O exception occurs.
|
||||
* @exception Asn1Exception if an Asn1Exception occurs.
|
||||
*/
|
||||
/*For object data fields which themselves have multiple data fields, such as PrincipalName, EncryptionKey
|
||||
HostAddresses, AuthorizationData, I created corresponding write methods (writePrincipal,
|
||||
writeKey,...) in each class, since converting the object into FCC format data stream
|
||||
should be encapsulated in object itself.
|
||||
*/
|
||||
public void addCreds(Credentials creds) throws IOException, Asn1Exception {
|
||||
creds.cname.writePrincipal(this);
|
||||
creds.sname.writePrincipal(this);
|
||||
creds.key.writeKey(this);
|
||||
write32((int)(creds.authtime.getTime()/1000));
|
||||
if (creds.starttime != null)
|
||||
write32((int)(creds.starttime.getTime()/1000));
|
||||
else write32(0);
|
||||
write32((int)(creds.endtime.getTime()/1000));
|
||||
if (creds.renewTill != null)
|
||||
write32((int)(creds.renewTill.getTime()/1000));
|
||||
|
||||
else write32(0);
|
||||
if (creds.isEncInSKey) {
|
||||
write8(1);
|
||||
}
|
||||
else write8(0);
|
||||
writeFlags(creds.flags);
|
||||
if (creds.caddr == null)
|
||||
write32(0);
|
||||
else
|
||||
creds.caddr.writeAddrs(this);
|
||||
|
||||
if (creds.authorizationData == null) {
|
||||
write32(0);
|
||||
}
|
||||
else
|
||||
creds.authorizationData.writeAuth(this);
|
||||
writeTicket(creds.ticket);
|
||||
writeTicket(creds.secondTicket);
|
||||
}
|
||||
|
||||
public void addConfigEntry(PrincipalName cname, CredentialsCache.ConfigEntry e)
|
||||
throws IOException {
|
||||
cname.writePrincipal(this);
|
||||
e.getSName().writePrincipal(this);
|
||||
write16(0); write16(0); write32(0);
|
||||
write32(0); write32(0); write32(0); write32(0);
|
||||
write8(0);
|
||||
write32(0);
|
||||
write32(0);
|
||||
write32(0);
|
||||
write32(e.getData().length);
|
||||
write(e.getData());
|
||||
write32(0);
|
||||
}
|
||||
|
||||
void writeTicket(Ticket t) throws IOException, Asn1Exception {
|
||||
if (t == null) {
|
||||
write32(0);
|
||||
}
|
||||
else {
|
||||
byte[] bytes = t.asn1Encode();
|
||||
write32(bytes.length);
|
||||
write(bytes, 0, bytes.length);
|
||||
}
|
||||
}
|
||||
|
||||
void writeFlags(TicketFlags flags) throws IOException {
|
||||
int tFlags = 0;
|
||||
boolean[] f = flags.toBooleanArray();
|
||||
if (f[1] == true) {
|
||||
tFlags |= TKT_FLG_FORWARDABLE;
|
||||
}
|
||||
if (f[2] == true) {
|
||||
tFlags |= TKT_FLG_FORWARDED;
|
||||
}
|
||||
if (f[3] == true) {
|
||||
tFlags |= TKT_FLG_PROXIABLE;
|
||||
}
|
||||
if (f[4] == true) {
|
||||
tFlags |= TKT_FLG_PROXY;
|
||||
}
|
||||
if (f[5] == true) {
|
||||
tFlags |= TKT_FLG_MAY_POSTDATE;
|
||||
}
|
||||
if (f[6] == true) {
|
||||
tFlags |= TKT_FLG_POSTDATED;
|
||||
}
|
||||
if (f[7] == true) {
|
||||
tFlags |= TKT_FLG_INVALID;
|
||||
}
|
||||
if (f[8] == true) {
|
||||
tFlags |= TKT_FLG_RENEWABLE;
|
||||
}
|
||||
if (f[9] == true) {
|
||||
tFlags |= TKT_FLG_INITIAL;
|
||||
}
|
||||
if (f[10] == true) {
|
||||
tFlags |= TKT_FLG_PRE_AUTH;
|
||||
}
|
||||
if (f[11] == true) {
|
||||
tFlags |= TKT_FLG_HW_AUTH;
|
||||
}
|
||||
write32(tFlags);
|
||||
|
||||
}
|
||||
}
|
||||
235
jdkSrc/jdk8/sun/security/krb5/internal/ccache/Credentials.java
Normal file
235
jdkSrc/jdk8/sun/security/krb5/internal/ccache/Credentials.java
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
public class Credentials {
|
||||
|
||||
PrincipalName cname;
|
||||
PrincipalName sname;
|
||||
EncryptionKey key;
|
||||
KerberosTime authtime;
|
||||
KerberosTime starttime;//optional
|
||||
KerberosTime endtime;
|
||||
KerberosTime renewTill; //optional
|
||||
HostAddresses caddr; //optional; for proxied tickets only
|
||||
AuthorizationData authorizationData; //optional, not being actually used
|
||||
public boolean isEncInSKey; // true if ticket is encrypted in another ticket's skey
|
||||
TicketFlags flags;
|
||||
Ticket ticket;
|
||||
Ticket secondTicket; //optional
|
||||
private boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public Credentials(
|
||||
PrincipalName new_cname,
|
||||
PrincipalName new_sname,
|
||||
EncryptionKey new_key,
|
||||
KerberosTime new_authtime,
|
||||
KerberosTime new_starttime,
|
||||
KerberosTime new_endtime,
|
||||
KerberosTime new_renewTill,
|
||||
boolean new_isEncInSKey,
|
||||
TicketFlags new_flags,
|
||||
HostAddresses new_caddr,
|
||||
AuthorizationData new_authData,
|
||||
Ticket new_ticket,
|
||||
Ticket new_secondTicket) {
|
||||
cname = (PrincipalName) new_cname.clone();
|
||||
sname = (PrincipalName) new_sname.clone();
|
||||
key = (EncryptionKey) new_key.clone();
|
||||
|
||||
authtime = new_authtime;
|
||||
starttime = new_starttime;
|
||||
endtime = new_endtime;
|
||||
renewTill = new_renewTill;
|
||||
|
||||
if (new_caddr != null) {
|
||||
caddr = (HostAddresses) new_caddr.clone();
|
||||
}
|
||||
if (new_authData != null) {
|
||||
authorizationData = (AuthorizationData) new_authData.clone();
|
||||
}
|
||||
|
||||
isEncInSKey = new_isEncInSKey;
|
||||
flags = (TicketFlags) new_flags.clone();
|
||||
ticket = (Ticket) (new_ticket.clone());
|
||||
if (new_secondTicket != null) {
|
||||
secondTicket = (Ticket) new_secondTicket.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public Credentials(
|
||||
KDCRep kdcRep,
|
||||
Ticket new_secondTicket,
|
||||
AuthorizationData new_authorizationData,
|
||||
boolean new_isEncInSKey) {
|
||||
if (kdcRep.encKDCRepPart == null) //can't store while encrypted
|
||||
{
|
||||
return;
|
||||
}
|
||||
cname = (PrincipalName) kdcRep.cname.clone();
|
||||
ticket = (Ticket) kdcRep.ticket.clone();
|
||||
key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
|
||||
flags = (TicketFlags) kdcRep.encKDCRepPart.flags.clone();
|
||||
authtime = kdcRep.encKDCRepPart.authtime;
|
||||
starttime = kdcRep.encKDCRepPart.starttime;
|
||||
endtime = kdcRep.encKDCRepPart.endtime;
|
||||
renewTill = kdcRep.encKDCRepPart.renewTill;
|
||||
|
||||
sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
|
||||
caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone();
|
||||
secondTicket = (Ticket) new_secondTicket.clone();
|
||||
authorizationData =
|
||||
(AuthorizationData) new_authorizationData.clone();
|
||||
isEncInSKey = new_isEncInSKey;
|
||||
}
|
||||
|
||||
public Credentials(KDCRep kdcRep) {
|
||||
this(kdcRep, null);
|
||||
}
|
||||
|
||||
public Credentials(KDCRep kdcRep, Ticket new_ticket) {
|
||||
sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
|
||||
cname = (PrincipalName) kdcRep.cname.clone();
|
||||
key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
|
||||
authtime = kdcRep.encKDCRepPart.authtime;
|
||||
starttime = kdcRep.encKDCRepPart.starttime;
|
||||
endtime = kdcRep.encKDCRepPart.endtime;
|
||||
renewTill = kdcRep.encKDCRepPart.renewTill;
|
||||
// if (kdcRep.msgType == Krb5.KRB_AS_REP) {
|
||||
// isEncInSKey = false;
|
||||
// secondTicket = null;
|
||||
// }
|
||||
flags = kdcRep.encKDCRepPart.flags;
|
||||
if (kdcRep.encKDCRepPart.caddr != null) {
|
||||
caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone();
|
||||
} else {
|
||||
caddr = null;
|
||||
}
|
||||
ticket = (Ticket) kdcRep.ticket.clone();
|
||||
if (new_ticket != null) {
|
||||
secondTicket = (Ticket) new_ticket.clone();
|
||||
isEncInSKey = true;
|
||||
} else {
|
||||
secondTicket = null;
|
||||
isEncInSKey = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this credential is expired
|
||||
*/
|
||||
public boolean isValid() {
|
||||
boolean valid = true;
|
||||
if (endtime.getTime() < System.currentTimeMillis()) {
|
||||
valid = false;
|
||||
} else if (starttime != null) {
|
||||
if (starttime.getTime() > System.currentTimeMillis()) {
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
if (authtime.getTime() > System.currentTimeMillis()) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
public PrincipalName getServicePrincipal() throws RealmException {
|
||||
return sname;
|
||||
}
|
||||
|
||||
public Ticket getTicket() throws RealmException {
|
||||
return ticket;
|
||||
}
|
||||
|
||||
public PrincipalName getServicePrincipal2() throws RealmException {
|
||||
return secondTicket == null ? null : secondTicket.sname;
|
||||
}
|
||||
|
||||
public PrincipalName getClientPrincipal() throws RealmException {
|
||||
return cname;
|
||||
}
|
||||
|
||||
public sun.security.krb5.Credentials setKrbCreds() {
|
||||
// Note: We will not pass authorizationData to s.s.k.Credentials. The
|
||||
// field in that class will be passed to Krb5Context as the return
|
||||
// value of ExtendedGSSContext.inquireSecContext(KRB5_GET_AUTHZ_DATA),
|
||||
// which is documented as the authData in the service ticket. That
|
||||
// is on the acceptor side.
|
||||
//
|
||||
// This class is for the initiator side. Also, authdata inside a ccache
|
||||
// is most likely to be the one in Authenticator in PA-TGS-REQ encoded
|
||||
// in TGS-REQ, therefore only stored with a service ticket. Currently
|
||||
// in Java, we only reads TGTs.
|
||||
return new sun.security.krb5.Credentials(ticket, cname, null, sname,
|
||||
null, key, flags, authtime, starttime, endtime, renewTill,
|
||||
caddr);
|
||||
}
|
||||
|
||||
public KerberosTime getStartTime() {
|
||||
return starttime;
|
||||
}
|
||||
|
||||
public KerberosTime getAuthTime() {
|
||||
return authtime;
|
||||
}
|
||||
|
||||
public KerberosTime getEndTime() {
|
||||
return endtime;
|
||||
}
|
||||
|
||||
public KerberosTime getRenewTill() {
|
||||
return renewTill;
|
||||
}
|
||||
|
||||
public TicketFlags getTicketFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public int getEType() {
|
||||
return key.getEType();
|
||||
}
|
||||
|
||||
public EncryptionKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public int getTktEType() {
|
||||
return ticket.encPart.getEType();
|
||||
}
|
||||
|
||||
public int getTktEType2() {
|
||||
return (secondTicket == null) ? 0 : secondTicket.encPart.getEType();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* CredentialsCache stores credentials(tickets, session keys, etc) in a semi-permanent store
|
||||
* for later use by different program.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public abstract class CredentialsCache {
|
||||
static CredentialsCache singleton = null;
|
||||
static String cacheName;
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public static CredentialsCache getInstance(PrincipalName principal) {
|
||||
return FileCredentialsCache.acquireInstance(principal, null);
|
||||
}
|
||||
|
||||
public static CredentialsCache getInstance(String cache) {
|
||||
if ((cache.length() >= 5) && cache.substring(0, 5).equalsIgnoreCase("FILE:")) {
|
||||
return FileCredentialsCache.acquireInstance(null, cache.substring(5));
|
||||
}
|
||||
// XXX else, memory credential cache
|
||||
// default is file credential cache.
|
||||
return FileCredentialsCache.acquireInstance(null, cache);
|
||||
}
|
||||
|
||||
public static CredentialsCache getInstance(PrincipalName principal,
|
||||
String cache) {
|
||||
|
||||
// XXX Modify this to use URL framework of the JDK
|
||||
if (cache != null &&
|
||||
(cache.length() >= 5) &&
|
||||
cache.regionMatches(true, 0, "FILE:", 0, 5)) {
|
||||
return FileCredentialsCache.acquireInstance(principal,
|
||||
cache.substring(5));
|
||||
}
|
||||
|
||||
// When cache is null, read the default cache.
|
||||
// XXX else ..we haven't provided support for memory credential cache
|
||||
// yet. (supported in native code)
|
||||
// default is file credentials cache.
|
||||
return FileCredentialsCache.acquireInstance(principal, cache);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default credentials cache.
|
||||
*/
|
||||
public static CredentialsCache getInstance() {
|
||||
// Default credentials cache is file-based.
|
||||
return FileCredentialsCache.acquireInstance();
|
||||
}
|
||||
|
||||
public static CredentialsCache create(PrincipalName principal, String name) {
|
||||
if (name == null) {
|
||||
throw new RuntimeException("cache name error");
|
||||
}
|
||||
if ((name.length() >= 5)
|
||||
&& name.regionMatches(true, 0, "FILE:", 0, 5)) {
|
||||
name = name.substring(5);
|
||||
return (FileCredentialsCache.New(principal, name));
|
||||
}
|
||||
// else return file credentials cache
|
||||
// default is file credentials cache.
|
||||
return (FileCredentialsCache.New(principal, name));
|
||||
}
|
||||
|
||||
public static CredentialsCache create(PrincipalName principal) {
|
||||
// create a default credentials cache for a specified principal
|
||||
return (FileCredentialsCache.New(principal));
|
||||
}
|
||||
|
||||
public static String cacheName() {
|
||||
return cacheName;
|
||||
}
|
||||
|
||||
public abstract PrincipalName getPrimaryPrincipal();
|
||||
public abstract void update(Credentials c);
|
||||
public abstract void save() throws IOException, KrbException;
|
||||
public abstract Credentials[] getCredsList();
|
||||
public abstract Credentials getDefaultCreds();
|
||||
public abstract sun.security.krb5.Credentials getInitialCreds();
|
||||
public abstract Credentials getCreds(PrincipalName sname);
|
||||
public abstract Credentials getCreds(LoginOptions options, PrincipalName sname);
|
||||
public abstract void addConfigEntry(ConfigEntry e);
|
||||
public abstract List<ConfigEntry> getConfigEntries();
|
||||
|
||||
public ConfigEntry getConfigEntry(String name) {
|
||||
List<ConfigEntry> entries = getConfigEntries();
|
||||
if (entries != null) {
|
||||
for (ConfigEntry e : entries) {
|
||||
if (e.getName().equals(name)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class ConfigEntry {
|
||||
|
||||
public ConfigEntry(String name, PrincipalName princ, byte[] data) {
|
||||
this.name = name;
|
||||
this.princ = princ;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final PrincipalName princ;
|
||||
private final byte[] data; // not worth cloning
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public PrincipalName getPrinc() {
|
||||
return princ;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + (princ != null ? ("." + princ) : "")
|
||||
+ ": " + new String(data);
|
||||
}
|
||||
|
||||
public PrincipalName getSName() {
|
||||
try {
|
||||
return new PrincipalName("krb5_ccache_conf_data/" + name
|
||||
+ (princ != null ? ("/" + princ) : "")
|
||||
+ "@X-CACHECONF:");
|
||||
} catch (RealmException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
/**
|
||||
* Constants used by file-based credential cache classes.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*
|
||||
*/
|
||||
public interface FileCCacheConstants {
|
||||
/*
|
||||
* FCC version 2 contains type information for principals. FCC
|
||||
* version 1 does not.
|
||||
*
|
||||
* FCC version 3 contains keyblock encryption type information, and is
|
||||
* architecture independent. Previous versions are not. */
|
||||
public final int KRB5_FCC_FVNO_1 = 0x501;
|
||||
public final int KRB5_FCC_FVNO_2 = 0x502;
|
||||
public final int KRB5_FCC_FVNO_3 = 0x503;
|
||||
public final int KRB5_FCC_FVNO_4 = 0x504;
|
||||
public final int FCC_TAG_DELTATIME = 1;
|
||||
public final int KRB5_NT_UNKNOWN = 0;
|
||||
public final int TKT_FLG_FORWARDABLE = 0x40000000;
|
||||
public final int TKT_FLG_FORWARDED = 0x20000000;
|
||||
public final int TKT_FLG_PROXIABLE = 0x10000000;
|
||||
public final int TKT_FLG_PROXY = 0x08000000;
|
||||
public final int TKT_FLG_MAY_POSTDATE = 0x04000000;
|
||||
public final int TKT_FLG_POSTDATED = 0x02000000;
|
||||
public final int TKT_FLG_INVALID = 0x01000000;
|
||||
public final int TKT_FLG_RENEWABLE = 0x00800000;
|
||||
public final int TKT_FLG_INITIAL = 0x00400000;
|
||||
public final int TKT_FLG_PRE_AUTH = 0x00200000;
|
||||
public final int TKT_FLG_HW_AUTH = 0x00100000;
|
||||
}
|
||||
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
*
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
* ===========================================================================
|
||||
*
|
||||
*/
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.util.SecurityProperties;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
/**
|
||||
* CredentialsCache stores credentials(tickets, session keys, etc) in a
|
||||
* semi-permanent store
|
||||
* for later use by different program.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
* @author Ram Marti
|
||||
*/
|
||||
|
||||
public class FileCredentialsCache extends CredentialsCache
|
||||
implements FileCCacheConstants {
|
||||
public int version;
|
||||
public Tag tag; // optional
|
||||
public PrincipalName primaryPrincipal;
|
||||
private Vector<Credentials> credentialsList;
|
||||
private static String dir;
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public static synchronized FileCredentialsCache acquireInstance(
|
||||
PrincipalName principal, String cache) {
|
||||
try {
|
||||
FileCredentialsCache fcc = new FileCredentialsCache();
|
||||
if (cache == null) {
|
||||
cacheName = FileCredentialsCache.getDefaultCacheName();
|
||||
} else {
|
||||
cacheName = FileCredentialsCache.checkValidation(cache);
|
||||
}
|
||||
if ((cacheName == null) || !(new File(cacheName)).exists()) {
|
||||
// invalid cache name or the file doesn't exist
|
||||
return null;
|
||||
}
|
||||
if (principal != null) {
|
||||
fcc.primaryPrincipal = principal;
|
||||
}
|
||||
fcc.load(cacheName);
|
||||
return fcc;
|
||||
} catch (IOException e) {
|
||||
// we don't handle it now, instead we return a null at the end.
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (KrbException e) {
|
||||
// we don't handle it now, instead we return a null at the end.
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static FileCredentialsCache acquireInstance() {
|
||||
return acquireInstance(null, null);
|
||||
}
|
||||
|
||||
static synchronized FileCredentialsCache New(PrincipalName principal,
|
||||
String name) {
|
||||
try {
|
||||
FileCredentialsCache fcc = new FileCredentialsCache();
|
||||
cacheName = FileCredentialsCache.checkValidation(name);
|
||||
if (cacheName == null) {
|
||||
// invalid cache name or the file doesn't exist
|
||||
return null;
|
||||
}
|
||||
fcc.init(principal, cacheName);
|
||||
return fcc;
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
catch (KrbException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static synchronized FileCredentialsCache New(PrincipalName principal) {
|
||||
try {
|
||||
FileCredentialsCache fcc = new FileCredentialsCache();
|
||||
cacheName = FileCredentialsCache.getDefaultCacheName();
|
||||
fcc.init(principal, cacheName);
|
||||
return fcc;
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (KrbException e) {
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private FileCredentialsCache() {
|
||||
}
|
||||
|
||||
boolean exists(String cache) {
|
||||
File file = new File(cache);
|
||||
if (file.exists()) {
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
synchronized void init(PrincipalName principal, String name)
|
||||
throws IOException, KrbException {
|
||||
primaryPrincipal = principal;
|
||||
try (FileOutputStream fos = new FileOutputStream(name);
|
||||
CCacheOutputStream cos = new CCacheOutputStream(fos)) {
|
||||
version = KRB5_FCC_FVNO_3;
|
||||
cos.writeHeader(primaryPrincipal, version);
|
||||
}
|
||||
load(name);
|
||||
}
|
||||
|
||||
synchronized void load(String name) throws IOException, KrbException {
|
||||
PrincipalName p;
|
||||
try (FileInputStream fis = new FileInputStream(name);
|
||||
CCacheInputStream cis = new CCacheInputStream(fis)) {
|
||||
version = cis.readVersion();
|
||||
if (version == KRB5_FCC_FVNO_4) {
|
||||
tag = cis.readTag();
|
||||
} else {
|
||||
tag = null;
|
||||
if (version == KRB5_FCC_FVNO_1 || version == KRB5_FCC_FVNO_2) {
|
||||
cis.setNativeByteOrder();
|
||||
}
|
||||
}
|
||||
p = cis.readPrincipal(version);
|
||||
|
||||
if (primaryPrincipal != null) {
|
||||
if (!(primaryPrincipal.match(p))) {
|
||||
throw new IOException("Primary principals don't match.");
|
||||
}
|
||||
} else
|
||||
primaryPrincipal = p;
|
||||
credentialsList = new Vector<Credentials>();
|
||||
while (cis.available() > 0) {
|
||||
Object cred = cis.readCred(version);
|
||||
if (cred != null) {
|
||||
if (cred instanceof Credentials) {
|
||||
credentialsList.addElement((Credentials)cred);
|
||||
} else {
|
||||
addConfigEntry((CredentialsCache.ConfigEntry)cred);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the credentials list. If the specified credentials for the
|
||||
* service is new, add it to the list. If there is an entry in the list,
|
||||
* replace the old credentials with the new one.
|
||||
* @param c the credentials.
|
||||
*/
|
||||
|
||||
public synchronized void update(Credentials c) {
|
||||
if (credentialsList != null) {
|
||||
if (credentialsList.isEmpty()) {
|
||||
credentialsList.addElement(c);
|
||||
} else {
|
||||
Credentials tmp = null;
|
||||
boolean matched = false;
|
||||
|
||||
for (int i = 0; i < credentialsList.size(); i++) {
|
||||
tmp = credentialsList.elementAt(i);
|
||||
if (match(c.sname.getNameStrings(),
|
||||
tmp.sname.getNameStrings()) &&
|
||||
((c.sname.getRealmString()).equalsIgnoreCase(
|
||||
tmp.sname.getRealmString()))) {
|
||||
matched = true;
|
||||
if (c.endtime.getTime() >= tmp.endtime.getTime()) {
|
||||
if (DEBUG) {
|
||||
System.out.println(" >>> FileCredentialsCache "
|
||||
+ "Ticket matched, overwrite "
|
||||
+ "the old one.");
|
||||
}
|
||||
credentialsList.removeElementAt(i);
|
||||
credentialsList.addElement(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matched == false) {
|
||||
if (DEBUG) {
|
||||
System.out.println(" >>> FileCredentialsCache Ticket "
|
||||
+ "not exactly matched, "
|
||||
+ "add new one into cache.");
|
||||
}
|
||||
|
||||
credentialsList.addElement(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized PrincipalName getPrimaryPrincipal() {
|
||||
return primaryPrincipal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves the credentials cache file to the disk.
|
||||
*/
|
||||
public synchronized void save() throws IOException, Asn1Exception {
|
||||
try (FileOutputStream fos = new FileOutputStream(cacheName);
|
||||
CCacheOutputStream cos = new CCacheOutputStream(fos)) {
|
||||
cos.writeHeader(primaryPrincipal, version);
|
||||
Credentials[] tmp = null;
|
||||
if ((tmp = getCredsList()) != null) {
|
||||
for (int i = 0; i < tmp.length; i++) {
|
||||
cos.addCreds(tmp[i]);
|
||||
}
|
||||
}
|
||||
for (ConfigEntry e : getConfigEntries()) {
|
||||
cos.addConfigEntry(primaryPrincipal, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean match(String[] s1, String[] s2) {
|
||||
if (s1.length != s2.length) {
|
||||
return false;
|
||||
} else {
|
||||
for (int i = 0; i < s1.length; i++) {
|
||||
if (!(s1[i].equalsIgnoreCase(s2[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of credentials entries in the cache file.
|
||||
*/
|
||||
public synchronized Credentials[] getCredsList() {
|
||||
if ((credentialsList == null) || (credentialsList.isEmpty())) {
|
||||
return null;
|
||||
} else {
|
||||
Credentials[] tmp = new Credentials[credentialsList.size()];
|
||||
for (int i = 0; i < credentialsList.size(); i++) {
|
||||
tmp[i] = credentialsList.elementAt(i);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Credentials getCreds(LoginOptions options, PrincipalName sname) {
|
||||
if (options == null) {
|
||||
return getCreds(sname);
|
||||
} else {
|
||||
Credentials[] list = getCredsList();
|
||||
if (list == null) {
|
||||
return null;
|
||||
} else {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (sname.match(list[i].sname)) {
|
||||
if (list[i].flags.match(options)) {
|
||||
return list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ConfigEntry> configEntries = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addConfigEntry(ConfigEntry e) {
|
||||
configEntries.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConfigEntry> getConfigEntries() {
|
||||
return Collections.unmodifiableList(configEntries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a credentials for a specified service.
|
||||
* @param sname service principal name.
|
||||
*/
|
||||
public Credentials getCreds(PrincipalName sname) {
|
||||
Credentials[] list = getCredsList();
|
||||
if (list == null) {
|
||||
return null;
|
||||
} else {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (sname.match(list[i].sname)) {
|
||||
return list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public sun.security.krb5.Credentials getInitialCreds() {
|
||||
|
||||
Credentials defaultCreds = getDefaultCreds();
|
||||
if (defaultCreds == null) {
|
||||
return null;
|
||||
}
|
||||
sun.security.krb5.Credentials tgt = defaultCreds.setKrbCreds();
|
||||
|
||||
CredentialsCache.ConfigEntry entry = getConfigEntry("proxy_impersonator");
|
||||
if (entry == null) {
|
||||
if (DEBUG) {
|
||||
System.out.println("get normal credential");
|
||||
}
|
||||
return tgt;
|
||||
}
|
||||
|
||||
boolean force;
|
||||
String prop = SecurityProperties.privilegedGetOverridable(
|
||||
"jdk.security.krb5.default.initiate.credential");
|
||||
if (prop == null) {
|
||||
prop = "always-impersonate";
|
||||
}
|
||||
switch (prop) {
|
||||
case "no-impersonate": // never try impersonation
|
||||
if (DEBUG) {
|
||||
System.out.println("get normal credential");
|
||||
}
|
||||
return tgt;
|
||||
case "try-impersonate":
|
||||
force = false;
|
||||
break;
|
||||
case "always-impersonate":
|
||||
force = true;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Invalid jdk.security.krb5.default.initiate.credential");
|
||||
}
|
||||
|
||||
try {
|
||||
PrincipalName service = new PrincipalName(
|
||||
new String(entry.getData(), StandardCharsets.UTF_8));
|
||||
if (!tgt.getClient().equals(service)) {
|
||||
if (DEBUG) {
|
||||
System.out.println("proxy_impersonator does not match service name");
|
||||
}
|
||||
return force ? null : tgt;
|
||||
}
|
||||
PrincipalName client = getPrimaryPrincipal();
|
||||
Credentials proxy = null;
|
||||
for (Credentials c : getCredsList()) {
|
||||
if (c.getClientPrincipal().equals(client)
|
||||
&& c.getServicePrincipal().equals(service)) {
|
||||
proxy = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (proxy == null) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Cannot find evidence ticket in ccache");
|
||||
}
|
||||
return force ? null : tgt;
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println("Get proxied credential");
|
||||
}
|
||||
return tgt.setProxy(proxy.setKrbCreds());
|
||||
} catch (KrbException e) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Impersonation with ccache failed");
|
||||
}
|
||||
return force ? null : tgt;
|
||||
}
|
||||
}
|
||||
|
||||
public Credentials getDefaultCreds() {
|
||||
Credentials[] list = getCredsList();
|
||||
if (list == null) {
|
||||
return null;
|
||||
} else {
|
||||
for (int i = list.length-1; i >= 0; i--) {
|
||||
if (list[i].sname.toString().startsWith("krbtgt")) {
|
||||
String[] nameStrings = list[i].sname.getNameStrings();
|
||||
// find the TGT for the current realm krbtgt/realm@realm
|
||||
if (nameStrings[1].equals(list[i].sname.getRealm().toString())) {
|
||||
return list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns path name of the credentials cache file.
|
||||
* The path name is searched in the following order:
|
||||
*
|
||||
* 1. KRB5CCNAME (bare file name without FILE:)
|
||||
* 2. /tmp/krb5cc_<uid> on unix systems
|
||||
* 3. <user.home>/krb5cc_<user.name>
|
||||
* 4. <user.home>/krb5cc (if can't get <user.name>)
|
||||
*/
|
||||
|
||||
public static String getDefaultCacheName() {
|
||||
|
||||
String stdCacheNameComponent = "krb5cc";
|
||||
String name;
|
||||
|
||||
// The env var can start with TYPE:, we only support FILE: here.
|
||||
// https://docs.oracle.com/cd/E19082-01/819-2252/6n4i8rtr3/index.html
|
||||
name = java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<String>() {
|
||||
@Override
|
||||
public String run() {
|
||||
String cache = System.getenv("KRB5CCNAME");
|
||||
if (cache != null &&
|
||||
(cache.length() >= 5) &&
|
||||
cache.regionMatches(true, 0, "FILE:", 0, 5)) {
|
||||
cache = cache.substring(5);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
});
|
||||
if (name != null) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>KinitOptions cache name is " + name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// get cache name from system.property
|
||||
String osname =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("os.name"));
|
||||
|
||||
/*
|
||||
* For Unix platforms we use the default cache name to be
|
||||
* /tmp/krbcc_uid ; for all other platforms we use
|
||||
* {user_home}/krb5_cc{user_name}
|
||||
* Please note that for Windows 2K we will use LSA to get
|
||||
* the TGT from the the default cache even before we come here;
|
||||
* however when we create cache we will create a cache under
|
||||
* {user_home}/krb5_cc{user_name} for non-Unix platforms including
|
||||
* Windows 2K.
|
||||
*/
|
||||
|
||||
if (osname != null) {
|
||||
String cmd = null;
|
||||
String uidStr = null;
|
||||
long uid = 0;
|
||||
|
||||
if (!osname.startsWith("Windows")) {
|
||||
try {
|
||||
Class<?> c = Class.forName
|
||||
("com.sun.security.auth.module.UnixSystem");
|
||||
Constructor<?> constructor = c.getConstructor();
|
||||
Object obj = constructor.newInstance();
|
||||
Method method = c.getMethod("getUid");
|
||||
uid = ((Long)method.invoke(obj)).longValue();
|
||||
name = File.separator + "tmp" +
|
||||
File.separator + stdCacheNameComponent + "_" + uid;
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>KinitOptions cache name is " +
|
||||
name);
|
||||
}
|
||||
return name;
|
||||
} catch (Exception e) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Exception in obtaining uid " +
|
||||
"for Unix platforms " +
|
||||
"Using user's home directory");
|
||||
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we did not get the uid;
|
||||
|
||||
|
||||
String user_name =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("user.name"));
|
||||
|
||||
String user_home =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("user.home"));
|
||||
|
||||
if (user_home == null) {
|
||||
user_home =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("user.dir"));
|
||||
}
|
||||
|
||||
if (user_name != null) {
|
||||
name = user_home + File.separator +
|
||||
stdCacheNameComponent + "_" + user_name;
|
||||
} else {
|
||||
name = user_home + File.separator + stdCacheNameComponent;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>KinitOptions cache name is " + name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public static String checkValidation(String name) {
|
||||
String fullname = null;
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
// get full path name
|
||||
fullname = (new File(name)).getCanonicalPath();
|
||||
File fCheck = new File(fullname);
|
||||
if (!(fCheck.exists())) {
|
||||
// get absolute directory
|
||||
File temp = new File(fCheck.getParent());
|
||||
// test if the directory exists
|
||||
if (!(temp.isDirectory()))
|
||||
fullname = null;
|
||||
temp = null;
|
||||
}
|
||||
fCheck = null;
|
||||
|
||||
} catch (IOException e) {
|
||||
fullname = null; // invalid name
|
||||
}
|
||||
return fullname;
|
||||
}
|
||||
|
||||
|
||||
private static String exec(String c) {
|
||||
StringTokenizer st = new StringTokenizer(c);
|
||||
Vector<String> v = new Vector<>();
|
||||
while (st.hasMoreTokens()) {
|
||||
v.addElement(st.nextToken());
|
||||
}
|
||||
final String[] command = new String[v.size()];
|
||||
v.copyInto(command);
|
||||
try {
|
||||
|
||||
Process p =
|
||||
java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<Process> () {
|
||||
public Process run() {
|
||||
try {
|
||||
return (Runtime.getRuntime().exec(command));
|
||||
} catch (java.io.IOException e) {
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (p == null) {
|
||||
// exception occurred during executing the command
|
||||
return null;
|
||||
}
|
||||
|
||||
BufferedReader commandResult =
|
||||
new BufferedReader
|
||||
(new InputStreamReader(p.getInputStream(), "8859_1"));
|
||||
String s1 = null;
|
||||
if ((command.length == 1) &&
|
||||
(command[0].equals("/usr/bin/env"))) {
|
||||
while ((s1 = commandResult.readLine()) != null) {
|
||||
if (s1.length() >= 11) {
|
||||
if ((s1.substring(0, 11)).equalsIgnoreCase
|
||||
("KRB5CCNAME=")) {
|
||||
s1 = s1.substring(11);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else s1 = commandResult.readLine();
|
||||
commandResult.close();
|
||||
return s1;
|
||||
} catch (Exception e) {
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
//Windows supports the "API: cache" type, which is a shared memory cache. This is
|
||||
//implemented by krbcc32.dll as part of the MIT Kerberos for Win32 distribution.
|
||||
//MemoryCredentialsCache will provide future functions to access shared memeory cache on
|
||||
//Windows platform. Native code implementation may be necessary.
|
||||
/**
|
||||
* This class extends CredentialsCache. It is used for accessing data in shared memory
|
||||
* cache on Windows platforms.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public abstract class MemoryCredentialsCache extends CredentialsCache {
|
||||
|
||||
private static CredentialsCache getCCacheInstance(PrincipalName p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static CredentialsCache getCCacheInstance(PrincipalName p, File cacheFile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public abstract boolean exists(String cache);
|
||||
|
||||
public abstract void update(Credentials c);
|
||||
|
||||
public abstract void save() throws IOException, KrbException;
|
||||
|
||||
public abstract Credentials[] getCredsList();
|
||||
|
||||
public abstract Credentials getCreds(PrincipalName sname) ;
|
||||
|
||||
public abstract PrincipalName getPrimaryPrincipal();
|
||||
|
||||
}
|
||||
73
jdkSrc/jdk8/sun/security/krb5/internal/ccache/Tag.java
Normal file
73
jdkSrc/jdk8/sun/security/krb5/internal/ccache/Tag.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* tag field introduced in KRB5_FCC_FVNO_4
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public class Tag{
|
||||
int length;
|
||||
int tag;
|
||||
int tagLen;
|
||||
Integer time_offset;
|
||||
Integer usec_offset;
|
||||
|
||||
public Tag(int len, int new_tag, Integer new_time, Integer new_usec) {
|
||||
tag = new_tag;
|
||||
tagLen = 8;
|
||||
time_offset = new_time;
|
||||
usec_offset = new_usec;
|
||||
length = 4 + tagLen;
|
||||
}
|
||||
public Tag(int new_tag) {
|
||||
tag = new_tag;
|
||||
tagLen = 0;
|
||||
length = 4 + tagLen;
|
||||
}
|
||||
public byte[] toByteArray() {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
os.write(length);
|
||||
os.write(tag);
|
||||
os.write(tagLen);
|
||||
if (time_offset != null) {
|
||||
os.write(time_offset.intValue());
|
||||
}
|
||||
if (usec_offset != null) {
|
||||
os.write(usec_offset.intValue());
|
||||
}
|
||||
return os.toByteArray();
|
||||
}
|
||||
}
|
||||
85
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Aes128.java
Normal file
85
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Aes128.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2005, 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 sun.security.krb5.internal.crypto;
|
||||
|
||||
import sun.security.krb5.internal.crypto.dk.AesDkCrypto;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Class with static methods for doing AES operations.
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class Aes128 {
|
||||
private static final AesDkCrypto CRYPTO = new AesDkCrypto(128);
|
||||
|
||||
private Aes128() {
|
||||
}
|
||||
|
||||
public static byte[] stringToKey(char[] password, String salt, byte[] params)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.stringToKey(password, salt, params);
|
||||
}
|
||||
|
||||
// in bytes
|
||||
public static int getChecksumLength() {
|
||||
return CRYPTO.getChecksumLength();
|
||||
}
|
||||
|
||||
public static byte[] calculateChecksum(byte[] baseKey, int usage,
|
||||
byte[] input, int start, int len) throws GeneralSecurityException {
|
||||
return CRYPTO.calculateChecksum(baseKey, usage, input, start, len);
|
||||
}
|
||||
|
||||
public static byte[] encrypt(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
return CRYPTO.encrypt(baseKey, usage, ivec, null /* new_ivec */,
|
||||
plaintext, start, len);
|
||||
}
|
||||
|
||||
/* Encrypt plaintext; do not add confounder, or checksum */
|
||||
public static byte[] encryptRaw(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
return CRYPTO.encryptRaw(baseKey, usage, ivec, plaintext, start, len);
|
||||
}
|
||||
|
||||
public static byte[] decrypt(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.decrypt(baseKey, usage, ivec, ciphertext, start, len);
|
||||
}
|
||||
|
||||
/* Decrypt ciphertext; do not remove confounder, or check checksum */
|
||||
public static byte[] decryptRaw(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.decryptRaw(baseKey, usage, ivec, ciphertext, start, len);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.security.krb5.internal.crypto;
|
||||
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.security.GeneralSecurityException;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.Checksum;
|
||||
|
||||
/*
|
||||
* This class encapsulates the encryption type for AES128
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public final class Aes128CtsHmacSha1EType extends EType {
|
||||
|
||||
public int eType() {
|
||||
return EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96;
|
||||
}
|
||||
|
||||
public int minimumPadSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return blockSize();
|
||||
}
|
||||
|
||||
public int checksumType() {
|
||||
return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128;
|
||||
}
|
||||
|
||||
public int checksumSize() {
|
||||
return Aes128.getChecksumLength();
|
||||
}
|
||||
|
||||
public int blockSize() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_AES;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 16; // bytes
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte[] data, byte[] key, int usage)
|
||||
throws KrbCryptoException {
|
||||
byte[] ivec = new byte[blockSize()];
|
||||
return encrypt(data, key, ivec, usage);
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte[] data, byte[] key, byte[] ivec, int usage)
|
||||
throws KrbCryptoException {
|
||||
try {
|
||||
return Aes128.encrypt(key, usage, ivec, data, 0, data.length);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, int usage)
|
||||
throws KrbApErrException, KrbCryptoException {
|
||||
byte[] ivec = new byte[blockSize()];
|
||||
return decrypt(cipher, key, ivec, usage);
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, byte[] ivec, int usage)
|
||||
throws KrbApErrException, KrbCryptoException {
|
||||
try {
|
||||
return Aes128.decrypt(key, usage, ivec, cipher, 0, cipher.length);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
// Override default, because our decrypted data does not return confounder
|
||||
// Should eventually get rid of EType.decryptedData and
|
||||
// EncryptedData.decryptedData altogether
|
||||
public byte[] decryptedData(byte[] data) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
88
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Aes256.java
Normal file
88
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Aes256.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2005, 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 sun.security.krb5.internal.crypto;
|
||||
|
||||
import sun.security.krb5.internal.crypto.dk.AesDkCrypto;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Class with static methods for doing AES operations.
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class Aes256 {
|
||||
private static final AesDkCrypto CRYPTO = new AesDkCrypto(256);
|
||||
|
||||
private Aes256() {
|
||||
}
|
||||
|
||||
public static byte[] stringToKey(char[] password, String salt, byte[] params)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.stringToKey(password, salt, params);
|
||||
}
|
||||
|
||||
// in bytes
|
||||
public static int getChecksumLength() {
|
||||
return CRYPTO.getChecksumLength();
|
||||
}
|
||||
|
||||
public static byte[] calculateChecksum(byte[] baseKey, int usage,
|
||||
byte[] input, int start, int len) throws GeneralSecurityException {
|
||||
return CRYPTO.calculateChecksum(baseKey, usage, input, start, len);
|
||||
}
|
||||
|
||||
public static byte[] encrypt(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
return CRYPTO.encrypt(baseKey, usage, ivec, null /* new_ivec */,
|
||||
plaintext, start, len);
|
||||
}
|
||||
|
||||
/* Encrypt plaintext; do not add confounder, padding, or checksum */
|
||||
public static byte[] encryptRaw(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
return CRYPTO.encryptRaw(baseKey, usage, ivec, plaintext, start, len);
|
||||
}
|
||||
|
||||
public static byte[] decrypt(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.decrypt(baseKey, usage, ivec, ciphertext, start, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypt ciphertext; do not remove confounder, padding, or check
|
||||
* checksum
|
||||
*/
|
||||
public static byte[] decryptRaw(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.decryptRaw(baseKey, usage, ivec, ciphertext, start, len);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.security.krb5.internal.crypto;
|
||||
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.security.GeneralSecurityException;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.Checksum;
|
||||
|
||||
/*
|
||||
* This class encapsulates the encryption type for AES256
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public final class Aes256CtsHmacSha1EType extends EType {
|
||||
|
||||
public int eType() {
|
||||
return EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96;
|
||||
}
|
||||
|
||||
public int minimumPadSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return blockSize();
|
||||
}
|
||||
|
||||
public int checksumType() {
|
||||
return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256;
|
||||
}
|
||||
|
||||
public int checksumSize() {
|
||||
return Aes256.getChecksumLength();
|
||||
}
|
||||
|
||||
public int blockSize() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_AES;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 32; // bytes
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte[] data, byte[] key, int usage)
|
||||
throws KrbCryptoException {
|
||||
byte[] ivec = new byte[blockSize()];
|
||||
return encrypt(data, key, ivec, usage);
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte[] data, byte[] key, byte[] ivec, int usage)
|
||||
throws KrbCryptoException {
|
||||
try {
|
||||
return Aes256.encrypt(key, usage, ivec, data, 0, data.length);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, int usage)
|
||||
throws KrbApErrException, KrbCryptoException {
|
||||
byte[] ivec = new byte[blockSize()];
|
||||
return decrypt(cipher, key, ivec, usage);
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, byte[] ivec, int usage)
|
||||
throws KrbApErrException, KrbCryptoException {
|
||||
try {
|
||||
return Aes256.decrypt(key, usage, ivec, cipher, 0, cipher.length);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
// Override default, because our decrypted data does not return confounder
|
||||
// Should eventually get rid of EType.decryptedData and
|
||||
// EncryptedData.decryptedData altogether
|
||||
public byte[] decryptedData(byte[] data) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
100
jdkSrc/jdk8/sun/security/krb5/internal/crypto/ArcFourHmac.java
Normal file
100
jdkSrc/jdk8/sun/security/krb5/internal/crypto/ArcFourHmac.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.security.krb5.internal.crypto;
|
||||
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.internal.crypto.dk.ArcFourCrypto;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Class with static methods for doing RC4-HMAC operations.
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class ArcFourHmac {
|
||||
private static final ArcFourCrypto CRYPTO = new ArcFourCrypto(128);
|
||||
|
||||
private ArcFourHmac() {
|
||||
}
|
||||
|
||||
public static byte[] stringToKey(char[] password)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.stringToKey(password);
|
||||
}
|
||||
|
||||
// in bytes
|
||||
public static int getChecksumLength() {
|
||||
return CRYPTO.getChecksumLength();
|
||||
}
|
||||
|
||||
public static byte[] calculateChecksum(byte[] baseKey, int usage,
|
||||
byte[] input, int start, int len) throws GeneralSecurityException {
|
||||
return CRYPTO.calculateChecksum(baseKey, usage, input, start, len);
|
||||
}
|
||||
|
||||
/* Encrypt Sequence Number */
|
||||
public static byte[] encryptSeq(byte[] baseKey, int usage,
|
||||
byte[] checksum, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
return CRYPTO.encryptSeq(baseKey, usage, checksum, plaintext, start, len);
|
||||
}
|
||||
|
||||
/* Decrypt Sequence Number */
|
||||
public static byte[] decryptSeq(byte[] baseKey, int usage, byte[] checksum,
|
||||
byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
return CRYPTO.decryptSeq(baseKey, usage, checksum, ciphertext, start, len);
|
||||
}
|
||||
|
||||
public static byte[] encrypt(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
return CRYPTO.encrypt(baseKey, usage, ivec, null /* new_ivec */,
|
||||
plaintext, start, len);
|
||||
}
|
||||
|
||||
/* Encrypt plaintext; do not add confounder, or checksum */
|
||||
public static byte[] encryptRaw(byte[] baseKey, int usage,
|
||||
byte[] seqNum, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
return CRYPTO.encryptRaw(baseKey, usage, seqNum, plaintext, start, len);
|
||||
}
|
||||
|
||||
public static byte[] decrypt(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.decrypt(baseKey, usage, ivec, ciphertext, start, len);
|
||||
}
|
||||
|
||||
/* Decrypt ciphertext; do not remove confounder, or check checksum */
|
||||
public static byte[] decryptRaw(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len, byte[] seqNum)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.decryptRaw(baseKey, usage, ivec, ciphertext, start, len, seqNum);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.security.krb5.internal.crypto;
|
||||
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.security.GeneralSecurityException;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.Checksum;
|
||||
|
||||
/*
|
||||
* This class encapsulates the encryption type for RC4-HMAC
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public final class ArcFourHmacEType extends EType {
|
||||
|
||||
public int eType() {
|
||||
return EncryptedData.ETYPE_ARCFOUR_HMAC;
|
||||
}
|
||||
|
||||
public int minimumPadSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public int checksumType() {
|
||||
return Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR;
|
||||
}
|
||||
|
||||
public int checksumSize() {
|
||||
return ArcFourHmac.getChecksumLength();
|
||||
}
|
||||
|
||||
public int blockSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_ARCFOUR_HMAC;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 16; // bytes
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte[] data, byte[] key, int usage)
|
||||
throws KrbCryptoException {
|
||||
byte[] ivec = new byte[blockSize()];
|
||||
return encrypt(data, key, ivec, usage);
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte[] data, byte[] key, byte[] ivec, int usage)
|
||||
throws KrbCryptoException {
|
||||
try {
|
||||
return ArcFourHmac.encrypt(key, usage, ivec, data, 0, data.length);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, int usage)
|
||||
throws KrbApErrException, KrbCryptoException {
|
||||
byte[] ivec = new byte[blockSize()];
|
||||
return decrypt(cipher, key, ivec, usage);
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, byte[] ivec, int usage)
|
||||
throws KrbApErrException, KrbCryptoException {
|
||||
try {
|
||||
return ArcFourHmac.decrypt(key, usage, ivec, cipher, 0, cipher.length);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
// Override default, because our decrypted data does not return confounder
|
||||
// Should eventually get rid of EType.decryptedData and
|
||||
// EncryptedData.decryptedData altogether
|
||||
public byte[] decryptedData(byte[] data) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
152
jdkSrc/jdk8/sun/security/krb5/internal/crypto/CksumType.java
Normal file
152
jdkSrc/jdk8/sun/security/krb5/internal/crypto/CksumType.java
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.crypto;
|
||||
|
||||
import sun.security.krb5.Checksum;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
public abstract class CksumType {
|
||||
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public static CksumType getInstance(int cksumTypeConst)
|
||||
throws KdcErrException {
|
||||
CksumType cksumType = null;
|
||||
String cksumTypeName = null;
|
||||
switch (cksumTypeConst) {
|
||||
case Checksum.CKSUMTYPE_CRC32:
|
||||
cksumType = new Crc32CksumType();
|
||||
cksumTypeName = "sun.security.krb5.internal.crypto.Crc32CksumType";
|
||||
break;
|
||||
case Checksum.CKSUMTYPE_DES_MAC:
|
||||
cksumType = new DesMacCksumType();
|
||||
cksumTypeName = "sun.security.krb5.internal.crypto.DesMacCksumType";
|
||||
break;
|
||||
case Checksum.CKSUMTYPE_DES_MAC_K:
|
||||
cksumType = new DesMacKCksumType();
|
||||
cksumTypeName =
|
||||
"sun.security.krb5.internal.crypto.DesMacKCksumType";
|
||||
break;
|
||||
case Checksum.CKSUMTYPE_RSA_MD5:
|
||||
cksumType = new RsaMd5CksumType();
|
||||
cksumTypeName = "sun.security.krb5.internal.crypto.RsaMd5CksumType";
|
||||
break;
|
||||
case Checksum.CKSUMTYPE_RSA_MD5_DES:
|
||||
cksumType = new RsaMd5DesCksumType();
|
||||
cksumTypeName =
|
||||
"sun.security.krb5.internal.crypto.RsaMd5DesCksumType";
|
||||
break;
|
||||
|
||||
case Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD:
|
||||
cksumType = new HmacSha1Des3KdCksumType();
|
||||
cksumTypeName =
|
||||
"sun.security.krb5.internal.crypto.HmacSha1Des3KdCksumType";
|
||||
break;
|
||||
|
||||
case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128:
|
||||
cksumType = new HmacSha1Aes128CksumType();
|
||||
cksumTypeName =
|
||||
"sun.security.krb5.internal.crypto.HmacSha1Aes128CksumType";
|
||||
break;
|
||||
|
||||
case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256:
|
||||
cksumType = new HmacSha1Aes256CksumType();
|
||||
cksumTypeName =
|
||||
"sun.security.krb5.internal.crypto.HmacSha1Aes256CksumType";
|
||||
break;
|
||||
|
||||
case Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR:
|
||||
cksumType = new HmacMd5ArcFourCksumType();
|
||||
cksumTypeName =
|
||||
"sun.security.krb5.internal.crypto.HmacMd5ArcFourCksumType";
|
||||
break;
|
||||
|
||||
// currently we don't support MD4.
|
||||
case Checksum.CKSUMTYPE_RSA_MD4_DES_K:
|
||||
// cksumType = new RsaMd4DesKCksumType();
|
||||
// cksumTypeName =
|
||||
// "sun.security.krb5.internal.crypto.RsaMd4DesKCksumType";
|
||||
case Checksum.CKSUMTYPE_RSA_MD4:
|
||||
// cksumType = new RsaMd4CksumType();
|
||||
// linux box support rsamd4, how to solve conflict?
|
||||
// cksumTypeName =
|
||||
// "sun.security.krb5.internal.crypto.RsaMd4CksumType";
|
||||
case Checksum.CKSUMTYPE_RSA_MD4_DES:
|
||||
// cksumType = new RsaMd4DesCksumType();
|
||||
// cksumTypeName =
|
||||
// "sun.security.krb5.internal.crypto.RsaMd4DesCksumType";
|
||||
|
||||
default:
|
||||
throw new KdcErrException(Krb5.KDC_ERR_SUMTYPE_NOSUPP);
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> CksumType: " + cksumTypeName);
|
||||
}
|
||||
return cksumType;
|
||||
}
|
||||
|
||||
public abstract int confounderSize();
|
||||
|
||||
public abstract int cksumType();
|
||||
|
||||
public abstract boolean isKeyed();
|
||||
|
||||
public abstract int cksumSize();
|
||||
|
||||
public abstract int keyType();
|
||||
|
||||
public abstract int keySize();
|
||||
|
||||
// Note: key and usage will be ignored for an unkeyed checksum.
|
||||
public abstract byte[] calculateChecksum(byte[] data, int size,
|
||||
byte[] key, int usage) throws KrbCryptoException;
|
||||
|
||||
// Note: key and usage will be ignored for an unkeyed checksum.
|
||||
public abstract boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage) throws KrbCryptoException;
|
||||
|
||||
public static boolean isChecksumEqual(byte[] cksum1, byte[] cksum2) {
|
||||
if (cksum1 == cksum2)
|
||||
return true;
|
||||
if ((cksum1 == null && cksum2 != null) ||
|
||||
(cksum1 != null && cksum2 == null))
|
||||
return false;
|
||||
if (cksum1.length != cksum2.length)
|
||||
return false;
|
||||
for (int i = 0; i < cksum1.length; i++)
|
||||
if (cksum1[i] != cksum2[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.crypto;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
public class Crc32CksumType extends CksumType {
|
||||
|
||||
public Crc32CksumType() {
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int cksumType() {
|
||||
return Checksum.CKSUMTYPE_CRC32;
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int cksumSize() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_NULL;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public byte[] calculateChecksum(byte[] data, int size,
|
||||
byte[] key, int usage) {
|
||||
return crc32.byte2crc32sum_bytes(data, size);
|
||||
}
|
||||
|
||||
public boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage) {
|
||||
return CksumType.isChecksumEqual(checksum,
|
||||
crc32.byte2crc32sum_bytes(data));
|
||||
}
|
||||
|
||||
public static byte[] int2quad(long input) {
|
||||
byte[] output = new byte[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
output[i] = (byte)((input >>> (i * 8)) & 0xff);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static long bytes2long(byte[] input) {
|
||||
long result = 0;
|
||||
|
||||
result |= (((long)input[0]) & 0xffL) << 24;
|
||||
result |= (((long)input[1]) & 0xffL) << 16;
|
||||
result |= (((long)input[2]) & 0xffL) << 8;
|
||||
result |= (((long)input[3]) & 0xffL);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
368
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Des.java
Normal file
368
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Des.java
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.crypto;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import java.util.Arrays;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
public final class Des {
|
||||
|
||||
// RFC 3961 demands that UTF-8 encoding be used in DES's
|
||||
// string-to-key function. For historical reasons, some
|
||||
// implementations use a locale-specific encoding. Even
|
||||
// so, when the client and server use different locales,
|
||||
// they must agree on a common value, normally the one
|
||||
// used when the password is set/reset.
|
||||
//
|
||||
// The following system property is provided to perform the
|
||||
// string-to-key encoding. When set, the specified charset
|
||||
// name is used. Otherwise, the system default charset.
|
||||
|
||||
private final static String CHARSET =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new GetPropertyAction("sun.security.krb5.msinterop.des.s2kcharset"));
|
||||
|
||||
private static final long[] bad_keys = {
|
||||
0x0101010101010101L, 0xfefefefefefefefeL,
|
||||
0x1f1f1f1f1f1f1f1fL, 0xe0e0e0e0e0e0e0e0L,
|
||||
0x01fe01fe01fe01feL, 0xfe01fe01fe01fe01L,
|
||||
0x1fe01fe00ef10ef1L, 0xe01fe01ff10ef10eL,
|
||||
0x01e001e001f101f1L, 0xe001e001f101f101L,
|
||||
0x1ffe1ffe0efe0efeL, 0xfe1ffe1ffe0efe0eL,
|
||||
0x011f011f010e010eL, 0x1f011f010e010e01L,
|
||||
0xe0fee0fef1fef1feL, 0xfee0fee0fef1fef1L
|
||||
};
|
||||
|
||||
private static final byte[] good_parity = {
|
||||
1, 1, 2, 2, 4, 4, 7, 7,
|
||||
8, 8, 11, 11, 13, 13, 14, 14,
|
||||
16, 16, 19, 19, 21, 21, 22, 22,
|
||||
25, 25, 26, 26, 28, 28, 31, 31,
|
||||
32, 32, 35, 35, 37, 37, 38, 38,
|
||||
41, 41, 42, 42, 44, 44, 47, 47,
|
||||
49, 49, 50, 50, 52, 52, 55, 55,
|
||||
56, 56, 59, 59, 61, 61, 62, 62,
|
||||
64, 64, 67, 67, 69, 69, 70, 70,
|
||||
73, 73, 74, 74, 76, 76, 79, 79,
|
||||
81, 81, 82, 82, 84, 84, 87, 87,
|
||||
88, 88, 91, 91, 93, 93, 94, 94,
|
||||
97, 97, 98, 98, 100, 100, 103, 103,
|
||||
104, 104, 107, 107, 109, 109, 110, 110,
|
||||
112, 112, 115, 115, 117, 117, 118, 118,
|
||||
121, 121, 122, 122, 124, 124, 127, 127,
|
||||
(byte)128, (byte)128, (byte)131, (byte)131,
|
||||
(byte)133, (byte)133, (byte)134, (byte)134,
|
||||
(byte)137, (byte)137, (byte)138, (byte)138,
|
||||
(byte)140, (byte)140, (byte)143, (byte)143,
|
||||
(byte)145, (byte)145, (byte)146, (byte)146,
|
||||
(byte)148, (byte)148, (byte)151, (byte)151,
|
||||
(byte)152, (byte)152, (byte)155, (byte)155,
|
||||
(byte)157, (byte)157, (byte)158, (byte)158,
|
||||
(byte)161, (byte)161, (byte)162, (byte)162,
|
||||
(byte)164, (byte)164, (byte)167, (byte)167,
|
||||
(byte)168, (byte)168, (byte)171, (byte)171,
|
||||
(byte)173, (byte)173, (byte)174, (byte)174,
|
||||
(byte)176, (byte)176, (byte)179, (byte)179,
|
||||
(byte)181, (byte)181, (byte)182, (byte)182,
|
||||
(byte)185, (byte)185, (byte)186, (byte)186,
|
||||
(byte)188, (byte)188, (byte)191, (byte)191,
|
||||
(byte)193, (byte)193, (byte)194, (byte)194,
|
||||
(byte)196, (byte)196, (byte)199, (byte)199,
|
||||
(byte)200, (byte)200, (byte)203, (byte)203,
|
||||
(byte)205, (byte)205, (byte)206, (byte)206,
|
||||
(byte)208, (byte)208, (byte)211, (byte)211,
|
||||
(byte)213, (byte)213, (byte)214, (byte)214,
|
||||
(byte)217, (byte)217, (byte)218, (byte)218,
|
||||
(byte)220, (byte)220, (byte)223, (byte)223,
|
||||
(byte)224, (byte)224, (byte)227, (byte)227,
|
||||
(byte)229, (byte)229, (byte)230, (byte)230,
|
||||
(byte)233, (byte)233, (byte)234, (byte)234,
|
||||
(byte)236, (byte)236, (byte)239, (byte)239,
|
||||
(byte)241, (byte)241, (byte)242, (byte)242,
|
||||
(byte)244, (byte)244, (byte)247, (byte)247,
|
||||
(byte)248, (byte)248, (byte)251, (byte)251,
|
||||
(byte)253, (byte)253, (byte)254, (byte)254
|
||||
};
|
||||
|
||||
public static final byte[] set_parity(byte[] key) {
|
||||
for (int i=0; i < 8; i++) {
|
||||
key[i] = good_parity[key[i] & 0xff];
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public static final long set_parity(long key) {
|
||||
return octet2long(set_parity(long2octet(key)));
|
||||
}
|
||||
|
||||
public static final boolean bad_key(long key) {
|
||||
for (int i = 0; i < bad_keys.length; i++) {
|
||||
if (bad_keys[i] == key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final boolean bad_key(byte[] key) {
|
||||
return bad_key(octet2long(key));
|
||||
}
|
||||
|
||||
public static long octet2long(byte[] input) {
|
||||
return octet2long(input, 0);
|
||||
}
|
||||
|
||||
public static long octet2long(byte[] input, int offset) { //convert a 8-byte to a long
|
||||
long result = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i + offset < input.length) {
|
||||
result |= (((long)input[i + offset]) & 0xffL) << ((7 - i) * 8);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] long2octet(long input) {
|
||||
byte[] output = new byte[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
output[i] = (byte)((input >>> ((7 - i) * 8)) & 0xffL);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static void long2octet(long input, byte[] output) {
|
||||
long2octet(input, output, 0);
|
||||
}
|
||||
|
||||
public static void long2octet(long input, byte[] output, int offset) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i + offset < output.length) {
|
||||
output[i + offset] =
|
||||
(byte)((input >>> ((7 - i) * 8)) & 0xffL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DES cipher in Electronic Codebook mode, with no padding.
|
||||
* @param input plain text.
|
||||
* @param output the buffer for the result.
|
||||
* @param key DES the key to encrypt the text.
|
||||
* @param ivec initialization vector.
|
||||
*
|
||||
* @created by Yanni Zhang, Dec 6 99.
|
||||
*/
|
||||
public static void cbc_encrypt (
|
||||
byte[] input,
|
||||
byte[] output,
|
||||
byte[] key,
|
||||
byte[] ivec,
|
||||
boolean encrypt) throws KrbCryptoException {
|
||||
|
||||
Cipher cipher = null;
|
||||
|
||||
try {
|
||||
cipher = Cipher.getInstance("DES/CBC/NoPadding");
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException("JCE provider may not be installed. "
|
||||
+ e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
IvParameterSpec params = new IvParameterSpec(ivec);
|
||||
SecretKeySpec skSpec = new SecretKeySpec(key, "DES");
|
||||
try {
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
|
||||
// SecretKey sk = skf.generateSecret(skSpec);
|
||||
SecretKey sk = (SecretKey) skSpec;
|
||||
if (encrypt)
|
||||
cipher.init(Cipher.ENCRYPT_MODE, sk, params);
|
||||
else
|
||||
cipher.init(Cipher.DECRYPT_MODE, sk, params);
|
||||
byte[] result;
|
||||
result = cipher.doFinal(input);
|
||||
System.arraycopy(result, 0, output, 0, result.length);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates DES key from the password.
|
||||
* @param passwdChars a char[] used to create the key.
|
||||
* @return DES key.
|
||||
*
|
||||
* @modified by Yanni Zhang, Dec 6, 99
|
||||
*/
|
||||
public static long char_to_key(char[] passwdChars) throws KrbCryptoException {
|
||||
long key = 0;
|
||||
long octet, octet1, octet2 = 0;
|
||||
byte[] cbytes = null;
|
||||
|
||||
// Convert password to byte array
|
||||
try {
|
||||
if (CHARSET == null) {
|
||||
cbytes = (new String(passwdChars)).getBytes();
|
||||
} else {
|
||||
cbytes = (new String(passwdChars)).getBytes(CHARSET);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// clear-up sensitive information
|
||||
if (cbytes != null) {
|
||||
Arrays.fill(cbytes, 0, cbytes.length, (byte) 0);
|
||||
}
|
||||
KrbCryptoException ce =
|
||||
new KrbCryptoException("Unable to convert passwd, " + e);
|
||||
ce.initCause(e);
|
||||
throw ce;
|
||||
}
|
||||
|
||||
// pad data
|
||||
byte[] passwdBytes = pad(cbytes);
|
||||
|
||||
byte[] newkey = new byte[8];
|
||||
int length = (passwdBytes.length / 8) + (passwdBytes.length % 8 == 0 ? 0 : 1);
|
||||
for (int i = 0; i < length; i++) {
|
||||
octet = octet2long(passwdBytes, i * 8) & 0x7f7f7f7f7f7f7f7fL;
|
||||
if (i % 2 == 1) {
|
||||
octet1 = 0;
|
||||
for (int j = 0; j < 64; j++) {
|
||||
octet1 |= ((octet & (1L << j)) >>> j) << (63 - j);
|
||||
}
|
||||
octet = octet1 >>> 1;
|
||||
}
|
||||
key ^= (octet << 1);
|
||||
}
|
||||
key = set_parity(key);
|
||||
if (bad_key(key)) {
|
||||
byte [] temp = long2octet(key);
|
||||
temp[7] ^= 0xf0;
|
||||
key = octet2long(temp);
|
||||
}
|
||||
|
||||
newkey = des_cksum(long2octet(key), passwdBytes, long2octet(key));
|
||||
key = octet2long(set_parity(newkey));
|
||||
if (bad_key(key)) {
|
||||
byte [] temp = long2octet(key);
|
||||
temp[7] ^= 0xf0;
|
||||
key = octet2long(temp);
|
||||
}
|
||||
|
||||
// clear-up sensitive information
|
||||
if (cbytes != null) {
|
||||
Arrays.fill(cbytes, 0, cbytes.length, (byte) 0);
|
||||
}
|
||||
if (passwdBytes != null) {
|
||||
Arrays.fill(passwdBytes, 0, passwdBytes.length, (byte) 0);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts the message blocks using DES CBC and output the
|
||||
* final block of 8-byte ciphertext.
|
||||
* @param ivec Initialization vector.
|
||||
* @param msg Input message as an byte array.
|
||||
* @param key DES key to encrypt the message.
|
||||
* @return the last block of ciphertext.
|
||||
*
|
||||
* @created by Yanni Zhang, Dec 6, 99.
|
||||
*/
|
||||
public static byte[] des_cksum(byte[] ivec, byte[] msg, byte[] key) throws KrbCryptoException {
|
||||
Cipher cipher = null;
|
||||
|
||||
byte[] result = new byte[8];
|
||||
try{
|
||||
cipher = Cipher.getInstance("DES/CBC/NoPadding");
|
||||
} catch (Exception e) {
|
||||
KrbCryptoException ke = new KrbCryptoException("JCE provider may not be installed. "
|
||||
+ e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
IvParameterSpec params = new IvParameterSpec(ivec);
|
||||
SecretKeySpec skSpec = new SecretKeySpec(key, "DES");
|
||||
try {
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
|
||||
// SecretKey sk = skf.generateSecret(skSpec);
|
||||
SecretKey sk = (SecretKey) skSpec;
|
||||
cipher.init(Cipher.ENCRYPT_MODE, sk, params);
|
||||
for (int i = 0; i < msg.length / 8; i++) {
|
||||
result = cipher.doFinal(msg, i * 8, 8);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, sk, (new IvParameterSpec(result)));
|
||||
}
|
||||
}
|
||||
catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pads the data so that its length is a multiple of 8 bytes.
|
||||
* @param data the raw data.
|
||||
* @return the data being padded.
|
||||
*
|
||||
* @created by Yanni Zhang, Dec 6 99. //Kerberos does not use PKCS5 padding.
|
||||
*/
|
||||
static byte[] pad(byte[] data) {
|
||||
int len;
|
||||
if (data.length < 8) len = data.length;
|
||||
else len = data.length % 8;
|
||||
if (len == 0) return data;
|
||||
else {
|
||||
byte[] padding = new byte[ 8 - len + data.length];
|
||||
for (int i = padding.length - 1; i > data.length - 1; i--) {
|
||||
padding[i] = 0;
|
||||
}
|
||||
System.arraycopy(data, 0, padding, 0, data.length);
|
||||
return padding;
|
||||
}
|
||||
}
|
||||
|
||||
// Caller is responsible for clearing password
|
||||
public static byte[] string_to_key_bytes(char[] passwdChars)
|
||||
throws KrbCryptoException {
|
||||
return long2octet(char_to_key(passwdChars));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user