Skip to content

Commit

Permalink
Merge pull request #19 from nuts-foundation/fix-credential
Browse files Browse the repository at this point in the history
Properly set credential ID and expiration date
  • Loading branch information
reinkrul authored Nov 22, 2024
2 parents e4536b5 + 6345637 commit 39f7cb9
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 23 deletions.
2 changes: 0 additions & 2 deletions pem/pem_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package pem

import (
"encoding/pem"
"fmt"
"os"
)

Expand Down Expand Up @@ -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 {
Expand Down
14 changes: 9 additions & 5 deletions uzi_vc_issuer/ura_issuer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"encoding/pem"
"errors"
"fmt"
"github.com/nuts-foundation/go-did/did"
"time"

"github.com/google/uuid"
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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,
Expand All @@ -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
}
33 changes: 17 additions & 16 deletions uzi_vc_issuer/ura_issuer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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: "",
},
Expand Down Expand Up @@ -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)
}
})
}
Expand All @@ -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 <issuer DID>#<uuid>")
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
}

0 comments on commit 39f7cb9

Please sign in to comment.