aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Ryabitsev <konstantin@linuxfoundation.org>2021-04-29 17:16:08 -0400
committerKonstantin Ryabitsev <konstantin@linuxfoundation.org>2021-04-29 17:16:08 -0400
commit7d34f11b9143fad202ab3cf0e49c9637fe30369a (patch)
tree9fc6f0b5b1615637ac479657406c6434dd1c5e7f
parentb0e98279568c2339d5391716744cfb7bcd46b31d (diff)
downloadpatch-attestation-poc-7d34f11b9143fad202ab3cf0e49c9637fe30369a.tar.gz
Copy-editing README
Tweak awkward sentences in order to make them a bit less awkward. Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
-rw-r--r--README.rst107
1 files changed, 58 insertions, 49 deletions
diff --git a/README.rst b/README.rst
index 744405c..1128a40 100644
--- a/README.rst
+++ b/README.rst
@@ -80,9 +80,6 @@ infrastructure.
Just as PGP and S/MIME attestation, this has important problems when it
comes to patches sent via mailing lists:
- - If the "sender" header is included in the attestation, the DKIM
- signature will no longer verify due to mailing lists necessarily
- rewriting it for bounce handling.
- ML software commonly modifies the subject header in order to insert
list identification (e.g. ``[some-topic]``). Since the "subject"
header is almost always included into the list of headers attested
@@ -100,9 +97,12 @@ whitespace is collapsed, so patches for languages like Python or GNU
Make where whitespace is syntactically significant may have different
code result in the same hash.
-DKIM works well enough for end-to-end email attestation, but has
-important drawbacks for domain-level attestation of patches, especially
-when they are delivered via mailing lists.
+So, while DKIM works well enough for regular domain-level email
+attestation, it still has significant drawbacks for attesting patches.
+Similarly, it does not provide significant developer identity assurances
+for patches sent via large public hosting services like Gmail, Fastmail,
+or others -- at best, we have proof that the email traversed their
+mail gateways (hopefully, after being properly authenticated).
Proposal
--------
@@ -113,15 +113,16 @@ standard in order to adapt (and adopt) it for this purpose.
X-Developer-Signature header
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We largely take the DKIM standard and adopt it for developer attestation
-signatures, with some steps taken to make the workflow fit better with
-patches sent via mailing lists.
+We use DKIM RFC-6376 to implement a compatible subset of it for
+developer attestation signatures, with some extra steps taken to make
+the workflow fit better with patches sent via DKIM-non-compliant mailing
+lists.
Differences from DKIM:
- the d= field is not used (no domain signatures involved)
- the q= field is not used (end-user tooling handles key lookup)
- - the c= field is not used (git-mailinfo is used for canonicalization)
+ - the c= field is not used (see below for canonicalization)
- the i= field is optional, but MUST be the canonical email address of
the sender, if not the same as the From: field
@@ -131,9 +132,10 @@ We use the "relaxed/simple" canonicalization as defined by the DKIM
standard, but the message is first parsed by "git-mailinfo" in order to
achieve the following:
- - normalize any content-transfer-encoding modifications
- - move any in-body git headers (From:, Subject: Date:) into the
- message headers
+ - normalize any content-transfer-encoding modifications (convert back
+ from base64/quoted-printable/etc into 8-bit)
+ - use any encountered in-body git headers (From:, Subject: Date:) to
+ rewrite the outer message headers
- perform any subject-line normalization in order to strip content not
considered by git-am when applying the patch
@@ -144,19 +146,24 @@ following flags::
We then use the data found in "i" to replace the From:, Subject: and
Date: headers of the original message, and concatenate "m" and "p" back
-together to form the body of the message, which is normalized using CRLF
-line endings and DKIM "simple" body canonicalization.
+together to form the body of the message, which is then normalized using
+CRLF line endings and the DKIM "simple" body canonicalization (any
+trailing blank lines are removed).
Any other headers included in signing are canonicalized using the
"relaxed" header canonicalization routines defined in the DKIM standard.
+In other words, the body and some of the headers are normalized and
+reconstituted using the "git-mailinfo" command, and then canonicalized
+using DKIM's relaxed/simple standard.
+
Algorithms
~~~~~~~~~~
DKIM standard mostly relies on RSA signatures, though RFC 8463 extends
-it to support ED25519 keys as well. Since this implementation is fully
+it to support ED25519 keys as well. Since our implementation is fully
backward compatible with the DKIM standard, it is possible to use any of
-the DKIM-defined algorithms. For the purposes of this POC, we only
-support the following two sign-hash algorithms:
+the DKIM-defined algorithms. However, for the purposes of this POC, we
+only support the following two signing/hashing algorithms:
- ed25519-sha256: exactly as defined in RFC8463
- openpgp-sha256: uses OpenPGP to create the signature
@@ -167,8 +174,8 @@ The provided POC code in main.py is pretty feature-complete, though it
probably needs further improvements to properly deal with corner-cases.
You will notice that it's only a few hundred lines of Python code and
does not require any external libraries/programs except libsodium and
-GnuPG for crypto and git for canonicalization. All of these are already
-likely to be present on a developer's workstation.
+GnuPG for crypto, plus git for message canonicalization. All of these
+are already likely to be present on a developer's workstation.
Running the code
~~~~~~~~~~~~~~~~
@@ -191,7 +198,7 @@ PATH.
ED25519 signatures
~~~~~~~~~~~~~~~~~~
-ED25519 is a "nothing up my sleeve" implementation of Elliptic-Curve
+ED25519 is the "nothing up my sleeve" implementation of Elliptic-Curve
Cryptography (ECC) favoured by free software enthusiasts. Its primary
benefits are algorithmic speed of all crypto operations and relative
smallness of both public/private keys and generated signatures.
@@ -215,10 +222,10 @@ OpenPGP signatures
~~~~~~~~~~~~~~~~~~
OpenPGP is not really an "algorithm," so this is merely an indicator
that the signature is created using an OpenPGP-compliant application.
-Here it is in action, though you will need to use your own PGP key to
-if you want to try it::
+Here it is in action, though you will need to use your own PGP key if
+you want to try it::
- ./main.py -m emails/mricon-unsigned.eml sign-pgp -k B6C41CE35664996C
+ $ ./main.py -m emails/mricon-unsigned.eml sign-pgp -k B6C41CE35664996C
SIGNING : PGP using B6C41CE35664996C
MSGSRC : emails/mricon-unsigned.eml
--- SIGNED MESSAGE STARTS ---
@@ -258,7 +265,7 @@ by malicious actors en-route.
The proposed POC offers several ways of achieving this:
- tracking the keys in a regular development branch
-- tracking the keys in a special dedicated ref
+- tracking the keys in a special dedicated branch
- tracking the keys in a dedicated git repository
Using the regular development branch
@@ -288,28 +295,28 @@ specified in the signature header.
NB: Since domain/local/selector values are taken from untrusted sources,
they should be urlencoded before attempting to locate the public key on
-disk or via commands passed to "git show".
+disk or via any commands passed to "git show".
Using a dedicated ref
~~~~~~~~~~~~~~~~~~~~~
In the case of the project the size of the Linux Kernel, it would be too
-onerous to track the keys of contributors centrally, so individual
+onerous to track the keys of all contributors centrally, so individual
subsystem maintainers will likely want to track their own subsets of
keys from just the developers with whom they work on a regular basis.
-Using a general development branch would be too inconvenient in this
+Using the regular development branch would be too inconvenient in this
case, since it would interfere with upstream work, so it makes sense to
use a separate branch for this purpose, e.g. "refs/heads/keys" that
contains just the keys directory with no other content.
-Contributors can then still submit key additions and changes as regular
-patches or pull requests and the maintainer merely needs to remember to
-apply them to the proper branch.
+Participating contributors can then submit key additions and changes as
+regular patches or pull requests and the maintainer merely needs to
+remember to apply them to the proper key management branch.
Using a dedicated git repository
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Similarly, instead of using a dedicated branch, maintainers may choose
to use a wholly separate git repository for this purpose. This may be
-useful if the same set of developers work on multiple repositories.
+useful if the same set of developers work on multiple projects.
Key formats for ED25519 and OpenPGP
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -319,22 +326,24 @@ The public keys should be in the following format:
- openpgp: any format that can be passed to "gpg --import", but
preferably an ascii-armored key export
-In the case of PGP signatures, the POC implementation will create a
-temporary keyring containing just the imported key.
+In the case of verifying PGP signatures, the POC implementation will
+create a temporary keyring containing just the imported key, so it
+should never clash with the default keyring.
Using the default GnuPG keyring
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-It is up to the implementation to fall back to the default GnuPG keyring
-when checking openpgp signatures. The POC code will do so and will
-additionally warn if the key has insufficient trust (this check is
+It is up to the implementation whether to fall back to the default GnuPG
+keyring when checking openpgp signatures. The POC code will do so and
+will additionally warn if the key has insufficient trust (this check is
meaningless for in-git bundled keys, so it is not performed).
Rotating and revoking keys
~~~~~~~~~~~~~~~~~~~~~~~~~~
-Keys can be retired or replaced at any time by merely changing it in the
-repository, committing and pushing (or submitting a pull request/patch
-with the change). Maintainers can then pull the change or apply the
-patch and push the change to all other participating co-maintainers.
+Keys can be retired or replaced at any time by merely changing them in
+the repository, committing, and pushing (or submitting a pull
+request/patch to the maintainer with the change). Maintainers can then
+pull the change or apply the patch and push it out to all other
+participating co-maintainers.
Contributors can have multiple valid keys if they properly specify the
selector when adding signatures -- or the verification tooling can
@@ -342,22 +351,22 @@ simply iterate through all keys listed in the directory for that
domain/local to find the matching one.
Revoked keys can be simply deleted or moved into the revoked/
-subdirectory with perhaps an explanation why the key was revoked.
+subdirectory with perhaps an explanation why they were revoked.
Verifying keys before accepting them
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As stated earlier, bootstrapping trust remains a hard problem. We do not
-aim to resolve it here and defer to the participating maintainers to
-pick their key verification strategy, e.g.:
+aim to resolve it here and will cowardly defer to the participating
+maintainers to pick their preferred key verification strategy, e.g.:
- meeting up in person at a conference and exchanging keys
- holding a video session and reciting fingerprints (or entire keys, in
the case of ed25519)
- using an email round-trip as proof of key ownership
-This can be as lax or as strict as maintainers choose. Obviously, if the
+This can be as lax or as strict as maintainers choose (though if the
procedure is too lax, then the whole point of cryptographic attestation
-becomes moot.
+becomes moot).
Trusting the git repository
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -377,11 +386,11 @@ maintainers, should this scheme become adopted.
Automating patch attestation
----------------------------
The git-send-email application supports executing a validation hook
-before sending out patches. The attestation library should provide such
-integration so that patches are automatically attested every time a
+before sending out patches. The end-user tooling should provide git hook
+integration so that patches are automatically attested every time
"git-send-email" is used.
-We aim to provide a lightweight attestation library for this purpose, as
+We aim to provide a lightweight attestation utility for this purpose, as
well as implement all necessary verification routines in "b4"
client-side tooling used by many Linux developers for their patch
workflow.