Author: kayyagari Date: Sun Jan 4 10:26:09 2009 New Revision: 731310 URL: http://svn.apache.org/viewvc?rev=731310&view=rev Log: source file for ASN1 codec for the new certificate generation/modification extended operation Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationContainer.java directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationDecoder.java directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationGrammar.java directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationObject.java directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationStatesEnum.java directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationRequest.java directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationResponse.java directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationRequestTest.java Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationContainer.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationContainer.java?rev=731310&view=auto ============================================================================== --- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationContainer.java (added) +++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationContainer.java Sun Jan 4 10:26:09 2009 @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.shared.ldap.codec.extended.operations; + +import org.apache.directory.shared.asn1.ber.AbstractContainer; + +/** + * + * A container for certificate generation request codec. + * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class CertGenerationContainer extends AbstractContainer +{ + /** CertGenerationObject */ + private CertGenerationObject certGenObj; + + + /** + * Creates a new CertGenContainer object. We will store one + * grammar, it's enough ... + */ + public CertGenerationContainer() + { + super(); + stateStack = new int[1]; + grammar = CertGenerationGrammar.getInstance(); + states = CertGenerationStatesEnum.getInstance(); + } + + + /** + * @return Returns the CertGenerationObject instance. + */ + public CertGenerationObject getCertGenerationObject() + { + return certGenObj; + } + + + /** + * Set a CertGenerationObject Object into the container. It will be completed by + * the ldapDecoder. + * + * @param certGenObj the CertGenerationObject to set. + */ + public void setCertGenerationObject( CertGenerationObject certGenObj ) + { + this.certGenObj = certGenObj; + } + + + /** + * Clean the container for the next decoding. + */ + public void clean() + { + super.clean(); + certGenObj = null; + } +} Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationDecoder.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationDecoder.java?rev=731310&view=auto ============================================================================== --- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationDecoder.java (added) +++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationDecoder.java Sun Jan 4 10:26:09 2009 @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.shared.ldap.codec.extended.operations; + + +import java.nio.ByteBuffer; + +import org.apache.directory.shared.asn1.Asn1Object; +import org.apache.directory.shared.asn1.ber.Asn1Decoder; +import org.apache.directory.shared.asn1.codec.DecoderException; + + +/** + * + * A decoder for CertGenerationObject. + * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class CertGenerationDecoder extends Asn1Decoder +{ + /** The decoder */ + private static final Asn1Decoder decoder = new Asn1Decoder(); + + + /** + * Decode a PDU which must contain a CertGenRequest extended operation. + * Note that the stream of bytes much contain a full PDU, not a partial one. + * + * @param stream The bytes to be decoded + * @return a CertGenerationObject object + * @throws DecoderException If the decoding failed + */ + public Asn1Object decode( byte[] stream ) throws DecoderException + { + ByteBuffer bb = ByteBuffer.wrap( stream ); + CertGenerationContainer container = new CertGenerationContainer(); + decoder.decode( bb, container ); + CertGenerationObject certGenObj = container.getCertGenerationObject(); + + // Clean the container for the next decoding + container.clean(); + + return certGenObj; + } + +} Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationGrammar.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationGrammar.java?rev=731310&view=auto ============================================================================== --- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationGrammar.java (added) +++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationGrammar.java Sun Jan 4 10:26:09 2009 @@ -0,0 +1,254 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.shared.ldap.codec.extended.operations; + + +import org.apache.directory.shared.asn1.ber.IAsn1Container; +import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar; +import org.apache.directory.shared.asn1.ber.grammar.GrammarAction; +import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition; +import org.apache.directory.shared.asn1.ber.grammar.IGrammar; +import org.apache.directory.shared.asn1.ber.grammar.IStates; +import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; +import org.apache.directory.shared.asn1.ber.tlv.Value; +import org.apache.directory.shared.asn1.codec.DecoderException; +import org.apache.directory.shared.ldap.util.StringTools; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * This class implements the Certificate generation extended operation's ASN.1 grammer. + * All the actions are declared in this class. As it is a singleton, + * these declaration are only done once. The grammar is : + * + *
+ *   CertGenerateObject ::= SEQUENCE 
+ *   {
+ *      targetDN        IA5String,
+ *      issuerDN        IA5String,
+ *      subjectDN       IA5String,
+ *      keyAlgorithm    IA5String
+ *   }
+ * 
+ * + * @author Apache Directory Project + * @version $Rev: 664290 $, $Date: 2008-06-07 11:58:06 +0530 (Sat, 07 Jun 2008) $, + */ + +public class CertGenerationGrammar extends AbstractGrammar +{ + + /** logger */ + private static final Logger LOG = LoggerFactory.getLogger( CertGenerationGrammar.class ); + + /** Speedup for logs */ + static final boolean IS_DEBUG = LOG.isDebugEnabled(); + + /** The instance of grammar. CertGenerationObjectGrammar is a singleton */ + private static IGrammar instance = new CertGenerationGrammar(); + + + public CertGenerationGrammar() + { + name = CertGenerationGrammar.class.getName(); + statesEnum = CertGenerationStatesEnum.getInstance(); + + // Create the transitions table + super.transitions = new GrammarTransition[CertGenerationStatesEnum.LAST_CERT_GENERATION_STATE][256]; + + /** + * Transition from init state to certificate generation + * + * CertGenerationObject ::= SEQUENCE { + * ... + * + * Creates the CertGenerationObject object + */ + super.transitions[IStates.INIT_GRAMMAR_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition( + IStates.INIT_GRAMMAR_STATE, CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE, + UniversalTag.SEQUENCE_TAG, new GrammarAction( "Init CertGenerationObject" ) + { + public void action( IAsn1Container container ) + { + CertGenerationContainer certGenContainer = ( CertGenerationContainer ) container; + CertGenerationObject certGenerationObject = new CertGenerationObject(); + certGenContainer.setCertGenerationObject( certGenerationObject ); + certGenContainer.grammarEndAllowed( true ); + } + } ); + + /** + * Transition from certificate generation request to targetDN + * + * CertGenerationObject ::= SEQUENCE { + * targetDN IA5String, + * ... + * + * Set the targetDN value into the CertGenerationObject instance. + */ + super.transitions[CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE][UniversalTag.OCTET_STRING] = new GrammarTransition( + CertGenerationStatesEnum.CERT_GENERATION_REQUEST_SEQUENCE_STATE, CertGenerationStatesEnum.TARGETDN_STATE, + UniversalTag.OCTET_STRING, new GrammarAction( "Set Cert Generation target DN value" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + CertGenerationContainer CertGenContainer = ( CertGenerationContainer ) container; + Value value = CertGenContainer.getCurrentTLV().getValue(); + + String targetDN = StringTools.utf8ToString( value.getData() ); + + if ( IS_DEBUG ) + { + LOG.debug( "Target DN = " + targetDN ); + } + + if ( targetDN != null && ( targetDN.trim().length() > 0 ) ) + { + CertGenContainer.getCertGenerationObject().setTargetDN( targetDN ); + } + else + { + String msg = "failed to decode the target DN, it cannot be null or empty it is '" + + StringTools.dumpBytes( value.getData() ); + LOG.error( msg ); + throw new DecoderException( msg ); + } + + CertGenContainer.grammarEndAllowed( true ); + } + } ); + + /** + * Transition from targetDN state to issuerDN + * + * CertGenerationObject ::= SEQUENCE { + * ... + * issuerDN IA5String, + * ... + * + * Set the issuerDN value into the CertGenerationObject instance. + */ + super.transitions[CertGenerationStatesEnum.TARGETDN_STATE][UniversalTag.OCTET_STRING] = new GrammarTransition( + CertGenerationStatesEnum.TARGETDN_STATE, CertGenerationStatesEnum.ISSUER_STATE, UniversalTag.OCTET_STRING, + new GrammarAction( "Set Cert Generation issuer DN value" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + CertGenerationContainer CertGenContainer = ( CertGenerationContainer ) container; + Value value = CertGenContainer.getCurrentTLV().getValue(); + + String issuerDN = StringTools.utf8ToString( value.getData() ); + + if ( IS_DEBUG ) + { + LOG.debug( "Issuer DN = " + issuerDN ); + } + + if ( issuerDN != null && ( issuerDN.trim().length() > 0 ) ) + { + CertGenContainer.getCertGenerationObject().setIssuerDN( issuerDN ); + } + CertGenContainer.grammarEndAllowed( true ); + } + } ); + + /** + * Transition from issuerDN state to subjectDN + * + * CertGenerationObject ::= SEQUENCE { + * ... + * subjectDN IA5String, + * ... + * + * Set the subjectDN value into the CertGenerationObject instance. + */ + super.transitions[CertGenerationStatesEnum.ISSUER_STATE][UniversalTag.OCTET_STRING] = new GrammarTransition( + CertGenerationStatesEnum.ISSUER_STATE, CertGenerationStatesEnum.SUBJECT_STATE, UniversalTag.OCTET_STRING, + new GrammarAction( "Set Cert Generation subject DN value" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + CertGenerationContainer CertGenContainer = ( CertGenerationContainer ) container; + Value value = CertGenContainer.getCurrentTLV().getValue(); + + String subjectDN = StringTools.utf8ToString( value.getData() ); + + if ( IS_DEBUG ) + { + LOG.debug( "subject DN = " + subjectDN ); + } + + if ( subjectDN != null && ( subjectDN.trim().length() > 0 ) ) + { + CertGenContainer.getCertGenerationObject().setSubjectDN( subjectDN ); + } + + CertGenContainer.grammarEndAllowed( true ); + } + } ); + + /** + * Transition from subjectDN state to keyAlgo + * + * CertGenerationObject ::= SEQUENCE { + * ... + * issuerDN IA5String + * + * Set the key algorithm value into the CertGenerationObject instance. + */ + super.transitions[CertGenerationStatesEnum.SUBJECT_STATE][UniversalTag.OCTET_STRING] = new GrammarTransition( + CertGenerationStatesEnum.SUBJECT_STATE, CertGenerationStatesEnum.KEY_ALGORITHM_STATE, + UniversalTag.OCTET_STRING, new GrammarAction( "Set Cert Generation key algorithm value" ) + { + public void action( IAsn1Container container ) throws DecoderException + { + CertGenerationContainer CertGenContainer = ( CertGenerationContainer ) container; + Value value = CertGenContainer.getCurrentTLV().getValue(); + + String keyAlgorithm = StringTools.utf8ToString( value.getData() ); + + if ( IS_DEBUG ) + { + LOG.debug( "subject DN = " + keyAlgorithm ); + } + + if ( keyAlgorithm != null && ( keyAlgorithm.trim().length() > 0 ) ) + { + CertGenContainer.getCertGenerationObject().setKeyAlgorithm( keyAlgorithm ); + } + + CertGenContainer.grammarEndAllowed( true ); + } + } ); + + } + + + /** + * This class is a singleton. + * + * @return An instance on this grammar + */ + public static IGrammar getInstance() + { + return instance; + } +} Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationObject.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationObject.java?rev=731310&view=auto ============================================================================== --- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationObject.java (added) +++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationObject.java Sun Jan 4 10:26:09 2009 @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.shared.ldap.codec.extended.operations; + + +import java.nio.ByteBuffer; + +import org.apache.directory.shared.asn1.AbstractAsn1Object; +import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; +import org.apache.directory.shared.asn1.ber.tlv.Value; +import org.apache.directory.shared.asn1.codec.EncoderException; +import org.apache.directory.shared.ldap.util.StringTools; + + +/** + * + * An extended operation for generating a public key Certificate. + *
+ *   CertGenerateObject ::= SEQUENCE 
+ *   {
+ *      targetDN        IA5String,
+ *      issuerDN        IA5String,
+ *      subjectDN       IA5String,
+ *      keyAlgorithm    IA5String
+ *   }
+ * 
+ * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class CertGenerationObject extends AbstractAsn1Object +{ + + /** the DN of the server entry which will be updated*/ + private String targetDN; + + /** the issuer DN that will be set in the certificate*/ + private String issuerDN;// = "CN=ApacheDS, OU=Directory, O=ASF, C=US"; + + /** the DN of the subject that is present in the certificate*/ + private String subjectDN;// = "CN=ApacheDS, OU=Directory, O=ASF, C=US"; + + /** name of the algorithm used for generating the keys*/ + private String keyAlgorithm;// = "RSA"; + + /** stores the length of the request*/ + private int requestLength = 0; + + + @Override + public int computeLength() + { + int len = StringTools.getBytesUtf8( targetDN ).length; + requestLength = 1 + Value.getNbBytes( len ) + len; + + len = StringTools.getBytesUtf8( issuerDN ).length; + requestLength += 1 + Value.getNbBytes( len ) + len; + + len = StringTools.getBytesUtf8( subjectDN ).length; + requestLength += 1 + Value.getNbBytes( len ) + len; + + len = StringTools.getBytesUtf8( keyAlgorithm ).length; + requestLength += 1 + Value.getNbBytes( len ) + len; + + return 1 + Value.getNbBytes( requestLength ) + requestLength; + } + + + @Override + public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException + { + ByteBuffer bb = ByteBuffer.allocate( computeLength() ); + + bb.put( UniversalTag.SEQUENCE_TAG ); + bb.put( Value.getBytes( requestLength ) ); + + Value.encode( bb, targetDN ); + Value.encode( bb, issuerDN ); + Value.encode( bb, subjectDN ); + Value.encode( bb, keyAlgorithm ); + + return bb; + } + + + public String getTargetDN() + { + return targetDN; + } + + + public void setTargetDN( String targetDN ) + { + this.targetDN = targetDN; + } + + + public String getIssuerDN() + { + return issuerDN; + } + + + public void setIssuerDN( String issuerDN ) + { + this.issuerDN = issuerDN; + } + + + public String getSubjectDN() + { + return subjectDN; + } + + + public void setSubjectDN( String subjectDN ) + { + this.subjectDN = subjectDN; + } + + + public String getKeyAlgorithm() + { + return keyAlgorithm; + } + + + public void setKeyAlgorithm( String keyAlgorithm ) + { + this.keyAlgorithm = keyAlgorithm; + } + + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append( "Certficate Generation Object { " ).append( " Target DN: " ).append( targetDN ).append( ',' ); + sb.append( " Issuer DN: " ).append( issuerDN ).append( ',' ); + sb.append( " Subject DN: " ).append( subjectDN ).append( ',' ); + sb.append( " Key Algorithm: " ).append( keyAlgorithm ).append( " }" ); + + return sb.toString(); + } +} Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationStatesEnum.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationStatesEnum.java?rev=731310&view=auto ============================================================================== --- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationStatesEnum.java (added) +++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationStatesEnum.java Sun Jan 4 10:26:09 2009 @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.shared.ldap.codec.extended.operations; + + +import org.apache.directory.shared.asn1.ber.grammar.IGrammar; +import org.apache.directory.shared.asn1.ber.grammar.IStates; + +/** + * This class store the CertGeneration's grammar constants. It is also used + * for debugging purposes. + * + * @author Apache Directory Project + * @version $Rev: 664290 $, $Date: 2008-06-07 11:58:06 +0530 (Sat, 07 Jun 2008) $, + */ +public class CertGenerationStatesEnum implements IStates +{ + + /** start state*/ + public static final int START_STATE = 0; + + /** sequence*/ + public static final int CERT_GENERATION_REQUEST_SEQUENCE_STATE = 1; + + /** the target DN*/ + public static final int TARGETDN_STATE = 2; + + /** the issuer DN*/ + public static final int ISSUER_STATE = 3; + + /** the subject DN*/ + public static final int SUBJECT_STATE = 4; + + /** the key algorithm*/ + public static final int KEY_ALGORITHM_STATE = 5; + + /** terminal state */ + public static final int LAST_CERT_GENERATION_STATE = 6; + + private static String[] certGenerationString = new String[] + { + "START_STATE", + "CERT_GENERATION_REQUEST_SEQUENCE_STATE", + "TARGETDN_STATE", "ISSUER_STATE", + "SUBJECT_STATE", + "KEY_ALGORITHM_STATE" + }; + + /** a singleton instance*/ + private static CertGenerationStatesEnum instance = new CertGenerationStatesEnum(); + + + /** + * Get the grammar name + * + * @param grammar The grammar class + * @return The grammar name + */ + public String getGrammarName( IGrammar grammar ) + { + if ( grammar instanceof CertGenerationGrammar ) + { + return "CERT_GENERATION_GRAMMER"; + } + + return "UNKNOWN GRAMMAR"; + } + + + /** + * Get the grammar name + * + * @param grammar The grammar code + * @return The grammar name + */ + public String getGrammarName( int grammar ) + { + return "CERT_GENERATION_GRAMMER"; + } + + + /** + * Get the string representing the state + * + * @param state The state number + * @return The String representing the state + */ + public String getState( int state ) + { + return ( ( state == GRAMMAR_END ) ? "CERT_GENERATION_END_STATE" : certGenerationString[state] ); + } + + /** + * Get an instance of this class + * + * @return An instance on this class + */ + public static IStates getInstance() + { + return instance; + } +} Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationRequest.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationRequest.java?rev=731310&view=auto ============================================================================== --- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationRequest.java (added) +++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationRequest.java Sun Jan 4 10:26:09 2009 @@ -0,0 +1,202 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.shared.ldap.message.extended; + + +import javax.naming.NamingException; +import javax.naming.ldap.ExtendedResponse; + +import org.apache.directory.shared.asn1.codec.DecoderException; +import org.apache.directory.shared.asn1.codec.EncoderException; +import org.apache.directory.shared.ldap.codec.extended.operations.CertGenerationDecoder; +import org.apache.directory.shared.ldap.codec.extended.operations.CertGenerationObject; +import org.apache.directory.shared.ldap.message.ExtendedRequestImpl; +import org.apache.directory.shared.ldap.message.ResultResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * + * An extended operation requesting the server to generate a public/private key pair and a certificate + * and store them in a specified target entry in the DIT. + * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class CertGenerationRequest extends ExtendedRequestImpl +{ + private CertGenerationObject certGenObj; + + private static final Logger LOG = LoggerFactory.getLogger( CertGenerationRequest.class ); + + public static final String EXTENSION_OID = "1.3.6.1.4.1.18060.0.1.6"; + + /** + * + * Creates a new instance of CertGenerationRequest. + * + * @param messageId the message id + * @param targerDN the DN of target entry whose key and certificate values will be changed + * @param issuerDN DN to be used as the issuer's DN in the certificate + * @param subjectDN DN to be used as certificate's subject + * @param keyAlgorithm crypto algorithm name to be used for generating the keys + */ + public CertGenerationRequest( int messageId, String targerDN, String issuerDN, String subjectDN, String keyAlgorithm ) + { + super( messageId ); + setOid( EXTENSION_OID ); + + this.certGenObj = new CertGenerationObject(); + certGenObj.setTargetDN( targerDN ); + certGenObj.setIssuerDN( issuerDN ); + certGenObj.setSubjectDN( subjectDN ); + certGenObj.setKeyAlgorithm( keyAlgorithm ); + } + + + private void encodePayload() throws EncoderException + { + payload = certGenObj.encode( null ).array(); + } + + + public void setPayload( byte[] payload ) + { + CertGenerationDecoder decoder = new CertGenerationDecoder(); + try + { + certGenObj = ( CertGenerationObject ) decoder.decode( payload ); + if ( payload != null ) + { + this.payload = new byte[payload.length]; + System.arraycopy( payload, 0, this.payload, 0, payload.length ); + } + else + { + this.payload = null; + } + } + catch ( DecoderException e ) + { + LOG.error( "failed to decode payload", e ); + throw new RuntimeException( e ); + } + } + + + public ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset, int length ) + throws NamingException + { + return ( ExtendedResponse ) getResultResponse(); + } + + + public byte[] getEncodedValue() + { + return getPayload(); + } + + + public byte[] getPayload() + { + if ( payload == null ) + { + try + { + encodePayload(); + } + catch ( EncoderException e ) + { + LOG.error( "Failed to encode payload CertGenerateRequest", e ); + throw new RuntimeException( e ); + } + } + + if ( payload == null ) + { + return null; + } + + final byte[] copy = new byte[payload.length]; + System.arraycopy( payload, 0, copy, 0, payload.length ); + return copy; + } + + + public ResultResponse getResultResponse() + { + if ( response == null ) + { + response = new CertGenerationResponse( getMessageId() ); + } + + return response; + } + + + public String getTargetDN() + { + return certGenObj.getTargetDN(); + } + + + public void setTargetDN( String targetDN ) + { + certGenObj.setTargetDN( targetDN ); + } + + + public String getIssuerDN() + { + return certGenObj.getIssuerDN(); + } + + + public void setIssuerDN( String issuerDN ) + { + certGenObj.setIssuerDN( issuerDN ); + } + + + public String getSubjectDN() + { + return certGenObj.getSubjectDN(); + } + + + public void setSubjectDN( String subjectDN ) + { + certGenObj.setSubjectDN( subjectDN ); + } + + + public String getKeyAlgorithm() + { + return certGenObj.getKeyAlgorithm(); + } + + + public void setKeyAlgorithm( String keyAlgorithm ) + { + certGenObj.setKeyAlgorithm( keyAlgorithm ); + } + +} Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationResponse.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationResponse.java?rev=731310&view=auto ============================================================================== --- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationResponse.java (added) +++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationResponse.java Sun Jan 4 10:26:09 2009 @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.shared.ldap.message.extended; + +import org.apache.directory.shared.ldap.message.ExtendedResponseImpl; +import org.apache.directory.shared.ldap.message.ResultCodeEnum; +/** + * + * The response sent back from the server after the CertGeneration extended operation is performed. + * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class CertGenerationResponse extends ExtendedResponseImpl +{ + + public static final String EXTENSION_OID = "1.3.6.1.4.1.18060.0.1.7"; + + private static final byte[] EMPTY_RESPONSE = new byte[0]; + + + public CertGenerationResponse(int messageId, ResultCodeEnum rcode) + { + super( messageId, EXTENSION_OID ); + + switch ( rcode ) + { + case SUCCESS : + break; + + case OPERATIONS_ERROR : + break; + + case INSUFFICIENT_ACCESS_RIGHTS : + break; + + default: + throw new IllegalArgumentException( "The result code can only be one of: " + ResultCodeEnum.SUCCESS + + ", " + ResultCodeEnum.OPERATIONS_ERROR + ", " + ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS ); + } + + super.getLdapResult().setMatchedDn( null ); + super.getLdapResult().setResultCode( rcode ); + } + + + public CertGenerationResponse(int messageId) + { + super( messageId, EXTENSION_OID ); + super.getLdapResult().setMatchedDn( null ); + super.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS ); + } + + + // ------------------------------------------------------------------------ + // ExtendedResponse Interface Method Implementations + // ------------------------------------------------------------------------ + + /** + * Gets the reponse OID specific encoded response values. + * + * @return the response specific encoded response values. + */ + public byte[] getResponse() + { + return EMPTY_RESPONSE; + } + + + /** + * Sets the reponse OID specific encoded response values. + * + * @param value + * the response specific encoded response values. + */ + public void setResponse( byte[] value ) + { + // do nothing here instead + } + + + /** + * Gets the OID uniquely identifying this extended response (a.k.a. its + * name). + * + * @return the OID of the extended response type. + */ + public String getResponseName() + { + return EXTENSION_OID; + } + + + /** + * Sets the OID uniquely identifying this extended response (a.k.a. its + * name). + * + * @param oid + * the OID of the extended response type. + */ + public void setResponseName( String oid ) + { + throw new UnsupportedOperationException( "the OID is fixed: " + EXTENSION_OID ); + } + + + public boolean equals( Object obj ) + { + if ( obj == this ) + { + return true; + } + + if ( obj instanceof CertGenerationResponse ) + { + return true; + } + + return false; + } +} Added: directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationRequestTest.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationRequestTest.java?rev=731310&view=auto ============================================================================== --- directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationRequestTest.java (added) +++ directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/operations/CertGenerationRequestTest.java Sun Jan 4 10:26:09 2009 @@ -0,0 +1,186 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.shared.ldap.codec.extended.operations; + + +import static org.junit.Assert.*; + +import java.nio.ByteBuffer; + +import org.apache.directory.shared.asn1.ber.Asn1Decoder; +import org.apache.directory.shared.asn1.codec.DecoderException; +import org.apache.directory.shared.asn1.codec.EncoderException; +import org.apache.directory.shared.ldap.codec.LdapDecoder; +import org.apache.directory.shared.ldap.util.StringTools; +import org.junit.Test; + + +/** + * + * Test case for CertGenerate extended operation request. + * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class CertGenerationRequestTest +{ + + /** + * test the decode operation + */ + @Test + public void testCertGenrationDecode() + { + String dn = "uid=admin,ou=system"; + String keyAlgo = "RSA"; + + Asn1Decoder decoder = new LdapDecoder(); + + int dnLen = dn.length(); + + // start Tag + L is 2 bytes + // the same value of DN is used for all target,issuer and subject DNs so + // it is ( ( OCTET_STRING Tag + Len ) + dnLen ) * 3 + // finally for keyAlgo ( OCTET_STRING Tag + Len ) + keyAlgoLen + + int bufLen = 2 + ( ( 2 + dnLen ) * 3 ) + ( keyAlgo.length() + 2 ); + + ByteBuffer bb = ByteBuffer.allocate( bufLen ); + + bb.put( new byte[] + { 0x30, ( byte ) ( bufLen - 2 ) } ); // CertGenerateObject ::= SEQUENCE { + + /* targetDN IA5String, + * issuerDN IA5String, + * subjectDN IA5String, + * keyAlgorithm IA5String + */ + for ( int i = 0; i < 3; i++ ) + { + bb.put( new byte[] + { 0x04, ( byte ) dnLen } ); + for ( char c : dn.toCharArray() ) + { + bb.put( ( byte ) c ); + } + } + bb.put( new byte[] + { 0x04, 0x03, 'R', 'S', 'A' } ); + + String decodedPdu = StringTools.dumpBytes( bb.array() ); + bb.flip(); + + CertGenerationContainer container = new CertGenerationContainer(); + try + { + decoder.decode( bb, container ); + } + catch ( DecoderException e ) + { + e.printStackTrace(); + fail( e.getMessage() ); + } + + CertGenerationObject certGenObj = container.getCertGenerationObject(); + assertEquals( dn, certGenObj.getTargetDN() ); + assertEquals( dn, certGenObj.getIssuerDN() ); + assertEquals( dn, certGenObj.getSubjectDN() ); + assertEquals( keyAlgo, certGenObj.getKeyAlgorithm() ); + + assertEquals( bufLen, certGenObj.computeLength() ); + + try + { + ByteBuffer encodedBuf = certGenObj.encode( null ); + String encodedPdu = StringTools.dumpBytes( encodedBuf.array() ); + + assertEquals( decodedPdu, encodedPdu ); + } + catch ( EncoderException e ) + { + e.getMessage(); + fail( e.getMessage() ); + } + + } + + + @Test + public void testCertGenrationDecodeWithoutTargetDN() + { + Asn1Decoder decoder = new LdapDecoder(); + + ByteBuffer bb = ByteBuffer.allocate( 5 ); + + bb.put( new byte[] + { 0x30, 0x03, // CertGenerateObject ::= SEQUENCE { + 0x04, 0x01, ' ' } ); // empty targetDN value + + String decodedPdu = StringTools.dumpBytes( bb.array() ); + bb.flip(); + + CertGenerationContainer container = new CertGenerationContainer(); + + try + { + decoder.decode( bb, container ); + fail( "shouldn't accept the empty targetDN" ); + } + catch ( DecoderException e ) + { + e.printStackTrace(); + assertTrue( true ); + } + + } + + + @Test + public void testNullvalues() + { + Asn1Decoder decoder = new LdapDecoder(); + + ByteBuffer bb = ByteBuffer.allocate( 5 ); + + bb.put( new byte[] + { 0x30, 0x03, // CertGenerateObject ::= SEQUENCE { + 0x04, 0x01, 'x' } ); // non empty DN string + + CertGenerationContainer container = new CertGenerationContainer(); + bb.flip(); + + try + { + decoder.decode( bb, container ); + } + catch ( DecoderException e ) + { + e.printStackTrace(); + fail( e.getMessage() ); + } + + CertGenerationObject certGenObj = container.getCertGenerationObject(); + + assertEquals( "x", certGenObj.getTargetDN() ); + assertNull( certGenObj.getIssuerDN() ); + assertNull( certGenObj.getSubjectDN() ); + assertNull( certGenObj.getKeyAlgorithm() ); + } +}