Back in March we started a discussion of how we'd handle trust anchors for the project. It didn't get very far. The basic problem is that we need to establish trust in the identity server corresponding to a NAI. We don't want to send our password to some random attacker; we only want to send it to our identity server we have a trusted relationship with. There are a number of ways we can do this: 1. We can do certificate path validation. This is what web browsers do. There is some set of trust anchors; we construct a path from the root certificate to the certificate of the identity server. We also need to confirm the name of the identity server somehow. So, we'd need: * Set of trust anchors * Constraints on subject name of server * Constraints on subject alternative name of server 2. We can store a hash of the server certificate. This is nice and simple: we simply need a 64-byte string. 3. Leap of faith. We can blindly send the password the first time we connect to the identity server but then only connect to that identity server again. This is roughly what ssh does. ### Our goal Our goal is to optimize for the situation where we're getting configuration information from those running the identity server. However we also want a secure experience when a user is creating an identity card themselves or an application is supplying an identity. ### Where do we get trust anchors Before understanding the tradeoffs between these three approaches we need to look at how we would get trust anchors if we choose to do certificate validation. There are a number of options: * we have a system-wide global default. This is easy to code but tends to be quite bad from an operational/security standpoint. * We get a trust anchor from the identity provider itself. It's unclear what to do in the case where the user adds the identity * We ask the user to select a trust anchor. It's possible to do this, but it's really worse than any other option so not worth spending a lot of time on. Note that deciding how identity providers need to be named is tricky if we have a system set of trust anchors. EAP implementations haven't been very consistent on this point. ### Tradeoffs * Leap of faith tends to be easy for users * We would have to significantly extend the libeap code to implement leap of faith * Leap of faith tends to create support and operational complexity when a server needs to change keys. * Certificate validation with system trust anchors tends to create operational and support complexity all the time * Storing a certificate hash tends to create operational complexity if there is not an update mechanism when servers need to rekey ## What needs to represent a trust anchor on an ID card * An optional base64-encoded CA certificate (a relatively long base64 string) * An optional subject name constraint (string) * An optional subject alternative name constraint (string) * An optional hash of a server certificate The server certificate hash field is mutually exclusive with the other fields. ## An option * Support provisioning a server cert hash and a trust anchor+name constraints in the identity provisioning format * Use the system trust anchor store for user-provisioned identities and do something about naminge ## User Web Provisioning Format Unique Name user_name ENCRYPTEDPW issuer name xmpp@jabber.project-moonshot.org email@project-moonshot.org PATTERN true ANOTHER_PATTERN false ABCDEFGHIJKLMNOPQRSTUVWXYZ123455678910 Foo Bar ABCDEFGHIJKLMNOPQRSTUVWXYZ123455678910 Another Identity another_username