1

A client sends to me a message signed with a private key, type ECDSA secp256R1. I'm in possession of a leaf certificate, in DER format, provided by the client. In addition, I also have the raw message and a sha256 digest of the msg.

I have created a struct where to store all the required info for the verification, with the idea of providing a public API in my application:

struct SignatureVerifyData {
    unsigned char *msg;
    unsigned char *hash; // digest sha256 of msg
    unsigned char *cert; // leaf cert in DER
    unsigned char *signature; 
    size_t msg_len;
    size_t hash_len;
    size_t cert_len;
    size_t signature_len;
};

I'm reading the ecdsa.c example from MbedTLS, but in this case the cert is generated in the same example, I can use mbedtls_x509_crt_parse_der() to load my leaf cert, but then, should I to move it to a mbedtls_ecdsa_context object to use with mbedtls_ecdsa_read_signature()?

Should I use other way to load the leaf cert?

Confused on how to use the group and point objects, or if I need to use them at all.

#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_TIME
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
#define MBEDTLS_PLATFORM_C
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_2
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_GCM_C
#define MBEDTLS_MD_C
#define MBEDTLS_NET_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA384_C
#define MBEDTLS_SHA512_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_BASE64_C
#define MBEDTLS_PEM_PARSE_C
#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_MPI_MAX_SIZE    48 // 384-bit EC curve = 48 bytes
#define MBEDTLS_ECP_WINDOW_SIZE        2
#define MBEDTLS_ECP_FIXED_POINT_OPTIM  0
#define MBEDTLS_ECP_NIST_OPTIM
#define MBEDTLS_ENTROPY_MAX_SOURCES 2
#define MBEDTLS_SSL_CIPHERSUITES                        \
    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,    \
    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
#define MBEDTLS_SSL_IN_CONTENT_LEN             1024
#define MBEDTLS_SSL_OUT_CONTENT_LEN             1024
#include "mbedtls/check_config.h"
jfreek
  • 21
  • 1

1 Answers1

-1

mbedtls_x509_crt_parse_der constructs an object of type mbedtls_x509_crt. This structure has a field called pk which contains the public key. Call mbedtls_pk_verify to verify the signature.

Here's the general idea of the code to parse the certificate, calculate the hash and verify the signature. Untested code, typed directly into my browser. Error checking omitted, be sure to check that all the function calls succeed.

#include <mbedtls/md.h>
#include <mbedtls/pk.h>
#include <mbedtls/x509_crt.h>

mbedtls_x509_crt crt;
mbedtls_x509_init(&crt);
mbedtls_x509_crt_parse_der(&crt, cert, cert_len);

const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
hash_len = mbedtls_md_get_size(md_info);
hash = malloc(hash_len);
mbedtls_md(md_info, msg, msg_len, hash);

mbedtls_pk_verify(&crt->pk, MBEDTLS_MD_SHA256, hash, hash_len, signature, signature_len);

mbedtls_x509_free(&crt);
free(hash);
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254