summaryrefslogtreecommitdiff
path: root/src/mscrypto/signatures.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscrypto/signatures.c')
-rw-r--r--src/mscrypto/signatures.c317
1 files changed, 227 insertions, 90 deletions
diff --git a/src/mscrypto/signatures.c b/src/mscrypto/signatures.c
index 1806dd22..424804eb 100644
--- a/src/mscrypto/signatures.c
+++ b/src/mscrypto/signatures.c
@@ -1,5 +1,6 @@
-/**
- * XMLSec library
+/*
+ * XML Security Library (http://www.aleksey.com/xmlsec).
+ *
*
* This is free software; see Copyright file in the source
* distribution for preciese wording.
@@ -8,6 +9,13 @@
* Copyright (C) 2003-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
* Copyright (c) 2005-2006 Cryptocom LTD (http://www.cryptocom.ru).
*/
+/**
+ * SECTION:signatures
+ * @Short_description: Signatures implementation for Microsoft Crypto API.
+ * @Stability: Private
+ *
+ */
+
#include "globals.h"
#include <string.h>
@@ -121,13 +129,20 @@ static int xmlSecMSCryptoSignatureCheckId(xmlSecTransformPtr transform) {
} else
#endif /* XMLSEC_NO_GOST*/
+#ifndef XMLSEC_NO_GOST2012
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2012_256Id)) {
+ return(1);
+ } else
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2012_512Id)) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_GOST2012*/
+
/* not found */
{
return(0);
}
-
- return(0);
}
static int xmlSecMSCryptoSignatureInitialize(xmlSecTransformPtr transform) {
@@ -195,13 +210,20 @@ static int xmlSecMSCryptoSignatureInitialize(xmlSecTransformPtr transform) {
} else
#endif /* XMLSEC_NO_GOST*/
+#ifndef XMLSEC_NO_GOST2012
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2012_256Id)) {
+ ctx->digestAlgId = CALG_GR3411_2012_256;
+ ctx->keyId = xmlSecMSCryptoKeyDataGost2012_256Id;
+ } else
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2012_512Id)) {
+ ctx->digestAlgId = CALG_GR3411_2012_512;
+ ctx->keyId = xmlSecMSCryptoKeyDataGost2012_512Id;
+ } else
+#endif /* XMLSEC_NO_GOST2012*/
+
/* not found */
{
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_TRANSFORM,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecInvalidTransfromError(transform)
return(-1);
}
@@ -249,11 +271,8 @@ static int xmlSecMSCryptoSignatureSetKey(xmlSecTransformPtr transform, xmlSecKey
ctx->data = xmlSecKeyDataDuplicate(value);
if(ctx->data == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecKeyDataDuplicate",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecInternalError("xmlSecKeyDataDuplicate",
+ xmlSecTransformGetName(transform));
return(-1);
}
@@ -307,11 +326,9 @@ static int xmlSecMSCryptoSignatureVerify(xmlSecTransformPtr transform,
ret = xmlSecBufferInitialize(&tmp, dataSize);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferInitialize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "dataSize=%d", dataSize);
+ xmlSecInternalError2("xmlSecBufferInitialize",
+ xmlSecTransformGetName(transform),
+ "dataSize=%d", dataSize);
return(-1);
}
@@ -367,23 +384,23 @@ static int xmlSecMSCryptoSignatureVerify(xmlSecTransformPtr transform,
} else
#endif /* XMLSEC_NO_GOST*/
+#ifndef XMLSEC_NO_GOST2012
+ if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2012_256Id) ||
+ xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2012_512Id)) {
+ ConvertEndian(data, tmpBuf, dataSize);
+ } else
+#endif /* XMLSEC_NO_GOST2012*/
+
{
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "Invalid algo");
+ xmlSecInvalidTypeError("Invalid signature algorithm", xmlSecTransformGetName(transform));
xmlSecBufferFinalize(&tmp);
return(-1);
}
hKey = xmlSecMSCryptoKeyDataGetKey(ctx->data, xmlSecKeyDataTypePublic);
if (hKey == 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecMSCryptoKeyDataGetKey",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecInternalError("xmlSecMSCryptoKeyDataGetKey",
+ xmlSecTransformGetName(transform));
xmlSecBufferFinalize(&tmp);
return(-1);
}
@@ -395,20 +412,15 @@ static int xmlSecMSCryptoSignatureVerify(xmlSecTransformPtr transform,
0)) {
dwError = GetLastError();
if (NTE_BAD_SIGNATURE == dwError) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "CryptVerifySignature",
- XMLSEC_ERRORS_R_DATA_NOT_MATCH,
- "signature do not match");
+ xmlSecOtherError(XMLSEC_ERRORS_R_DATA_NOT_MATCH,
+ xmlSecTransformGetName(transform),
+ "CryptVerifySignature: signature does not verify");
transform->status = xmlSecTransformStatusFail;
xmlSecBufferFinalize(&tmp);
return(0);
} else {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "CryptVerifySignature",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecMSCryptoError("CryptVerifySignature",
+ xmlSecTransformGetName(transform));
xmlSecBufferFinalize(&tmp);
return (-1);
}
@@ -430,6 +442,8 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
int ret;
DWORD dwSigLen;
BYTE *tmpBuf, *outBuf;
+ int bOk;
+ PCRYPT_KEY_PROV_INFO pProviderInfo = NULL;
xmlSecAssert2(xmlSecMSCryptoSignatureCheckId(transform), -1);
xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
@@ -452,20 +466,68 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
xmlSecAssert2(outSize == 0, -1);
if (0 == (hProv = xmlSecMSCryptoKeyDataGetMSCryptoProvider(ctx->data))) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecMSCryptoKeyDataGetMSCryptoProvider",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecMSCryptoError("xmlSecMSCryptoKeyDataGetMSCryptoProvider",
+ xmlSecTransformGetName(transform));
return (-1);
}
- if (!CryptCreateHash(hProv, ctx->digestAlgId, 0, 0, &(ctx->mscHash))) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptCreateHash",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ //First try create hash with provider acquired in function xmlSecMSCryptoKeyDataAdoptCert.
+ bOk = CryptCreateHash(hProv, ctx->digestAlgId, 0, 0, &(ctx->mscHash));
+
+ //Then try it with container name, provider name and type acquired from certificate context.
+ if(!bOk) {
+ pProviderInfo = xmlSecMSCryptoKeyDataGetMSCryptoProviderInfo(ctx->data);
+
+ if(pProviderInfo == NULL) {
+ xmlSecInternalError("xmlSecMSCryptoKeyDataGetMSCryptoProviderInfo", NULL);
+ return(-1);
+ }
+
+ if(!CryptReleaseContext(hProv, 0)) {
+ xmlSecMSCryptoError("CryptReleaseContext", NULL);
+ return(-1);
+ }
+ hProv = (HCRYPTPROV)0;
+
+ if(!CryptAcquireContextW(&hProv,
+ pProviderInfo->pwszContainerName,
+ pProviderInfo->pwszProvName,
+ pProviderInfo->dwProvType,
+ 0)) {
+
+ xmlSecMSCryptoError("CryptAcquireContext", NULL);
+ return(-1);
+ }
+
+ bOk = CryptCreateHash(hProv, ctx->digestAlgId, 0, 0, &(ctx->mscHash));
+ }
+
+ //Last try it with PROV_RSA_AES provider type.
+ if(!bOk) {
+ if (!CryptReleaseContext(hProv, 0)) {
+ xmlSecMSCryptoError("CryptReleaseContext", NULL);
+ return(-1);
+ }
+ hProv = (HCRYPTPROV)0;
+
+ if(!CryptAcquireContextW(&hProv,
+ pProviderInfo->pwszContainerName,
+ NULL,
+ PROV_RSA_AES,
+ 0)) {
+ xmlSecMSCryptoError("CryptAcquireContext", NULL);
+ return(-1);
+ }
+
+ bOk = CryptCreateHash(hProv, ctx->digestAlgId, 0, 0, &(ctx->mscHash));
+ }
+
+ if(pProviderInfo != NULL) {
+ free(pProviderInfo);
+ }
+
+ if(!bOk) {
+ xmlSecMSCryptoError("CryptCreateHash", NULL);
return(-1);
}
@@ -476,21 +538,14 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
xmlSecAssert2(outSize == 0, -1);
if (!CryptHashData(ctx->mscHash, xmlSecBufferGetData(in), inSize, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptHashData",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecMSCryptoError("CryptHashData", NULL);
return(-1);
}
ret = xmlSecBufferRemoveHead(in, inSize);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferRemoveHead",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecInternalError("xmlSecBufferRemoveHead",
+ xmlSecTransformGetName(transform));
return(-1);
}
}
@@ -503,33 +558,23 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
if(transform->operation == xmlSecTransformOperationSign) {
dwKeySpec = xmlSecMSCryptoKeyDataGetMSCryptoKeySpec(ctx->data);
if (!CryptSignHash(ctx->mscHash, dwKeySpec, NULL, 0, NULL, &dwSigLen)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptSignHash",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecMSCryptoError("CryptSignHash", NULL);
return(-1);
}
outSize = (xmlSecSize)dwSigLen;
ret = xmlSecBufferInitialize(&tmp, outSize);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferSetMaxSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", outSize);
+ xmlSecInternalError2("xmlSecBufferSetMaxSize",
+ xmlSecTransformGetName(transform),
+ "size=%d", outSize);
return(-1);
}
tmpBuf = xmlSecBufferGetData(&tmp);
xmlSecAssert2(tmpBuf != NULL, -1);
if (!CryptSignHash(ctx->mscHash, dwKeySpec, NULL, 0, tmpBuf, &dwSigLen)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptSignHash",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecMSCryptoError("CryptSignHash", NULL);
xmlSecBufferFinalize(&tmp);
return(-1);
}
@@ -537,11 +582,9 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
ret = xmlSecBufferSetSize(out, outSize);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferSetSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", outSize);
+ xmlSecInternalError2("xmlSecBufferSetSize",
+ xmlSecTransformGetName(transform),
+ "size=%d", outSize);
xmlSecBufferFinalize(&tmp);
return(-1);
}
@@ -597,13 +640,16 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
} else
#endif /* XMLSEC_NO_GOST*/
+#ifndef XMLSEC_NO_GOST2012
+ if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2012_256Id) ||
+ xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2012_512Id)) {
+ ConvertEndian(tmpBuf, outBuf, outSize);
+ } else
+#endif /* XMLSEC_NO_GOST2012*/
+
{
/* We shouldn't get at this place */
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "Invalid algo");
+ xmlSecInvalidTypeError("Invalid signature algorithm", xmlSecTransformGetName(transform));
xmlSecBufferFinalize(&tmp);
return(-1);
}
@@ -616,11 +662,7 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
/* the only way we can get here is if there is no input */
xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
} else {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_STATUS,
- "status=%d", transform->status);
+ xmlSecInvalidTransfromStatusError(transform);
return(-1);
}
@@ -958,3 +1000,98 @@ xmlSecMSCryptoTransformGost2001GostR3411_94GetKlass(void) {
#endif /* XMLSEC_NO_GOST*/
+
+#ifndef XMLSEC_NO_GOST2012
+
+/****************************************************************************
+ *
+ * GOST R 34.10-2012 256 signature transform
+ *
+ ***************************************************************************/
+
+static xmlSecTransformKlass xmlSecMSCryptoGost2012_256Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecMSCryptoSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameGostR3410_2012GostR3411_2012_256, /* const xmlChar* name; */
+ xmlSecHrefGostR3410_2012GostR3411_2012_256, /* const xmlChar* href; */
+ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
+
+ xmlSecMSCryptoSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecMSCryptoSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecMSCryptoSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ xmlSecMSCryptoSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecMSCryptoSignatureVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoSignatureExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecMSCryptoTransformGost2012GostR3411_94GetKlass:
+ *
+ * The GOST R 34.10-2012 signature transform klass.
+ *
+ * Returns: GOST2001-GOST R 34.10-2012 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecMSCryptoTransformGost2012_256GetKlass(void) {
+ return(&xmlSecMSCryptoGost2012_256Klass);
+}
+
+/****************************************************************************
+ *
+ * GOST R 34.10-2012 512 signature transform
+ *
+ ***************************************************************************/
+
+static xmlSecTransformKlass xmlSecMSCryptoGost2012_512Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecMSCryptoSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameGostR3410_2012GostR3411_2012_512, /* const xmlChar* name; */
+ xmlSecHrefGostR3410_2012GostR3411_2012_512, /* const xmlChar* href; */
+ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
+
+ xmlSecMSCryptoSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecMSCryptoSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecMSCryptoSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ xmlSecMSCryptoSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecMSCryptoSignatureVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoSignatureExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecMSCryptoTransformGost2012GostR3411_94GetKlass:
+ *
+ * The GOST R 34.10-2012 signature transform klass.
+ *
+ * Returns: GOST2001-GOST R 34.10-2012 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecMSCryptoTransformGost2012_512GetKlass(void) {
+ return(&xmlSecMSCryptoGost2012_512Klass);
+}
+
+#endif /* XMLSEC_NO_GOST2012*/
+