Woking with BouncyCastle and trying to casting Asn1Object
to DerOctetString
DerOctetString dosCrlDP = (DerOctetString)derObjCrlDP;
Getting the casting error: "Unable to cast object of type 'Org.BouncyCastle.Asn1.DerSequence' to type 'Org.BouncyCastle.Asn1.DerOctetString'."
The full code is given below
public List<string> getCrlDistributionPoints(Org.BouncyCastle.X509.X509Certificate cert)
{
byte[] crldpExt = cert.GetExtensionValue(X509Extensions.CrlDistributionPoints.Id).GetOctets();
if ((crldpExt == null))
{
List<string> emptyList;
return emptyList;
}
Asn1InputStream oAsnInStream = null/* TODO Change to default(_) if this is not a reference type */;
Asn1InputStream oAsnInStream2 = null/* TODO Change to default(_) if this is not a reference type */;
List<string> crlUrls;
try
{
oAsnInStream = new Asn1InputStream(new MemoryStream(crldpExt));
Asn1Object derObjCrlDP = oAsnInStream.ReadObject;
//Getting the casting error.
DerOctetString dosCrlDP = (DerOctetString)derObjCrlDP;
byte[] crldpExtOctets = dosCrlDP.GetOctets;
oAsnInStream2 = new Asn1InputStream(new MemoryStream(crldpExtOctets));
Asn1Object derObj2 = oAsnInStream2.ReadObject;
CrlDistPoint distPoint = CrlDistPoint.GetInstance(derObj2);
foreach (DistributionPoint dp in distPoint.GetDistributionPoints)
{
DistributionPointName dpn = dp.DistributionPointName;
// Look for URIs in fullName
if ((!(dpn) == null))
{
if (dpn.GetType.Name == DistributionPointName.FullName)
{
GeneralName[] genNames = GeneralNames.GetInstance(dpn.Name).GetNames;
// Look for an URI
int j = 0;
while ((j < genNames.Length))
{
if ((genNames[j].TagNo == GeneralName.UniformResourceIdentifier))
{
string url = DerIA5String.GetInstance(genNames[j].Name).GetString;
crlUrls.Add(url);
}
j = (j + 1);
}
}
}
}
}
catch (IOException e)
{
throw new Exception(e.Message, e);
}
return crlUrls;
}
I have no idea how to deal with it.
Please share ideas, suggestions, and working code. or any alternatives.
Thanks in advance.
In a comment you say
Check this link and see how casting works in this java code: https://stackoverflow.com/a/46330079/18803035
The difference between that code and yours is that in the Java code there is
final byte[] crldpExt = cert.getExtensionValue(X509Extension.cRLDistributionPoints.getId());
while in your C# code you have
byte[] crldpExt = cert.GetExtensionValue(X509Extensions.CrlDistributionPoints.Id).GetOctets();
Apparently, the Java cert.getExtensionValue
returns a byte[]
while the C# cert.GetExtensionValue
returns something with a GetOctets()
method. Looking into the (open source!!) code of .NET BouncyCastle one sees that the C# version actually returns an Asn1OctetString
object of which you call that GetOctets()
method.
Thus, while the Java code first has to put the retrieved byte[]
into an ASN1InputStream
and call readObject()
to get an ...OctetString
object, the C# code already has that ...OctetString
object. Furthermore, your call of GetOctets()
retrieves the content contained in the octet string, not an encoding of that full octet string object anymore.
In the code lines quoted above, therefore, the C# code already is one step ahead of the Java code in the process of unwrapping the information. So you have to remove the extra code required for that step in Java.
In other words, as a quick fix replace
oAsnInStream = new Asn1InputStream(new MemoryStream(crldpExt));
Asn1Object derObjCrlDP = oAsnInStream.ReadObject;
//Getting the casting error.
DerOctetString dosCrlDP = (DerOctetString)derObjCrlDP;
byte[] crldpExtOctets = dosCrlDP.GetOctets;
by
byte[] crldpExtOctets = crldpExt;
Beware, I did not check whether there are similar differences in the following code, too, where you'd have to consider what you actually do.
As a side note, there not only are certain differences between the Java and the .NET version of BouncyCastle; actually there are certain breaking changes between arbitrary BouncyCastle versions even though the version numbers may differ only in the minor position. Thus, whenever re-using BouncyCastle code you find somewhere, be prepared to have to look up and compare the BouncyCastle APIs used by your source and by you unless you're using the exactly identical version.