Skip to content

Commit

Permalink
Remove preset profile names and refactor profiles (#288)
Browse files Browse the repository at this point in the history
* feat(profiles): Remove pre-set profile name strings and refactor

- Remove profile name map
- Rename Crypto Refresh profile to RFC9580
- Remove GnuPG profile
  • Loading branch information
lubux authored Jul 17, 2024
1 parent 83d20e8 commit 3e723ea
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 77 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 13 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -268,29 +266,29 @@ 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
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)
```

Expand Down
2 changes: 1 addition & 1 deletion crypto/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
4 changes: 2 additions & 2 deletions crypto/crypto_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion crypto/key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func initGenerateKeys() {
keyTestName,
keyTestDomain,
clock,
profile.GnuPG(),
profile.Default(),
constants.StandardSecurity,
0,
)
Expand Down
2 changes: 1 addition & 1 deletion mobile/mobile_stream_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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().
Expand Down
54 changes: 6 additions & 48 deletions profile/preset.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand All @@ -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{},
Expand Down
9 changes: 0 additions & 9 deletions profile/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 3e723ea

Please sign in to comment.