config.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package shadowsocks
  2. import (
  3. "bytes"
  4. "crypto/cipher"
  5. "crypto/md5"
  6. "v2ray.com/core/common/crypto"
  7. "v2ray.com/core/common/protocol"
  8. )
  9. type ShadowsocksAccount struct {
  10. Cipher Cipher
  11. Key []byte
  12. OneTimeAuth Account_OneTimeAuth
  13. }
  14. func (v *ShadowsocksAccount) Equals(another protocol.Account) bool {
  15. if account, ok := another.(*ShadowsocksAccount); ok {
  16. return bytes.Equal(v.Key, account.Key)
  17. }
  18. return false
  19. }
  20. func (v *Account) GetCipher() (Cipher, error) {
  21. switch v.CipherType {
  22. case CipherType_AES_128_CFB:
  23. return &AesCfb{KeyBytes: 16}, nil
  24. case CipherType_AES_256_CFB:
  25. return &AesCfb{KeyBytes: 32}, nil
  26. case CipherType_CHACHA20:
  27. return &ChaCha20{IVBytes: 8}, nil
  28. case CipherType_CHACHA20_IETF:
  29. return &ChaCha20{IVBytes: 12}, nil
  30. default:
  31. return nil, newError("Unsupported cipher.")
  32. }
  33. }
  34. func (v *Account) AsAccount() (protocol.Account, error) {
  35. cipher, err := v.GetCipher()
  36. if err != nil {
  37. return nil, newError("failed to get cipher").Base(err)
  38. }
  39. return &ShadowsocksAccount{
  40. Cipher: cipher,
  41. Key: v.GetCipherKey(),
  42. OneTimeAuth: v.Ota,
  43. }, nil
  44. }
  45. func (v *Account) GetCipherKey() []byte {
  46. ct, err := v.GetCipher()
  47. if err != nil {
  48. return nil
  49. }
  50. return PasswordToCipherKey(v.Password, ct.KeySize())
  51. }
  52. type Cipher interface {
  53. KeySize() int
  54. IVSize() int
  55. NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error)
  56. NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error)
  57. }
  58. type AesCfb struct {
  59. KeyBytes int
  60. }
  61. func (v *AesCfb) KeySize() int {
  62. return v.KeyBytes
  63. }
  64. func (v *AesCfb) IVSize() int {
  65. return 16
  66. }
  67. func (v *AesCfb) NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error) {
  68. stream := crypto.NewAesEncryptionStream(key, iv)
  69. return stream, nil
  70. }
  71. func (v *AesCfb) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
  72. stream := crypto.NewAesDecryptionStream(key, iv)
  73. return stream, nil
  74. }
  75. type ChaCha20 struct {
  76. IVBytes int
  77. }
  78. func (v *ChaCha20) KeySize() int {
  79. return 32
  80. }
  81. func (v *ChaCha20) IVSize() int {
  82. return v.IVBytes
  83. }
  84. func (v *ChaCha20) NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error) {
  85. return crypto.NewChaCha20Stream(key, iv), nil
  86. }
  87. func (v *ChaCha20) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
  88. return crypto.NewChaCha20Stream(key, iv), nil
  89. }
  90. func PasswordToCipherKey(password string, keySize int) []byte {
  91. pwdBytes := []byte(password)
  92. key := make([]byte, 0, keySize)
  93. md5Sum := md5.Sum(pwdBytes)
  94. key = append(key, md5Sum[:]...)
  95. for len(key) < keySize {
  96. md5Hash := md5.New()
  97. md5Hash.Write(md5Sum[:])
  98. md5Hash.Write(pwdBytes)
  99. md5Hash.Sum(md5Sum[:0])
  100. key = append(key, md5Sum[:]...)
  101. }
  102. return key
  103. }