Пример #1
0
// OpenProtectedFile reads the header of the given protected file and returns the data
// needed to work further with that file.
func OpenProtectedFile(sync *SyncInfo, protFilePath string) (*Header, error) {
	f, err := os.Open(filepath.Join(sync.RemoteBase(), protFilePath))
	if err != nil {
		return nil, err
	}
	defer f.Close()

	// Decrypt header
	headBytes := memstream.New()
	keys := sync.Keys()
	encHeadLen, _, err := aes.Decrypt(f, headBytes, &keys)
	if err != nil {
		return nil, err
	}

	header := new(Header)
	header.sync = sync
	header.headerLen = int(encHeadLen)
	header.remotePath = protFilePath
	header.contentKeys = new(gocrypt.KeyCombo)

	// Interpret
	headBytes.Rewind()
	buf := bufio.NewReader(headBytes)

	version, err := buf.ReadByte()
	if err != nil {
		return nil, &ErrProtectedFile{"Unable to read header version", err}
	}

	switch version {
	case 1:
		// Format:
		// 1 - version (currently at version 1)
		// 16 - crypto key for contents
		// 16 - auth key
		// 32 - hash of DECRYPTED contents
		// 8 - length of Path
		// <Variable> - local relative path
		header.contentKeys.CryptoKey, err = readKey(buf)
		if err != nil {
			return nil, &ErrProtectedFile{"Unable to read crypto key", err}
		}

		header.contentKeys.AuthKey, err = readKey(buf)
		if err != nil {
			return nil, &ErrProtectedFile{"Unable to read auth key", err}
		}

		header.contentHash, err = readFixedSize(buf, hash.Sha256Size)
		if err != nil {
			return nil, &ErrProtectedFile{"Unable to read content hash", err}
		}

		lenBytes, err := readFixedSize(buf, 8)
		pathLen := gocrypt.BytesToUint64(lenBytes)
		if err != nil {
			return nil, &ErrProtectedFile{"Unable to read path length", err}
		}

		pathBytes, err := readFixedSize(buf, int(pathLen))
		header.localPath = string(pathBytes)
		if err != nil {
			return nil, &ErrProtectedFile{"Unable to read path", err}
		}

	default:
		return nil, &ErrProtectedFile{fmt.Sprintf("Version %v of header is not recognized", version), nil}
	}

	return header, nil
}
Пример #2
0
func bytesToInt64(b []byte) int64 {
	return int64(gocrypt.BytesToUint64(b))
}