Subject: [openpgp] Scoped trust (signatures)

From: Leo Gaspard <[email-masked]>
Date: Fri, 18 May 2018 22:26:03 +0200

Hello,

I have subscribed to this list only recently (late 2016), so please
forgive me if this has already been discussed, as I couldn't find it in
the ML archives. I also hope I didn't miss something fundamental while
writing down this idea.

As I understand it, currently, with OpenPGP, it is possible to simulate
the Certificate Authority model:
 * The clients wishing to use it assign full trust to the root CAs
 * Root CAs use 255-trust trust signatures for subordinate CAs
 * Subordinate CAs sign the verified OpenPGP keys

I think it would be great to also be able to simulate the DNSSEC model,
so that as a client I would be able to say “I trust [this key] to make
statements about [this set of keys].” I see it as, is in a way, a
logical follow-up of Web Key Directory.

As I understand it, RFC4880 already has a provision for such a model,
with §5.2.3.14 _Regular Expression_.

However, there is from my reading an issue with (the wording of) this
section: it only restricts one-level trust signatures. In other words,
from my reading, if:
 * User U trusts(255, r".*<[email-masked]>") "A <[email-masked]>"
 * [email-masked] trusts(255, r".*<[email-masked]>") "B <[email-masked]>"
 * [email-masked] signs "C <[email-masked]>"

Then, from A's point of view:
 * [email-masked] has trust(255, r".*<[email-masked]>")
 * [email-masked] has trust(254, r".*<[email-masked]>")
 * [email-masked] is valid

However, I don't think [email-masked] should be valid, as user U only
wanted to give permissions on r".*<[email-masked]>" to [email-masked]. So I
think all regular expressions in the trust chain should have to match in
order to not be rejected -- in a similar fashion as the DNSSEC model.

So the “wrong” line here would be [email-masked]'s trust, which should be
calculated as trust(254, r".*<[email-masked]>" AND r".*<[email-masked]>").

Another issue of this scheme, obviously, is that noone “in the wild”
currently uses regular expression subpackets (that I know of). However,
I hope this could change, were this change to allow creation of scoped
CAs, that would interact nicely with WKD.

For instance, a mail provider could set up such a “CA”, that would
automatically sign all keys that would pass the WKD test, and for which
the UID would be confirmed as valid by the internal database. Then,
users could start trusting such mail-provider-provided CAs, for
additional validation of the user ID (in addition to the localpart
already “validated” by HTTPS), while still restricting them for only
being valid for the domain(s) they own. For easy discovery,
mail-provider-provided CAs could have a path at
.well-known/openpgpkey/mail-provider-key, and the user could decide to
add some trust to this CA.

The aim of this proposal being to make OpenPGP easier to use by
introducing ways to reduce the work required for setting up a secure
channel, while leaving control over these to the user (or to the
implementer, for opinionated implementations)

What do you think about this?

Cheers,
Leo

---

From: "Neal H. Walfield" <[email-masked]>
Date: Sun, 27 May 2018 22:56:10 +0200

Hi Leo,

On Fri, 18 May 2018 22:26:03 +0200,
>  * [email-masked] has trust(254, r".*<[email-masked]>")

For reference, here's the relevant text:

  5.2.3.14.  Regular Expression

     Used in conjunction with trust Signature packets (of level > 0) to
     limit the scope of trust that is extended.  Only signatures by the
     target key on User IDs that match the regular expression in the body
     of this packet have trust extended by the trust Signature subpacket.

I interpret this differently.  I interpret "to limit the scope of the
trust that is extended" to mean that the source extends *its* trust to
the target.  That is, trust is not somehow reset when following an
edge in the graph, but either passed on as is or narrowed.

> calculated as trust(254, r".*<[email-masked]>" AND r".*<[email-masked]>").

Even if the standard is wrong here, this is definitely a more useful
and non-broken approach, and, I suspect, almost certainly what was
intended.

