From 93ae21a48423e4448e63262ab1b48d08779bc59f Mon Sep 17 00:00:00 2001 From: Chul Lee Date: Thu, 16 Jun 2016 13:56:33 +0900 Subject: [PATCH] Hoxfix to support the base64 encoded credential. This patch for the test w/ CTT to support base64 encoded private data as workround. Also this changes will be replaced when I upload SVR data structure modification. [Patch #1~#3] : Intial upload [Patch #4] : Remove the compile errors for arduino Change-Id: Iaddd6068e15e316cfc8cea1c7acda8e89f8fc9b0 Signed-off-by: Chul Lee Reviewed-on: https://gerrit.iotivity.org/gerrit/8687 Tested-by: jenkins-iotivity Reviewed-by: Jongsung Lee Reviewed-by: Randeep Singh --- .../security/include/securevirtualresourcetypes.h | 11 ++ .../provisioning/src/ownershiptransfermanager.c | 24 ++- resource/csdk/security/src/credresource.c | 181 ++++++++++++++++++--- .../csdk/security/unittest/credentialresource.cpp | 2 + 4 files changed, 194 insertions(+), 24 deletions(-) diff --git a/resource/csdk/security/include/securevirtualresourcetypes.h b/resource/csdk/security/include/securevirtualresourcetypes.h index 786658e..d7d4888 100644 --- a/resource/csdk/security/include/securevirtualresourcetypes.h +++ b/resource/csdk/security/include/securevirtualresourcetypes.h @@ -261,6 +261,13 @@ typedef enum OIC_OXM_COUNT }OicSecOxm_t; +typedef enum +{ + OIC_ENCODING_UNKNOW = 0, + OIC_ENCODING_RAW = 1, + OIC_ENCODING_BASE64 = 2 +}OicEncodingType_t; + typedef struct OicSecKey OicSecKey_t; typedef struct OicSecPstat OicSecPstat_t; @@ -308,6 +315,10 @@ struct OicSecKey { uint8_t *data; size_t len; + + // TODO: This field added as workaround. Will be replaced soon. + OicEncodingType_t encoding; + }; /** diff --git a/resource/csdk/security/provisioning/src/ownershiptransfermanager.c b/resource/csdk/security/provisioning/src/ownershiptransfermanager.c index e057b7e..d17bcf9 100644 --- a/resource/csdk/security/provisioning/src/ownershiptransfermanager.c +++ b/resource/csdk/security/provisioning/src/ownershiptransfermanager.c @@ -419,6 +419,27 @@ static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo) &ownerKey, &ptDeviceID); VERIFY_NON_NULL(TAG, cred, ERROR); + // TODO: Added as workaround. Will be replaced soon. + cred->privateData.encoding = OIC_ENCODING_RAW; + +#if 1 + // NOTE: Test codes to use BASE64 encoded owner PSK. + uint32_t outSize = 0; + size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1)); + char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize); + VERIFY_NON_NULL(TAG, b64Buf, ERROR); + b64Encode(cred->privateData.data, cred->privateData.len, b64Buf, b64BufSize, &outSize); + + OICFree( cred->privateData.data ); + cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1); + VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); + + strcpy(cred->privateData.data, b64Buf); + cred->privateData.encoding = OIC_ENCODING_BASE64; + cred->privateData.len = outSize; + OICFree(b64Buf); +#endif //End of Test codes + res = AddCredential(cred); if(res != OC_STACK_OK) { @@ -953,8 +974,9 @@ static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx) memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t)); //Fill private data as empty string - newCredential.privateData.data = NULL; + newCredential.privateData.data = ""; newCredential.privateData.len = 0; + newCredential.privateData.encoding = ownerCredential->privateData.encoding; #ifdef __WITH_X509__ newCredential.publicData.data = NULL; newCredential.publicData.len = 0; diff --git a/resource/csdk/security/src/credresource.c b/resource/csdk/security/src/credresource.c index 5b24d66..69bb539 100644 --- a/resource/csdk/security/src/credresource.c +++ b/resource/csdk/security/src/credresource.c @@ -257,20 +257,45 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map"); - cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME, - strlen(OIC_JSON_DATA_NAME)); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag."); - cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data, - cred->privateData.len); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value."); - // TODO: Need to data strucure modification for OicSecKey_t. - cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME, - strlen(OIC_JSON_ENCODING_NAME)); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag."); - cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW, - strlen(OIC_SEC_ENCODING_RAW)); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value."); + // TODO: Added as workaround, will be replaced soon. + if(OIC_ENCODING_RAW == cred->privateData.encoding) + { + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME, + strlen(OIC_JSON_ENCODING_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag."); + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW, + strlen(OIC_SEC_ENCODING_RAW)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value."); + + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME, + strlen(OIC_JSON_DATA_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag."); + cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data, + cred->privateData.len); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value."); + } + else if(OIC_ENCODING_BASE64 == cred->privateData.encoding) + { + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME, + strlen(OIC_JSON_ENCODING_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag."); + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64, + strlen(OIC_SEC_ENCODING_BASE64)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value."); + + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME, + strlen(OIC_JSON_DATA_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag."); + cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data), + cred->privateData.len); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value."); + } + else + { + OIC_LOG(ERROR, TAG, "Unknow encoding type for private data."); + VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value."); + } cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map."); @@ -477,14 +502,48 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size, // PrivateData::privdata -- Mandatory if (strcmp(privname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&privateMap)) { - cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data, - &cred->privateData.len, NULL); + if(cbor_value_is_byte_string(&privateMap)) + { + cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data, + &cred->privateData.len, NULL); + } + else if(cbor_value_is_text_string(&privateMap)) + { + cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data), + &cred->privateData.len, NULL); + } + else + { + cborFindResult = CborErrorUnknownType; + OIC_LOG(ERROR, TAG, "Unknow type for private data."); + } VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData."); } + // PrivateData::encoding -- Mandatory if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0) { - // TODO: Need to update data structure, just ignore encoding value now. + // TODO: Added as workaround. Will be replaced soon. + char* strEncoding = NULL; + cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType"); + + if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0) + { + cred->privateData.encoding = OIC_ENCODING_RAW; + } + else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0) + { + cred->privateData.encoding = OIC_ENCODING_BASE64; + } + else + { + //For unit test + cred->privateData.encoding = OIC_ENCODING_RAW; + OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data."); + } + + OICFree(strEncoding); } } if (cbor_value_is_valid(&privateMap)) @@ -634,6 +693,28 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); memcpy(cred->privateData.data, privateData->data, privateData->len); cred->privateData.len = privateData->len; + + // TODO: Added as workaround. Will be replaced soon. + cred->privateData.encoding = OIC_ENCODING_RAW; + +#if 0 + // NOTE: Test codes to use base64 for credential. + uint32_t outSize = 0; + size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1)); + char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize); + VERIFY_NON_NULL(TAG, b64Buf, ERROR); + b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize); + + OICFree( cred->privateData.data ); + cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1); + VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); + + strcpy(cred->privateData.data, b64Buf); + cred->privateData.encoding = OIC_ENCODING_BASE64; + cred->privateData.len = outSize; + OICFree(b64Buf); +#endif //End of Test codes + } VERIFY_NON_NULL(TAG, rownerID, ERROR); @@ -848,10 +929,34 @@ static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoi OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128); //Generate owner credential based on recevied credential information - receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128); - VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR); - receviedCred->privateData.len = OWNER_PSK_LENGTH_128; - memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128); + + // TODO: Added as workaround, will be replaced soon. + if(OIC_ENCODING_RAW == receviedCred->privateData.encoding) + { + receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128); + VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR); + receviedCred->privateData.len = OWNER_PSK_LENGTH_128; + memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128); + } + else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding) + { + uint32_t b64OutSize = 0; + size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1)); + char* b64Buf = OICCalloc(1, b64BufSize); + VERIFY_NON_NULL(TAG, b64Buf, ERROR); + + b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize); + + receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1); + VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR); + receviedCred->privateData.len = b64OutSize; + strcpy((char*)receviedCred->privateData.data, b64Buf); + } + else + { + // TODO: error + VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR); + } OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully"); @@ -874,6 +979,7 @@ static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehR OicSecCred_t *cred = NULL; uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData); size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize); + OCStackResult res = CBORPayloadToCred(payload, size, &cred); if (res == OC_STACK_OK) { @@ -1282,8 +1388,37 @@ int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type, } // Copy PSK. - result_length = cred->privateData.len; - memcpy(result, cred->privateData.data, result_length); + // TODO: Added as workaround. Will be replaced soon. + if(OIC_ENCODING_RAW == cred->privateData.encoding) + { + result_length = cred->privateData.len; + memcpy(result, cred->privateData.data, result_length); + } + else if(OIC_ENCODING_BASE64 == cred->privateData.encoding) + { + size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1)); + uint8_t* outKey = OICCalloc(1, outBufSize); + uint32_t outKeySize; + if(NULL == outKey) + { + result_length = -1; + OIC_LOG (ERROR, TAG, "Failed to memoray allocation."); + } + + if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize)) + { + memcpy(result, outKey, outKeySize); + result_length = outKeySize; + } + else + { + result_length = -1; + OIC_LOG (ERROR, TAG, "Failed to base64 decoding."); + } + + OICFree(outKey); + } + return result_length; } } @@ -1326,7 +1461,7 @@ OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t cre } uint8_t privData[OWNER_PSK_LENGTH_128] = {0,}; - OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128}; + OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW}; OicSecCred_t* cred = NULL; int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id, UUID_LENGTH, PBKDF_ITERATIONS, diff --git a/resource/csdk/security/unittest/credentialresource.cpp b/resource/csdk/security/unittest/credentialresource.cpp index 02c209f..530d342 100644 --- a/resource/csdk/security/unittest/credentialresource.cpp +++ b/resource/csdk/security/unittest/credentialresource.cpp @@ -52,6 +52,7 @@ OicSecCred_t * getCredList() #endif cred->credType = SYMMETRIC_PAIR_WISE_KEY; + cred->privateData.encoding = OIC_ENCODING_RAW; cred->privateData.data = (uint8_t *)OICCalloc(1, strlen("My private Key11") + 1); VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); OICStrcpy((char *)cred->privateData.data, strlen("My private Key11")+1,"My private Key11"); @@ -66,6 +67,7 @@ OicSecCred_t * getCredList() cred->next->roleIdsLen = 0; #endif cred->next->credType = SYMMETRIC_PAIR_WISE_KEY; + cred->next->privateData.encoding = OIC_ENCODING_RAW; sz = strlen("My private Key21") + 1; cred->next->privateData.data = (uint8_t *)OICCalloc(1, sz); VERIFY_NON_NULL(TAG, cred->next->privateData.data, ERROR); -- 2.7.4