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 */ 020package org.apache.directory.api.ldap.extras.extended.ads_impl.certGeneration; 021 022 023import org.apache.directory.api.asn1.DecoderException; 024import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; 025import org.apache.directory.api.asn1.ber.grammar.Grammar; 026import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 027import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 028import org.apache.directory.api.asn1.ber.tlv.BerValue; 029import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 030import org.apache.directory.api.i18n.I18n; 031import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory; 032import org.apache.directory.api.ldap.extras.extended.certGeneration.CertGenerationRequestImpl; 033import org.apache.directory.api.ldap.model.name.Dn; 034import org.apache.directory.api.util.Strings; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038 039/** 040 * This class implements the Certificate generation extended operation's ASN.1 grammer. 041 * All the actions are declared in this class. As it is a singleton, 042 * these declaration are only done once. The grammar is : 043 * 044 * <pre> 045 * CertGenerateObject ::= SEQUENCE 046 * { 047 * targetDN IA5String, 048 * issuerDN IA5String, 049 * subjectDN IA5String, 050 * keyAlgorithm IA5String 051 * } 052 * </pre> 053 * 054 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 055 */ 056 057public class CertGenerationGrammar extends AbstractGrammar<CertGenerationContainer> 058{ 059 060 /** logger */ 061 private static final Logger LOG = LoggerFactory.getLogger( CertGenerationGrammar.class ); 062 063 /** Speedup for logs */ 064 static final boolean IS_DEBUG = LOG.isDebugEnabled(); 065 066 /** The instance of grammar. CertGenerationObjectGrammar is a singleton */ 067 private static Grammar<CertGenerationContainer> instance = new CertGenerationGrammar(); 068 069 070 /** 071 * Creates a new CertGenerationGrammar object. 072 */ 073 @SuppressWarnings("unchecked") 074 public CertGenerationGrammar() 075 { 076 setName( CertGenerationGrammar.class.getName() ); 077 078 // Create the transitions table 079 super.transitions = new GrammarTransition[CertGenerationStatesEnum.LAST_CERT_GENERATION_STATE.ordinal()][256]; 080 081 /** 082 * Transition from init state to certificate generation 083 * 084 * CertGenerationObject ::= SEQUENCE { 085 * ... 086 * 087 * Creates the CertGenerationObject object 088 */ 089 super.transitions[CertGenerationStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 090 new GrammarTransition<CertGenerationContainer>( 091 CertGenerationStatesEnum.START_STATE, CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE, 092 UniversalTag.SEQUENCE.getValue(), new GrammarAction<CertGenerationContainer>( 093 "Init CertGenerationObject" ) 094 { 095 public void action( CertGenerationContainer container ) 096 { 097 CertGenerationRequestDecorator certGenerationRequest = new CertGenerationRequestDecorator( 098 LdapApiServiceFactory.getSingleton(), new CertGenerationRequestImpl() ); 099 container.setCertGenerationRequest( certGenerationRequest ); 100 } 101 } ); 102 103 /** 104 * Transition from certificate generation request to targetDN 105 * 106 * CertGenerationObject ::= SEQUENCE { 107 * targetDN IA5String, 108 * ... 109 * 110 * Set the targetDN value into the CertGenerationObject instance. 111 */ 112 super.transitions[CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE.ordinal()][UniversalTag.OCTET_STRING 113 .getValue()] = 114 new GrammarTransition<CertGenerationContainer>( 115 CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE, 116 CertGenerationStatesEnum.TARGETDN_STATE, UniversalTag.OCTET_STRING.getValue(), 117 new GrammarAction<CertGenerationContainer>( "Set Cert Generation target Dn value" ) 118 { 119 public void action( CertGenerationContainer container ) throws DecoderException 120 { 121 BerValue value = container.getCurrentTLV().getValue(); 122 123 String targetDN = Strings.utf8ToString( value.getData() ); 124 125 if ( IS_DEBUG ) 126 { 127 LOG.debug( "Target Dn = " + targetDN ); 128 } 129 130 if ( ( targetDN != null ) && ( targetDN.trim().length() > 0 ) ) 131 { 132 if ( !Dn.isValid( targetDN ) ) 133 { 134 String msg = I18n.err( I18n.ERR_04032, targetDN ); 135 LOG.error( msg ); 136 throw new DecoderException( msg ); 137 } 138 139 container.getCertGenerationRequest().setTargetDN( targetDN ); 140 } 141 else 142 { 143 String msg = I18n.err( I18n.ERR_04033, Strings.dumpBytes( value.getData() ) ); 144 LOG.error( msg ); 145 throw new DecoderException( msg ); 146 } 147 } 148 } ); 149 150 /** 151 * Transition from targetDN state to issuerDN 152 * 153 * CertGenerationObject ::= SEQUENCE { 154 * ... 155 * issuerDN IA5String, 156 * ... 157 * 158 * Set the issuerDN value into the CertGenerationObject instance. 159 */ 160 super.transitions[CertGenerationStatesEnum.TARGETDN_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 161 new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.TARGETDN_STATE, 162 CertGenerationStatesEnum.ISSUER_STATE, UniversalTag.OCTET_STRING.getValue(), 163 new GrammarAction<CertGenerationContainer>( "Set Cert Generation issuer Dn value" ) 164 { 165 public void action( CertGenerationContainer container ) throws DecoderException 166 { 167 BerValue value = container.getCurrentTLV().getValue(); 168 169 String issuerDN = Strings.utf8ToString( value.getData() ); 170 171 if ( IS_DEBUG ) 172 { 173 LOG.debug( "Issuer Dn = " + issuerDN ); 174 } 175 176 if ( ( issuerDN != null ) && ( issuerDN.trim().length() > 0 ) ) 177 { 178 if ( !Dn.isValid( issuerDN ) ) 179 { 180 String msg = I18n.err( I18n.ERR_04034, issuerDN ); 181 LOG.error( msg ); 182 throw new DecoderException( msg ); 183 } 184 185 container.getCertGenerationRequest().setIssuerDN( issuerDN ); 186 } 187 } 188 } ); 189 190 /** 191 * Transition from issuerDN state to subjectDN 192 * 193 * CertGenerationObject ::= SEQUENCE { 194 * ... 195 * subjectDN IA5String, 196 * ... 197 * 198 * Set the subjectDN value into the CertGenerationObject instance. 199 */ 200 super.transitions[CertGenerationStatesEnum.ISSUER_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 201 new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.ISSUER_STATE, 202 CertGenerationStatesEnum.SUBJECT_STATE, UniversalTag.OCTET_STRING.getValue(), 203 new GrammarAction<CertGenerationContainer>( "Set Cert Generation subject Dn value" ) 204 { 205 public void action( CertGenerationContainer container ) throws DecoderException 206 { 207 BerValue value = container.getCurrentTLV().getValue(); 208 209 String subjectDN = Strings.utf8ToString( value.getData() ); 210 211 if ( IS_DEBUG ) 212 { 213 LOG.debug( "subject Dn = " + subjectDN ); 214 } 215 216 if ( ( subjectDN != null ) && ( subjectDN.trim().length() > 0 ) ) 217 { 218 if ( !Dn.isValid( subjectDN ) ) 219 { 220 String msg = I18n.err( I18n.ERR_04035, subjectDN ); 221 LOG.error( msg ); 222 throw new DecoderException( msg ); 223 } 224 225 container.getCertGenerationRequest().setSubjectDN( subjectDN ); 226 } 227 else 228 { 229 String msg = I18n.err( I18n.ERR_04033, Strings.dumpBytes( value.getData() ) ); 230 LOG.error( msg ); 231 throw new DecoderException( msg ); 232 } 233 } 234 } ); 235 236 /** 237 * Transition from subjectDN state to keyAlgo 238 * 239 * CertGenerationObject ::= SEQUENCE { 240 * ... 241 * keyAlgorithm IA5String 242 * 243 * Set the key algorithm value into the CertGenerationObject instance. 244 */ 245 super.transitions[CertGenerationStatesEnum.SUBJECT_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 246 new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.SUBJECT_STATE, 247 CertGenerationStatesEnum.KEY_ALGORITHM_STATE, 248 UniversalTag.OCTET_STRING.getValue(), 249 new GrammarAction<CertGenerationContainer>( "Set Cert Generation key algorithm value" ) 250 { 251 public void action( CertGenerationContainer container ) throws DecoderException 252 { 253 BerValue value = container.getCurrentTLV().getValue(); 254 255 String keyAlgorithm = Strings.utf8ToString( value.getData() ); 256 257 if ( IS_DEBUG ) 258 { 259 LOG.debug( "key algorithm = " + keyAlgorithm ); 260 } 261 262 if ( keyAlgorithm != null && ( keyAlgorithm.trim().length() > 0 ) ) 263 { 264 container.getCertGenerationRequest().setKeyAlgorithm( keyAlgorithm ); 265 } 266 267 container.setGrammarEndAllowed( true ); 268 } 269 } ); 270 271 } 272 273 274 /** 275 * This class is a singleton. 276 * 277 * @return An instance on this grammar 278 */ 279 public static Grammar<CertGenerationContainer> getInstance() 280 { 281 return instance; 282 } 283}