I've just came across the same issue in C#, trying to generate certificates with CDPs (CRL Distribution Points) extension through CertEnroll.dll
The only way I could make this work was by handcrafting the extension at byte level, though I didn't find any documentation about how the bytes should be ordered or the meaning of some bytes. To figure it out I generated some certs using OpenSSL in Linux and inspected the raw bytes in C# (load the certificate in X509Certificate2 class and take a look at the Extensions
property. The X509Extension class has a RawData
property).
You should be able to convert my code to PowerShell, so I ended up with:
var urisStr = new string[]
{
"http://pki.example.com/list.crl"
};
var uris = urisStr.Select(u => Encoding.UTF8.GetBytes(u));
var zero = new byte[] { 48 }; //"0", delimiter ?
var nbsp = new byte[] { 160 }; //" ", separator ?
var dagger = new byte[] { 134 }; //"dagger", separator ?
var zeroSize = zero.Length + 1;
var nbspSize = nbsp.Length + 1;
var daggerSize = dagger.Length + 1;
var col = new List<byte>();
col.AddRange(zero); //delimiter
int totalBytes = uris.Sum(u => u.Length);
totalBytes += (zeroSize + (nbspSize * 2) + daggerSize) * uris.Count();
col.Add((byte)totalBytes); //size of everything it contains
foreach (var uri in uris)
{
var uriSize = uri.Length;
col.AddRange(zero); //delimiter
col.Add((byte)(nbspSize + nbspSize + uriSize + daggerSize)); //size of everything it contains
col.AddRange(nbsp);
col.Add((byte)(nbspSize + uriSize + daggerSize)); //size of everything it contains
col.AddRange(nbsp);
col.Add((byte)(uriSize + daggerSize)); //size of everything it contains
col.AddRange(dagger); //separator ?
col.Add((byte)uriSize);
col.AddRange(uri);
}
var bytes = col.ToArray();
var base64 = Convert.ToBase64String(bytes);
var oidCDP = new CObjectId();
oidCDP.InitializeFromName(CERTENROLL_OBJECTID.XCN_OID_CRL_DIST_POINTS);
// There is no specific class to CDPs, so we use the CX509Extension
var crlList = new CX509Extension();
crlList.Initialize(oidCDP, EncodingType.XCN_CRYPT_STRING_BASE64, base64);
certRequest.X509Extensions.Add(crlList);
Please note that I didn't found any documentation about the format of the bytes that I'm generating, so this code has no official basis. It's based only on observations of working certificates.