@@ -57,10 +57,9 @@ OCSP::OCSP(const X509Cert &cert, const X509Cert &issuer, const std::string &user
57
57
string url = Conf::instance ()->ocsp (cert.issuerName (" CN" ));
58
58
if (url.empty ())
59
59
{
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 );
64
63
}
65
64
DEBUG (" OCSP url %s" , url.c_str ());
66
65
if (url.empty ())
@@ -70,11 +69,11 @@ OCSP::OCSP(const X509Cert &cert, const X509Cert &issuer, const std::string &user
70
69
throw e;
71
70
}
72
71
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 ());
75
73
if (!req)
76
74
THROW_OPENSSLEXCEPTION (" Failed to create new OCSP request, out of memory?" );
77
75
76
+ OCSP_CERTID *certId = OCSP_cert_to_id (nullptr , cert.handle (), issuer.handle ());
78
77
if (!OCSP_request_add0_id (req.get (), certId))
79
78
THROW_OPENSSLEXCEPTION (" Failed to add certificate ID to OCSP request." );
80
79
@@ -143,32 +142,35 @@ bool OCSP::compareResponderCert(const X509Cert &cert) const
143
142
{
144
143
if (!basic || !cert)
145
144
return false ;
145
+
146
146
const ASN1_OCTET_STRING *hash {};
147
147
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 ;
151
150
if (hash)
152
151
{
153
152
std::array<unsigned char ,SHA_DIGEST_LENGTH> sha1{};
154
153
ASN1_BIT_STRING *key = X509_get0_pubkey_bitstr (cert.handle ());
155
154
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 ;
157
157
}
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 ;
159
166
}
160
167
161
168
X509Cert OCSP::responderCert () const
162
169
{
163
170
if (!basic)
164
171
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);
172
174
for (const X509Cert &cert: X509CertStore::instance ()->certs (X509CertStore::OCSP))
173
175
{
174
176
if (compareResponderCert (cert))
@@ -191,12 +193,15 @@ void OCSP::verifyResponse(const X509Cert &cert) const
191
193
THROW (" Failed to verify OCSP response." );
192
194
193
195
tm tm = producedAt ();
194
- // Some OCSP-s do not have certificates in response and stack is used for finding certificate for this
195
196
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
+ if (X509 *signer{}; OCSP_resp_get0_signer (basic.get (), &signer, nullptr ) == 0 || !signer)
197
199
{
198
- if (compareResponderCert (i))
199
- sk_X509_push (stack.get (), i.handle ());
200
+ for (const X509Cert &i: X509CertStore::instance ()->certs (X509CertStore::OCSP))
201
+ {
202
+ if (compareResponderCert (i))
203
+ sk_X509_push (stack.get (), i.handle ());
204
+ }
200
205
}
201
206
auto store = X509CertStore::createStore (X509CertStore::OCSP, tm);
202
207
if (OCSP_basic_verify (basic.get (), stack.get (), store.get (), OCSP_NOCHECKS | OCSP_PARTIAL_CHAIN) != 1 )
@@ -230,7 +235,7 @@ void OCSP::verifyResponse(const X509Cert &cert) const
230
235
ASN1_OBJECT *md {};
231
236
if (OCSP_id_get0_info (nullptr , &md, nullptr , nullptr , const_cast <OCSP_CERTID*>(certID)) == 1 )
232
237
evp_md = EVP_get_digestbyobj (md);
233
- SCOPE (OCSP_CERTID, certId, OCSP_cert_to_id (evp_md, cert.handle (), issuer.handle ()));
238
+ auto certId = make_unique_ptr<OCSP_CERTID_free>( OCSP_cert_to_id (evp_md, cert.handle (), issuer.handle ()));
234
239
if (OCSP_resp_find_status (basic.get (), certId.get (), &status, nullptr , nullptr , nullptr , nullptr ) == 1 )
235
240
break ;
236
241
}
0 commit comments