/// <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)); } }