Beispiel #1
0
        /// <summary>
        /// Convert value to byte array.
        /// </summary>
        /// <returns></returns>
        public byte[] ToArray()
        {
            int          pos;
            UInt32       value;
            GXByteBuffer bb        = new GXByteBuffer();
            int          zeroIndex = -1;

            for (pos = 0; pos != Count; ++pos)
            {
                value = Data[pos];
                if (value == 0)
                {
                    zeroIndex = pos;
                }
                else
                {
                    zeroIndex = -1;
                }
                bb.SetUInt32(value);
                Array.Reverse(bb.Data, 4 * pos, 4);
            }
            //Remove leading zeroes.
            if (zeroIndex != -1)
            {
                bb.Size = zeroIndex * 4;
            }
            Array.Reverse(bb.Data, 0, bb.Size);
            return(bb.Array());
        }
Beispiel #2
0
        public override string ToString()
        {
            string str = null;

            if (IsZero)
            {
                str = "0x00";
            }
            else
            {
                int          pos, cnt = 0;
                GXByteBuffer bb = new GXByteBuffer();
                for (pos = Count - 1; pos != -1; --pos)
                {
                    bb.SetUInt32(Data[pos]);
                }
                for (pos = 0; pos != bb.Size; ++pos)
                {
                    if (bb.Data[pos] != 0)
                    {
                        cnt = bb.Size - pos;
                        break;
                    }
                }
                if (negative)
                {
                    str = "-";
                }
                str += "0x";
                str += bb.ToHex(false, pos, cnt);
            }
            return(str);
        }
