SignatureServiceConfiguration.java
package io.mersel.dss.signer.api.models.configurations;
import eu.europa.esig.dss.xades.signature.XAdESSigningTimeZoneHolder;
import io.mersel.dss.signer.api.services.timestamp.tubitak.TubitakTspDetector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.time.ZoneId;
@Component
public class SignatureServiceConfiguration {
@Value("${PFX_PATH:}")
private String pfxPath;
@Value("${PKCS11_LIBRARY:}")
private String pkcs11LibraryPath;
@Value("${PKCS11_SLOT:-1}")
private Long pkcs11Slot;
@Value("${PKCS11_SLOT_LIST_INDEX:-1}")
private Long pkcs11SlotIndex;
/**
* TÜBİTAK BİLGEM AKİS macOS/Linux sürücüsü gibi standart
* {@code C_Initialize(CK_C_INITIALIZE_ARGS{flags=CKF_OS_LOCKING_OK})}
* çağrısını {@code CKR_ARGUMENTS_BAD} ile reddeden kütüphaneler için
* trial-and-error yapmadan doğrudan {@code C_Initialize(NULL)} yoluna
* gidilir. Auto-detect zaten devrede; bu bayrak yalnızca operatöre
* "ben biliyorum, hemen NULL'a git" demek için.
*
* <p>Yan etki: kütüphane PKCS#11 v2.40 §5.4 gereği thread-unsafe
* sayılacağı için {@code PKCS11Token} havuzu {@code numSessions=1}'e
* sıkıştırılır. Akıllı kart donanımı paralel oturum kaldırmadığı için
* pratik bir performans kaybı yoktur.</p>
*/
@Value("${PKCS11_NULL_INIT_ARGS:false}")
private boolean pkcs11NullInitArgs;
@Value("${CERTIFICATE_PIN}")
private String certificatePin;
@Value("${CERTIFICATE_SERIAL_NUMBER:}")
private String certificateSerialNumber;
@Value("${CERTIFICATE_ALIAS:}")
private String certificateAlias;
@Value("${CERTIFICATE_CHAIN_GET_ONLINE:true}")
private boolean certificateChainGetOnline;
@Value("${ISSUER_CERTIFICATE_PATH:/}")
private String issuerCertificatePath;
@Value("${CA_CERTIFICATE_PATH:/}")
private String caCertificatePath;
@Value("${TS_SERVER_HOST:http://zd.kamusm.gov.tr}")
private String timeStampServerHost;
@Value("${TS_DIGEST_ALGORITHM:SHA-256}")
private String timeStampDigestAlgorithm;
@Value("${TS_USER_ID:0}")
private String timeStampUserId;
@Value("${TS_USER_PASSWORD:0}")
private String timeStampUserPassword;
@Value("${IS_TUBITAK_TSP:false}")
private boolean isTubitakTsp;
@Value("${MA3API_LICENSE_PATH:0}")
private String ma3apiLicensePath;
@Value("${MAX_SESSION_COUNT:5}")
private int maxSessionCount;
@Value("${CERTSTORE_PATH:SertifikaDeposu.svt}")
private String certStorePath;
/**
* XAdES {@code <SigningTime>} elemanının XML çıktısında kullanılacak
* zaman dilimi. Default {@code +03:00} — TÜBİTAK MA3 referans çıktısı
* ve İMZAGER lokal gösterimi ile birebir uyumlu (bkz. issue #7).
*
* <p>Desteklenen değerler:</p>
* <ul>
* <li>Sabit ofset: {@code +03:00}, {@code -05:30}</li>
* <li>UTC: {@code Z}, {@code UTC}, {@code GMT}</li>
* <li>IANA bölge: {@code Europe/Istanbul} (DST destekli)</li>
* </ul>
*
* <p><b>ETSI/EN 319 132-1 saf yorumu</b> {@code Z} ister; bu kullanıcılar
* için ENV'i {@code Z} olarak set etmek yeterlidir. Default Türkiye
* ekosistemi gözetilerek {@code +03:00} bırakılmıştır.</p>
*/
@Value("${XADES_SIGNING_TIME_ZONE:+03:00}")
private String xadesSigningTimeZone;
public String getPkcs11LibraryPath() {
return pkcs11LibraryPath;
}
public String getCertificatePin() {
return certificatePin;
}
public String getCertificateSerialNumber() {
return certificateSerialNumber;
}
public String getCertificateAlias() {
return certificateAlias;
}
public Long getPkcs11Slot() {
return pkcs11Slot;
}
public Long getPkcs11SlotIndex() {
return pkcs11SlotIndex;
}
public boolean isPkcs11NullInitArgs() {
return pkcs11NullInitArgs;
}
public String getIssuerCertificatePath() {
return issuerCertificatePath;
}
public String getCaCertificatePath() {
return caCertificatePath;
}
public boolean isCertificateChainGetOnline() {
return certificateChainGetOnline;
}
public String getTimeStampServerHost() {
return timeStampServerHost;
}
public String getTimeStampDigestAlgorithm() {
return timeStampDigestAlgorithm;
}
public String getTimeStampUserId() {
return timeStampUserId;
}
public String getTimeStampUserPassword() {
return timeStampUserPassword;
}
public String getMa3apiLicensePath() {
return ma3apiLicensePath;
}
public String getPfxPath() {
return pfxPath;
}
public String getCertStorePath() {
return certStorePath;
}
public int getMaxSessionCount() {
return maxSessionCount;
}
/**
* Etkin TÜBİTAK modu. {@code IS_TUBITAK_TSP} açıkça {@code true} ise
* her zaman {@code true}; aksi halde {@code TS_SERVER_HOST} KamuSM
* zaman damgası endpoint'lerinden birine işaret ediyorsa otomatik
* olarak {@code true} döner. Operatörün bayrağı set etmeyi
* unutmasına karşı fail-safe.
*/
public boolean isTubitakTsp() {
return TubitakTspDetector.resolveTubitakTspMode(isTubitakTsp, timeStampServerHost);
}
/**
* XAdES {@code <SigningTime>} için yapılandırılmış zaman dilimini ham
* string olarak döner. Çoğunlukla loglama / observability içindir;
* çözümlenmiş hâli için {@link #getXadesSigningTimeZone()} kullanın.
*/
public String getXadesSigningTimeZoneRaw() {
return xadesSigningTimeZone;
}
/**
* XAdES {@code <SigningTime>} için kullanılacak {@link ZoneId}. Parse
* başarısız olursa fail-fast: uygulama açılışta hatayla durur, böylece
* üretimde sessizce yanlış formatta imza üretmek yerine yapılandırma
* problemi erken yakalanır.
*/
public ZoneId getXadesSigningTimeZone() {
return XAdESSigningTimeZoneHolder.parseZone(xadesSigningTimeZone);
}
}