How to verify for counter signed XML document? - xml-signature

How to verify the use library Xades4j for counter signed xml document.
Iam getting the following error when verifying with Xades4j :
xades4j.verification.CounterSignatureSigValueRefException:
Verification failed for property 'CounterSignature': the counter
signature doesn't reference the SignatureValue element of the
countersigned signature at
xades4j.verification.CounterSignatureVerifier.verify(CounterSignatureVerifier.java:75)
at
xades4j.verification.CounterSignatureVerifier.verify(CounterSignatureVerifier.java:37)
at
xades4j.verification.GenericDOMDataVerifier.verify(GenericDOMDataVerifier.java:65)
at
xades4j.verification.GenericDOMDataVerifier.verify(GenericDOMDataVerifier.java:30)
at
xades4j.verification.QualifyingPropertiesVerifierImpl.verifyProperties(QualifyingPropertiesVerifierImpl.java:59)
at
xades4j.verification.XadesVerifierImpl.verify(XadesVerifierImpl.java:187)
at
com.fit.einvoice.ingcountersigner.service.xades.XadesVerifyOperation.verifySignature(XadesVerifyOperation.java:92)
at
com.fit.einvoice.ingcountersigner.service.xades.XadesVerifyOperation.verifySignature(XadesVerifyOperation.java:87)
at
com.fit.einvoice.ingcountersigner.service.xades.XadesVerifyOperation.verifySignature(XadesVerifyOperation.java:64)
My validation function :
static void checkSigned(File file) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
XadesVerifyOperation verifyOperation = new XadesVerifyOperation();
ArrayList<XadesVerificationResults> results = verifyOperation.verifySignature(inputStream);
System.out.println("results size: " + results.size());
for (XadesVerificationResults result : results) {
System.out.println(result.SigningCertificate.getIssuerDN());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException ex) {
}
}
}
EDIT:
My counter signed function :
public void CounterSign() throws TransformerFactoryConfigurationError, Exception {
Document doc = SignatureServicesBase.getDocument(_inputStream);
Element sigElem = (Element) doc.getElementsByTagNameNS(Constants.SignatureSpecNS, Constants._TAG_SIGNATURE).item(0);
System.out.println(sigElem.getNodeName());
org.apache.xml.security.Init.init();
XMLSignature xmlSig = new XMLSignature(sigElem, doc.getBaseURI());
//Create counter signer
XadesBesSigningProfile signingProfile = new XadesBesSigningProfile(new Pkcs11KeyingDataProvider(_certInfo));
signingProfile.withAlgorithmsProvider(Sha1AlgProvider.class);
signingProfile.withBasicSignatureOptionsProvider(new MyBasicSignatureOptionsProvider(true, true, false));
final XadesSigner counterSigner = signingProfile.newSigner();
//Extend with counter signature
XadesFormatExtenderProfile extenderProfile = new XadesFormatExtenderProfile();
XadesSignatureFormatExtender extender = extenderProfile.getFormatExtender();
List unsignedProps = Arrays.asList(new CounterSignatureProperty(counterSigner));
extender.enrichSignature(xmlSig, new UnsignedProperties(unsignedProps));
SignatureServicesBase.outputDocument(doc, _outStream);
if (!_isStream) {
_inputStream.close();
_outStream.close();
}
}

I'm not sure I completely understood your question. If you're asking how to verify a counter signature property, it is already done as part of the verification of the "main" signature. Please note:
The same XadesVerifier is used for both the main signature and the counter signature.
If the validation succeeds, a property of type CounterSignatureProperty is added to the result.
You can access the property through the verification result of the main signature
XAdESVerificationResult res = ...;
CounterSignatureProperty p = res.getPropertiesFilter().getOfType(CounterSignatureProperty.class);
EDIT:
The message says everything: the counter signature is probably invalid. By definition, a counter signature must include a reference to the countersigned SignatureValue element.
Can you lookup the CounterSignature element on the original XML document and post it here?

Related

Using Persistent Flash Message Library for ColdFusion

