public List<ObjectAttribute> GetAttributeValue(ObjectHandle objectHandle, List<ulong> attributes)
{
if (this._disposed)
throw new ObjectDisposedException(this.GetType().FullName);
if (objectHandle == null)
throw new ArgumentNullException("objectHandle");
if (attributes == null)
throw new ArgumentNullException("attributes");
if (attributes.Count < 1)
throw new ArgumentException("No attributes specified", "attributes");
// Prepare array of CK_ATTRIBUTEs
CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[attributes.Count];
for (int i = 0; i < attributes.Count; i++)
template[i] = CkaUtils.CreateAttribute(attributes[i]);
// Determine size of attribute values
CKR rv = _p11.C_GetAttributeValue(_sessionId, objectHandle.ObjectId, template, Convert.ToUInt64(template.Length));
if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_ATTRIBUTE_SENSITIVE) && (rv != CKR.CKR_ATTRIBUTE_TYPE_INVALID))
throw new Pkcs11Exception("C_GetAttributeValue", rv);
// Allocate memory for each attribute
for (int i = 0; i < template.Length; i++)
{
// PKCS#11 v2.20 page 133:
// If the specified attribute (i.e., the attribute specified by the type field) for the object
// cannot be revealed because the object is sensitive or unextractable, then the
// ulValueLen field in that triple is modified to hold the value -1 (i.e., when it is cast to a
// CK_LONG, it holds -1).
if ((long)template[i].valueLen != -1)
template[i].value = Common.UnmanagedMemory.Allocate(Convert.ToInt32(template[i].valueLen));
}
// Read values of attributes
rv = _p11.C_GetAttributeValue(_sessionId, objectHandle.ObjectId, template, Convert.ToUInt64(template.Length));
if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_ATTRIBUTE_SENSITIVE) && (rv != CKR.CKR_ATTRIBUTE_TYPE_INVALID))
throw new Pkcs11Exception("C_GetAttributeValue", rv);
// Convert CK_ATTRIBUTEs to ObjectAttributes
List<ObjectAttribute> outAttributes = new List<ObjectAttribute>();
for (int i = 0; i < template.Length; i++)
outAttributes.Add(new ObjectAttribute(template[i]));
return outAttributes;
}