我正在为OpenThread堆栈通过CoAP实现EST(安全传输注册)-客户端的实现。为此,我想使用mbedTLS编写CSR(证书签名请求),mbedTLS作为第三方软件是堆栈的一部分。我现在的问题是,在构建代码时(我在Ubuntu 18.04.2 LTS计算机上使用GCC),我从链接器中收到一些“未定义的引用”错误。
由于有多个功能会发生错误,因此我仅提供一个示例代码。这是我的源文件:
openthread / src / core / crypto / ecp.cpp:
#include "ecp.hpp"
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/ecp.h>
#include <mbedtls/pk.h>
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/random.hpp"
#include "openthread/entropy.h"
#include "openthread/random_crypto.h"
namespace ot {
namespace Crypto {
#if OPENTHREAD_ENABLE_EST_CLIENT && OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
otError Ecp::KeyPairGeneration(const uint8_t *aPersonalSeed,
uint32_t aPersonalSeedLength,
uint8_t * aPrivateKey,
uint32_t * aPrivateKeyLength,
uint8_t * aPublicKey,
uint32_t * aPublicKeyLength)
{
otError error = OT_ERROR_NONE;
mbedtls_pk_context keypair;
OT_UNUSED_VARIABLE(aPersonalSeed);
OT_UNUSED_VARIABLE(aPersonalSeedLength);
mbedtls_pk_init(&keypair);
// Generate keypair
VerifyOrExit(mbedtls_pk_setup(&keypair, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)),
error = OT_ERROR_FAILED);
VerifyOrExit(mbedtls_ecp_group_load(&mbedtls_pk_ec(keypair)->grp, MBEDTLS_ECP_DP_SECP256R1) == 0,
error = OT_ERROR_FAILED);
VerifyOrExit(mbedtls_ecp_gen_keypair(&mbedtls_pk_ec(keypair)->grp, &mbedtls_pk_ec(keypair)->d,
&mbedtls_pk_ec(keypair)->Q, mbedtls_ctr_drbg_random,
Random::Crypto::MbedTlsContextGet()) == 0,
error = OT_ERROR_FAILED);
VerifyOrExit(mbedtls_pk_write_pubkey_pem(&keypair, (unsigned char*)aPublicKey,
*aPublicKeyLength) == 0,
error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(mbedtls_pk_write_key_pem(&keypair, (unsigned char*)aPrivateKey,
*aPrivateKeyLength) == 0,
error = OT_ERROR_INVALID_ARGS);
exit:
mbedtls_pk_free(&keypair);
return error;
}
#endif // OPENTHREAD_ENABLE_EST_CLIENT
} // namespace Crypto
} // namespace ot
我的头文件:
openthread / src / core / crypto / ecp.hpp
#ifndef ECP_HPP_
#define ECP_HPP_
#include "openthread-core-config.h"
#include <stdint.h>
#include <stdlib.h>
#include <openthread/error.h>
namespace ot {
namespace Crypto {
/**
* @addtogroup core-security
*
* @{
*
*/
/**
* This class implements elliptic curve key generation.
*
*/
class Ecp
{
public:
/**
* This method generate a Elliptic Curve key pair.
*
* @param[in] aPersonalSeed An additional seed for the entropy. Can be NULL.
* @param[in] aPersonalSeedLengh The length of the @p aPersonalSeed.
* @param[out] aPrivateKey An output buffer where the private key should be stored.
* @param[inout] aPrivateKeyLength The length of the @p aPrivateKey buffer.
* @param[out] aPublicKey An output buffer where the private key should be stored.
* @param[inout] aPublicKeyLength The length of the @p aPublicKey buffer.
*
* @retval OT_ERROR_NONE EC key pairs has been created successfully.
* OT_ERROR_NO_BUFS Key buffers are too small or mbedtls heap too small.
*/
static otError KeyPairGeneration(const uint8_t *aPersonalSeed,
uint32_t aPersonalSeedLength,
uint8_t * aPrivateKey,
uint32_t * aPrivateKeyLength,
uint8_t * aPublicKey,
uint32_t * aPublicKeyLength);
};
/**
* @}
*
*/
} // namespace Crypto
} // namespace ot
#endif // ECP_HPP_
导致错误的函数在此处为mbedtls_pk_write_pubkey_pem和mbedtls_pk_write_key_pem。
这也是控制台输出的一部分:
Making all in apps
Making all in cli
CC ot_cli_ftd-main.o
CC ot_cli_mtd-main.o
CCLD ot-cli-ftd
CCLD ot-cli-mtd
/opt/gcc-arm-none-eabi-8-2018-q4-major/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld: ../../../src/core/libopenthread-mtd.a(libopenthread_mtd_a-ecp.o): in function `ot::Crypto::Ecp::KeyPairGeneration(unsigned char const*, unsigned long, unsigned char*, unsigned long*, unsigned char*, unsigned long*)':
/home/scnm/eclipse-workspace/openthread/examples/../src/core/crypto/ecp.cpp:79: undefined reference to `mbedtls_pk_write_pubkey_pem'
/opt/gcc-arm-none-eabi-8-2018-q4-major/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld: /home/scnm/eclipse-workspace/openthread/examples/../src/core/crypto/ecp.cpp:83: undefined reference to `mbedtls_pk_write_key_pem'
collect2: error: ld returned 1 exit status
Makefile:1249: recipe for target 'ot-cli-mtd' failed
make[5]: *** [ot-cli-mtd] Error 1
我首先想到的是,因为我缺少一些#define才能实际使用这些功能,但是我将其与其他使用mbedtls的OpenThread代码进行了比较,但我看不出我做错了什么。据我了解,我必须修改“ openthread / third_party / mbedtls / mbedtls-config.h”文件,以便构建这些功能,这就是我所做的:
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <openthread/config.h>
#include <openthread/platform/logging.h>
#include <openthread/platform/memory.h>
#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf
#define MBEDTLS_AES_C
#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CMAC_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_ECJPAKE_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_NIST_OPTIM
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
#define MBEDTLS_MD_C
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_PLATFORM_C
#define MBEDTLS_PLATFORM_MEMORY
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA256_SMALLER
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
#define MBEDTLS_SSL_EXPORT_KEYS
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
#define MBEDTLS_SSL_PROTO_TLS1_2
#define MBEDTLS_SSL_PROTO_DTLS
#define MBEDTLS_SSL_TLS_C
#if OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER || OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
#define MBEDTLS_SSL_COOKIE_C
#define MBEDTLS_SSL_SRV_C
#endif
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#if OPENTHREAD_ENABLE_EST_CLIENT
#define MBEDTLS_PEM_WRITE_C
#define MBEDTLS_PK_WRITE_C
#define MBEDTLS_X509_CSR_WRITE_C
#define MBEDTLS_X509_CREATE_C
#endif
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#define MBEDTLS_BASE64_C
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_OID_C
#define MBEDTLS_PEM_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C
#endif
#if OPENTHREAD_ENABLE_ECDSA
#define MBEDTLS_BASE64_C
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_OID_C
#define MBEDTLS_PEM_PARSE_C
#endif
#define MBEDTLS_MPI_WINDOW_SIZE 1 /**< Maximum windows size used. */
#define MBEDTLS_MPI_MAX_SIZE 32 /**< Maximum number of bytes for usable MPIs. */
#define MBEDTLS_ECP_MAX_BITS 256 /**< Maximum bit size of groups */
#define MBEDTLS_ECP_WINDOW_SIZE 2 /**< Maximum window size used */
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Enable fixed-point speed-up */
#define MBEDTLS_ENTROPY_MAX_SOURCES 1 /**< Maximum number of sources supported */
#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
#define MBEDTLS_PLATFORM_STD_CALLOC otPlatCAlloc /**< Default allocator to use, can be undefined */
#define MBEDTLS_PLATFORM_STD_FREE otPlatFree /**< Default free to use, can be undefined */
#else
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
#endif
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
#define MBEDTLS_SSL_MAX_CONTENT_LEN 900 /**< Maxium fragment length in bytes */
#else
#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maxium fragment length in bytes */
#endif
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
#if defined(MBEDTLS_USER_CONFIG_FILE)
#include MBEDTLS_USER_CONFIG_FILE
#endif
#if defined(MBEDTLS_ECP_ALT) && !defined(MBEDTLS_ECP_RESTARTABLE)
typedef void mbedtls_ecp_restart_ctx;
#endif
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */
它解决了我以前遇到的“未在此范围内定义”错误,但是现在我遇到了上述错误。
这是我在通用开关文件中编辑的内容:
openthread / examples / common-switches.mk
ECDSA ?= 0
// my code begin
EST_CLIENT ?= 0
// my code end
JAM_DETECTION ?= 0
ifeq ($(ECDSA),1)
configure_OPTIONS += --enable-ecdsa
endif
// my code begin
ifeq ($(EST_CLIENT),1)
configure_OPTIONS += --enable-est-client --enable-application-coap-secure
endif
// my code end
ifeq ($(JAM_DETECTION),1)
configure_OPTIONS += --enable-jam-detection
endif
和她我要配置的内容:
openthread / configure.ac
#
# EST Client
#
AC_ARG_ENABLE(est_client,
[AS_HELP_STRING([--enable-est-client],[Enable EST client support @<:@default=no@:>@.])],
[
case "${enableval}" in
no|yes)
enable_est_client=${enableval}
;;
*)
AC_MSG_ERROR([Invalid value ${enable_est_client} for --enable-est-client])
;;
esac
],
[enable_est_client=no])
if test "$enable_est_client" = "yes"; then
OPENTHREAD_ENABLE_EST_CLIENT=1
else
OPENTHREAD_ENABLE_EST_CLIENT=0
fi
AC_SUBST(OPENTHREAD_ENABLE_EST_CLIENT)
AM_CONDITIONAL([OPENTHREAD_ENABLE_EST_CLIENT], [test "${enable_est_client}" = "yes"])
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_EST_CLIENT],[${OPENTHREAD_ENABLE_EST_CLIENT}],[Define to 1 if you want to enable EST Client])
OpenThread DNS Client support : ${enable_dns_client}
// my code begin
OpenThread EST Client support : ${enable_est_client}
// my code end
OpenThread SNTP Client support : ${enable_sntp_client}
我还编辑了makefile:
openthread / src / core / Makefile.am
crypto/ecdsa.hpp \
crypto/ecp.hpp \
crypto/hmac_sha256.hpp \
crypto/ecdsa.cpp \
crypto/ecp.cpp \
crypto/hmac_sha256.cpp \
我的构建命令是“ make -f examples / Makefile-nrf52840 EST_CLIENT = 1”。
我认为这个问题一旦解决,我就可以自己解决其他问题,因为问题的根源似乎是相同的。
谢谢。
答案 0 :(得分:0)
您在链接期间出错,未定义符号mbedtls_pk_write_pubkey_pem
,这意味着您错过了指定定义它的库的权限。在网络上浏览似乎需要链接 mbedcrypto ,因此添加 libmbedcrypto.a 或 -lmbedcrypto (并且可以使用选项{ {1}}指定路径)
如果您缺少与 mbedx509 的符号-L
链接,似乎还使用X509,因此添加 libmbedx509.a 或 -lmbedx509 < / em>(并且可以使用选项*X509*
指定路径)