> currently uses regular expression subpackets (that I know of).

Not only does almost no one use regular expressions, but regular
expression support is not very widely supported (GnuPG doesn't support
regular expressions on Windows), and until recently broken in GnuPG
(see https://dev.gnupg.org/T2923).

I would like to make a counter proposal, that Vincent and I came up
with at FOSDEM: I think that we should deprecate Regular Expression
support and replace it with a list of domains (optionally prefixed
with "*." to indicate any subdomain).  First, most users don't
understand regular expressions.  And, although it would be possible to
allow users to enter one or more domains and then convert them to a
regular expression, it is not easy to reverse this process, which is
essential for explanatory purposes and editing.  Second, not including
an RE engine reduces complexity.

:) Neal

---

From: Leo Gaspard <[email-masked]>
Date: Mon, 28 May 2018 00:27:19 +0200

> an RE engine reduces complexity.

Issue
-----

This is what I had in mind at the beginning, but then I came upon a
stumbling block: User IDs. They are not at all standardized, so it's not
possible to assume they are in the form “Name (Comment)
<[email-masked]>”. And, even if assuming this, how could the
implementation validate the “Name” and “Comment” parts, when the Regular
Expression support is replaced by something to validate by domain?

So I think there are two problems here:
 1. User IDs are not standardized
 2. User IDs contain many unrelated information

