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.io.*;
38 
39 /**
40  * Implements the ASN.1 EncTicketPart type.
41  *
42  * <pre>{@code
43  * EncTicketPart   ::= [APPLICATION 3] SEQUENCE {
44  *         flags                   [0] TicketFlags,
45  *         key                     [1] EncryptionKey,
46  *         crealm                  [2] Realm,
47  *         cname                   [3] PrincipalName,
48  *         transited               [4] TransitedEncoding,
49  *         authtime                [5] KerberosTime,
50  *         starttime               [6] KerberosTime OPTIONAL,
51  *         endtime                 [7] KerberosTime,
52  *         renew-till              [8] KerberosTime OPTIONAL,
53  *         caddr                   [9] HostAddresses OPTIONAL,
54  *         authorization-data      [10] AuthorizationData OPTIONAL
55  * }
56  * }</pre>
57  *
58  * <p>
59  * This definition reflects the Network Working Group RFC 4120
60  * specification available at
61  * <a href="http://www.ietf.org/rfc/rfc4120.txt">
62  * http://www.ietf.org/rfc/rfc4120.txt</a>.
63  */
64 public class EncTicketPart {
65 
66     public TicketFlags flags;
67     public EncryptionKey key;
68     public PrincipalName cname;
69     public TransitedEncoding transited;
70     public KerberosTime authtime;
71     public KerberosTime starttime; //optional
72     public KerberosTime endtime;
73     public KerberosTime renewTill; //optional
74     public HostAddresses caddr; //optional
75     public AuthorizationData authorizationData; //optional
76 
EncTicketPart( TicketFlags new_flags, EncryptionKey new_key, PrincipalName new_cname, TransitedEncoding new_transited, KerberosTime new_authtime, KerberosTime new_starttime, KerberosTime new_endtime, KerberosTime new_renewTill, HostAddresses new_caddr, AuthorizationData new_authorizationData)77     public EncTicketPart(
78             TicketFlags new_flags,
79             EncryptionKey new_key,
80             PrincipalName new_cname,
81             TransitedEncoding new_transited,
82             KerberosTime new_authtime,
83             KerberosTime new_starttime,
84             KerberosTime new_endtime,
85             KerberosTime new_renewTill,
86             HostAddresses new_caddr,
87             AuthorizationData new_authorizationData) {
88         flags = new_flags;
89         key = new_key;
90         cname = new_cname;
91         transited = new_transited;
92         authtime = new_authtime;
93         starttime = new_starttime;
94         endtime = new_endtime;
95         renewTill = new_renewTill;
96         caddr = new_caddr;
97         authorizationData = new_authorizationData;
98     }
99 
EncTicketPart(byte[] data)100     public EncTicketPart(byte[] data)
101             throws Asn1Exception, KrbException, IOException {
102         init(new DerValue(data));
103     }
104 
EncTicketPart(DerValue encoding)105     public EncTicketPart(DerValue encoding)
106             throws Asn1Exception, KrbException, IOException {
107         init(encoding);
108     }
109 
110     /**
111      * Initializes an EncTicketPart object.
112      * @param encoding a single DER-encoded value.
113      * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
114      * @exception IOException if an I/O error occurs while reading encoded data.
115      * @exception RealmException if an error occurs while parsing a Realm object.
116      */
getHexBytes(byte[] bytes, int len)117     private static String getHexBytes(byte[] bytes, int len)
118             throws IOException {
119 
120         StringBuilder sb = new StringBuilder();
121         for (int i = 0; i < len; i++) {
122 
123             int b1 = (bytes[i] >> 4) & 0x0f;
124             int b2 = bytes[i] & 0x0f;
125 
126             sb.append(Integer.toHexString(b1));
127             sb.append(Integer.toHexString(b2));
128             sb.append(' ');
129         }
130         return sb.toString();
131     }
132 
init(DerValue encoding)133     private void init(DerValue encoding)
134             throws Asn1Exception, IOException, RealmException {
135         DerValue der, subDer;
136 
137         renewTill = null;
138         caddr = null;
139         authorizationData = null;
140         if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x03)
141                 || (encoding.isApplication() != true)
142                 || (encoding.isConstructed() != true)) {
143             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
144         }
145         der = encoding.getData().getDerValue();
146         if (der.getTag() != DerValue.tag_Sequence) {
147             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
148         }
149         flags = TicketFlags.parse(der.getData(), (byte) 0x00, false);
150         key = EncryptionKey.parse(der.getData(), (byte) 0x01, false);
151         Realm crealm = Realm.parse(der.getData(), (byte) 0x02, false);
152         cname = PrincipalName.parse(der.getData(), (byte) 0x03, false, crealm);
153         transited = TransitedEncoding.parse(der.getData(), (byte) 0x04, false);
154         authtime = KerberosTime.parse(der.getData(), (byte) 0x05, false);
155         starttime = KerberosTime.parse(der.getData(), (byte) 0x06, true);
156         endtime = KerberosTime.parse(der.getData(), (byte) 0x07, false);
157         if (der.getData().available() > 0) {
158             renewTill = KerberosTime.parse(der.getData(), (byte) 0x08, true);
159         }
160         if (der.getData().available() > 0) {
161             caddr = HostAddresses.parse(der.getData(), (byte) 0x09, true);
162         }
163         if (der.getData().available() > 0) {
164             authorizationData = AuthorizationData.parse(der.getData(), (byte) 0x0A, true);
165         }
166         if (der.getData().available() > 0) {
167             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
168         }
169 
170     }
171 
172     /**
173      * Encodes an EncTicketPart object.
174      * @return byte array of encoded EncTicketPart object.
175      * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
176      * @exception IOException if an I/O error occurs while reading encoded data.
177      */
asn1Encode()178     public byte[] asn1Encode() throws Asn1Exception, IOException {
179         DerOutputStream bytes = new DerOutputStream();
180         DerOutputStream temp = new DerOutputStream();
181         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
182                 true, (byte) 0x00), flags.asn1Encode());
183         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
184                 true, (byte) 0x01), key.asn1Encode());
185         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
186                 true, (byte) 0x02), cname.getRealm().asn1Encode());
187         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
188                 true, (byte) 0x03), cname.asn1Encode());
189         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
190                 true, (byte) 0x04), transited.asn1Encode());
191         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
192                 true, (byte) 0x05), authtime.asn1Encode());
193         if (starttime != null) {
194             bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
195                     true, (byte) 0x06), starttime.asn1Encode());
196         }
197         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
198                 true, (byte) 0x07), endtime.asn1Encode());
199 
200         if (renewTill != null) {
201             bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
202                     true, (byte) 0x08), renewTill.asn1Encode());
203         }
204 
205         if (caddr != null) {
206             bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
207                     true, (byte) 0x09), caddr.asn1Encode());
208         }
209 
210         if (authorizationData != null) {
211             bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
212                     true, (byte) 0x0A), authorizationData.asn1Encode());
213         }
214         temp.write(DerValue.tag_Sequence, bytes);
215         bytes = new DerOutputStream();
216         bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
217                 true, (byte) 0x03), temp);
218         return bytes.toByteArray();
219     }
220 }
221