Java tutorial
/* * HSM Proxy Project. * Copyright (C) 2013 FedICT. * Copyright (C) 2013 Frank Cornelis. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version * 3.0 as published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, see * http://www.gnu.org/licenses/. */ package be.fedict.hsm.ws.impl; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.util.List; import java.util.Set; import javax.annotation.Resource; import javax.ejb.EJB; import javax.jws.HandlerChain; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.bind.JAXBElement; import javax.xml.ws.BindingType; import javax.xml.ws.WebServiceContext; import javax.xml.ws.soap.SOAPBinding; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import be.fedict.hsm.model.SignatureService; import be.fedict.hsm.ws.DSSConstants; import be.fedict.hsm.ws.ResultMajor; import be.fedict.hsm.ws.jaxb.dss.AnyType; import be.fedict.hsm.ws.jaxb.dss.Base64Signature; import be.fedict.hsm.ws.jaxb.dss.DocumentHash; import be.fedict.hsm.ws.jaxb.dss.InputDocuments; import be.fedict.hsm.ws.jaxb.dss.KeySelector; import be.fedict.hsm.ws.jaxb.dss.ObjectFactory; import be.fedict.hsm.ws.jaxb.dss.ResponseBaseType; import be.fedict.hsm.ws.jaxb.dss.Result; import be.fedict.hsm.ws.jaxb.dss.SignRequest; import be.fedict.hsm.ws.jaxb.dss.SignResponse; import be.fedict.hsm.ws.jaxb.dss.SignatureObject; import be.fedict.hsm.ws.jaxb.dss.VerifyRequest; import be.fedict.hsm.ws.jaxb.hsm.GetAliasesRequest; import be.fedict.hsm.ws.jaxb.hsm.GetCertificateChainRequest; import be.fedict.hsm.ws.jaxb.xmldsig.DigestMethodType; import be.fedict.hsm.ws.jaxb.xmldsig.KeyInfoType; import be.fedict.hsm.ws.jaxb.xmldsig.X509DataType; import be.fedict.hsm.ws.jaxws.DigitalSignatureServicePortType; @WebService(endpointInterface = "be.fedict.hsm.ws.jaxws.DigitalSignatureServicePortType", targetNamespace = "urn:be:fedict:hsm-proxy:ws", serviceName = "DigitalSignatureService") @BindingType(SOAPBinding.SOAP12HTTP_BINDING) @HandlerChain(file = "/hsm-proxy-ws-handlers.xml") public class DigitalSignatureServicePortImpl implements DigitalSignatureServicePortType { private static final Log LOG = LogFactory.getLog(DigitalSignatureServicePortImpl.class); @EJB private SignatureService signatureService; @Resource private WebServiceContext webServiceContext; private final ObjectFactory objectFactory; private final be.fedict.hsm.ws.jaxb.xmldsig.ObjectFactory xmldsigObjectFactory; public DigitalSignatureServicePortImpl() { this.objectFactory = new ObjectFactory(); this.xmldsigObjectFactory = new be.fedict.hsm.ws.jaxb.xmldsig.ObjectFactory(); } @Override @WebMethod @WebResult(name = "VerifyResponse", targetNamespace = "urn:oasis:names:tc:dss:1.0:core:schema", partName = "VerifyResponse") public ResponseBaseType verify( @WebParam(name = "VerifyRequest", targetNamespace = "urn:oasis:names:tc:dss:1.0:core:schema", partName = "VerifyRequest") VerifyRequest verifyRequest) { return null; } @Override @WebMethod @WebResult(name = "SignResponse", targetNamespace = "urn:oasis:names:tc:dss:1.0:core:schema", partName = "SignResponse") public SignResponse sign( @WebParam(name = "SignRequest", targetNamespace = "urn:oasis:names:tc:dss:1.0:core:schema", partName = "SignRequest") SignRequest signRequest) { LOG.debug("sign"); Principal userPrincipal = this.webServiceContext.getUserPrincipal(); if (null != userPrincipal) { String userName = userPrincipal.getName(); LOG.debug("username: " + userName); } else { LOG.debug("no user principal"); } String requestId = signRequest.getRequestID(); String digestMethodAlgorithm = null; byte[] digestValue = null; String keyAlias = null; InputDocuments inputDocuments = signRequest.getInputDocuments(); if (null == inputDocuments) { LOG.error("missing dss:InputDocuments"); return errorSignResponse(ResultMajor.REQUESTER_ERROR); } List<Object> inputDocumentsContent = inputDocuments.getDocumentOrTransformedDataOrDocumentHash(); for (Object object : inputDocumentsContent) { if (object instanceof DocumentHash) { DocumentHash documentHash = (DocumentHash) object; DigestMethodType digestMethod = documentHash.getDigestMethod(); digestMethodAlgorithm = digestMethod.getAlgorithm(); digestValue = documentHash.getDigestValue(); } } AnyType optionalInputs = signRequest.getOptionalInputs(); if (null == optionalInputs) { LOG.error("missing dss:OptionalInputs"); return errorSignResponse(ResultMajor.REQUESTER_ERROR); } List<Object> optionalInputsContent = optionalInputs.getAny(); for (Object object : optionalInputsContent) { if (object instanceof KeySelector) { KeySelector keySelector = (KeySelector) object; KeyInfoType keyInfo = keySelector.getKeyInfo(); List<Object> keyInfoContent = keyInfo.getContent(); for (Object keyInfoObject : keyInfoContent) { if (keyInfoObject instanceof JAXBElement) { JAXBElement jaxbElement = (JAXBElement) keyInfoObject; keyAlias = (String) jaxbElement.getValue(); } } } } if (null == digestMethodAlgorithm) { LOG.error("missing digest algo"); return errorSignResponse(ResultMajor.REQUESTER_ERROR); } if (null == digestValue) { LOG.error("missing digest value"); return errorSignResponse(ResultMajor.REQUESTER_ERROR); } if (null == keyAlias) { LOG.error("missing dss:KeySelector"); return errorSignResponse(ResultMajor.REQUESTER_ERROR); } LOG.debug("digest algo: " + digestMethodAlgorithm); LOG.debug("key alias: " + keyAlias); byte[] signatureValue; try { signatureValue = this.signatureService.sign(digestMethodAlgorithm, digestValue, keyAlias); } catch (NoSuchAlgorithmException e) { return errorSignResponse(ResultMajor.REQUESTER_ERROR); } SignResponse signResponse = this.objectFactory.createSignResponse(); signResponse.setRequestID(requestId); signResponse.setProfile(DSSConstants.HSM_PROXY_DSS_PROFILE_URI); Result result = this.objectFactory.createResult(); signResponse.setResult(result); result.setResultMajor(ResultMajor.SUCCESS.getUri()); result.setResultMinor(DSSConstants.RESULT_MINOR_VALID_ON_ALL_DOCS); SignatureObject signatureObject = this.objectFactory.createSignatureObject(); signResponse.setSignatureObject(signatureObject); Base64Signature base64Signature = this.objectFactory.createBase64Signature(); signatureObject.setBase64Signature(base64Signature); base64Signature.setValue(signatureValue); return signResponse; } private SignResponse errorSignResponse(ResultMajor resultMajor) { SignResponse signResponse = this.objectFactory.createSignResponse(); Result result = this.objectFactory.createResult(); signResponse.setResult(result); result.setResultMajor(resultMajor.getUri()); return signResponse; } private ResponseBaseType errorResponse(ResultMajor resultMajor) { ResponseBaseType response = this.objectFactory.createResponseBaseType(); Result result = this.objectFactory.createResult(); response.setResult(result); result.setResultMajor(resultMajor.getUri()); return response; } @Override @WebMethod(operationName = "get-aliases") @WebResult(name = "Response", targetNamespace = "urn:oasis:names:tc:dss:1.0:core:schema", partName = "GetAliasesResponse") public ResponseBaseType getAliases( @WebParam(name = "GetAliasesRequest", targetNamespace = "urn:be:fedict:hsm-proxy:ws:dss:profiles:hsm-proxy:1.0", partName = "GetAliasesRequest") GetAliasesRequest getAliasesRequest) { String requestId = getAliasesRequest.getRequestID(); Set<String> aliases = this.signatureService.getAliases(); ResponseBaseType response = this.objectFactory.createResponseBaseType(); response.setRequestID(requestId); response.setProfile(DSSConstants.HSM_PROXY_DSS_PROFILE_URI); Result result = this.objectFactory.createResult(); response.setResult(result); result.setResultMajor(ResultMajor.SUCCESS.getUri()); AnyType optionalOutputs = this.objectFactory.createAnyType(); response.setOptionalOutputs(optionalOutputs); for (String alias : aliases) { KeySelector keySelector = this.objectFactory.createKeySelector(); optionalOutputs.getAny().add(keySelector); KeyInfoType keyInfo = this.xmldsigObjectFactory.createKeyInfoType(); keySelector.setKeyInfo(keyInfo); keyInfo.getContent().add(this.xmldsigObjectFactory.createKeyName(alias)); } response.setOptionalOutputs(optionalOutputs); return response; } @Override @WebMethod(operationName = "get-certificate-chain") @WebResult(name = "Response", targetNamespace = "urn:oasis:names:tc:dss:1.0:core:schema", partName = "GetCertificateChainResponse") public ResponseBaseType getCertificateChain( @WebParam(name = "GetCertificateChainRequest", targetNamespace = "urn:be:fedict:hsm-proxy:ws:dss:profiles:hsm-proxy:1.0", partName = "GetCertificateChainRequest") GetCertificateChainRequest getCertificateChainRequest) { String requestId = getCertificateChainRequest.getRequestID(); AnyType optionalInputs = getCertificateChainRequest.getOptionalInputs(); if (null == optionalInputs) { LOG.error("missing dss:OptionalInputs"); return errorResponse(ResultMajor.REQUESTER_ERROR); } List<Object> optionalInputsContent = optionalInputs.getAny(); String alias = null; for (Object object : optionalInputsContent) { if (object instanceof KeySelector) { KeySelector keySelector = (KeySelector) object; KeyInfoType keyInfo = keySelector.getKeyInfo(); if (null == keyInfo) { LOG.error("missing ds:KeyInfo"); return errorResponse(ResultMajor.REQUESTER_ERROR); } List<Object> keyInfoContent = keyInfo.getContent(); for (Object keyInfoObject : keyInfoContent) { if (keyInfoObject instanceof JAXBElement) { JAXBElement jaxbElement = (JAXBElement) keyInfoObject; alias = (String) jaxbElement.getValue(); } } } } if (null == alias) { LOG.error("missing dss:KeySelector/ds:KeyInfo/ds:KeyName"); return errorResponse(ResultMajor.REQUESTER_ERROR); } LOG.debug("get certificate chain for alias: " + alias); Certificate[] certificateChain; try { certificateChain = this.signatureService.getCertificateChain(alias); } catch (NoSuchAlgorithmException e) { LOG.error("no such algo: " + e.getMessage()); return errorResponse(ResultMajor.REQUESTER_ERROR); } if (null == certificateChain) { LOG.error("no cert chain found"); return errorResponse(ResultMajor.REQUESTER_ERROR); } ResponseBaseType response = this.objectFactory.createResponseBaseType(); response.setRequestID(requestId); response.setProfile(DSSConstants.HSM_PROXY_DSS_PROFILE_URI); Result result = this.objectFactory.createResult(); response.setResult(result); result.setResultMajor(ResultMajor.SUCCESS.getUri()); KeyInfoType keyInfo = this.xmldsigObjectFactory.createKeyInfoType(); AnyType optionalOutputs = this.objectFactory.createAnyType(); optionalOutputs.getAny().add(this.xmldsigObjectFactory.createKeyInfo(keyInfo)); response.setOptionalOutputs(optionalOutputs); List<Object> keyInfoContent = keyInfo.getContent(); X509DataType x509Data = this.xmldsigObjectFactory.createX509DataType(); keyInfoContent.add(this.xmldsigObjectFactory.createX509Data(x509Data)); List<Object> x509DataContent = x509Data.getX509IssuerSerialOrX509SKIOrX509SubjectName(); for (Certificate certificate : certificateChain) { try { x509DataContent .add(this.xmldsigObjectFactory.createX509DataTypeX509Certificate(certificate.getEncoded())); } catch (CertificateEncodingException e) { LOG.error("certificate encoding error: " + e.getMessage()); return errorResponse(ResultMajor.RESPONDER_ERROR); } } return response; } }