mirror of
https://github.com/kairos-io/kcrypt-challenger.git
synced 2025-08-13 12:15:57 +00:00
🌱 Small fixups
Signed-off-by: mudler <mudler@c3os.io>
This commit is contained in:
parent
2c8a589906
commit
83f529b53d
@ -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
|
||||||
|
@ -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"`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
package constants
|
package constants
|
||||||
|
|
||||||
const TPMSecret = "tpm"
|
const TPMSecret = "tpm"
|
||||||
|
const GeneratedByKey = "generated_by"
|
||||||
|
Loading…
Reference in New Issue
Block a user