diff --git a/misc/w3c/as2/OpenPGPoverActivityStreams.org b/misc/w3c/as2/OpenPGPoverActivityStreams.org index 6e6bf70..57847c2 100644 --- a/misc/w3c/as2/OpenPGPoverActivityStreams.org +++ b/misc/w3c/as2/OpenPGPoverActivityStreams.org @@ -1,1383 +1,1412 @@ #+TITLE: Active Cryptography: OpenPGP over Activity Streams 2.0 #+STARTUP: showall #+LATEX_COMPILER: xelatex #+LATEX_CLASS: article #+LATEX_CLASS_OPTIONS: [12pt] #+LATEX_HEADER: \usepackage{xltxtra} #+LATEX_HEADER: \usepackage[margin=1in]{geometry} #+LATEX_HEADER: \setmainfont[Ligatures={Common}]{Times New Roman} #+LATEX_HEADER: \author{Ben McGinnes } * Introduction :PROPERTIES: :CUSTOM_ID: intro :END: | Version: | 0.0.1-draft-002 | | Author: | Ben McGinnes | | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | | Language: | Australian English, British English | - | xml:lang: | en-AU, en-GB, en | + | Language code: | en-AU, en-GB, en | This document provides a specification for using OpenPGP cryptography with the Activity Streams 2.0 transport method. It was devised with particular attention towards providing end-user encryption and verification on federated ActivityPub based instances (e.g. Mastodon and Pleroma). This proposal is not an official part of the W3C's protocols, but is offered as an optional means of addressing some of the security issues identified as lacking or missing in those protocols. As such it is offered under the same terms as any [[https://www.ietf.org/][IETF]] or [[https://www.w3.org][W3 Consortium]] standards or proposals as free for any use. Example code, however, may be released under the same terms as the GnuPG Project or some other license as relevant. Example code will be provided separately from this document. ** Motivation :PROPERTIES: :CUSTOM_ID: intro-motive :END: The current Presidential Administration in the USA has diverged -considerably from the policies of his predecessors with recent +considerably from the policies of his predecessors with certain legislative and regulatory changes which are set to enable a far greater implementation of authoritarian policies and agendas, as well as enabling those policies to be enforced beyond the territory of the United States of America. This sets a dangerous precedent with regards to the freedom of all people around the globe to communicate freely and privately, particularly when they may become subject to matters which are entirely legal where they live, but which the United States legislates against. The legislative and regulatory changes in the United States of most concern to the rest of the world at the present time are: the removal -of Net Neutrality provisions by the FCC, the CLOUD Act and the -SESTA/FOSTA Act. The latter being the attempt to enforce American +of Net Neutrality provisions by the FCC, the /CLOUD Act/ and the +/SESTA-FOSTA Act/. The latter being the attempt to enforce American laws regarding adult content, primarily of a sexual nature, globally. They also remove the “safe harbour” provisions which previously permitted hosting providers to ignore what their customers were doing, in turn making those providers tools of the state who must police the actions of end users and actively censor them. +Since the first draft of this protocol extension was written, the +types of wholesale legislative threats to privacy have been +exacerbated by Australia's efforts to “double down” on the arbitrary +powers overreach in passing the /Telecommunications and Other +Legislation Amendment (Assistance and Access) Bill 2018/. + + +** Contributors and Attribution + :PROPERTIES: + :CUSTOM_ID: intro-contrib + :END: + +Obviously the creators of the ActivityStreams 2.0 and ActivityPub +protocols have already contributed significantly with those +protocols. Those people are: Christopher Lemmer Webber, Jessica +Tallon, Evan Prodromou, James M. Snell, Amy Guy and Erin Shepherd. + +Additionally the lead developers of the two most popular ActivityPub +implementations, [[https://mastodon.social/@gargron][Eugen Rochko]] (Mastodon) and [[https://pleroma.soykaf.com/users/lain][Lain Soykaf]] (Pleroma), +have been very welcoming of a proposal which seeking to supply a +comprehensive solution to a number of the frequently requested +features in their two projects. + +Feedback on the first draft has been very valuable; especially from +Wiktor Kwapisiewicz. Particularly with regards to the discussions +around the WebFinger protocol and related matters. + +Input and encouragement from [[https://mastodon.social/@david_ross][David Ross]] (Mozilla), [[https://switter.at/@e][Eliza]] (Assembly +Four, Switter), [[https://mastodon.social/@ThisIsMissEm][Emelia]] (Switter) and [[https://switter.at/@vwerner][Vince Werner]] has been a boon. + + +*** Additional Thanks + :PROPERTIES: + :CUSTOM_ID: intro-thanks + :END: + +Additionally the following people have provided non-technical support +of various types during the course of designing and writing this +protocol extension: Chamara “Mara” Caldera, Trindy Oakley and Michael +“Elgy” Eldritch. + +Obviously thanks are also due to [[https://g10code.com][Werner Koch]] for not even batting an +eyelid at what could arguably have been a bit of a tangent from my +work on [[https://www.gnupg.org/][GnuPG]] and [[https://www.gnupg.org/software/gpgme/index.html][GPGME]] in order to devise precisely how to apply +OpenPGP to a whole new transport protocol. + ** Approach :PROPERTIES: :CUSTOM_ID: intro-approach :END: Over the course of the last decade or a little more, a great deal of communication online has shifted towards using social media networks. Email is still good for many things, but it is not good for everything and various types of social networks fill that need. Modifying the underlying protocols or specifications of proprietary networks, such as Twitter and Facebook, is generally not possible. It is also clear that these networks will act against some or even all of their own user base in order to achieve the goals of those running the companies in question. In the case of Facebook that is in the form of surveillance of large populations and subsequent manipulation of them. In the case of Twitter it is in the form of banning those who vehemently oppose Nazism or who discuss or promote adult entertainment of various types, primarily pornography and sex work, regardless of the jurisdiction to which the end user is actually subject. Open standards and protocols, however, can be leveraged freely and as necessary. This is what Phil Zimmermann did back in 1991 when he released the first version of Pretty Good Privacy for use with Email, USENET and, very likely, FidoNet (or FidoNet style) BBS networks. The same approach may be utilised now with social networks which themselves provide an open specification and where that specification provides the means for extending or advancing itself. There is clearly grounds for social network users to have access to the tools to send and receive end-to-end encrypted private messages via their social network accounts and identities. Likewise there is a need for end users to be able to prove, should they wish to do so, that a message was not modified in transit; either by their own server of another within the federated networks in use. This current proposal applies to the W3 Consortium's [[https://www.w3.org/TR/activitystreams-core/][Activity Streams 2.0]] and [[https://www.w3.org/TR/activitypub/][ActivityPub]] protocols; the latter being based upon the former. ** Cryptographic Implementation Choice :PROPERTIES: :CUSTOM_ID: intro-crypto-choice :END: The cryptographic choice with regards to the GnuPG Project was limited to the two engines which GnuPG currently supports: OpenPGP and S/MIME. -Since the intended outcome of this proposal is to provide a means of -securing or preventing content manipulation to end users directly, the -OpenPGP model was selected. +Since the intended outcome of this proposal is to provide end users +with a means of securing content or preventing content manipulation, +the OpenPGP model was selected. It would, however, be possible to switch the security focus to the -server level in order to utilise some future advancement may +server level in order to utilise some future advancement. This may necessitate or simply favour utilising a different cryptographic implementation or method. As a consequence this proposal is designed to more easily enable swapping one method for another. -Note that this is separate and in addition to the use of a PEM key by -ActivityPub servers for each of their users. In those cases the -private key is generated by the ActivityPub server when the user +Note that this is separate from and in addition to the use of a PEM +key by ActivityPub servers for each of their users. In those cases +the private key is generated by the ActivityPub server when the user account is created. As a consequence it is inherently flawed from a user security perspective. It does, however, move the complexity out of the user level and back to the server level. Whereas this proposal does not. ** Definitions :PROPERTIES: :CUSTOM_ID: intro-definitions :END: *IMPORTANT:* Everything in this proposal is optional. The definitions listed here are within the context of the proposal itself. This document uses the terms defined in [[https://tools.ietf.org/html/rfc4880][RFC 4880]] and in the same way. The key words: "*must*", "*must not*", "*required*", "*shall*", "*shall not*", "*should*", "*should not*", "*recommended*", "*may*", and "*optional*" to be interpreted as defined in [[https://tools.ietf.org/html/rfc2119][RFC 2119]]. The following terms have these definitions: - *AP* means ActivityPub. - *AS* means Activity Streams. - *AS2* means Activity Streams 2.0. - *AC* means Active Cryptography or Activity Cryptography; the working title for the protocol extension. The document also draws on the same RFCs cited by both the Activity Streams [[https://www.w3.org/TR/activitystreams-core/][core]] and [[https://www.w3.org/TR/activitystreams-vocabulary/][vocabulary]] documents, as well as the [[https://www.w3.org/TR/activitypub/][ActivityPub]] protocol definition. * Cryptographic Activities :PROPERTIES: :CUSTOM_ID: crypto :END: This section introduces the new objects, collections, activity types and properties necessary to implement OpenPGP functions with Activity Streams 2.0 and ActivityPub. ** Cryptographic protocol :PROPERTIES: :CUSTOM_ID: crypto-protocol :END: In order to handle any situations in which servers and/or clients may implement multiple cryptographic protocols, a property *must* be set for any cryptographic object or activity. - #+begin_src javascript - { "cryptographic-protocol": "openpgp" } - #+end_src +#+begin_src javascript + {"cryptographic-protocol": "openpgp"} +#+end_src Where the relevant JSON data is already clearly part of a cryptographic object or activity this proprty *may* be defined as =protocol=. - #+begin_src javascript - { "protocol": "openpgp" } - #+end_src +#+begin_src javascript + {"protocol": "openpgp"} +#+end_src *** OpenPGP Protocol :PROPERTIES: :CUSTOM_ID: crypto-protocol-openpgp :END: When integrating OpenPGP with Activities or Objects, consideration must be given to both the versions in use throughout the network and setting sensible minimum requirements so as not to adversely affect the rest of the network. For this reason the current standards defined in RFC 4880 *must* be implemented, while the recommendations of RFC 4880bis *should* be -available. While a number of older versions of the standard *may* be +available. Though a number of older versions of the standard *may* be available with any given implementation, any older standard for which -existing recommendations state not to use +existing recommendations state not to use them due to security related +issues then those older standards *must not* be used. ** MIME and file types :PROPERTIES: :CUSTOM_ID: crypto-mime-types :END: The media or content types utilised are adapted from the PGP/MIME types defined in [[https://tools.ietf.org/html/rfc2015][RFC 2015]] and [[https://tools.ietf.org/html/rfc3156][RFC 3156]]. Specifically this covers the =pgp-keys=, =application/pgp-encrypted= and =application/pgp-signed= MIME types. In addition to these an implementation *may* utilise =application/pgp-encrypted+activitystreams= and *may* utilise =application/pgp-signed+activitystreams= to indicate an Activity Stream object (i.e. an =application/activity+json= object) is either entirely affected by the cryptographic function or the object is OpenPGP data which contains an ActivityPub or Activity Strams object or activity type which will need to be processed upon decryption or signature validation. ** Keys :PROPERTIES: :CUSTOM_ID: crypto-keys :END: Unlike the PEM key included with ActivityPub instances, OpenPGP keys are always intended to be generated by the end user(s) controlling a given actor's account and not controlled or accessed by the server, even when that server is controlled by a single user. There are also valid reasons or use cases for assigning multiple keys to an actor or using the same key with multiple actors. This is particularly the case if proof of OpenPGP key control was adopted as an alternative means of providing authentication between a client and server, in addition to OAuth methods. Though there is already a well established network of public -keyservers, the SKS keyserver pool, and from GPG 2.1 there is an -alternative method of retrieving keys associated with a domain name -built-in; there are also valid reasons for not using these methods of -providing access to a public key used with activities. +keyservers, the SKS keyserver pool, and from GnuPG 2.1 there is the +[[https://datatracker.ietf.org/doc/draft-koch-openpgp-webkey-service/][OpenPGP Web Key Directory]] (WKD); there are also valid reasons for not +using these methods of providing access to a public key used with +activities. Likewise, there is a need for serving key information with actor information and referencing it with objects and activities where necessary. This would effectively turn an ActivityPub instance into a limited public keyserver for the keys assigned to actors under its purview, though it may not maintain or serve copies of those keys containing full web-of-trust signatures, particularly if there are size constraints or bandwidth limitations.[fn:1] *** Public keys and Actors :PROPERTIES: :CUSTOM_ID: crypto-actor :END: In order to enable access to cryptographic information controlled at the user level we need to add an optional property to actors; one where the absence of it equates to a value of =null=. Since it is theoretically possible for multiple cryptographic protocols to be in use, in addition to the Linked Data and HTTP Signatures referenced in the ActivityPub specification, this optional property *must* contain an array of JSON data listing the =protocol= or =cryptographic-protocol=, the =cryptoContext= for a URI of a collection containing more relevant data, the =publicKeys= for an additional URI just for checking public key data and *may* contain a =primaryKeyID= referencing the preferred key ID used with the actor. Here is an example using the same actor example in the ActivityPub specification. Note that the key ID or fingerprint used here does not exist on the keyservers and is really just a SHA1 sum of the actor's name. #+BEGIN_SRC javascript { "@context": ["https://www.w3.org/ns/activitystreams", {"@language": "ja"}], "type": "Person", "id": "https://kenzoishii.example.com/", "following": "https://kenzoishii.example.com/following.json", "followers": "https://kenzoishii.example.com/followers.json", "liked": "https://kenzoishii.example.com/liked.json", "inbox": "https://kenzoishii.example.com/inbox.json", "outbox": "https://kenzoishii.example.com/feed.json", "preferredUsername": "kenzoishii", "name": "石井健蔵", "summary": "この方はただの例です", "icon": [ "https://kenzoishii.example.com/image/165987aklre4" ], "cryptoProtocols": [ { "protocol": "openpgp", "cryptoContext": "https://kenzoishii.example.com/openpgp.json", "publicKeys": "https://kenzoishii.example.com/openpgpkeys.json", "primaryKeyID": "3A1222F4BE79DB2AF069FADCF507B8E7E6EF68BF" } ] } #+END_SRC A slight variation demonstrating how multiple cryptographic implementations could be utilised along with not specifying a primary key ID may appear more like this: #+BEGIN_SRC javascript { "@context": ["https://www.w3.org/ns/activitystreams", {"@language": "ja"}], "type": "Person", "id": "https://kenzoishii.example.com/", "following": "https://kenzoishii.example.com/following.json", "followers": "https://kenzoishii.example.com/followers.json", "liked": "https://kenzoishii.example.com/liked.json", "inbox": "https://kenzoishii.example.com/inbox.json", "outbox": "https://kenzoishii.example.com/feed.json", "preferredUsername": "kenzoishii", "name": "石井健蔵", "summary": "この方はただの例です", "icon": [ "https://kenzoishii.example.com/image/165987aklre4" ], "cryptoProtocols": [ { "protocol": "openpgp", "cryptoContext": "https://kenzoishii.example.com/openpgp.json", "publicKeys": "https://kenzoishii.example.com/openpgpkeys.json", "primaryKeyID": "3A1222F4BE79DB2AF069FADCF507B8E7E6EF68BF" }, { "protocol": "openquantum", "cryptoContext": "https://kenzoishii.example.com/openquantum.json", "publicKeys": "https://kenzoishii.example.com/openquantumkeys.json" } ] } #+END_SRC In this example of the near-ish future OpenPGP usage is complemented by advances in Quantum Cryptography and the development of the FOSS Quantum Privacy Guard (QPG) with the standard being developed right along side it.[fn:2] *** Cryptography Context :PROPERTIES: :CUSTOM_ID: crypto-context :END: The cryptography contexts referenced from the actor define all the ways in which any key or keys are used in relation to actions and objects by or for that actor. First by identifying the keys and subkeys and then by defining which type of objects they're used in relation to. As well as whether the account is configured to always use them, as *may* be the case with signatures or not. The Cryptography Context is a collection of nested collections and objects dealing with each key or subkey type and the ways they're used in regards to activities or other objects. -In the following examples I use my current key in conjunction with an -imaginary (not-yet-existing) ActivityPub instance on my own domain, -=snuffy.adversary.org=.[fn:3] +In the following examples I use a key created in the name of the same +fictional character I used in the /GPGME Python Bindings HOWTO/ in +conjunction with an imaginary ActivityPub instance on an example +domain with a thematically related subdomain, =not.secret.example.com=. The =keys= item *must* contain a =keyinfo= item for each public key associated with the actor account. The =keyinfo= item *must* contain =keyIDs= data for the primary key and all enabled subkeys of the key. The =keyinfo= item *must* contain a =type= property which indicates both the key's cryptographic protocol and version number of that protocol. Most current OpenPGP keys are version 4 keys. The =keyinfo= item *may* contain =keyIDs= data for /revoked/ or /disabled/ keys previously used with the actor or revoked subkeys of an active key. Where this data is included the =keyID= item *must* contain an =enabled= property with a boolean value of /*true*/ or /*false*/. Additionally a =revoked= property *may* be included, also with a boolean value of /*true*/ or /*false*/. Where the =enabled= and =revoked= properties are not included, the default values are assumed to be that =enabled= is /*true*/ and =revoked= is /*false*/. The =keyinfo= item *may* contain =userIDs= data for some or all of the userIDs listed on the key itself. The =keyinfo= item *may* contain a =keyfiles= property with direct links to either or both of the GPG or PGP binary key formats or the ASCII armored key file format. The =keyinfo= item *must* contain the =publicKeys= property pointing to a JSON encoded URL containing at least the minimised version of the -public key. +public key. Alternatively the =publicKeys= property *may* point to an +array in which the first item is the JSON encoded URL containing key +material. The subsequent items in such an array *may* point to either +or both of URLs or URIs for accessing the keys via WebFinger or via +the Web Key Directory. A =keyID= item *must* contain an =id= property of the full key ID which is the hexadecimal key fingerprint without spaces. The =id= property *must not* be either the short or long key ID formats. A =keyID= item *must* contain a =type= property with a value indicating whether the key is the /*primary*/ (certification) key or a /*subkey*/. A =keyID= item *may* contain a =fingerprint= property with the full key ID in a human readable format. This is the fingerprint format which most OpenPGP users will be familiar with and normally presents the fingerprint with spaces between hexadecimal groupings of four characters each. A =keyID= item *must* contain an =algorithm= property with a value -indicating which asymmetric cryptographic algorithm *or* which -elliptic curve algorithm it uses. +indicating which asymmetric cryptographic algorithm *or* whether the +key utilised elliptic curve cryptography (as =ECC=). + +If the =algorithm= property has a value of =ECC= then the =keyID= item +*must* also include a =curve= property with a value of the specific +elliptic curve in use. If the =algorithm= property contains a value +specifying an asymmetric cryptographic algorithm then the =curve= +property *may* be omitted. If the =curve= property is not omitted, +but the =algorithm= property contains an asymmetric algorithm then the +=curve= property *must* be =null=. A =keyID= item *must* contain a =size= property with an integer value of the bit size of the key or subkey. A =keyID= item *must* contain properties for each of the four capabilities a key or subkey may possess: =certification=, =encryption=, =signing= and =authentication=. The values for each property are boolean strings; /*true*/ or /*false*/. A =keyID= item *must* contain a =timestamp= property with an integer value of the number of seconds since the epoch since the key or subkey was last modified. This will usually be the timestamp of the key's creation, but may indicate some other modification such as changing an expiration date or revoking the key or subkey. The remaining items address the three basic functions for which OpenPGP keys can be used with Activity Streams: signing, encryption and authentication. In addition to those three functions and policies, additional use case policies *may* be appended: refreshing a key from the keyservers, encrypting email notifications regarding -activities to the relevant email address for the actor account.[fn:4] +activities to the relevant email address for the actor account.[fn:3] Each of these items *must* include a =policy= property which stipulates whether or not that function is available and the consistency of that use. Possible policy values are /*must*/, /*may*/ and /*never*/. Recommended default values are /*may*/ unless the relevant key or subkey type is unavailable, in which case the correct value is /*never*/. If the policy value for an item is either /*must*/ or /*may*/ then the =authorizedKeyIDs= property *must* include an array with all full key IDs of the primary key and relevant subkeys to perform that task. If the policy value is /*never*/ then the =authorizedKeyIDs= *may* be =null=. #+BEGIN_SRC javascript { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://snuffy.adversary.org/openpgp.json", + "id": "https://not.secret.example.com/openpgp.json", "summary": "OpenPGP use and keys with this stream", "type": "openpgpCollection", "cryptographic-protocol": "openpgp", "totalItems": 6, "items": [ { "type": "openpgpKeys", "totalItems": 1, "items": [ { "id": "keyinfo", "type": "openpgpKeyV4", - "timestamp": 1514332912, - "lastUpdated": 1524951377, + "timestamp": 1546043571, + "lastUpdated": 1546039861, "keyIDs": [ { - "id": "DB4724E6FA4286C92B4E55C4321E4E2373590E5D", + "id": "C2FA40FD7A2E6DDB7A4FDFCB1A7425A225C3EF1F", "type": "primary", - "fingerprint": "DB47 24E6 FA42 86C9 2B4E 55C4 321E 4E23 7359 0E5D", - "algorithm": "RSA", - "size": 4096, + "fingerprint": "C2FA 40FD 7A2E 6DDB 7A4F DFCB 1A74 25A2 25C3 EF1F", + "algorithm": "ECC", + "curve": "ed25519", + "size": 256, "certification": true, "signing": true, "encryption": false, "authentication": false, - "timestamp": 1343480251 - }, - { - "id": "B7F0FE759387430DD0C58BDB7FF2D37135C7553C", - "type": "subkey", - "fingerprint": "B7F0 FE75 9387 430D D0C5 8BDB 7FF2 D371 35C7 553C", - "algorithm": "RSA", - "size": 3072, - "certification": false, - "signing": true, - "encryption": false, - "authentication": false, - "timestamp": 1343480419 + "timestamp": 1546039687 }, { - "id": "9CBEF6B7E0DF72CF91009AA5C98BAA1862E4484D", + "id": "681CBF37BE8ED04CB20BD5D0483F423E32DD79A8", "type": "subkey", - "fingerprint": "9CBE F6B7 E0DF 72CF 9100 9AA5 C98B AA18 62E4 484D", - "algorithm": "ELG", - "size": 4096, + "fingerprint": "681C BF37 BE8E D04C B20B D5D0 483F 423E 32DD 79A8", + "algorithm": "ECC", + "curve": "cv25519", + "size": 256, "certification": false, "signing": false, "encryption": true, "authentication": false, - "timestamp": 1343480559 + "timestamp": 1546039819 }, { - "id": "A48B28F39A83E63C55B8F30E48723A7579041EC6", + "id": "65DF3A3814D3BADC5E7D68F48D87C4418347F2BB", "type": "subkey", - "fingerprint": "A48B 28F3 9A83 E63C 55B8 F30E 4872 3A75 7904 1EC6", - "algorithm": "DSA", - "size": 3072, + "fingerprint": "65DF 3A38 14D3 BADC 5E7D 68F4 8D87 C441 8347 F2BB", + "algorithm": "ECC", + "curve": "ed25519", + "size": 256, "certification": false, "signing": true, "encryption": false, - "authentication": False - "timestamp": 1514332912 + "authentication": false, + "timestamp": 1546039861 } ], "userIDs": [ { - "name": "Ben McGinnes", - "comment": null, - "email": "ben@adversary.org" - }, - { - "name": "Ben McGinnes", - "comment": null, - "email": "ben@gnupg.org" + "name": "Danger Mouse", + "comment": "Social: @dm@not.secret.example.com", + "email": "dm@secret.example.net" } ], "keyfiles": [ { - "url": "http://www.adversary.org/ben-key.asc", + "url": "https://agents.secret.example.net/dm-key.asc", "Content-Type", "application/pgp-signature", "summary": "ASCII armored openpgp keyfile, full key" }, { - "url": "http://www.adversary.org/ben-key.gpg", + "url": "https://agents.secret.example.net/dm-key.gpg", "Content-Type", "application/pgp-keys", "summary": "Binary openpgp keyfile, full key" }, { - "url": "http://www.adversary.org/ben-key-clean.asc", + "url": "https://agents.secret.example.net/dm-key-clean.asc", "Content-Type", "application/pgp-signature", "summary": "ASCII armored openpgp keyfile, clean key" }, { - "url": "http://www.adversary.org/ben-key-clean.gpg", + "url": "https://agents.secret.example.net/dm-key-clean.gpg", "Content-Type", "application/pgp-keys", "summary": "Binary openpgp keyfile, clean key" }, { - "url": "http://www.adversary.org/ben-key-min.asc", + "url": "https://agents.secret.example.net/dm-key-min.asc", "Content-Type", "application/pgp-signature", "summary": "ASCII armored openpgp keyfile, minimised key" }, { - "url": "http://www.adversary.org/ben-key-min.gpg", + "url": "https://agents.secret.example.net/dm-key-min.gpg", "Content-Type", "application/pgp-keys", "summary": "Binary openpgp keyfile, minimised key" } ], - "publicKeys": "https://snuffy.adversary.org/openpgpkeys.json" + "publicKeys": "https://not.secret.example.com/openpgpkeys.json" } ] }, { "type": "content-signing", "policy": "May", - "authorizedKeyIDs": [ "DB4724E6FA4286C92B4E55C4321E4E2373590E5D", - "B7F0FE759387430DD0C58BDB7FF2D37135C7553C", - "A48B28F39A83E63C55B8F30E48723A7579041EC6" ] + "authorizedKeyIDs": [ "C2FA40FD7A2E6DDB7A4FDFCB1A7425A225C3EF1F", + "65DF3A3814D3BADC5E7D68F48D87C4418347F2BB" ] }, { "type": "encryption", "policy": "May", - "authorizedKeyIDs": [ "DB4724E6FA4286C92B4E55C4321E4E2373590E5D", - "9CBEF6B7E0DF72CF91009AA5C98BAA1862E4484D" ] + "authorizedKeyIDs": [ "C2FA40FD7A2E6DDB7A4FDFCB1A7425A225C3EF1F", + "681CBF37BE8ED04CB20BD5D0483F423E32DD79A8" ] }, { "type": "authentication", "policy": "Never", - "authorizedKeyIDs": None + "authorizedKeyIDs": null }, { "type": "refresh" "policy": "May", - "authorizedKeyIDs": [ "DB4724E6FA4286C92B4E55C4321E4E2373590E5D" ] + "authorizedKeyIDs": [ "C2FA40FD7A2E6DDB7A4FDFCB1A7425A225C3EF1F" ] }, { "type": "email-encryption", "policy": "Must", - "authorizedKeyIDs": [ "DB4724E6FA4286C92B4E55C4321E4E2373590E5D", - "9CBEF6B7E0DF72CF91009AA5C98BAA1862E4484D" ] + "authorizedKeyIDs": [ "C2FA40FD7A2E6DDB7A4FDFCB1A7425A225C3EF1F", + "681CBF37BE8ED04CB20BD5D0483F423E32DD79A8" ] } ] } #+END_SRC There are numerous ways in which OpenPGP may be leveraged by a server to provide authentication mechanisms for an actor utilising either signatures, encrypted tokens to be decrypted and used like OAuth or even using the authentication subkey type in a manner similar to TLS or SSH. For this example these possibilities are disregarded in order to demonstrate how a policy may be set to not use one possible function. A server might also use the public keys in a more traditional manner for OpenPGP if end users receive email notifications of activites. In that circumstance the server could, if the public key had a subkey with the encryption capability and the relevant matching policy, encrypt those emailed notifications. Also note that while default and recommended key generation stipulates that OpenPGP primary (certification) keys *should not* have the encryption capability, it is still advisable to include that primary key ID as authorized for any function granted to any of its subkeys. The reason being that not every OpenPGP implementation correctly interprets the relationship between the primary key and those subkeys (e.g. some of the JavaScript implementations). By explicitly including the primary as authorized, even for those tasks for which it does not have the capability we avoid unnecessary false error reports with certain OpenPGP implementations. If an actor has multiple keys assigned to it, it *should* be permitted to extend the policy section to provide for different policies for each key. For instance it may be preferred to have one main key which is always refreshed from the keyservers, but a backup key which is only updated manually by an end user. The following example demonstrates how a single type can be expanded to cover multiple policies. Where there is only one policy, as in the larger example above it is assumed that the =policies= property has a value of =1= and *may* be omitted. #+BEGIN_SRC javascript { "type": "email-encryption", "policies": 2, { "policy": "Must", - "authorizedKeyIDs": [ "DB4724E6FA4286C92B4E55C4321E4E2373590E5D", - "9CBEF6B7E0DF72CF91009AA5C98BAA1862E4484D" ] + "authorizedKeyIDs": [ "C2FA40FD7A2E6DDB7A4FDFCB1A7425A225C3EF1F", + "681CBF37BE8ED04CB20BD5D0483F423E32DD79A8" ] }, { - "policy": "May": - "authorizedKeyIDs": [ "6468C3737B7B3F396827EC15371AC5BFA04AE313", - "BA212621459C5135409D5F5DDE7D158D34DF2F7F" ] + "policy": "May", + "authorizedKeyIDs": [ "DB4724E6FA4286C92B4E55C4321E4E2373590E5D", + "9CBEF6B7E0DF72CF91009AA5C98BAA1862E4484D" ] } } #+END_SRC +Note that the second key listed here is that of the principal author +of this proposal and thus secret key material for that key will never +be provided; unlike the example key for “The Greatest Secret Agent in +the World: Danger Mouse.” + +While the secret key and paassphrase for these examples will be +published in supplemental files. This document will also contain +copies of the session keys used with encrypted examples; in case this +document is distributed separately from the supplemental files. -*** Serving Public Keys + +*** Serving Public Keys Directly :PROPERTIES: - :CUSTOM_ID: crypto-keyserving + :CUSTOM_ID: crypto-keyserv-direct :END: The =openpgpKeys.json= file contains a lot of matching data to the main context file by necessity since both need to include the key ID -data and both will usually include someuser ID data. Both of which +data and both will usually include some user ID data. Both of which being data about the public key which is available from the public key itself. The main differences, however, are that the context file provides the information on the circumstances under which the public key either can, should or must be used; but does not include a copy of the public key itself. While the other file only has data about the key itself and a copy of at least the minimised key (or keys if there are multiple keys assigned to an actor or stream). #+BEGIN_SRC javascript { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://snuffy.adversary.org/openpgpkeys.json", - "stream": "https://snuffy.adversary.org/", + "id": "https://not.secret.example.com/openpgpkeys.json", + "stream": "https://not.secret.example.com/", "summary": "OpenPGP public keys for this stream.", "type": "openpgpKeys", "cryptographic-protocol": "openpgp", "totalItems": 1, "items": [ { "type": "openpgpKey", "keyVersion": 4, "totalItems": 2, "lastUpdated": 1524951377, "items": [ { "type": "openpgpKeyData", "timestamp": 1514332912, "keyIDs": [ { - "id": "DB4724E6FA4286C92B4E55C4321E4E2373590E5D", + "id": "C2FA40FD7A2E6DDB7A4FDFCB1A7425A225C3EF1F", "type": "primary", "fingerprint": "DB47 24E6 FA42 86C9 2B4E 55C4 321E 4E23 7359 0E5D", "cipher": "RSA", + "curve": null, "size": 4096, "certification": true, "signing": true, "encryption": false, "authentication": false, "timestamp": 1343480251 }, { "id": "B7F0FE759387430DD0C58BDB7FF2D37135C7553C", "type": "subkey", "fingerprint": "B7F0 FE75 9387 430D D0C5 8BDB 7FF2 D371 35C7 553C", "cipher": "RSA", + "curve": null, "size": 3072, "certification": false, "signing": true, "encryption": false, "authentication": false, "timestamp": 1343480419 }, { - "id": "9CBEF6B7E0DF72CF91009AA5C98BAA1862E4484D", + "id": "681CBF37BE8ED04CB20BD5D0483F423E32DD79A8", "type": "subkey", - "fingerprint": "9CBE F6B7 E0DF 72CF 9100 9AA5 C98B AA18 62E4 484D", - "cipher": "ELG", - "size": 4096, + "fingerprint": "681C BF37 BE8E D04C B20B D5D0 483F 423E 32DD 79A8", + "cipher": "ECC", + "curve": "cv25519", + "size": 256, "certification": false, "signing": false, "encryption": true, "authentication": false, "timestamp": 1343480559 - }, - { - "id": "A48B28F39A83E63C55B8F30E48723A7579041EC6", - "type": "subkey", - "fingerprint": "A48B 28F3 9A83 E63C 55B8 F30E 4872 3A75 7904 1EC6", - "cipher": "DSA", - "size": 3072, - "certification": false, - "signing": true, - "encryption": false, - "authentication": false, - "timestamp": 1514332912 } ], "userIDs": [ { - "name": "Ben McGinnes", - "comment": null, - "email": "ben@adversary.org" - }, - { - "name": "Ben McGinnes", - "comment": null, - "email": "ben@gnupg.org" + "name": "Danger Mouse", + "comment": "Social: @dm@not.secret.example.com", + "email": "dm@secret.example.net" } ], "keyfiles": [ { - "url": "http://www.adversary.org/ben-key.asc", + "url": "https://agents.secret.example.net/dm-key.asc", "Content-Type", "application/pgp-signature", "summary": "ASCII armored openpgp keyfile, full key" }, { - "url": "http://www.adversary.org/ben-key.gpg", + "url": "https://agents.secret.example.net/dm-key.gpg", "Content-Type", "application/pgp-keys", "summary": "Binary openpgp keyfile, full key" }, { - "url": "http://www.adversary.org/ben-key-clean.asc", + "url": "https://agents.secret.example.net/dm-key-clean.asc", "Content-Type", "application/pgp-signature", "summary": "ASCII armored openpgp keyfile, clean key" }, { - "url": "http://www.adversary.org/ben-key-clean.gpg", + "url": "https://agents.secret.example.net/dm-key-clean.gpg", "Content-Type", "application/pgp-keys", "summary": "Binary openpgp keyfile, clean key" }, { - "url": "http://www.adversary.org/ben-key-min.asc", + "url": "https://agents.secret.example.net/dm-key-min.asc", "Content-Type", "application/pgp-signature", "summary": "ASCII armored openpgp keyfile, minimised key" }, { - "url": "http://www.adversary.org/ben-key-min.gpg", + "url": "https://agents.secret.example.net/dm-key-min.gpg", "Content-Type", "application/pgp-keys", "summary": "Binary openpgp keyfile, minimised key" } ] }, { - "keyblockASCII": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBFAT4bsBEADDsKVDXPxbY88oDXwoNeTQ6KaKxxZ9fE2PGv3dtUBqCX8opuVz\nLaJ19UBuTjiFdgqY+jx2hYBKl026q2btg7Ijhcstbu3HZ3NzxDGk2JGFMUe0WHxC\ndLSf5MuFbCFu17zwCmkT1my9Fcb++0UkwCFnVaKzXB1oS8gnl1Hjr3jbmH8LhUAi\nYXfSIZPbLb+LGxVhEKldUBVlmjbDvbiMFe2c+X2nixA64Vtaqo4q6D78401CQXns\nZ8Z4lA9pXj6sB/4d+zFLtyvSmsq0ccTbmwmw0kk5FYnM7Gn75kCviXQZyT5wt2EE\nDv7zwRgs9Ih009Y4+xyrCt/ks34sWTPFDXhys7h9E0ujCJ65pxOl9pRXo1Mii6SF\n/0a5gHQZwaZ+a2wMoMD7tWw9d1OFNEOKAxv8ZY4Kk4kFp/Nq2Rb9wIVLY8TQhX34\nn9zIEnRwt/BiC9xo/2U+FxKrWTvZieJDNsrETnmRRcwWsfp16RBFUNe6bakSkxZ3\nqbVZesg1qExB9xbfzm00/c4mWr40wfE/UZsJnszzmNUBVtKCJJT5SmwP3xrHAssS\n0SeGhRwqJ+sUCfyjvo8zHCIkRS5CDiJ9Mc8rN3vSJuAf6dxr3NrExrRuMTpO0zaq\n2JPz4CF1Efu1YoggDhSltliRTw+Nhy7JxsIMKWLRimtfjxXDVH18plJ0bQARAQAB\ntCBCZW4gTWNHaW5uZXMgPGJlbkBhZHZlcnNhcnkub3JnPokCfwQTAQoAaQIbAwIe\nAQIXgAIZAQwLCg0JDAgLBwQBAwIHFQoJCAsDAgUWAgMBABYhBNtHJOb6QobJK05V\nxDIeTiNzWQ5dBQJaOjS/JBhoa3BzOi8vaGtwcy5wb29sLnNrcy1rZXlzZXJ2ZXJz\nLm5ldAAKCRAyHk4jc1kOXa/YD/9qnQOd39KlR035Gm9g1lOCCpjiVctZ225LipKb\nPUNtH6aXo4QkFuVaGdkKdHd4YUiAlxD0BGe7WVj8wnRrS0uo4Nt8+wqFmkalXRu/\nExIFuJqPN/UxQpxnQxZRNraohBX4/q/G6OcOcR24lvinbckpaA5cLaaahcaXQgy/\nzGh9vpv15ldbIlFcony4B/cIxBYm9H4AgF4/tl1CK4uC4t7ZeuctXjyPt0XM+fdN\nK9X4xr+Q5LZ+Z8QWMDEzaxLSiZoUxehdlGQprELQDSngjP8PoKcgXzjA9mCxQ7zN\nCuoq+R1OV7fPmtgJxkw5LWvS4CEiIeh37epfBxz0tu0U1iy+Swgzx1cD39ENVoqI\nkaddAy09Vfr8BYWkMFBsLnA7FMCJineaDZV9bu2vBCeGT3zsb5lLUWcJoFqE2gtl\nBKCVBTniMcSCb0O5ztT4R0E/BUfYlVkAJYRUTCytYmilp9Vx6VckFRqECzB34OyD\n3hLCeof/uy4lmU0WSi0bkPgFvyF0jSZvPDwfqPRN9jGRamul9j9UJXgQZWEXsmOr\n/8Lh+Mwhzm5Y3pLns8us8cpEZAl2ykz/aPHYVJ9CvI0a4V9dsil3wod+Ll7iaZHP\nR8CPQHsGDVW7/8tyK2NvXfOhjbnYKWeV7UHrjsd8NmL5UmniwDW/GUnrGGz5z9Ky\nVxq1QrQ7QmVuIE1jR2lubmVzIChiYWNrdXAgZW1haWwgYWRkcmVzcykgPGJlbm1j\nZ2lubmVzQGdtYWlsLmNvbT6JAnwEEwEKAGYCGwMCHgECF4AMCwoNCQwICwcEAQMC\nBxUKCQgLAwIFFgIDAQAWIQTbRyTm+kKGyStOVcQyHk4jc1kOXQUCWjo1HSQYaGtw\nczovL2lwdjQucG9vbC5za3Mta2V5c2VydmVycy5uZXQACgkQMh5OI3NZDl2U6w/8\nDOc2qm3aXr/vcdsLVRTS0cpN9Mz0EOiQVsFqfLHUo90kAUCfVxJu51qILpm7oXwf\nR+MXOSNqLMNQt6/PTjUMedWttVWlHVQTtyRwNSrY+5h2OBJln+VCcatIDLt97pgH\nkeih/PCHFuhOoy08YUutLnara1aSXEQqqvGZcYsZPc1znLgludkIUyfyhbu7umB6\n5BkPEgomBpNUqZ6Z5NNrqQNflI5yNCe0yN93Qfja7YBPafk1OXjumjIP3SjGo9+Z\nkre4A6i88DAxmZQLNsTD4aoqrm5S2NfnoqZXIiJqfAwj+n/LhaT3J8VjheUeOJVx\nMCEzgKaHLTMK0ClcTIpajsPqklBEGzgL8bgU79hbZCOXM7wEz9Kz8YEN2PrblaXp\n5/MfZoTHejfZuwZ1GcsbMCyTumbhLqbwpyHQADPbpgx+gcV587Wty4RzZglIbMu6\nK7r5z6PN32df6chXBS2tdFk2uH8JKHY2eMhCdxZPsPVJn9mOF7EoXLmmpjMqynmj\nsLHD3fFgcZn4DPRoczU+6jfbB29QUsd++plY0j3zhr5iE/+KCwFiDUK3qMgXBbbE\nWSSgnj08AognfdZCslsWrr54WsUD2X5twwfV9iR7JQMs7bq0vfo5zpBTNuskk7N/\nY8gQ/560t4kMdDqIeFtT8cauWcbD6HNfLPF1ara6vrm0LkJlbiBNY0dpbm5lcyA8\nYmVuLm1jZ2lubmVzQHBpcmF0ZXBhcnR5Lm9yZy5hdT6JAnYEEwEKAGACGwMCHgEC\nF4AMCwoNCQwICwcEAQMCBxUKCQgLAwIFFgIDAQAWIQTbRyTm+kKGyStOVcQyHk4j\nc1kOXQUCWjo1WB4YaGtwOi8vcG9vbC5za3Mta2V5c2VydmVycy5uZXQACgkQMh5O\nI3NZDl2qKRAAiZAwfN1WNzx6P9Ts5jtSCt+3zGohZftQ382C5quud6NCKuO9//ql\nuepriQk+5TJ58nXgz8T6BUzDGTTAVh26czsVKw7CEqPHD1psOSFUZV7nW13Z3YJO\ng3oKelg1LfSSKCYlWS1K7eBCT/2Uo/NV/yQfNqLoFYmxQX7u0fzTyLvCfBC6NIrf\nYCQTS77NP3lKpDLLkIyh9pKcOttljKv7uxz1Bpf3ozpfbSKVJaOgm/F8qQQkmtXy\nbu/8N5k5VJCodPFyU7HOiouzUv1hFQeqyZRsdgOILWJbC2r5Y57mMEshgfdBebwU\nYqyjvtRq9DKumQMJwTTGYshqEIgugUpBcqDfl1ZIDtQWyGkr96q5FP6z+48/pFa5\nOEQdFwjL5OPBLOJVLeKoj05XpG5JPPkgxHoQAw+FDZDXN22QYjeZmpOQi4kXb9DK\nAPHnAMk6aDFdVHzPtN/15+jByvhGVb4XttMVhbpOrUwrGOgVaVFVoi/w8mufkF8c\niCCYRSDzJJlC99XLqclISmuhMypzTpEFI5IIConC5oznicXLa8hY8O09HGx0dTr/\nOeteQOg423XIHf0XoERshtZcoACsszQYWGrGG6WCxz9js14VLevfinpSxlTk0MI/\njSuv8ZQACiNO3aDqTo8nzjGR1vATP3lxoJobDdHwCZ9D/0LNFIECDCO0KUJlbiBN\nY0dpbm5lcyA8YmVuLm1jZ2lubmVzQHBpcmF0ZS5vcmcuYXU+iQJbBDABCABFBQJX\naN76Ph0gcGlyYXRlLm9yZy5hdSBubyBsb25nZXIgZm9yd2FyZHMgbWFpbCB0byBw\naXJhdGVwYXJ0eS5vcmcuYXUuAAoJEDIeTiNzWQ5dxKAP/A5KmG+O6g+HK/tCkR3x\ntdLTKwUtF4LGmexzI00cHTNWrrPXKGIsxZM+Bf4+YDls6VhwJFTJBddoE+8WIw4C\nQdtxJp151xkqsZxInjS99ch9OylqcjXTKvHC3myX/cYWnSAXTbS31SgPruUZX5sk\nLTqcd+GfT1S8OzQRwGtPfWVRwvR6IyhoJKG8j6o+OPFfvqEJSTzHkOMYn5pYY6Ji\nIZktthrnKCvStSGNn9QArBKLtZKDuDHHq+dpu8fZngtnrMigwn4a3Sak0lVKh+CU\nUkBPxLzMJYB/4ecKBIGSyY+0NHzEJ58zzNFgk9M/xjhcVzbrzDnBtphtJGeJszu9\nPtwmQIvLbIwa/uDYXKWWYnSE2hMslyGSV0qe/5aOF29PAUXybhy+Bp1iHAjYCMJ7\nGTC8p48wCBVBImyW9DZrZsCAnazewbEZa7mPeUyUpvio+BfGSDm8LnmdzpkMTZi0\nEA+06qvFCOx2IXDBm1Q+HKfsiq4ft5cnCcKNAu5YtKELoh3dT9+smhMJYkqpJJqK\nUWdQZu1abxFok9W4hHEBQHYbBZlVfZydOeCRZs4tqMHxQk3kFYJtalWWnUrfJaG5\nIDrEPju4T5njOh98S3aRwlFCtUDz94rinRRAzgK5+8nB84lkUNrm6VE/nNa5RkC6\nAY0mAyooRF89BpFbHVTJE3REtCtrZXliYXNlLmlvL2FkdmVyc2FyeSA8YWR2ZXJz\nYXJ5QGtleWJhc2UuaW8+iQJ8BBMBCgBmAhsDAh4BAheADAsKDQkMCAsHBAEDAgcV\nCgkICwMCBRYCAwEAFiEE20ck5vpChskrTlXEMh5OI3NZDl0FAlo6NX0kGGh0dHA6\nLy9pcHY0LnBvb2wuc2tzLWtleXNlcnZlcnMubmV0AAoJEDIeTiNzWQ5d1YwP/1CR\nc8GFMNyu3wypeUW/+DTzEhUigtdHx1e+XO+CkouhIHbXHlIoIZjuKOxoaAxaCXo3\nW24HE4N9BCp7NE2aJ2vIWnvzNiv1YDxBnUx/+kUzuLIUSVGNjqhN+bV8MZ4uix+m\nc3WaN36BX6FF7lzavQ6C54cijl0HRc77Scyw/OdlOBtviNCB6Lr7hBHMIEyCUn5E\n4fIyZz1SZDzL9ZZL2IUhSFZAmm6Ff6yqd0uQVLmXyS++lGpuWrIPxtYGPWA0W8GQ\nmQUrOn8EhPz/Z2oVMoAcZfEElRXftf96FG+kCps+WVpSgixzrZIgTQMVDB1SqQRC\n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\nuQ==\n=P42o\n-----END PGP PUBLIC KEY BLOCK-----\n" + "keyblockASCII": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmDMEXCaxhxYJKwYBBAHaRw8BAQdAMSVyt57XCqdve8pvgC4BDkj+BYq6xKlsdMua\nIYiKl+y0SURhbmdlciBNb3VzZSAoU29jaWFsOiBAZG1Abm90LnNlY3JldC5leGFt\ncGxlLmNvbSkgPGRtQHNlY3JldC5leGFtcGxlLm5ldD6ImQQTFgoAQRYhBML6QP16\nLm3bek/fyxp0JaIlw+8fBQJcJrGHAhsDDAsKDQkMCAsHBAEDAgcVCgkICwMCBRYC\nAwEAAh4BAheAAAoJEBp0JaIlw+8fR0wBAOLXF7eYegcI4w21BsceE669hpwHBl6b\n5G5/dJQObkSkAP0Vdx7+CyIMJwAqDesQtnUKrxLp1TEsR3FWXmPO5fAvB7g4BFwm\nsgsSCisGAQQBl1UBBQEBB0AyMCTt0r9Gvth5whz4ED8znHo9KqR0AVjftlG86xe0\nLgMBCAeIeAQYFgoAIBYhBML6QP16Lm3bek/fyxp0JaIlw+8fBQJcJrILAhsMAAoJ\nEBp0JaIlw+8fRoQBANjV8BrkS0EzIcQpG8xgsfQESYGsj/B59h9QdL7eS6q5AP9V\nV/6JC2wBwzL38B4accNW/lNPDAMfS3LgqvQnAfgeDbgzBFwmsjUWCSsGAQQB2kcP\nAQEHQLiOaYOPCSEIc1SLk1dM/XbTr5+bIl1DPduKbl2aWsaTiO8EGBYKACAWIQTC\n+kD9ei5t23pP38sadCWiJcPvHwUCXCayNQIbAgCBCRAadCWiJcPvH3YgBBkWCgAd\nFiEEZd86OBTTutxefWj0jYfEQYNH8rsFAlwmsjUACgkQjYfEQYNH8rtiewEAp+wJ\nvMc3Qq8hv372nNVdzE7TySjvJpy05DmtPcbAZ4UBAMrpR6MadshSM7NZvlBAyhPl\n7YmogPQ2N28Ja3kX8l4GIMYBAKRzQtRVH+NlOA0tvPO2wcBYXJhSQF0k/S8EnzZu\nYMmwAP4h+e4ytRt5yUupjFRM+S4OY7rMRTAY0eeu8rJwBeLrAw==\n=0Eei\n-----END PGP PUBLIC KEY BLOCK-----\n" } ] } ] } #+END_SRC Note the main =timestamp= is the date the key itself was last modified and will usually match the timestamp of the last subkey to be added or the timestamp of the most recent self-certification of a key. Whereas the =lastUpdated= property notes the last time the copy of the public key was updated on the server serving that data. Such an update *should* normally be the result of a client uploading the key to the actor account, but *may* be the result of the server refreshing key -data from the SKS keyserver network. +data from the SKS keyserver network or the Web Key Directory service. + + +*** Serving Public Keys Via WebFinger + :PROPERTIES: + :CUSTOM_ID: crypto-keyserv-webfinger + :END: + +An alternative approach to using the =openpgpkeys.json= file defined +in the previous section is to instead direct key retrieval traffic to +the existing [[https://webfinger.net/][WebFinger]] service utilised by ActivityPub and [[https://datatracker.ietf.org/doc/rfc7033/][defined]] in +[[https://tools.ietf.org/html/rfc7033][RFC 7033]]. + +In that case this part of the specification: + +#+BEGIN_SRC html + The keyinfo item must contain + the publicKeys property pointing to a JSON encoded URL + containing at least the minimised version of the public key. + Alternatively the publicKeys property may point to + an array in which the first item is the JSON encoded URL containing + key material. The subsequent items in such an array may point + to either or both of URLs or URIs for accessing the keys via WebFinger + or via the Web Key Directory. +#+END_SRC + +Would need to be modified slightly to something more akin to this: + +#+BEGIN_SRC html + The keyinfo item must contain + the publicKeys property pointing to a JSON encoded + WebFinger URL containing links to the relevant OpenPGP key or keys + associated with the account. Alternatively the publicKeys + property may point to an array in which the first item is the + WebFinger URL. The subsequent items in such an array may point + to either or both of URLs or URIs for accessing the keys directly or + via the Web Key Directory. +#+END_SRC + +As this transport protocol is ultimately driven by HTTP/S traffic, it +does not matter so much if the distribution of key data occurs in a +binary format (e.g. =.pgp=, =.gpg= and =.sig= files). As a +consequence there is less need to serve Radix64 encoded versions of +those binary formats (e.g. =.asc= files) for key distribution. + +As the WebFinger specification already utilises existing [[http://microformats.org/wiki/existing-rel-values][rel values]] +and as there is already a =pgpkey= value specifically serving OpenPGP +key data, leveraging this here ought to be fairly straight forward. + +All the WebFinger service requires is a means of identifying each key +and possibly subkeys, along with accessing those keys. Both of which +are simple enough to deliver with a URL for a key file and the +fingerprint(s) of the keys and subkeys. + +Utilising the WebFinger specification here provides the additional +advantage that other, otherwise unrelated, services or software may +benefit from accessing these OpenPGP keys and subsequently enhancing +privacy features. + + +*** Serving Public Keys Via Web Key Directory + :PROPERTIES: + :CUSTOM_ID: crypto-keyserv-wkd + :END: + +An alternative to both serving key data directly and linking to keys +via the WebFinger service is to incorporate the Web Key Directory +service into the specification. + +In that case this part of the specification: + +#+BEGIN_SRC html + The keyinfo item must contain + the publicKeys property pointing to a JSON encoded URL + containing at least the minimised version of the public key. + Alternatively the publicKeys property may point to + an array in which the first item is the JSON encoded URL containing + key material. The subsequent items in such an array may point + to either or both of URLs or URIs for accessing the keys via WebFinger + or via the Web Key Directory. +#+END_SRC + +Would need to be modified slightly to something more like this: + +#+BEGIN_SRC html + The keyinfo item must contain + the publicKeys property pointing to a Well Known URI + matching the Web Key Directory format and which links to a key or keys + associated with the account. Alternatively + the publicKeys property may point to an array in + which the first item is the Web Key Directory URI. The subsequent + items in such an array may point to either or both of URLs or + URIs for accessing the keys directly, or the URL of a JSON encoded + WebFinger file. +#+END_SRC + +Though the Web Key Directory service may very well prove to be the +ultimate replacement for the SKS keyserver network, it is not yet a +finalised specification. As a consequence it is currently recommended +as an *optional* supplementary key discovery method. ** Signatures :PROPERTIES: :CUSTOM_ID: crypto-signing :END: Signing activities as a means of providing assurance that they genuinely originate with the client and have not been modified in transit will probably be one of the most common uses of these functions. There are, however, issues with the possibility that a server may render the content differently to the author's system or sanitize the content in an unexpected manner. Also the author might use another content format (e.g. Markdown) which is intended to be rendered into HTML by the server. The solution to this problem is a new object type, the Signed Note. A Signed Note *must* contain a =source= property containing the original data transmitted, even if the mediaType is =text/html= as the -server may still render it differently. +server might still render it differently. A Signed Note *must* contain a =signatures= property which *must* specify the protocol and *must* include a detached signature file for the source data. The =scope= property specifies which source properties were signed, usually this should only be the subject and content or just the content. The =signatures= property *may* include a signature for the expected rendered output. As with the source signature, the =scope= property specifies which rendered output properties were signed. Since the order will matter with regards to the =scope= a =signedData= property must be included with with each signature. This is followed by the detached =signature= in ASCII armored (radix64) format and some additional data pertaining to the key or subkey used to sign the data as =signingKeyID=, the algorithms used as the =pubkeyAlgorithm= and the digital =hashAlgorithm=, and the =timestamp= of the signature. It *should* be possible for anyone with the Signed Note object to take the signedData and the detached signature, save them both to files and -then manually verify them with OpenPGP compliant software (e.g. =gpg=, +then manually verify them with OpenPGP compliant software (e.g. =gpg= or =gpg.exe=). #+BEGIN_SRC javascript - { - "@context": ["https://www.w3.org/ns/activitystreams", - { "@language": "en" } ], - "type": "Signed Note", - "id": "http://snuffy.adversary.org/posted/thing", - "subject": "GnuPG rocks", - "content": "

