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.IOException;
021: import java.math.BigInteger;
022: import java.net.DatagramPacket;
023: import java.net.DatagramSocket;
024: import java.net.InetAddress;
025: import java.util.ArrayList;
026: import java.util.Date;
027:
028: import org.apache.harmony.security.asn1.ASN1Any;
029: import org.apache.harmony.security.asn1.ASN1Constants;
030: import org.apache.harmony.security.asn1.ASN1Explicit;
031: import org.apache.harmony.security.asn1.ASN1Integer;
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:
037: /**
038: * @see http://www.ietf.org/rfc/rfc3961.txt
039: * @see http://www.ietf.org/rfc/rfc4120.txt
040: */
041: public class KDCRequest {
042:
043: /**
044: * Authentication Service request message type
045: */
046: public static final int AS_REQ = 10;
047:
048: /**
049: * Ticket-Granting Service request message type
050: */
051: public static final int TGS_REQ = 12;
052:
053: // type of a protocol message: AS_REQ or TGS_REQ
054: private final int msgType;
055:
056: private final PrincipalName cname;
057:
058: private final String realm;
059:
060: private final PrincipalName sname;
061:
062: KDCRequest(int msgType, PrincipalName cname, String realm,
063: PrincipalName sname) {
064: super ();
065: this .msgType = msgType;
066: this .cname = cname;
067: this .realm = realm;
068: this .sname = sname;
069: }
070:
071: public DatagramSocket send(InetAddress address, int port)
072: throws IOException {
073:
074: if (msgType != AS_REQ) {
075: throw new RuntimeException("Not implemented");
076: }
077:
078: byte[] enc = AS_REQ_ASN1.encode(this );
079:
080: DatagramPacket req = new DatagramPacket(enc, enc.length,
081: address, port);
082: DatagramSocket socket = new DatagramSocket();
083:
084: socket.send(req);
085:
086: return socket;
087: }
088:
089: /**
090: *
091: * <pre>
092: * KDC-REQ-BODY ::= SEQUENCE {
093: * kdc-options [0] KDCOptions,
094: * cname [1] PrincipalName OPTIONAL
095: * -- Used only in AS-REQ --,
096: * realm [2] Realm
097: * -- Server's realm
098: * -- Also client's in AS-REQ --,
099: * sname [3] PrincipalName OPTIONAL,
100: * from [4] KerberosTime OPTIONAL,
101: * till [5] KerberosTime,
102: * rtime [6] KerberosTime OPTIONAL,
103: * nonce [7] UInt32,
104: * etype [8] SEQUENCE OF Int32 -- EncryptionType
105: * -- in preference order --,
106: * addresses [9] HostAddresses OPTIONAL,
107: * enc-authorization-data [10] EncryptedData OPTIONAL
108: * -- AuthorizationData --,
109: * additional-tickets [11] SEQUENCE OF Ticket OPTIONAL
110: * -- NOTE: not empty
111: * }
112: * </pre>
113: */
114: private static final ASN1Sequence KDC_REQ_BODY = new ASN1Sequence(
115: new ASN1Type[] {
116: new ASN1Explicit(0, ASN1Any.getInstance()), // TODO: ignored
117: new ASN1Explicit(1, PrincipalName.ASN1),
118: // TODO should we define Realm type?
119: new ASN1Explicit(2, ASN1StringType.GENERALSTRING),
120: new ASN1Explicit(3, PrincipalName.ASN1),
121: new ASN1Explicit(4, ASN1Any.getInstance()), //TODO: ignored
122: new ASN1Explicit(5, KerberosTime.getASN1()),
123: new ASN1Explicit(6, ASN1Any.getInstance()), //TODO: ignored
124: new ASN1Explicit(7, ASN1Integer.getInstance()),
125: new ASN1Explicit(8, new ASN1SequenceOf(ASN1Integer
126: .getInstance())),
127: new ASN1Explicit(9, ASN1Any.getInstance()), //TODO: ignored
128: new ASN1Explicit(10, ASN1Any.getInstance()), //TODO: ignored
129: new ASN1Explicit(11, ASN1Any.getInstance()), //TODO: ignored
130:
131: }) {
132: {
133: setOptional(1); // cname
134: setOptional(3); // sname
135: setOptional(4); // from
136: setOptional(6); // rtime
137: setOptional(9); // addresses
138: setOptional(10); // enc-authorization-data
139: setOptional(11); // additional-tickets
140: }
141:
142: @Override
143: protected void getValues(Object object, Object[] values) {
144: KDCRequest request = (KDCRequest) object;
145:
146: // FIXME: hardcoded - no KDCOptions are set
147: // note: number of bits should be >= 32
148: // (see RFC 4120, 5.2.8. KerberosFlags)
149: values[0] = new byte[] { (byte) 0x03, (byte) 0x05,
150: (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
151: (byte) 0x00, };
152:
153: values[1] = request.cname;
154: values[2] = request.realm;
155: values[3] = request.sname;
156:
157: // value[4] = from; //TODO
158:
159: // till: requested: "19700101000000Z" FIXME
160: values[5] = new Date(0);
161:
162: // values[6] = rtime //TODO
163:
164: // nonce FIXME: hardcoded
165: values[7] = BigInteger.valueOf(0).toByteArray();
166:
167: // etype FIXME
168: ArrayList<byte[]> list = new ArrayList<byte[]>();
169:
170: // see RFC 3961 (Section 8)
171: list.add(BigInteger.valueOf(1).toByteArray());// des-cbc-crc
172: list.add(BigInteger.valueOf(2).toByteArray());// des-cbc-md4
173: list.add(BigInteger.valueOf(3).toByteArray());// des-cbc-md5
174: values[8] = list;
175:
176: // value[9] = FIXME
177: // value[10] = FIXME
178: // value[11] = FIXME
179: }
180: };
181:
182: /**
183: * <pre>
184: * KDC-REQ ::= SEQUENCE {
185: * -- NOTE: first tag is [1], not [0]
186: * pvno [1] INTEGER (5) ,
187: * msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --),
188: * padata [3] SEQUENCE OF PA-DATA OPTIONAL
189: * -- NOTE: not empty --,
190: * req-body [4] KDC-REQ-BODY
191: * }
192: * </pre>
193: */
194: static final ASN1Sequence KDC_REQ_ASN1 = new ASN1Sequence(
195: new ASN1Type[] {
196: // pvno [1] INTEGER (5)
197: new ASN1Explicit(1, ASN1Integer.getInstance()),
198: // msg-type [2] INTEGER
199: new ASN1Explicit(2, ASN1Integer.getInstance()),
200: // padata [3] SEQUENCE OF PA-DATA OPTIONAL
201: new ASN1Explicit(3, new ASN1SequenceOf(ASN1Any
202: .getInstance())),
203: // req-body [4] KDC-REQ-BODY
204: new ASN1Explicit(4, KDC_REQ_BODY), }) {
205: {
206: setOptional(2); // padata
207: }
208:
209: @Override
210: protected void getValues(Object object, Object[] values) {
211: KDCRequest request = (KDCRequest) object;
212:
213: values[0] = BigInteger.valueOf(5).toByteArray();
214: values[1] = BigInteger.valueOf(request.msgType)
215: .toByteArray();
216: // values[2] = //FIXME
217: values[3] = request; // pass for further use
218: }
219: };
220:
221: static final ASN1Explicit AS_REQ_ASN1 = new ASN1Explicit(
222: ASN1Constants.CLASS_APPLICATION, AS_REQ, KDC_REQ_ASN1);
223: }
|