Skip to content

Commit 29bdd31

Browse files
committed
Check certificate key type and fetch certifcate when responder is missing
IB-8461 Signed-off-by: Raul Metsma <[email protected]>
1 parent 83fcde4 commit 29bdd31

File tree

2 files changed

+30
-23
lines changed

2 files changed

+30
-23
lines changed

src/Container.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ void digidoc::initialize(const string &appInfo, const string &userAgent, initCal
120120
THROW("Error during initialisation of xmlsec. Failed to register custom callbacks.");
121121

122122
INFO("Libxml2 version: %s", LIBXML_DOTTED_VERSION);
123+
INFO("OpenSSL version: %s", OpenSSL_version(OPENSSL_VERSION_STRING));
123124
INFO("Xmlsec1 version: %s", XMLSEC_VERSION);
124125
INFO("digidocpp version: %s", VERSION_STR);
125126

src/crypto/OCSP.cpp

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,9 @@ OCSP::OCSP(const X509Cert &cert, const X509Cert &issuer, const std::string &user
5757
string url = Conf::instance()->ocsp(cert.issuerName("CN"));
5858
if(url.empty())
5959
{
60-
STACK_OF(OPENSSL_STRING) *urls = X509_get1_ocsp(cert.handle());
61-
if(urls && sk_OPENSSL_STRING_num(urls) > 0)
62-
url = sk_OPENSSL_STRING_value(urls, 0);
63-
X509_email_free(urls);
60+
if(auto urls = make_unique_ptr<X509_email_free>(X509_get1_ocsp(cert.handle()));
61+
urls && sk_OPENSSL_STRING_num(urls.get()) > 0)
62+
url = sk_OPENSSL_STRING_value(urls.get(), 0);
6463
}
6564
DEBUG("OCSP url %s", url.c_str());
6665
if(url.empty())
@@ -70,11 +69,11 @@ OCSP::OCSP(const X509Cert &cert, const X509Cert &issuer, const std::string &user
7069
throw e;
7170
}
7271

73-
OCSP_CERTID *certId = OCSP_cert_to_id(nullptr, cert.handle(), issuer.handle());
74-
SCOPE(OCSP_REQUEST, req, OCSP_REQUEST_new());
72+
auto req = make_unique_ptr<OCSP_REQUEST_free>(OCSP_REQUEST_new());
7573
if(!req)
7674
THROW_OPENSSLEXCEPTION("Failed to create new OCSP request, out of memory?");
7775

76+
OCSP_CERTID *certId = OCSP_cert_to_id(nullptr, cert.handle(), issuer.handle());
7877
if(!OCSP_request_add0_id(req.get(), certId))
7978
THROW_OPENSSLEXCEPTION("Failed to add certificate ID to OCSP request.");
8079

@@ -143,32 +142,35 @@ bool OCSP::compareResponderCert(const X509Cert &cert) const
143142
{
144143
if(!basic || !cert)
145144
return false;
145+
146146
const ASN1_OCTET_STRING *hash {};
147147
const X509_NAME *name {};
148-
OCSP_resp_get0_id(basic.get(), &hash, &name);
149-
if(name)
150-
return X509_NAME_cmp(X509_get_subject_name(cert.handle()), name) == 0;
148+
if(OCSP_resp_get0_id(basic.get(), &hash, &name) != 1)
149+
return false;
151150
if(hash)
152151
{
153152
std::array<unsigned char,SHA_DIGEST_LENGTH> sha1{};
154153
ASN1_BIT_STRING *key = X509_get0_pubkey_bitstr(cert.handle());
155154
SHA1(key->data, size_t(key->length), sha1.data());
156-
return equal(sha1.cbegin(), sha1.cend(), hash->data, std::next(hash->data, hash->length));
155+
if(!equal(sha1.cbegin(), sha1.cend(), hash->data, std::next(hash->data, hash->length)))
156+
return false;
157157
}
158-
return false;
158+
else if(X509_NAME_cmp(X509_get_subject_name(cert.handle()), name) != 0)
159+
return false;
160+
161+
const ASN1_OBJECT *sigalg {};
162+
X509_ALGOR_get0(&sigalg, nullptr, nullptr, OCSP_resp_get0_tbs_sigalg(basic.get()));
163+
int pknid = 0;
164+
return OBJ_find_sigid_algs(OBJ_obj2nid(sigalg), nullptr, &pknid) == 1 &&
165+
EVP_PKEY_is_a(X509_get0_pubkey(cert.handle()), OBJ_nid2sn(pknid)) == 1;
159166
}
160167

161168
X509Cert OCSP::responderCert() const
162169
{
163170
if(!basic)
164171
return X509Cert();
165-
const STACK_OF(X509) *certs = OCSP_resp_get0_certs(basic.get());
166-
for(int i = 0; i < sk_X509_num(certs); ++i)
167-
{
168-
X509Cert cert(sk_X509_value(certs, i));
169-
if(compareResponderCert(cert))
170-
return cert;
171-
}
172+
if(X509 *signer{}; OCSP_resp_get0_signer(basic.get(), &signer, nullptr) != 0 && signer)
173+
return X509Cert(signer);
172174
for(const X509Cert &cert: X509CertStore::instance()->certs(X509CertStore::OCSP))
173175
{
174176
if(compareResponderCert(cert))
@@ -191,12 +193,16 @@ void OCSP::verifyResponse(const X509Cert &cert) const
191193
THROW("Failed to verify OCSP response.");
192194

193195
tm tm = producedAt();
194-
// Some OCSP-s do not have certificates in response and stack is used for finding certificate for this
195196
auto stack = make_unique_ptr(sk_X509_new_null(), [](auto *sk) { sk_X509_free(sk); });
196-
for(const X509Cert &i: X509CertStore::instance()->certs(X509CertStore::OCSP))
197+
// Some OCSP-s do not have certificates in response and stack is used for finding certificate for this
198+
199+
if(X509 *signer{}; OCSP_resp_get0_signer(basic.get(), &signer, nullptr) == 0 || !signer)
197200
{
198-
if(compareResponderCert(i))
199-
sk_X509_push(stack.get(), i.handle());
201+
for(const X509Cert &i: X509CertStore::instance()->certs(X509CertStore::OCSP))
202+
{
203+
if(compareResponderCert(i))
204+
sk_X509_push(stack.get(), i.handle());
205+
}
200206
}
201207
auto store = X509CertStore::createStore(X509CertStore::OCSP, tm);
202208
if(OCSP_basic_verify(basic.get(), stack.get(), store.get(), OCSP_NOCHECKS | OCSP_PARTIAL_CHAIN) != 1)
@@ -230,7 +236,7 @@ void OCSP::verifyResponse(const X509Cert &cert) const
230236
ASN1_OBJECT *md {};
231237
if(OCSP_id_get0_info(nullptr, &md, nullptr, nullptr, const_cast<OCSP_CERTID*>(certID)) == 1)
232238
evp_md = EVP_get_digestbyobj(md);
233-
SCOPE(OCSP_CERTID, certId, OCSP_cert_to_id(evp_md, cert.handle(), issuer.handle()));
239+
auto certId = make_unique_ptr<OCSP_CERTID_free>(OCSP_cert_to_id(evp_md, cert.handle(), issuer.handle()));
234240
if(OCSP_resp_find_status(basic.get(), certId.get(), &status, nullptr, nullptr, nullptr, nullptr) == 1)
235241
break;
236242
}

0 commit comments

Comments
 (0)