You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2007/10/25 01:25:02 UTC
svn commit: r588079 - in
/directory/apacheds/branches/bigbang/kerberos-shared/src:
main/java/org/apache/directory/server/kerberos/shared/keytab/
main/java/org/apache/directory/server/kerberos/shared/messages/value/
test/java/org/apache/directory/server...
Author: elecharny
Date: Wed Oct 24 16:25:01 2007
New Revision: 588079
URL: http://svn.apache.org/viewvc?rev=588079&view=rev
Log:
Added the new version of EncryptionKey class, plus some tests
Added:
directory/apacheds/branches/bigbang/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKeyTest.java
Modified:
directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/keytab/KeytabDecoder.java
directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKey.java
Modified: directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/keytab/KeytabDecoder.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/keytab/KeytabDecoder.java?rev=588079&r1=588078&r2=588079&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/keytab/KeytabDecoder.java (original)
+++ directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/keytab/KeytabDecoder.java Wed Oct 24 16:25:01 2007
@@ -138,7 +138,7 @@
byte[] keyblock = getCountedBytes( buffer );
EncryptionType encryptionType = EncryptionType.getTypeByOrdinal( type );
- EncryptionKey key = new EncryptionKey( encryptionType, keyblock, keyVersion );
+ EncryptionKey key = new EncryptionKey( encryptionType, keyblock );
return key;
}
Modified: directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKey.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKey.java?rev=588079&r1=588078&r2=588079&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKey.java (original)
+++ directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKey.java Wed Oct 24 16:25:01 2007
@@ -20,30 +20,70 @@
package org.apache.directory.server.kerberos.shared.messages.value;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
import java.util.Arrays;
import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
+import org.apache.directory.shared.asn1.AbstractAsn1Object;
+import org.apache.directory.shared.asn1.ber.tlv.TLV;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A Kerberos symmetric encryption key, which includes metadata support for
* the associated key type and key version number.
*
+ * The ASN.1 description for this structure is :
+ * EncryptionKey ::= SEQUENCE {
+ * keytype [0] Int32 -- actually encryption type --,
+ * keyvalue [1] OCTET STRING
+ * }
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
-public class EncryptionKey
+public class EncryptionKey extends AbstractAsn1Object
{
+ /** The logger */
+ private static final Logger log = LoggerFactory.getLogger( EncryptionKey.class );
+
+ /** Speedup for logs */
+ private static final boolean IS_DEBUG = log.isDebugEnabled();
+
+ // The encryption type
private EncryptionType keyType;
+
+ // The encrypted value
private byte[] keyValue;
+
+ // The key version
private int keyVersion;
+ // Storage for computed lengths
+ private transient int keyTypeLength;
+ private transient int keyValueLength;
+ private transient int encryptionKeyLength;
+
+
+ /**
+ * Creates a new instance of EncryptionKey.
+ */
+ public EncryptionKey()
+ {
+ }
+
/**
* Creates a new instance of EncryptionKey.
*
- * @param keyType
- * @param keyValue
+ * @param keyType The encryptionType
+ * @param keyValue The value
*/
public EncryptionKey( EncryptionType keyType, byte[] keyValue )
{
@@ -53,15 +93,11 @@
/**
- * Creates a new instance of EncryptionKey. This constructor supports 'keyVersion',
- * which is sent over the wire as part of EncryptedData but makes more sense
- * in the domain model to have here as part of the key itself. Therefore, the
- * keyVersion should only be constructor-injected when EncryptionKey's are
- * retrieved from persisted storage.
- *
- * @param keyType
- * @param keyValue
- * @param keyVersion
+ * Creates a new instance of EncryptionKey.
+ *
+ * @param keyType The encryptionType
+ * @param keyValue The value
+ * @param keyVersion ???
*/
public EncryptionKey( EncryptionType keyType, byte[] keyValue, int keyVersion )
{
@@ -78,10 +114,7 @@
{
if ( keyValue != null )
{
- for ( int ii = 0; ii < keyValue.length; ii++ )
- {
- keyValue[ii] = 0;
- }
+ Arrays.fill( keyValue, ( byte ) 0x00 );
}
}
@@ -98,6 +131,16 @@
/**
+ * Set the encryption type
+ * @param keyType The encryption type
+ */
+ public void setKeyType( EncryptionType keyType )
+ {
+ this.keyType = keyType;
+ }
+
+
+ /**
* Returns the key value.
*
* @return The key value.
@@ -118,7 +161,31 @@
return keyVersion;
}
+
+ /**
+ * Returns the key version.
+ *
+ * @return The key version.
+ */
+ public void setKeyVersion( int keyVersion)
+ {
+ this.keyVersion = keyVersion;
+ }
+
+
+ /**
+ * Set the key value
+ * @param keyValue The key value
+ */
+ public void setKeyValue( byte[] keyValue )
+ {
+ this.keyValue = keyValue;
+ }
+
+ /**
+ * @see Object#equals(Object)
+ */
public boolean equals( Object o )
{
if ( this == o )
@@ -126,7 +193,7 @@
return true;
}
- if ( !( o instanceof EncryptionKey ) )
+ if ( ( o == null ) || !( o instanceof EncryptionKey ) )
{
return false;
}
@@ -136,6 +203,112 @@
}
+ /**
+ * Compute the EncryptionKey length
+ *
+ * EncryptionKey :
+ *
+ * 0x30 L1 EncryptionKey
+ * |
+ * +--> 0xA0 L2 keyType tag
+ * | |
+ * | +--> 0x02 L2-1 keyType (int)
+ * |
+ * +--> 0xA1 L3 keyValue tag
+ * |
+ * +--> 0x04 L3-1 keyValue (OCTET STRING)
+ *
+ * where L1 = L2 + lenght(0xA0) + length(L2) +
+ * L3 + lenght(0xA1) + length(L3)
+ * and
+ * L2 = L2-1 + length(0x02) + length( L2-1)
+ * L3 = L3-1 + length(0x04) + length( L3-1)
+ */
+ public int computeLength()
+ {
+ // Compute the keyType. The Length will always be cobntained in 1 byte
+ keyTypeLength = 1 + 1 + Value.getNbBytes( keyType.getOrdinal() );
+ encryptionKeyLength = 1 + TLV.getNbBytes( keyTypeLength ) + keyTypeLength;
+
+ // Compute the keyValue
+ if ( keyValue == null )
+ {
+ keyValueLength = 1 + 1;
+ }
+ else
+ {
+ keyValueLength = 1 + TLV.getNbBytes( keyValue.length ) + keyValue.length;
+ }
+
+ encryptionKeyLength += 1 + TLV.getNbBytes( keyValueLength ) + keyValueLength;
+
+ // Compute the whole sequence length
+ int encryptionKeySeqLength = 1 + Value.getNbBytes( encryptionKeyLength ) + encryptionKeyLength;
+
+ return encryptionKeySeqLength;
+
+ }
+
+
+ /**
+ * Encode the EncryptionKey message to a PDU.
+ *
+ * EncryptionKey :
+ *
+ * 0x30 LL
+ * 0xA0 LL
+ * 0x02 0x01 keyType
+ * 0xA1 LL
+ * 0x04 LL keyValue
+ *
+ * @param buffer The buffer where to put the PDU. It should have been allocated
+ * before, with the right size.
+ * @return The constructed PDU.
+ */
+ public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
+ {
+ if ( buffer == null )
+ {
+ throw new EncoderException( "Cannot put a PDU in a null buffer !" );
+ }
+
+ try
+ {
+ // The EncryptionKey SEQ Tag
+ buffer.put( UniversalTag.SEQUENCE_TAG );
+ buffer.put( TLV.getBytes( encryptionKeyLength ) );
+
+ // The keyType, first the tag, then the value
+ buffer.put( ( byte ) 0xA0 );
+ buffer.put( TLV.getBytes( keyTypeLength ) );
+ Value.encode( buffer, keyType.getOrdinal() );
+
+ // The keyValue, first the tag, then the value
+ buffer.put( ( byte ) 0xA1 );
+ buffer.put( TLV.getBytes( keyValueLength ) );
+ Value.encode( buffer, keyValue );
+ }
+ catch ( BufferOverflowException boe )
+ {
+ log.error(
+ "Cannot encode the EncryptionKey object, the PDU size is {} when only {} bytes has been allocated", 1
+ + TLV.getNbBytes( encryptionKeyLength ) + encryptionKeyLength, buffer.capacity() );
+ throw new EncoderException( "The PDU buffer size is too small !" );
+ }
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "EncryptionKey encoding : {}", StringTools.dumpBytes( buffer.array() ) );
+ log.debug( "EncryptionKey initial value : {}", toString() );
+ }
+
+ return buffer;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
public String toString()
{
return keyType.toString() + " (" + keyType.getOrdinal() + ")";
Added: directory/apacheds/branches/bigbang/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKeyTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKeyTest.java?rev=588079&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKeyTest.java (added)
+++ directory/apacheds/branches/bigbang/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/messages/value/EncryptionKeyTest.java Wed Oct 24 16:25:01 2007
@@ -0,0 +1,164 @@
+/*
+ * 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.server.kerberos.shared.messages.value;
+
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
+import org.apache.directory.server.kerberos.shared.io.encoder.EncryptionKeyEncoder;
+import org.apache.directory.shared.asn1.codec.EncoderException;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Test the EncryptionKey encoding and decoding
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 542147 $, $Date: 2007-05-28 10:14:21 +0200 (Mon, 28 May 2007) $
+ */
+public class EncryptionKeyTest extends TestCase
+{
+ public void testEncodingFast() throws Exception
+ {
+ EncryptionKey ec = new EncryptionKey( EncryptionType.AES128_CTS_HMAC_SHA1_96, new byte[]
+ { 0x01, 0x02, 0x03 } );
+
+ ByteBuffer encoded = ByteBuffer.allocate( ec.computeLength() );
+
+ ec.encode( encoded );
+
+ byte[] expectedResult = new byte[]
+ {
+ 0x30, 0x0c,
+ ( byte ) 0xA0, 0x03,
+ 0x02, 0x01, 0x11,
+ ( byte ) 0xA1, 0x05,
+ 0x04, 0x03, 0x01, 0x02, 0x03
+ };
+
+ assertTrue( Arrays.equals( expectedResult, encoded.array() ) );
+ }
+
+
+ public void testEncodingNoStructureFast() throws Exception
+ {
+ EncryptionKey ec = new EncryptionKey( EncryptionType.AES128_CTS_HMAC_SHA1_96, null );
+
+ ByteBuffer encoded = ByteBuffer.allocate( ec.computeLength() );
+
+ ec.encode( encoded );
+
+ byte[] expectedResult = new byte[]
+ {
+ 0x30, 0x09,
+ ( byte ) 0xA0, 0x03,
+ 0x02, 0x01, 0x11,
+ ( byte ) 0xA1, 0x02,
+ 0x04, 0x00
+ };
+
+ assertTrue( Arrays.equals( expectedResult, encoded.array() ) );
+ }
+
+
+ /*
+ public void testEncodingNoStructureSlow() throws Exception
+ {
+ EncryptionKey ec = new EncryptionKey( EncryptionType.AES128_CTS_HMAC_SHA1_96, null );
+
+ byte[] encoded = EncryptionKeyEncoder.encode( ec );
+
+ byte[] expectedResult = new byte[]
+ {
+ 0x30, 0x09,
+ (byte)0xA0, 0x03,
+ 0x02, 0x01, 0x11,
+ (byte)0xA1, 0x02,
+ 0x04, 0x00
+ };
+
+ assertTrue( Arrays.equals( expectedResult, encoded ) );
+ }
+ */
+
+ public void testEncodingSlow() throws Exception
+ {
+ EncryptionKey ec = new EncryptionKey( EncryptionType.AES128_CTS_HMAC_SHA1_96, new byte[]
+ { 0x01, 0x02, 0x03 } );
+
+ byte[] encoded = EncryptionKeyEncoder.encode( ec );
+
+ byte[] expectedResult = new byte[]
+ {
+ 0x30, 0x0c,
+ ( byte ) 0xA0, 0x03,
+ 0x02, 0x01, 0x11,
+ ( byte ) 0xA1, 0x05,
+ 0x04, 0x03, 0x01, 0x02, 0x03
+ };
+
+ assertTrue( Arrays.equals( expectedResult, encoded ) );
+ }
+
+
+ public void testPerfSlow() throws IOException
+ {
+ EncryptionKey ec = new EncryptionKey( EncryptionType.AES128_CTS_HMAC_SHA1_96, new byte[]
+ { 0x01, 0x02, 0x03 } );
+ EncryptionKeyEncoder.encode( ec );
+
+ long t0 = System.currentTimeMillis();
+
+ //for ( int i = 0; i < 10000000; i++ )
+ {
+ EncryptionKeyEncoder.encode( ec );
+ }
+
+ long t1 = System.currentTimeMillis();
+
+ System.out.println( "Delta = " + ( t1 - t0 ) );
+ }
+
+
+ public void testPerfFast() throws EncoderException
+ {
+ EncryptionKey ec = new EncryptionKey( EncryptionType.AES128_CTS_HMAC_SHA1_96, new byte[]
+ { 0x01, 0x02, 0x03 } );
+ ByteBuffer encoded = ByteBuffer.allocate( ec.computeLength() );
+ ec.encode( encoded );
+
+ long t0 = System.currentTimeMillis();
+
+ //for ( int i = 0; i < 40000000; i++ )
+ {
+ encoded = ByteBuffer.allocate( ec.computeLength() );
+
+ ec.encode( encoded );
+ }
+
+ long t1 = System.currentTimeMillis();
+
+ System.out.println( "Delta2 = " + ( t1 - t0 ) );
+ }
+}