Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Stars

10 stars

Watchers

3 watching

Forks

Repository files navigation

🔍 Verify API

Türkiye e-imza standartlarına uygun dijital imza doğrulama (PAdES, XAdES, Timestamp) servisi.

Java Spring Boot License DSS Version PRs Welcome


📚 Tam Dökümantasyon

Tüm detaylı dökümantasyon merkezi dökümantasyon sitesinde bulunur:

  • 📖 Kurulum ve yapılandırma
  • 🚀 Hızlı başlangıç kılavuzu
  • 🔍 İmza doğrulama detayları
  • ⚙️ Docker ve Kubernetes deployment
  • 📊 Monitoring ve performance tuning
  • ⏰ Zaman damgası doğrulama
  • 💡 Kod örnekleri ve kullanım senaryoları
  • 🧪 Test stratejileri
  • 🔒 Güvenlik en iyi pratikleri

Bu API, PAdES (PDF), XAdES (XML) dijital imzaların ve zaman damgalarının doğrulanması için kapsamlı bir servis sağlar. EU DSS (Digital Signature Service) kütüphanesi üzerine inşa edilmiştir.

🌟 Özellikler

📝 Desteklenen İmza Formatları

XAdES (XML Advanced Electronic Signatures)

  • ✅ XAdES-BES - Basic Electronic Signature
  • ✅ XAdES-EPES - Explicit Policy-based Electronic Signature
  • ✅ XAdES-T - Timestamp
  • ✅ XAdES-C - Complete
  • ✅ XAdES-X - eXtended
  • ✅ XAdES-XL - eXtended Long-term
  • ✅ XAdES-A - Archival (uzun vadeli arşivleme)

PAdES (PDF Advanced Electronic Signatures)

  • ✅ PAdES-B-B - Basic
  • ✅ PAdES-B-T - Basic with Timestamp
  • ✅ PAdES-B-LT - Basic Long-Term
  • ✅ PAdES-B-LTA - Basic Long-Term with Archive timestamp

CAdES (CMS Advanced Electronic Signatures)

  • ✅ CAdES-BES - Basic Electronic Signature
  • ✅ CAdES-EPES - Explicit Policy-based Electronic Signature
  • ✅ CAdES-T, C, X, XL, A - Tüm seviyeler desteklenir

🔧 Temel Özellikler

  • ✅ Birleşik Doğrulama Endpoint - Tüm formatları otomatik algılar
  • ✅ Enveloped, Enveloping ve Detached İmza - Tüm imza tipleri
  • ✅ Zaman Damgası Doğrulama - RFC 3161 uyumlu, TSA sertifika kontrolü
  • ✅ Message Imprint Doğrulama - Orijinal veri ile timestamp eşleştirme
  • ✅ Sertifika Zinciri Doğrulama - Güvenilir root'a kadar tam zincir
  • ✅ Strict-Safe Revocation Pipeline - OCSP/CRL üretim sınıfı: Caffeine cache (token nextUpdate-aware TTL + configurable üst sınır), exponential backoff + jitter retry (anlık flake toleransı), INFO seviyesinde audit log, Prometheus metric expose. Strict policy'de tüm retry'lar tükenirse imza güvenle INDETERMINATE/NO_REVOCATION_DATA döner — anlık kesinti yüzünden valid imza reddedilmez, gerçek kesintide de "iptal mi belli değil" asla VALID gösterilmez. Sonuçlar her sertifika için response'a zengin biçimde yansır (signerCertificate.revocation alt nesnesi: source, status, responderUrl, producedAt/thisUpdate/nextUpdate, origin, vb.).
  • ✅ AIA Support - Otomatik sertifika zinciri tamamlama
  • ✅ Güvenilir Kök Sertifika Resolver Desteği - Üç farklı resolver tipi
    • KamuSM XML Depo Online: İnternet üzerinden KamuSM XML deposunu yükler
    • KamuSM XML Depo Offline: Yerel dosyadan KamuSM XML deposunu yükler
    • Certificate Folder: Klasördeki tüm .crt/.cer/.pem dosyalarını yükler
  • ✅ İki Seviyeli Doğrulama
    • Simple: Hızlı, temel imza doğrulaması
    • Comprehensive: Detaylı, tüm bilgileri içeren doğrulama (sertifika zinciri, policy bilgisi, vb.)
  • ✅ Çoklu İmza Desteği - Tek dokümanda birden fazla imza
  • ✅ Docker Desteği - Kolay deployment
  • ✅ Prometheus Metrics - Monitoring ve metrikleme
  • ✅ RESTful API - OpenAPI/Scalar dokümantasyonu
  • ✅ OpenAPI Dokümantasyonu - Swagger UI alternatifi

🚀 Hızlı Başlangıç

Gereksinimler

  • Java 8 veya üzeri
  • Maven 3.6+
  • Docker (opsiyonel)

Local Çalıştırma

  1. Repoyu klonlayın:
git clone https://github.com/mersel-dss/verify-api.git
cd verify-api
  1. Maven ile derleyin:
mvn clean package
  1. Uygulamayı başlatın:
java -jar target/verify-api.jar

Servis http://localhost:8086 adresinde çalışmaya başlayacaktır.

Docker ile Çalıştırma

  1. Docker Compose ile başlatın:
cd devops/docker
cp .env.example .env
docker-compose up -d
  1. Logları kontrol edin:
docker-compose logs -f verify-api
  1. Health check:
curl http://localhost:8086/api/v1/health

📚 API Kullanımı

PAdES (PDF) İmza Doğrulama

Basit Doğrulama

curl -X POST http://localhost:8086/api/v1/verify/pades \
  -F "signedDocument=@signed-document.pdf" \
  -F "level=SIMPLE"

Kapsamlı Doğrulama (Tüm Detaylar)

curl -X POST http://localhost:8086/api/v1/verify/pades \
  -F "signedDocument=@signed-document.pdf" \
  -F "level=COMPREHENSIVE" \
  -F "checkRevocation=true" \
  -F "validateTimestamp=true"

Not:

  • level=SIMPLE: Sadece temel bilgiler (valid/invalid, format, signing time)
  • level=COMPREHENSIVE: Tüm detaylar (sertifika zinciri, timestamp, validation details)
  • Validation parametreleri (checkRevocation, validateTimestamp) her iki seviyede de kullanılabilir

Örnek Response (Simple):

{
  "valid": true,
  "status": "VALID",
  "signatureType": "PADES",
  "verificationTime": "2024-11-08T10:30:00Z",
  "signatures": [
    {
      "signatureId": "id-1234",
      "valid": true,
      "signatureFormat": "PAdES-BASELINE-B",
      "signingTime": "2024-11-07T14:20:00Z",
      "signatureAlgorithm": "RSA_SHA256",
      "digestAlgorithm": "SHA256"
    }
  ]
}

signatureAlgorithm vs digestAlgorithm:

  • signatureAlgorithm → İmzayı üreten kriptografik kompozit (encryption + digest). DSS SignatureAlgorithm enum sabit adı — örn. RSA_SHA256, ECDSA_SHA384, RSA_SSA_PSS_SHA256. Belgeyi imzacının nasıl imzaladığını söyler.
  • digestAlgorithm → ds:SignedInfo özet algoritması — örn. SHA256. Belgenin nasıl özetlendiğini söyler; kriptografik politika denetimi (zayıf algoritma yasağı) için tek başına da yeterli.

