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 31 package sun.security.krb5.internal; 32 33 import sun.security.krb5.*; 34 import sun.security.util.*; 35 import java.util.Vector; 36 import java.io.IOException; 37 import java.math.BigInteger; 38 39 /** 40 * Implements the ASN.1 EncAPRepPart type. 41 * 42 * <xmp> 43 * EncAPRepPart ::= [APPLICATION 27] SEQUENCE { 44 * ctime [0] KerberosTime, 45 * cusec [1] Microseconds, 46 * subkey [2] EncryptionKey OPTIONAL, 47 * seq-number [3] UInt32 OPTIONAL 48 * } 49 * </xmp> 50 * 51 * <p> 52 * This definition reflects the Network Working Group RFC 4120 53 * specification available at 54 * <a href="http://www.ietf.org/rfc/rfc4120.txt"> 55 * http://www.ietf.org/rfc/rfc4120.txt</a>. 56 */ 57 public class EncAPRepPart { 58 59 public KerberosTime ctime; 60 public int cusec; 61 EncryptionKey subKey; //optional 62 Integer seqNumber; //optional 63 64 public EncAPRepPart( 65 KerberosTime new_ctime, 66 int new_cusec, 67 EncryptionKey new_subKey, 68 Integer new_seqNumber) { 69 ctime = new_ctime; 70 cusec = new_cusec; 71 subKey = new_subKey; 72 seqNumber = new_seqNumber; 73 } 74 75 public EncAPRepPart(byte[] data) 76 throws Asn1Exception, IOException { 77 init(new DerValue(data)); 78 } 79 80 public EncAPRepPart(DerValue encoding) 81 throws Asn1Exception, IOException { 82 init(encoding); 83 } 84 85 /** 86 * Initializes an EncaPRepPart object. 87 * @param encoding a single DER-encoded value. 88 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. 89 * @exception IOException if an I/O error occurs while reading encoded data. 90 */ 91 private void init(DerValue encoding) throws Asn1Exception, IOException { 92 DerValue der, subDer; 93 if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1B) 94 || (encoding.isApplication() != true) 95 || (encoding.isConstructed() != true)) { 96 throw new Asn1Exception(Krb5.ASN1_BAD_ID); 97 } 98 der = encoding.getData().getDerValue(); 99 if (der.getTag() != DerValue.tag_Sequence) { 100 throw new Asn1Exception(Krb5.ASN1_BAD_ID); 101 } 102 ctime = KerberosTime.parse(der.getData(), (byte) 0x00, true); 103 subDer = der.getData().getDerValue(); 104 if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x01) { 105 cusec = subDer.getData().getBigInteger().intValue(); 106 } else { 107 throw new Asn1Exception(Krb5.ASN1_BAD_ID); 108 } 109 if (der.getData().available() > 0) { 110 subKey = EncryptionKey.parse(der.getData(), (byte) 0x02, true); 111 } else { 112 subKey = null; 113 seqNumber = null; 114 } 115 if (der.getData().available() > 0) { 116 subDer = der.getData().getDerValue(); 117 if ((subDer.getTag() & 0x1F) != 0x03) { 118 throw new Asn1Exception(Krb5.ASN1_BAD_ID); 119 } 120 seqNumber = subDer.getData().getBigInteger().intValue(); 121 } else { 122 seqNumber = null; 123 } 124 if (der.getData().available() > 0) { 125 throw new Asn1Exception(Krb5.ASN1_BAD_ID); 126 } 127 } 128 129 /** 130 * Encodes an EncAPRepPart object. 131 * @return byte array of encoded EncAPRepPart object. 132 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. 133 * @exception IOException if an I/O error occurs while reading encoded data. 134 */ 135 public byte[] asn1Encode() throws Asn1Exception, IOException { 136 Vector<DerValue> v = new Vector<>(); 137 DerOutputStream temp = new DerOutputStream(); 138 v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, 139 true, (byte) 0x00), ctime.asn1Encode())); 140 temp.putInteger(BigInteger.valueOf(cusec)); 141 v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, 142 true, (byte) 0x01), temp.toByteArray())); 143 if (subKey != null) { 144 v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, 145 true, (byte) 0x02), subKey.asn1Encode())); 146 } 147 if (seqNumber != null) { 148 temp = new DerOutputStream(); 149 // encode as an unsigned integer (UInt32) 150 temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); 151 v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, 152 true, (byte) 0x03), temp.toByteArray())); 153 } 154 DerValue[] der = new DerValue[v.size()]; 155 v.copyInto(der); 156 temp = new DerOutputStream(); 157 temp.putSequence(der); 158 DerOutputStream out = new DerOutputStream(); 159 out.write(DerValue.createTag(DerValue.TAG_APPLICATION, 160 true, (byte) 0x1B), temp); 161 return out.toByteArray(); 162 } 163 164 public final EncryptionKey getSubKey() { 165 return subKey; 166 } 167 168 public final Integer getSeqNumber() { 169 return seqNumber; 170 } 171 }