Ejemplo n.º 1
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
}
Ejemplo n.º 2
0
// ImportVerified imports a verified key under the label. The original
// signature data is preserved in the keystore.
func (s *KeyStore) ImportVerified(label string, signedKey []byte) bool {
	var pub []byte

	if !s.Valid(true) || s.Has(label) {
		return false
	}

	var vkey VerifiedKey
	_, err := asn1.Unmarshal(signedKey, &vkey)
	if err != nil {
		return false
	}

	var signerLabel string
	if bytes.Equal(vkey.Signer, s.PublicKey) {
		signerLabel = "self"
		pub = s.PublicKey
	} else {
		var ok bool
		signerLabel, ok = s.FindPublic(vkey.Signer)
		if !ok {
			return false
		}
		pub = s.Keys[signerLabel].Keys
	}

	if signerLabel == "" || pub == nil {
		return false
	} else if _, ok := s.VerifyKeySignature(signerLabel); !ok {
		return false
	}

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

	signatureData := vkey.SignatureData()
	if !public.Verify(pubkey, signatureData, vkey.Signature) {
		return false
	}

	rec := &PublicKeyRecord{
		Label:         label,
		Version:       KeyStoreVersion,
		Timestamp:     time.Now().Unix(),
		Keys:          vkey.Public,
		KeySignature:  vkey.Signature,
		KeySigner:     pub,
		SignatureTime: vkey.Timestamp,
	}
	s.Keys[label] = rec
	return true
}
Ejemplo n.º 3
0
func (s *KeyStore) getPublic(label string) *public.PublicKey {
	if !s.Has(label) {
		return nil
	}

	if label == "self" {
		if s.Locked() {
			pub, err := public.UnmarshalPublic(s.PublicKey)
			if err != nil {
				return nil
			}
			return pub
		}
		return s.privateKey.PublicKey
	}
	pub, err := public.UnmarshalPublic(s.Keys[label].Keys)
	if err != nil {
		return nil
	}
	return pub
}
Ejemplo n.º 4
0
// IsSelfSigned returns true if the verified key is self-signed.
func (vkey *VerifiedKey) IsSelfSigned() bool {
	if !bytes.Equal(vkey.Public, vkey.Signer) {
		return false
	}

	signer, err := public.UnmarshalPublic(vkey.Signer)
	if err != nil {
		return false
	}

	sigData := vkey.SignatureData()
	return public.Verify(signer, sigData, vkey.Signature)
}
Ejemplo n.º 5
0
// KeySession sets up a new session from the user's private key and the
// server's ephemeral public key.
func KeySession(priv, pub []byte) (*Session, bool) {
	privKey, err := public.UnmarshalPrivate(priv)
	if err != nil {
		return nil, false
	}
	defer privKey.Zero()

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

	shared := public.KeyExchange(privKey, pubKey)
	return &Session{shared: shared}, true
}
Ejemplo n.º 6
0
// EncryptTo encrypts the message to the named public key.
func (s *KeyStore) EncryptTo(label string, message []byte) ([]byte, bool) {
	if !s.Valid(true) || !s.Has(label) {
		return nil, false
	}

	var pubBytes []byte
	if label == "self" {
		pubBytes = s.PublicKey
	} else {
		pubBytes = s.Keys[label].Keys
	}

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

	return public.Encrypt(pub, message)
}
Ejemplo n.º 7
0
// AddKey adds the new peer key to the keystore, signing it with the
// owner's key. If the keystore is locked, this will fail.
func (s *KeyStore) AddKey(label string, peer []byte, metadata map[string]string) bool {
	if !s.Valid(true) {
		return false
	} else if s.Has(label) {
		return false
	} else if s.Locked() {
		return false
	} else if _, err := public.UnmarshalPublic(peer); err != nil {
		return false
	}

	signTime := time.Now().Unix()
	vkey := &VerifiedKey{
		Public:    peer,
		Signer:    s.PublicKey,
		Timestamp: signTime,
	}
	signatureData := vkey.SignatureData()

	sig, ok := public.Sign(s.privateKey, signatureData)
	if !ok {
		return false
	}
	if !public.Verify(s.privateKey.PublicKey, signatureData, sig) {
		return false
	}

	metadataCopy := map[string]string{}
	for k, v := range metadata {
		metadataCopy[k] = v
	}

	s.Keys[label] = &PublicKeyRecord{
		Label:         label,
		Timestamp:     time.Now().Unix(),
		Keys:          peer,
		KeySignature:  sig,
		KeySigner:     s.PublicKey,
		SignatureTime: signTime,
		Metadata:      metadataCopy,
	}
	return true
}
Ejemplo n.º 8
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
}
Ejemplo n.º 9
0
func testCreateOTP(t *testing.T) string {
	if sessionAuth == nil {
		t.Fatal("auth: session not established")
	}

	last, err := hex.DecodeString(sessionAuth.Last)
	if err != nil {
		t.Fatalf("%v", err)
	}

	sessionPublic, err := public.UnmarshalPublic(sessionPub)
	if err != nil {
		t.Fatalf("%v", err)
	}

	shared := public.KeyExchange(peerPrivate, sessionPublic)

	h := hmac.New(sha256.New, shared)
	h.Write(last)
	last = append(last, h.Sum(nil)...)
	return hex.EncodeToString(last)
}
Ejemplo n.º 10
0
// VerifyKeySignature authenticates the signature on the key indicated
// by label. If the label is self, Verify returns true as that label
// is assumed always valid.
func (s *KeyStore) VerifyKeySignature(label string) (string, bool) {
	if !s.Valid(true) {
		return "", false
	}

	if label == "self" {
		return "self", true
	}

	rec := s.Keys[label]
	var signerLabel string

	var vkey = &VerifiedKey{
		Public:    rec.Keys,
		Signature: rec.KeySignature,
		Timestamp: rec.SignatureTime,
	}
	if bytes.Equal(rec.KeySigner, s.PublicKey) {
		vkey.Signer = s.PublicKey
		signerLabel = "self"
	} else {
		var ok bool
		signerLabel, ok = s.FindPublic(rec.KeySigner)
		if !ok {
			return "", false
		}
		vkey.Signer = s.Keys[signerLabel].Keys
	}
	pub, err := public.UnmarshalPublic(vkey.Signer)
	if err != nil {
		return "", false
	}
	signatureData := vkey.SignatureData()

	if !public.Verify(pub, signatureData, vkey.Signature) {
		return "", false
	}
	return signerLabel, true
}