KeyGen2
 
Credential Provisioning and Management Protocol
Disclaimer: This is a system in development. That is, the specification may change without notice.
Table of Contents
1. Introduction
2. Proxy Scheme
3. Protocol Description
3.1. Invocation
3.2. HTTP Dependencies
3.3. Error Handling
3.4. Key Management Operations
3.5. Termination Message
4. Notation
5. Data Types
6. Objects
InvocationRequest
InvocationResponse
ProvisioningInitializationRequest
ProvisioningInitializationResponse
CredentialDiscoveryRequest
CredentialDiscoveryResponse
KeyCreationRequest
KeyCreationResponse
ProvisioningFinalizationRequest
ProvisioningFinalizationResponse
updatableKeyManagementKey
lookupSpecifier
searchFilter
lookupResult
matchingCredential
pukPolicySpecifier
pinPolicySpecifier
keyEntrySpecifier
generatedKey
issuedCredential
cloneKeyProtection
deleteKey
unlockKey
updateKey
encryptedExtension
extension
logotype
propertyBag
property
importPrivateKey
importSymmetricKey
clientCapability
imageAttributes
deviceId
7. Elliptic Curve Support
Appendix A: Sample Run
Appendix B: Acknowledgements
Appendix C: References
Appendix D: Document History
Appendix E: Author
1. Introduction
KeyGen2 is a web-based protocol for enrolling and managing credentials like X.509 certificates [RFC5280]. The protocol is a part of a security architecture which at the core consists of SKS (Secure Key Store) [SKS].
The KeyGen2 protocol is expressed as a set of JSON [RFC8259] objects. This document contains a description of these objects and how they interact, while the integration with the SKS API is dealt with in the SKS architecture document [SKS].
Parts of the protocol rely on cryptographic constructs using JSON which initially were created for the KeyGen2 project, but later became an activity of its own: JSON Signature Format [JSF].
Finding the proper balance in a complex scheme like KeyGen2 is a combination of "gut feeling", political considerations, available technology, foresight and market research. If this particular specification hit the right level only time can tell.
"Perfection is achieved, not when there is nothing more
to add, but when there is nothing left to take away
"
Antoine de Saint-Exupéry
2. Proxy Scheme
Unlike certificate management protocols like CMP [RFC4210], KeyGen2 mandates a two-layer client architecture where the outermost part is talking to the outside world (user and issuer), while an inner part does the communication with the SKS. That is, the client implementation acts as "proxy" enabling the use of a cleartext, JSON based, fairly high-level protocol with issuer, in spite of the fact that SKS only deals with low-level binary data.
Another core proxy task is minimizing network roundtrips through SKS command aggregation.
Although KeyGen2 depends on a proxy for doing the "Heavy Lifting", E2ES (End To End Security) is achieved through the use of a dynamically created shared secret, which is only known by the SKS and the issuer.
For a detailed description of the proxy scheme and the E2ES solution, consult the SKS architecture document [SKS].
3. Protocol Description
This chapter contains a high-level description of the KeyGen2 protocol while the subsequent chapters cover the actual format.
To facilitate a straightforward implementation as well as robust operation, KeyGen2 builds on a concept where each major process step is handled by a specific request/response pair as outlined below:
Invocation
Protocol invocation. During this step the user should be alerted by a browser defined dialog telling what is supposed to happen giving as well as providing an option aborting the process. In addition, the issuer may perform a client platform capability query.
ProvisioningInitialization
Creation of a shared session key securing the rest of the interactions between the issuer and the SKS. To support future updates of provisioned credentials, the issuer may also provide a keyManagementKey.
CredentialDiscovery
Optional: Issuer lookup of already provisioned SKS credentials. This is primarily used when keys need to be updated or unlocked.
KeyCreation
Creation of asymmetric key pairs in the SKS. If user-defined PINs are to be set, this is carried out during KeyCreationRequest. After key pairs have been created the public keys are sent to the issuer for certification.
ProvisioningFinalization
Deployment of credentials and associated attributes as well as key management operations are performed in this step. Finally the session is terminated. If the operation is successful, a cryptographic proof is returned to the issuer.
The result of the ProvisioningFinalizationResponse is anticipated to be a custom Termination Message, typically telling the user that the operation succeeded.
3.1. Invocation
Since the interface between the Web and native applications is not (yet) standardized, the invocation of KeyGen2 relies on browser and platform specific solutions. For Android, "Intents" are currently utilized for handing over an invocation URL (including possible session cookies), to a local KeyGen2 "App".
3.2. HTTP Dependencies
KeyGen2 objects transferred through HTTP must use the Content-Type application/json.
Since KeyGen2 is to be regarded as an intrinsic part of the browser, HTTP cookies must be handled as for other HTTP requests.
3.3. Error Handling
Errors occurring on the client's side must terminate the session and display an error dialog telling the user what happened.
Server-side errors must abort the current server operation and return an appropriate Termination Message to the user. If the KeyGen2 proxy at this stage is rather expecting a KeyGen2 protocol object (see HTTP Dependencies), the client session must be terminated.
Whenever a KeyGen2 client session is aborted, the proxy should also abort the associated, potentially active SKS provisioning session (see abortProvisioningSession).
3.4. Key Management Operations
KeyGen2 provides built-in support for the SKS key management operations postUnlockKey, postDeleteKey, postUpdateKey and postCloneKeyProtection.
In the case the exact key is not known in advance, you must include a key discovery sequence as described in [SKS] Appendix D, Remote Key Lookup.
3.5. Termination Message
When a KeyGen2 protocol sequence terminates (like when the proxy has sent a ProvisioningFinalizationResponse object to the server), the browser must return to its "normal" state, ready for receiving a matching HTTP body containing a HTML page or similar.
Note that returned data must target the same window object which was used during invocation.
4. Notation
JSON objects are described as tables with associated properties. When a property holds a JSON object this is denoted by a link to the actual definition.
Properties may either be mandatory (M) or optional (O) as defined in the "Req" column.
Array properties are identified by [ ] x-y where the range expression represents the valid number of array elements.
In some JSON objects there is a choice from a set of mutually exclusive alternatives.
This is manifested in object tables like the following:
Property selection 1Type selection 1ReqComment selection 1
Property selection 2Type selection 2Comment selection 2
5. Data Types
The table below shows how the data types used by this specification are mapped into native JSON types:
TypeMappingDescription
booltrue|falseBoolean
ushortnumberUnsigned two-byte integer
uintnumberUnsigned four-byte integer
bigintstringBase10-encoded integer with arbitrary precision
stringstringArbitrary string
uristringURI [RFC3986]
idstringIdentifier which must consist of 1-32 characters, where each character is in the range '!' - '~' (0x21 - 0x7e).
byte[]stringBase64URL-encoded [RFC4648] binary data
timestringDate-time string in ISO format YYYY-MM-DDThh:mm:ss{ms}tz where ms is an optional field consisting of '.' followed by 1-3 digits, while tz is either 'Z' or ±hh:mm.
object{}JSON object
Note that "Type" refers to the element type for arrays.
6. Objects
The following tables describe the KeyGen2 JSON structures in detail.
Entries written in italics like generatedKey represent sub objects, while the other entries such as InvocationRequest consitute of the actual messages.
InvocationRequest
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "InvocationRequest"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"idMThe serverSessionId must remain constant for the entire session.
"action": "action"stringMThe action property gives (through a suitable GUI dialog) the user a hint of what the session in progress is about to perform. The valid constants are:
  • manage - Create, delete and/or update credentials
  • unlock - Unlock existing keys. A conforming client should disallow KeyCreationRequest
"privacyEnabled": "privacyEnabled"boolOOptional: The "privacyEnabled" flag is used to set mode during ProvisioningInitializationRequest.
See SKS:createProvisioningSession.privacyEnabled.
Note: The default value is false.
"preferredLanguages": ["preferredLanguages"] 1-nstringOOptional: List of preferred languages using ISO 639-1 two-character notation.
"targetKeyContainers": ["targetKeyContainers"] 1-nstringOOptional: List of target key container types. The elements may be:
  • software - Software protected key container
  • embedded - Hardware protected embedded key container
  • uicc - UICC/SIM card
  • sdcard - SD card
  • external - External/connected key container
The key containers are listed in preference order. If no matching container is available the client may prompt the user for inserting a card or similar.
If targetKeyContainers is undefined the provisioning client is supposed to use the system's 'native' keystore.
"clientCapabilityQuery": ["List of URIs"] 1-nuriOOptional: List of URIs signifying client (platform) capabilities. The response (clientCapabilities) must contain the same URIs (in any order).
Note that capabilities may refer to algorithms or specific extensions (see SKS:addExtension), as well as to non-SKS items.
Another possible use of this feature is for signaling support for extensions in the protocol itself while keeping the name-space etc. intact.
If requested capabilities are considered as privacy sensitive, a conforming implementation should ask for the user's permission to disclose them.
Device-specific data like IMEI numbers must not be requested in the privacyEnabled mode.
The following client attribute URIs are pre-defined:
  • https://webpki.github.io/keygen2/clientattr#imei-number
  • https://webpki.github.io/keygen2/clientattr#ip-address
  • https://webpki.github.io/keygen2/clientattr#mac-address
  • https://webpki.github.io/keygen2/clientattr#os-vendor
  • https://webpki.github.io/keygen2/clientattr#os-version
  • https://webpki.github.io/keygen2/feature#device-pin-support
  • https://webpki.github.io/keygen2/feature#biometric-support
