예제 #1
0
/**
 * \brief Decode and check the identifier information of the
 *        current node that we are parsing, also check invalid opts
 *
 * \param ac pointer to the ASN1 Context data
 *
 * \retval byte of the status of the parser
 */
uint8_t SCAsn1DecodeIdentifier(Asn1Ctx *ac) {
    uint8_t ret = 0;
    ret = SCAsn1CheckBounds(ac);
    if (ret == ASN1_PARSER_ERR) {
        ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB;
        return ret;
    }

    Asn1Node *node = ASN1CTX_CUR_NODE(ac);
    /* Store the position */
    node->id.ptr = ac->iter;

    //SCPrintByteBin(*ac->iter);

    node->id.class_tag = ASN1_BER_GET_CLASS_TAG(*ac->iter);
    node->id.tag_type = ASN1_BER_IS_CONSTRUCTED(*ac->iter);

    if (ASN1_BER_IS_HIGH_TAG(*ac->iter)) {
        return SCAsn1GetHighTagNumber(ac);
    } else {
        node->id.tag_num = ASN1_BER_GET_LOW_TAG_NUM(*ac->iter);
        ac->iter++;
    }

    return ASN1_PARSER_OK;
}
예제 #2
0
/**
 * \brief Decode and check the length, of the current node
 *        that we are parsing, also check invalid opts
 *
 * \param ac pointer to the ASN1 Context data
 *
 * \retval byte of the status of the parser
 */
uint8_t SCAsn1DecodeLength(Asn1Ctx *ac) {
    uint8_t ret = 0;
    ret = SCAsn1CheckBounds(ac);
    if (ret == ASN1_PARSER_ERR) {
        ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB;
        return ASN1_PARSER_ERR;
    }

    Asn1Node *node = ASN1CTX_CUR_NODE(ac);
    /* Store the position */
    node->len.ptr = ac->iter;

    uint8_t len_byte = *ac->iter;

    //SCPrintByteBin(len_byte);

    if (*node->id.ptr == 0 && len_byte == 0) {
        node->flags |= ASN1_NODE_IS_EOC;
        ac->iter++;
        return ASN1_PARSER_OK;
    }

    if (ASN1_BER_IS_INDEFINITE_LEN(len_byte)) {
        node->len.form = ASN1_BER_LEN_INDEFINITE;
        node->len.len = 0;
        ac->iter++;

        uint8_t *tmp_iter = ac->iter;

        /* Check that e-o-c is in bounds */
        for (; tmp_iter < ac->end - 1; tmp_iter++) {
            if (ASN1_BER_IS_EOC(tmp_iter)) {
                node->data.len = tmp_iter - ac->iter;
                node->len.len = tmp_iter - ac->iter;
                return ASN1_PARSER_OK;
            }
        }

        /* EOC Not found */
        ac->parser_status |= ASN1_STATUS_INVALID;
        node->flags |= ASN1_BER_EVENT_EOC_NOT_FOUND;

        return ASN1_PARSER_ERR;

    } else {
        /* Look which form we get (and if it apply to the id type) */
        if (ASN1_BER_IS_SHORT_LEN(len_byte)) {
            node->len.form = ASN1_BER_LEN_SHORT;
            node->len.len = ASN1_BER_GET_SHORT_LEN(len_byte);
            ac->iter++;
        } else {
            node->len.form = ASN1_BER_LEN_LONG;

            /* Ok, let's parse the long form */
            return SCAsn1GetLengthLongForm(ac);
        }

    }
    return ASN1_PARSER_OK;
}
예제 #3
0
/**
 * \brief Check the content length and perform other inspections
 *        and decodings if necessary
 *
 * \param ac pointer to the ASN1 Context data
 *
 * \retval byte of the status of the parser
 */
