Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Security.SecureRepository / Tizen.Security.SecureRepository / Crypto / Signature.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
19 namespace Tizen.Security.SecureRepository.Crypto
20 {
21     /// <summary>
22     /// This class provides the methods creating and verifying a signature.
23     /// </summary>
24     /// <since_tizen> 3 </since_tizen>
25     public class Signature
26     {
27         private SignatureParameters _parameters;
28
29         /// <summary>
30         /// A constructor of Signature that takes the algorithm specific parameters.
31         /// </summary>
32         /// <since_tizen> 3 </since_tizen>
33         /// <param name="parameters">The algorithm specific parameters.</param>
34         public Signature(SignatureParameters parameters)
35         {
36             _parameters = parameters;
37         }
38
39         /// <summary>
40         /// The algorithm specific parameters.
41         /// </summary>
42         /// <since_tizen> 3 </since_tizen>
43         public SignatureParameters Parameters
44         {
45             get { return _parameters; }
46         }
47
48         /// <summary>
49         /// Creates a signature on a given message using a private key and returns
50         /// the signature.
51         /// </summary>
52         /// <since_tizen> 3 </since_tizen>
53         /// <param name="privateKeyAlias">The name of private key.</param>
54         /// <param name="password">
55         /// The password used in decrypting a private key value.
56         /// </param>
57         /// <param name="message">The message that is signed with a private key.</param>
58         /// <returns>A newly created signature.</returns>
59         /// <exception cref="ArgumentNullException">
60         /// privateKeyAlias or message is null.
61         /// </exception>
62         /// <exception cref="ArgumentException">
63         /// privateKeyAlias is invalid format.
64         /// </exception>
65         /// <exception cref="InvalidOperationException">
66         /// Key-protecting password isn't matched.
67         /// Key does not exist with privateKeyAlias.
68         /// </exception>
69         /// <remarks>
70         /// The key type specified by privateKeyAlias should be compatible with the
71         /// algorithm specified in Parameters.
72         /// </remarks>
73         /// <remarks>
74         /// If password of policy is provided during storing a key, the same password
75         /// should be provided.
76         /// </remarks>
77         public byte[] Sign(string privateKeyAlias, string password, byte[] message)
78         {
79             if (privateKeyAlias == null || message == null)
80                 throw new ArgumentNullException("alias and message should not be null");
81
82             int hash = (int)HashAlgorithm.None;
83             try
84             {
85                 hash = (int)Parameters.Get(SignatureParameterName.HashAlgorithm);
86             }
87             catch {}
88
89             int rsaPadding = (int)RsaPaddingAlgorithm.None;
90             try
91             {
92                 rsaPadding = (int)Parameters.Get(SignatureParameterName.RsaPaddingAlgorithm);
93             }
94             catch {}
95
96             IntPtr ptr = IntPtr.Zero;
97
98             try
99             {
100                 Interop.CheckNThrowException(
101                     Interop.CkmcManager.CreateSignature(
102                         privateKeyAlias, password,
103                         new Interop.CkmcRawBuffer(
104                             new PinnedObject(message), message.Length),
105                         hash, rsaPadding, out ptr),
106                     "Failed to generate signature");
107                 return new SafeRawBufferHandle(ptr).Data;
108             }
109             finally
110             {
111                 if (ptr != IntPtr.Zero)
112                     Interop.CkmcTypes.BufferFree(ptr);
113             }
114         }
115
116         /// <summary>
117         /// Verifies a given signature on a given message using a public key and returns
118         /// the signature status.
119         /// </summary>
120         /// <since_tizen> 3 </since_tizen>
121         /// <param name="publicKeyAlias">The name of public key.</param>
122         /// <param name="password">
123         /// The password used in decrypting a public key value.
124         /// </param>
125         /// <param name="message">The input on which the signature is created.</param>
126         /// <param name="signature">The signature that is verified with public key.</param>
127         /// <returns>
128         /// The signature status. True is returned when the signature is valid.
129         /// </returns>
130         /// <exception cref="ArgumentNullException">
131         /// publicKeyAlias, message or signature is null.
132         /// </exception>
133         /// <exception cref="ArgumentException">
134         /// publicKeyAlias is invalid format.
135         /// </exception>
136         /// <exception cref="InvalidOperationException">
137         /// Key-protecting password isn't matched.
138         /// Key does not exist with publicKeyAlias.
139         /// </exception>
140         /// <remarks>
141         /// The key type specified by publicKeyAlias should be compatible with the
142         /// algorithm specified in Parameters.
143         /// </remarks>
144         /// <remarks>
145         /// If password of policy is provided during storing a key, the same password
146         /// should be provided.
147         /// </remarks>
148         public bool Verify(
149             string publicKeyAlias, string password, byte[] message, byte[] signature)
150         {
151             if (publicKeyAlias == null || message == null || signature == null)
152                 throw new ArgumentNullException("mandatory arg should not be null");
153
154             int hash = (int)HashAlgorithm.None;
155             try
156             {
157                 hash = (int)Parameters.Get(SignatureParameterName.HashAlgorithm);
158             }
159             catch {}
160
161             int rsaPadding = (int)RsaPaddingAlgorithm.None;
162             try
163             {
164                 rsaPadding = (int)Parameters.Get(SignatureParameterName.RsaPaddingAlgorithm);
165             }
166             catch {}
167
168
169             int ret = Interop.CkmcManager.VerifySignature(
170                 publicKeyAlias,
171                 password,
172                 new Interop.CkmcRawBuffer(new PinnedObject(message), message.Length),
173                 new Interop.CkmcRawBuffer(new PinnedObject(signature), signature.Length),
174                 hash,
175                 rsaPadding);
176
177             if (ret == (int)Interop.KeyManagerError.VerificationFailed)
178                 return false;
179             Interop.CheckNThrowException(ret, "Failed to verify signature");
180
181             return true;
182         }
183     }
184 }