pharo-project / pharo-vm

This is the VM used by Pharo
http://pharo.org
Other
113 stars 68 forks source link

Extend macOS implementation of SqueakSSL plugin to support setting a certificate on the SSL session context #816

Closed Rinzwind closed 3 months ago

Rinzwind commented 3 months ago

This pull request extends the macOS implementation of the SqueakSSL plugin to support setting a certificate on the SSL session context. It differs from pull request #812 in that the ‘CERTNAME’ property is used to identify a certificate and private key in a keychain rather than as the path to a file containing the certificate and private key. Commit 539aedd1d4 in this pull request corresponds to commit 3d9d9004f7 in the earlier pull request and fixes a bug in ‘sqAcceptSSL’.

This can be used to set up a ZnSecureServer on macOS as follows:

"Generate a private key and certificate for a certificate authority:"
result1 := LibC resultOfCommand: 'cd /tmp && /usr/bin/openssl ' ,
    'req -x509 -newkey rsa -nodes -keyout ca-key -out ca-cert ' ,
    '-subj "/CN=ZnSecureServer Test CA Certificate" 2>&1'.

"Generate a private key and certificate for the server:"
result2 := LibC resultOfCommand: 'cd /tmp && /usr/bin/openssl ' ,
    'req -x509 -newkey rsa -nodes -keyout s-key -out s-cert1 ' ,
    '-subj "/CN=ZnSecureServer Test Server Certificate" ' ,
    '-addext subjectAltName=DNS:localhost 2>&1'.

"Generate a certificate for the server signed by the certificate authority:"
result3 := LibC resultOfCommand: 'cd /tmp && /usr/bin/openssl ' ,
    'x509 -in s-cert1 -out s-cert2 ' ,
    '-CAkey ca-key -CA ca-cert -CAserial ca-srl -CAcreateserial 2>&1'.

"Add the server certificate signed by the certificate authority to the ‘login’ keychain:"
result4 := LibC resultOfCommand: 'cd /tmp && /usr/bin/security ' ,
    'add-certificates -k ~/Library/Keychains/login.keychain-db s-cert2 2>&1'.

"Add the server private key to the ‘login’ keychain:"
result5 := LibC resultOfCommand: 'cd /tmp && /usr/bin/security ' ,
    'import s-key -k ~/Library/Keychains/login.keychain-db 2>&1'.

"Add the certificate authority’s certificate as trusted to the ‘login’ keychain (needs confirmation):"
result6 := LibC resultOfCommand: 'cd /tmp && /usr/bin/security ' ,
    'add-trusted-cert -k ~/Library/Keychains/login.keychain-db ca-cert 2>&1'.

"Start a ZnSecureServer with ‘certificate’ set to the common name of the server certificate’s subject:"
(server := ZnSecureServer on: 1443)
    certificate: 'ZnSecureServer Test Server Certificate';
    logToTranscript;
    start.

"Get ‘/’ from the server (needs permission to use the private key, use the button to always allow):"
response := ZnEasy get: 'https://localhost:1443'.

Browsing ‘https://localhost:1443’ works with Chrome and Firefox. As noted in the earlier pull request, with Safari, there’s a problem which seems to be related to the use of IPv4 rather than IPv6.

The earlier pull request was closed, and this new one opened, following comments given in OpenSmalltalk VM issue #680. As mentioned there, a concern now could be that there can be multiple certificates for the same subject, which one is then used is not really specified, except that expired certificates are excluded from the search performed through ‘SecItemCopyMatching’ by using ‘kSecMatchValidOnDate’ in the query.

Rinzwind commented 3 months ago

I replaced commit a675a2b647 by commit 28670bcf54 to fix a mistake: the return value of ‘SSLSetCertificate’ didn’t get assigned to ‘status’.

Rinzwind commented 3 months ago

It’s ready for integration yes.

guillep commented 3 months ago

Thanks!