// --- BEGIN COPYRIGHT BLOCK --- // 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; version 2 of the License. // // 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., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.connector; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Enumeration; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import netscape.security.x509.CRLExtensions; import netscape.security.x509.CRLReasonExtension; import netscape.security.x509.CertificateAlgorithmId; import netscape.security.x509.CertificateExtensions; import netscape.security.x509.CertificateSubjectName; import netscape.security.x509.CertificateValidity; import netscape.security.x509.CertificateX509Key; import netscape.security.x509.Extension; import netscape.security.x509.RevocationReason; import netscape.security.x509.RevokedCertImpl; import netscape.security.x509.X509CertImpl; import netscape.security.x509.X509CertInfo; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.authentication.AuthToken; import com.netscape.certsrv.authentication.EInvalidCredentials; import com.netscape.certsrv.authentication.IAuthSubsystem; import com.netscape.certsrv.authentication.IAuthToken; import com.netscape.certsrv.authority.IAuthority; import com.netscape.certsrv.authorization.AuthzToken; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.SessionContext; import com.netscape.certsrv.connector.IPKIMessage; import com.netscape.certsrv.connector.IRequestEncoder; import com.netscape.certsrv.logging.AuditFormat; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.profile.EProfileException; import com.netscape.certsrv.profile.IEnrollProfile; import com.netscape.certsrv.profile.IProfileSubsystem; import com.netscape.certsrv.request.IRequest; import com.netscape.certsrv.request.IRequestQueue; import com.netscape.certsrv.request.RequestId; import com.netscape.certsrv.request.RequestStatus; import com.netscape.cms.servlet.base.CMSServlet; import com.netscape.cms.servlet.common.CMSRequest; import com.netscape.cmsutil.util.Utils; /** * Connector servlet * process requests from remote authority - * service request or return status. * * @version $Revision$, $Date$ */ public class ConnectorServlet extends CMSServlet { /** * */ private static final long serialVersionUID = 1221916495803185863L; public static final String INFO = "Connector Servlet"; public final static String PROP_AUTHORITY = "authority"; protected ServletConfig mConfig = null; protected IAuthority mAuthority = null; protected IRequestEncoder mReqEncoder = null; protected IAuthSubsystem mAuthSubsystem = null; protected ILogger mLogger = CMS.getLogger(); protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger(); private final static String SIGNED_AUDIT_PROTECTION_METHOD_SSL = "ssl"; private final static String LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS = "LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS_5"; private final static String LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST = "LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST_5"; private final static String LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED = "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5"; private final static byte EOL[] = { Character.LINE_SEPARATOR }; public ConnectorServlet() { } public void init(ServletConfig sc) throws ServletException { super.init(sc); mConfig = sc; String authority = sc.getInitParameter(PROP_AUTHORITY); if (authority != null) mAuthority = (IAuthority) CMS.getSubsystem(authority); mReqEncoder = CMS.getHttpRequestEncoder(); mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH); } public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean running_state = CMS.isInRunningState(); if (!running_state) throw new IOException( "CMS server is not ready to serve."); HttpServletRequest req = request; HttpServletResponse resp = response; CMSRequest cmsRequest = newCMSRequest(); // set argblock cmsRequest.setHttpParams(CMS.createArgBlock(toHashtable(request))); // set http request cmsRequest.setHttpReq(request); // set http response cmsRequest.setHttpResp(response); // set servlet config. cmsRequest.setServletConfig(mConfig); // set servlet context. cmsRequest.setServletContext(mConfig.getServletContext()); char[] content = null; String encodedreq = null; String method = null; int len = -1; IPKIMessage msg = null; IPKIMessage replymsg = null; // NOTE must read all bufer before redoing handshake for // ssl client auth for client auth to work. // get request method method = req.getMethod(); // get content length len = request.getContentLength(); // get content, a base 64 encoded serialized request. if (len > 0) { InputStream in = request.getInputStream(); InputStreamReader inreader = new InputStreamReader(in, "UTF8"); BufferedReader reader = new BufferedReader(inreader, len); content = new char[len]; int done = reader.read(content, 0, len); int total = done; while (done >= 0 && total < len) { done = reader.read(content, total, len - total); total += done; } reader.close(); encodedreq = new String(content); } // force client auth handshake, validate RA and get RA's Id. // NOTE must do this after all contents are read for ssl // redohandshake to work X509Certificate peerCert; try { peerCert = getPeerCert(req); } catch (EBaseException e) { mAuthority.log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSGW_HAS_NO_CLIENT_CERT")); resp.sendError(HttpServletResponse.SC_UNAUTHORIZED); return; } if (peerCert == null) { // XXX log something here. resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } // authenticate RA String RA_Id = null; String raUserId = null; IAuthToken token = null; try { token = authenticate(request); raUserId = token.getInString("userid"); RA_Id = peerCert.getSubjectDN().toString(); } catch (EInvalidCredentials e) { // already logged. resp.sendError(HttpServletResponse.SC_UNAUTHORIZED); return; } catch (EBaseException e) { // already logged. resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } mAuthority.log(ILogger.LL_INFO, "Remote Authority authenticated: " + peerCert.getSubjectDN()); // authorize AuthzToken authzToken = null; try { authzToken = authorize(mAclMethod, token, mAuthzResourceName, "submit"); } catch (Exception e) { // do nothing for now } if (authzToken == null) { cmsRequest.setStatus(CMSRequest.UNAUTHORIZED); return; } // after cert validated, check http request. if (!method.equalsIgnoreCase("POST")) { resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); return; } if (len <= 0) { resp.sendError(HttpServletResponse.SC_LENGTH_REQUIRED); return; } // now process request. CMS.debug("ConnectorServlet: process request RA_Id=" + RA_Id); try { // decode request. msg = (IPKIMessage) mReqEncoder.decode(encodedreq); // process request replymsg = processRequest(RA_Id, raUserId, msg, token); } catch (IOException e) { CMS.debug("ConnectorServlet: service " + e.toString()); CMS.debug(e); mAuthority.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString())); resp.sendError(HttpServletResponse.SC_BAD_REQUEST); return; } catch (EBaseException e) { CMS.debug("ConnectorServlet: service " + e.toString()); CMS.debug(e); mAuthority.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString())); resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } catch (Exception e) { CMS.debug("ConnectorServlet: service " + e.toString()); CMS.debug(e); } CMS.debug("ConnectorServlet: done processRequest"); // encode reply try { String encodedrep = mReqEncoder.encode(replymsg); resp.setStatus(HttpServletResponse.SC_OK); resp.setContentType("text/html"); resp.setContentLength(encodedrep.length()); // send reply OutputStream out = response.getOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(out, "UTF8"); writer.write(encodedrep); writer.flush(); writer.close(); out.flush(); } catch (Exception e) { CMS.debug("ConnectorServlet: error writing e=" + e.toString()); } CMS.debug("ConnectorServlet: send response RA_Id=" + RA_Id); } public static boolean isProfileRequest(IRequest request) { String profileId = request.getExtDataInString("profileId"); if (profileId == null || profileId.equals("")) return false; else return true; } public void normalizeProfileRequest(IRequest request) { // if it is profile request, we need to normalize the // x509certinfo from ra into request X509CertInfo info = null; ByteArrayOutputStream byteStream; try { info = request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO); // request.set(IEnrollProfile.REQUEST_SEQ_NUM, new Integer("0")); CertificateX509Key certKey = (CertificateX509Key) info.get(X509CertInfo.KEY); if (certKey != null) { byteStream = new ByteArrayOutputStream(); certKey.encode(byteStream); request.setExtData(IEnrollProfile.REQUEST_KEY, byteStream.toByteArray()); } CertificateSubjectName certSubject = (CertificateSubjectName) info.get(X509CertInfo.SUBJECT); if (certSubject != null) { request.setExtData(IEnrollProfile.REQUEST_SUBJECT_NAME, certSubject); } CertificateValidity certValidity = (CertificateValidity) info.get(X509CertInfo.VALIDITY); if (certValidity != null) { byteStream = new ByteArrayOutputStream(); certValidity.encode(byteStream); request.setExtData(IEnrollProfile.REQUEST_VALIDITY, byteStream.toByteArray()); } CertificateExtensions extensions = (CertificateExtensions) info.get(X509CertInfo.EXTENSIONS); if (extensions != null) { request.setExtData(IEnrollProfile.REQUEST_EXTENSIONS, extensions); } CertificateAlgorithmId certAlg = (CertificateAlgorithmId) info.get(X509CertInfo.ALGORITHM_ID); if (certAlg != null) { ByteArrayOutputStream certAlgOut = new ByteArrayOutputStream(); certAlg.encode(certAlgOut); request.setExtData(IEnrollProfile.REQUEST_SIGNING_ALGORITHM, certAlgOut.toByteArray()); } } catch (Exception e) { CMS.debug("ConnectorServlet: profile normalization " + e.toString()); } String profileId = request.getExtDataInString("profileId"); IProfileSubsystem ps = (IProfileSubsystem) CMS.getSubsystem("profile"); IEnrollProfile profile = null; // profile subsystem may not be available. In case of KRA for // example if (ps == null) { CMS.debug("ConnectorServlet: Profile Subsystem not found "); return; } try { profile = (IEnrollProfile) (ps.getProfile(profileId)); profile.setDefaultCertInfo(request); } catch (EProfileException e) { CMS.debug("ConnectorServlet: normalizeProfileRequest Exception: " + e.toString()); } if (profile == null) { CMS.debug("ConnectorServlet: Profile not found " + profileId); return; } } /** * Process request *

