Port envd from e2b with internalized shared packages and Connect RPC
- Copy envd source from e2b-dev/infra, internalize shared dependencies
into envd/internal/shared/ (keys, filesystem, id, smap, utils)
- Switch from gRPC to Connect RPC for all envd services
- Update module paths to git.omukk.dev/wrenn/{sandbox,sandbox/envd}
- Add proto specs (process, filesystem) with buf-based code generation
- Implement full envd: process exec, filesystem ops, port forwarding,
cgroup management, MMDS integration, and HTTP API
- Update main module dependencies (firecracker SDK, pgx, goose, etc.)
- Remove placeholder .gitkeep files replaced by real implementations
This commit is contained in:
99
envd/internal/shared/keys/key.go
Normal file
99
envd/internal/shared/keys/key.go
Normal file
@ -0,0 +1,99 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
identifierValueSuffixLength = 4
|
||||
identifierValuePrefixLength = 2
|
||||
|
||||
keyLength = 20
|
||||
)
|
||||
|
||||
var hasher Hasher = NewSHA256Hashing()
|
||||
|
||||
type Key struct {
|
||||
PrefixedRawValue string
|
||||
HashedValue string
|
||||
Masked MaskedIdentifier
|
||||
}
|
||||
|
||||
type MaskedIdentifier struct {
|
||||
Prefix string
|
||||
ValueLength int
|
||||
MaskedValuePrefix string
|
||||
MaskedValueSuffix string
|
||||
}
|
||||
|
||||
// MaskKey returns identifier masking properties in accordance to the OpenAPI response spec
|
||||
func MaskKey(prefix, value string) (MaskedIdentifier, error) {
|
||||
valueLength := len(value)
|
||||
|
||||
suffixOffset := valueLength - identifierValueSuffixLength
|
||||
prefixOffset := identifierValuePrefixLength
|
||||
|
||||
if suffixOffset < 0 {
|
||||
return MaskedIdentifier{}, fmt.Errorf("mask value length is less than identifier suffix length (%d)", identifierValueSuffixLength)
|
||||
}
|
||||
|
||||
if suffixOffset == 0 {
|
||||
return MaskedIdentifier{}, fmt.Errorf("mask value length is equal to identifier suffix length (%d), which would expose the entire identifier in the mask", identifierValueSuffixLength)
|
||||
}
|
||||
|
||||
// cap prefixOffset by suffixOffset to prevent overlap with the suffix.
|
||||
if prefixOffset > suffixOffset {
|
||||
prefixOffset = suffixOffset
|
||||
}
|
||||
|
||||
maskPrefix := value[:prefixOffset]
|
||||
maskSuffix := value[suffixOffset:]
|
||||
|
||||
maskedIdentifierProperties := MaskedIdentifier{
|
||||
Prefix: prefix,
|
||||
ValueLength: valueLength,
|
||||
MaskedValuePrefix: maskPrefix,
|
||||
MaskedValueSuffix: maskSuffix,
|
||||
}
|
||||
|
||||
return maskedIdentifierProperties, nil
|
||||
}
|
||||
|
||||
func GenerateKey(prefix string) (Key, error) {
|
||||
keyBytes := make([]byte, keyLength)
|
||||
|
||||
_, err := rand.Read(keyBytes)
|
||||
if err != nil {
|
||||
return Key{}, err
|
||||
}
|
||||
|
||||
generatedIdentifier := hex.EncodeToString(keyBytes)
|
||||
|
||||
mask, err := MaskKey(prefix, generatedIdentifier)
|
||||
if err != nil {
|
||||
return Key{}, err
|
||||
}
|
||||
|
||||
return Key{
|
||||
PrefixedRawValue: prefix + generatedIdentifier,
|
||||
HashedValue: hasher.Hash(keyBytes),
|
||||
Masked: mask,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func VerifyKey(prefix string, key string) (string, error) {
|
||||
if !strings.HasPrefix(key, prefix) {
|
||||
return "", fmt.Errorf("invalid key prefix")
|
||||
}
|
||||
|
||||
keyValue := key[len(prefix):]
|
||||
keyBytes, err := hex.DecodeString(keyValue)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid key")
|
||||
}
|
||||
|
||||
return hasher.Hash(keyBytes), nil
|
||||
}
|
||||
Reference in New Issue
Block a user