private static void CaptureArray(GXDLMSServer server, GXByteBuffer tmp, GXByteBuffer bb, int index)
        {
            //Skip type.
            tmp.GetUInt8();
            int cnt = GXCommon.GetObjectCount(tmp);

            for (int pos = 0; pos != cnt; ++pos)
            {
                if (index == -1 || index == pos)
                {
                    DataType dt = (DataType)tmp.GetUInt8(tmp.Position);
                    if (dt == DataType.Structure || dt == DataType.Array)
                    {
                        CaptureArray(server, tmp, bb, -1);
                    }
                    else
                    {
                        CaptureValue(server, tmp, bb);
                    }
                    if (index == pos)
                    {
                        break;
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Parse application context name.
        /// </summary>
        /// <param name="settings">DLMS settings.</param>
        /// <param name="buff">Received data.</param>
        private static bool ParseApplicationContextName(GXDLMSSettings settings, GXByteBuffer buff)
        {
            //Get length.
            int len = buff.GetUInt8();

            if (buff.Size - buff.Position < len)
            {
                throw new Exception("Encoding failed. Not enough data.");
            }
            if (buff.GetUInt8() != 0x6)
            {
                throw new Exception("Encoding failed. Not an Object ID.");
            }
            if (settings.IsServer)
            {
                settings.Cipher.Security = Security.None;
            }
            //Object ID length.
            len = buff.GetUInt8();
            if (settings.UseLogicalNameReferencing)
            {
                if (buff.Compare(GXCommon.LogicalNameObjectID))
                {
                    return(true);
                }
                // If ciphering is used.
                return(buff.Compare(GXCommon.LogicalNameObjectIdWithCiphering));
            }
            if (buff.Compare(GXCommon.ShortNameObjectID))
            {
                return(true);
            }
            // If ciphering is used.
            return(buff.Compare(GXCommon.ShortNameObjectIdWithCiphering));
        }
        /// <summary>
        /// Get OID string from bytes.
        /// </summary>
        /// <param name="bb">converted bytes. </param>
        /// <param name="len">byte count. </param>
        /// <returns> OID string. </returns>
        private static string OidStringFromBytes(GXByteBuffer bb, int len)
        {
            long          value = 0;
            StringBuilder sb    = new StringBuilder();

            if (len != 0)
            {
                // Get first byte.
                int tmp = bb.GetUInt8();
                sb.Append(tmp / 40);
                sb.Append('.');
                sb.Append(tmp % 40);
                for (int pos = 1; pos != len; ++pos)
                {
                    tmp = bb.GetUInt8();
                    if ((tmp & 0x80) != 0)
                    {
                        value  += (tmp & 0x7F);
                        value <<= 7;
                    }
                    else
                    {
                        value += tmp;
                        sb.Append('.');
                        sb.Append(value);
                        value = 0;
                    }
                }
            }
            return(sb.ToString());
        }
Beispiel #4
0
        /// <summary>
        /// Get values from byte buffer.
        /// </summary>
        /// <param name="value"></param>
        private void FromByteBuffer(GXByteBuffer value)
        {
            for (int pos = value.Size - 4; pos > -1; pos = pos - 4)
            {
                Add(value.GetUInt32(pos));
            }
            switch (value.Size % 4)
            {
            case 1:
                Add(value.GetUInt8());
                break;

            case 2:
                Add(value.GetUInt16());
                break;

            case 3:
                // Data.Add(value.GetUInt24());
                break;

            default:
                break;
            }
            changed = true;
        }
        private static void UpdateTemplateDescription(GXByteBuffer columns, GXByteBuffer data, int index)
        {
            DataType ch    = (DataType)data.GetUInt8();
            int      count = GXCommon.GetObjectCount(data);

            if (index == -1)
            {
                columns.SetUInt8(ch);
                if (ch == DataType.Array)
                {
                    columns.SetUInt16((UInt16)count);
                }
                else
                {
                    columns.SetUInt8((byte)count);
                }
            }
            GXDataInfo info = new GXDataInfo();

            for (int pos = 0; pos < count; ++pos)
            {
                //If all data is captured.
                if (index == -1 || pos == index)
                {
                    DataType dt = (DataType)data.GetUInt8(data.Position);
                    if (dt == DataType.Array || dt == DataType.Structure)
                    {
                        UpdateTemplateDescription(columns, data, -1);
                        if (ch == DataType.Array)
                        {
                            break;
                        }
                    }
                    else
                    {
                        info.Clear();
                        columns.SetUInt8((byte)dt);
                        //Get data.
                        GXCommon.GetData(null, data, info);
                    }
                    if (index == pos)
                    {
                        break;
                    }
                }
            }
        }
 byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, int index, Object parameters)
 {
     //Check reply_to_HLS_authentication
     if (index == 1)
     {
         UInt32 ic = 0;
         byte[] secret;
         if (settings.Authentication == Authentication.HighGMAC)
         {
             secret = settings.SourceSystemTitle;
             GXByteBuffer bb = new GXByteBuffer(parameters as byte[]);
             bb.GetUInt8();
             ic = bb.GetUInt32();
         }
         else
         {
             secret = Secret;
         }
         byte[] serverChallenge = GXSecure.Secure(settings, settings.Cipher, ic, settings.StoCChallenge, secret);
         byte[] clientChallenge = (byte[])parameters;
         if (GXCommon.Compare(serverChallenge, clientChallenge))
         {
             if (settings.Authentication == Authentication.HighGMAC)
             {
                 secret = settings.Cipher.SystemTitle;
             }
             else
             {
                 secret = Secret;
             }
             ic = settings.Cipher.FrameCounter;
             byte[]       tmp       = GXSecure.Secure(settings, settings.Cipher, ic, settings.CtoSChallenge, secret);
             GXByteBuffer challenge = new GXByteBuffer();
             // ReturnParameters.
             challenge.SetUInt8(1);
             challenge.SetUInt8(0);
             challenge.SetUInt8((byte)DataType.OctetString);
             GXCommon.SetObjectCount(tmp.Length, challenge);
             challenge.Set(tmp);
             return(challenge.Array());
         }
         else
         {
             throw new ArgumentException("Invoke failed. Invalid attribute index.");
         }
     }
     else
     {
         throw new ArgumentException("Invoke failed. Invalid attribute index.");
     }
 }
        private static void UpdateInterval(GXDLMSInterval interval, byte[] value)
        {
            GXByteBuffer bb = new GXByteBuffer(value);
            byte         b  = bb.GetUInt8();

            interval.StartHour        = (byte)(b & 0x1F);
            interval.IntervalTariff   = (DefaultTariffBand)((b >> 5) & 0x3);
            interval.UseInterval      = (b >> 7) != 0;
            interval.WeeklyActivation = (WeeklyActivation)bb.GetUInt16();
            UInt16 v = bb.GetUInt16();

            interval.SpecialDayMonth   = (byte)(v & 0xF);
            interval.SpecialDay        = (byte)((v >> 8) & 0xF);
            interval.SpecialDayEnabled = (v >> 15) != 0;
        }
Beispiel #8
0
 byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e)
 {
     //Check reply_to_HLS_authentication
     if (e.Index == 8)
     {
         UInt32 ic = 0;
         byte[] secret;
         if (settings.Authentication == Authentication.HighGMAC)
         {
             secret = settings.SourceSystemTitle;
             GXByteBuffer bb = new GXByteBuffer(e.Parameters as byte[]);
             bb.GetUInt8();
             ic = bb.GetUInt32();
         }
         else
         {
             secret = Secret;
         }
         byte[] serverChallenge = GXSecure.Secure(settings, settings.Cipher, ic, settings.StoCChallenge, secret);
         byte[] clientChallenge = (byte[])e.Parameters;
         if (GXCommon.Compare(serverChallenge, clientChallenge))
         {
             if (settings.Authentication == Authentication.HighGMAC)
             {
                 secret = settings.Cipher.SystemTitle;
                 ic     = settings.Cipher.InvocationCounter;
             }
             else
             {
                 secret = Secret;
             }
             settings.Connected = true;
             return(GXSecure.Secure(settings, settings.Cipher, ic, settings.CtoSChallenge, secret));
         }
         else
         {
             // If the password does not match.
             settings.Connected = false;
             return(null);
         }
     }
     else
     {
         e.Error = ErrorCode.ReadWriteDenied;
         return(null);
     }
 }
Beispiel #9
0
        /// <summary>
        /// Decrypt data.
        /// </summary>
        /// <param name="p">Decryption parameters</param>
        /// <returns>Decrypted data.</returns>
        public static byte[] DecryptAesGcm(AesGcmParameter p, GXByteBuffer data)
        {
            if (data == null || data.Size < 2)
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            byte[]  tmp;
            int     len;
            Command cmd = (Command)data.GetUInt8();

            switch (cmd)
            {
            case Command.GeneralGloCiphering:
                len = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    p.SystemTitle = new byte[len];
                    data.Get(p.SystemTitle);
                }
                break;

            case Command.GeneralCiphering:
            case Command.GloInitiateRequest:
            case Command.GloInitiateResponse:
            case Command.GloReadRequest:
            case Command.GloReadResponse:
            case Command.GloWriteRequest:
            case Command.GloWriteResponse:
            case Command.GloGetRequest:
            case Command.GloGetResponse:
            case Command.GloSetRequest:
            case Command.GloSetResponse:
            case Command.GloMethodRequest:
            case Command.GloMethodResponse:
            case Command.GloEventNotificationRequest:
                break;

            default:
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int    value         = 0;
            UInt64 transactionId = 0;

            if (cmd == Command.GeneralCiphering)
            {
                len = GXCommon.GetObjectCount(data);
                tmp = new byte[len];
                data.Get(tmp);
                GXByteBuffer t = new GXByteBuffer(tmp);
                transactionId = t.GetUInt64();
                len           = GXCommon.GetObjectCount(data);
                tmp           = new byte[len];
                data.Get(tmp);
                p.SystemTitle = tmp;
                len           = GXCommon.GetObjectCount(data);
                tmp           = new byte[len];
                data.Get(tmp);
                p.RecipientSystemTitle = tmp;
                // Get date time.
                len = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.DateTime = tmp;
                }
                // other-information
                len = data.GetUInt8();
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.OtherInformation = tmp;
                }
                // KeyInfo OPTIONAL
                len = data.GetUInt8();
                // AgreedKey CHOICE tag.
                data.GetUInt8();
                // key-parameters
                len             = data.GetUInt8();
                value           = data.GetUInt8();
                p.KeyParameters = value;
                if (value == 1)
                {
                    // KeyAgreement.ONE_PASS_DIFFIE_HELLMAN
                    // key-ciphered-data
                    len = GXCommon.GetObjectCount(data);
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.KeyCipheredData = tmp;
                }
                else if (value == 2)
                {
                    // KeyAgreement.STATIC_UNIFIED_MODEL
                    len = GXCommon.GetObjectCount(data);
                    if (len != 0)
                    {
                        throw new ArgumentException("Invalid key parameters");
                    }
                }
                else
                {
                    throw new ArgumentException("key-parameters");
                }
            }
            len = GXCommon.GetObjectCount(data);
            p.CipheredContent = data.Remaining();
            byte sc = (byte)data.GetUInt8();

            Enums.Security security = (Enums.Security)(sc & 0x30);
            SecuritySuite  ss       = (SecuritySuite)(sc & 0x3);

            p.Security = security;
            UInt32 invocationCounter = data.GetUInt32();

            p.InvocationCounter = invocationCounter;
            if (ss != SecuritySuite.AesGcm128)
            {
                throw new NotImplementedException("Security Suite 1 is not implemented.");
            }
            System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString());
            System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Data,
                                                                              false, data.Position, data.Size - data.Position));
            byte[] tag = new byte[12];
            byte[] encryptedData;
            int    length;

            if (security == Enums.Security.Authentication)
            {
                length        = data.Size - data.Position - 12;
                encryptedData = new byte[length];
                data.Get(encryptedData);
                data.Get(tag);
                // Check tag.
                EncryptAesGcm(p, encryptedData);
                if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
                {
                    if (transactionId != 0)
                    {
                        p.InvocationCounter = transactionId;
                    }
                    throw new GXDLMSException("Decrypt failed. Invalid tag.");
                }
                return(encryptedData);
            }
            byte[] ciphertext = null;
            if (security == Enums.Security.Encryption)
            {
                length     = data.Size - data.Position;
                ciphertext = new byte[length];
                data.Get(ciphertext);
            }
            else if (security == Enums.Security.AuthenticationEncryption)
            {
                length     = data.Size - data.Position - 12;
                ciphertext = new byte[length];
                data.Get(ciphertext);
                data.Get(tag);
            }
            byte[] aad = GetAuthenticatedData(p, ciphertext),
            iv = GetNonse(invocationCounter, p.SystemTitle);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(security, true,
                                                                    p.BlockCipherKey, aad, iv, tag);

            gcm.Write(ciphertext);
            if (transactionId != 0)
            {
                p.InvocationCounter = transactionId;
            }
            return(gcm.FlushFinalBlock());

            /*
             * len = Gurux.DLMS.Internal.GXCommon.GetObjectCount(data);
             * p.Security = (Gurux.DLMS.Enums.Security)data.GetUInt8();
             * p.InvocationCounter = data.GetUInt32();
             * System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString());
             * System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Array(), true));
             *
             * byte[] tag = new byte[12];
             * byte[] encryptedData;
             * int length;
             * if (p.Security == Gurux.DLMS.Enums.Security.Authentication)
             * {
             *  length = data.Size - data.Position - 12;
             *  encryptedData = new byte[length];
             *  data.Get(encryptedData);
             *  data.Get(tag);
             *  // Check tag.
             *  EncryptAesGcm(p, encryptedData);
             *  if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
             *  {
             *      throw new GXDLMSException("Decrypt failed. Invalid tag.");
             *  }
             *  return encryptedData;
             * }
             * byte[] ciphertext = null;
             * if (p.Security == Gurux.DLMS.Enums.Security.Encryption)
             * {
             *  length = data.Size - data.Position;
             *  ciphertext = new byte[length];
             *  data.Get(ciphertext);
             * }
             * else if (p.Security == Gurux.DLMS.Enums.Security.AuthenticationEncryption)
             * {
             *  length = data.Size - data.Position - 12;
             *  ciphertext = new byte[length];
             *  data.Get(ciphertext);
             *  data.Get(tag);
             * }
             * byte[] aad = GetAuthenticatedData(p.Security, p.AuthenticationKey, ciphertext);
             * byte[] iv = GetNonse(p.InvocationCounter, p.SystemTitle);
             * GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(p.Security, true, p.BlockCipherKey, aad, iv, tag);
             * gcm.Write(ciphertext);
             * ciphertext = gcm.FlushFinalBlock();
             * if (p.Security == Gurux.DLMS.Enums.Security.AuthenticationEncryption)
             * {
             *  // Check tag.
             *  EncryptAesGcm(p, ciphertext);
             *  if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
             *  {
             *      //    throw new GXDLMSException("Decrypt failed. Invalid tag.");
             *  }
             * }
             * return ciphertext;
             */
        }
        /// <summary>
        /// Update ephemeral keys.
        /// </summary>
        /// <param name="client">DLMS Client.</param>
        /// <param name="value">Received reply from the server.</param>
        /// <returns>List of Parsed key id and GUAK. This is for debugging purpose.</returns>
        public List <KeyValuePair <GlobalKeyType, byte[]> > UpdateEphemeralKeys(GXDLMSSecureClient client, GXByteBuffer value)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }
            if (value.GetUInt8() != (byte)DataType.Array)
            {
                throw new ArgumentOutOfRangeException("Invalid tag.");
            }
            GXEcdsa c     = new GXEcdsa(client.Ciphering.EphemeralKeyPair.Key);
            int     count = GXCommon.GetObjectCount(value);
            List <KeyValuePair <GlobalKeyType, byte[]> > list = new List <KeyValuePair <GlobalKeyType, byte[]> >();

            for (int pos = 0; pos != count; ++pos)
            {
                if (value.GetUInt8() != (byte)DataType.Structure)
                {
                    throw new ArgumentOutOfRangeException("Invalid tag.");
                }
                if (value.GetUInt8() != 2)
                {
                    throw new ArgumentOutOfRangeException("Invalid length.");
                }
                if (value.GetUInt8() != (byte)DataType.Enum)
                {
                    throw new ArgumentOutOfRangeException("Invalid key id data type.");
                }
                int keyId = value.GetUInt8();
                if (keyId > 4)
                {
                    throw new ArgumentOutOfRangeException("Invalid key type.");
                }
                if (value.GetUInt8() != (byte)DataType.OctetString)
                {
                    throw new ArgumentOutOfRangeException("Invalid tag.");
                }
                if (GXCommon.GetObjectCount(value) != 128)
                {
                    throw new ArgumentOutOfRangeException("Invalid length.");
                }
                //Get ephemeral public key server.
                GXByteBuffer key = new GXByteBuffer();
                key.SetUInt8(4);
                key.Set(value, 64);
                GXPublicKey targetEphemeralKey = GXPublicKey.FromRawBytes(key.Array());
                //Get ephemeral public key signature server.
                byte[] signature = new byte[64];
                value.Get(signature);
                key.SetUInt8(0, (byte)keyId);
                //Verify signature.
                if (!GXSecure.ValidateEphemeralPublicKeySignature(key.Array(), signature, client.Ciphering.SigningKeyPair.Value))
                {
                    throw new GXDLMSCipherException("Invalid signature.");
                }
                byte[] z = c.GenerateSecret(targetEphemeralKey);
                System.Diagnostics.Debug.WriteLine("Shared secret:" + GXCommon.ToHex(z, true));
                GXByteBuffer kdf = new GXByteBuffer();
                kdf.Set(GXSecure.GenerateKDF(client.SecuritySuite, z,
                                             AlgorithmId.AesGcm128,
                                             client.Ciphering.SystemTitle,
                                             client.Settings.SourceSystemTitle, null, null));
                System.Diagnostics.Debug.WriteLine("KDF:" + kdf.ToString());
                list.Add(new KeyValuePair <GlobalKeyType, byte[]>((GlobalKeyType)keyId, kdf.SubArray(0, 16)));
            }
            //Update ephemeral keys.
            foreach (KeyValuePair <GlobalKeyType, byte[]> it in list)
            {
                switch (it.Key)
                {
                case GlobalKeyType.UnicastEncryption:
                    client.Settings.EphemeralBlockCipherKey = it.Value;
                    break;

                case GlobalKeyType.BroadcastEncryption:
                    client.Settings.EphemeralBroadcastBlockCipherKey = it.Value;
                    break;

                case GlobalKeyType.Authentication:
                    client.Settings.EphemeralAuthenticationKey = it.Value;
                    break;

                case GlobalKeyType.Kek:
                    client.Settings.EphemeralKek = it.Value;
                    break;
                }
            }
            return(list);
        }
 void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         LogicalName = GXCommon.ToLogicalName(e.Value);
     }
     else if (e.Index == 2)
     {
         ObjectList.Clear();
         if (e.Value != null)
         {
             foreach (Object[] item in (Object[])e.Value)
             {
                 ObjectType   type    = (ObjectType)Convert.ToInt32(item[0]);
                 int          version = Convert.ToInt32(item[1]);
                 String       ln      = GXCommon.ToLogicalName((byte[])item[2]);
                 GXDLMSObject obj     = null;
                 if (settings.Objects != null)
                 {
                     obj = settings.Objects.FindByLN(type, ln);
                 }
                 if (obj == null)
                 {
                     obj             = Gurux.DLMS.GXDLMSClient.CreateObject(type);
                     obj.LogicalName = ln;
                     obj.Version     = version;
                 }
                 //Unknown objects are not shown.
                 if (obj is IGXDLMSBase && item[3] != null)
                 {
                     UpdateAccessRights(obj, (Object[])item[3]);
                     ObjectList.Add(obj);
                 }
             }
         }
     }
     else if (e.Index == 3)
     {
         if (e.Value != null)
         {
             ClientSAP = Convert.ToByte(((Object[])e.Value)[0]);
             ServerSAP = Convert.ToUInt16(((Object[])e.Value)[1]);
         }
     }
     else if (e.Index == 4)
     {
         //Value of the object identifier encoded in BER
         if (e.Value is byte[])
         {
             GXByteBuffer arr = new GXByteBuffer(e.Value as byte[]);
             if (arr.GetUInt8(0) == 0x60)
             {
                 ApplicationContextName.JointIsoCtt = 0;
                 ++arr.Position;
                 ApplicationContextName.Country = 0;
                 ++arr.Position;
                 ApplicationContextName.CountryName = 0;
                 ++arr.Position;
                 ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                 ApplicationContextName.DlmsUA             = arr.GetUInt8();
                 ApplicationContextName.ApplicationContext = arr.GetUInt8();
                 ApplicationContextName.ContextId          = arr.GetUInt8();
             }
             else
             {
                 //Get Tag and Len.
                 if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.JointIsoCtt = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.Country = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x12)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.CountryName = arr.GetUInt16();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.DlmsUA = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.ApplicationContext = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.ContextId = arr.GetUInt8();
             }
         }
         else if (e.Value != null)
         {
             Object[] arr = (Object[])e.Value;
             ApplicationContextName.JointIsoCtt            = Convert.ToByte(arr[0]);
             ApplicationContextName.Country                = Convert.ToByte(arr[1]);
             ApplicationContextName.CountryName            = Convert.ToUInt16(arr[2]);
             ApplicationContextName.IdentifiedOrganization = Convert.ToByte(arr[3]);
             ApplicationContextName.DlmsUA             = Convert.ToByte(arr[4]);
             ApplicationContextName.ApplicationContext = Convert.ToByte(arr[5]);
             ApplicationContextName.ContextId          = Convert.ToByte(arr[6]);
         }
     }
     else if (e.Index == 5)
     {
         if (e.Value != null)
         {
             Object[]     arr = (Object[])e.Value;
             GXByteBuffer bb  = new GXByteBuffer();
             GXCommon.SetBitString(bb, arr[0]);
             bb.SetUInt8(0, 0);
             XDLMSContextInfo.Conformance       = (Conformance)bb.GetUInt32();
             XDLMSContextInfo.MaxReceivePduSize = Convert.ToUInt16(arr[1]);
             XDLMSContextInfo.MaxSendPduSize    = Convert.ToUInt16(arr[2]);
             XDLMSContextInfo.DlmsVersionNumber = Convert.ToByte(arr[3]);
             XDLMSContextInfo.QualityOfService  = Convert.ToSByte(arr[4]);
             XDLMSContextInfo.CypheringInfo     = (byte[])arr[5];
         }
     }
     else if (e.Index == 6)
     {
         //Value of the object identifier encoded in BER
         if (e.Value is byte[])
         {
             GXByteBuffer arr = new GXByteBuffer(e.Value as byte[]);
             if (arr.GetUInt8(0) == 0x60)
             {
                 AuthenticationMechanismName.JointIsoCtt = 0;
                 ++arr.Position;
                 AuthenticationMechanismName.Country = 0;
                 ++arr.Position;
                 AuthenticationMechanismName.CountryName = 0;
                 ++arr.Position;
                 AuthenticationMechanismName.IdentifiedOrganization = arr.GetUInt8();
                 AuthenticationMechanismName.DlmsUA = arr.GetUInt8();
                 AuthenticationMechanismName.AuthenticationMechanismName = arr.GetUInt8();
                 AuthenticationMechanismName.MechanismId = (Authentication)arr.GetUInt8();
             }
             else
             {
                 //Get Tag and Len.
                 if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.JointIsoCtt = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.Country = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x12)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.CountryName = arr.GetUInt16();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.IdentifiedOrganization = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.DlmsUA = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.AuthenticationMechanismName = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.MechanismId = (Authentication)arr.GetUInt8();
             }
         }
         else if (e.Value != null)
         {
             Object[] arr = (Object[])e.Value;
             AuthenticationMechanismName.JointIsoCtt            = Convert.ToByte(arr[0]);
             AuthenticationMechanismName.Country                = Convert.ToByte(arr[1]);
             AuthenticationMechanismName.CountryName            = Convert.ToUInt16(arr[2]);
             AuthenticationMechanismName.IdentifiedOrganization = Convert.ToByte(arr[3]);
             AuthenticationMechanismName.DlmsUA = Convert.ToByte(arr[4]);
             AuthenticationMechanismName.AuthenticationMechanismName = Convert.ToByte(arr[5]);
             AuthenticationMechanismName.MechanismId = (Authentication)Convert.ToByte(arr[6]);
         }
     }
     else if (e.Index == 7)
     {
         Secret = (byte[])e.Value;
     }
     else if (e.Index == 8)
     {
         if (e.Value == null)
         {
             AssociationStatus = AssociationStatus.NonAssociated;
         }
         else
         {
             AssociationStatus = (AssociationStatus)Convert.ToInt32(e.Value);
         }
     }
     else if (e.Index == 9)
     {
         SecuritySetupReference = GXCommon.ToLogicalName(e.Value);
     }
     else
     {
         e.Error = ErrorCode.ReadWriteDenied;
     }
 }
