summaryrefslogtreecommitdiff
path: root/src/mscrypto/ciphers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscrypto/ciphers.c')
-rw-r--r--src/mscrypto/ciphers.c1507
1 files changed, 547 insertions, 960 deletions
diff --git a/src/mscrypto/ciphers.c b/src/mscrypto/ciphers.c
index 59161639..ea2edcd5 100644
--- a/src/mscrypto/ciphers.c
+++ b/src/mscrypto/ciphers.c
@@ -1,10 +1,10 @@
-/**
+/**
* XMLSec library
*
* This is free software; see Copyright file in the source
* distribution for preciese wording.
- *
- * Copyrigth (C) 2003 Cordys R&D BV, All rights reserved.
+ *
+ * Copyright (C) 2003 Cordys R&D BV, All rights reserved.
* Copyright (C) 2003 Aleksey Sanin <aleksey@aleksey.com>
*/
#include "globals.h"
@@ -21,65 +21,49 @@
#include <xmlsec/mscrypto/crypto.h>
-#if defined(__MINGW32__)
-# include "xmlsec-mingw.h"
-#endif
+#include "private.h"
-#ifndef MS_ENH_RSA_AES_PROV_PROTO
-#define MS_ENH_RSA_AES_PROV_PROTO "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
-#endif /* MS_ENH_RSA_AES_PROV_PROTO */
-
-static BOOL xmlSecMSCryptoCreatePrivateExponentOneKey (HCRYPTPROV hProv,
- HCRYPTKEY *hPrivateKey);
-static BOOL xmlSecMSCryptoImportPlainSessionBlob (HCRYPTPROV hProv,
- HCRYPTKEY hPrivateKey,
- ALG_ID dwAlgId,
- LPBYTE pbKeyMaterial,
- DWORD dwKeyMaterial,
- HCRYPTKEY *hSessionKey);
/**************************************************************************
*
* Internal MSCrypto Block cipher CTX
*
*****************************************************************************/
-typedef struct _xmlSecMSCryptoBlockCipherCtx xmlSecMSCryptoBlockCipherCtx,
- *xmlSecMSCryptoBlockCipherCtxPtr;
+typedef struct _xmlSecMSCryptoBlockCipherCtx xmlSecMSCryptoBlockCipherCtx,
+ *xmlSecMSCryptoBlockCipherCtxPtr;
struct _xmlSecMSCryptoBlockCipherCtx {
- ALG_ID algorithmIdentifier;
- int mode;
- HCRYPTPROV cryptProvider;
- HCRYPTKEY cryptKey;
- HCRYPTKEY pubPrivKey;
- xmlSecKeyDataId keyId;
- LPCTSTR providerName;
- int providerType;
- int keyInitialized;
- int ctxInitialized;
- xmlSecSize keySize;
+ ALG_ID algorithmIdentifier;
+ const xmlSecMSCryptoProviderInfo * providers;
+ xmlSecKeyDataId keyId;
+ xmlSecSize keySize;
+
+ HCRYPTPROV cryptProvider;
+ HCRYPTKEY pubPrivKey;
+ HCRYPTKEY cryptKey;
+ int ctxInitialized;
};
/* function declarations */
-static int xmlSecMSCryptoBlockCipherCtxUpdate (xmlSecMSCryptoBlockCipherCtxPtr ctx,
- xmlSecBufferPtr in,
- xmlSecBufferPtr out,
- int encrypt,
- const xmlChar* cipherName,
- xmlSecTransformCtxPtr transformCtx);
+static int xmlSecMSCryptoBlockCipherCtxUpdate (xmlSecMSCryptoBlockCipherCtxPtr ctx,
+ xmlSecBufferPtr in,
+ xmlSecBufferPtr out,
+ int encrypt,
+ const xmlChar* cipherName,
+ xmlSecTransformCtxPtr transformCtx);
-static int
+static int
xmlSecMSCryptoBlockCipherCtxInit(xmlSecMSCryptoBlockCipherCtxPtr ctx,
- xmlSecBufferPtr in,
- xmlSecBufferPtr out,
- int encrypt,
- const xmlChar* cipherName,
- xmlSecTransformCtxPtr transformCtx) {
+ xmlSecBufferPtr in,
+ xmlSecBufferPtr out,
+ int encrypt,
+ const xmlChar* cipherName,
+ xmlSecTransformCtxPtr transformCtx) {
int blockLen;
int ret;
DWORD dwBlockLen, dwBlockLenLen;
xmlSecAssert2(ctx != NULL, -1);
- xmlSecAssert2(ctx->keyInitialized != 0, -1);
+ xmlSecAssert2(ctx->cryptKey != 0, -1);
xmlSecAssert2(ctx->ctxInitialized == 0, -1);
xmlSecAssert2(in != NULL, -1);
xmlSecAssert2(out != NULL, -1);
@@ -88,92 +72,92 @@ xmlSecMSCryptoBlockCipherCtxInit(xmlSecMSCryptoBlockCipherCtxPtr ctx,
/* iv len == block len */
dwBlockLenLen = sizeof(DWORD);
if (!CryptGetKeyParam(ctx->cryptKey, KP_BLOCKLEN, (BYTE *)&dwBlockLen, &dwBlockLenLen, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptGetKeyParam",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptGetKeyParam",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
}
-
+
blockLen = dwBlockLen / 8;
xmlSecAssert2(blockLen > 0, -1);
if(encrypt) {
- unsigned char* iv;
- size_t outSize;
-
- /* allocate space for IV */
- outSize = xmlSecBufferGetSize(out);
- ret = xmlSecBufferSetSize(out, outSize + blockLen);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "xmlSecBufferSetSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", outSize + blockLen);
- return(-1);
- }
- iv = xmlSecBufferGetData(out) + outSize;
-
- /* generate and use random iv */
- if(!CryptGenRandom(ctx->cryptProvider, blockLen, iv)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptGenRandom",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "len=%d", blockLen);
- return(-1);
- }
-
- if(!CryptSetKeyParam(ctx->cryptKey, KP_IV, iv, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptSetKeyParam",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
+ unsigned char* iv;
+ size_t outSize;
+
+ /* allocate space for IV */
+ outSize = xmlSecBufferGetSize(out);
+ ret = xmlSecBufferSetSize(out, outSize + blockLen);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "xmlSecBufferSetSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", outSize + blockLen);
+ return(-1);
+ }
+ iv = xmlSecBufferGetData(out) + outSize;
+
+ /* generate and use random iv */
+ if(!CryptGenRandom(ctx->cryptProvider, blockLen, iv)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptGenRandom",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "len=%d", blockLen);
+ return(-1);
+ }
+
+ if(!CryptSetKeyParam(ctx->cryptKey, KP_IV, iv, 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptSetKeyParam",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
} else {
- /* if we don't have enough data, exit and hope that
- * we'll have iv next time */
- if(xmlSecBufferGetSize(in) < (size_t)blockLen) {
- return(0);
- }
- xmlSecAssert2(xmlSecBufferGetData(in) != NULL, -1);
-
- /* set iv */
- if (!CryptSetKeyParam(ctx->cryptKey, KP_IV, xmlSecBufferGetData(in), 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptSetKeyParam",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
-
- /* and remove from input */
- ret = xmlSecBufferRemoveHead(in, blockLen);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "xmlSecBufferRemoveHead",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", blockLen);
- return(-1);
-
- }
+ /* if we don't have enough data, exit and hope that
+ * we'll have iv next time */
+ if(xmlSecBufferGetSize(in) < (size_t)blockLen) {
+ return(0);
+ }
+ xmlSecAssert2(xmlSecBufferGetData(in) != NULL, -1);
+
+ /* set iv */
+ if (!CryptSetKeyParam(ctx->cryptKey, KP_IV, xmlSecBufferGetData(in), 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptSetKeyParam",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* and remove from input */
+ ret = xmlSecBufferRemoveHead(in, blockLen);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "xmlSecBufferRemoveHead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", blockLen);
+ return(-1);
+
+ }
}
ctx->ctxInitialized = 1;
- return(0);
+ return(0);
}
-static int
+static int
xmlSecMSCryptoBlockCipherCtxUpdate(xmlSecMSCryptoBlockCipherCtxPtr ctx,
- xmlSecBufferPtr in, xmlSecBufferPtr out,
- int encrypt,
- const xmlChar* cipherName,
- xmlSecTransformCtxPtr transformCtx) {
+ xmlSecBufferPtr in, xmlSecBufferPtr out,
+ int encrypt,
+ const xmlChar* cipherName,
+ xmlSecTransformCtxPtr transformCtx) {
size_t inSize, inBlocks, outSize;
int blockLen;
unsigned char* outBuf;
@@ -186,44 +170,44 @@ xmlSecMSCryptoBlockCipherCtxUpdate(xmlSecMSCryptoBlockCipherCtxPtr ctx,
xmlSecAssert2(in != NULL, -1);
xmlSecAssert2(out != NULL, -1);
xmlSecAssert2(transformCtx != NULL, -1);
-
+
dwBlockLenLen = sizeof(DWORD);
if (!CryptGetKeyParam(ctx->cryptKey, KP_BLOCKLEN, (BYTE *)&dwBlockLen, &dwBlockLenLen, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptSetKeyParam",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptSetKeyParam",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
}
blockLen = dwBlockLen / 8;
xmlSecAssert2(blockLen > 0, -1);
inSize = xmlSecBufferGetSize(in);
outSize = xmlSecBufferGetSize(out);
-
+
if(inSize < (size_t)blockLen) {
- return(0);
+ return(0);
}
if(encrypt) {
- inBlocks = inSize / ((size_t)blockLen);
+ inBlocks = inSize / ((size_t)blockLen);
} else {
- /* we want to have the last block in the input buffer
- * for padding check */
- inBlocks = (inSize - 1) / ((size_t)blockLen);
+ /* we want to have the last block in the input buffer
+ * for padding check */
+ inBlocks = (inSize - 1) / ((size_t)blockLen);
}
inSize = inBlocks * ((size_t)blockLen);
/* we write out the input size plus may be one block */
ret = xmlSecBufferSetMaxSize(out, outSize + inSize + blockLen);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "xmlSecBufferSetMaxSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", outSize + inSize + blockLen);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "xmlSecBufferSetMaxSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", outSize + inSize + blockLen);
+ return(-1);
}
outBuf = xmlSecBufferGetData(out) + outSize;
inBuf = xmlSecBufferGetData(in);
@@ -232,72 +216,72 @@ xmlSecMSCryptoBlockCipherCtxUpdate(xmlSecMSCryptoBlockCipherCtxPtr ctx,
memcpy(outBuf, inBuf, inSize);
dwCLen = inSize;
if(encrypt) {
- if(!CryptEncrypt(ctx->cryptKey, 0, FALSE, 0, outBuf, &dwCLen, inSize + blockLen)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptEncrypt",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
+ if(!CryptEncrypt(ctx->cryptKey, 0, FALSE, 0, outBuf, &dwCLen, inSize + blockLen)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptEncrypt",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
} else {
- if (!CryptDecrypt(ctx->cryptKey, 0, FALSE, 0, outBuf, &dwCLen)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptSetKeyDecrypt",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
+ if (!CryptDecrypt(ctx->cryptKey, 0, FALSE, 0, outBuf, &dwCLen)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptSetKeyDecrypt",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
}
/* Check if we really have de/encrypted the numbers of bytes that we requested */
if (dwCLen != inSize) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptEn/Decrypt",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%ld", dwCLen);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptEn/Decrypt",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%ld", dwCLen);
+ return(-1);
}
/* set correct output buffer size */
ret = xmlSecBufferSetSize(out, outSize + inSize);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "xmlSecBufferSetSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", outSize + inSize);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "xmlSecBufferSetSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", outSize + inSize);
+ return(-1);
}
/* remove the processed block from input */
ret = xmlSecBufferRemoveHead(in, inSize);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "xmlSecBufferRemoveHead",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", inSize);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "xmlSecBufferRemoveHead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", inSize);
+ return(-1);
}
return(0);
}
-static int
+static int
xmlSecMSCryptoBlockCipherCtxFinal(xmlSecMSCryptoBlockCipherCtxPtr ctx,
- xmlSecBufferPtr in,
- xmlSecBufferPtr out,
- int encrypt,
- const xmlChar* cipherName,
- xmlSecTransformCtxPtr transformCtx) {
+ xmlSecBufferPtr in,
+ xmlSecBufferPtr out,
+ int encrypt,
+ const xmlChar* cipherName,
+ xmlSecTransformCtxPtr transformCtx) {
size_t inSize, outSize;
int blockLen, outLen = 0;
unsigned char* inBuf;
unsigned char* outBuf;
int ret;
DWORD dwBlockLen, dwBlockLenLen, dwCLen;
-
+
xmlSecAssert2(ctx != NULL, -1);
xmlSecAssert2(ctx->ctxInitialized != 0, -1);
xmlSecAssert2(in != NULL, -1);
@@ -306,12 +290,12 @@ xmlSecMSCryptoBlockCipherCtxFinal(xmlSecMSCryptoBlockCipherCtxPtr ctx,
dwBlockLenLen = sizeof(DWORD);
if (!CryptGetKeyParam(ctx->cryptKey, KP_BLOCKLEN, (BYTE *)&dwBlockLen, &dwBlockLenLen, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptGetKeyParam",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptGetKeyParam",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
}
blockLen = dwBlockLen / 8;
xmlSecAssert2(blockLen > 0, -1);
@@ -320,129 +304,129 @@ xmlSecMSCryptoBlockCipherCtxFinal(xmlSecMSCryptoBlockCipherCtxPtr ctx,
outSize = xmlSecBufferGetSize(out);
if(encrypt != 0) {
- xmlSecAssert2(inSize < (size_t)blockLen, -1);
-
- /* create padding */
- ret = xmlSecBufferSetMaxSize(in, blockLen);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "xmlSecBufferSetMaxSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", blockLen);
- return(-1);
- }
- inBuf = xmlSecBufferGetData(in);
-
- /* create random padding */
- if((size_t)blockLen > (inSize + 1)) {
- if (!CryptGenRandom(ctx->cryptProvider, blockLen - inSize - 1, inBuf + inSize)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptGenRandom",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
- }
- inBuf[blockLen - 1] = blockLen - inSize;
- inSize = blockLen;
+ xmlSecAssert2(inSize < (size_t)blockLen, -1);
+
+ /* create padding */
+ ret = xmlSecBufferSetMaxSize(in, blockLen);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "xmlSecBufferSetMaxSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", blockLen);
+ return(-1);
+ }
+ inBuf = xmlSecBufferGetData(in);
+
+ /* create random padding */
+ if((size_t)blockLen > (inSize + 1)) {
+ if (!CryptGenRandom(ctx->cryptProvider, blockLen - inSize - 1, inBuf + inSize)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptGenRandom",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+ inBuf[blockLen - 1] = blockLen - inSize;
+ inSize = blockLen;
} else {
- if(inSize != (size_t)blockLen) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- NULL,
- XMLSEC_ERRORS_R_INVALID_DATA,
- "data=%d;block=%d", inSize, blockLen);
- return(-1);
- }
- inBuf = xmlSecBufferGetData(in);
+ if(inSize != (size_t)blockLen) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "data=%d;block=%d", inSize, blockLen);
+ return(-1);
+ }
+ inBuf = xmlSecBufferGetData(in);
}
-
+
/* process last block */
ret = xmlSecBufferSetMaxSize(out, outSize + 2 * blockLen);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "xmlSecBufferSetMaxSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", outSize + 2 * blockLen);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "xmlSecBufferSetMaxSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", outSize + 2 * blockLen);
+ return(-1);
}
outBuf = xmlSecBufferGetData(out) + outSize;
memcpy(outBuf, inBuf, inSize);
dwCLen = inSize;
if(encrypt) {
- /* Set process last block to false, since we handle padding ourselves, and MSCrypto padding
- * can be skipped. I hope this will work .... */
- if(!CryptEncrypt(ctx->cryptKey, 0, FALSE, 0, outBuf, &dwCLen, inSize + blockLen)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptEncrypt",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
+ /* Set process last block to false, since we handle padding ourselves, and MSCrypto padding
+ * can be skipped. I hope this will work .... */
+ if(!CryptEncrypt(ctx->cryptKey, 0, FALSE, 0, outBuf, &dwCLen, inSize + blockLen)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptEncrypt",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
} else {
- if (!CryptDecrypt(ctx->cryptKey, 0, FALSE, 0, outBuf, &dwCLen)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptDecrypt",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
+ if (!CryptDecrypt(ctx->cryptKey, 0, FALSE, 0, outBuf, &dwCLen)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptDecrypt",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
}
/* Check if we really have de/encrypted the numbers of bytes that we requested */
if (dwCLen != inSize) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "CryptEn/Decrypt",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%ld", dwCLen);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "CryptEn/Decrypt",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%ld", dwCLen);
+ return(-1);
}
if(encrypt == 0) {
- /* check padding */
- if(inSize < outBuf[blockLen - 1]) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- NULL,
- XMLSEC_ERRORS_R_INVALID_DATA,
- "padding=%d;buffer=%d",
- outBuf[blockLen - 1], inSize);
- return(-1);
- }
- outLen = inSize - outBuf[blockLen - 1];
+ /* check padding */
+ if(inSize < outBuf[blockLen - 1]) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "padding=%d;buffer=%d",
+ outBuf[blockLen - 1], inSize);
+ return(-1);
+ }
+ outLen = inSize - outBuf[blockLen - 1];
} else {
- outLen = inSize;
+ outLen = inSize;
}
/* set correct output buffer size */
ret = xmlSecBufferSetSize(out, outSize + outLen);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "xmlSecBufferSetSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", outSize + outLen);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "xmlSecBufferSetSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", outSize + outLen);
+ return(-1);
}
/* remove the processed block from input */
ret = xmlSecBufferRemoveHead(in, inSize);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(cipherName),
- "xmlSecBufferRemoveHead",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", inSize);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(cipherName),
+ "xmlSecBufferRemoveHead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", inSize);
+ return(-1);
}
-
+
return(0);
}
@@ -451,29 +435,52 @@ xmlSecMSCryptoBlockCipherCtxFinal(xmlSecMSCryptoBlockCipherCtxPtr ctx,
* Block Cipher transforms
*
* xmlSecMSCryptoBlockCipherCtx block is located after xmlSecTransform structure
- *
+ *
*****************************************************************************/
-#define xmlSecMSCryptoBlockCipherSize \
+#define xmlSecMSCryptoBlockCipherSize \
(sizeof(xmlSecTransform) + sizeof(xmlSecMSCryptoBlockCipherCtx))
#define xmlSecMSCryptoBlockCipherGetCtx(transform) \
((xmlSecMSCryptoBlockCipherCtxPtr)(((unsigned char*)(transform)) + sizeof(xmlSecTransform)))
-static int xmlSecMSCryptoBlockCipherInitialize (xmlSecTransformPtr transform);
-static void xmlSecMSCryptoBlockCipherFinalize (xmlSecTransformPtr transform);
-static int xmlSecMSCryptoBlockCipherSetKeyReq (xmlSecTransformPtr transform,
- xmlSecKeyReqPtr keyReq);
-static int xmlSecMSCryptoBlockCipherSetKey (xmlSecTransformPtr transform,
- xmlSecKeyPtr key);
-static int xmlSecMSCryptoBlockCipherExecute (xmlSecTransformPtr transform,
- int last,
- xmlSecTransformCtxPtr transformCtx);
-static int xmlSecMSCryptoBlockCipherCheckId (xmlSecTransformPtr transform);
-
+static int xmlSecMSCryptoBlockCipherInitialize (xmlSecTransformPtr transform);
+static void xmlSecMSCryptoBlockCipherFinalize (xmlSecTransformPtr transform);
+static int xmlSecMSCryptoBlockCipherSetKeyReq (xmlSecTransformPtr transform,
+ xmlSecKeyReqPtr keyReq);
+static int xmlSecMSCryptoBlockCipherSetKey (xmlSecTransformPtr transform,
+ xmlSecKeyPtr key);
+static int xmlSecMSCryptoBlockCipherExecute (xmlSecTransformPtr transform,
+ int last,
+ xmlSecTransformCtxPtr transformCtx);
+static int xmlSecMSCryptoBlockCipherCheckId (xmlSecTransformPtr transform);
+
+
+
+/* Ordered list of providers to search for algorithm implementation using
+ * xmlSecMSCryptoFindProvider() function
+ *
+ * MUST END with { NULL, 0 } !!!
+ */
+#ifndef XMLSEC_NO_DES
+static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Des[] = {
+ { MS_STRONG_PROV, PROV_RSA_FULL },
+ { MS_ENHANCED_PROV, PROV_RSA_FULL },
+ { NULL, 0 }
+};
+#endif /* XMLSEC_NO_DES */
+
+#ifndef XMLSEC_NO_AES
+static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Aes[] = {
+ { XMLSEC_CRYPTO_MS_ENH_RSA_AES_PROV, PROV_RSA_AES},
+ { XMLSEC_CRYPTO_MS_ENH_RSA_AES_PROV_PROTOTYPE, PROV_RSA_AES },
+ { NULL, 0 }
+};
+#endif /* XMLSEC_NO_AES */
+
static int
xmlSecMSCryptoBlockCipherCheckId(xmlSecTransformPtr transform) {
#ifndef XMLSEC_NO_DES
if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformDes3CbcId)) {
- return(1);
+ return(1);
}
#endif /* XMLSEC_NO_DES */
@@ -489,115 +496,83 @@ xmlSecMSCryptoBlockCipherCheckId(xmlSecTransformPtr transform) {
return(0);
}
-static int
+static int
xmlSecMSCryptoBlockCipherInitialize(xmlSecTransformPtr transform) {
xmlSecMSCryptoBlockCipherCtxPtr ctx;
+ int ret;
xmlSecAssert2(xmlSecMSCryptoBlockCipherCheckId(transform), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoBlockCipherSize), -1);
ctx = xmlSecMSCryptoBlockCipherGetCtx(transform);
xmlSecAssert2(ctx != NULL, -1);
-
+
memset(ctx, 0, sizeof(xmlSecMSCryptoBlockCipherCtx));
#ifndef XMLSEC_NO_DES
if(transform->id == xmlSecMSCryptoTransformDes3CbcId) {
- ctx->algorithmIdentifier = CALG_3DES;
- ctx->keyId = xmlSecMSCryptoKeyDataDesId;
- ctx->providerName = MS_ENHANCED_PROV;
- ctx->providerType = PROV_RSA_FULL;
- ctx->keySize = 24;
- } else
+ ctx->algorithmIdentifier = CALG_3DES;
+ ctx->keyId = xmlSecMSCryptoKeyDataDesId;
+ ctx->providers = xmlSecMSCryptoProviderInfo_Des;
+ ctx->keySize = 24;
+ } else
#endif /* XMLSEC_NO_DES */
#ifndef XMLSEC_NO_AES
if(transform->id == xmlSecMSCryptoTransformAes128CbcId) {
- ctx->algorithmIdentifier = CALG_AES_128;
- ctx->keyId = xmlSecMSCryptoKeyDataAesId;
- ctx->providerName = MS_ENH_RSA_AES_PROV_PROTO;
- ctx->providerType = PROV_RSA_AES;
- ctx->keySize = 16;
+ ctx->algorithmIdentifier = CALG_AES_128;
+ ctx->keyId = xmlSecMSCryptoKeyDataAesId;
+ ctx->providers = xmlSecMSCryptoProviderInfo_Aes;
+ ctx->keySize = 16;
} else if(transform->id == xmlSecMSCryptoTransformAes192CbcId) {
- ctx->algorithmIdentifier = CALG_AES_192;
- ctx->keyId = xmlSecMSCryptoKeyDataAesId;
- ctx->providerName = MS_ENH_RSA_AES_PROV_PROTO;
- ctx->providerType = PROV_RSA_AES;
- ctx->keySize = 24;
+ ctx->algorithmIdentifier = CALG_AES_192;
+ ctx->keyId = xmlSecMSCryptoKeyDataAesId;
+ ctx->providers = xmlSecMSCryptoProviderInfo_Aes;
+ ctx->keySize = 24;
} else if(transform->id == xmlSecMSCryptoTransformAes256CbcId) {
- ctx->algorithmIdentifier = CALG_AES_256;
- ctx->keyId = xmlSecMSCryptoKeyDataAesId;
- ctx->providerName = MS_ENH_RSA_AES_PROV_PROTO;
- ctx->providerType = PROV_RSA_AES;
- ctx->keySize = 32;
- } else
+ ctx->algorithmIdentifier = CALG_AES_256;
+ ctx->keyId = xmlSecMSCryptoKeyDataAesId;
+ ctx->providers = xmlSecMSCryptoProviderInfo_Aes;
+ ctx->keySize = 32;
+ } else
#endif /* XMLSEC_NO_AES */
- if(1) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_TRANSFORM,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
-
- if(!CryptAcquireContext(&ctx->cryptProvider, NULL /*"xmlSecMSCryptoTempContainer"*/,
- ctx->providerName, ctx->providerType, 0)) {
- DWORD dwError = GetLastError();
- if (dwError == NTE_EXISTS) {
- if (!CryptAcquireContext(&ctx->cryptProvider, "xmlSecMSCryptoTempContainer",
- ctx->providerName, ctx->providerType, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "CryptAcquireContext",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
-
- return(-1);
- }
- } else if (dwError == NTE_BAD_KEYSET) {
- /* This error can indicate that a newly installed provider
- * does not have a usable key container yet. It needs to be
- * created, and then we have to try again CryptAcquireContext.
- * This is also referenced in
- * http://www.microsoft.com/mind/0697/crypto.asp (inituser)
- */
- if(!CryptAcquireContext(&ctx->cryptProvider, NULL, ctx->providerName,
- ctx->providerType, CRYPT_NEWKEYSET)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "CryptAcquireContext",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
- } else {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "CryptAcquireContext",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
+ {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_TRANSFORM,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ctx->cryptProvider = xmlSecMSCryptoFindProvider(ctx->providers, NULL, CRYPT_VERIFYCONTEXT, TRUE);
+ if(ctx->cryptProvider == 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecMSCryptoFindProvider",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+
+ return(-1);
}
/* Create dummy key to be able to import plain session keys */
if (!xmlSecMSCryptoCreatePrivateExponentOneKey(ctx->cryptProvider, &(ctx->pubPrivKey))) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecMSCryptoCreatePrivateExponentOneKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecMSCryptoCreatePrivateExponentOneKey",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
+ return(-1);
}
ctx->ctxInitialized = 0;
return(0);
}
-static void
+static void
xmlSecMSCryptoBlockCipherFinalize(xmlSecTransformPtr transform) {
xmlSecMSCryptoBlockCipherCtxPtr ctx;
@@ -608,21 +583,19 @@ xmlSecMSCryptoBlockCipherFinalize(xmlSecTransformPtr transform) {
xmlSecAssert(ctx != NULL);
if (ctx->cryptKey) {
- CryptDestroyKey(ctx->cryptKey);
+ CryptDestroyKey(ctx->cryptKey);
}
if (ctx->pubPrivKey) {
- CryptDestroyKey(ctx->pubPrivKey);
+ CryptDestroyKey(ctx->pubPrivKey);
}
if (ctx->cryptProvider) {
- CryptReleaseContext(ctx->cryptProvider, 0);
- CryptAcquireContext(&ctx->cryptProvider, "xmlSecMSCryptoTempContainer",
- MS_ENHANCED_PROV, ctx->providerType, CRYPT_DELETEKEYSET);
+ CryptReleaseContext(ctx->cryptProvider, 0);
}
-
+
memset(ctx, 0, sizeof(xmlSecMSCryptoBlockCipherCtx));
}
-static int
+static int
xmlSecMSCryptoBlockCipherSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) {
xmlSecMSCryptoBlockCipherCtxPtr ctx;
@@ -635,12 +608,12 @@ xmlSecMSCryptoBlockCipherSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPt
xmlSecAssert2(ctx != NULL, -1);
xmlSecAssert2(ctx->cryptProvider != 0, -1);
- keyReq->keyId = ctx->keyId;
- keyReq->keyType = xmlSecKeyDataTypeSymmetric;
+ keyReq->keyId = ctx->keyId;
+ keyReq->keyType = xmlSecKeyDataTypeSymmetric;
if(transform->operation == xmlSecTransformOperationEncrypt) {
- keyReq->keyUsage = xmlSecKeyUsageEncrypt;
+ keyReq->keyUsage = xmlSecKeyUsageEncrypt;
} else {
- keyReq->keyUsage = xmlSecKeyUsageDecrypt;
+ keyReq->keyUsage = xmlSecKeyUsageDecrypt;
}
keyReq->keyBitsSize = 8 * ctx->keySize;
@@ -660,23 +633,23 @@ xmlSecMSCryptoBlockCipherSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key)
ctx = xmlSecMSCryptoBlockCipherGetCtx(transform);
xmlSecAssert2(ctx != NULL, -1);
- xmlSecAssert2(ctx->keyInitialized == 0, -1);
+ xmlSecAssert2(ctx->cryptKey == 0, -1);
+ xmlSecAssert2(ctx->pubPrivKey != 0, -1);
xmlSecAssert2(ctx->keyId != NULL, -1);
xmlSecAssert2(xmlSecKeyCheckId(key, ctx->keyId), -1);
-
xmlSecAssert2(ctx->keySize > 0, -1);
buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key));
xmlSecAssert2(buffer != NULL, -1);
if(xmlSecBufferGetSize(buffer) < ctx->keySize) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
- "keySize=%d;expected=%d",
- xmlSecBufferGetSize(buffer), ctx->keySize);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
+ "keySize=%d;expected=%d",
+ xmlSecBufferGetSize(buffer), ctx->keySize);
+ return(-1);
}
bufData = xmlSecBufferGetData(buffer);
@@ -684,35 +657,35 @@ xmlSecMSCryptoBlockCipherSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key)
/* Import this key and get an HCRYPTKEY handle */
if (!xmlSecMSCryptoImportPlainSessionBlob(ctx->cryptProvider,
- ctx->pubPrivKey,
- ctx->algorithmIdentifier,
- bufData,
- ctx->keySize,
- &(ctx->cryptKey))) {
-
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecMSCryptoImportPlainSessionBlob",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
+ ctx->pubPrivKey,
+ ctx->algorithmIdentifier,
+ bufData,
+ ctx->keySize,
+ TRUE,
+ &(ctx->cryptKey))) {
+
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecMSCryptoImportPlainSessionBlob",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
}
- ctx->keyInitialized = 1;
return(0);
}
-static int
+static int
xmlSecMSCryptoBlockCipherExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
xmlSecMSCryptoBlockCipherCtxPtr ctx;
xmlSecBufferPtr in, out;
int ret;
-
+
xmlSecAssert2(xmlSecMSCryptoBlockCipherCheckId(transform), -1);
xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoBlockCipherSize), -1);
xmlSecAssert2(transformCtx != NULL, -1);
-
+
in = &(transform->inBuf);
out = &(transform->outBuf);
@@ -720,79 +693,79 @@ xmlSecMSCryptoBlockCipherExecute(xmlSecTransformPtr transform, int last, xmlSecT
xmlSecAssert2(ctx != NULL, -1);
if(transform->status == xmlSecTransformStatusNone) {
- transform->status = xmlSecTransformStatusWorking;
+ transform->status = xmlSecTransformStatusWorking;
}
if(transform->status == xmlSecTransformStatusWorking) {
- if(ctx->ctxInitialized == 0) {
- ret = xmlSecMSCryptoBlockCipherCtxInit(ctx,
- in,
- out,
- (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
- xmlSecTransformGetName(transform),
- transformCtx);
-
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecMSCryptoBlockCipherCtxInit",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
- }
- if((ctx->ctxInitialized == 0) && (last != 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_DATA,
- "not enough data to initialize transform");
- return(-1);
- }
- if(ctx->ctxInitialized != 0) {
- ret = xmlSecMSCryptoBlockCipherCtxUpdate(ctx, in, out,
- (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
- xmlSecTransformGetName(transform), transformCtx);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecMSCryptoBlockCipherCtxUpdate",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
- }
-
- if(last) {
- ret = xmlSecMSCryptoBlockCipherCtxFinal(ctx, in, out,
- (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
- xmlSecTransformGetName(transform), transformCtx);
-
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecMSCryptoBlockCipherCtxFinal",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
- transform->status = xmlSecTransformStatusFinished;
- }
+ if(ctx->ctxInitialized == 0) {
+ ret = xmlSecMSCryptoBlockCipherCtxInit(ctx,
+ in,
+ out,
+ (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
+ xmlSecTransformGetName(transform),
+ transformCtx);
+
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecMSCryptoBlockCipherCtxInit",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+ if((ctx->ctxInitialized == 0) && (last != 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "not enough data to initialize transform");
+ return(-1);
+ }
+ if(ctx->ctxInitialized != 0) {
+ ret = xmlSecMSCryptoBlockCipherCtxUpdate(ctx, in, out,
+ (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
+ xmlSecTransformGetName(transform), transformCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecMSCryptoBlockCipherCtxUpdate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ if(last) {
+ ret = xmlSecMSCryptoBlockCipherCtxFinal(ctx, in, out,
+ (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
+ xmlSecTransformGetName(transform), transformCtx);
+
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecMSCryptoBlockCipherCtxFinal",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ transform->status = xmlSecTransformStatusFinished;
+ }
} else if(transform->status == xmlSecTransformStatusFinished) {
- /* the only way we can get here is if there is no input */
- xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1);
+ /* the only way we can get here is if there is no input */
+ xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1);
} else if(transform->status == xmlSecTransformStatusNone) {
- /* the only way we can get here is if there is no enough data in the input */
- xmlSecAssert2(last == 0, -1);
+ /* the only way we can get here is if there is no enough data in the input */
+ xmlSecAssert2(last == 0, -1);
} else {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_STATUS,
- "status=%d", transform->status);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_STATUS,
+ "status=%d", transform->status);
+ return(-1);
}
-
+
return(0);
}
@@ -804,117 +777,117 @@ xmlSecMSCryptoBlockCipherExecute(xmlSecTransformPtr transform, int last, xmlSecT
********************************************************************/
static xmlSecTransformKlass xmlSecMSCryptoAes128CbcKlass = {
/* klass/object sizes */
- sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
- xmlSecMSCryptoBlockCipherSize, /* xmlSecSize objSize */
-
- xmlSecNameAes128Cbc, /* const xmlChar* name; */
- xmlSecHrefAes128Cbc, /* const xmlChar* href; */
- xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
-
- xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
- xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
- NULL, /* xmlSecTransformNodeReadMethod readNode; */
- NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
- xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
- xmlSecMSCryptoBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */
- NULL, /* xmlSecTransformValidateMethod validate; */
- xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
- xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
- xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
- NULL, /* xmlSecTransformPushXmlMethod pushXml; */
- NULL, /* xmlSecTransformPopXmlMethod popXml; */
- xmlSecMSCryptoBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */
-
- NULL, /* void* reserved0; */
- NULL, /* void* reserved1; */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecMSCryptoBlockCipherSize, /* xmlSecSize objSize */
+
+ xmlSecNameAes128Cbc, /* const xmlChar* name; */
+ xmlSecHrefAes128Cbc, /* const xmlChar* href; */
+ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecMSCryptoBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
};
/**
* xmlSecMSCryptoTransformAes128CbcGetKlass:
- *
+ *
* AES 128 CBC encryption transform klass.
- *
+ *
* Returns: pointer to AES 128 CBC encryption transform.
- */
-xmlSecTransformId
+ */
+xmlSecTransformId
xmlSecMSCryptoTransformAes128CbcGetKlass(void) {
return(&xmlSecMSCryptoAes128CbcKlass);
}
static xmlSecTransformKlass xmlSecMSCryptoAes192CbcKlass = {
/* klass/object sizes */
- sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
- xmlSecMSCryptoBlockCipherSize, /* xmlSecSize objSize */
-
- xmlSecNameAes192Cbc, /* const xmlChar* name; */
- xmlSecHrefAes192Cbc, /* const xmlChar* href; */
- xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
-
- xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
- xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
- NULL, /* xmlSecTransformNodeReadMethod readNode; */
- NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
- xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
- xmlSecMSCryptoBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */
- NULL, /* xmlSecTransformValidateMethod validate; */
- xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
- xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
- xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
- NULL, /* xmlSecTransformPushXmlMethod pushXml; */
- NULL, /* xmlSecTransformPopXmlMethod popXml; */
- xmlSecMSCryptoBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */
-
- NULL, /* void* reserved0; */
- NULL, /* void* reserved1; */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecMSCryptoBlockCipherSize, /* xmlSecSize objSize */
+
+ xmlSecNameAes192Cbc, /* const xmlChar* name; */
+ xmlSecHrefAes192Cbc, /* const xmlChar* href; */
+ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecMSCryptoBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
};
/**
* xmlSecMSCryptoTransformAes192CbcGetKlass:
- *
+ *
* AES 192 CBC encryption transform klass.
- *
+ *
* Returns: pointer to AES 192 CBC encryption transform.
- */
-xmlSecTransformId
+ */
+xmlSecTransformId
xmlSecMSCryptoTransformAes192CbcGetKlass(void) {
return(&xmlSecMSCryptoAes192CbcKlass);
}
static xmlSecTransformKlass xmlSecMSCryptoAes256CbcKlass = {
/* klass/object sizes */
- sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
- xmlSecMSCryptoBlockCipherSize, /* xmlSecSize objSize */
-
- xmlSecNameAes256Cbc, /* const xmlChar* name; */
- xmlSecHrefAes256Cbc, /* const xmlChar* href; */
- xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
-
- xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
- xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
- NULL, /* xmlSecTransformNodeReadMethod readNode; */
- NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
- xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
- xmlSecMSCryptoBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */
- NULL, /* xmlSecTransformValidateMethod validate; */
- xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
- xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
- xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
- NULL, /* xmlSecTransformPushXmlMethod pushXml; */
- NULL, /* xmlSecTransformPopXmlMethod popXml; */
- xmlSecMSCryptoBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */
-
- NULL, /* void* reserved0; */
- NULL, /* void* reserved1; */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecMSCryptoBlockCipherSize, /* xmlSecSize objSize */
+
+ xmlSecNameAes256Cbc, /* const xmlChar* name; */
+ xmlSecHrefAes256Cbc, /* const xmlChar* href; */
+ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecMSCryptoBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
};
/**
* xmlSecMSCryptoTransformAes256CbcGetKlass:
- *
+ *
* AES 256 CBC encryption transform klass.
- *
+ *
* Returns: pointer to AES 256 CBC encryption transform.
- */
-xmlSecTransformId
+ */
+xmlSecTransformId
xmlSecMSCryptoTransformAes256CbcGetKlass(void) {
return(&xmlSecMSCryptoAes256CbcKlass);
}
@@ -925,426 +898,40 @@ xmlSecMSCryptoTransformAes256CbcGetKlass(void) {
#ifndef XMLSEC_NO_DES
static xmlSecTransformKlass xmlSecMSCryptoDes3CbcKlass = {
/* klass/object sizes */
- sizeof(xmlSecTransformKlass), /* size_t klassSize */
- xmlSecMSCryptoBlockCipherSize, /* size_t objSize */
+ sizeof(xmlSecTransformKlass), /* size_t klassSize */
+ xmlSecMSCryptoBlockCipherSize, /* size_t objSize */
- xmlSecNameDes3Cbc, /* const xmlChar* name; */
- xmlSecHrefDes3Cbc, /* const xmlChar* href; */
+ xmlSecNameDes3Cbc, /* const xmlChar* name; */
+ xmlSecHrefDes3Cbc, /* const xmlChar* href; */
xmlSecTransformUsageEncryptionMethod,/* xmlSecAlgorithmUsage usage; */
xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
- xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
- NULL, /* xmlSecTransformNodeReadMethod readNode; */
- NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
- xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
- xmlSecMSCryptoBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */
- NULL, /* xmlSecTransformValidateMethod validate; */
- xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
- xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
- xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
- NULL, /* xmlSecTransformPushXmlMethod pushXml; */
- NULL, /* xmlSecTransformPopXmlMethod popXml; */
- xmlSecMSCryptoBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */
-
- NULL, /* void* reserved0; */
- NULL, /* void* reserved1; */
+ xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecMSCryptoBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
};
-/**
+/**
* xmlSecMSCryptoTransformDes3CbcGetKlass:
*
* Triple DES CBC encryption transform klass.
- *
+ *
* Returns: pointer to Triple DES encryption transform.
*/
-xmlSecTransformId
+xmlSecTransformId
xmlSecMSCryptoTransformDes3CbcGetKlass(void) {
return(&xmlSecMSCryptoDes3CbcKlass);
}
#endif /* XMLSEC_NO_DES */
-
-/*
- * Low level helper routines for importing plain text keys in MS HKEY handle,
- * since MSCrypto API does not support import of plain text (session) keys
- * just like that.
- * These functions are based upon MS kb article: 228786
- *
- * aleksey: also check "Base Provider Key BLOBs" article for priv key blob format
- **/
-static BOOL
-xmlSecMSCryptoCreatePrivateExponentOneKey(HCRYPTPROV hProv, HCRYPTKEY *hPrivateKey)
-{
- HCRYPTKEY hKey = 0;
- LPBYTE keyBlob = NULL;
- DWORD keyBlobLen;
- PUBLICKEYSTRUC* pubKeyStruc;
- RSAPUBKEY* rsaPubKey;
- DWORD bitLen;
- BYTE *ptr;
- int n;
- BOOL res = FALSE;
-
- xmlSecAssert2(hProv != 0, FALSE);
- xmlSecAssert2(hPrivateKey != NULL, FALSE);
-
- /* just in case */
- *hPrivateKey = 0;
-
- /* Generate the private key */
- if(!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptGenKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
- }
-
- /* Export the private key, we'll convert it to a private exponent of one key */
- if(!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, NULL, &keyBlobLen)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptExportKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
- }
-
- keyBlob = (LPBYTE)xmlMalloc(sizeof(BYTE) * keyBlobLen);
- if(keyBlob == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- NULL,
- XMLSEC_ERRORS_R_MALLOC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
- }
-
- if(!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, keyBlob, &keyBlobLen)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptExportKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
- }
- CryptDestroyKey(hKey);
- hKey = 0;
-
- /* Get the bit length of the key */
- if(keyBlobLen < sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptExportKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "len=%ld", keyBlobLen);
- goto done;
- }
- pubKeyStruc = (PUBLICKEYSTRUC*)keyBlob;
- if(pubKeyStruc->bVersion != 0x02) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptExportKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "pubKeyStruc->bVersion=%d", pubKeyStruc->bVersion);
- goto done;
- }
- if(pubKeyStruc->bType != PRIVATEKEYBLOB) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptExportKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "pubKeyStruc->bType=%d", (int)pubKeyStruc->bType);
- goto done;
- }
-
- /* aleksey: don't ask me why it is RSAPUBKEY, just don't ask */
- rsaPubKey = (RSAPUBKEY*)(keyBlob + sizeof(PUBLICKEYSTRUC));
-
- /* check that we have RSA private key */
- if(rsaPubKey->magic != 0x32415352) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptExportKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "rsaPubKey->magic=0x%08lx", rsaPubKey->magic);
- goto done;
- }
- bitLen = rsaPubKey->bitlen;
-
- /* Modify the Exponent in Key BLOB format Key BLOB format is documented in SDK */
- rsaPubKey->pubexp = 1;
-
- /* Private-key BLOBs, type PRIVATEKEYBLOB, are used to store private keys outside a CSP.
- * Base provider private-key BLOBs have the following format:
- *
- * PUBLICKEYSTRUC publickeystruc ;
- * RSAPUBKEY rsapubkey;
- * BYTE modulus[rsapubkey.bitlen/8]; 1/8
- * BYTE prime1[rsapubkey.bitlen/16]; 1/16
- * BYTE prime2[rsapubkey.bitlen/16]; 1/16
- * BYTE exponent1[rsapubkey.bitlen/16]; 1/16
- * BYTE exponent2[rsapubkey.bitlen/16]; 1/16
- * BYTE coefficient[rsapubkey.bitlen/16]; 1/16
- * BYTE privateExponent[rsapubkey.bitlen/8]; 1/8
- */
- if(keyBlobLen < sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + bitLen / 2 + bitLen / 16) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptExportKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "len=%ld", keyBlobLen);
- goto done;
- }
- ptr = (BYTE*)(keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
-
- /* Skip modulus, prime1, prime2 */
- ptr += bitLen / 8;
- ptr += bitLen / 16;
- ptr += bitLen / 16;
-
- /* Convert exponent1 to 1 */
- for (n = 0; n < (bitLen / 16); n++) {
- if (n == 0) ptr[n] = 1;
- else ptr[n] = 0;
- }
- ptr += bitLen / 16;
-
- /* Convert exponent2 to 1 */
- for (n = 0; n < (bitLen / 16); n++) {
- if (n == 0) ptr[n] = 1;
- else ptr[n] = 0;
- }
- ptr += bitLen / 16;
-
- /* Skip coefficient */
- ptr += bitLen / 16;
-
- /* Convert privateExponent to 1 */
- for (n = 0; n < (bitLen / 16); n++) {
- if (n == 0) ptr[n] = 1;
- else ptr[n] = 0;
- }
-
- /* Import the exponent-of-one private key. */
- if (!CryptImportKey(hProv, keyBlob, keyBlobLen, 0, 0, &hKey)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptImportKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
- }
- (*hPrivateKey) = hKey;
- hKey = 0;
- res = TRUE;
-
-done:
- if(keyBlob != NULL) {
- xmlFree(keyBlob);
- }
- if (hKey != 0) {
- CryptDestroyKey(hKey);
- }
-
- return res;
-}
-
-static BOOL
-xmlSecMSCryptoImportPlainSessionBlob(HCRYPTPROV hProv, HCRYPTKEY hPrivateKey,
- ALG_ID dwAlgId, LPBYTE pbKeyMaterial,
- DWORD dwKeyMaterial, HCRYPTKEY *hSessionKey) {
- ALG_ID dwPrivKeyAlg;
- LPBYTE keyBlob = NULL;
- DWORD keyBlobLen, rndBlobSize, dwSize, n;
- PUBLICKEYSTRUC* pubKeyStruc;
- ALG_ID* algId;
- DWORD dwPublicKeySize;
- DWORD dwProvSessionKeySize;
- LPBYTE pbPtr;
- DWORD dwFlags;
- PROV_ENUMALGS_EX ProvEnum;
- HCRYPTKEY hTempKey = 0;
- BOOL fFound;
- BOOL res = FALSE;
-
- xmlSecAssert2(hProv != 0, FALSE);
- xmlSecAssert2(hPrivateKey != 0, FALSE);
- xmlSecAssert2(pbKeyMaterial != NULL, FALSE);
- xmlSecAssert2(dwKeyMaterial > 0, FALSE);
- xmlSecAssert2(hSessionKey != NULL, FALSE);
-
- /* Double check to see if this provider supports this algorithm and key size */
- fFound = FALSE;
- dwFlags = CRYPT_FIRST;
- dwSize = sizeof(ProvEnum);
- while(CryptGetProvParam(hProv, PP_ENUMALGS_EX, (LPBYTE)&ProvEnum, &dwSize, dwFlags)) {
- if (ProvEnum.aiAlgid == dwAlgId) {
- fFound = TRUE;
- break;
- }
- dwSize = sizeof(ProvEnum);
- dwFlags = 0;
- }
- if(!fFound) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptGetProvParam",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "algId=%d is not supported", dwAlgId);
- goto done;
- }
-
- /* We have to get the key size(including padding) from an HCRYPTKEY handle.
- * PP_ENUMALGS_EX contains the key size without the padding so we can't use it.
- */
- if(!CryptGenKey(hProv, dwAlgId, 0, &hTempKey)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptGenKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "algId=%d", dwAlgId);
- goto done;
- }
-
- dwSize = sizeof(DWORD);
- if(!CryptGetKeyParam(hTempKey, KP_KEYLEN, (LPBYTE)&dwProvSessionKeySize, &dwSize, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptGetKeyParam(KP_KEYLEN)",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "algId=%d", dwAlgId);
- goto done;
- }
- CryptDestroyKey(hTempKey);
- hTempKey = 0;
-
- /* Our key is too big, leave */
- if ((dwKeyMaterial * 8) > dwProvSessionKeySize) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- NULL,
- XMLSEC_ERRORS_R_INVALID_SIZE,
- "dwKeyMaterial=%ld;dwProvSessionKeySize=%ld",
- dwKeyMaterial, dwProvSessionKeySize);
- goto done;
- }
-
- /* Get private key's algorithm */
- dwSize = sizeof(ALG_ID);
- if(!CryptGetKeyParam(hPrivateKey, KP_ALGID, (LPBYTE)&dwPrivKeyAlg, &dwSize, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptGetKeyParam(KP_ALGID)",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "algId=%d", dwAlgId);
- goto done;
- }
-
- /* Get private key's length in bits */
- dwSize = sizeof(DWORD);
- if(!CryptGetKeyParam(hPrivateKey, KP_KEYLEN, (LPBYTE)&dwPublicKeySize, &dwSize, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptGetKeyParam(KP_KEYLEN)",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "algId=%d", dwAlgId);
- goto done;
- }
-
- /* 3 is for the first reserved byte after the key material and the 2 reserved bytes at the end. */
- if(dwPublicKeySize / 8 < dwKeyMaterial + 3) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- NULL,
- XMLSEC_ERRORS_R_INVALID_SIZE,
- "dwKeyMaterial=%ld;dwPublicKeySize=%ld",
- dwKeyMaterial, dwPublicKeySize);
- goto done;
- }
- rndBlobSize = dwPublicKeySize / 8 - (dwKeyMaterial + 3);
-
- /* Simple key BLOBs, type SIMPLEBLOB, are used to store and transport session keys outside a CSP.
- * Base provider simple-key BLOBs are always encrypted with a key exchange public key. The pbData
- * member of the SIMPLEBLOB is a sequence of bytes in the following format:
- *
- * PUBLICKEYSTRUC publickeystruc ;
- * ALG_ID algid;
- * BYTE encryptedkey[rsapubkey.bitlen/8];
- */
-
- /* calculate Simple blob's length */
- keyBlobLen = sizeof(PUBLICKEYSTRUC) + sizeof(ALG_ID) + (dwPublicKeySize / 8);
-
- /* allocate simple blob buffer */
- keyBlob = (LPBYTE)xmlMalloc(sizeof(BYTE) * keyBlobLen);
- if(keyBlob == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- NULL,
- XMLSEC_ERRORS_R_MALLOC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
- }
- memset(keyBlob, 0, keyBlobLen);
-
- /* initialize PUBLICKEYSTRUC */
- pubKeyStruc = (PUBLICKEYSTRUC*)(keyBlob);
- pubKeyStruc->bType = SIMPLEBLOB;
- pubKeyStruc->bVersion = 0x02;
- pubKeyStruc->reserved = 0;
- pubKeyStruc->aiKeyAlg = dwAlgId;
-
- /* Copy private key algorithm to buffer */
- algId = (ALG_ID*)(keyBlob + sizeof(PUBLICKEYSTRUC));
- (*algId) = dwPrivKeyAlg;
-
- /* Place the key material in reverse order */
- pbPtr = (BYTE*)(keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(ALG_ID));
- for (n = 0; n < dwKeyMaterial; n++) {
- pbPtr[n] = pbKeyMaterial[dwKeyMaterial - n - 1];
- }
- pbPtr += dwKeyMaterial;
-
- /* skip reserved byte */
- pbPtr += 1;
-
- /* Generate random data for the rest of the buffer */
- if((rndBlobSize > 0) && !CryptGenRandom(hProv, rndBlobSize, pbPtr)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptGenRandom",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "rndBlobSize=%ld", rndBlobSize);
- goto done;
- }
- /* aleksey: why are we doing this? */
- for (n = 0; n < rndBlobSize; n++) {
- if (pbPtr[n] == 0) pbPtr[n] = 1;
- }
-
- /* set magic number at the end */
- keyBlob[keyBlobLen - 2] = 2;
-
- if(!CryptImportKey(hProv, keyBlob , keyBlobLen, hPrivateKey, CRYPT_EXPORTABLE, hSessionKey)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "CryptImportKey",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- "algId=%d", dwAlgId);
- goto done;
- }
-
- /* success */
- res = TRUE;
-
-done:
- if(hTempKey != 0) {
- CryptDestroyKey(hTempKey);
- }
- if(keyBlob != NULL) {
- xmlFree(keyBlob);
- }
- return(res);
-}
-