source: trunk/CrypP2P/Helper/PAPCertificate.cs @ 2273

Last change on this file since 2273 was 2273, checked in by krueger, 11 years ago

This commit repairs CT2 build
Main features:

  • New peer2peer certificate system included
  • P2PEditor Password field added
  • Keysearcher is now using the Avatarname

You will need a certificate to join the peer2peer network

File size: 20.6 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Security.Cryptography.X509Certificates;
5using System.IO;
6using Cryptool.PluginBase;
7using PeersAtPlay.CertificateLibrary.Certificates;
8
9/*
10 * EVERYTHING UNTESTED AND NOT READY!!!
11 */
12
13namespace Cryptool.P2P.Helper
14{
15    public static class PAPCertificate
16    {
17        #region Variables
18
19        /// <summary>
20        /// You can only use the P@P-network by using this user name!!!
21        /// All certificates, which are necessary for using the P@P-P2P-Network, are
22        /// registered with this user name.
23        /// </summary>
24        //public const string CERTIFIED_PEER_NAME = "CrypTool2"; //"pap0001"; //"CT_PAP_User";
25        //public const string CERTIFICATE_DIRECTORY = "pap_certificates";
26
27        private static string sCertPath;
28        /// <summary>
29        /// only set the application path - without certificate
30        /// directory or a specific certificate file name!
31        /// </summary>
32        public static string CertPath
33        {
34            get { return sCertPath; }
35            private set
36            {
37                if (Directory.Exists(value))
38                    sCertPath = value;
39                else
40                    throw (new DirectoryNotFoundException("Path: " + value + " not found"));
41            }
42        }
43
44        //private const string CERT_USER_SUBJECT = "CN=pap0001@pap.de@pap0001@.*, O=Peers@Play, S=None, C=NA";
45        private const string CERT_USER_FILE_NAME = "CrypTool2.pfx"; //"pap0001.p12"; //ct2_user_pap.cer
46        private const string CERT_USER_PASSWORD = "ct2"; //"test"; //CT2p@pC3rt1f1cat10n
47        private const string CERT_USER_ISSUER = "P@P project";
48        private const string CERT_USER_SERIAL = "1E"; //"0D";
49
50        private const string CERT_PAP_FILE_NAME = "pap.cer";
51        private const string CERT_PAP_PASSWORD = "test";
52        private const string CERT_PAP_ISSUER = "P@P project";
53        private const string CERT_PAP_SERIAL = "37cbb8163698c48845e9d5c80e3496b1";
54
55        private const string CERT_OPA_FILE_NAME = "opa.vs.uni-due.de.cer";
56        private const string CERT_OPA_PASSWORD = "";
57        private const string CERT_OPA_ISSUER = "opa.vs.uni-due.de";
58        private const string CERT_OPA_SERIAL = "2FB799C15BAE2FB74FDB72DD0329196A";
59
60        private const string CERT_SERVER_CA_FILE_NAME = "ServerCA.cer";
61        private const string CERT_SERVER_CA_PASSWORD = "";
62        private const string CERT_SERVER_CA_ISSUER = "PAP Server CA";
63        private const string CERT_SERVER_CA_SERIAL = "23440A89B21FA7B84ADDB59DA494F79B";
64
65        private const X509FindType PAP_FIND_TYPE = X509FindType.FindBySerialNumber;
66        // here have to be at least two certificate (PAP Server CA, P@P project)
67        private const StoreName CERT_STORE_ROOT = StoreName.Root;
68        private const StoreLocation CERT_STORE_LOCATION = StoreLocation.CurrentUser;
69        // here has to be one certificate (User certificate)
70        private const StoreName CERT_STORE_USER = StoreName.My;
71
72        #endregion
73
74        #region VERY PAP-SPECIFIC CERTIFICATE METHODS
75
76        public enum PAP_Certificates
77        {
78            Server_CA,
79            Opa,
80            Pap,
81            User
82        }
83
84        /// <summary>
85        /// Checks if all neccessary certificates were installed, otherwise trying to
86        /// install all missing certificates. Returns true if everything worked fine.
87        /// </summary>
88        /// <param name="sPath">only the path of the running application, not the
89        /// certificate direction or a specific filename!!! Everything else will
90        /// be combined internally!!!</param>
91        /// <returns></returns>
92        //public static bool CheckAvailabilityAndInstallMissingCertificates(string sPath)
93        //{
94        //    List<PAP_Certificates> lstMissingCerts = new List<PAP_Certificates>();
95        //    lstMissingCerts = CheckAvailabilityOfPAPCertificates(sPath);
96        //    return InstallMissingCertificates(lstMissingCerts, sPath);
97        //}
98
99        /// <summary>
100        /// Checks if all neccessary certificates were installed, otherwise it returns a
101        /// list with all missing certificates
102        /// </summary>
103        /// <param name="sPath">only the path of the running application, not the
104        /// certificate direction or a specific filename!!! Everything else will
105        /// be combined internally!!!</param>
106        /// <returns></returns>
107        public static List<PAP_Certificates> CheckAvailabilityOfPAPCertificates(string sPath)
108        {
109            CertPath = sPath;
110            List<PAP_Certificates> retLst = new List<PAP_Certificates>();
111            //X509Certificate2Collection certColl;
112
113            /* BEGIN: Checking availablity of the three root certificates */
114
115            // Wacker 27.02.2010: Removed checking for Server and OPA (operator-SSL) certificates; These are only needed if
116            // we want to get a new certificate online - a feature which is not implmented now. When this feature is
117            // implemented, just uncommentd the following lines
118
119            //certColl = FindCertificates(CERT_STORE_ROOT, CERT_STORE_LOCATION,
120            //    PAP_FIND_TYPE, CERT_SERVER_CA_SERIAL, true);
121            //if (certColl.Count == 0)
122            //    retLst.Add(PAP_Certificates.Server_CA);
123
124            //certColl = FindCertificates(CERT_STORE_ROOT, CERT_STORE_LOCATION,
125            //    PAP_FIND_TYPE, CERT_OPA_SERIAL, true);
126            //if (certColl.Count == 0)
127            //    retLst.Add(PAP_Certificates.Opa);
128
129            //certColl = FindCertificates(CERT_STORE_ROOT, CERT_STORE_LOCATION,
130            //    PAP_FIND_TYPE, CERT_PAP_SERIAL, true);
131            //if (certColl.Count == 0)
132            //    retLst.Add(PAP_Certificates.Pap);
133            /* END: Checking availablity of the three root certificates */
134
135            // Check user certificate availability
136            //certColl = FindCertificates(CERT_STORE_USER, CERT_STORE_LOCATION,
137            //    PAP_FIND_TYPE, CERT_USER_SERIAL, true);
138            //if (certColl.Count == 0)
139            //    retLst.Add(PAP_Certificates.User);
140
141            return retLst;
142        }
143
144        /// <summary>
145        /// Installs all certificates, which are specified in the parameter list.
146        /// Returns true, if everything works fine
147        /// </summary>
148        /// <param name="installList">a list of all certificates, which you want to install</param>
149        /// <param name="sPath">only the path of the running application, not the
150        /// certificate direction or a specific filename!!! Everything else will
151        /// be combined internally!!!</param>
152        /// <returns></returns>
153        //public static bool InstallMissingCertificates(List<PAP_Certificates> installList, string sPath)
154        //{
155        //    bool intermediateResult = true;
156        //    bool actualResult = true;
157
158        //    CertPath = sPath;
159
160        //    foreach (PAP_Certificates papCert in installList)
161        //    {
162        //        switch (papCert)
163        //        {
164        //            case PAP_Certificates.Server_CA:
165        //                intermediateResult = InstallCertificate(CERT_STORE_ROOT, CERT_STORE_LOCATION,
166        //                    Path.Combine(CertPath, CERT_SERVER_CA_FILE_NAME), CERT_SERVER_CA_PASSWORD);
167        //                break;
168        //            case PAP_Certificates.Opa:
169        //                intermediateResult = InstallCertificate(CERT_STORE_ROOT, CERT_STORE_LOCATION,
170        //                    Path.Combine(CertPath, CERT_OPA_FILE_NAME), CERT_OPA_PASSWORD);
171        //                break;
172        //            case PAP_Certificates.Pap:
173        //                intermediateResult = InstallCertificate(CERT_STORE_ROOT, CERT_STORE_LOCATION,
174        //                    Path.Combine(CertPath, CERT_PAP_FILE_NAME), CERT_PAP_PASSWORD);
175        //                break;
176        //            case PAP_Certificates.User:
177        //                intermediateResult = InstallCertificate(CERT_STORE_USER, CERT_STORE_LOCATION,
178        //                    Path.Combine(CertPath, CERT_USER_FILE_NAME), CERT_USER_PASSWORD);
179        //                break;
180        //            default:
181        //                break;
182        //        }
183        //        actualResult = actualResult && intermediateResult;
184        //    }
185        //    return actualResult;
186        //}
187
188        #endregion
189
190        #region Common Certificate Operations (Find and Install Certs)
191
192        /// <summary>
193        /// Searches for certificates in the given Store with the given FindType and value
194        /// </summary>
195        /// <param name="storeName">Name of the store</param>
196        /// <param name="storeLocation">Location of the store</param>
197        /// <param name="findType">choose which attribute of the installed cert's should be compare with the given value</param>
198        /// <param name="findValue">value, which should be exactly in the chosen FindType of an installed certificate</param>
199        /// <param name="onlyValidCerts">only valid certificates (not outdated, revocated, etc.) will be considered.</param>
200        /// <returns>a list of all certificates, who satisfy the search attributes</returns>
201        //private static X509Certificate2Collection FindCertificates(StoreName storeName, StoreLocation storeLocation, X509FindType findType, object findValue, bool onlyValidCerts)
202        //{
203        //    X509Certificate2Collection findedCertCol = null;
204        //    X509Store store = new X509Store(storeName, storeLocation);
205        //    try
206        //    {
207        //        store.Open(OpenFlags.ReadOnly);
208        //        findedCertCol = store.Certificates.Find(findType, findValue, onlyValidCerts);
209        //    }
210        //    catch (Exception)
211        //    {
212
213        //        throw;
214        //    }
215        //    finally
216        //    {
217        //        store.Close();
218        //    }
219
220        //    return findedCertCol;
221        //}
222
223        /// <summary>
224        /// Installs a given certificate if it is already valid and not installed yet
225        /// </summary>
226        /// <param name="storeName">Name of the store</param>
227        /// <param name="storeLocation">Location of the store</param>
228        /// <param name="sCertPath">Whole certification path and filename</param>
229        /// <param name="sCertPassword">if necessary, you have to declare a password. Otherwise use ""</param>
230        //private static bool InstallCertificate(StoreName storeName, StoreLocation storeLocation, string sCertPath, string sCertPassword)
231        //{
232        //    bool ret = false;
233
234        //    if (File.Exists(sCertPath))
235        //    {
236        //        X509Store store = new X509Store(storeName, storeLocation);
237        //        try
238        //        {
239        //            /* Verification of certifates failed every time - no idea why */
240        //            //if (cert.Verify())
241        //            //{
242        //            X509Certificate2 cert = new X509Certificate2(sCertPath, sCertPassword);
243        //            store.Open(OpenFlags.ReadWrite);
244        //            store.Add(cert);
245        //            store.Close();
246        //            ret = true;
247        //            //}
248        //            //else
249        //            //{
250        //            //    throw (new Exception("Installing Certificate " + cert.SubjectName.Name + " wasn't possible, because Certificate isn't valid anymore"));
251        //            //}
252        //        }
253        //        catch (Exception ex)
254        //        {
255        //            throw (new Exception("Installation of " + sCertPath + " certificate wasn't possible", ex));
256        //        }
257        //        finally
258        //        {
259        //            store.Close();
260        //        }
261        //    }
262        //    return ret;
263        //}
264
265        #endregion
266
267        #region (currently not used) PAP specific stuff (eMail Address registered certificates, etc.)
268
269        /// <summary>
270        /// Will search for the root certificate in the windows certificate store.
271        /// </summary>
272        /// <returns>The root certificate or null on error</returns>
273        //public static X509Certificate2Collection getRootCertificate()
274        //{
275        //    //X509Certificate2Collection root = FindCertificates(CERT_STORE_ROOT, CERT_STORE_LOCATION, X509FindType.FindBySerialNumber, CERT_PAP_SERIAL, true);
276           
277        //    return new X509Certificate2Collection(new X509Certificate2(CertificateServices.CaCertificate));
278        //}
279
280        /// <summary>
281        /// Gives back an X509Certificate2 from an given email address (hashed value)
282        /// </summary>
283        /// <param name="email">the email</param>
284        /// <returns>the searched certificate</returns>
285        //public static X509Certificate2 GetCertificateWithMail(String email)
286        //{
287        //    try
288        //    {
289        //        return new X509Certificate2(CertificateServices.ConvertToDotNet(CertificateServices.GetX509CertificateByEmail(PeerCertificate.DEFAULT_USER_CERTIFICATE_DIRECTORY, email)));
290        //        //String fileName = GetHash(email);
291        //        //X509Certificate2Collection col = FindCertificates(StoreName.My, StoreLocation.CurrentUser, X509FindType.FindByIssuerName, CERT_PAP_ISSUER, true);
292        //        //foreach (X509Certificate2 cert in col)
293        //        //{
294        //        //    if (cert.Subject.Contains(fileName))
295        //        //    {
296        //        //        return cert;
297        //        //    }
298        //        //}
299        //        //return null;
300        //    }
301        //    catch
302        //    {
303        //        return null;
304        //    }
305        //}
306
307        /// <summary>
308        /// Creates an crypted string from an ordinary
309        /// </summary>
310        /// <param name="str">the ordinary string</param>
311        /// <returns>an coded string</returns>
312        //public static String GetHash(String str)
313        //{
314        //    str = str.ToLower();
315        //    System.Security.Cryptography.SHA1 sec = new System.Security.Cryptography.SHA1CryptoServiceProvider();
316        //    Encoding encoding = Encoding.Unicode;
317        //    byte[] insertion = encoding.GetBytes(str);
318        //    byte[] hash = sec.ComputeHash(insertion);
319        //    String result = BitConverter.ToString(hash);//Convert.ToBase64String(hash);
320        //    result = result.Substring(result.Length / 2 + 1);
321        //    return result;
322        //}
323
324        #endregion
325
326        #region PickCertificate (currently not used)
327        /// <summary>
328        /// Let the user choose a certificate from given location and store name
329        /// </summary>
330        /// <param name="location">The location</param>
331        /// <param name="name">The store name</param>
332        //public static void PickCertificate(StoreLocation location, StoreName name)
333        //{
334        //    X509Certificate2 MyCertificate;
335        //    X509Store store = new X509Store(name, location);
336        //    try
337        //    {
338        //        store.Open(OpenFlags.ReadOnly);
339
340        //        // Pick a certificate from the store
341        //        MyCertificate = X509Certificate2UI.SelectFromCollection(store.Certificates, "P@P certificates", "Please select your certificate", X509SelectionFlag.SingleSelection)[0];
342
343        //        // Comment next line to enable selection of an invalid certificate
344        //        ValidateCert(MyCertificate);
345
346        //        //MyCertificateSerialNumber = MyCertificate.SerialNumber;
347        //    }
348        //    catch (Exception ex)
349        //    {
350        //        MyCertificate = null;
351        //        throw (new Exception("Certificate not valid", ex));
352        //    }
353        //    finally { store.Close(); }
354        //}
355        #endregion
356
357        #region ValidateCert (currently not used)
358        /// <summary>
359        /// Validates a certificate according to P@P-rules
360        /// </summary>
361        /// <exception cref="SNALCertificateNotValidException"></exception>
362        /// <exception cref="ArgumentNullException"></exception>
363        /// <param name="cert">Certificate to validate</param>
364        //public static void ValidateCert(X509Certificate2 cert)
365        //{
366        //    if (cert == null)
367        //    {
368        //        throw new ArgumentNullException("cert");
369        //    }
370
371        //    X509Chain chain = new X509Chain();
372
373        //    // check entire chain for revocation
374        //    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
375
376        //    // TODO: Check Online
377        //    chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
378
379        //    // timeout for online revocation list
380        //    chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 30);
381
382        //    // TODO: Revocation unknown allowed
383        //    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
384
385        //    // Check chain
386        //    chain.Build(cert);
387
388        //    // If there was an error or no root CA is given throw exception
389        //    if (chain.ChainStatus.Length != 0 || chain.ChainElements.Count != 2)
390        //    {
391        //        throw new Exception("Certificates chain not valid!");
392        //    }
393
394        //    // Check root certificate
395        //    if (chain.ChainElements[1].Certificate.SerialNumber.ToLower() != CERT_PAP_SERIAL.ToLower())
396        //    {
397        //        throw new Exception("Certificates root CA not valid!");
398        //    }
399        //}
400        #endregion
401
402        /// <summary>
403        /// Checks if all certificates for using the pap p2p system are installed.
404        /// Otherwise it tries to install the missing certificates. If all operations
405        /// succeed, return value is true. Only when value is true, you can try
406        /// to initialize the PAP System.
407        /// </summary>
408        /// <returns>If all operations succeed, return value is true. Only when value
409        /// is true, you can try to initialize the PAP System.</returns>
410        public static bool CheckAndInstallPAPCertificates()
411        {
412            bool retValue = false;
413
414            // get exe directory, because there resides the certificate directory
415            //System.Reflection.Assembly assemb = System.Reflection.Assembly.GetEntryAssembly();
416            //string applicationDir = System.IO.Path.GetDirectoryName(assemb.Location);
417            // check if all necessary certs are installed
418            P2PManager.GuiLogMessage("Validating installation of P2P certificates.", NotificationLevel.Info);
419            List<PAPCertificate.PAP_Certificates> lstMissingCerts = PAPCertificate.CheckAvailabilityOfPAPCertificates(PeerCertificate.DEFAULT_USER_CERTIFICATE_DIRECTORY);
420            if (lstMissingCerts.Count == 0)
421            {
422                P2PManager.GuiLogMessage("All neccessary p2p certificates are installed.", NotificationLevel.Info);
423                retValue = true;
424            }
425            //else
426            //{
427            //    StringBuilder sbMissingCerts = new StringBuilder();
428            //    for (int i = 0; i < lstMissingCerts.Count; i++)
429            //    {
430            //        sbMissingCerts.AppendLine(Enum.GetName(typeof(PAPCertificate.PAP_Certificates), lstMissingCerts[i]));
431            //    }
432            //    P2PManager.GuiLogMessage("Following certificates are missing. They will be installed now.\n" + sbMissingCerts.ToString(), NotificationLevel.Info);
433
434            //    // try/catch neccessary because the CT-Editor doesn't support the whole exception display process (e.g. shows only "unknown error.")
435            //    try
436            //    {
437            //        if (PAPCertificate.InstallMissingCertificates(lstMissingCerts, applicationDir))
438            //        {
439            //            P2PManager.GuiLogMessage("Installation of all missing certificates was successful.", NotificationLevel.Info);
440            //            retValue = true;
441            //        }
442            //        else
443            //        {
444            //            P2PManager.GuiLogMessage("No/not all missing certificates were installed successful.", NotificationLevel.Error);
445            //        }
446            //    }
447            //    catch (Exception ex)
448            //    {
449            //        P2PManager.GuiLogMessage("Error occured while installing certificates. Exception: " + ex.ToString(), NotificationLevel.Error);
450            //    }
451            //}
452            return retValue;
453        }
454    }
455}
Note: See TracBrowser for help on using the repository browser.