Skip to content

Commit

Permalink
Address further review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ksperling-apple committed Nov 6, 2023
1 parent 9b21b59 commit 87db9cf
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 79 deletions.
14 changes: 7 additions & 7 deletions src/credentials/CHIPCert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1440,12 +1440,13 @@ void InitNetworkIdentitySubject(ChipDN & name)
VerifyOrDie(err == CHIP_NO_ERROR); // AddAttribute can't fail in this case
}

static void CalculateKeyIdentifierSha256(const P256PublicKeySpan & publicKey, MutableCertificateKeyId keyId)
static CHIP_ERROR CalculateKeyIdentifierSha256(const P256PublicKeySpan & publicKey, MutableCertificateKeyId keyId)
{
uint8_t hash[kSHA256_Hash_Length];
static_assert(keyId.size() <= sizeof(hash)); // truncating 32 bytes down to 20
chip::Crypto::Hash_SHA256(publicKey.data(), publicKey.size(), hash);
ReturnErrorOnFailure(Hash_SHA256(publicKey.data(), publicKey.size(), hash));
memcpy(keyId.data(), hash, keyId.size());
return CHIP_NO_ERROR;
}

static CHIP_ERROR ValidateChipNetworkIdentity(const ChipCertificateData & certData)
Expand Down Expand Up @@ -1484,7 +1485,7 @@ CHIP_ERROR ValidateChipNetworkIdentity(const ByteSpan & cert, MutableCertificate
ChipCertificateData certData;
ReturnErrorOnFailure(DecodeChipCert(cert, certData, CertDecodeFlags::kGenerateTBSHash));
ReturnErrorOnFailure(ValidateChipNetworkIdentity(certData));
CalculateKeyIdentifierSha256(certData.mPublicKey, keyId);
ReturnErrorOnFailure(CalculateKeyIdentifierSha256(certData.mPublicKey, keyId));
return CHIP_NO_ERROR;
}

Expand All @@ -1493,18 +1494,18 @@ CHIP_ERROR ExtractIdentifierFromChipNetworkIdentity(const ByteSpan & cert, Mutab
ChipCertificateData certData;
ReturnErrorOnFailure(DecodeChipCert(cert, certData));
ReturnErrorOnFailure(ValidateCertificateType(certData, CertType::kNetworkIdentity));
CalculateKeyIdentifierSha256(certData.mPublicKey, keyId);
ReturnErrorOnFailure(CalculateKeyIdentifierSha256(certData.mPublicKey, keyId));
return CHIP_NO_ERROR;
}

