config.go 2.7 KB

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