1 /* 2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * 28 * (C) Copyright IBM Corp. 1999 All Rights Reserved. 29 * Copyright 1997 The Open Group Research Institute. All rights reserved. 30 */ 31 32 package sun.security.krb5; 33 34 import sun.security.krb5.internal.*; 35 import sun.security.krb5.internal.crypto.KeyUsage; 36 import sun.security.util.*; 37 import java.io.IOException; 38 39 /** 40 * This class encapsulates a KRB-AP-REP sent from the service to the 41 * client. 42 */ 43 public class KrbApRep { 44 private byte[] obuf; 45 private byte[] ibuf; 46 private EncAPRepPart encPart; // although in plain text 47 private APRep apRepMessg; 48 49 /** 50 * Constructs a KRB-AP-REP to send to a client. 51 * @throws KrbException 52 * @throws IOException 53 */ 54 // Used in AcceptSecContextToken KrbApRep(KrbApReq incomingReq, boolean useSeqNumber, EncryptionKey subKey)55 public KrbApRep(KrbApReq incomingReq, 56 boolean useSeqNumber, 57 EncryptionKey subKey) 58 throws KrbException, IOException { 59 60 SeqNumber seqNum = new LocalSeqNumber(); 61 62 init(incomingReq, subKey, seqNum); 63 } 64 65 /** 66 * Constructs a KRB-AP-REQ from the bytes received from a service. 67 * @throws KrbException 68 * @throws IOException 69 */ 70 // Used in AcceptSecContextToken KrbApRep(byte[] message, Credentials tgtCreds, KrbApReq outgoingReq)71 public KrbApRep(byte[] message, Credentials tgtCreds, 72 KrbApReq outgoingReq) throws KrbException, IOException { 73 this(message, tgtCreds); 74 authenticate(outgoingReq); 75 } 76 init(KrbApReq apReq, EncryptionKey subKey, SeqNumber seqNumber)77 private void init(KrbApReq apReq, 78 EncryptionKey subKey, 79 SeqNumber seqNumber) 80 throws KrbException, IOException { 81 createMessage( 82 apReq.getCreds().key, 83 apReq.getCtime(), 84 apReq.cusec(), 85 subKey, 86 seqNumber); 87 obuf = apRepMessg.asn1Encode(); 88 } 89 90 91 /** 92 * Constructs a KrbApRep object. 93 * @param msg a byte array of reply message. 94 * @param tgs_creds client's credential. 95 * @exception KrbException 96 * @exception IOException 97 */ KrbApRep(byte[] msg, Credentials tgs_creds)98 private KrbApRep(byte[] msg, Credentials tgs_creds) 99 throws KrbException, IOException { 100 this(new DerValue(msg), tgs_creds); 101 } 102 103 /** 104 * Constructs a KrbApRep object. 105 * @param msg a byte array of reply message. 106 * @param tgs_creds client's credential. 107 * @exception KrbException 108 * @exception IOException 109 */ KrbApRep(DerValue encoding, Credentials tgs_creds)110 private KrbApRep(DerValue encoding, Credentials tgs_creds) 111 throws KrbException, IOException { 112 APRep rep = null; 113 try { 114 rep = new APRep(encoding); 115 } catch (Asn1Exception e) { 116 rep = null; 117 KRBError err = new KRBError(encoding); 118 String errStr = err.getErrorString(); 119 String eText; 120 if (errStr.charAt(errStr.length() - 1) == 0) 121 eText = errStr.substring(0, errStr.length() - 1); 122 else 123 eText = errStr; 124 KrbException ke = new KrbException(err.getErrorCode(), eText); 125 ke.initCause(e); 126 throw ke; 127 } 128 129 byte[] temp = rep.encPart.decrypt(tgs_creds.key, 130 KeyUsage.KU_ENC_AP_REP_PART); 131 byte[] enc_ap_rep_part = rep.encPart.reset(temp); 132 133 encoding = new DerValue(enc_ap_rep_part); 134 encPart = new EncAPRepPart(encoding); 135 } 136 authenticate(KrbApReq apReq)137 private void authenticate(KrbApReq apReq) 138 throws KrbException, IOException { 139 if (encPart.ctime.getSeconds() != apReq.getCtime().getSeconds() || 140 encPart.cusec != apReq.getCtime().getMicroSeconds()) 141 throw new KrbApErrException(Krb5.KRB_AP_ERR_MUT_FAIL); 142 } 143 144 145 /** 146 * Returns the optional subkey stored in 147 * this message. Returns null if none is stored. 148 */ getSubKey()149 public EncryptionKey getSubKey() { 150 // XXX Can encPart be null 151 return encPart.getSubKey(); 152 153 } 154 155 /** 156 * Returns the optional sequence number stored in the 157 * this message. Returns null if none is stored. 158 */ getSeqNumber()159 public Integer getSeqNumber() { 160 // XXX Can encPart be null 161 return encPart.getSeqNumber(); 162 } 163 164 /** 165 * Returns the ASN.1 encoding that should be sent to the peer. 166 */ getMessage()167 public byte[] getMessage() { 168 return obuf; 169 } 170 createMessage( EncryptionKey key, KerberosTime ctime, int cusec, EncryptionKey subKey, SeqNumber seqNumber)171 private void createMessage( 172 EncryptionKey key, 173 KerberosTime ctime, 174 int cusec, 175 EncryptionKey subKey, 176 SeqNumber seqNumber) 177 throws Asn1Exception, IOException, 178 KdcErrException, KrbCryptoException { 179 180 Integer seqno = null; 181 182 if (seqNumber != null) 183 seqno = seqNumber.current(); 184 185 encPart = new EncAPRepPart(ctime, 186 cusec, 187 subKey, 188 seqno); 189 190 byte[] encPartEncoding = encPart.asn1Encode(); 191 192 EncryptedData encEncPart = new EncryptedData(key, encPartEncoding, 193 KeyUsage.KU_ENC_AP_REP_PART); 194 195 apRepMessg = new APRep(encEncPart); 196 } 197 198 } 199