I already explained point 1, so I'll now explain point 2. User IDs as
currently used tie in a name and an email (I'll omit the Comment part).
Which are two completely unrelated things: I have a single real-life
name (well -- most people do), a pseudonym, and a lot of e-mail addresses.

When I want to sign someone's User ID, I need to both check their
real-life name (with eg. a state-provided ID) and their e-mail address.
And if someone has put a pseudonym on the User ID, should I sign it?
This tight coupling of name and email address in User IDs is already an
issue for me (in choosing what User ID(s) I should put, choosing whether
to sign a User ID I only know part of…), and is now again an issue in
fixing the standard to be both more simple and more usable.

Idea
----

So here is my idea: drop User IDs in v5 keys, and standardize more User
Attributes. In particular, standardize at least a “name”, an “email” and
a “pseudonym” user attribute. (I'm not sure about the “comment” user
attribute, and would prefer seeing it handled otherwise, see the
“Possible extensions” section)

Consequences
------------

So what would happen were this done?

First, when picking my User IDs, I wouldn't have to think over whether I
really want to associate such email address with my name or with my
pseudonym.

Then, when signing User Attributes, I could just sign all user
attributes I checked. I could sign “email” User Attributes after
checking I could send and receive mail to the provided email, I could
sign “name” attributes after checking a state-provided ID, and I could
sign “pseudonym” and “comment” attributes depending on my local signing
policy (which I haven't really determined yet).

Finally, this would make the scoping-by-domain-name proposal possible:
it'd be “can only sign `email` User Attributes and the part after the
last @ must match this restriction”.

Possible extensions
-------------------

So now with this change it would become possible to handle extensions of
the User IDs that have been proposed.

First, the “[project] signing key” comment, that can be seen eg.
[here](https://sks-keyservers.net/pks/lookup?op=vindex&search=0x8B3F30F9C8C0C2EF).
This could be handled by adding a “role” User Attribute, that could be
“Qubes OS developer” here. And thus the organization only needs to
validate the keyholder is a QubesOS developer when signing this, without
having to also validate a name, an email address or whatever else.

Then, the “I have this account on this website”, that can be seen eg.
[here](https://sks-keyservers.net/pks/lookup?op=vindex&search=0xAC6D00DB7F24B2C2),
and is the point that, as far as I understand, lead to the birth of
keybase.io (which did show some traction). It could be handled by a
“account-on” that would store both a domain name (for the website) and a
username.

Finally, I think it would be good to stay more “open to extensions” than
the current scheme of (mis)using User IDs, by eg. reserving attribute
type 255 for “plaintext key-value user ID”, so that implementations that
can't reasonably fit some data in one of these User Attributes could
just use it with raw key/values instead of using one of the 100-110
reserved values, which wouldn't be displayed by implementations not
aware of them.

Remaining issues
----------------

The foremost issue with this change is the one of the UI to display the
user: currently, in Enigmail (the only end-user-oriented UI I know of),
the primary User ID of the key is displayed. With this change, there
would no longer be a primary User ID.

I can currently think of two UIs. The first would check that the name
and the email address of the received mail are valid, and error-out
otherwise. The second one would just pick a name and an email address
from the list of valid ones, and display it.

In my opinion, the first option is *way* better than the second one, and
it's the reason why I didn't propose an extension of the Primary User ID
flag to handle multiple primary User Attributes (would be one name and
one email, for instance).

For instance, a problem with primary User IDs/Attributes is the
following: let's assume I can validate a few UIDs on the key, but not
the primary one. What should I display? I think there is no good answer
to this question apart from “validate the one it came as” or “show all
the valid ones”, and thus removing the Primary UID may remove some traps
naive implementations may fall in, like displaying a non-validated
primary UID.

> [snip]

Indeed, it looks like I had misinterpreted this, thanks!

---

From: Vincent Breitmoser <[email-masked]>
Date: Mon, 28 May 2018 00:55:15 +0200

> “account-on” that would store both a domain name (for the website) and a

Been there, done that: https://tools.ietf.org/html/draft-vb-openpgp-linked-ids-01
It's also implemented and deployed as an experimental feature in OpenKeychain.

As a more general note, it would be nice if we could drop the requirement to
have at least one (unsigned) user id, in which case the primary key gets its
properties from a (then mandatory) direct key signature. For key distribution
models other than searchable-by-uid keyservers (including autocrypt and wkd),
user ids can quickly become unnecessary metadata.

 - V

---

From: Leo Gaspard <[email-masked]>
Date: Mon, 28 May 2018 01:27:55 +0200

> It's also implemented and deployed as an experimental feature in OpenKeychain.

Hmm, this sounds like not solving the exact same issue: I was thinking
of a user asserting “I am [X] on service [Y]”, and (if I read correctly
your I-D) your proposal included having the OpenPGP implementation doing
the validation of this statement.

I think having the OpenPGP implementation doing the validation of such
statements is *really* hard to do. For instance, the section 4.4 of your
I-D doesn't explain how to do it, and I don't think it reasonably could
(you mention yourself that a proper VERIFY operation requires additional
insight on the specifics of each service).

This is the reason why I was only proposing a way to include in a User
ID “I am [this person]”, and then leave validation of this statement to
the same mechanism as the usual User IDs: I think this has a chance to
get in RFC4880bis, while having a more complex and
modifying-the-trust-model scheme could only live in a separate RFC,
especially when it potentially has implications on the privacy (as the
services would then know when I attempt to verify a User ID).

As for the validation of this User ID, with only my proposal, it could
be handled in the same way as email addresses: scoped trust for the
domain, that would be trusted to sign User IDs. Or scoped trust for
keybase.io (or any other equivalent service), that would be trusted to
validate the cookie online and sign the keys accordingly. Actually,
email is just a special case of an account on an online service, but I
think handling it separately makes sense, as eg. @github.com email
addresses won't be the same as @users.noreply.github.com ones.

That said, I do believe there is value in your proposal (eg. not relying
on a trusted third-party when the upstream service doesn't have a public
key that could be trusted), but I also think these two approaches are
complementary.

> user ids can quickly become unnecessary metadata.

With the changes I proposed, there would no longer be any User ID in v5
keys (the User ID subpacket would just be forbidden there, and likely
Primary User ID too).

There could be an arbitrary number of User Attributes, like now,
because, as you mentioned, it may make sense to not have any for eg.
TOFU use.

---

From: Jon Callas <[email-masked]>
Date: Sun, 27 May 2018 17:44:21 -0700

> On May 18, 2018, at 1:26 PM, Leo Gaspard <ietf=[email-masked]> wrote:
> 
> Hello,
> 

No problem. Since I wrote that text, I can provide some color. I think gentle persons can also disagree, so I'm not saying what I think is law, merely that I wrote it, and therefore I think I can give some indication of what the group consensus meant. Group consensus is often vague, wishy-washy, etc.

> * Subordinate CAs sign the verified OpenPGP keys

That's pretty much the intent. The idea is that you should be able to mark a key as being something like a CA.

Two important things to remember about OpenPGP philosophy are: (1) OpenPGP democratizes being a CA. All keys can sign, endorse, etc. and (2) Trust is also democratized in that trust is in the eye of the beholder. Also note that in many cases the beholder might be an organization. That organization might push its policy to its members, and be polite enough to scope that trust only to keys operating in that environment.

> logical follow-up of Web Key Directory.

I suppose. 

> calculated as trust(254, r".*<[email-masked]>" AND r".*<[email-masked]>").

Well, I think I disagree. I think that if I am trusting ca-a.com with scope at the root, subordinates cannot widen that scope. Scope is supposed to be narrowed only through subordinates. If that weren't true, then your subordinate that issues trust for example.org could just as easily issue it for ".*" and now all of a sudden the subordinate gets to sign everything, and that's the opposite of what scoping even means.

> CAs, that would interact nicely with WKD.

Yup, it's a little-used feature. So little used that I don't know of anyone using it, either.

> add some trust to this CA.

I believe that is pretty much the intended use case. The idea is that if I'm a member of an club (or company, etc.), then that club can bring in new members and I don't have to go to the trouble of trusting their keys, it happens for me.

In the naive trust model, I can say, "Whatever Alice signs is okay with me." This is obviously giving Alice a lot of power.

The trust-extension feature says, "Alice can deputize others to sign for her" and also permits those deputies to have deputies to some specified depth. This is obviously extending Alice's power in huge ways. Even with a level of only one, the only limit on Alice's power is that she has to deputize new deputies, but she has unbounded power to deputize.

The scoping feature is there so you can say, "Whatever Alice signs about our club is okay with me." It limits Alice's power. This is a reasonable and arguably important thing, especially if you're going to let Alice deputize people who can deputize people. It's so that the second assistant to the deputy undersecretary of the membership committee can't just go sign anything and I'll believe it.

> implementer, for opinionated implementations)

Sure! If there's anything OpenPGP needs it's more ease of use and work reduction.

> What do you think about this?

I am not sure what you're really proposing, though. I think you might be proposing the very thing I described, but I'm not sure.

If that's not what I described, then do me a favor and describe the problem you want solved.

	Jon

> 
> Cheers,
> Leo
> 
> _______________________________________________
> openpgp mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/openpgp

---

From: Jon Callas <[email-masked]>
Date: Sun, 27 May 2018 19:06:59 -0700

> On May 27, 2018, at 1:56 PM, Neal H. Walfield <[email-masked]> wrote:
> 
> 

[...[\]

> with "*." to indicate any subdomain).  

I believe you can do this.

A regexp that is "domain_1|domain_2" does this just fine.

> First, most users don't

My response is that that was not what the working group consensus was.

The working group consensus was that we didn't want to debate specifics, but regular expressions are sufficiently powerful to meet any reasonable (and probably lots of unreasonable) scoping.

I understand what you're saying, but I gotta reply, "So what?" I think I'm going to end up in a small rant in the following. I apologize in advance for any offense I might give in this small rant.

Let me shift the discussion to something slightly related. I have email accounts on a number of servers, and several of them allow me to do server-side filtering of my email. They provide a handy web page that lets me set up my own filtering rules. At the bottom of everything, all of these sites do filtering with Sieve. Sieve, like OpenPGP is an IETF standard, it is RFC 5228 and a lot more.

Each of the email servers I use has a slightly different web-GUI framework for specifying a rule. One of them, for example, is structured so that I have to enter "To" and "CC" on separate lines. Another one lets me specify "To" or "Any Recipient" (which means either To or CC). On another, I have to actually use the generic filter on some line and type in the CC if I want to filter on CC. In the actions phase of this, one of them automatically terminates after matching one other rule, while another one makes me put in an action line to stop processing following rules. But at the end of the day, they're all Sieve scripts.

(Oh, and one of them lets me upload my own Sieve script, but If I do that, I can no longer use the web GUI. Well, I can, but the GUI will likely overwrite all or part of the rules in ways that might totally break everything.)

There is *nothing* in OpenPGP that says you have to expose the full details of regular expressions to the user. Just like with Sieve, there's a full grammar that has expressive power that doesn't need to be used, and probably shouldn't be.

I agree completely that most users don't understand regexes. I agree that they shouldn't be subjected to them, and that the vast majority of what anyone needs is pretty much what you said — a list of domains. And yes, sensible software that does something nice for the user is not going to be able to ingest in an arbitrary regular expression and display it simply. Just like these server filtering web pages don't expose all the power of Sieve, a sensible program that lets people construct trust scope doesn't have to be just a text box that someone types a regexp into.

A protocol standard like OpenPGP specifies a grammar for messages. It's a way to encode a message so that other people can understand it as well as a way to interpret a message that someone else hands you.

In English, you can go up a staircase. You can also mount the staircase, ascend it, climb it, mount it, and even more. Grammar and vocabulary do not require you to put all the synonyms on the sign by the stairs. Up and Down are wonderful things to put on the sign. Ascend and Descend are a bit pretentious and non-native speakers might have trouble with them; thus they're compliant but have UX issues. The symbol ⬆ (that's the "Up Arrow" emoji in case it doesn't display properly) is not strictly standards-compliant, but if you're a fan of the Postel meta-rule, knock yourself out.  

Protocol standards are not specifications for software implementations nor are they requirements documents. GnuPG is a wonderful piece of software that tries very hard to be a reference implementation that implements every single feature. It is not a requirement that every implementation implement every feature. That's why we have the RFC 2119 keywords. You gotta do the MUSTs. It would be nice to do the SHOULDs. You don't have to do the MAYs. 

If you look at Section 5.2.3.1 of RFC 4880, it is perhaps more convoluted than it could be, but whatever. The gist of it is that since it says that an implementation SHOULD implement the preference subpackets as well as the Reason for Revocation, which at least implies that the others are all MAYs. It further says that you SHOULD ignore anything you don't "recognize" (which I interpret to be a synonym for "implement") and that if the critical bit it set, you SHOULD sit in the corner and sulk about anything you don't recognize.

Moreover, there's a regular expression helpfully defined in Section 8 that is a pretty bog-simple language, but like any regular expression matcher, you can create patterns that will drive weak people to strong drink. Nowhere are you *required* to let your user do things legal but silly. The reason it's there is to *permit* people to do complex things, not to expose the complexity to every user. It doesn't break the standard to implement a list of domains. It doesn't break the standard to let someone type in "*.example.com" for their scoping as opposed to ".*\.example\.com".

I believe that part of the reason so many people rail about the horrors of OpenPGP is that lots of us have the idea that OpenPGP is a software specification for GnuPG. That GnuPG is such a good piece of software is ironically part of the problem. It's as if every web browser revolved around the "curl" command. 

I agree with you completely about scoping up until you want to change the standard. The scoping is the way it is so that simple things are easy and complex things are possible. If we make it so that only simple things are possible it doesn't help anyone. (And as I said before, working group consensus was such that the bog-simple regular expressions were the way to go. 

Okay, thanks for reading this far.

	Jon

---

From: Leo Gaspard <[email-masked]>
Date: Mon, 28 May 2018 08:08:00 +0200

> I am not sure what you're really proposing, though. I think you might be proposing the very thing I described, but I'm not sure.

You're right, now that I understand that the RFC already meant what I
was trying to do, my message didn't make much sense.

> If that's not what I described, then do me a favor and describe the problem you want solved.
The problem I want solved is “no-one is using regular expressions and
thus implementations are likely non-existent or broken”. At first I
assumed it was because of what I thought was an issue of wording in the
RFC that would make it useless (hence my first post), but upon more
thought I think it is due to the following:

> The scoping feature is there so you can say, "Whatever Alice signs
> about our club is okay with me." It limits Alice's power.

I think the issue here is this “Whatever Alice signs about our club is
okay with me”. It can't really be encoded well in regular expressions: I
can not even say “Alice is only allowed to sign UIDs that end with
@myclub.example.org>”, because that would allow Alice to sign keys with
any name in it, and I would then implicitly trust Alice to have verified
the real-world identity of the key.

So upon more thought, I think the issue I'm feeling is there is better
described by my forked-from-this-thread “[openpgp] Overhauling User IDs
/ Standardizing User Attributes (was: Re: Scoped trust (signatures))”,
as with these changes it would become possible to scope the trust of
Alice to verify email addresses in @myclub.example.org and roles ending
with “at my club”, and even to scope the trust of a government's key to
sign any name whatsoever (as they already can issue any state-provided
ID thus make anyone fall for it at a keysigning party) but not any email
or role.

That said, it is a big change and I'm not sure it could gather enough
momentum to be accepted. But I think (hope?) that with such a
simplification in the way User IDs are handled (ie. without coupling of
unrelated parts of a user's identity), regex filtering (or by-domain
filtering) would become a tool adapted to the problem to solve, that is
delegating limited trust. This way, automated CA-like systems for
OpenPGP could appear without having issues with signing real names,
mailbox providers could sign their user's email addresses without having
to fear the risk that a user's real name is not the one on the User ID, etc.

Does what I'm saying make sense?
Anyway, thank you for this information on the background of this RFC!
Leo

---

From: Vincent Breitmoser <[email-masked]>
Date: Mon, 28 May 2018 09:06:00 +0200

> Each of the email servers I use has a slightly different web-GUI framework for
> specifying a rule. One of them, for example, is structured so that I have to
> enter "To" and "CC" on separate lines. Another one lets me specify "To" or
> "Any Recipient" (which means either To or CC). On another, I have to actually
> use the generic filter on some line and type in the CC if I want to filter on
> CC. In the actions phase of this, one of them automatically terminates after
> matching one other rule, while another one makes me put in an action line to
> stop processing following rules. But at the end of the day, they're all Sieve
> scripts.

I believe you've described the very problem with this approach here: A powerful
and flexible mechanism leads to many inconsistencies between implementations,
that's just unavoidable. For sieve scripts you might be fine with that, at worst
some messages will go in the wrong folder once in a while. But are you really
okay with same level of inconsistency in a trust model?

 - V

---

From: "Neal H. Walfield" <[email-masked]>
Date: Mon, 28 May 2018 10:42:22 +0200

On Mon, 28 May 2018 04:06:59 +0200,
Jon Callas wrote:
> Moreover, there's a regular expression helpfully defined in Section
> 8 that is a pretty bog-simple language

Implementing regular expression support might be bog-simple, but I
think it is still orders of magnitude more complicated than just a
list of domains.  And, I think, the general lack of support for this
feature is strong evidence that this is the case.

Thus, it seems to me, that making the complicated theoretically
possible has made the simple practically impossible.  That's
unfortunate.

Do you know of any examples where a list of domains is not sufficient?

Thanks!

:) Neal