Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed

Conversation

Rinzwind
Copy link
Contributor

@Rinzwind Rinzwind commented Jun 1, 2024

This pull request extends the macOS implementation of the SqueakSSL plugin to support setting a certificate on the SSL session context. The certificate and private key can be given by setting the ‘CERTNAME’ property to the path of a PKCS#12 file (the Windows implementation expects the property to be set to the name of a certificate in a certificate store, while the Unix implementation expects the path to a PEM file). The function ‘SecPKCS12Import’ that is used to read the PKCS#12 file seems to require it to have a non-empty password, so a property ‘CERTPASS’ for giving the password is added. Commit 3d9d900 also fixes a bug in ‘sqAcceptSSL’.

This can be used to set up a ZnSecureServer on macOS as follows (which assumes #certificatePassword: has been implemented similarly to the implementation of #certificate: and #certificateName: on ZdcPluginSSLSession):

"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'.

"Put the server private key and the certificate signed by the certificate authority in a PKCS#12 file:"
result4 := LibC resultOfCommand: 'cd /tmp && /usr/bin/openssl ' ,
	'pkcs12 -export -inkey s-key -in s-cert2 ' ,
	'-out s-pkcs12 -password pass:password123 2>&1'.

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

"Start a ZnSecureServer with the PKCS#12 file and password:"
(server := ZnSecureServer on: 1443)
	certificate: '/tmp/s-pkcs12';
	certificatePassword: 'password123';
	logToTranscript;
	start.

"Get ‘/’ from the server:"
response := ZnEasy get: 'https://localhost:1443'.

Browsing ‘https://localhost:1443’ works with Chrome and Firefox. With Safari, a ConnectionClosed is signaled while performing #accept on a ZdcSecureSocketStream, I haven’t tried to find the cause yet.

A point I’m not sure about is whether the ‘items’ array assigned by ‘SecPKCS12Import’ should be released or not, though I assumed not as the function doesn’t have ‘Create’ or ‘Copy’ in its name (see ‘The Create Rule’ in the ‘Memory Management Programming Guide for Core Foundation’).

There’s a corresponding issue that I had opened about this in the OpenSmalltalk VM repository: OpenSmalltalk VM issue #680.

…tate to ‘SQSSL_CONNECTED’, returned the value of ‘SQSSL_OK’ (zero) rather than the number of bytes written to the output buffer.
…ng been set (expected to be the path to a file of at most 128KiB with data that can be imported by ‘SecPKCS12Import’ as an array whose first item contains a ‘SecIdentityRef’ that is passed to ‘SSLSetCertificate’) and added support for setting a ‘CERTPASS’ property (expected to be the password needed by ‘SecPKCS12Import’).
@Rinzwind
Copy link
Contributor Author

Rinzwind commented Jun 3, 2024

I converted this to a draft because of the question in the OpenSmalltalk VM issue on whether to use ‘CERTNAME’ to identity a certificate in a keychain rather than as the path to a file containing the certificate like it is implemented here.

As for the problem with Safari, I found that when using port forwarding through ‘socat’ as follows, browsing ‘https://localhost:2443’ does work:

$ socat TCP6-LISTEN:2443,fork TCP4:localhost:1443

If I change the command to use ‘TCP4-LISTEN’ as follows instead, then browsing ‘https://localhost:2443’ also causes the signaling of a ConnectionClosed while performing #accept on a ZdcSecureSocketStream:

$ socat TCP4-LISTEN:2443,fork TCP4:localhost:1443

I’m afraid I don’t understand why that is though.

@Rinzwind
Copy link
Contributor Author

I closed this and opened a new pull request: pull request #816.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant