config.go 2.6 KB

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