Beispiel #12
0
        /// <summary>
        /// Parse User Information from PDU.
        /// </summary>
        public static void ParseUserInformation(GXDLMSSettings settings, GXICipher cipher, GXByteBuffer data, GXDLMSTranslatorStructure xml)
        {
            byte len = data.GetUInt8();
            GXByteBuffer tmp2 = new GXByteBuffer();
            tmp2.SetUInt8(0);
            if (data.Size - data.Position < len)
            {
                throw new Exception("Not enough data.");
            }
            if (xml != null && xml.OutputType == TranslatorOutputType.StandardXml)
            {
                len = (byte)(data.Size - data.Position);
                xml.AppendLine(Command.InitiateRequest, null, GXCommon
                               .ToHex(data.Data, false, data.Position, len));
                data.Position = data.Position + len;
                return;
            }
            //Excoding the choice for user information
            int tag = data.GetUInt8();
            if (tag != 0x4)
            {
                throw new Exception("Invalid tag.");
            }
            len = data.GetUInt8();
            //Tag for xDLMS-Initate.response
            tag = data.GetUInt8();
            if (tag == (byte)Command.GloInitiateResponse)
            {
                if (xml != null)
                {
                    int cnt = GXCommon.GetObjectCount(data);
                    byte[] tmp = new byte[cnt];
                    data.Get(tmp);
                    //<glo_InitiateResponse>
                    xml.AppendLine(Command.GloInitiateResponse, "Value", GXCommon.ToHex(tmp, false));
                    return;
                }
                --data.Position;
                cipher.Security = cipher.Decrypt(settings.SourceSystemTitle, data);
                tag = data.GetUInt8();
            }
            else if (tag == (byte)Command.GloInitiateRequest)
            {
                if (xml != null)
                {
                    int cnt = GXCommon.GetObjectCount(data);
                    byte[] tmp = new byte[cnt];
                    data.Get(tmp);
                    //<glo_InitiateRequest>
                    xml.AppendLine(Command.GloInitiateRequest, "Value", GXCommon.ToHex(tmp, false));
                    return;
                }
                --data.Position;
                cipher.Security = cipher.Decrypt(settings.SourceSystemTitle, data);
                tag = data.GetUInt8();
            }
            bool response = tag == (byte)Command.InitiateResponse;
            if (response)
            {
                if (xml != null)
                {
                    //<InitiateResponse>
                    xml.AppendStartTag(Command.InitiateResponse);
                }
                //Optional usage field of the negotiated quality of service component
                tag = data.GetUInt8();
                len = 0;
                if (tag != 0)//Skip if used.
                {
                    len = data.GetUInt8();
                    data.Position += len;
                    if (len == 0 && xml != null)
                    {
                        //NegotiatedQualityOfService
                        xml.AppendLine(TranslatorGeneralTags.NegotiatedQualityOfService, "Value", "00");
                    }
                }
            }
            else if (tag == (byte)Command.InitiateRequest)
            {
                if (xml != null)
                {
                    //<InitiateRequest>
                    xml.AppendStartTag(Command.InitiateRequest);
                }
                //Optional usage field of the negotiated quality of service component
                tag = data.GetUInt8();
                //CtoS.
                if (tag != 0)
                {
                    len = data.GetUInt8();
                    settings.CtoSChallenge = new byte[len];
                    data.Get(settings.CtoSChallenge);
                }
                //Optional usage field of the negotiated quality of service component
                tag = data.GetUInt8();
                if (tag != 0)//Skip if used.
                {
                    len = data.GetUInt8();
                    data.Position += len;
                }
                //Optional usage field of the proposed quality of service component
                tag = data.GetUInt8();
                if (tag != 0)//Skip if used.
                {
                    len = data.GetUInt8();
                    data.Position += len;
                }
            }
            else
            {
                throw new Exception("Invalid tag.");
            }
            //Get DLMS version number.
            if (!response)
            {
                if (data.GetUInt8() != 6)
                {
                    throw new Exception("Invalid DLMS version number.");
                }
                //ProposedDlmsVersionNumber
                if (xml != null)
                {
                    xml.AppendLine(TranslatorGeneralTags.ProposedDlmsVersionNumber, "Value", xml.IntegerToHex(settings.DLMSVersion, 2));
                }
            }
            else
            {
                if (data.GetUInt8() != 6)
                {
                    throw new Exception("Invalid DLMS version number.");
                }
                if (xml != null)
                {
                    xml.AppendLine(TranslatorGeneralTags.NegotiatedDlmsVersionNumber, "Value", xml.IntegerToHex(settings.DLMSVersion, 2));
                }
            }

            //Tag for conformance block
            tag = data.GetUInt8();
            if (tag != 0x5F)
            {
                throw new Exception("Invalid tag.");
            }
            //Old Way...
            if (data.GetUInt8(data.Position) == 0x1F)
            {
                data.GetUInt8();
            }
            len = data.GetUInt8();
            //The number of unused bits in the bit string.
            tag = data.GetUInt8();
            if (!response)
            {
                //ProposedConformance
                if (xml != null)
                {
                    xml.AppendStartTag(TranslatorGeneralTags.ProposedConformance);
                }
                data.Get(settings.ConformanceBlock);
                tmp2.Set(settings.ConformanceBlock);
            }
            else
            {
                //NegotiatedConformance
                if (xml != null)
                {
                    xml.AppendStartTag(TranslatorGeneralTags.NegotiatedConformance);
                }
                if (settings.UseLogicalNameReferencing)
                {
                    data.Get(settings.LnSettings.ConformanceBlock);
                    tmp2.Set(settings.LnSettings.ConformanceBlock);
                }
                else
                {
                    data.Get(settings.SnSettings.ConformanceBlock);
                    tmp2.Set(settings.SnSettings.ConformanceBlock);
                }
            }
            if (xml != null)
            {
                GetConformance(tmp2.GetUInt32(), xml);
            }
            if (!response)
            {
                //Proposed max PDU size.
                settings.MaxPduSize = data.GetUInt16();
                if (xml != null)
                {
                    //ProposedConformance closing
                    xml.AppendEndTag(TranslatorGeneralTags.ProposedConformance);
                    //ProposedMaxPduSize
                    xml.AppendLine(TranslatorGeneralTags.ProposedMaxPduSize, "Value", xml.IntegerToHex(settings.MaxPduSize, 4));
                }
                //If client asks too high PDU.
                if (settings.MaxPduSize > settings.MaxServerPDUSize)
                {
                    settings.MaxPduSize = settings.MaxServerPDUSize;
                }
            }
            else
            {
                //Max PDU size.
                settings.MaxPduSize = data.GetUInt16();
                if (xml != null)
                {
                    //NegotiatedConformance closing
                    xml.AppendEndTag(TranslatorGeneralTags.NegotiatedConformance);
                    //NegotiatedMaxPduSize
                    xml.AppendLine(TranslatorGeneralTags.NegotiatedMaxPduSize, "Value", xml.IntegerToHex(settings.MaxPduSize, 4));
                }
            }
            if (response)
            {
                //VAA Name
                tag = data.GetUInt16();
                if (xml != null)
                {
                    xml.AppendLine(TranslatorGeneralTags.VaaName, "Value", xml.IntegerToHex(tag, 4));
                }
                if (tag == 0x0007)
                {
                    // If LN
                    if (!settings.UseLogicalNameReferencing)
                    {
                        throw new ArgumentException("Invalid VAA.");
                    }
                }
                else if (tag == 0xFA00)
                {
                    // If SN
                    if (settings.UseLogicalNameReferencing)
                    {
                        throw new ArgumentException("Invalid VAA.");
                    }
                }
                else
                {
                    // Unknown VAA.
                    throw new ArgumentException("Invalid VAA.");
                }
                if (xml != null)
                {
                    //<InitiateResponse>
                    xml.AppendEndTag(Command.InitiateResponse);
                }
            }
            else if (xml != null)
            {
                //</InitiateRequest>
                xml.AppendEndTag(Command.InitiateRequest);
            }
        }
    byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e)
    {
        //Check reply_to_HLS_authentication
        if (e.Index == 8)
        {
            UInt32 ic = 0;
            byte[] secret;
            if (settings.Authentication == Authentication.HighGMAC)
            {
                secret = settings.SourceSystemTitle;
                GXByteBuffer bb = new GXByteBuffer(e.Parameters as byte[]);
                bb.GetUInt8();
                ic = bb.GetUInt32();
            }
            else
            {
                secret = HlsSecret;
            }
            byte[] serverChallenge = GXSecure.Secure(settings, settings.Cipher, ic, settings.StoCChallenge, secret);
            byte[] clientChallenge = (byte[])e.Parameters;
            if (GXCommon.Compare(serverChallenge, clientChallenge))
            {
                if (settings.Authentication == Authentication.HighGMAC)
                {
                    secret = settings.Cipher.SystemTitle;
                    ic = settings.Cipher.FrameCounter;
                }
                else
                {
                    secret = HlsSecret;
                }
                settings.Connected = true;
                return GXSecure.Secure(settings, settings.Cipher, ic, settings.CtoSChallenge, secret);
            }
            else
            {
                // If the password does not match.
                settings.Connected = false;
                return null;
            }

        }
        else
        {
            e.Error = ErrorCode.ReadWriteDenied;
            return null;
        }
    }
        /// <summary>
        /// Decrypt data.
        /// </summary>
        /// <param name="p">Decryption parameters</param>
        /// <returns>Decrypted data.</returns>
        public static byte[] DecryptAesGcm(AesGcmParameter p, GXByteBuffer data)
        {
            if (data == null || data.Size < 2)
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int len;
            Command cmd = (Command)data.GetUInt8();
            switch (cmd)
            {
                case Command.GloGeneralCiphering:
                    len = GXCommon.GetObjectCount(data);
                    p.SystemTitle = new byte[len];
                    data.Get(p.SystemTitle);
                    break;
                case Command.GloInitiateRequest:
                case Command.GloInitiateResponse:
                case Command.GloReadRequest:
                case Command.GloReadResponse:
                case Command.GloWriteRequest:
                case Command.GloWriteResponse:
                case Command.GloGetRequest:
                case Command.GloGetResponse:
                case Command.GloSetRequest:
                case Command.GloSetResponse:
                case Command.GloMethodRequest:
                case Command.GloMethodResponse:
                case Command.GloEventNotificationRequest:
                    break;
                default:
                    throw new ArgumentOutOfRangeException("cryptedData");
            }
            len = Gurux.DLMS.Internal.GXCommon.GetObjectCount(data);
            p.Security = (Gurux.DLMS.Enums.Security)data.GetUInt8();
            p.FrameCounter = data.GetUInt32();
            System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString());
            System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Array(), true));

            byte[] tag = new byte[12];
            byte[] encryptedData;
            int length;
            if (p.Security == Gurux.DLMS.Enums.Security.Authentication)
            {
                length = data.Size - data.Position - 12;
                encryptedData = new byte[length];
                data.Get(encryptedData);
                data.Get(tag);
                // Check tag.
                EncryptAesGcm(p, encryptedData);
                if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
                {
                    throw new GXDLMSException("Decrypt failed. Invalid tag.");
                }
                return encryptedData;
            }
            byte[] ciphertext = null;
            if (p.Security == Gurux.DLMS.Enums.Security.Encryption)
            {
                length = data.Size - data.Position;
                ciphertext = new byte[length];
                data.Get(ciphertext);
            }
            else if (p.Security == Gurux.DLMS.Enums.Security.AuthenticationEncryption)
            {
                length = data.Size - data.Position - 12;
                ciphertext = new byte[length];
                data.Get(ciphertext);
                data.Get(tag);
            }
            byte[] aad = GetAuthenticatedData(p.Security, p.AuthenticationKey, data.Array());
            byte[] iv = GetNonse(p.FrameCounter, p.SystemTitle);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(p.Security, true, p.BlockCipherKey, aad, iv, tag);
            gcm.Write(ciphertext);
            return gcm.FlushFinalBlock();
        }