I am trying to use a library for showing Flash Messages https://github.com/elpete/flashmessage But I am having trouble getting it working correctly. The documentation isn't that great and I am new to ColdFusion. I want to have the ability to have persistent error messages across pages. Specifically during checkout so when the user needs to go back or a validation error occurs the message will appear. According to the documentation:
The FlashMessage.cfc needs three parameters to work:
A reference to your flash storage object. This object will need
get(key) and put(key, value) methods. A config object with the
following properties: A unique flashKey name to avoid naming
conflicts. A reference to your containerTemplatePath. This is the view
that surrounds each of the individual messages. It will have
references to a flashMessages array and your messageTemplatePath. A
reference to your messageTemplatePath. This is the view that
represents a single message in FlashMessage. It will have a reference
to a single flash message. The name is chosen by you in your container
template. Create your object with your two parameters and then use it
as normal.
I am getting the error
the function getMessages has an invalid return value , can't cast null value to value of type [array]
I had this script somewhat working at one point but it seems very finicky. I believe it is my implementation of it. I am hoping someone here can help me figure out where I went wrong. Or give me some pointers because I am not sure I am even implementing it correctly.
This is What I have in my testing script:
<cfscript>
alertStorage = createObject("component", 'alert');
config = {
flashKey = "myCustomFlashKey",
containerTemplatePath = "/flashmessage/views/_templates/FlashMessageContainer.cfm",
messageTemplatePath = "/flashmessage/views/_templates/FlashMessage.cfm"
};
flash = new flashmessage.models.FlashMessage(alertStorage, config);
flash.message('blah');
flash.danger('boom');
</cfscript>
And inside of alert.cfc I have:
component {
public any function get(key) {
for(var i = 1; i < ArrayLen(session[key]); i++) {
return session[key][i];
}
}
public any function put(key, value) {
ArrayAppend(session.myCustomFlashKey, value);
return true;
}
public any function exists() {
if(structKeyExists(session,"myCustomFlashKey")) {
return true;
} else {
session.myCustomFlashKey = ArrayNew();
return false;
}
}
}
The Flash Message Component looks like this:
component name="FlashMessage" singleton {
/**
* #flashStorage.inject coldbox:flash
* #config.inject coldbox:setting:flashmessage
*/
public FlashMessage function init(any flashStorage, any config) {
instance.flashKey = arguments.config.flashKey;
singleton.flashStorage = arguments.flashStorage;
instance.containerTemplatePath = arguments.config.containerTemplatePath;
instance.messageTemplatePath = arguments.config.messageTemplatePath;
// Initialize our flash messages to an empty array if it hasn't ever been created
if (! singleton.flashStorage.exists(instance.flashKey)) {
setMessages([]);
}
return this;
}
public void function message(required string text, string type = "default") {
appendMessage({ message: arguments.text, type = arguments.type });
}
public any function onMissingMethod(required string methodName, required struct methodArgs) {
message(methodArgs[1], methodName);
}
public any function render() {
var flashMessages = getMessages();
var flashMessageTemplatePath = instance.messageTemplatePath;
savecontent variable="messagesHTML" {
include "#instance.containerTemplatePath#";
}
setMessages([]);
return messagesHTML;
}
public array function getMessages() {
return singleton.flashStorage.get(instance.flashKey, []);
}
private void function setMessages(required array messages) {
singleton.flashStorage.put(
name = instance.flashKey,
value = arguments.messages
);
}
private void function appendMessage(required struct message) {
var currentMessages = getMessages();
ArrayAppend(currentMessages, arguments.message);
setMessages(currentMessages);
}
}

Using Mockito to test Java Hbase API

This is the method that I am testing. This method gets some Bytes from a Hbase Database based on an specific id, in this case called dtmid. The reason I why I want to return some specific values is because I realized that there is no way to know if an id will always be in Hbase. Also, the column Family and column name could change.
#Override
public void execute(Tuple tuple, BasicOutputCollector collector) {
try {
if (tuple.size() > 0) {
Long dtmid = tuple.getLong(0);
byte[] rowKey = HBaseRowKeyDistributor.getDistributedKey(dtmid);
Get get = new Get(rowKey);
get.addFamily("a".getBytes());
Result result = table.get(get);
byte[] bidUser = result.getValue("a".getBytes(),
"co_created_5076".getBytes());
collector.emit(new Values(dtmid, bidUser));
}
} catch (IOException e) {
e.printStackTrace();
}
}
On my main class when this method is called I want to return a specific value. The method should return some bytes.
byte[] bidUser = result.getValue("a".getBytes(),
"co_created_5076".getBytes());
This is what I have on my Unit Test.
#Test
public void testExecute() throws IOException {
long dtmId = 350000000770902930L;
final byte[] COL_FAMILY = "a".getBytes();
final byte[] COL_QUALIFIER = "co_created_5076".getBytes();
//setting a key value pair to put in result
List<KeyValue> kvs = new ArrayList<KeyValue>();
kvs.add(new KeyValue("--350000000770902930".getBytes(), COL_FAMILY, COL_QUALIFIER, Bytes.toBytes("ExpedtedBytes")));
// I create an Instance of result
Result result = new Result(kvs);
// A mock tuple with a single dtmid
Tuple tuple = mock(Tuple.class);
bolt.table = mock(HTable.class);
Result mcResult = mock(Result.class);
when(tuple.size()).thenReturn(1);
when(tuple.getLong(0)).thenReturn(dtmId);
when(bolt.table.get(any(Get.class))).thenReturn(result);
when(mcResult.getValue(any(byte[].class), any(byte[].class))).thenReturn(Bytes.toBytes("Bytes"));
BasicOutputCollector collector = mock(BasicOutputCollector.class);
// Execute the bolt.
bolt.execute(tuple, collector);
ArgumentCaptor<Values> valuesArg = ArgumentCaptor
.forClass(Values.class);
verify(collector).emit(valuesArg.capture());
Values d = valuesArg.getValue();
//casting this object in to a byteArray.
byte[] i = (byte[]) d.get(1);
assertEquals(dtmId, d.get(0));
}
I am using this down here to return my bytes.For some reason is not working.
when(mcResult.getValue(any(byte[].class), any(byte[].class))).thenReturn(Bytes
.toBytes("myBytes"));
For some reason when I capture the values, I still get the bytes that I specified here:
List<KeyValue> kvs = new ArrayList<KeyValue>();
kvs.add(new KeyValue("--350000000770902930".getBytes(),COL_FAMILY, COL_QUALIFIER, Bytes
.toBytes("ExpedtedBytes")));
Result result = new Result(kvs);
How about replacing
when(bolt.table.get(any(Get.class))).thenReturn(result);
with...
when(bolt.table.get(any(Get.class))).thenReturn(mcResult);

