dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.46k stars 10.03k forks source link

The generated certificate from dotnet dev-certs https isn't valid on iOS #3957

Open azimuthdeveloper opened 6 years ago

azimuthdeveloper commented 6 years ago

When you use dotnet dev-certs https --trust on Mac OSX, it creates a new certificate and adds it to the store as expected. However, when you are using the iOS simulator to test that website, or even use Azure B2C authorisation, you can't use the generated certificate on the device.

The reason for this is the certificate generated isn't a self-signed cert with Basic Constraint x509 extension with enabled CA option. The dotnet certs tool should provide the option to create this type of certificate. Without it, you can't trust the certificate on iOS and you can't do any HTTPS calls from your iOS simulator to your localhost webserver.

Tratcher commented 6 years ago

@javiercn @blowdart

azimuthdeveloper commented 6 years ago

I also tried cloning the tool that makes the certificate to see if I could manually add the properties required but I couldn't make it work unfortunately :(. This means that any https calls to a development server while developing won't work, because the iOS simulator does not share a certificate store with the parent OS (OSX).

blowdart commented 6 years ago

Can you not use a development mobile profile to trust it, using the Apple Configurator app? Changing the tools to start supporting the pretense of a CA is something I'm uncomfortable with to be honest. You wouldn't install a CA cert on a web site, so you're not testing with like for like type certs.

azimuthdeveloper commented 6 years ago

I'll try that and report back 😀

azimuthdeveloper commented 6 years ago

I couldn't work out how to use Apple Configurator to install the SSL certificate. But I will keep on with it.

I'm also having issues getting Edge to trust the self signed certificate, Chrome and Firefox are fine with it. I would have thought running "dotnet dev-certs https --trust" would have made the certificate also trusted by Edge on Windows 10. But it seems it doesn't work out of the box.

javiercn commented 6 years ago

Browsers cache the trust settings for the certificates. You most likely had Edge opened when you ran the tool. Close all Edge instances and reopen it and the certificate should show as trusted.


From: lewcianci notifications@github.com Sent: Saturday, November 10, 2018 7:27:37 PM To: aspnet/AspNetCore Cc: Javier Calvarro Nelson; Mention Subject: Re: [aspnet/AspNetCore] The generated certificate from dotnet dev-certs https isn't valid on iOS (#3957)

I couldn't work out how to use Apple Configurator to install the SSL certificate. But I will keep on with it.

I'm also having issues getting Edge to trust the self signed certificate, Chrome and Firefox are fine with it. I would have thought running "dotnet dev-certs https --trust" would have made the certificate also trusted by Edge on Windows 10. But it seems it doesn't work out of the box.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Faspnet%2FAspNetCore%2Fissues%2F3957%23issuecomment-437640693&data=02%7C01%7Cjacalvar%40microsoft.com%7C7adc4f1579b348a5e2dc08d64785a139%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636775036595928791&sdata=sFjUx4TNa7dwIlCtKcy%2BoV6rJUDcyyGl5B%2F2TrLeqSg%3D&reserved=0, or mute the threadhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAGq8a34w1oqwpeFeqD0zozm4O8hRMyUfks5ut5kogaJpZM4YRzfR&data=02%7C01%7Cjacalvar%40microsoft.com%7C7adc4f1579b348a5e2dc08d64785a139%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636775036595938800&sdata=K61X4GDKD6%2BoykP6j3cgLpd7uRXbqlI26WT4qUCUuTg%3D&reserved=0.

javiercn commented 5 years ago

Closing this issue as the question has been answered and there's no more action to be taken here.

ckpearson commented 5 years ago

@lewcianci did you get it working with the iOS simulator?

I'm running up against this issue, I have:

  1. Created a profile in configurator
  2. Added the certificate created by dev-certs
  3. Signed the profile using my Apple Developer Credentials

iOS is happy to accept the profile, even going so far as giving it a checkmark to say it's a verifiably signed profile.

BUT

The trust store still won't let me trust the certificate (it simply doesn't show up).

Installing the profile:

screenshot 2019-01-29 at 22 49 58

Certificates in profile:

screenshot 2019-01-29 at 22 51 53

Profile has been installed:

screenshot 2019-01-29 at 22 54 28

The certificate trust store is empty however:

screenshot 2019-01-29 at 22 56 58

