Skip to content

Commit

Permalink
Addressed Review Comments and More Minor Updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
emargolis committed Jun 16, 2021
1 parent f6a48e6 commit 059a1f5
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 147 deletions.
4 changes: 2 additions & 2 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,15 +261,15 @@ CHIP_ERROR DeviceController::LoadLocalCredentials(Transport::AdminPairingInfo *

uint8_t * chipCert = buffer1.Get();
uint32_t chipCertLen = 0;
ReturnErrorOnFailure(ConvertX509CertToChipCert(cert, certLen, chipCert, kMaxCHIPOpCertLength, chipCertLen));
ReturnErrorOnFailure(ConvertX509CertToChipCert(ByteSpan(cert, certLen), chipCert, kMaxCHIPOpCertLength, chipCertLen));

ReturnErrorOnFailure(admin->SetOperationalCert(ByteSpan(chipCert, chipCertLen)));

ChipLogProgress(Controller, "Getting root certificate for the controller from the issuer");
ReturnErrorOnFailure(mOperationalCredentialsDelegate->GetRootCACertificate(0, cert, kMaxCHIPOpCertLength, certLen));

chipCertLen = 0;
ReturnErrorOnFailure(ConvertX509CertToChipCert(cert, certLen, chipCert, kMaxCHIPOpCertLength, chipCertLen));
ReturnErrorOnFailure(ConvertX509CertToChipCert(ByteSpan(cert, certLen), chipCert, kMaxCHIPOpCertLength, chipCertLen));

ReturnErrorOnFailure(admin->SetRootCert(ByteSpan(chipCert, chipCertLen)));

Expand Down
58 changes: 30 additions & 28 deletions src/credentials/CHIPCert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,8 @@ CHIP_ERROR ChipCertificateSet::VerifySignature(const ChipCertificateData * cert,
P256ECDSASignature signature;
uint16_t derSigLen;

ReturnErrorOnFailure(ConvertECDSASignatureRawToDER(cert->mSignature.data(), static_cast<uint16_t>(cert->mSignature.size()),
signature, static_cast<uint16_t>(signature.Capacity()), derSigLen));
ReturnErrorOnFailure(
ConvertECDSASignatureRawToDER(cert->mSignature, signature, static_cast<uint16_t>(signature.Capacity()), derSigLen));

ReturnErrorOnFailure(signature.SetLength(derSigLen));

Expand Down Expand Up @@ -831,48 +831,52 @@ DLL_EXPORT CHIP_ERROR ChipEpochToASN1Time(uint32_t epochTime, chip::ASN1::ASN1Un
return CHIP_NO_ERROR;
}

CHIP_ERROR ConvertIntegerDERToRaw(const uint8_t * derInt, uint16_t derIntLen, uint8_t * rawInt, const uint16_t rawIntLen)
CHIP_ERROR ConvertIntegerDERToRaw(ByteSpan derInt, uint8_t * rawInt, const uint16_t rawIntLen)
{
VerifyOrReturnError(derInt != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(derIntLen > 0, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(!derInt.empty(), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(rawInt != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

const uint8_t * derIntData = derInt.data();
size_t derIntLen = derInt.size();

/* one leading zero is allowed for positive integer in ASN1 DER format */
if (*derInt == 0)
if (*derIntData == 0)
{
derInt++;
derIntData++;
derIntLen--;
}

VerifyOrReturnError(derIntLen <= rawIntLen, CHIP_ERROR_INVALID_ARGUMENT);

if (derIntLen > 0)
{
VerifyOrReturnError(*derInt != 0, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(*derIntData != 0, CHIP_ERROR_INVALID_ARGUMENT);
}

memset(rawInt, 0, (rawIntLen - derIntLen));
memcpy(rawInt + (rawIntLen - derIntLen), derInt, derIntLen);
memcpy(rawInt + (rawIntLen - derIntLen), derIntData, derIntLen);

return CHIP_NO_ERROR;
}

CHIP_ERROR ConvertIntegerRawToDER(const uint8_t * rawInt, uint16_t rawIntLen, uint8_t * derInt, const uint16_t derIntBufSize,
uint16_t & derIntLen)
CHIP_ERROR ConvertIntegerRawToDER(P256IntegerSpan rawInt, uint8_t * derInt, const uint16_t derIntBufSize, uint16_t & derIntLen)
{
VerifyOrReturnError(rawInt != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(rawIntLen > 0, CHIP_ERROR_INVALID_ARGUMENT);
static_assert(rawInt.size() <= UINT16_MAX - 1, "P256 raw integer doesn't fit in a uint16_t");

VerifyOrReturnError(!rawInt.empty(), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(derInt != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

while (*rawInt == 0)
const uint8_t * rawIntData = rawInt.data();
size_t rawIntLen = rawInt.size();

while (*rawIntData == 0)
{
rawInt++;
rawIntData++;
rawIntLen--;
}

if (*rawInt & 0x80) /* Need Leading Zero */
if (*rawIntData & 0x80) /* Need Leading Zero */
{
VerifyOrReturnError(rawIntLen <= UINT16_MAX - 1, CHIP_ERROR_BUFFER_TOO_SMALL);
VerifyOrReturnError(derIntBufSize >= rawIntLen + 1, CHIP_ERROR_BUFFER_TOO_SMALL);

*derInt++ = 0;
Expand All @@ -882,15 +886,15 @@ CHIP_ERROR ConvertIntegerRawToDER(const uint8_t * rawInt, uint16_t rawIntLen, ui
{
VerifyOrReturnError(derIntBufSize >= rawIntLen, CHIP_ERROR_BUFFER_TOO_SMALL);

derIntLen = rawIntLen;
derIntLen = static_cast<uint16_t>(rawIntLen);
}

memcpy(derInt, rawInt, rawIntLen);
memcpy(derInt, rawIntData, rawIntLen);

return CHIP_NO_ERROR;
}

CHIP_ERROR ConvertECDSASignatureRawToDER(const uint8_t * rawSig, uint16_t rawSigLen, uint8_t * derSig, const uint16_t derSigBufSize,
CHIP_ERROR ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan rawSig, uint8_t * derSig, const uint16_t derSigBufSize,
uint16_t & derSigLen)
{
static constexpr size_t kMaxBytesForDeferredLenList = sizeof(uint8_t *) + // size of a single pointer in the deferred list
Expand All @@ -900,13 +904,11 @@ CHIP_ERROR ConvertECDSASignatureRawToDER(const uint8_t * rawSig, uint16_t rawSig
uint8_t localDERSigBuf[kMax_ECDSA_Signature_Length + kMaxBytesForDeferredLenList];
ASN1Writer writer;

VerifyOrReturnError(rawSig != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(rawSigLen > 0, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(derSig != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

writer.Init(localDERSigBuf, sizeof(localDERSigBuf));

ReturnErrorOnFailure(ConvertECDSASignatureRawToDER(rawSig, rawSigLen, writer));
ReturnErrorOnFailure(ConvertECDSASignatureRawToDER(rawSig, writer));

ReturnErrorOnFailure(writer.Finalize());

Expand All @@ -919,24 +921,24 @@ CHIP_ERROR ConvertECDSASignatureRawToDER(const uint8_t * rawSig, uint16_t rawSig
return CHIP_NO_ERROR;
}

CHIP_ERROR ConvertECDSASignatureRawToDER(const uint8_t * rawSig, uint16_t rawSigLen, ASN1Writer & writer)
CHIP_ERROR ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan rawSig, ASN1Writer & writer)
{
CHIP_ERROR err = CHIP_NO_ERROR;
uint8_t derInt[kP256_FE_Length + 1];
uint16_t derIntLen;

VerifyOrReturnError(rawSig != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(rawSigLen == kP256_ECDSA_Signature_Length_Raw, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(!rawSig.empty(), CHIP_ERROR_INVALID_ARGUMENT);

// Ecdsa-Sig-Value ::= SEQUENCE
ASN1_START_SEQUENCE
{
// r INTEGER
ReturnErrorOnFailure(ConvertIntegerRawToDER(rawSig, kP256_FE_Length, derInt, sizeof(derInt), derIntLen));
ReturnErrorOnFailure(ConvertIntegerRawToDER(P256IntegerSpan(rawSig.data()), derInt, sizeof(derInt), derIntLen));
ReturnErrorOnFailure(writer.PutValue(kASN1TagClass_Universal, kASN1UniversalTag_Integer, false, derInt, derIntLen));

// s INTEGER
ReturnErrorOnFailure(ConvertIntegerRawToDER(rawSig + kP256_FE_Length, kP256_FE_Length, derInt, sizeof(derInt), derIntLen));
ReturnErrorOnFailure(
ConvertIntegerRawToDER(P256IntegerSpan(rawSig.data() + kP256_FE_Length), derInt, sizeof(derInt), derIntLen));
ReturnErrorOnFailure(writer.PutValue(kASN1TagClass_Universal, kASN1UniversalTag_Integer, false, derInt, derIntLen));
}
ASN1_END_SEQUENCE;
Expand Down
40 changes: 19 additions & 21 deletions src/credentials/CHIPCert.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ typedef FixedByteSpan<Crypto::kP256_ECDSA_Signature_Length_Raw> P256ECDSASignatu
*/
typedef FixedByteSpan<Crypto::kP256_Point_Length> P256PublicKeySpan;

/**
* @brief A data structure for holding a P256 Integer, without the ownership of it.
*/
typedef FixedByteSpan<Crypto::kP256_FE_Length> P256IntegerSpan;

/**
* @struct ChipCertificateData
*
Expand Down Expand Up @@ -613,16 +618,15 @@ CHIP_ERROR DecodeChipDN(chip::TLV::TLVReader & reader, ChipDN & dn);
/**
* @brief Convert standard X.509 certificate to CHIP certificate.
*
* @param x509Cert Buffer containing X.509 DER encoded certificate.
* @param x509CertLen The length of the X.509 DER encoded certificate.
* @param x509Cert CHIP X.509 DER encoded certificate.
* @param chipCertBuf Buffer to store converted certificate in CHIP format.
* @param chipCertBufSize The size of the buffer to store converted certificate.
* @param chipCertLen The length of the converted certificate.
*
* @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
**/
CHIP_ERROR ConvertX509CertToChipCert(const uint8_t * x509Cert, uint32_t x509CertLen, uint8_t * chipCertBuf,
uint32_t chipCertBufSize, uint32_t & chipCertLen);
CHIP_ERROR ConvertX509CertToChipCert(const ByteSpan x509Cert, uint8_t * chipCertBuf, uint32_t chipCertBufSize,
uint32_t & chipCertLen);

/**
* @brief Convert standard X.509 certificates to CHIP certificate array.
Expand All @@ -648,16 +652,15 @@ CHIP_ERROR ConvertX509CertsToChipCertArray(const ByteSpan & x509NOC, const ByteS
/**
* @brief Convert CHIP certificate to the standard X.509 DER encoded certificate.
*
* @param chipCert Buffer containing CHIP certificate.
* @param chipCertLen The length of the CHIP certificate.
* @param chipCert CHIP certificate in CHIP TLV encoding.
* @param x509CertBuf Buffer to store converted certificate in X.509 DER format.
* @param x509CertBufSize The size of the buffer to store converted certificate.
* @param x509CertLen The length of the converted certificate.
*
* @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
**/
CHIP_ERROR ConvertChipCertToX509Cert(const uint8_t * chipCert, uint32_t chipCertLen, uint8_t * x509CertBuf,
uint32_t x509CertBufSize, uint32_t & x509CertLen);
CHIP_ERROR ConvertChipCertToX509Cert(const ByteSpan chipCert, uint8_t * x509CertBuf, uint32_t x509CertBufSize,
uint32_t & x509CertLen);

/**
* @brief Generate a standard X.509 DER encoded certificate using provided CHIP certificate and signing key
Expand Down Expand Up @@ -798,53 +801,48 @@ inline bool IsChipDNAttr(chip::ASN1::OID oid)
/**
* @brief Convert an ASN.1 DER encoded integer to a raw big-endian integer.
*
* @param derInt Buffer that holds ASN.1 DER encoded integer.
* @param derIntLen The length of the ASN.1 DER encoded integer.
* @param derInt P256 integer in ASN.1 DER encoded form.
* @param rawInt Buffer to store converted raw integer.
* @param rawIntLen The length of the converted raw integer.
*
* @retval #CHIP_NO_ERROR If the integer value was successfully converted.
*/
CHIP_ERROR ConvertIntegerDERToRaw(const uint8_t * derInt, uint16_t derIntLen, uint8_t * rawInt, const uint16_t rawIntLen);
CHIP_ERROR ConvertIntegerDERToRaw(ByteSpan derInt, uint8_t * rawInt, const uint16_t rawIntLen);

/**
* @brief Convert a raw integer in big-endian form to an ASN.1 DER encoded integer.
*
* @param rawInt Buffer that holds raw integer.
* @param rawIntLen The length of the raw integer.
* @param rawInt P256 integer in raw form.
* @param derInt Buffer to store converted ASN.1 DER encoded integer.
* @param derIntBufSize The size of the buffer to store ASN.1 DER encoded integer.
* @param derIntLen The length of the ASN.1 DER encoded integer.
*
* @retval #CHIP_NO_ERROR If the integer value was successfully converted.
*/
CHIP_ERROR ConvertIntegerRawToDER(const uint8_t * rawInt, uint16_t rawIntLen, uint8_t * derInt, const uint16_t derIntBufSize,
uint16_t & derIntLen);
CHIP_ERROR ConvertIntegerRawToDER(P256IntegerSpan rawInt, uint8_t * derInt, const uint16_t derIntBufSize, uint16_t & derIntLen);

/**
* @brief Convert a raw CHIP signature to an ASN.1 DER encoded signature structure.
*
* @param rawSig Buffer that holds raw CHIP signature.
* @param rawSigLen The length of the raw CHIP signature.
* @param rawSig P256 ECDSA signature in raw form.
* @param derSig Buffer to store converted ASN.1 DER encoded signature.
* @param derSigBufSize The size of the buffer to store ASN.1 DER encoded signature.
* @param derSigLen The length of the ASN.1 DER encoded signature.
*
* @retval #CHIP_NO_ERROR If the signature value was successfully converted.
*/
CHIP_ERROR ConvertECDSASignatureRawToDER(const uint8_t * rawSig, uint16_t rawSigLen, uint8_t * derSig, const uint16_t derSigBufSize,
CHIP_ERROR ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan rawSig, uint8_t * derSig, const uint16_t derSigBufSize,
uint16_t & derSigLen);

/**
* @brief Convert a raw CHIP ECDSA signature to an ASN.1 DER encoded signature structure.
*
* @param rawSig Buffer that holds raw CHIP signature.
* @param rawSigLen The length of the raw CHIP signature.
* @param rawSig P256 ECDSA signature in raw form.
* @param writer A reference to the ASN1Writer to store ASN.1 DER encoded signature.
*
* @retval #CHIP_NO_ERROR If the signature value was successfully converted.
*/
CHIP_ERROR ConvertECDSASignatureRawToDER(const uint8_t * rawSig, uint16_t rawSigLen, ASN1::ASN1Writer & writer);
CHIP_ERROR ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan rawSig, ASN1::ASN1Writer & writer);

/**
* @brief Convert an ASN.1 DER encoded ECDSA signature to a raw CHIP signature.
Expand Down
33 changes: 15 additions & 18 deletions src/credentials/CHIPCertFromX509.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,15 +554,13 @@ CHIP_ERROR ConvertECDSASignatureDERToRaw(ASN1Reader & reader, TLVWriter & writer
{
// r INTEGER
ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_Integer);
VerifyOrReturnError(reader.GetValueLen() <= UINT16_MAX, CHIP_ERROR_INVALID_ARGUMENT);
ReturnErrorOnFailure(
ConvertIntegerDERToRaw(reader.GetValue(), static_cast<uint16_t>(reader.GetValueLen()), rawSig, kP256_FE_Length));
ConvertIntegerDERToRaw(ByteSpan(reader.GetValue(), reader.GetValueLen()), rawSig, kP256_FE_Length));

// s INTEGER
ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_Integer);
VerifyOrReturnError(reader.GetValueLen() <= UINT16_MAX, CHIP_ERROR_INVALID_ARGUMENT);
ReturnErrorOnFailure(ConvertIntegerDERToRaw(reader.GetValue(), static_cast<uint16_t>(reader.GetValueLen()),
rawSig + kP256_FE_Length, kP256_FE_Length));
ReturnErrorOnFailure(ConvertIntegerDERToRaw(ByteSpan(reader.GetValue(), reader.GetValueLen()), rawSig + kP256_FE_Length,
kP256_FE_Length));
}
ASN1_EXIT_SEQUENCE;
}
Expand Down Expand Up @@ -702,37 +700,36 @@ static CHIP_ERROR ConvertCertificate(ASN1Reader & reader, TLVWriter & writer, ui
return err;
}

DLL_EXPORT CHIP_ERROR ConvertX509CertToChipCert(const uint8_t * x509Cert, uint32_t x509CertLen, uint8_t * chipCertBuf,
uint32_t chipCertBufSize, uint32_t & chipCertLen)
DLL_EXPORT CHIP_ERROR ConvertX509CertToChipCert(const ByteSpan x509Cert, uint8_t * chipCertBuf, uint32_t chipCertBufSize,
uint32_t & chipCertLen)
{
CHIP_ERROR err;
ASN1Reader reader;
TLVWriter writer;

uint64_t issuer, subject, fabric;

reader.Init(x509Cert, x509CertLen);
VerifyOrReturnError(!x509Cert.empty(), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(CanCastTo<uint32_t>(x509Cert.size()), CHIP_ERROR_INVALID_ARGUMENT);

reader.Init(x509Cert.data(), static_cast<uint32_t>(x509Cert.size()));

writer.Init(chipCertBuf, chipCertBufSize);

err = ConvertCertificate(reader, writer, ProfileTag(Protocols::OpCredentials::Id.ToTLVProfileId(), kTag_ChipCertificate),
issuer, subject, fabric);
SuccessOrExit(err);
ReturnErrorOnFailure(ConvertCertificate(
reader, writer, ProfileTag(Protocols::OpCredentials::Id.ToTLVProfileId(), kTag_ChipCertificate), issuer, subject, fabric));

err = writer.Finalize();
SuccessOrExit(err);
ReturnErrorOnFailure(writer.Finalize());

chipCertLen = writer.GetLengthWritten();

exit:
return err;
return CHIP_NO_ERROR;
}

CHIP_ERROR ConvertX509CertsToChipCertArray(const ByteSpan & x509NOC, const ByteSpan & x509ICAC, uint8_t * chipCertArrayBuf,
uint32_t chipCertArrayBufSize, uint32_t & chipCertBufLen)
{
// NOC is mandatory
VerifyOrReturnError(x509NOC.size() > 0, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(!x509NOC.empty(), CHIP_ERROR_INVALID_ARGUMENT);

TLVWriter writer;
writer.Init(chipCertArrayBuf, chipCertArrayBufSize);
Expand All @@ -747,7 +744,7 @@ CHIP_ERROR ConvertX509CertsToChipCertArray(const ByteSpan & x509NOC, const ByteS
ReturnErrorOnFailure(ConvertCertificate(reader, writer, AnonymousTag, nocIssuer, nocSubject, nocFabric));

// ICAC is optional
if (x509ICAC.size() > 0)
if (!x509ICAC.empty())
{
VerifyOrReturnError(CanCastTo<uint32_t>(x509ICAC.size()), CHIP_ERROR_INVALID_ARGUMENT);
reader.Init(x509ICAC.data(), static_cast<uint32_t>(x509ICAC.size()));
Expand Down
Loading

0 comments on commit 059a1f5

Please sign in to comment.