InvocationResponse
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "InvocationResponse"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"stringMCopy of serverSessionId from InvocationRequest.
"clientCapabilities": [clientCapability] 1-nobjectOList of capabilities including algorithms, specific features, dynamic or static data, and preferred image sizes.
ProvisioningInitializationRequest
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "ProvisioningInitializationRequest"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"idMSee SKS:createProvisioningSession.serverSessionId and InvocationRequest.
"serverTime": "serverTime"timeMServer time which the client should verify as a "sanity" check.
"sessionKeyAlgorithm": "https://webpki.github.io/sks/algorithm#session.1"uriMSee SKS:createProvisioningSession.sessionKeyAlgorithm.
"sessionKeyLimit": sessionKeyLimitushortMSee SKS:createProvisioningSession.sessionKeyLimit.
"sessionLifeTime": sessionLifeTimeuintMSee SKS:createProvisioningSession.sessionLifeTime.
"serverEphemeralKey": "serverEphemeralKey"objectMEC public key in JSF [JSF] "publicKey" format.
See SKS:createProvisioningSession.serverEphemeralKey.
For EC curve support see Elliptic Curve Support.
"keyManagementKey": "keyManagementKey"objectOOptional: RSA or EC public key in JSF [JSF] "publicKey" format, dedicated for key management.
See SKS:createProvisioningSession.keyManagementKey.
For EC curve support see Elliptic Curve Support.
"updatableKeyManagementKeys": [updatableKeyManagementKey] 1-nobjectOOptional: List of the previous generation of key management keys.
ProvisioningInitializationResponse
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "ProvisioningInitializationResponse"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"idMSee SKS:createProvisioningSession.serverSessionId and InvocationRequest.
"clientSessionId": "clientSessionId"idMSee SKS:createProvisioningSession.clientSessionId.
"serverTime": "serverTime"timeMServer time transferred verbatim from ProvisioningInitializationRequest.
"clientTime": "clientTime"timeMSee SKS:createProvisioningSession.clientTime.
"clientEphemeralKey": "clientEphemeralKey"objectMEC public key in JSF [JSF] "publicKey" format, using an identical curve to serverEphemeralKey.
See SKS:createProvisioningSession.clientEphemeralKey.
For EC curve support see Elliptic Curve Support.
"deviceId": deviceIdobjectOSee SKS:createProvisioningSession. Note that this property is either required or forbidden depending on the value of privacyEnabled.
"attestation": "attestation"byte[]MSee SKS:createProvisioningSession.attestation.
CredentialDiscoveryRequest
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "CredentialDiscoveryRequest"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"idMSee SKS:createProvisioningSession.serverSessionId and InvocationRequest.
"clientSessionId": "clientSessionId"idMSee SKS:createProvisioningSession.clientSessionId.
"lookupSpecifiers": [lookupSpecifier] 1-nobjectMList of signed credential lookup specifiers. See SKS appendix "Remote Key Lookup" for details.
CredentialDiscoveryResponse
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "CredentialDiscoveryResponse"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"idMSee SKS:createProvisioningSession.serverSessionId and InvocationRequest.
"clientSessionId": "clientSessionId"idMSee SKS:createProvisioningSession.clientSessionId.
"lookupResults": [lookupResult] 1-nobjectMList of credential lookup results. See SKS appendix "Remote Key Lookup" for details.
KeyCreationRequest
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "KeyCreationRequest"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"idMSee SKS:createProvisioningSession.serverSessionId and InvocationRequest.
"clientSessionId": "clientSessionId"idMSee SKS:createProvisioningSession.clientSessionId.
"keyEntryAlgorithm": "https://webpki.github.io/sks/algorithm#key.1"uriMSee SKS:createKeyEntry.keyEntryAlgorithm.
"deferredIssuance": deferredIssuanceboolOFlag telling if the process should be suspended after KeyCreationResponse. Default value: false. See the action property in InvocationRequest.
"pukPolicySpecifiers": [pukPolicySpecifier] 1-nobjectOList of PUK policy objects to be created. See SKS:createPukPolicy.
"pinPolicySpecifiers": [pinPolicySpecifier] 1-nobjectOList of PIN policy objects to be created. See SKS:createPinPolicy.
"keyEntrySpecifiers": [keyEntrySpecifier] 1-nobjectOList of key entries to be created. See SKS:createKeyEntry.
Due to the stateful MAC scheme featured in SKS, the properties beginning with pukPolicySpecifiers and ending with keyEntrySpecifiers, must be generated (by the issuer) and executed (by the SKS) in exactly the order they are declared in this table as well as in associated object arrays.
KeyCreationResponse
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "KeyCreationResponse"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"idMSee SKS:createProvisioningSession.serverSessionId and InvocationRequest.
"clientSessionId": "clientSessionId"idMSee SKS:createProvisioningSession.clientSessionId.
"generatedKeys": [generatedKey] 1-nobjectMList of generated keys. See SKS:createKeyEntry.
Due to the stateful MAC scheme featured in SKS, generatedKey must be encoded (by the SKS) and decoded (by the issuer) in exactly the same order (message wise) as they are encountered in the associated keyEntrySpecifiers (including those embedded by pinPolicySpecifiers).
ProvisioningFinalizationRequest
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "ProvisioningFinalizationRequest"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"idMSee SKS:createProvisioningSession.serverSessionId and InvocationRequest.
"clientSessionId": "clientSessionId"idMSee SKS:createProvisioningSession.clientSessionId.
"issuedCredentials": [issuedCredential] 1-nobjectOOptional: List of issued credentials. See SKS:setCertificatePath.
"unlockKeys": [unlockKey] 1-nobjectOOptional: List of keys to be unlocked. See SKS:postUnlockKey.
"deleteKeys": [deleteKey] 1-nobjectOOptional: List of keys to be deleted. See SKS:postDeleteKey.
"nonce": "nonce"byte[]MSee SKS:closeProvisioningSession.
"mac": "mac"byte[]MCaller authentication. See SKS:closeProvisioningSession.mac.
Due to the stateful MAC scheme featured in SKS, this mac must be the final of a provisioning session both during encoding and decoding.
Due to the stateful MAC scheme featured in SKS, the properties beginning with issuedCredentials and ending with deleteKeys, must be generated (by the issuer) and executed (by the SKS) in exactly the order they are declared in this table as well as in associated object arrays.
ProvisioningFinalizationResponse
PropertyTypeReqComment
"@context": "https://webpki.github.io/keygen2#20190318"uriMKeyGen2 name space/version indicator.
"@qualifier": "ProvisioningFinalizationResponse"stringMActual KeyGen2 message type.
"serverSessionId": "serverSessionId"idMSee SKS:createProvisioningSession.serverSessionId and InvocationRequest.
"clientSessionId": "clientSessionId"idMSee SKS:createProvisioningSession.clientSessionId.
"attestation": "attestation"byte[]MSee SKS:closeProvisioningSession.
updatableKeyManagementKey
PropertyTypeReqComment
"publicKey": "publicKey"objectMRSA or EC public key in JSF [JSF] "publicKey" format, containing a previous generation key management key.
Note that SKS:updateKeyManagementKey.keyManagementKey refers to the new key management key specified in the object immediately above this updatableKeyManagementKey object.
For EC curve support see Elliptic Curve Support.
"authorization": "authorization"byte[]MAuthorization of the new key management key. See SKS:updateKeyManagementKey.authorization.
"updatableKeyManagementKeys": [updatableKeyManagementKey] 1-nobjectOOptional: List of the previous generation of key management keys.
lookupSpecifier
PropertyTypeReqComment
"id": "id"idMEach specifier must have a unique "id".
"nonce": "nonce"byte[]MProperty holding a "nonce" object. See SKS appendix "Remote Key Lookup" for details.
"searchFilter": searchFilterobjectOOptional additional search conditions.
Note that at least one search condition must be specified if this option is used. The result of each condition is combined through a logical AND operation.
"signature": "signature"objectMJSF [JSF] "signature" object using a key management key signature covering the lookup specifier. Note that the "publicKey" property must be present. See SKS appendix "Remote Key Lookup" for more details.
For maximum interoperability, RSA 2048-bit or EC P-256 signature keys should be used with SHA256 as the recommended hash method.
searchFilter
PropertyTypeReqComment
"fingerPrint": "fingerPrint"byte[]OSHA256 fingerprint matching any certificate in the certificate path.
"issuerRegEx": "issuerRegEx"stringORegular expression matching any issuer in the certificate path. Issuer names are assumed to be expressed in LDAP [RFC4514] notation.
"serialNumber": "serialNumber"bigintOSerial number matching that of the end entity certificate.
"subjectRegEx": "subjectRegEx"stringORegular expression matching the subject in the end entity certificate. Subject names are assumed to be expressed in LDAP [RFC4514] notation.
"emailRegEx": "emailRegEx"stringORegular expression matching any of the e-mail addresses in the end entity certificate.
Note that both RFC 822 subject attributes and subjectAltName fields are in scope.
"policyRules": ["policyRules"] 1-nstringOList of X.509 policy extension OIDs using the notation "1.4.3" and "-1.4.7" for a required and forbidden policy OID respectively.
Policy OIDs encountered in end entity certificates that are not specified in policyRules must be ignored.
"keyUsageRules": ["keyUsageRules"] 1-nstringOList of X.509 key usage flags using the notation "digitalSignature" and "-dataEncipherment" for a required and forbidden key usage respectively.
Key usage flags encountered in end entity certificates that are not specified in keyUsageRules must be ignored.
The set of permitted flags include:
  • digitalSignature
  • nonRepudiation
  • keyEncipherment
  • dataEncipherment
  • keyAgreement
  • keyCertSign
  • cRLSign
  • encipherOnly
  • decipherOnly
