1 /* *****************************************************************
3 * Copyright 2017 Samsung Electronics All Rights Reserved.
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 * *****************************************************************/
25 #include <mbedtls/ssl.h>
26 #include <mbedtls/ctr_drbg.h>
27 #include <mbedtls/x509_crt.h>
28 #include <mbedtls/pkcs12.h>
29 #include <mbedtls/ssl_internal.h>
36 #include "oic_malloc.h"
37 #include "oic_string.h"
40 #include "srmresourcestrings.h"
41 #include "pinoxmcommon.h"
42 #include "credresource.h"
44 #include "security_internals.h"
45 #include "psinterface.h"
47 #include "svrdbeditordoxm.h"
48 #include "svrdbeditorcred.h"
50 typedef enum CredModifyType
52 CRED_EDIT_SUBJECTUUID = 1,
54 CRED_EDIT_ROWNERUUID = 3,
59 OCStackResult ocResult = OC_STACK_ERROR;
60 uint8_t *secPayload = NULL;
61 size_t payloadSize = 0;
63 OicSecCred_t *credList = NULL;
64 OicSecCred_t *cred = NULL;
65 OicSecCred_t *tmpCred = NULL;
66 //Load security resouce data from SVR DB.
67 ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &secPayload, &payloadSize);
68 if (OC_STACK_OK != ocResult)
70 PRINT_WARN("GetSecureVirtualDatabaseFromPS : %d", ocResult);
73 if (secPayload && 0 != payloadSize)
75 ocResult = CBORPayloadToCred(secPayload, payloadSize, &credList);
76 if (OC_STACK_OK != ocResult)
78 PRINT_ERR("CBORPayloadToCred : %d", ocResult);
86 //Add the loaded credentials into gCred of CredResource module in order to use the credential management mechanism.
87 LL_FOREACH_SAFE(credList, cred, tmpCred)
89 ocResult = AddCredential(cred);
90 if (OC_STACK_OK != ocResult)
92 PRINT_ERR("AddCredential : %d", ocResult);
99 static void UpdateCred(void)
101 OCStackResult credResult = OC_STACK_ERROR;
102 uint8_t *credPayload = NULL;
103 size_t credPayloadSize = 0;
106 credResult = CredToCBORPayload(GetCredList(), &credPayload, &credPayloadSize, secureFlag);
107 if (OC_STACK_OK != credResult)
109 PRINT_ERR("CredToCBORPayload error : %d", credResult);
112 credResult = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, credPayload, credPayloadSize);
113 if (OC_STACK_OK != credResult)
115 PRINT_ERR("UpdateSecureResourceInPS error : %d", credResult);
116 OICFree(credPayload);
119 OICFree(credPayload);
123 * Parse chain of X.509 certificates.
125 * @param[out] crt container for X.509 certificates
126 * @param[in] buf buffer with X.509 certificates. Certificates may be in either in PEM
127 or DER format in a jumble. Each PEM certificate must be NULL-terminated.
128 * @param[in] bufLen buffer length
130 * @return 0 on success, -1 on error
132 // TODO: Update to use credresource.c
133 static int ParseCertChain(mbedtls_x509_crt *crt, unsigned char *buf, size_t bufLen)
135 if (NULL == crt || NULL == buf || 0 == bufLen)
137 PRINT_ERR("ParseCertChain : Invalid param");
141 /* byte encoded ASCII string '-----BEGIN CERTIFICATE-----' */
142 char pemCertHeader[] =
144 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
145 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
147 // byte encoded ASCII string '-----END CERTIFICATE-----' */
148 char pemCertFooter[] =
150 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
151 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
153 size_t pemCertHeaderLen = sizeof(pemCertHeader);
154 size_t pemCertFooterLen = sizeof(pemCertFooter);
157 unsigned char *tmp = NULL;
164 if (0x30 == buf[pos] && 0x82 == buf[pos + 1])
166 tmp = (unsigned char *)buf + pos + 1;
167 ret = mbedtls_asn1_get_len(&tmp, buf + bufLen, &len);
170 PRINT_ERR("mbedtls_asn1_get_len failed: 0x%04x", ret);
174 if (pos + len < bufLen)
176 ret = mbedtls_x509_crt_parse_der(crt, buf + pos, len + 4);
183 PRINT_ERR("mbedtls_x509_crt_parse_der failed: 0x%04x", ret);
188 else if ((buf + pos + pemCertHeaderLen < buf + bufLen) &&
189 0 == memcmp(buf + pos, pemCertHeader, pemCertHeaderLen))
192 endPos = memmem(&(buf[pos]), bufLen - pos, pemCertFooter, pemCertFooterLen);
195 PRINT_ERR("end of PEM certificate not found.");
199 len = (char *)endPos - ((char *)buf + pos) + pemCertFooterLen;
200 if (pos + len + 1 <= bufLen)
202 char con = buf[pos + len];
203 buf[pos + len] = 0x00;
204 ret = mbedtls_x509_crt_parse(crt, buf + pos, len + 1);
211 PRINT_ERR("mbedtls_x509_crt_parse failed: 0x%04x", ret);
213 buf[pos + len] = con;
217 unsigned char *lastCert = (unsigned char *)OICMalloc((len + 1) * sizeof(unsigned char));
218 if (NULL == lastCert)
220 PRINT_ERR("Failed to allocate memory for certificate");
223 memcpy(lastCert, buf + pos, len);
224 lastCert[len] = 0x00;
225 ret = mbedtls_x509_crt_parse(crt, lastCert, len + 1);
232 PRINT_ERR("mbedtls_x509_crt_parse failed: 0x%04x", ret);
247 // TODO: Update to use credresource.c
248 static void ParseDerCaCert(ByteArray_t *crt, const char *usage, uint16_t credId)
250 if (NULL == crt || NULL == usage)
252 PRINT_ERR("ParseDerCaCert : Invalid param");
256 OicSecCred_t *temp = NULL;
258 LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
260 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
261 0 == strcmp(temp->credUsage, usage) &&
262 temp->credId == credId)
264 if (OIC_ENCODING_BASE64 == temp->optionalData.encoding)
266 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
267 uint8_t *buf = OICCalloc(1, bufSize);
270 PRINT_ERR("ParseDerCaCert : Failed to allocate memory");
274 if (B64_OK != b64Decode((char *)(temp->optionalData.data), temp->optionalData.len, buf, bufSize,
278 PRINT_ERR("ParseDerCaCert : Failed to decode base64 data");
281 crt->data = OICRealloc(crt->data, crt->len + outSize);
282 memcpy(crt->data + crt->len, buf, outSize);
288 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
289 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
290 crt->len += temp->optionalData.len;
296 PRINT_INFO("ParseDerCaCert : %s not found", usage);
301 // TODO: Update to use credresource.c
302 static void ParseDerOwnCert(ByteArray_t *crt, const char *usage, uint16_t credId)
304 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
305 if (NULL == crt || NULL == usage)
307 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
311 OicSecCred_t *temp = NULL;
312 LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
314 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
315 0 == strcmp(temp->credUsage, usage) &&
316 temp->credId == credId)
318 crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
319 memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
320 crt->len += temp->publicData.len;
321 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
326 OIC_LOG_V(WARNING, TAG, "%s not found", usage);
328 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
332 inline void ParseDerKey(ByteArray_t *key, const char *usage, uint16_t credId)
334 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
335 if (NULL == key || NULL == usage)
337 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
341 OicSecCred_t *temp = NULL;
343 LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
345 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
346 0 == strcmp(temp->credUsage, usage) &&
347 temp->credId == credId)
349 key->data = OICRealloc(key->data, key->len + temp->privateData.len);
350 memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
351 key->len += temp->privateData.len;
352 OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
357 OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
359 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
362 static void PrintCredType(OicSecCredType_t credType)
364 PRINT_DATA("%d", credType);
367 case NO_SECURITY_MODE:
368 PRINT_DATA(" (NO_SECURITY_MODE)\n");
370 case SYMMETRIC_PAIR_WISE_KEY:
371 PRINT_DATA(" (SYMMETRIC_PAIR_WISE_KEY)\n");
373 case SYMMETRIC_GROUP_KEY:
374 PRINT_DATA(" (SYMMETRIC_GROUP_KEY)\n");
377 PRINT_DATA(" (ASYMMETRIC_KEY)\n");
379 case SIGNED_ASYMMETRIC_KEY:
380 PRINT_DATA(" (SIGNED_ASYMMETRIC_KEY)\n");
383 PRINT_DATA(" (PIN_PASSWORD)\n");
385 case ASYMMETRIC_ENCRYPTION_KEY:
386 PRINT_DATA(" (ASYMMETRIC_ENCRYPTION_KEY)\n");
389 PRINT_ERR(" (Unknown Cred type)");
394 static void PrintCredEncodingType(OicEncodingType_t encoding)
396 PRINT_DATA("%d", encoding);
399 case OIC_ENCODING_RAW:
400 PRINT_DATA(" (OIC_ENCODING_RAW)\n");
402 case OIC_ENCODING_BASE64:
403 PRINT_DATA(" (OIC_ENCODING_BASE64)\n");
405 case OIC_ENCODING_PEM:
406 PRINT_DATA(" (OIC_ENCODING_PEM)\n");
408 case OIC_ENCODING_DER:
409 PRINT_DATA(" (OIC_ENCODING_DER)\n");
412 PRINT_ERR(" (Unknown Encoding type)");
419 * This API to print credential list.
420 * Also return the number of credential in credential list.
422 void PrintCredList(const OicSecCred_t *creds)
424 const OicSecCred_t *cred = NULL;
425 const OicSecCred_t *tempCred = NULL;
426 bool isEmptyList = true;
427 PRINT_INFO("\n\n********************* [%-20s] *********************",
428 "Credential Resource");
429 LL_FOREACH_SAFE(creds, cred, tempCred)
431 PRINT_PROG("%15s : ", OIC_JSON_CREDID_NAME);
432 PrintInt(cred->credId);
434 PRINT_PROG("%15s : ", OIC_JSON_SUBJECTID_NAME);
435 if (0 == memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)))
437 PrintString((char *)WILDCARD_SUBJECT_ID.id);
441 PrintUuid(&(cred->subject));
444 #ifdef MULTIPLE_OWNER
447 PRINT_PROG("%15s : ", OIC_JSON_EOWNERID_NAME);
448 PrintUuid(cred->eownerID);
452 PRINT_PROG("%15s : ", OIC_JSON_CREDTYPE_NAME);
453 PrintCredType(cred->credType);
455 switch (cred->credType)
457 case SYMMETRIC_PAIR_WISE_KEY:
458 case SYMMETRIC_GROUP_KEY:
459 PRINT_PROG("%15s : \n", OIC_JSON_PRIVATEDATA_NAME);
460 if (cred->privateData.data)
462 PRINT_DATA("%s : ", OIC_JSON_ENCODING_NAME);
463 PrintCredEncodingType(cred->privateData.encoding);
465 PRINT_DATA("%s : ", OIC_JSON_DATA_NAME);
466 if (OIC_ENCODING_BASE64 == cred->privateData.encoding)
468 PrintString((char *)cred->privateData.data);
472 PrintBuffer(cred->privateData.data, cred->privateData.len);
477 PRINT_ERR("Private data is null");
481 case SIGNED_ASYMMETRIC_KEY:
482 // TODO: Print certificate and asymmetric key in readable formats
487 PRINT_PROG("%15s : ", OIC_JSON_CREDUSAGE_NAME);
488 PRINT_DATA("%s\n", cred->credUsage);
492 if (cred->privateData.data)
494 PRINT_PROG("%15s : \n", OIC_JSON_PRIVATEDATA_NAME);
495 PrintBuffer(cred->privateData.data, cred->privateData.len);
497 if (cred->credUsage &&
498 (0 == strcmp(cred->credUsage, PRIMARY_CERT) ||
499 0 == strcmp(cred->credUsage, MF_PRIMARY_CERT)))
510 if (cred->publicData.data)
512 PRINT_PROG("%15s : ", OIC_JSON_PUBLICDATA_NAME);
513 PRINT_DATA("%-17s : ", OIC_JSON_ENCODING_NAME);
514 PrintCredEncodingType(cred->publicData.encoding);
516 if (cred->credUsage &&
517 (0 == strcmp(cred->credUsage, PRIMARY_CERT) ||
518 0 == strcmp(cred->credUsage, MF_PRIMARY_CERT)))
521 mbedtls_x509_crt crt;
522 mbedtls_x509_crt *tmpCrt = NULL;
526 memset(&inf, 0x00, sizeof(PkiInfo_t));
527 mbedtls_x509_crt_init(&crt);
529 ParseDerOwnCert(&inf.crt, cred->credUsage, cred->credId);
530 ParseCertChain(&crt, inf.crt.data, inf.crt.len);
532 for (i = 0, tmpCrt = &crt; NULL != tmpCrt; i++, tmpCrt = tmpCrt->next)
534 PRINT_INFO("[Cert #%d]", (i + 1));
535 mbedtls_x509_crt_info( buf, sizeof(buf) - 1, "", tmpCrt );
536 PRINT_DATA("%s", buf);
538 mbedtls_x509_crt_free(&crt);
542 PRINT_INFO("will be updated to print public data");
547 if (cred->optionalData.data)
549 PRINT_PROG("%15s : \n", OIC_JSON_OPTDATA_NAME);
552 PRINT_DATA("%-17s : %s\n", OIC_JSON_REVOCATION_STATUS_NAME,
553 (cred->optionalData.revstat ? "True" : "False"));
555 PRINT_DATA("%-17s : ", OIC_JSON_ENCODING_NAME);
556 PrintCredEncodingType(cred->optionalData.encoding);
559 if (cred->credUsage &&
560 (0 == strcmp(cred->credUsage, TRUST_CA) ||
561 0 == strcmp(cred->credUsage, MF_TRUST_CA)))
565 mbedtls_x509_crt *tmpCa = NULL;
569 memset(&inf, 0x00, sizeof(PkiInfo_t));
570 mbedtls_x509_crt_init(&ca);
572 ParseDerCaCert(&inf.ca, cred->credUsage, cred->credId);
573 ParseCertChain(&ca, inf.ca.data, inf.ca.len);
575 for (i = 0, tmpCa = &ca; NULL != tmpCa; i++, tmpCa = tmpCa->next)
577 PRINT_INFO("[Cert #%d]", (i + 1));
578 mbedtls_x509_crt_info( buf, sizeof(buf) - 1, "", tmpCa );
579 PRINT_DATA("%s", buf);
581 mbedtls_x509_crt_free(&ca);
586 PRINT_INFO("will be updated to print optional data");
591 PRINT_PROG("%15s : ", OIC_JSON_PRIVATEDATA_NAME);
592 if (cred->privateData.data)
594 PRINT_DATA("%s : ", OIC_JSON_ENCODING_NAME);
595 PrintCredEncodingType(cred->privateData.encoding);
597 PRINT_DATA("%s : ", OIC_JSON_DATA_NAME);
598 PRINT_DATA("%s\n", cred->privateData.data);
602 PRINT_ERR("Private data is null");
605 case ASYMMETRIC_ENCRYPTION_KEY:
608 PRINT_ERR(" (Unknown Cred type)");
611 PRINT_PROG("------------------------------------------------------------------\n");
617 OicUuid_t uuid = {.id = {0}};
618 if (OC_STACK_OK != GetCredRownerId(&uuid))
620 PRINT_WARN("GetCredRownerId failed");
624 PRINT_PROG("%15s : ", OIC_JSON_ROWNERID_NAME);
630 PRINT_PROG("Cred List is empty.\n");
633 PRINT_INFO("********************* [%-20s] *********************",
634 "Credential Resource");
639 static int ReadDataFromFile(const char *infoTxt, uint8_t **buffer, size_t *bufferSize)
641 char filePath[512] = {0};
642 char tmpBuffer[SVR_DB_PATH_LENGTH] = {0};
644 size_t filePathLen = 0 ;
647 if (NULL == buffer || NULL != *buffer || NULL == bufferSize)
649 PRINT_ERR("ReadDataFromFile : Invaild param");
653 PRINT_NORMAL("%s", infoTxt);
654 if (NULL == fgets(filePath, sizeof(filePath), stdin))
656 PRINT_ERR("Failed fgets");
659 filePathLen = strlen(filePath);
660 if ('\n' == filePath[filePathLen - 1])
662 filePath[filePathLen - 1] = '\0';
666 fp = fopen(filePath, "rb");
669 size_t bytesRead = 0;
672 bytesRead = fread(tmpBuffer, 1, 1023, fp);
673 fileSize += bytesRead;
676 PRINT_ERR("Error fread\n");
687 PRINT_ERR("Failed to open %s" , filePath);
688 PRINT_ERR("Please make sure the file path and access permission.");
694 PRINT_ERR("%s is empty." , filePath);
698 fp = fopen(filePath, "rb");
701 *buffer = (uint8_t *) OICCalloc(1, fileSize);
702 if ( NULL == *buffer)
704 PRINT_ERR("Failed to allocate memory.");
708 if ( fread(*buffer, 1, fileSize, fp) == fileSize)
710 *bufferSize = fileSize;
716 PRINT_ERR("Failed to open %s" , filePath);
717 PRINT_ERR("Please make sure the file path and access permission.");
735 static int InputCredUsage(char **credUsage)
737 char inputUsage[128] = {0};
738 int credUsageNum = 0;
740 if (NULL == credUsage || NULL != *credUsage)
742 PRINT_ERR("InputCredUsage error : invaild param");
748 PRINT_NORMAL("\n\n");
749 PRINT_NORMAL("\t1. %s\n", TRUST_CA);
750 PRINT_NORMAL("\t2. %s\n", PRIMARY_CERT);
751 PRINT_NORMAL("\t3. %s\n", MF_TRUST_CA);
752 PRINT_NORMAL("\t4. %s\n", MF_PRIMARY_CERT);
753 PRINT_NORMAL("\t5. Input manually\n");
754 credUsageNum = InputNumber("\tSelect the credential usage : ");
755 switch (credUsageNum)
758 *credUsage = OICStrdup(TRUST_CA);
761 *credUsage = OICStrdup(PRIMARY_CERT);
764 *credUsage = OICStrdup(MF_TRUST_CA);
767 *credUsage = OICStrdup(MF_PRIMARY_CERT);
770 PRINT_NORMAL("\tInput the credential usage : ");
771 for (int ret = 0; 1 != ret; )
773 ret = scanf("%128s", inputUsage);
774 for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
775 // '0x20<=code' is character region
777 *credUsage = OICStrdup(inputUsage);
780 PRINT_ERR("Invaild credential usage");
785 while (0 == credUsageNum);
787 if (NULL == *credUsage)
789 PRINT_ERR("Failed OICStrdup");
796 static int InputCredEncodingType(const char *dataType, OicEncodingType_t *encoding)
799 char infoText[512] = {0};
801 if (NULL == dataType || NULL == encoding)
803 PRINT_ERR("InputCredEncodingType : Invaild param");
807 snprintf(infoText, sizeof(infoText), "\tSelect the encoding type of %s : ", dataType);
811 PRINT_NORMAL("\n\n");
812 PRINT_NORMAL("\t%d. %s\n", OIC_ENCODING_RAW, "OIC_ENCODING_RAW");
813 PRINT_NORMAL("\t%d. %s\n", OIC_ENCODING_BASE64, "OIC_ENCODING_BASE64");
814 PRINT_NORMAL("\t%d. %s\n", OIC_ENCODING_PEM, "OIC_ENCODING_PEM");
815 PRINT_NORMAL("\t%d. %s\n", OIC_ENCODING_DER, "OIC_ENCODING_DER");
816 credEncType = InputNumber(infoText);
817 switch ( (OicEncodingType_t)credEncType )
819 case OIC_ENCODING_RAW:
821 case OIC_ENCODING_BASE64:
823 case OIC_ENCODING_PEM:
825 case OIC_ENCODING_DER:
828 PRINT_ERR("Invaild encoding type");
833 while (0 == credEncType);
835 *encoding = (OicEncodingType_t)credEncType;
840 static int InputCredSubject(OicUuid_t *uuid)
843 OicUuid_t emptyUuid = {.id = {0}};
845 "\tInput the Subject UUID for this access (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
846 ret = InputUuid(uuid);
849 PRINT_ERR("InputUuid failed");
853 if (0 == memcmp(emptyUuid.id, (*uuid).id, sizeof((*uuid).id) ) )
855 PRINT_ERR("Cred Subject UUID can't be empty uuid");
861 static int InputPSK(OicSecKey_t *secKey)
867 uint32_t outSize = 0;
869 data = InputString("\tInput encoded base64 psk (decoded psk 128 or 256 bits,\n"
870 "\te.g. BxjJidB+u21QlEwMCYBoKA== ) : ");
873 PRINT_ERR("Failed InputString");
877 psklen = strlen(data);
878 bufSize = B64DECODE_OUT_SAFESIZE(psklen + 1);
879 buf = OICCalloc(1, bufSize);
882 PRINT_ERR("Failed to allocate memory");
886 //validate base64 psk
887 if (B64_OK != b64Decode(data, psklen, buf, bufSize, &outSize))
889 PRINT_ERR("Failed to decode base64 data. Invalid base64 input");
894 if (!(OWNER_PSK_LENGTH_128 == outSize || OWNER_PSK_LENGTH_256 == outSize))
896 PRINT_ERR("Invalid key size");
901 secKey->data = (uint8_t *)data;
902 secKey->encoding = OIC_ENCODING_BASE64;
903 secKey->len = psklen;
908 static int InputCredentialData(OicSecCred_t *cred)
910 uint8_t *certChain = NULL;
911 uint8_t *privateKey = NULL;
912 uint8_t *publicKey = NULL;
913 size_t certChainSize = 0;
914 size_t privateKeySize = 0;
915 size_t publicKeySize = 0;
917 PRINT_PROG("\n\nPlease input the each entity of new credential.\n");
919 PRINT_NORMAL("\t%3d. Symmetric pair wise key\n", SYMMETRIC_PAIR_WISE_KEY);
920 PRINT_NORMAL("\t%3d. Symmetric group key\n", SYMMETRIC_GROUP_KEY);
921 PRINT_NORMAL("\t%3d. Asymmetric key\n", ASYMMETRIC_KEY);
922 PRINT_NORMAL("\t%3d. Signed asymmetric key\n", SIGNED_ASYMMETRIC_KEY);
923 PRINT_NORMAL("\t%3d. PIN/Password\n", PIN_PASSWORD);
924 PRINT_NORMAL("\t%3d. Asymmetric encryption key\n", ASYMMETRIC_ENCRYPTION_KEY);
925 cred->credType = (OicSecCredType_t)InputNumber("\tSelect the credential type : ");
926 if (SYMMETRIC_PAIR_WISE_KEY != cred->credType &&
927 SYMMETRIC_GROUP_KEY != cred->credType &&
928 SIGNED_ASYMMETRIC_KEY != cred->credType &&
929 PIN_PASSWORD != cred->credType &&
930 ASYMMETRIC_ENCRYPTION_KEY != cred->credType)
932 PRINT_ERR("Invaild credential type");
936 //Input the key data according to credential type
937 switch (cred->credType)
939 case SYMMETRIC_PAIR_WISE_KEY:
941 PRINT_PROG("\tSubject UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
942 if (0 != InputCredSubject(&cred->subject))
944 PRINT_ERR("InputCredSubject failed");
947 if (0 != InputPSK(&cred->privateData))
949 PRINT_ERR("Failed InputPSK");
954 case SYMMETRIC_GROUP_KEY:
956 PRINT_INFO("Not supported yet.");
961 PRINT_INFO("Not supported yet.");
964 case SIGNED_ASYMMETRIC_KEY:
966 if ( 0 != InputCredUsage(&cred->credUsage))
968 PRINT_ERR("Failed InputCredUsage");
972 //Input the other data according to credential usage.
973 if (0 == strcmp(cred->credUsage, TRUST_CA) ||
974 0 == strcmp(cred->credUsage, MF_TRUST_CA))
977 if (0 != GetDoxmDevID(&doxmUuid))
979 PRINT_ERR("Failed get doxm device id");
983 memcpy(cred->subject.id, doxmUuid.id, sizeof(doxmUuid.id));
987 if ( 0 != InputCredEncodingType("certificate chain", &cred->optionalData.encoding))
989 PRINT_ERR("Failed InputCredEncodingType");
993 //Read chain data from file (readed data will be saved to optional data)
994 if (0 != ReadDataFromFile("\tInput the certificate chain path : ", &certChain, &certChainSize))
996 PRINT_ERR("Failed ReadDataFromFile");
1001 if (OIC_ENCODING_PEM == cred->optionalData.encoding)
1003 cred->optionalData.data = (uint8_t *)OICCalloc(1, certChainSize + 1);
1004 if (NULL == cred->optionalData.data)
1006 PRINT_ERR("InputCredentialData : Failed to allocate memory.");
1009 cred->optionalData.len = certChainSize + 1;
1013 cred->optionalData.data = (uint8_t *)OICCalloc(1, certChainSize);
1014 if (NULL == cred->optionalData.data)
1016 PRINT_ERR("InputCredentialData : Failed to allocate memory.");
1019 cred->optionalData.len = certChainSize;
1021 memcpy(cred->optionalData.data, certChain, certChainSize);
1022 cred->optionalData.revstat = false;
1024 else if (0 == strcmp(cred->credUsage, PRIMARY_CERT) ||
1025 0 == strcmp(cred->credUsage, MF_PRIMARY_CERT))
1028 if (0 != GetDoxmDevID(&doxmUuid))
1030 PRINT_ERR("Failed get doxm device id");
1034 memcpy(cred->subject.id, doxmUuid.id, sizeof(doxmUuid.id));
1039 if ( 0 != InputCredEncodingType(YELLOW_BEGIN"Private key"COLOR_END, &cred->privateData.encoding))
1041 PRINT_ERR("Failed InputCredEncodingType");
1045 if (OIC_ENCODING_RAW != cred->privateData.encoding)
1047 PRINT_ERR("Not supported encoding type for private key");
1051 //Read private key data from file
1052 if (0 != ReadDataFromFile("\tInput the private key's path : ", &privateKey, &privateKeySize))
1054 PRINT_ERR("Failed ReadDataFromFile");
1058 cred->privateData.data = OICCalloc(1, privateKeySize);
1059 if (NULL == cred->privateData.data)
1061 PRINT_ERR("InputCredentialData : Failed to allocate memory.");
1064 memcpy(cred->privateData.data, privateKey, privateKeySize);
1065 cred->privateData.len = privateKeySize;
1069 if ( 0 != InputCredEncodingType(YELLOW_BEGIN"Certificate"COLOR_END, &cred->publicData.encoding))
1071 PRINT_ERR("Failed InputCredEncodingType");
1075 if (OIC_ENCODING_DER != cred->publicData.encoding &&
1076 OIC_ENCODING_PEM != cred->publicData.encoding)
1078 PRINT_ERR("Not supported encoding type for private key");
1082 //Read certificate data from file
1083 if (0 != ReadDataFromFile("\tInput the certificate's path : ", &publicKey, &publicKeySize))
1085 PRINT_ERR("Failed ReadDataFromFile");
1089 if (OIC_ENCODING_PEM == cred->publicData.encoding)
1091 cred->publicData.data = OICCalloc(1, publicKeySize + 1);
1092 if (NULL == cred->publicData.data)
1094 PRINT_ERR("InputCredentialData : Failed to allocate memory.");
1097 cred->publicData.len = publicKeySize + 1;
1101 cred->publicData.data = OICCalloc(1, publicKeySize);
1102 if (NULL == cred->publicData.data)
1104 PRINT_ERR("InputCredentialData : Failed to allocate memory.");
1107 cred->publicData.len = publicKeySize;
1109 memcpy(cred->publicData.data, publicKey, publicKeySize);
1113 // TODO: T.B.D : Data type should be selected by user.
1114 PRINT_ERR("Not supported yet.");
1120 char pinPass[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
1122 PRINT_NORMAL("\tSubject UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
1123 if (0 != InputCredSubject(&cred->subject))
1125 PRINT_ERR("InputCredSubject failed");
1129 PRINT_NORMAL("\tInput the PIN or Password : ");
1130 for (int ret = 0; 1 != ret; )
1132 ret = scanf("%32s", pinPass);
1133 for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
1134 // '0x20<=code' is character region
1136 cred->privateData.data = (uint8_t *)OICStrdup(pinPass);
1137 if (NULL == cred->privateData.data)
1139 PRINT_ERR("Failed OICStrdup");
1142 cred->privateData.len = strlen((char *)cred->privateData.data);
1143 cred->privateData.encoding = OIC_ENCODING_RAW;
1146 case ASYMMETRIC_ENCRYPTION_KEY:
1148 PRINT_INFO("Not supported yet.");
1152 PRINT_ERR("Invalid credential type");
1157 OICFree(privateKey);
1163 OICFree(privateKey);
1165 memset(cred, 0x00, sizeof(OicSecCred_t));
1169 static int ModifyCred(void)
1171 OCStackResult credResult = OC_STACK_ERROR;
1174 OicSecCred_t *cred = NULL;
1175 uint16_t credId = 0;
1176 OicUuid_t uuid = {.id = {0}};
1177 OicSecKey_t key = {0};
1179 PRINT_PROG("\n\nPlease select the menu you want to modify\n");
1180 PRINT_DATA("\t%2d. Edit subjectuuid\n", CRED_EDIT_SUBJECTUUID);
1181 PRINT_DATA("\t%2d. Edit psk of symmetric cred\n", CRED_EDIT_PSK);
1182 PRINT_DATA("\t%2d. Edit rowner uuid\n", CRED_EDIT_ROWNERUUID);
1183 PRINT_DATA("\t%2d. Back to the previous\n", BACK);
1184 modifyMenu = InputNumber("Select the menu : ");
1187 case CRED_EDIT_SUBJECTUUID:
1188 PrintCredList(GetCredList());
1189 credId = (uint16_t)InputNumber("\tPlease input the credential ID : ");
1190 cred = GetCredEntryByCredId(credId);
1193 PRINT_ERR("Invalid credId");
1197 if (0 != InputCredSubject(&uuid))
1199 PRINT_ERR("InputCredSubject failed");
1200 DeleteCredList(cred);
1204 if (0 == memcmp(cred->subject.id, uuid.id, sizeof(cred->subject.id)))
1206 PRINT_ERR("Please input different uuid from the selected cred's uuid");
1207 DeleteCredList(cred);
1210 memcpy(cred->subject.id, uuid.id , sizeof(cred->subject.id));
1212 credResult = AddCredential(cred);
1213 if (OC_STACK_OK != credResult)
1215 PRINT_ERR("AddCredential : %d", credResult);
1216 DeleteCredList(cred);
1219 credResult = RemoveCredentialByCredId(credId);
1220 if ( OC_STACK_RESOURCE_DELETED != credResult)
1222 PRINT_ERR("RemoveCredentialByCredId error : %d" , credResult);
1228 PrintCredList(GetCredList());
1229 credId = (uint16_t)InputNumber("\tPlease input the credential ID : ");
1230 cred = GetCredEntryByCredId(credId);
1233 PRINT_ERR("Invalid credId");
1236 if (SYMMETRIC_PAIR_WISE_KEY != cred->credType)
1238 PRINT_ERR("Selected cred is not SYMMETRIC_PAIR_WISE_KEY type\n");
1239 DeleteCredList(cred);
1242 if (0 != InputPSK(&key))
1244 PRINT_ERR("Failed InputPSK");
1245 DeleteCredList(cred);
1248 if (key.len == cred->privateData.len &&
1249 key.encoding == cred->privateData.encoding &&
1250 0 == memcmp(key.data, cred->privateData.data, key.len))
1252 PRINT_ERR("Please input different psk from the selected cred's psk");
1254 DeleteCredList(cred);
1257 cred->privateData = key;
1259 credResult = AddCredential(cred);
1260 if (OC_STACK_OK != credResult)
1262 PRINT_ERR("AddCredential : %d", credResult);
1263 DeleteCredList(cred);
1266 credResult = RemoveCredentialByCredId(credId);
1267 if ( OC_STACK_RESOURCE_DELETED != credResult)
1269 PRINT_ERR("RemoveCredentialByCredId error : %d" , credResult);
1274 case CRED_EDIT_ROWNERUUID:
1276 "\tInput the ROWNER UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
1277 ret = InputUuid(&uuid);
1280 PRINT_ERR("InputUuid failed");
1283 credResult = SetCredRownerId(&uuid);
1284 if (OC_STACK_OK != credResult)
1286 PRINT_ERR("SetCredRownerId failed");
1291 PRINT_INFO("Back to the previous menu.");
1294 PRINT_ERR("Wrong type Number");
1301 void HandleCredOperation(SubOperationType_t cmd)
1303 uint16_t credId = 0;
1304 OCStackResult credResult = OC_STACK_ERROR;
1306 if (SVR_EDIT_IDX_SIZE <= cmd)
1308 PRINT_ERR("Invalid menu for credential");
1314 PrintCredList(GetCredList());
1318 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
1321 PRINT_ERR("Failed to allocate memory");
1325 if (0 != InputCredentialData(cred))
1327 PRINT_ERR("Failed to InputCredentialData");
1328 DeleteCredList(cred);
1332 credResult = AddCredential(cred);
1333 if ( OC_STACK_OK != credResult)
1335 PRINT_ERR("AddCredential error : %d" , credResult);
1336 DeleteCredList(cred);
1342 PrintCredList(GetCredList());
1343 credId = (uint16_t)InputNumber("\tPlease input the credential ID : ");
1345 credResult = RemoveCredentialByCredId(credId);
1346 if ( OC_STACK_RESOURCE_DELETED != credResult)
1348 PRINT_ERR("RemoveCredentialByCredId error : %d" , credResult);
1353 if (0 != ModifyCred())
1355 PRINT_ERR("Failed Modification");
1358 PRINT_INFO("\n\nCred Modified");