Save and Provision Trust Cert. Chain
authorjs126.lee <js126.lee@samsung.com>
Thu, 18 Aug 2016 07:43:39 +0000 (16:43 +0900)
committerDmitriy Zhuravlev <d.zhuravlev@samsung.com>
Tue, 23 Aug 2016 05:59:24 +0000 (05:59 +0000)
1. Save TrustCertChain as binary
2. Provision TrustCertChain
3. Add credusae and optionaldata into cred resource

[Patch 1] Upload patch
[Patch 2] Add encodingtype into optionaldata
[Patch 3] Add encodingtype into OC/SRPSVACETrustCertChain API
[Patch 4] Apply review comment

Note: You can verify this patch with https://gerrit.iotivity.org/gerrit/#/c/10597/

Change-Id: I651f3e61bcfc16e2d7355fe6a01833fda4433579
Signed-off-by: js126.lee <js126.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/10595
Reviewed-by: Dmitriy Zhuravlev <d.zhuravlev@samsung.com>
Tested-by: Dmitriy Zhuravlev <d.zhuravlev@samsung.com>
resource/csdk/security/include/internal/credresource.h
resource/csdk/security/include/internal/srmresourcestrings.h
resource/csdk/security/include/securevirtualresourcetypes.h
resource/csdk/security/provisioning/include/internal/secureresourceprovider.h
resource/csdk/security/provisioning/include/ocprovisioningmanager.h
resource/csdk/security/provisioning/src/ocprovisioningmanager.c
resource/csdk/security/provisioning/src/secureresourceprovider.c
resource/csdk/security/src/credresource.c
resource/csdk/security/src/srmresourcestrings.c

index 52e105c..a1c1c5a 100644 (file)
@@ -57,6 +57,16 @@ OCStackResult DeInitCredResource();
 OicSecCred_t* GetCredResourceData(const OicUuid_t* subjectId);
 
 /**
+ * This method is used by SRM to retrieve credential for given credId.
+ *
+ * @param credId for which credential is required.
+ *
+ * @return reference to @ref OicSecCred_t, if credential is found, else NULL, if credential
+ * not found.
+ */
+OicSecCred_t* GetCredResourceDataByCredId(const uint16_t credId);
+
+/**
  * This function converts credential data into CBOR format.
  * Caller needs to invoke 'free' when done using returned string.
  *
index d9e8de8..f7f0773 100644 (file)
@@ -115,6 +115,7 @@ extern const char * OIC_JSON_PRIVATEDATA_NAME;
 extern const char * OIC_JSON_PUBDATA_NAME;
 extern const char * OIC_JSON_PRIVDATA_NAME;
 extern const char * OIC_JSON_OPTDATA_NAME;
+extern const char * OIC_JSON_CREDUSAGE_NAME;
 extern const char * OIC_JSON_CRMS_NAME;
 extern const char * OIC_JSON_VALIDITY_NAME;
 extern const char * OIC_JSON_PERIOD_NAME;
@@ -151,6 +152,8 @@ extern const char * OIC_JSON_SEC_V_NAME;
 
 extern const char * OIC_JSON_EMPTY_STRING;
 
+extern const char * TRUST_CA;
+
 extern OicUuid_t WILDCARD_SUBJECT_ID;
 extern OicUuid_t WILDCARD_SUBJECT_B64_ID;
 extern size_t WILDCARD_SUBJECT_ID_LEN;
@@ -163,6 +166,8 @@ extern const char * OXM_MANUFACTURER_CERTIFICATE;
 
 extern const char * OIC_SEC_ENCODING_BASE64;
 extern const char * OIC_SEC_ENCODING_RAW;
+extern const char * OIC_SEC_ENCODING_PEM;
+extern const char * OIC_SEC_ENCODING_DER;
 
 extern const char * OIC_SEC_TRUE;
 extern const char * OIC_SEC_FALSE;
index 407040e..bc0efb4 100644 (file)
@@ -273,7 +273,9 @@ typedef enum
 {
     OIC_ENCODING_UNKNOW = 0,
     OIC_ENCODING_RAW = 1,
-    OIC_ENCODING_BASE64 = 2
+    OIC_ENCODING_BASE64 = 2,
+    OIC_ENCODING_PEM = 3,
+    OIC_ENCODING_DER = 4
 }OicEncodingType_t;
 
 typedef struct OicSecKey OicSecKey_t;
@@ -400,7 +402,8 @@ struct OicSecCred
     OicSecCredType_t    credType;       // 3:R:S:Y:oic.sec.credtype
 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
     OicSecCert_t        publicData;     // own cerificate chain
-    OicSecCert_t        optionalData;   // CA's cerificate chain
+    char            *credUsage;            // 4:R:S:N:String
+    OicSecKey_t        optionalData;   // CA's cerificate chain
 #endif /* __WITH_X509__  or __WITH_TLS__*/
     OicSecKey_t         privateData;    // 6:R:S:N:oic.sec.key
     char                *period;        // 7:R:S:N:String
