프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / MarkusAutoUpdate / src / NetSparkle.Tools.AppCastGenerator / SignatureManager.cs @ d8f5045e

이력 | 보기 | 이력해설 | 다운로드 (5.1 KB)

1 d8f5045e taeseongkim
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
}
클립보드 이미지 추가 (최대 크기: 500 MB)