@@ -32,49 +32,13 @@ namespace Credentials {
32
32
33
33
namespace {
34
34
35
- static constexpr uint32_t kMaxIssuerBase64Len = BASE64_ENCODED_LEN(kMaxCertificateDistinguishedNameLength );
36
-
37
- CHIP_ERROR BytesToHexStr (const ByteSpan & bytes, MutableCharSpan & outHexStr)
35
+ CHIP_ERROR BytesToHexStr (const ByteSpan & bytes, std::string & outHexStr)
38
36
{
39
- Encoding::HexFlags flags = Encoding::HexFlags::kUppercase ;
40
- ReturnErrorOnFailure (BytesToHex (bytes.data (), bytes.size (), outHexStr.data (), outHexStr.size (), flags));
41
- outHexStr.reduce_size (2 * bytes.size ());
42
- return CHIP_NO_ERROR;
43
- }
44
-
45
- CHIP_ERROR X509_PemToDer (const std::string & pemCert, MutableByteSpan & derCert)
46
- {
47
- std::string beginMarker = " -----BEGIN CERTIFICATE-----" ;
48
- std::string endMarker = " -----END CERTIFICATE-----" ;
49
-
50
- std::size_t beginPos = pemCert.find (beginMarker);
51
- VerifyOrReturnError (beginPos != std::string::npos, CHIP_ERROR_INVALID_ARGUMENT);
37
+ size_t hexLength = bytes.size () * 2 ;
38
+ outHexStr.resize (hexLength);
52
39
53
- std::size_t endPos = pemCert.find (endMarker);
54
- VerifyOrReturnError (endPos != std::string::npos, CHIP_ERROR_INVALID_ARGUMENT);
55
-
56
- VerifyOrReturnError (beginPos < endPos, CHIP_ERROR_INVALID_ARGUMENT);
57
-
58
- // Extract content between markers
59
- std::string plainB64Str = pemCert.substr (beginPos + beginMarker.length (), endPos - (beginPos + beginMarker.length ()));
60
-
61
- // Remove all newline characters '\n' and '\r'
62
- plainB64Str.erase (std::remove (plainB64Str.begin (), plainB64Str.end (), ' \n ' ), plainB64Str.end ());
63
- plainB64Str.erase (std::remove (plainB64Str.begin (), plainB64Str.end (), ' \r ' ), plainB64Str.end ());
64
-
65
- VerifyOrReturnError (!plainB64Str.empty (), CHIP_ERROR_INVALID_ARGUMENT);
66
-
67
- // Verify we have enough room to store the decoded certificate
68
- size_t maxDecodeLen = BASE64_MAX_DECODED_LEN (plainB64Str.size ());
69
- VerifyOrReturnError (derCert.size () >= maxDecodeLen, CHIP_ERROR_BUFFER_TOO_SMALL);
70
-
71
- // decode b64
72
- uint16_t derLen = Base64Decode (plainB64Str.c_str (), static_cast <uint16_t >(plainB64Str.size ()), derCert.data ());
73
- VerifyOrReturnError (derLen != UINT16_MAX, CHIP_ERROR_INVALID_ARGUMENT);
74
-
75
- derCert.reduce_size (derLen);
76
-
77
- return CHIP_NO_ERROR;
40
+ Encoding::HexFlags flags = Encoding::HexFlags::kUppercase ;
41
+ return BytesToHex (bytes.data (), bytes.size (), &outHexStr[0 ], hexLength, flags);
78
42
}
79
43
80
44
} // anonymous namespace
@@ -92,51 +56,40 @@ void TestDACRevocationDelegateImpl::ClearDeviceAttestationRevocationSetPath()
92
56
mDeviceAttestationRevocationSetPath = mDeviceAttestationRevocationSetPath .substr (0 , 0 );
93
57
}
94
58
95
- // outSubject is subject encoded as base64 string
96
- // outKeyId is SKID encoded as hex string
97
- CHIP_ERROR TestDACRevocationDelegateImpl::GetSubjectAndKeyIdFromPEMCert (const std::string & certPEM, std::string & outSubject,
98
- std::string & outKeyId)
99
- {
100
- // buffers and spans for storing crl signer delegator OR crl signer cert info
101
- char subjectBuf[kMaxIssuerBase64Len ] = { 0 };
102
- char skidBuf[2 * kAuthorityKeyIdentifierLength ] = { 0 };
103
- uint8_t certDerBuf[kMax_x509_Certificate_Length ] = { 0 };
104
-
105
- MutableCharSpan subject (subjectBuf);
106
- MutableCharSpan keyId (skidBuf);
107
- MutableByteSpan certDER (certDerBuf);
108
-
109
- ReturnLogErrorOnFailure (X509_PemToDer (certPEM, certDER));
110
- ReturnErrorOnFailure (GetSubjectNameBase64Str (certDER, subject));
111
- ReturnErrorOnFailure (GetSKIDHexStr (certDER, keyId));
112
-
113
- outSubject = std::string (subject.data (), subject.size ());
114
- outKeyId = std::string (keyId.data (), keyId.size ());
115
-
116
- return CHIP_NO_ERROR;
117
- }
118
-
119
59
// Check if issuer and AKID matches with the crl signer OR crl signer delegator's subject and SKID
120
60
bool TestDACRevocationDelegateImpl::CrossValidateCert (const Json::Value & revokedSet, const std::string & akidHexStr,
121
61
const std::string & issuerNameBase64Str)
122
62
{
123
- std::string certPEM ;
63
+ std::string certBase64 ;
124
64
[[maybe_unused]] std::string certType;
125
65
126
66
if (revokedSet.isMember (" crl_signer_delegator" ))
127
67
{
128
- certPEM = revokedSet[" crl_signer_delegator" ].asString ();
129
- certType = " CRL Signer delegator" ;
68
+ certBase64 = revokedSet[" crl_signer_delegator" ].asString ();
69
+ certType = " CRL Signer delegator" ;
130
70
}
131
71
else
132
72
{
133
- certPEM = revokedSet[" crl_signer_cert" ].asString ();
134
- certType = " CRL Signer" ;
73
+ certBase64 = revokedSet[" crl_signer_cert" ].asString ();
74
+ certType = " CRL Signer" ;
135
75
}
136
76
137
- std::string subject; // crl signer or crl signer delegator subject
138
- std::string keyId; // crl signer or crl signer delegator SKID
139
- VerifyOrReturnValue (CHIP_NO_ERROR == GetSubjectAndKeyIdFromPEMCert (certPEM, subject, keyId), false );
77
+ uint8_t certDerBuf[kMax_x509_Certificate_Length ] = { 0 };
78
+ MutableByteSpan certDER (certDerBuf);
79
+
80
+ // Verify we have enough room to store the decoded certificate
81
+ size_t maxDecodeLen = BASE64_MAX_DECODED_LEN (certBase64.size ());
82
+ VerifyOrReturnValue (certDER.size () >= maxDecodeLen, false );
83
+
84
+ uint16_t derLen = Base64Decode (certBase64.c_str (), static_cast <uint16_t >(certBase64.size ()), certDER.data ());
85
+ VerifyOrReturnValue (derLen != UINT16_MAX, false );
86
+ certDER.reduce_size (derLen);
87
+
88
+ std::string subject;
89
+ std::string keyId;
90
+
91
+ VerifyOrReturnValue (CHIP_NO_ERROR == GetSubjectNameBase64Str (certDER, subject), false );
92
+ VerifyOrReturnValue (CHIP_NO_ERROR == GetSKIDHexStr (certDER, keyId), false );
140
93
141
94
ChipLogDetail (NotSpecified, " %s: Subject: %s" , certType.c_str (), subject.c_str ());
142
95
ChipLogDetail (NotSpecified, " %s: SKID: %s" , certType.c_str (), keyId.c_str ());
@@ -154,13 +107,13 @@ bool TestDACRevocationDelegateImpl::CrossValidateCert(const Json::Value & revoke
154
107
// "serial1 bytes as base64",
155
108
// "serial2 bytes as base64"
156
109
// ]
157
- // "crl_signer_cert": "<PEM incoded CRL signer certificate>",
158
- // "crl_signer_delegator": <PEM incoded CRL signer delegator certificate>,
110
+ // "crl_signer_cert": "<base64 encoded DER certificate>",
111
+ // "crl_signer_delegator": "<base64 encoded DER certificate>" ,
159
112
// }
160
113
// ]
161
114
//
162
- bool TestDACRevocationDelegateImpl::IsEntryInRevocationSet (const CharSpan & akidHexStr, const CharSpan & issuerNameBase64Str,
163
- const CharSpan & serialNumberHexStr)
115
+ bool TestDACRevocationDelegateImpl::IsEntryInRevocationSet (const std::string & akidHexStr, const std::string & issuerNameBase64Str,
116
+ const std::string & serialNumberHexStr)
164
117
{
165
118
std::ifstream file (mDeviceAttestationRevocationSetPath .c_str ());
166
119
if (!file.is_open ())
@@ -185,30 +138,26 @@ bool TestDACRevocationDelegateImpl::IsEntryInRevocationSet(const CharSpan & akid
185
138
return false ;
186
139
}
187
140
188
- std::string issuerName = std::string (issuerNameBase64Str.data (), issuerNameBase64Str.size ());
189
- std::string serialNumber = std::string (serialNumberHexStr.data (), serialNumberHexStr.size ());
190
- std::string akid = std::string (akidHexStr.data (), akidHexStr.size ());
191
-
192
141
// 6.2.4.2. Determining Revocation Status of an Entity
193
142
for (const auto & revokedSet : jsonData)
194
143
{
195
- if (revokedSet[" issuer_name" ].asString () != issuerName )
144
+ if (revokedSet[" issuer_name" ].asString () != issuerNameBase64Str )
196
145
{
197
146
continue ;
198
147
}
199
- if (revokedSet[" issuer_subject_key_id" ].asString () != akid )
148
+ if (revokedSet[" issuer_subject_key_id" ].asString () != akidHexStr )
200
149
{
201
150
continue ;
202
151
}
203
152
204
153
// 4.a cross validate PAI with crl signer OR crl signer delegator
205
154
// 4.b cross validate DAC with crl signer OR crl signer delegator
206
- VerifyOrReturnValue (CrossValidateCert (revokedSet, akid, issuerName ), false );
155
+ VerifyOrReturnValue (CrossValidateCert (revokedSet, akidHexStr, issuerNameBase64Str ), false );
207
156
208
157
// 4.c check if serial number is revoked
209
158
for (const auto & revokedSerialNumber : revokedSet[" revoked_serial_numbers" ])
210
159
{
211
- if (revokedSerialNumber.asString () == serialNumber )
160
+ if (revokedSerialNumber.asString () == serialNumberHexStr )
212
161
{
213
162
return true ;
214
163
}
@@ -217,36 +166,42 @@ bool TestDACRevocationDelegateImpl::IsEntryInRevocationSet(const CharSpan & akid
217
166
return false ;
218
167
}
219
168
220
- CHIP_ERROR TestDACRevocationDelegateImpl::GetKeyIDHexStr (const ByteSpan & certDer, MutableCharSpan & outKeyIDHexStr, bool isAKID)
169
+ CHIP_ERROR TestDACRevocationDelegateImpl::GetKeyIDHexStr (const ByteSpan & certDer, std::string & outKeyIDHexStr,
170
+ KeyIdType keyIdType)
221
171
{
222
172
static_assert (kAuthorityKeyIdentifierLength == kSubjectKeyIdentifierLength , " AKID and SKID length mismatch" );
223
173
224
174
uint8_t keyIdBuf[kAuthorityKeyIdentifierLength ];
225
175
MutableByteSpan keyId (keyIdBuf);
226
176
227
- if (isAKID )
177
+ switch (keyIdType )
228
178
{
179
+ case KeyIdType::kAKID :
229
180
ReturnErrorOnFailure (ExtractAKIDFromX509Cert (certDer, keyId));
230
- }
231
- else
232
- {
181
+ break ;
182
+
183
+ case KeyIdType:: kSKID :
233
184
ReturnErrorOnFailure (ExtractSKIDFromX509Cert (certDer, keyId));
185
+ break ;
186
+
187
+ default :
188
+ return CHIP_ERROR_INVALID_ARGUMENT;
234
189
}
235
190
236
191
return BytesToHexStr (keyId, outKeyIDHexStr);
237
192
}
238
193
239
- CHIP_ERROR TestDACRevocationDelegateImpl::GetAKIDHexStr (const ByteSpan & certDer, MutableCharSpan & outAKIDHexStr)
194
+ CHIP_ERROR TestDACRevocationDelegateImpl::GetAKIDHexStr (const ByteSpan & certDer, std::string & outAKIDHexStr)
240
195
{
241
- return GetKeyIDHexStr (certDer, outAKIDHexStr, true );
196
+ return GetKeyIDHexStr (certDer, outAKIDHexStr, KeyIdType:: kAKID );
242
197
}
243
198
244
- CHIP_ERROR TestDACRevocationDelegateImpl::GetSKIDHexStr (const ByteSpan & certDer, MutableCharSpan & outSKIDHexStr)
199
+ CHIP_ERROR TestDACRevocationDelegateImpl::GetSKIDHexStr (const ByteSpan & certDer, std::string & outSKIDHexStr)
245
200
{
246
- return GetKeyIDHexStr (certDer, outSKIDHexStr, false /* isAKID */ );
201
+ return GetKeyIDHexStr (certDer, outSKIDHexStr, KeyIdType:: kSKID );
247
202
}
248
203
249
- CHIP_ERROR TestDACRevocationDelegateImpl::GetSerialNumberHexStr (const ByteSpan & certDer, MutableCharSpan & outSerialNumberHexStr)
204
+ CHIP_ERROR TestDACRevocationDelegateImpl::GetSerialNumberHexStr (const ByteSpan & certDer, std::string & outSerialNumberHexStr)
250
205
{
251
206
uint8_t serialNumberBuf[kMaxCertificateSerialNumberLength ] = { 0 };
252
207
MutableByteSpan serialNumber (serialNumberBuf);
@@ -255,50 +210,55 @@ CHIP_ERROR TestDACRevocationDelegateImpl::GetSerialNumberHexStr(const ByteSpan &
255
210
return BytesToHexStr (serialNumber, outSerialNumberHexStr);
256
211
}
257
212
258
- CHIP_ERROR TestDACRevocationDelegateImpl::GetRDNBase64Str (const ByteSpan & certDer, MutableCharSpan & outRDNBase64String,
259
- bool isIssuer )
213
+ CHIP_ERROR TestDACRevocationDelegateImpl::GetRDNBase64Str (const ByteSpan & certDer, std::string & outRDNBase64String,
214
+ RDNType rdnType )
260
215
{
261
216
uint8_t rdnBuf[kMaxCertificateDistinguishedNameLength ] = { 0 };
262
217
MutableByteSpan rdn (rdnBuf);
263
218
264
- if (isIssuer )
219
+ switch (rdnType )
265
220
{
221
+ case RDNType::kIssuer :
266
222
ReturnErrorOnFailure (ExtractIssuerFromX509Cert (certDer, rdn));
267
- }
268
- else
269
- {
223
+ break ;
224
+
225
+ case RDNType:: kSubject :
270
226
ReturnErrorOnFailure (ExtractSubjectFromX509Cert (certDer, rdn));
227
+ break ;
228
+
229
+ default :
230
+ return CHIP_ERROR_INVALID_ARGUMENT;
271
231
}
272
232
273
- VerifyOrReturnError (outRDNBase64String.size () >= BASE64_ENCODED_LEN (rdn.size ()), CHIP_ERROR_BUFFER_TOO_SMALL);
233
+ // calculate the b64 length needed
234
+ size_t b64LenNeeded = BASE64_ENCODED_LEN (rdn.size ());
235
+
236
+ // Ensure string has enough capacity for base64 encoded data
237
+ outRDNBase64String.resize (b64LenNeeded);
238
+
239
+ uint16_t encodedLen = Base64Encode (rdn.data (), static_cast <uint16_t >(rdn.size ()), &outRDNBase64String[0 ]);
240
+ outRDNBase64String.resize (encodedLen);
274
241
275
- uint16_t encodedLen = Base64Encode (rdn.data (), static_cast <uint16_t >(rdn.size ()), outRDNBase64String.data ());
276
- outRDNBase64String.reduce_size (encodedLen);
277
242
return CHIP_NO_ERROR;
278
243
}
279
244
280
- CHIP_ERROR TestDACRevocationDelegateImpl::GetIssuerNameBase64Str (const ByteSpan & certDer,
281
- MutableCharSpan & outIssuerNameBase64String)
245
+ CHIP_ERROR TestDACRevocationDelegateImpl::GetIssuerNameBase64Str (const ByteSpan & certDer, std::string & outIssuerNameBase64String)
282
246
{
283
- return GetRDNBase64Str (certDer, outIssuerNameBase64String, true /* isIssuer */ );
247
+ return GetRDNBase64Str (certDer, outIssuerNameBase64String, RDNType:: kIssuer );
284
248
}
285
249
286
250
CHIP_ERROR TestDACRevocationDelegateImpl::GetSubjectNameBase64Str (const ByteSpan & certDer,
287
- MutableCharSpan & outSubjectNameBase64String)
251
+ std::string & outSubjectNameBase64String)
288
252
{
289
- return GetRDNBase64Str (certDer, outSubjectNameBase64String, false /* isIssuer */ );
253
+ return GetRDNBase64Str (certDer, outSubjectNameBase64String, RDNType:: kSubject );
290
254
}
291
255
292
256
// @param certDer Certificate, in DER format, to check for revocation
293
257
bool TestDACRevocationDelegateImpl::IsCertificateRevoked (const ByteSpan & certDer)
294
258
{
295
- char issuerNameBuffer[kMaxIssuerBase64Len ] = { 0 };
296
- char serialNumberHexStrBuffer[2 * kMaxCertificateSerialNumberLength ] = { 0 };
297
- char akidHexStrBuffer[2 * kAuthorityKeyIdentifierLength ] = { 0 };
298
-
299
- MutableCharSpan issuerName (issuerNameBuffer);
300
- MutableCharSpan serialNumber (serialNumberHexStrBuffer);
301
- MutableCharSpan akid (akidHexStrBuffer);
259
+ std::string serialNumber;
260
+ std::string akid;
261
+ std::string issuerName;
302
262
303
263
VerifyOrReturnValue (CHIP_NO_ERROR == GetIssuerNameBase64Str (certDer, issuerName), false );
304
264
ChipLogDetail (NotSpecified, " Issuer: %.*s" , static_cast <int >(issuerName.size ()), issuerName.data ());
0 commit comments