Beispiel #1
0
        /// <summary>
        /// Marshal the PDU struct to a byte array.
        /// </summary>
        /// <returns>A byte array contains PDU data.</returns>
        public override byte[] ToBytes()
        {
            int size = GetSize();

            FieldInfo fieldInfo = GetType().GetField("stub");

            if (fieldInfo != null)
            {
                byte[] stub = (byte[])fieldInfo.GetValue(this);
                if (stub != null)
                {
                    size += stub.Length;
                }
            }

            fieldInfo = GetType().GetField("auth_verifier");
            if (fieldInfo != null)
            {
                auth_verifier_co_t?authVerifier = (auth_verifier_co_t?)fieldInfo.GetValue(this);
                size += RpceUtility.AuthVerifierGetSize(authVerifier);
            }

            byte[] pduBytes = new byte[size];
            using (BinaryWriter binaryWriter = new BinaryWriter(new MemoryStream(pduBytes)))
            {
                ToBytes(binaryWriter);
            }

            return(pduBytes);
        }
Beispiel #2
0
        /// <summary>
        /// Set length field of PDU.
        /// </summary>
        public override void SetLength()
        {
            auth_verifier_co_t?authVerifier = null;
            FieldInfo          fieldInfo    = this.GetType().GetField("auth_verifier");

            if (fieldInfo != null)
            {
                authVerifier = (auth_verifier_co_t?)fieldInfo.GetValue(this);
            }

            byte[] stub       = GetStub();
            int    stubLength = (stub == null) ? 0 : stub.Length;

            // stub was already padded in AppendAuthenticationVerifier()
            auth_length = (authVerifier == null || authVerifier.Value.auth_value == null)
                            ? (ushort)0
                            : (ushort)authVerifier.Value.auth_value.Length;
            frag_length = (ushort)(GetSize() + stubLength + RpceUtility.AuthVerifierGetSize(authVerifier));
        }
Beispiel #3
0
        /// <summary>
        /// Encrypt and sign to get auth_token.
        /// </summary>
        /// <param name="authVerifier">auth_verifier, not null.</param>
        private void EncryptAndSign(ref auth_verifier_co_t authVerifier)
        {
            //Request, Response, Fault
            //Get stub, pad the length to a multiple of 4 bytes.
            byte[] stub = GetStub();
            if (stub == null)
            {
                stub = new byte[0];
                SetStub(stub);
            }

            //Get SecurityBuffers.
            int stubSecBufIndex;
            int tokenSecBufIndex;
            SecurityBufferType    readonlyFlag;
            List <SecurityBuffer> securityBufferList = new List <SecurityBuffer>();

            if (context.SupportsHeaderSign)
            {
                readonlyFlag = SecurityBufferType.ReadOnlyWithChecksum;
            }
            else
            {
                readonlyFlag = SecurityBufferType.ReadOnly;
            }
            int headerSize = GetSize();

            byte[] buf = new byte[
                headerSize
                + stub.Length
                + RpceUtility.AuthVerifierGetSize(authVerifier)];
            using (BinaryWriter binaryWriter = new BinaryWriter(new MemoryStream(buf)))
            {
                ToBytes(binaryWriter);
            }

            securityBufferList.Add(
                new SecurityBuffer(
                    SecurityBufferType.Data | readonlyFlag,
                    ArrayUtility.SubArray(buf, 0, headerSize)));
            stubSecBufIndex = securityBufferList.Count;
            securityBufferList.Add(
                new SecurityBuffer(
                    SecurityBufferType.Data,
                    ArrayUtility.ConcatenateArrays(stub, authVerifier.auth_pad)));
            securityBufferList.Add(
                new SecurityBuffer(
                    SecurityBufferType.Data | readonlyFlag,
                    ArrayUtility.SubArray(
                        buf,
                        headerSize + stub.Length + authVerifier.auth_pad_length,
                        RpceUtility.AUTH_VERIFIER_SIZE))); //8 == length of auth_verifier
            tokenSecBufIndex = securityBufferList.Count;
            securityBufferList.Add(
                new SecurityBuffer(
                    SecurityBufferType.Token,
                    authVerifier.auth_value));
            SecurityBuffer[] securityBuffers = securityBufferList.ToArray();

            //encrypt and sign
            switch (context.AuthenticationLevel)
            {
            case RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_CALL:     //Same as RPC_C_AUTHN_LEVEL_PKT
            case RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT:
                //the field "checksum" is the checksum value returned
                //by the underlying security service in response to
                //an integrity protection call
                context.SecurityContext.Sign(securityBuffers);
                authVerifier.auth_value = securityBuffers[tokenSecBufIndex].Buffer;
                break;

            case RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:
                //the field "checksum" is the checksum value returned
                //by the underlying security service in response to
                //an integrity protection call
                context.SecurityContext.Sign(securityBuffers);
                authVerifier.auth_value = securityBuffers[tokenSecBufIndex].Buffer;
                break;

            case RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_PRIVACY:
                //This level of service provides strong integrity protection for the
                //entire PDU, plus privacy protection for the body data only.
                //Therefore, only the bodies of the request, response and fault PDUs
                //are encrypted.
                context.SecurityContext.Encrypt(securityBuffers);
                authVerifier.auth_pad   = ArrayUtility.SubArray(securityBuffers[stubSecBufIndex].Buffer, stub.Length);
                authVerifier.auth_value = securityBuffers[tokenSecBufIndex].Buffer;
                stub = ArrayUtility.SubArray(securityBuffers[stubSecBufIndex].Buffer, 0, stub.Length);
                SetStub(stub);
                break;

                //default do nothing.
            }

            //A client or a server that (during composing of a PDU) has allocated more space for
            //the authentication token than the security provider fills in SHOULD<36> fill in
            //the rest of the allocated space with zero octets. These zero octets are still
            //considered to belong to the authentication token part of the PDU.
            int padLength = (int)auth_length - authVerifier.auth_value.Length;

            if (padLength < 0)
            {
                throw new InvalidOperationException("Length of calculated auth_value is incorrect.");
            }
            else if (padLength > 0)
            {
                authVerifier.auth_value = ArrayUtility.ConcatenateArrays(authVerifier.auth_value, new byte[padLength]);
            }
        }