Repository: Digitaler-Impfnachweis/certification-apis Branch: master Commit: 7e0a01d0a09c Files: 17 Total size: 2.4 MB Directory structure: gitextract_fzod8ytb/ ├── .gitignore ├── .gitmodules ├── DCC.combined-schema.json ├── Implementation.md ├── LICENSE ├── README.md ├── SMCB-Authentication.md ├── dcc-certify-api.html ├── dcc-certify-api.yaml ├── dcc-reissue-api.html ├── dcc-reissue-api.yaml ├── dsc-update/ │ ├── README.md │ └── dsc-update-api.yaml ├── examples/ │ ├── 01_example.txt │ ├── README.md │ └── demo-dsc.crt └── templates/ └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .idea ================================================ FILE: .gitmodules ================================================ [submodule "valuesets"] path = valuesets url = https://github.com/ehn-dcc-development/ehn-dcc-valuesets ================================================ FILE: DCC.combined-schema.json ================================================ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://id.uvci.eu/DCC.combined-schema.json", "title": "EU DCC", "description": "EU Digital Covid Certificate", "$comment": "Schema version 1.3.2", "type": "object", "oneOf": [ { "required": [ "ver", "nam", "dob", "v" ] }, { "required": [ "ver", "nam", "dob", "t" ] }, { "required": [ "ver", "nam", "dob", "r" ] } ], "properties": { "ver": { "title": "Schema version", "description": "Version of the schema, according to Semantic versioning (ISO, https://semver.org/ version 2.0.0 or newer)", "type": "string", "pattern": "^\\d+.\\d+.\\d+$", "examples": [ "1.0.0", "1.3.0", "1.3.1", "1.3.2" ] }, "nam": { "description": "Surname(s), forename(s) - in that order", "$ref": "#/$defs/person_name" }, "dob": { "title": "Date of birth", "description": "Date of Birth of the person addressed in the DCC. ISO 8601 date format restricted to range 1900-2099 or empty", "type": "string", "pattern": "^((19|20)\\d\\d(-\\d\\d){0,2}){0,1}$", "examples": [ "1979-04-14", "1950", "1901-08", "" ] }, "v": { "description": "Vaccination Group", "type": "array", "items": { "$ref": "#/$defs/vaccination_entry" }, "minItems": 1, "maxItems": 1 }, "t": { "description": "Test Group", "type": "array", "items": { "$ref": "#/$defs/test_entry" }, "minItems": 1, "maxItems": 1 }, "r": { "description": "Recovery Group", "type": "array", "items": { "$ref": "#/$defs/recovery_entry" }, "minItems": 1, "maxItems": 1 } }, "$defs": { "dose_posint": { "description": "Dose Number / Total doses in Series: positive integer", "type": "integer", "minimum": 1 }, "issuer": { "description": "Certificate Issuer", "type": "string", "maxLength": 80 }, "person_name": { "description": "Person name: Surname(s), forename(s) - in that order", "anyOf": [ { "required": [ "fnt" ] }, { "required": [ "gnt" ] } ], "type": "object", "properties": { "fn": { "title": "Surname", "description": "The surname or primary name(s) of the person addressed in the certificate", "type": "string", "maxLength": 80, "examples": [ "d'Červenková Panklová" ] }, "fnt": { "title": "Standardised surname", "description": "The surname(s) of the person, transliterated ICAO 9303", "type": "string", "pattern": "^[A-Z<]*$", "maxLength": 80, "examples": [ "DCERVENKOVA/auth/realms//protocol/openid-connect/auth` | Query-Param | Value | Description | | --- | --- | --- | | client_id | `user-access-ti` or `user-access-ti-simulator` | `user-access-ti` requires a RU SMCB . `user-access-ti-simulator` can be used in conjuction with the gematik KOPS. [Further Details](https://github.com/Digitaler-Impfnachweis/certification-apis/discussions/14) | | redirect_uri | connector://authenticated | custom-uri scheme | | response_type | code | | | scope | openid | | | nonce | | | Triggering of this call results in redirect which contains details for the next step. Example Request ``` curl --request GET 'https:///auth/realms//protocol/openid-connect/auth?redirect_uri=connector://authenticated&response_type=code&scope=openid&client_id=user-access-ti&nonce=' -v ``` Example Response ``` < HTTP/2 200 < content-length: 0 < location: https:///auth/realms//login-actions/authenticate?session_code=kNJIzxgdw6GWYHdNIeI5aEA7x91b8-tuw0zdVHGMabE&execution=ab86f06d-69b0-44d3-8c7b-a980ed1dc3a7&client_id=user-access-ti&tab_id=WGEj4oBWvh4&auth_session_id=ce6ed41d-b46d-4a69-9ef7-ef5ab7ad63c0&tab_id=FBGZX-SyeqI < x-auth-challenge: 171c09de-2f1a-493a-bad7-ee4761a2bec3 < set-cookie: AUTH_SESSION_ID=916a0ffc-ebca-408b-973c-c470ed000d62.keycloak-certificato-keycloakx-0-33399; Version=1; Path=/auth/realms/bmg-ti-certify/; SameSite=None; Secure; HttpOnly < set-cookie: KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNjlhM2ViOS1iNDgyLTRiNTctYjIwNC01M2E3NTg5ZTE1NWUifQ.eyJjaWQiOiJ1c2VyLWFjY2Vzcy10aSIsInB0eSI6Im9wZW5pZC1jb25uZWN0IiwicnVyaSI6ImNvbm5lY3RvcjovL2F1dGhlbnRpY2F0ZWQiLCJhY3QiOiJBVVRIRU5USUNBVEUiLCJub3RlcyI6eyJzY29wZSI6Im9wZW5pZCIsImlzcyI6Imh0dHBzOi8vaWQuY2VydGlmeS5kZW1vLnViaXJjaC5jb20vYXV0aC9yZWFsbXMvYm1nLXRpLWNlcnRpZnkiLCJyZXNwb25zZV90eXBlIjoiY29kZSIsInJlZGlyZWN0X3VyaSI6ImNvbm5lY3RvcjovL2F1dGhlbnRpY2F0ZWQiLCJub25jZSI6ImYyM2c0ZjRmNWczIn19.27XzBiLoMnSakd_e-OpCYCRkX449JK8WeVw-hSYchz0; Version=1; Path=/auth/realms/bmg-ti-certify/; HttpOnly ``` > **Important**: with the update to a new keycloak version, the previous cookie-less session handling is no longer available. To ensure the authentication flow works, please send the `AUTH_SESSION_ID` for subsequent requests. > The reason is that Keycloak deprecates and will remove cookie-less authentication flows. ## 2. Receive Challenge Response of step 1 contains the following header parameters: | Header | Value | Description | | --- | --- | --- | | x-auth-challenge | ... | Challenge in form of a UUID | | Location | | URI | Both parameters are important and need to be saved temporary since they're relevant for step 4. ## 3. Perform Signature operation with SMCB This step takes care of signing the provided challenge with the SMCB. The steps are not illustrated here because there are dependent on the framework of the integrating system. Details about the interaction with the SMCB can be seen in the [sequence diagram](authentication/seq_diagram_smcb_iam.png). The signature is created based on the provided challenge and must be hashed with `SHA-256`. **Supported Ciphers:** RSA and ECC **Signature Scheme:** RSASSA-PSS **SMC-B Certificate Requirements** | OID | Value | Description | | --- | --- | --- | | Policy | 1.2.276.0.76.4.77 | "OID-Festlegung Zertifikatstyp" | | ProfessionOID | 1.2.276.0.76.4.50 | "Betriebsstätte Arzt" | Test environments are not limited in respect to the `ProfessionOID`. ## 4. Submit Signed challenge and SMCB public certificate Call action-uri from step 2 and add the following request headers | Header | Value | Description | | --- | --- | --- | | x-auth-signed-challenge | ... | the signed challenge as base64 encoded string | | x-auth-certificate | ... | the public certificate of the smcb as base64 encoded string | ``` curl --location -viks --request GET 'https:///auth/realms//login-actions/authenticate?client_id=user-access-ti&execution=ab86f06d-69b0-44d3-8c7b-a980ed1dc3a7&session_code=xidVii9ba-WI2pLuVGA6VxKZRhCs6NmtbrwYFFaeh2k&tab_id=BpjQ0_H_Mvk&auth_session_id=0a4d8e20-3ed5-4af2-97bb-c7d16b7c7e00' \ --header 'x-auth-signed-challenge: WX/kLxPnAlhBOyvXAiCCgul2U07xJ+kiFCz9CHp3/gLGpOA7sSWgJVB/rY6MHve4mtqBhlvgwPfdfTc3ubPLK8I0GLCGTbsbwCBvm+FkC+OxN+5VkNp7Azwxhol7hWjEeTFj1C3raA5p6jBZ3FZMugySPXcKkSzpew8JzeVElDBdfl7z0drmBsVyDF2Cu9HOt1TU0qAqXgdf2Yhs+hvAme9J9iurfjOziUoGBNDR5FX2MQfAPToWVXuImrdmNqOJMHnT6eDk9hHQJeikVNwimMk2aB0FAz/U7B79XVnkAluWeRQ2F6R135gF4M2MXZy/floCljYisuzkrfU3uLB2wA==' \ --header 'x-auth-certificate: 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' \ ``` This will result in an auth code that can be used to obtain an access token in the next step. The response contains 2 query parameters attached to the redirect uri (see below): session_state and code. These need to be extracted. ``` HTTP/2 302 location: connector://authenticated?session_state=9d56c0f8-295a-4db2-acbe-eaee7ace5238&code=0849d5f4-30fc-4c58-ae70-40b64e8bad3c.9d56c0f8-295a-4db2-acbe-eaee7ace5238.446dd6a3-54b2-4b6a-a385-d2a471dbb6af ``` ## 5. Exchange code against token Use the token endpoint to obtain an access token. OIDC Token endpoint: `https:///auth/realms//protocol/openid-connect/token` | Header | Value | Description | | --- | --- | --- | | Content-Type | application/x-www-form-urlencoded | information will be send as url encoded data in the request body | | data | Value | Description | | --- | --- | --- | | grant_type | authorization_code | - | | redirect_uri | connector://authenticated | custom-uri scheme | | client_id | user-access-ti | | | session_state | ... | session state retrieved in previous request | | code | ... | the auth code retrieved in previous request | Sample response: ``` { "access_token": "eyJz93a...k4laUWw", "refresh_token": "GEbRxBN...edjnXbL", "id_token": "eyJ0XAi...4faeEoQ", "token_type": "Bearer", "expires_in": 60, "refresh_expires_in": 1800, "not-before-policy": 1620218638, "session_state": "9d56c0f8-295a-4db2-acbe-eaee7ace5238", "scope": "openid email profile" } ``` Please note that a system is meant to reuse the token until it expires. A standard OIDC [refresh_token flow](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens) should be imlemented. ================================================ FILE: dcc-certify-api.html ================================================ Issuer Service API

