replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / cloud / cloudCommon.c
index acf96ac..d4913b5 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <pthread.h>
 
 #include "ocstack.h"
 #include "logger.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "cathreadpool.h"
 #include "ocpayload.h"
 #include "payload_logging.h"
+#include "aclresource.h"
+#include "crlresource.h"
 #include "ocprovisioningmanager.h"
+#include "casecurityinterface.h"
+#include "mbedtls/ssl_ciphersuites.h"
+#include "pkix_interface.h"
+#include "../hw_emul/hw_interface.h"
 
 #include "utils.h"
 #include "cloudAuth.h"
@@ -49,7 +56,7 @@
 
 #define GITHUB_AUTH_LINK        "https://github.com/login?return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3Dea9c18f540323b0213d0%26redirect_uri%3Dhttp%253A%252F%252Fwww.example.com%252Foauth_callback%252F"
 
-#define CLIENT_ONLY(mode)       if (OC_SERVER == mode) { wrongRequest(); break; }
+#define CLIENT_ONLY(mode)       if (OC_SERVER == (mode)) { wrongRequest(); sendDataToServer = false; break; }
 
 static bool fExit = false;
 
@@ -61,8 +68,8 @@ static char *fname = DEFAULT_DB_FILE;
 static uint64_t timeout;
 static uint16_t g_credId = 0;
 
-static ca_cond cond;
-static ca_mutex mutex;
+static oc_cond cond;
+static oc_mutex mutex;
 
 typedef enum {
     SIGN_UP       = 1,
@@ -76,6 +83,8 @@ typedef enum {
     USE_RSA = 8,
     SAVE_TRUST_CERT = 9,
     USE_SECURE_CONN = 10,
+    CONFIG_SELF_OWNERSHIP = 11,
+    SECURE_STORAGE_HW_EMULATION = 12,
 
     DISCOVERY     = 13,
     GET           = 14,
@@ -93,7 +102,9 @@ typedef enum {
 
     ACL_INDIVIDUAL_GET_INFO = 40,
     ACL_INDIVIDUAL_UPDATE_ACE = 41,
-    ACL_INDIVIDUAL_DELETE = 42,
+    ACL_INDIVIDUAL_UPDATE = 42,
+    ACL_INDIVIDUAL_DELETE = 43,
+    ACL_INDIVIDUAL_DELETE_ACE = 44,
 
     ACL_GROUP_CREATE = 50,
     ACL_GROUP_FIND   = 51,
@@ -135,9 +146,11 @@ static void printMenu(OCMode mode)
     printf("** %d - Change default port\n", PORT);
     printf("** %d - Change default database filename\n", DB_FILE);
     printf("** %d - Change default auth provider\n", AUTH_PROVIDER);
-    printf("** %d - Change TLS cipher suite to RSA\n", USE_RSA);
+    printf("** %d - Change TLS cipher suite (ECDSA/RSA)\n", USE_RSA);
     printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
     printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
+    printf("** %d - Configure SVRdb as Self-OwnerShip\n", CONFIG_SELF_OWNERSHIP);
+    printf("** %d - Configure Secure Storage HW Emulation\n", SECURE_STORAGE_HW_EMULATION);
 
     if (OC_CLIENT == mode)
     {
@@ -163,7 +176,9 @@ static void printMenu(OCMode mode)
     printf("** ACL INDIVIDUAL\n");
     printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
     printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
+    printf("** %d - ACL individual update Request\n", ACL_INDIVIDUAL_UPDATE);
     printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
+    printf("** %d - ACL individual delete ACE Request\n", ACL_INDIVIDUAL_DELETE_ACE);
 
     printf("** ACL GROUP MANAGER\n");
     printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
@@ -187,10 +202,8 @@ static void printMenu(OCMode mode)
     printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE);
 
     printf("** EXIT\n");
-    printf("** %d - Exit cloud %s\n\n", EXIT, title);
+    printf("** %d - Exit cloud %s\n", EXIT, title);
     printf("************************************************************\n");
-
-    printf(">> Enter Menu number:\n");
 }
 
 void unlockMenu(void *data)
@@ -199,9 +212,9 @@ void unlockMenu(void *data)
 
     if (!fExit)
     {
-        ca_mutex_lock(mutex);
-        ca_cond_signal(cond);
-        ca_mutex_unlock(mutex);
+        oc_mutex_lock(mutex);
+        oc_cond_signal(cond);
+        oc_mutex_unlock(mutex);
     }
 }
 
@@ -223,33 +236,212 @@ static void handleCB(void* ctx, OCStackResult result, void* data)
     unlockMenu(NULL);
 }
 
