/// <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);
        }
Esempio n. 3
0
 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);
     }
 }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 9
0
        /// <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);
            }
        }
Esempio n. 10
0
        /// <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);
        }
Esempio n. 11
0
        /// <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));
        }
Esempio n. 12
0
        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)));
        }
Esempio n. 13
0
        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);
                }
            }
        }
Esempio n. 14
0
        /// <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);
            }
        }
Esempio n. 15
0
        /// <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);
        }
Esempio n. 16
0
        /// <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;
                            }
                        }
                    }
                }
            }
        }