blob: 2c364e834b01ba5ac268fe9b672783885bf7c9f7 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
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. Sun designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any 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.krb5.EncryptedData;
34import sun.security.krb5.Asn1Exception;
35import sun.security.krb5.RealmException;
36import sun.security.util.*;
37import java.util.Vector;
38import java.io.IOException;
39import java.math.BigInteger;
40
41/**
42 * Implements the ASN.1 Authenticator type.
43 *
44 * <xmp>
45 * KRB-CRED ::= [APPLICATION 22] SEQUENCE {
46 * pvno [0] INTEGER (5),
47 * msg-type [1] INTEGER (22),
48 * tickets [2] SEQUENCE OF Ticket,
49 * enc-part [3] EncryptedData -- EncKrbCredPart
50 * }
51 * </xmp>
52 *
53 * <p>
54 * This definition reflects the Network Working Group RFC 4120
55 * specification available at
56 * <a href="http://www.ietf.org/rfc/rfc4120.txt">
57 * http://www.ietf.org/rfc/rfc4120.txt</a>.
58 */
59
60public class KRBCred {
61 public Ticket[] tickets = null;
62 public EncryptedData encPart;
63
64 private int pvno;
65 private int msgType;
66
67 public KRBCred(Ticket[] new_tickets, EncryptedData new_encPart) throws IOException {
68 pvno = Krb5.PVNO;
69 msgType = Krb5.KRB_CRED;
70 if (new_tickets != null) {
71 tickets = new Ticket[new_tickets.length];
72 for (int i = 0; i < new_tickets.length; i++) {
73 if (new_tickets[i] == null) {
74 throw new IOException("Cannot create a KRBCred");
75 } else {
76 tickets[i] = (Ticket)new_tickets[i].clone();
77 }
78 }
79 }
80 encPart = new_encPart;
81 }
82
83 public KRBCred(byte[] data) throws Asn1Exception,
84 RealmException, KrbApErrException, IOException {
85 init(new DerValue(data));
86 }
87
88 public KRBCred(DerValue encoding) throws Asn1Exception,
89 RealmException, KrbApErrException, IOException {
90 init(encoding);
91 }
92
93 /**
94 * Initializes an KRBCred object.
95 * @param encoding a single DER-encoded value.
96 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
97 * @exception IOException if an I/O error occurs while reading encoded data.
98 * @exception KrbApErrException if the value read from the DER-encoded data
99 * stream does not match the pre-defined value.
100 * @exception RealmException if an error occurs while parsing a Realm object.
101 */
102 private void init(DerValue encoding) throws Asn1Exception,
103 RealmException, KrbApErrException, IOException {
104 if (((encoding.getTag() & (byte)0x1F) != (byte)0x16)
105 || (encoding.isApplication() != true)
106 || (encoding.isConstructed() != true))
107 throw new Asn1Exception(Krb5.ASN1_BAD_ID);
108 DerValue der, subDer;
109 der = encoding.getData().getDerValue();
110 if (der.getTag() != DerValue.tag_Sequence)
111 throw new Asn1Exception(Krb5.ASN1_BAD_ID);
112 subDer = der.getData().getDerValue();
113 if ((subDer.getTag() & 0x1F) == 0x00) {
114 pvno = subDer.getData().getBigInteger().intValue();
115 if (pvno != Krb5.PVNO) {
116 throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
117 }
118 }
119 else
120 throw new Asn1Exception(Krb5.ASN1_BAD_ID);
121 subDer = der.getData().getDerValue();
122 if ((subDer.getTag() & 0x1F) == 0x01) {
123 msgType = subDer.getData().getBigInteger().intValue();
124 if (msgType != Krb5.KRB_CRED)
125 throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
126 }
127 else
128 throw new Asn1Exception(Krb5.ASN1_BAD_ID);
129 subDer = der.getData().getDerValue();
130 if ((subDer.getTag() & 0x1F) == 0x02) {
131 DerValue subsubDer = subDer.getData().getDerValue();
132 if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
133 throw new Asn1Exception(Krb5.ASN1_BAD_ID);
134 }
135 Vector<Ticket> v = new Vector<Ticket> ();
136 while (subsubDer.getData().available() > 0) {
137 v.addElement(new Ticket(subsubDer.getData().getDerValue()));
138 }
139 if (v.size() > 0) {
140 tickets = new Ticket[v.size()];
141 v.copyInto(tickets);
142 }
143 }
144 else
145 throw new Asn1Exception(Krb5.ASN1_BAD_ID);
146 encPart = EncryptedData.parse(der.getData(), (byte)0x03, false);
147
148 if (der.getData().available() > 0)
149 throw new Asn1Exception(Krb5.ASN1_BAD_ID);
150 }
151
152
153 /**
154 * Encodes an KRBCred object.
155 * @return the data of encoded EncAPRepPart object.
156 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
157 * @exception IOException if an I/O error occurs while reading encoded data.
158 */
159 public byte[] asn1Encode() throws Asn1Exception, IOException {
160 DerOutputStream temp, bytes, out;
161 temp = new DerOutputStream();
162 temp.putInteger(BigInteger.valueOf(pvno));
163 out = new DerOutputStream();
164 out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
165 temp = new DerOutputStream();
166 temp.putInteger(BigInteger.valueOf(msgType));
167 out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
168 temp = new DerOutputStream();
169 for (int i = 0; i < tickets.length; i++) {
170 temp.write(tickets[i].asn1Encode());
171 }
172 bytes = new DerOutputStream();
173 bytes.write(DerValue.tag_SequenceOf, temp);
174 out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), bytes);
175 out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), encPart.asn1Encode());
176 bytes = new DerOutputStream();
177 bytes.write(DerValue.tag_Sequence, out);
178 out = new DerOutputStream();
179 out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x16), bytes);
180 return out.toByteArray();
181 }
182
183}