try { byte[] keyBytes = Base64.decode(sKey); key = new Buffer.PlainBuffer(keyBytes).readPublicKey(); } catch (IOException ioe) { log.warn("Error decoding Base64 key bytes", ioe);
public byte[] toBytes() { Buffer.PlainBuffer buf = new Buffer.PlainBuffer(); buf.putUInt32(mask); if (has(Flag.SIZE)) buf.putUInt64(size); if (has(Flag.UIDGID)) { buf.putUInt32(uid); buf.putUInt32(gid); } if (has(Flag.MODE)) buf.putUInt32(mode.getMask()); if (has(Flag.ACMODTIME)) { buf.putUInt32(atime); buf.putUInt32(mtime); } if (has(Flag.EXTENDED)) { buf.putUInt32(ext.size()); for (Entry<String, String> entry : ext.entrySet()) { buf.putString(entry.getKey()); buf.putString(entry.getValue()); } } return buf.getCompactData(); }
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)"); int checkInt1 = keyBuffer.readUInt32AsInt(); // uint32 checkint1 int checkInt2 = keyBuffer.readUInt32AsInt(); // uint32 checkint2 if (checkInt1 != checkInt2) { throw new IOException("The checkInts differed, the key was not correctly decoded."); String keyType = keyBuffer.readString(); // string keytype KeyType kt = KeyType.fromString(keyType); logger.info("Read key type: {}", keyType, kt); switch (kt) { case ED25519: keyBuffer.readBytes(); // string publickey (again...) keyBuffer.readUInt32(); // length of privatekey+publickey byte[] privKey = new byte[32]; keyBuffer.readRawBytes(privKey); // string privatekey keyBuffer.readRawBytes(new byte[32]); // string publickey (again...) kp = new KeyPair(publicKey, new EdDSAPrivateKey(new EdDSAPrivateKeySpec(privKey, EdDSANamedCurveTable.getByName("Ed25519")))); break; case RSA: BigInteger n = keyBuffer.readMPInt(); // Modulus keyBuffer.readMPInt(); // Public Exponent BigInteger d = keyBuffer.readMPInt(); // Private Exponent keyBuffer.readMPInt(); // iqmp (q^-1 mod p) keyBuffer.readMPInt(); // p (Prime 1) keyBuffer.readMPInt(); // q (Prime 2)
final Buffer.PlainBuffer hashInput = new Buffer.PlainBuffer() .putMPInt(kex.getK()) .putRawBytes(H) .putByte((byte) 0) // <placeholder> .putRawBytes(sessionID); final int pos = hashInput.available() - sessionID.length - 1; // Position of <placeholder> hashInput.array()[pos] = 'A'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] initialIV_C2S = hash.digest(); hashInput.array()[pos] = 'B'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] initialIV_S2C = hash.digest(); hashInput.array()[pos] = 'C'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] encryptionKey_C2S = hash.digest(); hashInput.array()[pos] = 'D'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] encryptionKey_S2C = hash.digest(); hashInput.array()[pos] = 'E'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] integrityKey_C2S = hash.digest(); hashInput.array()[pos] = 'F'; hash.update(hashInput.array(), 0, hashInput.available());
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)"); int checkInt1 = keyBuffer.readUInt32AsInt(); // uint32 checkint1 int checkInt2 = keyBuffer.readUInt32AsInt(); // uint32 checkint2 if (checkInt1 != checkInt2) { throw new IOException("The checkInts differed, the key was not correctly decoded."); String keyType = keyBuffer.readString(); // string keytype KeyType kt = KeyType.fromString(keyType); logger.info("Read key type: {}", keyType, kt); switch (kt) { case ED25519: byte[] pubKey = keyBuffer.readBytes(); // string publickey (again...) keyBuffer.readUInt32(); // length of privatekey+publickey byte[] privKey = new byte[32]; keyBuffer.readRawBytes(privKey); // string privatekey keyBuffer.readRawBytes(new byte[32]); // string publickey (again...) kp = new KeyPair(publicKey, new EdDSAPrivateKey(new EdDSAPrivateKeySpec(privKey, EdDSANamedCurveTable.getByName("Ed25519")))); break; case RSA: BigInteger n = keyBuffer.readMPInt(); // Modulus BigInteger e = keyBuffer.readMPInt(); // Public Exponent BigInteger d = keyBuffer.readMPInt(); // Private Exponent keyBuffer.readMPInt(); // iqmp (q^-1 mod p) keyBuffer.readMPInt(); // p (Prime 1) keyBuffer.readMPInt(); // q (Prime 2)
try { byte[] keyBytes = Base64.decode(sKey); key = new Buffer.PlainBuffer(keyBytes).readPublicKey(); } catch (IOException ioe) { log.warn("Error decoding Base64 key bytes", ioe);
final Buffer.PlainBuffer hashInput = new Buffer.PlainBuffer() .putMPInt(kex.getK()) .putRawBytes(H) .putByte((byte) 0) // <placeholder> .putRawBytes(sessionID); final int pos = hashInput.available() - sessionID.length - 1; // Position of <placeholder> hashInput.array()[pos] = 'A'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] initialIV_C2S = hash.digest(); hashInput.array()[pos] = 'B'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] initialIV_S2C = hash.digest(); hashInput.array()[pos] = 'C'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] encryptionKey_C2S = hash.digest(); hashInput.array()[pos] = 'D'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] encryptionKey_S2C = hash.digest(); hashInput.array()[pos] = 'E'; hash.update(hashInput.array(), 0, hashInput.available()); final byte[] integrityKey_C2S = hash.digest(); hashInput.array()[pos] = 'F'; hash.update(hashInput.array(), 0, hashInput.available());
f = packet.readMPInt(); sig = packet.readBytes(); hostKey = new Buffer.PlainBuffer(K_S).readPublicKey(); } catch (Buffer.BufferException be) { throw new TransportException(be); final Buffer.PlainBuffer buf = new Buffer.PlainBuffer() .putString(V_C) .putString(V_S) .putString(I_C) .putString(I_S) .putString(K_S) .putMPInt(dh.getE()) .putMPInt(f) .putMPInt(dh.getK()); sha1.update(buf.array(), buf.rpos(), buf.available()); H = sha1.digest();
f = packet.readBytes(); sig = packet.readBytes(); hostKey = new Buffer.PlainBuffer(K_S).readPublicKey(); } catch (Buffer.BufferException be) { throw new TransportException(be); .putString(K_S) .putBytes(dh.getE()) .putBytes(f) .putMPInt(dh.getK()); digest.update(buf.array(), buf.rpos(), buf.available()); H = digest.digest();
/** * Read and store the separate public key provided alongside the private key * * @param publicKey Public key accessible through a {@code Reader} */ private void initPubKey(Reader publicKey) { try { final BufferedReader br = new BufferedReader(publicKey); try { final String keydata = br.readLine(); if (keydata != null) { String[] parts = keydata.split(" "); assert parts.length >= 2; type = KeyType.fromString(parts[0]); pubKey = new Buffer.PlainBuffer(Base64.decode(parts[1])).readPublicKey(); } } finally { br.close(); } } catch (IOException e) { // let super provide both public & private key log.warn("Error reading public key: {}", e.toString()); } } }
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 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."); } }
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; } } } }
/** * Check whether the signature is generated using the expected algorithm, and if so, return the signature blob * * @param sig The full signature * @param expectedKeyAlgorithm The expected key algorithm * @return The blob part of the signature */ protected byte[] extractSig(byte[] sig, String expectedKeyAlgorithm) { Buffer.PlainBuffer buffer = new Buffer.PlainBuffer(sig); try { String algo = buffer.readString(); if (!expectedKeyAlgorithm.equals(algo)) { throw new SSHRuntimeException("Expected '" + expectedKeyAlgorithm + "' key algorithm, but got: " + algo); } return buffer.readBytes(); } catch (Buffer.BufferException e) { throw new SSHRuntimeException(e); } }
/** * Read and store the separate public key provided alongside the private key * * @param publicKey Public key accessible through a {@code Reader} */ private void initPubKey(Reader publicKey) throws IOException { final BufferedReader br = new BufferedReader(publicKey); try { final String keydata = br.readLine(); if (keydata != null) { String[] parts = keydata.trim().split(" "); assert parts.length >= 2; type = KeyType.fromString(parts[0]); pubKey = new Buffer.PlainBuffer(Base64.decode(parts[1])).readPublicKey(); } } finally { br.close(); } } }
protected SSHPacket putSig(SSHPacket reqBuf) throws UserAuthException { PrivateKey key; try { key = kProv.getPrivate(); } catch (IOException ioe) { throw new UserAuthException("Problem getting private key from " + kProv, ioe); } final String kt = KeyType.fromKey(key).toString(); Signature signature = Factory.Named.Util.create(params.getTransport().getConfig().getSignatureFactories(), kt); if (signature == null) throw new UserAuthException("Could not create signature instance for " + kt + " key"); signature.initSign(key); signature.update(new Buffer.PlainBuffer() .putString(params.getTransport().getSessionID()) .putBuffer(reqBuf) // & rest of the data for sig .getCompactData()); reqBuf.putSignature(kt, signature.encode(signature.sign())); return reqBuf; }
@Override public void init(String remoteHost, int remotePort, InputStream in, OutputStream out) throws TransportException { connInfo = new ConnInfo(remoteHost, remotePort, in, out); try { log.info("Client identity string: {}", clientID); connInfo.out.write((clientID + "\r\n").getBytes(IOUtils.UTF8)); connInfo.out.flush(); // Read server's ID final Buffer.PlainBuffer buf = new Buffer.PlainBuffer(); while ((serverID = readIdentification(buf)).isEmpty()) { buf.putByte((byte) connInfo.in.read()); } log.info("Server identity string: {}", serverID); } catch (IOException e) { throw new TransportException(e); } reader.start(); }
protected SSHPacket putSig(SSHPacket reqBuf) throws UserAuthException { PrivateKey key; try { key = kProv.getPrivate(); } catch (IOException ioe) { throw new UserAuthException("Problem getting private key from " + kProv, ioe); } final String kt = KeyType.fromKey(key).toString(); Signature signature = Factory.Named.Util.create(params.getTransport().getConfig().getSignatureFactories(), kt); if (signature == null) throw new UserAuthException("Could not create signature instance for " + kt + " key"); signature.init(null, key); signature.update(new Buffer.PlainBuffer() .putString(params.getTransport().getSessionID()) .putBuffer(reqBuf) // & rest of the data for sig .getCompactData()); reqBuf.putSignature(kt, signature.encode(signature.sign())); return reqBuf; }
private PublicKey readPublicKey(final PlainBuffer plainBuffer) throws Buffer.BufferException, GeneralSecurityException { return KeyType.fromString(plainBuffer.readString()).readPubKeyFromBuffer(plainBuffer); }
@Override public void allocatePTY(String term, int cols, int rows, int width, int height, Map<PTYMode, Integer> modes) throws ConnectionException, TransportException { sendChannelRequest( "pty-req", true, new Buffer.PlainBuffer() .putString(term) .putUInt32(cols) .putUInt32(rows) .putUInt32(width) .putUInt32(height) .putBytes(PTYMode.encode(modes)) ).await(conn.getTimeoutMs(), TimeUnit.MILLISECONDS); }