diff options
15 files changed, 405 insertions, 74 deletions
diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java index ca93aa50..c6a2f72a 100644 --- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java +++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java @@ -196,12 +196,16 @@ public class AppletSecureViewer implements SecureViewer { log.debug("Digesting reference " + signedRefId + " (" + mimeType + ";" + encoding + ")"); } - byte[] hashDataInputDigest = digest(hdi, signedDigestAlg); + if (signedDigestAlg.startsWith("CMS:")) { + log.info("CMS signature - skip verifying hashdata for now"); + } else { + byte[] hashDataInputDigest = digest(hdi, signedDigestAlg); - log.debug("Comparing digest to claimed digest value for reference {}.", signedRefId); - if (!Arrays.equals(hashDataInputDigest, signedDigest)) { - log.error("Bad digest value for reference {}.", signedRefId); - throw new DigestException("Bad digest value for reference " + signedRefId); + log.debug("Comparing digest to claimed digest value for reference {}.", signedRefId); + if (!Arrays.equals(hashDataInputDigest, signedDigest)) { + log.error("Bad digest value for reference {}.", signedRefId); + throw new DigestException("Bad digest value for reference " + signedRefId); + } } verifiedHashDataInputs.add(new ByteArrayHashDataInput(hdi, signedRefId, mimeType, encoding, filename)); diff --git a/BKULocal/src/test/java/at/gv/egiz/bku/local/stal/TestSignRequest.java b/BKULocal/src/test/java/at/gv/egiz/bku/local/stal/TestSignRequest.java index da6c8664..0f967285 100644 --- a/BKULocal/src/test/java/at/gv/egiz/bku/local/stal/TestSignRequest.java +++ b/BKULocal/src/test/java/at/gv/egiz/bku/local/stal/TestSignRequest.java @@ -34,6 +34,7 @@ import at.gv.egiz.bku.utils.StreamUtil; import at.gv.egiz.smcc.SignatureCard; import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.SignRequest; +import at.gv.egiz.stal.SignRequest.SignedInfo; @Ignore public class TestSignRequest { @@ -43,7 +44,9 @@ public class TestSignRequest { StreamUtil.copyStream(getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/local/stal/sigInfo.xml"), os); byte[] signedInfo = os.toByteArray(); SignRequest sr = new SignRequest(); - sr.setSignedInfo(signedInfo); + SignedInfo si = new SignedInfo(); + si.setValue(signedInfo); + sr.setSignedInfo(si); sr.setKeyIdentifier(SignatureCard.KeyboxName.SECURE_SIGNATURE_KEYPAIR.getKeyboxName()); List<STALRequest> reqList = new ArrayList<STALRequest>(1); reqList.add(sr); diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java index a1e29870..836d6538 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java @@ -408,7 +408,9 @@ public class STALServiceImpl implements STALPortType { log.info("[TestSession] add SIGN " + keyIdentifier + " request"); SignRequestType sigT = stalObjFactory.createSignRequestType(); sigT.setKeyIdentifier(keyIdentifier); - sigT.setSignedInfo(TestSignatureData.SIGNED_INFO.get(1)); //select! + SignRequestType.SignedInfo sigI = stalObjFactory.createSignRequestTypeSignedInfo(); + sigI.setValue(TestSignatureData.SIGNED_INFO.get(1)); + sigT.setSignedInfo(sigI); //select! reqs.add(stalObjFactory.createGetNextRequestResponseTypeSignRequest(sigT)); } diff --git a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd index b37e8df7..5f96578d 100644 --- a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd +++ b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd @@ -123,7 +123,16 @@ </restriction> </simpleType> </element> - <element name="SignedInfo" type="base64Binary"/> + <element name="SignedInfo"> + <complexType> + <simpleContent> + <extension base="base64Binary"> + <attribute name="IsCMSSignedAttributes" type="boolean" default="false"/> + </extension> + </simpleContent> + </complexType> + </element> + <element name="SignatureMethod" type="string" minOccurs="0"/> </sequence> </extension> </complexContent> diff --git a/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java b/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java index 164e6335..bfbff5a4 100644 --- a/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java +++ b/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java @@ -114,7 +114,9 @@ public class STALRequestBrokerTest { List<STALRequest> requests = new ArrayList<STALRequest>(); SignRequest r1 = new SignRequest(); r1.setKeyIdentifier("keybox1"); - r1.setSignedInfo("1234".getBytes()); + SignRequest.SignedInfo si1 = new SignRequest.SignedInfo(); + si1.setValue("1234".getBytes()); + r1.setSignedInfo(si1); HashDataInput hdi = new HashDataInput() { @Override @@ -166,7 +168,9 @@ public class STALRequestBrokerTest { List<STALRequest> requests = new ArrayList<STALRequest>(); SignRequest r1 = new SignRequest(); r1.setKeyIdentifier("keybox1"); - r1.setSignedInfo("1234".getBytes()); + SignRequest.SignedInfo si1 = new SignRequest.SignedInfo(); + si1.setValue("1234".getBytes()); + r1.setSignedInfo(si1); HashDataInput hdi = new HashDataInput() { @Override @@ -230,7 +234,9 @@ public class STALRequestBrokerTest { List<STALRequest> requests = new ArrayList<STALRequest>(); SignRequest r1 = new SignRequest(); r1.setKeyIdentifier("keybox1"); - r1.setSignedInfo("1234".getBytes()); + SignRequest.SignedInfo si1 = new SignRequest.SignedInfo(); + si1.setValue("1234".getBytes()); + r1.setSignedInfo(si1); HashDataInput hdi = new HashDataInput() { @Override @@ -263,7 +269,9 @@ public class STALRequestBrokerTest { List<STALRequest> requests2 = new ArrayList<STALRequest>(); SignRequest r2 = new SignRequest(); r2.setKeyIdentifier("keybox2"); - r2.setSignedInfo("6789".getBytes()); + SignRequest.SignedInfo si2 = new SignRequest.SignedInfo(); + si2.setValue("6789".getBytes()); + r2.setSignedInfo(si2); HashDataInput hdi2 = new HashDataInput() { @Override diff --git a/STAL/src/main/java/at/gv/egiz/stal/SignRequest.java b/STAL/src/main/java/at/gv/egiz/stal/SignRequest.java index 7319efcb..e4a49e97 100644 --- a/STAL/src/main/java/at/gv/egiz/stal/SignRequest.java +++ b/STAL/src/main/java/at/gv/egiz/stal/SignRequest.java @@ -27,9 +27,11 @@ package at.gv.egiz.stal; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; /** * <p>Java class for SignRequestType complex type. @@ -42,7 +44,16 @@ import javax.xml.bind.annotation.XmlType; * <extension base="{http://www.egiz.gv.at/stal}RequestType"> * <sequence> * <element name="KeyIdentifier" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="SignedInfo" type="{http://www.w3.org/2001/XMLSchema}base64Binary"/> + * <element name="SignedInfo"> + * <complexType> + * <simpleContent> + * <extension base="<http://www.w3.org/2001/XMLSchema>base64Binary"> + * <attribute name="IsCMSSignedAttributes" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /> + * </extension> + * </simpleContent> + * </complexType> + * </element> + * <element name="SignatureMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> * </sequence> * </extension> * </complexContent> @@ -54,7 +65,8 @@ import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "SignRequestType", propOrder = { "keyIdentifier", - "signedInfo" + "signedInfo", + "signatureMethod" }) public class SignRequest extends STALRequest { @@ -62,13 +74,11 @@ public class SignRequest @XmlElement(name = "KeyIdentifier", required = true) protected String keyIdentifier; @XmlElement(name = "SignedInfo", required = true) - protected byte[] signedInfo; + protected SignRequest.SignedInfo signedInfo; + @XmlElement(name = "SignatureMethod") + protected String signatureMethod; @XmlTransient protected List<HashDataInput> hashData; - @XmlTransient - protected boolean signedInfoIsCMSSignedAttributes = false; - @XmlTransient - protected String signatureMethod; /** * Gets the value of the keyIdentifier property. @@ -99,9 +109,10 @@ public class SignRequest * * @return * possible object is - * byte[] + * {@link SignRequestType.SignedInfo } + * */ - public byte[] getSignedInfo() { + public SignRequest.SignedInfo getSignedInfo() { return signedInfo; } @@ -110,10 +121,35 @@ public class SignRequest * * @param value * allowed object is - * byte[] + * {@link SignRequestType.SignedInfo } + * + */ + public void setSignedInfo(SignRequest.SignedInfo value) { + this.signedInfo = value; + } + + /** + * Gets the value of the signatureMethod property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSignatureMethod() { + return signatureMethod; + } + + /** + * Sets the value of the signatureMethod property. + * + * @param value + * allowed object is + * {@link String } + * */ - public void setSignedInfo(byte[] value) { - this.signedInfo = ((byte[]) value); + public void setSignatureMethod(String value) { + this.signatureMethod = value; } public List<HashDataInput> getHashDataInput() { @@ -124,19 +160,83 @@ public class SignRequest this.hashData = hashData; } - public boolean getSignedInfoIsCMSSignedAttributes() { - return signedInfoIsCMSSignedAttributes; - } + /** + * <p>Java class for anonymous complex type. + * + * <p>The following schema fragment specifies the expected content contained within this class. + * + * <pre> + * <complexType> + * <simpleContent> + * <extension base="<http://www.w3.org/2001/XMLSchema>base64Binary"> + * <attribute name="IsCMSSignedAttributes" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /> + * </extension> + * </simpleContent> + * </complexType> + * </pre> + * + * + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { + "value" + }) + public static class SignedInfo { - public void setSignedInfoIsCMSSignedAttributes(boolean signedInfoIsCMSSignedAttributes) { - this.signedInfoIsCMSSignedAttributes = signedInfoIsCMSSignedAttributes; - } + @XmlValue + protected byte[] value; + @XmlAttribute(name = "IsCMSSignedAttributes") + protected Boolean isCMSSignedAttributes; - public String getSignatureMethod() { - return signatureMethod; - } + /** + * Gets the value of the value property. + * + * @return + * possible object is + * byte[] + */ + public byte[] getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * byte[] + */ + public void setValue(byte[] value) { + this.value = ((byte[]) value); + } + + /** + * Gets the value of the isCMSSignedAttributes property. + * + * @return + * possible object is + * {@link Boolean } + * + */ + public boolean isIsCMSSignedAttributes() { + if (isCMSSignedAttributes == null) { + return false; + } else { + return isCMSSignedAttributes; + } + } + + /** + * Sets the value of the isCMSSignedAttributes property. + * + * @param value + * allowed object is + * {@link Boolean } + * + */ + public void setIsCMSSignedAttributes(Boolean value) { + this.isCMSSignedAttributes = value; + } - public void setSignatureMethod(String signatureMethod) { - this.signatureMethod = signatureMethod; } } diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/translator/STALTranslator.java b/STALService/src/main/java/at/gv/egiz/stal/service/translator/STALTranslator.java index 26eeaf55..28d60ed6 100644 --- a/STALService/src/main/java/at/gv/egiz/stal/service/translator/STALTranslator.java +++ b/STALService/src/main/java/at/gv/egiz/stal/service/translator/STALTranslator.java @@ -41,6 +41,7 @@ import at.gv.egiz.stal.QuitRequest; import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; +import at.gv.egiz.stal.SignRequest.SignedInfo; import at.gv.egiz.stal.SignResponse; import at.gv.egiz.stal.StatusRequest; import at.gv.egiz.stal.StatusResponse; @@ -218,7 +219,11 @@ public class STALTranslator { if (request instanceof SignRequest) { SignRequestType req = of.createSignRequestType(); req.setKeyIdentifier(((SignRequest) request).getKeyIdentifier()); - req.setSignedInfo(((SignRequest) request).getSignedInfo()); + SignRequestType.SignedInfo signedInfo = of.createSignRequestTypeSignedInfo(); + signedInfo.setValue(((SignRequest) request).getSignedInfo().getValue()); + signedInfo.setIsCMSSignedAttributes(((SignRequest) request).getSignedInfo().isIsCMSSignedAttributes()); + req.setSignedInfo(signedInfo); + req.setSignatureMethod(((SignRequest) request).getSignatureMethod()); //TODO add hashdatainput (refactor signRequestType) return of.createGetNextRequestResponseTypeSignRequest(req); } else if (request instanceof InfoboxReadRequest) { @@ -245,7 +250,11 @@ public class STALTranslator { } else if (request instanceof SignRequestType) { SignRequest stalReq = new SignRequest(); stalReq.setKeyIdentifier(((SignRequestType) request).getKeyIdentifier()); - stalReq.setSignedInfo(((SignRequestType) request).getSignedInfo()); + SignedInfo signedInfo = new SignedInfo(); + signedInfo.setValue(((SignRequestType) request).getSignedInfo().getValue()); + signedInfo.setIsCMSSignedAttributes(((SignRequestType) request).getSignedInfo().isIsCMSSignedAttributes()); + stalReq.setSignedInfo(signedInfo); + stalReq.setSignatureMethod(((SignRequestType) request).getSignatureMethod()); return stalReq; } else if (request instanceof QuitRequestType) { return new QuitRequest(); diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/ObjectFactory.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/ObjectFactory.java index 90479808..f3b00402 100644 --- a/STALService/src/main/java/at/gv/egiz/stal/service/types/ObjectFactory.java +++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/ObjectFactory.java @@ -121,6 +121,14 @@ public class ObjectFactory { } /** + * Create an instance of {@link SignRequestType.SignedInfo } + * + */ + public SignRequestType.SignedInfo createSignRequestTypeSignedInfo() { + return new SignRequestType.SignedInfo(); + } + + /** * Create an instance of {@link GetHashDataInputType.Reference } * */ diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/SignRequestType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/SignRequestType.java index 8249491c..50a00406 100644 --- a/STALService/src/main/java/at/gv/egiz/stal/service/types/SignRequestType.java +++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/SignRequestType.java @@ -27,8 +27,10 @@ package at.gv.egiz.stal.service.types; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; /** @@ -49,7 +51,16 @@ import javax.xml.bind.annotation.XmlType; * </restriction> * </simpleType> * </element> - * <element name="SignedInfo" type="{http://www.w3.org/2001/XMLSchema}base64Binary"/> + * <element name="SignedInfo"> + * <complexType> + * <simpleContent> + * <extension base="<http://www.w3.org/2001/XMLSchema>base64Binary"> + * <attribute name="IsCMSSignedAttributes" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /> + * </extension> + * </simpleContent> + * </complexType> + * </element> + * <element name="SignatureMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> * </sequence> * </extension> * </complexContent> @@ -61,7 +72,8 @@ import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "SignRequestType", propOrder = { "keyIdentifier", - "signedInfo" + "signedInfo", + "signatureMethod" }) public class SignRequestType extends RequestType @@ -70,7 +82,9 @@ public class SignRequestType @XmlElement(name = "KeyIdentifier", required = true) protected String keyIdentifier; @XmlElement(name = "SignedInfo", required = true) - protected byte[] signedInfo; + protected SignRequestType.SignedInfo signedInfo; + @XmlElement(name = "SignatureMethod") + protected String signatureMethod; /** * Gets the value of the keyIdentifier property. @@ -101,9 +115,10 @@ public class SignRequestType * * @return * possible object is - * byte[] + * {@link SignRequestType.SignedInfo } + * */ - public byte[] getSignedInfo() { + public SignRequestType.SignedInfo getSignedInfo() { return signedInfo; } @@ -112,10 +127,116 @@ public class SignRequestType * * @param value * allowed object is - * byte[] + * {@link SignRequestType.SignedInfo } + * + */ + public void setSignedInfo(SignRequestType.SignedInfo value) { + this.signedInfo = value; + } + + /** + * Gets the value of the signatureMethod property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSignatureMethod() { + return signatureMethod; + } + + /** + * Sets the value of the signatureMethod property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSignatureMethod(String value) { + this.signatureMethod = value; + } + + + /** + * <p>Java class for anonymous complex type. + * + * <p>The following schema fragment specifies the expected content contained within this class. + * + * <pre> + * <complexType> + * <simpleContent> + * <extension base="<http://www.w3.org/2001/XMLSchema>base64Binary"> + * <attribute name="IsCMSSignedAttributes" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /> + * </extension> + * </simpleContent> + * </complexType> + * </pre> + * + * */ - public void setSignedInfo(byte[] value) { - this.signedInfo = ((byte[]) value); + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { + "value" + }) + public static class SignedInfo { + + @XmlValue + protected byte[] value; + @XmlAttribute(name = "IsCMSSignedAttributes") + protected Boolean isCMSSignedAttributes; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * byte[] + */ + public byte[] getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * byte[] + */ + public void setValue(byte[] value) { + this.value = ((byte[]) value); + } + + /** + * Gets the value of the isCMSSignedAttributes property. + * + * @return + * possible object is + * {@link Boolean } + * + */ + public boolean isIsCMSSignedAttributes() { + if (isCMSSignedAttributes == null) { + return false; + } else { + return isCMSSignedAttributes; + } + } + + /** + * Sets the value of the isCMSSignedAttributes property. + * + * @param value + * allowed object is + * {@link Boolean } + * + */ + public void setIsCMSSignedAttributes(Boolean value) { + this.isCMSSignedAttributes = value; + } + } } diff --git a/STALService/src/test/java/at/gv/egiz/stal/service/translator/STALTranslatorTest.java b/STALService/src/test/java/at/gv/egiz/stal/service/translator/STALTranslatorTest.java index 8331c993..98d301a7 100644 --- a/STALService/src/test/java/at/gv/egiz/stal/service/translator/STALTranslatorTest.java +++ b/STALService/src/test/java/at/gv/egiz/stal/service/translator/STALTranslatorTest.java @@ -28,6 +28,7 @@ package at.gv.egiz.stal.service.translator; import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; +import at.gv.egiz.stal.SignRequest.SignedInfo; import at.gv.egiz.stal.service.translator.STALTranslator.TranslationHandler; import at.gv.egiz.stal.service.types.ObjectFactory; import at.gv.egiz.stal.service.types.RequestType; @@ -94,13 +95,17 @@ public class STALTranslatorTest { System.out.println("translate"); SignRequest request = new SignRequest(); request.setKeyIdentifier("kid"); - request.setSignedInfo("signedinfo".getBytes()); + SignedInfo signedInfo = new SignedInfo(); + signedInfo.setValue("signedinfo".getBytes()); + request.setSignedInfo(signedInfo); STALTranslator instance = new STALTranslator(); JAXBElement<? extends RequestType> result = instance.translate(request); assertEquals(SignRequestType.class, result.getValue().getClass()); SignRequestType resultT = (SignRequestType) result.getValue(); assertEquals(request.getKeyIdentifier(), resultT.getKeyIdentifier()); - assertEquals(request.getSignedInfo(), resultT.getSignedInfo()); + assertEquals(request.getSignedInfo().getValue(), resultT.getSignedInfo().getValue()); + assertEquals(request.getSignedInfo().isIsCMSSignedAttributes(), resultT.getSignedInfo().isIsCMSSignedAttributes()); + assertEquals(request.getSignatureMethod(), resultT.getSignatureMethod()); } /** @@ -111,13 +116,18 @@ public class STALTranslatorTest { System.out.println("translate"); SignRequestType req = of.createSignRequestType(); req.setKeyIdentifier("kid"); - req.setSignedInfo("signedinfo".getBytes()); + SignRequestType.SignedInfo signedInfo = of.createSignRequestTypeSignedInfo(); + signedInfo.setValue("signedinfo".getBytes()); + req.setSignedInfo(signedInfo); + req.setSignatureMethod("signatureMethod"); JAXBElement<? extends RequestType> request = of.createGetNextRequestResponseTypeSignRequest(req); STALTranslator instance = new STALTranslator(); STALRequest result = instance.translateWSRequest(request); assertEquals(SignRequest.class, result.getClass()); assertEquals(req.getKeyIdentifier(), ((SignRequest) result).getKeyIdentifier()); - assertEquals(req.getSignedInfo(), ((SignRequest) result).getSignedInfo()); + assertEquals(req.getSignedInfo().getValue(), ((SignRequest) result).getSignedInfo().getValue()); + assertEquals(req.getSignedInfo().isIsCMSSignedAttributes(), ((SignRequest) result).getSignedInfo().isIsCMSSignedAttributes()); + assertEquals(req.getSignatureMethod(), ((SignRequest) result).getSignatureMethod()); } @Test(expected=RuntimeException.class) diff --git a/STALXService/src/main/resources/wsdl/stal.xsd b/STALXService/src/main/resources/wsdl/stal.xsd index 814aebdb..30880d74 100644 --- a/STALXService/src/main/resources/wsdl/stal.xsd +++ b/STALXService/src/main/resources/wsdl/stal.xsd @@ -123,7 +123,16 @@ </restriction> </simpleType> </element> - <element name="SignedInfo" type="base64Binary"/> + <element name="SignedInfo"> + <complexType> + <simpleContent> + <extension base="base64Binary"> + <attribute name="IsCMSSignedAttributes" type="boolean" default="false"/> + </extension> + </simpleContent> + </complexType> + </element> + <element name="SignatureMethod" type="string" minOccurs="0"/> </sequence> </extension> </complexContent> diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java index cdd8f111..0a2140c3 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java @@ -27,6 +27,7 @@ import at.gv.egiz.stal.STAL; import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; +import at.gv.egiz.stal.SignRequest.SignedInfo; import at.gv.egiz.stal.SignResponse; public class STALSecurityProvider extends IaikProvider { @@ -89,8 +90,10 @@ public class STALSecurityProvider extends IaikProvider { SignRequest signRequest = new SignRequest(); signRequest.setKeyIdentifier(keyboxIdentifier); log.debug("SignedAttributes: " + Util.toBase64String(signedAttributes)); - signRequest.setSignedInfo(signedAttributes); - signRequest.setSignedInfoIsCMSSignedAttributes(true); + SignedInfo signedInfo = new SignedInfo(); + signedInfo.setValue(signedAttributes); + signedInfo.setIsCMSSignedAttributes(true); + signRequest.setSignedInfo(signedInfo); signRequest.setSignatureMethod(signatureMethod); signRequest.setHashDataInput(hashDataInput); return signRequest; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java index 51c6c805..1a6f6df9 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java @@ -25,6 +25,8 @@ package at.gv.egiz.bku.slcommands.impl.xsect; +import iaik.xml.crypto.dsig.AbstractSignatureMethodImpl; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -48,10 +50,9 @@ import at.gv.egiz.stal.STAL; import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; +import at.gv.egiz.stal.SignRequest.SignedInfo; import at.gv.egiz.stal.SignResponse; -import iaik.xml.crypto.dsig.AbstractSignatureMethodImpl; - public class STALSignatureMethod extends AbstractSignatureMethodImpl { /** @@ -99,7 +100,9 @@ public class STALSignatureMethod extends AbstractSignatureMethodImpl { SignRequest signRequest = new SignRequest(); signRequest.setKeyIdentifier(keyboxIdentifier); - signRequest.setSignedInfo(m.toByteArray()); + SignedInfo signedInfo = new SignedInfo(); + signedInfo.setValue(m.toByteArray()); + signRequest.setSignedInfo(signedInfo); signRequest.setHashDataInput(hashDataInputs); List<STALResponse> responses = diff --git a/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java b/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java index 853505ce..61d0d480 100644 --- a/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java +++ b/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java @@ -137,7 +137,7 @@ public class DummySTAL implements STAL { SignRequest signReq = (SignRequest) request; Signature s = Signature.getInstance("SHA1withRSA"); s.initSign(privateKey); - s.update(signReq.getSignedInfo()); + s.update(signReq.getSignedInfo().getValue()); byte[] sigVal = s.sign(); SignResponse resp = new SignResponse(); resp.setSignatureValue(sigVal); diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java index c67084ba..bb7856c3 100644 --- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java +++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java @@ -24,9 +24,12 @@ package at.gv.egiz.bku.smccstal; +import iaik.me.asn1.ASN1; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.security.SignatureException; import java.util.List; import javax.xml.bind.JAXBContext; @@ -53,6 +56,7 @@ import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; import at.gv.egiz.stal.SignResponse; import at.gv.egiz.stal.signedinfo.CanonicalizationMethodType; +import at.gv.egiz.stal.signedinfo.DigestMethodType; import at.gv.egiz.stal.signedinfo.ObjectFactory; import at.gv.egiz.stal.signedinfo.ReferenceType; import at.gv.egiz.stal.signedinfo.SignatureMethodType; @@ -64,6 +68,7 @@ public class SignRequestHandler extends AbstractRequestHandler { private final static String CMS_DEF_SIGNEDINFO_ID = "SignedInfo-1"; private final static String CMS_DEF_OBJECT_ID = "SignatureData-1"; + private final static String OID_MESSAGEDIGEST = "1.2.840.113549.1.9.4"; private static JAXBContext jaxbContext; @@ -82,7 +87,7 @@ public class SignRequestHandler extends AbstractRequestHandler { this.secureViewer = secureViewer; } - private ErrorResponse errorResponse(int errorCode, String errorMessage, Exception e) + private static ErrorResponse errorResponse(int errorCode, String errorMessage, Exception e) { log.error(errorMessage, e); ErrorResponse err = new ErrorResponse(errorCode); @@ -90,32 +95,19 @@ public class SignRequestHandler extends AbstractRequestHandler { return err; } - @SuppressWarnings("unchecked") @Override public STALResponse handleRequest(STALRequest request) throws InterruptedException { if (request instanceof SignRequest) { SignRequest signReq = (SignRequest) request; - byte[] signedInfoData = signReq.getSignedInfo(); + byte[] signedInfoData = signReq.getSignedInfo().getValue(); try { SignedInfoType signedInfo; - if (signReq.getSignedInfoIsCMSSignedAttributes()) { - signedInfo = new SignedInfoType(); - CanonicalizationMethodType canonicalizationMethod = - new CanonicalizationMethodType(); - canonicalizationMethod.setAlgorithm(""); - SignatureMethodType signatureMethod = new SignatureMethodType(); - signatureMethod.setAlgorithm(signReq.getSignatureMethod()); - signedInfo.setCanonicalizationMethod(canonicalizationMethod); - signedInfo.setSignatureMethod(signatureMethod); - signedInfo.setId(CMS_DEF_SIGNEDINFO_ID); - List<ReferenceType> references = signedInfo.getReference(); - ReferenceType reference = new ReferenceType(); - reference.setId(HashDataInput.CMS_DEF_REFERENCE_ID); - reference.setURI(CMS_DEF_OBJECT_ID); - references.add(reference); + if (signReq.getSignedInfo().isIsCMSSignedAttributes()) { + signedInfo = createCMSSignedInfo(signReq); } else { Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); InputStream is = new ByteArrayInputStream(signedInfoData); + @SuppressWarnings("unchecked") JAXBElement<SignedInfoType> si = (JAXBElement<SignedInfoType>) unmarshaller.unmarshal(is); signedInfo = si.getValue(); @@ -160,12 +152,62 @@ public class SignRequestHandler extends AbstractRequestHandler { return errorResponse(1000, "Cannot unmarshal signed info.", e); } catch (IOException e) { return errorResponse(4000, "Error while creating signature.", e); + } catch (SignatureException e) { + return errorResponse(4000, "Error while parsing CMS signature.", e); } } else { return errorResponse(1000, "Got unexpected STAL request: " + request + ".", null); } } + private static SignedInfoType createCMSSignedInfo(SignRequest signReq) throws SignatureException { + SignedInfoType signedInfo = new SignedInfoType(); + byte[] signedInfoData = signReq.getSignedInfo().getValue(); + + CanonicalizationMethodType canonicalizationMethod = + new CanonicalizationMethodType(); + canonicalizationMethod.setAlgorithm(""); + signedInfo.setCanonicalizationMethod(canonicalizationMethod); + + SignatureMethodType signatureMethod = new SignatureMethodType(); + signatureMethod.setAlgorithm(signReq.getSignatureMethod()); + signedInfo.setSignatureMethod(signatureMethod); + + signedInfo.setId(CMS_DEF_SIGNEDINFO_ID); + + List<ReferenceType> references = signedInfo.getReference(); + ReferenceType reference = new ReferenceType(); + reference.setId(HashDataInput.CMS_DEF_REFERENCE_ID); + reference.setURI(CMS_DEF_OBJECT_ID); + DigestMethodType digestMethod = new DigestMethodType(); + digestMethod.setAlgorithm("CMS:" + signReq.getSignatureMethod()); + reference.setDigestMethod(digestMethod); + byte[] messageDigest = null; + try { + ASN1 signedAttributes = new ASN1(signedInfoData); + if (!signedAttributes.isConstructed()) + throw new SignatureException("Error while parsing CMS signature"); + for (int i = 0; i < signedAttributes.getSize(); ++i) { + ASN1 signedAttribute = signedAttributes.getElementAt(i); + if (!signedAttribute.isConstructed()) + throw new SignatureException("Error while parsing CMS signature"); + ASN1 oid = signedAttribute.getElementAt(0); + if (oid.gvObjectId().equals(OID_MESSAGEDIGEST)) { + ASN1 value = signedAttribute.getElementAt(1); + if (!value.isConstructed()) + throw new SignatureException("Error while parsing CMS signature"); + messageDigest = value.getElementAt(0).gvByteArray(); + break; + } + } + } catch (IOException e) { + throw new SignatureException(e); + } + reference.setDigestValue(messageDigest); + references.add(reference); + return signedInfo; + } + @Override public boolean requireCard() { return true; |