Skip to content

Commit

Permalink
Reduce jdk8 dependencies in client
Browse files Browse the repository at this point in the history
  • Loading branch information
e5l committed Aug 23, 2019
1 parent e7a3aac commit 06077ee
Show file tree
Hide file tree
Showing 35 changed files with 218 additions and 122 deletions.
12 changes: 7 additions & 5 deletions gradle/jdk.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
project.ext.jdk8Modules = [
'ktor-http',
'ktor-utils',

'ktor-client-tests',

'ktor-network-tls',
'ktor-server-core', 'ktor-server-host-common', 'ktor-server-servlet', 'ktor-server-netty', 'ktor-server-tomcat',
'ktor-server-test-host',

'ktor-websockets', 'ktor-webjars', 'ktor-metrics', 'ktor-server-sessions', 'ktor-auth', 'ktor-auth-jwt'
'ktor-websockets', 'ktor-webjars', 'ktor-metrics', 'ktor-server-sessions', 'ktor-auth', 'ktor-auth-jwt',

'ktor-network-tls-certificates'
]

project.ext.jdk7Modules = [
'ktor-http',
'ktor-utils',
'ktor-network-tls',
'ktor-websockets'
]
1 change: 0 additions & 1 deletion gradle/jvm.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ kotlin {
api("org.jetbrains.kotlinx:atomicfu:$atomicfu_version")

api group: 'org.slf4j', name: 'slf4j-api', version: slf4j_version
api group: 'com.typesafe', name: 'config', version: typesafe_config_version
}