Issuer Service API (2.2.0)

Download OpenAPI specification:Download

The issuer service API generates signed Digital Green Certificate (DGC) conforming certificates.

Copyright (C) 2021 IBM Deutschland GmbH
Copyright (C) 2021 ubirch GmbH

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Certification

Issue a vaccination certificate.

Description

Issue a health certificate based on the provided input according to spec 1.3.3 of the Digital Green Certificate (DGC).

Authentication: clients connecting via Internet (not SNK/TI) need an X.509 client certificate and must provide a list of authorized vaccination center id's.

Applications: vaccination center software, patient information systems, integrators

Authorizations:
AppBearerToken
header Parameters
X-Transaction-Id
string <hex> ^[A-Za-z0-9]{64}$
Example: 56e9926cd68bf5818e176196b324aeca05a2fe7ea10b486876d194898e9ccc22

The transaction id that identifies this request. Needs to be a SHA256 of the actual transaction id encoded as hex string.

X-UBIRCH-DCCType
required
string^[VTR]$
Examples:
  • V - Request a vaccination certificate signature.
  • T - Request a test certificate signature.
  • R - Request a recovery certificate signature.

The type of signature to be acquired. V - for vaccination certificates, T - for test certificates, and R - for recovery certificates

Request Body schema:

Digital Green Certificate request information. The value-sets are defined in the EU eHealthNetwork: Value Sets for Digital Green Certificates. version 1.0.

required
Person name (object) or Person name (object) (Person name)

Name of the person which receives the certificate.

dob
required
string <date> (Date of birth) (19|20)\d{2}-\d{2}-\d{2}

Date of Birth of the person addressed in the DGC. ISO 8601 date format restricted to range 1900-2099

required
Array of objects (VaccinationEntry) = 1 items

Vaccination Certificate Entry

Responses

Request samples

Content type
{
  • "nam": {
    },
  • "dob": "1979-04-14",
  • "v": [
    ]
}

Sign a CBOR Web Token hash.

Description

Verifies and signs the hash of a CBOR Web Token (CWT). This is the actual signature operation of the ECDSA algorithm applied to the pre-hashed data of the CWT. It returns the skeleton of the signed CWT which needs to be filled with the actual payload that was used in the process of creating the signature hash. This endpoint is used for a privacy friendly way to remotely sign certificates.

Applications: secure backend integrators, vaccination web frontend

Authorizations:
AppBearerToken
header Parameters
X-Location-Id
required
string <hex> ^[A-Za-z0-9]{64}$
Example: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

The location id for which this certificate signature is acquired. Needs to be a SHA256 of the actual location id encoded as hex string.

X-Transaction-Id
required
string <hex> ^[A-Za-z0-9]{64}$
Example: 56e9926cd68bf5818e176196b324aeca05a2fe7ea10b486876d194898e9ccc22

The transaction id that identifies this request. Needs to be a SHA256 of the actual transaction id encoded as hex string.

X-UBIRCH-DCCType
required
string^[VTR]$
Examples:
  • V - Request a vaccination certificate signature.
  • T - Request a test certificate signature.
  • R - Request a recovery certificate signature.

