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