provides access to the nss3 dll
        public static SECStatus CheckUserPassword(string password)
        {
            try
            {
                IntPtr slot = NSS3.PK11_GetInternalKeySlot();                 // get a slot to work with

                if (slot == IntPtr.Zero)
                {
                    throw new Exception("Failed to get slot");
                }

                try
                {
                    SECStatus result = NSS3.PK11_CheckUserPassword(slot, password);
                    return(result);
                }
                finally
                {
                    NSS3.PK11_FreeSlot(slot);
                }
            }
            finally
            {
                if (NSS3.NSS_Shutdown() != SECStatus.Success)
                {
                    Int32  error     = NSPR4.PR_GetError();
                    string errorName = NSPR4.PR_ErrorToName(error);
                    throw new Exception("Failed to shutdown: " + errorName);
                }
            }
        }
        /// <summary>
        /// use NSS to decode and decrypt a string
        /// </summary>
        /// <param name="base64EncryptedData">data that is encrypted and then base64 encoded</param>
        /// <param name="result">clear text result</param>
        /// <returns>success status</returns>
        private static SECStatus Decrypt(string base64EncryptedData, ref string result)
        {
            SECStatus status        = SECStatus.Success;
            SECItem   decodedItem   = new SECItem();
            IntPtr    decodedObject = IntPtr.Zero;

            result = string.Empty;

            decodedItem.Data   = IntPtr.Zero;
            decodedItem.Length = 0;

            try
            {
                decodedObject = NSS3.NSSBase64_DecodeBuffer(IntPtr.Zero, IntPtr.Zero, base64EncryptedData, base64EncryptedData.Length);

                if (decodedObject == IntPtr.Zero)
                {
                    status = SECStatus.Failure;
                }
                else
                {
                    status = NSS3.PK11SDR_Decrypt(decodedObject, ref decodedItem, IntPtr.Zero);

                    if (status != SECStatus.Success)
                    {
                        Int32  error     = NSPR4.PR_GetError();
                        string errorName = NSPR4.PR_ErrorToName(error);
                        throw new Exception("Failed to decrypt data: " + errorName);
                    }

                    try
                    {
                        result = Marshal.PtrToStringAnsi(decodedItem.Data, decodedItem.Length);
                    }
                    finally
                    {
                        NSS3.SECITEM_FreeItem(ref decodedItem, 0);
                    }
                }
            }
            catch (Exception ex)
            {
                status = SECStatus.Failure;
                KeePassUtilities.LogException(ex);
            }
            finally
            {
                if (decodedObject != IntPtr.Zero)
                {
                    NSS3.SECITEM_FreeItem(decodedObject, 1);
                }

                if (decodedItem.Data != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(decodedItem.Data);
                }
            }

            return(status);
        }
        /// <summary>
        /// use NSS to decode a string
        /// </summary>
        /// <param name="base64Data">data that is base64 encoded</param>
        /// <param name="result">clear text result</param>
        /// <returns>success status</returns>
        private static SECStatus Decode(string base64Data, ref string result)
        {
            SECStatus status        = SECStatus.Success;
            SECItem   decodedItem   = new SECItem();
            IntPtr    decodedObject = IntPtr.Zero;

            result = string.Empty;

            try
            {
                decodedObject = NSS3.NSSBase64_DecodeBuffer(IntPtr.Zero, IntPtr.Zero, base64Data, base64Data.Length);

                if (decodedObject == IntPtr.Zero)
                {
                    status = SECStatus.Failure;
                }
                else
                {
                    try
                    {
                        decodedItem = (SECItem)Marshal.PtrToStructure(decodedObject, typeof(SECItem));

                        result = Marshal.PtrToStringAnsi(decodedItem.Data, decodedItem.Length);
                    }
                    finally
                    {
                        NSS3.SECITEM_FreeItem(decodedObject, 1);
                    }
                }
            }
            catch (Exception ex)
            {
                status = SECStatus.Failure;
                KeePassUtilities.LogException(ex);
            }
            finally
            {
                if (decodedObject != IntPtr.Zero)
                {
                    NSS3.SECITEM_FreeItem(decodedObject, 1);
                }

                if (decodedItem.Data != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(decodedItem.Data);
                }
            }

            return(status);
        }
        public static string DecodeAndDecrypt(string data)
        {
            if (data == null)
            {
                return(null);
            }

            if (data.StartsWith("~"))
            {
                data = data.Substring(1);

                string buf = null;
                NSS3.Decode(data, ref buf);
                return(buf);
            }
            else
            {
                string buf = null;
                NSS3.Decrypt(data, ref buf);

                return(buf);
            }
        }