GetSlotList() публичный Метод

Obtains a list of slots in the system
public GetSlotList ( bool tokenPresent ) : List
tokenPresent bool Flag indicating whether the list obtained includes only those slots with a token present (true), or all slots (false)
Результат List
Пример #1
0
 public static Slot slots()
 {
     if (pk.GetSlotList(true).Count == 1)
     {
         return(pk.GetSlotList(true)[0]);
     }
     else
     {
         return(pk.GetSlotList(true)[1]);
     }
 }
Пример #2
0
        /// <summary>
        /// Obtains a list of all PKCS#11 URI matching slots
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="pkcs11">High level PKCS#11 wrapper</param>
        /// <param name="tokenPresent">Flag indicating whether the list obtained includes only those slots with a token present (true), or all slots (false)</param>
        /// <returns>List of slots matching PKCS#11 URI</returns>
        public static List <Slot> GetMatchingSlotList(Pkcs11Uri pkcs11Uri, Pkcs11 pkcs11, bool tokenPresent)
        {
            if (pkcs11Uri == null)
            {
                throw new ArgumentNullException("pkcs11Uri");
            }

            if (pkcs11 == null)
            {
                throw new ArgumentNullException("pkcs11");
            }

            List <Slot> matchingSlots = new List <Slot>();

            LibraryInfo libraryInfo = pkcs11.GetInfo();

            if (!Matches(pkcs11Uri, libraryInfo))
            {
                return(matchingSlots);
            }

            List <Slot> slots = pkcs11.GetSlotList(false);

            if ((slots == null) || (slots.Count == 0))
            {
                return(slots);
            }

            foreach (Slot slot in slots)
            {
                SlotInfo slotInfo = slot.GetSlotInfo();
                if (Matches(pkcs11Uri, slotInfo))
                {
                    if (slotInfo.SlotFlags.TokenPresent)
                    {
                        TokenInfo tokenInfo = slot.GetTokenInfo();
                        if (Matches(pkcs11Uri, tokenInfo))
                        {
                            matchingSlots.Add(slot);
                        }
                    }
                    else
                    {
                        if (!tokenPresent && Pkcs11UriSharedUtils.Matches(pkcs11Uri, null, null, null, null))
                        {
                            matchingSlots.Add(slot);
                        }
                    }
                }
            }

            return(matchingSlots);
        }
        public void _01_SlotListTest()
        {
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, Settings.UseOsLocking))
            {
                // Get list of available slots
                List<Slot> slots = pkcs11.GetSlotList(false);

                // Do something interesting with slots
                Assert.IsNotNull(slots);
                Assert.IsTrue(slots.Count > 0);
            }
        }
Пример #4
0
        /// <summary>
        /// Finds slot containing the token that matches criteria specified in Settings class
        /// </summary>
        /// <param name='pkcs11'>Initialized PKCS11 wrapper</param>
        /// <returns>Slot containing the token that matches criteria</returns>
        public static Slot GetUsableSlot(Pkcs11 pkcs11)
        {
            // Get list of available slots with token present
            List<Slot> slots = pkcs11.GetSlotList(true);

            Assert.IsNotNull(slots);
            Assert.IsTrue(slots.Count > 0);

            // First slot with token present is OK...
            Slot matchingSlot = slots[0];

            // ...unless there are matching criteria specified in Settings class
            if (Settings.TokenSerial != null || Settings.TokenLabel != null)
            {
                matchingSlot = null;

                foreach (Slot slot in slots)
                {
                    TokenInfo tokenInfo = null;

                    try
                    {
                        tokenInfo = slot.GetTokenInfo();
                    }
                    catch (Pkcs11Exception ex)
                    {
                        if (ex.RV != CKR.CKR_TOKEN_NOT_RECOGNIZED && ex.RV != CKR.CKR_TOKEN_NOT_PRESENT)
                            throw;
                    }

                    if (tokenInfo == null)
                        continue;

                    if (!string.IsNullOrEmpty(Settings.TokenSerial))
                        if (0 != string.Compare(Settings.TokenSerial, tokenInfo.SerialNumber, StringComparison.Ordinal))
                            continue;

                    if (!string.IsNullOrEmpty(Settings.TokenLabel))
                        if (0 != string.Compare(Settings.TokenLabel, tokenInfo.Label, StringComparison.Ordinal))
                            continue;

                    matchingSlot = slot;
                    break;
                }
            }

            Assert.IsTrue(matchingSlot != null, "Token matching criteria specified in Settings class is not present");
            return matchingSlot;
        }
        public void _02_BasicSlotListAndInfoTest()
        {
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, Settings.UseOsLocking))
            {
                // Get list of available slots
                List<Slot> slots = pkcs11.GetSlotList(false);
                
                // Do something interesting with slots
                Assert.IsNotNull(slots);
                Assert.IsTrue(slots.Count > 0);

                // Analyze first slot
                SlotInfo slotInfo = slots[0].GetSlotInfo();

                // Do something interesting with slot info
                Assert.IsNotNull(slotInfo.ManufacturerId);
            }
        }
