diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index b10c3f25..fe98149f 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -4,7 +4,7 @@ on: push: branches: [ main ] pull_request: - branches: [ main, v3 ] + branches: [ main, Proton ] jobs: build: @@ -18,9 +18,9 @@ jobs: java-version: 1.8 - name: Set up Go 1.x - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: - go-version: ^1.16 + go-version: '^1.16' id: go - name: Install NDK diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f243df6c..5fb62884 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -4,7 +4,7 @@ on: push: branches: [ main ] pull_request: - branches: [ main, v3 ] + branches: [ main, Proton ] jobs: test: @@ -15,35 +15,20 @@ jobs: uses: actions/checkout@v4 - name: Set up latest golang - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: ^1.18 + go-version: '^1.18' - name: Test run: go test -v -race ./... - - test-old: - name: Test with 1.17 - runs-on: ubuntu-latest - steps: - - name: Check out repo - uses: actions/checkout@v4 - - - name: Set up Go 1.17 - uses: actions/setup-go@v3 - with: - go-version: 1.17 - - - name: Test - run: go test -v -race ./... lint: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v5 with: - go-version: 1.17 + go-version: '1.22' - uses: actions/checkout@v4 - name: golangci-lint uses: golangci/golangci-lint-action@v3 diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 4df1b195..43029ed8 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -4,7 +4,7 @@ on: push: branches: [ main ] pull_request: - branches: [ main, v3 ] + branches: [ main, Proton ] jobs: build: @@ -18,10 +18,10 @@ jobs: xcode-version: 15.3.0 id: xcode - - name: Set up Go 1.x - uses: actions/setup-go@v2 + - name: Set up Go 1.22 + uses: actions/setup-go@v5 with: - go-version: ^1.16 + go-version: '1.22' id: go - name: Checkout diff --git a/.github/workflows/sop-test-suite.yml b/.github/workflows/sop-test-suite.yml index f5d2a2ee..431491e0 100644 --- a/.github/workflows/sop-test-suite.yml +++ b/.github/workflows/sop-test-suite.yml @@ -2,7 +2,7 @@ name: SOP interoperability test suite on: pull_request: - branches: [ main, v3 ] + branches: [ main, Proton ] jobs: diff --git a/.golangci.yml b/.golangci.yml index 33f2e665..b971f272 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -20,6 +20,8 @@ issues: - ST1003 # CamelCase variables; see constants/cipher.go - missing output for example, go test can't validate it - variable 'hasExpiredEntity' is only used in the if-statement + - SA1019 + - commentFormatting exclude-rules: - path: crypto/key_clear.go text: "SA1019" diff --git a/crypto/base_test.go b/crypto/base_test.go index a4b88636..d0e281f7 100644 --- a/crypto/base_test.go +++ b/crypto/base_test.go @@ -35,8 +35,8 @@ 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.Default(), profile.RFC4880(), profile.RFC9580()} - testProfileNames = []string{"Default", "RFC4880", "RFC9580"} + testProfiles = []*profile.Custom{profile.Default(), profile.RFC4880(), profile.RFC9580(), profile.Symmetric(), profile.PQC()} + testProfileNames = []string{"Default", "RFC4880", "RFC9580", "Symmetric", "PQC"} initEncDecTest() initGenerateKeys() initArmoredKeys() diff --git a/crypto/key_clear.go b/crypto/key_clear.go index b19aae86..587d67b8 100644 --- a/crypto/key_clear.go +++ b/crypto/key_clear.go @@ -3,7 +3,6 @@ package crypto import ( "crypto/dsa" "crypto/rsa" - "errors" "math/big" "github.com/ProtonMail/go-crypto/openpgp/ecdh" @@ -76,7 +75,7 @@ func clearPrivateKey(privateKey interface{}) error { case *ed448.PrivateKey: return clearEd448PrivateKey(priv) default: - return errors.New("gopenpgp: unknown private key") + return nil } } diff --git a/crypto/proton_test.go b/crypto/proton_test.go new file mode 100644 index 00000000..f608f5df --- /dev/null +++ b/crypto/proton_test.go @@ -0,0 +1,77 @@ +package crypto + +import ( + "encoding/base64" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestForwardeeDecryption(t *testing.T) { + //pgp.latestServerTime = 1679044110 + + forwardeeKey, err := NewKeyFromArmored(readTestFile("key_forwardee", false)) + if err != nil { + t.Fatal("Expected no error while unarmoring private keyring, got:", err) + } + + forwardeeKeyRing, err := NewKeyRing(forwardeeKey) + if err != nil { + t.Fatal("Expected no error while building private keyring, got:", err) + } + + pgpMessage := readTestFile("message_forwardee", false) + decryptor, err := PGP().Decryption(). + DecryptionKeys(forwardeeKeyRing). + VerifyTime(1679044110). + New() + if err != nil { + t.Fatal(err) + } + plainMessage, err := decryptor.Decrypt([]byte(pgpMessage), Armor) + if err != nil { + t.Fatal("Expected no error while decrypting/verifying, got:", err) + } + + assert.Exactly(t, "Message for Bob", plainMessage.String()) +} + +func TestSymmetricKeys(t *testing.T) { + symmetricKey, err := NewKeyFromArmored(readTestFile("key_symmetric", false)) + if err != nil { + t.Fatal("Expected no error while unarmoring private keyring, got:", err) + } + + symmetricKeyRing, err := NewKeyRing(symmetricKey) + if err != nil { + t.Fatal("Expected no error while building private keyring, got:", err) + } + + binData, _ := base64.StdEncoding.DecodeString("ExXmnSiQ2QCey20YLH6qlLhkY3xnIBC1AwlIXwK/HvY=") + pgp := PGP() + encryptor, err := pgp.Encryption(). + Recipients(symmetricKeyRing). + SignTime(1679044110). + New() + if err != nil { + t.Fatal(err) + } + + ciphertext, err := encryptor.Encrypt(binData) + if err != nil { + t.Fatal("Expected no error when encrypting, got:", err) + } + + decryptor, err := pgp.Decryption(). + DecryptionKeys(symmetricKeyRing). + VerifyTime(1679044110). + New() + if err != nil { + t.Fatal(err) + } + decrypted, err := decryptor.Decrypt(ciphertext.Bytes(), Bytes) + if err != nil { + t.Fatal("Expected no error when decrypting, got:", err) + } + assert.Exactly(t, binData, decrypted.Bytes()) +} diff --git a/crypto/testdata/key_forwardee b/crypto/testdata/key_forwardee new file mode 100644 index 00000000..adf82ad1 --- /dev/null +++ b/crypto/testdata/key_forwardee @@ -0,0 +1,15 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +xVgEZAdtGBYJKwYBBAHaRw8BAQdAcNgHyRGEaqGmzEqEwCobfUkyrJnY8faBvsf9 +R2c5ZzYAAP9bFL4nPBdo04ei0C2IAh5RXOpmuejGC3GAIn/UmL5cYQ+XzRtjaGFy +bGVzIDxjaGFybGVzQHByb3Rvbi5tZT7CigQTFggAPAUCZAdtGAmQFXJtmBzDhdcW +IQRl2gNflypl1XjRUV8Vcm2YHMOF1wIbAwIeAQIZAQILBwIVCAIWAAIiAQAAJKYA +/2qY16Ozyo5erNz51UrKViEoWbEpwY3XaFVNzrw+b54YAQC7zXkf/t5ieylvjmA/ +LJz3/qgH5GxZRYAH9NTpWyW1AsdxBGQHbRgSCisGAQQBl1UBBQEBB0CxmxoJsHTW +TiETWh47ot+kwNA1hCk1IYB9WwKxkXYyIBf/CgmKXzV1ODP/mRmtiBYVV+VQk5MF +EAAA/1NW8D8nMc2ky140sPhQrwkeR7rVLKP2fe5n4BEtAnVQEB3CeAQYFggAKgUC +ZAdtGAmQFXJtmBzDhdcWIQRl2gNflypl1XjRUV8Vcm2YHMOF1wIbUAAAl/8A/iIS +zWBsBR8VnoOVfEE+VQk6YAi7cTSjcMjfsIez9FYtAQDKo9aCMhUohYyqvhZjn8aS +3t9mIZPc+zRJtCHzQYmhDg== +=lESj +-----END PGP PRIVATE KEY BLOCK----- \ No newline at end of file diff --git a/crypto/testdata/key_symmetric b/crypto/testdata/key_symmetric new file mode 100644 index 00000000..98f702f2 --- /dev/null +++ b/crypto/testdata/key_symmetric @@ -0,0 +1,15 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +xVgEYs/4KxYJKwYBBAHaRw8BAQdA7tIsntXluwloh/H62PJMqasjP00M86fv +/Pof9A968q8AAQDYcgkPKUdWAxsDjDHJfouPS4q5Me3ks+umlo5RJdwLZw4k +zQ1TeW1tZXRyaWMgS2V5wowEEBYKAB0FAmLP+CsECwkHCAMVCAoEFgACAQIZ +AQIbAwIeAQAhCRDkNhFDvaU8vxYhBDJNoyEFquVOCf99d+Q2EUO9pTy/5XQA +/1F2YPouv0ydBDJU3EOS/4bmPt7yqvzciWzeKVEOkzYuAP9OsP7q/5ccqOPX +mmRUKwd82/cNjdzdnWZ8Tq89XMwMAMdqBGLP+CtkCfFyZxOMF0BWLwAE8pLy +RVj2n2K7k6VvrhyuTqDkFDUFALiSLrEfnmTKlsPYS3/YzsODF354ccR63q73 +3lmCrvFRyaf6AHvVrBYPbJR+VhuTjZTwZKvPPKv0zVdSqi5JDEQiocJ4BBgW +CAAJBQJiz/grAhsMACEJEOQ2EUO9pTy/FiEEMk2jIQWq5U4J/3135DYRQ72l +PL+fEQEA7RaRbfa+AtiRN7a4GuqVEDZi3qtQZ2/Qcb27/LkAD0sA/3r9drYv +jyu46h1fdHHyo0HS2MiShZDZ8u60JnDltloD +=8TxH +-----END PGP PRIVATE KEY BLOCK----- \ No newline at end of file diff --git a/crypto/testdata/message_forwardee b/crypto/testdata/message_forwardee new file mode 100644 index 00000000..cd44ecf1 --- /dev/null +++ b/crypto/testdata/message_forwardee @@ -0,0 +1,8 @@ +-----BEGIN PGP MESSAGE----- + +wV4DB27Wn97eACkSAQdA62TlMU2QoGmf5iBLnIm4dlFRkLIg+6MbaatghwxK+Ccw +yGZuVVMAK/ypFfebDf4D/rlEw3cysv213m8aoK8nAUO8xQX3XQq3Sg+EGm0BNV8E +0kABEPyCWARoo5klT1rHPEhelnz8+RQXiOIX3G685XCWdCmaV+tzW082D0xGXSlC +7lM8r1DumNnO8srssko2qIja +=pVRa +-----END PGP MESSAGE----- \ No newline at end of file diff --git a/go.mod b/go.mod index cf3b0313..7f2ee90c 100644 --- a/go.mod +++ b/go.mod @@ -1,22 +1,22 @@ module github.com/ProtonMail/gopenpgp/v3 -go 1.17 +go 1.22.0 require ( - github.com/ProtonMail/go-crypto v1.1.6 + github.com/ProtonMail/go-crypto v1.1.6-proton github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.7.0 ) require ( - github.com/cloudflare/circl v1.3.7 // indirect + github.com/cloudflare/circl v1.5.0 // indirect github.com/davecgh/go-spew v1.1.0 // indirect github.com/kr/pretty v0.2.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/go.sum b/go.sum index 4ce2ae19..7bb9becc 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,9 @@ -github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= -github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.6-proton h1:6tuszwH3IEq7wQDHFK9yB2eFYfYXD/JJWS6/Yx2Whto= +github.com/ProtonMail/go-crypto v1.1.6-proton/go.mod h1:zNoyBJW3p/yVWiHNZgfTF9VsjwqYof5YY0M9kt2QaX0= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= +github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -22,15 +21,14 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -40,23 +38,18 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/profile/preset.go b/profile/preset.go index 01ce53a1..3a015030 100644 --- a/profile/preset.go +++ b/profile/preset.go @@ -11,24 +11,7 @@ import ( // Default returns a custom profile that support features // that are widely implemented. func Default() *Custom { - setKeyAlgorithm := func(cfg *packet.Config, securityLevel int8) { - cfg.Algorithm = packet.PubKeyAlgoEdDSA - switch securityLevel { - case constants.HighSecurity: - cfg.Curve = packet.Curve25519 - default: - cfg.Curve = packet.Curve25519 - } - } - return &Custom{ - SetKeyAlgorithm: setKeyAlgorithm, - Hash: crypto.SHA256, - CipherEncryption: packet.CipherAES256, - CompressionAlgorithm: packet.CompressionZLIB, - CompressionConfiguration: &packet.CompressionConfig{ - Level: 6, - }, - } + return ProtonV1() } // RFC4880 returns a custom profile for this library @@ -80,3 +63,99 @@ func RFC9580() *Custom { V6: true, } } + +func PQC() *Custom { + setKeyAlgorithm := func(cfg *packet.Config, securityLevel int8) { + cfg.Algorithm = packet.PubKeyAlgoMldsa65Ed25519 + } + return &Custom{ + SetKeyAlgorithm: setKeyAlgorithm, + Hash: crypto.SHA512, + CipherEncryption: packet.CipherAES256, + CipherKeyEncryption: packet.CipherAES256, + CompressionAlgorithm: packet.CompressionZLIB, + AeadKeyEncryption: &packet.AEADConfig{ + DefaultMode: packet.AEADModeGCM, + }, + AeadEncryption: &packet.AEADConfig{ + DefaultMode: packet.AEADModeGCM, + }, + CompressionConfiguration: &packet.CompressionConfig{ + Level: 6, + }, + S2kKeyEncryption: &s2k.Config{ + S2KMode: s2k.Argon2S2K, + Argon2Config: &s2k.Argon2Config{}, + }, + S2kEncryption: &s2k.Config{ + S2KMode: s2k.Argon2S2K, + Argon2Config: &s2k.Argon2Config{}, + }, + V6: true, + } +} + +func Symmetric() *Custom { + setKeyAlgorithm := func(cfg *packet.Config, securityLevel int8) { + cfg.Algorithm = packet.ExperimentalPubKeyAlgoHMAC + } + return &Custom{ + SetKeyAlgorithm: setKeyAlgorithm, + Hash: crypto.SHA512, + CipherEncryption: packet.CipherAES256, + CipherKeyEncryption: packet.CipherAES256, + CompressionAlgorithm: packet.CompressionZLIB, + AeadKeyEncryption: &packet.AEADConfig{ + DefaultMode: packet.AEADModeGCM, + }, + AeadEncryption: &packet.AEADConfig{ + DefaultMode: packet.AEADModeGCM, + }, + CompressionConfiguration: &packet.CompressionConfig{ + Level: 6, + }, + S2kKeyEncryption: &s2k.Config{ + S2KMode: s2k.Argon2S2K, + Argon2Config: &s2k.Argon2Config{}, + }, + S2kEncryption: &s2k.Config{ + S2KMode: s2k.Argon2S2K, + Argon2Config: &s2k.Argon2Config{}, + }, + V6: true, + } +} + +// ProtonV1 is the version 1 profile used in proton clients. +func ProtonV1() *Custom { + setKeyAlgorithm := func(cfg *packet.Config, securityLevel int8) { + cfg.Algorithm = packet.PubKeyAlgoEdDSA + switch securityLevel { + case constants.HighSecurity: + cfg.Curve = packet.Curve25519 + default: + cfg.Curve = packet.Curve25519 + } + } + s2kConfig := s2k.Config{ + S2KMode: s2k.IteratedSaltedS2K, + Hash: crypto.SHA256, + S2KCount: 65536, + } + return &Custom{ + SetKeyAlgorithm: setKeyAlgorithm, + Hash: crypto.SHA512, + CipherEncryption: packet.CipherAES256, + CipherKeyEncryption: packet.CipherAES256, + CompressionAlgorithm: packet.CompressionZLIB, + CompressionConfiguration: &packet.CompressionConfig{ + Level: 6, + }, + S2kKeyEncryption: &s2kConfig, + S2kEncryption: &s2kConfig, + DisableIntendedRecipients: true, + AllowAllPublicKeyAlgorithms: true, + InsecureAllowWeakRSA: true, + InsecureAllowDecryptionWithSigningKeys: true, + } +} diff --git a/profile/profile.go b/profile/profile.go index 3018e1f6..25ce12c2 100644 --- a/profile/profile.go +++ b/profile/profile.go @@ -24,7 +24,12 @@ type Custom struct { // S2kKeyEncryption defines the s2k algorithm for key encryption. S2kKeyEncryption *s2k.Config // AeadEncryption defines the aead encryption algorithm for pgp encryption. + // If nil, aead is disabled even if the key supports it. AeadEncryption *packet.AEADConfig + // KeyGenAeadEncryption defines if the output key in key generation + // advertises SEIPDv2 and aead algorithms in its key preferences. + // If nil, uses AeadEncryption as key preferences. + KeyGenAeadEncryption *packet.AEADConfig // S2kEncryption defines the s2k algorithm for pgp encryption. S2kEncryption *s2k.Config // CompressionConfiguration defines the compression configuration to be used if any. @@ -56,10 +61,14 @@ type Custom struct { // KeyGenerationProfile, KeyEncryptionProfile, EncryptionProfile, and SignProfile func (p *Custom) KeyGenerationConfig(securityLevel int8) *packet.Config { + aeadConfig := p.AeadEncryption + if p.KeyGenAeadEncryption != nil { + aeadConfig = p.KeyGenAeadEncryption + } cfg := &packet.Config{ DefaultHash: p.Hash, DefaultCipher: p.CipherEncryption, - AEADConfig: p.AeadEncryption, + AEADConfig: aeadConfig, DefaultCompressionAlgo: p.CompressionAlgorithm, CompressionConfig: p.CompressionConfiguration, V6Keys: p.V6,