Subject: [websec] Review of draft-evans-palmer-hsts-pinning-00

From: =JeffH <[email-masked]>
Date: Fri, 14 Oct 2011 15:04:56 -0700

Here's my detailed review of 
https://tools.ietf.org/html/draft-evans-palmer-hsts-pinning-00  ( note that the 
latter rev in the repository is different/fresher than the -00 rev that'd been 
sent only to the mailing list the prior day )

Many thanks to ChrisP & ChrisE for writing this up, I think this is something 
the WebSec WG should further consider.

This I-D is a really good start, although there's some fundamental design 
decisions to make, and it needs a fair bit of work to turn it into a polished 
spec. Below, I've listed my substantive comments with pointers down into the 
spec text.  I interspersed editorial comments throughout the spec text.

Hope this is helpful,

=JeffH
------

substantive comments:

0. overall name -- what's pinned in this approach is public keys rather than 
certs (for specific reasons), so perhaps the mechanism should be called "public 
key pinning" rather than "certificate pinning". But in any case, the subtle 
distinction that the public key in certs is what is pinned, rather than the 
cert as a whole, should be clarified throughout, perhaps by using a term like 
"key/cert" rather than just "cert" in various places.

0.1. need to further tease appart security considerations and 
deployment/operational considerations. This is mentioned in various places below.

1. the "digest uri" I-D and thread(s) on [email-masked] are attempting to come 
up with a more general purpose means to reference something while suppling its 
hash as a part of the reference, with the aim being to have such an approach be 
used for things such as this pinning effort.  see [1] below. probably ought to 
chime in on review of of those I-Ds from perspective of their suitability for 
this use case.

2. see [2] below -- wrt specifying the hash of the SubjectPublicKeyInfo

3. issues with breakv and breakc directive approach.  See [3] below (multiple 
occurrences). This is something to explore in a specific separate email thread.

4. need to at least reference -websec-strict-transport-sec wrt details on 
domain name matching and noting a Pinned HSTS Host, and may need to 
appropriately "profile" it. See [4] below.

5. pin check machinery is up at the HTTP layer rather than down lower in or 
near the TLS layer ?  See [5] below.

6. need a prose description of behavior, can use pseudo code as an example. See 
[6] below.

7. UA and server implementation features/optimizations that aren't a part of 
the protocol proper, e.g. section 2.2, should be placed in separate sections 
identified as such. See [7] below.

8. "current accepted practice" wrt TLS cert chain validation is not modified or 
obviated by this mechanism -- this is implicit in the spec but should be made 
explicit. See [8] below.

9. should tease apart the normative statements and "deployment considerations" 
  aspects from "sec considerations" stuff in the present Section 3 "Risks of 
Pinning, and Mitigations". See [9] below.

10. need more fully described "deploying a backup pin" and it should be more 
accurately named, e.g. "deploying backup server cert and pin". See [10] below.

11. should perhaps have an explicit "scope" section with explicit declaration 
of things that are "in scope" and "out of scope". see [10] below (multiple 
occurrences).

12. The question of whether this "key/cert pinning" should be designed as an 
extension to the HSTS mechanism, or accomplished via its own header, is a good 
question and something to explore in a specific separate email thread. See [12] 
below.

13. The spec doesn't explicitly state that the response header MUST be received 
over error-free TLS connection in order to be "noted". Probably should be 
mentioned even when cast as HSTS extension, but must be mentioned if pins are 
conveyed in their own separate header field.

-----

 > Web Security                                                    C. Evans
 > Internet-Draft                                                 C. Palmer
 > Expires: March 24, 2012                                     Google, Inc.
 >                                                       September 21, 2011
 >
 >
 >                  Certificate Pinning Extension for HSTS
 >                    draft-evans-palmer-hsts-pinning-00
 >
 > Abstract
 >
 >    This memo describes an extension to the HTTP Strict Transport
 >    Security specification allowing web host operators to instruct UAs to

s/UAs/user agents/

suggest introducing the UA acronym down in spec proper.

 >    remember ("pin") hosts' cryptographic identities for a given period
 >    of time.  During that time, UAs will require that the host present a
 >    certificate chain including at least one public key whose fingerprint
 >    matches one or more of the pinned fingerprints for that host.  By
 >    effectively reducing the scope of authorities who can authenticate
 >    the domain during the lifetime of the pin, we hope pinning reduces
 >    the incidence of man-in-the-middle attacks due to compromised
 >    Certification Authorities and other authentication errors and
 >    attacks.
 >
 > Status of this Memo
 >
<snippage/>
 >
 >
 > 1.  Introduction
 >
 >    We propose to extend the HSTS HTTP header to enable a web host to
 >    express to UAs which certificate(s) UAs may expect to be present in
 >    the host's certificate chain in future connections.  We call this
 >    "certificate pinning".

[0] But the pins are to the public keys in the certs, and expressly so (as you 
mention elsewhere below) because sometimes a certificate will change but the 
embedded public key will not.

So perhaps this mechanism should be named "public key pinning" ?

 >                             The Google Chrome/ium browser ships with a
 >    static set of pins, and individual users can extend the set of pins.

perhaps more generically restate:

"At least one user agent has experimented with shipping with a user-extensible 
embeded set of pins (e.g. Google Chrome)."

 >    Although effective, this does not scale.  This proposal addresses the
 >    scale problem.

but not the bootstrap MITM problem when the initial pin is conveyed over protocol.

 >
 >    Deploying certificate pinning safely will require operational and
 >    organizational maturity due to the risk that HSTS Hosts may "brick"

