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;