Bu iki alan SIMPLE ve COMPREHENSIVE modlarda eşit görünür ve imzanın kendisinin algoritmasıdır — signerCertificate.signatureAlgorithm ise CA'nın leaf sertifikayı hangi algoritmayla imzaladığını gösterir (farklı kavram, karıştırılmamalı).

Örnek Response (Comprehensive):

{
  "valid": true,
  "status": "VALID",
  "signatureType": "PADES",
  "verificationTime": "2024-11-08T10:30:00Z",
  "signatures": [
    {
      "signatureId": "id-1234",
      "valid": true,
      "signatureFormat": "PAdES-BASELINE-LT",
      "signatureLevel": "PAdES-BASELINE-LT",
      "signatureAlgorithm": "RSA_SHA256",
      "digestAlgorithm": "SHA256",
      "signingTime": "2024-11-07T14:20:00Z",
      "claimedSigningTime": "2024-11-07T14:20:00Z",
      "signerCertificateProfile": "NES_E_IMZA",
      "signerCertificate": {
        "subjectDN": "CN=Test User, O=Test Organization",
        "issuerDN": "CN=Test CA, O=KamuSM",
        "serialNumber": "5A2295753A906E",
        "notBefore": "2023-01-01T00:00:00Z",
        "notAfter": "2025-01-01T00:00:00Z",
        "qcStatements": ["0.4.0.1862.1.1", "2.16.792.1.61.0.1.5070.1.1"],
        "trusted": true,
        "expired": false,
        "revoked": false,
        "revocation": {
          "source": "OCSP",
          "status": "GOOD",
          "producedAt": "2024-11-07T14:20:03Z",
          "thisUpdate": "2024-11-07T14:00:00Z",
          "nextUpdate": "2024-11-07T15:00:00Z",
          "responderUrl": "http://ocsp.kamusm.gov.tr",
          "origin": "REVOCATION_VALUES"
        }
      },
      "chainRevocationStatus": "ALL_GOOD",
      "certificateChain": [...],
      "timestampInfo": {
        "valid": true,
        "timestampTime": "2024-11-07T14:20:05Z"
      }
    }
  ],
  "validationDetails": {
    "signatureIntact": true,
    "certificateChainValid": true,
    "certificateNotExpired": true,
    "certificateNotRevoked": true,
    "trustAnchorReached": true,
    "timestampValid": true
  }
}

XAdES (XML) İmza Doğrulama

Basit Doğrulama (Enveloped/Enveloping)

curl -X POST http://localhost:8086/api/v1/verify/xades \
  -F "signedDocument=@signed-document.xml" \
  -F "level=SIMPLE"

Kapsamlı Doğrulama (Tüm Detaylar)

curl -X POST http://localhost:8086/api/v1/verify/xades \
  -F "signedDocument=@signed-document.xml" \
  -F "level=COMPREHENSIVE" \
  -F "checkRevocation=true" \
  -F "validateTimestamp=true"

Detached İmza Doğrulama

curl -X POST http://localhost:8086/api/v1/verify/xades \
  -F "signedDocument=@signature.xml" \
  -F "originalDocument=@original-document.xml" \
  -F "level=COMPREHENSIVE" \
  -F "checkRevocation=true"

Not:

  • DSS otomatik olarak imza tipini (Enveloped, Enveloping, Detached) tespit eder
  • Detached imza için originalDocument parametresi opsiyoneldir - DSS otomatik tespit edebilir ancak belirtilmesi daha güvenilir sonuçlar verir
  • level parametresi sadece response detay seviyesini belirler
  • Validation özellikleri (OCSP/CRL, timestamp) bağımsız olarak kontrol edilir

Zaman Damgası Doğrulama

curl -X POST http://localhost:8086/api/v1/verify/timestamp \
  -F "timestampToken=@timestamp.tst" \
  -F "originalData=@data.pdf" \
  -F "validateCertificate=true"

Örnek Response:

{
  "valid": true,
  "status": "VALID",
  "timestampTime": "2024-11-07T14:20:05Z",
  "tsaName": "CN=KamuSM TSA",
  "digestAlgorithm": "SHA-256",
  "messageImprint": "ZGF0YSBoYXNo...",
  "tsaCertificate": {
    "subjectDN": "CN=KamuSM TSA",
    "notBefore": "2023-01-01T00:00:00Z",
    "notAfter": "2026-01-01T00:00:00Z"
  },
  "verificationTime": "2024-11-08T10:30:00Z"
}

⚙️ Konfigürasyon

Environment Variables

Uygulama aşağıdaki environment variable'lar ile yapılandırılabilir:

Server Configuration

SERVER_PORT=8086                    # Sunucu portu

Logging

LOG_LEVEL=INFO                      # Log seviyesi (DEBUG, INFO, WARN, ERROR)
LOG_PATH=./logs                     # Log dosya dizini

CORS

CORS_ALLOWED_ORIGINS=*              # İzin verilen origin'ler
CORS_ALLOWED_METHODS=GET,POST       # İzin verilen HTTP metodları

Certificate Store (Zorunlu)

CERTSTORE_PATH=/path/to/store.jks   # Sertifika deposu yolu (zorunlu)
CERTSTORE_PASSWORD=secret           # Sertifika deposu şifresi
CUSTOM_ROOT_CERT_PATH=/path/to/root.cer  # Özel root sertifika (opsiyonel)

Validation Configuration

ONLINE_VALIDATION_ENABLED=true      # Online OCSP/CRL kontrolü (master switch).
                                    # false: revocation source bean'leri context'e yaratılmaz,
                                    # tek paket bile dışarı çıkmaz (air-gapped / offline modu).
                                    # OCSP/CRL pipeline parametreleri için aşağıdaki
                                    # "Revocation Pipeline (OCSP/CRL)" bölümüne bakın.
VERIFICATION_STRICT_MODE=true       # Rapor seviyesi katılık: SubIndication varsa imza invalid sayılır
                                    # (Not: Bu DSS policy XML değildir; DSS validation kuralları
                                    #  için aşağıdaki "DSS Validation Policy" bölümüne bakın.)
TR_LEGACY_XADES_TOLERANCE=true      # KamuSM/GİB üreticisinin XAdES SignedProperties Type URI
                                    # yazım hatasına tolerans (TÜBİTAK İmzager paritesi).
                                    # Detaylar için aşağıdaki "TR-Legacy XAdES Toleransı" bölümüne bakın.
CERT_CACHE_TTL=3600                 # Sertifika cache süresi (saniye)
CRL_CACHE_TTL=3600                  # [LEGACY] CRL cache süresi (saniye). Geriye dönük uyumluluk
                                    # için korunuyor; yeni revocation cache sistemi
                                    # REVOCATION_CACHE_TTL'i kullanır — set edilmezse buradaki
                                    # değer fallback olur. Detay: "Revocation Pipeline" bölümü.

DSS Validation Policy

Doğrulamada kullanılacak constraint XML'ini iki kademeli olarak seçer:

# 1) Built-in profil — değerler: signer-strict (DEFAULT) | strict
DSS_POLICY_PROFILE=signer-strict

