ehn-dcc-development / hcert-testdata

Electronic Health Certificates prototype
BSD 2-Clause "Simplified" License
6 stars 1 forks source link

Principles for keyID and issuer name binding #2

Closed Razumain closed 3 years ago

Razumain commented 3 years ago

One important aspect of the hcert is the binding between the signing key and the issuer of the hcert.

The KeyID is used as a universal identification key that allows the verifier to locate and find the signer certificate holding the signer key.

Once the trusted signer key has been located and used to validate the hcert, we then need to establish the identity of the signer.

KeyID Both of these tasks can easily be accomplished by incorporating the signer identity in both the KeyID as well as in the hcert issuer information. But textual information about the hcert issuer in the form of a Distinguished Name (DN) according to X.500 requires quite some data space, which we want to minimise. So the question is how we can do better, but still retain the necessary functionality as well as international interoperability.

The first task to find the optimal solution is to determine what use-cases we need to support in the process to locate the signer key/certificate based on the KeyID. Whatever the solution is, it is absolutely essential that the format of KeyID is standardised and harmonised among the participating countries. Without such harmonisation we can't guarantee that a verifying application can locate the correct signing key/certificate.

The master storage space for keys/certificates is the ICAO PKD (Public Key Directory) which is an LDAP directory. LDAP directories uses DN to locate objects in the directory. In absence of a DN, you can't make a direct lookup in the directory. So the first task is to determine if we need to be able to locate a key/certificate using an LDAP lookup using a DN as the lookup key. If the answer to this question is YES, then the KeyID must contain the DN, or at the least, it must be possible to derive the DN from the KeyID. If tis is to be done off-line, we then need to encode/compress the DN in a way that it can be reassembled and used to make an LDAP lookup.

If the answer to this question is NO, then we can do much better by deriving an arbitrarily small identifier that can be matched against a key/certificate in the directory.

The discussions so far has concluded that it is NOT necessary to allow direct LDAP lookup based on a DN. It appears that the common practice is to simply download all certificates from the PKD and build your own "hash-table" where you can do your own local indexing to locate an appropriate certificate. The amount of data and keys is small enough to make this task trivial.

The first conclusion here is therefore that the KeyID does NOT have to contain the DN of the hcert issuer.

The second question is whether KeyID must be unique. If the answer is yes, then we need a longer KeyID than if the answer is no. The conclusion here is that KeyID does not have to be unique. It only need to be unique enough to limit the number of potential keys in a meaningful way. It is not the KeyID itself, but the actual key and how that 1) can be verified and 2) matches the signature on the hcert, that determines if it is the right key or not. There is no threat or attack made possible caused by KeyID collisions. It only makes the matching process a little bit harder since more than one key may have to be tested.

PROPOSAL on KeyID: The proposal for a KeyID algorithm is to use the well known hash Algorithm SHA 256 to hash the certificate from the PKD that was intended to be used with this hcert. This hash value MAY be truncated to an arbitrary size. However the size MUST not be shorter than 8 bytes. When KeyID is truncated, it always represent the first bytes of the hash value of the certificate.

Issuer name binding Once the Hcert is validated the verifier need to obtain the identity of the issuer. This can be stored in the Hcert, but as we have gone through efforts to obtain and verify the signing certificate of the Hcert signer, and because we consequently always will have such verified certificate available, we could just refer to the issuer identity located in that certificate.

A short issuer identity in the Hcert can be accomplished either by setting up naming restrictions ensuring short issuer names, or by simply allowing a simple short reference the the issuer name in th issuer certificate.

PROPOSAL on Issuer name binding: The proposal for issuer name in the Hcert is to have a choice between either a short explicit identifier according to some set rules for constrained issuer identities, or to include a hash of the DN in the associated issuer certificate.

The defined process to validate a hcert is:

  1. Determine the claimed country of issuance of the Hcert
  2. Obtain all trusted certificates related to that country and a hash table over SHA256 hashes of these certificates
  3. Obtain the KeyID of the Hcert
  4. Locate the (1 or possibly more) certificates where the KeyID match the first bytes of the cert hash.
  5. Try all matching certificates to determine which match the signature of the Hcert
  6. Use the explicit short issuer name from the Hcert, alternatively validate the hash of the subject DN of the issuer certificate and import the issuer identity from that certificate.
jschlyter commented 3 years ago

Online Lookup

I proposed that we drop any requirement to be able to look up a certificate online given the kid. The system is designed to operate in offline mode so validators must be able to operate on a downloaded trusted list anyway.

Classic JWT/CWT Validation

  1. Retrieve kid from token (JWT/CWT)
  2. Find all keys where key.kid == token.kid (there can be more than one since kid does not need to be unique)
  3. Try to validate token signature using all found keys
  4. For the first validation that succeeds, extract issuer from token iss claim.
  5. Look up issuer metadata (e.g., display name) via iss

X.509 to iss/kid Mapping

Issuer

Key Identifier

Razumain commented 3 years ago

The reason why I propose a hash of the cert is because it is 1) simple and 2) the solution that is guaranteed to cover most information that we have bound to the verification key, which may include aspects such as extended key usage and more.

If we just bind to the key or name only, then I fear that there may be some ambiguity if there are 2 certs for the same key, or 2 certs for the same name, with slightly different metadata in the cert.

I don't know if such threats are realistic, I'm just trying to pick the solution that is more safe and where I can't see any obvious penalties of choosing it.

fredriklj commented 3 years ago

The first of the proposed validation steps is to determine the claimed country of issuance. This may not be straight-forward? It would require further decoding of the payload before validation of the signature has actually taken place, unless that is given as some sort of pre-amble to the kid?

On the subject on how to generate the kid, one option could be to use RFC 7638 as described in section 3.5, as it could be more agnostic if certs are not used in all contexts. Obviously, that hash would only be over the public key itself, not over any related information. Are there such use-cases where the same key are used for different purposes (different issuers)? Two keys for the same owner is not a problem I believe.

Remaining question is, do we even need iss in the hcert? That would be looked up be checking to whom the key belongs?

jschlyter commented 3 years ago

If we drop iss and set kid to a truncated (16 bytes) SHA-256 of the public key per RFC7638?

jschlyter commented 3 years ago
jschlyter commented 3 years ago

Closing this, we can reopen if we no longer agree :-)