static void test_errors(void) { cbor_failure tests[] = { {"81", CN_CBOR_ERR_OUT_OF_DATA}, {"0000", CN_CBOR_ERR_NOT_ALL_DATA_CONSUMED}, {"bf00ff", CN_CBOR_ERR_ODD_SIZE_INDEF_MAP}, {"ff", CN_CBOR_ERR_BREAK_OUTSIDE_INDEF}, {"1f", CN_CBOR_ERR_MT_UNDEF_FOR_INDEF}, {"1c", CN_CBOR_ERR_RESERVED_AI}, {"7f4100", CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING}, }; cn_cbor inv = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL}; TEST_ASSERT_EQUAL_INT(-1, cn_cbor_encoder_write(ebuf, 0, sizeof(ebuf), &inv)); for (offs = 0; offs < sizeof(tests) / sizeof(cbor_failure); offs++) { unsigned char buf[32] = {0}; TEST_ASSERT((strlen(tests[offs].hex)/2) <= sizeof(buf)); size_t len = fmt_hex_bytes(buf, tests[offs].hex); TEST_ASSERT(len); cn_cbor *cbor = cn_cbor_decode(buf, len, &ct, &errb); TEST_ASSERT_NULL(cbor); TEST_ASSERT_EQUAL_INT(errb.err, tests[offs].err); cn_cbor_free(cbor, &ct); } }
bool _COSE_Init_From_Object(COSE* pobj, cn_cbor * pcbor, CBOR_CONTEXT_COMMA cose_errback * perr) { const cn_cbor * pmap = NULL; cn_cbor_errback errState; // = { 0 }; #ifdef TAG_IN_ARRAY cn_cbor * cbor; #endif // TAG_IN_ARRAY #ifdef USE_CBOR_CONTEXT if (context != NULL) pobj->m_allocContext = *context; #endif pobj->m_cborRoot = pcbor; pobj->m_cbor = pcbor; #ifdef TAG_IN_ARRAY cbor = cn_cbor_index(pobj->m_cbor, 0); CHECK_CONDITION(cbor != NULL, COSE_ERR_INVALID_PARAMETER); if (cbor->type == CN_CBOR_UINT) { pobj->m_msgType = (int) cbor->v.uint; } #else // Check if we have a tag if (pcbor->type == CN_CBOR_TAG) { pcbor = pobj->m_cbor = pcbor->first_child; } #endif pmap = _COSE_arrayget_int(pobj, INDEX_PROTECTED); CHECK_CONDITION(pmap != NULL, COSE_ERR_INVALID_PARAMETER); if (pmap != NULL) { CHECK_CONDITION(pmap->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER); if (pmap->length == 0) { pobj->m_protectedMap = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA NULL); CHECK_CONDITION(pobj->m_protectedMap, COSE_ERR_OUT_OF_MEMORY); } else { pobj->m_protectedMap = cn_cbor_decode((const byte *)pmap->v.str, pmap->length, CBOR_CONTEXT_PARAM_COMMA &errState); CHECK_CONDITION(pobj->m_protectedMap != NULL, COSE_ERR_INVALID_PARAMETER); } } pobj->m_unprotectMap = _COSE_arrayget_int(pobj, INDEX_UNPROTECTED); CHECK_CONDITION((pobj->m_unprotectMap != NULL) && (pobj->m_unprotectMap->type == CN_CBOR_MAP), COSE_ERR_INVALID_PARAMETER); pobj->m_ownUnprotectedMap = false; pobj->m_ownMsg = true; pobj->m_refCount = 1; return true; errorReturn: _COSE_Release(pobj); return false; }
LS_API bool spud_parse(const uint8_t* payload, size_t length, spud_message* msg, ls_err* err) { cn_cbor_errback cbor_err; if ( (payload == NULL) || (msg == NULL) || !spud_is_spud(payload, length) ) { LS_ERROR(err, LS_ERR_INVALID_ARG); return false; } msg->header = (spud_header*)payload; if ( length > sizeof(spud_header) ) { msg->cbor = cn_cbor_decode(payload + sizeof(spud_header), length - sizeof(spud_header), NULL, &cbor_err); if (!msg->cbor) { if (err != NULL) { err->code = LS_ERR_USER + cbor_err.err; err->message = cn_cbor_error_str[cbor_err.err]; err->function = __func__; err->file = __FILE__; err->line = __LINE__; } return false; } } else { msg->cbor = NULL; } return true; }
static void test_parse(void) { char *tests[] = { "00", // 0 "01", // 1 "17", // 23 "1818", // 24 "190100", // 256 "1a00010000", // 65536 #ifndef CBOR_NO_LL "1b0000000100000000", // 4294967296 #endif /* CBOR_NO_LL */ "20", // -1 "37", // -24 "3818", // -25 "390100", // -257 "3a00010000", // -65537 #ifndef CBOR_NO_LL "3b0000000100000000", // -4294967297 #endif /* CBOR_LL */ "4161", // h"a" "6161", // "a" "80", // [] "8100", // [0] "820102", // [1,2] "818100", // [[0]] "a1616100", // {"a":0} "d8184100", // tag "f4", // false "f5", // true "f6", // null "f7", // undefined "f8ff", // simple(255) #ifndef CBOR_NO_FLOAT "f93c00", // 1.0 "f9bc00", // -1.0 "f903ff", // 6.097555160522461e-05 "f90400", // 6.103515625e-05 "f907ff", // 0.00012201070785522461 "f90800", // 0.0001220703125 "fa47800000", // 65536.0 "fb3ff199999999999a", // 1.1 "f97e00", // NaN #endif /* CBOR_NO_FLOAT */ "5f42010243030405ff", // (_ h'0102', h'030405') "7f61616161ff", // (_ "a", "a") "9fff", // [_ ] "9f9f9fffffff", // [_ [_ [_ ]]] "9f009f00ff00ff", // [_ 0, [_ 0], 0] "bf61610161629f0203ffff", // {_ "a": 1, "b": [_ 2, 3]} }; for (test = 0; test < sizeof(tests) / sizeof(char*); test++) { unsigned char buf[64] = {0}; TEST_ASSERT((strlen(tests[test])/2) <= sizeof(buf)); size_t len = fmt_hex_bytes(buf, tests[test]); TEST_ASSERT(len); errb.err = CN_CBOR_NO_ERROR; cn_cbor *cbor = cn_cbor_decode(buf, len, &ct, &errb); TEST_ASSERT_EQUAL_INT(errb.err, CN_CBOR_NO_ERROR); TEST_ASSERT_NOT_NULL(cbor); cn_cbor_encoder_write(ebuf, 0, sizeof(ebuf), cbor); for (offs = 0; offs < len; offs++) { TEST_ASSERT_EQUAL_INT(buf[offs], ebuf[offs]); } cn_cbor_free(cbor, &ct); } }
int main(int argc, char ** argv) { int i; FILE * in = NULL; FILE * out = NULL; byte * pb = NULL; size_t cb = 0; byte rgb[2048]; size_t cbIn; int forXML = false; FOO * root = NULL; for (i=1; i<argc; i++) { if ((argv[i][0] == '-') || (argv[i][0] == '/')) { if (strcmp(&argv[i][1], "someoption") == 0) { } else if (strcmp(&argv[i][1], "xml=yes") == 0) { forXML = true; } else if (strcmp(&argv[i][1], "xml=no") == 0) forXML = false; else if (strncmp(&argv[i][1], "wrap=", 5) == 0) { WrapLineAt = atoi(&argv[i][6]); } else if (strncmp(&argv[i][1], "type=", 5) == 0) { if (strcmp(&argv[i][1], "type=encrypt") == 0) root = &EncryptedMessage; else if (strcmp(&argv[i][1], "type=envelope") == 0) root = &EnvelopedMessage; else if (strcmp(&argv[i][1], "type=signed") == 0) root = &SignedMessage; else if (strcmp(&argv[i][1], "type=mac") == 0) root = &MacMessage; else if (strcmp(&argv[i][1], "type=mac0") == 0) root = &Mac0Message; else if (strcmp(&argv[i][1], "type=keyset") == 0) root = &KeySet; else if (strcmp(&argv[i][1], "type=key") == 0) root = &Key; else PrintUsage(); } else { PrintUsage(); exit(1); } } else { if (in == NULL) { in = fopen(argv[i], "rb"); if (in == NULL) { fprintf(stderr, "Unable to open file '%s'\n", argv[i]); exit(1); } } else if (out == NULL) { out = fopen(argv[i], "wt"); if (out == NULL) { fprintf(stderr, "Unable to open file '%s'\n", argv[i]); exit(1); } } else { PrintUsage(); exit(1); } } } // Set defaults if (in == NULL) { #ifdef _WIN32 in = stdin; _setmode(_fileno(stdin), _O_BINARY); #else in = stdin; // fdreopen(_fileno(stdin), NULL, O_RDONLY | OPEN_O_BINARY); #endif } if (out == NULL) out = stdout; // Read the input to a buffer - needed for the parser cbIn = 1; while (cbIn > 0) { cbIn = fread(rgb, 1, sizeof(rgb), in); if (cbIn == 0) { // finished break; } pb = realloc(pb, cb+cbIn); if (pb == NULL) { fprintf(stderr, "Error allocating memory\n"); exit(1); } memcpy(pb+cb, rgb, cbIn); cb += cbIn; } // Parse it cn_cbor * cbor = cn_cbor_decode(pb, cb CBOR_CONTEXT_PARAM, NULL); if (cbor == NULL) { fprintf(stderr, "Error parsing CBOR"); exit(1); } if (root == NULL) { if (cbor->type == CN_CBOR_TAG) { switch (cbor->v.sint) { case 98: root = &SignedMessageWithTag; break; case 96: root = &EnvelopedMessageWithTag; break; case 16: root = &EncryptedMessageWithTag; break; case 97: root = &MacMessageWithTag; break; case 17: root = &Mac0MessageWithTag; break; case 18: root = &Sign0MessageWithTag; break; } } } if (forXML) { fprintf(out, "<t>Size of binary file is %lu bytes</t>\n\n", (unsigned long) cb); fprintf(out, "<figure><artwork type='CBORdiag'><![CDATA[\n"); } DumpTree(cbor, out, root, 0, true, true, false); WrapPrintF(out, "\n"); if (forXML) { fprintf(out, "]]></artwork></figure>\n"); } }
void DumpTree(const cn_cbor * cbor, FILE * out, const FOO *pFOO, int depth, int fField, int fValue, int fInComment) { int i; int i2; const cn_cbor * cbor2; const FOO * pFoo2; int group; if (pFOO != NULL) { switch (pFOO->type) { case CN_CBOR_TAG: if (cbor->type != CN_CBOR_TAG) pFOO = NULL; break; default: break; } } if (fField && (pFOO != NULL) && (pFOO->fieldName != NULL)) { if (fInComment) WrapPrintF(out, "\\ %s \\ ", pFOO -> fieldName); else WrapPrintF(out, "/ %s / ", pFOO->fieldName); } switch (cbor->type) { case CN_CBOR_TAG: WrapPrintF(out, "%u(\n", cbor->v.uint); Indent(out, depth + 1); DumpTree(cbor->last_child, out, pFOO != NULL ? pFOO->children : NULL, depth+1, true, true, fInComment); WrapPrintF(out, "\n"); Indent(out, depth); WrapPrintF(out, ")"); break; case CN_CBOR_ARRAY: WrapPrintF(out, "["); cbor2 = cbor->first_child; for (i = 0; i < cbor->length; i++, cbor2 = cbor2->next) { if (i != 0) WrapPrintF(out, ", "); if (pFOO == NULL) pFoo2 = NULL; else if (pFOO->count == 1) pFoo2 = pFOO->children; else if (i >= pFOO->count) pFoo2 = NULL; else pFoo2 = &pFOO->children[i]; WrapPrintF(out, "\n"); Indent(out, depth + 1); DumpTree(cbor2, out, pFoo2, depth + 1, true, true, fInComment); } if (i > 0) { WrapPrintF(out, "\n"); Indent(out, depth); } WrapPrintF(out, "]"); break; case CN_CBOR_MAP: WrapPrintF(out, "{"); cbor2 = cbor->first_child; // Determine the correct group - always assume it is at element UINT=1 group = 0; for (i = 0; i < cbor->length; i+=2, cbor2 = cbor2->next->next) { if ((cbor2->type == CN_CBOR_UINT) && (cbor2->v.uint == 1)) { group = (int) cbor2->next->v.uint; break; } } cbor2 = cbor->first_child; // Dump each element for (i = 0; i < cbor->length; i+=2, cbor2 = cbor2->next) { pFoo2 = NULL; if (pFOO != NULL) { // Locate the right entry in foo for (i2 = 0, pFoo2 = pFOO->children; i2 < pFOO->count; pFoo2++, i2 += 1) { if (pFoo2->type != cbor2->type) continue; switch (cbor2->type) { case CN_CBOR_UINT: if ((group != 0) && (pFoo2->group != 0) && (pFoo2->group != group)) continue; if (pFoo2->value == (int) cbor2->v.uint) i2 = pFOO->count + 1; break; case CN_CBOR_INT: if ((group != 0) && (pFoo2->group != 0) && (pFoo2->group != group)) continue; if (pFoo2->value == cbor2->v.sint) i2 = pFOO->count + 1; break; default: // Should assert here? break; } if (i2 == pFOO->count + 1) break; } if (i2 == pFOO->count) pFoo2 = NULL; } if (i != 0) WrapPrintF(out, ", "); WrapPrintF(out, "\n"); Indent(out, depth + 1); DumpTree(cbor2, out, pFoo2, depth + 1, true, false, fInComment); WrapPrintF(out, ":"); cbor2 = cbor2->next; DumpTree(cbor2, out, pFoo2, depth + 1, false, true, fInComment); } if (i > 0) { WrapPrintF(out, "\n"); Indent(out, depth); } WrapPrintF(out, "}"); break; case CN_CBOR_BYTES: DumpBytes(out, cbor); if ((pFOO != NULL) && (pFOO->children != NULL)) { const cn_cbor * cbor3 = cn_cbor_decode(cbor->v.bytes, cbor->length CBOR_CONTEXT_PARAM, NULL); if (cbor3 != NULL) { WrapPrintF(out, fInComment ? " \\ " : " / "); DumpTree(cbor3, out, pFOO->children, depth+1, true, true, true); WrapPrintF(out, fInComment ? " \\ " : " / "); } } break; case CN_CBOR_INT: WrapPrintF(out, "%d", cbor->v.sint); if (fValue && pFOO != NULL) { for (i = 0, pFoo2 = pFOO->children; i < pFOO->count; i++, pFoo2++) { if ((pFoo2->type == CN_CBOR_INT) && (pFoo2->value == cbor->v.sint)) { if (pFoo2->fieldName != NULL) { if (fInComment) WrapPrintF(out, " \\ %s \\", pFoo2->fieldName); else WrapPrintF(out, " / %s /", pFoo2->fieldName); } break; } } } break; case CN_CBOR_UINT: WrapPrintF(out, "%u", cbor->v.uint); if (fValue && (pFOO != NULL)) { for (i = 0, pFoo2 = pFOO->children; i < pFOO->count; i++, pFoo2++) { if ((pFoo2->type == CN_CBOR_UINT) && (pFoo2->value == (int) cbor->v.uint)) { if (pFoo2->fieldName != NULL) { if (fInComment) WrapPrintF(out, " \\ %s \\", pFoo2->fieldName); else WrapPrintF(out, " / %s /", pFoo2->fieldName); } break; } } } break; case CN_CBOR_TEXT: WrapPrintF(out, "\""); for (i = 0; i < cbor->length; i++) { if (fInComment && (cbor->v.str[i] == '/')) { WrapPrintF(out, "%c", cbor->v.str[i]); } WrapPrintF(out, "%c", cbor->v.str[i]); } WrapPrintF(out, "\""); break; case CN_CBOR_TRUE: WrapPrintF(out, "true"); break; case CN_CBOR_FALSE: WrapPrintF(out, "false"); break; default: WrapPrintF(out, "##"); break; } }
HCOSE COSE_Decode(const byte * rgbData, size_t cbData, int * ptype, COSE_object_type struct_type, CBOR_CONTEXT_COMMA cose_errback * perr) { cn_cbor * cbor = NULL; cn_cbor * cborRoot = NULL; #ifdef TAG_IN_ARRAY const cn_cbor * pType = NULL; #endif cn_cbor_errback cbor_err; HCOSE h; CHECK_CONDITION((rgbData != NULL) && (ptype != NULL), COSE_ERR_INVALID_PARAMETER); cbor = cborRoot = cn_cbor_decode(rgbData, cbData, CBOR_CONTEXT_PARAM_COMMA &cbor_err); CHECK_CONDITION_CBOR(cbor != NULL, cbor_err); #ifdef TAG_IN_ARRAY CHECK_CONDITION(cbor->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER); pType = cn_cbor_index(cbor, 0); CHECK_CONDITION(((pType != NULL) && (pType->type == CN_CBOR_UINT)), COSE_ERR_INVALID_PARAMETER); *ptype = pType->v.sint; #else // ! TAG_IN_ARRAY if (cbor->type == CN_CBOR_TAG) { if (struct_type != 0) { CHECK_CONDITION(struct_type == (COSE_object_type) cbor->v.sint, COSE_ERR_INVALID_PARAMETER); } else struct_type = cbor->v.uint; *ptype = struct_type; cbor = cbor->first_child; } else { *ptype = struct_type; } CHECK_CONDITION(cbor->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER); #endif // TAG_IN_ARRAY switch (*ptype) { case COSE_enveloped_object: h = (HCOSE)_COSE_Enveloped_Init_From_Object(cbor, NULL, CBOR_CONTEXT_PARAM_COMMA perr); if (h == NULL) { goto errorReturn; } break; case COSE_sign_object: h = (HCOSE)_COSE_Sign_Init_From_Object(cborRoot, NULL, CBOR_CONTEXT_PARAM_COMMA perr); if (h == NULL) { goto errorReturn; } break; case COSE_sign0_object: h = (HCOSE)_COSE_Sign0_Init_From_Object(cborRoot, NULL, CBOR_CONTEXT_PARAM_COMMA perr); if (h == NULL) { goto errorReturn; } break; case COSE_mac_object: h = (HCOSE)_COSE_Mac_Init_From_Object(cbor, NULL, CBOR_CONTEXT_PARAM_COMMA perr); if (h == NULL) { goto errorReturn; } break; case COSE_mac0_object: h = (HCOSE)_COSE_Mac0_Init_From_Object(cbor, NULL, CBOR_CONTEXT_PARAM_COMMA perr); if (h == NULL) { goto errorReturn; } break; case COSE_encrypt_object: h = (HCOSE)_COSE_Encrypt_Init_From_Object(cbor, NULL, CBOR_CONTEXT_PARAM_COMMA perr); if (h == NULL) { goto errorReturn; } break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } return h; errorReturn: COSE_FREE(cbor, context); return NULL; }