Exemple #1
0
 /// <summary>
 /// Creates attribute of given type with ulong array value
 /// </summary>
 /// <param name="type">Attribute type</param>
 /// <param name="value">Attribute value</param>
 /// <returns>Attribute of given type with ulong array value</returns>
 public static CK_ATTRIBUTE CreateAttribute(ulong type, ulong[] value)
 {
     CK_ATTRIBUTE attribute = new CK_ATTRIBUTE();
     attribute.type = type;
     if ((value != null) && (value.Length > 0))
     {
         int ckmSize = UnmanagedMemory.SizeOf(typeof(ulong));
         attribute.value = UnmanagedMemory.Allocate(ckmSize * value.Length);
         for (int i = 0; i < value.Length; i++)
         {
             IntPtr tempPointer = new IntPtr(attribute.value.ToInt64() + (i * ckmSize));
             UnmanagedMemory.Write(tempPointer, ConvertUtils.ULongToBytes(value[i]));
         }
         attribute.valueLen = Convert.ToUInt64(ckmSize * value.Length);
     }
     else
     {
         attribute.value = IntPtr.Zero;
         attribute.valueLen = 0;
     }
     
     return attribute;
 }
Exemple #2
0
 /// <summary>
 /// Reads value of attribute and returns it as byte array
 /// </summary>
 /// <param name="attribute">Attribute whose value should be read</param>
 /// <param name="value">Location that receives attribute value</param>
 public static void ConvertValue(ref CK_ATTRIBUTE attribute, out byte[] value)
 {
     value = ConvertValue(ref attribute);
 }
Exemple #3
0
 /// <summary>
 /// Creates attribute of given type with attribute array value
 /// </summary>
 /// <param name="type">Attribute type</param>
 /// <param name="value">Attribute value</param>
 /// <returns>Attribute of given type with attribute array value</returns>
 public static CK_ATTRIBUTE CreateAttribute(CKA type, CK_ATTRIBUTE[] value)
 {
     return CreateAttribute(Convert.ToUInt64((uint)type), value);
 }
Exemple #4
0
        /// <summary>
        /// Searches for all token and session objects that match provided attributes
        /// </summary>
        /// <param name="attributes">Attributes that should be matched</param>
        /// <returns>Handles of found objects</returns>
        public List<ObjectHandle> FindAllObjects(List<ObjectAttribute> attributes)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            List<ObjectHandle> foundObjects = new List<ObjectHandle>();

            CK_ATTRIBUTE[] template = null;
            ulong templateLength = 0;
            
            if (attributes != null)
            {
                templateLength = Convert.ToUInt64(attributes.Count);
                template = new CK_ATTRIBUTE[templateLength];
                for (int i = 0; i < Convert.ToInt32(templateLength); i++)
                    template[i] = attributes[i].CkAttribute;
            }

            CKR rv = _p11.C_FindObjectsInit(_sessionId, template, templateLength);
            if (rv != CKR.CKR_OK)
                throw new Pkcs11Exception("C_FindObjectsInit", rv);

            ulong objectsLength = 256;
            ulong[] objects = new ulong[objectsLength];
            ulong objectCount = objectsLength;
            while (objectCount == objectsLength)
            {
                rv = _p11.C_FindObjects(_sessionId, objects, objectsLength, ref objectCount);
                if (rv != CKR.CKR_OK)
                    throw new Pkcs11Exception("C_FindObjects", rv);

                for (int i = 0; i < Convert.ToInt32(objectCount); i++)
                    foundObjects.Add(new ObjectHandle(objects[i]));
            }

            rv = _p11.C_FindObjectsFinal(_sessionId);
            if (rv != CKR.CKR_OK)
                throw new Pkcs11Exception("C_FindObjectsFinal", rv);

            return foundObjects;
        }
Exemple #5
0
 /// <summary>
 /// Reads value of attribute and returns it as bool
 /// </summary>
 /// <param name="attribute">Attribute whose value should be read</param>
 /// <param name="value">Location that receives attribute value</param>
 public static void ConvertValue(ref CK_ATTRIBUTE attribute, out bool value)
 {
     byte[] bytes = ConvertValue(ref attribute);
     value = ConvertUtils.BytesToBool(bytes);
 }
Exemple #6
0
 /// <summary>
 /// Reads value of attribute and returns it as bool
 /// </summary>
 /// <param name="attribute">Attribute whose value should be read</param>
 /// <param name="value">Location that receives attribute value</param>
 public static void ConvertValue(ref CK_ATTRIBUTE attribute, out bool value)
 {
     byte[] bytes = ConvertValue(ref attribute);
     value = ConvertUtils.BytesToBool(bytes);
 }
