Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/xmlsec/mscng/x509.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ XMLSEC_CRYPTO_EXPORT int xmlSecMSCngX509StoreAdoptTrustedStore (x
XMLSEC_CRYPTO_EXPORT int xmlSecMSCngX509StoreAdoptUntrustedStore (xmlSecKeyDataStorePtr store,
HCERTSTORE untrustedStore);
XMLSEC_CRYPTO_EXPORT PCCERT_CONTEXT xmlSecMSCngX509StoreVerify (xmlSecKeyDataStorePtr store,
HCERTSTORE certs,
xmlSecKeyInfoCtxPtr keyInfoCtx);
HCERTSTORE certs,
xmlSecKeyInfoCtxPtr keyInfoCtx);

/******************************************************************************
*
Expand Down
9 changes: 9 additions & 0 deletions include/xmlsec/mscrypto/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ extern "C" {
*****************************************************************************/
XMLSEC_CRYPTO_EXPORT int xmlSecMSCryptoAppInit (const char* config);
XMLSEC_CRYPTO_EXPORT int xmlSecMSCryptoAppShutdown (void);

/* This getter returns LPCTSTR (const TCHAR*). The width of TCHAR is fixed at
* compile time by the UNICODE/_UNICODE macro: wchar_t (2 bytes) when UNICODE
* is defined, char (1 byte) otherwise. The underlying string is allocated by
* the library with the library's own TCHAR width, so the consuming application
* must be compiled with the same UNICODE/_UNICODE setting as the xmlsec
* library. If the character sets mismatch, the returned pointer misinterprets
* the string (e.g. a wide string read as a narrow one), which is undefined
* behavior. */
XMLSEC_CRYPTO_EXPORT LPCTSTR xmlSecMSCryptoAppGetCertStoreName (void);

/******************************************************************************
Expand Down
16 changes: 13 additions & 3 deletions include/xmlsec/mscrypto/symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,19 @@ extern "C" {
#define xmlSecKeyDataGostR3410_2012_512Id xmlSecMSCryptoKeyDataGost2012_512Id
#define xmlSecKeyDataHmacId xmlSecMSCryptoKeyDataHmacId
#define xmlSecKeyDataRsaId xmlSecMSCryptoKeyDataRsaId
#ifndef XMLSEC_NO_X509
#define xmlSecKeyDataX509Id xmlSecMSCryptoKeyDataX509Id
#define xmlSecKeyDataRawX509CertId xmlSecMSCryptoKeyDataRawX509CertId
#endif /* XMLSEC_NO_X509 */

/******************************************************************************
*
* Key data store ids
*
*****************************************************************************/
*
*****************************************************************************/
#ifndef XMLSEC_NO_X509
#define xmlSecX509StoreId xmlSecMSCryptoX509StoreId
#endif /* XMLSEC_NO_X509 */