So, what should be signed, what was written or what was rendered?

", - "source": { - "subject": "GnuPG rocks", - "content": "So, what *should* be signed, what was written or what was rendered?", - "mediaType": "text/markdown" - }, - "signatures": { - "cryptographic-protocol": "openpgp", - { - "scope": { "source": ["subject", "content"] }, - "signedData": "GnuPG rocksSo, what *should* be signed, what was written or what was rendered?", - "signature": "-----BEGIN PGP SIGNATURE-----\n\niHUEABEKAB0WIQSkiyjzmoPmPFW48w5Icjp1eQQexgUCWuVpjAAKCRBIcjp1eQQe\nxhXcAP0e5qTuD4wO+fyL+0djvoAmZtPAzg4zyf5Tn5dZZVzOhAEA4B1I7ApWHpTr\nIJ0SwT/wy0vc5guSt/gru7SLANnBZGI=\n=fwud\n-----END PGP SIGNATURE-----\n", - "signingKeyID": "A48B28F39A83E63C55B8F30E48723A7579041EC6", - "pubkeyAlgorithm": "DSA", - "hashAlgorithm": "SHA512", - "timestamp": 1524984204 - }, - { - "scope": { "expectedRender": ["subject", "content"] }, - "signedData": "GnuPG rocks

So, what should be signed, what was written or what was rendered?

