diff --git a/certs/How-to-setup-did-signing.md b/certs/How-to-setup-did-signing.md new file mode 100644 index 0000000..ed34cac --- /dev/null +++ b/certs/How-to-setup-did-signing.md @@ -0,0 +1,64 @@ +# How to setup signing material for DID Signing + +KDS is able to provide a DID-Document holding the downloaded keys. The DID-Document will be signed by a private key provided in a KeyStore. + +Generate Private Key (Choose another Curve depending your needs) + +``` +openssl ecparam -name prime256v1 -genkey -noout -out did-signer.pem +``` + +Convert PEM-File to KeyStore + +``` +openssl pkcs12 -export -out did-signer.p12 -inkey did-signer.pem -nocerts -passout pass:secure-password -name did-signer +``` + +This will result in a KeyStore (P12) containing the previously generated private key stored with alias "did-signer" and secured with password "secure-password" + +```yaml +dgc: + did: + didSigningProvider: local-keystore + localKeyStore: + alias: did-signer + password: secure-password + path: ./certs/did-signer.p12 +``` + +## How to publish corresponding public key for verification of DID signature + +Generate the public key of the did singer + +``` +openssl ec -in did-signer.pem -pubout -out did-signer-public-key.pem +``` + +Adapt the following environment variables to your needs and generate a did document for your public key. + +| Environment Variable | Description | +| --- | --- | +| `PUBLIC_KEY_FILE` | Path to the public key file (e.g., "./did-signer-public-key.pem") | +| `DID_ID` | Identifier for the DID (e.g., "did:web:raw.githubusercontent.com:WorldHealthOrganization:tng-participants-dev:main:WHO:signing:DID") | +| `DID_CONTROLLER` | Controller for the DID (e.g., "did:web:raw.githubusercontent.com:WorldHealthOrganization:tng-participants-dev:main:WHO:signing:DID") | + +``` +export PUBLIC_KEY_FILE="./did-signer-public-key.pem" +export DID_ID="did:web:raw.githubusercontent.com:WorldHealthOrganization:tng-participants-dev:main:WHO:signing:DID" +export DID_CONTROLLER="did:web:raw.githubusercontent.com:WorldHealthOrganization:tng-participants-dev:main:WHO:signing:DID" +python generate_did_document.py +``` + +Place the generated DID to it's intended location on a host corresponding to the DID ID as defined by [did:web method specification](https://w3c-ccg.github.io/did-method-web/). + +## How to update the did-signer in the environment + +``` +kubectl create secret generic did-signer-secret --dry-run=client --namespace=kds -o yaml --from-file=did-signer.p12 > did-signer-secret.yaml +``` + +Connected to the correct kubernetes context deploy the generated secret + +```(shell) +kubectl apply -f did-signer-secret.yaml +``` diff --git a/certs/PlaceYourGatewayAccessKeysHere.md b/certs/PlaceYourGatewayAccessKeysHere.md index 649a702..f181094 100644 --- a/certs/PlaceYourGatewayAccessKeysHere.md +++ b/certs/PlaceYourGatewayAccessKeysHere.md @@ -29,31 +29,3 @@ Create a pkcs12 KeyStore from the TLS.pem and TLS.key: ``` openssl pkcs12 -export -out tls_key_store.p12 -inkey TLS.key -in TLS.pem -passout pass:dgcg-p4ssw0rd -name clientcredentials ``` - -# How to setup signing material for DID Signing - -KDS is able to provide a DID-Document holding the downloaded keys. The DID-Document will be signed by a private key provided in a KeyStore. - -Generate Private Key (Choose another Curve depending your needs) - -``` -openssl ecparam -name prime256v1 -genkey -noout -out did-signer.pem -``` - -Convert PEM-File to KeyStore - -``` -openssl pkcs12 -export -out did-signer.p12 -inkey did-signer.pem -nocerts -passout pass:secure-password -name did-signer -``` - -This will result in a KeyStore (P12) containing the previously generated private key stored with alias "did-signer" and secured with password "secure-password" - -```yaml -dgc: - did: - didUploadProvider: local-file - localKeyStore: - alias: did-signer - password: secure-password - path: ./did-signer.p12 -``` diff --git a/certs/generate_did_document.py b/certs/generate_did_document.py new file mode 100644 index 0000000..4215ebe --- /dev/null +++ b/certs/generate_did_document.py @@ -0,0 +1,55 @@ +import json +import base64 +import os +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.backends import default_backend + +# Get the path to the public key file, did-id and did-controller from the environment variables +public_key_file = os.getenv('PUBLIC_KEY_FILE') +did_id = os.getenv('DID_ID') +did_controller = os.getenv('DID_CONTROLLER') + +# Read the public key from the file +with open(public_key_file, 'rb') as f: + public_key_pem = f.read() + +# Load the public key +public_key = serialization.load_pem_public_key(public_key_pem, backend=default_backend()) + +# Check if the public key is an elliptic curve public key +if isinstance(public_key, ec.EllipticCurvePublicKey): + # Get the x and y coordinates of the public key + x = public_key.public_numbers().x + y = public_key.public_numbers().y + +# Convert the x and y coordinates to base64url format +# using base64url without padding as in https://datatracker.ietf.org/doc/html/rfc7515#appendix-C +x = base64.urlsafe_b64encode(x.to_bytes((x.bit_length() + 7) // 8, 'big')).decode().rstrip('=') +y = base64.urlsafe_b64encode(y.to_bytes((y.bit_length() + 7) // 8, 'big')).decode().rstrip('=') + +did_document = { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": did_id, + "controller": did_controller, + "verificationMethod": [ + { + "id": did_id, + "type": "JsonWebKey2020", + "controller": did_controller, + "publicKeyJwk": { + "kty": "EC", + "crv": "P-256", + "x": x, + "y": y + } + } + ] +} + +# Write the DID document to a file +with open('did.json', 'w') as f: + json.dump(did_document, f, indent=4) diff --git a/k8s/helm/tngkds/charts/tngkds-backend/templates/deployment.yaml b/k8s/helm/tngkds/charts/tngkds-backend/templates/deployment.yaml index 828c5e6..65307f0 100644 --- a/k8s/helm/tngkds/charts/tngkds-backend/templates/deployment.yaml +++ b/k8s/helm/tngkds/charts/tngkds-backend/templates/deployment.yaml @@ -103,10 +103,12 @@ spec: value: "{{ index .Values.did "trust-list-ref-path" }}" - name: DGC_DID_DIDCONTROLLER value: "{{ index .Values.did "did-controller" }}" - - name: DGC_DID_TRUSTLISTIDPREFIX - value: "{{ index .Values.did "trust-list-id-prefix" }}" - - name: DGC_DID_TRUSTLISTCONTROLLEPREFIX - value: "{{ index .Values.did "trust-list-controller-prefix" }}" + - name: DGC_DID_LOCALKEYSTORE_ALIAS + value: {{ .Values.did.localKeyStore.alias | quote }} + - name: DGC_DID_LOCALKEYSTORE_PASSWORD + value: {{ .Values.did.localKeyStore.password | quote }} + - name: DGC_DID_LOCALKEYSTORE_PATH + value: {{ .Values.did.localKeyStore.path | quote }} {{- range $key, $value := .Values.did.virtualCountries }} - name: DGC_DID_VIRTUALCOUNTRIES_{{ $key | toString | upper }} value: "{{ $value }}" @@ -122,6 +124,9 @@ spec: - name: secrets-jks mountPath: /certs readOnly: true + - name: did-signing + mountPath: /didcerts + readOnly: true resources: {{- toYaml .Values.resources | nindent 12 }} {{- with .Values.nodeSelector }} @@ -147,3 +152,10 @@ spec: path: trustanchor_store.jks - key: tng_tls_server_truststore.p12 path: tng_tls_server_truststore.p12 + - name: did-signing + secret: + secretName: did-signer-secret + items: + - key: did-signer.p12 + path: did-signer.p12 + diff --git a/k8s/helm/tngkds/charts/tngkds-backend/values.yaml b/k8s/helm/tngkds/charts/tngkds-backend/values.yaml index c26858c..84da4a4 100644 --- a/k8s/helm/tngkds/charts/tngkds-backend/values.yaml +++ b/k8s/helm/tngkds/charts/tngkds-backend/values.yaml @@ -152,15 +152,17 @@ did: workdir: /tmp/kdsgituploader # oon clonind will checkout e.g. tng-cdn-dev prefix: v2.0.0 #for copy action into git workdir from local file exporter path url: https://github.com/WorldHealthOrganization/tng-cdn-dev - pat: #TODO: set by secret - didSigningProvider: dummy + pat: + didSigningProvider: local-keystore + localKeyStore: + alias: did-signer + password: secure-password + path: ld-proof-verification-method: did:web:dummy.net did-id: did:web:worldhealthorganization.github.io:tng-cdn-dev:v2.0.0 trust-list-path: trustlist trust-list-ref-path: trustlist-ref - did-controller: did:web:def - trust-list-id-prefix: did:web:abc - trust-list-controller-prefix: did:web:abc + did-controller: did:web:worldhealthorganization.github.io:tng-cdn-dev:v2.0.0 contextMapping: "[https://www.w3.org/ns/did/v1]": did_v1.json "[https://w3id.org/security/suites/jws-2020/v1]": jws-2020_v1.json diff --git a/src/main/java/tng/trustnetwork/keydistribution/config/KdsConfigProperties.java b/src/main/java/tng/trustnetwork/keydistribution/config/KdsConfigProperties.java index f4c3e11..1e7b98a 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/config/KdsConfigProperties.java +++ b/src/main/java/tng/trustnetwork/keydistribution/config/KdsConfigProperties.java @@ -101,9 +101,6 @@ public static class DidConfig { private String trustListPath; private String trustListRefPath; - private String trustListIdPrefix; - private String trustListControllerPrefix; - private String ldProofVerificationMethod; private String ldProofDomain; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 24ae187..9d6e802 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -102,8 +102,6 @@ dgc: trust-list-path: trustlist trust-list-ref-path: trustlist-ref did-controller: did:web:def - trust-list-id-prefix: did:web:abc - trust-list-controller-prefix: did:web:abc contextMapping: "[https://www.w3.org/ns/did/v1]": did_v1.json "[https://w3id.org/security/suites/jws-2020/v1]": jws-2020_v1.json