From 6345637a5d208a63bd652f54f21ffafda7724364 Mon Sep 17 00:00:00 2001 From: Rein Krul Date: Tue, 19 Nov 2024 14:07:45 +0100 Subject: [PATCH] Properly set credential ID and expiration date, remove logging --- pem/pem_reader.go | 2 -- uzi_vc_issuer/ura_issuer.go | 14 +++++++++----- uzi_vc_issuer/ura_issuer_test.go | 33 ++++++++++++++++---------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/pem/pem_reader.go b/pem/pem_reader.go index 3a3ec8a..0b6d6c9 100644 --- a/pem/pem_reader.go +++ b/pem/pem_reader.go @@ -2,7 +2,6 @@ package pem import ( "encoding/pem" - "fmt" "os" ) @@ -38,7 +37,6 @@ func ParseFileOrPath(path string, pemType string) ([][]byte, error) { // readFile reads a file from the given filename, parses it for PEM blocks of the specified type, and returns the blocks. func readFile(filename string, pemType string) ([][]byte, error) { - fmt.Println("filename: ", filename) files := make([][]byte, 0) content, err := os.ReadFile(filename) if err != nil { diff --git a/uzi_vc_issuer/ura_issuer.go b/uzi_vc_issuer/ura_issuer.go index 6a267f7..a716827 100644 --- a/uzi_vc_issuer/ura_issuer.go +++ b/uzi_vc_issuer/ura_issuer.go @@ -9,6 +9,7 @@ import ( "encoding/pem" "errors" "fmt" + "github.com/nuts-foundation/go-did/did" "time" "github.com/google/uuid" @@ -119,7 +120,7 @@ func BuildUraVerifiableCredential(chain []*x509.Certificate, signingKey *rsa.Pri if uzi != serialNumber { return nil, errors.New("serial number does not match UZI number") } - template, err := uraCredential(did, otherNameValues, subjectTypes, subjectDID) + template, err := uraCredential(did, signingCert.NotAfter, otherNameValues, subjectTypes, subjectDID) if err != nil { return nil, err } @@ -264,8 +265,7 @@ func convertHeaders(headers map[string]interface{}) (jws.Headers, error) { // uraCredential generates a VerifiableCredential for a given URA and UZI number, including the subject's DID. // It sets a 1-year expiration period from the current issuance date. -func uraCredential(issuer string, otherNameValues []*x509_cert.OtherNameValue, subjectTypes []*x509_cert.SubjectValue, subjectDID string) (*vc.VerifiableCredential, error) { - exp := time.Now().Add(time.Hour * 24 * 365 * 100) +func uraCredential(issuer string, expirationDate time.Time, otherNameValues []*x509_cert.OtherNameValue, subjectTypes []*x509_cert.SubjectValue, subjectDID string) (*vc.VerifiableCredential, error) { iat := time.Now() subject := map[string]interface{}{ "id": subjectDID, @@ -278,13 +278,17 @@ func uraCredential(issuer string, otherNameValues []*x509_cert.OtherNameValue, s subject[string(subjectType.Type)] = subjectType.Value } + id := did.DIDURL{ + DID: did.MustParseDID(issuer), + Fragment: uuid.NewString(), + }.URI() return &vc.VerifiableCredential{ Issuer: ssi.MustParseURI(issuer), Context: []ssi.URI{ssi.MustParseURI("https://www.w3.org/2018/credentials/v1")}, Type: []ssi.URI{ssi.MustParseURI("VerifiableCredential"), ssi.MustParseURI("UziServerCertificateCredential")}, - ID: func() *ssi.URI { id := ssi.MustParseURI(uuid.NewString()); return &id }(), + ID: &id, IssuanceDate: iat, - ExpirationDate: &exp, + ExpirationDate: &expirationDate, CredentialSubject: []interface{}{subject}, }, nil } diff --git a/uzi_vc_issuer/ura_issuer_test.go b/uzi_vc_issuer/ura_issuer_test.go index 516be0c..4e627cd 100644 --- a/uzi_vc_issuer/ura_issuer_test.go +++ b/uzi_vc_issuer/ura_issuer_test.go @@ -13,8 +13,9 @@ import ( "github.com/nuts-foundation/go-did/did" "github.com/nuts-foundation/go-did/vc" "github.com/nuts-foundation/uzi-did-x509-issuer/x509_cert" + "github.com/stretchr/testify/require" "os" - "slices" + "strings" "testing" ) @@ -231,7 +232,7 @@ func TestIssue(t *testing.T) { failError(t, err) identifier := "2.16.528.1.1007.99.2110-1-900030787-S-90000380-00.000-11223344" ura := "90000380" - chain, _, rootCert, privKey, _, err := x509_cert.BuildSelfSignedCertChain(identifier, ura) + chain, _, rootCert, privKey, signingCert, err := x509_cert.BuildSelfSignedCertChain(identifier, ura) bytesRootHash := sha512.Sum512(rootCert.Raw) rootHash := base64.RawURLEncoding.EncodeToString(bytesRootHash[:]) failError(t, err) @@ -286,9 +287,10 @@ func TestIssue(t *testing.T) { subjectDID: "did:example:123", allowTest: true, out: &vc.VerifiableCredential{ - Context: []ssi.URI{ssi.MustParseURI("https://www.w3.org/2018/credentials/v1")}, - Issuer: did.MustParseDID(fmt.Sprintf("did:x509:0:sha512:%s::san:otherName:%s::san:permanentIdentifier.value:%s::san:permanentIdentifier.assigner:%s", rootHash, identifier, ura, x509_cert.UraAssigner.String())).URI(), - Type: []ssi.URI{ssi.MustParseURI("VerifiableCredential"), ssi.MustParseURI("UziServerCertificateCredential")}, + Context: []ssi.URI{ssi.MustParseURI("https://www.w3.org/2018/credentials/v1")}, + Issuer: did.MustParseDID(fmt.Sprintf("did:x509:0:sha512:%s::san:otherName:%s::san:permanentIdentifier.value:%s::san:permanentIdentifier.assigner:%s", rootHash, identifier, ura, x509_cert.UraAssigner.String())).URI(), + Type: []ssi.URI{ssi.MustParseURI("VerifiableCredential"), ssi.MustParseURI("UziServerCertificateCredential")}, + ExpirationDate: toPtr(signingCert.NotAfter), }, errorText: "", }, @@ -335,9 +337,7 @@ func TestIssue(t *testing.T) { found := vc.VerifiableCredential{} err = json.Unmarshal([]byte("\""+result+"\""), &found) failError(t, err) - if !compare(tt.out, &found) { - t.Errorf("Issue() expected %v, got %v", tt.out, found) - } + compare(t, tt.out, &found) } }) } @@ -350,12 +350,13 @@ func failError(t *testing.T, err error) { } } -func compare(expected *vc.VerifiableCredential, found *vc.VerifiableCredential) bool { - if expected.Issuer.String() != found.Issuer.String() { - return false - } - if !slices.Equal(expected.Type, found.Type) { - return false - } - return true +func compare(t *testing.T, expected *vc.VerifiableCredential, found *vc.VerifiableCredential) { + require.True(t, strings.HasPrefix(found.ID.String(), found.Issuer.String()+"#"), "credential ID must be in form #") + require.Equal(t, expected.Issuer.String(), found.Issuer.String(), "credential issuer mismatch") + require.Equal(t, expected.Type, found.Type, "credential type mismatch") + require.Equal(t, expected.ExpirationDate, found.ExpirationDate, "credential expiration date mismatch") +} + +func toPtr[T any](v T) *T { + return &v }