Create your client with a SecurityContext
with no trusted roots to force the bad certificate callback, even for a good certificate.
SecurityContext(withTrustedRoots: false);
In the bad certificate callback, parse the DER encoded certificate using the asn1lib package. For example:
ASN1Parser p = ASN1Parser(der);
ASN1Sequence signedCert = p.nextObject() as ASN1Sequence;
ASN1Sequence cert = signedCert.elements[0] as ASN1Sequence;
ASN1Sequence pubKeyElement = cert.elements[6] as ASN1Sequence;
ASN1BitString pubKeyBits = pubKeyElement.elements[1] as ASN1BitString;
List<int> encodedPubKey = pubKeyBits.stringValue;
// could stop here and compare the encoded key parts, or...
// parse them into their modulus/exponent parts, and test those
// (assumes RSA public key)
ASN1Parser rsaParser = ASN1Parser(encodedPubKey);
ASN1Sequence keySeq = rsaParser.nextObject() as ASN1Sequence;
ASN1Integer modulus = keySeq.elements[0] as ASN1Integer;
ASN1Integer exponent = keySeq.elements[1] as ASN1Integer;
print(modulus.valueAsBigInteger);
print(exponent);