mbedTLS常用结构体

ECP密钥对mbedtls_ecp_keypair

/**
 * \brief           ECP key pair structure
 *
 * A generic key pair that could be used for ECDSA, fixed ECDH, etc.
 *
 * \note Members purposefully in the same order as struc mbedtls_ecdsa_context.
 */
typedef struct
{
    mbedtls_ecp_group grp;      /*!<  Elliptic curve and base point     */
    mbedtls_mpi d;              /*!<  our secret value                  */
    mbedtls_ecp_point Q;        /*!<  our public value                  */
}
mbedtls_ecp_keypair;

公钥算法类型mbedtls_pk_type_t

/**
 * \brief          Public key types
 */
typedef enum {
    MBEDTLS_PK_NONE=0,
    MBEDTLS_PK_RSA,
    MBEDTLS_PK_ECKEY,
    MBEDTLS_PK_ECKEY_DH,
    MBEDTLS_PK_ECDSA,
    MBEDTLS_PK_RSA_ALT,
    MBEDTLS_PK_RSASSA_PSS,
	MBEDTLS_PK_SM2,
} mbedtls_pk_type_t;

摘要算法类型mbedtls_md_type_t

typedef enum {
    MBEDTLS_MD_NONE=0,
    MBEDTLS_MD_MD2,
    MBEDTLS_MD_MD4,
    MBEDTLS_MD_MD5,
    MBEDTLS_MD_SHA1,
    MBEDTLS_MD_SHA224,
    MBEDTLS_MD_SHA256,
    MBEDTLS_MD_SHA384,
    MBEDTLS_MD_SHA512,
    MBEDTLS_MD_RIPEMD160,
	MBEDTLS_MD_SM3,
} mbedtls_md_type_t;

X509证书

/**
 * Container for an X.509 certificate. The certificate may be chained.
 */
typedef struct mbedtls_x509_crt
{
    mbedtls_x509_buf raw;               /**< The raw certificate data (DER). */
    mbedtls_x509_buf tbs;               /**< The raw certificate body (DER). The part that is To Be Signed. */

    int version;                /**< The X.509 version. (1=v1, 2=v2, 3=v3) */
    mbedtls_x509_buf serial;            /**< Unique id for certificate issued by a specific CA. */
    mbedtls_x509_buf sig_oid;           /**< Signature algorithm, e.g. sha1RSA */

    mbedtls_x509_buf issuer_raw;        /**< The raw issuer data (DER). Used for quick comparison. */
    mbedtls_x509_buf subject_raw;       /**< The raw subject data (DER). Used for quick comparison. */

    mbedtls_x509_name issuer;           /**< The parsed issuer data (named information object). */
    mbedtls_x509_name subject;          /**< The parsed subject data (named information object). */

    mbedtls_x509_time valid_from;       /**< Start time of certificate validity. */
    mbedtls_x509_time valid_to;         /**< End time of certificate validity. */

    mbedtls_pk_context pk;              /**< Container for the public key context. */

    mbedtls_x509_buf issuer_id;         /**< Optional X.509 v2/v3 issuer unique identifier. */
    mbedtls_x509_buf subject_id;        /**< Optional X.509 v2/v3 subject unique identifier. */
    mbedtls_x509_buf v3_ext;            /**< Optional X.509 v3 extensions.  */
    mbedtls_x509_sequence subject_alt_names;    /**< Optional list of Subject Alternative Names (Only dNSName supported). */

    int ext_types;              /**< Bit string containing detected and parsed extensions */
    int ca_istrue;              /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
    int max_pathlen;            /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */

    unsigned int key_usage;     /**< Optional key usage extension value: See the values in x509.h */

    mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */

    unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */

    mbedtls_x509_buf sig;               /**< Signature: hash of the tbs part signed with the private key. */
    mbedtls_md_type_t sig_md;           /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
    mbedtls_pk_type_t sig_pk;           /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
    void *sig_opts;             /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */

    struct mbedtls_x509_crt *next;     /**< Next certificate in the CA-chain. */
}
mbedtls_x509_crt;

