From 565ca51ee3ebed90da88c3c3142a6a76f9658290 Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Wed, 26 Oct 2016 16:24:12 +0800 Subject: [PATCH] fix bugs; --- .../Cryptography/CertificateQueryService.cs | 87 +++++++++++++------ AntSharesUI/UI/MainForm.cs | 15 +++- 2 files changed, 74 insertions(+), 28 deletions(-) diff --git a/AntSharesUI/Cryptography/CertificateQueryService.cs b/AntSharesUI/Cryptography/CertificateQueryService.cs index cada1bba4f..31ce3f1878 100644 --- a/AntSharesUI/Cryptography/CertificateQueryService.cs +++ b/AntSharesUI/Cryptography/CertificateQueryService.cs @@ -1,6 +1,8 @@ -using AntShares.Core; -using AntShares.Cryptography.ECC; +using AntShares.Cryptography.ECC; using AntShares.Properties; +using System; +using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Net; using System.Security.Cryptography; @@ -10,56 +12,91 @@ namespace AntShares.Cryptography { internal static class CertificateQueryService { - public static CertificateQueryResult Query(ECPoint pubkey, string url) + private static WebClient web = new WebClient(); + private static Dictionary results = new Dictionary(); + + static CertificateQueryService() { - if (pubkey.Equals(Blockchain.AntShare.Issuer) || pubkey.Equals(Blockchain.AntCoin.Issuer)) - return new CertificateQueryResult { Type = CertificateQueryResultType.System }; Directory.CreateDirectory(Settings.Default.CertCachePath); + web.DownloadFileCompleted += Web_DownloadFileCompleted; + } + + private static void Web_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) + { + ECPoint pubkey = (ECPoint)e.UserState; + lock (results) + { + if (e.Cancelled || e.Error != null) + results[pubkey].Type = CertificateQueryResultType.Missing; + else + UpdateResultFromFile(pubkey); + } + } + + public static CertificateQueryResult Query(ECPoint pubkey, string url) + { + lock (results) + { + if (results.ContainsKey(pubkey)) return results[pubkey]; + results[pubkey] = new CertificateQueryResult { Type = CertificateQueryResultType.Querying }; + } string path = Path.Combine(Settings.Default.CertCachePath, $"{pubkey}.cer"); - if (!File.Exists(path)) + if (File.Exists(path)) { - if (string.IsNullOrEmpty(url)) - url = $"http://cert.onchain.com/antshares/{pubkey}.cer"; - using (WebClient web = new WebClient()) + lock (results) { - try - { - web.DownloadFile(url, path); - } - catch (WebException) { } + UpdateResultFromFile(pubkey); } } - if (!File.Exists(path)) - return new CertificateQueryResult { Type = CertificateQueryResultType.Missing }; + else + { + if (string.IsNullOrEmpty(url)) + url = $"http://cert.onchain.com/antshares/{pubkey}.cer"; + web.DownloadFileAsync(new Uri(url), path, pubkey); + } + return results[pubkey]; + + //if (!File.Exists(path)) + // return new CertificateQueryResult { Type = CertificateQueryResultType.Missing }; + } + + private static void UpdateResultFromFile(ECPoint pubkey) + { X509Certificate2 cert; try { - cert = new X509Certificate2(path); + cert = new X509Certificate2(Path.Combine(Settings.Default.CertCachePath, $"{pubkey}.cer")); } catch (CryptographicException) { - return new CertificateQueryResult { Type = CertificateQueryResultType.Missing }; + results[pubkey].Type = CertificateQueryResultType.Missing; + return; } if (cert.PublicKey.Oid.Value != "1.2.840.10045.2.1") - return new CertificateQueryResult { Type = CertificateQueryResultType.Missing }; + { + results[pubkey].Type = CertificateQueryResultType.Missing; + return; + } if (!pubkey.Equals(ECPoint.DecodePoint(cert.PublicKey.EncodedKeyValue.RawData, ECCurve.Secp256r1))) - return new CertificateQueryResult { Type = CertificateQueryResultType.Missing }; + { + results[pubkey].Type = CertificateQueryResultType.Missing; + return; + } using (X509Chain chain = new X509Chain()) { - CertificateQueryResult result = new CertificateQueryResult { Certificate = cert }; + results[pubkey].Certificate = cert; if (chain.Build(cert)) { - result.Type = CertificateQueryResultType.Good; + results[pubkey].Type = CertificateQueryResultType.Good; } else if (chain.ChainStatus.Length == 1 && chain.ChainStatus[0].Status == X509ChainStatusFlags.NotTimeValid) { - result.Type = CertificateQueryResultType.Expired; + results[pubkey].Type = CertificateQueryResultType.Expired; } else { - result.Type = CertificateQueryResultType.Invalid; + results[pubkey].Type = CertificateQueryResultType.Invalid; } - return result; } } } diff --git a/AntSharesUI/UI/MainForm.cs b/AntSharesUI/UI/MainForm.cs index 3473b9c1d9..dfdf4619f9 100644 --- a/AntSharesUI/UI/MainForm.cs +++ b/AntSharesUI/UI/MainForm.cs @@ -257,9 +257,18 @@ private void timer1_Tick(object sender, EventArgs e) { ListViewItem.ListViewSubItem subitem = item.SubItems["issuer"]; RegisterTransaction asset = (RegisterTransaction)item.Tag; - byte[] cert_url_data = asset.Attributes.FirstOrDefault(p => p.Usage == TransactionAttributeUsage.CertUrl)?.Data; - string cert_url = cert_url_data == null ? null : Encoding.UTF8.GetString(cert_url_data); - using (CertificateQueryResult result = CertificateQueryService.Query(asset.Issuer, cert_url)) + CertificateQueryResult result; + if (asset.AssetType == AssetType.AntShare || asset.AssetType == AssetType.AntCoin) + { + result = new CertificateQueryResult { Type = CertificateQueryResultType.System }; + } + else + { + byte[] cert_url_data = asset.Attributes.FirstOrDefault(p => p.Usage == TransactionAttributeUsage.CertUrl)?.Data; + string cert_url = cert_url_data == null ? null : Encoding.UTF8.GetString(cert_url_data); + result = CertificateQueryService.Query(asset.Issuer, cert_url); + } + using (result) { switch (result.Type) {