* * (Certificate Request - all "agent" profile cert requests made through a connector) *

* * (Certificate Request Processed - all automated "agent" profile based cert acceptance made through a connector) *

* *

* * @param source string containing source * @param sourceUserId string containing source user ID * @param msg PKI message * @param token the authentication token * @exception EBaseException an error has occurred * @return PKI message */ protected IPKIMessage processRequest( String source, String sourceUserId, IPKIMessage msg, IAuthToken token) throws EBaseException { String auditMessage = null; String auditSubjectID = sourceUserId; String auditProtectionMethod = SIGNED_AUDIT_PROTECTION_METHOD_SSL; String auditRequestType = msg.getReqType(); String auditRequesterID = msg.getReqId(); // additional parms for LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST String auditCertificateSubjectName = ILogger.SIGNED_AUDIT_EMPTY_VALUE; String subject = null; // additional parms for LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED String auditInfoCertValue = ILogger.SIGNED_AUDIT_EMPTY_VALUE; // "normalize" the "auditSubjectID" if (auditSubjectID != null) { auditSubjectID = auditSubjectID.trim(); } else { auditSubjectID = ILogger.UNIDENTIFIED; } // "normalize" the "auditRequestType" if (auditRequestType != null) { auditRequestType = auditRequestType.trim(); } else { auditRequestType = ILogger.SIGNED_AUDIT_EMPTY_VALUE; } // "normalize" the "auditRequesterID" if (auditRequesterID != null) { auditRequesterID = auditRequesterID.trim(); } else { auditRequesterID = ILogger.UNIDENTIFIED; } IPKIMessage replymsg = null; try { IRequestQueue queue = mAuthority.getRequestQueue(); String srcid = source + ":" + msg.getReqId(); // find request in request queue and return result. RequestId thisreqid = queue.findRequestBySourceId(srcid); IRequest thisreq = null; if (thisreqid != null) { thisreq = queue.findRequest(thisreqid); if (thisreq == null) { // strange case. String errormsg = "Cannot find request in request queue " + thisreqid; mAuthority.log(ILogger.LL_FAILURE, CMS.getLogMessage( "CMSGW_REQUEST_ID_NOT_FOUND_1", thisreqid.toString())); // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS, auditSubjectID, ILogger.FAILURE, auditProtectionMethod, auditRequestType, auditRequesterID); audit(auditMessage); // NOTE: The signed audit event // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST // does not yet matter at this point! throw new EBaseException(errormsg); } else { mAuthority.log(ILogger.LL_INFO, "Found request " + thisreqid + " for " + srcid); replymsg = CMS.getHttpPKIMessage(); replymsg.fromRequest(thisreq); // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS, auditSubjectID, ILogger.SUCCESS, auditProtectionMethod, auditRequestType, auditRequesterID); audit(auditMessage); // NOTE: The signed audit event // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST // does not yet matter at this point! return replymsg; } } // if not found process request. thisreq = queue.newRequest(msg.getReqType()); CMS.debug("ConnectorServlet: created requestId=" + thisreq.getRequestId().toString()); thisreq.setSourceId(srcid); // NOTE: For the following signed audit message, since we only // care about the "msg.toRequest( thisreq );" command, and // since this command does not throw an EBaseException // (which is the only exception designated by this method), // then this code does NOT need to be contained within its // own special try/catch block. msg.toRequest(thisreq); if (isProfileRequest(thisreq)) { X509CertInfo info = thisreq.getExtDataInCertInfo( IEnrollProfile.REQUEST_CERTINFO); try { CertificateSubjectName sn = (CertificateSubjectName) info.get(X509CertInfo.SUBJECT); // if the cert subject name is NOT MISSING, retrieve the // actual "auditCertificateSubjectName" and "normalize" // it if (sn != null) { subject = sn.toString(); if (subject != null) { // NOTE: This is ok even if the cert subject // name is "" (empty)! auditCertificateSubjectName = subject.trim(); } } // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST, auditSubjectID, ILogger.SUCCESS, auditRequesterID, auditProfileID(), auditCertificateSubjectName); audit(auditMessage); } catch (CertificateException e) { CMS.debug("ConnectorServlet: processRequest " + e.toString()); // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST, auditSubjectID, ILogger.FAILURE, auditRequesterID, auditProfileID(), auditCertificateSubjectName); audit(auditMessage); } catch (IOException e) { CMS.debug("ConnectorServlet: processRequest " + e.toString()); // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST, auditSubjectID, ILogger.FAILURE, auditRequesterID, auditProfileID(), auditCertificateSubjectName); audit(auditMessage); } } thisreq.setExtData(IRequest.AUTH_TOKEN, token); // setting requestor type must come after copy contents. because // requestor is a regular attribute. thisreq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_RA); mAuthority.log(ILogger.LL_INFO, "Processing remote request " + srcid); // Set this so that request's updateBy is recorded SessionContext s = SessionContext.getContext(); if (s.get(SessionContext.USER_ID) == null) { s.put(SessionContext.USER_ID, sourceUserId); } if (s.get(SessionContext.REQUESTER_ID) == null) { s.put(SessionContext.REQUESTER_ID, msg.getReqId()); } CMS.debug("ConnectorServlet: calling processRequest instance=" + thisreq); if (isProfileRequest(thisreq)) { normalizeProfileRequest(thisreq); } try { queue.processRequest(thisreq); if (isProfileRequest(thisreq)) { // reset the "auditInfoCertValue" auditInfoCertValue = auditInfoCertValue(thisreq); if (auditInfoCertValue != null) { if (!(auditInfoCertValue.equals( ILogger.SIGNED_AUDIT_EMPTY_VALUE))) { // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED, auditSubjectID, ILogger.SUCCESS, auditRequesterID, ILogger.SIGNED_AUDIT_ACCEPTANCE, auditInfoCertValue); audit(auditMessage); } } } } catch (EBaseException eAudit1) { if (isProfileRequest(thisreq)) { // reset the "auditInfoCertValue" auditInfoCertValue = auditInfoCertValue(thisreq); if (auditInfoCertValue != null) { if (!(auditInfoCertValue.equals( ILogger.SIGNED_AUDIT_EMPTY_VALUE))) { // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED, auditSubjectID, ILogger.FAILURE, auditRequesterID, ILogger.SIGNED_AUDIT_ACCEPTANCE, auditInfoCertValue); audit(auditMessage); } } } // rethrow EBaseException to primary catch clause // within this method throw eAudit1; } replymsg = CMS.getHttpPKIMessage(); replymsg.fromRequest(thisreq); CMS.debug("ConnectorServlet: replymsg.reqStatus=" + replymsg.getReqStatus()); //for audit log String agentID = sourceUserId; String initiative = AuditFormat.FROMRA + " trustedManagerID: " + agentID + " remote reqID " + msg.getReqId(); String authMgr = AuditFormat.NOAUTH; if (token != null) { authMgr = token.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME); } if (isProfileRequest(thisreq)) { // XXX audit log CMS.debug("ConnectorServlet: done requestId=" + thisreq.getRequestId().toString()); // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS, auditSubjectID, ILogger.SUCCESS, auditProtectionMethod, auditRequestType, auditRequesterID); audit(auditMessage); // NOTE: The signed audit event // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST // has already been logged at this point! return replymsg; } // Get the certificate info from the request X509CertInfo x509Info[] = thisreq.getExtDataInCertInfoArray(IRequest.CERT_INFO); try { if (!thisreq.getRequestStatus().equals(RequestStatus.COMPLETE)) { if (x509Info != null) { for (int i = 0; i < x509Info.length; i++) { mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.FORMAT, new Object[] { thisreq.getRequestType(), thisreq.getRequestId(), initiative, authMgr, thisreq.getRequestStatus(), x509Info[i].get(X509CertInfo.SUBJECT), "" } ); } } else { mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.NODNFORMAT, new Object[] { thisreq.getRequestType(), thisreq.getRequestId(), initiative, authMgr, thisreq.getRequestStatus() } ); } } else { if (thisreq.getRequestType().equals(IRequest.ENROLLMENT_REQUEST)) { // XXX make the repeat record. // Get the certificate(s) from the request X509CertImpl x509Certs[] = null; if (x509Info != null) x509Certs = thisreq.getExtDataInCertArray(IRequest.ISSUED_CERTS); // return potentially more than one certificates. if (x509Certs != null) { for (int i = 0; i < x509Certs.length; i++) { mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.FORMAT, new Object[] { thisreq.getRequestType(), thisreq.getRequestId(), initiative, authMgr, "completed", x509Certs[i].getSubjectDN(), "cert issued serial number: 0x" + x509Certs[i].getSerialNumber().toString(16) } ); } } else { mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.NODNFORMAT, new Object[] { thisreq.getRequestType(), thisreq.getRequestId(), initiative, authMgr, "completed" } ); } } else if (thisreq.getRequestType().equals(IRequest.RENEWAL_REQUEST)) { X509CertImpl[] certs = thisreq.getExtDataInCertArray(IRequest.OLD_CERTS); X509CertImpl old_cert = certs[0]; certs = thisreq.getExtDataInCertArray(IRequest.ISSUED_CERTS); X509CertImpl renewed_cert = certs[0]; if (old_cert != null && renewed_cert != null) { mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.RENEWALFORMAT, new Object[] { thisreq.getRequestId(), initiative, authMgr, "completed", old_cert.getSubjectDN(), old_cert.getSerialNumber().toString(16), "new serial number: 0x" + renewed_cert.getSerialNumber().toString(16) } ); } else { mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.NODNFORMAT, new Object[] { thisreq.getRequestType(), thisreq.getRequestId(), initiative, authMgr, "completed with error" } ); } } else if (thisreq.getRequestType().equals(IRequest.REVOCATION_REQUEST)) { Certificate[] oldCerts = thisreq.getExtDataInCertArray(IRequest.OLD_CERTS); RevokedCertImpl crlentries[] = thisreq.getExtDataInRevokedCertArray(IRequest.REVOKED_CERTS); CRLExtensions crlExts = crlentries[0].getExtensions(); int reason = 0; if (crlExts != null) { Enumeration enum1 = crlExts.getElements(); while (enum1.hasMoreElements()) { Extension ext = enum1.nextElement(); if (ext instanceof CRLReasonExtension) { reason = ((CRLReasonExtension) ext).getReason().toInt(); break; } } } int count = oldCerts.length; Integer result = thisreq.getExtDataInInteger(IRequest.RESULT); if (result.equals(IRequest.RES_ERROR)) { String[] svcErrors = thisreq.getExtDataInStringArray(IRequest.SVCERRORS); if (svcErrors != null && svcErrors.length > 0) { for (int i = 0; i < svcErrors.length; i++) { String err = svcErrors[i]; if (err != null) { for (int j = 0; j < count; j++) { if (oldCerts[j] != null) { if (oldCerts[j] instanceof X509CertImpl) { X509CertImpl cert = (X509CertImpl) oldCerts[j]; mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.DOREVOKEFORMAT, new Object[] { thisreq.getRequestId(), initiative, "completed with error: " + err, cert.getSubjectDN(), cert.getSerialNumber().toString(16), RevocationReason.fromInt(reason).toString() } ); } } } } } } } else { // the success. for (int j = 0; j < count; j++) { if (oldCerts[j] != null) { if (oldCerts[j] instanceof X509CertImpl) { X509CertImpl cert = (X509CertImpl) oldCerts[j]; mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.DOREVOKEFORMAT, new Object[] { thisreq.getRequestId(), initiative, "completed", cert.getSubjectDN(), cert.getSerialNumber().toString(16), RevocationReason.fromInt(reason).toString() } ); } } } } } else { mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.NODNFORMAT, new Object[] { thisreq.getRequestType(), thisreq.getRequestId(), initiative, authMgr, "completed" } ); } } // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS, auditSubjectID, ILogger.SUCCESS, auditProtectionMethod, auditRequestType, auditRequesterID); audit(auditMessage); } catch (IOException e) { CMS.debug("ConnectorServlet: process " + e.toString()); // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS, auditSubjectID, ILogger.FAILURE, auditProtectionMethod, auditRequestType, auditRequesterID); audit(auditMessage); } catch (CertificateException e) { CMS.debug("ConnectorServlet: process " + e.toString()); // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS, auditSubjectID, ILogger.FAILURE, auditProtectionMethod, auditRequestType, auditRequesterID); audit(auditMessage); } catch (Exception e) { CMS.debug("ConnectorServlet: process " + e.toString()); // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS, auditSubjectID, ILogger.FAILURE, auditProtectionMethod, auditRequestType, auditRequesterID); audit(auditMessage); } finally { SessionContext.releaseContext(); } // NOTE: The signed audit event // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST // has already been logged at this point! return replymsg; } catch (EBaseException e) { // store a message in the signed audit log file auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS, auditSubjectID, ILogger.FAILURE, auditProtectionMethod, auditRequestType, auditRequesterID); audit(auditMessage); // NOTE: The signed audit event // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST // has either already been logged, or // does not yet matter at this point! return replymsg; } } protected X509Certificate getPeerCert(HttpServletRequest req) throws EBaseException { return getSSLClientCertificate(req); } public String getServletInfo() { return INFO; } /** * Signed Audit Log * * This method is inherited by all extended "CMSServlet"s, * and is called to store messages to the signed audit log. *

* * @param msg signed audit log message */ protected void audit(String msg) { // in this case, do NOT strip preceding/trailing whitespace // from passed-in String parameters if (mSignedAuditLogger == null) { return; } mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT, null, ILogger.S_SIGNED_AUDIT, ILogger.LL_SECURITY, msg); } /** * Signed Audit Log Profile ID * * This method is inherited by all extended "EnrollProfile"s, * and is called to obtain the "ProfileID" for * a signed audit log message. *

* * @return id string containing the signed audit log message ProfileID */ protected String auditProfileID() { // if no signed audit object exists, bail if (mSignedAuditLogger == null) { return null; } String profileID = getId(); if (profileID != null) { profileID = profileID.trim(); } else { profileID = ILogger.UNIDENTIFIED; } return profileID; } /** * Signed Audit Log Info Certificate Value * * This method is called to obtain the certificate from the passed in * "X509CertImpl" for a signed audit log message. *

* * @param request a Request containing an X509CertImpl * @return cert string containing the certificate */ private String auditInfoCertValue(IRequest request) { // if no signed audit object exists, bail if (mSignedAuditLogger == null) { return null; } X509CertImpl x509cert = request.getExtDataInCert( IEnrollProfile.REQUEST_ISSUED_CERT); if (x509cert == null) { return ILogger.SIGNED_AUDIT_EMPTY_VALUE; } byte rawData[] = null; try { rawData = x509cert.getEncoded(); } catch (CertificateEncodingException e) { return ILogger.SIGNED_AUDIT_EMPTY_VALUE; } String cert = null; // convert "rawData" into "base64Data" if (rawData != null) { String base64Data = null; base64Data = Utils.base64encode(rawData).trim(); StringBuffer sb = new StringBuffer(); // extract all line separators from the "base64Data" for (int i = 0; i < base64Data.length(); i++) { if (base64Data.substring(i, i).getBytes() != EOL) { sb.append(base64Data.substring(i, i)); } } cert = sb.toString(); } if (cert != null) { cert = cert.trim(); if (cert.equals("")) { return ILogger.SIGNED_AUDIT_EMPTY_VALUE; } else { return cert; } } else { return ILogger.SIGNED_AUDIT_EMPTY_VALUE; } } }