0

I am issuing (with own Certificate Authority) a certificate in c# code (based on: .NET Core 2.0 CertificateRequest class)

In CertificateRequest, unable to add Certificate ocsp Authority Information Access (oid: 1.3.6.1.5.5.7.1.1) and certificate policies (oid: 2.5.29.32) extensions (similar results of: Authority Information Access extension)

I do not want to use external libraries, perhaps only ASN1 libraries if needed.

Anyone can help with c# code to add these extensions as I didn't find any suitable types in .Net?

certificateRequestObject.CertificateExtensions.Add(
                  new X509Extension("2.5.29.32", **[Authority Information Access text] to RawData?** , false));

[Authority Information Access text]

Authority Information Access   1.3.6.1.5.5.7.1.1
[1]Authority Info Access
     Access Method=On-line Certificate Status Protocol (1.3.6.1.5.5.7.48.1)
     Alternative Name:
          URL=example.org
[2]Authority Info Access
     Access Method=Certification Authority Issuer (1.3.6.1.5.5.7.48.2)
     Alternative Name:
          URL=example.org
Guru_07
  • 362
  • 3
  • 15
  • What option do you need? There are a lot of different options for RSA like padding and TLS 1.2 vs TLS 1.3 ( See https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations). And Net moving from 32 bit to 64 bit.The new version of Net added X509Certificate2. The defaults for Net are for TLS 1.3 and X509Certificate2 is need to still use TLS 1.2 with the new Net. I do not know all the options and answer you may have. Just know recently I seen a lot of issues with OPs using new version of Net and older code not working. – jdweng Oct 29 '19 at 14:51
  • This is somewhat incorrect usage. Authority Information Access extension population is CA responsibility, not client. You need to configure CA to include the right URL in extension. Clients shall not control which URLs are included in AIA/CDP extensions. – Crypt32 Oct 29 '19 at 15:45
  • @Crypt32: yes, its for CA to include the right URL while issuing a certificate. SubjectAlternativeNameBuilder is available but could not figure out how to add Authority Information Access and Certificate extensions – Guru_07 Oct 29 '19 at 15:51
  • Did you read my comment? AIA extension population in issued certificates is CA responsibility, not client. You shall not include AIA extension in request. Moreover, CAs ignore this extension from requests and use their configuration to insert AIA extension. – Crypt32 Oct 29 '19 at 15:54
  • @Crypt32: As mentioned in the question, as own CA, I am issuing a client certificate and no other CA here. In such cases as a CA, I need to insert AIA extension myself and the question is how. If I am submitting a request to any other CA, I agree with you, they need to insert AIA extension and issue it. – Guru_07 Oct 29 '19 at 15:59

2 Answers2

2

Disclaimer: I do strongly believe that you should not roll own crypto/CA and use standard CA software to issue certificate since they are intended to solve this problem.


There is no built-in support for ASN encoding/decoding in .NET (including .NET Core), you have to use 3rd party libraries.

For ASN encoding you can use ASN.1 library I developed: Asn1DerParser.NET

And use for your particular case will be:

Byte[] encodedData = new Asn1Builder()
    .AddSequence(x => x.AddObjectIdentifier(new Oid("1.3.6.1.5.5.7.48.1")
        .AddImplicit(6, Encoding.ASCII.GetBytes("http://ocsp.example.com"), true))
    .GetEncoded();
var extension = new X509Extension("1.3.6.1.5.5.7.1.1", encodedData, false);

and add extension item to your request. If you need to add more URLs, then add more SEQUENCE elements:

Byte[] encodedData = new Asn1Builder()
    .AddSequence(x => x.AddObjectIdentifier(new Oid("1.3.6.1.5.5.7.48.1")
        .AddImplicit(6, Encoding.ASCII.GetBytes("http://ocsp1.example.com"), true))
    .AddSequence(x => x.AddObjectIdentifier(new Oid("1.3.6.1.5.5.7.48.1")
        .AddImplicit(6, Encoding.ASCII.GetBytes("http://ocsp2.example.com"), true))
    .GetEncoded();
var extension = new X509Extension("1.3.6.1.5.5.7.1.1", encodedData, false);
Crypt32
  • 12,850
  • 2
  • 41
  • 70
  • Crypt32, are you aware of a way to add an AIA extension and OCSP url property using the `New-SelfSignedCertificate` Powershell cmdlet and its `TextExtension` parameter? I can't quite make the translation as C# is not familiar to me. – ericOnline Mar 17 '21 at 23:45
  • @ericOnline, sorry, I don't have an example – Crypt32 Mar 18 '21 at 15:14
1

I needed to add an AIA (Authority Information Access) extension using dotnet also. It is super cool @Crypt32 shared the code from Asn1DerParser.NET. It made me curious. I started looking at other code like BouncyCastle and I didn't see any code that did the same thing. There is a AuthorityInformationAccess class, but I couldn't find any tests that created an AIA extension. Maybe the implementation isn't finished. I could dig further but I instead looked at the dotnet runtime code. While of course there isn't a dotnet AIA builder, there is a SubjectAlternativeNameBuilder]2 I could learn from. So, I did just that. Essensually it uses the AsnWriter to encapsulate the mechanics of building an ASN1 Sequence. Below is an example where I add two certificate authority issuers. Next steps would be to encapuslate this in an AIA Builder but here is an example.

The parts that I struggled with were ensuring when to call writer.Encode and writer.WriteEncodedValue. After an hour or so everything made sense.

@Guru_07, I believe this allows you to avoid third party code. Although it has been some time since you posted your question.

List<byte[]> encodedUrls = new List<byte[]>();
List<byte[]> encodedSequences = new List<byte[]>();

AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

writer.WriteObjectIdentifier("1.3.6.1.5.5.7.48.2");
encodedUrls.Add(writer.Encode());

writer = new AsnWriter(AsnEncodingRules.DER);
writer.WriteCharacterString(
    UniversalTagNumber.IA5String, 
    "http://ocsp.example.com", 
    new Asn1Tag(TagClass.ContextSpecific, 6)
);

encodedUrls.Add(writer.Encode());

writer = new AsnWriter(AsnEncodingRules.DER);
using (writer.PushSequence())
{
    foreach (byte[] encodedName in encodedUrls)
    {
        writer.WriteEncodedValue(encodedName);
    }
}
encodedSequences.Add(writer.Encode());

encodedUrls = new List<byte[]>();
writer = new AsnWriter(AsnEncodingRules.DER);
writer.WriteObjectIdentifier("1.3.6.1.5.5.7.48.2");
encodedUrls.Add(writer.Encode());

writer = new AsnWriter(AsnEncodingRules.DER);
writer.WriteCharacterString(
    UniversalTagNumber.IA5String, 
    "http://ocsp2.example.com", 
    new Asn1Tag(TagClass.ContextSpecific, 6)
);

encodedUrls.Add(writer.Encode());

writer = new AsnWriter(AsnEncodingRules.DER);
using (writer.PushSequence())
{
    foreach (byte[] encodedName in encodedUrls)
    {
        writer.WriteEncodedValue(encodedName);
    }
}
encodedSequences.Add(writer.Encode());


writer = new AsnWriter(AsnEncodingRules.DER);
using (writer.PushSequence())
{
    foreach (byte[] encodedSequence in encodedSequences)
    {
        writer.WriteEncodedValue(encodedSequence);
    }
}

var ext = new X509Extension(
    new Oid("1.3.6.1.5.5.7.1.1"),
    writer.Encode(),
    false);