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.shared.ldap.extras.extended.ads_impl.certGeneration; 021 022 023import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar; 024import org.apache.directory.shared.asn1.ber.grammar.Grammar; 025import org.apache.directory.shared.asn1.ber.grammar.GrammarAction; 026import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition; 027import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; 028import org.apache.directory.shared.asn1.ber.tlv.Value; 029import org.apache.directory.shared.asn1.DecoderException; 030import org.apache.directory.shared.i18n.I18n; 031import org.apache.directory.shared.ldap.codec.api.LdapApiServiceFactory; 032import org.apache.directory.shared.ldap.extras.extended.CertGenerationRequestImpl; 033import org.apache.directory.shared.ldap.model.name.Dn; 034import org.apache.directory.shared.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 @SuppressWarnings("unchecked") 071 public CertGenerationGrammar() 072 { 073 setName( CertGenerationGrammar.class.getName() ); 074 075 // Create the transitions table 076 super.transitions = new GrammarTransition[CertGenerationStatesEnum.LAST_CERT_GENERATION_STATE.ordinal()][256]; 077 078 /** 079 * Transition from init state to certificate generation 080 * 081 * CertGenerationObject ::= SEQUENCE { 082 * ... 083 * 084 * Creates the CertGenerationObject object 085 */ 086 super.transitions[CertGenerationStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 087 new GrammarTransition<CertGenerationContainer>( 088 CertGenerationStatesEnum.START_STATE, CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE, 089 UniversalTag.SEQUENCE.getValue(), new GrammarAction<CertGenerationContainer>( "Init CertGenerationObject" ) 090 { 091 public void action( CertGenerationContainer container ) 092 { 093 CertGenerationRequestDecorator certGenerationObject = new CertGenerationRequestDecorator( 094 LdapApiServiceFactory.getSingleton(), new CertGenerationRequestImpl() ); 095 container.setCertGenerationObject( certGenerationObject ); 096 } 097 } ); 098 099 /** 100 * Transition from certificate generation request to targetDN 101 * 102 * CertGenerationObject ::= SEQUENCE { 103 * targetDN IA5String, 104 * ... 105 * 106 * Set the targetDN value into the CertGenerationObject instance. 107 */ 108 super.transitions[CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 109 new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE, 110 CertGenerationStatesEnum.TARGETDN_STATE, UniversalTag.OCTET_STRING.getValue(), 111 new GrammarAction<CertGenerationContainer>( "Set Cert Generation target Dn value" ) 112 { 113 public void action( CertGenerationContainer container ) throws DecoderException 114 { 115 Value value = container.getCurrentTLV().getValue(); 116 117 String targetDN = Strings.utf8ToString(value.getData()); 118 119 if ( IS_DEBUG ) 120 { 121 LOG.debug( "Target Dn = " + targetDN ); 122 } 123 124 if ( ( targetDN != null ) && ( targetDN.trim().length() > 0 ) ) 125 { 126 if( !Dn.isValid(targetDN) ) 127 { 128 String msg = I18n.err( I18n.ERR_04032, targetDN ); 129 LOG.error( msg ); 130 throw new DecoderException( msg ); 131 } 132 133 container.getCertGenerationObject().setTargetDN( targetDN ); 134 } 135 else 136 { 137 String msg = I18n.err( I18n.ERR_04033, Strings.dumpBytes(value.getData()) ); 138 LOG.error( msg ); 139 throw new DecoderException( msg ); 140 } 141 } 142 } ); 143 144 /** 145 * Transition from targetDN state to issuerDN 146 * 147 * CertGenerationObject ::= SEQUENCE { 148 * ... 149 * issuerDN IA5String, 150 * ... 151 * 152 * Set the issuerDN value into the CertGenerationObject instance. 153 */ 154 super.transitions[CertGenerationStatesEnum.TARGETDN_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 155 new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.TARGETDN_STATE, 156 CertGenerationStatesEnum.ISSUER_STATE, UniversalTag.OCTET_STRING.getValue(), 157 new GrammarAction<CertGenerationContainer>( "Set Cert Generation issuer Dn value" ) 158 { 159 public void action( CertGenerationContainer container ) throws DecoderException 160 { 161 Value value = container.getCurrentTLV().getValue(); 162 163 String issuerDN = Strings.utf8ToString(value.getData()); 164 165 if ( IS_DEBUG ) 166 { 167 LOG.debug( "Issuer Dn = " + issuerDN ); 168 } 169 170 if ( ( issuerDN != null ) && ( issuerDN.trim().length() > 0 ) ) 171 { 172 if( !Dn.isValid(issuerDN) ) 173 { 174 String msg = I18n.err( I18n.ERR_04034, issuerDN ); 175 LOG.error( msg ); 176 throw new DecoderException( msg ); 177 } 178 179 container.getCertGenerationObject().setIssuerDN( issuerDN ); 180 } 181 } 182 } ); 183 184 /** 185 * Transition from issuerDN state to subjectDN 186 * 187 * CertGenerationObject ::= SEQUENCE { 188 * ... 189 * subjectDN IA5String, 190 * ... 191 * 192 * Set the subjectDN value into the CertGenerationObject instance. 193 */ 194 super.transitions[CertGenerationStatesEnum.ISSUER_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 195 new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.ISSUER_STATE, 196 CertGenerationStatesEnum.SUBJECT_STATE, UniversalTag.OCTET_STRING.getValue(), 197 new GrammarAction<CertGenerationContainer>( "Set Cert Generation subject Dn value" ) 198 { 199 public void action( CertGenerationContainer container ) throws DecoderException 200 { 201 Value value = container.getCurrentTLV().getValue(); 202 203 String subjectDN = Strings.utf8ToString(value.getData()); 204 205 if ( IS_DEBUG ) 206 { 207 LOG.debug( "subject Dn = " + subjectDN ); 208 } 209 210 if ( ( subjectDN != null ) && ( subjectDN.trim().length() > 0 ) ) 211 { 212 if( !Dn.isValid(subjectDN) ) 213 { 214 String msg = I18n.err( I18n.ERR_04035, subjectDN ); 215 LOG.error( msg ); 216 throw new DecoderException( msg ); 217 } 218 219 container.getCertGenerationObject().setSubjectDN( subjectDN ); 220 } 221 else 222 { 223 String msg = I18n.err( I18n.ERR_04033, Strings.dumpBytes(value.getData()) ); 224 LOG.error( msg ); 225 throw new DecoderException( msg ); 226 } 227 } 228 } ); 229 230 /** 231 * Transition from subjectDN state to keyAlgo 232 * 233 * CertGenerationObject ::= SEQUENCE { 234 * ... 235 * keyAlgorithm IA5String 236 * 237 * Set the key algorithm value into the CertGenerationObject instance. 238 */ 239 super.transitions[CertGenerationStatesEnum.SUBJECT_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 240 new GrammarTransition<CertGenerationContainer>( CertGenerationStatesEnum.SUBJECT_STATE, 241 CertGenerationStatesEnum.KEY_ALGORITHM_STATE, 242 UniversalTag.OCTET_STRING.getValue(), 243 new GrammarAction<CertGenerationContainer>( "Set Cert Generation key algorithm value" ) 244 { 245 public void action( CertGenerationContainer container ) throws DecoderException 246 { 247 Value value = container.getCurrentTLV().getValue(); 248 249 String keyAlgorithm = Strings.utf8ToString(value.getData()); 250 251 if ( IS_DEBUG ) 252 { 253 LOG.debug( "key algorithm = " + keyAlgorithm ); 254 } 255 256 if ( keyAlgorithm != null && ( keyAlgorithm.trim().length() > 0 ) ) 257 { 258 container.getCertGenerationObject().setKeyAlgorithm( keyAlgorithm ); 259 } 260 261 container.setGrammarEndAllowed( true ); 262 } 263 } ); 264 265 } 266 267 268 /** 269 * This class is a singleton. 270 * 271 * @return An instance on this grammar 272 */ 273 public static Grammar<CertGenerationContainer> getInstance() 274 { 275 return instance; 276 } 277}