should use terms other than those based on "brick" (a colloquialism) -- suggest 
"render themselves unavailable" or "are rendered unavailable" depending upon 
enclosing sentence grammar.

 >    themselves by pinning to a certificate that becomes invalid.  We
 >    discuss potential mitigations for those risks.  We believe that, with
 >    care, host operators can greatly reduce the risk of MITM attacks and
 >    other false-authentication problems for their users without incurring
 >    undue risk.
 >
 >    This document extends the version of HSTS defined in [hsts-spec] and
 >    follows that document's notational and naming conventions.
 >
 >    This draft is being discussed on the WebSec Working Group mailing
 >    list, [email-masked].
 >
 > 1.1.  About Notation
 >
 >    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 RFC 2119.
                                                     ^^^^^^^^^
did you use <xref target="rfc-2119"/> here?

 >
 >    This document includes some pseudocode examples written in a Python-
 >    like language, to clarify UA behavior.  The examples assume that a
 >    global data structure, hsts_metadata, exists and contains the HSTS
 >    metadata that the UA has accumulated over time.  It is indexable by
 >    domain name and includes the usual HSTS parameters (maxAge,

s/maxAge/max-age/g

 >    includesSubDomains) as well as the new HSTS parameter, pins, that
 >    this document introduces.  It also assumes a hypothetical X.509
 >    datatype, denoted with a variable named "certificate", that includes
 >    likely X.509 fields such as public_key (which would correspond to the
 >    SubjectPublicKeyInfo field in a real X.509 certificate).

pseudocode should be marked as non-normative and there should be a sufficiently 
rich prose description, in the present section 2,  such that pseudo code isn't 
strictly necessary, incorporating the material from the para above.

 >
 >    There are also some working code examples using the Python and Go
 >    languages.
 >
 >    The examples are intended to be illustrative, not necessarily precise
 >    or using algorithms that a real, optimized UA would employ.

these are good to point out, but I don't know if I'd term it "notation".

 > 2.  Server and Client Behavior

I suggest having separate sections for an overview of the pinning mechanism's 
semantics and effects, the syntax, and then the server processing model, and 
the user agent processing model.

 >
 >    To set a pin, HSTS Hosts use a new STS extension directive (STS-d-
 >    ext) in their HSTS response header field: pins.  To enable pin
 >    revocation (Section 2.3), hosts may also use the new breakv and
 >    breakc directives.
 >
 >    STS-d-ext-pin    =    "pins" OWS "=" OWS [fingerprints]
 >    STS-d-ext-breakv =    "breakv" OWS "=" OWS fp-type "/" base64-digits
 >    STS-d-ext-breakc =    "breakc" OWS "=" OWS base64-digits
 >
 >    fingerprints     =     fingerprint
 >                           / fingerprint "," fingerprints
 >
 >    fingerprint      =     fp-type "/" base64-digits
 >
 >    fp-type          =     "sha1"
 >                           / "sha256"
 >
 >                                  Figure 1

using "/" as a separator ?   Base64 includes "/" in its encoding -- perhaps use 
another char for a separator such as ";" ?

[1] see substantive comment (1) above wrt such fingerprint references and 
"digest uri" et al.

note: STS-d-ext needs to be fixed in HTTPS spec to be a "value" so can have "=" 
in it, but that won't be a big deal if we do this pinning with a separate 
header field.

need to reference RFC4648 for base64.

I would put the examples in their own subsection...

 >    Here is an example response header field using the pins extension
 >    (folded for clarity):
 >
 >    Strict-Transport-Security: max-age=500; includeSubDomains;
 >        pins=sha1/4n972HfV354KP560yw4uqe/baXc=,
 >        sha1/IvGeLsbqzPxdI0b0wuj2xVTdXgc=
 >
 >                                  Figure 2
 >
 >    Here is an example response header field using both the pins and the
 >    breakv extensions (folded for clarity):
 >
 >    Strict-Transport-Security: max-age=500; includeSubDomains;
 >        pins=sha1/4n972HfV354KP560yw4uqe/baXc=,
 >        sha1/IvGeLsbqzPxdI0b0wuj2xVTdXgc=;
 >        breakv=sha1/jUQEXH7Q2Ly+Xn/yFWJxAHT3fDc=
 >
 >                                  Figure 3
 >
 >    The fingerprint is the SHA-1 (or SHA-256) hash of the raw
 >    SubjectPublicKeyInfo field of the certificate,

[2] above sentence needs to specify that it is the SubjectPublicKeyInfo (SPKI) 
from the ASN.1 DER-encoded cert representation that's hashed. Does the hash 
input include the DER tag and length for  SubjectPublicKeyInfo itself, or just 
hash the DER value of SubjectPublicKeyInfo ?  The latter is apparently the 
practice when crafting a  keyIdentifier by hashing the subjectPublicKey (RFC5280)

