2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @author Michal Ciepielski(m.ciepielski@samsung.com)
22 #include "OCSPCertMgrUtil.h"
23 #include "SSLContainers.h"
25 #include <openssl/pem.h>
26 #include <openssl/ocsp.h>
27 #include <dpl/log/log.h>
28 #include <dpl/scoped_resource.h>
33 #include <cert-service.h>
36 const int MAX_BUF = 1024;
40 typedef CERT_CONTEXT* Type;
41 static Type NullValue()
45 static void Destroy(Type context)
48 cert_svc_cert_context_final(context);
54 namespace ValidationCore {
55 namespace OCSPCertMgrUtil {
57 * TODO This API function should be changed to:
58 * CertifiatePtr getCertFromStore(const std::string &subject);
60 * All of cert_svc function could return error because input
61 * data are corruped. That's why I dont want to throw exceptions
64 void getCertFromStore(X509_NAME *subject,
67 if (!xcert || *xcert || !subject) {
68 LogError("Invalid input!");
72 typedef DPL::ScopedResource<ContextDeleter> ScopedContext;
76 const unsigned char* ptr = NULL;
77 X509 *pCertificate = NULL;
78 cert_svc_filename_list *fileList = NULL;
80 X509_NAME_oneline(subject, buffer, MAX_BUF);
82 ScopedContext ctx(cert_svc_cert_context_init());
83 if (ctx.Get() == NULL) {
84 LogWarning("Error in cert_svc_cert_context_init.");
88 LogDebug("Search certificate with subject: " << buffer);
89 result = cert_svc_search_certificate(ctx.Get(), SUBJECT_STR, buffer);
90 LogDebug("Search finished!");
92 if (CERT_SVC_ERR_NO_ERROR != result) {
93 LogWarning("Error during certificate search");
97 fileList = ctx.Get()->fileNames;
99 if (fileList == NULL) {
100 LogDebug("No certificate found");
104 if (fileList->filename == NULL) {
105 LogWarning("Empty filename");
109 LogDebug("Found cert file: " << fileList->filename);
110 ScopedContext ctx2(cert_svc_cert_context_init());
112 if (ctx2.Get() == NULL) {
113 LogWarning("Error in cert_svc_cert_context_init.");
117 // TODO add read_certifcate_from_file function to Certificate.h
118 if (CERT_SVC_ERR_NO_ERROR !=
119 cert_svc_load_file_to_context(ctx2.Get(), fileList->filename)) {
120 LogWarning("Error in cert_svc_load_file_to_context");
124 ptr = ctx2.Get()->certBuf->data;
125 // create a certificate from mem buff
126 pCertificate = d2i_X509(NULL, &ptr, ctx2.Get()->certBuf->size);
128 if (pCertificate == NULL) {
129 LogWarning("Error during certificate conversion in d2i_X509");
133 *xcert = pCertificate;
134 if (fileList->next != NULL) {
135 LogError("There is more then one certificate with same subject :/");
136 // TODO Implement me.
137 for (fileList = fileList->next;
139 fileList = fileList->next) {
141 "Additional certificate with same subject: " <<
147 CertificatePtr getParentFromStore(const CertificatePtr &certificate)
149 Assert(certificate.Get());
150 X509* rawPtr = certificate->getX509();
152 /* TODO Add getIssuerName function to Certificate.h */
153 X509_NAME *name = X509_get_issuer_name(rawPtr);
155 X509* rawTemp = NULL;
156 getCertFromStore(name, &rawTemp);
158 if (rawTemp == NULL) {
159 return CertificatePtr();
162 SSLSmartContainer<X509> scope(rawTemp);
163 return CertificatePtr(new Certificate(rawTemp));
166 CertificateList completeCertificateChain(const CertificateList &certificateList)
168 CertificateList result = certificateList;
169 CertificatePtr last = result.back();
170 if (last->isSignedBy(last)) {
173 CertificatePtr parent = getParentFromStore(last);
175 result.push_back(parent);
179 } // namespace OCSPCertMgrUtil
180 } // namespace ValidationCore