krb5.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package packets
  2. import (
  3. "errors"
  4. "fmt"
  5. "strconv"
  6. "time"
  7. "encoding/asn1"
  8. "encoding/hex"
  9. )
  10. const (
  11. Krb5AsRequestType = 10
  12. Krb5Krb5PrincipalNameType = 1
  13. Krb5CryptDesCbcMd4 = 2
  14. Krb5CryptDescCbcMd5 = 3
  15. Krb5CryptRc4Hmac = 23
  16. )
  17. var (
  18. ErrNoCrypt = errors.New("No crypt alg found")
  19. ErrReqData = errors.New("Failed to extract pnData from as-req")
  20. ErrNoCipher = errors.New("No encryption type or cipher found")
  21. Krb5AsReqParam = "application,explicit,tag:10"
  22. )
  23. type Krb5PrincipalName struct {
  24. NameType int `asn1:"explicit,tag:0"`
  25. NameString []string `asn1:"general,explicit,tag:1"`
  26. }
  27. type Krb5EncryptedData struct {
  28. Etype int `asn1:"explicit,tag:0"`
  29. Kvno int `asn1:"optional,explicit,tag:1"`
  30. Cipher []byte `asn1:"explicit,tag:2"`
  31. }
  32. type Krb5Ticket struct {
  33. TktVno int `asn1:"explicit,tag:0"`
  34. Realm string `asn1:"general,explicit,tag:1"`
  35. Sname Krb5PrincipalName `asn1:"explicit,tag:2"`
  36. EncPart Krb5EncryptedData `asn1:"explicit,tag:3"`
  37. }
  38. type Krb5Address struct {
  39. AddrType int `asn1:"explicit,tag:0"`
  40. Krb5Address []byte `asn1:"explicit,tag:1"`
  41. }
  42. type Krb5PnData struct {
  43. Krb5PnDataType int `asn1:"explicit,tag:1"`
  44. Krb5PnDataValue []byte `asn1:"explicit,tag:2"`
  45. }
  46. type Krb5ReqBody struct {
  47. KDCOptions asn1.BitString `asn1:"explicit,tag:0"`
  48. Cname Krb5PrincipalName `asn1:"optional,explicit,tag:1"`
  49. Realm string `asn1:"general,explicit,tag:2"`
  50. Sname Krb5PrincipalName `asn1:"optional,explicit,tag:3"`
  51. From time.Time `asn1:"generalized,optional,explicit,tag:4"`
  52. Till time.Time `asn1:"generalized,optional,explicit,tag:5"`
  53. Rtime time.Time `asn1:"generalized,optional,explicit,tag:6"`
  54. Nonce int `asn1:"explicit,tag:7"`
  55. Etype []int `asn1:"explicit,tag:8"`
  56. Krb5Addresses []Krb5Address `asn1:"optional,explicit,tag:9"`
  57. EncAuthData Krb5EncryptedData `asn1:"optional,explicit,tag:10"`
  58. AdditionalKrb5Tickets []Krb5Ticket `asn1:"optional,explicit,tag:11"`
  59. }
  60. type Krb5Request struct {
  61. Pvno int `asn1:"explicit,tag:1"`
  62. MsgType int `asn1:"explicit,tag:2"`
  63. Krb5PnData []Krb5PnData `asn1:"optional,explicit,tag:3"`
  64. ReqBody Krb5ReqBody `asn1:"explicit,tag:4"`
  65. }
  66. func (kdc Krb5Request) String() (string, error) {
  67. var eType, cipher string
  68. if kdc.ReqBody.Cname.NameType != Krb5Krb5PrincipalNameType {
  69. return "", ErrNoCrypt
  70. }
  71. realm := kdc.ReqBody.Realm
  72. crypt := kdc.ReqBody.Cname.NameString
  73. for _, pn := range kdc.Krb5PnData {
  74. if pn.Krb5PnDataType == 2 {
  75. enc, err := pn.getParsedValue()
  76. if err != nil {
  77. return "", ErrReqData
  78. }
  79. eType = strconv.Itoa(enc.Etype)
  80. cipher = hex.EncodeToString(enc.Cipher)
  81. }
  82. }
  83. if eType == "" || cipher == "" {
  84. return "", ErrNoCipher
  85. }
  86. return fmt.Sprintf("$krb5$%s$%s$%s$nodata$%s", eType, crypt[0], realm, cipher), nil
  87. }
  88. func (pd Krb5PnData) getParsedValue() (Krb5EncryptedData, error) {
  89. var encData Krb5EncryptedData
  90. _, err := asn1.Unmarshal(pd.Krb5PnDataValue, &encData)
  91. if err != nil {
  92. return Krb5EncryptedData{}, ErrReqData
  93. }
  94. return encData, nil
  95. }