", - "signature": "-----BEGIN PGP SIGNATURE-----\n\niHUEABEKAB0WIQSkiyjzmoPmPFW48w5Icjp1eQQexgUCWuVsKQAKCRBIcjp1eQQe\nxoYFAP4oOZSYXTAKd673B4PqZQp47kdYxRUfR7tdKBh8qV2YVgEA8m+/foWZO9xy\nm9v3zzeI/BYpGCeKZ7eqe29exQpvKds=\n=FDKU\n-----END PGP SIGNATURE-----\n", - "signingKeyID": "A48B28F39A83E63C55B8F30E48723A7579041EC6", - "pubkeyAlgorithm": "DSA", - "hashAlgorithm": "SHA512", - "timestamp": 1524984204 - } - } - } + { + "@context": ["https://www.w3.org/ns/activitystreams", + { "@language": "en" } ], + "type": "Signed Note", + "id": "https://not.secret.example.com/agents/dm/posted/thing", + "subject": "GnuPG rocks", + "content": "

So, what should be signed, what was written or what was rendered?

", + "source": { + encryption "subject": "GnuPG rocks", + "content": "So, what *should* be signed, what was written or what was rendered?", + "mediaType": "text/markdown" + }, + "signatures": { + "cryptographic-protocol": "openpgp", + { + "scope": { "source": ["subject", "content"] }, + "signedData": "GnuPG rocksSo, what *should* be signed, what was written or what was rendered?", + "signature": "-----BEGIN PGP SIGNATURE-----\n\niHUEABYIAB0WIQRl3zo4FNO63F59aPSNh8RBg0fyuwUCXCl4HgAKCRCNh8RBg0fy\nu6fZAQDqCKlaQRmIBdZgoHmMHDBU6KO/vw6iW5q/PYKChBM5dwEAv5UPYNY33mKh\n/CFvwLnZ0j+pVGgsuEidp5J1zk5JgA0=\n=xHh0\n-----END PGP SIGNATURE-----\n", + "signingKeyID": "65DF3A3814D3BADC5E7D68F48D87C4418347F2BB", + "pubkeyAlgorithm": "EDDSA", + "hashAlgorithm": "SHA256", + "timestamp": 1546221598 + }, + { + "scope": { "expectedRender": ["subject", "content"] }, + "signedData": "GnuPG rocks

