Example #1
0
// TestSessionSetup validates creating a new session and successful
// validation of an OTP.
func TestSessionSetup(t *testing.T) {
	var err error

	peerPrivate, err = public.GenerateKey()
	if err != nil {
		t.Fatalf("%v", err)
	}

	peer, err = public.MarshalPublic(peerPrivate.PublicKey)
	if err != nil {
		t.Fatalf("%v", err)
	}

	sessionAuth, sessionPub, err = NewSession(peer)
	if err != nil {
		t.Fatalf("%v", err)
	}

	newOTP := testCreateOTP(t)

	shouldUpdate, err := ValidateSession(sessionAuth, newOTP)
	if err != nil {
		t.Fatalf("%v", err)
	}

	if !shouldUpdate {
		t.Fatal("auth: ValidateSession should signal that an update is required")
	}
}
Example #2
0
// NewSession sets up a new session. The Last field should be sent
// to the client. The returned public key should be sent to the
// user for generating a shared MAC key. The authenticator should ensure
// some mechanism for expiring sessions exists.
func NewSession(pub []byte) (*Authenticator, []byte, error) {
	next := util.RandBytes(sessionLength)
	if next == nil {
		return nil, nil, errors.New("auth: PRNG failure")
	}

	ephemeral, err := public.GenerateKey()
	if err != nil || !ephemeral.Valid() {
		return nil, nil, errors.New("auth: failed to set up session key")
	}

	// Validated that the key was correct previously.
	ephemeralPublic, _ := public.MarshalPublic(ephemeral.PublicKey)

	peer, err := public.UnmarshalPublic(pub)
	if err != nil {
		return nil, nil, err
	}

	shared := public.KeyExchange(ephemeral, peer)

	return &Authenticator{
		Type:   TypeSession,
		Last:   hex.EncodeToString(next),
		Secret: shared,
	}, ephemeralPublic, nil
}
Example #3
0
// Unlock decrypts the private key stored in the keystore.
func (s *KeyStore) Unlock(passphrase []byte) bool {
	if !s.Valid(true) {
		return false
	} else if !s.Locked() {
		return true
	}

	priv, ok := public.UnlockKey(s.PrivateKey, passphrase)
	if !ok {
		return false
	}
	pub, err := public.MarshalPublic(priv.PublicKey)
	if err != nil {
		priv.Zero()
		return false
	}

	s.privateKey = priv
	s.PublicKey = pub
	s.locked = false

	if s.ExportKey == nil {
		fmt.Println("Building export key.")
		vkey := &VerifiedKey{
			Public:    s.PublicKey,
			Signer:    s.PublicKey,
			Timestamp: time.Now().Unix(),
		}
		signatureData := vkey.SignatureData()
		sig, ok := public.Sign(s.privateKey, signatureData)
		if !ok {
			s.Lock()
			return false
		}
		vkey.Signature = sig
		verified, err := vkey.Serialise()
		if err != nil {
			s.Lock()
			return false
		}
		s.ExportKey = verified
	}

	return !s.Locked()
}
Example #4
0
// Valid performs sanity checks on the keystore to make sure it is
// valid. If quick is false, the public key and private key (if
// unlocked) will be checked as well.
func (s *KeyStore) Valid(quick bool) bool {
	if s == nil {
		return false
	}

	if s.Version != KeyStoreVersion {
		return false
	}

	if s.Timestamp == 0 {
		return false
	}

	if s.Keys == nil {
		return false
	}

	if quick {
		return true
	}

	if !s.locked {
		if !s.privateKey.Valid() {
			return false
		}
		pub, err := public.MarshalPublic(s.privateKey.PublicKey)
		if err != nil {
			return false
		}
		if !bytes.Equal(pub, s.PublicKey) {
			return false
		}
	}

	if s.PublicKey == nil {
		return false
	} else if _, err := public.UnmarshalPublic(s.PublicKey); err != nil {
		return false
	}

	return true
}
Example #5
0
// NewPrivateKeyStore builds a keystore from a private key.
func NewPrivateKeyStore(priv *public.PrivateKey) (*KeyStore, bool) {
	if !priv.Valid() {
		return nil, false
	}

	pub, err := public.MarshalPublic(priv.PublicKey)
	if err != nil {
		return nil, false
	}

	vkey := &VerifiedKey{
		Public:    pub,
		Signer:    pub,
		Timestamp: time.Now().Unix(),
	}
	signatureData := vkey.SignatureData()
	sig, ok := public.Sign(priv, signatureData)
	if !ok {
		return nil, false
	}
	vkey.Signature = sig
	verified, err := vkey.Serialise()
	if err != nil {
		return nil, false
	}

	return &KeyStore{
		Version:    KeyStoreVersion,
		Timestamp:  time.Now().Unix(),
		Keys:       map[string]*PublicKeyRecord{},
		privateKey: priv,
		locked:     false,
		PublicKey:  pub,
		ExportKey:  verified,
	}, true

}