"extendedKeyUsageRules": ["extendedKeyUsageRules"] 1-nstringOList of X.509 extended key usage extension OIDs using the notation "1.4.3" and "-1.4.7" for a required and forbidden extended key usage respectively.
Extended key usage OIDs encountered in end entity certificates that are not specified in extendedKeyUsageRules must be ignored.
"issuedBefore": "issuedBefore"timeOMatching end entity certificates issued before this date.
Note that you can combine this condition with an issuedAfter condition using an earlier date, effectively creating a time window.
"issuedAfter": "issuedAfter"timeOMatching end entity certificates issued after this date.
"grouping": "grouping"stringOMatching keys based on the SKS:createPinPolicy.grouping attribute.
Note that keys that are not PIN-protected must always fail to match.
"appUsage": "appUsage"stringOMatching keys based on the SKS:createKeyEntry.appUsage attribute.
lookupResult
PropertyTypeReqComment
"id": "id"idMEach result must have a unique "id" matching the request.
"matchingCredentials": [matchingCredential] 0-nobjectMList of matching credentials.
matchingCredential
PropertyTypeReqComment
"serverSessionId": "serverSessionId"stringMserverSessionId of matching credential.
"clientSessionId": "clientSessionId"stringMclientSessionId of matching credential.
"certificatePath": ["Certificate Path"] 1-nbyte[]MCertificate path having identical representation to "certificatePath" in JSF [JSF].
"locked": lockedboolOIf this property is true the key associated with the credential is locked due to multiple PIN errors. The default value is false. See unlockKeys.
pukPolicySpecifier
PropertyTypeReqComment
"id": "id"idMSee SKS:createPukPolicy.id.
"encryptedPuk": "encryptedPuk"byte[]MSee SKS:createPukPolicy.encryptedPuk.
"retryLimit": retryLimitushortMSee SKS:createPukPolicy.retryLimit.
"format": "format"stringMSee SKS:createPukPolicy.format.
"mac": "mac"byte[]MCaller authentication. See SKS:createPukPolicy.mac.
"pinPolicySpecifiers": [pinPolicySpecifier] 1-nobjectMList of PIN policy objects to be created and controlled by this PUK policy. See SKS:createPinPolicy.
pinPolicySpecifier
PropertyTypeReqComment
"id": "id"idMSee SKS:createPinPolicy.id.
"minLength": minLengthushortMSee SKS:createPinPolicy.minLength.
"maxLength": maxLengthushortMSee SKS:createPinPolicy.maxLength.
"retryLimit": retryLimitushortMSee SKS:createPinPolicy.retryLimit.
"format": "format"stringMSee SKS:createPinPolicy.format.
"userModifiable": userModifiableboolOFlag with the default value true.
See SKS:createPinPolicy.userModifiable.
"grouping": "grouping"stringOGrouping specifier with the default value none.
See SKS:createPINPolicy.grouping.
"inputMethod": "inputMethod"stringOInput method specifier with the default value any.
See SKS:createPinPolicy.inputMethod.
"patternRestrictions": ["patternRestrictions"] 1-nstringOList of pattern restrictions. See SKS:createPinPolicy.patternRestrictions.
If this property is undefined, there are no PIN pattern restrictions.
"mac": "mac"byte[]MCaller authentication. See SKS:createPinPolicy.mac.
"keyEntrySpecifiers": [keyEntrySpecifier] 1-nobjectMList of key entries to be created and controlled by this PIN policy.
See SKS:createKeyEntry.
keyEntrySpecifier
PropertyTypeReqComment
"id": "id"idMSee SKS:createKeyEntry.id.
"encryptedPin": "encryptedPin"byte[]OSee SKS:createKeyEntry.pinValue.
Note that if this property is defined, the SKS:createPinPolicy.userDefined flag of the required embedding PIN policy is set to false else it is set to true.
Keys associated with a specific PIN policy must not mix user-defined and preset PINs.
"enablePinCaching": enablePinCachingboolOFlag with the default value false.
See SKS:createKeyEntry.enablePinCaching.
"devicePinProtection": devicePinProtectionboolOFlag with the default value false.
See SKS:createKeyEntry.devicePinProtection.
Note that this flag (if true) cannot be combined with PIN policy settings.
"appUsage": "appUsage"stringMSee SKS:createKeyEntry.appUsage.
"keyAlgorithm": "keyAlgorithm"uriMSee SKS:createKeyEntry.keyAlgorithm. See also SKS "Algorithm Support".
The currently recognized key algorithms include:
  • https://webpki.github.io/sks/algorithm#rsa2048
  • https://webpki.github.io/sks/algorithm#rsa3072
  • https://webpki.github.io/sks/algorithm#rsa4096
  • https://webpki.github.io/sks/algorithm#rsa2048.exp
  • https://webpki.github.io/sks/algorithm#rsa3072.exp
  • https://webpki.github.io/sks/algorithm#rsa4096.exp
  • https://webpki.github.io/sks/algorithm#ec.nist.p256
  • https://webpki.github.io/sks/algorithm#ec.nist.p384
  • https://webpki.github.io/sks/algorithm#ec.nist.p521
  • https://webpki.github.io/sks/algorithm#ed25519
  • https://webpki.github.io/sks/algorithm#ed448
  • https://webpki.github.io/sks/algorithm#x25519
  • https://webpki.github.io/sks/algorithm#x448
