001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.auth.internal.kerberos.v5;
019:
020: import java.io.ByteArrayInputStream;
021: import java.io.IOException;
022: import java.util.Date;
023:
024: import javax.crypto.SecretKey;
025:
026: import org.apache.harmony.security.asn1.ASN1Any;
027: import org.apache.harmony.security.asn1.ASN1BitString;
028: import org.apache.harmony.security.asn1.ASN1Constants;
029: import org.apache.harmony.security.asn1.ASN1Explicit;
030: import org.apache.harmony.security.asn1.ASN1Integer;
031: import org.apache.harmony.security.asn1.ASN1OctetString;
032: import org.apache.harmony.security.asn1.ASN1Sequence;
033: import org.apache.harmony.security.asn1.ASN1SequenceOf;
034: import org.apache.harmony.security.asn1.ASN1StringType;
035: import org.apache.harmony.security.asn1.ASN1Type;
036: import org.apache.harmony.security.asn1.BerInputStream;
037: import org.apache.harmony.security.asn1.BitString;
038: import org.apache.harmony.security.asn1.DerInputStream;
039:
040: /**
041: * @see http://www.ietf.org/rfc/rfc4120.txt
042: */
043: public class KDCReply {
044:
045: /**
046: * Authentication Service request message type
047: */
048: public static final int AS_REP = 11;
049:
050: /**
051: * Ticket-Granting Service request message type
052: */
053: public static final int TGS_REP = 13;
054:
055: // type of a protocol message: AS_REP or TGS_REP
056: private final int msgType;
057:
058: private final PrincipalName cname;
059:
060: private final String crealm;
061:
062: private final Ticket ticket;
063:
064: private final EncryptedData encPart;
065:
066: //
067: //
068: //
069: private Date authtime;
070:
071: private Date starttime;
072:
073: private Date endtime;
074:
075: private Date renewtill;
076:
077: private String srealm;
078:
079: private PrincipalName sname;
080:
081: // session key
082: private EncryptionKey key;
083:
084: private BitString flags;
085:
086: private KDCReply(int msgType, String crealm, PrincipalName cname,
087: Ticket ticket, EncryptedData encPart) {
088: this .msgType = msgType;
089: this .cname = cname;
090: this .crealm = crealm;
091: this .ticket = ticket;
092: this .encPart = encPart;
093: }
094:
095: public void decrypt(SecretKey key) throws IOException {
096: DerInputStream in = new DerInputStream(
097: new ByteArrayInputStream(encPart.decrypt(key)));
098:
099: Object[] values = (Object[]) ENC_AS_REP_PART.decode(in);
100:
101: this .key = (EncryptionKey) values[0];
102: flags = (BitString) values[4];
103: authtime = (Date) values[5];
104: starttime = (Date) values[6];
105: endtime = (Date) values[7];
106: renewtill = (Date) values[8];
107: srealm = (String) values[9];
108: sname = (PrincipalName) values[10];
109: }
110:
111: public int getMsgtype() {
112: return msgType;
113: }
114:
115: public String getCrealm() {
116: return crealm;
117: }
118:
119: public PrincipalName getCname() {
120: return cname;
121: }
122:
123: public Ticket getTicket() {
124: return ticket;
125: }
126:
127: public EncryptedData getEncPart() {
128: return encPart;
129: }
130:
131: //
132: //
133: //
134:
135: public Date getAuthtime() {
136: return authtime;
137: }
138:
139: public Date getStarttime() {
140: return starttime;
141: }
142:
143: public Date getEndtime() {
144: return endtime;
145: }
146:
147: public Date getRenewtill() {
148: return renewtill;
149: }
150:
151: public String getSrealm() {
152: return srealm;
153: }
154:
155: public PrincipalName getSname() {
156: return sname;
157: }
158:
159: public EncryptionKey getKey() {
160: return key;
161: }
162:
163: public BitString getFlags() {
164: return flags;
165: }
166:
167: /**
168: * <pre>
169: * KDC-REP ::= SEQUENCE {
170: * pvno [0] INTEGER (5),
171: * msg-type [1] INTEGER (11 -- AS -- | 13 -- TGS --),
172: * padata [2] SEQUENCE OF PA-DATA OPTIONAL
173: * -- NOTE: not empty --,
174: * crealm [3] Realm,
175: * cname [4] PrincipalName,
176: * ticket [5] Ticket,
177: * enc-part [6] EncryptedData
178: * -- EncASRepPart or EncTGSRepPart,
179: * -- as appropriate
180: * }
181: * </pre>
182: */
183: static final ASN1Sequence KDC_REP_ASN1 = new ASN1Sequence(
184: new ASN1Type[] {
185: new ASN1Explicit(0, ASN1Integer.getInstance()), // pvno
186: new ASN1Explicit(1, ASN1Integer.getInstance()), // msg-type
187: new ASN1Explicit(2, new ASN1SequenceOf(ASN1Any
188: .getInstance())),
189: // TODO should we define Realm type?
190: new ASN1Explicit(3, ASN1StringType.GENERALSTRING), // crealm
191: new ASN1Explicit(4, PrincipalName.ASN1), // cname
192: new ASN1Explicit(5, Ticket.TICKET_ASN1), // ticket
193: new ASN1Explicit(6, EncryptedData.ASN1), // enc-part
194: }) {
195: {
196: setOptional(2); // padata
197: }
198:
199: @Override
200: protected Object getDecodedObject(BerInputStream in)
201: throws IOException {
202:
203: Object[] values = (Object[]) in.content;
204:
205: return new KDCReply(ASN1Integer.toIntValue(values[1]),
206: (String) values[3], (PrincipalName) values[4],
207: (Ticket) values[5], (EncryptedData) values[6]);
208: }
209:
210: @Override
211: protected void getValues(Object object, Object[] values) {
212: throw new RuntimeException(); // FIXME message
213: }
214: };
215:
216: public static final ASN1Explicit AS_REP_ASN1 = new ASN1Explicit(
217: ASN1Constants.CLASS_APPLICATION, AS_REP, KDC_REP_ASN1);
218:
219: private static final ASN1SequenceOf LAST_REQ = new ASN1SequenceOf(
220: new ASN1Sequence(new ASN1Type[] {
221: // TODO should we define Int32 type?
222: new ASN1Explicit(0, ASN1Integer.getInstance()), // lr-type
223: new ASN1Explicit(1, KerberosTime.getASN1()), // lr-value
224: }));
225:
226: private static final ASN1Sequence HOST_ADDRESS = new ASN1Sequence(
227: new ASN1Type[] {
228: // TODO should we define Int32 type?
229: new ASN1Explicit(0, ASN1Integer.getInstance()), // addr-type
230: new ASN1Explicit(1, ASN1OctetString.getInstance()), // address
231: });
232:
233: private static final ASN1Sequence ENC_KDC_REP_PART = new ASN1Sequence(
234: new ASN1Type[] { new ASN1Explicit(0, EncryptionKey.ASN1), // key
235: new ASN1Explicit(1, LAST_REQ), // last-req
236: // TODO should we define UInt32 type?
237: new ASN1Explicit(2, ASN1Integer.getInstance()), // nonce
238: new ASN1Explicit(3, KerberosTime.getASN1()), // key-expiration
239: // TODO TicketFlags type?
240: new ASN1Explicit(4, ASN1BitString.getInstance()), // flags
241: new ASN1Explicit(5, KerberosTime.getASN1()), // authtime
242: new ASN1Explicit(6, KerberosTime.getASN1()), // starttime
243: new ASN1Explicit(7, KerberosTime.getASN1()), // endtime
244: new ASN1Explicit(8, KerberosTime.getASN1()), // renew-till
245: // TODO should we define Realm type?
246: new ASN1Explicit(9, ASN1StringType.GENERALSTRING), // srealm
247: new ASN1Explicit(10, PrincipalName.ASN1), // sname
248: new ASN1Explicit(11, HOST_ADDRESS), // caddr
249: }) {
250: {
251: setOptional(3); // key-expiration
252: setOptional(6); // starttime
253: setOptional(8); // renew-till
254: setOptional(11); // caddr
255: }
256: };
257:
258: //TODO: create const ENC_AS_REP_PART=25
259: private static final ASN1Explicit ENC_AS_REP_PART = new ASN1Explicit(
260: ASN1Constants.CLASS_APPLICATION, 25, ENC_KDC_REP_PART);
261:
262: }
|