/// <summary>
 /// Refresh certificates.
 /// </summary>
 public void RefreshCertificates()
 {
     CertificatesList.Items.Clear();
     Certificates.Clear();
     keys.Clear();
     duplicate.Clear();
     foreach (string p in Directory.GetFiles(CertificateFolder))
     {
         string ext = Path.GetExtension(p);
         if (string.Compare(ext, ".pem", true) == 0 || string.Compare(ext, ".cer", true) == 0)
         {
             try
             {
                 GXx509Certificate cert = GXx509Certificate.Load(p);
                 AddCertificate(cert, p, null);
             }
             catch (Exception ex)
             {
                 ListViewItem li = new ListViewItem(new string[] { ex.Message, "", "", "", "", Path.GetFileNameWithoutExtension(p) });
                 li.Tag       = p;
                 li.BackColor = Color.Red;
                 CertificatesList.Items.Add(li);
             }
         }
     }
 }
Beispiel #2
0
 private void SelectWithCertificate(ComboBox items, string value)
 {
     try
     {
         GXx509Certificate cert = GXx509Certificate.FromDer(value);
         bool found             = false;
         //Select default values.
         foreach (object tmp in items.Items)
         {
             if (tmp is KeyValuePair <GXPkcs8, GXx509Certificate> it)
             {
                 if (it.Value.Equals(cert))
                 {
                     items.SelectedItem = it;
                     found = true;
                     break;
                 }
             }
         }
         if (!found)
         {
             items.SelectedIndex = items.Items.Add(new KeyValuePair <GXPkcs8, GXx509Certificate>(null, cert));
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(Parent, ex.Message);
     }
 }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="certificateFolder"></param>
        /// <param name="title"></param>
        /// <param name="systemTitle">If system title is not null this certificate is selected.</param>
        public GXCertificateForm(IGXUpdater updater, string address, string certificateFolder, string title, byte[] systemTitle)
        {
            InitializeComponent();
            _updater = updater;
            _address = address;
            string st = null;

            if (systemTitle != null && systemTitle.Length == 8)
            {
                st = GXAsn1Converter.SystemTitleToSubject(systemTitle);
            }

            Certificates      = new GXx509CertificateCollection();
            CertificateFolder = certificateFolder;
            Title             = title;
            foreach (string p in Directory.GetFiles(CertificateFolder))
            {
                string ext = Path.GetExtension(p);
                if (string.Compare(ext, ".pem", true) == 0 || string.Compare(ext, ".cer", true) == 0)
                {
                    try
                    {
                        GXx509Certificate cert = GXx509Certificate.Load(p);
                        AddCertificate(cert, p, st);
                    }
                    catch (Exception ex)
                    {
                        ListViewItem li = new ListViewItem(new string[] { ex.Message, "", "", "", "", Path.GetFileNameWithoutExtension(p) });
                        li.Tag       = p;
                        li.BackColor = Color.Red;
                        CertificatesList.Items.Add(li);
                    }
                }
            }
        }
Beispiel #4
0
        internal void ShowInfo(GXx509Certificate cert)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Public key info:");
            sb.AppendLine(cert.ToString());
            MessageBox.Show(Parent, sb.ToString());
        }
 /// <summary>
 /// Add new certificate.
 /// </summary>
 private void CertificateAddMnu_Click(object sender, EventArgs e)
 {
     try
     {
         OpenFileDialog dlg = new OpenFileDialog();
         dlg.Multiselect = true;
         if (string.IsNullOrEmpty(_path))
         {
             dlg.InitialDirectory = Directory.GetCurrentDirectory();
         }
         else
         {
             System.IO.FileInfo fi = new System.IO.FileInfo(_path);
             dlg.InitialDirectory = fi.DirectoryName;
             dlg.FileName         = fi.Name;
         }
         dlg.Filter        = Properties.Resources.PemFilterTxt;
         dlg.DefaultExt    = ".pem";
         dlg.ValidateNames = true;
         if (dlg.ShowDialog(Parent) == DialogResult.OK)
         {
             foreach (string fileName in dlg.FileNames)
             {
                 try
                 {
                     _path = fileName;
                     if (File.Exists(fileName))
                     {
                         GXx509Certificate cert = GXx509Certificate.Load(fileName);
                         foreach (ListViewItem it in CertificatesList.Items)
                         {
                             if (it.SubItems[1].Text == cert.SerialNumber.ToString())
                             {
                                 throw new Exception("Certificate already exists for the meter." + cert.Subject +
                                                     ". File name:" + Path.GetFileNameWithoutExtension((string)it.Tag));
                             }
                         }
                         string path = Path.Combine(CertificateFolder, Path.GetFileName(fileName));
                         cert.Save(path);
                         AddCertificate(cert, path, null);
                     }
                 }
                 catch (Exception ex)
                 {
                     MessageBox.Show(Parent, ex.Message);
                 }
             }
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(Parent, ex.Message);
     }
 }
 private void InfoMnu_Click(object sender, EventArgs e)
 {
     try
     {
         ListViewItem it = CertificatesList.SelectedItems[0];
         ShowInfo(GXx509Certificate.Load((string)it.Tag));
     }
     catch (Exception ex)
     {
         MessageBox.Show(Parent, ex.Message);
     }
 }
        internal void ShowInfo(GXx509Certificate cert)
        {
            StringBuilder sb = new StringBuilder();

            if (!string.IsNullOrEmpty(cert.Description))
            {
                sb.AppendLine("Description:");
                sb.AppendLine(cert.Description);
                sb.AppendLine("");
            }
            sb.AppendLine("Public key info:");
            sb.AppendLine(cert.ToString());
            MessageBox.Show(Parent, sb.ToString());
        }
        private void AddCertificate(GXx509Certificate cert, string path, string st)
        {
            ListViewItem li  = new ListViewItem(cert.PublicKey.Scheme.ToString());
            string       tmp = GXDLMSTranslator.ToHex(GXAsn1Converter.SystemTitleFromSubject(cert.Subject));

            tmp += ((int)cert.KeyUsage).ToString();
            object tmp2 = keys[tmp];

            //Show duplicate certificates.
            if (tmp2 == null)
            {
                keys[tmp]      = cert.KeyUsage;
                duplicate[tmp] = li;
            }
            else
            {
                ((ListViewItem)duplicate[tmp]).BackColor = Color.Yellow;
                li.BackColor = Color.Yellow;
            }
            li.StateImageIndex = li.ImageIndex = 0;
            li.SubItems.Add(cert.SerialNumber.ToString());
            li.SubItems.Add(cert.Subject);
            li.SubItems.Add(cert.ValidFrom + "-" + cert.ValidTo);
            StringBuilder sb = new StringBuilder();

            foreach (KeyUsage it in Enum.GetValues(typeof(KeyUsage)))
            {
                if (((int)it & (int)cert.KeyUsage) != 0)
                {
                    sb.Append(it);
                    sb.Append(", ");
                }
            }
            if (sb.Length != 0)
            {
                sb.Length -= 2;
            }
            li.SubItems.Add(sb.ToString());
            li.SubItems.Add(Path.GetFileNameWithoutExtension(path));
            li.SubItems.Add(cert.Description);
            CertificatesList.Items.Add(li);
            li.Tag = path;
            if (st != null && cert.Subject.Contains(st))
            {
                li.Selected = true;
            }
            Certificates.Add(cert);
        }
Beispiel #9
0
 void SaveCertificate(GXActionArgs arg)
 {
     try
     {
         GXx509Certificate csr = new GXx509Certificate((byte[])arg.Value);
         SaveFileDialog    dlg = new SaveFileDialog();
         dlg.Filter     = Properties.Resources.PemFilterTxt;
         dlg.DefaultExt = ".pem";
         if (string.IsNullOrEmpty(path))
         {
             dlg.InitialDirectory = Directory.GetCurrentDirectory();
         }
         else
         {
             FileInfo fi = new FileInfo(path);
             dlg.InitialDirectory = fi.DirectoryName;
             dlg.FileName         = fi.Name;
         }
         dlg.FileName = "";
         int pos = csr.Subject.IndexOf("CN=");
         if (pos != -1)
         {
             string name;
             if (csr.KeyUsage == ASN.Enums.KeyUsage.DigitalSignature)
             {
                 name = "D";
             }
             else if (csr.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement)
             {
                 name = "A";
             }
             else
             {
                 name = "";
             }
             dlg.FileName = name + csr.Subject.Substring(pos + 3, 16);
         }
         if (dlg.ShowDialog(Parent) == DialogResult.OK)
         {
             csr.Save(dlg.FileName);
             path = dlg.FileName;
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(Parent, ex.Message);
     }
 }
 /// <summary>
 /// Copy system title to clipboard.
 /// </summary>
 private void CopySystemTitleMnu_Click(object sender, EventArgs e)
 {
     try
     {
         ListViewItem it      = CertificatesList.SelectedItems[0];
         string       subject = GXx509Certificate.Load((string)it.Tag).Subject;
         int          pos     = subject.IndexOf("CN=");
         if (pos == -1)
         {
             throw new Exception("System title not found.");
         }
         subject = subject.Substring(pos + 3, 16);
         Clipboard.SetText(subject);
     }
     catch (Exception ex)
     {
         MessageBox.Show(Parent, ex.Message);
     }
 }
 private void descriptionToolStripMenuItem_Click(object sender, EventArgs e)
 {
     try
     {
         ListViewItem it  = CertificatesList.SelectedItems[0];
         GXTextDlg    dlg = new GXTextDlg("Certificate description.", "Certificate description:", it.SubItems[6].Text);
         if (dlg.ShowDialog(Parent) == DialogResult.OK)
         {
             string            desc = dlg.GetValue();
             GXx509Certificate cert = GXx509Certificate.Load((string)it.Tag);
             cert.Description = desc;
             cert.Save((string)it.Tag);
             it.SubItems[6].Text = desc;
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(Parent, ex.Message);
     }
 }
Beispiel #12
0
 void ImportCertificate(GXActionArgs arg)
 {
     try
     {
         OpenFileDialog dlg = new OpenFileDialog();
         dlg.Multiselect = false;
         if (string.IsNullOrEmpty(path))
         {
             dlg.InitialDirectory = Directory.GetCurrentDirectory();
         }
         else
         {
             FileInfo fi = new FileInfo(path);
             dlg.InitialDirectory = fi.DirectoryName;
             dlg.FileName         = fi.Name;
         }
         dlg.Filter        = Properties.Resources.PemFilterTxt;
         dlg.DefaultExt    = ".pem";
         dlg.ValidateNames = true;
         if (dlg.ShowDialog(Parent) == DialogResult.OK)
         {
             foreach (string fileName in dlg.FileNames)
             {
                 GXx509Certificate cert = GXx509Certificate.Load(fileName);
                 arg.Value = ((GXDLMSSecuritySetup)arg.Target).ImportCertificate(arg.Client, cert);
             }
         }
         else
         {
             arg.Handled = true;
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(Parent, ex.Message);
     }
 }
Beispiel #13
0
 private void OKBtn_Click(object sender, EventArgs e)
 {
     try
     {
         List <GXCertificateRequest> certificates = new List <GXCertificateRequest>();
         GXCertificateRequest        it           = new GXCertificateRequest();
         it.Certificate = GXPkcs10.FromPem(Pkcs10Tb.Text);
         if (DigitalSignatureCb.Checked)
         {
             it.CertificateType = CertificateType.DigitalSignature;
         }
         else if (KeyAgreementCb.Checked)
         {
             it.CertificateType = CertificateType.KeyAgreement;
         }
         else
         {
             if (ServerTlsCb.Checked)
             {
                 it.ExtendedKeyUsage = ExtendedKeyUsage.ServerAuth;
             }
             else
             {
                 it.ExtendedKeyUsage = ExtendedKeyUsage.ClientAuth;
             }
             it.CertificateType = CertificateType.TLS;
         }
         certificates.Add(it);
         Certificate = GXPkcs10.GetCertificate(_address, certificates)[0];
     }
     catch (Exception ex)
     {
         DialogResult = DialogResult.None;
         MessageBox.Show(Parent, ex.Message);
     }
 }
 /// <summary>
 /// Add new certificate.
 /// </summary>
 private void CertificateAddMnu_Click(object sender, EventArgs e)
 {
     try
     {
         OpenFileDialog dlg = new OpenFileDialog();
         dlg.Multiselect = false;
         if (string.IsNullOrEmpty(path))
         {
             dlg.InitialDirectory = Directory.GetCurrentDirectory();
         }
         else
         {
             System.IO.FileInfo fi = new System.IO.FileInfo(path);
             dlg.InitialDirectory = fi.DirectoryName;
             dlg.FileName         = fi.Name;
         }
         dlg.Filter        = Properties.Resources.CertificateFilterTxt;
         dlg.DefaultExt    = ".pem";
         dlg.ValidateNames = true;
         if (dlg.ShowDialog(this) == DialogResult.OK)
         {
             bool exists = false;
             if (File.Exists(dlg.FileName))
             {
                 try
                 {
                     GXx509Certificate cert = GXx509Certificate.Load(dlg.FileName);
                     foreach (ListViewItem it in CertificatesList.Items)
                     {
                         if (it.Tag is GXx509Certificate c)
                         {
                             if (c.Subject == cert.Subject)
                             {
                                 exists = true;
                                 throw new Exception("Public key already exists.");
                             }
                         }
                     }
                     ListViewItem li = new ListViewItem("Public Key");
                     li.StateImageIndex = li.ImageIndex = 0;
                     li.SubItems.Add(cert.Subject);
                     li.SubItems.Add(cert.ValidFrom + "-" + cert.ValidTo);
                     StringBuilder sb = new StringBuilder();
                     foreach (KeyUsage it in Enum.GetValues(typeof(KeyUsage)))
                     {
                         if (((int)it & (int)cert.KeyUsage) != 0)
                         {
                             sb.Append(it);
                             sb.Append(", ");
                         }
                     }
                     if (sb.Length != 0)
                     {
                         sb.Length -= 2;
                     }
                     li.SubItems.Add(sb.ToString());
                     CertificatesList.Items.Add(li).Tag = cert;
                 }
                 catch (Exception)
                 {
                     if (!exists)
                     {
                         //Check if this is private key.
                         GXPkcs8      cert = GXPkcs8.Load(dlg.FileName);
                         ListViewItem li   = new ListViewItem("Private Key");
                         li.StateImageIndex = li.ImageIndex = 1;
                         foreach (ListViewItem it in CertificatesList.Items)
                         {
                             if (it.Tag is GXPkcs8)
                             {
                                 throw new Exception("Private key already exists. There can be only one private key.");
                             }
                         }
                         CertificatesList.Items.Add(li).Tag = cert;
                     }
                 }
                 path = dlg.FileName;
             }
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(this, ex.Message);
     }
 }
        public DLMSTranslatorForm()
        {
            InitializeComponent();
            translator.Comments = true;
            SecurityCB.Items.AddRange(new object[] { Security.None, Security.Authentication,
                                                     Security.Encryption, Security.AuthenticationEncryption });
            SecurityCB.SelectedItem  = Enum.Parse(typeof(Security), Properties.Settings.Default.Security);
            SystemTitleTB.Text       = Properties.Settings.Default.NotifySystemTitle;
            ServerSystemTitleTB.Text = Properties.Settings.Default.ServerSystemTitle;
            BlockCipherKeyTB.Text    = Properties.Settings.Default.NotifyBlockCipherKey;
            AuthenticationKeyTB.Text = Properties.Settings.Default.AuthenticationKey;
            InvocationCounterTB.Text = Properties.Settings.Default.InvocationCounter.ToString();
            ChallengeTb.Text         = Properties.Settings.Default.Challenge;
            DedicatedKeyTb.Text      = Properties.Settings.Default.DedicatedKey;

            DataPdu.Text = Properties.Settings.Default.Data;
            tabControl1_SelectedIndexChanged(null, null);
            if (!string.IsNullOrEmpty(Properties.Settings.Default.Pdu))
            {
                PduTB.Text = Properties.Settings.Default.Pdu;
            }
            if (!string.IsNullOrEmpty(Properties.Settings.Default.Message))
            {
                MessagePduTB.Text = Properties.Settings.Default.Message;
            }

            try
            {
                string[] certificates = Properties.Settings.Default.Certificates.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string str in certificates)
                {
                    try
                    {
                        if (str[0] == '0')
                        {
                            GXx509Certificate cert = new GXx509Certificate(str.Substring(1));
                            ListViewItem      li   = new ListViewItem("Public Key");
                            li.StateImageIndex = li.ImageIndex = 0;
                            li.SubItems.Add(cert.Subject);
                            li.SubItems.Add(cert.ValidFrom + "-" + cert.ValidTo);
                            StringBuilder sb = new StringBuilder();
                            foreach (KeyUsage it in Enum.GetValues(typeof(KeyUsage)))
                            {
                                if (((int)it & (int)cert.KeyUsage) != 0)
                                {
                                    sb.Append(it);
                                    sb.Append(", ");
                                }
                            }
                            if (sb.Length != 0)
                            {
                                sb.Length -= 2;
                            }
                            li.SubItems.Add(sb.ToString());
                            CertificatesList.Items.Add(li).Tag = cert;
                        }
                        else
                        {
                            GXPkcs8      cert = new GXPkcs8(str.Substring(1));
                            ListViewItem li   = new ListViewItem("Private Key");
                            li.StateImageIndex = li.ImageIndex = 1;
                            foreach (ListViewItem it in CertificatesList.Items)
                            {
                                if (it.Tag is GXPkcs8)
                                {
                                    throw new Exception("Private key already exists. There can be only one private key.");
                                }
                            }
                            CertificatesList.Items.Add(li).Tag = cert;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
Beispiel #16
0
        public static int GetParameters(string[] args, Settings settings)
        {
            string[] tmp;
            List <GXCmdParameter> parameters = GXCommon.GetParameters(args, "h:p:c:s:r:i:It:a:P:g:S:C:n:v:o:T:A:B:D:d:l:F:K:k:m:");
            GXNet net = null;

            foreach (GXCmdParameter it in parameters)
            {
                switch (it.Tag)
                {
                case 'r':
                    if (string.Compare(it.Value, "sn", true) == 0)
                    {
                        settings.client.UseLogicalNameReferencing = false;
                    }
                    else if (string.Compare(it.Value, "ln", true) == 0)
                    {
                        settings.client.UseLogicalNameReferencing = true;
                    }
                    else
                    {
                        throw new ArgumentException("Invalid reference option.");
                    }
                    break;

                case 'h':
                    //Host address.
                    if (settings.media == null)
                    {
                        settings.media = new GXNet();
                    }
                    net          = settings.media as GXNet;
                    net.HostName = it.Value;
                    break;

                case 't':
                    //Trace.
                    try
                    {
                        settings.trace = (TraceLevel)Enum.Parse(typeof(TraceLevel), it.Value);
                    }
                    catch (Exception)
                    {
                        throw new ArgumentException("Invalid trace level option. (Error, Warning, Info, Verbose, Off)");
                    }
                    break;

                case 'p':
                    //Port.
                    if (settings.media == null)
                    {
                        settings.media = new GXNet();
                    }
                    net      = settings.media as GXNet;
                    net.Port = int.Parse(it.Value);
                    break;

                case 'P':    //Password
                    settings.client.Password = ASCIIEncoding.ASCII.GetBytes(it.Value);
                    break;

                case 'i':
                    try
                    {
                        settings.client.InterfaceType = (InterfaceType)Enum.Parse(typeof(InterfaceType), it.Value);
                        settings.client.Plc.Reset();
                    }
                    catch (Exception)
                    {
                        throw new ArgumentException("Invalid interface type option. (HDLC, WRAPPER, HdlcWithModeE, Plc, PlcHdlc)");
                    }
                    break;

                case 'I':
                    //AutoIncreaseInvokeID.
                    settings.client.AutoIncreaseInvokeID = true;
                    break;

                case 'v':
                    settings.invocationCounter = it.Value.Trim();
                    Objects.GXDLMSObject.ValidateLogicalName(settings.invocationCounter);
                    break;

                case 'g':
                    //Get (read) selected objects.
                    foreach (string o in it.Value.Split(new char[] { ';', ',' }))
                    {
                        tmp = o.Split(new char[] { ':' });
                        if (tmp.Length != 2)
                        {
                            throw new ArgumentOutOfRangeException("Invalid Logical name or attribute index.");
                        }
                        settings.readObjects.Add(new KeyValuePair <string, int>(tmp[0].Trim(), int.Parse(tmp[1].Trim())));
                    }
                    break;

                case 'S':    //Serial Port
                    settings.media = new GXSerial();
                    GXSerial serial = settings.media as GXSerial;
                    tmp             = it.Value.Split(':');
                    serial.PortName = tmp[0];
                    if (tmp.Length > 1)
                    {
                        serial.BaudRate = int.Parse(tmp[1]);
                        serial.DataBits = int.Parse(tmp[2].Substring(0, 1));
                        serial.Parity   = (Parity)Enum.Parse(typeof(Parity), tmp[2].Substring(1, tmp[2].Length - 2));
                        serial.StopBits = (StopBits)int.Parse(tmp[2].Substring(tmp[2].Length - 1, 1));
                    }
                    else
                    {
                        if (settings.client.InterfaceType == InterfaceType.HdlcWithModeE)
                        {
                            serial.BaudRate = 300;
                            serial.DataBits = 7;
                            serial.Parity   = Parity.Even;
                            serial.StopBits = StopBits.One;
                        }
                        else
                        {
                            serial.BaudRate = 9600;
                            serial.DataBits = 8;
                            serial.Parity   = Parity.None;
                            serial.StopBits = StopBits.One;
                        }
                    }
                    break;

                case 'a':
                    try
                    {
                        if (string.Compare("None", it.Value, true) == 0)
                        {
                            settings.client.Authentication = Authentication.None;
                        }
                        else if (string.Compare("Low", it.Value, true) == 0)
                        {
                            settings.client.Authentication = Authentication.Low;
                        }
                        else if (string.Compare("High", it.Value, true) == 0)
                        {
                            settings.client.Authentication = Authentication.High;
                        }
                        else if (string.Compare("HighMd5", it.Value, true) == 0)
                        {
                            settings.client.Authentication = Authentication.HighMD5;
                        }
                        else if (string.Compare("HighSha1", it.Value, true) == 0)
                        {
                            settings.client.Authentication = Authentication.HighSHA1;
                        }
                        else if (string.Compare("HighSha256", it.Value, true) == 0)
                        {
                            settings.client.Authentication = Authentication.HighSHA256;
                        }
                        else if (string.Compare("HighGMac", it.Value, true) == 0)
                        {
                            settings.client.Authentication = Authentication.HighGMAC;
                        }
                        else if (string.Compare("HighECDSA", it.Value, true) == 0)
                        {
                            settings.client.Authentication = Authentication.HighECDSA;
                        }
                        else
                        {
                            throw new ArgumentException("Invalid Authentication option: '" + it.Value + "'. (None, Low, High, HighMd5, HighSha1, HighGMac, HighSha256)");
                        }
                    }
                    catch (Exception)
                    {
                        throw new ArgumentException("Invalid Authentication option: '" + it.Value + "'. (None, Low, High, HighMd5, HighSha1, HighGMac, HighSha256)");
                    }
                    break;

                case 'C':
                    try
                    {
                        settings.client.Ciphering.Security = Convert.ToByte(Enum.Parse(typeof(Security), it.Value));
                    }
                    catch (Exception)
                    {
                        throw new ArgumentException("Invalid Ciphering option '" + it.Value + "'. (None, Authentication, Encryption, AuthenticationEncryption)");
                    }
                    break;

                case 'T':
                    settings.client.Ciphering.SystemTitle = GXCommon.HexToBytes(it.Value);
                    break;

                case 'A':
                    settings.client.Ciphering.AuthenticationKey = GXCommon.HexToBytes(it.Value);
                    break;

                case 'B':
                    settings.client.Ciphering.BlockCipherKey = GXCommon.HexToBytes(it.Value);
                    break;

                case 'D':
                    settings.client.Ciphering.DedicatedKey = GXCommon.HexToBytes(it.Value);
                    break;

                case 'F':
                    settings.client.Ciphering.InvocationCounter = UInt32.Parse(it.Value.Trim());
                    break;

                case 'K':
                    GXPkcs8 cert1 = GXPkcs8.Load(it.Value);
                    settings.client.Ciphering.SigningKeyPair = new KeyValuePair <GXPrivateKey, GXPublicKey>(cert1.PrivateKey, cert1.PublicKey);
                    Console.WriteLine("Client Private key: " + GXDLMSTranslator.ToHex(cert1.PrivateKey.RawValue));
                    Console.WriteLine("Client Public key: " + GXDLMSTranslator.ToHex(cert1.PublicKey.RawValue));
                    break;

                case 'k':
                    GXx509Certificate cert = GXx509Certificate.Load(it.Value);
                    if ((cert.KeyUsage & ASN.Enums.KeyUsage.DigitalSignature) == 0)
                    {
                        throw new Exception("This certificate is not used for digital signature.");
                    }
                    settings.client.Ciphering.PublicKeys.Add(new KeyValuePair <CertificateType, GXx509Certificate>(CertificateType.DigitalSignature, cert));
                    string[] sn = cert.Subject.Split('=');
                    if (sn.Length != 2)
                    {
                        throw new ArgumentOutOfRangeException("Invalid public key subject.");
                    }
                    settings.client.Ciphering.SystemTitle = GXDLMSTranslator.HexToBytes(sn[1]);
                    Console.WriteLine("Server Public key: " + GXDLMSTranslator.ToHex(cert.PublicKey.RawValue));
                    break;

                case 'o':
                    settings.outputFile = it.Value;
                    break;

                case 'd':
                    try
                    {
                        settings.client.Standard = (Standard)Enum.Parse(typeof(Standard), it.Value);
                        if (settings.client.Standard == Standard.Italy || settings.client.Standard == Standard.India || settings.client.Standard == Standard.SaudiArabia)
                        {
                            settings.client.UseUtc2NormalTime = true;
                        }
                    }
                    catch (Exception)
                    {
                        throw new ArgumentException("Invalid DLMS standard option '" + it.Value + "'. (DLMS, India, Italy, SaudiArabia, IDIS)");
                    }
                    break;

                case 'c':
                    settings.client.ClientAddress = int.Parse(it.Value);
                    break;

                case 's':
                    if (settings.client.ServerAddress != 1)
                    {
                        settings.client.ServerAddress = GXDLMSClient.GetServerAddress(settings.client.ServerAddress, int.Parse(it.Value));
                    }
                    else
                    {
                        settings.client.ServerAddress = int.Parse(it.Value);
                    }
                    break;

                case 'l':
                    settings.client.ServerAddress = GXDLMSClient.GetServerAddress(int.Parse(it.Value), settings.client.ServerAddress);
                    break;

                case 'n':
                    settings.client.ServerAddress = GXDLMSClient.GetServerAddress(int.Parse(it.Value));
                    break;

                case 'm':
                    settings.client.Plc.MacDestinationAddress = UInt16.Parse(it.Value);
                    break;

                case '?':
                    switch (it.Tag)
                    {
                    case 'c':
                        throw new ArgumentException("Missing mandatory client option.");

                    case 's':
                        throw new ArgumentException("Missing mandatory server option.");

                    case 'h':
                        throw new ArgumentException("Missing mandatory host name option.");

                    case 'p':
                        throw new ArgumentException("Missing mandatory port option.");

                    case 'r':
                        throw new ArgumentException("Missing mandatory reference option.");

                    case 'a':
                        throw new ArgumentException("Missing mandatory authentication option.");

                    case 'S':
                        throw new ArgumentException("Missing mandatory Serial port option.");

                    case 't':
                        throw new ArgumentException("Missing mandatory trace option.");

                    case 'g':
                        throw new ArgumentException("Missing mandatory OBIS code option.");

                    case 'C':
                        throw new ArgumentException("Missing mandatory Ciphering option.");

                    case 'v':
                        throw new ArgumentException("Missing mandatory invocation counter logical name option.");

                    case 'T':
                        throw new ArgumentException("Missing mandatory system title option.");

                    case 'A':
                        throw new ArgumentException("Missing mandatory authentication key option.");

                    case 'B':
                        throw new ArgumentException("Missing mandatory block cipher key option.");

                    case 'D':
                        throw new ArgumentException("Missing mandatory dedicated key option.");

                    case 'F':
                        throw new ArgumentException("Missing mandatory frame counter option.");

                    case 'd':
                        throw new ArgumentException("Missing mandatory DLMS standard option.");

                    case 'K':
                        throw new ArgumentException("Missing mandatory private key file option.");

                    case 'k':
                        throw new ArgumentException("Missing mandatory public key file option.");

                    case 'l':
                        throw new ArgumentException("Missing mandatory logical server address option.");

                    case 'm':
                        throw new ArgumentException("Missing mandatory MAC destination address option.");

                    default:
                        ShowHelp();
                        return(1);
                    }

                default:
                    ShowHelp();
                    return(1);
                }
            }
            if (settings.media == null)
            {
                ShowHelp();
                return(1);
            }
            return(0);
        }
        byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e)
        {
            if (e.Index == 1)
            {
                SecurityPolicy = (SecurityPolicy)e.Parameters;
            }
            else if (e.Index == 2)
            {
                try
                {
                    foreach (List <object> item in e.Parameters as List <object> )
                    {
                        GlobalKeyType type = (GlobalKeyType)Convert.ToInt32(item[0]);
                        byte[]        data = (byte[])item[1];
                        //if settings.Cipher is null non secure server is used.
                        //Keys are take in action after reply is generated.
                        switch (type)
                        {
                        case GlobalKeyType.UnicastEncryption:
                            GXDLMSSecureClient.Decrypt(settings.Kek, data);
                            break;

                        case GlobalKeyType.BroadcastEncryption:
                            //Invalid type
                            e.Error = ErrorCode.ReadWriteDenied;
                            break;

                        case GlobalKeyType.Authentication:
                            GXDLMSSecureClient.Decrypt(settings.Kek, data);
                            break;

                        case GlobalKeyType.Kek:
                            GXDLMSSecureClient.Decrypt(settings.Kek, data);
                            break;

                        default:
                            //Invalid type
                            e.Error = ErrorCode.ReadWriteDenied;
                            break;
                        }
                    }
                }
                catch (Exception)
                {
                    e.Error = ErrorCode.ReadWriteDenied;
                }
            }
            else if (e.Index == 3)
            {
                // key_agreement
                try
                {
                    List <Object> tmp   = (List <Object>)(e.Parameters as List <Object>)[0];
                    byte          keyId = (byte)tmp[0];
                    if (keyId != 0)
                    {
                        e.Error = ErrorCode.InconsistentClass;
                    }
                    else
                    {
                        byte[] data = (byte[])tmp[0];
                        // ephemeral public key
                        GXByteBuffer data2 = new GXByteBuffer(65);
                        data2.SetUInt8(keyId);
                        data2.Set(data, 0, 64);
                        GXByteBuffer sign = new GXByteBuffer();
                        sign.Set(data, 64, 64);
                        GXPublicKey pk      = null;
                        string      subject = SystemTitleToSubject(settings.SourceSystemTitle);
                        foreach (GXx509Certificate it in settings.Cipher.Certificates)
                        {
                            if ((it.KeyUsage & KeyUsage.DigitalSignature) != 0 && it.Subject == subject)
                            {
                                pk = it.PublicKey;
                                break;
                            }
                        }
                        if (pk == null) //TODO:|| !GXSecure.ValidateEphemeralPublicKeySignature(data2.Array(), sign.Array(), pk))
                        {
                            e.Error = ErrorCode.InconsistentClass;
                            settings.TargetEphemeralKey = null;
                        }
                        else
                        {
                            settings.TargetEphemeralKey = GXPublicKey.FromRawBytes(data2.SubArray(1, 64));
                            // Generate ephemeral keys.
                            KeyValuePair <GXPrivateKey, GXPublicKey> eKpS = settings.Cipher.EphemeralKeyPair;
                            if (eKpS.Key == null)
                            {
                                eKpS = GXEcdsa.GenerateKeyPair(GetEcc(SecuritySuite));
                                settings.Cipher.EphemeralKeyPair = eKpS;
                            }
                            // Generate shared secret.
                            return(null);
                        }
                    }
                }
                catch (Exception)
                {
                    e.Error = ErrorCode.InconsistentClass;
                }
            }
            else if (e.Index == 4)
            {
                // generate_key_pair
                CertificateType key = (CertificateType)(int)e.Parameters;
                KeyValuePair <GXPrivateKey, GXPublicKey> value = GXEcdsa.GenerateKeyPair(GetEcc(SecuritySuite));
                switch (key)
                {
                case CertificateType.DigitalSignature:
                    settings.Cipher.SigningKeyPair = value;
                    break;

                case CertificateType.KeyAgreement:
                    settings.Cipher.KeyAgreementKeyPair = value;
                    break;

                default:
                    e.Error = ErrorCode.InconsistentClass;
                    break;
                }
            }
            else if (e.Index == 5)
            {
                // generate_certificate_request
                CertificateType key = (CertificateType)(int)e.Parameters;
                try
                {
                    KeyValuePair <GXPrivateKey, GXPublicKey> kp = default(KeyValuePair <GXPrivateKey, GXPublicKey>);
                    switch (key)
                    {
                    case CertificateType.DigitalSignature:
                        kp = settings.Cipher.SigningKeyPair;
                        break;

                    case CertificateType.KeyAgreement:
                        kp = settings.Cipher.KeyAgreementKeyPair;
                        break;

                    default:
                        break;
                    }
                    if (kp.Key != null)
                    {
                        GXPkcs10 pkc10 = GXPkcs10.CreateCertificateSigningRequest(kp, SystemTitleToSubject(settings.Cipher.SystemTitle));
                        return(pkc10.Encoded);
                    }
                    else
                    {
                        e.Error = ErrorCode.ReadWriteDenied;
                    }
                }
                catch (Exception)
                {
                    e.Error = ErrorCode.ReadWriteDenied;
                }
            }
            else if (e.Index == 6)
            {
                // import_certificate
                GXx509Certificate cert = new GXx509Certificate((byte[])e.Parameters);
                if (cert.KeyUsage == 0)
                {
                    // At least one bit must be used.
                    e.Error = ErrorCode.InconsistentClass;
                }
                else
                {
                    settings.Cipher.Certificates.Add(cert);
                }
            }
            else if (e.Index == 7)
            {
                // export_certificate
                List <Object>     tmp  = (List <Object>)e.Parameters;
                short             type = (short)tmp[0];
                GXx509Certificate cert = null;
                lock (settings.Cipher.Certificates)
                {
                    if (type == 0)
                    {
                        tmp  = (List <Object>)tmp[1];
                        cert = FindCertificateByEntity(settings, (CertificateEntity)tmp[0], (CertificateType)tmp[1], (byte[])tmp[2]);
                    }
                    else if (type == 1)
                    {
                        tmp  = (List <Object>)tmp[1];
                        cert = FindCertificateBySerial(settings, (byte[])tmp[1], ASCIIEncoding.ASCII.GetString((byte[])tmp[2]));
                    }
                    if (cert == null)
                    {
                        e.Error = ErrorCode.InconsistentClass;
                    }
                    else
                    {
                        return(cert.Encoded);
                    }
                }
            }
            else if (e.Index == 8)
            {
                // remove_certificate
                List <Object>     tmp  = (List <Object>)((List <object>)e.Parameters)[0];
                short             type = (short)tmp[0];
                GXx509Certificate cert = null;
                lock (settings.Cipher.Certificates)
                {
                    if (type == 0)
                    {
                        cert = FindCertificateByEntity(settings, (CertificateEntity)tmp[1], (CertificateType)tmp[2], (byte[])tmp[3]);
                    }
                    else if (type == 1)
                    {
                        cert = FindCertificateBySerial(settings, (byte[])tmp[1], ASCIIEncoding.ASCII.GetString((byte[])tmp[2]));
                    }
                    if (cert == null)
                    {
                        e.Error = ErrorCode.InconsistentClass;
                    }
                    else
                    {
                        settings.Cipher.Certificates.Remove(cert);
                    }
                }
            }
            else
            {
                e.Error = ErrorCode.ReadWriteDenied;
            }
            //Return standard reply.
            return(null);
        }
 /// <summary>
 ///  Imports an X.509 v3 certificate of a public key.
 /// </summary>
 /// <param name="client">DLMS client that is used to generate action.</param>
 /// <param name="key">Public key.</param>
 /// <returns>Generated action.</returns>
 public byte[][] ImportCertificate(GXDLMSClient client, GXx509Certificate certificate)
 {
     return(ImportCertificate(client, certificate.Encoded));
 }