/// <summary> /// Decrypts message /// </summary> public byte[] DecryptMessage(SecurityContext context, byte[] encBuffer) { // parameters validation if (context == null) throw new ArgumentNullException("context"); if (encBuffer == null) throw new ArgumentNullException("encMessage"); // parse encrypted buffer byte[] encrypted; byte[] trailer; ParseEncryptedBuffer(encBuffer, out encrypted, out trailer); // prepare buffers SecurityBuffers inputBuffers = new SecurityBuffers(2); inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_DATA, encrypted); inputBuffers.SetBuffer(1, (int)SSPINative.SECBUFFER_TOKEN, trailer); // encrypt message Int64 contextHandle = context.Handle; int error = SSPINative.DecryptMessage( ref contextHandle, inputBuffers, 0, 0); if (error < 0) throw new SSPIException(error, "Could not decrypt message"); // get decrypted message byte[] message = inputBuffers.GetBuffer(0); inputBuffers.Dispose(); return message; }
/// <summary> /// Encrypts message /// </summary> public byte[] EncryptMessage(SecurityContext context, byte[] message) { // parameters validation if (context == null) throw new ArgumentNullException("context"); if (message == null) throw new ArgumentNullException("message"); // prepare buffers SecurityBuffers inputBuffers = new SecurityBuffers(2); inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_DATA, message); inputBuffers.SetBuffer(1, (int)SSPINative.SECBUFFER_TOKEN, context.SecurityTrailer); // encrypt message Int64 contextHandle = context.Handle; int error = SSPINative.EncryptMessage( ref contextHandle, 0, inputBuffers, 0); if (error < 0) throw new SSPIException(error, "Could not encrypt message"); // get encrypted data and trailer byte[] encrypted = inputBuffers.GetBuffer(0); byte[] trailer = inputBuffers.GetBuffer(1); inputBuffers.Dispose(); // create encrypted buffer return CreateEncryptedBuffer(encrypted, trailer); }
/// <summary> /// Creates the signature of a message /// </summary> public byte[] CreateSignature(SecurityContext context, byte[] message) { // parameters validation if (context == null) throw new ArgumentNullException("context"); if (message == null) throw new ArgumentNullException("message"); // prepare buffers SecurityBuffers inputBuffers = new SecurityBuffers(2); inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_DATA, message); inputBuffers.SetBuffer(1, (int)SSPINative.SECBUFFER_TOKEN, context.MaxSignature); // create signature Int64 contextHandle = context.Handle; int error = SSPINative.MakeSignature( ref contextHandle, 0, inputBuffers, 0); if (error < 0) throw new SSPIException(error, "Could not create signature"); // get signature byte[] signature = inputBuffers.GetBuffer(1); inputBuffers.Dispose(); return signature; }
/// <summary> /// Verifies the signature of a message /// </summary> public void VerifySignature(SecurityContext context, byte[] message, byte[] signature) { // parameters validation if (context == null) throw new ArgumentNullException("context"); if (message == null) throw new ArgumentNullException("message"); if (signature == null) throw new ArgumentNullException("signature"); // prepare buffers SecurityBuffers inputBuffers = new SecurityBuffers(2); inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_DATA, message); inputBuffers.SetBuffer(1, (int)SSPINative.SECBUFFER_TOKEN, signature); // verify signature Int64 contextHandle = context.Handle; int error = SSPINative.VerifySignature( ref contextHandle, inputBuffers, 0, 0); if (error < 0) { switch (error) { case SSPINative.SEC_E_MESSAGE_ALTERED: throw new SSPIException(error, "The message or signature supplied for verification has been altered"); case SSPINative.SEC_E_OUT_OF_SEQUENCE: throw new SSPIException(error, "The message supplied for verification is out of sequence"); default: throw new SSPIException(error, "Could not verify message signature"); }; } }
/// <summary> /// Updates security context, proceeds input token and generates output token /// </summary> public void UpdateSecurityContext( SecurityContext context, SecurityContextAttributes contextAttributes, byte[] inputToken, out byte[] outputToken) { // parameters validation if (context == null) throw new ArgumentNullException("credentials"); if (inputToken == null) throw new ArgumentNullException("inputToken"); // prepare requirements for context uint contextReq = GetContextRequirements(context.Type == SecurityContextType.Server, contextAttributes); // prepare buffers SecurityBuffers inputBuffers = new SecurityBuffers(1); inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_TOKEN, inputToken); SecurityBuffers outputBuffers = new SecurityBuffers(1); outputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_TOKEN, _secPackage.MaxToken); // update context Int64 credHandle = context.credentials.Handle; Int64 contextHandle = context.Handle; uint contextAttribs; int error; if (context.Type == SecurityContextType.Client) { error = SSPINative.InitializeSecurityContext( ref credHandle, ref contextHandle, null, contextReq, 0, SSPINative.SECURITY_NETWORK_DREP, inputBuffers, 0, IntPtr.Zero, outputBuffers, out contextAttribs, IntPtr.Zero); } else { error = SSPINative.AcceptSecurityContext( ref credHandle, ref contextHandle, inputBuffers, contextReq, SSPINative.SECURITY_NETWORK_DREP, IntPtr.Zero, outputBuffers, out contextAttribs, IntPtr.Zero); } inputBuffers.Dispose(); // check context state bool continueNeeded = false; bool completeNeeded = false; switch (error) { case Win32.ERROR_SUCCESS: break; case SSPINative.SEC_I_CONTINUE_NEEDED: continueNeeded = true; break; case SSPINative.SEC_I_COMPLETE_NEEDED: completeNeeded = true; break; case SSPINative.SEC_I_COMPLETE_AND_CONTINUE: continueNeeded = true; completeNeeded = true; break; default: throw new SSPIException(error, "Could not update security context"); } if (completeNeeded) { // complete context error = SSPINative.CompleteAuthToken(ref contextHandle, outputBuffers); if (error < 0) throw new SSPIException(error, "Could not complete security context"); } // get output token outputToken = outputBuffers.GetBuffer(0); outputBuffers.Dispose(); // update context object state if (!continueNeeded) { context.SetCompleted(); } }