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 <vcore/OCSPCertMgrUtil.h>
23 #include <vcore/SSLContainers.h>
25 #include <openssl/pem.h>
26 #include <openssl/x509.h>
27 #include <dpl/assert.h>
28 #include <dpl/log/log.h>
29 #include <dpl/scoped_resource.h>
34 #include <cert-service.h>
37 const int MAX_BUF = 1024;
41 typedef CERT_CONTEXT* Type;
42 static Type NullValue()
46 static void Destroy(Type context)
49 cert_svc_cert_context_final(context);
55 namespace ValidationCore {
56 namespace OCSPCertMgrUtil {
58 * TODO This API function should be changed to:
59 * CertifiatePtr getCertFromStore(const std::string &subject);
61 * All of cert_svc function could return error because input
62 * data are corruped. That's why I dont want to throw exceptions
65 void getCertFromStore(X509_NAME *subject,
68 if (!xcert || *xcert || !subject) {
69 LogError("Invalid input!");
73 typedef VcoreDPL::ScopedResource<ContextDeleter> ScopedContext;
77 const unsigned char* ptr = NULL;
78 X509 *pCertificate = NULL;
79 cert_svc_filename_list *fileList = NULL;
81 X509_NAME_oneline(subject, buffer, MAX_BUF);
83 ScopedContext ctx(cert_svc_cert_context_init());
84 if (ctx.Get() == NULL) {
85 LogWarning("Error in cert_svc_cert_context_init.");
89 LogDebug("Search certificate with subject: " << buffer);
90 result = cert_svc_search_certificate(ctx.Get(), SUBJECT_STR, buffer);
91 LogDebug("Search finished!");
93 if (CERT_SVC_ERR_NO_ERROR != result) {
94 LogWarning("Error during certificate search");
98 fileList = ctx.Get()->fileNames;
100 if (fileList == NULL) {
101 LogDebug("No certificate found");
105 if (fileList->filename == NULL) {
106 LogWarning("Empty filename");
110 LogDebug("Found cert file: " << fileList->filename);
111 ScopedContext ctx2(cert_svc_cert_context_init());
113 if (ctx2.Get() == NULL) {
114 LogWarning("Error in cert_svc_cert_context_init.");
118 // TODO add read_certifcate_from_file function to Certificate.h
119 if (CERT_SVC_ERR_NO_ERROR !=
120 cert_svc_load_file_to_context(ctx2.Get(), fileList->filename)) {
121 LogWarning("Error in cert_svc_load_file_to_context");
125 ptr = ctx2.Get()->certBuf->data;
126 // create a certificate from mem buff
127 pCertificate = d2i_X509(NULL, &ptr, ctx2.Get()->certBuf->size);
129 if (pCertificate == NULL) {
130 LogWarning("Error during certificate conversion in d2i_X509");
134 *xcert = pCertificate;
135 if (fileList->next != NULL) {
136 LogError("There is more then one certificate with same subject :/");
137 // TODO Implement me.
138 for (fileList = fileList->next;
140 fileList = fileList->next) {
141 LogError("Additional certificate with same subject: " << fileList->filename);
146 CertificatePtr getParentFromStore(const CertificatePtr &certificate)
148 Assert(certificate.get());
149 X509* rawPtr = certificate->getX509();
151 /* TODO Add getIssuerName function to Certificate.h */
152 X509_NAME *name = X509_get_issuer_name(rawPtr);
154 X509* rawTemp = NULL;
155 getCertFromStore(name, &rawTemp);
157 if (rawTemp == NULL) {
158 return CertificatePtr();
160 SSLSmartContainer<X509> scope(rawTemp);
161 return CertificatePtr(new Certificate(rawTemp));
164 CertificateList completeCertificateChain(const CertificateList &certificateList)
166 CertificateList result = certificateList;
167 CertificatePtr last = result.back();
168 if (last->isSignedBy(last)) {
171 CertificatePtr parent = getParentFromStore(last);
173 result.push_back(parent);
177 } // namespace OCSPCertMgrUtil
178 } // namespace ValidationCore