Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions reference/verifier-service/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
var (
port = flag.String("port", ":8888", "Listening port")
certs = flag.String("cacerts", "certs.pem", "File containing issuer CA certs")
vicalUrl = flag.String("vical_url", "https://vical.dts.aamva.org/vical/vc", "URL to fetch AAMVA VICAL from")
circuitDir = flag.String("circuit_dir", "circuits", "Directory from which to load circuits")
)

Expand Down Expand Up @@ -76,6 +77,11 @@ func main() {
os.Exit(1)
}

if err := zk.LoadVICAL(*vicalUrl); err != nil {
logger.Error("could not load VICAL", "url", *vicalUrl, "err", err)
// We decide not to exit here, as the server might still be useful with just local certs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// We decide not to exit here, as the server might still be useful with just local certs
// We decided not to exit here, as the server might still be useful with just local certs

}

server := NewServer(*port, logger)

mux := http.NewServeMux()
Expand Down
Binary file added reference/verifier-service/server/vical.cbor
Binary file not shown.
5 changes: 0 additions & 5 deletions reference/verifier-service/server/zk/cbor.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,6 @@ import (
"github.com/fxamacker/cbor/v2"
)

var (
// IssuerRoots is a pool of trusted root certificate authorities.
IssuerRoots = x509.NewCertPool()
)

// X5ChainIndex is the index of the x509 chain in the COSE_Sign1 unprotected header.
const X5ChainIndex = 33

Expand Down
8 changes: 8 additions & 0 deletions reference/verifier-service/server/zk/roots.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package zk

import "crypto/x509"

var (
// IssuerRoots is a pool of trusted root certificate authorities.
IssuerRoots = x509.NewCertPool()
)
75 changes: 75 additions & 0 deletions reference/verifier-service/server/zk/vical.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package zk

import (
"crypto/x509"
"fmt"
"io"
"log"
"net/http"

"github.com/fxamacker/cbor/v2"
)

// LoadVICAL fetches the VICAL from the given URL and adds the certificates to the IssuerRoots pool.
func LoadVICAL(url string) error {
log.Printf("Fetching VICAL from %s", url)
resp, err := http.Get(url)
if err != nil {
return fmt.Errorf("failed to fetch VICAL: %w", err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to fetch VICAL: status %s", resp.Status)
}

data, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read VICAL body: %w", err)
}

var rawItems []interface{}
if err := cbor.Unmarshal(data, &rawItems); err != nil {
return fmt.Errorf("failed to unmarshal VICAL CBOR: %w", err)
}

count := 0
var findCerts func(item interface{}, depth int)
findCerts = func(item interface{}, depth int) {
if depth > 10 {
return // Avoid infinite recursion
}
switch v := item.(type) {
case []byte:
// Try to parse as certificate first
if len(v) > 0 && v[0] == 0x30 {
cert, err := x509.ParseCertificate(v)
if err == nil {
IssuerRoots.AddCert(cert)
count++
return // Found a cert, stop digging in this branch
}
}
// If not a cert or cert parse failed, try treating as CBOR
var child interface{}
if err := cbor.Unmarshal(v, &child); err == nil {
findCerts(child, depth+1)
}
case []interface{}:
for _, child := range v {
findCerts(child, depth+1)
}
case map[interface{}]interface{}:
for _, val := range v {
findCerts(val, depth+1)
}
}
}

for _, item := range rawItems {
findCerts(item, 0)
}

log.Printf("Loaded %d certificates from VICAL", count)
return nil
}
27 changes: 27 additions & 0 deletions reference/verifier-service/server/zk/vical_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package zk

import (
"net/http"
"net/http/httptest"
"os"
"testing"
)

func TestLoadVICAL(t *testing.T) {
// Load real test data
cborData, err := os.ReadFile("../vical.cbor")
if err != nil {
t.Fatalf("Failed to read vical.cbor: %v", err)
}

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/cbor")
w.Write(cborData)
}))
defer ts.Close()

err = LoadVICAL(ts.URL)
if err != nil {
t.Fatalf("LoadVICAL failed: %v", err)
}
}
Loading