예제 #1
0
        /// <summary>
        /// Sets properties of Pkcs11UriBuilder class with default values specified by 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>
        private void ConstructFromPkcs11Uri(Pkcs11Uri pkcs11Uri, bool checkLengths)
        {
            if (pkcs11Uri == null)
                throw new ArgumentException("pkcs11Uri");

            _checkLengths = checkLengths;

            Token = pkcs11Uri.Token;
            Manufacturer = pkcs11Uri.Manufacturer;
            Serial = pkcs11Uri.Serial;
            Model = pkcs11Uri.Model;
            LibraryManufacturer = pkcs11Uri.LibraryManufacturer;
            LibraryDescription = pkcs11Uri.LibraryDescription;
            LibraryVersion = pkcs11Uri.LibraryVersion;
            Object = pkcs11Uri.Object;
            Type = pkcs11Uri.Type;
            Id = pkcs11Uri.Id;
            SlotManufacturer = pkcs11Uri.SlotManufacturer;
            SlotDescription = pkcs11Uri.SlotDescription;
            SlotId = pkcs11Uri.SlotId;
            UnknownPathAttributes = pkcs11Uri.UnknownPathAttributes;

            PinSource = pkcs11Uri.PinSource;
            PinValue = pkcs11Uri.PinValue;
            ModuleName = pkcs11Uri.ModuleName;
            ModulePath = pkcs11Uri.ModulePath;
            UnknownQueryAttributes = pkcs11Uri.UnknownQueryAttributes;
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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, HLA.LibraryInfo libraryInfo)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            return Matches(pkcs11Uri, libraryInfo.ManufacturerId, libraryInfo.LibraryDescription, libraryInfo.LibraryVersion);
        }
예제 #4
0
        /// <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>
        private static bool Matches(Pkcs11Uri pkcs11Uri, string libraryManufacturer, string libraryDescription, string libraryVersion)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            if (pkcs11Uri.UnknownPathAttributes != null)
                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;
        }
예제 #5
0
        /// <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<LLA4.CK_ATTRIBUTE> objectAttributes)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            uint ckaClassType = (uint)CKA.CKA_CLASS;
            CKO? ckaClassValue = null;
            bool ckaClassFound = false;

            uint ckaLabelType = (uint)CKA.CKA_LABEL;
            string ckaLabelValue = null;
            bool ckaLabelFound = false;

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

            foreach (LLA4.CK_ATTRIBUTE objectAttribute in objectAttributes)
            {
                LLA4.CK_ATTRIBUTE attribute = objectAttribute;

                if (attribute.type == ckaClassType)
                {
                    uint uintValue = 0;
                    LLA4.CkaUtils.ConvertValue(ref attribute, out uintValue);
                    ckaClassValue = (CKO)uintValue;
                    ckaClassFound = true;
                }
                else if (attribute.type == ckaLabelType)
                {
                    LLA4.CkaUtils.ConvertValue(ref attribute, out ckaLabelValue);
                    ckaLabelFound = true;
                }
                else if (objectAttribute.type == ckaIdType)
                {
                    LLA4.CkaUtils.ConvertValue(ref attribute, out ckaIdValue);
                    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 Matches(pkcs11Uri, ckaClassValue, ckaLabelValue, ckaIdValue);
        }
예제 #6
0
        /// <summary>
        /// Checks whether token information matches PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="tokenLabel">Token label</param>
        /// <param name="tokenManufacturer">Token manufacturer</param>
        /// <param name="tokenSerial">Token serial number</param>
        /// <param name="tokenModel">Token model</param>
        /// <returns>True if token information matches PKCS#11 URI</returns>
        private static bool Matches(Pkcs11Uri pkcs11Uri, string tokenLabel, string tokenManufacturer, string tokenSerial, string tokenModel)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            if (pkcs11Uri.UnknownPathAttributes != null)
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.Token, tokenLabel))
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.Manufacturer, tokenManufacturer))
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.Serial, tokenSerial))
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.Model, tokenModel))
                return false;

            return true;
        }
예제 #7
0
        /// <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, LLA4.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 Matches(pkcs11Uri, token, manufacturer, serial, model);
        }
예제 #8
0
        /// <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, LLA4.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 = ConvertUtils.CkVersionToString(libraryInfo.LibraryVersion);

            return Matches(pkcs11Uri, manufacturer, description, version);
        }
예제 #9
0
        /// <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, HLA4.SlotInfo slotInfo)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            return Matches(pkcs11Uri, slotInfo.ManufacturerId, slotInfo.SlotDescription, slotInfo.SlotId);
        }
예제 #10
0
        public void _04_TokenInfoMatches()
        {
            Helpers.CheckPlatform();

            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, Settings.AppType))
            {
                List <Slot> slots = pkcs11.GetSlotList(SlotsType.WithTokenPresent);
                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));
            }
        }
예제 #11
0
        /// <summary>
        /// Returns list of object attributes defined by PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="objectAttributes">List of object attributes defined by PKCS#11 URI</param>
        public static void GetObjectAttributes(Pkcs11Uri pkcs11Uri, out List<HLA4.ObjectAttribute> objectAttributes)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            List<HLA4.ObjectAttribute> attributes = null;

            if (pkcs11Uri.DefinesObject)
            {
                attributes = new List<HLA4.ObjectAttribute>();
                if (pkcs11Uri.Type != null)
                    attributes.Add(new HLA4.ObjectAttribute(CKA.CKA_CLASS, pkcs11Uri.Type.Value));
                if (pkcs11Uri.Object != null)
                    attributes.Add(new HLA4.ObjectAttribute(CKA.CKA_LABEL, pkcs11Uri.Object));
                if (pkcs11Uri.Id != null)
                    attributes.Add(new HLA4.ObjectAttribute(CKA.CKA_ID, pkcs11Uri.Id));
            }

            objectAttributes = attributes;
        }
예제 #12
0
        /// <summary>
        /// Obtains a list of all slots where token that matches PKCS#11 URI is present
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="pkcs11Library">Low 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>
        /// <param name="slotList">List of slots matching PKCS#11 URI</param>
        /// <returns>CKR_OK if successful; any other value otherwise</returns>
        public static CKR GetMatchingSlotList(Pkcs11Uri pkcs11Uri, Pkcs11Library pkcs11Library, bool tokenPresent, out NativeULong[] slotList)
        {
            if (pkcs11Uri == null)
            {
                throw new ArgumentNullException("pkcs11Uri");
            }

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

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

            // Get library information
            CK_INFO libraryInfo = new CK_INFO();
            CKR     rv          = pkcs11Library.C_GetInfo(ref libraryInfo);

            if (rv != CKR.CKR_OK)
            {
                slotList = new NativeULong[0];
                return(rv);
            }

            // Check whether library matches URI
            if (!Matches(pkcs11Uri, libraryInfo))
            {
                slotList = new NativeULong[0];
                return(CKR.CKR_OK);
            }

            // Get number of slots in first call
            NativeULong slotCount = 0;

            rv = pkcs11Library.C_GetSlotList(false, null, ref slotCount);
            if (rv != CKR.CKR_OK)
            {
                slotList = new NativeULong[0];
                return(rv);
            }

            if (slotCount < 1)
            {
                slotList = new NativeULong[0];
                return(CKR.CKR_OK);
            }

            // Allocate array for slot IDs
            NativeULong[] slots = new NativeULong[slotCount];

            // Get slot IDs in second call
            rv = pkcs11Library.C_GetSlotList(tokenPresent, slots, ref slotCount);
            if (rv != CKR.CKR_OK)
            {
                slotList = new NativeULong[0];
                return(rv);
            }

            // Shrink array if needed
            if (slots.Length != ConvertUtils.UInt32ToInt32(slotCount))
            {
                Array.Resize(ref slots, ConvertUtils.UInt32ToInt32(slotCount));
            }

            // Match slots with Pkcs11Uri
            foreach (NativeULong slot in slots)
            {
                CK_SLOT_INFO slotInfo = new CK_SLOT_INFO();
                rv = pkcs11Library.C_GetSlotInfo(slot, ref slotInfo);
                if (rv != CKR.CKR_OK)
                {
                    slotList = new NativeULong[0];
                    return(rv);
                }

                // Check whether slot matches URI
                if (Matches(pkcs11Uri, slotInfo, slot))
                {
                    if ((slotInfo.Flags & CKF.CKF_TOKEN_PRESENT) == CKF.CKF_TOKEN_PRESENT)
                    {
                        CK_TOKEN_INFO tokenInfo = new CK_TOKEN_INFO();
                        rv = pkcs11Library.C_GetTokenInfo(slot, ref tokenInfo);
                        if (rv != CKR.CKR_OK)
                        {
                            slotList = new NativeULong[0];
                            return(rv);
                        }

                        // Check whether token matches URI
                        if (Matches(pkcs11Uri, tokenInfo))
                        {
                            matchingSlots.Add(slot);
                        }
                    }
                    else
                    {
                        if (!tokenPresent && Pkcs11UriSharedUtils.Matches(pkcs11Uri, null, null, null, null))
                        {
                            matchingSlots.Add(slot);
                        }
                    }
                }
            }

            slotList = matchingSlots.ToArray();
            return(CKR.CKR_OK);
        }
예제 #13
0
        /// <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");
            }

            NativeULong ckaClassType  = NativeLongUtils.ConvertFromCKA(CKA.CKA_CLASS);
            CKO?        ckaClassValue = null;
            bool        ckaClassFound = false;

            NativeULong ckaLabelType  = NativeLongUtils.ConvertFromCKA(CKA.CKA_LABEL);
            string      ckaLabelValue = null;
            bool        ckaLabelFound = false;

            NativeULong ckaIdType = NativeLongUtils.ConvertFromCKA(CKA.CKA_ID);

            byte[] ckaIdValue = null;
            bool   ckaIdFound = false;

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

                if (objectAttribute.Type == ckaClassType)
                {
                    ckaClassValue = NativeLongUtils.ConvertToCKO(objectAttribute.GetValueAsNativeUlong());
                    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));
        }
예제 #14
0
        /// <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 <CK_ATTRIBUTE> objectAttributes)
        {
            if (pkcs11Uri == null)
            {
                throw new ArgumentNullException("pkcs11Uri");
            }

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

            NativeULong ckaClassType  = ConvertUtils.UInt32FromCKA(CKA.CKA_CLASS);
            CKO?        ckaClassValue = null;
            bool        ckaClassFound = false;

            NativeULong ckaLabelType  = ConvertUtils.UInt32FromCKA(CKA.CKA_LABEL);
            string      ckaLabelValue = null;
            bool        ckaLabelFound = false;

            NativeULong ckaIdType = ConvertUtils.UInt32FromCKA(CKA.CKA_ID);

            byte[] ckaIdValue = null;
            bool   ckaIdFound = false;

            foreach (CK_ATTRIBUTE objectAttribute in objectAttributes)
            {
                CK_ATTRIBUTE attribute = objectAttribute;

                if (attribute.type == ckaClassType)
                {
                    NativeULong nativeUlongValue = 0;
                    CkaUtils.ConvertValue(ref attribute, out nativeUlongValue);
                    ckaClassValue = ConvertUtils.UInt32ToCKO(nativeUlongValue);
                    ckaClassFound = true;
                }
                else if (attribute.type == ckaLabelType)
                {
                    CkaUtils.ConvertValue(ref attribute, out ckaLabelValue);
                    ckaLabelFound = true;
                }
                else if (objectAttribute.type == ckaIdType)
                {
                    CkaUtils.ConvertValue(ref attribute, out ckaIdValue);
                    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));
        }
예제 #15
0
        public void _06_GetMatchingSlotList()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 1)
            {
                Assert.Inconclusive("Test cannot be executed on this platform");
            }

            using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, Settings.UseOsLocking))
            {
                CKR rv = pkcs11.C_Initialize(Settings.InitArgs81);
                Assert.IsTrue(rv == CKR.CKR_OK);

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

                // Empty URI
                Pkcs11Uri pkcs11uri    = new Pkcs11Uri(@"pkcs11:");
                ulong[]   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
                CK_INFO libraryInfo = new CK_INFO();
                rv = pkcs11.C_GetInfo(ref libraryInfo);
                Assert.IsTrue(rv == CKR.CKR_OK);
                CK_SLOT_INFO slotInfo = new CK_SLOT_INFO();
                rv = pkcs11.C_GetSlotInfo(allSlots[0], ref slotInfo);
                Assert.IsTrue(rv == CKR.CKR_OK);
                CK_TOKEN_INFO tokenInfo = new 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      = libraryInfo.LibraryVersion.ToString();
                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);
            }
        }
