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); }
private void logHeaderLine(Buffer.PlainBuffer lineBuffer) throws Buffer.BufferException { byte[] bytes = new byte[lineBuffer.available()]; lineBuffer.readRawBytes(bytes); String header = new String(bytes, 0, bytes.length - 1); log.debug("Received header: {}", header); }
private boolean checkForIdentification(Buffer.PlainBuffer lineBuffer) throws Buffer.BufferException { if (lineBuffer.available() < 4) { return false; } byte[] buf = new byte[4]; lineBuffer.readRawBytes(buf); // Reset lineBuffer.rpos(0); return Arrays.equals(EXPECTED_START_BYTES, buf); } }
private String getKeyString(PublicKey pk) { final Buffer.PlainBuffer buf = new Buffer.PlainBuffer().putPublicKey(pk); return Base64.encodeBytes(buf.array(), buf.rpos(), buf.available()); }
private boolean checkForIdentification(Buffer.PlainBuffer lineBuffer) throws Buffer.BufferException { if (lineBuffer.available() < 4) { return false; } byte[] buf = new byte[4]; lineBuffer.readRawBytes(buf); // Reset lineBuffer.rpos(0); return Arrays.equals(EXPECTED_START_BYTES, buf); } }
private PlainBuffer decryptBuffer(PlainBuffer privateKeyBuffer, String cipherName, String kdfName, byte[] kdfOptions) throws IOException { Cipher cipher = createCipher(cipherName); initializeCipher(kdfName, kdfOptions, cipher); byte[] array = privateKeyBuffer.array(); cipher.update(array, 0, privateKeyBuffer.available()); return new PlainBuffer(array); }
@Override public int available() { synchronized (buf) { return buf.available(); } }
@Override public int available() { synchronized (buf) { return buf.available(); } }
private void logHeaderLine(Buffer.PlainBuffer lineBuffer) throws Buffer.BufferException { byte[] bytes = new byte[lineBuffer.available()]; lineBuffer.readRawBytes(bytes); String header = new String(bytes, 0, bytes.length - 1); log.debug("Received header: {}", header); }
private KeyPair readUnencrypted(final PlainBuffer keyBuffer, final PublicKey publicKey) throws IOException, GeneralSecurityException { int privKeyListSize = keyBuffer.available(); if (privKeyListSize % 8 != 0) { throw new IOException("The private key section must be a multiple of the block size (8)"); byte[] padding = new byte[keyBuffer.available()];
.putByte((byte) 0) // <placeholder> .putRawBytes(sessionID); final int pos = hashInput.available() - sessionID.length - 1; // Position of <placeholder> hash.update(hashInput.array(), 0, hashInput.available()); final byte[] initialIV_C2S = hash.digest(); hash.update(hashInput.array(), 0, hashInput.available()); final byte[] initialIV_S2C = hash.digest(); hash.update(hashInput.array(), 0, hashInput.available()); final byte[] encryptionKey_C2S = hash.digest(); hash.update(hashInput.array(), 0, hashInput.available()); final byte[] encryptionKey_S2C = hash.digest(); hash.update(hashInput.array(), 0, hashInput.available()); final byte[] integrityKey_C2S = hash.digest(); hash.update(hashInput.array(), 0, hashInput.available()); final byte[] integrityKey_S2C = hash.digest();
.putBytes(f) .putMPInt(dh.getK()); digest.update(buf.array(), buf.rpos(), buf.available()); H = digest.digest();
private boolean parseGexReply(SSHPacket buffer) throws Buffer.BufferException, GeneralSecurityException, TransportException { byte[] K_S = buffer.readBytes(); byte[] f = buffer.readBytes(); byte[] sig = buffer.readBytes(); hostKey = new Buffer.PlainBuffer(K_S).readPublicKey(); dh.computeK(f); BigInteger k = dh.getK(); final Buffer.PlainBuffer buf = initializedBuffer() .putString(K_S) .putUInt32(minBits) .putUInt32(preferredBits) .putUInt32(maxBits) .putMPInt(((DH) dh).getP()) .putMPInt(((DH) dh).getG()) .putBytes(dh.getE()) .putBytes(f) .putMPInt(k); digest.update(buf.array(), buf.rpos(), buf.available()); H = digest.digest(); Signature signature = Factory.Named.Util.create(trans.getConfig().getSignatureFactories(), KeyType.fromKey(hostKey).toString()); signature.initVerify(hostKey); signature.update(H, 0, H.length); if (!signature.verify(sig)) throw new TransportException(DisconnectReason.KEY_EXCHANGE_FAILED, "KeyExchange signature verification failed"); return true; }
/** * Private method used while putting new keys into use that will resize the key used to initialize the cipher to the * needed length. * * @param E the key to resize * @param blockSize the cipher block size * @param hash the hash algorithm * @param K the key exchange K parameter * @param H the key exchange H parameter * * @return the resized key */ private static byte[] resizedKey(byte[] E, int blockSize, Digest hash, BigInteger K, byte[] H) { while (blockSize > E.length) { Buffer.PlainBuffer buffer = new Buffer.PlainBuffer().putMPInt(K).putRawBytes(H).putRawBytes(E); hash.update(buffer.array(), 0, buffer.available()); byte[] foo = hash.digest(); byte[] bar = new byte[E.length + foo.length]; System.arraycopy(E, 0, bar, 0, E.length); System.arraycopy(foo, 0, bar, E.length, foo.length); E = bar; } return E; }
public String parseIdentificationString() throws IOException { for (;;) { Buffer.PlainBuffer lineBuffer = new Buffer.PlainBuffer(); int lineStartPos = buffer.rpos(); for (;;) { if (buffer.available() == 0) { buffer.rpos(lineStartPos); return ""; } byte b = buffer.readByte(); lineBuffer.putByte(b); if (b == '\n') { if (checkForIdentification(lineBuffer)) { return readIdentification(lineBuffer); } else { logHeaderLine(lineBuffer); } break; } } } }
private String getKeyString(PublicKey pk) { final Buffer.PlainBuffer buf = new Buffer.PlainBuffer().putPublicKey(pk); return Base64.encodeBytes(buf.array(), buf.rpos(), buf.available()); }
@Override public int available() { synchronized (buf) { return buf.available(); } }
@Test public void testPosition() throws UnsupportedEncodingException, Buffer.BufferException { assertEquals(5, posBuf.wpos()); assertEquals(0, posBuf.rpos()); assertEquals(5, posBuf.available()); // read some bytes byte b = posBuf.readByte(); assertEquals(b, (byte) 'H'); assertEquals(1, posBuf.rpos()); assertEquals(4, posBuf.available()); }
private PlainBuffer decryptBuffer(PlainBuffer privateKeyBuffer, String cipherName, String kdfName, byte[] kdfOptions) throws IOException { Cipher cipher = createCipher(cipherName); initializeCipher(kdfName, kdfOptions, cipher); byte[] array = privateKeyBuffer.array(); cipher.update(array, 0, privateKeyBuffer.available()); return new PlainBuffer(array); }