1 /* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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
16 * @file client-certificate-impl.cpp
17 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19 * @brief Key implementation.
21 #include <openssl/x509.h>
22 #include <openssl/x509v3.h>
23 #include <openssl/pem.h>
25 #include <dpl/log/log.h>
27 #include <buffer-conversion.h>
28 #include <generic-key.h>
29 #include <certificate-impl.h>
34 CertificateImpl::CertificateImpl(const RawBuffer &der, DataFormat format)
38 const unsigned char *ptr;
41 LogDebug("Certificate to parse. Size: " << der.size());
43 if (DataFormat::FORM_DER_BASE64 == format) {
46 base64.append(toSafeBuffer(der));
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);
63 LogError("Unknown certificate format");
68 LogError("Certificate could not be parsed.");
69 // ThrowMsg(Exception::OpensslInternalError,
70 // "Internal Openssl error in d2i_X509 function.");
74 CertificateImpl::CertificateImpl(const SafeBuffer &der, DataFormat format)
78 const unsigned char *ptr;
81 LogDebug("Certificate to parse. Size: " << der.size());
83 if (DataFormat::FORM_DER_BASE64 == format) {
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);
103 LogError("Unknown certificate format");
108 LogError("Certificate could not be parsed.");
109 // ThrowMsg(Exception::OpensslInternalError,
110 // "Internal Openssl error in d2i_X509 function.");
114 CertificateImpl::CertificateImpl(X509 *x509)
115 : m_x509(X509_dup(x509))
118 CertificateImpl::CertificateImpl(const CertificateImpl &second){
119 m_x509 = X509_dup(second.m_x509);
122 CertificateImpl::CertificateImpl(CertificateImpl &&second) {
123 m_x509 = second.m_x509;
124 second.m_x509 = NULL;
125 LogDebug("Certificate moved: " << (void*)m_x509);
128 CertificateImpl& CertificateImpl::operator=(CertificateImpl &&second) {
132 m_x509 = second.m_x509;
133 second.m_x509 = NULL;
134 LogDebug("Certificate moved: " << (void*)m_x509);
138 CertificateImpl& CertificateImpl::operator=(const CertificateImpl &second) {
142 m_x509 = X509_dup(second.m_x509);
146 X509* CertificateImpl::getX509() const {
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");
159 reinterpret_cast<char*>(rawDer),
160 reinterpret_cast<char*>(rawDer) + size);
161 OPENSSL_free(rawDer);
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");
174 reinterpret_cast<char*>(rawDer),
175 reinterpret_cast<char*>(rawDer) + size);
176 OPENSSL_free(rawDer);
180 bool CertificateImpl::empty() const {
181 return m_x509 == NULL;
184 GenericKey::EvpShPtr CertificateImpl::getEvpShPtr() const {
185 return GenericKey::EvpShPtr(X509_get_pubkey(m_x509), EVP_PKEY_free);
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.");
198 X509_NAME *getX509Name(X509 *x509, CertificateFieldId type) {
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);
207 LogError("Invalid param. Unknown CertificateFieldId");
211 std::string CertificateImpl::getOneLine(CertificateFieldId type) const
213 X509_NAME *name = getX509Name(m_x509, type);
215 return std::string();
216 static const int MAXB = 1024;
218 X509_NAME_oneline(name, buffer, MAXB);
219 return std::string(buffer);
222 std::string CertificateImpl::getField(CertificateFieldId type, int fieldNid) const {
223 X509_NAME *subjectName = getX509Name(m_x509, type);
224 X509_NAME_ENTRY *subjectEntry = NULL;
227 return std::string();
229 int entryCount = X509_NAME_entry_count(subjectName);
231 for (int i = 0; i < entryCount; ++i) {
232 subjectEntry = X509_NAME_get_entry(subjectName, i);
238 int nid = OBJ_obj2nid(
239 static_cast<ASN1_OBJECT*>(
240 X509_NAME_ENTRY_get_object(subjectEntry)));
242 if (nid != fieldNid) {
246 ASN1_STRING* pASN1Str = subjectEntry->value;
248 unsigned char* pData = NULL;
249 int nLength = ASN1_STRING_to_UTF8(&pData, pASN1Str);
252 LogError("Reading field error.");
253 return std::string();
256 std::string output(reinterpret_cast<char*>(pData), nLength);
260 return std::string();
263 std::string CertificateImpl::getCommonName(CertificateFieldId type) const {
264 return getField(type, NID_commonName);
267 std::string CertificateImpl::getCountryName(CertificateFieldId type) const {
268 return getField(type, NID_countryName);
271 std::string CertificateImpl::getStateOrProvinceName(CertificateFieldId type) const {
272 return getField(type, NID_stateOrProvinceName);
275 std::string CertificateImpl::getLocalityName(CertificateFieldId type) const {
276 return getField(type, NID_localityName);
279 std::string CertificateImpl::getOrganizationName(CertificateFieldId type) const {
280 return getField(type, NID_organizationName);
283 std::string CertificateImpl::getOrganizationalUnitName(CertificateFieldId type) const {
284 return getField(type, NID_organizationalUnitName);
287 std::string CertificateImpl::getEmailAddres(CertificateFieldId type) const {
288 return getField(type, NID_pkcs9_emailAddress);
291 std::string CertificateImpl::getOCSPURL() const {
293 return std::string();
295 STACK_OF(OPENSSL_STRING) *aia = X509_get1_ocsp(m_x509);
298 return std::string();
300 std::string result(sk_OPENSSL_STRING_value(aia, 0));
301 X509_email_free(aia); // TODO is it correct?
305 CertificateImpl::~CertificateImpl() {
306 LogDebug("free cert start ptr: " << (void*)m_x509);
308 LogDebug("free cert end");
311 CertificateShPtr Certificate::create(const RawBuffer &rawBuffer, DataFormat format) {
312 CertificateShPtr output(new CertificateImpl(rawBuffer, format));
313 if (output.get() == NULL)