<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC5246 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5246.xml">
<!ENTITY RFC5050 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5050.xml">
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2629 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2629.xml">
<!ENTITY RFC3552 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3552.xml">
<!ENTITY RFC3986 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3986.xml">
<!ENTITY RFC3986 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5234.xml">
<!ENTITY RFC3986 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4648.xml">
<!ENTITY RFC3986 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2045.xml">
<!ENTITY I-D.narten-iana-considerations-rfc2434bis SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.narten-iana-considerations-rfc2434bis.xml">
]>

<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>

<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<rfc category="exp" ipr="trust200902" submissionType="independent" docName="draft-farrell-kc-01">

<front>

<title abbrev="Public Key Checking Protocol">Public Key Checking Protocol</title>

<author fullname="Stephen Farrell" initials="S." 
surname="Farrell">
<organization>Trinity College Dublin</organization>
<address>
<postal>
<street></street>
<city>Dublin</city>
<region></region>
<code>2</code>
<country>Ireland</country>
</postal>
<phone>+353-1-896-2354</phone>
<email>stephen.farrell@cs.tcd.ie</email>
</address>
</author>

<date month="February" year="2012" />

<area>IETF</area>

<workgroup>Network Working Group</workgroup>

<keyword>public key checking</keyword>
<keyword>weak key generation</keyword>
<keyword>prng</keyword>

<abstract>

<t>Some asymmetric key generation implementations do not use sufficient
randomness giving rise to a number of bad public keys, for example with known
factors, being used on the Internet. This memo specifies [[for now: just
outlines]] an experimental protocol that could be used by a private key holder
to talk to a responder that knows the values of (some of) those bad keys that
have been seen in the wild. The protocol only allows a holder of the relevant
private key to request information, as doing otherwise could weaken the
overall security of the Internet and also considers confidentiality and
privacy as important requirements, as information that a given bad public key
is associated with a particular identifier could also weaken the security of
the Internet.</t>

</abstract>

</front>

<middle>

<section title="Introduction">