So, what should be signed, what was written or what was rendered?

", + "signature": "-----BEGIN PGP SIGNATURE-----\n\niHUEABYIAB0WIQRl3zo4FNO63F59aPSNh8RBg0fyuwUCXC6NDQAKCRCNh8RBg0fy\nuyH6AQDOD7QfcYfPx6xpHKRsv6SzDijNXOS3vq1qaIYRkY/a/AEAyvn6uwRSJ1L5\nKEEKIvWhFsJoFJf0RCIraxoNlyWnvQ0=\n=Qea9\n-----END PGP SIGNATURE-----\n", + "signingKeyID": "65DF3A3814D3BADC5E7D68F48D87C4418347F2BB", + "pubkeyAlgorithm": "EDDSA", + "hashAlgorithm": "SHA256", + "timestamp": 1546554637 + } + } + } #+END_SRC ** Encryption :PROPERTIES: :CUSTOM_ID: crypto-encryption :END: Encrypting activity content or content and subjects will meet the needs of many feature requests on numerous instances. There are, however, some variations of methods which may be worth examining, along with issues pertaining to availability of metadata and what options, if any, exist for providing any measure of forward secrecy. There are multiple issues to be addressed when dealing with encrypted activities, objects or portions of either. Some of these issues relate to whether the ciphertext contains additional embedded JSON data to be interpreted or rendered by the recipient upon decryption, while others relate more to the addressing or total number of recipients or how to treat data when not all the intended recipients have a public ky available. Still, one problem it readily solves is in providing end-to-end encrypted messages between two single actors. *** Encrypted Private Messages :PROPERTIES: :CUSTOM_ID: crypto-encryption-privmsg :END: There are essentially two methods of sending an encrypted private message: one in which the encrypted content is just the message being sent, which *may* contain content or markup intended to be parsed or rendered at the recipient's end; and the other being when the encrypted content contains embedded JSON data matching the Activity -Streams 2.0 specification and possibly the ActivityPub specificationto -be interpreted by software at the recipient's end. +Streams 2.0 specification and possibly the ActivityPub specification +to be interpreted by software at the recipient's end. Regardless of which it is, the sending of it requires another new AP object, the Encrypted Note. The Encrypted Note *must* contain an =encrypted= property. -Thw =encrypted= property *may* contain a =subject= property. +The =encrypted= property *may* contain a =subject= property. -Thw =encrypted= property *must* contain a =content= property in which -then encrypted data is inserted in radix64 ASCII armored format. +The =encrypted= property *must* contain a =content= property in which +the encrypted data is inserted in radix64 ASCII armored format. -Thw =encrypted= property *should* contain a =mediaType= property with +The =encrypted= property *should* contain a =mediaType= property with a value of =application/pgp-encrypted= or =application/pgp-encrypted+activitystreams=. -Thw =encrypted= property *may* contain a =signingKeyID= property +The =encrypted= property *may* contain a =signingKeyID= property containing the =id= of the key used to sign the encrypted content, if any. Alternatively the =signingKeyID= property *may* be an array of multiple keys or subkeys if more than one key was used to sign the data. -Thw =encrypted= property *may* contain a =recipientKeyIDs= property +The =encrypted= property *may* contain a =recipientKeyIDs= property containing an array of the key IDs to which the encrypted data has been encrypted. If the recipients have been hidden then the =recipientKeyIDs= property *may* be excluded or explicitly set to either =null= or /*hidden*/. -Thw =encrypted= property *must* contain a =cipher= property with a +The =encrypted= property *must* contain a =cipher= property with a value of the symmetric cipher used to encrypt the =content= data. -Thw =encrypted= property *must* contain an =encryptedAlgorithm= +The =encrypted= property *must* contain an =encryptedAlgorithm= property containing a value of the asymmetric encryption or elliptic curve algorithms of the =recipientKeyIDs=. If there multiple algorithms then this data *must* be included in an array. This requirement remains even if the =recipientKeyIDs= property is =null= or /*hidden*/. -Thw =encrypted= property *may* contain a =hash= property with a value +The =encrypted= property *may* contain a =hash= property with a value of the hash digest algorithm used to sign the =content= data, if any. -Thw =encrypted= property *may* contain a =signingAlgorithm= property +The =encrypted= property *may* contain a =signingAlgorithm= property with a value of the digital signature algorithm of the key used to sign the =content= data. If multiple keys were used to sign the data and those keys used different signing algorithms then this *may* be an array containing each algorithm. -Thw =encrypted= property *should* contain a =timestamp=, except where +The =encrypted= property *should* contain a =timestamp=, except where enough of the data regarding the encrypted =content= does not include an actual timestamp. The following example is about as simple as it gets. The =content= is encrypted and signed, in this case simply containing a small Markdown -text file.[fn:5] +text file.[fn:4] #+BEGIN_SRC javascript { "@context": ["https://www.w3.org/ns/activitystreams", - { "@language": "en-AU" } ], + { "@language": "en-GB" } ], "type": "Encrypted Note", - "id": "http://snuffy.adversary.org/posted/encrypted-thing", - "to": "http://snuffy.adversary.org/inbox", + "id": "https://not.secret.example.com/agents/dm/posted/encrypted-thing", + "to": "https://not.secret.example.com/agents/dm/inbox", "subject": "Secret Message", "cryptographic-protocol": "openpgp", "encrypted": { "subject": "Secret Message", - "content": "-----BEGIN PGP MESSAGE-----\n\n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\nBzIvDuNDNcYV\n=elBL\n-----END PGP MESSAGE-----\n", + "content": "-----BEGIN PGP MESSAGE-----\n\nhF4DSD9CPjLdeagSAQdAqdWMriKCydTELA/6Rn0V6v0iCx2tTz4qFzvl0iutjWMw\nl8OJnLw+5xy0aUEr17PujJCnrcI8hUVxarZHZSOILLjLLVtWjI5LB3YuSepP0Iav\n0sEsARd02MNCp32Eyj8X1vFEsf8pvWxPe0ojrZ9afwjWF6ZIYpOHoiYPZc/za3Gf\nJGeyDyZ+FJMDkP5TnJsME9K6vqF+fZnwP4m2K1HoPOMH1pCqH4jI54IMy06c4ZUx\nLh7zPrOmfcdFMSBQ4jVxw/hDaeLUaPw7J1bE21jd9dTuK8Nn6q1zteI0hmw9d6t7\nQYHw7CwNI3dsrU5y1YiHs7PoEZO2W1qqoykvOFeNzkx8RmkbNUPy1LULFiDED+Y+\nDrFYPH9Xpfaqp4SqV+kE/zL7T/edftL/ZCDmRNwzoCUcvUkg6MMTfmiTZglZ5O/k\nzFn74RTmrGjXDnQv7iikP+urs41bJvOzBKYRGfRFQ08GRgZR6HJS19NrdLiB8M9I\njHQZG2fpDpNKNByx3gfXwSCXEhpurYh7m4ssK80KFXdWKRpECTN0qXj5B9LFcok8\nD1GSdX0WvKIarvtyKDxaaruAS6gVD59QODELpDnK6sKHuP4mkX34D9zKpV/yJqMb\nMNiNlNnBvQF/9cp+wyVpA5BW5WlkqWKOgev+V7z0DuPkBHrsilAZOCFplaiVU//m\nmErPTT6FeHSP9U5iPXTKq6vkDnDnUkNEHLIR8LgUvVvQLvGHZXWqxQpMXOcMmiyd\n7rlVFL4CRXYaLlhfYH2c\n=OIPC\n-----END PGP MESSAGE-----\n", "mediaType": "application/pgp-encrypted", - "signingKeyID": "A48B28F39A83E63C55B8F30E48723A7579041EC6", - "recipientKeyIDs": [ "9CBEF6B7E0DF72CF91009AA5C98BAA1862E4484D" ], + "signingKeyID": "65DF3A3814D3BADC5E7D68F48D87C4418347F2BB", + "recipientKeyIDs": [ "681CBF37BE8ED04CB20BD5D0483F423E32DD79A8" ], "cipher": "TWOFISH", - "encryptionAlgorithm": "ELG", + "encryptionAlgorithm": "EDDSA", "hash": "SHA512", - "signingAlgorithm": "DSA", - "timestamp": 1524996957 + "signingAlgorithm": "ECDH", + "timestamp": 1546206334 } } #+END_SRC A more complete and possibly more effective method, however, is in the following example. Like the preceding one, the Encrypted Note object contains OpenPGP encrypted data in the =content= property. A =summary= is optional and *may* indicate that the content is encrypted if the Encrypted Note is being posted publicly (see next section). The encrypted data, however is an entire ActivityPub object including source format which may be rendered by a recipient's software and -which *may* include a Signed Note as described above.[fn:6] +which *may* include a Signed Note as described above.[fn:5] #+BEGIN_SRC javascript - { - "@context": ["https://www.w3.org/ns/activitystreams", - { "@language": "en-AU" } ], - "type": "Encrypted Note", - "id": "http://snuffy.adversary.org/posted/encrypted-thing", - "to": "http://snuffy.adversary.org/inbox", - "cryptographic-protocol": "openpgp", - "encrypted": { - "content": "-----BEGIN PGP MESSAGE-----\n\n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\nO8rHVVfv5pA7bk3Fqy39QZz2OgR0PExy\n=DCuG\n-----END PGP MESSAGE-----\n", - "mediaType": "application/pgp-encrypted+activitystreams", - "signingKeyID": null, - "recipientKeyIDs": [ "9CBEF6B7E0DF72CF91009AA5C98BAA1862E4484D" ], - "cipher": "TWOFISH", - "encryptionAlgorithm": "ELG", - "timestamp": None - } - } + { + "@context": ["https://www.w3.org/ns/activitystreams", + { "@language": "en-GB" } ], + "type": "Encrypted Note", + "id": "https://not.secret.example.com/agents/dm/posted/encrypted-thing", + "to": "https://not.secret.example.com/agents/dm/inbox", + "cryptographic-protocol": "openpgp", + "encrypted": { + "content": "-----BEGIN PGP MESSAGE-----\n\nhF4DSD9CPjLdeagSAQdAaR4vYSrOenqGK3sM0V3rGLJtRCcPb3NTpf1/yuNQLy0w\nHRirczb52+WarwgcbJXpnslVOyFNJnHnJ8fi6G++w98ZNycf7UrOPTbu/EoINPom\n0ukB1CC4aelHjhE90SosjP/wosrn7YzZxm3QUDu/kR2y6um1v/gIghpBlTHWovK9\nXJMd7c0JGSxtEqHoJAUlTXsRZn7CYMGHTJ1W+In4uc1rZb5aHNv+iHzKLBCylfsO\n0VsHJ6MET74FO40iWYjlfReoPP08n9x8Q2J/6RuuCDLbYKPX3W2VD2Gv4tASRCW8\nXJuv9knMCnbV4yUD0EAn2ZmJSH9LbBSiJUT5yBEmUqgme09EiuPxP8/uRmCf03+n\nab5S1yjR5xKUfGHhSs2MJZqKLP0xKmClgZIA3PYnPyHLtlzASn6EhZ9PZ0d2DFrA\n5uIKdTpuly0esfCWjCjMH+S7W85Zk3ne7Qk4ZOsuejj8Z+HHAjKMVBAlAZ0gFU4G\nJGvM9U0Hs84vFLcNShdY+KixTL1yxMT4nom9ch9vKZszT9KBFfTxFZP9JAeO2Xam\n1hbKCL7uo+xKLdGCD38X3FTOtQNAFohpffzb5aQqLRb5+GSO720Dkhn6/RwjCfpB\n4+PJiz8jnlVzdMPOb2QumfjF4BOAGK3L9L0wIdszelwP7WrIFrUHh0BwwHOM7F0e\nPHTFj5nxE+BZ7KO3EHcqR0oTokUjQY/oNm2W3rZr8ZtZCsWNMr5BDGN4yMBxOrQq\nnwe+kzys9bAR+u683DzPE6K7e8uyy4Fs+irZQO1AKC7Z1QA=\n=Kxtt\n-----END PGP MESSAGE-----\n", + "mediaType": "application/pgp-encrypted+activitystreams", + "signingKeyID": null, + "recipientKeyIDs": [ "C2FA40FD7A2E6DDB7A4FDFCB1A7425A225C3EF1F", + "681CBF37BE8ED04CB20BD5D0483F423E32DD79A8" ], + "cipher": "TWOFISH", + "encryptionAlgorithm": "ECDH", + "timestamp": null + } + } #+END_SRC This second method of encrypting ActivityPub or Activity Streams data would enable providing signed information without revealing publicly which key actually signed the that data except to the intended recipient(s). *** Encrypted Public Messages :PROPERTIES: :CUSTOM_ID: crypto-encryption-pubmsg :END: It would be possible to post an encrypted message publicly, but in which the recipients' key IDs were hidden using any of the =hidden-recipient= (=-R=), =hidden-encrypt-to= or =throw-keyids= options available when using GPG. For such messages the second of the two options in the previous section is likely to be the most useful, but it could be used with the first. This would enable the use of a public stream of objects and activities as a “dead drop” as a means of providing anonymous or pseudonymous communication with any other party and without requiring a means by which that party might be directly identified by others. ** Authentication :PROPERTIES: :CUSTOM_ID: crypto-auth :END: There are multiple methods by which OpenPGP keys could be employed to provide authentication services between a client and server, In particular as an alternative to using passwords or two-factor authentication when used in conjunction with OAuth tokens for sessions. These methods have the additional advantage of providing a means by which a remote server could confirm the identity of a user of another server without requiring the transfer of any sensitive or secure data between the two servers. For the most part this advantage stems from confirming a status is signed by the same key as used on that remote server, but it could also be used to directly authenticate in order to access any private messages of a local user intended for that user and in the local user's ActivityPub outbox. *** Authentication With Signing Keys :PROPERTIES: :CUSTOM_ID: crypto-auth-sign :END: Utilising signing keys or subkeys would enable a means of authentication with a server without requiring an ongoing session between the client and the server. This could be used to facilitate a secure update or activity even across an insecure connection without compromising the security of the account itself as the server would be able to determine the authenticity of the activity and any relevant objects by verifying the signature alone. *** Authentication With Encryption Keys :PROPERTIES: :CUSTOM_ID: crypto-auth-encrypt :END: Utilising encryption subkeys would enable a means of establishing a secure session's token exchange which does not rely on the transmission of a password, two-factor authentication or other API key, as is most commonly utilised. Instead the server simply issues the token for that session in an encrypted format. Since only an authorised user or client with control of the OpenPGP key could decrypt the data and obtain the token. *** Authentication With Authentication Keys :PROPERTIES: :CUSTOM_ID: crypto-auth-squared :END: OpenPGP authentication keys or subkeys are intended for use with protocols like SSH or other remote access. In spite of the name they may be less useful in this use case. Nevertheless, it would be possible to configure a server to accept connections utilising an authentication key or subkey to establish an authorised connection from the client to the server. * Additional Technical Notes :PROPERTIES: :CUSTOM_ID: tech :END: ** Data size limitations :PROPERTIES: :CUSTOM_ID: tech-size :END: -Since the conversion of encrypted binary data in the GnuPG format to +Since the conversion of encrypted binary data in the OpenPGP format to radix64 encoded ASCII text generally adds to the size of the output data, determined according to both the size of the original input data and the size of the keys to which that data is encrypted, the maximum message size *should not* be arbitrarily limited in the same way that many ActivityPub objects are limited. The common limitation of five hundred characters per status to be found with many Mastodon servers, -for instance, would severly hamper the ability to usefully employ any +for instance, would severely hamper the ability to usefully employ any of these options. ** Metadata and Forward Secrecy :PROPERTIES: :CUSTOM_ID: tech-metadata :END: The nature of ActivityPub and Activity Streams 2.0 data is such that there is an inherent leakage of metadata with each object and activity posted to a stream. As a consequence there are certain limitations on what can or should be concealed. There are, however, methods of mitigating that leakage. A good example being the second message encryption method described above. Forward secrecy is a little more difficult with a messaging format like this, even where it appears to be a stream to an end user. This is due to each object being separate packages in that stream rather than the data being transmitted as a single encrypted session originating with the author and ending with the recipient in real time. Even in those circumstances in which the overall communication (e.g. a conversation) does occur in real time or near real time. Nevertheless, between using OpenPGP keys with pseudonymous identifiers linked to the ActivityPub stream end points and minimising the amount of data revealed by encrypted content, there are points which can facilitate this process. In many respects this could be done in a manner not too dissimilar to the use of anonymous remailers and posts to the old =alt.anonymous.messages= USENET news group. * References :PROPERTIES: :CUSTOM_ID: refs :END: TBA. ** Normative References :PROPERTIES: :CUSTOM_ID: refs-norm :END: ** Non-Normative References :PROPERTIES: :CUSTOM_ID: refs-non-norm :END: ** Informative References :PROPERTIES: :CUSTOM_ID: refs-inform :END: -* About this Document - :PROPERTIES: - :CUSTOM_ID: about - :END: - - -** Authors - :PROPERTIES: - :CUSTOM_ID: about-authors - :END: - - -*** Ben McGinnes - :PROPERTIES: - :CUSTOM_ID: about-authors-ben - :END: - -/Et in arcadia ego .../ - - -** Contributors - :PROPERTIES: - :CUSTOM_ID: about-contribution - :END: - - -*** Wiktor Kwapisiewicz - :PROPERTIES: - :CUSTOM_ID: about-conspirators-wik - :END: - -Wiktor is co-conspirator no. 1, providing valuable suggestions and -proofreading from the first draft onward. He runs his own ActivityPub -node at [[https://metacode.biz/][metacode.biz]]. - - -*** The AS2 and AP designers - :PROPERTIES: - :CUSTOM_ID: about-contributors-as2-ap - :END: - -As this proposl is built on existing work, it is pretty obvious that -each and every one of the authors of both Activity Streams 2.0 and -ActivityPub have most definitely contributed to this proposed -extension of them. - -Also, they were all really cool and welcoming of the first draft when -I finally sent it through to them. - - -*** Assembly Four aka Switter - :PROPERTIES: - :CUSTOM_ID: about-contributors-assembly4 - :END: - -The technical staff at AssemblyFour were invited into the initial -review group shortly following the initial overture to the AS2 and AP -authors. As their work was one of the principal reasons for needing -something like this, it was appropriate to bring them into the -discussion early on. - - -*** Eugen Rochko - :PROPERTIES: - :CUSTOM_ID: about-contributors-gargron - :END: - -Creator of Mastodon and thus will be at the forefront of implementing -this proposal if it is accepted. - - -*** Lain Soykaf - :PROPERTIES: - :CUSTOM_ID: about-contributors-lain - :END: - -Creator of Pleroma and thus will be implementing this right along side -Eugen. - - -** Thanks - :PROPERTIES: - :CUSTOM_ID: about-thanks - :END: - - -*** Switter - :PROPERTIES: - :CUSTOM_ID: about-thanks-switter - :END: - -So not only was [[https://switter.at/][Switter]] and the censorship it has faced since -[[https://twitter.com/realDonaldTrump][Trumplestiltskin]] signed the merged FOSTA-SESTA into law, letting his -Vice President launch a moral crusade against women and minorities; -but the overworked founders of it have been willing to share a little -more of their experiences during the course of my work. - -Much of this affected both the scope of the draft and some additional -or incidental aspects of my regular work on GPGME. - - * Copyright and Licensing :PROPERTIES: - :CUSTOM_ID: copyright-and-licensing + :CUSTOM_ID: copyright-and-license :END: ** Copyright :PROPERTIES: :CUSTOM_ID: copyright :END: -Copyright © Benjamin D. McGinnes, 2018. +Copyright © Benjamin D. McGinnes, 2018, 2019. -Copyright © The GnuPG Project, 2018. +Copyright © The GnuPG Hackers, 2018. ** Licensing :PROPERTIES: :CUSTOM_ID: license :END: This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * Footnotes [fn:1] As a point of comparison, the author's current public key in ASCII armored format with all the web-of-trust signatures included is approximately 100KB in size, whereas the same key exported in its most minimal and concise form is approximately 13KB. Most keys will be smaller than that (the author's key is a 4Kb RSA certification and signing primary key with a 3Kb RSA signing subkey, a 4Kb El-Gamal encryption subkey and a 3Kb DSA2 signing subkey). Note that a future draft of this protocol extension may shift the key distribution method to utilise the proposed [[https://datatracker.ietf.org/doc/draft-koch-openpgp-webkey-service/?include_text=1][OpenPGP Web Key Directory]] protocol; which would meet all the requirements of this protocol along with very fine tuned user ID control with key distribution. At the -current time adoption of the Web Key Directory service is limited. - -Alternatively, even if keeping all the existing key sharing data -(including the key itself), the =openpgpKeys.json= file may be moved -out to become a component (within its own =rel= parameter) of the -[[https://www.rfc-editor.org/info/rfc7033][WebFinger]] protocol. This has the added advantage of letting non AS2 -protocols utilise the key data. Should this option be taken, it is -likely that the key data will simply be referenced as local files in -either or both of the binary and ASCII armoured formats. +current time, however, adoption of the Web Key Directory service is +limited and its protocol design is not finalised. [fn:2] As the example suggests, the example is heavily based on the current state of the GnuPG Project. As this is a fictional thing which may become real in the future, it's necessary to stress that such a project *must* be both free and permissive in its licensing. To choose only free (e.g. GPL and/or Affero GPL only) means to sacrifice other people's security/lives for one's own political beliefs, while to choose only permissive (e.g. BSD and/or Apache and/or proprietary only) means to sacrifice other people's security/lives for profit. If any reading this have ever wondered why the GnuPG Project hasn't moved away from its dual licensing under the GPLv2+ (free) and the LGPLv2.1+ (permissive), this is why. -[fn:3] Named after the Woolly Mammoth character in /Sesame Street/, of -course, and who was originally believed to be Big Bird's imaginary -friend. - -[fn:4] Since an actor contact email address may be different from any +[fn:3] Since an actor contact email address may be different from any of the user IDs listed on the public key, servers should be configured with their own means of matching key IDs to email addresses. In GnuPG this is what the =group= option is used for and various MUAs have their own solutions (e.g. Enigmail's Per-Recipient Record and Mutt's =crypt-hook=). It is also *recommended* that servers automatically encrypt such notifications with the =trust model= set to /*always*/, otherwise the server will need to be configured with its own key which signs or locally signs all the keys uploaded by clients. -[fn:5] The session key for the encrypted message in this example is: -10:CAADC2A355B8DFA2798CCC42386544DDE490EBDFA12CFD663197EBAA61460879 +[fn:4] The session key for the encrypted message in this example is: +10:E877FC8B0CB0B69F15A3397E3A9CD00419A3F47795469A973A841BE0388F8BA0 -[fn:6] The session key for the second encrypted message example is: -10:63A611B7B935B654100104F057BBF3B76D725AFCE45AFB83623A9C480DAED732 +[fn:5] The session key for the second encrypted message example is: +10:9A4CAAFD053E45B9895C9C882AC24D51C4810E1F6F7834DDFB29DE3EB5ABB083 diff --git a/misc/w3c/as2/supplemental/61FB2CD43A34ABAA694C88423106EAD5B7F5BA40.key b/misc/w3c/as2/supplemental/61FB2CD43A34ABAA694C88423106EAD5B7F5BA40.key new file mode 100644 index 0000000..ecf0b4e Binary files /dev/null and b/misc/w3c/as2/supplemental/61FB2CD43A34ABAA694C88423106EAD5B7F5BA40.key differ diff --git a/misc/w3c/as2/supplemental/E1BE2B69D1B893B8600A1E7F7B3B23A280A20A7D.key b/misc/w3c/as2/supplemental/E1BE2B69D1B893B8600A1E7F7B3B23A280A20A7D.key new file mode 100644 index 0000000..421a7a2 --- /dev/null +++ b/misc/w3c/as2/supplemental/E1BE2B69D1B893B8600A1E7F7B3B23A280A20A7D.key @@ -0,0 +1 @@ +(21:protected-private-key(3:ecc(5:curve10:Curve25519)(5:flags9:djb-tweak)(1:q33:@20$ҿFy?3z=*tX߶Q.)(9:protected25:openpgp-s2k3-sha1-aes-cbc((4:sha18:z熌)<8:21371904)16:~엮 SK @)96:1UWmw %*܋2\E Q,/ITA`~1#t~D'{jN,6cǪgs mΧ#  {)(12:protected-at15:20181228T233043))) \ No newline at end of file diff --git a/misc/w3c/as2/supplemental/F911915940FEC1B19827BE6E8D0ACA0D9B25F0E8.key b/misc/w3c/as2/supplemental/F911915940FEC1B19827BE6E8D0ACA0D9B25F0E8.key new file mode 100644 index 0000000..e4e4a7a Binary files /dev/null and b/misc/w3c/as2/supplemental/F911915940FEC1B19827BE6E8D0ACA0D9B25F0E8.key differ diff --git a/misc/w3c/as2/supplemental/dm+auth-minimal-public-key.asc b/misc/w3c/as2/supplemental/dm+auth-minimal-public-key.asc new file mode 100644 index 0000000..4741a1a --- /dev/null +++ b/misc/w3c/as2/supplemental/dm+auth-minimal-public-key.asc @@ -0,0 +1,24 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEXCaxhxYJKwYBBAHaRw8BAQdAMSVyt57XCqdve8pvgC4BDkj+BYq6xKlsdMua +IYiKl+y0SURhbmdlciBNb3VzZSAoU29jaWFsOiBAZG1Abm90LnNlY3JldC5leGFt +cGxlLmNvbSkgPGRtQHNlY3JldC5leGFtcGxlLm5ldD6ImQQTFgoAQRYhBML6QP16 +Lm3bek/fyxp0JaIlw+8fBQJcJrGHAhsDDAsKDQkMCAsHBAEDAgcVCgkICwMCBRYC +AwEAAh4BAheAAAoJEBp0JaIlw+8fR0wBAOLXF7eYegcI4w21BsceE669hpwHBl6b +5G5/dJQObkSkAP0Vdx7+CyIMJwAqDesQtnUKrxLp1TEsR3FWXmPO5fAvB7g4BFwm +sgsSCisGAQQBl1UBBQEBB0AyMCTt0r9Gvth5whz4ED8znHo9KqR0AVjftlG86xe0 +LgMBCAeIeAQYFgoAIBYhBML6QP16Lm3bek/fyxp0JaIlw+8fBQJcJrILAhsMAAoJ +EBp0JaIlw+8fRoQBANjV8BrkS0EzIcQpG8xgsfQESYGsj/B59h9QdL7eS6q5AP9V +V/6JC2wBwzL38B4accNW/lNPDAMfS3LgqvQnAfgeDbgzBFwmsjUWCSsGAQQB2kcP +AQEHQLiOaYOPCSEIc1SLk1dM/XbTr5+bIl1DPduKbl2aWsaTiO8EGBYKACAWIQTC ++kD9ei5t23pP38sadCWiJcPvHwUCXCayNQIbAgCBCRAadCWiJcPvH3YgBBkWCgAd +FiEEZd86OBTTutxefWj0jYfEQYNH8rsFAlwmsjUACgkQjYfEQYNH8rtiewEAp+wJ +vMc3Qq8hv372nNVdzE7TySjvJpy05DmtPcbAZ4UBAMrpR6MadshSM7NZvlBAyhPl +7YmogPQ2N28Ja3kX8l4GIMYBAKRzQtRVH+NlOA0tvPO2wcBYXJhSQF0k/S8EnzZu +YMmwAP4h+e4ytRt5yUupjFRM+S4OY7rMRTAY0eeu8rJwBeLrA7gzBFwnIVAWCSsG +AQQB2kcPAQEHQKUocNdK3Co+lGq/DjOPGhHQhCATB4jC+PFFXuTEsM8ciHgEGBYK +ACAWIQTC+kD9ei5t23pP38sadCWiJcPvHwUCXCchUAIbIAAKCRAadCWiJcPvH8w7 +AP4otPj8zWRBeLnOnezFUq3gDCrQXSFcc0OWxELpLhs3nwD/TenisSKYpRKr+rB9 +4R8eqhVMufnCDMBZaBxn3aY+Kwk= +=pHz0 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/misc/w3c/as2/supplemental/dm+auth-minimal-public-key.gpg b/misc/w3c/as2/supplemental/dm+auth-minimal-public-key.gpg new file mode 100644 index 0000000..37cb8b6 Binary files /dev/null and b/misc/w3c/as2/supplemental/dm+auth-minimal-public-key.gpg differ diff --git a/misc/w3c/as2/supplemental/dm+auth-public-key.asc b/misc/w3c/as2/supplemental/dm+auth-public-key.asc new file mode 100644 index 0000000..4741a1a --- /dev/null +++ b/misc/w3c/as2/supplemental/dm+auth-public-key.asc @@ -0,0 +1,24 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEXCaxhxYJKwYBBAHaRw8BAQdAMSVyt57XCqdve8pvgC4BDkj+BYq6xKlsdMua +IYiKl+y0SURhbmdlciBNb3VzZSAoU29jaWFsOiBAZG1Abm90LnNlY3JldC5leGFt +cGxlLmNvbSkgPGRtQHNlY3JldC5leGFtcGxlLm5ldD6ImQQTFgoAQRYhBML6QP16 +Lm3bek/fyxp0JaIlw+8fBQJcJrGHAhsDDAsKDQkMCAsHBAEDAgcVCgkICwMCBRYC +AwEAAh4BAheAAAoJEBp0JaIlw+8fR0wBAOLXF7eYegcI4w21BsceE669hpwHBl6b +5G5/dJQObkSkAP0Vdx7+CyIMJwAqDesQtnUKrxLp1TEsR3FWXmPO5fAvB7g4BFwm +sgsSCisGAQQBl1UBBQEBB0AyMCTt0r9Gvth5whz4ED8znHo9KqR0AVjftlG86xe0 +LgMBCAeIeAQYFgoAIBYhBML6QP16Lm3bek/fyxp0JaIlw+8fBQJcJrILAhsMAAoJ +EBp0JaIlw+8fRoQBANjV8BrkS0EzIcQpG8xgsfQESYGsj/B59h9QdL7eS6q5AP9V +V/6JC2wBwzL38B4accNW/lNPDAMfS3LgqvQnAfgeDbgzBFwmsjUWCSsGAQQB2kcP +AQEHQLiOaYOPCSEIc1SLk1dM/XbTr5+bIl1DPduKbl2aWsaTiO8EGBYKACAWIQTC ++kD9ei5t23pP38sadCWiJcPvHwUCXCayNQIbAgCBCRAadCWiJcPvH3YgBBkWCgAd +FiEEZd86OBTTutxefWj0jYfEQYNH8rsFAlwmsjUACgkQjYfEQYNH8rtiewEAp+wJ +vMc3Qq8hv372nNVdzE7TySjvJpy05DmtPcbAZ4UBAMrpR6MadshSM7NZvlBAyhPl +7YmogPQ2N28Ja3kX8l4GIMYBAKRzQtRVH+NlOA0tvPO2wcBYXJhSQF0k/S8EnzZu +YMmwAP4h+e4ytRt5yUupjFRM+S4OY7rMRTAY0eeu8rJwBeLrA7gzBFwnIVAWCSsG +AQQB2kcPAQEHQKUocNdK3Co+lGq/DjOPGhHQhCATB4jC+PFFXuTEsM8ciHgEGBYK +ACAWIQTC+kD9ei5t23pP38sadCWiJcPvHwUCXCchUAIbIAAKCRAadCWiJcPvH8w7 +AP4otPj8zWRBeLnOnezFUq3gDCrQXSFcc0OWxELpLhs3nwD/TenisSKYpRKr+rB9 +4R8eqhVMufnCDMBZaBxn3aY+Kwk= +=pHz0 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/misc/w3c/as2/supplemental/dm+auth-public-key.gpg b/misc/w3c/as2/supplemental/dm+auth-public-key.gpg new file mode 100644 index 0000000..37cb8b6 Binary files /dev/null and b/misc/w3c/as2/supplemental/dm+auth-public-key.gpg differ diff --git a/misc/w3c/as2/supplemental/dm+auth-secret-key.asc b/misc/w3c/as2/supplemental/dm+auth-secret-key.asc new file mode 100644 index 0000000..bdc07f5 --- /dev/null +++ b/misc/w3c/as2/supplemental/dm+auth-secret-key.asc @@ -0,0 +1,31 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lIYEXCaxhxYJKwYBBAHaRw8BAQdAMSVyt57XCqdve8pvgC4BDkj+BYq6xKlsdMua +IYiKl+z+BwMCTU2Vi6K7UD3lmzHK1FbEOoMYuihusH1HvapAHQPZdtSK5pVsLC5z +So007gb7vdJIymhqpICCC7qrxyK/EdSyqyIsge8bzdkg6c44RR52YbRJRGFuZ2Vy +IE1vdXNlIChTb2NpYWw6IEBkbUBub3Quc2VjcmV0LmV4YW1wbGUuY29tKSA8ZG1A +c2VjcmV0LmV4YW1wbGUubmV0PoiZBBMWCgBBFiEEwvpA/Xoubdt6T9/LGnQloiXD +7x8FAlwmsYcCGwMMCwoNCQwICwcEAQMCBxUKCQgLAwIFFgIDAQACHgECF4AACgkQ +GnQloiXD7x9HTAEA4tcXt5h6BwjjDbUGxx4Trr2GnAcGXpvkbn90lA5uRKQA/RV3 +Hv4LIgwnACoN6xC2dQqvEunVMSxHcVZeY87l8C8HnIsEXCayCxIKKwYBBAGXVQEF +AQEHQDIwJO3Sv0a+2HnCHPgQPzOcej0qpHQBWN+2UbzrF7QuAwEIB/4HAwJ+Eeuz +oKcQwOWNOA0Ib5ZUistWvDBiZGj8ZbuVfCZd8jgURG8nNH02Wc5J4j9al8/i/Ram +DfQfKPPp/mlR8uo+lDjr5Y8QtiJzZyHG90x3iHgEGBYKACAWIQTC+kD9ei5t23pP +38sadCWiJcPvHwUCXCayCwIbDAAKCRAadCWiJcPvH0aEAQDY1fAa5EtBMyHEKRvM +YLH0BEmBrI/wefYfUHS+3kuquQD/VVf+iQtsAcMy9/AeGnHDVv5TTwwDH0ty4Kr0 +JwH4Hg2chgRcJrI1FgkrBgEEAdpHDwEBB0C4jmmDjwkhCHNUi5NXTP1206+fmyJd +Qz3bim5dmlrGk/4HAwJMRObH5KmaZuW9P9l1SBLscTLD9wKYyFBg7j/Wg69cd6Zk +BIWm1tpQqqm8+z9K0tNhvZY+jGqmH4AIB7a5M/1G9LakB3BC8+lQKXiJNSgliO8E +GBYKACAWIQTC+kD9ei5t23pP38sadCWiJcPvHwUCXCayNQIbAgCBCRAadCWiJcPv +H3YgBBkWCgAdFiEEZd86OBTTutxefWj0jYfEQYNH8rsFAlwmsjUACgkQjYfEQYNH +8rtiewEAp+wJvMc3Qq8hv372nNVdzE7TySjvJpy05DmtPcbAZ4UBAMrpR6MadshS +M7NZvlBAyhPl7YmogPQ2N28Ja3kX8l4GIMYBAKRzQtRVH+NlOA0tvPO2wcBYXJhS +QF0k/S8EnzZuYMmwAP4h+e4ytRt5yUupjFRM+S4OY7rMRTAY0eeu8rJwBeLrA5yG +BFwnIVAWCSsGAQQB2kcPAQEHQKUocNdK3Co+lGq/DjOPGhHQhCATB4jC+PFFXuTE +sM8c/gcDAmQFGEO1b+rq5VbPkUgKjxMXWTRTmxAbZ/Wf9LpLgg+7k9eQl+C9TVrO +n99FpPrzJILgZ+ea8moYNtYgKKntmYKJUWn9SByqLfT5AmitmCOIeAQYFgoAIBYh +BML6QP16Lm3bek/fyxp0JaIlw+8fBQJcJyFQAhsgAAoJEBp0JaIlw+8fzDsA/ii0 ++PzNZEF4uc6d7MVSreAMKtBdIVxzQ5bEQukuGzefAP9N6eKxIpilEqv6sH3hHx6q +FUy5+cIMwFloHGfdpj4rCQ== +=6hxL +-----END PGP PRIVATE KEY BLOCK----- diff --git a/misc/w3c/as2/supplemental/dm+auth-secret-key.gpg b/misc/w3c/as2/supplemental/dm+auth-secret-key.gpg new file mode 100644 index 0000000..e236707 Binary files /dev/null and b/misc/w3c/as2/supplemental/dm+auth-secret-key.gpg differ diff --git a/misc/w3c/as2/supplemental/dm-minimal-public-key.asc b/misc/w3c/as2/supplemental/dm-minimal-public-key.asc new file mode 100644 index 0000000..af4755e --- /dev/null +++ b/misc/w3c/as2/supplemental/dm-minimal-public-key.asc @@ -0,0 +1,20 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEXCaxhxYJKwYBBAHaRw8BAQdAMSVyt57XCqdve8pvgC4BDkj+BYq6xKlsdMua +IYiKl+y0SURhbmdlciBNb3VzZSAoU29jaWFsOiBAZG1Abm90LnNlY3JldC5leGFt +cGxlLmNvbSkgPGRtQHNlY3JldC5leGFtcGxlLm5ldD6ImQQTFgoAQRYhBML6QP16 +Lm3bek/fyxp0JaIlw+8fBQJcJrGHAhsDDAsKDQkMCAsHBAEDAgcVCgkICwMCBRYC +AwEAAh4BAheAAAoJEBp0JaIlw+8fR0wBAOLXF7eYegcI4w21BsceE669hpwHBl6b +5G5/dJQObkSkAP0Vdx7+CyIMJwAqDesQtnUKrxLp1TEsR3FWXmPO5fAvB7g4BFwm +sgsSCisGAQQBl1UBBQEBB0AyMCTt0r9Gvth5whz4ED8znHo9KqR0AVjftlG86xe0 +LgMBCAeIeAQYFgoAIBYhBML6QP16Lm3bek/fyxp0JaIlw+8fBQJcJrILAhsMAAoJ +EBp0JaIlw+8fRoQBANjV8BrkS0EzIcQpG8xgsfQESYGsj/B59h9QdL7eS6q5AP9V +V/6JC2wBwzL38B4accNW/lNPDAMfS3LgqvQnAfgeDbgzBFwmsjUWCSsGAQQB2kcP +AQEHQLiOaYOPCSEIc1SLk1dM/XbTr5+bIl1DPduKbl2aWsaTiO8EGBYKACAWIQTC ++kD9ei5t23pP38sadCWiJcPvHwUCXCayNQIbAgCBCRAadCWiJcPvH3YgBBkWCgAd +FiEEZd86OBTTutxefWj0jYfEQYNH8rsFAlwmsjUACgkQjYfEQYNH8rtiewEAp+wJ +vMc3Qq8hv372nNVdzE7TySjvJpy05DmtPcbAZ4UBAMrpR6MadshSM7NZvlBAyhPl +7YmogPQ2N28Ja3kX8l4GIMYBAKRzQtRVH+NlOA0tvPO2wcBYXJhSQF0k/S8EnzZu +YMmwAP4h+e4ytRt5yUupjFRM+S4OY7rMRTAY0eeu8rJwBeLrAw== +=0Eei +-----END PGP PUBLIC KEY BLOCK----- diff --git a/misc/w3c/as2/supplemental/dm-minimal-public-key.gpg b/misc/w3c/as2/supplemental/dm-minimal-public-key.gpg new file mode 100644 index 0000000..b11f020 Binary files /dev/null and b/misc/w3c/as2/supplemental/dm-minimal-public-key.gpg differ diff --git a/misc/w3c/as2/supplemental/dm-passphrase.txt b/misc/w3c/as2/supplemental/dm-passphrase.txt new file mode 100644 index 0000000..2d5ef38 --- /dev/null +++ b/misc/w3c/as2/supplemental/dm-passphrase.txt @@ -0,0 +1 @@ +shush diff --git a/misc/w3c/as2/supplemental/dm-public-key.asc b/misc/w3c/as2/supplemental/dm-public-key.asc new file mode 100644 index 0000000..af4755e --- /dev/null +++ b/misc/w3c/as2/supplemental/dm-public-key.asc @@ -0,0 +1,20 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEXCaxhxYJKwYBBAHaRw8BAQdAMSVyt57XCqdve8pvgC4BDkj+BYq6xKlsdMua +IYiKl+y0SURhbmdlciBNb3VzZSAoU29jaWFsOiBAZG1Abm90LnNlY3JldC5leGFt +cGxlLmNvbSkgPGRtQHNlY3JldC5leGFtcGxlLm5ldD6ImQQTFgoAQRYhBML6QP16 +Lm3bek/fyxp0JaIlw+8fBQJcJrGHAhsDDAsKDQkMCAsHBAEDAgcVCgkICwMCBRYC +AwEAAh4BAheAAAoJEBp0JaIlw+8fR0wBAOLXF7eYegcI4w21BsceE669hpwHBl6b +5G5/dJQObkSkAP0Vdx7+CyIMJwAqDesQtnUKrxLp1TEsR3FWXmPO5fAvB7g4BFwm +sgsSCisGAQQBl1UBBQEBB0AyMCTt0r9Gvth5whz4ED8znHo9KqR0AVjftlG86xe0 +LgMBCAeIeAQYFgoAIBYhBML6QP16Lm3bek/fyxp0JaIlw+8fBQJcJrILAhsMAAoJ +EBp0JaIlw+8fRoQBANjV8BrkS0EzIcQpG8xgsfQESYGsj/B59h9QdL7eS6q5AP9V +V/6JC2wBwzL38B4accNW/lNPDAMfS3LgqvQnAfgeDbgzBFwmsjUWCSsGAQQB2kcP +AQEHQLiOaYOPCSEIc1SLk1dM/XbTr5+bIl1DPduKbl2aWsaTiO8EGBYKACAWIQTC ++kD9ei5t23pP38sadCWiJcPvHwUCXCayNQIbAgCBCRAadCWiJcPvH3YgBBkWCgAd +FiEEZd86OBTTutxefWj0jYfEQYNH8rsFAlwmsjUACgkQjYfEQYNH8rtiewEAp+wJ +vMc3Qq8hv372nNVdzE7TySjvJpy05DmtPcbAZ4UBAMrpR6MadshSM7NZvlBAyhPl +7YmogPQ2N28Ja3kX8l4GIMYBAKRzQtRVH+NlOA0tvPO2wcBYXJhSQF0k/S8EnzZu +YMmwAP4h+e4ytRt5yUupjFRM+S4OY7rMRTAY0eeu8rJwBeLrAw== +=0Eei +-----END PGP PUBLIC KEY BLOCK----- diff --git a/misc/w3c/as2/supplemental/dm-public-key.gpg b/misc/w3c/as2/supplemental/dm-public-key.gpg new file mode 100644 index 0000000..b11f020 Binary files /dev/null and b/misc/w3c/as2/supplemental/dm-public-key.gpg differ diff --git a/misc/w3c/as2/supplemental/dm-secret-key.asc b/misc/w3c/as2/supplemental/dm-secret-key.asc new file mode 100644 index 0000000..aa5fd6e --- /dev/null +++ b/misc/w3c/as2/supplemental/dm-secret-key.asc @@ -0,0 +1,25 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lIYEXCaxhxYJKwYBBAHaRw8BAQdAMSVyt57XCqdve8pvgC4BDkj+BYq6xKlsdMua +IYiKl+z+BwMC7MUJUDfdnBHltX19hAgX4bziXkPb25zY3EUYmOCU0lvn0c5n8LPl +ALmczPC3oPW38JoTShPMhcHO/zFWvdcRrS0BbY7xK/E7A5p4/VaQ6rRJRGFuZ2Vy +IE1vdXNlIChTb2NpYWw6IEBkbUBub3Quc2VjcmV0LmV4YW1wbGUuY29tKSA8ZG1A +c2VjcmV0LmV4YW1wbGUubmV0PoiZBBMWCgBBFiEEwvpA/Xoubdt6T9/LGnQloiXD +7x8FAlwmsYcCGwMMCwoNCQwICwcEAQMCBxUKCQgLAwIFFgIDAQACHgECF4AACgkQ +GnQloiXD7x9HTAEA4tcXt5h6BwjjDbUGxx4Trr2GnAcGXpvkbn90lA5uRKQA/RV3 +Hv4LIgwnACoN6xC2dQqvEunVMSxHcVZeY87l8C8HnIsEXCayCxIKKwYBBAGXVQEF +AQEHQDIwJO3Sv0a+2HnCHPgQPzOcej0qpHQBWN+2UbzrF7QuAwEIB/4HAwI7/TfW +aK8cZeXiGx4Ibrm+EGwZkYAYwTxGjppmCPM/y2aNyFuVyh7O/zjzq/lKSNFb8PA3 +ac/3gCb94ItcvO80nq4mQme1X+3vRPF6KmSjiHgEGBYKACAWIQTC+kD9ei5t23pP +38sadCWiJcPvHwUCXCayCwIbDAAKCRAadCWiJcPvH0aEAQDY1fAa5EtBMyHEKRvM +YLH0BEmBrI/wefYfUHS+3kuquQD/VVf+iQtsAcMy9/AeGnHDVv5TTwwDH0ty4Kr0 +JwH4Hg2chgRcJrI1FgkrBgEEAdpHDwEBB0C4jmmDjwkhCHNUi5NXTP1206+fmyJd +Qz3bim5dmlrGk/4HAwLY6CwBD4kI1+VEAJCjLUsV+pM7LDS8FSTWfHo33ns2kKMr +tZSBV3NdaQI7j7X1BGn2+7/fzEkL1UErRk+l7RxuLFMzhmu5OQvaz1GkVt/aiO8E +GBYKACAWIQTC+kD9ei5t23pP38sadCWiJcPvHwUCXCayNQIbAgCBCRAadCWiJcPv +H3YgBBkWCgAdFiEEZd86OBTTutxefWj0jYfEQYNH8rsFAlwmsjUACgkQjYfEQYNH +8rtiewEAp+wJvMc3Qq8hv372nNVdzE7TySjvJpy05DmtPcbAZ4UBAMrpR6MadshS +M7NZvlBAyhPl7YmogPQ2N28Ja3kX8l4GIMYBAKRzQtRVH+NlOA0tvPO2wcBYXJhS +QF0k/S8EnzZuYMmwAP4h+e4ytRt5yUupjFRM+S4OY7rMRTAY0eeu8rJwBeLrAw== +=iflV +-----END PGP PRIVATE KEY BLOCK----- diff --git a/misc/w3c/as2/supplemental/dm-secret-key.gpg b/misc/w3c/as2/supplemental/dm-secret-key.gpg new file mode 100644 index 0000000..3d5f8d2 Binary files /dev/null and b/misc/w3c/as2/supplemental/dm-secret-key.gpg differ diff --git a/misc/w3c/as2/supplemental/enote01.txt b/misc/w3c/as2/supplemental/enote01.txt new file mode 100644 index 0000000..ba0088d --- /dev/null +++ b/misc/w3c/as2/supplemental/enote01.txt @@ -0,0 +1,8 @@ +Yes, obviously a properly designed merging of OpenPGP and ActivityPub +is a good thing. The popularity of [Switter](https://switter.at/) is +proof enough of that. + +Not only that, but the problems created by this new totalitarian +America, with its puritanical war on sex being the motivation to +provide more weapons in favour of freedom. Which is what this +protocol extension is. diff --git a/misc/w3c/as2/supplemental/enote01.txt.asc b/misc/w3c/as2/supplemental/enote01.txt.asc new file mode 100644 index 0000000..67ee3ab --- /dev/null +++ b/misc/w3c/as2/supplemental/enote01.txt.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP MESSAGE----- + +hF4DSD9CPjLdeagSAQdAqdWMriKCydTELA/6Rn0V6v0iCx2tTz4qFzvl0iutjWMw +l8OJnLw+5xy0aUEr17PujJCnrcI8hUVxarZHZSOILLjLLVtWjI5LB3YuSepP0Iav +0sEsARd02MNCp32Eyj8X1vFEsf8pvWxPe0ojrZ9afwjWF6ZIYpOHoiYPZc/za3Gf +JGeyDyZ+FJMDkP5TnJsME9K6vqF+fZnwP4m2K1HoPOMH1pCqH4jI54IMy06c4ZUx +Lh7zPrOmfcdFMSBQ4jVxw/hDaeLUaPw7J1bE21jd9dTuK8Nn6q1zteI0hmw9d6t7 +QYHw7CwNI3dsrU5y1YiHs7PoEZO2W1qqoykvOFeNzkx8RmkbNUPy1LULFiDED+Y+ +DrFYPH9Xpfaqp4SqV+kE/zL7T/edftL/ZCDmRNwzoCUcvUkg6MMTfmiTZglZ5O/k +zFn74RTmrGjXDnQv7iikP+urs41bJvOzBKYRGfRFQ08GRgZR6HJS19NrdLiB8M9I +jHQZG2fpDpNKNByx3gfXwSCXEhpurYh7m4ssK80KFXdWKRpECTN0qXj5B9LFcok8 +D1GSdX0WvKIarvtyKDxaaruAS6gVD59QODELpDnK6sKHuP4mkX34D9zKpV/yJqMb +MNiNlNnBvQF/9cp+wyVpA5BW5WlkqWKOgev+V7z0DuPkBHrsilAZOCFplaiVU//m +mErPTT6FeHSP9U5iPXTKq6vkDnDnUkNEHLIR8LgUvVvQLvGHZXWqxQpMXOcMmiyd +7rlVFL4CRXYaLlhfYH2c +=OIPC +-----END PGP MESSAGE----- diff --git a/misc/w3c/as2/supplemental/enote02.txt b/misc/w3c/as2/supplemental/enote02.txt new file mode 100644 index 0000000..e596560 --- /dev/null +++ b/misc/w3c/as2/supplemental/enote02.txt @@ -0,0 +1,13 @@ +{ + "@context": "https://www.w3.org/ns/activitystreams", + "expectedRender": { + "subject": "Adding OpenPGP to ActivityPub", + "content": "

