/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.ssh;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import org.eclipse.osgi.util.NLS;

class Misc {
	private static MessageDigest md5 = null;
	private static SecureRandom random = null;
	private static long crc32_tab[] = {
		0x00000000L,
		0x77073096L,
		0xee0e612cL,
		0x990951baL,
		0x076dc419L,
		0x706af48fL,
		0xe963a535L,
		0x9e6495a3L,
		0x0edb8832L,
		0x79dcb8a4L,
		0xe0d5e91eL,
		0x97d2d988L,
		0x09b64c2bL,
		0x7eb17cbdL,
		0xe7b82d07L,
		0x90bf1d91L,
		0x1db71064L,
		0x6ab020f2L,
		0xf3b97148L,
		0x84be41deL,
		0x1adad47dL,
		0x6ddde4ebL,
		0xf4d4b551L,
		0x83d385c7L,
		0x136c9856L,
		0x646ba8c0L,
		0xfd62f97aL,
		0x8a65c9ecL,
		0x14015c4fL,
		0x63066cd9L,
		0xfa0f3d63L,
		0x8d080df5L,
		0x3b6e20c8L,
		0x4c69105eL,
		0xd56041e4L,
		0xa2677172L,
		0x3c03e4d1L,
		0x4b04d447L,
		0xd20d85fdL,
		0xa50ab56bL,
		0x35b5a8faL,
		0x42b2986cL,
		0xdbbbc9d6L,
		0xacbcf940L,
		0x32d86ce3L,
		0x45df5c75L,
		0xdcd60dcfL,
		0xabd13d59L,
		0x26d930acL,
		0x51de003aL,
		0xc8d75180L,
		0xbfd06116L,
		0x21b4f4b5L,
		0x56b3c423L,
		0xcfba9599L,
		0xb8bda50fL,
		0x2802b89eL,
		0x5f058808L,
		0xc60cd9b2L,
		0xb10be924L,
		0x2f6f7c87L,
		0x58684c11L,
		0xc1611dabL,
		0xb6662d3dL,
		0x76dc4190L,
		0x01db7106L,
		0x98d220bcL,
		0xefd5102aL,
		0x71b18589L,
		0x06b6b51fL,
		0x9fbfe4a5L,
		0xe8b8d433L,
		0x7807c9a2L,
		0x0f00f934L,
		0x9609a88eL,
		0xe10e9818L,
		0x7f6a0dbbL,
		0x086d3d2dL,
		0x91646c97L,
		0xe6635c01L,
		0x6b6b51f4L,
		0x1c6c6162L,
		0x856530d8L,
		0xf262004eL,
		0x6c0695edL,
		0x1b01a57bL,
		0x8208f4c1L,
		0xf50fc457L,
		0x65b0d9c6L,
		0x12b7e950L,
		0x8bbeb8eaL,
		0xfcb9887cL,
		0x62dd1ddfL,
		0x15da2d49L,
		0x8cd37cf3L,
		0xfbd44c65L,
		0x4db26158L,
		0x3ab551ceL,
		0xa3bc0074L,
		0xd4bb30e2L,
		0x4adfa541L,
		0x3dd895d7L,
		0xa4d1c46dL,
		0xd3d6f4fbL,
		0x4369e96aL,
		0x346ed9fcL,
		0xad678846L,
		0xda60b8d0L,
		0x44042d73L,
		0x33031de5L,
		0xaa0a4c5fL,
		0xdd0d7cc9L,
		0x5005713cL,
		0x270241aaL,
		0xbe0b1010L,
		0xc90c2086L,
		0x5768b525L,
		0x206f85b3L,
		0xb966d409L,
		0xce61e49fL,
		0x5edef90eL,
		0x29d9c998L,
		0xb0d09822L,
		0xc7d7a8b4L,
		0x59b33d17L,
		0x2eb40d81L,
		0xb7bd5c3bL,
		0xc0ba6cadL,
		0xedb88320L,
		0x9abfb3b6L,
		0x03b6e20cL,
		0x74b1d29aL,
		0xead54739L,
		0x9dd277afL,
		0x04db2615L,
		0x73dc1683L,
		0xe3630b12L,
		0x94643b84L,
		0x0d6d6a3eL,
		0x7a6a5aa8L,
		0xe40ecf0bL,
		0x9309ff9dL,
		0x0a00ae27L,
		0x7d079eb1L,
		0xf00f9344L,
		0x8708a3d2L,
		0x1e01f268L,
		0x6906c2feL,
		0xf762575dL,
		0x806567cbL,
		0x196c3671L,
		0x6e6b06e7L,
		0xfed41b76L,
		0x89d32be0L,
		0x10da7a5aL,
		0x67dd4accL,
		0xf9b9df6fL,
		0x8ebeeff9L,
		0x17b7be43L,
		0x60b08ed5L,
		0xd6d6a3e8L,
		0xa1d1937eL,
		0x38d8c2c4L,
		0x4fdff252L,
		0xd1bb67f1L,
		0xa6bc5767L,
		0x3fb506ddL,
		0x48b2364bL,
		0xd80d2bdaL,
		0xaf0a1b4cL,
		0x36034af6L,
		0x41047a60L,
		0xdf60efc3L,
		0xa867df55L,
		0x316e8eefL,
		0x4669be79L,
		0xcb61b38cL,
		0xbc66831aL,
		0x256fd2a0L,
		0x5268e236L,
		0xcc0c7795L,
		0xbb0b4703L,
		0x220216b9L,
		0x5505262fL,
		0xc5ba3bbeL,
		0xb2bd0b28L,
		0x2bb45a92L,
		0x5cb36a04L,
		0xc2d7ffa7L,
		0xb5d0cf31L,
		0x2cd99e8bL,
		0x5bdeae1dL,
		0x9b64c2b0L,
		0xec63f226L,
		0x756aa39cL,
		0x026d930aL,
		0x9c0906a9L,
		0xeb0e363fL,
		0x72076785L,
		0x05005713L,
		0x95bf4a82L,
		0xe2b87a14L,
		0x7bb12baeL,
		0x0cb61b38L,
		0x92d28e9bL,
		0xe5d5be0dL,
		0x7cdcefb7L,
		0x0bdbdf21L,
		0x86d3d2d4L,
		0xf1d4e242L,
		0x68ddb3f8L,
		0x1fda836eL,
		0x81be16cdL,
		0xf6b9265bL,
		0x6fb077e1L,
		0x18b74777L,
		0x88085ae6L,
		0xff0f6a70L,
		0x66063bcaL,
		0x11010b5cL,
		0x8f659effL,
		0xf862ae69L,
		0x616bffd3L,
		0x166ccf45L,
		0xa00ae278L,
		0xd70dd2eeL,
		0x4e048354L,
		0x3903b3c2L,
		0xa7672661L,
		0xd06016f7L,
		0x4969474dL,
		0x3e6e77dbL,
		0xaed16a4aL,
		0xd9d65adcL,
		0x40df0b66L,
		0x37d83bf0L,
		0xa9bcae53L,
		0xdebb9ec5L,
		0x47b2cf7fL,
		0x30b5ffe9L,
		0xbdbdf21cL,
		0xcabac28aL,
		0x53b39330L,
		0x24b4a3a6L,
		0xbad03605L,
		0xcdd70693L,
		0x54de5729L,
		0x23d967bfL,
		0xb3667a2eL,
		0xc4614ab8L,
		0x5d681b02L,
		0x2a6f2b94L,
		0xb40bbe37L,
		0xc30c8ea1L,
		0x5a05df1bL,
		0x2d02ef8dL
	};
static public long crc32(byte[] b, int off, int len) {
	return crc32(b, off, len, 0);
}
/**
 * Compute the crc	Cyclic Redundancy Check, with the polynomial 0xedb88320,
 * The polynomial is X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
 *  We take it "backwards" and put the highest-order term in the lowest-order bit. 
 * The X^32 term is "implied"; the LSB is the X^31 term, etc.  
 * The X^0 term (usually shown as "+1") results in the MSB being 1.
 * so the poly is 0x04c11db7 (used for Ethernet)
 * The buf will be the Padding, Packet type, and Data fields. 
 * The crc is computed before any encryption.
 * R =X^n * M rem P		M message		P polynomial crc	R : crc calculated.
 * T(x) = x^n * M(x)  +  R(x)	property: T rem P = 0
 */
static public long crc32(byte[] b, int off, int len, long crc32val) {
	for (int i = 0; i < len; i++) {
		crc32val = crc32_tab[(int) ((crc32val ^ b[off + i]) & 0xff)] ^ (crc32val >> 8);
	}

	return crc32val;
}
static public byte[] lengthEncode(byte[] b, int off, int len) {
	byte[] result = new byte[len + 4];
	writeInt(len, result, 0);
	System.arraycopy(b, off, result, 4, len);
	return result;
}
static public byte[] readMpInt(InputStream is) throws IOException {
	int a = is.read();
	int b = is.read();

	if(a == -1 || b == -1){
		throw new IOException(CVSSSHMessages.stream);
	}

	int bits = ((a & 0xFF) << 8) + (b & 0xFF);
	int bytes = (bits + 7) / 8;

	byte[] result = new byte[bytes];

	readFully(is, result);

	return result;
}
public static byte[] md5(byte[] b) throws IOException {
	if (md5 == null) {
		try {
			md5 = MessageDigest.getInstance("MD5");//$NON-NLS-1$
		} catch (NoSuchAlgorithmException e) {
			throw new IOException(NLS.bind(CVSSSHMessages.Misc_missingMD5, new String[] { e.getMessage() })); 
		}
	}

	return md5.digest(b);
}
public static byte[] md5(String s) throws IOException {
	return md5(s.getBytes());
}
public static void readFully(InputStream is, byte[] b) throws IOException {
	readFully(is, b, 0, b.length);
}
public static void readFully(InputStream is, byte[] b, int off, int len) throws IOException {
	int bytesRead = 0;
	int totalBytesRead = 0;

	while (totalBytesRead < len) {
		bytesRead = is.read(b, totalBytesRead + off, len - totalBytesRead);

		if (bytesRead == -1) {
			throw new IOException(CVSSSHMessages.stream);
		}

		totalBytesRead += bytesRead;
	}
}
public static int readInt(byte[] arr, int off) {
	int a = arr[off] & 0xff;
	int b = arr[off + 1] & 0xff;
	int c = arr[off + 2] & 0xff;
	int d = arr[off + 3] & 0xff;

	return (a << 24) + (b << 16) + (c << 8) + d;
}
public static int readInt(InputStream is) throws IOException {
	int a = is.read();
	int b = is.read();
	int c = is.read();
	int d = is.read();

	if (a == -1 || b == -1 || c == -1 || d == -1) {
		throw new IOException(CVSSSHMessages.stream);
	}

	return (a << 24) + (b << 16) + (c << 8) + d;
}
public static String readString(InputStream is) throws IOException {
	int size = Misc.readInt(is);
	byte[] buffer = new byte[size];
	for (int i = 0; i < buffer.length; i++) {
		int next = is.read();
		if (next == -1) {
			throw new IOException(CVSSSHMessages.stream); 
		} else {
			buffer[i] = (byte)next;
		}
	}
	return new String(buffer);
}
public static void skipFully(InputStream is, long n) throws IOException {
	while (n != 0) {
		int b = is.read();

		if (b == -1) {
			if (n > 0) {
				throw new IOException(CVSSSHMessages.stream);
			}

			return;
		}

		--n;
	}
}
public static void writeInt(int i, byte[] b, int off) {
	b[off] = (byte) ((i >> 24) & 0xff);
	b[off + 1] = (byte) ((i >> 16) & 0xff);
	b[off + 2] = (byte) ((i >> 8) & 0xff);
	b[off + 3] = (byte) (i & 0xff);
}
static public void xor(byte[] src_a, int off_a, byte[] src_b, int off_b, byte[] dst, int dst_off, int len) {
	for(int i = 0; i < len; ++i){
		dst[i + dst_off] = (byte) (src_a[i + off_a] ^ src_b[i + off_b]);
	}
}
static public void random(byte[] b, int off, int len, boolean allowZeroBytes) {
	if (random == null) {
		try {
			random = SecureRandom.getInstance("SHA1PRNG");//$NON-NLS-1$
		} catch (NoSuchAlgorithmException e) {
			// If SHA1PRNG is not available, just use the default
			random = new SecureRandom();
		}
	}

	for(int i = off; i < off + len; ++i){
		do {
			b[i] = (byte) random.nextInt();
		} while(!allowZeroBytes && b[i] == 0);
	}
}
static public byte[] encryptRSAPkcs1(byte[] data, byte[] public_key_exponent, byte[] public_key_modulus) {
	byte[] block;

	int offset = 0;
	block = new byte[public_key_modulus.length];
	block[offset++] = 0;
	block[offset++] = 2;

	Misc.random(block, offset, block.length - data.length - 3, false);
	offset += block.length - data.length - 3;

	block[offset++] = 0;

	for (int i = 0; i < data.length; i++){
		block[offset++] = data[i];
	}

	BigInteger m, e, message;
	byte[] messageByte;

	m = new BigInteger(1, public_key_modulus);
	e = new BigInteger(1, public_key_exponent);
	message = new BigInteger(1, block);
	message = message.modPow(e, m);

	byte[] messageByteTemp = message.toByteArray();
	messageByte = new byte[public_key_modulus.length];

	int tempOffset = 0;
	while (messageByteTemp[tempOffset] == 0){
		tempOffset++;
	}

	for (int i = messageByte.length - messageByteTemp.length + tempOffset; i < messageByte.length; i++){
		messageByte[i] = messageByteTemp[tempOffset++];
	}

	return messageByte;
}
}
