Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Security.SecureRepository / Tizen.Security.SecureRepository / CertificateManager.cs
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using static Interop;
20
21 namespace Tizen.Security.SecureRepository
22 {
23     /// <summary>
24     /// This class provides the methods handling certificates.
25     /// </summary>
26     /// <since_tizen> 3 </since_tizen>
27     public class CertificateManager : Manager
28     {
29         /// <summary>
30         /// Gets a certificate from secure repository.
31         /// </summary>
32         /// <since_tizen> 3 </since_tizen>
33         /// <param name="alias">The name of a certificate to retrieve.</param>
34         /// <param name="password">
35         /// The password used in decrypting a certificate value. If password of
36         /// policy is provided in SaveCertificate(), the same password should be
37         /// provided.
38         /// </param>
39         /// <returns>A certificate specified by alias.</returns>
40         /// <exception cref="ArgumentNullException">
41         /// Alias argument is null
42         /// </exception>
43         /// <exception cref="ArgumentException">
44         /// Alias argument is invalid format.
45         /// </exception>
46         /// <exception cref="InvalidOperationException">
47         /// Certificate does not exist with the alias or certificate-protecting
48         /// password isn't matched.
49         /// </exception>
50         static public Certificate Get(string alias, string password)
51         {
52             if (alias == null)
53                 throw new ArgumentNullException("alias cannot be null");
54
55             IntPtr ptr = IntPtr.Zero;
56
57             try
58             {
59                 Interop.CheckNThrowException(
60                     Interop.CkmcManager.GetCert(alias, password, out ptr),
61                     "Failed to get certificate. alias=" + alias);
62                 return new Certificate(ptr);
63             }
64             finally
65             {
66                 if (ptr != IntPtr.Zero)
67                     Interop.CkmcTypes.CertFree(ptr);
68             }
69         }
70
71         /// <summary>
72         /// Gets all alias of certificates which the client can access.
73         /// </summary>
74         /// <since_tizen> 3 </since_tizen>
75         /// <returns>All alias of certificates which the client can access.</returns>
76         /// <exception cref="ArgumentException">No alias to get.</exception>
77         static public IEnumerable<string> GetAliases()
78         {
79             IntPtr ptr = IntPtr.Zero;
80
81             try
82             {
83                 Interop.CheckNThrowException(
84                     Interop.CkmcManager.GetCertAliasList(out ptr),
85                     "Failed to get certificate aliases.");
86                 return new SafeAliasListHandle(ptr).Aliases;
87             }
88             finally
89             {
90                 if (ptr != IntPtr.Zero)
91                     Interop.CkmcTypes.AliasListAllFree(ptr);
92             }
93         }
94
95         /// <summary>
96         /// Stores a certificate inside secure repository based on the provided policy.
97         /// </summary>
98         /// <since_tizen> 3 </since_tizen>
99         /// <param name="alias">The name of a certificate to be stored.</param>
100         /// <param name="cert">The certificate's binary value to be stored.</param>
101         /// <param name="policy">
102         /// The policy about how to store a certificate securely.
103         /// </param>
104         /// <exception cref="ArgumentNullException">
105         /// Any of argument is null.
106         /// </exception>
107         /// <exception cref="ArgumentException">
108         /// Alias argument is invalid format. cert argument is invalid format.
109         /// </exception>
110         /// <exception cref="InvalidOperationException">
111         /// Certificate with alias does already exist.
112         /// </exception>
113         static public void Save(string alias, Certificate cert, Policy policy)
114         {
115             if (alias == null || cert == null || policy == null)
116                 throw new ArgumentNullException("More than one of argument is null");
117
118             Interop.CheckNThrowException(
119                 Interop.CkmcManager.SaveCert(
120                     alias, cert.ToCkmcCert(), policy.ToCkmcPolicy()),
121                 "Failed to save certificate. alias=" + alias);
122         }
123
124         /// <summary>
125         /// Verifies a certificate chain and returns that chain.
126         /// </summary>
127         /// <since_tizen> 3 </since_tizen>
128         /// <param name="certificate">The certificate to be verified.</param>
129         /// <param name="untrustedCertificates">
130         /// The untrusted CA certificates to be used in verifying a certificate chain.
131         /// </param>
132         /// <returns>A newly created certificate chain.</returns>
133         /// <exception cref="ArgumentNullException">
134         /// certificate argument is null.
135         /// </exception>
136         /// <exception cref="ArgumentException">
137         /// Some of certificate in arguments is invalid.
138         /// </exception>
139         /// <exception cref="InvalidOperationException">
140         /// Some of certificate in arguments is expired or not valid yet.
141         /// Certificate cannot build chain.
142         /// Root certificate is not in trusted system certificate store.
143         /// </exception>
144         /// <remarks>
145         /// The trusted root certificate of the chain should exist in the system's
146         /// certificate storage.
147         /// </remarks>
148         /// <remarks>
149         /// The trusted root certificate of the chain in system's certificate storage
150         /// is added to the certificate chain.
151         /// </remarks>
152         static public IEnumerable<Certificate> GetCertificateChain(
153             Certificate certificate, IEnumerable<Certificate> untrustedCertificates)
154         {
155             if (certificate == null)
156                 throw new ArgumentNullException("Certificate is null");
157
158             IntPtr ptrCertChain = IntPtr.Zero;
159             IntPtr certPtr = IntPtr.Zero;
160             IntPtr untrustedPtr = IntPtr.Zero;
161
162             try
163             {
164                 var untrusted = new SafeCertificateListHandle(untrustedCertificates);
165
166                 certPtr = certificate.GetHandle();
167                 untrustedPtr = untrusted.GetHandle();
168
169                 Interop.CheckNThrowException(
170                     Interop.CkmcManager.GetCertChain(
171                         certPtr, untrustedPtr,
172                         out ptrCertChain),
173                     "Failed to get certificate chain");
174
175                 return new SafeCertificateListHandle(ptrCertChain).Certificates;
176             }
177             finally
178             {
179                 if (certPtr != IntPtr.Zero)
180                     Interop.CkmcTypes.CertFree(certPtr);
181                 if (untrustedPtr != IntPtr.Zero)
182                     Interop.CkmcTypes.CertListAllFree(untrustedPtr);
183             }
184         }
185
186         /// <summary>
187         /// Verifies a certificate chain and returns that chain using user entered
188         /// trusted and untrusted CA certificates.
189         /// </summary>
190         /// <since_tizen> 3 </since_tizen>
191         /// <param name="certificate">The certificate to be verified.</param>
192         /// <param name="untrustedCertificates">
193         /// The untrusted CA certificates to be used in verifying a certificate chain.
194         /// </param>
195         /// <param name="trustedCertificates">
196         /// The trusted CA certificates to be used in verifying a certificate chain.
197         /// </param>
198         /// <param name="useTrustedSystemCertificates">
199         /// The flag indicating the use of the trusted root certificates in the
200         /// system's certificate storage.
201         /// </param>
202         /// <returns>A newly created certificate chain.</returns>
203         /// <exception cref="ArgumentNullException">
204         /// certificate argument is null.
205         /// </exception>
206         /// <exception cref="ArgumentException">
207         /// Some of certificate in arguments is invalid.
208         /// </exception>
209         /// <exception cref="InvalidOperationException">
210         /// Some of certificate in arguments is expired or not valid yet.
211         /// Certificate cannot build chain.
212         /// Root certificate is not in trusted system certificate store.
213         /// </exception>
214         /// <remarks>
215         /// The trusted root certificate of the chain in system's certificate storage
216         /// is added to the certificate chain.
217         /// </remarks>
218         static public IEnumerable<Certificate> GetCertificateChain(
219             Certificate certificate, IEnumerable<Certificate> untrustedCertificates,
220             IEnumerable<Certificate> trustedCertificates,
221             bool useTrustedSystemCertificates)
222         {
223             if (certificate == null)
224                 throw new ArgumentNullException("Certificate is null");
225
226             IntPtr certPtr = IntPtr.Zero;
227             IntPtr untrustedPtr = IntPtr.Zero;
228             IntPtr trustedPtr = IntPtr.Zero;
229             IntPtr ptrCertChain = IntPtr.Zero;
230
231             try
232             {
233                 var untrusted = new SafeCertificateListHandle(untrustedCertificates);
234                 var trusted = new SafeCertificateListHandle(trustedCertificates);
235
236                 certPtr = certificate.GetHandle();
237                 untrustedPtr = untrusted.GetHandle();
238                 trustedPtr = trusted.GetHandle();
239
240                 Interop.CheckNThrowException(
241                     Interop.CkmcManager.GetCertChainWithTrustedCerts(
242                         certPtr, untrustedPtr, trustedPtr,
243                         useTrustedSystemCertificates, out ptrCertChain),
244                     "Failed to get certificate chain with trusted certificates");
245                 return new SafeCertificateListHandle(ptrCertChain).Certificates;
246             }
247             finally
248             {
249                 if (certPtr != IntPtr.Zero)
250                     Interop.CkmcTypes.CertFree(certPtr);
251                 if (untrustedPtr != IntPtr.Zero)
252                     Interop.CkmcTypes.CertListAllFree(untrustedPtr);
253                 if (trustedPtr != IntPtr.Zero)
254                     Interop.CkmcTypes.CertListAllFree(trustedPtr);
255             }
256         }
257
258         /// <summary>
259         /// Perform OCSP which checks certificate is whether revoked or not.
260         /// </summary>
261         /// <since_tizen> 3 </since_tizen>
262         /// <param name="certificateChain">
263         /// Valid certificate chain to perform OCSP check.
264         /// </param>
265         /// <returns>A status result of OCSP check.</returns>
266         /// <exception cref="ArgumentNullException">
267         /// certificateChain argument is null.
268         /// </exception>
269         /// <exception cref="ArgumentException">
270         /// certificateChain is not valid chain or certificate.
271         /// </exception>
272         /// <exception cref="InvalidOperationException">
273         /// some of certificate in chain is expired or not valid yet.
274         /// </exception>
275         static public OcspStatus CheckOcsp(IEnumerable<Certificate> certificateChain)
276         {
277             if (certificateChain == null)
278                 throw new ArgumentNullException("Certificate chain is null");
279
280             IntPtr ptr = IntPtr.Zero;
281
282             try
283             {
284                 int ocspStatus = (int)OcspStatus.Good;
285                 var certChain = new SafeCertificateListHandle(certificateChain);
286
287                 ptr = certChain.GetHandle();
288
289                 Interop.CheckNThrowException(
290                     Interop.CkmcManager.OcspCheck(ptr, ref ocspStatus),
291                     "Failed to get certificate chain with trusted certificates");
292                 return (OcspStatus)ocspStatus;
293             }
294             finally
295             {
296                 if (ptr != IntPtr.Zero)
297                     Interop.CkmcTypes.CertListAllFree(ptr);
298             }
299         }
300
301         // to be static class safely
302         internal CertificateManager()
303         {
304         }
305     }
306 }