Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Security.SecureRepository / Tizen.Security.SecureRepository / Pkcs12.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 System.Runtime.InteropServices;
20 using static Interop;
21
22 namespace Tizen.Security.SecureRepository
23 {
24     /// <summary>
25     /// Class that represents a PKCS#12 contents.
26     /// It has a private key or its certificate or all the members of a chain of trust.
27     /// </summary>
28     /// <since_tizen> 3 </since_tizen>
29     public class Pkcs12
30     {
31         private SafeCertificateListHandle _certChainHandle = null;
32
33         /// <summary>
34         /// Load Pkcs12 from the given PKCS#12 file path.
35         /// </summary>
36         /// <since_tizen> 3 </since_tizen>
37         /// <param name="filePath">The path of PKCS12 file to be loaded.</param>
38         /// <param name="filePassword">The passphrase used to decrypt the PCKS12 file.
39         /// If PKCS12 file is not encrypted, passphrase can be null.</param>
40         /// <exception cref="ArgumentNullException">filePath is null.</exception>
41         /// <exception cref="InvalidOperationException">
42         /// No file on filePath.
43         /// No permission to access file.
44         /// File is invalid PKCS12 format.
45         /// File cannot be extracted with provided filePassword.
46         /// </exception>
47         static public Pkcs12 Load(string filePath, string filePassword)
48         {
49             if (filePath == null)
50                 throw new ArgumentNullException("filePath should not be null");
51
52             IntPtr ptr = IntPtr.Zero;
53
54             try
55             {
56                 Interop.CheckNThrowException(
57                     Interop.CkmcTypes.Pkcs12Load(filePath, filePassword, out ptr),
58                     "Failed to load PKCS12. file=" + filePath);
59                 return new Pkcs12(ptr);
60             }
61             finally
62             {
63                 if (ptr != IntPtr.Zero)
64                     Interop.CkmcTypes.Pkcs12Free(ptr);
65             }
66         }
67
68         /// <summary>
69         /// A constructor of Key that takes a private key.
70         /// </summary>
71         /// <since_tizen> 3 </since_tizen>
72         /// <param name="privateKey">A private key.</param>
73         public Pkcs12(Key privateKey)
74         {
75             this.PrivateKey = privateKey;
76             this.Certificate = null;
77             this.CaChain = null;
78         }
79
80         /// <summary>
81         /// A constructor of Key that takes a private key, its corresponding certicate,
82         /// and CA's certificate chain.
83         /// </summary>
84         /// <since_tizen> 3 </since_tizen>
85         /// <param name="privateKey">A private key.</param>
86         /// <param name="certificate">A certificate corresponding the private key</param>
87         /// <param name="caChain">
88         /// A certificate chain of CA(Certificate Authority) that issued the certificate.
89         /// </param>
90         public Pkcs12(Key privateKey,
91                       Certificate certificate,
92                       IEnumerable<Certificate> caChain)
93         {
94             this.PrivateKey = privateKey;
95             this.Certificate = certificate;
96             this.CaChain = caChain;
97         }
98
99         internal Pkcs12(IntPtr ptr)
100         {
101             var ckmcPkcs12 = Marshal.PtrToStructure<Interop.CkmcPkcs12>(ptr);
102
103             this.PrivateKey = new Key(ckmcPkcs12.privateKey);
104             if (ckmcPkcs12.certificate != IntPtr.Zero)
105                 this.Certificate = new Certificate(ckmcPkcs12.certificate);
106             if (ckmcPkcs12.caChain != IntPtr.Zero)
107                 this._certChainHandle = new SafeCertificateListHandle(ckmcPkcs12.caChain);
108         }
109
110         internal IntPtr GetHandle()
111         {
112             IntPtr keyPtr = IntPtr.Zero;
113             IntPtr certPtr = IntPtr.Zero;
114             IntPtr cacertPtr = IntPtr.Zero;
115             IntPtr p12Ptr = IntPtr.Zero;
116             try
117             {
118                 keyPtr = this.PrivateKey.GetHandle();
119
120                 if (this.Certificate != null)
121                     certPtr = this.Certificate.GetHandle();
122
123                 if (this._certChainHandle != null)
124                     cacertPtr = this._certChainHandle.GetHandle();
125
126                 Interop.CheckNThrowException(
127                     Interop.CkmcTypes.Pkcs12New(keyPtr, certPtr, cacertPtr, out p12Ptr),
128                     "Failed to create pkcs12");
129
130                 return p12Ptr;
131             }
132             catch
133             {
134                 if (p12Ptr != IntPtr.Zero)
135                 {
136                     Interop.CkmcTypes.Pkcs12Free(p12Ptr);
137                 }
138                 else
139                 {
140                     if (keyPtr != IntPtr.Zero)
141                         Interop.CkmcTypes.KeyFree(keyPtr);
142                     if (certPtr != IntPtr.Zero)
143                         Interop.CkmcTypes.CertFree(certPtr);
144                     if (cacertPtr != IntPtr.Zero)
145                         Interop.CkmcTypes.CertListAllFree(cacertPtr);
146                 }
147
148                 throw;
149             }
150         }
151
152         /// <summary>
153         /// A private key.
154         /// </summary>
155         /// <since_tizen> 3 </since_tizen>
156         public Key PrivateKey
157         {
158             get; set;
159         }
160
161         /// <summary>
162         /// A certificate corresponding the private key.
163         /// </summary>
164         /// <since_tizen> 3 </since_tizen>
165         public Certificate Certificate
166         {
167             get; set;
168         }
169
170         /// <summary>
171         /// A certificate chain of CA(Certificate Authority) that issued the certificate.
172         /// </summary>
173         /// <since_tizen> 3 </since_tizen>
174         public IEnumerable<Certificate> CaChain
175         {
176             get
177             {
178                 if (this._certChainHandle == null)
179                     return null;
180                 else
181                     return this._certChainHandle.Certificates;
182             }
183             set
184             {
185                 if (value == null)
186                     this._certChainHandle = null;
187                 else
188                     this._certChainHandle = new SafeCertificateListHandle(value);
189             }
190         }
191     }
192 }