diff options
Diffstat (limited to 'pki/base/common/src/com/netscape/cms/servlet/cert/scep')
3 files changed, 2121 insertions, 2090 deletions
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java index fe2485a6..79151072 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java +++ b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java @@ -123,303 +123,298 @@ import com.netscape.certsrv.request.RequestStatus; import com.netscape.cms.servlet.profile.SSLClientCertProvider; import com.netscape.cmsutil.scep.CRSPKIMessage; + /** - * This servlet deals with PKCS#10-based certificate requests from CRS, now - * called SCEP, and defined at: - * http://search.ietf.org/internet-drafts/draft-nourse-scep-02.txt + * This servlet deals with PKCS#10-based certificate requests from + * CRS, now called SCEP, and defined at: + * http://search.ietf.org/internet-drafts/draft-nourse-scep-02.txt * * The router is hardcoded to look for the http://host:80/cgi-bin/pkiclient.exe - * - * The HTTP parameters are 'operation' and 'message' operation can be either - * 'GetCACert' or 'PKIOperation' - * + * + * The HTTP parameters are 'operation' and 'message' + * operation can be either 'GetCACert' or 'PKIOperation' + * * @version $Revision$, $Date$ */ -public class CRSEnrollment extends HttpServlet { - /** +public class CRSEnrollment extends HttpServlet +{ + /** * */ private static final long serialVersionUID = 8483002540957382369L; - protected IProfileSubsystem mProfileSubsystem = null; - protected String mProfileId = null; - protected ICertAuthority mAuthority; - protected IConfigStore mConfig = null; - protected IAuthSubsystem mAuthSubsystem; - protected String mAppendDN = null; - protected String mEntryObjectclass = null; - protected boolean mCreateEntry = false; - protected boolean mFlattenDN = false; - - private String mAuthManagerName; - private String mSubstoreName; - private boolean mEnabled = false; - private boolean mUseCA = true; - private String mNickname = null; - private String mTokenName = ""; - private String mHashAlgorithm = "SHA1"; - private String mHashAlgorithmList = null; - private String[] mAllowedHashAlgorithm; - private String mConfiguredEncryptionAlgorithm = "DES3"; - private String mEncryptionAlgorithm = "DES3"; - private String mEncryptionAlgorithmList = null; - private String[] mAllowedEncryptionAlgorithm; - private Random mRandom = null; - private int mNonceSizeLimit = 0; - protected ILogger mLogger = CMS.getLogger(); - private ICertificateAuthority ca; - /* for hashing challenge password */ - protected MessageDigest mSHADigest = null; - - private static final String PROP_SUBSTORENAME = "substorename"; - private static final String PROP_AUTHORITY = "authority"; - private static final String PROP_CRS = "crs"; - private static final String PROP_CRSCA = "casubsystem"; - private static final String PROP_CRSAUTHMGR = "authName"; - private static final String PROP_APPENDDN = "appendDN"; - private static final String PROP_CREATEENTRY = "createEntry"; - private static final String PROP_FLATTENDN = "flattenDN"; - private static final String PROP_ENTRYOC = "entryObjectclass"; - - // URL parameters - private static final String URL_OPERATION = "operation"; - private static final String URL_MESSAGE = "message"; - - // possible values for 'operation' - private static final String OP_GETCACERT = "GetCACert"; - private static final String OP_PKIOPERATION = "PKIOperation"; - - public static final String AUTH_PASSWORD = "pwd"; - - public static final String AUTH_CREDS = "AuthCreds"; - public static final String AUTH_TOKEN = "AuthToken"; - public static final String AUTH_FAILED = "AuthFailed"; - - public static final String SANE_DNSNAME = "DNSName"; - public static final String SANE_IPADDRESS = "IPAddress"; - - public static final String CERTINFO = "CertInfo"; - public static final String SUBJECTNAME = "SubjectName"; - - public static ObjectIdentifier OID_UNSTRUCTUREDNAME = null; - public static ObjectIdentifier OID_UNSTRUCTUREDADDRESS = null; - public static ObjectIdentifier OID_SERIALNUMBER = null; - - public CRSEnrollment() { +protected IProfileSubsystem mProfileSubsystem = null; + protected String mProfileId = null; + protected ICertAuthority mAuthority; + protected IConfigStore mConfig = null; + protected IAuthSubsystem mAuthSubsystem; + protected String mAppendDN=null; + protected String mEntryObjectclass=null; + protected boolean mCreateEntry=false; + protected boolean mFlattenDN=false; + + private String mAuthManagerName; + private String mSubstoreName; + private boolean mEnabled = false; + private boolean mUseCA = true; + private String mNickname = null; + private String mTokenName = ""; + private String mHashAlgorithm = "SHA1"; + private String mHashAlgorithmList = null; + private String[] mAllowedHashAlgorithm; + private String mConfiguredEncryptionAlgorithm = "DES3"; + private String mEncryptionAlgorithm = "DES3"; + private String mEncryptionAlgorithmList = null; + private String[] mAllowedEncryptionAlgorithm; + private Random mRandom = null; + private int mNonceSizeLimit = 0; + protected ILogger mLogger = CMS.getLogger(); + private ICertificateAuthority ca; + /* for hashing challenge password */ + protected MessageDigest mSHADigest = null; + + private static final String PROP_SUBSTORENAME = "substorename"; + private static final String PROP_AUTHORITY = "authority"; + private static final String PROP_CRS = "crs"; + private static final String PROP_CRSCA = "casubsystem"; + private static final String PROP_CRSAUTHMGR = "authName"; + private static final String PROP_APPENDDN = "appendDN"; + private static final String PROP_CREATEENTRY= "createEntry"; + private static final String PROP_FLATTENDN = "flattenDN"; + private static final String PROP_ENTRYOC = "entryObjectclass"; + + // URL parameters + private static final String URL_OPERATION = "operation"; + private static final String URL_MESSAGE = "message"; + + // possible values for 'operation' + private static final String OP_GETCACERT = "GetCACert"; + private static final String OP_PKIOPERATION = "PKIOperation"; + + public static final String AUTH_PASSWORD = "pwd"; + + public static final String AUTH_CREDS = "AuthCreds"; + public static final String AUTH_TOKEN = "AuthToken"; + public static final String AUTH_FAILED = "AuthFailed"; + + public static final String SANE_DNSNAME = "DNSName"; + public static final String SANE_IPADDRESS = "IPAddress"; + + public static final String CERTINFO = "CertInfo"; + public static final String SUBJECTNAME = "SubjectName"; + + + public static ObjectIdentifier OID_UNSTRUCTUREDNAME = null; + public static ObjectIdentifier OID_UNSTRUCTUREDADDRESS = null; + public static ObjectIdentifier OID_SERIALNUMBER = null; + + public CRSEnrollment(){} + + public static Hashtable toHashtable(HttpServletRequest req) { + Hashtable httpReqHash = new Hashtable(); + Enumeration names = req.getParameterNames(); + while (names.hasMoreElements()) { + String name = (String)names.nextElement(); + httpReqHash.put(name, req.getParameter(name)); + } + return httpReqHash; + } + + public void init(ServletConfig sc) { + // Find the CertificateAuthority we should use for CRS. + String crsCA = sc.getInitParameter(PROP_AUTHORITY); + if (crsCA == null) + crsCA = "ca"; + mAuthority = (ICertAuthority) CMS.getSubsystem(crsCA); + ca = (ICertificateAuthority)mAuthority; + + if (mAuthority == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CANT_FIND_AUTHORITY",crsCA)); + } + + try { + if (mAuthority instanceof ISubsystem) { + IConfigStore authorityConfig = ((ISubsystem)mAuthority).getConfigStore(); + IConfigStore scepConfig = authorityConfig.getSubStore("scep"); + mEnabled = scepConfig.getBoolean("enable", false); + mHashAlgorithm = scepConfig.getString("hashAlgorithm", "SHA1"); + mConfiguredEncryptionAlgorithm = scepConfig.getString("encryptionAlgorithm", "DES3"); + mNonceSizeLimit = scepConfig.getInteger("nonceSizeLimit", 0); + mHashAlgorithmList = scepConfig.getString("allowedHashAlgorithms", "SHA1,SHA256,SHA512"); + mAllowedHashAlgorithm = mHashAlgorithmList.split(","); + mEncryptionAlgorithmList = scepConfig.getString("allowedEncryptionAlgorithms", "DES3"); + mAllowedEncryptionAlgorithm = mEncryptionAlgorithmList.split(","); + mNickname = scepConfig.getString("nickname", ca.getNickname()); + if (mNickname.equals(ca.getNickname())) { + mTokenName = ca.getSigningUnit().getTokenName(); + } else { + mTokenName = scepConfig.getString("tokenname", ""); + mUseCA = false; + } + if (!(mTokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN) || + mTokenName.equalsIgnoreCase("Internal Key Storage Token") || + mTokenName.length() == 0)) { + int i = mNickname.indexOf(':'); + if (!((i > -1) && (mTokenName.length() == i) && (mNickname.startsWith(mTokenName)))) { + mNickname = mTokenName + ":" + mNickname; + } + } + } + } catch (EBaseException e) { + CMS.debug("CRSEnrollment: init: EBaseException: "+e); + } + mEncryptionAlgorithm = mConfiguredEncryptionAlgorithm; + CMS.debug("CRSEnrollment: init: SCEP support is "+((mEnabled)?"enabled":"disabled")+"."); + CMS.debug("CRSEnrollment: init: SCEP nickname: "+mNickname); + CMS.debug("CRSEnrollment: init: CA nickname: "+ca.getNickname()); + CMS.debug("CRSEnrollment: init: Token name: "+mTokenName); + CMS.debug("CRSEnrollment: init: Is SCEP using CA keys: "+mUseCA); + CMS.debug("CRSEnrollment: init: mNonceSizeLimit: "+mNonceSizeLimit); + CMS.debug("CRSEnrollment: init: mHashAlgorithm: "+mHashAlgorithm); + CMS.debug("CRSEnrollment: init: mHashAlgorithmList: "+mHashAlgorithmList); + for (int i = 0; i < mAllowedHashAlgorithm.length; i++) { + mAllowedHashAlgorithm[i] = mAllowedHashAlgorithm[i].trim(); + CMS.debug("CRSEnrollment: init: mAllowedHashAlgorithm["+i+"]="+mAllowedHashAlgorithm[i]); + } + CMS.debug("CRSEnrollment: init: mEncryptionAlgorithm: "+mEncryptionAlgorithm); + CMS.debug("CRSEnrollment: init: mEncryptionAlgorithmList: "+mEncryptionAlgorithmList); + for (int i = 0; i < mAllowedEncryptionAlgorithm.length; i++) { + mAllowedEncryptionAlgorithm[i] = mAllowedEncryptionAlgorithm[i].trim(); + CMS.debug("CRSEnrollment: init: mAllowedEncryptionAlgorithm["+i+"]="+mAllowedEncryptionAlgorithm[i]); + } + + try { + mProfileSubsystem = (IProfileSubsystem)CMS.getSubsystem("profile"); + mProfileId = sc.getInitParameter("profileId"); + CMS.debug("CRSEnrollment: init: mProfileId="+mProfileId); + + mAuthSubsystem = (IAuthSubsystem)CMS.getSubsystem(CMS.SUBSYSTEM_AUTH); + mAuthManagerName = sc.getInitParameter(PROP_CRSAUTHMGR); + mAppendDN = sc.getInitParameter(PROP_APPENDDN); + String tmp = sc.getInitParameter(PROP_CREATEENTRY); + if (tmp != null && tmp.trim().equalsIgnoreCase("true")) + mCreateEntry = true; + else + mCreateEntry = false; + tmp = sc.getInitParameter(PROP_FLATTENDN); + if (tmp != null && tmp.trim().equalsIgnoreCase("true")) + mFlattenDN = true; + else + mFlattenDN = false; + mEntryObjectclass = sc.getInitParameter(PROP_ENTRYOC); + if (mEntryObjectclass == null) + mEntryObjectclass = "cep"; + mSubstoreName = sc.getInitParameter(PROP_SUBSTORENAME); + if (mSubstoreName == null) + mSubstoreName = "default"; + } catch (Exception e) { + } + + OID_UNSTRUCTUREDNAME = X500NameAttrMap.getDefault().getOid("UNSTRUCTUREDNAME"); + OID_UNSTRUCTUREDADDRESS = X500NameAttrMap.getDefault().getOid("UNSTRUCTUREDADDRESS"); + OID_SERIALNUMBER = X500NameAttrMap.getDefault().getOid("SERIALNUMBER"); + + + try { + mSHADigest = MessageDigest.getInstance("SHA1"); } - - public static Hashtable toHashtable(HttpServletRequest req) { - Hashtable httpReqHash = new Hashtable(); - Enumeration names = req.getParameterNames(); - while (names.hasMoreElements()) { - String name = (String) names.nextElement(); - httpReqHash.put(name, req.getParameter(name)); - } - return httpReqHash; - } - - public void init(ServletConfig sc) { - // Find the CertificateAuthority we should use for CRS. - String crsCA = sc.getInitParameter(PROP_AUTHORITY); - if (crsCA == null) - crsCA = "ca"; - mAuthority = (ICertAuthority) CMS.getSubsystem(crsCA); - ca = (ICertificateAuthority) mAuthority; - - if (mAuthority == null) { - log(ILogger.LL_FAILURE, - CMS.getLogMessage("CMSGW_CANT_FIND_AUTHORITY", crsCA)); - } - - try { - if (mAuthority instanceof ISubsystem) { - IConfigStore authorityConfig = ((ISubsystem) mAuthority) - .getConfigStore(); - IConfigStore scepConfig = authorityConfig.getSubStore("scep"); - mEnabled = scepConfig.getBoolean("enable", false); - mHashAlgorithm = scepConfig.getString("hashAlgorithm", "SHA1"); - mConfiguredEncryptionAlgorithm = scepConfig.getString( - "encryptionAlgorithm", "DES3"); - mNonceSizeLimit = scepConfig.getInteger("nonceSizeLimit", 0); - mHashAlgorithmList = scepConfig.getString( - "allowedHashAlgorithms", "SHA1,SHA256,SHA512"); - mAllowedHashAlgorithm = mHashAlgorithmList.split(","); - mEncryptionAlgorithmList = scepConfig.getString( - "allowedEncryptionAlgorithms", "DES3"); - mAllowedEncryptionAlgorithm = mEncryptionAlgorithmList - .split(","); - mNickname = scepConfig.getString("nickname", ca.getNickname()); - if (mNickname.equals(ca.getNickname())) { - mTokenName = ca.getSigningUnit().getTokenName(); - } else { - mTokenName = scepConfig.getString("tokenname", ""); - mUseCA = false; - } - if (!(mTokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN) - || mTokenName - .equalsIgnoreCase("Internal Key Storage Token") || mTokenName - .length() == 0)) { - int i = mNickname.indexOf(':'); - if (!((i > -1) && (mTokenName.length() == i) && (mNickname - .startsWith(mTokenName)))) { - mNickname = mTokenName + ":" + mNickname; - } - } - } - } catch (EBaseException e) { - CMS.debug("CRSEnrollment: init: EBaseException: " + e); - } - mEncryptionAlgorithm = mConfiguredEncryptionAlgorithm; - CMS.debug("CRSEnrollment: init: SCEP support is " - + ((mEnabled) ? "enabled" : "disabled") + "."); - CMS.debug("CRSEnrollment: init: SCEP nickname: " + mNickname); - CMS.debug("CRSEnrollment: init: CA nickname: " + ca.getNickname()); - CMS.debug("CRSEnrollment: init: Token name: " + mTokenName); - CMS.debug("CRSEnrollment: init: Is SCEP using CA keys: " + mUseCA); - CMS.debug("CRSEnrollment: init: mNonceSizeLimit: " + mNonceSizeLimit); - CMS.debug("CRSEnrollment: init: mHashAlgorithm: " + mHashAlgorithm); - CMS.debug("CRSEnrollment: init: mHashAlgorithmList: " - + mHashAlgorithmList); - for (int i = 0; i < mAllowedHashAlgorithm.length; i++) { - mAllowedHashAlgorithm[i] = mAllowedHashAlgorithm[i].trim(); - CMS.debug("CRSEnrollment: init: mAllowedHashAlgorithm[" + i + "]=" - + mAllowedHashAlgorithm[i]); - } - CMS.debug("CRSEnrollment: init: mEncryptionAlgorithm: " - + mEncryptionAlgorithm); - CMS.debug("CRSEnrollment: init: mEncryptionAlgorithmList: " - + mEncryptionAlgorithmList); - for (int i = 0; i < mAllowedEncryptionAlgorithm.length; i++) { - mAllowedEncryptionAlgorithm[i] = mAllowedEncryptionAlgorithm[i] - .trim(); - CMS.debug("CRSEnrollment: init: mAllowedEncryptionAlgorithm[" + i - + "]=" + mAllowedEncryptionAlgorithm[i]); - } - - try { - mProfileSubsystem = (IProfileSubsystem) CMS.getSubsystem("profile"); - mProfileId = sc.getInitParameter("profileId"); - CMS.debug("CRSEnrollment: init: mProfileId=" + mProfileId); - - mAuthSubsystem = (IAuthSubsystem) CMS - .getSubsystem(CMS.SUBSYSTEM_AUTH); - mAuthManagerName = sc.getInitParameter(PROP_CRSAUTHMGR); - mAppendDN = sc.getInitParameter(PROP_APPENDDN); - String tmp = sc.getInitParameter(PROP_CREATEENTRY); - if (tmp != null && tmp.trim().equalsIgnoreCase("true")) - mCreateEntry = true; - else - mCreateEntry = false; - tmp = sc.getInitParameter(PROP_FLATTENDN); - if (tmp != null && tmp.trim().equalsIgnoreCase("true")) - mFlattenDN = true; - else - mFlattenDN = false; - mEntryObjectclass = sc.getInitParameter(PROP_ENTRYOC); - if (mEntryObjectclass == null) - mEntryObjectclass = "cep"; - mSubstoreName = sc.getInitParameter(PROP_SUBSTORENAME); - if (mSubstoreName == null) - mSubstoreName = "default"; - } catch (Exception e) { - } - - OID_UNSTRUCTUREDNAME = X500NameAttrMap.getDefault().getOid( - "UNSTRUCTUREDNAME"); - OID_UNSTRUCTUREDADDRESS = X500NameAttrMap.getDefault().getOid( - "UNSTRUCTUREDADDRESS"); - OID_SERIALNUMBER = X500NameAttrMap.getDefault().getOid("SERIALNUMBER"); - - try { - mSHADigest = MessageDigest.getInstance("SHA1"); - } catch (NoSuchAlgorithmException e) { - } - - mRandom = new Random(); - } - - /** - * - * Service a CRS Request. It all starts here. This is where the message from - * the router is processed - * - * @param httpReq The HttpServletRequest. - * @param httpResp The HttpServletResponse. - * - */ - public void service(HttpServletRequest httpReq, HttpServletResponse httpResp) - throws ServletException { - boolean running_state = CMS.isInRunningState(); - if (!running_state) - throw new ServletException("CMS server is not ready to serve."); + catch (NoSuchAlgorithmException e) { + } + + mRandom = new Random(); + } + + + /** + * + * Service a CRS Request. It all starts here. This is where the message from the + * router is processed + * + * @param httpReq The HttpServletRequest. + * @param httpResp The HttpServletResponse. + * + */ + public void service(HttpServletRequest httpReq, + HttpServletResponse httpResp) + throws ServletException + { + boolean running_state = CMS.isInRunningState(); + if (!running_state) + throw new ServletException( + "CMS server is not ready to serve."); String operation = null; - String message = null; + String message = null; mEncryptionAlgorithm = mConfiguredEncryptionAlgorithm; - + + // Parse the URL from the HTTP Request. Split it up into // a structure which enables us to read the form elements IArgBlock input = CMS.createArgBlock(toHashtable(httpReq)); - - try { + + try { // Read in two form parameters - the router sets these - operation = (String) input.get(URL_OPERATION); + operation = (String)input.get(URL_OPERATION); CMS.debug("operation=" + operation); - message = (String) input.get(URL_MESSAGE); + message = (String)input.get(URL_MESSAGE); CMS.debug("message=" + message); - + if (!mEnabled) { CMS.debug("CRSEnrollment: SCEP support is disabled."); throw new ServletException("SCEP support is disabled."); } if (operation == null) { // 'operation' is mandatory. - throw new ServletException( - "Bad request: operation missing from URL"); + throw new ServletException("Bad request: operation missing from URL"); } - - /** - * the router can make two kinds of requests 1) simple request for - * CA cert 2) encoded, signed, enveloped request for anything else - * (PKIOperation) + + /** + * the router can make two kinds of requests + * 1) simple request for CA cert + * 2) encoded, signed, enveloped request for anything else (PKIOperation) */ - + if (operation.equals(OP_GETCACERT)) { - handleGetCACert(httpReq, httpResp); - } else if (operation.equals(OP_PKIOPERATION)) { - String decodeMode = (String) input.get("decode"); + handleGetCACert(httpReq, httpResp); + } + else if (operation.equals(OP_PKIOPERATION)) { + String decodeMode = (String)input.get("decode"); if (decodeMode == null || decodeMode.equals("false")) { - handlePKIOperation(httpReq, httpResp, message); + handlePKIOperation(httpReq, httpResp, message); } else { - decodePKIMessage(httpReq, httpResp, message); + decodePKIMessage(httpReq, httpResp, message); } - } else { + } + else { CMS.debug("Invalid operation " + operation); - throw new ServletException("unknown operation requested: " - + operation); + throw new ServletException("unknown operation requested: "+operation); } - - } catch (ServletException e) { + + } + catch (ServletException e) + { CMS.debug("ServletException " + e); throw new ServletException(e.getMessage().toString()); - } catch (Exception e) { - CMS.debug("Service exception " + e); - log(ILogger.LL_FAILURE, e.getMessage()); } - + catch (Exception e) + { + CMS.debug("Service exception " + e); + log(ILogger.LL_FAILURE,e.getMessage()); + } + } /** - * Log a message to the system log + * Log a message to the system log */ - private void log(int level, String msg) { - mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, level, - "CEP Enrollment: " + msg); + private void log(int level, String msg) { + + mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, + level, "CEP Enrollment: "+msg); } - private boolean isAlgorithmAllowed(String[] allowedAlgorithm, - String algorithm) { + private boolean isAlgorithmAllowed (String[] allowedAlgorithm, String algorithm) { boolean allowed = false; if (algorithm != null && algorithm.length() > 0) { @@ -433,9 +428,8 @@ public class CRSEnrollment extends HttpServlet { return allowed; } - public IAuthToken authenticate(AuthCredentials credentials, - IProfileAuthenticator authenticator, HttpServletRequest request) - throws EBaseException { + public IAuthToken authenticate(AuthCredentials credentials, IProfileAuthenticator authenticator, + HttpServletRequest request) throws EBaseException { // build credential Enumeration authNames = authenticator.getValueNames(); @@ -451,319 +445,313 @@ public class CRSEnrollment extends HttpServlet { credentials.set("clientHost", request.getRemoteHost()); IAuthToken authToken = authenticator.authenticate(credentials); if (authToken == null) { - return null; + return null; } SessionContext sc = SessionContext.getContext(); if (sc != null) { - sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName()); - String userid = authToken.getInString(IAuthToken.USER_ID); - if (userid != null) { - sc.put(SessionContext.USER_ID, userid); - } + sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName()); + String userid = authToken.getInString(IAuthToken.USER_ID); + if (userid != null) { + sc.put(SessionContext.USER_ID, userid); + } } return authToken; } - /** - * Return the CA certificate back to the requestor. This needs to be changed - * so that if the CA has a certificate chain, the whole thing should get - * packaged as a PKIMessage (degnerate PKCS7 - no signerInfo) - */ - - public void handleGetCACert(HttpServletRequest httpReq, - HttpServletResponse httpResp) throws ServletException { - java.security.cert.X509Certificate[] chain = null; - - CertificateChain certChain = mAuthority.getCACertChain(); - - try { - if (certChain == null) { - throw new ServletException("Internal Error: cannot get CA Cert"); - } - - chain = certChain.getChain(); - - byte[] bytes = null; - - int i = 0; - String message = (String) httpReq.getParameter(URL_MESSAGE); - CMS.debug("handleGetCACert message=" + message); - if (message != null) { - try { - int j = Integer.parseInt(message); - if (j < chain.length) { - i = j; - } - } catch (NumberFormatException e1) { - } - } - CMS.debug("handleGetCACert selected chain=" + i); - - if (mUseCA) { - bytes = chain[i].getEncoded(); - } else { - CryptoContext cx = new CryptoContext(); - bytes = cx.getSigningCert().getEncoded(); - } - - httpResp.setContentType("application/x-x509-ca-cert"); - - // The following code may be used one day to encode - // the RA/CA cert chain for RA mode, but it will need some - // work. - - /****** - * SET certs = new SET(); for (int i=0; i<chain.length; i++) { ANY - * cert = new ANY(chain[i].getEncoded()); certs.addElement(cert); } - * - * SignedData crsd = new SignedData( new SET(), // empty set of - * digestAlgorithmID's new ContentInfo( new OBJECT_IDENTIFIER(new - * long[] {1,2,840,113549,1,7,1}), null), //empty content certs, - * null, // no CRL's new SET() // empty SignerInfos ); - * - * ContentInfo wrap = new ContentInfo(ContentInfo.SIGNED_DATA, - * crsd); - * - * ByteArrayOutputStream baos = new ByteArrayOutputStream(); - * wrap.encode(baos); - * - * bytes = baos.toByteArray(); - * - * httpResp.setContentType("application/x-x509-ca-ra-cert"); - *****/ - - httpResp.setContentLength(bytes.length); - httpResp.getOutputStream().write(bytes); - httpResp.getOutputStream().flush(); - - CMS.debug("Output certificate chain:"); - CMS.debug(bytes); - } catch (Exception e) { - CMS.debug("handleGetCACert exception " + e); - log(ILogger.LL_FAILURE, - CMS.getLogMessage("CMSGW_ERROR_SENDING_DER_ENCODE_CERT", - e.getMessage())); - throw new ServletException( - "Failed sending DER encoded version of CA cert to client"); - } - - } - - public String getPasswordFromP10(PKCS10 p10) { - PKCS10Attributes p10atts = p10.getAttributes(); - Enumeration e = p10atts.getElements(); - - try { - while (e.hasMoreElements()) { - PKCS10Attribute p10a = (PKCS10Attribute) e.nextElement(); - CertAttrSet attr = p10a.getAttributeValue(); - - if (attr.getName().equals(ChallengePassword.NAME)) { - if (attr.get(ChallengePassword.PASSWORD) != null) { - return (String) attr.get(ChallengePassword.PASSWORD); - } - } - } - } catch (Exception e1) { - // do nothing - } - return null; - } - - /** - * If the 'operation' is 'PKIOperation', the 'message' part of the URL is a - * PKIMessage structure. We decode it to see what type message it is. - */ - - /** - * Decodes the PKI message and return information to RA. - */ - public void decodePKIMessage(HttpServletRequest httpReq, - HttpServletResponse httpResp, String msg) throws ServletException { - - CryptoContext cx = null; - - CRSPKIMessage req = null; - - byte[] decodedPKIMessage; - byte[] response = null; - String responseData = ""; - - decodedPKIMessage = com.netscape.osutil.OSUtil.AtoB(msg); - - try { - ByteArrayInputStream is = new ByteArrayInputStream( - decodedPKIMessage); - - // We make two CRSPKIMessages. One of them, is the request, so we - // initialize - // it from the DER given to us from the router. - // The second is the response, and we'll fill this in as we go. - - if (decodedPKIMessage.length < 50) { - throw new ServletException( - "CRS request is too small to be a real request (" - + decodedPKIMessage.length + " bytes)"); - } - try { - req = new CRSPKIMessage(is); - String ea = req.getEncryptionAlgorithm(); - if (!isAlgorithmAllowed(mAllowedEncryptionAlgorithm, ea)) { - CMS.debug("CRSEnrollment: decodePKIMessage: Encryption algorithm '" - + ea - + "' is not allowed (" - + mEncryptionAlgorithmList + ")."); - throw new ServletException("Encryption algorithm '" + ea - + "' is not allowed (" + mEncryptionAlgorithmList - + ")."); - } - String da = req.getDigestAlgorithmName(); - if (!isAlgorithmAllowed(mAllowedHashAlgorithm, da)) { - CMS.debug("CRSEnrollment: decodePKIMessage: Hashing algorithm '" - + da - + "' is not allowed (" - + mHashAlgorithmList - + ")."); - throw new ServletException("Hashing algorithm '" + da - + "' is not allowed (" + mHashAlgorithmList + ")."); - } - if (ea != null) { - mEncryptionAlgorithm = ea; - } - } catch (Exception e) { - CMS.debug(e); - throw new ServletException("Could not decode the request."); - } - - // Create a new crypto context for doing all the crypto operations - cx = new CryptoContext(); - - // Verify Signature on message (throws exception if sig bad) - verifyRequest(req, cx); - unwrapPKCS10(req, cx); - - IProfile profile = mProfileSubsystem.getProfile(mProfileId); - if (profile == null) { - CMS.debug("Profile '" + mProfileId + "' not found."); - throw new ServletException("Profile '" + mProfileId - + "' not found."); - } else { - CMS.debug("Found profile '" + mProfileId + "'."); - } - - IProfileAuthenticator authenticator = null; + /** + * Return the CA certificate back to the requestor. + * This needs to be changed so that if the CA has a certificate chain, + * the whole thing should get packaged as a PKIMessage (degnerate PKCS7 - no + * signerInfo) + */ + + public void handleGetCACert(HttpServletRequest httpReq, + HttpServletResponse httpResp) + throws ServletException { + java.security.cert.X509Certificate[] chain = null; + + CertificateChain certChain = mAuthority.getCACertChain(); + + try { + if (certChain == null) { + throw new ServletException("Internal Error: cannot get CA Cert"); + } + + chain = certChain.getChain(); + + byte[] bytes = null; + + int i = 0; + String message = (String)httpReq.getParameter(URL_MESSAGE); + CMS.debug("handleGetCACert message=" + message); + if (message != null) { try { - CMS.debug("Retrieving authenticator"); - authenticator = profile.getAuthenticator(); - if (authenticator == null) { - CMS.debug("Authenticator not found."); - throw new ServletException("Authenticator not found."); - } else { - CMS.debug("Got authenticator=" - + authenticator.getClass().getName()); - } - } catch (EProfileException e) { - throw new ServletException("Authenticator not found."); + int j = Integer.parseInt(message); + if (j < chain.length) { + i = j; + } + } catch (NumberFormatException e1) { } - AuthCredentials credentials = new AuthCredentials(); - IAuthToken authToken = null; - // for ssl authentication; pass in servlet for retrieving - // ssl client certificates - SessionContext context = SessionContext.getContext(); - - // insert profile context so that input parameter can be retrieved - context.put("sslClientCertProvider", new SSLClientCertProvider( - httpReq)); - - try { - authToken = authenticate(credentials, authenticator, httpReq); - } catch (Exception e) { - CMS.debug("Authentication failure: " + e.getMessage()); - throw new ServletException("Authentication failure: " - + e.getMessage()); + } + CMS.debug("handleGetCACert selected chain=" + i); + + if (mUseCA) { + bytes = chain[i].getEncoded(); + } else { + CryptoContext cx = new CryptoContext(); + bytes = cx.getSigningCert().getEncoded(); + } + + httpResp.setContentType("application/x-x509-ca-cert"); + + +// The following code may be used one day to encode +// the RA/CA cert chain for RA mode, but it will need some +// work. + + /****** + SET certs = new SET(); + for (int i=0; i<chain.length; i++) { + ANY cert = new ANY(chain[i].getEncoded()); + certs.addElement(cert); + } + + SignedData crsd = new SignedData( + new SET(), // empty set of digestAlgorithmID's + new ContentInfo( + new OBJECT_IDENTIFIER(new long[] {1,2,840,113549,1,7,1}), + null), //empty content + certs, + null, // no CRL's + new SET() // empty SignerInfos + ); + + ContentInfo wrap = new ContentInfo(ContentInfo.SIGNED_DATA, crsd); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + wrap.encode(baos); + + bytes = baos.toByteArray(); + + httpResp.setContentType("application/x-x509-ca-ra-cert"); + *****/ + + httpResp.setContentLength(bytes.length); + httpResp.getOutputStream().write(bytes); + httpResp.getOutputStream().flush(); + + CMS.debug("Output certificate chain:"); + CMS.debug(bytes); + } + catch (Exception e) { + CMS.debug("handleGetCACert exception " + e); + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_SENDING_DER_ENCODE_CERT",e.getMessage())); + throw new ServletException("Failed sending DER encoded version of CA cert to client"); + } + + } + + public String getPasswordFromP10(PKCS10 p10) + { + PKCS10Attributes p10atts = p10.getAttributes(); + Enumeration e = p10atts.getElements(); + + try { + while (e.hasMoreElements()) { + PKCS10Attribute p10a = (PKCS10Attribute)e.nextElement(); + CertAttrSet attr = p10a.getAttributeValue(); + + if (attr.getName().equals(ChallengePassword.NAME)) { + if (attr.get(ChallengePassword.PASSWORD) != null) { + return (String)attr.get(ChallengePassword.PASSWORD); + } + } + } + } catch(Exception e1) { + // do nothing + } + return null; + } + + /** + * If the 'operation' is 'PKIOperation', the 'message' part of the URL is a + * PKIMessage structure. We decode it to see what type message it is. + */ + + /** + * Decodes the PKI message and return information to RA. + */ + public void decodePKIMessage(HttpServletRequest httpReq, + HttpServletResponse httpResp, + String msg) + throws ServletException { + + CryptoContext cx=null; + + CRSPKIMessage req=null; + + byte[] decodedPKIMessage; + byte[] response=null; + String responseData = ""; + + decodedPKIMessage = com.netscape.osutil.OSUtil.AtoB(msg); + + try { + ByteArrayInputStream is = new ByteArrayInputStream(decodedPKIMessage); + + // We make two CRSPKIMessages. One of them, is the request, so we initialize + // it from the DER given to us from the router. + // The second is the response, and we'll fill this in as we go. + + if (decodedPKIMessage.length < 50) { + throw new ServletException("CRS request is too small to be a real request ("+ + decodedPKIMessage.length+" bytes)"); + } + try { + req = new CRSPKIMessage(is); + String ea = req.getEncryptionAlgorithm(); + if (!isAlgorithmAllowed (mAllowedEncryptionAlgorithm, ea)) { + CMS.debug("CRSEnrollment: decodePKIMessage: Encryption algorithm '"+ea+ + "' is not allowed ("+mEncryptionAlgorithmList+")."); + throw new ServletException("Encryption algorithm '"+ea+ + "' is not allowed ("+mEncryptionAlgorithmList+")."); } - if (authToken == null) { - CMS.debug("Authentication failure."); - throw new ServletException("Authentication failure."); + String da = req.getDigestAlgorithmName(); + if (!isAlgorithmAllowed (mAllowedHashAlgorithm, da)) { + CMS.debug("CRSEnrollment: decodePKIMessage: Hashing algorithm '"+da+ + "' is not allowed ("+mHashAlgorithmList+")."); + throw new ServletException("Hashing algorithm '"+da+ + "' is not allowed ("+mHashAlgorithmList+")."); } - - // Deal with Transaction ID - String transactionID = req.getTransactionID(); - responseData = responseData + "<TransactionID>" + transactionID - + "</TransactionID>"; - - // End-User or RA's IP address - responseData = responseData + "<RemoteAddr>" - + httpReq.getRemoteAddr() + "</RemoteAddr>"; - - responseData = responseData + "<RemoteHost>" - + httpReq.getRemoteHost() + "</RemoteHost>"; - - // Deal with Nonces - byte[] sn = req.getSenderNonce(); - - // Deal with message type - String mt = req.getMessageType(); - responseData = responseData + "<MessageType>" + mt - + "</MessageType>"; - - PKCS10 p10 = (PKCS10) req.getP10(); - X500Name p10subject = p10.getSubjectName(); - responseData = responseData + "<SubjectName>" - + p10subject.toString() + "</SubjectName>"; - - String pkcs10Attr = ""; - PKCS10Attributes p10atts = p10.getAttributes(); - Enumeration e = p10atts.getElements(); - - while (e.hasMoreElements()) { - PKCS10Attribute p10a = (PKCS10Attribute) e.nextElement(); - CertAttrSet attr = p10a.getAttributeValue(); - - if (attr.getName().equals(ChallengePassword.NAME)) { - if (attr.get(ChallengePassword.PASSWORD) != null) { - pkcs10Attr = pkcs10Attr - + "<ChallengePassword><Password>" - + (String) attr.get(ChallengePassword.PASSWORD) - + "</Password></ChallengePassword>"; - } - - } - String extensionsStr = ""; - if (attr.getName().equals(ExtensionsRequested.NAME)) { - - Enumeration exts = ((ExtensionsRequested) attr) - .getExtensions().elements(); - while (exts.hasMoreElements()) { - Extension ext = (Extension) exts.nextElement(); - - if (ext.getExtensionId() - .equals(OIDMap - .getOID(SubjectAlternativeNameExtension.IDENT))) { - DerOutputStream dos = new DerOutputStream(); - SubjectAlternativeNameExtension sane = new SubjectAlternativeNameExtension( - Boolean.valueOf(false), // noncritical - ext.getExtensionValue()); - - Vector v = (Vector) sane - .get(SubjectAlternativeNameExtension.SUBJECT_NAME); - - Enumeration gne = v.elements(); + if (ea != null) { + mEncryptionAlgorithm = ea; + } + } + catch (Exception e) { + CMS.debug(e); + throw new ServletException("Could not decode the request."); + } + + // Create a new crypto context for doing all the crypto operations + cx = new CryptoContext(); + + // Verify Signature on message (throws exception if sig bad) + verifyRequest(req,cx); + unwrapPKCS10(req,cx); + + IProfile profile = mProfileSubsystem.getProfile(mProfileId); + if (profile == null) { + CMS.debug("Profile '" + mProfileId + "' not found."); + throw new ServletException("Profile '" + mProfileId + "' not found."); + } else { + CMS.debug("Found profile '" + mProfileId + "'."); + } + + IProfileAuthenticator authenticator = null; + try { + CMS.debug("Retrieving authenticator"); + authenticator = profile.getAuthenticator(); + if (authenticator == null) { + CMS.debug("Authenticator not found."); + throw new ServletException("Authenticator not found."); + } else { + CMS.debug("Got authenticator=" + authenticator.getClass().getName()); + } + } catch (EProfileException e) { + throw new ServletException("Authenticator not found."); + } + AuthCredentials credentials = new AuthCredentials(); + IAuthToken authToken = null; + // for ssl authentication; pass in servlet for retrieving + // ssl client certificates + SessionContext context = SessionContext.getContext(); + + // insert profile context so that input parameter can be retrieved + context.put("sslClientCertProvider", new SSLClientCertProvider(httpReq)); + + try { + authToken = authenticate(credentials, authenticator, httpReq); + } catch (Exception e) { + CMS.debug("Authentication failure: "+ e.getMessage()); + throw new ServletException("Authentication failure: "+ e.getMessage()); + } + if (authToken == null) { + CMS.debug("Authentication failure."); + throw new ServletException("Authentication failure."); + } + + // Deal with Transaction ID + String transactionID = req.getTransactionID(); + responseData = responseData + + "<TransactionID>" + transactionID + "</TransactionID>"; + + // End-User or RA's IP address + responseData = responseData + + "<RemoteAddr>" + httpReq.getRemoteAddr() + "</RemoteAddr>"; + + responseData = responseData + + "<RemoteHost>" + httpReq.getRemoteHost() + "</RemoteHost>"; + + // Deal with Nonces + byte[] sn = req.getSenderNonce(); + + // Deal with message type + String mt = req.getMessageType(); + responseData = responseData + + "<MessageType>" + mt + "</MessageType>"; + + PKCS10 p10 = (PKCS10)req.getP10(); + X500Name p10subject = p10.getSubjectName(); + responseData = responseData + + "<SubjectName>" + p10subject.toString() + "</SubjectName>"; + + String pkcs10Attr = ""; + PKCS10Attributes p10atts = p10.getAttributes(); + Enumeration e = p10atts.getElements(); + + while (e.hasMoreElements()) { + PKCS10Attribute p10a = (PKCS10Attribute)e.nextElement(); + CertAttrSet attr = p10a.getAttributeValue(); + + + if (attr.getName().equals(ChallengePassword.NAME)) { + if (attr.get(ChallengePassword.PASSWORD) != null) { + pkcs10Attr = pkcs10Attr + + "<ChallengePassword><Password>" + (String)attr.get(ChallengePassword.PASSWORD) + "</Password></ChallengePassword>"; + } + + } + String extensionsStr = ""; + if (attr.getName().equals(ExtensionsRequested.NAME)) { + + Enumeration exts = ((ExtensionsRequested)attr).getExtensions().elements(); + while (exts.hasMoreElements()) { + Extension ext = (Extension) exts.nextElement(); + + if (ext.getExtensionId().equals( + OIDMap.getOID(SubjectAlternativeNameExtension.IDENT)) ) { + DerOutputStream dos = new DerOutputStream(); + SubjectAlternativeNameExtension sane = new SubjectAlternativeNameExtension( + Boolean.valueOf(false), // noncritical + ext.getExtensionValue()); + + + Vector v = + (Vector) sane.get(SubjectAlternativeNameExtension. SUBJECT_NAME); + + Enumeration gne = v.elements(); StringBuffer subjAltNameStr = new StringBuffer(); - while (gne.hasMoreElements()) { - GeneralNameInterface gni = (GeneralNameInterface) gne - .nextElement(); - if (gni instanceof GeneralName) { - GeneralName genName = (GeneralName) gni; - - String gn = genName.toString(); - int colon = gn.indexOf(':'); - String gnType = gn.substring(0, colon) - .trim(); - String gnValue = gn.substring(colon + 1) - .trim(); + while (gne.hasMoreElements()) { + GeneralNameInterface gni = (GeneralNameInterface) gne.nextElement(); + if (gni instanceof GeneralName) { + GeneralName genName = (GeneralName) gni; + + String gn = genName.toString(); + int colon = gn.indexOf(':'); + String gnType = gn.substring(0,colon).trim(); + String gnValue = gn.substring(colon+1).trim(); subjAltNameStr.append("<"); subjAltNameStr.append(gnType); @@ -772,1460 +760,1465 @@ public class CRSEnrollment extends HttpServlet { subjAltNameStr.append("</"); subjAltNameStr.append(gnType); subjAltNameStr.append(">"); - } - } // while - extensionsStr = "<SubjAltName>" - + subjAltNameStr.toString() - + "</SubjAltName>"; - } // if - } // while - pkcs10Attr = pkcs10Attr + "<Extensions>" + extensionsStr - + "</Extensions>"; - } // if extensions - } // while - responseData = responseData + "<PKCS10>" + pkcs10Attr + "</PKCS10>"; - - } catch (ServletException e) { - throw new ServletException(e.getMessage().toString()); - } catch (CRSInvalidSignatureException e) { - CMS.debug("handlePKIMessage exception " + e); - CMS.debug(e); - } catch (Exception e) { - CMS.debug("handlePKIMessage exception " + e); - CMS.debug(e); - throw new ServletException( - "Failed to process message in CEP servlet: " - + e.getMessage()); - } - - // We have now processed the request, and need to make the response - // message - - try { - - responseData = "<XMLResponse>" + responseData + "</XMLResponse>"; - // Get the response coding - response = responseData.getBytes(); - - // Encode the httpResp into B64 - httpResp.setContentType("application/xml"); - httpResp.setContentLength(response.length); - httpResp.getOutputStream().write(response); - httpResp.getOutputStream().flush(); - - int i1 = responseData.indexOf("<Password>"); - if (i1 > -1) { - i1 += 10; // 10 is a length of "<Password>" - int i2 = responseData.indexOf("</Password>", i1); - if (i2 > -1) { - responseData = responseData.substring(0, i1) + "********" - + responseData.substring(i2, responseData.length()); - } - } - - CMS.debug("Output (decoding) PKIOperation response:"); - CMS.debug(responseData); - } catch (Exception e) { - throw new ServletException( - "Failed to create response for CEP message" - + e.getMessage()); - } - - } - - /** - * finds a request with this transaction ID. If could not find any request - - * return null If could only find 'rejected' or 'cancelled' requests, return - * null If found 'pending' or 'completed' request - return that request - */ - - public void handlePKIOperation(HttpServletRequest httpReq, - HttpServletResponse httpResp, String msg) throws ServletException { - - CryptoContext cx = null; - - CRSPKIMessage req = null; - CRSPKIMessage crsResp = null; - - byte[] decodedPKIMessage; - byte[] response = null; - X509CertImpl cert = null; - - decodedPKIMessage = com.netscape.osutil.OSUtil.AtoB(msg); - - try { - ByteArrayInputStream is = new ByteArrayInputStream( - decodedPKIMessage); - - // We make two CRSPKIMessages. One of them, is the request, so we - // initialize - // it from the DER given to us from the router. - // The second is the response, and we'll fill this in as we go. - - if (decodedPKIMessage.length < 50) { - throw new ServletException( - "CRS request is too small to be a real request (" - + decodedPKIMessage.length + " bytes)"); - } - try { - req = new CRSPKIMessage(is); - String ea = req.getEncryptionAlgorithm(); - if (!isAlgorithmAllowed(mAllowedEncryptionAlgorithm, ea)) { - CMS.debug("CRSEnrollment: handlePKIOperation: Encryption algorithm '" - + ea - + "' is not allowed (" - + mEncryptionAlgorithmList + ")."); - throw new ServletException("Encryption algorithm '" + ea - + "' is not allowed (" + mEncryptionAlgorithmList - + ")."); - } - String da = req.getDigestAlgorithmName(); - if (!isAlgorithmAllowed(mAllowedHashAlgorithm, da)) { - CMS.debug("CRSEnrollment: handlePKIOperation: Hashing algorithm '" - + da - + "' is not allowed (" - + mHashAlgorithmList - + ")."); - throw new ServletException("Hashing algorithm '" + da - + "' is not allowed (" + mHashAlgorithmList + ")."); - } - if (ea != null) { - mEncryptionAlgorithm = ea; - } - crsResp = new CRSPKIMessage(); - } catch (ServletException e) { - throw new ServletException(e.getMessage().toString()); - } catch (Exception e) { - CMS.debug(e); - throw new ServletException("Could not decode the request."); - } - crsResp.setMessageType(CRSPKIMessage.mType_CertRep); - - // Create a new crypto context for doing all the crypto operations - cx = new CryptoContext(); - - // Verify Signature on message (throws exception if sig bad) - verifyRequest(req, cx); - - // Deal with Transaction ID - String transactionID = req.getTransactionID(); - if (transactionID == null) { - throw new ServletException( - "Error: malformed PKIMessage - missing transactionID"); - } else { - crsResp.setTransactionID(transactionID); - } - - // Deal with Nonces - byte[] sn = req.getSenderNonce(); - if (sn == null) { - throw new ServletException( - "Error: malformed PKIMessage - missing sendernonce"); - } else { - if (mNonceSizeLimit > 0 && sn.length > mNonceSizeLimit) { - byte[] snLimited = (mNonceSizeLimit > 0) ? new byte[mNonceSizeLimit] - : null; - System.arraycopy(sn, 0, snLimited, 0, mNonceSizeLimit); - crsResp.setRecipientNonce(snLimited); - } else { - crsResp.setRecipientNonce(sn); - } - byte[] serverNonce = new byte[16]; - mRandom.nextBytes(serverNonce); - crsResp.setSenderNonce(serverNonce); - // crsResp.setSenderNonce(new byte[] {0}); - } - - // Deal with message type - String mt = req.getMessageType(); - if (mt == null) { - throw new ServletException( - "Error: malformed PKIMessage - missing messageType"); + } + } // while + extensionsStr = "<SubjAltName>" + + subjAltNameStr.toString() + "</SubjAltName>"; + } // if + } // while + pkcs10Attr = pkcs10Attr + + "<Extensions>" + extensionsStr + "</Extensions>"; + } // if extensions + } // while + responseData = responseData + + "<PKCS10>" + pkcs10Attr + "</PKCS10>"; + + } catch (ServletException e) { + throw new ServletException(e.getMessage().toString()); + } catch (CRSInvalidSignatureException e) { + CMS.debug("handlePKIMessage exception " + e); + CMS.debug(e); + } catch (Exception e) { + CMS.debug("handlePKIMessage exception " + e); + CMS.debug(e); + throw new ServletException("Failed to process message in CEP servlet: "+ e.getMessage()); + } + + // We have now processed the request, and need to make the response message + + try { + + responseData = "<XMLResponse>" + responseData + "</XMLResponse>"; + // Get the response coding + response = responseData.getBytes(); + + // Encode the httpResp into B64 + httpResp.setContentType("application/xml"); + httpResp.setContentLength(response.length); + httpResp.getOutputStream().write(response); + httpResp.getOutputStream().flush(); + + int i1 = responseData.indexOf("<Password>"); + if (i1 > -1) { + i1 += 10; // 10 is a length of "<Password>" + int i2 = responseData.indexOf("</Password>", i1); + if (i2 > -1) { + responseData = responseData.substring(0, i1) + "********" + + responseData.substring(i2, responseData.length()); + } + } + + CMS.debug("Output (decoding) PKIOperation response:"); + CMS.debug(responseData); + } + catch (Exception e) { + throw new ServletException("Failed to create response for CEP message"+e.getMessage()); + } + + } + + + /** + * finds a request with this transaction ID. + * If could not find any request - return null + * If could only find 'rejected' or 'cancelled' requests, return null + * If found 'pending' or 'completed' request - return that request + */ + + + public void handlePKIOperation(HttpServletRequest httpReq, + HttpServletResponse httpResp, + String msg) + throws ServletException { + + + CryptoContext cx=null; + + CRSPKIMessage req=null; + CRSPKIMessage crsResp=null; + + byte[] decodedPKIMessage; + byte[] response=null; + X509CertImpl cert = null; + + decodedPKIMessage = com.netscape.osutil.OSUtil.AtoB(msg); + + try { + ByteArrayInputStream is = new ByteArrayInputStream(decodedPKIMessage); + + // We make two CRSPKIMessages. One of them, is the request, so we initialize + // it from the DER given to us from the router. + // The second is the response, and we'll fill this in as we go. + + if (decodedPKIMessage.length < 50) { + throw new ServletException("CRS request is too small to be a real request ("+ + decodedPKIMessage.length+" bytes)"); + } + try { + req = new CRSPKIMessage(is); + String ea = req.getEncryptionAlgorithm(); + if (!isAlgorithmAllowed (mAllowedEncryptionAlgorithm, ea)) { + CMS.debug("CRSEnrollment: handlePKIOperation: Encryption algorithm '"+ea+ + "' is not allowed ("+mEncryptionAlgorithmList+")."); + throw new ServletException("Encryption algorithm '"+ea+ + "' is not allowed ("+mEncryptionAlgorithmList+")."); } - - // now run appropriate code, depending on message type - if (mt.equals(CRSPKIMessage.mType_PKCSReq)) { - CMS.debug("Processing PKCSReq"); - try { - // Check if there is an existing request. If this returns - // non-null, - // then the request is 'active' (either pending or - // completed) in - // which case, we compare the hash of the new request to the - // hash of the - // one in the queue - if they are the same, I return the - // state of the - // original request - as if it was 'getCertInitial' message. - // If the hashes are different, then the user attempted to - // enroll - // for a new request with the same txid, which is not - // allowed - - // so we return 'failure'. - - IRequest cmsRequest = findRequestByTransactionID( - req.getTransactionID(), true); - - // If there was no request (with a cert) with this - // transaction ID, - // process it as a new request - - cert = handlePKCSReq(httpReq, cmsRequest, req, crsResp, cx); - - } catch (CRSFailureException e) { - throw new ServletException( - "Couldn't handle CEP request (PKCSReq) - " - + e.getMessage()); - } - } else if (mt.equals(CRSPKIMessage.mType_GetCertInitial)) { - CMS.debug("Processing GetCertInitial"); - cert = handleGetCertInitial(req, crsResp); - } else { - CMS.debug("Invalid request type " + mt); + String da = req.getDigestAlgorithmName(); + if (!isAlgorithmAllowed (mAllowedHashAlgorithm, da)) { + CMS.debug("CRSEnrollment: handlePKIOperation: Hashing algorithm '"+da+ + "' is not allowed ("+mHashAlgorithmList+")."); + throw new ServletException("Hashing algorithm '"+da+ + "' is not allowed ("+mHashAlgorithmList+")."); } - } catch (ServletException e) { - throw new ServletException(e.getMessage().toString()); - } catch (CRSInvalidSignatureException e) { - CMS.debug("handlePKIMessage exception " + e); + if (ea != null) { + mEncryptionAlgorithm = ea; + } + crsResp = new CRSPKIMessage(); + } + catch (ServletException e) { + throw new ServletException(e.getMessage().toString()); + } + catch (Exception e) { CMS.debug(e); - crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badMessageCheck); - } catch (Exception e) { - CMS.debug("handlePKIMessage exception " + e); - CMS.debug(e); - throw new ServletException( - "Failed to process message in CEP servlet: " - + e.getMessage()); - } - - // We have now processed the request, and need to make the response - // message - - try { - // make the response - processCertRep(cx, cert, crsResp, req); - - // Get the response coding - response = crsResp.getResponse(); - - // Encode the crsResp into B64 - httpResp.setContentType("application/x-pki-message"); - httpResp.setContentLength(response.length); - httpResp.getOutputStream().write(response); - httpResp.getOutputStream().flush(); - - CMS.debug("Output PKIOperation response:"); - CMS.debug(CMS.BtoA(response)); - } catch (Exception e) { - throw new ServletException( - "Failed to create response for CEP message" - + e.getMessage()); - } - - } - - /** - * finds a request with this transaction ID. If could not find any request - - * return null If could only find 'rejected' or 'cancelled' requests, return - * null If found 'pending' or 'completed' request - return that request - */ - - public IRequest findRequestByTransactionID(String txid, - boolean ignoreRejected) throws EBaseException { - - /* Check if certificate request has been completed */ - - IRequestQueue rq = ca.getRequestQueue(); - IRequest foundRequest = null; - - Enumeration rids = rq.findRequestsBySourceId(txid); - if (rids == null) { - return null; - } - - int count = 0; - while (rids.hasMoreElements()) { - RequestId rid = (RequestId) rids.nextElement(); - if (rid == null) { - continue; - } - - IRequest request = rq.findRequest(rid); - if (request == null) { - continue; - } - if (!ignoreRejected - || request.getRequestStatus().equals(RequestStatus.PENDING) - || request.getRequestStatus() - .equals(RequestStatus.COMPLETE)) { - if (foundRequest != null) { - } - foundRequest = request; - } - } - return foundRequest; - } - - /** - * Called if the router is requesting us to send it its certificate Examine - * request queue for a request matching the transaction ID. Ignore any - * rejected or cancelled requests. - * - * If a request is found in the pending state, the response should be - * 'pending' - * - * If a request is found in the completed state, the response should be to - * return the certificate - * - * If no request is found, the response should be to return null - * - */ - - public X509CertImpl handleGetCertInitial(CRSPKIMessage req, - CRSPKIMessage resp) { - IRequest foundRequest = null; - - // already done by handlePKIOperation - // resp.setRecipientNonce(req.getSenderNonce()); - // resp.setSenderNonce(null); - - try { - foundRequest = findRequestByTransactionID(req.getTransactionID(), - false); - } catch (EBaseException e) { - } - - if (foundRequest == null) { - resp.setFailInfo(CRSPKIMessage.mFailInfo_badCertId); - resp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); - return null; - } - - return makeResponseFromRequest(req, resp, foundRequest); - } - - public void verifyRequest(CRSPKIMessage req, CryptoContext cx) - throws CRSInvalidSignatureException { - - // Get Signed Data - - byte[] reqAAbytes = req.getAA(); - byte[] reqAAsig = req.getAADigest(); - - } - - /** - * Create an entry for this user in the publishing directory - * - */ - - private boolean createEntry(String dn) { - boolean result = false; - - IPublisherProcessor ldapPub = mAuthority.getPublisherProcessor(); - if (ldapPub == null || !ldapPub.enabled()) { - log(ILogger.LL_FAILURE, - CMS.getLogMessage("CMSGW_ERROR_CREATE_ENTRY_FROM_CEP")); - - return result; - } - - ILdapConnFactory connFactory = ((IPublisherProcessor) ldapPub) - .getLdapConnModule().getLdapConnFactory(); - if (connFactory == null) { - return result; - } - - LDAPConnection connection = null; - try { - connection = connFactory.getConn(); - String[] objectclasses = { "top", mEntryObjectclass }; - LDAPAttribute ocAttrs = new LDAPAttribute("objectclass", - objectclasses); - - LDAPAttributeSet attrSet = new LDAPAttributeSet(); - attrSet.add(ocAttrs); - - LDAPEntry newEntry = new LDAPEntry(dn, attrSet); - connection.add(newEntry); - result = true; - } catch (Exception e) { - log(ILogger.LL_FAILURE, - CMS.getLogMessage("CMSGW_FAIL_CREAT_ENTRY_EXISTS", dn)); - } finally { - try { - connFactory.returnConn(connection); - } catch (Exception f) { - } - } - return result; - } - - /** - * Here we decrypt the PKCS10 message from the client - * - */ - - public void unwrapPKCS10(CRSPKIMessage req, CryptoContext cx) - throws ServletException, CryptoManager.NotInitializedException, - CryptoContext.CryptoContextException, CRSFailureException { - - byte[] decryptedP10bytes = null; - SymmetricKey sk; - SymmetricKey skinternal; - SymmetricKey.Type skt; - KeyWrapper kw; - Cipher cip; - EncryptionAlgorithm ea; - boolean errorInRequest = false; - - // Unwrap the session key with the Cert server key - try { - kw = cx.getKeyWrapper(); - - kw.initUnwrap(cx.getPrivateKey(), null); - - skt = SymmetricKey.Type.DES; - ea = EncryptionAlgorithm.DES_CBC; - if (mEncryptionAlgorithm != null - && mEncryptionAlgorithm.equals("DES3")) { - skt = SymmetricKey.Type.DES3; - ea = EncryptionAlgorithm.DES3_CBC; - } - - sk = kw.unwrapSymmetric(req.getWrappedKey(), skt, - SymmetricKey.Usage.DECRYPT, 0); // keylength is ignored - - skinternal = cx.getDESKeyGenerator().clone(sk); - - cip = skinternal.getOwningToken().getCipherContext(ea); - - cip.initDecrypt(skinternal, (new IVParameterSpec(req.getIV()))); - - decryptedP10bytes = cip.doFinal(req.getEncryptedPkcs10()); - CMS.debug("decryptedP10bytes:"); - CMS.debug(decryptedP10bytes); - - req.setP10(new PKCS10(decryptedP10bytes)); - } catch (Exception e) { - CMS.debug("failed to unwrap PKCS10 " + e); - throw new CRSFailureException("Could not unwrap PKCS10 blob: " - + e.getMessage()); - } - - } - - private void getDetailFromRequest(CRSPKIMessage req, CRSPKIMessage crsResp) - throws CRSFailureException { - - IRequest issueReq = null; - X509CertImpl issuedCert = null; - Vector extensionsRequested = null; - SubjectAlternativeNameExtension sane = null; - CertAttrSet requested_ext = null; - - try { - PKCS10 p10 = (PKCS10) req.getP10(); - - if (p10 == null) { - crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badMessageCheck); - crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); - throw new CRSFailureException( - "Failed to decode pkcs10 from CEP request"); - } - - AuthCredentials authCreds = new AuthCredentials(); - - String challengePassword = null; - // Here, we make a new CertInfo - it's a new start for a certificate - - X509CertInfo certInfo = CMS.getDefaultX509CertInfo(); - - // get some stuff out of the request - X509Key key = p10.getSubjectPublicKeyInfo(); - X500Name p10subject = p10.getSubjectName(); - - X500Name subject = null; - - // The following code will copy all the attributes - // into the AuthCredentials so they can be used for - // authentication - // - // Optionally, you can re-map the subject name from: - // one RDN, with many AVA's to - // many RDN's with one AVA in each. - - Enumeration rdne = p10subject.getRDNs(); - Vector rdnv = new Vector(); - - Hashtable sanehash = new Hashtable(); - - X500NameAttrMap xnap = X500NameAttrMap.getDefault(); - while (rdne.hasMoreElements()) { - RDN rdn = (RDN) rdne.nextElement(); - int i = 0; - AVA[] oldavas = rdn.getAssertion(); - for (i = 0; i < rdn.getAssertionLength(); i++) { - AVA[] newavas = new AVA[1]; - newavas[0] = oldavas[i]; - - authCreds.set(xnap.getName(oldavas[i].getOid()), oldavas[i] - .getValue().getAsString()); - - if (oldavas[i].getOid().equals(OID_UNSTRUCTUREDNAME)) { - - sanehash.put(SANE_DNSNAME, oldavas[i].getValue() - .getAsString()); - } - if (oldavas[i].getOid().equals(OID_UNSTRUCTUREDADDRESS)) { - sanehash.put(SANE_IPADDRESS, oldavas[i].getValue() - .getAsString()); - } - - RDN newrdn = new RDN(newavas); - if (mFlattenDN) { - rdnv.addElement(newrdn); - } - } - } - - if (mFlattenDN) - subject = new X500Name(rdnv); - else - subject = p10subject; - - // create default key usage extension - KeyUsageExtension kue = new KeyUsageExtension(); - kue.set(KeyUsageExtension.DIGITAL_SIGNATURE, Boolean.valueOf(true)); - kue.set(KeyUsageExtension.KEY_ENCIPHERMENT, Boolean.valueOf(true)); - - PKCS10Attributes p10atts = p10.getAttributes(); - Enumeration e = p10atts.getElements(); - - while (e.hasMoreElements()) { - PKCS10Attribute p10a = (PKCS10Attribute) e.nextElement(); - CertAttrSet attr = p10a.getAttributeValue(); - - if (attr.getName().equals(ChallengePassword.NAME)) { - if (attr.get(ChallengePassword.PASSWORD) != null) { - req.put(AUTH_PASSWORD, - (String) attr.get(ChallengePassword.PASSWORD)); - req.put(ChallengePassword.NAME, - hashPassword((String) attr - .get(ChallengePassword.PASSWORD))); - } - } - - if (attr.getName().equals(ExtensionsRequested.NAME)) { - - Enumeration exts = ((ExtensionsRequested) attr) - .getExtensions().elements(); - while (exts.hasMoreElements()) { - Extension ext = (Extension) exts.nextElement(); - - if (ext.getExtensionId().equals( - OIDMap.getOID(KeyUsageExtension.IDENT))) { - - kue = new KeyUsageExtension(new Boolean(false), // noncritical - ext.getExtensionValue()); - } - - if (ext.getExtensionId() - .equals(OIDMap - .getOID(SubjectAlternativeNameExtension.IDENT))) { - DerOutputStream dos = new DerOutputStream(); - sane = new SubjectAlternativeNameExtension( - new Boolean(false), // noncritical - ext.getExtensionValue()); - - Vector v = (Vector) sane - .get(SubjectAlternativeNameExtension.SUBJECT_NAME); - - Enumeration gne = v.elements(); - - while (gne.hasMoreElements()) { - GeneralNameInterface gni = (GeneralNameInterface) gne - .nextElement(); - if (gni instanceof GeneralName) { - GeneralName genName = (GeneralName) gni; - - String gn = genName.toString(); - int colon = gn.indexOf(':'); - String gnType = gn.substring(0, colon) - .trim(); - String gnValue = gn.substring(colon + 1) - .trim(); - - authCreds.set(gnType, gnValue); - } - } - } - } - } - } - - if (authCreds != null) - req.put(AUTH_CREDS, authCreds); - - try { - if (sane == null) - sane = makeDefaultSubjectAltName(sanehash); - } catch (Exception sane_e) { - log(ILogger.LL_FAILURE, CMS.getLogMessage( - "CMSGW_ENROLL_FAIL_NO_SUBJ_ALT_NAME", - sane_e.getMessage())); - } - - try { - if (mAppendDN != null && !mAppendDN.equals("")) { - - X500Name newSubject = new X500Name(subject.toString()); - subject = new X500Name(subject.toString().concat( - "," + mAppendDN)); - } - - } catch (Exception sne) { - log(ILogger.LL_INFO, "Unable to use appendDN parameter: " - + mAppendDN + ". Error is " + sne.getMessage() - + " Using unmodified subjectname"); - } - - if (subject != null) - req.put(SUBJECTNAME, subject); - - if (key == null || subject == null) { - // log - // throw new - // ERegistrationException(RegistrationResources.ERROR_MALFORMED_P10); - } - - certInfo.set(X509CertInfo.VERSION, new CertificateVersion( - CertificateVersion.V3)); - - certInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName( - subject)); - - certInfo.set(X509CertInfo.KEY, new CertificateX509Key(key)); - - CertificateExtensions ext = new CertificateExtensions(); - - if (kue != null) { - ext.set(KeyUsageExtension.NAME, kue); - } - - // add subjectAltName extension, if present - if (sane != null) { - ext.set(SubjectAlternativeNameExtension.NAME, sane); - } - - certInfo.set(X509CertInfo.EXTENSIONS, ext); - - req.put(CERTINFO, certInfo); - } catch (Exception e) { - crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badMessageCheck); - crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); - return; - } // NEED TO FIX - } - - private SubjectAlternativeNameExtension makeDefaultSubjectAltName( - Hashtable ht) { - - // if no subjectaltname extension was requested, we try to make it up - // from some of the elements of the subject name - - int itemCount = ht.size(); - GeneralNameInterface[] gn = new GeneralNameInterface[ht.size()]; - - itemCount = 0; - Enumeration en = ht.keys(); - while (en.hasMoreElements()) { - String key = (String) en.nextElement(); - if (key.equals(SANE_DNSNAME)) { - gn[itemCount++] = new DNSName((String) ht.get(key)); - } - if (key.equals(SANE_IPADDRESS)) { - gn[itemCount++] = new IPAddressName((String) ht.get(key)); - } - } - - try { - return new SubjectAlternativeNameExtension(new GeneralNames(gn)); - } catch (Exception e) { - log(ILogger.LL_INFO, - CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_SUBJ_ALT_NAME", - e.getMessage())); - return null; - } + throw new ServletException("Could not decode the request."); + } + crsResp.setMessageType(CRSPKIMessage.mType_CertRep); + + // Create a new crypto context for doing all the crypto operations + cx = new CryptoContext(); + + // Verify Signature on message (throws exception if sig bad) + verifyRequest(req,cx); + + // Deal with Transaction ID + String transactionID = req.getTransactionID(); + if (transactionID == null) { + throw new ServletException("Error: malformed PKIMessage - missing transactionID"); + } + else { + crsResp.setTransactionID(transactionID); + } + + // Deal with Nonces + byte[] sn = req.getSenderNonce(); + if (sn == null) { + throw new ServletException("Error: malformed PKIMessage - missing sendernonce"); + } + else { + if (mNonceSizeLimit > 0 && sn.length > mNonceSizeLimit) { + byte[] snLimited = (mNonceSizeLimit > 0)? new byte[mNonceSizeLimit]: null; + System.arraycopy(sn, 0, snLimited, 0, mNonceSizeLimit); + crsResp.setRecipientNonce(snLimited); + } else { + crsResp.setRecipientNonce(sn); + } + byte[] serverNonce = new byte[16]; + mRandom.nextBytes(serverNonce); + crsResp.setSenderNonce(serverNonce); + // crsResp.setSenderNonce(new byte[] {0}); + } + + // Deal with message type + String mt = req.getMessageType(); + if (mt == null) { + throw new ServletException("Error: malformed PKIMessage - missing messageType"); + } + + // now run appropriate code, depending on message type + if (mt.equals(CRSPKIMessage.mType_PKCSReq)) { + CMS.debug("Processing PKCSReq"); + try { + // Check if there is an existing request. If this returns non-null, + // then the request is 'active' (either pending or completed) in + // which case, we compare the hash of the new request to the hash of the + // one in the queue - if they are the same, I return the state of the + // original request - as if it was 'getCertInitial' message. + // If the hashes are different, then the user attempted to enroll + // for a new request with the same txid, which is not allowed - + // so we return 'failure'. + + IRequest cmsRequest= findRequestByTransactionID(req.getTransactionID(),true); + + // If there was no request (with a cert) with this transaction ID, + // process it as a new request + + cert = handlePKCSReq(httpReq, cmsRequest,req,crsResp,cx); + + } + catch (CRSFailureException e) { + throw new ServletException("Couldn't handle CEP request (PKCSReq) - "+e.getMessage()); + } + } + else if (mt.equals(CRSPKIMessage.mType_GetCertInitial)) { + CMS.debug("Processing GetCertInitial"); + cert = handleGetCertInitial(req,crsResp); + } else { + CMS.debug("Invalid request type " + mt); + } + } + catch (ServletException e) { + throw new ServletException(e.getMessage().toString()); + } + catch (CRSInvalidSignatureException e) { + CMS.debug("handlePKIMessage exception " + e); + CMS.debug(e); + crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badMessageCheck); + } + catch (Exception e) { + CMS.debug("handlePKIMessage exception " + e); + CMS.debug(e); + throw new ServletException("Failed to process message in CEP servlet: "+ e.getMessage()); + } + + // We have now processed the request, and need to make the response message + + try { + // make the response + processCertRep(cx, cert,crsResp, req); + + // Get the response coding + response = crsResp.getResponse(); + + // Encode the crsResp into B64 + httpResp.setContentType("application/x-pki-message"); + httpResp.setContentLength(response.length); + httpResp.getOutputStream().write(response); + httpResp.getOutputStream().flush(); + + CMS.debug("Output PKIOperation response:"); + CMS.debug(CMS.BtoA(response)); + } + catch (Exception e) { + throw new ServletException("Failed to create response for CEP message"+e.getMessage()); + } + + } + + + /** + * finds a request with this transaction ID. + * If could not find any request - return null + * If could only find 'rejected' or 'cancelled' requests, return null + * If found 'pending' or 'completed' request - return that request + */ + + public IRequest findRequestByTransactionID(String txid, boolean ignoreRejected) + throws EBaseException { + + /* Check if certificate request has been completed */ + + IRequestQueue rq = ca.getRequestQueue(); + IRequest foundRequest = null; + + Enumeration rids = rq.findRequestsBySourceId(txid); + if (rids == null) { return null; } + + int count=0; + while (rids.hasMoreElements()) { + RequestId rid = (RequestId) rids.nextElement(); + if (rid == null) { + continue; + } + + IRequest request = rq.findRequest(rid); + if (request == null) { + continue; + } + if ( !ignoreRejected || + request.getRequestStatus().equals(RequestStatus.PENDING) || + request.getRequestStatus().equals(RequestStatus.COMPLETE)) { + if (foundRequest != null) { + } + foundRequest = request; + } + } + return foundRequest; + } + + /** + * Called if the router is requesting us to send it its certificate + * Examine request queue for a request matching the transaction ID. + * Ignore any rejected or cancelled requests. + * + * If a request is found in the pending state, the response should be + * 'pending' + * + * If a request is found in the completed state, the response should be + * to return the certificate + * + * If no request is found, the response should be to return null + * + */ + + public X509CertImpl handleGetCertInitial(CRSPKIMessage req,CRSPKIMessage resp) + { + IRequest foundRequest=null; + + // already done by handlePKIOperation + // resp.setRecipientNonce(req.getSenderNonce()); + // resp.setSenderNonce(null); + + try { + foundRequest = findRequestByTransactionID(req.getTransactionID(),false); + } catch (EBaseException e) { + } + + if (foundRequest == null) { + resp.setFailInfo(CRSPKIMessage.mFailInfo_badCertId); + resp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); + return null; + } + + return makeResponseFromRequest(req,resp,foundRequest); + } + + + public void verifyRequest(CRSPKIMessage req, CryptoContext cx) + throws CRSInvalidSignatureException { + + // Get Signed Data + + byte[] reqAAbytes = req.getAA(); + byte[] reqAAsig = req.getAADigest(); + + } + + + /** + * Create an entry for this user in the publishing directory + * + */ + + private boolean createEntry(String dn) + { + boolean result = false; + + IPublisherProcessor ldapPub = mAuthority.getPublisherProcessor(); + if (ldapPub == null || !ldapPub.enabled()) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_CREATE_ENTRY_FROM_CEP")); + + return result; + } + + ILdapConnFactory connFactory = ((IPublisherProcessor)ldapPub).getLdapConnModule().getLdapConnFactory(); + if (connFactory == null) { + return result; + } + + LDAPConnection connection=null; + try { + connection = connFactory.getConn(); + String[] objectclasses = { "top", mEntryObjectclass }; + LDAPAttribute ocAttrs = new LDAPAttribute("objectclass",objectclasses); + + LDAPAttributeSet attrSet = new LDAPAttributeSet(); + attrSet.add(ocAttrs); + + LDAPEntry newEntry = new LDAPEntry(dn, attrSet); + connection.add(newEntry); + result=true; + } + catch (Exception e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_FAIL_CREAT_ENTRY_EXISTS",dn)); + } + finally { + try { + connFactory.returnConn(connection); + } + catch (Exception f) {} + } + return result; } - // Perform authentication - - /* - * if the authentication is set up for CEP, and the user provides some - * credential, an attempt is made to authenticate the user If this fails, - * this method will return true If it is sucessful, this method will return - * true and an authtoken will be in the request - * - * If authentication is not configured, this method will return false. The - * request will be processed in the usual way, but no authtoken will be in - * the request. - * - * In other word, this method returns true if the request should be aborted, - * false otherwise. - */ - - private boolean authenticateUser(CRSPKIMessage req) { - boolean authenticationFailed = true; - - if (mAuthManagerName == null) { - return false; - } - - String password = (String) req.get(AUTH_PASSWORD); - - AuthCredentials authCreds = (AuthCredentials) req.get(AUTH_CREDS); - - if (authCreds == null) { - authCreds = new AuthCredentials(); - } - - // authtoken starts as null - AuthToken token = null; - - if (password != null && !password.equals("")) { - try { - authCreds.set(AUTH_PASSWORD, password); - } catch (Exception e) { - } - } - try { - token = (AuthToken) mAuthSubsystem.authenticate(authCreds, - mAuthManagerName); - authCreds.delete(AUTH_PASSWORD); - // if we got here, the authenticate call must not have thrown - // an exception - authenticationFailed = false; - } catch (EInvalidCredentials ex) { - // Invalid credentials - we must reject the request - authenticationFailed = true; - } catch (EMissingCredential mc) { - // Misssing credential - we'll log, and process manually - authenticationFailed = false; - } catch (EBaseException ex) { - // If there's some other error, we'll reject - // So, we just continue on, - AUTH_TOKEN will not be set. - } - if (token != null) { - req.put(AUTH_TOKEN, token); + /** + * Here we decrypt the PKCS10 message from the client + * + */ + + public void unwrapPKCS10(CRSPKIMessage req, CryptoContext cx) + throws ServletException, + CryptoManager.NotInitializedException, + CryptoContext.CryptoContextException, + CRSFailureException { + + byte[] decryptedP10bytes = null; + SymmetricKey sk; + SymmetricKey skinternal; + SymmetricKey.Type skt; + KeyWrapper kw; + Cipher cip; + EncryptionAlgorithm ea; + boolean errorInRequest = false; + + // Unwrap the session key with the Cert server key + try { + kw = cx.getKeyWrapper(); + + kw.initUnwrap(cx.getPrivateKey(),null); + + skt = SymmetricKey.Type.DES; + ea = EncryptionAlgorithm.DES_CBC; + if (mEncryptionAlgorithm != null && mEncryptionAlgorithm.equals("DES3")) { + skt = SymmetricKey.Type.DES3; + ea = EncryptionAlgorithm.DES3_CBC; + } + + sk = kw.unwrapSymmetric(req.getWrappedKey(), + skt, + SymmetricKey.Usage.DECRYPT, + 0); // keylength is ignored + + skinternal = cx.getDESKeyGenerator().clone(sk); + + cip = skinternal.getOwningToken().getCipherContext(ea); + + cip.initDecrypt(skinternal,(new IVParameterSpec(req.getIV()))); + + decryptedP10bytes = cip.doFinal(req.getEncryptedPkcs10()); + CMS.debug("decryptedP10bytes:"); + CMS.debug(decryptedP10bytes); + + req.setP10(new PKCS10(decryptedP10bytes)); + } catch (Exception e) { + CMS.debug("failed to unwrap PKCS10 " + e); + throw new CRSFailureException("Could not unwrap PKCS10 blob: "+e.getMessage()); + } + + } + + + +private void getDetailFromRequest(CRSPKIMessage req, CRSPKIMessage crsResp) + throws CRSFailureException { + + IRequest issueReq = null; + X509CertImpl issuedCert=null; + Vector extensionsRequested = null; + SubjectAlternativeNameExtension sane = null; + CertAttrSet requested_ext = null; + + try { + PKCS10 p10 = (PKCS10)req.getP10(); + + if (p10 == null) { + crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badMessageCheck); + crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); + throw new CRSFailureException("Failed to decode pkcs10 from CEP request"); + } + + AuthCredentials authCreds = new AuthCredentials(); + + String challengePassword = null; + // Here, we make a new CertInfo - it's a new start for a certificate + + X509CertInfo certInfo = CMS.getDefaultX509CertInfo(); + + // get some stuff out of the request + X509Key key = p10.getSubjectPublicKeyInfo(); + X500Name p10subject = p10.getSubjectName(); + + X500Name subject=null; + + // The following code will copy all the attributes + // into the AuthCredentials so they can be used for + // authentication + // + // Optionally, you can re-map the subject name from: + // one RDN, with many AVA's to + // many RDN's with one AVA in each. + + Enumeration rdne = p10subject.getRDNs(); + Vector rdnv = new Vector(); + + Hashtable sanehash = new Hashtable(); + + X500NameAttrMap xnap = X500NameAttrMap.getDefault(); + while (rdne.hasMoreElements()) { + RDN rdn = (RDN) rdne.nextElement(); + int i=0; + AVA[] oldavas = rdn.getAssertion(); + for (i=0; i<rdn.getAssertionLength(); i++) { + AVA[] newavas = new AVA[1]; + newavas[0] = oldavas[i]; + + authCreds.set(xnap.getName(oldavas[i].getOid()), + oldavas[i].getValue().getAsString()); + + if (oldavas[i].getOid().equals(OID_UNSTRUCTUREDNAME)) { + + sanehash.put(SANE_DNSNAME,oldavas[i].getValue().getAsString()); + } + if (oldavas[i].getOid().equals(OID_UNSTRUCTUREDADDRESS)) { + sanehash.put(SANE_IPADDRESS,oldavas[i].getValue().getAsString()); + } + + RDN newrdn = new RDN(newavas); + if (mFlattenDN) { + rdnv.addElement(newrdn); + } + } + } + + if (mFlattenDN) subject = new X500Name(rdnv); + else subject = p10subject; + + + // create default key usage extension + KeyUsageExtension kue = new KeyUsageExtension(); + kue.set(KeyUsageExtension.DIGITAL_SIGNATURE, Boolean.valueOf(true)); + kue.set(KeyUsageExtension.KEY_ENCIPHERMENT, Boolean.valueOf(true)); + + + PKCS10Attributes p10atts = p10.getAttributes(); + Enumeration e = p10atts.getElements(); + + while (e.hasMoreElements()) { + PKCS10Attribute p10a = (PKCS10Attribute)e.nextElement(); + CertAttrSet attr = p10a.getAttributeValue(); + + + if (attr.getName().equals(ChallengePassword.NAME)) { + if (attr.get(ChallengePassword.PASSWORD) != null) { + req.put(AUTH_PASSWORD, + (String)attr.get(ChallengePassword.PASSWORD)); + req.put(ChallengePassword.NAME, + hashPassword( + (String)attr.get(ChallengePassword.PASSWORD))); + } + } + + if (attr.getName().equals(ExtensionsRequested.NAME)) { + + Enumeration exts = ((ExtensionsRequested)attr).getExtensions().elements(); + while (exts.hasMoreElements()) { + Extension ext = (Extension) exts.nextElement(); + + if (ext.getExtensionId().equals( + OIDMap.getOID(KeyUsageExtension.IDENT)) ) { + + kue = new KeyUsageExtension( + new Boolean(false), // noncritical + ext.getExtensionValue()); + } + + if (ext.getExtensionId().equals( + OIDMap.getOID(SubjectAlternativeNameExtension.IDENT)) ) { + DerOutputStream dos = new DerOutputStream(); + sane = new SubjectAlternativeNameExtension( + new Boolean(false), // noncritical + ext.getExtensionValue()); + + + Vector v = + (Vector) sane.get(SubjectAlternativeNameExtension. SUBJECT_NAME); + + Enumeration gne = v.elements(); + + while (gne.hasMoreElements()) { + GeneralNameInterface gni = (GeneralNameInterface) gne.nextElement(); + if (gni instanceof GeneralName) { + GeneralName genName = (GeneralName) gni; + + String gn = genName.toString(); + int colon = gn.indexOf(':'); + String gnType = gn.substring(0,colon).trim(); + String gnValue = gn.substring(colon+1).trim(); + + authCreds.set(gnType,gnValue); + } + } + } + } + } + } + + if (authCreds != null) req.put(AUTH_CREDS,authCreds); + + try { + if (sane == null) sane = makeDefaultSubjectAltName(sanehash); + } catch (Exception sane_e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_SUBJ_ALT_NAME", + sane_e.getMessage())); + } + + + + try { + if (mAppendDN != null && ! mAppendDN.equals("")) { + + X500Name newSubject = new X500Name(subject.toString()); + subject = new X500Name( subject.toString().concat(","+mAppendDN)); + } + + } catch (Exception sne) { + log(ILogger.LL_INFO, "Unable to use appendDN parameter: "+mAppendDN+". Error is "+sne.getMessage()+" Using unmodified subjectname"); + } + + if (subject != null) req.put(SUBJECTNAME, subject); + + if (key == null || subject == null) { + // log + //throw new ERegistrationException(RegistrationResources.ERROR_MALFORMED_P10); + } + + + + certInfo.set(X509CertInfo.VERSION, + new CertificateVersion(CertificateVersion.V3)); + + certInfo.set(X509CertInfo.SUBJECT, + new CertificateSubjectName(subject)); + + certInfo.set(X509CertInfo.KEY, + new CertificateX509Key(key)); + + CertificateExtensions ext = new CertificateExtensions(); + + if (kue != null) { + ext.set(KeyUsageExtension.NAME, kue); + } + + // add subjectAltName extension, if present + if (sane != null) { + ext.set(SubjectAlternativeNameExtension.NAME, sane); + } + + certInfo.set(X509CertInfo.EXTENSIONS,ext); + + req.put(CERTINFO, certInfo); + } catch (Exception e) { + crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badMessageCheck); + crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); + return ; + } // NEED TO FIX + } + + + private SubjectAlternativeNameExtension makeDefaultSubjectAltName(Hashtable ht) { + + // if no subjectaltname extension was requested, we try to make it up + // from some of the elements of the subject name + + int itemCount = ht.size(); + GeneralNameInterface[] gn = new GeneralNameInterface[ht.size()]; + + itemCount = 0; + Enumeration en = ht.keys(); + while (en.hasMoreElements()) { + String key = (String) en.nextElement(); + if (key.equals(SANE_DNSNAME)) { + gn[itemCount++] = new DNSName((String)ht.get(key)); + } + if (key.equals(SANE_IPADDRESS)) { + gn[itemCount++] = new IPAddressName((String)ht.get(key)); } - - return authenticationFailed; } - private boolean areFingerprintsEqual(IRequest req, Hashtable fingerprints) { - - Hashtable old_fprints = req - .getExtDataInHashtable(IRequest.FINGERPRINTS); - if (old_fprints == null) { - return false; - } - - byte[] old_md5 = CMS.AtoB((String) old_fprints.get("MD5")); - byte[] new_md5 = (byte[]) fingerprints.get("MD5"); - - if (old_md5.length != new_md5.length) - return false; - - for (int i = 0; i < old_md5.length; i++) { - if (old_md5[i] != new_md5[i]) - return false; - } - return true; - } - - public X509CertImpl handlePKCSReq(HttpServletRequest httpReq, - IRequest cmsRequest, CRSPKIMessage req, CRSPKIMessage crsResp, - CryptoContext cx) throws ServletException, - CryptoManager.NotInitializedException, CRSFailureException { - - try { - unwrapPKCS10(req, cx); - Hashtable fingerprints = makeFingerPrints(req); - - if (cmsRequest != null) { - if (areFingerprintsEqual(cmsRequest, fingerprints)) { - CMS.debug("created response from request"); - return makeResponseFromRequest(req, crsResp, cmsRequest); - } else { - CMS.debug("duplicated transaction id"); - log(ILogger.LL_FAILURE, - CMS.getLogMessage("CMSGW_ENROLL_FAIL_DUP_TRANS_ID")); - crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badRequest); - crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); - return null; - } - } - - getDetailFromRequest(req, crsResp); - boolean authFailed = authenticateUser(req); - - if (authFailed) { - CMS.debug("authentication failed"); - log(ILogger.LL_SECURITY, - CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_AUTH")); - crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badIdentity); - crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); - - // perform audit log - String auditMessage = CMS.getLogMessage( - "LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST_5", - httpReq.getRemoteAddr(), ILogger.FAILURE, - req.getTransactionID(), "CRSEnrollment", - ILogger.SIGNED_AUDIT_EMPTY_VALUE); - ILogger signedAuditLogger = CMS.getSignedAuditLogger(); - if (signedAuditLogger != null) { - signedAuditLogger.log(ILogger.EV_SIGNED_AUDIT, null, - ILogger.S_SIGNED_AUDIT, ILogger.LL_SECURITY, - auditMessage); - } - - return null; - } else { - IRequest ireq = postRequest(httpReq, req, crsResp); - - CMS.debug("created response"); - return makeResponseFromRequest(req, crsResp, ireq); - } - } catch (CryptoContext.CryptoContextException e) { - CMS.debug("failed to decrypt the request " + e); - log(ILogger.LL_FAILURE, - CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_DECRYPT_PKCS10", - e.getMessage())); - crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badMessageCheck); - crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); - } catch (EBaseException e) { - CMS.debug("operation failure - " + e); - log(ILogger.LL_FAILURE, CMS.getLogMessage( - "CMSGW_ERNOLL_FAIL_NO_NEW_REQUEST_POSTED", e.getMessage())); - crsResp.setFailInfo(CRSPKIMessage.mFailInfo_internalCAError); - crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); - } - return null; - } - - // //// post the request - - /* - * needed: - * - * token (authtoken) certInfo fingerprints x req.transactionID crsResp - */ - - private IRequest postRequest(HttpServletRequest httpReq, CRSPKIMessage req, - CRSPKIMessage crsResp) throws EBaseException { - X500Name subject = (X500Name) req.get(SUBJECTNAME); - - if (mCreateEntry) { - if (subject == null) { - CMS.debug("CRSEnrollment::postRequest() - subject is null!"); - return null; - } - createEntry(subject.toString()); - } - - // use profile framework to handle SCEP - if (mProfileId != null) { - PKCS10 pkcs10data = (PKCS10) req.getP10(); - String pkcs10blob = CMS.BtoA(pkcs10data.toByteArray()); - - // XXX authentication handling - CMS.debug("Found profile=" + mProfileId); - IProfile profile = mProfileSubsystem.getProfile(mProfileId); - if (profile == null) { - CMS.debug("profile " + mProfileId + " not found"); - return null; - } - IProfileContext ctx = profile.createContext(); - - IProfileAuthenticator authenticator = null; - try { - CMS.debug("Retrieving authenticator"); - authenticator = profile.getAuthenticator(); - if (authenticator == null) { - CMS.debug("No authenticator Found"); - } else { - CMS.debug("Got authenticator=" - + authenticator.getClass().getName()); - } - } catch (EProfileException e) { - // authenticator not installed correctly - } - - IAuthToken authToken = null; - - // for ssl authentication; pass in servlet for retrieving - // ssl client certificates - SessionContext context = SessionContext.getContext(); - - // insert profile context so that input parameter can be retrieved - context.put("profileContext", ctx); - context.put("sslClientCertProvider", new SSLClientCertProvider( - httpReq)); - - String p10Password = getPasswordFromP10(pkcs10data); - AuthCredentials credentials = new AuthCredentials(); - credentials.set("UID", httpReq.getRemoteAddr()); - credentials.set("PWD", p10Password); + try { + return new SubjectAlternativeNameExtension( new GeneralNames(gn) ); + } catch (Exception e) { + log(ILogger.LL_INFO, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_SUBJ_ALT_NAME", + e.getMessage())); + return null; + } + } + + + + // Perform authentication + + /* + * if the authentication is set up for CEP, and the user provides + * some credential, an attempt is made to authenticate the user + * If this fails, this method will return true + * If it is sucessful, this method will return true and + * an authtoken will be in the request + * + * If authentication is not configured, this method will + * return false. The request will be processed in the usual + * way, but no authtoken will be in the request. + * + * In other word, this method returns true if the request + * should be aborted, false otherwise. + */ + + private boolean authenticateUser(CRSPKIMessage req) { + boolean authenticationFailed = true; + + if (mAuthManagerName == null) { + return false; + } + + String password = (String)req.get(AUTH_PASSWORD); + + AuthCredentials authCreds = (AuthCredentials)req.get(AUTH_CREDS); + + if (authCreds == null) { + authCreds = new AuthCredentials(); + } + + // authtoken starts as null + AuthToken token = null; + + if (password != null && !password.equals("")) { + try { + authCreds.set(AUTH_PASSWORD,password); + } catch (Exception e) {} + } + + try { + token = (AuthToken)mAuthSubsystem.authenticate(authCreds,mAuthManagerName); + authCreds.delete(AUTH_PASSWORD); + // if we got here, the authenticate call must not have thrown + // an exception + authenticationFailed = false; + } + catch (EInvalidCredentials ex) { + // Invalid credentials - we must reject the request + authenticationFailed = true; + } + catch (EMissingCredential mc) { + // Misssing credential - we'll log, and process manually + authenticationFailed = false; + } + catch (EBaseException ex) { + // If there's some other error, we'll reject + // So, we just continue on, - AUTH_TOKEN will not be set. + } + + if (token != null) { + req.put(AUTH_TOKEN,token); + } + + return authenticationFailed; + } + + private boolean areFingerprintsEqual(IRequest req, Hashtable fingerprints) + { + + Hashtable old_fprints = req.getExtDataInHashtable(IRequest.FINGERPRINTS); + if (old_fprints == null) { return false; } + + byte[] old_md5 = CMS.AtoB((String) old_fprints.get("MD5")); + byte[] new_md5 = (byte[]) fingerprints.get("MD5"); + + if (old_md5.length != new_md5.length) return false; + + for (int i=0;i<old_md5.length; i++) { + if (old_md5[i] != new_md5[i]) return false; + } + return true; + } + + public X509CertImpl handlePKCSReq(HttpServletRequest httpReq, + IRequest cmsRequest, CRSPKIMessage req, + CRSPKIMessage crsResp, CryptoContext cx) + throws ServletException, + CryptoManager.NotInitializedException, + CRSFailureException { + + try { + unwrapPKCS10(req,cx); + Hashtable fingerprints = makeFingerPrints(req); + + if (cmsRequest != null) { + if (areFingerprintsEqual(cmsRequest, fingerprints)) { + CMS.debug("created response from request"); + return makeResponseFromRequest(req,crsResp,cmsRequest); + } + else { + CMS.debug("duplicated transaction id"); + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ENROLL_FAIL_DUP_TRANS_ID")); + crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badRequest); + crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); + return null; + } + } + + getDetailFromRequest(req,crsResp); + boolean authFailed = authenticateUser(req); + + if (authFailed) { + CMS.debug("authentication failed"); + log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_AUTH")); + crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badIdentity); + crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); + + + // perform audit log + String auditMessage = CMS.getLogMessage( + "LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST_5", + httpReq.getRemoteAddr(), + ILogger.FAILURE, + req.getTransactionID(), + "CRSEnrollment", + ILogger.SIGNED_AUDIT_EMPTY_VALUE); + ILogger signedAuditLogger = CMS.getSignedAuditLogger(); + if (signedAuditLogger != null) { + signedAuditLogger.log(ILogger.EV_SIGNED_AUDIT, + null, ILogger.S_SIGNED_AUDIT, + ILogger.LL_SECURITY, auditMessage); + } + + return null; + } + else { + IRequest ireq = postRequest(httpReq, req,crsResp); + + + CMS.debug("created response"); + return makeResponseFromRequest(req,crsResp, ireq); + } + } catch (CryptoContext.CryptoContextException e) { + CMS.debug("failed to decrypt the request " + e); + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_DECRYPT_PKCS10", + e.getMessage())); + crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badMessageCheck); + crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); + } catch (EBaseException e) { + CMS.debug("operation failure - " + e); + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERNOLL_FAIL_NO_NEW_REQUEST_POSTED", + e.getMessage())); + crsResp.setFailInfo(CRSPKIMessage.mFailInfo_internalCAError); + crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); + } + return null; + } + + +////// post the request + +/* + needed: + + token (authtoken) + certInfo + fingerprints x + req.transactionID + crsResp +*/ + +private IRequest postRequest(HttpServletRequest httpReq, CRSPKIMessage req, CRSPKIMessage crsResp) +throws EBaseException { + X500Name subject = (X500Name)req.get(SUBJECTNAME); + + if (mCreateEntry) { + if (subject == null) { + CMS.debug( "CRSEnrollment::postRequest() - subject is null!" ); + return null; + } + createEntry(subject.toString()); + } + + // use profile framework to handle SCEP + if (mProfileId != null) { + PKCS10 pkcs10data = (PKCS10)req.getP10(); + String pkcs10blob = CMS.BtoA(pkcs10data.toByteArray()); + + // XXX authentication handling + CMS.debug("Found profile=" + mProfileId); + IProfile profile = mProfileSubsystem.getProfile(mProfileId); + if (profile == null) { + CMS.debug("profile " + mProfileId + " not found"); + return null; + } + IProfileContext ctx = profile.createContext(); + + IProfileAuthenticator authenticator = null; + try { + CMS.debug("Retrieving authenticator"); + authenticator = profile.getAuthenticator(); if (authenticator == null) { - // XXX - to help caRouterCert to work, we need to - // add authentication to caRouterCert - authToken = new AuthToken(null); - } else { - authToken = authenticate(credentials, authenticator, httpReq); - } - - IRequest reqs[] = null; - CMS.debug("CRSEnrollment: Creating profile requests"); - ctx.set(IEnrollProfile.CTX_CERT_REQUEST_TYPE, "pkcs10"); - ctx.set(IEnrollProfile.CTX_CERT_REQUEST, pkcs10blob); - Locale locale = Locale.getDefault(); - reqs = profile.createRequests(ctx, locale); - if (reqs == null) { - CMS.debug("CRSEnrollment: No request has been created"); - return null; + CMS.debug("No authenticator Found"); } else { - CMS.debug("CRSEnrollment: Request (" + reqs.length - + ") have been created"); - } - // set transaction id - reqs[0].setSourceId(req.getTransactionID()); - reqs[0].setExtData("profile", "true"); - reqs[0].setExtData("profileId", mProfileId); - reqs[0].setExtData(IEnrollProfile.CTX_CERT_REQUEST_TYPE, - IEnrollProfile.REQ_TYPE_PKCS10); - reqs[0].setExtData(IEnrollProfile.CTX_CERT_REQUEST, pkcs10blob); - reqs[0].setExtData("requestor_name", ""); - reqs[0].setExtData("requestor_email", ""); - reqs[0].setExtData("requestor_phone", ""); - reqs[0].setExtData("profileRemoteHost", httpReq.getRemoteHost()); - reqs[0].setExtData("profileRemoteAddr", httpReq.getRemoteAddr()); - reqs[0].setExtData("profileApprovedBy", profile.getApprovedBy()); - - CMS.debug("CRSEnrollment: Populating inputs"); - profile.populateInput(ctx, reqs[0]); - CMS.debug("CRSEnrollment: Populating requests"); - profile.populate(reqs[0]); - - CMS.debug("CRSEnrollment: Submitting request"); - profile.submit(authToken, reqs[0]); - CMS.debug("CRSEnrollment: Done submitting request"); - profile.getRequestQueue().markAsServiced(reqs[0]); - CMS.debug("CRSEnrollment: Request marked as serviced"); - - return reqs[0]; - - } - - IRequestQueue rq = ca.getRequestQueue(); - IRequest pkiReq = rq.newRequest(IRequest.ENROLLMENT_REQUEST); - - AuthToken token = (AuthToken) req.get(AUTH_TOKEN); - if (token != null) { - pkiReq.setExtData(IRequest.AUTH_TOKEN, token); - } - - pkiReq.setExtData(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE, - IRequest.CEP_CERT); - X509CertInfo certInfo = (X509CertInfo) req.get(CERTINFO); - pkiReq.setExtData(IRequest.CERT_INFO, new X509CertInfo[] { certInfo }); - pkiReq.setExtData("cepsubstore", mSubstoreName); - - try { - String chpwd = (String) req.get(ChallengePassword.NAME); - if (chpwd != null) { - pkiReq.setExtData("challengePhrase", chpwd); - } - } catch (Exception pwex) { - } - - Hashtable fingerprints = (Hashtable) req.get(IRequest.FINGERPRINTS); - if (fingerprints.size() > 0) { - Hashtable encodedPrints = new Hashtable(fingerprints.size()); - Enumeration e = fingerprints.keys(); - while (e.hasMoreElements()) { - String key = (String) e.nextElement(); - byte[] value = (byte[]) fingerprints.get(key); - encodedPrints.put(key, CMS.BtoA(value)); + CMS.debug("Got authenticator=" + authenticator.getClass().getName()); } - pkiReq.setExtData(IRequest.FINGERPRINTS, encodedPrints); - } - - pkiReq.setSourceId(req.getTransactionID()); - - rq.processRequest(pkiReq); - - crsResp.setPKIStatus(CRSPKIMessage.mStatus_SUCCESS); - - mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL, - AuditFormat.ENROLLMENTFORMAT, - new Object[] { - pkiReq.getRequestId(), - AuditFormat.FROMROUTER, - mAuthManagerName == null ? AuditFormat.NOAUTH - : mAuthManagerName, "pending", subject, "" }); - - return pkiReq; - } - - public Hashtable makeFingerPrints(CRSPKIMessage req) { + } catch (EProfileException e) { + // authenticator not installed correctly + } + + IAuthToken authToken = null; + + // for ssl authentication; pass in servlet for retrieving + // ssl client certificates + SessionContext context = SessionContext.getContext(); + + + // insert profile context so that input parameter can be retrieved + context.put("profileContext", ctx); + context.put("sslClientCertProvider", + new SSLClientCertProvider(httpReq)); + + String p10Password = getPasswordFromP10(pkcs10data); + AuthCredentials credentials = new AuthCredentials(); + credentials.set("UID", httpReq.getRemoteAddr()); + credentials.set("PWD", p10Password); + + if (authenticator == null) { + // XXX - to help caRouterCert to work, we need to + // add authentication to caRouterCert + authToken = new AuthToken(null); + } else { + authToken = authenticate(credentials, authenticator, httpReq); + } + + IRequest reqs[] = null; + CMS.debug("CRSEnrollment: Creating profile requests"); + ctx.set(IEnrollProfile.CTX_CERT_REQUEST_TYPE, "pkcs10"); + ctx.set(IEnrollProfile.CTX_CERT_REQUEST, pkcs10blob); + Locale locale = Locale.getDefault(); + reqs = profile.createRequests(ctx, locale); + if (reqs == null) { + CMS.debug("CRSEnrollment: No request has been created"); + return null; + } else { + CMS.debug("CRSEnrollment: Request (" + reqs.length + ") have been created"); + } + // set transaction id + reqs[0].setSourceId(req.getTransactionID()); + reqs[0].setExtData("profile", "true"); + reqs[0].setExtData("profileId", mProfileId); + reqs[0].setExtData(IEnrollProfile.CTX_CERT_REQUEST_TYPE, IEnrollProfile.REQ_TYPE_PKCS10); + reqs[0].setExtData(IEnrollProfile.CTX_CERT_REQUEST, pkcs10blob); + reqs[0].setExtData("requestor_name", ""); + reqs[0].setExtData("requestor_email", ""); + reqs[0].setExtData("requestor_phone", ""); + reqs[0].setExtData("profileRemoteHost", httpReq.getRemoteHost()); + reqs[0].setExtData("profileRemoteAddr", httpReq.getRemoteAddr()); + reqs[0].setExtData("profileApprovedBy", profile.getApprovedBy()); + + CMS.debug("CRSEnrollment: Populating inputs"); + profile.populateInput(ctx, reqs[0]); + CMS.debug("CRSEnrollment: Populating requests"); + profile.populate(reqs[0]); + + CMS.debug("CRSEnrollment: Submitting request"); + profile.submit(authToken, reqs[0]); + CMS.debug("CRSEnrollment: Done submitting request"); + profile.getRequestQueue().markAsServiced(reqs[0]); + CMS.debug("CRSEnrollment: Request marked as serviced"); + + return reqs[0]; + + } + + IRequestQueue rq = ca.getRequestQueue(); + IRequest pkiReq = rq.newRequest(IRequest.ENROLLMENT_REQUEST); + + AuthToken token = (AuthToken) req.get(AUTH_TOKEN); + if (token != null) { + pkiReq.setExtData(IRequest.AUTH_TOKEN,token); + } + + pkiReq.setExtData(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE, IRequest.CEP_CERT); + X509CertInfo certInfo = (X509CertInfo) req.get(CERTINFO); + pkiReq.setExtData(IRequest.CERT_INFO, new X509CertInfo[] { certInfo } ); + pkiReq.setExtData("cepsubstore", mSubstoreName); + + try { + String chpwd = (String)req.get(ChallengePassword.NAME); + if (chpwd != null) { + pkiReq.setExtData("challengePhrase", + chpwd ); + } + } catch (Exception pwex) { + } + + Hashtable fingerprints = (Hashtable)req.get(IRequest.FINGERPRINTS); + if (fingerprints.size() > 0) { + Hashtable encodedPrints = new Hashtable(fingerprints.size()); + Enumeration e = fingerprints.keys(); + while (e.hasMoreElements()) { + String key = (String)e.nextElement(); + byte[] value = (byte[])fingerprints.get(key); + encodedPrints.put(key, CMS.BtoA(value)); + } + pkiReq.setExtData(IRequest.FINGERPRINTS, encodedPrints); + } + + pkiReq.setSourceId(req.getTransactionID()); + + rq.processRequest(pkiReq); + + crsResp.setPKIStatus(CRSPKIMessage.mStatus_SUCCESS); + + mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, + AuditFormat.LEVEL, + AuditFormat.ENROLLMENTFORMAT, + new Object[] { + pkiReq.getRequestId(), + AuditFormat.FROMROUTER, + mAuthManagerName == null ? AuditFormat.NOAUTH : mAuthManagerName, + "pending", + subject , + ""} + ); + + return pkiReq; + } + + + + public Hashtable makeFingerPrints(CRSPKIMessage req) { Hashtable fingerprints = new Hashtable(); MessageDigest md; - String[] hashes = new String[] { "MD2", "MD5", "SHA1", "SHA256", - "SHA512" }; - PKCS10 p10 = (PKCS10) req.getP10(); + String[] hashes = new String[] {"MD2", "MD5", "SHA1", "SHA256", "SHA512"}; + PKCS10 p10 = (PKCS10)req.getP10(); - for (int i = 0; i < hashes.length; i++) { - try { - md = MessageDigest.getInstance(hashes[i]); - md.update(p10.getCertRequestInfo()); - fingerprints.put(hashes[i], md.digest()); - } catch (NoSuchAlgorithmException nsa) { - } + for (int i=0;i<hashes.length;i++) { + try { + md = MessageDigest.getInstance(hashes[i]); + md.update(p10.getCertRequestInfo()); + fingerprints.put(hashes[i],md.digest()); + } + catch (NoSuchAlgorithmException nsa) {} } - if (fingerprints != null) { - req.put(IRequest.FINGERPRINTS, fingerprints); - } - return fingerprints; - } + if (fingerprints != null) { + req.put(IRequest.FINGERPRINTS,fingerprints); + } + return fingerprints; + } + + + // Take a look to see if the request was successful, and fill + // in the response message - // Take a look to see if the request was successful, and fill - // in the response message - private X509CertImpl makeResponseFromRequest(CRSPKIMessage crsReq, - CRSPKIMessage crsResp, IRequest pkiReq) { + private X509CertImpl makeResponseFromRequest(CRSPKIMessage crsReq, CRSPKIMessage crsResp, + IRequest pkiReq) + { - X509CertImpl issuedCert = null; + X509CertImpl issuedCert=null; RequestStatus status = pkiReq.getRequestStatus(); String profileId = pkiReq.getExtDataInString("profileId"); if (profileId != null) { - CMS.debug("CRSEnrollment: Found profile request"); - X509CertImpl cert = pkiReq - .getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT); - if (cert == null) { - CMS.debug("CRSEnrollment: No certificate has been found"); - } else { - CMS.debug("CRSEnrollment: Found certificate"); - } - crsResp.setPKIStatus(CRSPKIMessage.mStatus_SUCCESS); - return cert; + CMS.debug("CRSEnrollment: Found profile request"); + X509CertImpl cert = + pkiReq.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT); + if (cert == null) { + CMS.debug("CRSEnrollment: No certificate has been found"); + } else { + CMS.debug("CRSEnrollment: Found certificate"); + } + crsResp.setPKIStatus(CRSPKIMessage.mStatus_SUCCESS); + return cert; } - if (status.equals(RequestStatus.COMPLETE)) { + + if ( status.equals(RequestStatus.COMPLETE)) { Integer success = pkiReq.getExtDataInInteger(IRequest.RESULT); + if (success.equals(IRequest.RES_SUCCESS)) { // The cert was issued, lets send it back to the router - X509CertImpl[] issuedCertBuf = pkiReq - .getExtDataInCertArray(IRequest.ISSUED_CERTS); + X509CertImpl[] issuedCertBuf = + pkiReq.getExtDataInCertArray(IRequest.ISSUED_CERTS); if (issuedCertBuf == null || issuedCertBuf.length == 0) { - // writeError("Internal Error: Bad operation",httpReq,httpResp); - CMS.debug("CRSEnrollment::makeResponseFromRequest() - " - + "Bad operation"); + // writeError("Internal Error: Bad operation",httpReq,httpResp); + CMS.debug( "CRSEnrollment::makeResponseFromRequest() - " + + "Bad operation" ); return null; } issuedCert = issuedCertBuf[0]; crsResp.setPKIStatus(CRSPKIMessage.mStatus_SUCCESS); - - } else { // status is not 'success' - there must've been a problem - + + } + else { // status is not 'success' - there must've been a problem + crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badAlg); } - } else if (status.equals(RequestStatus.REJECTED_STRING) - || status.equals(RequestStatus.CANCELED_STRING)) { - crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); - crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badRequest); - } else { // not complete + } + else if (status.equals(RequestStatus.REJECTED_STRING) || + status.equals(RequestStatus.CANCELED_STRING)) { + crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE); + crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badRequest); + } + else { // not complete crsResp.setPKIStatus(CRSPKIMessage.mStatus_PENDING); } return issuedCert; } - /** - * This needs to be re-written to log the messages to the system log, since - * there will be no visual webpage feedback for the user. (he's using a - * router) - */ - - private void writeError(String errMsg, HttpServletRequest httpReq, - HttpServletResponse httpResp) throws IOException { - } - - protected String hashPassword(String pwd) { - String salt = "lala123"; - byte[] pwdDigest = mSHADigest.digest((salt + pwd).getBytes()); - String b64E = com.netscape.osutil.OSUtil.BtoA(pwdDigest); - return "{SHA}" + b64E; - } - - /** - * Make the CRSPKIMESSAGE response - */ - - private void processCertRep(CryptoContext cx, X509CertImpl issuedCert, - CRSPKIMessage crsResp, CRSPKIMessage crsReq) - throws CRSFailureException { - byte[] msgdigest = null; - byte[] encryptedDesKey = null; - - try { - if (issuedCert != null) { - - SymmetricKey sk; - SymmetricKey skinternal; - - KeyGenAlgorithm kga = KeyGenAlgorithm.DES; - EncryptionAlgorithm ea = EncryptionAlgorithm.DES_CBC; - if (mEncryptionAlgorithm != null - && mEncryptionAlgorithm.equals("DES3")) { - kga = KeyGenAlgorithm.DES3; - ea = EncryptionAlgorithm.DES3_CBC; - } - - // 1. Make the Degenerated PKCS7 with the recipient's - // certificate in it - - byte toBeEncrypted[] = crsResp.makeSignedRep(1, // version - issuedCert.getEncoded()); - - // 2. Encrypt the above byte array with a new random DES key - - sk = cx.getDESKeyGenerator().generate(); - - skinternal = cx.getInternalToken().getKeyGenerator(kga) - .clone(sk); - - byte[] padded = Cipher.pad(toBeEncrypted, ea.getBlockSize()); - - // This should be changed to generate proper DES IV. - - Cipher cipher = cx.getInternalToken().getCipherContext(ea); - IVParameterSpec desIV = new IVParameterSpec(new byte[] { - (byte) 0xff, (byte) 0x00, (byte) 0xff, (byte) 0x00, - (byte) 0xff, (byte) 0x00, (byte) 0xff, (byte) 0x00 }); - - cipher.initEncrypt(sk, desIV); - byte[] encryptedData = cipher.doFinal(padded); - - crsResp.makeEncryptedContentInfo(desIV.getIV(), encryptedData, - mEncryptionAlgorithm); - - // 3. Extract the recipient's public key - - PublicKey rcpPK = crsReq.getSignerPublicKey(); - - // 4. Encrypt the DES key with the public key - - // we have to move the key onto the interal token. - // skinternal = cx.getInternalKeyStorageToken().cloneKey(sk); - skinternal = cx.getInternalToken().cloneKey(sk); - - KeyWrapper kw = cx.getInternalKeyWrapper(); - kw.initWrap(rcpPK, null); - encryptedDesKey = kw.wrap(skinternal); - crsResp.setRcpIssuerAndSerialNumber(crsReq - .getSgnIssuerAndSerialNumber()); - crsResp.makeRecipientInfo(0, encryptedDesKey); - } - - byte[] ed = crsResp.makeEnvelopedData(0); - - // 7. Make Digest of SignedData Content - MessageDigest md = MessageDigest.getInstance(mHashAlgorithm); - msgdigest = md.digest(ed); - - crsResp.setMsgDigest(msgdigest); - - } - - catch (Exception e) { - throw new CRSFailureException( - "Failed to create inner response to CEP message: " - + e.getMessage()); - } - // 5. Make a RecipientInfo - // The issuer name & serial number here, should be that of - // the EE's self-signed Certificate - // [I can get it from the req blob, but later, I should - // store the recipient's self-signed certificate with the request - // so I can get at it later. I need to do this to support - // 'PENDING'] - try { - - // 8. Make Authenticated Attributes - // we can just pull the transaction ID out of the request. - // Later, we will have to put it out of the Request queue, - // so we can support PENDING - crsResp.setTransactionID(crsReq.getTransactionID()); - // recipientNonce and SenderNonce have already been set - - crsResp.makeAuthenticatedAttributes(); - // crsResp.makeAuthenticatedAttributes_old(); - - // now package up the rest of the SignerInfo - { - byte[] signingcertbytes = cx.getSigningCert().getEncoded(); - - Certificate.Template sgncert_t = new Certificate.Template(); - Certificate sgncert = (Certificate) sgncert_t - .decode(new ByteArrayInputStream(signingcertbytes)); + /** + * This needs to be re-written to log the messages to the system log, since there + * will be no visual webpage feedback for the user. (he's using a router) + */ - IssuerAndSerialNumber sgniasn = new IssuerAndSerialNumber( - sgncert.getInfo().getIssuer(), sgncert.getInfo() - .getSerialNumber()); - - crsResp.setSgnIssuerAndSerialNumber(sgniasn); + private void writeError(String errMsg, HttpServletRequest httpReq, + HttpServletResponse httpResp) + throws IOException + { + } - // 10. Make SignerInfo - crsResp.makeSignerInfo(1, cx.getPrivateKey(), mHashAlgorithm); - // 11. Make SignedData - crsResp.makeSignedData(1, signingcertbytes, mHashAlgorithm); + protected String hashPassword(String pwd) { + String salt = "lala123"; + byte[] pwdDigest = mSHADigest.digest((salt+pwd).getBytes()); + String b64E = com.netscape.osutil.OSUtil.BtoA(pwdDigest); + return "{SHA}"+b64E; + } - crsResp.debug(); - } - } catch (Exception e) { - throw new CRSFailureException( - "Failed to create outer response to CEP request: " - + e.getMessage()); - } - // if debugging, dump out the response into a file - } - class CryptoContext { - private CryptoManager cm; - private CryptoToken internalToken; - private CryptoToken keyStorageToken; - private CryptoToken internalKeyStorageToken; - private KeyGenerator DESkg; - private Enumeration externalTokens = null; - private org.mozilla.jss.crypto.X509Certificate signingCert; - private org.mozilla.jss.crypto.PrivateKey signingCertPrivKey; - private int signingCertKeySize = 0; - - class CryptoContextException extends Exception { - /** + /** + * Make the CRSPKIMESSAGE response + */ + + + private void processCertRep(CryptoContext cx, + X509CertImpl issuedCert, + CRSPKIMessage crsResp, + CRSPKIMessage crsReq) + throws CRSFailureException { + byte[] msgdigest = null; + byte[] encryptedDesKey = null; + + try { + if (issuedCert != null) { + + SymmetricKey sk; + SymmetricKey skinternal; + + KeyGenAlgorithm kga = KeyGenAlgorithm.DES; + EncryptionAlgorithm ea = EncryptionAlgorithm.DES_CBC; + if (mEncryptionAlgorithm != null && mEncryptionAlgorithm.equals("DES3")) { + kga = KeyGenAlgorithm.DES3; + ea = EncryptionAlgorithm.DES3_CBC; + } + + // 1. Make the Degenerated PKCS7 with the recipient's certificate in it + + byte toBeEncrypted[] = + crsResp.makeSignedRep(1, // version + issuedCert.getEncoded() + ); + + // 2. Encrypt the above byte array with a new random DES key + + sk = cx.getDESKeyGenerator().generate(); + + skinternal = cx.getInternalToken().getKeyGenerator(kga).clone(sk); + + byte[] padded = Cipher.pad(toBeEncrypted, ea.getBlockSize()); + + + // This should be changed to generate proper DES IV. + + Cipher cipher = cx.getInternalToken().getCipherContext(ea); + IVParameterSpec desIV = + new IVParameterSpec(new byte[]{ + (byte)0xff, (byte)0x00, + (byte)0xff, (byte)0x00, + (byte)0xff, (byte)0x00, + (byte)0xff, (byte)0x00 } ); + + cipher.initEncrypt(sk,desIV); + byte[] encryptedData = cipher.doFinal(padded); + + crsResp.makeEncryptedContentInfo(desIV.getIV(),encryptedData, mEncryptionAlgorithm); + + // 3. Extract the recipient's public key + + PublicKey rcpPK = crsReq.getSignerPublicKey(); + + + // 4. Encrypt the DES key with the public key + + // we have to move the key onto the interal token. + //skinternal = cx.getInternalKeyStorageToken().cloneKey(sk); + skinternal = cx.getInternalToken().cloneKey(sk); + + KeyWrapper kw = cx.getInternalKeyWrapper(); + kw.initWrap(rcpPK, null); + encryptedDesKey = kw.wrap(skinternal); + + crsResp.setRcpIssuerAndSerialNumber(crsReq.getSgnIssuerAndSerialNumber()); + crsResp.makeRecipientInfo(0, encryptedDesKey ); + + } + + + byte[] ed = crsResp.makeEnvelopedData(0); + + // 7. Make Digest of SignedData Content + MessageDigest md = MessageDigest.getInstance(mHashAlgorithm); + msgdigest = md.digest(ed); + + crsResp.setMsgDigest(msgdigest); + + } + + catch (Exception e) { + throw new CRSFailureException("Failed to create inner response to CEP message: "+e.getMessage()); + } + + + // 5. Make a RecipientInfo + + // The issuer name & serial number here, should be that of + // the EE's self-signed Certificate + // [I can get it from the req blob, but later, I should + // store the recipient's self-signed certificate with the request + // so I can get at it later. I need to do this to support + // 'PENDING'] + + + try { + + // 8. Make Authenticated Attributes + // we can just pull the transaction ID out of the request. + // Later, we will have to put it out of the Request queue, + // so we can support PENDING + crsResp.setTransactionID(crsReq.getTransactionID()); + // recipientNonce and SenderNonce have already been set + + crsResp.makeAuthenticatedAttributes(); + // crsResp.makeAuthenticatedAttributes_old(); + + + + // now package up the rest of the SignerInfo + { + byte[] signingcertbytes = cx.getSigningCert().getEncoded(); + + + Certificate.Template sgncert_t = new Certificate.Template(); + Certificate sgncert = + (Certificate) sgncert_t.decode(new ByteArrayInputStream(signingcertbytes)); + + IssuerAndSerialNumber sgniasn = + new IssuerAndSerialNumber(sgncert.getInfo().getIssuer(), + sgncert.getInfo().getSerialNumber()); + + crsResp.setSgnIssuerAndSerialNumber(sgniasn); + + // 10. Make SignerInfo + crsResp.makeSignerInfo(1, cx.getPrivateKey(), mHashAlgorithm); + + // 11. Make SignedData + crsResp.makeSignedData(1, signingcertbytes, mHashAlgorithm); + + crsResp.debug(); + } + } + catch (Exception e) { + throw new CRSFailureException("Failed to create outer response to CEP request: "+e.getMessage()); + } + + + // if debugging, dump out the response into a file + + } + + + + class CryptoContext { + private CryptoManager cm; + private CryptoToken internalToken; + private CryptoToken keyStorageToken; + private CryptoToken internalKeyStorageToken; + private KeyGenerator DESkg; + private Enumeration externalTokens = null; + private org.mozilla.jss.crypto.X509Certificate signingCert; + private org.mozilla.jss.crypto.PrivateKey signingCertPrivKey; + private int signingCertKeySize = 0; + + + class CryptoContextException extends Exception { + /** * */ - private static final long serialVersionUID = -1124116326126256475L; + private static final long serialVersionUID = -1124116326126256475L; + public CryptoContextException() { super(); } + public CryptoContextException(String s) { super(s); } + } - public CryptoContextException() { - super(); - } + public CryptoContext() + throws CryptoContextException + { + try { + KeyGenAlgorithm kga = KeyGenAlgorithm.DES; + if (mEncryptionAlgorithm != null && mEncryptionAlgorithm.equals("DES3")) { + kga = KeyGenAlgorithm.DES3; + } + cm = CryptoManager.getInstance(); + internalToken = cm.getInternalCryptoToken(); + DESkg = internalToken.getKeyGenerator(kga); + if (mTokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN) || + mTokenName.equalsIgnoreCase("Internal Key Storage Token") || + mTokenName.length() == 0) { + keyStorageToken = cm.getInternalKeyStorageToken(); + internalKeyStorageToken = keyStorageToken; + CMS.debug("CRSEnrollment: CryptoContext: internal token name: '"+mTokenName+"'"); + } else { + keyStorageToken = cm.getTokenByName(mTokenName); + internalKeyStorageToken = null; + } + if (!mUseCA && internalKeyStorageToken == null) { + PasswordCallback cb = CMS.getPasswordCallback(); + keyStorageToken.login(cb); // ONE_TIME by default. + } + signingCert = cm.findCertByNickname(mNickname); + signingCertPrivKey = cm.findPrivKeyByCert(signingCert); + byte[] encPubKeyInfo = signingCert.getPublicKey().getEncoded(); + SEQUENCE.Template outer = SEQUENCE.getTemplate(); + outer.addElement( ANY.getTemplate() ); // algid + outer.addElement( BIT_STRING.getTemplate() ); + SEQUENCE outerSeq = (SEQUENCE) ASN1Util.decode(outer, encPubKeyInfo); + BIT_STRING bs = (BIT_STRING) outerSeq.elementAt(1); + byte[] encPubKey = bs.getBits(); + if( bs.getPadCount() != 0) { + throw new CryptoContextException("Internal error: Invalid Public key. Not an integral number of bytes."); + } + SEQUENCE.Template inner = new SEQUENCE.Template(); + inner.addElement( INTEGER.getTemplate()); + inner.addElement( INTEGER.getTemplate()); + SEQUENCE pubKeySeq = (SEQUENCE) ASN1Util.decode(inner, encPubKey); + INTEGER modulus = (INTEGER) pubKeySeq.elementAt(0); + signingCertKeySize = modulus.bitLength(); + + try { + FileOutputStream fos = new FileOutputStream("pubkey.der"); + fos.write(signingCert.getPublicKey().getEncoded()); + fos.close(); + } catch (Exception e) {} + + } + catch (InvalidBERException e) { + throw new CryptoContextException("Internal Error: Bad internal Certificate Representation. Not a valid RSA-signed certificate"); + } + catch (CryptoManager.NotInitializedException e) { + throw new CryptoContextException("Crypto Manager not initialized"); + } + catch (NoSuchAlgorithmException e) { + throw new CryptoContextException("Cannot create DES key generator"); + } + catch (ObjectNotFoundException e) { + throw new CryptoContextException("Certificate not found: "+ca.getNickname()); + } + catch (TokenException e) { + throw new CryptoContextException("Problem with Crypto Token: "+e.getMessage()); + } + catch (NoSuchTokenException e) { + throw new CryptoContextException("Crypto Token not found: "+e.getMessage()); + } + catch (IncorrectPasswordException e) { + throw new CryptoContextException("Incorrect Password."); + } + } + + + public KeyGenerator getDESKeyGenerator() { + return DESkg; + } - public CryptoContextException(String s) { - super(s); - } - } + public CryptoToken getInternalToken() { + return internalToken; + } - public CryptoContext() throws CryptoContextException { - try { - KeyGenAlgorithm kga = KeyGenAlgorithm.DES; - if (mEncryptionAlgorithm != null - && mEncryptionAlgorithm.equals("DES3")) { - kga = KeyGenAlgorithm.DES3; - } - cm = CryptoManager.getInstance(); - internalToken = cm.getInternalCryptoToken(); - DESkg = internalToken.getKeyGenerator(kga); - if (mTokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN) - || mTokenName - .equalsIgnoreCase("Internal Key Storage Token") - || mTokenName.length() == 0) { - keyStorageToken = cm.getInternalKeyStorageToken(); - internalKeyStorageToken = keyStorageToken; - CMS.debug("CRSEnrollment: CryptoContext: internal token name: '" - + mTokenName + "'"); - } else { - keyStorageToken = cm.getTokenByName(mTokenName); - internalKeyStorageToken = null; - } - if (!mUseCA && internalKeyStorageToken == null) { - PasswordCallback cb = CMS.getPasswordCallback(); - keyStorageToken.login(cb); // ONE_TIME by default. - } - signingCert = cm.findCertByNickname(mNickname); - signingCertPrivKey = cm.findPrivKeyByCert(signingCert); - byte[] encPubKeyInfo = signingCert.getPublicKey().getEncoded(); - SEQUENCE.Template outer = SEQUENCE.getTemplate(); - outer.addElement(ANY.getTemplate()); // algid - outer.addElement(BIT_STRING.getTemplate()); - SEQUENCE outerSeq = (SEQUENCE) ASN1Util.decode(outer, - encPubKeyInfo); - BIT_STRING bs = (BIT_STRING) outerSeq.elementAt(1); - byte[] encPubKey = bs.getBits(); - if (bs.getPadCount() != 0) { - throw new CryptoContextException( - "Internal error: Invalid Public key. Not an integral number of bytes."); - } - SEQUENCE.Template inner = new SEQUENCE.Template(); - inner.addElement(INTEGER.getTemplate()); - inner.addElement(INTEGER.getTemplate()); - SEQUENCE pubKeySeq = (SEQUENCE) ASN1Util.decode(inner, - encPubKey); - INTEGER modulus = (INTEGER) pubKeySeq.elementAt(0); - signingCertKeySize = modulus.bitLength(); + public void setExternalTokens( Enumeration tokens ) { + externalTokens = tokens; + } - try { - FileOutputStream fos = new FileOutputStream("pubkey.der"); - fos.write(signingCert.getPublicKey().getEncoded()); - fos.close(); - } catch (Exception e) { - } + public Enumeration getExternalTokens() { + return externalTokens; + } - } catch (InvalidBERException e) { - throw new CryptoContextException( - "Internal Error: Bad internal Certificate Representation. Not a valid RSA-signed certificate"); - } catch (CryptoManager.NotInitializedException e) { - throw new CryptoContextException( - "Crypto Manager not initialized"); - } catch (NoSuchAlgorithmException e) { - throw new CryptoContextException( - "Cannot create DES key generator"); - } catch (ObjectNotFoundException e) { - throw new CryptoContextException("Certificate not found: " - + ca.getNickname()); - } catch (TokenException e) { - throw new CryptoContextException("Problem with Crypto Token: " - + e.getMessage()); - } catch (NoSuchTokenException e) { - throw new CryptoContextException("Crypto Token not found: " - + e.getMessage()); - } catch (IncorrectPasswordException e) { - throw new CryptoContextException("Incorrect Password."); - } - } + public CryptoToken getInternalKeyStorageToken() { + return internalKeyStorageToken; + } - public KeyGenerator getDESKeyGenerator() { - return DESkg; - } + public CryptoToken getKeyStorageToken() { + return keyStorageToken; + } - public CryptoToken getInternalToken() { - return internalToken; - } + public CryptoManager getCryptoManager() { + return cm; + } - public void setExternalTokens(Enumeration tokens) { - externalTokens = tokens; + public KeyWrapper getKeyWrapper() + throws CryptoContextException { + try { + return signingCertPrivKey.getOwningToken().getKeyWrapper(KeyWrapAlgorithm.RSA); } - - public Enumeration getExternalTokens() { - return externalTokens; + catch (TokenException e) { + throw new CryptoContextException("Problem with Crypto Token: "+e.getMessage()); } - - public CryptoToken getInternalKeyStorageToken() { - return internalKeyStorageToken; + catch (NoSuchAlgorithmException e) { + throw new CryptoContextException(e.getMessage()); } + } - public CryptoToken getKeyStorageToken() { - return keyStorageToken; + public KeyWrapper getInternalKeyWrapper() + throws CryptoContextException { + try { + return getInternalToken().getKeyWrapper(KeyWrapAlgorithm.RSA); } - - public CryptoManager getCryptoManager() { - return cm; + catch (TokenException e) { + throw new CryptoContextException("Problem with Crypto Token: "+e.getMessage()); } - - public KeyWrapper getKeyWrapper() throws CryptoContextException { - try { - return signingCertPrivKey.getOwningToken().getKeyWrapper( - KeyWrapAlgorithm.RSA); - } catch (TokenException e) { - throw new CryptoContextException("Problem with Crypto Token: " - + e.getMessage()); - } catch (NoSuchAlgorithmException e) { - throw new CryptoContextException(e.getMessage()); - } + catch (NoSuchAlgorithmException e) { + throw new CryptoContextException(e.getMessage()); } + } - public KeyWrapper getInternalKeyWrapper() throws CryptoContextException { - try { - return getInternalToken().getKeyWrapper(KeyWrapAlgorithm.RSA); - } catch (TokenException e) { - throw new CryptoContextException("Problem with Crypto Token: " - + e.getMessage()); - } catch (NoSuchAlgorithmException e) { - throw new CryptoContextException(e.getMessage()); - } - } + public org.mozilla.jss.crypto.PrivateKey getPrivateKey() { + return signingCertPrivKey; + } - public org.mozilla.jss.crypto.PrivateKey getPrivateKey() { - return signingCertPrivKey; - } + public org.mozilla.jss.crypto.X509Certificate getSigningCert() { + return signingCert; + } + + } - public org.mozilla.jss.crypto.X509Certificate getSigningCert() { - return signingCert; - } - } + /* General failure. The request/response cannot be processed. */ - /* General failure. The request/response cannot be processed. */ - class CRSFailureException extends Exception { - /** + class CRSFailureException extends Exception { + /** * */ - private static final long serialVersionUID = 1962741611501549051L; + private static final long serialVersionUID = 1962741611501549051L; + public CRSFailureException() { super(); } + public CRSFailureException(String s) { super(s); } + } - public CRSFailureException() { - super(); - } - - public CRSFailureException(String s) { - super(s); - } - } - - class CRSInvalidSignatureException extends Exception { - /** + class CRSInvalidSignatureException extends Exception { + /** * */ - private static final long serialVersionUID = 9096408193567657944L; - - public CRSInvalidSignatureException() { - super(); - } + private static final long serialVersionUID = 9096408193567657944L; + public CRSInvalidSignatureException() { super(); } + public CRSInvalidSignatureException(String s) { super(s); } + } - public CRSInvalidSignatureException(String s) { - super(s); - } - } + - class CRSPolicyException extends Exception { - /** + class CRSPolicyException extends Exception { + /** * */ - private static final long serialVersionUID = 5846593800658787396L; - - public CRSPolicyException() { - super(); - } - - public CRSPolicyException(String s) { - super(s); - } - } + private static final long serialVersionUID = 5846593800658787396L; + public CRSPolicyException() { super(); } + public CRSPolicyException(String s) { super(s); } + } } + diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java index 0456071f..b449a8bd 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java +++ b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java @@ -29,109 +29,115 @@ import netscape.security.util.DerValue; import netscape.security.x509.CertAttrSet; /** - * Class for handling the decoding of a SCEP Challenge Password object. - * Currently this class cannot be used for encoding thus some fo the methods are - * unimplemented + * Class for handling the decoding of a SCEP Challenge Password + * object. Currently this class cannot be used for encoding + * thus some fo the methods are unimplemented */ public class ChallengePassword implements CertAttrSet { - public static final String NAME = "ChallengePassword"; - public static final String PASSWORD = "password"; - - private String cpw; - - /** - * Get the password marshalled in this object - * - * @return the challenge password - */ - public String toString() { - return cpw; - } - - /** - * Create a ChallengePassword object - * - * @param stuff (must be of type byte[]) a DER-encoded by array following - * The ASN.1 template for ChallenegePassword specified in the - * SCEP documentation - * @throws IOException if the DER encoded byt array was malformed, or if it - * did not match the template - */ - - public ChallengePassword(Object stuff) throws IOException { - - ByteArrayInputStream is = new ByteArrayInputStream((byte[]) stuff); - try { - decode(is); - } catch (Exception e) { - throw new IOException(e.getMessage()); - } - - } - - /** - * Currently Unimplemented - */ - public void encode(OutputStream out) throws CertificateException, - IOException { - } - - public void decode(InputStream in) throws CertificateException, IOException { + public static final String NAME = "ChallengePassword"; + public static final String PASSWORD = "password"; + + private String cpw; + + + /** + * Get the password marshalled in this object + * @return the challenge password + */ + public String toString() { + return cpw; + } + + /** + * Create a ChallengePassword object + * @param stuff (must be of type byte[]) a DER-encoded by array following + * The ASN.1 template for ChallenegePassword specified in the SCEP + * documentation + * @throws IOException if the DER encoded byt array was malformed, or if it + * did not match the template + */ + + public ChallengePassword(Object stuff) + throws IOException { + + ByteArrayInputStream is = new ByteArrayInputStream((byte[])stuff); + try { + decode(is); + } catch (Exception e) { + throw new IOException(e.getMessage()); + } + + } + + /** + * Currently Unimplemented + */ + public void encode(OutputStream out) + throws CertificateException, IOException + { } + + public void decode(InputStream in) + throws CertificateException, IOException + { DerValue derVal = new DerValue(in); construct(derVal); - - } - - private void construct(DerValue derVal) throws IOException { - try { - cpw = derVal.getPrintableString(); - } catch (NullPointerException e) { - cpw = ""; - } - } - - /** - * Currently Unimplemented - */ - public void set(String name, Object obj) throws CertificateException, - IOException { + } - /** - * Get an attribute of this object. - * - * @param name the name of the attribute of this object to get. The only - * supported attribute is "password" - */ - public Object get(String name) throws CertificateException, IOException { + private void construct(DerValue derVal) throws IOException { + try { + cpw = derVal.getPrintableString(); + } + catch (NullPointerException e) { + cpw = ""; + } + } + + + /** + * Currently Unimplemented + */ + public void set(String name, Object obj) + throws CertificateException, IOException + { } + + /** + * Get an attribute of this object. + * @param name the name of the attribute of this object to get. The only + * supported attribute is "password" + */ + public Object get(String name) + throws CertificateException, IOException + { if (name.equalsIgnoreCase(PASSWORD)) { return cpw; - } else { - throw new IOException("Attribute name not recognized by " - + "CertAttrSet: ChallengePassword"); + } + else { + throw new IOException("Attribute name not recognized by "+ + "CertAttrSet: ChallengePassword"); } } - - /** - * Currently Unimplemented - */ - public void delete(String name) throws CertificateException, IOException { - } - - /** - * @return an empty set of elements - */ - public Enumeration getElements() { - return (new Hashtable()).elements(); - } - - /** - * @return the String "ChallengePassword" - */ - public String getName() { - return NAME; - } - + + /** + * Currently Unimplemented + */ + public void delete(String name) + throws CertificateException, IOException + { } + + /** + * @return an empty set of elements + */ + public Enumeration getElements() + { return (new Hashtable()).elements();} + + /** + * @return the String "ChallengePassword" + */ + public String getName() + { return NAME;} + + } diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java index e0c0c347..a8757e74 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java +++ b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java @@ -31,44 +31,51 @@ import netscape.security.util.DerValue; import netscape.security.x509.CertAttrSet; import netscape.security.x509.Extension; + public class ExtensionsRequested implements CertAttrSet { - public static final String NAME = "EXTENSIONS_REQUESTED"; + public static final String NAME = "EXTENSIONS_REQUESTED"; + public static final String KUE_DIGITAL_SIGNATURE = "kue_digital_signature"; - public static final String KUE_KEY_ENCIPHERMENT = "kue_key_encipherment"; + public static final String KUE_KEY_ENCIPHERMENT = "kue_key_encipherment"; private String kue_digital_signature = "false"; - private String kue_key_encipherment = "false"; - + private String kue_key_encipherment = "false"; + private Vector exts = new Vector(); public ExtensionsRequested(Object stuff) throws IOException { ByteArrayInputStream is = new ByteArrayInputStream((byte[]) stuff); - + try { decode(is); - } catch (Exception e) { + } + catch (Exception e) { e.printStackTrace(); throw new IOException(e.getMessage()); } } - - public void encode(OutputStream out) throws CertificateException, - IOException { - } - - public void decode(InputStream in) throws CertificateException, IOException { + + public void encode(OutputStream out) + throws CertificateException, IOException + { } + + public void decode(InputStream in) + throws CertificateException, IOException + { DerValue derVal = new DerValue(in); - + construct(derVal); } - - public void set(String name, Object obj) throws CertificateException, - IOException { - } - - public Object get(String name) throws CertificateException, IOException { + + public void set(String name, Object obj) + throws CertificateException, IOException + { } + + public Object get(String name) + throws CertificateException, IOException + { if (name.equalsIgnoreCase(KUE_DIGITAL_SIGNATURE)) { return kue_digital_signature; } @@ -78,82 +85,107 @@ public class ExtensionsRequested implements CertAttrSet { throw new IOException("Unsupported attribute queried"); } - - public void delete(String name) throws CertificateException, IOException { - } - - public Enumeration getElements() { - return (new Hashtable()).elements(); - } - - public String getName() { - return NAME; + + public void delete(String name) + throws CertificateException, IOException + { } - /** - * construct - expects this in the inputstream (from the router): - * - * 211 30 31: SEQUENCE { 213 06 10: OBJECT IDENTIFIER '2 16 840 1 113733 1 9 - * 8' 225 31 17: SET { 227 04 15: OCTET STRING, encapsulates { 229 30 13: - * SEQUENCE { 231 30 11: SEQUENCE { 233 06 3: OBJECT IDENTIFIER keyUsage (2 - * 5 29 15) 238 04 4: OCTET STRING : 03 02 05 A0 : } : } : } - * - * or this (from IRE client): - * - * 262 30 51: SEQUENCE { 264 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 - * 113549 1 9 14) 275 31 38: SET { 277 30 36: SEQUENCE { 279 30 34: SEQUENCE - * { 281 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17) 286 04 27: OCTET - * STRING : 30 19 87 04 D0 0C 3E 6F 81 03 61 61 61 82 0C 61 : 61 61 2E 6D 63 - * 6F 6D 2E 63 6F 6D : } : } : } : } - */ + public Enumeration getElements() + { return (new Hashtable()).elements();} + + public String getName() + { return NAME;} + + + +/** + construct - expects this in the inputstream (from the router): + + 211 30 31: SEQUENCE { + 213 06 10: OBJECT IDENTIFIER '2 16 840 1 113733 1 9 8' + 225 31 17: SET { + 227 04 15: OCTET STRING, encapsulates { + 229 30 13: SEQUENCE { + 231 30 11: SEQUENCE { + 233 06 3: OBJECT IDENTIFIER keyUsage (2 5 29 15) + 238 04 4: OCTET STRING + : 03 02 05 A0 + : } + : } + : } + + or this (from IRE client): + + 262 30 51: SEQUENCE { + 264 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 14) + 275 31 38: SET { + 277 30 36: SEQUENCE { + 279 30 34: SEQUENCE { + 281 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17) + 286 04 27: OCTET STRING + : 30 19 87 04 D0 0C 3E 6F 81 03 61 61 61 82 0C 61 + : 61 61 2E 6D 63 6F 6D 2E 63 6F 6D + : } + : } + : } + : } + + + */ private void construct(DerValue dv) throws IOException { - DerInputStream stream = null; - DerValue[] dvs; + DerInputStream stream = null; + DerValue[] dvs; - try { // try decoding as sequence first + try { // try decoding as sequence first - stream = dv.toDerInputStream(); + stream = dv.toDerInputStream(); - DerValue stream_dv = stream.getDerValue(); - stream.reset(); + DerValue stream_dv = stream.getDerValue(); + stream.reset(); + - dvs = stream.getSequence(2); - } catch (IOException ioe) { - // if it failed, the outer sequence may be - // encapsulated in an octet string, as in the first - // example above + dvs = stream.getSequence(2); + } + catch (IOException ioe) { + // if it failed, the outer sequence may be + // encapsulated in an octet string, as in the first + // example above - byte[] octet_string = dv.getOctetString(); + byte[] octet_string = dv.getOctetString(); - // Make a new input stream from the byte array, - // and re-parse it as a sequence. + // Make a new input stream from the byte array, + // and re-parse it as a sequence. - dv = new DerValue(octet_string); + dv = new DerValue(octet_string); - stream = dv.toDerInputStream(); - dvs = stream.getSequence(2); - } + stream = dv.toDerInputStream(); + dvs = stream.getSequence(2); + } - // now, the stream will be in the correct format - stream.reset(); + // now, the stream will be in the correct format + stream.reset(); - while (true) { - DerValue ext_dv = null; - try { - ext_dv = stream.getDerValue(); - } catch (IOException ex) { - break; - } + while (true) { + DerValue ext_dv=null; + try { + ext_dv = stream.getDerValue(); + } + catch (IOException ex) { + break; + } - Extension ext = new Extension(ext_dv); - exts.addElement(ext); - } + Extension ext = new Extension(ext_dv); + exts.addElement(ext); + } } - public Vector getExtensions() { - return exts; - } + public Vector getExtensions() { + return exts; + } } + + |