1 13 14 package org.ejbca.core.protocol.ocsp; 15 16 import java.io.File ; 17 import java.io.IOException ; 18 import java.security.cert.CertificateException ; 19 import java.security.cert.X509Certificate ; 20 import java.sql.Connection ; 21 import java.sql.PreparedStatement ; 22 import java.sql.ResultSet ; 23 import java.sql.SQLException ; 24 import java.util.Hashtable ; 25 26 import javax.ejb.EJBException ; 27 import javax.servlet.ServletConfig ; 28 import javax.servlet.http.HttpServletRequest ; 29 30 import org.apache.commons.lang.StringUtils; 31 import org.apache.log4j.Logger; 32 import org.bouncycastle.asn1.DEROctetString; 33 import org.bouncycastle.asn1.x509.X509Extension; 34 import org.bouncycastle.ocsp.CertificateStatus; 35 import org.ejbca.core.ejb.ServiceLocator; 36 import org.ejbca.core.model.InternalResources; 37 import org.ejbca.util.CertTools; 38 import org.ejbca.util.FileTools; 39 import org.ejbca.util.JDBCUtil; 40 41 47 public class OCSPUnidExtension implements IOCSPExtension { 48 49 private static final Logger m_log = Logger.getLogger(OCSPUnidExtension.class); 50 51 private static final InternalResources intres = InternalResources.getInstance(); 52 53 56 public static final int ERROR_NO_ERROR = 0; 57 public static final int ERROR_UNKNOWN = 1; 58 public static final int ERROR_UNAUTHORIZED = 2; 59 public static final int ERROR_NO_FNR_MAPPING = 3; 60 public static final int ERROR_NO_SERIAL_IN_DN = 4; 61 public static final int ERROR_SERVICE_UNAVAILABLE = 5; 62 public static final int ERROR_CERT_REVOKED = 6; 63 64 private String dataSourceJndi; 65 private Hashtable trustedCerts = new Hashtable (); 66 private X509Certificate cacert = null; 67 private int errCode = OCSPUnidExtension.ERROR_NO_ERROR; 68 69 73 public void init(ServletConfig config) { 74 dataSourceJndi = config.getInitParameter("unidDataSource"); 76 if (StringUtils.isEmpty(dataSourceJndi)) { 77 String errMsg = intres.getLocalizedMessage("ocsp.errornoinitparam", "unidDataSource"); 78 m_log.error(errMsg); 79 throw new IllegalArgumentException (errMsg); 80 } 81 String trustDir = config.getInitParameter("unidTrustDir"); 82 if (StringUtils.isEmpty(trustDir)) { 83 String errMsg = intres.getLocalizedMessage("ocsp.errornoinitparam", "unidTrustDir"); 84 m_log.error(errMsg); 85 throw new IllegalArgumentException (errMsg); 86 } 87 CertTools.installBCProvider(); 89 File dir = new File (trustDir); 90 try { 91 if (dir == null || dir.isDirectory() == false) { 92 m_log.error(dir.getCanonicalPath()+ " is not a directory."); 93 throw new IllegalArgumentException (dir.getCanonicalPath()+ " is not a directory."); 94 } 95 File files[] = dir.listFiles(); 96 if (files == null || files.length == 0) { 97 String errMsg = intres.getLocalizedMessage("ocsp.errornotrustfiles", dir.getCanonicalPath()); 98 m_log.error(errMsg); 99 } 100 for ( int i=0; i<files.length; i++ ) { 101 final String fileName = files[i].getCanonicalPath(); 102 try { 104 byte[] bytes = FileTools.getBytesFromPEM(FileTools.readFiletoBuffer(fileName), 105 "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----"); 106 X509Certificate cert = CertTools.getCertfromByteArray(bytes); 107 String key = CertTools.getIssuerDN(cert)+";"+cert.getSerialNumber().toString(16); 108 trustedCerts.put(key,cert); 109 } catch (CertificateException e) { 110 String errMsg = intres.getLocalizedMessage("ocsp.errorreadingfile", fileName, "trustDir", e.getMessage()); 111 m_log.error(errMsg, e); 112 } catch (IOException e) { 113 String errMsg = intres.getLocalizedMessage("ocsp.errorreadingfile", fileName, "trustDir", e.getMessage()); 114 m_log.error(errMsg, e); 115 } 116 } 117 } catch (IOException e) { 118 String errMsg = intres.getLocalizedMessage("ocsp.errorreadingtrustfiles", e.getMessage()); 119 m_log.error(errMsg, e); 120 throw new IllegalArgumentException (errMsg); 121 } 122 String cacertfile = config.getInitParameter("unidCACert"); 123 if (StringUtils.isEmpty(cacertfile)) { 124 String errMsg = intres.getLocalizedMessage("ocsp.errornoinitparam", "unidCACert"); 125 m_log.error(errMsg); 126 throw new IllegalArgumentException (errMsg); 127 } 128 try { 129 byte[] bytes = FileTools.getBytesFromPEM(FileTools 130 .readFiletoBuffer(cacertfile), 131 "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----"); 132 cacert = CertTools.getCertfromByteArray(bytes); 133 } catch (Exception e) { 134 String errMsg = intres.getLocalizedMessage("ocsp.errorreadingfile", "file", "cacertfile", e.getMessage()); 135 m_log.error(errMsg, e); 136 throw new IllegalArgumentException (errMsg); 137 } 138 139 } 140 141 148 public Hashtable process(HttpServletRequest request, X509Certificate cert, CertificateStatus status) { 149 if (m_log.isDebugEnabled()) { 150 m_log.debug(">process()"); 151 } 152 if (!checkAuthorization(request)) { 154 errCode = OCSPUnidExtension.ERROR_UNAUTHORIZED; 155 return null; 156 } 157 if (status != null) { 159 errCode = OCSPUnidExtension.ERROR_CERT_REVOKED; 160 return null; 161 } 162 Connection con = null; 163 PreparedStatement ps = null; 164 ResultSet result = null; 165 String fnr = null; 166 String sn = null; 167 try { 168 sn = CertTools.getPartFromDN(cert.getSubjectDN().getName(), "SN"); 170 if (sn != null) { 171 if (m_log.isDebugEnabled()) { 172 m_log.debug("Found serialNumber: "+sn); 173 } 174 String iMsg = intres.getLocalizedMessage("ocsp.receivedunidreq", request.getRemoteAddr(), request.getRemoteHost(), sn); 175 m_log.info(iMsg); 176 try { 177 con = ServiceLocator.getInstance().getDataSource(dataSourceJndi).getConnection(); 178 } catch (SQLException e) { 179 String errMsg = intres.getLocalizedMessage("ocsp.errordatabaseunid"); 180 m_log.error(errMsg, e); 181 errCode = OCSPUnidExtension.ERROR_SERVICE_UNAVAILABLE; 182 return null; 183 } 184 ps = con.prepareStatement("select fnr from UnidFnrMapping where unid=?"); 185 ps.setString(1, sn); 186 result = ps.executeQuery(); 187 if (result.next()) { 188 fnr = result.getString(1); 189 } 190 } else { 191 String errMsg = intres.getLocalizedMessage("ocsp.errorunidnosnindn", cert.getSubjectDN().getName()); 192 m_log.error(errMsg); 193 errCode = OCSPUnidExtension.ERROR_NO_SERIAL_IN_DN; 194 return null; 195 } 196 if (m_log.isDebugEnabled()) { 197 m_log.debug("<process()"); 198 } 199 } catch (Exception e) { 200 throw new EJBException (e); 201 } finally { 202 JDBCUtil.close(con, ps, result); 203 } 204 205 if (fnr == null) { 207 String errMsg = intres.getLocalizedMessage("ocsp.errorunidnosnmapping", sn); 208 m_log.error(errMsg); 209 errCode = OCSPUnidExtension.ERROR_NO_FNR_MAPPING; 210 return null; 211 212 } 213 String errMsg = intres.getLocalizedMessage("ocsp.returnedunidresponse", request.getRemoteAddr(), request.getRemoteHost(), fnr, sn); 214 m_log.info(errMsg); 215 FnrFromUnidExtension ext = new FnrFromUnidExtension(fnr); 216 Hashtable ret = new Hashtable (); 217 ret.put(FnrFromUnidExtension.FnrFromUnidOid, new X509Extension(false, new DEROctetString(ext))); 218 return ret; 219 } 220 221 225 public int getLastErrorCode() { 226 return errCode; 227 } 228 229 boolean checkAuthorization(HttpServletRequest request) { 233 X509Certificate [] certs = (X509Certificate []) request.getAttribute("javax.servlet.request.X509Certificate"); 234 if (certs == null) { 235 String errMsg = intres.getLocalizedMessage("ocsp.errornoclientauth", request.getRemoteAddr(), request.getRemoteHost()); 236 m_log.error(errMsg); 237 return false; 238 } 239 X509Certificate cert = certs[0]; 241 if (cert == null) { 242 String errMsg = intres.getLocalizedMessage("ocsp.errornoclientauth", request.getRemoteAddr(), request.getRemoteHost()); 243 m_log.error(errMsg); 244 return false; 245 } 246 String key = CertTools.getIssuerDN(cert)+";"+cert.getSerialNumber().toString(16); 248 Object found = trustedCerts.get(key); 249 if (found != null) { 250 try { 253 cert.verify(cacert.getPublicKey()); 254 } catch (Exception e) { 255 String errMsg = intres.getLocalizedMessage("ocsp.errorverifycert"); 256 m_log.error(errMsg, e); 257 return false; 258 } 259 return true; 261 } 262 String errMsg = intres.getLocalizedMessage("ocsp.erroruntrustedclientauth", request.getRemoteAddr(), request.getRemoteHost()); 263 m_log.error(errMsg); 264 return false; 265 } 266 } 267 | Popular Tags |