index 8bc23eb..001339b 100644 (file)
@@ -64,7 +64,7 @@ OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDevi
 OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
         OCProvisionResultCB resultCallback);
 
-#ifdef __WITH_X509__
+#if defined(__WITH_X509__) || defined(__WITH_TLS__)
 /**
  * API to send CRL information to resource.
  *
@@ -76,7 +76,35 @@ OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDevic
  */
 OCStackResult SRPProvisionCRL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
         OicSecCrl_t *crl, OCProvisionResultCB resultCallback);
-#endif // __WITH_X509__
+
+/**
+ * function to provision Trust certificate chain to devices.
+ *
+ * @param[in] ctx Application context would be returned in result callback.
+ * @param[in] type Type of credentials to be provisioned to the device.
+ * @param[in] credId CredId of trust certificate chain to be provisioned to the device.
+ * @param[in] selectedDeviceInfo Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ *            provisioning request recieves a response from first resource server.
+ * @return  OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult SRPProvisionTrustCertChain(void *ctx, OicSecCredType_t type, uint16_t credId,
+                                      const OCProvisionDev_t *selectedDeviceInfo,
+                                      OCProvisionResultCB resultCallback);
+
+/**
+ * function to save Trust certificate chain into Cred of SVR.
+ *
+ * @param[in] trustCertChain Trust certificate chain to be saved in Cred of SVR.
+ * @param[in] chainSize Size of trust certificate chain to be saved in Cred of SVR
+ * @param[in] encodingType Encoding type of trust certificate chain to be saved in Cred of SVR
+ * @param[out] credId CredId of saved trust certificate chain in Cred of SVR.
+ * @return  OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult SRPSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
+                                        OicEncodingType_t encodingType,uint16_t *credId);
+
+#endif // __WITH_X509__ || __WITH_TLS__
 /**
  * API to send Direct-Pairing Configuration to a device.
  *
index 1ab0f10..925c81a 100755 (executable)
@@ -293,7 +293,7 @@ void OCDeleteACLList(OicSecAcl_t* pAcl);
  */\r
 void OCDeletePdAclList(OicSecPdAcl_t* pPdAcl);\r
 \r
-#ifdef __WITH_X509__\r
+#if defined(__WITH_X509__) || defined(__WITH_TLS__)\r
 /**\r
  * this function sends CRL information to resource.\r
  *\r
@@ -306,7 +306,34 @@ void OCDeletePdAclList(OicSecPdAcl_t* pPdAcl);
  */\r
 OCStackResult OCProvisionCRL(void* ctx, const OCProvisionDev_t *selectedDeviceInfo, OicSecCrl_t *crl,\r
                              OCProvisionResultCB resultCallback);\r
