markus / MarkusAutoUpdate / src / NetSparkle.Tools.AppCastGenerator / SignatureManager.cs @ d8f5045e
이력 | 보기 | 이력해설 | 다운로드 (5.1 KB)
1 |
using System; |
---|---|
2 |
using System.IO; |
3 |
using System.Runtime.CompilerServices; |
4 |
using Org.BouncyCastle.Crypto; |
5 |
using Org.BouncyCastle.Crypto.Generators; |
6 |
using Org.BouncyCastle.Crypto.Parameters; |
7 |
using Org.BouncyCastle.Crypto.Signers; |
8 |
using Org.BouncyCastle.Security; |
9 |
|
10 |
namespace NetSparkleUpdater.AppCastGenerator |
11 |
{ |
12 |
public class SignatureManager |
13 |
{ |
14 |
private string _storagePath; |
15 |
private string _privateKeyFilePath; |
16 |
private string _publicKeyFilePath; |
17 |
|
18 |
public const string PrivateKeyEnvironmentVariable = "SPARKLE_PRIVATE_KEY"; |
19 |
public const string PublicKeyEnvironmentVariable = "SPARKLE_PUBLIC_KEY"; |
20 |
|
21 |
public SignatureManager() |
22 |
{ |
23 |
SetStorageDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "netsparkle")); |
24 |
} |
25 |
|
26 |
public void SetStorageDirectory(string path) |
27 |
{ |
28 |
_storagePath = path; |
29 |
|
30 |
if (!Directory.Exists(_storagePath)) |
31 |
{ |
32 |
Directory.CreateDirectory(_storagePath); |
33 |
} |
34 |
|
35 |
_privateKeyFilePath = Path.Combine(_storagePath, "NetSparkle_Ed25519.priv"); |
36 |
_publicKeyFilePath = Path.Combine(_storagePath, "NetSparkle_Ed25519.pub"); |
37 |
} |
38 |
|
39 |
public bool KeysExist() |
40 |
{ |
41 |
if (GetPublicKey() != null && GetPrivateKey() != null) |
42 |
{ |
43 |
return true; |
44 |
} |
45 |
|
46 |
return false; |
47 |
} |
48 |
|
49 |
public bool Generate(bool force = false) |
50 |
{ |
51 |
|
52 |
if (KeysExist() && !force) |
53 |
{ |
54 |
Console.WriteLine("Keys already exist, use --force to force regeneration"); |
55 |
return false; |
56 |
} |
57 |
|
58 |
// start key generation |
59 |
Console.WriteLine("Generating key pair..."); |
60 |
|
61 |
|
62 |
var Random = new SecureRandom(); |
63 |
|
64 |
Ed25519KeyPairGenerator kpg = new Ed25519KeyPairGenerator(); |
65 |
kpg.Init(new Ed25519KeyGenerationParameters(Random)); |
66 |
|
67 |
AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); |
68 |
Ed25519PrivateKeyParameters privateKey = (Ed25519PrivateKeyParameters)kp.Private; |
69 |
Ed25519PublicKeyParameters publicKey = (Ed25519PublicKeyParameters)kp.Public; |
70 |
|
71 |
var privKeyBase64 = Convert.ToBase64String(privateKey.GetEncoded()); |
72 |
var pubKeyBase64 = Convert.ToBase64String(publicKey.GetEncoded()); |
73 |
|
74 |
File.WriteAllText(_privateKeyFilePath, privKeyBase64); |
75 |
File.WriteAllText(_publicKeyFilePath, pubKeyBase64); |
76 |
|
77 |
Console.WriteLine("Storing public/private keys to " + _storagePath); |
78 |
return true; |
79 |
} |
80 |
|
81 |
public bool VerifySignature(string filePath, string signature) |
82 |
{ |
83 |
return VerifySignature(new FileInfo(filePath), signature); |
84 |
} |
85 |
|
86 |
public bool VerifySignature(FileInfo file, string signature) |
87 |
{ |
88 |
if (!KeysExist()) |
89 |
{ |
90 |
Console.WriteLine("Keys do not exist"); |
91 |
return false; |
92 |
} |
93 |
if (signature == null) |
94 |
{ |
95 |
Console.WriteLine("Signature at path {0} is null", file.FullName); |
96 |
return false; |
97 |
} |
98 |
|
99 |
|
100 |
var data = File.ReadAllBytes(file.FullName); |
101 |
|
102 |
var validator = new Ed25519Signer(); |
103 |
validator.Init(false, new Ed25519PublicKeyParameters(GetPublicKey(), 0)); |
104 |
validator.BlockUpdate(data, 0, data.Length); |
105 |
|
106 |
return validator.VerifySignature(Convert.FromBase64String(signature)); |
107 |
} |
108 |
|
109 |
public string GetSignatureForFile(string filePath) |
110 |
{ |
111 |
return GetSignatureForFile(new FileInfo(filePath)); |
112 |
} |
113 |
|
114 |
public string GetSignatureForFile(FileInfo file) |
115 |
{ |
116 |
if (!KeysExist()) |
117 |
{ |
118 |
Console.WriteLine("Keys do not exist"); |
119 |
return null; |
120 |
} |
121 |
|
122 |
if (!file.Exists) |
123 |
{ |
124 |
Console.Error.WriteLine("Target binary " + file.FullName + " does not exists"); |
125 |
return null; |
126 |
} |
127 |
|
128 |
|
129 |
var data = File.ReadAllBytes(file.FullName); |
130 |
|
131 |
var signer = new Ed25519Signer(); |
132 |
|
133 |
signer.Init(true, new Ed25519PrivateKeyParameters(GetPrivateKey(), 0)); |
134 |
signer.BlockUpdate(data, 0, data.Length); |
135 |
|
136 |
return Convert.ToBase64String(signer.GenerateSignature()); |
137 |
} |
138 |
|
139 |
public byte[] GetPrivateKey() |
140 |
{ |
141 |
return ResolveKeyLocation(PrivateKeyEnvironmentVariable, _privateKeyFilePath); |
142 |
} |
143 |
|
144 |
public byte[] GetPublicKey() |
145 |
{ |
146 |
return ResolveKeyLocation(PublicKeyEnvironmentVariable, _publicKeyFilePath); |
147 |
} |
148 |
|
149 |
private byte[] ResolveKeyLocation(string environmentVariableName, string fileLocation) |
150 |
{ |
151 |
var key = Environment.GetEnvironmentVariable(environmentVariableName); |
152 |
|
153 |
if (key != null) |
154 |
{ |
155 |
return Convert.FromBase64String(key); |
156 |
} |
157 |
|
158 |
if (!File.Exists(fileLocation)) |
159 |
{ |
160 |
return null; |
161 |
} |
162 |
|
163 |
return Convert.FromBase64String(File.ReadAllText(fileLocation)); |
164 |
} |
165 |
} |
166 |
} |