You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2017/08/23 18:51:28 UTC

[mynewt-newtmgr] 01/03: nmxact - BLE security

This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git

commit 1d74b2de30db5c3493deecad790e1933b04c57b5
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Fri Aug 18 19:15:34 2017 -0700

    nmxact - BLE security
---
 nmxact/bledefs/bledefs.go | 17 +++++++++++++++++
 nmxact/nmble/ble_proto.go |  5 +++++
 nmxact/nmble/ble_sesn.go  | 41 +++++++++++++++++++++++++++++++++++++++++
 nmxact/nmble/ble_util.go  | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 nmxact/nmble/conn.go      |  6 +++---
 nmxact/nmble/profile.go   |  6 +++---
 6 files changed, 115 insertions(+), 6 deletions(-)

diff --git a/nmxact/bledefs/bledefs.go b/nmxact/bledefs/bledefs.go
index 5538681..16f4c6f 100644
--- a/nmxact/bledefs/bledefs.go
+++ b/nmxact/bledefs/bledefs.go
@@ -643,6 +643,10 @@ type BleConnDesc struct {
 	PeerOtaAddrType BleAddrType
 	PeerOtaAddr     BleAddr
 	Role            BleRole
+	Encrypted       bool
+	Authenticated   bool
+	Bonded          bool
+	KeySize         int
 }
 
 func (d *BleConnDesc) String() string {
@@ -785,6 +789,19 @@ const (
 	BLE_ATT_F_WRITE_AUTHOR             = 0x80
 )
 
+type BleDiscChrProperties int
+
+const (
+	BLE_DISC_CHR_PROP_BROADCAST       BleDiscChrProperties = 0x01
+	BLE_DISC_CHR_PROP_READ                                 = 0x02
+	BLE_DISC_CHR_PROP_WRITE_NO_RSP                         = 0x04
+	BLE_DISC_CHR_PROP_WRITE                                = 0x08
+	BLE_DISC_CHR_PROP_NOTIFY                               = 0x10
+	BLE_DISC_CHR_PROP_INDICATE                             = 0x20
+	BLE_DISC_CHR_PROP_AUTH_SIGN_WRITE                      = 0x40
+	BLE_DISC_CHR_PROP_EXTENDED                             = 0x80
+)
+
 type BleGattAccess struct {
 	Op         BleGattOp
 	ConnHandle uint16
diff --git a/nmxact/nmble/ble_proto.go b/nmxact/nmble/ble_proto.go
index 61c086a..e1aec01 100644
--- a/nmxact/nmble/ble_proto.go
+++ b/nmxact/nmble/ble_proto.go
@@ -956,6 +956,11 @@ type BleConnFindRsp struct {
 	PeerIdAddr      BleAddr     `json:"peer_id_addr"`
 	PeerOtaAddrType BleAddrType `json:"peer_ota_addr_type"`
 	PeerOtaAddr     BleAddr     `json:"peer_ota_addr"`
+	Role            BleRole     `json:"role"`
+	Encrypted       bool        `json:"encrypted"`
+	Authenticated   bool        `json:"authenticated"`
+	Bonded          bool        `json:"bonded"`
+	KeySize         int         `json:"key_size"`
 }
 
 type BleResetReq struct {
diff --git a/nmxact/nmble/ble_sesn.go b/nmxact/nmble/ble_sesn.go
index 763997d..ad990e4 100644
--- a/nmxact/nmble/ble_sesn.go
+++ b/nmxact/nmble/ble_sesn.go
@@ -320,6 +320,38 @@ func (s *BleSesn) ConnInfo() (BleConnDesc, error) {
 	return s.conn.ConnInfo(), nil
 }
 
+func (s *BleSesn) checkSecurity(encReqd bool, authReqd bool) (bool, bool) {
+	desc, _ := s.ConnInfo()
+
+	return !encReqd || desc.Encrypted,
+		!authReqd || desc.Authenticated
+}
+
+func (s *BleSesn) ensureSecurity(encReqd bool, authReqd bool) error {
+	encGood, authGood := s.checkSecurity(encReqd, authReqd)
+	if encGood && authGood {
+		return nil
+	}
+
+	if err := s.conn.InitiateSecurity(); err != nil {
+		return err
+	}
+
+	// Ensure pairing meets characteristic's requirements.
+	encGood, authGood = s.checkSecurity(encReqd, authReqd)
+	if !encGood {
+		return fmt.Errorf("Insufficient BLE security; " +
+			"characteristic requires encryption")
+	}
+
+	if !authGood {
+		return fmt.Errorf("Insufficient BLE security; " +
+			"characteristic  requires authentication")
+	}
+
+	return nil
+}
+
 func (s *BleSesn) TxNmpOnce(req *nmp.NmpMsg, opt sesn.TxOptions) (
 	nmp.NmpRsp, error) {
 
@@ -352,6 +384,15 @@ func (s *BleSesn) TxCoapOnce(m coap.Message,
 	if err != nil {
 		return 0, nil, err
 	}
+
+	encReqd, authReqd, err := ResTypeSecReqs(resType)
+	if err != nil {
+		return 0, nil, err
+	}
+	if err := s.ensureSecurity(encReqd, authReqd); err != nil {
+		return 0, nil, err
+	}
+
 	txRaw := func(b []byte) error {
 		return s.conn.WriteChrNoRsp(chr, b, "coap")
 	}
diff --git a/nmxact/nmble/ble_util.go b/nmxact/nmble/ble_util.go
index 6c814de..d41f867 100644
--- a/nmxact/nmble/ble_util.go
+++ b/nmxact/nmble/ble_util.go
@@ -89,6 +89,11 @@ func BleDescFromConnFindRsp(r *BleConnFindRsp) BleConnDesc {
 		PeerIdAddr:      r.PeerIdAddr,
 		PeerOtaAddrType: r.PeerOtaAddrType,
 		PeerOtaAddr:     r.PeerOtaAddr,
+		Role:            r.Role,
+		Encrypted:       r.Encrypted,
+		Authenticated:   r.Authenticated,
+		Bonded:          r.Bonded,
+		KeySize:         r.KeySize,
 	}
 }
 
@@ -843,3 +848,44 @@ func StopWaitingForMaster(bx *BleXport, prio MasterPrio, token interface{},
 		return fmt.Errorf("Invalid session priority: %+v", prio)
 	}
 }
+
+func IsSecErr(err error) bool {
+	bhdErr := nmxutil.ToBleHost(err)
+	if bhdErr == nil {
+		return false
+	}
+
+	switch bhdErr.Status - ERR_CODE_ATT_BASE {
+	case ERR_CODE_ATT_INSUFFICIENT_AUTHEN,
+		ERR_CODE_ATT_INSUFFICIENT_AUTHOR,
+		ERR_CODE_ATT_INSUFFICIENT_KEY_SZ,
+		ERR_CODE_ATT_INSUFFICIENT_ENC:
+
+		return true
+
+	default:
+		return false
+	}
+}
+
+// Indicates the minimum security requirements for accessing the specified
+// resource type.
+//
+// @return bool                 Whether encryption is required.
+// @return bool                 Whether authentiation is required.
+// @return error                Error.
+func ResTypeSecReqs(resType sesn.ResourceType) (bool, bool, error) {
+	switch resType {
+	case sesn.RES_TYPE_PUBLIC:
+		return false, false, nil
+
+	case sesn.RES_TYPE_UNAUTH:
+		return true, false, nil
+
+	case sesn.RES_TYPE_SECURE:
+		return true, true, nil
+
+	default:
+		return false, false, fmt.Errorf("invalid resource type: %+v", resType)
+	}
+}
diff --git a/nmxact/nmble/conn.go b/nmxact/nmble/conn.go
index c8a98bf..e82b35e 100644
--- a/nmxact/nmble/conn.go
+++ b/nmxact/nmble/conn.go
@@ -476,7 +476,7 @@ func (c *Conn) discAllChrsOnce(svc Service) ([]*Characteristic, error) {
 			Uuid:       rc.Uuid,
 			DefHandle:  uint16(rc.DefHandle),
 			ValHandle:  uint16(rc.ValHandle),
-			Properties: BleChrFlags(rc.Properties),
+			Properties: BleDiscChrProperties(rc.Properties),
 		}
 	}
 
@@ -651,9 +651,9 @@ func (c *Conn) Subscribe(chr *Characteristic) error {
 
 	var payload []byte
 	switch chr.SubscribeType() {
-	case BLE_GATT_F_NOTIFY:
+	case BLE_DISC_CHR_PROP_NOTIFY:
 		payload = []byte{1, 0}
-	case BLE_GATT_F_INDICATE:
+	case BLE_DISC_CHR_PROP_INDICATE:
 		payload = []byte{2, 0}
 	default:
 		return fmt.Errorf("Cannot subscribe to characteristic %s; "+
diff --git a/nmxact/nmble/profile.go b/nmxact/nmble/profile.go
index 9db78e9..202314f 100644
--- a/nmxact/nmble/profile.go
+++ b/nmxact/nmble/profile.go
@@ -14,7 +14,7 @@ type Characteristic struct {
 	Uuid       BleUuid
 	DefHandle  uint16
 	ValHandle  uint16
-	Properties BleChrFlags
+	Properties BleDiscChrProperties
 	Dscs       []*Descriptor
 }
 
@@ -35,11 +35,11 @@ func (c *Characteristic) String() string {
 	return c.Uuid.String()
 }
 
-func (c *Characteristic) SubscribeType() BleChrFlags {
+func (c *Characteristic) SubscribeType() BleDiscChrProperties {
 	if c.Properties&BLE_GATT_F_NOTIFY != 0 {
 		return BLE_GATT_F_NOTIFY
 	} else {
-		return c.Properties & BLE_GATT_F_INDICATE
+		return c.Properties & BLE_DISC_CHR_PROP_INDICATE
 	}
 }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <co...@mynewt.apache.org>.