User Tools

Site Tools


security_resource_manager

Security Resource Manager

Security Resource Manager (SRM) provides management of Secure Virtual Resources (SVRs) and access control based on policies defined by SVRs. SVRs are defined in a database with standard format and provided to SRM for security handling. SRM is in charge of loading, verifying and parsing the SVRs database and maintain it in memory to serve requests for access decision or credential information.

Features

SRM consists of two major roles:

  • Request Filtering
  • Secure Virtual Resource (SVR) Management

Request Filtering

When performing this role, SRM receives a request from Connectivity Abstraction layer and either:

  • Grants the request
  • Denies the request
  • Responds to the request for SVRs

Secure Virtual Resource Management

SVRs includes security-related resources such as Access Control Lists (ACLs), Device Owner State, Credentials and Security Services. When performing this role, the SRM manages a database of SVRs in memory or persistent storage.

For the database of SVRs there are four categories of formatting:

  • In Memory - database in memory as the “active working set” with proprietary data structures format defined by SRM.
  • Marshalled: - database marshalled into a specific standard format. Current implementation has chosen CBOR as data format for SVRs.
  • In Persistent Storage - database in persistent storage which is signed and encrypted with OS or Platform-provided wrapping key. Note that database will have already been marshalled prior to being place in storage.
  • In Flight (sending off-device) - database in flight which is signed and encrypted with protocol-specific wrapping key (e.g. DTLS). Note that database will have already been marshalled prior to be sent off-device.

Architecture

The SRM has the following sub-modules to encapsulate functional blocks:

  • Resource Manager (RM)
  • Policy Engine (PE)
  • Persistent Storage Interface (PSI)

Block Diagram of SRM Module

Resource Manager (RM)

The Resource Manager is responsible for:

  • Loading the Secure Virtual Resources to and from persistent storage using the PSI
  • Supplying the Policy Engine (PE) with resources upon request
  • Responding to requests for SVRs

The RM is responsible for maintaining the privacy and integrity of the SVRs. This is achieved by encryption and integrity protection of the SVRs before storing them to the platform persistent storage. The RM initially used JSON format to marshal SVR data structures. Now as the CBOR implementation is completed within IoTivity Core, the SRM is migrated to CBOR as a more efficient marshalling format.

Policy Engine (PE)

The Policy Engine takes a request and responds with either “ACCESS_GRANTED” or “ACCESS_DENIED”. It also may include a reason code with the response. Upon a request, the PE will do the following in sequence:

  • Consult the appropriate ACL provided by RM
  • Find the best Access Control Entry (ACE) that applies to the request
  • Compare the ACE rights to the request rights to make a decision

Persistent Storage Interface (PSI)

Because persistent storage is platform (OS and hardware) specific, the Application is required to provide these functions to the PSI. The PSI then exposes them to the RM. The PSI supplies the RM with at least five file APIs:

  • fopen() – opens or creates a file
  • fread() – reads the contents of a file
  • fwrite() – writes to a file
  • fclose() – closes a file
  • unlink() – deletes an existing file

These APIs are chosen to permit maximum flexibility to the Provisioning Manager (PM) on managing its own memory and storage utilization.

SVRs Database Format Conversion

A default SVRs database needs to be pre-loaded on the device to operate manufacturer-specified “default” (a.k.a. “factory reset” or “out of box” behaviour). As the device is on-boarded and provisioned (refer to the Provisioning Security &Tool section), the SVRs database is updated accordingly. SVRs database can be defined in JSON format as it is human-readable/editable. But SRM operates using CBOR formatted database (DAT files). So a JSON-to-CBOR conversion tool is provided here (to create the target DAT file):

  • <iotivity-base>/out/<…>/release/resource/csdk/security/tool/json2cbor

Run the command like:

  • ./json2cbor <jsonFileName> <datFileName>

Sample SVR database files for Server and Client

Sequence Diagrams

1. General Request Flow with Local ACL

In this figure, a Client issues a get, put, delete, post or observe request to a Server. Server refers to the ACL database, finds an Access Control Entry (ACE) for the request, and grants/denies the request.

2. Request flow for usecase using Access Management Service (AMS)

AMS is used to provide centralized access control decisions to the server devices.

In this figure, a server device cannot find a local /acl which corresponds to a resource request, but it does find an /amacl resource, and it will then use the AMS to resolve the access rights for the resource request.

C APIs

API for Register Persistent storage callback.

OCStackResult 	OCRegisterPersistentStorageHandler (OCPersistentStorage *persistentStorageHandler)
 

