User Tools

Site Tools


ckm

Certificate Key Manager - Programmer's Guide

To achieve authentication and transport security during communications in IoT network, certificates containing public keys of communicating parties and private keys can be used. The certificate and private key may be issued by a local or remote certificate authority(CA) when an OIC device is deployed in the IoT network and credential provisioning is supported by a credential management service

Introduction

Certificate Key Manager (CKM) is designed to address X.509-based Public Key Infrasturcture (PKI) needs in the IoTivity. Unlike PSK, this feature allows users to use the same keys for establishing a secure connection with all devices on the local area.

Architecture

Certificate based Key Manager (CKM for short) at a high level plays the roles of certificate issuer for devices and Certificate Revocation List (CRL for short) issuer.

  1. The certificate issuing is as a part of the bootstrapping service to provide a public/private key-pair for a device

  1. Certificate Revocation List Issuing

API list of CKM

C API

PKIError SetSerialNumber (const long serNum)
Set serial number for next certificate and save it in the CA storage.
PKIError SetRootName (const ByteArray rootName)
Set CA common name and save it in the CA storage.
PKIError CKMSetCAInfo (const long serNum, const ByteArray rootName)
Set CA info and save it in the CA storage. Should be called before certificate generation.
PKIError GenerateCAKeyPair (ByteArray *caPrivateKey, ByteArray *caPublicKey)
Generate key pair for CA. Should be called before certificate generation.
PKIError CKMIssueRootCertificate (const uint8_t *uint8NotBefore, const uint8_t *uint8NotAfter, ByteArray *issuedRootCertificate)
Issues X.509 certificate with specified parameters. SetSerialNumber, SetRootName and GenerateCAKeyPair should be called before.
PKIError GenerateKeyPair (ByteArray *privateKey, ByteArray *publicKey)
Generate key pair for ordinary device.
PKIError CKMIssueDeviceCertificate (const uint8_t *uint8SubjectName, const uint8_t *uint8NotBefore, const uint8_t *uint8NotAfter, const uint8_t *uint8SubjectPublicKey, ByteArray *issuedCertificate)
Issues X.509 certificate with specified parameters. SetSerialNumber, SetRootName and GenerateCAKeyPair should be called before.
PKIError GenerateDERCertificateFile (const ByteArray *certificate, const char *const certFileName)
Write certificate into specified file.
PKIError GenerateCSR (const uint8_t *uint8SubjectName, const uint8_t *uint8SubjectPublicKey, const uint8_t *uint8SubjectPrivateKey, ByteArray *encodedCSR)
Issues certificate signing request with specified parameters.
PKIError GenerateCertificateByCSR (const ByteArray *encodedCSR, ByteArray *issuedCertificate)
Issues X.509 certificate based on certificate signing request.
PKIError CKMIssueCRL (const uint8_t *uint8ThisUpdateTime, const uint32_t nuberOfRevoked, const uint32_t *revokedNumbers, const uint8_t **revocationDates, ByteArray *encodedCRL)
Generate certificate revocation list with specified parameters.
PKIError CKMGetCRL (ByteArray *certificateRevocationList)
Gets current certificate revocation list.
PKIError CKMRevocateCertificate (const uint8_t *uint8ThisUpdateTime, const long revokedNumber, ByteArray *encodedCRL)
Add specified certificate into certificate revocation list.

C++ API

