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 32package sun.security.krb5; 33 34import sun.security.krb5.internal.*; 35import sun.security.krb5.internal.crypto.KeyUsage; 36import java.io.IOException; 37 38import sun.security.util.DerValue; 39 40/** 41 * This class encapsulates the KRB-CRED message that a client uses to 42 * send its delegated credentials to a server. 43 * 44 * Supports delegation of one ticket only. 45 * @author Mayank Upadhyay 46 */ 47public class KrbCred { 48 49 private static boolean DEBUG = Krb5.DEBUG; 50 51 private byte[] obuf = null; 52 private KRBCred credMessg = null; 53 private Ticket ticket = null; 54 private EncKrbCredPart encPart = null; 55 private Credentials creds = null; 56 private KerberosTime timeStamp = null; 57 58 // Used in InitialToken with null key 59 public KrbCred(Credentials tgt, 60 Credentials serviceTicket, 61 EncryptionKey key) 62 throws KrbException, IOException { 63 64 PrincipalName client = tgt.getClient(); 65 PrincipalName tgService = tgt.getServer(); 66 if (!serviceTicket.getClient().equals(client)) 67 throw new KrbException(Krb5.KRB_ERR_GENERIC, 68 "Client principal does not match"); 69 70 // XXX Check Windows flag OK-TO-FORWARD-TO 71 72 // Invoke TGS-REQ to get a forwarded TGT for the peer 73 74 KDCOptions options = new KDCOptions(); 75 options.set(KDCOptions.FORWARDED, true); 76 options.set(KDCOptions.FORWARDABLE, true); 77 78 KrbTgsReq tgsReq = new KrbTgsReq(options, tgt, tgService, 79 null, null, null, null, 80 null, // No easy way to get addresses right 81 null, null, null); 82 credMessg = createMessage(tgsReq.sendAndGetCreds(), key); 83 84 obuf = credMessg.asn1Encode(); 85 } 86 87 KRBCred createMessage(Credentials delegatedCreds, EncryptionKey key) 88 throws KrbException, IOException { 89 90 EncryptionKey sessionKey 91 = delegatedCreds.getSessionKey(); 92 PrincipalName princ = delegatedCreds.getClient(); 93 PrincipalName tgService = delegatedCreds.getServer(); 94 95 KrbCredInfo credInfo = new KrbCredInfo(sessionKey, 96 princ, delegatedCreds.flags, delegatedCreds.authTime, 97 delegatedCreds.startTime, delegatedCreds.endTime, 98 delegatedCreds.renewTill, tgService, 99 delegatedCreds.cAddr); 100 101 timeStamp = KerberosTime.now(); 102 KrbCredInfo[] credInfos = {credInfo}; 103 EncKrbCredPart encPart = 104 new EncKrbCredPart(credInfos, 105 timeStamp, null, null, null, null); 106 107 EncryptedData encEncPart = new EncryptedData(key, 108 encPart.asn1Encode(), KeyUsage.KU_ENC_KRB_CRED_PART); 109 110 Ticket[] tickets = {delegatedCreds.ticket}; 111 112 credMessg = new KRBCred(tickets, encEncPart); 113 114 return credMessg; 115 } 116 117 // Used in InitialToken, NULL_KEY might be used 118 public KrbCred(byte[] asn1Message, EncryptionKey key) 119 throws KrbException, IOException { 120 121 credMessg = new KRBCred(asn1Message); 122 123 ticket = credMessg.tickets[0]; 124 125 if (credMessg.encPart.getEType() == 0) { 126 key = EncryptionKey.NULL_KEY; 127 } 128 byte[] temp = credMessg.encPart.decrypt(key, 129 KeyUsage.KU_ENC_KRB_CRED_PART); 130 byte[] plainText = credMessg.encPart.reset(temp); 131 DerValue encoding = new DerValue(plainText); 132 EncKrbCredPart encPart = new EncKrbCredPart(encoding); 133 134 timeStamp = encPart.timeStamp; 135 136 KrbCredInfo credInfo = encPart.ticketInfo[0]; 137 EncryptionKey credInfoKey = credInfo.key; 138 PrincipalName pname = credInfo.pname; 139 TicketFlags flags = credInfo.flags; 140 KerberosTime authtime = credInfo.authtime; 141 KerberosTime starttime = credInfo.starttime; 142 KerberosTime endtime = credInfo.endtime; 143 KerberosTime renewTill = credInfo.renewTill; 144 PrincipalName sname = credInfo.sname; 145 HostAddresses caddr = credInfo.caddr; 146 147 if (DEBUG) { 148 System.out.println(">>>Delegated Creds have pname=" + pname 149 + " sname=" + sname 150 + " authtime=" + authtime 151 + " starttime=" + starttime 152 + " endtime=" + endtime 153 + "renewTill=" + renewTill); 154 } 155 creds = new Credentials(ticket, pname, sname, credInfoKey, 156 flags, authtime, starttime, endtime, renewTill, caddr); 157 } 158 159 /** 160 * Returns the delegated credentials from the peer. 161 */ 162 public Credentials[] getDelegatedCreds() { 163 164 Credentials[] allCreds = {creds}; 165 return allCreds; 166 } 167 168 /** 169 * Returns the ASN.1 encoding that should be sent to the peer. 170 */ 171 public byte[] getMessage() { 172 return obuf; 173 } 174} 175