NOTE: OCRegisterPersistentStorageHandler must be called before OCInit

Usage example:

static char CRED_FILE[] = "oic_svr_db_server.dat";	
FILE* server_fopen(const char *path, const char *mode)
{
    (void)path;
    return fopen(CRED_FILE, mode);
}   
int main(int argc, char* argv[])
{
    ...    
    OCPersistentStorage ps = { server_fopen, fread, fwrite, fclose, unlink };
    OCRegisterPersistentStorageHandler(&ps);
    if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
    {
        OIC_LOG(ERROR, TAG, "OCStack init error");
        return 0;
    }
	...
}	

C++ API

API for setting configuration of the OCPlatform object, including registering persistent storage callback.

void 	OC::OCPlatform::Configure (const PlatformConfig &config)

Usage example:

static FILE* client_open(const char* /*path*/, const char *mode)
{
    return fopen(SVR_DB_FILE_NAME, mode);
}
OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
 
int main(int argc, char* argv[])
{
    ...    
    PlatformConfig cfg {
        OC::ServiceType::InProc,
        OC::ModeType::Server,
        "0.0.0.0",
        0,
        OC::QualityOfService::LowQos,
        &ps
    };
    OCPlatform::Configure(cfg);
	...
}	

Android API

Classes and methods for setting configuration of the OCPlatform object, including registering persistent storage callback.

Class: PlatformConfig
Constructor: PlatformConfig(Context context, ServiceType serviceType, ModeType modeType, java.lang.String ipAddress, int port, QualityOfService qualityOfService, java.lang.String dbPath) 
 
Class OcPlatform
Method: static void	Configure(PlatformConfig platformConfig)
Description: API for setting the configuration of the OcPlatform.

Usage example:

import org.iotivity.base.PlatformConfig;
import org.iotivity.base.OcPlatform;
 
private String OIC_CLIENT_CBOR_DB_FILE =  "oic_svr_db_client.dat";
private void initOICStack() {
    PlatformConfig cfg = new PlatformConfig(
                this,
                ServiceType.IN_PROC,
                ModeType.CLIENT_SERVER,
                "0.0.0.0",
                0,
                QualityOfService.LOW, OIC_CLIENT_CBOR_DB_FILE);
    OcPlatform.Configure(cfg);
}

Guidelines on building applications with Security enabled

1)Iotivity stack should be compiled with SECURED=1 flag:

  • scons resource SECURED=1

2) Register persistent storage handler with default SVR database (CBOR-formatted dat file) with the APIs described above. An Iotivity application needs to perform this at startup.

3) An Iotivity Server hosting a resource should assign 'OC_SECURE' property during resource creation.

C API

OCCreateResource(.......,  OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE );

C++ API

OCPlatform::registerResource(.......,  OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE );

JAVA API

OcPlatform.registerResource(......, EnumSet.of(ResourceProperty.DISCOVERABLE, ResourceProperty.OBSERVABLE, ResourceProperty.SECURE));

4) NOTE: Due to an existing bug in iotivity, a Client application should register itself as OC_CLIENT_SERVER mode with iotivity stack:

OCInit(NULL, 0, OC_CLIENT_SERVER);

Sample Application

This section introduces how to run secure sample applications to demonstrate about discovery of resources on the server and the handling of requests to secure resources. The samples below are for Linux build only.

Source code location of the sample code

 iotivity/resource/csdk/stack/samples/linux/secure 

Binary location after source code build

 iotivity/out/linux/x86_64/release/resource/csdk/stack/samples/linux/secure 

Executing samples

  • 1) Setting LD_LIBRARY_PATH
 $ export LD_LIBRARY_PATH=<iotivity-base>/out/<...>/release 
  • 2) Running server app
$ ./ocserverbasicops &
59:43.385 DEBUG: ocserverbasicops: OCServer is starting...
59:45.389 INFO: ocserverbasicops: Created LED resource with result: OC_STACK_OK
59:45.389 INFO: ocserverbasicops: Entering ocserver main loop...
  • 3) Running client app

Testcase1: secure resource discovery

Message “INFO: occlientbasicops: Secure – YES” indicates success!

$ ./occlientbasicops -t 1
......
01:23.985 INFO: occlientbasicops: Uri -- /a/led
01:23.985 INFO: occlientbasicops: Secure -- YES
......

Testcase2: GET/PUT Request to secure resource

Completion of 'GET' and 'PUT' query successfully indicates success!

