Storing X509 Certificate

Hi, 

Platform: nRF54L15

SDK: V2.9.0

The application is Matter + BLE. 

We would like to use X509 certificates which will be used for authentication when the application is used in BLE. We would like to

  1. Store the certificate either in KMU(preferred, if possible) or in the Trusted storage.
  2. Extract the pubic key and the signature value for authentication. 

Is there a sample code or example for the above? I went the samples/crypto but could not find one.

Thanks.

Subu Muthu

  • Hi,

    Store the certificate either in KMU(preferred, if possible) or in the Trusted storage.

    Storing certificates in KMU is not supported. For certificates, the use of PSA PS API is recommended.

    Extract the pubic key and the signature value for authentication. 

    We recommend for public keys to be stored separately from certificates. As there is no standard methodology of mapping certificate with a certain public key, this would need to be done offline. Retrieving public key from the certificate (for example in .pem format) can be done using openssl x509.

    Best regards,
    Dejan

  • Hi Dejan, Thanks for the response.

    On #2. Extract public key and the signature value from the certification: I have tried the below approach.

    1. Use mbedtls x509 libraries and API's to parse and validate.  Mbedtils provides two API's for the certificate validation:
      1. int mbedtls_x509_crt_parse(mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen:Parse one DER-encoded or one or more concatenated PEM-encoded certificates and add them to the chained list.
        1. This gets the certificates(Device and CA) IN.
      2. 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) :  verify a chain of certificates.
    2. prj.conf
      1. CONFIG_MBEDTLS=y
        CONFIG_MBEDTLS_X509_LIBRARY=y
        CONFIG_MBEDTLS_X509_CRT_PARSE_C=y
        CONFIG_MBEDTLS_X509_USE_C=y
        CONFIG_MBEDTLS_MD_C=y
        CONFIG_MBEDTLS_USE_PSA_CRYPTO=y
        CONFIG_MBEDTLS_PK_PARSE_C=y
        
        CONFIG_MBEDTLS_X509_CREATE_C=y
        CONFIG_MBEDTLS_PEM_PARSE_C=y
    3. When trying to build, the following error occurs:
      1. Excerpt from build failure:
        
        [261/344] c++ obj/src/lib/core/error.ErrorStr.cpp.o
        [262/344] ar libSupportLayer.a
        [263/344] ar tracing.a
        [264/344] c++ obj/src/crypto/cryptopal_psa.CHIPCryptoPALmbedTLSCert.cpp.o
        FAILED: obj/src/crypto/cryptopal_psa.CHIPCryptoPALmbedTLSCert.cpp.o 
        ccache /opt/nordic/ncs/toolchains/b8efef2ad5/opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi-g
         
         "Note: I have removed content to simplify"
        
        
        ./../../../../../../../opt/nordic/ncs/v2.9.0/modules/lib/matter/src/crypto/CHIPCryptoPALmbedTLSCert.cpp: In function 'CHIP_ERROR chip::Crypto::VerifyCertificateSigningRequest(const uint8_t*, size_t, P256PublicKey&)':
        ../../../../../../../../opt/nordic/ncs/v2.9.0/modules/lib/matter/src/crypto/CHIPCryptoPALmbedTLSCert.cpp:69:15: error: 'mbedtls_pk_ec' was not declared in this scope; did you mean 'mbedtls_pk_free'?
           69 |     keypair = mbedtls_pk_ec(csr.CHIP_CRYPTO_PAL_PRIVATE_X509(pk));
              |               ^~~~~~~~~~~~~
              |               mbedtls_pk_free
        ../../../../../../../../opt/nordic/ncs/v2.9.0/modules/lib/matter/src/crypto/CHIPCryptoPALmbedTLSCert.cpp: In function 'CHIP_ERROR chip::Crypto::ExtractPubkeyFromX509Cert(const chip::ByteSpan&, P256PublicKey&)':
        ../../../../../../../../opt/nordic/ncs/v2.9.0/modules/lib/matter/src/crypto/CHIPCryptoPALmbedTLSCert.cpp:521:15: error: 'mbedtls_pk_ec' was not declared in this scope; did you mean 'mbedtls_pk_free'?
          521 |     keypair = mbedtls_pk_ec(mbed_cert.CHIP_CRYPTO_PAL_PRIVATE_X509(pk));
              |               ^~~~~~~~~~~~~
              |               mbedtls_pk_free
        At global scope:
        cc1plus: note: unrecognized command-line option '-Wno-unknown-warning-option' may have been intended to silence earlier diagnostics
        [265/344] c++ obj/src/lib/asn1/libASN1.ASN1Writer.cpp.o
        [266/344] c++ obj/src/lib/core/libChipCore.TLVTags.cpp.o
        [267/344] c++ obj/src/lib/core/libChipCore.TLVDebug.cpp.o
        [268/344] c++ obj/src/lib/core/libChipCore.TLVCircularBuffer.cpp.o
        [269/344] c++ obj/src/lib/core/libChipCore.TLVReader.cpp.o
        [270/344] c++ obj/src/lib/address_resolve/address_resolve.AddressResolve.cpp.o
        [271/344] c++ obj/src/lib/core/libChipCore.TLVUtilities.cpp.o
        [272/344] c++ obj/src/lib/core/libChipCore.TLVUpdater.cpp.o
        [273/344] c++ obj/src/lib/core/libChipCore.TLVWriter.cpp.o
        ninja: build stopped: subcommand failed.
      2.  Please note that I have the large block of message to simplify which I don't  think is needed.
    4. After going through "x509_crt.g" and "x509_crt.c" and other  materials, use of API's from mbedtls_x509_crt requires MBEDTLS_X509  libraries and also PK_PARSE_C. I also went through the   
      modules/lib/matter/src/crypto/CHIPCryptoPALmbedTLSCert.cpp file and enabling the X509 libraries enables part of the code.
      Note: I made this work without Matter, so these API's are the correct ones. However,
      #A. If it became clear or not,  the product is a Matter + BLE product and we need matter. When built with Matter, the   Matter code fails.  Please review the prj.conf and let me know.  
      #B: Matter is also using certificates so it must be reading the certificates, parsing and checking the signature. We must be able to use the similar method without any conflict. Can you please ask the Matter experts to suggest a solution?
      #C: I also contemplated other options. Using CMake, it may be possible to apply the MBEDTLS_X509 configuration specifically to my code. I tried the below:
      # Add application with a specific compile definition
      target_sources(app PRIVATE src/mti_src/crypto/mti_authentication.cpp)
      target_compile_definitions(app PRIVATE CONFIG_MBEDTLS_X509_LIBRARY=y)
      target_compile_definitions(app PRIVATE CONFIG_MBEDTLS_PK_PARSE_C=y)
      target_compile_definitions(app PRIVATE CONFIG_MBEDTLS_X509_CRT_PARSE_C=y)
      
      
      target_sources(app PRIVATE
          src/app_task.cpp
          src/bolt_lock_manager.cpp
          src/main.cpp
          src/zcl_callbacks.cpp
          ${access_srcs}
          src/mti_src/mti_main.cpp
      Note that mti_authentication.cpp is  the application. When tried, the build fails and the error is same as in #3 above. It does not look like the CONFIG is applied specifically to my code. If I am applying wrongly, please let me know.
      #4: I also attempted to male a copy of the source files (x509_crt.c and h) and modify which did not go very well - the API's are nested and it fails. Any suggestions will be helpful.
      The use case is as follows:
      1. A mobile device App and the Matter/BLE product needs to authenticate using X509 Certificates.
      2. The device is programmed/provisioned with X509 certificates (the standard root-of-trust, private key, certificate signed by CA etc).
      3. Mobile App gets its certificate.
      4. After BLE connection is made, Certificates are exchanged and verified.
      5. Authentication is done.
      Please let me know if other options are possible.
      Thanks.
  • Hi,

    Thank you for additional information. 
    I will discuss your questions with the Matter developers. I expect to get back to you by the end of this week.

    Best regards,
    Dejan

  • Hi,

    The easiest way to build Matter with given configuration is to remove "CHIPCryptoPALmbedTLSCert.cpp" as a source in source_set("cryptopal_psa") in Build.gn since we do not use X509 parsing defined there and do not support dependencies arising from MBEDTLS_X509_CSR_PARSE_C enabled.

    Best regards,
    Dejan

  • Thank  you and I will try it! Not sure if any other dependencies will show up. The build stopped when the failure occurred and did not go further.

    Meanwhile,  I started to take a different approach:

    Matter code has the below APIs for certificate validation and I thought why not make use of them. These API's are similar to Mbedtls' API's. I am guessing that Matter wrote the application using Mbedtls API's.

    1. Load the certificates using 

    CHIP_ERROR chip::Credentials::ConvertX509CertToChipCert(chip::ByteSpan x509Cert, chip::MutableByteSpan &chipCert)
    Convert standard X.509 certificate to CHIP certificate.
    
    Parameters:
    x509Cert – CHIP X.509 DER encoded certificate.
    chipCert – Buffer to store converted certificate in CHIP format.
    
    Returns:
    Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise

    2. Decode the certificates using 

    CHIP_ERROR chip::Credentials::DecodeChipCert(chip::ByteSpan chipCert, chip::Credentials::ChipCertificateData &certData, chip::BitFlags<chip::Credentials::CertDecodeFlags> decodeFlags = {(unsigned char)0U})
    +1 overload
    
    Decode CHIP certificate. It is required that the CHIP certificate in the chipCert buffer stays valid while the certData is used.
    
    Parameters:
    chipCert – Buffer containing CHIP certificate.
    certData – Structure containing data extracted from the CHIP certificate.
    
    Returns:
    Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise

    3. Verify the certificate signature using 

    CHIP_ERROR chip::Credentials::VerifyCertSignature(const chip::Credentials::ChipCertificateData &cert, const chip::Credentials::ChipCertificateData &signer)
    Verifies the signature of a certificate.
    
    Parameters:
    cert – The certificate to be verified.
    signer – The certificate containing the public key used to verify the signature.
    
    Returns:
    Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise

    I have been able to validate the Matter test certificates using the above. When I tried the in-house generated certificates, most of them worked expect for one  specific certificate. The root cause is pending.

    Matter uses ECDSA and we want to use EdDSA so not sure if EdDSA will work or not. Yet to be tried. Please let me know.

    We are going to try the one you recommended  but do you see any drawbacks with using Matter supplied API's? 

    Do you see long support for the Matter based API? we don't want to go with  a solution that will not be supported in the future. 

    Thanks.

    Subu Muthu

Related