Exemple #7
0
        /// <summary>
        /// Modifies the value of one or more attributes of an object
        /// </summary>
        /// <param name="objectHandle">Handle of object whose attributes should be modified</param>
        /// <param name="attributes">List of attributes that should be modified</param>
        public void SetAttributeValue(ObjectHandle objectHandle, List<ObjectAttribute> 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");

            CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[attributes.Count];
            for (int i = 0; i < attributes.Count; i++)
                template[i] = attributes[i].CkAttribute;

            CKR rv = _p11.C_SetAttributeValue(_sessionId, objectHandle.ObjectId, template, Convert.ToUInt64(template.Length));
            if (rv != CKR.CKR_OK)
                throw new Pkcs11Exception("C_SetAttributeValue", rv);
        }
        /// <summary>
        /// Initializes a search for token and session objects that match a template
        /// </summary>
        /// <param name="session">The session's handle</param>
        /// <param name="template">Search template that specifies the attribute values to match</param>
        /// <param name="count">The number of attributes in the search template</param>
        /// <returns>CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_VALUE_INVALID, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK, CKR_OPERATION_ACTIVE, CKR_PIN_EXPIRED, CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID</returns>
        public CKR C_FindObjectsInit(ulong session, CK_ATTRIBUTE[] template, ulong count)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            ulong rv = _delegates.C_FindObjectsInit(session, template, count);
            return (CKR)Convert.ToUInt32(rv);
        }
        public void _01_GetAttributeValueTest()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0)
                Assert.Inconclusive("Test cannot be executed on this platform");

            CKR rv = CKR.CKR_OK;
            
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath))
            {
                rv = pkcs11.C_Initialize(Settings.InitArgs80);
                if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED))
                    Assert.Fail(rv.ToString());
                
                // Find first slot with token present
                ulong slotId = Helpers.GetUsableSlot(pkcs11);
                
                ulong session = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Login as normal user
                rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Create object
                ulong objectId = CK.CK_INVALID_HANDLE;
                rv = Helpers.CreateDataObject(pkcs11, session, ref objectId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Prepare list of empty attributes we want to read
                CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[2];
                template[0] = CkaUtils.CreateAttribute(CKA.CKA_LABEL);
                template[1] = CkaUtils.CreateAttribute(CKA.CKA_VALUE);

                // Get size of each individual attribute value in first call
                rv = pkcs11.C_GetAttributeValue(session, objectId, template, Convert.ToUInt64(template.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // In LowLevelAPI we have to allocate unmanaged memory for attribute value
                for (int i = 0; i < template.Length; i++)
                    template[i].value = UnmanagedMemory.Allocate(Convert.ToInt32(template[i].valueLen));

                // Get attribute value in second call
                rv = pkcs11.C_GetAttributeValue(session, objectId, template, Convert.ToUInt64(template.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Do something interesting with attribute value
                byte[] ckaLabel = UnmanagedMemory.Read(template[0].value, Convert.ToInt32(template[0].valueLen));
                Assert.IsTrue(Convert.ToBase64String(ckaLabel) == Convert.ToBase64String(Settings.ApplicationNameArray));

                // In LowLevelAPI we have to free unmanaged memory taken by attributes
                for (int i = 0; i < template.Length; i++)
                {
                    UnmanagedMemory.Free(ref template[i].value);
                    template[i].valueLen = 0;
                }

                rv = pkcs11.C_DestroyObject(session, objectId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_Logout(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_CloseSession(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_Finalize(IntPtr.Zero);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
            }
        }
Exemple #10
0
        /// <summary>
        /// Copies an object, creating a new object for the copy
        /// </summary>
        /// <param name="session">The session's handle</param>
        /// <param name="objectId">The object's handle</param>
        /// <param name="template">Template for the new object</param>
        /// <param name="count">The number of attributes in the template</param>
        /// <param name="newObjectId">Location that receives the handle for the copy of the object</param>
        /// <returns>CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_VALUE_INVALID, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OBJECT_HANDLE_INVALID, CKR_OK, CKR_PIN_EXPIRED, CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY, CKR_TEMPLATE_INCONSISTENT, CKR_TOKEN_WRITE_PROTECTED, CKR_USER_NOT_LOGGED_IN</returns>
        public CKR C_CopyObject(ulong session, ulong objectId, CK_ATTRIBUTE[] template, ulong count, ref ulong newObjectId)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            ulong rv = _delegates.C_CopyObject(session, objectId, template, count, ref newObjectId);
            return (CKR)Convert.ToUInt32(rv);
        }
Exemple #11
0
        /// <summary>
        /// Modifies the value of one or more attributes of an object
        /// </summary>
        /// <param name="session">The session's handle</param>
        /// <param name="objectId">The object's handle</param>
        /// <param name="template">Template that specifies which attribute values are to be modified and their new values</param>
        /// <param name="count">The number of attributes in the template</param>
        /// <returns>CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_VALUE_INVALID, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OBJECT_HANDLE_INVALID, CKR_OK, CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY, CKR_TEMPLATE_INCONSISTENT, CKR_TOKEN_WRITE_PROTECTED, CKR_USER_NOT_LOGGED_IN</returns>
        public CKR C_SetAttributeValue(ulong session, ulong objectId, CK_ATTRIBUTE[] template, ulong count)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            ulong rv = _delegates.C_SetAttributeValue(session, objectId, template, count);
            return (CKR)Convert.ToUInt32(rv);
        }
Exemple #12
0
        /// <summary>
        /// Derives a key from a base key, creating a new key object
        /// </summary>
        /// <param name="session">The session's handle</param>
        /// <param name="mechanism">Key derivation mechanism</param>
        /// <param name="baseKey">The handle of the base key</param>
        /// <param name="template">The template for the new key</param>
        /// <param name="attributeCount">The number of attributes in the template</param>
        /// <param name="key">Location that receives the handle of the derived key</param>
        /// <returns>CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_VALUE_INVALID, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_DOMAIN_PARAMS_INVALID, CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_KEY_HANDLE_INVALID, CKR_KEY_SIZE_RANGE, CKR_KEY_TYPE_INCONSISTENT, CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID, CKR_OK, CKR_OPERATION_ACTIVE, CKR_PIN_EXPIRED, CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY, CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT, CKR_TOKEN_WRITE_PROTECTED, CKR_USER_NOT_LOGGED_IN</returns>
        public CKR C_DeriveKey(ulong session, ref CK_MECHANISM mechanism, ulong baseKey, CK_ATTRIBUTE[] template, ulong attributeCount, ref ulong key)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            ulong rv = _delegates.C_DeriveKey(session, ref mechanism, baseKey, template, attributeCount, ref key);
            return (CKR)Convert.ToUInt32(rv);
        }
Exemple #13
0
 /// <summary>
 /// Reads value of attribute and returns it as byte array
 /// </summary>
 /// <param name="attribute">Attribute whose value should be read</param>
 /// <param name="value">Location that receives attribute value</param>
 public static void ConvertValue(ref CK_ATTRIBUTE attribute, out byte[] value)
 {
     value = ConvertValue(ref attribute);
 }
Exemple #14
0
 /// <summary>
 /// Reads value of attribute and returns it as string
 /// </summary>
 /// <param name="attribute">Attribute whose value should be read</param>
 /// <param name="value">Location that receives attribute value</param>
 public static void ConvertValue(ref CK_ATTRIBUTE attribute, out string value)
 {
     byte[] bytes = ConvertValue(ref attribute);
     value = ConvertUtils.BytesToUtf8String(bytes);
 }
Exemple #15
0
        /// <summary>
        /// Reads value of attribute and returns it as mechanism array
        /// </summary>
        /// <param name="attribute">Attribute whose value should be read</param>
        /// <param name="value">Location that receives attribute value</param>
        public static void ConvertValue(ref CK_ATTRIBUTE attribute, out CKM[] value)
        {
            ulong[] ulongArray = null;
            ConvertValue(ref attribute, out ulongArray);

            CKM[] ckmArray = null;
            if (ulongArray != null)
            {
                ckmArray = new CKM[ulongArray.Length];
                for (int i = 0; i < ulongArray.Length; i++)
                    ckmArray[i] = (CKM)Convert.ToUInt32(ulongArray[i]);
            }
            value = ckmArray;
        }
        public void _07_AttributeArrayAttributeTest()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0)
                Assert.Inconclusive("Test cannot be executed on this platform");

            CK_ATTRIBUTE[] originalValue = new CK_ATTRIBUTE[2];
            originalValue[0] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, true);
            originalValue[1] = CkaUtils.CreateAttribute(CKA.CKA_PRIVATE, true);
            // Create attribute with attribute array value
            CK_ATTRIBUTE attr = CkaUtils.CreateAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue);
            Assert.IsTrue(attr.type == (ulong)CKA.CKA_WRAP_TEMPLATE);
            Assert.IsTrue(attr.value != IntPtr.Zero);
            Assert.IsTrue(attr.valueLen == Convert.ToUInt64((UnmanagedMemory.SizeOf(typeof(CK_ATTRIBUTE)) * originalValue.Length)));

            CK_ATTRIBUTE[] recoveredValue = null;
            // Read the value of attribute
            CkaUtils.ConvertValue(ref attr, out recoveredValue);
            Assert.IsTrue(originalValue.Length == recoveredValue.Length);
            for (int i = 0; i < recoveredValue.Length; i++)
            {
                Assert.IsTrue(originalValue[i].type == recoveredValue[i].type);
                Assert.IsTrue(originalValue[i].valueLen == recoveredValue[i].valueLen);
                
                bool originalBool = false;
                // Read the value of nested attribute
                CkaUtils.ConvertValue(ref originalValue[i], out originalBool);

                bool recoveredBool = true;
                // Read the value of nested attribute
                CkaUtils.ConvertValue(ref recoveredValue[i], out recoveredBool);
                Assert.IsTrue(originalBool == recoveredBool);

                // In this example there is the same pointer to unmanaged memory 
                // in both originalValue and recoveredValue array therefore it
                // needs to be freed only once.
                Assert.IsTrue(originalValue[i].value == recoveredValue[i].value);
                // Free value of nested attributes
                UnmanagedMemory.Free(ref originalValue[i].value);
                originalValue[i].valueLen = 0;
                recoveredValue[i].value = IntPtr.Zero;
                recoveredValue[i].valueLen = 0;
            }

            // Free attribute value
            UnmanagedMemory.Free(ref attr.value);
            attr.valueLen = 0;
            Assert.IsTrue(attr.type == (ulong)CKA.CKA_WRAP_TEMPLATE);
            Assert.IsTrue(attr.value == IntPtr.Zero);
            Assert.IsTrue(attr.valueLen == 0);

            // Create attribute with null attribute array value
            attr = CkaUtils.CreateAttribute(CKA.CKA_WRAP_TEMPLATE, (CK_ATTRIBUTE[])null);
            Assert.IsTrue(attr.type == (ulong)CKA.CKA_WRAP_TEMPLATE);
            Assert.IsTrue(attr.value == IntPtr.Zero);
            Assert.IsTrue(attr.valueLen == 0);

            // Create attribute with empty attribute array value
            attr = CkaUtils.CreateAttribute(CKA.CKA_WRAP_TEMPLATE, new CK_ATTRIBUTE[0]);
            Assert.IsTrue(attr.type == (ulong)CKA.CKA_WRAP_TEMPLATE);
            Assert.IsTrue(attr.value == IntPtr.Zero);
            Assert.IsTrue(attr.valueLen == 0);
        }
