Skip to content

Commit

Permalink
Update mbedTLS tests, define certificate size as per spec
Browse files Browse the repository at this point in the history
  • Loading branch information
jpk233 committed Jun 2, 2021
1 parent a36794b commit 9136fa8
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 8 deletions.
39 changes: 39 additions & 0 deletions src/credentials/tests/CHIPCert_test_vectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ CHIP_ERROR GetTestCert(uint8_t certType, BitFlags<TestCertLoadFlags> certLoadFla
SELECT_CERT(Node02_05);
SELECT_CERT(Node02_06);
SELECT_CERT(Node02_07);
#undef SELECT_CERT

err = CHIP_ERROR_CA_CERT_NOT_FOUND;

Expand Down Expand Up @@ -133,6 +134,44 @@ const char * GetTestCertName(uint8_t certType)
return nullptr;
}

CHIP_ERROR GetTestCertPubkey(uint8_t certType, const uint8_t *& certPubkey, uint32_t & certPubkeyLen)
{
CHIP_ERROR err;

#define SELECT_CERT(NAME) \
do \
{ \
if (certType == TestCert::k##NAME) \
{ \
certPubkey = sTestCert_##NAME##_PublicKey; \
certPubkeyLen = sTestCert_##NAME##_PublicKey_Len; \
ExitNow(err = CHIP_NO_ERROR); \
} \
} while (0)

SELECT_CERT(Root01);
SELECT_CERT(Root02);
SELECT_CERT(ICA01);
SELECT_CERT(ICA02);
SELECT_CERT(ICA01_1);
SELECT_CERT(FWSign01);
SELECT_CERT(Node01_01);
SELECT_CERT(Node01_02);
SELECT_CERT(Node02_01);
SELECT_CERT(Node02_02);
SELECT_CERT(Node02_03);
SELECT_CERT(Node02_04);
SELECT_CERT(Node02_05);
SELECT_CERT(Node02_06);
SELECT_CERT(Node02_07);
#undef SELECT_CERT

err = CHIP_ERROR_CA_CERT_NOT_FOUND;

exit:
return err;
}

CHIP_ERROR LoadTestCert(ChipCertificateSet & certSet, uint8_t certType, BitFlags<TestCertLoadFlags> certLoadFlags,
BitFlags<CertDecodeFlags> decodeFlags)
{
Expand Down
1 change: 1 addition & 0 deletions src/credentials/tests/CHIPCert_test_vectors.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ enum class TestCertLoadFlags : uint8_t
extern CHIP_ERROR GetTestCert(uint8_t certType, BitFlags<TestCertLoadFlags> certLoadFlags, const uint8_t *& certData,
uint32_t & certDataLen);
extern const char * GetTestCertName(uint8_t certType);
extern CHIP_ERROR GetTestCertPubkey(uint8_t certType, const uint8_t *& certPubkey, uint32_t & certPubkeyLen);
extern CHIP_ERROR LoadTestCert(ChipCertificateSet & certSet, uint8_t certType, BitFlags<TestCertLoadFlags> certLoadFlags,
BitFlags<CertDecodeFlags> decodeFlags);

Expand Down
5 changes: 4 additions & 1 deletion src/crypto/CHIPCryptoPAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@

#include <core/CHIPError.h>
#include <support/CodeUtils.h>
#include <support/Span.h>

#include <stddef.h>
#include <string.h>

namespace chip {
namespace Crypto {

const size_t kMax_x509_Certificate_Length = 1024;
const size_t kMax_x509_Certificate_Length = 600;

const size_t kP256_FE_Length = 32;
const size_t kP256_Point_Length = (2 * kP256_FE_Length + 1);
Expand Down Expand Up @@ -911,6 +912,8 @@ CHIP_ERROR GetNumberOfCertsFromPKCS7(const uint8_t * pkcs7, uint32_t * n_certs);
CHIP_ERROR ValidateCertificateChain(const uint8_t * rootCertificate, size_t rootCertificateLen, const uint8_t * caCertificate,
size_t caCertificateLen, const uint8_t * leafCertificate, size_t leafCertificateLen);

CHIP_ERROR ExtractPubkeyFromX509Cert(const ByteSpan & certificate, Crypto::P256PublicKey & pubkey);

} // namespace Crypto
} // namespace chip

Expand Down
37 changes: 31 additions & 6 deletions src/crypto/CHIPCryptoPALOpenSSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1584,7 +1584,6 @@ CHIP_ERROR LoadCertsFromPKCS7(const uint8_t * pkcs7, X509DerCertificate * x509li
bio_cert = BIO_new_mem_buf(pkcs7, -1);

p7 = PEM_read_bio_PKCS7(bio_cert, NULL, NULL, NULL);
// TODO -> error value
VerifyOrExit(p7 != nullptr, err = CHIP_ERROR_WRONG_CERT_TYPE);

p7_type = OBJ_obj2nid(p7->type);
Expand All @@ -1597,7 +1596,6 @@ CHIP_ERROR LoadCertsFromPKCS7(const uint8_t * pkcs7, X509DerCertificate * x509li
certs = p7->d.signed_and_enveloped->cert;
}

// TODO -> error value
VerifyOrExit(certs != NULL, err = CHIP_ERROR_WRONG_CERT_TYPE);
VerifyOrExit(static_cast<uint32_t>(sk_X509_num(certs)) <= *max_certs, err = CHIP_ERROR_WRONG_CERT_TYPE);

Expand Down Expand Up @@ -1639,7 +1637,6 @@ CHIP_ERROR LoadCertFromPKCS7(const uint8_t * pkcs7, X509DerCertificate * x509lis
bio_cert = BIO_new_mem_buf(pkcs7, -1);

p7 = PEM_read_bio_PKCS7(bio_cert, NULL, NULL, NULL);
// TODO -> error value
VerifyOrExit(p7 != nullptr, err = CHIP_ERROR_WRONG_CERT_TYPE);

p7_type = OBJ_obj2nid(p7->type);
Expand All @@ -1652,7 +1649,6 @@ CHIP_ERROR LoadCertFromPKCS7(const uint8_t * pkcs7, X509DerCertificate * x509lis
certs = p7->d.signed_and_enveloped->cert;
}

// TODO -> error value
VerifyOrExit(certs != NULL, err = CHIP_ERROR_WRONG_CERT_TYPE);
VerifyOrExit(n_cert < static_cast<uint32_t>(sk_X509_num(certs)), err = CHIP_ERROR_INVALID_ARGUMENT);

Expand Down Expand Up @@ -1691,7 +1687,6 @@ CHIP_ERROR GetNumberOfCertsFromPKCS7(const uint8_t * pkcs7, uint32_t * n_certs)
bio_cert = BIO_new_mem_buf(pkcs7, -1);

p7 = PEM_read_bio_PKCS7(bio_cert, NULL, NULL, NULL);
// TODO -> error value
VerifyOrExit(p7 != nullptr, err = CHIP_ERROR_WRONG_CERT_TYPE);

p7_type = OBJ_obj2nid(p7->type);
Expand All @@ -1704,7 +1699,6 @@ CHIP_ERROR GetNumberOfCertsFromPKCS7(const uint8_t * pkcs7, uint32_t * n_certs)
certs = p7->d.signed_and_enveloped->cert;
}

// TODO -> error value
VerifyOrExit(certs != NULL, err = CHIP_ERROR_WRONG_CERT_TYPE);

*n_certs = static_cast<uint32_t>(sk_X509_num(certs));
Expand Down Expand Up @@ -1765,5 +1759,36 @@ CHIP_ERROR ValidateCertificateChain(const uint8_t * rootCertificate, size_t root
return err;
}

CHIP_ERROR ExtractPubkeyFromX509Cert(const ByteSpan & certificate, Crypto::P256PublicKey & pubkey)
{
CHIP_ERROR err = CHIP_NO_ERROR;
EVP_PKEY * pkey = nullptr;
X509 * x509certificate = nullptr;
const unsigned char * pCertificate = certificate.data();
const unsigned char ** ppCertificate = &pCertificate;
unsigned char * pPubkey = pubkey;
unsigned char ** ppPubkey = &pPubkey;
int pkeyLen;

x509certificate = d2i_X509(NULL, ppCertificate, static_cast<long>(certificate.size()));
VerifyOrExit(x509certificate != nullptr, err = CHIP_ERROR_NO_MEMORY);

pkey = X509_get_pubkey(x509certificate);
VerifyOrExit(pkey != nullptr, err = CHIP_ERROR_INTERNAL);
VerifyOrExit(EVP_PKEY_base_id(pkey) == EVP_PKEY_EC, err = CHIP_ERROR_INTERNAL);
VerifyOrExit(EVP_PKEY_bits(pkey) == 256, err = CHIP_ERROR_INTERNAL);

pkeyLen = i2d_PublicKey(pkey, NULL);
VerifyOrExit(pkeyLen == static_cast<int>(pubkey.Length()), err = CHIP_ERROR_INTERNAL);

VerifyOrExit(i2d_PublicKey(pkey, ppPubkey) == pkeyLen, err = CHIP_ERROR_INTERNAL);

exit:
EVP_PKEY_free(pkey);
X509_free(x509certificate);

return err;
}

} // namespace Crypto
} // namespace chip
5 changes: 5 additions & 0 deletions src/crypto/CHIPCryptoPALmbedTLS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1219,5 +1219,10 @@ CHIP_ERROR ValidateCertificateChain(const uint8_t * rootCertificate, size_t root
return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ExtractPubkeyFromX509Cert(const ByteSpan & certificate, Crypto::P256PublicKey & pubkey)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}

} // namespace Crypto
} // namespace chip
1 change: 1 addition & 0 deletions src/crypto/tests/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ chip_test_suite("tests") {
cflags = [ "-Wconversion" ]

public_deps = [
"${chip_root}/src/credentials/tests:cert_test_vectors",
"${chip_root}/src/crypto",
"${chip_root}/src/lib/core",
"${chip_root}/src/platform",
Expand Down
41 changes: 40 additions & 1 deletion src/crypto/tests/CHIPCryptoPALTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include "SPAKE2P_POINT_RW_test_vectors.h"
#include "SPAKE2P_POINT_VALID_test_vectors.h"
#include "SPAKE2P_RFC_test_vectors.h"
#include "X509_PKCS7Extraction_test_vectors.h"

#include <crypto/CHIPCryptoPAL.h>
#if CHIP_CRYPTO_HSM
Expand All @@ -50,6 +49,13 @@
#include <stdlib.h>
#include <string.h>

#if CHIP_CRYPTO_OPENSSL
#include "X509_PKCS7Extraction_test_vectors.h"
#endif

#include <credentials/CHIPCert.h>
#include <credentials/tests/CHIPCert_test_vectors.h>

#define HSM_ECC_KEYID 0x11223344

using namespace chip;
Expand Down Expand Up @@ -1429,6 +1435,8 @@ static void TestSPAKE2P_RFC(nlTestSuite * inSuite, void * inContext)
NL_TEST_ASSERT(inSuite, numOfTestsRan == numOfTestVectors);
}

// TODO: Add mbedTLS implementation for PKCS7 and Pubkey Extraction methods
#if CHIP_CRYPTO_OPENSSL
static void TestX509_PKCS7Extraction(nlTestSuite * inSuite, void * inContext)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand All @@ -1448,6 +1456,34 @@ static void TestX509_PKCS7Extraction(nlTestSuite * inSuite, void * inContext)
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
}