<t>[[Text in double square brackets (like this) is commentary.
So far this is just an outline. I'll do more if there's interest.
I'm also happy to get some help if someone wants to.]]</t> 

<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document
are to be interpreted as described in <xref target="RFC2119">RFC
2119</xref>.</t>

<t>
Recent publications <xref target="blog"/><xref target="lens"/>
have found yet again that some asymmetric
key generation implementations do not use sufficient randomness
giving rise to a number of bad public keys, estimated to be
of the order of 0.2% of tested keys, being used on the Internet.
Nonetheless, this small percentage maps to some tens of thousands
of bad keys. And the distribution of bad keys is likely to 
be concentrated on specific devices or devices used in 
specific ways, so that their Pesudo Random Number Generators
(PRNG) for one reason or another have not produced sufficient
randomness at key generation time.
</t>

<t>
The publications referred to above involved acquiring 
large (in millions) sets of keys and then analysing those
for example looking for common factors. While that is a
computationally expensive process, once done, it should
be much quicker to incrementally check if for example a single new
RSA public key has one of the already known common factors
or if any public key is an exact match for a known-bad key. Thus if a responder
were to store and analyse many public keys it could assist
key generators in knowing if they have inadvertently
produced a bad key. Note that such a responder cannot, 
(especially in real-time), determine that a public key
is good, but only whether the public key is known to
be bad.
</t>

<t>
The entire set of known-bad keys cannot however be 
made available to all, as some of those keys are in real use
and simply publishing their values could put Internet
users at risk. However, if we have a responder with the bad
keys and a protocol that only allows the relevant
private key holder to make requests then we may be able
to provide a useful service.
</t>

<t>
In addition to requiring that only private key holders
can query the responder, we must also ensure that 
eavesdroppers cannot tell whether the answer to the 
query is that the key is known to be bad or not known to be bad.
For example, response packet sizes could expose this
information.
</t>

<t>
Servers implementing this protocol are REQUIRED to store
the public keys presented to them for offline analysis.
(Though they may also acquire public keys for analysis
in many other ways.)
Thus, the answer that a requestor receives might change
from not-known-bad to known-bad
in a matter of minutes or hours. Some requestors could
take advantage of this and not actually use a key until
they have gotten not-known-bad answers for a 
configured period.
</t>

<t>
Note also that my public key may be good now but might
become known to be bad after someone else has posted e.g.
a public key with a common factor. In other words,
every private key holder could benefit from periodically
checking with a responder for this protocol.
</t>

<t>
While a responder may take hours to find new bad keys,
once a responder has a set of e.g. factors of RSA 
moduli, then it can easily check if a supplied 
public key has one of those as a factor, and this
is one of the bad-key patterns seen in the wild. This will
not detect all bad keys however, a process that
does reqiure more computation. Similarly,
if there are blacklists of bad keys (e.g. as happened
in the Debian case <xref target="deb"/>) then those can be 
spotted immediately. So the responder can 
in such cases give quick and accurate answers. Ultimately, the responder can do 
anything it wants for any algorithm - the specific
checks are not a part of this protocol.
</t>

<t>
While a responder here could lie and say that a key
is not-known-bad even if it is in fact known-bad,
using more than one responder could mitigate that
and reduce the level of trust required in the
responder's honesty.
Clients can also test any responder for this kind of
dishonesty 
by occasionally generating and sending bad keys to check if
the responder is honest. This is why we REQUIRE 
the responders to store and analyse the keys 
presented to it. [[Could be interesting games
to play here.]]
</t>

<t>
If a responder considers a public key to be known
bad, then the responder might know the corresponding
private key in which case it can produce a proof
that it know this, e.g by signing a hash of
the request message or otherwise. Note that
responders MUST ensure that the inclusion or 
omission of such proofs is done so as not to
expose the responder's opinion of the status of
the public key - in otherwords, keep all 
response messages the same length for a
given public key length.
</t>

<t>
Note also that this protocol does not tell
the requestor what to do with a known-bad 
public key. Presumably they'd stop using
it but the best action to take will depend
on the application using the public key
so is out of scope here.
</t>

<t>
This is an experimental specification for
at least two good reasons. Firstly, it is not yet
clear that it would be broadly adopted by
private key holders. Secondly, it is not clear
that responders with access to the data about
known-bad keys will make that information
available via this protocol, or at all.
If responders for this protocol with 
significant data sets appear on the Internet
and private key holders adopt this protocol
then the experiment will have been successful
and a future version of this could be 
considered for the IETF standards track.
</t>

</section>

<section title="Protocol Overview">

<t>
[[The protocol below requires the private
key be usable for signing. We could extend
it to e.g. D-H public values if we put
more structure into the ChalResp. Not sure
if that's worthwhile for now since the
overwhelming majority of keys will be
ok for signing.]]
</t>

<t>The abstract protocol is simple:</t>

<t><list style="symbols">

<t>ChalReq: the requestor sends a message asking for a challenge</t>

<t>ChalResp: the responder replies with a challenge</t>

<t>CheckReq: the requestor sends a signed query containing the public 
key and challenge</t>

<t>CheckResp: the responder replies saying the public key is known to 
be bad, or not known to be bad</t>

</list></t>

<t>In addition there is an ErrorMsg defined.</t>

<t>
This protocol MUST be run over a responder-authenticated
TLS <xref target="RFC5246"/> session using a 
TLS ciphersuite that provides strong confidentiality.
</t>

<t>
In order to ensure confidentiality even in the face
of traffic analysis, we ensure that all messages
containing the responder's result are the same size (for a given public key 
algorithm and size). This can involve the
responder sending random bits to the requestor, and
those MUST be of sufficient quality to be useful as
input to key generation.

</t>

<t>
For additional privacy, a requestor might choose to
run this protocol over some onion routing network such
as Tor. <xref target="tor"/> 
The protocol is designed to allow for
such use-cases. [[not sure yet how to do that though,
help appreciated]]
</t>

<t>
Note that the challenge has no strucure from the 
requestor perspective but might have for the 
responder. For example, a responder could 
include encrypted values in order to ensure
that the challenge is valid and or fresh. 
[[we might want to make that a MUST but its
probably only useful if done so I could 
test it from outside.]]
</t>

</section>

<section title="Message Formats">

	<t>
In this section we describe the messages used in 
this protocol. [[The concrete encoding is TBD. Maybe
JSON or just binary, dunno.]]
	</t>

<t>
[[Would it be worthwhile REQUIRING that all 
messages be randomly padded out to some 
particular length that's longer than all
real messages for the key length in 
question? Not sure.]]
</t>

<t>
All multi-octet values MUST be sent in network
byte order.
</t>

<section title="ChalReq Message">

	<t>
This message is sent from a requestor to a responder
asking for a fresh challenge.
	</t>

<figure anchor="reqmsg" title="ChalReq Message Format">
<artwork><![CDATA[

+--------------------+
| stuff
+--------------------+

]]></artwork>
</figure>

<t>This message has the following fields:</t>

<t>
<list style="symbols">
	
<t>Type:  0x01, 1-octet, meaning that this is a ChalReq</t>
<t>Flags: TBD, 4-octets </t>


</list>
</t>

</section>

<section title="ChalResp Message Format">

<t>This message is sent from a responder and contains a
fresh challenge.</t>

<t>
<list style="symbols">

<t>Type:  0x02, 1-octet, meaning that this is a ChalResp</t>
<t>Flags: TBD, 4-octets </t>
<t>ChalId: 4-octets, a value chosen by the responder to index the challenge</t>
<t>ChalLen: 4-octets, the length of the challenge in octets</t>
<t>Chal: NN octets, the octets of the challenge</t>

</list>
</t>

<t>
[[Maybe ChalId should be a transaction ID? figure out later.
With the ChalId you could do all this over DTLS/UDP maybe. 
Probably not worth it though.]]</t>

</section>


<section title="CheckReq Message Format">
<t>This message is sent from a requestor to a responder
and contains a public key, challenge and signature over
those.</t>
<t>
<list style="symbols">
<t>Type:  0x03, 1-octet, meaning that this is a CheckReq</t>
<t>Flags: TBD, 4-octets </t>
<t>ChalId: 4-octets, a value chosen by the responder to index the challenge</t>
<t>ChalLen: 4-octets, the length of the challenge in octets</t>
<t>Chal: NN octets, the octets of the challenge</t>
<t>PKAlg: public key algorithm identifier and format (details TBD)</t>
<t>PKLen: 4-octets, the length of the public key in octets</t>
<t>PK: NN octets, the octets of the public key</t>
<t>Sigalg: signature algorithm identifier and format (details TBD)</t>
<t>Siglen: 4-octets, the length of the signature in octets</t>
<t>Sig: NN octets, the octets of the signature</t>
</list>
</t>
</section>

<section title="CheckResp Message Format">
<t>This message is sent from a responder
to a requestor and contains the status of
the public key according to the responder.
.</t>

<t>
<list style="symbols">
<t>Type:  0x04, 1-octet, meaning that this is a CheckReq</t>
<t>Flags: TBD, 4-octets </t>
<t>ChalId: 4-octets, a value chosen by the responder to index the challenge</t>
<t>Status: 1-octet, an even numbered value means the key is 
not known to be bad; an odd numbered value means the key 
is known to be bad (says the responder!)
</t>
<t>ProofType: 2-octets, proof algorithm identifier and format (details TBD)</t>
<t>Prooflen: 4-octets, the length of the proof in octets</t>
<t>Proof: NN octets, the octets of the proof</t>
</list>
</t>


<t>In order to keep response to the same length, a 
ProofType value of zero (0) means that the Proof field
contains the relevant number of octets of
random values.</t>
</section>

<section title="Error Message Format">

<t>Error messages all have the following format.</t>

<t>
<list style="symbols">
<t>Type:  0x00, 1-octet, meaning that this is an ErrorMsg</t>
<t>Flags: TBD, 4-octets </t>
<t>ChalId: 4-octets, a value chosen by the responder to index the challenge or
zero if no relevant ChalId is known</t>
<t>ErrType: 2-octets, the specific error (values TBD)</t>
<t>Errlen: 4-octets, the length of the error string in octets</t>
<t>ErrorString: NN octets, the octets of the error string</t>
</list>
</t>

<t>[[There will be i18n silliness needed here, maybe.]]</t>

</section>

</section>

<section title="Cryptographic Operations">

<t>
In this section we define the signature operation
and define proof types.
</t>

<section title="Signature Operation">
<t>
The requestor has to sign some data for the CheckReq.
The input to the signature is the following values,
concatenated.
</t>

<t>
<list style="symbols">
<t>A fixed string "CHECKING A PUBLIC KEY" </t>
<t>Type:  0x03, 1-octet, meaning that this is a CheckReq</t>
<t>Flags: TBD, 4-octets </t>
<t>ChalId: 4-octets, a value chosen by the responder to index the challenge</t>
<t>ChalLen: 4-octets, the length of the challenge in octets</t>
<t>Chal: NN octets, the octets of the challenge</t>
<t>PKAlg: public key algorithm identifier and format (details TBD)</t>
<t>PKLen: 4-octets, the length of the public key in octets</t>
<t>PK: NN octets, the octets of the public key</t>
<t>Sigalg: signature algorithm identifier and format (details TBD)</t>
<t>Siglen: 4-octets, the length of the signature in octets</t>
</list>
</t>

<t>This is essentially the fixed string (to prevent cross-protocol
attacks) followed by the CheckReq message minus the Sig field
but including the length.</t>

</section>

<section title="Basic Proof Types">

<t>
We define two types of proof here, a signature scheme (ProofType 1) and a
random scheme (ProofType 0) to be used when the public key is not known to be
bad.
</t>

<t>
For ProofType 0, the responder just includes
the same number of random octets as it 
would have used for ProofType 1 had the status 
been known-bad. As with the challenge value
those random octets MUST be good enough to
use as a PRNG seed.
</t>

<t>
Note that a responder can use ProofType 0 even
if it says that the public key is known-bad.
Not all kinds of badness result in the responder
being able to demonstrate that it knows the
private key.
</t>

<t>
ProofType 1 involves the responder signing a
sha-256 hash of the CheckReq message with the
private key corresponding to the public key
submitted in the CheckReq. This 
signature demonstrates to the private key
holder that their key is toast.
</t>

<t>[[At some stage think about this some
more to see what's best to use as proof.]]</t>

</section>

</section>


<section title="Sample Challenge Method">
<t>
Regardless of the scheme used to generate the challenge, 
a responder's challenge MUST be a good random value,
suitable for a requestor to use as an additional
seed for a PRNG and the challenge MUST be at least
256 bits long. 
</t>
<t>
A fresh challenge value MUST be used for all 
transactions. Attempts to re-use a challenge
MUST result in an error (BadChal).
[[Not sure this is needed but
we should say something and this is the
easiest to say, if not to implement;-)]]
</t>
<t>
If the responder wishes to remain stateless then 
it can emit challenge values that are a
symmetically encrypted form (with integrity!) of the current
responder time and/or a sequence number of some
sort. This would allow the responder to 
detect attempts to use stale challenges.
</t>
</section>

<section title="Responder Actions">

<t>Responders need to ensure that simple timing attacks 
are not possible. The processing of CheckReq messages MUST 
take the same amount of time regardless of errors, known-bad 
status and of the ProofType used in the 
corresponding CheckResp.</t> 

<t>For clarity: the time between receipt
of a CheckReq and emission of a CheckResp or ErrroMsg
corresponding to that CheckReq MUST be a constant
for any given public key algorithm and key size.</t>

<t>When a responder recevives a message that
does not decode properly it SHOULD return an
ErrorMsg with an ErrType value of BadMessage (1).
An example where an ErrorMsg might not be 
returned would be if the responder considered
itself as being under a Denial-of-Service (DoS)
attack.
</t>

<t>When a responder receives a ChalReq message,
it MUST generate a fresh ChalRep message.</t>

<t>When a responder receives a CheckReq message
it MUST do all of the following:</t>

<t>
<list style="numbers">

<t>Verify that the ChecReq challenge value meets whatever are the server's
criteria. If it does not then the responder MUST return an ErrorMsg with ErrType BadChal (2).</t>

<t>Verify that the public key from the message verifies the signature
from the message. If the signture check fails then the responder
SHOULD an ErrorMsg with ErrType BadSig (3). The responder might not 
send an ErrorMsg if it considered that some attack was under way,
e.g. if many bad signatures were received for the same public key.</t>

<t>Store the public key for later analysis. The responder MUST NOT
store any other information about the requestor, for example, its IP
address.</t>

<t>Determine whether to answer that the key is known-bad or not-known-bad
based on whatever local criteria are used.</t>

<t>Construct a corresponding CheckResp message and return that to
the requestor.</t>

</list>
</t>

</section>

<section title="Requestor Actions">

<t>[[Still TBD, but fairly obvious]]</t>

</section>

<section title="Mandatory-to-Implement Things">

<t>
[[You MUST be able to do RSA, prooftypes 0 (random bits) and 1
(signature), signatures MUST use rsa-sha256 with OAEP
or pkcs1v1.5 maybe. What else?]]
</t>

</section>

<section title="Transport Considerations">

<t>[[Maybe just right over TLS over TCP, maybe via HTTP, 
with a .well-known URL, dunno.]]</t>

</section>

<section title="Security Considerations">

<t>[[You'd have to imagine there are:-)]]</t>

</section>

<section title="IANA Considerations">

<t>[[None yet, there will be a bunch with registries for 
many of the fields in the messages defined above.]]</t>

</section>


<section title="Acknowledgements">

<t>Steve Bellovin proposed the main idea here independently
<xref target="bell"/>, I only saw that after the -00 was
out.</t>

<t>Thanks for Paul Hoffman for some off-list discussions
that didn't quite convince him this is worth some effort;-)</t>

</section>

<section title="Changes">

<t>This section describes the various versions of 
this draft and is to be removed later when/if this
becomes an RFC.</t>


<t>-00: just a sketch of the protocol</t>

<t>-01: sketch -> fairly detailed outline</t>

</section>
</middle>
  
<back>
<references title="Normative References">

&RFC2119;
&RFC5246;

</references>

<references title="Informative References">

<reference anchor="lens" target="http://eprint.iacr.org/2012/064">
	<front>
	<title>Ron was wrong, Whit is right</title>
	<author surname="Lenstra" initials="A" fullname="Arjen K. Lenstra"/> 
	<author surname="Hughes" initials="J" fullname="James P. Hughes"/> 
	<author surname="Augier" initials="M" fullname="Maxime Augier"/> 
	<author surname="Bos" initials="J" fullname="Joppe W. Bos"/> 
	<author surname="Kleinjung" initials="T" fullname="Thorsten Kleinjung"/> 
	<author surname="Wachter" initials="C" fullname="Christophe Wachter"/>
	<date month="February" year="2012"/>
	</front>
	<seriesInfo name="Cryptology ePrint Archive" value="Report 2012/064"/>
</reference>

<reference anchor="blog"
	target="https://freedom-to-tinker.com/blog/nadiah/new-research-theres-no-need-panic-over-factorable-keys-just-mind-your-ps-and-qs">
	<front>
	<title>New research: There's no need to panic over factorable keys--just mind your Ps and Qs</title>
	<author surname="Heniger" initials="N" fullname="Nadia Heniger"/>
	<date month="February" year="2012"/>
	</front>
</reference>

<reference anchor="tor" target="http://www.torproject.org/">
	<front>
	<title>The Tor Project</title>
	<author/>
	<date/>
	</front>

</reference>

<reference anchor="deb" target="http://www.debian.org/security/2008/dsa-1571">
	<front>
	<title>Debian Security Advisory, DSA-1571-1: openssl -- predictable random number generator</title>
	<author/>
	<date month="May" year="2008"/>
	</front>

</reference>

<reference anchor="bell" target="http://lists.randombit.net/pipermail/cryptography/2012-February/002310.html">
	<front>
	<title>Duplicate primes in lots of RSA moduli</title>
	<author surname="Bellovin" initials="S"/>
	<date month="February" year="2012"/>
	</front>
</reference>


</references>

</back>
</rfc>

