Skip to content

Commit c7cbdc6

Browse files
Feature: Add "Digital Signatures" tab to the properties window
1 parent 5a7f153 commit c7cbdc6

File tree

10 files changed

+435
-13
lines changed

10 files changed

+435
-13
lines changed

src/Files.App/Data/Enums/PropertiesNavigationViewItemType.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,10 @@ public enum PropertiesNavigationViewItemType
4747
/// Shortcut page type
4848
/// </summary>
4949
Shortcut,
50-
}
50+
51+
/// <summary>
52+
/// Signatures page type
53+
/// </summary>
54+
Signatures,
55+
}
5156
}

src/Files.App/Data/Factories/PropertiesNavigationViewItemFactory.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,16 @@ public static ObservableCollection<NavigationViewItemButtonStyleItem> Initialize
6161
ItemType = PropertiesNavigationViewItemType.Compatibility,
6262
ThemedIconStyle = (Style)Application.Current.Resources["App.ThemedIcons.Properties.Compatability"],
6363
};
64-
65-
PropertiesNavigationViewItems.Add(generalItem);
66-
PropertiesNavigationViewItems.Add(securityItem);
64+
var signaturesItem = new NavigationViewItemButtonStyleItem()
65+
{
66+
Name = Strings.Signatures.GetLocalizedResource(),
67+
ItemType = PropertiesNavigationViewItemType.Signatures,
68+
ThemedIconStyle = (Style)Application.Current.Resources["App.ThemedIcons.Properties.Signatures"],
69+
};
70+
71+
PropertiesNavigationViewItems.Add(generalItem);
72+
PropertiesNavigationViewItems.Add(signaturesItem);
73+
PropertiesNavigationViewItems.Add(securityItem);
6774
PropertiesNavigationViewItems.Add(hashesItem);
6875
PropertiesNavigationViewItems.Add(shortcutItem);
6976
PropertiesNavigationViewItems.Add(libraryItem);
@@ -89,7 +96,8 @@ public static ObservableCollection<NavigationViewItemButtonStyleItem> Initialize
8996
PropertiesNavigationViewItems.Remove(securityItem);
9097
PropertiesNavigationViewItems.Remove(customizationItem);
9198
PropertiesNavigationViewItems.Remove(hashesItem);
92-
}
99+
PropertiesNavigationViewItems.Remove(signaturesItem);
100+
}
93101
else if (item is ListedItem listedItem)
94102
{
95103
var isShortcut = listedItem.IsShortcut;
@@ -106,10 +114,13 @@ public static ObservableCollection<NavigationViewItemButtonStyleItem> Initialize
106114
if (!securityItemEnabled)
107115
PropertiesNavigationViewItems.Remove(securityItem);
108116

109-
if (!hashItemEnabled)
110-
PropertiesNavigationViewItems.Remove(hashesItem);
117+
if (!hashItemEnabled)
118+
{
119+
PropertiesNavigationViewItems.Remove(hashesItem);
120+
PropertiesNavigationViewItems.Remove(signaturesItem);
121+
}
111122

112-
if (!isShortcut)
123+
if (!isShortcut)
113124
PropertiesNavigationViewItems.Remove(shortcutItem);
114125

115126
if (!isLibrary)
@@ -132,7 +143,8 @@ public static ObservableCollection<NavigationViewItemButtonStyleItem> Initialize
132143
PropertiesNavigationViewItems.Remove(detailsItem);
133144
PropertiesNavigationViewItems.Remove(customizationItem);
134145
PropertiesNavigationViewItems.Remove(compatibilityItem);
135-
}
146+
PropertiesNavigationViewItems.Remove(signaturesItem);
147+
}
136148

137149
return PropertiesNavigationViewItems;
138150
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using System.Windows.Input;
5+
6+
namespace Files.App.Data.Models
7+
{
8+
public sealed partial class SignatureInfoItem : ObservableObject
9+
{
10+
private string _Version = string.Empty;
11+
public string Version
12+
{
13+
get => _Version;
14+
set => SetProperty(ref _Version, value);
15+
}
16+
17+
private string _IssuedBy = string.Empty;
18+
public string IssuedBy
19+
{
20+
get => _IssuedBy;
21+
set => SetProperty(ref _IssuedBy, value);
22+
}
23+
24+
private string _IssuedTo = string.Empty;
25+
public string IssuedTo
26+
{
27+
get => _IssuedTo;
28+
set => SetProperty(ref _IssuedTo, value);
29+
}
30+
31+
private string _ValidFromTimestamp = string.Empty;
32+
public string ValidFromTimestamp
33+
{
34+
get => _ValidFromTimestamp;
35+
set => SetProperty(ref _ValidFromTimestamp, value);
36+
}
37+
38+
private string _ValidToTimestamp = string.Empty;
39+
public string ValidToTimestamp
40+
{
41+
get => _ValidToTimestamp;
42+
set => SetProperty(ref _ValidToTimestamp, value);
43+
}
44+
45+
private string _VerifiedTimestamp = string.Empty;
46+
public string VerifiedTimestamp
47+
{
48+
get => _VerifiedTimestamp;
49+
set => SetProperty(ref _VerifiedTimestamp, value);
50+
}
51+
52+
private bool _Verified = false;
53+
public bool Verified
54+
{
55+
get => _Verified;
56+
set
57+
{
58+
if (SetProperty(ref _Verified, value))
59+
OnPropertyChanged(nameof(Glyph));
60+
}
61+
}
62+
63+
public string Glyph => Verified ? "\uE930" : "\uEA39";
64+
65+
public ICommand OpenDetailsCommand { get; }
66+
67+
public SignatureInfoItem()
68+
{
69+
OpenDetailsCommand = new AsyncRelayCommand(DoOpenDetails);
70+
}
71+
72+
private Task DoOpenDetails()
73+
{
74+
return Task.CompletedTask;
75+
}
76+
}
77+
}

