/// <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); } } } }
/// <summary> /// Create the private key from DER. /// </summary> /// <param name="key">DER Base64 coded string.</param> /// <returns></returns> public static GXPrivateKey FromDer(string der) { byte[] key = GXCommon.FromBase64(der); object[] tmp = (object[])GXAsn1Converter.FromByteArray(key); GXPrivateKey value = new GXPrivateKey(); //If private key is given if (key.Length == 32) { value.Scheme = Ecc.P256; value.RawValue = key; } else if (key.Length == 48) { value.Scheme = Ecc.P384; value.RawValue = key; } else if (key.Length == 65) { value.Scheme = Ecc.P256; value.RawValue = key; } else if (key.Length == 97) { value.Scheme = Ecc.P384; value.RawValue = key; } else { throw new ArgumentOutOfRangeException("Invalid key."); } return(value); }
private void UpdateSecuritySettings() { translator.SecuritySuite = Ciphering.SecuritySuite; translator.Security = Ciphering.Security; translator.SystemTitle = Ciphering.SystemTitle; translator.ServerSystemTitle = Ciphering.ServerSystemTitle; translator.BlockCipherKey = Ciphering.BlockCipherKey; translator.AuthenticationKey = Ciphering.AuthenticationKey; translator.InvocationCounter = Ciphering.InvocationCounter; translator.DedicatedKey = Ciphering.DedicatedKey; translator.Keys.Clear(); translator.Keys.AddRange(Ciphering.KeyPairs); if (!string.IsNullOrEmpty(Ciphering.ClientSigningKey)) { KeyValuePair <GXPkcs8, GXx509Certificate> it = FindKey(Ciphering.ClientSigningKey); GXPrivateKey pk = null; if (it.Key != null) { pk = it.Key.PrivateKey; pk.SystemTitle = it.Value != null?GXAsn1Converter.SystemTitleFromSubject(it.Value.Subject) : null; } translator.SigningKeyPair = new KeyValuePair <GXPublicKey, GXPrivateKey>(translator.SigningKeyPair.Key, pk); } if (!string.IsNullOrEmpty(Ciphering.ServerSigningKey)) { KeyValuePair <GXPkcs8, GXx509Certificate> it = FindKey(Ciphering.ServerSigningKey); GXPublicKey pub = null; if (it.Value != null) { pub = it.Value.PublicKey; pub.SystemTitle = it.Value != null?GXAsn1Converter.SystemTitleFromSubject(it.Value.Subject) : null; } translator.SigningKeyPair = new KeyValuePair <GXPublicKey, GXPrivateKey>(pub, translator.SigningKeyPair.Value); } }
public List <KeyValuePair <GXPkcs8, GXx509Certificate> > GetClientKeys(string systemTitle) { byte[] st = null; if (!string.IsNullOrEmpty(systemTitle)) { st = GXDLMSTranslator.HexToBytes(systemTitle); } List <KeyValuePair <GXPkcs8, GXx509Certificate> > list = new List <KeyValuePair <GXPkcs8, GXx509Certificate> >(); if (st == null || st.Length == 8) { string subject = null; if (st != null) { subject = GXAsn1Converter.SystemTitleToSubject(st); } GXPkcs8 k; foreach (GXx509Certificate cert in _certifications) { if (subject == null || cert.Subject.Contains(subject)) { if ((k = _privateKeys.Find(cert.PublicKey)) != null) { if ((cert.KeyUsage & KeyUsage.DigitalSignature) != 0) { list.Add(new KeyValuePair <GXPkcs8, GXx509Certificate>(k, cert)); } } } } } return(list); }
/// <summary> /// Get Ephemeral Public Key Signature. /// </summary> /// <param name="keyId">Key ID.</param> /// <param name="ephemeralKey">Ephemeral key.</param> /// <returns>Ephemeral Public Key Signature.</returns> public static byte[] GetEphemeralPublicKeyData(int keyId, GXPublicKey ephemeralKey) { GXAsn1BitString tmp = (GXAsn1BitString)((GXAsn1Sequence)GXAsn1Converter.FromByteArray(ephemeralKey.ToEncoded()))[1]; // Ephemeral public key client GXByteBuffer epk = new GXByteBuffer(tmp.Value); // First byte is 4 and that is not used. We can override it. epk.Data[0] = (byte)keyId; return(epk.Array()); }
/// <summary> /// Find certificate with given parameters. /// </summary> /// <param name="entity">Certificate entity.</param> /// <param name="type">Certificate type.</param> /// <param name="systemtitle">System title.</param> /// <returns></returns> public GXDLMSCertificateInfo Find(CertificateEntity entity, CertificateType type, byte[] systemtitle) { string subject = GXAsn1Converter.SystemTitleToSubject(systemtitle); foreach (GXDLMSCertificateInfo it in this) { if ((it.Entity == CertificateEntity.Server && entity == CertificateEntity.Server) || (it.Entity == CertificateEntity.Client && entity == CertificateEntity.Client) && it.Subject == subject) { return(it); } } return(null); }
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); }
/// <summary> /// Create the private key from DER. /// </summary> /// <param name="key">DER Base64 coded string.</param> /// <returns></returns> public static GXPrivateKey FromDer(string der) { der = der.Replace("\r\n", ""); der = der.Replace("\n", ""); byte[] key = GXCommon.FromBase64(der); GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(key); if ((sbyte)seq[0] > 3) { throw new ArgumentOutOfRangeException("Invalid private key version."); } List <object> tmp = (List <object>)seq[2]; GXPrivateKey value = new GXPrivateKey(); X9ObjectIdentifier id = X9ObjectIdentifierConverter.FromString(tmp[0].ToString()); switch (id) { case X9ObjectIdentifier.Prime256v1: value.Scheme = Ecc.P256; break; case X9ObjectIdentifier.Secp384r1: value.Scheme = Ecc.P384; break; default: if (id == X9ObjectIdentifier.None) { throw new ArgumentOutOfRangeException("Invalid private key " + tmp[0].ToString() + "."); } else { throw new ArgumentOutOfRangeException("Invalid private key " + id + " " + tmp[0].ToString() + "."); } } value.RawValue = (byte[])seq[1]; if (seq[3] is byte[]) { value.publicKey = GXPublicKey.FromRawBytes((byte[])seq[3]); } else { //Open SSL PEM. value.publicKey = GXPublicKey.FromRawBytes(((GXAsn1BitString)((List <object>)seq[3])[0]).Value); } return(value); }
/// <summary> /// Generate Certificate Signing Request (CSR) from private key. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CSRBtn_Click(object sender, EventArgs e) { try { if (SystemTitleTb.Text == "") { throw new Exception("Invalid system title."); } byte[] st = GXDLMSTranslator.HexToBytes(SystemTitleTb.Text); if (st.Length != 8) { throw new Exception("Invalid system title."); } 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.PemFilterTxt; dlg.DefaultExt = ".pem"; dlg.ValidateNames = true; if (dlg.ShowDialog(Parent) == DialogResult.OK) { string path = dlg.FileName; GXPkcs8 pk = GXPkcs8.Load(path); KeyValuePair <GXPublicKey, GXPrivateKey> kp = new KeyValuePair <GXPublicKey, GXPrivateKey>(pk.PublicKey, pk.PrivateKey); //Generate certificate request and ask new x509Certificate. GXPkcs10 pkc10 = GXPkcs10.CreateCertificateSigningRequest(kp, GXAsn1Converter.SystemTitleToSubject(st)); Pkcs10Tb.Text = pkc10.ToPem(); Pkcs10Tb.AppendText(Environment.NewLine); Pkcs10Tb.AppendText(pkc10.ToString()); } } catch (Exception ex) { MessageBox.Show(Parent, ex.Message); } }
/// <summary> /// Validate ephemeral public key signature. /// </summary> /// <param name="data">Data to validate.</param> /// <param name="sign">Sign</param> /// <param name="publicSigningKey">Public Signing key from other party.</param> /// <returns>Is verify succeeded.</returns> public static bool ValidateEphemeralPublicKeySignature( byte[] data, byte[] sign, GXPublicKey publicSigningKey) { GXAsn1Integer a = new GXAsn1Integer(sign, 0, 32); GXAsn1Integer b = new GXAsn1Integer(sign, 32, 32); GXAsn1Sequence s = new GXAsn1Sequence(); s.Add(a); s.Add(b); byte[] tmp = GXAsn1Converter.ToByteArray(s); GXEcdsa c = new GXEcdsa(publicSigningKey); bool ret = c.Verify(sign, data); if (!ret) { System.Diagnostics.Debug.WriteLine("Data:" + GXCommon.ToHex(data, true)); System.Diagnostics.Debug.WriteLine("Sign:" + GXCommon.ToHex(sign, true)); } return(ret); }
/// <summary> /// Get public key as encoded format. /// </summary> /// <returns></returns> public byte[] ToEncoded() { //Subject Public Key Info. GXAsn1Sequence d = new GXAsn1Sequence(); GXAsn1Sequence d1 = new GXAsn1Sequence(); d1.Add(new GXAsn1ObjectIdentifier("1.2.840.10045.2.1")); if (Scheme == Ecc.P256) { d1.Add(new GXAsn1ObjectIdentifier("1.2.840.10045.3.1.7")); } else if (Scheme == Ecc.P384) { d1.Add(new GXAsn1ObjectIdentifier("1.3.132.0.34")); } else { throw new Exception("Invalid ECC scheme."); } d.Add(d1); d.Add(new GXAsn1BitString(RawValue, 0)); return(GXAsn1Converter.ToByteArray(d)); }
public string ToDer() { GXAsn1Sequence d = new GXAsn1Sequence(); d.Add((sbyte)CertificateVersion.Version2); d.Add(RawValue); GXAsn1Sequence d1 = new GXAsn1Sequence(); if (Scheme == Ecc.P256) { d1.Add(new GXAsn1ObjectIdentifier("1.2.840.10045.3.1.7")); } else if (Scheme == Ecc.P384) { d1.Add(new GXAsn1ObjectIdentifier("1.3.132.0.34")); } else { throw new Exception("Invalid ECC scheme."); } d.Add(d1); d.Add(new GXAsn1BitString(GetPublicKey().RawValue)); return(GXCommon.ToBase64(GXAsn1Converter.ToByteArray(d))); }
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> /// Get certificate for the private key. /// </summary> private void GetCertificateMnu_Click(object sender, EventArgs e) { try { ListViewItem it = KeyList.SelectedItems[0]; GXCertificateSigningRequestDlg dlg = new GXCertificateSigningRequestDlg(SystemTitle); if (dlg.ShowDialog(Parent) == DialogResult.OK) { SystemTitle = dlg.SystemTitle; GXPkcs8 pk = GXPkcs8.Load((string)it.Tag); KeyValuePair <GXPublicKey, GXPrivateKey> kp = new KeyValuePair <GXPublicKey, GXPrivateKey>(pk.PublicKey, pk.PrivateKey); List <GXCertificateRequest> certifications = new List <GXCertificateRequest>(); GXCertificateRequest it2 = new GXCertificateRequest(); it2.CertificateType = dlg.CertificateType; it2.ExtendedKeyUsage = dlg.ExtendedKeyUsage; //Generate certificate request and ask new x509Certificate. it2.Certificate = GXPkcs10.CreateCertificateSigningRequest(kp, GXAsn1Converter.SystemTitleToSubject(SystemTitle)); certifications.Add(it2); //Note! There is a limit how many request you can do in a day. GXx509Certificate[] certificates = GXPkcs10.GetCertificate(_address, certifications); foreach (GXx509Certificate cert in certificates) { if (cert.KeyUsage == KeyUsage.DigitalSignature) { _path = "D" + Path.GetFileName((string)it.Tag); } else if (cert.KeyUsage == KeyUsage.KeyAgreement) { _path = "A" + Path.GetFileName((string)it.Tag); } else if (cert.KeyUsage == (KeyUsage.KeyAgreement | KeyUsage.DigitalSignature)) { //TLS. _path = "T" + Path.GetFileName((string)it.Tag); } else { //Other. _path = "O" + Path.GetFileName((string)it.Tag); } if (File.Exists(_path)) { 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)) { //TLS. _path = "T" + GXDLMSTranslator.ToHex(SystemTitle, false); } else { //Other. _path = "O" + GXDLMSTranslator.ToHex(SystemTitle, false); } _path += ".pem"; } _path = Path.Combine(_certificateFolder, _path); cert.Save(_path); } _updater.UpdateUI(); } } catch (Exception ex) { MessageBox.Show(Parent, ex.Message); } }
/// <summary> /// Decrypt data. /// </summary> /// <param name="p">Decryption parameters</param> /// <returns>Decrypted data.</returns> public static byte[] DecryptAesGcm(AesGcmParameter p, GXByteBuffer data) { if (data == null || data.Size < 2) { throw new ArgumentOutOfRangeException("cryptedData"); } byte[] tmp; int len; Command cmd = (Command)data.GetUInt8(); switch (cmd) { case Command.GeneralGloCiphering: case Command.GeneralDedCiphering: len = GXCommon.GetObjectCount(data); if (len != 0) { p.SystemTitle = new byte[len]; data.Get(p.SystemTitle); if (p.Xml != null && p.Xml.Comments) { p.Xml.AppendComment(GXCommon.SystemTitleToString(Standard.DLMS, p.SystemTitle, true)); } } if (p.SystemTitle == null || p.SystemTitle.Length != 8) { if (p.Xml == null) { throw new ArgumentNullException("Invalid sender system title."); } else { p.Xml.AppendComment("Invalid sender system title."); } } break; case Command.GeneralCiphering: case Command.GloInitiateRequest: case Command.GloInitiateResponse: case Command.GloReadRequest: case Command.GloReadResponse: case Command.GloWriteRequest: case Command.GloWriteResponse: case Command.GloGetRequest: case Command.GloGetResponse: case Command.GloSetRequest: case Command.GloSetResponse: case Command.GloMethodRequest: case Command.GloMethodResponse: case Command.GloEventNotification: case Command.DedInitiateRequest: case Command.DedInitiateResponse: case Command.DedGetRequest: case Command.DedGetResponse: case Command.DedSetRequest: case Command.DedSetResponse: case Command.DedMethodRequest: case Command.DedMethodResponse: case Command.DedEventNotification: case Command.DedReadRequest: case Command.DedReadResponse: case Command.DedWriteRequest: case Command.DedWriteResponse: case Command.GloConfirmedServiceError: case Command.DedConfirmedServiceError: break; default: throw new ArgumentOutOfRangeException("cryptedData"); } int value = 0; GXPrivateKey key = null; GXPublicKey pub = null; GXByteBuffer transactionId = null; if (cmd == Command.GeneralCiphering) { transactionId = new GXByteBuffer(); len = GXCommon.GetObjectCount(data); GXCommon.SetObjectCount(len, transactionId); transactionId.Set(data, len); p.TransactionId = transactionId.GetUInt64(1); len = GXCommon.GetObjectCount(data); if (len != 0) { tmp = new byte[len]; data.Get(tmp); p.SystemTitle = tmp; } if (p.SystemTitle == null || p.SystemTitle.Length != 8) { if (p.Xml == null) { throw new ArgumentNullException("Invalid sender system title."); } else { p.Xml.AppendComment("Invalid sender system title."); } } len = GXCommon.GetObjectCount(data); tmp = new byte[len]; data.Get(tmp); p.RecipientSystemTitle = tmp; // Get date time. len = GXCommon.GetObjectCount(data); if (len != 0) { tmp = new byte[len]; data.Get(tmp); p.DateTime = tmp; } // other-information len = data.GetUInt8(); if (len != 0) { tmp = new byte[len]; data.Get(tmp); p.OtherInformation = tmp; } // KeyInfo OPTIONAL len = data.GetUInt8(); // AgreedKey CHOICE tag. data.GetUInt8(); // key-parameters len = data.GetUInt8(); value = data.GetUInt8(); p.KeyParameters = value; if (value == (int)KeyAgreementScheme.OnePassDiffieHellman) { // key-ciphered-data len = GXCommon.GetObjectCount(data); GXByteBuffer bb = new GXByteBuffer(); bb.Set(data, len); if (p.Xml != null) { p.KeyCipheredData = bb.Array(); //Find key agreement key using subject. string subject = GXAsn1Converter.SystemTitleToSubject(p.SystemTitle); foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys) { if (it.Key != null && it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject)) { key = it.Key.PrivateKey; //Get recipient Ephemeral public key. subject = GXAsn1Converter.SystemTitleToSubject(p.RecipientSystemTitle); foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it2 in p.Settings.Keys) { if (it2.Value != null && it2.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it2.Value.Subject.Contains(subject)) { pub = it2.Value.PublicKey; break; } } break; } } if (key == null) { //Find key agreement key using subject. subject = GXAsn1Converter.SystemTitleToSubject(p.RecipientSystemTitle); foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys) { if (it.Key != null && it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject)) { key = it.Key.PrivateKey; break; } } } } else { key = p.Settings.Cipher.KeyAgreementKeyPair.Key; } if (key != null && pub == null) { //Get Ephemeral public key. int keySize = len / 2; pub = GXPublicKey.FromRawBytes(bb.SubArray(0, keySize)); } } else if (value == (int)KeyAgreementScheme.StaticUnifiedModel) { len = GXCommon.GetObjectCount(data); if (len != 0) { throw new ArgumentException("Invalid key parameters"); } if (p.Xml != null) { //Find key agreement key using subject. string subject = GXAsn1Converter.SystemTitleToSubject(p.RecipientSystemTitle); foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys) { if (it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject)) { key = it.Key.PrivateKey; break; } } if (key != null) { //Find key agreement key using subject. subject = GXAsn1Converter.SystemTitleToSubject(p.Settings.SourceSystemTitle); foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys) { if (it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject)) { pub = it.Value.PublicKey; break; } } } } else { key = p.Settings.Cipher.KeyAgreementKeyPair.Key; pub = p.Settings.Cipher.KeyAgreementKeyPair.Value; } } else { throw new ArgumentException("key-parameters"); } } len = GXCommon.GetObjectCount(data); if (len > data.Available) { throw new Exception("Not enought data."); } p.CipheredContent = data.Remaining(); byte sc = data.GetUInt8(); p.SecuritySuite = (SecuritySuite)(sc & 0x3); p.Security = (Security)(sc & 0x30); if ((sc & 0x80) != 0) { System.Diagnostics.Debug.WriteLine("Compression is used."); } if ((sc & 0x40) != 0) { System.Diagnostics.Debug.WriteLine("Error: Key_Set is used."); } if ((sc & 0x20) != 0) { System.Diagnostics.Debug.WriteLine("Encryption is applied."); } if (key != null) { if (value == (int)KeyAgreementScheme.OnePassDiffieHellman) { GXEcdsa c = new GXEcdsa(key); //Get Ephemeral signing key and verify it. byte[] z = c.GenerateSecret(pub); System.Diagnostics.Debug.WriteLine("Originator ephemeral public key: " + pub.ToHex()); System.Diagnostics.Debug.WriteLine("Recipient private agreement key: " + key.ToHex()); System.Diagnostics.Debug.WriteLine("Shared secret:" + GXCommon.ToHex(z, true)); GXByteBuffer kdf = new GXByteBuffer(); kdf.Set(GXSecure.GenerateKDF(p.SecuritySuite, z, p.SecuritySuite == SecuritySuite.Ecdsa256 ? AlgorithmId.AesGcm128 : AlgorithmId.AesGcm256, p.SystemTitle, p.RecipientSystemTitle, null, null)); System.Diagnostics.Debug.WriteLine("KDF:" + kdf.ToString()); p.BlockCipherKey = kdf.SubArray(0, 16); } else if (value == (int)KeyAgreementScheme.StaticUnifiedModel) { GXEcdsa c = new GXEcdsa(key); byte[] z = c.GenerateSecret(pub); System.Diagnostics.Debug.WriteLine("Shared secret:" + GXCommon.ToHex(z, true)); GXByteBuffer kdf = new GXByteBuffer(); kdf.Set(GXSecure.GenerateKDF(p.SecuritySuite, z, p.SecuritySuite == SecuritySuite.Ecdsa256 ? AlgorithmId.AesGcm128 : AlgorithmId.AesGcm256, p.SystemTitle, transactionId.Array(), p.RecipientSystemTitle, null)); System.Diagnostics.Debug.WriteLine("KDF:" + kdf.ToString()); p.BlockCipherKey = kdf.SubArray(0, 16); } else { throw new ArgumentOutOfRangeException("Invalid Key-id value."); } } UInt32 invocationCounter = data.GetUInt32(); p.InvocationCounter = invocationCounter; System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString()); System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Data, false, data.Position, data.Size - data.Position)); byte[] tag = new byte[12]; byte[] encryptedData; int length; if (p.Security == Security.Authentication) { length = data.Size - data.Position - 12; encryptedData = new byte[length]; data.Get(encryptedData); data.Get(tag); // Check tag. EncryptAesGcm(p, encryptedData); if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag)) { if (p.Xml == null) { throw new GXDLMSException("Decrypt failed. Invalid tag."); } else { p.Xml.AppendComment("Decrypt failed. Invalid tag."); } } return(encryptedData); } byte[] ciphertext = null; if (p.Security == Security.Encryption) { length = data.Size - data.Position; ciphertext = new byte[length]; data.Get(ciphertext); } else if (p.Security == Security.AuthenticationEncryption) { length = data.Size - data.Position - 12; ciphertext = new byte[length]; data.Get(ciphertext); data.Get(tag); } byte[] aad = GetAuthenticatedData(p, ciphertext), iv = GetNonse(invocationCounter, p.SystemTitle); GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(p.Security, true, p.BlockCipherKey, aad, iv, tag); gcm.Write(ciphertext); byte[] decrypted = gcm.FlushFinalBlock(); System.Diagnostics.Debug.WriteLine("Decrypted: " + GXCommon.ToHex(decrypted, true)); if (p.Security != Security.Encryption) { if (!GXCommon.Compare(gcm.GetTag(), tag)) { if (p.Xml == null) { throw new Exception("Decrypt failed. Invalid authentication tag."); } p.Xml.AppendComment("Decrypt failed. Invalid authentication tag."); } } return(decrypted); }
/// <summary> /// Update private and public keys to the translator. /// </summary> private void GetKeys() { if (updateUI) { if (ClientSigningKeysCb.SelectedItem is KeyValuePair <GXPkcs8, GXx509Certificate> cs) { ClientSigningKey = cs.Key.ToDer(); } else { ClientSigningKey = null; } if (ClientAgreementKeysCb.SelectedItem is KeyValuePair <GXPkcs8, GXx509Certificate> ca) { ClientAgreementKey = ca.Key.ToDer(); } else { ClientAgreementKey = null; } if (ServerSigningKeysCb.SelectedItem is KeyValuePair <GXPkcs8, GXx509Certificate> ss) { ServerSigningKey = ss.Value.ToDer(); } else { ServerSigningKey = null; } if (ServerAgreementKeysCb.SelectedItem is KeyValuePair <GXPkcs8, GXx509Certificate> sa) { ServerAgreementKey = sa.Value.ToDer(); } else { ServerAgreementKey = null; } bool check = _checkSystemTitle; if (check) { string st; if (SystemTitleAsciiCb.Checked) { st = GXDLMSTranslator.ToHex(ASCIIEncoding.ASCII.GetBytes(SystemTitleTb.Text), false); } else { st = SystemTitleTb.Text.Replace(" ", ""); } if (check && (ClientSigningKeysCb.SelectedItem is KeyValuePair <GXPkcs8, GXx509Certificate> cv) && cv.Value != null) { string certificateSt = GXDLMSTranslator.ToHex(GXAsn1Converter.SystemTitleFromSubject(cv.Value.Subject), false); if (st != certificateSt) { if (MessageBox.Show(Parent, string.Format("System title '{0}' of the client is different than in the certificate '{1}'. Do you want to update the system title from the certificate?", SystemTitleTb.Text, certificateSt), "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes) { SystemTitleAsciiCb.Checked = false; SystemTitleTb.Text = certificateSt; check = false; } } } if (check && (ClientAgreementKeysCb.SelectedItem is KeyValuePair <GXPkcs8, GXx509Certificate> ck) && ck.Value != null) { string certificateSt = GXDLMSTranslator.ToHex(GXAsn1Converter.SystemTitleFromSubject(ck.Value.Subject), false); if (st != certificateSt) { if (MessageBox.Show(Parent, string.Format("System title '{0}' of the client is different than in the certificate '{1}'. Do you want to update the system title from the certificate?", SystemTitleTb.Text, certificateSt), "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes) { SystemTitleAsciiCb.Checked = false; SystemTitleTb.Text = certificateSt; check = false; } } } if (check && ServerSigningKeysCb.SelectedItem is KeyValuePair <GXPkcs8, GXx509Certificate> sv) { string certificateSt = GXDLMSTranslator.ToHex(GXAsn1Converter.SystemTitleFromSubject(sv.Value.Subject), false); if (ServerSystemTitleTb.Text.Replace(" ", "") != certificateSt) { if (MessageBox.Show(Parent, string.Format("System title '{0}' of the server is different than in the certificate '{1}'. Do you want to update the system title from the certificate?", ServerSystemTitleTb.Text, certificateSt), "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes) { ServerSystemTitleTb.Text = certificateSt; check = false; } } } if (check && ServerAgreementKeysCb.SelectedItem is KeyValuePair <GXPkcs8, GXx509Certificate> sk) { string certificateSt = GXDLMSTranslator.ToHex(GXAsn1Converter.SystemTitleFromSubject(sk.Value.Subject), false); if (ServerSystemTitleTb.Text.Replace(" ", "") != certificateSt) { if (MessageBox.Show(Parent, string.Format("System title '{0}' of the server is different than in the certificate '{1}'. Do you want to update the system title from the certificate?", ServerSystemTitleTb.Text, certificateSt), "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes) { ServerSystemTitleTb.Text = certificateSt; check = false; } } } } } }