From 4f7fbc0d6475facdeca0de22fcf682718e339f75 Mon Sep 17 00:00:00 2001 From: Lukas Burkhalter <10532077+lubux@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:17:38 +0200 Subject: [PATCH] Remove preset profile names and refactor profiles (#288) * feat(profiles): Remove pre-set profile name strings and refactor - Remove profile name map - Rename Crypto Refresh profile to RFC9580 - Remove GnuPG profile --- CHANGELOG.md | 2 ++ README.md | 28 +++++++++--------- crypto/base_test.go | 2 +- crypto/crypto_example_test.go | 4 +-- crypto/key_test.go | 2 +- mobile/mobile_stream_test.go | 2 +- profile/preset.go | 54 ++++------------------------------- profile/profile.go | 9 ------ 8 files changed, 26 insertions(+), 77 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5565ac14..9fab263c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [3.0.0-alpha.4] 2024-07-16 ### Changed - Update go-crypto to `1.1.0-alpha.4`. +- Remove logic to get a profile by name. +- Reduce preset profiles to `Default`, `RFC4880`, and `RFC9580`. ## [3.0.0-alpha.3] 2024-06-25 ### Added diff --git a/README.md b/README.md index 2c659667..4ea10305 100644 --- a/README.md +++ b/README.md @@ -82,12 +82,12 @@ decrypted, err := decHandle.Decrypt(armored, crypto.Armor) myMessage := decrypted.Bytes() ``` -To encrypt with the [latest proposed standard](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html): +To encrypt with the [latest proposed standard (RFC9580-to-be)](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html): ```go import "github.com/ProtonMail/gopenpgp/v3/profile" -// Use the default crypto refresh profile -pgp := crypto.PGPWithProfile(profile.CryptoRefresh()) +// Use the profile that conforms with the crypto refresh (RFC9580-to-be). +pgp := crypto.PGPWithProfile(profile.RFC9580()) // The default crypto refresh profile uses Argon2 for deriving // session keys and uses an AEAD for encryption (AES-256, OCB mode). // Encrypt data with password @@ -102,10 +102,8 @@ import "github.com/ProtonMail/gopenpgp/v3/profile" // RFC4880 profile pgp4880 := crypto.PGPWithProfile(profile.RFC4880()) -// GnuPG profile -gnuPG := crypto.PGPWithProfile(profile.GnuPG()) -// Crypto refresh profile -pgpCryptoRefresh := crypto.PGPWithProfile(profile.CryptoRefresh()) +// RFC9580 crypto refresh profile +pgpCryptoRefresh := crypto.PGPWithProfile(profile.RFC9580()) ``` ### Encrypt / Decrypt with PGP keys @@ -268,12 +266,12 @@ const ( passphrase = []byte("LongSecret") ) +pgpDefault := crypto.PGPWithProfile(profile.Default()) pgp4880 := crypto.PGPWithProfile(profile.RFC4880()) -gnuPG := crypto.PGPWithProfile(profile.GnuPG()) -pgpCryptoRefresh := crypto.PGPWithProfile(profile.CryptoRefresh()) +pgpCryptoRefresh := crypto.PGPWithProfile(profile.RFC9580()) // Note that RSA keys should not be generated anymore according to -// draft-ietf-openpgp-crypto-refresh +// RFC9580 (crypto refresh). keyGenHandle := pgp4880.KeyGeneration().AddUserId(name, email).New() // Generates rsa keys with 3072 bits @@ -281,16 +279,16 @@ rsaKey, err := keyGenHandle.GenerateKey() // Generates rsa keys with 4092 bits rsaKeyHigh, err := keyGenHandle.GenerateKeyWithSecurity(constants.HighSecurity) -keyGenHandle = gnuPG.KeyGeneration().AddUserId(name, email).New() -// Generates curve25519 keys with GnuPG compatibility +keyGenHandle = pgpDefault.KeyGeneration().AddUserId(name, email).New() +// Generates curve25519 v4 keys. ecKey, err := keyGenHandle.GenerateKey() -// Generates curve448 keys with GnuPG compatibility +// Generates curve448 v4 keys. ecKeyHigh, err := keyGenHandle.GenerateKeyWithSecurity(constants.HighSecurity) keyGenHandle = pgpCryptoRefresh.KeyGeneration().AddUserId(name, email).New() -// Generates curve25519 keys with draft-ietf-openpgp-crypto-refresh +// Generates curve25519 v6 keys with RFC9580 (crypto refresh). ecKey, err = keyGenHandle.GenerateKey() -// Generates curve448 keys with draft-ietf-openpgp-crypto-refresh +// Generates curve448 v6 keys with RFC9580 (crypto refresh). ecKeyHigh, err = keyGenHandle.GenerateKeyWithSecurity(constants.HighSecurity) ``` diff --git a/crypto/base_test.go b/crypto/base_test.go index c21dde9f..454f885e 100644 --- a/crypto/base_test.go +++ b/crypto/base_test.go @@ -34,7 +34,7 @@ func readTestFile(name string, trimNewlines bool) string { func init() { testPGP = PGP() testPGP.defaultTime = NewConstantClock(testTime) // 2019-05-13T13:37:07+00:00 - testProfiles = []*profile.Custom{profile.RFC4880(), profile.GnuPG(), profile.CryptoRefresh()} + testProfiles = []*profile.Custom{profile.Default(), profile.RFC4880(), profile.RFC9580()} initEncDecTest() initGenerateKeys() diff --git a/crypto/crypto_example_test.go b/crypto/crypto_example_test.go index 2408c18e..18767071 100644 --- a/crypto/crypto_example_test.go +++ b/crypto/crypto_example_test.go @@ -545,7 +545,7 @@ func ExamplePGPHandle_KeyGeneration_basic() { func ExamplePGPHandle_KeyGeneration_profile() { // Generate a PGP key with the crypto-refresh profile - pgp := PGPWithProfile(profile.CryptoRefresh()) + pgp := PGPWithProfile(profile.RFC9580()) genHandle := pgp.KeyGeneration(). AddUserId("Max Mustermann", "max.mustermann@example.com"). New() @@ -559,7 +559,7 @@ func ExamplePGPHandle_KeyGeneration_profile() { func ExamplePGPHandle_KeyGeneration_level() { // Generate a PGP key with the crypto-refresh profile // higher security level (Curve448) - pgp := PGPWithProfile(profile.CryptoRefresh()) + pgp := PGPWithProfile(profile.RFC9580()) genHandle := pgp.KeyGeneration(). AddUserId("Max Mustermann", "max.mustermann@example.com"). New() diff --git a/crypto/key_test.go b/crypto/key_test.go index 5bf7a597..ef5972b5 100644 --- a/crypto/key_test.go +++ b/crypto/key_test.go @@ -45,7 +45,7 @@ func initGenerateKeys() { keyTestName, keyTestDomain, clock, - profile.GnuPG(), + profile.Default(), constants.StandardSecurity, 0, ) diff --git a/mobile/mobile_stream_test.go b/mobile/mobile_stream_test.go index 73b8ab5a..9db680bd 100644 --- a/mobile/mobile_stream_test.go +++ b/mobile/mobile_stream_test.go @@ -186,7 +186,7 @@ func TestMobile2GoReader(t *testing.T) { } func setUpTestKeyRing() (*crypto.PGPHandle, *crypto.KeyRing, *crypto.KeyRing, error) { - pgpHandle := crypto.PGPWithProfile(profile.GnuPG()) + pgpHandle := crypto.PGPWithProfile(profile.Default()) testKey, err := pgpHandle.KeyGeneration(). AddUserId("test", "test@protonmail.com"). New(). diff --git a/profile/preset.go b/profile/preset.go index f54eac7d..ac95f0e6 100644 --- a/profile/preset.go +++ b/profile/preset.go @@ -8,24 +8,6 @@ import ( "github.com/ProtonMail/gopenpgp/v3/constants" ) -var nameToProfile = map[string]func() *Custom{ - "default": Default, - "rfc4880": RFC4880, - "draft-koch-eddsa-for-openpgp-00": GnuPG, - "draft-ietf-openpgp-crypto-refresh-10": CryptoRefresh, -} - -// PresetProfiles returns the names of the available profiles. -func PresetProfiles() []string { - profiles := make([]string, len(nameToProfile)) - index := 0 - for profile := range nameToProfile { - profiles[index] = profile - index++ - } - return profiles -} - // Default returns a custom profile that support features // that are widely implemented. func Default() *Custom { @@ -51,7 +33,7 @@ func Default() *Custom { } // RFC4880 returns a custom profile for this library -// that conforms with the algorithms in rfc 4880. +// that conforms with the algorithms in RFC4880. func RFC4880() *Custom { setKeyAlgorithm := func(cfg *packet.Config, securityLevel int8) { cfg.Algorithm = packet.PubKeyAlgoRSA @@ -71,45 +53,21 @@ func RFC4880() *Custom { } } -// GnuPG returns a custom profile for this library -// that conforms with the algorithms in GnuPG. -// Use this profile for modern algorithms and GnuPG interoperability. -func GnuPG() *Custom { - setKeyAlgorithm := func(cfg *packet.Config, securityLevel int8) { - cfg.Algorithm = packet.PubKeyAlgoEdDSA - switch securityLevel { - case constants.HighSecurity: - cfg.Curve = packet.Curve448 - cfg.DefaultHash = crypto.SHA512 - default: - cfg.Curve = packet.Curve25519 - } - } - return &Custom{ - Name: "draft-koch-eddsa-for-openpgp-00", - SetKeyAlgorithm: setKeyAlgorithm, - Hash: crypto.SHA256, - CipherEncryption: packet.CipherAES256, - CompressionAlgorithm: packet.CompressionZLIB, - } -} - -// CryptoRefresh returns a custom profile for this library -// that conforms with the algorithms in draft-ietf-openpgp-crypto-refresh. -func CryptoRefresh() *Custom { +// RFC9580 returns a custom profile for this library +// that conforms with the algorithms in RFC9580 (crypto refresh). +func RFC9580() *Custom { setKeyAlgorithm := func(cfg *packet.Config, securityLevel int8) { switch securityLevel { case constants.HighSecurity: cfg.Algorithm = packet.PubKeyAlgoEd448 - cfg.DefaultHash = crypto.SHA512 default: cfg.Algorithm = packet.PubKeyAlgoEd25519 } } return &Custom{ - Name: "draft-ietf-openpgp-crypto-refresh", + Name: "rfc9580", SetKeyAlgorithm: setKeyAlgorithm, - Hash: crypto.SHA256, + Hash: crypto.SHA512, CipherEncryption: packet.CipherAES256, CompressionAlgorithm: packet.CompressionZLIB, AeadKeyEncryption: &packet.AEADConfig{}, diff --git a/profile/profile.go b/profile/profile.go index 53200c2a..d86930b3 100644 --- a/profile/profile.go +++ b/profile/profile.go @@ -52,15 +52,6 @@ type Custom struct { AllowWeakRSA bool } -// WithName returns the custom profile with the given name. -func WithName(name string) *Custom { - profileFunction, ok := nameToProfile[name] - if !ok { - return nil - } - return profileFunction() -} - // Custom implements the profile interfaces: // KeyGenerationProfile, KeyEncryptionProfile, EncryptionProfile, and SignProfile