Use new classes to sign and verify messages.
[platform/core/security/key-manager.git] / src / manager / crypto / sw-backend / key.cpp
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       key.cpp
18  * @author     BartÅ‚omiej Grzelewski (b.grzelewski@samsung.com)
19  * @version    1.0
20  */
21 #include <memory>
22
23 #include <openssl/bio.h>
24 #include <openssl/evp.h>
25 #include <openssl/x509.h>
26
27 #include <dpl/log/log.h>
28
29 #include <generic-backend/exception.h>
30 #include <sw-backend/key.h>
31 #include <sw-backend/internals.h>
32
33 #define EVP_SUCCESS 1   // DO NOTCHANGE THIS VALUE
34 #define EVP_FAIL    0   // DO NOTCHANGE THIS VALUE
35
36 namespace CKM {
37 namespace Crypto {
38 namespace SW {
39
40 typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr;
41
42 RawBuffer AKey::sign(
43     const CryptoAlgorithm &alg,
44     const RawBuffer &message)
45 {
46     return Internals::sign(getEvpShPtr().get(), alg, message);
47 }
48
49 int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign) {
50     return Internals::verify(getEvpShPtr().get(), alg, message, sign);
51 }
52
53 EvpShPtr AKey::getEvpShPtr() {
54     if (m_evp)
55         return m_evp;
56
57     EVP_PKEY *pkey = NULL;
58     BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
59
60     LogDebug("Start to parse key:");
61
62     if (!pkey) {
63         (void)BIO_reset(bio.get());
64         BIO_write(bio.get(), m_key.data(), m_key.size());
65         pkey = d2i_PrivateKey_bio(bio.get(), NULL);
66         LogDebug("Trying d2i_PrivateKey_bio Status: " << (void*)pkey);
67     }
68
69     if (!pkey) {
70         (void)BIO_reset(bio.get());
71         BIO_write(bio.get(), m_key.data(), m_key.size());
72         pkey = d2i_PUBKEY_bio(bio.get(), NULL);
73         LogDebug("Trying d2i_PUBKEY_bio Status: " << (void*)pkey);
74     }
75
76     if (!pkey) {
77         LogError("Failed to parse key");
78         ThrowMsg(Exception::InternalError, "Failed to parse key");
79     }
80
81     m_evp.reset(pkey, EVP_PKEY_free);
82     return m_evp;
83 }
84
85 EvpShPtr Cert::getEvpShPtr() {
86     if (m_evp)
87         return m_evp;
88
89     int size = static_cast<int>(m_key.size());
90     const unsigned char *ptr = reinterpret_cast<const unsigned char *>(m_key.data());
91
92     X509 *x509 = d2i_X509(NULL, &ptr, size);
93
94     if (!x509) {
95         LogError("Failed to parse certificate.");
96         ThrowMsg(Exception::InternalError, "Failed to parse certificate.");
97     }
98
99     m_evp.reset(X509_get_pubkey(x509), EVP_PKEY_free);
100     X509_free(x509);
101     return m_evp;
102 }
103
104 } // namespace SW
105 } // namespace Crypto
106 } // namespace CKM
107