/******************************************************************************
*
Expand Down Expand Up @@ -124,25 +128,31 @@ extern "C" {
*
* High-level routines for the xmlsec command-line utility
*
*****************************************************************************/
*****************************************************************************/
#define xmlSecCryptoAppInit xmlSecMSCryptoAppInit
#define xmlSecCryptoAppShutdown xmlSecMSCryptoAppShutdown
#define xmlSecCryptoAppDefaultKeysMngrInit xmlSecMSCryptoAppDefaultKeysMngrInit
#define xmlSecCryptoAppDefaultKeysMngrAdoptKey xmlSecMSCryptoAppDefaultKeysMngrAdoptKey
#define xmlSecCryptoAppDefaultKeysMngrVerifyKey xmlSecMSCryptoAppDefaultKeysMngrVerifyKey
#define xmlSecCryptoAppDefaultKeysMngrLoad xmlSecMSCryptoAppDefaultKeysMngrLoad
#define xmlSecCryptoAppDefaultKeysMngrSave xmlSecMSCryptoAppDefaultKeysMngrSave
#ifndef XMLSEC_NO_X509
#define xmlSecCryptoAppKeysMngrCertLoad xmlSecMSCryptoAppKeysMngrCertLoad
#define xmlSecCryptoAppKeysMngrCertLoadMemory xmlSecMSCryptoAppKeysMngrCertLoadMemory
#define xmlSecCryptoAppKeysMngrCrlLoad xmlSecMSCryptoAppKeysMngrCrlLoad
#define xmlSecCryptoAppKeysMngrCrlLoadMemory xmlSecMSCryptoAppKeysMngrCrlLoadMemory
#define xmlSecCryptoAppKeysMngrCrlLoadAndVerify xmlSecMSCryptoAppKeysMngrCrlLoadAndVerify
#endif /* XMLSEC_NO_X509 */
#define xmlSecCryptoAppKeyLoadEx xmlSecMSCryptoAppKeyLoadEx
#ifndef XMLSEC_NO_X509
#define xmlSecCryptoAppPkcs12Load xmlSecMSCryptoAppPkcs12Load
#define xmlSecCryptoAppKeyCertLoad xmlSecMSCryptoAppKeyCertLoad
#endif /* XMLSEC_NO_X509 */
#define xmlSecCryptoAppKeyLoadMemory xmlSecMSCryptoAppKeyLoadMemory
#ifndef XMLSEC_NO_X509
#define xmlSecCryptoAppPkcs12LoadMemory xmlSecMSCryptoAppPkcs12LoadMemory
#define xmlSecCryptoAppKeyCertLoadMemory xmlSecMSCryptoAppKeyCertLoadMemory
#endif /* XMLSEC_NO_X509 */
#define xmlSecCryptoAppGetDefaultPwdCallback xmlSecMSCryptoAppGetDefaultPwdCallback

#endif /* XMLSEC_CRYPTO_MSCRYPTO */
Expand Down
3 changes: 1 addition & 2 deletions include/xmlsec/mscrypto/x509.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ XMLSEC_CRYPTO_EXPORT int xmlSecMSCryptoX509StoreAdoptUntrustedSto
HCERTSTORE untrustedStore);

XMLSEC_CRYPTO_EXPORT void xmlSecMSCryptoX509StoreEnableSystemTrustedCerts(xmlSecKeyDataStorePtr store,
int val);

int val);


#ifdef __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion scripts/build_release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ echo "RUN MANUALLY (smtp): cd /home/apps/www/aleksey.com/xmlsec/ && sudo ln -sfn

echo "Verify that the website is working correctly."
echo "Check the Windows build script, build the Windows version, and upload it to smtp.aleksey.com:"
echo "RUN MANUALLY (Windows): scp d:\home\aleksey\distro\xmlsec1-${full_version}-win64.zip smtp.aleksey.com:"
echo "RUN MANUALLY (Windows): scp d:\home\aleksey\distro.release\xmlsec1-${full_version}-win64.zip smtp.aleksey.com:"
echo "RUN MANUALLY (smtp): sudo cp ~/xmlsec1-${full_version}-win64.zip /home/apps/www/aleksey.com/xmlsec/download/win64/"
echo "RUN MANUALLY (smtp): cd /home/apps/www/aleksey.com/xmlsec/download/"
echo "Move old versions to the 'older-releases' folder"
Expand Down
8 changes: 5 additions & 3 deletions scripts/build_windows.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ openssl_version="4.0.0"
xmlsec_version="1.3.13-rc1"

orig_pwd=$(pwd)
script_dir=$(dirname "$0")
# "$0" may use Windows backslash separators (e.g. "scripts\build_windows.sh");
# normalize them to forward slashes so dirname() resolves the script directory.
script_dir=$(dirname "${0//\\//}")