This is a bit of an oversight in my opinion, as understandably iOS wants to be able to maintain a trust chain for the certificate, and it can't do that because there's no CA information.

The only potential workaround I've been able to identify (and yet to pursue) would be to generate my own CA, produce certificates using that, get .net to use those certs, and then send the CA & dev cert over to iOS - but this seems like overkill considering dev-certs is supposed to support certificate-related tasks for development.

I'd request you reopen the issue and look into allowing the tool to generate suitable certificates for these sorts of scenarios.

azimuthdeveloper commented 5 years ago

No I never got it working. I agree with you @ckpearson - these development scenarios are supposed to make it super easy for development in these situations. I never found a way forward. I think the only reason why I had these issues is because I was trying to use oauth authentication in my app and I absolutely had to have https on the identity server.

I'd love to see this fixed, or worked around, or anything

azimuthdeveloper commented 5 years ago

@blowdart any chance of this getting some attention? @ckpearson has included screenshots and a fresh set of reasons as to why this is required. If I had the slightest idea how the dev-certs app worked I would have a go at it and submit a PR.

ckpearson commented 5 years ago

@lewcianci I'm building something using IdentityServer, so I of course want https.

It's all fine for the web app, because that's running on my local machine and as such is able to just trust the certificate because it's in the keychain.

iOS is a bit stricter about it because it can't verify the CA, we either need dev-certs to produce a local-dev CA cert and the local-dev signing cert, or just produce a cert with the CA extension which is what iOS is looking for / a valid chain to enable you to trust it.

I gather that the common dev scenario for .net core is web apps, but for native app dev in simulators and on test devices, this really is needed...

azimuthdeveloper commented 5 years ago

FWIW, I think its fairly straightforward to get ASP .NET to load a HTTPS certificate at startup that could be provisioned from your development CA. I started going down this path back in the day but got waylaid by other stuff.

I'd love to see this get fixed 👍

ckpearson commented 5 years ago

