vendor: Update github.com/t3rm1n4l/go-mega to fix base64 decoding issue

See: https://forum.rclone.org/t/problem-to-login-with-mega/12276
This commit is contained in:
Nick Craig-Wood 2019-10-14 11:24:03 +01:00
parent b4b59c53f1
commit 48fa6f5700
10 changed files with 473 additions and 677 deletions

4
go.mod
View File

@ -51,12 +51,12 @@ require (
github.com/spf13/cobra v0.0.5 github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.3 github.com/spf13/pflag v1.0.3
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
github.com/t3rm1n4l/go-mega v0.0.0-20190528125457-55e675378686 github.com/t3rm1n4l/go-mega v0.0.0-20191014094753-e8695d78299a
github.com/xanzy/ssh-agent v0.2.1 github.com/xanzy/ssh-agent v0.2.1
github.com/youmark/pkcs8 v0.0.0-20181201043747-70daafe5d78a github.com/youmark/pkcs8 v0.0.0-20181201043747-70daafe5d78a
github.com/yunify/qingstor-sdk-go/v3 v3.0.2 github.com/yunify/qingstor-sdk-go/v3 v3.0.2
go.etcd.io/bbolt v1.3.3 // indirect go.etcd.io/bbolt v1.3.3 // indirect
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/sync v0.0.0-20190423024810-112230192c58

6
go.sum
View File

@ -228,8 +228,8 @@ github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709 h1:Ko2LQMrRU+Oy
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/t3rm1n4l/go-mega v0.0.0-20190528125457-55e675378686 h1:U7mF+tjDK9zWoxCU+kBNa1XT7WZMF5bjwtRpjeIkSYw= github.com/t3rm1n4l/go-mega v0.0.0-20191014094753-e8695d78299a h1:9VwG6wBA1jd6oOCnmQ/OaKM1GRfChadtH5N3bx1oSKE=
github.com/t3rm1n4l/go-mega v0.0.0-20190528125457-55e675378686/go.mod h1:XWL4vDyd3JKmJx+hZWUVgCNmmhZ2dTBcaNDcxH465s0= github.com/t3rm1n4l/go-mega v0.0.0-20191014094753-e8695d78299a/go.mod h1:XWL4vDyd3JKmJx+hZWUVgCNmmhZ2dTBcaNDcxH465s0=
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
@ -252,6 +252,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=

View File

@ -105,7 +105,7 @@ type Mega struct {
// Server state sn // Server state sn
ssn string ssn string
// Session ID // Session ID
sid []byte sid string
// Master key // Master key
k []byte k []byte
// User handle // User handle
@ -407,8 +407,8 @@ func (m *Mega) api_request(r []byte) (buf []byte, err error) {
url := fmt.Sprintf("%s/cs?id=%d", m.baseurl, m.sn) url := fmt.Sprintf("%s/cs?id=%d", m.baseurl, m.sn)
if m.sid != nil { if m.sid != "" {
url = fmt.Sprintf("%s&sid=%s", url, string(m.sid)) url = fmt.Sprintf("%s&sid=%s", url, m.sid)
} }
sleepTime := minSleepTime // inital backoff time sleepTime := minSleepTime // inital backoff time
@ -499,7 +499,7 @@ func (m *Mega) prelogin(email string) error {
if len(res[0].Salt) == 0 { if len(res[0].Salt) == 0 {
return errors.New("prelogin: no salt returned") return errors.New("prelogin: no salt returned")
} }
m.accountSalt, err = base64urldecode([]byte(res[0].Salt)) m.accountSalt, err = base64urldecode(res[0].Salt)
if err != nil { if err != nil {
return err return err
} }
@ -532,7 +532,7 @@ func (m *Mega) login(email string, passwd string) error {
msg[0].Cmd = "us" msg[0].Cmd = "us"
msg[0].User = email msg[0].User = email
if m.accountVersion == 1 { if m.accountVersion == 1 {
msg[0].Handle = string(uhandle) msg[0].Handle = uhandle
} else { } else {
const derivedKeyLength = 2 * aes.BlockSize const derivedKeyLength = 2 * aes.BlockSize
derivedKey := pbkdf2.Key([]byte(passwd), m.accountSalt, 100000, derivedKeyLength, sha512.New) derivedKey := pbkdf2.Key([]byte(passwd), m.accountSalt, 100000, derivedKeyLength, sha512.New)
@ -544,8 +544,8 @@ func (m *Mega) login(email string, passwd string) error {
if err != nil { if err != nil {
return err return err
} }
msg[0].Handle = string(base64urlencode(authKey)) msg[0].Handle = base64urlencode(authKey)
msg[0].SessionKey = string(base64urlencode(sessionKey)) msg[0].SessionKey = base64urlencode(sessionKey)
} }
req, err := json.Marshal(msg) req, err := json.Marshal(msg)
@ -562,7 +562,7 @@ func (m *Mega) login(email string, passwd string) error {
return err return err
} }
m.k, err = base64urldecode([]byte(res[0].Key)) m.k, err = base64urldecode(res[0].Key)
if err != nil { if err != nil {
return err return err
} }
@ -571,7 +571,7 @@ func (m *Mega) login(email string, passwd string) error {
return err return err
} }
cipher.Decrypt(m.k, m.k) cipher.Decrypt(m.k, m.k)
m.sid, err = decryptSessionId([]byte(res[0].Privk), []byte(res[0].Csid), m.k) m.sid, err = decryptSessionId(res[0].Privk, res[0].Csid, m.k)
if err != nil { if err != nil {
return err return err
} }
@ -708,7 +708,7 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
switch { switch {
// File or folder owned by current user // File or folder owned by current user
case args[0] == itm.User: case args[0] == itm.User:
buf, err := base64urldecode([]byte(args[1])) buf, err := base64urldecode(args[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -722,7 +722,7 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
} }
// Shared folder // Shared folder
case itm.SUser != "" && itm.SKey != "": case itm.SUser != "" && itm.SKey != "":
sk, err := base64urldecode([]byte(itm.SKey)) sk, err := base64urldecode(itm.SKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -736,7 +736,7 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
} }
m.FS.skmap[itm.Hash] = itm.SKey m.FS.skmap[itm.Hash] = itm.SKey
buf, err := base64urldecode([]byte(args[1])) buf, err := base64urldecode(args[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -751,7 +751,7 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
// Shared file // Shared file
default: default:
k := m.FS.skmap[args[0]] k := m.FS.skmap[args[0]]
b, err := base64urldecode([]byte(k)) b, err := base64urldecode(k)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -763,7 +763,7 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
buf, err := base64urldecode([]byte(args[1])) buf, err := base64urldecode(args[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -779,6 +779,10 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
switch { switch {
case itm.T == FILE: case itm.T == FILE:
if len(compkey) < 8 {
m.logf("ignoring item: compkey too short (%d): %#v", len(compkey), itm)
return nil, nil
}
key = []uint32{compkey[0] ^ compkey[4], compkey[1] ^ compkey[5], compkey[2] ^ compkey[6], compkey[3] ^ compkey[7]} key = []uint32{compkey[0] ^ compkey[4], compkey[1] ^ compkey[5], compkey[2] ^ compkey[6], compkey[3] ^ compkey[7]}
default: default:
key = compkey key = compkey
@ -789,7 +793,7 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
// FIXME: // FIXME:
attr.Name = "BAD ATTRIBUTE" attr.Name = "BAD ATTRIBUTE"
} else { } else {
attr, err = decryptAttr(bkey, []byte(itm.Attr)) attr, err = decryptAttr(bkey, itm.Attr)
// FIXME: // FIXME:
if err != nil { if err != nil {
attr.Name = "BAD ATTRIBUTE" attr.Name = "BAD ATTRIBUTE"
@ -978,7 +982,12 @@ func (m *Mega) NewDownload(src *Node) (*Download, error) {
return nil, err return nil, err
} }
_, err = decryptAttr(key, []byte(res[0].Attr)) // DownloadResp has an embedded error in it for some reason
if res[0].Err != 0 {
return nil, parseError(res[0].Err)
}
_, err = decryptAttr(key, res[0].Attr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1484,8 +1493,8 @@ func (u *Upload) Finish() (node *Node, err error) {
cmsg[0].T = u.parenthash cmsg[0].T = u.parenthash
cmsg[0].N[0].H = string(u.completion_handle) cmsg[0].N[0].H = string(u.completion_handle)
cmsg[0].N[0].T = FILE cmsg[0].N[0].T = FILE
cmsg[0].N[0].A = string(attr_data) cmsg[0].N[0].A = attr_data
cmsg[0].N[0].K = string(base64urlencode(buf)) cmsg[0].N[0].K = base64urlencode(buf)
request, err := json.Marshal(cmsg) request, err := json.Marshal(cmsg)
if err != nil { if err != nil {
@ -1662,8 +1671,8 @@ func (m *Mega) Rename(src *Node, name string) error {
} }
msg[0].Cmd = "a" msg[0].Cmd = "a"
msg[0].Attr = string(attr_data) msg[0].Attr = attr_data
msg[0].Key = string(base64urlencode(key)) msg[0].Key = base64urlencode(key)
msg[0].N = src.hash msg[0].N = src.hash
msg[0].I, err = randString(10) msg[0].I, err = randString(10)
if err != nil { if err != nil {
@ -1723,8 +1732,8 @@ func (m *Mega) CreateDir(name string, parent *Node) (*Node, error) {
msg[0].T = parent.hash msg[0].T = parent.hash
msg[0].N[0].H = "xxxxxxxx" msg[0].N[0].H = "xxxxxxxx"
msg[0].N[0].T = FOLDER msg[0].N[0].T = FOLDER
msg[0].N[0].A = string(attr_data) msg[0].N[0].A = attr_data
msg[0].N[0].K = string(base64urlencode(key)) msg[0].N[0].K = base64urlencode(key)
msg[0].I, err = randString(10) msg[0].I, err = randString(10)
if err != nil { if err != nil {
return nil, err return nil, err
@ -1817,7 +1826,7 @@ func (m *Mega) processUpdateNode(evRaw []byte) error {
} }
node := m.FS.hashLookup(ev.N) node := m.FS.hashLookup(ev.N)
attr, err := decryptAttr(node.meta.key, []byte(ev.Attr)) attr, err := decryptAttr(node.meta.key, ev.Attr)
if err == nil { if err == nil {
node.name = attr.Name node.name = attr.Name
} else { } else {
@ -1861,7 +1870,7 @@ func (m *Mega) pollEvents() {
sleepTime = minSleepTime sleepTime = minSleepTime
} }
url := fmt.Sprintf("%s/sc?sn=%s&sid=%s", m.baseurl, m.ssn, string(m.sid)) url := fmt.Sprintf("%s/sc?sn=%s&sid=%s", m.baseurl, m.ssn, m.sid)
resp, err = m.client.Post(url, "application/xml", nil) resp, err = m.client.Post(url, "application/xml", nil)
if err != nil { if err != nil {
m.logf("pollEvents: Error fetching status: %s", err) m.logf("pollEvents: Error fetching status: %s", err)
@ -2014,7 +2023,7 @@ func (m *Mega) Link(n *Node, includeKey bool) (string, error) {
} }
if includeKey { if includeKey {
m.FS.mutex.Lock() m.FS.mutex.Lock()
key := string(base64urlencode(n.meta.compkey)) key := base64urlencode(n.meta.compkey)
m.FS.mutex.Unlock() m.FS.mutex.Unlock()
return fmt.Sprintf("%v/#!%v!%v", BASE_DOWNLOAD_URL, id, key), nil return fmt.Sprintf("%v/#!%v!%v", BASE_DOWNLOAD_URL, id, key), nil
} else { } else {

View File

@ -120,10 +120,10 @@ type DownloadMsg struct {
} }
type DownloadResp struct { type DownloadResp struct {
G string `json:"g"` G string `json:"g"`
Size uint64 `json:"s"` Size uint64 `json:"s"`
Attr string `json:"at"` Attr string `json:"at"`
Err uint32 `json:"e"` Err ErrorMsg `json:"e"`
} }
type UploadMsg struct { type UploadMsg struct {

View File

@ -66,48 +66,27 @@ func a32_to_bytes(a []uint32) ([]byte, error) {
return buf.Bytes(), nil return buf.Bytes(), nil
} }
// base64urlencode encodes byte slice b using base64 url encoding. // base64urlencode encodes byte slice b using base64 url encoding
// It removes `=` padding when necessary // without `=` padding.
func base64urlencode(b []byte) []byte { func base64urlencode(b []byte) string {
enc := base64.URLEncoding return base64.RawURLEncoding.EncodeToString(b)
encSize := enc.EncodedLen(len(b))
buf := make([]byte, encSize)
enc.Encode(buf, b)
paddSize := 3 - len(b)%3
if paddSize < 3 {
encSize -= paddSize
buf = buf[:encSize]
}
return buf
} }
// base64urldecode decodes the byte slice b using base64 url decoding. // base64urldecode decodes the byte slice b using unpadded base64 url
// It adds required '=' padding before decoding. // decoding. It also allows the characters from standard base64 to be
func base64urldecode(b []byte) ([]byte, error) { // compatible with the mega decoder.
enc := base64.URLEncoding func base64urldecode(s string) ([]byte, error) {
padSize := 4 - len(b)%4 enc := base64.RawURLEncoding
// mega base64 decoder accepts the characters from both URLEncoding and StdEncoding
switch padSize { // though nearly all strings are URL encoded
case 1: s = strings.Replace(s, "+", "-", -1)
b = append(b, '=') s = strings.Replace(s, "/", "_", -1)
case 2: return enc.DecodeString(s)
b = append(b, '=', '=')
}
decSize := enc.DecodedLen(len(b))
buf := make([]byte, decSize)
n, err := enc.Decode(buf, b)
if err != nil {
return nil, err
}
return buf[:n], err
} }
// base64_to_a32 converts base64 encoded byte slice b to uint32 slice. // base64_to_a32 converts base64 encoded byte slice b to uint32 slice.
func base64_to_a32(b []byte) ([]uint32, error) { func base64_to_a32(s string) ([]uint32, error) {
d, err := base64urldecode(b) d, err := base64urldecode(s)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -115,10 +94,10 @@ func base64_to_a32(b []byte) ([]uint32, error) {
} }
// a32_to_base64 converts uint32 slice to base64 encoded byte slice. // a32_to_base64 converts uint32 slice to base64 encoded byte slice.
func a32_to_base64(a []uint32) ([]byte, error) { func a32_to_base64(a []uint32) (string, error) {
d, err := a32_to_bytes(a) d, err := a32_to_bytes(a)
if err != nil { if err != nil {
return nil, err return "", err
} }
return base64urlencode(d), nil return base64urlencode(d), nil
} }
@ -181,10 +160,10 @@ func password_key(p string) ([]byte, error) {
// stringhash computes generic string hash. Uses k as the key for AES // stringhash computes generic string hash. Uses k as the key for AES
// cipher. // cipher.
func stringhash(s string, k []byte) ([]byte, error) { func stringhash(s string, k []byte) (string, error) {
a, err := bytes_to_a32(paddnull([]byte(s), 4)) a, err := bytes_to_a32(paddnull([]byte(s), 4))
if err != nil { if err != nil {
return nil, err return "", err
} }
h := []uint32{0, 0, 0, 0} h := []uint32{0, 0, 0, 0}
for i, v := range a { for i, v := range a {
@ -193,18 +172,18 @@ func stringhash(s string, k []byte) ([]byte, error) {
hb, err := a32_to_bytes(h) hb, err := a32_to_bytes(h)
if err != nil { if err != nil {
return nil, err return "", err
} }
cipher, err := aes.NewCipher(k) cipher, err := aes.NewCipher(k)
if err != nil { if err != nil {
return nil, err return "", err
} }
for i := 16384; i > 0; i-- { for i := 16384; i > 0; i-- {
cipher.Encrypt(hb, hb) cipher.Encrypt(hb, hb)
} }
ha, err := bytes_to_a32(paddnull(hb, 4)) ha, err := bytes_to_a32(paddnull(hb, 4))
if err != nil { if err != nil {
return nil, err return "", err
} }
return a32_to_base64([]uint32{ha[0], ha[2]}) return a32_to_base64([]uint32{ha[0], ha[2]})
@ -272,24 +251,24 @@ func blockEncrypt(blk cipher.Block, dst, src []byte) error {
// decryptSeessionId decrypts the session id using the given private // decryptSeessionId decrypts the session id using the given private
// key. // key.
func decryptSessionId(privk []byte, csid []byte, mk []byte) ([]byte, error) { func decryptSessionId(privk string, csid string, mk []byte) (string, error) {
block, err := aes.NewCipher(mk) block, err := aes.NewCipher(mk)
if err != nil { if err != nil {
return nil, err return "", err
} }
pk, err := base64urldecode(privk) pk, err := base64urldecode(privk)
if err != nil { if err != nil {
return nil, err return "", err
} }
err = blockDecrypt(block, pk, pk) err = blockDecrypt(block, pk, pk)
if err != nil { if err != nil {
return nil, err return "", err
} }
c, err := base64urldecode(csid) c, err := base64urldecode(csid)
if err != nil { if err != nil {
return nil, err return "", err
} }
m, _ := getMPI(c) m, _ := getMPI(c)
@ -328,7 +307,7 @@ func getChunkSizes(size int64) (chunks []chunkSize) {
var attrMatch = regexp.MustCompile(`{".*"}`) var attrMatch = regexp.MustCompile(`{".*"}`)
func decryptAttr(key []byte, data []byte) (attr FileAttr, err error) { func decryptAttr(key []byte, data string) (attr FileAttr, err error) {
err = EBADATTR err = EBADATTR
block, err := aes.NewCipher(key) block, err := aes.NewCipher(key)
if err != nil { if err != nil {
@ -340,7 +319,7 @@ func decryptAttr(key []byte, data []byte) (attr FileAttr, err error) {
} }
mode := cipher.NewCBCDecrypter(block, iv) mode := cipher.NewCBCDecrypter(block, iv)
buf := make([]byte, len(data)) buf := make([]byte, len(data))
ddata, err := base64urldecode([]byte(data)) ddata, err := base64urldecode(data)
if err != nil { if err != nil {
return attr, err return attr, err
} }
@ -357,15 +336,15 @@ func decryptAttr(key []byte, data []byte) (attr FileAttr, err error) {
return attr, err return attr, err
} }
func encryptAttr(key []byte, attr FileAttr) (b []byte, err error) { func encryptAttr(key []byte, attr FileAttr) (b string, err error) {
err = EBADATTR err = EBADATTR
block, err := aes.NewCipher(key) block, err := aes.NewCipher(key)
if err != nil { if err != nil {
return nil, err return "", err
} }
data, err := json.Marshal(attr) data, err := json.Marshal(attr)
if err != nil { if err != nil {
return nil, err return "", err
} }
attrib := []byte("MEGA") attrib := []byte("MEGA")
attrib = append(attrib, data...) attrib = append(attrib, data...)
@ -373,7 +352,7 @@ func encryptAttr(key []byte, attr FileAttr) (b []byte, err error) {
iv, err := a32_to_bytes([]uint32{0, 0, 0, 0}) iv, err := a32_to_bytes([]uint32{0, 0, 0, 0})
if err != nil { if err != nil {
return nil, err return "", err
} }
mode := cipher.NewCBCEncrypter(block, iv) mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(attrib, attrib) mode.CryptBlocks(attrib, attrib)

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !ppc64le,!arm64,!s390x arm64,!go1.11 gccgo appengine // +build !arm64,!s390x,!ppc64le arm64,!go1.11 gccgo appengine
package chacha20 package chacha20

View File

@ -6,22 +6,24 @@
package chacha20 package chacha20
import "encoding/binary" import (
"encoding/binary"
const (
bufSize = 256
haveAsm = true
) )
var haveAsm = true
const bufSize = 256
//go:noescape //go:noescape
func chaCha20_ctr32_vmx(out, inp *byte, len int, key *[8]uint32, counter *uint32) func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
func (c *Cipher) xorKeyStreamAsm(dst, src []byte) { func (c *Cipher) xorKeyStreamAsm(dst, src []byte) {
// This implementation can handle buffers that aren't multiples of
// 256.
if len(src) >= bufSize { if len(src) >= bufSize {
chaCha20_ctr32_vmx(&dst[0], &src[0], len(src)-len(src)%bufSize, &c.key, &c.counter) chaCha20_ctr32_vsx(&dst[0], &src[0], len(src), &c.key, &c.counter)
} } else if len(src)%bufSize != 0 {
if len(src)%bufSize != 0 { chaCha20_ctr32_vsx(&c.buf[0], &c.buf[0], bufSize, &c.key, &c.counter)
chaCha20_ctr32_vmx(&c.buf[0], &c.buf[0], bufSize, &c.key, &c.counter)
start := len(src) - len(src)%bufSize start := len(src) - len(src)%bufSize
ts, td, tb := src[start:], dst[start:], c.buf[:] ts, td, tb := src[start:], dst[start:], c.buf[:]
// Unroll loop to XOR 32 bytes per iteration. // Unroll loop to XOR 32 bytes per iteration.
@ -46,7 +48,6 @@ func (c *Cipher) xorKeyStreamAsm(dst, src []byte) {
td[i] = tb[i] ^ v td[i] = tb[i] ^ v
} }
c.len = bufSize - (len(src) % bufSize) c.len = bufSize - (len(src) % bufSize)
} }
} }

View File

@ -58,6 +58,14 @@ var serverForbiddenKexAlgos = map[string]struct{}{
kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests
} }
// preferredKexAlgos specifies the default preference for key-exchange algorithms
// in preference order.
var preferredKexAlgos = []string{
kexAlgoCurve25519SHA256,
kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
kexAlgoDH14SHA1,
}
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods // supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
// of authenticating servers) in preference order. // of authenticating servers) in preference order.
var supportedHostKeyAlgos = []string{ var supportedHostKeyAlgos = []string{
@ -246,7 +254,7 @@ func (c *Config) SetDefaults() {
c.Ciphers = ciphers c.Ciphers = ciphers
if c.KeyExchanges == nil { if c.KeyExchanges == nil {
c.KeyExchanges = supportedKexAlgos c.KeyExchanges = preferredKexAlgos
} }
if c.MACs == nil { if c.MACs == nil {

4
vendor/modules.txt vendored
View File

@ -169,7 +169,7 @@ github.com/spf13/pflag
# github.com/stretchr/testify v1.4.0 # github.com/stretchr/testify v1.4.0
github.com/stretchr/testify/assert github.com/stretchr/testify/assert
github.com/stretchr/testify/require github.com/stretchr/testify/require
# github.com/t3rm1n4l/go-mega v0.0.0-20190528125457-55e675378686 # github.com/t3rm1n4l/go-mega v0.0.0-20191014094753-e8695d78299a
github.com/t3rm1n4l/go-mega github.com/t3rm1n4l/go-mega
# github.com/xanzy/ssh-agent v0.2.1 # github.com/xanzy/ssh-agent v0.2.1
github.com/xanzy/ssh-agent github.com/xanzy/ssh-agent
@ -204,7 +204,7 @@ go.opencensus.io/trace
go.opencensus.io/trace/internal go.opencensus.io/trace/internal
go.opencensus.io/trace/propagation go.opencensus.io/trace/propagation
go.opencensus.io/trace/tracestate go.opencensus.io/trace/tracestate
# golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 # golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
golang.org/x/crypto/bcrypt golang.org/x/crypto/bcrypt
golang.org/x/crypto/blowfish golang.org/x/crypto/blowfish
golang.org/x/crypto/curve25519 golang.org/x/crypto/curve25519