Beispiel #3
0
        /// <summary>
        /// Generate KDF.
        /// </summary>
        /// <param name="securitySuite">Security suite.</param>
        /// <param name="z">z Shared Secret.</param>
        /// <param name="otherInfo">Other info.</param>
        /// <returns></returns>
        public static byte[] GenerateKDF(SecuritySuite securitySuite, byte[] z, byte[] otherInfo)
        {
            GXByteBuffer bb = new GXByteBuffer();

            bb.SetUInt32(1);
            bb.Set(z);
            bb.Set(otherInfo);
            if (securitySuite == SecuritySuite.Ecdsa256)
            {
                using (SHA256 sha = new SHA256CryptoServiceProvider())
                {
                    return(sha.ComputeHash(bb.Array()));
                }
            }
            else if (securitySuite == SecuritySuite.Ecdsa384)
            {
                using (SHA384 sha = new SHA384CryptoServiceProvider())
                {
                    return(sha.ComputeHash(bb.Array()));
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException("Invalid sevurity suite.");
            }
        }
Beispiel #4
0
        /// <summary>
        /// Generate GMAC password from given challenge.
        /// </summary>
        /// <param name="challenge"></param>
        /// <returns></returns>
        public byte[] GenerateGmacPassword(byte[] challenge)
        {
            AesGcmParameter p = new AesGcmParameter(0x10, Gurux.DLMS.Enums.Security.Authentication, InvocationCounter,
                                                    systemTitle, BlockCipherKey, AuthenticationKey);
            GXByteBuffer bb = new GXByteBuffer();

            GXDLMSChippering.EncryptAesGcm(p, challenge);
            bb.SetUInt8(0x10);
            bb.SetUInt32(InvocationCounter);
            bb.Set(p.CountTag);
            return(bb.Array());
        }
Beispiel #5
0
        /// <summary>
        /// Convert value to byte array.
        /// </summary>
        /// <returns></returns>
        public byte[] ToArray(int start, int count)
        {
            int          pos;
            GXByteBuffer bb = new GXByteBuffer();

            for (pos = start; pos != count; ++pos)
            {
                bb.SetUInt32(Data[pos]);
                Array.Reverse(bb.Data, 4 * pos, 4);
            }
            Array.Reverse(bb.Data, 0, bb.Size);
            return(bb.Array());
        }
Beispiel #6
0
 private void ValuesLb_ItemCheck(object sender, ItemCheckEventArgs e)
 {
     try
     {
         if (DurationTb.Text != "")
         {
             UInt32        dur = UInt32.Parse(DurationTb.Text);
             StringBuilder sb  = new StringBuilder();
             for (int pos = 0; pos != 16; ++pos)
             {
                 if (e != null && e.Index == pos)
                 {
                     sb.Append(e.NewValue == CheckState.Checked ? "1" : "0");
                 }
                 else
                 {
                     if (ValuesLb.GetItemChecked(pos))
                     {
                         sb.Append("1");
                     }
                     else
                     {
                         sb.Append("0");
                     }
                 }
             }
             GXBitString  bs = new GXBitString(sb.ToString());
             GXByteBuffer bb = new GXByteBuffer();
             bb.SetUInt16(Convert.ToUInt16(bs));
             bb.SetUInt32(dur);
             (Target as GXDLMSData).Value = bb.Array();
             errorProvider1.SetError((Control)sender, Properties.Resources.ValueChangedTxt);
             Target.UpdateDirty(2, bb.Array());
             HexTb.Text = bb.ToString();
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
Beispiel #7
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return(GXCommon.LogicalNameToBytes(LogicalName));
     }
     if (e.Index == 2)
     {
         return(GetObjects(settings, e).Array());
     }
     if (e.Index == 3)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         data.SetUInt8(2);
         data.SetUInt8((byte)DataType.Int8);
         data.SetUInt8(ClientSAP);
         data.SetUInt8((byte)DataType.UInt16);
         data.SetUInt16(ServerSAP);
         return(data.Array());
     }
     if (e.Index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         data.SetUInt8(0x7);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.JointIsoCtt);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.Country);
         GXCommon.SetData(settings, data, DataType.UInt16, ApplicationContextName.CountryName);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.IdentifiedOrganization);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.DlmsUA);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.ApplicationContext);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.ContextId);
         return(data.Array());
     }
     if (e.Index == 5)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         data.SetUInt8(6);
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt32((UInt32)XDLMSContextInfo.Conformance);
         GXCommon.SetData(settings, data, DataType.BitString, bb.SubArray(1, 3));
         GXCommon.SetData(settings, data, DataType.UInt16, XDLMSContextInfo.MaxReceivePduSize);
         GXCommon.SetData(settings, data, DataType.UInt16, XDLMSContextInfo.MaxSendPduSize);
         GXCommon.SetData(settings, data, DataType.UInt8, XDLMSContextInfo.DlmsVersionNumber);
         GXCommon.SetData(settings, data, DataType.Int8, XDLMSContextInfo.QualityOfService);
         GXCommon.SetData(settings, data, DataType.OctetString, XDLMSContextInfo.CypheringInfo);
         return(data.Array());
     }
     if (e.Index == 6)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         data.SetUInt8(0x7);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.JointIsoCtt);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.Country);
         GXCommon.SetData(settings, data, DataType.UInt16, AuthenticationMechanismName.CountryName);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.IdentifiedOrganization);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.DlmsUA);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.AuthenticationMechanismName);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.MechanismId);
         return(data.Array());
     }
     if (e.Index == 7)
     {
         return(Secret);
     }
     if (e.Index == 8)
     {
         return(AssociationStatus);
     }
     if (e.Index == 9)
     {
         return(GXCommon.LogicalNameToBytes(SecuritySetupReference));
     }
     if (e.Index == 10)
     {
         return(GetUserList(settings, e).Array());
     }
     if (e.Index == 11)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add structure size.
         data.SetUInt8(2);
         GXCommon.SetData(settings, data, DataType.UInt8, CurrentUser.Key);
         GXCommon.SetData(settings, data, DataType.String, CurrentUser.Value);
         return(data.Array());
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return(null);
 }