static void TestPubkey_x509Extraction(nlTestSuite * inSuite, void * inContext)
{
using namespace TestCerts;

CHIP_ERROR err = CHIP_NO_ERROR;
P256PublicKey publicKey;

const uint8_t * cert;
uint32_t certLen;
const uint8_t * certPubkey;
uint32_t certPubkeyLen;

for (size_t i = 0; i < gNumTestCerts; i++)
{
uint8_t certType = TestCerts::gTestCerts[i];

err = GetTestCert(certType, TestCertLoadFlags::kDERForm, cert, certLen);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
err = GetTestCertPubkey(certType, certPubkey, certPubkeyLen);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

err = ExtractPubkeyFromX509Cert(ByteSpan(cert, certLen), publicKey);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, memcmp(publicKey, certPubkey, certPubkeyLen) == 0);
}
}
#endif // CHIP_CRYPTO_OPENSSL

/**
* Test Suite. It lists all the test functions.
*/
Expand Down Expand Up @@ -1502,7 +1538,10 @@ static const nlTest sTests[] = {
NL_TEST_DEF("Test Spake2p_spake2p PointLoad/PointWrite", TestSPAKE2P_spake2p_PointLoadWrite),
NL_TEST_DEF("Test Spake2p_spake2p PointIsValid", TestSPAKE2P_spake2p_PointIsValid),
NL_TEST_DEF("Test Spake2+ against RFC test vectors", TestSPAKE2P_RFC),
#if CHIP_CRYPTO_OPENSSL
NL_TEST_DEF("Test x509 Certificate Extraction from PKCS7", TestX509_PKCS7Extraction),
NL_TEST_DEF("Test Pubkey Extraction from x509 Certificate", TestPubkey_x509Extraction),
#endif // CHIP_CRYPTO_OPENSSL
NL_TEST_SENTINEL()
};

Expand Down

0 comments on commit 9136fa8

Please sign in to comment.