Пример #6
0
        /// <summary>
        /// Finds slot containing the token that matches specified criteria
        /// </summary>
        /// <param name="pkcs11">High level PKCS#11 wrapper</param>
        /// <param name="tokenSerial">Serial number of token that should be found</param>
        /// <param name="tokenLabel">Label of token that should be found</param>
        /// <returns>Slot containing the token that matches specified criteria</returns>urns>
        public static Slot FindSlot(Pkcs11 pkcs11, string tokenSerial, string tokenLabel)
        {
            if (string.IsNullOrEmpty(tokenSerial) && string.IsNullOrEmpty(tokenLabel))
                throw new ArgumentException("Token serial and/or label has to be specified");

            List<Slot> slots = pkcs11.GetSlotList(true);
            foreach (Slot slot in slots)
            {
                TokenInfo tokenInfo = slot.GetTokenInfo();

                if (!string.IsNullOrEmpty(tokenSerial))
                    if (0 != String.Compare(tokenSerial, tokenInfo.SerialNumber, StringComparison.InvariantCultureIgnoreCase))
                        continue;

                if (!string.IsNullOrEmpty(tokenLabel))
                    if (0 != String.Compare(tokenLabel, tokenInfo.Label, StringComparison.InvariantCultureIgnoreCase))
                        continue;

                return slot;
            }

            return null;
        }
Пример #7
0
        public void TokenInfoMatchesHLA()
        {
            using (HLA.Pkcs11 pkcs11 = new HLA.Pkcs11(Settings.Pkcs11LibraryPath, false))
            {
                List<HLA.Slot> slots = pkcs11.GetSlotList(true);
                Assert.IsTrue(slots != null && slots.Count > 0);
                HLA.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));
            }
        }
Пример #8
0
        public void SlotInfoMatchesHLA()
        {
            using (HLA.Pkcs11 pkcs11 = new HLA.Pkcs11(Settings.Pkcs11LibraryPath, false))
            {
                List<HLA.Slot> slots = pkcs11.GetSlotList(true);
                Assert.IsTrue(slots != null && slots.Count > 0);
                HLA.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));
            }
        }
Пример #9
0
        public void GetMatchingSlotListHLA()
        {
            using (HLA.Pkcs11 pkcs11 = new HLA.Pkcs11(Settings.Pkcs11LibraryPath, false))
            {
                // Get all slots
                List<HLA.Slot> allSlots = pkcs11.GetSlotList(true);
                Assert.IsTrue(allSlots != null && allSlots.Count > 0);

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                List<HLA.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
                HLA.LibraryInfo libraryInfo = pkcs11.GetInfo();
                HLA.SlotInfo slotInfo = allSlots[0].GetSlotInfo();
                HLA.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);
            }
        }
