zoukankan      html  css  js  c++  java
  • OpenSSL API: asn1_par.c源码分析

    openssl有关asn1编解码的函数都定义在crypto/asn1/asn1_par.c下,这些函数直接在官方文档里是找不到的,也就是说openssl其实没有直接暴露asn1编解码的接口,而是在这之上又封装了一层证书格式,比如X509
    但是由于我们要做的是asn1的解码器,而不是针对证书格式的解码,所以无法直接调用openssl暴露的接口,只能通过学习源码来编写API供后面的软件使用。

    概览

    原型

    一共有五个函数

    static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, int indent)
    int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
    int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
    static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset, int depth, int indent, int dump)
    const char *ASN1_tag2str(int tag)
    

    功能

    • ASN1_parse()ASN1_parse_dump()
      openssl asn1parse命令直接调用的函数,其实内部都调用了asn1_parse2(),唯一的区别就是输出格式的不同,详情看后面的分析
    • asn1_parse2()
      真正进行解码的函数。本函数用于将pplen指明的DER编码值写在BIO中,其中indentdump用于设置打印的格式。indent用来设置打印出来当列之间空格个数,ident越小,打印内容越紧凑。dump表明当asn1单元为BIT STRINGOCTET STRING时,打印内容的字节数
    • ASN1_tag2str()
      根据tag的值返回对应类型的名称字符串
    • asn1_print_info()
      按格式打印解码出的asn1信息

    ASN1_parse/ASN1_parse_dump

    不多说

    ASN1_tag2str

    将tag值和类型名称对应起来

    asn1_print_info

    输出传入的结构是结构化的还是原始的,以及对应的tag

    asn1_parse2

    重头戏,首先要明白这是个递归函数

    参数

    • BIO *bp解析过程中所有的结果都会写入这个BIO中
    • const unsigned char *pp其中包含需要解析的二进制数据
    • long lengthpp中需要解析二进制数据的长度
    • int offset偏移量,初始值0,在递归过程中会被修改
    • int depth深度。众所周知,asn1其实也是个树形结构,depth也就是当前所在树的深度,初始值为0,在递归过程中会被修改
    • int indent用来设置打印出来当列之间空格个数,ident越小,打印内容越紧凑
    • int dump表明当asn1单元为BIT STRINGOCTET STRING时,打印内容的字节数

    整体结构

    asn1_parse2(){
        while (length > 0) {
            if(xxx){
                ...
                goto end;
            }
            if(xxx){
                asn1_parse2()
            }
            length -= len
        }
        end:
            free();
            return ret;
    }
    

    详细分析

    接下来一步一步分析

    超过最大递归层数时退出

    ASN1_get_object定义在asn1_lib.c中,会在其中修改传入的指针位置,hl计算出头部长度,然后length从中减掉hl

    (long)offset + (long)(op - *pp)算出偏移

    依次输出层数、头部长度、长度,以及调用asn1_print_info

    如果当前解析的结构是结构化的,那么递归调用asn1_parse2,对内层进行解析

  • 相关阅读:
    作业七:用户体验设计案例分析
    作业五:需求分析
    作业四:结对编程 词频统计
    作业四:结对编程,词频统计
    作业三:词频统计
    作业2
    Github注册过程
    ArrayList的说明及简单用法
    Java类中成员变量、局部变量、静态变量的区别
    AspNetCore.SignalR的JwtBearer认证
  • 原文地址:https://www.cnblogs.com/20175211lyz/p/12815469.html
Copyright © 2011-2022 走看看