Package org.ejbca.ui.web.admin.cainterface

Source Code of org.ejbca.ui.web.admin.cainterface.AdminCertReqServlet

/*************************************************************************
*                                                                       *
*  EJBCA: The OpenSource Certificate Authority                          *
*                                                                       *
*  This software is free software; you can redistribute it and/or       *
*  modify it under the terms of the GNU Lesser General Public           *
*  License as published by the Free Software Foundation; either         *
*  version 2.1 of the License, or any later version.                    *
*                                                                       *
*  See terms of license at gnu.org.                                     *
*                                                                       *
*************************************************************************/

package org.ejbca.ui.web.admin.cainterface;

import java.beans.Beans;
import java.io.IOException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.ejb.EJB;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.ejbca.core.EjbcaException;
import org.ejbca.core.ejb.ca.sign.SignSessionLocal;
import org.ejbca.core.ejb.ra.UserAdminSessionLocal;
import org.ejbca.core.model.SecConst;
import org.ejbca.core.model.log.Admin;
import org.ejbca.core.protocol.IResponseMessage;
import org.ejbca.core.protocol.PKCS10RequestMessage;
import org.ejbca.ui.web.RequestHelper;
import org.ejbca.ui.web.admin.configuration.EjbcaWebBean;
import org.ejbca.ui.web.admin.rainterface.RAInterfaceBean;
import org.ejbca.ui.web.admin.rainterface.UserView;
import org.ejbca.util.Base64;
import org.ejbca.util.CertTools;
import org.ejbca.util.CryptoProviderTools;
import org.ejbca.util.FileTools;
import org.ejbca.util.StringTools;


