From 4fc7eaed34e37e7f16f9b58f284ad4372e1d85f3 Mon Sep 17 00:00:00 2001 From: Pavel Korotkov Date: Wed, 15 Jul 2020 18:20:45 +0300 Subject: [PATCH] Remove global state --- auth/center.go | 45 ++++++++++++++------------- auth/enclave.go | 82 +++++++++++++++++++------------------------------ 2 files changed, 55 insertions(+), 72 deletions(-) diff --git a/auth/center.go b/auth/center.go index dc556ce..966177c 100644 --- a/auth/center.go +++ b/auth/center.go @@ -8,45 +8,48 @@ import ( "github.com/pkg/errors" ) -var _debug = false - -func SetDebug() { - _debug = true -} - // Center is a central app's authentication/authorization management unit. type Center struct { + enclave *secureEnclave zstdEncoder *zstd.Encoder zstdDecoder *zstd.Decoder } -// NewAuthCenter creates an instance of AuthCenter. -func NewCenter() (*Center, error) { +// NewCenter creates an instance of AuthCenter. +func NewCenter(pathToRSAKey, pathToECDSAKey string) (*Center, error) { zstdEncoder, _ := zstd.NewWriter(nil) zstdDecoder, _ := zstd.NewReader(nil) - ac := &Center{zstdEncoder: zstdEncoder, zstdDecoder: zstdDecoder} - return ac, nil + enclave, err := newSecureEnclave(pathToRSAKey, pathToECDSAKey) + if err != nil { + return nil, errors.Wrap(err, "failed to create secure enclave") + } + center := &Center{ + enclave: enclave, + zstdEncoder: zstdEncoder, + zstdDecoder: zstdDecoder, + } + return center, nil } -func (ac *Center) PackBearerToken(bearerToken *service.BearerTokenMsg) ([]byte, error) { +func (center *Center) PackBearerToken(bearerToken *service.BearerTokenMsg) ([]byte, error) { data, err := bearerToken.Marshal() if err != nil { return nil, errors.Wrap(err, "failed to marshal bearer token") } - encryptedKeyID, err := globalEnclave.Encrypt(gateUserAuthKey, ac.compress(data)) + encryptedKeyID, err := center.enclave.Encrypt(gateUserAuthKey, center.compress(data)) if err != nil { return nil, errors.Wrap(err, "") } return append(sha256Hash(data), encryptedKeyID...), nil } -func (ac *Center) UnpackBearerToken(packedBearerToken []byte) (*service.BearerTokenMsg, error) { +func (center *Center) UnpackBearerToken(packedBearerToken []byte) (*service.BearerTokenMsg, error) { compressedKeyID := packedBearerToken[32:] - encryptedKeyID, err := ac.decompress(compressedKeyID) + encryptedKeyID, err := center.decompress(compressedKeyID) if err != nil { return nil, errors.Wrap(err, "failed to decompress key ID") } - keyID, err := globalEnclave.Decrypt(gateUserAuthKey, encryptedKeyID) + keyID, err := center.enclave.Decrypt(gateUserAuthKey, encryptedKeyID) if err != nil { return nil, errors.Wrap(err, "failed to decrypt key ID") } @@ -57,17 +60,17 @@ func (ac *Center) UnpackBearerToken(packedBearerToken []byte) (*service.BearerTo return bearerToken, nil } -func (ac *Center) compress(data []byte) []byte { - ac.zstdEncoder.Reset(nil) +func (center *Center) compress(data []byte) []byte { + center.zstdEncoder.Reset(nil) var compressedData []byte - ac.zstdEncoder.EncodeAll(data, compressedData) + center.zstdEncoder.EncodeAll(data, compressedData) return compressedData } -func (ac *Center) decompress(data []byte) ([]byte, error) { - ac.zstdDecoder.Reset(nil) +func (center *Center) decompress(data []byte) ([]byte, error) { + center.zstdDecoder.Reset(nil) var decompressedData []byte - if _, err := ac.zstdDecoder.DecodeAll(data, decompressedData); err != nil { + if _, err := center.zstdDecoder.DecodeAll(data, decompressedData); err != nil { return nil, err } return decompressedData, nil diff --git a/auth/enclave.go b/auth/enclave.go index 851e89c..1033ed0 100644 --- a/auth/enclave.go +++ b/auth/enclave.go @@ -10,19 +10,18 @@ import ( "encoding/pem" "io/ioutil" "os" - "path/filepath" "github.com/pkg/errors" ) -const ( - // PathToUserAuthPrivateKeyFile is a linux-specific predefined path - // to a persisted RSA private key for authenticating at S3 server. - PathToUserAuthPrivateKeyFile = "/etc/neofs/1.pem" - // PathToNeoFSECDSAPrivateKeyFile is a linux-specific predefined path - // to a persisted ECDSA private key for accessing NeoFS network. - PathToNeoFSECDSAPrivateKeyFile = "/etc/neofs/2.pem" -) +// const ( +// // PathToUserAuthPrivateKeyFile is a linux-specific predefined path +// // to a persisted RSA private key for authenticating at S3 server. +// PathToUserAuthPrivateKeyFile = "/etc/neofs/1.pem" +// // PathToNeoFSECDSAPrivateKeyFile is a linux-specific predefined path +// // to a persisted ECDSA private key for accessing NeoFS network. +// PathToNeoFSECDSAPrivateKeyFile = "/etc/neofs/2.pem" +// ) const ( gatewayEncryptionKeySize = 4096 @@ -60,92 +59,73 @@ type ( } ) -var globalEnclave *secureEnclave - -func init() { - var err error - globalEnclave, err = newSecureEnclave() - if err != nil { - panic("failed to initialize secure enclave") - } -} - type secureEnclave struct { signatureKeys map[signatureKeyName]signatureKeyPair encryptionKeys map[encryptionKeyName]encryptionKeyPair } -func newSecureEnclave() (*secureEnclave, error) { +func newSecureEnclave(pathToRSAKey, pathToECDSAKey string) (*secureEnclave, error) { var ( - pathToKey1, pathToKey2 string - key1 *rsa.PrivateKey - key2 *ecdsa.PrivateKey + rsaKey *rsa.PrivateKey + ecdsaKey *ecdsa.PrivateKey ) - // FIXME: Get private keys properly. - if _debug { - ep, _ := os.Executable() - base := filepath.Dir(ep) - pathToKey1, pathToKey2 = filepath.Join(base, "1.pem"), filepath.Join(base, "2.pem") - } else { - pathToKey1, pathToKey2 = PathToUserAuthPrivateKeyFile, PathToNeoFSECDSAPrivateKeyFile - } - if key1bs, err := ioutil.ReadFile(pathToKey1); err != nil { + if key1bs, err := ioutil.ReadFile(pathToRSAKey); err != nil { // No file found. if os.IsNotExist(err) { - if key1, err = rsa.GenerateKey(rand.Reader, gatewayEncryptionKeySize); err != nil { + if rsaKey, err = rsa.GenerateKey(rand.Reader, gatewayEncryptionKeySize); err != nil { return nil, errors.Wrap(err, "failed to generate RSA key") } - key1bs := x509.MarshalPKCS1PrivateKey(key1) + key1bs := x509.MarshalPKCS1PrivateKey(rsaKey) data := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: key1bs}) - if err := ioutil.WriteFile(pathToKey1, data, 0o600); err != nil { - return nil, errors.Wrapf(err, "failed to write file %s", pathToKey1) + if err := ioutil.WriteFile(pathToRSAKey, data, 0o600); err != nil { + return nil, errors.Wrapf(err, "failed to write file %s", pathToRSAKey) } } else { - return nil, errors.Wrapf(err, "failed to open file %s", pathToKey1) + return nil, errors.Wrapf(err, "failed to open file %s", pathToRSAKey) } } else { pemBlock, _ := pem.Decode(key1bs) if pemBlock == nil { - return nil, errors.Errorf("failed to decode PEM data from file %s", pathToKey1) + return nil, errors.Errorf("failed to decode PEM data from file %s", pathToRSAKey) } - key1, err = x509.ParsePKCS1PrivateKey(pemBlock.Bytes) + rsaKey, err = x509.ParsePKCS1PrivateKey(pemBlock.Bytes) if err != nil { - return nil, errors.Wrapf(err, "failed to parse private key bytes from pem data from file %s", pathToKey1) + return nil, errors.Wrapf(err, "failed to parse private key bytes from pem data from file %s", pathToRSAKey) } } - if key2bs, err := ioutil.ReadFile(pathToKey2); err != nil { + if key2bs, err := ioutil.ReadFile(pathToECDSAKey); err != nil { // No file found. if os.IsNotExist(err) { - if key2, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil { + if ecdsaKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil { return nil, errors.Wrap(err, "failed to generate ECDSA key") } - key2bs, err := x509.MarshalECPrivateKey(key2) + key2bs, err := x509.MarshalECPrivateKey(ecdsaKey) if err != nil { return nil, errors.New("failed to marshal ECDSA private key") } data := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: key2bs}) - if err := ioutil.WriteFile(pathToKey2, data, 0o600); err != nil { - return nil, errors.Wrapf(err, "failed to write file %s", pathToKey2) + if err := ioutil.WriteFile(pathToECDSAKey, data, 0o600); err != nil { + return nil, errors.Wrapf(err, "failed to write file %s", pathToECDSAKey) } } else { - return nil, errors.Wrapf(err, "failed to open file %s", pathToKey2) + return nil, errors.Wrapf(err, "failed to open file %s", pathToECDSAKey) } } else { pemBlock, _ := pem.Decode(key2bs) if pemBlock == nil { - return nil, errors.Errorf("failed to decode PEM data from file %s", pathToKey2) + return nil, errors.Errorf("failed to decode PEM data from file %s", pathToECDSAKey) } - key2, err = x509.ParseECPrivateKey(pemBlock.Bytes) + ecdsaKey, err = x509.ParseECPrivateKey(pemBlock.Bytes) if err != nil { - return nil, errors.Wrapf(err, "failed to parse private key bytes from pem data from file %s", pathToKey2) + return nil, errors.Wrapf(err, "failed to parse private key bytes from pem data from file %s", pathToECDSAKey) } } return &secureEnclave{ encryptionKeys: map[encryptionKeyName]encryptionKeyPair{ - gateUserAuthKey: {key1, &key1.PublicKey}, + gateUserAuthKey: {rsaKey, &rsaKey.PublicKey}, }, signatureKeys: map[signatureKeyName]signatureKeyPair{ - gateNeoFSECDSAKey: {key2, &key2.PublicKey}, + gateNeoFSECDSAKey: {ecdsaKey, &ecdsaKey.PublicKey}, }, }, nil }