Пример #10
0
        /// <summary>
        /// Obtains a list of all PKCS#11 URI matching slots
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="pkcs11">High level PKCS#11 wrapper</param>
        /// <param name="tokenPresent">Flag indicating whether the list obtained includes only those slots with a token present (true), or all slots (false)</param>
        /// <returns>List of slots matching PKCS#11 URI</returns>
        public static List<Slot> GetMatchingSlotList(Pkcs11Uri pkcs11Uri, Pkcs11 pkcs11, bool tokenPresent)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            List<Slot> matchingSlots = new List<Slot>();

            LibraryInfo libraryInfo = pkcs11.GetInfo();
            if (!Matches(pkcs11Uri, libraryInfo))
                return matchingSlots;

            List<Slot> slots = pkcs11.GetSlotList(false);
            if ((slots == null) || (slots.Count == 0))
                return slots;

            foreach (Slot slot in slots)
            {
                SlotInfo slotInfo = slot.GetSlotInfo();
                if (Matches(pkcs11Uri, slotInfo))
                {
                    if (slotInfo.SlotFlags.TokenPresent)
                    {
                        TokenInfo tokenInfo = slot.GetTokenInfo();
                        if (Matches(pkcs11Uri, tokenInfo))
                            matchingSlots.Add(slot);
                    }
                    else
                    {
                        if (!tokenPresent && Pkcs11UriSharedUtils.Matches(pkcs11Uri, null, null, null, null))
                            matchingSlots.Add(slot);
                    }
                }
            }

            return matchingSlots;
        }
        public void EnablePinTest()
        {
            DeleteEnvironmentVariables();

            uint flags = 0;

            // Delete log file
            if (File.Exists(Settings.Pkcs11LoggerLogPath1))
                File.Delete(Settings.Pkcs11LoggerLogPath1);

            // Log to Pkcs11LoggerLogPath1 with PIN logging disabled
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath);
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1);
            flags = flags & ~PKCS11_LOGGER_FLAG_ENABLE_PIN;
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_FLAGS, Convert.ToString(flags));
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LoggerLibraryPath, true))
            using (Session session = pkcs11.GetSlotList(true)[0].OpenSession(true))
                session.Login(CKU.CKU_USER, Settings.NormalUserPin);

            Assert.IsTrue(File.ReadAllText(Settings.Pkcs11LoggerLogPath1).Contains(" *pPin: *** Intentionally hidden ***"));

            // Delete log file
            File.Delete(Settings.Pkcs11LoggerLogPath1);

            // Log to Pkcs11LoggerLogPath1 with PIN logging enabled
            flags = flags | PKCS11_LOGGER_FLAG_ENABLE_PIN;
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_FLAGS, Convert.ToString(flags));
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LoggerLibraryPath, true))
            using (Session session = pkcs11.GetSlotList(true)[0].OpenSession(true))
                session.Login(CKU.CKU_USER, Settings.NormalUserPin);

            Assert.IsTrue(File.ReadAllText(Settings.Pkcs11LoggerLogPath1).Contains(" *pPin: " + Settings.NormalUserPin));
        }
        public void EnableFclosePerformanceTest()
        {
            DeleteEnvironmentVariables();

            uint flags = 0;
            int fcloseDisabledTicks = 0;
            int fcloseEnabledTicks = 0;

            // Delete log file
            if (File.Exists(Settings.Pkcs11LoggerLogPath1))
                File.Delete(Settings.Pkcs11LoggerLogPath1);

            // Log to Pkcs11LoggerLogPath1 with fclose disabled
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath);
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1);
            flags = flags & ~PKCS11_LOGGER_FLAG_ENABLE_FCLOSE;
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_FLAGS, Convert.ToString(flags));
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LoggerLibraryPath, true))
            {
                int tickCountStart = Environment.TickCount;

                for (int i = 0; i < 10; i++)
                {
                    pkcs11.GetInfo();
                    foreach (Slot slot in pkcs11.GetSlotList(true))
                    {
                        slot.GetTokenInfo();
                        foreach (CKM mechanism in slot.GetMechanismList())
                        {
                            slot.GetMechanismInfo(mechanism);
                        }
                    }
                }

                int tickCountStop = Environment.TickCount;
                fcloseDisabledTicks = tickCountStop - tickCountStart;
            }

            // Delete log file
            if (File.Exists(Settings.Pkcs11LoggerLogPath1))
                File.Delete(Settings.Pkcs11LoggerLogPath1);

            // Log to Pkcs11LoggerLogPath1 with fclose enabled
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath);
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1);
            flags = flags | PKCS11_LOGGER_FLAG_ENABLE_FCLOSE;
            System.Environment.SetEnvironmentVariable(PKCS11_LOGGER_FLAGS, Convert.ToString(flags));
            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LoggerLibraryPath, true))
            {
                int tickCountStart = Environment.TickCount;

                for (int i = 0; i < 10; i++)
                {
                    pkcs11.GetInfo();
                    foreach (Slot slot in pkcs11.GetSlotList(true))
                    {
                        slot.GetTokenInfo();
                        foreach (CKM mechanism in slot.GetMechanismList())
                        {
                            slot.GetMechanismInfo(mechanism);
                        }
                    }
                }

                int tickCountStop = Environment.TickCount;
                fcloseEnabledTicks = tickCountStop - tickCountStart;
            }

            // Delete log file
            if (File.Exists(Settings.Pkcs11LoggerLogPath1))
                File.Delete(Settings.Pkcs11LoggerLogPath1);

            // PKCS11_LOGGER_FLAG_ENABLE_FCLOSE decreases performance
            Assert.IsTrue(fcloseEnabledTicks > fcloseDisabledTicks);
        }
