Add decryptMime and refactor package structure
This commit is contained in:
parent
07b3a2c739
commit
97e70855b8
27 changed files with 516 additions and 486 deletions
54
armor.go
54
armor.go
|
|
@ -1,54 +0,0 @@
|
|||
package pmcrypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/openpgp/armor"
|
||||
)
|
||||
|
||||
const (
|
||||
pgpMessageType string = "PGP MESSAGE"
|
||||
pgpPublicBlockType string = "PGP PUBLIC KEY BLOCK"
|
||||
pgpPrivateBlockType string = "PGP PRIVATE KEY BLOCK"
|
||||
)
|
||||
|
||||
// ArmorKey make bytes input key to armor format
|
||||
func ArmorKey(input []byte) (string, error) {
|
||||
return ArmorWithType(input, pgpPublicBlockType)
|
||||
}
|
||||
|
||||
// ArmorWithType make bytes input to armor format
|
||||
func ArmorWithType(input []byte, armorType string) (string, error) {
|
||||
var b bytes.Buffer
|
||||
w, err := armor.Encode(&b, armorType, armorHeader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = w.Write(input)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
w.Close()
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
// UnArmor an armored key to bytes key
|
||||
func UnArmor(input string) ([]byte, error) {
|
||||
b, err := unArmor(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ioutil.ReadAll(b.Body)
|
||||
}
|
||||
|
||||
func unArmor(input string) (*armor.Block, error) {
|
||||
io := strings.NewReader(input)
|
||||
b, err := armor.Decode(io)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
|
||||
}
|
||||
133
armor/armor.go
Normal file
133
armor/armor.go
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
package armor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"golang.org/x/crypto/openpgp/armor"
|
||||
"proton/pmcrypto/internal"
|
||||
"golang.org/x/crypto/openpgp/clearsign"
|
||||
"errors"
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
"io"
|
||||
"proton/pmcrypto/models"
|
||||
)
|
||||
|
||||
// ArmorKey make bytes input key to armor format
|
||||
func ArmorKey(input []byte) (string, error) {
|
||||
return ArmorWithType(input, PUBLIC_KEY_HEADER)
|
||||
}
|
||||
|
||||
// ArmorWithType make bytes input to armor format
|
||||
func ArmorWithType(input []byte, armorType string) (string, error) {
|
||||
var b bytes.Buffer
|
||||
w, err := armor.Encode(&b, armorType, internal.ArmorHeaders)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = w.Write(input)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
w.Close()
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
// UnArmor an armored key to bytes key
|
||||
func UnArmor(input string) ([]byte, error) {
|
||||
b, err := internal.UnArmor(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ioutil.ReadAll(b.Body)
|
||||
}
|
||||
|
||||
//ReadClearSignedMessage read clear message from a clearsign package
|
||||
func ReadClearSignedMessage(signedMessage string) (string, error) {
|
||||
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
|
||||
if len(rest) != 0 {
|
||||
return "", errors.New("pmapi: extra data after modulus")
|
||||
}
|
||||
return string(modulusBlock.Bytes), nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
//SeparateKeyAndData ...
|
||||
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
|
||||
|
||||
var err error
|
||||
|
||||
encryptedRaw, err := UnArmor(encrypted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
encryptedReader := bytes.NewReader(encryptedRaw)
|
||||
|
||||
//kr *KeyRing, r io.Reader) (key *SymmetricKey, symEncryptedData []byte,
|
||||
packets := packet.NewReader(encryptedReader)
|
||||
|
||||
outSplit := &models.EncryptedSplit{}
|
||||
|
||||
// Save encrypted key and signature apart
|
||||
var ek *packet.EncryptedKey
|
||||
// var decryptErr error
|
||||
for {
|
||||
var p packet.Packet
|
||||
if p, err = packets.Next(); err == io.EOF {
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
switch p := p.(type) {
|
||||
case *packet.EncryptedKey:
|
||||
// We got an encrypted key. Try to decrypt it with each available key
|
||||
if ek != nil && ek.Key != nil {
|
||||
break
|
||||
}
|
||||
ek = p
|
||||
break
|
||||
case *packet.SymmetricallyEncrypted:
|
||||
var packetContents []byte
|
||||
if packetContents, err = ioutil.ReadAll(p.Contents); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
encodedLength := encodedLength(len(packetContents) + 1)
|
||||
var symEncryptedData []byte
|
||||
symEncryptedData = append(symEncryptedData, byte(210))
|
||||
symEncryptedData = append(symEncryptedData, encodedLength...)
|
||||
symEncryptedData = append(symEncryptedData, byte(1))
|
||||
symEncryptedData = append(symEncryptedData, packetContents...)
|
||||
|
||||
outSplit.DataPacket = symEncryptedData
|
||||
break
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
ek.Serialize(&buf)
|
||||
outSplit.KeyPacket = buf.Bytes()
|
||||
|
||||
return outSplit, err
|
||||
}
|
||||
|
||||
|
||||
|
||||
//encode length based on 4.2.2. in the RFC
|
||||
func encodedLength(length int) (b []byte) {
|
||||
if length < 192 {
|
||||
b = append(b, byte(length))
|
||||
} else if length < 8384 {
|
||||
length = length - 192
|
||||
b = append(b, 192+byte(length>>8))
|
||||
b = append(b, byte(length))
|
||||
} else {
|
||||
b = append(b, byte(255))
|
||||
b = append(b, byte(length>>24))
|
||||
b = append(b, byte(length>>16))
|
||||
b = append(b, byte(length>>8))
|
||||
b = append(b, byte(length))
|
||||
}
|
||||
return
|
||||
}
|
||||
14
armor/constants.go
Normal file
14
armor/constants.go
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package armor
|
||||
|
||||
import (
|
||||
"proton/pmcrypto/internal"
|
||||
)
|
||||
|
||||
const (
|
||||
ARMOR_HEADER_VERSION = internal.ARMOR_HEADER_VERSION
|
||||
ARMOR_HEADER_COMMENT = internal.ARMOR_HEADER_COMMENT
|
||||
MESSAGE_HEADER string = "PGP MESSAGE"
|
||||
PUBLIC_KEY_HEADER string = "PGP PUBLIC KEY BLOCK"
|
||||
PRIVATE_KEY_HEADER string = "PGP PRIVATE KEY BLOCK"
|
||||
)
|
||||
|
||||
11
build.sh
11
build.sh
|
|
@ -2,21 +2,20 @@
|
|||
|
||||
SCRIPT_LOCATION=$(cd $(dirname $0);echo $PWD)
|
||||
|
||||
OUTPUT_PATH="bin"
|
||||
OUTPUT_PATH="dist"
|
||||
ANDROID_OUT=${OUTPUT_PATH}/"Android"
|
||||
IOS_OUT=${OUTPUT_PATH}/"iOS"
|
||||
|
||||
mkdir -p $ANDROID_OUT
|
||||
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"
|
||||
|
||||
gomobile bind -target ios -o ${IOS_OUT}/PM.framework
|
||||
|
||||
gomobile bind -target ios -o ${IOS_OUT}/pmcrypto.framework proton/pmcrypto/crypto proton/pmcrypto/armor proton/pmcrypto/constants proton/pmcrypto/key proton/pmcrypto/models
|
||||
|
||||
printf "\e[0;32mStart Building Android lib .. Location: ${ANDROID_OUT} \033[0m\n\n"
|
||||
|
||||
gomobile bind -target android -o ${ANDROID_OUT}/PM.aar
|
||||
|
||||
gomobile bind -target android -javapkg com.proton.pmcrypto -o ${ANDROID_OUT}/pmcrypto.aar proton/pmcrypto/crypto proton/pmcrypto/armor proton/pmcrypto/constants proton/pmcrypto/key proton/pmcrypto/models
|
||||
|
||||
printf "\e[0;32mInstalling frameworks. \033[0m\n\n"
|
||||
|
||||
|
|
|
|||
36
common.go
36
common.go
|
|
@ -1,36 +0,0 @@
|
|||
package pmcrypto
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var armorHeader = map[string]string{
|
||||
"Version": "OpenPGP Golang 0.0.1 (" + Version() + ")",
|
||||
"Comment": "https://protonmail.com",
|
||||
}
|
||||
|
||||
// Key ... add later
|
||||
// protonmail key object
|
||||
type Key struct {
|
||||
KeyID string
|
||||
PublicKey string
|
||||
PrivateKey string
|
||||
FingerPrint string
|
||||
}
|
||||
|
||||
//Address ... add later protonmail address object
|
||||
type Address struct {
|
||||
// address_id : string;
|
||||
// #optional
|
||||
// address_name : string;
|
||||
keys []Key
|
||||
}
|
||||
|
||||
func trimNewlines(input string) string {
|
||||
var re = regexp.MustCompile(`(?m)[ \t]*$`)
|
||||
return re.ReplaceAllString(input, "")
|
||||
}
|
||||
|
||||
// Amount of seconds that a signature may be created after the verify time
|
||||
// Consistent with the 2 day slack allowed in the ProtonMail Email Parser
|
||||
var creationTimeOffset = int64(60 * 60 * 24 * 2)
|
||||
3
constants/version.go
Normal file
3
constants/version.go
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
package constants
|
||||
|
||||
const VERSION = "ddacebe0"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pmcrypto
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
|
@ -6,15 +6,18 @@ import (
|
|||
"io/ioutil"
|
||||
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"golang.org/x/crypto/openpgp/armor"
|
||||
armorUtils "proton/pmcrypto/armor"
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
"proton/pmcrypto/internal"
|
||||
"golang.org/x/crypto/openpgp/armor"
|
||||
"proton/pmcrypto/models"
|
||||
)
|
||||
|
||||
//EncryptAttachmentBinKey ...
|
||||
func (o *OpenPGP) EncryptAttachmentBinKey(plainData []byte, fileName string, publicKey []byte) (*EncryptedSplit, error) {
|
||||
func (pm *PmCrypto) EncryptAttachmentBinKey(plainData []byte, fileName string, publicKey []byte) (*models.EncryptedSplit, error) {
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
w, err := armor.Encode(&outBuf, pgpMessageType, armorHeader)
|
||||
w, err := armor.Encode(&outBuf, armorUtils.MESSAGE_HEADER, internal.ArmorHeaders)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -30,7 +33,7 @@ func (o *OpenPGP) EncryptAttachmentBinKey(plainData []byte, fileName string, pub
|
|||
|
||||
config := &packet.Config{
|
||||
DefaultCipher: packet.CipherAES256,
|
||||
Time: o.getTimeGenerator(),
|
||||
Time: pm.getTimeGenerator(),
|
||||
}
|
||||
|
||||
ew, err := openpgp.Encrypt(w, pubKeyEntries, nil, hints, config)
|
||||
|
|
@ -39,7 +42,7 @@ func (o *OpenPGP) EncryptAttachmentBinKey(plainData []byte, fileName string, pub
|
|||
ew.Close()
|
||||
w.Close()
|
||||
|
||||
split, err := SeparateKeyAndData(outBuf.String())
|
||||
split, err := armorUtils.SplitArmor(outBuf.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -48,19 +51,19 @@ func (o *OpenPGP) EncryptAttachmentBinKey(plainData []byte, fileName string, pub
|
|||
}
|
||||
|
||||
//EncryptAttachment ...
|
||||
func (o *OpenPGP) EncryptAttachment(plainData []byte, fileName string, publicKey string) (*EncryptedSplit, error) {
|
||||
rawPubKey, err := UnArmor(publicKey)
|
||||
func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicKey string) (*models.EncryptedSplit, error) {
|
||||
rawPubKey, err := armorUtils.UnArmor(publicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return o.EncryptAttachmentBinKey(plainData, fileName, rawPubKey)
|
||||
return pm.EncryptAttachmentBinKey(plainData, fileName, rawPubKey)
|
||||
}
|
||||
|
||||
//DecryptAttachmentBinKey ...
|
||||
//keyPacket
|
||||
//dataPacket
|
||||
//privateKeys could be mutiple private keys
|
||||
func (o *OpenPGP) DecryptAttachmentBinKey(keyPacket []byte, dataPacket []byte, privateKeys []byte, passphrase string) ([]byte, error) {
|
||||
func (pm *PmCrypto) DecryptAttachmentBinKey(keyPacket []byte, dataPacket []byte, privateKeys []byte, passphrase string) ([]byte, error) {
|
||||
privKeyRaw := bytes.NewReader(privateKeys)
|
||||
privKeyEntries, err := openpgp.ReadKeyRing(privKeyRaw)
|
||||
if err != nil {
|
||||
|
|
@ -86,7 +89,7 @@ func (o *OpenPGP) DecryptAttachmentBinKey(keyPacket []byte, dataPacket []byte, p
|
|||
|
||||
encryptedReader := io.MultiReader(keyReader, dataReader)
|
||||
|
||||
config := &packet.Config{ Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{ Time: pm.getTimeGenerator() }
|
||||
|
||||
md, err := openpgp.ReadMessage(encryptedReader, privKeyEntries, nil, config)
|
||||
if err != nil {
|
||||
|
|
@ -103,24 +106,24 @@ func (o *OpenPGP) DecryptAttachmentBinKey(keyPacket []byte, dataPacket []byte, p
|
|||
}
|
||||
|
||||
//DecryptAttachment ...
|
||||
func (o *OpenPGP) DecryptAttachment(keyPacket []byte, dataPacket []byte, privateKey string, passphrase string) ([]byte, error) {
|
||||
rawPrivKey, err := UnArmor(privateKey)
|
||||
func (pm *PmCrypto) DecryptAttachment(keyPacket []byte, dataPacket []byte, privateKey string, passphrase string) ([]byte, error) {
|
||||
rawPrivKey, err := armorUtils.UnArmor(privateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return o.DecryptAttachmentBinKey(keyPacket, dataPacket, rawPrivKey, passphrase)
|
||||
return pm.DecryptAttachmentBinKey(keyPacket, dataPacket, rawPrivKey, passphrase)
|
||||
}
|
||||
|
||||
//EncryptAttachmentWithPassword ...
|
||||
func (o *OpenPGP) EncryptAttachmentWithPassword(plainData []byte, password string) (string, error) {
|
||||
func (pm *PmCrypto) EncryptAttachmentWithPassword(plainData []byte, password string) (string, error) {
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
w, err := armor.Encode(&outBuf, pgpMessageType, armorHeader)
|
||||
w, err := armor.Encode(&outBuf, armorUtils.MESSAGE_HEADER, internal.ArmorHeaders)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
config := &packet.Config{ Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{ Time: pm.getTimeGenerator() }
|
||||
|
||||
plaintext, err := openpgp.SymmetricallyEncrypt(w, []byte(password), nil, config)
|
||||
if err != nil {
|
||||
|
|
@ -141,7 +144,7 @@ func (o *OpenPGP) EncryptAttachmentWithPassword(plainData []byte, password strin
|
|||
}
|
||||
|
||||
//DecryptAttachmentWithPassword ...
|
||||
func (o *OpenPGP) DecryptAttachmentWithPassword(keyPacket []byte, dataPacket []byte, password string) ([]byte, error) {
|
||||
func (pm *PmCrypto) DecryptAttachmentWithPassword(keyPacket []byte, dataPacket []byte, password string) ([]byte, error) {
|
||||
|
||||
encrypted := append(keyPacket, dataPacket...)
|
||||
|
||||
|
|
@ -151,7 +154,7 @@ func (o *OpenPGP) DecryptAttachmentWithPassword(keyPacket []byte, dataPacket []b
|
|||
return []byte(password), nil
|
||||
}
|
||||
|
||||
config := &packet.Config{ Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{ Time: pm.getTimeGenerator() }
|
||||
|
||||
md, err := openpgp.ReadMessage(encryptedReader, nil, prompt, config)
|
||||
if err != nil {
|
||||
|
|
@ -1,38 +1,19 @@
|
|||
package pmcrypto
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
"math/big"
|
||||
"proton/pmcrypto/armor"
|
||||
)
|
||||
|
||||
//EncryptedSplit when encrypt attachemt
|
||||
type EncryptedSplit struct {
|
||||
DataPacket []byte
|
||||
KeyPacket []byte
|
||||
Algo string
|
||||
}
|
||||
|
||||
//SessionSplit splited session
|
||||
type SessionSplit struct {
|
||||
Session []byte
|
||||
Algo string
|
||||
}
|
||||
|
||||
//EncryptedSigned encrypt_sign_package
|
||||
type EncryptedSigned struct {
|
||||
Encrypted string
|
||||
Signature string
|
||||
}
|
||||
|
||||
const (
|
||||
ok = 0
|
||||
notSigned = 1
|
||||
|
|
@ -40,49 +21,10 @@ const (
|
|||
failed = 3
|
||||
)
|
||||
|
||||
//DecryptSignedVerify decrypt_sign_verify
|
||||
type DecryptSignedVerify struct {
|
||||
//clear text
|
||||
Plaintext string
|
||||
//bitmask verify status : 0
|
||||
Verify int
|
||||
//error message if verify failed
|
||||
Message string
|
||||
}
|
||||
|
||||
//CheckPassphrase check is private key passphrase ok
|
||||
func CheckPassphrase(privateKey string, passphrase string) bool {
|
||||
privKeyReader := strings.NewReader(privateKey)
|
||||
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return false
|
||||
}
|
||||
|
||||
var keys []*packet.PrivateKey
|
||||
|
||||
for _, e := range entries {
|
||||
keys = append(keys, e.PrivateKey)
|
||||
}
|
||||
var decryptError error
|
||||
var n int
|
||||
for _, key := range keys {
|
||||
if !key.Encrypted {
|
||||
continue // Key already decrypted
|
||||
}
|
||||
if decryptError = key.Decrypt([]byte(passphrase)); decryptError == nil {
|
||||
n++
|
||||
}
|
||||
}
|
||||
if n == 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//IsKeyExpiredBin ...
|
||||
func (o *OpenPGP) IsKeyExpiredBin(publicKey []byte) (bool, error) {
|
||||
now := o.getNow()
|
||||
func (pm *PmCrypto) IsKeyExpiredBin(publicKey []byte) (bool, error) {
|
||||
now := pm.getNow()
|
||||
pubKeyReader := bytes.NewReader(publicKey)
|
||||
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
|
||||
if err != nil {
|
||||
|
|
@ -134,15 +76,15 @@ func (o *OpenPGP) IsKeyExpiredBin(publicKey []byte) (bool, error) {
|
|||
|
||||
//IsKeyExpired ....
|
||||
// will user the cached time to check
|
||||
func (o *OpenPGP) IsKeyExpired(publicKey string) (bool, error) {
|
||||
rawPubKey, err := UnArmor(publicKey)
|
||||
func (pm *PmCrypto) IsKeyExpired(publicKey string) (bool, error) {
|
||||
rawPubKey, err := armor.UnArmor(publicKey)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return o.IsKeyExpiredBin(rawPubKey)
|
||||
return pm.IsKeyExpiredBin(rawPubKey)
|
||||
}
|
||||
|
||||
func (o *OpenPGP) generateKey(userName string, domain string, passphrase string, keyType string, bits int,
|
||||
func (pm *PmCrypto) generateKey(userName string, domain string, passphrase string, keyType string, bits int,
|
||||
prime1 []byte, prime2 []byte, prime3 []byte, prime4 []byte) (string, error) {
|
||||
|
||||
if len(userName) <= 0 {
|
||||
|
|
@ -157,9 +99,9 @@ func (o *OpenPGP) generateKey(userName string, domain string, passphrase string,
|
|||
comments := ""
|
||||
|
||||
cfg := &packet.Config{
|
||||
Algorithm: packet.PubKeyAlgoRSA,
|
||||
Algorithm: packet.PubKeyAlgoRSA,
|
||||
RSABits: bits,
|
||||
Time: o.getTimeGenerator(),
|
||||
Time: pm.getTimeGenerator(),
|
||||
DefaultHash: crypto.SHA256,
|
||||
DefaultCipher: packet.CipherAES256,
|
||||
}
|
||||
|
|
@ -212,12 +154,12 @@ func (o *OpenPGP) generateKey(userName string, domain string, passphrase string,
|
|||
return "", err
|
||||
}
|
||||
serialized := w.Bytes()
|
||||
return ArmorWithType(serialized, pgpPrivateBlockType)
|
||||
return armor.ArmorWithType(serialized, armor.PRIVATE_KEY_HEADER)
|
||||
}
|
||||
|
||||
func (o *OpenPGP) GenerateRSAKeyWithPrimes(userName string, domain string, passphrase string, bits int,
|
||||
func (pm *PmCrypto) GenerateRSAKeyWithPrimes(userName string, domain string, passphrase string, bits int,
|
||||
primeone []byte, primetwo []byte, primethree []byte, primefour []byte) (string, error) {
|
||||
return o.generateKey(userName, domain, passphrase, "rsa", bits, primeone, primetwo, primethree, primefour)
|
||||
return pm.generateKey(userName, domain, passphrase, "rsa", bits, primeone, primetwo, primethree, primefour)
|
||||
}
|
||||
|
||||
// GenerateKey ...
|
||||
|
|
@ -226,11 +168,11 @@ func (o *OpenPGP) GenerateRSAKeyWithPrimes(userName string, domain string, passp
|
|||
// #static generate_key_with_email(email : string, passphrase : string, bits : i32) : open_pgp_key;
|
||||
// # generate new key
|
||||
// #static generate_new_key(user_id : string, email : string, passphrase : string, bits : i32) : open_pgp_key;
|
||||
func (o *OpenPGP) GenerateKey(userName string, domain string, passphrase string, keyType string, bits int) (string, error) {
|
||||
return o.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil)
|
||||
func (pm *PmCrypto) GenerateKey(userName string, domain string, passphrase string, keyType string, bits int) (string, error) {
|
||||
return pm.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil)
|
||||
}
|
||||
// UpdatePrivateKeyPassphrase ...
|
||||
func (o *OpenPGP) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase string, newPassphrase string) (string, error) {
|
||||
func (pm *PmCrypto) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase string, newPassphrase string) (string, error) {
|
||||
|
||||
privKey := strings.NewReader(privateKey)
|
||||
privKeyEntries, err := openpgp.ReadArmoredKeyRing(privKey)
|
||||
|
|
@ -271,48 +213,11 @@ func (o *OpenPGP) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase st
|
|||
}
|
||||
|
||||
serialized := w.Bytes()
|
||||
return ArmorWithType(serialized, pgpPrivateBlockType)
|
||||
}
|
||||
|
||||
// PublicKey get a public key from a private key
|
||||
func PublicKey(privateKey string) (string, error) {
|
||||
privKeyReader := strings.NewReader(privateKey)
|
||||
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
for _, e := range entries {
|
||||
e.Serialize(&outBuf)
|
||||
}
|
||||
|
||||
outString, err := ArmorWithType(outBuf.Bytes(), pgpPublicBlockType)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return outString, nil
|
||||
}
|
||||
|
||||
// PublicKeyBinOut get a public key from a private key
|
||||
func PublicKeyBinOut(privateKey string) ([]byte, error) {
|
||||
privKeyReader := strings.NewReader(privateKey)
|
||||
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
for _, e := range entries {
|
||||
e.Serialize(&outBuf)
|
||||
}
|
||||
|
||||
return outBuf.Bytes(), nil
|
||||
return armor.ArmorWithType(serialized, armor.PRIVATE_KEY_HEADER)
|
||||
}
|
||||
|
||||
// CheckKey print out the key and subkey fingerprint
|
||||
func CheckKey(pubKey string) (string, error) {
|
||||
func (pm *PmCrypto) CheckKey(pubKey string) (string, error) {
|
||||
pubKeyReader := strings.NewReader(pubKey)
|
||||
entries, err := openpgp.ReadArmoredKeyRing(pubKeyReader)
|
||||
if err != nil {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pmcrypto
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
|
@ -13,32 +13,35 @@ import (
|
|||
"golang.org/x/crypto/openpgp/packet"
|
||||
errors2 "golang.org/x/crypto/openpgp/errors"
|
||||
"math"
|
||||
)
|
||||
armorUtils "proton/pmcrypto/armor"
|
||||
"proton/pmcrypto/internal"
|
||||
"proton/pmcrypto/models"
|
||||
)
|
||||
|
||||
// DecryptMessage decrypt 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 (o *OpenPGP) DecryptMessage(encryptedText string, privateKey string, passphrase string) (string, error) {
|
||||
privKeyRaw, err := UnArmor(privateKey)
|
||||
func (pm *PmCrypto) DecryptMessage(encryptedText string, privateKey string, passphrase string) (string, error) {
|
||||
privKeyRaw, err := armorUtils.UnArmor(privateKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return o.DecryptMessageBinKey(encryptedText, privKeyRaw, passphrase)
|
||||
return pm.DecryptMessageBinKey(encryptedText, privKeyRaw, passphrase)
|
||||
}
|
||||
|
||||
// DecryptMessageBinKey decrypt encrypted message use private key (bytes )
|
||||
// encryptedText : string armored encrypted
|
||||
// privateKey : unarmored private use to decrypt message could be mutiple keys
|
||||
// passphrase : match with private key to decrypt message
|
||||
func (o *OpenPGP) DecryptMessageBinKey(encryptedText string, privateKey []byte, passphrase string) (string, error) {
|
||||
func (pm *PmCrypto) DecryptMessageBinKey(encryptedText string, privateKey []byte, passphrase string) (string, error) {
|
||||
privKey := bytes.NewReader(privateKey)
|
||||
privKeyEntries, err := openpgp.ReadKeyRing(privKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
encryptedio, err := unArmor(encryptedText)
|
||||
encryptedio, err := internal.UnArmor(encryptedText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -56,7 +59,7 @@ func (o *OpenPGP) DecryptMessageBinKey(encryptedText string, privateKey []byte,
|
|||
}
|
||||
}
|
||||
|
||||
config := &packet.Config{ Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{ Time: pm.getTimeGenerator() }
|
||||
|
||||
md, err := openpgp.ReadMessage(encryptedio.Body, privKeyEntries, nil, config)
|
||||
if err != nil {
|
||||
|
|
@ -76,54 +79,54 @@ func (o *OpenPGP) DecryptMessageBinKey(encryptedText string, privateKey []byte,
|
|||
// DecryptMessageVerifyPrivbinkeys decrypt message and verify the signature
|
||||
// veriferKey string: armored verifier keys
|
||||
// privateKey []byte: unarmored private key to decrypt. could be mutiple
|
||||
func (o *OpenPGP) DecryptMessageVerifyPrivbinkeys(encryptedText string, veriferKey string, privateKeys []byte, passphrase string, verifyTime int64) (*DecryptSignedVerify, error) {
|
||||
func (pm *PmCrypto) DecryptMessageVerifyPrivbinkeys(encryptedText string, veriferKey string, privateKeys []byte, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
|
||||
|
||||
if len(veriferKey) > 0 {
|
||||
verifierRaw, err := UnArmor(veriferKey)
|
||||
verifierRaw, err := armorUtils.UnArmor(veriferKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return o.decryptMessageVerifyAllBin(encryptedText, verifierRaw, privateKeys, passphrase, verifyTime)
|
||||
return pm.decryptMessageVerifyAllBin(encryptedText, verifierRaw, privateKeys, passphrase, verifyTime)
|
||||
}
|
||||
return o.decryptMessageVerifyAllBin(encryptedText, nil, privateKeys, passphrase, verifyTime)
|
||||
return pm.decryptMessageVerifyAllBin(encryptedText, nil, privateKeys, passphrase, verifyTime)
|
||||
}
|
||||
|
||||
// DecryptMessageVerifyBinKeyPrivbinkeys decrypt message and verify the signature
|
||||
// veriferKey []byte: unarmored verifier keys
|
||||
// privateKey []byte: unarmored private key to decrypt. could be mutiple
|
||||
func (o *OpenPGP) DecryptMessageVerifyBinKeyPrivbinkeys(encryptedText string, veriferKey []byte, privateKeys []byte, passphrase string, verifyTime int64) (*DecryptSignedVerify, error) {
|
||||
return o.decryptMessageVerifyAllBin(encryptedText, veriferKey, privateKeys, passphrase, verifyTime)
|
||||
func (pm *PmCrypto) DecryptMessageVerifyBinKeyPrivbinkeys(encryptedText string, veriferKey []byte, privateKeys []byte, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
|
||||
return pm.decryptMessageVerifyAllBin(encryptedText, veriferKey, privateKeys, passphrase, verifyTime)
|
||||
}
|
||||
|
||||
// DecryptMessageVerify decrypt message and verify the signature
|
||||
// veriferKey string: armored verifier keys
|
||||
// privateKey string: private to decrypt
|
||||
func (o *OpenPGP) DecryptMessageVerify(encryptedText string, veriferKey string, privateKey string, passphrase string, verifyTime int64) (*DecryptSignedVerify, error) {
|
||||
func (pm *PmCrypto) DecryptMessageVerify(encryptedText string, veriferKey string, privateKey string, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
|
||||
if len(veriferKey) > 0 {
|
||||
verifierRaw, err := UnArmor(veriferKey)
|
||||
verifierRaw, err := armorUtils.UnArmor(veriferKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return o.DecryptMessageVerifyBinKey(encryptedText, verifierRaw, privateKey, passphrase, verifyTime)
|
||||
return pm.DecryptMessageVerifyBinKey(encryptedText, verifierRaw, privateKey, passphrase, verifyTime)
|
||||
}
|
||||
return o.DecryptMessageVerifyBinKey(encryptedText, nil, privateKey, passphrase, verifyTime)
|
||||
return pm.DecryptMessageVerifyBinKey(encryptedText, nil, privateKey, passphrase, verifyTime)
|
||||
}
|
||||
|
||||
// DecryptMessageVerifyBinKey decrypt message and verify the signature
|
||||
// veriferKey []byte: unarmored verifier keys
|
||||
// privateKey string: private to decrypt
|
||||
func (o *OpenPGP) DecryptMessageVerifyBinKey(encryptedText string, veriferKey []byte, privateKey string, passphrase string, verifyTime int64) (*DecryptSignedVerify, error) {
|
||||
privateKeyRaw, err := UnArmor(privateKey)
|
||||
func (pm *PmCrypto) DecryptMessageVerifyBinKey(encryptedText string, veriferKey []byte, privateKey string, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
|
||||
privateKeyRaw, err := armorUtils.UnArmor(privateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return o.decryptMessageVerifyAllBin(encryptedText, veriferKey, privateKeyRaw, passphrase, verifyTime)
|
||||
return pm.decryptMessageVerifyAllBin(encryptedText, veriferKey, privateKeyRaw, passphrase, verifyTime)
|
||||
}
|
||||
|
||||
// decryptMessageVerifyAllBin
|
||||
// decrypt_message_verify_single_key(private_key: string, passphras: string, encrypted : string, signature : string) : decrypt_sign_verify;
|
||||
// decrypt_message_verify(passphras: string, encrypted : string, signature : string) : decrypt_sign_verify;
|
||||
func (o *OpenPGP) decryptMessageVerifyAllBin(encryptedText string, veriferKey []byte, privateKey []byte, passphrase string, verifyTime int64) (*DecryptSignedVerify, error) {
|
||||
func (pm *PmCrypto) decryptMessageVerifyAllBin(encryptedText string, veriferKey []byte, privateKey []byte, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
|
||||
privKey := bytes.NewReader(privateKey)
|
||||
privKeyEntries, err := openpgp.ReadKeyRing(privKey)
|
||||
if err != nil {
|
||||
|
|
@ -144,7 +147,7 @@ func (o *OpenPGP) decryptMessageVerifyAllBin(encryptedText string, veriferKey []
|
|||
}
|
||||
}
|
||||
|
||||
out := &DecryptSignedVerify{}
|
||||
out := &models.DecryptSignedVerify{}
|
||||
out.Verify = failed
|
||||
|
||||
var verifierEntries openpgp.EntityList
|
||||
|
|
@ -162,7 +165,7 @@ func (o *OpenPGP) decryptMessageVerifyAllBin(encryptedText string, veriferKey []
|
|||
out.Verify = noVerifier
|
||||
}
|
||||
|
||||
encryptedio, err := unArmor(encryptedText)
|
||||
encryptedio, err := internal.UnArmor(encryptedText)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -219,7 +222,7 @@ func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
|
|||
if md.Signature.KeyLifetimeSecs != nil {
|
||||
expires = int64(*md.Signature.KeyLifetimeSecs) + created
|
||||
}
|
||||
if created - creationTimeOffset <= verifyTime && verifyTime <= expires {
|
||||
if created - internal.CreationTimeOffset <= verifyTime && verifyTime <= expires {
|
||||
md.SignatureError = nil
|
||||
}
|
||||
} else {
|
||||
|
|
@ -234,12 +237,12 @@ func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
|
|||
// plainText : the input
|
||||
// privateKey : optional required when you want to sign
|
||||
// passphrase : optional required when you pass the private key and this passphrase must could decrypt the private key
|
||||
func (o *OpenPGP) EncryptMessage(plainText string, publicKey string, privateKey string, passphrase string, trim bool) (string, error) {
|
||||
rawPubKey, err := UnArmor(publicKey)
|
||||
func (pm *PmCrypto) EncryptMessage(plainText string, publicKey string, privateKey string, passphrase string, trim bool) (string, error) {
|
||||
rawPubKey, err := armorUtils.UnArmor(publicKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return o.EncryptMessageBinKey(plainText, rawPubKey, privateKey, passphrase, trim)
|
||||
return pm.EncryptMessageBinKey(plainText, rawPubKey, privateKey, passphrase, trim)
|
||||
}
|
||||
|
||||
// EncryptMessageBinKey encrypt message with unarmored public key, if pass private key and passphrase will also sign the message
|
||||
|
|
@ -247,13 +250,13 @@ func (o *OpenPGP) EncryptMessage(plainText string, publicKey string, privateKey
|
|||
// plainText : the input
|
||||
// privateKey : optional required when you want to sign
|
||||
// passphrase : optional required when you pass the private key and this passphrase must could decrypt the private key
|
||||
func (o *OpenPGP) EncryptMessageBinKey(plainText string, publicKey []byte, privateKey string, passphrase string, trim bool) (string, error) {
|
||||
func (pm *PmCrypto) EncryptMessageBinKey(plainText string, publicKey []byte, privateKey string, passphrase string, trim bool) (string, error) {
|
||||
|
||||
if trim {
|
||||
plainText = trimNewlines(plainText)
|
||||
plainText = internal.TrimNewlines(plainText)
|
||||
}
|
||||
var outBuf bytes.Buffer
|
||||
w, err := armor.Encode(&outBuf, pgpMessageType, armorHeader)
|
||||
w, err := armor.Encode(&outBuf, armorUtils.MESSAGE_HEADER, internal.ArmorHeaders)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -291,7 +294,7 @@ func (o *OpenPGP) EncryptMessageBinKey(plainText string, publicKey []byte, priva
|
|||
}
|
||||
}
|
||||
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator() }
|
||||
|
||||
ew, err := openpgp.Encrypt(w, pubKeyEntries, signEntity, nil, config)
|
||||
|
||||
|
|
@ -304,15 +307,15 @@ func (o *OpenPGP) EncryptMessageBinKey(plainText string, publicKey []byte, priva
|
|||
//EncryptMessageWithPassword encrypt a plain text to pgp message with a password
|
||||
//plainText string: clear text
|
||||
//output string: armored pgp message
|
||||
func (o *OpenPGP) EncryptMessageWithPassword(plainText string, password string) (string, error) {
|
||||
func (pm *PmCrypto) EncryptMessageWithPassword(plainText string, password string) (string, error) {
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
w, err := armor.Encode(&outBuf, pgpMessageType, armorHeader)
|
||||
w, err := armor.Encode(&outBuf, armorUtils.MESSAGE_HEADER, internal.ArmorHeaders)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
config := &packet.Config{ Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{ Time: pm.getTimeGenerator() }
|
||||
plaintext, err := openpgp.SymmetricallyEncrypt(w, []byte(password), nil, config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -334,8 +337,8 @@ func (o *OpenPGP) EncryptMessageWithPassword(plainText string, password string)
|
|||
//DecryptMessageWithPassword decrypt a pgp message with a password
|
||||
//encrypted string : armored pgp message
|
||||
//output string : clear text
|
||||
func (o *OpenPGP) DecryptMessageWithPassword(encrypted string, password string) (string, error) {
|
||||
encryptedio, err := unArmor(encrypted)
|
||||
func (pm *PmCrypto) DecryptMessageWithPassword(encrypted string, password string) (string, error) {
|
||||
encryptedio, err := internal.UnArmor(encrypted)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -344,7 +347,7 @@ func (o *OpenPGP) DecryptMessageWithPassword(encrypted string, password string)
|
|||
return []byte(password), nil
|
||||
}
|
||||
|
||||
config := &packet.Config{ Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{ Time: pm.getTimeGenerator() }
|
||||
md, err := openpgp.ReadMessage(encryptedio.Body, nil, prompt, config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pmcrypto
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"proton/pmmime"
|
||||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"io/ioutil"
|
||||
"bytes"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"proton/pmcrypto/armor"
|
||||
)
|
||||
|
||||
// ======================== Attachments Collector ==============
|
||||
|
|
@ -16,17 +17,15 @@ import (
|
|||
// them as a string
|
||||
|
||||
|
||||
|
||||
|
||||
func (o OpenPGP) parseMIME(mimeBody string, verifierKey []byte) (*pmmime.BodyCollector, int, []string, []string, error) {
|
||||
privKey := bytes.NewReader(verifierKey)
|
||||
privKeyEntries, err := openpgp.ReadKeyRing(privKey)
|
||||
func (pm PmCrypto) parseMIME(mimeBody string, verifierKey []byte) (*pmmime.BodyCollector, int, []string, []string, error) {
|
||||
pubKey := bytes.NewReader(verifierKey)
|
||||
pubKeyEntries, err := openpgp.ReadKeyRing(pubKey)
|
||||
|
||||
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
|
||||
if err != nil {
|
||||
return nil, 0, nil, nil, err
|
||||
}
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: o.getTimeGenerator()}
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator()}
|
||||
|
||||
h := textproto.MIMEHeader(mm.Header)
|
||||
mmBodyData, err := ioutil.ReadAll(mm.Body)
|
||||
|
|
@ -35,7 +34,8 @@ func (o OpenPGP) parseMIME(mimeBody string, verifierKey []byte) (*pmmime.BodyCol
|
|||
bodyCollector := pmmime.NewBodyCollector(printAccepter)
|
||||
attachmentsCollector := pmmime.NewAttachmentsCollector(bodyCollector)
|
||||
mimeVisitor := pmmime.NewMimeVisitor(attachmentsCollector)
|
||||
signatureCollector := NewSignatureCollector(mimeVisitor, privKeyEntries, config)
|
||||
str, err := armor.ArmorKey(verifierKey)
|
||||
signatureCollector := newSignatureCollector(mimeVisitor, pubKeyEntries, config)
|
||||
err = pmmime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
|
||||
|
||||
verified := signatureCollector.verified
|
||||
|
|
@ -48,36 +48,36 @@ func (o OpenPGP) parseMIME(mimeBody string, verifierKey []byte) (*pmmime.BodyCol
|
|||
|
||||
// define call back interface
|
||||
type MIMECallbacks interface {
|
||||
onBody(body string, mimetype string)
|
||||
onAttachment(headers string, data []byte)
|
||||
OnBody(body string, mimetype string)
|
||||
OnAttachment(headers string, data []byte)
|
||||
// Encrypted headers can be an attachment and thus be placed at the end of the mime structure
|
||||
onEncryptedHeaders(headers string)
|
||||
onVerified(verified int)
|
||||
onError(err error)
|
||||
OnEncryptedHeaders(headers string)
|
||||
OnVerified(verified int)
|
||||
OnError(err error)
|
||||
}
|
||||
|
||||
func (o *OpenPGP) decryptMIMEMessage(encryptedText string, verifierKey []byte, privateKeys []byte,
|
||||
func (pm *PmCrypto) DecryptMIMEMessage(encryptedText string, verifierKey []byte, privateKeys []byte,
|
||||
passphrase string, callbacks MIMECallbacks, verifyTime int64) {
|
||||
decsignverify, err := o.decryptMessageVerifyAllBin(encryptedText, verifierKey, privateKeys, passphrase, verifyTime)
|
||||
decsignverify, err := pm.decryptMessageVerifyAllBin(encryptedText, verifierKey, privateKeys, passphrase, verifyTime)
|
||||
if err != nil {
|
||||
callbacks.onError(err)
|
||||
callbacks.OnError(err)
|
||||
return
|
||||
}
|
||||
|
||||
body, verified, attachments, attachmentHeaders, err := o.parseMIME(decsignverify.Plaintext, verifierKey)
|
||||
body, verified, attachments, attachmentHeaders, err := pm.parseMIME(decsignverify.Plaintext, verifierKey)
|
||||
if err != nil {
|
||||
callbacks.onError(err)
|
||||
callbacks.OnError(err)
|
||||
return
|
||||
}
|
||||
bodyContent, bodyMimeType := body.GetBody()
|
||||
callbacks.onBody(bodyContent, bodyMimeType)
|
||||
callbacks.OnBody(bodyContent, bodyMimeType)
|
||||
for i := 0; i < len(attachments); i++ {
|
||||
callbacks.onAttachment(attachmentHeaders[i], []byte(attachments[i]))
|
||||
callbacks.OnAttachment(attachmentHeaders[i], []byte(attachments[i]))
|
||||
}
|
||||
callbacks.onEncryptedHeaders("")
|
||||
callbacks.OnEncryptedHeaders("")
|
||||
if decsignverify.Verify == notSigned {
|
||||
callbacks.onVerified(verified)
|
||||
callbacks.OnVerified(verified)
|
||||
} else {
|
||||
callbacks.onVerified(decsignverify.Verify)
|
||||
callbacks.OnVerified(decsignverify.Verify)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package pmcrypto
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"proton/pmcrypto/internal"
|
||||
)
|
||||
|
||||
const publicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
|
@ -118,7 +119,7 @@ LloBMV1YNGsW45M+oQ==
|
|||
const privatekeypassword = "test"
|
||||
const privatekey = `
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: OpenPGP.js v3.1.2
|
||||
Version: PmCrypto.js v3.1.2
|
||||
Comment: https://openpgpjs.org
|
||||
|
||||
xcaGBFtq/A4BEAC0VKmsQb6HKMWwcpBNaPdEDYTUOQRdA9MvaOgRqJRmxYAG
|
||||
|
|
@ -239,30 +240,30 @@ z9GxJikRwscymWmXx2QsvhUiWeOJ05WwK+WAnKR1uVtkEJ9QJVe2chyuMORY
|
|||
type Callbacks struct {
|
||||
}
|
||||
|
||||
func (t *Callbacks) onBody(body string, mimetype string) {
|
||||
func (t *Callbacks) OnBody(body string, mimetype string) {
|
||||
fmt.Println(body)
|
||||
}
|
||||
func (t Callbacks) onAttachment(headers string, data []byte) {
|
||||
func (t Callbacks) OnAttachment(headers string, data []byte) {
|
||||
fmt.Println(headers)
|
||||
}
|
||||
func (t Callbacks) onEncryptedHeaders(headers string) {
|
||||
func (t Callbacks) OnEncryptedHeaders(headers string) {
|
||||
fmt.Println(headers)
|
||||
}
|
||||
func (t Callbacks) onVerified(verified int) {
|
||||
func (t Callbacks) OnVerified(verified int) {
|
||||
fmt.Println(verified)
|
||||
}
|
||||
func (t Callbacks) onError(err error) {
|
||||
func (t Callbacks) OnError(err error) {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
func TestDecrypt(t *testing.T) {
|
||||
callbacks := Callbacks{}
|
||||
o := OpenPGP{}
|
||||
block, _ := unArmor(publicKey)
|
||||
o := PmCrypto{}
|
||||
block, _ := internal.UnArmor(publicKey)
|
||||
publicKeyUnarmored, _ := ioutil.ReadAll(block.Body)
|
||||
block, _ = unArmor(privatekey)
|
||||
block, _ = internal.UnArmor(privatekey)
|
||||
privateKeyUnarmored, _ := ioutil.ReadAll(block.Body)
|
||||
o.decryptMIMEMessage(testMessage, publicKeyUnarmored, privateKeyUnarmored, privatekeypassword,
|
||||
o.DecryptMIMEMessage(testMessage, publicKeyUnarmored, privateKeyUnarmored, privatekeypassword,
|
||||
&callbacks, o.GetTime())
|
||||
}
|
||||
|
||||
|
|
@ -368,7 +369,7 @@ QkxPQ0stLS0tLQ0KDQo=
|
|||
-----------------------f0e64db835d0f5c3674df52a164b06bb--
|
||||
-----------------------4a9ea9f4dad3f36079bdb3f1e7b75bd0
|
||||
Content-Type: application/pgp-signature; name="signature.asc"
|
||||
Content-Description: OpenPGP digital signature
|
||||
Content-Description: PmCrypto digital signature
|
||||
Content-Disposition: attachment; filename="signature.asc"
|
||||
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
|
@ -388,7 +389,7 @@ RIzX2CG47PuGl/uvImFW/Iw=
|
|||
|
||||
-----------------------4a9ea9f4dad3f36079bdb3f1e7b75bd0--
|
||||
`
|
||||
o := OpenPGP{}
|
||||
o := PmCrypto{}
|
||||
body, _, atts, attHeaders, err := o.parseMIME(testMessage, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
package pmcrypto
|
||||
package crypto
|
||||
|
||||
import "time"
|
||||
|
||||
// OpenPGP structure to manage mutiple address keys and user keys
|
||||
type OpenPGP struct {
|
||||
addresses []*Address
|
||||
|
||||
// PmCrypto structure to manage multiple address keys and user keys
|
||||
// Called PGP crypto because it cannot have the same name as the package by gomobile's ridiculous rules.
|
||||
type PmCrypto struct {
|
||||
//latestServerTime unix time cache
|
||||
latestServerTime int64
|
||||
latestClientTime time.Time
|
||||
|
|
@ -13,28 +12,28 @@ type OpenPGP struct {
|
|||
|
||||
// //AddAddress add a new address to key ring
|
||||
// //add a new address into addresses list
|
||||
// func (pgp *OpenPGP) AddAddress(address *Address) (bool, error) {
|
||||
// func (pgp *PmCrypto) AddAddress(address *Address) (bool, error) {
|
||||
// return true, errors.New("this is not implemented yet, will add this later")
|
||||
// }
|
||||
|
||||
// //RemoveAddress remove address from the keyring
|
||||
// //
|
||||
// //#remove a exsit address from the list based on address id
|
||||
// func (pgp *OpenPGP) RemoveAddress(addressID string) (bool, error) {
|
||||
// func (pgp *PmCrypto) RemoveAddress(addressID string) (bool, error) {
|
||||
// return true, errors.New("this is not implemented yet, will add this later")
|
||||
// }
|
||||
|
||||
// //CleanAddresses clear all addresses in keyring
|
||||
// func (pgp *OpenPGP) CleanAddresses() (bool, error) {
|
||||
// func (pgp *PmCrypto) CleanAddresses() (bool, error) {
|
||||
// return true, errors.New("this is not implemented yet, will add this later")
|
||||
// }
|
||||
|
||||
// //EncryptMessage encrypt message use address id
|
||||
// func (pgp *OpenPGP) EncryptMessage(addressID string, plainText string, passphrase string, trim bool) (string, error) {
|
||||
// func (pgp *PmCrypto) EncryptMessage(addressID string, plainText string, passphrase string, trim bool) (string, error) {
|
||||
// return "", errors.New("this is not implemented yet, will add this later")
|
||||
// }
|
||||
|
||||
// //DecryptMessage decrypt message, this will lookup all keys
|
||||
// func (pgp *OpenPGP) DecryptMessage(encryptText string, passphras string) (string, error) {
|
||||
// func (pgp *PmCrypto) DecryptMessage(encryptText string, passphras string) (string, error) {
|
||||
// return "", errors.New("this is not implemented yet, will add this later")
|
||||
// }
|
||||
|
|
@ -1,19 +1,20 @@
|
|||
package pmcrypto
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
"proton/pmcrypto/armor"
|
||||
"proton/pmcrypto/models"
|
||||
)
|
||||
|
||||
//RandomToken ...
|
||||
func RandomToken() ([]byte, error) {
|
||||
func (pm *PmCrypto) RandomToken() ([]byte, error) {
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
||||
keySize := config.DefaultCipher.KeySize()
|
||||
symKey := make([]byte, keySize)
|
||||
|
|
@ -24,7 +25,7 @@ func RandomToken() ([]byte, error) {
|
|||
}
|
||||
|
||||
// RandomTokenWith ...
|
||||
func RandomTokenWith(size int) ([]byte, error) {
|
||||
func (pm *PmCrypto) RandomTokenWith(size int) ([]byte, error) {
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
||||
symKey := make([]byte, size)
|
||||
if _, err := io.ReadFull(config.Random(), symKey); err != nil {
|
||||
|
|
@ -34,7 +35,7 @@ func RandomTokenWith(size int) ([]byte, error) {
|
|||
}
|
||||
|
||||
//GetSessionFromKeyPacketBinkeys get session key no encoding in and out
|
||||
func GetSessionFromKeyPacketBinkeys(keyPackage []byte, privateKey []byte, passphrase string) (*SessionSplit, error) {
|
||||
func (pm *PmCrypto) GetSessionFromKeyPacketBinkeys(keyPackage []byte, privateKey []byte, passphrase string) (*models.SessionSplit, error) {
|
||||
|
||||
keyReader := bytes.NewReader(keyPackage)
|
||||
packets := packet.NewReader(keyReader)
|
||||
|
|
@ -75,7 +76,7 @@ func GetSessionFromKeyPacketBinkeys(keyPackage []byte, privateKey []byte, passph
|
|||
}
|
||||
|
||||
//GetSessionFromKeyPacket get session key no encoding in and out
|
||||
func GetSessionFromKeyPacket(keyPackage []byte, privateKey string, passphrase string) (*SessionSplit, error) {
|
||||
func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey string, passphrase string) (*models.SessionSplit, error) {
|
||||
|
||||
keyReader := bytes.NewReader(keyPackage)
|
||||
packets := packet.NewReader(keyReader)
|
||||
|
|
@ -116,16 +117,16 @@ func GetSessionFromKeyPacket(keyPackage []byte, privateKey string, passphrase st
|
|||
}
|
||||
|
||||
//KeyPacketWithPublicKey ...
|
||||
func KeyPacketWithPublicKey(sessionSplit *SessionSplit, publicKey string) ([]byte, error) {
|
||||
pubkeyRaw, err := UnArmor(publicKey)
|
||||
func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *models.SessionSplit, publicKey string) ([]byte, error) {
|
||||
pubkeyRaw, err := armor.UnArmor(publicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return KeyPacketWithPublicKeyBin(sessionSplit, pubkeyRaw)
|
||||
return pm.KeyPacketWithPublicKeyBin(sessionSplit, pubkeyRaw)
|
||||
}
|
||||
|
||||
// KeyPacketWithPublicKeyBin ...
|
||||
func KeyPacketWithPublicKeyBin(sessionSplit *SessionSplit, publicKey []byte) ([]byte, error) {
|
||||
func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *models.SessionSplit, publicKey []byte) ([]byte, error) {
|
||||
publicKeyReader := bytes.NewReader(publicKey)
|
||||
pubKeyEntries, err := openpgp.ReadKeyRing(publicKeyReader)
|
||||
|
||||
|
|
@ -170,7 +171,7 @@ func KeyPacketWithPublicKeyBin(sessionSplit *SessionSplit, publicKey []byte) ([]
|
|||
}
|
||||
|
||||
//GetSessionFromSymmetricPacket ...
|
||||
func GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*SessionSplit, error) {
|
||||
func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*models.SessionSplit, error) {
|
||||
|
||||
keyReader := bytes.NewReader(keyPackage)
|
||||
packets := packet.NewReader(keyReader)
|
||||
|
|
@ -196,7 +197,7 @@ func GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*Session
|
|||
for _, s := range symKeys {
|
||||
key, cipherFunc, err := s.Decrypt(pwdRaw)
|
||||
if err == nil {
|
||||
return &SessionSplit{
|
||||
return &models.SessionSplit{
|
||||
Session: key,
|
||||
Algo: getAlgo(cipherFunc),
|
||||
}, nil
|
||||
|
|
@ -209,7 +210,7 @@ func GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*Session
|
|||
}
|
||||
|
||||
// SymmetricKeyPacketWithPassword ...
|
||||
func SymmetricKeyPacketWithPassword(sessionSplit *SessionSplit, password string) ([]byte, error) {
|
||||
func (pm *PmCrypto) SymmetricKeyPacketWithPassword(sessionSplit *models.SessionSplit, password string) ([]byte, error) {
|
||||
outbuf := &bytes.Buffer{}
|
||||
|
||||
cf := cipherFunc(sessionSplit.Algo)
|
||||
|
|
@ -249,7 +250,7 @@ func cipherFunc(algo string) packet.CipherFunction {
|
|||
return packet.CipherAES256
|
||||
}
|
||||
|
||||
func getSessionSplit(ek *packet.EncryptedKey) (*SessionSplit, error) {
|
||||
func getSessionSplit(ek *packet.EncryptedKey) (*models.SessionSplit, error) {
|
||||
if ek == nil {
|
||||
return nil, errors.New("can't decrypt key packet")
|
||||
}
|
||||
|
|
@ -265,7 +266,7 @@ func getSessionSplit(ek *packet.EncryptedKey) (*SessionSplit, error) {
|
|||
return nil, errors.New("can't decrypt key packet key is nil")
|
||||
}
|
||||
|
||||
return &SessionSplit{
|
||||
return &models.SessionSplit{
|
||||
Session: ek.Key,
|
||||
Algo: algo,
|
||||
}, nil
|
||||
|
|
@ -281,82 +282,4 @@ func getAlgo(cipher packet.CipherFunction) string {
|
|||
}
|
||||
|
||||
return algo
|
||||
}
|
||||
|
||||
//encode length based on 4.2.2. in the RFC
|
||||
func encodedLength(length int) (b []byte) {
|
||||
if length < 192 {
|
||||
b = append(b, byte(length))
|
||||
} else if length < 8384 {
|
||||
length = length - 192
|
||||
b = append(b, 192+byte(length>>8))
|
||||
b = append(b, byte(length))
|
||||
} else {
|
||||
b = append(b, byte(255))
|
||||
b = append(b, byte(length>>24))
|
||||
b = append(b, byte(length>>16))
|
||||
b = append(b, byte(length>>8))
|
||||
b = append(b, byte(length))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SeparateKeyAndData ...
|
||||
func SeparateKeyAndData(encrypted string) (*EncryptedSplit, error) {
|
||||
|
||||
var err error
|
||||
|
||||
encryptedRaw, err := UnArmor(encrypted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
encryptedReader := bytes.NewReader(encryptedRaw)
|
||||
|
||||
//kr *KeyRing, r io.Reader) (key *SymmetricKey, symEncryptedData []byte,
|
||||
packets := packet.NewReader(encryptedReader)
|
||||
|
||||
outSplit := &EncryptedSplit{}
|
||||
|
||||
// Save encrypted key and signature apart
|
||||
var ek *packet.EncryptedKey
|
||||
// var decryptErr error
|
||||
for {
|
||||
var p packet.Packet
|
||||
if p, err = packets.Next(); err == io.EOF {
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
switch p := p.(type) {
|
||||
case *packet.EncryptedKey:
|
||||
// We got an encrypted key. Try to decrypt it with each available key
|
||||
if ek != nil && ek.Key != nil {
|
||||
break
|
||||
}
|
||||
ek = p
|
||||
break
|
||||
case *packet.SymmetricallyEncrypted:
|
||||
var packetContents []byte
|
||||
if packetContents, err = ioutil.ReadAll(p.Contents); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
encodedLength := encodedLength(len(packetContents) + 1)
|
||||
var symEncryptedData []byte
|
||||
symEncryptedData = append(symEncryptedData, byte(210))
|
||||
symEncryptedData = append(symEncryptedData, encodedLength...)
|
||||
symEncryptedData = append(symEncryptedData, byte(1))
|
||||
symEncryptedData = append(symEncryptedData, packetContents...)
|
||||
|
||||
outSplit.DataPacket = symEncryptedData
|
||||
break
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
ek.Serialize(&buf)
|
||||
outSplit.KeyPacket = buf.Bytes()
|
||||
|
||||
return outSplit, err
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pmcrypto
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
|
@ -7,28 +7,19 @@ import (
|
|||
"time"
|
||||
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"golang.org/x/crypto/openpgp/clearsign"
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
errors2 "golang.org/x/crypto/openpgp/errors"
|
||||
"io"
|
||||
"proton/pmcrypto/internal"
|
||||
)
|
||||
|
||||
//ReadClearSignedMessage read clear message from a clearsign package
|
||||
func ReadClearSignedMessage(signedMessage string) (string, error) {
|
||||
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
|
||||
if len(rest) != 0 {
|
||||
return "", errors.New("pmapi: extra data after modulus")
|
||||
}
|
||||
return string(modulusBlock.Bytes), nil
|
||||
}
|
||||
|
||||
// SignTextDetached sign detached text type
|
||||
func (o *OpenPGP) SignTextDetached(plainText string, privateKey string, passphrase string, trim bool) (string, error) {
|
||||
func (pm *PmCrypto) SignTextDetached(plainText string, privateKey string, passphrase string, trim bool) (string, error) {
|
||||
//sign with 0x01 text
|
||||
var signEntity *openpgp.Entity
|
||||
|
||||
if trim {
|
||||
plainText = trimNewlines(plainText)
|
||||
plainText = internal.TrimNewlines(plainText)
|
||||
}
|
||||
|
||||
signerReader := strings.NewReader(privateKey)
|
||||
|
|
@ -54,7 +45,7 @@ func (o *OpenPGP) SignTextDetached(plainText string, privateKey string, passphra
|
|||
return "", errors.New("cannot sign message, signer key is not unlocked")
|
||||
}
|
||||
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator() }
|
||||
|
||||
att := strings.NewReader(plainText)
|
||||
|
||||
|
|
@ -68,12 +59,12 @@ func (o *OpenPGP) SignTextDetached(plainText string, privateKey string, passphra
|
|||
}
|
||||
|
||||
// SignTextDetachedBinKey ...
|
||||
func (o *OpenPGP) SignTextDetachedBinKey(plainText string, privateKey []byte, passphrase string, trim bool) (string, error) {
|
||||
func (pm *PmCrypto) SignTextDetachedBinKey(plainText string, privateKey []byte, passphrase string, trim bool) (string, error) {
|
||||
//sign with 0x01
|
||||
var signEntity *openpgp.Entity
|
||||
|
||||
if trim {
|
||||
plainText = trimNewlines(plainText)
|
||||
plainText = internal.TrimNewlines(plainText)
|
||||
}
|
||||
|
||||
signerReader := bytes.NewReader(privateKey)
|
||||
|
|
@ -99,7 +90,7 @@ func (o *OpenPGP) SignTextDetachedBinKey(plainText string, privateKey []byte, pa
|
|||
return "", errors.New("cannot sign message, singer key is not unlocked")
|
||||
}
|
||||
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator() }
|
||||
|
||||
att := strings.NewReader(plainText)
|
||||
|
||||
|
|
@ -113,7 +104,7 @@ func (o *OpenPGP) SignTextDetachedBinKey(plainText string, privateKey []byte, pa
|
|||
}
|
||||
|
||||
// SignBinDetached sign bin data
|
||||
func (o *OpenPGP) SignBinDetached(plainData []byte, privateKey string, passphrase string) (string, error) {
|
||||
func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey string, passphrase string) (string, error) {
|
||||
//sign with 0x00
|
||||
var signEntity *openpgp.Entity
|
||||
|
||||
|
|
@ -140,7 +131,7 @@ func (o *OpenPGP) SignBinDetached(plainData []byte, privateKey string, passphras
|
|||
return "", errors.New("cannot sign message, singer key is not unlocked")
|
||||
}
|
||||
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator() }
|
||||
|
||||
att := bytes.NewReader(plainData)
|
||||
|
||||
|
|
@ -154,7 +145,7 @@ func (o *OpenPGP) SignBinDetached(plainData []byte, privateKey string, passphras
|
|||
}
|
||||
|
||||
// SignBinDetachedBinKey ...
|
||||
func (o *OpenPGP) SignBinDetachedBinKey(plainData []byte, privateKey []byte, passphrase string) (string, error) {
|
||||
func (pm *PmCrypto) SignBinDetachedBinKey(plainData []byte, privateKey []byte, passphrase string) (string, error) {
|
||||
//sign with 0x00
|
||||
var signEntity *openpgp.Entity
|
||||
|
||||
|
|
@ -181,7 +172,7 @@ func (o *OpenPGP) SignBinDetachedBinKey(plainData []byte, privateKey []byte, pas
|
|||
return "", errors.New("cannot sign message, singer key is not unlocked")
|
||||
}
|
||||
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: o.getTimeGenerator() }
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator() }
|
||||
|
||||
att := bytes.NewReader(plainData)
|
||||
|
||||
|
|
@ -195,7 +186,7 @@ func (o *OpenPGP) SignBinDetachedBinKey(plainData []byte, privateKey []byte, pas
|
|||
}
|
||||
|
||||
// VerifyTextSignDetached ...
|
||||
func (o *OpenPGP) VerifyTextSignDetached(signature string, plainText string, publicKey string, verifyTime int64) (bool, error) {
|
||||
func (pm *PmCrypto) VerifyTextSignDetached(signature string, plainText string, publicKey string, verifyTime int64) (bool, error) {
|
||||
|
||||
pubKeyReader := strings.NewReader(publicKey)
|
||||
|
||||
|
|
@ -204,7 +195,7 @@ func (o *OpenPGP) VerifyTextSignDetached(signature string, plainText string, pub
|
|||
return false, err
|
||||
}
|
||||
|
||||
plainText = trimNewlines(plainText)
|
||||
plainText = internal.TrimNewlines(plainText)
|
||||
|
||||
origText := bytes.NewReader(bytes.NewBufferString(plainText).Bytes())
|
||||
|
||||
|
|
@ -212,7 +203,7 @@ func (o *OpenPGP) VerifyTextSignDetached(signature string, plainText string, pub
|
|||
}
|
||||
|
||||
// VerifyTextSignDetachedBinKey ...
|
||||
func (o *OpenPGP) VerifyTextSignDetachedBinKey(signature string, plainText string, publicKey []byte, verifyTime int64) (bool, error) {
|
||||
func (pm *PmCrypto) VerifyTextSignDetachedBinKey(signature string, plainText string, publicKey []byte, verifyTime int64) (bool, error) {
|
||||
|
||||
pubKeyReader := bytes.NewReader(publicKey)
|
||||
|
||||
|
|
@ -221,7 +212,7 @@ func (o *OpenPGP) VerifyTextSignDetachedBinKey(signature string, plainText strin
|
|||
return false, err
|
||||
}
|
||||
|
||||
plainText = trimNewlines(plainText)
|
||||
plainText = internal.TrimNewlines(plainText)
|
||||
origText := bytes.NewReader(bytes.NewBufferString(plainText).Bytes())
|
||||
|
||||
return verifySignature(pubKeyEntries, origText, signature, verifyTime)
|
||||
|
|
@ -235,7 +226,7 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, s
|
|||
}
|
||||
} else {
|
||||
config.Time = func() time.Time {
|
||||
return time.Unix(verifyTime + creationTimeOffset, 0)
|
||||
return time.Unix(verifyTime + internal.CreationTimeOffset, 0)
|
||||
}
|
||||
}
|
||||
signatureReader := strings.NewReader(signature)
|
||||
|
|
@ -272,7 +263,7 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, s
|
|||
|
||||
|
||||
// VerifyBinSignDetached ...
|
||||
func (o *OpenPGP) VerifyBinSignDetached(signature string, plainData []byte, publicKey string, verifyTime int64) (bool, error) {
|
||||
func (pm *PmCrypto) VerifyBinSignDetached(signature string, plainData []byte, publicKey string, verifyTime int64) (bool, error) {
|
||||
|
||||
pubKeyReader := strings.NewReader(publicKey)
|
||||
|
||||
|
|
@ -286,7 +277,7 @@ func (o *OpenPGP) VerifyBinSignDetached(signature string, plainData []byte, publ
|
|||
}
|
||||
|
||||
// VerifyBinSignDetachedBinKey ...
|
||||
func (o *OpenPGP) VerifyBinSignDetachedBinKey(signature string, plainData []byte, publicKey []byte, verifyTime int64) (bool, error) {
|
||||
func (pm *PmCrypto) VerifyBinSignDetachedBinKey(signature string, plainData []byte, publicKey []byte, verifyTime int64) (bool, error) {
|
||||
pubKeyReader := bytes.NewReader(publicKey)
|
||||
|
||||
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pmcrypto
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
|
@ -21,7 +21,7 @@ type SignatureCollector struct {
|
|||
verified int
|
||||
}
|
||||
|
||||
func NewSignatureCollector(targetAccepter pmmime.VisitAcceptor, keyring openpgp.KeyRing, config *packet.Config) *SignatureCollector {
|
||||
func newSignatureCollector(targetAccepter pmmime.VisitAcceptor, keyring openpgp.KeyRing, config *packet.Config) *SignatureCollector {
|
||||
return &SignatureCollector{
|
||||
target: targetAccepter,
|
||||
config: config,
|
||||
|
|
@ -140,7 +140,8 @@ func (sc *SignatureCollector) Accept(part io.Reader, header textproto.MIMEHeader
|
|||
return err
|
||||
}
|
||||
sc.signature = string(buffer)
|
||||
|
||||
str, _ := ioutil.ReadAll(rawBody)
|
||||
rawBody = bytes.NewReader(str)
|
||||
if sc.keyring != nil {
|
||||
_, err = openpgp.CheckArmoredDetachedSignature(sc.keyring, rawBody, bytes.NewReader(buffer), sc.config)
|
||||
|
||||
32
crypto/time.go
Normal file
32
crypto/time.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// UpdateTime update cached time
|
||||
func (pm *PmCrypto) UpdateTime(newTime int64) {
|
||||
pm.latestServerTime = newTime
|
||||
pm.latestClientTime = time.Now()
|
||||
}
|
||||
|
||||
//GetTime get latest cached time
|
||||
func (pm *PmCrypto) GetTime() int64 {
|
||||
return pm.getNow().Unix()
|
||||
}
|
||||
|
||||
func (pm *PmCrypto) getNow() time.Time {
|
||||
if pm.latestServerTime > 0 && !pm.latestClientTime.IsZero() {
|
||||
// Sub is monotome, it uses a monotime time clock in this case instead of the wall clock
|
||||
extrapolate := int64(pm.latestClientTime.Sub(time.Now()).Seconds())
|
||||
return time.Unix(pm.latestServerTime + extrapolate, 0)
|
||||
}
|
||||
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
func (pm *PmCrypto) getTimeGenerator() func() time.Time {
|
||||
return func() time.Time {
|
||||
return pm.getNow()
|
||||
}
|
||||
}
|
||||
BIN
dist/Android/pmcrypto-sources.jar
vendored
Normal file
BIN
dist/Android/pmcrypto-sources.jar
vendored
Normal file
Binary file not shown.
BIN
dist/Android/pmcrypto.aar
vendored
Normal file
BIN
dist/Android/pmcrypto.aar
vendored
Normal file
Binary file not shown.
12
glide.lock
generated
12
glide.lock
generated
|
|
@ -1,8 +1,8 @@
|
|||
hash: 4251e23b87e24d3580705ee49d6354cbd956d2ecc254bd9cb2037d5fd6f34d48
|
||||
updated: 2018-09-04T20:05:07.075614+02:00
|
||||
hash: 0e0069ce69a4e3bde6233726f21a880347400808a97c2e6f7a173e4d7daea51c
|
||||
updated: 2018-09-07T10:20:50.211694+02:00
|
||||
imports:
|
||||
- name: github.com/Sirupsen/logrus
|
||||
version: 78fa2915c1fa231f62e0438da493688c21ca678e
|
||||
version: 3791101e143bf0f32515ac23e831475684f61229
|
||||
- name: golang.org/x/crypto
|
||||
version: 9e4251120d8c43f10024d798bc6dde21d40704a0
|
||||
repo: https://github.com/ProtonMail/crypto.git
|
||||
|
|
@ -31,12 +31,12 @@ imports:
|
|||
- rsa
|
||||
- ssh/terminal
|
||||
- name: golang.org/x/sys
|
||||
version: 2b024373dcd9800f0cae693839fac6ede8d64a8c
|
||||
version: 8cf3aee429924738c56c34bb819c4ea8273fc434
|
||||
subpackages:
|
||||
- unix
|
||||
- windows
|
||||
- name: golang.org/x/text
|
||||
version: 6e3c4e7365ddcc329f090f96e4348398f6310088
|
||||
version: 4ae1256249243a4eb350a9a372e126557f2aa346
|
||||
subpackages:
|
||||
- encoding
|
||||
- encoding/charmap
|
||||
|
|
@ -44,6 +44,6 @@ imports:
|
|||
- encoding/internal/identifier
|
||||
- transform
|
||||
- name: proton/pmmime
|
||||
version: f64ddc9969090ae55c92712def8289587816dc11
|
||||
version: 347d69204aa62d6958bcb3b9bbacccb24a36372b
|
||||
repo: git@gitlab.protontech.ch:ProtonMail/go-pm-mime.git
|
||||
testImports: []
|
||||
|
|
|
|||
|
|
@ -5,4 +5,3 @@ import:
|
|||
repo: https://github.com/ProtonMail/crypto.git
|
||||
- package: proton/pmmime
|
||||
repo: git@gitlab.protontech.ch:ProtonMail/go-pm-mime.git
|
||||
version: feat/mimevisitor
|
||||
|
|
|
|||
16
internal/armor.go
Normal file
16
internal/armor.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/openpgp/armor"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func UnArmor(input string) (*armor.Block, error) {
|
||||
io := strings.NewReader(input)
|
||||
b, err := armor.Decode(io)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
|
||||
}
|
||||
25
internal/common.go
Normal file
25
internal/common.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"proton/pmcrypto/constants"
|
||||
)
|
||||
|
||||
|
||||
func TrimNewlines(input string) string {
|
||||
var re = regexp.MustCompile(`(?m)[ \t]*$`)
|
||||
return re.ReplaceAllString(input, "")
|
||||
}
|
||||
|
||||
// Amount of seconds that a signature may be created after the verify time
|
||||
// Consistent with the 2 day slack allowed in the ProtonMail Email Parser
|
||||
const CreationTimeOffset = int64(60 * 60 * 24 * 2)
|
||||
|
||||
const (
|
||||
ARMOR_HEADER_VERSION = "Pmcrypto Golang 0.0.1 (" + constants.VERSION + ")"
|
||||
ARMOR_HEADER_COMMENT = "https://protonmail.com"
|
||||
)
|
||||
var ArmorHeaders = map[string]string {
|
||||
"Version": ARMOR_HEADER_VERSION,
|
||||
"Comment": ARMOR_HEADER_COMMENT,
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pmcrypto
|
||||
package key
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
|
@ -6,11 +6,12 @@ import (
|
|||
"errors"
|
||||
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"proton/pmcrypto/armor"
|
||||
)
|
||||
|
||||
// GetFingerprint get a armored public key fingerprint
|
||||
func GetFingerprint(publicKey string) (string, error) {
|
||||
rawPubKey, err := UnArmor(publicKey)
|
||||
rawPubKey, err := armor.UnArmor(publicKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
78
key/key.go
Normal file
78
key/key.go
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
package key
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
"bytes"
|
||||
"proton/pmcrypto/armor"
|
||||
)
|
||||
|
||||
//CheckPassphrase check is private key passphrase ok
|
||||
func CheckPassphrase(privateKey string, passphrase string) bool {
|
||||
privKeyReader := strings.NewReader(privateKey)
|
||||
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return false
|
||||
}
|
||||
|
||||
var keys []*packet.PrivateKey
|
||||
|
||||
for _, e := range entries {
|
||||
keys = append(keys, e.PrivateKey)
|
||||
}
|
||||
var decryptError error
|
||||
var n int
|
||||
for _, key := range keys {
|
||||
if !key.Encrypted {
|
||||
continue // Key already decrypted
|
||||
}
|
||||
if decryptError = key.Decrypt([]byte(passphrase)); decryptError == nil {
|
||||
n++
|
||||
}
|
||||
}
|
||||
if n == 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
// PublicKey get a public key from a private key
|
||||
func PublicKey(privateKey string) (string, error) {
|
||||
privKeyReader := strings.NewReader(privateKey)
|
||||
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
for _, e := range entries {
|
||||
e.Serialize(&outBuf)
|
||||
}
|
||||
|
||||
outString, err := armor.ArmorWithType(outBuf.Bytes(), armor.PUBLIC_KEY_HEADER)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return outString, nil
|
||||
}
|
||||
|
||||
// PublicKeyBinOut get a public key from a private key
|
||||
func PublicKeyBinOut(privateKey string) ([]byte, error) {
|
||||
privKeyReader := strings.NewReader(privateKey)
|
||||
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
for _, e := range entries {
|
||||
e.Serialize(&outBuf)
|
||||
}
|
||||
|
||||
return outBuf.Bytes(), nil
|
||||
}
|
||||
32
models/models.go
Normal file
32
models/models.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package models
|
||||
|
||||
|
||||
//EncryptedSplit when encrypt attachemt
|
||||
type EncryptedSplit struct {
|
||||
DataPacket []byte
|
||||
KeyPacket []byte
|
||||
Algo string
|
||||
}
|
||||
|
||||
//SessionSplit splited session
|
||||
type SessionSplit struct {
|
||||
Session []byte
|
||||
Algo string
|
||||
}
|
||||
|
||||
//EncryptedSigned encrypt_sign_package
|
||||
type EncryptedSigned struct {
|
||||
Encrypted string
|
||||
Signature string
|
||||
}
|
||||
|
||||
//DecryptSignedVerify decrypt_sign_verify
|
||||
type DecryptSignedVerify struct {
|
||||
//clear text
|
||||
Plaintext string
|
||||
//bitmask verify status : 0
|
||||
Verify int
|
||||
//error message if verify failed
|
||||
Message string
|
||||
}
|
||||
|
||||
32
time.go
32
time.go
|
|
@ -1,32 +0,0 @@
|
|||
package pmcrypto
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// UpdateTime update cached time
|
||||
func (o *OpenPGP) UpdateTime(newTime int64) {
|
||||
o.latestServerTime = newTime
|
||||
o.latestClientTime = time.Now()
|
||||
}
|
||||
|
||||
//GetTime get latest cached time
|
||||
func (o *OpenPGP) GetTime() int64 {
|
||||
return o.getNow().Unix()
|
||||
}
|
||||
|
||||
func (o *OpenPGP) getNow() time.Time {
|
||||
if o.latestServerTime > 0 && !o.latestClientTime.IsZero() {
|
||||
// Sub is monotome, it uses a monotime time clock in this case instead of the wall clock
|
||||
extrapolate := int64(o.latestClientTime.Sub(time.Now()).Seconds())
|
||||
return time.Unix(o.latestServerTime + extrapolate, 0)
|
||||
}
|
||||
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
func (o *OpenPGP) getTimeGenerator() func() time.Time {
|
||||
return func() time.Time {
|
||||
return o.getNow()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
package pmcrypto
|
||||
|
||||
// Version get current lib version
|
||||
func Version() string {
|
||||
return "ddacebe0"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue