<div dir="ltr"><div>Re post my code here, since I send it alone to Michael.</div><div><br></div><div><div><span>Below is the error message:</span></div><div><span><br></span></div><div><span>```</span></div><div><span>Traceback (most recent call last):<br>  File "test.py", line 6, in <module><br>    r = s.get('<a href="https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag" target="_blank">https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag</a>', verify='./ca.pem')<br>  File "/home/kubo/.local/lib/python2.7/site-packages/requests/sessions.py", line 555, in get<br>    return self.request('GET', url, **kwargs)<br>  File "/home/kubo/.local/lib/python2.7/site-packages/requests/sessions.py", line 542, in request<br>    resp = self.send(prep, **send_kwargs)<br>  File "/home/kubo/.local/lib/python2.7/site-packages/requests/sessions.py", line 655, in send<br>    r = adapter.send(request, **kwargs)<br>  File "/home/kubo/.local/lib/python2.7/site-packages/requests/adapters.py", line 517, in send<br>    raise SSLError(e, request=request)<br>requests.exceptions.SSLError: HTTPSConnectionPool(host='nsxmanager.pks.vmware.local',
 port=443): Max retries exceeded with url: /api/v1/spec/vmware/types/Tag
 (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] 
certificate verify failed (_ssl.c:590)'),))</span></div><div><span>```<br></span></div><div><span><br></span></div><div><span>but the CURL command and Golang code I used to access client, it shows CA cert.</span></div><div><span><br></span></div><div><span>My python code(which report above error):</span></div><div><span><br></span></div><div><span>```</span></div><div><span>import requests<br><br>s = requests.Session()<br>s.auth = ('admin', 'Admin!23Admin')<br>r = s.get('<a href="https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag" target="_blank">https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag</a>', verify='./ca.crt')<br>print(r.status_code)</span></div><div><span>```<br></span></div><div><span><br></span></div><div><span>CURL:</span></div><div><span>```</span></div><div><span>curl -I -u admin:'Admin!23Admin' <a href="https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag" target="_blank">https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag</a> --cacert ./ca.crt<br></span></div><div><span>```<br></span></div><div><span><br></span></div><div><span>Golang:</span></div><div><span>```</span></div><div><span>package main<br><br>import (<br>    "crypto/tls"<br>    "io/ioutil"<br>    "log"<br>    "fmt"<br>    "net/http"<br>    "crypto/x509"<br>)<br><br>func main() {<br>    caCert, err := ioutil.ReadFile("./ca.crt")<br>    if err != nil {<br>        log.Fatal(err)<br>    }<br>    caCertPool := x509.NewCertPool()<br>    caCertPool.AppendCertsFromPEM(caCert)<br><br>    client := &http.Client{<br>        Transport: &http.Transport{<br>            TLSClientConfig: &tls.Config{<br>                RootCAs:      caCertPool,<br>            },<br>        },<br>    }<br>    req, err := http.NewRequest("GET", "<a href="https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag" target="_blank">https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag</a>", nil)<br>    req.SetBasicAuth("admin", "Admin!23Admin")<br>    r, err := client.Do(req)<br>    if err != nil {<br>        panic(err)<br>    }<br>    fmt.Println(r.Status)<br>}</span></div><div><span>```<br></span></div><div><span><br></span></div><div><span>All
 the 3 clients used the same ca.crt file, which has an old cert in the 
