Example #1
0
/**
 * \test Check we handle events correctly
 */
int DecodeAsn1Test09(void) {
    uint8_t *str = (uint8_t *) "\x3F\x84\x06\x80\xAB\xCD\xEF";

    Asn1Ctx *ac = SCAsn1CtxNew();
    if (ac == NULL)
        return 0;
    uint8_t ret = 1;

    uint16_t len = 7;

    SCAsn1CtxInit(ac, str, len);

    SCAsn1Decode(ac, ac->cur_frame);
    Asn1Node *node = ASN1CTX_GET_NODE(ac, 0);
    if ( !(ac->ctx_flags & ASN1_BER_EVENT_EOC_NOT_FOUND)
        || !(node->flags & ASN1_BER_EVENT_EOC_NOT_FOUND))
    {
        ret = 0;
        printf("Error, expected eoc not found, got flags %"PRIu8": ", ac->ctx_flags);
        goto end;
    }

end:
    SCAsn1CtxDestroy(ac);
    return ret;
}
Example #2
0
/**
 * \test Check we handle events correctly
 */
int DecodeAsn1Test08(void) {
    uint8_t *str = (uint8_t *) "\x3F\x84\x06\x81\xFF";

    Asn1Ctx *ac = SCAsn1CtxNew();
    if (ac == NULL)
        return 0;
    uint8_t ret = 1;

    uint16_t len = 5;

    SCAsn1CtxInit(ac, str, len);

    SCAsn1Decode(ac, ac->cur_frame);
    Asn1Node *node = ASN1CTX_GET_NODE(ac, 0);
    if ( !(ac->ctx_flags & ASN1_BER_EVENT_INVALID_LEN)
        || !(node->flags & ASN1_BER_EVENT_INVALID_LEN))
    {
        ret = 0;
        printf("Error, expected invalid length, got flags %"PRIu8": ", ac->ctx_flags);
        goto end;
    }

end:
    SCAsn1CtxDestroy(ac);
    return ret;
}
Example #3
0
/**
 * \test Check we handle short lengths correctly
 */
int DecodeAsn1Test06(void)
{
    uint8_t *str = (uint8_t *) "\x3F\x84\x06\x26";

    Asn1Ctx *ac = SCAsn1CtxNew();
    if (ac == NULL)
        return 0;
    uint8_t ret = 1;

    uint16_t len = 4;

    SCAsn1CtxInit(ac, str, len);

    SCAsn1Decode(ac, ac->cur_frame);
    Asn1Node *node = ASN1CTX_GET_NODE(ac, 0);
    if (node->len.len != 38) {
        ret = 0;
        printf("Error, expected length 10, got %"PRIu32": ", node->len.len);
        goto end;
    }

end:
    SCAsn1CtxDestroy(ac);
    return ret;
}
Example #4
0
/**
 * \test Check we handle short identifiers correctly
 */
int DecodeAsn1Test03(void)
{
    uint8_t *str = (uint8_t *) "\x28";

    Asn1Ctx *ac = SCAsn1CtxNew();
    if (ac == NULL)
        return 0;
    uint8_t ret = 1;

    uint16_t len = 1;

    SCAsn1CtxInit(ac, str, len);

    SCAsn1Decode(ac, ac->cur_frame);
    Asn1Node *node = ASN1CTX_GET_NODE(ac, 0);
    if (node->id.tag_num != 8) {
        ret = 0;
        printf("Error, expected tag_num 10, got %"PRIu32": ", node->id.tag_num);
        goto end;
    }

end:
    SCAsn1CtxDestroy(ac);
    return ret;
}
Example #5
0
/**
 * \test Decode a big chunk of data
 */