The type of signature to be acquired. V - for vaccination certificates, T - for test certificates, and R - for recovery certificates

Request Body schema: text/plain

Base64 encoded SHA256 message digest of the CBOR Web Token prior to the application of the signature algorithm.

string <base64>

Responses

Request samples

Content type
text/plain
TvQb78AX/5r+5ZkVYYeUW0Rn/4FB8ICt6sSdrwOq0EI=

Response samples

Content type
application/cbor
<Signed Incomplete CBOR Web Token>
================================================ FILE: dcc-certify-api.yaml ================================================ openapi: 3.0.1 servers: - url: https://api.certify.demo.ubirch.com/ description: Endpoint for vaccination centers only - STAGING api server - url: https://api.certify.ubirch.com/ description: Endpoint for vaccination centers only - PRODUCTION api server - url: https://api.ru.impfnachweis.info description: Endpoint for medical practitioners with TI access only - STAGING api server - url: https://api-pvs.certify.demo.ubirch.com description: Endpoint for medical practitioners with Gematik Kops simulator access only - requires no client-cert required - STAGING api server - url: https://api.impfnachweis.info description: Endpoint for medical practitioners with TI access only - PRODUCTION api server info: title: Issuer Service API description: | The issuer service API generates signed [Digital Green Certificate (DGC)](https://github.com/ehn-digital-green-development/ehn-dgc-schema/releases/tag/1.0.0) conforming certificates. ``` Copyright (C) 2021 IBM Deutschland GmbH Copyright (C) 2021 ubirch GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` version: 2.2.0 license: name: 'Apache License, Version 2.0' url: 'https://www.apache.org/licenses/LICENSE-2.0' contact: name: UBIRCH GmbH url: https://ubirch.com email: support@ubirch.com paths: # =========================================================== # Available API endpoints # =========================================================== /api/certify/v2/issue: post: tags: - Certification summary: Issue a vaccination certificate. description: | # Description Issue a health certificate based on the provided input according to spec 1.3.3 of the [Digital Green Certificate (DGC)](https://github.com/ehn-digital-green-development/ehn-dgc-schema/releases/tag/1.3.2). **Authentication:** clients connecting via Internet (not [SNK](https://www.kbv.de/html/sicheres_netz.php)/[TI](https://www.gematik.de/telematikinfrastruktur/)) need an X.509 client certificate and must provide a list of authorized vaccination center `id`'s. **Applications:** vaccination center software, patient information systems, integrators parameters: - in: header name: X-Transaction-Id description: | The transaction id that identifies this request. Needs to be a SHA256 of the actual transaction id encoded as hex string. schema: type: string format: hex pattern: "^[A-Za-z0-9]{64}$" example: 56e9926cd68bf5818e176196b324aeca05a2fe7ea10b486876d194898e9ccc22 # required: true - in: header name: X-UBIRCH-DCCType description: | The type of signature to be acquired. V - for vaccination certificates, T - for test certificates, and R - for recovery certificates schema: type: string pattern: "^[VTR]$" examples: vaccination: value: V summary: Request a vaccination certificate signature. test: value: T summary: Request a test certificate signature. recovery: value: R summary: Request a recovery certificate signature. required: true requestBody: description: >- Digital Green Certificate request information. The value-sets are defined in the [EU eHealthNetwork: Value Sets for Digital Green Certificates. version 1.0](https://ec.europa.eu/health/sites/default/files/ehealth/docs/digital-green-certificates_dt-specifications_en.pdf). content: application/json: #deprecated and required for backwards compatability schema: '$ref': '#/components/schemas/VaccinationCertificateRequest' application/vnd.dgc.v1+json: schema: oneOf: - '$ref': '#/components/schemas/VaccinationCertificateRequest' - '$ref': '#/components/schemas/RecoveryCertificateRequest' - '$ref': '#/components/schemas/TestCertificateRequest' application/vnd.dgc.v1.3+json: schema: oneOf: - '$ref': '#/components/schemas/VaccinationCertificateRequest' - '$ref': '#/components/schemas/RecoveryCertificateRequest' - '$ref': '#/components/schemas/TestCertificateRequest' examples: Vaccination Certification Request: description: | This is an example for a vaccination certification request. value: nam: fn: "Musterfrau-Dießner" gn: "Erika Dörte" dob: "1979-04-14" v: - id: "IZ28215B" tg: "840539006" vp: "1119305005" mp: "EU/1/20/1528" ma: "ORG-100001699" dn: 1 sd: 2 dt: "2021-04-14" Recovery Certification Request: description: | This is an example for a vaccination certification request. value: nam: fn: "Musterfrau-Dießner" gn: "Erika Dörte" dob: "1979-04-14" r: - id: "BSNR12345" tg: "840539006" fr: "2021-04-21" df: "2021-05-01" du: "2021-10-21" Test Certification Request: description: | This is an example for a test certification request. value: nam: fn: "Musterfrau-Dießner" gn: "Erika Dörte" dob: "1979-04-14" t: - id: "TC12345" tg: "840539006" tt: "LP6464-4" nm: "Roche LightCycler qPCR" tr: "260415000" sc: "2021-04-13T14:20:00+00:00" tc: "Hauptbahnhof Köln" responses: '200': description: Certificate response as PDF, encoded or binary token. headers: X-DGC-Id: schema: '$ref': 'DCC.combined-schema.json#/$defs/certificate_id' description: The generated certificate identifier contained in the certificate. example: "01DE/IZ999999X/3B05FC5T96C6HY3YS4FS6H8DD#Z" content: application/cbor+base45: schema: '$ref': '#/components/schemas/CertificateEncoded' application/cbor: schema: '$ref': '#/components/schemas/CertificateBinary' application/pdf: schema: '$ref': '#/components/schemas/CertificationPDF' '400': description: Invalid Request # WIP: define extended error messages if input is wrong '401': description: Authentication Failure (Credential missing) '403': description: Forbidden (Invalid Credentials) '406': description: Incorrect data model '500': description: Internal Server Error security: - AppBearerToken: [ ] /api/certify/v2/issue/hash: post: tags: - Certification summary: Sign a CBOR Web Token hash. description: | # Description Verifies and signs the hash of a [CBOR Web Token](https://tools.ietf.org/html/rfc8392) (CWT). This is the actual signature operation of the [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) algorithm applied to the pre-hashed data of the CWT. It returns the skeleton of the signed CWT which needs to be filled with the actual payload that was used in the process of creating the signature hash. This endpoint is used for a privacy friendly way to remotely sign certificates. **Applications:** secure backend integrators, vaccination web frontend parameters: - in: header name: X-Location-Id description: | The location id for which this certificate signature is acquired. Needs to be a SHA256 of the actual location id encoded as hex string. schema: type: string format: hex pattern: "^[A-Za-z0-9]{64}$" example: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 required: true - in: header name: X-Transaction-Id description: | The transaction id that identifies this request. Needs to be a SHA256 of the actual transaction id encoded as hex string. schema: type: string format: hex pattern: "^[A-Za-z0-9]{64}$" example: 56e9926cd68bf5818e176196b324aeca05a2fe7ea10b486876d194898e9ccc22 required: true - in: header name: X-UBIRCH-DCCType description: | The type of signature to be acquired. V - for vaccination certificates, T - for test certificates, and R - for recovery certificates schema: type: string pattern: "^[VTR]$" examples: vaccination: value: V summary: Request a vaccination certificate signature. test: value: T summary: Request a test certificate signature. recovery: value: R summary: Request a recovery certificate signature. required: true requestBody: description: | Base64 encoded SHA256 message digest of the CBOR Web Token prior to the application of the signature algorithm. content: text/plain: schema: type: string format: base64 example: "TvQb78AX/5r+5ZkVYYeUW0Rn/4FB8ICt6sSdrwOq0EI=" responses: '200': description: A signed incomplete CBOR Web Token. content: application/cbor: schema: type: string format: binary example: "" '400': description: Invalid Request '401': description: Authentication Failure (Credential missing) '403': description: Forbidden (Invalid Credentials) '406': description: Incorrect CBOR Data '500': description: Internal Server Error security: - AppBearerToken: [ ] components: # =========================================================== # Request and response schema definitions # =========================================================== schemas: CertificateRequestBase: description: >- Common Digital Green Certificate (DGC) request data containing the name and date of birth of the person receiving the certificate. type: object required: - nam - dob properties: nam: title: Person name description: Name of the person which receives the certificate. type: object anyOf: - properties: fn: title: Family name description: The family or primary name(s) of the person addressed in the certificate type: string maxLength: 80 example: "Musterfrau-Dießner" required: [ fn ] - properties: gn: title: Given name description: The given name(s) of the person addressed in the certificate type: string maxLength: 80 example: "Erika Dörte" required: [ gn ] dob: title: Date of birth description: Date of Birth of the person addressed in the DGC. ISO 8601 date format restricted to range 1900-2099 type: string format: date pattern: '(19|20)\d{2}-\d{2}-\d{2}' example: '1979-04-14' VaccinationCertificateRequest: allOf: - '$ref': '#/components/schemas/CertificateRequestBase' - type: object description: >- Vaccination certificate request object. The value-sets are defined in the [EU eHealthNetwork: Value Sets for Digital Green Certificates. version 1.0](https://ec.europa.eu/health/sites/default/files/ehealth/docs/digital-green-certificates_dt-specifications_en.pdf). required: - v properties: v: description: Vaccination Certificate Entry type: array items: '$ref': '#/components/schemas/VaccinationEntry' minItems: 1 maxItems: 1 RecoveryCertificateRequest: allOf: - '$ref': '#/components/schemas/CertificateRequestBase' - type: object description: >- Recovery certificate request object. The value-sets are defined in the [EU eHealthNetwork: Value Sets for Digital Green Certificates. version 1.0](https://ec.europa.eu/health/sites/default/files/ehealth/docs/digital-green-certificates_dt-specifications_en.pdf). required: - r properties: r: description: Recovery Certificate Entry type: array items: '$ref': '#/components/schemas/RecoveryEntry' minItems: 1 maxItems: 1 TestCertificateRequest: allOf: - '$ref': '#/components/schemas/CertificateRequestBase' - type: object description: >- Test certificate request object. The value-sets are defined in the [EU eHealthNetwork: Value Sets for Digital Green Certificates. version 1.0](https://ec.europa.eu/health/sites/default/files/ehealth/docs/digital-green-certificates_dt-specifications_en.pdf). required: - t properties: t: description: Test Group type: array items: '$ref': '#/components/schemas/TestEntry' minItems: 1 maxItems: 1 VaccinationEntry: description: Single vaccination data entry. type: object required: - id - tg - vp - mp - ma - dn - sd - dt properties: id: description: >- Identifier of the administering location (i.e. vaccination center ID, BSNR or similar identifer). It will be used in the construction of the DGCI (digitial green certificate identifier). Due to the specification of the DGCI only the use of uppercase letters and numbers 0-9 are allowed. type: string pattern: "^[0-9A-Z]+$" tg: '$ref': 'DCC.combined-schema.json#/$defs/disease-agent-targeted' vp: '$ref': 'DCC.combined-schema.json#/$defs/vaccine-prophylaxis' mp: '$ref': 'DCC.combined-schema.json#/$defs/vaccine-medicinal-product' ma: '$ref': 'DCC.combined-schema.json#/$defs/vaccine-mah-manf' dn: '$ref': 'DCC.combined-schema.json#/$defs/dose_posint' sd: '$ref': 'DCC.combined-schema.json#/$defs/dose_posint' dt: description: ISO 8601 date of the vaccination type: string format: date RecoveryEntry: description: Single recovery data entry. type: object required: - id - tg - fr - df - du properties: id: description: >- Identifier of the health professional location (i.e. BSNR or similar identifer). It will be used in the construction of the DGCI (digitial green certificate identifier). Due to the specification of the DGCI only the use of uppercase letters and numbers 0-9 are allowed. type: string pattern: "^[0-9A-Z]+$" tg: '$ref': 'DCC.combined-schema.json#/$defs/disease-agent-targeted' fr: description: First positive test result date as ISO 8601. type: string format: date df: description: Certificate valid from date as ISO 8601. type: string format: date du: description: Certificate valid until date as ISO 8601. type: string format: date TestEntry: description: Test Entry required: - id - tg - tt - sc - tr - tc type: object properties: id: description: >- Identifier of the test center location (i.e. postal code or similar identifer). It will be used in the construction of the DGCI (digitial green certificate identifier). Due to the specification of the DGCI only the use of uppercase letters and numbers 0-9 are allowed. type: string pattern: "^[0-9A-Z]+$" tg: '$ref': 'DCC.combined-schema.json#/$defs/disease-agent-targeted' tt: '$ref': 'DCC.combined-schema.json#/$defs/test-type' nm: description: NAA Test Name type: string ma: '$ref': 'DCC.combined-schema.json#/$defs/test-manf' sc: description: Date/Time of Sample Collection type: string format: date-time tr: '$ref': 'DCC.combined-schema.json#/$defs/test-result' tc: description: Test center or laboratory type: string maxLength: 50 CertificateEncoded: description: >- Base45 encoded and compressed Digital Green Certificate (DGC) according to EU specification. An encoded certificate can be directly rendered as a QR code according to the EU specification. type: string format: base45 example: "HC1:6BFOXN*TS0BI$ZD4N9:9S6RCVN5+O30K3/XIV0W23NTDEMWK4MI6UOS03CR83KLBKAVN74.CL91/8K6%KEG3983NS9SVBHABVCNN95SWMPHQUHQN%A400H%UBT16Y51Y9AT1:+P6YBKD0:XB7NGJQOIS7I$H%T5+XO8YJMVHBZJF 9NSG:PICIG%*47%S%*48YIZ73423ZQT-EJDG3XW44$22CLY.IE.KD+2H0D3ZCU7JI$2K3JQH5-Y3$PA$HSCHBI I7995R5ZFQETU 9R*PP:+P*.1D9RYO05QD/8D3FC:XIBEIVG395EP1E+WEDJL8FF3DE0OA0D9E2LBHHNHL$EQ+-CVYCMBB:AV5AL5:4A93MOJLWT.C3FDA.-B97U: KMZNKASADIMKN2GFLF9$HF.3O.X21FDLW4L4OVIOE1M24OR:FTNP8EFVMP9/HWKP/HLIJL8JF8JF172OTTHO9YW2E6LS7WGYNDDSHRSFXT*LMK8P*G8QWD8%P%5GPPMEVMTHDBESW2L.TN8BBBDR9+JLDR/1JGIF8BS0IKT8LB1T7WLA:FI%JI50H:EK1" CertificateBinary: description: >- Binary representation of the Digital Green Certificate (DGC) according to EU specification. This is a pure CBOR Web Token (CWT) without compression and encoding and HC1: prefix. type: string format: binary example: "" CertificationPDF: description: >- A rendered PDF document containing the certificate information including a Digital Green Certificate (DGC) QR Code according to EU specification. type: string format: binary example: "" securitySchemes: AppBearerToken: type: http description: >- Authentication is based on a bearer token scheme: bearer bearerFormat: JWT ================================================ FILE: dcc-reissue-api.html ================================================ Re-issue Service API

