Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
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.java198
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;
+ }
+}

Back to the top