jvmTest.dependencies {
Expand Down
1 change: 1 addition & 0 deletions ktor-client/ktor-client-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ kotlin.sourceSets {
dependencies {
api(project(":ktor-client:ktor-client-tests"))
api(project(":ktor-network:ktor-network-tls"))
api(project(":ktor-network:ktor-network-tls:ktor-network-tls-certificates"))
}
}
}
1 change: 1 addition & 0 deletions ktor-client/ktor-client-cio/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ kotlin.sourceSets {
}
jvmTest.dependencies {
api project(':ktor-client:ktor-client-tests')
api project(':ktor-network:ktor-network-tls:ktor-network-tls-certificates')
api group: 'ch.qos.logback', name: 'logback-classic', version: logback_version
}
}
12 changes: 9 additions & 3 deletions ktor-network/ktor-network-tls/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
kotlin.sourceSets.jvmMain.dependencies {
api project(':ktor-network')
api project(':ktor-http:ktor-http-cio')
kotlin.sourceSets {
jvmMain.dependencies {
api project(':ktor-network')
api project(':ktor-http:ktor-http-cio')
}

jvmTest.dependencies {
api project(':ktor-network:ktor-network-tls:ktor-network-tls-certificates')
}
}
13 changes: 9 additions & 4 deletions ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/OID.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

package io.ktor.network.tls

internal data class OID(val identifier: String) {
import io.ktor.util.*

@InternalAPI
data class OID(val identifier: String) {
val asArray: IntArray = identifier.split(".", " ").map { it.trim().toInt() }.toIntArray()

companion object {
Expand All @@ -23,20 +26,21 @@ internal data class OID(val identifier: String) {
/**
* Algorithm OID
*/
val Sha1withRSAEncryption = OID("1.2.840.113549.1.1.5")
val ECDSAwithSHA384Encryption = OID("1.2.840.10045.4.3.3")
val ECDSAwithSHA256Encryption = OID("1.2.840.10045.4.3.2")

val RSAwithSHA512Encryption = OID("1.2.840.113549.1.1.13")
val RSAwithSHA384Encryption = OID("1.2.840.113549.1.1.12")
val RSAwithSHA256Encryption = OID("1.2.840.113549.1.1.11")
val RSAwithSHA1Encryption = OID("1.2.840.113549.1.1.5")

/**
* EC curves
*/
val secp256r1 = OID("1.2.840.10045.3.1.7")

fun fromAlgorithm(algorithm: String): OID = when (algorithm) {
"SHA1withRSA" -> Sha1withRSAEncryption
"SHA1withRSA" -> RSAwithSHA1Encryption
"SHA384withECDSA" -> ECDSAwithSHA384Encryption
"SHA256withECDSA" -> ECDSAwithSHA256Encryption
"SHA384withRSA" -> RSAwithSHA384Encryption
Expand All @@ -46,7 +50,8 @@ internal data class OID(val identifier: String) {
}
}

internal fun keysGenerationAlgorithm(algorithm: String): String = when {
@InternalAPI
fun keysGenerationAlgorithm(algorithm: String): String = when {
algorithm.endsWith("ecdsa", ignoreCase = true) -> "EC"
algorithm.endsWith("dsa", ignoreCase = true) -> "DSA"
algorithm.endsWith("rsa", ignoreCase = true) -> "RSA"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,8 @@ internal class TLSClientHandshake(

serverCertificate = x509s.firstOrNull { certificate ->
SupportedSignatureAlgorithms.any {
it.name.equals(
certificate.sigAlgName,
ignoreCase = true
)
val oid = it.oid?.identifier ?: return@any false
oid.equals(certificate.sigAlgOID, ignoreCase = true)
}
} ?: throw TLSException("No suitable server certificate received: $certs")
}
Expand All @@ -235,7 +233,7 @@ internal class TLSClientHandshake(
repeat(hashAndSignCount / 2) {
val hash = packet.readByte()
val sign = packet.readByte()
hashAndSign += HashAndSign(hash, sign)
hashAndSign += HashAndSign.byCode(hash, sign)
}

val authoritiesSize = packet.readShort().toInt() and 0xFFFF
Expand Down Expand Up @@ -282,7 +280,7 @@ internal class TLSClientHandshake(

encryptionInfo = generateECKeys(curve, point)
}
SecretExchangeType.RSA -> {
RSA -> {
packet.release()
error("Server key exchange handshake doesn't expected in RCA exchange type")
}
Expand Down Expand Up @@ -333,7 +331,7 @@ internal class TLSClientHandshake(

private fun generatePreSecret(encryptionInfo: EncryptionInfo?): ByteArray =
when (serverHello.cipherSuite.exchangeType) {
SecretExchangeType.RSA -> ByteArray(48).also {
RSA -> ByteArray(48).also {
config.random.nextBytes(it)
it[0] = 0x03
it[1] = 0x03
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package io.ktor.network.tls.extensions

import io.ktor.network.tls.*
import io.ktor.util.*
import kotlinx.io.core.*

/**
Expand Down Expand Up @@ -55,29 +56,35 @@ enum class SignatureAlgorithm(val code: Byte) {

/**
* Hash and signature algorithm pair
* @property hash algorithm
* @property sign algorithm
*
* @property hash algorithm.
* @property sign algorithm.
* @property oid [object identifier](https://en.wikipedia.org/wiki/Object_identifier).
*/
data class HashAndSign(val hash: HashAlgorithm, val sign: SignatureAlgorithm) {
constructor(hash: Byte, sign: Byte) : this(HashAlgorithm.byCode(hash), SignatureAlgorithm.byCode(sign))
data class HashAndSign(val hash: HashAlgorithm, val sign: SignatureAlgorithm, val oid: OID? = null) {
constructor(hash: Byte, sign: Byte, oid: String? = null) : this(
HashAlgorithm.byCode(hash), SignatureAlgorithm.byCode(sign), oid?.let{ OID(it) }
)

/**
* String representation of this algorithms pair
*/
val name: String = "${hash.name}with${sign.name}"

companion object
}

/**
* List of supported combinations of hash and signature algorithms
*/
val SupportedSignatureAlgorithms: List<HashAndSign> = listOf(
HashAndSign(HashAlgorithm.SHA384, SignatureAlgorithm.ECDSA),
HashAndSign(HashAlgorithm.SHA256, SignatureAlgorithm.ECDSA),
HashAndSign(HashAlgorithm.SHA384, SignatureAlgorithm.ECDSA, OID.ECDSAwithSHA384Encryption),
HashAndSign(HashAlgorithm.SHA256, SignatureAlgorithm.ECDSA, OID.ECDSAwithSHA256Encryption),

HashAndSign(HashAlgorithm.SHA512, SignatureAlgorithm.RSA),
HashAndSign(HashAlgorithm.SHA384, SignatureAlgorithm.RSA),
HashAndSign(HashAlgorithm.SHA256, SignatureAlgorithm.RSA),
HashAndSign(HashAlgorithm.SHA1, SignatureAlgorithm.RSA)
HashAndSign(HashAlgorithm.SHA512, SignatureAlgorithm.RSA, OID.RSAwithSHA512Encryption),
HashAndSign(HashAlgorithm.SHA384, SignatureAlgorithm.RSA, OID.RSAwithSHA384Encryption),
HashAndSign(HashAlgorithm.SHA256, SignatureAlgorithm.RSA, OID.RSAwithSHA256Encryption),
HashAndSign(HashAlgorithm.SHA1, SignatureAlgorithm.RSA, OID.RSAwithSHA1Encryption)
)

internal fun ByteReadPacket.parseSignatureAlgorithms(): List<HashAndSign> {
Expand All @@ -97,8 +104,12 @@ internal fun ByteReadPacket.parseSignatureAlgorithms(): List<HashAndSign> {
internal fun ByteReadPacket.readHashAndSign(): HashAndSign {
val hash = readByte()
val sign = readByte()
return HashAndSign.byCode(hash, sign)
}

check(sign != SignatureAlgorithm.ANON.code) { "Anonymous signature not al" }
@InternalAPI
fun HashAndSign.Companion.byCode(hash: Byte, sign: Byte): HashAndSign {
check(sign != SignatureAlgorithm.ANON.code) { "Anonymous signature not allowed." }

return HashAndSign(hash, sign)
return SupportedSignatureAlgorithms.find { it.hash.code == hash && it.sign.code == sign } ?: HashAndSign(hash, sign)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package io.ktor.network.tls.extensions
import io.ktor.network.tls.*
import kotlinx.io.core.*

internal enum class TLSExtensionType(val code: Short) {
enum class TLSExtensionType(val code: Short) {
SERVER_NAME(0),
MAX_FRAGMENT_LENGTH(1),
CLIENT_CERTIFICATE_URL(2),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

kotlin {
sourceSets {
jvmMain {
dependencies {
api(project(":ktor-network:ktor-network-tls"))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class CertificateBuilder internal constructor() {
var keySizeInBits: Int = 1024

internal fun build(): CertificateInfo {
val algorithm = HashAndSign(hash, sign)
val algorithm = HashAndSign.byCode(hash.code, sign.code)
val keys = KeyPairGenerator.getInstance(keysGenerationAlgorithm(algorithm.name))!!.apply {
initialize(keySizeInBits)
}.genKeyPair()!!
Expand Down
1 change: 1 addition & 0 deletions ktor-server/ktor-server-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ kotlin.sourceSets {
api project(':ktor-utils')
api project(':ktor-http')

api group: 'com.typesafe', name: 'config', version: typesafe_config_version
api group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: kotlin_version
}
jvmTest.dependencies {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ fun LastModifiedVersion(lastModified: ZonedDateTime) : LastModifiedVersion = Las
/**
* Construct [LastModifiedVersion] version from a [FileTime] instance
*/
fun LastModifiedVersion(lastModified: FileTime) : LastModifiedVersion = LastModifiedVersion(GMTDate(lastModified.toMillis()))
fun LastModifiedVersion(lastModified: FileTime) : LastModifiedVersion =
LastModifiedVersion(GMTDate(lastModified.toMillis()))

Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ class LocalFileContent(
fun LocalFileContent(
baseDir: File, relativePath: String,
contentType: ContentType = ContentType.defaultForFilePath(relativePath)
): LocalFileContent = LocalFileContent(baseDir.combineSafe(relativePath), contentType)
): LocalFileContent =
LocalFileContent(baseDir.combineSafe(relativePath), contentType)

/**
* Creates an instance of [LocalFileContent] for a file designated by [relativePath] in a [baseDir]
*/
fun LocalFileContent(
baseDir: Path, relativePath: Path,
contentType: ContentType = ContentType.defaultForFile(relativePath)
): LocalFileContent = LocalFileContent(baseDir.combineSafe(relativePath), contentType)
): LocalFileContent =
LocalFileContent(baseDir.combineSafe(relativePath), contentType)
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import java.util.concurrent.*
/**
* Convert [Instant] to [GMTDate]
*/
fun Instant.toGMTDate(): GMTDate = GMTDate(TimeUnit.SECONDS.toMillis(atZone(ZoneOffset.UTC).toEpochSecond()))
fun Instant.toGMTDate(): GMTDate =
GMTDate(TimeUnit.SECONDS.toMillis(atZone(ZoneOffset.UTC).toEpochSecond()))

/**
* Convert [ZonedDateTime] to [GMTDate]
Expand Down
1 change: 1 addition & 0 deletions ktor-server/ktor-server-test-host/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ kotlin.sourceSets.jvmMain.dependencies {
api project(':ktor-server:ktor-server-core')
api project(':ktor-server:ktor-server-host-common')
api project(':ktor-network:ktor-network-tls')
api project(':ktor-network:ktor-network-tls:ktor-network-tls-certificates')
api project(':ktor-client:ktor-client-core')
api project(':ktor-client:ktor-client-jetty')
api project(':ktor-client:ktor-client-cio')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ class CompressionTest {
init {
versions += LastModifiedVersion(dateTime)
caching = CachingOptions(
cacheControl = CacheControl.NoCache(CacheControl.Visibility.Public),
expires = dateTime
cacheControl = CacheControl.NoCache(CacheControl.Visibility.Public),
expires = dateTime
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,12 @@ class StaticContentTest {
@Test
fun testSendLocalFile() = withTestApplication {
application.intercept(ApplicationCallPipeline.Call) {
call.respond(LocalFileContent(basedir, "/features/StaticContentTest.kt".replaceSeparators()))
call.respond(
LocalFileContent(
basedir,
"/features/StaticContentTest.kt".replaceSeparators()
)
)
}

handleRequest(HttpMethod.Get, "/").let { result ->
Expand Down Expand Up @@ -193,10 +198,20 @@ class StaticContentTest {
fun testSendLocalFileBadRelative() = withTestApplication {
application.intercept(ApplicationCallPipeline.Call) {
assertFailsWithSuspended<Exception> {
call.respond(LocalFileContent(basedir, "/../../../../../../../../../../../../../etc/passwd"))
call.respond(
LocalFileContent(
basedir,
"/../../../../../../../../../../../../../etc/passwd"
)
)
}
assertFailsWithSuspended<Exception> {
call.respond(LocalFileContent(basedir, "../../../../../../../../../../../../../etc/passwd"))
call.respond(
LocalFileContent(
basedir,
"../../../../../../../../../../../../../etc/passwd"
)
)
}
assertFailsWithSuspended<Exception> {
call.respond(LocalFileContent(basedir.toPath(), Paths.get("../build.gradle")))
Expand Down
Loading

0 comments on commit 06077ee

Please sign in to comment.