@@ -244,16 +244,16 @@ public static function getxRequestId()
244244 }
245245
246246 /**
247- * Calculate and return the SHA1 fingerprint of the certificate used for mTLS.
247+ * Get the decimal serial number of the certificate used for mTLS.
248248 *
249- * This fingerprint is used as the client identifier for rate limiting,
249+ * This serial number is used as the client identifier for rate limiting,
250250 * as rate limits in the API are tied to the certificate, not to X-IBM-Client-Id.
251251 *
252252 * @throws \Exception if unable to read or parse the certificate
253253 *
254- * @return string SHA1 fingerprint of the certificate in lowercase hex format
254+ * @return string Decimal serial number of the certificate
255255 */
256- public function getCertificateFingerprint (): string
256+ public function getCertificateSerialNumber (): string
257257 {
258258 if ($ this ->certFingerprint !== null ) {
259259 return $ this ->certFingerprint ;
@@ -285,13 +285,14 @@ public function getCertificateFingerprint(): string
285285 throw new \Exception ('Unable to read X509 certificate: ' .openssl_error_string ());
286286 }
287287
288- $ fingerprint = openssl_x509_fingerprint ($ certResource, ' sha1 ' );
288+ $ certData = openssl_x509_parse ($ certResource );
289289
290- if ($ fingerprint === false ) {
291- throw new \Exception ('Unable to calculate certificate fingerprint : ' .openssl_error_string ());
290+ if ($ certData === false || ! isset ( $ certData [ ' serialNumber ' ]) ) {
291+ throw new \Exception ('Unable to parse certificate data : ' .openssl_error_string ());
292292 }
293293
294- $ this ->certFingerprint = strtolower ($ fingerprint );
294+ // serialNumber from openssl_x509_parse is already in decimal format
295+ $ this ->certFingerprint = $ certData ['serialNumber ' ];
295296
296297 return $ this ->certFingerprint ;
297298 }
@@ -300,7 +301,7 @@ public function getCertificateFingerprint(): string
300301 * Send an HTTP request while enforcing and updating client rate limits.
301302 *
302303 * Rate limits are enforced per certificate (not per X-IBM-Client-Id).
303- * The certificate fingerprint is used as the client identifier.
304+ * The certificate serial number is used as the client identifier.
304305 *
305306 * @param \Psr\Http\Message\RequestInterface $request the HTTP request to send
306307 * @param array $options Request options to apply to the transfer. See \GuzzleHttp\RequestOptions.
@@ -312,7 +313,7 @@ public function getCertificateFingerprint(): string
312313 */
313314 public function send (\Psr \Http \Message \RequestInterface $ request , array $ options = []): \Psr \Http \Message \ResponseInterface
314315 {
315- $ certFingerprint = $ this ->getCertificateFingerprint ();
316+ $ certFingerprint = $ this ->getCertificateSerialNumber ();
316317
317318 $ this ->rateLimiter ->checkBeforeRequest ($ certFingerprint );
318319
@@ -341,7 +342,7 @@ public function send(\Psr\Http\Message\RequestInterface $request, array $options
341342 /**
342343 * Update rate limits from API response headers.
343344 *
344- * Uses the certificate fingerprint as the client identifier for storing rate limits.
345+ * Uses the certificate serial number as the client identifier for storing rate limits.
345346 *
346347 * @param \Psr\Http\Message\ResponseInterface $response the HTTP response containing rate limit headers
347348 */
@@ -351,7 +352,7 @@ private function updateRateLimitsFromResponse(\Psr\Http\Message\ResponseInterfac
351352 $ remainingSecond = (int ) $ response ->getHeaderLine ('x-ratelimit-remaining-second ' );
352353 $ remainingDay = (int ) $ response ->getHeaderLine ('x-ratelimit-remaining-day ' );
353354 $ timestamp = time ();
354- $ certFingerprint = $ this ->getCertificateFingerprint ();
355+ $ certFingerprint = $ this ->getCertificateSerialNumber ();
355356 $ this ->rateLimiter ->handleRateLimits ($ certFingerprint , $ remainingSecond , $ remainingDay , $ timestamp );
356357 }
357358 }
0 commit comments