github.com/minio/madmin-go/v2@v2.2.1/estream/README.md (about)

     1  # Encrypted Stream
     2  
     3  This package provides a flexible way to merge multiple streams with controlled encryption.
     4  
     5  The stream is stateful and allows to send individually encrypted streams.
     6  
     7  ## Features
     8  
     9  * Allows encrypted and unencrypted streams.
    10  * Any number of keys can be used on streams.
    11  * Each key can be encrypted by a (different) public key.
    12  * Each stream is identified by a string "name".
    13  * A stream has optional (unencrypted) metadata slice.
    14  * Keys can be re-encrypted with another public key without needing data re-encryption given the private key.
    15  * Streams are checksummed.
    16  * Streams cannot be truncated by early EOF.
    17  * Format is extensible with skippable blocks.
    18  * Allows signaling errors while writing streams.
    19  * Nonce per stream (of course).
    20  * Messagepack for platform independent type safety.
    21  
    22  # Usage
    23  
    24  Create a writer that will write the stream. 
    25  
    26  You must provide an `io.Writer` to which the output is written. 
    27  Once all streams have been written it should be closed to indicate end of payload. 
    28  
    29  ```Go
    30      w := estream.NewWriter(output)
    31      defer w.Close()
    32  ```
    33  
    34  It is possible to signal an error to the receiver using `w.AddError(msg string)`.
    35  This will return the error to the receiver.  
    36  
    37  ## Adding keys
    38  
    39  Keys for streams must be added. The keys themselves are 32 bytes of random data, 
    40  but it must be specified how they are stored. 
    41  
    42  They can be added as plain text, which isn't secure, 
    43  but allows later encryption using a public key.
    44  To add a key without encryption use `w.AddKeyPlain()` 
    45  which will add the keys to the stream.
    46  
    47  To add an encrypted key provide a 2048 bit public RSA key.
    48  Use `w.AddKeyEncrypted(publicKey)` to add a key to the stream.
    49  
    50  Once a key has been sent on the stream it will be used for all subsequent encrypted streams.
    51  This means that different keys with different private/public keys can be sent for different streams.
    52  
    53  ## Sending streams
    54  
    55  Streams are added using either `w.AddEncryptedStream` or `w.AddUnencryptedStream`.
    56  
    57  A string identifier can be used to identify each stream when reading.
    58  An optional byte block can also be sent.
    59  
    60  Note that neither the name nor the byte block is encrypted, 
    61  so they should not contain sensitive data.
    62  
    63  The functions above return an `io.WriteCloser`.
    64  Data for this stream should be written to this interface
    65  and `Close()` should be called before another stream can be added.
    66  
    67  Note that en-uncrypted streams are unbuffered, so it may be a benefit to insert a `bufio.Writer`
    68  to avoid very small packets. Encrypted streams are buffered since sio collects block before sending.
    69  
    70  # Reading Streams
    71  
    72  To read back data `r, err := estream.NewReader(input)` can be used for create a Reader.
    73  
    74  To set a private key, use `r.SetPrivateKey(key)` to set a single private key.
    75  
    76  For multiple keys a key provider can be made to return the appropriate key:
    77  
    78  ```Go
    79      var key1, key2 *rsa.PrivateKey
    80      // (read keys)
    81      r.PrivateKeyProvider(func(key *rsa.PublicKey) *rsa.PrivateKey {
    82          if key.Equal(&key1.PublicKey) {
    83              return key1
    84          }
    85          if key.Equal(&key2.PublicKey) {
    86              return key2
    87          }
    88          // Unknown key :(
    89          return nil
    90      })
    91  ```
    92  
    93  It is possible to skip streams that cannot be decrypted using `r.SkipEncrypted(true)`.
    94  
    95  A simple for loop can be used to get all streams:
    96  
    97  ```Go
    98      for {
    99          stream, err := r.NextStream()
   100          if err == io.EOF {
   101              // All streams read
   102              break
   103          }
   104          // Metadata:
   105          fmt.Println(stream.Name)
   106          fmt.Println(stream.Extra)
   107  		
   108          // Stream content is a standard io.Reader
   109          io.Copy(os.StdOut, stream)
   110      }
   111  ```
   112  
   113  ## Replacing keys
   114  
   115  It is possible to replace public keys needed for decryption using `estream.ReplaceKeys()`.
   116  
   117  For encrypted keys the private key must be provided and optionally unencrypted keys can also be 
   118  encrypted using a public key.
   119  
   120  # Format
   121  
   122  ## Header
   123  
   124  Format starts with 2 version bytes.
   125  
   126  | Field         | Type   |
   127  |---------------|--------|
   128  | Major Version | 1 byte |
   129  | Minor Version | 1 byte |
   130  
   131  Unknown major versions should be rejected by the decoder, 
   132  however minor versions are assumed to be compatible, 
   133  but may contain data that will be ignored by older versions.
   134  
   135  ## Blocks
   136  
   137  
   138  | Field  | Type         | Contents                 |
   139  |--------|--------------|--------------------------|
   140  | id     | integer      | Block ID                 |
   141  | length | unsigned int | Length of block in bytes |
   142  
   143  Each block is preceded by a messagepack encoded int8 indicating the block type.
   144  
   145  Positive types must be parsed by the decoder. Negative types are *skippable* blocks, 
   146  so unknown skippable blocks can be ignored.
   147  
   148  Blocks have their length encoded as a messagepack unsigned integer following the block ID.
   149  This indicates the number of bytes to skip after the length to reach the next block ID.
   150  
   151  Maximum block size is 2^32-1 (4294967295) bytes.
   152  
   153  All block content is messagepack encoded.
   154  
   155  ### id 1: Plain Key
   156  
   157  This block contains an unencrypted key that is used for all following streams.
   158  
   159  Multiple keys can be sent, but only the latest key should be used to decrypt a stream. 
   160  
   161  | Field         | Type      | Contents      |
   162  |---------------|-----------|---------------|
   163  | Stream Key    | bin array | 32 byte key   |
   164  
   165  ### id 2: RSA Encrypted Key
   166  
   167  This block contains an RSA encrypted key that is used for all following streams.
   168  
   169  Multiple keys can be sent, but only the latest key should be used to decrypt a stream.
   170  
   171  | Field      | Type      | Contents                                    |
   172  |------------|-----------|---------------------------------------------|
   173  | Public Key | bin array | RSA public key to PKCS #1 in ASN.1 DER form |
   174  | Cipher Key | bin array | 32 byte key encrypted with public key above |
   175  
   176  The cipher key is encrypted with RSA-OAEP using SHA-512.
   177  
   178  
   179  ### id 3: SIO Encrypted Stream
   180  
   181  Start of stream encrypted using [sio-go](github.com/secure-io/sio-go).
   182  
   183  Stream will be encrypted using `AES_256_GCM` using the last key provided on stream.
   184  
   185  | Field    | Type      | Contents                      |
   186  |----------|-----------|-------------------------------|
   187  | Name     | string    | Identifier of the stream      |
   188  | Extra    | bin array | Optional extra data           |
   189  | Checksum | uint8     | Checksum type used for stream |
   190  | Nonce    | bin array | 8 byte nonce used for stream  |
   191  
   192  The stream consists of all data blocks following until "End Of Stream" block is sent.
   193  
   194  Checksum is of encrypted data.
   195  There is no checksum for decrypted data.
   196  
   197  ### id 4: Plain Stream
   198  
   199  Start of unencrypted stream.
   200  
   201  | Field    | Type      | Contents                      |
   202  |----------|-----------|-------------------------------|
   203  | Name     | string    | Identifier of the stream      |
   204  | Extra    | bin array | Optional extra data           |
   205  | Checksum | uint8     | Checksum type used for stream |
   206  
   207  The stream consists of all data blocks following until "End Of Stream" block is sent.
   208  
   209  ### id 5: Data Block
   210  
   211  Data contains a data block.
   212  
   213  | Field | Type      | Contents                 |
   214  |-------|-----------|--------------------------|
   215  | Data  | bin array | Data to append to stream |
   216  
   217  If block is part of an encrypted stream it should be sent to the stream decrypter as is.
   218  
   219  ### id 6: End Of Stream
   220  
   221  Indicates successful end of individual stream. 
   222  
   223  | Field         | Type      | Contents  |
   224  |---------------|-----------|-----------|
   225  | Checksum      | bin array | Checksum  |
   226  
   227  No more data blocks should be expected before new stream information is sent.
   228  
   229  ### id 7: EOF
   230  
   231  Indicates successful end of all streams.
   232  
   233  ### id 8: Error
   234  
   235  An error block can be sent to indicate an error occurred while generating the stream.
   236  
   237  It is expected that the parser returns the message and stops processing.
   238  
   239  | Field   | Type   | Contents                            |
   240  |---------|--------|-------------------------------------|
   241  | Message | string | Error message that will be returned |
   242  
   243  ## Checksum types
   244  
   245  | ID  | Type                               | Bytes     |
   246  |-----|------------------------------------|-----------|
   247  | 0   | No checksum                        | (ignored) | 
   248  | 1   | 64 bit xxhash (XXH64) (Big Endian) | 8         |
   249  
   250  # Version History
   251  
   252  | Major | Minor | Changes         |
   253  |-------|-------|-----------------|
   254  | 2     | 1     | Initial Version | 
   255