프로젝트

일반

사용자정보

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

markus / AutoUpdater / NetSparkle.Tools.AppCastGenerator / SignatureManager.cs @ 9d5b4bc2

이력 | 보기 | 이력해설 | 다운로드 (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
}
클립보드 이미지 추가 (최대 크기: 500 MB)