CertificateInfoController.java
package io.mersel.dss.signer.api.controllers;
import io.mersel.dss.signer.api.dtos.CertificateInfoDto;
import io.mersel.dss.signer.api.models.configurations.SignatureServiceConfiguration;
import io.mersel.dss.signer.api.services.CertificateInfoService;
import io.mersel.dss.signer.api.services.keystore.KeyStoreProvider;
import io.mersel.dss.signer.api.services.keystore.PKCS11KeyStoreProvider;
import io.mersel.dss.signer.api.services.keystore.PfxKeyStoreProvider;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Keystore içerisindeki sertifika bilgilerini listeleme endpoint'i.
* PKCS#11 veya PFX keystore'dan sertifika alias ve serial number bilgilerini almak için kullanılır.
*/
@RestController
@CrossOrigin(origins = "*", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, RequestMethod.OPTIONS})
@RequestMapping("/api/certificates")
@Tag(name = "Certificate Info", description = "Keystore sertifika bilgileri API'si")
public class CertificateInfoController {
private static final Logger LOGGER = LoggerFactory.getLogger(CertificateInfoController.class);
@Autowired
private CertificateInfoService certificateInfoService;
@Autowired
private SignatureServiceConfiguration config;
/**
* Singleton {@link KeyStoreProvider} bean'i — HSM yolunda da PFX yolunda
* da {@link io.mersel.dss.signer.api.config.SignatureConfiguration}
* tarafından sağlanır. Burada her istekte yeni provider üretmiyoruz;
* yapılandırma yaşam döngüsü Spring container'a teslim edilir.
*/
@Autowired
private KeyStoreProvider keyStoreProvider;
/**
* Yapılandırılmış keystore'dan tüm sertifikaları listeler.
*
* GET /api/certificates/list
*/
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(
summary = "Keystore sertifikalarını listele",
description = "Yapılandırılmış keystore (PKCS#11 veya PFX) içerisindeki tüm sertifikaları listeler. " +
"Bu endpoint ile alias ve serial number bilgilerini öğrenebilirsiniz.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Sertifika listesi başarıyla döndürüldü",
content = @Content(schema = @Schema(implementation = CertificateInfoDto.class))
),
@ApiResponse(responseCode = "500", description = "Keystore yüklenemedi veya sertifikalar okunamadı")
}
)
public ResponseEntity<?> listCertificates() {
try {
LOGGER.info("Sertifika listesi istendi");
char[] pin = config.getCertificatePin().toCharArray();
List<CertificateInfoDto> certificates =
certificateInfoService.listCertificates(keyStoreProvider, pin);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("keystoreType", keyStoreProvider.getType());
response.put("certificateCount", certificates.size());
response.put("certificates", certificates);
return ResponseEntity.ok(response);
} catch (Exception e) {
LOGGER.error("Sertifika listesi alınamadı", e);
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("success", false);
errorResponse.put("error", e.getMessage());
return ResponseEntity.status(500).body(errorResponse);
}
}
/**
* Keystore bilgilerini döndürür (hangi tip kullanılıyor, vs.)
*
* GET /api/certificates/info
*/
@GetMapping(value = "/info", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(
summary = "Keystore bilgilerini getir",
description = "Yapılandırılmış keystore hakkında genel bilgi döndürür (tip, yol, slot, vb.)",
responses = {
@ApiResponse(responseCode = "200", description = "Keystore bilgileri başarıyla döndürüldü")
}
)
public ResponseEntity<Map<String, Object>> getKeystoreInfo() {
Map<String, Object> info = new HashMap<>();
try {
info.put("success", true);
info.put("keystoreType", keyStoreProvider.getType());
if (keyStoreProvider instanceof PKCS11KeyStoreProvider) {
info.put("library", config.getPkcs11LibraryPath());
info.put("slot", config.getPkcs11Slot());
} else if (keyStoreProvider instanceof PfxKeyStoreProvider) {
info.put("pfxPath", config.getPfxPath());
}
info.put("certificateAlias", config.getCertificateAlias());
info.put("certificateSerialNumber", config.getCertificateSerialNumber());
} catch (Exception e) {
info.put("success", false);
info.put("error", e.getMessage());
}
return ResponseEntity.ok(info);
}
}