"keyParameters": "keyParameters"byte[]OSee SKS:createKeyEntry.keyParameters.
"endorsedAlgorithms": ["List of URIs"] 1-nuriOSee SKS:createKeyEntry.endorsedAlgorithms. See also SKS "Algorithm Support".
Note that endorsed algorithm URIs must be specified in strict lexical order.
The currently recognized algorithms include:
  • http://www.w3.org/2001/04/xmldsig-more#hmac-sha256
  • http://www.w3.org/2001/04/xmldsig-more#hmac-sha384
  • http://www.w3.org/2001/04/xmldsig-more#hmac-sha512
  • https://webpki.github.io/sks/algorithm#rsa.pkcs1.none
  • http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
  • http://www.w3.org/2001/04/xmldsig-more#rsa-sha384
  • http://www.w3.org/2001/04/xmldsig-more#rsa-sha512
  • https://webpki.github.io/sks/algorithm#ecdsa.none
  • http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256
  • http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384
  • http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512
  • https://webpki.github.io/sks/algorithm#ed25519
  • https://webpki.github.io/sks/algorithm#ed448
  • https://webpki.github.io/sks/algorithm#rsa.oaep.sha1
  • https://webpki.github.io/sks/algorithm#rsa.oaep.sha256
  • http://www.w3.org/2001/04/xmlenc#aes128-cbc
  • http://www.w3.org/2001/04/xmlenc#aes192-cbc
  • http://www.w3.org/2001/04/xmlenc#aes256-cbc
  • http://www.w3.org/2001/04/xmlenc#kw-aes128
  • http://www.w3.org/2001/04/xmlenc#kw-aes256
  • https://webpki.github.io/sks/algorithm#aes.ecb.nopad
  • https://webpki.github.io/sks/algorithm#aes.ecb
  • https://webpki.github.io/sks/algorithm#aes.cbc.nopad
  • https://webpki.github.io/sks/algorithm#aes.cbc
  • https://webpki.github.io/sks/algorithm#ecdh.raw
  • https://webpki.github.io/sks/algorithm#none