the Go program in Figure 6 (Appendix A) doesn't include the code for 
cert.RawSubjectPublicKeyInfo so one can't tell what actual portions of the 
SubjectPublicKeyInfo sequence are getting hashed and used to generate cert key 
fingerprints (ie are the SPKI's tag and length included in the hash?).

probably should include the SubjectPublicKeyInfo definition here in this spec 
to provide context:

SubjectPublicKeyInfo  ::=  SEQUENCE  {
      algorithm            AlgorithmIdentifier,
      subjectPublicKey     BIT STRING  }

AlgorithmIdentifier  ::=  SEQUENCE  {
      algorithm               OBJECT IDENTIFIER,
      parameters              ANY DEFINED BY algorithm OPTIONAL  }
                                 -- contains a value of the type
                                 -- registered for use with the
                                 -- algorithm object identifier value

 >                                                   encoded in base-64 for
 >    brevity.  We pin public keys, rather than entire certificates, to
 >    enable operators to generate new certificates containing old public
 >    keys (see [why-fingerprint-key]).  (Although host operators may do
 >    this, certification authorities already do.  Additionally, when UAs
 >    check certificate chains, they do so by checking that each
 >    certificate is signed by its parent's public key, making the public
 >    key -- not the certificate -- the essential identifier.)

perhaps the above para should be up above in a overall exposition section.

 >
 >    See Appendix A for an example program that generates public key
 >    fingerprints from SubjectPublicKeyInfo fields in certificates.

see comment above wrt this example program.

 >
 >    The breakv directive communicates to UAs a pin break verifier, and
 >    the breakc directive communicates the pin break code.  Hosts SHOULD
 >    generate pin break codes and verifiers.  When present, UAs MUST note
 >    pin break verifiers and honor pin break codes.  See Section 2.3 for a
 >    discussion of verifiers and codes.

[3] will comment on breakv and  breakc directive approach in separate message.

 > 2.1.  Noting and Validating Pins

Noting a Known Pinned HSTS Host, and checking (nee validating) host pins should 
be separate subsections.  If pinning becomes a separate stand-alone policy, 
then perhaps an appropriate term will be "Pinned Host".

 >    Upon receipt of this header field, the UA will note the HSTS Host as
 >    a Known Pinned HSTS Host.

should have an explicit terminology section (above) and define Known Pinned 
HSTS Host.

[4] probably need to reference I-D.ietf-websec-strict-transport-sec ( <xref 
target="I-D.ietf-websec-strict-transport-sec"/> ) for the details wrt domain 
name matching and noting a Pinned HSTS Host.

 >    When connecting to a Known Pinned HSTS
 >    Host, the UA will compare the public key fingerprint(s) in the Host's
 >    certificate chain to the pinned fingerprints, and will fail closed

s/fail closed/terminate the TLS connection/

 >    unless at least one public key in the chain has a fingerprint
 >    matching one of the pinned fingerprints.

s/matching one/matching one of the set/

 >                                               (Following the HSTS
 >    specification, TLS errors for HSTS hosts must be hard, with no chance
 >    for the user to click through any warnings or errors.  We treat
 >    fingerprint mismatch in the same way.)

so in the HSTS spec, we've moved the "no user recourse" stipulation to "user 
agent advice", which is non-normative, because it's a protocol spec.

 >    Note that to validate pins, UAs must necessarily read the headers of
 >    a response.

[5] response = HTTP response?

This implies that the pin check machinery is up at the HTTP layer rather than 
down lower in or near the TLS layer, which implies that the UA can make normal 
HTTP requests to a bogus Known Pinned Host, and send cookies, before realizing 
that the pin check has failed.

This is a fundamental security issue.

 >                 In case of mismatch, UAs SHOULD NOT read the response
 >    body as part of failing hard.

So this is assuming that the pin check is inserted in the HTTP protocol 
machinery at the point of having read the HTTP header fields, but before 
processing the body, and making the body processing contingent on the outcome 
of the pin check (if the host is a Known Pinned Host).

 >    This pseudocode illustrates how UAs validate the certificate chains
 >    they receive from Known Pinned HSTS Hosts.
 >
 >    def chain_is_pinned_valid(chain, pins):
 >        for certificate in chain:
 >            for fingerprint in pins:
 >                if certificate.public_key.fingerprint == fingerprint:
 >                    return True
 >
 >        return False
 >
 >    # ...
 >    if not chain_is_pinned_valid(request.tls_info.certificate_chain,
 >                                 hsts_metadata[request.hostname].pins):
 >        request.fail()
 >    # ...
 >
 >                                  Figure 4

[6] a prose description of the behavior described by the above pseudocode is 
needed.

 >    The pin list appearing in an HSTS header MUST have at least one pin
 >    matching one of the public key fingerprints in the chain that was
 >    validated for the HTTPS connection.

having this stipulation of "have _at least one_ pin matching one cert in cert 
chain from TLS handshake" is a critical nuance: it gives the web app provider 
(nee host operator) flexibility in terms of which key/cert(s) they pin to, e.g. 
end host key, intermediate keys, CA root keys.

  thus security consideration ramifications, and which should be more fully 
discussed in operational/deployment considerations.

 >                                         This defends against HTTP header
 >    injection attacks (see Section 3.4.1).

it defends against other stuff too, eg TLS MITM via fraudulent cert, depending 
on which cert(s) in the cert chain one is pinned to. In any case, probably 
should not mention "defends against" stuff here, rather put it in security 
considerations (and perhaps mention in overview material)

 >
 >    UAs MUST cache pins and pin break verifiers for Known Pinned HSTS
 >    Hosts, and MIGHT AS WELL do so in the same manner as other HSTS
 >    metadata.

aboves needs to be more rigorous and precise.

"MIGHT AS WELL" not recognized as proper spec language :)

 >    If the maxAge directive is present in the HSTS response
 >    header, the HSTS metadata -- including fingerprints in the pins
 >    directive -- expire at that time.

