ory-am/hydra

View on GitHub
persistence/sql/persister_nonce.go

Summary

Maintainability
A
0 mins
Test Coverage
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0

package sql

import (
    "context"
    "time"

    "github.com/ory/fosite"
    "github.com/ory/hydra/v2/x"
    "github.com/ory/x/errorsx"
    "github.com/ory/x/otelx"
)

// Set the aadAccessTokenPrefix to something unique to avoid ciphertext confusion with other usages of the AEAD cipher.
var aadAccessTokenPrefix = "vc-nonce-at:" // nolint:gosec

func (p *Persister) NewNonce(ctx context.Context, accessToken string, expiresIn time.Time) (res string, err error) {
    ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.NewNonce")
    defer otelx.End(span, &err)

    plaintext := x.IntToBytes(expiresIn.Unix())
    aad := []byte(aadAccessTokenPrefix + accessToken)

    return p.r.FlowCipher().Encrypt(ctx, plaintext, aad)
}

func (p *Persister) IsNonceValid(ctx context.Context, accessToken, nonce string) (err error) {
    ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.IsNonceValid")
    defer otelx.End(span, &err)

    aad := []byte(aadAccessTokenPrefix + accessToken)
    plaintext, err := p.r.FlowCipher().Decrypt(ctx, nonce, aad)
    if err != nil {
        return errorsx.WithStack(fosite.ErrInvalidRequest.WithHintf("The nonce is invalid."))
    }

    exp, err := x.BytesToInt(plaintext)
    if err != nil {
        return errorsx.WithStack(fosite.ErrInvalidRequest.WithHintf("The nonce is invalid.")) // should never happen
    }

    if exp < time.Now().Unix() {
        return errorsx.WithStack(fosite.ErrInvalidRequest.WithHintf("The nonce has expired."))
    }

    return nil
}