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