seba-365 - implemented dep

Change-Id: Ia6226d50e7615935a0c8876809a687427ff88c22
diff --git a/vendor/github.com/xdg/scram/client.go b/vendor/github.com/xdg/scram/client.go
new file mode 100644
index 0000000..ca0c4c7
--- /dev/null
+++ b/vendor/github.com/xdg/scram/client.go
@@ -0,0 +1,130 @@
+// Copyright 2018 by David A. Golden. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package scram
+
+import (
+	"sync"
+
+	"golang.org/x/crypto/pbkdf2"
+)
+
+// Client implements the client side of SCRAM authentication.  It holds
+// configuration values needed to initialize new client-side conversations for
+// a specific username, password and authorization ID tuple.  Client caches
+// the computationally-expensive parts of a SCRAM conversation as described in
+// RFC-5802.  If repeated authentication conversations may be required for a
+// user (e.g. disconnect/reconnect), the user's Client should be preserved.
+//
+// For security reasons, Clients have a default minimum PBKDF2 iteration count
+// of 4096.  If a server requests a smaller iteration count, an authentication
+// conversation will error.
+//
+// A Client can also be used by a server application to construct the hashed
+// authentication values to be stored for a new user.  See StoredCredentials()
+// for more.
+type Client struct {
+	sync.RWMutex
+	username string
+	password string
+	authzID  string
+	minIters int
+	nonceGen NonceGeneratorFcn
+	hashGen  HashGeneratorFcn
+	cache    map[KeyFactors]derivedKeys
+}
+
+func newClient(username, password, authzID string, fcn HashGeneratorFcn) *Client {
+	return &Client{
+		username: username,
+		password: password,
+		authzID:  authzID,
+		minIters: 4096,
+		nonceGen: defaultNonceGenerator,
+		hashGen:  fcn,
+		cache:    make(map[KeyFactors]derivedKeys),
+	}
+}
+
+// WithMinIterations changes minimum required PBKDF2 iteration count.
+func (c *Client) WithMinIterations(n int) *Client {
+	c.Lock()
+	defer c.Unlock()
+	c.minIters = n
+	return c
+}
+
+// WithNonceGenerator replaces the default nonce generator (base64 encoding of
+// 24 bytes from crypto/rand) with a custom generator.  This is provided for
+// testing or for users with custom nonce requirements.
+func (c *Client) WithNonceGenerator(ng NonceGeneratorFcn) *Client {
+	c.Lock()
+	defer c.Unlock()
+	c.nonceGen = ng
+	return c
+}
+
+// NewConversation constructs a client-side authentication conversation.
+// Conversations cannot be reused, so this must be called for each new
+// authentication attempt.
+func (c *Client) NewConversation() *ClientConversation {
+	c.RLock()
+	defer c.RUnlock()
+	return &ClientConversation{
+		client:   c,
+		nonceGen: c.nonceGen,
+		hashGen:  c.hashGen,
+		minIters: c.minIters,
+	}
+}
+
+func (c *Client) getDerivedKeys(kf KeyFactors) derivedKeys {
+	dk, ok := c.getCache(kf)
+	if !ok {
+		dk = c.computeKeys(kf)
+		c.setCache(kf, dk)
+	}
+	return dk
+}
+
+// GetStoredCredentials takes a salt and iteration count structure and
+// provides the values that must be stored by a server to authentication a
+// user.  These values are what the Server credential lookup function must
+// return for a given username.
+func (c *Client) GetStoredCredentials(kf KeyFactors) StoredCredentials {
+	dk := c.getDerivedKeys(kf)
+	return StoredCredentials{
+		KeyFactors: kf,
+		StoredKey:  dk.StoredKey,
+		ServerKey:  dk.ServerKey,
+	}
+}
+
+func (c *Client) computeKeys(kf KeyFactors) derivedKeys {
+	h := c.hashGen()
+	saltedPassword := pbkdf2.Key([]byte(c.password), []byte(kf.Salt), kf.Iters, h.Size(), c.hashGen)
+	clientKey := computeHMAC(c.hashGen, saltedPassword, []byte("Client Key"))
+
+	return derivedKeys{
+		ClientKey: clientKey,
+		StoredKey: computeHash(c.hashGen, clientKey),
+		ServerKey: computeHMAC(c.hashGen, saltedPassword, []byte("Server Key")),
+	}
+}
+
+func (c *Client) getCache(kf KeyFactors) (derivedKeys, bool) {
+	c.RLock()
+	defer c.RUnlock()
+	dk, ok := c.cache[kf]
+	return dk, ok
+}
+
+func (c *Client) setCache(kf KeyFactors, dk derivedKeys) {
+	c.Lock()
+	defer c.Unlock()
+	c.cache[kf] = dk
+	return
+}