From ff0dcdbbb41969ca8b9c7923d2f345f177170cb7 Mon Sep 17 00:00:00 2001 From: Alex Feyerke Date: Wed, 15 Nov 2023 15:08:30 +0100 Subject: [PATCH 1/3] Guide to org/project structure and forking info --- PROJECT_STRUCTURE.md | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 PROJECT_STRUCTURE.md diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md new file mode 100644 index 00000000..8f01357a --- /dev/null +++ b/PROJECT_STRUCTURE.md @@ -0,0 +1,61 @@ +# OpenPGP.js Repositories + +This documents explains all repositories in the OpenPGP.js organization and how they relate to each other. + +**Table of Contents** +- [Forks](#forks) +- [Repo Dependency Chart](#repo-dependency-chart) + +## Forks +You will notice a large number of forked projects that are dependencies of OpenPGP.js itself. These are often due to necessary changes that are of no interest to the upstream maintainers, mostly concerning build processes, eg. making node-only libraries available for frontend use. The `tweetnacl` fork is mainly there to shrink the dependency, since most of the library isn’t used. + +There’s a [useful discussion](https://github.com/openpgpjs/openpgpjs/discussions/1574) on the topic that includes some analysis of the forks in regard to their upstreams, as well as explainations from the maintainers concerning the reasons for the forks and their versioning. + +## Repo Dependency Chart + +```mermaid +flowchart LR + CORE -->|depends on| InternalLibraries + CORE -->|depends on| PublicLibraries + CORE -->|depends on| SoonObsolete + CORE .->|will depend on| v6InternalLibraries + CORE .->|no longer depends on| UnusedForks + subgraph Core + CORE(OpenPGP.js) + end + subgraph NoInternalDependencies [Repos with no internal dependencies] + direction LR + CLI(sop-openpgp.js) + WEBSITE(openpgpjs.org website) + GHA(Github Actions fork) + HKP-CLIENT(HKP Client) + WKD-CLIENT(WKD Client) + end + subgraph PublicLibraries [Public Libraries] + direction LR + WEB-STREAMS-POLYFILL(web-streams-polyfill fork) + ARGON2ID(Argon2id) + end + subgraph InternalLibraries [Internal Libraries and Forks] + direction LR + ASMCRYPTO.JS(openpgp/asmcrypto.js fork) + JSDOC(openpgp/jsdoc fork) + PAKO(openpgp/pako fork) + SEEK-BZIP(openpgp/seek-bzip fork) + TWEETNACL(openpgp/tweetnacl fork) + WEB-STREAM-TOOLS(openpgp/web-stream-tools) -->|depends on| JSDOC + end + subgraph v6InternalLibraries [Internal Libraries that will be added in v6] + NOBLE-CURVES(Noble Curves fork) + NOBLE-HASHES(Noble Hashes fork) + end + subgraph SoonObsolete [Internal Libraries that will be removed in v6] + ELLIPTIC(openpgp/elliptic fork) + end + subgraph UnusedForks [Unused Forks] + direction LR + COMPRESSJS(compressjs fork, unused since 2018) + ES6-PROMISE(es6-promise fork, seems unused?) + EMAIL-ADDRESSES(email-addresses fork, replaced by upstream in 528fbfb, 2019) + end +``` From ac8cf57098bbfad2139afe450e0e5f6d2b86e921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julia=20Kr=C3=BCger?= Date: Wed, 17 Jan 2024 12:34:56 +0100 Subject: [PATCH 2/3] Add project structure descriptions --- PROJECT_STRUCTURE.md | 132 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 3 deletions(-) diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md index 8f01357a..5ce313a7 100644 --- a/PROJECT_STRUCTURE.md +++ b/PROJECT_STRUCTURE.md @@ -1,15 +1,18 @@ # OpenPGP.js Repositories -This documents explains all repositories in the OpenPGP.js organization and how they relate to each other. +This document explains all repositories in the OpenPGP.js organization and how they relate to each other. **Table of Contents** - [Forks](#forks) - [Repo Dependency Chart](#repo-dependency-chart) +- [OpenPGP Overview](#openpgp-overview) +- [Crypto Refresh Features](#crypto-refresh-features) ## Forks -You will notice a large number of forked projects that are dependencies of OpenPGP.js itself. These are often due to necessary changes that are of no interest to the upstream maintainers, mostly concerning build processes, eg. making node-only libraries available for frontend use. The `tweetnacl` fork is mainly there to shrink the dependency, since most of the library isn’t used. -There’s a [useful discussion](https://github.com/openpgpjs/openpgpjs/discussions/1574) on the topic that includes some analysis of the forks in regard to their upstreams, as well as explainations from the maintainers concerning the reasons for the forks and their versioning. +You will notice a large number of forked projects that are dependencies of OpenPGP.js itself. These are often due to necessary changes that are of no interest to the upstream maintainers, mostly concerning build processes, eg. making node-only libraries available for frontend use. The `tweetnacl` fork is mainly there to shrink the dependency since most of the library isn’t used. + +There’s a [useful discussion](https://github.com/openpgpjs/openpgpjs/discussions/1574) on the topic that includes some analysis of the forks regarding their upstreams, as well as explanations from the maintainers concerning the reasons for the forks and their versioning. ## Repo Dependency Chart @@ -59,3 +62,126 @@ flowchart LR EMAIL-ADDRESSES(email-addresses fork, replaced by upstream in 528fbfb, 2019) end ``` + + +## OpenPGP.js Overview +OpenPGP.js is an implementation of [RFC 4880](https://datatracker.ietf.org/doc/html/rfc4880). +And consists of these main building blocks: + +### Key Module +The relevant code is located in `src/key` + +#### Transferable Public Keys +A transferable public key is the object that a person uses to publish (or revoke) their public key, and to have it authenticated by third parties. +The code is located in `src/key/public_key.js`. + +#### Transferable Secret Keys +Transferable secret keys are identical to transferable public keys, except they use Secret-Key and Secret-Subkey packets instead of Public-Key and Public-Subkey packets. +They're typically used by one user transferring keys between applications/devices under their control, and not for sending keys between users. +In the code, this key is referred to as a private key and its code representation is in `src/key/private_key.js`. + +#### Subkeys +A Subkey is the same as a (transferable) public key but is typically used when a user does not want to use the same key pair for signing and encryption. The "root" public key will be used to sign the subkey, which will then be used for encryption. +Secret Keys can also have Subkeys. You can find the code in `src/key/subkey.js`. + +### OpenPGP Messages + +The class that represents an OpenPGP message is located at `src/message.js`. +It can be any of the following: + +- A _literal message_: + - The implementation of a Literal Message is the class `LiteralDataPacket` at `src/packet/literal_data.js`. A Literal Data packet contains the body of a message; data that is not to be further interpreted. +- A _compressed message_: + - A Compressed Message is represented by the `CompressedDataPacket` class at `src/packet/compressed_data.js`. + The Compressed Data packet contains compressed data. Typically, this packet is found as the contents of an encrypted packet, or following a Signature or One-Pass Signature packet, and contains a literal data packet. +- An _encrypted message_, which can consist of: + - Either a Symmetrically Encrypted Data packet (`src/packet/symmetrically_encrypted_data.js`), that contains data encrypted with a symmetric-key algorithm. When it has been decrypted, it contains other packets. Usually a literal data packet or compressed data packet, but in theory other Symmetrically Encrypted Data packets or sequences of packets that form whole OpenPGP messages. + - A Symmetrically Encrypted Integrity Protected Data packet (`src/packet/sym_encrypted_integrity_protected_data.js`) is a variant of the Symmetrically Encrypted Data packet. It is a feature created for OpenPGP that addresses the problem of detecting a modification to encrypted data. It is used in combination with a Modification Detection Code packet. + - Accompanying the encrypted data is a set of encrypted session keys, one for each recipient. Each ESK can be one of: + - _Public Key Encrypted Session Key_ (represented by `src/packet/public_key_encrypted_session_key.js` at `src/packet/public_key_encrypted_session_key.js`), which encrypts the session key using the recipient's public key. Includes the key ID (which may identify a subkey), the encryption algorithms used to encrypt both the session key and the message, and the encrypted session key itself. + - _Symmetric-Key Encrypted Session Key_ (represented by `SymEncryptedSessionKeyPacket` at `src/packet/sym_encrypted_session_key.js`), which encrypts the session key using a symmetric algorithm based on a shared secret passphrase. Includes the encryption algorithms used to encrypt the session key and the message, a string-to-key specifier, and the encrypted session key. +- A _signed message_: + - with a Signature that covers the message data, signed by the sender's private key. There are a couple of different ways of encoding this that allow the placement of the signature at either the start or the end of the message. + +### Signatures +Signatures are needed to authenticate messages and public keys. They +cryptographically sign a block of data using the signer's private key, which +anyone else can then verify using their public key. + +The code for signatures can be found in `src/signature.js`, `src/packet/signature.js` as well as `src/crypto/signature.js`. + +### Identifiers + +Users are normally identified by a name-email pair. This code can be found in `src/key/user.js` +which receives `src/packet/userid.js` and `src/packet/user_attribute.js`. + +Keys are identified by a _fingerprint_, which in recent versions is derived from +a hash of the key's full content. A _key ID_ is an abbreviated form of the +fingerprint, usually the lowest 32 or 64 bits of the fingerprint (an 8 or +16-digit hex value). Key IDs should not be assumed to be unique. +The code for Key IDs is in `src/type/keyid.js`. + +### String-to-Key (S2K) + +Usually, the session key will encrypt using each recipient's public key, but the protocol also supports encrypting using a _symmetric_ algorithm. In this case, the users assume they all know a shared secret, a textual passphrase, rather than the encrypted session keys identifying each recipient's public key. To produce the fixed-size binary key that the encryption algorithm needs, the passphrase needs to be passed through a _string-to-key_ (S2K) function. Symmetric-Key Encrypted Session Keys include an _S2K specifier_ that describes how to do this. + +There are a few types of S2K specifiers: +- _Simple_: specifies a hash algorithm, and the passphrase is simply +hashed using that algorithm to produce a key. + +- _Salted_: specifies a hash algorithm and a 64-bit salt value; the passphrase is combined with the salt before hashing. + +- _Iterated and Salted_: specifies a hash algorithm, a 64-bit salt, and an + iteration count. The hashing is repeated the given number of times to make key derivation more expensive. + +S2K is implemented in `src/type/s2k`. + + +### Crypto Module + +According to the RFC OpenPGP implementations must support a couple of Algorithms for different uses. + +#### Public-Key Algorithms +Implementations MUST implement [DSA](https://en.wikipedia.org/wiki/Digital_Signature_Algorithm)and should +support [RSA]() for signatures, and [ElGamal](https://en.wikipedia.org/wiki/ElGamal_encryption) for encryption. +These implementations can be found in `src/crypto/public_key`. + +#### Symmetric-Key Algorithms +Implementations MUST implement [Triple DES](https://en.wikipedia.org/wiki/Triple_DES). Implementations SHOULD +implement [AES-128](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) and [CAST5](https://en.wikipedia.org/wiki/CAST-128). +Implementations may support AES-192, AES-256, +[Blowfish](), +[IDEA](https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm), +and [Twofish-256](https://en.wikipedia.org/wiki/Twofish). IDEA is required for +interoperability with older PGP versions but is not implemented here. +These implementations can be found in `src/crypto/cipher`. + +#### Compression Algorithms +Implementations MUST implement uncompressed data. Implementations +SHOULD implement [ZIP](), and may +support [zlib](https://en.wikipedia.org/wiki/Zlib) and +[bzip2](https://en.wikipedia.org/wiki/Bzip2). +The compression algorithms can be found in `src/packet/compressed_data.js`. + +#### Hash Algorithms +Implementations MUST implement [SHA-1](https://en.wikipedia.org/wiki/SHA-1). and may support [SHA-224, SHA-256, SSHA-384, SHA-512](https://en.wikipedia.org/wiki/SHA-2), +[MD5](https://en.wikipedia.org/wiki/MD5) and +[RIPEMD-160](https://en.wikipedia.org/wiki/RIPEMD). MD5 is deprecated but +retained for backward compatibility. +These algorithms are implemented in `src/crypto/hash`. + + +## Crypto Refresh Features + +A new revision of the OpenPGP spec is currently under development but has not yet been stabilized, its working name is [draft-ietf-openpgp-crypto-refresh](https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh) + and its main purpose is to update the algorithms used in OpenPGP to include advances in cryptography since RFC 4880 was published. + +With v6 of OpenPGP.js all crypto refresh features will be available: + +- support for v6 keys, signatures, and encrypted-session keys & more (behind feature flag openpgp.config.v6Keys) +- support for AEAD-protected encrypted messages (new format, behind feature flag openpgp.config.aeadProtect) - support for Argon2 +- support for Ed448 & X448 +- support for generating Ed25519 & X25519 keys in new format + +More info in this [discussion](https://github.com/openpgpjs/openpgpjs/discussions/1695) + From 5e39886de83f5114475f4fa2823418d3a5fe194c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julia=20Kr=C3=BCger?= Date: Mon, 29 Jan 2024 16:48:45 +0100 Subject: [PATCH 3/3] Update Description for v6 --- PROJECT_STRUCTURE.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md index 5ce313a7..68e8a1e9 100644 --- a/PROJECT_STRUCTURE.md +++ b/PROJECT_STRUCTURE.md @@ -20,8 +20,6 @@ There’s a [useful discussion](https://github.com/openpgpjs/openpgpjs/discussio flowchart LR CORE -->|depends on| InternalLibraries CORE -->|depends on| PublicLibraries - CORE -->|depends on| SoonObsolete - CORE .->|will depend on| v6InternalLibraries CORE .->|no longer depends on| UnusedForks subgraph Core CORE(OpenPGP.js) @@ -43,29 +41,28 @@ flowchart LR direction LR ASMCRYPTO.JS(openpgp/asmcrypto.js fork) JSDOC(openpgp/jsdoc fork) - PAKO(openpgp/pako fork) SEEK-BZIP(openpgp/seek-bzip fork) TWEETNACL(openpgp/tweetnacl fork) WEB-STREAM-TOOLS(openpgp/web-stream-tools) -->|depends on| JSDOC - end - subgraph v6InternalLibraries [Internal Libraries that will be added in v6] NOBLE-CURVES(Noble Curves fork) NOBLE-HASHES(Noble Hashes fork) end - subgraph SoonObsolete [Internal Libraries that will be removed in v6] - ELLIPTIC(openpgp/elliptic fork) - end subgraph UnusedForks [Unused Forks] direction LR COMPRESSJS(compressjs fork, unused since 2018) - ES6-PROMISE(es6-promise fork, seems unused?) + ES6-PROMISE(es6-promise fork) EMAIL-ADDRESSES(email-addresses fork, replaced by upstream in 528fbfb, 2019) + PAKO(openpgp/pako fork) + ELLIPTIC(openpgp/elliptic fork) end ``` ## OpenPGP.js Overview -OpenPGP.js is an implementation of [RFC 4880](https://datatracker.ietf.org/doc/html/rfc4880). +OpenPGP.js is a JavaScript implementation of the OpenPGP protocol. It implements + [RFC 4880](https://datatracker.ietf.org/doc/html/rfc4880) and most of the [crypto refresh](https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh) +. + And consists of these main building blocks: ### Key Module @@ -173,10 +170,10 @@ These algorithms are implemented in `src/crypto/hash`. ## Crypto Refresh Features -A new revision of the OpenPGP spec is currently under development but has not yet been stabilized, its working name is [draft-ietf-openpgp-crypto-refresh](https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh) - and its main purpose is to update the algorithms used in OpenPGP to include advances in cryptography since RFC 4880 was published. +A new version of the OpenPGP spec called [crypto-refresh](https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh), will be published as an RFC soon. +Its main purpose is to update the algorithms used in OpenPGP to include advances in cryptography since RFC 4880 was published. -With v6 of OpenPGP.js all crypto refresh features will be available: +With v6 of OpenPGP.js most of crypto refresh features will be available: - support for v6 keys, signatures, and encrypted-session keys & more (behind feature flag openpgp.config.v6Keys) - support for AEAD-protected encrypted messages (new format, behind feature flag openpgp.config.aeadProtect) - support for Argon2