[xmlsec] adding support for HMAC with MD5, SHA1, SHA256/384/512 and MD5, RSA with MD5 in xmlsec-mscrypto
- From: Aleksey Sanin <aleksey src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [xmlsec] adding support for HMAC with MD5, SHA1, SHA256/384/512 and MD5, RSA with MD5 in xmlsec-mscrypto
- Date: Mon, 26 Apr 2010 21:43:28 +0000 (UTC)
commit a9fc9ecd394d254f4c7e8ce269d7b88ba9a8daae
Author: Aleksey Sanin <aleksey aleksey com>
Date: Mon Apr 26 14:43:06 2010 -0700
adding support for HMAC with MD5, SHA1, SHA256/384/512 and MD5, RSA with MD5 in xmlsec-mscrypto
ChangeLog | 4 +
TODO | 45 ++++-
docs/xmldsig.html | 15 +-
include/xmlsec/mscrypto/crypto.h | 119 +++++++++-
include/xmlsec/mscrypto/keysstore.h | 12 +
src/mscrypto/Makefile.am | 1 +
src/mscrypto/README | 5 -
src/mscrypto/ciphers.c | 395 +-----------------------------
src/mscrypto/crypto.c | 65 ++++-
src/mscrypto/digests.c | 71 ++++++-
src/mscrypto/signatures.c | 133 +++++++++--
src/mscrypto/symkeys.c | 463 ++++++++++++++++++++++++++++++++++-
win32/Makefile.msvc | 2 +
13 files changed, 883 insertions(+), 447 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 2739f89..b76e1ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-26 Aleksey Sanin <aleksey aleksey com>
+ * Added support for HMAC with MD5, SHA1, SHA256/384/512 in xmlsec-mscrypto
+ * Added support for MD5 RSA/MD5 in xmlsec-mscrypto
+
2010-04-25 Aleksey Sanin <aleksey aleksey com>
* Added support for SHA256/384/512 for digest, HMAC and RSA in xmlsec-nss
(requires nss 3.8 + nspr 4.3 or greater)
diff --git a/TODO b/TODO
index 0fd14ac..53a5485 100644
--- a/TODO
+++ b/TODO
@@ -32,6 +32,49 @@ merlin-xmlenc-five/encrypt-data-tripledes-cbc-rsa-oaep-mgf1p
merlin-xmldsig-twenty-three/signature-x509-crt-crl
-* xmlsec-mscrypto (April 25, 2010)
+* xmlsec-mscrypto (April 26, 2010)
+** Skipped tests due to missing transforms: RIPEMD160, SHA224, RSA/OAEP,
+AES and DES KW
+
+aleksey-xmldsig-01/enveloping-ripemd160-hmac-ripemd160
+aleksey-xmldsig-01/enveloping-ripemd160-hmac-ripemd160-64
+aleksey-xmldsig-01/enveloping-sha224-hmac-sha224
+aleksey-xmldsig-01/enveloping-sha224-hmac-sha224-64
+aleksey-xmldsig-01/enveloping-ripemd160-rsa-ripemd160
+aleksey-xmldsig-01/enveloping-sha224-rsa-sha224
+
+merlin-xmlenc-five/encsig-ripemd160-hmac-ripemd160-kw-tripledes
+merlin-xmlenc-five/encsig-sha256-hmac-sha256-kw-aes128
+merlin-xmlenc-five/encsig-sha384-hmac-sha384-kw-aes192
+merlin-xmlenc-five/encsig-sha512-hmac-sha512-kw-aes256
+aleksey-xmlenc-01/enc-des3cbc-aes192-keyname
+merlin-xmlenc-five/encrypt-data-tripledes-cbc-rsa-oaep-mgf1p
+merlin-xmlenc-five/encrypt-data-aes256-cbc-kw-tripledes
+merlin-xmlenc-five/encrypt-content-aes128-cbc-kw-aes192
+merlin-xmlenc-five/encrypt-data-aes192-cbc-kw-aes256
+merlin-xmlenc-five/encrypt-element-tripledes-cbc-kw-aes128
+merlin-xmlenc-five/encrypt-element-aes256-cbc-retrieved-kw-aes256
+01-phaos-xmlenc-3/enc-element-3des-kt-rsa_oaep_sha1
+01-phaos-xmlenc-3/enc-element-aes128-kt-rsa_oaep_sha1
+01-phaos-xmlenc-3/enc-element-aes192-kt-rsa_oaep_sha1
+01-phaos-xmlenc-3/enc-element-3des-kt-rsa_oaep_sha1
+01-phaos-xmlenc-3/enc-element-aes128-kt-rsa_oaep_sha1
+01-phaos-xmlenc-3/enc-element-aes192-kt-rsa_oaep_sha1
+01-phaos-xmlenc-3/enc-text-aes256-kt-rsa_oaep_sha1
+01-phaos-xmlenc-3/enc-element-3des-kw-3des
+01-phaos-xmlenc-3/enc-content-aes128-kw-3des
+01-phaos-xmlenc-3/enc-element-aes128-kw-aes128
+01-phaos-xmlenc-3/enc-element-aes128-kw-aes256
+01-phaos-xmlenc-3/enc-content-3des-kw-aes192
+01-phaos-xmlenc-3/enc-content-aes192-kw-aes256
+01-phaos-xmlenc-3/enc-element-aes192-kw-aes192
+01-phaos-xmlenc-3/enc-element-aes256-kw-aes256
+01-phaos-xmlenc-3/enc-text-3des-kw-aes256
+01-phaos-xmlenc-3/enc-text-aes128-kw-aes192
+
+** Failed tests due to no GOST crypto providers on test machine
+
+aleksey-xmldsig-01/enveloped-gost
+
diff --git a/docs/xmldsig.html b/docs/xmldsig.html
index b70a00f..a00f2b5 100644
--- a/docs/xmldsig.html
+++ b/docs/xmldsig.html
@@ -423,7 +423,7 @@ MSCrypto</b> </td>
</td>
<td style="vertical-align: top;">N<br>
</td>
- <td style="vertical-align: top;">N<br>
+ <td style="vertical-align: top;">Y<br>
</td>
</tr>
<tr>
@@ -483,7 +483,7 @@ MSCrypto</b> </td>
</td>
<td style="vertical-align: top;">Y<br>
</td>
- <td style="vertical-align: top;">N<br>
+ <td style="vertical-align: top;">Y<br>
</td>
</tr>
<tr>
@@ -506,7 +506,7 @@ MSCrypto</b> </td>
</td>
<td style="vertical-align: top;">N<br>
</td>
- <td style="vertical-align: top;">N<br>
+ <td style="vertical-align: top;">Y<br>
</td>
</tr>
<tr>
@@ -517,7 +517,7 @@ MSCrypto</b> </td>
</td>
<td style="vertical-align: top;">N<br>
</td>
- <td style="vertical-align: top;">N<br>
+ <td style="vertical-align: top;">Y<br>
</td>
</tr>
<tr>
@@ -528,7 +528,7 @@ MSCrypto</b> </td>
</td>
<td style="vertical-align: top;">N<br>
</td>
- <td style="vertical-align: top;">N<br>
+ <td style="vertical-align: top;">Y<br>
</td>
</tr>
<tr>
@@ -552,7 +552,7 @@ MSCrypto</b> </td>
</td>
<td style="vertical-align: top;">N<br>
</td>
- <td style="vertical-align: top;">N<br>
+ <td style="vertical-align: top;">Y<br>
</td>
</tr>
<tr>
@@ -728,8 +728,7 @@ MSCrypto</b> </td>
</td>
</tr>
<tr>
-<td style="vertical-align: top; width: 40%;">Minimal
-C14N (deprecated) </td>
+<td style="vertical-align: top; width: 40%;">Minimal C14N (deprecated) </td>
<td style="vertical-align: top;">N<br>
</td>
<td style="vertical-align: top;">N<br>
diff --git a/include/xmlsec/mscrypto/crypto.h b/include/xmlsec/mscrypto/crypto.h
index 0d69935..cf6c17b 100644
--- a/include/xmlsec/mscrypto/crypto.h
+++ b/include/xmlsec/mscrypto/crypto.h
@@ -151,46 +151,60 @@ XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformGost2001GostR3411_
xmlSecMSCryptoKeyDataRsaGetKlass()
XMLSEC_CRYPTO_EXPORT xmlSecKeyDataId xmlSecMSCryptoKeyDataRsaGetKlass(void);
+#ifndef XMLSEC_NO_MD5
+/**
+ * xmlSecMSCryptoTransformRsaMd5Id:
+ *
+ * The RSA-MD5 signature transform klass.
+ */
+#define xmlSecMSCryptoTransformRsaMd5Id \
+ xmlSecMSCryptoTransformRsaMd5GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformRsaMd5GetKlass(void);
+#endif /* XMLSEC_NO_MD5 */
+#ifndef XMLSEC_NO_SHA1
/**
* xmlSecMSCryptoTransformRsaSha1Id:
*
* The RSA-SHA1 signature transform klass.
*/
-
#define xmlSecMSCryptoTransformRsaSha1Id \
xmlSecMSCryptoTransformRsaSha1GetKlass()
XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformRsaSha1GetKlass(void);
+#endif /* XMLSEC_NO_SHA1 */
+#ifndef XMLSEC_NO_SHA256
/**
* xmlSecMSCryptoTransformRsaSha256Id:
*
* The RSA-SHA256 signature transform klass.
*/
-
#define xmlSecMSCryptoTransformRsaSha256Id \
xmlSecMSCryptoTransformRsaSha256GetKlass()
XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformRsaSha256GetKlass(void);
+#endif /* XMLSEC_NO_SHA256 */
+#ifndef XMLSEC_NO_SHA384
/**
* xmlSecMSCryptoTransformRsaSha384Id:
*
* The RSA-SHA384 signature transform klass.
*/
-
#define xmlSecMSCryptoTransformRsaSha384Id \
xmlSecMSCryptoTransformRsaSha384GetKlass()
XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformRsaSha384GetKlass(void);
+#endif /* XMLSEC_NO_SHA384 */
+#ifndef XMLSEC_NO_SHA512
/**
* xmlSecMSCryptoTransformRsaSha512Id:
*
* The RSA-SHA512 signature transform klass.
*/
-
#define xmlSecMSCryptoTransformRsaSha512Id \
xmlSecMSCryptoTransformRsaSha512GetKlass()
XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformRsaSha512GetKlass(void);
+#endif /* XMLSEC_NO_SHA512 */
/**
* xmlSecMSCryptoTransformRsaPkcs1Id:
@@ -213,6 +227,23 @@ XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformRsaOaepGetKlass(vo
*/
#endif /* XMLSEC_NO_RSA */
+/********************************************************************
+ *
+ * Md5 transforms
+ *
+ *******************************************************************/
+#ifndef XMLSEC_NO_MD5
+/**
+ * xmlSecMSCryptoTransformMd5Id:
+ *
+ * The MD5 digest transform klass.
+ */
+#define xmlSecMSCryptoTransformMd5Id \
+ xmlSecMSCryptoTransformMd5GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformMd5GetKlass(void);
+#endif /* XMLSEC_NO_MD5 */
+
+
/********************************************************************
*
* SHA1 transform
@@ -370,9 +401,87 @@ XMLSEC_CRYPTO_EXPORT xmlSecKeyDataId xmlSecMSCryptoKeyDataDesGetKlass(void);
xmlSecMSCryptoTransformDes3CbcGetKlass()
XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformDes3CbcGetKlass(void);
+#endif /* XMLSEC_NO_DES */
-#endif /* XMLSEC_NO_DES */
+/********************************************************************
+ *
+ * HMAC transforms
+ *
+ *******************************************************************/
+#ifndef XMLSEC_NO_HMAC
+
+XMLSEC_CRYPTO_EXPORT int xmlSecMSCryptoHmacGetMinOutputLength(void);
+XMLSEC_CRYPTO_EXPORT void xmlSecMSCryptoHmacSetMinOutputLength(int min_length);
+
+/**
+ * xmlSecMSCryptoKeyDataHmacId:
+ *
+ * The DHMAC key klass.
+ */
+#define xmlSecMSCryptoKeyDataHmacId \
+ xmlSecMSCryptoKeyDataHmacGetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecKeyDataId xmlSecMSCryptoKeyDataHmacGetKlass(void);
+XMLSEC_CRYPTO_EXPORT int xmlSecMSCryptoKeyDataHmacSet (xmlSecKeyDataPtr data,
+ const xmlSecByte* buf,
+ xmlSecSize bufSize);
+
+#ifndef XMLSEC_NO_MD5
+/**
+ * xmlSecMSCryptoTransformHmacMd5Id:
+ *
+ * The HMAC with MD5 signature transform klass.
+ */
+#define xmlSecMSCryptoTransformHmacMd5Id \
+ xmlSecMSCryptoTransformHmacMd5GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformHmacMd5GetKlass(void);
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_SHA1
+/**
+ * xmlSecMSCryptoTransformHmacSha1Id:
+ *
+ * The HMAC with SHA1 signature transform klass.
+ */
+#define xmlSecMSCryptoTransformHmacSha1Id \
+ xmlSecMSCryptoTransformHmacSha1GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformHmacSha1GetKlass(void);
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+/**
+ * xmlSecMSCryptoTransformHmacSha256Id:
+ *
+ * The HMAC with SHA256 signature transform klass.
+ */
+#define xmlSecMSCryptoTransformHmacSha256Id \
+ xmlSecMSCryptoTransformHmacSha256GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformHmacSha256GetKlass(void);
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+/**
+ * xmlSecMSCryptoTransformHmacSha384Id:
+ *
+ * The HMAC with SHA384 signature transform klass.
+ */
+#define xmlSecMSCryptoTransformHmacSha384Id \
+ xmlSecMSCryptoTransformHmacSha384GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformHmacSha384GetKlass(void);
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+/**
+ * xmlSecMSCryptoTransformHmacSha512Id:
+ *
+ * The HMAC with SHA512 signature transform klass.
+ */
+#define xmlSecMSCryptoTransformHmacSha512Id \
+ xmlSecMSCryptoTransformHmacSha512GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformHmacSha512GetKlass(void);
+#endif /* XMLSEC_NO_SHA512 */
+
+#endif /* XMLSEC_NO_HMAC */
#ifdef __cplusplus
}
diff --git a/include/xmlsec/mscrypto/keysstore.h b/include/xmlsec/mscrypto/keysstore.h
index bd38547..867a6f7 100644
--- a/include/xmlsec/mscrypto/keysstore.h
+++ b/include/xmlsec/mscrypto/keysstore.h
@@ -38,6 +38,18 @@ XMLSEC_CRYPTO_EXPORT int xmlSecMSCryptoKeysStoreSave (xmlSecK
const char *filename,
xmlSecKeyDataType type);
+
+/* keys */
+XMLSEC_CRYPTO_EXPORT BOOL xmlSecMSCryptoCreatePrivateExponentOneKey (HCRYPTPROV hProv,
+ HCRYPTKEY *hPrivateKey);
+
+XMLSEC_CRYPTO_EXPORT BOOL xmlSecMSCryptoImportPlainSessionBlob (HCRYPTPROV hProv,
+ HCRYPTKEY hPrivateKey,
+ ALG_ID dwAlgId,
+ LPBYTE pbKeyMaterial,
+ DWORD dwKeyMaterial,
+ HCRYPTKEY *hSessionKey);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/src/mscrypto/Makefile.am b/src/mscrypto/Makefile.am
index 318af51..b471bb6 100644
--- a/src/mscrypto/Makefile.am
+++ b/src/mscrypto/Makefile.am
@@ -25,6 +25,7 @@ libxmlsec1_mscrypto_la_SOURCES =\
ciphers.c \
crypto.c \
digests.c \
+ hmac.c \
keysstore.c \
kt_rsa.c \
signatures.c \
diff --git a/src/mscrypto/README b/src/mscrypto/README
index e7b8d63..3086024 100644
--- a/src/mscrypto/README
+++ b/src/mscrypto/README
@@ -34,11 +34,6 @@ KNOWN ISSUES.
(http://bugzilla.gnome.org/show_bug.cgi?id=123668).
2) Missing crypto functionality:
- - HMAC (http://bugzilla.gnome.org/show_bug.cgi?id=123670): does not look
- like MS would support it soon.
-
- See - http://msdn.microsoft.com/en-us/library/Aa379863
-
- RSA-OAEP (http://bugzilla.gnome.org/show_bug.cgi?id=123671): MS says
that they will support this in the near future.
- AES KW (http://bugzilla.gnome.org/show_bug.cgi?id=123672): no native
diff --git a/src/mscrypto/ciphers.c b/src/mscrypto/ciphers.c
index b4601aa..aa34452 100644
--- a/src/mscrypto/ciphers.c
+++ b/src/mscrypto/ciphers.c
@@ -26,14 +26,6 @@
#endif
-static BOOL xmlSecMSCryptoCreatePrivateExponentOneKey (HCRYPTPROV hProv,
- HCRYPTKEY *hPrivateKey);
-static BOOL xmlSecMSCryptoImportPlainSessionBlob (HCRYPTPROV hProv,
- HCRYPTKEY hPrivateKey,
- ALG_ID dwAlgId,
- LPBYTE pbKeyMaterial,
- DWORD dwKeyMaterial,
- HCRYPTKEY *hSessionKey);
/**************************************************************************
*
@@ -645,9 +637,9 @@ xmlSecMSCryptoBlockCipherSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key)
ctx = xmlSecMSCryptoBlockCipherGetCtx(transform);
xmlSecAssert2(ctx != NULL, -1);
xmlSecAssert2(ctx->keyInitialized == 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));
@@ -947,388 +939,3 @@ xmlSecMSCryptoTransformDes3CbcGetKlass(void) {
}
#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);
-}
-
diff --git a/src/mscrypto/crypto.c b/src/mscrypto/crypto.c
index b3d9e8d..5b44e18 100644
--- a/src/mscrypto/crypto.c
+++ b/src/mscrypto/crypto.c
@@ -70,19 +70,12 @@ xmlSecCryptoGetFunctions_mscrypto(void) {
#ifndef XMLSEC_NO_RSA
gXmlSecMSCryptoFunctions->keyDataRsaGetKlass = xmlSecMSCryptoKeyDataRsaGetKlass;
-
-#ifndef XMLSEC_NO_SHA256
- gXmlSecMSCryptoFunctions->transformRsaSha256GetKlass = xmlSecMSCryptoTransformRsaSha256GetKlass;
-#endif /* XMLSEC_NO_SHA256 */
-#ifndef XMLSEC_NO_SHA384
- gXmlSecMSCryptoFunctions->transformRsaSha384GetKlass = xmlSecMSCryptoTransformRsaSha384GetKlass;
-#endif /* XMLSEC_NO_SHA384 */
-#ifndef XMLSEC_NO_SHA512
- gXmlSecMSCryptoFunctions->transformRsaSha512GetKlass = xmlSecMSCryptoTransformRsaSha512GetKlass;
-#endif /* XMLSEC_NO_SHA512 */
-
#endif /* XMLSEC_NO_RSA */
+#ifndef XMLSEC_NO_HMAC
+ gXmlSecMSCryptoFunctions->keyDataHmacGetKlass = xmlSecMSCryptoKeyDataHmacGetKlass;
+#endif /* XMLSEC_NO_HMAC */
+
#ifndef XMLSEC_NO_DSA
gXmlSecMSCryptoFunctions->keyDataDsaGetKlass = xmlSecMSCryptoKeyDataDsaGetKlass;
#endif /* XMLSEC_NO_DSA */
@@ -117,7 +110,27 @@ xmlSecCryptoGetFunctions_mscrypto(void) {
#endif /* XMLSEC_NO_DES */
#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_SMD5
+ gXmlSecMSCryptoFunctions->transformRsaMd5GetKlass = xmlSecMSCryptoTransformRsaMd5GetKlass;
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_SHA1
gXmlSecMSCryptoFunctions->transformRsaSha1GetKlass = xmlSecMSCryptoTransformRsaSha1GetKlass;
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+ gXmlSecMSCryptoFunctions->transformRsaSha256GetKlass = xmlSecMSCryptoTransformRsaSha256GetKlass;
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+ gXmlSecMSCryptoFunctions->transformRsaSha384GetKlass = xmlSecMSCryptoTransformRsaSha384GetKlass;
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+ gXmlSecMSCryptoFunctions->transformRsaSha512GetKlass = xmlSecMSCryptoTransformRsaSha512GetKlass;
+#endif /* XMLSEC_NO_SHA512 */
+
gXmlSecMSCryptoFunctions->transformRsaPkcs1GetKlass = xmlSecMSCryptoTransformRsaPkcs1GetKlass;
#endif /* XMLSEC_NO_RSA */
@@ -142,6 +155,36 @@ xmlSecCryptoGetFunctions_mscrypto(void) {
gXmlSecMSCryptoFunctions->transformSha512GetKlass = xmlSecMSCryptoTransformSha512GetKlass;
#endif /* XMLSEC_NO_SHA512 */
+
+ /******************************* MD5 ********************************/
+#ifndef XMLSEC_NO_MD5
+ gXmlSecMSCryptoFunctions->transformMd5GetKlass = xmlSecMSCryptoTransformMd5GetKlass;
+#endif /* XMLSEC_NO_MD5 */
+
+ /******************************* HMAC ********************************/
+#ifndef XMLSEC_NO_HMAC
+#ifndef XMLSEC_NO_MD5
+ gXmlSecMSCryptoFunctions->transformHmacMd5GetKlass = xmlSecMSCryptoTransformHmacMd5GetKlass;
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_SHA1
+ gXmlSecMSCryptoFunctions->transformHmacSha1GetKlass = xmlSecMSCryptoTransformHmacSha1GetKlass;
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+ gXmlSecMSCryptoFunctions->transformHmacSha256GetKlass = xmlSecMSCryptoTransformHmacSha256GetKlass;
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+ gXmlSecMSCryptoFunctions->transformHmacSha384GetKlass = xmlSecMSCryptoTransformHmacSha384GetKlass;
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+ gXmlSecMSCryptoFunctions->transformHmacSha512GetKlass = xmlSecMSCryptoTransformHmacSha512GetKlass;
+#endif /* XMLSEC_NO_SHA512 */
+
+#endif /* XMLSEC_NO_HMAC */
+
#ifndef XMLSEC_NO_GOST
gXmlSecMSCryptoFunctions->transformGostR3411_94GetKlass = xmlSecMSCryptoTransformGostR3411_94GetKlass;
#endif /* XMLSEC_NO_GOST */
diff --git a/src/mscrypto/digests.c b/src/mscrypto/digests.c
index 7fa7581..7e2c500 100644
--- a/src/mscrypto/digests.c
+++ b/src/mscrypto/digests.c
@@ -80,6 +80,13 @@ static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Sha2[] = {
{ NULL, 0 }
};
+static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Md5[] = {
+ { MS_STRONG_PROV, PROV_RSA_FULL },
+ { MS_ENHANCED_PROV, PROV_RSA_FULL },
+ { MS_DEF_PROV, PROV_RSA_FULL },
+ { NULL, 0 }
+};
+
static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Gost[] = {
{ MAGPRO_CSP, PROV_MAGPRO_GOST },
{ CRYPTOPRO_CSP, PROV_CRYPTOPRO_GOST },
@@ -88,6 +95,13 @@ static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Gost[] = {
static int
xmlSecMSCryptoDigestCheckId(xmlSecTransformPtr transform) {
+
+#ifndef XMLSEC_NO_MD5
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformMd5Id)) {
+ return(1);
+ }
+#endif /* XMLSEC_NO_MD5 */
+
#ifndef XMLSEC_NO_SHA1
if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformSha1Id)) {
return(1);
@@ -134,9 +148,16 @@ xmlSecMSCryptoDigestInitialize(xmlSecTransformPtr transform) {
/* initialize context */
memset(ctx, 0, sizeof(xmlSecMSCryptoDigestCtx));
+#ifndef XMLSEC_NO_MD5
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformMd5Id)) {
+ ctx->alg_id = CALG_MD5;
+ ctx->providers = xmlSecMSCryptoProviderInfo_Md5;
+ } else
+#endif /* XMLSEC_NO_MD5 */
+
#ifndef XMLSEC_NO_SHA1
if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformSha1Id)) {
- ctx->alg_id = CALG_SHA;
+ ctx->alg_id = CALG_SHA1;
ctx->providers = xmlSecMSCryptoProviderInfo_Sha1;
} else
#endif /* XMLSEC_NO_SHA1 */
@@ -203,7 +224,9 @@ static void xmlSecMSCryptoDigestFinalize(xmlSecTransformPtr transform) {
if(ctx->mscHash != 0) {
CryptDestroyHash(ctx->mscHash);
}
- CryptReleaseContext(ctx->provider, 0);
+ if(ctx->provider != 0) {
+ CryptReleaseContext(ctx->provider, 0);
+ }
memset(ctx, 0, sizeof(xmlSecMSCryptoDigestCtx));
}
@@ -376,6 +399,50 @@ xmlSecMSCryptoDigestExecute(xmlSecTransformPtr transform,
}
+#ifndef XMLSEC_NO_MD5
+/******************************************************************************
+ *
+ * MD5
+ *
+ *****************************************************************************/
+static xmlSecTransformKlass xmlSecMSCryptoMd5Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* size_t klassSize */
+ xmlSecMSCryptoDigestSize, /* size_t objSize */
+
+ xmlSecNameMd5, /* const xmlChar* name; */
+ xmlSecHrefMd5, /* const xmlChar* href; */
+ xmlSecTransformUsageDigestMethod, /* xmlSecTransformUsage usage; */
+ xmlSecMSCryptoDigestInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecMSCryptoDigestFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ NULL, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecMSCryptoDigestVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoDigestExecute, /* xmlSecTransformExecuteMethod execute; */
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecMSCryptoTransformMd5GetKlass:
+ *
+ * SHA-1 digest transform klass.
+ *
+ * Returns: pointer to SHA-1 digest transform klass.
+ */
+xmlSecTransformId
+xmlSecMSCryptoTransformMd5GetKlass(void) {
+ return(&xmlSecMSCryptoMd5Klass);
+}
+#endif /* XMLSEC_NO_MD5 */
+
#ifndef XMLSEC_NO_SHA1
/******************************************************************************
*
diff --git a/src/mscrypto/signatures.c b/src/mscrypto/signatures.c
index 005ea6c..72aaef7 100644
--- a/src/mscrypto/signatures.c
+++ b/src/mscrypto/signatures.c
@@ -83,33 +83,52 @@ static int xmlSecMSCryptoSignatureCheckId(xmlSecTransformPtr transform) {
}
#endif /* XMLSEC_NO_DSA */
-#ifndef XMLSEC_NO_GOST
- if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2001GostR3411_94Id)) {
+#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaMd5Id)) {
return(1);
- }
-#endif /* XMLSEC_NO_GOST*/
+ } else
+#endif /* XMLSEC_NO_MD5 */
-#ifndef XMLSEC_NO_RSA
+#ifndef XMLSEC_NO_SHA1
if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha1Id)) {
return(1);
- }
+ } else
+#endif /* XMLSEC_NO_SHA1 */
+
#ifndef XMLSEC_NO_SHA256
if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha256Id)) {
return(1);
- }
+ } else
#endif /* XMLSEC_NO_SHA256 */
+
#ifndef XMLSEC_NO_SHA384
if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha384Id)) {
return(1);
- }
+ } else
#endif /* XMLSEC_NO_SHA384 */
+
#ifndef XMLSEC_NO_SHA512
if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha512Id)) {
return(1);
- }
+ } else
#endif /* XMLSEC_NO_SHA512 */
+
#endif /* XMLSEC_NO_RSA */
+#ifndef XMLSEC_NO_GOST
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformGost2001GostR3411_94Id)) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_GOST*/
+
+
+ /* not found */
+ {
+ return(0);
+ }
+
return(0);
}
@@ -124,11 +143,29 @@ static int xmlSecMSCryptoSignatureInitialize(xmlSecTransformPtr transform) {
memset(ctx, 0, sizeof(xmlSecMSCryptoSignatureCtx));
+
+#ifndef XMLSEC_NO_DSA
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformDsaSha1Id)) {
+ ctx->digestAlgId = CALG_SHA1;
+ ctx->keyId = xmlSecMSCryptoKeyDataDsaId;
+ } else
+#endif /* XMLSEC_NO_DSA */
+
#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaMd5Id)) {
+ ctx->digestAlgId = CALG_MD5;
+ ctx->keyId = xmlSecMSCryptoKeyDataRsaId;
+ } else
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_SHA1
if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha1Id)) {
ctx->digestAlgId = CALG_SHA1;
ctx->keyId = xmlSecMSCryptoKeyDataRsaId;
} else
+#endif /* XMLSEC_NO_SHA1 */
#ifndef XMLSEC_NO_SHA256
if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha256Id)) {
@@ -160,14 +197,8 @@ static int xmlSecMSCryptoSignatureInitialize(xmlSecTransformPtr transform) {
} else
#endif /* XMLSEC_NO_GOST*/
-#ifndef XMLSEC_NO_DSA
- if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformDsaSha1Id)) {
- ctx->digestAlgId = CALG_SHA1;
- ctx->keyId = xmlSecMSCryptoKeyDataDsaId;
- } else
-#endif /* XMLSEC_NO_DSA */
-
- if(1) {
+ /* not found */
+ {
xmlSecError(XMLSEC_ERRORS_HERE,
xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
NULL,
@@ -308,9 +339,18 @@ static int xmlSecMSCryptoSignatureVerify(xmlSecTransformPtr transform,
/* Reverse the sig - Windows stores integers as octet streams in little endian
* order. The I2OSP algorithm used by XMLDSig to store integers is big endian */
#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+ if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaMd5Id)) {
+ ConvertEndian(data, tmpBuf, dataSize);
+ } else
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_SHA1
if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha1Id)) {
ConvertEndian(data, tmpBuf, dataSize);
} else
+#endif /* XMLSEC_NO_SHA1 */
#ifndef XMLSEC_NO_SHA256
if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha256Id)) {
@@ -529,9 +569,18 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
/* Reverse the sig - Windows stores integers as octet streams in little endian
* order. The I2OSP algorithm used by XMLDSig to store integers is big endian */
#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+ if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaMd5Id)) {
+ ConvertEndian(tmpBuf, outBuf, outSize);
+ } else
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_SHA1
if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha1Id)) {
ConvertEndian(tmpBuf, outBuf, outSize);
} else
+#endif /* XMLSEC_NO_SHA1 */
#ifndef XMLSEC_NO_SHA256
if (xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformRsaSha256Id)) {
@@ -551,7 +600,6 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
} else
#endif /* XMLSEC_NO_SHA512 */
-
#endif /* XMLSEC_NO_RSA*/
#ifndef XMLSEC_NO_DSA
@@ -599,6 +647,54 @@ xmlSecMSCryptoSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+/****************************************************************************
+ *
+ * RSA-MD5 signature transform
+ *
+ ***************************************************************************/
+static xmlSecTransformKlass xmlSecMSCryptoRsaMd5Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecMSCryptoSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameRsaMd5, /* const xmlChar* name; */
+ xmlSecHrefRsaMd5, /* 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; */
+};
+
+/**
+ * xmlSecMSCryptoTransformRsaMd5GetKlass:
+ *
+ * The RSA-MD5 signature transform klass.
+ *
+ * Returns: RSA-MD5 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecMSCryptoTransformRsaMd5GetKlass(void) {
+ return(&xmlSecMSCryptoRsaMd5Klass);
+}
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_SHA1
/****************************************************************************
*
* RSA-SHA1 signature transform
@@ -642,6 +738,7 @@ xmlSecTransformId
xmlSecMSCryptoTransformRsaSha1GetKlass(void) {
return(&xmlSecMSCryptoRsaSha1Klass);
}
+#endif /* XMLSEC_NO_SHA1 */
#ifndef XMLSEC_NO_SHA256
/****************************************************************************
diff --git a/src/mscrypto/symkeys.c b/src/mscrypto/symkeys.c
index 259db44..d42144e 100644
--- a/src/mscrypto/symkeys.c
+++ b/src/mscrypto/symkeys.c
@@ -160,7 +160,7 @@ static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataDesKlass = {
/* data */
xmlSecNameDESKeyValue,
xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
- /* xmlSecKeyDataUsage usage; */
+ /* xmlSecKeyDataUsage usage; */
xmlSecHrefDESKeyValue, /* const xmlChar* href; */
xmlSecNodeDESKeyValue, /* const xmlChar* dataNodeName; */
xmlSecNs, /* const xmlChar* dataNodeNs; */
@@ -204,6 +204,63 @@ xmlSecMSCryptoKeyDataDesGetKlass(void) {
}
#endif /* XMLSEC_NO_DES */
+#ifndef XMLSEC_NO_HMAC
+/**************************************************************************
+ *
+ * <xmlsec:HMACKeyValue> processing
+ *
+ *************************************************************************/
+static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataHmacKlass = {
+ sizeof(xmlSecKeyDataKlass),
+ xmlSecKeyDataBinarySize,
+
+ /* data */
+ xmlSecNameHMACKeyValue,
+ xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
+ /* xmlSecKeyDataUsage usage; */
+ xmlSecHrefHMACKeyValue, /* const xmlChar* href; */
+ xmlSecNodeHMACKeyValue, /* const xmlChar* dataNodeName; */
+ xmlSecNs, /* const xmlChar* dataNodeNs; */
+
+ /* constructors/destructor */
+ xmlSecMSCryptoSymKeyDataInitialize, /* xmlSecKeyDataInitializeMethod initialize; */
+ xmlSecMSCryptoSymKeyDataDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */
+ xmlSecMSCryptoSymKeyDataFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */
+ xmlSecMSCryptoSymKeyDataGenerate, /* xmlSecKeyDataGenerateMethod generate; */
+
+ /* get info */
+ xmlSecMSCryptoSymKeyDataGetType, /* xmlSecKeyDataGetTypeMethod getType; */
+ xmlSecMSCryptoSymKeyDataGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */
+ NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */
+
+ /* read/write */
+ xmlSecMSCryptoSymKeyDataXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */
+ xmlSecMSCryptoSymKeyDataXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
+ xmlSecMSCryptoSymKeyDataBinRead, /* xmlSecKeyDataBinReadMethod binRead; */
+ xmlSecMSCryptoSymKeyDataBinWrite, /* xmlSecKeyDataBinWriteMethod binWrite; */
+
+ /* debug */
+ xmlSecMSCryptoSymKeyDataDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */
+ xmlSecMSCryptoSymKeyDataDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
+
+ /* reserved for the future */
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecMSCryptoKeyDataHmacGetKlass:
+ *
+ * The HMAC key data klass.
+ *
+ * Returns: HMAC key data klass.
+ */
+xmlSecKeyDataId
+xmlSecMSCryptoKeyDataHmacGetKlass(void) {
+ return(&xmlSecMSCryptoKeyDataHmacKlass);
+}
+#endif /* XMLSEC_NO_HMAC */
+
/*
* GENERIC HELPER FUNCTIONS
*/
@@ -317,17 +374,417 @@ xmlSecMSCryptoSymKeyDataDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
static int
xmlSecMSCryptoSymKeyDataKlassCheck(xmlSecKeyDataKlass* klass) {
+
#ifndef XMLSEC_NO_DES
if(klass == xmlSecMSCryptoKeyDataDesId) {
return(1);
- }
+ } else
#endif /* XMLSEC_NO_DES */
#ifndef XMLSEC_NO_AES
if(klass == xmlSecMSCryptoKeyDataAesId) {
return(1);
- }
+ } else
#endif /* XMLSEC_NO_AES */
+#ifndef XMLSEC_NO_HMAC
+ if(klass == xmlSecMSCryptoKeyDataHmacId) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_HMAC */
+
+ {
+ return(0);
+ }
+
return(0);
}
+
+
+
+/*
+ * 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
+ **/
+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;
+}
+
+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);
+}
+
+
diff --git a/win32/Makefile.msvc b/win32/Makefile.msvc
index 401b72e..2e1cc6f 100644
--- a/win32/Makefile.msvc
+++ b/win32/Makefile.msvc
@@ -262,6 +262,7 @@ XMLSEC_MSCRYPTO_OBJS = \
$(XMLSEC_MSCRYPTO_INTDIR)\crypto.obj \
$(XMLSEC_MSCRYPTO_INTDIR)\ciphers.obj \
$(XMLSEC_MSCRYPTO_INTDIR)\digests.obj \
+ $(XMLSEC_MSCRYPTO_INTDIR)\hmac.obj \
$(XMLSEC_MSCRYPTO_INTDIR)\symkeys.obj \
$(XMLSEC_MSCRYPTO_INTDIR)\kt_rsa.obj \
$(XMLSEC_MSCRYPTO_INTDIR)\strings.obj \
@@ -275,6 +276,7 @@ XMLSEC_MSCRYPTO_OBJS_A = \
$(XMLSEC_MSCRYPTO_INTDIR_A)\crypto.obj \
$(XMLSEC_MSCRYPTO_INTDIR_A)\ciphers.obj \
$(XMLSEC_MSCRYPTO_INTDIR_A)\digests.obj \
+ $(XMLSEC_MSCRYPTO_INTDIR_A)\hmac.obj \
$(XMLSEC_MSCRYPTO_INTDIR_A)\symkeys.obj \
$(XMLSEC_MSCRYPTO_INTDIR_A)\kt_rsa.obj \
$(XMLSEC_MSCRYPTO_INTDIR_A)\strings.obj \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]