2022-03-20 19:55:47 +00:00
|
|
|
package persistent
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"crypto/x509"
|
|
|
|
"encoding/binary"
|
|
|
|
"fmt"
|
|
|
|
|
2023-03-07 13:38:26 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/session/storage"
|
2022-03-20 19:55:47 +00:00
|
|
|
"go.etcd.io/bbolt"
|
|
|
|
)
|
|
|
|
|
2022-03-27 15:55:24 +00:00
|
|
|
const keyOffset = 8
|
2022-03-20 19:55:47 +00:00
|
|
|
|
2022-03-21 11:53:49 +00:00
|
|
|
func (s *TokenStore) packToken(exp uint64, key *ecdsa.PrivateKey) ([]byte, error) {
|
2022-03-20 19:55:47 +00:00
|
|
|
rawKey, err := x509.MarshalECPrivateKey(key)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("could not marshal private key: %w", err)
|
|
|
|
}
|
|
|
|
|
2022-03-21 11:53:49 +00:00
|
|
|
if s.gcm != nil {
|
|
|
|
rawKey, err = s.encrypt(rawKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("could not encrypt session key: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-27 15:55:24 +00:00
|
|
|
res := make([]byte, keyOffset, keyOffset+len(rawKey))
|
2022-03-20 19:55:47 +00:00
|
|
|
binary.LittleEndian.PutUint64(res, exp)
|
|
|
|
|
|
|
|
res = append(res, rawKey...)
|
|
|
|
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
2022-03-21 11:53:49 +00:00
|
|
|
func (s *TokenStore) unpackToken(raw []byte) (*storage.PrivateToken, error) {
|
|
|
|
var err error
|
|
|
|
|
|
|
|
epoch := epochFromToken(raw)
|
2022-03-27 15:55:24 +00:00
|
|
|
rawKey := raw[keyOffset:]
|
2022-03-21 11:53:49 +00:00
|
|
|
|
|
|
|
if s.gcm != nil {
|
|
|
|
rawKey, err = s.decrypt(rawKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("could not decrypt session key: %w", err)
|
|
|
|
}
|
|
|
|
}
|
2022-03-20 19:55:47 +00:00
|
|
|
|
2022-03-21 11:53:49 +00:00
|
|
|
key, err := x509.ParseECPrivateKey(rawKey)
|
2022-03-20 19:55:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("could not unmarshal private key: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return storage.NewPrivateToken(key, epoch), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func epochFromToken(rawToken []byte) uint64 {
|
|
|
|
return binary.LittleEndian.Uint64(rawToken)
|
|
|
|
}
|
|
|
|
|
|
|
|
func iterateNestedBuckets(b *bbolt.Bucket, fn func(b *bbolt.Bucket) error) error {
|
|
|
|
c := b.Cursor()
|
|
|
|
|
|
|
|
for k, v := c.First(); k != nil; k, v = c.Next() {
|
|
|
|
// nil value is a hallmark
|
|
|
|
// of the nested buckets
|
|
|
|
if v == nil {
|
|
|
|
err := fn(b.Bucket(k))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|