MICToken_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package gssapi
  2. import (
  3. "encoding/binary"
  4. "encoding/hex"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. "gopkg.in/jcmturner/gokrb5.v7/iana/keyusage"
  8. "gopkg.in/jcmturner/gokrb5.v7/types"
  9. )
  10. const (
  11. testMICPayload = "deadbeef"
  12. // What a kerberized server might send
  13. testMICChallengeFromAcceptor = "040401ffffffffff00000000575e85d6c34d12ba3e5b1b1310cd9cb3"
  14. // What an initiator client could reply
  15. testMICChallengeReplyFromInitiator = "040400ffffffffff00000000000000009649ca09d2f1bc51ff6e5ca3"
  16. acceptorSign = keyusage.GSSAPI_ACCEPTOR_SIGN
  17. initiatorSign = keyusage.GSSAPI_INITIATOR_SIGN
  18. )
  19. func getMICChallengeReference() *MICToken {
  20. challenge, _ := hex.DecodeString(testMICChallengeFromAcceptor)
  21. return &MICToken{
  22. Flags: MICTokenFlagSentByAcceptor,
  23. SndSeqNum: binary.BigEndian.Uint64(challenge[8:16]),
  24. Payload: nil,
  25. Checksum: challenge[16:],
  26. }
  27. }
  28. func getMICChallengeReferenceNoChksum() *MICToken {
  29. c := getMICChallengeReference()
  30. c.Checksum = nil
  31. return c
  32. }
  33. func getMICResponseReference() *MICToken {
  34. response, _ := hex.DecodeString(testMICChallengeReplyFromInitiator)
  35. return &MICToken{
  36. Flags: 0x00,
  37. SndSeqNum: 0,
  38. Payload: nil,
  39. Checksum: response[16:],
  40. }
  41. }
  42. func getMICResponseReferenceNoChkSum() *MICToken {
  43. r := getMICResponseReference()
  44. r.Checksum = nil
  45. return r
  46. }
  47. func TestUnmarshal_MICChallenge(t *testing.T) {
  48. t.Parallel()
  49. challenge, _ := hex.DecodeString(testMICChallengeFromAcceptor)
  50. var mt MICToken
  51. err := mt.Unmarshal(challenge, true)
  52. assert.Nil(t, err, "Unexpected error occurred.")
  53. assert.Equal(t, getMICChallengeReference(), &mt, "Token not decoded as expected.")
  54. }
  55. func TestUnmarshalFailure_MICChallenge(t *testing.T) {
  56. t.Parallel()
  57. challenge, _ := hex.DecodeString(testMICChallengeFromAcceptor)
  58. var mt MICToken
  59. err := mt.Unmarshal(challenge, false)
  60. assert.NotNil(t, err, "Expected error did not occur: a message from the acceptor cannot be expected to be sent from the initiator.")
  61. assert.Nil(t, mt.Payload, "Token fields should not have been initialised")
  62. assert.Nil(t, mt.Checksum, "Token fields should not have been initialised")
  63. assert.Equal(t, byte(0x00), mt.Flags, "Token fields should not have been initialised")
  64. assert.Equal(t, uint64(0), mt.SndSeqNum, "Token fields should not have been initialised")
  65. }
  66. func TestUnmarshal_MICChallengeReply(t *testing.T) {
  67. t.Parallel()
  68. response, _ := hex.DecodeString(testMICChallengeReplyFromInitiator)
  69. var mt MICToken
  70. err := mt.Unmarshal(response, false)
  71. assert.Nil(t, err, "Unexpected error occurred.")
  72. assert.Equal(t, getMICResponseReference(), &mt, "Token not decoded as expected.")
  73. }
  74. func TestUnmarshalFailure_MICChallengeReply(t *testing.T) {
  75. t.Parallel()
  76. response, _ := hex.DecodeString(testMICChallengeReplyFromInitiator)
  77. var mt MICToken
  78. err := mt.Unmarshal(response, true)
  79. assert.NotNil(t, err, "Expected error did not occur: a message from the initiator cannot be expected to be sent from the acceptor.")
  80. assert.Nil(t, mt.Payload, "Token fields should not have been initialised")
  81. assert.Nil(t, mt.Checksum, "Token fields should not have been initialised")
  82. assert.Equal(t, byte(0x00), mt.Flags, "Token fields should not have been initialised")
  83. assert.Equal(t, uint64(0), mt.SndSeqNum, "Token fields should not have been initialised")
  84. }
  85. func TestMICChallengeChecksumVerification(t *testing.T) {
  86. t.Parallel()
  87. challenge, _ := hex.DecodeString(testMICChallengeFromAcceptor)
  88. var mt MICToken
  89. mt.Unmarshal(challenge, true)
  90. mt.Payload, _ = hex.DecodeString(testMICPayload)
  91. challengeOk, cErr := mt.Verify(getSessionKey(), acceptorSign)
  92. assert.Nil(t, cErr, "Error occurred during checksum verification.")
  93. assert.True(t, challengeOk, "Checksum verification failed.")
  94. }
  95. func TestMICResponseChecksumVerification(t *testing.T) {
  96. t.Parallel()
  97. reply, _ := hex.DecodeString(testMICChallengeReplyFromInitiator)
  98. var mt MICToken
  99. mt.Unmarshal(reply, false)
  100. mt.Payload, _ = hex.DecodeString(testMICPayload)
  101. replyOk, rErr := mt.Verify(getSessionKey(), initiatorSign)
  102. assert.Nil(t, rErr, "Error occurred during checksum verification.")
  103. assert.True(t, replyOk, "Checksum verification failed.")
  104. }
  105. func TestMICChecksumVerificationFailure(t *testing.T) {
  106. t.Parallel()
  107. challenge, _ := hex.DecodeString(testMICChallengeFromAcceptor)
  108. var mt MICToken
  109. mt.Unmarshal(challenge, true)
  110. // Test a failure with the correct key but wrong keyusage:
  111. challengeOk, cErr := mt.Verify(getSessionKey(), initiatorSign)
  112. assert.NotNil(t, cErr, "Expected error did not occur.")
  113. assert.False(t, challengeOk, "Checksum verification succeeded when it should have failed.")
  114. wrongKeyVal, _ := hex.DecodeString("14f9bde6b50ec508201a97f74c4effff")
  115. badKey := types.EncryptionKey{
  116. KeyType: sessionKeyType,
  117. KeyValue: wrongKeyVal,
  118. }
  119. // Test a failure with the wrong key but correct keyusage:
  120. wrongKeyOk, wkErr := mt.Verify(badKey, acceptorSign)
  121. assert.NotNil(t, wkErr, "Expected error did not occur.")
  122. assert.False(t, wrongKeyOk, "Checksum verification succeeded when it should have failed.")
  123. }
  124. func TestMarshal_MICChallenge(t *testing.T) {
  125. t.Parallel()
  126. bytes, _ := getMICChallengeReference().Marshal()
  127. assert.Equal(t, testMICChallengeFromAcceptor, hex.EncodeToString(bytes),
  128. "Marshalling did not yield the expected result.")
  129. }
  130. func TestMarshal_MICChallengeReply(t *testing.T) {
  131. t.Parallel()
  132. bytes, _ := getMICResponseReference().Marshal()
  133. assert.Equal(t, testMICChallengeReplyFromInitiator, hex.EncodeToString(bytes),
  134. "Marshalling did not yield the expected result.")
  135. }
  136. func TestMarshal_MICFailures(t *testing.T) {
  137. t.Parallel()
  138. noChkSum := getMICResponseReferenceNoChkSum()
  139. chkBytes, chkErr := noChkSum.Marshal()
  140. assert.Nil(t, chkBytes, "No bytes should be returned.")
  141. assert.NotNil(t, chkErr, "Expected an error as no checksum was set")
  142. }
  143. func TestNewInitiatorMICTokenSignatureAndMarshalling(t *testing.T) {
  144. t.Parallel()
  145. bytes, _ := hex.DecodeString(testMICPayload)
  146. token, tErr := NewInitiatorMICToken(bytes, getSessionKey())
  147. token.Payload = nil
  148. assert.Nil(t, tErr, "Unexpected error.")
  149. assert.Equal(t, getMICResponseReference(), token, "Token failed to be marshalled to the expected bytes.")
  150. }