OCStackResult provisionInit (const std::string &dbPath)
The API is responsible for initialization of the provisioning manager. It will load provisioning database which have owned device's list and their linked status.
OCStackResult discoverUnownedDevices (unsigned short timeout, DeviceList_t &list)
API is responsible for discovery of devices in it's subnet. It will list all the device in subnet which are not yet owned.
OCStackResult discoverOwnedDevices (unsigned short timeout, DeviceList_t &list)
API is responsible for discovery of devices in it's subnet. It will list all the device in subnet which are already owned by calling provisioning client.
OCStackResult provisionPairwiseDevices (const Credential &cred, const OicSecAcl_t *acl1, const OCSecureResource &device2, const OicSecAcl_t *acl2, ResultCallBack resultCallback)
API to provision credentials between two devices and ACLs for the devices who act as a server.
OCStackResult doOwnershipTransfer (ResultCallBack resultCallback)
API to do ownership transfer for un-owned device.
OCStackResult provisionACL (const OicSecAcl_t *acl, ResultCallBack resultCallback)
API to provision credential to devices.
OCStackResult provisionCredentials (const Credential &cred, const OCSecureResource &device2, ResultCallBack resultCallback)
API to provision credentials between two devices and ACLs for the devices who act as a server.
OCStackResult unlinkDevices (const OCSecureResource &device2, ResultCallBack resultCallback)
API to remove the credential & relationship between the two devices.
OCStackResult removeDevice (unsigned short waitTimeForOwnedDeviceDiscovery, ResultCallBack resultCallback)
API to remove device credential from all devices in subnet.
OCStackResult getLinkedDevices (UuidList_t &uuidList)
This method is used to get linked devices' IDs.

Sample Application

Open three terminal windows in linux The first one use for start Light server Note: Here and below $PROJ_DIR is root directory of iotivity project (e.g /path/to/iotivity).

$ cd $PROJ_DIR/out/linux/x86_64/release/resource/csdk/security/provisioning/ck_manager/sample/Light_Resource
$ cp $PROJ_DIR/resource/csdk/security/provisioning/ck_manager/sample/Light_Resource/*.json ./
$ ./Light_server</olmap>

Second terminal window use for start Door server

$ cp $PROJ_DIR/resource/csdk/security/provisioning/ck_manager/sample/Door_Resource/*.json ./
$ ./Door_server

And third terminal window use for start provisioning_client provisioning_client ask for input ACL data:

  1. Controller device. Enter ID of the doorDeviceUUID00.
  2. Controlee device. Enter ID of the lightDeviceUUID0.
  3. Subject : doorDeviceUUID00.
  4. Num. of Resource : 1.
  5. [1]Resource : /a/light
  6. permissions: CRUDN
  7. Num. of Rowner : 1
  8. [1]Rowner : lightDeviceUUID0

After successfull sending acl provisioning_client will ask you for CRL data:

  1. Enter number of revoced certificates(1..9): 1
  2. Revoced certificate 0: Serial number (E. g.: 100): 3

And then you should see message about successfull sending CRL Note: provisioning_client send ACL and CRL only to Light sever

$ cd $PROJ_DIR/out/linux/x86_64/release/resource/csdk/security/provisioning/ck_manager/sample
$ rm ckminfo.dat
$ cp $PROJ_DIR/resource/csdk/security/provisioning/ck_manager/sample/oic_svr_db_pt.json ./
$ ./provisioningclient
Provisioning device ID : doorDeviceUUID00
Provisioning Success~!!
Provisioning device ID : lightDeviceUUID0
Provisioning Success~!!
Sending credential is succeed~!!
$ cd $PROJ_DIR/out/linux/x86_64/release/resource/csdk/security/provisioning/ck_manager/sample
$ rm ckminfo.dat
$ cp $PROJ_DIR/resource/csdk/security/provisioning/ck_manager/sample/oic_svr_db_pt.json ./
$ ./provisioningclient
Provisioning device ID : doorDeviceUUID00
Provisioning Success~!!
Provisioning device ID : lightDeviceUUID0
Provisioning Success~!!
Sending credential is succeed~!!
 
-Set ACL policy for target device
 
-URN identifying the subject
ex) doorDeviceUUID00 (16 Numbers except to '-')
Subject : doorDeviceUUID00
Num. of Resource : 1
-URI of resource
ex) /a/light (Max_URI_Length: 64 Byte )
[1]Resource : /a/light
-Set the permission(C,R,U,D,N)
ex) CRUDN, CRU_N,..(5 Charaters)
Permission : CRUDN
Num. of Rowner : 1
-URN identifying the rowner
ex) lightDeviceUUID0 (16 Numbers except to '-')
[1]Rowner : lightDeviceUUID0
Sending ACL is succeed~!!
Enter number of revoced certificates (1..9)
1
Revoked certificate 0:
Serial number (E. g.: 100):
2
Sending CRL is succeed~!!

Change window to terminal where Door server is running Enter 'd' for discovery. You should see output like this:

21:56.283 INFO: DEMO: isUpdated is false...
21:56.495 INFO: DEMO: Callback Context for DISCOVER query recvd successfully
21:56.495 INFO: DEMO: StackResult: OC_STACK_OK
21:56.495 INFO: DEMO: Device =============> Discovered @ 10.0.2.15:37942
21:56.495 INFO: DEMO: Payload Type: Discovery
21:56.495 INFO: DEMO: 	Resource #1
21:56.495 INFO: DEMO: 	URI:/a/light
21:56.495 INFO: DEMO: 	SID:
21:56.495 INFO: DEMO: F0 5A 6C 8B 59 66 48 89 BE 1E 4E EF FA 23 4E FD
21:56.495 INFO: DEMO: 	Resource Types:
21:56.495 INFO: DEMO: 		core.light
21:56.495 INFO: DEMO: 	Interfaces:
21:56.495 INFO: DEMO: 		oic.if.baseline
21:56.495 INFO: DEMO: 	Bitmap: 3
21:56.495 INFO: DEMO: 	Secure?: true
21:56.495 INFO: DEMO: 	Port: 43910
21:56.495 INFO: DEMO:
21:56.495 INFO: DEMO: Uri -- /a/light
21:56.495 INFO: DEMO: Secure -- YES
21:56.591 INFO: DEMO: Callback Context for DISCOVER query recvd successfully
21:56.591 INFO: DEMO: StackResult: OC_STACK_OK
21:56.591 INFO: DEMO: Device =============> Discovered @ 10.0.2.15:55808
21:56.591 INFO: DEMO: Payload Type: Discovery
21:56.591 INFO: DEMO: 	Resource #1
21:56.591 INFO: DEMO: 	URI:/a/door
21:56.591 INFO: DEMO: 	SID:
21:56.591 INFO: DEMO: E9 68 45 ED 5D E1 4A F3 86 31 FD 0E 5E 25 EB B3
21:56.591 INFO: DEMO: 	Resource Types:
21:56.591 INFO: DEMO: 		core.door
21:56.591 INFO: DEMO: 	Interfaces:
21:56.591 INFO: DEMO: 		oic.if.baseline
21:56.591 INFO: DEMO: 	Bitmap: 3
21:56.591 INFO: DEMO: 	Secure?: true
21:56.591 INFO: DEMO: 	Port: 41403
21:56.591 INFO: DEMO:
21:56.591 INFO: DEMO: Uri -- /a/door
21:56.591 INFO: DEMO: Secure -- YES

If you can see /a/light discowered then this is success. Next you should enter g to start get request Enter address : 10.0.2.15:43910 Port you can find here

21:56.495 INFO: DEMO: 	URI:/a/light
21:56.495 INFO: DEMO: 	SID:
21:56.495 INFO: DEMO: F0 5A 6C 8B 59 66 48 89 BE 1E 4E EF FA 23 4E FD
21:56.495 INFO: DEMO: 	Resource Types:
21:56.495 INFO: DEMO: 		core.light
21:56.495 INFO: DEMO: 	Interfaces:
21:56.495 INFO: DEMO: 		oic.if.baseline
21:56.495 INFO: DEMO: 	Bitmap: 3
21:56.495 INFO: DEMO: 	Secure?: true
21:56.495 INFO: DEMO: 	Port: 43910

If you see this lines in output:

22:31.647 INFO: DEMO: Callback Context for GET query recvd successfully
22:31.647 INFO: DEMO: StackResult: OC_STACK_OK
22:31.647 INFO: DEMO: SEQUENCE NUMBER: 2
22:31.647 INFO: DEMO: Payload Type: Representation
22:31.647 INFO: DEMO: 	Resource #1
22:31.647 INFO: DEMO: 	URI:/a/light
22:31.647 INFO: DEMO: 	Resource Types:
22:31.647 INFO: DEMO: 	Interfaces:
22:31.647 INFO: DEMO: 	Values:
22:31.647 INFO: DEMO: 		brightness(int):0
22:31.647 INFO: DEMO: =============> Get Response

then certificate did not rejected with CRL if not then it did.

ckm.txt · Last modified: 2016/07/22 09:50 by dongik Lee