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

Add CertOpenStore to c.s.j.p.win32.Crypt32 #1418

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -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
---------
Expand Down
99 changes: 97 additions & 2 deletions contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java
Expand Up @@ -43,6 +43,63 @@ public interface Crypt32 extends StdCallLibrary {

Crypt32 INSTANCE = Native.load("Crypt32", Crypt32.class, W32APIOptions.DEFAULT_OPTIONS);

// Store providers for CertOpenStore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go into WinCrypt.java as definition comes from WinCrypt.h. The two encoding definitions are already there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new constants should still be moved to WinCrypt.java. As CertStoreProviderName is not from a header it is debatable, but I would also move it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I did not add a javadoc to each of them, from MSDN page it looks like a lot of text with references and we probably don't want to have it all copied to WinCrypt

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;

// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptencodeobjectex
int X509_ASN_ENCODING = 1;
int PKCS_7_ASN_ENCODING = 0x10000;

/**
* The CryptProtectData function performs encryption on the data in a
* DATA_BLOB structure. Typically, only a user with the same logon
Expand Down Expand Up @@ -157,11 +214,47 @@ 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 <a href="https://docs.microsoft.com/en-us/windows/desktop/SecGloss/c-gly">certificate encoding type</a>
* and <a href="https://docs.microsoft.com/en-us/windows/desktop/SecGloss/m-gly">message encoding</a> type.
* Encoding is used only when the {@code dwSaveAs} parameter of the
* <a href="https://docs.microsoft.com/en-us/windows/desktop/api/wincrypt/nf-wincrypt-certsavestore">CertSaveStore</a>
* 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
* A 32-bit value that can contain additional information for this function. The contents of
shalupov marked this conversation as resolved.
Show resolved Hide resolved
* 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 <a href="https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certopenstore">MSDN</a>
*/
WinCrypt.HCERTSTORE CertOpenStore(
WTypes.LPSTR lpszStoreProvider,
int dwEncodingType,
WinCrypt.HCRYPTPROV_LEGACY hCryptProv,
int dwFlags,
Pointer 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(LPSTR, 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
Expand All @@ -171,7 +264,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 <a href="https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certopensystemstorew">MSDN</a>
*/
HCERTSTORE CertOpenSystemStore(Pointer hprov, String szSubsystemProtocol);

Expand Down
18 changes: 15 additions & 3 deletions contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java
Expand Up @@ -423,10 +423,22 @@ 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 testCertOpenStore() {
WinCrypt.HCERTSTORE hCertStore = Crypt32.INSTANCE.CertOpenStore(
new WTypes.LPSTR(new Pointer(Crypt32.CERT_STORE_PROV_SYSTEM_REGISTRY_W)),
shalupov marked this conversation as resolved.
Show resolved Hide resolved
0,
new WinCrypt.HCRYPTPROV_LEGACY(0),
shalupov marked this conversation as resolved.
Show resolved Hide resolved
Crypt32.CERT_SYSTEM_STORE_LOCAL_MACHINE | Crypt32.CERT_STORE_OPEN_EXISTING_FLAG | Crypt32.CERT_STORE_READONLY_FLAG,
new WTypes.LPWSTR("ROOT").getPointer());
shalupov marked this conversation as resolved.
Show resolved Hide resolved
enumerateRootCertificates(hCertStore);
}

private void enumerateRootCertificates(HCERTSTORE hCertStore) {
int readCertificates = 0;
int readExtensions = 0;

Expand Down