feat: implement register Passkey user API v2 (#5873)

* command/crypto: DRY the code

- reuse the the algorithm switch to create a secret generator
- add a verifyCryptoCode function

* command: crypto code tests

* migrate webauthn package

* finish integration tests with webauthn mock client
This commit is contained in:
Tim Möhlmann
2023-05-24 13:22:00 +03:00
committed by GitHub
parent 6839a5c203
commit a301c40f9f
44 changed files with 2528 additions and 517 deletions

View File

@@ -10,6 +10,8 @@ import (
"github.com/zitadel/zitadel/internal/errors"
)
type cryptoCodeFunc func(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto) (*CryptoCodeWithExpiry, error)
type CryptoCodeWithExpiry struct {
Crypted *crypto.CryptoValue
Plain string
@@ -17,42 +19,50 @@ type CryptoCodeWithExpiry struct {
}
func newCryptoCodeWithExpiry(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto) (*CryptoCodeWithExpiry, error) {
config, err := secretGeneratorConfig(ctx, filter, typ)
gen, config, err := secretGenerator(ctx, filter, typ, alg)
if err != nil {
return nil, err
}
code := new(CryptoCodeWithExpiry)
switch a := alg.(type) {
case crypto.HashAlgorithm:
code.Crypted, code.Plain, err = crypto.NewCode(crypto.NewHashGenerator(*config, a))
case crypto.EncryptionAlgorithm:
code.Crypted, code.Plain, err = crypto.NewCode(crypto.NewEncryptionGenerator(*config, a))
default:
return nil, errors.ThrowInternal(nil, "COMMA-RreV6", "Errors.Internal")
}
crypted, plain, err := crypto.NewCode(gen)
if err != nil {
return nil, err
}
return &CryptoCodeWithExpiry{
Crypted: crypted,
Plain: plain,
Expiry: config.Expiry,
}, nil
}
code.Expiry = config.Expiry
return code, nil
func verifyCryptoCode(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto, creation time.Time, expiry time.Duration, crypted *crypto.CryptoValue, plain string) error {
gen, _, err := secretGenerator(ctx, filter, typ, alg)
if err != nil {
return err
}
return crypto.VerifyCode(creation, expiry, crypted, plain, gen)
}
func newCryptoCodeWithPlain(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto) (value *crypto.CryptoValue, plain string, err error) {
config, err := secretGeneratorConfig(ctx, filter, typ)
gen, _, err := secretGenerator(ctx, filter, typ, alg)
if err != nil {
return nil, "", err
}
return crypto.NewCode(gen)
}
func secretGenerator(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto) (crypto.Generator, *crypto.GeneratorConfig, error) {
config, err := secretGeneratorConfig(ctx, filter, typ)
if err != nil {
return nil, nil, err
}
switch a := alg.(type) {
case crypto.HashAlgorithm:
return crypto.NewCode(crypto.NewHashGenerator(*config, a))
return crypto.NewHashGenerator(*config, a), config, nil
case crypto.EncryptionAlgorithm:
return crypto.NewCode(crypto.NewEncryptionGenerator(*config, a))
return crypto.NewEncryptionGenerator(*config, a), config, nil
default:
return nil, nil, errors.ThrowInternalf(nil, "COMMA-RreV6", "Errors.Internal unsupported crypto algorithm type %T", a)
}
return nil, "", errors.ThrowInvalidArgument(nil, "V2-NGESt", "Errors.Internal")
}
func secretGeneratorConfig(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType) (*crypto.GeneratorConfig, error) {