Пример #13
0
        /// <summary>
        /// Main method specifying where program execution is to begin
        /// </summary>
        /// <param name="args">Command line arguments passed to the program</param>
        static void Main(string[] args)
        {
            try
            {
                // Parse command line arguments
                string uri = null;
                int listSlots = 0;
                int listTokens = 0;
                int listObjects = 0;

                if (args.Length == 0)
                    ExitWithHelp(null);

                int i = 0;
                while (i < args.Length)
                {
                    switch (args[i])
                    {
                        case _argUri:
                            uri = args[++i];
                            break;
                        case _argListSlots:
                            listSlots = 1;
                            break;
                        case _argListTokens:
                            listTokens = 1;
                            break;
                        case _argListObjects:
                            listObjects = 1;
                            break;
                        default:
                            ExitWithHelp("Invalid argument: " + args[i]);
                            break;
                    }

                    i++;
                }

                // Validate operation modes
                if (listSlots + listTokens + listObjects != 1)
                    ExitWithHelp(string.Format("Argument \"{0}\", \"{1}\" or \"{2}\" has to be specified", _argListSlots, _argListTokens, _argListObjects));

                #region List slots

                // Handle "--list-slots" operation mode
                if (listSlots == 1)
                {
                    // Validate command line arguments
                    if (string.IsNullOrEmpty(uri))
                        ExitWithHelp("Required argument: " + _argUri);

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

                    // Verify that URI contains "module-path" attribute
                    if (string.IsNullOrEmpty(pkcs11Uri.ModulePath))
                        throw new Exception("PKCS#11 URI does not specify PKCS#11 library");

                    // Load and initialize PKCS#11 library specified by URI
                    using (Pkcs11 pkcs11 = new Pkcs11(pkcs11Uri.ModulePath, true))
                    {
                        Console.WriteLine("Listing available slots");

                        int j = 0;

                        //  Obtain a list of all slots
                        List<Slot> slots = pkcs11.GetSlotList(false);
                        foreach (Slot slot in slots)
                        {
                            j++;

                            // Obtain information about the particular slot
                            SlotInfo slotInfo = slot.GetSlotInfo();

                            // Build PKCS#11 URI for the particular slot
                            Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                            pkcs11UriBuilder.ModulePath = pkcs11Uri.ModulePath;
                            pkcs11UriBuilder.SlotManufacturer = slotInfo.ManufacturerId;
                            pkcs11UriBuilder.SlotDescription = slotInfo.SlotDescription;
                            pkcs11UriBuilder.SlotId = slotInfo.SlotId;

                            // Display slot information
                            Console.WriteLine();
                            Console.WriteLine("Slot no." + j);
                            Console.WriteLine("  Manufacturer:       " + slotInfo.ManufacturerId);
                            Console.WriteLine("  Description:        " + slotInfo.SlotDescription);
                            Console.WriteLine("  ID:                 " + slotInfo.SlotId);
                            Console.WriteLine("  PKCS#11 URI:        " + pkcs11UriBuilder.ToString());
                        }

                        Console.WriteLine();
                        Console.WriteLine(string.Format("Total number of listed slots: {0}", j));
                    }
                }

                #endregion

                #region List tokens

                // Handle "--list-tokens" operation mode
                if (listTokens == 1)
                {
                    // Validate command line arguments
                    if (string.IsNullOrEmpty(uri))
                        ExitWithHelp("Required argument: " + _argUri);

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

                    // Verify that URI contains "module-path" attribute
                    if (string.IsNullOrEmpty(pkcs11Uri.ModulePath))
                        throw new Exception("PKCS#11 URI does not specify PKCS#11 library");

                    // Load and initialize PKCS#11 library specified by URI
                    using (Pkcs11 pkcs11 = new Pkcs11(pkcs11Uri.ModulePath, true))
                    {
                        Console.WriteLine("Listing available tokens");

                        int j = 0;

                        //  Obtain a list of all slots with tokens
                        List<Slot> slots = pkcs11.GetSlotList(true);
                        foreach (Slot slot in slots)
                        {
                            j++;

                            // Obtain information about the particular token
                            TokenInfo tokenInfo = slot.GetTokenInfo();

                            // Build PKCS#11 URI for the particular token
                            Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder();
                            pkcs11UriBuilder.ModulePath = pkcs11Uri.ModulePath;
                            pkcs11UriBuilder.Token = tokenInfo.Label;
                            pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId;
                            pkcs11UriBuilder.Serial = tokenInfo.SerialNumber;
                            pkcs11UriBuilder.Model = tokenInfo.Model;

                            // Display token information
                            Console.WriteLine();
                            Console.WriteLine("Token no." + j);
                            Console.WriteLine("  Manufacturer:       " + tokenInfo.ManufacturerId);
                            Console.WriteLine("  Model:              " + tokenInfo.Model);
                            Console.WriteLine("  Serial number:      " + tokenInfo.SerialNumber);
                            Console.WriteLine("  Label:              " + tokenInfo.Label);
                            Console.WriteLine("  PKCS#11 URI:        " + pkcs11UriBuilder.ToString());
                        }

                        Console.WriteLine();
                        Console.WriteLine(string.Format("Total number of listed tokens: {0}", j));
                    }
                }

                #endregion

                #region List objects

                // Handle "--list-objects" operation mode
                if (listObjects == 1)
                {
                    // Validate command line arguments
                    if (string.IsNullOrEmpty(uri))
                        ExitWithHelp("Required argument: " + _argUri);

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

                    // Verify that URI contains "module-path" attribute
                    if (string.IsNullOrEmpty(pkcs11Uri.ModulePath))
                        throw new Exception("PKCS#11 URI does not specify PKCS#11 library");

                    // 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 matching provided URI
                        List<Slot> slots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11Uri, pkcs11, true);
                        if (slots.Count == 0)
                            throw new Exception("No token matches provided PKCS#11 URI");
                        if (slots.Count > 1)
                            throw new Exception("More than one token matches provided PKCS#11 URI");

                        // Obtain information about the token
                        TokenInfo tokenInfo = slots[0].GetTokenInfo();

                        Console.WriteLine(string.Format("Listing objects available on token with serial \"{0}\" and label \"{1}\"", tokenInfo.SerialNumber, tokenInfo.Label));

                        Pkcs11UriBuilder pkcs11UriBuilder = null;
                        List<ObjectAttribute> searchTemplate = null;
                        List<ObjectHandle> foundObjects = null;
                        List<CKA> attributes = null;
                        List<ObjectAttribute> objectAttributes = null;
                        int j = 0;

                        // Open RO session with token
                        using (Session session = slots[0].OpenSession(true))
                        {
                            // Login if PIN has been provided
                            if (pkcs11Uri.PinValue != null)
                                session.Login(CKU.CKU_USER, pkcs11Uri.PinValue);

                            #region List data objects

                            searchTemplate = new List<ObjectAttribute>();
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_DATA));

                            attributes = new List<CKA>();
                            attributes.Add(CKA.CKA_LABEL);

                            foundObjects = session.FindAllObjects(searchTemplate);
                            foreach (ObjectHandle foundObject in foundObjects)
                            {
                                j++;

                                objectAttributes = session.GetAttributeValue(foundObject, attributes);

                                pkcs11UriBuilder = new Pkcs11UriBuilder(pkcs11Uri);
                                pkcs11UriBuilder.Type = CKO.CKO_DATA;
                                pkcs11UriBuilder.Object = objectAttributes[0].GetValueAsString();
                                pkcs11UriBuilder.Id = null;

                                Console.WriteLine("");
                                Console.WriteLine("Object no." + j);
                                Console.WriteLine("  CKA_CLASS:             CKO_DATA");
                                Console.WriteLine("  CKA_LABEL:             " + pkcs11UriBuilder.Object);
                                Console.WriteLine("  PKCS#11 URI:           " + pkcs11UriBuilder.ToString());
                            }

                            #endregion

                            #region List private keys

                            searchTemplate = new List<ObjectAttribute>();
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));

                            attributes = new List<CKA>();
                            attributes.Add(CKA.CKA_ID);
                            attributes.Add(CKA.CKA_LABEL);
                            attributes.Add(CKA.CKA_KEY_TYPE);

                            foundObjects = session.FindAllObjects(searchTemplate);
                            foreach (ObjectHandle foundObject in foundObjects)
                            {
                                j++;

                                objectAttributes = session.GetAttributeValue(foundObject, attributes);

                                pkcs11UriBuilder = new Pkcs11UriBuilder(pkcs11Uri);
                                pkcs11UriBuilder.Type = CKO.CKO_PRIVATE_KEY;
                                pkcs11UriBuilder.Id = objectAttributes[0].GetValueAsByteArray();
                                pkcs11UriBuilder.Object = objectAttributes[1].GetValueAsString();
                                
                                Console.WriteLine("");
                                Console.WriteLine("Object no." + j);
                                Console.WriteLine("  CKA_CLASS:             CKO_PRIVATE_KEY");
                                Console.WriteLine("  CKA_ID:                " + ConvertUtils.BytesToHexString(pkcs11UriBuilder.Id));
                                Console.WriteLine("  CKA_LABEL:             " + pkcs11UriBuilder.Object);
                                Console.WriteLine("  CKA_KEY_TYPE:          " + ((CKK)objectAttributes[2].GetValueAsUlong()).ToString());
                                Console.WriteLine("  PKCS#11 URI:           " + pkcs11UriBuilder.ToString());
                            }

                            #endregion

                            #region List public keys

                            searchTemplate = new List<ObjectAttribute>();
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));

                            attributes = new List<CKA>();
                            attributes.Add(CKA.CKA_ID);
                            attributes.Add(CKA.CKA_LABEL);
                            attributes.Add(CKA.CKA_KEY_TYPE);

                            foundObjects = session.FindAllObjects(searchTemplate);
                            foreach (ObjectHandle foundObject in foundObjects)
                            {
                                j++;

                                objectAttributes = session.GetAttributeValue(foundObject, attributes);

                                pkcs11UriBuilder = new Pkcs11UriBuilder(pkcs11Uri);
                                pkcs11UriBuilder.Type = CKO.CKO_PUBLIC_KEY;
                                pkcs11UriBuilder.Id = objectAttributes[0].GetValueAsByteArray();
                                pkcs11UriBuilder.Object = objectAttributes[1].GetValueAsString();

                                Console.WriteLine("");
                                Console.WriteLine("Object no." + j);
                                Console.WriteLine("  CKA_CLASS:             CKO_PUBLIC_KEY");
                                Console.WriteLine("  CKA_ID:                " + ConvertUtils.BytesToHexString(pkcs11UriBuilder.Id));
                                Console.WriteLine("  CKA_LABEL:             " + pkcs11UriBuilder.Object);
                                Console.WriteLine("  CKA_KEY_TYPE:          " + ((CKK)objectAttributes[2].GetValueAsUlong()).ToString());
                                Console.WriteLine("  PKCS#11 URI:           " + pkcs11UriBuilder.ToString());
                            }

                            #endregion

                            #region List certificates

                            searchTemplate = new List<ObjectAttribute>();
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE));

                            attributes = new List<CKA>();
                            attributes.Add(CKA.CKA_ID);
                            attributes.Add(CKA.CKA_LABEL);
                            attributes.Add(CKA.CKA_CERTIFICATE_TYPE);
                            attributes.Add(CKA.CKA_VALUE);

                            foundObjects = session.FindAllObjects(searchTemplate);
                            foreach (ObjectHandle foundObject in foundObjects)
                            {
                                j++;

                                objectAttributes = session.GetAttributeValue(foundObject, attributes);

                                pkcs11UriBuilder = new Pkcs11UriBuilder(pkcs11Uri);
                                pkcs11UriBuilder.Type = CKO.CKO_CERTIFICATE;
                                pkcs11UriBuilder.Id = objectAttributes[0].GetValueAsByteArray();
                                pkcs11UriBuilder.Object = objectAttributes[1].GetValueAsString();

                                Console.WriteLine("");
                                Console.WriteLine("Object no." + j);
                                Console.WriteLine("  CKA_CLASS:             CKO_CERTIFICATE");
                                Console.WriteLine("  CKA_ID:                " + ConvertUtils.BytesToHexString(pkcs11UriBuilder.Id));
                                Console.WriteLine("  CKA_LABEL:             " + pkcs11UriBuilder.Object);
                                Console.WriteLine("  CKA_CERTIFICATE_TYPE:  " + ((CKC)objectAttributes[2].GetValueAsUlong()).ToString());

                                if (CKC.CKC_X_509 == (CKC)objectAttributes[2].GetValueAsUlong())
                                {
                                    X509Certificate2 x509Cert = new X509Certificate2(objectAttributes[3].GetValueAsByteArray());

                                    Console.WriteLine("  Serial number:         " + x509Cert.SerialNumber);
                                    Console.WriteLine("  Subject DN:            " + x509Cert.Subject);
                                    Console.WriteLine("  Issuer DN:             " + x509Cert.Issuer);
                                    Console.WriteLine("  Not before:            " + x509Cert.NotBefore);
                                    Console.WriteLine("  Not after:             " + x509Cert.NotAfter);
                                }

                                Console.WriteLine("  PKCS#11 URI:           " + pkcs11UriBuilder.ToString());
                            }

                            #endregion

                            #region List secret keys

                            searchTemplate = new List<ObjectAttribute>();
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
                            searchTemplate.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));

                            attributes = new List<CKA>();
                            attributes.Add(CKA.CKA_ID);
                            attributes.Add(CKA.CKA_LABEL);
                            attributes.Add(CKA.CKA_KEY_TYPE);

                            foundObjects = session.FindAllObjects(searchTemplate);
                            foreach (ObjectHandle foundObject in foundObjects)
                            {
                                j++;

                                objectAttributes = session.GetAttributeValue(foundObject, attributes);

                                pkcs11UriBuilder = new Pkcs11UriBuilder(pkcs11Uri);
                                pkcs11UriBuilder.Type = CKO.CKO_SECRET_KEY;
                                pkcs11UriBuilder.Id = objectAttributes[0].GetValueAsByteArray();
                                pkcs11UriBuilder.Object = objectAttributes[1].GetValueAsString();

                                Console.WriteLine("");
                                Console.WriteLine("Object no." + j);
                                Console.WriteLine("  CKA_CLASS:             CKO_SECRET_KEY");
                                Console.WriteLine("  CKA_ID:                " + ConvertUtils.BytesToHexString(pkcs11UriBuilder.Id));
                                Console.WriteLine("  CKA_LABEL:             " + pkcs11UriBuilder.Object);
                                Console.WriteLine("  CKA_KEY_TYPE:          " + ((CKK)objectAttributes[2].GetValueAsUlong()).ToString());
                                Console.WriteLine("  PKCS#11 URI:           " + pkcs11UriBuilder.ToString());
                            }

                            #endregion
                        }

                        Console.WriteLine();
                        Console.WriteLine(string.Format("Total number of listed objects: {0}", j));
                    }
                }

                #endregion
            }
            catch (Exception ex)
            {
                Console.WriteLine(@"Operation error: " + ex.GetType() + " - " + ex.Message);
                Console.WriteLine(ex.StackTrace);
                Environment.Exit(_exitError);
            }

            Environment.Exit(_exitSuccess);
        }