The X509Certificate
class represents a Public Key Certificate (PKC), while an Attribute Certificate (AC), although it's a similar (but not that much) structure, has no public key. And they're not the same thing.
A X509Certificate
can't be used without a public key, because the key is part of it. If you take a look at the RFC's definition, you'll see it's a mandatory field:
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING }
TBSCertificate ::= SEQUENCE {
... lots of fields...
subjectPublicKeyInfo SubjectPublicKeyInfo,
... }
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
The public key is also part of the definition of a PKC: something that binds an identity and a public key, as stated in the RFC:
...public key certificates, which are data structures that bind
public key values to subjects
Attribute Certificates are defined in this RFC, which tells the differences from a PKC:
Some people constantly confuse PKCs and ACs. An analogy may make
the distinction clear. A PKC can be considered to be like a
passport: it identifies the holder, tends to last for a long time,
and should not be trivial to obtain. An AC is more like an entry
visa: it is typically issued by a different authority and does not
last for as long a time. As acquiring an entry visa typically
requires presenting a passport, getting a visa can be a simpler
process.
In the same page, you can see that AC's structure is very different from a PKC, so an AC's implementation shouldn't inherit from X509Certificate
. Although there are some similar fields, I don't think they're close enough to justify inheritance (and they also have different purposes and uses, which makes me discard inheritance at all).
The best approach in your case: I'd recommend using an existing implementation. BouncyCastle is one of them. If you can't use an external lib, you can use BouncyCastle's code as a reference.