src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Copyright (c) 2024 Files Community
2-
// Licensed under the MIT License. See the LICENSE.
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
33

44
using System.IO;
55
using System.Runtime.InteropServices;
@@ -347,5 +347,38 @@ public static extern int SHGetKnownFolderPath(
347347
IntPtr hToken,
348348
out IntPtr pszPath
349349
);
350-
}
350+
351+
[DllImport("wintrust.dll", CharSet = CharSet.Unicode, SetLastError = true)]
352+
private static extern uint WinVerifyTrust(
353+
IntPtr hwnd,
354+
[MarshalAs(UnmanagedType.LPStruct)] Guid pgActionID,
355+
IntPtr pWVTData
356+
);
357+
358+
[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
359+
private static extern bool CryptQueryObject(
360+
uint dwObjectType,
361+
IntPtr pvObject,
362+
uint dwExpectedContentTypeFlags,
363+
uint dwExpectedFormatTypeFlags,
364+
uint dwFlags,
365+
out uint pdwMsgAndCertEncodingType,
366+
out uint pdwContentType,
367+
out uint pdwFormatType,
368+
out IntPtr phCertStore,
369+
out IntPtr phMsg,
370+
out IntPtr ppvContext
371+
);
372+
373+
[DllImport("crypt32.dll", SetLastError = true)]
374+
private static extern bool CertCloseStore(
375+
IntPtr hCertStore,
376+
uint dwFlags
377+
);
378+
379+
[DllImport("crypt32.dll", SetLastError = true)]
380+
private static extern bool CryptMsgClose(
381+
IntPtr hCryptMsg
382+
);
383+
}
351384
}

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4273,4 +4273,22 @@
42734273
<data name="Filename" xml:space="preserve">
42744274
<value>Filename</value>
42754275
</data>
4276+
<data name="Signatures" xml:space="preserve">
4277+
<value>Signatures</value>
4278+
</data>
4279+
<data name="SignatureList" xml:space="preserve">
4280+
<value>Signature list</value>
4281+
</data>
4282+
<data name="IssuedBy" xml:space="preserve">
4283+
<value>Issued by:</value>
4284+
</data>
4285+
<data name="IssuedTo" xml:space="preserve">
4286+
<value>Issued to:</value>
4287+
</data>
4288+
<data name="ValidFrom" xml:space="preserve">
4289+
<value>Valid from:</value>
4290+
</data>
4291+
<data name="ValidTo" xml:space="preserve">
4292+
<value>Valid to:</value>
4293+
</data>
42764294
</root>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
namespace Files.App.Utils.Signatures
5+
{
6+
public static class DigitalSignaturesUtil
7+
{
8+
public static List<SignatureInfoItem> GetSignaturesOfItem(string filePath)
9+
{
10+
var signatures = new List<SignatureInfoItem>();
11+
12+
return signatures;
13+
}
14+
}
15+
}

src/Files.App/ViewModels/Properties/MainPropertiesViewModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public NavigationViewItemButtonStyleItem SelectedNavigationViewItem
4141
PropertiesNavigationViewItemType.Customization => typeof(CustomizationPage),
4242
PropertiesNavigationViewItemType.Compatibility => typeof(CompatibilityPage),
4343
PropertiesNavigationViewItemType.Hashes => typeof(HashesPage),
44-
_ => typeof(GeneralPage),
44+
PropertiesNavigationViewItemType.Signatures => typeof(SignaturesPage),
45+
_ => typeof(GeneralPage),
4546
};
4647

4748
_mainFrame?.Navigate(page, parameter, new EntranceNavigationTransitionInfo());
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using Files.App.Utils.Signatures;
5+
6+
namespace Files.App.ViewModels.Properties
7+
{
8+
public sealed partial class SignaturesViewModel : ObservableObject, IDisposable
9+
{
10+
private CancellationTokenSource _cancellationTokenSource;
11+
12+
public ObservableCollection<SignatureInfoItem> Signatures { get; set; }
13+
14+
public SignaturesViewModel(ListedItem item)
15+
{
16+
_cancellationTokenSource = new();
17+
Signatures = new();
18+
19+
var signatures = DigitalSignaturesUtil.GetSignaturesOfItem(item.ItemPath);
20+
signatures.ForEach(s => Signatures.Add(s));
21+
}
22+
23+
public void Dispose()
24+
{
25+
_cancellationTokenSource.Cancel();
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)