Beispiel #15
0
        ///<summary>
        ///Parse APDU.
        ///</summary>
        static internal SourceDiagnostic ParsePDU(GXDLMSSettings settings, GXICipher cipher,
                GXByteBuffer buff, GXDLMSTranslatorStructure xml)
        {
            // Get AARE tag and length
            int tag = buff.GetUInt8();
            if (settings.IsServer)
            {
                if (tag != ((byte)BerType.Application | (byte)BerType.Constructed | (byte)PduType.ProtocolVersion))
                {
                    throw new Exception("Invalid tag.");
                }
            }
            else
            {
                if (tag != ((byte)BerType.Application | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName))
                {
                    throw new Exception("Invalid tag.");
                }
            }
            int len = buff.GetUInt8();
            int size = buff.Size - buff.Position;
            if (len > size)
            {
                throw new Exception("Not enough data.");
            }
            //Opening tags
            if (xml != null)
            {
                if (settings.IsServer)
                {
                    xml.AppendStartTag(Command.Aarq);
                }
                else
                {
                    xml.AppendStartTag(Command.Aare);
                }
            }
            AssociationResult resultComponent = AssociationResult.Accepted;
            SourceDiagnostic resultDiagnosticValue = SourceDiagnostic.None;
            while (buff.Position < buff.Size)
            {
                tag = buff.GetUInt8();
                switch (tag)
                {
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName://0xA1
                        if (!ParseApplicationContextName(settings, buff, xml))
                        {
                            throw new GXDLMSException(AssociationResult.PermanentRejected, SourceDiagnostic.ApplicationContextNameNotSupported);
                        }
                        break;
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApTitle://0xA2
                                                                                                         //Get len.
                        if (buff.GetUInt8() != 3)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        //Choice for result (INTEGER, universal)
                        if (buff.GetUInt8() != (byte)BerType.Integer)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        //Get len.
                        if (buff.GetUInt8() != 1)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        resultComponent = (AssociationResult)buff.GetUInt8();
                        if (xml != null)
                        {
                            xml.AppendLine(TranslatorGeneralTags.AssociationResult, "Value", xml.IntegerToHex((int)resultComponent, 2));
                            xml.AppendStartTag(TranslatorGeneralTags.ResultSourceDiagnostic);
                        }
                        break;
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledAeQualifier:////SourceDiagnostic 0xA3
                        len = buff.GetUInt8();
                        // ACSE service user tag.
                        tag = buff.GetUInt8();
                        len = buff.GetUInt8();
                        // Result source diagnostic component.
                        if (buff.GetUInt8() != (byte)BerType.Integer)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        if (buff.GetUInt8() != 1)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        resultDiagnosticValue = (SourceDiagnostic)buff.GetUInt8();
                        if (xml != null)
                        {
                            xml.AppendLine(TranslatorGeneralTags.ACSEServiceUser, "Value", xml.IntegerToHex((int)resultDiagnosticValue, 2));
                            xml.AppendEndTag(TranslatorGeneralTags.ResultSourceDiagnostic);
                        }
                        break;
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApInvocationId:
                        ////Result 0xA4
                        //Get len.
                        if (buff.GetUInt8() != 0xA)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        //Choice for result (Universal, Octetstring type)
                        if (buff.GetUInt8() != (byte)BerType.OctetString)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        //responding-AP-title-field
                        //Get len.
                        len = buff.GetUInt8();
                        settings.SourceSystemTitle = new byte[len];
                        buff.Get(settings.SourceSystemTitle);
                        if (xml != null)
                        {
                            //RespondingAPTitle
                            xml.AppendLine(TranslatorGeneralTags.RespondingAPTitle, "Value", GXCommon.ToHex(settings.SourceSystemTitle, false));
                        }
                        break;
                    //Client Challenge.
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CallingApTitle://0xA6
                        len = buff.GetUInt8();
                        tag = buff.GetUInt8();
                        len = buff.GetUInt8();
                        settings.SourceSystemTitle = new byte[len];
                        buff.Get(settings.SourceSystemTitle);
                        if (xml != null)
                        {
                            //CallingAPTitle
                            xml.AppendLine(TranslatorGeneralTags.CallingAPTitle, "Value", GXCommon.ToHex(settings.SourceSystemTitle, false));
                        }
                        break;
                    //Server Challenge.
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.SenderAcseRequirements://0xAA
                        len = buff.GetUInt8();
                        tag = buff.GetUInt8();
                        len = buff.GetUInt8();
                        settings.StoCChallenge = new byte[len];
                        buff.Get(settings.StoCChallenge);
                        AppendServerSystemTitleToXml(settings, xml, tag);
                        break;
                    case (byte)BerType.Context | (byte)PduType.SenderAcseRequirements:
                    //0x8A
                    case (byte)BerType.Context | (byte)PduType.CallingApInvocationId:
                        //0x88

                        //Get sender ACSE-requirements field component.
                        if (buff.GetUInt8() != 2)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        if (buff.GetUInt8() != (byte)BerType.ObjectDescriptor)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        if (buff.GetUInt8() != 0x80)
                        {
                            throw new Exception("Invalid tag.");
                        }
                        //SenderACSERequirements
                        if (xml != null)
                        {
                            xml.AppendLine(tag, "Value", "1");
                        }
                        break;
                    case (byte)BerType.Context | (byte)PduType.MechanismName://0x8B
                    case (byte)BerType.Context | (byte)PduType.CallingAeInvocationId://0x89
                        UpdateAuthentication(settings, buff);
                        if (xml != null)
                        {
                            if (xml.OutputType == TranslatorOutputType.SimpleXml)
                            {
                                xml.AppendLine(tag, "Value", settings.Authentication.ToString());
                            }
                            else
                            {
                                xml.AppendLine(tag, "Value", ((int)settings.Authentication).ToString());
                            }
                        }
                        break;
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CallingAuthenticationValue://0xAC
                        updatePassword(settings, buff, xml);
                        break;
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.UserInformation:
                        //0xBE
                        if (xml == null && resultComponent != AssociationResult.Accepted && resultDiagnosticValue != SourceDiagnostic.None)
                        {
                            throw new GXDLMSException(resultComponent, resultDiagnosticValue);
                        }
                        ParseUserInformation(settings, cipher, buff, xml);
                        break;
                    default:
                        //Unknown tags.
                        System.Diagnostics.Debug.WriteLine("Unknown tag: " + tag + ".");
                        if (buff.Position < buff.Size)
                        {
                            len = buff.GetUInt8();
                            buff.Position += (UInt16)len;
                        }
                        break;
                }
            }
            //Closing tags
            if (xml != null)
            {
                if (settings.IsServer)
                {
                    xml.AppendEndTag(Command.Aarq);
                }
                else
                {
                    xml.AppendEndTag(Command.Aare);
                }
            }
            return resultDiagnosticValue;
        }
Beispiel #16
0
 /// <summary>
 /// Get object count. If first byte is 0x80 or higger it will tell bytes count.
 /// </summary>
 /// <param name="data">Received data.</param>
 /// <returns>Object count.</returns>
 public static int GetObjectCount(GXByteBuffer data)
 {
     int cnt = data.GetUInt8();
     if (cnt > 0x80)
     {
         if (cnt == 0x81)
         {
             return data.GetUInt8();
         }
         else if (cnt == 0x82)
         {
             return data.GetUInt16();
         }
         else if (cnt == 0x84)
         {
             return (int)data.GetUInt32();
         }
         else
         {
             throw new System.ArgumentException("Invalid count.");
         }
     }
     return cnt;
 }
Beispiel #17
0
 /// <summary>
 /// Get HDLC address from byte array.
 /// </summary>
 /// <param name="GXByteBuffer">Byte array.</param>
 /// <returns>HDLC address.</returns>
 public static int GetHDLCAddress(GXByteBuffer buff)
 {
     int size = 0;
     for (int pos = buff.Position; pos != buff.Size; ++pos)
     {
         ++size;
         if ((buff.GetUInt8(pos) & 0x1) == 1)
         {
             break;
         }
     }
     if (size == 1)
     {
         return (byte)((buff.GetUInt8() & 0xFE) >> 1);
     }
     else if (size == 2)
     {
         size = buff.GetUInt16();
         size = ((size & 0xFE) >> 1) | ((size & 0xFE00) >> 2);
         return size;
     }
     else if (size == 4)
     {
         UInt32 tmp = buff.GetUInt32();
         tmp = ((tmp & 0xFE) >> 1) | ((tmp & 0xFE00) >> 2)
               | ((tmp & 0xFE0000) >> 3) | ((tmp & 0xFE000000) >> 4);
         return (int)tmp;
     }
     throw new ArgumentException("Wrong size.");
 }
Beispiel #18
0
 ///<summary>
 ///Convert Bit string to DLMS bytes.
 ///</summary>
 ///<param name="buff">
 ///Byte buffer where data is write.
 ///</param>
 ///<param name="value">
 ///Added value.
 ///</param>
 private static void SetBitString(GXByteBuffer buff, object value)
 {
     if (value is string)
     {
         GXByteBuffer tmp = new GXByteBuffer();
         byte val = 0;
         int index = 0;
         string str = ((string)value);
         SetObjectCount(str.Length, buff);
         foreach (char it in str.Reverse())
         {
             if (it == '1')
             {
                 val |= (byte)(1 << index);
                 ++index;
             }
             else if (it == '0')
             {
                 ++index;
             }
             else
             {
                 throw new Exception("Not a bit string.");
             }
             if (index == 8)
             {
                 index = 0;
                 tmp.SetUInt8(val);
                 val = 0;
             }
         }
         if (index != 0)
         {
             tmp.SetUInt8(val);
         }
         for (int pos = tmp.Size - 1; pos != -1; --pos)
         {
             buff.SetUInt8(tmp.GetUInt8(pos));
         }
     }
     else if (value is sbyte[])
     {
         byte[] arr = (byte[])value;
         SetObjectCount(arr.Length, buff);
         buff.Set(arr);
     }
     else if (value == null)
     {
         buff.SetUInt8(0);
     }
     else
     {
         throw new Exception("BitString must give as string.");
     }
 }
Beispiel #19
0
 ///<summary>
 ///Get boolean value from DLMS data.
 ///</summary>
 ///<param name="buff">
 ///Received DLMS data.
 ///</param>
 ///<param name="info">
 ///Data info.
 ///</param>
 ///<returns>
 ///Parsed boolean value.
 ///</returns>
 private static object GetBoolean(GXByteBuffer buff, GXDataInfo info)
 {
     // If there is not enough data available.
     if (buff.Size - buff.Position < 1)
     {
         info.Complete = false;
         return null;
     }
     byte value = buff.GetUInt8();
     if (info.xml != null)
     {
         info.xml.AppendLine(GXDLMS.DATA_TYPE_OFFSET + (int)info.Type, "Value", value);
     }
     return value != 0;
 }
Beispiel #20
0
 ///<summary>
 ///Get bit string value from DLMS data.
 ///</summary>
 ///<param name="buff">
 ///Received DLMS data.
 ///</param>
 ///<param name="info">
 ///Data info.
 ///</param>
 ///<returns>
 ///Parsed bit string value.
 ///</returns>
 private static string GetBitString(GXByteBuffer buff, GXDataInfo info)
 {
     int cnt = GetObjectCount(buff);
     double t = cnt;
     t /= 8;
     if (cnt % 8 != 0)
     {
         ++t;
     }
     int byteCnt = (int)Math.Floor(t);
     // If there is not enough data available.
     if (buff.Size - buff.Position < byteCnt)
     {
         info.Complete = false;
         return null;
     }
     StringBuilder sb = new StringBuilder();
     while (cnt > 0)
     {
         ToBitString(sb, buff.GetUInt8(), cnt);
         cnt -= 8;
     }
     if (info.xml != null)
     {
         info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", sb.ToString());
     }
     return sb.ToString();
 }