first, then a new cert behind. Only Python (used OpenSSL) failed.<br></span></div><div><span>After I compile curl with openssl backend, the new binary failed too.</span></div><div><span><br></span></div><div><span>```</span></div><div><span>./curl.openssl -vvvv -u admin:'Admin!23Admin' <a href="https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag" target="_blank">https://nsxmanager.pks.vmware.local/api/v1/spec/vmware/types/Tag</a> --cacert ./ca.crt<br>*   Trying 192.168.111.4:443...<br>* Connected to nsxmanager.pks.vmware.local (192.168.111.4) port 443 (#0)<br>* ALPN, offering http/1.1<br>* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH<br>* successfully set certificate verify locations:<br>*  CAfile: ./ca.crt<br>*  CApath: none<br>* TLSv1.2 (OUT), TLS header, Certificate Status (22):<br>* TLSv1.2 (OUT), TLS handshake, Client hello (1):<br>* TLSv1.2 (IN), TLS handshake, Server hello (2):<br>* TLSv1.2 (IN), TLS handshake, Certificate (11):<br>* TLSv1.2 (OUT), TLS alert, unknown CA (560):<br>* SSL certificate problem: self signed certificate<br>* Closing connection 0<br>curl: (60) SSL certificate problem: self signed certificate<br>More details here: <a href="https://curl.se/docs/sslcerts.html" target="_blank">https://curl.se/docs/sslcerts.html</a><br><br>curl failed to verify the legitimacy of the server and therefore could not<br>establish a secure connection to it. To learn more about this situation and<br>how to fix it, please visit the web page mentioned above.</span></div><div><span>```<br></span></div><div><span>Is above information enough?</span></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">定平袁 <<a href="mailto:pkudingping@gmail.com">pkudingping@gmail.com</a>> 于2020年12月25日周五 上午7:35写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thanks a lot for your reply! Merry Christmas!<br><div><div><br></div><div><a class="gmail_plusreply" id="gmail-m_-4150760943053332174m_1380141081388625801plusReplyChip-7" href="mailto:Michael.Wojcik@microfocus.com" target="_blank">@Michael Wojcik</a>   Apologies. I clicked the wrong reply button.</div><div><br></div><div><a class="gmail_plusreply" id="gmail-m_-4150760943053332174m_1380141081388625801plusReplyChip-2" href="mailto:dev@ddvo.net" target="_blank">@David von Oheimb</a> I will update to a new version and try again. To append cert is to make sure new cert and old cert both exist in trust store, thus when server switches cert, it can be trusted by client.<br></div><div></div><div><br></div><div>@Jochen actually, the certs have different SN, which indeed is not consistent with the man doc. The thing that confuses me is that CURL (compiled with gnutls) and Golang works. <br></div><div>below is my ca.crt file, I am not sure where it went wrong, maybe just my wrong behavior?</div><div><br></div><div>```</div><div><br>-----BEGIN CERTIFICATE-----<br>MIIFdzCCA1+gAwIBAgIJAJcvKUQ0Bz4tMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNV<br>BAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJUGFsbyBBbHRvMQ8wDQYDVQQK<br>DAZWTXdhcmUxJDAiBgNVBAMMG25zeG1hbmFnZXIucGtzLnZtd2FyZS5sb2NhbDAe<br>Fw0yMDEyMTcwMDM2MjBaFw0zMDEyMTUwMDM2MjBaMGUxCzAJBgNVBAYTAlVTMQsw<br>CQYDVQQIDAJDQTESMBAGA1UEBwwJUGFsbyBBbHRvMQ8wDQYDVQQKDAZWTXdhcmUx<br>JDAiBgNVBAMMG25zeG1hbmFnZXIucGtzLnZtd2FyZS5sb2NhbDCCAiIwDQYJKoZI<br>hvcNAQEBBQADggIPADCCAgoCggIBAMC4EFsukdnrj26EYSaCCrvUtEhbi33wXHKi<br>6utmOe9r+M17Q0MArjJeEzklmrTkj+qKJCB4TgWFY2djJ+hA0a5I2eOn/0OjJ0c2<br>67FcqX7pq1JwYMSkwN4dQUbAN82xjQOcmj03PVjgLQSFXLfNxcfym0G2KtwkIg8K<br>V4JwC0L048BBu/EynAXA2kYHXiJ6uSjeMOuTyogmVilzUOjfJztaNj2jpq3D8sek<br>qtRNBYRcgSwx1wq7uWSe6qjHVDmom4nlUQznOZfJYodFWZll6Wv8Itk28ovhIhgk<br>G9wJv3QJp6Gef1GN22Q7KU09/ZG61PRPVgoPTuRxHKn75aKl6FJcztvz/X4egt9K<br>yGxsxEtWrLW52U1EUVg0zVUO/VAbtm1NLsEGv1L19vYjg6gpU4zQjP7enuSFqvKo<br>rLLDvSzUWRzXIDwWSWGNBoAkry8jZmKWnjHqSW2EVbCaFTXcIQ6kPQGYvH3cFUyG<br>fW06NlCL+AYGNaOVJkL7J3RYH+5cstGTpCNpyAmYNsEs1G+yXwCH5aDcP/0qbU2W<br>WXO0Jh/+2KhmZ1Op1o6x69FLQ+g/0m705nGhx8NQWC3V+BC/mUdyXlom7yZde+uT<br>qZS/0K7z/O8FpNwAddLmhgNHq2cHRjQFH6WeAhw3tBLGS5OFAP23SG/OItEaWp7h<br>nXgRedMVAgMBAAGjKjAoMCYGA1UdEQQfMB2CG25zeG1hbmFnZXIucGtzLnZtd2Fy<br>ZS5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAgEAlfMDgcI6DiRH7eRJfg0SrtkRSAIe<br>0icQ8RH6Z8SBYIbPnzR2qeAm0V7BV7qGSOHGb1ezghCXQAjL2JF1pHw9aKZ0ST49<br>vZSlkp6tKojk1HZqa3OSfji+o8ROSvpfBW+qYqgsTkSD0VqZ4xkGUnXaRbQ3H+2V<br>CV/MsXn/lgJ1pXDhNifUBtTa4OQx3WsA74lh7pddtbEWQJbFPwDvwzKo62P8b6zq<br>MDhccVBmV5QZDwGH3v9Dy6QHq91b1grMkIQb67e1E6VQia6++Sq8b8ZCOJ1VUOjt<br>I7KTIco57dLyIJPO+wvTKKpLraFIGUxNBwVOnI6wekUlhhhMcXvL/dNbD8htO/SQ<br>VtiB8BL8SJ8HlRy2REDwvNMj0ChWeFjimb6k/40vKet3lmmAwewjy4OWBkkfrv3Y<br>/I+RQ8Ua3vsz8KZywZvXAYWTTnsFbsHQBv9TgI0crKajVgm06stz7X+RHmhVyckV<br>54nSQhzZPagxfwJNzcKNb+HMr57D6SNl8xYLK1V5lmDjtAFeII3fnCJpCszNptKy<br>cHY8Jq1eb5no5cAK7WfvepVQD0CGR6JhEuNpYNa0bp6uGTYv9EqYYqrNq8cx/41v<br>jaNI9N6oqi3Qqt+MARXXLgMjl1CYZQ7mNT0pOXPC6gEFoyKhTnDmACAV82WB1ClR<br>ZlY/eRzAK/iXECs=<br>-----END CERTIFICATE-----<br>-----BEGIN CERTIFICATE-----<br>MIIFdzCCA1+gAwIBAgIJAITnARyY8iCRMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNV<br>BAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJUGFsbyBBbHRvMQ8wDQYDVQQK<br>DAZWTXdhcmUxJDAiBgNVBAMMG25zeG1hbmFnZXIucGtzLnZtd2FyZS5sb2NhbDAe<br>Fw0yMDEyMTUwOTIzMjVaFw0zMDEyMTMwOTIzMjVaMGUxCzAJBgNVBAYTAlVTMQsw<br>CQYDVQQIDAJDQTESMBAGA1UEBwwJUGFsbyBBbHRvMQ8wDQYDVQQKDAZWTXdhcmUx<br>JDAiBgNVBAMMG25zeG1hbmFnZXIucGtzLnZtd2FyZS5sb2NhbDCCAiIwDQYJKoZI<br>hvcNAQEBBQADggIPADCCAgoCggIBAJ1vvdCHRdGFvleEAGANFv9ttVAa4DdewpKK<br>M+DCyOnRfnsfJWxtTSpzu+nDQg9/wvFs2RQBu+Yh1iF40KVc6aYMDjxb+4uAC2nR<br>/0g8ANGXYE1BoDShJwwTosWrQ6RaPTLw3rK4U6+OW//g7EHUR9LRHNRRdItbyXkT<br>ULQac4x/k8ApwXQvFZ6Vb/L+nNBUBJQapWoi361v7Z2fxzmJwB9D+KfGU4pMKKL7<br>/VuMvDaZuxzeAnPdkaYrmF8XlnUr5ZoW85xWLVLPPRjDqcNiKcXBhUHWUB3+RzEc<br>1leLcX9yrtiJjO91hTzsTPvd4Tqi8ojyY+SILJiqJRDNcrVtrW+leVlxOGcLgnT3<br>gR3EB5zAaT8z+RBMn+SPJSUKslh1P/bAyOaPLg3NQwTpk/gDoShGva01y/7/kBnk<br>nvkz6mTl+UZIWCj5cI7a3+zkR6ptNZDArn2JpFW1ePmnQjz+Bt7y6tueJxnj8Q5M<br>cUbEOhcqfzadpJort0/70STtR0LSvLe0Q+8r1sTDuO9RXjqqdbveyp9w+dUFW1et<br>SF/w+ak3f4nZZCjI0FU68HtzNmmqPdgKJuE197J4XNVyCHQW1h0X2zURyvGOYp5D<br>UHsdQYfm6G0aw3VppiT71t5BeBQi2Z6jyVVqGGBf36rhbp8BsP5FxTQI7apXR/u3<br>jhTblAvHAgMBAAGjKjAoMCYGA1UdEQQfMB2CG25zeG1hbmFnZXIucGtzLnZtd2Fy<br>ZS5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAgEAlvoh8fFQpAzElmkIVLBr739cscLz<br>ALXnBgAFPhR/leoZjdEdHfq7Pm80dtEaluCrm81MX1wKiCJKgA6oAzAf7vK1seu5<br>Mx4yu9hwpNE9xXheea5cASzvR355JPjvUdFohChuvnVcPV0yZdVzEOhtmyrYPCHd<br>OYcEA0xyV2sqKZRil39dHRi1VRoALZL8n2UHZa1EN0wTHfRKdmx9QOAxhsxhNSMg<br>kiCMGe9OoYfcU98dlXNclvkIqkVl8RN6W4A8z/7VFB/Aq3NQBfGeTR3l/+dZH+e0<br>boioZDkpGRVCtfYyjvfPRUeMJXgqUfdMIsQGm0YbtQ0PWhIhjdxiuLUJ4jEqen8G<br>5ssz0/V4vlJ0wgkhliQcybxRhCWayKr95kuV6yiHKZgpTX9ovOhE+Ew208Y6Poh3<br>vR7YAWfyI7QxPAhSuLMQFKtRbD2cbAQ/CD+CsFVquiGj8J6DUS+pWPr5JHNz8rzA<br>Ba29dMTPeKmbbW3aHZ4pA2aJNT5lmA6RQ85cR7oNU48HAhwSqpw23NZQb2MF7Qqp<br>cTey+etb2kVR83fp47g2hfgzCBKoTYdqC5G5kVarvO1+BsdKwApz+iElUqKfkRZo<br>NwHJp5KUauGKGrN2WY5yAMUq9iEsVlTBt+rsixtnRlP1yhGhc9DrLsKquOw03myL<br>hDISqFnOh+zVz10=<br>-----END CERTIFICATE-----</div><div><br></div><div>```<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Jochen Bern <<a href="mailto:Jochen.Bern@binect.de" target="_blank">Jochen.Bern@binect.de</a>> 于2020年12月24日周四 下午7:44写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 23.12.20 23:56, <a href="mailto:openssl-users-request@openssl.org" target="_blank">openssl-users-request@openssl.org</a> digested:<br>
> Message: 4<br>
> Date: Wed, 23 Dec 2020 23:56:44 +0100<br>
> From: David von Oheimb <<a href="mailto:dev@ddvo.net" target="_blank">dev@ddvo.net</a>><br>
[...]<br>
> Yet since both your old and new server cert are not expired and have the<br>
> same subject, keyIdentifier, and serial number,<br>
> and you appended the new server cert to your list, it is no surprise<br>
> that the certificate chain building algorithm will pick up the old one.<br>
> For efficiency reasons, no other (equally applicable) certificates will<br>
> be tried.<br>
<br>
To expand on the "*should* you actually do it like this" angle: I do not<br>
see any reason why the new server cert (SC) should have *the same serial<br>
number* (SN) as the old one.<br>
<br>
At least in the general case - where the CA and the server are run by<br>
different entities -, the CA wants(*) to be able to revoke old and new<br>
SC separately, and CRLs identify revoked certs exclusively by the<br>
issuing CA Cert (CC) and the revoked cert's SN.<br>
<br>
So, what *is* the rationale to reuse the SN? Do you have a<br>
"verification" mechanism somewhere that (cannot be updated in a timely<br>
manner for the new SC and) would protest a changed SN, but *not* the<br>
changed validity period (or, for that matter, fingerprint or CA<br>
signature)? Note that the mere thought already makes me put quote marks<br>
around "verification" ...<br>
<br>
Disclaimer: I'm *not* saying that merely using different SNs will make<br>
the problem you're currently experiencing disappear. In fact, I consider<br>
that rather unlikely, but it might be one contributing factor.<br>
<br>
(*) Scenario 1: Before the old SC expires, the CA finds out that it<br>
issued a new SC to an imposter, so they now want to revoke the new but<br>
not the old. Scenario 2: The old SC is found to have been leaked after<br>
the new one was already issued, so at least the server admin would<br>
prefer to have the old SC revoked but *not* the new one.<br>
<br>
Kind regards,<br>
-- <br>
Jochen Bern<br>
Systemingenieur<br>
<br>
Binect GmbH<br>
<br>
</blockquote></div></div></div>
</blockquote></div>