expiration time language not rigorous/precise enough.  see 
-websec-strict-transport-sec Section 7.

 >
 > 2.2.  Interactions With Built-in HSTS Lists
 >
 >    UAs MAY choose to implement built-in certificate pins, alongside any
 >    built-in HSTS opt-in list.  UAs MUST allow users to override a
 >    built-in pin list, including turning it off.

[7] this section should be a part of non-normative UA advice

 >
 >    Hosts can update built-in pin lists by using this extension.

does this capture what you're trying to say:

"Hosts can update UAs' built-in pin lists through the HSTS-basesd pin mechanism"  ?

if so should perhaps add some modest details wrt how that be accomplished.

 >    Similarly, UAs can update their built-in pin lists with software
 >    updates.

the above is trying to say that UA software updates could convey new built-in 
pin lists ?

 >              In either case, UAs MUST use the newest information --
 >    built-in or set via HSTS -- when validating certificate chains for
 >    the host.

This overall requirement should probably go somewhere above in a normative 
portion of Section 2.x.

 > 2.3.  Un-pinning

[3] this section is about server-driven explicit unpinning, rather than, say, 
unpinning occuring due to cert expiration, yes?  should more clearly explain 
(if this approach remains).

will comment on breakv & breakc approach in separate message.

 >
 >    Hosts can enable pin revocation for their previously-pinned key
 >    fingerprints by setting pin break verifiers using the breakv
 >    directive.  Then, when hosts want to break pins, they set the pin
 >    break code in their HSTS headers using the breakc directive.  (This
 >    idea is due to Perrin in [pin-break-codes].)
 >
 >    Pin break codes are short random strings, kept secret until the host
 >    operator wants to break the pins.  Pin break verifiers are simply
 >    hashes of the codes.  Generating codes and verifiers, and verifying
 >    that codes match a previously set verifier, is trivial.  See
 >    Figure 5.
 >
 >    def make_pin_break():
 >        code = os.urandom(16)
 >        verifier = hashlib.sha1(code).digest()
 >        return base64.b64encode(code), base64.b64encode(verifier)
 >
 >    def verify_code(code, verifier):
 >        c = base64.b64decode(code)
 >        v = hashlib.sha1(c).digest()
 >        return verifier == base64.b64encode(v)
 >
 >
 >    if __name__ == "__main__":
 >        import sys
 >
 >        if 1 == len(sys.argv):
 >            print make_pin_break()
 >        elif 3 == len(sys.argv):
 >            print verify_code(sys.argv[1], sys.argv[2])
 >
 >                                  Figure 5
 >
 >    Hosts can request that UAs forget pinned fingerprints by issuing a
 >    valid HSTS header containing the pin break code.  UAs MUST forget all
 >    pinned fingerprints associated with the matching pin break verifier,
 >    and MUST NOT forget any pinned fingerprints not associated with that
 >    verifier.
 >
 >    In the event that a host sends an HSTS header containing a breakc

do you mean a Known Pinned Host on a connection that has passed a pin check?

 >    that does not match a breakv the UA has previously noted, the UA MUST
 >    ignore that breakc and MUST process any pins or breakv directives as
 >    normal.  This is so that hosts can break old pins but still
 >    successfully set new pins and verifiers in UAs that have not
 >    previously (or recently) noted the host.
 >
 >    Host operators SHOULD keep the pin break code secret, and SHOULD
 >    generate codes that are computationally infeasible to guess (such as
 >    by using their system's cryptographic random number generator; note
 >    that a 128-bit security level suffices).
 >
 > 2.4.  Pinning Self-Signed Leaf Certificates
 >
 >    To the extent that UAs allow or enable hosts to authenticate
 >    themselves with self-signed end entity certificates, they MAY also
 >    allow hosts to pin the public keys in such certificates.  The
 >    usability and security implications of this practice are outside the
 >    scope of this specification.

[8] This (S 2.4) is an important nuance, as is the presently implicit 
requirement that UAs continue to perform "current accepted practice" cert chain 
validation. An explicit normative statement of the latter should be made 
somewhere in S 2, plus the self-signed stuff here in S 2.4 probably should be 
in another section, not sure exactly where right now, and deserves appropriate 
mention in Sec Considerations.

 > 3.  Security Considerations

[9] this section is overall intended to be operational/deployment 
considerations, yes?  it'd been entitled "Risks of Pinning, and Mitigations" 
until this rev of the spec.

Thus the operational/deployment considerations below should be teased apart 
from the proper sec cons stuff and placed appropriately in separate sections. 
There's also at least one normative stipulation below that needs to be in the 
appropriate normative section above.

a brief intro sentence or two here would be good.

 >
 > 3.1.  Deployment Guidance
 >
 >    To recover from disasters of various types, as described below, we
 >    recommend that HSTS Hosts follow these guidelines.

the below items should probably be numbered subsections so they can be 
individually referenced.

 >
 >    o  Operators SHOULD have a safety net: they should generate a backup
 >       key pair, get it signed by a different (root and/or intermediary)
 >       CA than their live certificate(s), store it safely offline, and
 >       set this backup pin in their pins directive.

By "Set this backup pin"  are you trying to say "set a pin to your backup 
key/cert" ?

 >       *  Having a backup certificate was always a good idea anyway.
 >
 >    o  It is most economical to have the backup certificate signed by a
 >       completely different signature chain than the live certificate, to
 >       maximize recoverability in the event of either root or
 >       intermediary signer compromise.
 >
 >    o  Operators SHOULD periodically exercise their backup pin plan -- an
 >       untested backup is no backup at all.
 >
 >    o  Operators SHOULD have a diverse certificate portfolio.  They
 >       should pin to a few different roots, owned by different companies
 >       if possible.
 >
 >    o  Operators SHOULD start small.  Operators SHOULD first deploy HSTS
 >       certificate pinning by setting a maxAge of minutes or a few hours,
 >       and gradually increase maxAge as they gain confidence in their
 >       operational capability.

