mirror of
https://github.com/matter-labs/vault-auth-tee.git
synced 2025-07-20 23:33:56 +02:00
117 lines
2.6 KiB
Go
117 lines
2.6 KiB
Go
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) Matter Labs
|
|
//
|
|
// Gets the rough network time using NTS-KE.
|
|
// It queries a number of servers and returns the time from the last server that responds.
|
|
// It returns an error if it fails to query enough servers or if the time fluctuates too much.
|
|
|
|
package vault_auth_tee
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"errors"
|
|
"log"
|
|
"math/rand"
|
|
"time"
|
|
|
|
"gitlab.com/hacklunch/ntp"
|
|
"gitlab.com/hacklunch/ntske"
|
|
)
|
|
|
|
// Gets the rough network time using NTS-KE.
|
|
// It queries a number of servers and returns the time from the last server that responds.
|
|
// It returns an error if it fails to query enough servers or if the time fluctuates too much.
|
|
func getRoughNtsUnixTime() (time.Time, error) {
|
|
tlsconfig := &tls.Config{}
|
|
servers := []string{
|
|
"time.cloudflare.com",
|
|
"nts.ntp.se",
|
|
"gps.ntp.br",
|
|
"paris.time.system76.com",
|
|
"ntp3.fau.de",
|
|
"ptbtime1.ptb.de",
|
|
"ntppool1.time.nl",
|
|
"nts.netnod.se",
|
|
"time.txryan.com",
|
|
"ntpmon.dcs1.biz",
|
|
}
|
|
|
|
// Shuffle the servers to avoid always querying the same servers.
|
|
for i := range servers {
|
|
j := rand.Intn(i + 1)
|
|
servers[i], servers[j] = servers[j], servers[i]
|
|
}
|
|
|
|
numToQuery := 3
|
|
queried := 0
|
|
sumOffset := time.Duration(0)
|
|
retTime := time.Unix(0, 0)
|
|
|
|
for _, server := range servers {
|
|
ke, err := ntske.Connect(server, tlsconfig, false)
|
|
if err != nil {
|
|
log.Printf("Failed to connect to %v: %v\n", server, err)
|
|
continue
|
|
}
|
|
|
|
err = ke.Exchange()
|
|
if err != nil {
|
|
log.Printf("Key exchange failed for %v: %v\n", server, err)
|
|
continue
|
|
}
|
|
|
|
if len(ke.Meta.Cookie) == 0 {
|
|
log.Printf("No Cookies from %v: %v\n", server, err)
|
|
continue
|
|
}
|
|
|
|
if ke.Meta.Algo != ntske.AES_SIV_CMAC_256 {
|
|
log.Printf("Algorithm mismatch for %v: %v\n", server, err)
|
|
continue
|
|
}
|
|
|
|
err = ke.ExportKeys()
|
|
if err != nil {
|
|
log.Printf("Failed to export keys from %v: %v\n", server, err)
|
|
continue
|
|
}
|
|
|
|
var opt ntp.QueryOptions
|
|
opt.Port = int(ke.Meta.Port)
|
|
opt.NTS = true
|
|
opt.C2s = ke.Meta.C2sKey
|
|
opt.S2c = ke.Meta.S2cKey
|
|
opt.Cookie = ke.Meta.Cookie[0]
|
|
opt.Debug = false
|
|
|
|
resp, err := ntp.QueryWithOptions(ke.Meta.Server, opt)
|
|
if err != nil {
|
|
log.Printf("Failed query NTP for %v: %v\n", server, err)
|
|
continue
|
|
}
|
|
|
|
err = resp.Validate()
|
|
if err != nil {
|
|
log.Printf("Failed to validate NTP response for %v: %v\n", server, err)
|
|
continue
|
|
}
|
|
|
|
sumOffset += resp.ClockOffset.Abs()
|
|
|
|
queried++
|
|
if queried >= numToQuery {
|
|
retTime = resp.Time
|
|
break
|
|
}
|
|
}
|
|
|
|
if queried < numToQuery {
|
|
return retTime, errors.New("failed to query enough servers")
|
|
}
|
|
|
|
if sumOffset > time.Minute {
|
|
return retTime, errors.New("queried time fluctuates too much")
|
|
}
|
|
|
|
return retTime, nil
|
|
}
|