Skip to content

Commit

Permalink
fixup! Implement Certificate Revocation List
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielius1922 committed Sep 30, 2024
1 parent 2c958e9 commit 7d1bb1d
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 59 deletions.
4 changes: 2 additions & 2 deletions certificate-authority/pb/signingRecords.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ func (credential *CredentialStatus) Validate() error {
if _, ok := serial.SetString(credential.GetSerial(), 10); !ok {
return errors.New("invalid signing record credential certificate serial number")
}
if credential.GetIssuerId() == "" {
return errors.New("empty signing record credential issuer's ID")
if _, err := uuid.Parse(credential.GetIssuerId()); err != nil {
return fmt.Errorf("invalid signing record issuer's ID(%v): %w", credential.GetIssuerId(), err)
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion certificate-authority/service/cleanDatabase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestCertificateAuthorityServerCleanUpSigningRecords(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestCertificateAuthorityServerDeleteSigningRecords(t *testing.T) {
Date: constDate().UnixNano(),
ValidUntilDate: constDate().UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerId",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
}
type args struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestCertificateAuthorityServerGetSigningRecords(t *testing.T) {
Date: constDate().UnixNano(),
ValidUntilDate: constDate().UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerId",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
}
type args struct {
Expand Down
7 changes: 6 additions & 1 deletion certificate-authority/service/http/revocationList.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"crypto/rand"
"crypto/x509"
"errors"
"fmt"
"math/big"
"net/http"
"time"

"github.com/google/uuid"
"github.com/gorilla/mux"
"github.com/plgd-dev/hub/v2/certificate-authority/service/uri"
"github.com/plgd-dev/hub/v2/certificate-authority/store"
Expand All @@ -26,7 +28,10 @@ func errCannotGetRevocationList(err error) error {
func (requestHandler *RequestHandler) revocationList(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
issuerID := vars[uri.IssuerIDKey]

if _, err := uuid.Parse(issuerID); err != nil {
serverMux.WriteError(w, errCannotGetRevocationList(fmt.Errorf("invalid issuer's ID(%s): %w", issuerID, err)))
return
}
template := &x509.RevocationList{
NextUpdate: time.Now().Add(time.Minute * 10), // TODO: pridat konfiguraciu, default napr. 10min
}
Expand Down
88 changes: 76 additions & 12 deletions certificate-authority/service/http/revocationList_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,51 @@ import (
"context"
"crypto/x509"
"io"
"math/big"
"net/http"
"testing"
"time"

certAuthURI "github.com/plgd-dev/hub/v2/certificate-authority/service/uri"
"github.com/plgd-dev/hub/v2/certificate-authority/store"
"github.com/plgd-dev/hub/v2/certificate-authority/test"
httpgwTest "github.com/plgd-dev/hub/v2/http-gateway/test"
"github.com/plgd-dev/hub/v2/pkg/config/database"
pkgGrpc "github.com/plgd-dev/hub/v2/pkg/net/grpc"
pkgTime "github.com/plgd-dev/hub/v2/pkg/time"
"github.com/plgd-dev/hub/v2/test/config"
oauthTest "github.com/plgd-dev/hub/v2/test/oauth-server/test"
testService "github.com/plgd-dev/hub/v2/test/service"
"github.com/stretchr/testify/require"
)

func checkRevocationList(t *testing.T, crl *x509.RevocationList, certificates []*store.RevocationListCertificate) {
require.NotEmpty(t, crl.ThisUpdate)
require.NotEmpty(t, crl.NextUpdate)
expected := make([]x509.RevocationListEntry, 0, len(certificates))
for _, cert := range certificates {
var serial big.Int
_, ok := serial.SetString(cert.Serial, 10)
require.True(t, ok)
expected = append(expected, x509.RevocationListEntry{
SerialNumber: &serial,
RevocationTime: pkgTime.Unix(pkgTime.Unix(0, cert.Revocation).Unix(), 0).UTC(),
})
}
actual := make([]x509.RevocationListEntry, 0, len(crl.RevokedCertificateEntries))
for _, cert := range crl.RevokedCertificateEntries {
newCert := cert
newCert.Raw = nil
actual = append(actual, newCert)
}
require.Equal(t, expected, actual)
}

func TestRevocationList(t *testing.T) {
if config.ACTIVE_DATABASE() == database.CqlDB {
t.Skip("revocation list not supported for CqlDB")
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3600)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()

shutDown := testService.SetUpServices(context.Background(), t, testService.SetUpServicesOAuth|testService.SetUpServicesMachine2MachineOAuth)
Expand All @@ -36,17 +61,56 @@ func TestRevocationList(t *testing.T) {
token := oauthTest.GetDefaultAccessToken(t)
ctx = pkgGrpc.CtxWithToken(ctx, token)

test.AddRevocationListToStore(ctx, t, s, time.Now())
stored := test.AddRevocationListToStore(ctx, t, s, time.Now().Add(-2*time.Hour-time.Minute))

request := httpgwTest.NewRequest(http.MethodGet, certAuthURI.SigningRevocationList, nil).Host(config.CERTIFICATE_AUTHORITY_HTTP_HOST).AuthToken(token).AddIssuerID(test.GetIssuerID(2)).Build()
httpResp := httpgwTest.HTTPDo(t, request)
respBody, err := io.ReadAll(httpResp.Body)
require.NoError(t, err)
err = httpResp.Body.Close()
require.NoError(t, err)

_, err = x509.ParseRevocationList(respBody)
require.NoError(t, err)
type args struct {
issuer string
}
tests := []struct {
name string
args args
verifyCRL func(crl *x509.RevocationList)
wantErr bool
}{
{
name: "all certificates expired",
args: args{
issuer: test.GetIssuerID(0),
},
wantErr: true,
},
{
name: "valid",
args: args{
issuer: test.GetIssuerID(7),
},
verifyCRL: func(crl *x509.RevocationList) {
var certificates []*store.RevocationListCertificate
for _, issuerCerts := range stored {
if issuerCerts.Id != test.GetIssuerID(7) {
continue
}
certificates = append(certificates, issuerCerts.Certificates...)
}
checkRevocationList(t, crl, certificates)
},
},
}

// time.Sleep(time.Minute)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
request := httpgwTest.NewRequest(http.MethodGet, certAuthURI.SigningRevocationList, nil).Host(config.CERTIFICATE_AUTHORITY_HTTP_HOST).AuthToken(token).AddIssuerID(tt.args.issuer).Build()
httpResp := httpgwTest.HTTPDo(t, request)
respBody, err := io.ReadAll(httpResp.Body)
require.NoError(t, err)
err = httpResp.Body.Close()
require.NoError(t, err)
crl, err := x509.ParseRevocationList(respBody)
if tt.wantErr {
require.Error(t, err)
return
}
tt.verifyCRL(crl)
})
}
}
28 changes: 14 additions & 14 deletions certificate-authority/store/cqldb/signingRecords_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestStoreInsertSigningRecord(t *testing.T) {
Date: date.UnixNano() - 1,
ValidUntilDate: date.UnixNano() - 1,
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
}
tests := []struct {
Expand All @@ -53,7 +53,7 @@ func TestStoreInsertSigningRecord(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
},
},
Expand Down Expand Up @@ -108,7 +108,7 @@ func TestStoreUpdateSigningRecord(t *testing.T) {
Date: date.UnixNano() - 1,
ValidUntilDate: date.UnixNano() - 1,
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
}
tests := []struct {
Expand All @@ -128,7 +128,7 @@ func TestStoreUpdateSigningRecord(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
},
},
Expand All @@ -148,7 +148,7 @@ func TestStoreUpdateSigningRecord(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
},
},
Expand All @@ -167,7 +167,7 @@ func TestStoreUpdateSigningRecord(t *testing.T) {
Date: date1.UnixNano(),
ValidUntilDate: date1.UnixNano(),
Serial: big.NewInt(43).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
},
},
Expand Down Expand Up @@ -292,7 +292,7 @@ func TestStoreDeleteSigningRecord(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
})
require.NoError(t, err)
Expand All @@ -308,7 +308,7 @@ func TestStoreDeleteSigningRecord(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(43).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
})
require.NoError(t, err)
Expand All @@ -324,7 +324,7 @@ func TestStoreDeleteSigningRecord(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(44).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
})
require.NoError(t, err)
Expand Down Expand Up @@ -361,7 +361,7 @@ func TestStoreDeleteExpiredRecords(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
})
require.NoError(t, err)
Expand Down Expand Up @@ -406,7 +406,7 @@ func TestStoreLoadSigningRecords(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
},
{
Expand All @@ -421,7 +421,7 @@ func TestStoreLoadSigningRecords(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(43).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
},
{
Expand All @@ -436,7 +436,7 @@ func TestStoreLoadSigningRecords(t *testing.T) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(44).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
},
}
Expand Down Expand Up @@ -572,7 +572,7 @@ func BenchmarkSigningRecords(b *testing.B) {
Date: date.UnixNano(),
ValidUntilDate: date.UnixNano(),
Serial: big.NewInt(42).String(),
IssuerId: "issuerID",
IssuerId: "42424242-4242-4242-4242-424242424242",
},
})
}
Expand Down
3 changes: 3 additions & 0 deletions certificate-authority/store/mongodb/revocationList.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ func (s *Store) GetRevocationLists(ctx context.Context, query store.RevocationLi
},
}
projection := bson.M{
"_id": 1,
store.NumberKey: 1,
store.UpdatedAtKey: 1,
store.CertificatesKey: bson.M{
"$filter": bson.M{
"input": "$" + store.CertificatesKey,
Expand Down
19 changes: 9 additions & 10 deletions certificate-authority/store/mongodb/revocationList_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/google/uuid"
"github.com/plgd-dev/hub/v2/certificate-authority/store"
"github.com/plgd-dev/hub/v2/certificate-authority/test"
pkgTime "github.com/plgd-dev/hub/v2/pkg/time"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -64,8 +63,8 @@ func TestRevokeCertificates(t *testing.T) {
id: id,
certificate: &store.RevocationListCertificate{
Serial: "1",
Expiration: pkgTime.UnixNano(time.Now().Add(time.Hour)),
Revocation: time.Now().UnixNano(),
Expiration: time.Now().Add(time.Hour).Unix(),
Revocation: time.Now().Unix(),
},
},
},
Expand All @@ -75,8 +74,8 @@ func TestRevokeCertificates(t *testing.T) {
id: id,
certificate: &store.RevocationListCertificate{
Serial: "2",
Expiration: pkgTime.UnixNano(time.Now().Add(time.Hour)),
Revocation: time.Now().UnixNano(),
Expiration: time.Now().Add(time.Hour).Unix(),
Revocation: time.Now().Unix(),
},
},
},
Expand All @@ -86,8 +85,8 @@ func TestRevokeCertificates(t *testing.T) {
id: id,
certificate: &store.RevocationListCertificate{
Serial: "2",
Expiration: pkgTime.UnixNano(time.Now().Add(time.Hour)),
Revocation: time.Now().UnixNano(),
Expiration: time.Now().Add(time.Hour).Unix(),
Revocation: time.Now().Unix(),
},
},
wantErr: true,
Expand All @@ -98,8 +97,8 @@ func TestRevokeCertificates(t *testing.T) {
id: uuid.NewString(),
certificate: &store.RevocationListCertificate{
Serial: "2",
Expiration: pkgTime.UnixNano(time.Now().Add(time.Hour)),
Revocation: time.Now().UnixNano(),
Expiration: time.Now().Add(time.Hour).Unix(),
Revocation: time.Now().Unix(),
},
},
},
Expand Down Expand Up @@ -138,7 +137,7 @@ func TestGetRevocationLists(t *testing.T) {
{
name: "no matching ID",
args: args{
query: store.RevocationListsQuery{IssuerIdFilter: []string{"invalid"}},
query: store.RevocationListsQuery{IssuerIdFilter: []string{"00000000-0000-0000-0000-123456789012"}},
},
wantErr: true,
},
Expand Down
Loading

0 comments on commit 7d1bb1d

Please sign in to comment.