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