# 2) Tam custom override — set edilirse DSS_POLICY_PROFILE ignore edilir
#    Spring Resource paterni: classpath: | file: | http(s):
DSS_POLICY_PATH=                    # boş = profil kullan
# Production typical:
# DSS_POLICY_PATH=file:/etc/mersel-dss-verify/policy.xml
Profil İmzacı sertifika OCSP/CRL Ara CA OCSP/CRL TS signer OCSP/CRL TS CA OCSP/CRL Ne zaman?
signer-strict FAIL (zorunlu) WARN WARN WARN Mali Mühür / KamuSM üretim default'u. İptal kontrolü garanti, ara CA endpoint kesintilerinde yine validation devam eder.
strict FAIL FAIL FAIL WARN eIDAS-QES paralel; online OCSP/CRL altyapısı kesintisiz olan ortamlar (sigorta, banka, kamu kurumu).

Profil seçim kılavuzu — özet:

  • signer-strict (default): İmzacının iptali için zero-tolerance, ama ara CA OCSP responder'larının geçici kesintilerinde imzayı feda etmez. Türkiye e-Fatura / e-Defter ekosisteminde KamuSM ara CA'larının operasyonel realitesini gözeten pragmatik denge. Ara CA için iptal verisi bulunamaması imzayı reddettirmez; ancak TR uyum kontrolleri açıkken (TR_COMPLIANCE_CHECKS_ENABLED, varsayılan) kontrol zamanından önce iptal edilmiş ara CA MDSS-TR-CERT-REVOKED ile reddedilir. İmzacı ve karşı imza RevocationFreshness kuralı WARN'dur: uzun dönemli imzadaki iptal verisi imzadan önce yayımlanmış olabilir (MA3 de verinin kontrol zamanını kapsamasına bakar); geçerlilik penceresi MDSS-TR-CRL-EXPIRED / MDSS-TR-OCSP-EXPIRED ile denetlenir. TÜBİTAK uyum değerlendirmesi bu profille, özel XML yüklemeden yapılabilir.
  • strict: eIDAS QES paralelinde tüm zincir için sıkı davranış — ara CA REVOKED ise imza geçersiz. Operasyonel kesinti tolere edilmez; OCSP/CRL altyapısı garanti edilmiş kurumsal ortamlar için. chainRevocationStatus: LEAF_GOOD_CA_REVOKED durumunda valid: false + sub-indication REVOKED_CA_NO_POE döner.
  • Custom XML: Yukarıdaki iki profil ihtiyacı karşılamazsa DSS_POLICY_PATH ile kendi XML'inizi mount edin. Built-in profiller src/main/resources/policy/ altında tam yorumlu, baz alabilirsiniz.

Önemli: DSS_POLICY_PATH ile verilen XML erişilemezse servis sessizce DSS default'una düşmez — VerificationException atar. Built-in profil XML jar'da yoksa da aynı şekilde fail-fast. Bilinmeyen DSS_POLICY_PROFILE değeri verilirse default signer-strict'e düşülür ve startup'ta WARN loglanır.

DSS_POLICY_PROFILE + ONLINE_VALIDATION_ENABLED=false kombinasyonu risk yaratır: imzacı için OCSP/CRL FAIL ama online fetch kapalı → her doğrulama INDETERMINATE/NO_REVOCATION_DATA döner. Servis startup'ta bu kombinasyonu tespit edip uyarır. Test/CI ortamları için DSS_POLICY_PATH ile permissive bir XML mount edin.