+/**
+ * This function prints Acl id and calls default callback function handleCB()
+ *
+ * @param[in] ctx          context
+ * @param[in] result       result
+ * @param[in] aclId        acl id
+ */
+static void handleAclIdCB(void* ctx, OCStackResult result, void* aclId)
+{
+    OIC_LOG_V(INFO, TAG, "Received Acl id = %s", (char *)aclId);
+    handleCB(ctx, result, aclId);
+    OICFree(aclId);
+}
+
+/**
+ * This function prints group id and calls default callback function handleCB()
+ *
+ * @param[in] ctx          context
+ * @param[in] result       result
+ * @param[in] groupId      group id
+ */
+static void handleAclCreateGroupCB(void* ctx, OCStackResult result, void* groupId)
+{
+    OIC_LOG_V(INFO, TAG, "Received gid = %s", (char *)groupId);
+    handleCB(ctx, result, groupId);
+    OICFree(groupId);
+}
+
+/**
+ * This function prints group policy and calls default callback function handleCB()
+ *
+ * @param[in] ctx          context
+ * @param[in] result       result
+ * @param[in] gp           group policy
+ */
+static void handleAclPolicyCheckCB(void* ctx, OCStackResult result, void* gp)
+{
+    OIC_LOG_V(INFO, TAG, "Received gp = %s", (char *)gp);
+    handleCB(ctx, result, gp);
+    OICFree(gp);
+}
+
+/**
+ * This function prints received acl and calls default callback function handleCB()
+ *
+ * @param[in] ctx          context
+ * @param[in] result       result
+ * @param[in] acl          acl
+ */
+static void handleAclIndividualGetInfoCB(void* ctx, OCStackResult result, void* acl)
+{
+    printACL((OicSecAcl_t* )acl);
+    handleCB(ctx, result, acl);
+    //can't delete acl here because its ACE's were added to gAcl
+    //TODO: changes in aclresources.c required to fix that
+}
+
+/**
+ * This function prints received group id list and calls default callback function handleCB()
+ *
+ * @param[in] ctx          context
+ * @param[in] result       result
+ * @param[in] gidList      group id list
+ */
+static void handleAclFindMyGroupCB(void* ctx, OCStackResult result, void* gidList)
+{
+    printStringArray((stringArray_t *)gidList);
+    handleCB(ctx, result, gidList);
+    clearStringArray((stringArray_t *)gidList);
+}
+
+/**
+ * This function prints received acl and calls default callback function handleCB()
+ *
+ * @param[in] ctx          context
+ * @param[in] result       result
+ * @param[in] crl          crl
+ */
+static void handleGetCrlCB(void* ctx, OCStackResult result, void* crl)
+{
+    printCrl((OicSecCrl_t *)crl);
+    handleCB(ctx, result, crl);
+    DeleteCrl((OicSecCrl_t *)crl);
+}
+
+/**
+ * This function prints received invitation response and calls default callback function handleCB()
+ *
+ * @param[in] ctx          context
+ * @param[in] result       result
+ * @param[in] invite       invitation response (it has inviteResponse_t* type)
+ */
+static void handleAclGetInvitationCB(void* ctx, OCStackResult result, void* invite)
+{
+    printInviteResponse((inviteResponse_t *)invite);
+    handleCB(ctx, result, invite);
+    clearInviteResponse((inviteResponse_t *)invite);
+    OICFree(invite);
+}
+
 static OCStackResult saveTrustCert(void)
 {
     OCStackResult res = OC_STACK_ERROR;
     OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
 
-    ByteArray trustCertChainArray = {0, 0};
+    OCByteString trustCertChainArray = {0, 0};
     const char *filename = "rootca.crt";
 
-    if (!readFile(filename, (OCByteString *)&trustCertChainArray))
+    if (!readFile(filename, &trustCertChainArray))
     {
         OIC_LOG_V(ERROR, TAG, "Can't read %s file", filename);
+        OICFree(trustCertChainArray.bytes);
         return OC_STACK_ERROR;
     }
-    OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
+    OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.bytes, trustCertChainArray.len);
 
-    res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
+    res = OCSaveTrustCertChain(trustCertChainArray.bytes, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
 
-    if(OC_STACK_OK != res)
+    if (OC_STACK_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "OCSaveTrustCertChainBin API error");
-        return res;
+        OIC_LOG(ERROR, TAG, "OCSaveTrustCertChain API error");
+    }
+    else
+    {
+        OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
+    }
+    OICFree(trustCertChainArray.bytes);
+
+    return res;
+}
+
+static OCStackResult configSelfOwnership(void)
+{
+    OCStackResult res = OC_STACK_ERROR;
+    OIC_LOG(INFO, TAG, "Configures SVR DB as self-ownership.");
+
+    res = OCConfigSelfOwnership();
+
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "OCConfigSelfOwnership API error. Please check SVR DB");
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "Success to configures SVR DB as self-ownership");
     }
