dc14966920635db7e13651253539e6d3a910b62f
[platform/core/security/key-manager.git] / src / manager / crypto / generic-backend / algo-validation.h
1 /*
2  *  Copyright (c) 2000 - 2015 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  * @file       algo-validation.h
18  * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
19  * @version    1.0
20  */
21
22 #pragma once
23
24 #include <sstream>
25 #include <string>
26 #include <utility>
27
28 #include <ckm/ckm-type.h>
29
30 #include <exception.h>
31
32 namespace CKM {
33 namespace Crypto {
34
35 template<typename T>
36 T unpack(
37         const CryptoAlgorithm &alg,
38         ParamName paramName)
39 {
40         T result;
41
42         if (!alg.getParam(paramName, result))
43                 ThrowErr(Exc::Crypto::InputParam, "Wrong input param");
44
45         return result;
46 }
47
48
49 ////////// Validators //////////////
50
51 // Always validates as true. Useful for checking parameter existence only
52 template <typename T>
53 struct DefaultValidator {
54         static bool Check(const T &)
55         {
56                 return true;
57         }
58         static void Why(std::ostringstream &os)
59         {
60                 os << "is ok";
61         }
62 };
63
64 // Validates as true if parameter value is equal to one of Args
65 template <typename T>
66 struct Type {
67         template <T ...Args>
68         struct Equals;
69
70         template <T First>
71         struct Equals<First> {
72         public:
73                 static bool Check(const T &value)
74                 {
75                         return First == value;
76                 }
77
78                 static void Why(std::ostringstream &os)
79                 {
80                         os << "doesn't match " << static_cast<int>(First);
81                 }
82         };
83
84         template <T First, T ...Args>
85         struct Equals<First, Args...> : public Equals<First>, public Equals<Args...> {
86         public:
87                 static bool Check(const T &value)
88                 {
89                         return Equals<First>::Check(value) || Equals<Args...>::Check(value);
90                 }
91
92                 static void Why(std::ostringstream &os)
93                 {
94                         Equals<First>::Why(os);
95                         os << ", ";
96                         Equals<Args...>::Why(os);
97                 }
98         };
99 };
100
101 template <typename T>
102 struct Unsupported {
103         static bool Check(const T &)
104         {
105                 return false;
106         }
107         static void Why(std::ostringstream &os)
108         {
109                 os << "is not supported";
110         }
111 };
112
113
114 ////////// Getters //////////////
115
116 // simply returns parameter value
117 template <typename T>
118 struct DefaultGetter {
119         static T Get(const T &value)
120         {
121                 return value;
122         }
123         static void What(std::ostringstream &os)
124         {
125                 os << "value";
126         }
127         static void Print(std::ostringstream &os, const T &value)
128         {
129                 os << static_cast<int>(value);
130         }
131 };
132
133 template <>
134 inline void DefaultGetter<RawBuffer>::Print(std::ostringstream &os,
135                                                                          const RawBuffer &buffer)
136 {
137         os << "[" << buffer.size() << "B buffer]";
138 }
139
140 // returns buffer param size
141 struct BufferSizeGetter {
142         static size_t Get(const RawBuffer &buffer)
143         {
144                 return buffer.size();
145         }
146         static void What(std::ostringstream &os)
147         {
148                 os << "buffer size";
149         }
150         static void Print(std::ostringstream &os, const RawBuffer &buffer)
151         {
152                 os << buffer.size();
153         }
154 };
155
156
157 ////////// ErrorHandlers //////////////
158
159 struct ThrowingHandler {
160         static void Handle(std::string message)
161         {
162                 ThrowErr(Exc::Crypto::InputParam, message);
163         }
164 };
165
166
167 // base class for parameter check
168 struct ParamCheckBase {
169         virtual ~ParamCheckBase() {}
170         virtual void Check(const CryptoAlgorithm &ca) const = 0;
171 };
172
173 typedef std::unique_ptr<const ParamCheckBase> ParamCheckBasePtr;
174
175 typedef std::vector<ParamCheckBasePtr> ValidatorVector;
176
177
178 // ValidatorVector builder. Creates a vector of ParamCheckBasePtr's specified as Args
179 template <typename ...Args>
180 struct VBuilder;
181
182 template <>
183 struct VBuilder<> {
184         static ValidatorVector Build()
185         {
186                 return ValidatorVector();
187         }
188 };
189
190 template <typename First>
191 struct VBuilder<First> {
192         static ValidatorVector Build()
193         {
194                 ValidatorVector validators;
195                 Add(validators);
196                 return validators;
197         }
198 protected:
199         static void Add(ValidatorVector &validators)
200         {
201                 validators.emplace_back(new First);
202         }
203 };
204
205 template <typename First, typename ...Args>
206 struct VBuilder<First, Args...> : public VBuilder<First>,
207         public VBuilder<Args...> {
208         static ValidatorVector Build()
209         {
210                 ValidatorVector validators;
211                 Add(validators);
212                 return validators;
213         }
214
215 protected:
216         static void Add(ValidatorVector &validators)
217         {
218                 VBuilder<First>::Add(validators);
219                 VBuilder<Args...>::Add(validators);
220         }
221 };
222
223 /*
224  * Generic struct responsible for checking a single constraint on given algorithm parameter
225  *
226  * Name - name of param to check
227  * Type - type of param value
228  * Mandatory - true if param is mandatory
229  * Validator - class providing validation function bool Check(const CryptoAlgorithm&)
230  * Getter - gets the value used for validation (param value itself or a buffer size for example)
231  * ErrorHandler - class providing method for error handling void Handle(std::string)
232  */
233
234 template <ParamName Name,
235                   typename Type,
236                   bool Mandatory,
237                   typename Validator = DefaultValidator<Type>,
238                   typename Getter = DefaultGetter<Type>,
239                   typename ErrorHandler = ThrowingHandler>
240 struct ParamCheck : public ParamCheckBase {
241         void Check(const CryptoAlgorithm &ca) const
242         {
243                 Type value;
244                 std::ostringstream os;
245
246                 // check existence
247                 if (!ca.getParam(Name, value)) {
248                         if (Mandatory) {
249                                 os << "Mandatory parameter " << static_cast<int>(Name) << " doesn't exist";
250                                 ErrorHandler::Handle(os.str());
251                         }
252
253                         return;
254                 }
255
256                 // validate
257                 if (!Validator::Check(Getter::Get(value))) {
258                         os << "The ";
259                         Getter::What(os);
260                         os << " of param '" << static_cast<int>(Name) << "'=";
261                         Getter::Print(os, value);
262                         os << " ";
263                         Validator::Why(os);
264                         ErrorHandler::Handle(os.str());
265                 }
266         }
267 };
268
269 } // namespace Crypto
270 } // namespace CKM