Re-issue Service API (2.0.0)

Download OpenAPI specification:Download

The re-issue service API generates signed Digital Green Certificate (DGC) conforming certificates with the short validity and based on current regulations. It is mainly used by Apps to re-issue validation certificates.

Copyright (C) 2021 IBM Deutschland GmbH
Copyright (C) 2021 ubirch GmbH

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Re-issuing

Re-issue a new certificate based on an existing valid certificate.

Description

Re-issue a new certificate based on an existing valid certificate. This operation verifies the authenticity and the integrity of the certificate, checks some formal rules of the content of the certificate and re-issues a new certificate with a different validity and/or re-encoded specifics (i.e. series encoding) than the original certificate.

All certificates in a single request must adhere to same-person rule. Each request operates on certificates of one person.

Applications: mobile applications, wallet apps

Request Body schema: application/json

A list of valid Digital Green Certificate(s) (DGC) signed in Germany (DE) that are needed for re-issue.

action
string
Enum: "renew" "extend" "combine"

The operation to execute on the input certificate(s). All certificates in a single request must adhere to same-person rule. Each request operates on certificates of one person.

  • renew - replace a certificate with a new version, i.e. booster recoding 2/2 -> 2/1
  • extend - extend the technical validity of a certificate
  • combine - combine multiple certificates (not used yet)