"serverSeed": "serverSeed"byte[]OSee SKS:createKeyEntry.serverSeed. If this property is undefined, it is assumed to be a zero-length array.
"biometricProtection": "biometricProtection"stringOSee SKS:createKeyEntry.biometricProtection. The default value is none.
"deleteProtection": "deleteProtection"stringOSee SKS:createKeyEntry.deleteProtection. The default value is none.
"exportProtection": "exportProtection"stringOSee SKS:createKeyEntry.exportProtection. The default value is non-exportable.
"friendlyName": "friendlyName"stringOSee SKS:createKeyEntry.friendlyName.
"mac": "mac"byte[]MCaller authentication. See SKS:createKeyEntry.mac.
generatedKey
PropertyTypeReqComment
"id": "id"idMThe "id" property must match the identifier used in KeyCreationRequest for a specific key.
"publicKey": "publicKey"objectMRSA or EC public key in JSF [JSF] "publicKey" format.
See SKS:createKeyEntry.publicKey.
For EC curve support see Elliptic Curve Support.
"attestation": "attestation"byte[]MSee SKS:createKeyEntry.attestation.
issuedCredential
PropertyTypeReqComment
"id": "id"idMSee SKS:setCertificatePath.id.
The "id" property must match the identifier used in KeyCreationRequest for a specific key.
"certificatePath": ["Certificate Path"] 1-nbyte[]MCertificate path having identical representation to "certificatePath" in JSF [JSF].
See SKS:setCertificatePath.certificate.
"mac": "mac"byte[]MCaller authentication. See SKS:setCertificatePath.mac.
"trustAnchor": trustAnchorboolOOptional: Flag (with the default value false), which tells if certificatePath contains a user-installable trust anchor as well.
Trust anchor installation is meant to be independent of SKS provisioning.
"importSymmetricKey": importSymmetricKeyobjectOOptional: Import of raw symmetric key. See SKS:importSymmetricKey.
"importPrivateKey": importPrivateKeyobjectOptional: Import of private key in PKCS #8 [RFC5208] format. See SKS:importPrivateKey.
"updateKey": updateKeyobjectOOptional: See SKS:postUpdateKey.
"cloneKeyProtection": cloneKeyProtectionobjectOptional: See SKS:postCloneKeyProtection.
"extensions": [extension] 1-nobjectOOptional: List of extension objects. See SKS:addExtension.
"encryptedExtensions": [encryptedExtension] 1-nobjectOOptional: List of encrypted extension objects. See SKS:addExtension.
"propertyBags": [propertyBag] 1-nobjectOOptional: List of property objects. See SKS:addExtension.
"logotypes": [logotype] 1-nobjectOOptional: List of logotype objects. See SKS:addExtension.
Due to the stateful MAC scheme featured in SKS, the properties beginning with importSymmetricKey and ending with logotypes, must be generated (by the issuer) and executed (by the SKS) in exactly the order they are declared in this table as well as in associated object arrays.
Note that that credential ids are not guaranteed to be supplied in the same order as during the associated KeyCreationRequest.
cloneKeyProtection,  deleteKey,  unlockKey,  updateKey
PropertyTypeReqComment
"fingerPrint": "fingerPrint"byte[]MSHA256 fingerprint of target certificate.
"serverSessionId": "serverSessionId"stringMFor locating the target key.
"clientSessionId": "clientSessionId"stringMFor locating the target key.
"authorization": "authorization"byte[]MSee "Target Key Reference" in the SKS reference.
"mac": "mac"byte[]MCaller authentication. See SKS:post* methods.mac.
encryptedExtension,  extension
PropertyTypeReqComment
"type": "type"uriMExtension type URI.
"extensionData": "extensionData"byte[]MExtension data.
"mac": "mac"byte[]MCaller authentication. See SKS:addExtension.mac.
logotype
PropertyTypeReqComment
"type": "type"uriMLogotype type URI.
"mimeType": "mimeType"stringMLogotype MIME type.
"extensionData": "extensionData"byte[]MLogotype image data.
"mac": "mac"byte[]MCaller authentication. See SKS:addExtension.mac.
propertyBag
PropertyTypeReqComment
"type": "type"uriMProperty bag type URI. See SKS:addExtension.
"properties": [property] 1-nobjectMList of property values. See SKS:addExtension.
"mac": "mac"byte[]MCaller authentication. See SKS:addExtension.mac.
property
PropertyTypeReqComment
"name": "name"stringMProperty name.
"value": "value"stringMProperty value.
"writable": writableboolOWritable flag. Default is false. See SKS:setProperty.
importPrivateKey,  importSymmetricKey
PropertyTypeReqComment
"encryptedKey": "encryptedKey"byte[]MEncrypted key material. See SKS:import* methods.encryptedKey.
"mac": "mac"byte[]MCaller authentication. See SKS:import* methods.mac.
clientCapability
PropertyTypeReqComment
"type": "type"uriMClient capability type URI.
"supported": "supported"boolMFor non-parametric queries like algorithms this property tells if the type is supported or not.
Unknown or unsupported query types must always return this attribute with the argument false.
"values": ["values"] 1-nstringList of attribute data associated with type.
"imageAttributes": imageAttributesobjectList of client image preferences that the issuer may use for creating suitable logotype objects. Known logotypes include:
  • https://webpki.github.io/keygen2/logotype#list
    This type is meant to be used in credential lists and management dialogs where you could use a logotype together with a "friendly name" string or similar.
  • https://webpki.github.io/keygen2/logotype#card
    A shape designed for wallet-like applications where logotypes usually are personalized.
  • https://webpki.github.io/keygen2/logotype#icon
    Intended for selection windows holding large collections of credentials featured as maps or lists of small icons.
  • https://webpki.github.io/keygen2/logotype#application
    Could be used in applications where a logotype is useful for branding/recognition purposes like in OTP systems.
Logotypes should not have framing borders or extra margins unless these are integral parts of the actual logotype image. Logotypes should render nicely on light backgrounds. Shadows should be avoided since the icon viewer itself may add such. Support for PNG and SVG files is mandatory.
imageAttributes
PropertyTypeReqComment
"mimeType": "mimeType"stringMImage MIME type.
"width": "width"uintMImage width.
"height": "height"uintMImage height.
deviceId
PropertyTypeReqComment
"certificatePath": ["Certificate Path"] 1-nbyte[]MDevice certificate path having identical representation to "certificatePath" in JSF [JSF].
7. Elliptic Curve Support
EC curves can be expressed in SKS [SKS] or JWA [RFC7518] notation.
The following table shows the mandatory to support curve names:
SKS NameJWA Name
https://webpki.github.io/sks/algorithm#ec.nist.p256P-256
https://webpki.github.io/sks/algorithm#ec.nist.p384P-384
https://webpki.github.io/sks/algorithm#ec.nist.p521P-521
https://webpki.github.io/sks/algorithm#ec.secg.p256k1-
https://webpki.github.io/sks/algorithm#ec.brainpool.p256r1-
Appendix A: Sample Run
In the following KeyGen2 sample run the issuer requests that the client (SKS) creates an RSA 2048-bit key protected by a user-set PIN governed by a number of issuer-defined policies.
Finally, the issuer provides a certificate and a platform-adapted logotype.
For information regarding the cryptographic constructs, consult the SKS architecture manual.
InvocationRequest
{
  "@context": "https://webpki.github.io/keygen2#20190318",
  "@qualifier": "InvocationRequest",
  "serverSessionId": "142f1bdb286XVQnqmIRc1bSzm-QN-ZJk",
  "action": "manage",
  "clientCapabilityQuery": ["https://webpki.github.io/keygen2/logotype#list"]
}
After a compatible browser has received this message, a dialog like the following is shown to user:
Credential Enrollment
The following provider wants to create a
login credential for you:
issuer.example.com
Cancel
  OK  