Beispiel #21
0
        /// <summary>
        /// Decrypt data.
        /// </summary>
        /// <param name="p">Decryption parameters</param>
        /// <returns>Decrypted data.</returns>
        public static byte[] DecryptAesGcm(AesGcmParameter p, GXByteBuffer data)
        {
            if (data == null || data.Size < 2)
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int     len;
            Command cmd = (Command)data.GetUInt8();

            switch (cmd)
            {
            case Command.GeneralGloCiphering:
                len = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    p.SystemTitle = new byte[len];
                    data.Get(p.SystemTitle);
                }
                break;

            case Command.GloInitiateRequest:
            case Command.GloInitiateResponse:
            case Command.GloReadRequest:
            case Command.GloReadResponse:
            case Command.GloWriteRequest:
            case Command.GloWriteResponse:
            case Command.GloGetRequest:
            case Command.GloGetResponse:
            case Command.GloSetRequest:
            case Command.GloSetResponse:
            case Command.GloMethodRequest:
            case Command.GloMethodResponse:
            case Command.GloEventNotificationRequest:
                break;

            default:
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            len                 = Gurux.DLMS.Internal.GXCommon.GetObjectCount(data);
            p.Security          = (Gurux.DLMS.Enums.Security)data.GetUInt8();
            p.InvocationCounter = data.GetUInt32();
            System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString());
            System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Array(), true));

            byte[] tag = new byte[12];
            byte[] encryptedData;
            int    length;

            if (p.Security == Gurux.DLMS.Enums.Security.Authentication)
            {
                length        = data.Size - data.Position - 12;
                encryptedData = new byte[length];
                data.Get(encryptedData);
                data.Get(tag);
                // Check tag.
                EncryptAesGcm(p, encryptedData);
                if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
                {
                    throw new GXDLMSException("Decrypt failed. Invalid tag.");
                }
                return(encryptedData);
            }
            byte[] ciphertext = null;
            if (p.Security == Gurux.DLMS.Enums.Security.Encryption)
            {
                length     = data.Size - data.Position;
                ciphertext = new byte[length];
                data.Get(ciphertext);
            }
            else if (p.Security == Gurux.DLMS.Enums.Security.AuthenticationEncryption)
            {
                length     = data.Size - data.Position - 12;
                ciphertext = new byte[length];
                data.Get(ciphertext);
                data.Get(tag);
            }
            byte[] aad = GetAuthenticatedData(p.Security, p.AuthenticationKey, ciphertext);
            byte[] iv  = GetNonse(p.InvocationCounter, p.SystemTitle);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(p.Security, true, p.BlockCipherKey, aad, iv, tag);

            gcm.Write(ciphertext);
            ciphertext = gcm.FlushFinalBlock();
            if (p.Security == Gurux.DLMS.Enums.Security.AuthenticationEncryption)
            {
                // Check tag.
                EncryptAesGcm(p, ciphertext);
                if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
                {
                    //    throw new GXDLMSException("Decrypt failed. Invalid tag.");
                }
            }
            return(ciphertext);
        }
        /// <summary>
        /// Decrypt data.
        /// </summary>
        /// <param name="p">Decryption parameters</param>
        /// <returns>Decrypted data.</returns>
        public static byte[] DecryptAesGcm(AesGcmParameter p, GXByteBuffer data)
        {
            if (data == null || data.Size < 2)
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            byte[]  tmp;
            int     len;
            Command cmd = (Command)data.GetUInt8();

            switch (cmd)
            {
            case Command.GeneralGloCiphering:
            case Command.GeneralDedCiphering:
                len = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    p.SystemTitle = new byte[len];
                    data.Get(p.SystemTitle);
                    if (p.Xml != null && p.Xml.Comments)
                    {
                        p.Xml.AppendComment(GXCommon.SystemTitleToString(Standard.DLMS, p.SystemTitle));
                    }
                }
                if (p.SystemTitle == null || p.SystemTitle.Length != 8)
                {
                    if (p.Xml == null)
                    {
                        throw new ArgumentNullException("Invalid sender system title.");
                    }
                    else
                    {
                        p.Xml.AppendComment("Invalid sender system title.");
                    }
                }
                break;

            case Command.GeneralCiphering:
            case Command.GloInitiateRequest:
            case Command.GloInitiateResponse:
            case Command.GloReadRequest:
            case Command.GloReadResponse:
            case Command.GloWriteRequest:
            case Command.GloWriteResponse:
            case Command.GloGetRequest:
            case Command.GloGetResponse:
            case Command.GloSetRequest:
            case Command.GloSetResponse:
            case Command.GloMethodRequest:
            case Command.GloMethodResponse:
            case Command.GloEventNotification:
            case Command.DedInitiateRequest:
            case Command.DedInitiateResponse:
            case Command.DedGetRequest:
            case Command.DedGetResponse:
            case Command.DedSetRequest:
            case Command.DedSetResponse:
            case Command.DedMethodRequest:
            case Command.DedMethodResponse:
            case Command.DedEventNotification:
            case Command.DedReadRequest:
            case Command.DedReadResponse:
            case Command.DedWriteRequest:
            case Command.DedWriteResponse:
            case Command.GloConfirmedServiceError:
            case Command.DedConfirmedServiceError:
                break;

            default:
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int    value         = 0;
            UInt64 transactionId = 0;

            if (cmd == Command.GeneralCiphering)
            {
                len = GXCommon.GetObjectCount(data);
                tmp = new byte[len];
                data.Get(tmp);
                GXByteBuffer t = new GXByteBuffer(tmp);
                transactionId = t.GetUInt64();
                len           = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.SystemTitle = tmp;
                }
                if (p.SystemTitle == null || p.SystemTitle.Length != 8)
                {
                    if (p.Xml == null)
                    {
                        throw new ArgumentNullException("Invalid sender system title.");
                    }
                    else
                    {
                        p.Xml.AppendComment("Invalid sender system title.");
                    }
                }
                len = GXCommon.GetObjectCount(data);
                tmp = new byte[len];
                data.Get(tmp);
                p.RecipientSystemTitle = tmp;
                // Get date time.
                len = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.DateTime = tmp;
                }
                // other-information
                len = data.GetUInt8();
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.OtherInformation = tmp;
                }
                // KeyInfo OPTIONAL
                len = data.GetUInt8();
                // AgreedKey CHOICE tag.
                data.GetUInt8();
                // key-parameters
                len             = data.GetUInt8();
                value           = data.GetUInt8();
                p.KeyParameters = value;
                if (value == 1)
                {
                    // KeyAgreement.ONE_PASS_DIFFIE_HELLMAN
                    // key-ciphered-data
                    len = GXCommon.GetObjectCount(data);
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.KeyCipheredData = tmp;
                }
                else if (value == 2)
                {
                    // KeyAgreement.STATIC_UNIFIED_MODEL
                    len = GXCommon.GetObjectCount(data);
                    if (len != 0)
                    {
                        throw new ArgumentException("Invalid key parameters");
                    }
                }
                else
                {
                    throw new ArgumentException("key-parameters");
                }
            }
            len = GXCommon.GetObjectCount(data);
            p.CipheredContent = data.Remaining();
            byte sc = (byte)data.GetUInt8();

            Enums.Security security = (Enums.Security)(sc & 0x30);
            if ((sc & 0x80) != 0)
            {
                System.Diagnostics.Debug.WriteLine("Compression is used.");
            }
            if ((sc & 0x40) != 0)
            {
                System.Diagnostics.Debug.WriteLine("Error: Key_Set is used.");
            }
            if ((sc & 0x20) != 0)
            {
                System.Diagnostics.Debug.WriteLine("Encryption is applied.");
            }

            SecuritySuite ss = (SecuritySuite)(sc & 0x3);

            p.Security = (byte)security;
            UInt32 invocationCounter = data.GetUInt32();

            p.InvocationCounter = invocationCounter;
            if (ss == SecuritySuite.Version2)
            {
                throw new NotImplementedException("Security Suite 2 is not implemented.");
            }
            System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString());
            System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Data,
                                                                              false, data.Position, data.Size - data.Position));
            byte[] tag = new byte[12];
            byte[] encryptedData;
            int    length;

            if (security == Enums.Security.Authentication)
            {
                length        = data.Size - data.Position - 12;
                encryptedData = new byte[length];
                data.Get(encryptedData);
                data.Get(tag);
                // Check tag.
                EncryptAesGcm(p, encryptedData);
                if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
                {
                    if (transactionId != 0)
                    {
                        p.InvocationCounter = transactionId;
                    }
                    if (p.Xml == null)
                    {
                        throw new GXDLMSException("Decrypt failed. Invalid tag.");
                    }
                    else
                    {
                        p.Xml.AppendComment("Decrypt failed. Invalid tag.");
                    }
                }
                return(encryptedData);
            }
            byte[] ciphertext = null;
            if (security == Enums.Security.Encryption)
            {
                length     = data.Size - data.Position;
                ciphertext = new byte[length];
                data.Get(ciphertext);
            }
            else if (security == Enums.Security.AuthenticationEncryption)
            {
                length     = data.Size - data.Position - 12;
                ciphertext = new byte[length];
                data.Get(ciphertext);
                data.Get(tag);
            }
            byte[] aad = GetAuthenticatedData(p, ciphertext),
            iv = GetNonse(invocationCounter, p.SystemTitle);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream((byte)security, true,
                                                                    p.BlockCipherKey, aad, iv, tag);

            gcm.Write(ciphertext);
            if (transactionId != 0)
            {
                p.InvocationCounter = transactionId;
            }
            return(gcm.FlushFinalBlock());
        }
        void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e)
        {
            if (e.Index == 1)
            {
                if (e.Value is string)
                {
                    LogicalName = e.Value.ToString();
                }
                else
                {
                    LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString();
                }
            }
            else if (e.Index == 2)
            {
                ObjectList.Clear();
                if (e.Value != null)
                {
                    foreach (Object[] item in (Object[])e.Value)
                    {
                        ObjectType type = (ObjectType)Convert.ToInt32(item[0]);
                        int version = Convert.ToInt32(item[1]);
                        String ln = GXDLMSObject.ToLogicalName((byte[])item[2]);
                        GXDLMSObject obj = null;
                        if (settings.Objects != null)
                        {
                            obj = settings.Objects.FindByLN(type, ln);
                        }
                        if (obj == null)
                        {
                            obj = Gurux.DLMS.GXDLMSClient.CreateObject(type);
                            obj.LogicalName = ln;
                            obj.Version = version;
                        }
                        //Unknown objects are not shown.
                        if (obj is IGXDLMSBase && item[3] != null)
                        {
                            UpdateAccessRights(obj, (Object[])item[3]);
                            ObjectList.Add(obj);
                        }
                    }
                }
            }
            else if (e.Index == 3)
            {
                if (e.Value != null)
                {
                    ClientSAP = Convert.ToByte(((Object[])e.Value)[0]);
                    ServerSAP = Convert.ToUInt16(((Object[])e.Value)[1]);
                }
            }
            else if (e.Index == 4)
            {
                //Value of the object identifier encoded in BER
                if (e.Value is byte[])
                {
                    GXByteBuffer arr = new GXByteBuffer(e.Value as byte[]);
                    if (arr.GetUInt8(0) == 0x60)
                    {

                        ApplicationContextName.JointIsoCtt = 0;
                        ++arr.Position;
                        ApplicationContextName.Country = 0;
                        ++arr.Position;
                        ApplicationContextName.CountryName = 0;
                        ++arr.Position;
                        ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                        ApplicationContextName.DlmsUA = arr.GetUInt8();
                        ApplicationContextName.ApplicationContext = arr.GetUInt8();
                        ApplicationContextName.ContextId = arr.GetUInt8();
                    }
                    else
                    {
                        //Get Tag and Len.
                        if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        ApplicationContextName.JointIsoCtt = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        ApplicationContextName.Country = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x12)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        ApplicationContextName.CountryName = arr.GetUInt16();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        ApplicationContextName.DlmsUA = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        ApplicationContextName.ApplicationContext = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        ApplicationContextName.ContextId = arr.GetUInt8();
                    }
                }
                else if (e.Value != null)
                {
                    Object[] arr = (Object[])e.Value;
                    ApplicationContextName.JointIsoCtt = Convert.ToByte(arr[0]);
                    ApplicationContextName.Country = Convert.ToByte(arr[1]);
                    ApplicationContextName.CountryName = Convert.ToUInt16(arr[2]);
                    ApplicationContextName.IdentifiedOrganization = Convert.ToByte(arr[3]);
                    ApplicationContextName.DlmsUA = Convert.ToByte(arr[4]);
                    ApplicationContextName.ApplicationContext = Convert.ToByte(arr[5]);
                    ApplicationContextName.ContextId = Convert.ToByte(arr[6]);
                }
            }
            else if (e.Index == 5)
            {
                if (e.Value != null)
                {
                    Object[] arr = (Object[])e.Value;
                    XDLMSContextInfo.Conformance = arr[0].ToString();
                    XDLMSContextInfo.MaxReceivePduSize = Convert.ToUInt16(arr[1]);
                    XDLMSContextInfo.MaxSendPpuSize = Convert.ToUInt16(arr[2]);
                    XDLMSContextInfo.DlmsVersionNumber = Convert.ToByte(arr[3]);
                    XDLMSContextInfo.QualityOfService = Convert.ToSByte(arr[4]);
                    XDLMSContextInfo.CypheringInfo = (byte[])arr[5];
                }
            }
            else if (e.Index == 6)
            {
                //Value of the object identifier encoded in BER
                if (e.Value is byte[])
                {
                    GXByteBuffer arr = new GXByteBuffer(e.Value as byte[]);
                    if (arr.GetUInt8(0) == 0x60)
                    {
                        AuthenticationMechanismMame.JointIsoCtt = 0;
                        ++arr.Position;
                        AuthenticationMechanismMame.Country = 0;
                        ++arr.Position;
                        AuthenticationMechanismMame.CountryName = 0;
                        ++arr.Position;
                        AuthenticationMechanismMame.IdentifiedOrganization = arr.GetUInt8();
                        AuthenticationMechanismMame.DlmsUA = arr.GetUInt8();
                        AuthenticationMechanismMame.AuthenticationMechanismName = arr.GetUInt8();
                        AuthenticationMechanismMame.MechanismId = (Authentication)arr.GetUInt8();
                    }
                    else
                    {
                        //Get Tag and Len.
                        if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        AuthenticationMechanismMame.JointIsoCtt = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        AuthenticationMechanismMame.Country = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x12)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        AuthenticationMechanismMame.CountryName = arr.GetUInt16();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        AuthenticationMechanismMame.IdentifiedOrganization = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        AuthenticationMechanismMame.DlmsUA = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        AuthenticationMechanismMame.AuthenticationMechanismName = arr.GetUInt8();
                        //Get tag
                        if (arr.GetUInt8() != 0x11)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        AuthenticationMechanismMame.MechanismId = (Authentication)arr.GetUInt8();
                    }
                }
                else if (e.Value != null)
                {
                    Object[] arr = (Object[])e.Value;
                    AuthenticationMechanismMame.JointIsoCtt = Convert.ToByte(arr[0]);
                    AuthenticationMechanismMame.Country = Convert.ToByte(arr[1]);
                    AuthenticationMechanismMame.CountryName = Convert.ToUInt16(arr[2]);
                    AuthenticationMechanismMame.IdentifiedOrganization = Convert.ToByte(arr[3]);
                    AuthenticationMechanismMame.DlmsUA = Convert.ToByte(arr[4]);
                    AuthenticationMechanismMame.AuthenticationMechanismName = Convert.ToByte(arr[5]);
                    AuthenticationMechanismMame.MechanismId = (Authentication)Convert.ToByte(arr[6]);
                }
            }
            else if (e.Index == 7)
            {
                Secret = (byte[])e.Value;
            }
            else if (e.Index == 8)
            {
                if (e.Value == null)
                {
                    AssociationStatus = AssociationStatus.NonAssociated;
                }
                else
                {
                    AssociationStatus = (AssociationStatus)Convert.ToInt32(e.Value);
                }
            }
            else if (e.Index == 9)
            {
                SecuritySetupReference = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString();
            }
            else
            {
                e.Error = ErrorCode.ReadWriteDenied;
            }
        }
