/// <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()); }
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); }
/// <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."); } }
/// <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()); }
/// <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()); }
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); } }
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); }
///<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); }
///<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; }
///<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); }
/// <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); } }
///<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."); } }