crypto.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Package crypto implements cryptographic functions for Kerberos 5 implementation.
  2. package crypto
  3. import (
  4. "encoding/hex"
  5. "fmt"
  6. "github.com/jcmturner/gokrb5/v8/crypto/etype"
  7. "github.com/jcmturner/gokrb5/v8/iana/chksumtype"
  8. "github.com/jcmturner/gokrb5/v8/iana/etypeID"
  9. "github.com/jcmturner/gokrb5/v8/iana/patype"
  10. "github.com/jcmturner/gokrb5/v8/types"
  11. )
  12. // GetEtype returns an instances of the required etype struct for the etype ID.
  13. func GetEtype(id int32) (etype.EType, error) {
  14. switch id {
  15. case etypeID.AES128_CTS_HMAC_SHA1_96:
  16. var et Aes128CtsHmacSha96
  17. return et, nil
  18. case etypeID.AES256_CTS_HMAC_SHA1_96:
  19. var et Aes256CtsHmacSha96
  20. return et, nil
  21. case etypeID.AES128_CTS_HMAC_SHA256_128:
  22. var et Aes128CtsHmacSha256128
  23. return et, nil
  24. case etypeID.AES256_CTS_HMAC_SHA384_192:
  25. var et Aes256CtsHmacSha384192
  26. return et, nil
  27. case etypeID.DES3_CBC_SHA1_KD:
  28. var et Des3CbcSha1Kd
  29. return et, nil
  30. case etypeID.RC4_HMAC:
  31. var et RC4HMAC
  32. return et, nil
  33. default:
  34. return nil, fmt.Errorf("unknown or unsupported EType: %d", id)
  35. }
  36. }
  37. // GetChksumEtype returns an instances of the required etype struct for the checksum ID.
  38. func GetChksumEtype(id int32) (etype.EType, error) {
  39. switch id {
  40. case chksumtype.HMAC_SHA1_96_AES128:
  41. var et Aes128CtsHmacSha96
  42. return et, nil
  43. case chksumtype.HMAC_SHA1_96_AES256:
  44. var et Aes256CtsHmacSha96
  45. return et, nil
  46. case chksumtype.HMAC_SHA256_128_AES128:
  47. var et Aes128CtsHmacSha256128
  48. return et, nil
  49. case chksumtype.HMAC_SHA384_192_AES256:
  50. var et Aes256CtsHmacSha384192
  51. return et, nil
  52. case chksumtype.HMAC_SHA1_DES3_KD:
  53. var et Des3CbcSha1Kd
  54. return et, nil
  55. case chksumtype.KERB_CHECKSUM_HMAC_MD5:
  56. var et RC4HMAC
  57. return et, nil
  58. //case chksumtype.KERB_CHECKSUM_HMAC_MD5_UNSIGNED:
  59. // var et RC4HMAC
  60. // return et, nil
  61. default:
  62. return nil, fmt.Errorf("unknown or unsupported checksum type: %d", id)
  63. }
  64. }
  65. // GetKeyFromPassword generates an encryption key from the principal's password.
  66. func GetKeyFromPassword(passwd string, cname types.PrincipalName, realm string, etypeID int32, pas types.PADataSequence) (types.EncryptionKey, etype.EType, error) {
  67. var key types.EncryptionKey
  68. et, err := GetEtype(etypeID)
  69. if err != nil {
  70. return key, et, fmt.Errorf("error getting encryption type: %v", err)
  71. }
  72. sk2p := et.GetDefaultStringToKeyParams()
  73. var salt string
  74. var paID int32
  75. for _, pa := range pas {
  76. switch pa.PADataType {
  77. case patype.PA_PW_SALT:
  78. if paID > pa.PADataType {
  79. continue
  80. }
  81. salt = string(pa.PADataValue)
  82. case patype.PA_ETYPE_INFO:
  83. if paID > pa.PADataType {
  84. continue
  85. }
  86. var eti types.ETypeInfo
  87. err := eti.Unmarshal(pa.PADataValue)
  88. if err != nil {
  89. return key, et, fmt.Errorf("error unmashaling PA Data to PA-ETYPE-INFO2: %v", err)
  90. }
  91. if etypeID != eti[0].EType {
  92. et, err = GetEtype(eti[0].EType)
  93. if err != nil {
  94. return key, et, fmt.Errorf("error getting encryption type: %v", err)
  95. }
  96. }
  97. salt = string(eti[0].Salt)
  98. case patype.PA_ETYPE_INFO2:
  99. if paID > pa.PADataType {
  100. continue
  101. }
  102. var et2 types.ETypeInfo2
  103. err := et2.Unmarshal(pa.PADataValue)
  104. if err != nil {
  105. return key, et, fmt.Errorf("error unmashalling PA Data to PA-ETYPE-INFO2: %v", err)
  106. }
  107. if etypeID != et2[0].EType {
  108. et, err = GetEtype(et2[0].EType)
  109. if err != nil {
  110. return key, et, fmt.Errorf("error getting encryption type: %v", err)
  111. }
  112. }
  113. if len(et2[0].S2KParams) == 4 {
  114. sk2p = hex.EncodeToString(et2[0].S2KParams)
  115. }
  116. salt = et2[0].Salt
  117. }
  118. }
  119. if salt == "" {
  120. salt = cname.GetSalt(realm)
  121. }
  122. k, err := et.StringToKey(passwd, salt, sk2p)
  123. if err != nil {
  124. return key, et, fmt.Errorf("error deriving key from string: %+v", err)
  125. }
  126. key = types.EncryptionKey{
  127. KeyType: etypeID,
  128. KeyValue: k,
  129. }
  130. return key, et, nil
  131. }
  132. // GetEncryptedData encrypts the data provided and returns and EncryptedData type.
  133. // Pass a usage value of zero to use the key provided directly rather than deriving one.
  134. func GetEncryptedData(plainBytes []byte, key types.EncryptionKey, usage uint32, kvno int) (types.EncryptedData, error) {
  135. var ed types.EncryptedData
  136. et, err := GetEtype(key.KeyType)
  137. if err != nil {
  138. return ed, fmt.Errorf("error getting etype: %v", err)
  139. }
  140. _, b, err := et.EncryptMessage(key.KeyValue, plainBytes, usage)
  141. if err != nil {
  142. return ed, err
  143. }
  144. ed = types.EncryptedData{
  145. EType: key.KeyType,
  146. Cipher: b,
  147. KVNO: kvno,
  148. }
  149. return ed, nil
  150. }
  151. // DecryptEncPart decrypts the EncryptedData.
  152. func DecryptEncPart(ed types.EncryptedData, key types.EncryptionKey, usage uint32) ([]byte, error) {
  153. return DecryptMessage(ed.Cipher, key, usage)
  154. }
  155. // DecryptMessage decrypts the ciphertext and verifies the integrity.
  156. func DecryptMessage(ciphertext []byte, key types.EncryptionKey, usage uint32) ([]byte, error) {
  157. et, err := GetEtype(key.KeyType)
  158. if err != nil {
  159. return []byte{}, fmt.Errorf("error decrypting: %v", err)
  160. }
  161. b, err := et.DecryptMessage(key.KeyValue, ciphertext, usage)
  162. if err != nil {
  163. return nil, fmt.Errorf("error decrypting: %v", err)
  164. }
  165. return b, nil
  166. }