Sample application maintenance for OCFSecure
[iotivity.git] / examples / OCFSecure / README.md
1 # Introduction
2 This is a sample secure application using the "justworks" security model
3 There are 2 applications; server and client, which need to be running from 2
4 different terminals regardless whether those 2 terminals are running within
5 the same machine or not as long as they can discover each other.
6 These 2 applications are verified on
7 * Regular Ubuntu machine
8 * Ubuntu running on Intel Joule
9 * Raspbian running on Raspberry Pi 3 and Raspberry Pi Zero W
10
11 These applications can be used to verify the build environment is setup
12 properly. They can serve as a baseline and a reference for new developers to
13 learn how to write simple server and client applications and implement OCF
14 security and pass the OCF Conformance Test Tool (CTT).
15
16 The client application does not know how to onboard, so the server is
17 provisioned already onboarded and owned by the client (Ready for Normal
18 Operation or RFNOP state). If the server application is to be used with a
19 different client, it will need to be reset first.
20
21 # Building the applications
22
23 To build the applications, type the following scons command from the root
24 directory of IoTivity
25
26 ```
27 $ scons examples/OCFSecure TARGET_TRANSPORT=IP
28 ```
29
30 To speed up the build procerss and utilize more than a single core, you can
31 add the -j option followed by the number of cores to utilize for building
32 the applications
33
34 To build the applications in the debug mode, you can add the following option
35 to the scons command RELEASE=0
36
37 # Running the applications
38
39 To run the applications on a regular machine with Ubuntu, change the directory
40 to `out/linux/x86_64/release/examples/OCFSecure` with the following command
41 ```
42 $ cd out/linux/x86_64/release/examples/OCFSecure/
43 ```
44 Next, run the server application with the following command
45 ```
46 $ ./server
47 ```
48 open up another terminal window within the same directory
49 (shortcut:Ctrl+Shift+n) and run the client application with the following
50 command.
51 ```
52 $ ./client
53 ```
54 Since there is no physical led attached to a regular machine with Ubuntu, the
55 led resource will be simulated. Otherwise, if you are running these
56 applications on a Raspberry Pi or Intel Joule board then you would need to
57 run the server application with the sudo command so the server application
58 can have access to the hardware of the board.
59
60 If successful, you should be able to see the list of discovered resources
61 in the client terminal as shown below.
62 ```
63 Discovered Resources:
64     #0: /oic/res    @224.0.1.187:5683    resource type: nil
65     #1: /oic/sec/doxm    @fe80::3749:e171:d50f:966d%enp0s3:42825    resource type
66     #2: /oic/sec/pstat    @fe80::3749:e171:d50f:966d%enp0s3:0    resource type
67     #3: /oic/sec/acl2    @10.0.2.15:47132    resource type: oic.r.acl2
68     #4: /oic/sec/cred    @10.0.2.15:47132    resource type: oic.r.cred
69     #5: /oic/sec/crl    @10.0.2.15:47132    resource type: oic.r.crl
70     #6: /oic/sec/csr    @10.0.2.15:47132    resource type: oic.r.csr
71     #7: /oic/sec/roles    @10.0.2.15:47132    resource type: oic.r.roles
72     #8: /oic/d    @10.0.2.15:47132    resource type: oic.wk.d
73     #9: /oic/p    @10.0.2.15:0    resource type: oic.wk.p
74     #10: /introspection    @10.0.2.15:0    resource type: oic.wk.introspection
75
76 Request Methods:    1: GET    4: POST
77 Usage:\<resource number> \<request method> :
78 ```
79 Usually, you might need to press enter a couple of times to refresh the stdout
80 to finally see the complete list like so.
81 ```
82 Discovered Resources:
83     #0: /oic/res    @224.0.1.187:5683    resource type: nil
84     #1: /oic/sec/doxm    @fe80::3749:e171:d50f:966d%enp0s3:42825    resource type
85     #2: /oic/sec/pstat    @fe80::3749:e171:d50f:966d%enp0s3:0    resource type
86     #3: /oic/sec/acl2    @10.0.2.15:47132    resource type: oic.r.acl2
87     #4: /oic/sec/cred    @10.0.2.15:47132    resource type: oic.r.cred
88     #5: /oic/sec/crl    @10.0.2.15:47132    resource type: oic.r.crl
89     #6: /oic/sec/csr    @10.0.2.15:47132    resource type: oic.r.csr
90     #7: /oic/sec/roles    @10.0.2.15:47132    resource type: oic.r.roles
91     #8: /oic/d    @10.0.2.15:47132    resource type: oic.wk.d
92     #9: /oic/p    @10.0.2.15:0    resource type: oic.wk.p
93     #10: /introspection    @10.0.2.15:0    resource type: oic.wk.introspection
94     #11: /oic/sec/doxm    @fe80::5c79:f160:691d:40bd%enp0s8:42825    resource type
95     #12: /oic/sec/pstat    @fe80::5c79:f160:691d:40bd%enp0s8:0    resource type
96     #13: /oic/sec/acl2    @192.168.56.101:47132    resource type: oic.r.acl2
97     #14: /oic/sec/cred    @192.168.56.101:47132    resource type: oic.r.cred
98     #15: /oic/sec/crl    @192.168.56.101:47132    resource type: oic.r.crl
99     #16: /oic/sec/csr    @192.168.56.101:47132    resource type: oic.r.csr
100     #17: /oic/sec/roles    @192.168.56.101:47132    resource type: oic.r.roles
101     #18: /oic/d    @192.168.56.101:47132    resource type: oic.wk.d
102     #19: /oic/p    @192.168.56.101:0    resource type: oic.wk.p
103     #20: /introspection    @192.168.56.101:0    resource type: oic.wk.introspection
104     #21: /oic/sec/doxm    @fe80::3749:e171:d50f:966d%enp0s3:59488    resource type
105     #22: /oic/sec/pstat    @fe80::3749:e171:d50f:966d%enp0s3:0    resource type
106     #23: /oic/sec/acl2    @10.0.2.15:50400    resource type: oic.r.acl2
107     #24: /oic/sec/cred    @10.0.2.15:50400    resource type: oic.r.cred
108     #25: /oic/sec/crl    @10.0.2.15:50400    resource type: oic.r.crl
109     #26: /oic/sec/csr    @10.0.2.15:50400    resource type: oic.r.csr
110     #27: /oic/sec/roles    @10.0.2.15:50400    resource type: oic.r.roles
111     #28: /oic/d    @10.0.2.15:50400    resource type: oic.wk.d
112     #29: /oic/p    @10.0.2.15:0    resource type: oic.wk.p
113     #30: /introspection    @10.0.2.15:0    resource type: oic.wk.introspection
114     #31: /switch    @10.0.2.15:50400    resource type: oic.r.switch.binary
115     #32: /oic/sec/doxm    @fe80::5c79:f160:691d:40bd%enp0s8:59488    resource type
116     #33: /oic/sec/pstat    @fe80::5c79:f160:691d:40bd%enp0s8:0    resource type
117     #34: /oic/sec/acl2    @192.168.56.101:50400    resource type: oic.r.acl2
118     #35: /oic/sec/cred    @192.168.56.101:50400    resource type: oic.r.cred
119     #36: /oic/sec/crl    @192.168.56.101:50400    resource type: oic.r.crl
120     #37: /oic/sec/csr    @192.168.56.101:50400    resource type: oic.r.csr
121     #38: /oic/sec/roles    @192.168.56.101:50400    resource type: oic.r.roles
122     #39: /oic/d    @192.168.56.101:50400    resource type: oic.wk.d
123     #40: /oic/p    @192.168.56.101:0    resource type: oic.wk.p
124     #41: /introspection    @192.168.56.101:0    resource type: oic.wk.introspection
125     #42: /switch    @192.168.56.101:50400    resource type: oic.r.switch.binary
126
127 Request Methods:    1: GET    4: POST
128 Usage:\<resource number> \<request method> :
129 ```
130 Notice the "/switch" uri on resources #31 and #42. This is a known issue will
131 be fixed at the soonest chance. be aware, the "/switch" uri might occure more
132 than twice and not all of them are going to work. However, one of them will
133 work.
134
135 As instructed in the client application. you can enter the number of the
136 discovered resource you want to interact with (which is either 31 or 42 in this
137 case) followed by 1 for issuing a GET request or 4 for a POST request.
138 If you decided to issue a GET request, you should see the following GET
139 response if everything went OK.
140
141 ```
142 =========================================================
143 Result: (0) - OC_STACK_OK
144 07:12.062 INFO: PayloadLog: Payload Type: Representation
145 07:12.062 INFO: PayloadLog:     Resource #1
146 07:12.062 INFO: PayloadLog:     Resource Types:
147 07:12.062 INFO: PayloadLog:         oic.r.switch.binary
148 07:12.062 INFO: PayloadLog:     Interfaces:
149 07:12.062 INFO: PayloadLog:         oic.if.baseline
150 07:12.062 INFO: PayloadLog:         oic.if.a
151 07:12.062 INFO: PayloadLog:     Values:
152 07:12.062 INFO: PayloadLog:         value(bool):false
153 ==========================================================
154 ```
155 If you decided to issue a POST request, you will be prompted to create a custom
156 payload to be attached to the POST request. As of right now, the only supported
157 feature is turning the led on and off. As a result, type 0 to select the
158 boolean data type then follow it with the name of the property (the key) which
159 is "value" (without quotes as it is writing in the GET response above)
160 and then follow that with (the value) either 1 to turn the led on
161 or 0 to turn the led off. Next press ENTER twice; once to end the first
162 key-value pair entry and once again for completing the custom payload creation.
163
164 Below is a copy of an example usage.
165 ```
166     #42: /switch    @192.168.56.101:50400    resource type: oic.r.switch.binary
167
168 Request Methods:    1: GET    4: POST
169 Usage:<resource number> <request method> :42 4
170
171 Need to create a custom POST payload
172 Enter key value pairs as:    <type(int)> <key> <value>
173 Type: 0:bool      1:int      2:double      3:string
174 press ENTER to finish :0 value 1
175 press ENTER to finish :
176 ```
177
178 If successful, you should see the following POST response
179 ```
180 ==========================================================
181 Result: (4) - OC_STACK_RESOURCE_CHANGED
182 08:24.366 INFO: PayloadLog: Payload Type: Representation
183 08:24.366 INFO: PayloadLog:     Resource #1
184 08:24.366 INFO: PayloadLog:     Resource Types:
185 08:24.366 INFO: PayloadLog:         oic.r.switch.binary
186 08:24.366 INFO: PayloadLog:     Interfaces:
187 08:24.366 INFO: PayloadLog:         oic.if.baseline
188 08:24.366 INFO: PayloadLog:         oic.if.a
189 08:24.366 INFO: PayloadLog:     Values:
190 08:24.366 INFO: PayloadLog:         value(bool):true
191 ==========================================================
192 ```
193 If for whatever reason you noticed the following response instead, then there
194 is a security issue. Hopefully, you will not see this!
195 ```
196 ==========================================================
197 Result: (46) - OC_STACK_UNAUTHORIZED_REQ
198 10:16.370 INFO: PayloadLog: NULL Payload
199 ==========================================================
200 ```
201 To run the applications on either the Intel Joule or the Raspberry Pi, the mraa
202 library must be installed! this is the library that is used to control the
203 physical hardware. Without it, you will still get the simulated led but it is
204 not as fun as the real led turning on and off in the physical world that you
205 can control with your own software! Install it, it is worth it ;)
206
207 Installing mraa on the intel joule. From the home directory, type commands
208 * $sudo add-apt-repository ppa:mraa/mraa
209 * $sudo apt-get update
210 * $sudo apt-get install libmraa1 libmraa-dev mraa-tools python-mraa python3-mraa
211
212 Installing mraa on the raspberry pi, from the parent directory of IoTivity's
213 root directory, type the following commands.
214 * $ git clone https://github.com/intel-iot-devkit/mraa.git
215 * $ cd mraa && mkdir build && cd build && cmake .. && make
216 * $ sudo make install
217
218 To run the applications on Intel Joule running ubuntu then the built-in
219 led on gpio 100 will be connected to the server and you would be able to
220 control it with the client application. It is important to remember to run the
221 server applications in sudo mode as hardware access is a super user privilege!
222 ```
223 $ sudo ./server
224 ```
225 Otherwise, you would get an error with unknown gpio or sometimes you will not
226 get any errors but the built-in led will not respond to your control. It is the
227 same usage as running the applications on a regular machine with Ubuntu which
228 should be described above.
229
230 To run the applications on Raspberry Pi with Raspian then make sure to connect
231 an LED on hardware pin 4 which is gpio 7! The pin mapping of raspberry pi is
232 just messed up like that! Google raspberry pi pinout
233 This pin has all the following names
234 * BCM pin 4
235 * Physical pin 7
236 * Wiring Pi pin 7
237
238 Anyways, have a jumper wire from GPIO 7 to the positive terminal of the led.
239 Then connect a resistor from the negative terminal of the led to ground.
240
241 Also, it is important to remember to run the server application in sudo mode as
242 hardware access is a super user privilege. Otherwise, you might get an error of
243 unknown gpio or the app might run but will not control the led and you might
244 think you connected the led on the wrong pin which may not be the case.
245
246 You can also connect the Enviro pHat sensor board if you have it. Its LED is
247 already connected to gpio 7.
248
249 # Resetting the server app
250 Sometimes it is necessary to reset the server application. For example, the
251 server app needs to be reset during OCF conformance testing or to be
252 onboarded by an OnBoarding tool.
253
254 In order to reset the server app, make sure it is not running. If it is running,
255 then kill it with Ctrl+C.
256 Copy the `ocf_svr_db_server_RFOTM.dat` from the project directory to the project
257 output directory and name it as `ocf_svr_db_server.dat` as shown
258 in the following command
259 From the output directory from which the server application can be exexuted,
260 type
261  
262 ```
263 cp ~/iot/iotivity/examples/OCFSecure/ocf_svr_db_server_RFOTM.dat ocf_svr_db_server.dat
264 ```
265
266 # Testing the server app against CTT
267 You need to install the OCF Certification Test Tool 2.0 on a Windows machine
268 and start it and if the windows machine on the same network as the server and
269 the server app is running then the CTT should discover the server. If not,
270 please check the correct network interface from the options menu and then
271 press the Select IUT button or from the File menu. A pop-up window will
272 show the discovered devices and you should be able to see the server device
273 as 12345678-1234-1234-1234-123456789012 and in the details section, you
274 should be able to see the /switch uri. click on Next. Now, browse to select
275 the PICS file which should be included in this example named
276 `PICS_server_OCF10_vprime.json` then click on Next. From the Testing Profiles
277 uncheck everything and check OCF 1.0 Server. Next, click on
278 Run All Test Cases button. Most likely, you will get a prompt saying
279 "Please initiate device to revert to "ready for OTM" state" and there are
280 2 options to click on; OK and Cancel because this sample is shipped in the
281 "Ready for Normal Operation" state. In this case, reset the server as explained
282 in the "Resetting the server app" section of this document. Then run the server
283 application. You might get this prompt again since the CTT does not un-onboard
284 the device but now you know what to do!
285 Also, you will be prompted to power cycle the device. In this case, you can
286 either kill the server app and restart it again or literally power cycle
287 your device and re-run the server app once your device is back up and
288 connected to the same network.
289 Please note, you might see tests passing with warnings and CT1.7.8.11 test
290 Case failing but that is OK. In order to know which tests are required for
291 certification, refer to the Certification Requirements Status List (CRST) that
292 is associated with the CTT version.
293 This device is tested using CTT version 2.1, which is associated with CRSL 4.3.
294
295 # Known issues
296
297 1. Sometimes, the applications will not run because of not finding some library.
298 In this case, you would need to export the `LD_LIBRARY_PATH` to the environment.
299     ```
300     export LD_LIBRARY_PATH=<output dir orwherever the library is>
301     ```
302     Also, since you need to run the server application in privileged mode, you
303 would need to type this command
304     ```
305     $sudo ldconfig
306     ```
307 and you might also need to type
308     ```
309     $sudo env LD_LIBRARY_PATH=<output dir or wherever the library is>
310     ```
311 Hopefully, you will not run into any library issues but if you run into any
312 issue with this application, please send me an e-mail at ralshafi@vprime.com
313 and file a bug in JIRA and assign it to me (username: alshafi).
314
315 2. Multiple endpoints get discovered and they need to be filtered out
316 eventually. In the meantime, there will be multiple /switch links and only one
317 of them works and the user will need to issues GET requests to all of them
318 until the good one is found. The wrong /switch links will result in
319 Result: (255) - `OC_STACK_ERROR`.
320 The correct /a/led link will result in Result: (0) - `OC_STACK_OK`
321
322 # Example Directory
323
324 There are 16 files in the example directory.
325 * `client.c`
326     * This is the client program
327 * `device_properties.dat`
328     * This is a file storing the device properties in cbor format which is
329 generated automatically by the server application
330 * `ocf_svr_db_client.dat`
331     * This is the cbor format of the secure virtual resource database, defined
332 by the human-readable version `ocf_svr_db_client.json` file, and it is used by
333 the client application
334 * `ocf_svr_db_client.json`
335     * This is the human-readable version of `ocf_svr_db_client.dat`.
336 * `ocf_svr_db_server.dat`
337     * This is the cbor format of the secure virtual resource database and it is
338 an exact copy from the `ocf_svr_db_server_RFNOP.dat` which is the cbor version
339 of the human-readable version `ocf_svr_db_server_RFNOP.json` file. This is the
340 case because the client application does not support the onboarding and
341 provisioning process currently and we need to set the state in the "Ready For
342 Normal Operation" manually.
343
344 We also need to set the state in the "Ready For Ownership Method Transfer"
345 when testing the application with the OCF Certification Test Tool (CTT).
346 In this case, you would need to copy `ocf_svr_db_server_RFOTM.dat` into
347 `ocf_svr_db_server.dat` since that is the file that will be read by the server.
348 * `ocf_svr_db_server_RFNOP.dat`
349     * This is the cbor format of the secure virtual resource database, defined
350 by the human-readable version `ocf_svr_db_server_RFNOP.json` file and it is
351 *NOT* used by the server application. Rename it without the _RFNOP suffix to be
352 read by the server
353 * `ocf_svr_db_server_RFNOP.json`
354     * This is the human-readable version of `ocf_svr_db_server_RFNOP.dat`
355 * `ocf_svr_db_server_RFOTM.dat`
356     * This is the cbor format of the secure virtual resource database, defined
357 by the human-readable version `ocf_svr_db_server_RFOTM.json` file and it is
358 *NOT* used by the server application. Rename it without the `_RFOTM` suffix to
359 be read by the server
360 * `ocf_svr_db_server_RFOTM.json`
361     * This is the human-readable version of `ocf_svr_db_server_RFOTM.dat`
362 * `PICS_server_OCF10_vprime.json`
363     * This is the file that was used as the input to the OCF Certification
364 Test Tool.
365 * `README.md`
366     * This is this file :)
367 * `SConscript`
368     * This is the script that is being used by the scons tool to know how
369 to build the sample applications and what needs to be copied to the output
370 directory.
371 * `server.cpp`
372     * This is the server program.
373 * `switch_introspection.dat`
374     * This is the cbor format of the introspection file (also known as
375 Introspection Device Data IDD) the server needs to read to implement
376 the introspection feature.
377 * `switch_introspection.json`
378     * This is the human-readable version of `switch_introspection.dat` file
379 which is also know as the "swagger" file.
380 * `utilities.c`
381     * this is a supplementary program containing custom utility c functions
382 that help with reporting log messages mainly as of current.