/**
* This is a servlet that is used for creating a user into EJBCA and retrieving her certificate.
* This servlet requires authentication of the administrator, specifically it requires that the
* client certificate has the privilege "/ra_functionallity/create_end_entity", as defined in the
* admin-GUI.
*
* <p>
* This implementation handles only the POST method.
* </p>
*
* <p>
* The CGI parameters for requests are the following.
* </p>
*
* <dl>
* <dt>
* pkcs10req
* </dt>
* <dd>
* A PKCS#10 request, mandatory.
* </dd>
* <dt>
* username
* </dt>
* <dd>
* The username (for EJBCA use only).  Optional, defaults to the DN in the PKCS#10 request.
* </dd>
* <dt>
* password
* </dt>
* <dd>
* Password for the user (for EJBCA internal use only).  Optional, defaults to an empty string.
* Used for authorization af certificate request.
* </dd>
* <dt>
* entityprofile
* </dt>
* <dd>
* The name of the EJBCA end entity profile for the user.  Optional, defaults to the built-in EMPTY
* end entity profile.
* </dd>
* <dt>
* certificateprofile
* </dt>
* <dd>
* The name of the EJBCA certificate profile to use.  Optional, defaults to the built-in ENDUSER
* certificate profile.
* </dd>
* <dt>ca</dt>
* <dd>
*   The name of the ca to use.  Required,
* </dd>
* </dl>
*
*
* @author Ville Skytt�
* @version $Id: AdminCertReqServlet.java 10500 2010-11-15 17:48:24Z jeklund $
*/
public class AdminCertReqServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;
  private final static Logger log = Logger.getLogger(AdminCertReqServlet.class);
   
    private final static byte[] BEGIN_CERT =
        "-----BEGIN CERTIFICATE-----".getBytes();
    private final static int BEGIN_CERT_LENGTH = BEGIN_CERT.length;
   
    private final static byte[] END_CERT =
        "-----END CERTIFICATE-----".getBytes();
    private final static int END_CERT_LENGTH = END_CERT.length;
   
    private final static byte[] NL = "\n".getBytes();
    private final static int NL_LENGTH = NL.length;
   
    @EJB
    private SignSessionLocal signSession;
    @EJB
    private UserAdminSessionLocal userAdminSession;

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        try {
          CryptoProviderTools.installBCProvider()// Install BouncyCastle provider
        } catch (Exception e) {
            throw new ServletException(e);
        }
      if (signSession==null || userAdminSession==null) {
        log.error("Local EJB injection failed.");
      }
    }

    /**
     * Handles PKCS10 certificate request, these are constructed as:
     * <pre><code>
     * CertificationRequest ::= SEQUENCE {
     * certificationRequestInfo  CertificationRequestInfo,
     * signatureAlgorithm          AlgorithmIdentifier{{ SignatureAlgorithms }},
     * signature                       BIT STRING
     * }
     * CertificationRequestInfo ::= SEQUENCE {
     * version             INTEGER { v1(0) } (v1,...),
     * subject             Name,
     * subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
     * attributes          [0] Attributes{{ CRIAttributes }}
     * }
     * SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE {
     * algorithm           AlgorithmIdentifier {{IOSet}},
     * subjectPublicKey    BIT STRING
     * }
     * </pre>
     *
     * PublicKey's encoded-format has to be RSA X.509.
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {       
        // Check if authorized
        EjbcaWebBean ejbcawebbean= getEjbcaWebBean(request);
        try{
            ejbcawebbean.initialize(request, "/ra_functionallity/create_end_entity");
        } catch(Exception e){
            throw new java.io.IOException("Authorization Denied");
        }
       
        X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
        if (certs == null) {
            throw new ServletException("This servlet requires certificate authentication!");
        }
       
        Admin admin = userAdminSession.getAdmin(certs[0]);
       
        RequestHelper.setDefaultCharacterEncoding(request);

        byte[] buffer = pkcs10Bytes(request.getParameter("pkcs10req"));
        if (buffer == null) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid request, missing 'pkcs10req'!");
            return;
        }
       
        RAInterfaceBean rabean = getRaBean(request);
       
        // Decompose the PKCS#10 request, and create the user.
        PKCS10RequestMessage p10 = new PKCS10RequestMessage(buffer);
        String dn = p10.getCertificationRequest().getCertificationRequestInfo().getSubject().toString();
       
        String username = request.getParameter("username");
        if (username == null || username.trim().length() == 0) {
            username = dn;
        }
        // Strip dangerous chars
        username = StringTools.strip(username);
        // need null check here?
        // Before doing anything else, check if the user name is unique and ok.
        username = checkUsername(rabean, username);
       
        UserView newuser = new UserView();
        newuser.setUsername(username);
       
        newuser.setSubjectDN(dn);
        newuser.setTokenType(SecConst.TOKEN_SOFT_BROWSERGEN);
        newuser.setKeyRecoverable(false);
       
        String email = CertTools.getPartFromDN(dn, "E"); // BC says VeriSign
        if (email == null) {
          email = CertTools.getPartFromDN(dn, "EMAILADDRESS");
        } else {
            newuser.setEmail(email);
        }
       
        String tmp = null;
        int eProfileId = SecConst.EMPTY_ENDENTITYPROFILE;
        if ((tmp = request.getParameter("entityprofile")) != null) {
            int reqId = rabean.getEndEntityProfileId(tmp);
            if (reqId == 0) {
                throw new ServletException("No such end entity profile: " + tmp);
            }
            eProfileId = reqId;
        }
        newuser.setEndEntityProfileId(eProfileId);
       
        int cProfileId = SecConst.CERTPROFILE_FIXED_ENDUSER;
        if ((tmp = request.getParameter("certificateprofile")) != null) {
            CAInterfaceBean cabean = getCaBean(request);
            int reqId = cabean.getCertificateProfileId(tmp);
            if (reqId == 0) {
                throw new ServletException("No such certificate profile: " + tmp);
            }
            cProfileId = reqId;
        }
        newuser.setCertificateProfileId(cProfileId);
       
        int caid = 0;
        if ((tmp = request.getParameter("ca")) != null) {
            // TODO: get requested CA to sign with
        }
        newuser.setCAId(caid);
       
       
        String password = request.getParameter("password");
        if (password == null) {
          password = "";
        }
        newuser.setPassword(password);
        newuser.setClearTextPassword(false);
       
        try {
            rabean.addUser(newuser);
        } catch (Exception e) {
            throw new ServletException("Error adding user: " + e.toString(), e);
        }
       
        byte[] pkcs7;
        try {
            p10.setUsername(username);
            p10.setPassword(password);
            IResponseMessage resp = signSession.createCertificate(admin, p10, org.ejbca.core.protocol.X509ResponseMessage.class, null);
            Certificate cert = CertTools.getCertfromByteArray(resp.getResponseMessage());
            pkcs7 = signSession.createPKCS7(admin, cert, true);
        } catch (EjbcaException e) {
            // EJBCA did not accept any of all parameters in the request.
            throw new ServletException(e);
        } catch (CertificateEncodingException e) {
            // Error in cert
            throw new ServletException(e);
        } catch (CertificateException e) {
            // Error in cert
            throw new ServletException(e);
        }
       
        log.debug("Created certificate (PKCS7) for " + username);
       
        sendNewB64Cert(Base64.encode(pkcs7), response);
       
    }
   
   
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
        log.trace(">doGet()");
        response.setHeader("Allow", "POST");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "The certificate request servlet only handles the POST method.");
        log.trace("<doGet()");
    } // doGet
   
   
    private void sendNewB64Cert(byte[] b64cert, HttpServletResponse out)
    throws IOException
    {
        out.setContentType("application/octet-stream");
        out.setHeader("Content-Disposition", "filename=cert.pem");
        out.setContentLength(b64cert.length +
                BEGIN_CERT_LENGTH + END_CERT_LENGTH + (3 *NL_LENGTH));
       
        ServletOutputStream os = out.getOutputStream();
        os.write(BEGIN_CERT);
        os.write(NL);
        os.write(b64cert);
        os.write(NL);
        os.write(END_CERT);
        os.write(NL);
        out.flushBuffer();
    }
   
   
    /**
     *
     */
    private final static byte[] pkcs10Bytes(String pkcs10)
    {
      byte[] bytes = null;
        if (pkcs10 != null) {
            byte[] reqBytes = pkcs10.getBytes();
            try {
                // A real PKCS10 PEM request
                String beginKey = "-----BEGIN CERTIFICATE REQUEST-----";
                String endKey   = "-----END CERTIFICATE REQUEST-----";
                bytes = FileTools.getBytesFromPEM(reqBytes, beginKey, endKey);
            } catch (IOException e) {
                try {
                    // Keytool PKCS10 PEM request
                    String beginKey = "-----BEGIN NEW CERTIFICATE REQUEST-----";
                    String endKey   = "-----END NEW CERTIFICATE REQUEST-----";
                    bytes = FileTools.getBytesFromPEM(reqBytes, beginKey, endKey);
                } catch (IOException e2) {
                    // IE PKCS10 Base64 coded request
                    bytes = Base64.decode(reqBytes);
                }
            }
        }
        return bytes;
    }
   
   
    /**
     *
     */
    private final RAInterfaceBean getRaBean(HttpServletRequest req)
    throws ServletException
    {
        HttpSession session = req.getSession();
        RAInterfaceBean rabean = (RAInterfaceBean) session.getAttribute("rabean");
        if (rabean == null) {
            try {
                rabean = (RAInterfaceBean) Beans.instantiate(Thread.currentThread().getContextClassLoader(), org.ejbca.ui.web.admin.rainterface.RAInterfaceBean.class.getName());
            } catch (ClassNotFoundException e) {
                throw new ServletException(e);
            } catch (Exception e) {
                throw new ServletException("Unable to instantiate RAInterfaceBean", e);
            }
            try {
                rabean.initialize(req, getEjbcaWebBean(req));
            } catch (Exception e) {
                throw new ServletException("Cannot initialize RAInterfaceBean", e);
            }
            session.setAttribute("rabean", rabean);
        }
        return rabean;
    }
   
   
    /**
     *
     */
    private final EjbcaWebBean getEjbcaWebBean(HttpServletRequest req)
    throws ServletException
    {
        HttpSession session = req.getSession();
        EjbcaWebBean ejbcawebbean= (EjbcaWebBean)session.getAttribute("ejbcawebbean");
        if ( ejbcawebbean == null ){
            try {
                ejbcawebbean = (EjbcaWebBean) java.beans.Beans.instantiate(Thread.currentThread().getContextClassLoader(), org.ejbca.ui.web.admin.configuration.EjbcaWebBean.class.getName());
            } catch (ClassNotFoundException exc) {
                throw new ServletException(exc.getMessage());
            }catch (Exception exc) {
                throw new ServletException (" Cannot create bean of class "+org.ejbca.ui.web.admin.configuration.EjbcaWebBean.class.getName(), exc);
            }
            session.setAttribute("ejbcawebbean", ejbcawebbean);
        }
        return ejbcawebbean;
    }
    /**
     *
     */
    private final CAInterfaceBean getCaBean(HttpServletRequest req)
    throws ServletException
    {
        HttpSession session = req.getSession();
        CAInterfaceBean cabean = (CAInterfaceBean) session.getAttribute("cabean");
        if (cabean == null) {
            try {
                cabean = (CAInterfaceBean) Beans.instantiate(Thread.currentThread().getContextClassLoader(), org.ejbca.ui.web.admin.cainterface.CAInterfaceBean.class.getName());
            } catch (ClassNotFoundException e) {
                throw new ServletException(e);
            } catch (Exception e) {
                throw new ServletException("Unable to instantiate CAInterfaceBean", e);
            }
            try {
                cabean.initialize(req, getEjbcaWebBean(req));
            } catch (Exception e) {
                throw new ServletException("Cannot initialize CAInterfaceBean", e);
            }
            session.setAttribute("cabean", cabean);
        }
        return cabean;
    }
   
   
    /**
     *
     */
    private final String checkUsername(RAInterfaceBean rabean, String username)
    throws ServletException
    {
        if (username != null) {
          username = username.trim();
        }
        if (username == null || username.length() == 0) {
            throw new ServletException("Username must not be empty.");
        }
       
        String msg = null;
        try {
            if (rabean.userExist(username)) {
                msg = "User '" + username + "' already exists.";
            }
        } catch (Exception e) {
            throw new ServletException("Error checking username '" + username +
                    ": " + e.toString(), e);
        }
        if (msg != null) {
            throw new ServletException(msg);
        }
       
        return username;
    }
   
}
TOP

Related Classes of org.ejbca.ui.web.admin.cainterface.AdminCertReqServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.