private void checkMAC(final byte[] data) throws TransportException { mac.update(seq); // seq num mac.update(data, 0, packetLength + 4); // packetLength+4 = entire packet w/o mac mac.doFinal(macResult, 0); // compute // Check against the received MAC if (!ByteArrayUtils.equals(macResult, 0, data, packetLength + 4, mac.getBlockSize())) { throw new TransportException(DisconnectReason.MAC_ERROR, "MAC Error"); } }
private String readIdentification(Buffer.PlainBuffer lineBuffer) throws Buffer.BufferException, TransportException { byte[] bytes = new byte[lineBuffer.available()]; lineBuffer.readRawBytes(bytes); if (bytes.length > 255) { log.error("Incorrect identification String received, line was longer than expected: {}", new String(bytes)); log.error("Just for good measure, bytes were: {}", ByteArrayUtils.printHex(bytes, 0, bytes.length)); throw new TransportException("Incorrect identification: line too long: " + ByteArrayUtils.printHex(bytes, 0, bytes.length)); } if (bytes[bytes.length - 2] != '\r') { String ident = new String(bytes, 0, bytes.length - 1); log.warn("Server identification has bad line ending, was expecting a '\\r\\n' however got: '{}' (hex: {})", (char) (bytes[bytes.length - 2] & 0xFF), Integer.toHexString(bytes[bytes.length - 2] & 0xFF)); log.warn("Will treat the identification of this server '{}' leniently", ident); return ident; // log.error("Data received up til here was: {}", new String(bytes)); // throw new TransportException("Incorrect identification: bad line ending: " + ByteArrayUtils.toHex(bytes, 0, bytes.length)); } // Strip off the \r\n return new String(bytes, 0, bytes.length - 2); }
/** * Get the hexadecimal representation of a byte array. * * @param array * * @return hex string */ public static String toHex(byte[] array) { return toHex(array, 0, array.length); }
public static byte[] parseHex(String hex) { if (hex == null) { throw new IllegalArgumentException("Hex string is null"); } if (hex.length() % 2 != 0) { throw new IllegalArgumentException("Hex string '" + hex + "' should have even length."); } byte[] result = new byte[hex.length() / 2]; for (int i = 0; i < result.length; i++) { int hi = parseHexDigit(hex.charAt(i * 2)) << 4; int lo = parseHexDigit(hex.charAt(i * 2 + 1)); result[i] = (byte) (hi + lo); } return result; }
throw new FormatException("Not a supported algorithm: " + algorithm); iv = Arrays.copyOfRange(ByteArrayUtils.parseHex(line.substring(ptr + 1)), 0, cipher.getIVSize());
public static byte[] parseHex(String hex) { if (hex == null) { throw new IllegalArgumentException("Hex string is null"); } if (hex.length() % 2 != 0) { throw new IllegalArgumentException("Hex string '" + hex + "' should have even length."); } byte[] result = new byte[hex.length() / 2]; for (int i = 0; i < result.length; i++) { int hi = parseHexDigit(hex.charAt(i * 2)) << 4; int lo = parseHexDigit(hex.charAt(i * 2 + 1)); result[i] = (byte) (hi + lo); } return result; }
throw new FormatException("Not a supported algorithm: " + algorithm); iv = Arrays.copyOfRange(ByteArrayUtils.parseHex(line.substring(ptr + 1)), 0, cipher.getIVSize());
/** * Gives a readable snapshot of the buffer in hex. This is useful for debugging. * * @return snapshot of the buffer as a hex string with each octet delimited by a space */ public String printHex() { return ByteArrayUtils.printHex(array(), rpos(), available()); }
/** * Computes the fingerprint for a public key, in the standard SSH format, e.g. "4b:69:6c:72:6f:79:20:77:61:73:20:68:65:72:65:21" * * @param key the public key * @return the fingerprint * @see <a href="http://tools.ietf.org/html/draft-friedl-secsh-fingerprint-00">specification</a> */ public static String getFingerprint(PublicKey key) { MessageDigest md5; try { md5 = getMessageDigest("MD5"); } catch (GeneralSecurityException e) { throw new SSHRuntimeException(e); } md5.update(new Buffer.PlainBuffer().putPublicKey(key).getCompactData()); final String undelimited = ByteArrayUtils.toHex(md5.digest()); assert undelimited.length() == 32 : "md5 contract"; StringBuilder fp = new StringBuilder(undelimited.substring(0, 2)); for (int i = 2; i <= undelimited.length() - 2; i += 2) fp.append(":").append(undelimited.substring(i, i + 2)); return fp.toString(); }
private KeyPair readDecodedKeyPair(final PlainBuffer keyBuffer) throws IOException, GeneralSecurityException { byte[] bytes = new byte[AUTH_MAGIC.length]; keyBuffer.readRawBytes(bytes); // byte[] AUTH_MAGIC if (!ByteArrayUtils.equals(bytes, 0, AUTH_MAGIC, 0, AUTH_MAGIC.length)) { throw new IOException("This key does not contain the 'openssh-key-v1' format magic header"); } String cipherName = keyBuffer.readString(); // string ciphername String kdfName = keyBuffer.readString(); // string kdfname byte[] kdfOptions = keyBuffer.readBytes(); // string kdfoptions int nrKeys = keyBuffer.readUInt32AsInt(); // int number of keys N; Should be 1 if (nrKeys != 1) { throw new IOException("We don't support having more than 1 key in the file (yet)."); } PublicKey publicKey = readPublicKey(new PlainBuffer(keyBuffer.readBytes())); // string publickey1 PlainBuffer privateKeyBuffer = new PlainBuffer(keyBuffer.readBytes()); // string (possibly) encrypted, padded list of private keys if ("none".equals(cipherName)) { logger.debug("Reading unencrypted keypair"); return readUnencrypted(privateKeyBuffer, publicKey); } else { logger.info("Keypair is encrypted with: " + cipherName + ", " + kdfName + ", " + Arrays.toString(kdfOptions)); PlainBuffer decrypted = decryptBuffer(privateKeyBuffer, cipherName, kdfName, kdfOptions); return readUnencrypted(decrypted, publicKey); // throw new IOException("Cannot read encrypted keypair with " + cipherName + " yet."); } }
protected void receiveInto(ChannelInputStream stream, SSHPacket buf) throws ConnectionException, TransportException { final int len; try { len = buf.readUInt32AsInt(); } catch (Buffer.BufferException be) { throw new ConnectionException(be); } if (len < 0 || len > getLocalMaxPacketSize() || len > buf.available()) { throw new ConnectionException(DisconnectReason.PROTOCOL_ERROR, "Bad item length: " + len); } if (log.isTraceEnabled()) { log.trace("IN #{}: {}", id, ByteArrayUtils.printHex(buf.array(), buf.rpos(), len)); } stream.receive(buf.array(), buf.rpos(), len); }
/** * Get the hexadecimal representation of a byte array. * * @param array * * @return hex string */ public static String toHex(byte[] array) { return toHex(array, 0, array.length); }
private void checkMAC(final byte[] data) throws TransportException { mac.update(seq); // seq num mac.update(data, 0, packetLength + 4); // packetLength+4 = entire packet w/o mac mac.doFinal(macResult, 0); // compute // Check against the received MAC if (!ByteArrayUtils.equals(macResult, 0, data, packetLength + 4, mac.getBlockSize())) throw new TransportException(DisconnectReason.MAC_ERROR, "MAC Error"); }
private String readIdentification(Buffer.PlainBuffer lineBuffer) throws Buffer.BufferException, TransportException { byte[] bytes = new byte[lineBuffer.available()]; lineBuffer.readRawBytes(bytes); if (bytes.length > 255) { log.error("Incorrect identification String received, line was longer than expected: {}", new String(bytes)); log.error("Just for good measure, bytes were: {}", ByteArrayUtils.printHex(bytes, 0, bytes.length)); throw new TransportException("Incorrect identification: line too long: " + ByteArrayUtils.printHex(bytes, 0, bytes.length)); } if (bytes[bytes.length - 2] != '\r') { String ident = new String(bytes, 0, bytes.length - 1); log.warn("Server identification has bad line ending, was expecting a '\\r\\n' however got: '{}' (hex: {})", (char) (bytes[bytes.length - 2] & 0xFF), Integer.toHexString(bytes[bytes.length - 2] & 0xFF)); log.warn("Will treat the identification of this server '{}' leniently", ident); return ident; // log.error("Data received up til here was: {}", new String(bytes)); // throw new TransportException("Incorrect identification: bad line ending: " + ByteArrayUtils.toHex(bytes, 0, bytes.length)); } // Strip off the \r\n return new String(bytes, 0, bytes.length - 2); }
/** * Get the hexadecimal representation of a byte array. * * @param array * * @return hex string */ public static String toHex(byte[] array) { return toHex(array, 0, array.length); }
private void checkMAC(final byte[] data) throws TransportException { mac.update(seq); // seq num mac.update(data, 0, packetLength + 4); // packetLength+4 = entire packet w/o mac mac.doFinal(macResult, 0); // compute // Check against the received MAC if (!ByteArrayUtils.equals(macResult, 0, data, packetLength + 4, mac.getBlockSize())) { throw new TransportException(DisconnectReason.MAC_ERROR, "MAC Error"); } }
/** * Gives a readable snapshot of the buffer in hex. This is useful for debugging. * * @return snapshot of the buffer as a hex string with each octet delimited by a space */ public String printHex() { return ByteArrayUtils.printHex(array(), rpos(), available()); }
/** * Computes the fingerprint for a public key, in the standard SSH format, e.g. "4b:69:6c:72:6f:79:20:77:61:73:20:68:65:72:65:21" * * @param key the public key * @return the fingerprint * @see <a href="http://tools.ietf.org/html/draft-friedl-secsh-fingerprint-00">specification</a> */ public static String getFingerprint(PublicKey key) { MessageDigest md5; try { md5 = getMessageDigest("MD5"); } catch (GeneralSecurityException e) { throw new SSHRuntimeException(e); } md5.update(new Buffer.PlainBuffer().putPublicKey(key).getCompactData()); final String undelimited = ByteArrayUtils.toHex(md5.digest()); assert undelimited.length() == 32 : "md5 contract"; StringBuilder fp = new StringBuilder(undelimited.substring(0, 2)); for (int i = 2; i <= undelimited.length() - 2; i += 2) fp.append(":").append(undelimited.substring(i, i + 2)); return fp.toString(); }
private KeyPair readDecodedKeyPair(final PlainBuffer keyBuffer) throws IOException, GeneralSecurityException { byte[] bytes = new byte[AUTH_MAGIC.length]; keyBuffer.readRawBytes(bytes); // byte[] AUTH_MAGIC if (!ByteArrayUtils.equals(bytes, 0, AUTH_MAGIC, 0, AUTH_MAGIC.length)) { throw new IOException("This key does not contain the 'openssh-key-v1' format magic header"); } String cipherName = keyBuffer.readString(); // string ciphername String kdfName = keyBuffer.readString(); // string kdfname byte[] kdfOptions = keyBuffer.readBytes(); // string kdfoptions int nrKeys = keyBuffer.readUInt32AsInt(); // int number of keys N; Should be 1 if (nrKeys != 1) { throw new IOException("We don't support having more than 1 key in the file (yet)."); } PublicKey publicKey = readPublicKey(new PlainBuffer(keyBuffer.readBytes())); // string publickey1 PlainBuffer privateKeyBuffer = new PlainBuffer(keyBuffer.readBytes()); // string (possibly) encrypted, padded list of private keys if ("none".equals(cipherName)) { logger.debug("Reading unencrypted keypair"); return readUnencrypted(privateKeyBuffer, publicKey); } else { logger.info("Keypair is encrypted with: " + cipherName + ", " + kdfName + ", " + Arrays.toString(kdfOptions)); PlainBuffer decrypted = decryptBuffer(privateKeyBuffer, cipherName, kdfName, kdfOptions); return readUnencrypted(decrypted, publicKey); // throw new IOException("Cannot read encrypted keypair with " + cipherName + " yet."); } }
/** * Gives a readable snapshot of the buffer in hex. This is useful for debugging. * * @return snapshot of the buffer as a hex string with each octet delimited by a space */ public String printHex() { return ByteArrayUtils.printHex(array(), rpos(), available()); }