/// <summary>
        /// Intializes new instance of Pkcs11UriBuilder class with specified PKCS#11 URI whose ChecksLengths property specifies whether max lengths of path attribute values should be checked
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI with default values</param>
        public Pkcs11UriBuilder(Pkcs11Uri pkcs11Uri)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            ConstructFromPkcs11Uri(pkcs11Uri, pkcs11Uri.ChecksLengths);
        }
        /// <summary>
        /// Intializes new instance of Pkcs11UriBuilder class with specified PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI with default values</param>
        /// <param name="checkLengths">Flag indicating whether max lengths of path attribute values should be checked</param>
        public Pkcs11UriBuilder(Pkcs11Uri pkcs11Uri, bool checkLengths)
        {
            if (pkcs11Uri == null)
                throw new ArgumentException("pkcs11Uri");

            ConstructFromPkcs11Uri(pkcs11Uri, checkLengths);
        }
        /// <summary>
        /// Checks whether object attributes match PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="objectAttributes">Object attributes</param>
        /// <returns>True if object attributes match PKCS#11 URI</returns>
        public static bool Matches(Pkcs11Uri pkcs11Uri, List<ObjectAttribute> objectAttributes)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            ulong ckaClassType = Convert.ToUInt64(CKA.CKA_CLASS);
            CKO? ckaClassValue = null;
            bool ckaClassFound = false;

            ulong ckaLabelType = Convert.ToUInt64(CKA.CKA_LABEL);
            string ckaLabelValue = null;
            bool ckaLabelFound = false;

            ulong ckaIdType = Convert.ToUInt64(CKA.CKA_ID);
            byte[] ckaIdValue = null;
            bool ckaIdFound = false;

            foreach (ObjectAttribute objectAttribute in objectAttributes)
            {
                if (objectAttribute == null)
                    continue;

                if (objectAttribute.Type == ckaClassType)
                {
                    ckaClassValue = (CKO)Convert.ToUInt32(objectAttribute.GetValueAsUlong());
                    ckaClassFound = true;
                }
                else if (objectAttribute.Type == ckaLabelType)
                {
                    ckaLabelValue = objectAttribute.GetValueAsString();
                    ckaLabelFound = true;
                }
                else if (objectAttribute.Type == ckaIdType)
                {
                    ckaIdValue = objectAttribute.GetValueAsByteArray();
                    ckaIdFound = true;
                }

                if (ckaClassFound && ckaLabelFound && ckaIdFound)
                    break;
            }

            if ((!ckaClassFound) && (pkcs11Uri.Type != null))
                throw new Pkcs11UriException("CKA_CLASS attribute is not present in the list of object attributes");

            if ((!ckaLabelFound) && (pkcs11Uri.Object != null))
                throw new Pkcs11UriException("CKA_LABEL attribute is not present in the list of object attributes");

            if ((!ckaIdFound) && (pkcs11Uri.Id != null))
                throw new Pkcs11UriException("CKA_ID attribute is not present in the list of object attributes");

            return Pkcs11UriSharedUtils.Matches(pkcs11Uri, ckaClassValue, ckaLabelValue, ckaIdValue);
        }
        /// <summary>
        /// Checks whether slot information matches PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="slotInfo">Slot information</param>
        /// <param name="slotId">Slot identifier</param>
        /// <returns>True if slot information matches PKCS#11 URI</returns>
        public static bool Matches(Pkcs11Uri pkcs11Uri, CK_SLOT_INFO slotInfo, uint? slotId)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            string manufacturer = ConvertUtils.BytesToUtf8String(slotInfo.ManufacturerId, true);
            string description = ConvertUtils.BytesToUtf8String(slotInfo.SlotDescription, true);

            return Pkcs11UriSharedUtils.Matches(pkcs11Uri, manufacturer, description, slotId);
        }
        /// <summary>
        /// Checks whether token information matches PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="tokenInfo">Token information</param>
        /// <returns>True if token information matches PKCS#11 URI</returns>
        public static bool Matches(Pkcs11Uri pkcs11Uri, TokenInfo tokenInfo)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            return Pkcs11UriSharedUtils.Matches(pkcs11Uri, tokenInfo.Label, tokenInfo.ManufacturerId, tokenInfo.SerialNumber, tokenInfo.Model);
        }
        /// <summary>
        /// Checks whether slot information matches PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="slotInfo">Slot information</param>
        /// <returns>True if slot information matches PKCS#11 URI</returns>
        public static bool Matches(Pkcs11Uri pkcs11Uri, SlotInfo slotInfo)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            return Pkcs11UriSharedUtils.Matches(pkcs11Uri, slotInfo.ManufacturerId, slotInfo.SlotDescription, slotInfo.SlotId);
        }
        /// <summary>
        /// Checks whether PKCS#11 library information matches PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="libraryInfo">PKCS#11 library information</param>
        /// <returns>True if PKCS#11 library information matches PKCS#11 URI</returns>
        public static bool Matches(Pkcs11Uri pkcs11Uri, LibraryInfo libraryInfo)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            return Pkcs11UriSharedUtils.Matches(pkcs11Uri, libraryInfo.ManufacturerId, libraryInfo.LibraryDescription, libraryInfo.LibraryVersion);
        }
        /// <summary>
        /// Checks whether PKCS#11 library information matches PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="libraryInfo">PKCS#11 library information</param>
        /// <returns>True if PKCS#11 library information matches PKCS#11 URI</returns>
        public static bool Matches(Pkcs11Uri pkcs11Uri, CK_INFO libraryInfo)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            string manufacturer = ConvertUtils.BytesToUtf8String(libraryInfo.ManufacturerId, true);
            string description = ConvertUtils.BytesToUtf8String(libraryInfo.LibraryDescription, true);
            string version = libraryInfo.LibraryVersion.ToString();

            return Pkcs11UriSharedUtils.Matches(pkcs11Uri, manufacturer, description, version);
        }
        /// <summary>
        /// Checks whether token information matches PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="tokenInfo">Token information</param>
        /// <returns>True if token information matches PKCS#11 URI</returns>
        public static bool Matches(Pkcs11Uri pkcs11Uri, CK_TOKEN_INFO tokenInfo)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            string token = ConvertUtils.BytesToUtf8String(tokenInfo.Label, true);
            string manufacturer = ConvertUtils.BytesToUtf8String(tokenInfo.ManufacturerId, true);
            string serial = ConvertUtils.BytesToUtf8String(tokenInfo.SerialNumber, true);
            string model = ConvertUtils.BytesToUtf8String(tokenInfo.Model, true);

            return Pkcs11UriSharedUtils.Matches(pkcs11Uri, token, manufacturer, serial, model);
        }
        /// <summary>
        /// Creates the PKCS#1 v1.5 RSA signature with SHA-1 mechanism
        /// </summary>
        /// <param name="data">Data that should be signed</param>
        /// <param name="uri">PKCS#11 URI identifying PKCS#11 library, token and private key</param>
        /// <returns>PKCS#1 v1.5 RSA signature</returns>
        private byte[] SignData(byte[] data, string uri)
        {
            // Verify input parameters
            if (data == null)
                throw new ArgumentNullException("data");

            if (string.IsNullOrEmpty(uri))
                throw new ArgumentNullException("uri");

            // Parse PKCS#11 URI
            Pkcs11Uri pkcs11Uri = new Pkcs11Uri(uri);

            // Verify that URI contains all information required to perform this operation
            if (pkcs11Uri.ModulePath == null)
                throw new Exception("PKCS#11 URI does not specify PKCS#11 library");

            if (pkcs11Uri.PinValue == null)
                throw new Exception("PKCS#11 URI does not specify PIN");

            if (!pkcs11Uri.DefinesObject || pkcs11Uri.Type != CKO.CKO_PRIVATE_KEY)
                throw new Exception("PKCS#11 URI does not specify private key");

            // Load and initialize PKCS#11 library specified by URI
            using (Pkcs11 pkcs11 = new Pkcs11(pkcs11Uri.ModulePath, true))
            {
                //  Obtain a list of all slots with tokens that match URI
                List<Slot> slots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11Uri, pkcs11, true);
                if ((slots == null) || (slots.Count == 0))
                    throw new Exception("None of the slots matches PKCS#11 URI");

                // Open read only session with first token that matches URI
                using (Session session = slots[0].OpenSession(true))
                {
                    // Login as normal user with PIN acquired from URI
                    session.Login(CKU.CKU_USER, pkcs11Uri.PinValue);

                    // Get list of object attributes for the private key specified by URI
                    List<ObjectAttribute> searchTemplate = null;
                    Pkcs11UriUtils.GetObjectAttributes(pkcs11Uri, out searchTemplate);

                    // Find private key specified by URI
                    List<ObjectHandle> foundObjects = session.FindAllObjects(searchTemplate);
                    if ((foundObjects == null) || (foundObjects.Count == 0))
                        throw new Exception("None of the private keys match PKCS#11 URI");

                    // Create signature with the private key specified by URI
                    return session.Sign(new Mechanism(CKM.CKM_SHA1_RSA_PKCS), foundObjects[0], data);
                }
            }
        }
        public void _02_LibraryInfoMatches()
        {
            if (Platform.UnmanagedLongSize != 4 || Platform.StructPackingSize != 1)
                Assert.Inconclusive("Test cannot be executed on this platform");

            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, Settings.UseOsLocking))
            {
                LibraryInfo libraryInfo = pkcs11.GetInfo();

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // Unknown path attribute in URI
                pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar");
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // All attributes matching
                Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = libraryInfo.ManufacturerId;
                pkcs11UriBuilder.LibraryDescription = libraryInfo.LibraryDescription;
                pkcs11UriBuilder.LibraryVersion = libraryInfo.LibraryVersion;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // LibraryManufacturer nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = "foobar";
                pkcs11UriBuilder.LibraryDescription = libraryInfo.LibraryDescription;
                pkcs11UriBuilder.LibraryVersion = libraryInfo.LibraryVersion;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // LibraryDescription nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = libraryInfo.ManufacturerId;
                pkcs11UriBuilder.LibraryDescription = "foobar";
                pkcs11UriBuilder.LibraryVersion = libraryInfo.LibraryVersion;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // LibraryVersion nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = libraryInfo.ManufacturerId;
                pkcs11UriBuilder.LibraryDescription = libraryInfo.LibraryDescription;
                pkcs11UriBuilder.LibraryVersion = "0";
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));
            }
        }
        public void LibraryInfoMatchesHLA()
        {
            using (HLA.Pkcs11 pkcs11 = new HLA.Pkcs11(Settings.Pkcs11LibraryPath, false))
            {
                HLA.LibraryInfo libraryInfo = pkcs11.GetInfo();

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // Unknown path attribute in URI
                pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar");
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // All attributes matching
                Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = libraryInfo.ManufacturerId;
                pkcs11UriBuilder.LibraryDescription = libraryInfo.LibraryDescription;
                pkcs11UriBuilder.LibraryVersion = libraryInfo.LibraryVersion;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // LibraryManufacturer nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = "foobar";
                pkcs11UriBuilder.LibraryDescription = libraryInfo.LibraryDescription;
                pkcs11UriBuilder.LibraryVersion = libraryInfo.LibraryVersion;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // LibraryDescription nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = libraryInfo.ManufacturerId;
                pkcs11UriBuilder.LibraryDescription = "foobar";
                pkcs11UriBuilder.LibraryVersion = libraryInfo.LibraryVersion;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

                // LibraryVersion nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = libraryInfo.ManufacturerId;
                pkcs11UriBuilder.LibraryDescription = libraryInfo.LibraryDescription;
                pkcs11UriBuilder.LibraryVersion = "0";
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));
            }
        }
        public void EmptyUri()
        {
            string uri = string.Empty;

            // Note: Builder cannot be used to produce URI like this one

            try
            {
                // Parse URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(uri);
                Assert.Fail("Exception expected but not thrown");
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is ArgumentNullException);
            }
        }
        /// <summary>
        /// Checks whether PKCS#11 library information matches PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="libraryManufacturer">PKCS#11 library manufacturer</param>
        /// <param name="libraryDescription">PKCS#11 library description</param>
        /// <param name="libraryVersion">PKCS#11 library version</param>
        /// <returns>True if PKCS#11 library information matches PKCS#11 URI</returns>
        internal static bool Matches(Pkcs11Uri pkcs11Uri, string libraryManufacturer, string libraryDescription, string libraryVersion)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            if (pkcs11Uri.UnknownPathAttributes.Count > 0)
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.LibraryManufacturer, libraryManufacturer))
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.LibraryDescription, libraryDescription))
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.LibraryVersion, libraryVersion))
                return false;

            return true;
        }
        /// <summary>
        /// Checks whether slot information matches PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="slotManufacturer">Slot manufacturer</param>
        /// <param name="slotDescription">Slot description</param>
        /// <param name="slotId">Slot identifier</param>
        /// <returns>True if slot information matches PKCS#11 URI</returns>
        internal static bool Matches(Pkcs11Uri pkcs11Uri, string slotManufacturer, string slotDescription, ulong? slotId)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            if (pkcs11Uri.UnknownPathAttributes.Count > 0)
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.SlotManufacturer, slotManufacturer))
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.SlotDescription, slotDescription))
                return false;

            if (!SlotIdsMatch(pkcs11Uri.SlotId, slotId))
                return false;

            return true;
        }
        public void _04_TokenInfoMatches()
        {
            if (Platform.UnmanagedLongSize != 4 || Platform.StructPackingSize != 1)
                Assert.Inconclusive("Test cannot be executed on this platform");

            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, Settings.UseOsLocking))
            {
                List<Slot> slots = pkcs11.GetSlotList(true);
                Assert.IsTrue(slots != null && slots.Count > 0);
                TokenInfo tokenInfo = slots[0].GetTokenInfo();

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Unknown path attribute in URI
                pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar");
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // All attributes matching
                Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Token nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = "foobar";
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Manufacturer nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = "foobar";
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Serial nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = "foobar";
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Model nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = "foobar";
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));
            }
        }
        public void SlotInfoMatchesHLA8()
        {
            // Skip test on incompatible platforms
            if (UnmanagedLong.Size != 8)
                return;

            using (HLA8.Pkcs11 pkcs11 = new HLA8.Pkcs11(Settings.Pkcs11LibraryPath, false))
            {
                List<HLA8.Slot> slots = pkcs11.GetSlotList(true);
                Assert.IsTrue(slots != null && slots.Count > 0);
                HLA8.SlotInfo slotInfo = slots[0].GetSlotInfo();

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // Unknown path attribute in URI
                pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar");
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // All attributes matching
                Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.SlotManufacturer = slotInfo.ManufacturerId;
                pkcs11UriBuilder.SlotDescription = slotInfo.SlotDescription;
                pkcs11UriBuilder.SlotId = slotInfo.SlotId;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // Manufacturer nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.SlotManufacturer = "foobar";
                pkcs11UriBuilder.SlotDescription = slotInfo.SlotDescription;
                pkcs11UriBuilder.SlotId = slotInfo.SlotId;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // Description nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.SlotManufacturer = slotInfo.ManufacturerId;
                pkcs11UriBuilder.SlotDescription = "foobar";
                pkcs11UriBuilder.SlotId = slotInfo.SlotId;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // Slot id nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.SlotManufacturer = slotInfo.ManufacturerId;
                pkcs11UriBuilder.SlotDescription = slotInfo.SlotDescription;
                pkcs11UriBuilder.SlotId = slotInfo.SlotId + 1;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));
            }
        }
        public void LibraryInfoMatchesLLA4()
        {
            // Empty URI
            Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            LLA4.CK_INFO libraryInfo = new LLA4.CK_INFO();
            libraryInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion = new LLA4.CK_VERSION() { Major = new byte[] { 0x01 }, Minor = new byte[] { 0x00 } };
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

            // Empty attribute
            pkcs11uri = new Pkcs11Uri(@"pkcs11:library-manufacturer=;library-description=bar;library-version=1");
            libraryInfo = new LLA4.CK_INFO();
            libraryInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("                                ");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion = new LLA4.CK_VERSION() { Major = new byte[] { 0x01 }, Minor = new byte[] { 0x00 } };
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

            // Unknown path attribute in URI
            pkcs11uri = new Pkcs11Uri(@"pkcs11:library-manufacturer=foo;library-description=bar;library-version=1;foo=bar");
            libraryInfo = new LLA4.CK_INFO();
            libraryInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion = new LLA4.CK_VERSION() { Major = new byte[] { 0x01 }, Minor = new byte[] { 0x00 } };
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

            // All attributes matching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:library-manufacturer=foo;library-description=bar;library-version=1");
            libraryInfo = new LLA4.CK_INFO();
            libraryInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion = new LLA4.CK_VERSION() { Major = new byte[] { 0x01 }, Minor = new byte[] { 0x00 } };
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

            // LibraryManufacturer nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:library-manufacturer=foo;library-description=bar;library-version=1");
            libraryInfo = new LLA4.CK_INFO();
            libraryInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion = new LLA4.CK_VERSION() { Major = new byte[] { 0x01 }, Minor = new byte[] { 0x00 } };
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

            // LibraryDescription nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:library-manufacturer=foo;library-description=bar;library-version=1");
            libraryInfo = new LLA4.CK_INFO();
            libraryInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryVersion = new LLA4.CK_VERSION() { Major = new byte[] { 0x01 }, Minor = new byte[] { 0x00 } };
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));

            // LibraryVersion nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:library-manufacturer=foo;library-description=bar;library-version=1");
            libraryInfo = new LLA4.CK_INFO();
            libraryInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion = new LLA4.CK_VERSION() { Major = new byte[] { 0x00 }, Minor = new byte[] { 0x01 } };
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));
        }
        public void GetObjectAttributesLLA4()
        {
            string uri = @"pkcs11:object=foo;type=private;id=%01%02%03";

            Pkcs11Uri pkcs11uri = new Pkcs11Uri(uri);

            LLA4.CK_ATTRIBUTE[] attributes = null;
            Pkcs11UriUtils.GetObjectAttributes(pkcs11uri, out attributes);

            Assert.IsTrue(attributes != null);
            Assert.IsTrue(attributes.Length == 3);

            Assert.IsTrue(attributes[0].type == (uint)CKA.CKA_CLASS);
            uint ckaClass = 0;
            LLA4.CkaUtils.ConvertValue(ref attributes[0], out ckaClass);
            Assert.IsTrue(ckaClass == (uint)CKO.CKO_PRIVATE_KEY);

            Assert.IsTrue(attributes[1].type == (uint)CKA.CKA_LABEL);
            string ckaLabel = null;
            LLA4.CkaUtils.ConvertValue(ref attributes[1], out ckaLabel);
            Assert.IsTrue(ckaLabel == "foo");

            Assert.IsTrue(attributes[2].type == (uint)CKA.CKA_ID);
            byte[] ckaId = null;
            LLA4.CkaUtils.ConvertValue(ref attributes[2], out ckaId);
            Assert.IsTrue(Helpers.ByteArraysMatch(ckaId, new byte[] { 0x01, 0x02, 0x03 }));
        }
        public void GetObjectAttributesHLA4()
        {
            string uri = @"pkcs11:object=foo;type=private;id=%01%02%03";

            Pkcs11Uri pkcs11uri = new Pkcs11Uri(uri);

            List<HLA4.ObjectAttribute> attributes = null;
            Pkcs11UriUtils.GetObjectAttributes(pkcs11uri, out attributes);

            Assert.IsTrue(attributes != null);
            Assert.IsTrue(attributes.Count == 3);

            Assert.IsTrue(attributes[0].Type == (uint)CKA.CKA_CLASS);
            Assert.IsTrue(attributes[0].GetValueAsUint() == (uint)CKO.CKO_PRIVATE_KEY);

            Assert.IsTrue(attributes[1].Type == (uint)CKA.CKA_LABEL);
            Assert.IsTrue(attributes[1].GetValueAsString() == "foo");

            Assert.IsTrue(attributes[2].Type == (uint)CKA.CKA_ID);
            Assert.IsTrue(Helpers.ByteArraysMatch(attributes[2].GetValueAsByteArray(), new byte[] { 0x01, 0x02, 0x03 }));
        }
        public void GetMatchingSlotListLLA4()
        {
            // Skip test on incompatible platforms
            if (UnmanagedLong.Size != 4)
                return;

            using (LLA4.Pkcs11 pkcs11 = new LLA4.Pkcs11(Settings.Pkcs11LibraryPath, false))
            {
                CKR rv = pkcs11.C_Initialize(null);
                Assert.IsTrue(rv == CKR.CKR_OK);

                // Get all slots
                uint allSlotsCount = 0;
                rv = pkcs11.C_GetSlotList(true, null, ref allSlotsCount);
                Assert.IsTrue(rv == CKR.CKR_OK);
                Assert.IsTrue(allSlotsCount > 0);
                uint[] allSlots = new uint[allSlotsCount];
                rv = pkcs11.C_GetSlotList(true, allSlots, ref allSlotsCount);
                Assert.IsTrue(rv == CKR.CKR_OK);

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                uint[] matchedSlots = null;
                rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true, out matchedSlots);
                Assert.IsTrue(rv == CKR.CKR_OK);
                Assert.IsTrue(matchedSlots.Length == allSlots.Length);

                // Unknown path attribute in URI
                pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar");
                rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true, out matchedSlots);
                Assert.IsTrue(rv == CKR.CKR_OK);
                Assert.IsTrue(matchedSlots.Length == 0);

                // All attributes matching one slot
                LLA4.CK_INFO libraryInfo = new LLA4.CK_INFO();
                rv = pkcs11.C_GetInfo(ref libraryInfo);
                Assert.IsTrue(rv == CKR.CKR_OK);
                LLA4.CK_SLOT_INFO slotInfo = new LLA4.CK_SLOT_INFO();
                rv = pkcs11.C_GetSlotInfo(allSlots[0], ref slotInfo);
                Assert.IsTrue(rv == CKR.CKR_OK);
                LLA4.CK_TOKEN_INFO tokenInfo = new LLA4.CK_TOKEN_INFO();
                rv = pkcs11.C_GetTokenInfo(allSlots[0], ref tokenInfo);
                Assert.IsTrue(rv == CKR.CKR_OK);

                Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = ConvertUtils.BytesToUtf8String(libraryInfo.ManufacturerId, true);
                pkcs11UriBuilder.LibraryDescription = ConvertUtils.BytesToUtf8String(libraryInfo.LibraryDescription, true);
                pkcs11UriBuilder.LibraryVersion = ConvertUtils.CkVersionToString(libraryInfo.LibraryVersion);
                pkcs11UriBuilder.SlotManufacturer = ConvertUtils.BytesToUtf8String(slotInfo.ManufacturerId, true);
                pkcs11UriBuilder.SlotDescription = ConvertUtils.BytesToUtf8String(slotInfo.SlotDescription, true);
                pkcs11UriBuilder.SlotId = allSlots[0];
                pkcs11UriBuilder.Token = ConvertUtils.BytesToUtf8String(tokenInfo.Label, true);
                pkcs11UriBuilder.Manufacturer = ConvertUtils.BytesToUtf8String(tokenInfo.ManufacturerId, true);
                pkcs11UriBuilder.Serial = ConvertUtils.BytesToUtf8String(tokenInfo.SerialNumber, true);
                pkcs11UriBuilder.Model = ConvertUtils.BytesToUtf8String(tokenInfo.Model, true);
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();

                rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true, out matchedSlots);
                Assert.IsTrue(rv == CKR.CKR_OK);
                Assert.IsTrue(matchedSlots.Length == 1);

                // One attribute nonmatching
                pkcs11UriBuilder.Serial = "foobar";
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true, out matchedSlots);
                Assert.IsTrue(rv == CKR.CKR_OK);
                Assert.IsTrue(matchedSlots.Length == 0);

                rv = pkcs11.C_Finalize(IntPtr.Zero);
                Assert.IsTrue(rv == CKR.CKR_OK);
            }
        }
        public void GetMatchingSlotListHLA4()
        {
            // Skip test on incompatible platforms
            if (UnmanagedLong.Size != 4)
                return;

            using (HLA4.Pkcs11 pkcs11 = new HLA4.Pkcs11(Settings.Pkcs11LibraryPath, false))
            {
                // Get all slots
                List<HLA4.Slot> allSlots = pkcs11.GetSlotList(true);
                Assert.IsTrue(allSlots != null && allSlots.Count > 0);

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                List<HLA4.Slot> matchedSlots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true);
                Assert.IsTrue(matchedSlots.Count == allSlots.Count);

                // Unknown path attribute in URI
                pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar");
                matchedSlots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true);
                Assert.IsTrue(matchedSlots.Count == 0);

                // All attributes matching one slot
                HLA4.LibraryInfo libraryInfo = pkcs11.GetInfo();
                HLA4.SlotInfo slotInfo = allSlots[0].GetSlotInfo();
                HLA4.TokenInfo tokenInfo = allSlots[0].GetTokenInfo();

                Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = libraryInfo.ManufacturerId;
                pkcs11UriBuilder.LibraryDescription = libraryInfo.LibraryDescription;
                pkcs11UriBuilder.LibraryVersion = libraryInfo.LibraryVersion;
                pkcs11UriBuilder.SlotManufacturer = slotInfo.ManufacturerId;
                pkcs11UriBuilder.SlotDescription = slotInfo.SlotDescription;
                pkcs11UriBuilder.SlotId = slotInfo.SlotId;
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();

                matchedSlots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true);
                Assert.IsTrue(matchedSlots.Count == 1);

                // One attribute nonmatching
                pkcs11UriBuilder.Serial = "foobar";
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                matchedSlots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true);
                Assert.IsTrue(matchedSlots.Count == 0);
            }
        }
        public void _03_SlotInfoMatches()
        {
            if (Platform.UnmanagedLongSize != 4 || Platform.StructPackingSize != 1)
                Assert.Inconclusive("Test cannot be executed on this platform");

            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, Settings.UseOsLocking))
            {
                List<Slot> slots = pkcs11.GetSlotList(true);
                Assert.IsTrue(slots != null && slots.Count > 0);
                SlotInfo slotInfo = slots[0].GetSlotInfo();

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // Unknown path attribute in URI
                pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar");
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // All attributes matching
                Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.SlotManufacturer = slotInfo.ManufacturerId;
                pkcs11UriBuilder.SlotDescription = slotInfo.SlotDescription;
                pkcs11UriBuilder.SlotId = slotInfo.SlotId;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // Manufacturer nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.SlotManufacturer = "foobar";
                pkcs11UriBuilder.SlotDescription = slotInfo.SlotDescription;
                pkcs11UriBuilder.SlotId = slotInfo.SlotId;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // Description nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.SlotManufacturer = slotInfo.ManufacturerId;
                pkcs11UriBuilder.SlotDescription = "foobar";
                pkcs11UriBuilder.SlotId = slotInfo.SlotId;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));

                // Slot id nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.SlotManufacturer = slotInfo.ManufacturerId;
                pkcs11UriBuilder.SlotDescription = slotInfo.SlotDescription;
                pkcs11UriBuilder.SlotId = slotInfo.SlotId + 1;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo));
            }
        }
        public void _07_GetObjectAttributes()
        {
            if (Platform.UnmanagedLongSize != 4 || Platform.StructPackingSize != 1)
                Assert.Inconclusive("Test cannot be executed on this platform");

            string uri = @"pkcs11:object=foo;type=private;id=%01%02%03";

            Pkcs11Uri pkcs11uri = new Pkcs11Uri(uri);

            List<ObjectAttribute> attributes = null;
            Pkcs11UriUtils.GetObjectAttributes(pkcs11uri, out attributes);

            Assert.IsTrue(attributes != null);
            Assert.IsTrue(attributes.Count == 3);

            Assert.IsTrue(attributes[0].Type == (uint)CKA.CKA_CLASS);
            Assert.IsTrue(attributes[0].GetValueAsUint() == (uint)CKO.CKO_PRIVATE_KEY);

            Assert.IsTrue(attributes[1].Type == (uint)CKA.CKA_LABEL);
            Assert.IsTrue(attributes[1].GetValueAsString() == "foo");

            Assert.IsTrue(attributes[2].Type == (uint)CKA.CKA_ID);
            Assert.IsTrue(Common.Helpers.ByteArraysMatch(attributes[2].GetValueAsByteArray(), new byte[] { 0x01, 0x02, 0x03 }));
        }
        public void SlotInfoMatchesLLA4()
        {
            // Empty URI
            Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            LLA4.CK_SLOT_INFO slotInfo = new LLA4.CK_SLOT_INFO();
            slotInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            uint slotId = 1;
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo, slotId));

            // Empty attribute
            pkcs11uri = new Pkcs11Uri(@"pkcs11:slot-manufacturer=;slot-description=bar;slot-id=1");
            slotInfo = new LLA4.CK_SLOT_INFO();
            slotInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("                                ");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            slotId = 1;
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo, slotId));

            // Unknown path attribute in URI
            pkcs11uri = new Pkcs11Uri(@"pkcs11:slot-manufacturer=foo;slot-description=bar;slot-id=1;foo=bar");
            slotInfo = new LLA4.CK_SLOT_INFO();
            slotInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            slotId = 1;
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo, slotId));

            // All attributes matching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:slot-manufacturer=foo;slot-description=bar;slot-id=1");
            slotInfo = new LLA4.CK_SLOT_INFO();
            slotInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            slotId = 1;
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo, slotId));

            // Manufacturer nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:slot-manufacturer=foo;slot-description=bar;slot-id=1");
            slotInfo = new LLA4.CK_SLOT_INFO();
            slotInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            slotId = 1;
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo, slotId));

            // Description nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:slot-manufacturer=foo;slot-description=bar;slot-id=1");
            slotInfo = new LLA4.CK_SLOT_INFO();
            slotInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("foo");
            slotId = 1;
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo, slotId));

            // Slot id nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:slot-manufacturer=foo;slot-description=bar;slot-id=1");
            slotInfo = new LLA4.CK_SLOT_INFO();
            slotInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            slotId = 2;
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo, slotId));
        }
        public void TokenInfoMatchesLLA4()
        {
            // Empty URI
            Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            LLA4.CK_TOKEN_INFO tokenInfo = new LLA4.CK_TOKEN_INFO();
            tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo");
            tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar");
            tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123");
            tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar");
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

            // Empty attribute
            pkcs11uri = new Pkcs11Uri(@"pkcs11:token=;manufacturer=bar;serial=123;model=foobar");
            tokenInfo = new LLA4.CK_TOKEN_INFO();
            tokenInfo.Label = ConvertUtils.Utf8StringToBytes("                                ");
            tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar");
            tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123");
            tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar");
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

            // Unknown path attribute in URI
            pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar;foo=bar");
            tokenInfo = new LLA4.CK_TOKEN_INFO();
            tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo");
            tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar");
            tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123");
            tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar");
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

            // All attributes matching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar");
            tokenInfo = new LLA4.CK_TOKEN_INFO();
            tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo");
            tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar");
            tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123");
            tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar");
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

            // Label nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar");
            tokenInfo = new LLA4.CK_TOKEN_INFO();
            tokenInfo.Label = ConvertUtils.Utf8StringToBytes("bar");
            tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar");
            tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123");
            tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar");
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

            // ManufacturerId nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar");
            tokenInfo = new LLA4.CK_TOKEN_INFO();
            tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo");
            tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo");
            tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123");
            tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar");
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

            // SerialNumber nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar");
            tokenInfo = new LLA4.CK_TOKEN_INFO();
            tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo");
            tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar");
            tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("012");
            tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar");
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

            // Model nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar");
            tokenInfo = new LLA4.CK_TOKEN_INFO();
            tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo");
            tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar");
            tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123");
            tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foo bar");
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));
        }
        public void TokenInfoMatchesHLA4()
        {
            // Skip test on incompatible platforms
            if (UnmanagedLong.Size != 4)
                return;

            using (HLA4.Pkcs11 pkcs11 = new HLA4.Pkcs11(Settings.Pkcs11LibraryPath, false))
            {
                List<HLA4.Slot> slots = pkcs11.GetSlotList(true);
                Assert.IsTrue(slots != null && slots.Count > 0);
                HLA4.TokenInfo tokenInfo = slots[0].GetTokenInfo();

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Unknown path attribute in URI
                pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar");
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // All attributes matching
                Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Token nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = "foobar";
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Manufacturer nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = "foobar";
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Serial nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = "foobar";
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));

                // Model nonmatching
                pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = "foobar";
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo));
            }
        }
        public void _05_ObjectAttributesMatches()
        {
            if (Platform.UnmanagedLongSize != 4 || Platform.StructPackingSize != 1)
                Assert.Inconclusive("Test cannot be executed on this platform");

            // Empty URI
            Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Empty attribute
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=;id=%01%02%03");
            objectAttributes = new List<ObjectAttribute>();
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, string.Empty));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Unknown path attribute in URI
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03;foo=bar");
            objectAttributes = new List<ObjectAttribute>();
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // All attributes matching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
            objectAttributes = new List<ObjectAttribute>();
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Type nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
            objectAttributes = new List<ObjectAttribute>();
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Object nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
            objectAttributes = new List<ObjectAttribute>();
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "foo bar"));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Id nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
            objectAttributes = new List<ObjectAttribute>();
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x04, 0x05, 0x06 }));
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            try
            {
                // Type present in URI but missing in list
                pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
                objectAttributes = new List<ObjectAttribute>();
                objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "foobar"));
                objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
                Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes);
                Assert.Fail("Exception expected but not thrown");
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is Pkcs11UriException);
            }

            try
            {
                // Object present in URI but missing in list
                pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
                objectAttributes = new List<ObjectAttribute>();
                objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
                objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
                Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes);
                Assert.Fail("Exception expected but not thrown");
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is Pkcs11UriException);
            }

            try
            {
                // Id present in URI but missing in list
                pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
                objectAttributes = new List<ObjectAttribute>();
                objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
                objectAttributes.Add(new ObjectAttribute(CKA.CKA_ID, new byte[] { 0x04, 0x05, 0x06 }));
                Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes);
                Assert.Fail("Exception expected but not thrown");
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is Pkcs11UriException);
            }
        }
        public void ObjectAttributesMatchesHLA()
        {
            // Empty URI
            Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            List<HLA.ObjectAttribute> objectAttributes = new List<HLA.ObjectAttribute>();
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Empty attribute
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=;id=%01%02%03");
            objectAttributes = new List<HLA.ObjectAttribute>();
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_LABEL, string.Empty));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Unknown path attribute in URI
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03;foo=bar");
            objectAttributes = new List<HLA.ObjectAttribute>();
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // All attributes matching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
            objectAttributes = new List<HLA.ObjectAttribute>();
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Type nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
            objectAttributes = new List<HLA.ObjectAttribute>();
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Object nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
            objectAttributes = new List<HLA.ObjectAttribute>();
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_LABEL, "foo bar"));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            // Id nonmatching
            pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
            objectAttributes = new List<HLA.ObjectAttribute>();
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x04, 0x05, 0x06 }));
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes));

            try
            {
                // Type present in URI but missing in list
                pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
                objectAttributes = new List<HLA.ObjectAttribute>();
                objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_LABEL, "foobar"));
                objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
                Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes);
                Assert.Fail("Exception expected but not thrown");
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is Pkcs11UriException);
            }

            try
            {
                // Object present in URI but missing in list
                pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
                objectAttributes = new List<HLA.ObjectAttribute>();
                objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
                objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 }));
                Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes);
                Assert.Fail("Exception expected but not thrown");
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is Pkcs11UriException);
            }

            try
            {
                // Id present in URI but missing in list
                pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03");
                objectAttributes = new List<HLA.ObjectAttribute>();
                objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
                objectAttributes.Add(new HLA.ObjectAttribute(CKA.CKA_ID, new byte[] { 0x04, 0x05, 0x06 }));
                Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes);
                Assert.Fail("Exception expected but not thrown");
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is Pkcs11UriException);
            }
        }
        public void _06_GetMatchingSlotList()
        {
            if (Platform.UnmanagedLongSize != 4 || Platform.StructPackingSize != 1)
                Assert.Inconclusive("Test cannot be executed on this platform");

            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, Settings.UseOsLocking))
            {
                // Get all slots
                List<Slot> allSlots = pkcs11.GetSlotList(true);
                Assert.IsTrue(allSlots != null && allSlots.Count > 0);

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                List<Slot> matchedSlots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true);
                Assert.IsTrue(matchedSlots.Count == allSlots.Count);

                // Unknown path attribute in URI
                pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar");
                matchedSlots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true);
                Assert.IsTrue(matchedSlots.Count == 0);

                // All attributes matching one slot
                LibraryInfo libraryInfo = pkcs11.GetInfo();
                SlotInfo slotInfo = allSlots[0].GetSlotInfo();
                TokenInfo tokenInfo = allSlots[0].GetTokenInfo();

                Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                pkcs11UriBuilder.LibraryManufacturer = libraryInfo.ManufacturerId;
                pkcs11UriBuilder.LibraryDescription = libraryInfo.LibraryDescription;
                pkcs11UriBuilder.LibraryVersion = libraryInfo.LibraryVersion;
                pkcs11UriBuilder.SlotManufacturer = slotInfo.ManufacturerId;
                pkcs11UriBuilder.SlotDescription = slotInfo.SlotDescription;
                pkcs11UriBuilder.SlotId = slotInfo.SlotId;
                pkcs11UriBuilder.Token = tokenInfo.Label;
                pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                pkcs11UriBuilder.Model = tokenInfo.Model;
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();

                matchedSlots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true);
                Assert.IsTrue(matchedSlots.Count == 1);

                // One attribute nonmatching
                pkcs11UriBuilder.Serial = "foobar";
                pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri();
                matchedSlots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11, true);
                Assert.IsTrue(matchedSlots.Count == 0);
            }
        }