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.encoder;
021
022
023 import java.io.ByteArrayOutputStream;
024 import java.io.IOException;
025
026 import org.apache.directory.server.kerberos.shared.messages.Encodable;
027 import org.apache.directory.server.kerberos.shared.messages.components.Authenticator;
028 import org.apache.directory.shared.asn1.der.ASN1OutputStream;
029 import org.apache.directory.shared.asn1.der.DERApplicationSpecific;
030 import org.apache.directory.shared.asn1.der.DERGeneralString;
031 import org.apache.directory.shared.asn1.der.DERInteger;
032 import org.apache.directory.shared.asn1.der.DERSequence;
033 import org.apache.directory.shared.asn1.der.DERTaggedObject;
034
035
036 /**
037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
038 * @version $Rev$, $Date$
039 */
040 public class AuthenticatorEncoder implements Encoder, EncoderFactory
041 {
042 /**
043 * Application code constant for the {@link Authenticator} (2).
044 */
045 private static final int APPLICATION_CODE = 2;
046
047
048 /**
049 * Encodes an {@link Authenticator} into a byte array.
050 *
051 * @param authenticator
052 * @return The byte array.
053 * @throws IOException
054 */
055 public byte[] encode( Encodable authenticator ) throws IOException
056 {
057 ByteArrayOutputStream baos = new ByteArrayOutputStream();
058 ASN1OutputStream aos = new ASN1OutputStream( baos );
059
060 DERSequence replySequence = encodeInitialSequence( ( Authenticator ) authenticator );
061 aos.writeObject( DERApplicationSpecific.valueOf( APPLICATION_CODE, replySequence ) );
062 aos.close();
063
064 return baos.toByteArray();
065 }
066
067
068 public Encoder getEncoder()
069 {
070 return new AuthenticatorEncoder();
071 }
072
073
074 /**
075 * Encodes an {@link Authenticator} into a {@link DERSequence}.
076 *
077 * -- Unencrypted authenticator
078 * Authenticator ::= [APPLICATION 2] SEQUENCE
079 * {
080 * authenticator-vno[0] INTEGER,
081 * crealm[1] Realm,
082 * cname[2] PrincipalName,
083 * cksum[3] Checksum OPTIONAL,
084 * cusec[4] INTEGER,
085 * ctime[5] KerberosTime,
086 * subkey[6] EncryptionKey OPTIONAL,
087 * seq-number[7] INTEGER OPTIONAL,
088 *
089 * authorization-data[8] AuthorizationData OPTIONAL
090 * }
091 *
092 * @param authenticator
093 * @return The {@link DERSequence}.
094 */
095 private DERSequence encodeInitialSequence( Authenticator authenticator )
096 {
097 String clientRealm = authenticator.getClientPrincipal().getRealm();
098
099 DERSequence sequence = new DERSequence();
100
101 sequence.add( new DERTaggedObject( 0, DERInteger.valueOf( authenticator.getVersionNumber() ) ) );
102 sequence.add( new DERTaggedObject( 1, DERGeneralString.valueOf( clientRealm ) ) );
103 sequence.add( new DERTaggedObject( 2, PrincipalNameEncoder.encode( authenticator.getClientPrincipal() ) ) );
104
105 // OPTIONAL
106 if ( authenticator.getChecksum() != null )
107 {
108 sequence.add( new DERTaggedObject( 3, ChecksumEncoder.encode( authenticator.getChecksum() ) ) );
109 }
110
111 sequence.add( new DERTaggedObject( 4, DERInteger.valueOf( authenticator.getClientMicroSecond() ) ) );
112 sequence.add( new DERTaggedObject( 5, KerberosTimeEncoder.encode( authenticator.getClientTime() ) ) );
113
114 // OPTIONAL
115 if ( authenticator.getSubSessionKey() != null )
116 {
117 sequence.add( new DERTaggedObject( 6, EncryptionKeyEncoder
118 .encodeSequence( authenticator.getSubSessionKey() ) ) );
119 }
120
121 // OPTIONAL
122 if ( authenticator.getSequenceNumber() > 0 )
123 {
124 sequence.add( new DERTaggedObject( 7, DERInteger.valueOf( authenticator.getSequenceNumber() ) ) );
125 }
126
127 // OPTIONAL
128 if ( authenticator.getAuthorizationData() != null )
129 {
130 sequence.add( new DERTaggedObject( 8, AuthorizationDataEncoder
131 .encode( authenticator.getAuthorizationData() ) ) );
132 }
133
134 return sequence;
135 }
136 }