公钥上下文mbedtls_pk_context

/**
 * \brief           Public key container
 */
typedef struct
{
    const mbedtls_pk_info_t *   pk_info; /**< Public key informations        */
    void *                      pk_ctx;  /**< Underlying public key context  */
} mbedtls_pk_context;

解析证书得到的mbedtls_pk_info_t

struct mbedtls_pk_info_t //解析证书得到的
{
    /** Public key type */
    mbedtls_pk_type_t type;
    /** Type name */
    const char *name;
    /** Get key size in bits */
    size_t (*get_bitlen)( const void * );
    /** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */
    int (*can_do)( mbedtls_pk_type_t type );
    /** Verify signature *///验证签名,证书,秘钥交换时服务器签名(如果有的话)
    int (*verify_func)( void *ctx, mbedtls_md_type_t md_alg,
                        const unsigned char *hash, size_t hash_len,
                        const unsigned char *sig, size_t sig_len );

    /** Make signature *///用秘钥来加密
    int (*sign_func)( void *ctx, mbedtls_md_type_t md_alg,
                      const unsigned char *hash, size_t hash_len,
                      unsigned char *sig, size_t *sig_len,
                      int (*f_rng)(void *, unsigned char *, size_t),
                      void *p_rng );

    /** Decrypt message *///秘钥交换,服务器解密使用
    int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
                         unsigned char *output, size_t *olen, size_t osize,
                         int (*f_rng)(void *, unsigned char *, size_t),
                         void *p_rng );

    /** Encrypt message */ //秘钥交换时加密秘钥用
    int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
                         unsigned char *output, size_t *olen, size_t osize,
                         int (*f_rng)(void *, unsigned char *, size_t),
                         void *p_rng );

    /** Check public-private key pair */
    int (*check_pair_func)( const void *pub, const void *prv );
    /** Allocate a new context */
    void * (*ctx_alloc_func)( void );
    /** Free the given context */
    void (*ctx_free_func)( void *ctx );
    /** Interface with the debug module */
    void (*debug_func)( const void *ctx, mbedtls_pk_debug_item *items );
};

net上下文mbedtls_net_context

/**
 * Wrapper type for sockets.
 *
 * Currently backed by just a file descriptor, but might be more in the future
 * (eg two file descriptors for combined IPv4 + IPv6 support, or additional
 * structures for hand-made UDP demultiplexing).
 */
typedef struct
{
    int fd;             /**< The underlying file descriptor                 */
}
mbedtls_net_context;

ssl上下文mbedtls_ssl_context

struct mbedtls_ssl_context
{
    const mbedtls_ssl_config *conf; /*!< configuration information          */
    /*
     * Miscellaneous
     */
    int state;                  /*!< SSL handshake: current state     */
#if defined(MBEDTLS_SSL_RENEGOTIATION)
    int renego_status;          /*!< Initial, in progress, pending?   */
    int renego_records_seen;    /*!< Records since renego request, or with DTLS,
                                  number of retransmissions of request if
                                  renego_max_records is < 0           */
#endif

    int major_ver;              /*!< equal to  MBEDTLS_SSL_MAJOR_VERSION_3    */
    int minor_ver;              /*!< either 0 (SSL3) or 1 (TLS1.0)    */

#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
    unsigned badmac_seen;       /*!< records with a bad MAC received    */
#endif

    mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
    mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
    mbedtls_ssl_recv_timeout_t *f_recv_timeout;
                                /*!< Callback for network receive with timeout */

    void *p_bio;                /*!< context for I/O operations   */

    /*
     * Session layer
     */
    mbedtls_ssl_session *session_in;            /*!<  current session data (in)   */
    mbedtls_ssl_session *session_out;           /*!<  current session data (out)  */
    mbedtls_ssl_session *session;               /*!<  negotiated session data     */
    mbedtls_ssl_session *session_negotiate;     /*!<  session data in negotiation */

