Author: erodriguez
Date: Tue Sep 28 11:55:16 2004
New Revision: 47414

Added:
   incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/
   
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/Confounder.java
   
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/CryptoService.java
   
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/DesStringToKey.java
   
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/GlobalSequenceNumber.java
   
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/Nonce.java
   
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/SequenceNumber.java
Log:
kerberos crypto package

Added: 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/Confounder.java
==============================================================================
--- (empty file)
+++ 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/Confounder.java
   Tue Sep 28 11:55:16 2004
@@ -0,0 +1,62 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.kerberos.crypto;
+
+import java.security.*;
+
+public class Confounder {
+       
+       private static final SecureRandom random = new SecureRandom();
+       
+       public static synchronized byte[] bytes(int size) {
+               return bytes(size, false);
+       }
+       
+       public static synchronized byte[] bytes(int size, boolean testMode) {
+               
+               /*
+                * Use setSeed call to improve unit test performance or else
+                * the first call to SecureRandom may take a second.
+                * 
+                * TODO - consider removing testMode; in practice, I haven't 
found
+                *        SecureRandom to start slowly at all
+                */
+               if (testMode)
+                       random.setSeed("testModeSeedString".getBytes());
+               
+               byte[] bytes = new byte[size];
+               random.nextBytes(bytes);
+               return bytes;
+       }
+
+       public static synchronized int intValue() {
+               byte[] data = Confounder.bytes(4);
+               int result = 0;
+               for (int i = 0; i < 4; i++)
+                       result += data[i] * (16 ^ i);
+               return result;
+       }
+
+       public static synchronized long longValue() {
+               byte[] data = Confounder.bytes(4);
+               long result = 0;
+               for (int i = 0; i < 8; i++)
+                       result += (data[i]) * (16L ^ i);
+               return result;
+       }
+}
+

Added: 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/CryptoService.java
==============================================================================
--- (empty file)
+++ 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/CryptoService.java
        Tue Sep 28 11:55:16 2004
@@ -0,0 +1,167 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.kerberos.crypto;
+
+import org.apache.kerberos.crypto.checksum.*;
+import org.apache.kerberos.crypto.encryption.*;
+import org.apache.kerberos.kdc.*;
+import org.apache.kerberos.messages.value.*;
+import org.apache.kerberos.util.*;
+
+import java.util.*;
+
+public class CryptoService {
+
+       private static final Map _encryptionEngines = new HashMap();
+       private static final Map _checksumEngines   = new HashMap();
+       
+       // TODO - these maps are classic configuration and, as such, probably 
belong elsewhere
+       public CryptoService() {
+               _encryptionEngines.put(EncryptionType.NULL,        new 
NullEncryption());
+               _encryptionEngines.put(EncryptionType.DES_CBC_CRC, new 
DesCbcCrcEncryption());
+               _encryptionEngines.put(EncryptionType.DES_CBC_MD4, new 
DesCbcMd4Encryption());
+               _encryptionEngines.put(EncryptionType.DES_CBC_MD5, new 
DesCbcMd5Encryption());
+               
+               _checksumEngines.put(ChecksumType.CRC32,   new Crc32Checksum());
+               _checksumEngines.put(ChecksumType.RSA_MD4, new 
RsaMd4Checksum());
+               _checksumEngines.put(ChecksumType.RSA_MD5, new 
RsaMd5Checksum());
+               _checksumEngines.put(ChecksumType.SHA1,    new Sha1Checksum());
+       }
+
+       public static ChecksumEngine getInstance(ChecksumType type) throws 
KerberosException {
+               if (!_checksumEngines.containsKey(type))
+                       throw KerberosException.KDC_ERR_SUMTYPE_NOSUPP;
+               return (ChecksumEngine)_checksumEngines.get(type);
+       }
+       
+       public static EncryptionEngine getInstance(EncryptionType type) throws 
KerberosException {
+               if (!_encryptionEngines.containsKey(type))
+                       throw KerberosException.KDC_ERR_ETYPE_NOSUPP;
+               return (EncryptionEngine)_encryptionEngines.get(type);
+       }
+       
+       public static EncryptionType getBestEncryptionType(EncryptionType[] 
requestedTypes) {
+               
+               for (int i = 0; i < requestedTypes.length; i++) {
+                       for (int j = 0; j < 
LocalConfig.DEFAULT_ETYPE_LIST.length; j++) {
+                               if (requestedTypes[i] == 
LocalConfig.DEFAULT_ETYPE_LIST[j])
+                                       return 
LocalConfig.DEFAULT_ETYPE_LIST[j];
+                       }
+               }
+               return LocalConfig.DEFAULT_ETYPE;
+       }
+       
+       public static EncryptionKey getNewSessionKey() {
+               byte[] confounder = Confounder.bytes(8);
+               DesStringToKey subSessionKey = new DesStringToKey(new 
String(confounder));
+               return new EncryptionKey(EncryptionType.DES_CBC_MD5, 
subSessionKey.getKey());
+       }
+
+       public static byte[] getEncryptedTimestamp(EncryptionKey key, Date date)
+                       throws KerberosException {
+               EncryptionEngine encryptionEngine = 
getInstance(key.getKeyType());
+               byte[] plaintext = ConversionUtils.long2octet(date.getTime());
+               return encryptionEngine.encrypt(plaintext, key.getKeyValue());
+       }
+
+       public byte[] encrypt(EncryptionKey key, byte[] plaintext) throws 
KerberosException {
+               EncryptionEngine encryptionEngine = 
getInstance(key.getKeyType());
+               return encryptionEngine.encrypt(plaintext, key.getKeyValue());
+       }
+
+       public EncryptionKey getEncryptionKey(String username, String password, 
String realm) {
+               DesStringToKey key = new DesStringToKey(username, password, 
realm);
+               byte[] keyBytes = key.getKey();
+               return new EncryptionKey(EncryptionType.DES_CBC_MD5, keyBytes);
+       }
+
+       public byte[] decrypt(EncryptionKey key, EncryptedData data) throws 
KerberosException {
+               // TODO - check for matching encryptionType and keyVersion
+               EncryptionEngine type = getInstance(key.getKeyType());
+               
+               byte[] decTicketPart = type.decrypt(data.getCipherText(), 
key.getKeyValue());
+               
+               byte[] asn1ticket = removeBytes(decTicketPart, 
type.confounderSize(), type.checksumSize());
+               
+               return asn1ticket;
+       }
+       
+       public EncryptedData getEncryptedData(EncryptionKey key, byte[] 
plainText)
+                       throws KerberosException {
+               
+               EncryptionEngine type = getInstance(key.getKeyType());
+               
+               byte[] conFounder      = 
Confounder.bytes(type.confounderSize());
+               byte[] zeroedChecksum  = new byte[type.checksumSize()];
+               byte[] dataBytes       = concatenateBytes(conFounder, 
concatenateBytes(zeroedChecksum,
+                               padString(plainText)));
+               byte[] checksumBytes   = type.calculateChecksum(dataBytes);
+               byte[] paddedDataBytes = padString(dataBytes);
+               for (int i = type.confounderSize(); i < type.confounderSize() + 
type.checksumSize(); i++)
+                       paddedDataBytes[i] = checksumBytes[i - 
type.confounderSize()];
+               byte[] encryptedData   = encrypt(key, paddedDataBytes);
+               
+               return new EncryptedData(type.encryptionType(), 
key.getKeyVersion(), encryptedData);
+       }
+       
+       // TODO - The classes below are key production util code and I can 
picture them moving
+       //        to a key production base class when I add DES3 and/or AES 
support.
+       
+       private byte[] padString(byte encodedString[]) {
+               int x;
+               if (encodedString.length < 8)
+                       x = encodedString.length;
+               else
+                       x = encodedString.length % 8;
+
+               if (x == 0)
+                       return encodedString;
+
+               byte paddedByteArray[] = new byte[(8 - x) + 
encodedString.length];
+               for (int y = paddedByteArray.length - 1; y > 
encodedString.length - 1; y--)
+                       paddedByteArray[y] = 0;
+
+               System.arraycopy(encodedString, 0, paddedByteArray, 0, 
encodedString.length);
+
+               return paddedByteArray;
+       }
+
+       private byte[] concatenateBytes(byte[] array1, byte[] array2) {
+               byte concatenatedBytes[] = new byte[array1.length + 
array2.length];
+
+               for (int i = 0; i < array1.length; i++)
+                       concatenatedBytes[i] = array1[i];
+
+               for (int j = array1.length; j < concatenatedBytes.length; j++)
+                       concatenatedBytes[j] = array2[j - array1.length];
+
+               return concatenatedBytes;
+       }
+       
+       private byte[] removeBytes(byte[] array, int confounder, int checksum) {
+               byte lessBytes[] = new byte[array.length - confounder - 
checksum];
+               
+               int j = 0;
+               for (int i = confounder + checksum; i < array.length; i++) {
+                       lessBytes[j] = array[i];
+                       j++;
+               }
+
+               return lessBytes;
+       }
+}
+