If the user accepts the request, the following response is sent back to the server:
InvocationResponse
{
  "@context": "https://webpki.github.io/keygen2#20190318",
  "@qualifier": "InvocationResponse",
  "serverSessionId": "142f1bdb286XVQnqmIRc1bSzm-QN-ZJk",
  "clientCapabilities": [{
    "type": "https://webpki.github.io/keygen2/logotype#list",
    "imageAttributes": {
      "mimeType": "image/png",
      "width": 94,
      "height": 74
    }
  }]
}
When the server has received the response above, it creates an ephemeral EC key pair and returns the public part to the client
together with other session parameters:
ProvisioningInitializationRequest
{
  "@context": "https://webpki.github.io/keygen2#20190318",
  "@qualifier": "ProvisioningInitializationRequest",
  "serverSessionId": "142f1bdb286XVQnqmIRc1bSzm-QN-ZJk",
  "serverTime": "2019-04-08T16:33:30Z",
  "sessionKeyAlgorithm": "https://webpki.github.io/sks/algorithm#session.1",
  "sessionKeyLimit": 20,
  "sessionLifeTime": 300,
  "serverEphemeralKey": {
    "kty": "EC",
    "crv": "P-256",
    "x": "cpxUxJVt-is8bgWRFm6RuvUkxyv7xJ7PbeT1BCQNNws",
    "y": "De7jXYsdL46ikHOWeC-V-AcNM/RURpu6ZgcVAxLUwns"
  }
}
Next the client generates a matching ephemeral EC key pair and sends the public part back to the server including a client
session-ID, key attestation, device-certificate, etc.:
ProvisioningInitializationResponse
{
  "@context": "https://webpki.github.io/keygen2#20190318",
  "@qualifier": "ProvisioningInitializationResponse",
  "serverSessionId": "142f1bdb286XVQnqmIRc1bSzm-QN-ZJk",
  "clientSessionId": "39NMWamKtHumJFfdIGkDrLP-NMB-5Lwo",
  "serverTime": "2019-04-08T16:33:30Z",
  "clientTime": "2019-04-08T18:33:36+02:00",
  "clientEphemeralKey": {
    "kty": "EC",
    "crv": "P-256",
    "x": "tQXczn7qxGgcLpOVBuw5i-tMHxbJTUF6k3RZGsjdauc",
    "y": "jIlm8sXwknZeQQDTxkfwXKUdhubt6JcqQYA6S8Dm3AE"
  },
  "deviceId": {
    "certificatePath": ["MIIC2DCCAcCgAwIBAgIGARTWcc7VMCSq....awCV4OfAGXLIwJBCp85AN7KNdcJfL"]
  },
  "attestation": "KMUpOesC8nDTLpu8PppsSGg1j....WiwvUcVpbNudbY14lLks8RQuwoiU"
}
After these message exchanges, the SKS and server (issuer) have established a shared session-key, which is used for securing the
rest of the session through MAC and encryption operations.
 
SKS API Reference: createProvisioningSession.
 
In the sample a request for creating a key is subsequently returned to the client:
KeyCreationRequest
{
  "@context": "https://webpki.github.io/keygen2#20190318",
  "@qualifier": "KeyCreationRequest",
  "serverSessionId": "142f1bdb286XVQnqmIRc1bSzm-QN-ZJk",
  "clientSessionId": "39NMWamKtHumJFfdIGkDrLP-NMB-5Lwo",
  "keyEntryAlgorithm": "https://webpki.github.io/sks/algorithm#key.1",
  "pinPolicySpecifiers": [{
    "id": "PIN.1",
    "minLength": 4,
    "maxLength": 8,
    "retryLimit": 3,
    "format": "numeric",
    "patternRestrictions": ["three-in-a-row", "sequence"],
    "mac": "2aUMRubbEk8Xs62QXlPiFJbYlJ68Sw4Fhu48j4uGKXk",
    "keyEntrySpecifiers": [{
      "id": "Key.1",
      "appUsage": "authentication",
      "keyAlgorithm": "https://webpki.github.io/sks/algorithm#rsa2048",
      "mac": "BQpWMwSz4EsYgliHH6RY3UNWuLsR3eJVapY0CYOUTtI"
    }]
  }]
}
After the browser has received this message, a dialog like the following is shown to user:
PIN Code Assignment
Set and memorize a PIN for the
login credential:
• • • • • •
Repeat PIN:
• • • • • •
Cancel
  OK  
When the user has set a PIN matching the issuer's policy and hit "OK", the requested key pair is created and the public part of the
key pair is sent to the server for certification as shown in the response below.
 
