package main // Item 16 scanner tests: input parsing (offline) and the probe against // a local TLS server (loopback only — the live-domain check happens in // the sandbox smoke run). import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/tls" "crypto/x509" "crypto/x509/pkix" "math/big" "net" "strings" "testing" "time" ) func TestParseScanTargetsPool(t *testing.T) { targets, err := parseScanTargets("") if err != nil { t.Fatal(err) } if len(targets) < len(RealityPresets) || len(targets) > scanMaxTargets { t.Fatalf("pool size %d out of bounds", len(targets)) } seen := map[string]bool{} for _, target := range targets { seen[target.Host] = true if target.Port != 443 { t.Fatalf("pool target %s port %d, want 443", target.Host, target.Port) } } for _, want := range []string{"www.microsoft.com", "www.google.com", "www.nvidia.com", "www.samsung.com", "www.intel.com"} { if !seen[want] { t.Fatalf("pool missing %s", want) } } } func TestParseScanTargetsInput(t *testing.T) { targets, err := parseScanTargets("a.example.com, b.example.com:8443 203.0.113.7") if err != nil { t.Fatal(err) } if len(targets) != 3 || targets[0].Port != 443 || targets[1].Port != 8443 || targets[2].Host != "203.0.113.7" { t.Fatalf("targets %+v", targets) } cidr, err := parseScanTargets("203.0.113.0/30") if err != nil { t.Fatal(err) } if len(cidr) != 4 { t.Fatalf("cidr /30 expanded to %d hosts, want 4", len(cidr)) } if _, err := parseScanTargets("10.0.0.0/33"); err == nil { t.Fatal("invalid CIDR must error") } if _, err := parseScanTargets("a.example.com:99999"); err == nil { t.Fatal("invalid port must error") } many := strings.TrimSuffix(strings.Repeat("a.example.com,", scanMaxTargets+1), ",") if _, err := parseScanTargets(many); err == nil { t.Fatal("over-cap input must error") } } func TestProbeRealityTargetLocalTLS(t *testing.T) { key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { t.Fatal(err) } template := &x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{CommonName: "localhost"}, DNSNames: []string{"localhost"}, NotBefore: time.Now().Add(-time.Hour), NotAfter: time.Now().Add(time.Hour), KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, } der, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key) if err != nil { t.Fatal(err) } cert := tls.Certificate{Certificate: [][]byte{der}, PrivateKey: key} listener, err := tls.Listen("tcp", "127.0.0.1:0", &tls.Config{Certificates: []tls.Certificate{cert}}) if err != nil { t.Fatal(err) } defer listener.Close() go func() { for { conn, err := listener.Accept() if err != nil { return } go func() { defer conn.Close() _ = conn.(*tls.Conn).Handshake() }() } }() port := listener.Addr().(*net.TCPAddr).Port result := probeRealityTarget(scanTarget{Host: "127.0.0.1", Port: port}) if !result.OK { t.Fatalf("local TLS target must be OK: %+v", result) } if result.TLSVersion != "TLS 1.3" { t.Fatalf("tlsVersion %q, want TLS 1.3", result.TLSVersion) } if result.KeyExchange == "" || !result.KeyExchangeOK { t.Fatalf("keyExchange %q ok=%v", result.KeyExchange, result.KeyExchangeOK) } // A dead port reports not-OK with a reason, never a panic. dead := probeRealityTarget(scanTarget{Host: "127.0.0.1", Port: 1}) if dead.OK || dead.Reason == "" { t.Fatalf("dead target: %+v", dead) } }