# Build locations, overridable via environment variables.
Expand Down Expand Up @@ -219,7 +221,7 @@ function build_openssl {

echo "*** Configuring \"${full_name}\" ..."
OLD_PATH="$PATH"
PATH="$PATH;$PERL_PATH"
PATH="${PATH}:${PERL_PATH}"
cd "${full_name}" || return 1
perl Configure no-unit-test --prefix="${openssl_install_dir_win}" ${OPENSSL_XMLSEC_CONFIG} VC-WIN64A-HYBRIDCRT
rc=$?
Expand Down Expand Up @@ -303,7 +305,7 @@ function build_xmlsec {
function create_readme {
echo "*** Creating README..."
cd "${orig_pwd}" || return 1
cat "${script_dir}\\README-WINDOWS.md.in" | \
cat "${script_dir}/README-WINDOWS.md.in" | \
sed "s/@libxml2_version@/${libxml2_version}/g" | \
sed "s/@libxslt_version@/${libxslt_version}/g" | \
sed "s/@openssl_version@/${openssl_version}/g" | \
Expand Down
59 changes: 43 additions & 16 deletions src/mscng/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,14 @@ xmlSecMSCngAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize, xmlSecK
* @return 0 on success or a negative value otherwise.
*/
int
xmlSecMSCngAppKeyCertLoad(xmlSecKeyPtr key, const char* filename,
xmlSecKeyDataFormat format) {
xmlSecMSCngAppKeyCertLoad(
xmlSecKeyPtr key,
const char* filename,
xmlSecKeyDataFormat format
) {
xmlSecBuffer buffer;
const xmlSecByte* bufferData;
xmlSecSize bufferSize;
int ret;

xmlSecAssert2(key != NULL, -1);
Expand All @@ -483,14 +488,23 @@ xmlSecMSCngAppKeyCertLoad(xmlSecKeyPtr key, const char* filename,
return(-1);
}

ret = xmlSecMSCngAppKeyCertLoadMemory(key, xmlSecBufferGetData(&buffer),
xmlSecBufferGetSize(&buffer), format);
bufferData = xmlSecBufferGetData(&buffer);
bufferSize = xmlSecBufferGetSize(&buffer);
if((bufferData == NULL) || (bufferSize == 0)) {
xmlSecOtherError2(XMLSEC_ERRORS_R_INVALID_DATA, NULL,
"empty file: %s", xmlSecErrorsSafeString(filename));
xmlSecBufferFinalize(&buffer);
return(-1);
}

ret = xmlSecMSCngAppKeyCertLoadMemory(key, bufferData, bufferSize, format);
if(ret < 0) {
xmlSecInternalError("xmlSecMSCngAppKeyCertLoadMemory", NULL);
xmlSecBufferFinalize(&buffer);
return(-1);
}

/* done */
xmlSecBufferFinalize(&buffer);
return(0);
}
Expand Down Expand Up @@ -579,24 +593,30 @@ xmlSecMSCngAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSec
* in format=xmlSecKeyDataFormatPkcs12.
*
* @param filename the PKCS12 key filename.
* @param pwd the PKCS12 file password.
* @param pwd the PKCS12 file password (UTF-8 encoded).
* @param pwdCallback the password callback. Not supported by the MSCng
* back-end and ignored; the password must be supplied via @p pwd.
* @param pwdCallbackCtx the user context for password callback. Not supported
* by the MSCng back-end and ignored.
* @return pointer to the key or NULL if an error occurs.
*/
xmlSecKeyPtr
xmlSecMSCngAppPkcs12Load(const char *filename,
const char *pwd, void* pwdCallback, void* pwdCallbackCtx
xmlSecMSCngAppPkcs12Load(
const char *filename,
const char *pwd,
void* pwdCallback, void* pwdCallbackCtx
) {
xmlSecBuffer buffer;
xmlSecByte* data;
xmlSecKeyPtr key;
int ret;

xmlSecAssert2(filename != NULL, NULL);
xmlSecAssert2(pwd != NULL, NULL);
if(pwd == NULL) {
xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_DATA, NULL,
"password is required; password callbacks are not supported by the MSCng back-end");
return(NULL);
}

ret = xmlSecBufferInitialize(&buffer, 0);
if(ret < 0) {
Expand Down Expand Up @@ -668,17 +688,19 @@ xmlSecMSCngIsPrivateKeyCert(PCCERT_CONTEXT cert, BOOL isPersistentKey) {
*
* @param data the key binary data.
* @param dataSize the key binary data size.
* @param pwd the PKCS12 password.
* @param pwd the PKCS12 password (UTF-8 encoded).
* @param pwdCallback the password callback. Not supported by the MSCng
* back-end and ignored; the password must be supplied via @p pwd.
* @param pwdCallbackCtx the user context for password callback. Not supported
* by the MSCng back-end and ignored.
* @return pointer to the key or NULL if an error occurs.
*/
xmlSecKeyPtr
xmlSecMSCngAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize, const char *pwd,
void *pwdCallback,
void* pwdCallbackCtx) {
xmlSecMSCngAppPkcs12LoadMemory(
const xmlSecByte* data, xmlSecSize dataSize,
const char *pwd,
void *pwdCallback, void* pwdCallbackCtx
) {
XMLSEC_UNREFERENCED(pwdCallback);
XMLSEC_UNREFERENCED(pwdCallbackCtx);
CRYPT_DATA_BLOB pfx;
Expand All @@ -694,7 +716,11 @@ xmlSecMSCngAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize, cons

xmlSecAssert2(data != NULL, NULL);
xmlSecAssert2(dataSize > 0, NULL);
xmlSecAssert2(pwd != NULL, NULL);
if(pwd == NULL) {
xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_DATA, NULL,
"password is required; password callbacks are not supported by the MSCng back-end");
return(NULL);
}

memset(&pfx, 0, sizeof(pfx));
pfx.pbData = (BYTE *)data;
Expand All @@ -706,9 +732,9 @@ xmlSecMSCngAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize, cons
return(NULL);
}

pwdWideChar = xmlSecWin32ConvertLocaleToUnicode(pwd);
pwdWideChar = xmlSecWin32ConvertUtf8ToUnicode((const xmlChar*)pwd);
if(pwdWideChar == NULL) {
xmlSecInternalError("xmlSecWin32ConvertLocaleToUnicode", NULL);
xmlSecInternalError("xmlSecWin32ConvertUtf8ToUnicode", NULL);
goto cleanup;
}

Expand Down Expand Up @@ -1366,6 +1392,7 @@ xmlSecMSCngAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename,
*/
void*
xmlSecMSCngAppGetDefaultPwdCallback(void) {
/* TODO: MSCNG doesn't support password callback */
/* The MSCng backend does not support password callbacks; the password (if any)
* must be supplied explicitly via the pwd parameter of the load functions. */
return(NULL);
}
74 changes: 52 additions & 22 deletions src/mscng/certkeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,10 @@ xmlSecMSCngKeyDataGetPubkey(xmlSecKeyDataPtr data) {
* @param data the key data to retrieve the private key from.
*
* @return the private key on success or 0 otherwise. The returned key is
* owned by the key data; the caller must not destroy it.
* owned by the key data; the caller must not destroy it. Note that DH and
* X25519 private keys are stored as a BCRYPT_KEY_HANDLE (not an
* NCRYPT_KEY_HANDLE) and are not accessible via this function; it returns 0
* for such keys.
*/
NCRYPT_KEY_HANDLE
xmlSecMSCngKeyDataGetPrivkey(xmlSecKeyDataPtr data) {
Expand Down Expand Up @@ -793,9 +796,38 @@ xmlSecMSCngCertKeyDataGetType(xmlSecKeyDataPtr data) {
return(xmlSecKeyDataTypePublic);
}

/**
* @brief Gets the key strength (in bits) of a CNG public key handle.
* @param hKey the CNG public key handle.
* @return the key strength in bits, or 0 on failure.
*/
static xmlSecSize
xmlSecMSCngGetPubkeyStrengthInBits(BCRYPT_KEY_HANDLE hKey) {
NTSTATUS status;
DWORD length = 0;
DWORD lenlen = sizeof(length);
xmlSecSize res;

/* Returns the number of bits in the key
* https://learn.microsoft.com/en-us/windows/win32/seccng/cng-property-identifiers */
status = BCryptGetProperty(hKey,
BCRYPT_KEY_STRENGTH,
(PUCHAR)&length,
lenlen,
&lenlen,
0);
if(status != STATUS_SUCCESS) {
xmlSecMSCngNtError("BCryptGetProperty", NULL, status);
return(0);
}
xmlSecAssert2(lenlen == sizeof(length), 0);

XMLSEC_SAFE_CAST_ULONG_TO_SIZE(length, res, return(0), NULL);
return(res);
}

xmlSecSize
xmlSecMSCngCertKeyDataGetSizeInBits(xmlSecKeyDataPtr data) {
NTSTATUS status;
xmlSecMSCngKeyDataCtxPtr ctx;
DWORD length = 0;
xmlSecSize res;
Expand All @@ -812,32 +844,30 @@ xmlSecMSCngCertKeyDataGetSizeInBits(xmlSecKeyDataPtr data) {
* https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetpublickeylength */
length = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
&ctx->cert->pCertInfo->SubjectPublicKeyInfo);
if(length == 0) {
xmlSecMSCngLastError("CertGetPublicKeyLength", NULL);
return(0);
if(length != 0) {
XMLSEC_SAFE_CAST_ULONG_TO_SIZE(length, res, return(0), NULL);
return(res);
}
} else if(ctx->pubkey != 0) {
DWORD lenlen = sizeof(length);
/* Returns the number of bits in the key
* https://learn.microsoft.com/en-us/windows/win32/seccng/cng-property-identifiers */
status = BCryptGetProperty(ctx->pubkey,
BCRYPT_KEY_STRENGTH,
(PUCHAR)&length,
lenlen,
&lenlen,
0);
if(status != STATUS_SUCCESS) {
xmlSecMSCngNtError("BCryptGetProperty", NULL, status);
return(0);
/* CertGetPublicKeyLength only understands RSA and some legacy EC/DSA
* encodings; it fails for X25519, DH (X9.42) and DSA > 1024.
* Fall back to the CNG key strength when the public key handle is available. */
if(ctx->pubkey != 0) {
return(xmlSecMSCngGetPubkeyStrengthInBits(ctx->pubkey));
}
xmlSecAssert2(lenlen == sizeof(length), 0);
} else if(ctx->privkey != 0) {
xmlSecMSCngLastError("CertGetPublicKeyLength", NULL);
return(0);
}

if(ctx->pubkey != 0) {
return(xmlSecMSCngGetPubkeyStrengthInBits(ctx->pubkey));
}

if(ctx->privkey != 0) {
xmlSecNotImplementedError("MSCNG doesn't support getting key length from private key");
return(0);
}

XMLSEC_SAFE_CAST_ULONG_TO_SIZE(length, res, return(0), NULL);
return(res);
return(0);
}

#define XMLSEC_MSCNG_CERTKEY_KLASS_EX(klassName, xmlName, usage, dataNodeName, dataNodeNs, generate, xmlRead, xmlWrite) \
Expand Down
5 changes: 3 additions & 2 deletions src/mscng/certkeys_dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ xmlSecMSCngKeyDataCertGetDsaPubkey(PCERT_PUBLIC_KEY_INFO spki, BCRYPT_KEY_HANDLE
xmlSecInvalidSizeMoreThanError("DSA Q size", (xmlSecSize)qSize, (xmlSecSize)XMLSEC_MSCNG_DSA_V2_Q_SIZE, NULL);
goto done;
}
if((gSize > pSize) || (ySize > pSize)) {
xmlSecInvalidDataError("invalid DSA key parameters (g/y longer than p)", NULL);
if((qSize > pSize) || (gSize > pSize) || (ySize > pSize)) {
xmlSecInvalidDataError("invalid DSA key parameters (q/g/y longer than p)", NULL);
goto done;
}

Expand Down Expand Up @@ -452,6 +452,7 @@ xmlSecMSCngKeyDataDsaRead(xmlSecKeyDataId id, xmlSecKeyValueDsaPtr dsaValue) {
xmlSecInvalidSizeMoreThanError("DSA P size", (xmlSecSize)pSize, (xmlSecSize)XMLSEC_MSCNG_DSA_MAX_P_SIZE, NULL);
goto done;
}
xmlSecAssert2(qSize <= pSize, NULL);
xmlSecAssert2(gSize <= pSize, NULL);
xmlSecAssert2(ySize <= pSize, NULL);

Expand Down
Loading
Loading