Merge branch 'gopenpgp' into 'master'

Rename go-pm-crypto to gopenpgp; prepare move to GitHub

See merge request ProtonMail/go-pm-crypto!22
This commit is contained in:
Daniel Huigens 2019-05-14 16:14:01 +00:00
commit 1376870ff3
29 changed files with 178 additions and 191 deletions

View file

@ -1,34 +0,0 @@
variables:
# Please edit to your GitLab project
REPO_NAME: github.com/ProtonMail/go-pm-crypto
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- export PATH=/opt/local/bin:$PATH
- mkdir -p $GOPATH/src/$(dirname $REPO_NAME)
- ln -svf $CI_PROJECT_DIR $GOPATH/src/$REPO_NAME
- cd $GOPATH/src/$REPO_NAME
- glide install
stages:
- test
test-all:
stage: test
image: gitlab.protontech.ch:4567/protonmail/import-export/linux
script:
- go test -coverprofile cover.out ./...
- mkdir reports
- go tool cover -html=cover.out -o reports/cover.html
- go run vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/main.go run crypto/... --enable-all -D govet -D interfacer -D gofmt -D prealloc -D gochecknoglobals -D goimports -D gosec -D gocritic -D gochecknoinits
tags:
- coverage
artifacts:
paths:
- reports
reports:
junit: reports/cover.html
when: always
expire_in: 5 days

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
(The MIT License)
Copyright (c) 2019 Proton Technologies AG
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View file

@ -2,7 +2,8 @@
## Download/Install
Manually `git clone` the repository into `$GOPATH/src/github.com/ProtonMail/go-pm-crypto`.
Run `go get -u github.com/ProtonMail/gopenpgp`, or manually `git clone` the
repository into `$GOPATH/src/github.com/ProtonMail/gopenpgp`.
This library is meant to be used together with https://github.com/ProtonMail/crypto.
@ -48,15 +49,15 @@ Encryption and decryption will use the AES256 algorithm by default.
#### Encrypt / Decrypt with password
```
var pmCrypto = PmCrypto{}
var pgp = GopenPGP{}
const password = "my secret password"
// Encrypt data with password
armor, err := pmCrypto.EncryptMessageWithPassword("my message", password)
armor, err := pgp.EncryptMessageWithPassword("my message", password)
// Decrypt data with password
message, err := pmCrypto.DecryptMessageWithPassword(armor, password)
message, err := pgp.DecryptMessageWithPassword(armor, password)
```
#### Encrypt / Decrypt with PGP keys
@ -76,13 +77,13 @@ privateKeyRing, err := crypto.ReadArmoredKeyRing(strings.NewReader(privkey))
publicKeyRing, err := crypto.ReadArmoredKeyRing(strings.NewReader(pubkey))
// encrypt message using public key and can be optionally signed using private key and passphrase
armor, err := pmCrypto.EncryptMessage("plain text", publicKeyRing, privateKeyRing, passphrase, false)
armor, err := pgp.EncryptMessage("plain text", publicKeyRing, privateKeyRing, passphrase, false)
// OR
privateKeyRing.Unlock([]byte(passphrase)) // if private key is locked with passphrase
armor, err := publicKeyRing.EncryptString("plain text", privateKeyRing)
// decrypt armored encrypted message using the private key and the passphrase of the private key
plainText, err := pmCrypto.DecryptMessage(armor, privateKeyRing, passphrase)
plainText, err := pgp.DecryptMessage(armor, privateKeyRing, passphrase)
// OR
signedText, err := privateKeyRing.DecryptString(armor)
plainText = signedText.String
@ -93,7 +94,7 @@ plainText = signedText.String
Keys are generated with the `GenerateKey` function, that returns the armored key as a string and a potential error.
The library supports RSA with different key lengths or Curve25519 keys.
```
var pmCrypto = PmCrypto{}
var pgp = GopenPGP{}
var (
localPart = "name.surname"
@ -104,10 +105,10 @@ var (
)
// RSA
rsaKey, err := pmCrypto.GenerateKey(localPart, domain, passphrase, "rsa", rsaBits)
rsaKey, err := pgp.GenerateKey(localPart, domain, passphrase, "rsa", rsaBits)
// Curve 25519
ecKey, err := pmCrypto.GenerateKey(localPart, domain, passphrase, "x25519", ecBits)
ecKey, err := pgp.GenerateKey(localPart, domain, passphrase, "x25519", ecBits)
```
### Sign

View file

