diff options
Diffstat (limited to 'pdf-as-web/src')
7 files changed, 521 insertions, 113 deletions
| diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java index 299c166f..288b62c4 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java @@ -35,58 +35,61 @@ import org.slf4j.LoggerFactory;  public class WebConfiguration { -	  	public static final String PUBLIC_URL = "public.url";  	public static final String LOCAL_BKU_URL = "bku.local.url";  	public static final String ONLINE_BKU_URL = "bku.online.url";  	public static final String MOBILE_BKU_URL = "bku.mobile.url";  	public static final String ERROR_DETAILS = "error.showdetails";  	public static final String PDF_AS_WORK_DIR = "pdfas.dir"; -	 +  	public static final String MOA_SS_ENABLED = "moa.enabled";  	public static final String SOAP_SIGN_ENABLED = "soap.sign.enabled"; -	 +  	public static final String KEYSTORE_ENABLED = "ks.enabled";  	public static final String KEYSTORE_FILE = "ks.file";  	public static final String KEYSTORE_TYPE = "ks.type";  	public static final String KEYSTORE_PASS = "ks.pass";  	public static final String KEYSTORE_ALIAS = "ks.key.alias";  	public static final String KEYSTORE_KEY_PASS = "ks.key.pass"; -	 +  	public static final String WHITELIST_ENABLED = "whitelist.enabled";  	public static final String WHITELIST_VALUE_PRE = "whitelist.url."; -	 +  	public static final String REQUEST_STORE = "request.store";  	public static final String REQUEST_STORE_INMEM = "at.gv.egiz.pdfas.web.store.InMemoryRequestStore"; -	 +	public static final String REQUEST_STORE_DB = "at.gv.egiz.pdfas.web.store.DBRequestStore"; +	public static final String DB_REQUEST_TIMEOUT = "request.db.timeout"; +	public static final String HIBERNATE_PREFIX = "hibernate.props."; +  	private static Properties properties = new Properties(); -	 +	private static Properties hibernateProps = new Properties(); +  	private static final Logger logger = LoggerFactory  			.getLogger(WebConfiguration.class); -	 +  	private static List<String> whiteListregEx = new ArrayList<String>();  	public static void configure(String config) { -		 +  		properties.clear();  		whiteListregEx.clear(); -		 +  		try {  			properties.load(new FileInputStream(config)); -		} catch(Exception e) { +		} catch (Exception e) {  			logger.error("Failed to load configuration: " + e.getMessage());  			throw new RuntimeException(e);  		} -		 -		if(isWhiteListEnabled()) { + +		if (isWhiteListEnabled()) {  			Iterator<Object> keyIt = properties.keySet().iterator(); -			while(keyIt.hasNext()) { +			while (keyIt.hasNext()) {  				Object keyObj = keyIt.next(); -				if(keyObj != null) { +				if (keyObj != null) {  					String key = keyObj.toString(); -					if(key.startsWith(WHITELIST_VALUE_PRE)) { +					if (key.startsWith(WHITELIST_VALUE_PRE)) {  						String whitelist_expr = properties.getProperty(key); -						if(whitelist_expr != null) { +						if (whitelist_expr != null) {  							whiteListregEx.add(whitelist_expr);  							logger.debug("URL Whitelist: " + whitelist_expr);  						} @@ -94,21 +97,52 @@ public class WebConfiguration {  				}  			}  		} -		 + +		Iterator<Object> keyIt = properties.keySet().iterator(); +		while (keyIt.hasNext()) { +			Object keyObj = keyIt.next(); +			if (keyObj != null) { +				String key = keyObj.toString(); +				if (key.startsWith(HIBERNATE_PREFIX)) { +					String value = properties.getProperty(key); +					if (value != null) { +						String hibKey = key.replace(HIBERNATE_PREFIX, ""); +						hibernateProps.put(hibKey, value); +					} +				} +			} +		} + +		if (hibernateProps.size() != 0) { +			logger.debug("DB Properties: "); +			Iterator<Object> hibkeyIt = hibernateProps.keySet().iterator(); +			while (hibkeyIt.hasNext()) { +				Object keyObj = hibkeyIt.next(); +				if (keyObj != null) { +					String key = keyObj.toString(); +					String value = hibernateProps.getProperty(key); +					logger.debug("  {}: {}", key, value); +				} +			} +		} +  		String pdfASDir = getPdfASDir(); -		if(pdfASDir == null) { +		if (pdfASDir == null) {  			logger.error("Please configure pdf as working directory in the web configuration"); -			throw new RuntimeException("Please configure pdf as working directory in the web configuration"); +			throw new RuntimeException( +					"Please configure pdf as working directory in the web configuration");  		} -		 +  		File f = new File(pdfASDir); -		 -		if(!f.exists() || !f.isDirectory()) { -			logger.error("Pdf As working directory does not exists or is not a directory!: " + pdfASDir); -			throw new RuntimeException("Pdf As working directory does not exists or is not a directory!"); + +		if (!f.exists() || !f.isDirectory()) { +			logger.error("Pdf As working directory does not exists or is not a directory!: " +					+ pdfASDir); +			throw new RuntimeException( +					"Pdf As working directory does not exists or is not a directory!");  		}  	} -	 +  	public static String getPublicURL() {  		return properties.getProperty(PUBLIC_URL);  	} @@ -124,71 +158,75 @@ public class WebConfiguration {  	public static String getHandyBKUURL() {  		return properties.getProperty(MOBILE_BKU_URL);  	} -	 +  	public static String getPdfASDir() {  		return properties.getProperty(PDF_AS_WORK_DIR);  	} -	 +  	public static String getKeystoreFile() {  		return properties.getProperty(KEYSTORE_FILE);  	} +  	public static String getKeystoreType() {  		return properties.getProperty(KEYSTORE_TYPE);  	} +  	public static String getKeystorePass() {  		return properties.getProperty(KEYSTORE_PASS);  	} +  	public static String getKeystoreAlias() {  		return properties.getProperty(KEYSTORE_ALIAS);  	} +  	public static String getKeystoreKeyPass() {  		return properties.getProperty(KEYSTORE_KEY_PASS);  	} -	 +  	public static boolean getMOASSEnabled() {  		String value = properties.getProperty(MOA_SS_ENABLED); -		if(value != null) { -			if(value.equals("true")) { +		if (value != null) { +			if (value.equals("true")) {  				return true;  			}  		}  		return false;  	} -	 +  	public static boolean getKeystoreEnabled() {  		String value = properties.getProperty(KEYSTORE_ENABLED); -		if(value != null) { -			if(value.equals("true")) { +		if (value != null) { +			if (value.equals("true")) {  				return true;  			}  		}  		return false;  	} -	 +  	public static boolean getSoapSignEnabled() {  		String value = properties.getProperty(SOAP_SIGN_ENABLED); -		if(value != null) { -			if(value.equals("true")) { +		if (value != null) { +			if (value.equals("true")) {  				return true;  			}  		}  		return false;  	} -	 +  	public static boolean isShowErrorDetails() {  		String value = properties.getProperty(ERROR_DETAILS); -		if(value != null) { -			if(value.equals("true")) { +		if (value != null) { +			if (value.equals("true")) {  				return true;  			}  		}  		return false;  	} -	 +  	public static boolean isWhiteListEnabled() {  		String value = properties.getProperty(WHITELIST_ENABLED); -		if(value != null) { -			if(value.equals("true")) { +		if (value != null) { +			if (value.equals("true")) {  				return true;  			}  		} @@ -196,32 +234,49 @@ public class WebConfiguration {  	}  	public static synchronized boolean isProvidePdfURLinWhitelist(String url) { -		if(isWhiteListEnabled()) { -			 +		if (isWhiteListEnabled()) { +  			Iterator<String> patterns = whiteListregEx.iterator(); -			while(patterns.hasNext()) { +			while (patterns.hasNext()) {  				String pattern = patterns.next();  				try { -					if(url.matches(pattern)) { +					if (url.matches(pattern)) {  						return true;  					} -				} catch(Throwable e) { +				} catch (Throwable e) {  					logger.error("Error in matching regex: " + pattern, e);  				}  			} -			 +  			return false;  		}  		return true;  	} + +	public static Properties getHibernateProps() { +		return (Properties) hibernateProps.clone(); +	} + +	public static int getDBTimeout() { +		String value = properties.getProperty(DB_REQUEST_TIMEOUT); +		int ivalue = 600; +		if (value != null) { +			try { +				ivalue = Integer.parseInt(value); +			} catch(NumberFormatException e) { +				logger.error("DB request Timeout not a number", e); +			} +		} +		return ivalue; +	}  	public static String getStoreClass() {  		String cls = properties.getProperty(REQUEST_STORE); -		 -		if(cls != null) { + +		if (cls != null) {  			return cls;  		} -		 +  		return REQUEST_STORE_INMEM;  	}  } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java index 041c7df3..b79075a1 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java @@ -45,14 +45,19 @@ import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;  import javax.servlet.http.HttpSession;  import javax.xml.bind.JAXBElement; +import javax.xml.ws.WebServiceException; +import org.apache.commons.codec.binary.Base64;  import org.apache.commons.io.FileUtils;  import org.apache.commons.lang3.StringEscapeUtils;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import at.gv.egiz.pdfas.api.ws.PDFASSignParameters; +import at.gv.egiz.pdfas.api.ws.PDFASVerificationResponse; +import at.gv.egiz.pdfas.api.ws.VerificationLevel;  import at.gv.egiz.pdfas.api.ws.PDFASSignParameters.Connector; +import at.gv.egiz.pdfas.api.ws.PDFASSignResponse;  import at.gv.egiz.pdfas.common.exceptions.PdfAsException;  import at.gv.egiz.pdfas.lib.api.ByteArrayDataSink;  import at.gv.egiz.pdfas.lib.api.ByteArrayDataSource; @@ -65,6 +70,7 @@ import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;  import at.gv.egiz.pdfas.lib.api.sign.SignParameter;  import at.gv.egiz.pdfas.lib.api.sign.SignResult;  import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; +import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;  import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;  import at.gv.egiz.pdfas.sigs.pades.PAdESSigner;  import at.gv.egiz.pdfas.sigs.pades.PAdESSignerKeystore; @@ -99,6 +105,9 @@ public class PdfAsHelper {  	private static final String PDF_USERENTRY_PAGE = "/userentry";  	private static final String PDF_ERR_URL = "PDF_ERR_URL";  	private static final String PDF_FILE_NAME = "PDF_FILE_NAME"; +	private static final String PDF_SIGNER_CERT = "PDF_SIGNER_CERT"; +	private static final String PDF_VER_LEVEL = "PDF_VER_LEVEL"; +	private static final String PDF_VER_RESP = "PDF_VER_RESP";  	private static final String PDF_INVOKE_URL = "PDF_INVOKE_URL";  	private static final String REQUEST_FROM_DU = "REQ_DATA_URL";  	private static final String SIGNATURE_DATA_HASH = "SIGNATURE_DATA_HASH"; @@ -158,7 +167,8 @@ public class PdfAsHelper {  		String posR = PdfAsParameterExtractor.getSigPosR(request);  		String posF = PdfAsParameterExtractor.getSigPosF(request); -		if (posP == null && posW == null && posX == null && posY == null && posR == null && posF == null) { +		if (posP == null && posW == null && posX == null && posY == null +				&& posR == null && posF == null) {  			return null;  		} @@ -217,7 +227,7 @@ public class PdfAsHelper {  		} else {  			sb.append("p:auto;");  		} -		 +  		if (posR != null) {  			try {  				Float.parseFloat(posR); @@ -230,7 +240,7 @@ public class PdfAsHelper {  		} else {  			sb.append("r:0;");  		} -		 +  		if (posF != null) {  			try {  				Float.parseFloat(posF); @@ -279,6 +289,27 @@ public class PdfAsHelper {  		return results;  	} +	public static List<VerifyResult> synchornousVerify(byte[] pdfData, +			int signIdx, SignatureVerificationLevel lvl) throws Exception { +		logger.debug("Verifing Signature index: " + signIdx); + +		Configuration config = pdfAs.getConfiguration(); + +		ByteArrayDataSource dataSource = new ByteArrayDataSource(pdfData); + +		VerifyParameter verifyParameter = PdfAsFactory.createVerifyParameter( +				config, dataSource); + +		verifyParameter.setSignatureVerificationLevel(lvl); +		verifyParameter.setDataSource(dataSource); +		verifyParameter.setConfiguration(config); +		verifyParameter.setWhichSignature(signIdx); + +		List<VerifyResult> results = pdfAs.verify(verifyParameter); + +		return results; +	} +  	/**  	 * Create synchronous PDF Signature  	 *  @@ -311,7 +342,7 @@ public class PdfAsHelper {  		IPlainSigner signer;  		if (connector.equals("moa")) {  			signer = new PAdESSigner(new MOAConnector(config)); -		} else if(connector.equals("jks")) { +		} else if (connector.equals("jks")) {  			signer = new PAdESSignerKeystore(  					WebConfiguration.getKeystoreFile(),  					WebConfiguration.getKeystoreAlias(), @@ -351,7 +382,8 @@ public class PdfAsHelper {  	 * @return The signed pdf data  	 * @throws Exception  	 */ -	public static byte[] synchornousServerSignature(byte[] pdfData, PDFASSignParameters params) throws Exception { +	public static PDFASSignResponse synchornousServerSignature(byte[] pdfData, +			PDFASSignParameters params) throws Exception {  		Configuration config = pdfAs.getConfiguration();  		// Generate Sign Parameter @@ -359,15 +391,15 @@ public class PdfAsHelper {  				new ByteArrayDataSource(pdfData));  		// Get Connector -		 +  		IPlainSigner signer;  		if (params.getConnector().equals(Connector.MOA)) { -			if(!WebConfiguration.getMOASSEnabled()) { +			if (!WebConfiguration.getMOASSEnabled()) {  				throw new PdfAsWebException("MOA connector disabled.");  			}  			signer = new PAdESSigner(new MOAConnector(config)); -		} else if(params.getConnector().equals(Connector.JKS)) { -			if(!WebConfiguration.getKeystoreEnabled()) { +		} else if (params.getConnector().equals(Connector.JKS)) { +			if (!WebConfiguration.getKeystoreEnabled()) {  				throw new PdfAsWebException("JKS connector disabled.");  			}  			signer = new PAdESSignerKeystore( @@ -391,15 +423,20 @@ public class PdfAsHelper {  		// set Signature Position  		signParameter.setSignaturePosition(params.getPosition()); -		pdfAs.sign(signParameter); +		SignResult signResult = pdfAs.sign(signParameter); -		return output.getData(); +		PDFASSignResponse signResponse = new PDFASSignResponse(); +		signResponse.setSignedPDF(output.getData()); +		signResponse.setSignerCertificate(signResult.getSignerCertificate() +				.getEncoded()); + +		return signResponse;  	} -	 +  	public static void startSignature(HttpServletRequest request, -			HttpServletResponse response, ServletContext context, byte[] pdfData,  -			String connector, String position, String transactionId, String profile) -			throws Exception { +			HttpServletResponse response, ServletContext context, +			byte[] pdfData, String connector, String position, +			String transactionId, String profile) throws Exception {  		// TODO: Protect session so that only one PDF can be signed during one  		// session @@ -424,14 +461,14 @@ public class PdfAsHelper {  				new ByteArrayDataSource(pdfData));  		logger.info("Setting TransactionID: " + transactionId); -		 +  		signParameter.setTransactionId(transactionId); -		 +  		IPlainSigner signer;  		if (connector.equals("bku") || connector.equals("onlinebku")  				|| connector.equals("mobilebku")) {  			BKUSLConnector conn = new BKUSLConnector(config); -			//conn.setBase64(true); +			// conn.setBase64(true);  			signer = new PAdESSigner(conn);  			session.setAttribute(PDF_SL_CONNECTOR, conn);  		} else { @@ -477,25 +514,27 @@ public class PdfAsHelper {  		return data;  	} -	public static byte[] generateVisualBlock(String profile, int resolution) throws IOException, CertificateException, PdfAsException { -		X509Certificate cert = new X509Certificate(PdfAsHelper.class.getResourceAsStream("/qualified.cer")); +	public static byte[] generateVisualBlock(String profile, int resolution) +			throws IOException, CertificateException, PdfAsException { +		X509Certificate cert = new X509Certificate( +				PdfAsHelper.class.getResourceAsStream("/qualified.cer"));  		Configuration config = pdfAs.getConfiguration(); -		SignParameter parameter = PdfAsFactory.createSignParameter( -				config, null); +		SignParameter parameter = PdfAsFactory +				.createSignParameter(config, null);  		parameter.setSignatureProfileId(profile); -		Image img = pdfAs.generateVisibleSignaturePreview(parameter, -				cert, resolution); -		 -		if(img == null) { +		Image img = pdfAs.generateVisibleSignaturePreview(parameter, cert, +				resolution); + +		if (img == null) {  			return null;  		} -		 +  		ByteArrayOutputStream baos = new ByteArrayOutputStream();  		ImageIO.write((RenderedImage) img, "png", baos);  		baos.close();  		return baos.toByteArray();  	} -	 +  	public static void injectCertificate(HttpServletRequest request,  			HttpServletResponse response,  			InfoboxReadResponseType infoboxReadResponseType, @@ -554,8 +593,8 @@ public class PdfAsHelper {  		HttpSession session = request.getSession();  		StatusRequest statusRequest = (StatusRequest) session  				.getAttribute(PDF_STATUS); -//		IPlainSigner plainSigner = (IPlainSigner) session -//				.getAttribute(PDF_SIGNER); +		// IPlainSigner plainSigner = (IPlainSigner) session +		// .getAttribute(PDF_SIGNER);  		String connector = (String) session.getAttribute(PDF_SL_INTERACTIVE); @@ -568,7 +607,8 @@ public class PdfAsHelper {  				logger.debug("Needing Certificate from BKU");  				// build SL Request to read certificate  				InfoboxReadRequestType readCertificateRequest = bkuSLConnector -						.createInfoboxReadRequest(statusRequest.getSignParameter()); +						.createInfoboxReadRequest(statusRequest +								.getSignParameter());  				JAXBElement<InfoboxReadRequestType> readRequest = of  						.createInfoboxReadRequest(readCertificateRequest); @@ -583,32 +623,39 @@ public class PdfAsHelper {  						StringEscapeUtils.escapeHtml4(slRequest));  				template = template.replace("##DataURL##", url);  				template = template.replace("##LOCALE##", locale); -				 -				if(statusRequest.getSignParameter().getTransactionId() != null) { -					template = template.replace("##ADDITIONAL##", "<input type=\"hidden\" name=\"TransactionId_\" value=\"" +  -							StringEscapeUtils.escapeHtml4(statusRequest.getSignParameter().getTransactionId()) + "\">"); + +				if (statusRequest.getSignParameter().getTransactionId() != null) { +					template = template.replace( +							"##ADDITIONAL##", +							"<input type=\"hidden\" name=\"TransactionId_\" value=\"" +									+ StringEscapeUtils +											.escapeHtml4(statusRequest +													.getSignParameter() +													.getTransactionId()) +									+ "\">");  				} else {  					template = template.replace("##ADDITIONAL##", "");  				} -				 +  				response.getWriter().write(template); -				//TODO: set content type of response!! +				// TODO: set content type of response!!  				response.setContentType("text/html");  				response.getWriter().close();  			} else if (statusRequest.needSignature()) {  				logger.debug("Needing Signature from BKU");  				// build SL Request for cms signature -				RequestPackage pack = bkuSLConnector -						.createCMSRequest(statusRequest.getSignatureData(), -								statusRequest.getSignatureDataByteRange(),  -								statusRequest.getSignParameter()); +				RequestPackage pack = bkuSLConnector.createCMSRequest( +						statusRequest.getSignatureData(), +						statusRequest.getSignatureDataByteRange(), +						statusRequest.getSignParameter());  				String slRequest = SLMarschaller  						.marshalToString(of -								.createCreateCMSSignatureRequest(pack.getRequestType())); +								.createCreateCMSSignatureRequest(pack +										.getRequestType()));  				logger.trace("SL Request: " + slRequest); -				 +  				response.setContentType("text/xml");  				response.getWriter().write(slRequest);  				response.getWriter().close(); @@ -621,9 +668,32 @@ public class PdfAsHelper {  				DataSink output = result.getOutputDocument();  				if (output instanceof ByteArrayDataSink) {  					ByteArrayDataSink byteDataSink = (ByteArrayDataSink) output; -					PdfAsHelper.setSignedPdf(request, response, -							byteDataSink.getData()); +					byte[] signedPdf = byteDataSink.getData(); + +					PDFASVerificationResponse verResponse = new PDFASVerificationResponse(); +					List<VerifyResult> verResults = PdfAsHelper +							.synchornousVerify(signedPdf, -2, +									PdfAsHelper.getVerificationLevel(request)); + +					if (verResults.size() != 1) { +						throw new WebServiceException( +								"Document verification failed!"); +					} +					VerifyResult verifyResult = verResults.get(0); + +					verResponse.setCertificateCode(verifyResult +							.getCertificateCheck().getCode()); +					verResponse.setValueCode(verifyResult.getValueCheckCode() +							.getCode()); + +					PdfAsHelper.setPDFASVerificationResponse(request, verResponse); +					PdfAsHelper.setSignedPdf(request, response, signedPdf);  					PdfAsHelper.gotoProvidePdf(context, request, response); + +					String signerCert = Base64.encodeBase64String(result +							.getSignerCertificate().getEncoded()); + +					PdfAsHelper.setSignerCertificate(request, signerCert);  				} else {  					throw new PdfAsWebException("No Signature data available");  				} @@ -689,7 +759,7 @@ public class PdfAsHelper {  		HttpSession session = request.getSession();  		session.setAttribute(PDF_SIGNED_DATA, signedData);  	} -	 +  	public static void setLocale(HttpServletRequest request,  			HttpServletResponse response, String locale) {  		HttpSession session = request.getSession(); @@ -832,21 +902,25 @@ public class PdfAsHelper {  			HttpServletResponse response) {  		return generateURL(request, response, PDF_PDFDATA_PAGE);  	} -	 +  	public static String generateUserEntryURL(String storeId) {  		String publicURL = WebConfiguration.getPublicURL(); -		if(publicURL == null) { -			logger.error("To use this functionality " + WebConfiguration.PUBLIC_URL + " has to be configured in the web configuration"); +		if (publicURL == null) { +			logger.error("To use this functionality " +					+ WebConfiguration.PUBLIC_URL +					+ " has to be configured in the web configuration");  			return null;  		} -		 +  		String baseURL = publicURL + PDF_USERENTRY_PAGE;  		try { -			return baseURL + "?" + UIEntryPointServlet.REQUEST_ID_PARAM + "=" + URLEncoder.encode(storeId, "UTF-8"); -		} catch(UnsupportedEncodingException e) { +			return baseURL + "?" + UIEntryPointServlet.REQUEST_ID_PARAM + "=" +					+ URLEncoder.encode(storeId, "UTF-8"); +		} catch (UnsupportedEncodingException e) {  			logger.warn("Encoding not supported for URL encoding", e);  		} -		return baseURL + "?" + UIEntryPointServlet.REQUEST_ID_PARAM + "=" + storeId; +		return baseURL + "?" + UIEntryPointServlet.REQUEST_ID_PARAM + "=" +				+ storeId;  	}  	public static String generateBKUURL(String connector) { @@ -903,6 +977,53 @@ public class PdfAsHelper {  		return "document.pdf";  	} +	public static void setSignerCertificate(HttpServletRequest request, +			String value) { +		HttpSession session = request.getSession(); +		session.setAttribute(PDF_SIGNER_CERT, value); +	} + +	public static String getSignerCertificate(HttpServletRequest request) { +		HttpSession session = request.getSession(); +		Object obj = session.getAttribute(PDF_SIGNER_CERT); +		if (obj != null) { +			return obj.toString(); +		} +		return null; +	} + +	public static void setVerificationLevel(HttpServletRequest request, +			SignatureVerificationLevel lvl) { +		HttpSession session = request.getSession(); +		session.setAttribute(PDF_VER_LEVEL, lvl); +	} + +	public static SignatureVerificationLevel getVerificationLevel( +			HttpServletRequest request) { +		HttpSession session = request.getSession(); +		Object obj = session.getAttribute(PDF_VER_LEVEL); +		if (obj != null && obj instanceof SignatureVerificationLevel) { +			return (SignatureVerificationLevel) obj; +		} +		return SignatureVerificationLevel.INTEGRITY_ONLY_VERIFICATION; +	} +	 +	public static void setPDFASVerificationResponse(HttpServletRequest request, +			PDFASVerificationResponse resp) { +		HttpSession session = request.getSession(); +		session.setAttribute(PDF_VER_RESP, resp); +	} + +	public static PDFASVerificationResponse getPDFASVerificationResponse( +			HttpServletRequest request) { +		HttpSession session = request.getSession(); +		Object obj = session.getAttribute(PDF_VER_RESP); +		if (obj != null && obj instanceof PDFASVerificationResponse) { +			return (PDFASVerificationResponse) obj; +		} +		return null; +	} +  	public static void setVerificationResult(HttpServletRequest request,  			List<VerifyResult> value) {  		HttpSession session = request.getSession(); @@ -944,11 +1065,11 @@ public class PdfAsHelper {  		}  		return false;  	} -	 +  	public static String getVersion() {  		return PdfAsFactory.getVersion();  	} -	 +  	public static String getSCMRevision() {  		return PdfAsFactory.getSCMRevision();  	} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java index 745e5ca8..cef19a76 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java @@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletResponse;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; +import at.gv.egiz.pdfas.api.ws.PDFASVerificationResponse;  import at.gv.egiz.pdfas.web.helper.PdfAsHelper;  /** @@ -94,6 +95,16 @@ public class PDFData extends HttpServlet {  				}  			}  			response.setHeader("Content-Disposition", "inline;filename=" + PdfAsHelper.getPDFFileName(request)); +			String pdfCert = PdfAsHelper.getSignerCertificate(request); +			if(pdfCert != null) { +				response.setHeader("Signer-Certificate", pdfCert); +			} +			 +			PDFASVerificationResponse resp = PdfAsHelper.getPDFASVerificationResponse(request); +			if(resp != null) { +				response.setHeader("CertificateCheckCode", String.valueOf(resp.getCertificateCode())); +				response.setHeader("ValueCheckCode", String.valueOf(resp.getValueCode())); +			}  			response.setContentType("application/pdf");  			OutputStream os = response.getOutputStream();  			os.write(signedData); diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java index 8eacd3cd..3ff6eb09 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java @@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;  import at.gv.egiz.pdfas.api.ws.PDFASSignRequest;  import at.gv.egiz.pdfas.api.ws.PDFASSignParameters.Connector;  import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;  import at.gv.egiz.pdfas.web.config.WebConfiguration;  import at.gv.egiz.pdfas.web.exception.PdfAsStoreException;  import at.gv.egiz.pdfas.web.exception.PdfAsWebException; @@ -92,6 +93,19 @@ public class UIEntryPointServlet extends HttpServlet {  			String errorUrl = pdfAsRequest.getParameters().getInvokeErrorURL();  			PdfAsHelper.setErrorURL(req, resp, errorUrl); +			SignatureVerificationLevel lvl = SignatureVerificationLevel.INTEGRITY_ONLY_VERIFICATION; +			if(pdfAsRequest.getVerificationLevel() != null) { +			switch (pdfAsRequest.getVerificationLevel()) { +			case INTEGRITY_ONLY: +				lvl = SignatureVerificationLevel.INTEGRITY_ONLY_VERIFICATION; +				break; +			default: +				lvl = SignatureVerificationLevel.FULL_VERIFICATION; +				break; +			} +			} +			PdfAsHelper.setVerificationLevel(req, lvl); +			  			if(pdfAsRequest.getInputData() == null) {  				throw new PdfAsException("No Signature data available");  			} @@ -135,6 +149,7 @@ public class UIEntryPointServlet extends HttpServlet {  		} catch (Throwable e) { +			logger.error("Failed to process Request: ", e);  			PdfAsHelper.setSessionException(req, resp, e.getMessage(), e);  			PdfAsHelper.gotoError(getServletContext(), req, resp);  		} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/DBRequestStore.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/DBRequestStore.java new file mode 100644 index 00000000..6ca6d9a4 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/DBRequestStore.java @@ -0,0 +1,121 @@ +package at.gv.egiz.pdfas.web.store; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.service.ServiceRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.api.ws.PDFASSignRequest; +import at.gv.egiz.pdfas.web.config.WebConfiguration; +import at.gv.egiz.pdfas.web.store.db.Request; + +public class DBRequestStore implements IRequestStore { + +	private static final Logger logger = LoggerFactory +			.getLogger(DBRequestStore.class); +	 +	private SessionFactory sessions; +	private ServiceRegistry serviceRegistry; +	 +	public DBRequestStore() { +		Configuration cfg = new Configuration(); +		cfg.addAnnotatedClass(Request.class); +		cfg.setProperties(WebConfiguration.getHibernateProps()); +		 +		serviceRegistry = new StandardServiceRegistryBuilder().applySettings( +				cfg.getProperties()).build(); +		 +		sessions = cfg.buildSessionFactory(serviceRegistry); +	} +	 +	private void cleanOldRequests() { +		int seconds = WebConfiguration.getDBTimeout(); +		Calendar calendar = Calendar.getInstance(); +		calendar.add(Calendar.SECOND, (-1)* seconds); +		Date date = calendar.getTime(); +		SimpleDateFormat dt = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");  +		logger.info("Clearing Entries before: " + dt.format(date)); +		Session session = null; +		Transaction tx = null; +		try { +			session = sessions.openSession(); +			tx = session.beginTransaction(); +			Query query = session.createQuery("delete from Request as req" +  +				" where req.created < :date"); +			query.setCalendar("date", calendar); +			query.executeUpdate(); +		} catch(Throwable e) { +			logger.error("Failed to save Request", e); +			tx.rollback(); +		} finally { +			if(session != null) { +				session.close(); +			} +		} +	} +	 +	public String createNewStoreEntry(PDFASSignRequest request) { +		// Clean Old Requests +		this.cleanOldRequests(); +		Session session = null; +		Transaction tx = null; +		try { +			session = sessions.openSession(); +			tx = session.beginTransaction(); +			Request dbRequest = new Request(); +			dbRequest.setSignRequest(request); +			dbRequest.setCreated(Calendar.getInstance().getTime()); +			session.save(dbRequest); +		 +			tx.commit(); +			return dbRequest.getId(); +		} catch(Throwable e) { +			logger.error("Failed to save Request", e); +			tx.rollback(); +			return null; +		} finally { +			if(session != null) { +				session.close(); +			} +		} +	} + +	public PDFASSignRequest fetchStoreEntry(String id) { +		// Clean Old Requests +		this.cleanOldRequests(); +	 +		Session session = null; +		Transaction tx = null; +		try { +			session = sessions.openSession(); +			tx = session.beginTransaction(); +			Request dbRequest = (Request) session.get(Request.class, id); +			 +			PDFASSignRequest request = dbRequest.getSignRequest(); +			 +			session.delete(dbRequest); +		 +			tx.commit(); +			return request; +		} catch(Throwable e) { +			logger.error("Failed to fetch Request", e); +			tx.rollback(); +			return null; +		} finally { +			if(session != null) { +				session.close(); +			} +		} +		 +	} + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/db/Request.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/db/Request.java new file mode 100644 index 00000000..d7377166 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/db/Request.java @@ -0,0 +1,52 @@ +package at.gv.egiz.pdfas.web.store.db; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +import at.gv.egiz.pdfas.api.ws.PDFASSignRequest; + +@Entity +@Table(name = "requests") +public class Request { + +	private String uuid;	 +	private Date created; +	private PDFASSignRequest signRequest; +	 +	@Id +	@GeneratedValue(generator = "uuid") +	@GenericGenerator(name = "uuid", strategy = "uuid2") +	@Column(name = "id", unique = true) +	public String getId() { +		return this.uuid; +	} + +	public void setId(String uuid) { +		this.uuid = uuid; +	} +	 +	@Column(name = "created", nullable = false) +	public Date getCreated() { +		return this.created; +	} + +	public void setCreated(Date created) { +		this.created = created; +	} +	 +	@Column(name = "signRequest", nullable = false, length = 52428800) +	public PDFASSignRequest getSignRequest() { +		return this.signRequest; +	} + +	public void setSignRequest(PDFASSignRequest signRequest) { +		this.signRequest = signRequest; +	} +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASSigningImpl.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASSigningImpl.java index 8ade0063..cca66f82 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASSigningImpl.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASSigningImpl.java @@ -35,11 +35,14 @@ import org.slf4j.LoggerFactory;  import at.gv.egiz.pdfas.api.ws.PDFASBulkSignRequest;  import at.gv.egiz.pdfas.api.ws.PDFASBulkSignResponse; -import at.gv.egiz.pdfas.api.ws.PDFASSignParameters; +import at.gv.egiz.pdfas.api.ws.PDFASSignParameters.Connector;  import at.gv.egiz.pdfas.api.ws.PDFASSignRequest;  import at.gv.egiz.pdfas.api.ws.PDFASSignResponse;  import at.gv.egiz.pdfas.api.ws.PDFASSigning; -import at.gv.egiz.pdfas.api.ws.PDFASSignParameters.Connector; +import at.gv.egiz.pdfas.api.ws.PDFASVerificationResponse; +import at.gv.egiz.pdfas.api.ws.VerificationLevel; +import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel; +import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;  import at.gv.egiz.pdfas.web.config.WebConfiguration;  import at.gv.egiz.pdfas.web.helper.PdfAsHelper;  import at.gv.egiz.pdfas.web.store.RequestStore; @@ -51,7 +54,7 @@ public class PDFASSigningImpl implements PDFASSigning {  	private static final Logger logger = LoggerFactory  			.getLogger(PDFASSigningImpl.class); -	public byte[] signPDFDokument(byte[] inputDocument, +	/*public byte[] signPDFDokument(byte[] inputDocument,  			PDFASSignParameters parameters) {  		checkSoapSignEnabled();  		try { @@ -65,7 +68,7 @@ public class PDFASSigningImpl implements PDFASSigning {  				throw new WebServiceException("Server Signature failed.");  			}  		} -	} +	}*/  	public PDFASSignResponse signPDFDokument(PDFASSignRequest request) {  		checkSoapSignEnabled(); @@ -78,12 +81,42 @@ public class PDFASSigningImpl implements PDFASSigning {  			if(request.getParameters().getConnector().equals(Connector.MOA) ||   					request.getParameters().getConnector().equals(Connector.JKS)) {  				// Plain server based signatures!! -				response.setSignedPDF(signPDFDokument(request.getInputData(), -					request.getParameters())); +				response = PdfAsHelper.synchornousServerSignature(request.getInputData(), +					request.getParameters()); +				 +				PDFASVerificationResponse verResponse = new PDFASVerificationResponse(); +				VerifyResult verifyResult = null; +				if(request.getVerificationLevel().equals(VerificationLevel.FULL_CERT_PATH)) { +					List<VerifyResult> verResults = PdfAsHelper.synchornousVerify(response.getSignedPDF(), -1,  +							SignatureVerificationLevel.FULL_VERIFICATION); +					 +					if(verResults.size() != 1) { +						throw new WebServiceException("Document verification failed!"); +					} +					verifyResult = verResults.get(0); +				} else { +					List<VerifyResult> verResults = PdfAsHelper.synchornousVerify(response.getSignedPDF(), -1,  +							SignatureVerificationLevel.INTEGRITY_ONLY_VERIFICATION); +					 +					if(verResults.size() != 1) { +						throw new WebServiceException("Document verification failed!"); +					} +					verifyResult = verResults.get(0); +				} +				 +				verResponse.setCertificateCode(verifyResult.getCertificateCheck().getCode()); +				verResponse.setValueCode(verifyResult.getValueCheckCode().getCode()); +				response.setVerificationResponse(verResponse);  			} else {  				// Signatures with user interaction!!  				String id = RequestStore.getInstance().createNewStoreEntry(request); +				 +				if(id == null) { +					throw new WebServiceException("Failed to store request"); +				} +				  				String userEntryURL = PdfAsHelper.generateUserEntryURL(id); +				  				logger.debug("Generated request store: " + id);  				logger.debug("Generated UI URL: " + userEntryURL); | 
