github.com/jcmturner/gokrb5/v8@v8.4.4/gssapi/wrapToken_test.go (about)

     1  package gssapi
     2  
     3  import (
     4  	"encoding/binary"
     5  	"encoding/hex"
     6  	"testing"
     7  
     8  	"github.com/jcmturner/gokrb5/v8/iana/keyusage"
     9  	"github.com/jcmturner/gokrb5/v8/types"
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  const (
    14  	// What a kerberized server might send
    15  	testChallengeFromAcceptor = "050401ff000c000000000000575e85d601010000853b728d5268525a1386c19f"
    16  	// What an initiator client could reply
    17  	testChallengeReplyFromInitiator = "050400ff000c000000000000000000000101000079a033510b6f127212242b97"
    18  	// session key used to sign the tokens above
    19  	sessionKey     = "14f9bde6b50ec508201a97f74c4e5bd3"
    20  	sessionKeyType = 17
    21  
    22  	acceptorSeal  = keyusage.GSSAPI_ACCEPTOR_SEAL
    23  	initiatorSeal = keyusage.GSSAPI_INITIATOR_SEAL
    24  )
    25  
    26  func getSessionKey() types.EncryptionKey {
    27  	key, _ := hex.DecodeString(sessionKey)
    28  	return types.EncryptionKey{
    29  		KeyType:  sessionKeyType,
    30  		KeyValue: key,
    31  	}
    32  }
    33  
    34  func getChallengeReference() *WrapToken {
    35  	challenge, _ := hex.DecodeString(testChallengeFromAcceptor)
    36  	return &WrapToken{
    37  		Flags:     0x01,
    38  		EC:        12,
    39  		RRC:       0,
    40  		SndSeqNum: binary.BigEndian.Uint64(challenge[8:16]),
    41  		Payload:   []byte{0x01, 0x01, 0x00, 0x00},
    42  		CheckSum:  challenge[20:32],
    43  	}
    44  }
    45  
    46  func getChallengeReferenceNoChksum() *WrapToken {
    47  	c := getChallengeReference()
    48  	c.CheckSum = nil
    49  	return c
    50  }
    51  
    52  func getResponseReference() *WrapToken {
    53  	response, _ := hex.DecodeString(testChallengeReplyFromInitiator)
    54  	return &WrapToken{
    55  		Flags:     0x00,
    56  		EC:        12,
    57  		RRC:       0,
    58  		SndSeqNum: 0,
    59  		Payload:   []byte{0x01, 0x01, 0x00, 0x00},
    60  		CheckSum:  response[20:32],
    61  	}
    62  }
    63  
    64  func getResponseReferenceNoChkSum() *WrapToken {
    65  	r := getResponseReference()
    66  	r.CheckSum = nil
    67  	return r
    68  }
    69  
    70  func TestUnmarshal_Challenge(t *testing.T) {
    71  	t.Parallel()
    72  	challenge, _ := hex.DecodeString(testChallengeFromAcceptor)
    73  	var wt WrapToken
    74  	err := wt.Unmarshal(challenge, true)
    75  	assert.Nil(t, err, "Unexpected error occurred.")
    76  	assert.Equal(t, getChallengeReference(), &wt, "Token not decoded as expected.")
    77  }
    78  
    79  func TestUnmarshalFailure_Challenge(t *testing.T) {
    80  	t.Parallel()
    81  	challenge, _ := hex.DecodeString(testChallengeFromAcceptor)
    82  	var wt WrapToken
    83  	err := wt.Unmarshal(challenge, false)
    84  	assert.NotNil(t, err, "Expected error did not occur: a message from the acceptor cannot be expected to be sent from the initiator.")
    85  	assert.Nil(t, wt.Payload, "Token fields should not have been initialised")
    86  	assert.Nil(t, wt.CheckSum, "Token fields should not have been initialised")
    87  	assert.Equal(t, byte(0x00), wt.Flags, "Token fields should not have been initialised")
    88  	assert.Equal(t, uint16(0), wt.EC, "Token fields should not have been initialised")
    89  	assert.Equal(t, uint16(0), wt.RRC, "Token fields should not have been initialised")
    90  	assert.Equal(t, uint64(0), wt.SndSeqNum, "Token fields should not have been initialised")
    91  }
    92  
    93  func TestUnmarshal_ChallengeReply(t *testing.T) {
    94  	t.Parallel()
    95  	response, _ := hex.DecodeString(testChallengeReplyFromInitiator)
    96  	var wt WrapToken
    97  	err := wt.Unmarshal(response, false)
    98  	assert.Nil(t, err, "Unexpected error occurred.")
    99  	assert.Equal(t, getResponseReference(), &wt, "Token not decoded as expected.")
   100  }
   101  
   102  func TestUnmarshalFailure_ChallengeReply(t *testing.T) {
   103  	t.Parallel()
   104  	response, _ := hex.DecodeString(testChallengeReplyFromInitiator)
   105  	var wt WrapToken
   106  	err := wt.Unmarshal(response, true)
   107  	assert.NotNil(t, err, "Expected error did not occur: a message from the initiator cannot be expected to be sent from the acceptor.")
   108  	assert.Nil(t, wt.Payload, "Token fields should not have been initialised")
   109  	assert.Nil(t, wt.CheckSum, "Token fields should not have been initialised")
   110  	assert.Equal(t, byte(0x00), wt.Flags, "Token fields should not have been initialised")
   111  	assert.Equal(t, uint16(0), wt.EC, "Token fields should not have been initialised")
   112  	assert.Equal(t, uint16(0), wt.RRC, "Token fields should not have been initialised")
   113  	assert.Equal(t, uint64(0), wt.SndSeqNum, "Token fields should not have been initialised")
   114  }
   115  
   116  func TestChallengeChecksumVerification(t *testing.T) {
   117  	t.Parallel()
   118  	challenge, _ := hex.DecodeString(testChallengeFromAcceptor)
   119  	var wt WrapToken
   120  	wt.Unmarshal(challenge, true)
   121  	challengeOk, cErr := wt.Verify(getSessionKey(), acceptorSeal)
   122  	assert.Nil(t, cErr, "Error occurred during checksum verification.")
   123  	assert.True(t, challengeOk, "Checksum verification failed.")
   124  }
   125  
   126  func TestResponseChecksumVerification(t *testing.T) {
   127  	t.Parallel()
   128  	reply, _ := hex.DecodeString(testChallengeReplyFromInitiator)
   129  	var wt WrapToken
   130  	wt.Unmarshal(reply, false)
   131  	replyOk, rErr := wt.Verify(getSessionKey(), initiatorSeal)
   132  	assert.Nil(t, rErr, "Error occurred during checksum verification.")
   133  	assert.True(t, replyOk, "Checksum verification failed.")
   134  }
   135  
   136  func TestChecksumVerificationFailure(t *testing.T) {
   137  	t.Parallel()
   138  	challenge, _ := hex.DecodeString(testChallengeFromAcceptor)
   139  	var wt WrapToken
   140  	wt.Unmarshal(challenge, true)
   141  
   142  	// Test a failure with the correct key but wrong keyusage:
   143  	challengeOk, cErr := wt.Verify(getSessionKey(), initiatorSeal)
   144  	assert.NotNil(t, cErr, "Expected error did not occur.")
   145  	assert.False(t, challengeOk, "Checksum verification succeeded when it should have failed.")
   146  
   147  	wrongKeyVal, _ := hex.DecodeString("14f9bde6b50ec508201a97f74c4effff")
   148  	badKey := types.EncryptionKey{
   149  		KeyType:  sessionKeyType,
   150  		KeyValue: wrongKeyVal,
   151  	}
   152  	// Test a failure with the wrong key but correct keyusage:
   153  	wrongKeyOk, wkErr := wt.Verify(badKey, acceptorSeal)
   154  	assert.NotNil(t, wkErr, "Expected error did not occur.")
   155  	assert.False(t, wrongKeyOk, "Checksum verification succeeded when it should have failed.")
   156  }
   157  
   158  func TestMarshal_Challenge(t *testing.T) {
   159  	t.Parallel()
   160  	bytes, _ := getChallengeReference().Marshal()
   161  	assert.Equal(t, testChallengeFromAcceptor, hex.EncodeToString(bytes),
   162  		"Marshalling did not yield the expected result.")
   163  }
   164  
   165  func TestMarshal_ChallengeReply(t *testing.T) {
   166  	t.Parallel()
   167  	bytes, _ := getResponseReference().Marshal()
   168  	assert.Equal(t, testChallengeReplyFromInitiator, hex.EncodeToString(bytes),
   169  		"Marshalling did not yield the expected result.")
   170  }
   171  
   172  func TestMarshal_Failures(t *testing.T) {
   173  	t.Parallel()
   174  	noChkSum := getResponseReferenceNoChkSum()
   175  	chkBytes, chkErr := noChkSum.Marshal()
   176  	assert.Nil(t, chkBytes, "No bytes should be returned.")
   177  	assert.NotNil(t, chkErr, "Expected an error as no checksum was set")
   178  
   179  	noPayload := getResponseReference()
   180  	noPayload.Payload = nil
   181  	pldBytes, pldErr := noPayload.Marshal()
   182  	assert.Nil(t, pldBytes, "No bytes should be returned.")
   183  	assert.NotNil(t, pldErr, "Expected an error as no checksum was set")
   184  }
   185  
   186  func TestNewInitiatorTokenSignatureAndMarshalling(t *testing.T) {
   187  	t.Parallel()
   188  	token, tErr := NewInitiatorWrapToken([]byte{0x01, 0x01, 0x00, 0x00}, getSessionKey())
   189  	assert.Nil(t, tErr, "Unexpected error.")
   190  	assert.Equal(t, getResponseReference(), token, "Token failed to be marshalled to the expected bytes.")
   191  }