From 9f6f06edcc2e26c569e23c791bba870aed801c0a Mon Sep 17 00:00:00 2001 From: Carlos Schmidt <18703981+carlos-schmidt@users.noreply.github.com> Date: Tue, 16 May 2023 20:19:49 +0200 Subject: [PATCH 1/4] Add self-signed cert and https config --- .../configurations/provider-https.properties | 52 ++++++++++++++++++ ...ataspaceconnector-configuration.properties | 6 ++ example/resources/keystore.pkcs | Bin 0 -> 2742 bytes 3 files changed, 58 insertions(+) create mode 100644 example/configurations/provider-https.properties create mode 100644 example/resources/keystore.pkcs diff --git a/example/configurations/provider-https.properties b/example/configurations/provider-https.properties new file mode 100644 index 00000000..a35730b3 --- /dev/null +++ b/example/configurations/provider-https.properties @@ -0,0 +1,52 @@ +# HTTPS config +edc.web.https.keystore.password = password +edc.web.https.keymanager.password = password +edc.web.https.keystore.path = ./example/resources/keystore.pkcs +edc.web.https.keystore.type = PKCS12 + +# AAS Extension specific +edc.aas.logPrefix = EDC-AAS-Extension +# Supply AAS model + (port XOR AAS service config) for an AAS service internally started by the extension +edc.aas.localAASModelPath = ./example/resources/FestoDemoAAS.json +edc.aas.localAASServicePort = 8080 +# edc.aas.localAASServiceConfigPath = ./example/resources/exampleConfig.json +# Provide a URL of an already running AAS service (such as FA³ST, BaSyx) +# edc.aas.remoteAasLocation = http://example.com/aas +# Period of synchronizing the EDC assetStore with the connected AAS services (in seconds) +edc.aas.syncPeriod = 100 +# Expose self description +# Path to a default access policy definition file +# edc.aas.defaultAccessPolicyDefinitionPath = ... +# Path to a default contract policy definition file +# edc.aas.defaultContractPolicyDefinitionPath = ... + + +# EDC specific, mostly default values +# Port and path for custom http services such as SelfDescription +web.http.port=8181 +web.http.path=/api +# Port and path for requesting an EDC to communicate with another EDC by IDS messages (consumer-provider) +web.http.data.port=8182 +web.http.data.path=/api/v1/data +# Port and path for IDS messages (from another EDC) +web.http.ids.port = 8282 +web.http.ids.path = /api/v1/ids + +edc.transfer.functions.enabled.protocols = http +# Connector hostname, which e.g. is used in referer urls +edc.hostname = localhost +# Auth key for using internal EDC api (header key: x-api-key) +edc.api.auth.key=password + +# IDS specific (see EDC/data-protocols/ids/ids-core/README.md) +edc.ids.id = urn:connector:provider +edc.ids.title = "Eclipse Dataspace Connector with AAS support" +edc.ids.description = "EDC with extension IDS-AAS-App enabled" +edc.ids.maintainer = iosb +edc.ids.curator = https://example.com +edc.ids.endpoint = https://example.com +edc.ids.security.profile = base +edc.ids.catalog.id = urn:catalog:default + +# Set this to the address at which another connector can reach your connector, as it is used as a callback address during the contract negotiation, where messages are exchanged asynchronously. If you change the IDS API port, make sure to adjust the webhook address accordingly. +ids.webhook.address=http://localhost:8282 diff --git a/example/dataspaceconnector-configuration.properties b/example/dataspaceconnector-configuration.properties index 67ac4a00..548d2048 100644 --- a/example/dataspaceconnector-configuration.properties +++ b/example/dataspaceconnector-configuration.properties @@ -1,3 +1,9 @@ +# HTTPS config +edc.web.https.keystore.password = password +edc.web.https.keymanager.password = password +edc.web.https.keystore.path = ./example/resources/keystore.pkcs +edc.web.https.keystore.type = PKCS12 + # Useful for debugging the extension since this will automatically be called when no config parameter is given # AAS Extension specific edc.aas.logPrefix = EDC-AAS-Extension diff --git a/example/resources/keystore.pkcs b/example/resources/keystore.pkcs new file mode 100644 index 0000000000000000000000000000000000000000..937aec8141baa75f33dd86e83208f402122fbbfc GIT binary patch literal 2742 zcma);X*d*&7RP7C7>zv!*@?y$X2vds5M_BKDI(OE2(M6>vNg(by~)03*VuPsMwFcl zV{K$oNn^`4q=q4```r8VKKIkTAI@{0^Z%d!`S^Pd0>{|^0lLyEF zEWmMEgK?Y}k7P3hj=k!?EcO>*9DCN0oOV=65U&5ExH*BK0vx;1k!XOx{7$g*ARH08 ze~;V<6)^0%Vl|^nzA^OPxuVT2I`Hc?40ZwpQs4&xWf0tuWB6W0Au91nSJXjBVZhO^g=Mj)ZfDPqC;XK%HFOt*dEmVP3OYMU(Z_0 zgx||W*_F+^52)VvK%1;k`1(}Os-xHLV3fBiP2In@jyO>5LloAW4tcNvm-eq9<7%2t zE|z%oV!}2{N6D>#jH$ND?KqC`TSRDQ(q8_gs#d5^a(O^B5NaHsa3$|^5xc2rnN7L) zl?#d|&NvI*;Hsw9li##mE?uYU%w$Zj5#K!b;!_V7l9o4|9ex*G*k~Ar6i-i;yFP6Q zr4)pJ3@BGhE?vCtO6%!t39PZ>caDnekl44n%u)V<_JIWm_y9|ZH@eVs0%BKuJSC^G zpE`p3D(5_@g|FSAbB;-Xo>J0$1!NJ+x}E21q6@o77W2C(2~jh+P=RX0Qk0-CsHEC< z8O1iVK9$vYLHoKXT0d|$GIg{}?T4YQP3FLmpvuB#f5{hB7G`1F+mv>DGeAxQmzF$= zRVR2=2feZVDPCSdcha~>ES+F3E}<}z9ox$%vZZTh|L9Q+lngS4J-6}Xg89HcS3aEI z6A3>r6}u>j*k3nqTosiD6rSmKOI^>;T&c`YH`lC4CfF(5*eJX14d&D*y>RXO{K zB&fSbe-+m%;n05vo=4vFp*Gg-p8H<+bO^F`b0nstrzqIp)k0_iMDHPo$#XNvnvRLb z9m6P&lHIM7sk^}u%>@tMEQglzseg$S6Wn~skcjl0IP~k8t@4%aEa`r+8^uS^>$y5Q z%aCY~8XNM1TUsPI@!Tnk^Ag?iQ93mlR88(R?&5v zOA9-n$Q?iQbN;gNPwd3lV*gtC1F8t`bi|Lh846q3;dxOmivgD&U%h$g*SA%@s6gW* z^)$97xvdGtvK|w?Ck=WDkiS;9bkeD-@?1~G36`%uh8js1mtm+WQc9`@Z-HhW6H)fb zdt&2r$n4lVe5Zz62>Sfk6(lpZdt9S#gX|LUmaazne6WR>-;P6z^?9{9d0RwRMWMx` zA{C!$FOa(0XugKr7Bk8c?op4Vg=1mzEi}nX0C{myu4{z{jq1Yo_mWBc5Ai9JT8-;t z^g)XB`fTy7!8s5cwtR6oa5tmUgG8Zf8vIldxbR#}hZ#Wbw(6CWl0ALk(3IfLh4m|! zqxSXrBhC*P;qRvIE-gWag=9BnVeA!HIcMQ_>H6ttRDzS>_pZ2?^kKbv$*_LN;`EOO zKI@__jWU3jkA*$CEkyiDoMOZSiD#@ASEuXP)QSYel3jLx0Z`z7eEIxcdTvNQ1)un- z)AdVzj0**8FRIYn3?z;KISlhx9>h~_iLYfjR+9H8=yo?zQIl6 z$IVR&%kdtg-UEn?F->CwjK2w@HNl-)w>3TR00yObR&A20CiduSkHydD#wU{%H&ptP zn>E)e1Gm1WC%w)op$WXo0>>JEbLT2fB4g4#ZB)Su9BaCwv4foHO34d zauzFl8gIqfGu)`qyPuT9ZBIJAmFG4|Lp+(7o?lc9iLZ3-^iW|wap<$Fh5;ta;X1*Ablym zddx}bWN_-p;l6FT?d3=u7$672(sEoGZgK-ipg$Ms#ODNGKfBJ9TB>K!Gvf!5zJO#( z*%$9}Y0HL2>>-J_R&%xMbx-q7hS|q%u80JW`cnZGm~Lj~J9pF9uuns(PpN9(ALi!9 z&7h2G+g-cwj5sPF=;F!E!s-&eZ?h>;H^P6J%WJqfXjKFV_w3mp%jSewMGWqJgRagy zE0?vF0*%Ma3gsbb%44IC+NP2_u?A?3H-X$b{ZcZeys6Bqva0V+mo;m@9|g2WOASF{ zV+8K?s?gD&TxZ2tjixuYi}^nq*q+Kin6rKzBxRNv#q;WxlkoZ>c*iTGXyU4EnVOUC zJ2)I5Pr08VgJ&s;*7l>rcs{pP=+4Kt@}yxaEkoeT0!sNyXCdi<1@lf%+p#u=ex{!= zrcXq2%h!cOQ2G{gHgUmSjKDeD>Pe0ucYk@w7K!Y3tyN+wvd%YYrdX{8fLwi$kN3i^ zxKsa}pr;3tc)+Iy-!?EI{ns-F7ngK-8zz;6Sf2T7^GzYI=5Bq}U)lC2BR`;7n0w|D ze`F-q-j#sev-i;!z5AYIV7jM$&59OE*o?Gx)OykG<1dy_EAfQy_J_Mqv<7elVB5A% z|8gbcn)R`Rsg4-Z){veLd4JSqoJ?_*{)bS=G1#f*g&DV{j3CB1ugaAVZ<#i$Xgjx- za)Ea(xf_X$Y^f%0jWaGt&cWcBra%lm4-g@MI%1akQY<)scQD~~A>D9{W#qLA*EgQw zuI6+1kWSO9%OZg1%B`#cre0R_|*O zdGJkeT2rnWei&uYw;c~fwY4jp8H)L8D-BaozFwg7hjwn|FSc*>4|sV>d~^ZdL}LBw z#Kk)DVE1(>B~J~n*S{RKWZ7q%?-AQ>`W(1*{rXZ5t}N*VAw3wz=!!thN5< zn;8nNK)vSDxPYS(aS1 zi;F?4FHJ0(<8Rh7)}B8Espw~l#t*jCHZ^|PKKtW9VX|%~t2yV292bba Date: Tue, 16 May 2023 20:43:01 +0200 Subject: [PATCH 2/4] Add consumer https config --- .../configurations/consumer-https.properties | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 example/configurations/consumer-https.properties diff --git a/example/configurations/consumer-https.properties b/example/configurations/consumer-https.properties new file mode 100644 index 00000000..3bb5dead --- /dev/null +++ b/example/configurations/consumer-https.properties @@ -0,0 +1,39 @@ +# HTTPS config +edc.web.https.keystore.password = password +edc.web.https.keymanager.password = password +edc.web.https.keystore.path = ./example/resources/keystore.pkcs +edc.web.https.keystore.type = PKCS12 + +# IDS AAS Extension specific +edc.aas.logPrefix = EDC-AAS-Extension-Consumer +edc.aas.exposeSelfDescription = False +# Timeouts in seconds +edc.aas.client.waitForAgreementTimeout = 15 +edc.aas.client.waitForTransferTimeout = 30 +edc.aas.client.acceptAllProviderOffers = true +edc.aas.client.acceptedContractOffersPath = ./example/resources/acceptedContractOffers.json +# EDC specific values +web.http.port=9191 +web.http.path=/api +web.http.data.port=9192 +web.http.data.path=/api/v1/data +web.http.ids.port = 9292 +web.http.ids.path = /api/v1/ids + +edc.api.auth.key=password + +# IDS specific (see EDC/data-protocols/ids/ids-core/README.md) +edc.ids.id = urn:connector:consumer +edc.ids.title = "Eclipse Dataspace Connector with AAS support" +edc.ids.description = "EDC with extension IDS-AAS-App enabled" +edc.ids.maintainer = iosb +edc.ids.curator = https://example.com +edc.ids.endpoint = https://example.com +edc.ids.security.profile = base +edc.ids.catalog.id = urn:catalog:default + +# Set this to the address at which another connector can reach your connector, +# as it is used as a callback address during the contract negotiation, +# where messages are exchanged asynchronously. If you change the IDS API port, +# make sure to adjust the webhook address accordingly. +ids.webhook.address=http://localhost:9292 From ba0ab1d86e7c84686eb69fca4cbebc1e78f7d170 Mon Sep 17 00:00:00 2001 From: Carlos Schmidt <18703981+carlos-schmidt@users.noreply.github.com> Date: Mon, 22 May 2023 15:06:50 +0200 Subject: [PATCH 3/4] Fix: Config files using old binding names --- example/configurations/consumer-https.properties | 11 ++++++----- example/configurations/provider-https.properties | 8 ++++---- example/dataspaceconnector-configuration.properties | 6 +++--- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/example/configurations/consumer-https.properties b/example/configurations/consumer-https.properties index 3bb5dead..4e74b86c 100644 --- a/example/configurations/consumer-https.properties +++ b/example/configurations/consumer-https.properties @@ -12,13 +12,14 @@ edc.aas.client.waitForAgreementTimeout = 15 edc.aas.client.waitForTransferTimeout = 30 edc.aas.client.acceptAllProviderOffers = true edc.aas.client.acceptedContractOffersPath = ./example/resources/acceptedContractOffers.json + # EDC specific values web.http.port=9191 web.http.path=/api -web.http.data.port=9192 -web.http.data.path=/api/v1/data -web.http.ids.port = 9292 -web.http.ids.path = /api/v1/ids +web.http.management.port=9192 +web.http.management.path=/api/v1/data +web.http.protocol.port = 9292 +web.http.protocol.path = /api/v1/ids edc.api.auth.key=password @@ -36,4 +37,4 @@ edc.ids.catalog.id = urn:catalog:default # as it is used as a callback address during the contract negotiation, # where messages are exchanged asynchronously. If you change the IDS API port, # make sure to adjust the webhook address accordingly. -ids.webhook.address=http://localhost:9292 +ids.webhook.address=https://localhost:9292 diff --git a/example/configurations/provider-https.properties b/example/configurations/provider-https.properties index a35730b3..98c893e9 100644 --- a/example/configurations/provider-https.properties +++ b/example/configurations/provider-https.properties @@ -26,11 +26,11 @@ edc.aas.syncPeriod = 100 web.http.port=8181 web.http.path=/api # Port and path for requesting an EDC to communicate with another EDC by IDS messages (consumer-provider) -web.http.data.port=8182 -web.http.data.path=/api/v1/data +web.http.management.port=8182 +web.http.management.path=/api/v1/data # Port and path for IDS messages (from another EDC) -web.http.ids.port = 8282 -web.http.ids.path = /api/v1/ids +web.http.protocol.port = 8282 +web.http.protocol.path = /api/v1/ids edc.transfer.functions.enabled.protocols = http # Connector hostname, which e.g. is used in referer urls diff --git a/example/dataspaceconnector-configuration.properties b/example/dataspaceconnector-configuration.properties index 4fcef69a..ac383cd5 100644 --- a/example/dataspaceconnector-configuration.properties +++ b/example/dataspaceconnector-configuration.properties @@ -1,7 +1,7 @@ # HTTPS config edc.web.https.keystore.password = password edc.web.https.keymanager.password = password -edc.web.https.keystore.path = ./example/resources/keystore.pkcs +edc.web.https.keystore.path = ./resources/keystore.pkcs edc.web.https.keystore.type = PKCS12 # Useful for debugging the extension since this will automatically be called when no config parameter is given @@ -41,7 +41,7 @@ web.http.management.path=/api/v1/data web.http.protocol.port = 8282 web.http.protocol.path = /api/v1/ids -edc.transfer.functions.enabled.protocols = http +edc.transfer.functions.enabled.protocols = https # Connector hostname, which e.g. is used in referer urls edc.hostname = localhost # Auth key for using internal EDC api (header key: x-api-key) @@ -58,4 +58,4 @@ edc.ids.security.profile = base edc.ids.catalog.id = urn:catalog:default # Set this to the address at which another connector can reach your connector, as it is used as a callback address during the contract negotiation, where messages are exchanged asynchronously. If you change the IDS API port, make sure to adjust the webhook address accordingly. -ids.webhook.address=http://localhost:8282 +ids.webhook.address=https://localhost:8282 From 8d6f27bd783a8271e3e3b5ea851a9fbe6f8f2972 Mon Sep 17 00:00:00 2001 From: Carlos Schmidt <18703981+carlos-schmidt@users.noreply.github.com> Date: Mon, 22 May 2023 15:07:37 +0200 Subject: [PATCH 4/4] Recreate self-signed cert keystore Created with KeyStore Explorer + Java11 --- example/resources/keystore.pkcs | Bin 2742 -> 2645 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/example/resources/keystore.pkcs b/example/resources/keystore.pkcs index 937aec8141baa75f33dd86e83208f402122fbbfc..9cccf33983f2a6be3d34bfaaf5d14df6676e2511 100644 GIT binary patch delta 2619 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