001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.server.kerberos.shared.io.decoder;
021
022
023 import java.io.IOException;
024 import java.util.Enumeration;
025
026 import org.apache.directory.server.kerberos.shared.messages.Encodable;
027 import org.apache.directory.server.kerberos.shared.messages.components.EncTicketPart;
028 import org.apache.directory.server.kerberos.shared.messages.components.EncTicketPartModifier;
029 import org.apache.directory.server.kerberos.shared.messages.value.TransitedEncoding;
030 import org.apache.directory.server.kerberos.shared.messages.value.flags.TicketFlags;
031 import org.apache.directory.server.kerberos.shared.messages.value.types.TransitedEncodingType;
032 import org.apache.directory.shared.asn1.der.ASN1InputStream;
033 import org.apache.directory.shared.asn1.der.DERApplicationSpecific;
034 import org.apache.directory.shared.asn1.der.DERBitString;
035 import org.apache.directory.shared.asn1.der.DEREncodable;
036 import org.apache.directory.shared.asn1.der.DERGeneralString;
037 import org.apache.directory.shared.asn1.der.DERGeneralizedTime;
038 import org.apache.directory.shared.asn1.der.DERInteger;
039 import org.apache.directory.shared.asn1.der.DEROctetString;
040 import org.apache.directory.shared.asn1.der.DERSequence;
041 import org.apache.directory.shared.asn1.der.DERTaggedObject;
042
043
044 /**
045 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
046 * @version $Rev: 591019 $, $Date: 2007-11-01 16:16:34 +0200 (Thu, 01 Nov 2007) $
047 */
048 public class EncTicketPartDecoder implements Decoder, DecoderFactory
049 {
050 public Decoder getDecoder()
051 {
052 return new EncTicketPartDecoder();
053 }
054
055
056 public Encodable decode( byte[] encodedTicket ) throws IOException
057 {
058 ASN1InputStream ais = new ASN1InputStream( encodedTicket );
059
060 DERApplicationSpecific app = ( DERApplicationSpecific ) ais.readObject();
061
062 DERSequence sequence = ( DERSequence ) app.getObject();
063
064 return decodeEncTicketPartSequence( sequence );
065 }
066
067
068 /*
069 -- Encrypted part of ticket
070 EncTicketPart ::= [APPLICATION 3] SEQUENCE {
071 flags[0] TicketFlags,
072 key[1] EncryptionKey,
073 crealm[2] Realm,
074 cname[3] PrincipalName,
075 transited[4] TransitedEncoding,
076 authtime[5] KerberosTime,
077 starttime[6] KerberosTime OPTIONAL,
078 endtime[7] KerberosTime,
079 renew-till[8] KerberosTime OPTIONAL,
080 caddr[9] HostAddresses OPTIONAL,
081 authorization-data[10] AuthorizationData OPTIONAL
082 }*/
083 private EncTicketPart decodeEncTicketPartSequence( DERSequence sequence )
084 {
085 EncTicketPartModifier modifier = new EncTicketPartModifier();
086
087 for ( Enumeration<DEREncodable> e = sequence.getObjects(); e.hasMoreElements(); )
088 {
089 DERTaggedObject object = ( DERTaggedObject ) e.nextElement();
090 int tag = object.getTagNo();
091 DEREncodable derObject = object.getObject();
092
093 switch ( tag )
094 {
095 case 0:
096 DERBitString tag0 = ( DERBitString ) derObject;
097 modifier.setFlags( new TicketFlags( tag0.getOctets() ) );
098 break;
099
100 case 1:
101 DERSequence tag1 = ( DERSequence ) derObject;
102 modifier.setSessionKey( EncryptionKeyDecoder.decode( tag1 ) );
103 break;
104
105 case 2:
106 DERGeneralString tag2 = ( DERGeneralString ) derObject;
107 modifier.setClientRealm( tag2.getString() );
108 break;
109
110 case 3:
111 DERSequence tag3 = ( DERSequence ) derObject;
112 modifier.setClientName( PrincipalNameDecoder.decode( tag3 ) );
113 break;
114
115 case 4:
116 DERSequence tag4 = ( DERSequence ) derObject;
117 modifier.setTransitedEncoding( decodeTransitedEncoding( tag4 ) );
118 break;
119
120 case 5:
121 DERGeneralizedTime tag5 = ( DERGeneralizedTime ) derObject;
122 modifier.setAuthTime( KerberosTimeDecoder.decode( tag5 ) );
123 break;
124
125 case 6:
126 DERGeneralizedTime tag6 = ( DERGeneralizedTime ) derObject;
127 modifier.setStartTime( KerberosTimeDecoder.decode( tag6 ) );
128 break;
129
130 case 7:
131 DERGeneralizedTime tag7 = ( DERGeneralizedTime ) derObject;
132 modifier.setEndTime( KerberosTimeDecoder.decode( tag7 ) );
133 break;
134
135 case 8:
136 DERGeneralizedTime tag8 = ( DERGeneralizedTime ) derObject;
137 modifier.setRenewTill( KerberosTimeDecoder.decode( tag8 ) );
138 break;
139
140 case 9:
141 DERSequence tag9 = ( DERSequence ) derObject;
142 modifier.setClientAddresses( HostAddressDecoder.decodeSequence( tag9 ) );
143 break;
144
145 case 10:
146 DERSequence tag10 = ( DERSequence ) derObject;
147 modifier.setAuthorizationData( AuthorizationDataDecoder.decodeSequence( tag10 ) );
148 break;
149 }
150 }
151 return modifier.getEncTicketPart();
152 }
153
154
155 /*
156 * TransitedEncoding ::= SEQUENCE {
157 * tr-type[0] INTEGER, -- must be
158 * registered contents[1] OCTET STRING
159 * }
160 */
161 protected TransitedEncoding decodeTransitedEncoding( DERSequence sequence )
162 {
163 TransitedEncodingType type = TransitedEncodingType.NULL;
164 byte[] contents = null;
165
166 for ( Enumeration<DEREncodable> e = sequence.getObjects(); e.hasMoreElements(); )
167 {
168 DERTaggedObject object = ( DERTaggedObject ) e.nextElement();
169 int tag = object.getTagNo();
170 DEREncodable derObject = object.getObject();
171
172 switch ( tag )
173 {
174 case 0:
175 DERInteger tag0 = ( DERInteger ) derObject;
176 type = TransitedEncodingType.getTypeByOrdinal( tag0.intValue() );
177 break;
178
179 case 1:
180 DEROctetString tag1 = ( DEROctetString ) derObject;
181 contents = tag1.getOctets();
182 break;
183 }
184 }
185
186 return new TransitedEncoding( type, contents );
187 }
188 }