Java Bug : Mutual HTTPS authentication not possible with a non-extractable private key with Apple/KeychainStore

Wei-Jun Wang weijun.wang at oracle.com
Thu May 6 00:09:52 UTC 2021



> On May 3, 2021, at 1:16 PM, Jean-Yves Cronier <cronier.jy at gmail.com> wrote:
> 
> Following the advice of Wei-Jun Wang, I share/forward to this mailing-list, details of a problem that I encounter on MacOS.
> 
> At the moment, I don't know how to modify the existing code so that the Apple Provider can behave like SunMSCAPI

You won’t be able to do this in an application. This is only possible if the Apple provider also implements Signature.

Note: the Apple provider is also maintained by Oracle now.

—Weijun

> 
> 
>> Début du message réexpédié :
>> 
>> De: Wei-Jun Wang <weijun.wang at oracle.com>
>> Objet: Rép. : Java Bug : Mutual HTTPS authentication not possible with a non-extractable private key with Apple/KeychainStore
>> Date: 3 mai 2021 à 18:11:12 UTC+2
>> À: Jean-Yves Cronier <cronier.jy at gmail.com>
>> 
>> And BTW, it’s better to write to an area-specific mail list next time when you find an issue in OpenJDK. The jdk-dev@ mail list is probably too big and people discuss more grand things there. :-)
>> 
>> For security, it’s security-dev at openjdk.java.net.
>> 
>> Thanks,
>> Weijun
>> 
>>>>> Le 3 mai 2021 à 16:03, Wei-Jun Wang <weijun.wang at oracle.com> a écrit :
>>>>> 
>>>>> Hi Jean-Yves,
>>>>> 
>>>>> On macOS there’s only native key/certificate management but no signature signing/verification. If you look at https://docs.oracle.com/javase/9/security/oracleproviders.htm, the Apple provider only implements KeyStore. If you need to use a key in client auth, it needs to extract that key and use another provider (SunRsaSign or SunEC) to use it.
>>>>> 
>>>>> On the other hand, SunMSCAPI has implemented both KeyStore and Signature, therefore it can do both things inside the provider and the key does not need to be extracted.
>>>>> 
>>>>> I’ve filed https://bugs.openjdk.java.net/browse/JDK-8266439.
>>>>> 
>>>>> Thanks,
>>>>> Weijun
>>>>> 
>>>>>> On May 1, 2021, at 8:19 AM, Jean-Yves Cronier <cronier.jy at gmail.com> wrote:
>>>>>> 
>>>>>> Description
>>>>>> 
>>>>>> I have imported my personal certificate in macOS keychain with "non-extractable" option (cf. https://ss64.com/osx/security-export.html<https://ss64.com/osx/security-export.html>).
>>>>>> Private key is now protected, and we can't export private key from macOS KeyChain
>>>>>> But I am unable to establish connexion with a web-API which require client certificate for mutual authentication with Java
>>>>>> It work perfectly well with curl/git, and browsers (safari/chrome)
>>>>>> 
>>>>>> 
>>>>>> <>System / OS / Java Runtime Information
>>>>>> 
>>>>>> openjdk 11.0.11
>>>>>> macOS 11.3
>>>>>> 
>>>>>> 
>>>>>> <>Steps to Reproduce
>>>>>> 
>>>>>> 1. Add personal certificate with "non-extractable" option. Example with a personal certificate sent to me in a P12 file named "my-certificate.p12", with following command-line:
>>>>>> security import my-certificate.p12 -x -P « my-strong-password"
>>>>>> 2. Connect a site require mutual authentication (for example : https://server.cryptomix.com/secure/ <https://server.cryptomix.com/secure/> )
>>>>>> 
>>>>>> 
>>>>>> <>Expected Result
>>>>>> 
>>>>>> Display content detail of selected client certificate
>>>>>> 
>>>>>> 
>>>>>> <>Actual Result
>>>>>> 
>>>>>> Error: No TLS client certificate presented 
>>>>>> 
>>>>>> 
>>>>>> <>Source code for an executable test case
>>>>>> 
>>>>>> import javax.net.ssl.HttpsURLConnection;
>>>>>> import java.io.IOException;
>>>>>> import java.net.URL;
>>>>>> import java.security.cert.X509Certificate;
>>>>>> 
>>>>>> public class MutualAuthenticationTest {
>>>>>> 	public static void main(String[] args) throws IOException {
>>>>>> 		System.setProperty("javax.net.ssl.keyStoreType", "KeychainStore");
>>>>>> 		System.setProperty("javax.net.ssl.keyStore", "NONE");
>>>>>> 		System.setProperty("javax.net.ssl.keyStorePassword", "-");
>>>>>> 		testUrl(new URL("https://server.cryptomix.com/secure/"));
>>>>>> 	}
>>>>>> 
>>>>>> 	public static void testUrl(URL targetUrl) throws IOException {
>>>>>> 		HttpsURLConnection con = (HttpsURLConnection) targetUrl.openConnection();
>>>>>> 		// Open the connection
>>>>>> 		con.getResponseCode();
>>>>>> 
>>>>>> 		assert con.getLocalCertificates() != null && con.getLocalCertificates().length > 0 : "Must use a personnel certificate for mutual authentication";
>>>>>> 		X509Certificate personalCertificate = (X509Certificate) con.getLocalCertificates()[0];
>>>>>> 		assert personalCertificate.getSubjectDN() != null;
>>>>>> 	}
>>>>>> }
>>>>>> 
>>>>>> 
>>>>>> <>Workaround
>>>>>> 
>>>>>> No possible workaround on MacOS which Apple/KeychainStore
>>>>>> NB : Perfectly work on Windows/MSCAPI with personnel certificate (with non-exportable private key option)
>>>> 
>>> 
>> 
> 



More information about the security-dev mailing list