-    OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
 
     return res;
 }
 
+static void configSecureStorageHwEmulation()
+{
+    OIC_LOG(INFO, TAG, "Enable Secure Storage HW Emulation");
+
+    printf("         Enter Own Certificate File Path[~4095]: ");
+    char cert_filepath[4096] = {0,};
+    for(int ret=0; 1!=ret; )
+    {
+        ret = scanf("%255s", cert_filepath);
+        for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                    // '0x20<=code' is character region
+    }
+
+    printf("         Enter Private Key File Path[~4095]: ");
+    char key_filepath[4096] = {0,};
+    for(int ret=0; 1!=ret; )
+    {
+        ret = scanf("%255s", key_filepath);
+        for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                    // '0x20<=code' is character region
+    }
+
+    printf("         Enter Password for Key Password[~31][Press (Enter) to not set]: ");
+    char pwd[32] = {0,};
+    for(int i=0; i < 31; i++)
+    {
+        pwd[i] = (char)getchar();
+        if (0x20 <= pwd[i])
+        {
+            pwd[i--] = '\0';
+            continue;
+        }
+        if (0x0A == pwd[i])
+        {
+            pwd[i] = '\0';
+            break;
+        }
+    }
+
+    if (0 != SSemulSetCertkeyFilepath(cert_filepath, key_filepath, pwd))
+    {
+        OIC_LOG(ERROR, TAG, "    Fail to set cert/key file path");
+        return;
+    }
+
+    if (0 != SetHwPkixCallbacks(HWGetKeyContext,
+                                                  HWFreeKeyContext,
+                                                  HWGetOwnCertificateChain,
+                                                  HWSetupPkContext))
+    {
+        OIC_LOG(ERROR, TAG, "    Fail to regist HW Pkix Callbacks");
+        return;
+    }
+    OIC_LOG(INFO, TAG, "    Success to regist HW Pkix Callbacks");
+}
+
 static void wrongRequest()
 {
     printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
@@ -269,12 +461,13 @@ static void userRequests(void *data)
     strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
     endPoint.port = DEFAULT_PORT;
 
-    mutex = ca_mutex_new();
-    cond = ca_cond_new();
+    mutex = oc_mutex_new();
+    cond = oc_cond_new();
 
     while (false == fExit)
     {
         OCStackResult res = OC_STACK_ERROR;
+        bool sendDataToServer = true;
         timeout = DEFAULT_RESPONSE_WAIT_TIME;
         //startup report
         printf("-----------------------------------------------------------\n");
@@ -287,7 +480,7 @@ static void userRequests(void *data)
         printMenu(mode);
 
         int request = 0;
-        scanf("%d", &request);
+        readInteger(&request, "Menu number", "see above");
 
         switch (request)
         {
@@ -307,6 +500,7 @@ static void userRequests(void *data)
             break;
         case HOST:
             readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST);
+            sendDataToServer = false;
             break;
         case PORT:
         {
@@ -315,19 +509,20 @@ static void userRequests(void *data)
             int tmp = 0;
             readInteger(&tmp, "port number", example);
             endPoint.port = tmp;
+            sendDataToServer = false;
         }
         break;
         case CRL_GET:
-            res = OCWrapperGetCRL(&endPoint, handleCB);
+            res = OCWrapperGetCRL(&endPoint, handleGetCrlCB);
             break;
         case CRL_POST:
             res = OCWrapperPostCRL(&endPoint, handleCB);
             break;
         case ACL_GROUP_CREATE:
-            res = OCWrapperAclCreateGroup(&endPoint, handleCB);
+            res = OCWrapperAclCreateGroup(&endPoint, handleAclCreateGroupCB);
             break;
         case ACL_GROUP_FIND:
-            res = OCWrapperAclFindMyGroup(&endPoint, handleCB);
+            res = OCWrapperAclFindMyGroup(&endPoint, handleAclFindMyGroupCB);
             break;
         case ACL_GROUP_DELETE:
             res = OCWrapperAclDeleteGroup(&endPoint, handleCB);
@@ -351,7 +546,7 @@ static void userRequests(void *data)
             res = OCWrapperAclInviteUser(&endPoint, handleCB);
             break;
         case ACL_GROUP_GET_INVITE:
-            res = OCWrapperAclGetInvitation(&endPoint, handleCB);
+            res = OCWrapperAclGetInvitation(&endPoint, handleAclGetInvitationCB);
             break;
         case ACL_GROUP_DELETE_INVITE:
             res = OCWrapperAclDeleteInvitation(&endPoint, handleCB);
@@ -360,26 +555,32 @@ static void userRequests(void *data)
             res = OCWrapperAclCancelInvitation(&endPoint, handleCB);
             break;
         case ACL_POLICY_CHECK_REQUEST:
-            res = OCWrapperAclPolicyCheck(&endPoint, handleCB);
+            res = OCWrapperAclPolicyCheck(&endPoint, handleAclPolicyCheckCB);
             break;
         case ACL_ID_GET_BY_DEVICE:
-            res = OCWrapperAclIdGetByDevice(&endPoint, handleCB);
+            res = OCWrapperAclIdGetByDevice(&endPoint, handleAclIdCB);
             break;
         case ACL_ID_CREATE:
-            res = OCWrapperAclIdCreate(&endPoint, handleCB);
+            res = OCWrapperAclIdCreate(&endPoint, handleAclIdCB);
             break;
         case ACL_ID_DELETE:
             res = OCWrapperAclIdDelete(&endPoint, handleCB);
             break;
         case ACL_INDIVIDUAL_GET_INFO:
-            res = OCWrapperAclIndividualGetInfo(&endPoint, handleCB);
+            res = OCWrapperAclIndividualGetInfo(&endPoint, handleAclIndividualGetInfoCB);
             break;
         case ACL_INDIVIDUAL_UPDATE_ACE:
             res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
             break;
+        case ACL_INDIVIDUAL_UPDATE:
+            res = OCWrapperAclIndividualUpdate(&endPoint, handleCB);
+            break;
         case ACL_INDIVIDUAL_DELETE:
             res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
             break;
+        case ACL_INDIVIDUAL_DELETE_ACE:
+            res = OCWrapperAclIndividualDeleteAce(&endPoint, handleCB);
+            break;
         case CSR_SIGN:
             res = OCWrapperCertificateIssueRequest(&endPoint, handleCB);
             break;
@@ -400,34 +601,63 @@ static void userRequests(void *data)
             res= InitRequest(OC_REST_POST);
             break;
         case USE_RSA:
-            CASelectCipherSuite(0x35, CA_ADAPTER_TCP);
+        {
+            int tmp = 0;
+            readInteger(&tmp, "Select Cipher Suite", "0 - ECDSA, other - RSA");
+            uint16_t cipher = tmp? MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256:
+                                   MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
+            if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP))
+            {
+                OIC_LOG(ERROR, TAG, "CASelectCipherSuite returned an error");
+            }
+            sendDataToServer = false;
+        }
             break;
         case SAVE_TRUST_CERT:
             saveTrustCert();
