Skip to content

Commit

Permalink
PROTON-2856: allow trusted intermediate CA verification using OpenSSL
Browse files Browse the repository at this point in the history
  • Loading branch information
Cliff Jansen committed Nov 5, 2024
1 parent 636ddf4 commit 2aed374
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 1 deletion.
2 changes: 1 addition & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions c/src/ssl/PLATFORM_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
========
Expand Down
4 changes: 4 additions & 0 deletions c/src/ssl/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions c/src/tls/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions python/tests/proton_tests/ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,30 @@ def test_server_authentication(self):
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")
Expand Down
12 changes: 12 additions & 0 deletions python/tests/proton_tests/ssl_db/mkcerts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Binary file not shown.
20 changes: 20 additions & 0 deletions python/tests/proton_tests/ssl_db/server-certificate-ca2.pem
Original file line number Diff line number Diff line change
@@ -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-----
34 changes: 34 additions & 0 deletions python/tests/proton_tests/ssl_db/server-private-key-ca2.pem
Original file line number Diff line number Diff line change
@@ -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-----
17 changes: 17 additions & 0 deletions python/tests/proton_tests/ssl_db/server-request-ca2.pem
Original file line number Diff line number Diff line change
@@ -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-----
16 changes: 16 additions & 0 deletions python/tests/proton_tests/ssl_db/subca-certificate.pem
Original file line number Diff line number Diff line change
@@ -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-----
17 changes: 17 additions & 0 deletions python/tests/proton_tests/ssl_db/subca-request.pem
Original file line number Diff line number Diff line change
@@ -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-----
Binary file added python/tests/proton_tests/ssl_db/subca.pkcs12
Binary file not shown.

0 comments on commit 2aed374

Please sign in to comment.