diff --git a/src/main/java/de/mlessmann/certassist/web/CertificatesEndpoint.java b/src/main/java/de/mlessmann/certassist/web/CertificatesEndpoint.java index bb1b389..8737584 100644 --- a/src/main/java/de/mlessmann/certassist/web/CertificatesEndpoint.java +++ b/src/main/java/de/mlessmann/certassist/web/CertificatesEndpoint.java @@ -5,20 +5,27 @@ import de.mlessmann.certassist.models.CertificateInfo; import de.mlessmann.certassist.models.CertificateInfoSubject; import de.mlessmann.certassist.repositories.CertificateRepository; import de.mlessmann.certassist.service.CertificateCreationService; +import de.mlessmann.certassist.web.dto.PrivateKey; 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 lombok.RequiredArgsConstructor; import org.springdoc.core.annotations.ParameterObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; +import org.springframework.util.MimeTypeUtils; import org.springframework.web.bind.annotation.*; +import java.nio.charset.StandardCharsets; + @RestController @RequestMapping("/api") @RequiredArgsConstructor(onConstructor_ = @Autowired) public class CertificatesEndpoint { + public static final String MIME_PEM_FILE = "application/x-pem-file"; private final CertificateRepository certificateRepository; private final CertificateCreationService certificateCreationService; @@ -48,4 +55,34 @@ public class CertificatesEndpoint { return ResponseEntity.ok(createdCertificate); } + @GetMapping(value = "/certificates/{cert}/privateKey", produces = { + MimeTypeUtils.APPLICATION_JSON_VALUE, + MIME_PEM_FILE + }) + @Operation(description = "Fetches the private key corresponding to the provided certificate.", + responses = { + @ApiResponse(responseCode = "200", content = { + @Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = PrivateKey.class)), + @Content(mediaType = MIME_PEM_FILE, + schema = @Schema(type = "string", description = "PEM formatted private key content")) + }) + }) + public ResponseEntity getCertificatePrivateKey( + @RequestHeader("Accept") String acceptType, + @PathVariable String cert + ) { + var requestedCert = certificateRepository.findByFingerprintIs(cert); + + if (MimeTypeUtils.APPLICATION_JSON_VALUE.equals(acceptType)) { + String pemContent = new String(requestedCert.getPrivateKey(), StandardCharsets.UTF_8); + var pKey = new PrivateKey(pemContent); + return ResponseEntity.ok(pKey); + } else if (MIME_PEM_FILE.equals(acceptType)) { + String pemContent = new String(requestedCert.getPrivateKey(), StandardCharsets.UTF_8); + return ResponseEntity.ok(pemContent); + } else { + return ResponseEntity.badRequest().build(); + } + } } diff --git a/src/main/java/de/mlessmann/certassist/web/dto/PrivateKey.java b/src/main/java/de/mlessmann/certassist/web/dto/PrivateKey.java new file mode 100644 index 0000000..5ca46d5 --- /dev/null +++ b/src/main/java/de/mlessmann/certassist/web/dto/PrivateKey.java @@ -0,0 +1,11 @@ +package de.mlessmann.certassist.web.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "Represents the private key of a certificate.") +public record PrivateKey( + @JsonProperty + @Schema(description = "The content of the private key as it would be in a .pem file.") + String pemContent) { +}