[IOT-1469] Fix MOT build issues for Windows
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / oxmpreconfpin.c
1 /* *****************************************************************
2  *
3  * Copyright 2016 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  * *****************************************************************/
20
21 #include <memory.h>
22
23 #include "ocstack.h"
24 #include "securevirtualresourcetypes.h"
25 #include "doxmresource.h"
26 #include "credresource.h"
27 #include "cacommon.h"
28 #include "cainterface.h"
29 #include "ocrandom.h"
30 #include "oic_malloc.h"
31 #include "logger.h"
32 #include "pbkdf2.h"
33 #include "global.h"
34 #include "base64.h"
35 #include "oxmpreconfpin.h"
36 #include "ownershiptransfermanager.h"
37 #include "pinoxmcommon.h"
38 #include "srmresourcestrings.h"
39
40 #define TAG "OXM_PreconfigPIN"
41
42 OCStackResult CreatePreconfigPinBasedSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **payload, size_t *size)
43 {
44     if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
45     {
46         return OC_STACK_INVALID_PARAM;
47     }
48
49     otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_PRECONFIG_PIN;
50
51     return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
52 }
53
54 OCStackResult CreatePreconfigPinBasedOwnerTransferPayload(OTMContext_t *otmCtx, uint8_t **payload, size_t *size)
55 {
56     if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
57     {
58         return OC_STACK_INVALID_PARAM;
59     }
60
61     OicUuid_t uuidPT = {.id={0}};
62     *payload = NULL;
63     *size = 0;
64
65     if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
66     {
67         OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
68         return OC_STACK_ERROR;
69     }
70     memcpy(otmCtx->selectedDeviceInfo->doxm->owner.id, uuidPT.id , UUID_LENGTH);
71
72     return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
73 }
74
75 OCStackResult LoadPreconfigPinCodeCallback(OTMContext_t *otmCtx)
76 {
77     OIC_LOG(INFO, TAG, "IN LoadPreconfigPinCodeCallback");
78     OCStackResult res = OC_STACK_ERROR;
79     OicSecCred_t* cred = GetCredResourceData(&otmCtx->selectedDeviceInfo->doxm->deviceID);
80     if(NULL == cred)
81     {
82         OicUuid_t uuid = {.id={0}};
83         OICStrcpy(uuid.id, sizeof(uuid.id), WILDCARD_SUBJECT_ID.id);
84         cred = GetCredResourceData(&uuid);
85         if(NULL == cred)
86         {
87             OIC_LOG(ERROR, TAG, "Can not find the Credential for MOT");
88             OIC_LOG(ERROR, TAG, "Please make sure the preconfigured PIN");
89             return OC_STACK_ERROR;
90         }
91     }
92
93     uint8_t* pinBuffer = NULL;
94     size_t pinBufLen = 0;
95     if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
96     {
97         //In case of 'preconfig PIN', secret data(PIN) already exist.
98         pinBufLen = B64DECODE_OUT_SAFESIZE(cred->privateData.len + 1);
99         pinBuffer = (uint8_t*)OICCalloc(1, pinBufLen);
100         if(NULL == pinBuffer)
101         {
102             OIC_LOG(ERROR, TAG, "Failed to memory allocation.");
103             return OC_STACK_NO_MEMORY;
104         }
105         uint32_t pinLen = 0;
106         if(B64_OK != b64Decode(cred->privateData.data, cred->privateData.len, pinBuffer, pinBufLen, &pinLen))
107         {
108             OIC_LOG(ERROR, TAG, "Failed to base64 deconding for preconfig PIN");
109             OICFree(pinBuffer);
110             return OC_STACK_ERROR;
111         }
112         pinBufLen = pinLen;
113     }
114     else if(OIC_ENCODING_RAW == cred->privateData.encoding)
115     {
116         pinBuffer = (uint8_t*)OICMalloc(cred->privateData.len + 1);
117         if(NULL == pinBuffer)
118         {
119             OIC_LOG(ERROR, TAG, "Failed to memory allocation.");
120             return OC_STACK_NO_MEMORY;
121         }
122         memcpy(pinBuffer, cred->privateData.data, cred->privateData.len);
123         pinBuffer[cred->privateData.len] = '\0';
124         pinBufLen = cred->privateData.len;
125     }
126     else
127     {
128         OIC_LOG(ERROR, TAG, "Unknown encoding type for PreConfigured PIN credential");
129         return OC_STACK_ERROR;
130     }
131
132     res = SetPreconfigPin((char*)pinBuffer, pinBufLen);
133     OICFree(pinBuffer);
134     if(OC_STACK_OK != res)
135     {
136         OIC_LOG_V(ERROR, TAG, "Failed to save the preconfig PIN : %d", res);
137         return res;
138     }
139
140     //in case of OTM
141     if(false == otmCtx->selectedDeviceInfo->doxm->owned)
142     {
143         if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForPreconfPinOxm))
144         {
145             OIC_LOG(ERROR, TAG, "Failed to register DTLS credentials handler for random PIN OxM.");
146             res = OC_STACK_ERROR;
147         }
148     }
149 #ifdef _ENABLE_MULTIPLE_OWNER_
150     //in case of MOT
151     else if(true == otmCtx->selectedDeviceInfo->doxm->owned &&
152             otmCtx->selectedDeviceInfo->doxm->mom &&
153             OIC_MULTIPLE_OWNER_DISABLE != otmCtx->selectedDeviceInfo->doxm->mom->mode)
154     {
155         if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForMotPreconfPinOxm))
156         {
157             OIC_LOG(ERROR, TAG, "Failed to register DTLS credentials handler for random PIN OxM.");
158             res = OC_STACK_ERROR;
159         }
160     }
161 #endif //_ENABLE_MULTIPLE_OWNER_
162
163     //Set the device id to derive temporal PSK
164     SetUuidForPinBasedOxm(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
165
166     OIC_LOG(INFO, TAG, "OUT LoadPreconfigPinCodeCallback");
167
168     return res;
169 }
170
171 OCStackResult CreateSecureSessionPreconfigPinCallback(OTMContext_t* otmCtx)
172 {
173     OIC_LOG(INFO, TAG, "IN CreateSecureSessionPreconfigPinCallback");
174
175     if (!otmCtx || !otmCtx->selectedDeviceInfo)
176     {
177         return OC_STACK_INVALID_PARAM;
178     }
179
180     CAResult_t caresult = CAEnableAnonECDHCipherSuite(false);
181     if (CA_STATUS_OK != caresult)
182     {
183         OIC_LOG_V(ERROR, TAG, "Unable to disable anon cipher suite");
184         return OC_STACK_ERROR;
185     }
186     OIC_LOG(INFO, TAG, "Anonymous cipher suite disabled.");
187
188     caresult  = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, otmCtx->selectedDeviceInfo->endpoint.adapter);
189     if (CA_STATUS_OK != caresult)
190     {
191         OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");
192         return OC_STACK_ERROR;
193     }
194     OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 cipher suite selected.");
195
196     OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
197     CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
198     if (NULL == endpoint)
199     {
200         return OC_STACK_NO_MEMORY;
201     }
202     memcpy(endpoint,&selDevInfo->endpoint,sizeof(CAEndpoint_t));
203     endpoint->port = selDevInfo->securePort;
204     caresult = CAInitiateHandshake(endpoint);
205     OICFree(endpoint);
206     if (CA_STATUS_OK != caresult)
207     {
208         OIC_LOG_V(ERROR, TAG, "DTLS handshake failure.");
209         return OC_STACK_ERROR;
210     }
211
212     OIC_LOG(INFO, TAG, "OUT CreateSecureSessionPreconfigPinCallback");
213
214     return OC_STACK_OK;
215 }