Skip to content

DRAFT response on keygen for TAG consideration

Travis Leithead edited this page Sep 25, 2015 · 3 revisions

DRAFT TAG Response on the <keygen> issue.

The HTMLKeygenElement is a mechanism in HTML for generating a public/private key pair during form submission. It is a legacy browser feature grandfathered into the HTML5 specification. The primary use case for <keygen> is to provision a user's device for client certificate enrolment. As such, use of <keygen> in the wild is expected to be small because provisioned devices may not need to re-provision using <keygen> for years at a time. Below, we describe keygen in more detail, describe recent threats associated with this element, and recommend updating or replacing keygen with an alternative API.

Usage detail: client certificate provisioning

Sequence diagram showing how keygen provisions a client certificate.

The diagram above describes a typical scenario in which the HTML keygen element is used for provisioning a client certificate.

  1. The user agent navigates to a provisioning site (at a specific origin). The HTML resource containing the keygen element with optional challenge attribute is received by the user agent. The keygen element is part of a form intended to be submitted by POST back to the server.
  2. The user can use the keygen element's user interface to choose a weak or strong key length.
  3. The user can submit the form. Alternately, JavaScript code in the user agent can also submit the form. At submission time the keygen element causes an asymmetric key pair to be generated: a public and private key. These keys are not exposed via a web API.
  4. The private key is used to optionally sign a challenge and then it is placed into a secure key store.
  5. The public key is encoded (ANS.1 DER) and submitted in the form to the server.
  6. In the POST response, the server has packaged the public key and related information into a client certificate which is returned via a mimetype (application/x-x509-*-cert) to the user agent. The user agent relays this certificate into the user's certificate store for later use.

Using client certificates in user agents

After requesting a URL, a server may respond with a request for a client certificate as part of its authentication scheme. The response will include a challenge to be signed to ensure proof of possession of the private key associated with the public key in the client certificate.

  • Note: using client certificates for authentication is not allowed in the HTTP2 protocol (it requires an older TLS re-negotiation protocol). Support for better integrating client certificate authentication without re-negotiation in HTTP2 is being investigated.
  1. The user agent prompts the user to select a client certificate to use in the negotiation (there may be more than one).
  2. [Typically] a second prompt (from the secure keystore) may ask the user to approve use of the private key to perform a signature.
  3. The signed challenge and client certificate are sent to the server for verification to release the resource.

Threat Model

The following threat model frames the issues currently found with keygen.

The trust boundaries in the thread model lie between the user agent and server, and the user agent and secure storage.

  • User agent/server - this trust boundary may be either protected via an HTTPS secure connection, or open using an untrusted link. The keygen element is not currently considered a "powerful feature" and thus it works in both secure and insecure contexts secure contexts. (Keygen would certainly be considered a powerful feature by today's standards.) When using an insecure connection, the content provided by the server cannot be trusted, including the behavior of script from that resource.
  • User agent/secure storage - some user agents defer to their host operating system to manage and secure crypto key material (an alternative, e.g., in Mozilla Firefox, is an independent browser-only key storage). For host OS-managed cases, a trust boundary exists between the user agent and the operating system. This boundary is typically trusted. The risk to user agents using an OS-provided key storage, is that actions taken by the user agent with regard to the key storage can have a global impact on the user's device. This is especially dangerous if these actions happen without user-consent and automatically by a potentially un-trusted web application. Because many applications on the host OS might share the same key storage all are put at risk when the key storage is manipulated by the browser. Of course, when the key storage is implemented by the browser separately from the OS key store, the risk to the OS and other applications in it is minimized.

Known Threats

  1. Untrusted script can launch denial-of-service attacks against the user's key storage because form submission including keygen material does not require user action.
  2. Keygen submission has unmitigated access to the key storage; web pages can affect either 1) global OS state changes without user permission, or 2) origin agnostic certificate installation (in user agents that implement their own key storage). At a minimum, this violates the same origin policy.
  3. User agents install client certificates via a special mime-type automatically, again affecting global OS state without user permission (in user agents that have a separate key storage)