How to get HttpServletRequest in Liferay WebService

Hi I have a webService that is generated from buildServices of Liferay..
the method looks like this
public User getUserTest(long userId) {
User u = null;
try {
Token token = OAuthFactoryUtil.createToken("sasa", "sdad");
} catch (OAuthException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
u = UserLocalServiceUtil.getUser(userId);
System.out.println("xx user " + u.getScreenName());
} catch (Exception e) {
System.out.println(" Exception ************* " + e.toString());
}
return u;
}
the parameters in this ws would be this :
http://localhost:8080/demo-portlet/api/json?serviceClassName=com.sample.portlet.library.service.BookServiceUtil&serviceMethodName=getUserTest&userId=10195&serviceParameters=[userId]
having userId as a parameter..
How would you pass a parameter if you need HttpServletRequest.. my method would look like this
public User getUserTest(HttpServletRequest httpRequest) {
User u = null;
try {
String version = httpRequest.getHeader("X-PHM-APP-VERSION");
Token token = OAuthFactoryUtil.createToken("sasa", "sdad");
} catch (OAuthException e1) {
e1.printStackTrace();
}
try {
String authorization = httpRequest.getHeader("Authorization");
u = UserLocalServiceUtil.getUser(Long.valueOf(authorization));
System.out.println("authorization --> " + authorization);
System.out.println("xx user " + u.getScreenName());
} catch (Exception e) {
System.out.println(" Exception ************* " + e.toString());
}
return u;
}
I need the HttpServletRequest to get the parameters from header, instead of passing through url. Is there a better way to get parameters from header? thanks for your help
I think webservice layer is normally at a later stage where in you would never pass request. Ideally what you would do is pass header parameter to the webservice instead of request
In Liferay, you will get HttpServletRequest from the PortletRequest. Please use com.liferay.portal.util.PortalUtil class.
There are 2 methods in it. getHttpServletRequest() and getOriginalServletRequest(), you will get the both core level http request from these methods.

How to send additional fields to soap handler along with soapMessage?

I am logging RequestXML for a webservice client using SoapHandler as follows
public boolean handleMessage(SOAPMessageContext smc) {
logToSystemOut(smc);
return true;
}
private void logToSystemOut(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean)
smc.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
out.println("\nOutbound message:");
} else {
out.println("\nInbound message:");
}
SOAPMessage message = smc.getMessage();
try {
message.writeTo(out);
out.println("");
} catch (Exception e) {
out.println("Exception in handler: " + e);
}
}
Got a new requirenment to add this xml to DB along with some extra values(which are not present in the xml). Is there any way I can pass few additional fields to above soap handler (in handleMessage method)?
Please note that changing the xml/WSDL or adding this to SOAP message header is not an option for me as it is owned by other interface. Any other solution?
Thanks!
You can cast your service class to a class of type "BindingProvider". In this form you can use it to assign it objects which you can access later from your SOAPHandler. Another useful usage is that you also can change the endPoint URL this way.
Before calling the service you do:
MySoapServicePortType service = new MySoapService().getMySoapServicePort();
BindingProvider bp = (BindingProvider)service;
MyTransferObject t = new MyTransferObject();
bp.getRequestContext().put("myTransferObject", t);
TypeResponse response = service.doRequest();
SOAPMessage message = t.getRequestMessage(message);
From your logging function you do:
private void logToSystemOut(SOAPMessageContext smc) {
...
MyTransferObject t = (MyTransferObject) messageContext.get("myTransferObject");
if (outboundProperty.booleanValue())
t.setRequestMessage(message);
else
t.setResponseMessage(message);
...
}

