Attribute Certificates
An attribute certificate is a structure similar to a public key certificate, with the difference that the attribute certificate does not contain a key. An attribute certificate can contain attributes that specify group membership, roles, security clearances or other authorization information associated with the certificate holder.
The PKI SDK is capable of decoding and validating attribute certificates through the class AttributeCertificate, as well as issuing attribute certificates, with the class AttributeCertificateGenerator.
Class hierarchy
Because an attribute certificate is similar to a public key certificate, classes that represent such structures in the SDK are related, having a common ancestor:
Note
The diagram above is incomplete, showing just some of the properties and methods of each class
Note that some properties present in the PKCertificate class are actually from the class Certificate, common ancestor with the class AttributeCertificate. Therefore, many of the operations that are possible with public key certificates work the same way for attribute certificates, especially the property Issuer and the method Validate(ITrustArbitrator).
The holder information, however, is not in the ancestral class, but in the child classes. That's because, in the case of public key certificates, the holder (subject) is a Name, whereas in attribute certificates the holder can be a GeneralNames or or even a public key certificate. These two values possible are accessible by properties HolderName and HolderPKCertificate. The property SubjectDisplayName it is a mere visual aid to treat public key and attribute certificates as a common entity, but this is just one aspect in which they differ.
Decoding and validating attribute certificates
Because of the common hierarchy with the class PKCertificate, the decryption and validation operations for attribute certificates are very similar to the same operations with public key certificates:
byte[] acContent = ...;
AttributeCertificate ac = AttributeCertificate.Decode(acContent);
ValidationResults vr = ac.Validate(TrustArbitrators.Windows);
if (!vr.IsValid) {
// ...
}
Decoding attributes
An additional difficulty in handling attribute certificates is to decode the attributes contained in the certificate, whose coding is often proprietary. The class Asn1Util provides methods for encoding and decode ASN.1 objects, which is the encoding generally used for attributes.
To use the encoding and decoding methods, it is necessary to make classes that represent the structures that if you want to encode and decode and denote with attributes the ASN.1 syntax of the structures, as below:
// MembershipIdAttribute ::= SEQUENCE {
// memberId INTEGER,
// memberNickname UTF8String
// }
[Asn1Sequence]
public class MembershipIdAttribute {
[Asn1SequenceElement(0, Asn1PrimitiveTypes.Integer)]
public int MemberId { get; set; }
[Asn1SequenceElement(1, Asn1PrimitiveTypes.UTF8String)]
public string MemberNickname { get; set; }
}
public class Program {
public static void Main(string[] args) {
MembershipIdAttribute memberAttribute = new MembershipIdAttribute() {
MemberId = 12345,
MemberNickname = "Mr. Bison"
};
// Encode in DER
byte[] encodedAttribute = Asn1Util.DerEncode(memberAttribute);
// Decode from DER/BER
MembershipIdAttribute decodedAttribute = Asn1Util.DecodeAs<MembershipIdAttribute>(encodedAttribute);
}
}
Once the classes represent the attributes and are decorated with the ASN.1 syntax indications, it is possible to obtain the attributes as follows:
byte[] acContent = ...;
// We decode the certificate
AttributeCertificate ac = AttributeCertificate.Decode(acContent);
// We look for an attribute by its OID
X509Attribute attributeObj = ac.Attributes["1.2.3.4"];
// There can be multiple values for the same OID, let's say that in this case we are only interested in the first value
byte[] encodedAttribute = attributeObj.EncodedValues[0];
// We decode the attribute
MembershipIdAttribute memberAttribute = Asn1Util.DecodeAs<MembershipIdAttribute>(encodedAttribute);
The method GetAndDecodeValueAs<T>(String, Boolean) allows you to search for an attribute and decode its first value directly:
byte[] acContent = ...;
// We decode the certificate
AttributeCertificate ac = AttributeCertificate.Decode(acContent);
// We search and decode the first value of an attribute by its OID
MembershipIdAttribute memberAttribute = ac.Attributes.GetAndDecodeValueAs<MembershipIdAttribute>("1.2.3.4");