Added: 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/DesStringToKey.java
==============================================================================
--- (empty file)
+++ 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/DesStringToKey.java
       Tue Sep 28 11:55:16 2004
@@ -0,0 +1,173 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.kerberos.crypto;
+
+import org.bouncycastle.crypto.engines.*;
+import org.bouncycastle.crypto.modes.*;
+import org.bouncycastle.crypto.params.*;
+
+public class DesStringToKey {
+       
+       private byte[] _desKey;
+       
+       public DesStringToKey(String passPhrase) {
+               _desKey = generateKey(passPhrase);
+       }
+       
+       // This is the concatenation order as designated in RFC 1510
+       public DesStringToKey(String password, String realmName, String 
userName) {
+               _desKey = generateKey(password + realmName + userName);
+       }
+       
+       public byte[] getKey() {
+               return _desKey;
+       }
+       
+       private byte[] generateKey(String passPhrase) {
+
+               byte encodedByteArray[] = characterEncodeString(passPhrase);
+
+               byte paddedByteArray[] = padString(encodedByteArray);
+
+               byte secretKey[] = fanFold(paddedByteArray);
+               
+               DESParameters.setOddParity(secretKey);
+               
+               if (DESParameters.isWeakKey(secretKey, 0))
+                       secretKey = getStrongKey(secretKey);
+
+               secretKey = encryptSecretKey(paddedByteArray, secretKey);
+
+               DESParameters.setOddParity(secretKey);
+
+               if (DESParameters.isWeakKey(secretKey, 0))
+                       secretKey = getStrongKey(secretKey);
+               
+               return secretKey;
+       }
+
+       private byte[] fanFold(byte[] paddedByteArray) {
+               
+               byte secretKey[] = new byte[8];
+               
+               int i = paddedByteArray.length / 8;
+
+               for (int x = 0; x < i; x++) {
+                       byte blockValue1[] = new byte[8];
+                       System.arraycopy(paddedByteArray, x * 8, blockValue1, 
0, 8);
+
+                       if (x % 2 == 1) {
+                               byte tempbyte1 = 0;
+                               byte tempbyte2 = 0;
+                               byte blockValue2[] = new byte[8];
+
+                               for (int y = 0; y < 8; y++) {
+                                       tempbyte2 = 0;
+                                       for (int z = 0; z < 4; z++) {
+                                               tempbyte2 = (byte) ((1 << (7 - 
z)) & 0xff);
+                                               tempbyte1 |= (blockValue1[y] & 
tempbyte2) >>> (7 - 2 * z);
+                                               tempbyte2 = 0;
+                                       }
+                                       for (int z = 4; z < 8; z++) {
+                                               tempbyte2 = (byte) ((1 << (7 - 
z)) & 0xff);
+                                               tempbyte1 |= (blockValue1[y] & 
tempbyte2) << (2 * z - 7);
+                                               tempbyte2 = 0;
+                                       }
+                                       blockValue2[7 - y] = tempbyte1;
+                                       tempbyte1 = 0;
+                               }
+
+                               for (int a = 0; a < 8; a++)
+                                       blockValue2[a] = (byte) 
(((blockValue2[a] & 0xff) >>> 1) & 0xff);
+
+                               System.arraycopy(blockValue2, 0, blockValue1, 
0, blockValue2.length);
+                       }
+
+                       for (int a = 0; a < 8; a++)
+                               blockValue1[a] = (byte) (((blockValue1[a] & 
0xff) << 1) & 0xff);
+                       
+                       // ... eXclusive-ORed with itself to form an 8-byte DES 
key
+                       for (int b = 0; b < 8; b++)
+                               secretKey[b] ^= blockValue1[b];
+               }
+               return secretKey;
+       }
+       
+       // TODO - Re-evaluate when DES3 keys are supported.  This is duplicated
+       //        with parts of CryptoService, but makes this class standalone.
+       private byte[] encryptSecretKey(byte data[], byte key[]) {
+               
+               CBCBlockCipher cipher = new CBCBlockCipher(new DESEngine());
+               KeyParameter kp = new KeyParameter(key);
+               ParametersWithIV iv;
+               
+               iv = new ParametersWithIV(kp, key);
+               cipher.init(true, iv);
+
+               byte encKey[] = new byte[data.length];
+               byte ivBytes[] = new byte[8];
+
+               for (int x = 0; x < data.length / 8; x++) {
+                       cipher.processBlock(data, x * 8, encKey, x * 8);
+                       System.arraycopy(encKey, x * 8, ivBytes, 0, 8);
+                       iv = new ParametersWithIV(kp, ivBytes);
+                       cipher.init(true, iv);
+               }
+
+               return ivBytes;
+       }
+
+       // Corrects the weak key by exclusive OR with 0xF0 constant.
+       private byte[] getStrongKey(byte keyValue[]) {
+               keyValue[7] ^= 0xf0;
+               return keyValue;
+       }
+
+       // Encodes string with ISO-Latin encoding
+       private byte[] characterEncodeString(String str) {
+               byte encodedByteArray[] = new byte[str.length()];
+               try {
+                       encodedByteArray = str.getBytes("8859_1");
+               } catch (java.io.UnsupportedEncodingException ue) {
+               }
+               return encodedByteArray;
+       }
+
+       // Add padding to make an exact multiple of 8.
+       // TODO - Re-evaluate when DES3 keys are supported.  This is duplicated
+       //        with parts of CryptoService, but makes this class standalone.
+       private byte[] padString(byte encodedString[]) {
+               int x;
+               if (encodedString.length < 8)
+                       x = encodedString.length;
+               else
+                       x = encodedString.length % 8;
+
+               if (x == 0)
+                       return encodedString;
+
+               byte paddedByteArray[] = new byte[(8 - x) + 
encodedString.length];
+               for (int y = paddedByteArray.length - 1; y > 
encodedString.length - 1; y--)
+                       paddedByteArray[y] = 0;
+
+               System.arraycopy(encodedString, 0, paddedByteArray, 0, 
encodedString.length);
+
+               return paddedByteArray;
+
+       }
+}
+

