aboutsummaryrefslogtreecommitdiffstats
path: root/posts/indiecert.md
diff options
context:
space:
mode:
Diffstat (limited to 'posts/indiecert.md')
-rw-r--r--posts/indiecert.md265
1 files changed, 265 insertions, 0 deletions
diff --git a/posts/indiecert.md b/posts/indiecert.md
new file mode 100644
index 0000000..8f5fedc
--- /dev/null
+++ b/posts/indiecert.md
@@ -0,0 +1,265 @@
+---
+title: Introducing IndieCert
+published: 2015-02-02
+modified: 2015-03-08
+---
+
+**More feedback is required before this document can be considered finished. See "Issues" section below.**
+
+Authenticating to web servers with a client certificate, installed in the
+user's browser, is unfortunately not widely used. They are convenient and safe
+to use once the initial hurdle of installing them is taken.
+
+There is now a Proof of Concept instance! Check it out [here](https://indiecert.net)!
+
+The main benefit is easy and secure authentication. There is no need to provide
+a password to any service, only the URL to your home page. So there is no
+chance you will leak your password to some service.
+
+<video controls="controls" width="575">
+ <source src="https://storage.tuxed.net/fkooman/public/upload/blog/indiecert_auth_flow.webm" type="video/webm">
+ <source src="https://storage.tuxed.net/fkooman/public/upload/blog/indiecert_auth_flow.mp4" type="video/mp4">
+</video>
+
+In addition, this proposal describes a way to make the use of client certificates
+feasible:
+
+1. A self-signed CA is used instead of a 'browser trusted' CA to issue the client certificates, this works without browser warnings;
+2. Users authorize the certificates by publishing the certificate fingerprint on their home page allowing to claim ownership of a URL and by authenticating with the certificate directly;
+3. Allow identity (certificate) linking using the user's home page address to allow registration of multiple fingerprints to support multiple devices and browsers.
+
+A possible drawback is that many users do not have a home page anymore. They
+have a Facebook profile or a Twitter account, but no home page. However, this
+is not relevant for [IndieWeb](https://indiewebcamp.com/) as all
+users should have their own home page running on their own domain anyway :)
+
+As a fallback it is possible to allow authenticating using existing social
+networks, similar to [IndieAuth](https://indieauth.com), instead
+of using the client certificates. Some browsers and operating systems
+unfortunately do not support easy client certificate enrollment.
+
+<img src="https://storage.tuxed.net/fkooman/public/upload/blog/keep-calm-and-use-certificates.png" width="300" height="350" alt="keep calm and use certificates">
+
+### Protocol for Relying Parties
+
+The protocol follows the protocol proposed for IndieAuth. The protocol is
+based on the IndieAuth protocol and aims to be compatible with it.
+
+#### Request Authentication
+
+The service redirects the user to `https://indiecert.net/auth` to
+start the authentication phase. Two parameters need to be specified:
+
+- **redirect_uri**:
+ - the URL the browser should be redirected back to after the authentication is successful. This MUST be a valid HTTPS URL;
+- **me**:
+ - the URL to the user's home page (see [Retrieving the User's Home Page](#retrieve_home_page));
+
+##### Example
+Below is an example of a browser redirect. The process can also be initiated
+with a `<form>` submit using the `GET` method.
+
+```
+HTTP/1.1 302 Found
+Location: https://indiecert.net/auth?redirect_uri=https://example.org/callback&amp;me=https://tuxed.net/fkooman
+```
+
+IndieCert will at this point take care of the authentication and optional
+enrollment process if that was not already done.
+
+#### Authentication Response
+
+IndieCert will redirect the browser back to the `redirect_uri`
+specified in the authentication request after the user is authenticated at
+IndieCert.
+
+##### Example
+
+```
+HTTP/1.1 302 Found
+Location: https://example.org/callback?code=wW3OLXJZn35d7zFwg9YGmWti
+```
+
+#### Verification Request
+
+The `code` parameter can now be used to request the claimed user
+identity. The following parameters are required:
+
+<dl>
+ <dt>`code`</dt>
+ <dd>the code obtained in the authentication response query parameter `code`.</dd>
+ <dt>`redirect_uri`</dt>
+ <dd>the URL the browser was redirected back to after the successful authentication;</dd>
+</dl>
+
+Now a HTTP `POST` can be used to obtain the user's (normalized) home
+page URL:
+
+```
+POST /auth HTTP/1.1
+Host: indiecert.net
+Content-Type: application/x-www-form-urlencoded
+Accept: application/json
+
+redirect_uri=https%3A%2F%2Fexample.org%2Fcallback&amp;code=wW3OLXJZn35d7zFwg9YGmWti
+```
+
+The response will be formatted as JSON indicating the actual user home page in
+the `me` parameter.
+
+This is the identity that MUST be used by the relying party to identify the
+user as it could differ from the initial `me` specified by the user,
+e.g.: redirects were followed to reach the user's home page.
+
+```
+HTTP/1.1 200 OK
+Content-Type: application/json
+Cache-Control: no-store
+Pragma: no-cache
+
+{
+ "me": "https://www.tuxed.net/fkooman/"
+}
+```
+
+In case there was a failure in verifying the code, e.g. it was already used, or
+not valid the following response can be expected:
+
+
+```
+HTTP/1.1 400 Bad Request
+Content-Type: application/json
+Cache-Control: no-store
+Pragma: no-cache
+
+{
+ "error":"invalid_request"
+}
+```
+
+### Protocol for the IndieCert Service
+
+The IndieCert service has to deal with certificates, issuing, installing and
+verifying them. The most convenient method is to use the HTML
+`<keygen>` tag. This makes the browser generate a private key
+and certificate request (SPKAC) that is then sent to the service for signing.
+The service will sign this with the CA generated for this particular IndieCert
+instance. The signed certificate is sent back to the client and (automatically)
+imported in the browser certificate store.
+
+After this, the certificate can be used to authenticate to the IndieCert
+service, but it still needs to be linked to the URL of the user's home page.
+This can be done by using the `rel="me"` attribute in a
+`<link>` header tag or `<a>` body tag.
+
+```
+<link rel="me" href="ni://indiecert.net/sha-256;WXXyBZDo1pZYiLbrCNGFtSdSamqEvSJJBRzpx-MNIUA?ct=application/x-x509-user-cert">
+```
+
+Once the user has placed this HTML element on their home page the URL it will
+be found when the IndieCert instance will fetch the URL and extract all
+`<link>` and `<a>` tags to look for the
+`rel="me"` attribute. The fingerprint of the client certificate
+used to authenticate to IndieCert needs to be listed on the home page.
+After that, the URL of the home page will be used as an accepted identifier.
+
+<video controls="controls" width="575">
+ <source src="https://storage.tuxed.net/fkooman/public/upload/blog/indiecert_enroll.webm" type="video/webm">
+ <source src="https://storage.tuxed.net/fkooman/public/upload/blog/indiecert_enroll.mp4" type="video/mp4">
+</video>
+
+#### Retrieving the User's Home Page
+
+The user's home page MUST be fetched over HTTPS only, MUST follow redirects and
+MUST NOT have any HTTP URLs in its redirect path. If the URL does not start
+with `https://` it MUST be added by IndieCert. If a URL starts with
+`http://` or is otherwise invalid it MUST be rejected. The final
+URL, the URL that returns a `200 OK` status, MUST be used in the
+response to the verification request, this is the normalized home page URL.
+
+For example the user provides `tuxed.net/fkooman`. IndieCert makes
+this `https://tuxed.net/fkooman` and starts the fetching process. It
+is then redirected to `https://www.tuxed.net/fkooman` and then to
+`https://www.tuxed.net/fkooman/`. The claimed identity thus becomes
+`https://www.tuxed.net/fkooman/` and this value is returned in
+response to the verification request.
+
+### Identity Linking
+
+One of the benefits of publishing fingerprints on the user's home page is that
+additional client certificate fingerprints can easily be added to the home page
+to allow those certificates to claim the same identity.
+
+```
+<!-- laptop -->
+<link rel="me" href="ni://indiecert.net/sha-256;WXXyBZDo1pZYiLbrCNGFtSdSamqEvSJJBRzpx-MNIUA?ct=application/x-x509-user-cert">
+
+<!-- phone -->
+<link rel="me" href="ni://indiecert.net/sha-256;ThIaJ7TJQ1oAIKCGKe0BdBO3Bh8NzxZeyAa-WCTuzpU?ct=application/x-x509-user-cert">
+```
+
+Certificate revocation is done by removing the entry from the home page and it
+can no longer be used to claim the identity.
+
+### Fingerprint Generation
+
+The fingerprint of the certificate is generated by calculating the SHA-256 hash
+over the DER encoded certificate and base64url encoding the resulting binary
+string according to RFC 6920 "Naming Things with Hashes" and RFC 4648
+"The Base16, Base32, and Base64 Data Encodings". An example of calculating a
+fingerprint in PHP:
+
+```
+<?php
+$string = 'Hello World!';
+echo rtrim(strtr(base64_encode(hash('SHA256', $string, true)), '+/', '-_'),'=');
+```
+
+### Distributed IndieCert
+
+One of the important issues to solve is how to make this protocol distributed,
+i.e.: how to allow multiple instances of IndieCert to be used by different
+services whilst allowing a smooth user experience.
+
+The relying party can choose to join an existing IndieCert instance, or run
+their own if they don't trust any of the existing instances. The benefit of
+running their own is better control and more trust and no requirement on third
+parties for the authentication to their service.
+
+Assuming they want to run their own instance that would require the user to
+generate a new certificate and put the fingerprint on their home page as well.
+This results in additional overhead, for the user, but may be worth it from a
+security perspective. And the process needs to be repeated once per IndieCert
+instance, per device or even per browser. This the greatest weakness of this
+proposal, that and adoption. If everyone runs their own IndieCert instance it
+will quickly become a management nightmare for the user if they have to keep
+track of all certificates in all their browsers on all their devices. This
+could be solved by a tool allowing users to easily add fingerprints to their
+website.
+
+For the actual user experience, the user just selects the specific certificate
+for the specific IndieCert instance (it can be pre-selected by most browsers
+based on the CA) so that should not be a problem.
+
+### Issues
+
+There are a number of issues we have to solve before this document can be
+considered stable:
+
+- CSRF. User X can generate a code for his identity and trick user Y into
+ going to a relying party with user X's code to work under user X's identity,
+ possibly storing private data under user X's identity instead of user Y's. We
+ need to implement some kind of state generating/checking;
+- Rate limiting on the verify endpoint;
+- Many browsers, many devices, many instances of IndieCert is a scalability nightmare for the user...
+
+### References
+
+- [IndieAuth](https://indieauth.com)
+- [IndieWebCamp](https://indiewebcamp.com)
+- [RelMeAuth](http://microformats.org/wiki/RelMeAuth)
+- [Certificate Download Specification](https://wiki.mozilla.org/CA:Certificate_Download_Specification)
+- [Keygen Tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen)
+- [Naming Things with Hashes](http://tools.ietf.org/html/rfc6920) (RFC 6920)
+- [The Base16, Base32, and Base64 Data Encodings](http://tools.ietf.org/html/rfc4648) (RFC 4648)
+- [The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749) (RFC 6749)