-#endif // __WITH_X509__\r
+\r
+/**\r
+ * function to provision Trust certificate chain to devices.\r
+ *\r
+ * @param[in] ctx Application context would be returned in result callback.\r
+ * @param[in] type Type of credentials to be provisioned to the device.\r
+ * @param[in] credId CredId of trust certificate chain to be provisioned to the device.\r
+ * @param[in] selectedDeviceInfo Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.\r
+ * @param[in] resultCallback callback provided by API user, callback will be called when\r
+ *            provisioning request recieves a response from first resource server.\r
+ * @return  OC_STACK_OK in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCProvisionTrustCertChain(void *ctx, OicSecCredType_t type, uint16_t credId,\r
+                                      const OCProvisionDev_t *selectedDeviceInfo,\r
+                                      OCProvisionResultCB resultCallback);\r
+/**\r
+ * function to save Trust certificate chain into Cred of SVR.\r
+ *\r
+ * @param[in] trustCertChain Trust certificate chain to be saved in Cred of SVR.\r
+ * @param[in] chainSize Size of trust certificate chain to be saved in Cred of SVR\r
+ * @param[in] encodingType Encoding type of trust certificate chain to be saved in Cred of SVR\r
+ * @param[out] credId CredId of saved trust certificate chain in Cred of SVR.\r
+ * @return  OC_STACK_OK in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,\r
+                                        OicEncodingType_t encodingType, uint16_t *credId);\r
+\r
+#endif // __WITH_X509__ || __WITH_TLS__\r
 \r
 \r
 #ifdef __cplusplus\r
index 67f859a..be7b864 100755 (executable)
@@ -994,7 +994,7 @@ void OCDeletePdAclList(OicSecPdAcl_t* pPdAcl)
 }
 
 
-#ifdef __WITH_X509__
+#if defined(__WITH_X509__) || defined(__WITH_TLS__)
 /**
  * this function sends CRL information to resource.
  *
@@ -1010,5 +1010,40 @@ OCStackResult OCProvisionCRL(void* ctx, const OCProvisionDev_t *selectedDeviceIn
 {
     return SRPProvisionCRL(ctx, selectedDeviceInfo, crl, resultCallback);
 }
-#endif // __WITH_X509__
+
+/**
+ * function to provision Trust certificate chain to devices.
+ *
+ * @param[in] ctx Application context would be returned in result callback.
+ * @param[in] type Type of credentials to be provisioned to the device.
+ * @param[in] credId CredId of trust certificate chain to be provisioned to the device.
+ * @param[in] selectedDeviceInfo Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ *            provisioning request recieves a response from first resource server.
+ * @return  OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OCProvisionTrustCertChain(void *ctx, OicSecCredType_t type, uint16_t credId,
+                                      const OCProvisionDev_t *selectedDeviceInfo,
+                                      OCProvisionResultCB resultCallback)
+{
+    return SRPProvisionTrustCertChain(ctx, type, credId,
+                                      selectedDeviceInfo, resultCallback);
+}
+
+/**
+ * function to save Trust certificate chain into Cred of SVR.
+ *
+ * @param[in] trustCertChain Trust certificate chain to be saved in Cred of SVR.
+ * @param[in] chainSize Size of trust certificate chain to be saved in Cred of SVR
+ * @param[in] encodingType Encoding type of trust certificate chain to be saved in Cred of SVR
+ * @param[out] credId CredId of saved trust certificate chain in Cred of SVR.
+ * @return  OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OCSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
+                                    OicEncodingType_t encodingType, uint16_t *credId)
+{
+    return SRPSaveTrustCertChain(trustCertChain, chainSize, encodingType, credId);
+}
+
+#endif // __WITH_X509__ || __WITH_TLS__
 
index e75ea21..1d2891d 100644 (file)
@@ -359,7 +359,7 @@ static OCStackResult provisionCredentials(const OicSecCred_t *cred,
     return OC_STACK_OK;
 }
 
-#ifdef __WITH_X509__
+#if defined(__WITH_X509__) || defined(__WITH_TLS__)
 /**
  * Structure to carry certificate data to callback.
  */
@@ -641,7 +641,138 @@ static OCStackApplicationResult provisionCertCB(void *ctx, OCDoHandle UNUSED,
     OICFree(certData);
     return OC_STACK_DELETE_TRANSACTION;
 }
