🌱 Small fixups

Signed-off-by: mudler <mudler@c3os.io>
This commit is contained in:
mudler 2023-01-19 14:24:33 +01:00
parent 2c8a589906
commit 83f529b53d
5 changed files with 48 additions and 36 deletions

View File

@ -15,7 +15,7 @@ import (
"github.com/mudler/yip/pkg/utils" "github.com/mudler/yip/pkg/utils"
) )
var partNotFound error = fmt.Errorf("pass for partition not found") var errPartNotFound error = fmt.Errorf("pass for partition not found")
func NewClient() (*Client, error) { func NewClient() (*Client, error) {
conf, err := unmarshalConfig() conf, err := unmarshalConfig()
@ -59,15 +59,15 @@ func (c *Client) Start() error {
func (c *Client) waitPass(p *block.Partition, attempts int) (pass string, err error) { func (c *Client) waitPass(p *block.Partition, attempts int) (pass string, err error) {
// IF we don't have any server configured, just do local // IF we don't have any server configured, just do local
if c.Config.Kcrypt.Server == "" { if c.Config.Kcrypt.Challenger.Server == "" {
return localPass(c.Config) return localPass(c.Config)
} }
challengeEndpoint := fmt.Sprintf("%s/getPass", c.Config.Kcrypt.Server) challengeEndpoint := fmt.Sprintf("%s/getPass", c.Config.Kcrypt.Challenger.Server)
postEndpoint := fmt.Sprintf("%s/postPass", c.Config.Kcrypt.Server) postEndpoint := fmt.Sprintf("%s/postPass", c.Config.Kcrypt.Challenger.Server)
// IF server doesn't have a pass for us, then we generate one and we set it // IF server doesn't have a pass for us, then we generate one and we set it
if _, _, err := getPass(challengeEndpoint, p); err == partNotFound { if _, _, err := getPass(challengeEndpoint, p); err == errPartNotFound {
rand := utils.RandomString(32) rand := utils.RandomString(32)
pass, err := tpm.EncodeBlob([]byte(rand)) pass, err := tpm.EncodeBlob([]byte(rand))
if err != nil { if err != nil {
@ -75,7 +75,8 @@ func (c *Client) waitPass(p *block.Partition, attempts int) (pass string, err er
} }
bpass := base64.RawURLEncoding.EncodeToString(pass) bpass := base64.RawURLEncoding.EncodeToString(pass)
opts := []tpm.Option{tpm.WithAdditionalHeader("label", p.Label), opts := []tpm.Option{
tpm.WithAdditionalHeader("label", p.Label),
tpm.WithAdditionalHeader("name", p.Name), tpm.WithAdditionalHeader("name", p.Name),
tpm.WithAdditionalHeader("uuid", p.UUID), tpm.WithAdditionalHeader("uuid", p.UUID),
} }
@ -83,7 +84,7 @@ func (c *Client) waitPass(p *block.Partition, attempts int) (pass string, err er
if err != nil { if err != nil {
return "", err return "", err
} }
err = conn.WriteJSON(map[string]string{"passphrase": bpass, "generated": constants.TPMSecret}) err = conn.WriteJSON(map[string]string{"passphrase": bpass, constants.GeneratedByKey: constants.TPMSecret})
if err != nil { if err != nil {
return rand, err return rand, err
} }
@ -92,17 +93,19 @@ func (c *Client) waitPass(p *block.Partition, attempts int) (pass string, err er
var generated bool var generated bool
pass, generated, err = getPass(challengeEndpoint, p) pass, generated, err = getPass(challengeEndpoint, p)
if generated { if generated {
// Decode what the challenger server gave us
blob, err := base64.RawURLEncoding.DecodeString(pass) blob, err := base64.RawURLEncoding.DecodeString(pass)
if err != nil { if err != nil {
return "", err return "", err
} }
// Decode and give it back
// Decrypt and return it to unseal the LUKS volume
opts := []tpm.TPMOption{} opts := []tpm.TPMOption{}
if c.Config.Kcrypt.CIndex != "" { if c.Config.Kcrypt.Challenger.CIndex != "" {
opts = append(opts, tpm.WithIndex(c.Config.Kcrypt.CIndex)) opts = append(opts, tpm.WithIndex(c.Config.Kcrypt.Challenger.CIndex))
} }
if c.Config.Kcrypt.TPMDevice != "" { if c.Config.Kcrypt.Challenger.TPMDevice != "" {
opts = append(opts, tpm.WithDevice(c.Config.Kcrypt.TPMDevice)) opts = append(opts, tpm.WithDevice(c.Config.Kcrypt.Challenger.TPMDevice))
} }
pass, err := tpm.DecodeBlob(blob, opts...) pass, err := tpm.DecodeBlob(blob, opts...)
return string(pass), err return string(pass), err
@ -111,7 +114,7 @@ func (c *Client) waitPass(p *block.Partition, attempts int) (pass string, err er
if pass != "" || err == nil { if pass != "" || err == nil {
return return
} }
if err == partNotFound { if err == errPartNotFound {
return return
} }
// Otherwise, we might have a generic network error and we retry // Otherwise, we might have a generic network error and we retry

View File

@ -11,10 +11,12 @@ type Client struct {
type Config struct { type Config struct {
Kcrypt struct { Kcrypt struct {
Server string `yaml:"challenger_server,omitempty"` Challenger struct {
NVIndex string `yaml:"nv_index,omitempty"` Server string `yaml:"challenger_server,omitempty"`
CIndex string `yaml:"c_index,omitempty"` NVIndex string `yaml:"nv_index,omitempty"`
TPMDevice string `yaml:"tpm_device,omitempty"` CIndex string `yaml:"c_index,omitempty"`
TPMDevice string `yaml:"tpm_device,omitempty"`
}
} }
} }

View File

@ -30,16 +30,16 @@ func getPass(server string, partition *block.Partition) (string, bool, error) {
if ok { if ok {
return fmt.Sprint(p), generated && gen == constants.TPMSecret, nil return fmt.Sprint(p), generated && gen == constants.TPMSecret, nil
} }
return "", false, partNotFound return "", false, errPartNotFound
} }
func genAndStore(k Config) (string, error) { func genAndStore(k Config) (string, error) {
opts := []tpm.TPMOption{} opts := []tpm.TPMOption{}
if k.Kcrypt.TPMDevice != "" { if k.Kcrypt.Challenger.TPMDevice != "" {
opts = append(opts, tpm.WithDevice(k.Kcrypt.TPMDevice)) opts = append(opts, tpm.WithDevice(k.Kcrypt.Challenger.TPMDevice))
} }
if k.Kcrypt.CIndex != "" { if k.Kcrypt.Challenger.CIndex != "" {
opts = append(opts, tpm.WithIndex(k.Kcrypt.CIndex)) opts = append(opts, tpm.WithIndex(k.Kcrypt.Challenger.CIndex))
} }
// Generate a new one, and return it to luks // Generate a new one, and return it to luks
@ -49,8 +49,8 @@ func genAndStore(k Config) (string, error) {
return "", err return "", err
} }
nvindex := "0x1500000" nvindex := "0x1500000"
if k.Kcrypt.NVIndex != "" { if k.Kcrypt.Challenger.NVIndex != "" {
nvindex = k.Kcrypt.NVIndex nvindex = k.Kcrypt.Challenger.NVIndex
} }
opts = append(opts, tpm.WithIndex(nvindex)) opts = append(opts, tpm.WithIndex(nvindex))
return rand, tpm.StoreBlob(blob, opts...) return rand, tpm.StoreBlob(blob, opts...)
@ -58,12 +58,12 @@ func genAndStore(k Config) (string, error) {
func localPass(k Config) (string, error) { func localPass(k Config) (string, error) {
index := "0x1500000" index := "0x1500000"
if k.Kcrypt.NVIndex != "" { if k.Kcrypt.Challenger.NVIndex != "" {
index = k.Kcrypt.NVIndex index = k.Kcrypt.Challenger.NVIndex
} }
opts := []tpm.TPMOption{tpm.WithIndex(index)} opts := []tpm.TPMOption{tpm.WithIndex(index)}
if k.Kcrypt.TPMDevice != "" { if k.Kcrypt.Challenger.TPMDevice != "" {
opts = append(opts, tpm.WithDevice(k.Kcrypt.TPMDevice)) opts = append(opts, tpm.WithDevice(k.Kcrypt.Challenger.TPMDevice))
} }
encodedPass, err := tpm.ReadBlob(opts...) encodedPass, err := tpm.ReadBlob(opts...)
if err != nil { if err != nil {
@ -73,11 +73,11 @@ func localPass(k Config) (string, error) {
// Decode and give it back // Decode and give it back
opts = []tpm.TPMOption{} opts = []tpm.TPMOption{}
if k.Kcrypt.CIndex != "" { if k.Kcrypt.Challenger.CIndex != "" {
opts = append(opts, tpm.WithIndex(k.Kcrypt.CIndex)) opts = append(opts, tpm.WithIndex(k.Kcrypt.Challenger.CIndex))
} }
if k.Kcrypt.TPMDevice != "" { if k.Kcrypt.Challenger.TPMDevice != "" {
opts = append(opts, tpm.WithDevice(k.Kcrypt.TPMDevice)) opts = append(opts, tpm.WithDevice(k.Kcrypt.Challenger.TPMDevice))
} }
pass, err := tpm.DecodeBlob(encodedPass, opts...) pass, err := tpm.DecodeBlob(encodedPass, opts...)
return string(pass), err return string(pass), err

View File

@ -9,6 +9,7 @@ import (
"time" "time"
keyserverv1alpha1 "github.com/kairos-io/kairos-challenger/api/v1alpha1" keyserverv1alpha1 "github.com/kairos-io/kairos-challenger/api/v1alpha1"
"github.com/kairos-io/kairos-challenger/pkg/constants"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/kairos-io/kairos-challenger/controllers" "github.com/kairos-io/kairos-challenger/controllers"
@ -152,8 +153,8 @@ func Start(ctx context.Context, kclient *kubernetes.Clientset, reconciler *contr
Namespace: namespace, Namespace: namespace,
}, },
Data: map[string][]byte{ Data: map[string][]byte{
secretPath: []byte(pass), secretPath: []byte(pass),
"generated": []byte(v["generated"]), constants.GeneratedByKey: []byte(v[constants.GeneratedByKey]),
}, },
Type: "Opaque", Type: "Opaque",
} }
@ -221,13 +222,18 @@ func Start(ctx context.Context, kclient *kubernetes.Clientset, reconciler *contr
secretPath = sealedVolumeData.SecretPath secretPath = sealedVolumeData.SecretPath
} }
// 1. The admin sets a specific cleartext password from Kube manager
// SealedVolume -> with a secret .
// 2. The admin just adds a SealedVolume associated with a TPM Hash ( you don't provide any passphrase )
// 3. There is no challenger server at all (offline mode)
//
secret, err := kclient.CoreV1().Secrets(namespace).Get(ctx, secretName, v1.GetOptions{}) secret, err := kclient.CoreV1().Secrets(namespace).Get(ctx, secretName, v1.GetOptions{})
if err == nil { if err == nil {
passphrase := secret.Data[secretPath] passphrase := secret.Data[secretPath]
gen, generated := secret.Data["generated"] gen, generated := secret.Data[constants.GeneratedByKey]
result := map[string]string{"passphrase": string(passphrase)} result := map[string]string{"passphrase": string(passphrase)}
if generated { if generated {
result["generated"] = string(gen) result[constants.GeneratedByKey] = string(gen)
} }
err = json.NewEncoder(writer).Encode(result) err = json.NewEncoder(writer).Encode(result)
if err != nil { if err != nil {

View File

@ -1,3 +1,4 @@
package constants package constants
const TPMSecret = "tpm" const TPMSecret = "tpm"
const GeneratedByKey = "generated_by"