<%@ page errorPage="error.jsp"%> <%@ page import="org.jivesoftware.openfire.keystore.CertificateStore"%> <%@ page import="org.jivesoftware.openfire.keystore.CertificateStoreManager"%> <%@ page import="org.jivesoftware.openfire.spi.ConnectionType"%> <%@ page import="org.jivesoftware.util.ParamUtils"%> <%@ page import="javax.xml.bind.DatatypeConverter" %> <%@ page import="java.security.AlgorithmParameters" %> <%@ page import="java.security.cert.X509Certificate" %> <%@ page import="java.util.HashMap" %> <%@ page import="java.util.Map" %> <%@ page import="org.jivesoftware.openfire.XMPPServer" %> <%@ taglib uri="admin" prefix="admin" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager" /> <jsp:useBean id="now" class="java.util.Date"/> <% webManager.init(request, response, session, application, out ); final String alias = ParamUtils.getParameter( request, "alias" ); final String storePurposeText = ParamUtils.getParameter( request, "connectionType" ); final boolean isTrustStore = ParamUtils.getBooleanParameter( request, "isTrustStore" ); final Map<String, String> errors = new HashMap<String, String>(); ConnectionType connectionType; try { connectionType = ConnectionType.valueOf( storePurposeText ); } catch (RuntimeException ex) { errors.put( "connectionType", ex.getMessage() ); connectionType = null; } pageContext.setAttribute( "connectionType", connectionType ); if (alias == null) { errors.put("alias", "The alias has not been specified."); } else { try { final CertificateStoreManager certificateStoreManager = XMPPServer.getInstance().getCertificateStoreManager(); final CertificateStore store; if (isTrustStore) { store = certificateStoreManager.getTrustStore( connectionType ); } else { store = certificateStoreManager.getIdentityStore( connectionType ); } // Get the certificate final X509Certificate certificate = (X509Certificate) store.getStore().getCertificate( alias ); if ( certificate == null ) { errors.put( "alias", "alias" ); } else { pageContext.setAttribute( "certificate", certificate ); } } catch ( Exception e ) { e.printStackTrace(); errors.put( "type", e.getMessage() ); } } // Handle a "go back" click: if ( request.getParameter( "back" ) != null ) { if ( isTrustStore ) { response.sendRedirect( "security-truststore.jsp?connectionType=" + connectionType ); } else { response.sendRedirect( "security-keystore.jsp?connectionType=" + connectionType ); } return; } pageContext.setAttribute( "errors", errors ); %> <html> <head> <title><fmt:message key="ssl.certificate.details.title"/></title> <meta name="pageID" content="security-certificate-store-management"/> <c:choose> <c:when test="${isTrustStore}"> <meta name="subPageID" content="sidebar-certificate-store-${fn:toLowerCase(connectionType)}-trust-store"/> </c:when> <c:otherwise> <meta name="subPageID" content="sidebar-certificate-store-${fn:toLowerCase(connectionType)}-identity-store"/> </c:otherwise> </c:choose> </head> <body> <c:forEach var="err" items="${errors}"> <admin:infobox type="error"> <c:choose> <c:when test="${err.key eq 'type'}"> <fmt:message key="ssl.certificate.details.type-error"/> </c:when> <c:when test="${err.key eq 'alias'}"> <fmt:message key="ssl.certificate.details.alias-error"/> </c:when> <c:otherwise> <c:if test="${not empty err.value}"> <fmt:message key="admin.error"/>: <c:out value="${err.value}"/> </c:if> (<c:out value="${err.key}"/>) </c:otherwise> </c:choose> </admin:infobox> </c:forEach> <c:if test="${empty errors}"> <p> <fmt:message key="ssl.certificate.details.intro"> <fmt:param value="${param.alias}"/> <fmt:param> <c:choose> <c:when test="${param.type eq 'c2s'}"><fmt:message key="ssl.certificates.truststore.c2s-title"/></c:when> <c:when test="${param.type eq 's2s'}"><fmt:message key="ssl.certificates.truststore.s2s-title"/></c:when> <c:when test="${param.type eq 'server'}"><fmt:message key="ssl.certificates.keystore.title"/></c:when> </c:choose> </fmt:param> </fmt:message> </p> <div class="jive-table"> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <thead> <tr> <th colspan="2"> <fmt:message key="ssl.certificate.details.title"/> </th> </tr> </thead> <tbody> <tr> <td class="c1"><fmt:message key="ssl.certificates.version"/></td> <td><c:out value="${certificate.version}"/></td> </tr> <tr> <td class="c1"><fmt:message key="ssl.certificates.serialnumber"/></td> <td><c:out value="${certificate.serialNumber}"/></td> </tr> </tbody> </table> </div> <br/> <div class="jive-table"> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <thead> <tr> <th colspan="2"> <fmt:message key="ssl.certificates.subject"/> </th> </tr> </thead> <tbody> <c:forEach var="namePart" items="${admin:split(certificate.subjectX500Principal.name, '(?<!\\\\\\\\),')}"> <c:set var="keyValue" value="${fn:split(namePart, '=')}"/> <tr> <td class="c1"> <c:choose> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'C'}"><fmt:message key="ssl.certificates.c"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'ST'}"><fmt:message key="ssl.certificates.st"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'L'}"><fmt:message key="ssl.certificates.l"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'O'}"><fmt:message key="ssl.certificates.o"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'OU'}"><fmt:message key="ssl.certificates.ou"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'CN'}"><fmt:message key="ssl.certificates.cn"/></c:when> <c:otherwise><c:out value="${keyValue[0]}"/></c:otherwise> </c:choose> </td> <td> <c:out value="${admin:replaceAll(keyValue[1], '\\\\\\\\(.)', '$1')}"/> </td> </tr> </c:forEach> </tbody> </table> </div> <c:forEach var="alternativeName" items="${certificate.subjectAlternativeNames}"> <br/> <div class="jive-table"> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <thead> <tr> <th colspan="2"> <fmt:message key="ssl.certificates.subject"/> <fmt:message key="ssl.certificates.alternative-name"/> <c:choose> <c:when test="${alternativeName[0] eq 0}">(Other Name)</c:when> <c:when test="${alternativeName[0] eq 1}">(RFC-822 Name)</c:when> <c:when test="${alternativeName[0] eq 2}">(DNS Name)</c:when> <c:when test="${alternativeName[0] eq 3}">(X400 Address)</c:when> <c:when test="${alternativeName[0] eq 4}">(Directory Name)</c:when> <c:when test="${alternativeName[0] eq 5}">(EDI Party Name)</c:when> <c:when test="${alternativeName[0] eq 6}">(Uniform Resource Identifier)</c:when> <c:when test="${alternativeName[0] eq 7}">(IP Address)</c:when> <c:when test="${alternativeName[0] eq 8}">(Registered ID)</c:when> </c:choose> </th> </tr> </thead> <tbody> <c:choose> <c:when test="${alternativeName[0] eq 4}"> <c:forEach var="namePart" items="${admin:split(alternativeName[1], '(?<!\\\\\\\\),')}"> <c:set var="keyValue" value="${fn:split(namePart, '=')}"/> <tr> <td class="c1"> <c:choose> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'C'}"><fmt:message key="ssl.certificates.c"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'ST'}"><fmt:message key="ssl.certificates.st"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'L'}"><fmt:message key="ssl.certificates.l"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'O'}"><fmt:message key="ssl.certificates.o"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'OU'}"><fmt:message key="ssl.certificates.ou"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'CN'}"><fmt:message key="ssl.certificates.cn"/></c:when> <c:otherwise><c:out value="${keyValue[0]}"/></c:otherwise> </c:choose> </td> <td> <c:out value="${admin:replaceAll(keyValue[1], '\\\\\\\\(.)', '$1')}"/> </td> </tr> </c:forEach> </c:when> <c:when test="${alternativeName[0] eq 1 or alternativeName[0] eq 2 or alternativeName[0] eq 6 or alternativeName[0] eq 7 or alternativeName[0] eq 8}"> <tr><td><c:out value="${alternativeName[1]}"/></td></tr> </c:when> <c:otherwise> <tr><td><admin:ASN1DER value="${alternativeName[1]}"/> </td></tr> </c:otherwise> </c:choose> </tbody> </table> </div> </c:forEach> <br/> <div class="jive-table"> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <thead> <tr> <th colspan="2"> <fmt:message key="ssl.certificates.validity"/> </th> </tr> </thead> <tbody> <tr> <td class="c1"><fmt:message key="ssl.certificates.not-valid-before"/></td> <td> <c:choose> <c:when test="${certificate.notBefore gt now}"> <span style="color: red;"> <fmt:formatDate type="DATE" dateStyle="MEDIUM" value="${certificate.notBefore}"/> </span> </c:when> <c:otherwise> <span> <fmt:formatDate type="DATE" dateStyle="MEDIUM" value="${certificate.notBefore}"/> </span> </c:otherwise> </c:choose> </td> </tr> <tr> <td class="c1"><fmt:message key="ssl.certificates.not-valid-after"/></td> <td> <c:choose> <c:when test="${certificate.notAfter lt now}"> <span style="color: red;"> <fmt:formatDate type="DATE" dateStyle="MEDIUM" value="${certificate.notAfter}"/> </span> </c:when> <c:otherwise> <span> <fmt:formatDate type="DATE" dateStyle="MEDIUM" value="${certificate.notAfter}"/> </span> </c:otherwise> </c:choose> </td> </tr> </tbody> </table> </div> <br/> <div class="jive-table"> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <thead> <tr> <th colspan="2"> <fmt:message key="ssl.certificates.issuer"/> </th> </tr> </thead> <tbody> <c:forEach var="namePart" items="${admin:split(certificate.issuerX500Principal.name, '(?<!\\\\\\\\),')}"> <c:set var="keyValue" value="${fn:split(namePart, '=')}"/> <tr> <td class="c1"> <c:choose> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'C'}"><fmt:message key="ssl.certificates.c"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'ST'}"><fmt:message key="ssl.certificates.st"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'L'}"><fmt:message key="ssl.certificates.l"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'O'}"><fmt:message key="ssl.certificates.o"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'OU'}"><fmt:message key="ssl.certificates.ou"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'CN'}"><fmt:message key="ssl.certificates.cn"/></c:when> <c:otherwise><c:out value="${keyValue[0]}"/></c:otherwise> </c:choose> </td> <td> <c:out value="${admin:replaceAll(keyValue[1], '\\\\\\\\(.)', '$1')}"/> </td> </tr> </c:forEach> </tbody> </table> </div> <c:forEach var="alternativeName" items="${certificate.issuerAlternativeNames}"> <br/> <div class="jive-table"> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <thead> <tr> <th colspan="2"> <fmt:message key="ssl.certificates.issuer"/> <fmt:message key="ssl.certificates.alternative-name"/> <c:choose> <c:when test="${alternativeName[0] eq 0}">(Other Name)</c:when> <c:when test="${alternativeName[0] eq 1}">(RFC-822 Name)</c:when> <c:when test="${alternativeName[0] eq 2}">(DNS Name)</c:when> <c:when test="${alternativeName[0] eq 3}">(X400 Address)</c:when> <c:when test="${alternativeName[0] eq 4}">(Directory Name)</c:when> <c:when test="${alternativeName[0] eq 5}">(EDI Party Name)</c:when> <c:when test="${alternativeName[0] eq 6}">(Uniform Resource Identifier)</c:when> <c:when test="${alternativeName[0] eq 7}">(IP Address)</c:when> <c:when test="${alternativeName[0] eq 8}">(Registered ID)</c:when> </c:choose> </th> </tr> </thead> <tbody> <c:choose> <c:when test="${alternativeName[0] eq 4}"> <c:forEach var="namePart" items="${admin:split(alternativeName[1], '(?<!\\\\\\\\),')}"> <c:set var="keyValue" value="${fn:split(namePart, '=')}"/> <tr> <td class="c1"> <c:choose> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'C'}"><fmt:message key="ssl.certificates.c"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'ST'}"><fmt:message key="ssl.certificates.st"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'L'}"><fmt:message key="ssl.certificates.l"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'O'}"><fmt:message key="ssl.certificates.o"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'OU'}"><fmt:message key="ssl.certificates.ou"/></c:when> <c:when test="${fn:toUpperCase(keyValue[0]) eq 'CN'}"><fmt:message key="ssl.certificates.cn"/></c:when> <c:otherwise><c:out value="${keyValue[0]}"/></c:otherwise> </c:choose> </td> <td> <c:out value="${admin:replaceAll(keyValue[1], '\\\\\\\\(.)', '$1')}"/> </td> </tr> </c:forEach> </c:when> <c:when test="${alternativeName[0] eq 1 or alternativeName[0] eq 2 or alternativeName[0] eq 6 or alternativeName[0] eq 7 or alternativeName[0] eq 8}"> <tr><td><c:out value="${alternativeName[1]}"/></td></tr> </c:when> <c:otherwise> <tr><td><admin:ASN1DER value="${alternativeName[1]}"/> </td></tr> </c:otherwise> </c:choose> </tbody> </table> </div> </c:forEach> <br/> <div class="jive-table"> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <thead> <tr> <th colspan="2"> <fmt:message key="ssl.certificates.signature"/> </th> </tr> </thead> <tbody> <tr> <td class="c1"> <fmt:message key="ssl.certificates.signature-algorithm"/> </td> <td><c:out value="${certificate.sigAlgName}"/></td> </tr> <c:if test="${not empty certificate.sigAlgParams}"> <% final X509Certificate certificate = (X509Certificate) pageContext.getAttribute("certificate"); final AlgorithmParameters sigParams = AlgorithmParameters.getInstance(certificate.getSigAlgName()); sigParams.init( certificate.getSigAlgParams() ); %> <tr> <td class="c1"><fmt:message key="ssl.certificates.signature-algorithm-parameters"/></td> <td><%= sigParams.toString() %></td> </tr> </c:if> <tr valign="top"> <% final X509Certificate certificate = (X509Certificate) pageContext.getAttribute("certificate"); final String hex = DatatypeConverter.printHexBinary( certificate.getSignature()); final StringBuilder sb = new StringBuilder(); for (int i=0; i<hex.length(); i++) { if (i != 0 && i != hex.length() - 1) { if (i % 2 == 0) { sb.append(':'); } if (i % 40 == 0) { sb.append("<br/>"); } } sb.append(hex.charAt(i)); } %> <td class="c1"><fmt:message key="ssl.certificates.signature"/></td> <td style="font-family: monospace;"><%=sb.toString()%></td> </tr> </tbody> </table> </div> <br/> <form action="security-certificate-details.jsp"> <input type="hidden" name="connectionType" value="${connectionType}"/> <input type="hidden" name="isTrustStore" value="${param.isTrustStore}"/> <div style="text-align: center;"> <input type="submit" name="back" value="<fmt:message key="session.details.back_button"/>"> </div> </form> </c:if> </body> </html>