diff --git a/CHANGES.md b/CHANGES.md
index 97b86158fc..8b4de2be88 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -7,6 +7,7 @@ Release 5.0.0 (Next release)
Features
--------
+* [#915](https://github.com/java-native-access/jna/pull/915): Adding interfaces to call to Cryptui and Crypt32 windows libraries and adding related structures to Wincrypt. - [@rosh89](https://github.com/rosh89).
* [#903](https://github.com/java-native-access/jna/pull/903): Carry `HRESULT` in `c.s.j.p.win32.COM.COMException`, introduce `c.s.j.p.win32.COM.COMInvokeException` as subclass of `COMException` for exception as the result of a `IDispatch#Invoke`. The `EXECPINFO` is unwrapped into fields in the `COMInvokeException` and correctly freed. - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#822](https://github.com/java-native-access/jna/issues/822): `Native#loadLibrary` requires that the interface class passed in is an instance of Library. The runtime check can be enhanced by using a constraint generic. This breaks binary compatibility (see notes below) - [@d-noll](https://github.com/d-noll).
* [#889](https://github.com/java-native-access/jna/issues/889): The `Structure#newInstance` receive the target type as a parameter. This adds a limited generic type, so that the return type ist the target type and not a generic structure, removing the necessity to do an explizit cast - [@matthiasblaesing](https://github.com/matthiasblaesing).
diff --git a/contrib/platform/nbproject/project.properties b/contrib/platform/nbproject/project.properties
index 2f595eea00..119204a4ec 100644
--- a/contrib/platform/nbproject/project.properties
+++ b/contrib/platform/nbproject/project.properties
@@ -48,7 +48,7 @@ jar.compress=false
javac.classpath=\
${file.reference.jna.jar}
# Space-separated list of extra javac options
-javac.compilerargs=
+javac.compilerargs=-XDignore.symbol.file
javac.deprecation=false
javac.source=1.6
javac.target=1.6
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 204f8f1d94..cdd92bca46 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java
@@ -30,6 +30,10 @@
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
+import com.sun.jna.platform.win32.WinCrypt.*;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.platform.win32.WinBase.FILETIME;
+import com.sun.jna.platform.win32.WTypes.LPSTR;
/**
* Crypt32.dll Interface.
@@ -140,6 +144,351 @@ public boolean CryptUnprotectData(DATA_BLOB pDataIn, PointerByReference szDataDe
* handling behaviors.
* For extended error information, call GetLastError.
* @see MSDN
- */
- boolean CertAddEncodedCertificateToSystemStore(String szCertStoreName, Pointer pbCertEncoded, int cbCertEncoded);
+ */
+ boolean CertAddEncodedCertificateToSystemStore(String szCertStoreName, Pointer pbCertEncoded, int cbCertEncoded);
+
+ /**
+ * 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.
+ *
+ * @param hprov This parameter is not used and should be set to NULL.
+ * @param szSubsystemProtocol A string that names a system store. If the
+ * system store name provided in this parameter is not the name of an
+ * existing system store, a new system store will be created and used.
+ * CertEnumSystemStore can be used to list the names of existing system
+ * 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.
+ */
+ HCERTSTORE CertOpenSystemStore(Pointer hprov, String szSubsystemProtocol);
+
+ /**
+ * The CryptSignMessage function creates a hash of the specified content,
+ * signs the hash, and then encodes both the original message content and
+ * the signed hash.
+ *
+ * @param pSignPara A pointer to CRYPT_SIGN_MESSAGE_PARA structure
+ * containing the signature parameters.
+ * @param fDetachedSignature TRUE if this is to be a detached signature.
+ * Otherwise, FALSE. If this parameter is set to TRUE, only the signed hash
+ * is encoded in pbSignedBlob. Otherwise, both rgpbToBeSigned and the signed
+ * hash are encoded.
+ * @param cToBeSigned Count of the number of array elements in
+ * rgpbToBeSigned and rgpbToBeSigned. This parameter must be set to one
+ * unless fDetachedSignature is set to TRUE.
+ * @param rgpbToBeSigned Array of pointers to buffers that contain the
+ * contents to be signed.
+ * @param rgcbToBeSigned Array of sizes, in bytes, of the content buffers
+ * pointed to in rgpbToBeSigned.
+ * @param pbSignedBlob A pointer to a buffer to receive the encoded signed
+ * hash, if fDetachedSignature is TRUE, or to both the encoded content and
+ * signed hash if fDetachedSignature is FALSE.
+ * @param pcbSignedBlob A pointer to a DWORD specifying the size, in bytes,
+ * of the pbSignedBlob buffer. When the function returns, this variable
+ * contains the size, in bytes, of the signed and encoded message.
+ * @return If the function succeeds, the return value is nonzero (TRUE). If
+ * the function fails, the return value is zero (FALSE).
+ */
+ boolean CryptSignMessage(CRYPT_SIGN_MESSAGE_PARA pSignPara, boolean fDetachedSignature, int cToBeSigned,
+ Pointer[] rgpbToBeSigned, int[] rgcbToBeSigned, Pointer pbSignedBlob, IntByReference pcbSignedBlob);
+
+ /**
+ * The CryptVerifyMessageSignature function verifies a signed message's
+ * signature.
+ *
+ * This function should not be used to verify the signature of a detached
+ * message. You should use the CryptVerifyDetachedMessageSignature function
+ * to verify the signature of a detached message.
+ *
+ * @param pVerifyPara A pointer to a CRYPT_VERIFY_MESSAGE_PARA structure
+ * that contains verification parameters.
+ * @param signerIndex The index of the de sired signature. There can be more
+ * than one signature. CryptVerifyMessageSignature can be called repeatedly,
+ * incrementing dwSignerIndex each time.
+ *
+ *
+ * Set this pa rameter to zero for the first signer, or if there is only one
+ * signer. If the function returns FALSE, and GetLastError returns
+ * CRYPT_E_NO_SIGNER, the previous call processed the last signer of the
+ * message.
+ * @param pbSignedBlob A pointer to a buffe r that contains the signed
+ * message.
+ * @param cbSignedBlob The size, in bytes, of the signed message buffer.
+ * @param pbDecoded * A pointer to a buffer to receive the decoded message.
+ *
+ *
+ * This parameter can be NULL if the decoded message is not needed for
+ * additional processing or to set the size of the message for memory
+ * allocation purposes. For more information, see Retrieving Data of Unknown
+ * Length.
+ *
+ * @param pcbDecoded A pointer to a DWO RD value that specifies the size, in
+ * bytes, of the pbDecoded buffer. When the function returns, this DWORD
+ * contains the size, in bytes, of the decoded message. The decoded message
+ * will not be returned if this parameter is NULL.
+ * @param ppSignerCert The address of a CER T_CONTEXT structure pointer that
+ * receives the certificate of the signer. When you have finished using this
+ * structure, free it by passing this pointer to the
+ * CertFreeCertificateContext function. This parameter can be NULL if the
+ * signer's certificate is not needed.
+ * @return If the function succeeds, the function returns nonzero. This does
+ * not necessarily mean that the signature was verified. In the case of a
+ * detached message, the variable pointe d to by pcbDecoded will contain
+ * zero. In this case, this funct ion will return nonzero, but the signature
+ * is not verified . To verify the signature of a detached message, use the
+ * CryptVerifyDetachedMessageSignature function.
+ *
+ *
+ * If the function succeeds, the function returns nonzero. This does not
+ * necessarily mean that the signature was verified. In the case of a
+ * detached message, the variable pointed to by pcbDecoded will contain
+ * zero. In this case, this function will return nonzero, but the signature
+ * is not verified. To verify the signature of a detached message, use t he
+ * CryptVerifyDetachedMessageSignature function.
+ */
+ boolean CryptVerifyMessageSignature(CRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
+ int signerIndex, Pointer pbSignedBlob, int cbSignedBlob,
+ Pointer pbDecoded, IntByReference pcbDecoded, PointerByReference ppSignerCert);
+
+ /**
+ * The CertGetCertificateChain function builds a certificate chain context
+ * starting from an end certificate and going back, if possible, to a
+ * trusted root certificate.
+ *
+ * @param hChainEngine A handle of the chain engine (namespace and cache) to
+ * be used. If hChainEngine is NULL, the default chain engine,
+ * HCCE_CURRENT_USER, is used. This parameter can be set to
+ * HCCE_LOCAL_MACHINE.
+ * @param pCertContext A pointer to the CERT_CONTEXT of the end certificate,
+ * the certificate for which a chain is being built. This certificate
+ * context will be the zero-index element in the first simple chain.
+ * @param pTime A pointer to a FILETIME variable that indicates the time for
+ * which the chain is to be validated. Note that the time does not affect
+ * trust list, revocation, or root store checking. The current system time
+ * is used if NULL is passed to this parameter. Trust in a particular
+ * certificate being a trusted root is based on the current state of the
+ * root store and not the state of the root store at a time passed in by
+ * this parameter. For revocation, a certificate revocation list (CRL),
+ * itself, must be valid at the current time. The value of this parameter is
+ * used to determine whether a certificate listed in a CRL has been revoked.
+ * @param hAdditionalStore A handle to any additional store to search for
+ * supporting certificates and certificate trust lists (CTLs). This
+ * parameter can be NULL if no additional store is to be searched.
+ * @param pChainPara A pointer to a CERT_CHAIN_PARA structure that includes
+ * chain-building parameters.
+ * @param dwFlags Flag values that indicate special processing. This
+ * parameter can be a combination of one or more of the following flags.
+ * @param pvReserved This parameter is reserved and must be NULL.
+ * @param ppChainContext The address of a pointer to the chain context
+ * created. When you have finished using the chain context, release the
+ * chain by calling the CertFreeCertificateChain function.
+ * @return If the function succeeds, the function returns nonzero (TRUE). If
+ * the function fails, it returns zero (FALSE).
+ */
+ boolean CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, CERT_CONTEXT pCertContext, FILETIME pTime,
+ HCERTSTORE hAdditionalStore, CERT_CHAIN_PARA pChainPara, int dwFlags, Pointer pvReserved,
+ PointerByReference ppChainContext);
+
+ /**
+ * The CertFreeCertificateContext function frees a certificate context by
+ * decrementing its reference count. When the reference count goes to zero,
+ * CertFreeCertificateContext frees the memory used by a certificate
+ * context.
+ *
+ * @param pCertContext A pointer to the CERT_CONTEXT to be freed.
+ * @return The function always returns nonzero.
+ */
+ boolean CertFreeCertificateContext(CERT_CONTEXT pCertContext);
+
+ /**
+ * The CertFreeCertificateChain function frees a certificate chain by
+ * reducing its reference count. If the reference count becomes zero, memory
+ * allocated for the chain is released.
+ *
+ *
To free a context obtained by a get, duplicate, or create function, call
+ * the appropriate free function. To free a context obtained by a find or
+ * enumerate function, either pass it in as the previous context parameter
+ * to a subsequent invocation of the function, or call the appropriate free
+ * function. For more information, see the reference topic for the function
+ * that obtains the context.
+ *
+ * @param pChainContext A pointer to a CERT_CHAIN_CONTEXT certificate chain
+ * context to be freed. If the reference count on the context reaches zero,
+ * the storage allocated for the context is freed.
+ */
+ void CertFreeCertificateChain(CERT_CHAIN_CONTEXT pChainContext);
+
+ /**
+ * The CertCloseStore function closes a certificate store handle and reduces
+ * the reference count on the store. There needs to be a corresponding call
+ * to CertCloseStore for each successful call to the CertOpenStore or
+ * CertDuplicateStore functions.
+ *
+ * @param hCertStore Handle of the certificate store to be closed.
+ * @param dwFlags Typically, this parameter uses the default value zero. The
+ * default is to close the store with memory remaining allocated for
+ * contexts that have not been freed. In this case, no check is made to
+ * determine whether memory for contexts remains allocated.
+ * @return If the function succeeds, the return value is TRUE. If the
+ * function fails, the return value is FALSE.
+ */
+ boolean CertCloseStore(HCERTSTORE hCertStore, int dwFlags);
+
+ /**
+ * The CertNameToStr function converts an encoded name in a CERT_NAME_BLOB
+ * structure to a character string.
+ *
+ * @param dwCertEncodingType The certificate encoding type that was used to
+ * encode the name. The message encoding type identifier, contained in the
+ * high WORD of this value, is ignored by this function.
+ * @param pName A pointer to the CERT_NAME_BLOB structure to be converted.
+ * @param dwStrType This parameter specifies the format of the output
+ * string. This parameter also specifies other options for the contents of
+ * the string.
+ * @param psz A pointer to a character buffer that receives the returned
+ * string. The size of this buffer is specified in the csz parameter.
+ * @param csz The size, in characters, of the psz buffer. The size must
+ * include the terminating null character.
+ * @return Returns the number of characters converted, including the
+ * terminating null character. If psz is NULL or csz is zero, returns the
+ * required size of the destination string.
+ */
+ int CertNameToStr(int dwCertEncodingType, DATA_BLOB pName, int dwStrType, Pointer psz, int csz);
+
+ /**
+ * The CertVerifyCertificateChainPolicy function checks a certificate chain
+ * to verify its validity, including its compliance with any specified
+ * validity policy criteria.
+ *
+ * @param pszPolicyOID Current predefined verify chain policy structures are
+ * listed in the following table.
+ * @param pChainContext A pointer to a CERT_CHAIN_CONTEXT structure that
+ * contains a chain to be verified.
+ * @param pPolicyPara A pointer to a CERT_CHAIN_POLICY_PARA structure that
+ * provides the policy verification criteria for the chain. The dwFlags
+ * member of that structure can be set to change the default policy checking
+ * behavior.
+ * @param pPolicyStatus A pointer to a CERT_CHAIN_POLICY_STATUS structure
+ * where status information on the chain is returned. OID-specific extra
+ * status can be returned in the pvExtraPolicyStatus member of this
+ * structure.
+ * @return The return value indicates whether the function was able to check
+ * for the policy, it does not indicate whether the policy check failed or
+ * passed.
+ *
+ * If the chain can be verified for the specified policy, TRUE is returned
+ * and the dwError member of the pPolicyStatus is updated. A dwError of 0
+ * (ERROR_SUCCESS or S_OK) indicates the chain satisfies the specified
+ * policy.
+ *
+ * If the chain cannot be validated, the return value is TRUE and you need
+ * to verify the pPolicyStatus parameter for the actual error.
+ *
+ * A value of FALSE indicates that the function wasn't able to check for the
+ * policy.
+ */
+ boolean CertVerifyCertificateChainPolicy(LPSTR pszPolicyOID, CERT_CHAIN_CONTEXT pChainContext,
+ CERT_CHAIN_POLICY_PARA pPolicyPara, CERT_CHAIN_POLICY_STATUS pPolicyStatus);
+
+ /**
+ * The CertFindCertificateInStore function finds the first or next
+ * certificate context in a certificate store that matches a search criteria
+ * established by the dwFindType and its associated pvFindPara. This
+ * function can be used in a loop to find all of the certificates in a
+ * certificate store that match the specified find criteria.
+ *
+ * @param hCertStore A handle of the certificate store to be searched.
+ * @param dwCertEncodingType Specifies the type of encoding used. Both the
+ * certificate and message encoding types must be specified by combining
+ * them with a bitwise-OR.
+ * @param dwFindFlags Used with some dwFindType values to modify the search
+ * criteria. For most dwFindType values, dwFindFlags is not used and should
+ * be set to zero.
+ * @param dwFindType Specifies the type of search being made. The search
+ * type determines the data type, contents, and the use of pvFindPara.
+ * @param pvFindPara Points to a data item or structure used with
+ * dwFindType.
+ * @param pPrevCertContext A pointer to the last CERT_CONTEXT structure
+ * returned by this function. This parameter must be NULL on the first call
+ * of the function. To find successive certificates meeting the search
+ * criteria, set pPrevCertContext to the pointer returned by the previous
+ * call to the function. This function frees the CERT_CONTEXT referenced by
+ * non-NULL values of this parameter.
+ * @return If the function succeeds, the function returns a pointer to a
+ * read-only CERT_CONTEXT structure.
+ *
+ * If the function fails and a certificate that matches the search criteria
+ * is not found, the return value is NULL.
+ *
+ * A non-NULL CERT_CONTEXT that CertFindCertificateInStore returns must be
+ * freed by CertFreeCertificateContext or by being passed as the
+ * pPrevCertContext parameter on a subsequent call to
+ * CertFindCertificateInStore.
+ */
+ CERT_CONTEXT.ByReference CertFindCertificateInStore(HCERTSTORE hCertStore, int dwCertEncodingType, int dwFindFlags,
+ int dwFindType, Pointer pvFindPara, CERT_CONTEXT pPrevCertContext);
+
+ /**
+ * The PFXImportCertStore function imports a PFX BLOB and returns the handle
+ * of a store that contains certificates and any associated private keys.
+ *
+ * @param pPFX A pointer to a CRYPT_DATA_BLOB structure that contains a PFX
+ * packet with the exported and encrypted certificates and keys.
+ * @param szPassword A string password used to decrypt and verify the PFX
+ * packet. Whether set to a string of length greater than zero or set to an
+ * empty string or to NULL, this value must be exactly the same as the value
+ * that was used to encrypt the packet.
+ *
+ *
+ * Beginning with Windows 8 and Windows Server 2012, if the PFX packet was
+ * created in the PFXExportCertStoreEx function by using the
+ * PKCS12_PROTECT_TO_DOMAIN_SIDS flag, the PFXImportCertStore function
+ * attempts to decrypt the password by using the Active Directory (AD)
+ * principal that was used to encrypt it. The AD principal is specified in
+ * the pvPara parameter. If the szPassword parameter in the
+ * PFXExportCertStoreEx function was an empty string or NULL and the dwFlags
+ * parameter was set to PKCS12_PROTECT_TO_DOMAIN_SIDS, that function
+ * randomly generated a password and encrypted it to the AD principal
+ * specified in the pvPara parameter. In that case you should set the
+ * password to the value, empty string or NULL, that was used when the PFX
+ * packet was created. The PFXImportCertStore function will use the AD
+ * principal to decrypt the random password, and the randomly generated
+ * password will be used to decrypt the PFX certificate.
+ *
+ *
+ * When you have finished using the password, clear it from memory by
+ * calling the SecureZeroMemory function. For more information about
+ * protecting passwords, see Handling Passwords.
+ *
+ * @param dwFlags This parameter can be one of the following values.
+ *
+ * - {@link WinCrypt#CRYPT_EXPORTABLE}
+ * - {@link WinCrypt#CRYPT_USER_PROTECTED}
+ * - {@link WinCrypt#CRYPT_MACHINE_KEYSET}
+ * - {@link WinCrypt#CRYPT_USER_KEYSET}
+ * - {@link WinCrypt#PKCS12_PREFER_CNG_KSP}
+ * - {@link WinCrypt#PKCS12_ALWAYS_CNG_KSP}
+ * - {@link WinCrypt#PKCS12_ALLOW_OVERWRITE_KEY}
+ * - {@link WinCrypt#PKCS12_NO_PERSIST_KEY}
+ * - {@link WinCrypt#PKCS12_INCLUDE_EXTENDED_PROPERTIES}
+ *
+ *
+ * @return If the function succeeds, the function returns a handle to a
+ * certificate store that contains the imported certificates, including
+ * available private keys.
+ *
+ *
+ * If the function fails, that is, if the password parameter does not
+ * contain an exact match with the password used to encrypt the exported
+ * packet or if there were any other problems decoding the PFX BLOB, the
+ * function returns NULL, and an error code can be found by calling the
+ * GetLastError function.
+ *
+ * @see MSDN
+ */
+ HCERTSTORE PFXImportCertStore(DATA_BLOB pPFX, WTypes.LPWSTR szPassword, int dwFlags);
}
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Crypt32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Crypt32Util.java
index 0c73a0d05b..d1712ee3b8 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/Crypt32Util.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Crypt32Util.java
@@ -23,6 +23,9 @@
*/
package com.sun.jna.platform.win32;
+import com.sun.jna.Pointer;
+import com.sun.jna.Memory;
+import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinCrypt.CRYPTPROTECT_PROMPTSTRUCT;
import com.sun.jna.platform.win32.WinCrypt.DATA_BLOB;
import com.sun.jna.ptr.PointerByReference;
@@ -174,4 +177,48 @@ public static byte[] cryptUnprotectData(byte[] data, byte[] entropy, int flags,
return unProtectedData;
}
+
+ /**
+ * Utility method to call to Crypt32's CertNameToStr that allocates the
+ * assigns the required memory for the psz parameter based on the type
+ * mapping used, calls to CertNameToStr, and returns the received string.
+ *
+ * @param dwCertEncodingType The certificate encoding type that was used to
+ * encode the name. The message encoding type identifier, contained in the
+ * high WORD of this value, is ignored by this function.
+ * @param pName A pointer to the CERT_NAME_BLOB structure to be converted.
+ * @param dwStrType This parameter specifies the format of the output
+ * string. This parameter also specifies other options for the contents of
+ * the string.
+ * @return Returns the retrieved string.
+ */
+ public static String CertNameToStr(int dwCertEncodingType, int dwStrType, DATA_BLOB pName) {
+ int charToBytes = Boolean.getBoolean("w32.ascii") ? 1 : Native.WCHAR_SIZE;
+
+ // Initialize the signature structure.
+ int requiredSize = Crypt32.INSTANCE.CertNameToStr(
+ dwCertEncodingType,
+ pName,
+ dwStrType,
+ Pointer.NULL,
+ 0);
+
+ Memory mem = new Memory(requiredSize * charToBytes);
+
+ // Initialize the signature structure.
+ int resultBytes = Crypt32.INSTANCE.CertNameToStr(
+ dwCertEncodingType,
+ pName,
+ dwStrType,
+ mem,
+ requiredSize);
+
+ assert resultBytes == requiredSize;
+
+ if (Boolean.getBoolean("w32.ascii")) {
+ return mem.getString(0);
+ } else {
+ return mem.getWideString(0);
+ }
+ }
}
\ No newline at end of file
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Cryptui.java b/contrib/platform/src/com/sun/jna/platform/win32/Cryptui.java
new file mode 100644
index 0000000000..b2c6f4ea12
--- /dev/null
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Cryptui.java
@@ -0,0 +1,71 @@
+/* Copyright (c) 2018 Roshan Muralidharan, All Rights Reserved
+ *
+ * The contents of this file is dual-licensed under 2
+ * alternative Open Source/Free licenses: LGPL 2.1 or later and
+ * Apache License 2.0. (starting with JNA version 4.0.0).
+ *
+ * You can freely decide which license you want to apply to
+ * the project.
+ *
+ * You may obtain a copy of the LGPL License at:
+ *
+ * http://www.gnu.org/licenses/licenses.html
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "LGPL2.1".
+ *
+ * You may obtain a copy of the Apache License at:
+ *
+ * http://www.apache.org/licenses/
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "AL2.0".
+ */
+package com.sun.jna.platform.win32;
+
+import com.sun.jna.Native;
+import com.sun.jna.PointerType;
+import com.sun.jna.platform.win32.WinDef.HWND;
+import com.sun.jna.platform.win32.WinNT.HANDLE;
+import com.sun.jna.win32.StdCallLibrary;
+import com.sun.jna.win32.W32APIOptions;
+import com.sun.jna.platform.win32.WinCrypt.*;
+
+/**
+ * Cryptui.dll Interface.
+ * @author roshan[dot]muralidharan[at]cerner[dot]com
+ */
+public interface Cryptui extends StdCallLibrary {
+
+ Cryptui INSTANCE = (Cryptui) Native.loadLibrary("Cryptui", Cryptui.class, W32APIOptions.UNICODE_OPTIONS);
+
+ /**
+ * The CryptUIDlgSelectCertificateFromStore function displays a dialog box that
+ * allows the selection of a certificate from a specified store.
+ *
+ * @param hCertStore
+ * Handle of the certificate store to be searched.
+ * @param hwnd
+ * Handle of the window for the display. If NULL, defaults to the
+ * desktop window.
+ * @param pwszTitle
+ * String used as the title of the dialog box. If NULL, the default
+ * title, "Select Certificate," is used.
+ * @param pwszDisplayString
+ * Text statement in the selection dialog box. If NULL, the default
+ * phrase, "Select a certificate you want to use," is used.
+ * @param dwDontUseColumn
+ * Flags that can be combined to exclude columns of the display.
+ * @param dwFlags
+ * Currently not used and should be set to 0.
+ * @param pvReserved
+ * Reserved for future use.
+ * @return Returns a pointer to the selected certificate context. If no
+ * certificate was selected, NULL is returned. When you have finished
+ * using the certificate, free the certificate context by calling the
+ * CertFreeCertificateContext function.
+ */
+ CERT_CONTEXT.ByReference CryptUIDlgSelectCertificateFromStore(HCERTSTORE hCertStore, HWND hwnd, String pwszTitle,
+ String pwszDisplayString, int dwDontUseColumn, int dwFlags, PointerType pvReserved);
+
+}
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java b/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java
index 1ae62a82e5..a36a05d529 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java
@@ -179,7 +179,7 @@ public String getString() {
}
public static class LPSTR extends PointerType {
- public static class ByReference extends BSTR implements
+ public static class ByReference extends LPSTR implements
Structure.ByReference {
}
@@ -192,19 +192,19 @@ public LPSTR(Pointer pointer) {
}
public LPSTR(String value) {
- this(new Memory((value.length() + 1L) * Native.WCHAR_SIZE));
+ this(new Memory(value.length() + 1L));
this.setValue(value);
}
public void setValue(String value) {
- this.getPointer().setWideString(0, value);
+ this.getPointer().setString(0, value);
}
public String getValue() {
Pointer pointer = this.getPointer();
String str = null;
if (pointer != null)
- str = pointer.getWideString(0);
+ str = pointer.getString(0);
return str;
}
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 be61b88397..416959e139 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java
@@ -28,9 +28,17 @@
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
+import com.sun.jna.StringArray;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.win32.W32APITypeMapper;
+import com.sun.jna.platform.win32.Guid.GUID;
+import com.sun.jna.platform.win32.WTypes.LPSTR;
+import com.sun.jna.platform.win32.WinBase.FILETIME;
+import com.sun.jna.platform.win32.WinCrypt.DATA_BLOB;
+import com.sun.jna.platform.win32.WinNT.HANDLE;
+import com.sun.jna.Union;
+import com.sun.jna.win32.StdCallLibrary;
/**
* Ported from WinCrypt.h.
@@ -43,7 +51,10 @@ public interface WinCrypt {
* The CryptoAPI CRYPTOAPI_BLOB structure is used for an arbitrary array of bytes.
*/
public static class DATA_BLOB extends Structure {
+ public static class ByReference extends DATA_BLOB implements Structure.ByReference {}
+
public static final List FIELDS = createFieldsOrder("cbData", "pbData");
+
/**
* The count of bytes in the buffer pointed to by pbData.
*/
@@ -87,7 +98,1312 @@ public byte[] getData() {
return pbData == null ? null : pbData.getByteArray(0, cbData);
}
}
+
+ /**
+ * The CERT_TRUST_STATUS structure contains trust information about a
+ * certificate in a certificate chain, summary trust information about a
+ * simple chain of certificates, or summary information about an array of
+ * simple chains.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_TRUST_STATUS extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwErrorStatus", "dwInfoStatus");
+
+ public static class ByReference extends CERT_TRUST_STATUS implements Structure.ByReference {
+ }
+
+ public int dwErrorStatus;
+ public int dwInfoStatus;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CTL_ENTRY structure is an element of a certificate trust list (CTL).
+ *
+ * @see
+ * MSDN
+ */
+ public static class CTL_ENTRY extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "SubjectIdentifier", "cAttribute", "rgAttribute");
+
+ public static class ByReference extends CTL_ENTRY implements Structure.ByReference {
+ }
+
+ public DATA_BLOB SubjectIdentifier;
+ public int cAttribute;
+ public Pointer rgAttribute;
+
+ public CRYPT_ATTRIBUTE[] getRgAttribute() {
+ if (cAttribute == 0) {
+ return new CRYPT_ATTRIBUTE[0];
+ } else {
+ return (CRYPT_ATTRIBUTE[]) Structure.newInstance(
+ CERT_EXTENSION.class,
+ rgAttribute)
+ .toArray(cAttribute);
+ }
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * Contains information updated by a certificate revocation list (CRL)
+ * revocation type handler. The CERT_REVOCATION_CRL_INFO structure is used
+ * with both base and delta CRLs.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_REVOCATION_CRL_INFO extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "pBaseCRLContext", "pDeltaCRLContext", "pCrlEntry",
+ "fDeltaCrlEntry");
+
+ public static class ByReference extends CERT_REVOCATION_CRL_INFO implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public CRL_CONTEXT.ByReference pBaseCRLContext;
+ public CRL_CONTEXT.ByReference pDeltaCRLContext;
+ public CRL_ENTRY.ByReference pCrlEntry;
+ public boolean fDeltaCrlEntry;
+
+ public CERT_REVOCATION_CRL_INFO() {
+ super(W32APITypeMapper.DEFAULT);
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_REVOCATION_INFO structure indicates the revocation status of a
+ * certificate in a CERT_CHAIN_ELEMENT.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_REVOCATION_INFO extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder("cbSize",
+ "dwRevocationResult", "pszRevocationOid", "pvOidSpecificInfo",
+ "fHasFreshnessTime", "dwFreshnessTime", "pCrlInfo");
+
+ public static class ByReference extends CERT_REVOCATION_INFO implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public int dwRevocationResult;
+ public String pszRevocationOid;
+ public Pointer pvOidSpecificInfo;
+ public boolean fHasFreshnessTime;
+ public int dwFreshnessTime;
+ public CERT_REVOCATION_CRL_INFO.ByReference pCrlInfo;
+
+ public CERT_REVOCATION_INFO() {
+ super(W32APITypeMapper.ASCII);
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_CHAIN_ELEMENT structure is a single element in a simple
+ * certificate chain. Each element has a pointer to a certificate context, a
+ * pointer to a structure that indicates the error status and information
+ * status of the certificate, and a pointer to a structure that indicates
+ * the revocation status of the certificate.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_CHAIN_ELEMENT extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder("cbSize",
+ "pCertContext", "TrustStatus", "pRevocationInfo", "pIssuanceUsage",
+ "pApplicationUsage", "pwszExtendedErrorInfo");
+
+ public static class ByReference extends CERT_CHAIN_ELEMENT implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public CERT_CONTEXT.ByReference pCertContext;
+ public CERT_TRUST_STATUS TrustStatus;
+ public CERT_REVOCATION_INFO.ByReference pRevocationInfo;
+ public CTL_USAGE.ByReference pIssuanceUsage;
+ public CTL_USAGE.ByReference pApplicationUsage;
+
+ public String pwszExtendedErrorInfo;
+
+ public CERT_CHAIN_ELEMENT() {
+ super(W32APITypeMapper.UNICODE);
+ }
+
+ public CERT_CHAIN_ELEMENT(Pointer p) {
+ super(p, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE);
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CTL_INFO structure contains the information stored in a Certificate
+ * Trust List (CTL).
+ *
+ * @see
+ * MSDN
+ */
+ public static class CTL_INFO extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwVersion", "SubjectUsage", "ListIdentifier", "SequenceNumber",
+ "ThisUpdate", "NextUpdate", "SubjectAlgorithm", "cCTLEntry",
+ "rgCTLEntry", "cExtension", "rgExtension");
+
+ public static class ByReference extends CTL_INFO implements Structure.ByReference {
+ }
+
+ public int dwVersion;
+ public CTL_USAGE SubjectUsage;
+ public DATA_BLOB ListIdentifier;
+ public DATA_BLOB SequenceNumber;
+ public FILETIME ThisUpdate;
+ public FILETIME NextUpdate;
+ public CRYPT_ALGORITHM_IDENTIFIER SubjectAlgorithm;
+ public int cCTLEntry;
+ public Pointer rgCTLEntry;
+ public int cExtension;
+ public Pointer rgExtension;
+
+ public CTL_ENTRY[] getRgExtension() {
+ if (cCTLEntry == 0) {
+ return new CTL_ENTRY[0];
+ } else {
+ return (CTL_ENTRY[]) Structure.newInstance(
+ CTL_ENTRY.class,
+ rgCTLEntry)
+ .toArray(cCTLEntry);
+ }
+ }
+
+ public CERT_EXTENSION[] getRgCTLEntry() {
+ if (cExtension == 0) {
+ return new CERT_EXTENSION[0];
+ } else {
+ return (CERT_EXTENSION[]) Structure.newInstance(
+ CERT_EXTENSION.class,
+ rgExtension)
+ .toArray(cExtension);
+ }
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CTL_CONTEXT structure contains both the encoded and decoded
+ * representations of a CTL. It also contains an opened HCRYPTMSG handle to
+ * the decoded, cryptographically signed message containing the CTL_INFO as
+ * its inner content.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CTL_CONTEXT extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwMsgAndCertEncodingType", "pbCtlEncoded", "cbCtlEncoded",
+ "pCtlInfo", "hCertStore", "hCryptMsg", "pbCtlContent",
+ "cbCtlContent");
+
+ public static class ByReference extends CTL_CONTEXT implements Structure.ByReference {
+ }
+
+ public int dwMsgAndCertEncodingType;
+ public Pointer pbCtlEncoded;
+ public int cbCtlEncoded;
+ public CTL_INFO.ByReference pCtlInfo;
+ public HCERTSTORE hCertStore;
+ public HCRYPTMSG hCryptMsg;
+ public Pointer pbCtlContent;
+ public int cbCtlContent;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_TRUST_LIST_INFO structure that indicates valid usage of a CTL.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_TRUST_LIST_INFO extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "pCtlEntry", "pCtlContext");
+
+ public static class ByReference extends CERT_TRUST_LIST_INFO implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public CTL_ENTRY.ByReference pCtlEntry;
+ public CTL_CONTEXT.ByReference pCtlContext;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CTL_USAGE structure contains an array of object identifiers (OIDs)
+ * for Certificate Trust List (CTL) extensions. CTL_USAGE structures are
+ * used in functions that search for CTLs for specific uses.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CTL_USAGE extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cUsageIdentifier", "rgpszUsageIdentifier");
+
+ public static class ByReference extends CTL_USAGE implements Structure.ByReference {
+ }
+
+ public int cUsageIdentifier;
+ public Pointer rgpszUsageIdentifier;
+
+ public CTL_USAGE() {
+ super();
+ }
+
+ public String[] getRgpszUsageIdentier() {
+ if (cUsageIdentifier == 0) {
+ return new String[0];
+ } else {
+ return rgpszUsageIdentifier.getStringArray(0, cUsageIdentifier);
+ }
+ }
+
+ public void setRgpszUsageIdentier(String[] array) {
+ if (array == null || array.length == 0) {
+ cUsageIdentifier = 0;
+ rgpszUsageIdentifier = null;
+ } else {
+ cUsageIdentifier = array.length;
+ rgpszUsageIdentifier = new StringArray(array);
+ }
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_USAGE_MATCH structure provides criteria for identifying issuer
+ * certificates to be used to build a certificate chain.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_USAGE_MATCH extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwType", "Usage");
+
+ public static class ByReference extends CERT_USAGE_MATCH implements Structure.ByReference {
+ }
+
+ public int dwType;
+ public CTL_USAGE Usage;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_CHAIN_PARA structure establishes the searching and matching
+ * criteria to be used in building a certificate chain.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_CHAIN_PARA extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "RequestedUsage", "RequestedIssuancePolicy",
+ "dwUrlRetrievalTimeout", "fCheckRevocationFreshnessTime",
+ "dwRevocationFreshnessTime", "pftCacheResync", "pStrongSignPara",
+ "dwStrongSignFlags");
+
+ public static class ByReference extends CERT_CHAIN_PARA implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public CERT_USAGE_MATCH RequestedUsage;
+ public CERT_USAGE_MATCH RequestedIssuancePolicy;
+ public int dwUrlRetrievalTimeout;
+ public boolean fCheckRevocationFreshnessTime;
+ public int dwRevocationFreshnessTime;
+ public FILETIME.ByReference pftCacheResync;
+ public CERT_STRONG_SIGN_PARA.ByReference pStrongSignPara;
+ public int dwStrongSignFlags;
+
+ public CERT_CHAIN_PARA() {
+ super(W32APITypeMapper.DEFAULT);
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * Contains parameters used to check for strong signatures on certificates,
+ * certificate revocation lists (CRLs), online certificate status protocol
+ * (OCSP) responses, and PKCS #7 messages.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_STRONG_SIGN_PARA extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "dwInfoChoice", "DUMMYUNIONNAME");
+
+ public static class ByReference extends CERT_CHAIN_PARA implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public int dwInfoChoice;
+ public DUMMYUNION DUMMYUNIONNAME;
+
+ public class DUMMYUNION extends Union {
+
+ Pointer pvInfo;
+ CERT_STRONG_SIGN_SERIALIZED_INFO.ByReference pSerializedInfo;
+ LPSTR pszOID;
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * Contains the signature algorithm/hash algorithm and public key
+ * algorithm/bit length pairs that can be used for strong signing. This
+ * structure is used by the CERT_STRONG_SIGN_PARA structure.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_STRONG_SIGN_SERIALIZED_INFO extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwFlags", "pwszCNGSignHashAlgids", "pwszCNGPubKeyMinBitLengths");
+
+ public static class ByReference extends CERT_CHAIN_PARA implements Structure.ByReference {
+ }
+
+ public int dwFlags;
+ public String pwszCNGSignHashAlgids;
+ public String pwszCNGPubKeyMinBitLengths;
+
+ public CERT_STRONG_SIGN_SERIALIZED_INFO() {
+ super(W32APITypeMapper.UNICODE);
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_CHAIN_POLICY_STATUS structure holds certificate chain status
+ * information returned by the CertVerifyCertificateChainPolicy function
+ * when the certificate chains are validated.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_CHAIN_POLICY_STATUS extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "dwError", "lChainIndex", "lElementIndex",
+ "pvExtraPolicyStatus");
+
+ public static class ByReference extends CERT_CHAIN_POLICY_STATUS implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public int dwError;
+ public int lChainIndex;
+ public int lElementIndex;
+ public Pointer pvExtraPolicyStatus;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_SIMPLE_CHAIN structure contains an array of chain elements and a
+ * summary trust status for the chain that the array represents.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_SIMPLE_CHAIN extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "TrustStatus", "cElement", "rgpElement", "pTrustListInfo",
+ "fHasRevocationFreshnessTime", "dwRevocationFreshnessTime");
+
+ public static class ByReference extends CERT_SIMPLE_CHAIN implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public CERT_TRUST_STATUS TrustStatus;
+ public int cElement;
+ public Pointer rgpElement;
+ public CERT_TRUST_LIST_INFO.ByReference pTrustListInfo;
+
+ public boolean fHasRevocationFreshnessTime;
+ public int dwRevocationFreshnessTime;
+
+ public CERT_SIMPLE_CHAIN() {
+ super(W32APITypeMapper.DEFAULT);
+ }
+
+ public CERT_CHAIN_ELEMENT[] getRgpElement() {
+ CERT_CHAIN_ELEMENT[] elements = new CERT_CHAIN_ELEMENT[cElement];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CERT_CHAIN_ELEMENT.class,
+ rgpElement.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_CHAIN_POLICY_PARA structure contains information used in
+ * CertVerifyCertificateChainPolicy to establish policy criteria for the
+ * verification of certificate chains.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_CHAIN_POLICY_PARA extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "dwFlags", "pvExtraPolicyPara");
+
+ public static class ByReference extends CERT_CHAIN_POLICY_PARA implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public int dwFlags;
+ public Pointer pvExtraPolicyPara;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_CHAIN_CONTEXT structure contains an array of simple certificate
+ * chains and a trust status structure that indicates summary validity data
+ * on all of the connected simple chains.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_CHAIN_CONTEXT extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "TrustStatus", "cChain", "rgpChain",
+ "cLowerQualityChainContext", "rgpLowerQualityChainContext",
+ "fHasRevocationFreshnessTime", "dwRevocationFreshnessTime",
+ "dwCreateFlags", "ChainId");
+
+ public static class ByReference extends CERT_CHAIN_CONTEXT implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public CERT_TRUST_STATUS TrustStatus;
+ public int cChain;
+ public Pointer rgpChain;
+ public int cLowerQualityChainContext;
+ public Pointer rgpLowerQualityChainContext;
+ public boolean fHasRevocationFreshnessTime;
+ public int dwRevocationFreshnessTime;
+ public int dwCreateFlags;
+ public GUID ChainId;
+
+ public CERT_SIMPLE_CHAIN[] getRgpChain() {
+ CERT_SIMPLE_CHAIN[] elements = new CERT_SIMPLE_CHAIN[cChain];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CERT_SIMPLE_CHAIN.class,
+ rgpChain.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ public CERT_CHAIN_CONTEXT[] getRgpLowerQualityChainContext() {
+ CERT_CHAIN_CONTEXT[] elements = new CERT_CHAIN_CONTEXT[cLowerQualityChainContext];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CERT_CHAIN_CONTEXT.class,
+ rgpLowerQualityChainContext.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ public CERT_CHAIN_CONTEXT() {
+ super(W32APITypeMapper.DEFAULT);
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_CONTEXT structure contains both the encoded and decoded
+ * representations of a certificate. A certificate context returned by one
+ * of the functions defined in Wincrypt.h must be freed by calling the
+ * CertFreeCertificateContext function. The CertDuplicateCertificateContext
+ * function can be called to make a duplicate copy (which also must be freed
+ * by calling CertFreeCertificateContext).
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_CONTEXT extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwCertEncodingType", "pbCertEncoded", "cbCertEncoded",
+ "pCertInfo", "hCertStore");
+
+ public static class ByReference extends CERT_CONTEXT implements Structure.ByReference {
+ }
+
+ public int dwCertEncodingType;
+ public Pointer pbCertEncoded;
+ public int cbCertEncoded;
+ public CERT_INFO.ByReference pCertInfo;
+ public HCERTSTORE hCertStore;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_EXTENSION structure contains the extension information for a
+ * certificate, Certificate Revocation List (CRL) or Certificate Trust List
+ * (CTL).
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_EXTENSION extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "pszObjId", "fCritical", "Value");
+
+ public static class ByReference extends CERT_EXTENSION implements Structure.ByReference {
+ }
+
+ public String pszObjId;
+ public boolean fCritical;
+ public DATA_BLOB Value;
+
+ public CERT_EXTENSION() {
+ super(W32APITypeMapper.ASCII);
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_EXTENSIONS structure contains an array of extensions.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_EXTENSIONS extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cExtension", "rgExtension");
+
+ public static class ByReference extends CERT_EXTENSIONS implements Structure.ByReference {
+ }
+
+ public int cExtension;
+ public Pointer rgExtension;
+
+ public CERT_EXTENSION[] getRgExtension() {
+ CERT_EXTENSION[] elements = new CERT_EXTENSION[cExtension];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CERT_EXTENSION.class,
+ rgExtension.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_INFO structure contains the information of a certificate.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_INFO extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwVersion", "SerialNumber", "SignatureAlgorithm", "Issuer",
+ "NotBefore", "NotAfter", "Subject", "SubjectPublicKeyInfo",
+ "IssuerUniqueId", "SubjectUniqueId", "cExtension", "rgExtension");
+
+ public static class ByReference extends CERT_INFO implements Structure.ByReference {
+ }
+
+ public int dwVersion;
+ public DATA_BLOB SerialNumber;
+ public CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
+ public DATA_BLOB Issuer;
+ public FILETIME NotBefore;
+ public FILETIME NotAfter;
+ public DATA_BLOB Subject;
+ public CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
+ public CRYPT_BIT_BLOB IssuerUniqueId;
+ public CRYPT_BIT_BLOB SubjectUniqueId;
+ public int cExtension;
+ public Pointer rgExtension;
+
+ public CERT_EXTENSION[] getRgExtension() {
+ CERT_EXTENSION[] elements = new CERT_EXTENSION[cExtension];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CERT_EXTENSION.class,
+ rgExtension.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CERT_PUBLIC_KEY_INFO structure contains a public key and its
+ * algorithm.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CERT_PUBLIC_KEY_INFO extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "Algorithm", "PublicKey");
+
+ public static class ByReference extends CERT_PUBLIC_KEY_INFO implements Structure.ByReference {
+ }
+
+ public CRYPT_ALGORITHM_IDENTIFIER Algorithm;
+ public CRYPT_BIT_BLOB PublicKey;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CRL_CONTEXT structure contains both the encoded and decoded
+ * representations of a certificate revocation list (CRL). CRL contexts
+ * returned by any CryptoAPI function must be freed by calling the
+ * CertFreeCRLContext function.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRL_CONTEXT extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwCertEncodingType", "pbCrlEncoded", "cbCrlEncoded",
+ "pCrlInfo", "hCertStore");
+
+ public static class ByReference extends CRL_CONTEXT implements Structure.ByReference {
+ }
+
+ public int dwCertEncodingType;
+ public Pointer pbCrlEncoded;
+ public int cbCrlEncoded;
+ public CRL_INFO.ByReference pCrlInfo;
+ public HCERTSTORE hCertStore;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CRL_ENTRY structure contains information about a single revoked
+ * certificate. It is a member of a CRL_INFO structure.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRL_ENTRY extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "SerialNumber", "RevocationDate", "cExtension", "rgExtension");
+
+ public static class ByReference extends CRL_ENTRY implements Structure.ByReference {
+ }
+
+ public DATA_BLOB SerialNumber;
+ public FILETIME RevocationDate;
+ public int cExtension;
+ public Pointer rgExtension;
+
+ public CERT_EXTENSION[] getRgExtension() {
+ CERT_EXTENSION[] elements = new CERT_EXTENSION[cExtension];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CERT_EXTENSION.class,
+ rgExtension.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CRL_INFO structure contains the information of a certificate
+ * revocation list (CRL).
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRL_INFO extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwVersion", "SignatureAlgorithm", "Issuer", "ThisUpdate",
+ "NextUpdate", "cCRLEntry", "rgCRLEntry", "cExtension",
+ "rgExtension");
+
+ public static class ByReference extends CRL_INFO implements Structure.ByReference {
+ }
+
+ public int dwVersion;
+ public CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
+ public DATA_BLOB Issuer;
+ public FILETIME ThisUpdate;
+ public FILETIME NextUpdate;
+ public int cCRLEntry;
+ public Pointer rgCRLEntry;
+ public int cExtension;
+ public Pointer rgExtension;
+
+ public CRL_ENTRY[] getRgCRLEntry() {
+ CRL_ENTRY[] elements = new CRL_ENTRY[cCRLEntry];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CRL_ENTRY.class,
+ rgCRLEntry.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ public CERT_EXTENSION[] getRgExtension() {
+ CERT_EXTENSION[] elements = new CERT_EXTENSION[cExtension];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CERT_EXTENSION.class,
+ rgExtension.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CRYPT_ALGORITHM_IDENTIFIER structure specifies an algorithm used to
+ * encrypt a private key. The structure includes the object identifier (OID)
+ * of the algorithm and any needed parameters for that algorithm. The
+ * parameters contained in its CRYPT_OBJID_BLOB are encoded.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRYPT_ALGORITHM_IDENTIFIER extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "pszObjId", "Parameters");
+
+ public static class ByReference extends CRYPT_ALGORITHM_IDENTIFIER implements Structure.ByReference {
+ }
+
+ public String pszObjId;
+ public DATA_BLOB Parameters;
+
+ public CRYPT_ALGORITHM_IDENTIFIER() {
+ super(W32APITypeMapper.ASCII);
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CRYPT_ATTRIBUTE structure specifies an attribute that has one or more
+ * values.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRYPT_ATTRIBUTE extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "pszObjId", "cValue", "rgValue");
+
+ public static class ByReference extends CRYPT_ATTRIBUTE implements Structure.ByReference {
+ }
+
+ public String pszObjId;
+ public int cValue;
+ public DATA_BLOB.ByReference rgValue;
+
+ public DATA_BLOB[] getRgValue() {
+ return (DATA_BLOB[]) rgValue.toArray(cValue);
+ }
+
+ public CRYPT_ATTRIBUTE() {
+ super(W32APITypeMapper.ASCII);
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CRYPT_BIT_BLOB structure contains a set of bits represented by an
+ * array of bytes.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRYPT_BIT_BLOB extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbData", "pbData", "cUnusedBits");
+
+ public static class ByReference extends CRYPT_BIT_BLOB implements Structure.ByReference {
+ }
+
+ public int cbData;
+ public Pointer pbData;
+ public int cUnusedBits;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CRYPT_KEY_PROV_INFO structure contains information about a key
+ * container within a cryptographic service provider (CSP).
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRYPT_KEY_PROV_INFO extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "pwszContainerName", "pwszProvName", "dwProvType", "dwFlags",
+ "cProvParam", "rgProvParam", "dwKeySpec");
+
+ public static class ByReference extends CRYPT_KEY_PROV_INFO implements Structure.ByReference {
+ }
+
+ public String pwszContainerName;
+ public String pwszProvName;
+ public int dwProvType;
+ public int dwFlags;
+ public int cProvParam;
+ public Pointer rgProvParam;
+ public int dwKeySpec;
+
+ public CRYPT_KEY_PROV_INFO() {
+ super(W32APITypeMapper.UNICODE);
+ }
+
+ public CRYPT_KEY_PROV_PARAM[] getRgProvParam() {
+ CRYPT_KEY_PROV_PARAM[] elements = new CRYPT_KEY_PROV_PARAM[cProvParam];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CRYPT_KEY_PROV_PARAM.class,
+ rgProvParam.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CRYPT_KEY_PROV_PARAM structure contains information about a key
+ * container parameter. This structure is used with the CRYPT_KEY_PROV_INFO
+ * structure.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRYPT_KEY_PROV_PARAM extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "dwParam", "pbData", "cbData", "dwFlags");
+
+ public static class ByReference extends CRYPT_KEY_PROV_PARAM implements Structure.ByReference {
+ }
+
+ public int dwParam;
+ public Pointer pbData;
+ public int cbData;
+ public int dwFlags;
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CRYPT_SIGN_MESSAGE_PARA structure contains information for signing
+ * messages using a specified signing certificate context.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRYPT_SIGN_MESSAGE_PARA extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "dwMsgEncodingType", "pSigningCert", "HashAlgorithm",
+ "pvHashAuxInfo", "cMsgCert", "rgpMsgCert", "cMsgCrl",
+ "rgpMsgCrl", "cAuthAttr", "rgAuthAttr", "cUnauthAttr",
+ "rgUnauthAttr", "dwFlags", "dwInnerContentType",
+ "HashEncryptionAlgorithm", "pvHashEncryptionAuxInfo");
+
+ public static class ByReference extends CRYPT_SIGN_MESSAGE_PARA implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public int dwMsgEncodingType;
+ public CERT_CONTEXT.ByReference pSigningCert;
+ public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
+ public Pointer pvHashAuxInfo;
+ public int cMsgCert;
+ public Pointer rgpMsgCert = null;
+ public int cMsgCrl;
+ public Pointer rgpMsgCrl = null;
+ public int cAuthAttr;
+ public Pointer rgAuthAttr = null;
+ public int cUnauthAttr;
+ public Pointer rgUnauthAttr = null;
+ public int dwFlags;
+ public int dwInnerContentType;
+ public CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
+ public Pointer pvHashEncryptionAuxInfo;
+
+ public CERT_CONTEXT[] getRgpMsgCert() {
+ CERT_CONTEXT[] elements = new CERT_CONTEXT[cMsgCrl];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CERT_CONTEXT.class,
+ rgpMsgCert.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ public CRL_CONTEXT[] getRgpMsgCrl() {
+ CRL_CONTEXT[] elements = new CRL_CONTEXT[cMsgCrl];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = Structure.newInstance(
+ CRL_CONTEXT.class,
+ rgpMsgCrl.getPointer(i * Native.POINTER_SIZE));
+ elements[i].read();
+ }
+ return elements;
+ }
+
+ public CRYPT_ATTRIBUTE[] getRgAuthAttr() {
+ if (cAuthAttr == 0) {
+ return new CRYPT_ATTRIBUTE[0];
+ } else {
+ return (CRYPT_ATTRIBUTE[]) Structure.newInstance(
+ CRYPT_ATTRIBUTE.class,
+ rgAuthAttr)
+ .toArray(cAuthAttr);
+ }
+ }
+
+ public CRYPT_ATTRIBUTE[] getRgUnauthAttr() {
+ if (cUnauthAttr == 0) {
+ return new CRYPT_ATTRIBUTE[0];
+ } else {
+ return (CRYPT_ATTRIBUTE[]) Structure.newInstance(
+ CRYPT_ATTRIBUTE.class,
+ rgUnauthAttr)
+ .toArray(cUnauthAttr);
+ }
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * The CryptGetSignerCertificateCallback user supplied callback function is
+ * used with the CRYPT_VERIFY_MESSAGE_PARA structure to get and verify a
+ * message signer's certificate.
+ */
+ public interface CryptGetSignerCertificateCallback extends StdCallLibrary.StdCallCallback {
+ /**
+ *
+ * @param pvGetArg
+ * A pointer to user-defined data passed on to the
+ * verification function as specified in the CRYPT_VERIFY_MESSAGE_PARA
+ * structure.
+ * @param dwCertEncodingType
+ * Specifies the type of encoding used. It is always acceptable to
+ * specify both the certificate and message encoding types by combining
+ * them with a bitwise-OR operation as shown in the following example:
+ *
+ * X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
+ *
+ * Currently defined encoding types are:
+ *
+ *
+ * - X509_ASN_ENCODING
+ * - PKCS_7_ASN_ENCODING
+ *
+ * @param pSignerId A pointer to a CERT_INFO structure containing the
+ * issuer and serial number. Can be NULL if there is no content or
+ * signer.
+ * @param hMsgCertStore A handle to the certificate store containing all
+ * the certificates and CRLs in the signed message.
+ * @return
+ */
+ public CERT_CONTEXT.ByReference callback(Pointer pvGetArg, int dwCertEncodingType,
+ CERT_INFO pSignerId,
+ HCERTSTORE hMsgCertStore);
+ }
+
+ /**
+ * The CRYPT_VERIFY_MESSAGE_PARA structure contains information needed to
+ * verify signed messages.
+ *
+ * @see
+ * MSDN
+ */
+ public static class CRYPT_VERIFY_MESSAGE_PARA extends Structure {
+
+ private static final List fieldOrder = createFieldsOrder(
+ "cbSize", "dwMsgAndCertEncodingType", "hCryptProv",
+ "pfnGetSignerCertificate", "pvGetArg", "pStrongSignPara");
+
+ public static class ByReference extends CRYPT_SIGN_MESSAGE_PARA implements Structure.ByReference {
+ }
+
+ public int cbSize;
+ public int dwMsgAndCertEncodingType;
+ public HCRYPTPROV_LEGACY hCryptProv;
+ public CryptGetSignerCertificateCallback pfnGetSignerCertificate;
+ public Pointer pvGetArg;
+ public CERT_STRONG_SIGN_PARA.ByReference pStrongSignPara;
+
+ @Override
+ public void write() {
+ cbSize = size();
+ super.write();
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return fieldOrder;
+ }
+ }
+
+ /**
+ * Handle to a certificate chain engine.
+ */
+ public static class HCERTCHAINENGINE extends HANDLE {
+
+ /**
+ * Instantiates a new hcertchainengine.
+ */
+ public HCERTCHAINENGINE() {
+
+ }
+
+ /**
+ * Instantiates a new hcertchainengine.
+ *
+ * @param p the p
+ */
+ public HCERTCHAINENGINE(Pointer p) {
+ super(p);
+ }
+ }
+
+ /**
+ * Handle to a certificate store.
+ */
+ public static class HCERTSTORE extends HANDLE {
+
+ /**
+ * Instantiates a new hcertstore.
+ */
+ public HCERTSTORE() {
+
+ }
+
+ /**
+ * Instantiates a new hcertstore.
+ *
+ * @param p
+ * the p
+ */
+ public HCERTSTORE(Pointer p) {
+ super(p);
+ }
+ }
+
+ /**
+ * Handle to a cryptographic message.
+ */
+ public static class HCRYPTMSG extends HANDLE {
+ /**
+ * Instantiates a new hcryptmgr.
+ */
+ public HCRYPTMSG() {
+
+ }
+
+ /**
+ * Instantiates a new hcryptmsg.
+ *
+ * @param p
+ * the p
+ */
+ public HCRYPTMSG(Pointer p) {
+ super(p);
+ }
+ }
+
+ public static class HCRYPTPROV_LEGACY extends BaseTSD.ULONG_PTR {
+
+ public HCRYPTPROV_LEGACY() {
+ }
+
+ public HCRYPTPROV_LEGACY(long value) {
+ super(value);
+ }
+ }
+
/**
* The CRYPTPROTECT_PROMPTSTRUCT structure provides the text of a prompt and
* information about when and where that prompt is to be displayed when using
@@ -301,4 +1617,267 @@ protected List getFieldOrder() {
* @see MSDN
*/
int CRYPT_E_ASN1_NOEOD = 0x80093202;
+
+ /**
+ * Message Encoding Type.
+ *
+ * @see MSDN
+ */
+ int CRYPT_ASN_ENCODING = 0x00000001;
+
+ /**
+ * Message Encoding Type.
+ *
+ * @see MSDN
+ */
+ int CRYPT_NDR_ENCODING = 0x00000002;
+
+ /**
+ * Message Encoding Type.
+ *
+ * @see MSDN
+ */
+ int X509_ASN_ENCODING = 0x00000001;
+
+ /**
+ * Message Encoding Type.
+ *
+ * @see MSDN
+ */
+ int X509_NDR_ENCODING = 0x00000002;
+
+ /**
+ * Message Encoding Type.
+ *
+ * @see MSDN
+ */
+ int PKCS_7_ASN_ENCODING = 0x00010000;
+
+ /**
+ * Message Encoding Type.
+ *
+ * @see MSDN
+ */
+ int PKCS_7_NDR_ENCODING = 0x00020000;
+
+ /**
+ * Determines the kind of issuer matching to be done.
+ *
+ * @see MSDN
+ */
+ int USAGE_MATCH_TYPE_AND = 0x00000000;
+
+ /**
+ * Determines the kind of issuer matching to be done.
+ *
+ * @see MSDN
+ */
+ int USAGE_MATCH_TYPE_OR = 0x00000001;
+
+ /**
+ * Set the window handle that the provider uses as the parent of any dialog
+ * boxes it creates.
+ *
+ * @see MSDN
+ */
+ int PP_CLIENT_HWND = 1;
+
+ /**
+ * Certificate name string type.
+ *
+ * @see MSDN
+ */
+ int CERT_SIMPLE_NAME_STR = 1;
+
+ /**
+ * Certificate name string type.
+ *
+ * @see MSDN
+ */
+ int CERT_OID_NAME_STR = 2;
+
+ /**
+ * Certificate name string type.
+ *
+ * @see MSDN
+ */
+ int CERT_X500_NAME_STR = 3;
+
+ /**
+ * Certificate name string type.
+ *
+ * @see MSDN
+ */
+ int CERT_XML_NAME_STR = 4;
+
+ /**
+ * Predefined verify chain policies.
+ *
+ * @see MSDN
+ */
+ int CERT_CHAIN_POLICY_BASE = 1;
+
+ /**
+ * Algorithm object identifiers RSA.
+ *
+ * @see MSDN
+ */
+ String szOID_RSA_SHA1RSA = "1.2.840.113549.1.1.5";
+
+ /**
+ * Predefined certificate chain engine values.
+ *
+ * @see
+ * MSDN
+ */
+ HCERTCHAINENGINE HCCE_CURRENT_USER = new HCERTCHAINENGINE(Pointer.createConstant(0x0));
+
+ /**
+ * Predefined certificate chain engine values.
+ *
+ * @see
+ * MSDN
+ */
+ HCERTCHAINENGINE HCCE_LOCAL_MACHINE = new HCERTCHAINENGINE(Pointer.createConstant(0x1));
+
+ /**
+ * Predefined certificate chain engine values.
+ *
+ * @see
+ * MSDN
+ */
+ HCERTCHAINENGINE HCCE_SERIAL_LOCAL_MACHINE = new HCERTCHAINENGINE(Pointer.createConstant(0x2));
+
+ /**
+ * Certificate comparison functions.
+ *
+ * @see MSDN
+ */
+ int CERT_COMPARE_SHIFT = 16;
+
+ /**
+ * Certificate comparison functions.
+ *
+ * @see MSDN
+ */
+ int CERT_COMPARE_NAME_STR_W = 8;
+
+ /**
+ * Certificate comparison functions.
+ *
+ * @see MSDN
+ */
+ int CERT_INFO_SUBJECT_FLAG = 7;
+
+ /**
+ * Certificate comparison functions.
+ *
+ * @see MSDN
+ */
+ int CERT_FIND_SUBJECT_STR_W = (CERT_COMPARE_NAME_STR_W << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG);
+
+ /**
+ * Certificate comparison functions.
+ *
+ * @see MSDN
+ */
+ int CERT_FIND_SUBJECT_STR = CERT_FIND_SUBJECT_STR_W;
+
+ /**
+ * Imported keys are marked as exportable. If this flag is not used, calls
+ * to the CryptExportKey function with the key handle fail.
+ */
+ int CRYPT_EXPORTABLE = 0x00000001;
+
+ /**
+ * The user is to be notified through a dialog box or other method when
+ * certain attempts to use this key are made. The precise behavior is
+ * specified by the cryptographic service provider (CSP) being used.
+ *
+ *
+ * Prior to Internet Explorer 4.0, Microsoft cryptographic service providers
+ * ignored this flag. Starting with Internet Explorer 4.0, Microsoft
+ * providers support this flag.
+ *
+ *
+ * If the provider context was opened with the CRYPT_SILENT flag set, using
+ * this flag causes a failure and the last error is set to
+ * NTE_SILENT_CONTEXT.
+ */
+ int CRYPT_USER_PROTECTED = 0x00000002;
+
+ /**
+ * The private keys are stored under the local computer and not under the
+ * current user.
+ */
+ int CRYPT_MACHINE_KEYSET = 0x00000020;
+
+ /**
+ * The private keys are stored under the current user and not under the
+ * local computer even if the PFX BLOB specifies that they should go into
+ * the local computer.
+ */
+ int CRYPT_USER_KEYSET = 0x00001000;
+
+ /**
+ * Indicates that the CNG key storage provider (KSP) is preferred. If the
+ * CSP is specified in the PFX file, then the CSP is used, otherwise the KSP
+ * is preferred. If the CNG KSP is unavailable, the PFXImportCertStore
+ * function will fail.
+ */
+ int PKCS12_PREFER_CNG_KSP = 0x00000100;
+
+ /**
+ * Indicates that the CNG KSP is always used. When specified,
+ * PFXImportCertStore attempts to use the CNG KSP irrespective of provider
+ * information in the PFX file. If the CNG KSP is unavailable, the import
+ * will not fail.
+ */
+ int PKCS12_ALWAYS_CNG_KSP = 0x00000200;
+
+ /**
+ * Allow overwrite of the existing key. Specify this flag when you encounter
+ * a scenario in which you must import a PFX file that contains a key name
+ * that already exists. For example, when you import a PFX file, it is
+ * possible that a container of the same name is already present because
+ * there is no unique namespace for key containers. If you have created a
+ * "TestKey" on your computer, and then you import a PFX file that also has
+ * "TestKey" as the key container, the PKCS12_ALLOW_OVERWRITE_KEY setting
+ * allows the key to be overwritten.
+ */
+ int PKCS12_ALLOW_OVERWRITE_KEY = 0x00004000;
+
+ /**
+ * Do not persist the key. Specify this flag when you do not want to persist
+ * the key. For example, if it is not necessary to store the key after
+ * verification, then instead of creating a container and then deleting it,
+ * you can specify this flag to dispose of the key immediately.
+ */
+ int PKCS12_NO_PERSIST_KEY = 0x00008000;
+
+ /**
+ * Import all extended properties on the certificate that were saved on the
+ * certificate when it was exported.
+ */
+ int PKCS12_INCLUDE_EXTENDED_PROPERTIES = 0x0010;
+
+ /**
+ * 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
+ * should only be used as a diagnostic tool in the development of
+ * applications.
+ */
+ int CERT_CLOSE_STORE_FORCE_FLAG = 0x00000001;
+ /**
+ * Forces the freeing of memory for all contexts associated with the store.
+ * This flag can be safely used only when the store is opened in a function
+ * and neither the store handle nor any of its contexts are passed to any
+ * called functions. For details, see Remarks.
+ */
+ int CERT_CLOSE_STORE_CHECK_FLAG = 0x00000002;
}
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinCryptUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/WinCryptUtil.java
new file mode 100644
index 0000000000..fb5d8c6eff
--- /dev/null
+++ b/contrib/platform/src/com/sun/jna/platform/win32/WinCryptUtil.java
@@ -0,0 +1,176 @@
+/* Copyright (c) 2018 Matthias Bläsing, All Rights Reserved
+ *
+ * The contents of this file is dual-licensed under 2
+ * alternative Open Source/Free licenses: LGPL 2.1 or later and
+ * Apache License 2.0. (starting with JNA version 4.0.0).
+ *
+ * You can freely decide which license you want to apply to
+ * the project.
+ *
+ * You may obtain a copy of the LGPL License at:
+ *
+ * http://www.gnu.org/licenses/licenses.html
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "LGPL2.1".
+ *
+ * You may obtain a copy of the Apache License at:
+ *
+ * http://www.apache.org/licenses/
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "AL2.0".
+ */
+package com.sun.jna.platform.win32;
+
+import com.sun.jna.Memory;
+import com.sun.jna.Native;
+import com.sun.jna.platform.win32.WinCrypt.CERT_CONTEXT;
+import com.sun.jna.platform.win32.WinCrypt.CRL_CONTEXT;
+import com.sun.jna.platform.win32.WinCrypt.CRYPT_ATTRIBUTE;
+import com.sun.jna.platform.win32.WinCrypt.CRYPT_SIGN_MESSAGE_PARA;
+
+
+public abstract class WinCryptUtil {
+
+ public static class MANAGED_CRYPT_SIGN_MESSAGE_PARA extends CRYPT_SIGN_MESSAGE_PARA {
+
+ private CERT_CONTEXT[] rgpMsgCerts;
+ private CRL_CONTEXT[] rgpMsgCrls;
+ private CRYPT_ATTRIBUTE[] rgAuthAttrs;
+ private CRYPT_ATTRIBUTE[] rgUnauthAttrs;
+
+ public void setRgpMsgCert(CERT_CONTEXT[] rgpMsgCerts) {
+ this.rgpMsgCerts = rgpMsgCerts;
+ if (rgpMsgCerts == null || rgpMsgCerts.length == 0) {
+ rgpMsgCert = null;
+ cMsgCert = 0;
+ } else {
+ cMsgCert = rgpMsgCerts.length;
+ Memory mem = new Memory(Native.POINTER_SIZE * rgpMsgCerts.length);
+ for (int i = 0; i < rgpMsgCerts.length; i++) {
+ mem.setPointer(i * Native.POINTER_SIZE, rgpMsgCerts[i].getPointer());
+ }
+ rgpMsgCert = mem;
+ }
+ }
+
+ @Override
+ public CERT_CONTEXT[] getRgpMsgCert() {
+ return rgpMsgCerts;
+ }
+
+ public void setRgpMsgCrl(CRL_CONTEXT[] rgpMsgCrls) {
+ this.rgpMsgCrls = rgpMsgCrls;
+ if (rgpMsgCrls == null || rgpMsgCrls.length == 0) {
+ rgpMsgCert = null;
+ cMsgCert = 0;
+ } else {
+ cMsgCert = rgpMsgCrls.length;
+ Memory mem = new Memory(Native.POINTER_SIZE * rgpMsgCrls.length);
+ for (int i = 0; i < rgpMsgCrls.length; i++) {
+ mem.setPointer(i * Native.POINTER_SIZE, rgpMsgCrls[i].getPointer());
+ }
+ rgpMsgCert = mem;
+ }
+ }
+
+ @Override
+ public CRL_CONTEXT[] getRgpMsgCrl() {
+ return rgpMsgCrls;
+ }
+
+ /**
+ * @param rgAuthAttrs array of CRYPT_ATTRIBUTE - it must be created from
+ * a continous memory region (manually allocated memory or
+ * CRYPT_ATTRIBUTE#toArray)
+ */
+ public void setRgAuthAttr(CRYPT_ATTRIBUTE[] rgAuthAttrs) {
+ this.rgAuthAttrs = rgAuthAttrs;
+ if (rgAuthAttrs == null || rgAuthAttrs.length == 0) {
+ rgAuthAttr = null;
+ cMsgCert = 0;
+ } else {
+ cMsgCert = rgpMsgCerts.length;
+ rgAuthAttr = rgAuthAttrs[0].getPointer();
+ }
+ }
+
+ @Override
+ public CRYPT_ATTRIBUTE[] getRgAuthAttr() {
+ return rgAuthAttrs;
+ }
+
+ /**
+ * @param rgUnauthAttrs array of CRYPT_ATTRIBUTE - it must be created
+ * from a continous memory region (manually allocated memory or
+ * CRYPT_ATTRIBUTE#toArray)
+ */
+ public void setRgUnauthAttr(CRYPT_ATTRIBUTE[] rgUnauthAttrs) {
+ this.rgUnauthAttrs = rgUnauthAttrs;
+ if (rgUnauthAttrs == null || rgUnauthAttrs.length == 0) {
+ rgUnauthAttr = null;
+ cMsgCert = 0;
+ } else {
+ cMsgCert = rgpMsgCerts.length;
+ rgUnauthAttr = rgUnauthAttrs[0].getPointer();
+ }
+ }
+
+ @Override
+ public CRYPT_ATTRIBUTE[] getRgUnauthAttr() {
+ return rgUnauthAttrs;
+ }
+
+ @Override
+ public void write() {
+ if (rgpMsgCerts != null) {
+ for (CERT_CONTEXT cc : rgpMsgCerts) {
+ cc.write();
+ }
+ }
+ if (rgpMsgCrls != null) {
+ for (CRL_CONTEXT cc : rgpMsgCrls) {
+ cc.write();
+ }
+ }
+ if (rgAuthAttrs != null) {
+ for (CRYPT_ATTRIBUTE cc : rgAuthAttrs) {
+ cc.write();
+ }
+ }
+ if (rgUnauthAttrs != null) {
+ for (CRYPT_ATTRIBUTE cc : rgUnauthAttrs) {
+ cc.write();
+ }
+ }
+ cbSize = size();
+ super.write();
+ }
+
+ @Override
+ public void read() {
+ if (rgpMsgCerts != null) {
+ for (CERT_CONTEXT cc : rgpMsgCerts) {
+ cc.read();
+ }
+ }
+ if (rgpMsgCrls != null) {
+ for (CRL_CONTEXT cc : rgpMsgCrls) {
+ cc.read();
+ }
+ }
+ if (rgAuthAttrs != null) {
+ for (CRYPT_ATTRIBUTE cc : rgAuthAttrs) {
+ cc.read();
+ }
+ }
+ if (rgUnauthAttrs != null) {
+ for (CRYPT_ATTRIBUTE cc : rgUnauthAttrs) {
+ cc.read();
+ }
+ }
+ super.read();
+ }
+ }
+}
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 246aca0977..0083ebab83 100644
--- a/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java
+++ b/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java
@@ -11,10 +11,26 @@
* Lesser General Public License for more details.
*/
package com.sun.jna.platform.win32;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import sun.security.tools.keytool.*;
+import sun.security.x509.X500Name;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinCrypt.DATA_BLOB;
import com.sun.jna.ptr.PointerByReference;
+import com.sun.jna.platform.win32.WinCrypt.*;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.Memory;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WTypes.LPSTR;
+import com.sun.jna.platform.win32.WinCryptUtil.MANAGED_CRYPT_SIGN_MESSAGE_PARA;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
import junit.framework.TestCase;
@@ -22,10 +38,40 @@
* @author dblock[at]dblock[dot]org
*/
public class Crypt32Test extends TestCase {
+ private static final String TESTCERT_CN = "cryptsigntest";
+
+ /**
+ * Track if the test certificate was created during the test.
+ */
+ private boolean createdCertificate = false;
public static void main(String[] args) {
junit.textui.TestRunner.run(Crypt32Test.class);
}
+
+ @Override
+ protected void setUp() {
+ HCERTSTORE hCertStore = Crypt32.INSTANCE.CertOpenSystemStore(Pointer.NULL, "MY");
+
+ CERT_CONTEXT.ByReference pc = Crypt32.INSTANCE.CertFindCertificateInStore(
+ hCertStore,
+ (WinCrypt.PKCS_7_ASN_ENCODING | WinCrypt.X509_ASN_ENCODING),
+ 0,
+ WinCrypt.CERT_FIND_SUBJECT_STR,
+ new WTypes.LPWSTR(TESTCERT_CN).getPointer(),
+ null);
+
+ if (pc == null) {
+ createdCertificate = createTestCertificate();
+ }
+ }
+
+ @Override
+ protected void tearDown() {
+ if(createdCertificate) {
+ removeTestCertificate();
+ }
+ }
public void testCryptProtectUnprotectData() {
DATA_BLOB pDataIn = new DATA_BLOB("hello world");
@@ -87,10 +133,297 @@ public void testCryptProtectUnprotectDataWithEntropy() {
}
}
- public void testCertAddEncodedCertificateToSystemStore() {
- // try to install a non-existent certificate
- assertFalse("Attempting to install a non-existent certificate should have returned false and set GetLastError()", Crypt32.INSTANCE.CertAddEncodedCertificateToSystemStore("ROOT", null, 0));
- // should fail with "unexpected end of data"
- assertEquals("GetLastError() should have been set to CRYPT_E_ASN1_EOD ('ASN.1 unexpected end of data' in WinCrypt.h)", WinCrypt.CRYPT_E_ASN1_EOD, Native.getLastError());
- }
+ public void testCertAddEncodedCertificateToSystemStore() {
+ // try to install a non-existent certificate
+ assertFalse("Attempting to install a non-existent certificate should have returned false and set GetLastError()", Crypt32.INSTANCE.CertAddEncodedCertificateToSystemStore("ROOT", null, 0));
+ // should fail with "unexpected end of data"
+ assertEquals("GetLastError() should have been set to CRYPT_E_ASN1_EOD ('ASN.1 unexpected end of data' in WinCrypt.h)", WinCrypt.CRYPT_E_ASN1_EOD, Native.getLastError());
+ }
+
+ public void testCryptSignMessage() {
+ // Open user keystore
+ HCERTSTORE hCertStore = Crypt32.INSTANCE.CertOpenSystemStore(Pointer.NULL, "MY");
+
+ assertNotNull(hCertStore);
+
+ // Acquire test certificate (created in setup routine)
+ CERT_CONTEXT.ByReference signCertContext = Crypt32.INSTANCE.CertFindCertificateInStore(
+ hCertStore,
+ (WinCrypt.PKCS_7_ASN_ENCODING | WinCrypt.X509_ASN_ENCODING),
+ 0,
+ WinCrypt.CERT_FIND_SUBJECT_STR,
+ new WTypes.LPWSTR(TESTCERT_CN).getPointer(),
+ null);
+
+ assertNotNull(signCertContext);
+
+ if (signCertContext.pCertInfo.cExtension > 0) {
+ assertTrue(signCertContext.pCertInfo.cExtension == signCertContext.pCertInfo.getRgExtension().length);
+ }
+
+ // Create sample message
+ String message1String = "Message Part 1 öäü";
+ Memory message1 = new Memory((message1String.length() + 1) * Native.WCHAR_SIZE);
+ message1.setWideString(0, message1String);
+
+ // Prepare signing
+ MANAGED_CRYPT_SIGN_MESSAGE_PARA sigParams = new MANAGED_CRYPT_SIGN_MESSAGE_PARA();
+ sigParams.dwMsgEncodingType = WinCrypt.X509_ASN_ENCODING | WinCrypt.PKCS_7_ASN_ENCODING;
+ sigParams.pSigningCert = signCertContext;
+ sigParams.HashAlgorithm.pszObjId = WinCrypt.szOID_RSA_SHA1RSA;
+ sigParams.HashAlgorithm.Parameters.cbData = 0;
+ sigParams.setRgpMsgCert(new CERT_CONTEXT[]{signCertContext});
+
+ Pointer[] rgpbToBeSigned = {message1};
+ int[] rgcbToBeSigned = {(int) message1.size()};
+
+ IntByReference pcbSignedBlob1 = new IntByReference(0);
+
+ // First determine required size of the required buffer
+ boolean result = Crypt32.INSTANCE.CryptSignMessage(
+ sigParams,
+ false,
+ rgpbToBeSigned.length,
+ rgpbToBeSigned,
+ rgcbToBeSigned,
+ Pointer.NULL,
+ pcbSignedBlob1);
+
+ assertTrue("Failed to determine buffer size required for signing", result);
+
+ Memory resultBuffer = new Memory(pcbSignedBlob1.getValue());
+
+ // Create signed/encrypted buffer
+ result = Crypt32.INSTANCE.CryptSignMessage(
+ sigParams,
+ false,
+ rgpbToBeSigned.length,
+ rgpbToBeSigned,
+ rgcbToBeSigned,
+ resultBuffer,
+ pcbSignedBlob1);
+
+ assertTrue("Failed to sign buffer", result);
+
+ // Prepare verification
+ CRYPT_VERIFY_MESSAGE_PARA verifyMessagePara = new CRYPT_VERIFY_MESSAGE_PARA();
+ verifyMessagePara.dwMsgAndCertEncodingType = WinCrypt.X509_ASN_ENCODING | WinCrypt.PKCS_7_ASN_ENCODING;
+ verifyMessagePara.hCryptProv = null;
+ verifyMessagePara.pfnGetSignerCertificate = null;
+ verifyMessagePara.pvGetArg = null;
+
+ IntByReference decodedBlobSize = new IntByReference();
+
+ // Determine required buffer size for decoded buffer
+ result = Crypt32.INSTANCE.CryptVerifyMessageSignature(
+ verifyMessagePara, 0, resultBuffer,
+ (int) resultBuffer.size(), null,
+ decodedBlobSize, null);
+
+ assertTrue("Failed to determine buffer size required for verification", result);
+
+ Memory resultBuffer2 = new Memory(decodedBlobSize.getValue());
+
+ PointerByReference certContextPointer = new PointerByReference();
+
+ result = Crypt32.INSTANCE.CryptVerifyMessageSignature(
+ verifyMessagePara, 0, resultBuffer,
+ (int) resultBuffer.size(), resultBuffer2,
+ decodedBlobSize, certContextPointer);
+
+ assertTrue("Verification failed", result);
+ assertEquals(message1String, resultBuffer2.getWideString(0));
+
+ assertNotNull(certContextPointer.getValue());
+ CERT_CONTEXT resCertContext = Structure.newInstance(CERT_CONTEXT.class, certContextPointer.getValue());
+
+ Crypt32.INSTANCE.CertFreeCertificateContext(signCertContext);
+ Crypt32.INSTANCE.CertFreeCertificateContext(resCertContext);
+
+ assertTrue("CERT_CONTEXT or CERT_CHAIN_CONTEXT were not correctly freed.",
+ Crypt32.INSTANCE.CertCloseStore(hCertStore, WinCrypt.CERT_CLOSE_STORE_CHECK_FLAG));
+ }
+
+ public void testCertGetCertificateChain() throws IOException {
+ byte[] testP12 = getBytes("/res/test.p12");
+ DATA_BLOB testP12Blob = new DATA_BLOB(testP12);
+
+ HCERTSTORE hCertStore = Crypt32.INSTANCE.PFXImportCertStore(testP12Blob, new WTypes.LPWSTR("test"), 0);
+
+ assertNotNull(hCertStore);
+
+ CERT_CONTEXT.ByReference pc = Crypt32.INSTANCE.CertFindCertificateInStore(hCertStore,
+ (WinCrypt.PKCS_7_ASN_ENCODING | WinCrypt.X509_ASN_ENCODING), 0, WinCrypt.CERT_FIND_SUBJECT_STR,
+ new WTypes.LPWSTR("www.doppel-helix.eu").getPointer(), null);
+
+ assertNotNull(pc);
+
+ CERT_CHAIN_PARA pChainPara = new CERT_CHAIN_PARA();
+
+ pChainPara.cbSize = pChainPara.size();
+ pChainPara.RequestedUsage.dwType = WinCrypt.USAGE_MATCH_TYPE_AND;
+ pChainPara.RequestedUsage.Usage.cUsageIdentifier = 0;
+ pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = null;
+
+ PointerByReference pbr = new PointerByReference();
+ boolean status = Crypt32.INSTANCE.CertGetCertificateChain(null, pc, null, null, pChainPara, 0, null,
+ pbr);
+
+ assertTrue("Assert that the operation succeeded when done with a valid certificate.", status);
+ assertNotNull("Assert that a returned certificate chain context was returned.", pbr.getValue());
+ CERT_CHAIN_CONTEXT pChainContext = Structure.newInstance(CERT_CHAIN_CONTEXT.class, pbr.getValue());
+ pChainContext.read();
+
+ Pointer[] chainPointers = new Pointer[pChainContext.cChain];
+ pChainContext.rgpChain.read(0, chainPointers, 0, chainPointers.length);
+
+ CERT_SIMPLE_CHAIN csc = Structure.newInstance(CERT_SIMPLE_CHAIN.class, chainPointers[0]);
+ csc.read();
+ CERT_CHAIN_ELEMENT[] element = csc.getRgpElement();
+ assertEquals("Certificate chain does not contain 3 elements", 3, element.length);
+ for (int i = 0; i < element.length; i++) {
+ String subjectName = Crypt32Util.CertNameToStr(
+ WinCrypt.X509_ASN_ENCODING,
+ WinCrypt.CERT_SIMPLE_NAME_STR,
+ element[i].pCertContext.pCertInfo.Subject);
+ switch(i) {
+ case 0:
+ assertEquals("www.doppel-helix.eu", subjectName);
+ break;
+ case 1:
+ assertEquals("US, Let's Encrypt, Let's Encrypt Authority X3", subjectName);
+ break;
+ case 2:
+ assertEquals("Digital Signature Trust Co., DST Root CA X3", subjectName);
+ break;
+ }
+ }
+
+ // Extract usage identifiers for root certificate
+ String[] usagesArray = element[2].pApplicationUsage.getRgpszUsageIdentier();
+ assertNotNull(usagesArray);
+ assertEquals(6, usagesArray.length);
+ List usages = Arrays.asList(usagesArray);
+ assertTrue(usages.contains("1.3.6.1.5.5.7.3.1")); // Indicates that a certificate can be used as an SSL server certificate.
+ assertTrue(usages.contains("1.3.6.1.5.5.7.3.2")); // Indicates that a certificate can be used as an SSL client certificate.
+ assertTrue(usages.contains("1.3.6.1.5.5.7.3.4")); // Indicates that a certificate can be used for protecting email (signing, encryption, key agreement).
+ assertTrue(usages.contains("1.3.6.1.5.5.7.3.8")); // Indicates that a certificate can be used to bind the hash of an object to a time from a trusted time source.
+ assertTrue(usages.contains("1.3.6.1.4.1.311.10.3.4")); // Can use encrypted file systems (EFS) - szOID_EFS_CRYPTO
+ assertTrue(usages.contains("1.3.6.1.4.1.311.10.3.12")); // Signer of documents - szOID_KP_DOCUMENT_SIGNING
+
+ Crypt32.INSTANCE.CertFreeCertificateChain(pChainContext);
+ Crypt32.INSTANCE.CertFreeCertificateContext(pc);
+
+ assertTrue("CERT_CONTEXT or CERT_CHAIN_CONTEXT were not correctly freed.",
+ Crypt32.INSTANCE.CertCloseStore(hCertStore, WinCrypt.CERT_CLOSE_STORE_CHECK_FLAG));
+ }
+
+ public void testCertNameToStr() {
+ // Open user keystore
+ HCERTSTORE hCertStore = Crypt32.INSTANCE.CertOpenSystemStore(Pointer.NULL, "MY");
+
+ // Acquire test certificate (created in setup routine)
+ CERT_CONTEXT.ByReference pc = Crypt32.INSTANCE.CertFindCertificateInStore(
+ hCertStore,
+ (WinCrypt.PKCS_7_ASN_ENCODING | WinCrypt.X509_ASN_ENCODING),
+ 0,
+ WinCrypt.CERT_FIND_SUBJECT_STR,
+ new WTypes.LPWSTR(TESTCERT_CN).getPointer(),
+ null);
+
+ assertNotNull(pc);
+
+ // Initialize the signature structure.
+ int requiredSize = Crypt32.INSTANCE.CertNameToStr(
+ WinCrypt.X509_ASN_ENCODING,
+ pc.pCertInfo.Issuer,
+ WinCrypt.CERT_SIMPLE_NAME_STR,
+ Pointer.NULL,
+ 0);
+
+ assertEquals("Issuer Name length repored incorrectly", TESTCERT_CN.length() + 1, requiredSize);
+
+ Memory mem = new Memory(requiredSize * Native.WCHAR_SIZE);
+
+ int resultSize = Crypt32.INSTANCE.CertNameToStr(
+ WinCrypt.X509_ASN_ENCODING,
+ pc.pCertInfo.Issuer,
+ WinCrypt.CERT_SIMPLE_NAME_STR,
+ mem,
+ requiredSize);
+
+ assertEquals(TESTCERT_CN, mem.getWideString(0));
+
+ String utilResult = Crypt32Util.CertNameToStr(WinCrypt.X509_ASN_ENCODING, WinCrypt.CERT_SIMPLE_NAME_STR, pc.pCertInfo.Issuer);
+
+ assertEquals(TESTCERT_CN, utilResult);
+ }
+
+ public void testCertVerifyCertificateChainPolicy() {
+ CERT_CHAIN_CONTEXT pChainContext = new CERT_CHAIN_CONTEXT();
+
+ CERT_CHAIN_POLICY_PARA ChainPolicyPara = new CERT_CHAIN_POLICY_PARA();
+ CERT_CHAIN_POLICY_STATUS PolicyStatus = new CERT_CHAIN_POLICY_STATUS();
+
+ ChainPolicyPara.cbSize = ChainPolicyPara.size();
+ ChainPolicyPara.dwFlags = 0;
+
+ PolicyStatus.cbSize = PolicyStatus.size();
+ boolean status = Crypt32.INSTANCE.CertVerifyCertificateChainPolicy(
+ new LPSTR(Pointer.createConstant(WinCrypt.CERT_CHAIN_POLICY_BASE)), pChainContext, ChainPolicyPara,
+ PolicyStatus);
+ assertTrue("The status would be true since a valid certificate chain was not passed in.", status);
+ }
+
+ private boolean createTestCertificate() {
+ try {
+ KeyStore keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
+ keyStore.load(null, null);
+
+ CertAndKeyGen certAndKeyGen = new CertAndKeyGen("RSA", "SHA256WithRSA", null);
+ certAndKeyGen.generate(1024);
+
+ X509Certificate certificate = certAndKeyGen.getSelfCertificate(new X500Name("CN=cryptsigntest"), 24 * 60 * 60);
+
+ keyStore.setKeyEntry(TESTCERT_CN, certAndKeyGen.getPrivateKey(), null, new X509Certificate[]{certificate});
+ } catch (Exception e) {
+ System.out.println("Unable to complete test. Certificate creation failed.");
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean removeTestCertificate() {
+ try {
+ KeyStore keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
+ keyStore.load(null, null);
+ keyStore.deleteEntry(TESTCERT_CN);
+ } catch (Exception e) {
+ System.out.println("Test certificate deletion failed.");
+ return false;
+ }
+
+ return true;
+ }
+
+ private static byte[] getBytes(String path) throws IOException {
+ InputStream is = Crypt32Test.class.getResourceAsStream(path);
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int read;
+ byte[] buffer = new byte[10240];
+ while ((read = is.read(buffer)) > 0) {
+ baos.write(buffer, 0, read);
+ }
+ return baos.toByteArray();
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ex) {
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/contrib/platform/test/com/sun/jna/platform/win32/CryptuiTest.java b/contrib/platform/test/com/sun/jna/platform/win32/CryptuiTest.java
new file mode 100644
index 0000000000..bf82737026
--- /dev/null
+++ b/contrib/platform/test/com/sun/jna/platform/win32/CryptuiTest.java
@@ -0,0 +1,47 @@
+/* Copyright (c) 2018 Roshan Muralidharan, All Rights Reserved
+ *
+ * The contents of this file is dual-licensed under 2
+ * alternative Open Source/Free licenses: LGPL 2.1 or later and
+ * Apache License 2.0. (starting with JNA version 4.0.0).
+ *
+ * You can freely decide which license you want to apply to
+ * the project.
+ *
+ * You may obtain a copy of the LGPL License at:
+ *
+ * http://www.gnu.org/licenses/licenses.html
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "LGPL2.1".
+ *
+ * You may obtain a copy of the Apache License at:
+ *
+ * http://www.apache.org/licenses/
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "AL2.0".
+ */
+package com.sun.jna.platform.win32;
+
+import com.sun.jna.Native;
+import com.sun.jna.platform.win32.WinCrypt.DATA_BLOB;
+import com.sun.jna.ptr.PointerByReference;
+import com.sun.jna.platform.win32.WinCrypt.*;
+
+import junit.framework.TestCase;
+
+/**
+ * @author roshan[dot]muralidharan[at]cerner[dot]com
+ */
+public class CryptuiTest extends TestCase {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(CryptuiTest.class);
+ }
+
+ public void testCryptUIDlgSelectCertificateFromStore() {
+ CERT_CONTEXT.ByReference context = Cryptui.INSTANCE.CryptUIDlgSelectCertificateFromStore(null, null, "", "", 2, 0, null);
+
+ assertNull("Context should be null as a valid certificate store handle was not provided.", context);
+ }
+}
\ No newline at end of file
diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java
index 91dd0ba93f..561d087c9b 100644
--- a/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java
+++ b/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java
@@ -22,10 +22,13 @@ public class WTypesTest extends TestCase {
private static final String TEST_STRING = "input";
- private static final Pointer TEST_POINTER = new Memory((TEST_STRING.length() + 1L) * Native.WCHAR_SIZE);
+ private static final Pointer TEST_POINTER_WCHAR = new Memory((TEST_STRING.length() + 1L) * Native.WCHAR_SIZE);
+
+ private static final Pointer TEST_POINTER_CHAR = new Memory(TEST_STRING.length() + 1L);
static {
- TEST_POINTER.setWideString(0, TEST_STRING);
+ TEST_POINTER_WCHAR.setWideString(0, TEST_STRING);
+ TEST_POINTER_CHAR.setString(0, TEST_STRING);
}
public void testLPOLESTRConstruction() {
@@ -33,7 +36,7 @@ public void testLPOLESTRConstruction() {
assertEquals(fromString.getValue(), TEST_STRING);
WTypes.LPOLESTR empty = new WTypes.LPOLESTR();
assertNull(empty.getValue());
- WTypes.LPOLESTR fromPointer = new WTypes.LPOLESTR(TEST_POINTER);
+ WTypes.LPOLESTR fromPointer = new WTypes.LPOLESTR(TEST_POINTER_WCHAR);
assertEquals(fromPointer.getValue(), TEST_STRING);
}
@@ -42,7 +45,7 @@ public void testLPSTRConstruction() {
assertEquals(instance.getValue(), TEST_STRING);
WTypes.LPSTR empty = new WTypes.LPSTR();
assertNull(empty.getValue());
- WTypes.LPSTR fromPointer = new WTypes.LPSTR(TEST_POINTER);
+ WTypes.LPSTR fromPointer = new WTypes.LPSTR(TEST_POINTER_CHAR);
assertEquals(fromPointer.getValue(), TEST_STRING);
}
@@ -51,7 +54,7 @@ public void testLPWSTRConstruction() {
assertEquals(instance.getValue(), TEST_STRING);
WTypes.LPWSTR empty = new WTypes.LPWSTR();
assertNull(empty.getValue());
- WTypes.LPWSTR fromPointer = new WTypes.LPWSTR(TEST_POINTER);
+ WTypes.LPWSTR fromPointer = new WTypes.LPWSTR(TEST_POINTER_WCHAR);
assertEquals(fromPointer.getValue(), TEST_STRING);
}
diff --git a/contrib/platform/test/res/test.p12 b/contrib/platform/test/res/test.p12
new file mode 100644
index 0000000000..fc720e690c
Binary files /dev/null and b/contrib/platform/test/res/test.p12 differ
diff --git a/www/Contributing.md b/www/Contributing.md
index 9ddd727113..897a212cbe 100644
--- a/www/Contributing.md
+++ b/www/Contributing.md
@@ -6,7 +6,7 @@ JNA contains work from many developers. You're encouraged to contribute to both
- Install Git and configure it to work with Github
- Fork the code from [github.com/twall/jna](https://github.com/java-native-access/jna)
- Check out the code with `git clone git@github.com:username/jna.git`
-- Ensure you can build the project with `ant dist test`
+- Ensure you can build the project with `ant dist test test-platform`
- Make your code changes, write tests, build
- Submit pull requests, forks and/or topical branches are encouraged.
@@ -28,7 +28,7 @@ For debian-style installs,
For most unix-like systems:
% git clone git@github.com:java-native-access/jna
- % ant dist test
+ % ant dist test test-platform
For Windows, see [Windows Development Environment](WindowsDevelopmentEnvironment.md).