diff --git a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp index eba2fdfdf4a..2d4a8adf58a 100644 --- a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp +++ b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -407,7 +407,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC const char* pszCertStoreName = NULL; HCERTSTORE hCertStore = NULL; PCCERT_CONTEXT pCertContext = NULL; - char* pszNameString = NULL; // certificate's friendly name + wchar_t* pszNameString = NULL; // certificate's friendly name DWORD cchNameString = 0; __try @@ -584,17 +584,17 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC // when storing this cert in the keystore.) // Get length of friendly name - if ((cchNameString = CertGetNameString(pc, + if ((cchNameString = CertGetNameStringW(pc, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) > 1) { // Found friendly name - pszNameString = new (env) char[cchNameString]; + pszNameString = new (env) wchar_t[cchNameString]; if (pszNameString == NULL) { __leave; } - CertGetNameString(pc, + CertGetNameStringW(pc, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString, cchNameString); } @@ -621,12 +621,13 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC // or SAN. if (pszNameString) { - PP("%s: %s", pszNameString, pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId); + PP("%S: %s", pszNameString, pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId); + jsize nameLen = (jsize)wcslen(pszNameString); if (bHasNoPrivateKey) { // Generate certificate chain and store into cert chain // collection - jstring name = env->NewStringUTF(pszNameString); + jstring name = env->NewString(pszNameString, nameLen); if (name == NULL) { __leave; } @@ -646,7 +647,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC { // Generate RSA certificate chain and store into cert // chain collection - jstring name = env->NewStringUTF(pszNameString); + jstring name = env->NewString(pszNameString, nameLen); if (name == NULL) { __leave; } @@ -663,7 +664,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC if (::NCryptGetProperty( hCryptProv, NCRYPT_ALGORITHM_PROPERTY, (PBYTE)buffer, 32, &len, NCRYPT_SILENT_FLAG) == ERROR_SUCCESS) { - jstring name = env->NewStringUTF(pszNameString); + jstring name = env->NewString(pszNameString, nameLen); if (name == NULL) { __leave; } @@ -1707,13 +1708,13 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_removeCertificate jbyteArray jCertEncoding, jint jCertEncodingSize) { const char* pszCertStoreName = NULL; - const char* pszCertAliasName = NULL; + const wchar_t* pszCertAliasName = NULL; HCERTSTORE hCertStore = NULL; PCCERT_CONTEXT pCertContext = NULL; PCCERT_CONTEXT pTBDCertContext = NULL; jbyte* pbCertEncoding = NULL; DWORD cchNameString = 0; - char* pszNameString = NULL; // certificate's friendly name + wchar_t* pszNameString = NULL; // certificate's friendly name BOOL bDeleteAttempted = FALSE; __try @@ -1752,24 +1753,24 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_removeCertificate } // Check that its friendly name matches the supplied alias - if ((cchNameString = ::CertGetNameString(pTBDCertContext, + if ((cchNameString = ::CertGetNameStringW(pTBDCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) > 1) { - pszNameString = new (env) char[cchNameString]; + pszNameString = new (env) wchar_t[cchNameString]; if (pszNameString == NULL) { __leave; } - ::CertGetNameString(pTBDCertContext, + ::CertGetNameStringW(pTBDCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString, cchNameString); // Compare the certificate's friendly name with supplied alias name - if ((pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL)) + if ((pszCertAliasName = env->GetStringChars(jCertAliasName, NULL)) == NULL) { __leave; } - if (strcmp(pszCertAliasName, pszNameString) == 0) { + if (wcscmp(pszCertAliasName, pszNameString) == 0) { // Only delete the certificate if the alias names matches if (! ::CertDeleteCertificateFromStore(pTBDCertContext)) { @@ -1797,7 +1798,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_removeCertificate env->ReleaseStringUTFChars(jCertStoreName, pszCertStoreName); if (pszCertAliasName) - env->ReleaseStringUTFChars(jCertAliasName, pszCertAliasName); + env->ReleaseStringChars(jCertAliasName, pszCertAliasName); if (pbCertEncoding) delete [] pbCertEncoding; diff --git a/test/jdk/sun/security/mscapi/NonAsciiAlias.java b/test/jdk/sun/security/mscapi/NonAsciiAlias.java new file mode 100644 index 00000000000..e2ebeb0ca14 --- /dev/null +++ b/test/jdk/sun/security/mscapi/NonAsciiAlias.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import sun.security.tools.keytool.CertAndKeyGen; +import sun.security.x509.X500Name; + +import java.security.KeyStore; +import java.security.cert.Certificate; +import jdk.test.lib.Asserts; + +/** + * @test + * @bug 6522064 + * @library /test/lib + * @requires os.family == "windows" + * @modules java.base/sun.security.tools.keytool + * java.base/sun.security.x509 + * @summary Aliases from Microsoft CryptoAPI has bad character encoding + */ + +public class NonAsciiAlias { + public static void main(String[] args) throws Exception { + KeyStore ks = KeyStore.getInstance("Windows-MY"); + String alias = "\u58c6\u94a56522064"; + try { + ks.load(null, null); + CertAndKeyGen cag = new CertAndKeyGen("RSA", "SHA256withRSA"); + cag.generate(2048); + ks.setKeyEntry(alias, cag.getPrivateKey(), null, new Certificate[]{ + cag.getSelfCertificate(new X500Name("CN=Me"), 1000) + }); + // Confirms the alias is there + Asserts.assertTrue(ks.containsAlias(alias)); + ks.store(null, null); + ks.load(null, null); + // Confirms the alias is there after reload + Asserts.assertTrue(ks.containsAlias(alias)); + ks.deleteEntry(alias); + // Confirms the alias is removed + Asserts.assertFalse(ks.containsAlias(alias)); + ks.store(null, null); + ks.load(null, null); + // Confirms the alias is removed after reload + Asserts.assertFalse(ks.containsAlias(alias)); + } finally { + ks.deleteEntry(alias); + // in case the correct alias is not found, clean up a wrong one + ks.deleteEntry("??6522064"); + } + } +}