diff options
Diffstat (limited to 'protocols/bundles/org.eclipse.ecf.protocol.msn/src/org/eclipse/ecf/protocol/msn/internal/encode/Challenge.java')
-rw-r--r-- | protocols/bundles/org.eclipse.ecf.protocol.msn/src/org/eclipse/ecf/protocol/msn/internal/encode/Challenge.java | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/protocols/bundles/org.eclipse.ecf.protocol.msn/src/org/eclipse/ecf/protocol/msn/internal/encode/Challenge.java b/protocols/bundles/org.eclipse.ecf.protocol.msn/src/org/eclipse/ecf/protocol/msn/internal/encode/Challenge.java new file mode 100644 index 000000000..2a7b2a24a --- /dev/null +++ b/protocols/bundles/org.eclipse.ecf.protocol.msn/src/org/eclipse/ecf/protocol/msn/internal/encode/Challenge.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 Remy Suen + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Remy Suen <remy.suen@gmail.com> - initial API and implementation + ******************************************************************************/ +package org.eclipse.ecf.protocol.msn.internal.encode; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public final class Challenge { + + public static final String PRODUCT_ID = "PROD0090YUAUV{2B"; //$NON-NLS-1$ + + private static final String PRODUCT_KEY = "YMM8C_H7KCQ2S_KL"; //$NON-NLS-1$ + + private static MessageDigest instance; + + static { + try { + instance = MessageDigest.getInstance("MD5"); //$NON-NLS-1$ + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("No MD5 digest found"); + } + } + + public static String createQuery(String challenge) { + String[] s = computeMD5DigestAsStringArray((challenge + PRODUCT_KEY) + .getBytes()); + String md5Hash = computeMD5Digest((challenge + PRODUCT_KEY).getBytes()); + int[] md5 = new int[4]; + for (int i = 0; i < 4; i++) { + md5[i] = Integer.parseInt(s[i], 16); + } + + String chl = challenge + PRODUCT_ID; + while (chl.length() % 8 != 0) { + chl += '0'; + } + + char[] array = chl.toCharArray(); + String[] values = new String[chl.length() / 4]; + for (int i = 0; i < array.length; i += 4) { + int j = array[i + 3]; + String value = Integer.toHexString(j); + j = array[i + 2]; + value += Integer.toHexString(j); + j = array[i + 1]; + value += Integer.toHexString(j); + j = array[i]; + value += Integer.toHexString(j); + values[i / 4] = value; + } + + int[] ints = new int[values.length]; + for (int i = 0; i < values.length; i++) { + ints[i] = Integer.parseInt(values[i], 16); + } + + long high = 0; + long low = 0; + for (int i = 0; i < ints.length; i += 2) { + long temp = ints[i]; + temp = (temp * 0xe79a9c1L) % 0x7fffffff; + temp += high; + temp = md5[0] * temp + md5[1]; + temp = temp % 0x7fffffff; + + high = ints[i + 1]; + high = (high + temp) % 0x7fffffff; + high = md5[2] * high + md5[3]; + high = high % 0x7fffffff; + + low = low + high + temp; + } + + high = (high + md5[1]) % 0x7fffffff; + low = (low + md5[3]) % 0x7fffffff; + + String highString = Long.toHexString(high); + String lowString = Long.toHexString(low); + + while (highString.length() < 8) { + highString = '0' + highString; + } + + while (lowString.length() < 8) { + lowString = '0' + lowString; + } + + highString = highString.substring(6, 8) + highString.substring(4, 6) + + highString.substring(2, 4) + highString.substring(0, 2); + lowString = lowString.substring(6, 8) + lowString.substring(4, 6) + + lowString.substring(2, 4) + lowString.substring(0, 2); + + high = Long.parseLong(highString, 16); + low = Long.parseLong(lowString, 16); + + String first = Long.toHexString((Long.parseLong( + md5Hash.substring(0, 8), 16) ^ high)); + String second = Long.toHexString((Long.parseLong(md5Hash.substring(8, + 16), 16) ^ low)); + String third = Long.toHexString((Long.parseLong(md5Hash.substring(16, + 24), 16) ^ high)); + String fourth = Long.toHexString((Long.parseLong(md5Hash.substring(24, + 32), 16) ^ low)); + + while (first.length() < 8) { + first = '0' + first; + } + + while (second.length() < 8) { + second = '0' + second; + } + + while (third.length() < 8) { + third = '0' + third; + } + + while (fourth.length() < 8) { + fourth = '0' + fourth; + } + + return first + second + third + fourth; + } + + /** + * Computes the MD5 digest of a string given its bytes. + * + * @param bytes + * the bytes of the string to be digested + * @return the MD5 digest of the original string + */ + private static final String computeMD5Digest(byte[] bytes) { + byte[] hash = instance.digest(bytes); + StringBuffer buffer = new StringBuffer(); + synchronized (buffer) { + for (int i = 0; i < hash.length; i++) { + int value = 0xff & hash[i]; + if (value < 16) { + buffer.append('0').append(Integer.toHexString(value)); + } else { + buffer.append(Integer.toHexString(value)); + } + } + return buffer.toString(); + } + } + + private static final String[] computeMD5DigestAsStringArray(byte[] bytes) { + byte[] hash = instance.digest(bytes); + StringBuffer buffer = new StringBuffer(); + synchronized (buffer) { + for (int i = 0; i < hash.length; i++) { + int value = 0xff & hash[i]; + if (value < 16) { + buffer.append('0').append(Integer.toHexString(value)); + } else { + buffer.append(Integer.toHexString(value)); + } + } + } + + String result = buffer.toString(); + String[] results = new String[4]; + results[0] = result.substring(0, 8); + results[1] = result.substring(8, 16); + results[2] = result.substring(16, 24); + results[3] = result.substring(24, 32); + + for (int i = 0; i < 4; i++) { + char[] array = results[i].toCharArray(); + char[] swapped = new char[8]; + for (int j = 0; j < 8; j += 2) { + swapped[7 - j] = array[j + 1]; + swapped[6 - j] = array[j]; + } + results[i] = new String(swapped); + } + + for (int i = 0; i < 4; i++) { + long l = Long.parseLong(results[i], 16); + l = l & 0x7fffffff; + if (l < 0x10000000) { + results[i] = '0' + Long.toHexString(l); + } else { + results[i] = Long.toHexString(l); + } + } + + return results; + } +} |