diff options
author | Endi Sukma Dewata <edewata@redhat.com> | 2012-03-24 02:27:47 -0500 |
---|---|---|
committer | Endi Sukma Dewata <edewata@redhat.com> | 2012-03-26 11:43:54 -0500 |
commit | 621d9e5c413e561293d7484b93882d985b3fe15f (patch) | |
tree | 638f3d75761c121d9a8fb50b52a12a6686c5ac5c /base/common/src/com/netscape/cms/servlet/common | |
parent | 40d3643b8d91886bf210aa27f711731c81a11e49 (diff) | |
download | pki-621d9e5c413e561293d7484b93882d985b3fe15f.tar.gz pki-621d9e5c413e561293d7484b93882d985b3fe15f.tar.xz pki-621d9e5c413e561293d7484b93882d985b3fe15f.zip |
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
Diffstat (limited to 'base/common/src/com/netscape/cms/servlet/common')
23 files changed, 4108 insertions, 0 deletions
diff --git a/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java b/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java new file mode 100644 index 000000000..88369ace3 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java @@ -0,0 +1,109 @@ +// --- 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.common; + +import java.util.Enumeration; +import java.util.Hashtable; + +import com.netscape.certsrv.authentication.IAuthCredentials; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IArgBlock; + +/** + * Authentication Credentials as input to the authMgr + * <P> + * + * @version $Revision$, $Date$ + */ +public class AuthCredentials implements IAuthCredentials { + /** + * + */ + private static final long serialVersionUID = -5995164231849154265L; + private Hashtable<String, Object> authCreds = null; + // Inserted by bskim + private IArgBlock argblk = null; + + // Insert end + + public AuthCredentials() { + authCreds = new Hashtable<String, Object>(); + } + + /** + * sets a credential with credential name and the credential + * + * @param name credential name + * @param cred credential + * @exception com.netscape.certsrv.base.EBaseException NullPointerException + */ + public void set(String name, Object cred) throws EBaseException { + if (cred == null) { + throw new EBaseException("AuthCredentials.set()"); + } + + authCreds.put(name, cred); + } + + /** + * returns the credential to which the specified name is mapped in this + * credential set + * + * @param name credential name + * @return the named authentication credential + */ + public Object get(String name) { + return authCreds.get(name); + } + + /** + * removes the name and its corresponding credential from this + * credential set. This method does nothing if the named + * credential is not in the credential set. + * + * @param name credential name + */ + public void delete(String name) { + authCreds.remove(name); + } + + /** + * returns an enumeration of the credential names in this credential + * set. Use the Enumeration methods on the returned object to + * fetch the elements sequentially. + * + * @return an enumeration of the names in this credential set + * @see java.util.Enumeration + */ + public Enumeration<String> getElements() { + return authCreds.keys(); + } + + // Inserted by bskim + public void setArgBlock(IArgBlock blk) { + argblk = blk; + return; + } + + // Insert end + + public IArgBlock getArgBlock() { + return argblk; + } + // Insert end +} diff --git a/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java b/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java new file mode 100644 index 000000000..38fcf24f9 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java @@ -0,0 +1,1112 @@ +// --- 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.common; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.util.Date; +import java.util.Hashtable; + +import javax.servlet.http.HttpServletResponse; + +import netscape.security.x509.CRLExtensions; +import netscape.security.x509.CRLReasonExtension; +import netscape.security.x509.CertificateChain; +import netscape.security.x509.InvalidityDateExtension; +import netscape.security.x509.RevocationReason; +import netscape.security.x509.RevokedCertImpl; +import netscape.security.x509.X500Name; +import netscape.security.x509.X509CertImpl; +import netscape.security.x509.X509Key; + +import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.asn1.ANY; +import org.mozilla.jss.asn1.ASN1Util; +import org.mozilla.jss.asn1.ENUMERATED; +import org.mozilla.jss.asn1.GeneralizedTime; +import org.mozilla.jss.asn1.INTEGER; +import org.mozilla.jss.asn1.InvalidBERException; +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.asn1.UTF8String; +import org.mozilla.jss.crypto.DigestAlgorithm; +import org.mozilla.jss.crypto.PrivateKey; +import org.mozilla.jss.crypto.SignatureAlgorithm; +import org.mozilla.jss.pkcs11.PK11PubKey; +import org.mozilla.jss.pkix.cert.Certificate; +import org.mozilla.jss.pkix.cmc.CMCCertId; +import org.mozilla.jss.pkix.cmc.CMCStatusInfo; +import org.mozilla.jss.pkix.cmc.GetCert; +import org.mozilla.jss.pkix.cmc.OtherInfo; +import org.mozilla.jss.pkix.cmc.OtherMsg; +import org.mozilla.jss.pkix.cmc.PendInfo; +import org.mozilla.jss.pkix.cmc.ResponseBody; +import org.mozilla.jss.pkix.cmc.TaggedAttribute; +import org.mozilla.jss.pkix.cmmf.RevRequest; +import org.mozilla.jss.pkix.cms.ContentInfo; +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.cms.SignerInfo; +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.ISharedToken; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.EPropertyNotFound; +import com.netscape.certsrv.base.SessionContext; +import com.netscape.certsrv.ca.ICertificateAuthority; +import com.netscape.certsrv.dbs.certdb.ICertRecord; +import com.netscape.certsrv.dbs.certdb.ICertificateRepository; +import com.netscape.certsrv.logging.AuditFormat; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.profile.IEnrollProfile; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.IRequestQueue; +import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestStatus; + +/** + * Utility CMCOutputTemplate + * + * @version $ $, $Date$ + */ +public class CMCOutputTemplate { + public CMCOutputTemplate() { + } + + public void createFullResponseWithFailedStatus(HttpServletResponse resp, + SEQUENCE bpids, int code, UTF8String s) { + SEQUENCE controlSeq = new SEQUENCE(); + SEQUENCE cmsSeq = new SEQUENCE(); + SEQUENCE otherMsgSeq = new SEQUENCE(); + + int bpid = 1; + OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, + new INTEGER(code), null); + CMCStatusInfo cmcStatusInfo = new CMCStatusInfo( + new INTEGER(CMCStatusInfo.FAILED), + bpids, s, otherInfo); + TaggedAttribute tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + + try { + ResponseBody respBody = new ResponseBody(controlSeq, + cmsSeq, otherMsgSeq); + + SET certs = new SET(); + ContentInfo contentInfo = getContentInfo(respBody, certs); + if (contentInfo == null) + return; + ByteArrayOutputStream fos = new ByteArrayOutputStream(); + contentInfo.encode(fos); + fos.close(); + byte[] contentBytes = fos.toByteArray(); + + resp.setContentType("application/pkcs7-mime"); + resp.setContentLength(contentBytes.length); + OutputStream os = resp.getOutputStream(); + os.write(contentBytes); + os.flush(); + } catch (Exception e) { + CMS.debug("CMCOutputTemplate createFullResponseWithFailedStatus Exception: " + e.toString()); + return; + } + } + + public void createFullResponse(HttpServletResponse resp, IRequest[] reqs, + String cert_request_type, int[] error_codes) { + + SEQUENCE controlSeq = new SEQUENCE(); + SEQUENCE cmsSeq = new SEQUENCE(); + SEQUENCE otherMsgSeq = new SEQUENCE(); + SessionContext context = SessionContext.getContext(); + + // set status info control for simple enrollment request + // in rfc 2797: body list value is 1 + int bpid = 1; + SEQUENCE pending_bpids = null; + SEQUENCE success_bpids = null; + SEQUENCE failed_bpids = null; + if (cert_request_type.equals("crmf") || + cert_request_type.equals("pkcs10")) { + String reqId = reqs[0].getRequestId().toString(); + OtherInfo otherInfo = null; + if (error_codes[0] == 2) { + PendInfo pendInfo = new PendInfo(reqId, new Date()); + otherInfo = new OtherInfo(OtherInfo.PEND, null, + pendInfo); + } else { + otherInfo = new OtherInfo(OtherInfo.FAIL, + new INTEGER(OtherInfo.BAD_REQUEST), null); + } + + SEQUENCE bpids = new SEQUENCE(); + bpids.addElement(new INTEGER(1)); + CMCStatusInfo cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.PENDING, + bpids, (String) null, otherInfo); + TaggedAttribute tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + } else if (cert_request_type.equals("cmc")) { + pending_bpids = new SEQUENCE(); + success_bpids = new SEQUENCE(); + failed_bpids = new SEQUENCE(); + if (reqs != null) { + for (int i = 0; i < reqs.length; i++) { + if (error_codes[i] == 0) { + success_bpids.addElement(new INTEGER( + reqs[i].getExtDataInBigInteger("bodyPartId"))); + } else if (error_codes[i] == 2) { + pending_bpids.addElement(new INTEGER( + reqs[i].getExtDataInBigInteger("bodyPartId"))); + } else { + failed_bpids.addElement(new INTEGER( + reqs[i].getExtDataInBigInteger("bodyPartId"))); + } + } + } + + TaggedAttribute tagattr = null; + CMCStatusInfo cmcStatusInfo = null; + SEQUENCE identityBpids = (SEQUENCE) context.get("identityProof"); + if (identityBpids != null && identityBpids.size() > 0) { + OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, + new INTEGER(OtherInfo.BAD_IDENTITY), null); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, + identityBpids, (String) null, otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + } + + SEQUENCE POPLinkWitnessBpids = (SEQUENCE) context.get("POPLinkWitness"); + if (POPLinkWitnessBpids != null && POPLinkWitnessBpids.size() > 0) { + OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, + new INTEGER(OtherInfo.BAD_REQUEST), null); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, + POPLinkWitnessBpids, (String) null, otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + } + + if (pending_bpids.size() > 0) { + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.PENDING, + pending_bpids, (String) null, null); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + } + + if (success_bpids.size() > 0) { + boolean confirmRequired = false; + try { + confirmRequired = + CMS.getConfigStore().getBoolean("cmc.cert.confirmRequired", + false); + } catch (Exception e) { + } + if (confirmRequired) { + CMS.debug("CMCOutputTemplate: confirmRequired in the request"); + cmcStatusInfo = + new CMCStatusInfo(CMCStatusInfo.CONFIRM_REQUIRED, + success_bpids, (String) null, null); + } else { + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.SUCCESS, + success_bpids, (String) null, null); + } + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + } + + if (failed_bpids.size() > 0) { + OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, + new INTEGER(OtherInfo.BAD_REQUEST), null); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, + failed_bpids, (String) null, otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + } + } + + SET certs = new SET(); + + try { + // deal with controls + Integer nums = (Integer) (context.get("numOfControls")); + if (nums != null && nums.intValue() > 0) { + TaggedAttribute attr = + (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_getCert)); + if (attr != null) { + try { + processGetCertControl(attr, certs); + } catch (EBaseException ee) { + CMS.debug("CMCOutputTemplate: " + ee.toString()); + OtherInfo otherInfo1 = new OtherInfo(OtherInfo.FAIL, + new INTEGER(OtherInfo.BAD_CERT_ID), null); + SEQUENCE bpids1 = new SEQUENCE(); + bpids1.addElement(attr.getBodyPartID()); + CMCStatusInfo cmcStatusInfo1 = new CMCStatusInfo( + new INTEGER(CMCStatusInfo.FAILED), + bpids1, null, otherInfo1); + TaggedAttribute tagattr1 = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo1); + controlSeq.addElement(tagattr1); + } + } + + attr = + (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_dataReturn)); + if (attr != null) + bpid = processDataReturnControl(attr, controlSeq, bpid); + + attr = + (TaggedAttribute) context.get(OBJECT_IDENTIFIER.id_cmc_transactionId); + if (attr != null) + bpid = processTransactionControl(attr, controlSeq, bpid); + + attr = + (TaggedAttribute) context.get(OBJECT_IDENTIFIER.id_cmc_senderNonce); + if (attr != null) + bpid = processSenderNonceControl(attr, controlSeq, bpid); + + attr = + (TaggedAttribute) context.get(OBJECT_IDENTIFIER.id_cmc_QueryPending); + if (attr != null) + bpid = processQueryPendingControl(attr, controlSeq, bpid); + + attr = + (TaggedAttribute) context.get(OBJECT_IDENTIFIER.id_cmc_idConfirmCertAcceptance); + + if (attr != null) + bpid = processConfirmCertAcceptanceControl(attr, controlSeq, + bpid); + + attr = + (TaggedAttribute) context.get(OBJECT_IDENTIFIER.id_cmc_revokeRequest); + + if (attr != null) + bpid = processRevokeRequestControl(attr, controlSeq, + bpid); + } + + if (success_bpids != null && success_bpids.size() > 0) { + for (int i = 0; i < reqs.length; i++) { + if (error_codes[i] == 0) { + X509CertImpl impl = + (reqs[i].getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT)); + byte[] bin = impl.getEncoded(); + Certificate.Template certTemplate = new Certificate.Template(); + Certificate cert = (Certificate) certTemplate.decode( + new ByteArrayInputStream(bin)); + certs.addElement(cert); + } + } + } + + ResponseBody respBody = new ResponseBody(controlSeq, + cmsSeq, otherMsgSeq); + + ContentInfo contentInfo = getContentInfo(respBody, certs); + ByteArrayOutputStream fos = new ByteArrayOutputStream(); + contentInfo.encode(fos); + fos.close(); + byte[] contentBytes = fos.toByteArray(); + + resp.setContentType("application/pkcs7-mime"); + resp.setContentLength(contentBytes.length); + OutputStream os = resp.getOutputStream(); + os.write(contentBytes); + os.flush(); + } catch (java.security.cert.CertificateEncodingException e) { + CMS.debug("CMCOutputTemplate exception: " + e.toString()); + } catch (InvalidBERException e) { + CMS.debug("CMCOutputTemplate exception: " + e.toString()); + } catch (IOException e) { + CMS.debug("CMCOutputTemplate exception: " + e.toString()); + } catch (Exception e) { + CMS.debug("Exception: " + e.toString()); + } + } + + private ContentInfo getContentInfo(ResponseBody respBody, SET certs) { + try { + ICertificateAuthority ca = null; + // add CA cert chain + ca = (ICertificateAuthority) CMS.getSubsystem("ca"); + CertificateChain certchains = ca.getCACertChain(); + java.security.cert.X509Certificate[] chains = certchains.getChain(); + + for (int i = 0; i < chains.length; i++) { + Certificate.Template certTemplate = new Certificate.Template(); + Certificate cert = (Certificate) certTemplate.decode( + new ByteArrayInputStream(chains[i].getEncoded())); + certs.addElement(cert); + } + + EncapsulatedContentInfo enContentInfo = new EncapsulatedContentInfo( + OBJECT_IDENTIFIER.id_cct_PKIResponse, respBody); + org.mozilla.jss.crypto.X509Certificate x509CAcert = null; + x509CAcert = ca.getCaX509Cert(); + X509CertImpl caimpl = new X509CertImpl(x509CAcert.getEncoded()); + X500Name issuerName = (X500Name) caimpl.getIssuerDN(); + byte[] issuerByte = issuerName.getEncoded(); + ByteArrayInputStream istream = new ByteArrayInputStream(issuerByte); + Name issuer = (Name) Name.getTemplate().decode(istream); + IssuerAndSerialNumber ias = new IssuerAndSerialNumber( + issuer, new INTEGER(x509CAcert.getSerialNumber().toString())); + SignerIdentifier si = new SignerIdentifier( + SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null); + // use CA instance's default signature and digest algorithm + SignatureAlgorithm signAlg = ca.getDefaultSignatureAlgorithm(); + org.mozilla.jss.crypto.PrivateKey privKey = + CryptoManager.getInstance().findPrivKeyByCert(x509CAcert); + /* + 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; + } else if( keyType.equals( org.mozilla.jss.crypto.PrivateKey.EC ) ) { + signAlg = SignatureAlgorithm.ECSignatureWithSHA1Digest; + } else { + CMS.debug( "CMCOutputTemplate::getContentInfo() - " + + "signAlg is unsupported!" ); + return null; + } + */ + DigestAlgorithm digestAlg = signAlg.getDigestAlg(); + MessageDigest msgDigest = null; + byte[] digest = null; + + msgDigest = MessageDigest.getInstance(digestAlg.toString()); + + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + + respBody.encode((OutputStream) ostream); + digest = msgDigest.digest(ostream.toByteArray()); + + SignerInfo signInfo = new + 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); + } + SignedData signedData = new SignedData(digestAlgs, + enContentInfo, certs, null, signInfos); + + ContentInfo contentInfo = new ContentInfo(signedData); + CMS.debug("CMCOutputTemplate::getContentInfo() - done"); + return contentInfo; + } catch (Exception e) { + CMS.debug("CMCOutputTemplate: Failed to create CMCContentInfo. Exception: " + e.toString()); + } + return null; + } + + public void createSimpleResponse(HttpServletResponse resp, IRequest[] reqs) { + SET certs = new SET(); + SessionContext context = SessionContext.getContext(); + try { + TaggedAttribute attr = + (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_getCert)); + processGetCertControl(attr, certs); + } catch (Exception e) { + CMS.debug("CMCOutputTemplate: No certificate is found."); + } + + SET digestAlgorithms = new SET(); + SET signedInfos = new SET(); + + // oid for id-data + OBJECT_IDENTIFIER oid = new OBJECT_IDENTIFIER("1.2.840.113549.1.7.1"); + EncapsulatedContentInfo enContentInfo = new EncapsulatedContentInfo(oid, null); + + try { + if (reqs != null) { + for (int i = 0; i < reqs.length; i++) { + X509CertImpl impl = + (reqs[i].getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT)); + byte[] bin = impl.getEncoded(); + Certificate.Template certTemplate = new Certificate.Template(); + Certificate cert = + (Certificate) certTemplate.decode(new ByteArrayInputStream(bin)); + + certs.addElement(cert); + } + + // Get CA certs + ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem("ca"); + CertificateChain certchains = ca.getCACertChain(); + java.security.cert.X509Certificate[] chains = certchains.getChain(); + + for (int i = 0; i < chains.length; i++) { + Certificate.Template certTemplate = new Certificate.Template(); + Certificate cert = (Certificate) certTemplate.decode( + new ByteArrayInputStream(chains[i].getEncoded())); + certs.addElement(cert); + } + } + + if (certs.size() == 0) + return; + SignedData signedData = new SignedData(digestAlgorithms, + enContentInfo, certs, null, signedInfos); + + ContentInfo contentInfo = new ContentInfo(signedData); + ByteArrayOutputStream fos = new ByteArrayOutputStream(); + contentInfo.encode(fos); + fos.close(); + byte[] contentBytes = fos.toByteArray(); + + resp.setContentType("application/pkcs7-mime"); + resp.setContentLength(contentBytes.length); + OutputStream os = resp.getOutputStream(); + os.write(contentBytes); + os.flush(); + } catch (java.security.cert.CertificateEncodingException e) { + CMS.debug("CMCOutputTemplate exception: " + e.toString()); + } catch (InvalidBERException e) { + CMS.debug("CMCOutputTemplate exception: " + e.toString()); + } catch (IOException e) { + CMS.debug("CMCOutputTemplate exception: " + e.toString()); + } + } + + private int processConfirmCertAcceptanceControl( + TaggedAttribute attr, SEQUENCE controlSeq, int bpid) { + if (attr != null) { + INTEGER bodyId = attr.getBodyPartID(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(bodyId); + SET values = attr.getValues(); + if (values != null && values.size() > 0) { + try { + CMCCertId cmcCertId = + (CMCCertId) (ASN1Util.decode(CMCCertId.getTemplate(), + ASN1Util.encode(values.elementAt(0)))); + BigInteger serialno = (BigInteger) (cmcCertId.getSerial()); + SEQUENCE issuers = cmcCertId.getIssuer(); + //ANY issuer = (ANY)issuers.elementAt(0); + ANY issuer = + (ANY) (ASN1Util.decode(ANY.getTemplate(), + ASN1Util.encode(issuers.elementAt(0)))); + byte[] b = issuer.getEncoded(); + X500Name n = new X500Name(b); + ICertificateAuthority ca = null; + ca = (ICertificateAuthority) CMS.getSubsystem("ca"); + X500Name caName = ca.getX500Name(); + boolean confirmAccepted = false; + if (n.toString().equalsIgnoreCase(caName.toString())) { + CMS.debug("CMCOutputTemplate: Issuer names are equal"); + ICertificateRepository repository = + (ICertificateRepository) ca.getCertificateRepository(); + try { + repository.getX509Certificate(serialno); + } catch (EBaseException ee) { + CMS.debug("CMCOutputTemplate: Certificate in the confirm acceptance control was not found"); + } + } + CMCStatusInfo cmcStatusInfo = null; + if (confirmAccepted) { + CMS.debug("CMCOutputTemplate: Confirm Acceptance received. The certificate exists in the certificate repository."); + cmcStatusInfo = + new CMCStatusInfo(CMCStatusInfo.SUCCESS, seq, + (String) null, null); + } else { + CMS.debug("CMCOutputTemplate: Confirm Acceptance received. The certificate does not exist in the certificate repository."); + OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, + new INTEGER(OtherInfo.BAD_CERT_ID), null); + cmcStatusInfo = + new CMCStatusInfo(CMCStatusInfo.FAILED, seq, + (String) null, otherInfo); + } + TaggedAttribute statustagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(statustagattr); + } catch (Exception e) { + CMS.debug("CMCOutputTemplate exception: " + e.toString()); + } + } + } + return bpid; + } + + private void processGetCertControl(TaggedAttribute attr, SET certs) + throws InvalidBERException, java.security.cert.CertificateEncodingException, + IOException, EBaseException { + if (attr != null) { + SET vals = attr.getValues(); + + if (vals.size() == 1) { + GetCert getCert = + (GetCert) (ASN1Util.decode(GetCert.getTemplate(), + ASN1Util.encode(vals.elementAt(0)))); + BigInteger serialno = (BigInteger) (getCert.getSerialNumber()); + ANY issuer = (ANY) getCert.getIssuer(); + byte b[] = issuer.getEncoded(); + X500Name n = new X500Name(b); + ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem("ca"); + X500Name caName = ca.getX500Name(); + if (!n.toString().equalsIgnoreCase(caName.toString())) { + CMS.debug("CMCOutputTemplate: Issuer names are equal in the GetCert Control"); + throw new EBaseException("Certificate is not found"); + } + ICertificateRepository repository = + (ICertificateRepository) ca.getCertificateRepository(); + X509CertImpl impl = repository.getX509Certificate(serialno); + byte[] bin = impl.getEncoded(); + Certificate.Template certTemplate = new Certificate.Template(); + Certificate cert = + (Certificate) certTemplate.decode(new ByteArrayInputStream(bin)); + certs.addElement(cert); + } + } + } + + private int processQueryPendingControl(TaggedAttribute attr, + SEQUENCE controlSeq, int bpid) { + if (attr != null) { + SET values = attr.getValues(); + if (values != null && values.size() > 0) { + SEQUENCE pending_bpids = new SEQUENCE(); + SEQUENCE success_bpids = new SEQUENCE(); + SEQUENCE failed_bpids = new SEQUENCE(); + for (int i = 0; i < values.size(); i++) { + try { + INTEGER reqId = (INTEGER) + ASN1Util.decode(INTEGER.getTemplate(), + ASN1Util.encode(values.elementAt(i))); + String requestId = new String(reqId.toByteArray()); + + ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem("ca"); + IRequestQueue queue = ca.getRequestQueue(); + IRequest r = queue.findRequest(new RequestId(requestId)); + if (r != null) { + RequestStatus status = r.getRequestStatus(); + if (status.equals(RequestStatus.PENDING)) { + pending_bpids.addElement(reqId); + } else if (status.equals(RequestStatus.APPROVED)) { + success_bpids.addElement(reqId); + } else if (status.equals(RequestStatus.REJECTED)) { + failed_bpids.addElement(reqId); + } + } + } catch (Exception e) { + } + } + + if (pending_bpids.size() > 0) { + CMCStatusInfo cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.PENDING, + pending_bpids, (String) null, null); + TaggedAttribute tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + } + if (success_bpids.size() > 0) { + CMCStatusInfo cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.SUCCESS, + pending_bpids, (String) null, null); + TaggedAttribute tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + } + + if (failed_bpids.size() > 0) { + CMCStatusInfo cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, + pending_bpids, (String) null, null); + TaggedAttribute tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + } + + } + } + return bpid; + } + + private int processTransactionControl(TaggedAttribute attr, + SEQUENCE controlSeq, int bpid) { + if (attr != null) { + SET transIds = attr.getValues(); + if (transIds != null) { + TaggedAttribute tagattr = new TaggedAttribute( + new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_transactionId, + transIds); + controlSeq.addElement(tagattr); + } + } + + return bpid; + } + + private int processSenderNonceControl(TaggedAttribute attr, + SEQUENCE controlSeq, int bpid) { + if (attr != null) { + SET sNonce = attr.getValues(); + if (sNonce != null) { + TaggedAttribute tagattr = new TaggedAttribute( + new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_recipientNonce, + sNonce); + controlSeq.addElement(tagattr); + Date date = new Date(); + String salt = "lala123" + date.toString(); + byte[] dig; + try { + MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1"); + dig = SHA1Digest.digest(salt.getBytes()); + } catch (NoSuchAlgorithmException ex) { + dig = salt.getBytes(); + } + + String b64E = CMS.BtoA(dig); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_senderNonce, + new OCTET_STRING(b64E.getBytes())); + controlSeq.addElement(tagattr); + } + } + + return bpid; + } + + private int processDataReturnControl(TaggedAttribute attr, + SEQUENCE controlSeq, int bpid) throws InvalidBERException { + + if (attr != null) { + SET vals = attr.getValues(); + + if (vals.size() > 0) { + OCTET_STRING str = + (OCTET_STRING) (ASN1Util.decode(OCTET_STRING.getTemplate(), + ASN1Util.encode(vals.elementAt(0)))); + TaggedAttribute tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_dataReturn, str); + controlSeq.addElement(tagattr); + } + } + + return bpid; + } + + private int processRevokeRequestControl(TaggedAttribute attr, + SEQUENCE controlSeq, int bpid) throws InvalidBERException, EBaseException, + IOException { + boolean revoke = false; + SessionContext context = SessionContext.getContext(); + if (attr != null) { + INTEGER attrbpid = attr.getBodyPartID(); + CMCStatusInfo cmcStatusInfo = null; + SET vals = attr.getValues(); + if (vals.size() > 0) { + RevRequest revRequest = + (RevRequest) (ASN1Util.decode(new RevRequest.Template(), + ASN1Util.encode(vals.elementAt(0)))); + OCTET_STRING str = revRequest.getSharedSecret(); + INTEGER pid = attr.getBodyPartID(); + TaggedAttribute tagattr = null; + INTEGER revokeCertSerial = revRequest.getSerialNumber(); + BigInteger revokeSerial = new BigInteger(revokeCertSerial.toByteArray()); + if (str == null) { + boolean needVerify = true; + try { + needVerify = CMS.getConfigStore().getBoolean("cmc.revokeCert.verify", true); + } catch (Exception e) { + } + + if (needVerify) { + Integer num1 = (Integer) context.get("numOfOtherMsgs"); + int num = num1.intValue(); + for (int i = 0; i < num; i++) { + OtherMsg data = (OtherMsg) context.get("otherMsg" + i); + INTEGER dpid = data.getBodyPartID(); + if (pid.longValue() == dpid.longValue()) { + ANY msgValue = data.getOtherMsgValue(); + SignedData msgData = + (SignedData) msgValue.decodeWith(SignedData.getTemplate()); + if (!verifyRevRequestSignature(msgData)) { + OtherInfo otherInfo = + new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK), + null); + SEQUENCE failed_bpids = new SEQUENCE(); + failed_bpids.addElement(attrbpid); + cmcStatusInfo = + new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, + otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + return bpid; + } + } + } + } + + revoke = true; + // check shared secret + } else { + ISharedToken tokenClass = null; + boolean sharedSecretFound = true; + String name = null; + try { + name = CMS.getConfigStore().getString("cmc.revokeCert.sharedSecret.class"); + } catch (EPropertyNotFound e) { + CMS.debug("EnrollProfile: Failed to find the token class in the configuration file."); + sharedSecretFound = false; + } catch (EBaseException e) { + CMS.debug("EnrollProfile: Failed to find the token class in the configuration file."); + sharedSecretFound = false; + } + + try { + tokenClass = (ISharedToken) Class.forName(name).newInstance(); + } catch (ClassNotFoundException e) { + CMS.debug("EnrollProfile: Failed to find class name: " + name); + sharedSecretFound = false; + } catch (InstantiationException e) { + CMS.debug("EnrollProfile: Failed to instantiate class: " + name); + sharedSecretFound = false; + } catch (IllegalAccessException e) { + CMS.debug("EnrollProfile: Illegal access: " + name); + sharedSecretFound = false; + } + + if (!sharedSecretFound) { + CMS.debug("CMCOutputTemplate: class for shared secret was not found."); + OtherInfo otherInfo = + new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.INTERNAL_CA_ERROR), null); + SEQUENCE failed_bpids = new SEQUENCE(); + failed_bpids.addElement(attrbpid); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + return bpid; + } + + String sharedSecret = null; + if (tokenClass != null) { + sharedSecret = tokenClass.getSharedToken(revokeSerial); + } + + if (sharedSecret == null) { + CMS.debug("CMCOutputTemplate: class for shared secret was not found."); + OtherInfo otherInfo = + new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.INTERNAL_CA_ERROR), null); + SEQUENCE failed_bpids = new SEQUENCE(); + failed_bpids.addElement(attrbpid); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + return bpid; + } + + byte[] strb = str.toByteArray(); + String clientSC = new String(strb); + if (clientSC.equals(sharedSecret)) { + CMS.debug("CMCOutputTemplate: Both client and server shared secret are the same, can go ahead to revoke certificate."); + revoke = true; + } else { + CMS.debug("CMCOutputTemplate: Both client and server shared secret are not the same, cant revoke certificate."); + OtherInfo otherInfo = + new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK), null); + SEQUENCE failed_bpids = new SEQUENCE(); + failed_bpids.addElement(attrbpid); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + return bpid; + } + } + + if (revoke) { + ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem("ca"); + ICertificateRepository repository = (ICertificateRepository) ca.getCertificateRepository(); + ICertRecord record = null; + try { + record = repository.readCertificateRecord(revokeSerial); + } catch (EBaseException ee) { + CMS.debug("CMCOutputTemplate: Exception: " + ee.toString()); + } + + if (record == null) { + CMS.debug("CMCOutputTemplate: The certificate is not found"); + OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_CERT_ID), null); + SEQUENCE failed_bpids = new SEQUENCE(); + failed_bpids.addElement(attrbpid); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + return bpid; + } + + if (record.getStatus().equals(ICertRecord.STATUS_REVOKED)) { + CMS.debug("CMCOutputTemplate: The certificate is already revoked."); + SEQUENCE success_bpids = new SEQUENCE(); + success_bpids.addElement(attrbpid); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.SUCCESS, + success_bpids, (String) null, null); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + return bpid; + } + X509CertImpl impl = record.getCertificate(); + X509CertImpl[] impls = new X509CertImpl[1]; + impls[0] = impl; + ENUMERATED n = revRequest.getReason(); + RevocationReason reason = toRevocationReason(n); + CRLReasonExtension crlReasonExtn = new CRLReasonExtension(reason); + CRLExtensions entryExtn = new CRLExtensions(); + GeneralizedTime t = revRequest.getInvalidityDate(); + InvalidityDateExtension invalidityDateExtn = null; + if (t != null) { + invalidityDateExtn = new InvalidityDateExtension(t.toDate()); + entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn); + } + if (crlReasonExtn != null) { + entryExtn.set(crlReasonExtn.getName(), crlReasonExtn); + } + + RevokedCertImpl revCertImpl = + new RevokedCertImpl(impl.getSerialNumber(), CMS.getCurrentDate(), entryExtn); + RevokedCertImpl[] revCertImpls = new RevokedCertImpl[1]; + revCertImpls[0] = revCertImpl; + IRequestQueue queue = ca.getRequestQueue(); + IRequest revReq = queue.newRequest(IRequest.REVOCATION_REQUEST); + revReq.setExtData(IRequest.CERT_INFO, revCertImpls); + revReq.setExtData(IRequest.REVOKED_REASON, + Integer.valueOf(reason.toInt())); + UTF8String utfstr = revRequest.getComment(); + if (utfstr != null) + revReq.setExtData(IRequest.REQUESTOR_COMMENTS, utfstr.toString()); + revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT); + queue.processRequest(revReq); + RequestStatus stat = revReq.getRequestStatus(); + if (stat == RequestStatus.COMPLETE) { + Integer result = revReq.getExtDataInInteger(IRequest.RESULT); + CMS.debug("CMCOutputTemplate: revReq result = " + result); + if (result.equals(IRequest.RES_ERROR)) { + CMS.debug("CMCOutputTemplate: revReq exception: " + + revReq.getExtDataInString(IRequest.ERROR)); + OtherInfo otherInfo = + new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_REQUEST), null); + SEQUENCE failed_bpids = new SEQUENCE(); + failed_bpids.addElement(attrbpid); + cmcStatusInfo = + new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + return bpid; + } + } + + ILogger logger = CMS.getLogger(); + String initiative = AuditFormat.FROMUSER; + logger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, + AuditFormat.DOREVOKEFORMAT, new Object[] { + revReq.getRequestId(), initiative, "completed", + impl.getSubjectDN(), + impl.getSerialNumber().toString(16), + reason.toString() }); + CMS.debug("CMCOutputTemplate: Certificate get revoked."); + SEQUENCE success_bpids = new SEQUENCE(); + success_bpids.addElement(attrbpid); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.SUCCESS, + success_bpids, (String) null, null); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + return bpid; + } else { + OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK), null); + SEQUENCE failed_bpids = new SEQUENCE(); + failed_bpids.addElement(attrbpid); + cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo); + tagattr = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo); + controlSeq.addElement(tagattr); + return bpid; + } + } + } + + return bpid; + } + + private RevocationReason toRevocationReason(ENUMERATED n) { + long code = n.getValue(); + if (code == RevRequest.aACompromise.getValue()) + return RevocationReason.UNSPECIFIED; + else if (code == RevRequest.affiliationChanged.getValue()) + return RevocationReason.AFFILIATION_CHANGED; + else if (code == RevRequest.cACompromise.getValue()) + return RevocationReason.CA_COMPROMISE; + else if (code == RevRequest.certificateHold.getValue()) + return RevocationReason.CERTIFICATE_HOLD; + else if (code == RevRequest.cessationOfOperation.getValue()) + return RevocationReason.CESSATION_OF_OPERATION; + else if (code == RevRequest.keyCompromise.getValue()) + return RevocationReason.KEY_COMPROMISE; + else if (code == RevRequest.privilegeWithdrawn.getValue()) + return RevocationReason.UNSPECIFIED; + else if (code == RevRequest.removeFromCRL.getValue()) + return RevocationReason.REMOVE_FROM_CRL; + else if (code == RevRequest.superseded.getValue()) + return RevocationReason.SUPERSEDED; + else if (code == RevRequest.unspecified.getValue()) + return RevocationReason.UNSPECIFIED; + return RevocationReason.UNSPECIFIED; + } + + private boolean verifyRevRequestSignature(SignedData msgData) { + try { + EncapsulatedContentInfo ci = msgData.getContentInfo(); + OCTET_STRING content = ci.getContent(); + ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray()); + TaggedAttribute tattr = (TaggedAttribute) (new TaggedAttribute.Template()).decode(s); + SET values = tattr.getValues(); + RevRequest revRequest = null; + if (values != null && values.size() > 0) + revRequest = + (RevRequest) (ASN1Util.decode(new RevRequest.Template(), + ASN1Util.encode(values.elementAt(0)))); + + SET dias = msgData.getDigestAlgorithmIdentifiers(); + int numDig = dias.size(); + Hashtable<String, byte[]> digs = new Hashtable<String, byte[]>(); + for (int i = 0; i < numDig; i++) { + AlgorithmIdentifier dai = + (AlgorithmIdentifier) dias.elementAt(i); + String name = + DigestAlgorithm.fromOID(dai.getOID()).toString(); + MessageDigest md = + MessageDigest.getInstance(name); + byte[] digest = md.digest(content.toByteArray()); + digs.put(name, digest); + } + + SET sis = msgData.getSignerInfos(); + int numSis = sis.size(); + for (int i = 0; i < numSis; i++) { + org.mozilla.jss.pkix.cms.SignerInfo si = + (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(i); + String name = si.getDigestAlgorithm().toString(); + byte[] digest = digs.get(name); + if (digest == null) { + MessageDigest md = MessageDigest.getInstance(name); + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + revRequest.encode((OutputStream) ostream); + digest = md.digest(ostream.toByteArray()); + } + SignerIdentifier sid = si.getSignerIdentifier(); + if (sid.getType().equals(SignerIdentifier.ISSUER_AND_SERIALNUMBER)) { + org.mozilla.jss.pkix.cms.IssuerAndSerialNumber issuerAndSerialNumber = + sid.getIssuerAndSerialNumber(); + java.security.cert.X509Certificate cert = null; + if (msgData.hasCertificates()) { + SET certs = msgData.getCertificates(); + int numCerts = certs.size(); + for (int j = 0; j < numCerts; j++) { + org.mozilla.jss.pkix.cert.Certificate certJss = + (Certificate) certs.elementAt(j); + org.mozilla.jss.pkix.cert.CertificateInfo certI = + certJss.getInfo(); + Name issuer = certI.getIssuer(); + byte[] issuerB = ASN1Util.encode(issuer); + INTEGER sn = certI.getSerialNumber(); + if (new String(issuerB).equalsIgnoreCase(new String(ASN1Util.encode(issuerAndSerialNumber + .getIssuer()))) && + sn.toString().equals(issuerAndSerialNumber.getSerialNumber().toString())) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + certJss.encode(os); + cert = new X509CertImpl(os.toByteArray()); + break; + } + } + } + + if (cert != null) { + PublicKey pbKey = cert.getPublicKey(); + String type = ((X509Key) pbKey).getAlgorithm(); + PrivateKey.Type kType = PrivateKey.RSA; + if (type.equals("DSA")) + kType = PrivateKey.DSA; + PK11PubKey pubK = PK11PubKey.fromRaw(kType, ((X509Key) pbKey).getKey()); + si.verify(digest, ci.getContentType(), pubK); + return true; + } + } + } + + return false; + } catch (Exception e) { + CMS.debug("CMCOutputTemplate: verifyRevRequestSignature. Exception: " + e.toString()); + return false; + } + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/CMSFile.java b/base/common/src/com/netscape/cms/servlet/common/CMSFile.java new file mode 100644 index 000000000..4d7c4cdd6 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/CMSFile.java @@ -0,0 +1,102 @@ +// --- 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.common; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.logging.ILogger; + +/** + * CMSFile represents a file from the filesystem cached in memory + * + * @version $Revision$, $Date$ + */ +public class CMSFile { + protected String mAbsPath; + protected long mLastModified; + protected byte[] mContent; + protected long mLastAccess = 0; + + protected ILogger mLogger = CMS.getLogger(); + + protected CMSFile() { + } + + public CMSFile(File file) throws IOException, EBaseException { + mAbsPath = file.getAbsolutePath(); + mLastModified = file.lastModified(); + fillContent(file); + } + + private void fillContent(File file) throws IOException { + int fileSize = (int) file.length(); + + mContent = new byte[fileSize]; + FileInputStream fileIn = new FileInputStream(file); + int actualSize = fileIn.read(mContent); + fileIn.close(); + + if (actualSize != fileSize) { + byte[] actualContent = new byte[actualSize]; + + System.arraycopy(mContent, 0, actualContent, 0, actualSize); + mContent = actualContent; + } + } + + public String getAbsPath() { + return mAbsPath; + } + + public byte[] getContent() { + return mContent; + } + + public long getLastModified() { + return mLastModified; + } + + public synchronized long getLastAccess() { + return mLastAccess; + } + + public synchronized void setLastAccess(long lastAccess) { + mLastAccess = lastAccess; + } + + protected void log(int level, String msg) { + mLogger.log(ILogger.EV_SYSTEM, level, ILogger.S_OTHER, "CMSgateway:" + msg); + } + + public String toString() { + try { + return new String(mContent, "UTF8"); + } catch (UnsupportedEncodingException e) { + return new String(mContent); + } + } + + public String toString(String enc) throws UnsupportedEncodingException { + return new String(mContent, enc); + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java b/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java new file mode 100644 index 000000000..808bdda78 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java @@ -0,0 +1,160 @@ +// --- 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.common; + +import java.io.File; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Hashtable; + +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; + +/** + * CMSFileLoader - file cache. + * + * @version $Revision$, $Date$ + */ + +public class CMSFileLoader { + // default max size + public final int MAX_SIZE = 200; + // default number of files to clear when max is reached. + public final int CLEAR_SIZE = 50; + // max size property + public final String PROP_MAX_SIZE = "maxSize"; + // clear size property + public final String PROP_CLEAR_SIZE = "clearSize"; + // property to cache templates only + public final String PROP_CACHE_TEMPLATES_ONLY = "cacheTemplatesOnly"; + + // hash of files to their content. + private Hashtable<String, CMSFile> mLoadedFiles = new Hashtable<String, CMSFile>(); + + // max number of files + private int mMaxSize = MAX_SIZE; + + // number of files to clear when max is reached. + private int mClearSize = CLEAR_SIZE; + + // whether to cache templates and forms only. + private boolean mCacheTemplatesOnly = true; + + public CMSFileLoader() { + } + + public void init(IConfigStore config) throws EBaseException { + mMaxSize = config.getInteger(PROP_MAX_SIZE, MAX_SIZE); + mClearSize = config.getInteger(PROP_CLEAR_SIZE, CLEAR_SIZE); + mCacheTemplatesOnly = + config.getBoolean(PROP_CACHE_TEMPLATES_ONLY, true); + } + + // Changed by bskim + //public byte[] get(String absPath) throws EBaseException, IOException { + // File file = new File(absPath); + // return get(file); + //} + public byte[] get(String absPath, String enc) throws EBaseException, IOException { + File file = new File(absPath); + + return get(file, enc); + } + + // Change end + + // Changed by bskim + //public byte[] get(File file) throws EBaseException, IOException { + // CMSFile cmsFile = getCMSFile(file); + public byte[] get(File file, String enc) throws EBaseException, IOException { + CMSFile cmsFile = getCMSFile(file, enc); + + // Change end + return cmsFile.getContent(); + } + + // Changed by bskim + //public CMSFile getCMSFile(File file) throws EBaseException, IOException { + public CMSFile getCMSFile(File file, String enc) throws EBaseException, IOException { + // Change end + String absPath = file.getAbsolutePath(); + long modified = file.lastModified(); + CMSFile cmsFile = (CMSFile) mLoadedFiles.get(absPath); + long lastModified = (cmsFile == null ? 0 : cmsFile.getLastModified()); + + // new file. + if (cmsFile == null || modified != lastModified) { + // Changed by bskim + //cmsFile = updateFile(absPath, file); + cmsFile = updateFile(absPath, file, enc); + // Change end + } + cmsFile.setLastAccess(System.currentTimeMillis()); + return cmsFile; + } + + // Changed by bskim + //private CMSFile updateFile(String absPath, File file) + private CMSFile updateFile(String absPath, File file, String enc) + // Change end + throws EBaseException, IOException { + // clear if cache size exceeded. + if (mLoadedFiles.size() >= mMaxSize) { + clearSomeFiles(); + } + + CMSFile cmsFile = null; + + // check if file is a js template or plain template by its first String + if (absPath.endsWith(CMSTemplate.SUFFIX)) { + // Changed by bskim + //cmsFile = new CMSTemplate(file); + cmsFile = new CMSTemplate(file, enc); + // End of Change + } else { + cmsFile = new CMSFile(file); + } + mLoadedFiles.put(absPath, cmsFile); // replace old one if any. + return cmsFile; + } + + private synchronized void clearSomeFiles() { + + // recheck this in case some other thread has cleared it. + if (mLoadedFiles.size() < mMaxSize) + return; + + // remove the LRU files. + // XXX could be optimized more. + Enumeration<CMSFile> elements = mLoadedFiles.elements(); + + for (int i = mClearSize; i > 0; i--) { + long lru = java.lang.Long.MAX_VALUE; + CMSFile lruFile = null; + + while (elements.hasMoreElements()) { + CMSFile cmsFile = elements.nextElement(); + + if (cmsFile.getLastAccess() < lru) { + lruFile = cmsFile; + } + mLoadedFiles.remove(lruFile.getAbsPath()); + } + } + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java b/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java new file mode 100644 index 000000000..7ae242ae7 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java @@ -0,0 +1,44 @@ +// --- 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.common; + +import java.util.ListResourceBundle; + +/** + * A class represents a resource bundle for cms gateway. + * <P> + * + * @version $Revision$, $Date$ + * @see java.util.ListResourceBundle + */ +public class CMSGWResources extends ListResourceBundle { + + /** + * Returns the content of this resource. + */ + public Object[][] getContents() { + return contents; + } + + /* + * Constants. The suffix represents the number of + * possible parameters. + */ + + static final Object[][] contents = {}; +} diff --git a/base/common/src/com/netscape/cms/servlet/common/CMSGateway.java b/base/common/src/com/netscape/cms/servlet/common/CMSGateway.java new file mode 100644 index 000000000..20743022a --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/CMSGateway.java @@ -0,0 +1,372 @@ +// --- 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.common; + +import java.io.File; +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Locale; +import java.util.StringTokenizer; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.AuthToken; +import com.netscape.certsrv.authentication.IAuthCredentials; +import com.netscape.certsrv.authentication.IAuthManager; +import com.netscape.certsrv.authentication.IAuthSubsystem; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.logging.ILogger; + +/** + * This class is to hold some general method for servlets. + * + * @version $Revision$, $Date$ + */ +public class CMSGateway { + public final static String PROP_CMSGATEWAY = "cmsgateway"; + private final static String PROP_ENABLE_ADMIN_ENROLL = "enableAdminEnroll"; + + private final static String PROP_SERVER_XML = "server.xml"; + public static final String CERT_ATTR = + "javax.servlet.request.X509Certificate"; + + protected static CMSFileLoader mFileLoader = new CMSFileLoader(); + + protected static boolean mEnableFileServing; + private static boolean mEnableAdminEnroll = true; + private static IConfigStore mConfig = null; + + // system logger. + protected static ILogger mLogger = CMS.getLogger(); + + static { + mEnableFileServing = true; + mConfig = CMS.getConfigStore().getSubStore(PROP_CMSGATEWAY); + try { + mEnableAdminEnroll = + mConfig.getBoolean(PROP_ENABLE_ADMIN_ENROLL, false); + } catch (EBaseException e) { + mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE, + CMS.getLogMessage("CMSGW_BAD_CONFIG_PARAM")); + } + } + + public CMSGateway() { + } + + public static Hashtable<String, String> toHashtable(HttpServletRequest req) { + Hashtable<String, String> httpReqHash = new Hashtable<String, String>(); + @SuppressWarnings("unchecked") + Enumeration<String> names = req.getParameterNames(); + + while (names.hasMoreElements()) { + String name = names.nextElement(); + + httpReqHash.put(name, req.getParameter(name)); + } + + String ip = req.getRemoteAddr(); + if (ip != null) + httpReqHash.put("clientHost", ip); + return httpReqHash; + } + + public static boolean getEnableAdminEnroll() { + return mEnableAdminEnroll; + } + + public static void setEnableAdminEnroll(boolean enableAdminEnroll) + throws EBaseException { + IConfigStore mainConfig = CMS.getConfigStore(); + + //!!! Is it thread safe? xxxx + mEnableAdminEnroll = enableAdminEnroll; + mConfig.putBoolean(PROP_ENABLE_ADMIN_ENROLL, enableAdminEnroll); + mainConfig.commit(true); + } + + public static void disableAdminEnroll() throws EBaseException { + setEnableAdminEnroll(false); + + /* need to do this in web.xml and restart ws + removeServlet("/ca/adminEnroll", "AdminEnroll"); + initGateway(); + */ + } + + /** + * construct a authentication credentials to pass into authentication + * manager. + */ + public static AuthCredentials getAuthCreds( + IAuthManager authMgr, IArgBlock argBlock, X509Certificate clientCert) + throws EBaseException { + // get credentials from http parameters. + if (authMgr == null) + return null; + String[] reqCreds = authMgr.getRequiredCreds(); + AuthCredentials creds = new AuthCredentials(); + + if (clientCert instanceof java.security.cert.X509Certificate) { + try { + clientCert = new netscape.security.x509.X509CertImpl(clientCert.getEncoded()); + } catch (Exception e) { + CMS.debug("CMSGateway: getAuthCreds " + e.toString()); + } + } + + for (int i = 0; i < reqCreds.length; i++) { + String reqCred = reqCreds[i]; + + if (reqCred.equals(IAuthManager.CRED_SSL_CLIENT_CERT)) { + // cert could be null; + creds.set(reqCred, new X509Certificate[] { clientCert } + ); + } else { + String value = argBlock.getValueAsString(reqCred); + + creds.set(reqCred, value); // value could be null; + } + } + + creds.set("clientHost", argBlock.getValueAsString("clientHost")); + // Inserted by bskim + creds.setArgBlock(argBlock); + // Insert end + return creds; + } + + protected final static String AUTHMGR_PARAM = "authenticator"; + + public static AuthToken checkAuthManager( + HttpServletRequest httpReq, IArgBlock httpParams, + X509Certificate cert, String authMgrName) + throws EBaseException { + IArgBlock httpArgs = httpParams; + + if (httpArgs == null) + httpArgs = CMS.createArgBlock(toHashtable(httpReq)); + + IAuthSubsystem authSub = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH); + + String authMgr_http = httpArgs.getValueAsString( + AUTHMGR_PARAM, null); + + if (authMgr_http != null) { + authMgrName = authMgr_http; + } + + if (authMgrName == null || authMgrName.length() == 0) { + throw new EBaseException(CMS.getLogMessage("BASE_INTERNAL_ERROR_1", + CMS.getLogMessage("CMSGW_AUTH_MAN_EXPECTED"))); + } + + IAuthManager authMgr = + authSub.getAuthManager(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID); + + authMgr = authSub.getAuthManager(authMgrName); + if (authMgr == null) + return null; + IAuthCredentials creds = + getAuthCreds(authMgr, CMS.createArgBlock(toHashtable(httpReq)), cert); + AuthToken authToken = null; + + try { + authToken = (AuthToken) authMgr.authenticate(creds); + } catch (EBaseException e) { + throw e; + } catch (Exception e) { + CMS.debug("CMSGateway: " + e); + // catch all errors from authentication manager. + throw new ECMSGWException(CMS.getLogMessage("CMSGW_AUTH_ERROR_2", + e.toString(), e.getMessage())); + } + return authToken; + } + + public static void renderTemplate( + String templateName, + HttpServletRequest req, + HttpServletResponse resp, + ServletConfig servletConfig, + CMSFileLoader fileLoader) + throws EBaseException, IOException { + CMSTemplate template = + getTemplate(templateName, req, + servletConfig, fileLoader, new Locale[1]); + ServletOutputStream out = resp.getOutputStream(); + + template.renderOutput(out, new CMSTemplateParams(null, null)); + } + + // XXX TBD move this to a utility function too. + + public static Locale getLocale(String lang) { + int dash = lang.indexOf('-'); + + if (dash == -1) + return new Locale(lang, ""); + else + return new Locale(lang.substring(0, dash), lang.substring(dash + 1)); + } + + /** + * @param req http servlet request + * @param realpathFile the file to get. + * @param locale array of at least one to be filled with locale found. + */ + public static File getLangFile( + HttpServletRequest req, File realpathFile, Locale[] locale) + throws IOException { + File file = null; + String acceptLang = req.getHeader("accept-language"); + + if (acceptLang != null && !acceptLang.equals("")) { + StringTokenizer tokenizer = new StringTokenizer(acceptLang, ","); + int numLangs = tokenizer.countTokens(); + + if (numLangs > 0) { + // languages are searched in order. + String parent = realpathFile.getParent(); + + if (parent == null) { + parent = "." + File.separatorChar; + } + String name = realpathFile.getName(); + + if (name == null) { // filename should never be null. + throw new IOException("file has no name"); + } + int i; + + for (i = 0; i < numLangs; i++) { + String lang = null; + String token = tokenizer.nextToken(); + + int semicolon = token.indexOf(';'); + + if (semicolon == -1) { + lang = token.trim(); + } else { + if (semicolon < 2) + continue; // protocol error. + lang = token.substring(0, semicolon).trim(); + } + // if browser locale is the same as default locale, + // use the default form. (is this the right thing to do ?) + Locale l = getLocale(lang); + + if (Locale.getDefault().equals(l)) { + locale[0] = l; + file = realpathFile; + break; + } + + String langfilepath = + parent + File.separatorChar + + lang + File.separatorChar + name; + + file = new File(langfilepath); + if (file.exists()) { + locale[0] = getLocale(lang); + break; + } + } + // if no file for lang was found use default + if (i == numLangs) { + file = realpathFile; + locale[0] = Locale.getDefault(); + } + } + } else { + // use default if accept-language is not availabe + file = realpathFile; + locale[0] = Locale.getDefault(); + } + return file; + } + + /** + * get a template + */ + protected static CMSTemplate getTemplate( + String templateName, + HttpServletRequest httpReq, + ServletConfig servletConfig, + CMSFileLoader fileLoader, + Locale[] locale) + throws EBaseException, IOException { + // this converts to system dependent file seperator char. + if (servletConfig == null) { + CMS.debug("CMSGateway:getTemplate() - servletConfig is null!"); + return null; + } + if (servletConfig.getServletContext() == null) { + } + if (templateName == null) { + } + String realpath = + servletConfig.getServletContext().getRealPath("/" + templateName); + File realpathFile = new File(realpath); + File templateFile = + getLangFile(httpReq, realpathFile, locale); + CMSTemplate template = + //(CMSTemplate)fileLoader.getCMSFile(templateFile); + (CMSTemplate) fileLoader.getCMSFile(templateFile, httpReq.getCharacterEncoding()); + + return template; + } + + /** + * Get the If-Modified-Since header and compare it to the millisecond + * epoch value passed in. If there is no header, or there is a problem + * parsing the value, or if the file has been modified this will return + * true, indicating the file has changed. + * + * @param lastModified The time value in milliseconds past the epoch to + * compare the If-Modified-Since header to. + */ + public static boolean modifiedSince(HttpServletRequest req, long lastModified) { + long ifModSinceStr; + + try { + ifModSinceStr = req.getDateHeader("If-Modified-Since"); + } catch (IllegalArgumentException e) { + return true; + } + + if (ifModSinceStr < 0) { + return true; + } + + if (ifModSinceStr < lastModified) { + return true; // Data must be resent + } + + return false; // Data has not been modified + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java b/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java new file mode 100644 index 000000000..62276df14 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java @@ -0,0 +1,60 @@ +// --- 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.common; + +/** + * handy class containing cms templates to load & fill. + * + * @version $Revision$, $Date$ + */ +public class CMSLoadTemplate { + public String mPropName; + public String mFillerPropName; + public String mTemplateName; + public ICMSTemplateFiller mFiller; + + public CMSLoadTemplate() { + } + + public CMSLoadTemplate( + String propName, String fillerPropName, + String templateName, ICMSTemplateFiller filler) { + + mPropName = propName; + mFillerPropName = fillerPropName; + mTemplateName = templateName; + mFiller = filler; + } + + public String getPropName() { + return mPropName; + } + + public String getFillerPropName() { + return mFillerPropName; + } + + public String getTemplateName() { + return mTemplateName; + } + + public ICMSTemplateFiller getTemplateFiller() { + return mFiller; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java b/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java new file mode 100644 index 000000000..256c01010 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java @@ -0,0 +1,300 @@ +// --- 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.common; + +import java.util.Hashtable; +import java.util.Vector; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestStatus; + +/** + * This represents a user request. + * + * @version $Revision$, $Date$ + */ +public class CMSRequest { + // statuses. the first two are out of band. + public static final Integer UNAUTHORIZED = Integer.valueOf(1); + public static final Integer SUCCESS = Integer.valueOf(2); + public static final Integer PENDING = Integer.valueOf(3); + public static final Integer SVC_PENDING = Integer.valueOf(4); + public static final Integer REJECTED = Integer.valueOf(5); + public static final Integer ERROR = Integer.valueOf(6); + public static final Integer EXCEPTION = Integer.valueOf(7); // unexpected error. + + private static final String RESULT = "cmsRequestResult"; + + // Reason message for request failure + private String reason = null; + + // http parameters - handier than getting directly from http request. + private IArgBlock mHttpParams = null; + + // http headers & other info. + private HttpServletRequest mHttpReq = null; + + // http response. + private HttpServletResponse mHttpResp = null; + + // http servlet config. + private ServletConfig mServletConfig = null; + + // http servlet context. + private ServletContext mServletContext = null; + + // permanent request in request queue. + private IRequest mRequest = null; + + // whether request processed successfully + private Integer mStatus = SUCCESS; + + // exception message containing error that occured. + // note exception could also be thrown seperately. + private String mError = null; + + // any error description. + private Vector<String> mErrorDescr = null; + + // any request resulting data; + Object mResult = null; + Hashtable<String, Object> mResults = new Hashtable<String, Object>(); + + /** + * Constructor + */ + public CMSRequest() { + } + + // set methods use by servlets. + + /** + * set the HTTP parameters + */ + public void setHttpParams(IArgBlock httpParams) { + mHttpParams = httpParams; + } + + /** + * set the Request aobject associated with this session + */ + public void setIRequest(IRequest request) { + mRequest = request; + } + + /** + * set the HTTP Request object associated with this session + */ + public void setHttpReq(HttpServletRequest httpReq) { + mHttpReq = httpReq; + } + + /** + * set the HTTP Response object which is used to create the + * HTTP response which is sent back to the user + */ + public void setHttpResp(HttpServletResponse httpResp) { + mHttpResp = httpResp; + } + + /** + * set the servlet configuration. The servlet configuration is + * read from the WEB-APPS/web.xml file under the <servlet> + * XML definition. The parameters are delimited by init-param + * param-name/param-value options as described in the servlet + * documentation. + */ + public void setServletConfig(ServletConfig servletConfig) { + mServletConfig = servletConfig; + } + + /* + * set the servlet context. the servletcontext has detail + * about the currently running request + */ + public void setServletContext(ServletContext servletContext) { + mServletContext = servletContext; + } + + /** + * Set request status. + * + * @param status request status. Allowed values are + * UNAUTHORIZED, SUCCESS, REJECTED, PENDING, ERROR, SVC_PENDING + * @throws IllegalArgumentException if status is not one of the above values + */ + public void setStatus(Integer status) { + if (!status.equals(UNAUTHORIZED) && + !status.equals(SUCCESS) && + !status.equals(REJECTED) && + !status.equals(PENDING) && + !status.equals(ERROR) && + !status.equals(SVC_PENDING) && + !status.equals(EXCEPTION)) { + throw new IllegalArgumentException(CMS.getLogMessage("CMSGW_BAD_REQ_STATUS")); + } + mStatus = status; + } + + public void setError(EBaseException error) { + mError = error.toString(); + } + + public void setError(String error) { + mError = error; + } + + public void setErrorDescription(String descr) { + if (mErrorDescr == null) + mErrorDescr = new Vector<String>(); + mErrorDescr.addElement(descr); + } + + public void setResult(Object result) { + mResult = result; + mResults.put(RESULT, result); + } + + public void setResult(String name, Object result) { + mResults.put(name, result); + } + + public IArgBlock getHttpParams() { + return mHttpParams; + } + + public HttpServletRequest getHttpReq() { + return mHttpReq; + } + + public HttpServletResponse getHttpResp() { + return mHttpResp; + } + + public ServletConfig getServletConfig() { + return mServletConfig; + } + + public ServletContext getServletContext() { + return mServletContext; + } + + public IRequest getIRequest() { + return mRequest; + } + + public Integer getStatus() { + return mStatus; + } + + public String getError() { + return mError; + } + + public Vector<String> getErrorDescr() { + return mErrorDescr; + } + + public Object getResult() { + return mResult; + } + + public Object getResult(String name) { + return mResults.get(name); + } + + public void setReason(String reason) { + this.reason = reason; + } + + public String getReason() { + return reason; + } + + // handy routines for IRequest. + + public void setExtData(String type, String value) { + if (mRequest != null) { + mRequest.setExtData(type, value); + } + } + + public String getExtData(String type) { + if (mRequest != null) { + return mRequest.getExtDataInString(type); + } else { + return null; + } + } + + // policy errors; set on rejection or possibly deferral. + public Vector<String> getPolicyMessages() { + if (mRequest != null) { + return mRequest.getExtDataInStringVector(IRequest.ERRORS); + } + return null; + } + + /** + * set default CMS status according to IRequest status. + */ + public void setIRequestStatus() throws EBaseException { + if (mRequest == null) { + EBaseException e = + new ECMSGWException(CMS.getLogMessage("CMSGW_MISSING_REQUEST")); + + throw e; + } + + RequestStatus status = mRequest.getRequestStatus(); + + // completed equivalent to success by default. + if (status == RequestStatus.COMPLETE) { + mStatus = CMSRequest.SUCCESS; + return; + } + // unexpected resulting request status. + if (status == RequestStatus.REJECTED) { + mStatus = CMSRequest.REJECTED; + return; + } // pending or service pending. + else if (status == RequestStatus.PENDING) { + mStatus = CMSRequest.PENDING; + return; + } else if (status == RequestStatus.SVC_PENDING) { + mStatus = CMSRequest.SVC_PENDING; + return; + } else { + RequestId reqId = mRequest.getRequestId(); + + throw new ECMSGWException( + CMS.getLogMessage("CMSGW_UNEXPECTED_REQUEST_STATUS_2", + status.toString(), reqId.toString())); + } + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java b/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java new file mode 100644 index 000000000..317bddbcd --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java @@ -0,0 +1,609 @@ +// --- 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.common; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.util.Date; +import java.util.Enumeration; + +import javax.servlet.ServletOutputStream; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.logging.ILogger; + +/** + * File templates. This implementation will take + * an HTML file with a special customer tag + * <CMS_TEMPLATE> and replace the tag with + * a series of javascript variable definitions + * (depending on the servlet) + * + * @version $Revision$, $Date$ + */ +public class CMSTemplate extends CMSFile { + + public static final String SUFFIX = ".template"; + + /*========================================================== + * variables + *==========================================================*/ + + /* private variables */ + private String mTemplateFileName = ""; + private ILogger mLogger = CMS.getLogger(); + private long mTimeStamp; + + /* public vaiables */ + public String mPreOutput; + public String mPostOutput; + public static final String TEMPLATE_TAG = "<CMS_TEMPLATE>"; + + /* Character set for i18n */ + + /* Will be set by CMSServlet.getTemplate() */ + private String mCharset = null; + + /*========================================================== + * constructors + *==========================================================*/ + + /** + * Constructor + * + * @param file template file to load + * @param charset character set + * @throws IOException if the there was an error opening the file + */ + public CMSTemplate(File file, String charset) throws IOException, EBaseException { + mCharset = charset; + mAbsPath = file.getAbsolutePath(); + mLastModified = file.lastModified(); + try { + init(file); + } catch (IOException e) { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("CMSGW_CANT_LOAD_TEMPLATE", mAbsPath, e.toString())); + throw new ECMSGWException( + CMS.getLogMessage("CMSGW_ERROR_LOADING_TEMPLATE")); + } + String content = mPreOutput + mPostOutput; + + mContent = content.getBytes(mCharset); + } + + /*========================================================== + * public methods + *==========================================================*/ + + /* * + * Load the form from the file and setup the + * pre/post output buffer if it is a template + * file. Otherwise, only post output buffer is + * filled. + * @param template the template file to load + * @return true if successful + */ + public boolean init(File template) throws EBaseException, IOException { + /* load template */ + String content = loadFile(template); + + if (content == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_TEMPLATE_EMPTY", mAbsPath)); + throw new ECMSGWException( + CMS.getLogMessage("CMSGW_TEMPLATE_NO_CONTENT_1", mAbsPath)); + } + + /* time stamp */ + Date now = CMS.getCurrentDate(); + + mTimeStamp = now.getTime(); + + /* if template file, find template tag substring and set + * pre/post output string + */ + int location = content.indexOf(TEMPLATE_TAG); + + if (location == -1) { + log(ILogger.LL_FAILURE, CMS.getLogMessage( + "CMSGW_TEMPLATE_MISSING", mAbsPath, TEMPLATE_TAG)); + throw new ECMSGWException( + CMS.getLogMessage("CMSGW_MISSING_TEMPLATE_TAG_2", + TEMPLATE_TAG, mAbsPath)); + } + mPreOutput = content.substring(0, location); + mPostOutput = content.substring(TEMPLATE_TAG.length() + location); + + return true; + } + + /** + * Write a javascript representation of 'input' + * surrounded by SCRIPT tags to the outputstream + * + * @param rout the outputstream to write to + * @param input the parameters to write + */ + public void renderOutput(OutputStream rout, CMSTemplateParams input) + throws IOException { + Enumeration<String> e = null; + Enumeration<IArgBlock> q = null; + IArgBlock r = null; + CMSTemplateParams data = (CMSTemplateParams) input; + HTTPOutputStreamWriter http_out = null; + + if (mCharset == null) + http_out = new HTTPOutputStreamWriter(rout); + else + http_out = new HTTPOutputStreamWriter(rout, mCharset); + + try { + templateLine out = new templateLine(); + + // Output the prolog + out.print(mPreOutput); + + // Output the header data + out.println("<SCRIPT LANGUAGE=\"JavaScript\">"); + out.println("var header = new Object();"); + out.println("var fixed = new Object();"); + out.println("var recordSet = new Array;"); + out.println("var result = new Object();"); + + // hack + out.println("var httpParamsCount = 0;"); + out.println("var httpHeadersCount = 0;"); + out.println("var authTokenCount = 0;"); + out.println("var serverAttrsCount = 0;"); + out.println("header.HTTP_PARAMS = new Array;"); + out.println("header.HTTP_HEADERS = new Array;"); + out.println("header.AUTH_TOKEN = new Array;"); + out.println("header.SERVER_ATTRS = new Array;"); + + r = data.getHeader(); + if (r != null) { + e = r.elements(); + while (e.hasMoreElements()) { + String n = e.nextElement(); + Object v = r.getValue(n); + + out.println("header." + n + " = " + renderValue(v) + ";"); + } + } + + // Output the fixed data + r = data.getFixed(); + if (r != null) { + e = r.elements(); + while (e.hasMoreElements()) { + String n = e.nextElement(); + Object v = r.getValue(n); + + out.println("fixed." + n + " = " + renderValue(v) + ";"); + } + } + + // Output the query data + q = data.queryRecords(); + if (q != null && q.hasMoreElements()) { + out.println("var recordCount = 0;"); + out.println("var record;"); + while (q.hasMoreElements()) { + out.println("record = new Object;"); + out.println("record.HTTP_PARAMS = new Array;"); + out.println("record.HTTP_HEADERS = new Array;"); + out.println("record.AUTH_TOKEN = new Array;"); + out.println("record.SERVER_ATTRS = new Array;"); + + // Get a query record + r = q.nextElement(); + e = r.elements(); + while (e.hasMoreElements()) { + String n = e.nextElement(); + Object v = r.getValue(n); + + out.println("record." + n + "=" + renderValue(v) + ";"); + } + out.println("recordSet[recordCount++] = record;"); + } + out.println("record.recordSet = recordSet;"); + } + + //if (headerBlock) + out.println("result.header = header;"); + //if (fixedBlock) + out.println("result.fixed = fixed;"); + //if (queryBlock) + out.println("result.recordSet = recordSet;"); + out.println("</SCRIPT>"); + out.println(mPostOutput); + http_out.print(out.toString()); + + } catch (EBaseException ex) { + throw new IOException(ex.getMessage()); + } + } + + /** + * Ouput the pre-amble HTML Header including + * the pre-output buffer. + * + * @param out output stream specified + * @return success or error + */ + public boolean outputProlog(PrintWriter out) { + + //Debug.trace("FormCache:outputProlog"); + + /* output pre-output buffer */ + out.print(mPreOutput); + + /* output JavaScript variables and objects */ + out.println("<SCRIPT LANGUAGE=\"JavaScript\">"); + out.println("var header = new Object();"); + out.println("var result = new Object();"); + + return true; + } + + /** + * Output the post HTML tags and post-output + * buffer. + * + * @param out output stream specified + * @return success or error + */ + public boolean outputEpilog(PrintWriter out) { + + out.println("</SCRIPT>"); + out.println(mPostOutput); + + return true; + } + + /** + * @return full path of template + */ + public String getTemplateName() { + return mAbsPath; + } + + // inherit getabspath, getContent, get last access and set last access + + /*========================================================== + * private methods + *==========================================================*/ + + /* load file into string */ + private String loadFile(File template) throws IOException { + + // Debug.trace("FormCache:loadFile"); + + /* create input stream, can throw IOException */ + FileInputStream inStream = new FileInputStream(template); + InputStreamReader inReader = new InputStreamReader(inStream, mCharset); + ; + BufferedReader in = new BufferedReader(inReader); + StringBuffer buf = new StringBuffer(); + String line; + + while ((line = in.readLine()) != null) { + buf.append(line); + buf.append('\n'); + } + try { + in.close(); + inStream.close(); + } catch (IOException e) { + log(ILogger.LL_WARN, + CMS.getLogMessage("CMSGW_ERR_CLOSE_TEMPL_FILE", mAbsPath, e.getMessage())); + } + return buf.toString(); + } + + private String renderValue(Object v) { + String s = null; + + // Figure out the type of object + if (v instanceof IRawJS) { + s = v.toString(); + } else if (v instanceof String) { + if (v.equals("")) + s = "null"; + else + s = "\"" + escapeJavaScriptString((String) v) + "\""; + } else if (v instanceof Integer) { + s = ((Integer) v).toString(); + } else if (v instanceof Boolean) { + + if (((Boolean) v).booleanValue() == true) { + s = "true"; + } else { + s = "false"; + } + } else if (v instanceof BigInteger) { + s = ((BigInteger) v).toString(10); + } else if (v instanceof Character && + ((Character) v).equals(Character.valueOf((char) 0))) { + s = "null"; + } else { + s = "\"" + v.toString() + "\""; + } + + return s; + } + + /** + * Escape the contents of src string in preparation to be enclosed in + * double quotes as a JavaScript String Literal within an <script> + * portion of an HTML document. + * stevep - performance improvements - about 4 times faster than before. + */ + public static String escapeJavaScriptString(String v) { + int l = v.length(); + char in[] = new char[l]; + char out[] = new char[l * 4]; + int j = 0; + + v.getChars(0, l, in, 0); + + for (int i = 0; i < l; i++) { + char c = in[i]; + + if ((c > 0x23) && (c != 0x5c) && (c != 0x3c) && (c != 0x3e)) { + out[j++] = c; + continue; + } + + if ((c == 0x5c) && ((i + 1) < l) && (in[i + 1] == 'n' || + in[i + 1] == 'r' || in[i + 1] == 'f' || in[i + 1] == 't' || + in[i + 1] == '<' || in[i + 1] == '>' || + in[i + 1] == '\"' || in[i + 1] == '\'' || in[i + 1] == '\\')) { + if (in[i + 1] == 'x' && ((i + 3) < l) && in[i + 2] == '3' && + (in[i + 3] == 'c' || in[i + 3] == 'e')) { + out[j++] = '\\'; + out[j++] = in[i + 1]; + out[j++] = in[i + 2]; + out[j++] = in[i + 3]; + i += 3; + } else { + out[j++] = '\\'; + out[j++] = in[i + 1]; + i++; + } + continue; + } + + switch (c) { + case '\n': + out[j++] = '\\'; + out[j++] = 'n'; + break; + + case '\\': + out[j++] = '\\'; + out[j++] = '\\'; + break; + + case '\"': + out[j++] = '\\'; + out[j++] = '\"'; + break; + + case '\r': + out[j++] = '\\'; + out[j++] = 'r'; + break; + + case '\f': + out[j++] = '\\'; + out[j++] = 'f'; + break; + + case '\t': + out[j++] = '\\'; + out[j++] = 't'; + break; + + case '<': + out[j++] = '\\'; + out[j++] = 'x'; + out[j++] = '3'; + out[j++] = 'c'; + break; + + case '>': + out[j++] = '\\'; + out[j++] = 'x'; + out[j++] = '3'; + out[j++] = 'e'; + break; + + default: + out[j++] = c; + } + } + return new String(out, 0, j); + } + + /** + * Like escapeJavaScriptString(String s) but also escape '[' for + * HTML processing. + */ + public static String escapeJavaScriptStringHTML(String v) { + int l = v.length(); + char in[] = new char[l]; + char out[] = new char[l * 4]; + int j = 0; + + v.getChars(0, l, in, 0); + + for (int i = 0; i < l; i++) { + char c = in[i]; + + if (c > 0x5C) { + out[j++] = c; + continue; + } + + if ((c == 0x5c) && ((i + 1) < l) && (in[i + 1] == 'n' || + in[i + 1] == 'r' || in[i + 1] == 'f' || in[i + 1] == 't' || + in[i + 1] == '<' || in[i + 1] == '>' || + in[i + 1] == '\"' || in[i + 1] == '\'' || in[i + 1] == '\\')) { + if (in[i + 1] == 'x' && ((i + 3) < l) && in[i + 2] == '3' && + (in[i + 3] == 'c' || in[i + 3] == 'e')) { + out[j++] = '\\'; + out[j++] = in[i + 1]; + out[j++] = in[i + 2]; + out[j++] = in[i + 3]; + i += 3; + } else { + out[j++] = '\\'; + out[j++] = in[i + 1]; + i++; + } + continue; + } + + switch (c) { + case '\n': + out[j++] = '\\'; + out[j++] = 'n'; + break; + + case '\\': + out[j++] = '\\'; + out[j++] = '\\'; + break; + + case '\"': + out[j++] = '\\'; + out[j++] = '\"'; + break; + + case '\r': + out[j++] = '\\'; + out[j++] = 'r'; + break; + + case '\f': + out[j++] = '\\'; + out[j++] = 'f'; + break; + + case '\t': + out[j++] = '\\'; + out[j++] = 't'; + break; + + case '<': + out[j++] = '\\'; + out[j++] = 'x'; + out[j++] = '3'; + out[j++] = 'c'; + break; + case '>': + out[j++] = '\\'; + out[j++] = 'x'; + out[j++] = '3'; + out[j++] = 'e'; + break; + + default: + out[j++] = c; + } + } + return new String(out, 0, j); + } + + /** + * for debugging, return contents that would've been outputed. + */ + public String getOutput(CMSTemplateParams input) + throws IOException { + debugOutputStream out = new debugOutputStream(); + + renderOutput(out, input); + return out.toString(); + } + + private class HTTPOutputStreamWriter extends OutputStreamWriter { + public HTTPOutputStreamWriter(OutputStream out) + throws UnsupportedEncodingException { + super(out); + } + + public HTTPOutputStreamWriter(OutputStream out, String enc) + throws UnsupportedEncodingException { + super(out, enc); + } + + public void print(String s) throws IOException { + write(s, 0, s.length()); + flush(); + return; + } + } + + private class templateLine { + private StringBuffer s = new StringBuffer(); + + void println(String p) { + s.append('\n'); + s.append(p); + } + + void print(String p) { + s.append(p); + } + + public String toString() { + return s.toString(); + } + + } + + private static class debugOutputStream extends ServletOutputStream { + private StringWriter mStringWriter = new StringWriter(); + + public debugOutputStream() { + super(); + } + + public void write(int b) throws IOException { + mStringWriter.write(b); + } + + public String toString() { + return mStringWriter.toString(); + } + + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java b/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java new file mode 100644 index 000000000..ce2c26c3c --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java @@ -0,0 +1,70 @@ +// --- 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.common; + +import java.util.Enumeration; +import java.util.Vector; + +import com.netscape.certsrv.base.IArgBlock; + +/** + * Holds template parameters + * + * @version $Revision$, $Date$ + */ +public class CMSTemplateParams { + private IArgBlock mHeader = null; + private IArgBlock mFixed = null; + private Vector<IArgBlock> mRepeat = new Vector<IArgBlock>(); + + public CMSTemplateParams() { + } + + public CMSTemplateParams(IArgBlock header, IArgBlock fixed) { + mHeader = header; + mFixed = fixed; + } + + public void setHeader(IArgBlock h) { + mHeader = h; + } + + public IArgBlock getHeader() { + return mHeader; + } + + public void setFixed(IArgBlock f) { + mFixed = f; + } + + public IArgBlock getFixed() { + return mFixed; + } + + public void addRepeatRecord(IArgBlock r) { + mRepeat.addElement(r); + } + + public void clearRepeatRecords() { + mRepeat = new Vector<IArgBlock>(); + } + + public Enumeration<IArgBlock> queryRecords() { + return mRepeat.elements(); + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java b/base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java new file mode 100644 index 000000000..e8b848f7d --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java @@ -0,0 +1,74 @@ +// --- 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.common; + +import com.netscape.certsrv.base.EBaseException; + +/** + * A class represents a CMS gateway exception. + * <P> + * + * @version $Revision$, $Date$ + */ +public class ECMSGWException extends EBaseException { + + /** + * + */ + private static final long serialVersionUID = 7546430025179838019L; + /** + * CA resource class name. + */ + private static final String CMSGW_RESOURCES = CMSGWResources.class.getName(); + + /** + * Constructs a CMS Gateway exception. + * <P> + */ + public ECMSGWException(String msgFormat) { + super(msgFormat); + } + + /** + * Constructs a CMSGW exception. + * <P> + */ + public ECMSGWException(String msgFormat, String param) { + super(msgFormat, param); + } + + /** + * Constructs a CMSGW exception. + * <P> + */ + public ECMSGWException(String msgFormat, Exception e) { + super(msgFormat, e); + } + + /** + * Constructs a CMSGW exception. + * <P> + */ + public ECMSGWException(String msgFormat, Object params[]) { + super(msgFormat, params); + } + + protected String getBundleName() { + return CMSGW_RESOURCES; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java new file mode 100644 index 000000000..40edb3bda --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java @@ -0,0 +1,102 @@ +// --- 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.common; + +import java.util.Enumeration; +import java.util.Locale; +import java.util.Vector; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authority.IAuthority; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IArgBlock; + +/** + * Default error template filler + * + * @version $Revision$, $Date$ + */ +public class GenErrorTemplateFiller implements ICMSTemplateFiller { + public GenErrorTemplateFiller() { + } + + /** + * fill error details and description if any. + * + * @param cmsReq the CMS Request. + * @param authority the authority + * @param locale the locale of template. + * @param e unexpected error. ignored. + */ + public CMSTemplateParams getTemplateParams( + CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) { + IArgBlock fixed = CMS.createArgBlock(); + CMSTemplateParams params = new CMSTemplateParams(null, fixed); + + // request status if any. + if (cmsReq != null) { + Integer sts = cmsReq.getStatus(); + + if (sts != null) + fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString()); + } else { + CMS.debug("GenErrorTemplateFiller::getTemplateParams() - " + + "cmsReq is null!"); + return null; + } + + // error + String ex = cmsReq.getError(); + + // Changed by beomsuk + /*if (ex == null) + ex = new EBaseException(CMS.getLogMessage("BASE_UNKNOWN_ERROR")); + fixed.set(ICMSTemplateFiller.ERROR, ex.toString(locale)); + */ + if ((ex == null) && (cmsReq.getReason() == null)) + ex = new EBaseException(CMS.getLogMessage("BASE_UNKNOWN_ERROR")).toString(); + else if (ex != null) + fixed.set(ICMSTemplateFiller.ERROR, ex); + else if (cmsReq.getReason() != null) + fixed.set(ICMSTemplateFiller.ERROR, cmsReq.getReason()); + // Change end + + // error description if any. + Vector<String> descr = cmsReq.getErrorDescr(); + + if (descr != null) { + Enumeration<String> num = descr.elements(); + + while (num.hasMoreElements()) { + String elem = num.nextElement(); + //System.out.println("Setting description "+elem.toString()); + IArgBlock argBlock = CMS.createArgBlock(); + + argBlock.set(ICMSTemplateFiller.ERROR_DESCR, + elem); + params.addRepeatRecord(argBlock); + } + } + + // this authority + if (authority != null) + fixed.set(ICMSTemplateFiller.AUTHORITY, + authority.getOfficialName()); + return params; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java new file mode 100644 index 000000000..1d479fef3 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java @@ -0,0 +1,287 @@ +// --- 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.common; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.Locale; + +import netscape.security.x509.X500Name; +import netscape.security.x509.X509CertImpl; + +import org.mozilla.jss.CryptoManager; +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.OtherInfo; +import org.mozilla.jss.pkix.cmc.PendInfo; +import org.mozilla.jss.pkix.cmc.ResponseBody; +import org.mozilla.jss.pkix.cmc.TaggedAttribute; +import org.mozilla.jss.pkix.cms.ContentInfo; +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.cms.SignerInfo; +import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; +import org.mozilla.jss.pkix.primitive.Name; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authority.IAuthority; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.ca.ICertificateAuthority; +import com.netscape.certsrv.ra.IRegistrationAuthority; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.RequestId; + +/** + * default Pending template filler + * + * @version $Revision$, $Date$ + */ +public class GenPendingTemplateFiller implements ICMSTemplateFiller { + public static String FULL_RESPONSE = "cmcFullEnrollmentResponse"; + + public GenPendingTemplateFiller() { + } + + /** + * fill error details and description if any. + * + * @param cmsReq CMS Request + * @param authority this authority + * @param locale locale of template. + * @param e unexpected exception e. ignored. + */ + public CMSTemplateParams getTemplateParams( + CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) { + IArgBlock fixed = CMS.createArgBlock(); + CMSTemplateParams params = new CMSTemplateParams(null, fixed); + + if (cmsReq == null) { + return null; + } + + // request status if any. + Integer sts = cmsReq.getStatus(); + + if (sts != null) + fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString()); + + // request id + IRequest req = cmsReq.getIRequest(); + + if (req != null) { + RequestId reqId = req.getRequestId(); + + fixed.set(ICMSTemplateFiller.REQUEST_ID, reqId); + // set pendInfo, CMCStatusInfo + IArgBlock httpParams = cmsReq.getHttpParams(); + + if (doFullResponse(httpParams)) { + SEQUENCE controlSeq = new SEQUENCE(); + int bpid = 1; + PendInfo pendInfo = new PendInfo(reqId.toString(), new + Date()); + OtherInfo otherInfo = new + OtherInfo(OtherInfo.PEND, null, pendInfo); + SEQUENCE bpids = new SEQUENCE(); + String[] reqIdArray = + req.getExtDataInStringArray(IRequest.CMC_REQIDS); + + for (int i = 0; i < reqIdArray.length; i++) { + bpids.addElement(new INTEGER(reqIdArray[i])); + } + CMCStatusInfo cmcStatusInfo = new + CMCStatusInfo(CMCStatusInfo.PENDING, bpids, + (String) null, otherInfo); + TaggedAttribute ta = new TaggedAttribute(new + INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, + cmcStatusInfo); + + controlSeq.addElement(ta); + // copy transactionID, senderNonce, + // create recipientNonce + // create responseInfo if regInfo exist + String[] transIds = + req.getExtDataInStringArray(IRequest.CMC_TRANSID); + SET ids = new SET(); + + for (int i = 0; i < transIds.length; i++) { + ids.addElement(new INTEGER(transIds[i])); + } + ta = new TaggedAttribute(new + INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_transactionId, + ids); + controlSeq.addElement(ta); + + String[] senderNonce = req.getExtDataInStringArray(IRequest.CMC_SENDERNONCE); + SET nonces = new SET(); + + for (int i = 0; i < senderNonce.length; i++) { + nonces.addElement(new OCTET_STRING(senderNonce[i].getBytes())); + } + ta = new TaggedAttribute(new + INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_recipientNonce, + nonces); + controlSeq.addElement(ta); + req.setExtData(IRequest.CMC_RECIPIENTNONCE, senderNonce); + + Date date = CMS.getCurrentDate(); + String salt = "lala123" + date.toString(); + 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); + req.setExtData(IRequest.CMC_SENDERNONCE, newNonce); + + 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 (authority instanceof ICertificateAuthority) { + x509cert = ((ICertificateAuthority) authority).getCaX509Cert(); + } else if (authority instanceof IRegistrationAuthority) { + x509cert = ((IRegistrationAuthority) authority).getRACert(); + } + if (x509cert == null) + return params; + try { + 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; + } else { + CMS.debug("GenPendingTemplateFiller::getTemplateParams() - " + + "keyType " + keyType.toString() + + " is unsupported!"); + return null; + } + + 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"); + } + + SignerInfo signInfo = new + 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); + } + + SignedData fResponse = new + SignedData(digestAlgs, ci, + null, null, signInfos); + ContentInfo fullResponse = new + ContentInfo(ContentInfo.SIGNED_DATA, fResponse); + ByteArrayOutputStream ostream = new + ByteArrayOutputStream(); + + fullResponse.encode((OutputStream) ostream); + byte[] fr = ostream.toByteArray(); + + fixed.set(FULL_RESPONSE, CMS.BtoA(fr)); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + } + // this authority + if (authority != null) + fixed.set(ICMSTemplateFiller.AUTHORITY, + authority.getOfficialName()); + return params; + } + + /** + * handy routine to check if client want full enrollment response + */ + public static boolean doFullResponse(IArgBlock httpParams) { + if (httpParams.getValueAsBoolean("fullResponse", false)) + return true; + else + return false; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java new file mode 100644 index 000000000..9e75cc799 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java @@ -0,0 +1,92 @@ +// --- 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.common; + +import java.util.Enumeration; +import java.util.Locale; +import java.util.Vector; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authority.IAuthority; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.request.IRequest; + +/** + * default Service Pending template filler + * + * @version $Revision$, $Date$ + */ +public class GenRejectedTemplateFiller implements ICMSTemplateFiller { + public final static String POLICY_MESSAGE = "policyMessage"; + + public GenRejectedTemplateFiller() { + } + + /** + * @param cmsReq CMS Request + * @param authority this authority + * @param locale locale of template. + * @param e unexpected exception e. ignored. + */ + public CMSTemplateParams getTemplateParams( + CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) { + IArgBlock fixed = CMS.createArgBlock(); + CMSTemplateParams params = new CMSTemplateParams(null, fixed); + + // request status if any. + if (cmsReq != null) { + Integer sts = cmsReq.getStatus(); + + if (sts != null) + fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString()); + } else { + CMS.debug("GenRejectedTemplateFiller::getTemplateParams() - " + + "cmsReq is null!"); + return null; + } + + // request id + IRequest req = cmsReq.getIRequest(); + + if (req != null) { + fixed.set(ICMSTemplateFiller.REQUEST_ID, req.getRequestId()); + + // policy errors (rejection reasons) + Vector<String> messages = req.getExtDataInStringVector(IRequest.ERRORS); + + if (messages != null) { + Enumeration<String> msgs = messages.elements(); + + while (msgs.hasMoreElements()) { + String ex = msgs.nextElement(); + IArgBlock messageArgBlock = CMS.createArgBlock(); + + messageArgBlock.set(POLICY_MESSAGE, ex); + params.addRepeatRecord(messageArgBlock); + } + } + } + + // this authority + + if (authority != null) + fixed.set(ICMSTemplateFiller.AUTHORITY, + authority.getOfficialName()); + return params; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java new file mode 100644 index 000000000..f6de38412 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java @@ -0,0 +1,63 @@ +// --- 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.common; + +import java.util.Locale; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authority.IAuthority; +import com.netscape.certsrv.base.IArgBlock; + +/** + * default Success template filler + * + * @version $Revision$, $Date$ + */ +public class GenSuccessTemplateFiller implements ICMSTemplateFiller { + + public GenSuccessTemplateFiller() { + } + + /** + * fill error details and description if any. + * + * @param cmsReq CMS Request + * @param authority this authority + * @param locale locale of template. + * @param e unexpected exception e. ignored. + */ + public CMSTemplateParams getTemplateParams( + CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) { + IArgBlock fixed = CMS.createArgBlock(); + CMSTemplateParams params = new CMSTemplateParams(null, fixed); + + // request status if any. + if (cmsReq != null) { + Integer sts = cmsReq.getStatus(); + + if (sts != null) + fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString()); + } + + // this authority + if (authority != null) + fixed.set(ICMSTemplateFiller.AUTHORITY, + authority.getOfficialName()); + return params; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java new file mode 100644 index 000000000..ec1b97779 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java @@ -0,0 +1,79 @@ +// --- 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.common; + +import java.util.Locale; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authority.IAuthority; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.request.IRequest; + +/** + * default Service Pending template filler + * + * @version $Revision$, $Date$ + */ +public class GenSvcPendingTemplateFiller implements ICMSTemplateFiller { + public static final String REMOTE_AUTHORITY = "remoteAuthority"; + + public GenSvcPendingTemplateFiller() { + } + + /** + * fill error details and description if any. + * + * @param cmsReq CMS Request + * @param authority this authority + * @param locale locale of template. + * @param e unexpected exception e. ignored. + */ + public CMSTemplateParams getTemplateParams( + CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) { + IArgBlock fixed = CMS.createArgBlock(); + CMSTemplateParams params = new CMSTemplateParams(null, fixed); + + // request status if any. + if (cmsReq != null) { + Integer sts = cmsReq.getStatus(); + + if (sts != null) + fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString()); + + // request id + IRequest req = cmsReq.getIRequest(); + + if (req != null) { + fixed.set(ICMSTemplateFiller.REQUEST_ID, req.getRequestId()); + + // remote authority we're waiting for + String remoteAuthority = + req.getExtDataInString(IRequest.REMOTE_SERVICE_AUTHORITY); + + if (remoteAuthority != null) + fixed.set(REMOTE_AUTHORITY, remoteAuthority); + } + } + + // this authority + if (authority != null) + fixed.set(ICMSTemplateFiller.AUTHORITY, + authority.getOfficialName()); + return params; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java new file mode 100644 index 000000000..cab1b36e6 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java @@ -0,0 +1,67 @@ +// --- 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.common; + +import java.util.Locale; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authority.IAuthority; +import com.netscape.certsrv.base.IArgBlock; + +/** + * default Unauthorized template filler + * + * @version $Revision$, $Date$ + */ +public class GenUnauthorizedTemplateFiller implements ICMSTemplateFiller { + + public GenUnauthorizedTemplateFiller() { + } + + /** + * fill error details and description if any. + * + * @param cmsReq CMS Request + * @param authority this authority + * @param locale locale of template. + * @param e unexpected exception e. ignored. + */ + public CMSTemplateParams getTemplateParams( + CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) { + IArgBlock fixed = CMS.createArgBlock(); + CMSTemplateParams params = new CMSTemplateParams(null, fixed); + + // request status if any. + if (cmsReq != null) { + Integer sts = cmsReq.getStatus(); + + if (sts != null) + fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString()); + } + + // set unauthorized error + fixed.set(ICMSTemplateFiller.ERROR, + new ECMSGWException(CMS.getLogMessage("CMSGW_UNAUTHORIZED"))); + + // this authority + if (authority != null) + fixed.set(ICMSTemplateFiller.AUTHORITY, + authority.getOfficialName()); + return params; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java new file mode 100644 index 000000000..8b560d7bc --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java @@ -0,0 +1,76 @@ +// --- 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.common; + +import java.util.Locale; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authority.IAuthority; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IArgBlock; + +/** + * default unexpected error template filler + * + * @version $Revision$, $Date$ + */ +public class GenUnexpectedErrorTemplateFiller implements ICMSTemplateFiller { + + public GenUnexpectedErrorTemplateFiller() { + } + + /** + * fill error details and description if any. + * + * @param cmsReq CMS Request + * @param authority this authority + * @param locale locale of template. + * @param e unexpected exception e. ignored. + */ + public CMSTemplateParams getTemplateParams( + CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) { + IArgBlock fixed = CMS.createArgBlock(); + CMSTemplateParams params = new CMSTemplateParams(null, fixed); + + // When an exception occurs the exit is non-local which probably + // will leave the requestStatus value set to something other + // than CMSRequest.EXCEPTION, so force the requestStatus to + // EXCEPTION since it must be that if we're here. + Integer sts = CMSRequest.EXCEPTION; + if (cmsReq != null) + cmsReq.setStatus(sts); + fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString()); + + // the unexpected error (exception) + if (e == null) + e = new EBaseException(CMS.getLogMessage("BASE_UNKNOWN_ERROR")); + String errMsg = null; + + if (e instanceof EBaseException) + errMsg = ((EBaseException) e).toString(locale); + else + errMsg = e.toString(); + fixed.set(ICMSTemplateFiller.EXCEPTION, errMsg); + + // this authority + if (authority != null) + fixed.set(ICMSTemplateFiller.AUTHORITY, + authority.getOfficialName()); + return params; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java new file mode 100644 index 000000000..2d046f0ee --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java @@ -0,0 +1,49 @@ +// --- 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.common; + +import java.util.Locale; + +import com.netscape.certsrv.authority.IAuthority; + +/** + * This interface represents a template filler. + * + * @version $Revision$, $Date$ + */ +public interface ICMSTemplateFiller { + // common template variables. + public final static String ERROR = "errorDetails"; + public final static String ERROR_DESCR = "errorDescription"; + public final static String EXCEPTION = "unexpectedError"; + + public static final String HOST = "host"; + public static final String PORT = "port"; + public static final String SCHEME = "scheme"; + + public static final String AUTHORITY = "authorityName"; + + public static final String REQUEST_STATUS = "requestStatus"; + + public static final String KEYREC_ID = "keyrecId"; + public static final String REQUEST_ID = "requestId"; + + public CMSTemplateParams getTemplateParams( + CMSRequest cmsReq, IAuthority mAuthority, Locale locale, Exception e) + throws Exception; +} diff --git a/base/common/src/com/netscape/cms/servlet/common/IRawJS.java b/base/common/src/com/netscape/cms/servlet/common/IRawJS.java new file mode 100644 index 000000000..827f24f1d --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/IRawJS.java @@ -0,0 +1,26 @@ +// --- 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.common; + +/** + * This represents raw JS parameters. + * + * @version $Revision$, $Date$ + */ +public interface IRawJS { +} diff --git a/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java new file mode 100644 index 000000000..59c4a0fe4 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java @@ -0,0 +1,114 @@ +// --- 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.common; + +import java.util.Locale; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authority.IAuthority; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.base.ISubsystem; + +/** + * A class represents a certificate server kernel. This + * kernel contains a list of resident subsystems such + * as logging, security, remote administration. Additional + * subsystems can be loaded into this kernel by specifying + * parameters in the configuration store. + * <P> + * + * @version $Revision$, $Date$ + */ +public class IndexTemplateFiller implements ICMSTemplateFiller { + + private final static String INFO = "index"; + + // input parameters + + // output parameters + private final static String OUT_TYPE = "type"; + private final static String OUT_ID = "id"; + private final static String OUT_TOTAL_COUNT = "totalCount"; + private final static String OUT_ERROR = "errorDetails"; + + public IndexTemplateFiller() { + } + + public CMSTemplateParams getTemplateParams( + CMSRequest cmsReq, IAuthority mAuthority, Locale locale, Exception e) { + IArgBlock header = CMS.createArgBlock(); + IArgBlock ctx = CMS.createArgBlock(); + CMSTemplateParams params = new CMSTemplateParams(header, ctx); + + ISubsystem ca = CMS.getSubsystem("ca"); + ISubsystem ra = CMS.getSubsystem("ra"); + ISubsystem kra = CMS.getSubsystem("kra"); + ISubsystem ocsp = CMS.getSubsystem("ocsp"); + ISubsystem tks = CMS.getSubsystem("tks"); + + IArgBlock rarg = null; + int count = 0; + + if (ca != null) { + rarg = CMS.createArgBlock(); + rarg.addStringValue(OUT_TYPE, "CertificateAuthority"); + rarg.addStringValue(OUT_ID, "ca"); + params.addRepeatRecord(rarg); + count++; + } + if (ra != null) { + rarg = CMS.createArgBlock(); + rarg.addStringValue(OUT_TYPE, "RegistrationAuthority"); + rarg.addStringValue(OUT_ID, "ra"); + params.addRepeatRecord(rarg); + count++; + } + if (ocsp != null) { + rarg = CMS.createArgBlock(); + rarg.addStringValue(OUT_TYPE, "OCSPAuthority"); + rarg.addStringValue(OUT_ID, "ocsp"); + params.addRepeatRecord(rarg); + count++; + } + if (kra != null) { + rarg = CMS.createArgBlock(); + rarg.addStringValue(OUT_TYPE, "KeyRecoveryAuthority"); + rarg.addStringValue(OUT_ID, "kra"); + params.addRepeatRecord(rarg); + count++; + } + if (tks != null) { + rarg = CMS.createArgBlock(); + rarg.addStringValue(OUT_TYPE, "TKSAuthority"); + rarg.addStringValue(OUT_ID, "tks"); + params.addRepeatRecord(rarg); + count++; + } + // information about what is selected is provided + // from the caller. This parameter (selected) is used + // by header servlet + try { + header.addStringValue("selected", + cmsReq.getHttpParams().getValueAsString("selected")); + } catch (EBaseException ex) { + } + header.addIntegerValue(OUT_TOTAL_COUNT, count); + return params; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/RawJS.java b/base/common/src/com/netscape/cms/servlet/common/RawJS.java new file mode 100644 index 000000000..f936e0757 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/RawJS.java @@ -0,0 +1,35 @@ +// --- 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.common; + +/** + * This represents raw JS parameters. + * + * @version $Revision$, $Date$ + */ +public class RawJS implements IRawJS { + private String mRawJSstr = null; + + public RawJS(String s) { + mRawJSstr = s; + } + + public String toString() { + return mRawJSstr; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/common/ServletUtils.java b/base/common/src/com/netscape/cms/servlet/common/ServletUtils.java new file mode 100644 index 000000000..5c16b8195 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/common/ServletUtils.java @@ -0,0 +1,106 @@ +// --- 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.common; + +import java.util.StringTokenizer; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authorization.IAuthzSubsystem; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; + +/** + * Utility class + * + * @version $Revision$, $Date$ + */ +public class ServletUtils { + + public final static String AUTHZ_SRC_LDAP = "ldap"; + public final static String AUTHZ_SRC_TYPE = "sourceType"; + public final static String AUTHZ_CONFIG_STORE = "authz"; + public final static String AUTHZ_SRC_XML = "web.xml"; + public final static String PROP_AUTHZ_MGR = "AuthzMgr"; + public final static String PROP_ACL = "ACLinfo"; + public final static String AUTHZ_MGR_BASIC = "BasicAclAuthz"; + public final static String AUTHZ_MGR_LDAP = "DirAclAuthz"; + + public static String initializeAuthz(ServletConfig sc, + IAuthzSubsystem authz, String id) throws ServletException { + String srcType = AUTHZ_SRC_LDAP; + + try { + IConfigStore authzConfig = + CMS.getConfigStore().getSubStore(AUTHZ_CONFIG_STORE); + + srcType = authzConfig.getString(AUTHZ_SRC_TYPE, AUTHZ_SRC_LDAP); + } catch (EBaseException e) { + CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_FAIL_SRC_TYPE")); + } + + String aclMethod = null; + + if (srcType.equalsIgnoreCase(AUTHZ_SRC_XML)) { + CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_INITED", "")); + aclMethod = sc.getInitParameter(PROP_AUTHZ_MGR); + if (aclMethod != null && + aclMethod.equalsIgnoreCase(AUTHZ_MGR_BASIC)) { + String aclInfo = sc.getInitParameter(PROP_ACL); + + if (aclInfo != null) { + try { + addACLInfo(authz, aclMethod, aclInfo); + } catch (EBaseException ee) { + throw new ServletException( + "failed to init authz info from xml config file"); + } + + CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_MGR_INIT_DONE", + id)); + } else { + CMS.debug(CMS.getLogMessage( + "ADMIN_SRVLT_PROP_ACL_NOT_SPEC", PROP_ACL, id, + AUTHZ_MGR_LDAP)); + } + } else { + CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_PROP_ACL_NOT_SPEC", + PROP_AUTHZ_MGR, id, AUTHZ_MGR_LDAP)); + } + } else { + aclMethod = AUTHZ_MGR_LDAP; + CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTH_LDAP_NOT_XML", id)); + } + + return aclMethod; + } + + public static void addACLInfo(IAuthzSubsystem authz, String aclMethod, + String aclInfo) throws EBaseException { + + StringTokenizer tokenizer = new StringTokenizer(aclInfo, "#"); + + while (tokenizer.hasMoreTokens()) { + String acl = (String) tokenizer.nextToken(); + + authz.authzMgrAccessInit(aclMethod, acl); + } + } +} |