Create X509 Certificate for Device from a CA certificate using C#

Viewed 586

I state that I'm not very expert on the subject of certificates and I'm probably not understanding something about the certificate-chain signature.

Our Customer will send to us a CA certificate that is an Intermediate certificate and we have to create device certificates that will be stored in our devices for connection with the Device Provisioning Service where a group will be enrolled using the Intermediate certificate.

Is it possible to create a device certificate from a CA certificate using only C#? We would like to add the CA certificate (intermediate certificate) to our devices and create a certificate for the device using a software written in C#? (We can also use other kind of scripts or openssl if necessary).Is it possible?

I did some tests. I created a root and intermediate certificate using the scripts at this link https://docs.microsoft.com/it-it/azure/iot-hub/tutorial-x509-scripts and then, using the intermediate certificate, i tried this

    X509Certificate2 certificate = new X509Certificate2("myIntermediateCA.pem");
    
    ECDsa ecd = ECDsa.Create();
    CertificateRequest req = new CertificateRequest("CN=myDevice",   
    ecd,
    HashAlgorithmName.SHA256);
    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.8")
          },
           true));

    req.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
    X509Certificate2 cert2 = req.Create(
                        certificate,
                        DateTimeOffset.UtcNow.AddDays(-1),
                        DateTimeOffset.UtcNow.AddDays(2),
                        new byte[] { 1, 2, 3, 4 });
   byte[] exported = cert2.Export(X509ContentType.Pfx, "pass12345678");
   string certificatePfxPath = "myDevice.pfx";
   File.WriteAllBytes(certificatePfxPath, exported);

But it is not working. If i use myDevice.pfx to connect to the Device Provisioning Service where i have created a group that uses the intermediate certificate, i have an error saing that the device is not authorized. (The device certificate that is created with this code seems not to have a private key. But must it have it or not?)

Thanks!

1 Answers

Our Customer will send to us a CA certificate that is an Intermediate certificate and we have to create device certificates that will be stored in our devices for connection with the Device Provisioning Service where a group will be enrolled using the Intermediate certificate.

There is a fundamental problem. Customer send you only public part of CA certificate. You CAN NOT use this certificate to sign other certificates, because signing process requires private key associated with the CA certificate which most likely isn't provided by Customer.

There are two options to solve this problem:

  1. Install a subordinate CA in your environment which is internally signed by customer's CA. That is, you install the CA, generate CA request, submit to Customer for signing and receive signed CA certificate you install to your CA. Then use your local CA to sign device certificates.
  2. Ask Customer to provide certificate signing API (or other flow) which accepts PKCS#10 requests as input and return signed x.509 certificate.

Option 1 is problematic in most cases, because this allows you to issue arbitrary certificates which will be trusted by Customer. This will raise privacy and security concerns between you and Customer since you can easily spoof Customer's PKI and their security.

Option 2 requires interaction with Customer environment/API every time you need to sign the certificate. On the other hand, Customer may review every request and reject the request if they find that the request is not authorized or fail compliance/policy rules.

Is it possible to create a device certificate from a CA certificate using only C#?

In any case you SHALL NOT do this and SHALL use specialized CA software instead. For example, Microsoft ADCS, PKI Prime EJBCA, other CA vendors/software at your choice (do not your pure OpenSSL as well).

Why you need to use specialized CA software? This is because, request signing only part of CA operation. Additional operations include: proper extension generation, CRL and CA certificate distribution points (CDP and AIA extensions) definition and maintenance, CA database maintenance, revocation functions and more. Most of these tasks are defined in RFC 5280. Do not roll your own crypto/CA, because it is not very easy task even for experienced people.

Related