I'm using the UploadCertificate message present in Onvif security service (AdvancedSecurity) https://www.onvif.org/specs/srv/security/ONVIF-Security-Service-Spec.pdf
Sniffing messages with wireshark, I noticed a "bad Request" response.
My code is
_tas__UploadCertificate tas__UploadCertificate_tmp;
_tas__UploadCertificateResponse tas__UploadCertificateResponse_tmp;
tas__UploadCertificate_tmp.Certificate.__ptr = certificate;
tas__UploadCertificate_tmp.Certificate.id = tas__CreatePKCS10CSRResponse_tmp.PKCS10CSR.id;
tas__UploadCertificate_tmp.Certificate.__size = tas__CreatePKCS10CSRResponse_tmp.PKCS10CSR.__size;
AddUsernameTokenDigest(deviceKeyStoreBindingProxy, NULL, GetUser(), GetPwd(), deltaT);
deviceKeyStoreBindingProxy->UploadCertificate(&tas__UploadCertificate_tmp, tas__UploadCertificateResponse_tmp)
in soap specification (link above) :
"If the device cannot process one of the uploaded certificates, it shall produce a BadCertificate fault and neither
store the uploaded certificates nor private key in the keystore. The BadCertificate fault shall not be produced
based on the mere fact that the device’s current time lies outside the interval defined by the notBefore and
notAfter fields as specified by [RFC 5280], Sect. 4.1."
But in section 4.1 I don't see any useful information.
my question is:
where is the field notBefore and notAfter? Any suggestion how to fix my code?
Related
If have multiple databases defined on a particular ArangoDB server, how do I specify the database I'd like an AQL query to run against?
Running the query through the REST endpoint that includes the db name (substituted into [DBNAME] below) ie:
/_db/[DBNAME]/_api/cursor
doesn't seem to work. The error message says 'unknown path /_db/[DBNAME]/_api/cursor'
Is this something I have to specify in the query itself?
Also: The query I'm trying to run is:
FOR col in COLLECTIONS() RETURN col.name
Fwiw, I haven't found a way to set the "current" database through the REST API. Also, I'm accessing the REST API from C++ using fuerte.
Tom Regner deserves primary credit here for prompting the enquiry that produced this answer. I am posting my findings here as an answer to help others who might run into this.
I don't know if this is a fuerte bug, shortcoming or just an api caveat that wasn't clear to me... BUT...
In order for the '/_db/[DBNAME/' prefix in an endpoint (eg full endpoint '/_db/[DBNAME/_api/cursor') to be registered and used in the header of a ::arangodb::fuerte::Request, it is NOT sufficient (as of arangodb 3.5.3 and the fuerte version available at the time of this answer) to simply call:
std::unique_ptr<fuerte::Request> request;
const char *endpoint = "/_db/[DBNAME/_api/cursor";
request = fuerte::createRequest(fuerte::RestVerb::Post,endpoint);
// and adding any arguments to the request using a VPackBuilder...
// in this case the query (omitted)
To have the database name included as part of such a request, you must additionally call the following:
request->header.parseArangoPath(endpoint);
Failure to do so seems to result in an error about an 'unknown path'.
Note 1: Simply setting the database member variable, ie
request->header.database = "[DBNAME]";
does not work.
Note 2: that operations without the leading '/_db/[DBNAME]/' prefix, seem to work fine using the 'current' database. (which at least for me, seems to be stuck at '_system' since as far as I can tell, there doesn't seem to be an endpoint to change this via the HTTP REST Api.)
The docs aren't very helpful right now, so just incase someone is looking for a more complete example, then please consider the following code.
EventLoopService eventLoopService;
// adjust the connection for your environment!
std::shared_ptr<Connection> conn = ConnectionBuilder().endpoint("http://localhost:8529")
.authenticationType(AuthenticationType::Basic)
.user(?) // enter a user with access
.password(?) // enter the password
.connect(eventLoopService);
// create the request
std::unique_ptr<Request> request = createRequest(RestVerb::Post, ContentType::VPack);
// enter the database name (ensure the user has access)
request->header.database = ?;
// API endpoint to submit AQL queries
request->header.path = "/_api/cursor";
// Create a payload to be submitted to the API endpoint
VPackBuilder builder;
builder.openObject();
// here is your query
builder.add("query", VPackValue("for col in collections() return col.name"));
builder.close();
// add the payload to the request
request->addVPack(builder.slice());
// send the request (blocking)
std::unique_ptr<Response> response = conn->sendRequest(std::move(request));
// check the response code - it should be 201
unsigned int statusCode = response->statusCode();
// slice has the response data
VPackSlice slice = response->slices().front();
std::cout << slice.get("result").toJson() << std::endl;
Using the json-rpc-cpp library, I am creating an EOS Wallet using wallet RPC.
HttpClient *temp = new HttpClient("http://127.0.0.1:30031/v1/wallet/create");
string res;
string str = "testwallet1";
temp->SendRPCMessage(str, res);
cout<<"res : "<<res<<endl;
It is creating the wallet successfully, but after that I am getting the following exception.
unknown file: Failure
C++ exception with description "Exception -32603 : INTERNAL_ERROR: : "PW5JcEu7jTXd7XUYLWkPuCUbr1pqBhusqRFfhSVToqUNcDuZ3oeYK"" thrown in the test body.
I found that HttpClient receives a 201 response code. I have no idea how to avoid that exception. Does anyone have any idea?
The issue is caused by a bug in the HttpClient::SendRPCMessage() implementation.
Internally, HttpClient uses libcurl for its HTTP handling, and at the very end of the SendRPCMessage() implementation is the following check if curl_easy_perform() is successful:
long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
if (http_code != 200) {
throw JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR, result);
}
As you can see, SendRPCMessage() throws an exception for ANY HTTP response code other than 200. But per the HTTP standard, ALL 2xx response codes indicate success, not just 200. In this case, response code 201 means:
10.2.2 201 Created
The request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code. If the action cannot be carried out immediately, the server SHOULD respond with 202 (Accepted) response instead.
A 201 response MAY contain an ETag response header field indicating the current value of the entity tag for the requested variant just created, see section 14.19.
This is clearly a logic error in the implementation of SendRPCMessage(). The check of the http_code should be more like this instead:
if ((http_code / 100) != 2)
This will treat all 2xx response codes as success.
I have filed a bug report with json-rpc-cpp's author:
#278 HttpClient::SendRPCMessage() throws ERROR_RPC_INTERNAL for successful HTTP responses
201 basically means that your request was processed successfully. As this source explains:
201 CREATED The request has been fulfilled and has resulted in one or more new resources being created.
The primary resource created by the request is identified by either a
Location header field in the response or, if no Location field is
received, by the effective request URI.
The 201 response payload typically describes and links to the
resource(s) created. See Section 7.2 of RFC7231 for a discussion of
the meaning and purpose of validator header fields, such as ETag and
Last-Modified, in a 201 response.
The exception must be thrown when any further processing is applied to the response data.
I can't tell what exactly causes this without more information.
I want to use Microsoft's Security Support Provider Interface (SSPI) in a Windows Domain environment (with Kerberos) to send encrypted and signed messages between two entities (in C++).
Based on the documentation within the MSDN, there are the two functions MakeSignature() and EncryptMessage() [1] but the documentation as well as the example code [2] do not explicitly anwser the question of how to send data encrypted and signed (according to encrypt-than-mac).
Can anyone confirm that I have to use manually invoke EncryptMessage() and MakeSignature() in sequence to get to the desired result? Or do I miss something there and EncryptMessage() has a way to directly create a signature of the encrypted data?
[1] MSDN documentation of EncryptMessage() and MakeSignature()
https://msdn.microsoft.com/en-us/library/windows/desktop/aa378736(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/aa375378(v=vs.85).aspx
[2] MSDN Example Code
https://msdn.microsoft.com/en-us/library/windows/desktop/aa380531(v=vs.85).aspx
---- Reply to Remus Rusanu's answer 2017-03-09 ---------------------------
Thanks #Remus Rusanu for your answer, I didn't take the GSSAPI interoperability document into account yet.
Here it is stated that "GSS_Wrap and GSS_Unwrap are used for both integrity and privacy with the use of privacy controlled by the value of the "conf_flag" argument." and that "The SSPI equivalent to GSS_Wrap is EncryptMessage (Kerberos) for both integrity and privacy".
You said that "EncryptMessage [...] will do the signing too, if the negotiated context requires it.". This means for me, that the at least the following fContextReq flags need to be set for InitializeSecurityContext():
ISC_REQ_CONFIDENTIALITY
ISC_REQ_INTEGRITY
Can you (or somebody else) can confirm this?
---- Update 2017-03-16 ----------------------------------------------------------------
After further research I came up with the following insights:
The Kerberos specific EncryptMessage() function does not provide message integrity, regardless of how the Securitycontext was initialized.
The general EncryptMessage() and general DecryptMessage functions support the feature of creating and verifying the message's integrity because there exists some supporting Security Support Providers (SSPs) - but Kerberos does not.
If DecryptMessage would check the message's integrity, there must be a respective error return code in case of a modified message. The general DecryptMessage interface lists the error code "SEC_E_MESSAGE_ALTERED" which is described as "The message has been altered. Used with the Digest and Schannel SSPs.".
The specific DecryptMessage interface for the SSPs Digest and Schannel lists the SEC_E_MESSAGE_ALTERED - but the Kerberos DecryptMessage does not.
Within the parameter description of the general EncryptMessage's documentation, the term 'signature' is used only regarding the Digest SSP: "When using the Digest SSP, there must be a second buffer of type
SECBUFFER_PADDING or SEC_BUFFER_DATA to hold signature information".
MakeSignature does not create a digital signature according to Wikipedia's definition (authenticity + non-repudiation + integrity). MakeSignature creates a cryptographic hash to provide message integrity.
The name of the MakeSignature() function leads to the idea that SSPI creates a digital signature (authenticity + non-repudiation + integrity) but the MakeSignature documentation explains that only a cryptographic checksum is created (providing integrity): "The MakeSignature function generates a cryptographic checksum of the message, and also includes sequencing information to prevent message loss or insertion."
The VerifySignature documentation helps as well to clarify SSPI's terminology: "Verifies that a message signed by using the MakeSignature function was received in the correct sequence and has not been modified."
From (1) and (2) it follows that one needs to invoke EncryptData() and afterwards MakeSignature() (for the ciphertext) to achieve confidentiality and integrity.
Hope that my self-answer will help someone at some point in time ;)
If someone has something to add or correct in my answer, please reply and help to improve the information collected here!
If I remember correctly you only call EncryptMessage/DecryptMessage and this will do the signing too, if the negotiated context requires it. For example if you look at SSPI/Kerberos Interoperability with GSSAPI it states that EncryptMessagepairs with GSS_Unwrap and DecryptMessage pairs with GSS_Wrap, without involving MakeSignature. The example in the link also shows that you must supply 3 SecBuffer structures (SECBUFFER_TOKEN, SECBUFFER_DATA and SECBUFFER_PADDING, the last I think is optional) to EncryptMessage and 2 for DecryptMessage. The two complementary examples at Using SSPI with a Windows Sockets Server and Using SSPI with a Windows Sockets Client give full functional message exchange and you can also see that MakeSignature/VerifySignature are never called, the signature is handled by Encrypt/Decrypt and is placed in the 'security token' header or trailer (where to it goes on the wire is not specified by SSPI/SPNego/Kerberos, this is not TLS/Schannel...).
If you want to create a GSS Wrap token with only a signature (not encrypted), pass KERB_WRAP_NO_ENCRYPT as the qop value to EncryptMessage. The signed wrap token includes the payload and the signature.
MakeSignature creates a GSS MIC token - which is only the signature and does not include the payload. You can use this with application protocols that require a detached signature.
I am developing webservice based on CXF. One of the requests is that client should be able to upload the optional PDF file as a part of message. This was pretty trivial:
I have added this with getter and setter to my transfer object:
#XmlMimeType("application/octet-stream")
#XmlElement(name = "InvoicePdf", required = false)
private DataHandler invoicePdf = null;
I have also enabled support for MTOM:
Endpoint endpoint = Endpoint.publish("/myWs", new WsImpl(getServletContext()));
SOAPBinding binding = (SOAPBinding) endpoint.getBinding();
binding.setMTOMEnabled(true);
And the usage:
DataHandler pdf2 = p_invoice.getInvoicePdf();
//pdf2.getInputStream();
//pdf2.writeTo(outputstream);
Everything works great. I am able to receive and process the file. However there might be the case when client do not upload the file since it is optional. The problem is that even though the client do not sent the file I am not able to notice it.
pdf2 is not null
pdf2.getInputStream() is not null
pdf2.getInputStream() contains some data. I would like to skip parsing the input stream and looking for PDF signature. Since it is a lot easier to forward the inputstrem to desired outpustream (write to file)
I have not found in DataHandler or DataSource (pdf2.getDataSource() ) API any appropriate method or field for determining file existance. I see in debug that the empty DataHandler contains DataSource which length is 9, which is a lot less then correct PDF file. Unfortunately the length property is not accessible at all.
Any idea how to determine if the file was sent or not?
The solution is to skip xml tag for this attachment in SOAP message. So my mistake was sending empty tag:
<InvoicePdf></InvoicePdf>
Then you get behavior described in question. However if you skip this tag entirely then DataHandel is null, so I am able to distinguish is file was sent or not.
(This is the first time I've done this actually.)
<mx:HTTPService id="post_update" method="POST" result="{Dumper.info('bye')}"/>
The result handler above is just for debugging purposes, but its never hit, even though what I'm uploading via POST...
post_update.url = getPath(parentDocument.url)+"update";
post_update.send(new_sel);
...is received and handled successfully by my Django view:
def wc_post(request) :
request.session['wc'] = request.POST
return http.HttpResponse("<ok/>", mimetype="text/xml")
As far as what I'm sending back from Django, I'm following the guidelines here:
Sending Images From Flex to a Server
I just don't want it to generate an error on the Flex side considering Django is actually receiving and processing the data. Any help appreciated. Can't remember the text of the error in Flex at the moment.
UPDATE: new_sel (what I'm posting from Flex) is just a Flex Object, with various text fields.
UPDATE: various error messages from event.message (in fault handler):
faultCode = "Server.Error.Request"
faultString = "HTTP request error"; DSStatusCode = 500; errorID = 2032; type = "ioError"
This is more grasping at straws than answers, but do I have to send a particular type of header back from Django- the default sent by Django includes a 200 success status code, and the response I was sending of "<ok/>" with mime type of "text/xml" was following the example exactly that I provided from that other source.
And also the url I'm sending the POST to is localhost:8000/wr_view1/wr_webcube/update, and I previously successfully did a GET to localhost:8000/wr_view1/wr_webcube/webcube.xml, and despite the .xml extension in the case of GET, it was still being handled by Django (and without errors in Flex). In the case of this POST, once again, the data is actually succesfully sent and handled by Django, but Flex is returning Error 2032, which I found out can mean numerous different things including cross domain issues, but don't see how that's the case here.
Just had to return HttpResponse("ok") Didn't like it being sent as xml for some reason. So much ado about nothing I guess.