Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java
38922 views
/*1* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.jgss.krb5;2627import com.sun.security.jgss.AuthorizationDataEntry;28import org.ietf.jgss.*;29import java.io.InputStream;30import java.io.IOException;3132import sun.security.action.GetPropertyAction;33import sun.security.krb5.*;34import java.net.InetAddress;35import sun.security.krb5.internal.AuthorizationData;36import sun.security.krb5.internal.KerberosTime;3738class InitSecContextToken extends InitialToken {3940// If non-mutual authentication is requested, there is no AP-REP message.41// The acceptor thus has no chance to send the seq-number field to the42// initiator. In this case, the initiator and acceptor should has an43// agreement to derive acceptor's initial seq-number if the acceptor wishes44// to send messages to the initiator.4546// If this flag is true, it will the same as the initiator's initial47// seq-number (as MIT krb5 and Windows SSPI do). Otherwise, it will be zero48// (as Heimdal does). The default value is true.49private static final boolean ACCEPTOR_USE_INITIATOR_SEQNUM;5051static {52// The ACCEPTOR_USE_INITIATOR_SEQNUM value is determined by the system53// property "sun.security.krb5.acceptor.sequence.number.nonmutual",54// which can be set to "initiator", "zero" or "0".55String propName = "sun.security.krb5.acceptor.sequence.number.nonmutual";56String s = GetPropertyAction.privilegedGetProperty(propName, "initiator");57if (s.equals("initiator")) {58ACCEPTOR_USE_INITIATOR_SEQNUM = true;59} else if (s.equals("zero") || s.equals("0")) {60ACCEPTOR_USE_INITIATOR_SEQNUM = false;61} else {62throw new AssertionError("Unrecognized value for " + propName63+ ": " + s);64}65}6667private KrbApReq apReq = null;6869/**70* For the context initiator to call. It constructs a new71* InitSecContextToken to send over to the peer containing the desired72* flags and the AP-REQ. It also updates the context with the local73* sequence number and shared context key.74* (When mutual auth is enabled the peer has an opportunity to75* renegotiate the session key in the followup AcceptSecContextToken76* that it sends.)77*/78InitSecContextToken(Krb5Context context,79Credentials tgt,80Credentials serviceTicket)81throws KrbException, IOException, GSSException {8283boolean mutualRequired = context.getMutualAuthState();84boolean useSubkey = true; // MIT Impl will crash if this is not set!85boolean useSequenceNumber = true;8687OverloadedChecksum gssChecksum =88new OverloadedChecksum(context, tgt, serviceTicket);8990Checksum checksum = gssChecksum.getChecksum();9192context.setTktFlags(serviceTicket.getFlags());93context.setAuthTime(94new KerberosTime(serviceTicket.getAuthTime()).toString());95apReq = new KrbApReq(serviceTicket,96mutualRequired,97useSubkey,98useSequenceNumber,99checksum);100101context.resetMySequenceNumber(apReq.getSeqNumber().intValue());102103EncryptionKey subKey = apReq.getSubKey();104if (subKey != null)105context.setKey(Krb5Context.INITIATOR_SUBKEY, subKey);106else107context.setKey(Krb5Context.SESSION_KEY, serviceTicket.getSessionKey());108109if (!mutualRequired)110context.resetPeerSequenceNumber(111ACCEPTOR_USE_INITIATOR_SEQNUM112? apReq.getSeqNumber().intValue()113: 0);114}115116/**117* For the context acceptor to call. It reads the bytes out of an118* InputStream and constructs an InitSecContextToken with them.119*/120InitSecContextToken(Krb5Context context, Krb5AcceptCredential cred,121InputStream is)122throws IOException, GSSException, KrbException {123124int tokenId = ((is.read()<<8) | is.read());125126if (tokenId != Krb5Token.AP_REQ_ID)127throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1,128"AP_REQ token id does not match!");129130// XXX Modify KrbApReq cons to take an InputStream131byte[] apReqBytes =132new sun.security.util.DerValue(is).toByteArray();133//debug("=====ApReqBytes: [" + getHexBytes(apReqBytes) + "]\n");134135InetAddress addr = null;136if (context.getChannelBinding() != null) {137addr = context.getChannelBinding().getInitiatorAddress();138}139apReq = new KrbApReq(apReqBytes, cred, addr);140//debug("\nReceived AP-REQ and authenticated it.\n");141142EncryptionKey sessionKey = apReq.getCreds().getSessionKey();143144/*145System.out.println("\n\nSession key from service ticket is: " +146getHexBytes(sessionKey.getBytes()));147*/148149EncryptionKey subKey = apReq.getSubKey();150if (subKey != null) {151context.setKey(Krb5Context.INITIATOR_SUBKEY, subKey);152/*153System.out.println("Sub-Session key from authenticator is: " +154getHexBytes(subKey.getBytes()) + "\n");155*/156} else {157context.setKey(Krb5Context.SESSION_KEY, sessionKey);158//System.out.println("Sub-Session Key Missing in Authenticator.\n");159}160161OverloadedChecksum gssChecksum = new OverloadedChecksum(162context, apReq.getChecksum(), sessionKey, subKey);163gssChecksum.setContextFlags(context);164Credentials delegCred = gssChecksum.getDelegatedCreds();165if (delegCred != null) {166Krb5CredElement credElement =167Krb5InitCredential.getInstance(168(Krb5NameElement)context.getSrcName(),169delegCred);170context.setDelegCred(credElement);171}172173Integer apReqSeqNumber = apReq.getSeqNumber();174int peerSeqNumber = (apReqSeqNumber != null ?175apReqSeqNumber.intValue() :1760);177context.resetPeerSequenceNumber(peerSeqNumber);178if (!context.getMutualAuthState()) {179context.resetMySequenceNumber(180ACCEPTOR_USE_INITIATOR_SEQNUM181? peerSeqNumber182: 0);183}184context.setAuthTime(185new KerberosTime(apReq.getCreds().getAuthTime()).toString());186context.setTktFlags(apReq.getCreds().getFlags());187AuthorizationData ad = apReq.getCreds().getAuthzData();188if (ad == null) {189context.setAuthzData(null);190} else {191AuthorizationDataEntry[] authzData =192new AuthorizationDataEntry[ad.count()];193for (int i=0; i<ad.count(); i++) {194authzData[i] = new AuthorizationDataEntry(195ad.item(i).adType, ad.item(i).adData);196}197context.setAuthzData(authzData);198}199}200201public final KrbApReq getKrbApReq() {202return apReq;203}204205public final byte[] encode() throws IOException {206byte[] apReqBytes = apReq.getMessage();207byte[] retVal = new byte[2 + apReqBytes.length];208writeInt(Krb5Token.AP_REQ_ID, retVal, 0);209System.arraycopy(apReqBytes, 0, retVal, 2, apReqBytes.length);210// System.out.println("GSS-Token with AP_REQ is:");211// System.out.println(getHexBytes(retVal));212return retVal;213}214}215216217