Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump com.hierynomus:sshj from 0.32.0 to 0.36.0 in /prime-router #11246

Merged
2 changes: 1 addition & 1 deletion prime-router/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ dependencies {
implementation("com.github.kittinunf.fuel:fuel-json:2.3.1")
implementation("org.json:json:20230618")
// DO NOT INCREMENT SSHJ to a newer version without first thoroughly testing it locally.
implementation("com.hierynomus:sshj:0.32.0")
implementation("com.hierynomus:sshj:0.36.0")
implementation("com.jcraft:jsch:0.1.55")
implementation("org.apache.poi:poi:5.2.3")
implementation("org.apache.commons:commons-csv:1.10.0")
Expand Down
6 changes: 3 additions & 3 deletions prime-router/src/main/kotlin/transport/RESTTransport.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ import io.ktor.serialization.kotlinx.json.json
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.json.Json
import net.schmizz.sshj.common.Base64
import org.json.JSONObject
import java.io.InputStream
import java.security.KeyStore
import java.util.Base64
import java.util.logging.Logger
import javax.net.ssl.KeyManagerFactory
import javax.net.ssl.SSLContext
Expand Down Expand Up @@ -405,7 +405,7 @@ class RESTTransport(private val httpClient: HttpClient? = null) : ITransport {
if (restUrl.contains("dataingestion.datateam-cdc-nbs")) {
val idTokenInfoString: String = client.post(restUrl) {
val credentialString = credential.user + ":" + credential.pass
val basicAuth = "Basic " + Base64.encodeBytes(credentialString.encodeToByteArray())
val basicAuth = "Basic " + Base64.getEncoder().encodeToString(credentialString.encodeToByteArray())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on Java standard library is always a good idea simple operations like this 👍

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @jalbinson

expectSuccess = true // throw an exception if not successful
postHeaders(
mapOf(
Expand Down Expand Up @@ -549,7 +549,7 @@ class RESTTransport(private val httpClient: HttpClient? = null) : ITransport {
*/
private fun getSslContext(jksCredential: UserJksCredential): SSLContext? {
// Open the keystore in the UserJksCredential, it's a PKCS12 type
val jksDecoded = Base64.decode(jksCredential.jks)
val jksDecoded = Base64.getDecoder().decode(jksCredential.jks)
val inStream: InputStream = jksDecoded.inputStream()
val jksPasscode = jksCredential.jksPasscode.toCharArray()
val keyStore: KeyStore = KeyStore.getInstance("PKCS12")
Expand Down
24 changes: 24 additions & 0 deletions prime-router/src/main/kotlin/transport/SftpTransport.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gov.cdc.prime.router.transport

import com.google.common.base.Preconditions
import com.hierynomus.sshj.key.KeyAlgorithms
import com.microsoft.azure.functions.ExecutionContext
import gov.cdc.prime.router.Receiver
import gov.cdc.prime.router.Report
Expand Down Expand Up @@ -306,6 +307,29 @@ class SftpTransport : ITransport, Logging {
// allow us to mock SSHClient because there is no dependency injection in this class
fun createDefaultSSHClient(): SSHClient {
val sshConfig = DefaultConfig()

// Started from version 0.33.0, SSHJ doesn't try to determine RSA-SHA2-* support on fly.
// Instead, it looks only config.getKeyAlgorithms(), which may or may not contain ssh-rsa
// and rsa-sha2-* in any order. The default config stops working with old servers like
// Apache SSHD that doesn't rsa-sha2-* signatures. To make it works with old servers,
// we need to include the KeyAlgorithms.SSHRSA at the top of the list or have higher
// priority than other as below.
sshConfig.keyAlgorithms = listOf(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth creating a tech debt ticket to make this configurable per receiver? I remember you saying this breaks after trying the first three key algorithms, is that still the case or is this not related to that?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it isn't worth it to create a tech dept for this. After this fix, it works with all of our reivers.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snesm our Security expert approved the fix. However, he suggested I get with the receiver who still using the SSHRAS key exchange and suggest they upgrade their server to support the new key exchange.

KeyAlgorithms.SSHRSA(),
KeyAlgorithms.EdDSA25519CertV01(),
KeyAlgorithms.EdDSA25519(),
KeyAlgorithms.ECDSASHANistp521CertV01(),
KeyAlgorithms.ECDSASHANistp521(),
KeyAlgorithms.ECDSASHANistp384CertV01(),
KeyAlgorithms.ECDSASHANistp384(),
KeyAlgorithms.ECDSASHANistp256CertV01(),
KeyAlgorithms.ECDSASHANistp256(),
KeyAlgorithms.RSASHA512(),
KeyAlgorithms.RSASHA256(),
KeyAlgorithms.SSHRSACertV01(),
KeyAlgorithms.SSHDSSCertV01(),
KeyAlgorithms.SSHDSA()
)
return SSHClient(sshConfig)
}
}
Expand Down