Custom policy yazımı: Built-in XML'ler src/main/resources/policy/ altında tam yorumlu. CA / ara / imzacı / counter signature / timestamp katmanları için ayrı ayrı RevocationDataAvailable, NotRevoked, AcceptableRevocationDataFound vb. constraint'leri FAIL/WARN/IGNORE seviyesinde yapılandırabilirsiniz — DSS native policy şeması zaten katman bazlı (bkz. SigningCertificate ve CACertificate node'ları).

Çalışma Anında Politika Etkinleştirme

Warning

Prod ortamında kesinlikle kullanmayın. Bu özellik yalnız TÜBİTAK Uyum Değerlendirme sürecindeki deployment'lar için geliştirilmiştir. Varsayılan olarak kapalıdır ve yalnız POLICY_ACTIVATION_ENABLED=true ENV'i ile açılır (feature flag); evaluation profili veya REQUEST_TRUST_ENABLED açmaz. Açıkken uygulama başlangıçta WARN loglar.

Yukarıdaki yapılandırma başlangıç politikasıdır. Feature flag açıksa etkin politika yeniden başlatmadan GET/POST /api/v1/policy/active ile okunup değiştirilebilir (Compliance UI'daki "Sunucuda etkinleştir"):

# POLICY_ACTIVATION_ENABLED=true    # feature flag, varsayılan false — prod'da AÇMAYIN
                                    # (yalnız TÜBİTAK Uyum Değerlendirme deployment'ları)
POLICY_MAX_BYTES=1048576            # CUSTOM_XML yükleme sınırı (1 MiB)
  • mode=BUILT_IN + profile=signer-strict|strict, mode=CUSTOM_XML + policyXml dosyası (+ opsiyonel policyName), mode=CONFIGURED (yapılandırmaya dönüş). Her istekte expectedPolicyId (GET'ten alınan güncel policyId) zorunludur; eskiyse 409 CONFLICT.
  • Özel XML DOCTYPE/ENTITY içeremez (XXE-güvenli ayrıştırma), iyi biçimlendirilmiş olmalı ve DSS ConstraintsParameters XSD'siyle yüklenebilmelidir; aksi halde 400 INVALID_POLICY. Kapalıysa 403 POLICY_ACTIVATION_DISABLED.
  • Etkinleştirme global (sonraki tüm imza doğrulamaları) ve bellek içidir: yeniden başlatma DSS_POLICY_PROFILE/DSS_POLICY_PATH'e döner. Erişimi deployment seviyesinde kısıtlayın.
  • /api/v1/info → verificationPolicy etkin politikayı gösterir; policyCapabilities: {activationSupported, activationEnabled, maxBytes}. İmza doğrulama yanıtları kullanılan politikayı policyContext (policyId, profile, source, name, sha256) ile bildirir.

Ayrıntılı sözleşme: docs/policy-activation.md.

Revocation Pipeline (OCSP/CRL)

DSS policy revocation kuralını belirler (RevocationDataAvailable=FAIL mı, WARN mı, vb.); bu bölümdeki env'ler revocation altyapısını (HTTP fetch, cache, retry) yapılandırır. İkisi ortogonal.

Decorator sırası (içten dışa):

OnlineOCSPSource / OnlineCRLSource   [DSS — gerçek HTTP fetch]
   │
   ▼ RetryingOCSPSource / RetryingCRLSource    [exponential backoff + jitter; fast-fail açıkken yalnız geçici hatalar]
   │
   ▼ LoggingCachingOCSPSource / LoggingCachingCRLSource    [Caffeine cache + INFO log; fast-fail açıkken + negatif cache + single-flight]
   │
   ▼ CertificateVerifier (DSS) — policy kararı uygular

Cache dış katman: cache hit retry'a girilmez (hızlı dönüş). Retry yalnız gerçek HTTP fetch'inde devreye girer: varsayılan olarak her hata yeniden denenir; fast-fail açıkken yalnız geçici hatalar (aşağıdaki "Revocation Fast-Fail"). Strict-safe garantisi: tüm retry'lar tükenirse (fast-fail açıkken hata kalıcıysa ilk denemede) son exception LoggingCachingOCSPSource'ta WARN'lanır ve null döner → DSS signer-strict / strict policy'sindeki RevocationDataAvailable=FAIL kuralı tetiklenir → imza INDETERMINATE/NO_REVOCATION_DATA.

Fast-fail açıkken başarısız fetch'ler kısa süre negatif cache'te tutulur (aşağıdaki "Negatif Cache"); bu sürede aynı sertifika için ağ çağrısı yapılmaz ve aynı null döner — DSS aynı girdiyi gördüğü için doğrulama kararı değişmez.

Cache Parametreleri
REVOCATION_CACHE_MAX_SIZE=10000         # Cache'te tutulacak maks entry sayısı
                                        # (OCSP ve CRL ayrı cache'ler — her biri 10K)
REVOCATION_CACHE_TTL=3600               # Default TTL (saniye). Token'in kendi
                                        # nextUpdate alanı varsa ondan küçük olan
                                        # seçilir; bu değer ÜST SINIR (iptali geç
                                        # görmeyelim diye). Set edilmezse legacy
                                        # CRL_CACHE_TTL fallback olur.

Cache davranış invariant'ları:

Status Cache'lenir mi? Gerekçe
GOOD / REVOKED ✅ Cache'lenir Status sabit; tekrar fetch israf
UNKNOWN ❌ Cache'lenmez Responder geçici down olabilir, bir sonraki çağrıda yeniden denenir
null (responder boş döndü) ❌ Cache'lenmez Transient olabilir
Exception (fast-fail kapalı — varsayılan) ❌ Cache'lenmez Her istek yeniden fetch eder (v1.0.4 davranışı)
Exception — kalıcı (HTTP 4xx, bozuk cevap), fast-fail açık ⏱ Negatif cache, REVOCATION_FAILURE_CACHE_TTL_SECONDS (300 s) Aynı istek aynı hatayı verir; tekrar fetch yalnız gecikme
Exception — geçici (timeout/5xx, retry'lar tükendi; DNS hatası), fast-fail açık ⏱ Negatif cache, REVOCATION_FAILURE_CACHE_TRANSIENT_TTL_SECONDS (30 s) Kesintide her isteğin 30 s beklemesini ve KamuSM'e yük bindirmesini önler; kısa TTL ile toparlanan responder hızla yeniden kullanılır
HTTP Timeout Parametreleri
REVOCATION_HTTP_CONNECT_TIMEOUT_MS=10000  # TCP connect timeout (ms)
REVOCATION_HTTP_SOCKET_TIMEOUT_MS=10000   # Socket read timeout (ms).
                                          # CRL'ler MB seviyesinde olabildiği için
                                          # düşük tutmuyoruz.
Retry Parametreleri (Anlık Flake Toleransı)

Strict policy revocation verisini ZORUNLU işaretler; tek bir KamuSM 503 / connection reset / TLS glitch geçerli bir e-Faturayı reddederdi. Retry mekanizması bunu çözer: anlık flake'te imza VALID kalır, gerçek kesintide hala FAIL.

Algoritma — exponential backoff + jitter:

delay(n)  = min(initialBackoff * multiplier^(n-1), maxBackoff)
sleepMs   = delay * (1 + uniform(-jitterRatio, +jitterRatio))
REVOCATION_RETRY_ENABLED=true             # Master switch.
                                          # false: maxAttempts=1 gibi davranır
                                          # (sadece ilk deneme, retry yok).
REVOCATION_RETRY_MAX_ATTEMPTS=3           # Toplam attempt: 1 = retry yok;
                                          # 3 = 1 ilk + 2 retry. KamuSM uçlarını
                                          # bombalamamak için >=5 default değildir.
REVOCATION_RETRY_INITIAL_BACKOFF_MS=200   # İlk retry öncesi temel bekleme.
                                          # KamuSM 503'leri tipik 200ms-1s içinde
                                          # toparlanır.
REVOCATION_RETRY_MAX_BACKOFF_MS=2000      # Exponential growth üst sınırı (clamp).
REVOCATION_RETRY_BACKOFF_MULTIPLIER=2.0   # Her retry'da çarpan. 1.0 = sabit
                                          # backoff; 2.0 = ikiye katla.
REVOCATION_RETRY_JITTER_RATIO=0.2         # ±jitterRatio rastgele varyasyon
                                          # (uniform). Thundering herd önleme
                                          # standart best-practice'i; 0.0
                                          # yaparsanız test determinizmi artar.
Revocation Fast-Fail (Feature Flag)
REVOCATION_FAST_FAIL_ENABLED=false   # Feature flag, varsayılan KAPALI.

Kapalıyken (varsayılan, canlı ortam) revocation davranışı v1.0.4 ile birebir aynıdır: her hata REVOCATION_RETRY_MAX_ATTEMPTS'e kadar yeniden denenir, başarısız fetch'ler hatırlanmaz, her istek yeniden fetch eder. Açıkken üç özellik birlikte devreye girer: aşağıdaki hata sınıflandırması (yalnız geçici hatalar yeniden denenir), negatif cache ve single-flight. TÜBİTAK Uyum Değerlendirme / test deployment'ları için geliştirilmiştir. (KamuSM test deposunun döndüğü HTTP 400 aslında Accept-Encoding: gzip başlığından kaynaklanıyordu; SİL / AIA indirmesi artık bunu otomatik aşar — bkz. Adaptive compression.)

Adaptive Compression (SİL / AIA indirmesi)

AdaptiveCompressionDataLoader her host için sıkıştırma davranışını çalışma zamanında öğrenir; yapılandırma gerekmez:

  1. İlk istek standart Accept-Encoding: gzip ile gider (sıkıştırmayı destekleyen sağlayıcılar etkilenmez).
  2. Sunucu isteği HTTP status hatasıyla reddederse (ör. KamuSM depo.test3.kamusm.gov.tr: 302 → / → 400) aynı istek sıkıştırmasız bir kez daha denenir. Zaman aşımı / bağlantı hatalarında ikinci deneme yapılmaz.
  3. Sıkıştırmasız deneme başarılıysa host hatırlanır; o hosta sonraki istekler doğrudan sıkıştırmasız gider (host başına yalnız bir kez ekstra istek).
TR Uyum Kontrolleri (Feature Flag)
TR_COMPLIANCE_CHECKS_ENABLED=true    # Feature flag, varsayılan AÇIK; false kapatır.

TÜBİTAK e-Fatura ön hazırlık değerlendirmesindeki MA3 politikasının DSS politika şemasıyla ifade edilemeyen kurallarını DSS doğrulamasından sonra uygular: özgün belgeyle (originalDocument) doğrulanamayan ayrık XAdES imza, bozuk sertifika imzası, imza zamanında süresi dolmuş / henüz geçerli olmayan sertifika, nextUpdate'i imza zaman damgasından önce dolmuş SİL, NES (UserNotice, ETSI ve BTK QC ibareleri) ve mali mühür (EKU ve politika OID'si) kuralları. NES nonRepudiation kuralı bu bayraktan bağımsız, varsayılan açık MDSS-TR-KEYUSAGE-PROFILE kontrolündedir. Bulgular appliedRejections[] altında MDSS-TR-* koduyla raporlanır ve imzanın kök nedeni olur; DSS'in asıl kararı originalIndication alanındadır. Açıkken DSS'in geçirdiği imzalar da reddedilebilir. Kod listesi: docs/rejections.

Her imza seviyesinde ayrıca zaman damgası (bozuk imza / mesaj özeti, damga anında geçersiz TSA sertifikası, güvenilir köke bağlanamayan TSA zinciri) ve bozuk imzalı güven kökü kuralları uygulanır.

TR_STRICT_REFERENCE_ENABLED=true     # Sıkı referans kullanımı, varsayılan AÇIK; yalnız TR uyum açıkken etkili.

MA3 force-strict-reference-use=true eşdeğeri (TÜBİTAK ön hazırlık kılavuzu zorunlu tutar). Uzun dönemli imzada (-C / -X / -XL / -A) zincirdeki her CA sertifikası (kök dahil) CompleteCertificateRefs içinde eşleşen özetle ve CertificateValues içinde bulunmalı; RevocationValues ile CompleteRevocationRefs birbiriyle eşleşmeli; imzacı zincirinin iptal durumu yalnız imzanın RevocationValues alanındaki veriyle, zaman damgası zincirininki bu veri ve zaman damgasının kendi içindeki veriyle değerlendirilir. DSS'in çevrimiçi veya zaman damgası içinden bulduğu başka veri; bozuk, süresi dolmuş veya eksik referans verisini ikame etmez (MDSS-TR-CERT-REF-*, MDSS-TR-CERT-VALUE-MISSING, MDSS-TR-REVOCATION-*, MDSS-TR-OCSP-*, MDSS-TR-CERT-REVOKED). Eksik referans / iptal verisinde VALIDATION_EVIDENCE_INCOMPLETE ("Eksik bilginin tamamlanması gerekmektedir") önerisi eklenir.

Takas: fast-fail açıkken responder toparlandıktan sonra aynı sertifika için negatif cache TTL'i kadar (geçici 30 s / kalıcı 300 s) "revocation verisi yok" dönebilir.

Hata sınıflandırması (RevocationFailureClassifier, yalnız fast-fail açıkken) — retry yalnız geçici hatalarda yapılır:

Hata Sınıf Retry
Connect/read timeout, havuz lease timeout geçici ✅
Bağlantı reddi (connection refused), reset, no route, erken kapanan bağlantı geçici ✅
HTTP 408, 425, 429, 5xx geçici ✅
OCSP TRY_LATER, INTERNAL_ERROR geçici ✅
HTTP 4xx (408/425/429 hariç), beklenmeyen 1xx/2xx/3xx kalıcı ❌
Bozuk/okunamayan CRL veya OCSP cevabı, boş gövde kalıcı ❌
DNS çözümleme hatası (UnknownHostException; çözümleyici kesintisi de bu hatayı verir) geçici (JVM negatif DNS cache'i ~10 s, saniye-altı retry aynı sonucu alır) ❌
Bozuk URL, desteklenmeyen protokol, TLS sertifika hatası kalıcı ❌
OCSP MALFORMED_REQUEST, SIG_REQUIRED, UNAUTHORIZED kalıcı ❌

HTTP status kodu tipli olarak okunur (StatusAwareHttpClientResponseHandler → UnacceptableHttpStatusException; mesaj DSS'inkiyle birebir aynı), stok DSS handler'ı ile kurulmuş loader'lar için DSS mesajından (HTTP status code : 400) parse edilir. Bağlantı reddi bilinçli olarak geçici sayılır: responder/LB yeniden başlarken saniyeler içinde düzelebilir, red anında döndüğü için retry maliyeti yalnız backoff'tur (~0.6 s) ve negatif cache sayesinde TTL başına en fazla bir kez ödenir. Örnek: KamuSM test CRL'leri (depo.test3.kamusm.gov.tr) kalıcı HTTP 400 döner — fast-fail kapalıyken her biri 3 deneme + backoff ile ~0.8-1.0 s sürer (ESA örneklerinde 4 CRL ≈ 3.5 s); fast-fail açıkken tek denemede (~0.1 s) biter, tekrar eden isteklerde hiç ağa çıkılmaz.

Default'larla worst-case latency (bir token için): maxAttempts × httpTimeout + Σ backoffs = 3 × 10s + (0.2s + 0.4s) ≈ 30.6s (KamuSM tamamen kapalıysa). Tipik flake yalnız +200-400ms ekler.

Senaryo örnekleri:

Senaryo MAX_ATTEMPTS INITIAL_BACKOFF_MS MAX_BACKOFF_MS JITTER_RATIO Worst-case latency
Üretim default (Mali Mühür) 3 200 2000 0.2 ~30.6s
Agresif retry (KamuSM stresli) 5 300 5000 0.2 ~75s
Düşük-latency (canlı API) 2 100 1000 0.2 ~20.1s
Deterministic test/CI 3 200 2000 0.0 ~30.6s (sabit)
Retry kapalı (REVOCATION_RETRY_ENABLED=false) 1 (effective) – – – ~10s
Negatif Cache (Başarısız OCSP/CRL Fetch'leri)

Yalnız REVOCATION_FAST_FAIL_ENABLED=true iken etkindir; kapalıyken aşağıdaki değerler kullanılmaz.

Başarısız bir fetch, sertifika + issuer kimliği + dağıtım noktası/responder URL'leri anahtarıyla kısa süre hatırlanır. Bu sürede aynı sertifika için delegate çağrılmaz; başarısız fetch'in bugün ürettiği sonucun aynısı (null token → "revocation verisi yok") döner, dolayısıyla DSS'in vereceği karar değişmez. Başarılı cevapların cache'i (yukarıdaki REVOCATION_CACHE_*) aynen çalışır. Aynı sertifika için eşzamanlı istekler tek bir fetch'i paylaşır (single-flight): N paralel istek KamuSM'e N değil 1 istek gönderir.

REVOCATION_FAILURE_CACHE_TTL_SECONDS=300            # Kalıcı hatalar (HTTP 4xx, bozuk cevap, protokol).
                                                    # 0 = negatif cache + single-flight kapalı
                                                    # (eski davranış: her istek yeniden fetch).
REVOCATION_FAILURE_CACHE_TRANSIENT_TTL_SECONDS=30   # Geçici hatalar (timeout/5xx sonrası retry'lar
                                                    # tükendi; DNS hatası). TTL_SECONDS'ı aşamaz; 0 = geçici
                                                    # hatalar cache'lenmez.
REVOCATION_FAILURE_CACHE_MAX_SIZE=1000              # Maks kayıt (OCSP ve CRL ayrı).

Loglar: hata ilk cache'lendiğinde INFO CRL fetch failure cached for 300 s: subject=..., urls=[...], failure=permanent (HTTP 400); cache'ten dönüldüğünde DEBUG CRL failure cache hit. URL'lerdeki kullanıcı bilgisi (user:pass@) loglanmaz. Metrikler: cache_gets_total{cache="mersel.revocation.crl.failure"|"mersel.revocation.ocsp.failure"}, retry atlanan kalıcı hatalar mdss_revocation_retry_total{event="permanent"}.

Trade-off: TTL süresince toparlanan bir responder kullanılmaz (o sertifika için "revocation verisi yok" kalır). Kalıcı hatalarda bu pratikte değişmez; geçici hatalar için TTL bu yüzden kısa (30 s). Kesin "her istekte yeniden dene" davranışı fast-fail kapalıyken (varsayılan) zaten geçerlidir; fast-fail açıkken yalnız negatif cache'i kapatmak için REVOCATION_FAILURE_CACHE_TTL_SECONDS=0 (veya yalnız geçiciler için REVOCATION_FAILURE_CACHE_TRANSIENT_TTL_SECONDS=0).

Response — Revocation Detayları

Her doğrulama response'unda zincir üzerindeki her sertifika için DSS DiagnosticData'sından çıkarılan zengin iptal detayı signerCertificate.revocation (ve certificateChain[].revocation) alt nesnesinde döner. Daha önce hem revoked: false hem certificateNotRevoked: true hardcoded'tu — REVOKED bir sertifika bile response'da "iptal değil" görünüyordu. Şimdi gerçek durum yansıtılır.

"signerCertificate": {
  "subjectDN": "CN=Test User, ...",
  "revoked": true,                          // geriye dönük; artık gerçeği yansıtır
  "revocationReason": "KEY_COMPROMISE",
  "revocationDate": "2024-09-15T08:30:00Z",
  "revocation": {                           // YENİ — zengin detay
    "source": "OCSP",                       // OCSP | CRL
    "status": "REVOKED",                    // GOOD | REVOKED | UNKNOWN
    "revocationDate": "2024-09-15T08:30:00Z",
    "revocationReason": "KEY_COMPROMISE",
    "producedAt": "2024-11-08T10:29:55Z",   // token üretim anı
    "thisUpdate": "2024-11-08T10:00:00Z",   // token freshness başlangıcı
    "nextUpdate": "2024-11-08T11:00:00Z",   // bir sonraki güncelleme (cache TTL ile uyumlu)
    "responderUrl": "http://ocsp.kamusm.gov.tr",
    "origin": "EXTERNAL"                    // EXTERNAL | CACHED | REVOCATION_VALUES | …
  }
}

Alan anlamları:

Alan Anlam
source İptal token'ının türü: OCSP veya CRL.
status Sertifikanın gerçek durumu: GOOD (iptal değil), REVOKED (iptalli), UNKNOWN (responder bilmiyor).
revocationDate Sertifikanın iptal edildiği an (yalnız REVOKED ise dolar).
revocationReason RFC 5280 iptal nedeni (örn. KEY_COMPROMISE, CESSATION_OF_OPERATION).
producedAt OCSP response / CRL'in üretildiği zaman.
thisUpdate Token'ın temsil ettiği bilginin geçerli olduğu başlangıç anı.
nextUpdate Bir sonraki güncellemenin beklendiği an. Cache TTL bu değerle clamp'lenir.
responderUrl İptal verisinin alındığı responder/dağıtım noktası — audit için kritik.
origin Veri menşei: EXTERNAL (canlı sorgu), CACHED (Caffeine cache hit), REVOCATION_VALUES / CMS_SIGNED_DATA (LT-level imzada gömülü), TIMESTAMP_VALIDATION_DATA, vb.

origin neden önemli? LT-level (PAdES/XAdES/CAdES BASELINE-LT) imzalarda revocation token'lar imzanın içinde gömülü gelir — bu durumda Mersel hiç OCSP/CRL ağ çağrısı yapmadan kararı verebilir. origin: REVOCATION_VALUES görüyorsanız "imzanın kendi içindeki güven kanıtı kullanıldı" demektir. origin: EXTERNAL ise canlı sorgu yapıldı (cache miss + retry zinciri çalıştı).

revocation ne zaman null olur?

  • ONLINE_VALIDATION_ENABLED=false ve imza içinde gömülü revocation yoksa,
  • DSS sertifika için hiçbir revocation token üretemediyse (örn. B-level imza, çevrimdışı, AIA çözülmedi),
  • Responder ile hiç iletişim kurulamadı ve gömülü veri de yok.

Bu durumda alan tamamen JSON'a düşmez (@JsonInclude(NON_NULL)). Strict policy'de imzanın valid field'ı zaten DSS tarafından INDETERMINATE/NO_REVOCATION_DATA ile FAIL'lenmiş olur.

Zincir Genel Durumu — chainRevocationStatus

signatures[].chainRevocationStatus, her doğrulama modunda (SIMPLE + COMPREHENSIVE) yayınlanan kompakt bir özet enum'dur. Önceden SIMPLE mod tüketicisi yalnız signerCertificate.revocation'i görüyordu; ara CA seviyesindeki "leaf GOOD ama bir CA REVOKED" gibi durumlar yalnız COMPREHENSIVE modda certificateChain[].revocation alt nesneleriyle ifşa ediliyordu. Bu alan tek bir string ile tüketicinin SIMPLE'da da zincirin geneline dair doğru kararı vermesini sağlar.

"signatures": [{
  "valid": true,
  "signerCertificate": { "revoked": false, ... },
  "chainRevocationStatus": "ALL_GOOD"   // YENİ
}]

Değer matrisi:

Değer Anlam Önerilen aksiyon
ALL_GOOD Zincirdeki tüm sertifikalar (leaf + ara CA'lar) revocation kontrolünden GOOD geçti. İşlemi gönül rahatlığıyla sürdür.
LEAF_REVOKED İmzacı sertifika REVOKED. CA durumu ne olursa olsun en kritik sinyal. Imza üzerinde iş yapma; sertifika sahibine bilgi ver.
LEAF_GOOD_CA_REVOKED İmzacı GOOD, ama zincirdeki bir ara CA REVOKED. signer-strict profilinde imza yine valid: true döner (NotRevoked=WARN); strict profilinde imza geçersiz olur (NotRevoked=FAIL). Politika tercihini sorgula; audit'e detay için COMPREHENSIVE çek.
UNKNOWN Zincirde bir veya daha fazla sertifika için durum UNKNOWN (responder cevap verdi ama "bilmiyorum" dedi) ya da leaf için karar verilemiyor. Operasyonel sorun olabilir; COMPREHENSIVE ile incele.
NOT_CHECKED Hiçbir sertifika için revocation kontrolü yapılmadı/yapılamadı. Çevrimdışı mod, B-level imza, ya da responder hep down olabilir. Çevrimdışı/strict kombinasyonu mu kontrol et.

Önemli — Bu alan doğrulama kararını değiştirmez. DSS policy zincirin tamamını SigningCertificate + CACertificate blokları üzerinden kendi kuralları çerçevesinde kontrol eder; signatures[].valid bu policy'ye göre belirlenir. chainRevocationStatus yalnız UI/audit görünürlüğü için bir özet sinyaldir.

Önceliklendirme: Leaf REVOKED her zaman kazanır (LEAF_REVOKED). Leaf UNKNOWN ikinci önceliktedir (UNKNOWN) — CA REVOKED olsa bile imzacı için belirsizlik daha öncelikli sinyal. Sadece leaf GOOD ise CA seviyesi değerlendirilir.

Politika profilleri ile etkileşim:

  • signer-strict (default) + LEAF_GOOD_CA_REVOKED → valid: true (CA için sadece WARN). Operasyonel toleranslı.
  • strict + LEAF_GOOD_CA_REVOKED → valid: false, sub-indication: REVOKED_CA_NO_POE / benzeri. eIDAS QES paralelinde sıkı davranır.

Detaylı zincir cert'lerine erişim için doğrulamayı level=COMPREHENSIVE ile çağırın — certificateChain[i].revocation alt nesneleri her cert için ayrı dolar.

İmzacı Sertifika Profili ve Nitelikli Sertifika İbareleri — signerCertificateProfile, qcStatements

Her doğrulama modunda (SIMPLE + COMPREHENSIVE) her imza, imzacı sertifikasının profilini ve nitelikli sertifika ibarelerini döner:

"signatures": [{
  "signerCertificateProfile": "NES_E_IMZA",   // NES_E_IMZA | MALI_MUHUR | UNKNOWN
  "signerCertificate": {
    "qcStatements": ["0.4.0.1862.1.1", "2.16.792.1.61.0.1.5070.1.1"],
    ...
  }
}]
  • signerCertificateProfile sertifikanın OID'lerinden tespit edilir: mali mühür politikası (2.16.792.1.2.1.1.5.7.4.1) veya EKU'su (2.16.792.1.2.1.1.5.7.50.1) → MALI_MUHUR; NES politikası (2.16.792.1.2.1.1.5.7.1.1) veya 5070 sayılı Kanun QC ibaresi (2.16.792.1.61.0.1.5070.*) → NES_E_IMZA; kanıt yoksa UNKNOWN. İmzacı sertifikası bulunamazsa alan JSON'a düşmez.
  • qcStatements, sertifikanın QCStatements uzantısındaki (RFC 3739) ibare OID'leridir, sertifikadaki sırayla; uzantı yoksa []. 5070 sayılı Kanun'a göre nitelikli sertifika ibaresi BTK 2.16.792.1.61.0.1.5070.1.1, ETSI QcCompliance 0.4.0.1862.1.1'dir. Aynı alan certificateChain[] (COMPREHENSIVE) ve zaman damgası sertifikalarında da bulunur.

Bu alanlar doğrulama kararını değiştirmez. Sertifikadaki beyanı aktarır; imzanın geçerliliği valid / indication alanlarındadır.

TR-Legacy XAdES Toleransı

KamuSM / GİB ekosistemindeki bazı imzalama araçları (özellikle bazı e-Belge entegratörlerinin eski sürümleri), XAdES Reference Type URI'sini standart dışı yazıyor:

Type URI
❌ Bazı TR araçlarında üretilen http://uri.etsi.org/01903/v1.3.2/XAdES.xsd#SignedProperties
✅ ETSI TS 101 903 standardı http://uri.etsi.org/01903#SignedProperties

Eclipse DSS spec'e harfiyen uyduğu için bu Type URI'yi tanımıyor ve kriptografik olarak sağlam imzaları bile INDETERMINATE / SIG_CONSTRAINTS_FAILURE ile reddediyor (BBB sebebi: BBB_SAV_ISQPMDOSPP). TÜBİTAK İmzager ve KamuSM doğrulama servisleri ise bu imzaları kabul ediyor.

TR_LEGACY_XADES_TOLERANCE=true      # Default: true (TÜBİTAK İmzager paritesi)
# TR_LEGACY_XADES_TOLERANCE=false   # eIDAS-QES paralelinde davran (DSS strict)

Tolerans AÇIKken aşağıdaki 6 koşulun TAMAMI sağlanırsa imza TOTAL_PASSED'e yükseltilir, açıklayıcı bir uyarı validationWarnings'e eklenir:

  1. Indication = INDETERMINATE
  2. SubIndication = SIG_CONSTRAINTS_FAILURE
  3. DSS DiagnosticData: signatureIntact && signatureValid (kriptografik bütünlük)
  4. BBB SAV içinde yalnızca BBB_SAV_ISQPMDOSPP constraint'i FAIL
  5. Orijinal XML'de 01903 + .xsd + #SignedProperties paterniyle eşleşen Type URI bulundu
  6. verification.tr-legacy-xades-tolerance-enabled=true

Önemli — bu jenerik bir SIG_CONSTRAINTS bypass değildir: zayıf algoritma (BBB_SAV_ISCDC), bozuk SignedProperties digest, eksik SigningCertificate gibi diğer SAV constraint'leri FAIL ediyorsa imza yine reddedilir.

Tolerans uygulandığında log'a tek satır kaydedilir:

TR legacy XAdES toleransı uygulandı (signatureId=…, code=MDSS-XADES-LEGACY-TR-TYPE-URI).
DSS INDETERMINATE/SIG_CONSTRAINTS_FAILURE iken imza kriptografik olarak sağlam
ve tek hata BBB_SAV_ISQPMDOSPP. Üretici Type URI: '…'

Applied Suppressions — Audit Trail

Mersel DSS Verifier'ın DSS kararını override ettiği her durum response içinde yapılandırılmış olarak raporlanır. Bu, "DSS aslında ne demişti, biz ne yaptık, neden?" sorusuna machine-readable cevap verir — audit, compliance ve operasyonel görünürlük için kritik.

{
  "signatures": [
    {
      "valid": true,
      "indication": "TOTAL_PASSED",
      "appliedSuppressions": [
        {
          "code": "MDSS-XADES-LEGACY-TR-TYPE-URI",
          "title": "TR-legacy XAdES SignedProperties Type URI toleransı",
          "reason": "İmza, KamuSM/GİB ekosistemine özgü XAdES SignedProperties Type URI yazım hatası içeriyor. Kriptografik bütünlük doğrulandı; tolerans uygulandı. Üretici Type URI: \"http://uri.etsi.org/01903/v1.3.2/XAdES.xsd#SignedProperties\".",
          "severity": "INFO",
          "originalIndication": "INDETERMINATE",
          "originalSubIndication": "SIG_CONSTRAINTS_FAILURE",
          "evidence": {
            "detectedTypeUri": "http://uri.etsi.org/01903/v1.3.2/XAdES.xsd#SignedProperties",
            "expectedTypeUri": "http://uri.etsi.org/01903#SignedProperties",
            "dssBbbConstraint": "BBB_SAV_ISQPMDOSPP"
          },
          "docsUrl": "https://github.com/mersel-dss/mersel-dss-verifier-api-java/blob/main/docs/suppressions/MDSS-XADES-LEGACY-TR-TYPE-URI.md"
        }
      ]
    }
  ]
}

Code naming convention: MDSS-{LAYER}-{DESCRIPTIVE-SLUG}

  • MDSS — Mersel DSS prefix'i.
  • {LAYER} — XADES / CADES / PADES / CHAIN / CRYPTO / TIMESTAMP / REVOCATION.
  • {DESCRIPTIVE-SLUG} — UPPER-KEBAB-CASE özellik adı.

Kararlılık (stability): bir kez yayınlanan kod değiştirilmez. Davranış değişiyorsa yeni kod eklenir, eskisi @Deprecated olur.

Detaylı dokümantasyon: Her bir kodun ne yaptığını, hangi koşullarda tetiklendiğini, severity gerekçesini ve nasıl kapatılabileceğini docs/suppressions/ klasörü altındaki MD dosyaları anlatır. Kayıtlı kodların tam listesi: SuppressionCode enum'u.

Severity seviyeleri:

  • INFO — tasarımdan sapma ama güvenlik etkisi yok (örn. üretici Type URI yazım hatası, kriptografi sağlam).
  • WARN — operatörün dikkat etmesi önerilir.
  • CRITICAL — operatör eylem almalı.

Operasyonel kullanım: appliedSuppressions[].code doğrudan Prometheus metric label, log filter veya support ticket referansı olarak kullanılabilir (mersel_dss_suppression_applied_total{code="MDSS-XADES-LEGACY-TR-TYPE-URI"}). appliedSuppressions boş veya null ise: DSS'in kararı aynen kullanıldı, hiçbir Mersel-spesifik tolerans uygulanmadı.

Güvenilir Kök Sertifika Resolver Kullanımı

Sistem üç farklı resolver tipini destekler. TRUSTED_ROOT_RESOLVER_TYPE parametresi ile seçim yapılır.

1. KamuSM XML Depo Online (Varsayılan)

Varsayılan olarak, KamuSM root ve ara sertifikaları otomatik olarak şu adresten yüklenir:

Bu sayede her zaman güncel sertifikalar kullanılır. Periyodik olarak otomatik yenilenir (varsayılan: her gün saat 03:15).

export TRUSTED_ROOT_RESOLVER_TYPE=kamusm-online
export KAMUSM_ROOT_URL=http://depo.kamusm.gov.tr/depo/SertifikaDeposu.xml
export KAMUSM_ROOT_REFRESH_CRON="0 15 3 * * *"  # Her gün saat 03:15

2. KamuSM XML Depo Offline

Offline ortamlarda veya internet bağlantısı olmayan sistemlerde, KamuSM sertifika deposunu yerel dosya sisteminden yükleyebilirsiniz:

export TRUSTED_ROOT_RESOLVER_TYPE=kamusm-offline
export KAMUSM_ROOT_OFFLINE_PATH=file:/path/to/SertifikaDeposu.xml
# veya classpath'ten
export KAMUSM_ROOT_OFFLINE_PATH=classpath:certs/SertifikaDeposu.xml

Offline Mod Kullanım Senaryoları:

  • Air-gapped (izole) sistemler
  • İnternet bağlantısı olmayan ortamlar
  • Güvenlik gereksinimleri nedeniyle dış bağlantı kısıtlamaları
  • Yerel sertifika deposu kullanımı

Not: Offline modda sertifikalar sadece uygulama başlangıcında yüklenir. Otomatik yenileme yapılmaz.

3. Certificate Folder Resolver

Belirtilen klasördeki tüm .crt, .cer ve .pem dosyalarını güvenilir kök sertifika olarak yükler. Bu resolver, özel sertifika klasörlerinden sertifika yüklemek için idealdir.

export TRUSTED_ROOT_RESOLVER_TYPE=certificate-folder
export TRUSTED_ROOT_CERT_FOLDER_PATH=/path/to/certificates
# veya file: prefix ile
export TRUSTED_ROOT_CERT_FOLDER_PATH=file:/path/to/certificates

Certificate Folder Resolver Kullanım Senaryoları:

  • Özel sertifika klasörlerinden yükleme
  • Kurumsal CA sertifikalarının toplu yüklenmesi
  • Test ortamlarında özel sertifika kullanımı
  • Farklı kaynaklardan sertifika birleştirme

Not: Klasördeki tüm geçerli sertifika dosyaları otomatik olarak yüklenir. Alt klasörler taranmaz.

Sertifika Deposu (Zorunlu)

Sertifika deposu kullanmak için (zorunlu):

export CERTSTORE_PATH=/path/to/kamusm-certstore.jks
export CERTSTORE_PASSWORD=yourpassword

veya özel bir root sertifika eklemek için:

export CUSTOM_ROOT_CERT_PATH=/path/to/custom-root.cer

📊 Monitoring

Prometheus metrikleri /actuator/prometheus endpoint'inde sunulur:

curl http://localhost:8086/actuator/prometheus

Revocation Cache Metric Ailesi

LoggingCachingOCSPSource ve LoggingCachingCRLSource Caffeine cache instance'ları Micrometer aracılığıyla otomatik publish edilir. Cache başına metric isimleri (Micrometer naming) ve cache tag'leri:

Metric OCSP tag CRL tag Anlamı
cache_size cache="mersel.revocation.ocsp" cache="mersel.revocation.crl" Anlık cache entry sayısı
cache_gets_total{result="hit"} aynı aynı Cache hit sayısı (HTTP fetch atlandı)
cache_gets_total{result="miss"} aynı aynı Cache miss sayısı (gerçek HTTP fetch tetiklendi)
cache_puts_total aynı aynı Cache'e konan response sayısı (GOOD/REVOKED; UNKNOWN ve null bilinçli cache'lenmez)
cache_evictions_total aynı aynı TTL veya size limit kaynaklı evict sayısı

Operasyonel sorgu örnekleri (PromQL):

# OCSP hit-rate (cache verimliliği)
rate(cache_gets_total{cache="mersel.revocation.ocsp",result="hit"}[5m])
  / rate(cache_gets_total{cache="mersel.revocation.ocsp"}[5m])

# KamuSM endpoint'lerine giden gerçek HTTP fetch yükü
rate(cache_puts_total{cache=~"mersel.revocation.(ocsp|crl)"}[1h])

# Cache büyüklüğü trend (memory baskısı için)
cache_size{cache=~"mersel.revocation.(ocsp|crl)"}

Grafana ile birlikte çalıştırmak için:

docker-compose --profile monitoring up -d

🔒 Güvenlik

Production Önerileri

  1. CORS Ayarları: Production'da CORS_ALLOWED_ORIGINS değerini spesifik domain'lere sınırlayın
  2. HTTPS: Reverse proxy (nginx, traefik) ile HTTPS kullanın
  3. Rate Limiting: API rate limiting uygulayın
  4. Network Segmentation: Servislerinizi izole network'lerde çalıştırın
  5. Sertifika Güvenliği: Sertifika deposu şifrelerini güvenli bir şekilde saklayın (vault, secrets manager)

🧪 Test

# Tüm testleri çalıştır
mvn test

# Spesifik test
mvn test -Dtest=SignatureVerificationServiceTest

📖 API Dokümantasyonu

OpenAPI dokümantasyonuna erişim:

http://localhost:8086/api-docs

🔗 Önemli Bağlantılar

Dosya Açıklama
dss.mersel.dev 📚 Merkezi Dökümantasyon
LICENSE MIT Lisansı
CHANGELOG.md Versiyon geçmişi
CONTRIBUTING.md Katkıda bulunma rehberi
SECURITY.md Güvenlik politikası
COMPARISON_REPORT.md Sign-API ile karşılaştırma raporu

🤝 Katkıda Bulunma

CONTRIBUTING.md dosyasına bakın.


📄 Lisans

MIT


💡 Hatırlatma

Detaylı dökümantasyon, API referansları, deployment rehberleri ve tüm güncellemeler için:

👉 https://dss.mersel.dev merkezi dökümantasyon sitesini ziyaret edin! 📚


Not: Bu servis, sign-api projesinin doğrulama karşılığıdır. İmzalama işlemleri için sign-api'yi kullanın.

About

No description, website, or topics provided.

Resources

Contributing

Stars

10 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages