3

Someone provided me with a intermediate certificate (signed by a root cert) and its password. In order to connect securely to an SSL enpoint I need to provide a signed certificate.

Here is what I do:

  1. Create a private key
  2. Create a CSR with that private key
  3. Sign it using the provided Intermediate certificate

I used openssl for all this and it worked flawlessly: The TLS endpoint accepted my conection request. In C# though it does not work. Any idea what is missing?

        var password = new SecureString();
        password.AppendChar('x');
        password.AppendChar('y');
        password.AppendChar('z');

        // Intermediate certificate with pw protection
        X509Certificate2 intermediateCert = new X509Certificate2("intermediate.pfx", password);
        X509Certificate2 certificate;

       using (RSA rsa = RSA.Create(2048))
        {

            //A client creates a certificate signing request.
            CertificateRequest req = new CertificateRequest(
                    new X500DistinguishedName("CN=myname"),
                    rsa,
                    HashAlgorithmName.SHA256,
                    RSASignaturePadding.Pkcs1);

            req.CertificateExtensions.Add(
                new X509BasicConstraintsExtension(false, false, 0, false));

            req.CertificateExtensions.Add(
                new X509KeyUsageExtension(
                    X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment,
                    false));

            req.CertificateExtensions.Add(
                new X509EnhancedKeyUsageExtension(
                    new OidCollection
                    {
                        new Oid("1.3.6.1.5.5.7.3.**1**")
                    },
                    true));

            req.CertificateExtensions.Add(
                new X509SubjectKeyIdentifierExtension(req.PublicKey, false));


            X500DistinguishedName dname = new X500DistinguishedName(intermediateCert.Subject);
            X509SignatureGenerator gen = X509SignatureGenerator.CreateForRSA((RSA)intermediateCert.PrivateKey, RSASignaturePadding.Pkcs1);

            certificate = req.Create(
                dname, gen,
                DateTimeOffset.UtcNow.AddDays(-1),
                DateTimeOffset.UtcNow.AddDays(10),
                new byte[] {1, 2, 3, 4});

          // Use certificate to connect to Azure IOT HUB
        }

edit: The named endpoint in this case is Azure IoT Hub. The error message is:

AmqpException: {"errorCode":401002,"trackingId":"e930cb7c-d1a5-4ad0-bb5d-e9b4ee97e8b2","message":"IotHubUnauthorizedAccess","timestampUtc":"2018-10-12T18:08:23.2328669Z"}

edit: Working certificate

X509v3 extensions:
    X509v3 Basic Constraints:
        CA:FALSE
    Netscape Cert Type:
        SSL Server
    Netscape Comment:
        OpenSSL Generated Server Certificate
    X509v3 Subject Key Identifier:
        9E:86:FF:19:70:DB:5D:56:2D:16:48:E3:81:76:66:FD:17:C8:82:9A
    X509v3 Authority Key Identifier:
        keyid:E0:31:C5:81:6F:75:6A:AC:9C:F1:B1:B8:72:B7:E3:C6:AB:4C:E9:89
        DirName:/CN=abuscert
        serial:01

    X509v3 Key Usage: critical
        Digital Signature, Key Encipherment
    X509v3 Extended Key Usage:
        TLS Web Server Authentication

The one created with C#:

X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, Time Stamping
            X509v3 Subject Key Identifier:
                00:5E:F2:48:5C:E4:CA:B5:F3:5F:A6:0E:62:7C:FF:61:87:B1:D5:89
binaryguy
  • 1,167
  • 3
  • 12
  • 29
  • Can you describe more about "doesn't work"? It gives an exception? The certificate is generated, but is invalid somehow (how is it invalid?) – vcsjones Oct 12 '18 at 18:06
  • updated my answer. FYI I used the same intermediate certificate to create a signed certificate using openssl so it is NOT an Azure IoT Hub endpoint issue. – binaryguy Oct 12 '18 at 18:09
  • The OID you used for EKU "1.3.6.1.5.5.7.3.8". Did you intentionally want to create a timestamping certificate (seems odd). If you compare the certificate from the working openssl cert and the output from this, what's different? Also, typically the EKU extension is not marked as critical (the last parameter in the constructor for `X509EnhancedKeyUsageExtension` should be false). Conversely, the `BasicConstraints` constraint _should_ be critical, so set that one to true. – vcsjones Oct 12 '18 at 18:17
  • yes the extensions of both certificates are different; see the edit – binaryguy Oct 12 '18 at 18:25
  • The EKU and basic constraints seem suspect to me (I doubt the netscape extensions matter). – vcsjones Oct 12 '18 at 18:32
  • 1. X509v3 Authority Key Identifier is missing completly. What is this? 2. How to get rid of EKU Time Stamping? – binaryguy Oct 12 '18 at 18:51
  • OK removed the Timestamping EKU – binaryguy Oct 12 '18 at 18:57

0 Answers0