Add a blocked keys table, and use it (#4773)
Fixes #4712 and fixes #4711.
This commit is contained in:
parent
5254844ba2
commit
9df97cbf06
1
ca/ca.go
1
ca/ca.go
|
|
@ -669,6 +669,7 @@ func (ca *CertificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
|
|||
}
|
||||
|
||||
if err := csrlib.VerifyCSR(
|
||||
ctx,
|
||||
csr,
|
||||
ca.maxNames,
|
||||
&ca.keyPolicy,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import (
|
|||
pkcs11key "github.com/letsencrypt/pkcs11key/v4"
|
||||
|
||||
"github.com/letsencrypt/boulder/ca"
|
||||
"github.com/letsencrypt/boulder/ca/config"
|
||||
ca_config "github.com/letsencrypt/boulder/ca/config"
|
||||
caPB "github.com/letsencrypt/boulder/ca/proto"
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
|
|
@ -155,9 +155,6 @@ func main() {
|
|||
issuers, err := loadIssuers(c)
|
||||
cmd.FailOnError(err, "Couldn't load issuers")
|
||||
|
||||
kp, err := goodkey.NewKeyPolicy(c.CA.WeakKeyFile, c.CA.BlockedKeyFile)
|
||||
cmd.FailOnError(err, "Unable to create key policy")
|
||||
|
||||
tlsConfig, err := c.CA.TLS.Load()
|
||||
cmd.FailOnError(err, "TLS config")
|
||||
|
||||
|
|
@ -168,6 +165,13 @@ func main() {
|
|||
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
|
||||
sa := bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(conn))
|
||||
|
||||
var blockedKeyFunc goodkey.BlockedKeyCheckFunc
|
||||
if features.Enabled(features.BlockedKeyTable) {
|
||||
blockedKeyFunc = sa.KeyBlocked
|
||||
}
|
||||
kp, err := goodkey.NewKeyPolicy(c.CA.WeakKeyFile, c.CA.BlockedKeyFile, blockedKeyFunc)
|
||||
cmd.FailOnError(err, "Unable to create key policy")
|
||||
|
||||
var orphanQueue *goque.Queue
|
||||
if c.CA.OrphanQueueDir != "" {
|
||||
orphanQueue, err = goque.OpenQueue(c.CA.OrphanQueueDir)
|
||||
|
|
|
|||
|
|
@ -204,7 +204,11 @@ func main() {
|
|||
pendingAuthorizationLifetime = time.Duration(c.RA.PendingAuthorizationLifetimeDays) * 24 * time.Hour
|
||||
}
|
||||
|
||||
kp, err := goodkey.NewKeyPolicy(c.RA.WeakKeyFile, c.RA.BlockedKeyFile)
|
||||
var blockedKeyFunc goodkey.BlockedKeyCheckFunc
|
||||
if features.Enabled(features.BlockedKeyTable) {
|
||||
blockedKeyFunc = sac.KeyBlocked
|
||||
}
|
||||
kp, err := goodkey.NewKeyPolicy(c.RA.WeakKeyFile, c.RA.BlockedKeyFile, blockedKeyFunc)
|
||||
cmd.FailOnError(err, "Unable to create key policy")
|
||||
|
||||
if c.RA.MaxNames == 0 {
|
||||
|
|
|
|||
|
|
@ -123,10 +123,14 @@ func main() {
|
|||
|
||||
clk := cmd.Clock()
|
||||
|
||||
// don't load any weak keys, but do load blocked keys
|
||||
kp, err := goodkey.NewKeyPolicy("", c.WFE.BlockedKeyFile)
|
||||
cmd.FailOnError(err, "Unable to create key policy")
|
||||
rac, sac, rns, npm := setupWFE(c, logger, stats, clk)
|
||||
var blockedKeyFunc goodkey.BlockedKeyCheckFunc
|
||||
if features.Enabled(features.BlockedKeyTable) {
|
||||
blockedKeyFunc = sac.KeyBlocked
|
||||
}
|
||||
// don't load any weak keys, but do load blocked keys
|
||||
kp, err := goodkey.NewKeyPolicy("", c.WFE.BlockedKeyFile, blockedKeyFunc)
|
||||
cmd.FailOnError(err, "Unable to create key policy")
|
||||
wfe, err := wfe.NewWebFrontEndImpl(stats, clk, kp, rns, npm, logger)
|
||||
cmd.FailOnError(err, "Unable to create WFE")
|
||||
wfe.RA = rac
|
||||
|
|
|
|||
|
|
@ -298,10 +298,14 @@ func main() {
|
|||
|
||||
clk := cmd.Clock()
|
||||
|
||||
// don't load any weak keys, but do load blocked keys
|
||||
kp, err := goodkey.NewKeyPolicy("", c.WFE.BlockedKeyFile)
|
||||
cmd.FailOnError(err, "Unable to create key policy")
|
||||
rac, sac, rns, npm := setupWFE(c, logger, stats, clk)
|
||||
var blockedKeyFunc goodkey.BlockedKeyCheckFunc
|
||||
if features.Enabled(features.BlockedKeyTable) {
|
||||
blockedKeyFunc = sac.KeyBlocked
|
||||
}
|
||||
// don't load any weak keys, but do load blocked keys
|
||||
kp, err := goodkey.NewKeyPolicy("", c.WFE.BlockedKeyFile, blockedKeyFunc)
|
||||
cmd.FailOnError(err, "Unable to create key policy")
|
||||
|
||||
if c.WFE.StaleTimeout.Duration == 0 {
|
||||
c.WFE.StaleTimeout.Duration = time.Minute * 10
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ type StorageGetter interface {
|
|||
CountInvalidAuthorizations2(ctx context.Context, req *sapb.CountInvalidAuthorizationsRequest) (*sapb.Count, error)
|
||||
GetValidAuthorizations2(ctx context.Context, req *sapb.GetValidAuthorizationsRequest) (*sapb.Authorizations, error)
|
||||
SerialExists(ctx context.Context, req *sapb.Serial) (*sapb.Exists, error)
|
||||
KeyBlocked(ctx context.Context, req *sapb.KeyBlockedRequest) (*sapb.Exists, error)
|
||||
}
|
||||
|
||||
// StorageAdder are the Boulder SA's write/update methods
|
||||
|
|
@ -155,6 +156,7 @@ type StorageAdder interface {
|
|||
NewAuthorizations2(ctx context.Context, req *sapb.AddPendingAuthorizationsRequest) (*sapb.Authorization2IDs, error)
|
||||
FinalizeAuthorization2(ctx context.Context, req *sapb.FinalizeAuthorizationRequest) error
|
||||
DeactivateAuthorization2(ctx context.Context, req *sapb.AuthorizationID2) (*corepb.Empty, error)
|
||||
AddBlockedKey(ctx context.Context, req *sapb.AddBlockedKeyRequest) (*corepb.Empty, error)
|
||||
}
|
||||
|
||||
// StorageAuthority interface represents a simple key/value
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package csr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"strings"
|
||||
|
|
@ -44,13 +45,13 @@ var (
|
|||
// VerifyCSR checks the validity of a x509.CertificateRequest. Before doing checks it normalizes
|
||||
// the CSR which lowers the case of DNS names and subject CN, and if forceCNFromSAN is true it
|
||||
// will hoist a DNS name into the CN if it is empty.
|
||||
func VerifyCSR(csr *x509.CertificateRequest, maxNames int, keyPolicy *goodkey.KeyPolicy, pa core.PolicyAuthority, forceCNFromSAN bool, regID int64) error {
|
||||
func VerifyCSR(ctx context.Context, csr *x509.CertificateRequest, maxNames int, keyPolicy *goodkey.KeyPolicy, pa core.PolicyAuthority, forceCNFromSAN bool, regID int64) error {
|
||||
normalizeCSR(csr, forceCNFromSAN)
|
||||
key, ok := csr.PublicKey.(crypto.PublicKey)
|
||||
if !ok {
|
||||
return invalidPubKey
|
||||
}
|
||||
if err := keyPolicy.GoodKey(key); err != nil {
|
||||
if err := keyPolicy.GoodKey(ctx, key); err != nil {
|
||||
return berrors.BadPublicKeyError("invalid public key in CSR: %s", err)
|
||||
}
|
||||
if !goodSignatureAlgorithms[csr.SignatureAlgorithm] {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package csr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
|
|
@ -170,7 +171,7 @@ func TestVerifyCSR(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
err := VerifyCSR(c.csr, c.maxNames, c.keyPolicy, c.pa, true, c.regID)
|
||||
err := VerifyCSR(context.Background(), c.csr, c.maxNames, c.keyPolicy, c.pa, true, c.regID)
|
||||
test.AssertDeepEquals(t, c.expectedError, err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,11 +26,12 @@ func _() {
|
|||
_ = x[StripDefaultSchemePort-15]
|
||||
_ = x[StoreIssuerInfo-16]
|
||||
_ = x[StoreKeyHashes-17]
|
||||
_ = x[BlockedKeyTable-18]
|
||||
}
|
||||
|
||||
const _FeatureFlag_name = "unusedWriteIssuedNamesPrecertHeadNonceStatusOKRemoveWFE2AccountIDCheckRenewalFirstParallelCheckFailedValidationDeleteUnusedChallengesCAAValidationMethodsCAAAccountURIEnforceMultiVAMultiVAFullResultsMandatoryPOSTAsGETAllowV1RegistrationV1DisableNewValidationsPrecertificateRevocationStripDefaultSchemePortStoreIssuerInfoStoreKeyHashes"
|
||||
const _FeatureFlag_name = "unusedWriteIssuedNamesPrecertHeadNonceStatusOKRemoveWFE2AccountIDCheckRenewalFirstParallelCheckFailedValidationDeleteUnusedChallengesCAAValidationMethodsCAAAccountURIEnforceMultiVAMultiVAFullResultsMandatoryPOSTAsGETAllowV1RegistrationV1DisableNewValidationsPrecertificateRevocationStripDefaultSchemePortStoreIssuerInfoStoreKeyHashesBlockedKeyTable"
|
||||
|
||||
var _FeatureFlag_index = [...]uint16{0, 6, 29, 46, 65, 82, 111, 133, 153, 166, 180, 198, 216, 235, 258, 282, 304, 319, 333}
|
||||
var _FeatureFlag_index = [...]uint16{0, 6, 29, 46, 65, 82, 111, 133, 153, 166, 180, 198, 216, 235, 258, 282, 304, 319, 333, 348}
|
||||
|
||||
func (i FeatureFlag) String() string {
|
||||
if i < 0 || i >= FeatureFlag(len(_FeatureFlag_index)-1) {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ const (
|
|||
StoreIssuerInfo
|
||||
// StoreKeyHashes enables storage of SPKI hashes associated with certificates.
|
||||
StoreKeyHashes
|
||||
// BlockedKeyTable enables storage, and checking, of the blockedKeys table in addition
|
||||
// to the blocked key list
|
||||
BlockedKeyTable
|
||||
)
|
||||
|
||||
// List of features and their default value, protected by fMu
|
||||
|
|
@ -71,6 +74,7 @@ var features = map[FeatureFlag]bool{
|
|||
StoreIssuerInfo: false,
|
||||
WriteIssuedNamesPrecert: false,
|
||||
StoreKeyHashes: false,
|
||||
BlockedKeyTable: false,
|
||||
}
|
||||
|
||||
var fMu = new(sync.RWMutex)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package goodkey
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
|
@ -85,7 +86,7 @@ func TestBlockedKeys(t *testing.T) {
|
|||
|
||||
// All of the test keys should not be considered blocked
|
||||
for _, k := range blockedKeys {
|
||||
err := testingPolicy.GoodKey(k)
|
||||
err := testingPolicy.GoodKey(context.Background(), k)
|
||||
test.AssertNotError(t, err, "test key was blocked by key policy without block list")
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +96,7 @@ func TestBlockedKeys(t *testing.T) {
|
|||
// Now all of the test keys should be considered blocked, and with the correct
|
||||
// type of error.
|
||||
for _, k := range blockedKeys {
|
||||
err := testingPolicy.GoodKey(k)
|
||||
err := testingPolicy.GoodKey(context.Background(), k)
|
||||
test.AssertError(t, err, "test key was not blocked by key policy with block list")
|
||||
test.Assert(t, berrors.Is(err, berrors.BadPublicKey), "err was not BadPublicKey error")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package goodkey
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
|
|
@ -8,7 +9,10 @@ import (
|
|||
"math/big"
|
||||
"sync"
|
||||
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
berrors "github.com/letsencrypt/boulder/errors"
|
||||
sapb "github.com/letsencrypt/boulder/sa/proto"
|
||||
|
||||
"github.com/titanous/rocacheck"
|
||||
)
|
||||
|
||||
|
|
@ -34,6 +38,11 @@ var (
|
|||
smallPrimes []*big.Int
|
||||
)
|
||||
|
||||
// BlockedKeyCheckFunc is used to pass in the sa.BlockedKey method to KeyPolicy,
|
||||
// rather than storing a full sa.SQLStorageAuthority. This makes testing
|
||||
// significantly simpler.
|
||||
type BlockedKeyCheckFunc func(context.Context, *sapb.KeyBlockedRequest) (*sapb.Exists, error)
|
||||
|
||||
// KeyPolicy determines which types of key may be used with various boulder
|
||||
// operations.
|
||||
type KeyPolicy struct {
|
||||
|
|
@ -42,6 +51,7 @@ type KeyPolicy struct {
|
|||
AllowECDSANISTP384 bool // Whether ECDSA NISTP384 keys should be allowed.
|
||||
weakRSAList *WeakRSAKeys
|
||||
blockedList *blockedKeys
|
||||
dbCheck BlockedKeyCheckFunc
|
||||
}
|
||||
|
||||
// NewKeyPolicy returns a KeyPolicy that allows RSA, ECDSA256 and ECDSA384.
|
||||
|
|
@ -51,11 +61,12 @@ type KeyPolicy struct {
|
|||
// containing Base64 encoded SHA256 hashes of pkix subject public keys that
|
||||
// should be blocked. If this argument is empty then no blocked key checking is
|
||||
// performed.
|
||||
func NewKeyPolicy(weakKeyFile, blockedKeyFile string) (KeyPolicy, error) {
|
||||
func NewKeyPolicy(weakKeyFile, blockedKeyFile string, bkc BlockedKeyCheckFunc) (KeyPolicy, error) {
|
||||
kp := KeyPolicy{
|
||||
AllowRSA: true,
|
||||
AllowECDSANISTP256: true,
|
||||
AllowECDSANISTP384: true,
|
||||
dbCheck: bkc,
|
||||
}
|
||||
if weakKeyFile != "" {
|
||||
keyList, err := LoadWeakRSASuffixes(weakKeyFile)
|
||||
|
|
@ -79,7 +90,7 @@ func NewKeyPolicy(weakKeyFile, blockedKeyFile string) (KeyPolicy, error) {
|
|||
// strength and algorithm checking. GoodKey only supports pointers: *rsa.PublicKey
|
||||
// and *ecdsa.PublicKey. It will reject non-pointer types.
|
||||
// TODO: Support JSONWebKeys once go-jose migration is done.
|
||||
func (policy *KeyPolicy) GoodKey(key crypto.PublicKey) error {
|
||||
func (policy *KeyPolicy) GoodKey(ctx context.Context, key crypto.PublicKey) error {
|
||||
// If there is a blocked list configured then check if the public key is one
|
||||
// that has been administratively blocked.
|
||||
if policy.blockedList != nil {
|
||||
|
|
@ -89,6 +100,19 @@ func (policy *KeyPolicy) GoodKey(key crypto.PublicKey) error {
|
|||
return berrors.BadPublicKeyError("public key is forbidden")
|
||||
}
|
||||
}
|
||||
if policy.dbCheck != nil {
|
||||
digest, err := core.KeyDigest(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
exists, err := policy.dbCheck(ctx, &sapb.KeyBlockedRequest{KeyHash: digest[:]})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if *exists.Exists {
|
||||
return berrors.BadPublicKeyError("public key is forbidden")
|
||||
}
|
||||
}
|
||||
switch t := key.(type) {
|
||||
case *rsa.PublicKey:
|
||||
return policy.goodKeyRSA(t)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package goodkey
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
|
|
@ -9,6 +10,8 @@ import (
|
|||
"math/big"
|
||||
"testing"
|
||||
|
||||
berrors "github.com/letsencrypt/boulder/errors"
|
||||
sapb "github.com/letsencrypt/boulder/sa/proto"
|
||||
"github.com/letsencrypt/boulder/test"
|
||||
)
|
||||
|
||||
|
|
@ -20,13 +23,13 @@ var testingPolicy = &KeyPolicy{
|
|||
|
||||
func TestUnknownKeyType(t *testing.T) {
|
||||
notAKey := struct{}{}
|
||||
err := testingPolicy.GoodKey(notAKey)
|
||||
err := testingPolicy.GoodKey(context.Background(), notAKey)
|
||||
test.AssertError(t, err, "Should have rejected a key of unknown type")
|
||||
test.AssertEquals(t, err.Error(), "unknown key type struct {}")
|
||||
}
|
||||
|
||||
func TestNilKey(t *testing.T) {
|
||||
err := testingPolicy.GoodKey(nil)
|
||||
err := testingPolicy.GoodKey(context.Background(), nil)
|
||||
test.AssertError(t, err, "Should have rejected a nil key")
|
||||
test.AssertEquals(t, err.Error(), "unknown key type <nil>")
|
||||
}
|
||||
|
|
@ -41,7 +44,7 @@ func TestSmallModulus(t *testing.T) {
|
|||
if !ok {
|
||||
t.Errorf("error parsing pubkey modulus")
|
||||
}
|
||||
err := testingPolicy.GoodKey(&pubKey)
|
||||
err := testingPolicy.GoodKey(context.Background(), &pubKey)
|
||||
test.AssertError(t, err, "Should have rejected too-short key")
|
||||
test.AssertEquals(t, err.Error(), "key too small: 2040")
|
||||
}
|
||||
|
|
@ -56,7 +59,7 @@ func TestLargeModulus(t *testing.T) {
|
|||
if !ok {
|
||||
t.Errorf("error parsing pubkey modulus")
|
||||
}
|
||||
err := testingPolicy.GoodKey(&pubKey)
|
||||
err := testingPolicy.GoodKey(context.Background(), &pubKey)
|
||||
test.AssertError(t, err, "Should have rejected too-long key")
|
||||
test.AssertEquals(t, err.Error(), "key too large: 4097 > 4096")
|
||||
}
|
||||
|
|
@ -67,7 +70,7 @@ func TestModulusModulo8(t *testing.T) {
|
|||
N: bigOne.Lsh(bigOne, 2048),
|
||||
E: 5,
|
||||
}
|
||||
err := testingPolicy.GoodKey(&key)
|
||||
err := testingPolicy.GoodKey(context.Background(), &key)
|
||||
test.AssertError(t, err, "Should have rejected modulus with length not divisible by 8")
|
||||
test.AssertEquals(t, err.Error(), "key length wasn't a multiple of 8: 2049")
|
||||
}
|
||||
|
|
@ -80,7 +83,7 @@ func TestNonStandardExp(t *testing.T) {
|
|||
N: evenMod,
|
||||
E: (1 << 16),
|
||||
}
|
||||
err := testingPolicy.GoodKey(&key)
|
||||
err := testingPolicy.GoodKey(context.Background(), &key)
|
||||
test.AssertError(t, err, "Should have rejected non-standard exponent")
|
||||
test.AssertEquals(t, err.Error(), "key exponent must be 65537")
|
||||
}
|
||||
|
|
@ -91,7 +94,7 @@ func TestEvenModulus(t *testing.T) {
|
|||
N: evenMod,
|
||||
E: (1 << 16) + 1,
|
||||
}
|
||||
err := testingPolicy.GoodKey(&key)
|
||||
err := testingPolicy.GoodKey(context.Background(), &key)
|
||||
test.AssertError(t, err, "Should have rejected even modulus")
|
||||
test.AssertEquals(t, err.Error(), "key divisible by small prime")
|
||||
}
|
||||
|
|
@ -101,7 +104,7 @@ func TestModulusDivisibleBySmallPrime(t *testing.T) {
|
|||
N: mod2048,
|
||||
E: (1 << 16) + 1,
|
||||
}
|
||||
err := testingPolicy.GoodKey(&key)
|
||||
err := testingPolicy.GoodKey(context.Background(), &key)
|
||||
test.AssertError(t, err, "Should have rejected modulus divisible by 3")
|
||||
test.AssertEquals(t, err.Error(), "key divisible by small prime")
|
||||
}
|
||||
|
|
@ -115,7 +118,7 @@ func TestROCA(t *testing.T) {
|
|||
N: n,
|
||||
E: 65537,
|
||||
}
|
||||
err := testingPolicy.GoodKey(&key)
|
||||
err := testingPolicy.GoodKey(context.Background(), &key)
|
||||
test.AssertError(t, err, "Should have rejected ROCA-weak key")
|
||||
test.AssertEquals(t, err.Error(), "key generated by vulnerable Infineon-based hardware")
|
||||
}
|
||||
|
|
@ -123,14 +126,14 @@ func TestROCA(t *testing.T) {
|
|||
func TestGoodKey(t *testing.T) {
|
||||
private, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
test.AssertNotError(t, err, "Error generating key")
|
||||
test.AssertNotError(t, testingPolicy.GoodKey(&private.PublicKey), "Should have accepted good key")
|
||||
test.AssertNotError(t, testingPolicy.GoodKey(context.Background(), &private.PublicKey), "Should have accepted good key")
|
||||
}
|
||||
|
||||
func TestECDSABadCurve(t *testing.T) {
|
||||
for _, curve := range invalidCurves {
|
||||
private, err := ecdsa.GenerateKey(curve, rand.Reader)
|
||||
test.AssertNotError(t, err, "Error generating key")
|
||||
err = testingPolicy.GoodKey(&private.PublicKey)
|
||||
err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
|
||||
test.AssertError(t, err, "Should have rejected key with unsupported curve")
|
||||
test.AssertEquals(t, err.Error(), fmt.Sprintf("ECDSA curve %s not allowed", curve.Params().Name))
|
||||
}
|
||||
|
|
@ -150,7 +153,7 @@ func TestECDSAGoodKey(t *testing.T) {
|
|||
for _, curve := range validCurves {
|
||||
private, err := ecdsa.GenerateKey(curve, rand.Reader)
|
||||
test.AssertNotError(t, err, "Error generating key")
|
||||
test.AssertNotError(t, testingPolicy.GoodKey(&private.PublicKey), "Should have accepted good key")
|
||||
test.AssertNotError(t, testingPolicy.GoodKey(context.Background(), &private.PublicKey), "Should have accepted good key")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -161,7 +164,7 @@ func TestECDSANotOnCurveX(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Error generating key")
|
||||
|
||||
private.X.Add(private.X, big.NewInt(1))
|
||||
err = testingPolicy.GoodKey(&private.PublicKey)
|
||||
err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
|
||||
test.AssertError(t, err, "Should not have accepted key not on the curve")
|
||||
test.AssertEquals(t, err.Error(), "key point is not on the curve")
|
||||
}
|
||||
|
|
@ -175,7 +178,7 @@ func TestECDSANotOnCurveY(t *testing.T) {
|
|||
|
||||
// Change the public key so that it is no longer on the curve.
|
||||
private.Y.Add(private.Y, big.NewInt(1))
|
||||
err = testingPolicy.GoodKey(&private.PublicKey)
|
||||
err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
|
||||
test.AssertError(t, err, "Should not have accepted key not on the curve")
|
||||
test.AssertEquals(t, err.Error(), "key point is not on the curve")
|
||||
}
|
||||
|
|
@ -188,14 +191,14 @@ func TestECDSANegative(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Error generating key")
|
||||
|
||||
private.X.Neg(private.X)
|
||||
err = testingPolicy.GoodKey(&private.PublicKey)
|
||||
err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
|
||||
test.AssertError(t, err, "Should not have accepted key with negative X")
|
||||
test.AssertEquals(t, err.Error(), "key x, y must not be negative")
|
||||
|
||||
// Check that negative Y is not accepted.
|
||||
private.X.Neg(private.X)
|
||||
private.Y.Neg(private.Y)
|
||||
err = testingPolicy.GoodKey(&private.PublicKey)
|
||||
err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
|
||||
test.AssertError(t, err, "Should not have accepted key with negative Y")
|
||||
test.AssertEquals(t, err.Error(), "key x, y must not be negative")
|
||||
}
|
||||
|
|
@ -208,7 +211,7 @@ func TestECDSAXOutsideField(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Error generating key")
|
||||
|
||||
private.X.Mul(private.X, private.Curve.Params().P)
|
||||
err = testingPolicy.GoodKey(&private.PublicKey)
|
||||
err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
|
||||
test.AssertError(t, err, "Should not have accepted key with a X > p-1")
|
||||
test.AssertEquals(t, err.Error(), "key x, y must not exceed P-1")
|
||||
}
|
||||
|
|
@ -221,7 +224,7 @@ func TestECDSAYOutsideField(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Error generating key")
|
||||
|
||||
private.X.Mul(private.Y, private.Curve.Params().P)
|
||||
err = testingPolicy.GoodKey(&private.PublicKey)
|
||||
err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
|
||||
test.AssertError(t, err, "Should not have accepted key with a Y > p-1")
|
||||
test.AssertEquals(t, err.Error(), "key x, y must not exceed P-1")
|
||||
}
|
||||
|
|
@ -236,7 +239,7 @@ func TestECDSAIdentity(t *testing.T) {
|
|||
Y: big.NewInt(0),
|
||||
}
|
||||
|
||||
err := testingPolicy.GoodKey(&public)
|
||||
err := testingPolicy.GoodKey(context.Background(), &public)
|
||||
test.AssertError(t, err, "Should not have accepted key with point at infinity")
|
||||
test.AssertEquals(t, err.Error(), "key x, y must not be the point at infinity")
|
||||
}
|
||||
|
|
@ -245,5 +248,25 @@ func TestECDSAIdentity(t *testing.T) {
|
|||
func TestNonRefKey(t *testing.T) {
|
||||
private, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
test.AssertNotError(t, err, "Error generating key")
|
||||
test.AssertError(t, testingPolicy.GoodKey(private.PublicKey), "Accepted non-reference key")
|
||||
test.AssertError(t, testingPolicy.GoodKey(context.Background(), private.PublicKey), "Accepted non-reference key")
|
||||
}
|
||||
|
||||
func TestDBBlacklist(t *testing.T) {
|
||||
exists := false
|
||||
testCheck := func(context.Context, *sapb.KeyBlockedRequest) (*sapb.Exists, error) {
|
||||
return &sapb.Exists{Exists: &exists}, nil
|
||||
}
|
||||
|
||||
policy, err := NewKeyPolicy("", "", testCheck)
|
||||
test.AssertNotError(t, err, "NewKeyPolicy failed")
|
||||
|
||||
k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
|
||||
err = policy.GoodKey(context.Background(), k.Public())
|
||||
test.AssertNotError(t, err, "GoodKey failed with a non-blocked key")
|
||||
exists = true
|
||||
err = policy.GoodKey(context.Background(), k.Public())
|
||||
test.AssertError(t, err, "GoodKey didn't fail with a blocked key")
|
||||
test.Assert(t, berrors.Is(err, berrors.BadPublicKey), "returned error is wrong type")
|
||||
test.AssertEquals(t, err.Error(), "public key is forbidden")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -500,6 +500,16 @@ func (sas StorageAuthorityClientWrapper) SerialExists(ctx context.Context, req *
|
|||
return res, nil
|
||||
}
|
||||
|
||||
func (sac StorageAuthorityClientWrapper) AddBlockedKey(ctx context.Context, req *sapb.AddBlockedKeyRequest) (*corepb.Empty, error) {
|
||||
// All return checking is done at the call site
|
||||
return sac.inner.AddBlockedKey(ctx, req)
|
||||
}
|
||||
|
||||
func (sac StorageAuthorityClientWrapper) KeyBlocked(ctx context.Context, req *sapb.KeyBlockedRequest) (*sapb.Exists, error) {
|
||||
// All return checking is done at the call site
|
||||
return sac.inner.KeyBlocked(ctx, req)
|
||||
}
|
||||
|
||||
// StorageAuthorityServerWrapper is the gRPC version of a core.ServerAuthority server
|
||||
type StorageAuthorityServerWrapper struct {
|
||||
// TODO(#3119): Don't use core.StorageAuthority
|
||||
|
|
@ -916,3 +926,13 @@ func (sas StorageAuthorityServerWrapper) SerialExists(ctx context.Context, req *
|
|||
}
|
||||
return sas.inner.SerialExists(ctx, req)
|
||||
}
|
||||
|
||||
func (sas StorageAuthorityServerWrapper) AddBlockedKey(ctx context.Context, req *sapb.AddBlockedKeyRequest) (*corepb.Empty, error) {
|
||||
// All request checking is done in the method
|
||||
return sas.inner.AddBlockedKey(ctx, req)
|
||||
}
|
||||
|
||||
func (sas StorageAuthorityServerWrapper) KeyBlocked(ctx context.Context, req *sapb.KeyBlockedRequest) (*sapb.Exists, error) {
|
||||
// All request checking is done in the method
|
||||
return sas.inner.KeyBlocked(ctx, req)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -700,6 +700,17 @@ func (sa *StorageAuthority) RevokeCertificate(ctx context.Context, req *sapb.Rev
|
|||
return nil
|
||||
}
|
||||
|
||||
// AddBlockedKey is a mock
|
||||
func (sa *StorageAuthority) AddBlockedKey(context.Context, *sapb.AddBlockedKeyRequest) (*corepb.Empty, error) {
|
||||
return &corepb.Empty{}, nil
|
||||
}
|
||||
|
||||
// KeyBlocked is a mock
|
||||
func (sa *StorageAuthority) KeyBlocked(ctx context.Context, req *sapb.KeyBlockedRequest) (*sapb.Exists, error) {
|
||||
exists := false
|
||||
return &sapb.Exists{Exists: &exists}, nil
|
||||
}
|
||||
|
||||
// Publisher is a mock
|
||||
type Publisher struct {
|
||||
// empty
|
||||
|
|
|
|||
33
ra/ra.go
33
ra/ra.go
|
|
@ -320,7 +320,7 @@ func (ra *RegistrationAuthorityImpl) checkRegistrationLimits(ctx context.Context
|
|||
|
||||
// NewRegistration constructs a new Registration from a request.
|
||||
func (ra *RegistrationAuthorityImpl) NewRegistration(ctx context.Context, init core.Registration) (core.Registration, error) {
|
||||
if err := ra.keyPolicy.GoodKey(init.Key.Key); err != nil {
|
||||
if err := ra.keyPolicy.GoodKey(ctx, init.Key.Key); err != nil {
|
||||
return core.Registration{}, berrors.MalformedError("invalid public key: %s", err.Error())
|
||||
}
|
||||
if err := ra.checkRegistrationLimits(ctx, init.InitialIP); err != nil {
|
||||
|
|
@ -985,7 +985,7 @@ func (ra *RegistrationAuthorityImpl) FinalizeOrder(ctx context.Context, req *rap
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := csrlib.VerifyCSR(csrOb, ra.maxNames, &ra.keyPolicy, ra.PA, ra.forceCNFromSAN, *req.Order.RegistrationID); err != nil {
|
||||
if err := csrlib.VerifyCSR(ctx, csrOb, ra.maxNames, &ra.keyPolicy, ra.PA, ra.forceCNFromSAN, *req.Order.RegistrationID); err != nil {
|
||||
// VerifyCSR returns berror instances that can be passed through as-is
|
||||
// without wrapping.
|
||||
return nil, err
|
||||
|
|
@ -1076,7 +1076,7 @@ func (ra *RegistrationAuthorityImpl) FinalizeOrder(ctx context.Context, req *rap
|
|||
// NewCertificate requests the issuance of a certificate.
|
||||
func (ra *RegistrationAuthorityImpl) NewCertificate(ctx context.Context, req core.CertificateRequest, regID int64) (core.Certificate, error) {
|
||||
// Verify the CSR
|
||||
if err := csrlib.VerifyCSR(req.CSR, ra.maxNames, &ra.keyPolicy, ra.PA, ra.forceCNFromSAN, regID); err != nil {
|
||||
if err := csrlib.VerifyCSR(ctx, req.CSR, ra.maxNames, &ra.keyPolicy, ra.PA, ra.forceCNFromSAN, regID); err != nil {
|
||||
return core.Certificate{}, berrors.MalformedError(err.Error())
|
||||
}
|
||||
// NewCertificate provides an order ID of 0, indicating this is a classic ACME
|
||||
|
|
@ -1687,10 +1687,10 @@ func revokeEvent(state, serial, cn string, names []string, revocationCode revoca
|
|||
|
||||
// revokeCertificate generates a revoked OCSP response for the given certificate, stores
|
||||
// the revocation information, and purges OCSP request URLs from Akamai.
|
||||
func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert x509.Certificate, code revocation.Reason) error {
|
||||
func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert x509.Certificate, code revocation.Reason, source string, comment string) error {
|
||||
status := string(core.OCSPStatusRevoked)
|
||||
reason := int32(code)
|
||||
revokedAt := time.Now().UnixNano()
|
||||
revokedAt := ra.clk.Now().UnixNano()
|
||||
ocspResponse, err := ra.CA.GenerateOCSP(ctx, &caPB.GenerateOCSPRequest{
|
||||
CertDER: cert.Raw,
|
||||
Status: &status,
|
||||
|
|
@ -1713,6 +1713,23 @@ func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if features.Enabled(features.BlockedKeyTable) && reason == revocation.KeyCompromise {
|
||||
digest, err := core.KeyDigest(cert.PublicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := &sapb.AddBlockedKeyRequest{
|
||||
KeyHash: digest[:],
|
||||
Added: &revokedAt,
|
||||
Source: &source,
|
||||
}
|
||||
if comment != "" {
|
||||
req.Comment = &comment
|
||||
}
|
||||
if _, err = ra.SA.AddBlockedKey(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
purgeURLs, err := akamai.GeneratePurgeURLs(cert.Raw, ra.issuer)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -1728,7 +1745,7 @@ func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert
|
|||
// RevokeCertificateWithReg terminates trust in the certificate provided.
|
||||
func (ra *RegistrationAuthorityImpl) RevokeCertificateWithReg(ctx context.Context, cert x509.Certificate, revocationCode revocation.Reason, regID int64) error {
|
||||
serialString := core.SerialToString(cert.SerialNumber)
|
||||
err := ra.revokeCertificate(ctx, cert, revocationCode)
|
||||
err := ra.revokeCertificate(ctx, cert, revocationCode, "API", "")
|
||||
|
||||
state := "Failure"
|
||||
defer func() {
|
||||
|
|
@ -1758,7 +1775,9 @@ func (ra *RegistrationAuthorityImpl) RevokeCertificateWithReg(ctx context.Contex
|
|||
// called from the admin-revoker tool.
|
||||
func (ra *RegistrationAuthorityImpl) AdministrativelyRevokeCertificate(ctx context.Context, cert x509.Certificate, revocationCode revocation.Reason, user string) error {
|
||||
serialString := core.SerialToString(cert.SerialNumber)
|
||||
err := ra.revokeCertificate(ctx, cert, revocationCode)
|
||||
// TODO(#4774): allow setting the comment via the RPC, format should be:
|
||||
// "revoked by %s: %s", user, comment
|
||||
err := ra.revokeCertificate(ctx, cert, revocationCode, "admin-revoker", fmt.Sprintf("revoked by %s", user))
|
||||
|
||||
state := "Failure"
|
||||
defer func() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package ra
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
|
|
@ -28,6 +29,7 @@ import (
|
|||
ctx509 "github.com/google/certificate-transparency-go/x509"
|
||||
ctpkix "github.com/google/certificate-transparency-go/x509/pkix"
|
||||
"github.com/jmhodges/clock"
|
||||
akamaipb "github.com/letsencrypt/boulder/akamai/proto"
|
||||
capb "github.com/letsencrypt/boulder/ca/proto"
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
|
|
@ -47,6 +49,7 @@ import (
|
|||
pubpb "github.com/letsencrypt/boulder/publisher/proto"
|
||||
rapb "github.com/letsencrypt/boulder/ra/proto"
|
||||
"github.com/letsencrypt/boulder/ratelimit"
|
||||
"github.com/letsencrypt/boulder/revocation"
|
||||
"github.com/letsencrypt/boulder/sa"
|
||||
sapb "github.com/letsencrypt/boulder/sa/proto"
|
||||
"github.com/letsencrypt/boulder/test"
|
||||
|
|
@ -3809,3 +3812,74 @@ xGUhoOJp0T++nz6R3TX7Rwk7KmG6xX3vWr/MFu5A3c8fvkqj987Vti5BeBezCXfs
|
|||
rA==
|
||||
-----END CERTIFICATE-----
|
||||
`)
|
||||
|
||||
type mockSABlockedKey struct {
|
||||
mocks.StorageAuthority
|
||||
|
||||
added *sapb.AddBlockedKeyRequest
|
||||
}
|
||||
|
||||
func (msabk *mockSABlockedKey) AddBlockedKey(_ context.Context, req *sapb.AddBlockedKeyRequest) (*corepb.Empty, error) {
|
||||
msabk.added = req
|
||||
return &corepb.Empty{}, nil
|
||||
}
|
||||
|
||||
type mockCAOCSP struct {
|
||||
mocks.MockCA
|
||||
}
|
||||
|
||||
func (mcao *mockCAOCSP) GenerateOCSP(context.Context, *capb.GenerateOCSPRequest) (*capb.OCSPResponse, error) {
|
||||
return &capb.OCSPResponse{Response: []byte{1, 2, 3}}, nil
|
||||
}
|
||||
|
||||
type mockPurger struct{}
|
||||
|
||||
func (mp *mockPurger) Purge(context.Context, *akamaipb.PurgeRequest, ...grpc.CallOption) (*corepb.Empty, error) {
|
||||
return &corepb.Empty{}, nil
|
||||
}
|
||||
|
||||
func TestRevocationAddBlockedKey(t *testing.T) {
|
||||
_, _, ra, _, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
|
||||
err := features.Set(map[string]bool{"BlockedKeyTable": true})
|
||||
test.AssertNotError(t, err, "features.Set failed")
|
||||
defer features.Reset()
|
||||
|
||||
mockSA := mockSABlockedKey{}
|
||||
ra.SA = &mockSA
|
||||
ra.CA = &mockCAOCSP{}
|
||||
ra.purger = &mockPurger{}
|
||||
|
||||
k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
|
||||
digest, err := core.KeyDigest(k.Public())
|
||||
test.AssertNotError(t, err, "core.KeyDigest failed")
|
||||
|
||||
template := x509.Certificate{PublicKey: k, SerialNumber: big.NewInt(257)}
|
||||
der, err := x509.CreateCertificate(rand.Reader, &template, &template, k.Public(), k)
|
||||
test.AssertNotError(t, err, "x509.CreateCertificate failed")
|
||||
cert, err := x509.ParseCertificate(der)
|
||||
test.AssertNotError(t, err, "x509.ParseCertificate failed")
|
||||
ra.issuer = cert
|
||||
|
||||
err = ra.RevokeCertificateWithReg(context.Background(), *cert, revocation.Unspecified, 0)
|
||||
test.AssertNotError(t, err, "RevokeCertificateWithReg failed")
|
||||
test.Assert(t, mockSA.added == nil, "blocked key was added when reason was not keyCompromise")
|
||||
|
||||
err = ra.RevokeCertificateWithReg(context.Background(), *cert, revocation.KeyCompromise, 0)
|
||||
test.AssertNotError(t, err, "RevokeCertificateWithReg failed")
|
||||
test.Assert(t, mockSA.added != nil, "blocked key was not added when reason was keyCompromise")
|
||||
test.Assert(t, bytes.Equal(digest[:], mockSA.added.KeyHash), "key hash mismatch")
|
||||
test.AssertEquals(t, *mockSA.added.Source, "API")
|
||||
test.Assert(t, mockSA.added.Comment == nil, "Comment is not nil")
|
||||
|
||||
mockSA.added = nil
|
||||
err = ra.AdministrativelyRevokeCertificate(context.Background(), *cert, revocation.KeyCompromise, "root")
|
||||
test.AssertNotError(t, err, "AdministrativelyRevokeCertificate failed")
|
||||
test.Assert(t, mockSA.added != nil, "blocked key was not added when reason was keyCompromise")
|
||||
test.Assert(t, bytes.Equal(digest[:], mockSA.added.KeyHash), "key hash mismatch")
|
||||
test.AssertEquals(t, *mockSA.added.Source, "admin-revoker")
|
||||
test.Assert(t, mockSA.added.Comment != nil, "Comment is nil")
|
||||
test.AssertEquals(t, *mockSA.added.Comment, "revoked by root")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
-- +goose Up
|
||||
-- SQL in section 'Up' is executed when this migration is applied
|
||||
|
||||
CREATE TABLE `blockedKeys` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`keyHash` binary(32) NOT NULL UNIQUE,
|
||||
`added` datetime NOT NULL,
|
||||
`source` tinyint NOT NULL,
|
||||
`comment` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- +goose Down
|
||||
-- SQL section 'Down' is executed when this migration is rolled back
|
||||
|
||||
DROP TABLE `blockedKeys`;
|
||||
|
|
@ -140,4 +140,5 @@ func initTables(dbMap *gorp.DbMap) {
|
|||
dbMap.AddTableWithName(recordedSerialModel{}, "serials").SetKeys(true, "ID")
|
||||
dbMap.AddTableWithName(precertificateModel{}, "precertificates").SetKeys(true, "ID")
|
||||
dbMap.AddTableWithName(keyHashModel{}, "keyHashToSerial").SetKeys(true, "ID")
|
||||
dbMap.AddTableWithName(blockedKeyModel{}, "blockedKeys").SetKeys(true, "ID")
|
||||
}
|
||||
|
|
|
|||
13
sa/model.go
13
sa/model.go
|
|
@ -617,3 +617,16 @@ type keyHashModel struct {
|
|||
CertNotAfter time.Time
|
||||
CertSerial string
|
||||
}
|
||||
|
||||
var stringToSourceInt = map[string]int{
|
||||
"API": 1,
|
||||
"admin-revoker": 2,
|
||||
}
|
||||
|
||||
type blockedKeyModel struct {
|
||||
ID int64
|
||||
KeyHash []byte
|
||||
Added time.Time
|
||||
Source int
|
||||
Comment *string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1804,6 +1804,108 @@ func (m *FinalizeAuthorizationRequest) GetValidationError() *proto1.ProblemDetai
|
|||
return nil
|
||||
}
|
||||
|
||||
type AddBlockedKeyRequest struct {
|
||||
KeyHash []byte `protobuf:"bytes,1,opt,name=keyHash" json:"keyHash,omitempty"`
|
||||
Added *int64 `protobuf:"varint,2,opt,name=added" json:"added,omitempty"`
|
||||
Source *string `protobuf:"bytes,3,opt,name=source" json:"source,omitempty"`
|
||||
Comment *string `protobuf:"bytes,4,opt,name=comment" json:"comment,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AddBlockedKeyRequest) Reset() { *m = AddBlockedKeyRequest{} }
|
||||
func (m *AddBlockedKeyRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*AddBlockedKeyRequest) ProtoMessage() {}
|
||||
func (*AddBlockedKeyRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_099fb35e782a48a6, []int{33}
|
||||
}
|
||||
|
||||
func (m *AddBlockedKeyRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_AddBlockedKeyRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *AddBlockedKeyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_AddBlockedKeyRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *AddBlockedKeyRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_AddBlockedKeyRequest.Merge(m, src)
|
||||
}
|
||||
func (m *AddBlockedKeyRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_AddBlockedKeyRequest.Size(m)
|
||||
}
|
||||
func (m *AddBlockedKeyRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_AddBlockedKeyRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_AddBlockedKeyRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *AddBlockedKeyRequest) GetKeyHash() []byte {
|
||||
if m != nil {
|
||||
return m.KeyHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AddBlockedKeyRequest) GetAdded() int64 {
|
||||
if m != nil && m.Added != nil {
|
||||
return *m.Added
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *AddBlockedKeyRequest) GetSource() string {
|
||||
if m != nil && m.Source != nil {
|
||||
return *m.Source
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *AddBlockedKeyRequest) GetComment() string {
|
||||
if m != nil && m.Comment != nil {
|
||||
return *m.Comment
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type KeyBlockedRequest struct {
|
||||
KeyHash []byte `protobuf:"bytes,1,opt,name=keyHash" json:"keyHash,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *KeyBlockedRequest) Reset() { *m = KeyBlockedRequest{} }
|
||||
func (m *KeyBlockedRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*KeyBlockedRequest) ProtoMessage() {}
|
||||
func (*KeyBlockedRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_099fb35e782a48a6, []int{34}
|
||||
}
|
||||
|
||||
func (m *KeyBlockedRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_KeyBlockedRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *KeyBlockedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_KeyBlockedRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *KeyBlockedRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_KeyBlockedRequest.Merge(m, src)
|
||||
}
|
||||
func (m *KeyBlockedRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_KeyBlockedRequest.Size(m)
|
||||
}
|
||||
func (m *KeyBlockedRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_KeyBlockedRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_KeyBlockedRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *KeyBlockedRequest) GetKeyHash() []byte {
|
||||
if m != nil {
|
||||
return m.KeyHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*RegistrationID)(nil), "sa.RegistrationID")
|
||||
proto.RegisterType((*JSONWebKey)(nil), "sa.JSONWebKey")
|
||||
|
|
@ -1841,121 +1943,129 @@ func init() {
|
|||
proto.RegisterType((*Authorization2IDs)(nil), "sa.Authorization2IDs")
|
||||
proto.RegisterType((*RevokeCertificateRequest)(nil), "sa.RevokeCertificateRequest")
|
||||
proto.RegisterType((*FinalizeAuthorizationRequest)(nil), "sa.FinalizeAuthorizationRequest")
|
||||
proto.RegisterType((*AddBlockedKeyRequest)(nil), "sa.AddBlockedKeyRequest")
|
||||
proto.RegisterType((*KeyBlockedRequest)(nil), "sa.KeyBlockedRequest")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("sa/proto/sa.proto", fileDescriptor_099fb35e782a48a6) }
|
||||
|
||||
var fileDescriptor_099fb35e782a48a6 = []byte{
|
||||
// 1739 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdd, 0x6e, 0xdb, 0xc8,
|
||||
0x15, 0xd6, 0x8f, 0x65, 0x4b, 0xc7, 0x7f, 0xd2, 0xc4, 0x56, 0xb9, 0x8a, 0x9d, 0xc8, 0xb3, 0xd9,
|
||||
0xc0, 0x8b, 0x02, 0x5e, 0x97, 0x5d, 0xec, 0x16, 0x70, 0x9b, 0xc4, 0x8e, 0x1c, 0xc7, 0x69, 0x62,
|
||||
0x2b, 0x54, 0xe3, 0x16, 0x45, 0x6f, 0x18, 0x71, 0xa2, 0xb0, 0x91, 0x49, 0x65, 0x66, 0x64, 0x47,
|
||||
0xbe, 0x2e, 0xd0, 0x3e, 0x41, 0x51, 0xa0, 0x37, 0x7d, 0x8e, 0xbe, 0x44, 0x5f, 0xa9, 0x98, 0xc3,
|
||||
0x21, 0x45, 0x52, 0xa4, 0x5c, 0xa3, 0x45, 0xef, 0xe6, 0x9c, 0x39, 0x7f, 0x33, 0x73, 0x7e, 0x3e,
|
||||
0x12, 0x1a, 0xc2, 0xfe, 0x6e, 0xc4, 0x7d, 0xe9, 0x7f, 0x27, 0xec, 0x3d, 0x5c, 0x90, 0x92, 0xb0,
|
||||
0x5b, 0x9b, 0x7d, 0x9f, 0x33, 0xbd, 0xa1, 0x96, 0xc1, 0x16, 0x6d, 0xc3, 0x9a, 0xc5, 0x06, 0xae,
|
||||
0x90, 0xdc, 0x96, 0xae, 0xef, 0x9d, 0x76, 0xc8, 0x1a, 0x94, 0x5c, 0xc7, 0x28, 0xb6, 0x8b, 0xbb,
|
||||
0x65, 0xab, 0xe4, 0x3a, 0xf4, 0x01, 0xc0, 0xab, 0xde, 0xf9, 0xd9, 0x6f, 0xd9, 0xfb, 0x5f, 0xb3,
|
||||
0x09, 0xa9, 0x43, 0xf9, 0x8f, 0xd7, 0x9f, 0x70, 0x7b, 0xc5, 0x52, 0x4b, 0xba, 0x03, 0xeb, 0x87,
|
||||
0x63, 0xf9, 0xd1, 0xe7, 0xee, 0xcd, 0xac, 0x89, 0x1a, 0x9a, 0xf8, 0x67, 0x11, 0x1e, 0x9c, 0x30,
|
||||
0xd9, 0x65, 0x9e, 0xe3, 0x7a, 0x83, 0x84, 0xb4, 0xc5, 0x3e, 0x8f, 0x99, 0x90, 0xe4, 0x31, 0xac,
|
||||
0xf1, 0x44, 0x1c, 0x3a, 0x82, 0x14, 0x57, 0xc9, 0xb9, 0x0e, 0xf3, 0xa4, 0xfb, 0xc1, 0x65, 0xfc,
|
||||
0x37, 0x93, 0x11, 0x33, 0x4a, 0xe8, 0x26, 0xc5, 0x25, 0xbb, 0xb0, 0x3e, 0xe5, 0x5c, 0xd8, 0xc3,
|
||||
0x31, 0x33, 0xca, 0x28, 0x98, 0x66, 0x93, 0x07, 0x00, 0x57, 0xf6, 0xd0, 0x75, 0xde, 0x79, 0xd2,
|
||||
0x1d, 0x1a, 0x0b, 0xe8, 0x35, 0xc6, 0xa1, 0x02, 0xb6, 0x4f, 0x98, 0xbc, 0x50, 0x8c, 0x44, 0xe4,
|
||||
0xe2, 0xae, 0xa1, 0x1b, 0xb0, 0xe4, 0xf8, 0x97, 0xb6, 0xeb, 0x09, 0xa3, 0xd4, 0x2e, 0xef, 0xd6,
|
||||
0xac, 0x90, 0x54, 0x97, 0xea, 0xf9, 0xd7, 0x18, 0x60, 0xd9, 0x52, 0x4b, 0xfa, 0x8f, 0x22, 0xdc,
|
||||
0xcb, 0x70, 0x49, 0x7e, 0x01, 0x15, 0x0c, 0xcd, 0x28, 0xb6, 0xcb, 0xbb, 0xcb, 0x26, 0xdd, 0x13,
|
||||
0xf6, 0x5e, 0x86, 0xdc, 0xde, 0x1b, 0x7b, 0x74, 0x3c, 0x64, 0x97, 0xcc, 0x93, 0x56, 0xa0, 0xd0,
|
||||
0x3a, 0x07, 0x98, 0x32, 0x49, 0x13, 0x16, 0x03, 0xe7, 0xfa, 0x95, 0x34, 0x45, 0xbe, 0x85, 0x8a,
|
||||
0x3d, 0x96, 0x1f, 0x6f, 0xf0, 0x56, 0x97, 0xcd, 0x7b, 0x7b, 0x98, 0x2a, 0xc9, 0x17, 0x0b, 0x24,
|
||||
0xe8, 0xbf, 0x4a, 0xd0, 0x78, 0xce, 0xb8, 0xba, 0xca, 0xbe, 0x2d, 0x59, 0x4f, 0xda, 0x72, 0x2c,
|
||||
0x94, 0x61, 0xc1, 0xb8, 0x6b, 0x0f, 0x43, 0xc3, 0x01, 0x85, 0x7c, 0x94, 0xd0, 0xcf, 0xa0, 0x29,
|
||||
0xf5, 0x4e, 0x7e, 0x5f, 0x8c, 0x5e, 0xdb, 0x42, 0xbe, 0x1b, 0x39, 0xb6, 0x64, 0x8e, 0x7e, 0x82,
|
||||
0x34, 0x9b, 0xb4, 0x61, 0x99, 0xb3, 0x2b, 0xff, 0x13, 0x73, 0x3a, 0xb6, 0x64, 0x46, 0x05, 0xa5,
|
||||
0xe2, 0x2c, 0xf2, 0x08, 0x56, 0x35, 0x69, 0x31, 0x5b, 0xf8, 0x9e, 0xb1, 0x88, 0x32, 0x49, 0x26,
|
||||
0xf9, 0x1e, 0x36, 0x87, 0xb6, 0x90, 0xc7, 0x5f, 0x46, 0x6e, 0xf0, 0x34, 0x67, 0xf6, 0xa0, 0xc7,
|
||||
0x3c, 0x69, 0x2c, 0xa1, 0x74, 0xf6, 0x26, 0xa1, 0xb0, 0xa2, 0x02, 0xb2, 0x98, 0x18, 0xf9, 0x9e,
|
||||
0x60, 0x46, 0x15, 0x0b, 0x20, 0xc1, 0x23, 0x2d, 0xa8, 0x7a, 0xbe, 0x3c, 0xfc, 0x20, 0x19, 0x37,
|
||||
0x6a, 0x68, 0x2c, 0xa2, 0xc9, 0x16, 0xd4, 0x5c, 0x81, 0x66, 0x99, 0x63, 0x40, 0xbb, 0xb8, 0x5b,
|
||||
0xb5, 0xa6, 0x8c, 0x57, 0x0b, 0xd5, 0x52, 0xbd, 0x4c, 0xdb, 0xb0, 0xd8, 0x9b, 0xde, 0x56, 0xc6,
|
||||
0x2d, 0xd2, 0x03, 0xa8, 0x58, 0xb6, 0x37, 0x40, 0x57, 0xcc, 0xe6, 0x43, 0x97, 0x09, 0xa9, 0xb3,
|
||||
0x2d, 0xa2, 0x95, 0xf2, 0xd0, 0x96, 0x6a, 0xa7, 0x84, 0x3b, 0x9a, 0xa2, 0xdb, 0x50, 0x79, 0xee,
|
||||
0x8f, 0x3d, 0x49, 0x36, 0xa0, 0xd2, 0x57, 0x0b, 0xad, 0x19, 0x10, 0xf4, 0x77, 0xf0, 0x10, 0xb7,
|
||||
0x63, 0x6f, 0x2a, 0x8e, 0x26, 0x67, 0xf6, 0x25, 0x8b, 0x32, 0xfd, 0x21, 0x54, 0xb8, 0x72, 0x8f,
|
||||
0x8a, 0xcb, 0x66, 0x4d, 0x65, 0x1f, 0xc6, 0x63, 0x05, 0x7c, 0x65, 0xd9, 0x53, 0x0a, 0x3a, 0xc1,
|
||||
0x03, 0x82, 0xfe, 0xb9, 0x08, 0x2b, 0x68, 0x5a, 0x9b, 0x23, 0x4f, 0x61, 0xa5, 0x1f, 0xa3, 0x75,
|
||||
0x32, 0xdf, 0x57, 0xe6, 0xe2, 0x72, 0xf1, 0x2c, 0x4e, 0x28, 0xb4, 0x7e, 0x48, 0x24, 0x33, 0x81,
|
||||
0x05, 0xe5, 0x48, 0xdf, 0x15, 0xae, 0xa7, 0x67, 0x2c, 0xc5, 0xcf, 0xd8, 0x85, 0x6d, 0x74, 0x10,
|
||||
0x6f, 0x79, 0xe2, 0x68, 0x72, 0xda, 0x0d, 0x4f, 0xa8, 0x3a, 0xd7, 0x48, 0x77, 0xb7, 0x92, 0x3b,
|
||||
0x9a, 0x9e, 0xb8, 0x94, 0x7d, 0x62, 0xfa, 0x97, 0x22, 0xec, 0xa0, 0xc9, 0x53, 0xef, 0xea, 0xbf,
|
||||
0x6f, 0x11, 0x2d, 0xa8, 0x7e, 0xf4, 0x85, 0xc4, 0xd3, 0x04, 0x7d, 0x2d, 0xa2, 0xa7, 0xa1, 0x94,
|
||||
0x73, 0x42, 0xe9, 0x01, 0xc1, 0x48, 0xce, 0xb9, 0xc3, 0x78, 0xe4, 0x7a, 0x0b, 0x6a, 0x76, 0x1f,
|
||||
0x4f, 0x1f, 0x79, 0x9d, 0x32, 0x6e, 0x3f, 0xdf, 0x4b, 0xd8, 0x40, 0xa3, 0x2f, 0xde, 0x76, 0xce,
|
||||
0x7a, 0x4c, 0x46, 0x66, 0x9b, 0xb0, 0x78, 0xed, 0x7a, 0x8e, 0x7f, 0xad, 0x6d, 0x6a, 0x2a, 0xbf,
|
||||
0xc9, 0xd1, 0x7d, 0xd8, 0xd0, 0x46, 0x8e, 0xbf, 0xb8, 0x62, 0x6a, 0x29, 0xa6, 0x51, 0x4c, 0x6a,
|
||||
0x74, 0xa1, 0xdd, 0xe5, 0xec, 0xca, 0xf5, 0xc7, 0x22, 0x96, 0x94, 0x49, 0xed, 0xbc, 0x46, 0xb6,
|
||||
0x01, 0x15, 0xce, 0x06, 0xa7, 0x9d, 0xf0, 0xfd, 0x91, 0x50, 0x15, 0x16, 0xa8, 0x2b, 0x3d, 0x86,
|
||||
0x2b, 0xd4, 0xab, 0x5a, 0x9a, 0xa2, 0x12, 0xea, 0x87, 0x8e, 0x13, 0x94, 0x61, 0xe8, 0x23, 0xb2,
|
||||
0x55, 0x8c, 0xd9, 0x8a, 0xd5, 0x68, 0x29, 0xd1, 0xe9, 0x0c, 0x58, 0xea, 0x73, 0x86, 0x9d, 0x2c,
|
||||
0x68, 0xe8, 0x21, 0xa9, 0x76, 0x18, 0x16, 0xbc, 0xd0, 0x3d, 0x2e, 0x24, 0x55, 0x85, 0x6c, 0x1e,
|
||||
0x3a, 0x4e, 0xec, 0x94, 0xa1, 0xef, 0x3a, 0x94, 0x1d, 0xc6, 0xc3, 0x79, 0xeb, 0x30, 0x9e, 0x7d,
|
||||
0x32, 0x55, 0x03, 0xaa, 0x17, 0xa1, 0xcb, 0x15, 0x0b, 0xd7, 0x2a, 0x42, 0x57, 0x88, 0x71, 0xd4,
|
||||
0x52, 0x35, 0xa5, 0xb2, 0x0c, 0x57, 0xfc, 0xb4, 0xa3, 0xdb, 0x68, 0x44, 0xd3, 0x7d, 0x68, 0xa6,
|
||||
0x03, 0xd1, 0xdd, 0x4d, 0xdd, 0xb4, 0x3b, 0x08, 0x1b, 0x8e, 0xba, 0x69, 0xa4, 0x68, 0x17, 0x56,
|
||||
0x30, 0xe3, 0xe2, 0x25, 0x14, 0xc3, 0x0f, 0x64, 0x1f, 0xee, 0x8d, 0x05, 0xbb, 0x30, 0x93, 0x95,
|
||||
0x81, 0xd1, 0x57, 0xad, 0xac, 0x2d, 0xfa, 0x1a, 0x68, 0x38, 0x71, 0xd1, 0x72, 0x76, 0x4d, 0xa5,
|
||||
0xfd, 0x34, 0x61, 0xd1, 0xee, 0xf7, 0x65, 0x74, 0x31, 0x9a, 0xa2, 0x13, 0xf8, 0xc9, 0x09, 0x0b,
|
||||
0x8a, 0xe2, 0x85, 0xcf, 0x13, 0xfd, 0x6c, 0xaa, 0x52, 0x8c, 0xab, 0x64, 0xb7, 0xb1, 0xbc, 0x83,
|
||||
0x94, 0xf3, 0x0f, 0xf2, 0xb7, 0x22, 0x18, 0x27, 0x4c, 0xfe, 0xdf, 0x60, 0x83, 0x9a, 0xa6, 0x9c,
|
||||
0x7d, 0x1e, 0xbb, 0x5c, 0xc7, 0x72, 0x13, 0x64, 0x5a, 0xd5, 0x4a, 0xb3, 0xe9, 0x5f, 0x8b, 0xb0,
|
||||
0x96, 0xc2, 0x16, 0x3f, 0x0f, 0x67, 0x7f, 0xd0, 0x8e, 0xb7, 0x55, 0x2f, 0x98, 0x03, 0x2b, 0x50,
|
||||
0xf6, 0x7f, 0x0f, 0x2b, 0x5e, 0xc3, 0xc3, 0x43, 0xc7, 0xc9, 0x82, 0x8a, 0xd1, 0xcd, 0x7d, 0x9b,
|
||||
0x0c, 0x74, 0x9e, 0xb5, 0x47, 0x50, 0x4f, 0x81, 0x53, 0xbc, 0x36, 0xd7, 0x09, 0x9b, 0x8d, 0x5a,
|
||||
0x52, 0x3a, 0x23, 0x65, 0xce, 0xc0, 0xe0, 0x6f, 0xa0, 0x91, 0x90, 0x31, 0x53, 0xa6, 0xca, 0x81,
|
||||
0xa9, 0x1b, 0x30, 0x2c, 0x84, 0x1b, 0x19, 0xb5, 0x3c, 0x07, 0x1b, 0xf1, 0x00, 0xb0, 0xe8, 0xcc,
|
||||
0x0d, 0x28, 0x55, 0xd3, 0x0a, 0xfa, 0xe8, 0x07, 0xc6, 0xb5, 0xaa, 0x5d, 0x1e, 0x62, 0x90, 0x05,
|
||||
0xac, 0xf5, 0x88, 0xa6, 0x7f, 0x2a, 0xc1, 0xd6, 0x0b, 0xd7, 0xb3, 0x87, 0xee, 0x0d, 0xcb, 0x04,
|
||||
0xd9, 0x19, 0x25, 0xa3, 0x41, 0x59, 0x29, 0x01, 0xca, 0x62, 0x8d, 0xaa, 0x9c, 0x68, 0x54, 0x38,
|
||||
0x4d, 0xa4, 0x64, 0x97, 0xa3, 0x10, 0xa8, 0xd5, 0xac, 0x29, 0x83, 0x74, 0xa0, 0x81, 0x43, 0x50,
|
||||
0x3b, 0xed, 0xfb, 0xdc, 0x11, 0x46, 0x05, 0x1f, 0xa9, 0x19, 0x3c, 0xd2, 0x45, 0x6a, 0xdb, 0x9a,
|
||||
0x55, 0x20, 0x4f, 0x60, 0x7d, 0xca, 0x3c, 0xe6, 0xdc, 0xe7, 0x08, 0xe4, 0x96, 0xcd, 0x8d, 0xc0,
|
||||
0x46, 0x97, 0xfb, 0xef, 0x87, 0xec, 0xb2, 0xc3, 0xa4, 0xed, 0x0e, 0x85, 0x95, 0x16, 0x36, 0xff,
|
||||
0x4e, 0xa0, 0xde, 0x93, 0x3e, 0xb7, 0x07, 0xe1, 0x2d, 0xc8, 0x09, 0x39, 0x80, 0xf5, 0x13, 0x96,
|
||||
0x98, 0xfb, 0x84, 0xe0, 0xb0, 0x4b, 0x14, 0x5b, 0x8b, 0x04, 0x2e, 0xe2, 0x5c, 0x5a, 0x20, 0xbf,
|
||||
0x84, 0x8d, 0x94, 0xf2, 0xd1, 0x44, 0x7d, 0x0c, 0xad, 0x29, 0x0b, 0xd3, 0x8f, 0xa3, 0x1c, 0xed,
|
||||
0x9f, 0xc1, 0xda, 0x09, 0x8b, 0xc3, 0x2a, 0x02, 0x4a, 0x2f, 0x98, 0x31, 0xad, 0x46, 0xa0, 0x13,
|
||||
0xdb, 0xa6, 0x05, 0xf2, 0x3d, 0x34, 0xd4, 0xf7, 0x12, 0x67, 0xfd, 0xbb, 0x68, 0x1d, 0x60, 0x98,
|
||||
0xb3, 0x98, 0x3c, 0xae, 0xb8, 0x89, 0x20, 0x2b, 0x2d, 0x42, 0x0b, 0xa4, 0x07, 0x46, 0x1e, 0xfc,
|
||||
0x23, 0x5f, 0x47, 0xc8, 0x2c, 0x1f, 0x1c, 0xb6, 0xea, 0x69, 0xf8, 0x46, 0x0b, 0xe4, 0x25, 0x34,
|
||||
0xb3, 0xf1, 0x16, 0xd9, 0x89, 0xa4, 0xf3, 0xb0, 0x58, 0xab, 0x16, 0x89, 0xd0, 0x02, 0x79, 0x03,
|
||||
0xf7, 0x73, 0xa4, 0x11, 0x78, 0xde, 0xd5, 0x9c, 0x09, 0xcb, 0x31, 0xac, 0x44, 0x9a, 0xd1, 0x5e,
|
||||
0x02, 0x3c, 0x25, 0x75, 0x7e, 0x80, 0xd5, 0x04, 0x14, 0x22, 0x46, 0xb4, 0x9b, 0x42, 0x47, 0x49,
|
||||
0xbd, 0x1f, 0x61, 0x35, 0x01, 0x7c, 0x02, 0xbd, 0x2c, 0x2c, 0xd4, 0xc2, 0x97, 0x0a, 0x58, 0xb4,
|
||||
0x40, 0xce, 0xe1, 0xab, 0x5c, 0xfc, 0x43, 0x1e, 0x29, 0xd1, 0xdb, 0xe0, 0x51, 0xca, 0xe0, 0x33,
|
||||
0x4c, 0xab, 0x64, 0x1b, 0x23, 0x1b, 0x33, 0x7d, 0xfe, 0xb4, 0x63, 0xb6, 0xb2, 0x9a, 0x2a, 0x3e,
|
||||
0x28, 0x99, 0x19, 0x68, 0x26, 0xd9, 0x52, 0x26, 0xf2, 0x06, 0x5d, 0x8b, 0xcc, 0x0e, 0x12, 0x5a,
|
||||
0x20, 0xef, 0x70, 0x34, 0x66, 0xf5, 0x79, 0x93, 0x50, 0x6d, 0x6f, 0xce, 0x0f, 0x83, 0xbc, 0x00,
|
||||
0x9f, 0xe8, 0x3c, 0xc9, 0x1c, 0x20, 0x66, 0x66, 0xcd, 0x27, 0x1e, 0xeb, 0x0f, 0xb0, 0x35, 0x07,
|
||||
0x7b, 0x98, 0xe4, 0xb1, 0x0e, 0xed, 0x16, 0x74, 0x92, 0x73, 0xe8, 0xb7, 0x3a, 0xba, 0xcc, 0x8f,
|
||||
0x05, 0x93, 0x7c, 0x13, 0x45, 0x32, 0xef, 0x6b, 0x22, 0x19, 0xb0, 0x85, 0xf0, 0xe6, 0x22, 0xcb,
|
||||
0xdc, 0x4e, 0x3c, 0xd6, 0xbb, 0x84, 0x79, 0x00, 0xeb, 0x67, 0xec, 0x3a, 0xd5, 0x2c, 0x67, 0x5a,
|
||||
0x5b, 0x4e, 0xbb, 0xfb, 0x11, 0x48, 0xf0, 0xc9, 0x7e, 0xab, 0xfe, 0x72, 0xc0, 0x3b, 0xbe, 0x1c,
|
||||
0xc9, 0x09, 0x2d, 0x90, 0x53, 0x58, 0x4b, 0x42, 0x4f, 0xf2, 0x15, 0x46, 0x97, 0x85, 0x8b, 0x5b,
|
||||
0xad, 0xac, 0x2d, 0x3d, 0x07, 0x0b, 0xe4, 0x57, 0xd0, 0x50, 0x20, 0x22, 0xd9, 0x3f, 0xe7, 0x58,
|
||||
0x4b, 0x45, 0xb2, 0x0f, 0xb5, 0xe8, 0x23, 0x40, 0xd7, 0x47, 0xea, 0x9b, 0x20, 0xad, 0x71, 0x00,
|
||||
0xcd, 0x0e, 0xb3, 0xfb, 0xd2, 0xbd, 0x9a, 0x3d, 0xf8, 0x6c, 0xc6, 0xa5, 0x94, 0x1f, 0x43, 0xf5,
|
||||
0x8c, 0x5d, 0x63, 0x32, 0x11, 0xbd, 0x85, 0x44, 0x2b, 0x4e, 0x60, 0x58, 0xa4, 0xa7, 0x91, 0x6c,
|
||||
0x97, 0xfb, 0x7d, 0x26, 0x84, 0xeb, 0x0d, 0x32, 0x35, 0x42, 0xcb, 0x3f, 0x85, 0xd5, 0x50, 0x03,
|
||||
0x67, 0xe3, 0x6d, 0xc2, 0x21, 0x7a, 0xc8, 0x8f, 0x65, 0x2a, 0x5c, 0x0d, 0x51, 0x35, 0xc1, 0xce,
|
||||
0x1f, 0xff, 0x06, 0x48, 0x07, 0xfe, 0x04, 0xea, 0x69, 0x08, 0x4e, 0xee, 0xeb, 0xe4, 0xcc, 0x02,
|
||||
0xe6, 0x69, 0xfd, 0x67, 0xd0, 0x98, 0x01, 0x55, 0x41, 0xd3, 0xc9, 0xc3, 0x5a, 0xe9, 0x70, 0x2d,
|
||||
0x20, 0x67, 0xec, 0x3a, 0x5d, 0x20, 0x5f, 0xeb, 0xa7, 0x9d, 0x87, 0x36, 0x83, 0x89, 0x39, 0x03,
|
||||
0xfd, 0x30, 0x5f, 0x9b, 0x99, 0x68, 0xcb, 0x24, 0x6d, 0x6c, 0xf0, 0x73, 0x90, 0x58, 0x3a, 0xbc,
|
||||
0xa7, 0x60, 0x4c, 0xd3, 0xe7, 0x3f, 0xea, 0xcf, 0x29, 0x03, 0xbb, 0xb0, 0x12, 0xe4, 0xa7, 0x9e,
|
||||
0x0e, 0xf1, 0x91, 0x9f, 0x98, 0x01, 0x47, 0x4b, 0xbf, 0xaf, 0xe0, 0x9f, 0xdf, 0x7f, 0x07, 0x00,
|
||||
0x00, 0xff, 0xff, 0x71, 0xbc, 0xd9, 0x84, 0x28, 0x16, 0x00, 0x00,
|
||||
// 1830 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xeb, 0x72, 0x1b, 0xb7,
|
||||
0x15, 0xe6, 0xc5, 0x94, 0xc9, 0xa3, 0x2b, 0x61, 0x99, 0xdd, 0xd0, 0xb2, 0x4d, 0x23, 0x8e, 0x47,
|
||||
0x99, 0x4e, 0x15, 0x67, 0x9b, 0x49, 0x32, 0xa3, 0xd6, 0x89, 0x14, 0xca, 0xb2, 0x62, 0x47, 0x66,
|
||||
0x96, 0xb5, 0xda, 0xe9, 0xf4, 0xcf, 0x86, 0x8b, 0xd0, 0x5b, 0x53, 0xbb, 0x0c, 0x00, 0x4a, 0xa6,
|
||||
0x7e, 0x77, 0xa6, 0x79, 0x82, 0x4e, 0x7f, 0xf6, 0x39, 0xfa, 0x12, 0x7d, 0xa5, 0x0e, 0x0e, 0xb0,
|
||||
0x57, 0xee, 0x52, 0xd5, 0xb4, 0xd3, 0x7f, 0x7b, 0x0e, 0xce, 0x0d, 0xc0, 0xb9, 0x7c, 0x58, 0x68,
|
||||
0x0b, 0xf7, 0x93, 0x29, 0x0f, 0x65, 0xf8, 0x89, 0x70, 0xf7, 0xf0, 0x83, 0xd4, 0x84, 0xdb, 0xbd,
|
||||
0x3b, 0x0a, 0x39, 0x33, 0x0b, 0xea, 0x53, 0x2f, 0xd1, 0x1e, 0x6c, 0x38, 0x6c, 0xec, 0x0b, 0xc9,
|
||||
0x5d, 0xe9, 0x87, 0xc1, 0x49, 0x9f, 0x6c, 0x40, 0xcd, 0xf7, 0xac, 0x6a, 0xaf, 0xba, 0x5b, 0x77,
|
||||
0x6a, 0xbe, 0x47, 0x1f, 0x00, 0x7c, 0x3b, 0x7c, 0x7d, 0xfa, 0x7b, 0xf6, 0xc3, 0x4b, 0x36, 0x27,
|
||||
0x5b, 0x50, 0xff, 0xf3, 0xe5, 0x3b, 0x5c, 0x5e, 0x73, 0xd4, 0x27, 0x7d, 0x04, 0x9b, 0x07, 0x33,
|
||||
0xf9, 0x36, 0xe4, 0xfe, 0xd5, 0xa2, 0x89, 0x16, 0x9a, 0xf8, 0x67, 0x15, 0x1e, 0x1c, 0x33, 0x39,
|
||||
0x60, 0x81, 0xe7, 0x07, 0xe3, 0x8c, 0xb4, 0xc3, 0x7e, 0x9a, 0x31, 0x21, 0xc9, 0x13, 0xd8, 0xe0,
|
||||
0x99, 0x38, 0x4c, 0x04, 0x39, 0xae, 0x92, 0xf3, 0x3d, 0x16, 0x48, 0xff, 0x47, 0x9f, 0xf1, 0xdf,
|
||||
0xcd, 0xa7, 0xcc, 0xaa, 0xa1, 0x9b, 0x1c, 0x97, 0xec, 0xc2, 0x66, 0xc2, 0x39, 0x73, 0x27, 0x33,
|
||||
0x66, 0xd5, 0x51, 0x30, 0xcf, 0x26, 0x0f, 0x00, 0x2e, 0xdc, 0x89, 0xef, 0xbd, 0x09, 0xa4, 0x3f,
|
||||
0xb1, 0x6e, 0xa1, 0xd7, 0x14, 0x87, 0x0a, 0xb8, 0x7f, 0xcc, 0xe4, 0x99, 0x62, 0x64, 0x22, 0x17,
|
||||
0x37, 0x0d, 0xdd, 0x82, 0xdb, 0x5e, 0x78, 0xee, 0xfa, 0x81, 0xb0, 0x6a, 0xbd, 0xfa, 0x6e, 0xcb,
|
||||
0x89, 0x48, 0x75, 0xa8, 0x41, 0x78, 0x89, 0x01, 0xd6, 0x1d, 0xf5, 0x49, 0xff, 0x51, 0x85, 0x3b,
|
||||
0x05, 0x2e, 0xc9, 0x97, 0xd0, 0xc0, 0xd0, 0xac, 0x6a, 0xaf, 0xbe, 0xbb, 0x6a, 0xd3, 0x3d, 0xe1,
|
||||
0xee, 0x15, 0xc8, 0xed, 0x7d, 0xe7, 0x4e, 0x8f, 0x26, 0xec, 0x9c, 0x05, 0xd2, 0xd1, 0x0a, 0xdd,
|
||||
0xd7, 0x00, 0x09, 0x93, 0x74, 0x60, 0x45, 0x3b, 0x37, 0xb7, 0x64, 0x28, 0xf2, 0x31, 0x34, 0xdc,
|
||||
0x99, 0x7c, 0x7b, 0x85, 0xa7, 0xba, 0x6a, 0xdf, 0xd9, 0xc3, 0x54, 0xc9, 0xde, 0x98, 0x96, 0xa0,
|
||||
0xff, 0xaa, 0x41, 0xfb, 0x1b, 0xc6, 0xd5, 0x51, 0x8e, 0x5c, 0xc9, 0x86, 0xd2, 0x95, 0x33, 0xa1,
|
||||
0x0c, 0x0b, 0xc6, 0x7d, 0x77, 0x12, 0x19, 0xd6, 0x14, 0xf2, 0x51, 0xc2, 0x5c, 0x83, 0xa1, 0xd4,
|
||||
0x3d, 0x85, 0x23, 0x31, 0x7d, 0xe5, 0x0a, 0xf9, 0x66, 0xea, 0xb9, 0x92, 0x79, 0xe6, 0x0a, 0xf2,
|
||||
0x6c, 0xd2, 0x83, 0x55, 0xce, 0x2e, 0xc2, 0x77, 0xcc, 0xeb, 0xbb, 0x92, 0x59, 0x0d, 0x94, 0x4a,
|
||||
0xb3, 0xc8, 0x63, 0x58, 0x37, 0xa4, 0xc3, 0x5c, 0x11, 0x06, 0xd6, 0x0a, 0xca, 0x64, 0x99, 0xe4,
|
||||
0x33, 0xb8, 0x3b, 0x71, 0x85, 0x3c, 0x7a, 0x3f, 0xf5, 0xf5, 0xd5, 0x9c, 0xba, 0xe3, 0x21, 0x0b,
|
||||
0xa4, 0x75, 0x1b, 0xa5, 0x8b, 0x17, 0x09, 0x85, 0x35, 0x15, 0x90, 0xc3, 0xc4, 0x34, 0x0c, 0x04,
|
||||
0xb3, 0x9a, 0x58, 0x00, 0x19, 0x1e, 0xe9, 0x42, 0x33, 0x08, 0xe5, 0xc1, 0x8f, 0x92, 0x71, 0xab,
|
||||
0x85, 0xc6, 0x62, 0x9a, 0xec, 0x40, 0xcb, 0x17, 0x68, 0x96, 0x79, 0x16, 0xf4, 0xaa, 0xbb, 0x4d,
|
||||
0x27, 0x61, 0x7c, 0x7b, 0xab, 0x59, 0xdb, 0xaa, 0xd3, 0x1e, 0xac, 0x0c, 0x93, 0xd3, 0x2a, 0x38,
|
||||
0x45, 0xba, 0x0f, 0x0d, 0xc7, 0x0d, 0xc6, 0xe8, 0x8a, 0xb9, 0x7c, 0xe2, 0x33, 0x21, 0x4d, 0xb6,
|
||||
0xc5, 0xb4, 0x52, 0x9e, 0xb8, 0x52, 0xad, 0xd4, 0x70, 0xc5, 0x50, 0xf4, 0x3e, 0x34, 0xbe, 0x09,
|
||||
0x67, 0x81, 0x24, 0xdb, 0xd0, 0x18, 0xa9, 0x0f, 0xa3, 0xa9, 0x09, 0xfa, 0x07, 0x78, 0x88, 0xcb,
|
||||
0xa9, 0x3b, 0x15, 0x87, 0xf3, 0x53, 0xf7, 0x9c, 0xc5, 0x99, 0xfe, 0x10, 0x1a, 0x5c, 0xb9, 0x47,
|
||||
0xc5, 0x55, 0xbb, 0xa5, 0xb2, 0x0f, 0xe3, 0x71, 0x34, 0x5f, 0x59, 0x0e, 0x94, 0x82, 0x49, 0x70,
|
||||
0x4d, 0xd0, 0xbf, 0x56, 0x61, 0x0d, 0x4d, 0x1b, 0x73, 0xe4, 0x2b, 0x58, 0x1b, 0xa5, 0x68, 0x93,
|
||||
0xcc, 0xf7, 0x94, 0xb9, 0xb4, 0x5c, 0x3a, 0x8b, 0x33, 0x0a, 0xdd, 0xcf, 0x33, 0xc9, 0x4c, 0xe0,
|
||||
0x96, 0x72, 0x64, 0xce, 0x0a, 0xbf, 0x93, 0x3d, 0xd6, 0xd2, 0x7b, 0x1c, 0xc0, 0x7d, 0x74, 0x90,
|
||||
0x6e, 0x79, 0xe2, 0x70, 0x7e, 0x32, 0x88, 0x76, 0xa8, 0x3a, 0xd7, 0xd4, 0x74, 0xb7, 0x9a, 0x3f,
|
||||
0x4d, 0x76, 0x5c, 0x2b, 0xde, 0x31, 0xfd, 0xb9, 0x0a, 0x8f, 0xd0, 0xe4, 0x49, 0x70, 0xf1, 0xdf,
|
||||
0xb7, 0x88, 0x2e, 0x34, 0xdf, 0x86, 0x42, 0xe2, 0x6e, 0x74, 0x5f, 0x8b, 0xe9, 0x24, 0x94, 0x7a,
|
||||
0x49, 0x28, 0x43, 0x20, 0x18, 0xc9, 0x6b, 0xee, 0x31, 0x1e, 0xbb, 0xde, 0x81, 0x96, 0x3b, 0xc2,
|
||||
0xdd, 0xc7, 0x5e, 0x13, 0xc6, 0xf5, 0xfb, 0x7b, 0x01, 0xdb, 0x68, 0xf4, 0xf9, 0xf7, 0xfd, 0xd3,
|
||||
0x21, 0x93, 0xb1, 0xd9, 0x0e, 0xac, 0x5c, 0xfa, 0x81, 0x17, 0x5e, 0x1a, 0x9b, 0x86, 0x2a, 0x6f,
|
||||
0x72, 0xf4, 0x29, 0x6c, 0x1b, 0x23, 0x47, 0xef, 0x7d, 0x91, 0x58, 0x4a, 0x69, 0x54, 0xb3, 0x1a,
|
||||
0x03, 0xe8, 0x0d, 0x38, 0xbb, 0xf0, 0xc3, 0x99, 0x48, 0x25, 0x65, 0x56, 0xbb, 0xac, 0x91, 0x6d,
|
||||
0x43, 0x83, 0xb3, 0xf1, 0x49, 0x3f, 0xba, 0x7f, 0x24, 0x54, 0x85, 0x69, 0x75, 0xa5, 0xc7, 0xf0,
|
||||
0x0b, 0xf5, 0x9a, 0x8e, 0xa1, 0xa8, 0x84, 0xad, 0x03, 0xcf, 0xd3, 0x65, 0x18, 0xf9, 0x88, 0x6d,
|
||||
0x55, 0x53, 0xb6, 0x52, 0x35, 0x5a, 0xcb, 0x74, 0x3a, 0x0b, 0x6e, 0x8f, 0x38, 0xc3, 0x4e, 0xa6,
|
||||
0x1b, 0x7a, 0x44, 0xaa, 0x15, 0x86, 0x05, 0x2f, 0x4c, 0x8f, 0x8b, 0x48, 0x55, 0x21, 0x77, 0x0f,
|
||||
0x3c, 0x2f, 0xb5, 0xcb, 0xc8, 0xf7, 0x16, 0xd4, 0x3d, 0xc6, 0xa3, 0x79, 0xeb, 0x31, 0x5e, 0xbc,
|
||||
0x33, 0x55, 0x03, 0xaa, 0x17, 0xa1, 0xcb, 0x35, 0x07, 0xbf, 0x55, 0x84, 0xbe, 0x10, 0xb3, 0xb8,
|
||||
0xa5, 0x1a, 0x4a, 0x65, 0x19, 0x7e, 0xf1, 0x93, 0xbe, 0x69, 0xa3, 0x31, 0x4d, 0x9f, 0x42, 0x27,
|
||||
0x1f, 0x88, 0xe9, 0x6e, 0xea, 0xa4, 0xfd, 0x71, 0xd4, 0x70, 0xd4, 0x49, 0x23, 0x45, 0x07, 0xb0,
|
||||
0x86, 0x19, 0x97, 0x2e, 0xa1, 0x14, 0x7e, 0x20, 0x4f, 0xe1, 0xce, 0x4c, 0xb0, 0x33, 0x3b, 0x5b,
|
||||
0x19, 0x18, 0x7d, 0xd3, 0x29, 0x5a, 0xa2, 0xaf, 0x80, 0x46, 0x13, 0x17, 0x2d, 0x17, 0xd7, 0x54,
|
||||
0xde, 0x4f, 0x07, 0x56, 0xdc, 0xd1, 0x48, 0xc6, 0x07, 0x63, 0x28, 0x3a, 0x87, 0x5f, 0x1c, 0x33,
|
||||
0x5d, 0x14, 0xcf, 0x43, 0x9e, 0xe9, 0x67, 0x89, 0x4a, 0x35, 0xad, 0x52, 0xdc, 0xc6, 0xca, 0x36,
|
||||
0x52, 0x2f, 0xdf, 0xc8, 0xdf, 0xab, 0x60, 0x1d, 0x33, 0xf9, 0x7f, 0x83, 0x0d, 0x6a, 0x9a, 0x72,
|
||||
0xf6, 0xd3, 0xcc, 0xe7, 0x26, 0x96, 0x2b, 0x9d, 0x69, 0x4d, 0x27, 0xcf, 0xa6, 0x7f, 0xab, 0xc2,
|
||||
0x46, 0x0e, 0x5b, 0xfc, 0x3a, 0x9a, 0xfd, 0xba, 0x1d, 0xdf, 0x57, 0xbd, 0x60, 0x09, 0xac, 0x40,
|
||||
0xd9, 0xff, 0x3d, 0xac, 0x78, 0x05, 0x0f, 0x0f, 0x3c, 0xaf, 0x08, 0x2a, 0xc6, 0x27, 0xf7, 0x71,
|
||||
0x36, 0xd0, 0x65, 0xd6, 0x1e, 0xc3, 0x56, 0x0e, 0x9c, 0xe2, 0xb1, 0xf9, 0x5e, 0xd4, 0x6c, 0xd4,
|
||||
0x27, 0xa5, 0x0b, 0x52, 0xf6, 0x02, 0x0c, 0xfe, 0x08, 0xda, 0x19, 0x19, 0x3b, 0x67, 0xaa, 0xae,
|
||||
0x4d, 0x5d, 0x81, 0xe5, 0x20, 0xdc, 0x28, 0xa8, 0xe5, 0x25, 0xd8, 0x88, 0x6b, 0xc0, 0x62, 0x32,
|
||||
0x57, 0x53, 0xaa, 0xa6, 0x15, 0xf4, 0x31, 0x17, 0x8c, 0xdf, 0xaa, 0x76, 0x79, 0x84, 0x41, 0x6e,
|
||||
0x61, 0xad, 0xc7, 0x34, 0xfd, 0x4b, 0x0d, 0x76, 0x9e, 0xfb, 0x81, 0x3b, 0xf1, 0xaf, 0x58, 0x21,
|
||||
0xc8, 0x2e, 0x28, 0x19, 0x03, 0xca, 0x6a, 0x19, 0x50, 0x96, 0x6a, 0x54, 0xf5, 0x4c, 0xa3, 0xc2,
|
||||
0x69, 0x22, 0x25, 0x3b, 0x9f, 0x46, 0x40, 0xad, 0xe5, 0x24, 0x0c, 0xd2, 0x87, 0x36, 0x0e, 0x41,
|
||||
0xe3, 0x74, 0x14, 0x72, 0x4f, 0x58, 0x0d, 0xbc, 0xa4, 0x8e, 0xbe, 0xa4, 0xb3, 0xdc, 0xb2, 0xb3,
|
||||
0xa8, 0x40, 0x9e, 0xc1, 0x66, 0xc2, 0x3c, 0xe2, 0x3c, 0xe4, 0x08, 0xe4, 0x56, 0xed, 0x6d, 0x6d,
|
||||
0x63, 0xc0, 0xc3, 0x1f, 0x26, 0xec, 0xbc, 0xcf, 0xa4, 0xeb, 0x4f, 0x84, 0x93, 0x17, 0xa6, 0xef,
|
||||
0x61, 0xfb, 0xc0, 0xf3, 0x0e, 0x27, 0xe1, 0xe8, 0x1d, 0xf3, 0x5e, 0xb2, 0x79, 0x6a, 0xd0, 0xbc,
|
||||
0x63, 0xf3, 0x17, 0xae, 0x78, 0x6b, 0xda, 0x69, 0x44, 0xaa, 0x7a, 0x77, 0x3d, 0x8f, 0x79, 0x51,
|
||||
0x4b, 0x45, 0x02, 0x4f, 0x27, 0x9c, 0xf1, 0x11, 0x8b, 0x21, 0x2b, 0x52, 0xd8, 0xe0, 0xc3, 0x73,
|
||||
0x95, 0xef, 0xe6, 0x04, 0x22, 0x92, 0xfe, 0x0a, 0xda, 0x2f, 0xd9, 0xdc, 0x78, 0xbe, 0xd6, 0xad,
|
||||
0xfd, 0xf3, 0x1d, 0xd8, 0x1a, 0xca, 0x90, 0xbb, 0xe3, 0xe8, 0xba, 0xe4, 0x9c, 0xec, 0xc3, 0xe6,
|
||||
0x31, 0xcb, 0x00, 0x14, 0x42, 0x70, 0x2a, 0x67, 0xba, 0x42, 0x97, 0xe8, 0xb3, 0x48, 0x73, 0x69,
|
||||
0x85, 0xfc, 0x06, 0xb6, 0x73, 0xca, 0x87, 0x73, 0xf5, 0x6a, 0xdb, 0x50, 0x16, 0x92, 0x57, 0x5c,
|
||||
0x89, 0xf6, 0xa7, 0xb0, 0x71, 0xcc, 0xd2, 0xf8, 0x8f, 0x80, 0xd2, 0xd3, 0xc3, 0xb0, 0xdb, 0xd6,
|
||||
0x3a, 0xa9, 0x65, 0x5a, 0x21, 0x9f, 0x41, 0x5b, 0x3d, 0xec, 0x38, 0x1b, 0xdd, 0x44, 0x6b, 0x1f,
|
||||
0xc3, 0x5c, 0x7c, 0x3c, 0xa4, 0x15, 0xef, 0x22, 0x1a, 0xcc, 0x8b, 0xd0, 0x0a, 0x19, 0x82, 0x55,
|
||||
0x86, 0x53, 0xc9, 0x87, 0x31, 0x84, 0x2c, 0x47, 0xb1, 0xdd, 0xad, 0x3c, 0xce, 0xa4, 0x15, 0xf2,
|
||||
0x02, 0x3a, 0xc5, 0xc0, 0x90, 0x3c, 0x8a, 0xa5, 0xcb, 0x40, 0x63, 0xb7, 0x15, 0x8b, 0xd0, 0x0a,
|
||||
0xf9, 0x0e, 0xee, 0x95, 0x48, 0x23, 0x42, 0xbe, 0xa9, 0x39, 0x1b, 0x56, 0x53, 0xa0, 0x8e, 0x74,
|
||||
0xe2, 0xb5, 0x0c, 0xca, 0xcb, 0xea, 0x7c, 0x0e, 0xeb, 0x19, 0xcc, 0x46, 0xac, 0x78, 0x35, 0x07,
|
||||
0xe3, 0xb2, 0x7a, 0x5f, 0xc0, 0x7a, 0x06, 0xa1, 0x69, 0xbd, 0x22, 0xd0, 0xd6, 0xc5, 0x9b, 0xd2,
|
||||
0x2c, 0x5a, 0x21, 0xaf, 0xe1, 0x83, 0x52, 0xa0, 0x46, 0x1e, 0x2b, 0xd1, 0xeb, 0x70, 0x5c, 0xce,
|
||||
0xe0, 0xd7, 0x98, 0x56, 0xd9, 0x7e, 0x4b, 0xb6, 0x17, 0x06, 0xd2, 0x49, 0xdf, 0xee, 0x16, 0x75,
|
||||
0x7f, 0xbc, 0x50, 0xb2, 0x30, 0x79, 0x6d, 0xb2, 0xa3, 0x4c, 0x94, 0x4d, 0xe4, 0x2e, 0x59, 0x9c,
|
||||
0x78, 0xb4, 0x42, 0xde, 0xe0, 0x0c, 0x2f, 0x1a, 0x48, 0x36, 0xa1, 0xc6, 0xde, 0x92, 0x3f, 0x1b,
|
||||
0x65, 0x01, 0x3e, 0x33, 0x79, 0x52, 0x38, 0xe9, 0xec, 0xc2, 0x9a, 0xcf, 0x5c, 0xd6, 0x9f, 0x60,
|
||||
0x67, 0x09, 0x48, 0xb2, 0xc9, 0x13, 0x13, 0xda, 0x35, 0x30, 0xaa, 0x64, 0xd3, 0xdf, 0x9b, 0xe8,
|
||||
0x0a, 0x5f, 0x35, 0x36, 0xf9, 0x28, 0x8e, 0x64, 0xd9, 0xb3, 0x27, 0x1b, 0xb0, 0x83, 0x38, 0xec,
|
||||
0xac, 0xc8, 0xdc, 0xa3, 0x74, 0xac, 0x37, 0x09, 0xf3, 0x53, 0x80, 0xa4, 0xe1, 0x12, 0x6c, 0x19,
|
||||
0x0b, 0x0d, 0x38, 0x97, 0x5a, 0xfb, 0xb0, 0x79, 0xca, 0x2e, 0x73, 0xfd, 0x75, 0xa1, 0x1b, 0x96,
|
||||
0x74, 0xc8, 0x2f, 0x80, 0xe8, 0xdf, 0x11, 0xd7, 0xea, 0xaf, 0x6a, 0xde, 0xd1, 0xf9, 0x54, 0xce,
|
||||
0x69, 0x85, 0x9c, 0xc0, 0x46, 0x16, 0x56, 0x93, 0x0f, 0x70, 0x43, 0x45, 0x98, 0xbf, 0xdb, 0x2d,
|
||||
0x5a, 0x32, 0x33, 0xbe, 0x42, 0x7e, 0x0b, 0x6d, 0x05, 0x90, 0xb2, 0x2d, 0x77, 0x89, 0xb5, 0x5c,
|
||||
0x24, 0x4f, 0xa1, 0x15, 0x3f, 0x70, 0x4c, 0x49, 0xe5, 0xde, 0x3b, 0x79, 0x8d, 0x7d, 0xe8, 0xf4,
|
||||
0x99, 0x3b, 0x92, 0xfe, 0xc5, 0xe2, 0xc6, 0x17, 0x93, 0x34, 0xa7, 0xfc, 0x04, 0x9a, 0xa7, 0xec,
|
||||
0x12, 0xf3, 0x8f, 0x98, 0x25, 0x24, 0xba, 0x69, 0x02, 0xc3, 0x22, 0x43, 0x83, 0xd2, 0x07, 0x3c,
|
||||
0x1c, 0x31, 0x21, 0xfc, 0x60, 0x5c, 0xa8, 0x11, 0x59, 0xfe, 0x25, 0xac, 0x47, 0x1a, 0x38, 0xf7,
|
||||
0xaf, 0x13, 0x8e, 0x90, 0x51, 0x79, 0x2c, 0x89, 0x70, 0x33, 0x7a, 0x31, 0x10, 0x1c, 0x16, 0xe9,
|
||||
0xf7, 0x4d, 0x3e, 0xf0, 0x67, 0xb0, 0x95, 0x7f, 0x5e, 0x90, 0x7b, 0x26, 0x9f, 0x8b, 0x1e, 0x1d,
|
||||
0x79, 0xfd, 0xaf, 0xa1, 0xbd, 0x00, 0x18, 0x75, 0x9f, 0x2a, 0xc3, 0x91, 0xf9, 0x70, 0x1d, 0x20,
|
||||
0xa7, 0xec, 0x32, 0x5f, 0x53, 0x1f, 0x9a, 0xab, 0x5d, 0x86, 0xa4, 0xf5, 0x90, 0x5d, 0x80, 0xb5,
|
||||
0x98, 0xaf, 0x9d, 0x42, 0x24, 0x69, 0x93, 0x1e, 0xce, 0x84, 0x25, 0x28, 0x33, 0x1f, 0xde, 0x57,
|
||||
0x60, 0x25, 0xe9, 0xf3, 0x1f, 0xb5, 0xf4, 0x9c, 0x81, 0x5d, 0x58, 0xd3, 0xf9, 0x69, 0x06, 0x4a,
|
||||
0x1a, 0x25, 0x64, 0x6b, 0xfb, 0x4b, 0x58, 0xcf, 0x20, 0x3f, 0x3d, 0xc0, 0x8a, 0xc0, 0x60, 0xce,
|
||||
0xc7, 0xe1, 0xed, 0x3f, 0x36, 0xf0, 0x7f, 0xf8, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x26, 0xa2,
|
||||
0x44, 0x9d, 0x3e, 0x17, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
|
@ -1992,6 +2102,7 @@ type StorageAuthorityClient interface {
|
|||
GetValidOrderAuthorizations2(ctx context.Context, in *GetValidOrderAuthorizationsRequest, opts ...grpc.CallOption) (*Authorizations, error)
|
||||
CountInvalidAuthorizations2(ctx context.Context, in *CountInvalidAuthorizationsRequest, opts ...grpc.CallOption) (*Count, error)
|
||||
GetValidAuthorizations2(ctx context.Context, in *GetValidAuthorizationsRequest, opts ...grpc.CallOption) (*Authorizations, error)
|
||||
KeyBlocked(ctx context.Context, in *KeyBlockedRequest, opts ...grpc.CallOption) (*Exists, error)
|
||||
// Adders
|
||||
NewRegistration(ctx context.Context, in *proto1.Registration, opts ...grpc.CallOption) (*proto1.Registration, error)
|
||||
UpdateRegistration(ctx context.Context, in *proto1.Registration, opts ...grpc.CallOption) (*proto1.Empty, error)
|
||||
|
|
@ -2010,6 +2121,7 @@ type StorageAuthorityClient interface {
|
|||
FinalizeAuthorization2(ctx context.Context, in *FinalizeAuthorizationRequest, opts ...grpc.CallOption) (*proto1.Empty, error)
|
||||
DeactivateAuthorization2(ctx context.Context, in *AuthorizationID2, opts ...grpc.CallOption) (*proto1.Empty, error)
|
||||
SerialExists(ctx context.Context, in *Serial, opts ...grpc.CallOption) (*Exists, error)
|
||||
AddBlockedKey(ctx context.Context, in *AddBlockedKeyRequest, opts ...grpc.CallOption) (*proto1.Empty, error)
|
||||
}
|
||||
|
||||
type storageAuthorityClient struct {
|
||||
|
|
@ -2191,6 +2303,15 @@ func (c *storageAuthorityClient) GetValidAuthorizations2(ctx context.Context, in
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *storageAuthorityClient) KeyBlocked(ctx context.Context, in *KeyBlockedRequest, opts ...grpc.CallOption) (*Exists, error) {
|
||||
out := new(Exists)
|
||||
err := c.cc.Invoke(ctx, "/sa.StorageAuthority/KeyBlocked", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *storageAuthorityClient) NewRegistration(ctx context.Context, in *proto1.Registration, opts ...grpc.CallOption) (*proto1.Registration, error) {
|
||||
out := new(proto1.Registration)
|
||||
err := c.cc.Invoke(ctx, "/sa.StorageAuthority/NewRegistration", in, out, opts...)
|
||||
|
|
@ -2344,6 +2465,15 @@ func (c *storageAuthorityClient) SerialExists(ctx context.Context, in *Serial, o
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *storageAuthorityClient) AddBlockedKey(ctx context.Context, in *AddBlockedKeyRequest, opts ...grpc.CallOption) (*proto1.Empty, error) {
|
||||
out := new(proto1.Empty)
|
||||
err := c.cc.Invoke(ctx, "/sa.StorageAuthority/AddBlockedKey", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// StorageAuthorityServer is the server API for StorageAuthority service.
|
||||
type StorageAuthorityServer interface {
|
||||
// Getters
|
||||
|
|
@ -2368,6 +2498,7 @@ type StorageAuthorityServer interface {
|
|||
GetValidOrderAuthorizations2(context.Context, *GetValidOrderAuthorizationsRequest) (*Authorizations, error)
|
||||
CountInvalidAuthorizations2(context.Context, *CountInvalidAuthorizationsRequest) (*Count, error)
|
||||
GetValidAuthorizations2(context.Context, *GetValidAuthorizationsRequest) (*Authorizations, error)
|
||||
KeyBlocked(context.Context, *KeyBlockedRequest) (*Exists, error)
|
||||
// Adders
|
||||
NewRegistration(context.Context, *proto1.Registration) (*proto1.Registration, error)
|
||||
UpdateRegistration(context.Context, *proto1.Registration) (*proto1.Empty, error)
|
||||
|
|
@ -2386,6 +2517,7 @@ type StorageAuthorityServer interface {
|
|||
FinalizeAuthorization2(context.Context, *FinalizeAuthorizationRequest) (*proto1.Empty, error)
|
||||
DeactivateAuthorization2(context.Context, *AuthorizationID2) (*proto1.Empty, error)
|
||||
SerialExists(context.Context, *Serial) (*Exists, error)
|
||||
AddBlockedKey(context.Context, *AddBlockedKeyRequest) (*proto1.Empty, error)
|
||||
}
|
||||
|
||||
// UnimplementedStorageAuthorityServer can be embedded to have forward compatible implementations.
|
||||
|
|
@ -2449,6 +2581,9 @@ func (*UnimplementedStorageAuthorityServer) CountInvalidAuthorizations2(ctx cont
|
|||
func (*UnimplementedStorageAuthorityServer) GetValidAuthorizations2(ctx context.Context, req *GetValidAuthorizationsRequest) (*Authorizations, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetValidAuthorizations2 not implemented")
|
||||
}
|
||||
func (*UnimplementedStorageAuthorityServer) KeyBlocked(ctx context.Context, req *KeyBlockedRequest) (*Exists, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method KeyBlocked not implemented")
|
||||
}
|
||||
func (*UnimplementedStorageAuthorityServer) NewRegistration(ctx context.Context, req *proto1.Registration) (*proto1.Registration, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method NewRegistration not implemented")
|
||||
}
|
||||
|
|
@ -2500,6 +2635,9 @@ func (*UnimplementedStorageAuthorityServer) DeactivateAuthorization2(ctx context
|
|||
func (*UnimplementedStorageAuthorityServer) SerialExists(ctx context.Context, req *Serial) (*Exists, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SerialExists not implemented")
|
||||
}
|
||||
func (*UnimplementedStorageAuthorityServer) AddBlockedKey(ctx context.Context, req *AddBlockedKeyRequest) (*proto1.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddBlockedKey not implemented")
|
||||
}
|
||||
|
||||
func RegisterStorageAuthorityServer(s *grpc.Server, srv StorageAuthorityServer) {
|
||||
s.RegisterService(&_StorageAuthority_serviceDesc, srv)
|
||||
|
|
@ -2847,6 +2985,24 @@ func _StorageAuthority_GetValidAuthorizations2_Handler(srv interface{}, ctx cont
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _StorageAuthority_KeyBlocked_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(KeyBlockedRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(StorageAuthorityServer).KeyBlocked(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/sa.StorageAuthority/KeyBlocked",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(StorageAuthorityServer).KeyBlocked(ctx, req.(*KeyBlockedRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _StorageAuthority_NewRegistration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(proto1.Registration)
|
||||
if err := dec(in); err != nil {
|
||||
|
|
@ -3153,6 +3309,24 @@ func _StorageAuthority_SerialExists_Handler(srv interface{}, ctx context.Context
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _StorageAuthority_AddBlockedKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AddBlockedKeyRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(StorageAuthorityServer).AddBlockedKey(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/sa.StorageAuthority/AddBlockedKey",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(StorageAuthorityServer).AddBlockedKey(ctx, req.(*AddBlockedKeyRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _StorageAuthority_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "sa.StorageAuthority",
|
||||
HandlerType: (*StorageAuthorityServer)(nil),
|
||||
|
|
@ -3233,6 +3407,10 @@ var _StorageAuthority_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "GetValidAuthorizations2",
|
||||
Handler: _StorageAuthority_GetValidAuthorizations2_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "KeyBlocked",
|
||||
Handler: _StorageAuthority_KeyBlocked_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "NewRegistration",
|
||||
Handler: _StorageAuthority_NewRegistration_Handler,
|
||||
|
|
@ -3301,6 +3479,10 @@ var _StorageAuthority_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "SerialExists",
|
||||
Handler: _StorageAuthority_SerialExists_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddBlockedKey",
|
||||
Handler: _StorageAuthority_AddBlockedKey_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "sa/proto/sa.proto",
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ service StorageAuthority {
|
|||
rpc GetValidOrderAuthorizations2(GetValidOrderAuthorizationsRequest) returns (Authorizations) {}
|
||||
rpc CountInvalidAuthorizations2(CountInvalidAuthorizationsRequest) returns (Count) {}
|
||||
rpc GetValidAuthorizations2(GetValidAuthorizationsRequest) returns (Authorizations) {}
|
||||
rpc KeyBlocked(KeyBlockedRequest) returns (Exists) {}
|
||||
// Adders
|
||||
rpc NewRegistration(core.Registration) returns (core.Registration) {}
|
||||
rpc UpdateRegistration(core.Registration) returns (core.Empty) {}
|
||||
|
|
@ -46,6 +47,7 @@ service StorageAuthority {
|
|||
rpc FinalizeAuthorization2(FinalizeAuthorizationRequest) returns (core.Empty) {}
|
||||
rpc DeactivateAuthorization2(AuthorizationID2) returns (core.Empty) {}
|
||||
rpc SerialExists(Serial) returns (Exists) {}
|
||||
rpc AddBlockedKey(AddBlockedKeyRequest) returns (core.Empty) {}
|
||||
}
|
||||
|
||||
message RegistrationID {
|
||||
|
|
@ -242,3 +244,14 @@ message FinalizeAuthorizationRequest {
|
|||
repeated core.ValidationRecord validationRecords = 5;
|
||||
optional core.ProblemDetails validationError = 6;
|
||||
}
|
||||
|
||||
message AddBlockedKeyRequest {
|
||||
optional bytes keyHash = 1;
|
||||
optional int64 added = 2; // Unix timestamp (nanoseconds)
|
||||
optional string source = 3;
|
||||
optional string comment = 4;
|
||||
}
|
||||
|
||||
message KeyBlockedRequest {
|
||||
optional bytes keyHash = 1;
|
||||
}
|
||||
|
|
|
|||
42
sa/sa.go
42
sa/sa.go
|
|
@ -1771,3 +1771,45 @@ func addKeyHash(db db.Inserter, cert *x509.Certificate) error {
|
|||
}
|
||||
return db.Insert(khm)
|
||||
}
|
||||
|
||||
// AddBlockedKey adds a key hash to the blockedKeys table
|
||||
func (ssa *SQLStorageAuthority) AddBlockedKey(ctx context.Context, req *sapb.AddBlockedKeyRequest) (*corepb.Empty, error) {
|
||||
if req == nil || req.KeyHash == nil || req.Added == nil || req.Source == nil {
|
||||
return nil, errIncompleteRequest
|
||||
}
|
||||
sourceInt, ok := stringToSourceInt[*req.Source]
|
||||
if !ok {
|
||||
return nil, errors.New("unknown source")
|
||||
}
|
||||
err := ssa.dbMap.Insert(&blockedKeyModel{
|
||||
KeyHash: req.KeyHash,
|
||||
Added: time.Unix(0, *req.Added),
|
||||
Source: sourceInt,
|
||||
Comment: req.Comment,
|
||||
})
|
||||
if err != nil {
|
||||
if db.IsDuplicate(err) {
|
||||
// Ignore duplicate inserts so multiple certs with the same key can
|
||||
// be revoked.
|
||||
return &corepb.Empty{}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &corepb.Empty{}, nil
|
||||
}
|
||||
|
||||
// KeyBlocked checks if a key, indicated by a hash, is present in the blockedKeys table
|
||||
func (ssa *SQLStorageAuthority) KeyBlocked(ctx context.Context, req *sapb.KeyBlockedRequest) (*sapb.Exists, error) {
|
||||
if req == nil || req.KeyHash == nil {
|
||||
return nil, errIncompleteRequest
|
||||
}
|
||||
exists := false
|
||||
if err := ssa.dbMap.SelectOne(&blockedKeyModel{}, `SELECT * FROM blockedKeys WHERE keyHash = ?`, req.KeyHash); err != nil {
|
||||
if db.IsNoRows(err) {
|
||||
return &sapb.Exists{Exists: &exists}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
exists = true
|
||||
return &sapb.Exists{Exists: &exists}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ import (
|
|||
"math/big"
|
||||
"math/bits"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -2247,3 +2249,75 @@ func TestSerialExists(t *testing.T) {
|
|||
test.AssertNotError(t, err, "SerialExists failed")
|
||||
test.AssertEquals(t, *resp.Exists, true)
|
||||
}
|
||||
|
||||
func TestBlockedKey(t *testing.T) {
|
||||
if !strings.HasSuffix(os.Getenv("BOULDER_CONFIG_DIR"), "config-next") {
|
||||
return
|
||||
}
|
||||
|
||||
sa, _, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
hashA := make([]byte, 32)
|
||||
hashA[0] = 1
|
||||
hashB := make([]byte, 32)
|
||||
hashB[0] = 2
|
||||
|
||||
added := time.Now().UnixNano()
|
||||
source := "API"
|
||||
_, err := sa.AddBlockedKey(context.Background(), &sapb.AddBlockedKeyRequest{
|
||||
KeyHash: hashA,
|
||||
Added: &added,
|
||||
Source: &source,
|
||||
})
|
||||
test.AssertNotError(t, err, "AddBlockedKey failed")
|
||||
_, err = sa.AddBlockedKey(context.Background(), &sapb.AddBlockedKeyRequest{
|
||||
KeyHash: hashA,
|
||||
Added: &added,
|
||||
Source: &source,
|
||||
})
|
||||
test.AssertNotError(t, err, "AddBlockedKey failed with duplicate insert")
|
||||
|
||||
comment := "testing comments"
|
||||
_, err = sa.AddBlockedKey(context.Background(), &sapb.AddBlockedKeyRequest{
|
||||
KeyHash: hashB,
|
||||
Added: &added,
|
||||
Source: &source,
|
||||
Comment: &comment,
|
||||
})
|
||||
test.AssertNotError(t, err, "AddBlockedKey failed")
|
||||
|
||||
exists, err := sa.KeyBlocked(context.Background(), &sapb.KeyBlockedRequest{
|
||||
KeyHash: hashA,
|
||||
})
|
||||
test.AssertNotError(t, err, "KeyBlocked failed")
|
||||
test.Assert(t, exists != nil, "*sapb.Exists is nil")
|
||||
test.Assert(t, *exists.Exists, "KeyBlocked returned false for blocked key")
|
||||
exists, err = sa.KeyBlocked(context.Background(), &sapb.KeyBlockedRequest{
|
||||
KeyHash: hashB,
|
||||
})
|
||||
test.AssertNotError(t, err, "KeyBlocked failed")
|
||||
test.Assert(t, exists != nil, "*sapb.Exists is nil")
|
||||
test.Assert(t, *exists.Exists, "KeyBlocked returned false for blocked key")
|
||||
exists, err = sa.KeyBlocked(context.Background(), &sapb.KeyBlockedRequest{
|
||||
KeyHash: []byte{5},
|
||||
})
|
||||
test.AssertNotError(t, err, "KeyBlocked failed")
|
||||
test.Assert(t, exists != nil, "*sapb.Exists is nil")
|
||||
test.Assert(t, !*exists.Exists, "KeyBlocked returned true for non-blocked key")
|
||||
}
|
||||
|
||||
func TestAddBlockedKeyUnknownSource(t *testing.T) {
|
||||
sa, _, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
added := int64(0)
|
||||
source := "heyo"
|
||||
_, err := sa.AddBlockedKey(context.Background(), &sapb.AddBlockedKeyRequest{
|
||||
KeyHash: []byte{1, 2, 3},
|
||||
Added: &added,
|
||||
Source: &source,
|
||||
})
|
||||
test.AssertError(t, err, "AddBlockedKey didn't fail with unknown source")
|
||||
test.AssertEquals(t, err.Error(), "unknown source")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,7 +137,8 @@
|
|||
"maxConcurrentRPCServerRequests": 100000,
|
||||
"orphanQueueDir": "/tmp/orphaned-certificates-a",
|
||||
"features": {
|
||||
"StoreIssuerInfo": true
|
||||
"StoreIssuerInfo": true,
|
||||
"BlockedKeyTable": true
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@
|
|||
"maxConcurrentRPCServerRequests": 100000,
|
||||
"orphanQueueDir": "/tmp/orphaned-certificates-b",
|
||||
"features": {
|
||||
"StoreIssuerInfo": true
|
||||
"StoreIssuerInfo": true,
|
||||
"BlockedKeyTable": true
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
]
|
||||
},
|
||||
"features": {
|
||||
"BlockedKeyTable": true
|
||||
},
|
||||
"CTLogGroups2": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@
|
|||
}
|
||||
},
|
||||
"features": {
|
||||
"StripDefaultSchemePort": true
|
||||
"StripDefaultSchemePort": true,
|
||||
"BlockedKeyTable": true
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@
|
|||
"features": {
|
||||
"MandatoryPOSTAsGET": true,
|
||||
"PrecertificateRevocation": true,
|
||||
"StripDefaultSchemePort": true
|
||||
"StripDefaultSchemePort": true,
|
||||
"BlockedKeyTable": true
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ func TestPrecertificateRevocation(t *testing.T) {
|
|||
tc.revokeClient.Account,
|
||||
cert,
|
||||
tc.revokeKey,
|
||||
ocsp.KeyCompromise)
|
||||
ocsp.Unspecified)
|
||||
test.AssertNotError(t, err, "revoking precert")
|
||||
|
||||
// Check the OCSP response for the precertificate again. It should now be
|
||||
|
|
@ -137,3 +137,33 @@ func TestPrecertificateRevocation(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRevokeWithKeyCompromise(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !strings.HasSuffix(os.Getenv("BOULDER_CONFIG_DIR"), "config-next") {
|
||||
return
|
||||
}
|
||||
|
||||
os.Setenv("DIRECTORY", "http://boulder:4001/directory")
|
||||
c, err := makeClient("mailto:example@letsencrypt.org")
|
||||
test.AssertNotError(t, err, "creating acme client")
|
||||
|
||||
certKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
test.AssertNotError(t, err, "failed to generate cert key")
|
||||
|
||||
res, err := authAndIssue(c, certKey, []string{random_domain()})
|
||||
test.AssertNotError(t, err, "authAndIssue failed")
|
||||
|
||||
err = c.RevokeCertificate(
|
||||
c.Account,
|
||||
res.certs[0],
|
||||
c.Account.PrivateKey,
|
||||
ocsp.KeyCompromise,
|
||||
)
|
||||
test.AssertNotError(t, err, "failed to revoke certificate")
|
||||
|
||||
// attempt to create a new account using the blacklisted key
|
||||
_, err = c.NewAccount(certKey, false, true)
|
||||
test.AssertError(t, err, "NewAccount didn't fail with a blacklisted key")
|
||||
test.AssertEquals(t, err.Error(), `acme: error code 400 "urn:ietf:params:acme:error:badPublicKey": public key is forbidden`)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ GRANT SELECT,INSERT ON orderToAuthz2 TO 'sa'@'localhost';
|
|||
GRANT INSERT,SELECT ON serials TO 'sa'@'localhost';
|
||||
GRANT SELECT,INSERT ON precertificates TO 'sa'@'localhost';
|
||||
GRANT SELECT,INSERT ON keyHashToSerial TO 'sa'@'localhost';
|
||||
GRANT SELECT,INSERT ON blockedKeys TO 'sa'@'localhost';
|
||||
|
||||
-- OCSP Responder
|
||||
GRANT SELECT ON certificateStatus TO 'ocsp_resp'@'localhost';
|
||||
|
|
|
|||
|
|
@ -528,7 +528,7 @@ func (wfe *WebFrontEndImpl) verifyPOST(ctx context.Context, logEvent *web.Reques
|
|||
// When looking up keys from the registrations DB, we can be confident they
|
||||
// are "good". But when we are verifying against any submitted key, we want
|
||||
// to check its quality before doing the verify.
|
||||
if err = wfe.keyPolicy.GoodKey(submittedKey.Key); err != nil {
|
||||
if err = wfe.keyPolicy.GoodKey(ctx, submittedKey.Key); err != nil {
|
||||
wfe.joseErrorCounter.WithLabelValues("JWKRejectedByGoodKey").Inc()
|
||||
return nil, nil, reg, probs.Malformed(err.Error())
|
||||
}
|
||||
|
|
@ -959,7 +959,7 @@ func (wfe *WebFrontEndImpl) NewCertificate(ctx context.Context, logEvent *web.Re
|
|||
// bytes on the wire, and (b) the CA logs all rejections as audit events, but
|
||||
// a bad key from the client is just a malformed request and doesn't need to
|
||||
// be audited.
|
||||
if err := wfe.keyPolicy.GoodKey(certificateRequest.CSR.PublicKey); err != nil {
|
||||
if err := wfe.keyPolicy.GoodKey(ctx, certificateRequest.CSR.PublicKey); err != nil {
|
||||
wfe.sendError(response, logEvent, probs.Malformed("Invalid key in certificate request :: %s", err), err)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -626,7 +626,7 @@ func (wfe *WebFrontEndImpl) validSelfAuthenticatedJWS(
|
|||
}
|
||||
|
||||
// If the key doesn't meet the GoodKey policy return a problem immediately
|
||||
if err := wfe.keyPolicy.GoodKey(pubKey.Key); err != nil {
|
||||
if err := wfe.keyPolicy.GoodKey(ctx, pubKey.Key); err != nil {
|
||||
wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "JWKRejectedByGoodKey"}).Inc()
|
||||
return nil, nil, probs.BadPublicKey(err.Error())
|
||||
}
|
||||
|
|
@ -689,6 +689,7 @@ type rolloverOperation struct {
|
|||
// account) and that the account field of the rollover object matches the
|
||||
// account that verified the outer JWS.
|
||||
func (wfe *WebFrontEndImpl) validKeyRollover(
|
||||
ctx context.Context,
|
||||
outerJWS *jose.JSONWebSignature,
|
||||
innerJWS *jose.JSONWebSignature,
|
||||
oldKey *jose.JSONWebKey,
|
||||
|
|
@ -701,7 +702,7 @@ func (wfe *WebFrontEndImpl) validKeyRollover(
|
|||
}
|
||||
|
||||
// If the key doesn't meet the GoodKey policy return a problem immediately
|
||||
if err := wfe.keyPolicy.GoodKey(jwk.Key); err != nil {
|
||||
if err := wfe.keyPolicy.GoodKey(ctx, jwk.Key); err != nil {
|
||||
wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "KeyRolloverJWKRejectedByGoodKey"}).Inc()
|
||||
return nil, probs.BadPublicKey(err.Error())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1789,7 +1789,7 @@ func (wfe *WebFrontEndImpl) KeyRollover(
|
|||
}
|
||||
|
||||
// Validate the inner JWS as a key rollover request for the outer JWS
|
||||
rolloverOperation, prob := wfe.validKeyRollover(outerJWS, innerJWS, oldKey, logEvent)
|
||||
rolloverOperation, prob := wfe.validKeyRollover(ctx, outerJWS, innerJWS, oldKey, logEvent)
|
||||
if prob != nil {
|
||||
wfe.sendError(response, logEvent, prob, nil)
|
||||
return
|
||||
|
|
|
|||
Loading…
Reference in New Issue