Project: certificate-usage · Branch: FHIR-1996_track-ecc-rsa-certificate-usage · Mode: ` · **Model:**claude-haiku-4-5-20251001`
Stats: 1 user messages, 22 tool calls, tools used: Glob, Bash, Read, Grep.
Conversation
Turn 1 — User
I need to understand the current certificate tracking implementation to plan a simplification where we log the raw JWA string instead of mapping it.
Please explore and document:
-
JWSUtils.deriveJWAFromCertificate in src/modules/gematik-crypto: - What does this function return? (e.g., "BP256R1", "RS256", "ES256") - Where is it implemented?
-
CertificateAnalyzer usage: - Where is CertificateAnalyzer.analyzeCertificate currently called? - What does the caller expect to receive? - Check both production code and tests
-
JWAMapper dependencies: - Is JWAMapper imported or used anywhere else besides adapter.ts? - Are there any other references to the CertificateInfo type?
-
Datadog tracking data format: - In src/modules/kbv-ti-connect/main/ti-connect.ts, how is the certificate data sent to Datadog? - What fields are currently logged? (certificateType, curveName, etc.)
Focus on understanding the current flow and what needs to change. Be thorough - check imports, exports, and test files.
Turn 1 — Assistant
I'll explore the codebase to understand the certificate tracking implementation. Let me start with a comprehensive search.
Tools used:
Glob:src/modules/gematik-crypto/**/*.ts
Tools used:
Glob:src/modules/kbv-ti-connect/**/*.ts
Tools used:
Bash:find /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage -type f -name "*.ts" | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/tools/cli-modules/vitest.config.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/tools/cli-modules/src/types.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/tools/cli-modules/src/tests/setup.test.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/tools/cli-modules/src/ddv-modules.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-cert …(truncated, 1758 more chars)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/constants/events.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/constants/module.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/index.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/main/tests/cryptoEngine.test.ts /Users/USER/wor …(truncated, 10443 more chars)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/constants/events.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/constants/module.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/constants/types.ts /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/helpers/tests/cardBinaryParser.test.t …(truncated, 13539 more chars)
Now let me search for the specific files and functions mentioned:
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/node/jose/JWSUtils.ts
Tool results:
→ result (ok): 1→import { Certificate } from 'pkijs' 2→import * as Asn1 from 'asn1js' 3→ 4→enum JWAlgorithms { 5→ HMAC = 'HS', // There is no MAC expected, so keeping here for the compatibility 6→ 'RSASSA-PKCS1-v1_5' = 'RS', 7→ ECDSA = 'ES', 8→ 'RSASSA-PSS' = 'PS', 9→} 10→ 11→type JWSAlgorithms = 'HMAC' | 'RSASSA-PKCS1-v1_5' | 'ECDSA' | 'RSASSA-PSS' 12→export class JWSUtils { 13→ static concatenateECDSASignature(signature: string, outputLength: numbe …(truncated, 5381 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/utils/jwaMapper.ts
Tool results:
→ result (ok): 1→/ 2→ * Maps JWA (JSON Web Algorithm) strings to certificate tracking format 3→ * Used to convert JWSUtils output to Datadog tracking events 4→ */ 5→/ 6→ * Certificate information extracted from JWA algorithm 7→ * @property certificateType - The type of certificate: ECC (Elliptic Curve Cryptography) or RSA 8→ * @property curveName - The elliptic curve name (e.g., 'brainpoolP256r1', 'P-256'). 9→ * Only present for ECC certificates …(truncated, 2162 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/ti-connect.ts
Tool results:
→ result (ok): 1→import { ipcManager } from '@core/ipc-manager' 2→import { sendPreferences } from '@core/app/main/helpers/preferences-helper' 3→import { TrackingEvent } from '@core/monitoring' 4→ 5→import { CertificateAnalyzer } from '@module/gematik-crypto' 6→import { TiEnvRepository } from '@module/gematik-ti-environment/services/tiEnvRepository' 7→import { kbvTiConnectLogger } from '@module/kbv-ti-connect/services/logger' 8→import tiConnect from '@module/kbv-ti-connect/ser …(truncated, 9718 more chars)
Now let me search for CertificateAnalyzer and where it's used:
Tools used:
Grep:class CertificateAnalyzerin/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto
Tools used:
Grep:CertificateAnalyzerin/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto
Tool results:
→ result (ok): Found 1 file src/modules/gematik-crypto/services/crypto-adapter/adapter.ts
Tool results:
→ result (ok): Found 1 file src/modules/gematik-crypto/services/crypto-adapter/adapter.ts
Tools used:
Grep:JWAMapperin/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules
Tool results:
→ result (ok): Found 4 files src/modules/gematik-crypto/services/utils/tests/jwaMapper.test.ts src/modules/gematik-crypto/services/utils/jwaMapper.ts src/modules/gematik-crypto/services/crypto-adapter/adapter.ts src/modules/gematik-crypto/index.ts
Let me read the adapter file to see the CertificateAnalyzer implementation:
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/crypto-adapter/adapter.ts
Tool results:
→ result (ok): 1→import { X509Certificate } from 'node:crypto' 2→import { JWE, JWS as NodeJWS } from '@doctolib/node-jose' 3→import { IOptions } from 'soap' 4→ 5→import { CryptoEngine } from '@module/gematik-crypto/services/crypto-adapter/crypto-engine' 6→import { CustomSoapClientOptions } from '@module/gematik-crypto/services/node/tls/customSoapClientOptions' 7→import { HttpsFetch as DoctoCryptHttpsFetch } from '@module/gematik-crypto/services/docto-crypt/tls/httpsFetch' 8→i …(truncated, 7958 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/index.ts
Tool results:
→ result (ok): 1→export { DoctoCryptExecutor } from './services/docto-crypt' 2→ 3→export * from './services/crypto-adapter' 4→export { Pkcs12Adapter as Pkcs12 } from '@module/gematik-crypto/services/crypto-adapter/pkcs12Adapter' 5→export { KeystoreFile, type DialogOptionProperties } from '@module/gematik-crypto/services/node/keystore/keystoreFile' 6→export { 7→ LdapAdapter as LdapClient, 8→ type SearchOptions, 9→} from '@module/gematik-crypto/services/crypto-adapter/ld …(truncated, 528 more chars)
Now let me check the tests to understand usage better:
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/utils/__tests__/jwaMapper.test.ts
Tool results:
→ result (ok): 1→import { describe, expect, it } from 'vitest' 2→ 3→import { JWAMapper } from '../jwaMapper' 4→ 5→describe('JWAMapper', () => { 6→ describe('.mapJWAToCertificateInfo', () => { 7→ it('identifies RSA algorithms (RS family)', () => { 8→ expect(JWAMapper.mapJWAToCertificateInfo('RS256')).toEqual({ 9→ certificateType: 'RSA', 10→ }) 11→ expect(JWAMapper.mapJWAToCertificateInfo('RS384')).toEqual({ 12→ certificateType: …(truncated, 2173 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/node/jose/__tests_electron__/JWSUtils.test.ts
Tool results:
→ result (ok): 1→import { JWSUtils } from '@module/gematik-crypto/services/node/jose/JWSUtils' 2→ 3→describe('JWSUtils', () => { 4→ afterEach(() => { 5→ vi.clearAllMocks() 6→ }) 7→ 8→ const rsaCertificate = 9→ 'MIIEljCCA36gAwIBAgIHAWMLSsvZvzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UE' + 10→ 'BhMCREUxHzAdBgNVBAoMFmdlbWF0aWsgR21iSCBOT1QtVkFMSUQxMjAwBgNVBAsM' + 11→ 'KUtvbXBvbmVudGVuLUNBIGRlciBUZWxlbWF0aWtpbmZyYXN0cnVrdHVyMSAwHgYD' + 12→ 'VQQDDBdHRU0uS09 …(truncated, 13415 more chars)
Now let me check where JWAMapper is imported and used:
Tools used:
Bash:grep -r "JWAMapper\|CertificateInfo" /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src --include="*.ts" | grep -v test | grep -v ".test.ts"
Tools used:
Bash:grep -r "CertificateAnalyzer" /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src --include="*.ts" | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/core/network/main/debug-menu/helpers/electron-helpers.ts:import { CertificateInfo } from '../../../services/network-environment-diagnostic' /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/core/network/main/debug-menu/helpers/electron-helpers.ts: getPeerCertificate?: () => CertificateInfo | undefined /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/core/network/ma …(truncated, 1863 more chars)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/tests/ti-connect.test.ts:import { CertificateAnalyzer } from '@module/gematik-crypto' /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/tests/ti-connect.test.ts: CertificateAnalyzer: { /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/tests/ti-connect.test.ts: mockAnal …(truncated, 614 more chars)
Let me check the test file to see how CertificateAnalyzer is used:
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/__tests__/ti-connect.test.ts(1–150)
Tool results:
→ result (ok): 1→import { Mock } from 'vitest' 2→ 3→import { ipcManager } from '@core/ipc-manager' 4→import { sendPreferences } from '@core/app/main/helpers/preferences-helper' 5→import { sendCustomTrackingEventToObservability, TrackingEvent } from '@core/monitoring' 6→ 7→import { CertificateAnalyzer } from '@module/gematik-crypto' 8→import { TiEnvRepository } from '@module/gematik-ti-environment/services/tiEnvRepository' 9→import { TiEnvValueSet } from '@module/gematik- …(truncated, 5664 more chars)
Let me continue reading the test file:
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/__tests__/ti-connect.test.ts(150–400)
Tool results:
→ result (ok): 150→ mockSendPreferences = vi.mocked(sendPreferences) 151→ mockTiConnectCallApi = vi.mocked(tiConnect.callApi) 152→ mockDecryptKeyStore = vi.mocked(decryptKeyStore) 153→ mockGetNewKeyStore = vi.mocked(getNewKeyStore) 154→ mockReadKeyStoreFromFile = vi.mocked(readKeyStoreFromFile) 155→ mockExtraLogParser = vi.mocked(extraLogParser) 156→ mockGetNestedKeys = vi.mocked(getNestedKeys) 157→ mockSendCustomTrackingEventToObservability = vi.mocked(sendCustomTr …(truncated, 11217 more chars)
Let me continue and look for the test that uses CertificateAnalyzer:
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/__tests__/ti-connect.test.ts(400–600)
Tool results:
→ result (ok): 400→ 401→ expect(TiConnectRepository.settings?.useConnectorContextFromElectronSettings).toBe(true) 402→ expect(mockSendPreferences).toHaveBeenCalled() 403→ 404→ expect(kbvTiConnectLogger.info).toHaveBeenCalledWith('TiConnectModule', { 405→ extra: 'mocked-log-string', 406→ }) 407→ expect(mockExtraLogParser).toHaveBeenCalledWith({ 408→ traceId: 'unknown', 409→ functionName: 'onTiConnectChangeModeListener', 410→ oper …(truncated, 9095 more chars)
Let me search for any other references to understand the data flow better:
Tools used:
Bash:grep -r "deriveJWAFromCertificate\|getJWA" /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src --include="*.ts" | grep -v test
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-idp-authentication/services/IdpChallenge.ts: const alg = await JWSUtils.getJWA( /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/crypto-adapter/adapter.ts: const jwa = await JWSUtils.deriveJWAFromCertificate(certificate) /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/node/jose/J …(truncated, 622 more chars)
Tools used:
Bash:grep -r "mapJWAToCertificateInfo" /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src --include="*.ts" | grep -v test
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/utils/jwaMapper.ts: static mapJWAToCertificateInfo(jwa: string): CertificateInfo { /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/crypto-adapter/adapter.ts: return JWAMapper.mapJWAToCertificateInfo(jwa)
Let me check the IdpChallenge to see how getJWA is used:
Tools used:
Read:/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-idp-authentication/services/IdpChallenge.ts(1–100)
Tool results:
→ result (ok): 1→import { createHash, randomBytes } from 'node:crypto' 2→ 3→import ConfigurationService from '@module/kbv-ti-connect/services/configuration-service' 4→import { SIG_TYPE_ECC } from '@module/kbv-ti-connect/services/types' 5→import { signWithCardCertificate, readCardCertificate } from '@module/gematik-idp-authentication/services/connector' 6→import type { 7→ ChallengeJwt, 8→ CodeVerifierAndChallenge, 9→ SignatureVerificationAndEncryptionKey, 10→} from …(truncated, 4456 more chars)
Perfect! Now let me create a comprehensive document summarizing the findings. Let me also check the recent commits to see what was changed:
Tools used:
Bash:git log --oneline -15
Tool results:
→ result (ok): 5e9eb7ad9 refactor(FHIR-1996): Fix PR review issues for safe error handling and RSA certificate mapping 8c23f5c41 Merge branch 'master' of https://github.com/doctolib/doctolib-pro-desktop into FHIR-1996_track-ecc-rsa-certificate-usage bb10862aa refactor(FHIR-1996): Remove unused TiCertificateConfigured tracking event 78da4fa09 refactor(FHIR-1996): Fix import consistency and enhance test coverage e7aa76c8a feat(DITTO-4078): logging with lazy initialization and error aggregation (#6980) 9e54598a3 …(truncated, 853 more chars)
Perfect! Now I have all the information needed. Let me create a comprehensive exploration report.
Certificate Tracking Implementation - Comprehensive Exploration Report
Based on my thorough exploration of the codebase, here's the complete understanding of the current certificate tracking implementation:
1. JWSUtils.deriveJWAFromCertificate - Location & Output
File: /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/node/jose/JWSUtils.ts
Function Signature:
static async deriveJWAFromCertificate(certificate: string): Promise<string>
What it returns: The function returns a JWA (JSON Web Algorithm) string representing the algorithm used by the certificate:
- RSA algorithms:
'RS256','RS384','RS512','PS256','PS384','PS512' - ECC/ECDSA algorithms:
'ES256','ES384','ES512' - German TI standard (Brainpool):
'BP256R1' - Fallback:
'none'(when parsing fails or no algorithm found)
Implementation Details (lines 83-118):
- Uses pkijs library to parse base64-encoded X.509 certificates
- Analyzes the public key algorithm from the certificate
- For RSA keys: calls selectJWA with algorithm name and hash function (e.g., "SHA-256" → "256")
- For ECC keys: calls selectJWA with algorithm name and named curve
- Has special handling for BrainpoolP256R1 curve (OID 1.3.36.3.3.2.8.1.1.7) due to unsupported algorithm exception
- Pure JavaScript implementation using pkijs (independent of crypto engine choice)
2. CertificateAnalyzer Usage
File: /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/crypto-adapter/adapter.ts
Implementation (lines 156-171):
export class CertificateAnalyzer {
static async analyzeCertificate(certificate: string): Promise<CertificateInfoType> {
const jwa = await JWSUtils.deriveJWAFromCertificate(certificate)
return JWAMapper.mapJWAToCertificateInfo(jwa)
}
}
Where it's called:
-
Production Code - Main Usage: -
/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/ti-connect.ts(lines 104-137) - Called intrackCertificateType()function after keystore decryption - Fire-and-forget pattern - wrapped in try-catch that logs errors without throwing -
Test Code: -
/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/__tests__/ti-connect.test.ts- Mocked for testing certificate tracking behavior - Tests verify certificate info is sent to Datadog observability
What the caller expects to receive:
interface CertificateInfo {
certificateType: 'ECC' | 'RSA'
curveName?: string // Only present for ECC certificates
}
Example returns:
- ECC: { certificateType: 'ECC', curveName: 'brainpoolP256r1' }
- RSA: { certificateType: 'RSA' } (no curve)
3. JWAMapper Dependencies & Usage
File: /Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/services/utils/jwaMapper.ts
Imports/Exports in the codebase:
- Exported from:
-
/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/gematik-crypto/index.ts(line 10) ```typescript export { JWAMapper, type CertificateInfo as CertificateInfoType } from './services/utils/jwaMapper'
2. **Used in:**
- `adapter.ts` - CertificateAnalyzer uses JWAMapper.mapJWAToCertificateInfo()
- Test file: `jwaMapper.test.ts` - comprehensive unit tests
3. **CertificateInfo type references:**
- `adapter.ts`: imported as `CertificateInfoType`
- `jwaMapper.ts`: defined as `CertificateInfo`
- `index.ts`: re-exported as `CertificateInfoType`
- `ti-connect.ts`: implicitly used (returns from CertificateAnalyzer)
**Key characteristic:** JWAMapper is ONLY used internally within the crypto-adapter module. It's NOT imported or used anywhere else in the codebase besides:
- `adapter.ts` (where CertificateAnalyzer uses it)
- `index.ts` (for re-export)
- Test files
---
### 4. **Datadog Tracking Data Format**
**File:** `/Users/USER/workspace/doctolib/FHIR-1996_track-ecc-rsa-certificate-usage/src/modules/kbv-ti-connect/main/ti-connect.ts`
**Location:** `trackCertificateType()` function (lines 104-137)
**Current data sent to Datadog:**
```typescript
// Success case (lines 114-119)
{
certificateType: certificateInfo.certificateType, // "ECC" or "RSA"
curveName: certificateInfo.curveName, // e.g., "brainpoolP256r1" or undefined
tiEnvironment: tiEnvironment, // e.g., "RU", "PU", "UNKNOWN"
}
// Error case (lines 129-135)
{
tiEnvironment: tiEnvironment,
error: true,
errorMessage: error.message,
errorName: error.name,
}
Observability Context:
- Sent via tiConnectEventObservability.send()
- Event type: TrackingEvent.KbvTiConnect
- Wrapped in extra metadata:
```typescript
{
traceId: string,
functionName: 'onTiConnectDecryptKeyStoreListener',
operation: 'read',
direction: 'output',
data: JSON.stringify({...})
}
**Test Verification (lines 515-585):**
Tests confirm that:
- `CertificateAnalyzer.analyzeCertificate()` is called with the decrypted certificate
- Certificate info (type and curve) is tracked
- Different TI environments are included
- Errors are tracked with error details
- RSA certificates log without curveName
---
### 5. **Call Flow Diagram**
onTiConnectDecryptKeyStoreListener (ti-connect.ts:139) ↓ readKeyStoreFromFile() + decryptKeyStore() ↓ trackCertificateType(cert, traceId) (ti-connect.ts:104) ↓ CertificateAnalyzer.analyzeCertificate(cert) (adapter.ts:167) ↓ JWSUtils.deriveJWAFromCertificate(cert) (JWSUtils.ts:83) ↓ Returns: JWA string ("RS256", "ES256", "BP256R1", "none", etc.) ↓ JWAMapper.mapJWAToCertificateInfo(jwa) (jwaMapper.ts:22) ↓ Returns: { certificateType: 'ECC'|'RSA', curveName?: string } ↓ tiConnectEventObservability.send(data) → Datadog ```
6. Key Dependencies & Imports
CertificateAnalyzer needs: - JWSUtils (JWA derivation) - JWAMapper (JWA → CertificateInfo conversion) - pkijs library (for X.509 cert parsing)
TiConnect tracking needs: - CertificateAnalyzer (from @module/gematik-crypto) - TiEnvRepository (for TI environment info) - TrackingEvent (from @core/monitoring) - tiConnectEventObservability (observability helper)
7. Simplification Implications
Current approach: 1. Derive JWA string from certificate 2. Map JWA to structured CertificateInfo (certificateType + curveName) 3. Send structured data to Datadog
Simplification (log raw JWA string):
- Remove JWAMapper entirely
- CertificateAnalyzer would return the JWA string directly
- Datadog would receive: { jwa: "RS256" } or { jwa: "BP256R1" } instead of { certificateType: "RSA" }
- Impact:
- Removes one layer of mapping/abstraction
- Changes what's logged to Datadog (raw algorithm vs semantic meaning)
- JWA strings are already standardized (RFC 7518)
- Loses the semantic "certificateType" and "curveName" distinction
Summary Table
| Component | Location | Returns | Current Behavior |
|---|---|---|---|
| JWSUtils.deriveJWAFromCertificate | JWSUtils.ts:83 | JWA string ("RS256", "ES256", "BP256R1", "none") | Parses X.509 cert using pkijs |
| JWAMapper.mapJWAToCertificateInfo | jwaMapper.ts:22 | {certificateType: 'ECC'\|'RSA', curveName?: string} |
Maps JWA to semantic info |
| CertificateAnalyzer.analyzeCertificate | adapter.ts:167 | {certificateType, curveName?} |
Combines JWSUtils + JWAMapper |
| trackCertificateType | ti-connect.ts:104 | void (sends to Datadog) | Fire-and-forget with error handling |
This should give you everyth …(truncated, 40 more chars)