Example #1
0
// NewYubiKey takes the key and initial OTP and returns an
// authenticator.
func NewYubiKey(key []byte, initialOTP string) (*Authenticator, error) {
	pub, otp, err := yubikey.ParseOTPString(initialOTP)
	if err != nil {
		return nil, err
	}

	tmpKey := yubikey.NewKey(key)
	token, err := otp.Parse(tmpKey)
	if err != nil {
		return nil, err
	}
	util.Zero(tmpKey[:])

	config := &YubiKeyConfig{
		Counter: getTokenCounter(token),
		Key:     key,
		Public:  pub,
	}
	defer util.Zero(config.Key[:])

	auth := &Authenticator{
		Type:   TypeYubiKey,
		Last:   initialOTP,
		Secret: config.Bytes(),
	}

	return auth, nil
}
Example #2
0
// TestBuildUserToken builds the test user token from an OTP.
func TestBuildUserToken(t *testing.T) {
	key, err := hex.DecodeString(testYubiKey)
	if err != nil {
		t.Fatalf("%v", err)
	}
	tmpKey := yubikey.NewKey(key)

	_, otp, err := yubikey.ParseOTPString(testInitialYKOTP)
	if err != nil {
		t.Fatalf("%v", err)
	}

	yubiToken, err = otp.Parse(tmpKey)
	if err != nil {
		t.Fatalf("%v", err)
	}
}
Example #3
0
// ValidateYubiKey takes an Authenticator that is presumed to be a
// YubiKey authenticator and attempts to validate the given OTP
// using it. The YubiKey authenticator will always need to be updated
// when successful to account for changes in the counter, and to
// update the last OTP.
func ValidateYubiKey(auth *Authenticator, otp string) (bool, error) {
	if (auth == nil) || (auth.Type != TypeYubiKey) {
		return false, ErrInvalidAuthenticator
	}

	if auth.Last == otp {
		return false, ErrValidationFail
	}

	config, err := ParseYubiKeyConfig(auth.Secret)
	if err != nil {
		return false, ErrInvalidAuthenticator
	}

	tmpKey := yubikey.NewKey(config.Key)
	defer util.Zero(tmpKey[:])

	pub, ykOTP, err := yubikey.ParseOTPString(otp)
	if err != nil {
		return false, ErrValidationFail
	}

	if !bytes.Equal(pub, config.Public) {
		return false, ErrValidationFail
	}

	userToken, err := ykOTP.Parse(tmpKey)
	if err != nil {
		return false, ErrValidationFail
	}

	if getTokenCounter(userToken) < config.Counter {
		return false, ErrValidationFail
	}

	config.Counter = getTokenCounter(userToken)
	auth.Last = otp
	auth.Secret = config.Bytes()

	return true, nil
}