    mbedtls_ssl_handshake_params *handshake;    /*!<  params required only during
                                              the handshake process        */

    /*
     * Record layer transformations
     */
    mbedtls_ssl_transform *transform_in;        /*!<  current transform params (in)   */
    mbedtls_ssl_transform *transform_out;       /*!<  current transform params (in)   */
    mbedtls_ssl_transform *transform;           /*!<  negotiated transform params     */
    mbedtls_ssl_transform *transform_negotiate; /*!<  transform params in negotiation */

    /*
     * Timers
     */
    void *p_timer;              /*!< context for the timer callbacks */

    mbedtls_ssl_set_timer_t *f_set_timer;       /*!< set timer callback */
    mbedtls_ssl_get_timer_t *f_get_timer;       /*!< get timer callback */

    /*
     * Record layer (incoming data)
     */
    unsigned char *in_buf;      /*!< input buffer                     */
    unsigned char *in_ctr;      /*!< 64-bit incoming message counter
                                     TLS: maintained by us
                                     DTLS: read from peer             */
    unsigned char *in_hdr;      /*!< start of record header           */
    unsigned char *in_len;      /*!< two-bytes message length field   */
    unsigned char *in_iv;       /*!< ivlen-byte IV                    */
    unsigned char *in_msg;      /*!< message contents (in_iv+ivlen)   */
    unsigned char *in_offt;     /*!< read offset in application data  */

    int in_msgtype;             /*!< record header: message type      */
    size_t in_msglen;           /*!< record header: message length    */
    size_t in_left;             /*!< amount of data read so far       */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
    uint16_t in_epoch;          /*!< DTLS epoch for incoming records  */
    size_t next_record_offset;  /*!< offset of the next record in datagram
                                     (equal to in_left if none)       */
#endif
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
    uint64_t in_window_top;     /*!< last validated record seq_num    */
    uint64_t in_window;         /*!< bitmask for replay detection     */
#endif

    size_t in_hslen;            /*!< current handshake message length,
                                     including the handshake header   */
    int nb_zero;                /*!< # of 0-length encrypted messages */

    int keep_current_message;   /*!< drop or reuse current message
                                     on next call to record layer? */

    /*
     * Record layer (outgoing data)
     */
    unsigned char *out_buf;     /*!< output buffer                    */
    unsigned char *out_ctr;     /*!< 64-bit outgoing message counter  */
    unsigned char *out_hdr;     /*!< start of record header           */
    unsigned char *out_len;     /*!< two-bytes message length field   */
    unsigned char *out_iv;      /*!< ivlen-byte IV                    */
    unsigned char *out_msg;     /*!< message contents (out_iv+ivlen)  */

    int out_msgtype;            /*!< record header: message type      */
    size_t out_msglen;          /*!< record header: message length    */
    size_t out_left;            /*!< amount of data not yet written   */

#if defined(MBEDTLS_ZLIB_SUPPORT)
    unsigned char *compress_buf;        /*!<  zlib data buffer        */
#endif
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
    signed char split_done;     /*!< current record already splitted? */
#endif

    /*
     * PKI layer
     */
    int client_auth;                    /*!<  flag for client auth.   */

    /*
     * User settings
     */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
    char *hostname;             /*!< expected peer CN for verification
                                     (and SNI if available)                 */
#endif

#if defined(MBEDTLS_SSL_ALPN)
    const char *alpn_chosen;    /*!<  negotiated protocol                   */
#endif

    /*
     * Information for DTLS hello verify
     */
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
    unsigned char  *cli_id;         /*!<  transport-level ID of the client  */
    size_t          cli_id_len;     /*!<  length of cli_id                  */
#endif

    /*
     * Secure renegotiation
     */
    /* needed to know when to send extension on server */
    int secure_renegotiation;           /*!<  does peer support legacy or
                                              secure renegotiation           */
#if defined(MBEDTLS_SSL_RENEGOTIATION)
    size_t verify_data_len;             /*!<  length of verify data stored   */
    char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!<  previous handshake verify data */
    char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!<  previous handshake verify data */
#endif
};

