/
githubmirror
/
xmlsec
Обзор
Документация
Войти
/
githubmirror
/
xmlsec
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/mscng/signatures.c
1 593 строки
51 KB
Javid Khan
return 0 on signature mismatch in nss/mscng/mscrypto verify (#1196)
01 июн 2026, 16:42
Не верифицирован
01 июн 2026, 16:42
74b0049
Код
Авторство
О чём код?
/** * XML Security Library (http://www.aleksey.com/xmlsec). * * This is free software; see the Copyright file in the source distribution for precise wording. * * Copyright (C) 2018-2026 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. * Copyright (C) 2018 Miklos Vajna. All Rights Reserved. */ /** * @addtogroup xmlsec_mscng_crypto * @brief Signatures implementation for MSCng. */ #include "globals.h" #include <string.h> #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> #include <xmlsec/errors.h> #include <xmlsec/mscng/crypto.h> #include <xmlsec/mscng/certkeys.h> #include "../cast_helpers.h" #include "private.h" /****************************************************************************** * * DSA EVP * * https://www.w3.org/TR/xmldsig-core1/#sec-DSA * The output of the DSA algorithm consists of a pair of integers usually referred by the pair (r, s). * DSA-SHA1: Integer to octet-stream conversion must be done according to the I2OSP operation defined * in the RFC 3447 [PKCS1] specification with a l parameter equal to 20 * DSA-SHA256: The pairs (2048, 256) and (3072, 256) correspond to the algorithm DSAwithSHA256 *****************************************************************************/ #define XMLSEC_MSCNG_SIGNATURE_DSA_SHA1_HALF_LEN 20 #define XMLSEC_MSCNG_SIGNATURE_DSA_SHA256_HALF_LEN (256 / 8) /****************************************************************************** * * Internal MSCng signatures ctx * *****************************************************************************/ typedef struct _xmlSecMSCngSignatureCtx xmlSecMSCngSignatureCtx, *xmlSecMSCngSignatureCtxPtr; struct _xmlSecMSCngSignatureCtx { xmlSecKeyDataPtr data; xmlSecKeyDataId keyId; DWORD signatureHalfSize; LPCWSTR pszHashAlgId; DWORD cbHash; PBYTE pbHash; BCRYPT_ALG_HANDLE hHashAlg; PBYTE pbHashObject; BCRYPT_HASH_HANDLE hHash; ULONG dwInfoFlags; ULONG dwRsaPssSaltSize; }; /****************************************************************************** * * Signature transforms * *****************************************************************************/ XMLSEC_TRANSFORM_DECLARE(MSCngSignature, xmlSecMSCngSignatureCtx) #define xmlSecMSCngSignatureSize XMLSEC_TRANSFORM_SIZE(MSCngSignature) static int xmlSecMSCngSignatureCheckId (xmlSecTransformPtr transform); static int xmlSecMSCngSignatureInitialize (xmlSecTransformPtr transform); static void xmlSecMSCngSignatureFinalize (xmlSecTransformPtr transform); static int xmlSecMSCngSignatureSetKeyReq (xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq); static int xmlSecMSCngSignatureSetKey (xmlSecTransformPtr transform, xmlSecKeyPtr key); static int xmlSecMSCngSignatureVerify (xmlSecTransformPtr transform, const xmlSecByte* data, xmlSecSize dataSize, xmlSecTransformCtxPtr transformCtx); static int xmlSecMSCngSignatureExecute (xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx); /* Helper macros to define the transform klass */ #define XMLSEC_MSCNG_SIGNATURE_KLASS_EX(name, readNode) \ static xmlSecTransformKlass xmlSecMSCng ## name ## Klass = { \ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ \ xmlSecMSCngSignatureSize, /* xmlSecSize objSize */ \ xmlSecName ## name, /* const xmlChar* name; */ \ xmlSecHref ## name, /* const xmlChar* href; */ \ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */ \ xmlSecMSCngSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */ \ xmlSecMSCngSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */ \ readNode, /* xmlSecTransformNodeReadMethod readNode; */ \ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ \ xmlSecMSCngSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */ \ xmlSecMSCngSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */ \ xmlSecMSCngSignatureVerify, /* xmlSecTransformVerifyMethod verify; */ \ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ \ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ \ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ \ NULL, /* xmlSecTransformPushXmlMethod pushXml; */ \ NULL, /* xmlSecTransformPopXmlMethod popXml; */ \ xmlSecMSCngSignatureExecute, /* xmlSecTransformExecuteMethod execute; */ \ NULL, /* void* reserved0; */ \ NULL, /* void* reserved1; */ \ }; #define XMLSEC_MSCNG_SIGNATURE_KLASS(name) \ XMLSEC_MSCNG_SIGNATURE_KLASS_EX(name, NULL) static int xmlSecMSCngSignatureCheckId(xmlSecTransformPtr transform) { #ifndef XMLSEC_NO_DSA #ifndef XMLSEC_NO_SHA1 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformDsaSha1Id)) { return(1); } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformDsaSha256Id)) { return(1); } else #endif /* XMLSEC_NO_SHA256 */ #endif /* XMLSEC_NO_DSA */ #ifndef XMLSEC_NO_RSA #ifndef XMLSEC_NO_MD5 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaMd5Id)) { return(1); } else #endif /* XMLSEC_NO_MD5 */ #ifndef XMLSEC_NO_SHA1 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaSha1Id)) { return(1); } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaSha256Id)) { return(1); } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaSha384Id)) { return(1); } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaSha512Id)) { return(1); } else #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA1 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha1Id)) { return(1); } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha256Id)) { return(1); } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha384Id)) { return(1); } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha512Id)) { return(1); } else #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA3 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha3_256Id)) { return(1); } else if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha3_384Id)) { return(1); } else if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha3_512Id)) { return(1); } else #endif /* XMLSEC_NO_SHA3 */ #endif /* XMLSEC_NO_RSA */ #ifndef XMLSEC_NO_EC #ifndef XMLSEC_NO_SHA1 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha1Id)) { return(1); } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha256Id)) { return(1); } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha384Id)) { return(1); } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha512Id)) { return(1); } else #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA3 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha3_256Id)) { return(1); } else if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha3_384Id)) { return(1); } else if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha3_512Id)) { return(1); } else #endif /* XMLSEC_NO_SHA3 */ #endif /* XMLSEC_NO_EC */ /* not found */ return(0); } static int xmlSecMSCngSignatureInitialize(xmlSecTransformPtr transform) { xmlSecMSCngSignatureCtxPtr ctx; xmlSecAssert2(xmlSecMSCngSignatureCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngSignatureSize), -1); ctx = xmlSecMSCngSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); memset(ctx, 0, sizeof(xmlSecMSCngSignatureCtx)); #ifndef XMLSEC_NO_DSA #ifndef XMLSEC_NO_SHA1 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformDsaSha1Id)) { ctx->pszHashAlgId = BCRYPT_SHA1_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataDsaId; ctx->signatureHalfSize = XMLSEC_MSCNG_SIGNATURE_DSA_SHA1_HALF_LEN; } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformDsaSha256Id)) { ctx->pszHashAlgId = BCRYPT_SHA256_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataDsaId; ctx->signatureHalfSize = XMLSEC_MSCNG_SIGNATURE_DSA_SHA256_HALF_LEN; } else #endif /* XMLSEC_NO_SHA256 */ #endif /* XMLSEC_NO_DSA */ #ifndef XMLSEC_NO_RSA #ifndef XMLSEC_NO_MD5 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaMd5Id)) { ctx->pszHashAlgId = BCRYPT_MD5_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PKCS1; } else #endif /* XMLSEC_NO_MD5 */ #ifndef XMLSEC_NO_SHA1 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaSha1Id)) { ctx->pszHashAlgId = BCRYPT_SHA1_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PKCS1; } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaSha256Id)) { ctx->pszHashAlgId = BCRYPT_SHA256_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PKCS1; } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaSha384Id)) { ctx->pszHashAlgId = BCRYPT_SHA384_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PKCS1; } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaSha512Id)) { ctx->pszHashAlgId = BCRYPT_SHA512_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PKCS1; } else #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA1 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha1Id)) { ctx->pszHashAlgId = BCRYPT_SHA1_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PSS; ctx->dwRsaPssSaltSize = 20; /* The default salt length is the length of the hash function. */ } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha256Id)) { ctx->pszHashAlgId = BCRYPT_SHA256_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PSS; ctx->dwRsaPssSaltSize = 32; /* The default salt length is the length of the hash function. */ } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha384Id)) { ctx->pszHashAlgId = BCRYPT_SHA384_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PSS; ctx->dwRsaPssSaltSize = 48; /* The default salt length is the length of the hash function. */ } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha512Id)) { ctx->pszHashAlgId = BCRYPT_SHA512_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PSS; ctx->dwRsaPssSaltSize = 64; /* The default salt length is the length of the hash function. */ } else #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA3 if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha3_256Id)) { ctx->pszHashAlgId = BCRYPT_SHA3_256_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PSS; ctx->dwRsaPssSaltSize = 32; /* The default salt length is the length of the hash function. */ } else if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha3_384Id)) { ctx->pszHashAlgId = BCRYPT_SHA3_384_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PSS; ctx->dwRsaPssSaltSize = 48; /* The default salt length is the length of the hash function. */ } else if (xmlSecTransformCheckId(transform, xmlSecMSCngTransformRsaPssSha3_512Id)) { ctx->pszHashAlgId = BCRYPT_SHA3_512_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataRsaId; ctx->dwInfoFlags = BCRYPT_PAD_PSS; ctx->dwRsaPssSaltSize = 64; /* The default salt length is the length of the hash function. */ } else #endif /* XMLSEC_NO_SHA3 */ #endif /* XMLSEC_NO_RSA */ #ifndef XMLSEC_NO_EC #ifndef XMLSEC_NO_SHA1 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha1Id)) { ctx->pszHashAlgId = BCRYPT_SHA1_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataEcId; } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha256Id)) { ctx->pszHashAlgId = BCRYPT_SHA256_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataEcId; } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha384Id)) { ctx->pszHashAlgId = BCRYPT_SHA384_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataEcId; } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha512Id)) { ctx->pszHashAlgId = BCRYPT_SHA512_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataEcId; } else #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA3 if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha3_256Id)) { ctx->pszHashAlgId = BCRYPT_SHA3_256_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataEcId; } else if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha3_384Id)) { ctx->pszHashAlgId = BCRYPT_SHA3_384_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataEcId; } else if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformEcdsaSha3_512Id)) { ctx->pszHashAlgId = BCRYPT_SHA3_512_ALGORITHM; ctx->keyId = xmlSecMSCngKeyDataEcId; } else #endif /* XMLSEC_NO_SHA3 */ #endif /* XMLSEC_NO_EC */ /* not found */ { xmlSecInvalidTransfromError(transform) return(-1); } return(0); } static void xmlSecMSCngSignatureFinalize(xmlSecTransformPtr transform) { xmlSecMSCngSignatureCtxPtr ctx; xmlSecAssert(xmlSecMSCngSignatureCheckId(transform)); xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecMSCngSignatureSize)); ctx = xmlSecMSCngSignatureGetCtx(transform); xmlSecAssert(ctx != NULL); if(ctx->data != NULL) { xmlSecKeyDataDestroy(ctx->data); } // MSDN documents at // https://msdn.microsoft.com/en-us/library/windows/desktop/aa376217(v=vs.85).aspx // that the order of cleanup should be: // - algo handle // - hash handle // - hash object pointer // - hash pointer if(ctx->hHashAlg != 0) { BCryptCloseAlgorithmProvider(ctx->hHashAlg, 0); } if(ctx->hHash != 0) { BCryptDestroyHash(ctx->hHash); } if(ctx->pbHashObject != NULL) { xmlFree(ctx->pbHashObject); } if(ctx->pbHash != NULL) { xmlFree(ctx->pbHash); } memset(ctx, 0, sizeof(xmlSecMSCngSignatureCtx)); } static int xmlSecMSCngSignatureSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecMSCngSignatureCtxPtr ctx; xmlSecKeyDataPtr value; xmlSecAssert2(xmlSecMSCngSignatureCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngSignatureSize), -1); xmlSecAssert2(key != NULL, -1); ctx = xmlSecMSCngSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->keyId != NULL, -1); xmlSecAssert2(ctx->pszHashAlgId != 0, -1); xmlSecAssert2(xmlSecKeyCheckId(key, ctx->keyId), -1); value = xmlSecKeyGetValue(key); xmlSecAssert2(value != NULL, -1); ctx->data = xmlSecKeyDataDuplicate(value); if(ctx->data == NULL) { xmlSecInternalError("xmlSecKeyDataDuplicate", xmlSecTransformGetName(transform)); return(-1); } return(0); } static int xmlSecMSCngSignatureSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) { xmlSecMSCngSignatureCtxPtr ctx; xmlSecAssert2(xmlSecMSCngSignatureCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngSignatureSize), -1); xmlSecAssert2(keyReq != NULL, -1); ctx = xmlSecMSCngSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->keyId != NULL, -1); keyReq->keyId = ctx->keyId; if(transform->operation == xmlSecTransformOperationSign) { keyReq->keyType = xmlSecKeyDataTypePrivate; keyReq->keyUsage = xmlSecKeyUsageSign; } else { keyReq->keyType = xmlSecKeyDataTypePublic; keyReq->keyUsage = xmlSecKeyUsageVerify; } return(0); } /* * https://www.w3.org/TR/xmldsig-core1/#sec-ECDSA * * The output of the ECDSA algorithm consists of a pair of integers usually * referred by the pair(r, s).The signature value consists of the base64 * encoding of the concatenation of two octet - streams that respectively result * from the octet - encoding of the values r and s in that order.Integer to * octet - stream conversion must be done according to the I2OSP operation defined * in the RFC 3447[PKCS1] specification with the l parameter equal to the size of * the base point order of the curve in bytes(e.g. 32 for the P - 256 curve and 66 * for the P - 521 curve). */ static int xmlSecMSCngSignatureFixBrokenJava(xmlSecMSCngSignatureCtxPtr ctx, const xmlSecByte* data, xmlSecSize dataSize, const xmlSecByte** out, xmlSecSize* outSize ) { xmlSecSize halfSize; xmlSecSize keySize; xmlSecByte* res; xmlSecSize offset; xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->data != NULL, -1); xmlSecAssert2(data != NULL, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(outSize != NULL, -1); if (ctx->keyId == xmlSecMSCngKeyDataDsaId) { halfSize = ctx->signatureHalfSize; } else if (ctx->keyId == xmlSecMSCngKeyDataEcId) { keySize = xmlSecMSCngCertKeyDataGetSize(ctx->data); if (keySize <= 0) { xmlSecInternalError("xmlSecMSCngCertKeyDataGetSize", NULL); return(-1); } halfSize = (keySize + 7) / 8; } else { /* nothing to do: this only applies to DSA and ECDSA signatures */ return(0); } /* check the size: we expect the DSA/ECDSA r and s to be the same size and either have * fixed size (DSA) or match the size of the key (ECDSA) */ if (2 * halfSize == dataSize) { return(0); } if ((dataSize < 2 * halfSize) && (dataSize % 2 == 0)) { /* however some implementations (e.g. Java) cut leading zeros: * https://github.com/lsh123/xmlsec/issues/228 */ /* let's fix it! */ res = (xmlSecByte*)xmlMalloc(2 * halfSize); if (res == NULL) { xmlSecMallocError(2 * halfSize, NULL); return(-1); } memset(res, 0, 2 * halfSize); /* add zeros at the beggining of both r and s */ offset = (2 * halfSize - dataSize) / 2; memcpy(res + offset, data, dataSize / 2); memcpy(res + halfSize + offset, data + dataSize / 2, dataSize / 2); /* success */ (*out) = res; (*outSize) = 2 * halfSize; } else if ((dataSize > 2 * halfSize) && (dataSize % 2 == 0)) { /* however some implementations (e.g. Java) add leading zeros: * https://github.com/lsh123/xmlsec/issues/941 */ /* let's fix it! */ res = (xmlSecByte*)xmlMalloc(2 * halfSize); if (res == NULL) { xmlSecMallocError(2 * halfSize, NULL); return(-1); } memset(res, 0, 2 * halfSize); /* remove zeros at the beggining of both r and s (note: we don't check if those * are actually zeros, just hope for the best) */ offset = (dataSize - 2 * halfSize) / 2; memcpy(res, data + offset, halfSize); memcpy(res + halfSize, data + dataSize / 2 + offset, halfSize); /* success */ (*out) = res; (*outSize) = 2 * halfSize; } else { xmlSecInternalError3("xmlSecMSCngSignatureFixBrokenJava", NULL, "expectedSignLen=" XMLSEC_SIZE_FMT "; actualSignLen=" XMLSEC_SIZE_FMT, 2 * halfSize, dataSize); return(-1); } /* done */ return(0); } static void ConvertEndianInPlace(xmlSecByte* buf, xmlSecSize size) { xmlSecByte* start; xmlSecByte* end; xmlSecAssert(buf != NULL); xmlSecAssert(size > 0); start = buf; end = buf + size - 1; while (start < end) { xmlSecByte tmp = *end; *end = *start; *start = tmp; start++; end--; } } static int xmlSecMSCngSignatureFixBrokenASN1(xmlSecMSCngSignatureCtxPtr ctx, const xmlSecByte* data, xmlSecSize dataSize, const xmlSecByte** out, xmlSecSize* outSize ) { xmlSecSize keySize; xmlSecSize halfSize; PCERT_ECC_SIGNATURE eccSignature = NULL; DWORD eccSignatureLen = 0; DWORD dataLen; BOOL status; xmlSecByte* res; xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->data != NULL, -1); xmlSecAssert2(data != NULL, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(outSize != NULL, -1); /* only ECDSA signatures are supported for ASN1 */ if (ctx->keyId != xmlSecMSCngKeyDataEcId) { xmlSecNotImplementedError("MSCNG only supports ASN1 signature values for ECDSA"); return(-1); } /* get half signature size */ keySize = xmlSecMSCngCertKeyDataGetSize(ctx->data); if (keySize <= 0) { xmlSecInternalError("xmlSecMSCngCertKeyDataGetSize", NULL); return(-1); } halfSize = (keySize + 7) / 8; /* parse asn1 structure */ XMLSEC_SAFE_CAST_SIZE_TO_UINT(dataSize, dataLen, return(-1), NULL); status = CryptDecodeObjectEx( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ECC_SIGNATURE, data, dataLen, CRYPT_DECODE_ALLOC_FLAG, NULL, &eccSignature, &eccSignatureLen ); if ((status != TRUE) || (eccSignature == NULL) || (eccSignatureLen <= 0)) { xmlSecMSCngNtError("CryptDecodeObjectEx", NULL, STATUS_SUCCESS); return(-1); } /* check sizes */ if ((eccSignature->r.cbData <= 0) || (halfSize < eccSignature->r.cbData)) { xmlSecInternalError3("xmlSecMSCngSignatureFixBrokenASN1", NULL, "halfSize=" XMLSEC_SIZE_FMT "; eccSignature->r.cbData=" XMLSEC_SIZE_FMT, halfSize, (xmlSecSize)eccSignature->r.cbData); LocalFree(eccSignature); return(-1); } if ((eccSignature->s.cbData <= 0) || (halfSize < eccSignature->s.cbData)) { xmlSecInternalError3("xmlSecMSCngSignatureFixBrokenASN1", NULL, "halfSize=" XMLSEC_SIZE_FMT "; eccSignature->s.cbData=" XMLSEC_SIZE_FMT, halfSize, (xmlSecSize)eccSignature->s.cbData); LocalFree(eccSignature); return(-1); } /* copy r and s other */ res = (xmlSecByte*)xmlMalloc(2 * halfSize); if (res == NULL) { xmlSecMallocError(2 * halfSize, NULL); LocalFree(eccSignature); return(-1); } memset(res, 0, 2 * halfSize); /* r and s are in little-endian order */ memcpy(res, eccSignature->r.pbData, eccSignature->r.cbData); ConvertEndianInPlace(res, halfSize); memcpy(res + halfSize, eccSignature->s.pbData, eccSignature->s.cbData); ConvertEndianInPlace(res + halfSize, halfSize); /* success */ (*out) = res; (*outSize) = 2 * halfSize; LocalFree(eccSignature); return(0); } static int xmlSecMSCngSignatureVerify(xmlSecTransformPtr transform, const xmlSecByte* data, xmlSecSize dataSize, xmlSecTransformCtxPtr transformCtx ) { xmlSecMSCngSignatureCtxPtr ctx; BCRYPT_KEY_HANDLE pubkey; NTSTATUS status; BCRYPT_PKCS1_PADDING_INFO pkcs1PaddingInfo; BCRYPT_PSS_PADDING_INFO pssPadingInfo; VOID* pPaddingInfo = NULL; xmlSecByte* fixedData = NULL; xmlSecSize fixedDataSize = 0; DWORD dwDataSize; int ret; int res = -1; xmlSecAssert2(xmlSecMSCngSignatureCheckId(transform), -1); xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngSignatureSize), -1); xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1); xmlSecAssert2(data != NULL, -1); xmlSecAssert2(dataSize > 0, -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecMSCngSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); pubkey = xmlSecMSCngKeyDataGetPubKey(ctx->data); if(pubkey == 0) { xmlSecInternalError("xmlSecMSCngKeyDataGetPubKey", xmlSecTransformGetName(transform)); goto done; } /* RSA needs explicit padding, otherwise STATUS_INVALID_PARAMETER is * returned */ if(ctx->dwInfoFlags == BCRYPT_PAD_PKCS1) { pkcs1PaddingInfo.pszAlgId = ctx->pszHashAlgId; pPaddingInfo = &pkcs1PaddingInfo; } else if (ctx->dwInfoFlags == BCRYPT_PAD_PSS) { pssPadingInfo.pszAlgId = ctx->pszHashAlgId; pssPadingInfo.cbSalt = ctx->dwRsaPssSaltSize; pPaddingInfo = &pssPadingInfo; } else if ((transformCtx->flags & XMLSEC_TRANSFORMCTX_FLAGS_SUPPORT_ASN1_SIGNATURE_VALUES) != 0) { /* however some implementations (e.g. Java) just put ASN1 structure in the signature * https://github.com/lsh123/xmlsec/issues/995 */ ret = xmlSecMSCngSignatureFixBrokenASN1(ctx, data, dataSize, (const xmlSecByte**)&fixedData, &fixedDataSize); if (ret < 0) { xmlSecInternalError("xmlSecMSCngSignatureFixBrokenASN1", xmlSecTransformGetName(transform)); goto done; } if ((fixedData != NULL) && (fixedDataSize > 0)) { data = fixedData; dataSize = fixedDataSize; } } else { /* we expect the DSA/ECDSA r and s to be the same size and either have fixed size (DSA) or match * the size of the key (ECDSA); however some implementations (e.g. Java) cut or add leading zeros */ ret = xmlSecMSCngSignatureFixBrokenJava(ctx, data, dataSize, (const xmlSecByte**)&fixedData, &fixedDataSize); if (ret < 0) { xmlSecInternalError("xmlSecMSCngSignatureFixBrokenJava", xmlSecTransformGetName(transform)); goto done; } if ((fixedData != NULL) && (fixedDataSize > 0)) { data = fixedData; dataSize = fixedDataSize; } } XMLSEC_SAFE_CAST_SIZE_TO_ULONG(dataSize, dwDataSize, goto done, xmlSecTransformGetName(transform)); status = BCryptVerifySignature( pubkey, pPaddingInfo, ctx->pbHash, ctx->cbHash, (PBYTE)((fixedData != NULL) ? fixedData : data), dwDataSize, ctx->dwInfoFlags); if(status != STATUS_SUCCESS) { if(status == STATUS_INVALID_SIGNATURE) { xmlSecOtherError(XMLSEC_ERRORS_R_DATA_NOT_MATCH, xmlSecTransformGetName(transform), "BCryptVerifySignature: the signature was not verified"); transform->status = xmlSecTransformStatusFail; res = 0; goto done; } else { xmlSecMSCngNtError("BCryptVerifySignature", xmlSecTransformGetName(transform), status); goto done; } } /* success */ transform->status = xmlSecTransformStatusOk; res = 0; done: if (fixedData != NULL) { xmlFree(fixedData); } return(res); } static int xmlSecMSCngSignatureConvertToASN1(xmlSecMSCngSignatureCtxPtr ctx, xmlSecBufferPtr buf) { xmlSecByte* data; xmlSecSize dataSize, halfSize; CERT_ECC_SIGNATURE eccSignature; xmlSecByte* encodedData = NULL; DWORD encodedDataSize = 0; BOOL status; int ret; xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(buf != NULL, -1); /* only ECDSA signatures are supported for ASN1 */ if (ctx->keyId != xmlSecMSCngKeyDataEcId) { xmlSecNotImplementedError("MSCNG only supports ASN1 signature values for ECDSA"); return(-1); } /* MSCng expect little-endian */ data = xmlSecBufferGetData(buf); dataSize = xmlSecBufferGetSize(buf); halfSize = dataSize / 2; xmlSecAssert2(data != NULL, -1); xmlSecAssert2(dataSize > 0, -1); xmlSecAssert2((dataSize % 2) == 0, -1); ConvertEndianInPlace(data, halfSize); ConvertEndianInPlace(data + halfSize, halfSize); /* encode */ eccSignature.r.cbData = (DWORD)halfSize; eccSignature.r.pbData = data; eccSignature.s.cbData = (DWORD)halfSize; eccSignature.s.pbData = data + halfSize; status = CryptEncodeObjectEx( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ECC_SIGNATURE, &eccSignature, CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedData, &encodedDataSize ); if ((status != TRUE) || (encodedData == NULL) || (encodedDataSize <= 0)) { xmlSecMSCngNtError("CryptEncodeObjectEx", NULL, STATUS_SUCCESS); return(-1); } ret = xmlSecBufferSetData(buf, encodedData, encodedDataSize); if (ret < 0) { xmlSecInternalError("xmlSecBufferSetData", NULL); LocalFree(encodedData); return(-1); } /* done */ LocalFree(encodedData); return(0); } static int xmlSecMSCngSignatureSign( xmlSecTransformPtr transform, xmlSecMSCngSignatureCtxPtr ctx, xmlSecTransformCtxPtr transformCtx ) { NCRYPT_KEY_HANDLE privkey; BCRYPT_PKCS1_PADDING_INFO pkcs1PaddingInfo; BCRYPT_PSS_PADDING_INFO pssPadingInfo; VOID* pPaddingInfo = NULL; DWORD cbSignature; NTSTATUS status; xmlSecSize outSize; int ret; xmlSecAssert2(transform != NULL, -1); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); outSize = xmlSecBufferGetSize(&transform->outBuf); xmlSecAssert2(outSize == 0, -1); privkey = xmlSecMSCngKeyDataGetPrivKey(ctx->data); if (privkey == 0) { xmlSecInternalError("xmlSecMSCngKeyDataGetPrivKey", xmlSecTransformGetName(transform)); return(-1); } /* calculate the length of the signature */ status = NCryptSignHash( privkey, NULL, ctx->pbHash, ctx->cbHash, NULL, 0, &cbSignature, 0); if (status != STATUS_SUCCESS) { xmlSecMSCngNtError("NCryptSignHash", xmlSecTransformGetName(transform), status); return(-1); } XMLSEC_SAFE_CAST_ULONG_TO_SIZE(cbSignature, outSize, return(-1), xmlSecTransformGetName(transform)); /* allocate the signature buffer on the heap */ ret = xmlSecBufferSetSize(&(transform->outBuf), outSize); if (ret < 0) { xmlSecInternalError2("xmlSecBufferSetSize", xmlSecTransformGetName(transform), "size=" XMLSEC_SIZE_FMT, outSize); return(-1); } /* RSA needs explicit padding, otherwise STATUS_INVALID_PARAMETER is * returned */ if (ctx->dwInfoFlags == BCRYPT_PAD_PKCS1) { pkcs1PaddingInfo.pszAlgId = ctx->pszHashAlgId; pPaddingInfo = &pkcs1PaddingInfo; } else if (ctx->dwInfoFlags == BCRYPT_PAD_PSS) { pssPadingInfo.pszAlgId = ctx->pszHashAlgId; pssPadingInfo.cbSalt = ctx->dwRsaPssSaltSize; pPaddingInfo = &pssPadingInfo; } /* sign the hash */ status = NCryptSignHash( privkey, pPaddingInfo, ctx->pbHash, ctx->cbHash, (PBYTE)xmlSecBufferGetData(&(transform->outBuf)), cbSignature, &cbSignature, ctx->dwInfoFlags); if (status != STATUS_SUCCESS) { xmlSecMSCngNtError("NCryptSignHash", xmlSecTransformGetName(transform), status); return(-1); } if ((transformCtx->flags & XMLSEC_TRANSFORMCTX_FLAGS_SUPPORT_ASN1_SIGNATURE_VALUES) != 0) { /* however some implementations (e.g. Java) just put ASN1 structure in the signature * https://github.com/lsh123/xmlsec/issues/995 */ ret = xmlSecMSCngSignatureConvertToASN1(ctx, &(transform->outBuf)); if (ret < 0) { xmlSecInternalError("xmlSecMSCngSignatureConvertToASN1", xmlSecTransformGetName(transform)); return(-1); } } /* done */ return(0); } static int xmlSecMSCngSignatureStartHash( xmlSecTransformPtr transform, xmlSecMSCngSignatureCtxPtr ctx) { NTSTATUS status; DWORD cbData = 0; DWORD cbHashObject = 0; xmlSecAssert2(transform != NULL, -1); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pszHashAlgId != NULL, -1); /* open an algorithm handle */ status = BCryptOpenAlgorithmProvider( &ctx->hHashAlg, ctx->pszHashAlgId, NULL, 0); if (status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptOpenAlgorithmProvider", xmlSecTransformGetName(transform), status); return(-1); } /* calculate the size of the buffer to hold the hash object */ status = BCryptGetProperty( ctx->hHashAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), &cbData, 0); if (status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptGetProperty", xmlSecTransformGetName(transform), status); return(-1); } /* allocate the hash object on the heap */ ctx->pbHashObject = (PBYTE)xmlMalloc(cbHashObject); if (ctx->pbHashObject == NULL) { xmlSecMallocError(cbHashObject, NULL); return(-1); } /* calculate the length of the hash */ status = BCryptGetProperty( ctx->hHashAlg, BCRYPT_HASH_LENGTH, (PBYTE)&ctx->cbHash, sizeof(DWORD), &cbData, 0); if (status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptGetProperty", xmlSecTransformGetName(transform), status); return(-1); } /* allocate the hash buffer on the heap */ ctx->pbHash = (PBYTE)xmlMalloc(ctx->cbHash); if (ctx->pbHash == NULL) { xmlSecMallocError(ctx->cbHash, NULL); return(-1); } /* create the hash */ status = BCryptCreateHash( ctx->hHashAlg, &ctx->hHash, ctx->pbHashObject, cbHashObject, NULL, 0, 0); if (status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptCreateHash", xmlSecTransformGetName(transform), status); return(-1); } /* done */ return (0); } static int xmlSecMSCngSignatureUpdateHash( xmlSecTransformPtr transform, xmlSecMSCngSignatureCtxPtr ctx) { xmlSecByte* inData; xmlSecSize inSize; DWORD dwInSize; NTSTATUS status; int ret; xmlSecAssert2(transform != NULL, -1); xmlSecAssert2(ctx != NULL, -1); inData = xmlSecBufferGetData(&transform->inBuf); inSize = xmlSecBufferGetSize(&transform->inBuf); if ((inData == NULL) || (inSize <= 0)) { /* nothing to do */ return(0); } /* hash some data */ XMLSEC_SAFE_CAST_SIZE_TO_ULONG(inSize, dwInSize, return(-1), xmlSecTransformGetName(transform)); status = BCryptHashData( ctx->hHash, (PBYTE)inData, dwInSize, 0); if (status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptHashData", xmlSecTransformGetName(transform), status); return(-1); } /* remove processed data */ ret = xmlSecBufferRemoveHead(&transform->inBuf, inSize); if (ret < 0) { xmlSecInternalError("xmlSecBufferRemoveHead", xmlSecTransformGetName(transform)); return(-1); } /* done */ return(0); } static int xmlSecMSCngSignatureFinishHash( xmlSecTransformPtr transform, xmlSecMSCngSignatureCtxPtr ctx) { NTSTATUS status; xmlSecAssert2(transform != NULL, -1); xmlSecAssert2(ctx != NULL, -1); status = BCryptFinishHash( ctx->hHash, ctx->pbHash, ctx->cbHash, 0); if (status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptFinishHash", xmlSecTransformGetName(transform), status); return(-1); } xmlSecAssert2(ctx->cbHash > 0, -1); return(0); } static int xmlSecMSCngSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecMSCngSignatureCtxPtr ctx; int ret; xmlSecAssert2(xmlSecMSCngSignatureCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngSignatureSize), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecMSCngSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); if(transform->status == xmlSecTransformStatusNone) { /* start hash */ ret = xmlSecMSCngSignatureStartHash(transform, ctx); if (ret < 0) { xmlSecInternalError("xmlSecMSCngSignatureStartHash", xmlSecTransformGetName(transform)); return(-1); } transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { /* update hash (if we have data) */ ret = xmlSecMSCngSignatureUpdateHash(transform, ctx); if (ret < 0) { xmlSecInternalError("xmlSecMSCngSignatureUpdateHash", xmlSecTransformGetName(transform)); return(-1); } if(last != 0) { /* finish the hash */ ret = xmlSecMSCngSignatureFinishHash(transform, ctx); if (ret < 0) { xmlSecInternalError("xmlSecMSCngSignatureFinishHash", xmlSecTransformGetName(transform)); return(-1); } /* create signature if needed */ if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecMSCngSignatureSign(transform, ctx, transformCtx); if (ret < 0) { xmlSecInternalError("xmlSecMSCngSignatureSign", xmlSecTransformGetName(transform)); return(-1); } } /* done */ transform->status = xmlSecTransformStatusFinished; } } /* check state */ if((transform->status == xmlSecTransformStatusWorking) || (transform->status == xmlSecTransformStatusFinished)) { xmlSecAssert2(xmlSecBufferGetSize(&transform->inBuf) == 0, -1); } else { xmlSecInvalidTransfromStatusError(transform); return(-1); } /* done */ return(0); } #ifndef XMLSEC_NO_DSA #ifndef XMLSEC_NO_SHA1 /****************************************************************************** * * DSA-SHA1 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(DsaSha1) /** * @brief The DSA-SHA1 signature transform klass. * @return DSA-SHA1 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformDsaSha1GetKlass(void) { return(&xmlSecMSCngDsaSha1Klass); } #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 /****************************************************************************** * * DSA-SHA2-256 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(DsaSha256) /** * @brief The DSA-SHA2-256 signature transform klass. * @return DSA-SHA2-256 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformDsaSha256GetKlass(void) { return(&xmlSecMSCngDsaSha256Klass); } #endif /* XMLSEC_NO_SHA256 */ #endif /* XMLSEC_NO_DSA */ #ifndef XMLSEC_NO_RSA #ifndef XMLSEC_NO_MD5 /****************************************************************************** * * RSA-MD5 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaMd5) /** * @brief The RSA-MD5 signature transform klass. * @return RSA-MD5 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaMd5GetKlass(void) { return(&xmlSecMSCngRsaMd5Klass); } #endif /* XMLSEC_NO_MD5 */ #ifndef XMLSEC_NO_SHA1 /****************************************************************************** * * RSA-SHA1 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaSha1) /** * @brief The RSA-SHA1 signature transform klass. * @return RSA-SHA1 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaSha1GetKlass(void) { return(&xmlSecMSCngRsaSha1Klass); } #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 /****************************************************************************** * * RSA-SHA2-256 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaSha256) /** * @brief The RSA-SHA2-256 signature transform klass. * @return RSA-SHA2-256 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaSha256GetKlass(void) { return(&xmlSecMSCngRsaSha256Klass); } #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 /****************************************************************************** * * RSA-SHA2-384 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaSha384) /** * @brief The RSA-SHA2-384 signature transform klass. * @return RSA-SHA2-384 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaSha384GetKlass(void) { return(&xmlSecMSCngRsaSha384Klass); } #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 /****************************************************************************** * * RSA-SHA2-512 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaSha512) /** * @brief The RSA-SHA2-512 signature transform klass. * @return RSA-SHA2-512 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaSha512GetKlass(void) { return(&xmlSecMSCngRsaSha512Klass); } #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA1 /****************************************************************************** * * RSA-PSS-SHA1 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaPssSha1) /** * @brief The RSA-PSS-SHA1 signature transform klass. * @return RSA-PSS-SHA1 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaPssSha1GetKlass(void) { return(&xmlSecMSCngRsaPssSha1Klass); } #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 /****************************************************************************** * * RSA-PSS-SHA2-256 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaPssSha256) /** * @brief The RSA-PSS-SHA2-256 signature transform klass. * @return RSA-PSS-SHA2-256 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaPssSha256GetKlass(void) { return(&xmlSecMSCngRsaPssSha256Klass); } #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 /****************************************************************************** * * RSA-PSS-SHA2-384 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaPssSha384) /** * @brief The RSA-PSS-SHA2-384 signature transform klass. * @return RSA-PSS-SHA2-384 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaPssSha384GetKlass(void) { return(&xmlSecMSCngRsaPssSha384Klass); } #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 /****************************************************************************** * * RSA-PSS-SHA2-512 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaPssSha512) /** * @brief The RSA-PSS-SHA2-512 signature transform klass. * @return RSA-PSS-SHA2-512 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaPssSha512GetKlass(void) { return(&xmlSecMSCngRsaPssSha512Klass); } #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA3 /****************************************************************************** * * RSA-PSS-SHA3-256 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaPssSha3_256) /** * @brief The RSA-PSS-SHA3-256 signature transform klass. * @return RSA-PSS-SHA3-256 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaPssSha3_256GetKlass(void) { return(&xmlSecMSCngRsaPssSha3_256Klass); } /****************************************************************************** * * RSA-PSS-SHA3-384 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaPssSha3_384) /** * @brief The RSA-PSS-SHA3-384 signature transform klass. * @return RSA-PSS-SHA3-384 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaPssSha3_384GetKlass(void) { return(&xmlSecMSCngRsaPssSha3_384Klass); } /****************************************************************************** * * RSA-PSS-SHA3-512 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(RsaPssSha3_512) /** * @brief The RSA-PSS-SHA3-512 signature transform klass. * @return RSA-PSS-SHA3-512 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformRsaPssSha3_512GetKlass(void) { return(&xmlSecMSCngRsaPssSha3_512Klass); } #endif /* XMLSEC_NO_SHA3 */ #endif /* XMLSEC_NO_RSA */ #ifndef XMLSEC_NO_EC #ifndef XMLSEC_NO_SHA1 /****************************************************************************** * * ECDSA-SHA1 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(EcdsaSha1) /** * @brief The ECDSA-SHA1 signature transform klass. * @return ECDSA-SHA1 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformEcdsaSha1GetKlass(void) { return(&xmlSecMSCngEcdsaSha1Klass); } #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA256 /****************************************************************************** * * ECDSA-SHA2-256 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(EcdsaSha256) /** * @brief The ECDSA-SHA2-256 signature transform klass. * @return ECDSA-SHA2-256 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformEcdsaSha256GetKlass(void) { return(&xmlSecMSCngEcdsaSha256Klass); } #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 /****************************************************************************** * * ECDSA-SHA2-384 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(EcdsaSha384) /** * @brief The ECDSA-SHA2-384 signature transform klass. * @return ECDSA-SHA2-384 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformEcdsaSha384GetKlass(void) { return(&xmlSecMSCngEcdsaSha384Klass); } #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 /****************************************************************************** * * ECDSA-SHA2-512 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(EcdsaSha512) /** * @brief The ECDSA-SHA2-512 signature transform klass. * @return ECDSA-SHA2-512 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformEcdsaSha512GetKlass(void) { return(&xmlSecMSCngEcdsaSha512Klass); } #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_SHA3 /****************************************************************************** * * ECDSA-SHA3-256 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(EcdsaSha3_256) /** * @brief The ECDSA-SHA3-256 signature transform klass. * @return ECDSA-SHA3-256 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformEcdsaSha3_256GetKlass(void) { return(&xmlSecMSCngEcdsaSha3_256Klass); } /****************************************************************************** * * ECDSA-SHA3-384 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(EcdsaSha3_384) /** * @brief The ECDSA-SHA3-384 signature transform klass. * @return ECDSA-SHA3-384 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformEcdsaSha3_384GetKlass(void) { return(&xmlSecMSCngEcdsaSha3_384Klass); } /****************************************************************************** * * ECDSA-SHA3-512 signature transform * *****************************************************************************/ XMLSEC_MSCNG_SIGNATURE_KLASS(EcdsaSha3_512) /** * @brief The ECDSA-SHA3-512 signature transform klass. * @return ECDSA-SHA3-512 signature transform klass. */ xmlSecTransformId xmlSecMSCngTransformEcdsaSha3_512GetKlass(void) { return(&xmlSecMSCngEcdsaSha3_512Klass); } #endif /* XMLSEC_NO_SHA3 */ #endif /* XMLSEC_NO_EC */