@lewcianci aye, it seems simple enough to get Kestrel pulling in a cert at runtime, and I found this (https://blogs.msdn.microsoft.com/webdev/2017/11/29/configuring-https-in-asp-net-core-across-different-platforms/) which has some openssl cert generation, and there's a lovely basicConstraints = critical, CA:false which I'm going to try tweaking.

Will let you know if I'm successful in producing a cert iOS is happy to take, if it's just that CA:false needs to be CA:true (I have no idea about the workings of certificates 🤷‍♂️) then hopefully a fix to dev-certs would be possible, because it really would be great to not have to pollute my code with manual cert loading, especially once it comes time to deploy because I'd like to make use of Azure cert binding...

azimuthdeveloper commented 5 years ago

@ckpearson you would be my favourite if you patched dev-certs to make it work. I have no idea about certificates either - its a very, very big topic that I haven't gotten into.

ckpearson commented 5 years ago

@lewcianci tbh who has the time?! I had a bloody hard enough time getting my head around OAuth and OIDC for IdentityServer, and then the IdentServer docs are hardly up to scratch, they're out of date in places, and there's no real section on how to configure clients for native app scenarios 🤷‍♂️

Still, if it were easy, we wouldn't have such in-demand jobs.

ckpearson commented 5 years ago

@lewcianci can confirm:

screenshot 2019-01-29 at 23 54 50 screenshot 2019-01-29 at 23 55 10

The difference here is that I've set CA:true manually by generating my own cert, but I can see in the source for the certificate utility dev-certs uses: https://github.com/aspnet/Extensions/blob/8ddc5722596937430ddb6b2aec2fcea06723d5a7/shared/Microsoft.AspNetCore.Certificates.Generation.Sources/CertificateManager.cs#L169 that it would be possible for it to do the same...

ckpearson commented 5 years ago

Actually, the CA thing just creates a root cert, which (I think) is useless in and of itself, so I'm now trying a workaround to produce a CA root and derivative certs myself, will update here as could be a way around this for people before a fix is made / it doesn't get changed.

azimuthdeveloper commented 5 years ago

Yeah thats exactly it @ckpearson (as an aside, I agonised for days over OIDC and OpenIddict. I got it working in the end but I felt extremely dense the whole time (like everyone else has it working/gets it working, why can't I?))

ckpearson commented 5 years ago

@lewcianci I can confirm I now have this up and running!

screenshot 2019-01-30 at 00 52 46

I've put the instructions I followed here

It's longer-winded than I'd have liked, and it sucks that I have to configure the cert at runtime, but it does the trick!

blowdart commented 5 years ago

A work around that uses a self trusted root CA isn't something I would be happy putting in the dev tool, because, well, we're venturing into risky territory, as now you have a root CA that can be used for more than local host. You can generate such a set in powershell, but it's not something we'd do.

ckpearson commented 5 years ago

@blowdart I get that, but it is only for localhost work really, and the CA is only going to be trusted where it's trusted, so the scope for abuse might be small enough...

I don't know enough about this to be able to say one way or the other, but iOS requires a valid chain to enable cert trust, and as it stands, dev-certs fails to support the scenario where you're building an api for consumption by a mobile app.

azimuthdeveloper commented 5 years ago

@blowdart For instances where you use OIDC or OpenIddict for OAuth, in order to test against iOS devices (and probably Android and UWP) you have to have a SSL trusted certificate in use. In the context of the developer undertaking this, they are on the right path from a security standpoint (using OAuth instead of transmitting credentials or equivalent).

You're absolutely right that the self trusted root CA would be risky, but the alternative is that the difficulty in getting this set up and facing a vertical wall of learning curve using openssl commands to generate the required stuff means that people could give up from this, and just revert to "what works" (using less secure ways to transmit credentials, etc).

On one hand, having dev-certs create a CA is a scary thing, but on the other, it should be easy for people to do the right thing and develop in a HTTPS environment without going through what we have to go through today. From a technical perspective this is something we need to have iOS devices query an in-development API. The only thing shutting this down is the security concerns in doing so. Are these security concerns in dotnet's team purview to enable/restrict?

Even if dev-certs had an option for this with a huge red console warning like "DRAGONS! THIS CA CAN'T BE TRUSTED". Even if the CA was called "DONT_TRUST_ME DOTNET" like what we see with Fiddler.

blowdart commented 5 years ago

Honestly at that point, where you want to test with ODIC servers, publish to the cloud. You get free SSL certs, be it via Azure or Amazon or LetsEncrypt, which don't need profile loading.

I'm sorry, but the risk of generating root CAs is too much for one mobile testing scenario.

ckpearson commented 5 years ago

@blowdart really? Deploying every time you want to test? Isn't that a bit mental? And you can't use certs on Azure unless it's a paid tier (last I checked).

I honestly feel it's an oversight for this to not be supported, at the very least with huge flashy warnings and all manner of controls around it, other tools like Fiddler support these sorts of certificates for inspecting traffic from an IOS device.

What specifically would be the concern around generating a new root CA? Particularly one limited to an individual dev machine, for work on localhost, with a password the user has to enter in the console?

I just don't see how (and this could be my lack of knowledge, if so, please do let me know) this could be abused, at least, not in any far-reaching, super-scary way...

ckpearson commented 5 years ago

@blowdart and I'd add that the OIDC server I'm developing against is IdentityServer, running locally...

azimuthdeveloper commented 5 years ago

Your solution to push to the cloud is a nonstarter because:

I didn't realise that developing with dotnet would leave me with with broken development workflows due to how heavily opinionated the tooling is (we're never going to let you generate CA's, even though you need them for a legitimate development scenario, because we think its a bad idea)

@ckpearson the concern is that your CA could get out in the wild and that would be bad for security. Something like, someone would deploy your code into production, see the cert warnings, and just install the certs from the development environment into production to make the errors "go away". That's really bad for a lot of reasons. But it depends on many stuff-ups of many different people first. It's weird that the dotnet tools are so heavily opinionated around what you should/shouldn't do, because something bad might happen.

ckpearson commented 5 years ago

@lewcianci oh, I'd argue no more so than secrets hardcoded in OSS repos anyway 🤷‍♂️

blowdart commented 5 years ago

Against every other piece of security work we have this is very low in the priority list, as well as being dangerous. As there are other ways to create suitable certs I'm just not convinced about the safety or that I should cancel something else to do this instead. Which is what it would boil down to.

ckpearson commented 5 years ago

@blowdart fair enough, is there somewhere I can log this as something for further consideration down the line / something that ought to at the least be documented, as I ran headfirst into this working with IdentityServer and it having practically zero documentation around mobile app dev scenarios.

I suppose I'm trying to work out what repo / team would be responsible for at least looking at this, as I feel it's something the community could do with being aware of / having input on.

azimuthdeveloper commented 5 years ago

@blowdart that's okay, as long as its somewhere in your priority list. Also you keep saying its dangerous, could you elaborate? @ckpearson and I have highlighted a legitimate development scenario for this, if you flesh out why its a bad idea I'll take heed appropriately. As far as I know, you are concerned that a CA could get out in the wild and that could cause security issues?

Also, you don't have to cancel anything else, it can just go on the backburner. @ckpearson or myself could submit a PR to bring this functionality in.

blowdart commented 5 years ago

I'll reopen in issue and put it into the backlog for consideration in the 3.1 timeframe.

kevinchalet commented 5 years ago

(as an aside, I agonised for days over OIDC and OpenIddict. I got it working in the end but I felt extremely dense the whole time (like everyone else has it working/gets it working, why can't I?))

If you want to chat about your (negative) experience with OpenIddict and/or have concrete elements you think could/should be improved (I suspect documentation is one of them), feel free to ping me on Gitter (https://gitter.im/openiddict/openiddict-core) or on Slack (http://tattoocoder.com/asp-net-core-slack-community/)

blowdart commented 5 years ago

And for triage;

Any root CA generated would need to be very constrained and only able to issue HTTPS certificates via EKU, not wide open for any purpose, so EKU of 1.3.6.1.5.5.7.3.1. Furthermore there should be a path length constraint of 0. Key usage should be restricted to Certificate Signing. As there will be no CRL or OCSP there's no need for those uses.

Validity length to be discussed.

Would this feature be offset by lets encrypt support instead? (Probably not)

ckpearson commented 5 years ago

@blowdart I understood practically none of that, but what might be a solution would be to use lets encrypt certs as you said, I'm fairly sure iOS would trust those quite readily, and avoids the need for self-issuance and self-creation of root CAs.

blowdart commented 5 years ago

You'd never get a lets encrypt certificate for localhost. So you'd have to get a domain validated cert, and the normal way is by putting a file on the server you want a cert for, but because that's your dev PC that's going to be firewalled off, so now you have to go the DNS route to validate your request, which can't be automated, because all DNS providers have different APIs. Hence "probably not", and why let's encrypt isn't really a solution for any dev work.

ckpearson commented 5 years ago

@blowdart gotcha, so perhaps the best approach really is to abandon local-dev https and just ensure it's configured and utilised properly upon deployment, because there's still all the considerations like running on a live test device over the local network too, as the cert isn't going to match "localhost" when requested remotely anyway...

'tis a shame that secure local dev practices aren't easier than this.

blowdart commented 5 years ago

And we had that before, but by enabled HTTPS for the majority of scenarios we're helping to close a gab and not rely on devs remembering to do the right configuration, which is a win. We won't abandon local-dev https simply because it won't work on iOS.

ckpearson commented 5 years ago

@blowdart apologies, I meant I could abandon local https for my dev scenario, rather than dropping it as a default in the templates - it most certainly should be default in the templates!

0xced commented 5 years ago

I'm currently working on a solution for iOS simulators to trust the ASP.NET Core development certificate. I got it to work but it needs cleanup, better diagnostics and error handling before I submit a pull request. I have not yet investigated the possibility of trusting the development certificate on an actual iOS device plugged in USB.

You can see my early work in progress on https://github.com/0xced/AspNetCore/tree/dev-certs-https-ios

0xced commented 5 years ago

Also, if you want to go the CA route you should have a look at mkcert which is a simple zero-config tool to make locally trusted development certificates with any names you'd like.

rmarinho commented 4 years ago

Plus one on maybe try to make the tool work for mobile and iOS. We want to make developers a delightful experience developing cross platform solutions with .NET. Since https as default is the way to go, would be great if we can make it work with a flag when generating the dev cert if we want to make it work for mobile too. Other approach is to have documentation how to get this working for iOS and Android .

0xced commented 4 years ago

@rmarinho I'll have to rebase #14228 on master then get it merged before I can continue to work on this feature. But first I'd like #19483 to be merged in order to reduce conflicts when rebasing and also to be sure that there's traction for this feature.