-#endif // __WITH_X509__
+
+OCStackResult SRPProvisionTrustCertChain(void *ctx, OicSecCredType_t type, uint16_t credId,
+        const OCProvisionDev_t *selectedDeviceInfo, OCProvisionResultCB resultCallback)
+{
+    OIC_LOG(INFO, TAG, "In SRPProvisionTrustCertChain");
+    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    if (SIGNED_ASYMMETRIC_KEY != type || NULL == type)
+    {
+        OIC_LOG(INFO, TAG, "Invalid key type");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OicSecCred_t *trustCertChainCred = GetCredResourceDataByCredId(credId);
+    if(NULL == trustCertChainCred)
+    {
+        OIC_LOG(ERROR, TAG, "Can not find matched Trust Cert. Chain.");
+        return OC_STACK_NO_RESOURCE;
+    }
+
+    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+    if(!secPayload)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
+        return OC_STACK_NO_MEMORY;
+    }
+    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+    int secureFlag = 0;
+    if(OC_STACK_OK != CredToCBORPayload(trustCertChainCred, &secPayload->securityData, &secPayload->payloadSize, secureFlag))
+    {
+        OCPayloadDestroy((OCPayload *)secPayload);
+        OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
+        return OC_STACK_NO_MEMORY;
+    }
+    OIC_LOG(DEBUG, TAG, "Created payload for Cred:");
+    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    if(!PMGenerateQuery(true,
+                        selectedDeviceInfo->endpoint.addr,
+                        selectedDeviceInfo->securePort,
+                        selectedDeviceInfo->connType,
+                        query, sizeof(query), OIC_RSRC_CRED_URI))
+    {
+        OIC_LOG(ERROR, TAG, "SRPProvisionTrustCertChain : Failed to generate query");
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
+    cbData.cb = &provisionCertCB;
+    CertData_t *certData = (CertData_t *) OICCalloc(1, sizeof(CertData_t));
+    if (NULL == certData)
+    {
+        OICFree(trustCertChainCred);
+        OIC_LOG(ERROR, TAG, "Memory allocation problem");
+        return OC_STACK_NO_MEMORY;
+    }
+    certData->deviceInfo = selectedDeviceInfo;
+    certData->resultCallback = resultCallback;
+    certData->credInfo = trustCertChainCred;
+    certData->numOfResults=0;
+    certData->ctx = ctx;
+
+    int noOfRiCalls = 1;
+    certData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
+    if (certData->resArr == NULL)
+    {
+        DeleteCredList(trustCertChainCred);
+        OICFree(certData);
+        OCPayloadDestroy((OCPayload *)secPayload);
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    cbData.context = (void *)certData;
+    cbData.cd = NULL;
+    OCMethod method = OC_REST_POST;
+    OCDoHandle handle = NULL;
+    OIC_LOG(DEBUG, TAG, "Sending Cred info to resource server");
+    OCStackResult ret = OCDoResource(&handle, method, query,
+            &selectedDeviceInfo->endpoint, (OCPayload*)secPayload,
+            selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    if (ret != OC_STACK_OK)
+    {
+        OICFree(certData->resArr);
+        OICFree(certData);
+    }
+    DeleteCredList(trustCertChainCred);
+
+    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    return OC_STACK_OK;
+}
+
+OCStackResult SRPSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
+                                            OicEncodingType_t encodingType, uint16_t *credId)
+{
+    OIC_LOG(DEBUG, TAG, "IN SRPSaveTrustCertChain");
+    VERIFY_NON_NULL(TAG, trustCertChain, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(TAG, credId, ERROR,  OC_STACK_INVALID_PARAM);
+
+    OCStackResult res = OC_STACK_ERROR;
+
+    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
+    VERIFY_NON_NULL(TAG, cred, ERROR, OC_STACK_NO_MEMORY);
+
+    memcpy(cred->subject.id, &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN);
+
+    cred->credUsage= (char *)OICCalloc(1, strlen(TRUST_CA)+1 );
+    VERIFY_NON_NULL(TAG, cred->credUsage, ERROR, OC_STACK_NO_MEMORY);
+    OICStrcpy(cred->credUsage, strlen(TRUST_CA) + 1, TRUST_CA) ;
+
+    cred->credType = SIGNED_ASYMMETRIC_KEY;
+
+    cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
+    VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR, OC_STACK_NO_MEMORY);
+    memcpy(cred->optionalData.data, trustCertChain, chainSize);
+    cred->optionalData.len = chainSize;
+    cred->optionalData.encoding = encodingType;
+
+    res = AddCredential(cred);
+    if(res != OC_STACK_OK)
+    {
+        DeleteCredList(cred);
+        return res;
+    }
+    *credId = cred->credId;
+
+    OIC_LOG(DEBUG, TAG, "OUT SRPSaveTrustCertChain");
+
+    return res;
+}
+#endif // __WITH_X509__ || __WITH_TLS__
 
 OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t keySize,
                                       const OCProvisionDev_t *pDev1,
index 3fdc187..b1867a7 100644 (file)
@@ -86,10 +86,14 @@ static void FreeCred(OicSecCred_t *cred)
     OICFree(cred->roleIds);
 #endif
 
-    //Clean PublicData
-#if defined(__WITH_X509__) || defined(WITH_TLS) 
+    //Clean PublicData/OptionalData/Credusage
+#if defined(__WITH_X509__) || defined(__WITH_TLS__)
+     // TODO: Need to check credUsage.
     OICFree(cred->publicData.data);
-#endif
+    OICFree(cred->optionalData.data);
+    OICFree(cred->credUsage);
+
+#endif /* __WITH_X509__ ||  __WITH_TLS__*/
 
     //Clean PrivateData
     OICFree(cred->privateData.data);
@@ -170,17 +174,25 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
     {
         CborEncoder credMap;
         size_t mapSize = CRED_MAP_SIZE;
-        char *subject = NULL;
+        size_t inLen = 0;
         if (cred->period)
         {
             mapSize++;
         }
-#ifdef __WITH_X509__
+#if defined(__WITH_X509__) || defined(__WITH_TLS__)
         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
         {
             mapSize++;
         }
-#endif /* __WITH_X509__ */
+        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
+        {
+            mapSize++;
+        }
+        if (cred->credUsage)
+        {
+            mapSize++;
+        }
+#endif /* __WITH_X509__ ||  __WITH_TLS__*/
         if (!secureFlag && cred->privateData.data)
         {
             mapSize++;
@@ -199,11 +211,23 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
             strlen(OIC_JSON_SUBJECTID_NAME));
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
-        ret = ConvertUuidToStr(&cred->subject, &subject);
-        VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
-        cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
-        OICFree(subject);
+        inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN) == 0) ?
+            WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
+        if(inLen == WILDCARD_SUBJECT_ID_LEN)
+        {
+            cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
+                strlen(WILDCARD_RESOURCE_URI));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
+        }
+        else
+        {
+            char *subject = NULL;
+            ret = ConvertUuidToStr(&cred->subject, &subject);
+            VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+            cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
+            OICFree(subject);
+        }
 
         //CredType -- Mandatory
         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
