3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 #include <glib/gprintf.h>
23 #include <sync_agent.h>
26 #include "common/dm_common.h"
27 #include "common/util/util.h"
28 #include "serviceadapter/sa_util.h"
30 #ifndef OMADM_AGENT_LOG
32 #define LOG_TAG "OMA_DM_SA"
38 void putCmdIntoList(GList ** commands, GList ** commands_last, void *pCommand)
43 if (*commands_last == NULL) {
44 *commands_last = *commands = g_list_append(*commands, pCommand);
46 temp = g_list_append(*commands_last, pCommand);
48 _DEBUG_ERROR("g_list_append return value NULL!!");
50 *commands_last = g_list_next(*commands_last);
56 DM_ERROR create_auth_credString(AuthType type, const char *username, const char *password, const unsigned char *nonce, const unsigned int nonce_size, char **pCred)
60 retvm_if((username) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "username is NULL!!");
61 retvm_if((password) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "password is NULL!!");
63 _DEBUG_INFO(" type : [%d] username :[%s], password :[%s] , nonce : [%s],nonce_size : [%d]", type, username, password, nonce, nonce_size);
70 char *plain = g_strjoin(":", username, password, NULL);
71 *pCred = g_base64_encode((unsigned char *)plain, strlen(plain));
74 ret = COMMON_ERR_INTERNAL_NO_MEMORY;
83 /* How does syncml:auth-md5 works?
89 * username + ":" + password
97 /* Let's determine the string for the comparison. */
99 auth = g_strjoin(":", username, password, NULL);
100 _DEBUG_INFO("[username:password] = %s\n", auth);
102 unsigned char *digest = NULL;
103 digest = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, auth, strlen(auth));
105 *pCred = g_base64_encode(digest, 16);
106 if (*pCred == NULL) {
107 ret = COMMON_ERR_INTERNAL_NO_MEMORY;
111 _DEBUG_INFO("nonce = %s", nonce);
112 _DEBUG_INFO("nonce_size = %d", nonce_size);
113 int auth_size = strlen(*pCred) + nonce_size + 1;
114 auth = (char *)calloc(strlen(*pCred) + nonce_size + 1 + 1, sizeof(char));
116 _DEBUG_INFO("alloc fail");
118 return COMMON_ERR_ALLOC;
120 memcpy(auth, *pCred, strlen(*pCred));
121 auth[strlen(*pCred)] = ':';
122 memcpy(auth + strlen(*pCred) + 1, nonce, nonce_size);
123 _DEBUG_INFO("base64[md5[username:password]] = %s\n", *pCred);
124 _DEBUG_INFO("before last base64 encoding = %s\n", auth);
127 digest = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, auth, auth_size);
128 _DEBUG_INFO("md5[base64[md5[username:password]]:nonce] = %s\n", digest);
131 *pCred = g_base64_encode(digest, 16);
133 _DEBUG_INFO("base64[md5[base64[md5[username:password]]:nonce]] = %s", *pCred);
134 if (*pCred == NULL) {
135 ret = COMMON_ERR_INTERNAL_NO_MEMORY;
142 /*do not use cred element */
145 case AUTH_TYPE_UNKNOWN:
146 case AUTH_TYPE_HTTP_BASIC:
147 case AUTH_TYPE_HTTP_DIGEST:
149 case AUTH_TYPE_SECURID:
150 case AUTH_TYPE_SAFEWORD:
151 case AUTH_TYPE_DIGIPASS:
152 case AUTH_TYPE_TRANSPORT:
153 _DEBUG_INFO("not support auth type");
154 ret = DM_ERR_FORBIDDEN;
165 _DEBUG_INFO("error : %d\n", ret);
170 DM_ERROR gemerate_hmac(char *username, char *password, unsigned char *nonce, unsigned int nonce_size, char *msg, unsigned int msg_size, char **mac)
174 DM_ERROR ret = DM_OK;
176 retvm_if((msg) == NULL, COMMON_ERR_IS_NULL, "session is NULL!!");
177 retvm_if((username) == NULL, COMMON_ERR_IS_NULL, "username is NULL!!");
178 retvm_if((password) == NULL, COMMON_ERR_IS_NULL, "password is NULL!!");
179 retvm_if((nonce) == NULL, COMMON_ERR_IS_NULL, "nonce is NULL!!");
181 char *resultmd = NULL;
182 unsigned char *resultmd5 = NULL;
183 unsigned char *resultmd6 = NULL;
184 //char md5Digest[16];
185 char buffer[BUF_SIZE];
186 char *temp_result1 = NULL;
187 char *temp_result2 = NULL;
188 char *temp_result3 = NULL;
192 /* if (nonce == NULL|| username == NULL|| password == NULL|| msg == NULL)
196 _DEBUG_INFO("generate HMAC");
197 //resultmd5 = (unsigned char *)calloc(1, sizeof(char)*17);
200 resultmd = (char *)sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, (const char *)msg, (int)msg_size);
201 resultmd5 = (unsigned char *)strdup(resultmd);
206 char *digest_msg = (char *)calloc(MAX_BUFFER, sizeof(char));
207 if (digest_msg == NULL) {
208 _DEBUG_INFO("alloc fail");
210 return COMMON_ERR_ALLOC;
212 for (i = 0; i < 16; i++) {
213 snprintf(digest_msg + (i * 2), MAX_BUFFER, "%02x", resultmd5[i]);
215 _DEBUG_INFO("MD 5 = %s", digest_msg);
216 /* B64(H(messageBody) */
217 temp_result1 = g_base64_encode(resultmd5, size);
221 _DEBUG_INFO("B64(H(messageBody)) : %s", temp_result1);
223 /* H(username:password) */
224 str_len = g_strlcpy(buffer, username, (int)sizeof(buffer));
225 if (str_len >= sizeof(buffer)) {
226 _DEBUG_INFO("buffer over flow");
227 ret = COMMON_ERR_BUFFER_OVERFLOW;
229 if(digest_msg != NULL) {
237 len = g_strlcat(buffer, ":", BUF_SIZE);
238 len = g_strlcat(buffer, password, BUF_SIZE);
239 size = strlen(buffer);
241 _DEBUG_INFO("username:password: %s", buffer);
242 resultmd5 = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, (const char *)buffer, (int)size);
245 /* B64(H(username:password)) */
246 temp_result2 = g_base64_encode(resultmd5, size);
247 _DEBUG_INFO("B64(H(username:password)) %s", temp_result2);
249 /* B64(H(username:password)):nonce:B64(H(message body)) */
250 str_len = g_strlcpy(buffer, (const char *)temp_result2, (int)sizeof(buffer));
251 if (str_len >= sizeof(buffer)) {
252 _DEBUG_INFO("buffer over flow");
253 ret = COMMON_ERR_BUFFER_OVERFLOW;
255 if(digest_msg != NULL) {
264 len = g_strlcat(buffer, ":", BUF_SIZE);
266 _DEBUG_INFO("B64(H(username:password)): = %s", buffer);
267 size = strlen((const char *)temp_result2) + 1;
268 _DEBUG_INFO("buffer : %s, real size : %d , size : %d\n", buffer, strlen(buffer), size);
270 len = g_strlcat(buffer, (const char *)nonce, BUF_SIZE);
272 _DEBUG_INFO("B64(H(username:password)):nonce = %s", buffer);
273 size += strlen((const char *)nonce);
274 _DEBUG_INFO("buffer : %s, real size : %d , size : %d\n", buffer, strlen(buffer), size);
276 len = g_strlcat(buffer, ":", BUF_SIZE);
279 _DEBUG_INFO("buffer : %s, real size : %d , size : %d\n", buffer, strlen(buffer), size);
281 len = g_strlcat(buffer, temp_result1, BUF_SIZE);
283 size += strlen((const char *)temp_result1);
284 _DEBUG_INFO("B64(H(username:password)):nonce:B64(H(message body)): %s", buffer);
286 /* Interim Clean up */
287 str_free((char **)(&temp_result1));
288 str_free((char **)(&temp_result2));
290 if (str_len >= BUF_SIZE) {
291 _DEBUG_INFO("buffer over flow");
292 ret = COMMON_ERR_BUFFER_OVERFLOW;
297 /*char *buffer1 = "wUN5aEY1cn4K1AhZnuSg6Q==:12345:stthIupGdabKGLdI7ezeBw==";
298 int size1 = strlen(buffer1);
299 printf("buffer1 : %s, size1 : %d\n", buffer1, size1);
301 /* H(B64(H(username:password)):nonce:B64(H(message body))) */
302 resultmd6 = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, buffer, size);
306 _DEBUG_INFO("gener : ");
307 for (i = 0; i < size; ++i) {
308 _DEBUG_INFO(" %02x", resultmd6[i]);
312 /* Return the base 64 of digest */
313 temp_result3 = g_base64_encode(resultmd6, size);
316 _DEBUG_INFO("B64(H(B64(H(username:password)):nonce:B64(H(message body)))): %s", temp_result3);
318 (*mac) = strdup((const char *)temp_result3);
319 str_free((char **)(&temp_result3));
321 if(digest_msg != NULL) {
330 void set_xml_to_file(char *xml, const char *path)
337 pFile = fopen(path, "a");
345 fputs("==================================================================================", pFile);
354 DM_ERROR findStgringValue(char *original, char *findParam, char *findSep, char **findValue)
358 DM_ERROR ret = DM_OK;
360 retvm_if((original) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "original is NULL!!");
361 retvm_if((findParam) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "findParam is NULL!!");
363 char *findOption = NULL;
364 char *findEnd = NULL;
365 char *findSepEnd = NULL;
367 /*int optionSize = 0;
370 /*mindt=10&dr=1&maclen=10 */
371 findOption = strstr(original, findParam);
372 if (findOption != NULL) {
373 _DEBUG_INFO(" find Option : %s\n", findOption);
375 /*=10&dr=1&maclen=10*/
376 findEnd = strstr(findOption, findSep);
377 if (findEnd != NULL) {
379 findSepEnd = strstr(findOption, UI_OP_SEPARATOR);
380 if (findSepEnd != NULL) {
381 valueSize = strlen(findEnd) - strlen(findSepEnd) - 1;
383 valueSize = strlen(findEnd);
385 _DEBUG_INFO(" findEnd : %s\n", findEnd);
386 _DEBUG_INFO(" findSepEnd : %s\n", findSepEnd);
387 _DEBUG_INFO(" value size : %d\n", valueSize);
389 _DEBUG_INFO("not found value");
393 (*findValue) = calloc(1, valueSize + 1);
394 if ((*findValue) == NULL) {
395 _DEBUG_INFO("alloc fail");
396 return COMMON_ERR_ALLOC;
398 memcpy((*findValue), findEnd + 1, valueSize);
399 (*findValue)[valueSize] = '\0';
401 _DEBUG_INFO(" find Value : %s : %d \n", (*findValue), valueSize);
404 _DEBUG_INFO(" not found \n");