Skip to content

Commit

Permalink
Utkast til tjeneste i cpa repo for henting av public sertifikat for k…
Browse files Browse the repository at this point in the history
…ryptering
  • Loading branch information
thburnett committed Sep 18, 2023
1 parent c8f1dac commit 7d6f645
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 22 deletions.
1 change: 1 addition & 0 deletions cpa-repo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ dependencies {
implementation("jakarta.xml.bind:jakarta.xml.bind-api:4.0.0", )
implementation("org.glassfish.jaxb:jaxb-runtime:2.4.0-b180830.0438")
implementation("no.nav.emottak:ebxml-protokoll:0.0.4")
implementation("ch.qos.logback:logback-classic:1.4.11")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
}
Expand Down
33 changes: 22 additions & 11 deletions cpa-repo/src/main/kotlin/no/nav/emottak/cpa/App.kt
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
/*
* This Kotlin source file was generated by the Gradle 'init' task.
*/
package no.nav.emottak.cpa

import io.ktor.http.content.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.application.call
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.plugins.BadRequestException
import io.ktor.server.plugins.NotFoundException
import io.ktor.server.response.respond
import io.ktor.server.routing.get
import io.ktor.server.routing.routing

fun main() {

embeddedServer(Netty, port = 8080) {

routing {
get("/cpa") {
call.respondText("Hello, world!")
get("/cpa/{id}") {
val cpaId = call.parameters["id"] ?: throw BadRequestException("Mangler CPA ID")
val cpa = getCpa(cpaId) ?: throw NotFoundException("Fant ikke CPA")
call.respond(cpa)
}

get("/cpa/{id}/{herId}/certificate/encryption") {
val cpaId = call.parameters["id"] ?: throw BadRequestException("Mangler CPA ID")
val herId = call.parameters["herId"] ?: throw BadRequestException("Mangler HER ID")
val cpa = getCpa(cpaId) ?: throw NotFoundException("Fant ikke CPA")

call.respond(cpa.getCertificateForEncryption(herId))
}
}
}.start(wait = true)

}
34 changes: 34 additions & 0 deletions cpa-repo/src/main/kotlin/no/nav/emottak/cpa/CPAUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package no.nav.emottak.cpa

import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.Certificate
import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.CollaborationProtocolAgreement
import org.w3._2000._09.xmldsig_.X509DataType
import javax.xml.bind.JAXBElement

private val cpaUtil = CPAUtil()

fun getCpa(id: String) = cpaUtil.getCpa(id)


private class CPAUtil {

fun getCpa(id: String): CollaborationProtocolAgreement? {
//TODO
val testCpaString = String(this::class.java.classLoader.getResource("nav-qass-35065.xml").readBytes())
return unmarshal(testCpaString, CollaborationProtocolAgreement::class.java)
}

}

fun CollaborationProtocolAgreement.getCertificateForEncryption(herId: String): ByteArray {
val partyInfo = this.partyInfo.first { partyInfo ->
partyInfo.partyId.any { partyId ->
partyId.type == "HER" && partyId.value == herId
}
}
val encryptionCert = partyInfo.collaborationRole.first().applicationCertificateRef.first().certId as Certificate
val datatype =
encryptionCert.keyInfo.content?.filterIsInstance(JAXBElement::class.java)?.firstOrNull()?.value as X509DataType
return datatype.x509IssuerSerialOrX509SKIOrX509SubjectName?.filterIsInstance(JAXBElement::class.java)
?.firstOrNull()?.value as ByteArray
}
36 changes: 36 additions & 0 deletions cpa-repo/src/main/kotlin/no/nav/emottak/cpa/XmlMarshaller.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package no.nav.emottak.cpa

import java.io.StringWriter
import javax.xml.bind.JAXBContext
import javax.xml.stream.XMLInputFactory

private val xmlMarshaller = XmlMarshaller()

fun marshal(objekt: Any) = xmlMarshaller.marshal(objekt)
fun <T> unmarshal(xml: String, clazz: Class<T>) : T = xmlMarshaller.unmarshal(xml , clazz)

class XmlMarshaller {

companion object {
private val jaxbContext = JAXBContext.newInstance(
org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.ObjectFactory::class.java,
org.oasis_open.committees.ebxml_msg.schema.msg_header_2_0.ObjectFactory::class.java,
org.xmlsoap.schemas.soap.envelope.ObjectFactory::class.java,
org.w3._1999.xlink.ObjectFactory::class.java,
org.w3._2009.xmldsig11_.ObjectFactory::class.java
);
private val marshaller = jaxbContext.createMarshaller()
private val unmarshaller = jaxbContext.createUnmarshaller()
}

fun marshal(objekt: Any) : String {
val writer = StringWriter()
marshaller.marshal(objekt,writer)
return writer.toString()
}

fun <T> unmarshal(xml: String, clazz: Class<T>) : T {
val reader = XMLInputFactory.newInstance().createXMLStreamReader(xml.reader())
return unmarshaller.unmarshal(reader, clazz).value
}
}
4 changes: 4 additions & 0 deletions ebms-provider/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ tasks.register<Wrapper>("wrapper") {
gradleVersion="8.1.1"
}

tasks.test {
useJUnitPlatform()
}

dependencies {
implementation("io.ktor:ktor-server-core:2.3.4")
implementation("io.ktor:ktor-server-netty:2.3.4")
Expand Down
2 changes: 2 additions & 0 deletions payload-processor/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ dependencies {
implementation("io.ktor:ktor-server-call-logging-jvm:2.3.4")
implementation("io.ktor:ktor-server-content-negotiation:2.3.4")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.4")
implementation("io.ktor:ktor-client-core:2.3.4")
implementation("io.ktor:ktor-client-cio:2.3.4")
implementation("jakarta.xml.bind:jakarta.xml.bind-api:4.0.0", )
implementation("org.glassfish.jaxb:jaxb-runtime:4.0.3")
implementation("org.bouncycastle:bcprov-jdk18on:1.76")
Expand Down
4 changes: 2 additions & 2 deletions payload-processor/src/main/kotlin/no/nav/emottak/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ private fun Application.serverSetup() {
conversationId = UUID.randomUUID().toString(),
cpaId = UUID.randomUUID().toString(),
to = Party(
"12345",
herID = "8141253",
role = "mottaker"
),
from = Party(
"54321",
herID = "54321",
role = "sender"
),
service = "melding",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package no.nav.emottak.melding.process
import io.ktor.server.plugins.BadRequestException
import no.nav.emottak.melding.model.Header
import no.nav.emottak.melding.model.Melding
import no.nav.emottak.util.hentKrypteringssertifikat
import org.bouncycastle.asn1.ASN1ObjectIdentifier
import org.bouncycastle.cms.CMSAlgorithm
import org.bouncycastle.cms.CMSEnvelopedDataGenerator
Expand Down Expand Up @@ -44,11 +45,6 @@ class Kryptering {

}

fun hentKrypteringssertifikat(cpaId: String, herId: String): ByteArray {
//TODO Hent krypteringssertifikat fra CPA
return this::class.java.classLoader.getResource("xml/cert.pem").readBytes()
}

}

private val encryptionAlgorithm: ASN1ObjectIdentifier = CMSAlgorithm.DES_EDE3_CBC
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package no.nav.emottak.util


internal fun getEnvVar(varName: String, defaultValue: String? = null) =
System.getenv(varName) ?:
System.getProperty(varName) ?:
defaultValue ?: throw RuntimeException("Missing required variable $varName")






Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package no.nav.emottak.util

import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import io.ktor.client.request.request
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.readBytes
import io.ktor.http.HttpMethod
import kotlinx.coroutines.runBlocking


private val httpClientUtil = HttpClientUtil()
private val cpaRepoUrl = "http://cpa-repo"

fun hentKrypteringssertifikat(cpaId: String, herId: String): ByteArray = runBlocking {
httpClientUtil.makeHttpRequest("$cpaRepoUrl/cpa/$cpaId/$herId/certificate/encryption").readBytes()
}

class HttpClientUtil {

private val client = HttpClient(CIO) {
expectSuccess = true
}

suspend fun makeHttpRequest(urlString: String): HttpResponse {
val response: HttpResponse = client.request(urlString) {
method = HttpMethod.Get
}
return response
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,3 @@ internal class KeyStoreUtil {
}
}

private fun getEnvVar(varName: String, defaultValue: String? = null) =
System.getenv(varName) ?:
System.getProperty(varName) ?:
defaultValue ?: throw RuntimeException("Missing required variable $varName")

0 comments on commit 7d6f645

Please sign in to comment.