Example #1
0
// hashCore hashes a SectionReader using the ImoHash parameters.
func (imo *ImoHash) hashCore(f *io.SectionReader) [Size]byte {
	var result [Size]byte

	imo.hasher.Reset()

	if f.Size() < int64(imo.sampleThreshold) || imo.sampleSize < 1 {
		buffer := make([]byte, f.Size())
		f.Read(buffer)
		imo.hasher.Write(buffer)
	} else {
		buffer := make([]byte, imo.sampleSize)
		f.Read(buffer)
		imo.hasher.Write(buffer)
		f.Seek(f.Size()/2, 0)
		f.Read(buffer)
		imo.hasher.Write(buffer)
		f.Seek(int64(-imo.sampleSize), 2)
		f.Read(buffer)
		imo.hasher.Write(buffer)
	}

	hash := imo.hasher.Sum(nil)

	binary.PutUvarint(hash, uint64(f.Size()))
	copy(result[:], hash)

	return result
}
Example #2
0
/*ParsePackHeader A header appears at the beginning and consists of the following:

     4-byte signature:
         The signature is: {'P', 'A', 'C', 'K'}

     4-byte version number (network byte order):
	 Git currently accepts version number 2 or 3 but
         generates version 2 only.

     4-byte number of objects contained in the pack (network byte order)

     Observation: we cannot have more than 4G versions ;-) and
     more than 4G objects in a pack.

*/
func ParsePackHeader(pack *io.SectionReader) (version, objectCount uint32, err error) {
	buf := make([]byte, 12)
	_, err = pack.Read(buf)
	if err != nil {
		return
	}
	if signature := string(buf[:4]); signature != packSignature {
		err = errors.New("pack header has wrong signature: " + signature)
		return
	}
	version = binary.BigEndian.Uint32(buf[4:8])
	if version != 2 {
		err = fmt.Errorf("version unsupport: %d ", version)
		return
	}
	objectCount = binary.BigEndian.Uint32(buf[8:])
	return
}
Example #3
0
// newDecryptionReader returns an authenticated, decryption reader
func newDecryptionReader(r *io.SectionReader, f *File) (io.Reader, error) {
	keyLen := aesKeyLen(f.aesStrength)
	saltLen := keyLen / 2 // salt is half of key len
	if saltLen == 0 {
		return nil, ErrDecryption
	}
	// grab the salt and pwvv
	saltpwvv := make([]byte, saltLen+2)
	if _, err := r.Read(saltpwvv); err != nil {
		return nil, err
	}
	salt := saltpwvv[:saltLen]
	pwvv := saltpwvv[saltLen : saltLen+2]
	// generate keys only if we have a password
	if f.password == nil {
		return nil, ErrPassword
	}
	decKey, authKey, pwv := generateKeys(f.password(), salt, keyLen)
	if !checkPasswordVerification(pwv, pwvv) {
		return nil, ErrPassword
	}
	dataOff := int64(saltLen + 2)
	dataLen := int64(f.CompressedSize64 - uint64(saltLen) - 2 - 10)
	// // TODO(alex): Should the compressed sizes be fixed?
	// // Not the ideal place to do this.
	// f.CompressedSize64 = uint64(dataLen)
	// f.CompressedSize = uint32(dataLen)
	data := io.NewSectionReader(r, dataOff, dataLen)
	authOff := dataOff + dataLen
	authcode := io.NewSectionReader(r, authOff, 10)
	ar := newAuthReader(authKey, data, authcode, f.DeferAuth)
	dr := decryptStream(decKey, ar)
	if dr == nil {
		return nil, ErrDecryption
	}
	return dr, nil
}