Skip to content

Commit

Permalink
changed logging; solvec bug with extenstion length check
Browse files Browse the repository at this point in the history
  • Loading branch information
randomlogin committed Mar 4, 2024
1 parent 25817fe commit a3b9b2d
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 73 deletions.
12 changes: 4 additions & 8 deletions cmd/sane/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"flag"
"fmt"
"log"
"log/slog"
"net"
"os"
"path"
Expand All @@ -19,6 +18,7 @@ import (
"github.com/buffrr/hsig0"
"github.com/miekg/dns"
sane "github.com/randomlogin/sane"
"github.com/randomlogin/sane/debuglog"
rs "github.com/randomlogin/sane/resolver"
"github.com/randomlogin/sane/sync"
)
Expand Down Expand Up @@ -274,15 +274,11 @@ func main() {
RootsPath: path.Join(p, "roots.json"),
ExternalService: *externalService,
}
debuglog.Logger = debuglog.NewDebugLogger(false)
if *verbose {
logHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelDebug,
AddSource: true,
})
logger := slog.New(logHandler)
slog.SetDefault(logger)
log.SetFlags(log.LstdFlags | log.Lshortfile)
debuglog.Logger = debuglog.NewDebugLogger(true)
}
// log.D

log.Printf("Listening on %s", *addr)
log.Fatal(c.Run(*addr))
Expand Down
48 changes: 48 additions & 0 deletions debuglog/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package debuglog

import (
"log"
"os"
)

type DebugLogger struct {
Verbose bool
*log.Logger
}

var Logger *DebugLogger

func (l *DebugLogger) Set() {
l.Verbose = true
}

func NewDebugLogger(verbose bool) *DebugLogger {
return &DebugLogger{
Verbose: verbose,
Logger: log.New(os.Stdout, "", log.LstdFlags),
}
}

func (l *DebugLogger) Debug(v ...interface{}) {
if l.Verbose {
l.Println(v...)
}
}

func (l *DebugLogger) Debugf(s string, v ...interface{}) {
if l.Verbose {
l.Printf(s, v...)
}
}

// func (l *DebugLogger) Print(v ...interface{}) {
// log.Print(v...)
// }
//
// func (l *DebugLogger) Fatal(v ...interface{}) {
// log.Fatal(v...)
// }
//
// func (l *DebugLogger) Fatalf(a string, v ...interface{}) {
// log.Fatalf(a, v...)
// }
116 changes: 55 additions & 61 deletions prove/prove.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package prove

// #cgo LDFLAGS: -lurkel
// #include "urkel.h"
import "C"
import (
"bytes"
"crypto/x509"
"encoding/hex"
"errors"
"fmt"
"log/slog"

"github.com/miekg/dns"
"github.com/randomlogin/sane/debuglog"
"github.com/randomlogin/sane/dnssec"
"github.com/randomlogin/sane/sync"
"golang.org/x/crypto/sha3"
Expand Down Expand Up @@ -70,46 +67,42 @@ func verifyUrkelExt(extensionValue []byte, domain string, roots []sync.BlockInfo
hexstr := hex.EncodeToString(certRoot)

if len(extensionValue) < 32 {
slog.Debug("urkel proof is empty")
debuglog.Logger.Debug("urkel proof is empty")
return fmt.Errorf("urkel data is corrupted")
}
certProof := extensionValue[32:]
length, err := checkProof(certProof, certRoot, key)
if err != nil {
//found invalid proof
slog.Debug("urkel verification failed: %s", err)
debuglog.Logger.Debug("urkel verification failed: %s", err)
return err
}
for _, block := range roots {
// found tree root among stored ones
if hexstr == block.TreeRoot {
slog.Debug("found tree root ", hexstr, " from the certificate in the stored roots")
debuglog.Logger.Debug("found tree root ", hexstr, " from the certificate in the stored roots")
return nil
}
}
extensionValue = extensionValue[32+*length:]
slog.Debug("could not find tree root ", hexstr, " from the certificate in the stored roots")
debuglog.Logger.Debug("could not find tree root ", hexstr, " from the certificate in the stored roots")
}
return fmt.Errorf("could not find tree root in the stored ones")
}

// extracts proof data from the certificate then verifies if the proof is correct
func VerifyCertificateExtensions(roots []sync.BlockInfo, cert x509.Certificate, tlsa *dns.TLSA, externalService string) error {
extensions := cert.Extensions
if len(extensions) < 2 {
return fmt.Errorf("not found enough extensions in the certificate")
}
if len(cert.DNSNames) == 0 {
return fmt.Errorf("certificate has empty dns names")
}

for _, domain := range cert.DNSNames {
err := verifyDomain(domain, cert, roots, tlsa, externalService)
if err == nil {
slog.Debug("successfully verified certificate extensions for domain " + domain)
debuglog.Logger.Debug("successfully verified certificate extensions for domain " + domain)
return nil
}
slog.Debug("got error %s verifying domain %s", err, domain)
debuglog.Logger.Debugf("got error: %s during verification domain %s", err, domain)
}
return fmt.Errorf("failed to verify certificate extensions")
}
Expand Down Expand Up @@ -168,64 +161,65 @@ func verifyDomain(domain string, cert x509.Certificate, roots []sync.BlockInfo,
return err
}
DNSSECVerificationError = dnssec.VerifyDNSSECChain(records, domain, tlsa)

if DNSSECVerificationError != nil {
// log.Print("DNSSECVerificationError", DNSSECVerificationError, domain)
debuglog.Logger.Debug("DNSSECVerificationError", DNSSECVerificationError, domain)
return DNSSECVerificationError
}

if (UrkelVerificationError == nil) && (DNSSECVerificationError == nil) {
slog.Debug("DANE extensions from certificate are both valid")
debuglog.Logger.Debug("DANE extensions from certificate are both valid")
return nil
} else {
return fmt.Errorf("could not verify SANE for domain %s: %s, %s", domain, UrkelVerificationError, DNSSECVerificationError)
}
}

// Deprecated: using native golang implementation of urkel trees to verify
func verifyUrkelExtC(extensionValue []byte, domain string, roots []sync.BlockInfo) error {
h := sha3.New256()
h.Write([]byte(domain))
key := h.Sum(nil)

certRoot := extensionValue[1 : 1+32] //Magic numbers, should be checked
certProof := extensionValue[33:]

proofResult := verifyUrkelProof(key, certProof, certRoot)
if !proofResult {
return fmt.Errorf("the proof in the certificate is not valid")
}

// check that root is one of the stored ones
hexstr := hex.EncodeToString(certRoot)
for _, block := range roots {
if hexstr == block.TreeRoot {
// log.Print("Found tree root ", block.TreeRoot, " from the certificate in the stored ones.")
return nil
}
}
return fmt.Errorf("urkel tree root %s from the certificate was not found among the stored ones", hexstr)
}

// func verifyUrkelExtC(extensionValue []byte, domain string, roots []sync.BlockInfo) error {
// h := sha3.New256()
// h.Write([]byte(domain))
// key := h.Sum(nil)
//
// certRoot := extensionValue[1 : 1+32] //Magic numbers, should be checked
// certProof := extensionValue[33:]
//
// proofResult := verifyUrkelProof(key, certProof, certRoot)
// if !proofResult {
// return fmt.Errorf("the proof in the certificate is not valid")
// }
//
// // check that root is one of the stored ones
// hexstr := hex.EncodeToString(certRoot)
// for _, block := range roots {
// if hexstr == block.TreeRoot {
// // log.Print("Found tree root ", block.TreeRoot, " from the certificate in the stored ones.")
// return nil
// }
// }
// return fmt.Errorf("urkel tree root %s from the certificate was not found among the stored ones", hexstr)
// }
//
// Deprecated: this version uses
// verifies key in the urkel tree with a given proof against a given root
func verifyUrkelProof(key, proof, root []byte) bool {
proofLen := C.size_t(len(proof))
var exists C.int
value := make([]byte, len(proof))
var valueLen C.size_t

intres := C.urkel_verify(
&exists,
(*C.uchar)(&value[0]),
&valueLen,
(*C.uchar)(&proof[0]),
proofLen,
(*C.uchar)(&key[0]),
(*C.uchar)(&root[0]))

if intres == 1 {
return true
} else {
return false
}
}
// func verifyUrkelProof(key, proof, root []byte) bool {
// proofLen := C.size_t(len(proof))
// var exists C.int
// value := make([]byte, len(proof))
// var valueLen C.size_t
//
// intres := C.urkel_verify(
// &exists,
// (*C.uchar)(&value[0]),
// &valueLen,
// (*C.uchar)(&proof[0]),
// proofLen,
// (*C.uchar)(&key[0]),
// (*C.uchar)(&root[0]))
//
// if intres == 1 {
// return true
// } else {
// return false
// }
// }
1 change: 0 additions & 1 deletion sync/hnsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ func checkIfSynced() (bool, error) {
// Check the DNS response for synchronization status
if len(response.Answer) > 0 {
if txtRecord, ok := response.Answer[0].(*dns.TXT); ok {
// slog.Debug("in syncing", txtRecord.Txt)
if txtRecord.Txt[0] == "true" {
return true, nil
}
Expand Down
4 changes: 3 additions & 1 deletion tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/miekg/dns"
"github.com/randomlogin/sane/debuglog"
"github.com/randomlogin/sane/prove"
"github.com/randomlogin/sane/sync"
)
Expand Down Expand Up @@ -57,12 +58,13 @@ func verifyConnection(rrs []*dns.TLSA, nameCheck bool, host string, roots []sync

// Verify the leaf certificate against the TLSA rrs
for _, t := range rrs {

if t.Usage != 3 {
continue
}
if err := t.Verify(cs.PeerCertificates[0]); err == nil {
if err := prove.VerifyCertificateExtensions(roots, *cert, t, externalService); err != nil {
// log.Print(err)
debuglog.Logger.Debug(err)
return err
}
return nil
Expand Down
3 changes: 1 addition & 2 deletions tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ import (
)

var (
// Version the current version
Version = "0.0.2"
Version = "0.0.4"
)

const (
Expand Down

0 comments on commit a3b9b2d

Please sign in to comment.