ssl会话mbedtls_ssl_session

/*
 * This structure is used for storing current session data.
 */
struct mbedtls_ssl_session
{
#if defined(MBEDTLS_HAVE_TIME)
    mbedtls_time_t start;       /*!< starting time      */
#endif
    int ciphersuite;            /*!< chosen ciphersuite */
    int compression;            /*!< chosen compression */
    size_t id_len;              /*!< session id length  */
    unsigned char id[32];       /*!< session identifier */
    unsigned char master[48];   /*!< the master secret  */

#if defined(MBEDTLS_X509_CRT_PARSE_C)
    mbedtls_x509_crt *peer_cert;        /*!< peer X.509 cert chain */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
    uint32_t verify_result;          /*!<  verification result     */

#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
    unsigned char *ticket;      /*!< RFC 5077 session ticket */
    size_t ticket_len;          /*!< session ticket length   */
    uint32_t ticket_lifetime;   /*!< ticket lifetime hint    */
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
    unsigned char mfl_code;     /*!< MaxFragmentLength negotiated by peer */
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */

#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
    int trunc_hmac;             /*!< flag for truncated hmac activation   */
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */

#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
    int encrypt_then_mac;       /*!< flag for EtM activation                */
#endif
};

encrypto上下文mbedtls_entropy_context

/**
 * \brief           Entropy context structure
 */
typedef struct
{
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
    mbedtls_sha512_context  accumulator;
#else
    mbedtls_sha256_context  accumulator;
#endif
    int             source_count;
    mbedtls_entropy_source_state    source[MBEDTLS_ENTROPY_MAX_SOURCES];
#if defined(MBEDTLS_HAVEGE_C)
    mbedtls_havege_state    havege_data;
#endif
#if defined(MBEDTLS_THREADING_C)
    mbedtls_threading_mutex_t mutex;    /*!< mutex                  */
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
    int initial_entropy_run;
#endif
}
mbedtls_entropy_context;






