Add RSA OAEP support
[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     if (!alg.getParam(paramName, result)) {
42         ThrowErr(Exc::Crypto::InputParam, "Wrong input param");
43     }
44     return result;
45 }
46
47
48 ////////// Validators //////////////
49
50 // Always validates as true. Useful for checking parameter existence only
51 template <typename T>
52 struct DefaultValidator {
53     static bool Check(const T&) { return true; }
54     static void Why(std::ostringstream& os) { os << "is ok"; }
55 };
56
57 // Validates as true if parameter value is equal to one of Args
58 template <typename T>
59 struct Type {
60     template <T ...Args>
61     struct Equals;
62
63     template <T First>
64     struct Equals<First> {
65     public:
66         static bool Check(const T& value) {
67             return First == value;
68         }
69         static void Why(std::ostringstream& os) {
70             os << "doesn't match " << static_cast<int>(First);
71         }
72     };
73
74     template <T First, T ...Args>
75     struct Equals<First, Args...> : public Equals<First>, public Equals<Args...> {
76     public:
77         static bool Check(const T& value) {
78             return Equals<First>::Check(value) || Equals<Args...>::Check(value);
79         }
80         static void Why(std::ostringstream& os) {
81             Equals<First>::Why(os);
82             os << ", ";
83             Equals<Args...>::Why(os);
84         }
85     };
86 };
87
88 template <typename T>
89 struct Unsupported {
90     static bool Check(const T&) { return false; }
91     static void Why(std::ostringstream& os) { os << "is not supported"; }
92 };
93
94
95 ////////// Getters //////////////
96
97 // simply returns parameter value
98 template <typename T>
99 struct DefaultGetter {
100     static T Get(const T& value) { return value; }
101     static void What(std::ostringstream& os) { os << "value"; }
102     static void Print(std::ostringstream& os, const T& value) { os << static_cast<int>(value); }
103 };
104
105 template <>
106 void DefaultGetter<RawBuffer>::Print(std::ostringstream& os, const RawBuffer& buffer) {
107     os << "[" << buffer.size() << "B buffer]";
108 }
109
110 // returns buffer param size
111 struct BufferSizeGetter {
112     static size_t Get(const RawBuffer& buffer) { return buffer.size(); }
113     static void What(std::ostringstream& os) { os << "buffer size"; }
114     static void Print(std::ostringstream& os, const RawBuffer& buffer) { os << buffer.size(); }
115 };
116
117
118 ////////// ErrorHandlers //////////////
119
120 struct ThrowingHandler {
121     static void Handle(std::string message) {
122         ThrowErr(Exc::Crypto::InputParam, message);
123     }
124 };
125
126
127 // base class for parameter check
128 struct ParamCheckBase {
129     virtual ~ParamCheckBase() {}
130     virtual void Check(const CryptoAlgorithm& ca) const = 0;
131 };
132
133 typedef std::unique_ptr<const ParamCheckBase> ParamCheckBasePtr;
134
135 typedef std::vector<ParamCheckBasePtr> ValidatorVector;
136
137
138 // ValidatorVector builder. Creates a vector of ParamCheckBasePtr's specified as Args
139 template <typename ...Args>
140 struct VBuilder;
141
142 template <>
143 struct VBuilder<> {
144 static ValidatorVector Build() {
145         return ValidatorVector();
146     }
147 };
148
149 template <typename First>
150 struct VBuilder<First> {
151 static ValidatorVector Build() {
152         ValidatorVector validators;
153         Add(validators);
154         return validators;
155     }
156 protected:
157     static void Add(ValidatorVector& validators) {
158         validators.emplace_back(new First);
159     }
160 };
161
162 template <typename First, typename ...Args>
163 struct VBuilder<First, Args...> : public VBuilder<First>, public VBuilder<Args...> {
164     static ValidatorVector Build() {
165         ValidatorVector validators;
166         Add(validators);
167         return validators;
168     }
169 protected:
170     static void Add(ValidatorVector& validators) {
171         VBuilder<First>::Add(validators);
172         VBuilder<Args...>::Add(validators);
173     }
174 };
175
176 /*
177  * Generic struct responsible for checking a single constraint on given algorithm parameter
178  *
179  * Name - name of param to check
180  * Type - type of param value
181  * Mandatory - true if param is mandatory
182  * Validator - class providing validation function bool Check(const CryptoAlgorithm&)
183  * Getter - gets the value used for validation (param value itself or a buffer size for example)
184  * ErrorHandler - class providing method for error handling void Handle(std::string)
185  */
186
187 template <ParamName Name,
188           typename Type,
189           bool Mandatory,
190           typename Validator = DefaultValidator<Type>,
191           typename Getter = DefaultGetter<Type>,
192           typename ErrorHandler = ThrowingHandler>
193 struct ParamCheck : public ParamCheckBase {
194     void Check(const CryptoAlgorithm& ca) const {
195         Type value;
196         std::ostringstream os;
197
198         // check existence
199         if(!ca.getParam(Name,value)) {
200             if (Mandatory) {
201                 os << "Mandatory parameter " << static_cast<int>(Name) << " doesn't exist";
202                 ErrorHandler::Handle(os.str());
203             }
204             return;
205         }
206         // validate
207         if(!Validator::Check(Getter::Get(value))) {
208             os << "The ";
209             Getter::What(os);
210             os << " of param '" << static_cast<int>(Name) << "'=";
211             Getter::Print(os, value);
212             os << " ";
213             Validator::Why(os);
214             ErrorHandler::Handle(os.str());
215         }
216     }
217 };
218
219 } // namespace Crypto
220 } // namespace CKM