static CHIP_ERROR GenerateNetworkIdentitySignature(const P256Keypair & keypair, P256ECDSASignature & signature)
{
// Create a buffer and writer to capture the TBS (to-be-signed) portion of the certificate.
chip::Platform::ScopedMemoryBuffer<uint8_t> asn1TBSBuf;
VerifyOrReturnError(asn1TBSBuf.Alloc(kNetworkIdenitityTBSLength), CHIP_ERROR_NO_MEMORY);
VerifyOrReturnError(asn1TBSBuf.Alloc(kNetworkIdentityTBSLength), CHIP_ERROR_NO_MEMORY);

ASN1Writer writer;
writer.Init(asn1TBSBuf.Get(), kNetworkIdenitityTBSLength);
writer.Init(asn1TBSBuf.Get(), kNetworkIdentityTBSLength);

// Generate the TBSCertificate and sign it
ReturnErrorOnFailure(EncodeNetworkIdentityTBSCert(keypair.Pubkey(), writer));
Expand Down Expand Up @@ -1537,7 +1538,6 @@ CHIP_ERROR NewChipNetworkIdentity(const Crypto::P256Keypair & keypair, MutableBy

P256PublicKeySpan publicKeySpan(keypair.Pubkey().ConstBytes());
P256ECDSASignatureSpan signatureSpan(signature.ConstBytes());
VerifyOrDie(signature.Length() == signatureSpan.size());
ReturnErrorOnFailure(EncodeCompactIdentityCert(writer, AnonymousTag(), publicKeySpan, signatureSpan));

compactIdentityCert.reduce_size(writer.GetLengthWritten());
Expand Down
2 changes: 1 addition & 1 deletion src/credentials/CHIPCertToX509.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ CHIP_ERROR DecodeChipCert(TLVReader & reader, ChipCertificateData & certData, Bi

// Hash the encoded TBS certificate. Only SHA256 is supported.
VerifyOrReturnError(certData.mSigAlgoOID == kOID_SigAlgo_ECDSAWithSHA256, CHIP_ERROR_UNSUPPORTED_SIGNATURE_TYPE);
chip::Crypto::Hash_SHA256(asn1TBSBuf.Get(), tbsWriter.GetLengthWritten(), certData.mTBSHash);
ReturnErrorOnFailure(Hash_SHA256(asn1TBSBuf.Get(), tbsWriter.GetLengthWritten(), certData.mTBSHash));
certData.mCertFlags.Set(CertFlags::kTBSHashPresent);
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/credentials/CHIPCert_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace Credentials {
inline constexpr size_t kMaxCHIPCertDecodeBufLength = kMaxDERCertLength - Crypto::kMax_ECDSA_Signature_Length_Der;

// The TBSCerticate of a Network (Client) Identity has a fixed (smaller) size.
inline constexpr size_t kNetworkIdenitityTBSLength = 244;
inline constexpr size_t kNetworkIdentityTBSLength = 244;

// Constants for Network (Client) Identities as per section 11.24 (Wi-Fi
// Authentication with Per-Device Credentials) of the Matter spec.
Expand Down
138 changes: 68 additions & 70 deletions src/tools/chip-cert/CertUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ bool SetCertSerialNumber(X509 * cert, uint64_t value = kUseRandomSerialNumber)
}

// Avoid negative numbers.
value = rnd & 0x7FFFFFFFFFFFFFFF;
value = rnd & 0x7FFFFFFFFFFFFFFFULL;
}

// Store the serial number as an ASN1 integer value within the certificate.
Expand Down Expand Up @@ -860,7 +860,7 @@ bool MakeCert(CertType certType, const ToolChipDN * subjectDN, X509 * caCert, EV
EVP_PKEY * newKey, CertStructConfig & certConfig)
{
bool res = true;
bool isCA = (certType != CertType::kNode && certType != CertType::kNetworkIdentity);
bool isCA = (certType == CertType::kRoot || certType == CertType::kICA);

VerifyOrExit(subjectDN != nullptr, res = false);
VerifyOrExit(caCert != nullptr, res = false);
Expand Down Expand Up @@ -1051,84 +1051,83 @@ CHIP_ERROR MakeCertTLV(CertType certType, const ToolChipDN * subjectDN, X509 * c

ReturnErrorOnFailure(writer.StartContainer(AnonymousTag(), kTLVType_Structure, containerType));

// serial number
if (!useCompactIdentityFormat && certConfig.IsSerialNumberPresent())
{
ASN1_INTEGER * asn1Integer = X509_get_serialNumber(x509Cert);
uint64_t serialNumber;
uint8_t serialNumberArray[sizeof(uint64_t)];
VerifyOrReturnError(1 == ASN1_INTEGER_get_uint64(&serialNumber, asn1Integer), CHIP_ERROR_INVALID_ARGUMENT);
Encoding::BigEndian::Put64(serialNumberArray, serialNumber);
ReturnErrorOnFailure(writer.PutBytes(ContextTag(kTag_SerialNumber), serialNumberArray, sizeof(serialNumberArray)));
}

// signature algorithm
if (!useCompactIdentityFormat)
{
// serial number
if (certConfig.IsSerialNumberPresent())
{
ASN1_INTEGER * asn1Integer = X509_get_serialNumber(x509Cert);
uint64_t serialNumber;
uint8_t serialNumberArray[sizeof(uint64_t)];
VerifyOrReturnError(1 == ASN1_INTEGER_get_uint64(&serialNumber, asn1Integer), CHIP_ERROR_INVALID_ARGUMENT);
Encoding::BigEndian::Put64(serialNumberArray, serialNumber);
ReturnErrorOnFailure(writer.PutBytes(ContextTag(kTag_SerialNumber), serialNumberArray, sizeof(serialNumberArray)));
}

// signature algorithm
ReturnErrorOnFailure(writer.Put(ContextTag(kTag_SignatureAlgorithm), certConfig.GetSignatureAlgorithmTLVEnum()));
}

// issuer Name
if (!useCompactIdentityFormat && certConfig.IsIssuerPresent())
{
if (certType == CertType::kRoot)
// issuer Name
if (certConfig.IsIssuerPresent())
{
ReturnErrorOnFailure(subjectDN->EncodeToTLV(writer, ContextTag(kTag_Issuer)));
if (certType == CertType::kRoot)
{
ReturnErrorOnFailure(subjectDN->EncodeToTLV(writer, ContextTag(kTag_Issuer)));
}
else
{
uint8_t caChipCertBuf[kMaxCHIPCertLength];
MutableByteSpan caChipCert(caChipCertBuf);
VerifyOrReturnError(true == X509ToChipCert(caCert, caChipCert), CHIP_ERROR_INVALID_ARGUMENT);
ChipDN issuerDN;
ReturnErrorOnFailure(ExtractSubjectDNFromChipCert(caChipCert, issuerDN));
ReturnErrorOnFailure(issuerDN.EncodeToTLV(writer, ContextTag(kTag_Issuer)));
}
}

// validity
uint32_t validFromChipEpoch;
uint32_t validToChipEpoch;

VerifyOrReturnError(
true ==
CalendarToChipEpochTime(static_cast<uint16_t>(validFrom.tm_year + 1900), static_cast<uint8_t>(validFrom.tm_mon + 1),
static_cast<uint8_t>(validFrom.tm_mday), static_cast<uint8_t>(validFrom.tm_hour),
static_cast<uint8_t>(validFrom.tm_min), static_cast<uint8_t>(validFrom.tm_sec),
validFromChipEpoch),
CHIP_ERROR_INVALID_ARGUMENT);
if (validDays == kCertValidDays_NoWellDefinedExpiration)
{
validToChipEpoch = 0;
}
else
{
uint8_t caChipCertBuf[kMaxCHIPCertLength];
MutableByteSpan caChipCert(caChipCertBuf);
VerifyOrReturnError(true == X509ToChipCert(caCert, caChipCert), CHIP_ERROR_INVALID_ARGUMENT);
ChipDN issuerDN;
ReturnErrorOnFailure(ExtractSubjectDNFromChipCert(caChipCert, issuerDN));
ReturnErrorOnFailure(issuerDN.EncodeToTLV(writer, ContextTag(kTag_Issuer)));
VerifyOrReturnError(CanCastTo<uint32_t>(validFromChipEpoch + validDays * kSecondsPerDay - 1),
CHIP_ERROR_INVALID_ARGUMENT);
validToChipEpoch = validFromChipEpoch + validDays * kSecondsPerDay - 1;
}
if (!certConfig.IsValidityCorrect())
{
uint32_t validTemp = validFromChipEpoch;
validFromChipEpoch = validToChipEpoch;
validToChipEpoch = validTemp;
}
if (certConfig.IsValidityNotBeforePresent())
{
ReturnErrorOnFailure(writer.Put(ContextTag(kTag_NotBefore), validFromChipEpoch));
}
if (certConfig.IsValidityNotAfterPresent())
{
ReturnErrorOnFailure(writer.Put(ContextTag(kTag_NotAfter), validToChipEpoch));
}
}

// validity
uint32_t validFromChipEpoch;
uint32_t validToChipEpoch;

VerifyOrReturnError(true ==
CalendarToChipEpochTime(
static_cast<uint16_t>(validFrom.tm_year + 1900), static_cast<uint8_t>(validFrom.tm_mon + 1),
static_cast<uint8_t>(validFrom.tm_mday), static_cast<uint8_t>(validFrom.tm_hour),
static_cast<uint8_t>(validFrom.tm_min), static_cast<uint8_t>(validFrom.tm_sec), validFromChipEpoch),
CHIP_ERROR_INVALID_ARGUMENT);
if (validDays == kCertValidDays_NoWellDefinedExpiration)
{
validToChipEpoch = 0;
}
else
{
VerifyOrReturnError(CanCastTo<uint32_t>(validFromChipEpoch + validDays * kSecondsPerDay - 1), CHIP_ERROR_INVALID_ARGUMENT);
validToChipEpoch = validFromChipEpoch + validDays * kSecondsPerDay - 1;
}
if (!certConfig.IsValidityCorrect())
{
uint32_t validTemp = validFromChipEpoch;
validFromChipEpoch = validToChipEpoch;
validToChipEpoch = validTemp;
}
if (!useCompactIdentityFormat && certConfig.IsValidityNotBeforePresent())
{
ReturnErrorOnFailure(writer.Put(ContextTag(kTag_NotBefore), validFromChipEpoch));
}
if (!useCompactIdentityFormat && certConfig.IsValidityNotAfterPresent())
{
ReturnErrorOnFailure(writer.Put(ContextTag(kTag_NotAfter), validToChipEpoch));
}

// subject Name
if (!useCompactIdentityFormat && certConfig.IsSubjectPresent())
{
ReturnErrorOnFailure(subjectDN->EncodeToTLV(writer, ContextTag(kTag_Subject)));
}
// subject Name
if (certConfig.IsSubjectPresent())
{
ReturnErrorOnFailure(subjectDN->EncodeToTLV(writer, ContextTag(kTag_Subject)));
}

// public key algorithm
if (!useCompactIdentityFormat)
{
// public key algorithm
ReturnErrorOnFailure(writer.Put(ContextTag(kTag_PublicKeyAlgorithm), GetOIDEnum(kOID_PubKeyAlgo_ECPublicKey)));

// public key curve Id
Expand Down Expand Up @@ -1161,7 +1160,6 @@ CHIP_ERROR MakeCertTLV(CertType certType, const ToolChipDN * subjectDN, X509 * c
ReturnErrorOnFailure(writer.PutBoolean(ContextTag(kTag_BasicConstraints_IsCA),
certConfig.IsExtensionBasicCACorrect() ? isCA : !isCA));
}
// TODO
if (pathLen != kPathLength_NotSpecified)
{
ReturnErrorOnFailure(
Expand Down

0 comments on commit 87db9cf

Please sign in to comment.