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)) }
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") } }
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 }
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 }
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 }
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) }
// 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 }
// 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 }
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) }
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 }
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 }
// 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)) }
// 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)) }
// 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)) }
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) }
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) }
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 }
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) } }
// 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 }
// 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 }
// 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 }
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 } } }
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 }
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) }) }
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) } }
// 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 }
// 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 }
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 }
// 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)) }