<think>嗯,用户问的是LWIP协议栈中mbedtls使用PSK和非PSK建立TLS连接时结构体的差异。这个问题很专业,用户应该是做嵌入式TLS开发的工程师。 首先需要区分两种连接方式的核心差异:PSK方式用预共享密钥代替证书验证,这会导致mbedtls配置结构体产生三处关键变化: 第一处是SSL配置结构体mbedtls_ssl_config。PSK模式必须设置PSK相关回调函数,比如mbedtls_ssl_conf_psk(),这会填充psk_identity和psk_key字段。而非PSK模式这里要配置证书链和CA验证参数。 第二处差异在会话结构体mbedtls_ssl_context。虽然结构体本身相同,但PSK模式下其handshake字段指向的握手子结构体内部状态完全不同——PSK握手会跳过证书验证流程,直接进入密钥交换阶段。第三处是用户需要额外管理PSK凭证。非PSK模式用标准证书文件,而PSK需要用户自己实现凭证存储和检索逻辑,比如硬编码密钥或从安全元件读取。用户可能正在调试PSK连接失败的问题,所以需要明确这些结构体差异。接下来考虑设计相关问题时,应该围绕配置细节、调试方法和应用场景展开: 第一个问题可以深入PSK回调的实现方式,这是配置的关键。第二个问题针对常见调试痛点——如何验证PSK是否生效。第三个问题探讨PSK的适用场景,帮助用户理解设计取舍。第四个问题则关联到PSK特有的安全考量,比如密钥轮换。这些问题应该能覆盖用户可能遇到的后续疑问,特别是实际开发中的陷阱。比如PSK调试时经常出现的回调函数注册遗漏问题,或是PSK密钥管理这种容易被忽视的安全实践。</think>LWIP协议栈中,mbedtls使用PSK建立TLS连接与非PSK连接(通常使用证书认证)在结构体使用上的核心差别体现在**`mbedtls_ssl_config`**的配置上,具体如下: 1. **`mbedtls_ssl_config` 的认证模式设置不同:** * **PSK连接:** 必须将认证模式设置为 `MBEDTLS_SSL_VERIFY_OPTIONAL` 或 `MBEDTLS_SSL_VERIFY_NONE`。 ```c mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); // 或 MBEDTLS_SSL_VERIFY_NONE ``` 因为PSK本身提供了认证,不需要服务器证书验证(或只需要弱验证)。 * **非PSK连接(证书认证):** 通常设置为 `MBEDTLS_SSL_VERIFY_REQUIRED`,强制验证服务器证书。 ```c mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED); ``` 2. **`mbedtls_ssl_config` 的PSK回调设置:** * **PSK连接:** **必须** 设置PSK回调函数 `mbedtls_ssl_conf_psk_cb`。这是PSK连接的核心配置项。该回调函数负责根据客户端发送的`PSK identity`查找并返回对应的预共享密钥`PSK`。 ```c mbedtls_ssl_conf_psk_cb(&conf, your_psk_callback, your_callback_arg); ``` * `your_psk_callback` 函数原型:`int (*)(void *info, mbedtls_ssl_context *ssl, const unsigned char *psk_identity, size_t psk_identity_len)`。它需要填充 `info->psk` 和 `info->psk_len`。 * **非PSK连接(证书认证):** **不需要且不应设置** PSK回调函数。配置的重点在于设置证书和密钥。 3. **`mbedtls_ssl_config` 的证书/密钥设置:** * **PSK连接:** **通常不需要** 为 `mbedtls_ssl_config` 配置证书链 (`mbedtls_ssl_conf_own_cert`) 和私钥 (`mbedtls_ssl_conf_own_key`)。因为PSK协商不依赖服务器证书。 * **非PSK连接(证书认证):** **必须** 配置服务器证书链和对应的私钥。 ```c mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey); // srvcert是证书链,pkey是私钥 ``` 客户端需要配置CA证书 (`mbedtls_ssl_conf_ca_chain`) 用于验证服务器证书。 4. **`mbedtls_ssl_context` 的差异:** * 该结构体本身 (`mbedtls_ssl_context`) 是通用的,用于表示一个SSL/TLS会话。无论使用PSK还是证书,都需要创建和初始化它。 * **关键区别在于其内部状态:** 在执行握手 (`mbedtls_ssl_handshake`) 时,根据 `mbedtls_ssl_config` 的配置(特别是PSK回调的存在与否和认证模式),握手过程会走完全不同的路径: * PSK连接会执行PSK密钥交换握手流程。 * 证书认证连接会执行基于证书的密钥交换握手流程(如RSA, ECDHE-RSA, ECDHE-ECDSA等)。 5. **凭证管理:** * **PSK连接:** 需要管理 `PSK identity` 和对应的 `PSK key`。这些通常是硬编码、存储在安全元件或通过安全方式配置的,**而不是**证书文件。 * **非PSK连接(证书认证):** 需要管理证书文件(服务器证书链、CA证书)和私钥文件。 **总结差异点:** | 结构体/配置项 | PSK 连接 | 非PSK连接 (证书认证) | | :-------------------- | :--------------------------------------- | :--------------------------------------- | | `mbedtls_ssl_config.authmode` | `VERIFY_OPTIONAL` 或 `VERIFY_NONE` | `VERIFY_REQUIRED` (客户端) | | `mbedtls_ssl_config.psk_cb` | **必须设置** (提供PSK查找逻辑) | **不设置** | | `mbedtls_ssl_config.own_cert/key` | **通常不设置** | **必须设置** (服务器端) | | `mbedtls_ssl_config.ca_chain` | **通常不设置** (客户端) | **必须设置** (客户端验证服务器) | | `mbedtls_ssl_context` | 结构体相同,握手过程根据配置走PSK路径 | 结构体相同,握手过程走证书认证路径 | | 主要凭证 | PSK Identity & PSK Key (预共享密钥对) | 证书文件 (PEM/DER) & 私钥文件 |
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值