@ -4,8 +4,8 @@ package armor
import (
"bytes"
"errors"
"github.com/ProtonMail/go-pm-crypto/constants"
"github.com/ProtonMail/go-pm-crypto/internal"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/ProtonMail/gopenpgp/internal"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/clearsign"
"io"

View file

@ -10,13 +10,13 @@ mkdir -p $IOS_OUT
# CHECK="${1-0}"
# if [ ${CHECK} -eq "1" ]; then
printf "\e[0;32mStart Building iOS framework .. Location: ${IOS_OUT} \033[0m\n\n"
PACKAGE_PATH=github.com/ProtonMail/go-pm-crypto
PACKAGE_PATH=github.com/ProtonMail/gopenpgp
gomobile bind -target ios -o ${IOS_OUT}/Crypto.framework $PACKAGE_PATH/crypto $PACKAGE_PATH/armor $PACKAGE_PATH/constants $PACKAGE_PATH/key $PACKAGE_PATH/models
printf "\e[0;32mStart Building Android lib .. Location: ${ANDROID_OUT} \033[0m\n\n"
gomobile bind -target android -javapkg com.proton.pmcrypto -o ${ANDROID_OUT}/pmcrypto.aar $PACKAGE_PATH/crypto $PACKAGE_PATH/armor $PACKAGE_PATH/constants $PACKAGE_PATH/key $PACKAGE_PATH/models
gomobile bind -target android -javapkg com.proton.gopenpgp -o ${ANDROID_OUT}/gopenpgp.aar $PACKAGE_PATH/crypto $PACKAGE_PATH/armor $PACKAGE_PATH/constants $PACKAGE_PATH/key $PACKAGE_PATH/models
printf "\e[0;32mInstalling frameworks. \033[0m\n\n"

View file

@ -8,9 +8,9 @@ import (
"runtime"
"sync"
armorUtils "github.com/ProtonMail/go-pm-crypto/armor"
"github.com/ProtonMail/go-pm-crypto/constants"
"github.com/ProtonMail/go-pm-crypto/models"
armorUtils "github.com/ProtonMail/gopenpgp/armor"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/ProtonMail/gopenpgp/models"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
)
@ -47,7 +47,7 @@ func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
}
// encryptAttachment takes input data from file
func (pm *PmCrypto) encryptAttachment(
func (pgp *GopenPGP) encryptAttachment(
estimatedSize int, fileName string, publicKey *KeyRing, garbageCollector int,
) (*AttachmentProcessor, error) {
attachmentProc := &AttachmentProcessor{}
@ -61,7 +61,7 @@ func (pm *PmCrypto) encryptAttachment(
config := &packet.Config{
DefaultCipher: packet.CipherAES256,
Time: pm.getTimeGenerator(),
Time: pgp.getTimeGenerator(),
}
reader, writer := io.Pipe()
@ -90,10 +90,10 @@ func (pm *PmCrypto) encryptAttachment(
// EncryptAttachment encrypts attachment. Takes input data and key data in
// binary form
func (pm *PmCrypto) EncryptAttachment(
func (pgp *GopenPGP) EncryptAttachment(
plainData []byte, fileName string, publicKey *KeyRing,
) (*models.EncryptedSplit, error) {
ap, err := pm.encryptAttachment(len(plainData), fileName, publicKey, -1)
ap, err := pgp.encryptAttachment(len(plainData), fileName, publicKey, -1)
if err != nil {
return nil, err
}
@ -106,10 +106,10 @@ func (pm *PmCrypto) EncryptAttachment(
}
// EncryptAttachmentLowMemory with garbage collected every megabyte
func (pm *PmCrypto) EncryptAttachmentLowMemory(
func (pgp *GopenPGP) EncryptAttachmentLowMemory(
estimatedSize int, fileName string, publicKey *KeyRing,
) (*AttachmentProcessor, error) {
return pm.encryptAttachment(estimatedSize, fileName, publicKey, 1<<20)
return pgp.encryptAttachment(estimatedSize, fileName, publicKey, 1<<20)
}
// SplitArmor is a Helper method. Splits armored pgp session into key and packet data
@ -128,7 +128,7 @@ func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
// DecryptAttachment takes input data and key data in binary form. The
// privateKeys can contains more keys. The passphrase is used to unlock keys
func (pm *PmCrypto) DecryptAttachment(
func (pgp *GopenPGP) DecryptAttachment(
keyPacket, dataPacket []byte,
kr *KeyRing, passphrase string,
) ([]byte, error) {
@ -144,7 +144,7 @@ func (pm *PmCrypto) DecryptAttachment(
encryptedReader := io.MultiReader(keyReader, dataReader)
config := &packet.Config{Time: pm.getTimeGenerator()}
config := &packet.Config{Time: pgp.getTimeGenerator()}
md, err := openpgp.ReadMessage(encryptedReader, privKeyEntries, nil, config)
if err != nil {

View file

@ -58,12 +58,12 @@ func TestAttachmentSetKey(t *testing.T) {
func TestAttachnentEncryptDecrypt(t *testing.T) {
var testAttachmentCleartext = "cc,\ndille."
encSplit, err := pmCrypto.EncryptAttachment([]byte(testAttachmentCleartext), "s.txt", testPrivateKeyRing)
encSplit, err := pgp.EncryptAttachment([]byte(testAttachmentCleartext), "s.txt", testPrivateKeyRing)
if err != nil {
t.Fatal("Expected no error while encrypting attachment, got:", err)
}
redecData, err := pmCrypto.DecryptAttachment(encSplit.KeyPacket, encSplit.DataPacket, testPrivateKeyRing, "")
redecData, err := pgp.DecryptAttachment(encSplit.KeyPacket, encSplit.DataPacket, testPrivateKeyRing, "")
if err != nil {
t.Fatal("Expected no error while decrypting attachment, got:", err)
}

View file

@ -13,9 +13,9 @@ import (
"strings"
"time"
"github.com/ProtonMail/go-pm-crypto/armor"
"github.com/ProtonMail/go-pm-crypto/constants"
"github.com/ProtonMail/go-pm-crypto/models"
"github.com/ProtonMail/gopenpgp/armor"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/ProtonMail/gopenpgp/models"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
@ -275,8 +275,8 @@ func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) {
}
// IsKeyExpiredBin checks if the given key is expired. Input in binary format
func (pm *PmCrypto) IsKeyExpiredBin(publicKey []byte) (bool, error) {
now := pm.getNow()
func (pgp *GopenPGP) IsKeyExpiredBin(publicKey []byte) (bool, error) {
now := pgp.getNow()
pubKeyReader := bytes.NewReader(publicKey)
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
if err != nil {
@ -334,15 +334,15 @@ const (
)
// IsKeyExpired checks if the given key is expired. Input in armored format
func (pm *PmCrypto) IsKeyExpired(publicKey string) (bool, error) {
func (pgp *GopenPGP) IsKeyExpired(publicKey string) (bool, error) {
rawPubKey, err := armor.Unarmor(publicKey)
if err != nil {
return false, err
}
return pm.IsKeyExpiredBin(rawPubKey)
return pgp.IsKeyExpiredBin(rawPubKey)
}
func (pm *PmCrypto) generateKey(
func (pgp *GopenPGP) generateKey(
userName, domain, passphrase, keyType string,
bits int,
prime1, prime2, prime3, prime4 []byte,
@ -361,7 +361,7 @@ func (pm *PmCrypto) generateKey(
cfg := &packet.Config{
Algorithm: packet.PubKeyAlgoRSA,
RSABits: bits,
Time: pm.getTimeGenerator(),
Time: pgp.getTimeGenerator(),
DefaultHash: crypto.SHA256,
DefaultCipher: packet.CipherAES256,
}
@ -417,22 +417,22 @@ func (pm *PmCrypto) generateKey(
}
// GenerateRSAKeyWithPrimes generates RSA key with given primes.
func (pm *PmCrypto) GenerateRSAKeyWithPrimes(
func (pgp *GopenPGP) GenerateRSAKeyWithPrimes(
userName, domain, passphrase string,
bits int,
primeone, primetwo, primethree, primefour []byte,
) (string, error) {
return pm.generateKey(userName, domain, passphrase, "rsa", bits, primeone, primetwo, primethree, primefour)
return pgp.generateKey(userName, domain, passphrase, "rsa", bits, primeone, primetwo, primethree, primefour)
}
// GenerateKey and generate primes
func (pm *PmCrypto) GenerateKey(userName, domain, passphrase, keyType string, bits int) (string, error) {
return pm.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil)
func (pgp *GopenPGP) GenerateKey(userName, domain, passphrase, keyType string, bits int) (string, error) {
return pgp.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil)
}
// UpdatePrivateKeyPassphrase decrypts the given private key with oldPhrase and
// re-encrypts with the newPassphrase
func (pm *PmCrypto) UpdatePrivateKeyPassphrase(
func (pgp *GopenPGP) UpdatePrivateKeyPassphrase(
privateKey string, oldPassphrase string, newPassphrase string,
) (string, error) {
privKey := strings.NewReader(privateKey)
@ -478,7 +478,7 @@ func (pm *PmCrypto) UpdatePrivateKeyPassphrase(
}
// CheckKey prints out the key and subkey fingerprint
func (pm *PmCrypto) CheckKey(pubKey string) (string, error) {
func (pgp *GopenPGP) CheckKey(pubKey string) (string, error) {
pubKeyReader := strings.NewReader(pubKey)
entries, err := openpgp.ReadArmoredKeyRing(pubKeyReader)
if err != nil {

View file

@ -6,7 +6,7 @@ import (
"strings"
"testing"
"github.com/ProtonMail/go-pm-crypto/constants"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/stretchr/testify/assert"
)
@ -24,12 +24,12 @@ var (
)
func TestGenerateKeys(t *testing.T) {
rsaKey, err = pmCrypto.GenerateKey(name, domain, passphrase, "rsa", 1024)
rsaKey, err = pgp.GenerateKey(name, domain, passphrase, "rsa", 1024)
if err != nil {
t.Fatal("Cannot generate RSA key:", err)
}
ecKey, err = pmCrypto.GenerateKey(name, domain, passphrase, "x25519", 256)
ecKey, err = pgp.GenerateKey(name, domain, passphrase, "x25519", 256)
if err != nil {
t.Fatal("Cannot generate EC key:", err)
}
@ -111,12 +111,12 @@ func TestEncryptDecryptKeys(t *testing.T) {
func TestUpdatePrivateKeysPassphrase(t *testing.T) {
newPassphrase := "I like GNU"
rsaKey, err = pmCrypto.UpdatePrivateKeyPassphrase(rsaKey, passphrase, newPassphrase)
rsaKey, err = pgp.UpdatePrivateKeyPassphrase(rsaKey, passphrase, newPassphrase)
if err != nil {
t.Fatal("Error in changing RSA key's passphrase:", err)
}
ecKey, err = pmCrypto.UpdatePrivateKeyPassphrase(ecKey, passphrase, newPassphrase)
ecKey, err = pgp.UpdatePrivateKeyPassphrase(ecKey, passphrase, newPassphrase)
if err != nil {
t.Fatal("Error in changing EC key's passphrase:", err)
}
@ -125,19 +125,19 @@ func TestUpdatePrivateKeysPassphrase(t *testing.T) {
}
func ExampleCheckKeys() {
_, _ = pmCrypto.CheckKey(readTestFile("keyring_publicKey", false))
_, _ = pgp.CheckKey(readTestFile("keyring_publicKey", false))
// Output:
// SubKey:37e4bcf09b36e34012d10c0247dc67b5cb8267f6
// PrimaryKey:6e8ba229b0cccaf6962f97953eb6259edf21df24
}
func TestIsKeyExpired(t *testing.T) {
rsaRes, err := pmCrypto.IsKeyExpired(rsaPublicKey)
rsaRes, err := pgp.IsKeyExpired(rsaPublicKey)
if err != nil {
t.Fatal("Error in checking expiration of RSA key:", err)
}
ecRes, err := pmCrypto.IsKeyExpired(ecPublicKey)
ecRes, err := pgp.IsKeyExpired(ecPublicKey)
if err != nil {
t.Fatal("Error in checking expiration of EC key:", err)
}
@ -145,10 +145,10 @@ func TestIsKeyExpired(t *testing.T) {
assert.Exactly(t, false, rsaRes)
assert.Exactly(t, false, ecRes)
pmCrypto.UpdateTime(1557754627) // 2019-05-13T13:37:07+00:00
pgp.UpdateTime(1557754627) // 2019-05-13T13:37:07+00:00
expRes, expErr := pmCrypto.IsKeyExpired(readTestFile("key_expiredKey", false))
futureRes, futureErr := pmCrypto.IsKeyExpired(readTestFile("key_futureKey", false))
expRes, expErr := pgp.IsKeyExpired(readTestFile("key_expiredKey", false))
futureRes, futureErr := pgp.IsKeyExpired(readTestFile("key_futureKey", false))
assert.Exactly(t, true, expRes)
assert.Exactly(t, true, futureRes)

View file

@ -19,9 +19,9 @@ import (
"golang.org/x/crypto/openpgp/packet"
xrsa "golang.org/x/crypto/rsa"
armorUtils "github.com/ProtonMail/go-pm-crypto/armor"
"github.com/ProtonMail/go-pm-crypto/constants"
"github.com/ProtonMail/go-pm-crypto/models"
armorUtils "github.com/ProtonMail/gopenpgp/armor"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/ProtonMail/gopenpgp/models"
)
// A keypair contains a private key and a public key.
@ -131,7 +131,7 @@ func (kr *KeyRing) GetSigningEntity(passphrase string) (*openpgp.Entity, error)
}
}
if signEntity == nil {
err := errors.New("pmcrypto: cannot sign message, unable to unlock signer key")
err := errors.New("gopenpgp: cannot sign message, unable to unlock signer key")
return signEntity, err
}
@ -172,7 +172,7 @@ func (kr *KeyRing) Encrypt(w io.Writer, sign *KeyRing, filename string, canonica
signEntity,
filename,
canonicalizeText,
func() time.Time { return GetPmCrypto().GetTime() })
func() time.Time { return GetGopenPGP().GetTime() })
}
// EncryptCore is common encryption method for desktop and mobile clients
@ -332,7 +332,7 @@ func (kr *KeyRing) DetachedSign(w io.Writer, toSign io.Reader, canonicalizeText
config := &packet.Config{DefaultCipher: packet.CipherAES256,
Time: func() time.Time {
return GetPmCrypto().GetTime()
return GetGopenPGP().GetTime()
},
}
@ -399,7 +399,7 @@ func (kr *KeyRing) Unlock(passphrase []byte) error {
}
if len(keys) == 0 {
return errors.New("go-pm-crypto: cannot unlock key ring, no private key available")
return errors.New("gopenpgp: cannot unlock key ring, no private key available")
}
var err error
@ -588,7 +588,7 @@ func (kr *KeyRing) readFrom(r io.Reader, armored bool) error {
}
// BuildKeyRing reads keyring from binary data
func (pm *PmCrypto) BuildKeyRing(binKeys []byte) (kr *KeyRing, err error) {
func (pgp *GopenPGP) BuildKeyRing(binKeys []byte) (kr *KeyRing, err error) {
kr = &KeyRing{}
entriesReader := bytes.NewReader(binKeys)
err = kr.readFrom(entriesReader, false)
@ -597,13 +597,13 @@ func (pm *PmCrypto) BuildKeyRing(binKeys []byte) (kr *KeyRing, err error) {
}
// BuildKeyRingNoError does not return error on fail
func (pm *PmCrypto) BuildKeyRingNoError(binKeys []byte) (kr *KeyRing) {
kr, _ = pm.BuildKeyRing(binKeys)
func (pgp *GopenPGP) BuildKeyRingNoError(binKeys []byte) (kr *KeyRing) {
kr, _ = pgp.BuildKeyRing(binKeys)
return
}
// BuildKeyRingArmored reads armored string and returns keyring
func (pm *PmCrypto) BuildKeyRingArmored(key string) (kr *KeyRing, err error) {
func (pgp *GopenPGP) BuildKeyRingArmored(key string) (kr *KeyRing, err error) {
keyRaw, err := armorUtils.Unarmor(key)
if err != nil {
return nil, err

View file

@ -8,7 +8,7 @@ import (
"golang.org/x/crypto/openpgp/armor"
"github.com/ProtonMail/go-pm-crypto/constants"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/stretchr/testify/assert"
)

View file

@ -14,17 +14,17 @@ import (
pgpErrors "golang.org/x/crypto/openpgp/errors"
"golang.org/x/crypto/openpgp/packet"
armorUtils "github.com/ProtonMail/go-pm-crypto/armor"
"github.com/ProtonMail/go-pm-crypto/constants"
"github.com/ProtonMail/go-pm-crypto/internal"
"github.com/ProtonMail/go-pm-crypto/models"
armorUtils "github.com/ProtonMail/gopenpgp/armor"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/ProtonMail/gopenpgp/internal"
"github.com/ProtonMail/gopenpgp/models"
)
// DecryptMessageStringKey decrypts encrypted message use private key (string)
// encryptedText : string armored encrypted
// privateKey : armored private use to decrypt message
// passphrase : match with private key to decrypt message
func (pm *PmCrypto) DecryptMessageStringKey(
func (pgp *GopenPGP) DecryptMessageStringKey(
encryptedText, privateKey, passphrase string,
) (string, error) {
privKeyRaw, err := armorUtils.Unarmor(privateKey)
@ -37,15 +37,15 @@ func (pm *PmCrypto) DecryptMessageStringKey(
return "", err
}
return pm.DecryptMessage(encryptedText, &KeyRing{entities: privKeyEntries}, passphrase)
return pgp.DecryptMessage(encryptedText, &KeyRing{entities: privKeyEntries}, passphrase)
}
// DecryptMessage decrypts encrypted string using keyring
// encryptedText : string armored encrypted
// privateKey : keyring with private key to decrypt message, could be multiple keys
// passphrase : match with private key to decrypt message
func (pm *PmCrypto) DecryptMessage(encryptedText string, privateKey *KeyRing, passphrase string) (string, error) {
md, err := decryptCore(encryptedText, nil, privateKey, passphrase, pm.getTimeGenerator())
func (pgp *GopenPGP) DecryptMessage(encryptedText string, privateKey *KeyRing, passphrase string) (string, error) {
md, err := decryptCore(encryptedText, nil, privateKey, passphrase, pgp.getTimeGenerator())
if err != nil {
return "", err
}
@ -92,7 +92,7 @@ func decryptCore(
// verifierKey []byte: unarmored verifier keys
// privateKeyRing []byte: unarmored private key to decrypt. could be multiple
// passphrase: match with private key to decrypt message
func (pm *PmCrypto) DecryptMessageVerify(
func (pgp *GopenPGP) DecryptMessageVerify(
encryptedText string, verifierKey, privateKeyRing *KeyRing,
passphrase string, verifyTime int64,
) (*models.DecryptSignedVerify, error) {
@ -171,14 +171,14 @@ func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
// EncryptMessageWithPassword encrypts a plain text to pgp message with a password
// plainText string: clear text
// output string: armored pgp message
func (pm *PmCrypto) EncryptMessageWithPassword(plainText string, password string) (string, error) {
func (pgp *GopenPGP) EncryptMessageWithPassword(plainText string, password string) (string, error) {
var outBuf bytes.Buffer
w, err := armor.Encode(&outBuf, constants.PGPMessageHeader, internal.ArmorHeaders)
if err != nil {
return "", err
}
config := &packet.Config{Time: pm.getTimeGenerator()}
config := &packet.Config{Time: pgp.getTimeGenerator()}
plaintext, err := openpgp.SymmetricallyEncrypt(w, []byte(password), nil, config)
if err != nil {
return "", err
@ -204,7 +204,7 @@ func (pm *PmCrypto) EncryptMessageWithPassword(plainText string, password string
// privateKey : optional required when you want to sign
// passphrase : optional required when you pass the private key and this passphrase should decrypt the private key
// trim : bool true if need to trim new lines
func (pm *PmCrypto) EncryptMessage(
func (pgp *GopenPGP) EncryptMessage(
plainText string, publicKey, privateKey *KeyRing,
passphrase string, trim bool,
) (string, error) {
@ -227,7 +227,7 @@ func (pm *PmCrypto) EncryptMessage(
}
}
ew, err := EncryptCore(w, publicKey.entities, signEntity, "", false, pm.getTimeGenerator())
ew, err := EncryptCore(w, publicKey.entities, signEntity, "", false, pgp.getTimeGenerator())
if err != nil {
return "", err
}
@ -241,7 +241,7 @@ func (pm *PmCrypto) EncryptMessage(
// DecryptMessageWithPassword decrypts a pgp message with a password
// encrypted string : armored pgp message
// output string : clear text
func (pm *PmCrypto) DecryptMessageWithPassword(encrypted string, password string) (string, error) {
func (pgp *GopenPGP) DecryptMessageWithPassword(encrypted string, password string) (string, error) {
encryptedio, err := internal.Unarmor(encrypted)
if err != nil {
return "", err
@ -256,7 +256,7 @@ func (pm *PmCrypto) DecryptMessageWithPassword(encrypted string, password string
return nil, errors.New("password incorrect")
}
config := &packet.Config{Time: pm.getTimeGenerator()}
config := &packet.Config{Time: pgp.getTimeGenerator()}
md, err := openpgp.ReadMessage(encryptedio.Body, nil, prompt, config)
if err != nil {
return "", err

View file

@ -7,20 +7,20 @@ import (
)
func TestMessageEncryptionWithPassword(t *testing.T) {
var pmCrypto = PmCrypto{}
var pgp = GopenPGP{}
const password = "my secret password"
// Encrypt data with password
armor, err := pmCrypto.EncryptMessageWithPassword("my message", password)
armor, err := pgp.EncryptMessageWithPassword("my message", password)
if err != nil {
t.Fatal("Expected no error when encrypting, got:", err)
}
// Decrypt data with wrong password
_, err = pmCrypto.DecryptMessageWithPassword(armor, "wrong password")
_, err = pgp.DecryptMessageWithPassword(armor, "wrong password")
assert.NotNil(t, err)
// Decrypt data with the good password
text, err := pmCrypto.DecryptMessageWithPassword(armor, password)
text, err := pgp.DecryptMessageWithPassword(armor, password)
if err != nil {
t.Fatal("Expected no error when decrypting, got:", err)
}
@ -28,7 +28,7 @@ func TestMessageEncryptionWithPassword(t *testing.T) {
}
func TestMessageEncryption(t *testing.T) {
var pmCrypto = PmCrypto{}
var pgp = GopenPGP{}
var (
message = "plain text"
)
@ -37,11 +37,11 @@ func TestMessageEncryption(t *testing.T) {
_ = testPrivateKeyRing.Unlock([]byte(testMailboxPassword))
testPublicKeyRing, _ = ReadArmoredKeyRing(strings.NewReader(readTestFile("keyring_publicKey", false)))
armor, err := pmCrypto.EncryptMessage(message, testPublicKeyRing, testPrivateKeyRing, testMailboxPassword, false)
armor, err := pgp.EncryptMessage(message, testPublicKeyRing, testPrivateKeyRing, testMailboxPassword, false)
if err != nil {
t.Fatal("Expected no error when encrypting, got:", err)
}
plainText, err := pmCrypto.DecryptMessage(armor, testPrivateKeyRing, testMailboxPassword)
plainText, err := pgp.DecryptMessage(armor, testPrivateKeyRing, testMailboxPassword)
if err != nil {
t.Fatal("Expected no error when decrypting, got:", err)
}

View file

@ -7,20 +7,20 @@ import (
"net/textproto"
"strings"
pmmime "github.com/ProtonMail/go-pm-mime"
pmmime "github.com/ProtonMail/go-mime"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
)
func (pm PmCrypto) parseMIME(
func (pgp GopenPGP) parseMIME(
mimeBody string, verifierKey *KeyRing,
) (*pmmime.BodyCollector, int, []string, []string, error) {
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
if err != nil {
return nil, 0, nil, nil, err
}
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator()}
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pgp.getTimeGenerator()}
h := textproto.MIMEHeader(mm.Header)
mmBodyData, err := ioutil.ReadAll(mm.Body)
@ -61,17 +61,17 @@ type MIMECallbacks interface {
}
// DecryptMIMEMessage decrypts a MIME message
func (pm *PmCrypto) DecryptMIMEMessage(
func (pgp *GopenPGP) DecryptMIMEMessage(
encryptedText string, verifierKey, privateKeyRing *KeyRing,
passphrase string, callbacks MIMECallbacks, verifyTime int64,
) {
decsignverify, err := pm.DecryptMessageVerify(encryptedText, verifierKey, privateKeyRing, passphrase, verifyTime)
decsignverify, err := pgp.DecryptMessageVerify(encryptedText, verifierKey, privateKeyRing, passphrase, verifyTime)
if err != nil {
callbacks.OnError(err)
return
}
body, verified, attachments, attachmentHeaders, err := pm.parseMIME(decsignverify.Plaintext, verifierKey)
body, verified, attachments, attachmentHeaders, err := pgp.parseMIME(decsignverify.Plaintext, verifierKey)
if err != nil {
callbacks.OnError(err)
return

View file

@ -2,7 +2,7 @@ package crypto
import (
"github.com/stretchr/testify/assert"
"github.com/ProtonMail/go-pm-crypto/internal"
"github.com/ProtonMail/gopenpgp/internal"
"io/ioutil"
"testing"
)
@ -53,17 +53,17 @@ func TestDecrypt(t *testing.T) {
privateKeyUnarmored, _ := ioutil.ReadAll(block.Body)
pmCrypto.DecryptMIMEMessage(
pgp.DecryptMIMEMessage(
readTestFile("mime_pgpMessage", false),
pmCrypto.BuildKeyRingNoError(publicKeyUnarmored),
pmCrypto.BuildKeyRingNoError(privateKeyUnarmored),
pgp.BuildKeyRingNoError(publicKeyUnarmored),
pgp.BuildKeyRingNoError(privateKeyUnarmored),
privateKeyPassword,
&callbacks,
pmCrypto.GetTimeUnix())
pgp.GetTimeUnix())
}
func TestParse(t *testing.T) {
body, _, atts, attHeaders, err := pmCrypto.parseMIME(readTestFile("mime_testMessage", false), nil)
body, _, atts, attHeaders, err := pgp.parseMIME(readTestFile("mime_testMessage", false), nil)
if err != nil {
t.Error("Expected no error while parsing message, got:", err)

View file

@ -6,9 +6,9 @@ package crypto
import "time"
// PmCrypto structure is used to manage server time shift. It should be also used for any
// GopenPGP structure is used to manage server time shift. It should be also used for any
// other specific general cryptographic entities.
type PmCrypto struct {
type GopenPGP struct {
//latestServerTime unix time cache
latestServerTime int64
latestClientTime time.Time

View file

@ -6,15 +6,15 @@ import (
"fmt"
"io"
"github.com/ProtonMail/go-pm-crypto/armor"
"github.com/ProtonMail/go-pm-crypto/constants"
"github.com/ProtonMail/gopenpgp/armor"
"github.com/ProtonMail/gopenpgp/constants"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
)
// RandomToken with a default key size
func (pm *PmCrypto) RandomToken() ([]byte, error) {
func (pgp *GopenPGP) RandomToken() ([]byte, error) {
config := &packet.Config{DefaultCipher: packet.CipherAES256}
keySize := config.DefaultCipher.KeySize()
symKey := make([]byte, keySize)
@ -25,7 +25,7 @@ func (pm *PmCrypto) RandomToken() ([]byte, error) {
}
// RandomTokenWith a given key size
func (pm *PmCrypto) RandomTokenWith(size int) ([]byte, error) {
func (pgp *GopenPGP) RandomTokenWith(size int) ([]byte, error) {
config := &packet.Config{DefaultCipher: packet.CipherAES256}
symKey := make([]byte, size)
if _, err := io.ReadFull(config.Random(), symKey); err != nil {
@ -35,7 +35,7 @@ func (pm *PmCrypto) RandomTokenWith(size int) ([]byte, error) {
}
// GetSessionFromKeyPacket gets session key no encoding in and out
func (pm *PmCrypto) GetSessionFromKeyPacket(
func (pgp *GopenPGP) GetSessionFromKeyPacket(
keyPackage []byte, privateKey *KeyRing, passphrase string,
) (*SymmetricKey,
error) {
@ -73,16 +73,16 @@ func (pm *PmCrypto) GetSessionFromKeyPacket(
}
// KeyPacketWithPublicKey returns binary packet from symmetric key and armored public key
func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey string) ([]byte, error) {
func (pgp *GopenPGP) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey string) ([]byte, error) {
pubkeyRaw, err := armor.Unarmor(publicKey)
if err != nil {
return nil, err
}
return pm.KeyPacketWithPublicKeyBin(sessionSplit, pubkeyRaw)
return pgp.KeyPacketWithPublicKeyBin(sessionSplit, pubkeyRaw)
}
// KeyPacketWithPublicKeyBin returns binary packet from symmetric key and binary public key
func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, publicKey []byte) ([]byte, error) {
func (pgp *GopenPGP) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, publicKey []byte) ([]byte, error) {
publicKeyReader := bytes.NewReader(publicKey)
pubKeyEntries, err := openpgp.ReadKeyRing(publicKeyReader)
if err != nil {
@ -130,7 +130,7 @@ func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, public
}
// GetSessionFromSymmetricPacket extracts symmentric key from binary packet
func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*SymmetricKey, error) {
func (pgp *GopenPGP) GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*SymmetricKey, error) {
keyReader := bytes.NewReader(keyPackage)
packets := packet.NewReader(keyReader)
@ -168,7 +168,7 @@ func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password st
}
// SymmetricKeyPacketWithPassword return binary packet from symmetric key and password
func (pm *PmCrypto) SymmetricKeyPacketWithPassword(sessionSplit *SymmetricKey, password string) ([]byte, error) {
func (pgp *GopenPGP) SymmetricKeyPacketWithPassword(sessionSplit *SymmetricKey, password string) ([]byte, error) {
outbuf := &bytes.Buffer{}
cf := sessionSplit.GetCipherFunc()

View file

@ -7,7 +7,7 @@ import (
"strings"
"time"
"github.com/ProtonMail/go-pm-crypto/internal"
"github.com/ProtonMail/gopenpgp/internal"
"golang.org/x/crypto/openpgp"
errorsPGP "golang.org/x/crypto/openpgp/errors"
@ -15,7 +15,7 @@ import (
)
// SignTextDetached signs detached text type
func (pm *PmCrypto) SignTextDetached(
func (pgp *GopenPGP) SignTextDetached(
plainText string, privateKey *KeyRing, passphrase string, trim bool,
) (string, error) {
//sign with 0x01 text
@ -28,7 +28,7 @@ func (pm *PmCrypto) SignTextDetached(
return "", err
}
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator()}
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pgp.getTimeGenerator()}
att := strings.NewReader(plainText)
@ -42,14 +42,14 @@ func (pm *PmCrypto) SignTextDetached(
}
// SignBinDetached Signs detached bin data using string key
func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passphrase string) (string, error) {
func (pgp *GopenPGP) SignBinDetached(plainData []byte, privateKey *KeyRing, passphrase string) (string, error) {
//sign with 0x00
signEntity, err := privateKey.GetSigningEntity(passphrase)
if err != nil {
return "", err
}
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator()}
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pgp.getTimeGenerator()}
att := bytes.NewReader(plainData)
@ -64,7 +64,7 @@ func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passp
// VerifyTextDetachedSig verifies detached text
// - check if signature is valid using a given publicKey in binary format
func (pm *PmCrypto) VerifyTextDetachedSig(
func (pgp *GopenPGP) VerifyTextDetachedSig(
signature string, plainText string, publicKey *KeyRing, verifyTime int64,
) (bool, error) {
plainText = internal.TrimNewlines(plainText)
@ -112,7 +112,7 @@ func verifySignature(
}
if signer == nil {
return false, errors.New("pmcrypto: signer is empty")
return false, errors.New("gopenpgp: signer is empty")
}
// if signer.PrimaryKey.KeyId != signed.PrimaryKey.KeyId {
// // t.Errorf("wrong signer got:%x want:%x", signer.PrimaryKey.KeyId, 0)
@ -123,7 +123,7 @@ func verifySignature(
// VerifyBinDetachedSig verifies detached text in binary format
// - check if signature is valid using a given publicKey in binary format
func (pm *PmCrypto) VerifyBinDetachedSig(
func (pgp *GopenPGP) VerifyBinDetachedSig(
signature string, plainData []byte, publicKey *KeyRing, verifyTime int64,
) (bool, error) {
origText := bytes.NewReader(plainData)

View file

@ -7,7 +7,7 @@ import (
"mime"
"net/textproto"
"github.com/ProtonMail/go-pm-mime"
"github.com/ProtonMail/go-mime"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"

View file

@ -1,8 +1,8 @@
package crypto
import (
"strings"
"regexp"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@ -20,11 +20,11 @@ func TestSignTextDetached(t *testing.T) {
t.Fatal("Cannot read private key:", err)
}
signature, err = pmCrypto.SignTextDetached(signedPlainText, signingKeyRing, "", true)
assert.EqualError(t, err, "pmcrypto: cannot sign message, unable to unlock signer key")
signature, err = pgp.SignTextDetached(signedPlainText, signingKeyRing, "", true)
assert.EqualError(t, err, "gopenpgp: cannot sign message, unable to unlock signer key")
// Password defined in keyring_test
signature, err = pmCrypto.SignTextDetached(signedPlainText, signingKeyRing, testMailboxPassword, true)
signature, err = pgp.SignTextDetached(signedPlainText, signingKeyRing, testMailboxPassword, true)
if err != nil {
t.Fatal("Cannot generate signature with encrypted key:", err)
}
@ -37,7 +37,7 @@ func TestSignTextDetached(t *testing.T) {
t.Fatal("Cannot decrypt private key:", err)
}
signatureDec, err := pmCrypto.SignTextDetached(signedPlainText, signingKeyRing, "", true)
signatureDec, err := pgp.SignTextDetached(signedPlainText, signingKeyRing, "", true)
if err != nil {
t.Fatal("Cannot generate signature with decrypted key:", err)
}
@ -52,11 +52,11 @@ func TestSignBinDetached(t *testing.T) {
// Reset keyring to locked state
signingKeyRing, _ = ReadArmoredKeyRing(strings.NewReader(readTestFile("keyring_privateKey", false)))
signatureBin, err = pmCrypto.SignBinDetached([]byte(signedPlainText), signingKeyRing, "")
assert.EqualError(t, err, "pmcrypto: cannot sign message, unable to unlock signer key")
signatureBin, err = pgp.SignBinDetached([]byte(signedPlainText), signingKeyRing, "")
assert.EqualError(t, err, "gopenpgp: cannot sign message, unable to unlock signer key")
// Password defined in keyring_test
signatureBin, err = pmCrypto.SignBinDetached([]byte(signedPlainText), signingKeyRing, testMailboxPassword)
signatureBin, err = pgp.SignBinDetached([]byte(signedPlainText), signingKeyRing, testMailboxPassword)
if err != nil {
t.Fatal("Cannot generate signature with encrypted key:", err)
}
@ -66,7 +66,7 @@ func TestSignBinDetached(t *testing.T) {
}
func TestVerifyTextDetachedSig(t *testing.T) {
verified, err := pmCrypto.VerifyTextDetachedSig(signature, signedPlainText, signingKeyRing, testTime)
verified, err := pgp.VerifyTextDetachedSig(signature, signedPlainText, signingKeyRing, testTime)
if err != nil {
t.Fatal("Cannot verify plaintext signature:", err)
}
@ -75,15 +75,14 @@ func TestVerifyTextDetachedSig(t *testing.T) {
}
func TestVerifyTextDetachedSigWrong(t *testing.T) {
verified, err := pmCrypto.VerifyTextDetachedSig(signature, "wrong text", signingKeyRing, testTime)
verified, err := pgp.VerifyTextDetachedSig(signature, "wrong text", signingKeyRing, testTime)
assert.EqualError(t, err, "pmcrypto: signer is empty")
assert.EqualError(t, err, "gopenpgp: signer is empty")
assert.Exactly(t, false, verified)
}
func TestVerifyBinDetachedSig(t *testing.T) {
verified, err := pmCrypto.VerifyBinDetachedSig(signatureBin, []byte(signedPlainText), signingKeyRing, testTime)
verified, err := pgp.VerifyBinDetachedSig(signatureBin, []byte(signedPlainText), signingKeyRing, testTime)
if err != nil {
t.Fatal("Cannot verify binary signature:", err)
}

View file

@ -1,5 +1,5 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: PmCrypto.js v3.1.2
Version: GopenPGP.js v3.1.2
Comment: https://openpgpjs.org
xcaGBFtq/A4BEAC0VKmsQb6HKMWwcpBNaPdEDYTUOQRdA9MvaOgRqJRmxYAG

View file

@ -98,7 +98,7 @@ QkxPQ0stLS0tLQ0KDQo=
-----------------------f0e64db835d0f5c3674df52a164b06bb--
-----------------------4a9ea9f4dad3f36079bdb3f1e7b75bd0
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: PmCrypto digital signature
Content-Description: GopenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"
-----BEGIN PGP SIGNATURE-----

View file

@ -4,41 +4,41 @@ import (
"time"
)
var pmCrypto = PmCrypto{}
var pgp = GopenPGP{}
// GetPmCrypto return global PmCrypto
func GetPmCrypto() *PmCrypto {
return &pmCrypto
// GetGopenPGP return global GopenPGP
func GetGopenPGP() *GopenPGP {
return &pgp
}
// UpdateTime updates cached time
func (pm *PmCrypto) UpdateTime(newTime int64) {
pm.latestServerTime = newTime
pm.latestClientTime = time.Now()
func (pgp *GopenPGP) UpdateTime(newTime int64) {
pgp.latestServerTime = newTime
pgp.latestClientTime = time.Now()
}
// GetTimeUnix gets latest cached time
func (pm *PmCrypto) GetTimeUnix() int64 {
return pm.getNow().Unix()
func (pgp *GopenPGP) GetTimeUnix() int64 {
return pgp.getNow().Unix()
}
// GetTime gets latest cached time
func (pm *PmCrypto) GetTime() time.Time {
return pm.getNow()
func (pgp *GopenPGP) GetTime() time.Time {
return pgp.getNow()
}
func (pm *PmCrypto) getNow() time.Time {
if pm.latestServerTime > 0 && !pm.latestClientTime.IsZero() {
func (pgp *GopenPGP) getNow() time.Time {
if pgp.latestServerTime > 0 && !pgp.latestClientTime.IsZero() {
// Until is monotonic, it uses a monotonic clock in this case instead of the wall clock
extrapolate := int64(time.Until(pm.latestClientTime).Seconds())
return time.Unix(pm.latestServerTime+extrapolate, 0)
extrapolate := int64(time.Until(pgp.latestClientTime).Seconds())
return time.Unix(pgp.latestServerTime+extrapolate, 0)
}
return time.Now()
}
func (pm *PmCrypto) getTimeGenerator() func() time.Time {
func (pgp *GopenPGP) getTimeGenerator() func() time.Time {
return func() time.Time {
return pm.getNow()
return pgp.getNow()
}
}

Binary file not shown.

Binary file not shown.

4
glide.lock generated
View file

@ -42,9 +42,9 @@ imports:
- encoding/internal
- encoding/internal/identifier
- transform
- name: github.com/ProtonMail/go-pm-mime
- name: github.com/ProtonMail/go-mime
version: dc270ae56b61837aa404c828a14b8ea731167ac0
repo: https://gitlab.protontech.ch/ProtonMail/go-pm-mime.git
repo: https://github.com/ProtonMail/go-mime.git
testImports:
- name: github.com/davecgh/go-spew
version: d8f796af33cc11cb798c1aaeb27a4ebc5099927d

View file

@ -1,9 +1,9 @@
package: proton/pmcrypto
package: proton/gopenpgp
import:
- package: golang.org/x/crypto
version: master
repo: https://github.com/ProtonMail/crypto.git
version: 9e4251120d8c43f10024d798bc6dde21d40704a0
- package: github.com/ProtonMail/go-pm-mime
repo: https://gitlab.protontech.ch/ProtonMail/go-pm-mime.git
- package: github.com/ProtonMail/go-mime
repo: https://github.com/ProtonMail/go-mime.git

View file

@ -1,7 +1,7 @@
package internal
import (
"github.com/ProtonMail/go-pm-crypto/constants"
"github.com/ProtonMail/gopenpgp/constants"
"regexp"
)

View file