File: nonce.go

package info (click to toggle)
golang-github-smallstep-certificates 0.20.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 23,144 kB
  • sloc: sh: 278; makefile: 170
file content (66 lines) | stat: -rw-r--r-- 1,547 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package nosql

import (
	"context"
	"encoding/base64"
	"time"

	"github.com/pkg/errors"
	"github.com/smallstep/certificates/acme"
	"github.com/smallstep/nosql"
	"github.com/smallstep/nosql/database"
)

// dbNonce contains nonce metadata used in the ACME protocol.
type dbNonce struct {
	ID        string
	CreatedAt time.Time
	DeletedAt time.Time
}

// CreateNonce creates, stores, and returns an ACME replay-nonce.
// Implements the acme.DB interface.
func (db *DB) CreateNonce(ctx context.Context) (acme.Nonce, error) {
	_id, err := randID()
	if err != nil {
		return "", err
	}

	id := base64.RawURLEncoding.EncodeToString([]byte(_id))
	n := &dbNonce{
		ID:        id,
		CreatedAt: clock.Now(),
	}
	if err := db.save(ctx, id, n, nil, "nonce", nonceTable); err != nil {
		return "", err
	}
	return acme.Nonce(id), nil
}

// DeleteNonce verifies that the nonce is valid (by checking if it exists),
// and if so, consumes the nonce resource by deleting it from the database.
func (db *DB) DeleteNonce(ctx context.Context, nonce acme.Nonce) error {
	err := db.db.Update(&database.Tx{
		Operations: []*database.TxEntry{
			{
				Bucket: nonceTable,
				Key:    []byte(nonce),
				Cmd:    database.Get,
			},
			{
				Bucket: nonceTable,
				Key:    []byte(nonce),
				Cmd:    database.Delete,
			},
		},
	})

	switch {
	case nosql.IsErrNotFound(err):
		return acme.NewError(acme.ErrorBadNonceType, "nonce %s not found", string(nonce))
	case err != nil:
		return errors.Wrapf(err, "error deleting nonce %s", string(nonce))
	default:
		return nil
	}
}