Re: [websec] Issue #53 - Clarify status of pin validation when used with private trust anchors

"Ryan Sleevi" <> Thu, 22 November 2012 00:45 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 80F7321E8043 for <>; Wed, 21 Nov 2012 16:45:37 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.999
X-Spam-Status: No, score=-1.999 tagged_above=-999 required=5 tests=[BAYES_00=-2.599, J_CHICKENPOX_66=0.6]
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id uZbqpZz6V-EJ for <>; Wed, 21 Nov 2012 16:45:36 -0800 (PST)
Received: from ( []) by (Postfix) with ESMTP id 7749521E8034 for <>; Wed, 21 Nov 2012 16:45:36 -0800 (PST)
Received: from (localhost []) by (Postfix) with ESMTP id 0030126C069; Wed, 21 Nov 2012 16:45:35 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed;; h=message-id :in-reply-to:references:date:subject:from:to:cc:reply-to :mime-version:content-type:content-transfer-encoding; s=; bh=JCUzTDvsdGBs33EH2Kr5QWE3/9g=; b=aKVbs1ZjG8AXBsbCx gZkdS/mQN/SDIACIcXn7Ei+R/C0Z7zwbdAYKI8SsiSGFcTAjMJmIstETNZ9Vortl aEZxJSBthm5bDUs9BNzJdJaFhvsx0rfCuyu6U095GbXfY/I7WZWNqyfxdegcQh2l 3jznxlKGanb2KUjJWJ4lsVdawk=
Received: from ( []) (Authenticated sender: by (Postfix) with ESMTPA id B658226C05E; Wed, 21 Nov 2012 16:45:35 -0800 (PST)
Received: from (proxying for (SquirrelMail authenticated user by with HTTP; Wed, 21 Nov 2012 16:45:35 -0800
Message-ID: <>
In-Reply-To: <>
References: <>
Date: Wed, 21 Nov 2012 16:45:35 -0800
From: Ryan Sleevi <>
To: Yoav Nir <>
User-Agent: SquirrelMail/1.4.21
MIME-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Cc: IETF WebSec WG <>
Subject: Re: [websec] Issue #53 - Clarify status of pin validation when used with private trust anchors
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: Web Application Security Minus Authentication and Transport <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Thu, 22 Nov 2012 00:45:37 -0000

On Wed, November 21, 2012 1:38 pm, Yoav Nir wrote:
>  Hi
>  During the meeting in Atlanta I said that saying that that pin validation
>  is disabled when the cert chains to a private trust anchor would not go
>  over well, because it's disabling a security feature in the presence of an
>  attack. I still think so, but I think we can raise less red flags if we
>  just describe what the issue is - that there is a TLS proxy.
>  I don't have suggested text, at least yet, but here's how I think the
>  issue can be addressed. Keep in mind that we're not writing a design for
>  any particular browser.
>  ===
>  On some networks, mostly corporate networks, there are TLS proxies,
>  transparent proxies that sign certificates on behalf of visited web sites
>  as described in [ref]. When a UA gets into such a network, the certificate
>  presented in the TLS handshake will not be consistent with the UA's
>  previously stored pins.
>  It is up to the UA to decide whether such a TLS proxy is acceptable or
>  not. If it is acceptable, then pinning should be disabled, and the UA
>  should not follow the mandates in section 2.4 of this document. Ideally,
>  such proxies, or their associated trust anchors would be specially marked
>  as trusted for this purpose. If the UA does not allow for such a
>  configuration, a heuristic MAY be used to determine what trust anchors are
>  used for a legitimate TLS proxy. One such heuristic, is that all trust
>  anchors that are not part of the stock trust anchor store that comes with
>  the UA or the operating system, but that are in the trust anchor store
>  (implying that they have been added by the user) are acceptable for TLS
>  proxies.
>  ===
>  I think this defuses the issue. What do others think?

The wording suggests that it's primarily a network layer 'attacker', which
somehow raises the spectre of RFC 1984 (unfairly, I think), but we also
see TLS proxies that are entirely local to clients' machines - for
example, Antivirus Software that installs a Winsock LSP.

I'm still working with Chris Palmer to find suitable language to propose
on this, but we've been looking at ways to define this processing in terms
of "client policy" that may supercede or disregard the the Pinning
Metadata for a Known Pinned Host, to be incorporated into Section 2.4.
(Validating Pinned Connections)

>  One other suggestion that was brought up in Atlanta, was to have the
>  server specify a policy about private trust anchors in the Public-Key-Pins
>  header, something like:
>     Public-Key-Pins: max-age=500; policy=strict;
>         pin-sha1="4n972HfV354KP560yw4uqe/baXc=";
>         pin-sha1="IvGeLsbqzPxdI0b0wuj2xVTdXgc="
>     Public-Key-Pins: max-age=31536000; policy=accept_private;
>         pin-sha1="4n972HfV354KP560yw4uqe/baXc=";
>         pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="
>  In case of policy=strict, the UA will not accept any handshake that
>  disagrees with stored pins. This might be preferred by some servers, that
>  are willing to accept not being accessible from all networks for the
>  benefit of preventing MitM attacks. What do others think about this idea?

Given HPKP's shared history with HSTS, and as discussed during Atlanta,
one of the things we were looking at was ensuring the ABNF grammar was
consistent with the grammar that was decided for HSTS. In particular, the
ABNF grammar should NOT specify all of individual tokens, but instead
define the set of directives, to allow new directives to be added.

This ABNF looks as such:

Public-Key-Pins  = "Public-Key-Pins" ":" [ directive ] *( ";" [ directive ] )

directive        = simple-directive
                   / pin-directive

simple-directive = directive-name [ "=" directive-value ]
directive-name   = token
directive-value  = token | quoted-string

pin-directive    = "pin-" token "=" quoted-string

With the above grammar, and given that HPKP's threat model is primarily
motivated by allowing site operators to defend against certificate
misissuance from CAs trusted by the client, we're proposing that 'strict'
be added (as a simple-directive). The absence of 'strict' implies that the
UA is permitted to allow client local policy to override the directive,
while the presence of 'strict' implies that the header should be
interpreted exactly as it is supplied.

The reasoning to making the default open, rather than closed, is that we
anticipate that 'strict' is not the primary or default mode that sites
intend to operate in (since client policy is a known-unknown from the
perspective of site operators), so this is primarily an ease-of-use

I think your proposal to use a policy directive with a set of known value
strings may also work, but my fear is that it would just end up with most
servers sending "policy=accept_private" to be safe, which seems like both
a sharp edge to find and perhaps more bytes than needed.