Release 0.1.65
[platform/core/security/key-manager.git] / common / base64_generic.cpp
1 /*
2  * Copyright (c) 2020 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 #include <base64_generic.h>
18 #include <utils.h>
19
20 #include <algorithm>
21 #include <cctype>
22 #include <memory>
23 #include <stdexcept>
24
25 #include <openssl/bio.h>
26 #include <openssl/evp.h>
27
28 namespace {
29
30 bool isBase64Char(char c)
31 {
32         return isalnum(c) || c == '+' || c == '/' || c == '=';
33 }
34
35 auto makeBioPtr(BIO* ptr)
36 {
37         if (!ptr)
38                 throw std::bad_alloc();
39         return uptr<BIO_free>(ptr);
40 }
41
42 } // anonymous namespace
43
44 int base64EncodeGenericImpl(const void* input, size_t inputLen, void* output)
45 {
46         return EVP_EncodeBlock(reinterpret_cast<unsigned char*>(output),
47                 reinterpret_cast<const unsigned char*>(input), inputLen);
48 }
49
50 int base64DecodeGenericImpl(const void* input, size_t inputLen, void* output, size_t outputLen)
51 {
52         if (inputLen == 0)
53                 return 0;
54         if (!std::all_of(static_cast<const char*>(input), static_cast<const char*>(input) + inputLen, isBase64Char))
55                 throw std::invalid_argument("decoding base64 failed, unexpected characters");
56
57         auto inputBio = makeBioPtr(BIO_new_mem_buf(input, inputLen));
58         auto base64Bio = makeBioPtr(BIO_new(BIO_f_base64()));
59         BIO_set_flags(base64Bio.get(), BIO_FLAGS_BASE64_NO_NL);
60         BIO_push(base64Bio.get(), inputBio.get());
61
62         int length = BIO_read(base64Bio.get(), output, outputLen);
63         if (length < 0)
64                 throw std::invalid_argument("decoding base64 failed, openssl bio api error");
65
66         return length;
67 }