1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 #include "ocsecurity.h"
24 #include "ocsecurityconfig.h"
25 #ifdef CA_SEC_MERGE_WORKAROUND
26 #include "ocsecurityinternal.h"
27 #endif //CA_SEC_MERGE_WORKAROUND
30 static OCSecConfigData* secConfigData;
31 static int secConfigDataLen;
34 * Currently, there is a disconnect in the data structure used between RI layer
35 * and CA layer to convey DTLS PSK credentials. We cannot update this data
36 * structure until all reviews of CA layer is completed. To enable security
37 * feature in CA branch this workaround is added as a temporary stop-gap.
40 #ifdef CA_SEC_MERGE_WORKAROUND
41 static CADtlsPskCredsBlob *caBlob;
42 #endif //CA_SEC_MERGE_WORKAROUND
45 * This internal API removes/clears the global variable holding the security
46 * config data. This needs to be invoked when OIC stack is shutting down.
50 void DeinitOCSecurityInfo()
54 // Initialize sensitive data to zeroes before freeing.
55 memset(secConfigData, 0, secConfigDataLen);
57 OCFree(secConfigData);
61 #ifdef CA_SEC_MERGE_WORKAROUND
64 OCFree(caBlob->creds);
72 * This internal callback is used by lower stack (i.e. CA layer) to
73 * retrieve PSK credentials from RI security layer.
75 * Note: When finished, caller should initialize memory to zeroes and
76 * invoke OCFree to delete @p credInfo.
79 * binary blob containing PSK credentials
83 void GetDtlsPskCredentials(OCDtlsPskCredsBlob **credInfo)
85 if(secConfigData && credInfo)
88 OCSecBlob * osb = (OCSecBlob*)secConfigData->blob;
89 for ( ;(i<secConfigData->numBlob) && osb; i++)
91 if (osb->type == OC_BLOB_TYPE_PSK)
93 #ifdef CA_SEC_MERGE_WORKAROUND
94 OCDtlsPskCredsBlob * ocBlob = (OCDtlsPskCredsBlob *)osb->val;
97 caBlob = (CADtlsPskCredsBlob *)OCCalloc(sizeof(CADtlsPskCredsBlob), 1);
100 memcpy(caBlob->identity, ocBlob->identity, sizeof(caBlob->identity));
101 caBlob->num = ocBlob->num;
103 (OCDtlsPskCreds*) OCMalloc(caBlob->num * sizeof(OCDtlsPskCreds));
106 memcpy(caBlob->creds, ocBlob->creds,
107 caBlob->num * sizeof(OCDtlsPskCreds));
111 *credInfo = (OCDtlsPskCredsBlob *) caBlob;
114 OCDtlsPskCredsBlob * blob;
115 blob = (OCDtlsPskCredsBlob *)OCMalloc(osb->len);
118 memcpy(blob, osb->val, osb->len);
122 #endif //CA_SEC_MERGE_WORKAROUND
124 osb = config_data_next_blob(osb);
131 * This method validates the sanctity of OCDtlsPskCredsBlob.
134 * binary blob containing PSK credentials
136 * @retval OC_STACK_OK for Success, otherwise some error value
139 OCStackResult ValidateBlobTypePSK(const OCSecBlob *secBlob)
141 OCDtlsPskCredsBlob *pskCredsBlob;
144 if(!secBlob || secBlob->len == 0)
146 return OC_STACK_INVALID_PARAM;
149 pskCredsBlob = (OCDtlsPskCredsBlob *)secBlob->val;
151 //calculate the expected length of PSKCredsBlob
152 if(pskCredsBlob->num >= 1)
154 validLen = sizeof(OCDtlsPskCredsBlob) +
155 (pskCredsBlob->num - 1) * sizeof(OCDtlsPskCredsBlob);
159 validLen = sizeof(OCDtlsPskCredsBlob);
162 if(secBlob->len != validLen)
163 return OC_STACK_INVALID_PARAM;
170 * This method validates the sanctity of configuration data provided
171 * by application to OC stack.
174 * binary blob containing credentials and other config data
176 * length of binary blob
178 * @retval OC_STACK_OK for Success, otherwise some error value
181 OCStackResult ValidateSecConfigData(const OCSecConfigData *cfgData,
184 OCStackResult ret = OC_STACK_OK;
186 OCSecBlob * osb = NULL;
188 if (!cfgData || (len == 0))
190 return OC_STACK_INVALID_PARAM;
193 if (cfgData->version != OCSecConfigVer_CurrentVersion)
195 return OC_STACK_INVALID_PARAM;
198 osb = (OCSecBlob*)cfgData->blob;
199 for ( ;(i<cfgData->numBlob) && osb; i++)
201 if (osb->type == OC_BLOB_TYPE_PSK)
203 ret = ValidateBlobTypePSK(osb);
207 return OC_STACK_INVALID_PARAM;
210 if (ret != OC_STACK_OK)
214 osb = config_data_next_blob(osb);
223 * Provides the Security configuration data to OC stack.
226 * binary blob containing credentials and other config data
228 * length of binary blob
230 * @retval OC_STACK_OK for Success, otherwise some error value
232 OCStackResult OCSecSetConfigData(const OCSecConfigData *cfgData,
235 // Validate the data inside blob before consuming
236 if (cfgData && ValidateSecConfigData(cfgData, len) == OC_STACK_OK)
238 // Remove existing blob
239 DeinitOCSecurityInfo();
240 // Allocate storage for new blob
241 secConfigData = (OCSecConfigData*)OCMalloc(len);
244 memcpy(secConfigData, cfgData, len);
245 secConfigDataLen = len;
249 return OC_STACK_NO_MEMORY;
252 return OC_STACK_INVALID_PARAM;