Beispiel #8
0
        ///<summary>
        /// Chipher text.
        ///</summary>
        ///<param name="settings">
        ///DLMS settings.
        ///</param>
        ///<param name="cipher">
        ///Cipher.
        ///</param>
        ///<param name="ic">
        ///Invocation counter.
        ///</param>
        ///<param name="data">
        ///Text to chipher.
        ///</param>
        ///<param name="secret">
        ///Secret.
        ///</param>
        ///<returns>
        ///Chiphered text.
        ///</returns>
        public static byte[] Secure(GXDLMSSettings settings, GXICipher cipher, uint ic, byte[] data, byte[] secret)
        {
            byte[] tmp;
            if (settings.Authentication == Authentication.High)
            {
                int len = secret.Length;
                if (len % 16 != 0)
                {
                    len += 16 - (secret.Length % 16);
                }
                byte[] p = new byte[len];
                byte[] s = new byte[16];
                byte[] x = new byte[16];
                int    i;
                data.CopyTo(p, 0);
                secret.CopyTo(s, 0);
                for (i = 0; i < p.Length; i += 16)
                {
                    Buffer.BlockCopy(p, i, x, 0, 16);
                    GXAes128.Encrypt(x, s);
                    Buffer.BlockCopy(x, 0, p, i, 16);
                }
                Buffer.BlockCopy(p, 0, x, 0, 16);
                return(x);
            }
            // Get server Challenge.
            GXByteBuffer challenge = new GXByteBuffer();

            // Get shared secret
            if (settings.Authentication == Authentication.HighGMAC)
            {
                challenge.Set(data);
            }
            else
            {
                challenge.Set(data);
                challenge.Set(secret);
            }
            tmp = challenge.Array();
            if (settings.Authentication == Authentication.HighMD5)
            {
#if !WINDOWS_UWP
                using (MD5 md5Hash = MD5.Create())
                {
                    tmp = md5Hash.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighSHA1)
            {
#if !WINDOWS_UWP
                using (SHA1 sha = new SHA1CryptoServiceProvider())
                {
                    tmp = sha.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighGMAC)
            {
                //SC is always Security.Authentication.
                AesGcmParameter p = new AesGcmParameter(0, Security.Authentication, ic,
                                                        secret, cipher.BlockCipherKey, cipher.AuthenticationKey);
                p.Type = CountType.Tag;
                challenge.Clear();
                challenge.SetUInt8((byte)Security.Authentication);
                challenge.SetUInt32(p.InvocationCounter);
                challenge.Set(GXDLMSChippering.EncryptAesGcm(p, tmp));
                tmp = challenge.Array();
                return(tmp);
            }
            return(data);
        }
Beispiel #9
0
 ///<summary>
 /// Chipher text.
 ///</summary>
 ///<param name="settings">
 ///DLMS settings. 
 ///</param>
 ///<param name="cipher">
 ///Cipher. 
 ///</param>
 ///<param name="ic">
 ///Invocation counter.
 ///</param>
 ///<param name="data">
 ///Text to chipher. 
 ///</param>
 ///<param name="secret">
 ///Secret. 
 ///</param>
 ///<returns>
 ///Chiphered text.
 ///</returns>
 public static byte[] Secure(GXDLMSSettings settings, GXICipher cipher, UInt32 ic, byte[] data, byte[] secret)
 {
     byte[] tmp;
     if (settings.Authentication == Authentication.High)
     {
         int len = secret.Length;
         if (len % 16 != 0)
         {
             len += 16 - (secret.Length % 16);
         }
         byte[] p = new byte[len];
         byte[] s = new byte[16];
         byte[] x = new byte[16];
         int i;
         data.CopyTo(p, 0);
         secret.CopyTo(s, 0);
         for (i = 0; i < p.Length; i += 16)
         {
             Buffer.BlockCopy(p, i, x, 0, 16);
             GXAes128.Encrypt(x, s);
             Buffer.BlockCopy(x, 0, p, i, 16);
         }
         Buffer.BlockCopy(p, 0, x, 0, 16);
         return x;
     }
     // Get server Challenge.
     GXByteBuffer challenge = new GXByteBuffer();
     // Get shared secret
     if (settings.Authentication == Authentication.HighGMAC)
     {
         challenge.Set(data);              
     }
     else
     {
         challenge.Set(data);
         challenge.Set(secret);
     }
     tmp = challenge.Array();
     if (settings.Authentication == Authentication.HighMD5)
     {
         using (MD5 md5Hash = MD5.Create())
         {
             tmp = md5Hash.ComputeHash(tmp);
             return tmp;
         }
     }
     else if (settings.Authentication == Authentication.HighSHA1)
     {
         using (SHA1 sha = new SHA1CryptoServiceProvider())
         {
             tmp = sha.ComputeHash(tmp);
             return tmp;
         }
     }
     else if (settings.Authentication == Authentication.HighGMAC)
     {
         //SC is always Security.Authentication.
         AesGcmParameter p = new AesGcmParameter(0, Security.Authentication, ic,
             secret, cipher.BlockCipherKey, cipher.AuthenticationKey);
         p.Type = CountType.Tag;
         challenge.Clear();
         challenge.SetUInt8((byte)Security.Authentication);
         challenge.SetUInt32(p.FrameCounter);
         challenge.Set(GXDLMSChippering.EncryptAesGcm(p, tmp));
         tmp = challenge.Array();
         return tmp;
     }
     return data;
 }
Beispiel #10
0
        ///<summary>
        /// Chipher text.
        ///</summary>
        ///<param name="settings">
        ///DLMS settings.
        ///</param>
        ///<param name="cipher">
        ///Cipher.
        ///</param>
        ///<param name="ic">
        ///Invocation counter.
        ///</param>
        ///<param name="data">
        ///Text to chipher.
        ///</param>
        ///<param name="secret">
        ///Secret.
        ///</param>
        ///<returns>
        ///Chiphered text.
        ///</returns>
        internal static byte[] Secure(GXDLMSSettings settings, GXICipher cipher, UInt32 ic, byte[] data, byte[] secret)
        {
            byte[] tmp;
            if (settings.Authentication == Authentication.High)
            {
                int len = secret.Length;
                if (len % 16 != 0)
                {
                    len += 16 - (secret.Length % 16);
                }
                byte[] p = new byte[len];
                byte[] s = new byte[16];
                byte[] x = new byte[16];
                int    i;
                data.CopyTo(p, 0);
                secret.CopyTo(s, 0);
                for (i = 0; i < p.Length; i += 16)
                {
                    Buffer.BlockCopy(p, i, x, 0, 16);
                    GXAes128.Encrypt(x, s);
                    Buffer.BlockCopy(x, 0, p, i, 16);
                }
                Buffer.BlockCopy(p, 0, x, 0, 16);
                return(x);
            }
            // Get server Challenge.
            GXByteBuffer challenge = new GXByteBuffer();

            // Get shared secret
            if (settings.Authentication == Authentication.HighGMAC ||
                settings.Authentication == Authentication.HighECDSA)
            {
                challenge.Set(data);
            }
            else if (settings.Authentication == Authentication.HighSHA256)
            {
                challenge.Set(secret);
            }
            else
            {
                challenge.Set(data);
                challenge.Set(secret);
            }
            tmp = challenge.Array();
            if (settings.Authentication == Authentication.HighMD5)
            {
#if !WINDOWS_UWP
                using (MD5 md5Hash = MD5.Create())
                {
                    tmp = md5Hash.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighSHA1)
            {
#if !WINDOWS_UWP
                using (SHA1 sha = new SHA1CryptoServiceProvider())
                {
                    tmp = sha.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighSHA256)
            {
                //Windows UWP, IOS ad Android don't support this.
#if !WINDOWS_UWP && !__IOS__ && !__ANDROID__
                using (SHA256 sha = new SHA256CryptoServiceProvider())
                {
                    tmp = sha.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighGMAC)
            {
                //SC is always Security.Authentication.
                AesGcmParameter p = new AesGcmParameter(0, Security.Authentication,
                                                        cipher.SecuritySuite,
                                                        ic,
                                                        secret,
                                                        cipher.BlockCipherKey,
                                                        cipher.AuthenticationKey);
                p.Type = CountType.Tag;
                challenge.Clear();
                //Security suite is 0.
                challenge.SetUInt8((byte)Security.Authentication);
                challenge.SetUInt32((UInt32)p.InvocationCounter);
                challenge.Set(GXDLMSChippering.EncryptAesGcm(p, tmp));
                tmp = challenge.Array();
                return(tmp);
            }
            else if (settings.Authentication == Authentication.HighECDSA)
            {
                if (cipher.SigningKeyPair.Key == null)
                {
                    throw new ArgumentNullException("SigningKeyPair is not set.");
                }
                GXEcdsa      sig = new GXEcdsa(cipher.SigningKeyPair.Key);
                GXByteBuffer bb  = new GXByteBuffer();
                bb.Set(settings.Cipher.SystemTitle);
                bb.Set(settings.SourceSystemTitle);
                if (settings.IsServer)
                {
                    bb.Set(settings.CtoSChallenge);
                    bb.Set(settings.StoCChallenge);
                }
                else
                {
                    bb.Set(settings.StoCChallenge);
                    bb.Set(settings.CtoSChallenge);
                }
                data = sig.Sign(bb.Array());
            }
            return(data);
        }
Beispiel #11
0
 /// <summary>
 /// Set item count.
 /// </summary>
 /// <param name="count"></param>
 /// <param name="buff"></param>
 internal static void SetObjectCount(int count, GXByteBuffer buff)
 {
     if (count < 0x80)
     {
         buff.SetUInt8((byte)count);
     }
     else if (count < 0x100)
     {
         buff.SetUInt8(0x81);
         buff.SetUInt8((byte)count);
     }
     else if (count < 0x10000)
     {
         buff.SetUInt8(0x82);
         buff.SetUInt16((UInt16)count);
     }
     else
     {
         buff.SetUInt8(0x84);
         buff.SetUInt32((UInt32)count);
     }
 }
Beispiel #12
0
        ///<summary>
        ///Convert object to DLMS bytes.
        ///</summary>
        ///<param name="settings">DLMS settings.</param>
        ///<param name="buff">Byte buffer where data is write.</param>
        ///<param name="dataType">Data type.</param>
        ///<param name="value">Added Value.</param>
        public static void SetData(GXDLMSSettings settings, GXByteBuffer buff, DataType type, object value)
        {
            if ((type == DataType.Array || type == DataType.Structure) && value is byte[])
            {
                // If byte array is added do not add type.
                buff.Set((byte[])value);
                return;
            }
            buff.SetUInt8((byte)type);
            switch (type)
            {
                case DataType.None:
                    break;
                case DataType.Boolean:
                    if (Convert.ToBoolean(value))
                    {
                        buff.SetUInt8(1);
                    }
                    else
                    {
                        buff.SetUInt8(0);
                    }
                    break;
                case DataType.Int8:
                    buff.SetUInt8((byte)Convert.ToSByte(value));
                    break;
                case DataType.UInt8:
                case DataType.Enum:
                    buff.SetUInt8(Convert.ToByte(value));
                    break;
                case DataType.Int16:
                    if (value is UInt16)
                    {
                        buff.SetUInt16((UInt16)value);
                    }
                    else
                    {
                        buff.SetUInt16((UInt16)(Convert.ToInt16(value) & 0xFFFF));
                    }
                    break;
                case DataType.UInt16:
                    buff.SetUInt16(Convert.ToUInt16(value));
                    break;
                case DataType.Int32:
                    buff.SetUInt32((UInt32)Convert.ToInt32(value));
                    break;
                case DataType.UInt32:

                    buff.SetUInt32(Convert.ToUInt32(value));
                    break;
                case DataType.Int64:
                    buff.SetUInt64((UInt64)Convert.ToInt64(value));
                    break;
                case DataType.UInt64:
                    buff.SetUInt64(Convert.ToUInt64(value));
                    break;
                case DataType.Float32:
                    buff.SetFloat((float)value);
                    break;
                case DataType.Float64:
                    buff.SetDouble((double)value);
                    break;
                case DataType.BitString:
                    SetBitString(buff, value);
                    break;
                case DataType.String:
                    SetString(buff, value);
                    break;
                case DataType.StringUTF8:
                    SetUtcString(buff, value);
                    break;
                case DataType.OctetString:
                    if (value is GXDate)
                    {
                        //Add size
                        buff.SetUInt8(5);
                        SetDate(buff, value);
                    }
                    else if (value is GXTime)
                    {
                        //Add size
                        buff.SetUInt8(4);
                        SetTime(buff, value);
                    }
                    else if (value is GXDateTime || value is DateTime)
                    {
                        //Add size
                        buff.SetUInt8(12);
                        SetDateTime(settings, buff, value);
                    }
                    else
                    {
                        SetOctetString(buff, value);
                    }
                    break;
                case DataType.Array:
                case DataType.Structure:
                    SetArray(settings, buff, value);
                    break;
                case DataType.Bcd:
                    SetBcd(buff, value);
                    break;
                case DataType.CompactArray:
                    throw new Exception("Invalid data type.");
                case DataType.DateTime:
                    SetDateTime(settings, buff, value);
                    break;
                case DataType.Date:
                    SetDate(buff, value);
                    break;
                case DataType.Time:
                    SetTime(buff, value);
                    break;
                default:
                    throw new Exception("Invalid data type.");
            }
        }