From 621d9e5c413e561293d7484b93882d985b3fe15f Mon Sep 17 00:00:00 2001 From: Endi Sukma Dewata Date: Sat, 24 Mar 2012 02:27:47 -0500 Subject: Removed unnecessary pki folder. Previously the source code was located inside a pki folder. This folder was created during svn migration and is no longer needed. This folder has now been removed and the contents have been moved up one level. Ticket #131 --- .../netscape/cms/servlet/request/CheckRequest.java | 621 +++++++++++++++++++++ 1 file changed, 621 insertions(+) create mode 100644 base/common/src/com/netscape/cms/servlet/request/CheckRequest.java (limited to 'base/common/src/com/netscape/cms/servlet/request/CheckRequest.java') diff --git a/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java b/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java new file mode 100644 index 000000000..b65c90fca --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java @@ -0,0 +1,621 @@ +// --- 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.request; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.Locale; +import java.util.StringTokenizer; +import java.math.BigInteger; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import netscape.security.pkcs.PKCS7; +import netscape.security.x509.AlgorithmId; +import netscape.security.x509.X500Name; +import netscape.security.x509.X509CertImpl; + +import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.asn1.ASN1Util; +import org.mozilla.jss.asn1.INTEGER; +import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; +import org.mozilla.jss.asn1.OCTET_STRING; +import org.mozilla.jss.asn1.SEQUENCE; +import org.mozilla.jss.asn1.SET; +import org.mozilla.jss.crypto.DigestAlgorithm; +import org.mozilla.jss.crypto.SignatureAlgorithm; +import org.mozilla.jss.pkix.cmc.CMCStatusInfo; +import org.mozilla.jss.pkix.cmc.PKIData; +import org.mozilla.jss.pkix.cmc.ResponseBody; +import org.mozilla.jss.pkix.cmc.TaggedAttribute; +import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo; +import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber; +import org.mozilla.jss.pkix.cms.SignedData; +import org.mozilla.jss.pkix.cms.SignerIdentifier; +import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; +import org.mozilla.jss.pkix.primitive.Name; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.IAuthToken; +import com.netscape.certsrv.authority.ICertAuthority; +import com.netscape.certsrv.authorization.AuthzToken; +import com.netscape.certsrv.authorization.EAuthzAccessDenied; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.ca.ICertificateAuthority; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.profile.IEnrollProfile; +import com.netscape.certsrv.ra.IRegistrationAuthority; +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.cms.servlet.common.CMSTemplate; +import com.netscape.cms.servlet.common.CMSTemplateParams; +import com.netscape.cms.servlet.common.ECMSGWException; + +/** + * Check the status of a certificate request + * + * @version $Revision$, $Date$ + */ +public class CheckRequest extends CMSServlet { + /** + * + */ + private static final long serialVersionUID = 2791195859767119636L; + // constants + public static String FULL_RESPONSE = "cmcFullEnrollmentResponse"; + private final static String INFO = "CheckRequest"; + private final static String REQ_ID = "requestId"; + private final static String REQ_TYPE = "requestType"; + private final static String STATUS = "status"; + private final static String CREATE_ON = "createdOn"; + private final static String UPDATE_ON = "updatedOn"; + private final static String UPDATE_BY = "updatedBy"; + + private final static String TPL_FILE = "requestStatus.template"; + + // variables + private IRequestQueue mQueue = null; + private String mFormPath = null; + private String mAuthorityId = null; + + public CMSRequest newCMSRequest() { + return new CMSRequest(); + } + + /** + * Constructs request query servlet. + */ + public CheckRequest() + throws EBaseException { + super(); + } + + /** + * initialize the servlet. This servlet uses the template file + * "requestStatus.template" to process the response. + * + * @param sc servlet configuration, read from the web.xml file + */ + public void init(ServletConfig sc) throws ServletException { + super.init(sc); + mQueue = mAuthority.getRequestQueue(); + mAuthorityId = mAuthority.getId(); + mFormPath = "/" + mAuthorityId + "/" + TPL_FILE; + + mTemplates.remove(CMSRequest.SUCCESS); + } + + /** + * Process the HTTP request. + * + * + * @param cmsReq the object holding the request and response information + */ + public void process(CMSRequest cmsReq) throws EBaseException { + CMS.debug("checkRequest: in process!"); + SET transIds = null, sNonces = null; + boolean isCMCReq = false; + INTEGER bodyPartId = null; + + HttpServletRequest req = cmsReq.getHttpReq(); + HttpServletResponse resp = cmsReq.getHttpResp(); + + IAuthToken authToken = authenticate(cmsReq); + + AuthzToken authzToken = null; + + try { + authzToken = authorize(mAclMethod, authToken, + mAuthzResourceName, "read"); + } catch (EAuthzAccessDenied e) { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString())); + } catch (Exception e) { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString())); + } + + if (authzToken == null) { + cmsReq.setStatus(CMSRequest.UNAUTHORIZED); + return; + } + + CMSTemplate form = null; + Locale[] locale = new Locale[1]; + + if (mOutputTemplatePath != null) + mFormPath = mOutputTemplatePath; + + try { + form = getTemplate(mFormPath, req, locale); + } catch (IOException e) { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString())); + throw new ECMSGWException( + CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")); + } + + IArgBlock header = CMS.createArgBlock(); + IArgBlock fixed = CMS.createArgBlock(); + CMSTemplateParams argSet = new CMSTemplateParams(header, fixed); + + // Note error is covered in the same template as success. + EBaseException error = null; + + String requestId = req.getParameter("requestId"); + String format = req.getParameter("format"); + + CMS.debug("checkRequest: requestId " + requestId); + + // They may check the status using CMC queryPending + String queryPending = req.getParameter("queryPending"); + + if (format != null && format.equals("cmc") && queryPending != null && !queryPending.equals("")) { + try { + isCMCReq = true; + byte[] cmcBlob = CMS.AtoB(queryPending); + ByteArrayInputStream cmcBlobIn = + new ByteArrayInputStream(cmcBlob); + + org.mozilla.jss.pkix.cms.ContentInfo cii = (org.mozilla.jss.pkix.cms.ContentInfo) + org.mozilla.jss.pkix.cms.ContentInfo.getTemplate().decode(cmcBlobIn); + SignedData cmcFullReq = (SignedData) + cii.getInterpretedContent(); + + EncapsulatedContentInfo ci = cmcFullReq.getContentInfo(); + + OBJECT_IDENTIFIER id = ci.getContentType(); + + if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIData) || !ci.hasContent()) { + throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_PKIDATA")); + } + OCTET_STRING content = ci.getContent(); + ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray()); + PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s); + + SEQUENCE controlSequence = pkiData.getControlSequence(); + int numControls = controlSequence.size(); + + for (int i = 0; i < numControls; i++) { + // decode message. + TaggedAttribute taggedAttr = (TaggedAttribute) controlSequence.elementAt(i); + OBJECT_IDENTIFIER type = taggedAttr.getType(); + + if (type.equals(OBJECT_IDENTIFIER.id_cmc_QueryPending)) { + bodyPartId = taggedAttr.getBodyPartID(); + SET requestIds = taggedAttr.getValues(); + int numReq = requestIds.size(); + + // We only process one for now. + if (numReq > 0) { + OCTET_STRING reqId = (OCTET_STRING) + ASN1Util.decode(OCTET_STRING.getTemplate(), + ASN1Util.encode(requestIds.elementAt(0))); + + requestId = new String(reqId.toByteArray()); + } + } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_transactionId)) { + transIds = taggedAttr.getValues(); + } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_recipientNonce)) { + // recipient nonce + } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_senderNonce)) { + sNonces = taggedAttr.getValues(); + } + } + } catch (Exception e) { + error = new EBaseException(e.toString()); + } + } + + IArgBlock httpParams = cmsReq.getHttpParams(); + boolean importCert = httpParams.getValueAsBoolean("importCert", + false); + // xxx need to check why this is not available at startup + X509Certificate mCACerts[] = null; + + try { + mCACerts = ((ICertAuthority) mAuthority).getCACertChain().getChain(); + } catch (Exception e) { + throw new ECMSGWException( + CMS.getUserMessage("CMS_GW_CA_CHAIN_NOT_AVAILABLE")); + } + + if (requestId == null || requestId.trim().equals("")) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_REQUEST_ID_PROVIDED")); + throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_REQUEST_ID_PROVIDED")); + } + try { + new BigInteger(requestId); + } catch (NumberFormatException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT_1", requestId)); + throw new EBaseException( + CMS.getUserMessage(getLocale(req), "CMS_BASE_INVALID_NUMBER_FORMAT_1", requestId)); + } + + IRequest r = mQueue.findRequest(new RequestId(requestId)); + + if (r == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REQUEST_ID_NOT_FOUND_1", requestId)); + throw new ECMSGWException( + CMS.getUserMessage("CMS_GW_REQUEST_ID_NOT_FOUND", requestId)); + } + + if (authToken != null) { + // if RA, requestOwner must match the group + String group = authToken.getInString("group"); + if ((group != null) && (group != "")) { + if (group.equals("Registration Manager Agents")) { + boolean groupMatched = false; + String requestOwner = r.getExtDataInString("requestOwner"); + if (requestOwner != null) { + if (requestOwner.equals(group)) + groupMatched = true; + } + if (groupMatched == false) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT_1", requestId.toString())); + throw new EBaseException( + CMS.getUserMessage(getLocale(req), "CMS_BASE_INVALID_NUMBER_FORMAT_1", requestId)); + } + } + } + } + + RequestStatus status = r.getRequestStatus(); + String note = r.getExtDataInString("requestNotes"); + + header.addStringValue("authority", mAuthorityId); + header.addLongValue(REQ_ID, Long.parseLong(r.getRequestId().toString())); + header.addStringValue(STATUS, status.toString()); + header.addLongValue(CREATE_ON, r.getCreationTime().getTime() / 1000); + header.addLongValue(UPDATE_ON, r.getModificationTime().getTime() / 1000); + if (note != null && note.length() > 0) + header.addStringValue("requestNotes", note); + + String type = r.getRequestType(); + Integer result = r.getExtDataInInteger(IRequest.RESULT); + + /* if (type.equals(IRequest.ENROLLMENT_REQUEST) && (r.get("profile") != null) && status.equals(RequestStatus.COMPLETE)) { + X509CertImpl cert = (X509CertImpl) r.get(IEnrollProfile.REQUEST_ISSUED_CERT); + IArgBlock rarg = CMS.createArgBlock(); + + rarg.addBigIntegerValue("serialNumber", + cert.getSerialNumber(), 16); + argSet.addRepeatRecord(rarg); + } + */ + String profileId = r.getExtDataInString("profileId"); + if (profileId != null) { + result = IRequest.RES_SUCCESS; + } + if ((type != null) && (type.equals(IRequest.ENROLLMENT_REQUEST) || + type.equals(IRequest.RENEWAL_REQUEST)) && (status != null) && + status.equals(RequestStatus.COMPLETE) && (result != null) && + result.equals(IRequest.RES_SUCCESS)) { + Object o = r.getExtDataInCertArray(IRequest.ISSUED_CERTS); + + if (profileId != null) { + X509CertImpl impl[] = new X509CertImpl[1]; + impl[0] = r.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT); + o = impl; + } + if (o != null && (o instanceof X509CertImpl[])) { + X509CertImpl[] certs = (X509CertImpl[]) o; + + if (certs != null && certs.length > 0) { + for (int i = 0; i < certs.length; i++) { + if (certs[i] != null) { + IArgBlock rarg = CMS.createArgBlock(); + + rarg.addBigIntegerValue("serialNumber", + certs[i].getSerialNumber(), 16); + // add pkcs7 cert for importing + if (importCert || isCMCReq) { + //byte[] ba = certs[i].getEncoded(); + X509CertImpl[] certsInChain = new X509CertImpl[1]; + ; + if (mCACerts != null) { + for (int ii = 0; ii < mCACerts.length; ii++) { + if (certs[i].equals(mCACerts[ii])) { + certsInChain = new + X509CertImpl[mCACerts.length]; + break; + } + certsInChain = new X509CertImpl[mCACerts.length + 1]; + } + } + + // Set the EE cert + certsInChain[0] = certs[i]; + + // Set the Ca certificate chain + if (mCACerts != null) { + for (int ii = 0; ii < mCACerts.length; ii++) { + if (!certs[i].equals(mCACerts[ii])) + certsInChain[ii + 1] = (X509CertImpl) mCACerts[ii]; + } + } + // Wrap the chain into a degenerate P7 object + String p7Str; + + try { + PKCS7 p7 = new PKCS7(new AlgorithmId[0], + new netscape.security.pkcs.ContentInfo(new byte[0]), + certsInChain, + new netscape.security.pkcs.SignerInfo[0]); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + p7.encodeSignedData(bos); + byte[] p7Bytes = bos.toByteArray(); + + p7Str = CMS.BtoA(p7Bytes); + + StringTokenizer tokenizer = null; + + if (File.separator.equals("\\")) { + char[] nl = new char[2]; + + nl[0] = 10; + nl[1] = 13; + String nlstr = new String(nl); + + tokenizer = new StringTokenizer(p7Str, nlstr); + } else + tokenizer = new StringTokenizer(p7Str, "\n"); + StringBuffer res = new StringBuffer(); + + while (tokenizer.hasMoreTokens()) { + String elem = (String) tokenizer.nextToken(); + + res.append(elem); + } + + header.addStringValue("pkcs7ChainBase64", res.toString()); + + // compose full response + if (isCMCReq) { + SEQUENCE controlSeq = new SEQUENCE(); + int bpid = 1; + SEQUENCE bpids = new SEQUENCE(); + + if (bodyPartId != null) + bpids.addElement(bodyPartId); + CMCStatusInfo cmcStatusInfo = new + CMCStatusInfo(CMCStatusInfo.SUCCESS, bpids); + TaggedAttribute ta = new TaggedAttribute(new + INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, + cmcStatusInfo); + + controlSeq.addElement(ta); + + // copy transactionID, senderNonce, + // create recipientNonce + if (transIds != null) { + ta = new TaggedAttribute(new + INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_transactionId, + transIds); + controlSeq.addElement(ta); + } + + if (sNonces != null) { + ta = new TaggedAttribute(new + INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_recipientNonce, + sNonces); + controlSeq.addElement(ta); + } + + String salt = CMSServlet.generateSalt(); + byte[] dig; + + try { + MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1"); + + dig = SHA1Digest.digest(salt.getBytes()); + } catch (NoSuchAlgorithmException ex) { + dig = salt.getBytes(); + } + String b64E = CMS.BtoA(dig); + String[] newNonce = { b64E }; + + ta = new TaggedAttribute(new + INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_senderNonce, + new OCTET_STRING(newNonce[0].getBytes())); + controlSeq.addElement(ta); + + ResponseBody rb = new ResponseBody(controlSeq, new + SEQUENCE(), new + SEQUENCE()); + EncapsulatedContentInfo ci = new + EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIResponse, + rb); + + org.mozilla.jss.crypto.X509Certificate x509cert = null; + + if (mAuthority instanceof ICertificateAuthority) { + x509cert = ((ICertificateAuthority) mAuthority).getCaX509Cert(); + } else if (mAuthority instanceof IRegistrationAuthority) { + x509cert = ((IRegistrationAuthority) mAuthority).getRACert(); + } + if (x509cert == null) + throw new ECMSGWException(CMS.getUserMessage("CMS_GW_CMC_ERROR", + "No signing cert found.")); + + X509CertImpl cert = new X509CertImpl(x509cert.getEncoded()); + ByteArrayInputStream issuer1 = new + ByteArrayInputStream(((X500Name) cert.getIssuerDN()).getEncoded()); + Name issuer = (Name) Name.getTemplate().decode(issuer1); + IssuerAndSerialNumber ias = + new + IssuerAndSerialNumber(issuer, new INTEGER(cert.getSerialNumber() + .toString())); + SignerIdentifier si = new + SignerIdentifier(SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null); + + // SHA1 is the default digest Alg for now. + DigestAlgorithm digestAlg = null; + SignatureAlgorithm signAlg = null; + org.mozilla.jss.crypto.PrivateKey privKey = + CryptoManager.getInstance().findPrivKeyByCert(x509cert); + org.mozilla.jss.crypto.PrivateKey.Type keyType = privKey.getType(); + + if (keyType.equals(org.mozilla.jss.crypto.PrivateKey.RSA)) + signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest; + else if (keyType.equals(org.mozilla.jss.crypto.PrivateKey.DSA)) + signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest; + MessageDigest SHADigest = null; + byte[] digest = null; + + try { + SHADigest = MessageDigest.getInstance("SHA1"); + digestAlg = DigestAlgorithm.SHA1; + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + + rb.encode((OutputStream) ostream); + digest = SHADigest.digest(ostream.toByteArray()); + } catch (NoSuchAlgorithmException ex) { + //log("digest fail"); + } + + org.mozilla.jss.pkix.cms.SignerInfo signInfo = new + org.mozilla.jss.pkix.cms.SignerInfo(si, null, null, + OBJECT_IDENTIFIER.id_cct_PKIResponse, + digest, signAlg, + privKey); + SET signInfos = new SET(); + + signInfos.addElement(signInfo); + + SET digestAlgs = new SET(); + + if (digestAlg != null) { + AlgorithmIdentifier ai = new + AlgorithmIdentifier(digestAlg.toOID(), + null); + + digestAlgs.addElement(ai); + } + + SET jsscerts = new SET(); + + for (int j = 0; j < certsInChain.length; j++) { + ByteArrayInputStream is = new + ByteArrayInputStream(certsInChain[j].getEncoded()); + org.mozilla.jss.pkix.cert.Certificate certJss = + (org.mozilla.jss.pkix.cert.Certificate) + org.mozilla.jss.pkix.cert.Certificate.getTemplate().decode(is); + + jsscerts.addElement(certJss); + } + + SignedData fResponse = new + SignedData(digestAlgs, ci, + jsscerts, null, signInfos); + org.mozilla.jss.pkix.cms.ContentInfo fullResponse = + new + org.mozilla.jss.pkix.cms.ContentInfo( + org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA, fResponse); + ByteArrayOutputStream ostream = new + ByteArrayOutputStream(); + + fullResponse.encode((OutputStream) ostream); + byte[] fr = ostream.toByteArray(); + + header.addStringValue(FULL_RESPONSE, CMS.BtoA(fr)); + } + } catch (Exception e) { + e.printStackTrace(); + log(ILogger.LL_FAILURE, + CMS.getLogMessage("CMSGW_ERROR_FORMING_PKCS7_1", e.toString())); + throw new ECMSGWException( + CMS.getUserMessage("CMS_GW_FORMING_PKCS7_ERROR")); + } + } + argSet.addRepeatRecord(rarg); + } + } + } + } + } + + try { + ServletOutputStream out = resp.getOutputStream(); + + if (error == null) { + String xmlOutput = req.getParameter("xml"); + if (xmlOutput != null && xmlOutput.equals("true")) { + outputXML(resp, argSet); + } else { + resp.setContentType("text/html"); + form.renderOutput(out, argSet); + cmsReq.setStatus(CMSRequest.SUCCESS); + } + } else { + cmsReq.setStatus(CMSRequest.ERROR); + cmsReq.setError(error); + } + } catch (IOException e) { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString())); + throw new ECMSGWException( + CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")); + } + } +} -- cgit