s/maxAge/max-age/g

Perhaps we should find a different term instead of "disaster" ?

should include the below from 
<http://www.imperialviolet.org/2011/05/04/pinning.html>:
                            ...you mustn't pin to a cross-certifying
root. For example, GoDaddy's root is signed by Valicert so that older
clients, which don't recognise GoDaddy as a root, still trust those
certificates. However, you wouldn't want to pin to Valicert because
newer clients will stop their chain at GoDaddy.

 >
 > 3.2.  Disasters Relating to Compromises of Certificates

compromises of keys ?

 >
 > 3.2.1.  The private key for the pinned leaf is stolen
 >
 >    If a leaf certificate is compromised, the host is likely to have
 >    experienced a complete compromise, in which case the problem is
 >    greater than certificates and pins.  See Section 3.4.2.

meaning: if one is pinned to one's leaf public key, and the corresponding 
private key is compromised, then....

 >
 > 3.2.2.  The root or intermediary CA is compromised
 >
 >    This disaster will affect many hosts (HSTS Hosts and other), and will
 >    likely require a client software update (e.g. to revoke the signing
 >    CA and/or the false certificates it issued).
 >
 >    If the operator has a backup pin whose signature chain is still
 >    valid, they should deploy it.

s/backup pin/backup server cert/ ?

[10] Should probably succinctly describe, perhaps in an individual section 
somewhere in "deployment considerations" the steps involved in what you're 
calling "deploying a backup pin"  -- i.e. deploy the backup server cert that 
corresponds to the "backup pin" that they have (hopefully) been setting in 
their pins list. See S 3.1.  Deployment Guidance, first bullet.

 >                                   In this case, the host need not even
 >    degrade from Known Pinned to Known.

This notion perhaps needs to be more clearly explained. Also, if some given UA 
encountered the bogus cert before the backup server cert is deployed, it will 
unpin the host (aka the host degrades to Known HSTS Host from Known Pinned, for 
that UA). So there is sort of a race condition here.

 >
 > 3.3.  Disasters Relating to Certificate Mismanagement
 >
 > 3.3.1.  The leaf certificate expires
 >
 >    Operators should deploy their backup pin.

see comment on "deploy backup pin" above.

 >
 >    Note that when evaluating a pinned certificate, the UA MUST un-pin
 >    the fingerprint if the certificate has expired.  If a pin list
 >    becomes empty, the UA downgrades the host from Known Pinned HSTS Host
 >    to Known HSTS Host.  The usual HTTPS validation procedure now
 >    applies.

above entire para contains normative stipulations that need to be in the 
present Sec 2.

 >
 >    Operators should get any CA to sign a new cert with updated expiry,
 >    based on the existing, unchanged public key.
 >
 >    o  And/or, operators should deploy their backup pin and/or have a CA
 >       sign an all-new key.
 >
 >    o  Operators should continue to set pins in their HSTS header, and
 >       UAs will upgrade from Known HSTS Host to Known Pinned HSTS Host
 >       when the fingerprint(s) refer(s) to valid certificate(s) again.
 >
 >

 > 3.3.2.  The leaf certificate is lost

how does one "lose" a leaf certificate ?

would this be an example: server suffers disk crash, or other catastrophic 
failure, server cert and/or private key not available for whatever reason ?

probably need more rigorous language here.

 >
 >    Operators should deploy their backup pin.

see comment on "deploy backup pin" above.

if the server been previously issuing pins to this backup cert, then (a), else 
(b) ....

also, is this presuming one pinned to one's leaf server cert ?  i think so 
given next sentence:

 >                                                  Alternately, if they
 >    pinned to a root or intermediary signer, they should get a new leaf
 >    certificate signed by one of those signers.

so these two cases need to be more clearly delineated.

 >
 >    Operators SHOULD attempt to get the certificate revoked by whatever
 >    means available (extant revocation mechanisms like CRL or OCSP,
 >    blacklisting in the UA, or future revocation mechanisms).
 >
 >    o  We know that extant revocation mechanisms are unreliable.
 >       Operators SHOULD NOT not depend on them.

above probably needs more rigorous/accurate language. CRL/OCSP revocation 
advertisement mechs are via the CA.

What should operators do instead of relying on extant revocation mechanisms? 
The implication is that this pinning mech is one way to supplant such reliance?

 >
 > 3.3.3.  The CA is extorting the operator approaching renewal/expiry time
 >
 >    If the backup pin chains to a different signer, the operator should
 >    deploy it.  (They should then get a new backup pin.)

see comment on "deploy backup pin" above.

 >
 >    The time running up to renewal can be used to serve additional HSTS
 >    public key hashes, pinning to new root CAs.

What is the difference between the above two sentences?

 >
 >    o  Hosts can also disable pinning altogether as described above.

which section specifically?  you mean via explicit unpinning in S 2.3 ?

 >
 >    If the host is pinned to leaves or its own intermediary, operators
 >    can simply get a different root CA to sign the existing public key.

