This is an automated email from the ASF dual-hosted git repository. cliffjansen pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
The following commit(s) were added to refs/heads/main by this push: new 2aed37433 PROTON-2856: allow trusted intermediate CA verification using OpenSSL 2aed37433 is described below commit 2aed3743363835ee63858a276d88d4cc4c0c6189 Author: Clifford Jansen <cliffjan...@apache.org> AuthorDate: Tue Nov 5 10:59:57 2024 -0800 PROTON-2856: allow trusted intermediate CA verification using OpenSSL --- INSTALL.md | 2 +- c/src/ssl/PLATFORM_NOTES.md | 4 +++ c/src/ssl/openssl.c | 4 +++ c/src/tls/openssl.c | 4 +++ python/tests/proton_tests/ssl.py | 24 +++++++++++++++ python/tests/proton_tests/ssl_db/mkcerts.sh | 12 ++++++++ python/tests/proton_tests/ssl_db/server-ca2.pkcs12 | Bin 0 -> 2519 bytes .../proton_tests/ssl_db/server-certificate-ca2.pem | 20 ++++++++++++ .../proton_tests/ssl_db/server-private-key-ca2.pem | 34 +++++++++++++++++++++ .../proton_tests/ssl_db/server-request-ca2.pem | 17 +++++++++++ .../proton_tests/ssl_db/subca-certificate.pem | 16 ++++++++++ python/tests/proton_tests/ssl_db/subca-request.pem | 17 +++++++++++ python/tests/proton_tests/ssl_db/subca.pkcs12 | Bin 0 -> 2533 bytes 13 files changed, 153 insertions(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index fa9975143..56db95885 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -20,7 +20,7 @@ Linux dependencies - GNU Make 3.81+ - GCC 9+ - Cyrus SASL 2.1+ (for SASL support) - - OpenSSL 1.0+ (for SSL support) + - OpenSSL 1.0.2a+ (for SSL support) - JsonCpp 1.8+ for C++ connection configuration file support Windows dependencies diff --git a/c/src/ssl/PLATFORM_NOTES.md b/c/src/ssl/PLATFORM_NOTES.md index 1c4c5175b..fa5664afc 100644 --- a/c/src/ssl/PLATFORM_NOTES.md +++ b/c/src/ssl/PLATFORM_NOTES.md @@ -21,6 +21,10 @@ of the certificate's name. See [here](https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.htm) for more details. +Proton uses the OpenSSL X509_V_FLAG_PARTIAL_CHAIN flag during peer verification. +All certificates included in a CA database, including those for intermediate +Certificate Authorities, will be treated as potential trust anchors by OpenSSL. + SChannel ======== diff --git a/c/src/ssl/openssl.c b/c/src/ssl/openssl.c index 4a1fc12b0..7455cb618 100644 --- a/c/src/ssl/openssl.c +++ b/c/src/ssl/openssl.c @@ -555,6 +555,10 @@ static bool pni_init_ssl_domain( pn_ssl_domain_t * domain, pn_ssl_mode_t mode ) return false; }; + // Support intermediate/subordinate CAs as trust anchors. + X509_STORE* store = SSL_CTX_get_cert_store(domain->ctx); + X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN); + const long reject_insecure = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 diff --git a/c/src/tls/openssl.c b/c/src/tls/openssl.c index 4ba457d13..8b78891cd 100644 --- a/c/src/tls/openssl.c +++ b/c/src/tls/openssl.c @@ -858,6 +858,10 @@ static bool pni_init_ssl_domain( pn_tls_config_t * domain, pn_tls_mode_t mode ) return false; }; + // Support intermediate/subordinate CAs as trust anchors. + X509_STORE* store = SSL_CTX_get_cert_store(domain->ctx); + X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN); + const long reject_insecure = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 diff --git a/python/tests/proton_tests/ssl.py b/python/tests/proton_tests/ssl.py index edb5f2cf6..a16adad1f 100644 --- a/python/tests/proton_tests/ssl.py +++ b/python/tests/proton_tests/ssl.py @@ -229,6 +229,30 @@ class SslTest(common.Test): server.connection.close() self._pump(client, server) + def test_intermediate_ca(self): + """ Ensure an intermediate/subordinate certificate can be used as a CA for validation. + """ + if os.name == "nt": + raise Skipped("Test of OpenSSL X509_V_FLAG_PARTIAL_CHAIN flag.") + self.server_domain.set_credentials(self._testpath("server-certificate-ca2.pem"), + self._testpath("server-private-key-ca2.pem"), + "server-password") + + self.client_domain.set_trusted_ca_db(self._testpath("subca-certificate.pem")) + self.client_domain.set_peer_authentication(SSLDomain.VERIFY_PEER) + + server = SslTest.SslTestConnection(self.server_domain, mode=Transport.SERVER) + client = SslTest.SslTestConnection(self.client_domain) + + client.connection.open() + server.connection.open() + self._pump(client, server) + assert client.ssl.get_cert_subject() is not None + assert client.transport.condition is None + client.connection.close() + server.connection.close() + self._pump(client, server) + def test_certificate_fingerprint_and_subfields(self): if os.name == "nt": raise Skipped("Windows support for certificate fingerprint and subfield not implemented yet") diff --git a/python/tests/proton_tests/ssl_db/mkcerts.sh b/python/tests/proton_tests/ssl_db/mkcerts.sh index 84e64b1aa..0fe91aba7 100644 --- a/python/tests/proton_tests/ssl_db/mkcerts.sh +++ b/python/tests/proton_tests/ssl_db/mkcerts.sh @@ -43,6 +43,18 @@ keytool -ext san=dns:alternate.name.one.com,dns:another.name.com -storetype pkcs keytool -ext san=dns:alternate.name.one.com,dns:another.name.com -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -keypass ca-password -gencert -rfc -validity 99999 -infile server-wc-request.pem -outfile server-wc-certificate.pem openssl pkcs12 -nocerts -passin pass:server-password -in server-wc.pkcs12 -passout pass:server-password -out server-wc-private-key.pem +# Create a certificate for a subordinate (intermediate) CA certificate issued by the root CA +keytool -storetype pkcs12 -keystore subca.pkcs12 -storepass subca-password -alias subca-certificate -keypass subca-password -keyalg RSA -genkey -dname "O=Trust Me Inc.,CN=Trusted.CA.com level 2 CA" -validity 99999 +keytool -storetype pkcs12 -keystore subca.pkcs12 -storepass subca-password -alias subca-certificate -keypass subca-password -certreq -file subca-request.pem +keytool -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -keypass ca-password -gencert -rfc -validity 99999 -infile subca-request.pem -outfile subca-certificate.pem -ext bc:c=ca:true -ext ku:c=digitalSignature,keyCertSign + +# Create a certificate request for a server certificate signed by the subordinate CA. +keytool -storetype pkcs12 -keystore server-ca2.pkcs12 -storepass server-password -alias server-certificate -keypass server-password -keyalg RSA -genkey -dname "O=Server,CN=serverbyca2.domain.com" -validity 99999 +keytool -storetype pkcs12 -keystore server-ca2.pkcs12 -storepass server-password -alias server-certificate -keypass server-password -certreq -file server-request-ca2.pem +keytool -storetype pkcs12 -keystore subca.pkcs12 -storepass subca-password -alias subca-certificate -keypass subca-password -gencert -rfc -validity 99999 -infile server-request-ca2.pem -outfile server-certificate-ca2.pem -ext bc:c=ca:false +openssl pkcs12 -nocerts -passin pass:server-password -in server-ca2.pkcs12 -passout pass:server-password -out server-private-key-ca2.pem + + # Create pkcs12 versions of the above certificates (for Windows SChannel) # The CA certificate store/DB is created without public keys. # Give the "p12" files the same base name so the tests can just change the extension to switch between platforms. diff --git a/python/tests/proton_tests/ssl_db/server-ca2.pkcs12 b/python/tests/proton_tests/ssl_db/server-ca2.pkcs12 new file mode 100644 index 000000000..886f42070 Binary files /dev/null and b/python/tests/proton_tests/ssl_db/server-ca2.pkcs12 differ diff --git a/python/tests/proton_tests/ssl_db/server-certificate-ca2.pem b/python/tests/proton_tests/ssl_db/server-certificate-ca2.pem new file mode 100644 index 000000000..35ee35523 --- /dev/null +++ b/python/tests/proton_tests/ssl_db/server-certificate-ca2.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIETH/jWTANBgkqhkiG9w0BAQsFADA8MSIwIAYDVQQDExlU +cnVzdGVkLkNBLmNvbSBsZXZlbCAyIENBMRYwFAYDVQQKEw1UcnVzdCBNZSBJbmMu +MCAXDTI0MTAyOTE2MzUyNVoYDzIyOTgwODEzMTYzNTI1WjAyMR8wHQYDVQQDExZz +ZXJ2ZXJieWNhMi5kb21haW4uY29tMQ8wDQYDVQQKEwZTZXJ2ZXIwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCAkuroiKjCUTgbwtWmMj8B7M0dIpc5mdyI +Dd1Fb6WwEiicuqj0cHYzcCmPimJBuGKUSbLyxUWwha725Dfc9HOZIrLsBSIdE9C4 +liyYn62d6J2KNVDIIMzcFujSMYJjoyL9p2iTXyaaulwHtEfHtiOWSMGryr38FqJD +ww/c9hJfqCVD1HoLhQolPj/JJ0ksNWZuCaq//j/ejfH8WRwHY2wP2sjEa8rYhEnU +derfs+yW44FDtjJzWmRn9W3SzUS5QFJ4uJ26mUzB3RpxQV6BSsK90Cd/NipiDhNr +p3r2J5PjblgKEENoE7apUkPmQgWlUSQx4ol4RA9yDJJjHMU68fLlAgMBAAGjUDBO +MB8GA1UdIwQYMBaAFDNmLOL72gohr3C2bnth7HT88Pw3MAwGA1UdEwEB/wQCMAAw +HQYDVR0OBBYEFP/V44xYE8qPQ0211umWbVciKe1wMA0GCSqGSIb3DQEBCwUAA4IB +AQByHSor8RP88Ii0c5PVLvrsvgXT/Kf9uQDAzt5Kq4q2W91zMYNdqAo8FURXoFCK +oN6Zu7hgTUjXYjqBWmA4KozpMzxFQeTY+IYGNq/lskQebjE9gWGS4QJD2vOacypp +a8SkzRKqpyTMNLvOgyteUwQ5oZE7HTGmxIP/tRuhsgjnSZZwUQLftd8BgCGj0e8O +46CXSmTzmxWyQf02PNkyDdoZAiBMgx0L4MpuDjYfM9lQWBn5+Sh0o0H4icml6rFD +HmubbLElFaCrF4qN/8e25TCkMgn3dWP6ITQUjSKtp6TXxevrv4PD4wtapvPUpMDE +7myoawP0qOlXq4jhYqQsvio+ +-----END CERTIFICATE----- diff --git a/python/tests/proton_tests/ssl_db/server-private-key-ca2.pem b/python/tests/proton_tests/ssl_db/server-private-key-ca2.pem new file mode 100644 index 000000000..3eb2ff14c --- /dev/null +++ b/python/tests/proton_tests/ssl_db/server-private-key-ca2.pem @@ -0,0 +1,34 @@ +Bag Attributes + friendlyName: server-certificate + localKeyID: 54 69 6D 65 20 31 37 33 30 32 31 39 37 32 34 31 37 31 +Key Attributes: <No Attributes> +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIO2cXV6kdWUkCAggA +MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECEJoje0kvByWBIIEyHu2jG1GIGCC +69Z4bIgwSORPXdXiH+DIw3JD+lifOjBOGo4FIQQDTYeCwp4y3aBS/40ad4Gv1nSk +N9wrbMjghaqkAwshNoKWJIM+YBvpeFb87gGQKzCiwBJkYeX3sqiiQAwoSOyL6eiN +oEtZUfJlV5kN9OwCnD4HuOdrwVGmj3iB9rPfXZe/KLXAlf5awK7y2bRi1Gq3PVOt +px+ToT9qGOx+JsEd1JlQjEJL09KdE87LxEp8SLzWl0hSMecgmyfp5EQ68ESg+x0t +DiM58DaSSP0f0HBK4q08a49kxp2puQsq2+lHy2iobNrhB5VUKRKfcALIAOkgPJK6 +xKMSMyEZTf03cnK3TUDPcLM4oKnXqkSoqZqO1adIXSii18Msb+aHVwKjsfpOTQFD +cexj2TJmClVfZHDdnUrAfyNS2PRR7U0OjJ/wWJtSAdIP3lpV0N9s5Xmp7uHRAmcq +Q3XDdc5U1iGG+VsfqSQT61kXE/61UgZHZntbfYs/xfxt1ZGCqXVrk+gqYfoHAZpl +Xq6BYX8s5Ea+o5GR5zEZZvcYEiWPNhgGrRqkSi/UIRHAAK8xmtIJooOPUw/D38aZ +MF1IGiZTZPJMTv8SVn73FEPLJyj3JpTNs7Zwok15pT/BpEHuP09LzR5J4KiepAwW +meL6qDFLms7Hl/MIkociqlXcePUCUp2GtyP5s8e4us/+cv4kOxVUY0g//9j2UOgz +FwZGoqfyclcQ+PeXAn4qesMQe0F2PLroQUXhEwAUvb6kZZg9Lak7u8wbsaE08JWO +Z24St2PTPtE53ogTPUtNtpm5Un/MdgytpXnzMJnG2StJfDklIlXco8oxzrM3ATXp +a+/uSfUcLJ7Y/ibDd5XOtTtMJLEBoYGMjOPavm5u72nNcdJEsrEBmaDXcipeW0bu +/LiaA5g2NEvo5sH6ntPfjhHpcj8uxDlxVxlO4RHOWk9BtvVA6dYLsTM21nyy5pp1 +AM1iuKexfuVkFOK9gnfU1o81hxuRJl62iXxJciBfjkCjxI7iyFCD9BoJ4YHgAXAv +W3ixItVcN9l2yIk9gOvYwQbQ0j9j/m1JD99YvLBIxqUaxX3KzghIZBqzEeLnXbdq +ul1DO+vO4mm+ZnYGaj0YRjmmZXKOElsHlQ/fw1rGfGssnBTnbuTZvII+SGIcPJ3N +EdhVLb2B22jw9PaxdNNQd+5xIdceg5c8aB8zSBb0rrGuqLPzM0fs2+zkj7fRpLvR +L2qB2QWki5GBAKpN+4kGHGDD1XgFfeA2vBkizt92gqbUSly4ifSJZz55S5BESrAd +bzO/ZxIKQb4imatQiQT7JemRteNfxYN3JKaRcvh45OMA8urUFvP91iZt2bFY+asQ +Fw4YWogNmvWICnM8NMYp3WRpBizOGFTm14kxKfdbOrInZpStYx8EHHwS78a44iSH +6/kjK8z+OaCuhC29xVjQkJal8X0qODR0ImDJtnXiHCv0cV8aYM2WiwXUGrGRFOIE +LbQ4GkfeaOzhsKYovb5oD6OX3mWTOQ36TkoEHzDc25iqvJtmx9upnHcZ57F+k9iI +JHGF9Lja4w1hlwEt5Wp0oVdHPuWnptzHkHAF846Bc6z2YkqvZ0jWaW0Rd6FlNz3O +nI6Z5TjPvDRbsjsDRpuhQw== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/python/tests/proton_tests/ssl_db/server-request-ca2.pem b/python/tests/proton_tests/ssl_db/server-request-ca2.pem new file mode 100644 index 000000000..524124a0e --- /dev/null +++ b/python/tests/proton_tests/ssl_db/server-request-ca2.pem @@ -0,0 +1,17 @@ +-----BEGIN NEW CERTIFICATE REQUEST----- +MIICpzCCAY8CAQAwMjEfMB0GA1UEAxMWc2VydmVyYnljYTIuZG9tYWluLmNvbTEP +MA0GA1UEChMGU2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +gJLq6IiowlE4G8LVpjI/AezNHSKXOZnciA3dRW+lsBIonLqo9HB2M3Apj4piQbhi +lEmy8sVFsIWu9uQ33PRzmSKy7AUiHRPQuJYsmJ+tneidijVQyCDM3Bbo0jGCY6Mi +/adok18mmrpcB7RHx7YjlkjBq8q9/BaiQ8MP3PYSX6glQ9R6C4UKJT4/ySdJLDVm +bgmqv/4/3o3x/FkcB2NsD9rIxGvK2IRJ1HXq37PsluOBQ7Yyc1pkZ/Vt0s1EuUBS +eLiduplMwd0acUFegUrCvdAnfzYqYg4Ta6d69ieT425YChBDaBO2qVJD5kIFpVEk +MeKJeEQPcgySYxzFOvHy5QIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4E +FgQU/9XjjFgTyo9DTbXW6ZZtVyIp7XAwDQYJKoZIhvcNAQELBQADggEBAD+kJpkF +iVCh/xVk1fpwwk0U+c2WYqRY0xPgeryEdA7kxiINtoNevKFed6hr+nfmnksP4XM+ +snIiAW05MkIw9xf7L9pgN22NNbjPZGCC1WTNy4pvR5r/fuOj1bMXQKL1xnBk9gBC +m42cFJ0W59bF7KVR1v2wdNBoleU60JW4KMMxUgqav4KUHuysRcGBPEcNrk03TYuO +y3BMLtzLT0ivRfbeMV4P0jajDRfefPFtognXTngVEgFlbAZVI+aPc0k5mJ5LIK00 +suZsu+AsXHylrONfqdElZbmOkqxUD69GwtlTbB7zR+DNlOaxJOU8vFgKMsK0YJfZ +rUQPaRS37zg7FrI= +-----END NEW CERTIFICATE REQUEST----- diff --git a/python/tests/proton_tests/ssl_db/subca-certificate.pem b/python/tests/proton_tests/ssl_db/subca-certificate.pem new file mode 100644 index 000000000..39758e50a --- /dev/null +++ b/python/tests/proton_tests/ssl_db/subca-certificate.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICkzCCAjegAwIBAgIEZM0SnTAMBggqhkjOPQQDAgUAMDExFzAVBgNVBAMTDlRy +dXN0ZWQuQ0EuY29tMRYwFAYDVQQKEw1UcnVzdCBNZSBJbmMuMCAXDTI0MTAyOTE2 +MzUyM1oYDzIyOTgwODEzMTYzNTIzWjA8MSIwIAYDVQQDExlUcnVzdGVkLkNBLmNv +bSBsZXZlbCAyIENBMRYwFAYDVQQKEw1UcnVzdCBNZSBJbmMuMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwA9maO5b0seoaC5ZbEr2c1JPtF/U0Cfzg8nh +yCyKxhNrw9TzGApijMOn92i7LyE8wv2BgMOQPmAgZ+xVUtEJO79AZ2Xxu8y9LPLN +UqBlgGykMrpPl6j4dfJfQyWuDZh4gFYoywHZ7kWAkDxvwNl6CtCxa8JGOT0NbQk/ +nCDQF4OR9nttWPgXw1HqT8mpu9/YrO7OB5XoBAF7DxxGFDi+ZT5MZNpdTsZbr88Z +ZJ1VXqsh7zC4+DRGADGTcMdGLCaO9uw+jpr4p3mPzkJN8E20N4L7UiEEdeB/vVFP +yRB3x1Jr+B0dYXAImF9fP0EOSruk3y4Q/64ENpWoGd+G4pXT3QIDAQABo2MwYTAf +BgNVHSMEGDAWgBSlzcWwofcIWyGFD/80a/bZWckKVTAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIChDAdBgNVHQ4EFgQUM2Ys4vvaCiGvcLZue2HsdPzw/Dcw +DAYIKoZIzj0EAwIFAANIADBFAiAa4hVR9oS2MDHe01UQ6Sg93xin14egkLh6Ku/i +gbyR6QIhALS6UkuQxU9986x5qChgqmwXLfqYAQ+MSwj44c+GXo4w +-----END CERTIFICATE----- diff --git a/python/tests/proton_tests/ssl_db/subca-request.pem b/python/tests/proton_tests/ssl_db/subca-request.pem new file mode 100644 index 000000000..9308aea20 --- /dev/null +++ b/python/tests/proton_tests/ssl_db/subca-request.pem @@ -0,0 +1,17 @@ +-----BEGIN NEW CERTIFICATE REQUEST----- +MIICsTCCAZkCAQAwPDEiMCAGA1UEAxMZVHJ1c3RlZC5DQS5jb20gbGV2ZWwgMiBD +QTEWMBQGA1UEChMNVHJ1c3QgTWUgSW5jLjCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMAPZmjuW9LHqGguWWxK9nNST7Rf1NAn84PJ4cgsisYTa8PU8xgK +YozDp/douy8hPML9gYDDkD5gIGfsVVLRCTu/QGdl8bvMvSzyzVKgZYBspDK6T5eo ++HXyX0Mlrg2YeIBWKMsB2e5FgJA8b8DZegrQsWvCRjk9DW0JP5wg0BeDkfZ7bVj4 +F8NR6k/Jqbvf2KzuzgeV6AQBew8cRhQ4vmU+TGTaXU7GW6/PGWSdVV6rIe8wuPg0 +RgAxk3DHRiwmjvbsPo6a+Kd5j85CTfBNtDeC+1IhBHXgf71RT8kQd8dSa/gdHWFw +CJhfXz9BDkq7pN8uEP+uBDaVqBnfhuKV090CAwEAAaAwMC4GCSqGSIb3DQEJDjEh +MB8wHQYDVR0OBBYEFDNmLOL72gohr3C2bnth7HT88Pw3MA0GCSqGSIb3DQEBCwUA +A4IBAQBBXQ8383OEtUQx1HAIb09TmgzdCWitcUZx4swpDymzCFj++vqtHlig35wO +OvoW/ToOz6INtrTE+2CQGQXcW7+4N8XMyOur+G8Z8EOnfZQZTnGKfmqL97sq50OO +fcsqcczmbeBjqyN72cozNFoZVz6IB5/IBTUL8CSXq/onXupGqOcTiqTK7YqEW0bN +ovNAeNQa1wWQhMi+AF/U1HVIJ1zNnW+MotB/FjvezCMd/uBKJPlvCz92DIHHc1eG +GpaaOncglPR9JHBu5LzhTr/Q/4KuNWkBF5I+MDgjYpbZEUkCSIXBmefjIH25ZnqM +IuxvnKrvs4AKqLZ/M/tu2H8yqKWP +-----END NEW CERTIFICATE REQUEST----- diff --git a/python/tests/proton_tests/ssl_db/subca.pkcs12 b/python/tests/proton_tests/ssl_db/subca.pkcs12 new file mode 100644 index 000000000..1dd6b07b6 Binary files /dev/null and b/python/tests/proton_tests/ssl_db/subca.pkcs12 differ --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org