certificates
Array of strings <base45> (CertificateEncoded) non-empty

One or more certificates required for the operation.

Responses

Request samples

Content type
application/json
{
  • "action": "renew",
  • "certificates": [
    ]
}

Response samples

Content type
application/json
[
  • {
    }
]
================================================ FILE: dcc-reissue-api.yaml ================================================ openapi: 3.0.1 servers: - url: https://api.reissue.demo.ubirch.com/ description: STAGING re-issue api server - url: https://api.reissue.ubirch.com/ description: PRODUCTION re-issue api server info: title: Re-issue Service API description: | The re-issue service API generates signed [Digital Green Certificate (DGC)](https://github.com/ehn-digital-green-development/ehn-dgc-schema) conforming certificates with the short validity and based on current regulations. It is mainly used by Apps to re-issue validation certificates. ``` Copyright (C) 2021 IBM Deutschland GmbH Copyright (C) 2021 ubirch GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` version: 2.0.0 license: name: 'Apache License, Version 2.0' url: 'https://www.apache.org/licenses/LICENSE-2.0' contact: name: UBIRCH GmbH url: https://ubirch.com email: mailto:support@ubirch.com paths: # =========================================================== # Available API endpoints # =========================================================== /api/certify/v2/reissue: post: tags: - Re-issuing summary: Re-issue a new certificate based on an existing valid certificate. description: | # Description Re-issue a new certificate based on an existing valid certificate. This operation verifies the authenticity and the integrity of the certificate, checks some formal rules of the content of the certificate and re-issues a new certificate with a different validity and/or re-encoded specifics (i.e. series encoding) than the original certificate. All certificates in a single request must adhere to same-person rule. Each request operates on certificates of one person. *Applications:* mobile applications, wallet apps requestBody: description: | A list of valid Digital Green Certificate(s) (DGC) signed in Germany (DE) that are needed for re-issue. content: application/json: schema: type: object properties: action: description: | The operation to execute on the input certificate(s). All certificates in a single request must adhere to same-person rule. Each request operates on certificates of one person. - `renew` - replace a certificate with a new version, i.e. booster recoding 2/2 -> 2/1 - `extend` - extend the technical validity of a certificate - `combine` - combine multiple certificates (not used yet) type: string required: true enum: - renew - extend - combine certificates: description: One or more certificates required for the operation. type: array required: true minItems: 1 items: '$ref': 'dcc-certify-api.yaml#/components/schemas/CertificateEncoded' responses: '200': description: OK content: application/json: schema: description: | The result of the operation, which may be one or more certificates. For each certificate the executed operation is indicated. type: array items: '$ref': '#/components/schemas/CertificateReissueResponse' '400': description: Invalid Request content: application/json: schema: '$ref': '#/components/schemas/ErrorResponse' examples: BodyTooLarge: description: The request is too large and considered unacceptable. value: error: RI400-0100 message: body too large InvalidRequest: description: The body does not contain parsable json or is missing required fields. value: error: RI400-0200 message: invalid request ActionNotAcceptable: description: The action field contains none of the accepted values. value: error: RI400-0300 message: action not acceptable WrongNumberOfCertificates: description: The number of certificates provided does not match the expected number for the case. value: error: RI400-0400 message: wrong number of certificates InvalidCertificateFormat: description: | One or more certificats does not conform to the DCC serialization format, i.e. missing the 'HC1:' prefix. value: error: RI400-0500 message: invalid certificate format InvalidCertificateEncoding: description: One or more certificates cannot be decoded. value: error: RI400-0600 message: invalid certificate encoding InvalidCertificateCompression: description: One of the certificates cannot be decompressed. value: error: RI400-0700 message: invalid certificate encoding InvalidCOSEEncoding: description: One of the certificates cannot be decoded to COSE/CBOR. value: error: RI400-0800 message: invalid certificate format UnknownSigner: description: One of the certificates has a signature from an unknown signer. value: error: RI400-0900 message: a certificate could not be verified NameMismatch: description: The certificates do not belong together due to a name mismatch. value: error: RI400-1000 message: certificates not acceptable for action BirthDateMismatch: description: The certificates do not belong together due to a birth date mismatch. value: error: RI400-1100 message: certificates not acceptable for action ConditionFailed: description: The certificates fail to meet the condition for reissuing. value: error: RI400-1200 message: certificate not acceptable for action InvalidSignature: description: One of the certificates fails the signature verification. value: error: RI400-1300 message: invalid signature RuleValidationError: description: One or more certificates are not valid. value: error: RI400-1400 message: certificates not acceptable for action InvalidCountry: description: One or more certificates cannot be used for reissuing because of country restrictions. value: error: RI400-1500 message: certificates not acceptable for action TooOldExpirationDate: description: The expiration date of the last issued cert is too old. value: error: RI400-1600 message: expiration date too old to become extended TooEarlyExpirationDate: description: The expiration date of the last issued cert is too early. value: error: RI400-1700 message: expiration date too young to become extended DateConflict: description: Two or more certificates reference the same date. value: error: RI400-1800 message: at least two DCCs have the same date (dt and/or fr) InvalidUVCI: description: The UVCI of the last issued cert is invalid. value: error: RI400-1900 message: invalid unique certificate identifier CertificateRevoked: description: One or more certificates are revoked. value: error: RI400-2000 message: a certificate is revoked WrongIssuerCountry: description: Issuer country does not correlate with signing key country value: error: RI400-2100 message: wrong issuer country '411': description: Length Required content: application/json: schema: '$ref': '#/components/schemas/ErrorResponse' example: LengthRequired: value: error: RI411-0100 message: length required '429': description: Too Many Requests '500': description: Internal Server Error components: schemas: CertificateReissueResponse: type: object properties: certificate: '$ref': 'dcc-certify-api.yaml#/components/schemas/CertificateEncoded' relations: description: Array of certificates related to this new certificate indicating the action. type: array items: '$ref': '#/components/schemas/CertificateReissueRelation' CertificateReissueRelation: type: object properties: index: description: The index of the related certificate from the request. type: number action: description: | The operational relation to the new certificate. (The nop action will be removed on production.) type: string enum: - replace - nop ErrorResponse: type: object properties: error: type: string description: A machine readable error code. message: type: string description: Human readable description of the error. required: - error ================================================ FILE: dsc-update/README.md ================================================ # DSC TrustList Update API To be able to validate [Digital COVID Certificates](https://ec.europa.eu/info/live-work-travel-eu/coronavirus-response/safe-covid-19-vaccines-europeans/eu-digital-covid-certificate_en) (DCCs) from different EU countries, the national verifier apps need to retrieve a list of public keys from all possible issuing authorities. Those are called Document Signing Certificates (DSCs). As more institutions get authorised to issue vaccination certificates, this list has to be maintained and synchronised to the verifier apps. For an EU wide synchronisation of the list of issuing authorities, the EU commission installed a centralised service called the [EU DCC Gateway](https://github.com/eu-digital-green-certificates/dgc-gateway): a collection of REST API endpoints to upload individual DSCs as well as [fetch the latest list of all DSCs](https://eu-digital-green-certificates.github.io/dgc-gateway/#/Trust%20Lists/downloadTrustList). Only EU Member States are allowed to access the EU Gateway (secured via mTLS), so every country must additionally provide the collection of their acknowledged DSCs via a national backend. Bilateral exchanges are not prohibited, and private institutions (airlines, commercial verifying vendors) might request access to the national endpoint. A removal of a DSC from the EU Gateway by a member state will be propagated to all verifier apps and is to be seen as invalidating all DCCs signed by this DSC. This API spec defines the endpoint for the national backend that offers the list of Trusted DSCs to the verifier apps for seal verification. A periodical request to the EU Gateway (~ every 6h) is made to fetch the latest set of all DSCs from all EU member states connected to the EU gateway. As the national backend is public, an additional signature element is added to the overall content provided by the EU Gateway. ## Data Schema The data structure that gets delivered looks as follows (inspired by the [COSE object](https://cose-wg.github.io/cose-spec/#rfc.appendix.C.1)): ```json o3SWKd9PKKaQcLqc+z0F6IJAK6lxaw/B1JCWETB9EZBYgT8F/+R29+vedCO/Wkz0aXgi8SOGkXIr2rW9fEk/Jg== {"certificates" : [ { "certificateType": "DSC", "country": "DE", "kid": "qroU+hDDovs=", "rawData": "MIICyDCCAbCgAwIBAgIGAXR3DZUUMA0GCSqGSIb3DQEBBQUAMBwxCzAJB ... Jpux30QRhsNZwkmEYSbRv+vp5/obgH1mL5ouoV5I=", "signature": "o53CbAa77LyIMFc5Gz+B2Jc275Gdg/SdLayw7gx0GrTcinR95zfTLr8nNHgJMYlX3rD8Y11zB/Osyt0...W+VIrYRGSEmgjGy2EwzvA5nVhsaA+/udnmbyQw9LjAOQ==", "thumbprint": "aaba14fa10c3a2fb441a28af0ec1bb4128153b9ddc796b66bfa04b02ea3e103e", "timestamp": "2021-05-12T21:48:50.583Z", }, ... ]} ``` - On the first line the base64 encoded signature of the contents of from the second line - On the second line a JSON map that looks the following: As such we provide as data structure a list of entries each representing a Document Signing Certificate (DSC - field 'rawData') along with metadata, most notably the [kid](https://github.com/ehn-dcc-development/hcert-spec/blob/main/hcert_spec.md#333-key-identifier). An overall signature on the first line ensures that this list can be guaranteed to be complete as well as integer. The signature over the Trusted List is calculated by building the SHA-256 hash over the JSON content of the second line, then signing it via ECDSA using prime256v1. ## DGC Update / DCC Verification Flow The high level flow for the DSC Update and DCC verification looks as follows: ![](Ablaufdiagramm_validationFlowCertificate.png) As can be seen in the diagram, the request for the latest list of trusted DGCs is decoupled from the actual DCC verification, which can be done offline. When updating the TrustedList of Document Signing Certificates (DSCs) it is important to check the authenticity and integrity of the list via the 'signature' field. ================================================ FILE: dsc-update/dsc-update-api.yaml ================================================ openapi: '3.0.1' servers: - url: https://de.test.dscg.ubirch.com/trustList/DSC/ description: Test / Demo Environment - url: https://de.dscg.ubirch.com/trustList/DSC/ description: Productive Environment info: title: German Trusted List of DSCs description: >- This endpoint provides access to the List of Document Signing Certificates (DSCs) that Germany considers authorized to sign Digital Green Certificates (DGCs). The list gets periodially updated with the latest list from the [EU Gateway](https://eu-digital-green-certificates.github.io/dgc-gateway/). The data structure of the response is similar to the response from the Gateway - however we add an additional signature of the overall list to ensure authenticity and integrity. This is also why this is a plain text response: the first line contains the signature, the second line the actual content, a JSON object of DSC entries. ``` Copyright (C) 2021 IBM Deutschland GmbH Copyright (C) 2021 ubirch GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` version: '0.1.1' license: name: 'Apache License, Version 2.0' url: 'https://www.apache.org/licenses/LICENSE-2.0' contact: name: UBIRCH GmbH url: https://ubirch.com email: support@ubirch.com paths: # =========================================================== # Available API endpoints # =========================================================== /DSC/: get: tags: - Trusted List of DSCs summary: The Trusted List of Document Signing Certificates. responses: '200': description: >- Returns a plain text containing two lines: the signature on the first line and the content on the second line. The content is a JSON map corresponding to the TrustedList datastructure. consists of a JSON array of objects representing the DSCs and additional metadata info. content: text/plain: schema: type: string example: >- yIMFc5Gz0... W+aA+/udQ== {"certificates":[{"certificateType": "DSC", "country": "DE", "kid": "DEsVUSvpFAE=", "rawData": "MIIGwI...If1QHu/nyDtQ=", "signature": "MIAG...0O1AAAAAAAA", "thumbprint": "0c4b1551...2c6a57477", "timestamp": "2021-05-18T10:36:56+02:00"}, ...]} components: # =========================================================== # Request and response schema definitions # =========================================================== schemas: TrustedList: type: object properties: certificates: type: array items: $ref: '#/components/schemas/DSCEntry' DSCEntry: type: object properties: kid: type: string example: qroU+hDDovs= timestamp: type: string format: date-time country: type: string example: SE thumbprint: type: string example: aaba14fa10c3a2fb441a28af0ec1bb4128153b9ddc796b66bfa04b02ea3e103e signature: type: string example: >- o53Ct0... W+VIrYAOQ== rawData: type: string example: >- MIICyDCCAb...Jpux30QRhV5I= ================================================ FILE: examples/01_example.txt ================================================ HC1:6BFOXN*TS0BI$ZD4N9:9S6RCVN5+O30K3/XIV0W23NTDEPWK G2EP4J0B3KLASMUG8GJL8LLG.3SA3/-2E%5VR5VVBJZILDBZ8D%JTQOL2009UVD0HX2JN*4CY009TX/9F/GZ%5U1MC82*%95HC2FCG2K80H-1GW$5IKKQJO0OPN484SI4UUIMI.J9WVHWVH+ZE/T9MX1HRIWQHCR2HL9EIAESHOP6OH6MN9*QHAO96Y2/*13A5-8E6V59I9BZK6:IR/S09T./0LWTHC0/P6HRTO$9KZ56DE/.QC$QUC0:GOODPUHLO$GAHLW 70SO:GOV636*2. KOKGKZGJMI:TU+MMPZ5OV1 V125VE-4RZ4E%5MK9BM57KPGX7K:7D-M1MO0Q2AQE:CA7ED6LF90I3DA+:E3OGJMSGX8+KL1FD*Y49+574MYKOE1MJ-69KKRB4AC8.C8HKK9NTYV4E1MZ3K1:HF.5E1MRB4WKP/HLIJL8JF8JF172M*8OEB2%7OREF:FO:7-WF11SKCU1MH8FWPVH%L635OBXTY*LPM6B9OBYSH:4Q1BQ:A5+I6:DQR9VKR8 BLHCFQMZA5:PHR14%GV4ZOP50$ A 3 ================================================ FILE: examples/README.md ================================================ # Examples This directory contains examples that help understand the structure of the certificates and how to use the API. ## Certificate Example and Structure The following is an example QR code encoded according to the EU specification (created via web frontend): ![Demo QR Code](01_example.png) The [plain text representation](01_example.txt) of the QR code content: ``` HC1:6BFOXN*TS0BI$ZD4N9:9S6RCVN5+O30K3/XIV0W23NTDEPWK G2EP4J0B3KLASMUG8GJL8LLG.3SA3/-2E%5VR5VVBJZILDBZ8D%JTQOL2009UVD0HX2JN*4CY009TX/9F/GZ%5U1MC82*%95HC2FCG2K80H-1GW$5IKKQJO0OPN484SI4UUIMI.J9WVHWVH+ZE/T9MX1HRIWQHCR2HL9EIAESHOP6OH6MN9*QHAO96Y2/*13A5-8E6V59I9BZK6:IR/S09T./0LWTHC0/P6HRTO$9KZ56DE/.QC$QUC0:GOODPUHLO$GAHLW 70SO:GOV636*2. KOKGKZGJMI:TU+MMPZ5OV1 V125VE-4RZ4E%5MK9BM57KPGX7K:7D-M1MO0Q2AQE:CA7ED6LF90I3DA+:E3OGJMSGX8+KL1FD*Y49+574MYKOE1MJ-69KKRB4AC8.C8HKK9NTYV4E1MZ3K1:HF.5E1MRB4WKP/HLIJL8JF8JF172M*8OEB2%7OREF:FO:7-WF11SKCU1MH8FWPVH%L635OBXTY*LPM6B9OBYSH:4Q1BQ:A5+I6:DQR9VKR8 BLHCFQMZA5:PHR14%GV4ZOP50$ A 3 ``` Pseudo-code representation of the decoded CBOR Web Token (CWT): - Issuer: `DE` - Valid from: `Friday, May 7, 2021 1:09:05 PM` - Expires: `Saturday, May 7, 2022 1:09:05 PM` *(be aware that the CWT keys `1`, `4`, `6`, `-260` are actual integer keys in the CWT)* ```json { "1": "DE", "4": 1651928945, "6": 1620392945, "-260": { "1": { "v": [ { "ci": "01DE/00000/1119349007/BW1DDJEZX2B0VGVYII1QN7DDU#S", "co": "DE", "dn": 2, "dt": "2021-05-07", "is": "Bundesministerium für Gesundheit", "ma": "ORG-100030215", "mp": "EU/1/20/1528", "sd": 2, "tg": "840539006", "vp": "1119349007" } ], "dob": "1970-01-01", "nam": { "fn": "Dießner Musterfrau", "gn": "Erika Dörte", "fnt": "DIESSNER 🔐 For JVM based systems, a JKS may be relevant: > ```shell > keytool -importkeystore -srckeystore demo.pfx -srcstoretype pkcs12 -destkeystore demo.jks -deststoretype JKS > ``` ## Certificate Issuing For integrators (vaccination centers, patient information systems, etc.) the issuer api provides a way to send certification requests. The following example demonstrators how to authenticate and use the [API](../dcc-certify-api.yaml) to request a certificate for a vaccination data set: ```bash # request a Base45 encoded certificate curl \ --location \ --request POST 'https://api.certify.demo.ubirch.com/api/certify/v2/issue' \ --cert-type p12 \ --cert demo.pfx:$(cat demo.pwd) \ --header 'Accept: application/cbor+base45' \ --header 'Content-Type: application/json' \ --data-raw '{ "nam": { "fn": "Musterfrau", "gn": "Erika" }, "dob": "1979-04-14", "v": [{ "id": "IZ12345A", "tg": "840539006", "vp": "1119305005", "mp": "EU/1/20/1528", "ma": "ORG-100001699", "dn": 1, "sd": 2, "dt": "2021-04-14" }] }' ``` The result is: ``` HC1:6BFOXN*TS0BI$ZD.P9O6RZ.1LKLX97/3AOW2TCVM6K6+3R651WG%MP8*IVH53VDR%28WA1*QC3B:ZH6I1$4JN:IN1MPK95%LNF6JWEA2RIZHUP0D310TE.IS599WCK-/3O3GQH0W-2C-23/5Z17U45LQE1ZS$*S1CK9B9LGF9B9LW4G%89-8CNNE+47/GVD98-O LHG-K0C5$:O4IJZJJBY4.Z8Z.KAE1M8HVO2LFNAZ2RV4SHA-O9/IE%TE6UG+ZE V1+GO9+PGF6Z6NC8P$WA3AA9EPBDSM+Q8H4O670C57Q4UYQD*O%+Q.SQBDOBKLP64-HQ/HQ3IRE+QJDO4A7E:7LYPPTQQE2*ED.-B97U: KMZNKAS7CI*DD2IHLF95HFI1MAKJ%IH1FDLW4L4OVIOE1MA.DI1ITNP8EFDKLDD846SWKP/HLIJL8JF8JF172-KQ-K1O8N: V9NVF7HO-OH6J4SSZK2K:T14FNDMA$RN$F/W74YH DT3ZLA/DMMFI4FKPPT$M %SPPS3QQZ.142DAP3P.5FJDNBWQF7L10J5R11 ``` To test this certificate, you can use [this page](https://github.pathcheck.org/debug.html) and paste the Base45 text and use the [demo signing certificate](demo-dsc.crt) certificate to verify. ## Possible Issues - X.509 client certificate is missing or invalid ``` 400 Sorry, there is something invalid in your request. header is missing. X-Forwarded-Tls-Client-Cert ``` - X.509 client certificate is not authorized for this endpoint ``` 403 Sorry, the credential is invalid. ``` ================================================ FILE: examples/demo-dsc.crt ================================================ -----BEGIN CERTIFICATE----- MIIGljCCBE6gAwIBAgIQYCT++pDPSoNLST5Q8HGIbzA9BgkqhkiG9w0BAQowMKAN MAsGCWCGSAFlAwQCA6EaMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgOiAwIBQDBg MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSEwHwYDVQQDExhE LVRSVVNUIFRlc3QgQ0EgMi0yIDIwMTkxFzAVBgNVBGETDk5UUkRFLUhSQjc0MzQ2 MB4XDTIxMDUwNzE3MDEzNVoXDTIyMDUxMDE3MDEzNVowgbUxCzAJBgNVBAYTAkRF MRQwEgYDVQQKEwtVYmlyY2ggR21iSDEUMBIGA1UEAxMLVWJpcmNoIEdtYkgxDjAM BgNVBAcMBUvDtmxuMQ4wDAYDVQQRDAU1MDY3MDEXMBUGA1UECRMOSW0gTWVkaWFw YXJrIDUxHDAaBgNVBGETE0RUOkRFLVVHTk9UUFJPVklERUQxFTATBgNVBAUTDENT TTAxNzI1NDM3MTEMMAoGA1UECBMDTlJXMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD QgAEQsykqO9mX0NkZ1D+/coSrySp8QmeQ/oR/EzwAz4AQbiert8MVTRmI7zmIFRZ dvUrnlj8G6l8dL2/cEfv7fmcYaOCAl8wggJbMB8GA1UdIwQYMBaAFFB2kqAa7IGu kcLdqAlSaDfeUYRPMC0GCCsGAQUFBwEDBCEwHzAIBgYEAI5GAQEwEwYGBACORgEG MAkGBwQAjkYBBgIwgf4GCCsGAQUFBwEBBIHxMIHuMCsGCCsGAQUFBzABhh9odHRw Oi8vc3RhZ2luZy5vY3NwLmQtdHJ1c3QubmV0MEcGCCsGAQUFBzAChjtodHRwOi8v d3d3LmQtdHJ1c3QubmV0L2NnaS1iaW4vRC1UUlVTVF9UZXN0X0NBXzItMl8yMDE5 LmNydDB2BggrBgEFBQcwAoZqbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5ldC9D Tj1ELVRSVVNUJTIwVGVzdCUyMENBJTIwMi0yJTIwMjAxOSxPPUQtVHJ1c3QlMjBH bWJILEM9REU/Y0FDZXJ0aWZpY2F0ZT9iYXNlPzAXBgNVHSAEEDAOMAwGCisGAQQB pTQCAgIwgb8GA1UdHwSBtzCBtDCBsaCBrqCBq4ZwbGRhcDovL2RpcmVjdG9yeS5k LXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwVGVzdCUyMENBJTIwMi0yJTIwMjAxOSxP PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdIY3 aHR0cDovL2NybC5kLXRydXN0Lm5ldC9jcmwvZC10cnVzdF90ZXN0X2NhXzItMl8y MDE5LmNybDAdBgNVHQ4EFgQUcM7SUF3sDg0G9c5phK6TB2eVD3AwDgYDVR0PAQH/ BAQDAgbAMD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZIAWUDBAIDoRowGAYJKoZIhvcN AQEIMAsGCWCGSAFlAwQCA6IDAgFAA4ICAQCIhkHCgrk1yfslWjnX0W59QiUBfDZu HnFrww+CACkwjkvQvL8ruVljxQIc+KUqhfZGcwNqYnfckmr+fYoF16tFuLkvodiJ +vYsQEbSfMikW3z7WsE51TKE4Vkp7jP/Mcfz2BN8DxApG7puzBIiNLH5DNbPuE5e hm3jPE9xIJr4HCUAsawNREAI3gTzkWKb40YkU3fq0KVpv0/JE4MPXvtiDrsosVTk jk+nfR3DT0Jj5xuOaZ6xAOvgRWnTOTnW/Khs8p9Y0vQcYDhRFIgl5jTA4VhRuxCt P4fkVxWHAjiYM6Nml9f9BjtMZ4pHrSZB7Vv6JRBTiO727yaU1GNPO0TR6U2VtJme mN9fAnUTQSbcML1osYDRDRsibmkQx44E87gDmjYVYjhC+eVUmmpKD9OKDXR6yj0V ++ne2MSc/OAXZPHbp6lK3lwipj0X2eqvN4E0Z7IyhnbuWiEwZ74eBuZE7bt3EGYg JEiHwCU4VMtGwlxw4B4EVrFSGpC7Dld+e3R0j3xQkzMW5OvpjIG4lyKtsUlMq2j8 u7ofDnwgh0U81ILT7WyMve+gZ7pojy/xICfqDZ0VwF9JLfqrq/tw33C9Hr/i9ipM hee7ihsVhQXvgV45LBHl3Z3ayu6WrvHTB5f+6hRRLxFzZDii+GPoFZ9tTmK2z6Mn 1nAhddpGFS0o0Q== -----END CERTIFICATE----- ================================================ FILE: templates/README.md ================================================ # DCC Print Templates (Germany) This directory contains the German print templates as SVG. The templates have placeholders in the form `$xx` where `xx` corresponds to the field names of the DCC schema. - [DCC Certificate of Recovery](RecoveryCertificateTemplate_v4.1.svg) - [DCC Test Certificate](TestCertificateTemplate_v4.1.svg) - [DCC Vaccination Certificate](VaccinationCertificateTemplate_v4.1.svg) > The templates contain DEMO overlays that need to be removed for production cases. ## Fonts The SVG templates require the free [Open Sans](https://fonts.google.com/specimen/Open+Sans) font. ## QR Code Replacement Within the SVG the QR Code is added by replacing `$qr` by a base64 encoded png image of the actual QR Code.