Skip to content
This repository has been archived by the owner on May 5, 2021. It is now read-only.

Commit

Permalink
Added support for client side certificate validation (#8)
Browse files Browse the repository at this point in the history
* Added support for client side certificate validation

* Added unit test with client side certificate validation

* Changed unit test from java to kotlin

* Added new line at the end
  • Loading branch information
Hakky54 committed Jul 31, 2020
1 parent 36997f8 commit ec07633
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import me.nikhilchaudhari.asynkio.helper.Auth
import me.nikhilchaudhari.asynkio.request.RequestImpl
import me.nikhilchaudhari.asynkio.response.Response
import me.nikhilchaudhari.asynkio.response.ResponseImpl
import javax.net.ssl.SSLContext

const val DEFAULT_TIMEOUT = 30.0

Expand All @@ -15,7 +16,7 @@ fun delete(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request(
"DELETE",
Expand All @@ -28,7 +29,8 @@ fun delete(
timeout,
allowRedirects,
stream,
files
files,
sslContext
)
}

Expand All @@ -37,27 +39,27 @@ fun get(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("GET", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("GET", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun head(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null,
json: Any? = null, timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("HEAD", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("HEAD", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun options(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request(
"OPTIONS",
Expand All @@ -70,7 +72,8 @@ fun options(
timeout,
allowRedirects,
stream,
files
files,
sslContext
)
}

Expand All @@ -79,42 +82,43 @@ fun patch(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("PATCH", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("PATCH", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun post(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("POST", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("POST", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun put(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("PUT", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("PUT", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun request(
method: String, url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null,
json: Any? = null, timeout: Double = DEFAULT_TIMEOUT,
allowRedirects: Boolean? = null, stream: Boolean = false, files: List<RawFiles> = listOf()
allowRedirects: Boolean? = null, stream: Boolean = false,
files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return ResponseImpl(
RequestImpl(
method, url, params, headers, auth, data,
json, timeout, allowRedirects, stream, files
json, timeout, allowRedirects, stream, files, sslContext
)
).run {
this.init()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package me.nikhilchaudhari.asynkio.request

import me.nikhilchaudhari.asynkio.helper.RawFiles
import me.nikhilchaudhari.asynkio.helper.Auth
import javax.net.ssl.SSLContext

interface Request {

Expand Down Expand Up @@ -29,4 +30,6 @@ interface Request {

val files: List<RawFiles>

val sslContext: SSLContext?

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import java.io.ByteArrayOutputStream
import java.io.File
import java.io.InputStream
import java.util.*
import javax.net.ssl.SSLContext


class RequestImpl internal constructor(
Expand All @@ -31,7 +32,8 @@ class RequestImpl internal constructor(
override val timeout: Double,
allowRedirects: Boolean?,
override val stream: Boolean,
override val files: List<RawFiles>
override val files: List<RawFiles>,
override val sslContext: SSLContext?
) : Request {

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import java.nio.charset.Charset
import java.util.*
import java.util.zip.GZIPInputStream
import java.util.zip.InflaterInputStream
import javax.net.ssl.HttpsURLConnection


class ResponseImpl internal constructor(override val request: Request) : Response {
Expand Down Expand Up @@ -141,6 +142,13 @@ class ResponseImpl internal constructor(override val request: Request) : Respons
connection.connectTimeout = timeout
connection.readTimeout = timeout
},
{ response, connection ->
response.request.sslContext?.let {
if (connection is HttpsURLConnection) {
connection.sslSocketFactory = it.socketFactory
}
}
},
{ _, connection ->
connection.instanceFollowRedirects = false
}
Expand Down Expand Up @@ -201,7 +209,8 @@ class ResponseImpl internal constructor(override val request: Request) : Respons
timeout = this.timeout,
allowRedirects = false,
stream = this.stream,
files = this.files
files = this.files,
sslContext = this.sslContext
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package me.nikhilchaudhari.asynkioapp

import me.nikhilchaudhari.asynkio.core.get
import org.hamcrest.CoreMatchers.equalTo
import org.junit.Assert.assertThat
import org.junit.Test
import java.nio.file.Files
import java.nio.file.Paths
import java.security.KeyStore
import javax.net.ssl.KeyManagerFactory
import javax.net.ssl.SSLContext

class NetworkCallTest {

@Test
fun executeGetRequestWithCertificateBasedClientAuthentication() {
val sslContext = createSslContextWithKeyMaterial()
val response = get(
url = "https://client.badssl.com/",
sslContext = sslContext
)
val statusCode = response.statusCode
if (statusCode == 400) {
println("Please validate if certificate is not expired")
} else {
assertThat(statusCode, equalTo(200))
}
}

private fun createSslContextWithKeyMaterial(): SSLContext {
val keyStorePath = "src/test/resources/badssl.com-client.jks"
val keyStorePassword = "badssl.com".toCharArray()
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())

Files.newInputStream(Paths.get(keyStorePath))
.use { keyStoreInputStream -> keyStore.load(keyStoreInputStream, keyStorePassword) }

val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
keyManagerFactory.init(keyStore, keyStorePassword)

val keyManagers = keyManagerFactory.keyManagers

val sslContext = SSLContext.getInstance("TLSv1.2")
sslContext.init(keyManagers, null, null)

return sslContext
}
}
Binary file added asynkio/src/test/resources/badssl.com-client.jks
Binary file not shown.

0 comments on commit ec07633

Please sign in to comment.