diff --git a/model/headers/headers.go b/model/headers/headers.go index 3b80cd2..6cbadc7 100644 --- a/model/headers/headers.go +++ b/model/headers/headers.go @@ -262,6 +262,29 @@ func NewHeaderPacket(reader io.Reader, readerPrivateKey [chacha20poly1305.KeySiz return &headerPacket, nil } +// EncryptedSegmentSize returns the size of an encrypted segment for a given header and reader private key. +func EncryptedSegmentSize(header []byte, readerPrivateKey [chacha20poly1305.KeySize]byte) (int, error) { + + buffer := bytes.NewBuffer(header) + decryptedHeader, err := NewHeader(buffer, readerPrivateKey) + if err != nil { + return 0, err + } + + dataEncryptionParametersHeaderPackets, err := decryptedHeader.GetDataEncryptionParameterHeaderPackets() + if err != nil { + return 0, err + } + + firstDataEncryptionParametersHeader := (*dataEncryptionParametersHeaderPackets)[0] + for _, dataEncryptionParametersHeader := range *dataEncryptionParametersHeaderPackets { + if dataEncryptionParametersHeader.GetPacketType() != firstDataEncryptionParametersHeader.GetPacketType() { + return 0, fmt.Errorf("different data encryption methods are not supported") + } + } + return firstDataEncryptionParametersHeader.EncryptedSegmentSize, nil +} + // MarshalBinary implements method MarshalBinary.BinaryMarshaler. func (hp *HeaderPacket) MarshalBinary() (data []byte, err error) { var encryptedMarshalledEncryptedHeaderPacket []byte diff --git a/model/headers/headers_test.go b/model/headers/headers_test.go index a7f8174..3bde2f7 100644 --- a/model/headers/headers_test.go +++ b/model/headers/headers_test.go @@ -299,3 +299,37 @@ func TestReEncryptedHeader(t *testing.T) { t.Fail() } } + +func TestEncryptedSegmentSize(t *testing.T) { + inFile, err := os.Open("../../test/sample.txt.enc") + if err != nil { + t.Errorf("Fileopen failed: %v", err) + } + readerSecretKey, err := keys.ReadPrivateKey(strings.NewReader(crypt4ghX25519Sec), []byte("password")) + if err != nil { + t.Errorf("ReadPrivateKey failed: %v", err) + } + + header, err := ReadHeader(inFile) + if err != nil { + t.Errorf("ReadHeader failed: %v", err) + } + + size, err := EncryptedSegmentSize(header, readerSecretKey) + if err != nil { + t.Errorf("EncryptedSegmentSize failed where it should work: %v", err) + } else if size != 65564 { + t.Errorf("EncryptedSegmentSize returned unexpected size %d (expected 65564)", size) + } + + size, err = EncryptedSegmentSize(header, ([32]byte)(make([]byte, 32))) + if err == nil { + t.Errorf("EncryptedSegmentSize worked where it should fail: %v", err) + } + + size, err = EncryptedSegmentSize(make([]byte, 2), readerSecretKey) + if err == nil { + t.Errorf("EncryptedSegmentSize worked where it should fail: %v", err) + } + +}