mirror of
				https://github.com/matter-labs/vault-auth-tee.git
				synced 2025-10-28 21:44:09 +01: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
 | |
| }
 | 
