refactor: qmc don't export internal functions
This commit is contained in:
parent
b275b552ed
commit
4365628bff
@ -8,7 +8,7 @@ type mapCipher struct {
|
|||||||
size int
|
size int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMapCipher(key []byte) (*mapCipher, error) {
|
func newMapCipher(key []byte) (*mapCipher, error) {
|
||||||
if len(key) == 0 {
|
if len(key) == 0 {
|
||||||
return nil, errors.New("qmc/cipher_map: invalid key size")
|
return nil, errors.New("qmc/cipher_map: invalid key size")
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ func Test_mapCipher_Decrypt(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("load testing data failed: %s", err)
|
t.Fatalf("load testing data failed: %s", err)
|
||||||
}
|
}
|
||||||
c, err := NewMapCipher(key)
|
c, err := newMapCipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("init mapCipher failed: %s", err)
|
t.Errorf("init mapCipher failed: %s", err)
|
||||||
return
|
return
|
||||||
|
@ -12,9 +12,9 @@ type rc4Cipher struct {
|
|||||||
n int
|
n int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRC4Cipher creates and returns a new rc4Cipher. The key argument should be the
|
// newRC4Cipher creates and returns a new rc4Cipher. The key argument should be the
|
||||||
// RC4 key, at least 1 byte and at most 256 bytes.
|
// RC4 key, at least 1 byte and at most 256 bytes.
|
||||||
func NewRC4Cipher(key []byte) (*rc4Cipher, error) {
|
func newRC4Cipher(key []byte) (*rc4Cipher, error) {
|
||||||
n := len(key)
|
n := len(key)
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return nil, errors.New("qmc/cipher_rc4: invalid key size")
|
return nil, errors.New("qmc/cipher_rc4: invalid key size")
|
||||||
|
@ -37,7 +37,7 @@ func Test_rc4Cipher_Decrypt(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("load testing data failed: %s", err)
|
t.Fatalf("load testing data failed: %s", err)
|
||||||
}
|
}
|
||||||
c, err := NewRC4Cipher(key)
|
c, err := newRC4Cipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("init rc4Cipher failed: %s", err)
|
t.Errorf("init rc4Cipher failed: %s", err)
|
||||||
return
|
return
|
||||||
@ -55,7 +55,7 @@ func BenchmarkRc4Cipher_Decrypt(b *testing.B) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("load testing data failed: %s", err)
|
b.Fatalf("load testing data failed: %s", err)
|
||||||
}
|
}
|
||||||
c, err := NewRC4Cipher(key)
|
c, err := newRC4Cipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Errorf("init rc4Cipher failed: %s", err)
|
b.Errorf("init rc4Cipher failed: %s", err)
|
||||||
return
|
return
|
||||||
@ -72,7 +72,7 @@ func Test_rc4Cipher_encFirstSegment(t *testing.T) {
|
|||||||
t.Fatalf("load testing data failed: %s", err)
|
t.Fatalf("load testing data failed: %s", err)
|
||||||
}
|
}
|
||||||
t.Run("first-block(0~128)", func(t *testing.T) {
|
t.Run("first-block(0~128)", func(t *testing.T) {
|
||||||
c, err := NewRC4Cipher(key)
|
c, err := newRC4Cipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("init rc4Cipher failed: %s", err)
|
t.Errorf("init rc4Cipher failed: %s", err)
|
||||||
return
|
return
|
||||||
@ -91,7 +91,7 @@ func Test_rc4Cipher_encASegment(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.Run("align-block(128~5120)", func(t *testing.T) {
|
t.Run("align-block(128~5120)", func(t *testing.T) {
|
||||||
c, err := NewRC4Cipher(key)
|
c, err := newRC4Cipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("init rc4Cipher failed: %s", err)
|
t.Errorf("init rc4Cipher failed: %s", err)
|
||||||
return
|
return
|
||||||
@ -102,7 +102,7 @@ func Test_rc4Cipher_encASegment(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("simple-block(5120~10240)", func(t *testing.T) {
|
t.Run("simple-block(5120~10240)", func(t *testing.T) {
|
||||||
c, err := NewRC4Cipher(key)
|
c, err := newRC4Cipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("init rc4Cipher failed: %s", err)
|
t.Errorf("init rc4Cipher failed: %s", err)
|
||||||
return
|
return
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package qmc
|
package qmc
|
||||||
|
|
||||||
func NewStaticCipher() *staticCipher {
|
func newStaticCipher() *staticCipher {
|
||||||
return &defaultStaticCipher
|
return &defaultStaticCipher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ func simpleMakeKey(salt byte, length int) []byte {
|
|||||||
|
|
||||||
const rawKeyPrefixV2 = "QQMusic EncV2,Key:"
|
const rawKeyPrefixV2 = "QQMusic EncV2,Key:"
|
||||||
|
|
||||||
func DecryptKey(rawKey []byte) ([]byte, error) {
|
func deriveKey(rawKey []byte) ([]byte, error) {
|
||||||
rawKeyDec := make([]byte, base64.StdEncoding.DecodedLen(len(rawKey)))
|
rawKeyDec := make([]byte, base64.StdEncoding.DecodedLen(len(rawKey)))
|
||||||
n, err := base64.StdEncoding.Decode(rawKeyDec, rawKey)
|
n, err := base64.StdEncoding.Decode(rawKeyDec, rawKey)
|
||||||
if err != nil {
|
if err != nil {
|
@ -43,13 +43,13 @@ func TestDecryptKey(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("load test data failed: %s", err)
|
t.Fatalf("load test data failed: %s", err)
|
||||||
}
|
}
|
||||||
got, err := DecryptKey(raw)
|
got, err := deriveKey(raw)
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("DecryptKey() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("deriveKey() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(got, want) {
|
if !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("DecryptKey() got = %v..., want %v...",
|
t.Errorf("deriveKey() got = %v..., want %v...",
|
||||||
string(got[:32]), string(want[:32]))
|
string(got[:32]), string(want[:32]))
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -28,18 +28,16 @@ type Decoder struct {
|
|||||||
// Validate should call before Read to check if the file is valid.
|
// Validate should call before Read to check if the file is valid.
|
||||||
func (d *Decoder) Read(p []byte) (int, error) {
|
func (d *Decoder) Read(p []byte) (int, error) {
|
||||||
n := len(p)
|
n := len(p)
|
||||||
if d.audioLen-d.offset <= 0 {
|
if d.audioLen <= d.offset {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
} else if d.audioLen-d.offset < n {
|
} else if d.audioLen-d.offset < n {
|
||||||
n = d.audioLen - d.offset
|
n = d.audioLen - d.offset
|
||||||
}
|
}
|
||||||
m, err := d.r.Read(p[:n])
|
m, err := d.r.Read(p[:n])
|
||||||
if m == 0 {
|
if m > 0 {
|
||||||
return 0, err
|
d.cipher.Decrypt(p[:m], d.offset)
|
||||||
|
d.offset += m
|
||||||
}
|
}
|
||||||
|
|
||||||
d.cipher.Decrypt(p[:m], d.offset)
|
|
||||||
d.offset += m
|
|
||||||
return m, err
|
return m, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,17 +49,17 @@ func NewDecoder(r io.ReadSeeker) (*Decoder, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(d.decodedKey) > 300 {
|
if len(d.decodedKey) > 300 {
|
||||||
d.cipher, err = NewRC4Cipher(d.decodedKey)
|
d.cipher, err = newRC4Cipher(d.decodedKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else if len(d.decodedKey) != 0 {
|
} else if len(d.decodedKey) != 0 {
|
||||||
d.cipher, err = NewMapCipher(d.decodedKey)
|
d.cipher, err = newMapCipher(d.decodedKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
d.cipher = NewStaticCipher()
|
d.cipher = newStaticCipher()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = d.r.Seek(0, io.SeekStart)
|
_, err = d.r.Seek(0, io.SeekStart)
|
||||||
@ -110,7 +108,7 @@ func (d *Decoder) searchKey() error {
|
|||||||
return errors.New("qmc: file with 'STag' suffix doesn't contains media key")
|
return errors.New("qmc: file with 'STag' suffix doesn't contains media key")
|
||||||
} else {
|
} else {
|
||||||
size := binary.LittleEndian.Uint32(buf)
|
size := binary.LittleEndian.Uint32(buf)
|
||||||
if size < 0x300 && size != 0 {
|
if size <= 0xFFFF && size != 0 { // assume size is key len
|
||||||
return d.readRawKey(int64(size))
|
return d.readRawKey(int64(size))
|
||||||
}
|
}
|
||||||
// try to use default static cipher
|
// try to use default static cipher
|
||||||
@ -134,7 +132,7 @@ func (d *Decoder) readRawKey(rawKeyLen int64) error {
|
|||||||
// clean suffix NULs
|
// clean suffix NULs
|
||||||
rawKeyData = bytes.TrimRight(rawKeyData, "\x00")
|
rawKeyData = bytes.TrimRight(rawKeyData, "\x00")
|
||||||
|
|
||||||
d.decodedKey, err = DecryptKey(rawKeyData)
|
d.decodedKey, err = deriveKey(rawKeyData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -169,7 +167,7 @@ func (d *Decoder) readRawMetaQTag() error {
|
|||||||
return errors.New("invalid raw meta data")
|
return errors.New("invalid raw meta data")
|
||||||
}
|
}
|
||||||
|
|
||||||
d.decodedKey, err = DecryptKey([]byte(items[0]))
|
d.decodedKey, err = deriveKey([]byte(items[0]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user