Skip to content

Commit 4d4ea22

Browse files
authored
fix cert verification (#15)
1 parent 8a61869 commit 4d4ea22

4 files changed

Lines changed: 94 additions & 30 deletions

File tree

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
MONGO_URL=mongodb://localhost:27017/
3+
MONGO_DB=tpp
4+
5+
start_server:
6+
MONGO_URL=$(MONGO_URL) MONGO_DB=$(MONGO_DB) go run server/run.go
7+
8+
test:
9+
go test ./...

app/verify/verify.go

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package verify
33
import (
44
"net/http"
55
"slices"
6+
"time"
67

78
"github.com/botsman/tppVerifier/app/db"
89
vhttp "github.com/botsman/tppVerifier/app/http"
@@ -48,8 +49,19 @@ type VerifyResult struct {
4849
Reason string `json:"reason,omitempty"`
4950
}
5051

51-
func (s *VerifySvc) SetRoots(roots *x509.CertPool) {
52-
s.roots = roots
52+
func (s *VerifySvc) SetRoots(roots []string) {
53+
certPool := x509.NewCertPool()
54+
for _, rawRoot := range roots {
55+
pemBytes, err := RawCertToPEM([]byte(rawRoot))
56+
if err != nil {
57+
log.Printf("Error converting root certificate to PEM format: %s", err)
58+
continue
59+
}
60+
if !certPool.AppendCertsFromPEM(pemBytes) {
61+
panic("Failed to append root certificate")
62+
}
63+
}
64+
s.roots = certPool
5365
}
5466

5567
func (s *VerifySvc) Verify(c *gin.Context) {
@@ -320,26 +332,42 @@ func (s *VerifySvc) isRevoked(c, issuer *x509.Certificate) (bool, error) {
320332
return ocspResponse.Status == ocsp.Revoked, nil
321333
}
322334

335+
func RawCertToPEM(raw []byte) ([]byte, error) {
336+
pemBytes := pem.EncodeToMemory(&pem.Block{
337+
Type: "CERTIFICATE",
338+
Bytes: raw,
339+
})
340+
if pemBytes == nil {
341+
return nil, errors.New("error encoding certificate to PEM format")
342+
}
343+
return pemBytes, nil
344+
}
345+
323346
func (s *VerifySvc) isTrusted(cert *x509.Certificate, chain []*x509.Certificate) (bool, error) {
324-
return true, nil // TODO: Implement certificate trust verification logic
325-
// intermediatePool := x509.NewCertPool()
326-
// for _, intermediate := range chain {
327-
// intermediatePool.AddCert(intermediate)
328-
// }
329-
// opts := x509.VerifyOptions{
330-
// Roots: s.roots,
331-
// Intermediates: intermediatePool,
332-
// }
333-
// _, err := cert.Verify(opts)
334-
// if err != nil {
335-
// log.Printf("Certificate verification failed: %s", err)
336-
// if _, ok := err.(x509.UnknownAuthorityError); ok {
337-
// log.Printf("Certificate is not trusted")
338-
// return false, nil
339-
// }
340-
// }
341-
// log.Printf("Certificate is trusted")
342-
// return true, nil
347+
intermediatePool := x509.NewCertPool()
348+
for _, intermediate := range chain {
349+
pemBytes, err := RawCertToPEM(intermediate.Raw)
350+
if err != nil {
351+
log.Printf("Error converting intermediate certificate to PEM format: %s", err)
352+
return false, err
353+
}
354+
if !intermediatePool.AppendCertsFromPEM(pemBytes) {
355+
log.Printf("Failed to append intermediate certificate to pool")
356+
return false, errors.New("failed to append intermediate certificate to pool")
357+
}
358+
}
359+
opts := x509.VerifyOptions{
360+
Roots: s.roots,
361+
Intermediates: intermediatePool,
362+
CurrentTime: time.Now(),
363+
}
364+
_, err := cert.Verify(opts)
365+
if err != nil {
366+
log.Printf("Certificate verification failed: %s", err)
367+
return false, err
368+
}
369+
log.Printf("Certificate is trusted")
370+
return true, nil
343371
}
344372

345373
func formatCertContent(content []byte) ([]byte, error) {

app/verify/verify_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,23 @@ func TestVerifyCert(t *testing.T) {
362362
t.Fatalf("Failed to read certificate file %s: %v", certPath, err)
363363
return
364364
}
365+
caCertPath := filepath.Join(chainsPath, entry.Name(), "ca.pem")
366+
caCertContent, err := os.ReadFile(caCertPath)
367+
if err != nil {
368+
t.Fatalf("Failed to read CA certificate file %s: %v", caCertPath, err)
369+
return
370+
}
371+
caPem, _ := pem.Decode(caCertContent)
372+
if caPem == nil {
373+
t.Fatalf("Failed to decode CA certificate PEM from %s", caCertPath)
374+
return
375+
}
376+
caCert, err := x509.ParseCertificate(caPem.Bytes)
377+
if err != nil {
378+
t.Fatalf("Failed to parse CA certificate from %s: %v", caCertPath, err)
379+
return
380+
}
381+
svc.SetRoots([]string{string(caCert.Raw)})
365382
cert, err := svc.parseCert(&ctx, []byte(certContent))
366383
if err != nil {
367384
t.Fatalf("Expected no error, got %v", err)
@@ -430,6 +447,24 @@ func TestVerify_Success(t *testing.T) {
430447
if len(certContent) == 0 {
431448
t.Fatal("Expected non-empty certificate content")
432449
}
450+
caCertContent, err := os.ReadFile(getTestDataPath("chains/1/ca.pem"))
451+
if err != nil {
452+
t.Fatalf("Couldn't read CA certificate file: %v\n", err)
453+
}
454+
if len(caCertContent) == 0 {
455+
t.Fatal("Expected non-empty CA certificate content")
456+
}
457+
caPem, _ := pem.Decode(caCertContent)
458+
if caPem == nil {
459+
t.Fatal("Failed to decode CA certificate PEM")
460+
return
461+
}
462+
caCert, err := x509.ParseCertificate(caPem.Bytes)
463+
if err != nil {
464+
t.Fatalf("Failed to parse CA certificate from %s: %v", "chains/1/ca.pem", err)
465+
return
466+
}
467+
svc.SetRoots([]string{string(caCert.Raw)})
433468
// Set the certificate content in the request
434469
verifyRequest.Cert = []byte(certContent)
435470
body, err := json.Marshal(verifyRequest)

server/run.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package main
22

33
import (
44
"context"
5-
"crypto/x509"
65
"log"
76
"net/http"
87

@@ -30,14 +29,7 @@ func main() {
3029
if err != nil {
3130
log.Fatalf("Failed to get root certificates: %v", err)
3231
}
33-
rootPool := x509.NewCertPool()
34-
for _, root := range roots {
35-
// TODO: check if roots are formatted correctly
36-
if !rootPool.AppendCertsFromPEM([]byte(root)) {
37-
log.Printf("Failed to append root certificate")
38-
}
39-
}
40-
vs.SetRoots(rootPool)
32+
vs.SetRoots(roots)
4133
r := app.SetupRouter(vs)
4234
r.Run()
4335
}

0 commit comments

Comments
 (0)