$ ./occlientbasicops -t 2
......
02:21.133 INFO: occlientbasicops: Callback Context for GET query recvd successfully
02:21.133 INFO: occlientbasicops: StackResult: OC_STACK_OK
02:21.133 INFO: occlientbasicops: SEQUENCE NUMBER: 2
02:21.133 INFO: PayloadLog: Payload Type: Representation
02:21.133 INFO: PayloadLog:     Resource #1
02:21.133 INFO: PayloadLog:     URI:(null)
02:21.133 INFO: PayloadLog:     Resource Types:
02:21.133 INFO: PayloadLog:     Interfaces:
02:21.133 INFO: PayloadLog:     Values:
02:21.133 INFO: PayloadLog:             state(bool):false
02:21.133 INFO: PayloadLog:             power(int):0
02:21.133 INFO: occlientbasicops: =============> Get Response
02:21.233 INFO: occlientbasicops: Callback Context for PUT recvd successfully
02:21.233 INFO: occlientbasicops: StackResult: OC_STACK_OK
02:21.233 INFO: PayloadLog: Payload Type: Representation
02:21.233 INFO: PayloadLog:     Resource #1
02:21.233 INFO: PayloadLog:     URI:(null)
02:21.233 INFO: PayloadLog:     Resource Types:
02:21.233 INFO: PayloadLog:     Interfaces:
02:21.233 INFO: PayloadLog:     Values:
02:21.233 INFO: PayloadLog:             state(bool):true
02:21.233 INFO: PayloadLog:             power(int):15
02:21.233 INFO: occlientbasicops: =============> Put Response
.....

Testcase 3: Testing GET/PUT request from devowner and non-devowner clients

(NOTE: Introduced with patch https://gerrit.iotivity.org/gerrit/#/c/7903/)

There is an option to test the following scenarios:

  1. Requests from DevOwner are allowed without checking ACL. *
  2. Requests from NonDevOwner are checked against ACL against subjectuuid, permission and period-recurrence. *

Client command for testing GET/PUT requests from devowner clients:

$ ./occlientbasicops -t 2 -d 1

Client command for testing GET/PUT requests from non-devowner clients:

$ ./occlientbasicops -t 2 -d 0

NOTE : To test for denied requests, you can update server SVR <oic_svr_db_server.json> (and then convert to dat with json2cbor tool) to test against invalid subjectuuid, permission and period-recurrence:

                    "subjectuuid": "31393139-3139-3139-3139-313931393139",
                    "resources": [
                        {
                            "href": "/a/led",
                            "rel": "",
                            "rt": "",
                            "if": ""
                        }
                    ],
                    "permission": 6,
                    "period" : ["20150630T060000/20150630T220000", "20150630T060000/20150630T200000"],
                    "recurrence" : ["FREQ=DAILY; BYDAY=MO, WE, FR", "FREQ=DAILY; BYDAY=TU, TH; UNTIL=20160630"]
                },

For example, if permission is updated as:

                    "permission": 1,

Then the GET/PUT requests will be denied with the following message:

$ ./occlientbasicops -t 2 -d 0
51:46.978 INFO: occlientbasicops: Callback Context for GET query recvd successfully
51:46.978 INFO: occlientbasicops: StackResult: OC_STACK_UNAUTHORIZED_REQ
51:46.978 INFO: occlientbasicops: SEQUENCE NUMBER: 2
51:46.978 INFO: PayloadLog: NULL Payload
51:46.978 INFO: occlientbasicops: =============> Get Response
51:47.078 INFO: occlientbasicops: Callback Context for PUT recvd successfully
51:47.078 INFO: occlientbasicops: StackResult: OC_STACK_UNAUTHORIZED_REQ
51:47.078 INFO: PayloadLog: NULL Payload
51:47.078 INFO: occlientbasicops: =============> Put Response

IoTivity security data protection

IoTivity security data storage

  • Device certificate and private key
    • Injection into HW element, e.g., TZ, eSE
    • Manufacturing time
  • SVR DB except device cert/key
    • Load and store from/into svr db(.dat) file
    • Possible to be changed on run-time

IoTivity security data

Iotivity protection required security resource (SVR DB)

Persistent Storage Interface (PSI)

  • Because persistent storage is platform (OS and hardware) specific, the Application is required to provide these functions to the PSI. The PSI then exposes them to the Resource Manager(RM).
  • OCRegisterPersistentStorageHandler must be used to supplies at least five file APIs:
    • fopen(), fread(), fwrite(), fclose(), unlink()
  • These APIs are chosen to permit maximum flexibility to the Provisioning Manager (PM) on managing its own memory and storage utilization.

security_resource_manager.txt · Last modified: 2017/03/20 22:42 by Phil Coval