[websec] HPKP & different encodings of the same public key

Jesse Wilson <jesse@swank.ca> Sun, 15 May 2016 02:46 UTC

Return-Path: <limpbizkit@gmail.com>
X-Original-To: websec@ietfa.amsl.com
Delivered-To: websec@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id D762312B01E for <websec@ietfa.amsl.com>; Sat, 14 May 2016 19:46:44 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.4
X-Spam-Level:
X-Spam-Status: No, score=-2.4 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.198, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AV4VqicBJBov for <websec@ietfa.amsl.com>; Sat, 14 May 2016 19:46:43 -0700 (PDT)
Received: from mail-io0-x232.google.com (mail-io0-x232.google.com [IPv6:2607:f8b0:4001:c06::232]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id DD09212B011 for <websec@ietf.org>; Sat, 14 May 2016 19:46:42 -0700 (PDT)
Received: by mail-io0-x232.google.com with SMTP id 190so175176784iow.1 for <websec@ietf.org>; Sat, 14 May 2016 19:46:42 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:from:date:message-id:subject:to; bh=Q6QOLvP4b5YfmTmoz7r4jBCsoPd9vxy7E4IiTMmGfrY=; b=mv9FcCD5UdpDoJDrAcuOuvW8aYANkEHaJ+81GZ6gYValfnH+ovBVQvfuxy9OPALaSX N6HqsgwMXPLrC33xbkeBBTm6yIYpP7HK83i1xp0BxV26LquAMzQfyuTiFOGmRtaakOt+ 961lN2ltY10cRb+jh5ErTOYQaNJEttyIxmw2souZb8n7gJOsS2kdGfZOh3N8s/iYCrEV 1dA2S8lotKwnRf71xJcWv8QcfRGjB4GvNl42LB/z7jbdDukqrJhsC930kCXZofG/qVoG JGweu2w5GgXyFZhD3RCGfevaeVBdIRu+O4cVHf1LfHJzHlY8HDpqwNPKqwHOa3evjcAY uylA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:sender:from:date:message-id:subject :to; bh=Q6QOLvP4b5YfmTmoz7r4jBCsoPd9vxy7E4IiTMmGfrY=; b=gXkb6ZtWsJ+jWE9RFo63P4q3XmLf8PaFnrjwbBk+qsFD5L3UvNr6fapkzmS/JGtQFQ 3hfm6lN1qVamJlhjidNYIUPstO/RZGSUIZEflDhTtTCPGAYa4YFfHBrfwOQBwXCpwJiG Jk4xYY3/U1wrS1Kmo3Bk7M1cqH0HHVG9/pmBAi7vt42ZOjcWMObOEX39+cOurYAhTcqZ A/7ZzfGfmtb82aD7ZCg4QirFPe7IfqgVaxpO7galir03bjwgPi0Wo4c3orflARtlp3cY kI1xf0fjSllH+/5eRwWWL2foMarUTVcvuW3zmyq/QtDJahmX3R9QlKGj8wY7dMqtFGiA XPDg==
X-Gm-Message-State: AOPr4FVMJP+/JbVqOaGvynUlKoCvgtORGsprmyAZNJB962VLAR8FmDGqvKVhy8HGAGsNaRQSeszxuO+kKzPb4g==
X-Received: by 10.107.37.16 with SMTP id l16mr14708073iol.138.1463280402107; Sat, 14 May 2016 19:46:42 -0700 (PDT)
MIME-Version: 1.0
Sender: limpbizkit@gmail.com
Received: by 10.79.35.106 with HTTP; Sat, 14 May 2016 19:46:22 -0700 (PDT)
From: Jesse Wilson <jesse@swank.ca>
Date: Sat, 14 May 2016 22:46:22 -0400
X-Google-Sender-Auth: PlASUMymjKeiLx8dYfwLT_iLM0k
Message-ID: <CAME=j1=QZTFdxaMQ=_Egy296zhAiL--2hcW0_nc-3BLgz7z9XA@mail.gmail.com>
To: websec@ietf.org
Content-Type: multipart/alternative; boundary="001a114088b09311fc0532d88438"
Archived-At: <http://mailarchive.ietf.org/arch/msg/websec/FNxx6cCUSuFPzIeMFfaXH9tg46E>
Subject: [websec] HPKP & different encodings of the same public key
X-BeenThere: websec@ietf.org
X-Mailman-Version: 2.1.17
Precedence: list
List-Id: Web Application Security Minus Authentication and Transport <websec.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/websec>, <mailto:websec-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/websec/>
List-Post: <mailto:websec@ietf.org>
List-Help: <mailto:websec-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/websec>, <mailto:websec-request@ietf.org?subject=subscribe>
X-List-Received-Date: Sun, 15 May 2016 02:51:55 -0000

I work on OkHttp, an Android HTTP client that implements HPKP-like
certificate pinning. We recently saw a problem where different versions of
Android returned different bytes for the ASN.1 encoding of the same
certificate. This is bad: the pins don’t match!

The certificate of interest uses a named curve (secp521r1) with ECC. I used
der2ascii <https://github.com/google/der-ascii> to view the SPKI ASN.1
bytes.

Older versions of Android (which use BouncyCastle) embed the curve:

SEQUENCE {
  SEQUENCE {
    # ecPublicKey
    OBJECT_IDENTIFIER { 1.2.840.10045.2.1 }
    SEQUENCE {
      INTEGER { 1 }
      SEQUENCE {
        # prime-field
        OBJECT_IDENTIFIER { 1.2.840.10045.1.1 }
        INTEGER { `01ffffffffffffff...` }
      }
      SEQUENCE {
        OCTET_STRING { `01ffffffffffffff...` }
        OCTET_STRING { `0051953eb9618e1c...` }
      }
      OCTET_STRING { `0400c6858e06b704...` }
      INTEGER { `01ffffffffffffff...` }
      INTEGER { 1 }
    }
  }
  BIT_STRING { `0004019519de800d...` }
}

But new versions of Android (which use Conscrypt/OpenSSL) reference the
curve by name:

SEQUENCE {
  SEQUENCE {
    # ecPublicKey
    OBJECT_IDENTIFIER { 1.2.840.10045.2.1 }
    # secp521r1
    OBJECT_IDENTIFIER { 1.3.132.0.35 }
  }
  BIT_STRING { `0004019519de800d...` }
}

The original certificate embeds the curve.

I believe my problem is that the Java APIs I’m using don’t return raw bytes
from the certificate. Instead Java decodes the certificate into a model and
re-encodes that when the bytes are requested. The original and roundtripped
SPKI bytes are not identical.

Does anyone else do ASN.1 encoding in order to compute a certificate’s pin?
Or is it a uniquely Java problem?!

The spec should warn that a single SPKI may have multiple conflicting
encodings. I suggest that only encoding in the certificate should be
pinned. TLS server administrators should also be careful to not
inadvertently re-encode their SPKIs when doing maintenance.

Thanks!
​