Angular local SSL with universal does not work - c#

I created an angular universal app and followed the following tutorial to use SSL for local development with SSR:
https://medium.com/#dnlcyan/local-angular-ssr-with-https-b9d305dc620d
The certificate is trusted in the browser and also the requests work on browser level. But for request coming from the node server the API throws the following exception:
Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware
Failed to authenticate HTTPS connection. System.IO.IOException:
Received an unexpected EOF or 0 bytes from the transport stream. at
System.Net.Security.SslStream.g__InternalFillHandshakeBufferAsync|189_0[TIOAdapter](TIOAdapter
adap, ValueTask`1 task, Int32 minSize) at
System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](TIOAdapter
adapter) at
System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter
adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean
isApm) at
Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware.OnConnectionAsync(ConnectionContext
context)
I read something about that the certificate might not be trusted, but I added it to windows and also the browser indicates that it's correct. I tried to create a new certificate according to this tutorial but it doesn't work as well: https://fmoralesdev.com/2020/01/03/serve-angular-app-over-https-using-angular-cli/
Does anyone know what the issue might be here?

Related

HttpClient connecting via certification validation

I need to connect to an endpoint and pass the certification for validation (on their end). Following this gives me this code:
using var cert = new X509Certificate2(pathToCert);
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(cobCert);
var client = new HttpClient(handler);
var response = await client.PostAsync(url, new StringContent(json, Encoding.UTF8, "application/json"));
This returns the following error:
System.Net.Http.HttpRequestException: The SSL connection could not be
established, see inner exception. --->
System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken
message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo
exception) at
System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken
message, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32
count, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32
count, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32
readBytes, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslStream.PartialFrameCallback(AsyncProtocolRequest
asyncRequest)
What is the correct way to handle this?
Note: The actual app will use IHttpClientFactory but currently creating the HttpClient for testing.
Edit: Sorry forgot to say, that this endpoint with this cert works in Postman
The error complains that the server certificate is invalid. Perhaps it has expired or revoked. Sometimes the root authority certificate itself is compromised and revoked. This is rare but it has happened in the past.
Perhaps a test server uses a self-signed certificate for development. Self-signed certificates are invalid by definition because they aren't signed by a trusted authority.
HTTPS isn't used to encrypt the connection, it's used to ensure that no other server gets "in the middle" of the client and server. It does that by ensuring the remote server is who its certificate says it is. Obviously, the certificate needs to be valid - which means it needs to be signed by a trusted source. Without validation someone could add a malicious proxy to your network that would pose as the remote server, intercept your calls and send them to the remote server.
If the server service has expired or been revoked, the server admin will have to renew it.
To use a self-signed certificate without compromising security is to trust it. The .NET Core SDK will add the self-signed certificate used by .NET Core projects to the trusted certificates of the local machine. On other machines you can navigate to the API URL with a browser, click on the warning that appears at the left of the address bar and trust the certificate

AWS Lambda Function (c#) - Works in debug mode, but errors occur once published

I am new to Amazon Web Services Lambda functions, and I decided to write a small function to ping a website. We have a VPC subnet and security group already set up, which I applied to my function when I published it.
When I run this small function in debug mode through Visual Studio it works okay, but once I publish it to AWS Lambda it fails and I get an exception:
System.Net.NetworkInformation.PingException: An exception occurred during a Ping request. ---> System.PlatformNotSupportedException: The system's ping utility could not be found.\n at System.Net.NetworkInformation.Ping.SendWithPingUtility(IPAddress address, Byte[] buffer, Int32 timeout, PingOptions options)\n at System.Net.NetworkInformation.Ping.SendPingAsyncCore(IPAddress address, Byte[] buffer, Int32 timeout, PingOptions options)\n at System.Net.NetworkInformation.Ping.GetAddressAndSendAsync(String hostNameOrAddress, Int32 timeout, Byte[] buffer, PingOptions options)\n --- End of inner exception stack trace ---\n at System.Net.NetworkInformation.Ping.GetAddressAndSendAsync(String hostNameOrAddress, Int32 timeout, Byte[] buffer, PingOptions options)\n at TestPingWebsite.Function.FunctionHandler(String input, ILambdaContext context) in C:\Users\GWhite\source\TestingWebsite\TestPingWebsite\TestPingWebsite\Function.cs:line 26
Can anybody help me understand why this error occurs please?
AWS lambda does not support outbound ICMP (the protocol that drives ping) traffic. In addition to this, the underlying infrastructure to create the ping messages isnt supported either.
From the AWS docs (https://aws.amazon.com/lambda/faqs/):
Q: What restrictions apply to AWS Lambda function code?
Lambda attempts to impose as few restrictions as possible on normal
language and operating system activities, but there are a few
activities that are disabled: Inbound network connections are blocked
by AWS Lambda, and for outbound connections only TCP/IP and UDP/IP
sockets are supported, and ptrace (debugging) system calls are
blocked. TCP port 25 traffic is also blocked as an anti-spam measure.

Authentication failed because the remote party has closed the transport stream

This happens on the sslStream.AuthenticateAsServer(serverCertificate,
true, SslProtocols.Default, true);
call.
I'm trying to do client authentification. I control both client and server, both are c# via sslstream.
When I use a nodejs server, it works perfectly. But I just cant get the serverside to reliably work in c# for some reason. Clearly the ssl authentification needs to wait for the client to choose the client certificate, but apparently this is not a built in feature for c# sslstream class?
I already tried doing this before the call, but it still immediately errors out on the call:
I dont mind the security question in IE. That's fine. I'm concerned with the fact how sslstream does not seem to work at all with such a basic szenario.
Error from wcf trace:
System.Net Error: 0 : [7928] Exception in AppDomain#13869071::UnhandledExceptionHandler - Authentication failed because the remote party has closed the transport stream..
at System.Net.Security.SslState.ValidateCreateContext(Boolean isServer, String targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertRevocationStatus, Boolean checkCertName)
at System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate serverCertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
Adding the below code helped me overcome the issue (I'm running the app in .NET 4.5.1).
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

Problems FTPing FROM Azure to another FTP site

I've tried using FtpWebRequest and EnterpriseDT.Net.Ftp on an Azure website where I want to pass a byte array from a FileUpload to another FTP site.
This works on local servers and hence will work on a VM but cannot get it working on an Azure website. Admittedly we're trying to avoid the costs of adding a VM or an additional Azure storage account.
It seems the port is blocked on Azure, yet it is open to us on local servers.
[IOException: Failed to connect to XXX.XXX.XXX.XXX:21 within timeout 120000 ms]
EnterpriseDT.Net.StandardSocket.InternalConnect(EndPoint remoteEP, Int32 timeout) +272
EnterpriseDT.Net.StandardSocket.Connect(EndPoint remoteEP, Int32 timeout) +350
EnterpriseDT.Net.Ftp.FTPControlSocket.ConnectSocket(BaseSocket socket, String address, Int32 port) +66
EnterpriseDT.Net.Ftp.FTPControlSocket.Initialize(BaseSocket sock, String remoteHost, Int32 controlPort, Int32 timeout, Encoding encoding) +57
EnterpriseDT.Net.Ftp.FTPClient.Connect(String remoteHost, Int32 controlPort, Int32 timeout) +407
EnterpriseDT.Net.Ftp.FTPClient.Connect() +43
EnterpriseDT.Net.Ftp.FTPConnection.Connect() +456
XXXXX.XXXXX.XXX.XXXXX.FtpUpload(String Id, FileUpload file, String ftpServer, String ftpUsername, String ftpPass, String domainName) +371
Does anyone know how this can be accomplished via .net FtpWebRequest or a third party library?
The FTP port (21) is blocked for an Azure website directly, if you use: ftp://{sitename}.azurewebsites.net, to get the proper FTP profile for that website you need to download it's publishing settings, there you'll find the address, user name and password.
Information on getting the publish profile is here: http://blogs.msdn.com/b/avkashchauhan/archive/2012/06/26/deploying-windows-azure-website-using-visual-studio-web-publish-wizard.aspx
I would also recommend you use the VFS endpoint of your scm site (https://{sitename}.scm.azurewebsites.net) to upload files, this way you use https protocol which is more reliable.
The VFS api:
https://github.com/projectkudu/kudu/wiki/REST-API#vfs
More about your scm site:
http://blogs.msdn.com/b/windowsazure/archive/2014/03/04/windows-azure-websites-online-tools-you-should-know-about.aspx

How to do HTTPS with TcpClient just like HttpWebRequest does?

I've got a communication system based on TcpClient, and it works great except for when it's doing HTTPS to a particular IP. Then it starts to fail.
By using a browser or HttpWebRequest, I have no problems doing HTTPS to that IP.
I've created a test program to narrow my problem down to its basic essence, you can have a look at it here if you want: TestViaTcp
That test program works perfectly for basic HTTP to the same IP, it always produces a successful response to the request. I put it in a loop, trigger it with a keypress, it will continue to succeed all day long. As soon as I toggle the HTTPS, I get a recurring pattern. It'll work, then it won't, success followed by failure followed by success back and forth all day long.
The particular failure I keep getting is this one:
{"Authentication failed because the remote party has closed the transport stream."}
[System.IO.IOException]: {"Authentication failed because the remote party has closed the transport stream."}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
InnerException: null
Message: "Authentication failed because the remote party has closed the transport stream."
Source: "System"
TargetSite: {Void StartReadFrame(Byte[], Int32, System.Net.AsyncProtocolRequest)}
And here's the stack trace attached to that:
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
at DeriveClassNameSpace.Services.Web.TcpMessaging.TestViaTcp(IPEndPoint endpoint, String auth, Boolean useSSL)
HttpWebRequest and the browser are both (IIRC) using the Win32 libraries to handle the back-and-forth communication, while TcpClient is (AFAIK) using the managed .net Socket class, so I'm sure there's a large difference between them. I do need to do this with TcpClient, so unfortunately I can't just "use HttpWebRequest since I know I can make it work".
The biggest hint as to what the problem is here is likely the "works, doesn't, works, doesn't" pattern, what's causing that? What can I do to avoid the IOException I'm getting? Is there some way to get the "always works" behaviour that I can see when I do the HTTPS with HttpWebRequest?
There should be something I can do with TcpClient to get it to act and react just like HttpWebRequest does, but I'm not there yet. Any ideas?
Note: The server I'm communicating with is configurable as to what port it listens on and what protocol it expects, but is otherwise completely unmodifiable.
Also note: I've read that .net 3.5 had this particular issue with SslStream before SP1, but I've got SP1 and my program is built targetting 3.5 so I'm assuming that this isn't a 'known bug' I'm running into here.
Wouldn't you know it, after I spend the time forming the question is when I stumble upon the answer.
Here's the relevant documentation: jpsanders blog entry
The important part was this:
If the stack from the exception includes something similar to this: System.IO.IOException: Authentication failed because the remote party has closed the transport stream. It is possible that the server is an older server does not understand TLS and so you need to change this as specified in the 915599 kb to something like this: ServicePointManager.SecurityProtocol= SecurityProtocolType.Ssl3;Before you make any HTTPS calls in your application.
So I change my accepted protocols to this: (removing the possibility of TLS)
SslProtocols protocol = SslProtocols.Ssl2 | SslProtocols.Ssl3;
And everything works great.
I was allowing TLS, so it tries that first, and the server doesn't support it, so the stream is closed. The next time it uses Ssl2 or Ssl3 and everything's fine. Or something like that. It works, I'm a happy panda.

Categories