byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (Version == 0) { SecurityPolicy0 = (SecurityPolicy0)e.Parameters; } else { 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]; switch (type) { case GlobalKeyType.UnicastEncryption: settings.Cipher.BlockCipherKey = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; case GlobalKeyType.BroadcastEncryption: //Invalid type e.Error = ErrorCode.ReadWriteDenied; break; case GlobalKeyType.Authentication: //if settings.Cipher is null non secure server is used. settings.Cipher.AuthenticationKey = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; case GlobalKeyType.Kek: settings.Kek = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; default: //Invalid type e.Error = ErrorCode.ReadWriteDenied; break; } } } catch (Exception) { e.Error = ErrorCode.ReadWriteDenied; } } else { e.Error = ErrorCode.ReadWriteDenied; } //Return standard reply. return(null); }
byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 2) { foreach (object tmp in e.Parameters as object[]) { object[] item = tmp as object[]; GlobalKeyType type = (GlobalKeyType)Convert.ToInt32(item[0]); byte[] data = (byte[])item[1]; switch (type) { case GlobalKeyType.UnicastEncryption: case GlobalKeyType.BroadcastEncryption: //Invalid type e.Error = ErrorCode.ReadWriteDenied; break; case GlobalKeyType.Authentication: //if settings.Cipher is null non secure server is used. settings.Cipher.AuthenticationKey = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; case GlobalKeyType.Kek: settings.Kek = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; default: //Invalid type e.Error = ErrorCode.ReadWriteDenied; break; } } //Return standard reply. return(null); } else { e.Error = ErrorCode.ReadWriteDenied; return(null); } }
/// <summary> /// Start to use new keys after reply is generated. /// </summary> /// <param name="settings">DLMS settings.</param> /// <param name="e"></param> internal void ApplyKeys(GXDLMSSettings settings, ValueEventArgs e) { try { foreach (List <object> item in e.Parameters as List <object> ) { GlobalKeyType type = (GlobalKeyType)Convert.ToInt32(item[0]); byte[] data = (byte[])item[1]; switch (type) { case GlobalKeyType.UnicastEncryption: settings.Cipher.BlockCipherKey = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; case GlobalKeyType.BroadcastEncryption: //Invalid type e.Error = ErrorCode.ReadWriteDenied; break; case GlobalKeyType.Authentication: //if settings.Cipher is null non secure server is used. settings.Cipher.AuthenticationKey = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; case GlobalKeyType.Kek: settings.Kek = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; default: //Invalid type e.Error = ErrorCode.ReadWriteDenied; break; } } } catch (Exception) { e.Error = ErrorCode.ReadWriteDenied; } }
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); }