/// <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> /// Constructor. /// </summary> /// <param name="tag">Tag.</param> /// <param name="settings">DLMS settings.</param> /// <param name="security">Security level.</param> /// <param name="securitySuite">Security suite.</param> /// <param name="invocationCounter">Invocation counter.</param> /// <param name="kdf">KDF.</param> /// <param name="authenticationKey">Authentication key.</param> /// <param name="originatorSystemTitle">Originator system title.</param> /// <param name="recipientSystemTitle">Recipient system title.</param> /// <param name="dateTime"> Date and time.</param> /// <param name="otherInformation">Other information.</param> public AesGcmParameter(byte tag, GXDLMSSettings settings, Security security, SecuritySuite securitySuite, UInt64 invocationCounter, byte[] kdf, byte[] authenticationKey, byte[] originatorSystemTitle, byte[] recipientSystemTitle, byte[] dateTime, byte[] otherInformation) { Tag = tag; Settings = settings; Security = security; InvocationCounter = invocationCounter; SecuritySuite = securitySuite; BlockCipherKey = kdf; AuthenticationKey = authenticationKey; SystemTitle = originatorSystemTitle; RecipientSystemTitle = recipientSystemTitle; Type = CountType.Packet; DateTime = dateTime; OtherInformation = otherInformation; }
private static Ecc GetEcc(SecuritySuite suite) { if (suite == SecuritySuite.Ecdsa256) { return(Ecc.P256); } return(Ecc.P384); }
private static Ecc GetEcc(SecuritySuite suite) { if (suite == SecuritySuite.Version1) { return(Ecc.P256); } return(Ecc.P384); }
/// <summary> /// Constructor. /// </summary> /// <param name="systemTitle"></param> /// <param name="blockCipherKey"></param> /// <param name="authenticationKey"></param> public AesGcmParameter( byte[] systemTitle, byte[] blockCipherKey, byte[] authenticationKey) { SystemTitle = systemTitle; BlockCipherKey = blockCipherKey; AuthenticationKey = authenticationKey; Type = CountType.Packet; SecuritySuite = SecuritySuite.AesGcm128; }
/// <summary> /// Constructor. /// </summary> /// <param name="tag">Command.</param> /// <param name="security"></param> /// <param name="invocationCounter">Invocation counter.</param> /// <param name="systemTitle"></param> /// <param name="blockCipherKey"></param> /// <param name="authenticationKey"></param> public AesGcmParameter( byte tag, Gurux.DLMS.Enums.Security security, UInt32 invocationCounter, byte[] systemTitle, byte[] blockCipherKey, byte[] authenticationKey) { Tag = tag; Security = security; InvocationCounter = invocationCounter; SystemTitle = systemTitle; BlockCipherKey = blockCipherKey; AuthenticationKey = authenticationKey; Type = CountType.Packet; SecuritySuite = SecuritySuite.AesGcm128; }
/// <summary> /// Constructor. /// </summary> /// <param name="address">Gurux certificate generator address.</param> /// <param name="privateKeysFolder">Private keys folder.</param> /// <param name="certificatesFolder">Certificates folder.</param> /// <param name="title">Dialog title.</param> /// <param name="securitySuite">Security Suite level.</param> /// <param name="systemTitle">System title.</param> public GXEcdsaKeysDlg(string address, string privateKeysFolder, string certificatesFolder, string title, SecuritySuite securitySuite, byte[] systemTitle) { InitializeComponent(); _address = address; if (systemTitle != null && systemTitle.Length != 8) { throw new ArgumentOutOfRangeException("Invalid system title."); } _systemTitle = systemTitle; if (!Directory.Exists(certificatesFolder)) { Directory.CreateDirectory(certificatesFolder); } if (!Directory.Exists(privateKeysFolder)) { Directory.CreateDirectory(privateKeysFolder); } cf = new GXCertificateForm(this, _address, certificatesFolder, title, _systemTitle); // Certificate is not generated if the certificate is found for the given system title. if (_systemTitle != null && cf.Certificates.FindBySystemTitle(_systemTitle, KeyUsage.None) != null) { _systemTitle = null; } kf = new GXKeyForm(this, _address, privateKeysFolder, certificatesFolder, title, securitySuite, _systemTitle); while (kf.Controls.Count != 0) { Control ctr = kf.Controls[0]; KeysView.Controls.Add(ctr); ctr.Visible = true; } if (_systemTitle != null) { cf.RefreshCertificates(); } while (cf.Controls.Count != 0) { Control ctr = cf.Controls[0]; CertificatesView.Controls.Add(ctr); ctr.Visible = true; } }
/// <summary> /// Generate KDF. /// </summary> /// <param name="securitySuite">Used security suite.</param> /// <param name="z">Shared Secret.</param> /// <param name="algorithmID">Algorithm ID.</param> /// <param name="partyUInfo">Sender system title.</param> /// <param name="partyVInfo">Receiver system title.</param> /// <param name="suppPubInfo">Not used in DLMS.</param> /// <param name="suppPrivInfo">Not used in DLMS.</param> /// <returns></returns> public static byte[] GenerateKDF(SecuritySuite securitySuite, byte[] z, AlgorithmId algorithmID, byte[] partyUInfo, byte[] partyVInfo, byte[] suppPubInfo, byte[] suppPrivInfo) { GXByteBuffer bb = new GXByteBuffer(); bb.Set(new byte[] { 0x60, 0x85, 0x74, 0x05, 0x08, 0x03, (byte)algorithmID }); bb.Set(partyUInfo); bb.Set(partyVInfo); if (suppPubInfo != null) { bb.Set(suppPubInfo); } if (suppPrivInfo != null) { bb.Set(suppPrivInfo); } return(GenerateKDF(securitySuite, z, bb.Array())); }
/// <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()); }
/// <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; */ }
public GXKeyForm(IGXUpdater updater, string address, string keyFolder, string certificateFolder, string title, SecuritySuite securitySuite, byte[] systemTitle) { InitializeComponent(); _updater = updater; _address = address; _certificateFolder = certificateFolder; _systemTitle = systemTitle; privateKeys = new GXPkcs8Collection(); KeyFolder = keyFolder; Title = title; foreach (string p in Directory.GetFiles(keyFolder)) { string ext = Path.GetExtension(p); if (string.Compare(ext, ".pem", true) == 0 || string.Compare(ext, ".cer", true) == 0) { try { GXPkcs8 cert = GXPkcs8.Load(p); AddKey(cert, p); } catch (Exception) { Debug.WriteLine("Failed to open " + p); } } } if (_systemTitle != null) { string path = Path.Combine(KeyFolder, "D" + GXDLMSTranslator.ToHex(_systemTitle, false)) + ".pem"; //Generate private key for digital signature. GXPkcs8 digitalSignature = new GXPkcs8(GXEcdsa.GenerateKeyPair(securitySuite == SecuritySuite.Suite1 ? Ecc.P256 : Ecc.P384)); digitalSignature.Save(path); AddKey(digitalSignature, path); path = Path.Combine(KeyFolder, "A" + GXDLMSTranslator.ToHex(_systemTitle, false)) + ".pem"; //Generate private key for Key agreement. GXPkcs8 keyAgreement = new GXPkcs8(GXEcdsa.GenerateKeyPair(Ecc.P256)); keyAgreement.Save(path); AddKey(keyAgreement, path); //Get CRS. KeyValuePair <GXPublicKey, GXPrivateKey> kp = new KeyValuePair <GXPublicKey, GXPrivateKey>(digitalSignature.PublicKey, digitalSignature.PrivateKey); //Generate certificate request and ask new x509Certificate. //Note! There is a limit how many request you can do in a day. List <GXCertificateRequest> certifications = new List <GXCertificateRequest>(); GXCertificateRequest it = new GXCertificateRequest(); it.Certificate = GXPkcs10.CreateCertificateSigningRequest(kp, GXAsn1Converter.SystemTitleToSubject(_systemTitle)); it.CertificateType = CertificateType.DigitalSignature; certifications.Add(it); it = new GXCertificateRequest(); it.Certificate = GXPkcs10.CreateCertificateSigningRequest(kp, GXAsn1Converter.SystemTitleToSubject(_systemTitle)); it.CertificateType = CertificateType.KeyAgreement; certifications.Add(it); GXx509Certificate[] certificates = GXPkcs10.GetCertificate(address, certifications); foreach (GXx509Certificate cert in certificates) { if (cert.KeyUsage == KeyUsage.DigitalSignature) { path = "D" + GXDLMSTranslator.ToHex(_systemTitle, false); } else if (cert.KeyUsage == KeyUsage.KeyAgreement) { path = "A" + GXDLMSTranslator.ToHex(_systemTitle, false); } else if (cert.KeyUsage == (KeyUsage.KeyAgreement | KeyUsage.DigitalSignature)) { path = "T" + GXDLMSTranslator.ToHex(_systemTitle, false); } else { path = "O" + GXDLMSTranslator.ToHex(_systemTitle, false); } path = Path.Combine(_certificateFolder, path) + ".pem"; cert.Save(path); } } }
/// <summary> /// Update certificates with server and client system title. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UpdateBtn_Click(object sender, EventArgs e) { try { _checkSystemTitle = false; SecuritySuite ss = (SecuritySuite)SecuritySuiteCb.SelectedItem; Ecc scheme = ss == SecuritySuite.Suite1 ? Ecc.P256 : Ecc.P384; byte[] tmp = GXDLMSTranslator.HexToBytes(SystemTitle); if (tmp.Length != 0 && tmp.Length != 8) { throw new Exception("Client system title is invalid."); } string clientST = null; if (tmp.Length != 0) { clientST = "CN=" + GXDLMSTranslator.ToHex(tmp, false); } tmp = GXDLMSTranslator.HexToBytes(ServerSystemTitle); if (tmp.Length != 0 && tmp.Length != 8) { throw new Exception("Server system title is invalid."); } string serverST = null; if (tmp.Length != 0) { serverST = "CN=" + GXDLMSTranslator.ToHex(tmp, false); } ClientAgreementKeysCb.SelectedItem = null; ServerAgreementKeysCb.SelectedItem = null; ClientSigningKeysCb.SelectedItem = null; ServerSigningKeysCb.SelectedItem = null; if (clientST != null) { foreach (object tmp2 in ClientAgreementKeysCb.Items) { if (tmp2 is KeyValuePair <GXPkcs8, GXx509Certificate> it) { if (it.Value != null && it.Value.PublicKey.Scheme == scheme && it.Value.Subject.Contains(clientST)) { ClientAgreementKeysCb.SelectedItem = it; break; } } } foreach (object tmp2 in ClientSigningKeysCb.Items) { if (tmp2 is KeyValuePair <GXPkcs8, GXx509Certificate> it) { if (it.Value != null && it.Value.PublicKey.Scheme == scheme && it.Value.Subject.Contains(clientST)) { ClientSigningKeysCb.SelectedItem = it; break; } } } } if (serverST != null) { foreach (object tmp2 in ServerAgreementKeysCb.Items) { if (tmp2 is KeyValuePair <GXPkcs8, GXx509Certificate> it) { if (it.Value != null && it.Value.PublicKey.Scheme == scheme && it.Value.Subject.Contains(serverST)) { ServerAgreementKeysCb.SelectedItem = it; break; } } } foreach (object tmp2 in ServerSigningKeysCb.Items) { if (tmp2 is KeyValuePair <GXPkcs8, GXx509Certificate> it) { if (it.Value != null && it.Value.PublicKey.Scheme == scheme && it.Value.Subject.Contains(serverST)) { ServerSigningKeysCb.SelectedItem = it; break; } } } } } catch (Exception ex) { MessageBox.Show(Parent, ex.Message); } finally { _checkSystemTitle = true; } }