⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn1.c

📁 Linux snort-2.4.4源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
                */                (*asn1_type)->data_len = 0;                            if(asn1_is_eoc(*asn1_type))                    (*asn1_type)->eoc = 1;            }            goto valid;        }        return ASN1_ERR_INVALID_INDEF_LEN;    }    /*    **  Set data ptr for asn1 types that have data.    */    (*asn1_type)->data = asn1data.data;    /*    **  Check for the ASN.1 type being larger than we have room for.    */    if(uiRawLen < (*asn1_type)->len.size)    {        (*asn1_type)->data_len = uiRawLen;        /*        **  If we're a construct, then don't skip over the data because        **  we have to process it.        */        if((*asn1_type)->ident.flag == SF_ASN1_FLAG_CONSTRUCT)            goto valid;        return ASN1_ERR_OOB;    }    /*    **  We got enough data in the buffer for the true identifier size, so    **  we set it.    */    (*asn1_type)->data_len = (*asn1_type)->len.size;    /*    **  Only jump data that's not going to be decoded.  That means jump    **  over primitive data and decode construct data.    */    if(!((*asn1_type)->ident.flag == SF_ASN1_FLAG_CONSTRUCT))    {        asn1data.data += (*asn1_type)->len.size;    }valid:    /*    **  Update data buffer, before we return.  Depending on if we just decoded    **  a zero length identifier and are on the last data byte, we could be at    **  the end of our buffer.  Otherwise, we're still in the buffer.    */    *len  = asn1data.end - asn1data.data;    *data = asn1data.data;    return ASN1_OK;}/***  NAME**    asn1_decode::*//****  This function decodes an ASN.1 string and returns the decoded**  structures.  We BER encoding, which means we handle both**  definite and indefinite length encodings (that was a B).****  @return integer****  @retval  ASN1_OK function successful**  @retval !ASN1_OK lots of error conditions, figure it out*/int asn1_decode(u_char *data, u_int len, ASN1_TYPE **asn1_type){    ASN1_TYPE *cur;    ASN1_TYPE *child = NULL;    ASN1_TYPE *indef;    ASN1_TYPE *asnstack[ASN1_MAX_STACK];    u_char *end;    u_int con_len;    int index = 0;    int iRet;    if(!data || !len)        return ASN1_ERR_NULL_MEM;    asn1_init_node_index();    /*    **  Keep track of where the end of the data buffer is so we can continue    **  processing if there is a construct.    */    end = data + len;    iRet = asn1_decode_type(&data,&len,asn1_type);    if(iRet || !(*asn1_type))    {        //printf("** initial bad decode\n");        return iRet;    }    cur  = *asn1_type;    while(cur)    {        /*        **  This is where we decode the ASN.1 constructs.  We do while()        **  because we may have back to back constructs.  We bail on the        **  first indentifier that isn't a construct.        */        while(cur && cur->ident.flag == SF_ASN1_FLAG_CONSTRUCT)        {            if(index < ASN1_MAX_STACK)                asnstack[index++] = cur;            else                return ASN1_ERR_STACK;            /*            **  We now set the current len for this constructs true length,            **  or raw length if true length is past buffer.            */            if(cur->len.type != SF_BER_LEN_INDEF)            {                if(len < cur->data_len)                    return ASN1_ERR_OVERLONG_LEN;                len = cur->data_len;            }            iRet = asn1_decode_type(&data, &len, &cur->cnext);            if(iRet)            {                return iRet;            }                        /*            **  Check next child for ending of indefinite encodings.            */            if(cur->cnext && cur->cnext->eoc)            {                if(index && (indef = asnstack[--index]))                {                    if(indef->len.type == SF_BER_LEN_INDEF)                    {                        indef->len.size = data - indef->data - 2;                        indef->data_len = indef->len.size;                        cur->cnext = NULL;                        cur = indef;                        break;                    }                    else                    {                        /*                        **  Not an EOC type, so it's just a strange child                        **  encoding.  Put the construct back on the stack.                        */                        asnstack[index++] = indef;                    }                }            }            cur = cur->cnext;        }        /*        **  If there is a node, then process any peers that this node has.        */        if(cur)        {            iRet = asn1_decode_type(&data, &len, &cur->next);            if(iRet)                return iRet;            /*            **  Cycle through any eoc that might be back to back            */            while(cur->next && cur->next->eoc)            {                if(index && (indef = asnstack[--index]))                {                    if(indef->len.type == SF_BER_LEN_INDEF)                    {                        indef->len.size = data - indef->data - 2;                        indef->data_len = indef->len.size;                        cur->next = NULL;                        cur = indef;                        iRet = asn1_decode_type(&data, &len, &cur->next);                        if(iRet)                        {                            return iRet;                        }                        continue;                    }                    asnstack[index++] = indef;                }                break;            }            cur = cur->next;            if(cur) continue;        }        /*        **  We only get here if the peer decode fails.        **        **  Traverse the stack and close off any constructs that we        **  are done with.  This gets a little trickier, because we have to        **  check for additional peers for each construct, depending on the        **  length of the parent construct.        */        while(index && (cur = asnstack[--index]))        {            /*            **  Get the construct length and set the length appropriately            **  if there is more data in this construct.            */            con_len = data - cur->data;            if(cur->data_len > con_len)            {                len = cur->data_len - con_len;            }            /*            **  If this construct has no more data left, then save it off as            **  the last child of the previous construct.            */            if(len == 0)            {                child = cur;            }            else if(child)            {                /*                **  Means this construct has more data left, so if the child is set                **  then we set it's next ptr.  Otherwise, this means we are in                **  an indeterminate construct, and need to check for eoc before we                **  continue processing.                */                asnstack[index++] = cur;                cur   = child;                child = NULL;            }            iRet = asn1_decode_type(&data, &len, &cur->next);            if(iRet)            {                return iRet;            }            if(cur->next && cur->next->eoc)            {                if(index && (indef = asnstack[--index]))                {                    if(indef->len.type == SF_BER_LEN_INDEF)                    {                        indef->len.size = data - indef->data - 2;                        indef->data_len = indef->len.size;                        cur->next = NULL;                        cur = indef;                    }                    else                    {                        asnstack[index++] = indef;                    }                }            }            /*            **  This logic tell us that we are on the root construct, but there            **  are additional peers because there is more data.  We recalculate            **  the length and continue on.            **            **  NOTE:            **    We may not want this because research may only be able to point            **    us at the first sequence and it's anyone's guess after that.            */            if(!index && !(cur->next) && (data < end))            {                len = (end - data);                                iRet = asn1_decode_type(&data, &len, &cur->next);                if(iRet)                    return iRet;            }            cur = cur->next;            if(cur)                break;        }        /*        **  The loop logic bails us out if there is no cur.        */    }    return ASN1_OK;}/***  NAME**    asn1_traverse::*//****  This function traverses a decoded ASN1 structure, applying a detection**  function for the different types.  This is just to make this user stack**  generic AND easy.****  @return integer****  @retval 1 detection function successful**  @retval 0 detection function unsuccessful*/int asn1_traverse(ASN1_TYPE *asn1, void *user,                   int (*DetectFunc)(ASN1_TYPE *, void *)){    ASN1_TYPE *asnstack[ASN1_MAX_STACK];    int index = 0;    ASN1_TYPE *cur;    int iRet;    if(!asn1)        return 0;    cur = asn1;    while(cur)    {        while(cur && cur->ident.flag == SF_ASN1_FLAG_CONSTRUCT)        {            if(index < ASN1_MAX_STACK)                asnstack[index++] = cur;            else                return 0;            iRet = DetectFunc(cur, user);            if(iRet)                return 1;            cur = cur->cnext;        }        if(cur)        {            iRet = DetectFunc(cur, user);            if(iRet)                return 1;            cur = cur->next;            if(cur) continue;        }        while(index && (cur = asnstack[--index]))        {            cur = cur->next;            if(cur)                break;        }    }    return 0;}/***  NAME**    asn1_print_types::*//****  Print out the ASN.1 type.****  @return integer****  @retval 0 printed*/int asn1_print_types(ASN1_TYPE *asn1_type, void *user){    unsigned int iTabs = 0;    unsigned int iCtr;    if(user)        iTabs = *((int *)user);    for(iCtr = 0; iCtr < iTabs; iCtr++)        printf("    ");    printf("## PRINT ASN1_TYPE STRUCTURE ##\n");    for(iCtr = 0; iCtr < iTabs; iCtr++)        printf("    ");    printf("IDENT - class: %.2x | flag: %.2x | tag_type: %.2x | "           "tag_num: %d\n", asn1_type->ident.class, asn1_type->ident.flag,           asn1_type->ident.tag_type, asn1_type->ident.tag);    for(iCtr = 0; iCtr < iTabs; iCtr++)        printf("    ");        printf("LEN - type: %d | size: %u\n", asn1_type->len.type,            asn1_type->len.size);    for(iCtr = 0; iCtr < iTabs; iCtr++)        printf("    ");    printf("DATA | data_len: %d | ", asn1_type->data_len);    if(asn1_type->data)    {        for(iCtr = 0; iCtr < asn1_type->data_len; iCtr++)            printf(" %.2x", asn1_type->data[iCtr]);    }    else    {        printf(" NULL");    }    printf("\n\n");    /*    printf("\n");    //if(BitStringOverflow(asn1_type))    //{    //    printf("!! BITSTRING OVERFLOW\n");    //}    printf("\n");        if(asn1_type->cnext)        asn1_print_types(asn1_type->cnext, iTabs+1);    if(asn1_type->next)        asn1_print_types(asn1_type->next, iTabs);    */    return 0;}#ifdef I_WANT_MAIN_DAMMITstatic int BitStringOverflow(ASN1_TYPE *asn1_type){    if(!asn1_type)        return 0;    if(asn1_type->ident.tag == SF_ASN1_TAG_BIT_STR && !asn1_type->ident.flag)    {        if(((asn1_type->len.size - 1)*8) < (u_int)asn1_type->data[0])        {                return 1;        }    }    return 0;}/***  Program reads from stdin and decodes the hexadecimal ASN.1 stream**  into identifier,len,data.*/int main(int argc, char **argv){    ASN1_TYPE *asn1_type;    char line[10000];    u_int ctmp;    char *buf;    int buf_size;    int iCtr;    int iRet;    fgets(line, sizeof(line), stdin);    buf_size = strlen(line);    while(buf_size && line[buf_size-1] <= 0x20)    {        buf_size--;        line[buf_size] = 0x00;    }    if(!buf_size)    {        printf("** No valid characters in data string.\n");        return 1;    }        if(buf_size % 2)    {        printf("** Data must be represent in hex, meaning that there is an "               "odd number of characters in the data string.\n");        return 1;    }    buf_size >>= 1;    buf = (char *)malloc(buf_size + 1);    if(!buf)    {        printf("** Bad malloc\n");        return 1;    }    for(iCtr = 0; iCtr < buf_size; iCtr++)    {        if(!(isxdigit(line[iCtr*2]) && isxdigit(line[(iCtr*2)+1])))        {            printf("** Data stream is not all hex digits.\n");            return 1;        }        sscanf(&line[iCtr*2], "%2x", &ctmp);        buf[iCtr] = (char)ctmp;    }    buf[iCtr] = 0x00;    if(asn1_init_mem(256))    {        printf("** asn1_init_mem() failed\n");        return 1;    }    iRet = asn1_decode(buf, buf_size, &asn1_type);    if(iRet && !asn1_type)    {        printf("** FAILED\n");        return 1;    }    printf("** iRet = %d\n", iRet);    asn1_print_types(asn1_type, 0);    free(buf);    return 0;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -