{"id":893,"date":"2019-07-04T13:23:53","date_gmt":"2019-07-04T11:23:53","guid":{"rendered":"https:\/\/blogs.gentoo.org\/mgorny\/?p=893"},"modified":"2019-07-07T23:01:59","modified_gmt":"2019-07-07T21:01:59","slug":"sks-poisoning-keys-openpgp-org-hagrid-and-other-non-solutions","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/mgorny\/2019\/07\/04\/sks-poisoning-keys-openpgp-org-hagrid-and-other-non-solutions\/","title":{"rendered":"SKS poisoning, keys.openpgp.org \/ Hagrid and other non-solutions"},"content":{"rendered":"<p>The&nbsp;recent <a rel=\"external\" href=\"https:\/\/gist.github.com\/rjhansen\/67ab921ffb4084c865b3618d6955275f\">key poisoning attack on&nbsp;SKS keyservers<\/a> shook the&nbsp;world of&nbsp;OpenPGP.  While this isn&#8217;t a&nbsp;new problem, it has not been exploited on&nbsp;this scale before.  The&nbsp;attackers have proved how easy it is to poison commonly used keys on&nbsp;the&nbsp;keyservers and&nbsp;effectively render GnuPG unusably slow.  A&nbsp;renewed discussion on&nbsp;improving keyservers has started as&nbsp;a&nbsp;result.  It also forced Gentoo to&nbsp;employ countermeasures.  You can read more on them in&nbsp;the&nbsp;<a rel=\"external\" href=\"https:\/\/www.gentoo.org\/news\/2019\/07\/03\/sks-key-poisoning.html\">\u2018Impact of SKS keyserver poisoning on Gentoo\u2019 news item<\/a>.<\/p>\n<p>Coincidentally, the&nbsp;attack happened shortly after the&nbsp;launch of&nbsp;<a rel=\"external\" href=\"https:\/\/keys.openpgp.org\/about\">keys.openpgp.org<\/a>, that advertises itself as&nbsp;both poisoning-resistant and&nbsp;GDPR-friendly keyserver.  Naturally, many users see it as&nbsp;the&nbsp;ultimate solution to the&nbsp;issues with&nbsp;SKS.  I&#8217;m afraid I have to&nbsp;disagree \u2014 in&nbsp;my opinion, this keyserver does not solve any problems, it merely cripples OpenPGP in&nbsp;order to&nbsp;avoid being affected by&nbsp;them, and&nbsp;harms its security in&nbsp;the&nbsp;process.<\/p>\n<p>In&nbsp;this article, I&#8217;d like to&nbsp;shortly explain what the&nbsp;problem is, and&nbsp;which of&nbsp;the&nbsp;different solutions proposed so far to it (e.g. on&nbsp;<a rel=\"external\" href=\"https:\/\/lists.gnupg.org\/pipermail\/gnupg-users\/\">gnupg-users mailing list<\/a>) make sense, and&nbsp;which make things even worse.  Naturally, I will also cover the&nbsp;new Hagrid keyserver as&nbsp;one of&nbsp;the&nbsp;glorified non-solutions.<\/p>\n<p><!--more--><\/p>\n<h2>The&nbsp;attack \u2014 key poisoning<\/h2>\n<p>OpenPGP uses a&nbsp;distributed design \u2014 once the&nbsp;primary key is created, additional packets can be freely appended to it and&nbsp;recombined on&nbsp;different systems.  Those packets include subkeys, user identifiers and&nbsp;signatures.  Signatures are used to confirm the&nbsp;authenticity of&nbsp;appended packets.  The&nbsp;packets are only meaningful if&nbsp;the&nbsp;client can verify the&nbsp;authenticity of&nbsp;their respective signatures.<\/p>\n<p>The&nbsp;attack is carried through third-party signatures that normally are used by&nbsp;different people to&nbsp;confirm the&nbsp;authenticity of&nbsp;the&nbsp;key \u2014 that is, to&nbsp;state that the&nbsp;signer has verified the&nbsp;identity of&nbsp;the&nbsp;key owner.  It relies on&nbsp;three distinct properties of&nbsp;OpenPGP:<\/p>\n<ol>\n<li>The&nbsp;key can contain unlimited number of signatures.  After all, it is natural that very old keys will have a&nbsp;large number of signatures made by&nbsp;different people on&nbsp;them.<\/li>\n<li>Anyone can append signatures to any OpenPGP key.  This is partially keyserver policy, and&nbsp;partially the&nbsp;fact that SKS keyserver nodes are propagating keys one to&nbsp;another.<\/li>\n<li>There is no way to&nbsp;distinguish legitimate signatures from garbage.  To put it other way, it is trivial to&nbsp;make garbage signatures look like the&nbsp;real deal.<\/li>\n<\/ol>\n<p>The&nbsp;attacker abuses those properties by&nbsp;creating a&nbsp;large number of&nbsp;garbage signatures and&nbsp;sending them to&nbsp;keyservers.  When users fetch key updates from&nbsp;the&nbsp;keyserver, GnuPG normally appends all those signatures to the&nbsp;local copy.  As&nbsp;a&nbsp;result, the&nbsp;key becomes unusually large and&nbsp;causes severe performance issues with GnuPG, preventing its normal usage.  The&nbsp;user ends up having to manually remove the&nbsp;key in&nbsp;order to fix the&nbsp;installation.<\/p>\n<h2>The&nbsp;obvious non-solutions and&nbsp;potential solutions<\/h2>\n<p>Let&#8217;s start by analyzing the&nbsp;properties I&#8217;ve listed above.  After all, removing at&nbsp;least one of&nbsp;the&nbsp;requirements should prevent the&nbsp;attack from being possible.  But can we really do that?<\/p>\n<p>Firstly, we could set a&nbsp;hard limit on&nbsp;number of&nbsp;signatures or&nbsp;key size.  This should obviously prevent the&nbsp;attacker from breaking user systems via&nbsp;huge keys.  However, it will make it entirely possible for the&nbsp;attacker to&nbsp;\u2018brick\u2019 the&nbsp;key by&nbsp;appending garbage up to the&nbsp;limit.  Then it would no longer be&nbsp;possible to append any valid signatures to the&nbsp;key.  Users would suffer less but the&nbsp;key owner will lose the&nbsp;ability to&nbsp;use the&nbsp;key meaningfully.  It&#8217;s a&nbsp;no-go.<\/p>\n<p>Secondly, we could limit key updates to the&nbsp;owner.  However, the&nbsp;keyserver update protocol currently does not provide any standard way of&nbsp;verifying who the&nbsp;uploader is, so it would effectively require incompatible changes at&nbsp;least to the&nbsp;upload protocol.  Furthermore, in&nbsp;order to&nbsp;prevent malicious keyservers from propagating fake signatures we&#8217;d also need to carry the&nbsp;verification along when propagating key updates.  This effectively means an&nbsp;extension of&nbsp;the&nbsp;key format, and&nbsp;it has been proposed e.g. in&nbsp;<a rel=\"external\" href=\"https:\/\/tools.ietf.org\/html\/draft-dkg-openpgp-abuse-resistant-keystore-00\">\u2018Abuse-Resistant OpenPGP Keystores\u2019 draft<\/a>.  This is probably a&nbsp;wortwhile option but it will take time before it&#8217;s implemented.<\/p>\n<p>Thirdly, we could try to&nbsp;validate signatures.  However, any validation can be easily worked around.  If we started requiring signing keys to be&nbsp;present on&nbsp;the&nbsp;keyserver, the&nbsp;attackers can simply mass-upload keys used to&nbsp;create garbage signatures.  If we went even further and&nbsp;e.g.&nbsp;started requiring verified e-mail addresses for the&nbsp;signing keys, the&nbsp;attackers can simply mass-create e-mail addresses and&nbsp;verify them.  It might work as&nbsp;a&nbsp;temporary solution but it will probably cause more harm than good.<\/p>\n<p>There were other non-solutions suggested \u2014 most notably, blacklisting poisoned keys.  However, this is even worse.  It means that every victim of&nbsp;poisoning attack would be excluded from using the&nbsp;keyserver, and&nbsp;in&nbsp;my opinion it will only provoke the&nbsp;attackers to&nbsp;poison even more keys.  It may sound like a&nbsp;good interim solution preventing users from being hit but it is rather short-sighted.<\/p>\n<h2>keys.openpgp.org \/ Hagrid \u2014 a&nbsp;big non-solution<\/h2>\n<p>A&nbsp;common suggestion for&nbsp;OpenPGP users \u2014 one that even Gentoo news item mentions for lack of&nbsp;alternative \u2014 is to switch to&nbsp;<a rel=\"external\" href=\"https:\/\/keys.openpgp.org\/about\">keys.openpgp.org<\/a> keyserver, or&nbsp;switch keyservers to their <a rel=\"external\" href=\"https:\/\/gitlab.com\/hagrid-keyserver\/hagrid\">Hagrid<\/a> software.  It is not vulnerable to key poisoning attack because it strips away <em>all<\/em> third-party signatures.  However, this and&nbsp;other limitations make it a&nbsp;rather poor replacement, and&nbsp;in&nbsp;my opinion can be harmful to&nbsp;security of&nbsp;OpenPGP.<\/p>\n<p>Firstly, stripping all third-party signatures is not a&nbsp;solution.  It simply avoids the&nbsp;problem by&nbsp;killing a&nbsp;very important portion of&nbsp;OpenPGP protocol \u2014 the&nbsp;Web of&nbsp;Trust.  Without it, the&nbsp;keys obtained from the&nbsp;server can not be authenticated otherwise than by&nbsp;direct interaction between the&nbsp;individuals.  For example, <a rel=\"external\" href=\"https:\/\/wiki.gentoo.org\/wiki\/Project:Infrastructure\/Authority_Keys\">Gentoo Authority Keys<\/a> can&#8217;t work there.  Most of&nbsp;the&nbsp;time, you won&#8217;t be able to&nbsp;tell whether the&nbsp;key on&nbsp;keyserver is legitimate or&nbsp;forged.<\/p>\n<p>The&nbsp;e-mail verification makes it even worse, though not intentionally.  While I agree that many users do not understand or&nbsp;use WoT, Hagrid is implicitly going to&nbsp;cause users to start relying on&nbsp;e-mail verification as&nbsp;proof of&nbsp;key authenticity.  In&nbsp;other words, people are going to assume that if a&nbsp;key on&nbsp;keys.openpgp.org has verified e-mail address, it has to be&nbsp;legitimate.  This makes it trivial for an&nbsp;attacker that manages to&nbsp;gain unauthorized access to the&nbsp;e-mail address or&nbsp;the&nbsp;keyserver to&nbsp;publish a&nbsp;forged key and&nbsp;convince others to use it.<\/p>\n<p>Secondly, Hagrid does not support UID revocations.  This is an&nbsp;entirely absurd case where GDPR fear won over security.  If&nbsp;your e-mail address becomes compromised, you will not be able to&nbsp;revoke it.  Sure, the&nbsp;keyserver admins may eventually stop propagating it along with your key, but all users who fetched the&nbsp;key before will continue seeing it as&nbsp;a&nbsp;valid UID.  Of&nbsp;course, if&nbsp;users send encrypted mail the&nbsp;attacker won&#8217;t be able to&nbsp;read it.  However, the&nbsp;users can be trivially persuaded to&nbsp;switch to a&nbsp;new, forged key.<\/p>\n<p>Thirdly, Hagrid rejects all UIDs except for verified e-mail-based UIDs.  This is something we could live with if&nbsp;key owners actively pursue having their identities verified.  However, this also means you can&#8217;t publish a&nbsp;photo identity or&nbsp;use <a rel=\"external\" href=\"https:\/\/keybase.io\/\">keybase.io<\/a>.  The&nbsp;\u2018explicit consent\u2019 argument used by&nbsp;upstream is&nbsp;rather silly \u2014 apparently every UID requires separate consent, while at&nbsp;the&nbsp;same time you can trivially share somebody else&#8217;s <abbr title=\"Personally identifiable information\">PII<\/abbr> as&nbsp;the&nbsp;real name of&nbsp;a&nbsp;valid e-mail address.<\/p>\n<p>Apparently, upstream is willing to&nbsp;resolve the&nbsp;first two of&nbsp;those issues once satisfactory solutions are established.  However, this doesn&#8217;t mean that it&#8217;s fine to&nbsp;ignore those problems.  Until they are resolved, and&nbsp;necessary OpenPGP client updates are sufficiently widely deployed, I don&#8217;t believe Hagrid or&nbsp;its instance at&nbsp;keys.openpgp.org are good replacements for&nbsp;SKS and&nbsp;other keyservers.<\/p>\n<h2>So what are the&nbsp;solutions?<\/h2>\n<p>Sadly, I am not aware of&nbsp;any good global solution at&nbsp;the&nbsp;moment.  The&nbsp;best workaround for&nbsp;GnuPG users so far is the&nbsp;<a rel=\"external\" href=\"https:\/\/github.com\/gpg\/gnupg\/commit\/2e349bb6173789e0e9e42c32873d89c7bc36cea4\">new self-sigs-only option<\/a> that prevents it from importing third-party signatures.  Of course, it shares the&nbsp;first limitation of&nbsp;Hagrid keyserver.  The future versions of&nbsp;GnuPG will supposedly fallback to this option upon meeting excessively large keys.<\/p>\n<p>For&nbsp;domain-limited use cases such as&nbsp;Gentoo&#8217;s, running a&nbsp;local keyserver with restricted upload access is an&nbsp;option.  However, it requires users to&nbsp;explicitly specify our keyserver, and&nbsp;effectively end up having to&nbsp;specify multiple different keyservers for&nbsp;each domain.  Furthermore, <a rel=\"external\" title=\"Web Key Directory\" href=\"https:\/\/wiki.gnupg.org\/WKD\">WKD<\/a> can be&nbsp;used to&nbsp;distribute keys.  Sadly, at&nbsp;the&nbsp;moment GnuPG uses it only to&nbsp;locate new keys and&nbsp;does not support refreshing keys via WKD (<a rel=\"external\" href=\"https:\/\/github.com\/mgorny\/gemato\">gemato<\/a> employs a&nbsp;cheap hack to&nbsp;make it happen).  In&nbsp;both cases, the&nbsp;attack is&nbsp;prevented via&nbsp;isolating the&nbsp;infrastructure and&nbsp;preventing public upload access.<\/p>\n<p>The&nbsp;long-term solution probably lies in&nbsp;the&nbsp;\u2018First-party-attested Third-party Certifications\u2018 section of the&nbsp;<a rel=\"external\" href=\"https:\/\/tools.ietf.org\/html\/draft-dkg-openpgp-abuse-resistant-keystore-00\">\u2018Abuse-Resistant OpenPGP Keystores\u2019 draft<\/a>.  In&nbsp;this proposal, every third-party signature must be explicitly attested by the&nbsp;key owner.  Therefore, only the&nbsp;key owner can append additional signatures to&nbsp;the&nbsp;key, and&nbsp;keyservers can reject any signatures that were not attested.  However, this is not currently supported by&nbsp;GnuPG, and&nbsp;once it is, deploying it will most likely take significant time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The&nbsp;recent key poisoning attack on&nbsp;SKS keyservers shook the&nbsp;world of&nbsp;OpenPGP. While this isn&#8217;t a&nbsp;new problem, it has not been exploited on&nbsp;this scale before. The&nbsp;attackers have proved how easy it is to poison commonly used keys on&nbsp;the&nbsp;keyservers and&nbsp;effectively render GnuPG unusably slow. A&nbsp;renewed discussion on&nbsp;improving keyservers has started as&nbsp;a&nbsp;result. It also forced Gentoo to&nbsp;employ countermeasures. You can &hellip; <a href=\"https:\/\/blogs.gentoo.org\/mgorny\/2019\/07\/04\/sks-poisoning-keys-openpgp-org-hagrid-and-other-non-solutions\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;SKS poisoning, keys.openpgp.org \/ Hagrid and other non-solutions&#8221;<\/span><\/a><\/p>\n","protected":false},"author":137,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[10],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/893"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/users\/137"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/comments?post=893"}],"version-history":[{"count":50,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/893\/revisions"}],"predecessor-version":[{"id":944,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/893\/revisions\/944"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/media?parent=893"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/categories?post=893"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/tags?post=893"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}