Added: 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/GlobalSequenceNumber.java
==============================================================================
--- (empty file)
+++ 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/GlobalSequenceNumber.java
 Tue Sep 28 11:55:16 2004
@@ -0,0 +1,43 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.kerberos.crypto;
+
+public class GlobalSequenceNumber implements SequenceNumber {
+
+       private int _sequenceNumber = Confounder.intValue();
+
+       public GlobalSequenceNumber(int start) {
+               _sequenceNumber = start;
+       }
+       
+       public synchronized void init() {
+               _sequenceNumber = Confounder.intValue();
+       }
+       
+       public synchronized int current() {
+               return _sequenceNumber;
+       }
+
+       public synchronized int next() {
+               return _sequenceNumber + 1;
+       }
+       
+       public synchronized void step() {
+               _sequenceNumber++;
+       }
+}
+

Added: 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/Nonce.java
==============================================================================
--- (empty file)
+++ 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/Nonce.java
        Tue Sep 28 11:55:16 2004
@@ -0,0 +1,32 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.kerberos.crypto;
+
+public class Nonce {
+       
+       private static int _nonce;
+
+       public static synchronized int getValue() {
+               int temp = (int)(System.currentTimeMillis() / 1000);
+               if (temp <= _nonce)
+                       _nonce++;
+               else
+                   _nonce = temp;
+               return _nonce;
+       }
+}
+

Added: 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/SequenceNumber.java
==============================================================================
--- (empty file)
+++ 
incubator/directory/kerberos/trunk/source/java/org/apache/kerberos/crypto/SequenceNumber.java
       Tue Sep 28 11:55:16 2004
@@ -0,0 +1,45 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.kerberos.crypto;
+
+/**
+ * Sequence number 
+ */
+public interface SequenceNumber {
+
+       /**
+        * Random initialization
+        */
+       public void init();
+       
+       /**
+        * Returns current value
+        */
+       public int current();
+       
+       /**
+        * Returns next value
+        */
+       public int next();
+       
+       /**
+        * Increments the value
+        */
+       public void step();
+
+}
+

Reply via email to