Yes, obviously a properly designed merging of OpenPGP and ActivityPub is a good thing. The popularity of Switter is proof enough of that.

\n

Not only that, but the problems created by this new totalitarian America, with its puritanical war on sex being the motivation to provide more weapons in favour of freedom. Which is what this protocol extension is.

", + "mediaType": "text/html" + }, + "source": { + "subject": "Adding OpenPGP to ActivityPub", + "content": "Yes, obviously a properly designed merging of OpenPGP and ActivityPub\nis a good thing. The popularity of [Switter](https://switter.at/) is\nproof enough of that.\n\nNot only that, but the problems created by this new totalitarian\nAmerica, with its puritanical war on sex being the motivation to\nprovide more weapons in favour of freedom. Which is what this\nprotocol extension is.\n", + "mediaType": "text/markdown" + } +} diff --git a/misc/w3c/as2/supplemental/enote02a.txt.asc b/misc/w3c/as2/supplemental/enote02a.txt.asc new file mode 100644 index 0000000..b674a7c --- /dev/null +++ b/misc/w3c/as2/supplemental/enote02a.txt.asc @@ -0,0 +1,21 @@ +-----BEGIN PGP MESSAGE----- + +hF4DSD9CPjLdeagSAQdA171kaqwxxLN9pOKpkkODvTbCXf5l2W7hC+x2xQ5wjzEw +f/ChF07UC7QJwfiOYJ/ss5QwOP0XSYNZfuhDF6FAq6aZLWhcg9adLEFGfpd8Fpo+ +0ukBv8Nh/xIUa1ZNq4wHgpRgPoy4cfswlFIubjQe5a2GWx/qz5b2b0AVFpRr4aaP +CZA4JWqxfETxz7efvEc+gBzhQ3d+2zjvq6OrT2DZrye8UWpOAYGPT56xbTNVmdiz +Q2gWF1jOkBSDNXmL1YPmz988m2AhN+9E9DQGpOc1TM52mxD1mW9keM+/WYawlFog +kVM5dQfBe5A4Jp4029gn0wy/Ld5Rjd5b02PknTDqjZ419ebuqp3bNntXIq4Y3r49 +zZ17/852g2zhUPSuFyryKyCe6py2bULVQOGAwJ/cpBrhz++YbAnM8Ps7eIWu9s8H +Abe0DQ8NeVhwovZQpOZYvAkU2zBibE6hE1rZX513A1RhP7RGD/EfHMtzaegiH/ro +oq4F48AbpctZ3u3hNnBYGSLlL1kCUCvbj6shvWwbeGb/6gpye+mEMZyXs9sXoykx +R8hAWEwybAoxkxsMp6pfD3jNEKMAJG3+BD20cJpgE62ubKYuJFw2iHtnVg+Jqtm0 +JRTl6O+/VvHnxBoKXHj1yyBap8i8/97hfcu3FrFYPFHCrnX6636r5WIt9vicQ0NR +r60EB2Uga5lJ045J/Y7VJbNXoIHOiaN9jYdG2/PFdJ8zcBlux/eg0I174IEto6+K +Rx/UwPPkGQA2oVeroz4E2vk+ZEJ9cWeZccUMtk19pNC1SaaWvQM0m9tP5lyYaU/v +7LMDBlZ6T1Y6lRYGNEbg4aW+ILqi2qJ/Ly2aStLy7HJ5fHvCHCUwA4y5v9/0P/X3 +zjKihj1Tuz6Umre0D1mh8WEWIH23m25Fou9Mk6GFuhYzUChkEf6uabqE5NQ1WgPL +L9awbuh3LWXPvVz7eSP8d8rTbHr3mHm+xWmLQlln9dnRtEuQHgdkaMT3/tHhdBcr +L/kqAfhEEjuD +=uP+m +-----END PGP MESSAGE----- diff --git a/misc/w3c/as2/supplemental/enote02b.txt.asc b/misc/w3c/as2/supplemental/enote02b.txt.asc new file mode 100644 index 0000000..827c042 --- /dev/null +++ b/misc/w3c/as2/supplemental/enote02b.txt.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP MESSAGE----- + +hF4DSD9CPjLdeagSAQdAaR4vYSrOenqGK3sM0V3rGLJtRCcPb3NTpf1/yuNQLy0w +HRirczb52+WarwgcbJXpnslVOyFNJnHnJ8fi6G++w98ZNycf7UrOPTbu/EoINPom +0ukB1CC4aelHjhE90SosjP/wosrn7YzZxm3QUDu/kR2y6um1v/gIghpBlTHWovK9 +XJMd7c0JGSxtEqHoJAUlTXsRZn7CYMGHTJ1W+In4uc1rZb5aHNv+iHzKLBCylfsO +0VsHJ6MET74FO40iWYjlfReoPP08n9x8Q2J/6RuuCDLbYKPX3W2VD2Gv4tASRCW8 +XJuv9knMCnbV4yUD0EAn2ZmJSH9LbBSiJUT5yBEmUqgme09EiuPxP8/uRmCf03+n +ab5S1yjR5xKUfGHhSs2MJZqKLP0xKmClgZIA3PYnPyHLtlzASn6EhZ9PZ0d2DFrA +5uIKdTpuly0esfCWjCjMH+S7W85Zk3ne7Qk4ZOsuejj8Z+HHAjKMVBAlAZ0gFU4G +JGvM9U0Hs84vFLcNShdY+KixTL1yxMT4nom9ch9vKZszT9KBFfTxFZP9JAeO2Xam +1hbKCL7uo+xKLdGCD38X3FTOtQNAFohpffzb5aQqLRb5+GSO720Dkhn6/RwjCfpB +4+PJiz8jnlVzdMPOb2QumfjF4BOAGK3L9L0wIdszelwP7WrIFrUHh0BwwHOM7F0e +PHTFj5nxE+BZ7KO3EHcqR0oTokUjQY/oNm2W3rZr8ZtZCsWNMr5BDGN4yMBxOrQq +nwe+kzys9bAR+u683DzPE6K7e8uyy4Fs+irZQO1AKC7Z1QA= +=Kxtt +-----END PGP MESSAGE-----