Custom webservice in Umbraco 4.5 giving odd error

We've created a custom webservice in Umbraco to add (async) files and upload them. After upload the service is called with node and file-information to add a new node to the content tree.
At first our main problem was that the service was running outside of the Umbraco context, giving strange errors with get_currentuser.
Now, we inherit the umbraco BaseWebService from the umbraco.webservices dll and we've set all acces information in the settings file; we authenticatie before doing anything else using (correct and ugly-hardcoded) administrator.
When we now execute the webservice (from the browser or anything else) we get:
at umbraco.DataLayer.SqlHelper`1.ExecuteReader(String commandText, IParameter[] parameters)
at umbraco.cms.businesslogic.CMSNode.setupNode()
at umbraco.cms.businesslogic.web.Document.setupNode()
at umbraco.cms.businesslogic.CMSNode..ctor(Int32 Id)
at umbraco.cms.businesslogic.Content..ctor(Int32 id)
at umbraco.cms.businesslogic.web.Document..ctor(Int32 id)
at FileUpload.AddDocument(String ProjectID, String NodeID, String FileName)*
Where AddDocument is our method. The node (filename w/o extension) does not exist in the tree (not anywhere, it's a new filename/node). We've cleared the recycle bin, so it's not in there either.
Are we missing something vital, does anyone has a solution?
Below is the source for the webservice;
using umbraco.cms.businesslogic.web;
using umbraco.BusinessLogic;
using umbraco.presentation.nodeFactory;
using umbraco.cms.businesslogic.member;
using umbraco.cms;
/// <summary>
/// Summary description for FileUpload
/// </summary>
[WebService(Namespace = "http://umbraco.org/webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FileUpload : umbraco.webservices.BaseWebService //System.Web.Services.WebService
{
private string GetMimeType(string fileName)
{
string mimeType = "application/unknown";
string ext = System.IO.Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null)
mimeType = regKey.GetValue("Content Type").ToString();
return mimeType;
}
[WebMethod]
public string HelloWorld() {
return "Hello World";
}
[WebMethod]
public void AddDocument(string ProjectID, string NodeID, string FileName)
{
Authenticate("***", "***");
string MimeType = GetMimeType(FileName); //"application/unknown";
// Create node
int nodeId = 1197;
string fileName = System.IO.Path.GetFileNameWithoutExtension(#"*****\Upload\" + FileName);
string secGroups = "";
//EDIT DUE TO COMMENT: Behavior remains the same though
Document node = umbraco.cms.businesslogic.web.Document.MakeNew(fileName.Replace(".", ""), new DocumentType(1049), umbraco.BusinessLogic.User.GetUser(0), nodeId);
secGroups = "Intern";
StreamWriter sw = null;
try
{
//EXCEPTION IS THROWN SOMEWHERE HERE
Document doc = NodeLevel.CreateNode(fileName, "Bestand", nodeId);
doc.getProperty("bestandsNaam").Value = fileName;
byte[] buffer = System.IO.File.ReadAllBytes(#"****\Upload\" + FileName);
int projectId = 0;
int tempid = nodeId;
//EXCEPTION IS THROWN TO THIS POINT (SEE BELOW)
try
{
Access.ProtectPage(false, doc.Id, 1103, 1103);
Access.AddMembershipRoleToDocument(doc.Id, secGroups);
}
catch (Exception ex)
{
// write to file
}
try
{
doc.Publish(umbraco.BusinessLogic.User.GetUser(0));
umbraco.library.UpdateDocumentCache(doc.Id);
umbraco.content.Instance.RefreshContentFromDatabaseAsync();
}
catch (Exception ex)
{
// write to file
}
System.IO.File.Delete(FileName);
}
catch (Exception ex)
{
// THIS EXCEPTION IS CAUGHT!!
}
}
public override umbraco.webservices.BaseWebService.Services Service
{
get { return umbraco.webservices.BaseWebService.Services.DocumentService; }
}
}
If anyone has a solution, pointer, hint or whatever; help is appreciated!!
TIA,
riffnl
We've rewritten the whole procedure (dumped all code and restart) and we've got it working now.
I think we've been messing around with the old code so much in trying to get it to work we were missing some key issues, because it functions.
Thanks for thinking along anyway!