@@ -1095,12 +1095,19 @@ DLL_EXPORT CHIP_ERROR ChipEpochToASN1Time(uint32_t epochTime, chip::ASN1::ASN1Un
1095
1095
return CHIP_NO_ERROR;
1096
1096
}
1097
1097
1098
+ static CHIP_ERROR ValidateCertificateType (const ChipCertificateData & certData, CertType expectedType)
1099
+ {
1100
+ CertType certType;
1101
+ ReturnErrorOnFailure (certData.mSubjectDN .GetCertType (certType));
1102
+ VerifyOrReturnError (certType == expectedType, CHIP_ERROR_WRONG_CERT_TYPE);
1103
+ return CHIP_NO_ERROR;
1104
+ }
1105
+
1098
1106
CHIP_ERROR ValidateChipRCAC (const ByteSpan & rcac)
1099
1107
{
1100
1108
ChipCertificateSet certSet;
1101
1109
ChipCertificateData certData;
1102
1110
ValidationContext validContext;
1103
- CertType certType;
1104
1111
1105
1112
// Note that this function doesn't check RCAC NotBefore / NotAfter time validity.
1106
1113
// It is assumed that RCAC should be valid at the time of installation by definition.
@@ -1109,8 +1116,7 @@ CHIP_ERROR ValidateChipRCAC(const ByteSpan & rcac)
1109
1116
1110
1117
ReturnErrorOnFailure (certSet.LoadCert (rcac, CertDecodeFlags::kGenerateTBSHash ));
1111
1118
1112
- ReturnErrorOnFailure (certData.mSubjectDN .GetCertType (certType));
1113
- VerifyOrReturnError (certType == CertType::kRoot , CHIP_ERROR_WRONG_CERT_TYPE);
1119
+ ReturnErrorOnFailure (ValidateCertificateType (certData, CertType::kRoot ));
1114
1120
1115
1121
VerifyOrReturnError (certData.mSubjectDN .IsEqual (certData.mIssuerDN ), CHIP_ERROR_WRONG_CERT_TYPE);
1116
1122
@@ -1427,16 +1433,27 @@ CHIP_ERROR CertificateValidityPolicy::ApplyDefaultPolicy(const ChipCertificateDa
1427
1433
}
1428
1434
}
1429
1435
1430
- CHIP_ERROR ValidateChipNetworkIdentity ( const ByteSpan & cert )
1436
+ void InitNetworkIdentitySubject (ChipDN & name )
1431
1437
{
1432
- ChipCertificateData certData;
1433
- ReturnErrorOnFailure (DecodeChipCert (cert, certData, CertDecodeFlags::kGenerateTBSHash ));
1438
+ name.Clear ();
1439
+ CHIP_ERROR err = name.AddAttribute_CommonName (kNetworkIdentityCN , /* not printable */ false );
1440
+ VerifyOrDie (err == CHIP_NO_ERROR); // AddAttribute can't fail in this case
1441
+ }
1434
1442
1435
- CertType certType;
1436
- ReturnErrorOnFailure (certData.mSubjectDN .GetCertType (certType));
1437
- VerifyOrReturnError (certType == CertType::kNetworkIdentity , CHIP_ERROR_WRONG_CERT_TYPE);
1443
+ static CHIP_ERROR CalculateKeyIdentifierSha256 (const P256PublicKeySpan & publicKey, MutableCertificateKeyId outKeyId)
1444
+ {
1445
+ uint8_t hash[kSHA256_Hash_Length ];
1446
+ static_assert (outKeyId.size () <= sizeof (hash)); // truncating 32 bytes down to 20
1447
+ ReturnErrorOnFailure (Hash_SHA256 (publicKey.data (), publicKey.size (), hash));
1448
+ memcpy (outKeyId.data (), hash, outKeyId.size ());
1449
+ return CHIP_NO_ERROR;
1450
+ }
1451
+
1452
+ static CHIP_ERROR ValidateChipNetworkIdentity (const ChipCertificateData & certData)
1453
+ {
1454
+ ReturnErrorOnFailure (ValidateCertificateType (certData, CertType::kNetworkIdentity ));
1438
1455
1439
- VerifyOrReturnError (certData.mSerialNumber .data_equal (kNetworkIdentitySerialNumber ), CHIP_ERROR_WRONG_CERT_TYPE);
1456
+ VerifyOrReturnError (certData.mSerialNumber .data_equal (kNetworkIdentitySerialNumberBytes ), CHIP_ERROR_WRONG_CERT_TYPE);
1440
1457
VerifyOrReturnError (certData.mNotBeforeTime == kNetworkIdentityNotBeforeTime , CHIP_ERROR_WRONG_CERT_TYPE);
1441
1458
VerifyOrReturnError (certData.mNotAfterTime == kNetworkIdentityNotAfterTime , CHIP_ERROR_WRONG_CERT_TYPE);
1442
1459
VerifyOrReturnError (certData.mIssuerDN .IsEqual (certData.mSubjectDN ), CHIP_ERROR_WRONG_CERT_TYPE);
@@ -1455,5 +1472,77 @@ CHIP_ERROR ValidateChipNetworkIdentity(const ByteSpan & cert)
1455
1472
return CHIP_NO_ERROR;
1456
1473
}
1457
1474
1475
+ CHIP_ERROR ValidateChipNetworkIdentity (const ByteSpan & cert)
1476
+ {
1477
+ ChipCertificateData certData;
1478
+ ReturnErrorOnFailure (DecodeChipCert (cert, certData, CertDecodeFlags::kGenerateTBSHash ));
1479
+ ReturnErrorOnFailure (ValidateChipNetworkIdentity (certData));
1480
+ return CHIP_NO_ERROR;
1481
+ }
1482
+
1483
+ CHIP_ERROR ValidateChipNetworkIdentity (const ByteSpan & cert, MutableCertificateKeyId outKeyId)
1484
+ {
1485
+ ChipCertificateData certData;
1486
+ ReturnErrorOnFailure (DecodeChipCert (cert, certData, CertDecodeFlags::kGenerateTBSHash ));
1487
+ ReturnErrorOnFailure (ValidateChipNetworkIdentity (certData));
1488
+ ReturnErrorOnFailure (CalculateKeyIdentifierSha256 (certData.mPublicKey , outKeyId));
1489
+ return CHIP_NO_ERROR;
1490
+ }
1491
+
1492
+ CHIP_ERROR ExtractIdentifierFromChipNetworkIdentity (const ByteSpan & cert, MutableCertificateKeyId outKeyId)
1493
+ {
1494
+ ChipCertificateData certData;
1495
+ ReturnErrorOnFailure (DecodeChipCert (cert, certData));
1496
+ ReturnErrorOnFailure (ValidateCertificateType (certData, CertType::kNetworkIdentity ));
1497
+ ReturnErrorOnFailure (CalculateKeyIdentifierSha256 (certData.mPublicKey , outKeyId));
1498
+ return CHIP_NO_ERROR;
1499
+ }
1500
+
1501
+ static CHIP_ERROR GenerateNetworkIdentitySignature (const P256Keypair & keypair, P256ECDSASignature & signature)
1502
+ {
1503
+ // Create a buffer and writer to capture the TBS (to-be-signed) portion of the certificate.
1504
+ chip::Platform::ScopedMemoryBuffer<uint8_t > asn1TBSBuf;
1505
+ VerifyOrReturnError (asn1TBSBuf.Alloc (kNetworkIdentityTBSLength ), CHIP_ERROR_NO_MEMORY);
1506
+
1507
+ ASN1Writer writer;
1508
+ writer.Init (asn1TBSBuf.Get (), kNetworkIdentityTBSLength );
1509
+
1510
+ // Generate the TBSCertificate and sign it
1511
+ ReturnErrorOnFailure (EncodeNetworkIdentityTBSCert (keypair.Pubkey (), writer));
1512
+ ReturnErrorOnFailure (keypair.ECDSA_sign_msg (asn1TBSBuf.Get (), writer.GetLengthWritten (), signature));
1513
+
1514
+ return CHIP_NO_ERROR;
1515
+ }
1516
+
1517
+ static CHIP_ERROR EncodeCompactIdentityCert (TLVWriter & writer, Tag tag, const P256PublicKeySpan & publicKey,
1518
+ const P256ECDSASignatureSpan & signature)
1519
+ {
1520
+ TLVType containerType;
1521
+ ReturnErrorOnFailure (writer.StartContainer (tag, kTLVType_Structure , containerType));
1522
+ ReturnErrorOnFailure (writer.Put (ContextTag (kTag_EllipticCurvePublicKey ), publicKey));
1523
+ ReturnErrorOnFailure (writer.Put (ContextTag (kTag_ECDSASignature ), signature));
1524
+ ReturnErrorOnFailure (writer.EndContainer (containerType));
1525
+ return CHIP_NO_ERROR;
1526
+ }
1527
+
1528
+ CHIP_ERROR NewChipNetworkIdentity (const Crypto::P256Keypair & keypair, MutableByteSpan & outCompactCert)
1529
+ {
1530
+ VerifyOrReturnError (!outCompactCert.empty (), CHIP_ERROR_INVALID_ARGUMENT);
1531
+ VerifyOrReturnError (CanCastTo<uint32_t >(outCompactCert.size ()), CHIP_ERROR_INVALID_ARGUMENT);
1532
+
1533
+ Crypto::P256ECDSASignature signature;
1534
+ ReturnErrorOnFailure (GenerateNetworkIdentitySignature (keypair, signature));
1535
+
1536
+ TLVWriter writer;
1537
+ writer.Init (outCompactCert);
1538
+
1539
+ P256PublicKeySpan publicKeySpan (keypair.Pubkey ().ConstBytes ());
1540
+ P256ECDSASignatureSpan signatureSpan (signature.ConstBytes ());
1541
+ ReturnErrorOnFailure (EncodeCompactIdentityCert (writer, AnonymousTag (), publicKeySpan, signatureSpan));
1542
+
1543
+ outCompactCert.reduce_size (writer.GetLengthWritten ());
1544
+ return CHIP_NO_ERROR;
1545
+ }
1546
+
1458
1547
} // namespace Credentials
1459
1548
} // namespace chip
0 commit comments