SKS API References: createPinPolicy, createKeyEntry.
KeyCreationResponse
{
  "@context": "https://webpki.github.io/keygen2#20190318",
  "@qualifier": "KeyCreationResponse",
  "serverSessionId": "142f1bdb286XVQnqmIRc1bSzm-QN-ZJk",
  "clientSessionId": "39NMWamKtHumJFfdIGkDrLP-NMB-5Lwo",
  "generatedKeys": [{
    "id": "Key.1",
    "publicKey": {
      "kty": "RSA",
      "n": "uSW5wpfano32Q6oU3xMkFig0r145DN....jkjy1ENPdBQaafvJnuh4x58WPTsVCvjimw",
      "e": "AQAB"
    },
    "attestation": "gyRmTPdW4UdGdXlLkHf40PPRL9xac31eJnyyBtf7-Io"
  }]
}
The server responds by issuing a matching certificate including an associated logotype.
 
SKS API References: setCertificatePath, addExtension.
ProvisioningFinalizationRequest
{
  "@context": "https://webpki.github.io/keygen2#20190318",
  "@qualifier": "ProvisioningFinalizationRequest",
  "serverSessionId": "142f1bdb286XVQnqmIRc1bSzm-QN-ZJk",
  "clientSessionId": "39NMWamKtHumJFfdIGkDrLP-NMB-5Lwo",
  "issuedCredentials": [{
    "id": "Key.1",
    "certificatePath": ["MIICmDCCAYCgAwIBAgIGAULxF0G....UimDl7Dt7733M0TT8qSpXeYvV0NLX5kM"],
    "mac": "FkwauPbrrfJZxuEsMkwOFWIIutzdYbEt3P9kr0CG4dc",
    "logotypes": [{
      "type": "https://webpki.github.io/keygen2/logotype#list",
      "mimeType": "image/png",
      "extensionData": "RBgoJkiaJk_IsZAEZUBsZAEZFg....NVBAMTC0RlbW8gU3ViIENBMBTEzMM1oDTM4",
      "mac": "uQ5IuLRDpbSkpfU9FHe1grrQ_FXUBfsxsk6HqspjuCU"
    }]
  }],
  "nonce": "_U9YmqyULox2Q53F4l9pQaxjbzlOu2wMo6_FgGAmooQ",
  "mac": "_e0T_svX9vXQTuyIxDUmmteM2IwvXbSOEREuqbe7fS4"
}
The finalization message which will only be sent to the server if the previous steps were successful.
 
SKS API Reference: closeProvisioningSession.
ProvisioningFinalizationResponse
{
  "@context": "https://webpki.github.io/keygen2#20190318",
  "@qualifier": "ProvisioningFinalizationResponse",
  "serverSessionId": "142f1bdb286XVQnqmIRc1bSzm-QN-ZJk",
  "clientSessionId": "39NMWamKtHumJFfdIGkDrLP-NMB-5Lwo",
  "attestation": "Oy8QaNN0orkE2gxlCWrMYHxDNr6m5FTdVpqTqF9eXlI"
}
Here the user is supposed to receive an issuer-specific web-page telling what to do next. See Termination Message.
Appendix B: Acknowledgements
The design of the KeyGen2 protocol was "inspired" by several predecessors, most notably IETF's DSKPP [RFC6063].
Funding has been provided by PrimeKey Solutions AB and the Swedish Innovation Board (VINNOVA).
Appendix C: References
ReferenceDescription
[JSF]A. Rundgren, "JSF - JSON Signature Format", Work in progress, V0.82, October 2020. https://cyberphone.github.io/doc/security/jsf.html
[OPENKEY]"OpenKeyStore Project", https://github.com/cyberphone/openkeystore
[RFC3986]T. Berners-Lee, R. Fielding, L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", RFC 3986, January 2005. https://tools.ietf.org/html/rfc3986
[RFC4210]C. Adams, S. Farrell, T. Kause, T. Mononen, "Internet X.509 Public Key Infrastructure Certificate Management Protocol (CMP)", RFC 4210, September 2005. https://tools.ietf.org/html/rfc4210
[RFC4514]K. Zeilenga, "Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names", RFC 4514, June 2006. https://tools.ietf.org/html/rfc4514
[RFC4648]S. Josefsson, "The Base16, Base32, and Base64 Data Encodings", RFC 4648, October 2006. https://tools.ietf.org/html/rfc4648
[RFC5208]B. Kaliski, "Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification Version 1.2", RFC 5208, May 2008. https://tools.ietf.org/html/rfc5208
[RFC5280]D. Cooper, S. Santesson, S. Farrell, S. Boeyen, R. Housley, W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, May 2008. https://tools.ietf.org/html/rfc5280
[RFC6063]A. Doherty, M. Pei, S. Machani, M. Nystrom, "Dynamic Symmetric Key Provisioning Protocol (DSKPP)", RFC 6063, December 2010. https://tools.ietf.org/html/rfc6063
[RFC7518]M. Jones, "JSON Web Algorithms (JWA)", RFC 7518, May 2015. https://tools.ietf.org/html/rfc7518
[RFC8259]T. Bray, "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 8259, December 2017. https://tools.ietf.org/html/rfc8259
[SKS]A. Rundgren, "Secure Key Store (SKS) - API and Architecture", Work in progress, V1.05, April 2019. https://cyberphone.github.io/doc/security/sks-api-arch.pdf
Appendix D: Document History
DateVerComment
2014-08-080.7First official release
2014-12-080.71Aligned KeyGen2 with the updated [SKS] and [JSF] specifications
2015-01-120.72Updated version to match ECDSA signature encoding change
2016-01-250.73Added JOSE algorithm support
2017-05-260.80Removed unessesary bloat from the protocol
2019-08-010.85Updated to reflect the 1.05 verson of [SKS]
2020-03-130.86Updated to reflect the 1.06 verson of [SKS]
Appendix E: Author
KeyGen2 was primarily developed by Anders Rundgren (anders.rundgren.net@gmail.com) as a part of the OpenKeyStore project [OPENKEY].