which public key?  needs expanded description.

 >
 >    If the operator fails to get new certs in time, and the host is
 >    pinned only to the one root CA, the solution is simple; see
 >    Section 3.3.1.
 >
 >
 > 3.4.  Disasters Relating to Vulnerabilities in the Known HSTS Host
 >
 > 3.4.1.  The host is vulnerable to HTTP header injection
 >
 >    Note that header injection vulnerabilities are in general more severe
 >    than merely disabling pinning for individual users.
 >
 >    The attacker could set additional pins for certificates he controls,
 >    or pin break verifiers for codes he controls, allowing him to
 >    undetectably MITM clients.  When or if the client is outside the
 >    scope of the attacker's MITM attack, the result is DoS.
 >
 >    The attacker could disable HSTS and pins.

the above is a risk if SSL MITM is a possibility, eg via sslstrip et al, what's 
often termed a "network attacker", but those could be protected against by 
pinning to the end entity key/cert. probably need to establish more context in 
the above -- eg it isn't clear via what means you're anticipating that header 
injection is occuring. if the server host is owned, then we have bigger troubles.

no remediation is noted here in S 3.4.1 ?

(tho there's no easy ones or server-side detectable ones)

 >
 > 3.4.2.  The host suffers full server-side compromise
 >
 >    After setting up a new host, operators should deploy the backup pin.
 >    Alternately, if the host is pinned to a root or intermediary signer,
 >    the operator should get a new leaf certificate signed by one of those
 >    signers.

how is the latter different from the former ?   in the former one already has a 
backup server cert & key pair, and the in the latter one doesn't ?

see comment on "deploy backup pin" above.

 >
 >    Operators SHOULD attempt to get the certificate containing the
 >    compromised private key

s/compromised private key/public key corresponding to the compromised private key/

 >                              revoked by whatever means available (extant
 >    revocation mechanisms like CRL or OCSP, blacklisting in the UA, or
 >    future revocation mechanisms).
 >
 >    o  We know that extant revocation mechanisms are unreliable.  Do not
 >       depend on them.

same comments here as on above similar revocation exhortation.

 >
 > 4.  Usability Considerations

User Agent Advice ?

 >
 >    When pinning works to detect impostor Known Pinned HSTS Hosts, users
 >    will experience denial of service.

I wouldn't term this as DoS - rather, users are protected from using an 
imposter web app.

 >    UAs SHOULD explain the reason why.

agreed.

 >    If it happens that true positives (actual attacks) outnumber
 >    false positives (hosts bricking themselves by accident), the feature
 >    will gain a positive reputation.  Note that pinning has started life
 >    with a good reputation because it provoked the discovery of the
 >    DigiNotar CA compromise.  (When DigiNotar signed a certificate for
 >    *.google.com in August 2011, Chrome users discovered the attack due
 >    to the pre-loaded pins for Google domains.)

perhaps this above stuff should be noted somewhere, but maybe not here

 >    We believe that, in general, DoS is a better failure mode than user
 >    account/session compromise or other result of TLS compromise.

s/DoS/rendering web applications unavailable/

needs better-composed rationalization of the tradeoffs from user perspective.

 >    UAs MUST have a way for users to clear current pins that were set by
 >    HSTS.  UAs SHOULD have a way for users to query the current state of
 >    Known (Pinned) HSTS Hosts.

Can't make normative requirements for UA implementation advice in this spec.

 > 5.  Economic Considerations
 >
 >    If pinning becomes common, host operators might become incentivized
 >    to choose CAs that get compromised less often, or respond better to
 >    compromise.  This will require information to flow into the market,
 >    and for people to interpret no news post-compromise as bad news.
 >    Pinning itself will provide some of that information, as will sources
 >    like UA vendor communications, the EFF SSL Observatory, the Qualys
 >    SSL survey, etc.

am not sure above para belongs in this protocol spec. perhaps in a separate 
"rationale" document or other places.

 >
 >    The disaster recovery plans described above all incur new costs for
 >    host operators, and increase the size of the certificate market.
 >    Arguably, well-run hosts had already absorbed these costs because
 >    (e.g.) backup certificates from different CAs were necessary disaster
 >    recovery mechanisms even before certificate pinning.  Small sites --
 >    which although small might still need to provide good security -- may
 >    not be able to afford the disaster recovery mechanisms we recommend.
 >    (The cost of the backup certificate is not the issue; it is more the
 >    operational costs in safely storing the backup and testing that it
 >    works.)  Thus, low-risk pinning may be available only to large sites;
 >    small sites may have to choose no pinning or potentially bricking
 >    their host (up to the maxAge window).  This is not worse than the
 >    status quo.

perhaps the above should be recast as simply decisions any TLS-based web app 
provider will need to make -- i.e., whether to obtain backup server certs, 
whether to test them, etc, and what the ramifications are of (not) doing so.

 > 6.  Ideas

this section is for consideration of features/functionality to be possibly be 
incorporated into the spec proper ?  I.e. this section will go away as the spec 
nears completion ?   should probably explain here in a brief intro.

 >
 > 6.1.  Requiring Backup Pins
 >
 >    Because bricking risk mitigation requires a backup pin, UAs could
 >    require that the pins directive have at least two fingerprints, at
 >    least one of which does not match any of the public keys in any of
 >    the certificates in the chain.  (This idea due to Tom Sepez.)

Not sure what such a UA-enforced config would accomplish. Does this imply that 
UAs would not pin hosts that advertise only one pin ? What is proposed that UAs 
should do when encountering a host that issues just one pin?

this would exclude those that wish to perform a simple pin and assume the 
risks. Its not clear that the risks are greater for users, except if such a 
stringent UA behavior were to render some otherwise legit web apps unavailable. 
  perhaps this is more appropriate as an expanded discussion on tradeoffs in 
deployment considerations.

 >
 > 6.2.  Prepopulating Pin Lists

suggest renaming this "Automatic Pin List Prepopulation"

 >
 >    HSTS-based certificate pinning, unlike built-in pinning, suffers from
 >    the bootstrap problem.  To work around this, we could pre-populate a
 >    built-in pin list with public keys as observed in the wild by one or
 >    more global observers, such as Googlebot, the EFF SSL Observatory,
 >    Convergence notaries, and so on.
 >
 >    One problem with this approach is that it does not involve host
 >    operators.  It is best to get operator consent before signing them up
 >    for a potentially risky new protocol such as this.  Therefore we
 >    leave this idea for work (including third-party UA extensions).

perhaps this spec should have functional requirements section, noting as one 
requirement that such a mechanism as cert/key pinning should be driven by the 
web app provider (what you are calling "host operators").

[11] otherwise probably should remove 3.7.2 or place this "auto pre-population" 
notion in a (out-of-)scope section.

 >
 > 6.3.  Tools to Assist Creation of Header
 >
 >    It would be good to provide tools that read X.509 certificate chains
 >    and generate example HSTS headers that operators can easily add to
 >    their webs erver configurations.

out of scope for spec proper, but could be perhaps be mentioned in "deployment 
considerations" section.

 >
 > 6.4.  Pinning Subresources

this section  should be in some "operational considerations" section (which is 
nominally distinct from a "deployment consderations" section")

 >
 >    Many hosts have pages that load subresources from domains not under
 >    the control, or under only partial control, of the main host's
 >    operators.

add subresource example such as "<IMG href="http://some.other.domain/"/>"

 >    For example, popular hosts often use CDNs, and CDN
 >    customers may have only limited, if any, ability to influence the
 >    configuration of the CDN's servers.  (This long-standing problem is
 >    independent of certificate pinning.)
 >
 >    To a limited extent, the includeSubDomains HSTS directive can address
 >    this: if the CDN host has a name that is a subdomain of the main host
 >    (e.g. assets-from-cdn.example.com points to CDN-owned servers), and
 >    if the main host's operators can guaranteeably keep up-to-date with

guaranteeably?

 >    the CDN's server certificate fingerprints -- perhaps as part of
 >    example.com's contract with the CDN -- then the problem may be
 >    solved.
 >
 >    CDNs SHOULD also use certificate pinning independently of any of
 >    their customers.

suggest phrasing this worthy requirement somewhat differently:

   Web app providers should also assess from whence their various app resources 
are obtained, and if over TLS/SSL, examine whether pinning those sources is 
possible (this may involve both business and technical considerations).

 >
 >    Although one can imagine an extension to this specification allowing
 >    the main resource to set pins for subresources in other domains, it
 >    is complex and fragile both from technical and business perspectives.
 >    The UA would have to accept those pins for the subresource domains
 >    ONLY when loading resources from the subdomains as part of a page
 >    load of the main host.  The independence of the two domains'
 >    operations teams would still pose synchronization problems, and
 >    potentially increase the bricking risk.
 >
 >    Therefore, except in simple cases, this document leaves the cross-
 >    domain subresource problem to future work.  Operational experience
 >    with HSTS-based certificate pinning should guide the development of a
 >    plan to handle the problem.

[11] add above paras to putative (out-of-)scope section/appendix.

 >
 > 6.5.  Pinning Without Requiring HTTPS
 >
 >    Some host operators would like to take advantage of certificate
 >    pinning without requiring HTTPS, but having clients require pins in
 >    the event that they do connect to the host with HTTPS.  As specified
 >    above, the current HSTS-based mechanism does not allow for this:
 >    clients that receive the pins directive via HSTS will also therefore
 >    require HTTPS -- that is the purpose of HSTS after all.  To have an
 >    additional directive, e.g. mode=optional, would not work because
 >    older clients that support HSTS but not the mode extension would
 >    effectively require HTTPS.
 >
 >    Alternatives include (a) putting the pins directive in a new header
 >    instead of extending HSTS; and (b) some kind of hack like setting
 >    maxAge=0 and having an additional directive to keep the pins alive
 >    (e.g. pinMaxAge).  These alternatives seem ugly to us and we welcome
 >    suggestions for a better way to support this deployment scenario.

[12] this overall question is quite apropos.

need to explore it on the mailing list (the topic's been opened already:

  Re: [websec] Pinning and beyond Was: Next rev of HSTS certificate
  pinning draft (Tobias Gondrom)
  https://www.ietf.org/mail-archive/web/websec/current/msg00593.html

)

 > 7.  Acknowledgements
 >
 >    Thanks to Jeff Hodges, Adam Langley, Nicolas Lidzborski, SM, and Yoav
 >    Nir for suggestions and edits that clarified the text.  Trevor Perrin
 >    for providing the pin break codes mechanism.  Adam Langley provided
 >    the SPKI fingerprint generation code.
 >
 >
 > 8.  What's Changed
 >
 >    This is the first draft of this proposal submitted as an official
 >    Internet Draft.
 >
 >
 > 9.  References

should have normative and informative references subsections.

 >
 >    [hsts-spec]
 >               Hodges, J., Jackson, C., and A. Barth, "HTTP Strict
 >               Transport Security (HSTS)", August 2011, <http://
 >               tools.ietf.org/html/
 >               draft-ietf-websec-strict-transport-sec-02>.

will need various normative references, eg to RFC5246, RFC4648,

there's an auto-generated I-D ref for this..

put this in "<!DOCTYPE ... " element at front of xml source for this I-D:

    <!ENTITY I-D.ietf-websec-strict-transport-sec     PUBLIC ""

"http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-ietf-websec-strict-transport-sec.xml">

and then down in <references> section put..

    &I-D.ietf-websec-strict-transport-sec;

..but will need to be

below refs are informative..

 >
 >    [why-fingerprint-key]
 >               Langley, A., "Public Key Pinning", May 2011,
 >               <http://www.imperialviolet.org/2011/05/04/pinning.html>.
 >
 >    [pin-break-codes]
 >               Perrin, T., "Self-Asserted Key Pinning", September 2011,
 >               <http://trevp.net/SAKP/>.

2119 is normative ref...

 >    [rfc-2119]
 >               Bradner, S., "Key words for use in RFCs to Indicate
 >               Requirement Levels", March 1997,
 >               <http://www.ietf.org/rfc/rfc2119.txt>.
 >
 >
 > Appendix A.  Fingerprint Generation
 >
 >    This Go program generates public key fingerprints, suitable for use
 >    in pinning, from PEM-encoded certificates.
 >
 >    package main
 >
 >    import (
 >           "io/ioutil"
 >           "os"
 >           "crypto/sha1"
 >           "crypto/x509"
 >           "encoding/base64"
 >           "encoding/pem"
 >           "fmt"
 >    )
 >
 >    func main() {
 >           if len(os.Args) < 2 {
 >                   fmt.Printf("Usage: %s PEM-filename\n", os.Args[0])
 >                   os.Exit(1)
 >           }
 >           pemBytes, err := ioutil.ReadFile(os.Args[1])
 >           if err != nil {
 >                   panic(err.String())
 >           }
 >           block, _ := pem.Decode(pemBytes)
 >           if block == nil {
 >                   panic("No PEM structure found")
 >           }
 >           derBytes := block.Bytes
 >           certs, err := x509.ParseCertificates(derBytes)
 >           if err != nil {
 >                   panic(err.String())
 >           }
 >           cert := certs[0]
 >           h := sha1.New()
 >           h.Write(cert.RawSubjectPublicKeyInfo)
 >           digest := h.Sum()
 >
 >           fmt.Printf("Hex: %x\nBase64: %s\n", digest,
 >                   base64.StdEncoding.EncodeToString(digest))
 >    }
 >
 >                                  Figure 6
 >
 >
 > Authors' Addresses

---
end

---

From: Tom Ritter <[email-masked]>
Date: Fri, 14 Oct 2011 21:04:19 -0400

I'm excited about this draft.

> This implies that the pin check machinery is up at the HTTP layer rather than down lower in or near the TLS layer, which implies that the UA can make normal HTTP requests to a bogus Known Pinned Host, and send cookies, before realizing that the pin check has failed.

I don't think this is worded correctly.

If a site is a Known Pinned Host, the pin check should occur after
recieving the certificate chain, but before the TLS session is wholly
established.  If this check does not pass, the connection is
aborted.[1]

If a pin check occured at the HTTP layer and does occur after a TLS
session has been established, data was sent by the client, and the
response received - I see only two things that could happen that would
be 'new' to the User Agent.

1) 'Oh, this site supports pinning.  I didn't know that.  I'll note it
down as a Known Pinned Host.  Let me check the pins just to be sane.'
This check wouldn't actually provide any security (that's what
preloading is for) - if the pins didn't match, either the server is
messed up or the attacker was incompetant because they could have
changed the pins.
2) 'I just recieved an unpin directive for the certificate I just used
to connect.' This is again a case of the server being messed up. [2]

