| /******************************************************************************* |
| * 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; |
| } |
| } |