+            sendDataToServer = false;
             break;
         case USE_SECURE_CONN:
         {
             int tmp = 0;
             readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure");
             setCoapPrefix(0 == tmp ? false : true);
+            sendDataToServer = false;
         }
             break;
+        case CONFIG_SELF_OWNERSHIP:
+            configSelfOwnership();
+            sendDataToServer = false;
+            break;
+        case SECURE_STORAGE_HW_EMULATION:
+            configSecureStorageHwEmulation();
+            sendDataToServer = false;
+            break;
         case EXIT:
-            ca_mutex_free(mutex);
-            ca_cond_free(cond);
+            oc_mutex_free(mutex);
+            oc_cond_free(cond);
             fExit = true;
+            sendDataToServer = false;
             break;
         default:
             wrongRequest();
+            sendDataToServer = false;
             break;
         }
 
         //if requests were sent then wait response
-        if (res == OC_STACK_OK)
+        if (sendDataToServer)
         {
-            ca_mutex_lock(mutex);
-            ca_cond_wait_for(cond, mutex, timeout);
-            ca_mutex_unlock(mutex);
+            if (OC_STACK_OK == res)
+            {
+                oc_mutex_lock(mutex);
+                oc_cond_wait_for(cond, mutex, timeout);
+                oc_mutex_unlock(mutex);
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, TAG, "Request returned an error %d", res);
+            }
         }
     }
 }
@@ -487,7 +717,7 @@ bool parseCommandLineArguments(int argc, char *argv[])
 OCStackResult initPersistentStorage()
 {
     //Initialize Persistent Storage for SVR database
-    static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+    static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
 
     return OCRegisterPersistentStorageHandler(&ps);
 }
@@ -501,7 +731,7 @@ OCStackResult startRequestsThread(OCMode *mode)
         return res;
     }
 
-    res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode);
+    res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode, NULL);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "thread pool add task error.");
@@ -517,6 +747,10 @@ OCStackResult initProcess(OCMode mode)
 
 void startProcess()
 {
+    struct timespec timeout;
+    timeout.tv_sec  = 0;
+    timeout.tv_nsec = 100000000L;
+
     while(false == fExit)
     {
         if (OCProcess() != OC_STACK_OK)
@@ -524,6 +758,7 @@ void startProcess()
             OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
             break;
         }
+        nanosleep(&timeout, NULL);
     }
 
     if (OCStop() != OC_STACK_OK)