Пример #1
0
func authKeyIsValid(key []byte, r *httpRequest, windowBits uint) bool {
	if len(key) == 0 {
		return false
	}

	return hmac.Equal(key, getAuthKey(r, unixTime, windowBits)) ||
		hmac.Equal(key, getAuthKey(r, unixTime-2-uint64(math.Pow(float64(windowBits), 2)), windowBits))
}
Пример #2
0
func TestKDF(t *testing.T) {
	kdf1 := kdf.KDF([]byte("aardvark"), kdf.DefaultSalt, kdf.DefaultReps)
	kdf2 := kdf.KDF([]byte("aardvark"), kdf.DefaultSalt, kdf.DefaultReps)
	if !hmac.Equal(kdf1, kdf2) {
		t.Error("Expected kdf's to be equal")
	}
	if hmac.Equal(kdf1, kdf.KDF([]byte("sailboat"), kdf.DefaultSalt, kdf.DefaultReps)) {
		t.Error("Expected kdf's not to be equal")
	}
	if len(kdf1) != 32 {
		t.Error("Expected key to be 32 bytes")
	}
}
Пример #3
0
func (rw *rlpxFrameRW) ReadMsg() (msg Msg, err error) {
	// read the header
	headbuf := make([]byte, 32)
	if _, err := io.ReadFull(rw.conn, headbuf); err != nil {
		return msg, err
	}
	// verify header mac
	shouldMAC := updateMAC(rw.ingressMAC, rw.macCipher, headbuf[:16])
	if !hmac.Equal(shouldMAC, headbuf[16:]) {
		return msg, errors.New("bad header MAC")
	}
	rw.dec.XORKeyStream(headbuf[:16], headbuf[:16]) // first half is now decrypted
	fsize := readInt24(headbuf)
	// ignore protocol type for now

	// read the frame content
	var rsize = fsize // frame size rounded up to 16 byte boundary
	if padding := fsize % 16; padding > 0 {
		rsize += 16 - padding
	}
	framebuf := make([]byte, rsize)
	if _, err := io.ReadFull(rw.conn, framebuf); err != nil {
		return msg, err
	}

	// read and validate frame MAC. we can re-use headbuf for that.
	rw.ingressMAC.Write(framebuf)
	fmacseed := rw.ingressMAC.Sum(nil)
	if _, err := io.ReadFull(rw.conn, headbuf[:16]); err != nil {
		return msg, err
	}
	shouldMAC = updateMAC(rw.ingressMAC, rw.macCipher, fmacseed)
	if !hmac.Equal(shouldMAC, headbuf[:16]) {
		return msg, errors.New("bad frame MAC")
	}

	// decrypt frame content
	rw.dec.XORKeyStream(framebuf, framebuf)

	// decode message code
	content := bytes.NewReader(framebuf[:fsize])
	if err := rlp.Decode(content, &msg.Code); err != nil {
		return msg, err
	}
	msg.Size = uint32(content.Len())
	msg.Payload = content
	return msg, nil
}
Пример #4
0
func (ds *decryptStream) processEncryptionBlock(bl *encryptionBlock) ([]byte, error) {

	blockNum := encryptionBlockNumber(bl.seqno - 1)

	if err := blockNum.check(); err != nil {
		return nil, err
	}

	nonce := nonceForChunkSecretBox(blockNum)
	ciphertext := bl.PayloadCiphertext

	// Check the authenticator.
	hashToAuthenticate := computePayloadHash(ds.headerHash, nonce, ciphertext)
	ourAuthenticator := hmacSHA512256(ds.macKey, hashToAuthenticate)
	if !hmac.Equal(ourAuthenticator, bl.HashAuthenticators[ds.position]) {
		return nil, ErrBadTag(bl.seqno)
	}

	plaintext, ok := secretbox.Open([]byte{}, ciphertext, (*[24]byte)(nonce), (*[32]byte)(ds.payloadKey))
	if !ok {
		return nil, ErrBadCiphertext(bl.seqno)
	}

	// The encoding of the empty buffer implies the EOF.  But otherwise, all mechanisms are the same.
	if len(plaintext) == 0 {
		return nil, nil
	}
	return plaintext, nil
}
Пример #5
0
func (ath *AuthReadWriter) readMessage() ([]byte, error) {
	header := make([]byte, 28+4)

	if _, err := io.ReadFull(ath.rwc, header); err != nil {
		return nil, err
	}

	size := binary.LittleEndian.Uint32(header[28:])
	if size > MaxMessageSize {
		return nil, fmt.Errorf("Message too large (%d/%d)", size, MaxMessageSize)
	}

	buf := make([]byte, size)

	if _, err := io.ReadAtLeast(ath.crypted, buf, int(size)); err != nil {
		return nil, err
	}

	macWriter := hmac.New(sha3.New224, ath.symkey)
	if _, err := macWriter.Write(buf); err != nil {
		return nil, err
	}

	mac := macWriter.Sum(nil)
	if !hmac.Equal(mac, header[:28]) {
		return nil, fmt.Errorf("Mac differs in received metadata message")
	}

	return buf, nil
}
Пример #6
0
func verifySignature(p7 *PKCS7, signer signerInfo) error {
	if len(signer.AuthenticatedAttributes) > 0 {
		// TODO(fullsailor): First check the content type match
		var digest []byte
		err := unmarshalAttribute(signer.AuthenticatedAttributes, oidAttributeMessageDigest, &digest)
		if err != nil {
			return err
		}
		hash, err := getHashForOID(signer.DigestAlgorithm.Algorithm)
		if err != nil {
			return err
		}
		h := hash.New()
		h.Write(p7.Content)
		computed := h.Sum(nil)
		if !hmac.Equal(digest, computed) {
			return &MessageDigestMismatchError{
				ExpectedDigest: digest,
				ActualDigest:   computed,
			}
		}
	}
	cert := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
	if cert == nil {
		return errors.New("pkcs7: No certificate for signer")
	}
	// TODO(fullsailor): Optionally verify certificate chain
	// TODO(fullsailor): Optionally verify signingTime against certificate NotAfter/NotBefore
	encodedAttributes, err := marshalAttributes(signer.AuthenticatedAttributes)
	if err != nil {
		return err
	}
	algo := x509.SHA1WithRSA
	return cert.CheckSignature(algo, encodedAttributes, signer.EncryptedDigest)
}
Пример #7
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
}
Пример #8
0
// Decrypt authentications and recovers the original message from
// its input using the private key and the ephemeral key included in
// the message.
func Decrypt(priv *ecdsa.PrivateKey, in []byte) (out []byte, err error) {
	ephLen := int(in[0])
	ephPub := in[1 : 1+ephLen]
	ct := in[1+ephLen:]
	if len(ct) < (sha1.Size + aes.BlockSize) {
		return nil, errors.New("Invalid ciphertext")
	}

	x, y := elliptic.Unmarshal(Curve(), ephPub)
	if x == nil {
		return nil, errors.New("Invalid public key")
	}

	x, _ = priv.Curve.ScalarMult(x, y, priv.D.Bytes())
	if x == nil {
		return nil, errors.New("Failed to generate encryption key")
	}
	shared := sha256.Sum256(x.Bytes())

	tagStart := len(ct) - sha1.Size
	h := hmac.New(sha1.New, shared[16:])
	h.Write(ct[:tagStart])
	mac := h.Sum(nil)
	if !hmac.Equal(mac, ct[tagStart:]) {
		return nil, errors.New("Invalid MAC")
	}

	paddedOut, err := symcrypt.DecryptCBC(ct[aes.BlockSize:tagStart], ct[:aes.BlockSize], shared[:16])
	if err != nil {
		return
	}
	out, err = padding.RemovePadding(paddedOut)
	return
}
Пример #9
0
func checkMAC(salt, message, messageMAC, key []byte) bool {
	mac := hmac.New(sha256.New, key)
	mac.Write(message)
	mac.Write(salt)
	expectedMAC := mac.Sum(nil)
	return hmac.Equal(messageMAC, expectedMAC)
}
Пример #10
0
func (TokenAuth) Authenticate(token string) (types.Uid, time.Time, int) {
	var zeroTime time.Time
	// [8:UID][4:expires][32:signature] == 44 bytes

	data, err := base64.URLEncoding.DecodeString(token)
	if err != nil {
		return types.ZeroUid, zeroTime, auth.ErrMalformed
	}

	if len(data) != token_len_decoded {
		return types.ZeroUid, zeroTime, auth.ErrMalformed
	}

	var uid types.Uid
	if err := uid.UnmarshalBinary(data[0:8]); err != nil {
		return types.ZeroUid, zeroTime, auth.ErrMalformed
	}

	hasher := hmac.New(sha256.New, hmac_salt)
	hasher.Write(data[:12])
	if !hmac.Equal(data[12:], hasher.Sum(nil)) {
		return types.ZeroUid, zeroTime, auth.ErrFailed
	}

	expires := time.Unix(int64(binary.LittleEndian.Uint32(data[8:12])), 0).UTC()
	if expires.Before(time.Now()) {
		return types.ZeroUid, zeroTime, auth.ErrExpired
	}

	return uid, expires, auth.NoErr
}
Пример #11
0
func (r *etmReader) macCheckThenDecrypt(m []byte) (int, error) {
	l := len(m)
	if l < r.mac.size {
		return 0, fmt.Errorf("buffer (%d) shorter than MAC size (%d)", l, r.mac.size)
	}

	mark := l - r.mac.size
	data := m[:mark]
	macd := m[mark:]

	r.mac.Write(data)
	expected := r.mac.Sum(nil)
	r.mac.Reset()

	// check mac. if failed, return error.
	if !hmac.Equal(macd, expected) {
		log.Debug("MAC Invalid:", expected, "!=", macd)
		return 0, ErrMACInvalid
	}

	// ok seems good. decrypt. (can decrypt in place, yay!)
	// log.Debugf("DEC ciphertext (%d): %s %v", len(data), data, data)
	r.str.XORKeyStream(data, data)
	// log.Debugf("DEC plaintext (%d): %s %v", len(data), data, data)

	return mark, nil
}
Пример #12
0
// CheckApiSign validates correctness of provided (in HTTP API request) sign
// comparing it with generated one
func CheckApiSign(secret string, data []byte, providedSign string) bool {
	if len(providedSign) != HMACLength {
		return false
	}
	sign := GenerateApiSign(secret, data)
	return hmac.Equal([]byte(sign), []byte(providedSign))
}
Пример #13
0
// CheckChannelSign validates a correctness of provided (in subscribe client command)
// sign comparing it with generated one
func CheckChannelSign(secret, client, channel, channelData, providedSign string) bool {
	if len(providedSign) != HMACLength {
		return false
	}
	sign := GenerateChannelSign(secret, client, channel, channelData)
	return hmac.Equal([]byte(sign), []byte(providedSign))
}
Пример #14
0
// CheckClientToken validates correctness of provided (by client connection) token
// comparing it with generated one
func CheckClientToken(secret, user, timestamp, info, providedToken string) bool {
	if len(providedToken) != HMACLength {
		return false
	}
	token := GenerateClientToken(secret, user, timestamp, info)
	return hmac.Equal([]byte(token), []byte(providedToken))
}
Пример #15
0
func checkMAC(mac hash.Hash, message, messageMAC []byte) bool {
	if _, err := mac.Write(message); err != nil {
		return false
	}
	expectedMAC := mac.Sum(nil)
	return hmac.Equal(messageMAC, expectedMAC)
}
Пример #16
0
func (wm *WhisperMessage) verifyMAC(senderIdentity, receiverIdentity *IdentityKey, macKey []byte) bool {
	macpos := len(wm.serialized) - macLength

	ourMAC := getMac(wm.Version, senderIdentity, receiverIdentity, macKey, wm.serialized[:macpos])
	theirMAC := wm.serialized[macpos:]
	return hmac.Equal(ourMAC, theirMAC)
}
Пример #17
0
func (ds *decryptStream) processEncryptionBlock(bl *EncryptionBlock) ([]byte, error) {

	blockNum := encryptionBlockNumber(bl.seqno - 1)

	if err := blockNum.check(); err != nil {
		return nil, err
	}

	nonce := ds.nonce.ForPayloadBox(blockNum)
	ciphertext := bl.PayloadCiphertext
	hash := sha512.Sum512(ciphertext)

	hashBox := ds.tagKey.Box(nonce, hash[:])
	ourAuthenticator := hashBox[:secretbox.Overhead]

	if !hmac.Equal(ourAuthenticator, bl.HashAuthenticators[ds.position]) {
		return nil, ErrBadTag(bl.seqno)
	}

	plaintext, ok := secretbox.Open([]byte{}, ciphertext, (*[24]byte)(nonce), (*[32]byte)(ds.payloadKey))
	if !ok {
		return nil, ErrBadCiphertext(bl.seqno)
	}

	// The encoding of the empty buffer implies the EOF.  But otherwise, all mechanisms are the same.
	if len(plaintext) == 0 {
		return nil, nil
	}
	return plaintext, nil
}
Пример #18
0
func TestCreateSignature(t *testing.T) {
	errStr := "Function return different result with the same parameters!"

	a := createSignature(secret, []byte("foo"), []byte("bar"))
	b := a

	if !hmac.Equal(a, b) {
		t.Errorf(errStr)
	}

	c := createSignature(secret, []byte("foo"), []byte("baz"))

	if hmac.Equal(a, c) {
		t.Errorf(errStr)
	}
}
Пример #19
0
// Decrypt checks the MAC then decrypts ciphertext into plaintext.
func (c *Crypter) Decrypt(ciphertext []byte) ([]byte, error) {
	var ed EncryptedData
	if err := proto.Unmarshal(ciphertext, &ed); err != nil {
		return nil, err
	}

	// TODO(tmroeder): we're currently mostly ignoring the CryptoHeader,
	// since we only have one key.
	if *ed.Header.Version != CryptoVersion_CRYPTO_VERSION_1 {
		return nil, newError("bad version")
	}

	// Check the HMAC before touching the ciphertext.
	fullCiphertext := make([]byte, len(ed.Iv)+len(ed.Ciphertext))
	copy(fullCiphertext, ed.Iv)
	copy(fullCiphertext[len(ed.Iv):], ed.Ciphertext)

	mac := hmac.New(sha256.New, c.hmacKey)
	mac.Write(fullCiphertext)
	m := mac.Sum(nil)
	if !hmac.Equal(m, ed.Mac) {
		return nil, newError("bad HMAC")
	}

	block, err := aes.NewCipher(c.aesKey)
	if err != nil {
		return nil, err
	}

	s := cipher.NewCTR(block, ed.Iv)
	data := make([]byte, len(ed.Ciphertext))
	s.XORKeyStream(data, ed.Ciphertext)
	return data, nil
}
Пример #20
0
// ValidateAuthorizeCodeSignature returns an AuthorizeCode, if the code argument is a valid authorize code
// and the signature matches the key.
func (c *HMACSHAEnigma) ValidateChallenge(secret []byte, t *Challenge) (err error) {
	if t.Key == "" || t.Signature == "" {
		return errors.New("Key and signature must both be not empty")
	}

	signature, err := b64.DecodeString(t.Signature)
	if err != nil {
		return err
	}

	key, err := b64.DecodeString(t.Key)
	if err != nil {
		return err
	}

	useSecret := append([]byte{}, c.GlobalSecret...)
	mac := hmac.New(sha256.New, append(useSecret, secret...))
	_, err = mac.Write(key)
	if err != nil {
		return errors.New(err)
	}

	if !hmac.Equal(signature, mac.Sum([]byte{})) {
		// Hash is invalid
		return errors.New("Key and signature do not match")
	}

	return nil
}
Пример #21
0
// unpackUploadState unpacks and validates the layer upload state from the
// token, using the hmacKey secret.
func (secret hmacKey) unpackUploadState(token string) (layerUploadState, error) {
	var state layerUploadState

	tokenBytes, err := base64.URLEncoding.DecodeString(token)
	if err != nil {
		return state, err
	}
	mac := hmac.New(sha256.New, []byte(secret))

	if len(tokenBytes) < mac.Size() {
		return state, fmt.Errorf("Invalid token")
	}

	macBytes := tokenBytes[:mac.Size()]
	messageBytes := tokenBytes[mac.Size():]

	mac.Write(messageBytes)
	if !hmac.Equal(mac.Sum(nil), macBytes) {
		return state, fmt.Errorf("Invalid token")
	}

	if err := json.Unmarshal(messageBytes, &state); err != nil {
		return state, err
	}

	return state, nil
}
Пример #22
0
func secureInProxy(in <-chan []byte, secureIn chan<- []byte, hashType string, tIV, tCKey, tMKey []byte) {
	theirBlock, _ := aes.NewCipher(tCKey)
	theirCipher := cipher.NewCTR(theirBlock, tIV)

	theirMac, macSize := makeMac(hashType, tMKey)

	for {
		data, ok := <-in
		if !ok {
			close(secureIn)
			return
		}

		if len(data) <= macSize {
			continue
		}

		mark := len(data) - macSize
		buff := make([]byte, mark)

		theirCipher.XORKeyStream(buff, data[0:mark])

		theirMac.Write(data[0:mark])
		expected := theirMac.Sum(nil)
		theirMac.Reset()

		hmacOk := hmac.Equal(data[mark:], expected)

		if hmacOk {
			secureIn <- buff
		} else {
			secureIn <- nil
		}
	}
}
Пример #23
0
func isVerifiedRequest(header http.Header, body []byte) bool {
	serverSignature := os.Getenv("SECRET")
	requestSignature := header.Get("X-Hub-Signature")

	// when not set up with a secret
	if len(serverSignature) < 1 {
		log.Println("http.request.signature.verification.skipped")
		return true
	}

	log.Println("http.request.signature.verification.started")

	if len(requestSignature) < 1 {
		log.Println("http.request.signature.verification.failed", "missing X-Hub-Signature header")
		return false
	}

	mac := hmac.New(sha1.New, []byte(serverSignature))
	mac.Write(body)
	expectedMAC := mac.Sum(nil)
	expectedSignature := "sha1=" + hex.EncodeToString(expectedMAC)
	signatureMatched := hmac.Equal([]byte(expectedSignature), []byte(requestSignature))

	if signatureMatched {
		log.Println("http.request.signature.verification.passed")
	} else {
		log.Println("http.request.signature.verification.failed")
	}

	return signatureMatched
}
Пример #24
0
func secretHandler(secret string, next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		if secret != "" {
			s := req.Header.Get("X-Hub-Signature")

			if s == "" {
				w.WriteHeader(http.StatusForbidden)
				fmt.Fprintf(w, "X-Hub-Signature required for HMAC verification")
				return
			}

			body, _ := ioutil.ReadAll(req.Body)

			hash := hmac.New(sha1.New, []byte(secret))
			hash.Write(body)
			expected := "sha1=" + hex.EncodeToString(hash.Sum(nil))

			if !hmac.Equal([]byte(expected), []byte(s)) {
				w.WriteHeader(http.StatusForbidden)
				fmt.Fprintf(w, "HMAC verification failed")
				return
			}
			req.Body = ioutil.NopCloser(bytes.NewBuffer(body))
		}

		next.ServeHTTP(w, req)
	})
}
Пример #25
0
func handlePodVerify(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()

	uuid, err := types.NewUUID(r.FormValue("uuid"))
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "uuid field missing or malformed: %v", err)
		return
	}

	content := r.FormValue("content")
	if content == "" {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "content field missing")
		return
	}

	sig, err := base64.StdEncoding.DecodeString(r.FormValue("signature"))
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "signature field missing or corrupt: %v", err)
		return
	}

	h := hmac.New(sha512.New, hmacKey[:])
	h.Write((*uuid)[:])
	h.Write([]byte(content))

	if hmac.Equal(sig, h.Sum(nil)) {
		w.WriteHeader(http.StatusOK)
	} else {
		w.WriteHeader(http.StatusForbidden)
	}
}
Пример #26
0
Файл: auth.go Проект: moshee/gas
// VerifyCookie checks and un-signs the cookie's contents against all of the
// configured HMAC keys.
func VerifyCookie(cookie *http.Cookie) error {
	decodedLen := base64.StdEncoding.DecodedLen(len(cookie.Value))
	if hmacKeys == nil || len(hmacKeys) == 0 || decodedLen < macLength {
		return nil
	}

	p, err := base64.StdEncoding.DecodeString(cookie.Value)
	if err != nil {
		return err
	}

	var (
		pos = len(p) - macLength
		val = p[:pos]
		sum = p[pos:]
	)

	for _, key := range hmacKeys {
		s := hmacSum(val, key, nil)
		if hmac.Equal(s, sum) {
			// So when we reset the value of the cookie to the un-signed value,
			// we're not decoding or encoding it again.
			// I guess this is how WTFs happen.
			cookie.Value = string(val)
			return nil
		}
	}

	return ErrBadMac
}
func (g *GitHubWebhookAuth) check(r *http.Request) error {

	if r.Method != "POST" {
		return ErrMethodNotAllowed
	}
	if r.ContentLength == 0 {
		return ErrMissingBody
	}

	h := r.Header.Get(HeaderName)
	if h == "" {
		return ErrMissingHeader
	}

	digest := hmac.New(sha1.New, g.SecretKey)
	_, err := io.Copy(digest, r.Body)

	if err != nil {
		return err
	}

	b := bytes.NewBufferString("sha1=" + hex.EncodeToString(digest.Sum(nil)))

	if !hmac.Equal(b.Bytes(), []byte(h)) {
		return ErrInvalidSignature
	}

	return nil
}
Пример #28
0
// Valid confirms that the timestamp is within skew and verifies the MAC.
//
// If the request is valid, nil will be returned. If auth is a bewit and the
// method is not GET or HEAD, ErrInvalidBewitMethod will be returned. If auth is
// a bewit and the timestamp is after the the specified expiry, ErrBewitExpired
// will be returned. If auth is from a request header and the timestamp is
// outside the maximum skew, ErrTimestampSkew will be returned. If the MAC is
// not the expected value, ErrInvalidMAC will be returned.
func (auth *Auth) Valid() error {
	t := AuthHeader
	if auth.IsBewit {
		t = AuthBewit
		if auth.Method != "GET" && auth.Method != "HEAD" {
			return ErrInvalidBewitMethod
		}
		if auth.ActualTimestamp.After(auth.Timestamp) {
			return ErrBewitExpired
		}
	} else {
		skew := auth.ActualTimestamp.Sub(auth.Timestamp)
		if abs(skew) > MaxTimestampSkew {
			return ErrTimestampSkew
		}
	}
	if !hmac.Equal(auth.mac(t), auth.MAC) {
		if auth.IsBewit && strings.HasPrefix(auth.RequestURI, "http") && len(auth.RequestURI) > 9 {
			// try just the path
			uri := auth.RequestURI
			auth.RequestURI = "/" + strings.SplitN(auth.RequestURI[8:], "/", 2)[1]
			if auth.Valid() == nil {
				return nil
			}
			auth.RequestURI = uri
		}
		return ErrInvalidMAC
	}
	return nil
}
Пример #29
0
func (v *Vault) DecryptEnvironments(password string) (map[string]Environment, error) {
	if v.MACDigest != "sha-256" && v.Cipher != "aes" && v.CipherMode != "ctr" {
		return nil, ErrInvalidEncryptionConfig
	}

	// derive the key
	key, err := v.KeyDetails.key(password)
	if err != nil {
		return nil, err
	}

	// validate the mac
	if !hmac.Equal(v.mac(key), v.MAC) {
		return nil, ErrInvalidPassword
	}

	// decrypt the environments
	plaintext := make([]byte, len(v.Environments))

	block, err := aes.NewCipher(key)
	decrypter := cipher.NewCTR(block, v.IV)
	decrypter.XORKeyStream(plaintext, v.Environments)

	// unmarshal the environments
	environments := map[string]Environment{}
	err = json.Unmarshal(plaintext, &environments)
	if err != nil {
		return nil, err
	}

	return environments, nil
}
Пример #30
0
// VerifyXsrfToken returns true if token is valid or false otherwise.
// action identifies the web page; now is the current time.
// If no userId is set, VerifyXsrfToken returns false.
func (s UserIdSession) VerifyXsrfToken(
	tokenToBeVerified, action string, now time.Time) bool {
	idx := strings.IndexByte(tokenToBeVerified, ':')
	if idx == -1 {
		return false
	}
	expireUnix, err := strconv.ParseInt(tokenToBeVerified[:idx], 10, 64)
	if err != nil {
		return false
	}
	if now.Unix() >= expireUnix {
		return false
	}
	userId, ok := s.UserId()
	if !ok {
		return false
	}
	secret, ok := s.xsrfSecret()
	if !ok {
		return false
	}
	expectedChecksum := tokenToBeVerified[idx+1:]
	mac := hmac.New(sha256.New, secret)
	message := fmt.Sprintf("%d_%d_%s", expireUnix, userId, action)
	mac.Write(([]byte)(message))
	checksum := strings.TrimRight(
		base32.StdEncoding.EncodeToString(mac.Sum(nil)), "=")
	return hmac.Equal(([]byte)(expectedChecksum), ([]byte)(checksum))
}