1/* 2 * Copyright (c) 2000, 2012, 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.EncryptionKey; 35import sun.security.krb5.internal.*; 36import sun.security.krb5.internal.crypto.*; 37import java.io.IOException; 38 39class KrbSafe extends KrbAppMessage { 40 41 private byte[] obuf; 42 private byte[] userData; 43 44 public KrbSafe(byte[] userData, 45 Credentials creds, 46 EncryptionKey subKey, 47 KerberosTime timestamp, 48 SeqNumber seqNumber, 49 HostAddress saddr, 50 HostAddress raddr 51 ) throws KrbException, IOException { 52 EncryptionKey reqKey = null; 53 if (subKey != null) 54 reqKey = subKey; 55 else 56 reqKey = creds.key; 57 58 obuf = mk_safe(userData, 59 reqKey, 60 timestamp, 61 seqNumber, 62 saddr, 63 raddr 64 ); 65 } 66 67 public KrbSafe(byte[] msg, 68 Credentials creds, 69 EncryptionKey subKey, 70 SeqNumber seqNumber, 71 HostAddress saddr, 72 HostAddress raddr, 73 boolean timestampRequired, 74 boolean seqNumberRequired 75 ) throws KrbException, IOException { 76 77 KRBSafe krb_safe = new KRBSafe(msg); 78 79 EncryptionKey reqKey = null; 80 if (subKey != null) 81 reqKey = subKey; 82 else 83 reqKey = creds.key; 84 85 userData = rd_safe( 86 krb_safe, 87 reqKey, 88 seqNumber, 89 saddr, 90 raddr, 91 timestampRequired, 92 seqNumberRequired, 93 creds.client 94 ); 95 } 96 97 public byte[] getMessage() { 98 return obuf; 99 } 100 101 public byte[] getData() { 102 return userData; 103 } 104 105 private byte[] mk_safe(byte[] userData, 106 EncryptionKey key, 107 KerberosTime timestamp, 108 SeqNumber seqNumber, 109 HostAddress sAddress, 110 HostAddress rAddress 111 ) throws Asn1Exception, IOException, KdcErrException, 112 KrbApErrException, KrbCryptoException { 113 114 Integer usec = null; 115 Integer seqno = null; 116 117 if (timestamp != null) 118 usec = timestamp.getMicroSeconds(); 119 120 if (seqNumber != null) { 121 seqno = seqNumber.current(); 122 seqNumber.step(); 123 } 124 125 KRBSafeBody krb_safeBody = 126 new KRBSafeBody(userData, 127 timestamp, 128 usec, 129 seqno, 130 sAddress, 131 rAddress 132 ); 133 134 byte[] temp = krb_safeBody.asn1Encode(); 135 Checksum cksum = new Checksum( 136 Checksum.SAFECKSUMTYPE_DEFAULT, 137 temp, 138 key, 139 KeyUsage.KU_KRB_SAFE_CKSUM 140 ); 141 142 KRBSafe krb_safe = new KRBSafe(krb_safeBody, cksum); 143 144 temp = krb_safe.asn1Encode(); 145 146 return krb_safe.asn1Encode(); 147 } 148 149 private byte[] rd_safe(KRBSafe krb_safe, 150 EncryptionKey key, 151 SeqNumber seqNumber, 152 HostAddress sAddress, 153 HostAddress rAddress, 154 boolean timestampRequired, 155 boolean seqNumberRequired, 156 PrincipalName cname 157 ) throws Asn1Exception, KdcErrException, 158 KrbApErrException, IOException, KrbCryptoException { 159 160 byte[] temp = krb_safe.safeBody.asn1Encode(); 161 162 if (!krb_safe.cksum.verifyKeyedChecksum(temp, key, 163 KeyUsage.KU_KRB_SAFE_CKSUM)) { 164 throw new KrbApErrException( 165 Krb5.KRB_AP_ERR_MODIFIED); 166 } 167 168 check(krb_safe.safeBody.timestamp, 169 krb_safe.safeBody.usec, 170 krb_safe.safeBody.seqNumber, 171 krb_safe.safeBody.sAddress, 172 krb_safe.safeBody.rAddress, 173 seqNumber, 174 sAddress, 175 rAddress, 176 timestampRequired, 177 seqNumberRequired, 178 cname 179 ); 180 181 return krb_safe.safeBody.userData; 182 } 183} 184