mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
Merge pull request #717 from corda/os-merge-ecce64b
O/S merge from ecce64b
This commit is contained in:
commit
973f6c0c08
@ -43,6 +43,7 @@ import java.io.*
|
|||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.HttpURLConnection.HTTP_OK
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
@ -362,10 +363,11 @@ val KClass<*>.packageName: String get() = java.`package`.name
|
|||||||
|
|
||||||
fun URL.openHttpConnection(): HttpURLConnection = openConnection() as HttpURLConnection
|
fun URL.openHttpConnection(): HttpURLConnection = openConnection() as HttpURLConnection
|
||||||
|
|
||||||
fun URL.post(serializedData: OpaqueBytes): ByteArray {
|
fun URL.post(serializedData: OpaqueBytes, vararg properties: Pair<String, String>): ByteArray {
|
||||||
return openHttpConnection().run {
|
return openHttpConnection().run {
|
||||||
doOutput = true
|
doOutput = true
|
||||||
requestMethod = "POST"
|
requestMethod = "POST"
|
||||||
|
properties.forEach { (key, value) -> setRequestProperty(key, value) }
|
||||||
setRequestProperty("Content-Type", "application/octet-stream")
|
setRequestProperty("Content-Type", "application/octet-stream")
|
||||||
outputStream.use { serializedData.open().copyTo(it) }
|
outputStream.use { serializedData.open().copyTo(it) }
|
||||||
checkOkResponse()
|
checkOkResponse()
|
||||||
@ -374,12 +376,13 @@ fun URL.post(serializedData: OpaqueBytes): ByteArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun HttpURLConnection.checkOkResponse() {
|
fun HttpURLConnection.checkOkResponse() {
|
||||||
if (responseCode != 200) {
|
if (responseCode != HTTP_OK) {
|
||||||
val message = errorStream.use { it.reader().readText() }
|
throw IOException("Response Code $responseCode: $errorMessage")
|
||||||
throw IOException("Response Code $responseCode: $message")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val HttpURLConnection.errorMessage: String? get() = errorStream?.let { it.use { it.reader().readText() } }
|
||||||
|
|
||||||
inline fun <reified T : Any> HttpURLConnection.responseAs(): T {
|
inline fun <reified T : Any> HttpURLConnection.responseAs(): T {
|
||||||
checkOkResponse()
|
checkOkResponse()
|
||||||
return inputStream.readObject()
|
return inputStream.readObject()
|
||||||
|
@ -20,6 +20,7 @@ import net.corda.core.crypto.Crypto
|
|||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.CertRole
|
import net.corda.core.internal.CertRole
|
||||||
|
import net.corda.core.internal.errorMessage
|
||||||
import net.corda.core.internal.post
|
import net.corda.core.internal.post
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
@ -28,7 +29,6 @@ import net.corda.node.utilities.registration.cacheControl
|
|||||||
import net.corda.nodeapi.internal.crypto.*
|
import net.corda.nodeapi.internal.crypto.*
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
|
import net.corda.nodeapi.internal.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
|
||||||
import net.corda.testing.internal.createDevIntermediateCaCertPath
|
import net.corda.testing.internal.createDevIntermediateCaCertPath
|
||||||
import org.apache.commons.io.IOUtils
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.bouncycastle.asn1.ASN1ObjectIdentifier
|
import org.bouncycastle.asn1.ASN1ObjectIdentifier
|
||||||
import org.bouncycastle.asn1.DERUTF8String
|
import org.bouncycastle.asn1.DERUTF8String
|
||||||
@ -47,7 +47,6 @@ import java.io.IOException
|
|||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
import java.net.HttpURLConnection.*
|
import java.net.HttpURLConnection.*
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.charset.StandardCharsets.UTF_8
|
|
||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
import java.security.cert.CertPath
|
import java.security.cert.CertPath
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
@ -252,8 +251,8 @@ class RegistrationWebServiceTest : TestBase() {
|
|||||||
}
|
}
|
||||||
PollResponse.Ready(certificates)
|
PollResponse.Ready(certificates)
|
||||||
}
|
}
|
||||||
HTTP_NO_CONTENT -> PollResponse.NotReady(conn.cacheControl().maxAgeSeconds())
|
HTTP_NO_CONTENT -> PollResponse.NotReady(conn.cacheControl.maxAgeSeconds())
|
||||||
HTTP_UNAUTHORIZED -> PollResponse.Unauthorised(IOUtils.toString(conn.errorStream, UTF_8))
|
HTTP_UNAUTHORIZED -> PollResponse.Unauthorised(conn.errorMessage)
|
||||||
else -> throw IOException("Cannot connect to Certificate Signing Server, HTTP response code : ${conn.responseCode}")
|
else -> throw IOException("Cannot connect to Certificate Signing Server, HTTP response code : ${conn.responseCode}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,6 +268,6 @@ class RegistrationWebServiceTest : TestBase() {
|
|||||||
private interface PollResponse {
|
private interface PollResponse {
|
||||||
data class NotReady(val pollInterval: Int) : PollResponse
|
data class NotReady(val pollInterval: Int) : PollResponse
|
||||||
data class Ready(val certChain: List<X509Certificate>) : PollResponse
|
data class Ready(val certChain: List<X509Certificate>) : PollResponse
|
||||||
data class Unauthorised(val message: String) : PollResponse
|
data class Unauthorised(val message: String?) : PollResponse
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -58,7 +58,7 @@ class NetworkMapClient(compatibilityZoneURL: URL, val trustedRoot: X509Certifica
|
|||||||
val connection = networkMapUrl.openHttpConnection()
|
val connection = networkMapUrl.openHttpConnection()
|
||||||
val signedNetworkMap = connection.responseAs<SignedNetworkMap>()
|
val signedNetworkMap = connection.responseAs<SignedNetworkMap>()
|
||||||
val networkMap = signedNetworkMap.verifiedNetworkMapCert(trustedRoot)
|
val networkMap = signedNetworkMap.verifiedNetworkMapCert(trustedRoot)
|
||||||
val timeout = connection.cacheControl().maxAgeSeconds().seconds
|
val timeout = connection.cacheControl.maxAgeSeconds().seconds
|
||||||
logger.trace { "Fetched network map update from $networkMapUrl successfully: $networkMap" }
|
logger.trace { "Fetched network map update from $networkMapUrl successfully: $networkMap" }
|
||||||
return NetworkMapResponse(networkMap, timeout)
|
return NetworkMapResponse(networkMap, timeout)
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,14 @@
|
|||||||
|
|
||||||
package net.corda.node.utilities.registration
|
package net.corda.node.utilities.registration
|
||||||
|
|
||||||
import com.google.common.net.MediaType
|
import net.corda.core.internal.errorMessage
|
||||||
import net.corda.core.internal.openHttpConnection
|
import net.corda.core.internal.openHttpConnection
|
||||||
|
import net.corda.core.internal.post
|
||||||
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
||||||
import okhttp3.CacheControl
|
import okhttp3.CacheControl
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import org.apache.commons.io.IOUtils
|
|
||||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
@ -31,7 +32,7 @@ class HTTPNetworkRegistrationService(compatibilityZoneURL: URL) : NetworkRegistr
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// TODO: Propagate version information from gradle
|
// TODO: Propagate version information from gradle
|
||||||
val clientVersion = "1.0"
|
const val CLIENT_VERSION = "1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(CertificateRequestException::class)
|
@Throws(CertificateRequestException::class)
|
||||||
@ -39,7 +40,7 @@ class HTTPNetworkRegistrationService(compatibilityZoneURL: URL) : NetworkRegistr
|
|||||||
// Poll server to download the signed certificate once request has been approved.
|
// Poll server to download the signed certificate once request has been approved.
|
||||||
val conn = URL("$registrationURL/$requestId").openHttpConnection()
|
val conn = URL("$registrationURL/$requestId").openHttpConnection()
|
||||||
conn.requestMethod = "GET"
|
conn.requestMethod = "GET"
|
||||||
val maxAge = conn.cacheControl().maxAgeSeconds()
|
val maxAge = conn.cacheControl.maxAgeSeconds()
|
||||||
// Default poll interval to 10 seconds if not specified by the server, for backward compatibility.
|
// Default poll interval to 10 seconds if not specified by the server, for backward compatibility.
|
||||||
val pollInterval = if (maxAge == -1) 10.seconds else maxAge.seconds
|
val pollInterval = if (maxAge == -1) 10.seconds else maxAge.seconds
|
||||||
|
|
||||||
@ -54,33 +55,15 @@ class HTTPNetworkRegistrationService(compatibilityZoneURL: URL) : NetworkRegistr
|
|||||||
}
|
}
|
||||||
HTTP_NO_CONTENT -> CertificateResponse(pollInterval, null)
|
HTTP_NO_CONTENT -> CertificateResponse(pollInterval, null)
|
||||||
HTTP_UNAUTHORIZED -> throw CertificateRequestException("Certificate signing request has been rejected: ${conn.errorMessage}")
|
HTTP_UNAUTHORIZED -> throw CertificateRequestException("Certificate signing request has been rejected: ${conn.errorMessage}")
|
||||||
else -> throwUnexpectedResponseCode(conn)
|
else -> throw IOException("Response Code ${conn.responseCode}: ${conn.errorMessage}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun submitRequest(request: PKCS10CertificationRequest): String {
|
override fun submitRequest(request: PKCS10CertificationRequest): String {
|
||||||
// Post request to certificate signing server via http.
|
return String(registrationURL.post(OpaqueBytes(request.encoded), "Client-Version" to CLIENT_VERSION))
|
||||||
val conn = URL("$registrationURL").openHttpConnection()
|
|
||||||
conn.doOutput = true
|
|
||||||
conn.requestMethod = "POST"
|
|
||||||
conn.setRequestProperty("Content-Type", MediaType.OCTET_STREAM.toString())
|
|
||||||
conn.setRequestProperty("Client-Version", clientVersion)
|
|
||||||
conn.outputStream.write(request.encoded)
|
|
||||||
|
|
||||||
return when (conn.responseCode) {
|
|
||||||
HTTP_OK -> IOUtils.toString(conn.inputStream, conn.charset)
|
|
||||||
HTTP_FORBIDDEN -> throw IOException("Client version $clientVersion is forbidden from accessing permissioning server, please upgrade to newer version.")
|
|
||||||
else -> throwUnexpectedResponseCode(conn)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun throwUnexpectedResponseCode(connection: HttpURLConnection): Nothing {
|
val HttpURLConnection.cacheControl: CacheControl get() {
|
||||||
throw IOException("Unexpected response code ${connection.responseCode} - ${connection.errorMessage}")
|
return CacheControl.parse(Headers.of(headerFields.filterKeys { it != null }.mapValues { it.value[0] }))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val HttpURLConnection.charset: String get() = MediaType.parse(contentType).charset().or(Charsets.UTF_8).name()
|
|
||||||
|
|
||||||
private val HttpURLConnection.errorMessage: String get() = IOUtils.toString(errorStream, charset)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun HttpURLConnection.cacheControl(): CacheControl = CacheControl.parse(Headers.of(headerFields.filterKeys { it != null }.mapValues { it.value[0] }))
|
|
||||||
|
Loading…
Reference in New Issue
Block a user