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.
|
2021-03-06 21:06:43 +00:00
|
|
|
func (db *DB) DeleteNonce(ctx context.Context, nonce acme.Nonce) error {
|
2021-02-25 18:24:24 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|