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.KerberosMessageType;
027    import org.apache.directory.server.kerberos.shared.messages.ApplicationRequest;
028    import org.apache.directory.server.kerberos.shared.messages.value.ApOptions;
029    import org.apache.directory.shared.asn1.der.ASN1InputStream;
030    import org.apache.directory.shared.asn1.der.DERApplicationSpecific;
031    import org.apache.directory.shared.asn1.der.DERBitString;
032    import org.apache.directory.shared.asn1.der.DEREncodable;
033    import org.apache.directory.shared.asn1.der.DERInteger;
034    import org.apache.directory.shared.asn1.der.DERSequence;
035    import org.apache.directory.shared.asn1.der.DERTaggedObject;
036    
037    
038    /**
039     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
040     * @version $Rev: 589780 $, $Date: 2007-10-29 19:14:59 +0100 (Mon, 29 Oct 2007) $
041     */
042    public class ApplicationRequestDecoder
043    {
044        /**
045         * Decodes a byte array into an {@link ApplicationRequest}.
046         *
047         * @param encodedAuthHeader
048         * @return The {@link ApplicationRequest}.
049         * @throws IOException
050         */
051        public ApplicationRequest decode( byte[] encodedAuthHeader ) throws IOException
052        {
053            ASN1InputStream ais = new ASN1InputStream( encodedAuthHeader );
054    
055            DERApplicationSpecific app = ( DERApplicationSpecific ) ais.readObject();
056    
057            DERSequence apreq = ( DERSequence ) app.getObject();
058    
059            return decodeApplicationRequestSequence( apreq );
060        }
061    
062    
063        /*
064         AP-REQ ::=      [APPLICATION 14] SEQUENCE {
065         pvno[0]                       INTEGER,
066         msg-type[1]                   INTEGER,
067    
068         ap-options[2]                 APOptions,
069         ticket[3]                     Ticket,
070         authenticator[4]              EncryptedData
071         }
072         */
073        private ApplicationRequest decodeApplicationRequestSequence( DERSequence sequence ) throws IOException
074        {
075            ApplicationRequest authHeader = new ApplicationRequest();
076    
077            for ( Enumeration<DEREncodable> e = sequence.getObjects(); e.hasMoreElements(); )
078            {
079                DERTaggedObject object = ( ( DERTaggedObject ) e.nextElement() );
080                int tag = object.getTagNo();
081                DEREncodable derObject = object.getObject();
082    
083                switch ( tag )
084                {
085                    case 0:
086                        DERInteger tag0 = ( DERInteger ) derObject;
087                        authHeader.setProtocolVersionNumber( tag0.intValue() );
088                        break;
089                        
090                    case 1:
091                        DERInteger tag1 = ( DERInteger ) derObject;
092                        authHeader.setMessageType( KerberosMessageType.getTypeByOrdinal( tag1.intValue() ) );
093                        break;
094                        
095                    case 2:
096                        DERBitString apOptions = ( DERBitString ) derObject;
097                        authHeader.setApOptions( new ApOptions( apOptions.getOctets() ) );
098                        break;
099                    case 3:
100                        DERApplicationSpecific tag3 = ( DERApplicationSpecific ) derObject;
101                        authHeader.setTicket( TicketDecoder.decode( tag3 ) );
102                        break;
103                        
104                    case 4:
105                        DERSequence tag4 = ( DERSequence ) derObject;
106                        authHeader.setEncPart( EncryptedDataDecoder.decode( tag4 ) );
107                        break;
108                }
109            }
110    
111            return authHeader;
112        }
113    }