Beispiel #24
0
 ///<summary>
 ///Get data from DLMS frame.
 ///</summary>
 ///<param name="settings">DLMS settings.</param>
 ///<param name="data">Received data.</param>
 ///<param name="info"> Data info.</param>
 ///<returns>Parsed object.</returns>
 ///
 public static object GetData(GXDLMSSettings settings, GXByteBuffer data, GXDataInfo info)
 {
     object value = null;
     int startIndex = data.Position;
     if (data.Position == data.Size)
     {
         info.Complete = false;
         return null;
     }
     info.Complete = true;
     bool knownType = info.Type != DataType.None;
     // Get data type if it is unknown.
     if (!knownType)
     {
         info.Type = (DataType)data.GetUInt8();
     }
     if (info.Type == DataType.None)
     {
         if (info.xml != null)
         {
             info.xml.AppendLine("<" + info.xml.GetDataType(info.Type) + " />");
         }
         return value;
     }
     if (data.Position == data.Size)
     {
         info.Complete = false;
         return null;
     }
     switch (info.Type)
     {
         case DataType.Array:
         case DataType.Structure:
             value = GetArray(data, info, startIndex);
             break;
         case DataType.Boolean:
             value = GetBoolean(data, info);
             break;
         case DataType.BitString:
             value = GetBitString(data, info);
             break;
         case DataType.Int32:
             value = GetInt32(data, info);
             break;
         case DataType.UInt32:
             value = GetUInt32(data, info);
             break;
         case DataType.String:
             value = GetString(data, info, knownType);
             break;
         case DataType.StringUTF8:
             value = GetUtfString(data, info, knownType);
             break;
         case DataType.OctetString:
             value = GetOctetString(data, info, knownType);
             break;
         case DataType.Bcd:
             value = GetBcd(data, info, knownType);
             break;
         case DataType.Int8:
             value = GetInt8(data, info);
             break;
         case DataType.Int16:
             value = GetInt16(data, info);
             break;
         case DataType.UInt8:
             value = GetUInt8(data, info);
             break;
         case DataType.UInt16:
             value = GetUInt16(data, info);
             break;
         case DataType.CompactArray:
             throw new Exception("Invalid data type.");
         case DataType.Int64:
             value = GetInt64(data, info);
             break;
         case DataType.UInt64:
             value = GetUInt64(data, info);
             break;
         case DataType.Enum:
             value = GetEnum(data, info);
             break;
         case DataType.Float32:
             value = Getfloat(data, info);
             break;
         case DataType.Float64:
             value = GetDouble(data, info);
             break;
         case DataType.DateTime:
             value = GetDateTime(settings, data, info);
             break;
         case DataType.Date:
             value = GetDate(data, info);
             break;
         case DataType.Time:
             value = GetTime(data, info);
             break;
         default:
             throw new Exception("Invalid data type.");
     }
     return value;
 }
Beispiel #25
0
 private static void UpdateAuthentication(GXDLMSSettings settings,
         GXByteBuffer buff)
 {
     byte len = buff.GetUInt8();
     if (buff.GetUInt8() != 0x60)
     {
         throw new Exception("Invalid tag.");
     }
     if (buff.GetUInt8() != 0x85)
     {
         throw new Exception("Invalid tag.");
     }
     if (buff.GetUInt8() != 0x74)
     {
         throw new Exception("Invalid tag.");
     }
     if (buff.GetUInt8() != 0x05)
     {
         throw new Exception("Invalid tag.");
     }
     if (buff.GetUInt8() != 0x08)
     {
         throw new Exception("Invalid tag.");
     }
     if (buff.GetUInt8() != 0x02)
     {
         throw new Exception("Invalid tag.");
     }
     int tmp = buff.GetUInt8();
     if (tmp < 0 || tmp > 7)
     {
         throw new Exception("Invalid tag.");
     }
     settings.Authentication = (Authentication)tmp;
 }
Beispiel #26
0
        ///<summary>
        ///Get time from DLMS data.
        ///</summary>
        ///<param name="buff">
        ///Received DLMS data.
        ///</param>
        ///<param name="info">
        ///Data info.
        ///</param>
        ///<returns>
        ///Parsed time.
        ///</returns>
        private static object GetTime(GXByteBuffer buff, GXDataInfo info)
        {
            object value;
            if (buff.Size - buff.Position < 4)
            {
                // If there is not enough data available.
                info.Complete = false;
                return null;
            }
            if (info.xml != null)
            {
                info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 4));
            }

            // Get time.
            int hour = buff.GetUInt8();
            int minute = buff.GetUInt8();
            int second = buff.GetUInt8();
            int ms = buff.GetUInt8();
            if (ms != 0xFF)
            {
                ms *= 10;
            }
            GXTime dt = new GXTime(hour, minute, second, ms);
            value = dt;
            return value;
        }
Beispiel #27
0
 ///<summary>
 ///Get date from DLMS data.
 ///</summary>
 ///<param name="buff">
 ///Received DLMS data.
 ///</param>
 ///<param name="info">
 ///Data info.
 ///</param>
 ///<returns>
 ///Parsed date.
 ///</returns>
 private static object GetDate(GXByteBuffer buff, GXDataInfo info)
 {
     object value;
     if (buff.Size - buff.Position < 5)
     {
         // If there is not enough data available.
         info.Complete = false;
         return null;
     }
     if (info.xml != null)
     {
         info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 5));
     }
     // Get year.
     int year = buff.GetUInt16();
     // Get month
     int month = buff.GetUInt8();
     // Get day
     int day = buff.GetUInt8();
     GXDate dt = new GXDate(year, month, day);
     // Skip week day
     if (buff.GetUInt8() == 0xFF)
     {
         dt.Skip |= DateTimeSkips.DayOfWeek;
     }
     value = dt;
     return value;
 }
Beispiel #28
0
        ///<summary>
        ///Get date and time from DLMS data.
        ///</summary>
        ///<param name="settings">DLMS settings.</param>
        ///<param name="buff">Received DLMS data.</param>
        ///<param name="info">Data info.</param>
        ///<returns>
        ///Parsed date and time.
        ///</returns>
        private static object GetDateTime(GXDLMSSettings settings, GXByteBuffer buff, GXDataInfo info)
        {
            // If there is not enough data available.
            if (buff.Size - buff.Position < 12)
            {
                //If time.
                if (buff.Size - buff.Position < 5)
                {
                    return GetTime(buff, info);
                }
                //If date.
                else if (buff.Size - buff.Position < 6)
                {
                    return GetDate(buff, info);
                }

                info.Complete = false;
                return null;
            }
            if (info.xml != null)
            {
                info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 12));
            }

            GXDateTime dt = new GXDateTime();
            //Get year.
            int year = buff.GetUInt16();
            if (year == 0xFFFF || year == 0)
            {
                year = DateTime.Now.Year;
                dt.Skip |= DateTimeSkips.Year;
            }
            //Get month
            int month = buff.GetUInt8();
            if (month == 0 || month == 0xFF || month == 0xFE || month == 0xFD)
            {
                month = 1;
                dt.Skip |= DateTimeSkips.Month;
            }
            int day = buff.GetUInt8();
            if (day < 1 || day == 0xFF)
            {
                day = 1;
                dt.Skip |= DateTimeSkips.Day;
            }
            else if (day == 0xFD || day == 0xFE)
            {
                day = DateTime.DaysInMonth(year, month) + (sbyte)day + 2;
            }
            //Skip week day
            if (buff.GetUInt8() == 0xFF)
            {
                dt.Skip |= DateTimeSkips.DayOfWeek;
            }
            //Get time.
            int hours = buff.GetUInt8();
            if (hours == 0xFF)
            {
                hours = 0;
                dt.Skip |= DateTimeSkips.Hour;
            }
            int minutes = buff.GetUInt8();
            if (minutes == 0xFF)
            {
                minutes = 0;
                dt.Skip |= DateTimeSkips.Minute;
            }
            int seconds = buff.GetUInt8();
            if (seconds == 0xFF)
            {
                seconds = 0;
                dt.Skip |= DateTimeSkips.Second;
            }
            int milliseconds = buff.GetUInt8();
            if (milliseconds != 0xFF)
            {
                milliseconds *= 10;
            }
            else
            {
                milliseconds = 0;
                dt.Skip |= DateTimeSkips.Ms;
            }
            int deviation = buff.GetInt16();
            dt.Status = (ClockStatus)buff.GetUInt8();
            if (settings != null && settings.UtcTimeZone)
            {
                deviation = -deviation;
            }
            dt.Deviation = deviation;
            //0x8000 == -32768
            //deviation = -1 if skipped.
            if (deviation != -1 && deviation != -32768 && year != 1 && (dt.Skip & DateTimeSkips.Year) == 0)
            {
                dt.Value = new DateTimeOffset(new DateTime(year, month, day, hours, minutes, seconds, milliseconds),
                                              new TimeSpan(0, -deviation, 0));
            }
            else //Use current time if deviation is not defined.
            {
                dt.Skip |= DateTimeSkips.Devitation;
                DateTime tmp = new DateTime(year, month, day, hours, minutes, seconds, milliseconds, DateTimeKind.Local);
                dt.Value = new DateTimeOffset(tmp, TimeZoneInfo.Local.GetUtcOffset(tmp));
            }
            return dt;
        }
Beispiel #29
0
 /// <summary>
 /// Parse application context name.
 /// </summary>
 /// <param name="settings">DLMS settings.</param>
 /// <param name="buff">Received data.</param>
 private static bool ParseApplicationContextName(GXDLMSSettings settings, GXByteBuffer buff, GXDLMSTranslatorStructure xml)
 {
     //Get length.
     int len = buff.GetUInt8();
     if (buff.Size - buff.Position < len)
     {
         throw new Exception("Encoding failed. Not enough data.");
     }
     if (buff.GetUInt8() != 0x6)
     {
         throw new Exception("Encoding failed. Not an Object ID.");
     }
     if (settings.IsServer && settings.Cipher != null)
     {
         settings.Cipher.Security = Gurux.DLMS.Enums.Security.None;
     }
     //Object ID length.
     len = buff.GetUInt8();
     if (xml != null)
     {
         if (buff.Compare(GXCommon.LogicalNameObjectID))
         {
             if (xml.OutputType == TranslatorOutputType.SimpleXml)
             {
                 xml.AppendLine(TranslatorGeneralTags.ApplicationContextName,
                                "Value", "LN");
             }
             else
             {
                 xml.AppendLine(
                     TranslatorGeneralTags.ApplicationContextName,
                     null, "1");
             }
             settings.UseLogicalNameReferencing = true;
         }
         else if (buff.Compare(GXCommon.LogicalNameObjectIdWithCiphering))
         {
             if (xml.OutputType == TranslatorOutputType.SimpleXml)
             {
                 xml.AppendLine(TranslatorGeneralTags.ApplicationContextName,
                                "Value", "LN_WITH_CIPHERING");
             }
             else
             {
                 xml.AppendLine(
                     TranslatorGeneralTags.ApplicationContextName,
                     null, "3");
             }
             settings.UseLogicalNameReferencing = true;
         }
         else if (buff.Compare(GXCommon.ShortNameObjectID))
         {
             if (xml.OutputType == TranslatorOutputType.SimpleXml)
             {
                 xml.AppendLine(TranslatorGeneralTags.ApplicationContextName,
                                "Value", "SN");
             }
             else
             {
                 xml.AppendLine(
                     TranslatorGeneralTags.ApplicationContextName,
                     null, "2");
             }
             settings.UseLogicalNameReferencing = false;
         }
         else if (buff.Compare(GXCommon.ShortNameObjectIdWithCiphering))
         {
             if (xml.OutputType == TranslatorOutputType.SimpleXml)
             {
                 xml.AppendLine(TranslatorGeneralTags.ApplicationContextName,
                                "Value", "SN_WITH_CIPHERING");
             }
             else
             {
                 xml.AppendLine(
                     TranslatorGeneralTags.ApplicationContextName,
                     null, "4");
             }
             settings.UseLogicalNameReferencing = false;
         }
         else
         {
             return false;
         }
         return true;
     }
     if (settings.UseLogicalNameReferencing)
     {
         if (buff.Compare(GXCommon.LogicalNameObjectID))
         {
             return true;
         }
         // If ciphering is used.
         return buff.Compare(GXCommon.LogicalNameObjectIdWithCiphering);
     }
     if (buff.Compare(GXCommon.ShortNameObjectID))
     {
         return true;
     }
     // If ciphering is used.
     return buff.Compare(GXCommon.ShortNameObjectIdWithCiphering);
 }
Beispiel #30
0
 ///<summary>
 ///Get enumeration value from DLMS data.
 ///</summary>
 ///<param name="buff">
 ///Received DLMS data.
 ///</param>
 ///<param name="info">
 ///Data info.
 ///</param>
 ///<returns>
 ///Parsed enumeration value.
 ///</returns>
 private static object GetEnum(GXByteBuffer buff, GXDataInfo info)
 {
     // If there is not enough data available.
     if (buff.Size - buff.Position < 1)
     {
         info.Complete = false;
         return null;
     }
     byte value = buff.GetUInt8();
     if (info.xml != null)
     {
         info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", info.xml.IntegerToHex(value, 2));
     }
     return value;
 }
Beispiel #31
0
        private static void GetValue(GXByteBuffer bb, IList <object> objects, GXAsn1Settings s)
        {
            int            len;
            short          type;
            IList <object> tmp;

            byte[] tmp2;
            type = bb.GetUInt8();
            len  = GXCommon.GetObjectCount(bb);
            if (len > bb.Available)
            {
                throw new OutOfMemoryException("GXAsn1Converter.GetValue");
            }
            int connectPos = 0;

            if (s != null)
            {
                connectPos = s.XmlLength;
            }
            int    start     = bb.Position;
            string tagString = null;

            if (s != null)
            {
                s.AppendSpaces();
                if (type == (byte)BerType.Integer)
                {
                    if (len == 1 || len == 2 || len == 4 || len == 8)
                    {
                        tagString = s.GetTag((short)-len);
                    }
                    else
                    {
                        tagString = s.GetTag((byte)BerType.Integer);
                    }
                }
                else
                {
                    tagString = s.GetTag(type);
                }
                s.Append("<" + tagString + ">");
            }

            switch (type)
            {
            case (byte)(BerType.Constructed | BerType.Context):
            case ((byte)(BerType.Constructed | BerType.Context) | 1):
            case ((byte)(BerType.Constructed | BerType.Context) | 2):
            case ((byte)(BerType.Constructed | BerType.Context) | 3):
            case ((byte)(BerType.Constructed | BerType.Context) | 4):
                if (s != null)
                {
                    s.Increase();
                }
                tmp = new GXAsn1Context()
                {
                    Index = type & 0xF
                };
                objects.Add(tmp);
                while (bb.Position < start + len)
                {
                    GetValue(bb, tmp, s);
                }
                if (s != null)
                {
                    s.Decrease();
                }
                break;

            case (byte)(BerType.Constructed | BerType.Sequence):
                if (s != null)
                {
                    s.Increase();
                }
                tmp = new GXAsn1Sequence();
                objects.Add(tmp);
                int cnt = 0;
                while (bb.Position < start + len)
                {
                    ++cnt;
                    GetValue(bb, tmp, s);
                }
                if (s != null)
                {
                    // Append comment.
                    s.AppendComment(connectPos, Convert.ToString(cnt) + " elements.");
                    s.Decrease();
                }
                break;

            case (byte)(BerType.Constructed | BerType.Set):
                if (s != null)
                {
                    s.Increase();
                }
                tmp = new List <object>();
                GetValue(bb, tmp, s);
                if (tmp[0] is GXAsn1Sequence)
                {
                    tmp = (GXAsn1Sequence)tmp[0];
                    objects.Add(new KeyValuePair <object, object>(tmp[0], tmp[1]));
                }
                else
                {
                    KeyValuePair <object, object> e = new KeyValuePair <object, object>(tmp, null);
                    objects.Add(e);
                }
                if (s != null)
                {
                    s.Decrease();
                }
                break;

            case (byte)BerType.ObjectIdentifier:
                GXAsn1ObjectIdentifier oi = new GXAsn1ObjectIdentifier(bb, len);
                objects.Add(oi);
                if (s != null)
                {
                    string str = oi.Description;
                    if (str != null)
                    {
                        s.AppendComment(connectPos, str);
                    }
                    s.Append(oi.ToString());
                }

                break;

            case (byte)BerType.PrintableString:
                objects.Add(bb.GetString(len));
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }

                break;

            case (byte)BerType.Utf8StringTag:
                objects.Add(new GXAsn1Utf8String(bb.GetString(bb.Position, len)));
                bb.Position = bb.Position + len;
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }

                break;

            case (byte)BerType.Ia5String:
                objects.Add(new GXAsn1Ia5String(bb.GetString(len)));
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }
                break;

            case (byte)BerType.Integer:
                if (len == 1)
                {
                    objects.Add(bb.GetInt8());
                }
                else if (len == 2)
                {
                    objects.Add(bb.GetInt16());
                }
                else if (len == 4)
                {
                    objects.Add(bb.GetInt32());
                }
                else
                {
                    tmp2 = new byte[len];
                    bb.Get(tmp2);
                    objects.Add(new GXAsn1Integer(tmp2));
                }
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }
                break;

            case (byte)BerType.Null:
                objects.Add(null);
                break;

            case (byte)BerType.BitString:
                GXAsn1BitString tmp3 = new GXAsn1BitString(bb.SubArray(bb.Position, len));
                objects.Add(tmp3);
                bb.Position = bb.Position + len;
                if (s != null)
                {
                    // Append comment.
                    s.AppendComment(connectPos, Convert.ToString(tmp3.Length) + " bit.");
                    s.Append(tmp3.asString());
                }
                break;

            case (byte)BerType.UtcTime:
                tmp2 = new byte[len];
                bb.Get(tmp2);
                objects.Add(GetUtcTime(ASCIIEncoding.ASCII.GetString(tmp2)));
                if (s != null)
                {
                    s.Append(((DateTimeOffset)objects[objects.Count - 1]).UtcDateTime.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture));
                }
                break;

            case (byte)BerType.GeneralizedTime:
                tmp2 = new byte[len];
                bb.Get(tmp2);
                objects.Add(GXCommon.GetGeneralizedTime(ASCIIEncoding.ASCII.GetString(tmp2)));
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }
                break;

            case (byte)BerType.Context:
            case (byte)BerType.Context | 1:
            case (byte)BerType.Context | 2:
            case (byte)BerType.Context | 3:
                tmp = new GXAsn1Context()
                {
                    Constructed = false, Index = type & 0xF
                };
                tmp2 = new byte[len];
                bb.Get(tmp2);
                tmp.Add(tmp2);
                objects.Add(tmp);
                if (s != null)
                {
                    s.Append(GXCommon.ToHex(tmp2, false));
                }
                break;

            case (byte)BerType.OctetString:
                int t = bb.GetUInt8(bb.Position);
                switch (t)
                {
                case (byte)(BerType.Constructed | BerType.Sequence):
                case (byte)BerType.BitString:
                    if (s != null)
                    {
                        s.Increase();
                    }
                    GetValue(bb, objects, s);
                    if (s != null)
                    {
                        s.Decrease();
                    }
                    break;

                default:
                    tmp2 = new byte[len];
                    bb.Get(tmp2);
                    objects.Add(tmp2);
                    if (s != null)
                    {
                        s.Append(GXCommon.ToHex(tmp2, false));
                    }
                    break;
                }
                break;

            case (byte)BerType.Boolean:
                bool b = bb.GetUInt8() != 0;
                objects.Add(b);
                if (s != null)
                {
                    s.Append(Convert.ToString(b));
                }
                break;

            default:
                throw new System.ArgumentException("Invalid type: " + type);
            }
            if (s != null)
            {
                s.Append("</" + tagString + ">\r\n");
            }
        }
