Replace private implemetation with interface.
[platform/core/security/key-manager.git] / src / manager / common / certificate-impl.cpp
1 /* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
2  *
3  *  Licensed under the Apache License, Version 2.0 (the "License");
4  *  you may not use this file except in compliance with the License.
5  *  You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  *  Unless required by applicable law or agreed to in writing, software
10  *  distributed under the License is distributed on an "AS IS" BASIS,
11  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  *  See the License for the specific language governing permissions and
13  *  limitations under the License
14  *
15  *
16  * @file        client-certificate-impl.cpp
17  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
18  * @version     1.0
19  * @brief       Key implementation.
20  */
21 #include <openssl/x509.h>
22 #include <openssl/x509v3.h>
23 #include <openssl/pem.h>
24
25 #include <dpl/log/log.h>
26
27 #include <generic-key.h>
28 #include <certificate-impl.h>
29 #include <base64.h>
30
31 namespace CKM {
32
33 CertificateImpl::CertificateImpl(const RawBuffer &der, DataFormat format)
34   : m_x509(NULL)
35 {
36     int size;
37     const unsigned char *ptr;
38     RawBuffer tmp;
39
40     LogDebug("Certificate to parse. Size: " << der.size());
41
42     if (DataFormat::FORM_DER_BASE64 == format) {
43         Base64Decoder base64;
44         base64.reset();
45         base64.append(der);
46         base64.finalize();
47         tmp = base64.get();
48         ptr = reinterpret_cast<const unsigned char*>(tmp.data());
49         size = static_cast<int>(tmp.size());
50         m_x509 = d2i_X509(NULL, &ptr, size);
51     } else if (DataFormat::FORM_DER == format) {
52         ptr = reinterpret_cast<const unsigned char*>(der.data());
53         size = static_cast<int>(der.size());
54         m_x509 = d2i_X509(NULL, &ptr, size);
55     } else if (DataFormat::FORM_PEM == format) {
56         BIO *buff = BIO_new(BIO_s_mem());
57         BIO_write(buff, der.data(), der.size());
58         m_x509 = PEM_read_bio_X509(buff, NULL, NULL, NULL);
59         BIO_free_all(buff);
60     } else {
61         // TODO
62         LogError("Unknown certificate format");
63     }
64
65     if (!m_x509) {
66         // TODO
67         LogError("Certificate could not be parsed.");
68 //        ThrowMsg(Exception::OpensslInternalError,
69 //          "Internal Openssl error in d2i_X509 function.");
70     }
71 }
72
73 CertificateImpl::CertificateImpl(X509 *x509)
74   : m_x509(X509_dup(x509))
75 {}
76
77 CertificateImpl::CertificateImpl(const CertificateImpl &second){
78     m_x509 = X509_dup(second.m_x509);
79 }
80
81 CertificateImpl::CertificateImpl(CertificateImpl &&second) {
82     m_x509 = second.m_x509;
83     second.m_x509 = NULL;
84     LogDebug("Certificate moved: " << (void*)m_x509);
85 }
86
87 CertificateImpl& CertificateImpl::operator=(CertificateImpl &&second) {
88     if (this == &second)
89         return *this;
90     X509_free(m_x509);
91     m_x509 = second.m_x509;
92     second.m_x509 = NULL;
93     LogDebug("Certificate moved: " << (void*)m_x509);
94     return *this;
95 }
96
97 CertificateImpl& CertificateImpl::operator=(const CertificateImpl &second) {
98     if (this == &second)
99         return *this;
100     X509_free(m_x509);
101     m_x509 = X509_dup(second.m_x509);
102     return *this;
103 }
104
105 X509* CertificateImpl::getX509() const {
106     return m_x509;
107 }
108
109 RawBuffer CertificateImpl::getDER(void) const {
110     unsigned char *rawDer = NULL;
111     int size = i2d_X509(m_x509, &rawDer);
112     if (!rawDer || size <= 0) {
113         LogError("i2d_X509 failed");
114         return RawBuffer();
115     }
116
117     RawBuffer output(
118         reinterpret_cast<char*>(rawDer),
119         reinterpret_cast<char*>(rawDer) + size);
120     OPENSSL_free(rawDer);
121     return output;
122 }
123
124 bool CertificateImpl::empty() const {
125     return m_x509 == NULL;
126 }
127
128 GenericKey::EvpShPtr CertificateImpl::getEvpShPtr() const {
129     return GenericKey::EvpShPtr(X509_get_pubkey(m_x509), EVP_PKEY_free);
130 }
131
132 GenericKey CertificateImpl::getGenericKey() const {
133     GenericKey::EvpShPtr evp(X509_get_pubkey(m_x509), EVP_PKEY_free);
134     if (EVP_PKEY_type(evp->type) == EVP_PKEY_RSA)
135         return GenericKey(evp, KeyType::KEY_RSA_PUBLIC);
136     if (EVP_PKEY_type(evp->type) == EVP_PKEY_EC)
137         return GenericKey(evp, KeyType::KEY_ECDSA_PUBLIC);
138     LogError("Unsupported key type in certificate.");
139     return GenericKey();
140 }
141
142 X509_NAME *getX509Name(X509 *x509, CertificateFieldId type) {
143     if (!x509)
144         return NULL;
145
146     if (type == CertificateFieldId::ISSUER)
147         return X509_get_issuer_name(x509);
148     else if (type == CertificateFieldId::SUBJECT)
149         return X509_get_subject_name(x509);
150
151     LogError("Invalid param. Unknown CertificateFieldId");
152     return NULL;
153 }
154
155 std::string CertificateImpl::getOneLine(CertificateFieldId type) const
156 {
157     X509_NAME *name = getX509Name(m_x509, type);
158     if (!name)
159         return std::string();
160     static const int MAXB = 1024;
161     char buffer[MAXB];
162     X509_NAME_oneline(name, buffer, MAXB);
163     return std::string(buffer);
164 }
165
166 std::string CertificateImpl::getField(CertificateFieldId type, int fieldNid) const {
167     X509_NAME *subjectName = getX509Name(m_x509, type);
168     X509_NAME_ENTRY *subjectEntry = NULL;
169
170     if (!subjectName)
171         return std::string();
172
173     int entryCount = X509_NAME_entry_count(subjectName);
174
175     for (int i = 0; i < entryCount; ++i) {
176         subjectEntry = X509_NAME_get_entry(subjectName, i);
177
178         if (!subjectEntry) {
179             continue;
180         }
181
182         int nid = OBJ_obj2nid(
183             static_cast<ASN1_OBJECT*>(
184                     X509_NAME_ENTRY_get_object(subjectEntry)));
185
186         if (nid != fieldNid) {
187             continue;
188         }
189
190         ASN1_STRING* pASN1Str = subjectEntry->value;
191
192         unsigned char* pData = NULL;
193         int nLength = ASN1_STRING_to_UTF8(&pData, pASN1Str);
194
195         if (nLength < 0) {
196             LogError("Reading field error.");
197             return std::string();
198         }
199
200         std::string output(reinterpret_cast<char*>(pData), nLength);
201         OPENSSL_free(pData);
202         return output;
203     }
204     return std::string();
205 }
206
207 std::string CertificateImpl::getCommonName(CertificateFieldId type) const {
208     return getField(type, NID_commonName);
209 }
210
211 std::string CertificateImpl::getCountryName(CertificateFieldId type) const {
212     return getField(type, NID_countryName);
213 }
214
215 std::string CertificateImpl::getStateOrProvinceName(CertificateFieldId type) const {
216     return getField(type, NID_stateOrProvinceName);
217 }
218
219 std::string CertificateImpl::getLocalityName(CertificateFieldId type) const {
220     return getField(type, NID_localityName);
221 }
222
223 std::string CertificateImpl::getOrganizationName(CertificateFieldId type) const {
224     return getField(type, NID_organizationName);
225 }
226
227 std::string CertificateImpl::getOrganizationalUnitName(CertificateFieldId type) const {
228     return getField(type, NID_organizationalUnitName);
229 }
230
231 std::string CertificateImpl::getEmailAddres(CertificateFieldId type) const {
232     return getField(type, NID_pkcs9_emailAddress);
233 }
234
235 std::string CertificateImpl::getOCSPURL() const {
236     if (!m_x509)
237         return std::string();
238
239     STACK_OF(OPENSSL_STRING) *aia = X509_get1_ocsp(m_x509);
240
241     if (NULL == aia)
242         return std::string();
243
244     std::string result(sk_OPENSSL_STRING_value(aia, 0));
245     X509_email_free(aia);   // TODO is it correct?
246     return result;
247 }
248
249 CertificateImpl::~CertificateImpl() {
250     LogDebug("free cert start ptr: " << (void*)m_x509);
251     X509_free(m_x509);
252     LogDebug("free cert end");
253 }
254
255 CertificateShPtr Certificate::create(const RawBuffer &rawBuffer, DataFormat format) {
256     CertificateShPtr output(new CertificateImpl(rawBuffer, format));
257     if (output.get() == NULL)
258         output.reset();
259     return output;
260 }
261
262 } // namespace CKM
263