uint8_t SCAsn1DecodeContent(Asn1Ctx *ac) {

    Asn1Node *node = ASN1CTX_CUR_NODE(ac);

    /* Uops, if we are done, we break here */
    if (node->flags & ASN1_NODE_IS_EOC)
        return ASN1_PARSER_OK;

    /* First check the form of length (BER, DER, CER)
     * and if we are on a zero length */
    if (node->len.form != ASN1_BER_LEN_INDEFINITE &&
        node->len.len == 0)
    {
        node->data.len = 0;
        return ASN1_PARSER_OK;
    }

    node->data.ptr = ac->iter;
    /* If we have a complete length, check that
     * it is in bounds */
    if (ac->iter + node->len.len > ac->end) {
        /* We do not have all the content octets! */
        node->data.len = ac->end - ac->iter;
    } else {
        /* We have all the content octets */
        node->data.len = node->len.len;
    }

    return ASN1_PARSER_OK;
}
예제 #4
0
/**
 * \brief Decode and check the identifier information of the
 *        current node that is in extended format
 *
 * \param ac pointer to the ASN1 Context data
 *
 * \retval byte of the status of the parser
 */
uint8_t SCAsn1GetHighTagNumber(Asn1Ctx *ac)
{
    uint8_t ret = 0;
    uint32_t tag_num = 0;

    /* If we have a high tag num, skip the id octet */
    ac->iter++;

    Asn1Node *node = ASN1CTX_CUR_NODE(ac);

    ret = SCAsn1CheckBounds(ac);
    if (ret == ASN1_PARSER_ERR) {
        ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB;
        return ret;
    }

    uint8_t raw_id = *ac->iter;

    tag_num += ASN1_BER_GET_HIGH_TAG_NUM(raw_id);

    if (ASN1_BER_GET_HIGH_TAG_NUM(raw_id) == 0) {
        /* Set event, invalid id */
        node->flags |= ASN1_BER_EVENT_INVALID_ID;
        ac->parser_status |= ASN1_STATUS_INVALID;
        return ASN1_PARSER_ERR;
    }

    ac->iter++;
    if (!ASN1_BER_IS_HIGH_TAG_END(raw_id)) {
        do {
            ret = SCAsn1CheckBounds(ac);
            if (ret == ASN1_PARSER_ERR) {
                ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB;
                return ret;
            }

            raw_id = *ac->iter;

            if ((uint64_t) ((uint64_t)tag_num +
                            (uint64_t)ASN1_BER_GET_HIGH_TAG_NUM(raw_id)) > UINT32_MAX)
            {
                node->flags |= ASN1_BER_EVENT_ID_TOO_LONG;
                ac->parser_status |= ASN1_STATUS_INVALID;
                return ASN1_PARSER_ERR;
            }

            tag_num += ASN1_BER_GET_HIGH_TAG_NUM(raw_id);
            ac->iter++;
        } while (!ASN1_BER_IS_HIGH_TAG_END(raw_id));
    }
    node->id.tag_num = tag_num;

    return ASN1_PARSER_OK;
}
예제 #5
0
/**
 * \brief Decode and check the length, of the current node
 *        in definite but extended format, that we are parsing,
 *        checking invalid opts
 *
 * \param ac pointer to the ASN1 Context data
 *
 * \retval byte of the status of the parser
 */
uint32_t SCAsn1GetLengthLongForm(Asn1Ctx *ac)
{
    uint8_t raw_len = *ac->iter;
    uint8_t ret = 0;
    uint32_t content_len = 0;
    uint8_t oct_len = ASN1_BER_GET_LONG_LEN_OCTETS(raw_len);
    uint8_t i = 0;

    Asn1Node *node = ASN1CTX_CUR_NODE(ac);

    for (; i < oct_len; i++) {
        ac->iter++;

        ret = SCAsn1CheckBounds(ac);
        if (ret == ASN1_PARSER_ERR) {
            ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB;
            return ASN1_PARSER_ERR;
        }

        raw_len = *ac->iter;
        if (raw_len == 0xFF && ac->iter == node->len.ptr + 1) {
            /* 8.1.3.5, 0xFF shall not be used */
            node->flags |= ASN1_BER_EVENT_INVALID_LEN;
            ac->parser_status = ASN1_STATUS_INVALID;
            return ASN1_PARSER_ERR;
        }

        if ((uint64_t) ((uint64_t)content_len +
                        (uint64_t) ASN1_BER_GET_HIGH_TAG_NUM(raw_len)) > UINT32_MAX)
        {
            node->flags |= ASN1_BER_EVENT_LEN_TOO_LONG;
            ac->parser_status = ASN1_STATUS_INVALID;
            return ASN1_PARSER_ERR;
        }

        content_len += raw_len;
    }

    ac->iter++;

    node->len.len = content_len;
    return ASN1_PARSER_OK;
}