Change RawBuffer into SafeBuffer.
[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 <buffer-conversion.h>
28 #include <generic-key.h>
29 #include <certificate-impl.h>
30 #include <base64.h>
31
32 namespace CKM {
33
34 CertificateImpl::CertificateImpl(const RawBuffer &der, DataFormat format)
35   : m_x509(NULL)
36 {
37     int size;
38     const unsigned char *ptr;
39     SafeBuffer tmp;
40
41     LogDebug("Certificate to parse. Size: " << der.size());
42
43     if (DataFormat::FORM_DER_BASE64 == format) {
44         Base64Decoder base64;
45         base64.reset();
46         base64.append(toSafeBuffer(der));
47         base64.finalize();
48         tmp = base64.get();
49         ptr = reinterpret_cast<const unsigned char*>(tmp.data());
50         size = static_cast<int>(tmp.size());
51         m_x509 = d2i_X509(NULL, &ptr, size);
52     } else if (DataFormat::FORM_DER == format) {
53         ptr = reinterpret_cast<const unsigned char*>(der.data());
54         size = static_cast<int>(der.size());
55         m_x509 = d2i_X509(NULL, &ptr, size);
56     } else if (DataFormat::FORM_PEM == format) {
57         BIO *buff = BIO_new(BIO_s_mem());
58         BIO_write(buff, der.data(), der.size());
59         m_x509 = PEM_read_bio_X509(buff, NULL, NULL, NULL);
60         BIO_free_all(buff);
61     } else {
62         // TODO
63         LogError("Unknown certificate format");
64     }
65
66     if (!m_x509) {
67         // TODO
68         LogError("Certificate could not be parsed.");
69 //        ThrowMsg(Exception::OpensslInternalError,
70 //          "Internal Openssl error in d2i_X509 function.");
71     }
72 }
73
74 CertificateImpl::CertificateImpl(const SafeBuffer &der, DataFormat format)
75   : m_x509(NULL)
76 {
77     int size;
78     const unsigned char *ptr;
79     SafeBuffer tmp;
80
81     LogDebug("Certificate to parse. Size: " << der.size());
82
83     if (DataFormat::FORM_DER_BASE64 == format) {
84         Base64Decoder base64;
85         base64.reset();
86         base64.append(der);
87         base64.finalize();
88         tmp = base64.get();
89         ptr = reinterpret_cast<const unsigned char*>(tmp.data());
90         size = static_cast<int>(tmp.size());
91         m_x509 = d2i_X509(NULL, &ptr, size);
92     } else if (DataFormat::FORM_DER == format) {
93         ptr = reinterpret_cast<const unsigned char*>(der.data());
94         size = static_cast<int>(der.size());
95         m_x509 = d2i_X509(NULL, &ptr, size);
96     } else if (DataFormat::FORM_PEM == format) {
97         BIO *buff = BIO_new(BIO_s_mem());
98         BIO_write(buff, der.data(), der.size());
99         m_x509 = PEM_read_bio_X509(buff, NULL, NULL, NULL);
100         BIO_free_all(buff);
101     } else {
102         // TODO
103         LogError("Unknown certificate format");
104     }
105
106     if (!m_x509) {
107         // TODO
108         LogError("Certificate could not be parsed.");
109 //        ThrowMsg(Exception::OpensslInternalError,
110 //          "Internal Openssl error in d2i_X509 function.");
111     }
112 }
113
114 CertificateImpl::CertificateImpl(X509 *x509)
115   : m_x509(X509_dup(x509))
116 {}
117
118 CertificateImpl::CertificateImpl(const CertificateImpl &second){
119     m_x509 = X509_dup(second.m_x509);
120 }
121
122 CertificateImpl::CertificateImpl(CertificateImpl &&second) {
123     m_x509 = second.m_x509;
124     second.m_x509 = NULL;
125     LogDebug("Certificate moved: " << (void*)m_x509);
126 }
127
128 CertificateImpl& CertificateImpl::operator=(CertificateImpl &&second) {
129     if (this == &second)
130         return *this;
131     X509_free(m_x509);
132     m_x509 = second.m_x509;
133     second.m_x509 = NULL;
134     LogDebug("Certificate moved: " << (void*)m_x509);
135     return *this;
136 }
137
138 CertificateImpl& CertificateImpl::operator=(const CertificateImpl &second) {
139     if (this == &second)
140         return *this;
141     X509_free(m_x509);
142     m_x509 = X509_dup(second.m_x509);
143     return *this;
144 }
145
146 X509* CertificateImpl::getX509() const {
147     return m_x509;
148 }
149
150 RawBuffer CertificateImpl::getDER(void) const {
151     unsigned char *rawDer = NULL;
152     int size = i2d_X509(m_x509, &rawDer);
153     if (!rawDer || size <= 0) {
154         LogError("i2d_X509 failed");
155         return RawBuffer();
156     }
157
158     RawBuffer output(
159         reinterpret_cast<char*>(rawDer),
160         reinterpret_cast<char*>(rawDer) + size);
161     OPENSSL_free(rawDer);
162     return output;
163 }
164
165 SafeBuffer CertificateImpl::getDERSB(void) const {
166     unsigned char *rawDer = NULL;
167     int size = i2d_X509(m_x509, &rawDer);
168     if (!rawDer || size <= 0) {
169         LogError("i2d_X509 failed");
170         return SafeBuffer();
171     }
172
173     SafeBuffer output(
174         reinterpret_cast<char*>(rawDer),
175         reinterpret_cast<char*>(rawDer) + size);
176     OPENSSL_free(rawDer);
177     return output;
178 }
179
180 bool CertificateImpl::empty() const {
181     return m_x509 == NULL;
182 }
183
184 GenericKey::EvpShPtr CertificateImpl::getEvpShPtr() const {
185     return GenericKey::EvpShPtr(X509_get_pubkey(m_x509), EVP_PKEY_free);
186 }
187
188 GenericKey CertificateImpl::getGenericKey() const {
189     GenericKey::EvpShPtr evp(X509_get_pubkey(m_x509), EVP_PKEY_free);
190     if (EVP_PKEY_type(evp->type) == EVP_PKEY_RSA)
191         return GenericKey(evp, KeyType::KEY_RSA_PUBLIC);
192     if (EVP_PKEY_type(evp->type) == EVP_PKEY_EC)
193         return GenericKey(evp, KeyType::KEY_ECDSA_PUBLIC);
194     LogError("Unsupported key type in certificate.");
195     return GenericKey();
196 }
197
198 X509_NAME *getX509Name(X509 *x509, CertificateFieldId type) {
199     if (!x509)
200         return NULL;
201
202     if (type == CertificateFieldId::ISSUER)
203         return X509_get_issuer_name(x509);
204     else if (type == CertificateFieldId::SUBJECT)
205         return X509_get_subject_name(x509);
206
207     LogError("Invalid param. Unknown CertificateFieldId");
208     return NULL;
209 }
210
211 std::string CertificateImpl::getOneLine(CertificateFieldId type) const
212 {
213     X509_NAME *name = getX509Name(m_x509, type);
214     if (!name)
215         return std::string();
216     static const int MAXB = 1024;
217     char buffer[MAXB];
218     X509_NAME_oneline(name, buffer, MAXB);
219     return std::string(buffer);
220 }
221
222 std::string CertificateImpl::getField(CertificateFieldId type, int fieldNid) const {
223     X509_NAME *subjectName = getX509Name(m_x509, type);
224     X509_NAME_ENTRY *subjectEntry = NULL;
225
226     if (!subjectName)
227         return std::string();
228
229     int entryCount = X509_NAME_entry_count(subjectName);
230
231     for (int i = 0; i < entryCount; ++i) {
232         subjectEntry = X509_NAME_get_entry(subjectName, i);
233
234         if (!subjectEntry) {
235             continue;
236         }
237
238         int nid = OBJ_obj2nid(
239             static_cast<ASN1_OBJECT*>(
240                     X509_NAME_ENTRY_get_object(subjectEntry)));
241
242         if (nid != fieldNid) {
243             continue;
244         }
245
246         ASN1_STRING* pASN1Str = subjectEntry->value;
247
248         unsigned char* pData = NULL;
249         int nLength = ASN1_STRING_to_UTF8(&pData, pASN1Str);
250
251         if (nLength < 0) {
252             LogError("Reading field error.");
253             return std::string();
254         }
255
256         std::string output(reinterpret_cast<char*>(pData), nLength);
257         OPENSSL_free(pData);
258         return output;
259     }
260     return std::string();
261 }
262
263 std::string CertificateImpl::getCommonName(CertificateFieldId type) const {
264     return getField(type, NID_commonName);
265 }
266
267 std::string CertificateImpl::getCountryName(CertificateFieldId type) const {
268     return getField(type, NID_countryName);
269 }
270
271 std::string CertificateImpl::getStateOrProvinceName(CertificateFieldId type) const {
272     return getField(type, NID_stateOrProvinceName);
273 }
274
275 std::string CertificateImpl::getLocalityName(CertificateFieldId type) const {
276     return getField(type, NID_localityName);
277 }
278
279 std::string CertificateImpl::getOrganizationName(CertificateFieldId type) const {
280     return getField(type, NID_organizationName);
281 }
282
283 std::string CertificateImpl::getOrganizationalUnitName(CertificateFieldId type) const {
284     return getField(type, NID_organizationalUnitName);
285 }
286
287 std::string CertificateImpl::getEmailAddres(CertificateFieldId type) const {
288     return getField(type, NID_pkcs9_emailAddress);
289 }
290
291 std::string CertificateImpl::getOCSPURL() const {
292     if (!m_x509)
293         return std::string();
294
295     STACK_OF(OPENSSL_STRING) *aia = X509_get1_ocsp(m_x509);
296
297     if (NULL == aia)
298         return std::string();
299
300     std::string result(sk_OPENSSL_STRING_value(aia, 0));
301     X509_email_free(aia);   // TODO is it correct?
302     return result;
303 }
304
305 CertificateImpl::~CertificateImpl() {
306     LogDebug("free cert start ptr: " << (void*)m_x509);
307     X509_free(m_x509);
308     LogDebug("free cert end");
309 }
310
311 CertificateShPtr Certificate::create(const RawBuffer &rawBuffer, DataFormat format) {
312     CertificateShPtr output(new CertificateImpl(rawBuffer, format));
313     if (output.get() == NULL)
314         output.reset();
315     return output;
316 }
317
318 } // namespace CKM
319