// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: MIT package krb5 import ( "bytes" "testing" ) // The AP-REP the acceptor answers with completes the client half of the // context: it verifies under the session key, and nothing else does. func TestClientAcceptRepRoundTrip(t *testing.T) { key := make([]byte, 32) for i := range key { key[i] = byte(i + 1) } client, token, err := ClientInit(EtypeAES256, key, "EXAMPLE.ORG", "nfs", "client") if err != nil { t.Fatal(err) } acceptor, aprep, err := AcceptInit(token, key) if err != nil { t.Fatal(err) } _ = acceptor if err := client.ClientAcceptRep(aprep); err != nil { t.Fatalf("accept rep: %v", err) } // The shared key makes both halves sign tokens the other verifies. mic, err := client.GetMIC([]byte("data")) if err != nil { t.Fatal(err) } if err := acceptor.VerifyMIC([]byte("data"), mic); err != nil { t.Fatalf("cross verify: %v", err) } // Anything but the genuine AP-REP is refused: a wrong tag, a wrong // message type, a body from another key. if err := client.ClientAcceptRep([]byte{0x6e, 0x00}); err == nil { t.Fatal("a two byte token accepted") } tampered := append([]byte{}, aprep...) tampered[len(tampered)-1] ^= 1 if err := client.ClientAcceptRep(tampered); err == nil { t.Fatal("a tampered AP-REP accepted") } other, otoken, err := ClientInit(EtypeAES256, key, "EXAMPLE.ORG", "nfs", "other") if err != nil { t.Fatal(err) } if err := other.ClientAcceptRep(aprep); err == nil { t.Fatal("an AP-REP of another context accepted") } if bytes.Equal(otoken, token) { t.Fatal("two inits minted the same token") } }