/// <summary>
        /// Initializes a new instance of the CkOtpSignatureInfo class.
        /// </summary>
        /// <param name='signature'>Signature value returned by all OTP mechanisms in successful calls to Sign method</param>
        public CkOtpSignatureInfo(byte[] signature)
        {
            if (signature == null)
            {
                throw new ArgumentNullException("signature");
            }

            // PKCS#11 v2.20a1 page 14:
            // Since C_Sign and C_SignFinal follows the convention described in Section 11.2 of [1]
            // on producing output, a call to C_Sign (or C_SignFinal) with pSignature set to
            // NULL_PTR will return (in the pulSignatureLen parameter) the required number of bytes
            // to hold the CK_OTP_SIGNATURE_INFO structure as well as all the data in all its
            // CK_OTP_PARAM components. If an application allocates a memory block based on this
            // information, it shall therefore not subsequently de-allocate components of such a received
            // value but rather de-allocate the complete CK_OTP_PARAMS structure itself. A
            // Cryptoki library that is called with a non-NULL pSignature pointer will assume that it
            // points to a contiguous memory block of the size indicated by the pulSignatureLen
            // parameter.

            // Create CK_OTP_SIGNATURE_INFO from  C_Sign or C_SignFinal output
            // TODO : This may require different low level delegate with IntPtr as output
            //        but currently I am not aware of any implementation I could test with.
            IntPtr tmpSignature = IntPtr.Zero;

            try
            {
                tmpSignature = UnmanagedMemory.Allocate(signature.Length);
                UnmanagedMemory.Write(tmpSignature, signature);
                UnmanagedMemory.Read(tmpSignature, _lowLevelStruct);
            }
            finally
            {
                UnmanagedMemory.Free(ref tmpSignature);
            }

            // Read all CK_OTP_PARAMs from CK_OTP_SIGNATURE_INFO
            int ckOtpParamSize = UnmanagedMemory.SizeOf(typeof(CK_OTP_PARAM));

            for (int i = 0; i < ConvertUtils.UInt32ToInt32(_lowLevelStruct.Count); i++)
            {
                // Read CK_OTP_PARAM from CK_OTP_SIGNATURE_INFO
                IntPtr       tempPointer = new IntPtr(_lowLevelStruct.Params.ToInt64() + (i * ckOtpParamSize));
                CK_OTP_PARAM ckOtpParam  = new CK_OTP_PARAM();
                UnmanagedMemory.Read(tempPointer, ckOtpParam);

                // Read members of CK_OTP_PARAM structure
                NativeULong ckOtpParamType  = ckOtpParam.Type;
                byte[]      ckOtpParamValue = UnmanagedMemory.Read(ckOtpParam.Value, ConvertUtils.UInt32ToInt32(ckOtpParam.ValueLen));

                // Construct new high level CkOtpParam object (creates copy of CK_OTP_PARAM structure which is good)
                _params.Add(new CkOtpParam(ckOtpParamType, ckOtpParamValue));
            }
        }
        /// <summary>
        /// Initializes a new instance of the CkOtpSignatureInfo class.
        /// </summary>
        /// <param name='signature'>Signature value returned by all OTP mechanisms in successful calls to Sign method</param>
        public CkOtpSignatureInfo(byte[] signature)
        {
            if (signature == null)
            {
                return;
            }

            int ckOtpParamSize = UnmanagedMemory.SizeOf(typeof(CK_OTP_PARAM));

            if (signature.Length % ckOtpParamSize != 0)
            {
                throw new ArgumentException("Invalid array length", "signature");
            }

            // Copy signature to unmanaged memory
            _signature = UnmanagedMemory.Allocate(signature.Length);
            UnmanagedMemory.Write(_signature, signature);

            // Read CK_OTP_SIGNATURE_INFO from unmanaged memory
            UnmanagedMemory.Read(_signature, _lowLevelStruct);

            for (int i = 0; i < _lowLevelStruct.Count; i++)
            {
                // Read CK_OTP_PARAM from CK_OTP_SIGNATURE_INFO
                IntPtr       tempPointer = new IntPtr(_lowLevelStruct.Params.ToInt32() + (i * ckOtpParamSize));
                CK_OTP_PARAM ckOtpParam  = new CK_OTP_PARAM();
                UnmanagedMemory.Read(tempPointer, ckOtpParam);

                // Read members of CK_OTP_PARAM structure
                uint   ckOtpParamType  = ckOtpParam.Type;
                byte[] ckOtpParamValue = UnmanagedMemory.Read(ckOtpParam.Value, (int)ckOtpParam.ValueLen);

                // Construct high level CkOtpParam class
                _params.Add(new CkOtpParam(ckOtpParamType, ckOtpParamValue));
            }
        }
        /// <summary>
        /// Initializes a new instance of the CkOtpSignatureInfo class.
        /// </summary>
        /// <param name='signature'>Signature value returned by all OTP mechanisms in successful calls to Sign method</param>
        public CkOtpSignatureInfo(byte[] signature)
        {
            if (signature == null)
                throw new ArgumentNullException("signature");

            // PKCS#11 v2.20a1 page 14:
            // Since C_Sign and C_SignFinal follows the convention described in Section 11.2 of [1]
            // on producing output, a call to C_Sign (or C_SignFinal) with pSignature set to
            // NULL_PTR will return (in the pulSignatureLen parameter) the required number of bytes
            // to hold the CK_OTP_SIGNATURE_INFO structure as well as all the data in all its
            // CK_OTP_PARAM components. If an application allocates a memory block based on this
            // information, it shall therefore not subsequently de-allocate components of such a received
            // value but rather de-allocate the complete CK_OTP_PARAMS structure itself. A
            // Cryptoki library that is called with a non-NULL pSignature pointer will assume that it
            // points to a contiguous memory block of the size indicated by the pulSignatureLen
            // parameter.

            // Create CK_OTP_SIGNATURE_INFO from  C_Sign or C_SignFinal output
            // TODO : This may require different low level delegate with IntPtr as output
            //        but currently I am not aware of any implementation I could test with.
            IntPtr tmpSignature = IntPtr.Zero;
            try
            {
                tmpSignature = UnmanagedMemory.Allocate(signature.Length);
                UnmanagedMemory.Write(tmpSignature, signature);
                UnmanagedMemory.Read(tmpSignature, _lowLevelStruct);
            }
            finally
            {
                UnmanagedMemory.Free(ref tmpSignature);
            }

            // Read all CK_OTP_PARAMs from CK_OTP_SIGNATURE_INFO
            int ckOtpParamSize = UnmanagedMemory.SizeOf(typeof(CK_OTP_PARAM));
            for (int i = 0; i < Convert.ToInt32(_lowLevelStruct.Count); i++)
            {
                // Read CK_OTP_PARAM from CK_OTP_SIGNATURE_INFO
                IntPtr tempPointer = new IntPtr(_lowLevelStruct.Params.ToInt64() + (i * ckOtpParamSize));
                CK_OTP_PARAM ckOtpParam = new CK_OTP_PARAM();
                UnmanagedMemory.Read(tempPointer, ckOtpParam);

                // Read members of CK_OTP_PARAM structure
                ulong ckOtpParamType = ckOtpParam.Type;
                byte[] ckOtpParamValue = UnmanagedMemory.Read(ckOtpParam.Value, Convert.ToInt32(ckOtpParam.ValueLen));

                // Construct new high level CkOtpParam object (creates copy of CK_OTP_PARAM structure which is good)
                _params.Add(new CkOtpParam(ckOtpParamType, ckOtpParamValue));
            }
        }