Add a streaming api to KeyRing and SessionKey (#131)
* barebone streaming functionality * encryption needs to return a writecloser * added eof check * workaround for reader problem with copies * separate mobile wrappers from main api * add a clone in the read result to avoid memory corruption * refactor to reuse code, and fix verification * have to give the verify key at the start of the decryption * enfore readAll before signature verification * streaming api for SessionKey * add split message stream apis * name interface params * fix streaming api so it's supported by go-mobile * hide internal writeCloser * fix nil access * added detached sigs methods * started unit testing * unit testing and fixed a bug where key and data packets where inverted * remove unecessary error wrapping * figured out closing order and error handling * add GC calls to mobile writer and reader * remove debugging values and arrays * writer with builtin sha256 * unit testing the mobile helpers * comments and linting * Typo in error Co-authored-by: wussler <aron@wussler.it> * Add GetKeyPacket doc Co-authored-by: wussler <aron@wussler.it> * Add rfc reference in comments Co-authored-by: wussler <aron@wussler.it> * small improvements * add compatibility tests with normal methods * remove unecessary copies in the tests * update go-crypto to the merged changes commit * update comments of core internal functions * remove unused nolint comment * group message metadata in a struct * fix comments * change default values for metadata * change the mobile reader wrapper to fit the behavior of java * remove gc calls in the wrappers to avoid performance penalties * bring back the former Go2MobileReader to be used for ios * Update crypto/keyring_streaming.go Co-authored-by: wussler <aron@wussler.it> * return an error when verifying an embedded sig with no keyring * Update crypto/sessionkey_streaming.go Co-authored-by: wussler <aron@wussler.it> * linter error * update changelog * update changelog Co-authored-by: wussler <aron@wussler.it>
This commit is contained in:
parent
7380f7391f
commit
c46ed8ed9e
11 changed files with 1718 additions and 97 deletions
127
CHANGELOG.md
127
CHANGELOG.md
|
|
@ -4,6 +4,133 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
### Added
|
||||
- Streaming API:
|
||||
- New structs:
|
||||
- `PlainMessageMetadata`: holds the metadata of a plain PGP message
|
||||
```go
|
||||
type PlainMessageMetadata struct {
|
||||
IsBinary bool
|
||||
Filename string
|
||||
ModTime int64
|
||||
}
|
||||
```
|
||||
- `PlainMessageReader` implements `Reader` and:
|
||||
```go
|
||||
func (msg *PlainMessageReader) GetMetadata() *PlainMessageMetadata
|
||||
func (msg *PlainMessageReader) VerifySignature() (err error)
|
||||
```
|
||||
- `EncryptSplitResult` implements `WriteCloser` and:
|
||||
```go
|
||||
func (res *EncryptSplitResult) GetKeyPacket() (keyPacket []byte, err error)
|
||||
```
|
||||
- Keyring methods:
|
||||
- Encrypt (and optionally sign) a message directly into a `Writer`:
|
||||
```go
|
||||
func (keyRing *KeyRing) EncryptStream(
|
||||
pgpMessageWriter Writer,
|
||||
plainMessageMetadata *PlainMessageMetadata,
|
||||
signKeyRing *KeyRing,
|
||||
) (plainMessageWriter WriteCloser, err error)
|
||||
```
|
||||
- Encrypt (and optionally sign) a message directly into a `Writer` (split keypacket and datapacket):
|
||||
```go
|
||||
func (keyRing *KeyRing) EncryptSplitStream(
|
||||
dataPacketWriter Writer,
|
||||
plainMessageMetadata *PlainMessageMetadata,
|
||||
signKeyRing *KeyRing,
|
||||
) (*EncryptSplitResult, error)
|
||||
```
|
||||
|
||||
- Decrypt (and optionally verify) a message from a `Reader`:
|
||||
```go
|
||||
func (keyRing *KeyRing) DecryptStream(
|
||||
message Reader,
|
||||
verifyKeyRing *KeyRing,
|
||||
verifyTime int64,
|
||||
) (plainMessage *PlainMessageReader, err error)
|
||||
```
|
||||
N.B.: to verify the signature, you will need to call `plainMessage.VerifySignature()` after all the data has been read from `plainMessage`.
|
||||
- Decrypt (and optionally verify) a split message, getting the datapacket from a `Reader`:
|
||||
```go
|
||||
func (keyRing *KeyRing) DecryptSplitStream(
|
||||
keypacket []byte,
|
||||
dataPacketReader Reader,
|
||||
verifyKeyRing *KeyRing, verifyTime int64,
|
||||
) (plainMessage *PlainMessageReader, err error)
|
||||
```
|
||||
N.B.: to verify the signature, you will need to call `plainMessage.VerifySignature()` after all the data has been read from `plainMessage`.
|
||||
- Generate a detached signature from a `Reader`:
|
||||
```go
|
||||
func (keyRing *KeyRing) SignDetachedStream(message Reader) (*PGPSignature, error)
|
||||
```
|
||||
- Verify a detached signature for a `Reader`:
|
||||
```go
|
||||
func (keyRing *KeyRing) VerifyDetachedStream(
|
||||
message Reader,
|
||||
signature *PGPSignature,
|
||||
verifyTime int64,
|
||||
) error
|
||||
```
|
||||
- Generate an encrypted detached signature from a `Reader`:
|
||||
```go
|
||||
func (keyRing *KeyRing) SignDetachedEncryptedStream(
|
||||
message Reader,
|
||||
encryptionKeyRing *KeyRing,
|
||||
) (encryptedSignature *PGPMessage, err error)
|
||||
```
|
||||
- Verify an encrypted detached signature for a `Reader`:
|
||||
```go
|
||||
func (keyRing *KeyRing) VerifyDetachedEncryptedStream(
|
||||
message Reader,
|
||||
encryptedSignature *PGPMessage,
|
||||
decryptionKeyRing *KeyRing,
|
||||
verifyTime int64,
|
||||
) error
|
||||
```
|
||||
- SessionKey methods:
|
||||
- Encrypt (and optionally sign) a message into a `Writer`:
|
||||
```go
|
||||
func (sk *SessionKey) EncryptStream(
|
||||
dataPacketWriter Writer,
|
||||
plainMessageMetadata *PlainMessageMetadata,
|
||||
signKeyRing *KeyRing,
|
||||
) (plainMessageWriter WriteCloser, err error)
|
||||
```
|
||||
- Decrypt (and optionally verify) a message from a `Reader`:
|
||||
```go
|
||||
func (sk *SessionKey) DecryptStream(
|
||||
dataPacketReader Reader,
|
||||
verifyKeyRing *KeyRing,
|
||||
verifyTime int64,
|
||||
) (plainMessage *PlainMessageReader, err error)
|
||||
```
|
||||
N.B.: to verify the signature, you will need to call `plainMessage.VerifySignature()` after all the data has been read from `plainMessage`.
|
||||
- Mobile apps helpers for `Reader` and `Writer`:
|
||||
Due to limitations of `gomobile`, mobile apps can't implement the `Reader` and `Writer` interfaces directly.
|
||||
|
||||
- Implementing `Reader`: Apps should implement the interface:
|
||||
```go
|
||||
type MobileReader interface {
|
||||
Read(max int) (result *MobileReadResult, err error)
|
||||
}
|
||||
type MobileReadResult struct {
|
||||
N int // N, The number of bytes read
|
||||
IsEOF bool // IsEOF, If true, then the reader has reached the end of the data to read.
|
||||
Data []byte // Data, the data that has been read
|
||||
}
|
||||
```
|
||||
And then wrap it with `Mobile2GoReader(mobileReader)` to turn it into a `Reader`.
|
||||
|
||||
- Implementing `Writer`:
|
||||
|
||||
The apps should implement the `Writer` interface directly, but still need to wrap the writer with `Mobile2GoWriter(mobileWriter)`. We also provide the `Mobile2GoWriterWithSHA256` if you want to compute the SHA256 hash of the written data.
|
||||
|
||||
- Using a `Reader`: To use a reader returned by golang in mobile apps: you should wrap it with:
|
||||
- Android: `Go2AndroidReader(reader)`, implements the `Reader` interface, but returns `n == -1` instead of `err == io.EOF`
|
||||
- iOS: `Go2IOSReader(reader)`, implements `MobileReader`.
|
||||
- Using a `Writer`: you can use a writer returned by golang directly.
|
||||
## [2.1.10] 2021-06-16
|
||||
### Fixed
|
||||
- Removed time interpolation via monotonic clock that can cause signatures in the future
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue