Opened 4 years ago

Closed 4 years ago

#9167 closed defect (fixed)

Find a more stable key pinning scheme for

Reported by: dcf Owned by: dcf
Priority: Medium Milestone:
Component: Archived/Flashproxy Version:
Severity: Keywords:
Cc: Actual Points:
Parent ID: Points:
Reviewer: Sponsor:


I've had to update the public key pin for in flashproxy-reg-appspot often: March 31, June 13, and again today on June 28.

transport_security_state_static.h in the Chromium source code is where the pins are stored, I believe. That file hasn't had any changes since March 28. That makes me think we're doing something wrong and hashing more than we're supposed to.

transport_security_state_static_generate.go is the program used to generate the Chromium file. It does:

        h := sha1.New()

Whereas flashproxy-reg-appspot does:

        pubkey_der = cert.get_pubkey().as_der()
        pubkey_digest = sha1(pubkey_der).digest()

The Chromium source code says:

// This file is automatically generated by transport_security_state_static_generate.go

// These are SubjectPublicKeyInfo hashes for public key pinning. The
// hashes are SHA1 digests.


static const char kSPKIHash_Google1024[] =

static const char kSPKIHash_Google2048[] =

static const char kSPKIHash_GoogleBackup1024[] =

static const char kSPKIHash_GoogleBackup2048[] =

static const char kSPKIHash_GoogleG2[] =


static const char* const kGoogleAcceptableCerts[] = {

None of these digests match what we have in flashproxy-reg-appspot:

# SHA-1 digest of expected public keys. Any of these is valid. See
# for the reason behind
# hashing the public key, not the entire certificate.
PUBKEY_SHA1 = tuple(x.decode("hex") for x in (

Our other programs using pins (flashproxy-reg-email and facilitator-email-poller) have been more stable historically but could benefit from whatever works for flashproxy-reg-appspot.

Child Tickets

Attachments (1)

intermediate-pin.patch (6.1 KB) - added by dcf 4 years ago.
Two patches implementing the pin checking of intermediate certs.

Download all attachments as: .zip

Change History (4)

comment:1 Changed 4 years ago by dcf

It looks like we are hashing the right thing (pubkey_der). What it looks like we're doing wrong is we need to also check intermediate certificates' keys.


openssl s_client -connect -showcerts

Running the leaf certificate through these OpenSSL commands gives

1e3f66cfa0eb03136297fdb238ad6619c30ff375  p1.key

which is what we have pinned in flashproxy-reg-appspot. But doing the same with the intermediate certificate gives

40c5401d6f8cbaf08b00edefb1ee87d005b3b9cd  p2.key

which is the same as a Chromium digest:

static const char kSPKIHash_Google1024[] =

Changed 4 years ago by dcf

Attachment: intermediate-pin.patch added

Two patches implementing the pin checking of intermediate certs.

comment:2 Changed 4 years ago by dcf

Status: newneeds_review

Please take a look at these two patches.

The first refactors the connection to directly use OpenSSL functions through M2Crypto. Python's ssl.wrap_socket doesn't provide enough access: we can getpeercert but as far as I can tell there's no way to get the certificate chain.

The second patch iterates over the certificate chain and looks for a match. It also uses a sha1sum copied directly from the Chromium source code.

comment:3 Changed 4 years ago by dcf

Resolution: fixed
Status: needs_reviewclosed

I effected the same change in flashproxy-reg-appspot, flashproxy-reg-email, and facilitator-email-poller.

Note: See TracTickets for help on using tickets.