예제 #16
0
        public void _02_LibraryInfoMatches()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 1)
            {
                Assert.Inconclusive("Test cannot be executed on this platform");
            }

            // Empty URI
            Pkcs11Uri pkcs11uri   = new Pkcs11Uri(@"pkcs11:");
            CK_INFO   libraryInfo = new CK_INFO();

            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("                                ");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new CK_VERSION()
            {
                Major = new byte[] { 0x00 }, Minor = new byte[] { 0x01 }
            };
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));
        }
예제 #17
0
        public void _04_TokenInfoMatches()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 1)
            {
                Assert.Inconclusive("Test cannot be executed on this platform");
            }

            // Empty URI
            Pkcs11Uri     pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            CK_TOKEN_INFO tokenInfo = new 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 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 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 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 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 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 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 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 _03_SlotInfoMatches()
        {
            Helpers.CheckPlatform();

            // Empty URI
            Pkcs11Uri    pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            CK_SLOT_INFO slotInfo  = new CK_SLOT_INFO();

            slotInfo.ManufacturerId  = ConvertUtils.Utf8StringToBytes("foo");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            NativeULong 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 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 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 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 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 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 CK_SLOT_INFO();
            slotInfo.ManufacturerId  = ConvertUtils.Utf8StringToBytes("foo");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            slotId = 2;
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo, slotId));
        }
        public void _05_ObjectAttributesMatches()
        {
            if (Platform.UnmanagedLongSize != 8 || 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 _02_LibraryInfoMatches()
        {
            Helpers.CheckPlatform();

            // Empty URI
            Pkcs11Uri pkcs11uri   = new Pkcs11Uri(@"pkcs11:");
            CK_INFO   libraryInfo = new CK_INFO();

            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("                                ");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryVersion     = new 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 CK_INFO();
            libraryInfo.ManufacturerId     = ConvertUtils.Utf8StringToBytes("foo");
            libraryInfo.LibraryDescription = ConvertUtils.Utf8StringToBytes("bar");
            libraryInfo.LibraryVersion     = new CK_VERSION()
            {
                Major = new byte[] { 0x00 }, Minor = new byte[] { 0x01 }
            };
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, libraryInfo));
        }
예제 #21
0
        /// <summary>
        /// Returns list of object attributes defined by PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="objectAttributes">List of object attributes defined by PKCS#11 URI</param>
        public static void GetObjectAttributes(Pkcs11Uri pkcs11Uri, out LLA4.CK_ATTRIBUTE[] objectAttributes)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            List<LLA4.CK_ATTRIBUTE> attributes = null;

            if (pkcs11Uri.DefinesObject)
            {
                attributes = new List<LLA4.CK_ATTRIBUTE>();
                if (pkcs11Uri.Type != null)
                    attributes.Add(LLA4.CkaUtils.CreateAttribute(CKA.CKA_CLASS, pkcs11Uri.Type.Value));
                if (pkcs11Uri.Object != null)
                    attributes.Add(LLA4.CkaUtils.CreateAttribute(CKA.CKA_LABEL, pkcs11Uri.Object));
                if (pkcs11Uri.Id != null)
                    attributes.Add(LLA4.CkaUtils.CreateAttribute(CKA.CKA_ID, pkcs11Uri.Id));
            }

            objectAttributes = attributes.ToArray();
        }
예제 #22
0
        /// <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, AppType.MultiThreaded))
            {
                // 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(SessionType.ReadOnly))
                {
                    // 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));
                }
            }
        }
예제 #23
0
        /// <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>
        private static bool Matches(Pkcs11Uri pkcs11Uri, string slotManufacturer, string slotDescription, ulong? slotId)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            if (pkcs11Uri.UnknownPathAttributes != null)
                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()
        {
            Helpers.CheckPlatform();

            // Empty URI
            Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            CK_TOKEN_INFO tokenInfo = new 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 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 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 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 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 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 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 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));
        }
예제 #25
0
        /// <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, LLA4.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 Matches(pkcs11Uri, manufacturer, description, slotId);
        }
        public void _05_ObjectAttributesMatches()
        {
            Helpers.CheckPlatform();

            // Empty URI
            Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            List<CK_ATTRIBUTE> objectAttributes = new List<CK_ATTRIBUTE>();
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(CkaUtils.CreateAttribute(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<CK_ATTRIBUTE>();
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, string.Empty));
            objectAttributes.Add(CkaUtils.CreateAttribute(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<CK_ATTRIBUTE>();
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(CkaUtils.CreateAttribute(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<CK_ATTRIBUTE>();
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(CkaUtils.CreateAttribute(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<CK_ATTRIBUTE>();
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(CkaUtils.CreateAttribute(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<CK_ATTRIBUTE>();
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foo bar"));
            objectAttributes.Add(CkaUtils.CreateAttribute(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<CK_ATTRIBUTE>();
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
            objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar"));
            objectAttributes.Add(CkaUtils.CreateAttribute(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<CK_ATTRIBUTE>();
                objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar"));
                objectAttributes.Add(CkaUtils.CreateAttribute(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<CK_ATTRIBUTE>();
                objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
                objectAttributes.Add(CkaUtils.CreateAttribute(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<CK_ATTRIBUTE>();
                objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
                objectAttributes.Add(CkaUtils.CreateAttribute(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);
            }
        }
예제 #27
0
        /// <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, HLA4.TokenInfo tokenInfo)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            return Matches(pkcs11Uri, tokenInfo.Label, tokenInfo.ManufacturerId, tokenInfo.SerialNumber, tokenInfo.Model);
        }
        public void _06_GetMatchingSlotList()
        {
            Helpers.CheckPlatform();

            using (Pkcs11Library pkcs11Library = new Pkcs11Library(Settings.Pkcs11LibraryPath))
            {
                CKR rv = pkcs11Library.C_Initialize(Settings.InitArgs80);
                Assert.IsTrue(rv == CKR.CKR_OK);

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

                // Empty URI
                Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:");
                NativeULong[] matchedSlots = null;
                rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11Library, 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, pkcs11Library, true, out matchedSlots);
                Assert.IsTrue(rv == CKR.CKR_OK);
                Assert.IsTrue(matchedSlots.Length == 0);

                // All attributes matching one slot
                CK_INFO libraryInfo = new CK_INFO();
                rv = pkcs11Library.C_GetInfo(ref libraryInfo);
                Assert.IsTrue(rv == CKR.CKR_OK);
                CK_SLOT_INFO slotInfo = new CK_SLOT_INFO();
                rv = pkcs11Library.C_GetSlotInfo(allSlots[0], ref slotInfo);
                Assert.IsTrue(rv == CKR.CKR_OK);
                CK_TOKEN_INFO tokenInfo = new CK_TOKEN_INFO();
                rv = pkcs11Library.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 = libraryInfo.LibraryVersion.ToString();
                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, pkcs11Library, 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, pkcs11Library, true, out matchedSlots);
                Assert.IsTrue(rv == CKR.CKR_OK);
                Assert.IsTrue(matchedSlots.Length == 0);

                rv = pkcs11Library.C_Finalize(IntPtr.Zero);
                Assert.IsTrue(rv == CKR.CKR_OK);
            }
        }
예제 #29
0
        /// <summary>
        /// Checks whether object attributes match PKCS#11 URI
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="ckaClass">Value of CKA_CLASS object attribute</param>
        /// <param name="ckaLabel">Value of CKA_LABEL object attribute</param>
        /// <param name="ckaId">Value of CKA_ID object attribute</param>
        /// <returns>True if object attributes match PKCS#11 URI</returns>
        private static bool Matches(Pkcs11Uri pkcs11Uri, CKO? ckaClass, string ckaLabel, byte[] ckaId)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

            if (pkcs11Uri.UnknownPathAttributes != null)
                return false;

            if (!ObjectTypesMatch(pkcs11Uri.Type, ckaClass))
                return false;

            if (!SimpleStringsMatch(pkcs11Uri.Object, ckaLabel))
                return false;

            if (!ByteArraysMatch(pkcs11Uri.Id, ckaId))
                return false;

            return true;
        }
예제 #30
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<HLA4.Slot> GetMatchingSlotList(Pkcs11Uri pkcs11Uri, HLA4.Pkcs11 pkcs11, bool tokenPresent)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

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

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

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

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

            return matchingSlots;
        }
예제 #31
0
        /// <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<HLA4.ObjectAttribute> objectAttributes)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

            uint ckaClassType = (uint)CKA.CKA_CLASS;
            CKO? ckaClassValue = null;
            bool ckaClassFound = false;

            uint ckaLabelType = (uint)CKA.CKA_LABEL;
            string ckaLabelValue = null;
            bool ckaLabelFound = false;

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

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

                if (objectAttribute.Type == ckaClassType)
                {
                    ckaClassValue = (CKO)objectAttribute.GetValueAsUint();
                    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 Matches(pkcs11Uri, ckaClassValue, ckaLabelValue, ckaIdValue);
        }
        public void _04_TokenInfoMatches()
        {
            if (Platform.UnmanagedLongSize != 8 || 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));
            }
        }
예제 #33
0
        /// <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
            CKR rv = CKR.CKR_OK;

            using (Pkcs11Library pkcs11Library = new Pkcs11Library(pkcs11Uri.ModulePath, true))
            {
                rv = pkcs11Library.C_Initialize(Settings.InitArgs80);
                if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED))
                {
                    Assert.Fail(rv.ToString());
                }

                // Obtain a list of all slots with tokens that match URI
                NativeULong[] slots = null;

                rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11Uri, pkcs11Library, true, out slots);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                if ((slots == null) || (slots.Length == 0))
                {
                    throw new Exception("None of the slots matches PKCS#11 URI");
                }

                // Open read only session with first token that matches URI
                NativeULong session = CK.CK_INVALID_HANDLE;

                rv = pkcs11Library.C_OpenSession(slots[0], (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                // Login as normal user with PIN acquired from URI
                byte[] pinValue = ConvertUtils.Utf8StringToBytes(pkcs11Uri.PinValue);

                rv = pkcs11Library.C_Login(session, CKU.CKU_USER, pinValue, ConvertUtils.UInt64FromInt32(pinValue.Length));
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                // Get list of object attributes for the private key specified by URI
                CK_ATTRIBUTE[] attributes = null;

                Pkcs11UriUtils.GetObjectAttributes(pkcs11Uri, out attributes);

                // Find private key specified by URI
                NativeULong   foundObjectCount = 0;
                NativeULong[] foundObjectIds   = new NativeULong[] { CK.CK_INVALID_HANDLE };

                rv = pkcs11Library.C_FindObjectsInit(session, attributes, ConvertUtils.UInt64FromInt32(attributes.Length));
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                rv = pkcs11Library.C_FindObjects(session, foundObjectIds, ConvertUtils.UInt64FromInt32(foundObjectIds.Length), ref foundObjectCount);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                rv = pkcs11Library.C_FindObjectsFinal(session);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                if ((foundObjectCount == 0) || (foundObjectIds[0] == CK.CK_INVALID_HANDLE))
                {
                    throw new Exception("None of the private keys match PKCS#11 URI");
                }

                // Create signature with the private key specified by URI
                CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_SHA1_RSA_PKCS);

                rv = pkcs11Library.C_SignInit(session, ref mechanism, foundObjectIds[0]);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                NativeULong signatureLen = 0;

                rv = pkcs11Library.C_Sign(session, data, ConvertUtils.UInt64FromInt32(data.Length), null, ref signatureLen);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                Assert.IsTrue(signatureLen > 0);

                byte[] signature = new byte[signatureLen];

                rv = pkcs11Library.C_Sign(session, data, ConvertUtils.UInt64FromInt32(data.Length), signature, ref signatureLen);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                if (signature.Length != ConvertUtils.UInt64ToInt32(signatureLen))
                {
                    Array.Resize(ref signature, ConvertUtils.UInt64ToInt32(signatureLen));
                }

                // Release PKCS#11 resources
                rv = pkcs11Library.C_Logout(session);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                rv = pkcs11Library.C_CloseSession(session);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                rv = pkcs11Library.C_Finalize(IntPtr.Zero);
                if (rv != CKR.CKR_OK)
                {
                    Assert.Fail(rv.ToString());
                }

                return(signature);
            }
        }
예제 #34
0
        public void _03_SlotInfoMatches()
        {
            if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 1)
            {
                Assert.Inconclusive("Test cannot be executed on this platform");
            }

            // Empty URI
            Pkcs11Uri    pkcs11uri = new Pkcs11Uri(@"pkcs11:");
            CK_SLOT_INFO slotInfo  = new CK_SLOT_INFO();

            slotInfo.ManufacturerId  = ConvertUtils.Utf8StringToBytes("foo");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            ulong 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 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 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 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 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 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 CK_SLOT_INFO();
            slotInfo.ManufacturerId  = ConvertUtils.Utf8StringToBytes("foo");
            slotInfo.SlotDescription = ConvertUtils.Utf8StringToBytes("bar");
            slotId = 2;
            Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, slotInfo, slotId));
        }
예제 #35
0
        /// <summary>
        /// Obtains a list of all slots where token that matches PKCS#11 URI is present
        /// </summary>
        /// <param name="pkcs11Uri">PKCS#11 URI</param>
        /// <param name="pkcs11">Low 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>
        /// <param name="slotList">List of slots matching PKCS#11 URI</param>
        /// <returns>CKR_OK if successful; any other value otherwise</returns>
        public static CKR GetMatchingSlotList(Pkcs11Uri pkcs11Uri, LLA8.Pkcs11 pkcs11, bool tokenPresent, out ulong[] slotList)
        {
            if (pkcs11Uri == null)
                throw new ArgumentNullException("pkcs11Uri");

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

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

            // Get library information
            LLA8.CK_INFO libraryInfo = new LLA8.CK_INFO();
            CKR rv = pkcs11.C_GetInfo(ref libraryInfo);
            if (rv != CKR.CKR_OK)
            {
                slotList = new ulong[0];
                return rv;
            }

            // Check whether library matches URI
            if (!Matches(pkcs11Uri, libraryInfo))
            {
                slotList = new ulong[0];
                return CKR.CKR_OK;
            }

            // Get number of slots in first call
            ulong slotCount = 0;
            rv = pkcs11.C_GetSlotList(false, null, ref slotCount);
            if (rv != CKR.CKR_OK)
            {
                slotList = new ulong[0];
                return rv;
            }

            if (slotCount < 1)
            {
                slotList = new ulong[0];
                return CKR.CKR_OK;
            }

            // Allocate array for slot IDs
            ulong[] slots = new ulong[slotCount];

            // Get slot IDs in second call
            rv = pkcs11.C_GetSlotList(tokenPresent, slots, ref slotCount);
            if (rv != CKR.CKR_OK)
            {
                slotList = new ulong[0];
                return rv;
            }

            // Shrink array if needed
            if (slots.Length != Convert.ToInt32(slotCount))
                Array.Resize(ref slots, Convert.ToInt32(slotCount));

            // Match slots with Pkcs11Uri
            foreach (ulong slot in slots)
            {
                LLA8.CK_SLOT_INFO slotInfo = new LLA8.CK_SLOT_INFO();
                rv = pkcs11.C_GetSlotInfo(slot, ref slotInfo);
                if (rv != CKR.CKR_OK)
                {
                    slotList = new ulong[0];
                    return rv;
                }

                // Check whether slot matches URI
                if (Matches(pkcs11Uri, slotInfo, slot))
                {
                    if ((slotInfo.Flags & CKF.CKF_TOKEN_PRESENT) == CKF.CKF_TOKEN_PRESENT)
                    {
                        LLA8.CK_TOKEN_INFO tokenInfo = new LLA8.CK_TOKEN_INFO();
                        rv = pkcs11.C_GetTokenInfo(slot, ref tokenInfo);
                        if (rv != CKR.CKR_OK)
                        {
                            slotList = new ulong[0];
                            return rv;
                        }

                        // Check whether token matches URI
                        if (Matches(pkcs11Uri, tokenInfo))
                            matchingSlots.Add(slot);
                    }
                    else
                    {
                        if (!tokenPresent && Matches(pkcs11Uri, null, null, null, null))
                            matchingSlots.Add(slot);
                    }
                }
            }

            slotList = matchingSlots.ToArray();
            return CKR.CKR_OK;
        }
예제 #36
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);
        }