omni/internal/backend/grpc/validate.go
Artem Chernyshev ed946b30a6
feat: display OMNI_ENDPOINT in the service account creation UI
Fixes: https://github.com/siderolabs/omni/issues/858

Signed-off-by: Artem Chernyshev <artem.chernyshev@talos-systems.com>
2025-01-29 15:27:36 +03:00

73 lines
1.9 KiB
Go

// Copyright (c) 2025 Sidero Labs, Inc.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
package grpc
import (
"errors"
"time"
pgpcrypto "github.com/ProtonMail/gopenpgp/v2/crypto"
authpb "github.com/siderolabs/go-api-signature/api/auth"
"github.com/siderolabs/go-api-signature/pkg/pgp"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
type publicKey struct {
expiration time.Time
id string
username string
data []byte
}
// validatePublicKey validates the public key in the request and returns a publicKey.
func validatePublicKey(keypb *authpb.PublicKey, opts ...pgp.ValidationOption) (publicKey, error) {
if keypb.GetPgpData() == nil && keypb.GetWebauthnData() == nil {
return publicKey{}, errors.New("no public key data provided")
}
if keypb.GetWebauthnData() != nil {
return publicKey{}, status.Error(codes.Unimplemented, "unimplemented") // todo: implement webauthn
}
return validatePGPPublicKey(keypb.GetPgpData(), opts...)
}
func validatePGPPublicKey(armored []byte, opts ...pgp.ValidationOption) (publicKey, error) {
pgpKey, err := pgpcrypto.NewKeyFromArmored(string(armored))
if err != nil {
return publicKey{}, err
}
key, err := pgp.NewKey(pgpKey)
if err != nil {
return publicKey{}, err
}
err = key.Validate(opts...)
if err != nil {
return publicKey{}, err
}
if key.IsPrivate() {
return publicKey{}, errors.New("PGP key contains private key")
}
lifetimeSecs := pgpKey.GetEntity().PrimaryIdentity().SelfSignature.KeyLifetimeSecs
if lifetimeSecs == nil {
return publicKey{}, errors.New("PGP key has no expiration")
}
expiration := pgpKey.GetEntity().PrimaryKey.CreationTime.Add(time.Duration(*lifetimeSecs) * time.Second)
return publicKey{
data: armored,
id: pgpKey.GetFingerprint(),
username: pgpKey.GetEntity().PrimaryIdentity().UserId.Name,
expiration: expiration,
}, nil
}