Beispiel #32
0
 void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         LogicalName = GXCommon.ToLogicalName(e.Value);
     }
     else if (e.Index == 2)
     {
         ObjectList.Clear();
         if (e.Value != null)
         {
             foreach (Object[] item in (Object[])e.Value)
             {
                 GXDLMSObject obj = GetObject(settings, item);
                 //Unknown objects are not shown.
                 if (obj is IGXDLMSBase)
                 {
                     ObjectList.Add(obj);
                 }
             }
         }
     }
     else if (e.Index == 3)
     {
         if (e.Value != null)
         {
             ClientSAP = Convert.ToByte(((Object[])e.Value)[0]);
             ServerSAP = Convert.ToUInt16(((Object[])e.Value)[1]);
         }
     }
     else if (e.Index == 4)
     {
         //Value of the object identifier encoded in BER
         if (e.Value is byte[])
         {
             GXByteBuffer arr = new GXByteBuffer(e.Value as byte[]);
             if (arr.GetUInt8(0) == 0x60)
             {
                 ApplicationContextName.JointIsoCtt            = arr.GetUInt8();
                 ApplicationContextName.Country                = arr.GetUInt8();
                 ApplicationContextName.CountryName            = arr.GetUInt8();
                 ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                 ApplicationContextName.DlmsUA             = arr.GetUInt8();
                 ApplicationContextName.ApplicationContext = arr.GetUInt8();
                 ApplicationContextName.ContextId          = (ApplicationContextName)arr.GetUInt8();
             }
             else
             {
                 //Get Tag and Len.
                 if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.JointIsoCtt = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.Country = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x12)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.CountryName = arr.GetUInt16();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.DlmsUA = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.ApplicationContext = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.ContextId = (ApplicationContextName)arr.GetUInt8();
             }
         }
         else if (e.Value != null)
         {
             Object[] arr = (Object[])e.Value;
             ApplicationContextName.JointIsoCtt            = Convert.ToByte(arr[0]);
             ApplicationContextName.Country                = Convert.ToByte(arr[1]);
             ApplicationContextName.CountryName            = Convert.ToUInt16(arr[2]);
             ApplicationContextName.IdentifiedOrganization = Convert.ToByte(arr[3]);
             ApplicationContextName.DlmsUA             = Convert.ToByte(arr[4]);
             ApplicationContextName.ApplicationContext = Convert.ToByte(arr[5]);
             ApplicationContextName.ContextId          = (ApplicationContextName)Convert.ToByte(arr[6]);
         }
     }
     else if (e.Index == 5)
     {
         if (e.Value != null)
         {
             Object[] arr = (Object[])e.Value;
             if (arr[0] is string || arr[0] is byte[])
             {
                 GXByteBuffer bb = new GXByteBuffer();
                 GXCommon.SetBitString(bb, arr[0], true);
                 bb.SetUInt8(0, 0);
                 XDLMSContextInfo.Conformance = (Conformance)bb.GetUInt32();
             }
             else
             {
                 XDLMSContextInfo.Conformance = (Conformance)Convert.ToUInt16(arr[0]);
             }
             XDLMSContextInfo.MaxReceivePduSize = Convert.ToUInt16(arr[1]);
             XDLMSContextInfo.MaxSendPduSize    = Convert.ToUInt16(arr[2]);
             XDLMSContextInfo.DlmsVersionNumber = Convert.ToByte(arr[3]);
             XDLMSContextInfo.QualityOfService  = Convert.ToSByte(arr[4]);
             XDLMSContextInfo.CypheringInfo     = (byte[])arr[5];
         }
     }
     else if (e.Index == 6)
     {
         //Value of the object identifier encoded in BER
         if (e.Value is byte[])
         {
             GXByteBuffer arr = new GXByteBuffer(e.Value as byte[]);
             if (arr.GetUInt8(0) == 0x60)
             {
                 AuthenticationMechanismName.JointIsoCtt            = arr.GetUInt8();
                 AuthenticationMechanismName.Country                = arr.GetUInt8();
                 AuthenticationMechanismName.CountryName            = arr.GetUInt8();
                 AuthenticationMechanismName.IdentifiedOrganization = arr.GetUInt8();
                 AuthenticationMechanismName.DlmsUA = arr.GetUInt8();
                 AuthenticationMechanismName.AuthenticationMechanismName = arr.GetUInt8();
                 AuthenticationMechanismName.MechanismId = (Authentication)arr.GetUInt8();
             }
             else
             {
                 //Get Tag and Len.
                 if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.JointIsoCtt = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.Country = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x12)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.CountryName = arr.GetUInt16();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.IdentifiedOrganization = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.DlmsUA = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.AuthenticationMechanismName = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.MechanismId = (Authentication)arr.GetUInt8();
             }
         }
         else if (e.Value != null)
         {
             Object[] arr = (Object[])e.Value;
             AuthenticationMechanismName.JointIsoCtt            = Convert.ToByte(arr[0]);
             AuthenticationMechanismName.Country                = Convert.ToByte(arr[1]);
             AuthenticationMechanismName.CountryName            = Convert.ToUInt16(arr[2]);
             AuthenticationMechanismName.IdentifiedOrganization = Convert.ToByte(arr[3]);
             AuthenticationMechanismName.DlmsUA = Convert.ToByte(arr[4]);
             AuthenticationMechanismName.AuthenticationMechanismName = Convert.ToByte(arr[5]);
             AuthenticationMechanismName.MechanismId = (Authentication)Convert.ToByte(arr[6]);
         }
     }
     else if (e.Index == 7)
     {
         Secret = (byte[])e.Value;
     }
     else if (e.Index == 8)
     {
         if (e.Value == null)
         {
             AssociationStatus = AssociationStatus.NonAssociated;
         }
         else
         {
             AssociationStatus = (AssociationStatus)Convert.ToInt32(e.Value);
         }
     }
     else if (e.Index == 9)
     {
         SecuritySetupReference = GXCommon.ToLogicalName(e.Value);
     }
     else if (e.Index == 10)
     {
         UserList.Clear();
         if (e.Value != null)
         {
             foreach (Object[] item in (Object[])e.Value)
             {
                 UserList.Add(new KeyValuePair <byte, string>(Convert.ToByte(item[0]), Convert.ToString(item[1])));
             }
         }
     }
     else if (e.Index == 11)
     {
         if (e.Value != null)
         {
             Object[] tmp = (Object[])e.Value;
             if (tmp.Length == 1)
             {
                 CurrentUser = new KeyValuePair <byte, string>(Convert.ToByte(tmp[0]), null);
             }
             else
             {
                 CurrentUser = new KeyValuePair <byte, string>(Convert.ToByte(tmp[0]), Convert.ToString(tmp[1]));
             }
         }
         else
         {
             CurrentUser = new KeyValuePair <byte, string>(0, null);
         }
     }
     else
     {
         e.Error = ErrorCode.ReadWriteDenied;
     }
 }
Beispiel #33
0
        /// <summary>
        /// Parse User Information from PDU.
        /// </summary>
        private static void ParseUserInformation(GXDLMSSettings settings, GXICipher cipher, GXByteBuffer data)
        {
            byte len = data.GetUInt8();

            if (data.Size - data.Position < len)
            {
                throw new Exception("Not enough data.");
            }
            //Excoding the choice for user information
            int tag = data.GetUInt8();

            if (tag != 0x4)
            {
                throw new Exception("Invalid tag.");
            }
            len = data.GetUInt8();
            //Tag for xDLMS-Initate.response
            tag = data.GetUInt8();
            if (tag == GXCommon.InitialResponceGlo)
            {
                --data.Position;
                cipher.Security = cipher.Decrypt(settings.SourceSystemTitle, data);
                tag             = data.GetUInt8();
            }
            else if (tag == GXCommon.InitialRequestGlo)
            {
                --data.Position;
                cipher.Security = cipher.Decrypt(settings.SourceSystemTitle, data);
                tag             = data.GetUInt8();
            }
            bool response = tag == GXCommon.InitialResponce;

            if (response)
            {
                //Optional usage field of the negotiated quality of service component
                tag = data.GetUInt8();
                if (tag != 0)//Skip if used.
                {
                    len            = data.GetUInt8();
                    data.Position += len;
                }
            }
            else if (tag == GXCommon.InitialRequest)
            {
                //Optional usage field of the negotiated quality of service component
                tag = data.GetUInt8();
                //CtoS.
                if (tag != 0)
                {
                    len = data.GetUInt8();
                    settings.CtoSChallenge = new byte[len];
                    data.Get(settings.CtoSChallenge);
                }
                //Optional usage field of the negotiated quality of service component
                tag = data.GetUInt8();
                if (tag != 0)//Skip if used.
                {
                    len            = data.GetUInt8();
                    data.Position += len;
                }
                //Optional usage field of the proposed quality of service component
                tag = data.GetUInt8();
                if (tag != 0)//Skip if used.
                {
                    len            = data.GetUInt8();
                    data.Position += len;
                }
            }
            else
            {
                throw new Exception("Invalid tag.");
            }
            //Get DLMS version number.
            if (settings.IsServer)
            {
                settings.DlmsVersionNumber = data.GetUInt8();
            }
            else
            {
                if (data.GetUInt8() != 6)
                {
                    throw new Exception("Invalid DLMS version number.");
                }
            }

            //Tag for conformance block
            tag = data.GetUInt8();
            if (tag != 0x5F)
            {
                throw new Exception("Invalid tag.");
            }
            //Old Way...
            if (data.GetUInt8(data.Position) == 0x1F)
            {
                data.GetUInt8();
            }
            len = data.GetUInt8();
            //The number of unused bits in the bit string.
            tag = data.GetUInt8();
            if (settings.UseLogicalNameReferencing)
            {
                if (settings.IsServer)
                {
                    //Skip settings what client asks.
                    //All server settings are always returned.
                    byte[] tmp = new byte[3];
                    data.Get(tmp);
                }
                else
                {
                    data.Get(settings.LnSettings.ConformanceBlock);
                }
            }
            else
            {
                if (settings.IsServer)
                {
                    //Skip settings what client asks.
                    //All server settings are always returned.
                    byte[] tmp = new byte[3];
                    data.Get(tmp);
                }
                else
                {
                    data.Get(settings.SnSettings.ConformanceBlock);
                }
            }
            if (settings.IsServer)
            {
                data.GetUInt16();
            }
            else
            {
                settings.MaxReceivePDUSize = data.GetUInt16();
            }
            if (response)
            {
                //VAA Name
                tag = data.GetUInt16();
                if (tag == 0x0007)
                {
                    // If LN
                    if (!settings.UseLogicalNameReferencing)
                    {
                        throw new ArgumentException("Invalid VAA.");
                    }
                }
                else if (tag == 0xFA00)
                {
                    // If SN
                    if (settings.UseLogicalNameReferencing)
                    {
                        throw new ArgumentException("Invalid VAA.");
                    }
                }
                else
                {
                    // Unknown VAA.
                    throw new ArgumentException("Invalid VAA.");
                }
            }
        }
Beispiel #34
0
        /// <summary>
        /// Decrypt data.
        /// </summary>
        /// <param name="p">Decryption parameters</param>
        /// <returns>Decrypted data.</returns>
        public static byte[] DecryptAesGcm(AesGcmParameter p, GXByteBuffer data)
        {
            if (data == null || data.Size < 2)
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            Command cmd = (Command)data.GetUInt8();

            if (!((byte)cmd == 0x21 || (byte)cmd == 0x28 ||
                  cmd == Command.GloGetRequest ||
                  cmd == Command.GloGetResponse ||
                  cmd == Command.GloSetRequest ||
                  cmd == Command.GloSetResponse ||
                  cmd == Command.GloMethodRequest ||
                  cmd == Command.GloMethodResponse))
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int len = Gurux.DLMS.Internal.GXCommon.GetObjectCount(data);

            p.Security     = (Security)data.GetUInt8();
            p.FrameCounter = data.GetUInt32();
            System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString());
            System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Array(), true));

            byte[] tag = new byte[12];
            byte[] encryptedData;
            int    length;

            if (p.Security == Security.Authentication)
            {
                length        = data.Size - data.Position - 12;
                encryptedData = new byte[length];
                data.Get(encryptedData);
                data.Get(tag);
                // Check tag.
                EncryptAesGcm(p, encryptedData);
                if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
                {
                    throw new GXDLMSException("Decrypt failed. Invalid tag.");
                }
                return(encryptedData);
            }
            byte[] ciphertext = null;
            if (p.Security == Security.Encryption)
            {
                length     = data.Size - data.Position;
                ciphertext = new byte[length];
                data.Get(ciphertext);
            }
            else if (p.Security == Security.AuthenticationEncryption)
            {
                length     = data.Size - data.Position - 12;
                ciphertext = new byte[length];
                data.Get(ciphertext);
                data.Get(tag);
            }
            byte[] aad = GetAuthenticatedData(p.Security, p.AuthenticationKey, data.Array());
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(p.Security, false, p.BlockCipherKey, aad, GetNonse(p.FrameCounter, p.SystemTitle), tag);

            gcm.Write(ciphertext);
            return(gcm.FlushFinalBlock());
        }
Beispiel #35
0
        ///<summary>
        ///Parse APDU.
        ///</summary>
        static internal SourceDiagnostic ParsePDU(GXDLMSSettings settings, GXICipher cipher, GXByteBuffer buff)
        {
            // Get AARE tag and length
            int tag = buff.GetUInt8();

            if (settings.IsServer)
            {
                if (tag != ((byte)BerType.Application | (byte)BerType.Constructed | (byte)PduType.ProtocolVersion))
                {
                    throw new Exception("Invalid tag.");
                }
            }
            else
            {
                if (tag != ((byte)BerType.Application | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName))
                {
                    throw new Exception("Invalid tag.");
                }
            }
            int len  = buff.GetUInt8();
            int size = buff.Size - buff.Position;

            if (len > size)
            {
                throw new Exception("Not enough data.");
            }
            AssociationResult resultComponent       = AssociationResult.Accepted;
            SourceDiagnostic  resultDiagnosticValue = SourceDiagnostic.None;

            while (buff.Position < buff.Size)
            {
                tag = buff.GetUInt8();
                switch (tag)
                {
                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName:    //0xA1
                    if (!ParseApplicationContextName(settings, buff))
                    {
                        throw new GXDLMSException(AssociationResult.PermanentRejected, SourceDiagnostic.ApplicationContextNameNotSupported);
                    }
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApTitle:    ////Result 0xA2
                    //Get len.
                    if (buff.GetUInt8() != 3)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    //Choice for result (INTEGER, universal)
                    if (buff.GetUInt8() != (byte)BerType.Integer)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    //Get len.
                    if (buff.GetUInt8() != 1)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    resultComponent = (AssociationResult)buff.GetUInt8();
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledAeQualifier:    ////SourceDiagnostic 0xA3
                    len = buff.GetUInt8();
                    // ACSE service user tag.
                    tag = buff.GetUInt8();
                    len = buff.GetUInt8();
                    // Result source diagnostic component.
                    if (buff.GetUInt8() != (byte)BerType.Integer)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 1)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    resultDiagnosticValue = (SourceDiagnostic)buff.GetUInt8();
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApInvocationId:    ////Result 0xA4
                    //Get len.
                    if (buff.GetUInt8() != 0xA)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    //Choice for result (Universal, Octetstring type)
                    if (buff.GetUInt8() != (byte)BerType.OctetString)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    //responding-AP-title-field
                    //Get len.
                    len = buff.GetUInt8();
                    settings.SourceSystemTitle = new byte[len];
                    buff.Get(settings.SourceSystemTitle);
                    break;

                //Client Challenge.
                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CallingApTitle:    //0xA6
                    len = buff.GetUInt8();
                    tag = buff.GetUInt8();
                    len = buff.GetUInt8();
                    settings.SourceSystemTitle = new byte[len];
                    buff.Get(settings.SourceSystemTitle);
                    break;

                //Server Challenge.
                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.SenderAcseRequirements:    //0xAA
                    len = buff.GetUInt8();
                    tag = buff.GetUInt8();
                    len = buff.GetUInt8();
                    settings.StoCChallenge = new byte[len];
                    buff.Get(settings.StoCChallenge);
                    break;

                case (byte)BerType.Context | (byte)PduType.SenderAcseRequirements:   //0x8A
                case (byte)BerType.Context | (byte)PduType.CallingApInvocationId:    //0x88
                    //Get sender ACSE-requirements field component.
                    if (buff.GetUInt8() != 2)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != (byte)BerType.ObjectDescriptor)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x80)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    break;

                case (byte)BerType.Context | (byte)PduType.MechanismName:         //0x8B
                case (byte)BerType.Context | (byte)PduType.CallingAeInvocationId: //0x89
                    len = buff.GetUInt8();
                    if (buff.GetUInt8() != 0x60)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x85)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x74)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x05)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x08)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x02)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    int tmp = buff.GetUInt8();
                    if (tmp < 0 || tmp > 5)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    settings.Authentication = (Authentication)tmp;
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CallingAuthenticationValue:    //0xAC
                    len = buff.GetUInt8();
                    // Get authentication information.
                    if (buff.GetUInt8() != 0x80)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    len = buff.GetUInt8();
                    if (settings.Authentication < Authentication.HighMD5)
                    {
                        settings.Password = new byte[len];
                        buff.Get(settings.Password);
                    }
                    else
                    {
                        settings.CtoSChallenge = new byte[len];
                        buff.Get(settings.CtoSChallenge);
                    }
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.UserInformation:    //0xBE
                    if (resultComponent != AssociationResult.Accepted && resultDiagnosticValue != SourceDiagnostic.None)
                    {
                        throw new GXDLMSException(resultComponent, resultDiagnosticValue);
                    }
                    ParseUserInformation(settings, cipher, buff);
                    break;

                default:
                    //Unknown tags.
                    System.Diagnostics.Debug.WriteLine("Unknown tag: " + tag + ".");
                    len            = buff.GetUInt8();
                    buff.Position += (UInt16)len;
                    break;
                }
            }
            return(resultDiagnosticValue);
        }
Beispiel #36
0
        void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e)
        {
            switch (e.Index)
            {
            case 1:
                LogicalName = GXCommon.ToLogicalName(e.Value);
                break;

            case 2:
                AccountStatus = (AccountStatus)((object[])e.Value)[0];
                PaymentMode   = (PaymentMode)((object[])e.Value)[1];
                break;

            case 3:
                CurrentCreditInUse = (byte)e.Value;
                break;

            case 4:
                if ((string)e.Value == "")
                {
                    CurrentCreditStatus = (AccountCreditStatus)0;
                }
                else
                {
                    GXByteBuffer bb = new GXByteBuffer();
                    GXCommon.SetBitString(bb, e.Value);
                    CurrentCreditStatus = (AccountCreditStatus)bb.GetUInt8(1);
                }
                break;

            case 5:
                AvailableCredit = (int)e.Value;
                break;

            case 6:
                AmountToClear = (int)e.Value;
                break;

            case 7:
                ClearanceThreshold = (int)e.Value;
                break;

            case 8:
                AggregatedDebt = (int)e.Value;
                break;

            case 9:
                CreditReferences.Clear();
                if (e.Value != null)
                {
                    foreach (object it in (object[])e.Value)
                    {
                        CreditReferences.Add(GXCommon.ToLogicalName(it));
                    }
                }
                break;

            case 10:
                ChargeReferences.Clear();
                if (e.Value != null)
                {
                    foreach (object it in (object[])e.Value)
                    {
                        ChargeReferences.Add(GXCommon.ToLogicalName(it));
                    }
                }
                break;

            case 11:
                CreditChargeConfigurations.Clear();
                if (e.Value != null)
                {
                    foreach (object[] it in (object[])e.Value)
                    {
                        GXCreditChargeConfiguration item = new GXCreditChargeConfiguration();
                        item.CreditReference = GXCommon.ToLogicalName(it[0]);
                        item.ChargeReference = GXCommon.ToLogicalName(it[1]);
                        if ((string)it[2] == "")
                        {
                            item.CollectionConfiguration = 0;
                        }
                        else
                        {
                            GXByteBuffer tmp2 = new GXByteBuffer();
                            GXCommon.SetBitString(tmp2, it[2]);
                            item.CollectionConfiguration = (CreditCollectionConfiguration)tmp2.GetUInt8(1);
                        }
                        CreditChargeConfigurations.Add(item);
                    }
                }
                break;

            case 12:
                TokenGatewayConfigurations.Clear();
                if (e.Value != null)
                {
                    foreach (object[] it in (object[])e.Value)
                    {
                        GXTokenGatewayConfiguration item = new GXTokenGatewayConfiguration();
                        item.CreditReference = GXCommon.ToLogicalName(it[0]);
                        item.TokenProportion = (byte)it[1];
                        TokenGatewayConfigurations.Add(item);
                    }
                }
                break;

            case 13:
                if (e.Value == null)
                {
                    AccountActivationTime = new GXDateTime(DateTime.MinValue);
                }
                else
                {
                    if (e.Value is byte[])
                    {
                        e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime);
                    }
                    else if (e.Value is string)
                    {
                        e.Value = new GXDateTime((string)e.Value);
                    }
                    if (e.Value is GXDateTime)
                    {
                        AccountActivationTime = (GXDateTime)e.Value;
                    }
                }
                break;

            case 14:
                if (e.Value == null)
                {
                    AccountClosureTime = new GXDateTime(DateTime.MinValue);
                }
                else
                {
                    if (e.Value is byte[])
                    {
                        e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime);
                    }
                    else if (e.Value is string)
                    {
                        e.Value = new GXDateTime((string)e.Value);
                    }
                    if (e.Value is GXDateTime)
                    {
                        AccountClosureTime = (GXDateTime)e.Value;
                    }
                }
                break;

            case 15:
                object[] tmp = (object[])e.Value;
                Currency.Name  = (string)tmp[0];
                Currency.Scale = (sbyte)tmp[1];
                Currency.Unit  = (Currency)tmp[2];
                break;

            case 16:
                LowCreditThreshold = (int)e.Value;
                break;

            case 17:
                NextCreditAvailableThreshold = (int)e.Value;
                break;

            case 18:
                MaxProvision = (UInt16)e.Value;
                break;

            case 19:
                MaxProvisionPeriod = (int)e.Value;
                break;

            default:
                e.Error = ErrorCode.ReadWriteDenied;
                break;
            }
        }
 /// <summary>
 /// Client has send data for for the gateway.
 /// </summary>
 /// <remarks>
 /// GW finds the correct client and sends data for it.
 /// </remarks>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 public static void OnGatewayReceived(object sender, Gurux.Common.ReceiveEventArgs e)
 {
     try
     {
         lock (buffers)
         {
             GXByteBuffer bb;
             if (!buffers.ContainsKey(e.SenderInfo))
             {
                 bb = new GXByteBuffer();
                 buffers[e.SenderInfo] = bb;
             }
             else
             {
                 bb = buffers[e.SenderInfo];
             }
             bb.Set((byte[])e.Data);
             GXServerReply sr = new GXServerReply(bb.Data);
             GatewayServer.Reset();
             try
             {
                 GatewayServer.HandleRequest(sr);
                 if (sr.Reply != null)
                 {
                     if (Trace > TraceLevel.Info)
                     {
                         Console.WriteLine("TX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true));
                     }
                     ((IGXMedia)sender).Send(sr.Reply, e.SenderInfo);
                     return;
                 }
             }
             catch (Exception)
             {
                 //Return error.
                 sr.Reply = GatewayServer.ReportError(sr.Command, ErrorCode.HardwareFault);
             }
             if (sr.Gateway != null && sr.Data != null)
             {
                 GXByteBuffer  pdu     = new GXByteBuffer(sr.Data);
                 InterfaceType type    = (InterfaceType)sr.Gateway.NetworkId;
                 GXByteBuffer  address = new GXByteBuffer();
                 address.Set(sr.Gateway.PhysicalDeviceAddress);
                 int addr = address.GetUInt8();
                 //Find correct meter using GW information.
                 if (meters.ContainsKey(addr))
                 {
                     //Find client for the server or create a new one.
                     GXDLMSClient cl;
                     if (!clients.ContainsKey(addr))
                     {
                         //Set client address if data is send without framing.
                         if (GatewayServer.Settings.ClientAddress == 0)
                         {
                             GatewayServer.Settings.ClientAddress = 0x10;
                         }
                         cl = new GXDLMSClient(true, GatewayServer.Settings.ClientAddress, addr, GatewayServer.Authentication, null, type);
                         clients.Add(addr, cl);
                     }
                     else
                     {
                         cl = clients[addr];
                     }
                     GXReplyData data   = new GXReplyData();
                     GXReplyData notify = new GXReplyData();
                     GXDLMSMeter m      = meters[addr];
                     //Send SNRM if needed.
                     if (sr.Command == Command.Aarq && (type == InterfaceType.HDLC || type == InterfaceType.HdlcWithModeE))
                     {
                         GXServerReply sr2 = new GXServerReply(cl.SNRMRequest());
                         m.HandleRequest(sr2);
                         if (cl.GetData(sr2.Reply, data, notify))
                         {
                             data.Clear();
                             notify.Clear();
                         }
                         else
                         {
                             //If the meter doesn't reply.
                             bb.Clear();
                             return;
                         }
                     }
                     byte[][] frames = cl.CustomFrameRequest(Command.None, pdu);
                     foreach (byte[] it in frames)
                     {
                         sr.Data = it;
                         m.HandleRequest(sr);
                         if (Trace > TraceLevel.Info)
                         {
                             Console.WriteLine("RX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true));
                         }
                         data.RawPdu = true;
                         if (cl.GetData(sr.Reply, data, notify))
                         {
                             while (data.IsMoreData)
                             {
                                 sr.Data = cl.ReceiverReady(data);
                                 m.HandleRequest(sr);
                                 if (Trace > TraceLevel.Info)
                                 {
                                     Console.WriteLine("RX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true));
                                 }
                                 cl.GetData(sr.Reply, data, notify);
                             }
                             byte[] reply = sr.Reply;
                             try
                             {
                                 GXByteBuffer tmp = new GXByteBuffer();
                                 tmp.Set(data.Data);
                                 GatewayServer.Gateway = sr.Gateway;
                                 reply = GatewayServer.CustomFrameRequest(Command.None, tmp);
                             }
                             finally
                             {
                                 GatewayServer.Gateway = null;
                             }
                             if (Trace > TraceLevel.Info)
                             {
                                 Console.WriteLine("TX:\t" + Gurux.Common.GXCommon.ToHex(reply, true));
                             }
                             ((IGXMedia)sender).Send(reply, e.SenderInfo);
                         }
                     }
                 }
                 bb.Clear();
             }
         }
     }
     catch (Exception ex)
     {
         if (!(ex is SocketException))
         {
             Console.WriteLine(ex.Message);
         }
     }
 }
Beispiel #38
0
        /// <summary>
        /// Decrypt data.
        /// </summary>
        /// <param name="p">Decryption parameters</param>
        /// <returns>Decrypted data.</returns>
        public static byte[] DecryptAesGcm(AesGcmParameter p, GXByteBuffer data)
        {
            if (data == null || data.Size < 2)
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            byte[]  tmp;
            int     len;
            Command cmd = (Command)data.GetUInt8();

            switch (cmd)
            {
            case Command.GeneralGloCiphering:
            case Command.GeneralDedCiphering:
                len = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    p.SystemTitle = new byte[len];
                    data.Get(p.SystemTitle);
                    if (p.Xml != null && p.Xml.Comments)
                    {
                        p.Xml.AppendComment(GXCommon.SystemTitleToString(Standard.DLMS, p.SystemTitle, true));
                    }
                }
                if (p.SystemTitle == null || p.SystemTitle.Length != 8)
                {
                    if (p.Xml == null)
                    {
                        throw new ArgumentNullException("Invalid sender system title.");
                    }
                    else
                    {
                        p.Xml.AppendComment("Invalid sender system title.");
                    }
                }
                break;

            case Command.GeneralCiphering:
            case Command.GloInitiateRequest:
            case Command.GloInitiateResponse:
            case Command.GloReadRequest:
            case Command.GloReadResponse:
            case Command.GloWriteRequest:
            case Command.GloWriteResponse:
            case Command.GloGetRequest:
            case Command.GloGetResponse:
            case Command.GloSetRequest:
            case Command.GloSetResponse:
            case Command.GloMethodRequest:
            case Command.GloMethodResponse:
            case Command.GloEventNotification:
            case Command.DedInitiateRequest:
            case Command.DedInitiateResponse:
            case Command.DedGetRequest:
            case Command.DedGetResponse:
            case Command.DedSetRequest:
            case Command.DedSetResponse:
            case Command.DedMethodRequest:
            case Command.DedMethodResponse:
            case Command.DedEventNotification:
            case Command.DedReadRequest:
            case Command.DedReadResponse:
            case Command.DedWriteRequest:
            case Command.DedWriteResponse:
            case Command.GloConfirmedServiceError:
            case Command.DedConfirmedServiceError:
                break;

            default:
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int          value         = 0;
            GXPrivateKey key           = null;
            GXPublicKey  pub           = null;
            GXByteBuffer transactionId = null;

            if (cmd == Command.GeneralCiphering)
            {
                transactionId = new GXByteBuffer();
                len           = GXCommon.GetObjectCount(data);
                GXCommon.SetObjectCount(len, transactionId);
                transactionId.Set(data, len);
                p.TransactionId = transactionId.GetUInt64(1);
                len             = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.SystemTitle = tmp;
                }
                if (p.SystemTitle == null || p.SystemTitle.Length != 8)
                {
                    if (p.Xml == null)
                    {
                        throw new ArgumentNullException("Invalid sender system title.");
                    }
                    else
                    {
                        p.Xml.AppendComment("Invalid sender system title.");
                    }
                }
                len = GXCommon.GetObjectCount(data);
                tmp = new byte[len];
                data.Get(tmp);
                p.RecipientSystemTitle = tmp;
                // Get date time.
                len = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.DateTime = tmp;
                }
                // other-information
                len = data.GetUInt8();
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.OtherInformation = tmp;
                }
                // KeyInfo OPTIONAL
                len = data.GetUInt8();
                // AgreedKey CHOICE tag.
                data.GetUInt8();
                // key-parameters
                len             = data.GetUInt8();
                value           = data.GetUInt8();
                p.KeyParameters = value;
                if (value == (int)KeyAgreementScheme.OnePassDiffieHellman)
                {
                    // key-ciphered-data
                    len = GXCommon.GetObjectCount(data);
                    GXByteBuffer bb = new GXByteBuffer();
                    bb.Set(data, len);
                    if (p.Xml != null)
                    {
                        p.KeyCipheredData = bb.Array();
                        //Find key agreement key using subject.
                        string subject = GXAsn1Converter.SystemTitleToSubject(p.SystemTitle);
                        foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys)
                        {
                            if (it.Key != null && it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject))
                            {
                                key = it.Key.PrivateKey;
                                //Get recipient Ephemeral public key.
                                subject = GXAsn1Converter.SystemTitleToSubject(p.RecipientSystemTitle);
                                foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it2 in p.Settings.Keys)
                                {
                                    if (it2.Value != null && it2.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it2.Value.Subject.Contains(subject))
                                    {
                                        pub = it2.Value.PublicKey;
                                        break;
                                    }
                                }
                                break;
                            }
                        }
                        if (key == null)
                        {
                            //Find key agreement key using subject.
                            subject = GXAsn1Converter.SystemTitleToSubject(p.RecipientSystemTitle);
                            foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys)
                            {
                                if (it.Key != null && it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject))
                                {
                                    key = it.Key.PrivateKey;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        key = p.Settings.Cipher.KeyAgreementKeyPair.Key;
                    }
                    if (key != null && pub == null)
                    {
                        //Get Ephemeral public key.
                        int keySize = len / 2;
                        pub = GXPublicKey.FromRawBytes(bb.SubArray(0, keySize));
                    }
                }
                else if (value == (int)KeyAgreementScheme.StaticUnifiedModel)
                {
                    len = GXCommon.GetObjectCount(data);
                    if (len != 0)
                    {
                        throw new ArgumentException("Invalid key parameters");
                    }
                    if (p.Xml != null)
                    {
                        //Find key agreement key using subject.
                        string subject = GXAsn1Converter.SystemTitleToSubject(p.RecipientSystemTitle);
                        foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys)
                        {
                            if (it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject))
                            {
                                key = it.Key.PrivateKey;
                                break;
                            }
                        }
                        if (key != null)
                        {
                            //Find key agreement key using subject.
                            subject = GXAsn1Converter.SystemTitleToSubject(p.Settings.SourceSystemTitle);
                            foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys)
                            {
                                if (it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject))
                                {
                                    pub = it.Value.PublicKey;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        key = p.Settings.Cipher.KeyAgreementKeyPair.Key;
                        pub = p.Settings.Cipher.KeyAgreementKeyPair.Value;
                    }
                }
                else
                {
                    throw new ArgumentException("key-parameters");
                }
            }
            len = GXCommon.GetObjectCount(data);
            if (len > data.Available)
            {
                throw new Exception("Not enought data.");
            }
            p.CipheredContent = data.Remaining();
            byte sc = data.GetUInt8();

            p.SecuritySuite = (SecuritySuite)(sc & 0x3);
            p.Security      = (Security)(sc & 0x30);
            if ((sc & 0x80) != 0)
            {
                System.Diagnostics.Debug.WriteLine("Compression is used.");
            }
            if ((sc & 0x40) != 0)
            {
                System.Diagnostics.Debug.WriteLine("Error: Key_Set is used.");
            }
            if ((sc & 0x20) != 0)
            {
                System.Diagnostics.Debug.WriteLine("Encryption is applied.");
            }
            if (key != null)
            {
                if (value == (int)KeyAgreementScheme.OnePassDiffieHellman)
                {
                    GXEcdsa c = new GXEcdsa(key);
                    //Get Ephemeral signing key and verify it.
                    byte[] z = c.GenerateSecret(pub);
                    System.Diagnostics.Debug.WriteLine("Originator ephemeral public key: " + pub.ToHex());
                    System.Diagnostics.Debug.WriteLine("Recipient private agreement key: " + key.ToHex());
                    System.Diagnostics.Debug.WriteLine("Shared secret:" + GXCommon.ToHex(z, true));

                    GXByteBuffer kdf = new GXByteBuffer();
                    kdf.Set(GXSecure.GenerateKDF(p.SecuritySuite, z,
                                                 p.SecuritySuite == SecuritySuite.Ecdsa256 ? AlgorithmId.AesGcm128 : AlgorithmId.AesGcm256,
                                                 p.SystemTitle,
                                                 p.RecipientSystemTitle,
                                                 null, null));
                    System.Diagnostics.Debug.WriteLine("KDF:" + kdf.ToString());
                    p.BlockCipherKey = kdf.SubArray(0, 16);
                }
                else if (value == (int)KeyAgreementScheme.StaticUnifiedModel)
                {
                    GXEcdsa c = new GXEcdsa(key);
                    byte[]  z = c.GenerateSecret(pub);
                    System.Diagnostics.Debug.WriteLine("Shared secret:" + GXCommon.ToHex(z, true));
                    GXByteBuffer kdf = new GXByteBuffer();
                    kdf.Set(GXSecure.GenerateKDF(p.SecuritySuite, z,
                                                 p.SecuritySuite == SecuritySuite.Ecdsa256 ? AlgorithmId.AesGcm128 : AlgorithmId.AesGcm256,
                                                 p.SystemTitle,
                                                 transactionId.Array(),
                                                 p.RecipientSystemTitle,
                                                 null));
                    System.Diagnostics.Debug.WriteLine("KDF:" + kdf.ToString());
                    p.BlockCipherKey = kdf.SubArray(0, 16);
                }
                else
                {
                    throw new ArgumentOutOfRangeException("Invalid Key-id value.");
                }
            }
            UInt32 invocationCounter = data.GetUInt32();

            p.InvocationCounter = invocationCounter;
            System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString());
            System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Data,
                                                                              false, data.Position, data.Size - data.Position));
            byte[] tag = new byte[12];
            byte[] encryptedData;
            int    length;

            if (p.Security == Security.Authentication)
            {
                length        = data.Size - data.Position - 12;
                encryptedData = new byte[length];
                data.Get(encryptedData);
                data.Get(tag);
                // Check tag.
                EncryptAesGcm(p, encryptedData);
                if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
                {
                    if (p.Xml == null)
                    {
                        throw new GXDLMSException("Decrypt failed. Invalid tag.");
                    }
                    else
                    {
                        p.Xml.AppendComment("Decrypt failed. Invalid tag.");
                    }
                }
                return(encryptedData);
            }
            byte[] ciphertext = null;
            if (p.Security == Security.Encryption)
            {
                length     = data.Size - data.Position;
                ciphertext = new byte[length];
                data.Get(ciphertext);
            }
            else if (p.Security == Security.AuthenticationEncryption)
            {
                length     = data.Size - data.Position - 12;
                ciphertext = new byte[length];
                data.Get(ciphertext);
                data.Get(tag);
            }
            byte[] aad = GetAuthenticatedData(p, ciphertext),
            iv = GetNonse(invocationCounter, p.SystemTitle);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(p.Security, true,
                                                                    p.BlockCipherKey, aad, iv, tag);

            gcm.Write(ciphertext);
            byte[] decrypted = gcm.FlushFinalBlock();
            System.Diagnostics.Debug.WriteLine("Decrypted: " + GXCommon.ToHex(decrypted, true));
            if (p.Security != Security.Encryption)
            {
                if (!GXCommon.Compare(gcm.GetTag(), tag))
                {
                    if (p.Xml == null)
                    {
                        throw new Exception("Decrypt failed. Invalid authentication tag.");
                    }
                    p.Xml.AppendComment("Decrypt failed. Invalid authentication tag.");
                }
            }
            return(decrypted);
        }
