github.com/jcmturner/gokrb5/v8@v8.4.4/spnego/krb5Token_test.go (about) 1 package spnego 2 3 import ( 4 "encoding/hex" 5 "math" 6 "testing" 7 8 "github.com/jcmturner/gofork/encoding/asn1" 9 "github.com/jcmturner/gokrb5/v8/client" 10 "github.com/jcmturner/gokrb5/v8/credentials" 11 "github.com/jcmturner/gokrb5/v8/gssapi" 12 "github.com/jcmturner/gokrb5/v8/iana/msgtype" 13 "github.com/jcmturner/gokrb5/v8/iana/nametype" 14 "github.com/jcmturner/gokrb5/v8/messages" 15 "github.com/jcmturner/gokrb5/v8/test/testdata" 16 "github.com/jcmturner/gokrb5/v8/types" 17 "github.com/stretchr/testify/assert" 18 ) 19 20 const ( 21 KRB5TokenHex = "6082026306092a864886f71201020201006e8202523082024ea003020105a10302010ea20703050000000000a382015d6182015930820155a003020105a10d1b0b544553542e474f4b524235a2233021a003020101a11a30181b04485454501b10686f73742e746573742e676f6b726235a382011830820114a003020112a103020103a28201060482010230621d868c97f30bf401e03bbffcd724bd9d067dce2afc31f71a356449b070cdafcc1ff372d0eb1e7a708b50c0152f3996c45b1ea312a803907fb97192d39f20cdcaea29876190f51de6e2b4a4df0460122ed97f363434e1e120b0e76c172b4424a536987152ac0b73013ab88af4b13a3fcdc63f739039dd46d839709cf5b51bb0ce6cb3af05fab3844caac280929955495235e9d0424f8a1fb9b4bd4f6bba971f40b97e9da60b9dabfcf0b1feebfca02c9a19b327a0004aa8e19192726cf347561fa8ac74afad5d6a264e50cf495b93aac86c77b2bc2d184234f6c2767dbea431485a25687b9044a20b601e968efaefffa1fc5283ff32aa6a53cb6c5cdd2eddcb26a481d73081d4a003020112a103020103a281c70481c4a1b29e420324f7edf9efae39df7bcaaf196a3160cf07e72f52a4ef8a965721b2f3343719c50699046e4fcc18ca26c2bfc7e4a9eddfc9d9cfc57ff2f6bdbbd1fc40ac442195bc669b9a0dbba12563b3e4cac9f4022fc01b8aa2d1ab84815bb078399ff7f4d5f9815eef896a0c7e3c049e6fd9932b97096cdb5861425b9d81753d0743212ded1a0fb55a00bf71a46be5ce5e1c8a5cc327b914347d9efcb6cb31ca363b1850d95c7b6c4c3cc6301615ad907318a0c5379d343610fab17eca9c7dc0a5a60658" 22 AuthChksum = "100000000000000000000000000000000000000030000000" 23 ) 24 25 func TestKRB5Token_Unmarshal(t *testing.T) { 26 t.Parallel() 27 b, err := hex.DecodeString(KRB5TokenHex) 28 if err != nil { 29 t.Fatalf("Error decoding KRB5Token hex: %v", err) 30 } 31 var mt KRB5Token 32 err = mt.Unmarshal(b) 33 if err != nil { 34 t.Fatalf("Error unmarshalling KRB5Token: %v", err) 35 } 36 assert.Equal(t, gssapi.OIDKRB5.OID(), mt.OID, "KRB5Token OID not as expected.") 37 assert.Equal(t, []byte{1, 0}, mt.tokID, "TokID not as expected") 38 assert.Equal(t, msgtype.KRB_AP_REQ, mt.APReq.MsgType, "KRB5Token AP_REQ does not have the right message type.") 39 assert.Equal(t, int32(0), mt.KRBError.ErrorCode, "KRBError in KRB5Token does not indicate no error.") 40 assert.Equal(t, int32(18), mt.APReq.EncryptedAuthenticator.EType, "Authenticator within AP_REQ does not have the etype expected.") 41 } 42 43 func TestKRB5Token_newAuthenticatorChksum(t *testing.T) { 44 t.Parallel() 45 b, err := hex.DecodeString(AuthChksum) 46 if err != nil { 47 t.Fatalf("Error decoding KRB5Token hex: %v", err) 48 } 49 cb := newAuthenticatorChksum([]int{gssapi.ContextFlagInteg, gssapi.ContextFlagConf}) 50 assert.Equal(t, b, cb, "SPNEGO Authenticator checksum not as expected") 51 } 52 53 // Test with explicit subkey generation. 54 func TestKRB5Token_newAuthenticatorWithSubkeyGeneration(t *testing.T) { 55 t.Parallel() 56 creds := credentials.New("hftsai", testdata.TEST_REALM) 57 creds.SetCName(types.PrincipalName{NameType: nametype.KRB_NT_PRINCIPAL, NameString: testdata.TEST_PRINCIPALNAME_NAMESTRING}) 58 var etypeID int32 = 18 59 keyLen := 32 // etypeID 18 refers to AES256 -> 32 bytes key 60 a, err := krb5TokenAuthenticator(creds, []int{gssapi.ContextFlagInteg, gssapi.ContextFlagConf}) 61 if err != nil { 62 t.Fatalf("Error creating authenticator: %v", err) 63 } 64 a.GenerateSeqNumberAndSubKey(etypeID, keyLen) 65 assert.Equal(t, int32(32771), a.Cksum.CksumType, "Checksum type in authenticator for SPNEGO mechtoken not as expected.") 66 assert.Equal(t, etypeID, a.SubKey.KeyType, "Subkey not of the expected type.") 67 assert.Equal(t, keyLen, len(a.SubKey.KeyValue), "Subkey value not of the right length") 68 var nz bool 69 for _, b := range a.SubKey.KeyValue { 70 if b != byte(0) { 71 nz = true 72 } 73 } 74 assert.True(t, nz, "subkey not initialised") 75 assert.Condition(t, assert.Comparison(func() bool { 76 return a.SeqNumber > 0 77 }), "Sequence number is not greater than zero") 78 assert.Condition(t, assert.Comparison(func() bool { 79 return a.SeqNumber <= math.MaxUint32 80 })) 81 } 82 83 // Test without subkey generation. 84 func TestKRB5Token_newAuthenticator(t *testing.T) { 85 t.Parallel() 86 creds := credentials.New("hftsai", testdata.TEST_REALM) 87 creds.SetCName(types.PrincipalName{NameType: nametype.KRB_NT_PRINCIPAL, NameString: testdata.TEST_PRINCIPALNAME_NAMESTRING}) 88 a, err := krb5TokenAuthenticator(creds, []int{gssapi.ContextFlagInteg, gssapi.ContextFlagConf}) 89 if err != nil { 90 t.Fatalf("Error creating authenticator: %v", err) 91 } 92 assert.Equal(t, int32(32771), a.Cksum.CksumType, "Checksum type in authenticator for SPNEGO mechtoken not as expected.") 93 assert.Equal(t, int32(0), a.SubKey.KeyType, "Subkey not of the expected type.") 94 assert.Nil(t, a.SubKey.KeyValue, "Subkey should not be set.") 95 96 assert.Condition(t, assert.Comparison(func() bool { 97 return a.SeqNumber > 0 98 }), "Sequence number is not greater than zero") 99 assert.Condition(t, assert.Comparison(func() bool { 100 return a.SeqNumber <= math.MaxUint32 101 })) 102 } 103 104 func TestNewAPREQKRB5Token_and_Marshal(t *testing.T) { 105 t.Parallel() 106 creds := credentials.New("hftsai", testdata.TEST_REALM) 107 creds.SetCName(types.PrincipalName{NameType: nametype.KRB_NT_PRINCIPAL, NameString: testdata.TEST_PRINCIPALNAME_NAMESTRING}) 108 cl := client.Client{ 109 Credentials: creds, 110 } 111 112 var tkt messages.Ticket 113 b, err := hex.DecodeString(testdata.MarshaledKRB5ticket) 114 if err != nil { 115 t.Fatalf("Test vector read error: %v", err) 116 } 117 err = tkt.Unmarshal(b) 118 if err != nil { 119 t.Fatalf("Unmarshal error: %v", err) 120 } 121 122 key := types.EncryptionKey{ 123 KeyType: 18, 124 KeyValue: make([]byte, 32), 125 } 126 127 mt, err := NewKRB5TokenAPREQ(&cl, tkt, key, []int{gssapi.ContextFlagInteg, gssapi.ContextFlagConf}, []int{}) 128 if err != nil { 129 t.Fatalf("Error creating KRB5Token: %v", err) 130 } 131 mb, err := mt.Marshal() 132 if err != nil { 133 t.Fatalf("Error unmarshalling KRB5Token: %v", err) 134 } 135 err = mt.Unmarshal(mb) 136 if err != nil { 137 t.Fatalf("Error unmarshalling KRB5Token: %v", err) 138 } 139 assert.Equal(t, asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}, mt.OID, "KRB5Token OID not as expected.") 140 assert.Equal(t, []byte{1, 0}, mt.tokID, "TokID not as expected") 141 assert.Equal(t, msgtype.KRB_AP_REQ, mt.APReq.MsgType, "KRB5Token AP_REQ does not have the right message type.") 142 assert.Equal(t, int32(0), mt.KRBError.ErrorCode, "KRBError in KRB5Token does not indicate no error.") 143 assert.Equal(t, testdata.TEST_REALM, mt.APReq.Ticket.Realm, "Realm in ticket within the AP_REQ of the KRB5Token not as expected.") 144 assert.Equal(t, testdata.TEST_PRINCIPALNAME_NAMESTRING, mt.APReq.Ticket.SName.NameString, "SName in ticket within the AP_REQ of the KRB5Token not as expected.") 145 assert.Equal(t, int32(18), mt.APReq.EncryptedAuthenticator.EType, "Authenticator within AP_REQ does not have the etype expected.") 146 }