Updated security config blob for extensibility
[platform/upstream/iotivity.git] / resource / csdk / security / src / ocsecurity.c
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 "ocstack.h"
22 #include "ocmalloc.h"
23 #include "ocsecurity.h"
24 #include "ocsecurityconfig.h"
25 #include <string.h>
26
27 static OCSecConfigData* secConfigData;
28 static int secConfigDataLen;
29
30 /**
31  * This internal API removes/clears the global variable holding the security
32  * config data. This needs to be invoked when OIC stack is shutting down.
33  *
34  * @retval none
35  */
36 void DeinitOCSecurityInfo()
37 {
38     if (secConfigData)
39     {
40         // Initialize sensitive data to zeroes before freeing.
41         memset(secConfigData, 0, secConfigDataLen);
42
43         OCFree(secConfigData);
44         secConfigData = NULL;
45     }
46 }
47
48 /**
49  * This internal callback is used by lower stack (i.e. CA layer) to
50  * retrieve PSK credentials from RI security layer.
51  *
52  * Note: When finished, caller should initialize memory to zeroes and
53  * invoke OCFree to delete @p credInfo.
54  *
55  * @param credInfo
56  *     binary blob containing PSK credentials
57  *
58  * @retval none
59  */
60 void GetDtlsPskCredentials(OCDtlsPskCredsBlob **credInfo)
61 {
62     if(secConfigData && credInfo)
63     {
64         unsigned int i = 0;
65         OCSecBlob * osb = (OCSecBlob*)secConfigData->blob;
66         for ( ;(i<secConfigData->numBlob) && osb; i++)
67         {
68             if (osb->type == OC_BLOB_TYPE_PSK)
69             {
70                 OCDtlsPskCredsBlob * blob;
71                 blob = (OCDtlsPskCredsBlob *)OCMalloc(osb->len);
72                 if (blob)
73                 {
74                     memcpy(blob, osb->val, osb->len);
75                     *credInfo = blob;
76                     break;
77                 }
78             }
79             osb = config_data_next_blob(osb);
80         }
81     }
82 }
83
84
85 /**
86  * This method validates the sanctity of OCDtlsPskCredsBlob.
87  *
88  * @param secBlob
89  *     binary blob containing PSK credentials
90  *
91  * @retval OC_STACK_OK for Success, otherwise some error value
92  */
93 static
94 OCStackResult ValidateBlobTypePSK(const OCSecBlob *secBlob)
95 {
96     OCDtlsPskCredsBlob *pskCredsBlob;
97     uint16_t validLen;
98
99     if(secBlob->len == 0)
100     {
101         return OC_STACK_INVALID_PARAM;
102     }
103
104     pskCredsBlob = (OCDtlsPskCredsBlob *)secBlob->val;
105
106     //calculate the expected length of PSKCredsBlob
107     if(pskCredsBlob->num >= 1)
108     {
109         validLen = sizeof(OCDtlsPskCredsBlob) +
110             (pskCredsBlob->num - 1) * sizeof(OCDtlsPskCredsBlob);
111     }
112     else
113     {
114         validLen = sizeof(OCDtlsPskCredsBlob);
115     }
116
117     if(secBlob->len != validLen)
118         return OC_STACK_INVALID_PARAM;
119
120     return OC_STACK_OK;
121 }
122
123
124 /**
125  * This method validates the sanctity of configuration data provided
126  * by application to OC stack.
127  *
128  * @param cfgdata
129  *     binary blob containing credentials and other config data
130  * @param len
131  *     length of binary blob
132  *
133  * @retval OC_STACK_OK for Success, otherwise some error value
134  */
135 static
136 OCStackResult ValidateSecConfigData(const OCSecConfigData *cfgData,
137                 size_t len)
138 {
139     OCStackResult ret = OC_STACK_OK;
140     unsigned int i = 0;
141     OCSecBlob * osb = NULL;
142
143     if (!cfgData || (len == 0))
144     {
145         return OC_STACK_INVALID_PARAM;
146     }
147
148     if (cfgData->version != OCSecConfigVer_CurrentVersion)
149     {
150         return OC_STACK_INVALID_PARAM;
151     }
152
153     osb = (OCSecBlob*)cfgData->blob;
154     for ( ;(i<cfgData->numBlob) && osb; i++)
155     {
156         if (osb->type == OC_BLOB_TYPE_PSK)
157         {
158             ret = ValidateBlobTypePSK(osb);
159         }
160         else
161         {
162             return OC_STACK_INVALID_PARAM;
163         }
164
165         if (ret != OC_STACK_OK)
166         {
167             return ret;
168         }
169         osb = config_data_next_blob(osb);
170     }
171
172     return ret;
173 }
174
175
176
177 /**
178  * Provides the Security configuration data to OC stack.
179  *
180  * @param cfgdata
181  *     binary blob containing credentials and other config data
182  * @param len
183  *     length of binary blob
184  *
185  * @retval OC_STACK_OK for Success, otherwise some error value
186  */
187 OCStackResult OCSecSetConfigData(const OCSecConfigData *cfgData,
188                 size_t len)
189 {
190     // Validate the data inside blob before consuming
191     if (cfgData && ValidateSecConfigData(cfgData, len) == OC_STACK_OK)
192     {
193         // Remove existing blob
194         DeinitOCSecurityInfo();
195         // Allocate storage for new blob
196         secConfigData = (OCSecConfigData*)OCMalloc(len);
197         if (secConfigData)
198         {
199             memcpy(secConfigData, cfgData, len);
200             secConfigDataLen = len;
201             return OC_STACK_OK;
202         }
203
204         return OC_STACK_NO_MEMORY;
205     }
206
207     return OC_STACK_INVALID_PARAM;
208 }
209
210