Exemple #1
0
// Decode decodes the given token and return its data
// and creation time in UTC.
func (tok *T) Decode(token []byte) (data []byte, creation time.Time, err error) {
	raw := make([]byte, base64.RawURLEncoding.DecodedLen(len(token)))
	n, err := base64.RawURLEncoding.Decode(raw, token)
	if err != nil {
		return nil, time.Time{}, err
	}
	raw = raw[:n]
	hash := tok.hmac()
	if len(raw) < aes.BlockSize*2+hash.Size() {
		return nil, time.Time{}, ErrInvalidToken
	}
	soff := len(raw) - hash.Size() // signature offset
	hash.Write(raw[:soff])
	want := hash.Sum(nil)
	have := raw[soff:]
	if !hmac.Equal(want, have) {
		return nil, time.Time{}, ErrInvalidTokenSignature
	}
	iv := raw[:aes.BlockSize]
	body := raw[aes.BlockSize:soff]
	if len(body)%aes.BlockSize != 0 {
		return nil, time.Time{}, ErrInvalidToken
	}
	mode := cipher.NewCBCDecrypter(tok.aes, iv)
	mode.CryptBlocks(body, body)
	ts := time.Unix(int64(binary.BigEndian.Uint32(body)), 0)
	body, err = pkcs7Unpad(body, aes.BlockSize)
	if err != nil {
		return nil, time.Time{}, err
	}
	return body[4:], ts.UTC(), nil
}
Exemple #2
0
func signPayload(payload, secret string, hashFunc func() hash.Hash) string {
	hash := hmac.New(hashFunc, []byte(secret))
	hash.Write([]byte(payload))
	signature := make([]byte, b64.EncodedLen(hash.Size()))
	b64.Encode(signature, hash.Sum(nil))
	return string(signature)
}
Exemple #3
0
// Encode encodes the given byte slice and returns a token.
func (tok *T) Encode(data []byte) (token []byte, err error) {
	if data == nil {
		data = []byte{}
	}
	body := make([]byte, 4+len(data))
	now := uint32(time.Now().UTC().Unix())
	binary.BigEndian.PutUint32(body, now)
	copy(body[4:], data)
	body, err = pkcs7Pad(body, aes.BlockSize)
	if err != nil {
		return nil, err
	}
	iv := NewKey(aes.BlockSize)
	mode := cipher.NewCBCEncrypter(tok.aes, iv)
	mode.CryptBlocks(body, body)
	hash := tok.hmac()
	// size = len(iv + aesblocks + signature)
	token = make([]byte, len(iv)+len(body)+hash.Size())
	copy(token, iv)
	offset := len(iv)
	copy(token[offset:], body)
	offset += len(body)
	hash.Write(token[:offset])
	copy(token[offset:], hash.Sum(nil))
	b := make([]byte, base64.RawURLEncoding.EncodedLen(len(token)))
	base64.RawURLEncoding.Encode(b, token)
	return b, nil
}
Exemple #4
0
// Calculates the key and iv for AES decryption given a password and salt.
func calcAes30Params(pass []uint16, salt []byte) (key, iv []byte) {
	p := make([]byte, 0, len(pass)*2+len(salt))
	for _, v := range pass {
		p = append(p, byte(v), byte(v>>8))
	}
	p = append(p, salt...)

	hash := sha1.New()
	iv = make([]byte, 16)
	s := make([]byte, 0, hash.Size())
	for i := 0; i < hashRounds; i++ {
		hash.Write(p)
		hash.Write([]byte{byte(i), byte(i >> 8), byte(i >> 16)})
		if i%(hashRounds/16) == 0 {
			s = hash.Sum(s[:0])
			iv[i/(hashRounds/16)] = s[4*4+3]
		}
	}
	key = hash.Sum(s[:0])
	key = key[:16]

	for k := key; len(k) >= 4; k = k[4:] {
		k[0], k[1], k[2], k[3] = k[3], k[2], k[1], k[0]
	}
	return key, iv
}
Exemple #5
0
// An implementation of PBKDF2 (Password-Based Key Derivation Function 2) as
// specified in PKCS #5 v2.0 from RSA Laboratorie and in `RFC 2898
// <http://www.ietf.org/rfc/rfc2898.txt>`.
func PBKDF2(hashfunc func([]byte) hash.Hash, password, salt []byte, iterations, keylen int) (key []byte) {

	var (
		digest          []byte
		i, j, k, length int
	)

	key = make([]byte, keylen)
	slice := key

	hash := hashfunc(password)
	hashlen := hash.Size()
	scratch := make([]byte, 4)

	for keylen > 0 {

		if hashlen > keylen {
			length = keylen
		} else {
			length = hashlen
		}

		i += 1

		scratch[0] = byte(i >> 24)
		scratch[1] = byte(i >> 16)
		scratch[2] = byte(i >> 8)
		scratch[3] = byte(i)

		hash.Write(salt)
		hash.Write(scratch)

		digest = hash.Sum()
		hash.Reset()

		for j = 0; j < length; j++ {
			slice[j] = digest[j]
		}

		for k = 1; k < iterations; k++ {
			hash.Write(digest)
			digest = hash.Sum()
			for j = 0; j < length; j++ {
				slice[j] ^= digest[j]
			}
			hash.Reset()
		}

		keylen -= length
		slice = slice[length:]

	}

	return

}
Exemple #6
0
func (self *FileNode) Signature() ([]byte, error) {
	if self.sig != nil {
		return self.sig, nil
	}
	hash := fnv.New64a()
	err := HashFile(self.Name(), hash)
	if err != nil {
		return nil, err
	}

	signature := make([]byte, 0, hash.Size())
	signature = hash.Sum(signature)
	self.sig = signature
	return signature, nil
}
Exemple #7
0
func (x *Xsrf) sign(data []byte) []byte {
	hash := x.hash()
	hash.Write(data)
	signing := hash.Sum(nil)

	bs := x.Pool.Get(len(data)+hash.Size(), false) // data+signature
	buf := bytes.NewBuffer(bs)
	buf.Write(data)
	buf.Write(signing)

	dst := x.Pool.Get(_ENCODING.EncodedLen(buf.Len()), true)
	_ENCODING.Encode(dst, buf.Bytes())
	x.Pool.Put(bs)

	return dst
}
Exemple #8
0
func (c *Cipher) encrypt(now int64, str string) string {
	hash := hmac.New(c.Hash, unsafe2.Bytes(c.SecretKey))

	if now == 0 {
		now = time.Now().Add(c.TTL).UnixNano()
	}
	hash.Write(unsafe2.Bytes(str))
	hash.Write(unsafe2.Bytes(c.segSep()))
	nows := strconv.FormatInt(now, 10)
	hash.Write(unsafe2.Bytes(nows))
	hash.Write(unsafe2.Bytes(c.segSep()))
	hash.Write(unsafe2.Bytes(c.SecretKey))
	sig := hash.Sum(nil)

	sigStr := hex.EncodeToString(sig[:hash.Size()/2])
	return str + c.segSep() + nows + c.segSep() + sigStr[:len(sigStr)/2]
}
Exemple #9
0
func (x *Xsrf) verify(signing []byte) []byte {
	dst := x.Pool.Get(_ENCODING.DecodedLen(len(signing)), true)
	n, err := _ENCODING.Decode(dst, signing)
	if err == nil {
		dst = dst[:n]
		hash := x.hash()

		sep := len(dst) - hash.Size()
		if sep > 0 {
			data := dst[:sep]
			hash.Write(data)

			if bytes.Equal(hash.Sum(nil), dst[sep:]) {
				return data
			}
		}
	}

	x.Pool.Put(dst)

	return nil
}
Exemple #10
0
// PayloadSign generates a sign based on the Algorithm instance variable.
// This fulfills the `PayloadSigner` interface
func (s EcdsaSign) PayloadSign(payload []byte) ([]byte, error) {
	hash, err := ecdsaHashForAlg(s.SignatureAlgorithm())
	if err != nil {
		return nil, err
	}

	privkey := s.PrivateKey
	if privkey == nil {
		return nil, errors.New("cannot proceed with Sign(): no private key available")
	}

	keysiz := hash.Size()
	curveBits := privkey.Curve.Params().BitSize
	if curveBits != keysiz*8 {
		return nil, errors.New("key size does not match curve bit size")
	}

	h := hash.New()
	h.Write(payload)
	signed := h.Sum(nil)
	if debug.Enabled {
		debug.Printf("payload = %s, signed -> %x", payload, signed)
	}

	r, v, err := ecdsa.Sign(rand.Reader, privkey, signed)
	if err != nil {
		return nil, err
	}

	out := make([]byte, keysiz*2)
	keys := [][]byte{r.Bytes(), v.Bytes()}
	for i, data := range keys {
		start := i * keysiz
		padlen := keysiz - len(data)
		copy(out[start+padlen:], data)
	}

	return out, nil
}
Exemple #11
0
// Decrypt decrypts an ECIES ciphertext.
func (prv *PrivateKey) Decrypt(rand io.Reader, c, s1, s2 []byte) (m []byte, err error) {
	if c == nil || len(c) == 0 {
		err = ErrInvalidMessage
		return
	}
	params := prv.PublicKey.Params
	if params == nil {
		if params = ParamsFromCurve(prv.PublicKey.Curve); params == nil {
			err = ErrUnsupportedECIESParameters
			return
		}
	}
	hash := params.Hash()

	var (
		rLen   int
		hLen   int = hash.Size()
		mStart int
		mEnd   int
	)

	switch c[0] {
	case 2, 3, 4:
		rLen = ((prv.PublicKey.Curve.Params().BitSize + 7) / 4)
		if len(c) < (rLen + hLen + 1) {
			err = ErrInvalidMessage
			return
		}
	default:
		err = ErrInvalidPublicKey
		return
	}

	mStart = rLen
	mEnd = len(c) - hLen

	R := new(PublicKey)
	R.Curve = prv.PublicKey.Curve
	R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen])
	if R.X == nil {
		err = ErrInvalidPublicKey
		return
	}
	if !R.Curve.IsOnCurve(R.X, R.Y) {
		err = ErrInvalidCurve
		return
	}

	z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen)
	if err != nil {
		return
	}

	K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
	if err != nil {
		return
	}

	Ke := K[:params.KeyLen]
	Km := K[params.KeyLen:]
	hash.Write(Km)
	Km = hash.Sum(nil)
	hash.Reset()

	d := messageTag(params.Hash, Km, c[mStart:mEnd], s2)
	if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 {
		err = ErrInvalidMessage
		return
	}

	m, err = symDecrypt(rand, params, Ke, c[mStart:mEnd])
	return
}