Beispiel #39
0
 byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e)
 {
     //Check reply_to_HLS_authentication
     if (e.Index == 1)
     {
         UInt32 ic = 0;
         byte[] secret;
         if (settings.Authentication == Authentication.HighGMAC)
         {
             secret = settings.SourceSystemTitle;
             GXByteBuffer bb = new GXByteBuffer(e.Parameters as byte[]);
             bb.GetUInt8();
             ic = bb.GetUInt32();
         }
         else
         {
             secret = Secret;
         }
         byte[] serverChallenge = GXSecure.Secure(settings, settings.Cipher, ic, settings.StoCChallenge, secret);
         byte[] clientChallenge = (byte[])e.Parameters;
         if (serverChallenge != null && clientChallenge != null && GXCommon.Compare(serverChallenge, clientChallenge))
         {
             if (settings.Authentication == Authentication.HighGMAC)
             {
                 secret = settings.Cipher.SystemTitle;
                 ic     = settings.Cipher.InvocationCounter;
             }
             else
             {
                 secret = Secret;
             }
             AssociationStatus = AssociationStatus.Associated;
             return(GXSecure.Secure(settings, settings.Cipher, ic, settings.CtoSChallenge, secret));
         }
         else //If the password does not match.
         {
             AssociationStatus = AssociationStatus.NonAssociated;
             return(null);
         }
     }
     else if (e.Index == 2)
     {
         byte[] tmp = e.Parameters as byte[];
         if (tmp == null || tmp.Length == 0)
         {
             e.Error = ErrorCode.ReadWriteDenied;
         }
         else
         {
             Secret = tmp;
         }
     }
     else if (e.Index == 3)
     {
         //Add COSEM object.
         GXDLMSObject obj = GetObject(settings, e.Parameters as object[]);
         //Unknown objects are not add.
         if (obj is IGXDLMSBase)
         {
             if (ObjectList.FindByLN(obj.ObjectType, obj.LogicalName) == null)
             {
                 ObjectList.Add(obj);
             }
             if (settings.Objects.FindByLN(obj.ObjectType, obj.LogicalName) == null)
             {
                 settings.Objects.Add(obj);
             }
         }
     }
     else if (e.Index == 4)
     {
         //Remove COSEM object.
         GXDLMSObject obj = GetObject(settings, e.Parameters as object[]);
         //Unknown objects are not removed.
         if (obj is IGXDLMSBase)
         {
             GXDLMSObject t = ObjectList.FindByLN(obj.ObjectType, obj.LogicalName);
             if (t != null)
             {
                 ObjectList.Remove(t);
             }
             //Item is not removed from all objects. It might be that use wants remove object only from association view.
         }
     }
     else if (e.Index == 5)
     {
         object[] tmp = e.Parameters as object[];
         if (tmp == null || tmp.Length != 2)
         {
             e.Error = ErrorCode.ReadWriteDenied;
         }
         else
         {
             UserList.Add(new KeyValuePair <byte, string>(Convert.ToByte(tmp[0]), Convert.ToString(tmp[1])));
         }
     }
     else if (e.Index == 6)
     {
         object[] tmp = e.Parameters as object[];
         if (tmp == null || tmp.Length != 2)
         {
             e.Error = ErrorCode.ReadWriteDenied;
         }
         else
         {
             UserList.Remove(new KeyValuePair <byte, string>(Convert.ToByte(tmp[0]), Convert.ToString(tmp[1])));
         }
     }
     else
     {
         e.Error = ErrorCode.ReadWriteDenied;
     }
     return(null);
 }
Beispiel #40
0
        private static void updatePassword(GXDLMSSettings settings, GXByteBuffer buff, GXDLMSTranslatorStructure xml)
        {
            int len = buff.GetUInt8();
            // Get authentication information.
            if (buff.GetUInt8() != 0x80)
            {
                throw new Exception("Invalid tag.");
            }
            len = buff.GetUInt8();
            if (settings.Authentication == Authentication.Low)
            {
                settings.Password = new byte[len];
                buff.Get(settings.Password);
            }
            else
            {
                settings.CtoSChallenge = new byte[len];
                buff.Get(settings.CtoSChallenge);
            }

            if (xml != null)
            {
                if (xml.OutputType == TranslatorOutputType.SimpleXml)
                {
                    if (settings.Authentication == Authentication.Low)
                    {
                        xml.AppendLine(TranslatorGeneralTags.CallingAuthentication,
                                       "Value",
                                       GXCommon.ToHex(settings.Password, false));
                    }
                    else
                    {
                        xml.AppendLine(TranslatorGeneralTags.CallingAuthentication,
                                       "Value",
                                       GXCommon.ToHex(settings.CtoSChallenge, false));
                    }
                }
                else
                {
                    xml.AppendStartTag(
                        TranslatorGeneralTags.CallingAuthentication);
                    xml.AppendStartTag(TranslatorGeneralTags.CharString);
                    if (settings.Authentication == Authentication.Low)
                    {
                        xml.Append(GXCommon.ToHex(settings.Password, false));
                    }
                    else
                    {
                        xml.Append(
                            GXCommon.ToHex(settings.CtoSChallenge, false));
                    }
                    xml.AppendEndTag(TranslatorGeneralTags.CharString);
                    xml.AppendEndTag(TranslatorGeneralTags.CallingAuthentication);
                }
            }
        }
Beispiel #41
0
        void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e)
        {
            switch (e.Index)
            {
            case 1:
                LogicalName = GXCommon.ToLogicalName(e.Value);
                break;

            case 2:
                CurrentCreditAmount = (int)e.Value;
                break;

            case 3:
                Type = (CreditType)(byte)e.Value;
                break;

            case 4:
                Priority = (byte)e.Value;
                break;

            case 5:
                WarningThreshold = (int)e.Value;
                break;

            case 6:
                Limit = (int)e.Value;
                break;

            case 7:
                if ((string)e.Value == "")
                {
                    CreditConfiguration = (CreditConfiguration)0;
                }
                else
                {
                    GXByteBuffer bb = new GXByteBuffer();
                    GXCommon.SetBitString(bb, e.Value, true);
                    CreditConfiguration = (CreditConfiguration)bb.GetUInt8(1);
                }
                break;

            case 8:
                Status = (CreditStatus)(byte)e.Value;
                break;

            case 9:
                PresetCreditAmount = (int)e.Value;
                break;

            case 10:
                CreditAvailableThreshold = (int)e.Value;
                break;

            case 11:
                if (e.Value == null)
                {
                    Period = new GXDateTime(DateTime.MinValue);
                }
                else
                {
                    if (e.Value is byte[])
                    {
                        e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime);
                    }
                    else if (e.Value is string)
                    {
                        e.Value = new GXDateTime((string)e.Value);
                    }
                    if (e.Value is GXDateTime)
                    {
                        Period = (GXDateTime)e.Value;
                    }
                }
                break;

            default:
                e.Error = ErrorCode.ReadWriteDenied;
                break;
            }
        }
Beispiel #42
0
 byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e)
 {
     //Check reply_to_HLS_authentication
     if (e.Index == 1)
     {
         UInt32 ic = 0;
         byte[] secret;
         if (settings.Authentication == Authentication.HighGMAC)
         {
             secret = settings.SourceSystemTitle;
             GXByteBuffer bb = new GXByteBuffer(e.Parameters as byte[]);
             bb.GetUInt8();
             ic = bb.GetUInt32();
         }
         else
         {
             secret = Secret;
         }
         byte[] serverChallenge = GXSecure.Secure(settings, settings.Cipher, ic, settings.StoCChallenge, secret);
         byte[] clientChallenge = (byte[])e.Parameters;
         if (serverChallenge != null && clientChallenge != null && GXCommon.Compare(serverChallenge, clientChallenge))
         {
             if (settings.Authentication == Authentication.HighGMAC)
             {
                 secret = settings.Cipher.SystemTitle;
                 ic     = settings.Cipher.InvocationCounter;
             }
             else
             {
                 secret = Secret;
             }
             settings.Connected = true;
             return(GXSecure.Secure(settings, settings.Cipher, ic, settings.CtoSChallenge, secret));
         }
         else //If the password does not match.
         {
             settings.Connected = false;
             return(null);
         }
     }
     else if (e.Index == 2)
     {
         byte[] tmp = e.Parameters as byte[];
         if (tmp == null || tmp.Length == 0)
         {
             e.Error = ErrorCode.ReadWriteDenied;
         }
         else
         {
             Secret = tmp;
         }
     }
     else if (e.Index == 5)
     {
         object[] tmp = e.Parameters as object[];
         if (tmp == null || tmp.Length != 2)
         {
             e.Error = ErrorCode.ReadWriteDenied;
         }
         else
         {
             UserList.Add(new KeyValuePair <byte, string>(Convert.ToByte(tmp[0]), Convert.ToString(tmp[1])));
         }
     }
     else if (e.Index == 6)
     {
         object[] tmp = e.Parameters as object[];
         if (tmp == null || tmp.Length != 2)
         {
             e.Error = ErrorCode.ReadWriteDenied;
         }
         else
         {
             UserList.Remove(new KeyValuePair <byte, string>(Convert.ToByte(tmp[0]), Convert.ToString(tmp[1])));
         }
     }
     else
     {
         e.Error = ErrorCode.ReadWriteDenied;
     }
     return(null);
 }