EncKrbCredPart.java revision 12318:bee34b1dcbf1
1/* 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 it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * 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 WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 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 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25/* 26 * 27 * (C) Copyright IBM Corp. 1999 All Rights Reserved. 28 * Copyright 1997 The Open Group Research Institute. All rights reserved. 29 */ 30 31package sun.security.krb5.internal; 32 33import sun.security.util.*; 34import sun.security.krb5.Asn1Exception; 35import sun.security.krb5.RealmException; 36import java.util.Vector; 37import java.io.IOException; 38import java.math.BigInteger; 39 40/** 41 * Implements the ASN.1 EncKrbCredPart type. 42 * 43 * <xmp> 44 * EncKrbCredPart ::= [APPLICATION 29] SEQUENCE { 45 * ticket-info [0] SEQUENCE OF KrbCredInfo, 46 * nonce [1] UInt32 OPTIONAL, 47 * timestamp [2] KerberosTime OPTIONAL, 48 * usec [3] Microseconds OPTIONAL, 49 * s-address [4] HostAddress OPTIONAL, 50 * r-address [5] HostAddress OPTIONAL 51 * } 52 * </xmp> 53 * 54 * <p> 55 * This definition reflects the Network Working Group RFC 4120 56 * specification available at 57 * <a href="http://www.ietf.org/rfc/rfc4120.txt"> 58 * http://www.ietf.org/rfc/rfc4120.txt</a>. 59 */ 60public class EncKrbCredPart { 61 62 public KrbCredInfo[] ticketInfo = null; 63 public KerberosTime timeStamp; //optional 64 private Integer nonce; //optional 65 private Integer usec; //optional 66 private HostAddress sAddress; //optional 67 private HostAddresses rAddress; //optional 68 69 public EncKrbCredPart( 70 KrbCredInfo[] new_ticketInfo, 71 KerberosTime new_timeStamp, 72 Integer new_usec, 73 Integer new_nonce, 74 HostAddress new_sAddress, 75 HostAddresses new_rAddress) throws IOException { 76 if (new_ticketInfo != null) { 77 ticketInfo = new KrbCredInfo[new_ticketInfo.length]; 78 for (int i = 0; i < new_ticketInfo.length; i++) { 79 if (new_ticketInfo[i] == null) { 80 throw new IOException("Cannot create a EncKrbCredPart"); 81 } else { 82 ticketInfo[i] = (KrbCredInfo) new_ticketInfo[i].clone(); 83 } 84 } 85 } 86 timeStamp = new_timeStamp; 87 usec = new_usec; 88 nonce = new_nonce; 89 sAddress = new_sAddress; 90 rAddress = new_rAddress; 91 } 92 93 public EncKrbCredPart(byte[] data) throws Asn1Exception, 94 IOException, RealmException { 95 init(new DerValue(data)); 96 } 97 98 public EncKrbCredPart(DerValue encoding) throws Asn1Exception, 99 IOException, RealmException { 100 init(encoding); 101 } 102 103 /** 104 * Initializes an EncKrbCredPart object. 105 * @param encoding a single DER-encoded value. 106 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. 107 * @exception IOException if an I/O error occurs while reading encoded data. 108 * @exception RealmException if an error occurs while parsing a Realm object. 109 */ 110 private void init(DerValue encoding) throws Asn1Exception, 111 IOException, RealmException { 112 DerValue der, subDer; 113 //may not be the correct error code for a tag 114 //mismatch on an encrypted structure 115 nonce = null; 116 timeStamp = null; 117 usec = null; 118 sAddress = null; 119 rAddress = null; 120 if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1D) 121 || (encoding.isApplication() != true) 122 || (encoding.isConstructed() != true)) { 123 throw new Asn1Exception(Krb5.ASN1_BAD_ID); 124 } 125 der = encoding.getData().getDerValue(); 126 if (der.getTag() != DerValue.tag_Sequence) { 127 throw new Asn1Exception(Krb5.ASN1_BAD_ID); 128 } 129 130 subDer = der.getData().getDerValue(); 131 if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x00) { 132 DerValue[] derValues = subDer.getData().getSequence(1); 133 ticketInfo = new KrbCredInfo[derValues.length]; 134 for (int i = 0; i < derValues.length; i++) { 135 ticketInfo[i] = new KrbCredInfo(derValues[i]); 136 } 137 } else { 138 throw new Asn1Exception(Krb5.ASN1_BAD_ID); 139 } 140 if (der.getData().available() > 0) { 141 if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x01) { 142 subDer = der.getData().getDerValue(); 143 nonce = subDer.getData().getBigInteger().intValue(); 144 } 145 } 146 if (der.getData().available() > 0) { 147 timeStamp = KerberosTime.parse(der.getData(), (byte) 0x02, true); 148 } 149 if (der.getData().available() > 0) { 150 if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x03) { 151 subDer = der.getData().getDerValue(); 152 usec = subDer.getData().getBigInteger().intValue(); 153 } 154 } 155 if (der.getData().available() > 0) { 156 sAddress = HostAddress.parse(der.getData(), (byte) 0x04, true); 157 } 158 if (der.getData().available() > 0) { 159 rAddress = HostAddresses.parse(der.getData(), (byte) 0x05, true); 160 } 161 if (der.getData().available() > 0) { 162 throw new Asn1Exception(Krb5.ASN1_BAD_ID); 163 } 164 } 165 166 /** 167 * Encodes an EncKrbCredPart object. 168 * @return byte array of encoded EncKrbCredPart object. 169 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. 170 * @exception IOException if an I/O error occurs while reading encoded data. 171 * 172 */ 173 public byte[] asn1Encode() throws Asn1Exception, IOException { 174 DerOutputStream bytes = new DerOutputStream(); 175 DerOutputStream temp = new DerOutputStream(); 176 DerValue[] tickets = new DerValue[ticketInfo.length]; 177 for (int i = 0; i < ticketInfo.length; i++) { 178 tickets[i] = new DerValue(ticketInfo[i].asn1Encode()); 179 } 180 temp.putSequence(tickets); 181 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, 182 true, (byte) 0x00), temp); 183 184 if (nonce != null) { 185 temp = new DerOutputStream(); 186 temp.putInteger(BigInteger.valueOf(nonce.intValue())); 187 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, 188 true, (byte) 0x01), temp); 189 } 190 if (timeStamp != null) { 191 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, 192 true, (byte) 0x02), timeStamp.asn1Encode()); 193 } 194 if (usec != null) { 195 temp = new DerOutputStream(); 196 temp.putInteger(BigInteger.valueOf(usec.intValue())); 197 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, 198 true, (byte) 0x03), temp); 199 } 200 if (sAddress != null) { 201 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, 202 true, (byte) 0x04), sAddress.asn1Encode()); 203 } 204 if (rAddress != null) { 205 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, 206 true, (byte) 0x05), rAddress.asn1Encode()); 207 } 208 temp = new DerOutputStream(); 209 temp.write(DerValue.tag_Sequence, bytes); 210 bytes = new DerOutputStream(); 211 bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, 212 true, (byte) 0x1D), temp); 213 return bytes.toByteArray(); 214 } 215} 216