some errors fix
[iotivity.git] / resource / csdk / security / provisioning / src / oxmrandompin.c
1 /* *****************************************************************
2  *
3  * Copyright 2015 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 "iotivity_config.h"
22
23 #ifdef HAVE_MEMORY_H
24 #include <memory.h>
25 #endif
26
27 #include "ocstack.h"
28 #include "experimental/securevirtualresourcetypes.h"
29 #include "experimental/doxmresource.h"
30 #include "credresource.h"
31 #include "cacommon.h"
32 #include "cainterface.h"
33 #include "experimental/ocrandom.h"
34 #include "oic_malloc.h"
35 #include "experimental/logger.h"
36 #include "pbkdf2.h"
37 #include "oxmrandompin.h"
38 #include "ownershiptransfermanager.h"
39 #include "pinoxmcommon.h"
40 #include "ocstackinternal.h"
41 #include "mbedtls/ssl_ciphersuites.h"
42
43 #define TAG "OIC_OXM_RandomPIN"
44
45 OCStackResult CreatePinBasedSelectOxmPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
46 {
47     if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
48     {
49         return OC_STACK_INVALID_PARAM;
50     }
51
52     bool propertiesToInclude[DOXM_PROPERTY_COUNT];
53     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
54     propertiesToInclude[DOXM_OXMSEL] = true;
55
56     return DoxmToCBORPayloadPartial(otmCtx->selectedDeviceInfo->doxm, payload,
57         size, propertiesToInclude);
58 }
59
60 OCStackResult CreatePinBasedOwnerTransferPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
61 {
62     if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
63     {
64         return OC_STACK_INVALID_PARAM;
65     }
66
67     OicUuid_t uuidPT = {.id={0}};
68     *payload = NULL;
69     *size = 0;
70
71     if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
72     {
73         OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
74         return OC_STACK_ERROR;
75     }
76     memcpy(otmCtx->selectedDeviceInfo->doxm->owner.id, uuidPT.id , UUID_LENGTH);
77
78     bool propertiesToInclude[DOXM_PROPERTY_COUNT];
79     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
80     propertiesToInclude[DOXM_DEVOWNERUUID] = true;
81
82     return DoxmToCBORPayloadPartial(otmCtx->selectedDeviceInfo->doxm, payload,
83         size, propertiesToInclude);
84 }
85
86 OCStackResult InputPinCodeCallback(OTMContext_t *otmCtx)
87 {
88     if (!otmCtx || !otmCtx->selectedDeviceInfo)
89     {
90         return OC_STACK_INVALID_PARAM;
91     }
92
93     uint8_t pinData[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
94
95     OCStackResult res = InputPin(otmCtx->selectedDeviceInfo->doxm->deviceID, (char*)pinData, sizeof(pinData));
96     if (OC_STACK_OK != res)
97     {
98         OIC_LOG(ERROR, TAG, "Failed to input PIN");
99         return res;
100     }
101
102     /**
103      * Since PSK will be used directly while PIN based ownership transfer,
104      * Credential should not be saved into SVR.
105      * For this reason, We will use a temporary get_psk_info callback to random PIN OxM.
106      */
107     //in case of OTM
108     if(!(otmCtx->selectedDeviceInfo->doxm->owned))
109     {
110         if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForRandomPinOxm))
111         {
112             OIC_LOG(ERROR, TAG, "Failed to register DTLS credentials handler for random PIN OxM.");
113             res = OC_STACK_ERROR;
114         }
115     }
116 #ifdef MULTIPLE_OWNER
117     //in case of MOT
118     else if(otmCtx->selectedDeviceInfo->doxm->owned &&
119             otmCtx->selectedDeviceInfo->doxm->mom &&
120             OIC_MULTIPLE_OWNER_DISABLE != otmCtx->selectedDeviceInfo->doxm->mom->mode)
121     {
122         if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForMotRandomPinOxm))
123         {
124             OIC_LOG(ERROR, TAG, "Failed to register TLS credentials handler for random PIN OxM.");
125             res = OC_STACK_ERROR;
126         }
127     }
128 #endif //MULTIPLE_OWNER
129
130     //Set the device id to derive temporal PSK
131     SetUuidForPinBasedOxm(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
132
133     return res;
134 }
135
136 OCStackResult CreateSecureSessionRandomPinCallback(OTMContext_t* otmCtx)
137 {
138     OIC_LOG(INFO, TAG, "IN CreateSecureSessionRandomPinCallback");
139
140     if (!otmCtx || !otmCtx->selectedDeviceInfo)
141     {
142         return OC_STACK_INVALID_PARAM;
143     }
144
145     CAResult_t caresult = CAEnableAnonECDHCipherSuite(false);
146     if (CA_STATUS_OK != caresult)
147     {
148         OIC_LOG_V(ERROR, TAG, "Unable to disable anon cipher suite");
149         return OC_STACK_ERROR;
150     }
151     OIC_LOG(INFO, TAG, "Anonymous cipher suite disabled.");
152
153     caresult  = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, (CATransportAdapter_t)otmCtx->selectedDeviceInfo->endpoint.adapter);
154     if (CA_STATUS_OK != caresult)
155     {
156         OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
157         return OC_STACK_ERROR;
158     }
159     OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 cipher suite selected.");
160
161     CAEndpoint_t endpoint;
162     OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
163     CopyDevAddrToEndpoint(&selDevInfo->endpoint, &endpoint);
164
165     if (CA_ADAPTER_IP == endpoint.adapter)
166     {
167         endpoint.port = selDevInfo->securePort;
168     }
169 #ifdef WITH_TCP
170     else if (CA_ADAPTER_TCP == endpoint.adapter)
171     {
172         endpoint.port = selDevInfo->tcpSecurePort;
173     }
174 #endif
175
176     caresult = CAInitiateHandshake(&endpoint);
177     if (CA_STATUS_OK != caresult)
178     {
179         OIC_LOG_V(ERROR, TAG, "DTLS handshake failure.");
180         return OC_STACK_ERROR;
181     }
182
183     OIC_LOG(INFO, TAG, "OUT CreateSecureSessionRandomPinCallback");
184
185     return OC_STACK_OK;
186 }