I'm currently working on a proof of concept to implement an AS2 client. I have set up a consle application that works as the sender, and a ASP .Net API that works as the receiver. I tried to achieve this using the Windows.Security library but there too, there were problem with verifying the signatutre. Then I found MimeKit which seemed easier to use.
While trying to find a solution to my problem it seemed to me that most of the questions on "how to verify a signature" the answers where to do a foreach loop on the signatures in a MultipartSigned, I tried to do that, but it didn't help me.
decrypted is a MimeEntity that contains the whole message.
The null reference occurs the when I call signed.Verify();.
var signed = decrypted as MultipartSigned;
if (signed != null) {
using (var ctx = new TemporaryMimeContext ()) {
foreach (var signature in signed.Verify (ctx)) {
try {
bool valid = signature.Verify ();
} catch (DigitalSignatureVerifyException) {
// There was an error verifying the signature.
}
}
}
}
What should happen is that the signatures should be OK, but what actually happens is that an null refrence exception occurs inside of the assembly files.
The stack trace looks like this
at MimeKit.Cryptography.BouncyCastleSecureMimeContext.<GetDigitalSignaturesAsync>d__28.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MimeKit.Cryptography.BouncyCastleSecureMimeContext.Verify(Stream content, Stream signatureData, CancellationToken cancellationToken)
at MimeKit.Cryptography.MultipartSigned.Verify(CryptographyContext ctx, CancellationToken cancellationToken)
at AS2_Proof_of_Concept.WebAPI.Controllers.MimeKitController.IncomingMessage() in C:\Users\chris\source\repos\AS2 Proof of Concept\AS2_Proof_of_Concept\AS2_Proof_of_Concept.WebAPI\Controllers\MimeKitController.cs:line 104
at Microsoft.Extensions.Internal.ObjectMethodExecutor.<>c__DisplayClass33_0.<WrapVoidMethod>b__0(Object target, Object[] parameters)
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.VoidResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
EDIT
Here is how the signed message looks like.
Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="----=_Part_946d8daa50ab44b699f82dbd3c6bacc0"
------=_Part_946d8daa50ab44b699f82dbd3c6bacc0
Content-Type: application/EDIFACT
Content-Transfer-Encoding: binary
Content-Disposition: attachment filename= HelloWorld.txt
test
------=_Part_946d8daa50ab44b699f82dbd3c6bacc0
Content-Type: application/pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment filename="smime.p7s"
MIIEmQYJKoZIhvcNAQcCoIIEijCCBIYCAQExDTALBglghkgBZQMEAgEwCwYJKoZIhvcNAQcBoIID
EzCCAw8wggH3oAMCAQICEHRJ0r9pduGJTCHsDzuElc4wDQYJKoZIhvcNAQELBQAwETEPMA0GA1UE
AwwGTXlDZXJ0MB4XDTE5MDMyNTEzNTQzMloXDTIwMDMyNTE0MTQzMlowETEPMA0GA1UEAwwGTXlD
ZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApOwOacjTjhHOqTzq3EhnQG3HHfO8
YjCE/+CKcbz++mCQ2gkNVyx37rnrNrSuPp6rYZioKss9sYtwaYUe4iyisZBe7rKWNE9itScZBnwj
SCWDId0zrdd+74bkoz8OOvCizjhIcQNmuq5IyCtwB6kF3VAs58QWacjT1C7sVO+YlZdItp97LqzD
s3N8ERCJWRwWawER9h3lkg+WZWSCG2D9SYaU5fv8PNLmQyTYaacRT32WPLjSoM3YB4J9/LXrfPg+
zrK1z+TByyCmnAeFUo3f7VLrtLZYlnbqEz+WkCmZLh9BQvPjt5M2FU+uljIhaooehEPjQa9MRnUY
il4/inh+FQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsG
AQUFBwMBMBEGA1UdEQQKMAiCBk15Q2VydDAdBgNVHQ4EFgQUaPko4FVtzSG9dxjfY30qhq3sGd0w
DQYJKoZIhvcNAQELBQADggEBAEcfxDHRyfjr378ieNwXRodb6/tCZoFXAHaJtEnNfMfbxit324cW
rKt43dQTYg/ByFRV3HZooeNDp8lNCT7zSfiBnxLaqyDPeNuoG910CVdJ3dp2fh5Jphof4R9hgVdx
FX8BNQYH+QdrNndbCdQr/UPbuc+lmuKMCHDW8HtEOcaMoa5CvIZtL6+w9ofFAz8nWEmngagCYavb
x0fz/XZGQ4zriFs9LZEuAF36QJWsbIc53r0KwZY5r7PTuipqQu5BdkF71ljqE39e9A0nLeYN0D/u
hqstrv4+koq1EiDL/hSJLDjLJF9WZK6UYZobikhWo2QCzMapo5nPHxbTWr98bCgxggFMMIIBSAIB
ATAlMBExDzANBgNVBAMMBk15Q2VydAIQdEnSv2l24YlMIewPO4SVzjALBglghkgBZQMEAgEwCwYJ
KoZIhvcNAQEBBIIBAJyIRI42Um2T1PCq/1rmAagSvogVPinemzQHBwxMN+GNDbyOxDom2jN5j7bC
6xb5PIA/hGGhGcPxY7056Llk/FV3nxN1fjiap7sS7HOzY3YkyzlxWMt93VE0auJJKmDCg1+0tTxs
IjXVYRSIwyiMXNltkGCPH4mTWCgy+M9XsQa5iPm/v+9XPcStnO8b/k8Cy3WWxEztwEl6wwiCywUU
V0OUUAZis5zkoYKrmpSZMN+T5jW6IJ566e1lc/jV5CX6D5Ukcskpmd8WdJyO5mPVRpbXuAJnzkoj
66KO8IjHRQzN8ihB3rj9+yZVdFQNobXBzNH4cVqO845OwhD5JbJFtWQ=
------=_Part_946d8daa50ab44b699f82dbd3c6bacc0--
While stepping through the BounncyCastleMimeContext.GetDigitalSignatureAsync() method, I found out that the SignerInformation.SignedAttributes at SecureMimeDigitalSignature (SignerInformation signerInfo, X509Certificate certificate) was null and then that null refrence caused the signature.EncryptionAlgorithms to be null too.
This was a legitimate bug in Mime 2.1.4 that is now fixed in build 2.1.4.9 located at https://www.myget.org/feed/mimekit/package/nuget/MimeKit
Related
I am unable to upload a text file as an attachment using the Bot framework (Bot.Builder v3.11.0), when trying in the Skype channel. It worked in the Bot framework emulator though. Following is the code which uploads a file and to returns the activity with the uploaded file URL in the attachment. It throws an exception when using the Skype channel. Alternatively is there any other way to achieve uploading/attaching a text file in the Skype channel which the user can then download from within the client?
public static async Task<Activity> GetTextAttachmentAsync(Activity message)
{
var reply = message.CreateReply("Here is a text attachment");
var serviceUrl = reply.ServiceUrl;
var conversationId = reply.Conversation.Id;
byte[] fileData = null;
using (var wc = new System.Net.WebClient())
fileData = wc.DownloadData("https://textfiles.com/100/adventur.txt");
using (var connector = new ConnectorClient(new Uri(serviceUrl)))
{
var attachments = new Attachments(connector);
var token = await (connector.Credentials as MicrosoftAppCredentials).GetTokenAsync();
connector.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = await attachments.Client.Conversations.UploadAttachmentAsync(
conversationId,
new AttachmentData
{
Name = "transcript.html",
OriginalBase64 = fileData,
Type = "text/html"
});
reply.Attachments = new List<Attachment>
{
new Attachment
{
Name = "transcript.html",
ContentType = "text/html",
ContentUrl = attachments.GetAttachmentUri(response.Id)
}
};
return reply;
}
}
Exception thrown from the UploadAttachmentAsync() function above:
Microsoft.Rest.HttpOperationException: Not Found
at Microsoft.Bot.Connector.ErrorHandling.<HandleErrorAsync>d__2`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Connector.ConversationsExtensions.<UploadAttachmentAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Support.Services.Bot.Core.Utilities.AdaptiveCardsHelper.<GetTextAttachmentAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Support.Services.Bot.Core.Dialogs.BotDialog.<HandleMessageAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Support.Services.Bot.Core.Dialogs.DialogBase`1.<MessageReceivedAsync>d__8.MoveNext()
When running your code with Common Language Runtime Errors enabled in Visual Studio. I got the following error:
It seems that the site address https://textfiles.com/100/adventur.txt does not have a trusted certificate and that makes .NET unhappy. When I went to investigate, I found this Stack Overflow answer that suggested using this code below to overcome this but is strongly recommended not to use this in production.
ServicePointManager.ServerCertificateValidationCallback += (o, c, ch, er) => true;
This was going to be my original suggestion before I ran your code: many channels (Skype included), limit the types of files you are able to send from a bot when using base64 and/or local files. For example, I know that you cannot send PDF files as Base64 in Skype. If memory serves correctly, you can only send image and video files (maybe audio too) using the base64 method in Skype. So even if you resolve this error you may run into this afterward. The workaround for this is using hosted files. I'm not exactly sure what you are trying to do with your bot, so I'm not sure if this is an option for you specifically, but it is an option.
So if you find this code not working after resolving the certificate issue, try sending an image file and see if that works, if it does but your HTML file still fails, you will know this is why.
I am trying to make a post call to my web Api which is on local host. But I am getting following error
result = {System.Net.WebException: The remote server returned an
error: (415) Unsupported Media Type. at
System.Net.HttpWebRequest.EndGetResponse (System.IAsyncResult
asyncResult) [0x0005e] in
/Users/builder/data/lanes/3511/f4db8a57/source/mono/mcs/class/System/Sy...
Can anyone help? Below is my code:
private void click (Object sender, EventArgs e)
{
UserInfo user = new UserInfo(1, "hellohello#gmail.com", "helloss");
String data = JsonConvert.SerializeObject(user);
WebClient wc = new WebClient();
wc.UploadStringAsync(new Uri("http://192.168.206.2:155/api/register"), data);
wc.UploadStringCompleted += Wc_UploadStringCompleted;
}
private void Wc_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
var result = e.Error;
}
So far, the Server only get's a string from you and can't know if, it is json, xml or something else. You just have to tell him.
You can to this on a WebClient via:
wc.Add("Content-Type", "aplication/json");
If you are using the HttpClient you have to set ist via the Content property:
request.Content = new StringContent("json", Encoding.UTF8, "application/json");
The HTTP specification states:
415 Unsupported Media Type
The 415 (Unsupported Media Type) status code indicates that the origin server is refusing to service the request because the payload is in a format not supported by the target resource for this method. The format problem might be due to the request's indicated Content- Type or Content-Encoding, or as a result of inspecting the data directly.
It seems your server is having troubles with the format... try adding the headers with .Add("Accept", "aplication/json");
I've upgrade Spring version from 4.0.x to 4.2.3 (4.2.4 just now), suddenly, "required = false" property from #RequestBody annotation does not work as expected (as it did before the version change).
Server response with HttpStatus 415 - Unsupported Media Type.
The controller method (same for every Spring versions).
#RequestMapping(value = "/entity/{entityId}/{from}/{size}", method = RequestMethod.POST)
#ResponseBody
#JsonView(ToShowIn.App.class)
public ResponseEntity<?> getActiveEntityPaged(
#PathVariable int entityId, #PathVariable int from, #PathVariable int size,
#RequestBody(required = false) EntityFilterParam entityFilterParam) {
...
}
Really, it's not problem because from the client, avoiding send null, for example, setting empty EntityFilterParam instance is enough to fix it. But I would like to understand if this bothering issue is because a wrong concept from me or rather is due for a bug from the new Spring versions.
UPDATE#1
Versions
<spring-version>4.2.4.RELEASE</spring-version>
<jackson-2-version>2.3.2</jackson-2-version>
Request is from Android device, working with spring-android library (AKA RestTemplate).
Generic method, works on 4.0.x version, where EntityFilterParam can be null.
super.doRestList(
new HttpEntity<EntityFilterParam>(EntityFilterParam, this.getHttpHeaders()),
HttpMethod.POST,
urlBuilder);
On 4.2.3 and 4.2.4, to fix the issue, EntityFilterParam can't be null. -> HttpStatus 415 - Unsupported Media Type. To fix it.
super.doRestList(
new HttpEntity<EntityFilterParam>((EntityFilterParam != null) ? EntityFilterParam : new EntityFilterParam(), this.getHttpHeaders()),
HttpMethod.POST,
urlBuilder);
Inside doRestList, RestTemplate request is performed.
final ResponseEntity<E[]> responseEntity =
(ResponseEntity) super.getRestTemplate()
.exchange(urlBuilder.getURL(), httpMhetod,
requestEntity, this.entityArray.getClass());
Where, urlBuilder.getURL() (URL string, here #PathVariables are working fine) and this.getHttpHeaders() return the next HttpHeaders configuration.
RestFactory.httpHeaders = new HttpHeaders();
RestFactory.httpHeaders.setAuthorization(this.getAuthorization(user));
RestFactory.httpHeaders.set(HttpHeaders.CONNECTION, "Close"); // Switch off keep-alive.
RestFactory.httpHeaders.set(HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.8");
RestFactory.httpHeaders.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
super.getRestTemplate() is the singleton method which returns the RestTemplate instance set with my own CloseableHttpClient configuration.
I know HttpHeaders.CONTENT_TYPE for application/json is missing, but is consciously, in fact, it works when the http body payload is not empty, and fails when it is.
When the error occurs, 415 is performed before the flow of the request goes inside the controller method, therefore, any operation is doesn't performed.
UPDATE#2
Another interesting point, Jackson2 serializes the null value as "null" string, then the body payload is not being null, is filled with "null".
I've tried reproducing this exact issue, without much success.
Do you confirm that with a curl command the problem still exists?
Something like curl -vvv -X POST https://example.com/entity/12/50/10 (if so, paste here the output)
I'm not 100% about this for RestTemplate in spring-android, but if no content type is provided, the template adds by default a "Content-Type: application/x-www-form-urlencoded". If this is the case, configuring a "DEBUG" log level for "org.springframework.web" should show something like
[INFO] [talledLocalContainer] org.springframework.web.HttpMediaTypeNotSupportedException:
Content type 'application/x-www-form-urlencoded' not supported
I think you should set the Content-Type anyway. You mentioned this fails when you do - could you elaborate a bit on that?
I am getting HTTP 400 when I POST some JSON using RestSharp PCL.
When I send a string, it seems that the \" is included. Which it should not. This might be the reason why the POST does not work.
I am probably missing something that I need to fill in but please do help me to understand what I am missing.
Here is the code I am using
public async Task<bool> DoPost<T>(string endPoint, T content) where T : class
{
var body = JsonConvert.SerializeObject(content);
var request = new RestRequest(endPoint, Method.POST);
request.AddParameter("application/json", body, ParameterType.RequestBody);
try
{
var response = await _client.Execute(request, _cancellationToken.Token);
if (response.IsSuccess)
{
return true;
}
}
catch (Exception e)
{
throw new GTSWebServiceException(e.Message, e);
}
return false;
}
Have you checked this: How to POST request using RestSharp I know you are including the content type in the first argument but maybe you can play with RequestFormat? I doubt that's needed though. Also, have you checked whether your string does actually contain an escaped character like a double quote on it? If you are also seeing that slash on strings could it also be because you are debugging it? What do you receive in the payload coming through in the server that returns you the bad request?
I have a web application on .NET4 and MVC3 (razor) .
I want to handle my application errors in Global.asax. I have created application_error function.
I have noticed and found some errors.
one of them returns this string in Application_Error when I am trying to add break point on line Response.Clear(); and that error is generic.
how can I find which codes or part of my codes makes it?
my code:
protected void Application_Error()
{
var exception = Server.GetLastError();
var httpException = exception as HttpException;
Response.Clear();
Server.ClearError();
}
error on httpException:
{System.Web.HttpException (0x80004005): File does not exist.
at System.Web.StaticFileHandler.GetFileInfo(String virtualPathWithPathInfo, String
physicalPath, HttpResponse response)
at System.Web.StaticFileHandler.ProcessRequestInternal(HttpContext context, String
overrideVirtualPath)
at System.Web.DefaultHttpHandler.BeginProcessRequest(HttpContext context,
AsyncCallback callback, Object state) at
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionSt
ep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&
completedSynchronously)}
i found the solution
string errorLocation = Request.Path;
this syntax in Application_Error() tel you where is the problem :)
Just to state my experience with this exception, in my case the reason was that there was no webpage specified as the start page for the site.