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