Skip to content

Commit

Permalink
Replaced custom Base64 with java.util.Base64 (hierynomus#879)
Browse files Browse the repository at this point in the history
  • Loading branch information
exceptionfactory authored Jul 14, 2023
1 parent 0783709 commit f35c2bd
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 2,135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
*/
package com.hierynomus.sshj.transport.verification;

import net.schmizz.sshj.common.Base64;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.common.SSHException;
import net.schmizz.sshj.transport.mac.MAC;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -85,12 +85,12 @@ public boolean match(String hostname) throws IOException {

private String hashHost(String host) throws IOException {
sha1.init(getSaltyBytes());
return "|1|" + salt + "|" + Base64.encodeBytes(sha1.doFinal(host.getBytes(IOUtils.UTF8)));
return "|1|" + salt + "|" + Base64.getEncoder().encodeToString(sha1.doFinal(host.getBytes(IOUtils.UTF8)));
}

private byte[] getSaltyBytes() throws IOException {
private byte[] getSaltyBytes() {
if (saltyBytes == null) {
saltyBytes = Base64.decode(salt);
saltyBytes = Base64.getDecoder().decode(salt);
}
return saltyBytes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package com.hierynomus.sshj.userauth.keyprovider;

import net.schmizz.sshj.common.Base64;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.KeyType;

Expand All @@ -24,6 +23,7 @@
import java.io.IOException;
import java.io.Reader;
import java.security.PublicKey;
import java.util.Base64;

public class OpenSSHKeyFileUtil {
private OpenSSHKeyFileUtil() {
Expand Down Expand Up @@ -56,7 +56,7 @@ public static ParsedPubKey initPubKey(Reader publicKey) throws IOException {
if (parts.length >= 2) {
return new ParsedPubKey(
KeyType.fromString(parts[0]),
new Buffer.PlainBuffer(Base64.decode(parts[1])).readPublicKey()
new Buffer.PlainBuffer(Base64.getDecoder().decode(parts[1])).readPublicKey()
);
} else {
throw new IOException("Got line with only one column");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import net.schmizz.sshj.common.*;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.Buffer.PlainBuffer;
import net.schmizz.sshj.common.ByteArrayUtils;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.common.SSHRuntimeException;
import net.schmizz.sshj.common.SecurityUtils;
import net.schmizz.sshj.transport.cipher.Cipher;
import net.schmizz.sshj.userauth.keyprovider.BaseFileKeyProvider;
import net.schmizz.sshj.userauth.keyprovider.FileKeyProvider;
Expand All @@ -47,6 +52,7 @@
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.util.Arrays;
import java.util.Base64;

/**
* Reads a key file in the new OpenSSH format.
Expand Down Expand Up @@ -99,7 +105,7 @@ protected KeyPair readKeyPair() throws IOException {
}

String keyFile = readKeyFile(reader);
byte[] decode = Base64.decode(keyFile);
byte[] decode = Base64.getDecoder().decode(keyFile);
PlainBuffer keyBuffer = new PlainBuffer(decode);
return readDecodedKeyPair(keyBuffer);

Expand Down
2,066 changes: 0 additions & 2,066 deletions src/main/java/net/schmizz/sshj/common/Base64.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@
*/
package net.schmizz.sshj.transport.verification;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

import net.schmizz.sshj.common.Base64;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.SSHRuntimeException;
import net.schmizz.sshj.common.SecurityUtils;
Expand All @@ -46,48 +45,40 @@ public class FingerprintVerifier implements HostKeyVerifier {
*
* @param fingerprint of an SSH fingerprint in MD5 (hex), SHA-1 (base64) or SHA-256(base64) format
*
* @return
* @return Host Key Verifier
*/
public static HostKeyVerifier getInstance(String fingerprint) {
if (fingerprint.startsWith("SHA1:")) {
return new FingerprintVerifier("SHA-1", fingerprint.substring(5));
}

try {
if (fingerprint.startsWith("SHA1:")) {
return new FingerprintVerifier("SHA-1", fingerprint.substring(5));
}
if (fingerprint.startsWith("SHA256:")) {
return new FingerprintVerifier("SHA-256", fingerprint.substring(7));
}

if (fingerprint.startsWith("SHA256:")) {
return new FingerprintVerifier("SHA-256", fingerprint.substring(7));
}
final String md5;
if (fingerprint.startsWith("MD5:")) {
md5 = fingerprint.substring(4); // remove the MD5: prefix
} else {
md5 = fingerprint;
}

final String md5;
if (fingerprint.startsWith("MD5:")) {
md5 = fingerprint.substring(4); // remove the MD5: prefix
} else {
md5 = fingerprint;
}
if (!MD5_FINGERPRINT_PATTERN.matcher(md5).matches()) {
throw new SSHRuntimeException("Invalid MD5 fingerprint: " + fingerprint);
}

if (!MD5_FINGERPRINT_PATTERN.matcher(md5).matches()) {
throw new SSHRuntimeException("Invalid MD5 fingerprint: " + fingerprint);
// Use the old default fingerprint verifier for md5 fingerprints
return (new HostKeyVerifier() {
@Override
public boolean verify(String h, int p, PublicKey k) {
return SecurityUtils.getFingerprint(k).equals(md5);
}

// Use the old default fingerprint verifier for md5 fingerprints
return (new HostKeyVerifier() {
@Override
public boolean verify(String h, int p, PublicKey k) {
return SecurityUtils.getFingerprint(k).equals(md5);
}

@Override
public List<String> findExistingAlgorithms(String hostname, int port) {
return Collections.emptyList();
}
});
} catch (SSHRuntimeException e) {
throw e;
} catch (IOException e) {
throw new SSHRuntimeException(e);
}

@Override
public List<String> findExistingAlgorithms(String hostname, int port) {
return Collections.emptyList();
}
});
}

private final String digestAlgorithm;
Expand All @@ -99,18 +90,16 @@ public List<String> findExistingAlgorithms(String hostname, int port) {
* the used digest algorithm
* @param base64Fingerprint
* base64 encoded fingerprint data
*
* @throws IOException
*/
private FingerprintVerifier(String digestAlgorithm, String base64Fingerprint) throws IOException {
private FingerprintVerifier(String digestAlgorithm, String base64Fingerprint) {
this.digestAlgorithm = digestAlgorithm;

// if the length is not padded with "=" chars at the end so that it is divisible by 4 the SSHJ Base64 implementation does not work correctly
StringBuilder base64FingerprintBuilder = new StringBuilder(base64Fingerprint);
while (base64FingerprintBuilder.length() % 4 != 0) {
base64FingerprintBuilder.append("=");
}
fingerprintData = Base64.decode(base64FingerprintBuilder.toString());
fingerprintData = Base64.getDecoder().decode(base64FingerprintBuilder.toString());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,30 @@
import com.hierynomus.sshj.common.KeyAlgorithm;
import com.hierynomus.sshj.transport.verification.KnownHostMatchers;
import com.hierynomus.sshj.userauth.certificate.Certificate;
import net.schmizz.sshj.common.*;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.common.LoggerFactory;
import net.schmizz.sshj.common.SSHException;
import net.schmizz.sshj.common.SSHRuntimeException;
import net.schmizz.sshj.common.SecurityUtils;
import org.slf4j.Logger;

import java.io.*;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

/**
Expand Down Expand Up @@ -274,7 +289,7 @@ public KnownHostEntry parseEntry(String line)
if (type != KeyType.UNKNOWN) {
final String sKey = split[i++];
try {
byte[] keyBytes = Base64.decode(sKey);
byte[] keyBytes = Base64.getDecoder().decode(sKey);
key = new Buffer.PlainBuffer(keyBytes).readPublicKey();
} catch (IOException ioe) {
log.warn("Error decoding Base64 key bytes", ioe);
Expand Down Expand Up @@ -453,8 +468,7 @@ public String getLine() {
}

private String getKeyString(PublicKey pk) {
final Buffer.PlainBuffer buf = new Buffer.PlainBuffer().putPublicKey(pk);
return Base64.encodeBytes(buf.array(), buf.rpos(), buf.available());
return Base64.getEncoder().encodeToString(pk.getEncoded());
}

protected String getHostPart() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
import net.schmizz.sshj.common.Base64;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.common.SecurityUtils;
Expand All @@ -43,9 +42,8 @@
import java.security.*;
import java.security.spec.*;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
Expand Down Expand Up @@ -243,7 +241,7 @@ protected void parseKeyPair() throws IOException {
throw new IOException("Invalid key file format: missing \"PuTTY-User-Key-File-?\" entry");
}
// Retrieve keys from payload
publicKey = Base64.decode(payload.get("Public-Lines"));
publicKey = Base64.getDecoder().decode(payload.get("Public-Lines"));
if (this.isEncrypted()) {
final char[] passphrase;
if (pwdf != null) {
Expand All @@ -252,7 +250,7 @@ protected void parseKeyPair() throws IOException {
passphrase = "".toCharArray();
}
try {
privateKey = this.decrypt(Base64.decode(payload.get("Private-Lines")), passphrase);
privateKey = this.decrypt(Base64.getDecoder().decode(payload.get("Private-Lines")), passphrase);
Mac mac;
if (this.keyFileVersion <= 2) {
mac = this.prepareVerifyMacV2(passphrase);
Expand All @@ -264,7 +262,7 @@ protected void parseKeyPair() throws IOException {
PasswordUtils.blankOut(passphrase);
}
} else {
privateKey = Base64.decode(payload.get("Private-Lines"));
privateKey = Base64.getDecoder().decode(payload.get("Private-Lines"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package com.hierynomus.sshj.common

import com.hierynomus.sshj.userauth.certificate.Certificate
import net.schmizz.sshj.common.Base64
import net.schmizz.sshj.common.Buffer
import net.schmizz.sshj.common.KeyType
import net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile
Expand Down Expand Up @@ -110,7 +109,7 @@ f26VSnEypH3G3cmPYfpVcXL63bCb0E4sNJwENM4tQGZa5YGz3CxMdgIVAJUv4z9+
def keyType = KeyType.fromString(parts[0])
when:
def pubKey = new Buffer.PlainBuffer(Base64.decode(parts[1])).readPublicKey()
def pubKey = new Buffer.PlainBuffer(Base64.getDecoder().decode(parts[1])).readPublicKey()
then:
KeyType.fromKey(pubKey) == keyType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package com.hierynomus.sshj.transport.verification

import net.schmizz.sshj.common.Base64
import net.schmizz.sshj.common.Buffer
import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts
import net.schmizz.sshj.util.KeyUtil
Expand Down Expand Up @@ -65,7 +64,7 @@ class OpenSSHKnownHostsSpec extends Specification {
host1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCiYp2IDgzDFhl8T4TRLIhEljvEixz1YN0XWh4dYh0REGK9T4QKiyb28EztPMdcOtz1uyX5rUGYXX9hj99S4SiU=
host1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTjA7hduYGmvV9smEEsIdGLdghSPD7kL8QarIIOkeXmBh+LTtT/T1K+Ot/rmXCZsP8hoUXxbvN+Tks440Ci0ck=
""")
def pk = new Buffer.PlainBuffer(Base64.decode("AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTjA7hduYGmvV9smEEsIdGLdghSPD7kL8QarIIOkeXmBh+LTtT/T1K+Ot/rmXCZsP8hoUXxbvN+Tks440Ci0ck=")).readPublicKey()
def pk = new Buffer.PlainBuffer(Base64.getDecoder().decode("AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTjA7hduYGmvV9smEEsIdGLdghSPD7kL8QarIIOkeXmBh+LTtT/T1K+Ot/rmXCZsP8hoUXxbvN+Tks440Ci0ck=")).readPublicKey()
when:
def knownhosts = new OpenSSHKnownHosts(f)

Expand All @@ -79,7 +78,7 @@ host1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL
host1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTIDgzDFhl8T4TRLIhEljvEixz1YN0XWh4dYh0REGK9T4QKiyb28EztPMdcOtz1uyX5rUGYXX9hj99S4SiU=
host1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTjA7hduYGmvV9smEEsIdGLdghSPD7kL8QarIIOkeXmBh+LTtT/T1K+Ot/rmXCZsP8hoUXxbvN+Tks440Ci0ck=
""")
def pk = new Buffer.PlainBuffer(Base64.decode("AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTjA7hduYGmvV9smEEsIdGLdghSPD7kL8QarIIOkeXmBh+LTtT/T1K+Ot/rmXCZsP8hoUXxbvN+Tks440Ci0ck=")).readPublicKey()
def pk = new Buffer.PlainBuffer(Base64.getDecoder().decode("AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTjA7hduYGmvV9smEEsIdGLdghSPD7kL8QarIIOkeXmBh+LTtT/T1K+Ot/rmXCZsP8hoUXxbvN+Tks440Ci0ck=")).readPublicKey()
when:
def knownhosts = new OpenSSHKnownHosts(f)

Expand Down Expand Up @@ -150,7 +149,7 @@ host1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL
def "should match any host name from multi-host line"() {
given:
def f = knownHosts("schmizz.net,69.163.155.180 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6P9Hlwdahh250jGZYKg2snRq2j2lFJVdKSHyxqbJiVy9VX9gTkN3K2MD48qyrYLYOyGs3vTttyUk+cK++JMzURWsrP4piby7LpeOT+3Iq8CQNj4gXZdcH9w15Vuk2qS11at6IsQPVHpKD9HGg9//EFUccI/4w06k4XXLm/IxOGUwj6I2AeWmEOL3aDi+fe07TTosSdLUD6INtR0cyKsg0zC7Da24ixoShT8Oy3x2MpR7CY3PQ1pUVmvPkr79VeA+4qV9F1JM09WdboAMZgWQZ+XrbtuBlGsyhpUHSCQOya+kOJ+bYryS+U7A+6nmTW3C9FX4FgFqTF89UHOC7V0zZQ==")
def pk = new Buffer.PlainBuffer(Base64.decode("AAAAB3NzaC1yc2EAAAABIwAAAQEA6P9Hlwdahh250jGZYKg2snRq2j2lFJVdKSHyxqbJiVy9VX9gTkN3K2MD48qyrYLYOyGs3vTttyUk+cK++JMzURWsrP4piby7LpeOT+3Iq8CQNj4gXZdcH9w15Vuk2qS11at6IsQPVHpKD9HGg9//EFUccI/4w06k4XXLm/IxOGUwj6I2AeWmEOL3aDi+fe07TTosSdLUD6INtR0cyKsg0zC7Da24ixoShT8Oy3x2MpR7CY3PQ1pUVmvPkr79VeA+4qV9F1JM09WdboAMZgWQZ+XrbtuBlGsyhpUHSCQOya+kOJ+bYryS+U7A+6nmTW3C9FX4FgFqTF89UHOC7V0zZQ==")).readPublicKey()
def pk = new Buffer.PlainBuffer(Base64.getDecoder().decode("AAAAB3NzaC1yc2EAAAABIwAAAQEA6P9Hlwdahh250jGZYKg2snRq2j2lFJVdKSHyxqbJiVy9VX9gTkN3K2MD48qyrYLYOyGs3vTttyUk+cK++JMzURWsrP4piby7LpeOT+3Iq8CQNj4gXZdcH9w15Vuk2qS11at6IsQPVHpKD9HGg9//EFUccI/4w06k4XXLm/IxOGUwj6I2AeWmEOL3aDi+fe07TTosSdLUD6INtR0cyKsg0zC7Da24ixoShT8Oy3x2MpR7CY3PQ1pUVmvPkr79VeA+4qV9F1JM09WdboAMZgWQZ+XrbtuBlGsyhpUHSCQOya+kOJ+bYryS+U7A+6nmTW3C9FX4FgFqTF89UHOC7V0zZQ==")).readPublicKey()

when:
def knownHosts = new OpenSSHKnownHosts(f)
Expand Down Expand Up @@ -184,7 +183,7 @@ host1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL
|\t\t\t\t\t
|\t@revoked host3\tssh-ed25519\t \t$key\t
""".stripMargin())
def pk = new Buffer.PlainBuffer(Base64.decode(key)).readPublicKey()
def pk = new Buffer.PlainBuffer(Base64.getDecoder().decode(key)).readPublicKey()

when:
def knownhosts = new OpenSSHKnownHosts(f)
Expand Down Expand Up @@ -212,7 +211,7 @@ host1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL
def knownhosts = new OpenSSHKnownHosts(f)

then:
knownhosts.verify("good-host", 22, new Buffer.PlainBuffer(Base64.decode(key)).readPublicKey())
knownhosts.verify("good-host", 22, new Buffer.PlainBuffer(Base64.getDecoder().decode(key)).readPublicKey())
}

def knownHosts(String s) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package net.schmizz.sshj.transport.verification

import net.schmizz.sshj.common.Base64
import net.schmizz.sshj.common.Buffer
import spock.lang.Specification
import spock.lang.Unroll
Expand Down Expand Up @@ -63,6 +62,6 @@ class FingerprintVerifierSpec extends Specification {
def getPublicKey() {
def lines = new File("src/test/resources/keytypes/test_ed25519.pub").readLines()
def keystring = lines[0].split(" ")[1]
return new Buffer.PlainBuffer(Base64.decode(keystring)).readPublicKey()
return new Buffer.PlainBuffer(Base64.getDecoder().decode(keystring)).readPublicKey()
}
}

0 comments on commit f35c2bd

Please sign in to comment.