Exemple #17
0
        /// <summary>
        /// Copies attribute value from unmanaged memory to managed byte array
        /// </summary>
        /// <param name="attribute">Attribute whose value should be read</param>
        /// <returns>Managed copy of attribute value</returns>
        private static byte[] ConvertValue(ref CK_ATTRIBUTE attribute)
        {
            byte[] value = null;

            if (attribute.value != IntPtr.Zero)
                value = UnmanagedMemory.Read(attribute.value, Convert.ToInt32(attribute.valueLen));

            return value;
        }
        public void _08_AttributeArrayAttributeTest()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0)
            {
                Assert.Inconclusive("Test cannot be executed on this platform");
            }

            ObjectAttribute nestedAttribute1 = new ObjectAttribute(CKA.CKA_TOKEN, true);
            ObjectAttribute nestedAttribute2 = new ObjectAttribute(CKA.CKA_PRIVATE, true);

            List <ObjectAttribute> originalValue = new List <ObjectAttribute>();

            originalValue.Add(nestedAttribute1);
            originalValue.Add(nestedAttribute2);

            // Create attribute with attribute array value
            using (ObjectAttribute attr = new ObjectAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue))
            {
                Assert.IsTrue(attr.Type == (ulong)CKA.CKA_WRAP_TEMPLATE);

                List <ObjectAttribute> recoveredValue = attr.GetValueAsObjectAttributeList();
                Assert.IsTrue(recoveredValue.Count == 2);
                Assert.IsTrue(recoveredValue[0].Type == (ulong)CKA.CKA_TOKEN);
                Assert.IsTrue(recoveredValue[0].GetValueAsBool() == true);
                Assert.IsTrue(recoveredValue[1].Type == (ulong)CKA.CKA_PRIVATE);
                Assert.IsTrue(recoveredValue[1].GetValueAsBool() == true);
            }

            // There is the same pointer to unmanaged memory in both nestedAttribute1 and recoveredValue[0] instances
            // therefore private low level attribute structure needs to be modified to prevent double free.
            // This special handling is needed only in this synthetic test and should be avoided in real world application.
            LLA80.CK_ATTRIBUTE ckAttribute1 = (LLA80.CK_ATTRIBUTE) typeof(ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(nestedAttribute1);
            ckAttribute1.value    = IntPtr.Zero;
            ckAttribute1.valueLen = 0;
            typeof(ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(nestedAttribute1, ckAttribute1);

            // There is the same pointer to unmanaged memory in both nestedAttribute2 and recoveredValue[1] instances
            // therefore private low level attribute structure needs to be modified to prevent double free.
            // This special handling is needed only in this synthetic test and should be avoided in real world application.
            LLA80.CK_ATTRIBUTE ckAttribute2 = (LLA80.CK_ATTRIBUTE) typeof(ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(nestedAttribute2);
            ckAttribute2.value    = IntPtr.Zero;
            ckAttribute2.valueLen = 0;
            typeof(ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(nestedAttribute2, ckAttribute2);

            originalValue = null;

            // Create attribute with null attribute array value
            using (ObjectAttribute attr = new ObjectAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue))
            {
                Assert.IsTrue(attr.Type == (ulong)CKA.CKA_WRAP_TEMPLATE);
                Assert.IsTrue(attr.GetValueAsObjectAttributeList() == originalValue);
            }

            originalValue = new List <ObjectAttribute>();

            // Create attribute with empty attribute array value
            using (ObjectAttribute attr = new ObjectAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue))
            {
                Assert.IsTrue(attr.Type == (ulong)CKA.CKA_WRAP_TEMPLATE);
                Assert.IsTrue(attr.GetValueAsObjectAttributeList() == null);
            }
        }
Exemple #19
0
        /// <summary>
        /// Obtains the value of one or more attributes of an object
        /// </summary>
        /// <param name="objectHandle">Handle of object whose attributes should be read</param>
        /// <param name="attributes">List of attributes that should be read</param>
        /// <returns>Object attributes</returns>
        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;
        }
        public void _02_GenerateKeyPairTest()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0)
                Assert.Inconclusive("Test cannot be executed on this platform");

            CKR rv = CKR.CKR_OK;
            
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath))
            {
                rv = pkcs11.C_Initialize(Settings.InitArgs80);
                if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED))
                    Assert.Fail(rv.ToString());
                
                // Find first slot with token present
                ulong slotId = Helpers.GetUsableSlot(pkcs11);
                
                ulong session = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Login as normal user
                rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // The CKA_ID attribute is intended as a means of distinguishing multiple key pairs held by the same subject
                byte[] ckaId = new byte[20];
                rv = pkcs11.C_GenerateRandom(session, ckaId, Convert.ToUInt64(ckaId.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Prepare attribute template of new public key
                CK_ATTRIBUTE[] pubKeyTemplate = new CK_ATTRIBUTE[10];
                pubKeyTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, true);
                pubKeyTemplate[1] = CkaUtils.CreateAttribute(CKA.CKA_PRIVATE, false);
                pubKeyTemplate[2] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.ApplicationName);
                pubKeyTemplate[3] = CkaUtils.CreateAttribute(CKA.CKA_ID, ckaId);
                pubKeyTemplate[4] = CkaUtils.CreateAttribute(CKA.CKA_ENCRYPT, true);
                pubKeyTemplate[5] = CkaUtils.CreateAttribute(CKA.CKA_VERIFY, true);
                pubKeyTemplate[6] = CkaUtils.CreateAttribute(CKA.CKA_VERIFY_RECOVER, true);
                pubKeyTemplate[7] = CkaUtils.CreateAttribute(CKA.CKA_WRAP, true);
                pubKeyTemplate[8] = CkaUtils.CreateAttribute(CKA.CKA_MODULUS_BITS, 1024);
                pubKeyTemplate[9] = CkaUtils.CreateAttribute(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 });

                // Prepare attribute template of new private key
                CK_ATTRIBUTE[] privKeyTemplate = new CK_ATTRIBUTE[9];
                privKeyTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, true);
                privKeyTemplate[1] = CkaUtils.CreateAttribute(CKA.CKA_PRIVATE, true);
                privKeyTemplate[2] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.ApplicationName);
                privKeyTemplate[3] = CkaUtils.CreateAttribute(CKA.CKA_ID, ckaId);
                privKeyTemplate[4] = CkaUtils.CreateAttribute(CKA.CKA_SENSITIVE, true);
                privKeyTemplate[5] = CkaUtils.CreateAttribute(CKA.CKA_DECRYPT, true);
                privKeyTemplate[6] = CkaUtils.CreateAttribute(CKA.CKA_SIGN, true);
                privKeyTemplate[7] = CkaUtils.CreateAttribute(CKA.CKA_SIGN_RECOVER, true);
                privKeyTemplate[8] = CkaUtils.CreateAttribute(CKA.CKA_UNWRAP, true);

                // Specify key generation mechanism (needs no parameter => no unamanaged memory is needed)
                CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_RSA_PKCS_KEY_PAIR_GEN);
                
                // Generate key pair
                ulong pubKeyId = CK.CK_INVALID_HANDLE;
                ulong privKeyId = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_GenerateKeyPair(session, ref mechanism, pubKeyTemplate, Convert.ToUInt64(pubKeyTemplate.Length), privKeyTemplate, Convert.ToUInt64(privKeyTemplate.Length), ref pubKeyId, ref privKeyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // In LowLevelAPI we have to free unmanaged memory taken by attributes
                for (int i = 0; i < privKeyTemplate.Length; i++)
                {
                    UnmanagedMemory.Free(ref privKeyTemplate[i].value);
                    privKeyTemplate[i].valueLen = 0;
                }

                for (int i = 0; i < pubKeyTemplate.Length; i++)
                {
                    UnmanagedMemory.Free(ref pubKeyTemplate[i].value);
                    pubKeyTemplate[i].valueLen = 0;
                }

                // Do something interesting with generated key pair
                
                // Destroy object
                rv = pkcs11.C_DestroyObject(session, privKeyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                rv = pkcs11.C_DestroyObject(session, pubKeyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_Logout(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_CloseSession(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_Finalize(IntPtr.Zero);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
            }
        }
Exemple #21
0
        /// <summary>
        /// Initializes a search for token and session objects that match a attributes
        /// </summary>
        /// <param name="attributes">Attributes that should be matched</param>
        public void FindObjectsInit(List<ObjectAttribute> attributes)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            CK_ATTRIBUTE[] template = null;
            ulong templateLength = 0;
            
            if (attributes != null)
            {
                templateLength = Convert.ToUInt64(attributes.Count);
                template = new CK_ATTRIBUTE[templateLength];
                for (int i = 0; i < Convert.ToInt32(templateLength); i++)
                    template[i] = attributes[i].CkAttribute;
            }

            CKR rv = _p11.C_FindObjectsInit(_sessionId, template, templateLength);
            if (rv != CKR.CKR_OK)
                throw new Pkcs11Exception("C_FindObjectsInit", rv);
        }
        public void _01_GenerateKeyTest()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0)
                Assert.Inconclusive("Test cannot be executed on this platform");

            CKR rv = CKR.CKR_OK;
            
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath))
            {
                rv = pkcs11.C_Initialize(Settings.InitArgs80);
                if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED))
                    Assert.Fail(rv.ToString());
                
                // Find first slot with token present
                ulong slotId = Helpers.GetUsableSlot(pkcs11);
                
                ulong session = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Login as normal user
                rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Prepare attribute template of new key
                CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[4];
                template[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY);
                template[1] = CkaUtils.CreateAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3);
                template[2] = CkaUtils.CreateAttribute(CKA.CKA_ENCRYPT, true);
                template[3] = CkaUtils.CreateAttribute(CKA.CKA_DECRYPT, true);

                // Specify key generation mechanism (needs no parameter => no unamanaged memory is needed)
                CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_DES3_KEY_GEN);
                
                // Generate key
                ulong keyId = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_GenerateKey(session, ref mechanism, template, Convert.ToUInt64(template.Length), ref keyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // In LowLevelAPI we have to free unmanaged memory taken by attributes
                for (int i = 0; i < template.Length; i++)
                {
                    UnmanagedMemory.Free(ref template[i].value);
                    template[i].valueLen = 0;
                }

                // Do something interesting with generated key

                // Destroy object
                rv = pkcs11.C_DestroyObject(session, keyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                rv = pkcs11.C_Logout(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_CloseSession(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_Finalize(IntPtr.Zero);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
            }
        }
        public void _01_BasicWrapAndUnwrapKeyTest()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0)
                Assert.Inconclusive("Test cannot be executed on this platform");

            CKR rv = CKR.CKR_OK;
            
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath))
            {
                rv = pkcs11.C_Initialize(Settings.InitArgs80);
                if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED))
                    Assert.Fail(rv.ToString());
                
                // Find first slot with token present
                ulong slotId = Helpers.GetUsableSlot(pkcs11);
                
                ulong session = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Login as normal user
                rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Generate asymetric key pair
                ulong pubKeyId = CK.CK_INVALID_HANDLE;
                ulong privKeyId = CK.CK_INVALID_HANDLE;
                rv = Helpers.GenerateKeyPair(pkcs11, session, ref pubKeyId, ref privKeyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Generate symetric key
                ulong keyId = CK.CK_INVALID_HANDLE;
                rv = Helpers.GenerateKey(pkcs11, session, ref keyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Specify wrapping mechanism (needs no parameter => no unamanaged memory is needed)
                CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_RSA_PKCS);

                // Get length of wrapped key in first call
                ulong wrappedKeyLen = 0;
                rv = pkcs11.C_WrapKey(session, ref mechanism, pubKeyId, keyId, null, ref wrappedKeyLen);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                Assert.IsTrue(wrappedKeyLen > 0);
                
                // Allocate array for wrapped key
                byte[] wrappedKey = new byte[wrappedKeyLen];

                // Get wrapped key in second call
                rv = pkcs11.C_WrapKey(session, ref mechanism, pubKeyId, keyId, wrappedKey, ref wrappedKeyLen);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Do something interesting with wrapped key

                // Define attributes for unwrapped key
                CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[6];
                template[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY);
                template[1] = CkaUtils.CreateAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3);
                template[2] = CkaUtils.CreateAttribute(CKA.CKA_ENCRYPT, true);
                template[3] = CkaUtils.CreateAttribute(CKA.CKA_DECRYPT, true);
                template[4] = CkaUtils.CreateAttribute(CKA.CKA_DERIVE, true);
                template[5] = CkaUtils.CreateAttribute(CKA.CKA_EXTRACTABLE, true);

                // Unwrap key
                ulong unwrappedKeyId = 0;
                rv = pkcs11.C_UnwrapKey(session, ref mechanism, privKeyId, wrappedKey, wrappedKeyLen, template, Convert.ToUInt64(template.Length), ref unwrappedKeyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Do something interesting with unwrapped key

                rv = pkcs11.C_DestroyObject(session, privKeyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_DestroyObject(session, pubKeyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_DestroyObject(session, keyId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_Logout(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_CloseSession(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_Finalize(IntPtr.Zero);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
            }
        }
        public void _01_CreateDestroyObjectTest()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0)
                Assert.Inconclusive("Test cannot be executed on this platform");

            CKR rv = CKR.CKR_OK;
            
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath))
            {
                rv = pkcs11.C_Initialize(Settings.InitArgs80);
                if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED))
                    Assert.Fail(rv.ToString());
                
                // Find first slot with token present
                ulong slotId = Helpers.GetUsableSlot(pkcs11);
                
                ulong session = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Login as normal user
                rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Prepare attribute template of new data object
                CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[5];
                template[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_DATA);
                template[1] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, true);
                template[2] = CkaUtils.CreateAttribute(CKA.CKA_APPLICATION, Settings.ApplicationName);
                template[3] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.ApplicationName);
                template[4] = CkaUtils.CreateAttribute(CKA.CKA_VALUE, "Data object content");

                // Create object
                ulong objectId = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_CreateObject(session, template, Convert.ToUInt64(template.Length), ref objectId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // In LowLevelAPI we have to free unmanaged memory taken by attributes
                for (int i = 0; i < template.Length; i++)
                {
                    UnmanagedMemory.Free(ref template[i].value);
                    template[i].valueLen = 0;
                }

                // Do something interesting with new object

                // Destroy object
                rv = pkcs11.C_DestroyObject(session, objectId);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                rv = pkcs11.C_Logout(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_CloseSession(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_Finalize(IntPtr.Zero);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
            }
        }
Exemple #25
0
 /// <summary>
 /// Reads value of attribute and returns it as string
 /// </summary>
 /// <param name="attribute">Attribute whose value should be read</param>
 /// <param name="value">Location that receives attribute value</param>
 public static void ConvertValue(ref CK_ATTRIBUTE attribute, out string value)
 {
     byte[] bytes = ConvertValue(ref attribute);
     value = ConvertUtils.BytesToUtf8String(bytes);
 }
Exemple #26
0
        public void _08_AttributeArrayAttributeTest()
        {
            IObjectAttribute nestedAttribute1 = Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_TOKEN, true);
            IObjectAttribute nestedAttribute2 = Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_PRIVATE, true);

            List <IObjectAttribute> originalValue = new List <IObjectAttribute>();

            originalValue.Add(nestedAttribute1);
            originalValue.Add(nestedAttribute2);

            // Create attribute with attribute array value
            using (IObjectAttribute attr = Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue))
            {
                Assert.IsTrue(attr.Type == ConvertUtils.UInt64FromCKA(CKA.CKA_WRAP_TEMPLATE));

                List <IObjectAttribute> recoveredValue = attr.GetValueAsObjectAttributeList();
                Assert.IsTrue(recoveredValue.Count == 2);
                Assert.IsTrue(recoveredValue[0].Type == ConvertUtils.UInt64FromCKA(CKA.CKA_TOKEN));
                Assert.IsTrue(recoveredValue[0].GetValueAsBool() == true);
                Assert.IsTrue(recoveredValue[1].Type == ConvertUtils.UInt64FromCKA(CKA.CKA_PRIVATE));
                Assert.IsTrue(recoveredValue[1].GetValueAsBool() == true);
            }

            if (Platform.NativeULongSize == 4)
            {
                if (Platform.StructPackingSize == 0)
                {
                    // There is the same pointer to unmanaged memory in both nestedAttribute1 and recoveredValue[0] instances
                    // therefore private low level attribute structure needs to be modified to prevent double free.
                    // This special handling is needed only in this synthetic test and should be avoided in real world application.
                    HLA40.ObjectAttribute objectAttribute40a = (HLA40.ObjectAttribute)nestedAttribute1;
                    LLA40.CK_ATTRIBUTE    ckAttribute40a     = (LLA40.CK_ATTRIBUTE) typeof(HLA40.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectAttribute40a);
                    ckAttribute40a.value    = IntPtr.Zero;
                    ckAttribute40a.valueLen = 0;
                    typeof(HLA40.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(objectAttribute40a, ckAttribute40a);

                    // There is the same pointer to unmanaged memory in both nestedAttribute2 and recoveredValue[1] instances
                    // therefore private low level attribute structure needs to be modified to prevent double free.
                    // This special handling is needed only in this synthetic test and should be avoided in real world application.
                    HLA40.ObjectAttribute objectAttribute40b = (HLA40.ObjectAttribute)nestedAttribute2;
                    LLA40.CK_ATTRIBUTE    ckAttribute40b     = (LLA40.CK_ATTRIBUTE) typeof(HLA40.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectAttribute40b);
                    ckAttribute40b.value    = IntPtr.Zero;
                    ckAttribute40b.valueLen = 0;
                    typeof(HLA40.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(objectAttribute40b, ckAttribute40b);
                }
                else
                {
                    // There is the same pointer to unmanaged memory in both nestedAttribute1 and recoveredValue[0] instances
                    // therefore private low level attribute structure needs to be modified to prevent double free.
                    // This special handling is needed only in this synthetic test and should be avoided in real world application.
                    HLA41.ObjectAttribute objectAttribute41a = (HLA41.ObjectAttribute)nestedAttribute1;
                    LLA41.CK_ATTRIBUTE    ckAttribute41a     = (LLA41.CK_ATTRIBUTE) typeof(HLA41.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectAttribute41a);
                    ckAttribute41a.value    = IntPtr.Zero;
                    ckAttribute41a.valueLen = 0;
                    typeof(HLA41.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(objectAttribute41a, ckAttribute41a);

                    // There is the same pointer to unmanaged memory in both nestedAttribute2 and recoveredValue[1] instances
                    // therefore private low level attribute structure needs to be modified to prevent double free.
                    // This special handling is needed only in this synthetic test and should be avoided in real world application.
                    HLA41.ObjectAttribute objectAttribute41b = (HLA41.ObjectAttribute)nestedAttribute2;
                    LLA41.CK_ATTRIBUTE    ckAttribute41b     = (LLA41.CK_ATTRIBUTE) typeof(HLA41.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectAttribute41b);
                    ckAttribute41b.value    = IntPtr.Zero;
                    ckAttribute41b.valueLen = 0;
                    typeof(HLA41.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(objectAttribute41b, ckAttribute41b);
                }
            }
            else
            {
                if (Platform.StructPackingSize == 0)
                {
                    // There is the same pointer to unmanaged memory in both nestedAttribute1 and recoveredValue[0] instances
                    // therefore private low level attribute structure needs to be modified to prevent double free.
                    // This special handling is needed only in this synthetic test and should be avoided in real world application.
                    HLA80.ObjectAttribute objectAttribute80a = (HLA80.ObjectAttribute)nestedAttribute1;
                    LLA80.CK_ATTRIBUTE    ckAttribute80a     = (LLA80.CK_ATTRIBUTE) typeof(HLA80.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectAttribute80a);
                    ckAttribute80a.value    = IntPtr.Zero;
                    ckAttribute80a.valueLen = 0;
                    typeof(HLA80.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(objectAttribute80a, ckAttribute80a);

                    // There is the same pointer to unmanaged memory in both nestedAttribute2 and recoveredValue[1] instances
                    // therefore private low level attribute structure needs to be modified to prevent double free.
                    // This special handling is needed only in this synthetic test and should be avoided in real world application.
                    HLA80.ObjectAttribute objectAttribute80b = (HLA80.ObjectAttribute)nestedAttribute2;
                    LLA80.CK_ATTRIBUTE    ckAttribute80b     = (LLA80.CK_ATTRIBUTE) typeof(HLA80.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectAttribute80b);
                    ckAttribute80b.value    = IntPtr.Zero;
                    ckAttribute80b.valueLen = 0;
                    typeof(HLA80.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(objectAttribute80b, ckAttribute80b);
                }
                else
                {
                    // There is the same pointer to unmanaged memory in both nestedAttribute1 and recoveredValue[0] instances
                    // therefore private low level attribute structure needs to be modified to prevent double free.
                    // This special handling is needed only in this synthetic test and should be avoided in real world application.
                    HLA81.ObjectAttribute objectAttribute81a = (HLA81.ObjectAttribute)nestedAttribute1;
                    LLA81.CK_ATTRIBUTE    ckAttribute81a     = (LLA81.CK_ATTRIBUTE) typeof(HLA81.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectAttribute81a);
                    ckAttribute81a.value    = IntPtr.Zero;
                    ckAttribute81a.valueLen = 0;
                    typeof(HLA81.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(objectAttribute81a, ckAttribute81a);

                    // There is the same pointer to unmanaged memory in both nestedAttribute2 and recoveredValue[1] instances
                    // therefore private low level attribute structure needs to be modified to prevent double free.
                    // This special handling is needed only in this synthetic test and should be avoided in real world application.
                    HLA81.ObjectAttribute objectAttribute81b = (HLA81.ObjectAttribute)nestedAttribute2;
                    LLA81.CK_ATTRIBUTE    ckAttribute81b     = (LLA81.CK_ATTRIBUTE) typeof(HLA81.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectAttribute81b);
                    ckAttribute81b.value    = IntPtr.Zero;
                    ckAttribute81b.valueLen = 0;
                    typeof(HLA81.ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(objectAttribute81b, ckAttribute81b);
                }
            }

            originalValue = null;

            // Create attribute with null attribute array value
            using (IObjectAttribute attr = Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue))
            {
                Assert.IsTrue(attr.Type == ConvertUtils.UInt64FromCKA(CKA.CKA_WRAP_TEMPLATE));
                Assert.IsTrue(attr.GetValueAsObjectAttributeList() == originalValue);
            }

            originalValue = new List <IObjectAttribute>();

            // Create attribute with empty attribute array value
            using (IObjectAttribute attr = Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue))
            {
                Assert.IsTrue(attr.Type == ConvertUtils.UInt64FromCKA(CKA.CKA_WRAP_TEMPLATE));
                Assert.IsTrue(attr.GetValueAsObjectAttributeList() == null);
            }
        }
Exemple #27
0
        /// <summary>
        /// Reads value of attribute and returns it as DateTime (CK_DATE)
        /// </summary>
        /// <param name="attribute">Attribute whose value should be read</param>
        /// <param name="value">Location that receives attribute value</param>
        public static void ConvertValue(ref CK_ATTRIBUTE attribute, out DateTime? value)
        {
            byte[] bytes = ConvertValue(ref attribute);

            if (bytes.Length == 0)
            {
                // PKCS#11 v2.20:
                // When a Cryptoki object carries an attribute of this type, and the default value of the
                // attribute is specified to be "empty," then Cryptoki libraries shall set the attribute's ulValueLen to 0.
                value = null;
                return;
            }

            if ((bytes == null) || (bytes.Length != 8))
                throw new Exception("Unable to convert attribute value to DateTime");

            string year = ConvertUtils.BytesToUtf8String(bytes, 0, 4);
            string month = ConvertUtils.BytesToUtf8String(bytes, 4, 2);
            string day = ConvertUtils.BytesToUtf8String(bytes, 6, 2);

            if ((year == "0000") && (month == "00") && (day == "00"))
            {
                // PKCS#11 v2.20:
                // Note that implementations of previous versions of Cryptoki may have used other
                // methods to identify an "empty" attribute of type CK_DATE, and that applications that needs to
                // interoperate with these libraries therefore have to be flexible in what they accept as an empty value.
                value = null;
                return;
            }

            value = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(day), 0, 0, 0, DateTimeKind.Utc);
        }
Exemple #28
0
        /// <summary>
        /// Generates a secret key or set of domain parameters, creating a new object
        /// </summary>
        /// <param name="mechanism">Generation mechanism</param>
        /// <param name="attributes">Attributes of the new key or set of domain parameters</param>
        /// <returns>Handle of the new key or set of domain parameters</returns>
        public ObjectHandle GenerateKey(Mechanism mechanism, List<ObjectAttribute> attributes)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            if (mechanism == null)
                throw new ArgumentNullException("mechanism");

            CK_MECHANISM ckMechanism = mechanism.CkMechanism;

            CK_ATTRIBUTE[] template = null;
            ulong templateLength = 0;
            
            if (attributes != null)
            {
                templateLength = Convert.ToUInt64(attributes.Count);
                template = new CK_ATTRIBUTE[templateLength];
                for (int i = 0; i < Convert.ToInt32(templateLength); i++)
                    template[i] = attributes[i].CkAttribute;
            }

            ulong keyId = CK.CK_INVALID_HANDLE;
            CKR rv = _p11.C_GenerateKey(_sessionId, ref ckMechanism, template, templateLength, ref keyId);
            if (rv != CKR.CKR_OK)
                throw new Pkcs11Exception("C_GenerateKey", rv);

            return new ObjectHandle(keyId);
        }
Exemple #29
0
        /// <summary>
        /// Reads value of attribute and returns it as attribute array
        /// </summary>
        /// <param name="attribute">Attribute whose value should be read</param>
        /// <param name="value">Location that receives attribute value</param>
        public static void ConvertValue(ref CK_ATTRIBUTE attribute, out CK_ATTRIBUTE[] value)
        {
            int ckAttributeSize = UnmanagedMemory.SizeOf(typeof(CK_ATTRIBUTE));
            int attrCount = Convert.ToInt32(attribute.valueLen) / ckAttributeSize;
            int attrCountMod = Convert.ToInt32(attribute.valueLen) % ckAttributeSize;

            if (attrCountMod != 0)
                throw new Exception("Unable to convert attribute value to attribute array");

            if (attrCount == 0)
            {
                value = null;
            }
            else
            {
                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[attrCount];

                for (int i = 0; i < attrCount; i++)
                {
                    IntPtr tempPointer = new IntPtr(attribute.value.ToInt64() + (i * ckAttributeSize));
#if SILVERLIGHT
                    CK_ATTRIBUTE_CLASS attrClass = (CK_ATTRIBUTE_CLASS)UnmanagedMemory.Read(tempPointer, typeof(CK_ATTRIBUTE_CLASS));
                    attrClass.ToCkAttributeStruct(ref attrs[i]);
#else
                    attrs[i] = (CK_ATTRIBUTE)UnmanagedMemory.Read(tempPointer, typeof(CK_ATTRIBUTE));
#endif
                }

                value = attrs;
            }
        }
Exemple #30
0
        /// <summary>
        /// Generates a public/private key pair, creating new key objects
        /// </summary>
        /// <param name="mechanism">Key generation mechanism</param>
        /// <param name="publicKeyAttributes">Attributes of the public key</param>
        /// <param name="privateKeyAttributes">Attributes of the private key</param>
        /// <param name="publicKeyHandle">Handle of the new public key</param>
        /// <param name="privateKeyHandle">Handle of the new private key</param>
        public void GenerateKeyPair(Mechanism mechanism, List<ObjectAttribute> publicKeyAttributes, List<ObjectAttribute> privateKeyAttributes, out ObjectHandle publicKeyHandle, out ObjectHandle privateKeyHandle)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            if (mechanism == null)
                throw new ArgumentNullException("mechanism");

            CK_MECHANISM ckMechanism = mechanism.CkMechanism;

            CK_ATTRIBUTE[] publicKeyTemplate = null;
            ulong publicKeyTemplateLength = 0;
            
            if (publicKeyAttributes != null)
            {
                publicKeyTemplateLength = Convert.ToUInt64(publicKeyAttributes.Count);
                publicKeyTemplate = new CK_ATTRIBUTE[publicKeyTemplateLength];
                for (int i = 0; i < Convert.ToInt32(publicKeyTemplateLength); i++)
                    publicKeyTemplate[i] = publicKeyAttributes[i].CkAttribute;
            }

            CK_ATTRIBUTE[] privateKeyTemplate = null;
            ulong privateKeyTemplateLength = 0;
            
            if (privateKeyAttributes != null)
            {
                privateKeyTemplateLength = Convert.ToUInt64(privateKeyAttributes.Count);
                privateKeyTemplate = new CK_ATTRIBUTE[privateKeyTemplateLength];
                for (int i = 0; i < Convert.ToInt32(privateKeyTemplateLength); i++)
                    privateKeyTemplate[i] = privateKeyAttributes[i].CkAttribute;
            }

            ulong publicKeyId = CK.CK_INVALID_HANDLE;
            ulong privateKeyId = CK.CK_INVALID_HANDLE;
            CKR rv = _p11.C_GenerateKeyPair(_sessionId, ref ckMechanism, publicKeyTemplate, publicKeyTemplateLength, privateKeyTemplate, privateKeyTemplateLength, ref publicKeyId, ref privateKeyId);
            if (rv != CKR.CKR_OK)
                throw new Pkcs11Exception("C_GenerateKeyPair", rv);

            publicKeyHandle = new ObjectHandle(publicKeyId);
            privateKeyHandle = new ObjectHandle(privateKeyId);
        }
Exemple #31
0
 /// <summary>
 /// Reads value of attribute and returns it as ulong array
 /// </summary>
 /// <param name="attribute">Attribute whose value should be read</param>
 /// <param name="value">Location that receives attribute value</param>
 public static void ConvertValue(ref CK_ATTRIBUTE attribute, out ulong[] value)
 {
     int ckmSize = UnmanagedMemory.SizeOf(typeof(ulong));
     int attrCount = Convert.ToInt32(attribute.valueLen) / ckmSize;
     int attrCountMod = Convert.ToInt32(attribute.valueLen) % ckmSize;
     
     if (attrCountMod != 0)
         throw new Exception("Unable to convert attribute value to ulong array");
     
     if (attrCount == 0)
     {
         value = null;
     }
     else
     {
         ulong[] attrs = new ulong[attrCount];
         
         for (int i = 0; i < attrCount; i++)
         {
             IntPtr tempPointer = new IntPtr(attribute.value.ToInt64() + (i * ckmSize));
             attrs[i] = ConvertUtils.BytesToULong(UnmanagedMemory.Read(tempPointer, ckmSize));
         }
         
         value = attrs;
     }
 }
Exemple #32
0
        /// <summary>
        /// Derives a key from a base key, creating a new key object
        /// </summary>
        /// <param name="mechanism">Derivation mechanism</param>
        /// <param name="baseKeyHandle">Handle of base key</param>
        /// <param name="attributes">Attributes for the new key</param>
        /// <returns>Handle of derived key</returns>
        public ObjectHandle DeriveKey(Mechanism mechanism, ObjectHandle baseKeyHandle, List<ObjectAttribute> attributes)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            if (mechanism == null)
                throw new ArgumentNullException("mechanism");
            
            if (baseKeyHandle == null)
                throw new ArgumentNullException("baseKeyHandle");

            CK_MECHANISM ckMechanism = mechanism.CkMechanism;

            CK_ATTRIBUTE[] template = null;
            ulong templateLen = 0;
            if (attributes != null)
            {
                template = new CK_ATTRIBUTE[attributes.Count];
                for (int i = 0; i < attributes.Count; i++)
                    template[i] = attributes[i].CkAttribute;
                templateLen = Convert.ToUInt64(attributes.Count);
            }

            ulong derivedKey = CK.CK_INVALID_HANDLE;
            CKR rv = _p11.C_DeriveKey(_sessionId, ref ckMechanism, baseKeyHandle.ObjectId, template, templateLen, ref derivedKey);
            if (rv != CKR.CKR_OK)
                throw new Pkcs11Exception("C_DeriveKey", rv);

            return new ObjectHandle(derivedKey);
        }
Exemple #33
0
        /// <summary>
        /// Creates attribute of given type with value copied from managed byte array to the newly allocated unmanaged memory
        /// </summary>
        /// <param name="type">Attribute type</param>
        /// <param name="value">Attribute value</param>
        /// <returns>Attribute of given type with specified value</returns>
        private static CK_ATTRIBUTE _CreateAttribute(ulong type, byte[] value)
        {
            CK_ATTRIBUTE attribute = new CK_ATTRIBUTE();
            attribute.type = type;
            if (value != null)
            {
                attribute.value = UnmanagedMemory.Allocate(value.Length);
                UnmanagedMemory.Write(attribute.value, value);
                attribute.valueLen = Convert.ToUInt64(value.Length);
            }
            else
            {
                attribute.value = IntPtr.Zero;
                attribute.valueLen = 0;
            }

            return attribute;
        }
Exemple #34
0
        /// <summary>
        /// Copies an object, creating a new object for the copy
        /// </summary>
        /// <param name="objectHandle">Handle of object to be copied</param>
        /// <param name="attributes">New values for any attributes of the object that can ordinarily be modified</param>
        /// <returns>Handle of copied object</returns>
        public ObjectHandle CopyObject(ObjectHandle objectHandle, List<ObjectAttribute> attributes)
        {
            if (this._disposed)
                throw new ObjectDisposedException(this.GetType().FullName);

            if (objectHandle == null)
                throw new ArgumentNullException("objectHandle");

            ulong objectId = CK.CK_INVALID_HANDLE;

            CK_ATTRIBUTE[] template = null;
            ulong templateLength = 0;

            if (attributes != null)
            {
                templateLength = Convert.ToUInt64(attributes.Count);
                template = new CK_ATTRIBUTE[templateLength];
                for (int i = 0; i < Convert.ToInt32(templateLength); i++)
                    template[i] = attributes[i].CkAttribute;
            }

            CKR rv = _p11.C_CopyObject(_sessionId, objectHandle.ObjectId, template, templateLength, ref objectId);
            if (rv != CKR.CKR_OK)
                throw new Pkcs11Exception("C_CopyObject", rv);

            return new ObjectHandle(objectId);
        }
        public void _01_BasicObjectFindingTest()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0)
                Assert.Inconclusive("Test cannot be executed on this platform");

            CKR rv = CKR.CKR_OK;
            
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath))
            {
                rv = pkcs11.C_Initialize(Settings.InitArgs80);
                if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED))
                    Assert.Fail(rv.ToString());
                
                // Find first slot with token present
                ulong slotId = Helpers.GetUsableSlot(pkcs11);
                
                ulong session = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Login as normal user
                rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                // Let's create two objects so we can find something
                ulong objectId1 = CK.CK_INVALID_HANDLE;
                rv = Helpers.CreateDataObject(pkcs11, session, ref objectId1);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                ulong objectId2 = CK.CK_INVALID_HANDLE;
                rv = Helpers.CreateDataObject(pkcs11, session, ref objectId2);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Prepare attribute template that defines search criteria
                CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[2];
                template[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_DATA);
                template[1] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, true);

                // Initialize searching
                rv = pkcs11.C_FindObjectsInit(session, template, Convert.ToUInt64(template.Length));
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Get search results
                ulong foundObjectCount = 0;
                ulong[] foundObjectIds = new ulong[2];
                foundObjectIds[0] = CK.CK_INVALID_HANDLE;
                foundObjectIds[1] = CK.CK_INVALID_HANDLE;
                rv = pkcs11.C_FindObjects(session, foundObjectIds, Convert.ToUInt64(foundObjectIds.Length), ref foundObjectCount);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Terminate searching
                rv = pkcs11.C_FindObjectsFinal(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                // Do something interesting with found objects
                Assert.IsTrue((foundObjectIds[0] != CK.CK_INVALID_HANDLE) && (foundObjectIds[1] != CK.CK_INVALID_HANDLE));

                // In LowLevelAPI we have to free unmanaged memory taken by attributes
                for (int i = 0; i < template.Length; i++)
                {
                    UnmanagedMemory.Free(ref template[i].value);
                    template[i].valueLen = 0;
                }

                rv = pkcs11.C_DestroyObject(session, objectId2);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                rv = pkcs11.C_DestroyObject(session, objectId1);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());

                rv = pkcs11.C_Logout(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_CloseSession(session);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
                
                rv = pkcs11.C_Finalize(IntPtr.Zero);
                if (rv != CKR.CKR_OK)
                    Assert.Fail(rv.ToString());
            }
        }
Exemple #36
0
 /// <summary>
 /// Reads value of attribute and returns it as NativeULong
 /// </summary>
 /// <param name="attribute">Attribute whose value should be read</param>
 /// <param name="value">Location that receives attribute value</param>
 public static void ConvertValue(ref CK_ATTRIBUTE attribute, out NativeULong value)
 {
     byte[] bytes = ConvertValue(ref attribute);
     value = ConvertUtils.UInt64FromBytes(bytes);
 }