So I think the existing wording is wrong, and better wording would be
something like:

Upon receipt of this header field, the UA will note the HSTS Host as a
Known Pinned HSTS Host if it was previously not.  When connecting to a
Known Pinned HSTS Host, the UA will compare the public key
fingerprint(s) in the Host's certificate chain to the pinned
fingerprints, and will fail closed before sending a HTTP request
unless at least one public key in the chain has a fingerprint matching
one of the pinned fingerprints.  (Following the HSTS specification,
TLS errors for HSTS hosts must be hard, with no chance for the user to
click through any warnings or errors.  We treat fingerprint mismatch
in the same way.)

Where I added
 - "..will note the HSTS Host as a Known Pinned HSTS Host IF IT WAS
PREVIOUSLY NOT."
 - "...will fail closed BEFORE SENDING A HTTP REQUEST unless at least...".

[1] From an engineering perspective, perhaps the connection IS
established because that occurs in a modular library that does not
know of pinning, but the HTTP request would not be sent, because the
connection would be examined outside the library.

[2] Do we handle the case where Alice connects to a Known Pinned Site,
recieves a valid certificate, but the certificate is unpinned in the
Pinning Header?  I think this is an error case, because while the
initial connection is valid, any subsequent connections in the TLS
session were 'fruit of the poison tree' - made using an unpinned
certificate.  I also think behavior should be noted explictly.

I have an additional comment: this header field could grow quite
large.  Site operators may wish to omit it in the response in several
scenarios that indicate to them the client has recieved it already.  I
don't see a reason this would cause any issue, I'm just noting it.

-tom

---

From: Chris Palmer <[email-masked]>
Date: Fri, 21 Oct 2011 16:25:55 -0700

Sorry I've been so slow getting back to you all on this. I've started
revising the doc and will submit a fresh -01 version next week.

Thanks for all your feedback!