Path: blob/master/src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java
41159 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation. Oracle designates this6* particular file as subject to the "Classpath" exception as provided7* by Oracle in the LICENSE file that accompanied this code.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324/*25*26* (C) Copyright IBM Corp. 1999 All Rights Reserved.27* Copyright 1997 The Open Group Research Institute. All rights reserved.28*/2930package sun.security.krb5;3132import sun.security.krb5.internal.*;33import sun.security.krb5.internal.crypto.KeyUsage;34import sun.security.util.DerInputStream;3536abstract class KrbKdcRep {3738static void check(39boolean isAsReq,40KDCReq req,41KDCRep rep,42EncryptionKey replyKey43) throws KrbApErrException {4445// cname change in AS-REP is allowed only if the client46// sent CANONICALIZE or an NT-ENTERPRISE cname in the request, and the47// server supports RFC 6806 - Section 11 FAST scheme (ENC-PA-REP flag).48if (isAsReq && !req.reqBody.cname.equals(rep.cname) &&49((!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&50req.reqBody.cname.getNameType() !=51PrincipalName.KRB_NT_ENTERPRISE) ||52!rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) {53rep.encKDCRepPart.key.destroy();54throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);55}5657// sname change in TGS-REP is allowed only if client58// sent CANONICALIZE and new sname is a referral of59// the form krbtgt/[email protected].60if (!req.reqBody.sname.equals(rep.encKDCRepPart.sname)) {61String[] snameStrings = rep.encKDCRepPart.sname.getNameStrings();62if (isAsReq || !req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||63snameStrings == null || snameStrings.length != 2 ||64!snameStrings[0].equals(PrincipalName.TGS_DEFAULT_SRV_NAME) ||65!rep.encKDCRepPart.sname.getRealmString().equals(66req.reqBody.sname.getRealmString())) {67rep.encKDCRepPart.key.destroy();68throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);69}70}7172if (req.reqBody.getNonce() != rep.encKDCRepPart.nonce) {73rep.encKDCRepPart.key.destroy();74throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);75}7677if (78((req.reqBody.addresses != null && rep.encKDCRepPart.caddr != null) &&79!req.reqBody.addresses.equals(rep.encKDCRepPart.caddr))) {80rep.encKDCRepPart.key.destroy();81throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);82}8384// We allow KDC to return a non-forwardable ticket if request has -f85for (int i = 2; i < 6; i++) {86if (req.reqBody.kdcOptions.get(i) !=87rep.encKDCRepPart.flags.get(i)) {88if (Krb5.DEBUG) {89System.out.println("> KrbKdcRep.check: at #" + i90+ ". request for " + req.reqBody.kdcOptions.get(i)91+ ", received " + rep.encKDCRepPart.flags.get(i));92}93throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);94}95}9697// Reply to a renewable request should be renewable, but if request does98// not contain renewable, KDC is free to issue a renewable ticket (for99// example, if ticket_lifetime is too big).100if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE) &&101!rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) {102throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);103}104105if ((req.reqBody.from == null) || req.reqBody.from.isZero()) {106// verify this is allowed107if ((rep.encKDCRepPart.starttime != null) &&108!rep.encKDCRepPart.starttime.inClockSkew()) {109rep.encKDCRepPart.key.destroy();110throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);111}112}113114if ((req.reqBody.from != null) && !req.reqBody.from.isZero()) {115// verify this is allowed116if ((rep.encKDCRepPart.starttime != null) &&117!req.reqBody.from.equals(rep.encKDCRepPart.starttime)) {118rep.encKDCRepPart.key.destroy();119throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);120}121}122123if (!req.reqBody.till.isZero() &&124rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {125rep.encKDCRepPart.key.destroy();126throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);127}128129if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE)) {130if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero()) {131// verify this is required132if ((rep.encKDCRepPart.renewTill == null) ||133rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime)134) {135rep.encKDCRepPart.key.destroy();136throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);137}138}139}140141// RFC 6806 - Section 11 mechanism check142// The availability of the ENC-PA-REP flag in the KDC response is143// mandatory on some cases (see Krb5.TKT_OPTS_ENC_PA_REP check above).144if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP)) {145boolean reqPaReqEncPaRep = false;146boolean repPaReqEncPaRepValid = false;147148if (req.pAData != null) {149for (PAData pa : req.pAData) {150if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {151// The KDC supports RFC 6806 and ENC-PA-REP was sent in152// the request (AS-REQ). A valid checksum is now required.153reqPaReqEncPaRep = true;154break;155}156}157}158159if (rep.encKDCRepPart.pAData != null) {160for (PAData pa : rep.encKDCRepPart.pAData) {161if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {162try {163Checksum repCksum = new Checksum(164new DerInputStream(165pa.getValue()).getDerValue());166// The checksum is inside encKDCRepPart so we don't167// care if it's keyed or not.168repPaReqEncPaRepValid =169repCksum.verifyAnyChecksum(170req.asn1Encode(), replyKey,171KeyUsage.KU_AS_REQ);172} catch (Exception e) {173if (Krb5.DEBUG) {174e.printStackTrace();175}176}177break;178}179}180}181182if (reqPaReqEncPaRep && !repPaReqEncPaRepValid) {183throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);184}185}186}187}188189190