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 <generic-key.h>
28 #include <certificate-impl.h>
33 CertificateImpl::CertificateImpl(const RawBuffer &der, DataFormat format)
37 const unsigned char *ptr;
40 LogDebug("Certificate to parse. Size: " << der.size());
42 if (DataFormat::FORM_DER_BASE64 == format) {
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);
62 LogError("Unknown certificate format");
67 LogError("Certificate could not be parsed.");
68 // ThrowMsg(Exception::OpensslInternalError,
69 // "Internal Openssl error in d2i_X509 function.");
73 CertificateImpl::CertificateImpl(X509 *x509)
74 : m_x509(X509_dup(x509))
77 CertificateImpl::CertificateImpl(const CertificateImpl &second){
78 m_x509 = X509_dup(second.m_x509);
81 CertificateImpl::CertificateImpl(CertificateImpl &&second) {
82 m_x509 = second.m_x509;
84 LogDebug("Certificate moved: " << (void*)m_x509);
87 CertificateImpl& CertificateImpl::operator=(CertificateImpl &&second) {
91 m_x509 = second.m_x509;
93 LogDebug("Certificate moved: " << (void*)m_x509);
97 CertificateImpl& CertificateImpl::operator=(const CertificateImpl &second) {
101 m_x509 = X509_dup(second.m_x509);
105 X509* CertificateImpl::getX509() const {
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");
118 reinterpret_cast<char*>(rawDer),
119 reinterpret_cast<char*>(rawDer) + size);
120 OPENSSL_free(rawDer);
124 bool CertificateImpl::empty() const {
125 return m_x509 == NULL;
128 GenericKey::EvpShPtr CertificateImpl::getEvpShPtr() const {
129 return GenericKey::EvpShPtr(X509_get_pubkey(m_x509), EVP_PKEY_free);
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.");
142 X509_NAME *getX509Name(X509 *x509, CertificateFieldId type) {
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);
151 LogError("Invalid param. Unknown CertificateFieldId");
155 std::string CertificateImpl::getOneLine(CertificateFieldId type) const
157 X509_NAME *name = getX509Name(m_x509, type);
159 return std::string();
160 static const int MAXB = 1024;
162 X509_NAME_oneline(name, buffer, MAXB);
163 return std::string(buffer);
166 std::string CertificateImpl::getField(CertificateFieldId type, int fieldNid) const {
167 X509_NAME *subjectName = getX509Name(m_x509, type);
168 X509_NAME_ENTRY *subjectEntry = NULL;
171 return std::string();
173 int entryCount = X509_NAME_entry_count(subjectName);
175 for (int i = 0; i < entryCount; ++i) {
176 subjectEntry = X509_NAME_get_entry(subjectName, i);
182 int nid = OBJ_obj2nid(
183 static_cast<ASN1_OBJECT*>(
184 X509_NAME_ENTRY_get_object(subjectEntry)));
186 if (nid != fieldNid) {
190 ASN1_STRING* pASN1Str = subjectEntry->value;
192 unsigned char* pData = NULL;
193 int nLength = ASN1_STRING_to_UTF8(&pData, pASN1Str);
196 LogError("Reading field error.");
197 return std::string();
200 std::string output(reinterpret_cast<char*>(pData), nLength);
204 return std::string();
207 std::string CertificateImpl::getCommonName(CertificateFieldId type) const {
208 return getField(type, NID_commonName);
211 std::string CertificateImpl::getCountryName(CertificateFieldId type) const {
212 return getField(type, NID_countryName);
215 std::string CertificateImpl::getStateOrProvinceName(CertificateFieldId type) const {
216 return getField(type, NID_stateOrProvinceName);
219 std::string CertificateImpl::getLocalityName(CertificateFieldId type) const {
220 return getField(type, NID_localityName);
223 std::string CertificateImpl::getOrganizationName(CertificateFieldId type) const {
224 return getField(type, NID_organizationName);
227 std::string CertificateImpl::getOrganizationalUnitName(CertificateFieldId type) const {
228 return getField(type, NID_organizationalUnitName);
231 std::string CertificateImpl::getEmailAddres(CertificateFieldId type) const {
232 return getField(type, NID_pkcs9_emailAddress);
235 std::string CertificateImpl::getOCSPURL() const {
237 return std::string();
239 STACK_OF(OPENSSL_STRING) *aia = X509_get1_ocsp(m_x509);
242 return std::string();
244 std::string result(sk_OPENSSL_STRING_value(aia, 0));
245 X509_email_free(aia); // TODO is it correct?
249 CertificateImpl::~CertificateImpl() {
250 LogDebug("free cert start ptr: " << (void*)m_x509);
252 LogDebug("free cert end");
255 CertificateShPtr Certificate::create(const RawBuffer &rawBuffer, DataFormat format) {
256 CertificateShPtr output(new CertificateImpl(rawBuffer, format));
257 if (output.get() == NULL)