[Openpgp-dt] v5 keys and hardware tokens (issue #63)

Daniel Kahn Gillmor <dkg@fifthhorseman.net> Thu, 10 March 2022 06:59 UTC

Return-Path: <dkg@fifthhorseman.net>
X-Original-To: openpgp-dt@ietfa.amsl.com
Delivered-To: openpgp-dt@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id AEBF13A07C0 for <openpgp-dt@ietfa.amsl.com>; Wed, 9 Mar 2022 22:59:45 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.109
X-Spam-Level:
X-Spam-Status: No, score=-2.109 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=neutral reason="invalid (unsupported algorithm ed25519-sha256)" header.d=fifthhorseman.net header.b=J4gfKtJd; dkim=pass (2048-bit key) header.d=fifthhorseman.net header.b=huJeTOhT
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 ExLJP95iJ7r5 for <openpgp-dt@ietfa.amsl.com>; Wed, 9 Mar 2022 22:59:40 -0800 (PST)
Received: from che.mayfirst.org (che.mayfirst.org [IPv6:2001:470:1:116::7]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id E2EEA3A07AC for <openpgp-dt@ietf.org>; Wed, 9 Mar 2022 22:59:39 -0800 (PST)
DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/simple; d=fifthhorseman.net; i=@fifthhorseman.net; q=dns/txt; s=2019; t=1646895576; h=from : to : subject : date : message-id : mime-version : content-type : from; bh=YwNw0AsC2Ti3b2BuGJrw/Ditrj9xVrnqlzh5t3MHhLE=; b=J4gfKtJdRXKZFdKpSkrZXm28iwjrGwyDMdU/lcSvk2eciwwQaAkSXd6z4eBvZZYxlLSAC XCnwdpEK32voQJ7DQ==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fifthhorseman.net; i=@fifthhorseman.net; q=dns/txt; s=2019rsa; t=1646895576; h=from : to : subject : date : message-id : mime-version : content-type : from; bh=YwNw0AsC2Ti3b2BuGJrw/Ditrj9xVrnqlzh5t3MHhLE=; b=huJeTOhTACgo7DyO6JdbSeAueBGb9+dTD1qUJ1tNHgUd/v4IEKf7UHZKypUidVaT615q+ /4hEmYndQo0zxXemlfHOkfxnmq/r/Cb8ZzC5uI32RzQZGHkAjSmvcrreqNU9pXWgOkAiIKk lAzCaOZ2e1nv9nTD44LL9d+YVZFJZdCBgYMPDtsMlRc17unE6eyZefNE56Oz9IeqWSwrsBo ZtlxWBzmKjeXweUTI8da14IKYysWezMQOgFWL+XRf3ltuFl3joY97ijQjd1r4Lwq/rwpebx kJBfUnCgjzBMgsyvG3aQ2UqQMyDS3Z5hxenx/cRaNTmrp0rqNcnj2TQ7nW7g==
Received: from fifthhorseman.net (lair.fifthhorseman.net [108.58.6.98]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by che.mayfirst.org (Postfix) with ESMTPSA id A1F3BF9AD for <openpgp-dt@ietf.org>; Thu, 10 Mar 2022 01:59:36 -0500 (EST)
Received: by fifthhorseman.net (Postfix, from userid 1000) id 30A282043A; Thu, 10 Mar 2022 01:59:34 -0500 (EST)
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
To: openpgp-dt@ietf.org
Autocrypt: addr=dkg@fifthhorseman.net; prefer-encrypt=mutual; keydata= mDMEX+i03xYJKwYBBAHaRw8BAQdACA4xvL/xI5dHedcnkfViyq84doe8zFRid9jW7CC9XBiI0QQf FgoAgwWCX+i03wWJBZ+mAAMLCQcJEOCS6zpcoQ26RxQAAAAAAB4AIHNhbHRAbm90YXRpb25zLnNl cXVvaWEtcGdwLm9yZ/tr8E9NA10HvcAVlSxnox6z62KXCInWjZaiBIlgX6O5AxUKCAKbAQIeARYh BMKfigwB81402BaqXOCS6zpcoQ26AADZHQD/Zx9nc3N2kj13AUsKMr/7zekBtgfSIGB3hRCU74Su G44A/34Yp6IAkndewLxb1WdRSokycnaCVyrk0nb4imeAYyoPtBc8ZGtnQGZpZnRoaG9yc2VtYW4u bmV0PojRBBMWCgCDBYJf6LTfBYkFn6YAAwsJBwkQ4JLrOlyhDbpHFAAAAAAAHgAgc2FsdEBub3Rh dGlvbnMuc2VxdW9pYS1wZ3Aub3JnL0Gwxvypz2tu1IPG+yu1zPjkiZwpscsitwrVvzN3bbADFQoI ApsBAh4BFiEEwp+KDAHzXjTYFqpc4JLrOlyhDboAAPkXAP0Z29z7jW+YzLzPTQML4EQLMbkHOfU4 +s+ki81Czt0WqgD/SJ8RyrqDCtEP8+E4ZSR01ysKqh+MUAsTaJlzZjehiQ24MwRf6LTfFgkrBgEE AdpHDwEBB0DkKHOW2kmqfAK461+acQ49gc2Z6VoXMChRqobGP0ubb4kBiAQYFgoBOgWCX+i03wWJ BZ+mAAkQ4JLrOlyhDbpHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3Jnfvo+ nHoxDwaLaJD8XZuXiaqBNZtIGXIypF1udBBRoc0CmwICHgG+oAQZFgoAbwWCX+i03wkQPp1xc3He VlxHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnaheiqE7Pfi3Atb3GGTw+ jFcBGOaobgzEJrhEuFpXREEWIQQttUkcnfDcj0MoY88+nXFzcd5WXAAAvrsBAIJ5sBg8Udocv25N stN/zWOiYpnjjvOjVMLH4fV3pWE1AP9T6hzHz7hRnAA8d01vqoxOlQ3O6cb/kFYAjqx3oMXSBhYh BMKfigwB81402BaqXOCS6zpcoQ26AADX7gD/b83VObe14xrNP8xcltRrBZF5OE1rQSPkMNy+eWpk eCwA/1hxiS8ZxL5/elNjXiWuHXEvUGnRoVj745Vl48sZPVYMuDgEX+i03xIKKwYBBAGXVQEFAQEH QIGex1WZbH6xhUBve5mblScGYU+Y8QJOomXH+rr5tMsMAwEICYjJBBgWCgB7BYJf6LTfBYkFn6YA CRDgkus6XKENukcUAAAAAAAeACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmcEAx9vTD3b J0SXkhvcRcCr6uIDJwic3KFKxkH1m4QW0QKbDAIeARYhBMKfigwB81402BaqXOCS6zpcoQ26AAAX mwD8CWmukxwskU82RZLMk5fm1wCgMB5z8dA50KLw3rgsCykBAKg1w/Y7XpBS3SlXEegIg1K1e6dR fRxL7Z37WZXoH8AH
Date: Thu, 10 Mar 2022 01:59:33 -0500
Message-ID: <87sfrqthre.fsf@fifthhorseman.net>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-="; micalg="pgp-sha256"; protocol="application/pgp-signature"
Archived-At: <https://mailarchive.ietf.org/arch/msg/openpgp-dt/0NOVUb96OZQhqN-5jSCLbS4SzW4>
Subject: [Openpgp-dt] v5 keys and hardware tokens (issue #63)
X-BeenThere: openpgp-dt@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OpenPGP working group design team <openpgp-dt.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/openpgp-dt>, <mailto:openpgp-dt-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/openpgp-dt/>
List-Post: <mailto:openpgp-dt@ietf.org>
List-Help: <mailto:openpgp-dt-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/openpgp-dt>, <mailto:openpgp-dt-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 10 Mar 2022 06:59:46 -0000

An outstanding concern we have is our story about using hardware tokens
with OpenPGP:

   https://gitlab.com/openpgp-wg/rfc4880bis/-/issues/63

In particular, the OpenPGP smartcard specification explicitly identifies
OpenPGP keys by 20-octet fingerprints:

   https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.1.pdf

I'm not a smartcard expert, but here's what i think i understand (i hope
the more expert folks in this group can correct me):

An OpenPGP smartcard can store three secret keys: one for signing (SIG),
one for decryption (DEC), and one for authentication (AUT).

The public keys data for each of these three secret keys can typically
be extracted from the card, but they will be the raw public key
material, not stored in full OpenPGP format.  Some cards may not be able
to produce the full raw public key material available, or may have it
wrong, somehow. Or maybe it's expensive to retrieve?  (when/why is it
not available?)

Alongside these keys, the card stores metadata fields that correspond to
the keys.  for each of these three keys, there is at least these
non-optional fields:

 - 4 octet creation date (unix timestamp)
 
 - 20 octet fingerprint identifier

 - a "cardholder certificate", an arbitrary blob (expected to be X.509)
   that is out of scope of the OpenPGP spec

all of these slots are arbitrarily writable, and the card does not
enforce that they adhere to any particular fingerprinting scheme.

The card as a whole is also required to accept the following general
fields (not associated with any particular key):

 - 0-39 octets of "Name", formatted in a particular flavor of ASCII

 - 1 octet of "Sex"

 - arbitrary-length field of binary, proprietary "login data"
 
 - arbitrary-length field of "URL", which is intended to point to a place to download the full certificates

 - 2-8 octets of language preferences.

In addition to these data points, the card also has three additional
read/write 20-octet "fingerprint" slots for fingerprints of trusted CAs.


As v5 fingerprints are 32 octets, not 20 octets, they don't fit nicely on these
cards.

As i understand it, the biggest concern we have is that some
applications rely on the fingerprint field from the card in order to
retrieve the OpenPGP fingerprint from the network.  Presumably this is
donen because extracting the public key material from the card to create
an OpenPGP public key and thereby derive the fingerprint is not always
possible.

I see several possible ways we can go forward with v5 keys on
existing smartcards:

 a) assert that existing smartcards are for v4 keys only, and require an
    update to the card (or buying a new card) to make it work with v5
    keys.

 b) assert that the secret key material can be stored in these cards and
    used with them, but v5 fingerprints will not be stored.  fingerprint
    fields for v5 keys will be set to a fixed magic value (maybe 20
    octets of 0x05 ?).  The cards can only be used if the user can
    extract the public key material from the card, formulate a v5 pubkey
    from it, and compute the fingerprint directly via local computation,
    not on the card.

 c) truncate v5 fingerprints to 20 octets and stuff them in the
    truncated slots.  The implementation using the card has to guess
    whether the corresponding public key is v5 or v4.

 d) some sort of compromise, like putting a magic value in the first 12
    octets of the fingerprint, and storing only the v5 key ID (8 octets)
    in the fingerprint field.  A reliant implementation checks for the
    magic value in the upper 12 octets, and has to work from the key ID,
    not the fingerprint, if it is unable to compute the fingerprint from
    the extracted pubkey material.

 e) cannibalize some other data field(s).  For example, cannibalize the CA
    fingerprint: when storing a v5 key in the SIG slot, store an 8-octet
    magic value concatenated with the low 12 octets of SIG key
    fingerprint, *and* overwrite the first CA fingerprint slot with the
    high 20 octets of the SIG key fingerprint.  same step applies for
    the DEC fingerprint and the second CA fingerprint, and AUT and the
    third CA.  A v5-aware application will check the fingerprint slot
    for the magic value, and if it finds it, extracts the rest of the
    fingerprint from the cannibalized fingerprint slot.

    If the CA fingerprint slots are too important to lose for the sake
    of storing a v5 key (are they?  who uses them and how?)  It's not
    too hard to imagine cannibalizing part of the URL field for this
    purpose instead of cannibalizing the CA fingerprint slots.  For
    example, store the remaining parts of the three fingerprints as
    base64-encoded blobs in a "#fragment" at the end of the URL.  But
    the max length of the URL field varies from card to card (see page
    33 of the spec) and it's not clear that there will always be enough
    room. We'd need 96 base64-encoded characters in the fragment to
    represent three sets of 20-octets, plus 1 octet for the fragment
    delimiter character "#".  That's 97 chars (3*32 + 1) in the URL
    field. (what are the most common lengths permitted for the URL in
    popular cards?)

    Alternately, if space is really tight, we could signal that the key
    is a v5 key by using fewer octets, for example by cannibalizing part
    of the first octet of the key creation date field: if the first four
    bits that field are all zero (an implausibly early timestamp, no
    later than 1978-07-04), then the key is a v5 key; reconstruct the
    timestamp by left-shifting the field by 4 bits (key generation must
    clear the low four bits of the creation timestamp). The fingerprint
    field stores 20 octets of the fingerprint, and we just need to find
    another 12 octets for the rest of the fingerprint.  Using a
    b64-encoded fragment in the URL field to store the remaining three
    fractions consumes only 59 chars (ceil(12*3*8/5)+1).  But that's
    starting to get pretty complicated.

Does anyone have a preference for any of these choices?  or a strong
objection to any of them?

          --dkg