int DecodeAsn1Test10(void) {
    // Example from the specification X.690-0207 Appendix A.3
    uint8_t *str = (uint8_t *) "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01"
                   "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director"
                   "\x42\x01\x33\xA1\x0A\x43\x08""19710917"
                   "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05"
                   "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01"
                   "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111"
                   "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05"
                   "Jones""\xA0\x0A\x43\x08""19590717"
                   "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01""P"
                   "\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director"
                   "\x42\x01\x33\xA1\x0A\x43\x08""19710917"
                   "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05"
                   "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01"
                   "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111""\x31\x1F"
                   "\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05""Jones"
                   "\xA0\x0A\x43\x08""19590717";

    Asn1Ctx *ac = SCAsn1CtxNew();
    if (ac == NULL)
        return 0;
    uint8_t ret = 1;

    uint16_t len = strlen((char *)str)-1;

    SCAsn1CtxInit(ac, str, len);

    ret = SCAsn1Decode(ac, ac->cur_frame);

    /* General checks */
    if (ret != ASN1_PARSER_OK) {
        printf("Error decoding asn1 data: ");
        ret = 0;
        goto end;
    }

    if (ac->cur_frame != 59) {
        printf("Error decoding asn1 data, not all the nodes"
               "were correctly decoded: ");
        ret = 0;
        goto end;
    }

    if (ac->iter != ac->end) {
        printf("Error decoding asn1 data, not all the nodes"
               "were correctly decoded: ");
        ret = 0;
        goto end;
    }

    Asn1Node *node = ASN1CTX_GET_NODE(ac, 0);
    if (node->len.len != 133) {
        printf("Error decoding asn1 data, not all the nodes"
               "were correctly decoded: ");
        ret = 0;
        goto end;
    }

    node = ASN1CTX_GET_NODE(ac, 30);
    if (node->len.len != 133) {
        printf("Error decoding asn1 data, not all the nodes"
               "were correctly decoded: ");
        ret = 0;
        goto end;
    }

end:
    SCAsn1CtxDestroy(ac);
    return ret;
}
Example #6
0
/**
 * \brief Decode the nodes/frames located at certain position/level
 *
 * \param ac pointer to the ASN1 ctx
 * \param node_id node index at the asn1 stack of the ctx
 *
 * \retval byte of parser status
 */
uint8_t SCAsn1Decode(Asn1Ctx *ac, uint16_t node_id) {
    Asn1Node *node = NULL;
    uint8_t ret = 0;

    /* while remaining data, and no fatal error, or end, or max stack frames */
    while (ac->iter < ac->end
           && !(ac->parser_status & ASN1_STATUS_DONE)
           && ac->cur_frame < asn1_max_frames_config)
    {
        /* Prepare a new frame */
        if (SCAsn1CtxNewFrame(ac, node_id) == NULL)
            break;

        ac->cur_frame = node_id;
        node = ASN1CTX_GET_NODE(ac, node_id);

        SCLogDebug("ASN1 Getting ID, cur:%x remaining %"PRIu32, (uint8_t)*ac->iter, (uint32_t)(ac->end - ac->iter));

        /* Get identifier/tag */
        ret = SCAsn1DecodeIdentifier(ac);
        if (ret == ASN1_PARSER_ERR) {
            SCLogDebug("Error parsing identifier");

            node->flags |= ASN1_BER_EVENT_INVALID_ID;
            ac->ctx_flags |= node->flags;

            break;
        }

        SCLogDebug("ASN1 Getting LEN");

        /* Get length of content */
        ret = SCAsn1DecodeLength(ac);
        if (ret == ASN1_PARSER_ERR) {
            SCLogDebug("Error parsing length");

            node->flags |= ASN1_BER_EVENT_INVALID_LEN;
            ac->ctx_flags |= node->flags;

            break;
        }

        if ( !(node->flags & ASN1_NODE_IS_EOC)) {
            SCLogDebug("ASN1 Getting CONTENT");

            /* Inspect content */
            ret = SCAsn1DecodeContent(ac);
            if (ret == ASN1_PARSER_ERR) {
                SCLogDebug("Error parsing content");

                break;
            }

            /* Skip to the next record (if any) */
            if (node->id.tag_type != ASN1_TAG_TYPE_CONSTRUCTED)
                /* Is primitive, skip it all (no need to decode it)*/
                ac->iter += node->data.len;
        }

        /* Check if we are done with data */
        ret = SCAsn1CheckBounds(ac);
        if (ret == ASN1_PARSER_ERR) {

            ac->parser_status |= ASN1_STATUS_DONE;
            /* There's no more data available */
            ret = ASN1_PARSER_OK;

            break;
        }
#if 0
        printf("Tag Num: %"PRIu32", Tag Type: %"PRIu8", Class:%"PRIu8", Length: %"PRIu32"\n", node->id.tag_num, node->id.tag_type, node->id.class_tag, node->len.len);
        printf("Data: \n");
        PrintRawDataFp(stdout, node->data.ptr, node->len.len);
        printf(" -- EOD --\n");
#endif

        /* Stack flags/events here, so we have the resume at the ctx flags */
        ac->ctx_flags |= node->flags;

        /* Check if it's not a primitive type,
         * then we need to decode contents */
        if (node->id.tag_type == ASN1_TAG_TYPE_CONSTRUCTED) {
            ret = SCAsn1Decode(ac, node_id + 1);
        } /* Else we have reached a primitive type and stop the recursion,
           * look if we have other branches at the same level */

        /* But first check if it's a constructed node, and the sum of child
         * lengths was more than the length of this frame
         * this would mean that we have an overflow at the attributes */
        if (ac->iter > node->data.ptr + node->data.len + 1) {
            /* We decoded more length on this frame */
        }

        node_id = ac->cur_frame + 1;
    }

    return ret;
}