diff --git a/src/credentials/CHIPCert.h b/src/credentials/CHIPCert.h index 4634db746d562a..8aa3e1f246a59c 100644 --- a/src/credentials/CHIPCert.h +++ b/src/credentials/CHIPCert.h @@ -658,14 +658,20 @@ CHIP_ERROR GenerateSignedX509CertFromChipCert(const uint8_t * chipCert, uint32_t struct X509CertRequestParams { - int64_t mSerialNumber; - uint64_t mIssuer; - uint32_t mValidityStart; - uint32_t mValidityEnd; - bool mHasFabricID; - uint64_t mFabricID; - bool mHasNodeID; - uint64_t mNodeID; + int64_t SerialNumber; + uint64_t Issuer; + uint32_t ValidityStart; + uint32_t ValidityEnd; + bool HasFabricID; + uint64_t FabricID; + bool HasNodeID; + uint64_t NodeID; +}; + +enum CertificateIssuerLevel +{ + kIssuerIsRootCA, + kIssuerIsIntermediateCA, }; /** @@ -679,7 +685,7 @@ struct X509CertRequestParams * * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ -CHIP_ERROR NewRootX509Cert(X509CertRequestParams & requestParams, Crypto::P256Keypair & issuerKeypair, uint8_t * x509CertBuf, +CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParams, Crypto::P256Keypair & issuerKeypair, uint8_t * x509CertBuf, uint32_t x509CertBufSize, uint32_t & x509CertLen); /** @@ -695,15 +701,15 @@ CHIP_ERROR NewRootX509Cert(X509CertRequestParams & requestParams, Crypto::P256Ke * * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ -CHIP_ERROR NewICAX509Cert(X509CertRequestParams & requestParams, uint64_t subject, const Crypto::P256PublicKey & subjectPubkey, - Crypto::P256Keypair & issuerKeypair, uint8_t * x509CertBuf, uint32_t x509CertBufSize, - uint32_t & x509CertLen); +CHIP_ERROR NewICAX509Cert(const X509CertRequestParams & requestParams, uint64_t subject, + const Crypto::P256PublicKey & subjectPubkey, Crypto::P256Keypair & issuerKeypair, uint8_t * x509CertBuf, + uint32_t x509CertBufSize, uint32_t & x509CertLen); /** * @brief Generate a new X.509 DER encoded Node operational certificate * * @param requestParams Certificate request parameters. - * @param rootCASigner Indicates if the signer is a root CA or an intermediate CA + * @param issuerLevel Indicates if the issuer is a root CA or an intermediate CA * @param subjectPubkey The public key of subject * @param issuerKeypair The certificate signing key * @param x509CertBuf Buffer to store signed certificate in X.509 DER format. @@ -712,7 +718,7 @@ CHIP_ERROR NewICAX509Cert(X509CertRequestParams & requestParams, uint64_t subjec * * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ -CHIP_ERROR NewNodeOperationalX509Cert(X509CertRequestParams & requestParams, bool rootCASigner, +CHIP_ERROR NewNodeOperationalX509Cert(const X509CertRequestParams & requestParams, CertificateIssuerLevel issuerLevel, const Crypto::P256PublicKey & subjectPubkey, Crypto::P256Keypair & issuerKeypair, uint8_t * x509CertBuf, uint32_t x509CertBufSize, uint32_t & x509CertLen); diff --git a/src/credentials/GenerateChipX509Cert.cpp b/src/credentials/GenerateChipX509Cert.cpp index 88c4ccfebd015d..e6dd8df059e025 100644 --- a/src/credentials/GenerateChipX509Cert.cpp +++ b/src/credentials/GenerateChipX509Cert.cpp @@ -44,6 +44,21 @@ namespace Credentials { using namespace chip::ASN1; using namespace chip::Protocols; +struct ChipDNParams +{ + OID AttrOID; + uint64_t Value; +}; + +enum IsCACert +{ + kCACert, + kNotCACert, +}; + +// For CHIP 64-bit DN attribute the string representation is 16 uppercase hex characters. +static constexpr uint8_t kChipDNAttributeLen = 16; + static CHIP_ERROR EncodeSubjectPublicKeyInfo(const Crypto::P256PublicKey & pubkey, ASN1Writer & writer) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -141,7 +156,7 @@ static CHIP_ERROR EncodeKeyUsageExtension(uint16_t keyUsageBits, ASN1Writer & wr return err; } -static CHIP_ERROR EncodeIsCAExtension(bool isCA, ASN1Writer & writer) +static CHIP_ERROR EncodeIsCAExtension(IsCACert isCA, ASN1Writer & writer) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -159,10 +174,10 @@ static CHIP_ERROR EncodeIsCAExtension(bool isCA, ASN1Writer & writer) ASN1_START_SEQUENCE { // cA BOOLEAN - if (isCA) + if (isCA == kCACert) { // Encode the boolean only if isCA is true - ASN1_ENCODE_BOOLEAN(isCA); + ASN1_ENCODE_BOOLEAN(true); } } ASN1_END_SEQUENCE; @@ -177,7 +192,7 @@ static CHIP_ERROR EncodeIsCAExtension(bool isCA, ASN1Writer & writer) static CHIP_ERROR EncodeCASpecificExtensions(ASN1Writer & writer) { - ReturnErrorOnFailure(EncodeIsCAExtension(true, writer)); + ReturnErrorOnFailure(EncodeIsCAExtension(kCACert, writer)); uint16_t keyUsageBits = static_cast(KeyUsageFlags::kKeyCertSign) | static_cast(KeyUsageFlags::kCRLSign); @@ -193,7 +208,7 @@ static CHIP_ERROR EncodeNOCSpecificExtensions(ASN1Writer & writer) uint16_t keyUsageBits = static_cast(KeyUsageFlags::kDigitalSignature) | static_cast(KeyUsageFlags::kKeyEncipherment); - ReturnErrorOnFailure(EncodeIsCAExtension(false, writer)); + ReturnErrorOnFailure(EncodeIsCAExtension(kNotCACert, writer)); ReturnErrorOnFailure(EncodeKeyUsageExtension(keyUsageBits, writer)); ASN1_START_SEQUENCE @@ -251,12 +266,6 @@ static CHIP_ERROR EncodeExtensions(bool isCA, const Crypto::P256PublicKey & SKI, return err; } -struct ChipDNParams -{ - OID mAttrOID; - uint64_t mValue; -}; - static CHIP_ERROR EncodeChipDNs(ChipDNParams * params, uint8_t numParams, ASN1Writer & writer) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -267,12 +276,12 @@ static CHIP_ERROR EncodeChipDNs(ChipDNParams * params, uint8_t numParams, ASN1Wr { ASN1_START_SET { - uint8_t chipAttrStr[17]; - snprintf(reinterpret_cast(chipAttrStr), sizeof(chipAttrStr), "%016" PRIX64, params[i].mValue); + uint8_t chipAttrStr[kChipDNAttributeLen + 1]; + snprintf(reinterpret_cast(chipAttrStr), sizeof(chipAttrStr), "%016" PRIX64, params[i].Value); ASN1_START_SEQUENCE { - ASN1_ENCODE_OBJECT_ID(params[i].mAttrOID); + ASN1_ENCODE_OBJECT_ID(params[i].AttrOID); ReturnErrorOnFailure(writer.PutString(kASN1UniversalTag_UTF8String, Uint8::to_const_char(chipAttrStr), 16)); } ASN1_END_SEQUENCE; @@ -331,7 +340,7 @@ static CHIP_ERROR EncodeChipECDSASignature(Crypto::P256ECDSASignature & signatur return err; } -CHIP_ERROR EncodeTBSCert(X509CertRequestParams & requestParams, bool rootCASigner, uint64_t subject, +CHIP_ERROR EncodeTBSCert(const X509CertRequestParams & requestParams, CertificateIssuerLevel issuerLevel, uint64_t subject, const Crypto::P256PublicKey & subjectPubkey, const Crypto::P256PublicKey & issuerPubkey, ASN1Writer & writer) { @@ -350,45 +359,45 @@ CHIP_ERROR EncodeTBSCert(X509CertRequestParams & requestParams, bool rootCASigne } ASN1_END_CONSTRUCTED; - ReturnErrorOnFailure(writer.PutInteger(requestParams.mSerialNumber)); + ReturnErrorOnFailure(writer.PutInteger(requestParams.SerialNumber)); ASN1_START_SEQUENCE { ASN1_ENCODE_OBJECT_ID(kOID_SigAlgo_ECDSAWithSHA256); } ASN1_END_SEQUENCE; // Issuer OID depends on if cert is being signed by the root CA - if (rootCASigner) + if (issuerLevel == kIssuerIsRootCA) { - dnParams[0].mAttrOID = chip::ASN1::kOID_AttributeType_ChipRootId; + dnParams[0].AttrOID = chip::ASN1::kOID_AttributeType_ChipRootId; } else { - dnParams[0].mAttrOID = chip::ASN1::kOID_AttributeType_ChipICAId; + dnParams[0].AttrOID = chip::ASN1::kOID_AttributeType_ChipICAId; } - dnParams[0].mValue = requestParams.mIssuer; + dnParams[0].Value = requestParams.Issuer; - if (requestParams.mHasFabricID) + if (requestParams.HasFabricID) { - dnParams[1].mAttrOID = chip::ASN1::kOID_AttributeType_ChipFabricId; - dnParams[1].mValue = requestParams.mFabricID; - numDNs = 2; + dnParams[1].AttrOID = chip::ASN1::kOID_AttributeType_ChipFabricId; + dnParams[1].Value = requestParams.FabricID; + numDNs = 2; } ReturnErrorOnFailure(EncodeChipDNs(dnParams, numDNs, writer)); // validity Validity, - ReturnErrorOnFailure(EncodeValidity(requestParams.mValidityStart, requestParams.mValidityEnd, writer)); + ReturnErrorOnFailure(EncodeValidity(requestParams.ValidityStart, requestParams.ValidityEnd, writer)); // subject Name - if (requestParams.mHasNodeID) + if (requestParams.HasNodeID) { - dnParams[0].mAttrOID = chip::ASN1::kOID_AttributeType_ChipNodeId; + dnParams[0].AttrOID = chip::ASN1::kOID_AttributeType_ChipNodeId; isCA = false; } else if (subjectPubkey != issuerPubkey) { - dnParams[0].mAttrOID = chip::ASN1::kOID_AttributeType_ChipICAId; + dnParams[0].AttrOID = chip::ASN1::kOID_AttributeType_ChipICAId; } - dnParams[0].mValue = subject; + dnParams[0].Value = subject; ReturnErrorOnFailure(EncodeChipDNs(dnParams, numDNs, writer)); @@ -403,7 +412,7 @@ CHIP_ERROR EncodeTBSCert(X509CertRequestParams & requestParams, bool rootCASigne return err; } -static CHIP_ERROR NewChipX509Cert(X509CertRequestParams & requestParams, bool rootCASigner, uint64_t subject, +static CHIP_ERROR NewChipX509Cert(const X509CertRequestParams & requestParams, CertificateIssuerLevel issuerLevel, uint64_t subject, const Crypto::P256PublicKey & subjectPubkey, Crypto::P256Keypair & issuerKeypair, uint8_t * x509CertBuf, uint32_t x509CertBufSize, uint32_t & x509CertLen) { @@ -411,7 +420,7 @@ static CHIP_ERROR NewChipX509Cert(X509CertRequestParams & requestParams, bool ro ASN1Writer writer; writer.Init(x509CertBuf, x509CertBufSize); - ReturnErrorOnFailure(EncodeTBSCert(requestParams, rootCASigner, subject, subjectPubkey, issuerKeypair.Pubkey(), writer)); + ReturnErrorOnFailure(EncodeTBSCert(requestParams, issuerLevel, subject, subjectPubkey, issuerKeypair.Pubkey(), writer)); writer.Finalize(); Crypto::P256ECDSASignature signature; @@ -421,7 +430,7 @@ static CHIP_ERROR NewChipX509Cert(X509CertRequestParams & requestParams, bool ro ASN1_START_SEQUENCE { - ReturnErrorOnFailure(EncodeTBSCert(requestParams, rootCASigner, subject, subjectPubkey, issuerKeypair.Pubkey(), writer)); + ReturnErrorOnFailure(EncodeTBSCert(requestParams, issuerLevel, subject, subjectPubkey, issuerKeypair.Pubkey(), writer)); SuccessOrExit(err); ASN1_START_SEQUENCE { ASN1_ENCODE_OBJECT_ID(kOID_SigAlgo_ECDSAWithSHA256); } @@ -439,29 +448,30 @@ static CHIP_ERROR NewChipX509Cert(X509CertRequestParams & requestParams, bool ro return err; } -DLL_EXPORT CHIP_ERROR NewRootX509Cert(X509CertRequestParams & requestParams, Crypto::P256Keypair & issuerKeypair, +DLL_EXPORT CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParams, Crypto::P256Keypair & issuerKeypair, uint8_t * x509CertBuf, uint32_t x509CertBufSize, uint32_t & x509CertLen) { - ReturnErrorCodeIf(requestParams.mHasNodeID, CHIP_ERROR_INVALID_ARGUMENT); - return NewChipX509Cert(requestParams, true, requestParams.mIssuer, issuerKeypair.Pubkey(), issuerKeypair, x509CertBuf, + ReturnErrorCodeIf(requestParams.HasNodeID, CHIP_ERROR_INVALID_ARGUMENT); + return NewChipX509Cert(requestParams, kIssuerIsRootCA, requestParams.Issuer, issuerKeypair.Pubkey(), issuerKeypair, x509CertBuf, x509CertBufSize, x509CertLen); } -DLL_EXPORT CHIP_ERROR NewICAX509Cert(X509CertRequestParams & requestParams, uint64_t subject, +DLL_EXPORT CHIP_ERROR NewICAX509Cert(const X509CertRequestParams & requestParams, uint64_t subject, const Crypto::P256PublicKey & subjectPubkey, Crypto::P256Keypair & issuerKeypair, uint8_t * x509CertBuf, uint32_t x509CertBufSize, uint32_t & x509CertLen) { - ReturnErrorCodeIf(requestParams.mHasNodeID, CHIP_ERROR_INVALID_ARGUMENT); - return NewChipX509Cert(requestParams, true, subject, subjectPubkey, issuerKeypair, x509CertBuf, x509CertBufSize, x509CertLen); + ReturnErrorCodeIf(requestParams.HasNodeID, CHIP_ERROR_INVALID_ARGUMENT); + return NewChipX509Cert(requestParams, kIssuerIsRootCA, subject, subjectPubkey, issuerKeypair, x509CertBuf, x509CertBufSize, + x509CertLen); } -DLL_EXPORT CHIP_ERROR NewNodeOperationalX509Cert(X509CertRequestParams & requestParams, bool rootCASigner, +DLL_EXPORT CHIP_ERROR NewNodeOperationalX509Cert(const X509CertRequestParams & requestParams, CertificateIssuerLevel issuerLevel, const Crypto::P256PublicKey & subjectPubkey, Crypto::P256Keypair & issuerKeypair, uint8_t * x509CertBuf, uint32_t x509CertBufSize, uint32_t & x509CertLen) { - VerifyOrReturnError(requestParams.mHasNodeID, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(requestParams.mHasFabricID, CHIP_ERROR_INVALID_ARGUMENT); - return NewChipX509Cert(requestParams, rootCASigner, requestParams.mNodeID, subjectPubkey, issuerKeypair, x509CertBuf, + VerifyOrReturnError(requestParams.HasNodeID, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(requestParams.HasFabricID, CHIP_ERROR_INVALID_ARGUMENT); + return NewChipX509Cert(requestParams, issuerLevel, requestParams.NodeID, subjectPubkey, issuerKeypair, x509CertBuf, x509CertBufSize, x509CertLen); } diff --git a/src/credentials/tests/TestChipCert.cpp b/src/credentials/tests/TestChipCert.cpp index 8d2a6ea1b31cdb..f9fe2bdd62a383 100644 --- a/src/credentials/tests/TestChipCert.cpp +++ b/src/credentials/tests/TestChipCert.cpp @@ -661,7 +661,7 @@ static void TestChipCert_GenerateRootCert(nlTestSuite * inSuite, void * inContex NL_TEST_ASSERT(inSuite, DecodeChipCert(outCertBuf, outCertLen, certData) == CHIP_NO_ERROR); // Test that root cert cannot be provided a node ID - root_params.mHasNodeID = true; + root_params.HasNodeID = true; NL_TEST_ASSERT(inSuite, NewRootX509Cert(root_params, keypair, signed_cert, sizeof(signed_cert), signed_len) == CHIP_ERROR_INVALID_ARGUMENT); @@ -720,7 +720,7 @@ static void TestChipCert_GenerateICACert(nlTestSuite * inSuite, void * inContext NL_TEST_ASSERT(inSuite, DecodeChipCert(outCertBuf, outCertLen, certData) == CHIP_NO_ERROR); // Test that ICA cert cannot be provided a node ID - ica_params.mHasNodeID = true; + ica_params.HasNodeID = true; NL_TEST_ASSERT(inSuite, NewICAX509Cert(ica_params, 4321, ica_keypair.Pubkey(), keypair, signed_cert, sizeof(signed_cert), signed_len) == CHIP_ERROR_INVALID_ARGUMENT); @@ -745,8 +745,8 @@ static void TestChipCert_GenerateNOCRoot(nlTestSuite * inSuite, void * inContext NL_TEST_ASSERT(inSuite, noc_keypair.Initialize() == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, - NewNodeOperationalX509Cert(noc_params, true, noc_keypair.Pubkey(), keypair, signed_cert, sizeof(signed_cert), - signed_len) == CHIP_NO_ERROR); + NewNodeOperationalX509Cert(noc_params, kIssuerIsRootCA, noc_keypair.Pubkey(), keypair, signed_cert, + sizeof(signed_cert), signed_len) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, ConvertX509CertToChipCert(signed_cert, signed_len, outCertBuf, sizeof(outCertBuf), outCertLen) == CHIP_NO_ERROR); @@ -754,17 +754,17 @@ static void TestChipCert_GenerateNOCRoot(nlTestSuite * inSuite, void * inContext NL_TEST_ASSERT(inSuite, DecodeChipCert(outCertBuf, outCertLen, certData) == CHIP_NO_ERROR); // Test that NOC cert must be provided a node ID - noc_params.mHasNodeID = false; + noc_params.HasNodeID = false; NL_TEST_ASSERT(inSuite, - NewNodeOperationalX509Cert(noc_params, true, noc_keypair.Pubkey(), keypair, signed_cert, sizeof(signed_cert), - signed_len) == CHIP_ERROR_INVALID_ARGUMENT); + NewNodeOperationalX509Cert(noc_params, kIssuerIsRootCA, noc_keypair.Pubkey(), keypair, signed_cert, + sizeof(signed_cert), signed_len) == CHIP_ERROR_INVALID_ARGUMENT); // Test that NOC cert must be provided a fabric ID - noc_params.mHasNodeID = true; - noc_params.mHasFabricID = false; + noc_params.HasNodeID = true; + noc_params.HasFabricID = false; NL_TEST_ASSERT(inSuite, - NewNodeOperationalX509Cert(noc_params, true, noc_keypair.Pubkey(), keypair, signed_cert, sizeof(signed_cert), - signed_len) == CHIP_ERROR_INVALID_ARGUMENT); + NewNodeOperationalX509Cert(noc_params, kIssuerIsRootCA, noc_keypair.Pubkey(), keypair, signed_cert, + sizeof(signed_cert), signed_len) == CHIP_ERROR_INVALID_ARGUMENT); } static void TestChipCert_GenerateNOCICA(nlTestSuite * inSuite, void * inContext) @@ -786,8 +786,8 @@ static void TestChipCert_GenerateNOCICA(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, noc_keypair.Initialize() == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, - NewNodeOperationalX509Cert(noc_params, false, noc_keypair.Pubkey(), keypair, signed_cert, sizeof(signed_cert), - signed_len) == CHIP_NO_ERROR); + NewNodeOperationalX509Cert(noc_params, kIssuerIsIntermediateCA, noc_keypair.Pubkey(), keypair, signed_cert, + sizeof(signed_cert), signed_len) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, ConvertX509CertToChipCert(signed_cert, signed_len, outCertBuf, sizeof(outCertBuf), outCertLen) == CHIP_NO_ERROR); diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index f7725e9c5949c5..5db4148a7fed56 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -297,16 +297,12 @@ CHIP_ERROR Hash_SHA256(const uint8_t * data, const size_t data_length, uint8_t * CHIP_ERROR Hash_SHA1(const uint8_t * data, const size_t data_length, uint8_t * out_buffer) { - CHIP_ERROR error = CHIP_NO_ERROR; - // zero data length hash is supported. - - VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); SHA1(data, data_length, Uint8::to_uchar(out_buffer)); -exit: - return error; + return CHIP_NO_ERROR; } Hash_SHA256_stream::Hash_SHA256_stream() {} diff --git a/src/crypto/CHIPCryptoPALmbedTLS.cpp b/src/crypto/CHIPCryptoPALmbedTLS.cpp index 9eb65c4ced6575..396a02ec17ea61 100644 --- a/src/crypto/CHIPCryptoPALmbedTLS.cpp +++ b/src/crypto/CHIPCryptoPALmbedTLS.cpp @@ -192,18 +192,15 @@ CHIP_ERROR Hash_SHA256(const uint8_t * data, const size_t data_length, uint8_t * CHIP_ERROR Hash_SHA1(const uint8_t * data, const size_t data_length, uint8_t * out_buffer) { - CHIP_ERROR error = CHIP_NO_ERROR; - int result = 0; + int result = 0; // zero data length hash is supported. - - VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); result = mbedtls_sha1_ret(Uint8::to_const_uchar(data), data_length, Uint8::to_uchar(out_buffer)); - VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); + VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL); -exit: - return error; + return CHIP_NO_ERROR; } Hash_SHA256_stream::Hash_SHA256_stream(void) {}