Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove preset profile names and refactor profiles #288

Merged
merged 2 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading