* Updates the garm-provider-common and go-github packages. * Update sqlToParamsInstance to return an error when unmarshaling This change is needed to pull in the new Seal/Unseal functions in common. Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
253 lines
6.4 KiB
Go
253 lines
6.4 KiB
Go
// Copyright (C) 2017 Minio Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package sio
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
)
|
|
|
|
type encReaderV10 struct {
|
|
authEncV10
|
|
src io.Reader
|
|
|
|
buffer packageV10
|
|
offset int
|
|
payloadSize int
|
|
stateErr error
|
|
}
|
|
|
|
// encryptReaderV10 returns an io.Reader wrapping the given io.Reader.
|
|
// The returned io.Reader encrypts everything it reads using DARE 1.0.
|
|
func encryptReaderV10(src io.Reader, config *Config) (*encReaderV10, error) {
|
|
ae, err := newAuthEncV10(config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &encReaderV10{
|
|
authEncV10: ae,
|
|
src: src,
|
|
buffer: packageBufferPool.Get().([]byte)[:maxPackageSize],
|
|
payloadSize: config.PayloadSize,
|
|
}, nil
|
|
}
|
|
|
|
func (r *encReaderV10) recycle() {
|
|
recyclePackageBufferPool(r.buffer)
|
|
r.buffer = nil
|
|
}
|
|
|
|
func (r *encReaderV10) Read(p []byte) (int, error) {
|
|
if r.stateErr != nil {
|
|
return 0, r.stateErr
|
|
}
|
|
var n int
|
|
if r.offset > 0 { // write the buffered package to p
|
|
remaining := r.buffer.Length() - r.offset // remaining encrypted bytes
|
|
if len(p) < remaining {
|
|
n = copy(p, r.buffer[r.offset:r.offset+len(p)])
|
|
r.offset += n
|
|
return n, nil
|
|
}
|
|
n = copy(p, r.buffer[r.offset:r.offset+remaining])
|
|
p = p[remaining:]
|
|
r.offset = 0
|
|
}
|
|
for len(p) >= headerSize+r.payloadSize+tagSize {
|
|
nn, err := io.ReadFull(r.src, p[headerSize:headerSize+r.payloadSize]) // read plaintext from src
|
|
if err != nil && err != io.ErrUnexpectedEOF {
|
|
r.recycle()
|
|
r.stateErr = err
|
|
return n, err // return if reading from src fails or reached EOF
|
|
}
|
|
r.Seal(p, p[headerSize:headerSize+nn])
|
|
n += headerSize + nn + tagSize
|
|
p = p[headerSize+nn+tagSize:]
|
|
}
|
|
if len(p) > 0 {
|
|
nn, err := io.ReadFull(r.src, r.buffer[headerSize:headerSize+r.payloadSize]) // read plaintext from src
|
|
if err != nil && err != io.ErrUnexpectedEOF {
|
|
r.stateErr = err
|
|
r.recycle()
|
|
return n, err // return if reading from src fails or reached EOF
|
|
}
|
|
r.Seal(r.buffer, r.buffer[headerSize:headerSize+nn])
|
|
if length := r.buffer.Length(); length < len(p) {
|
|
r.offset = copy(p, r.buffer[:length])
|
|
} else {
|
|
r.offset = copy(p, r.buffer[:len(p)])
|
|
}
|
|
n += r.offset
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
type decReaderV10 struct {
|
|
authDecV10
|
|
src io.Reader
|
|
|
|
buffer packageV10
|
|
offset int
|
|
stateErr error
|
|
}
|
|
|
|
// decryptReaderV10 returns an io.Reader wrapping the given io.Reader.
|
|
// The returned io.Reader decrypts everything it reads using DARE 1.0.
|
|
func decryptReaderV10(src io.Reader, config *Config) (*decReaderV10, error) {
|
|
ad, err := newAuthDecV10(config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &decReaderV10{
|
|
authDecV10: ad,
|
|
src: src,
|
|
buffer: packageBufferPool.Get().([]byte)[:maxPackageSize],
|
|
}, nil
|
|
}
|
|
|
|
func (r *decReaderV10) recycle() {
|
|
recyclePackageBufferPool(r.buffer)
|
|
r.buffer = nil
|
|
}
|
|
|
|
func (r *decReaderV10) Read(p []byte) (n int, err error) {
|
|
if r.stateErr != nil {
|
|
return 0, r.stateErr
|
|
}
|
|
if r.offset > 0 { // write the buffered plaintext to p
|
|
payload := r.buffer.Payload()
|
|
remaining := len(payload) - r.offset // remaining plaintext bytes
|
|
if len(p) < remaining {
|
|
n = copy(p, payload[r.offset:+r.offset+len(p)])
|
|
r.offset += n
|
|
return
|
|
}
|
|
n = copy(p, payload[r.offset:r.offset+remaining])
|
|
p = p[remaining:]
|
|
r.offset = 0
|
|
}
|
|
for len(p) >= maxPayloadSize {
|
|
if err = r.readPackage(r.buffer); err != nil {
|
|
r.stateErr = err
|
|
r.recycle()
|
|
return n, err
|
|
}
|
|
length := len(r.buffer.Payload())
|
|
if err = r.Open(p[:length], r.buffer[:r.buffer.Length()]); err != nil { // notice: buffer.Length() may be smaller than len(buffer)
|
|
r.stateErr = err
|
|
r.recycle()
|
|
return n, err // decryption failed
|
|
}
|
|
p = p[length:]
|
|
n += length
|
|
}
|
|
if len(p) > 0 {
|
|
if err = r.readPackage(r.buffer); err != nil {
|
|
r.stateErr = err
|
|
r.recycle()
|
|
return n, err
|
|
}
|
|
payload := r.buffer.Payload()
|
|
if err = r.Open(payload, r.buffer[:r.buffer.Length()]); err != nil { // notice: buffer.Length() may be smaller than len(buffer)
|
|
r.stateErr = err
|
|
r.recycle()
|
|
return n, err // decryption failed
|
|
}
|
|
if len(payload) < len(p) {
|
|
r.offset = copy(p, payload)
|
|
} else {
|
|
r.offset = copy(p, payload[:len(p)])
|
|
}
|
|
n += r.offset
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
func (r *decReaderV10) readPackage(dst packageV10) error {
|
|
header := dst.Header()
|
|
_, err := io.ReadFull(r.src, header)
|
|
if err == io.ErrUnexpectedEOF {
|
|
return errInvalidPayloadSize // partial header
|
|
}
|
|
if err != nil {
|
|
return err // reading from src failed or reached EOF
|
|
}
|
|
|
|
_, err = io.ReadFull(r.src, dst.Ciphertext())
|
|
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
|
return errInvalidPayloadSize // reading less data than specified by header
|
|
}
|
|
if err != nil {
|
|
return err // reading from src failed or reached EOF
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type decReaderAtV10 struct {
|
|
src io.ReaderAt
|
|
|
|
ad authDecV10
|
|
}
|
|
|
|
// decryptReaderAtV10 returns an io.ReaderAt wrapping the given io.ReaderAt.
|
|
// The returned io.ReaderAt decrypts everything it reads using DARE 1.0.
|
|
func decryptReaderAtV10(src io.ReaderAt, config *Config) (*decReaderAtV10, error) {
|
|
ad, err := newAuthDecV10(config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
r := &decReaderAtV10{
|
|
ad: ad,
|
|
src: src,
|
|
}
|
|
|
|
return r, nil
|
|
}
|
|
|
|
func (r *decReaderAtV10) ReadAt(p []byte, offset int64) (n int, err error) {
|
|
if offset < 0 {
|
|
return 0, errors.New("sio: DecReaderAt.ReadAt: offset is negative")
|
|
}
|
|
|
|
t := offset / int64(maxPayloadSize)
|
|
if t+1 > (1<<32)-1 {
|
|
return 0, errUnexpectedSize
|
|
}
|
|
|
|
buffer := packageBufferPool.Get().([]byte)[:maxPackageSize]
|
|
defer recyclePackageBufferPool(buffer)
|
|
decReader := decReaderV10{
|
|
authDecV10: r.ad,
|
|
src: §ionReader{r.src, t * maxPackageSize},
|
|
buffer: packageV10(buffer),
|
|
offset: 0,
|
|
}
|
|
decReader.SeqNum = uint32(t)
|
|
if k := offset % int64(maxPayloadSize); k > 0 {
|
|
if _, err := io.CopyN(io.Discard, &decReader, k); err != nil {
|
|
return 0, err
|
|
}
|
|
}
|
|
|
|
for n < len(p) && err == nil {
|
|
var nn int
|
|
nn, err = (&decReader).Read(p[n:])
|
|
n += nn
|
|
}
|
|
if err == io.EOF && n == len(p) {
|
|
err = nil
|
|
}
|
|
return n, err
|
|
}
|