1 /* *****************************************************************
3 * Copyright 2016 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * *****************************************************************/
24 #include "experimental/securevirtualresourcetypes.h"
25 #include "doxmresource.h"
26 #include "credresource.h"
28 #include "cainterface.h"
30 #include "oic_malloc.h"
31 #include "oic_string.h"
35 #include "oxmpreconfpin.h"
36 #include "ownershiptransfermanager.h"
37 #include "pinoxmcommon.h"
38 #include "srmresourcestrings.h"
39 #include "ocstackinternal.h"
40 #include "mbedtls/ssl_ciphersuites.h"
42 #define TAG "OIC_OXM_PreconfigPIN"
44 OCStackResult CreatePreconfigPinBasedSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **payload, size_t *size)
46 if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
48 return OC_STACK_INVALID_PARAM;
51 otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_PRECONFIG_PIN;
53 bool propertiesToInclude[DOXM_PROPERTY_COUNT];
54 memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
55 propertiesToInclude[DOXM_OXMSEL] = true;
57 return DoxmToCBORPayloadPartial(otmCtx->selectedDeviceInfo->doxm, payload, size, propertiesToInclude);
60 OCStackResult CreatePreconfigPinBasedOwnerTransferPayload(OTMContext_t *otmCtx, uint8_t **payload, size_t *size)
62 if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
64 return OC_STACK_INVALID_PARAM;
67 OicUuid_t uuidPT = {.id={0}};
71 if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
73 OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
74 return OC_STACK_ERROR;
76 memcpy(otmCtx->selectedDeviceInfo->doxm->owner.id, uuidPT.id , UUID_LENGTH);
78 bool propertiesToInclude[DOXM_PROPERTY_COUNT];
79 memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
80 propertiesToInclude[DOXM_DEVOWNERUUID] = true;
82 return DoxmToCBORPayloadPartial(otmCtx->selectedDeviceInfo->doxm, payload, size, propertiesToInclude);
85 OCStackResult LoadPreconfigPinCodeCallback(OTMContext_t *otmCtx)
87 OIC_LOG(INFO, TAG, "IN LoadPreconfigPinCodeCallback");
88 OCStackResult res = OC_STACK_ERROR;
89 OicSecCred_t* cred = GetCredResourceData(&otmCtx->selectedDeviceInfo->doxm->deviceID);
92 OicUuid_t uuid = {.id={0}};
93 memcpy(&uuid, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t));
94 cred = GetCredResourceData(&uuid);
97 OIC_LOG(ERROR, TAG, "Can not find the Credential for MOT");
98 OIC_LOG(ERROR, TAG, "Please make sure the preconfigured PIN");
99 return OC_STACK_ERROR;
103 uint8_t* pinBuffer = NULL;
104 size_t pinBufLen = 0;
105 if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
107 //In case of 'preconfig PIN', secret data(PIN) already exist.
108 pinBufLen = B64DECODE_OUT_SAFESIZE(cred->privateData.len + 1);
109 pinBuffer = (uint8_t*)OICCalloc(1, pinBufLen);
110 if(NULL == pinBuffer)
112 OIC_LOG(ERROR, TAG, "Failed to memory allocation.");
113 return OC_STACK_NO_MEMORY;
116 if(B64_OK != b64Decode((char*)cred->privateData.data, cred->privateData.len, pinBuffer, pinBufLen, &pinLen))
118 OIC_LOG(ERROR, TAG, "Failed to base64 deconding for preconfig PIN");
120 return OC_STACK_ERROR;
124 else if(OIC_ENCODING_RAW == cred->privateData.encoding)
126 pinBuffer = (uint8_t*)OICMalloc(cred->privateData.len + 1);
127 if(NULL == pinBuffer)
129 OIC_LOG(ERROR, TAG, "Failed to memory allocation.");
130 return OC_STACK_NO_MEMORY;
132 memcpy(pinBuffer, cred->privateData.data, cred->privateData.len);
133 pinBuffer[cred->privateData.len] = '\0';
134 pinBufLen = cred->privateData.len;
138 OIC_LOG(ERROR, TAG, "Unknown encoding type for PreConfigured PIN credential");
139 return OC_STACK_ERROR;
142 res = SetPreconfigPin((char*)pinBuffer, pinBufLen);
144 if(OC_STACK_OK != res)
146 OIC_LOG_V(ERROR, TAG, "Failed to save the preconfig PIN : %d", res);
151 if(false == otmCtx->selectedDeviceInfo->doxm->owned)
153 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForPreconfPinOxm))
155 OIC_LOG(ERROR, TAG, "Failed to register DTLS credentials handler for random PIN OxM.");
156 res = OC_STACK_ERROR;
159 #ifdef MULTIPLE_OWNER
161 else if(true == otmCtx->selectedDeviceInfo->doxm->owned &&
162 otmCtx->selectedDeviceInfo->doxm->mom &&
163 OIC_MULTIPLE_OWNER_DISABLE != otmCtx->selectedDeviceInfo->doxm->mom->mode)
165 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForMotPreconfPinOxm))
167 OIC_LOG(ERROR, TAG, "Failed to register DTLS credentials handler for random PIN OxM.");
168 res = OC_STACK_ERROR;
171 #endif //MULTIPLE_OWNER
173 //Set the device id to derive temporal PSK
174 SetUuidForPinBasedOxm(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
176 OIC_LOG(INFO, TAG, "OUT LoadPreconfigPinCodeCallback");
181 OCStackResult CreateSecureSessionPreconfigPinCallback(OTMContext_t* otmCtx)
183 OIC_LOG(INFO, TAG, "IN CreateSecureSessionPreconfigPinCallback");
185 if (!otmCtx || !otmCtx->selectedDeviceInfo)
187 return OC_STACK_INVALID_PARAM;
190 CAResult_t caresult = CAEnableAnonECDHCipherSuite(false);
191 if (CA_STATUS_OK != caresult)
193 OIC_LOG_V(ERROR, TAG, "Unable to disable anon cipher suite");
194 return OC_STACK_ERROR;
196 OIC_LOG(INFO, TAG, "Anonymous cipher suite disabled.");
198 caresult = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, otmCtx->selectedDeviceInfo->endpoint.adapter);
199 if (CA_STATUS_OK != caresult)
201 OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
202 return OC_STACK_ERROR;
204 OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 cipher suite selected.");
206 CAEndpoint_t endpoint;
207 OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
208 CopyDevAddrToEndpoint(&selDevInfo->endpoint, &endpoint);
210 if (CA_ADAPTER_IP == endpoint.adapter)
212 endpoint.port = selDevInfo->securePort;
215 else if (CA_ADAPTER_TCP == endpoint.adapter)
217 endpoint.port = selDevInfo->tcpSecurePort;
221 caresult = CAInitiateHandshake(&endpoint);
222 if (CA_STATUS_OK != caresult)
224 OIC_LOG_V(ERROR, TAG, "DTLS handshake failure.");
225 return OC_STACK_ERROR;
228 OIC_LOG(INFO, TAG, "OUT CreateSecureSessionPreconfigPinCallback");