本工程基于STM32L41RCT6开发板,包含了本系列文章中所编写的所有Demo,持续更新……
X.509是数字证书的一种标准格式,由国际电信联盟的标准化部分定义。
X.509证书主要包括12个字段,如下表:
名称字段意义Version版本证书版本Serial number序列号证书的唯一序列号Signature签名算法CA对证书进行签名所使用的签名算法Issuer发行商名称标识对证书进行签名并颁发的实体Validity有效期标识证书的生效日期和终止日期Subject证书主体名称标识获得证书的主体Subject public key infomation公钥用于指示使用者公钥信息Issure unique ID颁发者唯一标识用于标识证书签发机构subject unique ID使用者唯一标识用于标识证书使用者实体Extensions扩展一个或多个扩展域signature Algorithm签名算法标识CA对证书签名所使用的签名算法和参数signature Value签名值CA对证书的签名结果下面以百度的证书为例讲解X.509证书标准。
使用浏览器访问百度首页:https://www.baidu.com/,点击域名旁边的【小绿锁】,点击【证书】。 点击之后即可查看到百度的证书: ① 点击【证书路径】,将一级证书(根证书)导出: 点击【详细信息】,将此证书内容【复制到文件】: 进入证书导出向导: 选择使用【Base64编码】导出: 选择导出文件路径: 导出成功: ② 同样的方法,将二级证书导出为baidu_2.cer: ③ 同样的方法,将三级证书导出为baidu_3.cer: 三份证书如图: 使用记事本打开任意一份,可以看到该证书内容: 新建一个空文件baidu_ca.txt,将三份内容按照次序复制到该文件中,后续使用。
使用openssl工具查看刚刚获取的百度证书内容:
openssl x509 -text -in baidu_3.cer -noout① 证书颁发者和使用者信息: ② 公钥算法和公钥内容: ③ 签名算法和内容: 同样的方法可以查看百度二级证书和百度一级证书(根证书)的内容。
①
/** * \def MBEDTLS_PK_C * * Enable the generic public (asymetric) key layer. * * Module: library/pk.c * Caller: library/ssl_tls.c * library/ssl_cli.c * library/ssl_srv.c * * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C * * Uncomment to enable generic public key wrappers. */ #define MBEDTLS_PK_C②
/** * \def MBEDTLS_PK_PARSE_C * * Enable the generic public (asymetric) key parser. * * Module: library/pkparse.c * Caller: library/x509_crt.c * library/x509_csr.c * * Requires: MBEDTLS_PK_C * * Uncomment to enable generic public key parse functions. */ #define MBEDTLS_PK_PARSE_C③
/** * \def MBEDTLS_ASN1_PARSE_C * * Enable the generic ASN1 parser. * * Module: library/asn1.c * Caller: library/x509.c * library/dhm.c * library/pkcs12.c * library/pkcs5.c * library/pkparse.c */ #define MBEDTLS_ASN1_PARSE_C④
/** * \def MBEDTLS_ASN1_WRITE_C * * Enable the generic ASN1 writer. * * Module: library/asn1write.c * Caller: library/ecdsa.c * library/pkwrite.c * library/x509_create.c * library/x509write_crt.c * library/x509write_csr.c */ #define MBEDTLS_ASN1_WRITE_C⑤
/** * \def MBEDTLS_X509_USE_C * * Enable X.509 core for using certificates. * * Module: library/x509.c * Caller: library/x509_crl.c * library/x509_crt.c * library/x509_csr.c * * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, * MBEDTLS_PK_PARSE_C * * This module is required for the X.509 parsing modules. */ #define MBEDTLS_X509_USE_C⑥
/** * \def MBEDTLS_BASE64_C * * Enable the Base64 module. * * Module: library/base64.c * Caller: library/pem.c * * This module is required for PEM support (required by X.509). */ #define MBEDTLS_BASE64_C⑦
/** * \def MBEDTLS_PEM_PARSE_C * * Enable PEM decoding / parsing. * * Module: library/pem.c * Caller: library/dhm.c * library/pkparse.c * library/x509_crl.c * library/x509_crt.c * library/x509_csr.c * * Requires: MBEDTLS_BASE64_C * * This modules adds support for decoding / parsing PEM files. */ #define MBEDTLS_PEM_PARSE_C⑧
/** * \def MBEDTLS_X509_CRT_PARSE_C * * Enable X.509 certificate parsing. * * Module: library/x509_crt.c * Caller: library/ssl_cli.c * library/ssl_srv.c * library/ssl_tls.c * * Requires: MBEDTLS_X509_USE_C * * This module is required for X.509 certificate parsing. */ #define MBEDTLS_X509_CRT_PARSE_C新建配置文件mbedtls_config_x509.h,编辑以下内容:
/** * @brief Minimal configuration for X509 Function * @author mculover666 * @date 2020/10/04 */ #ifndef _MBEDTLS_CONFIG_X509_H_ #define _MBEDTLS_CONFIG_X509_H_ /* System support */ #define MBEDTLS_HAVE_ASM //#define MBEDTLS_HAVE_TIME /* mbed feature support */ #define MBEDTLS_ENTROPY_HARDWARE_ALT //#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES #define MBEDTLS_NO_PLATFORM_ENTROPY /* mbed modules */ #define MBEDTLS_SHA1_C #define MBEDTLS_SHA256_C #define MBEDTLS_MD_C #define MBEDTLS_BIGNUM_C #define MBEDTLS_OID_C #define MBEDTLS_RSA_C #define MBEDTLS_PKCS1_V21 #define MBEDTLS_PK_C #define MBEDTLS_PK_PARSE_C #define MBEDTLS_ASN1_PARSE_C #define MBEDTLS_ASN1_WRITE_C #define MBEDTLS_X509_USE_C #define MBEDTLS_BASE64_C #define MBEDTLS_PEM_PARSE_C #define MBEDTLS_X509_CRT_PARSE_C #include "mbedtls/check_config.h" #endif /* _MBEDTLS_CONFIG_X509_H_ */在MDK中配置使用该文件:
使用时需要包含头文件:
#include "mbedtls/x509_crt.h"① 初始化证书结构体
/** * \brief Initialize a certificate (chain) * * \param crt Certificate chain to initialize */ void mbedtls_x509_crt_init( mbedtls_x509_crt *crt );② 证书解析
/** * \brief Parse one DER-encoded or one or more concatenated PEM-encoded * certificates and add them to the chained list. * * For CRTs in PEM encoding, the function parses permissively: * if at least one certificate can be parsed, the function * returns the number of certificates for which parsing failed * (hence \c 0 if all certificates were parsed successfully). * If no certificate could be parsed, the function returns * the first (negative) error encountered during parsing. * * PEM encoded certificates may be interleaved by other data * such as human readable descriptions of their content, as * long as the certificates are enclosed in the PEM specific * '-----{BEGIN/END} CERTIFICATE-----' delimiters. * * \param chain The chain to which to add the parsed certificates. * \param buf The buffer holding the certificate data in PEM or DER format. * For certificates in PEM encoding, this may be a concatenation * of multiple certificates; for DER encoding, the buffer must * comprise exactly one certificate. * \param buflen The size of \p buf, including the terminating \c NULL byte * in case of PEM encoded data. * * \return \c 0 if all certificates were parsed successfully. * \return The (positive) number of certificates that couldn't * be parsed if parsing was partly successful (see above). * \return A negative X509 or PEM error code otherwise. * */ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen );③ 获取证书信息
/** * \brief Returns an informational string about the * certificate. * * \param buf Buffer to write to * \param size Maximum size of buffer * \param prefix A line prefix * \param crt The X509 certificate to represent * * \return The length of the string written (not including the * terminated nul byte), or a negative error code. */ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, const mbedtls_x509_crt *crt );④ 获取证书认证信息:
/** * \brief Returns an informational string about the * verification status of a certificate. * * \param buf Buffer to write to * \param size Maximum size of buffer * \param prefix A line prefix * \param flags Verification flags created by mbedtls_x509_crt_verify() * * \return The length of the string written (not including the * terminated nul byte), or a negative error code. */ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, uint32_t flags );⑤ 证书认证
/** * \brief Verify a chain of certificates. * * The verify callback is a user-supplied callback that * can clear / modify / add flags for a certificate. If set, * the verification callback is called for each * certificate in the chain (from the trust-ca down to the * presented crt). The parameters for the callback are: * (void *parameter, mbedtls_x509_crt *crt, int certificate_depth, * int *flags). With the flags representing current flags for * that specific certificate and the certificate depth from * the bottom (Peer cert depth = 0). * * All flags left after returning from the callback * are also returned to the application. The function should * return 0 for anything (including invalid certificates) * other than fatal error, as a non-zero return code * immediately aborts the verification process. For fatal * errors, a specific error code should be used (different * from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not * be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR * can be used if no better code is available. * * \note In case verification failed, the results can be displayed * using \c mbedtls_x509_crt_verify_info() * * \note Same as \c mbedtls_x509_crt_verify_with_profile() with the * default security profile. * * \note It is your responsibility to provide up-to-date CRLs for * all trusted CAs. If no CRL is provided for the CA that was * used to sign the certificate, CRL verification is skipped * silently, that is *without* setting any flag. * * \note The \c trust_ca list can contain two types of certificates: * (1) those of trusted root CAs, so that certificates * chaining up to those CAs will be trusted, and (2) * self-signed end-entity certificates to be trusted (for * specific peers you know) - in that case, the self-signed * certificate doesn't need to have the CA bit set. * * \param crt The certificate chain to be verified. * \param trust_ca The list of trusted CAs. * \param ca_crl The list of CRLs for trusted CAs. * \param cn The expected Common Name. This will be checked to be * present in the certificate's subjectAltNames extension or, * if this extension is absent, as a CN component in its * Subject name. Currently only DNS names are supported. This * may be \c NULL if the CN need not be verified. * \param flags The address at which to store the result of the verification. * If the verification couldn't be completed, the flag value is * set to (uint32_t) -1. * \param f_vrfy The verification callback to use. See the documentation * of mbedtls_x509_crt_verify() for more information. * \param p_vrfy The context to be passed to \p f_vrfy. * * \return \c 0 if the chain is valid with respect to the * passed CN, CAs, CRLs and security profile. * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the * certificate chain verification failed. In this case, * \c *flags will have one or more * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX * flags set. * \return Another negative error code in case of a fatal error * encountered during the verification process. */ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, const char *cn, uint32_t *flags, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy );⑥ 释放证书结构体
/** * \brief Unallocate all certificate data * * \param crt Certificate chain to free */ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt );⑦ 错误码:
/** * \name X509 Error codes * \{ */ #define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE -0x2080 /**< Unavailable feature, e.g. RSA hashing/encryption combination. */ #define MBEDTLS_ERR_X509_UNKNOWN_OID -0x2100 /**< Requested OID is unknown. */ #define MBEDTLS_ERR_X509_INVALID_FORMAT -0x2180 /**< The CRT/CRL/CSR format is invalid, e.g. different type expected. */ #define MBEDTLS_ERR_X509_INVALID_VERSION -0x2200 /**< The CRT/CRL/CSR version element is invalid. */ #define MBEDTLS_ERR_X509_INVALID_SERIAL -0x2280 /**< The serial tag or value is invalid. */ #define MBEDTLS_ERR_X509_INVALID_ALG -0x2300 /**< The algorithm tag or value is invalid. */ #define MBEDTLS_ERR_X509_INVALID_NAME -0x2380 /**< The name tag or value is invalid. */ #define MBEDTLS_ERR_X509_INVALID_DATE -0x2400 /**< The date tag or value is invalid. */ #define MBEDTLS_ERR_X509_INVALID_SIGNATURE -0x2480 /**< The signature tag or value invalid. */ #define MBEDTLS_ERR_X509_INVALID_EXTENSIONS -0x2500 /**< The extension tag or value is invalid. */ #define MBEDTLS_ERR_X509_UNKNOWN_VERSION -0x2580 /**< CRT/CRL/CSR has an unsupported version number. */ #define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG -0x2600 /**< Signature algorithm (oid) is unsupported. */ #define MBEDTLS_ERR_X509_SIG_MISMATCH -0x2680 /**< Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */ #define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED -0x2700 /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */ #define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT -0x2780 /**< Format not recognized as DER or PEM. */ #define MBEDTLS_ERR_X509_BAD_INPUT_DATA -0x2800 /**< Input invalid. */ #define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ #define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */ #define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */编写头文件baidu_certs.h,将百度的证书存储:
#ifndef __CERTS_H__ #define __CERTS_H__ const char baidu_ca_cert[] = "-----BEGIN CERTIFICATE-----\r\n" "MIIKLjCCCRagAwIBAgIMclh4Nm6fVugdQYhIMA0GCSqGSIb3DQEBCwUAMGYxCzAJ\r\n" "BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTwwOgYDVQQDEzNH\r\n" "bG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gU0hBMjU2IC0g\r\n" "RzIwHhcNMjAwNDAyMDcwNDU4WhcNMjEwNzI2MDUzMTAyWjCBpzELMAkGA1UEBhMC\r\n" "Q04xEDAOBgNVBAgTB2JlaWppbmcxEDAOBgNVBAcTB2JlaWppbmcxJTAjBgNVBAsT\r\n" "HHNlcnZpY2Ugb3BlcmF0aW9uIGRlcGFydG1lbnQxOTA3BgNVBAoTMEJlaWppbmcg\r\n" "QmFpZHUgTmV0Y29tIFNjaWVuY2UgVGVjaG5vbG9neSBDby4sIEx0ZDESMBAGA1UE\r\n" "AxMJYmFpZHUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwamw\r\n" "rkca0lfrHRUfblyy5PgLINvqAN8p/6RriSZLnyMv7FewirhGQCp+vNxaRZdPrUEO\r\n" "vCCGSwxdVSFH4jE8V6fsmUfrRw1y18gWVHXv00URD0vOYHpGXCh0ro4bvthwZnuo\r\n" "k0ko0qN2lFXefCfyD/eYDK2G2sau/Z/w2YEympfjIe4EkpbkeBHlxBAOEDF6Speg\r\n" "68ebxNqJN6nDN9dWsX9Sx9kmCtavOBaxbftzebFoeQOQ64h7jEiRmFGlB5SGpXhG\r\n" "eY9Ym+k1Wafxe1cxCpDPJM4NJOeSsmrp5pY3Crh8hy900lzoSwpfZhinQYbPJqYI\r\n" "jqVJF5JTs5Glz1OwMQIDAQABo4IGmDCCBpQwDgYDVR0PAQH/BAQDAgWgMIGgBggr\r\n" "BgEFBQcBAQSBkzCBkDBNBggrBgEFBQcwAoZBaHR0cDovL3NlY3VyZS5nbG9iYWxz\r\n" "aWduLmNvbS9jYWNlcnQvZ3Nvcmdhbml6YXRpb252YWxzaGEyZzJyMS5jcnQwPwYI\r\n" "KwYBBQUHMAGGM2h0dHA6Ly9vY3NwMi5nbG9iYWxzaWduLmNvbS9nc29yZ2FuaXph\r\n" "dGlvbnZhbHNoYTJnMjBWBgNVHSAETzBNMEEGCSsGAQQBoDIBFDA0MDIGCCsGAQUF\r\n" "BwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAIBgZn\r\n" "gQwBAgIwCQYDVR0TBAIwADBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmds\r\n" "b2JhbHNpZ24uY29tL2dzL2dzb3JnYW5pemF0aW9udmFsc2hhMmcyLmNybDCCA04G\r\n" "A1UdEQSCA0UwggNBggliYWlkdS5jb22CDGJhaWZ1YmFvLmNvbYIMd3d3LmJhaWR1\r\n" "LmNughB3d3cuYmFpZHUuY29tLmNugg9tY3QueS5udW9taS5jb22CC2Fwb2xsby5h\r\n" "dXRvggZkd3ouY26CCyouYmFpZHUuY29tgg4qLmJhaWZ1YmFvLmNvbYIRKi5iYWlk\r\n" "dXN0YXRpYy5jb22CDiouYmRzdGF0aWMuY29tggsqLmJkaW1nLmNvbYIMKi5oYW8x\r\n" "MjMuY29tggsqLm51b21pLmNvbYINKi5jaHVhbmtlLmNvbYINKi50cnVzdGdvLmNv\r\n" "bYIPKi5iY2UuYmFpZHUuY29tghAqLmV5dW4uYmFpZHUuY29tgg8qLm1hcC5iYWlk\r\n" "dS5jb22CDyoubWJkLmJhaWR1LmNvbYIRKi5mYW55aS5iYWlkdS5jb22CDiouYmFp\r\n" "ZHViY2UuY29tggwqLm1pcGNkbi5jb22CECoubmV3cy5iYWlkdS5jb22CDiouYmFp\r\n" "ZHVwY3MuY29tggwqLmFpcGFnZS5jb22CCyouYWlwYWdlLmNugg0qLmJjZWhvc3Qu\r\n" "Y29tghAqLnNhZmUuYmFpZHUuY29tgg4qLmltLmJhaWR1LmNvbYISKi5iYWlkdWNv\r\n" "bnRlbnQuY29tggsqLmRsbmVsLmNvbYILKi5kbG5lbC5vcmeCEiouZHVlcm9zLmJh\r\n" "aWR1LmNvbYIOKi5zdS5iYWlkdS5jb22CCCouOTEuY29tghIqLmhhbzEyMy5iYWlk\r\n" "dS5jb22CDSouYXBvbGxvLmF1dG+CEioueHVlc2h1LmJhaWR1LmNvbYIRKi5iai5i\r\n" "YWlkdWJjZS5jb22CESouZ3ouYmFpZHViY2UuY29tgg4qLnNtYXJ0YXBwcy5jboIN\r\n" "Ki5iZHRqcmN2LmNvbYIMKi5oYW8yMjIuY29tggwqLmhhb2thbi5jb22CDyoucGFl\r\n" "LmJhaWR1LmNvbYIRKi52ZC5iZHN0YXRpYy5jb22CEmNsaWNrLmhtLmJhaWR1LmNv\r\n" "bYIQbG9nLmhtLmJhaWR1LmNvbYIQY20ucG9zLmJhaWR1LmNvbYIQd24ucG9zLmJh\r\n" "aWR1LmNvbYIUdXBkYXRlLnBhbi5iYWlkdS5jb20wHQYDVR0lBBYwFAYIKwYBBQUH\r\n" "AwEGCCsGAQUFBwMCMB8GA1UdIwQYMBaAFJbeYfG9HBYpUxzAzH07gwBA5hp8MB0G\r\n" "A1UdDgQWBBSeyXnX6VurihbMMo7GmeafIEI1hzCCAX4GCisGAQQB1nkCBAIEggFu\r\n" "BIIBagFoAHYAXNxDkv7mq0VEsV6a1FbmEDf71fpH3KFzlLJe5vbHDsoAAAFxObU8\r\n" "ugAABAMARzBFAiBphmgxIbNZXaPWiUqXRWYLaRST38KecoekKIof5fXmsgIhAMkZ\r\n" "tF8XyKCu/nZll1e9vIlKbW8RrUr/74HpmScVRRsBAHYAb1N2rDHwMRnYmQCkURX/\r\n" "dxUcEdkCwQApBo2yCJo32RMAAAFxObU85AAABAMARzBFAiBURWwwTgXZ+9IV3mhm\r\n" "E0EOzbg901DLRszbLIpafDY/XgIhALsvEGqbBVrpGxhKoTVlz7+GWom8SrfUeHcn\r\n" "4+9Dn7xGAHYA9lyUL9F3MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOMAAAFxObU8\r\n" "qwAABAMARzBFAiBFBYPxKEdhlf6bqbwxQY7tskgdoFulPxPmdrzS5tNpPwIhAKnK\r\n" "qwzch98lINQYzLAV52+C8GXZPXFZNfhfpM4tQ6xbMA0GCSqGSIb3DQEBCwUAA4IB\r\n" "AQC83ALQ2d6MxeLZ/k3vutEiizRCWYSSMYLVCrxANdsGshNuyM8B8V/A57c0Nzqo\r\n" "CPKfMtX5IICfv9P/bUecdtHL8cfx24MzN+U/GKcA4r3a/k8pRVeHeF9ThQ2zo1xj\r\n" "k/7gJl75koztdqNfOeYiBTbFMnPQzVGqyMMfqKxbJrfZlGAIgYHT9bd6T985IVgz\r\n" "tRVjAoy4IurZenTsWkG7PafJ4kAh6jQaSu1zYEbHljuZ5PXlkhPO9DwW1WIPug6Z\r\n" "rlylLTTYmlW3WETOATi70HYsZN6NACuZ4t1hEO3AsF7lqjdA2HwTN10FX2HuaUvf\r\n" "5OzP+PKupV9VKw8x8mQKU6vr\r\n" "-----END CERTIFICATE-----\r\n"; #endif编写测试函数文件mbedtls_x509_test.c:
/** * @brief X509 Function demo * @author mculover666 * @date 2020/10/04 */ #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" #else #include MBEDTLS_CONFIG_FILE #endif #if defined(MBEDTLS_X509_CRT_PARSE_C) #include <stdio.h> #include "string.h" #include "mbedtls/x509_crt.h" #include "baidu_certs.h" char buf[4096]; int mbedtls_x509_test(void) { int ret; mbedtls_x509_crt cert, cacert; /* 1. init structure */ mbedtls_x509_crt_init(&cert); mbedtls_x509_crt_init(&cacert); /* 2. Parser cacert */ printf( "\n . Parse cacert..." ); ret = mbedtls_x509_crt_parse(&cacert, (unsigned char *)baidu_ca_cert, sizeof(baidu_ca_cert)); if(ret != 0) { printf( " failed\n ! mbedtls_x509_crt_parse cacert returned %d(-0xx)\n", ret, -ret); goto exit; } printf( " ok\n" ); /* 2. Cacert parser result */ printf( "\n . Cacert parser result..." ); ret = mbedtls_x509_crt_info(buf, sizeof(buf) - 1, " ", &cacert); if (ret < 0) { printf("fail! mbedtls_x509_crt_info return %d(-0xx)\n", ret, -ret); goto exit; } else { buf[ret] = '\0'; printf("ok!\r\n"); printf("crt info has %d chars\r\n", strlen(buf)); printf("%s\r\n", buf); } exit: /* 3. release structure */ mbedtls_x509_crt_free(&cert); mbedtls_x509_crt_free(&cacert); return ret; } #endif /* MBEDTLS_RSA_C */在main.c中声明该测试函数:
extern int mbedtls_x509_test(void);在main函数中调用该测试函数:
/* 10. x509 test */ mbedtls_x509_test();编译、下载、测试结果为: 接收精彩文章及资源推送,请订阅我的微信公众号:『mculover666』。
Mculover666 认证博客专家 嵌入式软件开发 IoT全栈开发 博客专家,微信公众号mculover666,凭借与生俱来的热爱专注于嵌入式领域,在自己折腾的同时,以文字的方式分享所玩、所思、所想、所悟,作为一个技术人,我们一起前进~