pluto实现分析(3)

发布时间:2019-08-05 15:35:17编辑:auto阅读(1571)

     
    本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,
    严禁用于任何商业用途。
    msn: yfydz_no1@hotmail.com
    来源:http://yfydz.cublog.cn

    5. 系统一些主要数据结构

    5.1 SA ID
     
    /* linux/include/openswan.h */
    // IP地址结构
    typedef struct {
    // V4和V6地址的联合
     union {
      struct sockaddr_in v4;
      struct sockaddr_in6 v6;
     } u;
    } ip_address;

     
    // 子网结构
    typedef struct {
    // 地址
     ip_address addr;
    // 掩码位数
     int maskbits;
    } ip_subnet;

    /* and the SA ID stuff */
    #ifdef __KERNEL__
    typedef __u32 ipsec_spi_t;
    #else
    typedef u_int32_t ipsec_spi_t;
    #endif
    // 包含3项: 目的地址, SPI和协议
    typedef struct {  /* to identify an SA, we need: */
            ip_address dst;  /* A. destination host */
            ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
    #  define SPI_PASS 256 /* magic values... */
    #  define SPI_DROP 257 /* ...for use... */
    #  define SPI_REJECT 258 /* ...with SA_INT */
    #  define SPI_HOLD 259
    #  define SPI_TRAP 260
    #  define  SPI_TRAPSUBNET  261
     int proto;  /* C. protocol */
    #  define SA_ESP 50 /* IPPROTO_ESP */
    #  define SA_AH 51 /* IPPROTO_AH */
    #  define SA_IPIP 4 /* IPPROTO_IPIP */
    #  define SA_COMP 108 /* IPPROTO_COMP */
    #  define SA_INT 61 /* IANA reserved for internal use */
    } ip_said;

    5.2 连接(connection)

    连接用于描述建立IPSec通道的连接信息, 参数直接的配置文件中配置, 连接可以是静态的, 也就是
    两端地址等信息都是固定; 也可以是动态的, 也就是连接一方可以先不固定地址, 这时的连接只相当
    于一个模板, 只有当真正有连接建立时再建立具体的连接实例。
    /* programs/pluto/connection.h */
    struct connection {
    // 连接名称
        char *name;
    // 策略
        lset_t policy;
    // IKE生命期
        time_t sa_ike_life_seconds;
    // IPSEC连接生命期
        time_t sa_ipsec_life_seconds;
    // 重协商间隔时间
        time_t sa_rekey_margin;
    //
        unsigned long sa_rekey_fuzz;
    // 重协商尝试次数
        unsigned long sa_keying_tries;
       
        /* RFC 3706 DPD */
    // DPD检查间隔时间
        time_t          dpd_delay;              /* time between checks */
    // DPD判断对方死亡时间,dpd_delay*dpd_tries
        time_t          dpd_timeout;            /* time after which we are dead */
    // DPD对方死亡后判断操作
        enum dpd_action dpd_action;             /* what to do when we die */
       
    // 强制使用UDP封装(NAT穿越)
        bool               forceencaps;         /* always use NAT-T encap */
       
    // 日志文件名称
        char              *log_file_name;       /* name of log file */
    // 日志文件流指针
        FILE              *log_file;            /* possibly open FILE */
        CIRCLEQ_ENTRY(connection) log_link;     /* linked list of open conns {} */
    // 日志文件是否错误
        bool               log_file_err;        /* only bitch once */
    // 安全策略路由
        struct spd_route spd;
        /* internal fields: */
    // 实例序号, 有的连接是那种动态通配连接,开始时并没有明确的IP地址,只有连接时才建立实例
        unsigned long instance_serial;
    // 策略优先权
        policy_prio_t prio;
    // 实例初始化正确标志
        bool instance_initiation_ok; /* this is an instance of a policy that mandates
    initiate */
    // 连接类型
        enum connection_kind kind;
    // 网卡
        const struct iface_port *interface; /* filled in iff oriented */
    // 是否已经初始化标志
        bool initiated;
    // 与连接相关的状态的序列号
        so_serial_t /* state object serial number */
     newest_isakmp_sa,
     newest_ipsec_sa;

    #ifdef DEBUG
        lset_t extra_debugging;
    #endif
        /* note: if the client is the gateway, the following must be equal */
    // 地址协议族:V4, V6
        sa_family_t addr_family;  /* between gateways */
    // 通道内封装的地址的协议族
        sa_family_t tunnel_addr_family; /* between clients */
    // 下一策略
        struct connection *policy_next; /* if multiple policies,
               next one to apply */
    // 网关信息指针
        struct gw_info *gw_info;
    // ESP使用算法名称
        char                *alg_esp;    /* string the admin provided */
    // IKE使用算法名称
        char                *alg_ike;    /* ditto. may be NULL */
    // ESP算法信息
        struct alg_info_esp *alg_info_esp;
    // IKE算法信息
        struct alg_info_ike *alg_info_ike;
    // 主机对
        struct host_pair *host_pair;
    // 主机对链表
        struct connection *hp_next; /* host pair list link */
    // 下一个连接
        struct connection *ac_next; /* all connections list link */
    // 证书信息   
        generalName_t *requested_ca; /* collected certificate requests */
    #ifdef XAUTH_USEPAM
    // PAM认证句柄
        pam_handle_t  *pamh;  /*  PAM handle for that connection  */
    #endif
    };

    // 安全策略路由结构
    struct spd_route {
    // 链表下一项
        struct spd_route *next;
    // 本地和对方的端点信息
        struct end this;
        struct end that;
    // 所有者
        so_serial_t eroute_owner;
    // 路由状态类型
        enum routing_t routing; /* level of routing in place */
    // 请求ID
        uint32_t reqid;
    };

    // 端点结构
    struct end {
    // 端点ID值,可为地址,也可以是一个字符串
        struct id id;
    // 端点地址, 下一跳(网关)地址, 源地址
        ip_address
     host_addr,
     host_nexthop,
     host_srcip;
    // 内部子网
        ip_subnet client;
    // 一些标志
    // 从DNS服务器获取key   
        bool key_from_DNS_on_demand;
    // 存在子网
        bool has_client;
    // 有通配子网
        bool has_client_wildcard;
    // 有通配端口
        bool has_port_wildcard;
    // 有通配ID
        bool has_id_wildcards;
    // 启动停止命令文件
        char *updown;
    // IKE端口
        u_int16_t host_port; /* where the IKE port is */
    // 指定了IKE端口
        bool      host_port_specific; /* if TRUE, then IKE ports are tested for*/
    // 端口
        u_int16_t port;  /* port number, if per-port keying. */
    // 协议
        u_int8_t protocol;          /* protocol number, if per-per keying. */
    // 证书
        cert_t cert;  /* end certificate */
    // CA的名称
        chunk_t ca;   /* CA distinguished name */
    // 属性表
        struct ietfAttrList *groups;/* access control groups */
    // smartcard
        smartcard_t *sc;  /* smartcard reader and key info */
    #ifdef VIRTUAL_IP
    // 虚拟IP(一般用于×××客户端)
        struct virtual_t *virt;
    #endif
    // 是XAUTH的服务器端
        bool xauth_server;
    // 是XAUTH的客户端
        bool xauth_client;
    // 是设置配置的服务器端, 可向客户端提供虚拟IP,DNS,WINS等参数
        bool modecfg_server;        /* Give local addresses to tunnel's end */
    // 是设置配置的客户端
        bool modecfg_client;        /* request address for local end */
    // 发送证书类型
        enum certpolicy sendcert;   /* whether or not to send the certificate */
    };

    // ID结构
    struct id {
    // 类型
        int kind;  /* ID_* value */
    // 地址
        ip_address ip_addr; /* ID_IPV4_ADDR, ID_IPV6_ADDR */
    // ID名称
        chunk_t name; /* ID_FQDN, ID_USER_FQDN (with @) */
       /* ID_KEY_ID, ID_DER_ASN_DN       */
    };
     
    5.2 状态(state)

    状态是用于描述连接建立过程中的各种中间阶段,
    /* programs/pluto/state.h */
    /* state object: record the state of a (possibly nascent) SA
     *
     * Invariants (violated only during short transitions):
     * - each state object will be in statetable exactly once.
     * - each state object will always have a pending event.
     *   This prevents leaks.
     */
    struct state
    {
    // 状态序号
        so_serial_t        st_serialno;          /*serial number (for seniority) */
    // 父状态序号
        so_serial_t        st_clonedfrom;        /* serial number of parent */
    // 状态使用数
        int                st_usage;
    // 相关的连接指针
        struct connection *st_connection;          /* connection for this SA */
    // 与whack通信的接口描述符
        int                st_whack_sock;          /* fd for our Whack TCP socket.
                                                    * Single copy: close when
          * freeing struct.
                                                    */
    // 缓期的消息摘要
        struct msg_digest *st_suspended_md;        /* suspended state-transition */
    // Oakley(主模式)转换属性参数
        struct oakley_trans_attrs st_oakley;
    // AH协议信息
        struct ipsec_proto_info st_ah;
    // ESP协议信息
        struct ipsec_proto_info st_esp;
    // IP压缩协议信息
        struct ipsec_proto_info st_ipcomp;
    #ifdef KLIPS
    // 进入方向的SPI
        ipsec_spi_t        st_tunnel_in_spi;          /* KLUDGE */
    // 发出方向的SPI
        ipsec_spi_t        st_tunnel_out_spi;         /* KLUDGE */
    #endif
    // 阶段2中使用的oakley组
        const struct oakley_group_desc *st_pfs_group; /*group for Phase 2 PFS */
    // DOI解释域
        u_int32_t          st_doi;                 /* Domain of Interpretation */
    // 状况
        u_int32_t          st_situation;
    // IPSEC SA策略
        lset_t             st_policy;              /* policy for IPsec SA */
    // 对端地址
        ip_address         st_remoteaddr;          /* where to send packets to */
    // 对端的端口
        u_int16_t          st_remoteport;          /* host byte order */
    // 网卡   
        const struct iface_port *st_interface;     /* where to send from */
    // 本地地址和端口
        ip_address         st_localaddr;           /* where to send them from */
        u_int16_t          st_localport;          
    // 消息ID
        msgid_t            st_msgid;               /* MSG-ID from header.  Network Order! */
    // 消息ID
        msgid_t            st_msgid_phase15;       /* msgid for phase 1.5 */
        msgid_t            st_msgid_phase15b;      /* msgid for phase 1.5 */
        /* only for a state representing an ISAKMP SA */
    // 使用的消息ID链表
        struct msgid_list  *st_used_msgids;        /* used-up msgids */
    /* symmetric stuff */
      /* initiator stuff */
    // 发起方公共值
        chunk_t            st_gi;                  /* Initiator public value */
    // 发起方cookie
        u_int8_t           st_icookie[COOKIE_SIZE];/* Initiator Cookie */
    // 发起方时间
        chunk_t            st_ni;                  /* Ni nonce */
      /* responder stuff */
    // 接收方公共值
        chunk_t            st_gr;                  /* Responder public value */
    // 接收方cookie
        u_int8_t           st_rcookie[COOKIE_SIZE];/* Responder Cookie */
    // 接收方时间
        chunk_t            st_nr;                  /* Nr nonce */

      /* my stuff */
    // 发送的包数
        chunk_t            st_tpacket;             /* Transmitted packet */
        /* Phase 2 ID payload info about my user */
    // 本地定义的协议和端口信息
        u_int8_t           st_myuserprotoid;       /* IDcx.protoid */
        u_int16_t          st_myuserport;
      /* his stuff */
    // 接收的包数
        chunk_t            st_rpacket;             /* Received packet */
        /* Phase 2 ID payload info about peer's user */
    // 对方的协议和端口信息
        u_int8_t           st_peeruserprotoid;     /* IDcx.protoid */
        u_int16_t          st_peeruserport;
    /* end of symmetric stuff */
    // 使用的密钥数
        u_int8_t           st_sec_in_use;      /* bool: does st_sec hold a value */
    // 本地秘密
        MP_INT             st_sec;             /* Our local secret value */
    // 本地秘密的备份
        chunk_t            st_sec_chunk;       /* copy of above */
    // 共享密钥
        chunk_t            st_shared;              /* Derived shared secret
                                                    * Note: during Quick Mode,
                                                    * presence indicates PFS
                                                    * selected.
                                                    */
    // 优先权
        enum crypto_importance st_import;          /* relative priority of crypto
          * operations
          */
        /* In a Phase 1 state, preserve peer's public key after authentication */
    // 对方的公钥
        struct pubkey     *st_peer_pubkey;
    // 状态类型
        enum state_kind    st_state;               /* State of exchange */
    // 重发数量
        u_int8_t           st_retransmit;          /* Number of retransmits */
    // 重协商尝试次数
        unsigned long      st_try;                 /* number of times rekeying attempted */
                                                   /* 0 means the only time */
    // 有效时间
        time_t             st_margin;              /* life after EVENT_SA_REPLACE */
    // 输出包数统计
        unsigned long      st_outbound_count;      /* traffic through eroute */
    // 已经持续时间
        time_t             st_outbound_time;       /* time of last change to
    st_outbound_count */
    // 是否需要加密
        bool               st_calculating;         /* set to TRUE, if we are performing
    cryptographic
          * operations on this state at this time
          */
    // 阶段1的发起方进行哈希的SA载荷
        chunk_t            st_p1isa;               /* Phase 1 initiator SA (Payload) for
    HASH */
    // KEY ID
        chunk_t            st_skeyid;              /* Key material */
        chunk_t            st_skeyid_d;            /* KM for non-ISAKMP key derivation */
        chunk_t            st_skeyid_a;            /* KM for ISAKMP authentication */
        chunk_t            st_skeyid_e;            /* KM for ISAKMP encryption */
    // 加密用的初始化向量
        u_char             st_iv[MAX_DIGEST_LEN];  /* IV for encryption */
    // 老的初始化向量
        u_char             st_old_iv[MAX_DIGEST_LEN];  /* IV for encryption */
        u_char             st_new_iv[MAX_DIGEST_LEN];
    // 阶段1的初始化向量
        u_char             st_ph1_iv[MAX_DIGEST_LEN]; /* IV at end if phase 1 */
    // 各种初始化向量长度
        unsigned int       st_iv_len;
        unsigned int       st_old_iv_len;
        unsigned int       st_new_iv_len;
        unsigned int       st_ph1_iv_len;
    // 加密密钥
        chunk_t            st_enc_key;             /* Oakley Encryption key *
    // 事件
        struct event      *st_event;               /* backpointer for certain events */
    // 状态链表的下一项和前一项
        struct state      *st_hashchain_next;      /* Next in list */
        struct state      *st_hashchain_prev;      /* Previous in list */
    // 内部参数
        struct {
    // 接收到的错误数据包数
            unsigned int   st_malformed_received;
    // 发送的错误数据包数
            unsigned int   st_malformed_sent;
    // XAUTH客户端认证结束
     bool           st_xauth_client_done;
    // XAUTH客户端认证尝试次数
     int            st_xauth_client_attempt;
    // 模式配置服务器端处理结束
            bool           st_modecfg_server_done;
    // 配置参数已经设置标志
            bool           st_modecfg_vars_set;
    // 已经获得证书请求标志
     bool           st_got_certrequest;
    // 模式配置启动标志
            bool           st_modecfg_started;
    // 密钥ID已经计算标志
     bool           st_skeyid_calculated;
    // 对方支持DPD标志
     bool           st_dpd;                 /* Peer supports DPD */
    // 本地是否使用DPD标志
     bool           st_dpd_local;        /* If we want DPD on this conn */
    // 是否已经在日志中记录了算法标志
     bool           st_logged_p1algos;      /* if we have logged algos */
    // NAT穿越参数
     u_int32_t      st_nat_traversal;       /* bit field of permitted
          * methods. If non-zero, then
          * NAT-T has been detected, and
          * should be used. */
    // NAT前的地址
     ip_address     st_nat_oa;
    // NAT后的地址
     ip_address     st_natd;
        } hidden_variables;                        /* internal state that
          * should get copied by god
          * Eistein would be proud
          */
    // XAUTH用户名
        unsigned char *st_xauth_username;
        /* RFC 3706 Dead Peer Detection */
    // 上次DPD时间
        time_t              st_last_dpd;            /* Time of last DPD transmit */
    // DPD包序号
        u_int32_t           st_dpd_seqno;           /* Next R_U_THERE to send */
    // 期待的DPD包序号
        u_int32_t           st_dpd_expectseqno;     /* Next R_U_THERE_ACK to receive */
    // 对方的DPD序号
        u_int32_t           st_dpd_peerseqno;       /* global variables */
    // DPD事件
        struct event        *st_dpd_event;          /* backpointer for DPD events */
    // 看到的提供者ID
        u_int32_t       st_seen_vendorid;   /* Bit field about recognized Vendor ID */
    // 不同IPSEC实现互连时的一些错误信息
        struct isakmp_quirks quirks;          /* work arounds for faults in other
             * products */
       
    };
     
    /* Oakley (Phase 1 / Main Mode) transform and attributes
     * This is a flattened/decoded version of what is represented
     * in the Transaction Payload.
     * Names are chosen to match corresponding names in state.
     */
    // Oakley(第一阶段/主模式)转换和属性结构
    struct oakley_trans_attrs {
    // 加密算法
        u_int16_t encrypt;  /* Encryption algorithm */
    // 密钥长度
        u_int16_t enckeylen; /* encryption key len (bits) */
    // 加密算法描述结构
        const struct encrypt_desc *encrypter; /* package of encryption routines */
    // 哈希算法
        oakley_hash_t hash;  /* Hash algorithm */
    // 哈希算法描述结构
        const struct hash_desc *hasher; /* package of hashing routines */
    // 认证算法
        oakley_auth_t auth;  /* Authentication method */
    #ifdef XAUTH
    // XAUTH认证
        u_int16_t xauth;            /* did we negotiate Extended Authentication? */
    #endif
    // Oakley组描述结构
        const struct oakley_group_desc *group; /* Oakley group */
    // 生存期, 时间限制
        time_t life_seconds; /* When this SA expires (seconds) */
    // 生存期, 数据量限制
        u_int32_t life_kilobytes; /* When this SA is exhausted (kilobytes) */
    #if 0 /* not yet */
    // 伪随机函数算法
        u_int16_t prf;  /* Pseudo Random Function */
    #endif
    };
     
    /* IPsec (Phase 2 / Quick Mode) transform and attributes
     * This is a flattened/decoded version of what is represented
     * by a Transaction Payload.  There may be one for AH, one
     * for ESP, and a funny one for IPCOMP.
     */
    // IPSEC(第2阶段/快速模式)转换和属性结构
    struct ipsec_trans_attrs {
    // 转换ID
        u_int8_t transid; /* transform id */
    // SPI
        ipsec_spi_t spi; /* his SPI */
    // 生存期, 时间限制
        time_t life_seconds;  /* When this SA expires */
    // 生存期, 数据量限制
        u_int32_t life_kilobytes; /* When this SA expires */
    // 封装类型
        u_int16_t encapsulation;
    // 认证类型
        ipsec_auth_t auth;           
    // 密钥长度
        u_int16_t key_len;
    // 密钥计算轮数
        u_int16_t key_rounds;
    #if 0 /* not implemented yet */
        u_int16_t cmprs_dict_sz;
        u_int32_t cmprs_alg;
    #endif
    };

    /* IPsec per protocol state information */
    // IPSEC协议信息
    struct ipsec_proto_info {
    // 是否提供标志
        bool present; /* was this transform specified? */
    // IPSEC(第2阶段/快速模式)转换和属性结构
        struct ipsec_trans_attrs attrs;
    // 本地SPI
        ipsec_spi_t our_spi;
    // 密钥长度
        u_int16_t keymat_len; /* same for both */
    // 本地密钥
        u_char *our_keymat;
    // 对方密钥
        u_char *peer_keymat;
    };

    // 事件结构
    struct event
    {
    // 事件事件
        time_t          ev_time;
    // 事件类型
        enum event_type ev_type;        /* Event type */
    // 事件相关的状态结构
        struct state   *ev_state;       /* Pointer to relevant state (if any) */
    // 事件链表的下一项
        struct event   *ev_next;        /* Pointer to next event */
    };

    5.4 内核接口相关结构

    /* programs/pluto/kernel.h */
    // pfkey协议信息
    struct pfkey_proto_info {
    // 协议
     int proto;
    // 封装类型
     int encapsulation;
    // 请求ID
     unsigned reqid;
    };

    // 内核SA结构
    struct kernel_sa {
    // 源地址
     const ip_address *src;
    // 目的地址
     const ip_address *dst;
    // 源子网
     const ip_subnet *src_client;
    // 目的子网
     const ip_subnet *dst_client;
    // SPI
     ipsec_spi_t spi;
    // 协议
     unsigned proto;
    // SA类型
     unsigned satype;
    // 回放窗口
     unsigned replay_window;
    // 请求ID
     unsigned reqid;

    // 认证算法
     unsigned authalg;
    // 认证算法密钥长度
     unsigned authkeylen;
    // 认证密钥
     char *authkey;

    // 加密算法
     unsigned encalg;
    // 加密算法密钥长度
     unsigned enckeylen;
    // 加密密钥
     char *enckey;

    // 封装
     int encapsulation;
    #ifdef NAT_TRAVERSAL
    // NAT穿越的源端口,目的端口
     u_int16_t natt_sport, natt_dport;
    // ID和类型
     u_int8_t transid, natt_type;
    // NAT转换前原地址
     ip_address *natt_oa;
    #endif
    // SA ID
     const char *text_said;
    };
     
    // 内核操作结构
    struct kernel_ops {
    // 枚举类型
     enum {
    // 内核不支持
             KERNEL_TYPE_NONE,
    // 内核使用KLIPS实现IPSEC
      KERNEL_TYPE_KLIPS,
    // 内核使用自带的native ipsec
      KERNEL_TYPE_LINUX,
     } type;
    // 操作名称
     const char *opname;
    // 是否存在进入方向的加密路由
     bool inbound_eroute;
    // 使用有策略生存期限制
     bool policy_lifetime;
    // 回放窗口
            int  replay_window;
     int *async_fdp;
    // 初始化
     void (*init)(void);
    // 登记
     void (*pfkey_register)(void);
    // 登记回应
     void (*pfkey_register_response)(const struct sadb_msg *msg);
    // 队列处理
     void (*process_queue)(void);
    // 处理消息
     void (*process_msg)(void);
    // 原始加密路由处理
     bool (*raw_eroute)(const ip_address *this_host,
          const ip_subnet *this_client,
          const ip_address *that_host,
          const ip_subnet *that_client,
          ipsec_spi_t spi,
          unsigned int proto,
          unsigned int transport_proto,
          unsigned int satype,
          const struct pfkey_proto_info *proto_info,
          time_t use_lifetime,
          unsigned int op,
          const char *text_said);
    // 增加SA
     bool (*add_sa)(const struct kernel_sa *sa, bool replace);
     bool (*grp_sa)(const struct kernel_sa *sa_outer,
             const struct kernel_sa *sa_inner);
    // 删除SA
     bool (*del_sa)(const struct kernel_sa *sa);
    // 获取SPI
     ipsec_spi_t (*get_spi)(const ip_address *src,
              const ip_address *dst,
              int proto,
              bool tunnel_mode,
              unsigned reqid,
              ipsec_spi_t min,
              ipsec_spi_t max,
              const char *text_said);
    // 执行建立连接命令
        bool (*docommand)(struct connection *c
            , struct spd_route *sr
            , const char *verb
            , struct state *st);
    };

    /* information from /proc/net/ipsec_eroute */
    // 加密路由信息
    struct eroute_info {
    // 包数
        unsigned long count;
    // 本地子网
        ip_subnet ours;
    // 对方子网
        ip_subnet his;
    // 目的地址
        ip_address dst;
    // SA ID
        ip_said said;
    // 传输协议
        int         transport_proto;
    // 链表下一项
        struct eroute_info *next;
    };

    5.5 密钥结构

    /* programs/pluto/keys.h */
    // RSA公钥
    struct RSA_public_key
    {
    // 密钥ID
        char keyid[KEYID_BUF]; /* see ipsec_keyblobtoid(3) */
        /* length of modulus n in octets: [RSA_MIN_OCTETS, RSA_MAX_OCTETS] */
    // 长度
        unsigned k;
        /* public: */
    // 公钥参数
        MP_INT
     n, /* modulus: p * q */
     e; /* exponent: relatively prime to (p-1) * (q-1) [probably small] */
    };
    // RSA私钥
    struct RSA_private_key {
    // 公钥结构, 因为私钥和公钥是对称的, 基本描述结构也相同
        struct RSA_public_key pub; /* must be at start for RSA_show_public_key */
    // 私钥相关参数, 主要是一些内部私有数据
        MP_INT
     d, /* private exponent: (e^-1) mod ((p-1) * (q-1)) */
     /* help for Chinese Remainder Theorem speedup: */
     p, /* first secret prime */
     q, /* second secret prime */
     dP, /* first factor's exponent: (e^-1) mod (p-1) == d mod (p-1) */
     dQ, /* second factor's exponent: (e^-1) mod (q-1) == d mod (q-1) */
     qInv; /* (q^-1) mod p */
    };

    /* public key machinery  */
    // 公开密钥结构
    struct pubkey {
    // ID结构
        struct id id;
    // 使用数
        unsigned refcnt; /* reference counted! */
    // 认证层次
        enum dns_auth_level dns_auth_level;
    // DNS签名
        char *dns_sig;
    // 相关时间: 安装时间, 上次尝试时间, 上次工作时间, 到期时间
        time_t installed_time
     , last_tried_time
     , last_worked_time
     , until_time;
    // 发布者
        chunk_t issuer;
    // 公开密钥算法类型
        enum pubkey_alg alg;
    // 公开密钥算法联合
        union {
    // 目前只支持RSA这种公开密钥算法
     struct RSA_public_key rsa;
        } u;
    };

    // 公开密钥链表结构
    struct pubkey_list {
        struct pubkey *key;
        struct pubkey_list *next;
    };

    ...... 待续 ......

关键字

上一篇: ios 笔试题3

下一篇: Python之列表的删除