@@ -212,7 +236,7 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
 
-#ifdef __WITH_X509__
+#if defined(__WITH_X509__) || defined(__WITH_TLS__)
         //PublicData -- Not Mandatory
         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
         {
@@ -244,7 +268,104 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
             cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
         }
-#endif /*__WITH_X509__*/
+        //OptionalData -- Not Mandatory
+        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
+        {
+            CborEncoder optionalMap;
+            const size_t optionalMapSize = 2;
+
+            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_OPTDATA_NAME,
+                strlen(OIC_JSON_OPTDATA_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
+
+            cborEncoderResult = cbor_encoder_create_map(&credMap, &optionalMap, optionalMapSize);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Map");
+
+            // TODO: Need to data strucure modification for OicSecCert_t.
+            if(OIC_ENCODING_RAW == cred->optionalData.encoding)
+            {
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
+                    strlen(OIC_JSON_ENCODING_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_RAW,
+                    strlen(OIC_SEC_ENCODING_RAW));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
+
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
+                    strlen(OIC_JSON_DATA_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
+                cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
+                    cred->optionalData.len);
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
+            }
+            else if(OIC_ENCODING_BASE64 == cred->optionalData.encoding)
+            {
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
+                    strlen(OIC_JSON_ENCODING_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_BASE64,
+                    strlen(OIC_SEC_ENCODING_BASE64));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
+
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
+                    strlen(OIC_JSON_DATA_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
+                    cred->optionalData.len);
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
+            }
+            else if(OIC_ENCODING_PEM == cred->optionalData.encoding)
+            {
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
+                    strlen(OIC_JSON_ENCODING_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_PEM,
+                    strlen(OIC_SEC_ENCODING_PEM));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
+
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
+                    strlen(OIC_JSON_DATA_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
+                    cred->optionalData.len);
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
+            }
+            else if(OIC_ENCODING_DER == cred->optionalData.encoding)
+            {
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
+                    strlen(OIC_JSON_ENCODING_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_DER,
+                    strlen(OIC_SEC_ENCODING_DER));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
+
+                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
+                    strlen(OIC_JSON_DATA_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
+                cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
+                    cred->optionalData.len);
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
+            }
+            else
+            {
+                OIC_LOG(ERROR, TAG, "Unknow encoding type for optional data.");
+                VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding optional Encoding Value.");
+            }
+
+            cborEncoderResult = cbor_encoder_close_container(&credMap, &optionalMap);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing OptionalData Map.");
+        }
+        //CredUsage -- Not Mandatory
+        if(cred->credUsage)
+        {
+            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
+                strlen(OIC_JSON_CREDUSAGE_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
+            cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
+                strlen(cred->credUsage));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
+        }
+#endif /* __WITH_X509__ ||  __WITH_TLS__*/
         //PrivateData -- Not Mandatory
         if(!secureFlag && cred->privateData.data)
         {
@@ -505,8 +626,15 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                 char *subjectid = NULL;
                                 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
-                                ret = ConvertStrToUuid(subjectid, &cred->subject);
-                                VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+                                if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
+                                {
+                                    cred->subject.id[0] = '*';
+                                }
+                                else
+                                {
+                                    ret = ConvertStrToUuid(subjectid, &cred->subject);
+                                    VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+                                }
                                 OICFree(subjectid);
                             }
                             // credtype
@@ -593,7 +721,8 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                 }
 
                             }
-#ifdef __WITH_X509__
+#if defined(__WITH_X509__) || defined(__WITH_TLS__)
+                            //PublicData -- Not Mandatory
                             if (strcmp(name, OIC_JSON_PUBLICDATA_NAME)  == 0)
                             {
                                 CborValue pubMap = { .parser = NULL };
@@ -634,7 +763,95 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                     OICFree(pubname);
                                 }
                             }
-#endif  //__WITH_X509__
+                            //OptionalData -- Not Mandatory
+                            if (strcmp(name, OIC_JSON_OPTDATA_NAME)  == 0)
+                            {
+                                CborValue optMap = { .parser = NULL };
+                                cborFindResult = cbor_value_enter_container(&credMap, &optMap);
+
+                                while (cbor_value_is_valid(&optMap))
+                                {
+                                    char* optname = NULL;
+                                    CborType type = cbor_value_get_type(&optMap);
+                                    if (type == CborTextStringType && cbor_value_is_text_string(&optMap))
+                                    {
+                                        cborFindResult = cbor_value_dup_text_string(&optMap, &optname,
+                                                &len, NULL);
+                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+                                        cborFindResult = cbor_value_advance(&optMap);
+                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+                                    }
+                                    if (optname)
+                                    {
+                                        // OptionalData::optdata -- Mandatory
+                                        if (strcmp(optname, OIC_JSON_DATA_NAME) == 0)
+                                        {
+                                            if(cbor_value_is_byte_string(&optMap))
+                                            {
+                                                cborFindResult = cbor_value_dup_byte_string(&optMap, &cred->optionalData.data,
+                                                    &cred->optionalData.len, NULL);
+                                            }
+                                            else if(cbor_value_is_text_string(&optMap))
+                                            {
+                                                cborFindResult = cbor_value_dup_text_string(&optMap, (char**)(&cred->optionalData.data),
+                                                    &cred->optionalData.len, NULL);
+                                            }
+                                            else
+                                            {
+                                                cborFindResult = CborErrorUnknownType;
+                                                OIC_LOG(ERROR, TAG, "Unknow type for optional data.");
+                                            }
+                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OptionalData.");
+                                        }
+                                        // OptionalData::encoding -- Mandatory
+                                        if (strcmp(optname, OIC_JSON_ENCODING_NAME) == 0)
+                                        {
+                                            // TODO: Added as workaround. Will be replaced soon.
+                                            char* strEncoding = NULL;
+                                            cborFindResult = cbor_value_dup_text_string(&optMap, &strEncoding, &len, NULL);
+                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
+
+                                            if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
+                                            {
+                                                OIC_LOG(INFO,TAG,"cbor_value_is_byte_string");
+                                                cred->optionalData.encoding = OIC_ENCODING_RAW;
+                                            }
+                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
+                                            {
+                                                cred->optionalData.encoding = OIC_ENCODING_BASE64;
+                                            }
+                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
+                                            {
+                                                cred->optionalData.encoding = OIC_ENCODING_PEM;
+                                            }
+                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
+                                            {
+                                                cred->optionalData.encoding = OIC_ENCODING_DER;
+                                            }
+                                            else
+                                            {
+                                                //For unit test
+                                                cred->optionalData.encoding = OIC_ENCODING_RAW;
+                                                OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for optional data.");
+                                            }
+                                            OICFree(strEncoding);
+                                        }
+                                    }
+                                    if (cbor_value_is_valid(&optMap))
+                                    {
+                                        cborFindResult = cbor_value_advance(&optMap);
+                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing optdata Map.");
+                                    }
+                                    OICFree(optname);
+                                }
+                            }
+                            //Credusage -- Not Mandatory
+                            if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
+                            {
+                                cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
+                            }
+#endif  //__WITH_X509__ ||  __WITH_TLS__
 
                             if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
                             {
@@ -1366,6 +1583,24 @@ OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
     return NULL;
 }
 
+OicSecCred_t* GetCredResourceDataByCredId(const uint16_t credId)
+{
+    OicSecCred_t *cred = NULL;
+
+   if ( 1 > credId)
+    {
+       return NULL;
+    }
+
+    LL_FOREACH(gCred, cred)
+    {
+        if(cred->credId == credId)
+        {
+            return cred;
+        }
+    }
+    return NULL;
+}
 
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
index d9f0210..c05e529 100644 (file)
@@ -115,7 +115,8 @@ const char * OIC_JSON_PUBLICDATA_NAME = "publicdata";
 const char * OIC_JSON_PRIVATEDATA_NAME = "privatedata";
 const char * OIC_JSON_PUBDATA_NAME = "pubdata";
 const char * OIC_JSON_PRIVDATA_NAME = "privdata";
-const char * OIC_JSON_OPTDATA_NAME = "optdata";
+const char * OIC_JSON_OPTDATA_NAME = "optionaldata";
+const char * OIC_JSON_CREDUSAGE_NAME = "credusage";
 const char * OIC_JSON_SERVICE_DEVICE_ID = "svcdid";
 const char * OIC_JSON_SERVICE_TYPE = "svct";
 const char* OIC_JSON_VALIDITY_NAME = "validity";
@@ -145,6 +146,8 @@ const char * OIC_JSON_SEC_V_NAME = "secv";
 
 const char * OIC_JSON_EMPTY_STRING = "";
 
+const char * TRUST_CA = "trust_ca";
+
 OicUuid_t WILDCARD_SUBJECT_ID = {"*"};
 OicUuid_t WILDCARD_SUBJECT_B64_ID = { .id = {'2', '2', '2', '2', '2', '2', '2', '2',
                                              '2', '2', '2', '2', '2', '2', '2', '2' }};
@@ -159,6 +162,8 @@ const char * OXM_MANUFACTURER_CERTIFICATE = "oic.sec.doxm.mfgcert";
 //Credential data encoding methods
 const char * OIC_SEC_ENCODING_BASE64 = "oic.sec.encoding.base64";
 const char * OIC_SEC_ENCODING_RAW = "oic.sec.encoding.raw";
+const char * OIC_SEC_ENCODING_PEM = "oic.sec.encoding.pem";
+const char * OIC_SEC_ENCODING_DER = "oic.sec.encoding.der";
 
 const char * OIC_SEC_TRUE = "true";
 const char * OIC_SEC_FALSE = "false";