View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.api.ldap.extras.extended.ads_impl.certGeneration;
21  
22  
23  import org.apache.directory.api.asn1.DecoderException;
24  import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
25  import org.apache.directory.api.asn1.ber.grammar.Grammar;
26  import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
27  import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
28  import org.apache.directory.api.asn1.ber.tlv.BerValue;
29  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
30  import org.apache.directory.api.i18n.I18n;
31  import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
32  import org.apache.directory.api.ldap.extras.extended.certGeneration.CertGenerationRequestImpl;
33  import org.apache.directory.api.ldap.model.name.Dn;
34  import org.apache.directory.api.util.Strings;
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  
38  
39  /**
40   * This class implements the Certificate generation extended operation's ASN.1 grammer. 
41   * All the actions are declared in this class. As it is a singleton, 
42   * these declaration are only done once. The grammar is :
43   * 
44   * <pre>
45   *   CertGenerateObject ::= SEQUENCE 
46   *   {
47   *      targetDN        IA5String,
48   *      issuerDN        IA5String,
49   *      subjectDN       IA5String,
50   *      keyAlgorithm    IA5String
51   *   }
52   * </pre>
53   * 
54   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
55   */
56  
57  public class CertGenerationGrammar extends AbstractGrammar<CertGenerationContainer>
58  {
59  
60      /** logger */
61      private static final Logger LOG = LoggerFactory.getLogger( CertGenerationGrammar.class );
62  
63      /** Speedup for logs */
64      static final boolean IS_DEBUG = LOG.isDebugEnabled();
65  
66      /** The instance of grammar. CertGenerationObjectGrammar is a singleton */
67      private static Grammar<CertGenerationContainer> instance = new CertGenerationGrammar();
68  
69  
70      @SuppressWarnings("unchecked")
71      public CertGenerationGrammar()
72      {
73          setName( CertGenerationGrammar.class.getName() );
74  
75          // Create the transitions table
76          super.transitions = new GrammarTransition[CertGenerationStatesEnum.LAST_CERT_GENERATION_STATE.ordinal()][256];
77  
78          /**
79           * Transition from init state to certificate generation
80           * 
81           * CertGenerationObject ::= SEQUENCE {
82           *     ...
83           *     
84           * Creates the CertGenerationObject object
85           */
86          super.transitions[CertGenerationStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
87              new GrammarTransition<CertGenerationContainer>(
88                  CertGenerationStatesEnum.START_STATE, CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE,
89                  UniversalTag.SEQUENCE.getValue(), new GrammarAction<CertGenerationContainer>(
90                      "Init CertGenerationObject" )
91                  {
92                      public void action( CertGenerationContainer container )
93                      {
94                          CertGenerationRequestDecorator certGenerationRequest = new CertGenerationRequestDecorator(
95                              LdapApiServiceFactory.getSingleton(), new CertGenerationRequestImpl() );
96                          container.setCertGenerationRequest( certGenerationRequest );
97                      }
98                  } );
99  
100         /**
101          * Transition from certificate generation request to targetDN
102          *
103          * CertGenerationObject ::= SEQUENCE { 
104          *     targetDN IA5String,
105          *     ...
106          *     
107          * Set the targetDN value into the CertGenerationObject instance.
108          */
109         super.transitions[CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE.ordinal()][UniversalTag.OCTET_STRING
110             .getValue()] =
111             new GrammarTransition<CertGenerationContainer>(
112                 CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE,
113                 CertGenerationStatesEnum.TARGETDN_STATE, UniversalTag.OCTET_STRING.getValue(),
114                 new GrammarAction<CertGenerationContainer>( "Set Cert Generation target Dn value" )
115                 {
116                     public void action( CertGenerationContainer container ) throws DecoderException
117                     {
118                         BerValue value = container.getCurrentTLV().getValue();
119 
120                         String targetDN = Strings.utf8ToString( value.getData() );
121 
122                         if ( IS_DEBUG )
123                         {
124                             LOG.debug( "Target Dn = " + targetDN );
125                         }
126 
127                         if ( ( targetDN != null ) && ( targetDN.trim().length() > 0 ) )
128                         {
129                             if ( !Dn.isValid( targetDN ) )
130                             {
131                                 String msg = I18n.err( I18n.ERR_04032, targetDN );
132                                 LOG.error( msg );
133                                 throw new DecoderException( msg );
134                             }
135 
136                             container.getCertGenerationRequest().setTargetDN( targetDN );
137                         }
138                         else
139                         {
140                             String msg = I18n.err( I18n.ERR_04033, Strings.dumpBytes( value.getData() ) );
141                             LOG.error( msg );
142                             throw new DecoderException( msg );
143                         }
144                     }
145                 } );
146 
147         /**
148          * Transition from targetDN state to issuerDN
149          *
150          * CertGenerationObject ::= SEQUENCE { 
151          *     ...
152          *     issuerDN IA5String,
153          *     ...
154          *     
155          * Set the issuerDN value into the CertGenerationObject instance.
156          */
157         super.transitions[CertGenerationStatesEnum.TARGETDN_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] =
158             new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.TARGETDN_STATE,
159                 CertGenerationStatesEnum.ISSUER_STATE, UniversalTag.OCTET_STRING.getValue(),
160                 new GrammarAction<CertGenerationContainer>( "Set Cert Generation issuer Dn value" )
161                 {
162                     public void action( CertGenerationContainer container ) throws DecoderException
163                     {
164                         BerValue value = container.getCurrentTLV().getValue();
165 
166                         String issuerDN = Strings.utf8ToString( value.getData() );
167 
168                         if ( IS_DEBUG )
169                         {
170                             LOG.debug( "Issuer Dn = " + issuerDN );
171                         }
172 
173                         if ( ( issuerDN != null ) && ( issuerDN.trim().length() > 0 ) )
174                         {
175                             if ( !Dn.isValid( issuerDN ) )
176                             {
177                                 String msg = I18n.err( I18n.ERR_04034, issuerDN );
178                                 LOG.error( msg );
179                                 throw new DecoderException( msg );
180                             }
181 
182                             container.getCertGenerationRequest().setIssuerDN( issuerDN );
183                         }
184                     }
185                 } );
186 
187         /**
188          * Transition from issuerDN state to subjectDN
189          *
190          * CertGenerationObject ::= SEQUENCE {
191          *     ... 
192          *     subjectDN IA5String,
193          *     ...
194          *     
195          * Set the subjectDN value into the CertGenerationObject instance.
196          */
197         super.transitions[CertGenerationStatesEnum.ISSUER_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] =
198             new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.ISSUER_STATE,
199                 CertGenerationStatesEnum.SUBJECT_STATE, UniversalTag.OCTET_STRING.getValue(),
200                 new GrammarAction<CertGenerationContainer>( "Set Cert Generation subject Dn value" )
201                 {
202                     public void action( CertGenerationContainer container ) throws DecoderException
203                     {
204                         BerValue value = container.getCurrentTLV().getValue();
205 
206                         String subjectDN = Strings.utf8ToString( value.getData() );
207 
208                         if ( IS_DEBUG )
209                         {
210                             LOG.debug( "subject Dn = " + subjectDN );
211                         }
212 
213                         if ( ( subjectDN != null ) && ( subjectDN.trim().length() > 0 ) )
214                         {
215                             if ( !Dn.isValid( subjectDN ) )
216                             {
217                                 String msg = I18n.err( I18n.ERR_04035, subjectDN );
218                                 LOG.error( msg );
219                                 throw new DecoderException( msg );
220                             }
221 
222                             container.getCertGenerationRequest().setSubjectDN( subjectDN );
223                         }
224                         else
225                         {
226                             String msg = I18n.err( I18n.ERR_04033, Strings.dumpBytes( value.getData() ) );
227                             LOG.error( msg );
228                             throw new DecoderException( msg );
229                         }
230                     }
231                 } );
232 
233         /**
234          * Transition from subjectDN state to keyAlgo
235          *
236          * CertGenerationObject ::= SEQUENCE { 
237          *     ...
238          *     keyAlgorithm IA5String
239          *     
240          * Set the key algorithm value into the CertGenerationObject instance.
241          */
242         super.transitions[CertGenerationStatesEnum.SUBJECT_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] =
243             new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.SUBJECT_STATE,
244                 CertGenerationStatesEnum.KEY_ALGORITHM_STATE,
245                 UniversalTag.OCTET_STRING.getValue(),
246                 new GrammarAction<CertGenerationContainer>( "Set Cert Generation key algorithm value" )
247                 {
248                     public void action( CertGenerationContainer container ) throws DecoderException
249                     {
250                         BerValue value = container.getCurrentTLV().getValue();
251 
252                         String keyAlgorithm = Strings.utf8ToString( value.getData() );
253 
254                         if ( IS_DEBUG )
255                         {
256                             LOG.debug( "key algorithm = " + keyAlgorithm );
257                         }
258 
259                         if ( keyAlgorithm != null && ( keyAlgorithm.trim().length() > 0 ) )
260                         {
261                             container.getCertGenerationRequest().setKeyAlgorithm( keyAlgorithm );
262                         }
263 
264                         container.setGrammarEndAllowed( true );
265                     }
266                 } );
267 
268     }
269 
270 
271     /**
272      * This class is a singleton.
273      * 
274      * @return An instance on this grammar
275      */
276     public static Grammar<CertGenerationContainer> getInstance()
277     {
278         return instance;
279     }
280 }