Skip to content

Conversation

@avparuch
Copy link
Contributor

@avparuch avparuch commented May 18, 2021

The typo was bothering me :)

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

PR Title
Summary of the changes (Less than 80 chars)

PR Description
Detail 1
Detail 2

Addresses #bugnumber (in this specific format)

The typo was bothering me :)
@ghost ghost added area-runtime community-contribution Indicates that the PR has been added by a community member labels May 18, 2021
@avparuch avparuch closed this May 18, 2021
@avparuch avparuch reopened this May 18, 2021
@Tratcher
Copy link
Member

@HaoK selfSignedNoEkuCertificateNotValidYet un-expired.

@HaoK
Copy link
Member

HaoK commented May 18, 2021

Yeah I noticed that in my PR too, @blowdart did you pick 5/17/2021 for your 'future' cert expiration date? :)

@blowdart
Copy link
Contributor

Well, it was two years from creation. You can run the powershell script and just regenerate.

@HaoK
Copy link
Member

HaoK commented May 18, 2021

Can I add like 50 years, so this won't happen again in a timeframe we care about? :)

@blowdart
Copy link
Contributor

Edit the script. I did it for 5 years a while back, but probably after you ran it.

10 years seems reasonable, 50 not so much

@blowdart
Copy link
Contributor

More seriously I'm sure @bartonjs can give you samples of creating the certs during runtime for tests so you don't need the test files any more

@HaoK
Copy link
Member

HaoK commented May 18, 2021

Fair enough, I'll file an issue to clean that up at some point, probably during an MQ

@Tratcher Tratcher self-assigned this May 18, 2021
@bartonjs
Copy link
Member

That was a nice diversion.

This makes ephemeral-key certificates, they can't be used with SslStream (or anything that uses SslStream, like HttpClient) on Windows (see below).

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace Namespace
{
    internal static class IDunnoCerts
    {
        private static readonly X509KeyUsageExtension s_digitalSignatureOnlyUsage =
               new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, true);

        internal static void GenerateCerts(
            out X509Certificate2 validSelfSignedClientEkuCertificate,
            out X509Certificate2 validSelfSignedServerEkuCertificate,
            out X509Certificate2 validSelfSignedNoEkuCertificate,
            out X509Certificate2 selfSignedNoEkuCertificateExpired,
            out X509Certificate2 selfSignedNoEkuCertificateNotValidYet)
        {
            DateTimeOffset now = DateTimeOffset.UtcNow;
            
            validSelfSignedClientEkuCertificate = MakeCert(
                "CN=Valid Self Signed Client EKU,OU=dev,DC=idunno-dev,DC=org",
                "1.3.6.1.5.5.7.3.2",
                now);

            validSelfSignedServerEkuCertificate = MakeCert(
                "CN=Valid Self Signed Server EKU,OU=dev,DC=idunno-dev,DC=org",
                "1.3.6.1.5.5.7.3.1",
                now);

            validSelfSignedNoEkuCertificate = MakeCert(
                "CN=Valid Self Signed No EKU,OU=dev,DC=idunno-dev,DC=org",
                eku: null,
                now);

            selfSignedNoEkuCertificateExpired = MakeCert(
                "CN=Expired Self Signed,OU=dev,DC=idunno-dev,DC=org",
                eku: null,
                now.AddYears(-1),
                now.AddDays(-1));

            selfSignedNoEkuCertificateNotValidYet = MakeCert(
                "CN=Not Valid Yet Self Signed,OU=dev,DC=idunno-dev,DC=org",
                eku: null,
                now.AddYears(2),
                now.AddYears(3));
        }

        private static X509Certificate2 MakeCert(
            string subjectName,
            string eku,
            DateTimeOffset now)
        {
            return MakeCert(subjectName, eku, now, now.AddYears(5));
        }

        private static X509Certificate2 MakeCert(
            string subjectName,
            string eku,
            DateTimeOffset notBefore,
            DateTimeOffset notAfter)
        {
            using (RSA key = RSA.Create(2048))
            {
                CertificateRequest request = new CertificateRequest(
                    subjectName,
                    key,
                    HashAlgorithmName.SHA256,
                    RSASignaturePadding.Pkcs1);

                request.CertificateExtensions.Add(s_digitalSignatureOnlyUsage);

                if (eku != null)
                {
                    request.CertificateExtensions.Add(
                        new X509EnhancedKeyUsageExtension(
                            new OidCollection { new Oid(eku, null) }, false));
                }

                return request.CreateSelfSigned(notBefore, notAfter);
            }
        }
    }
}

On Windows you'll need to have a persisted private key to use SslStream (because S/Channel requires it), and the way to go about that is new X509Certificate2(cert.Export(X509ContentType.Pkcs12)). When this certificate object gets disposed/collected it'll clean up the temporary keyfile. You can run this code on all OSes if you want, it doesn't hurt functionality... just perf.

That's easier than creating the keys as persisted to begin with, since that's a Windows-only concept.

@HaoK
Copy link
Member

HaoK commented May 18, 2021

Thanks I copied the info into #32813

@Tratcher
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@Tratcher Tratcher enabled auto-merge (squash) May 18, 2021 23:13
@Tratcher
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@Tratcher Tratcher merged commit 1a55677 into dotnet:main May 19, 2021
@ghost ghost added this to the 6.0-preview5 milestone May 19, 2021
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Jun 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants