From af8458bab2c1974fd3a4fe2af8257d35ffb5d8a0 Mon Sep 17 00:00:00 2001 From: Leonid Shalupov Date: Fri, 11 Mar 2022 17:34:52 +0100 Subject: [PATCH] Add CertOpenStore to c.s.j.p.win32.Crypt32 --- CHANGES.md | 1 + .../com/sun/jna/platform/win32/Crypt32.java | 81 ++++++++++++- .../com/sun/jna/platform/win32/WinCrypt.java | 107 ++++++++++++++++++ .../sun/jna/platform/win32/Crypt32Test.java | 28 ++++- 4 files changed, 210 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5d3279a80c..fbc73c7934 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ Features * [#1403](https://github.com/java-native-access/jna/pull/1403): Rebuild AIX binaries with libffi 3.4.2 (other architectures were part of 5.10) - [@matthiasblaesing](https://github.com/matthiasblaesing). * [#1404](https://github.com/java-native-access/jna/issues/1404): Added Solaris Kstat2 library - [@dbwiddis](https://github.com/dbwiddis). * [#1416](https://github.com/java-native-access/jna/pull/1416): Add `CFDictionaryGetCount` to `c.s.j.p.mac.CoreFoundation` - [@shalupov](https://github.com/shalupov) +* [#1418](https://github.com/java-native-access/jna/pull/1418): Add `CertOpenStore` to `c.s.j.p.win32.Crypt32` - [@shalupov](https://github.com/shalupov) Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java b/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java index e380ad5a32..7b013b54e5 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java @@ -23,8 +23,7 @@ */ package com.sun.jna.platform.win32; -import com.sun.jna.Native; -import com.sun.jna.Pointer; +import com.sun.jna.*; import com.sun.jna.platform.win32.WinCrypt.CRYPTPROTECT_PROMPTSTRUCT; import com.sun.jna.platform.win32.WinCrypt.DATA_BLOB; import com.sun.jna.ptr.PointerByReference; @@ -157,11 +156,83 @@ public boolean CryptUnprotectData(DATA_BLOB pDataIn, PointerByReference szDataDe */ boolean CertAddEncodedCertificateToSystemStore(String szCertStoreName, Pointer pbCertEncoded, int cbCertEncoded); + /** + * The {@code CertOpenStore} function opens a certificate store by using a specified store provider type + * + * @param lpszStoreProvider + * A pointer to a null-terminated ANSI string that contains the store provider type. + * @param dwEncodingType + * Specifies the certificate encoding type + * and message encoding type. + * Encoding is used only when the {@code dwSaveAs} parameter of the + * CertSaveStore + * function contains {@code CERT_STORE_SAVE_AS_PKCS7}. + * Otherwise, the {@code dwMsgAndCertEncodingType} parameter is not used. + * @param hCryptProv + * This parameter is not used and should be set to NULL. + * @param dwFlags + * These values consist of high-word and low-word values combined by using a bitwise-OR operation. + * See {@code CERT_STORE_*_FLAG} and {@code CERT_SYSTEM_STORE_*} constants. + * @param pvPara + * Additional information for this function. The contents of + * this parameter depends on the value of the {@code lpszStoreProvider} and other parameters. + * @return + * If the function succeeds, the function returns a handle to the certificate store. + * When you have finished using the store, release the handle by calling the + * {@link com.sun.jna.platform.win32.Crypt32#CertCloseStore(WinCrypt.HCERTSTORE, int)} function. + * If the function fails, it returns NULL. For extended error information, + * call {@link Native#getLastError()}. + * + * @see MSDN + */ + WinCrypt.HCERTSTORE CertOpenStore( + CertStoreProviderName lpszStoreProvider, + int dwEncodingType, + WinCrypt.HCRYPTPROV_LEGACY hCryptProv, + int dwFlags, + Pointer pvPara); + + /** + * The {@code CertOpenStore} function opens a certificate store by using a specified store provider type + * + * @param lpszStoreProvider + * A pointer to a null-terminated ANSI string that contains the store provider type. + * @param dwEncodingType + * Specifies the certificate encoding type + * and message encoding type. + * Encoding is used only when the {@code dwSaveAs} parameter of the + * CertSaveStore + * function contains {@code CERT_STORE_SAVE_AS_PKCS7}. + * Otherwise, the {@code dwMsgAndCertEncodingType} parameter is not used. + * @param hCryptProv + * This parameter is not used and should be set to NULL. + * @param dwFlags + * These values consist of high-word and low-word values combined by using a bitwise-OR operation. + * See {@code CERT_STORE_*_FLAG} and {@code CERT_SYSTEM_STORE_*} constants. + * @param pvPara + * Additional information for this function in {@link WTypes.LPWSTR} form. The contents of + * this parameter depends on the value of the {@code lpszStoreProvider} and other parameters. + * @return + * If the function succeeds, the function returns a handle to the certificate store. + * When you have finished using the store, release the handle by calling the + * {@link com.sun.jna.platform.win32.Crypt32#CertCloseStore(WinCrypt.HCERTSTORE, int)} function. + * If the function fails, it returns NULL. For extended error information, + * call {@link Native#getLastError()}. + * + * @see MSDN + */ + WinCrypt.HCERTSTORE CertOpenStore( + CertStoreProviderName lpszStoreProvider, + int dwEncodingType, + WinCrypt.HCRYPTPROV_LEGACY hCryptProv, + int dwFlags, + WTypes.LPWSTR pvPara); + /** * The CertOpenSystemStore function is a simplified function that opens the * most common system certificate store. To open certificate stores with * more complex requirements, such as file-based or memory-based stores, use - * CertOpenStore. + * {@link #CertOpenStore(CertStoreProviderName, int, HCRYPTPROV_LEGACY, int, Pointer)}. * * @param hprov This parameter is not used and should be set to NULL. * @param szSubsystemProtocol A string that names a system store. If the @@ -171,7 +242,9 @@ public boolean CryptUnprotectData(DATA_BLOB pDataIn, PointerByReference szDataDe * stores. Some example system stores are listed in the following table. * @return If the function succeeds, the function returns a handle to the * certificate store. If the function fails, it returns NULL. For extended - * error information, call GetLastError. + * error information, call {@link Native#getLastError()} + * + * @see MSDN */ HCERTSTORE CertOpenSystemStore(Pointer hprov, String szSubsystemProtocol); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java b/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java index a8cbce3e19..8065cf06a6 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java @@ -23,8 +23,10 @@ */ package com.sun.jna.platform.win32; +import com.sun.jna.FromNativeContext; import com.sun.jna.Memory; import com.sun.jna.Native; +import com.sun.jna.NativeMapped; import com.sun.jna.Pointer; import com.sun.jna.StringArray; import com.sun.jna.Structure; @@ -1194,6 +1196,49 @@ public CRYPTPROTECT_PROMPTSTRUCT(Pointer memory) { } } + /** + * Value wrapper for {@code lpszStoreProvider} of {@link Crypt32#CertOpenStore(CertStoreProviderName, int, HCRYPTPROV_LEGACY, int, Pointer)} + */ + class CertStoreProviderName implements NativeMapped { + private final Pointer pointer; + + private CertStoreProviderName(Pointer fixedValue) { + this.pointer = fixedValue; + } + + public CertStoreProviderName() { + pointer = Pointer.NULL; + } + + public CertStoreProviderName(int fixedValue) { + this.pointer = Pointer.createConstant(fixedValue); + } + + public CertStoreProviderName(String name) { + byte[] nameBytes = Native.toByteArray(name); + this.pointer = new Memory(nameBytes.length); + this.pointer.write(0, nameBytes, 0, nameBytes.length); + } + + @Override + public Object fromNative(Object nativeValue, FromNativeContext fnc) { + if (nativeValue == null) { + return null; + } + return new CertStoreProviderName((Pointer) nativeValue); + } + + @Override + public Object toNative() { + return pointer; + } + + @Override + public Class nativeType() { + return Pointer.class; + } + } + // // CryptProtect PromptStruct dwPromtFlags // @@ -1617,6 +1662,68 @@ public CRYPTPROTECT_PROMPTSTRUCT(Pointer memory) { */ int PKCS12_INCLUDE_EXTENDED_PROPERTIES = 0x0010; + // + // Store providers for CertOpenStore + // + + int CERT_STORE_PROV_MSG = 1; + int CERT_STORE_PROV_MEMORY = 2; + int CERT_STORE_PROV_FILE = 3; + int CERT_STORE_PROV_REG = 4; + int CERT_STORE_PROV_PKCS7 = 5; + int CERT_STORE_PROV_SERIALIZED = 6; + int CERT_STORE_PROV_FILENAME_A = 7; // ASCII + int CERT_STORE_PROV_FILENAME_W = 8; // Unicode + int CERT_STORE_PROV_FILENAME = CERT_STORE_PROV_FILENAME_W; + int CERT_STORE_PROV_SYSTEM_A = 9; // pvPara is ASCII (1 byte/char) + int CERT_STORE_PROV_SYSTEM_W = 10; // pvPara is Unicode (2 bytes/char) + int CERT_STORE_PROV_SYSTEM = CERT_STORE_PROV_SYSTEM_W; + int CERT_STORE_PROV_COLLECTION = 11; + int CERT_STORE_PROV_SYSTEM_REGISTRY_A = 12; + int CERT_STORE_PROV_SYSTEM_REGISTRY_W = 13; + int CERT_STORE_PROV_SYSTEM_REGISTRY = CERT_STORE_PROV_SYSTEM_REGISTRY_W; + int CERT_STORE_PROV_PHYSICAL_W = 14; + int CERT_STORE_PROV_PHYSICAL = CERT_STORE_PROV_PHYSICAL_W; + int CERT_STORE_PROV_SMART_CARD_W = 15; + int CERT_STORE_PROV_SMART_CARD = CERT_STORE_PROV_SMART_CARD_W; + int CERT_STORE_PROV_LDAP_W = 16; + int CERT_STORE_PROV_LDAP = CERT_STORE_PROV_LDAP_W; + + // + // Store characteristics for CertOpenStore + // + + int CERT_STORE_NO_CRYPT_RELEASE_FLAG = 0x00000001; + int CERT_STORE_SET_LOCALIZED_NAME_FLAG = 0x00000002; + int CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004; + int CERT_STORE_DELETE_FLAG = 0x00000010; + int CERT_STORE_UNSAFE_PHYSICAL_FLAG = 0x00000020; + int CERT_STORE_SHARE_STORE_FLAG = 0x00000040; + int CERT_STORE_SHARE_CONTEXT_FLAG = 0x00000080; + int CERT_STORE_MANIFOLD_FLAG = 0x00000100; + int CERT_STORE_ENUM_ARCHIVED_FLAG = 0x00000200; + int CERT_STORE_UPDATE_KEYID_FLAG = 0x00000400; + int CERT_STORE_BACKUP_RESTORE_FLAG = 0x00000800; + int CERT_STORE_MAXIMUM_ALLOWED_FLAG = 0x00001000; + int CERT_STORE_CREATE_NEW_FLAG = 0x00002000; + int CERT_STORE_OPEN_EXISTING_FLAG = 0x00004000; + int CERT_STORE_READONLY_FLAG = 0x00008000; + + // + // Store locations for CertOpenStore + // + + int CERT_SYSTEM_STORE_CURRENT_USER = 0x00010000; + int CERT_SYSTEM_STORE_LOCAL_MACHINE = 0x00020000; + int CERT_SYSTEM_STORE_CURRENT_SERVICE = 0x00040000; + int CERT_SYSTEM_STORE_SERVICES = 0x00050000; + int CERT_SYSTEM_STORE_USERS = 0x00060000; + int CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY = 0x00070000; + int CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY = 0x00080000; + int CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE = 0x00090000; + int CERT_SYSTEM_STORE_UNPROTECTED_FLAG = 0x40000000; + int CERT_SYSTEM_STORE_RELOCATE_FLAG = 0x80000000; + /** * Checks for nonfreed certificate, CRL, and CTL contexts. A returned error * code indicates that one or more store elements is still in use. This flag diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java index a81af5bf7d..11ca96a732 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java @@ -423,10 +423,32 @@ public void testCertVerifyCertificateChainPolicy() { assertTrue("The status would be true since a valid certificate chain was not passed in.", status); } - public void testCertEnumCertificatesInStore() { - String SYSTEM_STORE_NAME = "ROOT"; - WinCrypt.HCERTSTORE hCertStore = Crypt32.INSTANCE.CertOpenSystemStore(null, SYSTEM_STORE_NAME); + public void testCertOpenSystemStore() { + WinCrypt.HCERTSTORE hCertStore = Crypt32.INSTANCE.CertOpenSystemStore(null, "ROOT"); + enumerateRootCertificates(hCertStore); + } + + public void testCertOpenStoreWithPointerPara() { + WinCrypt.HCERTSTORE hCertStore = Crypt32.INSTANCE.CertOpenStore( + new WinCrypt.CertStoreProviderName(WinCrypt.CERT_STORE_PROV_SYSTEM_REGISTRY_W), + 0, + null, + WinCrypt.CERT_SYSTEM_STORE_LOCAL_MACHINE | WinCrypt.CERT_STORE_OPEN_EXISTING_FLAG | WinCrypt.CERT_STORE_READONLY_FLAG, + new WTypes.LPWSTR("ROOT")); + enumerateRootCertificates(hCertStore); + } + + public void testCertOpenStoreWithStringPara() { + WinCrypt.HCERTSTORE hCertStore = Crypt32.INSTANCE.CertOpenStore( + new WinCrypt.CertStoreProviderName(WinCrypt.CERT_STORE_PROV_SYSTEM_REGISTRY_W), + 0, + null, + WinCrypt.CERT_SYSTEM_STORE_LOCAL_MACHINE | WinCrypt.CERT_STORE_OPEN_EXISTING_FLAG | WinCrypt.CERT_STORE_READONLY_FLAG, + new WTypes.LPWSTR("ROOT").getPointer()); + enumerateRootCertificates(hCertStore); + } + private void enumerateRootCertificates(HCERTSTORE hCertStore) { int readCertificates = 0; int readExtensions = 0;