Optimize encrypt attachment
This commit is contained in:
parent
0456595f68
commit
9dfb46fe45
24 changed files with 726 additions and 94 deletions
105
src/gitlab.com/ProtonMail/go-pm-crypto/internal/packets.go
Normal file
105
src/gitlab.com/ProtonMail/go-pm-crypto/internal/packets.go
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
"gitlab.com/ProtonMail/go-pm-crypto/models"
|
||||
"io"
|
||||
)
|
||||
|
||||
func SplitPackets(encryptedReader io.Reader, estimatedLength int) (*models.EncryptedSplit, error){
|
||||
var err error
|
||||
|
||||
//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:
|
||||
// The code below is optimized to not
|
||||
var b bytes.Buffer
|
||||
// 128 is an estimation of the size difference between input and output, the size difference is most probably
|
||||
// 16 bytes at a maximum though.
|
||||
b.Grow(128 + estimatedLength)
|
||||
// empty encoded length + start byte
|
||||
b.Write(make([]byte, 6))
|
||||
b.WriteByte(byte(1))
|
||||
actualLength := 1
|
||||
block := make([]byte, 128)
|
||||
for {
|
||||
n, err := p.Contents.Read(block)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
b.Write(block[:n])
|
||||
actualLength += n
|
||||
}
|
||||
|
||||
// quick encoding
|
||||
symEncryptedData := b.Bytes()
|
||||
if actualLength < 192 {
|
||||
symEncryptedData[4] = byte(210)
|
||||
symEncryptedData[5] = byte(actualLength)
|
||||
symEncryptedData = symEncryptedData[4:]
|
||||
} else if actualLength < 8384 {
|
||||
actualLength = actualLength - 192
|
||||
symEncryptedData[3] = byte(210)
|
||||
symEncryptedData[4] = 192+byte(actualLength>>8)
|
||||
symEncryptedData[5] = byte(actualLength)
|
||||
symEncryptedData = symEncryptedData[3:]
|
||||
} else {
|
||||
symEncryptedData[0] = byte(210)
|
||||
symEncryptedData[1] = byte(255)
|
||||
symEncryptedData[2] = byte(actualLength>>24)
|
||||
symEncryptedData[3] = byte(actualLength>>16)
|
||||
symEncryptedData[4] = byte(actualLength>>8)
|
||||
symEncryptedData[5] = byte(actualLength)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue