示例#1
0
		/// <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;
		}
示例#2
0
		/// <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);
		}
示例#3
0
		/// <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;
		}
示例#4
0
		/// <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");
				};
			}
		}
示例#5
0
		/// <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();
			}
		}