Principle:

  • Web pages must not impact global OS/shared resource state without user permission or a clear understanding that the user directly caused the action to happen (the action should not happen implicitly by invoking an API exposed to script). This principle is correctly applied to resources such as cameras and microphones in WebRTC and Geolocation, which all ask for permission from the user before enabling access (which may simultaneously cause implicit revocation of the resource by another entity).

Improving Keygen

Using the above principle, and given the threats noted above, there is a non-trivial amount of work we recommend in order to improve the security and usability of keygen:

  • The MD5 hashing algorithm, as currently defined in HTML5 and interoperably implemented in several user agents is quite dated. Security researchers now recommend more secure hashing algorithms such as SHA-2. keygen should be upgraded to use strong secure hashing functions by default (with a compatibility option for MD5 if necessary for compatibility).
  • Keygen is a powerful feature. Its use should be restricted to a secure context.
  • Keygen must avoid changing global OS key storage state without user permission. For implementations that use a separate OS key storage, user permission must be granted prior to writing new private keys into the store.
  • Keygen's container structure for uploading public key material to the server should be modernized to new formats ?? (not sure which)
  • The user interface for keygen should be reconsidered. Users are not in the best position to evaluate which type of key strength is needed. This is usually a requirement of the server. Perhaps no user interface is required.
  • Consider supplementing keygen with basic extensibility such as the capability to add additional meta-data requests for client certificate extensions, certificate expiration requests, etc.
  • Consider allowing the public key material to be extracted from the keygen element so that custom packaging can be achieved out-of-band.

Additionally, the auto-installation of the returned client certificate should not be installed without user permission. Alternative approaches, such as prompting the user to download and manually install the certificate seem reasonable.

In looking at an alternative to improving keygen, we consider what features are already available in the Web Crypto API:

  • The CryptoKey interface is designed as a general read-only abstraction over key material. The object itself can be used as a proxy for the key material without disclosing the actual key material.
  • APIs to generate public/private CryptoKey objects are already defined (generateKey/deriveKey).
  • A flag is available to protect the key material from extraction (the 'extractable' flag in the generation APIs).

We note that provisioning of keys is declared out-of-scope for the current Web Crypto API.

If provisioning were to be provided by a Web Crypto API, we would expect to see at least the following requirements met:

  • Must be considered a powerful feature and only available under secure contexts (already the case for Web Crypto API?)
  • Must not release the provisioned private key as a transferrable object (it's not appropriate to persist, postMessage, or in any way store-for-later the key material). (Perhaps a new KeyUsage value of "non-transferrable"?)
  • A new provisioning API which:
    • Must require user permission to install the private key into any non-origin-tied persistent storage
    • Must require user permission to sign/use the private key after provisioning (this may be inevitable in OS-managed key storage systems)
    • Must require user permission to load/retrieve a private key from any non-origin-tied persistent storage (this would seem obvious as the user need identify which key to load, perhaps with hints from the web application)
  • Must allow the provisioned private key to be installed into a non-origin-tied persistent storage (either directly, or by alternative means, such as make the private key downloadable for the user to handle)

Recommendation

  • Key provisioning via keygen, as implemented in some user agents, is vulnerable to several threats. We encourage mitigation of these threats in a timely manner. Furthermore, we encourage:
    • improvements to keygen as previously described, and/or
    • a replacement API be developed as noted in the Web Crypto WG in order to secure and modernize the public key provisioning capabilities provided by the web platform.
  • We recognize that an improved polyfill of keygen could be implemented using a new Web Crypto Provisioning API. This may be a preferable route for compatibility with legacy web applications.
  • We also recognize the sad state of browser UI for client-certificate use in authentication:
    • Cert selection UI in browsers is hard (doesn't answer why and for what)?
    • Separate access to private key for signing is a challenge

We call on implementations to improve the UI for this experience in order to make client-certificate use in authentication more accessible to general users (where client certificates offer a stronger security authentication scheme than passwords with the additional benefit of being decentralized).

FIDO
  • Not much to say until we can begin collaboration, but hopeful that this extends the capabilities.