feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
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));
|
||||
}
|
||||
}
|
||||
91
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Des3.java
Normal file
91
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Des3.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.
|
||||
*/
|
||||
|
||||
|
||||
package sun.security.krb5.internal.crypto;
|
||||
|
||||
import sun.security.krb5.internal.crypto.dk.Des3DkCrypto;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Class with static methods for doing Triple DES operations.
|
||||
*/
|
||||
public class Des3 {
|
||||
private static final Des3DkCrypto CRYPTO = new Des3DkCrypto();
|
||||
|
||||
private Des3() {
|
||||
}
|
||||
|
||||
public static byte[] stringToKey(char[] chars)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.stringToKey(chars);
|
||||
}
|
||||
|
||||
public static byte[] parityFix(byte[] value)
|
||||
throws GeneralSecurityException {
|
||||
return CRYPTO.parityFix(value);
|
||||
}
|
||||
|
||||
// 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,108 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public final class Des3CbcHmacSha1KdEType extends EType {
|
||||
|
||||
public int eType() {
|
||||
return EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD;
|
||||
}
|
||||
|
||||
public int minimumPadSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return blockSize();
|
||||
}
|
||||
|
||||
public int checksumType() {
|
||||
return Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD;
|
||||
}
|
||||
|
||||
public int checksumSize() {
|
||||
return Des3.getChecksumLength();
|
||||
}
|
||||
|
||||
public int blockSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_DES3;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 24; // 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 Des3.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 Des3.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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.EncryptedData;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
public class DesCbcCrcEType extends DesCbcEType {
|
||||
|
||||
public DesCbcCrcEType() {
|
||||
}
|
||||
|
||||
public int eType() {
|
||||
return EncryptedData.ETYPE_DES_CBC_CRC;
|
||||
}
|
||||
|
||||
public int minimumPadSize() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public int checksumType() {
|
||||
return Checksum.CKSUMTYPE_RSA_MD5;
|
||||
}
|
||||
|
||||
public int checksumSize() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts data using DES in CBC mode with CRC32.
|
||||
* @param data the data to be encrypted.
|
||||
* @param key the secret key to encrypt the data. It is also used as initialization vector during cipher block chaining.
|
||||
* @return the buffer for cipher text.
|
||||
*
|
||||
* @written by Yanni Zhang, Dec 10, 1999
|
||||
*/
|
||||
public byte[] encrypt(byte[] data, byte[] key, int usage)
|
||||
throws KrbCryptoException {
|
||||
return encrypt(data, key, key, usage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts data with provided key using DES in CBC mode with CRC32.
|
||||
* @param cipher the cipher text to be decrypted.
|
||||
* @param key the secret key to decrypt the data.
|
||||
*
|
||||
* @written by Yanni Zhang, Dec 10, 1999
|
||||
*/
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, int usage)
|
||||
throws KrbApErrException, KrbCryptoException{
|
||||
return decrypt(cipher, key, key, usage);
|
||||
}
|
||||
|
||||
protected byte[] calculateChecksum(byte[] data, int size) {
|
||||
return crc32.byte2crc32sum_bytes(data, size);
|
||||
}
|
||||
|
||||
}
|
||||
222
jdkSrc/jdk8/sun/security/krb5/internal/crypto/DesCbcEType.java
Normal file
222
jdkSrc/jdk8/sun/security/krb5/internal/crypto/DesCbcEType.java
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* 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.internal.crypto;
|
||||
|
||||
import sun.security.krb5.Confounder;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
abstract class DesCbcEType extends EType {
|
||||
protected abstract byte[] calculateChecksum(byte[] data, int size)
|
||||
throws KrbCryptoException;
|
||||
|
||||
public int blockSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_DES;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts the data using DES in CBC mode.
|
||||
* @param data the buffer for plain text.
|
||||
* @param key the key to encrypt the data.
|
||||
* @return the buffer for encrypted data.
|
||||
*
|
||||
* @written by Yanni Zhang, Dec 6 99.
|
||||
*/
|
||||
|
||||
public byte[] encrypt(byte[] data, byte[] key, int usage)
|
||||
throws KrbCryptoException {
|
||||
byte[] ivec = new byte[keySize()];
|
||||
return encrypt(data, key, ivec, usage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts the data using DES in CBC mode.
|
||||
* @param data the buffer for plain text.
|
||||
* @param key the key to encrypt the data.
|
||||
* @param ivec initialization vector.
|
||||
* @return buffer for encrypted data.
|
||||
*
|
||||
* @modified by Yanni Zhang, Feb 24 00.
|
||||
*/
|
||||
public byte[] encrypt(byte[] data, byte[] key, byte[] ivec,
|
||||
int usage) throws KrbCryptoException {
|
||||
|
||||
/*
|
||||
* To meet export control requirements, double check that the
|
||||
* key being used is no longer than 64 bits.
|
||||
*
|
||||
* Note that from a protocol point of view, an
|
||||
* algorithm that is not DES will be rejected before this
|
||||
* point. Also, a DES key that is not 64 bits will be
|
||||
* rejected by a good implementations of JCE.
|
||||
*/
|
||||
if (key.length > 8)
|
||||
throw new KrbCryptoException("Invalid DES Key!");
|
||||
|
||||
int new_size = data.length + confounderSize() + checksumSize();
|
||||
byte[] new_data;
|
||||
byte pad;
|
||||
/*Data padding: using Kerberos 5 GSS-API mechanism (1.2.2.3), Jun 1996.
|
||||
*Before encryption, plain text data is padded to the next highest multiple of blocksize.
|
||||
*by appending between 1 and 8 bytes, the value of each such byte being the total number
|
||||
*of pad bytes. For example, if new_size = 10, blockSize is 8, we should pad 2 bytes,
|
||||
*and the value of each byte is 2.
|
||||
*If plaintext data is a multiple of blocksize, we pad a 8 bytes of 8.
|
||||
*/
|
||||
if (new_size % blockSize() == 0) {
|
||||
new_data = new byte[new_size + blockSize()];
|
||||
pad = (byte)8;
|
||||
}
|
||||
else {
|
||||
new_data = new byte[new_size + blockSize() - new_size % blockSize()];
|
||||
pad = (byte)(blockSize() - new_size % blockSize());
|
||||
}
|
||||
for (int i = new_size; i < new_data.length; i++) {
|
||||
new_data[i] = pad;
|
||||
}
|
||||
byte[] conf = Confounder.bytes(confounderSize());
|
||||
System.arraycopy(conf, 0, new_data, 0, confounderSize());
|
||||
System.arraycopy(data, 0, new_data, startOfData(), data.length);
|
||||
byte[] cksum = calculateChecksum(new_data, new_data.length);
|
||||
System.arraycopy(cksum, 0, new_data, startOfChecksum(),
|
||||
checksumSize());
|
||||
byte[] cipher = new byte[new_data.length];
|
||||
Des.cbc_encrypt(new_data, cipher, key, ivec, true);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts the data using DES in CBC mode.
|
||||
* @param cipher the input buffer.
|
||||
* @param key the key to decrypt the data.
|
||||
*
|
||||
* @written by Yanni Zhang, Dec 6 99.
|
||||
*/
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, int usage)
|
||||
throws KrbApErrException, KrbCryptoException{
|
||||
byte[] ivec = new byte[keySize()];
|
||||
return decrypt(cipher, key, ivec, usage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts the data using DES in CBC mode.
|
||||
* @param cipher the input buffer.
|
||||
* @param key the key to decrypt the data.
|
||||
* @param ivec initialization vector.
|
||||
*
|
||||
* @modified by Yanni Zhang, Dec 6 99.
|
||||
*/
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, byte[] ivec, int usage)
|
||||
throws KrbApErrException, KrbCryptoException {
|
||||
|
||||
/*
|
||||
* To meet export control requirements, double check that the
|
||||
* key being used is no longer than 64 bits.
|
||||
*
|
||||
* Note that from a protocol point of view, an
|
||||
* algorithm that is not DES will be rejected before this
|
||||
* point. Also, a DES key that is not 64 bits will be
|
||||
* rejected by a good JCE provider.
|
||||
*/
|
||||
if (key.length > 8)
|
||||
throw new KrbCryptoException("Invalid DES Key!");
|
||||
|
||||
byte[] data = new byte[cipher.length];
|
||||
Des.cbc_encrypt(cipher, data, key, ivec, false);
|
||||
if (!isChecksumValid(data))
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BAD_INTEGRITY);
|
||||
return data;
|
||||
}
|
||||
|
||||
private void copyChecksumField(byte[] data, byte[] cksum) {
|
||||
for (int i = 0; i < checksumSize(); i++)
|
||||
data[startOfChecksum() + i] = cksum[i];
|
||||
}
|
||||
|
||||
private byte[] checksumField(byte[] data) {
|
||||
byte[] result = new byte[checksumSize()];
|
||||
for (int i = 0; i < checksumSize(); i++)
|
||||
result[i] = data[startOfChecksum() + i];
|
||||
return result;
|
||||
}
|
||||
|
||||
private void resetChecksumField(byte[] data) {
|
||||
for (int i = startOfChecksum(); i < startOfChecksum() +
|
||||
checksumSize(); i++)
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
// Not used.
|
||||
public void setChecksum(byte[] data, int size) throws KrbCryptoException{
|
||||
resetChecksumField(data);
|
||||
byte[] cksum = calculateChecksum(data, size);
|
||||
copyChecksumField(data, cksum);
|
||||
}
|
||||
*/
|
||||
|
||||
private byte[] generateChecksum(byte[] data) throws KrbCryptoException{
|
||||
byte[] cksum1 = checksumField(data);
|
||||
resetChecksumField(data);
|
||||
byte[] cksum2 = calculateChecksum(data, data.length);
|
||||
copyChecksumField(data, cksum1);
|
||||
return cksum2;
|
||||
}
|
||||
|
||||
private 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;
|
||||
}
|
||||
|
||||
protected boolean isChecksumValid(byte[] data) throws KrbCryptoException {
|
||||
byte[] cksum1 = checksumField(data);
|
||||
byte[] cksum2 = generateChecksum(data);
|
||||
return isChecksumEqual(cksum1, cksum2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.internal.*;
|
||||
import sun.security.krb5.Checksum;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
|
||||
public final class DesCbcMd5EType extends DesCbcEType {
|
||||
|
||||
public DesCbcMd5EType() {
|
||||
}
|
||||
|
||||
public int eType() {
|
||||
return EncryptedData.ETYPE_DES_CBC_MD5;
|
||||
}
|
||||
|
||||
public int minimumPadSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public int checksumType() {
|
||||
return Checksum.CKSUMTYPE_RSA_MD5;
|
||||
}
|
||||
|
||||
public int checksumSize() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates checksum using MD5.
|
||||
* @param data the input data.
|
||||
* @param size the length of data.
|
||||
* @return the checksum.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/06/99.
|
||||
*/
|
||||
protected byte[] calculateChecksum(byte[] data, int size)
|
||||
throws KrbCryptoException {
|
||||
MessageDigest md5 = null;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (Exception e) {
|
||||
throw new KrbCryptoException("JCE provider may not be installed. " + e.getMessage());
|
||||
}
|
||||
try {
|
||||
md5.update(data);
|
||||
return(md5.digest());
|
||||
} catch (Exception e) {
|
||||
throw new KrbCryptoException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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.Confounder;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
public class DesMacCksumType extends CksumType {
|
||||
|
||||
public DesMacCksumType() {
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public int cksumType() {
|
||||
return Checksum.CKSUMTYPE_DES_MAC;
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int cksumSize() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_DES;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates keyed checksum.
|
||||
* @param data the data used to generate the checksum.
|
||||
* @param size length of the data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @return keyed checksum.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/08/99.
|
||||
*/
|
||||
public byte[] calculateChecksum(byte[] data, int size, byte[] key,
|
||||
int usage) throws KrbCryptoException {
|
||||
byte[] new_data = new byte[size + confounderSize()];
|
||||
byte[] conf = Confounder.bytes(confounderSize());
|
||||
System.arraycopy(conf, 0, new_data, 0, confounderSize());
|
||||
System.arraycopy(data, 0, new_data, confounderSize(), size);
|
||||
|
||||
//check for weak keys
|
||||
try {
|
||||
if (DESKeySpec.isWeak(key, 0)) {
|
||||
key[7] = (byte)(key[7] ^ 0xF0);
|
||||
}
|
||||
} catch (InvalidKeyException ex) {
|
||||
// swallow, since it should never happen
|
||||
}
|
||||
byte[] residue_ivec = new byte[key.length];
|
||||
byte[] residue = Des.des_cksum(residue_ivec, new_data, key);
|
||||
byte[] cksum = new byte[cksumSize()];
|
||||
System.arraycopy(conf, 0, cksum, 0, confounderSize());
|
||||
System.arraycopy(residue, 0, cksum, confounderSize(),
|
||||
cksumSize() - confounderSize());
|
||||
|
||||
byte[] new_key = new byte[keySize()];
|
||||
System.arraycopy(key, 0, new_key, 0, key.length);
|
||||
for (int i = 0; i < new_key.length; i++)
|
||||
new_key[i] = (byte)(new_key[i] ^ 0xf0);
|
||||
//check for weak keys
|
||||
try {
|
||||
if (DESKeySpec.isWeak(new_key, 0)) {
|
||||
new_key[7] = (byte)(new_key[7] ^ 0xF0);
|
||||
}
|
||||
} catch (InvalidKeyException ex) {
|
||||
// swallow, since it should never happen
|
||||
}
|
||||
byte[] ivec = new byte[new_key.length];
|
||||
|
||||
//des-cbc encrypt
|
||||
byte[] enc_cksum = new byte[cksum.length];
|
||||
Des.cbc_encrypt(cksum, enc_cksum, new_key, ivec, true);
|
||||
return enc_cksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies keyed checksum.
|
||||
* @param data the data.
|
||||
* @param size the length of data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @param checksum the checksum.
|
||||
* @return true if verification is successful.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/08/99.
|
||||
*/
|
||||
public boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
|
||||
byte[] cksum = decryptKeyedChecksum(checksum, key);
|
||||
|
||||
byte[] new_data = new byte[size + confounderSize()];
|
||||
System.arraycopy(cksum, 0, new_data, 0, confounderSize());
|
||||
System.arraycopy(data, 0, new_data, confounderSize(), size);
|
||||
|
||||
//check for weak keys
|
||||
try {
|
||||
if (DESKeySpec.isWeak(key, 0)) {
|
||||
key[7] = (byte)(key[7] ^ 0xF0);
|
||||
}
|
||||
} catch (InvalidKeyException ex) {
|
||||
// swallow, since it should never happen
|
||||
}
|
||||
byte[] ivec = new byte[key.length];
|
||||
byte[] new_cksum = Des.des_cksum(ivec, new_data, key);
|
||||
byte[] orig_cksum = new byte[cksumSize() - confounderSize()];
|
||||
System.arraycopy(cksum, confounderSize(), orig_cksum, 0,
|
||||
cksumSize() - confounderSize());
|
||||
return isChecksumEqual(orig_cksum, new_cksum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts keyed checksum.
|
||||
* @param enc_cksum the buffer for encrypted checksum.
|
||||
* @param key the key.
|
||||
* @return the checksum.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/08/99.
|
||||
*/
|
||||
private byte[] decryptKeyedChecksum(byte[] enc_cksum, byte[] key) throws KrbCryptoException {
|
||||
byte[] new_key = new byte[keySize()];
|
||||
System.arraycopy(key, 0, new_key, 0, key.length);
|
||||
for (int i = 0; i < new_key.length; i++)
|
||||
new_key[i] = (byte)(new_key[i] ^ 0xf0);
|
||||
//check for weak keys
|
||||
try {
|
||||
if (DESKeySpec.isWeak(new_key, 0)) {
|
||||
new_key[7] = (byte)(new_key[7] ^ 0xF0);
|
||||
}
|
||||
} catch (InvalidKeyException ex) {
|
||||
// swallow, since it should never happen
|
||||
}
|
||||
byte[] ivec = new byte[new_key.length];
|
||||
byte[] cksum = new byte[enc_cksum.length];
|
||||
Des.cbc_encrypt(enc_cksum, cksum, new_key, ivec, false);
|
||||
return cksum;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.*;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
public class DesMacKCksumType extends CksumType {
|
||||
|
||||
public DesMacKCksumType() {
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int cksumType() {
|
||||
return Checksum.CKSUMTYPE_DES_MAC_K;
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int cksumSize() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_DES;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates keyed checksum.
|
||||
* @param data the data used to generate the checksum.
|
||||
* @param size length of the data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @return keyed checksum.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/08/99.
|
||||
*/
|
||||
public byte[] calculateChecksum(byte[] data, int size, byte[] key,
|
||||
int usage) throws KrbCryptoException {
|
||||
//check for weak keys
|
||||
try {
|
||||
if (DESKeySpec.isWeak(key, 0)) {
|
||||
key[7] = (byte)(key[7] ^ 0xF0);
|
||||
}
|
||||
} catch (InvalidKeyException ex) {
|
||||
// swallow, since it should never happen
|
||||
}
|
||||
byte[] ivec = new byte[key.length];
|
||||
System.arraycopy(key, 0, ivec, 0, key.length);
|
||||
byte[] cksum = Des.des_cksum(ivec, data, key);
|
||||
return cksum;
|
||||
}
|
||||
|
||||
public boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
|
||||
byte[] new_cksum = calculateChecksum(data, data.length, key, usage);
|
||||
return isChecksumEqual(checksum, new_cksum);
|
||||
}
|
||||
|
||||
}
|
||||
370
jdkSrc/jdk8/sun/security/krb5/internal/crypto/EType.java
Normal file
370
jdkSrc/jdk8/sun/security/krb5/internal/crypto/EType.java
Normal file
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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.crypto;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.Config;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.EncryptionKey;
|
||||
import sun.security.krb5.KrbException;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import javax.crypto.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
//only needed if dataSize() implementation changes back to spec;
|
||||
//see dataSize() below
|
||||
|
||||
public abstract class EType {
|
||||
|
||||
private static final boolean DEBUG = Krb5.DEBUG;
|
||||
private static boolean allowWeakCrypto;
|
||||
|
||||
static {
|
||||
initStatic();
|
||||
}
|
||||
|
||||
public static void initStatic() {
|
||||
boolean allowed = false;
|
||||
try {
|
||||
Config cfg = Config.getInstance();
|
||||
allowed = cfg.getBooleanObject("libdefaults", "allow_weak_crypto")
|
||||
== Boolean.TRUE;
|
||||
} catch (Exception exc) {
|
||||
if (DEBUG) {
|
||||
System.out.println ("Exception in getting allow_weak_crypto, " +
|
||||
"using default value " +
|
||||
exc.getMessage());
|
||||
}
|
||||
}
|
||||
allowWeakCrypto = allowed;
|
||||
}
|
||||
|
||||
public static EType getInstance (int eTypeConst)
|
||||
throws KdcErrException {
|
||||
EType eType = null;
|
||||
String eTypeName = null;
|
||||
switch (eTypeConst) {
|
||||
case EncryptedData.ETYPE_NULL:
|
||||
eType = new NullEType();
|
||||
eTypeName = "sun.security.krb5.internal.crypto.NullEType";
|
||||
break;
|
||||
case EncryptedData.ETYPE_DES_CBC_CRC:
|
||||
eType = new DesCbcCrcEType();
|
||||
eTypeName = "sun.security.krb5.internal.crypto.DesCbcCrcEType";
|
||||
break;
|
||||
case EncryptedData.ETYPE_DES_CBC_MD5:
|
||||
eType = new DesCbcMd5EType();
|
||||
eTypeName = "sun.security.krb5.internal.crypto.DesCbcMd5EType";
|
||||
break;
|
||||
|
||||
case EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD:
|
||||
eType = new Des3CbcHmacSha1KdEType();
|
||||
eTypeName =
|
||||
"sun.security.krb5.internal.crypto.Des3CbcHmacSha1KdEType";
|
||||
break;
|
||||
|
||||
case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
|
||||
eType = new Aes128CtsHmacSha1EType();
|
||||
eTypeName =
|
||||
"sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType";
|
||||
break;
|
||||
|
||||
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
|
||||
eType = new Aes256CtsHmacSha1EType();
|
||||
eTypeName =
|
||||
"sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType";
|
||||
break;
|
||||
|
||||
case EncryptedData.ETYPE_ARCFOUR_HMAC:
|
||||
eType = new ArcFourHmacEType();
|
||||
eTypeName = "sun.security.krb5.internal.crypto.ArcFourHmacEType";
|
||||
break;
|
||||
|
||||
default:
|
||||
String msg = "encryption type = " + toString(eTypeConst)
|
||||
+ " (" + eTypeConst + ")";
|
||||
throw new KdcErrException(Krb5.KDC_ERR_ETYPE_NOSUPP, msg);
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> EType: " + eTypeName);
|
||||
}
|
||||
return eType;
|
||||
}
|
||||
|
||||
public abstract int eType();
|
||||
|
||||
public abstract int minimumPadSize();
|
||||
|
||||
public abstract int confounderSize();
|
||||
|
||||
public abstract int checksumType();
|
||||
|
||||
public abstract int checksumSize();
|
||||
|
||||
public abstract int blockSize();
|
||||
|
||||
public abstract int keyType();
|
||||
|
||||
public abstract int keySize();
|
||||
|
||||
public abstract byte[] encrypt(byte[] data, byte[] key, int usage)
|
||||
throws KrbCryptoException;
|
||||
|
||||
public abstract byte[] encrypt(byte[] data, byte[] key, byte[] ivec,
|
||||
int usage) throws KrbCryptoException;
|
||||
|
||||
public abstract byte[] decrypt(byte[] cipher, byte[] key, int usage)
|
||||
throws KrbApErrException, KrbCryptoException;
|
||||
|
||||
public abstract byte[] decrypt(byte[] cipher, byte[] key, byte[] ivec,
|
||||
int usage) throws KrbApErrException, KrbCryptoException;
|
||||
|
||||
public int dataSize(byte[] data)
|
||||
// throws Asn1Exception
|
||||
{
|
||||
// EncodeRef ref = new EncodeRef(data, startOfData());
|
||||
// return ref.end - startOfData();
|
||||
// should be the above according to spec, but in fact
|
||||
// implementations include the pad bytes in the data size
|
||||
return data.length - startOfData();
|
||||
}
|
||||
|
||||
public int padSize(byte[] data) {
|
||||
return data.length - confounderSize() - checksumSize() -
|
||||
dataSize(data);
|
||||
}
|
||||
|
||||
public int startOfChecksum() {
|
||||
return confounderSize();
|
||||
}
|
||||
|
||||
public int startOfData() {
|
||||
return confounderSize() + checksumSize();
|
||||
}
|
||||
|
||||
public int startOfPad(byte[] data) {
|
||||
return confounderSize() + checksumSize() + dataSize(data);
|
||||
}
|
||||
|
||||
public byte[] decryptedData(byte[] data) {
|
||||
int tempSize = dataSize(data);
|
||||
byte[] result = new byte[tempSize];
|
||||
System.arraycopy(data, startOfData(), result, 0, tempSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Note: the first 2 entries of BUILTIN_ETYPES and BUILTIN_ETYPES_NOAES256
|
||||
// should be kept DES-related. They will be removed when allow_weak_crypto
|
||||
// is set to false.
|
||||
|
||||
private static final int[] BUILTIN_ETYPES = new int[] {
|
||||
EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96,
|
||||
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96,
|
||||
EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD,
|
||||
EncryptedData.ETYPE_ARCFOUR_HMAC,
|
||||
EncryptedData.ETYPE_DES_CBC_CRC,
|
||||
EncryptedData.ETYPE_DES_CBC_MD5,
|
||||
};
|
||||
|
||||
private static final int[] BUILTIN_ETYPES_NOAES256 = new int[] {
|
||||
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96,
|
||||
EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD,
|
||||
EncryptedData.ETYPE_ARCFOUR_HMAC,
|
||||
EncryptedData.ETYPE_DES_CBC_CRC,
|
||||
EncryptedData.ETYPE_DES_CBC_MD5,
|
||||
};
|
||||
|
||||
|
||||
// used in Config
|
||||
public static int[] getBuiltInDefaults() {
|
||||
int allowed = 0;
|
||||
try {
|
||||
allowed = Cipher.getMaxAllowedKeyLength("AES");
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
}
|
||||
int[] result;
|
||||
if (allowed < 256) {
|
||||
result = BUILTIN_ETYPES_NOAES256;
|
||||
} else {
|
||||
result = BUILTIN_ETYPES;
|
||||
}
|
||||
if (!allowWeakCrypto) {
|
||||
// The last 4 etypes are now weak ones
|
||||
return Arrays.copyOfRange(result, 0, result.length - 4);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default etypes from the configuration file, or
|
||||
* if that's not available, return the built-in list of default etypes.
|
||||
* This result is always non-empty. If no etypes are found,
|
||||
* an exception is thrown.
|
||||
*/
|
||||
public static int[] getDefaults(String configName)
|
||||
throws KrbException {
|
||||
Config config = null;
|
||||
try {
|
||||
config = Config.getInstance();
|
||||
} catch (KrbException exc) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Exception while getting " +
|
||||
configName + exc.getMessage());
|
||||
System.out.println("Using default builtin etypes");
|
||||
}
|
||||
return getBuiltInDefaults();
|
||||
}
|
||||
return config.defaultEtype(configName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the default etypes from the configuration file for
|
||||
* those etypes for which there are corresponding keys.
|
||||
* Used in scenario we have some keys from a keytab with etypes
|
||||
* different from those named in configName. Then, in order
|
||||
* to decrypt an AS-REP, we should only ask for etypes for which
|
||||
* we have keys.
|
||||
*/
|
||||
public static int[] getDefaults(String configName, EncryptionKey[] keys)
|
||||
throws KrbException {
|
||||
int[] answer = getDefaults(configName);
|
||||
|
||||
List<Integer> list = new ArrayList<>(answer.length);
|
||||
for (int i = 0; i < answer.length; i++) {
|
||||
if (EncryptionKey.findKey(answer[i], keys) != null) {
|
||||
list.add(answer[i]);
|
||||
}
|
||||
}
|
||||
int len = list.size();
|
||||
if (len <= 0) {
|
||||
StringBuffer keystr = new StringBuffer();
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
keystr.append(toString(keys[i].getEType()));
|
||||
keystr.append(" ");
|
||||
}
|
||||
throw new KrbException(
|
||||
"Do not have keys of types listed in " + configName +
|
||||
" available; only have keys of following type: " +
|
||||
keystr.toString());
|
||||
} else {
|
||||
answer = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
answer[i] = list.get(i);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSupported(int eTypeConst, int[] config) {
|
||||
for (int i = 0; i < config.length; i++) {
|
||||
if (eTypeConst == config[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isSupported(int eTypeConst) {
|
||||
int[] enabledETypes = getBuiltInDefaults();
|
||||
return isSupported(eTypeConst, enabledETypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc4120#section-3.1.3:
|
||||
*
|
||||
* A "newer" enctype is any enctype first officially
|
||||
* specified concurrently with or subsequent to the issue of this RFC.
|
||||
* The enctypes DES, 3DES, or RC4 and any defined in [RFC1510] are not
|
||||
* "newer" enctypes.
|
||||
*
|
||||
* @param eTypeConst the encryption type
|
||||
* @return true if "newer"
|
||||
*/
|
||||
public static boolean isNewer(int eTypeConst) {
|
||||
return eTypeConst != EncryptedData.ETYPE_DES_CBC_CRC &&
|
||||
eTypeConst != EncryptedData.ETYPE_DES_CBC_MD4 &&
|
||||
eTypeConst != EncryptedData.ETYPE_DES_CBC_MD5 &&
|
||||
eTypeConst != EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD &&
|
||||
eTypeConst != EncryptedData.ETYPE_ARCFOUR_HMAC &&
|
||||
eTypeConst != EncryptedData.ETYPE_ARCFOUR_HMAC_EXP;
|
||||
}
|
||||
|
||||
public static String toString(int type) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
return "NULL";
|
||||
case 1:
|
||||
return "DES CBC mode with CRC-32";
|
||||
case 2:
|
||||
return "DES CBC mode with MD4";
|
||||
case 3:
|
||||
return "DES CBC mode with MD5";
|
||||
case 4:
|
||||
return "reserved";
|
||||
case 5:
|
||||
return "DES3 CBC mode with MD5";
|
||||
case 6:
|
||||
return "reserved";
|
||||
case 7:
|
||||
return "DES3 CBC mode with SHA1";
|
||||
case 9:
|
||||
return "DSA with SHA1- Cms0ID";
|
||||
case 10:
|
||||
return "MD5 with RSA encryption - Cms0ID";
|
||||
case 11:
|
||||
return "SHA1 with RSA encryption - Cms0ID";
|
||||
case 12:
|
||||
return "RC2 CBC mode with Env0ID";
|
||||
case 13:
|
||||
return "RSA encryption with Env0ID";
|
||||
case 14:
|
||||
return "RSAES-0AEP-ENV-0ID";
|
||||
case 15:
|
||||
return "DES-EDE3-CBC-ENV-0ID";
|
||||
case 16:
|
||||
return "DES3 CBC mode with SHA1-KD";
|
||||
case 17:
|
||||
return "AES128 CTS mode with HMAC SHA1-96";
|
||||
case 18:
|
||||
return "AES256 CTS mode with HMAC SHA1-96";
|
||||
case 23:
|
||||
return "RC4 with HMAC";
|
||||
case 24:
|
||||
return "RC4 with HMAC EXP";
|
||||
|
||||
}
|
||||
return "Unknown (" + type + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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.crypto;
|
||||
|
||||
import sun.security.krb5.Checksum;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* This class encapsulates the checksum type for HMAC RC4
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class HmacMd5ArcFourCksumType extends CksumType {
|
||||
|
||||
public HmacMd5ArcFourCksumType() {
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public int cksumType() {
|
||||
return Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR;
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int cksumSize() {
|
||||
return 16; // bytes
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_ARCFOUR_HMAC;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 16; // bytes
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates keyed checksum.
|
||||
* @param data the data used to generate the checksum.
|
||||
* @param size length of the data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @return keyed checksum.
|
||||
*/
|
||||
public byte[] calculateChecksum(byte[] data, int size, byte[] key,
|
||||
int usage) throws KrbCryptoException {
|
||||
|
||||
try {
|
||||
return ArcFourHmac.calculateChecksum(key, usage, data, 0, size);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies keyed checksum.
|
||||
* @param data the data.
|
||||
* @param size the length of data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @param checksum the checksum.
|
||||
* @return true if verification is successful.
|
||||
*/
|
||||
public boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
|
||||
|
||||
try {
|
||||
byte[] newCksum = ArcFourHmac.calculateChecksum(key, usage,
|
||||
data, 0, size);
|
||||
|
||||
return isChecksumEqual(checksum, newCksum);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.crypto;
|
||||
|
||||
import sun.security.krb5.Checksum;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/*
|
||||
* This class encapsulates the checksum type for AES128
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class HmacSha1Aes128CksumType extends CksumType {
|
||||
|
||||
public HmacSha1Aes128CksumType() {
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
public int cksumType() {
|
||||
return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128;
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int cksumSize() {
|
||||
return 12; // bytes
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_AES;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 16; // bytes
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates keyed checksum.
|
||||
* @param data the data used to generate the checksum.
|
||||
* @param size length of the data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @return keyed checksum.
|
||||
*/
|
||||
public byte[] calculateChecksum(byte[] data, int size, byte[] key,
|
||||
int usage) throws KrbCryptoException {
|
||||
|
||||
try {
|
||||
return Aes128.calculateChecksum(key, usage, data, 0, size);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies keyed checksum.
|
||||
* @param data the data.
|
||||
* @param size the length of data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @param checksum the checksum.
|
||||
* @return true if verification is successful.
|
||||
*/
|
||||
public boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
|
||||
|
||||
try {
|
||||
byte[] newCksum = Aes128.calculateChecksum(key, usage,
|
||||
data, 0, size);
|
||||
return isChecksumEqual(checksum, newCksum);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.crypto;
|
||||
|
||||
import sun.security.krb5.Checksum;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/*
|
||||
* This class encapsulates the checksum type for AES256
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class HmacSha1Aes256CksumType extends CksumType {
|
||||
|
||||
public HmacSha1Aes256CksumType() {
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
public int cksumType() {
|
||||
return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256;
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int cksumSize() {
|
||||
return 12; // bytes
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_AES;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 32; // bytes
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates keyed checksum.
|
||||
* @param data the data used to generate the checksum.
|
||||
* @param size length of the data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @return keyed checksum.
|
||||
*/
|
||||
public byte[] calculateChecksum(byte[] data, int size, byte[] key,
|
||||
int usage) throws KrbCryptoException {
|
||||
|
||||
try {
|
||||
return Aes256.calculateChecksum(key, usage, data, 0, size);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies keyed checksum.
|
||||
* @param data the data.
|
||||
* @param size the length of data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @param checksum the checksum.
|
||||
* @return true if verification is successful.
|
||||
*/
|
||||
public boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
|
||||
|
||||
try {
|
||||
byte[] newCksum = Aes256.calculateChecksum(key, usage, data,
|
||||
0, size);
|
||||
return isChecksumEqual(checksum, newCksum);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.crypto;
|
||||
|
||||
import sun.security.krb5.Checksum;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
public class HmacSha1Des3KdCksumType extends CksumType {
|
||||
|
||||
public HmacSha1Des3KdCksumType() {
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public int cksumType() {
|
||||
return Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD;
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int cksumSize() {
|
||||
return 20; // bytes
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_DES3;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 24; // bytes
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates keyed checksum.
|
||||
* @param data the data used to generate the checksum.
|
||||
* @param size length of the data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @return keyed checksum.
|
||||
*/
|
||||
public byte[] calculateChecksum(byte[] data, int size, byte[] key,
|
||||
int usage) throws KrbCryptoException {
|
||||
|
||||
try {
|
||||
return Des3.calculateChecksum(key, usage, data, 0, size);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies keyed checksum.
|
||||
* @param data the data.
|
||||
* @param size the length of data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @param checksum the checksum.
|
||||
* @return true if verification is successful.
|
||||
*/
|
||||
public boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
|
||||
|
||||
try {
|
||||
byte[] newCksum = Des3.calculateChecksum(key, usage,
|
||||
data, 0, size);
|
||||
|
||||
return isChecksumEqual(checksum, newCksum);
|
||||
} catch (GeneralSecurityException e) {
|
||||
KrbCryptoException ke = new KrbCryptoException(e.getMessage());
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
}
|
||||
}
|
||||
64
jdkSrc/jdk8/sun/security/krb5/internal/crypto/KeyUsage.java
Normal file
64
jdkSrc/jdk8/sun/security/krb5/internal/crypto/KeyUsage.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.crypto;
|
||||
|
||||
/**
|
||||
* Key usages used for key derivation in Kerberos.
|
||||
*/
|
||||
public class KeyUsage {
|
||||
|
||||
private KeyUsage() {
|
||||
}
|
||||
|
||||
public static final int KU_UNKNOWN = 0; // Cannot be 0
|
||||
|
||||
// Defined in draft-yu-krb-wg-kerberos-extensions-00.txt, Appendix A
|
||||
public static final int KU_PA_ENC_TS = 1; // KrbAsReq
|
||||
public static final int KU_TICKET = 2; // KrbApReq (ticket)
|
||||
public static final int KU_ENC_AS_REP_PART = 3; // KrbAsRep
|
||||
public static final int KU_TGS_REQ_AUTH_DATA_SESSKEY= 4; // KrbTgsReq
|
||||
public static final int KU_TGS_REQ_AUTH_DATA_SUBKEY = 5; // KrbTgsReq
|
||||
public static final int KU_PA_TGS_REQ_CKSUM = 6; // KrbTgsReq
|
||||
public static final int KU_PA_TGS_REQ_AUTHENTICATOR = 7; // KrbApReq
|
||||
public static final int KU_ENC_TGS_REP_PART_SESSKEY = 8; // KrbTgsRep
|
||||
public static final int KU_ENC_TGS_REP_PART_SUBKEY = 9; // KrbTgsRep
|
||||
public static final int KU_AUTHENTICATOR_CKSUM = 10;
|
||||
public static final int KU_AP_REQ_AUTHENTICATOR = 11; // KrbApReq
|
||||
public static final int KU_ENC_AP_REP_PART = 12; // KrbApRep
|
||||
public static final int KU_ENC_KRB_PRIV_PART = 13; // KrbPriv
|
||||
public static final int KU_ENC_KRB_CRED_PART = 14; // KrbCred
|
||||
public static final int KU_KRB_SAFE_CKSUM = 15; // KrbSafe
|
||||
public static final int KU_PA_FOR_USER_ENC_CKSUM = 17; // S4U2user
|
||||
public static final int KU_AD_KDC_ISSUED_CKSUM = 19;
|
||||
public static final int KU_AS_REQ = 56;
|
||||
|
||||
public static final boolean isValid(int usage) {
|
||||
return usage >= 0;
|
||||
}
|
||||
}
|
||||
40
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Nonce.java
Normal file
40
jdkSrc/jdk8/sun/security/krb5/internal/crypto/Nonce.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.crypto;
|
||||
|
||||
public class Nonce {
|
||||
|
||||
public static synchronized int value() {
|
||||
return sun.security.krb5.Confounder.intValue() & 0x7fffffff;
|
||||
}
|
||||
|
||||
}
|
||||
94
jdkSrc/jdk8/sun/security/krb5/internal/crypto/NullEType.java
Normal file
94
jdkSrc/jdk8/sun/security/krb5/internal/crypto/NullEType.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.EncryptedData;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
public class NullEType extends EType {
|
||||
|
||||
public NullEType() {
|
||||
}
|
||||
|
||||
public int eType() {
|
||||
return EncryptedData.ETYPE_NULL;
|
||||
}
|
||||
|
||||
public int minimumPadSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int checksumType() {
|
||||
return Checksum.CKSUMTYPE_NULL;
|
||||
}
|
||||
|
||||
public int checksumSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int blockSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_NULL;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte[] data, byte[] key, int usage) {
|
||||
byte[] cipher = new byte[data.length];
|
||||
System.arraycopy(data, 0, cipher, 0, data.length);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte[] data, byte[] key, byte[] ivec, int usage) {
|
||||
byte[] cipher = new byte[data.length];
|
||||
System.arraycopy(data, 0, cipher, 0, data.length);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, int usage)
|
||||
throws KrbApErrException {
|
||||
return cipher.clone();
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte[] cipher, byte[] key, byte[] ivec, int usage)
|
||||
throws KrbApErrException {
|
||||
return cipher.clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.*;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public final class RsaMd5CksumType extends CksumType {
|
||||
|
||||
public RsaMd5CksumType() {
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int cksumType() {
|
||||
return Checksum.CKSUMTYPE_RSA_MD5;
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int cksumSize() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_NULL;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates checksum using MD5.
|
||||
* @param data the data used to generate the checksum.
|
||||
* @param size length of the data.
|
||||
* @return the checksum.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/08/99.
|
||||
*/
|
||||
|
||||
public byte[] calculateChecksum(byte[] data, int size,
|
||||
byte[] key, int usage) throws KrbCryptoException{
|
||||
MessageDigest md5;
|
||||
byte[] result = null;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (Exception e) {
|
||||
throw new KrbCryptoException("JCE provider may not be installed. " + e.getMessage());
|
||||
}
|
||||
try {
|
||||
md5.update(data);
|
||||
result = md5.digest();
|
||||
} catch (Exception e) {
|
||||
throw new KrbCryptoException(e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage)
|
||||
throws KrbCryptoException {
|
||||
try {
|
||||
byte[] calculated = MessageDigest.getInstance("MD5").digest(data);
|
||||
return CksumType.isChecksumEqual(calculated, checksum);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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.Confounder;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.internal.*;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
public final class RsaMd5DesCksumType extends CksumType {
|
||||
|
||||
public RsaMd5DesCksumType() {
|
||||
}
|
||||
|
||||
public int confounderSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public int cksumType() {
|
||||
return Checksum.CKSUMTYPE_RSA_MD5_DES;
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int cksumSize() {
|
||||
return 24;
|
||||
}
|
||||
|
||||
public int keyType() {
|
||||
return Krb5.KEYTYPE_DES;
|
||||
}
|
||||
|
||||
public int keySize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates keyed checksum.
|
||||
* @param data the data used to generate the checksum.
|
||||
* @param size length of the data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @return keyed checksum.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/08/99.
|
||||
*/
|
||||
public byte[] calculateChecksum(byte[] data, int size, byte[] key,
|
||||
int usage) throws KrbCryptoException {
|
||||
//prepend confounder
|
||||
byte[] new_data = new byte[size + confounderSize()];
|
||||
byte[] conf = Confounder.bytes(confounderSize());
|
||||
System.arraycopy(conf, 0, new_data, 0, confounderSize());
|
||||
System.arraycopy(data, 0, new_data, confounderSize(), size);
|
||||
|
||||
//calculate md5 cksum
|
||||
byte[] mdc_cksum = calculateRawChecksum(new_data, new_data.length);
|
||||
byte[] cksum = new byte[cksumSize()];
|
||||
System.arraycopy(conf, 0, cksum, 0, confounderSize());
|
||||
System.arraycopy(mdc_cksum, 0, cksum, confounderSize(),
|
||||
cksumSize() - confounderSize());
|
||||
|
||||
//compute modified key
|
||||
byte[] new_key = new byte[keySize()];
|
||||
System.arraycopy(key, 0, new_key, 0, key.length);
|
||||
for (int i = 0; i < new_key.length; i++)
|
||||
new_key[i] = (byte)(new_key[i] ^ 0xf0);
|
||||
//check for weak keys
|
||||
try {
|
||||
if (DESKeySpec.isWeak(new_key, 0)) {
|
||||
new_key[7] = (byte)(new_key[7] ^ 0xF0);
|
||||
}
|
||||
} catch (InvalidKeyException ex) {
|
||||
// swallow, since it should never happen
|
||||
}
|
||||
byte[] ivec = new byte[new_key.length];
|
||||
|
||||
//des-cbc encrypt
|
||||
byte[] enc_cksum = new byte[cksum.length];
|
||||
Des.cbc_encrypt(cksum, enc_cksum, new_key, ivec, true);
|
||||
return enc_cksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies keyed checksum.
|
||||
* @param data the data.
|
||||
* @param size the length of data.
|
||||
* @param key the key used to encrypt the checksum.
|
||||
* @param checksum the checksum.
|
||||
* @return true if verification is successful.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/08/99.
|
||||
*/
|
||||
public boolean verifyChecksum(byte[] data, int size,
|
||||
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
|
||||
//decrypt checksum
|
||||
byte[] cksum = decryptKeyedChecksum(checksum, key);
|
||||
|
||||
//prepend confounder
|
||||
byte[] new_data = new byte[size + confounderSize()];
|
||||
System.arraycopy(cksum, 0, new_data, 0, confounderSize());
|
||||
System.arraycopy(data, 0, new_data, confounderSize(), size);
|
||||
|
||||
byte[] new_cksum = calculateRawChecksum(new_data, new_data.length);
|
||||
//extract original cksum value
|
||||
byte[] orig_cksum = new byte[cksumSize() - confounderSize()];
|
||||
System.arraycopy(cksum, confounderSize(), orig_cksum, 0,
|
||||
cksumSize() - confounderSize());
|
||||
|
||||
return isChecksumEqual(orig_cksum, new_cksum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts keyed checksum.
|
||||
* @param enc_cksum the buffer for encrypted checksum.
|
||||
* @param key the key.
|
||||
* @return the checksum.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/08/99.
|
||||
*/
|
||||
private byte[] decryptKeyedChecksum(byte[] enc_cksum, byte[] key) throws KrbCryptoException {
|
||||
//compute modified key
|
||||
byte[] new_key = new byte[keySize()];
|
||||
System.arraycopy(key, 0, new_key, 0, key.length);
|
||||
for (int i = 0; i < new_key.length; i++)
|
||||
new_key[i] = (byte)(new_key[i] ^ 0xf0);
|
||||
//check for weak keys
|
||||
try {
|
||||
if (DESKeySpec.isWeak(new_key, 0)) {
|
||||
new_key[7] = (byte)(new_key[7] ^ 0xF0);
|
||||
}
|
||||
} catch (InvalidKeyException ex) {
|
||||
// swallow, since it should never happen
|
||||
}
|
||||
byte[] ivec = new byte[new_key.length];
|
||||
|
||||
byte[] cksum = new byte[enc_cksum.length];
|
||||
Des.cbc_encrypt(enc_cksum, cksum, new_key, ivec, false);
|
||||
return cksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates checksum using MD5.
|
||||
* @param data the data used to generate the checksum.
|
||||
* @param size length of the data.
|
||||
* @return the checksum.
|
||||
*
|
||||
* @modified by Yanni Zhang, 12/08/99.
|
||||
*/
|
||||
private byte[] calculateRawChecksum(byte[] data, int size) throws KrbCryptoException{
|
||||
MessageDigest md5;
|
||||
byte[] result = null;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (Exception e) {
|
||||
throw new KrbCryptoException("JCE provider may not be installed. " + e.getMessage());
|
||||
}
|
||||
try {
|
||||
md5.update(data);
|
||||
result = md5.digest();
|
||||
} catch (Exception e) {
|
||||
throw new KrbCryptoException(e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
278
jdkSrc/jdk8/sun/security/krb5/internal/crypto/crc32.java
Normal file
278
jdkSrc/jdk8/sun/security/krb5/internal/crypto/crc32.java
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// crc32.java
|
||||
|
||||
package sun.security.krb5.internal.crypto;
|
||||
|
||||
import java.security.MessageDigestSpi;
|
||||
import java.security.DigestException;
|
||||
|
||||
public final class crc32 extends MessageDigestSpi implements Cloneable {
|
||||
private static final int CRC32_LENGTH = 4; //32-bit
|
||||
private int seed;
|
||||
private static boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;
|
||||
// buffer;
|
||||
// private int bufferIndex, bufferLeft;
|
||||
|
||||
public crc32() {
|
||||
init();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
try {
|
||||
crc32 crc = (crc32)super.clone();
|
||||
crc.init();
|
||||
return crc;
|
||||
}
|
||||
catch (CloneNotSupportedException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the digest length in bytes
|
||||
*/
|
||||
protected int engineGetDigestLength() {
|
||||
return (CRC32_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
protected byte[] engineDigest() {
|
||||
byte[] result = new byte[CRC32_LENGTH];
|
||||
result = int2quad(seed);
|
||||
//processBuffer(buffer, 0, bufferIndex, result, 0);
|
||||
init();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
protected int engineDigest(byte[] buf, int offset, int len) throws DigestException {
|
||||
byte[] result = new byte[CRC32_LENGTH];
|
||||
result = int2quad(seed);
|
||||
if (len < CRC32_LENGTH) {
|
||||
throw new DigestException("partial digests not returned");
|
||||
}
|
||||
if (buf.length - offset < CRC32_LENGTH) {
|
||||
throw new DigestException("insufficient space in the output " +
|
||||
"buffer to store the digest");
|
||||
}
|
||||
System.arraycopy(result, 0, buf, offset, CRC32_LENGTH);
|
||||
//processBuffer(buffer, 0, bufferIndex, result, 0);
|
||||
/*if (len < CRC32_LENGTH) {
|
||||
throw new DigestException("partial digests not returned");
|
||||
}
|
||||
if (buf.length - offset < CRC32_LENGTH) {
|
||||
throw new DigestException("insufficient space in the output " +
|
||||
"buffer to store the digest");
|
||||
}
|
||||
System.arraycopy(result, 0, buf, offset, CRC32_LENGTH); */
|
||||
init();
|
||||
return CRC32_LENGTH;
|
||||
}
|
||||
/**
|
||||
* Update adds the passed byte to the digested data.
|
||||
*/
|
||||
protected synchronized void engineUpdate(byte b) {
|
||||
byte[] input = new byte[1];
|
||||
input[0] = b;
|
||||
//engineUpdate(input, 0, 1);
|
||||
engineUpdate(input, seed, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update adds the selected part of an array of bytes to the digest.
|
||||
* This version is more efficient than the byte-at-a-time version;
|
||||
* it avoids data copies and reduces per-byte call overhead.
|
||||
*/
|
||||
protected synchronized void engineUpdate(byte input[], int offset,
|
||||
int len) {
|
||||
processData(input, offset, len);
|
||||
}
|
||||
private static int[] crc32Table = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
protected void engineReset() {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the CRC32 information
|
||||
*/
|
||||
public void init() {
|
||||
seed = 0;
|
||||
}
|
||||
|
||||
private void processData(byte[] data, int off, int len) {
|
||||
int result = seed;
|
||||
for (int i = 0; i < len; i++)
|
||||
result = (result >>> 8) ^ crc32Table[(result ^ data[i]) & 0xff];
|
||||
seed = result;
|
||||
}
|
||||
|
||||
public static int int2crc32(int b) {
|
||||
int crc = b;
|
||||
|
||||
for (int i = 8; i > 0; i--) {
|
||||
if ((crc & 1) != 0)
|
||||
crc = (crc >>> 1) ^ 0xedb88320;
|
||||
else
|
||||
crc = crc >>> 1;
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
public static void printcrc32Table() {
|
||||
String temp;
|
||||
String zerofill = "00000000";
|
||||
|
||||
System.out.print("\tpublic static int[] crc32Table = {");
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if ((i % 4) == 0)
|
||||
System.out.print("\n\t\t");
|
||||
temp = Integer.toHexString(int2crc32(i));
|
||||
System.out.print("0x" +
|
||||
zerofill.substring(temp.length()) + temp);
|
||||
if (i != 255)
|
||||
System.out.print(", ");
|
||||
}
|
||||
System.out.println("\n\t};");
|
||||
}
|
||||
|
||||
public static int byte2crc32sum(int seed, byte[] data, int size) {
|
||||
int crc = seed;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
crc = (crc >>> 8) ^ crc32Table[(crc ^ data[i]) & 0xff];
|
||||
return crc;
|
||||
}
|
||||
|
||||
public static int byte2crc32sum(int seed, byte[] data) {
|
||||
return byte2crc32sum(seed, data, data.length);
|
||||
}
|
||||
|
||||
//sum from zero, i.e., no pre- or post-conditioning
|
||||
public static int byte2crc32sum(byte[] data) {
|
||||
return byte2crc32sum(0, data);
|
||||
}
|
||||
|
||||
//CCITT ITU-T 3309 CRC-32 w/ standard pre- and post-conditioning
|
||||
public static int byte2crc32(byte[] data) {
|
||||
return ~byte2crc32sum(0xffffffff, data);
|
||||
}
|
||||
|
||||
public static byte[] byte2crc32sum_bytes(byte[] data) {
|
||||
int temp = byte2crc32sum(data);
|
||||
return int2quad(temp);
|
||||
}
|
||||
|
||||
public static byte[] byte2crc32sum_bytes(byte[] data, int size) {
|
||||
int temp = byte2crc32sum(0, data, size);
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>crc32: " + Integer.toHexString(temp));
|
||||
System.out.println(">>>crc32: " + Integer.toBinaryString(temp));
|
||||
}
|
||||
return int2quad(temp);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,501 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2008, 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.dk;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.crypto.spec.DESedeKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.GeneralSecurityException;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.Confounder;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class provides the implementation of AES Encryption for Kerberos
|
||||
* as defined RFC 3962.
|
||||
* http://www.ietf.org/rfc/rfc3962.txt
|
||||
*
|
||||
* Algorithm profile described in [KCRYPTO]:
|
||||
* +--------------------------------------------------------------------+
|
||||
* | protocol key format 128- or 256-bit string |
|
||||
* | |
|
||||
* | string-to-key function PBKDF2+DK with variable |
|
||||
* | iteration count (see |
|
||||
* | above) |
|
||||
* | |
|
||||
* | default string-to-key parameters 00 00 10 00 |
|
||||
* | |
|
||||
* | key-generation seed length key size |
|
||||
* | |
|
||||
* | random-to-key function identity function |
|
||||
* | |
|
||||
* | hash function, H SHA-1 |
|
||||
* | |
|
||||
* | HMAC output size, h 12 octets (96 bits) |
|
||||
* | |
|
||||
* | message block size, m 1 octet |
|
||||
* | |
|
||||
* | encryption/decryption functions, AES in CBC-CTS mode |
|
||||
* | E and D (cipher block size 16 |
|
||||
* | octets), with next to |
|
||||
* | last block as CBC-style |
|
||||
* | ivec |
|
||||
* +--------------------------------------------------------------------+
|
||||
*
|
||||
* Supports AES128 and AES256
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class AesDkCrypto extends DkCrypto {
|
||||
|
||||
private static final boolean debug = false;
|
||||
|
||||
private static final int BLOCK_SIZE = 16;
|
||||
private static final int DEFAULT_ITERATION_COUNT = 4096;
|
||||
private static final byte[] ZERO_IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
private static final int hashSize = 96/8;
|
||||
private final int keyLength;
|
||||
|
||||
public AesDkCrypto(int length) {
|
||||
keyLength = length;
|
||||
}
|
||||
|
||||
protected int getKeySeedLength() {
|
||||
return keyLength; // bits; AES key material
|
||||
}
|
||||
|
||||
public byte[] stringToKey(char[] password, String salt, byte[] s2kparams)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
byte[] saltUtf8 = null;
|
||||
try {
|
||||
saltUtf8 = salt.getBytes("UTF-8");
|
||||
return stringToKey(password, saltUtf8, s2kparams);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
} finally {
|
||||
if (saltUtf8 != null) {
|
||||
Arrays.fill(saltUtf8, (byte)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] stringToKey(char[] secret, byte[] salt, byte[] params)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
int iter_count = DEFAULT_ITERATION_COUNT;
|
||||
if (params != null) {
|
||||
if (params.length != 4) {
|
||||
throw new RuntimeException("Invalid parameter to stringToKey");
|
||||
}
|
||||
iter_count = readBigEndian(params, 0, 4);
|
||||
}
|
||||
|
||||
byte[] tmpKey = randomToKey(PBKDF2(secret, salt, iter_count,
|
||||
getKeySeedLength()));
|
||||
byte[] result = dk(tmpKey, KERBEROS_CONSTANT);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected byte[] randomToKey(byte[] in) {
|
||||
// simple identity operation
|
||||
return in;
|
||||
}
|
||||
|
||||
protected Cipher getCipher(byte[] key, byte[] ivec, int mode)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
// IV
|
||||
if (ivec == null) {
|
||||
ivec = ZERO_IV;
|
||||
}
|
||||
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
IvParameterSpec encIv = new IvParameterSpec(ivec, 0, ivec.length);
|
||||
cipher.init(mode, secretKey, encIv);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
// get an instance of the AES Cipher in CTS mode
|
||||
public int getChecksumLength() {
|
||||
return hashSize; // bytes
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the truncated HMAC
|
||||
*/
|
||||
protected byte[] getHmac(byte[] key, byte[] msg)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
SecretKey keyKi = new SecretKeySpec(key, "HMAC");
|
||||
Mac m = Mac.getInstance("HmacSHA1");
|
||||
m.init(keyKi);
|
||||
|
||||
// generate hash
|
||||
byte[] hash = m.doFinal(msg);
|
||||
|
||||
// truncate hash
|
||||
byte[] output = new byte[hashSize];
|
||||
System.arraycopy(hash, 0, output, 0, hashSize);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the checksum
|
||||
*/
|
||||
public byte[] calculateChecksum(byte[] baseKey, int usage, byte[] input,
|
||||
int start, int len) throws GeneralSecurityException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
|
||||
// Derive keys
|
||||
byte[] constant = new byte[5];
|
||||
constant[0] = (byte) ((usage>>24)&0xff);
|
||||
constant[1] = (byte) ((usage>>16)&0xff);
|
||||
constant[2] = (byte) ((usage>>8)&0xff);
|
||||
constant[3] = (byte) (usage&0xff);
|
||||
|
||||
constant[4] = (byte) 0x99;
|
||||
|
||||
byte[] Kc = dk(baseKey, constant); // Checksum key
|
||||
if (debug) {
|
||||
System.err.println("usage: " + usage);
|
||||
traceOutput("input", input, start, Math.min(len, 32));
|
||||
traceOutput("constant", constant, 0, constant.length);
|
||||
traceOutput("baseKey", baseKey, 0, baseKey.length);
|
||||
traceOutput("Kc", Kc, 0, Kc.length);
|
||||
}
|
||||
|
||||
try {
|
||||
// Generate checksum
|
||||
// H1 = HMAC(Kc, input)
|
||||
byte[] hmac = getHmac(Kc, input);
|
||||
if (debug) {
|
||||
traceOutput("hmac", hmac, 0, hmac.length);
|
||||
}
|
||||
if (hmac.length == getChecksumLength()) {
|
||||
return hmac;
|
||||
} else if (hmac.length > getChecksumLength()) {
|
||||
byte[] buf = new byte[getChecksumLength()];
|
||||
System.arraycopy(hmac, 0, buf, 0, buf.length);
|
||||
return buf;
|
||||
} else {
|
||||
throw new GeneralSecurityException("checksum size too short: " +
|
||||
hmac.length + "; expecting : " + getChecksumLength());
|
||||
}
|
||||
} finally {
|
||||
Arrays.fill(Kc, 0, Kc.length, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs encryption using derived key; adds confounder.
|
||||
*/
|
||||
public byte[] encrypt(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] new_ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
byte[] output = encryptCTS(baseKey, usage, ivec, new_ivec, plaintext,
|
||||
start, len, true);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs encryption using derived key; does not add confounder.
|
||||
*/
|
||||
public byte[] encryptRaw(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
byte[] output = encryptCTS(baseKey, usage, ivec, null, plaintext,
|
||||
start, len, false);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param baseKey key from which keys are to be derived using usage
|
||||
* @param ciphertext E(Ke, conf | plaintext | padding, ivec) | H1[1..h]
|
||||
*/
|
||||
public byte[] decrypt(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len) throws GeneralSecurityException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
byte[] output = decryptCTS(baseKey, usage, ivec, ciphertext,
|
||||
start, len, true);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts data using specified key and initial vector.
|
||||
* @param baseKey encryption key to use
|
||||
* @param ciphertext encrypted data to be decrypted
|
||||
* @param usage ignored
|
||||
*/
|
||||
public byte[] decryptRaw(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
byte[] output = decryptCTS(baseKey, usage, ivec, ciphertext,
|
||||
start, len, false);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt AES in CBC-CTS mode using derived keys.
|
||||
*/
|
||||
private byte[] encryptCTS(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] new_ivec, byte[] plaintext, int start, int len,
|
||||
boolean confounder_exists)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
|
||||
byte[] Ke = null;
|
||||
byte[] Ki = null;
|
||||
|
||||
if (debug) {
|
||||
System.err.println("usage: " + usage);
|
||||
if (ivec != null) {
|
||||
traceOutput("old_state.ivec", ivec, 0, ivec.length);
|
||||
}
|
||||
traceOutput("plaintext", plaintext, start, Math.min(len, 32));
|
||||
traceOutput("baseKey", baseKey, 0, baseKey.length);
|
||||
}
|
||||
|
||||
try {
|
||||
// derive Encryption key
|
||||
byte[] constant = new byte[5];
|
||||
constant[0] = (byte) ((usage>>24)&0xff);
|
||||
constant[1] = (byte) ((usage>>16)&0xff);
|
||||
constant[2] = (byte) ((usage>>8)&0xff);
|
||||
constant[3] = (byte) (usage&0xff);
|
||||
constant[4] = (byte) 0xaa;
|
||||
Ke = dk(baseKey, constant); // Encryption key
|
||||
|
||||
byte[] toBeEncrypted = null;
|
||||
if (confounder_exists) {
|
||||
byte[] confounder = Confounder.bytes(BLOCK_SIZE);
|
||||
toBeEncrypted = new byte[confounder.length + len];
|
||||
System.arraycopy(confounder, 0, toBeEncrypted,
|
||||
0, confounder.length);
|
||||
System.arraycopy(plaintext, start, toBeEncrypted,
|
||||
confounder.length, len);
|
||||
} else {
|
||||
toBeEncrypted = new byte[len];
|
||||
System.arraycopy(plaintext, start, toBeEncrypted, 0, len);
|
||||
}
|
||||
|
||||
// encryptedData + HMAC
|
||||
byte[] output = new byte[toBeEncrypted.length + hashSize];
|
||||
|
||||
// AES in JCE
|
||||
Cipher cipher = Cipher.getInstance("AES/CTS/NoPadding");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(Ke, "AES");
|
||||
IvParameterSpec encIv = new IvParameterSpec(ivec, 0, ivec.length);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey, encIv);
|
||||
cipher.doFinal(toBeEncrypted, 0, toBeEncrypted.length, output);
|
||||
|
||||
// Derive integrity key
|
||||
constant[4] = (byte) 0x55;
|
||||
Ki = dk(baseKey, constant);
|
||||
if (debug) {
|
||||
traceOutput("constant", constant, 0, constant.length);
|
||||
traceOutput("Ki", Ki, 0, Ke.length);
|
||||
}
|
||||
|
||||
// Generate checksum
|
||||
// H1 = HMAC(Ki, conf | plaintext | pad)
|
||||
byte[] hmac = getHmac(Ki, toBeEncrypted);
|
||||
|
||||
// encryptedData + HMAC
|
||||
System.arraycopy(hmac, 0, output, toBeEncrypted.length,
|
||||
hmac.length);
|
||||
return output;
|
||||
} finally {
|
||||
if (Ke != null) {
|
||||
Arrays.fill(Ke, 0, Ke.length, (byte) 0);
|
||||
}
|
||||
if (Ki != null) {
|
||||
Arrays.fill(Ki, 0, Ki.length, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt AES in CBC-CTS mode using derived keys.
|
||||
*/
|
||||
private byte[] decryptCTS(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len, boolean confounder_exists)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
byte[] Ke = null;
|
||||
byte[] Ki = null;
|
||||
|
||||
try {
|
||||
// Derive encryption key
|
||||
byte[] constant = new byte[5];
|
||||
constant[0] = (byte) ((usage>>24)&0xff);
|
||||
constant[1] = (byte) ((usage>>16)&0xff);
|
||||
constant[2] = (byte) ((usage>>8)&0xff);
|
||||
constant[3] = (byte) (usage&0xff);
|
||||
|
||||
constant[4] = (byte) 0xaa;
|
||||
Ke = dk(baseKey, constant); // Encryption key
|
||||
|
||||
if (debug) {
|
||||
System.err.println("usage: " + usage);
|
||||
if (ivec != null) {
|
||||
traceOutput("old_state.ivec", ivec, 0, ivec.length);
|
||||
}
|
||||
traceOutput("ciphertext", ciphertext, start, Math.min(len, 32));
|
||||
traceOutput("constant", constant, 0, constant.length);
|
||||
traceOutput("baseKey", baseKey, 0, baseKey.length);
|
||||
traceOutput("Ke", Ke, 0, Ke.length);
|
||||
}
|
||||
|
||||
// Decrypt [confounder | plaintext ] (without checksum)
|
||||
|
||||
// AES in JCE
|
||||
Cipher cipher = Cipher.getInstance("AES/CTS/NoPadding");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(Ke, "AES");
|
||||
IvParameterSpec encIv = new IvParameterSpec(ivec, 0, ivec.length);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, encIv);
|
||||
byte[] plaintext = cipher.doFinal(ciphertext, start, len-hashSize);
|
||||
|
||||
if (debug) {
|
||||
traceOutput("AES PlainText", plaintext, 0,
|
||||
Math.min(plaintext.length, 32));
|
||||
}
|
||||
|
||||
// Derive integrity key
|
||||
constant[4] = (byte) 0x55;
|
||||
Ki = dk(baseKey, constant); // Integrity key
|
||||
if (debug) {
|
||||
traceOutput("constant", constant, 0, constant.length);
|
||||
traceOutput("Ki", Ki, 0, Ke.length);
|
||||
}
|
||||
|
||||
// Verify checksum
|
||||
// H1 = HMAC(Ki, conf | plaintext | pad)
|
||||
byte[] calculatedHmac = getHmac(Ki, plaintext);
|
||||
int hmacOffset = start + len - hashSize;
|
||||
if (debug) {
|
||||
traceOutput("calculated Hmac", calculatedHmac,
|
||||
0, calculatedHmac.length);
|
||||
traceOutput("message Hmac", ciphertext, hmacOffset, hashSize);
|
||||
}
|
||||
boolean cksumFailed = false;
|
||||
if (calculatedHmac.length >= hashSize) {
|
||||
for (int i = 0; i < hashSize; i++) {
|
||||
if (calculatedHmac[i] != ciphertext[hmacOffset+i]) {
|
||||
cksumFailed = true;
|
||||
if (debug) {
|
||||
System.err.println("Checksum failed !");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cksumFailed) {
|
||||
throw new GeneralSecurityException("Checksum failed");
|
||||
}
|
||||
|
||||
if (confounder_exists) {
|
||||
// Get rid of confounder
|
||||
// [ confounder | plaintext ]
|
||||
byte[] output = new byte[plaintext.length - BLOCK_SIZE];
|
||||
System.arraycopy(plaintext, BLOCK_SIZE, output,
|
||||
0, output.length);
|
||||
return output;
|
||||
} else {
|
||||
return plaintext;
|
||||
}
|
||||
} finally {
|
||||
if (Ke != null) {
|
||||
Arrays.fill(Ke, 0, Ke.length, (byte) 0);
|
||||
}
|
||||
if (Ki != null) {
|
||||
Arrays.fill(Ki, 0, Ki.length, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke the PKCS#5 PBKDF2 algorithm
|
||||
*/
|
||||
private static byte[] PBKDF2(char[] secret, byte[] salt,
|
||||
int count, int keyLength) throws GeneralSecurityException {
|
||||
|
||||
PBEKeySpec keySpec = new PBEKeySpec(secret, salt, count, keyLength);
|
||||
SecretKeyFactory skf =
|
||||
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
|
||||
SecretKey key = skf.generateSecret(keySpec);
|
||||
byte[] result = key.getEncoded();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static final int readBigEndian(byte[] data, int pos, int size) {
|
||||
int retVal = 0;
|
||||
int shifter = (size-1)*8;
|
||||
while (size > 0) {
|
||||
retVal += (data[pos] & 0xff) << shifter;
|
||||
shifter -= 8;
|
||||
pos++;
|
||||
size--;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2008, 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.dk;
|
||||
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.util.*;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.krb5.Confounder;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
|
||||
/**
|
||||
* Support for ArcFour in Kerberos
|
||||
* as defined in RFC 4757.
|
||||
* http://www.ietf.org/rfc/rfc4757.txt
|
||||
*
|
||||
* @author Seema Malkani
|
||||
*/
|
||||
|
||||
public class ArcFourCrypto extends DkCrypto {
|
||||
|
||||
private static final boolean debug = false;
|
||||
|
||||
private static final int confounderSize = 8;
|
||||
private static final byte[] ZERO_IV = new byte[] {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
private static final int hashSize = 16;
|
||||
private final int keyLength;
|
||||
|
||||
public ArcFourCrypto(int length) {
|
||||
keyLength = length;
|
||||
}
|
||||
|
||||
protected int getKeySeedLength() {
|
||||
return keyLength; // bits; RC4 key material
|
||||
}
|
||||
|
||||
protected byte[] randomToKey(byte[] in) {
|
||||
// simple identity operation
|
||||
return in;
|
||||
}
|
||||
|
||||
public byte[] stringToKey(char[] passwd)
|
||||
throws GeneralSecurityException {
|
||||
return stringToKey(passwd, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* String2Key(Password)
|
||||
* K = MD4(UNICODE(password))
|
||||
*/
|
||||
private byte[] stringToKey(char[] secret, byte[] opaque)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
if (opaque != null && opaque.length > 0) {
|
||||
throw new RuntimeException("Invalid parameter to stringToKey");
|
||||
}
|
||||
|
||||
byte[] passwd = null;
|
||||
byte[] digest = null;
|
||||
try {
|
||||
// convert ascii to unicode
|
||||
passwd = charToUtf16(secret);
|
||||
|
||||
// provider for MD4
|
||||
MessageDigest md = sun.security.provider.MD4.getInstance();
|
||||
md.update(passwd);
|
||||
digest = md.digest();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
} finally {
|
||||
if (passwd != null) {
|
||||
Arrays.fill(passwd, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
return digest;
|
||||
}
|
||||
|
||||
protected Cipher getCipher(byte[] key, byte[] ivec, int mode)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
// IV
|
||||
if (ivec == null) {
|
||||
ivec = ZERO_IV;
|
||||
}
|
||||
SecretKeySpec secretKey = new SecretKeySpec(key, "ARCFOUR");
|
||||
Cipher cipher = Cipher.getInstance("ARCFOUR");
|
||||
IvParameterSpec encIv = new IvParameterSpec(ivec, 0, ivec.length);
|
||||
cipher.init(mode, secretKey, encIv);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
public int getChecksumLength() {
|
||||
return hashSize; // bytes
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HMAC-MD5
|
||||
*/
|
||||
protected byte[] getHmac(byte[] key, byte[] msg)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
SecretKey keyKi = new SecretKeySpec(key, "HmacMD5");
|
||||
Mac m = Mac.getInstance("HmacMD5");
|
||||
m.init(keyKi);
|
||||
|
||||
// generate hash
|
||||
byte[] hash = m.doFinal(msg);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the checksum
|
||||
*/
|
||||
public byte[] calculateChecksum(byte[] baseKey, int usage, byte[] input,
|
||||
int start, int len) throws GeneralSecurityException {
|
||||
|
||||
if (debug) {
|
||||
System.out.println("ARCFOUR: calculateChecksum with usage = " +
|
||||
usage);
|
||||
}
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
|
||||
byte[] Ksign = null;
|
||||
// Derive signing key from session key
|
||||
try {
|
||||
byte[] ss = "signaturekey".getBytes();
|
||||
// need to append end-of-string 00
|
||||
byte[] new_ss = new byte[ss.length+1];
|
||||
System.arraycopy(ss, 0, new_ss, 0, ss.length);
|
||||
Ksign = getHmac(baseKey, new_ss);
|
||||
} catch (Exception e) {
|
||||
GeneralSecurityException gse =
|
||||
new GeneralSecurityException("Calculate Checkum Failed!");
|
||||
gse.initCause(e);
|
||||
throw gse;
|
||||
}
|
||||
|
||||
// get the salt using key usage
|
||||
byte[] salt = getSalt(usage);
|
||||
|
||||
// Generate checksum of message
|
||||
MessageDigest messageDigest = null;
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
GeneralSecurityException gse =
|
||||
new GeneralSecurityException("Calculate Checkum Failed!");
|
||||
gse.initCause(e);
|
||||
throw gse;
|
||||
}
|
||||
messageDigest.update(salt);
|
||||
messageDigest.update(input, start, len);
|
||||
byte[] md5tmp = messageDigest.digest();
|
||||
|
||||
// Generate checksum
|
||||
byte[] hmac = getHmac(Ksign, md5tmp);
|
||||
if (debug) {
|
||||
traceOutput("hmac", hmac, 0, hmac.length);
|
||||
}
|
||||
if (hmac.length == getChecksumLength()) {
|
||||
return hmac;
|
||||
} else if (hmac.length > getChecksumLength()) {
|
||||
byte[] buf = new byte[getChecksumLength()];
|
||||
System.arraycopy(hmac, 0, buf, 0, buf.length);
|
||||
return buf;
|
||||
} else {
|
||||
throw new GeneralSecurityException("checksum size too short: " +
|
||||
hmac.length + "; expecting : " + getChecksumLength());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs encryption of Sequence Number using derived key.
|
||||
*/
|
||||
public byte[] encryptSeq(byte[] baseKey, int usage,
|
||||
byte[] checksum, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
// derive encryption for sequence number
|
||||
byte[] salt = new byte[4];
|
||||
byte[] kSeq = getHmac(baseKey, salt);
|
||||
|
||||
// derive new encryption key salted with sequence number
|
||||
kSeq = getHmac(kSeq, checksum);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("ARCFOUR");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(kSeq, "ARCFOUR");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
byte[] output = cipher.doFinal(plaintext, start, len);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs decryption of Sequence Number using derived key.
|
||||
*/
|
||||
public byte[] decryptSeq(byte[] baseKey, int usage,
|
||||
byte[] checksum, byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
|
||||
// derive decryption for sequence number
|
||||
byte[] salt = new byte[4];
|
||||
byte[] kSeq = getHmac(baseKey, salt);
|
||||
|
||||
// derive new encryption key salted with sequence number
|
||||
kSeq = getHmac(kSeq, checksum);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("ARCFOUR");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(kSeq, "ARCFOUR");
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||
byte[] output = cipher.doFinal(ciphertext, start, len);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs encryption using derived key; adds confounder.
|
||||
*/
|
||||
public byte[] encrypt(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] new_ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
System.out.println("ArcFour: ENCRYPT with key usage = " + usage);
|
||||
}
|
||||
|
||||
// get the confounder
|
||||
byte[] confounder = Confounder.bytes(confounderSize);
|
||||
|
||||
// add confounder to the plaintext for encryption
|
||||
int plainSize = roundup(confounder.length + len, 1);
|
||||
byte[] toBeEncrypted = new byte[plainSize];
|
||||
System.arraycopy(confounder, 0, toBeEncrypted, 0, confounder.length);
|
||||
System.arraycopy(plaintext, start, toBeEncrypted,
|
||||
confounder.length, len);
|
||||
|
||||
/* begin the encryption, compute K1 */
|
||||
byte[] k1 = new byte[baseKey.length];
|
||||
System.arraycopy(baseKey, 0, k1, 0, baseKey.length);
|
||||
|
||||
// get the salt using key usage
|
||||
byte[] salt = getSalt(usage);
|
||||
|
||||
// compute K2 using K1
|
||||
byte[] k2 = getHmac(k1, salt);
|
||||
|
||||
// generate checksum using K2
|
||||
byte[] checksum = getHmac(k2, toBeEncrypted);
|
||||
|
||||
// compute K3 using K2 and checksum
|
||||
byte[] k3 = getHmac(k2, checksum);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("ARCFOUR");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(k3, "ARCFOUR");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
byte[] output = cipher.doFinal(toBeEncrypted, 0, toBeEncrypted.length);
|
||||
|
||||
// encryptedData + HMAC
|
||||
byte[] result = new byte[hashSize + output.length];
|
||||
System.arraycopy(checksum, 0, result, 0, hashSize);
|
||||
System.arraycopy(output, 0, result, hashSize, output.length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs encryption using derived key; does not add confounder.
|
||||
*/
|
||||
public byte[] encryptRaw(byte[] baseKey, int usage,
|
||||
byte[] seqNum, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
System.out.println("\nARCFOUR: encryptRaw with usage = " + usage);
|
||||
}
|
||||
|
||||
// Derive encryption key for data
|
||||
// Key derivation salt = 0
|
||||
byte[] klocal = new byte[baseKey.length];
|
||||
for (int i = 0; i <= 15; i++) {
|
||||
klocal[i] = (byte) (baseKey[i] ^ 0xF0);
|
||||
}
|
||||
byte[] salt = new byte[4];
|
||||
byte[] kcrypt = getHmac(klocal, salt);
|
||||
|
||||
// Note: When using this RC4 based encryption type, the sequence number
|
||||
// is always sent in big-endian rather than little-endian order.
|
||||
|
||||
// new encryption key salted with sequence number
|
||||
kcrypt = getHmac(kcrypt, seqNum);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("ARCFOUR");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(kcrypt, "ARCFOUR");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
byte[] output = cipher.doFinal(plaintext, start, len);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param baseKey key from which keys are to be derived using usage
|
||||
* @param ciphertext E(Ke, conf | plaintext | padding, ivec) | H1[1..h]
|
||||
*/
|
||||
public byte[] decrypt(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
if (debug) {
|
||||
System.out.println("\nARCFOUR: DECRYPT using key usage = " + usage);
|
||||
}
|
||||
|
||||
// compute K1
|
||||
byte[] k1 = new byte[baseKey.length];
|
||||
System.arraycopy(baseKey, 0, k1, 0, baseKey.length);
|
||||
|
||||
// get the salt using key usage
|
||||
byte[] salt = getSalt(usage);
|
||||
|
||||
// compute K2 using K1
|
||||
byte[] k2 = getHmac(k1, salt);
|
||||
|
||||
// compute K3 using K2 and checksum
|
||||
byte[] checksum = new byte[hashSize];
|
||||
System.arraycopy(ciphertext, start, checksum, 0, hashSize);
|
||||
byte[] k3 = getHmac(k2, checksum);
|
||||
|
||||
// Decrypt [confounder | plaintext ] (without checksum)
|
||||
Cipher cipher = Cipher.getInstance("ARCFOUR");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(k3, "ARCFOUR");
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||
byte[] plaintext = cipher.doFinal(ciphertext, start+hashSize,
|
||||
len-hashSize);
|
||||
|
||||
// Verify checksum
|
||||
byte[] calculatedHmac = getHmac(k2, plaintext);
|
||||
if (debug) {
|
||||
traceOutput("calculated Hmac", calculatedHmac, 0,
|
||||
calculatedHmac.length);
|
||||
traceOutput("message Hmac", ciphertext, 0,
|
||||
hashSize);
|
||||
}
|
||||
boolean cksumFailed = false;
|
||||
if (calculatedHmac.length >= hashSize) {
|
||||
for (int i = 0; i < hashSize; i++) {
|
||||
if (calculatedHmac[i] != ciphertext[i]) {
|
||||
cksumFailed = true;
|
||||
if (debug) {
|
||||
System.err.println("Checksum failed !");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cksumFailed) {
|
||||
throw new GeneralSecurityException("Checksum failed");
|
||||
}
|
||||
|
||||
// Get rid of confounder
|
||||
// [ confounder | plaintext ]
|
||||
byte[] output = new byte[plaintext.length - confounderSize];
|
||||
System.arraycopy(plaintext, confounderSize, output, 0, output.length);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts data using specified key and initial vector.
|
||||
* @param baseKey encryption key to use
|
||||
* @param ciphertext encrypted data to be decrypted
|
||||
* @param usage ignored
|
||||
*/
|
||||
public byte[] decryptRaw(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len, byte[] seqNum)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
if (debug) {
|
||||
System.out.println("\nARCFOUR: decryptRaw with usage = " + usage);
|
||||
}
|
||||
|
||||
// Derive encryption key for data
|
||||
// Key derivation salt = 0
|
||||
byte[] klocal = new byte[baseKey.length];
|
||||
for (int i = 0; i <= 15; i++) {
|
||||
klocal[i] = (byte) (baseKey[i] ^ 0xF0);
|
||||
}
|
||||
byte[] salt = new byte[4];
|
||||
byte[] kcrypt = getHmac(klocal, salt);
|
||||
|
||||
// need only first 4 bytes of sequence number
|
||||
byte[] sequenceNum = new byte[4];
|
||||
System.arraycopy(seqNum, 0, sequenceNum, 0, sequenceNum.length);
|
||||
|
||||
// new encryption key salted with sequence number
|
||||
kcrypt = getHmac(kcrypt, sequenceNum);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("ARCFOUR");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(kcrypt, "ARCFOUR");
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||
byte[] output = cipher.doFinal(ciphertext, start, len);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// get the salt using key usage
|
||||
private byte[] getSalt(int usage) {
|
||||
int ms_usage = arcfour_translate_usage(usage);
|
||||
byte[] salt = new byte[4];
|
||||
salt[0] = (byte)(ms_usage & 0xff);
|
||||
salt[1] = (byte)((ms_usage >> 8) & 0xff);
|
||||
salt[2] = (byte)((ms_usage >> 16) & 0xff);
|
||||
salt[3] = (byte)((ms_usage >> 24) & 0xff);
|
||||
return salt;
|
||||
}
|
||||
|
||||
// Key usage translation for MS
|
||||
private int arcfour_translate_usage(int usage) {
|
||||
switch (usage) {
|
||||
case 3: return 8;
|
||||
case 9: return 8;
|
||||
case 23: return 13;
|
||||
default: return usage;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.crypto.dk;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import javax.crypto.spec.DESedeKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Des3DkCrypto extends DkCrypto {
|
||||
|
||||
private static final byte[] ZERO_IV = new byte[] {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
public Des3DkCrypto() {
|
||||
}
|
||||
|
||||
protected int getKeySeedLength() {
|
||||
return 168; // bits; 3DES key material has 21 bytes
|
||||
}
|
||||
|
||||
public byte[] stringToKey(char[] salt) throws GeneralSecurityException {
|
||||
byte[] saltUtf8 = null;
|
||||
try {
|
||||
saltUtf8 = charToUtf8(salt);
|
||||
return stringToKey(saltUtf8, null);
|
||||
} finally {
|
||||
if (saltUtf8 != null) {
|
||||
Arrays.fill(saltUtf8, (byte)0);
|
||||
}
|
||||
// Caller responsible for clearing its own salt
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] stringToKey(byte[] secretAndSalt, byte[] opaque)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
if (opaque != null && opaque.length > 0) {
|
||||
throw new RuntimeException("Invalid parameter to stringToKey");
|
||||
}
|
||||
|
||||
byte[] tmpKey = randomToKey(nfold(secretAndSalt, getKeySeedLength()));
|
||||
return dk(tmpKey, KERBEROS_CONSTANT);
|
||||
}
|
||||
|
||||
public byte[] parityFix(byte[] value)
|
||||
throws GeneralSecurityException {
|
||||
// fix key parity
|
||||
setParityBit(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* From RFC 3961.
|
||||
*
|
||||
* The 168 bits of random key data are converted to a protocol key value
|
||||
* as follows. First, the 168 bits are divided into three groups of 56
|
||||
* bits, which are expanded individually into 64 bits as in des3Expand().
|
||||
* Result is a 24 byte (192-bit) key.
|
||||
*/
|
||||
protected byte[] randomToKey(byte[] in) {
|
||||
if (in.length != 21) {
|
||||
throw new IllegalArgumentException("input must be 168 bits");
|
||||
}
|
||||
|
||||
byte[] one = keyCorrection(des3Expand(in, 0, 7));
|
||||
byte[] two = keyCorrection(des3Expand(in, 7, 14));
|
||||
byte[] three = keyCorrection(des3Expand(in, 14, 21));
|
||||
|
||||
byte[] key = new byte[24];
|
||||
System.arraycopy(one, 0, key, 0, 8);
|
||||
System.arraycopy(two, 0, key, 8, 8);
|
||||
System.arraycopy(three, 0, key, 16, 8);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
private static byte[] keyCorrection(byte[] key) {
|
||||
// check for weak key
|
||||
try {
|
||||
if (DESKeySpec.isWeak(key, 0)) {
|
||||
key[7] = (byte)(key[7] ^ 0xF0);
|
||||
}
|
||||
} catch (InvalidKeyException ex) {
|
||||
// swallow, since it should never happen
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* From RFC 3961.
|
||||
*
|
||||
* Expands a 7-byte array into an 8-byte array that contains parity bits.
|
||||
* The 56 bits are expanded into 64 bits as follows:
|
||||
* 1 2 3 4 5 6 7 p
|
||||
* 9 10 11 12 13 14 15 p
|
||||
* 17 18 19 20 21 22 23 p
|
||||
* 25 26 27 28 29 30 31 p
|
||||
* 33 34 35 36 37 38 39 p
|
||||
* 41 42 43 44 45 46 47 p
|
||||
* 49 50 51 52 53 54 55 p
|
||||
* 56 48 40 32 24 16 8 p
|
||||
*
|
||||
* (PI,P2,...,P8) are reserved for parity bits computed on the preceding
|
||||
* seven independent bits and set so that the parity of the octet is odd,
|
||||
* i.e., there is an odd number of "1" bits in the octet.
|
||||
*
|
||||
* @param start index of starting byte (inclusive)
|
||||
* @param end index of ending byte (exclusive)
|
||||
*/
|
||||
private static byte[] des3Expand(byte[] input, int start, int end) {
|
||||
if ((end - start) != 7)
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid length of DES Key Value:" + start + "," + end);
|
||||
|
||||
byte[] result = new byte[8];
|
||||
byte last = 0;
|
||||
System.arraycopy(input, start, result, 0, 7);
|
||||
byte posn = 0;
|
||||
|
||||
// Fill in last row
|
||||
for (int i = start; i < end; i++) {
|
||||
byte bit = (byte) (input[i]&0x01);
|
||||
if (debug) {
|
||||
System.out.println(i + ": " + Integer.toHexString(input[i]) +
|
||||
" bit= " + Integer.toHexString(bit));
|
||||
}
|
||||
++posn;
|
||||
if (bit != 0) {
|
||||
last |= (bit<<posn);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
System.out.println("last: " + Integer.toHexString(last));
|
||||
}
|
||||
result[7] = last;
|
||||
setParityBit(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parity bit (0th bit) in each byte so that each byte
|
||||
* contains an odd number of 1's.
|
||||
*/
|
||||
private static void setParityBit(byte[] key) {
|
||||
for (int i = 0; i < key.length; i++) {
|
||||
int b = key[i] & 0xfe;
|
||||
b |= (Integer.bitCount(b) & 1) ^ 1;
|
||||
key[i] = (byte) b;
|
||||
}
|
||||
}
|
||||
|
||||
protected Cipher getCipher(byte[] key, byte[] ivec, int mode)
|
||||
throws GeneralSecurityException {
|
||||
// NoSuchAlgorithException
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("desede");
|
||||
|
||||
// InvalidKeyException
|
||||
KeySpec spec = new DESedeKeySpec(key, 0);
|
||||
|
||||
// InvalidKeySpecException
|
||||
SecretKey secretKey = factory.generateSecret(spec);
|
||||
|
||||
// IV
|
||||
if (ivec == null) {
|
||||
ivec = ZERO_IV;
|
||||
}
|
||||
|
||||
// NoSuchAlgorithmException, NoSuchPaddingException
|
||||
// NoSuchProviderException
|
||||
Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
|
||||
IvParameterSpec encIv = new IvParameterSpec(ivec, 0, ivec.length);
|
||||
|
||||
// InvalidKeyException, InvalidAlgorithParameterException
|
||||
cipher.init(mode, secretKey, encIv);
|
||||
|
||||
return cipher;
|
||||
}
|
||||
|
||||
public int getChecksumLength() {
|
||||
return 20; // bytes
|
||||
}
|
||||
|
||||
protected byte[] getHmac(byte[] key, byte[] msg)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
SecretKey keyKi = new SecretKeySpec(key, "HmacSHA1");
|
||||
Mac m = Mac.getInstance("HmacSHA1");
|
||||
m.init(keyKi);
|
||||
return m.doFinal(msg);
|
||||
}
|
||||
}
|
||||
699
jdkSrc/jdk8/sun/security/krb5/internal/crypto/dk/DkCrypto.java
Normal file
699
jdkSrc/jdk8/sun/security/krb5/internal/crypto/dk/DkCrypto.java
Normal file
@@ -0,0 +1,699 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998 by the FundsXpress, INC.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Export of this software from the United States of America may require
|
||||
* a specific license from the United States Government. It is the
|
||||
* responsibility of any person or organization contemplating export to
|
||||
* obtain such a license before exporting.
|
||||
*
|
||||
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
||||
* distribute this software and its documentation for any purpose and
|
||||
* without fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright notice and
|
||||
* this permission notice appear in supporting documentation, and that
|
||||
* the name of FundsXpress. not be used in advertising or publicity pertaining
|
||||
* to distribution of the software without specific, written prior
|
||||
* permission. FundsXpress makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is" without express
|
||||
* or implied warranty.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.crypto.dk;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.Mac;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Arrays;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import sun.misc.HexDumpEncoder;
|
||||
import sun.security.krb5.Confounder;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
|
||||
/**
|
||||
* Implements Derive Key cryptography functionality as defined in RFC 3961.
|
||||
* http://www.ietf.org/rfc/rfc3961.txt
|
||||
*
|
||||
* This is an abstract class. Concrete subclasses need to implement
|
||||
* the abstract methods.
|
||||
*/
|
||||
|
||||
public abstract class DkCrypto {
|
||||
|
||||
protected static final boolean debug = false;
|
||||
|
||||
// These values correspond to the ASCII encoding for the string "kerberos"
|
||||
static final byte[] KERBEROS_CONSTANT =
|
||||
{0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73};
|
||||
|
||||
protected abstract int getKeySeedLength(); // in bits
|
||||
|
||||
protected abstract byte[] randomToKey(byte[] in);
|
||||
|
||||
protected abstract Cipher getCipher(byte[] key, byte[] ivec, int mode)
|
||||
throws GeneralSecurityException;
|
||||
|
||||
public abstract int getChecksumLength(); // in bytes
|
||||
|
||||
protected abstract byte[] getHmac(byte[] key, byte[] plaintext)
|
||||
throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* From RFC 3961.
|
||||
*
|
||||
* encryption function conf = random string of length c
|
||||
* pad = shortest string to bring confounder
|
||||
* and plaintext to a length that's a
|
||||
* multiple of m
|
||||
* (C1, newIV) = E(Ke, conf | plaintext | pad,
|
||||
* oldstate.ivec)
|
||||
* H1 = HMAC(Ki, conf | plaintext | pad)
|
||||
* ciphertext = C1 | H1[1..h]
|
||||
* newstate.ivec = newIV
|
||||
*
|
||||
* @param ivec initial vector to use when initializing the cipher; if null,
|
||||
* then blocksize number of zeros are used,
|
||||
* @param new_ivec if non-null, it is updated upon return to be the
|
||||
* new ivec to use when calling encrypt next time
|
||||
*/
|
||||
public byte[] encrypt(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] new_ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
|
||||
byte[] Ke = null;
|
||||
byte[] Ki = null;
|
||||
|
||||
try {
|
||||
// Derive encryption key
|
||||
|
||||
byte[] constant = new byte[5];
|
||||
constant[0] = (byte) ((usage>>24)&0xff);
|
||||
constant[1] = (byte) ((usage>>16)&0xff);
|
||||
constant[2] = (byte) ((usage>>8)&0xff);
|
||||
constant[3] = (byte) (usage&0xff);
|
||||
|
||||
constant[4] = (byte) 0xaa;
|
||||
|
||||
Ke = dk(baseKey, constant);
|
||||
if (debug) {
|
||||
System.err.println("usage: " + usage);
|
||||
if (ivec != null) {
|
||||
traceOutput("old_state.ivec", ivec, 0, ivec.length);
|
||||
}
|
||||
traceOutput("plaintext", plaintext, start, Math.min(len, 32));
|
||||
traceOutput("constant", constant, 0, constant.length);
|
||||
traceOutput("baseKey", baseKey, 0, baseKey.length);
|
||||
traceOutput("Ke", Ke, 0, Ke.length);
|
||||
}
|
||||
|
||||
// Encrypt
|
||||
// C1 = E(Ke, conf | plaintext | pad, oldivec)
|
||||
Cipher encCipher = getCipher(Ke, ivec, Cipher.ENCRYPT_MODE);
|
||||
int blockSize = encCipher.getBlockSize();
|
||||
byte[] confounder = Confounder.bytes(blockSize);
|
||||
|
||||
int plainSize = roundup(confounder.length + len, blockSize);
|
||||
if (debug) {
|
||||
System.err.println("confounder = " + confounder.length +
|
||||
"; plaintext = " + len + "; padding = " +
|
||||
(plainSize - confounder.length - len) + "; total = " +
|
||||
plainSize);
|
||||
traceOutput("confounder", confounder, 0, confounder.length);
|
||||
}
|
||||
|
||||
byte[] toBeEncrypted = new byte[plainSize];
|
||||
System.arraycopy(confounder, 0, toBeEncrypted,
|
||||
0, confounder.length);
|
||||
System.arraycopy(plaintext, start, toBeEncrypted,
|
||||
confounder.length, len);
|
||||
|
||||
// Set padding bytes to zero
|
||||
Arrays.fill(toBeEncrypted, confounder.length + len, plainSize,
|
||||
(byte)0);
|
||||
|
||||
int cipherSize = encCipher.getOutputSize(plainSize);
|
||||
int ccSize = cipherSize + getChecksumLength(); // cipher | hmac
|
||||
|
||||
byte[] ciphertext = new byte[ccSize];
|
||||
|
||||
encCipher.doFinal(toBeEncrypted, 0, plainSize, ciphertext, 0);
|
||||
|
||||
// Update ivec for next operation
|
||||
// (last blockSize bytes of ciphertext)
|
||||
// newstate.ivec = newIV
|
||||
if (new_ivec != null && new_ivec.length == blockSize) {
|
||||
System.arraycopy(ciphertext, cipherSize - blockSize,
|
||||
new_ivec, 0, blockSize);
|
||||
if (debug) {
|
||||
traceOutput("new_ivec", new_ivec, 0, new_ivec.length);
|
||||
}
|
||||
}
|
||||
|
||||
// Derive integrity key
|
||||
constant[4] = (byte) 0x55;
|
||||
Ki = dk(baseKey, constant);
|
||||
if (debug) {
|
||||
traceOutput("constant", constant, 0, constant.length);
|
||||
traceOutput("Ki", Ki, 0, Ke.length);
|
||||
}
|
||||
|
||||
// Generate checksum
|
||||
// H1 = HMAC(Ki, conf | plaintext | pad)
|
||||
byte[] hmac = getHmac(Ki, toBeEncrypted);
|
||||
|
||||
if (debug) {
|
||||
traceOutput("hmac", hmac, 0, hmac.length);
|
||||
traceOutput("ciphertext", ciphertext, 0,
|
||||
Math.min(ciphertext.length, 32));
|
||||
}
|
||||
|
||||
// C1 | H1[1..h]
|
||||
System.arraycopy(hmac, 0, ciphertext, cipherSize,
|
||||
getChecksumLength());
|
||||
return ciphertext;
|
||||
} finally {
|
||||
if (Ke != null) {
|
||||
Arrays.fill(Ke, 0, Ke.length, (byte) 0);
|
||||
}
|
||||
if (Ki != null) {
|
||||
Arrays.fill(Ki, 0, Ki.length, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs encryption using given key only; does not add
|
||||
* confounder, padding, or checksum. Incoming data to be encrypted
|
||||
* assumed to have the correct blocksize.
|
||||
* Ignore key usage.
|
||||
*/
|
||||
public byte[] encryptRaw(byte[] baseKey, int usage,
|
||||
byte[] ivec, byte[] plaintext, int start, int len)
|
||||
throws GeneralSecurityException, KrbCryptoException {
|
||||
|
||||
if (debug) {
|
||||
System.err.println("usage: " + usage);
|
||||
if (ivec != null) {
|
||||
traceOutput("old_state.ivec", ivec, 0, ivec.length);
|
||||
}
|
||||
traceOutput("plaintext", plaintext, start, Math.min(len, 32));
|
||||
traceOutput("baseKey", baseKey, 0, baseKey.length);
|
||||
}
|
||||
|
||||
// Encrypt
|
||||
Cipher encCipher = getCipher(baseKey, ivec, Cipher.ENCRYPT_MODE);
|
||||
int blockSize = encCipher.getBlockSize();
|
||||
|
||||
if ((len % blockSize) != 0) {
|
||||
throw new GeneralSecurityException(
|
||||
"length of data to be encrypted (" + len +
|
||||
") is not a multiple of the blocksize (" + blockSize + ")");
|
||||
}
|
||||
|
||||
int cipherSize = encCipher.getOutputSize(len);
|
||||
byte[] ciphertext = new byte[cipherSize];
|
||||
|
||||
encCipher.doFinal(plaintext, 0, len, ciphertext, 0);
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts data using specified key and initial vector.
|
||||
* @param baseKey encryption key to use
|
||||
* @param ciphertext encrypted data to be decrypted
|
||||
* @param usage ignored
|
||||
*/
|
||||
public byte[] decryptRaw(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
if (debug) {
|
||||
System.err.println("usage: " + usage);
|
||||
if (ivec != null) {
|
||||
traceOutput("old_state.ivec", ivec, 0, ivec.length);
|
||||
}
|
||||
traceOutput("ciphertext", ciphertext, start, Math.min(len, 32));
|
||||
traceOutput("baseKey", baseKey, 0, baseKey.length);
|
||||
}
|
||||
|
||||
Cipher decCipher = getCipher(baseKey, ivec, Cipher.DECRYPT_MODE);
|
||||
|
||||
int blockSize = decCipher.getBlockSize();
|
||||
|
||||
if ((len % blockSize) != 0) {
|
||||
throw new GeneralSecurityException(
|
||||
"length of data to be decrypted (" + len +
|
||||
") is not a multiple of the blocksize (" + blockSize + ")");
|
||||
}
|
||||
|
||||
byte[] decrypted = decCipher.doFinal(ciphertext, start, len);
|
||||
|
||||
if (debug) {
|
||||
traceOutput("decrypted", decrypted, 0,
|
||||
Math.min(decrypted.length, 32));
|
||||
}
|
||||
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param baseKey key from which keys are to be derived using usage
|
||||
* @param ciphertext E(Ke, conf | plaintext | padding, ivec) | H1[1..h]
|
||||
*/
|
||||
public byte[] decrypt(byte[] baseKey, int usage, byte[] ivec,
|
||||
byte[] ciphertext, int start, int len) throws GeneralSecurityException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
|
||||
byte[] Ke = null;
|
||||
byte[] Ki = null;
|
||||
|
||||
try {
|
||||
// Derive encryption key
|
||||
byte[] constant = new byte[5];
|
||||
constant[0] = (byte) ((usage>>24)&0xff);
|
||||
constant[1] = (byte) ((usage>>16)&0xff);
|
||||
constant[2] = (byte) ((usage>>8)&0xff);
|
||||
constant[3] = (byte) (usage&0xff);
|
||||
|
||||
constant[4] = (byte) 0xaa;
|
||||
|
||||
Ke = dk(baseKey, constant); // Encryption key
|
||||
|
||||
if (debug) {
|
||||
System.err.println("usage: " + usage);
|
||||
if (ivec != null) {
|
||||
traceOutput("old_state.ivec", ivec, 0, ivec.length);
|
||||
}
|
||||
traceOutput("ciphertext", ciphertext, start, Math.min(len, 32));
|
||||
traceOutput("constant", constant, 0, constant.length);
|
||||
traceOutput("baseKey", baseKey, 0, baseKey.length);
|
||||
traceOutput("Ke", Ke, 0, Ke.length);
|
||||
}
|
||||
|
||||
Cipher decCipher = getCipher(Ke, ivec, Cipher.DECRYPT_MODE);
|
||||
int blockSize = decCipher.getBlockSize();
|
||||
|
||||
// Decrypt [confounder | plaintext | padding] (without checksum)
|
||||
int cksumSize = getChecksumLength();
|
||||
int cipherSize = len - cksumSize;
|
||||
byte[] decrypted = decCipher.doFinal(ciphertext, start, cipherSize);
|
||||
|
||||
if (debug) {
|
||||
traceOutput("decrypted", decrypted, 0,
|
||||
Math.min(decrypted.length, 32));
|
||||
}
|
||||
|
||||
// decrypted = [confounder | plaintext | padding]
|
||||
|
||||
// Derive integrity key
|
||||
constant[4] = (byte) 0x55;
|
||||
Ki = dk(baseKey, constant); // Integrity key
|
||||
if (debug) {
|
||||
traceOutput("constant", constant, 0, constant.length);
|
||||
traceOutput("Ki", Ki, 0, Ke.length);
|
||||
}
|
||||
|
||||
// Verify checksum
|
||||
// H1 = HMAC(Ki, conf | plaintext | pad)
|
||||
byte[] calculatedHmac = getHmac(Ki, decrypted);
|
||||
|
||||
if (debug) {
|
||||
traceOutput("calculated Hmac", calculatedHmac, 0,
|
||||
calculatedHmac.length);
|
||||
traceOutput("message Hmac", ciphertext, cipherSize,
|
||||
cksumSize);
|
||||
}
|
||||
|
||||
boolean cksumFailed = false;
|
||||
if (calculatedHmac.length >= cksumSize) {
|
||||
for (int i = 0; i < cksumSize; i++) {
|
||||
if (calculatedHmac[i] != ciphertext[cipherSize+i]) {
|
||||
cksumFailed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cksumFailed) {
|
||||
throw new GeneralSecurityException("Checksum failed");
|
||||
}
|
||||
|
||||
// Prepare decrypted msg and ivec to be returned
|
||||
// Last blockSize bytes of ciphertext without checksum
|
||||
if (ivec != null && ivec.length == blockSize) {
|
||||
System.arraycopy(ciphertext, start + cipherSize - blockSize,
|
||||
ivec, 0, blockSize);
|
||||
if (debug) {
|
||||
traceOutput("new_state.ivec", ivec, 0, ivec.length);
|
||||
}
|
||||
}
|
||||
|
||||
// Get rid of confounder
|
||||
// [plaintext | padding]
|
||||
byte[] plaintext = new byte[decrypted.length - blockSize];
|
||||
System.arraycopy(decrypted, blockSize, plaintext,
|
||||
0, plaintext.length);
|
||||
return plaintext; // padding still there
|
||||
} finally {
|
||||
if (Ke != null) {
|
||||
Arrays.fill(Ke, 0, Ke.length, (byte) 0);
|
||||
}
|
||||
if (Ki != null) {
|
||||
Arrays.fill(Ki, 0, Ki.length, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Round up to the next blocksize
|
||||
int roundup(int n, int blocksize) {
|
||||
return (((n + blocksize - 1) / blocksize) * blocksize);
|
||||
}
|
||||
|
||||
public byte[] calculateChecksum(byte[] baseKey, int usage, byte[] input,
|
||||
int start, int len) throws GeneralSecurityException {
|
||||
|
||||
if (!KeyUsage.isValid(usage)) {
|
||||
throw new GeneralSecurityException("Invalid key usage number: "
|
||||
+ usage);
|
||||
}
|
||||
|
||||
// Derive keys
|
||||
byte[] constant = new byte[5];
|
||||
constant[0] = (byte) ((usage>>24)&0xff);
|
||||
constant[1] = (byte) ((usage>>16)&0xff);
|
||||
constant[2] = (byte) ((usage>>8)&0xff);
|
||||
constant[3] = (byte) (usage&0xff);
|
||||
|
||||
constant[4] = (byte) 0x99;
|
||||
|
||||
byte[] Kc = dk(baseKey, constant); // Checksum key
|
||||
if (debug) {
|
||||
System.err.println("usage: " + usage);
|
||||
traceOutput("input", input, start, Math.min(len, 32));
|
||||
traceOutput("constant", constant, 0, constant.length);
|
||||
traceOutput("baseKey", baseKey, 0, baseKey.length);
|
||||
traceOutput("Kc", Kc, 0, Kc.length);
|
||||
}
|
||||
|
||||
try {
|
||||
// Generate checksum
|
||||
// H1 = HMAC(Kc, input)
|
||||
byte[] hmac = getHmac(Kc, input);
|
||||
if (debug) {
|
||||
traceOutput("hmac", hmac, 0, hmac.length);
|
||||
}
|
||||
if (hmac.length == getChecksumLength()) {
|
||||
return hmac;
|
||||
} else if (hmac.length > getChecksumLength()) {
|
||||
byte[] buf = new byte[getChecksumLength()];
|
||||
System.arraycopy(hmac, 0, buf, 0, buf.length);
|
||||
return buf;
|
||||
} else {
|
||||
throw new GeneralSecurityException("checksum size too short: " +
|
||||
hmac.length + "; expecting : " + getChecksumLength());
|
||||
}
|
||||
} finally {
|
||||
Arrays.fill(Kc, 0, Kc.length, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
// DK(Key, Constant) = random-to-key(DR(Key, Constant))
|
||||
byte[] dk(byte[] key, byte[] constant)
|
||||
throws GeneralSecurityException {
|
||||
return randomToKey(dr(key, constant));
|
||||
}
|
||||
|
||||
/*
|
||||
* From RFC 3961.
|
||||
*
|
||||
* DR(Key, Constant) = k-truncate(E(Key, Constant,
|
||||
* initial-cipher-state))
|
||||
*
|
||||
* Here DR is the random-octet generation function described below, and
|
||||
* DK is the key-derivation function produced from it. In this
|
||||
* construction, E(Key, Plaintext, CipherState) is a cipher, Constant is
|
||||
* a well-known constant determined by the specific usage of this
|
||||
* function, and k-truncate truncates its argument by taking the first k
|
||||
* bits. Here, k is the key generation seed length needed for the
|
||||
* encryption system.
|
||||
*
|
||||
* The output of the DR function is a string of bits; the actual key is
|
||||
* produced by applying the cryptosystem's random-to-key operation on
|
||||
* this bitstring.
|
||||
*
|
||||
* If the Constant is smaller than the cipher block size of E, then it
|
||||
* must be expanded with n-fold() so it can be encrypted. If the output
|
||||
* of E is shorter than k bits it is fed back into the encryption as
|
||||
* many times as necessary. The construct is as follows (where |
|
||||
* indicates concatentation):
|
||||
*
|
||||
* K1 = E(Key, n-fold(Constant), initial-cipher-state)
|
||||
* K2 = E(Key, K1, initial-cipher-state)
|
||||
* K3 = E(Key, K2, initial-cipher-state)
|
||||
* K4 = ...
|
||||
*
|
||||
* DR(Key, Constant) = k-truncate(K1 | K2 | K3 | K4 ...)
|
||||
*/
|
||||
private byte[] dr(byte[] key, byte[] constant)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
Cipher encCipher = getCipher(key, null, Cipher.ENCRYPT_MODE);
|
||||
int blocksize = encCipher.getBlockSize();
|
||||
|
||||
if (constant.length != blocksize) {
|
||||
constant = nfold(constant, blocksize * 8);
|
||||
}
|
||||
byte[] toBeEncrypted = constant;
|
||||
|
||||
int keybytes = (getKeySeedLength()>>3); // from bits to bytes
|
||||
byte[] rawkey = new byte[keybytes];
|
||||
int posn = 0;
|
||||
|
||||
/* loop encrypting the blocks until enough key bytes are generated */
|
||||
int n = 0, len;
|
||||
while (n < keybytes) {
|
||||
if (debug) {
|
||||
System.err.println("Encrypting: " +
|
||||
bytesToString(toBeEncrypted));
|
||||
}
|
||||
|
||||
byte[] cipherBlock = encCipher.doFinal(toBeEncrypted);
|
||||
if (debug) {
|
||||
System.err.println("K: " + ++posn + " = " +
|
||||
bytesToString(cipherBlock));
|
||||
}
|
||||
|
||||
len = (keybytes - n <= cipherBlock.length ? (keybytes - n) :
|
||||
cipherBlock.length);
|
||||
if (debug) {
|
||||
System.err.println("copying " + len + " key bytes");
|
||||
}
|
||||
System.arraycopy(cipherBlock, 0, rawkey, n, len);
|
||||
n += len;
|
||||
toBeEncrypted = cipherBlock;
|
||||
}
|
||||
return rawkey;
|
||||
}
|
||||
|
||||
// ---------------------------------
|
||||
|
||||
// From MIT-1.3.1 distribution
|
||||
/*
|
||||
* n-fold(k-bits):
|
||||
* l = lcm(n,k)
|
||||
* r = l/k
|
||||
* s = k-bits | k-bits rot 13 | k-bits rot 13*2 | ... | k-bits rot 13*(r-1)
|
||||
* compute the 1's complement sum:
|
||||
* n-fold = s[0..n-1]+s[n..2n-1]+s[2n..3n-1]+..+s[(k-1)*n..k*n-1]
|
||||
*/
|
||||
|
||||
/*
|
||||
* representation: msb first, assume n and k are multiples of 8, and
|
||||
* that k>=16. this is the case of all the cryptosystems which are
|
||||
* likely to be used. this function can be replaced if that
|
||||
* assumption ever fails.
|
||||
*/
|
||||
|
||||
/* input length is in bits */
|
||||
static byte[] nfold(byte[] in, int outbits) {
|
||||
|
||||
int inbits = in.length;
|
||||
outbits >>= 3; // count in bytes
|
||||
|
||||
/* first compute lcm(n,k) */
|
||||
int a, b, c, lcm;
|
||||
a = outbits; // n
|
||||
b = inbits; // k
|
||||
|
||||
while (b != 0) {
|
||||
c = b;
|
||||
b = a % b;
|
||||
a = c;
|
||||
}
|
||||
lcm = outbits*inbits/a;
|
||||
|
||||
if (debug) {
|
||||
System.err.println("k: " + inbits);
|
||||
System.err.println("n: " + outbits);
|
||||
System.err.println("lcm: " + lcm);
|
||||
}
|
||||
|
||||
/* now do the real work */
|
||||
byte[] out = new byte[outbits];
|
||||
Arrays.fill(out, (byte)0);
|
||||
|
||||
int thisbyte = 0;
|
||||
int msbit, i, bval, oval;
|
||||
|
||||
// this will end up cycling through k lcm(k,n)/k times, which
|
||||
// is correct
|
||||
for (i = lcm-1; i >= 0; i--) {
|
||||
/* compute the msbit in k which gets added into this byte */
|
||||
msbit = (/* first, start with msbit in the first, unrotated byte */
|
||||
((inbits<<3)-1)
|
||||
/* then, for each byte, shift to right for each repetition */
|
||||
+ (((inbits<<3)+13)*(i/inbits))
|
||||
/* last, pick out correct byte within that shifted repetition */
|
||||
+ ((inbits-(i%inbits)) << 3)) % (inbits << 3);
|
||||
|
||||
/* pull out the byte value itself */
|
||||
// Mask off values using &0xff to get only the lower byte
|
||||
// Use >>> to avoid sign extension
|
||||
bval = ((((in[((inbits-1)-(msbit>>>3))%inbits]&0xff)<<8)|
|
||||
(in[((inbits)-(msbit>>>3))%inbits]&0xff))
|
||||
>>>((msbit&7)+1))&0xff;
|
||||
|
||||
/*
|
||||
System.err.println("((" +
|
||||
((in[((inbits-1)-(msbit>>>3))%inbits]&0xff)<<8)
|
||||
+ "|" + (in[((inbits)-(msbit>>>3))%inbits]&0xff) + ")"
|
||||
+ ">>>" + ((msbit&7)+1) + ")&0xff = " + bval);
|
||||
*/
|
||||
|
||||
thisbyte += bval;
|
||||
|
||||
/* do the addition */
|
||||
// Mask off values using &0xff to get only the lower byte
|
||||
oval = (out[i%outbits]&0xff);
|
||||
thisbyte += oval;
|
||||
out[i%outbits] = (byte) (thisbyte&0xff);
|
||||
|
||||
if (debug) {
|
||||
System.err.println("msbit[" + i + "] = " + msbit + "\tbval=" +
|
||||
Integer.toHexString(bval) + "\toval=" +
|
||||
Integer.toHexString(oval)
|
||||
+ "\tsum = " + Integer.toHexString(thisbyte));
|
||||
}
|
||||
|
||||
|
||||
/* keep around the carry bit, if any */
|
||||
thisbyte >>>= 8;
|
||||
|
||||
if (debug) {
|
||||
System.err.println("carry=" + thisbyte);
|
||||
}
|
||||
}
|
||||
|
||||
/* if there's a carry bit left over, add it back in */
|
||||
if (thisbyte != 0) {
|
||||
for (i = outbits-1; i >= 0; i--) {
|
||||
/* do the addition */
|
||||
thisbyte += (out[i]&0xff);
|
||||
out[i] = (byte) (thisbyte&0xff);
|
||||
|
||||
/* keep around the carry bit, if any */
|
||||
thisbyte >>>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// Routines used for debugging
|
||||
static String bytesToString(byte[] digest) {
|
||||
// Get character representation of digest
|
||||
StringBuffer digestString = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < digest.length; i++) {
|
||||
if ((digest[i] & 0x000000ff) < 0x10) {
|
||||
digestString.append("0" +
|
||||
Integer.toHexString(digest[i] & 0x000000ff));
|
||||
} else {
|
||||
digestString.append(
|
||||
Integer.toHexString(digest[i] & 0x000000ff));
|
||||
}
|
||||
}
|
||||
return digestString.toString();
|
||||
}
|
||||
|
||||
private static byte[] binaryStringToBytes(String str) {
|
||||
char[] usageStr = str.toCharArray();
|
||||
byte[] usage = new byte[usageStr.length/2];
|
||||
for (int i = 0; i < usage.length; i++) {
|
||||
byte a = Byte.parseByte(new String(usageStr, i*2, 1), 16);
|
||||
byte b = Byte.parseByte(new String(usageStr, i*2 + 1, 1), 16);
|
||||
usage[i] = (byte) ((a<<4)|b);
|
||||
}
|
||||
return usage;
|
||||
}
|
||||
|
||||
static void traceOutput(String traceTag, byte[] output, int offset,
|
||||
int len) {
|
||||
try {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(len);
|
||||
new HexDumpEncoder().encodeBuffer(
|
||||
new ByteArrayInputStream(output, offset, len), out);
|
||||
|
||||
System.err.println(traceTag + ":" + out.toString());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
// String.getBytes("UTF-8");
|
||||
// Do this instead of using String to avoid making password immutable
|
||||
static byte[] charToUtf8(char[] chars) {
|
||||
Charset utf8 = Charset.forName("UTF-8");
|
||||
|
||||
CharBuffer cb = CharBuffer.wrap(chars);
|
||||
ByteBuffer bb = utf8.encode(cb);
|
||||
int len = bb.limit();
|
||||
byte[] answer = new byte[len];
|
||||
bb.get(answer, 0, len);
|
||||
return answer;
|
||||
}
|
||||
|
||||
static byte[] charToUtf16(char[] chars) {
|
||||
Charset utf8 = Charset.forName("UTF-16LE");
|
||||
|
||||
CharBuffer cb = CharBuffer.wrap(chars);
|
||||
ByteBuffer bb = utf8.encode(cb);
|
||||
int len = bb.limit();
|
||||
byte[] answer = new byte[len];
|
||||
bb.get(answer, 0, len);
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
524
jdkSrc/jdk8/sun/security/krb5/internal/ktab/KeyTab.java
Normal file
524
jdkSrc/jdk8/sun/security/krb5/internal/ktab/KeyTab.java
Normal file
@@ -0,0 +1,524 @@
|
||||
/*
|
||||
* 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.internal.ktab;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.io.IOException;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
import sun.security.jgss.krb5.ServiceCreds;
|
||||
|
||||
/**
|
||||
* This class represents key table. The key table functions deal with storing
|
||||
* and retrieving service keys for use in authentication exchanges.
|
||||
*
|
||||
* A KeyTab object is always constructed, if the file specified does not
|
||||
* exist, it's still valid but empty. If there is an I/O error or file format
|
||||
* error, it's invalid.
|
||||
*
|
||||
* The class is immutable on the read side (the write side is only used by
|
||||
* the ktab tool).
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public class KeyTab implements KeyTabConstants {
|
||||
|
||||
private static final boolean DEBUG = Krb5.DEBUG;
|
||||
private static String defaultTabName = null;
|
||||
|
||||
// Attention: Currently there is no way to remove a keytab from this map,
|
||||
// this might lead to a memory leak.
|
||||
private static Map<String,KeyTab> map = new HashMap<>();
|
||||
|
||||
// KeyTab file does not exist. Note: a missing keytab is still valid
|
||||
private boolean isMissing = false;
|
||||
|
||||
// KeyTab file is invalid, possibly an I/O error or a file format error.
|
||||
private boolean isValid = true;
|
||||
|
||||
private final String tabName;
|
||||
private long lastModified;
|
||||
private int kt_vno = KRB5_KT_VNO;
|
||||
|
||||
private Vector<KeyTabEntry> entries = new Vector<>();
|
||||
|
||||
/**
|
||||
* Constructs a KeyTab object.
|
||||
*
|
||||
* If there is any I/O error or format errot during the loading, the
|
||||
* isValid flag is set to false, and all half-read entries are dismissed.
|
||||
* @param filename path name for the keytab file, must not be null
|
||||
*/
|
||||
private KeyTab(String filename) {
|
||||
tabName = filename;
|
||||
try {
|
||||
lastModified = new File(tabName).lastModified();
|
||||
try (KeyTabInputStream kis =
|
||||
new KeyTabInputStream(new FileInputStream(filename))) {
|
||||
load(kis);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
entries.clear();
|
||||
isMissing = true;
|
||||
} catch (Exception ioe) {
|
||||
entries.clear();
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a keytab file. Returns a new object and save it into cache when
|
||||
* new content (modified since last read) is available. If keytab file is
|
||||
* invalid, the old object will be returned. This is a safeguard for
|
||||
* partial-written keytab files or non-stable network. Please note that
|
||||
* a missing keytab is valid, which is equivalent to an empty keytab.
|
||||
*
|
||||
* @param s file name of keytab, must not be null
|
||||
* @return the keytab object, can be invalid, but never null.
|
||||
*/
|
||||
private synchronized static KeyTab getInstance0(String s) {
|
||||
long lm = new File(s).lastModified();
|
||||
KeyTab old = map.get(s);
|
||||
if (old != null && old.isValid() && old.lastModified == lm) {
|
||||
return old;
|
||||
}
|
||||
KeyTab ktab = new KeyTab(s);
|
||||
if (ktab.isValid()) { // A valid new keytab
|
||||
map.put(s, ktab);
|
||||
return ktab;
|
||||
} else if (old != null) { // An existing old one
|
||||
return old;
|
||||
} else {
|
||||
return ktab; // first read is invalid
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a KeyTab object.
|
||||
* @param s the key tab file name.
|
||||
* @return the KeyTab object, never null.
|
||||
*/
|
||||
public static KeyTab getInstance(String s) {
|
||||
if (s == null) {
|
||||
return getInstance();
|
||||
} else {
|
||||
return getInstance0(normalize(s));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a KeyTab object.
|
||||
* @param file the key tab file.
|
||||
* @return the KeyTab object, never null.
|
||||
*/
|
||||
public static KeyTab getInstance(File file) {
|
||||
if (file == null) {
|
||||
return getInstance();
|
||||
} else {
|
||||
return getInstance0(file.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default KeyTab object.
|
||||
* @return the KeyTab object, never null.
|
||||
*/
|
||||
public static KeyTab getInstance() {
|
||||
return getInstance(getDefaultTabName());
|
||||
}
|
||||
|
||||
public boolean isMissing() {
|
||||
return isMissing;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* The location of keytab file will be read from the configuration file
|
||||
* If it is not specified, consider user.home as the keytab file's
|
||||
* default location.
|
||||
* @return never null
|
||||
*/
|
||||
private static String getDefaultTabName() {
|
||||
if (defaultTabName != null) {
|
||||
return defaultTabName;
|
||||
} else {
|
||||
String kname = null;
|
||||
try {
|
||||
String keytab_names = Config.getInstance().get
|
||||
("libdefaults", "default_keytab_name");
|
||||
if (keytab_names != null) {
|
||||
StringTokenizer st = new StringTokenizer(keytab_names, " ");
|
||||
while (st.hasMoreTokens()) {
|
||||
kname = normalize(st.nextToken());
|
||||
if (new File(kname).exists()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (KrbException e) {
|
||||
kname = null;
|
||||
}
|
||||
|
||||
if (kname == null) {
|
||||
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"));
|
||||
}
|
||||
|
||||
kname = user_home + File.separator + "krb5.keytab";
|
||||
}
|
||||
defaultTabName = kname;
|
||||
return kname;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes some common keytab name formats into the bare file name.
|
||||
* For example, FILE:/etc/krb5.keytab to /etc/krb5.keytab
|
||||
* @param name never null
|
||||
* @return never null
|
||||
*/
|
||||
// This method is used in this class and Krb5LoginModule
|
||||
public static String normalize(String name) {
|
||||
String kname;
|
||||
if ((name.length() >= 5) &&
|
||||
(name.substring(0, 5).equalsIgnoreCase("FILE:"))) {
|
||||
kname = name.substring(5);
|
||||
} else if ((name.length() >= 9) &&
|
||||
(name.substring(0, 9).equalsIgnoreCase("ANY:FILE:"))) {
|
||||
// this format found in MIT's krb5.ini.
|
||||
kname = name.substring(9);
|
||||
} else if ((name.length() >= 7) &&
|
||||
(name.substring(0, 7).equalsIgnoreCase("SRVTAB:"))) {
|
||||
// this format found in MIT's krb5.ini.
|
||||
kname = name.substring(7);
|
||||
} else
|
||||
kname = name;
|
||||
return kname;
|
||||
}
|
||||
|
||||
private void load(KeyTabInputStream kis)
|
||||
throws IOException, RealmException {
|
||||
|
||||
entries.clear();
|
||||
kt_vno = kis.readVersion();
|
||||
if (kt_vno == KRB5_KT_VNO_1) {
|
||||
kis.setNativeByteOrder();
|
||||
}
|
||||
int entryLength = 0;
|
||||
KeyTabEntry entry;
|
||||
while (kis.available() > 0) {
|
||||
entryLength = kis.readEntryLength();
|
||||
entry = kis.readEntry(entryLength, kt_vno);
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KeyTab: load() entry length: " +
|
||||
entryLength + "; type: " +
|
||||
(entry != null? entry.keyType : 0));
|
||||
}
|
||||
if (entry != null)
|
||||
entries.addElement(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a principal name in this keytab. Used by
|
||||
* {@link ServiceCreds#getKKeys()}.
|
||||
*/
|
||||
public PrincipalName getOneName() {
|
||||
int size = entries.size();
|
||||
return size > 0 ? entries.elementAt(size-1).service : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all keys for a service from the keytab file that have
|
||||
* etypes that have been configured for use.
|
||||
* @param service the PrincipalName of the requested service
|
||||
* @return an array containing all the service keys, never null
|
||||
*/
|
||||
public EncryptionKey[] readServiceKeys(PrincipalName service) {
|
||||
KeyTabEntry entry;
|
||||
EncryptionKey key;
|
||||
int size = entries.size();
|
||||
ArrayList<EncryptionKey> keys = new ArrayList<>(size);
|
||||
if (DEBUG) {
|
||||
System.out.println("Looking for keys for: " + service);
|
||||
}
|
||||
for (int i = size-1; i >= 0; i--) {
|
||||
entry = entries.elementAt(i);
|
||||
if (entry.service.match(service)) {
|
||||
if (EType.isSupported(entry.keyType)) {
|
||||
key = new EncryptionKey(entry.keyblock,
|
||||
entry.keyType,
|
||||
new Integer(entry.keyVersion));
|
||||
keys.add(key);
|
||||
if (DEBUG) {
|
||||
System.out.println("Added key: " + entry.keyType +
|
||||
"version: " + entry.keyVersion);
|
||||
}
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Found unsupported keytype (" +
|
||||
entry.keyType + ") for " + service);
|
||||
}
|
||||
}
|
||||
}
|
||||
size = keys.size();
|
||||
EncryptionKey[] retVal = keys.toArray(new EncryptionKey[size]);
|
||||
|
||||
// Sort the keys by kvno. Sometimes we must choose a single key (say,
|
||||
// generate encrypted timestamp in AS-REQ). A key with a higher KVNO
|
||||
// sounds like a newer one.
|
||||
Arrays.sort(retVal, new Comparator<EncryptionKey>() {
|
||||
@Override
|
||||
public int compare(EncryptionKey o1, EncryptionKey o2) {
|
||||
return o2.getKeyVersionNumber().intValue()
|
||||
- o1.getKeyVersionNumber().intValue();
|
||||
}
|
||||
});
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Searches for the service entry in the keytab file.
|
||||
* The etype of the key must be one that has been configured
|
||||
* to be used.
|
||||
* @param service the PrincipalName of the requested service.
|
||||
* @return true if the entry is found, otherwise, return false.
|
||||
*/
|
||||
public boolean findServiceEntry(PrincipalName service) {
|
||||
KeyTabEntry entry;
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
entry = entries.elementAt(i);
|
||||
if (entry.service.match(service)) {
|
||||
if (EType.isSupported(entry.keyType)) {
|
||||
return true;
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Found unsupported keytype (" +
|
||||
entry.keyType + ") for " + service);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String tabName() {
|
||||
return tabName;
|
||||
}
|
||||
|
||||
/////////////////// THE WRITE SIDE ///////////////////////
|
||||
/////////////// only used by ktab tool //////////////////
|
||||
|
||||
/**
|
||||
* Adds a new entry in the key table.
|
||||
* @param service the service which will have a new entry in the key table.
|
||||
* @param psswd the password which generates the key.
|
||||
* @param kvno the kvno to use, -1 means automatic increasing
|
||||
* @param append false if entries with old kvno would be removed.
|
||||
* Note: if kvno is not -1, entries with the same kvno are always removed
|
||||
*/
|
||||
public void addEntry(PrincipalName service, char[] psswd,
|
||||
int kvno, boolean append) throws KrbException {
|
||||
addEntry(service, service.getSalt(), psswd, kvno, append);
|
||||
}
|
||||
|
||||
// Called by KDC test
|
||||
public void addEntry(PrincipalName service, String salt, char[] psswd,
|
||||
int kvno, boolean append) throws KrbException {
|
||||
|
||||
EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
|
||||
psswd, salt);
|
||||
|
||||
// There should be only one maximum KVNO value for all etypes, so that
|
||||
// all added keys can have the same KVNO.
|
||||
|
||||
int maxKvno = 0; // only useful when kvno == -1
|
||||
for (int i = entries.size()-1; i >= 0; i--) {
|
||||
KeyTabEntry e = entries.get(i);
|
||||
if (e.service.match(service)) {
|
||||
if (e.keyVersion > maxKvno) {
|
||||
maxKvno = e.keyVersion;
|
||||
}
|
||||
if (!append || e.keyVersion == kvno) {
|
||||
entries.removeElementAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (kvno == -1) {
|
||||
kvno = maxKvno + 1;
|
||||
}
|
||||
|
||||
for (int i = 0; encKeys != null && i < encKeys.length; i++) {
|
||||
int keyType = encKeys[i].getEType();
|
||||
byte[] keyValue = encKeys[i].getBytes();
|
||||
|
||||
KeyTabEntry newEntry = new KeyTabEntry(service,
|
||||
service.getRealm(),
|
||||
new KerberosTime(System.currentTimeMillis()),
|
||||
kvno, keyType, keyValue);
|
||||
entries.addElement(newEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of service entries in key table.
|
||||
* @return array of <code>KeyTabEntry</code>.
|
||||
*/
|
||||
public KeyTabEntry[] getEntries() {
|
||||
KeyTabEntry[] kentries = new KeyTabEntry[entries.size()];
|
||||
for (int i = 0; i < kentries.length; i++) {
|
||||
kentries[i] = entries.elementAt(i);
|
||||
}
|
||||
return kentries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new default key table.
|
||||
*/
|
||||
public synchronized static KeyTab create()
|
||||
throws IOException, RealmException {
|
||||
String dname = getDefaultTabName();
|
||||
return create(dname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new default key table.
|
||||
*/
|
||||
public synchronized static KeyTab create(String name)
|
||||
throws IOException, RealmException {
|
||||
|
||||
try (KeyTabOutputStream kos =
|
||||
new KeyTabOutputStream(new FileOutputStream(name))) {
|
||||
kos.writeVersion(KRB5_KT_VNO);
|
||||
}
|
||||
return new KeyTab(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the file at the directory.
|
||||
*/
|
||||
public synchronized void save() throws IOException {
|
||||
try (KeyTabOutputStream kos =
|
||||
new KeyTabOutputStream(new FileOutputStream(tabName))) {
|
||||
kos.writeVersion(kt_vno);
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
kos.writeEntry(entries.elementAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes entries from the key table.
|
||||
* @param service the service <code>PrincipalName</code>.
|
||||
* @param etype the etype to match, remove all if -1
|
||||
* @param kvno what kvno to remove, -1 for all, -2 for old
|
||||
* @return the number of entries deleted
|
||||
*/
|
||||
public int deleteEntries(PrincipalName service, int etype, int kvno) {
|
||||
int count = 0;
|
||||
|
||||
// Remember the highest KVNO for each etype. Used for kvno == -2
|
||||
Map<Integer,Integer> highest = new HashMap<>();
|
||||
|
||||
for (int i = entries.size()-1; i >= 0; i--) {
|
||||
KeyTabEntry e = entries.get(i);
|
||||
if (service.match(e.getService())) {
|
||||
if (etype == -1 || e.keyType == etype) {
|
||||
if (kvno == -2) {
|
||||
// Two rounds for kvno == -2. In the first round (here),
|
||||
// only find out highest KVNO for each etype
|
||||
if (highest.containsKey(e.keyType)) {
|
||||
int n = highest.get(e.keyType);
|
||||
if (e.keyVersion > n) {
|
||||
highest.put(e.keyType, e.keyVersion);
|
||||
}
|
||||
} else {
|
||||
highest.put(e.keyType, e.keyVersion);
|
||||
}
|
||||
} else if (kvno == -1 || e.keyVersion == kvno) {
|
||||
entries.removeElementAt(i);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second round for kvno == -2, remove old entries
|
||||
if (kvno == -2) {
|
||||
for (int i = entries.size()-1; i >= 0; i--) {
|
||||
KeyTabEntry e = entries.get(i);
|
||||
if (service.match(e.getService())) {
|
||||
if (etype == -1 || e.keyType == etype) {
|
||||
int n = highest.get(e.keyType);
|
||||
if (e.keyVersion != n) {
|
||||
entries.removeElementAt(i);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates key table file version.
|
||||
* @param file the key table file.
|
||||
* @exception IOException
|
||||
*/
|
||||
public synchronized void createVersion(File file) throws IOException {
|
||||
try (KeyTabOutputStream kos =
|
||||
new KeyTabOutputStream(new FileOutputStream(file))) {
|
||||
kos.write16(KRB5_KT_VNO);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.ktab;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
/**
|
||||
* This class represents a Key Table entry. Each entry contains the service principal of
|
||||
* the key, time stamp, key version and secret key itself.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public interface KeyTabConstants {
|
||||
final int principalComponentSize = 2;
|
||||
final int realmSize = 2;
|
||||
final int principalSize = 2;
|
||||
final int principalTypeSize = 4;
|
||||
final int timestampSize = 4;
|
||||
final int keyVersionSize = 1;
|
||||
final int keyTypeSize = 2;
|
||||
final int keySize = 2;
|
||||
static final int KRB5_KT_VNO_1 = 0x0501; /* krb v5, keytab version 1 (DCE compat) */
|
||||
static final int KRB5_KT_VNO = 0x0502; /* krb v5, keytab version 2 (standard) */
|
||||
}
|
||||
112
jdkSrc/jdk8/sun/security/krb5/internal/ktab/KeyTabEntry.java
Normal file
112
jdkSrc/jdk8/sun/security/krb5/internal/ktab/KeyTabEntry.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.ktab;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* This class represents a Key Table entry. Each entry contains the service principal of
|
||||
* the key, time stamp, key version and secret key itself.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public class KeyTabEntry implements KeyTabConstants {
|
||||
PrincipalName service;
|
||||
Realm realm;
|
||||
KerberosTime timestamp;
|
||||
int keyVersion;
|
||||
int keyType;
|
||||
byte[] keyblock = null;
|
||||
boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public KeyTabEntry (PrincipalName new_service, Realm new_realm, KerberosTime new_time,
|
||||
int new_keyVersion, int new_keyType, byte[] new_keyblock) {
|
||||
service = new_service;
|
||||
realm = new_realm;
|
||||
timestamp = new_time;
|
||||
keyVersion = new_keyVersion;
|
||||
keyType = new_keyType;
|
||||
if (new_keyblock != null) {
|
||||
keyblock = new_keyblock.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public PrincipalName getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public EncryptionKey getKey() {
|
||||
EncryptionKey key = new EncryptionKey(keyblock,
|
||||
keyType,
|
||||
new Integer(keyVersion));
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getKeyString() {
|
||||
StringBuffer sb = new StringBuffer("0x");
|
||||
for (int i = 0; i < keyblock.length; i++) {
|
||||
sb.append(String.format("%02x", keyblock[i]&0xff));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
public int entryLength() {
|
||||
int totalPrincipalLength = 0;
|
||||
String[] names = service.getNameStrings();
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
try {
|
||||
totalPrincipalLength += principalSize + names[i].getBytes("8859_1").length;
|
||||
} catch (UnsupportedEncodingException exc) {
|
||||
}
|
||||
}
|
||||
|
||||
int realmLen = 0;
|
||||
try {
|
||||
realmLen = realm.toString().getBytes("8859_1").length;
|
||||
} catch (UnsupportedEncodingException exc) {
|
||||
}
|
||||
|
||||
int size = principalComponentSize + realmSize + realmLen
|
||||
+ totalPrincipalLength + principalTypeSize
|
||||
+ timestampSize + keyVersionSize
|
||||
+ keyTypeSize + keySize + keyblock.length;
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KeyTabEntry: key tab entry size is " + size);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public KerberosTime getTimeStamp() {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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.internal.ktab;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.Realm;
|
||||
import sun.security.krb5.RealmException;
|
||||
import sun.security.krb5.internal.util.KrbDataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* This class implements a buffered input stream. It is used for parsing key table
|
||||
* data to memory.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*
|
||||
*/
|
||||
public class KeyTabInputStream extends KrbDataInputStream implements KeyTabConstants {
|
||||
|
||||
boolean DEBUG = Krb5.DEBUG;
|
||||
int index;
|
||||
|
||||
public KeyTabInputStream(InputStream is) {
|
||||
super(is);
|
||||
}
|
||||
/**
|
||||
* Reads the number of bytes this entry data occupy.
|
||||
*/
|
||||
int readEntryLength() throws IOException {
|
||||
return read(4);
|
||||
}
|
||||
|
||||
|
||||
KeyTabEntry readEntry(int entryLen, int ktVersion) throws IOException, RealmException {
|
||||
index = entryLen;
|
||||
if (index == 0) { //in native implementation, when the last entry is deleted, a byte 0 is left.
|
||||
return null;
|
||||
}
|
||||
if (index < 0) { //in native implementation, when one of the entries is deleted, the entry length turns to be negative, and
|
||||
skip(Math.abs(index)); //the fields are left with 0 bytes
|
||||
return null;
|
||||
}
|
||||
int principalNum = read(2); //the number of service names.
|
||||
index -= 2;
|
||||
if (ktVersion == KRB5_KT_VNO_1) { //V1 includes realm in the count.
|
||||
principalNum -= 1;
|
||||
}
|
||||
Realm realm = new Realm(readName());
|
||||
String[] nameParts = new String[principalNum];
|
||||
for (int i = 0; i < principalNum; i++) {
|
||||
nameParts[i] = readName();
|
||||
}
|
||||
int nameType = read(4);
|
||||
index -= 4;
|
||||
PrincipalName service = new PrincipalName(nameType, nameParts, realm);
|
||||
KerberosTime timeStamp = readTimeStamp();
|
||||
|
||||
int keyVersion = read() & 0xff;
|
||||
index -= 1;
|
||||
int keyType = read(2);
|
||||
index -= 2;
|
||||
int keyLength = read(2);
|
||||
index -= 2;
|
||||
byte[] keyblock = readKey(keyLength);
|
||||
index -= keyLength;
|
||||
// There might be a 32 bit kvno here.
|
||||
// If index is zero, assume that the 8 bit key version number was
|
||||
// right, otherwise trust the new nonzero value.
|
||||
if (index >= 4) {
|
||||
int extKvno = read(4);
|
||||
if (extKvno != 0) {
|
||||
keyVersion = extKvno;
|
||||
}
|
||||
index -= 4;
|
||||
}
|
||||
|
||||
// if index is negative, the keytab format must be wrong.
|
||||
if (index < 0) {
|
||||
throw new RealmException("Keytab is corrupted");
|
||||
}
|
||||
|
||||
// ignore the left bytes.
|
||||
skip(index);
|
||||
|
||||
return new KeyTabEntry(service, realm, timeStamp, keyVersion, keyType, keyblock);
|
||||
}
|
||||
|
||||
byte[] readKey(int length) throws IOException {
|
||||
byte[] bytes = new byte[length];
|
||||
read(bytes, 0, length);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
KerberosTime readTimeStamp() throws IOException {
|
||||
index -= 4;
|
||||
return new KerberosTime((long)read(4) * 1000);
|
||||
}
|
||||
|
||||
String readName() throws IOException {
|
||||
String name;
|
||||
int length = read(2); //length of the realm name or service name
|
||||
index -= 2;
|
||||
byte[] bytes = new byte[length];
|
||||
read(bytes, 0, length);
|
||||
index -= length;
|
||||
name = new String(bytes);
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> KeyTabInputStream, readName(): " + name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.ktab;
|
||||
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.util.KrbDataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* This class implements a buffered input stream. It is used for parsing key table
|
||||
* data to memory.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*
|
||||
*/
|
||||
public class KeyTabOutputStream extends KrbDataOutputStream implements KeyTabConstants {
|
||||
private KeyTabEntry entry;
|
||||
private int keyType;
|
||||
private byte[] keyValue;
|
||||
public int version;
|
||||
|
||||
public KeyTabOutputStream(OutputStream os) {
|
||||
super(os);
|
||||
}
|
||||
|
||||
public void writeVersion(int num) throws IOException {
|
||||
version = num;
|
||||
write16(num); //we use the standard version.
|
||||
}
|
||||
|
||||
public void writeEntry(KeyTabEntry entry) throws IOException {
|
||||
write32(entry.entryLength());
|
||||
String[] serviceNames = entry.service.getNameStrings();
|
||||
int comp_num = serviceNames.length;
|
||||
if (version == KRB5_KT_VNO_1) {
|
||||
write16(comp_num + 1);
|
||||
}
|
||||
else write16(comp_num);
|
||||
|
||||
byte[] realm = null;
|
||||
try {
|
||||
realm = entry.service.getRealmString().getBytes("8859_1");
|
||||
} catch (UnsupportedEncodingException exc) {
|
||||
}
|
||||
|
||||
write16(realm.length);
|
||||
write(realm);
|
||||
for (int i = 0; i < comp_num; i++) {
|
||||
try {
|
||||
write16(serviceNames[i].getBytes("8859_1").length);
|
||||
write(serviceNames[i].getBytes("8859_1"));
|
||||
} catch (UnsupportedEncodingException exc) {
|
||||
}
|
||||
}
|
||||
write32(entry.service.getNameType());
|
||||
//time is long, but we only use 4 bytes to store the data.
|
||||
write32((int)(entry.timestamp.getTime()/1000));
|
||||
|
||||
// the key version might be a 32 bit extended number.
|
||||
write8(entry.keyVersion % 256 );
|
||||
write16(entry.keyType);
|
||||
write16(entry.keyblock.length);
|
||||
write(entry.keyblock);
|
||||
|
||||
// if the key version isn't smaller than 256, it could be saved as
|
||||
// extension key version number in 4 bytes. The nonzero extension
|
||||
// key version number will be trusted. However, it isn't standardized
|
||||
// yet, we won't support it.
|
||||
// if (entry.keyVersion >= 256) {
|
||||
// write32(entry.keyVersion);
|
||||
//}
|
||||
}
|
||||
}
|
||||
151
jdkSrc/jdk8/sun/security/krb5/internal/rcache/AuthList.java
Normal file
151
jdkSrc/jdk8/sun/security/krb5/internal/rcache/AuthList.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2018, 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.rcache;
|
||||
|
||||
import sun.security.krb5.internal.Krb5;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.ListIterator;
|
||||
import sun.security.krb5.internal.KerberosTime;
|
||||
import sun.security.krb5.internal.KrbApErrException;
|
||||
|
||||
/**
|
||||
* This class provides an efficient caching mechanism to store AuthTimeWithHash
|
||||
* from client authenticators. The cache minimizes the memory usage by doing
|
||||
* self-cleanup of expired items in the cache.
|
||||
*
|
||||
* AuthTimeWithHash objects inside a cache are always sorted from big (new) to
|
||||
* small (old) as determined by {@link AuthTimeWithHash#compareTo}. In the most
|
||||
* common case a newcomer should be newer than the first element.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public class AuthList {
|
||||
|
||||
private final LinkedList<AuthTimeWithHash> entries;
|
||||
private final int lifespan;
|
||||
|
||||
// entries.getLast().ctime, updated after each cleanup.
|
||||
private volatile int oldestTime = Integer.MIN_VALUE;
|
||||
|
||||
/**
|
||||
* Constructs a AuthList.
|
||||
*/
|
||||
public AuthList(int lifespan) {
|
||||
this.lifespan = lifespan;
|
||||
entries = new LinkedList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the authenticator timestamp into the cache in descending order,
|
||||
* and throw an exception if it's already there.
|
||||
*/
|
||||
public synchronized void put(AuthTimeWithHash t, KerberosTime currentTime)
|
||||
throws KrbApErrException {
|
||||
|
||||
if (entries.isEmpty()) {
|
||||
entries.addFirst(t);
|
||||
oldestTime = t.ctime;
|
||||
return;
|
||||
} else {
|
||||
AuthTimeWithHash temp = entries.getFirst();
|
||||
int cmp = temp.compareTo(t);
|
||||
if (cmp < 0) {
|
||||
// This is the most common case, newly received authenticator
|
||||
// has larger timestamp.
|
||||
entries.addFirst(t);
|
||||
} else if (cmp == 0) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_REPEAT);
|
||||
} else {
|
||||
//unless client clock being re-adjusted.
|
||||
ListIterator<AuthTimeWithHash> it = entries.listIterator(1);
|
||||
boolean found = false;
|
||||
while (it.hasNext()) {
|
||||
temp = it.next();
|
||||
cmp = temp.compareTo(t);
|
||||
if (cmp < 0) {
|
||||
// Find an older one, put in front of it
|
||||
entries.add(entries.indexOf(temp), t);
|
||||
found = true;
|
||||
break;
|
||||
} else if (cmp == 0) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_REPEAT);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// All is newer than the newcomer. Sigh.
|
||||
entries.addLast(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// let us cleanup while we are here
|
||||
long timeLimit = currentTime.getSeconds() - lifespan;
|
||||
|
||||
// Only trigger a cleanup when the earliest entry is
|
||||
// lifespan + 5 sec ago. This ensures a cleanup is done
|
||||
// at most every 5 seconds so that we don't always
|
||||
// addLast(removeLast).
|
||||
if (oldestTime > timeLimit - 5) {
|
||||
return;
|
||||
}
|
||||
|
||||
// and we remove the *enough* old ones (1 lifetime ago)
|
||||
while (!entries.isEmpty()) {
|
||||
AuthTimeWithHash removed = entries.removeLast();
|
||||
if (removed.ctime >= timeLimit) {
|
||||
entries.addLast(removed);
|
||||
oldestTime = removed.ctime;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
oldestTime = Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return entries.isEmpty();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Iterator<AuthTimeWithHash> iter = entries.descendingIterator();
|
||||
int pos = entries.size();
|
||||
while (iter.hasNext()) {
|
||||
AuthTimeWithHash at = iter.next();
|
||||
sb.append('#').append(pos--).append(": ")
|
||||
.append(at.toString()).append('\n');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
156
jdkSrc/jdk8/sun/security/krb5/internal/rcache/AuthTime.java
Normal file
156
jdkSrc/jdk8/sun/security/krb5/internal/rcache/AuthTime.java
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.rcache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* The class represents an old style replay cache entry. It is only used in
|
||||
* a dfl file.
|
||||
*
|
||||
* @author Sun/Oracle
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public class AuthTime {
|
||||
final int ctime;
|
||||
final int cusec;
|
||||
final String client;
|
||||
final String server;
|
||||
|
||||
/**
|
||||
* Constructs an <code>AuthTime</code>.
|
||||
*/
|
||||
public AuthTime(String client, String server,
|
||||
int ctime, int cusec) {
|
||||
this.ctime = ctime;
|
||||
this.cusec = cusec;
|
||||
this.client = client;
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%d/%06d/----/%s", ctime, cusec, client);
|
||||
}
|
||||
|
||||
// Methods used when saved in a dfl file. See DflCache.java
|
||||
|
||||
/**
|
||||
* Reads an LC style string from a channel, which is a int32 length
|
||||
* plus a UTF-8 encoded string possibly ends with \0.
|
||||
* @throws IOException if there is a format error
|
||||
* @throws BufferUnderflowException if goes beyond the end
|
||||
*/
|
||||
private static String readStringWithLength(SeekableByteChannel chan)
|
||||
throws IOException {
|
||||
ByteBuffer bb = ByteBuffer.allocate(4);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
chan.read(bb);
|
||||
bb.flip();
|
||||
int len = bb.getInt();
|
||||
if (len > 1024) {
|
||||
// Memory attack? The string should be fairly short.
|
||||
throw new IOException("Invalid string length");
|
||||
}
|
||||
bb = ByteBuffer.allocate(len);
|
||||
if (chan.read(bb) != len) {
|
||||
throw new IOException("Not enough string");
|
||||
}
|
||||
byte[] data = bb.array();
|
||||
return (data[len-1] == 0)?
|
||||
new String(data, 0, len-1, StandardCharsets.UTF_8):
|
||||
new String(data, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an AuthTime or AuthTimeWithHash object from a channel.
|
||||
* @throws IOException if there is a format error
|
||||
* @throws BufferUnderflowException if goes beyond the end
|
||||
*/
|
||||
public static AuthTime readFrom(SeekableByteChannel chan)
|
||||
throws IOException {
|
||||
String client = readStringWithLength(chan);
|
||||
String server = readStringWithLength(chan);
|
||||
ByteBuffer bb = ByteBuffer.allocate(8);
|
||||
chan.read(bb);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
int cusec = bb.getInt(0);
|
||||
int ctime = bb.getInt(4);
|
||||
if (client.isEmpty()) {
|
||||
StringTokenizer st = new StringTokenizer(server, " :");
|
||||
if (st.countTokens() != 6) {
|
||||
throw new IOException("Incorrect rcache style");
|
||||
}
|
||||
String hashAlg = st.nextToken();
|
||||
String hash = st.nextToken();
|
||||
st.nextToken();
|
||||
client = st.nextToken();
|
||||
st.nextToken();
|
||||
server = st.nextToken();
|
||||
return new AuthTimeWithHash(
|
||||
client, server, ctime, cusec, hashAlg, hash);
|
||||
} else {
|
||||
return new AuthTime(
|
||||
client, server, ctime, cusec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes to be used in a dfl file
|
||||
*/
|
||||
protected byte[] encode0(String cstring, String sstring) {
|
||||
byte[] c = cstring.getBytes(StandardCharsets.UTF_8);;
|
||||
byte[] s = sstring.getBytes(StandardCharsets.UTF_8);;
|
||||
byte[] zero = new byte[1];
|
||||
int len = 4 + c.length + 1 + 4 + s.length + 1 + 4 + 4;
|
||||
ByteBuffer bb = ByteBuffer.allocate(len)
|
||||
.order(ByteOrder.nativeOrder());
|
||||
bb.putInt(c.length+1).put(c).put(zero)
|
||||
.putInt(s.length+1).put(s).put(zero)
|
||||
.putInt(cusec).putInt(ctime);
|
||||
return bb.array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes to be used in a dfl file
|
||||
* @param withHash useless here
|
||||
*/
|
||||
public byte[] encode(boolean withHash) {
|
||||
return encode0(client, server);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user