forked from TrueCloudLab/frostfs-s3-gw
Add encrypt/decrypt logic
This commit is contained in:
parent
fc0a329f0f
commit
05aedee59e
1 changed files with 82 additions and 22 deletions
|
@ -3,55 +3,115 @@ package layer
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
"crypto/sha256"
|
||||||
|
|
||||||
"github.com/klauspost/compress/zstd"
|
"github.com/klauspost/compress/zstd"
|
||||||
"github.com/nspcc-dev/neofs-api-go/service"
|
"github.com/nspcc-dev/neofs-api-go/service"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type KeyPair struct {
|
const (
|
||||||
|
GatewayKeySize = 2048
|
||||||
|
)
|
||||||
|
|
||||||
|
type keyPair struct {
|
||||||
PrivateKey *rsa.PrivateKey
|
PrivateKey *rsa.PrivateKey
|
||||||
PublicKey *rsa.PublicKey
|
PublicKey *rsa.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthCenter struct {
|
type AuthCenter struct {
|
||||||
gatewayKeys KeyPair
|
gatewayKeys keyPair
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthCenter() (*AuthCenter, error) {
|
func NewAuthCenter() (*AuthCenter, error) {
|
||||||
var kp KeyPair
|
var (
|
||||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
err error
|
||||||
|
privateKey *rsa.PrivateKey
|
||||||
|
)
|
||||||
|
privateKey, err = pullGatewayPrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to pull gateway private key from trusted enclave")
|
||||||
}
|
}
|
||||||
kp.PrivateKey = privateKey
|
if privateKey == nil {
|
||||||
kp.PublicKey = &privateKey.PublicKey
|
if privateKey, err = rsa.GenerateKey(rand.Reader, GatewayKeySize); err != nil {
|
||||||
ac := &AuthCenter{
|
return nil, errors.Wrap(err, "failed to generate gateway private key")
|
||||||
gatewayKeys: kp,
|
|
||||||
}
|
}
|
||||||
|
if err = pushGatewayPrivateKey(privateKey); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to push gateway private key to trusted enclave")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ac := &AuthCenter{gatewayKeys: keyPair{
|
||||||
|
PrivateKey: privateKey,
|
||||||
|
PublicKey: &privateKey.PublicKey,
|
||||||
|
}}
|
||||||
return ac, nil
|
return ac, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *AuthCenter) PackBearerToken(bt service.BearerToken) ([]byte, error) {
|
func (ac *AuthCenter) PackBearerToken(bearerToken *service.BearerTokenMsg) ([]byte, error) {
|
||||||
// TODO
|
data, err := bearerToken.Marshal()
|
||||||
panic("unimplemented method")
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to marshal bearer token")
|
||||||
|
}
|
||||||
|
encryptedKeyID, err := ac.encrypt(compress(data))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "")
|
||||||
|
}
|
||||||
|
return append(sha256Hash(data), encryptedKeyID...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *AuthCenter) UnpackBearerToken(packedCredentials []byte) (service.BearerToken, error) {
|
func (ac *AuthCenter) UnpackBearerToken(packedBearerToken []byte) (*service.BearerTokenMsg, error) {
|
||||||
zstdDecoder, _ := zstd.NewReader(nil)
|
compressedKeyID := packedBearerToken[32:]
|
||||||
// secretHash := packedCredentials[:32]
|
encryptedKeyID, err := decompress(compressedKeyID)
|
||||||
_ = packedCredentials[:32]
|
if err != nil {
|
||||||
compressedKeyID := packedCredentials[32:]
|
|
||||||
// Get an encrypted key.
|
|
||||||
var encryptedKeyID []byte
|
|
||||||
if _, err := zstdDecoder.DecodeAll(compressedKeyID, encryptedKeyID); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to decompress key ID")
|
return nil, errors.Wrap(err, "failed to decompress key ID")
|
||||||
}
|
}
|
||||||
// TODO: Decrypt the key ID.
|
keyID, err := ac.decrypt(encryptedKeyID)
|
||||||
var keyID []byte
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to decrypt key ID")
|
||||||
|
}
|
||||||
bearerToken := new(service.BearerTokenMsg)
|
bearerToken := new(service.BearerTokenMsg)
|
||||||
if err := bearerToken.Unmarshal(keyID); err != nil {
|
if err := bearerToken.Unmarshal(keyID); err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal embedded bearer token")
|
return nil, errors.Wrap(err, "failed to unmarshal embedded bearer token")
|
||||||
}
|
}
|
||||||
return bearerToken, nil
|
return bearerToken, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func pullGatewayPrivateKey() (*rsa.PrivateKey, error) {
|
||||||
|
// TODO: Pull the private key from a persistent and trusted enclave.
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func pushGatewayPrivateKey(key *rsa.PrivateKey) error {
|
||||||
|
// TODO: Push the private key to a persistent and trusted enclave.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ac *AuthCenter) encrypt(data []byte) ([]byte, error) {
|
||||||
|
return rsa.EncryptOAEP(sha256.New(), rand.Reader, ac.gatewayKeys.PublicKey, data, []byte{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ac *AuthCenter) decrypt(data []byte) ([]byte, error) {
|
||||||
|
return rsa.DecryptOAEP(sha256.New(), rand.Reader, ac.gatewayKeys.PrivateKey, data, []byte{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func compress(data []byte) []byte {
|
||||||
|
var compressedData []byte
|
||||||
|
zstdEncoder, _ := zstd.NewWriter(nil)
|
||||||
|
zstdEncoder.EncodeAll(data, compressedData)
|
||||||
|
return compressedData
|
||||||
|
}
|
||||||
|
|
||||||
|
func decompress(data []byte) ([]byte, error) {
|
||||||
|
var decompressedData []byte
|
||||||
|
zstdDecoder, _ := zstd.NewReader(nil)
|
||||||
|
if _, err := zstdDecoder.DecodeAll(data, decompressedData); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return decompressedData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func sha256Hash(data []byte) []byte {
|
||||||
|
hash := sha256.New()
|
||||||
|
hash.Write(data)
|
||||||
|
return hash.Sum(nil)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue