certificates/acme/db/nosql/nonce.go

71 lines
1.5 KiB
Go
Raw Normal View History

2021-02-25 18:24:24 +00:00
package nosql
import (
2021-03-01 06:49:20 +00:00
"context"
2021-02-25 18:24:24 +00:00
"encoding/base64"
"encoding/json"
"time"
"github.com/pkg/errors"
2021-03-01 06:49:20 +00:00
"github.com/smallstep/certificates/acme"
2021-02-25 18:24:24 +00:00
nosqlDB "github.com/smallstep/nosql"
"github.com/smallstep/nosql/database"
)
// dbNonce contains nonce metadata used in the ACME protocol.
type dbNonce struct {
ID string
Created time.Time
}
// CreateNonce creates, stores, and returns an ACME replay-nonce.
// Implements the acme.DB interface.
2021-03-01 06:49:20 +00:00
func (db *DB) CreateNonce(ctx context.Context) (acme.Nonce, error) {
2021-02-25 18:24:24 +00:00
_id, err := randID()
if err != nil {
2021-03-01 06:49:20 +00:00
return "", err
2021-02-25 18:24:24 +00:00
}
id := base64.RawURLEncoding.EncodeToString([]byte(_id))
n := &dbNonce{
ID: id,
Created: clock.Now(),
}
b, err := json.Marshal(n)
if err != nil {
2021-03-01 06:49:20 +00:00
return "", errors.Wrap(err, "error marshaling nonce")
2021-02-25 18:24:24 +00:00
}
2021-02-28 01:05:37 +00:00
if err = db.save(ctx, id, b, nil, "nonce", nonceTable); err != nil {
return "", err
2021-02-25 18:24:24 +00:00
}
2021-03-01 06:49:20 +00:00
return acme.Nonce(id), nil
2021-02-25 18:24:24 +00:00
}
// 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(nonce string) 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 nosqlDB.IsErrNotFound(err):
2021-03-01 06:49:20 +00:00
return errors.New("not found")
2021-02-25 18:24:24 +00:00
case err != nil:
2021-03-01 06:49:20 +00:00
return errors.Wrapf(err, "error deleting nonce %s", nonce)
2021-02-25 18:24:24 +00:00
default:
return nil
}
}