mirror of
https://github.com/siderolabs/omni.git
synced 2025-08-09 02:56:59 +02:00
Omni is source-available under BUSL. Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com> Co-Authored-By: Artem Chernyshev <artem.chernyshev@talos-systems.com> Co-Authored-By: Utku Ozdemir <utku.ozdemir@siderolabs.com> Co-Authored-By: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com> Co-Authored-By: Philipp Sauter <philipp.sauter@siderolabs.com> Co-Authored-By: Noel Georgi <git@frezbo.dev> Co-Authored-By: evgeniybryzh <evgeniybryzh@gmail.com> Co-Authored-By: Tim Jones <tim.jones@siderolabs.com> Co-Authored-By: Andrew Rynhard <andrew@rynhard.io> Co-Authored-By: Spencer Smith <spencer.smith@talos-systems.com> Co-Authored-By: Christian Rolland <christian.rolland@siderolabs.com> Co-Authored-By: Gerard de Leeuw <gdeleeuw@leeuwit.nl> Co-Authored-By: Steve Francis <67986293+steverfrancis@users.noreply.github.com> Co-Authored-By: Volodymyr Mazurets <volodymyrmazureets@gmail.com>
73 lines
1.9 KiB
Go
73 lines
1.9 KiB
Go
// Copyright (c) 2024 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
|
|
}
|