mirror of
https://github.com/2dust/v2rayN.git
synced 2026-09-28 17:42:09 +03:00
Cert Pinning (#8234)
* Cert Pinning * Cert Chain Pinning * Add Trusted Ca Pinning * Tip * Perf UI
This commit is contained in:
@@ -2,12 +2,22 @@ namespace ServiceLib.ViewModels;
|
||||
|
||||
public class AddServerViewModel : MyReactiveObject
|
||||
{
|
||||
private string _certError = string.Empty;
|
||||
|
||||
[Reactive]
|
||||
public ProfileItem SelectedSource { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string? CoreType { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string Cert { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string CertTip { get; set; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> FetchCertCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> FetchCertChainCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||
|
||||
public AddServerViewModel(ProfileItem profileItem, Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
@@ -15,11 +25,22 @@ public class AddServerViewModel : MyReactiveObject
|
||||
_config = AppManager.Instance.Config;
|
||||
_updateView = updateView;
|
||||
|
||||
FetchCertCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await FetchCert();
|
||||
});
|
||||
FetchCertChainCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await FetchCertChain();
|
||||
});
|
||||
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SaveServerAsync();
|
||||
});
|
||||
|
||||
this.WhenAnyValue(x => x.Cert)
|
||||
.Subscribe(_ => UpdateCertTip());
|
||||
|
||||
if (profileItem.IndexId.IsNullOrEmpty())
|
||||
{
|
||||
profileItem.Network = Global.DefaultNetwork;
|
||||
@@ -33,6 +54,7 @@ public class AddServerViewModel : MyReactiveObject
|
||||
SelectedSource = JsonUtils.DeepCopy(profileItem);
|
||||
}
|
||||
CoreType = SelectedSource?.CoreType?.ToString();
|
||||
Cert = SelectedSource?.Cert?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
private async Task SaveServerAsync()
|
||||
@@ -77,6 +99,7 @@ public class AddServerViewModel : MyReactiveObject
|
||||
}
|
||||
}
|
||||
SelectedSource.CoreType = CoreType.IsNullOrEmpty() ? null : (ECoreType)Enum.Parse(typeof(ECoreType), CoreType);
|
||||
SelectedSource.Cert = Cert.IsNullOrEmpty() ? null : Cert;
|
||||
|
||||
if (await ConfigHandler.AddServer(_config, SelectedSource) == 0)
|
||||
{
|
||||
@@ -88,4 +111,72 @@ public class AddServerViewModel : MyReactiveObject
|
||||
NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCertTip()
|
||||
{
|
||||
CertTip = _certError.IsNullOrEmpty()
|
||||
? (Cert.IsNullOrEmpty() ? ResUI.CertNotSet : ResUI.CertSet)
|
||||
: _certError;
|
||||
}
|
||||
|
||||
private async Task FetchCert()
|
||||
{
|
||||
if (SelectedSource.StreamSecurity != Global.StreamSecurity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var domain = SelectedSource.Address;
|
||||
var serverName = SelectedSource.Sni;
|
||||
if (serverName.IsNullOrEmpty())
|
||||
{
|
||||
serverName = SelectedSource.RequestHost;
|
||||
}
|
||||
if (serverName.IsNullOrEmpty())
|
||||
{
|
||||
serverName = SelectedSource.Address;
|
||||
}
|
||||
if (!Utils.IsDomain(serverName))
|
||||
{
|
||||
_certError = ResUI.ServerNameMustBeValidDomain;
|
||||
UpdateCertTip();
|
||||
_certError = string.Empty;
|
||||
return;
|
||||
}
|
||||
if (SelectedSource.Port > 0)
|
||||
{
|
||||
domain += $":{SelectedSource.Port}";
|
||||
}
|
||||
Cert = await CertPemManager.Instance.GetCertPemAsync(domain, serverName);
|
||||
}
|
||||
|
||||
private async Task FetchCertChain()
|
||||
{
|
||||
if (SelectedSource.StreamSecurity != Global.StreamSecurity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var domain = SelectedSource.Address;
|
||||
var serverName = SelectedSource.Sni;
|
||||
if (serverName.IsNullOrEmpty())
|
||||
{
|
||||
serverName = SelectedSource.RequestHost;
|
||||
}
|
||||
if (serverName.IsNullOrEmpty())
|
||||
{
|
||||
serverName = SelectedSource.Address;
|
||||
}
|
||||
if (!Utils.IsDomain(serverName))
|
||||
{
|
||||
_certError = ResUI.ServerNameMustBeValidDomain;
|
||||
UpdateCertTip();
|
||||
_certError = string.Empty;
|
||||
return;
|
||||
}
|
||||
if (SelectedSource.Port > 0)
|
||||
{
|
||||
domain += $":{SelectedSource.Port}";
|
||||
}
|
||||
var certs = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName);
|
||||
Cert = string.Join("\n", certs);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user