<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Victor, Jeremy-</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Thanks for your responses. It sounds like I should maybe take a step back and describe what I'm doing and how. I'm possibly doing things fundamentally wrong, maybe because the way I'm doing them is based originally on OpenSSL 0.9.8. I'm currently moving from
 1.0.2 to 1.1.1, which is why the questions are coming up.</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
I won't get into the details of my application as it's complex, but it can act as a client or a server. The case we are worried about is obviously when it's acting as a client. I thought the standard way of dealing with these type of errors was with setting
 a verify_callback() function, which is part of the description below.</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
I set up an X509_STORE object and then cycle through all of the certificate files in /etc/ssl/certs/, open them, and call PEM_read_X509() to get an X509 (certificate) object and then call X509_STORE_add_cert(x509_stor, certificate) to read the certificates
 into  my trusted store, X509_store object. Then when I create an SSL CTX, I call SSL_CTX_set_cert_store() to set the X509_store object for the CTX. I also call SSL_set_verify( ,SSL_VERIFY_PEER,verify_callback) with the SSL object created from that CTX to set
 the verify_callback() function for each user that will act as a client. </div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style=""><font face="Calibri, Helvetica, sans-serif" style="color: rgb(0, 0, 0);"><span style="font-size: 12pt;">If the user of this CTX is acting as a client and the server presents a certificate chain, and my trusted store has the root, the connection
 will work, as the chain is verified and trusted. If the server presents a self-signed certificate, the verify_callback() function is invoked with the error</span></font>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><span style="font-family: courier, "courier new", monospace; font-size: 14px;">18/X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, </span><font face="Calibri, Helvetica, sans-serif">but if I search for and find the self-signed cert in my trusted store, I clear the error and let the </font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif">connection proceed. The scenario is very similar for the case I asked about, the only difference is I'm presented a 2 certs in a chain, and I have the </font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif">intermediate cert in my store.  My understanding was the verify_callback() is the correct place to handle these cases. </font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif"><br></font></pre>
<pre style="overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif" style=""><font color="#000000">From Victor's response, I don't know what a custom X509_STORE type is or how to set one up. Likewise, I don't know how to use the "partial chain" flag </font></font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif">and what API I need to load intermediate certificates into my trusted store(other than what I describe above). Because of the way certificates are </font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif">distributed, I can't always rely on having the root in the trusted store, so I'll need to trust some intermediate certs, provided they are valid, actually signed</font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif">the end-entity cert, etc. </font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif"><br></font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif">Let me know if I am off track, and if so, what APIs I should be looking at, especially if there are been changes in this area.</font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif"><br></font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif">Thanks.</font></pre>
<pre style="color: rgb(0, 0, 0); overflow-wrap: break-word; margin: 0px; background-color: rgb(255, 255, 255);"><font face="Calibri, Helvetica, sans-serif"><br></font></pre>
</div>
<div>
<div id="appendonsend"></div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> openssl-users <openssl-users-bounces@openssl.org> on behalf of Viktor Dukhovni <openssl-users@dukhovni.org><br>
<b>Sent:</b> Monday, March 30, 2020 6:17 PM<br>
<b>To:</b> openssl-users@openssl.org <openssl-users@openssl.org><br>
<b>Subject:</b> Re: Peer certificate verification in verify_callback</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText">On Thu, Mar 05, 2020 at 02:04:27PM +0000, Jason Schultz wrote:<br>
<br>
> I have some questions about my application’s verify_callback() function and how I handle some of the OpenSSL errors.<br>
<br>
You're going about this the wrong way.  Instead of tryign (likely<br>
insecurely) to patch up verification errors in a verify callback, if you<br>
have a certificate store that is not directly supported by OpenSSL, you<br>
need to implement your own custom X509_STORE type, associate that store<br>
with the SSL_CTX and have OpenSSL's built-in certificate verification<br>
search that store for you.<br>
<br>
If you also want to directly trust intermediate certificates that are<br>
not self-signed roots, you can either set the "partial chain" flag,<br>
or load into your store intermediate certificates with auxiliary<br>
trust settings (aka "TRUSTED CERTIFICATES"), which will then be<br>
trusted without chaining to a root, but simpler to just add the<br>
roots to the store.<br>
<br>
-- <br>
    Viktor.<br>
</div>
</span></font></div>
</div>
</body>
</html>