/* ================================================================== * NodeCertificatesController.java - Dec 7, 2012 7:16:19 AM * * Copyright 2007-2012 SolarNetwork.net Dev Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * ================================================================== */ package net.solarnetwork.node.setup.web; import java.io.IOException; import java.io.InputStreamReader; import java.security.cert.X509Certificate; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.ui.Model; import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import net.solarnetwork.node.setup.PKIService; import net.solarnetwork.node.setup.web.support.ServiceAwareController; /** * Controller for node certificate management. * * @author matt * @version 1.1 */ @ServiceAwareController @RequestMapping("/a/certs") public class NodeCertificatesController extends BaseSetupController { @Autowired private PKIService pkiService; /** * View the main certs page. * * @param model * the view model * @return */ @RequestMapping public String home(Model model) { X509Certificate nodeCert = pkiService.getNodeCertificate(); final Date now = new Date(); final boolean expired = (nodeCert != null && now.after(nodeCert.getNotAfter())); final boolean valid = (nodeCert != null && (!nodeCert.getIssuerDN().equals(nodeCert.getSubjectDN()) && !now.before(nodeCert.getNotBefore()) && !expired)); model.addAttribute("nodeCert", nodeCert); if ( nodeCert != null ) { model.addAttribute("nodeCertSerialNumber", "0x" + nodeCert.getSerialNumber().toString(16)); } model.addAttribute("nodeCertExpired", expired); model.addAttribute("nodeCertValid", valid); return "certs/home"; } /** * Return a node's CSR based on its current certificate. * * @return a map with the PEM encoded certificate on key {@code csr} */ @RequestMapping(value = "/nodeCSR", method = RequestMethod.GET) @ResponseBody public Map<String, Object> nodeCSR() { String csr = pkiService.generateNodePKCS10CertificateRequestString(); Map<String, Object> result = new HashMap<String, Object>(1); result.put("csr", csr); return result; } /** * Return a node's current certificate. * * @return a map with the PEM encoded certificate on key {@code cert} if * {@code download} is not <em>true</em>, otherwise the content is * returned as a file attachment */ @RequestMapping(value = "/nodeCert", method = RequestMethod.GET) @ResponseBody public Object viewNodeCert( @RequestParam(value = "download", required = false) final Boolean download, @RequestParam(value = "chain", required = false) final Boolean asChain) { final String cert = (Boolean.TRUE.equals(asChain) ? pkiService.generateNodePKCS7CertificateChainString() : pkiService.generateNodePKCS7CertificateString()); if ( !Boolean.TRUE.equals(download) ) { Map<String, Object> result = new HashMap<String, Object>(1); result.put("cert", cert); return result; } HttpHeaders headers = new HttpHeaders(); headers.setContentLength(cert.length()); headers.setContentType(MediaType.parseMediaType("application/x-pem-file")); headers.setLastModified(System.currentTimeMillis()); headers.setCacheControl("no-cache"); headers.set("Content-Disposition", "attachment; filename=solarnode-" + getIdentityService().getNodeId() + ".pem"); return new ResponseEntity<String>(cert, headers, HttpStatus.OK); } /** * Import a certificate reply (signed certificate chain). * * @param file * the CSR file to import * @return the destination view * @throws IOException * if an IO error occurs */ @RequestMapping(value = "/import", method = RequestMethod.POST) public String importSettings(@RequestParam(value = "file", required = false) MultipartFile file, @RequestParam(value = "text", required = false) String text) throws IOException { String pem = text; if ( file != null && !file.isEmpty() ) { pem = FileCopyUtils.copyToString(new InputStreamReader(file.getInputStream(), "UTF-8")); } pkiService.saveNodeSignedCertificate(pem); return "redirect:/a/certs"; } @RequestMapping(value = "/renew", method = RequestMethod.POST) @ResponseBody public Object renewCertificate(@RequestParam("password") String password) { Map<String, Object> result = new HashMap<String, Object>(1); boolean success = false; try { getSetupBiz().renewNetworkCertificate(password); success = true; } catch ( RuntimeException e ) { result.put("message", e.getMessage()); } result.put("success", success); return result; } }