[xmlsec] Added RSA/SHA1/SHA256/SHA384/SHA512/MD5/RIPEMD160 for xmlsec-gcrypt
- From: Aleksey Sanin <aleksey src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [xmlsec] Added RSA/SHA1/SHA256/SHA384/SHA512/MD5/RIPEMD160 for xmlsec-gcrypt
- Date: Tue, 11 May 2010 04:53:30 +0000 (UTC)
commit aefd107520d90a2b6f7360c13429a76f58144f07
Author: Aleksey Sanin <aleksey aleksey com>
Date: Mon May 10 18:35:43 2010 -0700
Added RSA/SHA1/SHA256/SHA384/SHA512/MD5/RIPEMD160 for xmlsec-gcrypt
ChangeLog | 3 +
Makefile.am | 13 +-
TODO | 5 +-
apps/xmlsec.c | 19 +-
docs/xmldsig.html | 14 +-
src/gcrypt/Makefile.am | 1 +
src/gcrypt/app.c | 482 ++++++++++++++++++-
src/gcrypt/asymkeys.c | 4 +-
src/gcrypt/crypto.c | 14 -
src/gcrypt/digests.c | 11 +-
src/gcrypt/globals.h | 4 +
src/gcrypt/signatures.c | 1182 +++++++++++++++++++++++++++++++++++++++++++++++
src/gnutls/crypto.c | 10 -
tests/testrun.sh | 60 ++-
14 files changed, 1719 insertions(+), 103 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 7cb6385..2a0fb2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2010-05-10 Aleksey Sanin <aleksey aleksey com>
+ * Added RSA/SHA1/SHA256/SHA384/SHA512/MD5/RIPEMD160 for xmlsec-gcrypt
+
2010-05-09 Aleksey Sanin <aleksey aleksey com>
* Added DES KW support for xmlsec-mscrypto
* Added DES KW support for xmlsec-gnutls
diff --git a/Makefile.am b/Makefile.am
index 11b105b..70f86eb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -64,9 +64,6 @@ if XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING
PRECHECK_COMMANDS = \
cd $(ABS_SRCDIR) \
$(NULL)
-CHECK_CRYPTO_LIST = \
- "default" \
- $(NULL)
else
PRECHECK_COMMANDS= \
for i in $(XMLSEC_CRYPTO_LIST) ; do \
@@ -74,10 +71,10 @@ PRECHECK_COMMANDS= \
done && \
cd $(ABS_SRCDIR) \
$(NULL)
+endif
CHECK_CRYPTO_LIST = \
$(XMLSEC_CRYPTO_LIST) \
$(NULL)
-endif
docs: docs-man
@(cd docs && $(MAKE) docs)
@@ -127,7 +124,7 @@ check-keys: $(TEST_APP)
@($(PRECHECK_COMMANDS) && \
$(SHELL) ./tests/testrun.sh \
$(ABS_SRCDIR)/tests/testKeys.sh \
- default \
+ $(XMLSEC_CRYPTO) \
$(ABS_SRCDIR)/tests \
$(ABS_BUILDDIR)/$(TEST_APP) \
der \
@@ -137,7 +134,7 @@ check-dsig: $(TEST_APP)
@($(PRECHECK_COMMANDS) && \
$(SHELL) ./tests/testrun.sh \
$(ABS_SRCDIR)/tests/testDSig.sh \
- default \
+ $(XMLSEC_CRYPTO) \
$(ABS_SRCDIR)/tests \
$(ABS_BUILDDIR)/$(TEST_APP) \
der \
@@ -147,7 +144,7 @@ check-enc: $(TEST_APP)
@($(PRECHECK_COMMANDS) && \
$(SHELL) ./tests/testrun.sh \
$(ABS_SRCDIR)/tests/testEnc.sh \
- default \
+ $(XMLSEC_CRYPTO) \
$(ABS_SRCDIR)/tests \
$(ABS_BUILDDIR)/$(TEST_APP) \
der \
@@ -157,7 +154,7 @@ check-xkms: $(TEST_APP)
@($(PRECHECK_COMMANDS) && \
$(SHELL) ./tests/testrun.sh \
$(ABS_SRCDIR)/tests/testXKMS.sh \
- default \
+ $(XMLSEC_CRYPTO) \
$(ABS_SRCDIR)/tests \
$(ABS_BUILDDIR)/$(TEST_APP) \
der \
diff --git a/TODO b/TODO
index 97d851e..acaa223 100644
--- a/TODO
+++ b/TODO
@@ -142,10 +142,10 @@ merlin-xmlenc-five/encrypt-data-tripledes-cbc-rsa-oaep-mgf1p
01-phaos-xmlenc-3/enc-text-aes256-kt-rsa_oaep_sha1
-------------------------------------------------
-* xmlsec-gnutls (May 09, 2010 using GnuTLS)
+* xmlsec-gcrypt (May 09, 2010 using GCrypt)
-------------------------------------------------
-** Skipped tests due to missing transforms: RSA, DSA, RSA PKCS/OAEP, X509, GOST
+** Skipped tests due to missing transforms: DSA, RSA PKCS/OAEP, X509, GOST
aleksey-xmldsig-01/enveloping-dsa-x509chain
aleksey-xmldsig-01/enveloping-rsa-x509chain
@@ -164,7 +164,6 @@ aleksey-xmldsig-01/x509data-sn-test
merlin-xmldsig-twenty-three/signature-enveloped-dsa
merlin-xmldsig-twenty-three/signature-enveloping-dsa
merlin-xmldsig-twenty-three/signature-enveloping-b64-dsa
-merlin-xmldsig-twenty-three/signature-enveloping-rsa
merlin-xmldsig-twenty-three/signature-external-b64-dsa
merlin-xmldsig-twenty-three/signature-external-dsa
merlin-xmldsig-twenty-three/signature-keyname
diff --git a/apps/xmlsec.c b/apps/xmlsec.c
index ef7c891..3aa6ebd 100644
--- a/apps/xmlsec.c
+++ b/apps/xmlsec.c
@@ -160,9 +160,8 @@ static xmlSecAppCmdLineParam helpParam = {
xmlSecAppCmdLineParamTypeFlag,
xmlSecAppCmdLineParamFlagNone,
NULL
-};
+};
-#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING)
static xmlSecAppCmdLineParam cryptoParam = {
xmlSecAppCmdLineTopicCryptoConfig,
"--crypto",
@@ -175,7 +174,6 @@ static xmlSecAppCmdLineParam cryptoParam = {
xmlSecAppCmdLineParamFlagNone,
NULL
};
-#endif /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */
static xmlSecAppCmdLineParam cryptoConfigParam = {
xmlSecAppCmdLineTopicCryptoConfig,
@@ -899,9 +897,7 @@ static xmlSecAppCmdLineParamPtr parameters[] = {
#endif /* XMLSEC_NO_X509 */
/* General configuration params */
-#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING)
&cryptoParam,
-#endif /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */
&cryptoConfigParam,
&repeatParam,
&disableErrorMsgsParam,
@@ -1061,15 +1057,22 @@ int main(int argc, const char **argv) {
default:
break;
}
-
+
/* now init the xmlsec and all other libs */
-#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING)
+ /* ignore "--crypto" if we don't have dynamic loading */
tmp = xmlSecAppCmdLineParamGetString(&cryptoParam);
+#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING)
if((tmp != NULL) && (strcmp(tmp, "default") != 0)) {
xmlsec_crypto = tmp;
}
+#else /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */
+ if((tmp != NULL) && (strcmp(tmp, xmlsec_crypto) != 0)) {
+ fprintf(stderr, "Error: dynaimc crypto libraries loading is disabled and the only available crypto library is '%s'\n", xmlsec_crypto);
+ xmlSecAppPrintUsage();
+ goto fail;
+ }
#endif /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */
-
+
if(xmlSecAppInit() < 0) {
fprintf(stderr, "Error: initialization failed\n");
xmlSecAppPrintUsage();
diff --git a/docs/xmldsig.html b/docs/xmldsig.html
index 2eaa284..5b6a589 100644
--- a/docs/xmldsig.html
+++ b/docs/xmldsig.html
@@ -345,14 +345,14 @@ X509Data)<br>
</td>
</tr>
<tr>
-<td style="width: 40%;" align="left" valign="top">RSAwithSHA1
+<td style="width: 40%;" align="left" valign="top">RSA with SHA1
<br>
</td>
<td align="left" valign="top">Y<br>
</td>
<td style="vertical-align: top;">N<br>
</td>
- <td style="vertical-align: top;">N<br>
+ <td style="vertical-align: top;">Y<br>
</td>
<td style="vertical-align: top;">Y<br>
</td>
@@ -622,7 +622,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>
<td style="vertical-align: top;">N<br>
</td>
@@ -650,7 +650,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>
<td style="vertical-align: top;">Y<br>
</td>
@@ -664,7 +664,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>
<td style="vertical-align: top;">Y<br>
</td>
@@ -678,7 +678,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>
<td style="vertical-align: top;">Y<br>
</td>
@@ -691,7 +691,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>
<td style="vertical-align: top;">N<br>
</td>
diff --git a/src/gcrypt/Makefile.am b/src/gcrypt/Makefile.am
index 0b68359..1c6d031 100644
--- a/src/gcrypt/Makefile.am
+++ b/src/gcrypt/Makefile.am
@@ -28,6 +28,7 @@ libxmlsec1_gcrypt_la_SOURCES =\
kw_des.c \
symkeys.c \
asymkeys.c \
+ signatures.c \
globals.h \
$(NULL)
diff --git a/src/gcrypt/app.c b/src/gcrypt/app.c
index 6fe32d0..7643073 100644
--- a/src/gcrypt/app.c
+++ b/src/gcrypt/app.c
@@ -20,6 +20,372 @@
#include <xmlsec/gcrypt/app.h>
#include <xmlsec/gcrypt/crypto.h>
+/**************************************************************************
+ *
+ * ASN.1 parser is taken from GCrypt tests
+ *
+ *************************************************************************/
+
+/* ASN.1 classes. */
+enum
+{
+ UNIVERSAL = 0,
+ APPLICATION = 1,
+ ASNCONTEXT = 2,
+ PRIVATE = 3
+};
+
+
+/* ASN.1 tags. */
+enum
+{
+ TAG_NONE = 0,
+ TAG_BOOLEAN = 1,
+ TAG_INTEGER = 2,
+ TAG_BIT_STRING = 3,
+ TAG_OCTET_STRING = 4,
+ TAG_NULL = 5,
+ TAG_OBJECT_ID = 6,
+ TAG_OBJECT_DESCRIPTOR = 7,
+ TAG_EXTERNAL = 8,
+ TAG_REAL = 9,
+ TAG_ENUMERATED = 10,
+ TAG_EMBEDDED_PDV = 11,
+ TAG_UTF8_STRING = 12,
+ TAG_REALTIVE_OID = 13,
+ TAG_SEQUENCE = 16,
+ TAG_SET = 17,
+ TAG_NUMERIC_STRING = 18,
+ TAG_PRINTABLE_STRING = 19,
+ TAG_TELETEX_STRING = 20,
+ TAG_VIDEOTEX_STRING = 21,
+ TAG_IA5_STRING = 22,
+ TAG_UTC_TIME = 23,
+ TAG_GENERALIZED_TIME = 24,
+ TAG_GRAPHIC_STRING = 25,
+ TAG_VISIBLE_STRING = 26,
+ TAG_GENERAL_STRING = 27,
+ TAG_UNIVERSAL_STRING = 28,
+ TAG_CHARACTER_STRING = 29,
+ TAG_BMP_STRING = 30
+};
+
+/* ASN.1 Parser object. */
+struct tag_info
+{
+ int class; /* Object class. */
+ unsigned long tag; /* The tag of the object. */
+ unsigned long length; /* Length of the values. */
+ int nhdr; /* Length of the header (TL). */
+ unsigned int ndef:1; /* The object has an indefinite length. */
+ unsigned int cons:1; /* This is a constructed object. */
+};
+
+/* Parse the buffer at the address BUFFER which consists of the number
+ of octets as stored at BUFLEN. Return the tag and the length part
+ from the TLV triplet. Update BUFFER and BUFLEN on success. Checks
+ that the encoded length does not exhaust the length of the provided
+ buffer. */
+static int
+parse_tag (xmlSecByte const **buffer, xmlSecSize *buflen, struct tag_info *ti)
+{
+ int c;
+ unsigned long tag;
+ const xmlSecByte *buf = *buffer;
+ xmlSecSize length = *buflen;
+
+ xmlSecAssert2(buffer != NULL, -1);
+ xmlSecAssert2((*buffer) != NULL, -1);
+ xmlSecAssert2(buflen != NULL, -1);
+ xmlSecAssert2(ti != NULL, -1);
+
+ ti->length = 0;
+ ti->ndef = 0;
+ ti->nhdr = 0;
+
+ /* Get the tag */
+ if (length <= 0) {
+ return(-1); /* Premature EOF. */
+ }
+ c = *buf++;
+ length--;
+ ti->nhdr++;
+
+ ti->class = (c & 0xc0) >> 6;
+ ti->cons = !!(c & 0x20);
+ tag = (c & 0x1f);
+
+ if (tag == 0x1f) {
+ tag = 0;
+ do {
+ tag <<= 7;
+ if (length <= 0) {
+ return(-1); /* Premature EOF. */
+ }
+ c = *buf++;
+ length--;
+ ti->nhdr++;
+ tag |= (c & 0x7f);
+ } while ( (c & 0x80) );
+ }
+ ti->tag = tag;
+
+ /* Get the length */
+ if(length <= 0) {
+ return -1; /* Premature EOF. */
+ }
+ c = *buf++;
+ length--;
+ ti->nhdr++;
+
+ if ( !(c & 0x80) ) {
+ ti->length = c;
+ } else if (c == 0x80) {
+ ti->ndef = 1;
+ } else if (c == 0xff) {
+ return -1; /* Forbidden length value. */
+ } else {
+ xmlSecSize len = 0;
+ int count = c & 0x7f;
+
+ for (; count; count--) {
+ len <<= 8;
+ if (length <= 0) {
+ return -1; /* Premature EOF. */
+ }
+ c = *buf++; length--;
+ ti->nhdr++;
+ len |= (c & 0xff);
+ }
+ ti->length = len;
+ }
+
+ if (ti->class == UNIVERSAL && !ti->tag) {
+ ti->length = 0;\
+ }
+
+ if (ti->length > length) {
+ return(-1); /* Data larger than buffer. */
+ }
+
+ *buffer = buf;
+ *buflen = length;
+ return(0);
+}
+
+static xmlSecKeyDataPtr
+read_private_key_file (const xmlSecByte * der, xmlSecSize derlen) {
+ xmlSecKeyDataPtr key_data = NULL;
+ gcry_sexp_t s_key = NULL;
+ gcry_error_t err;
+ struct tag_info ti;
+ gcry_mpi_t keyparms[8] = {
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL
+ } ;
+ int n_keyparms = 8;
+ int idx;
+ int ret;
+
+ /* Parse the ASN.1 structure. */
+ if(parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ {
+ printf("ERROR - TODO: invalid ASN.1 structure\n");
+ goto done;
+ }
+
+ if (parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+ {
+ printf("ERROR - TODO: invalid ASN.1 structure\n");
+ goto done;
+ }
+
+ if (ti.length != 1 || *der) {
+ /* The value of the first integer is no 0. */
+ printf("ERROR - TODO: invalid ASN.1 structure\n");
+ goto done;
+ }
+ der += ti.length; derlen -= ti.length;
+
+ for (idx=0; idx < n_keyparms; idx++) {
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+ {
+ printf("ERROR - TODO: invalid ASN.1 structure\n");
+ goto done;
+ }
+
+ err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
+ if (err) {
+ printf("ERROR - TODO\n");
+ goto done;
+ }
+ der += ti.length;
+ derlen -= ti.length;
+ }
+ if (idx != n_keyparms) {
+ /* die ("not enough RSA key parameters\n"); */
+ printf("ERROR - TODO\n");
+ goto done;
+ }
+
+ /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
+ /* First check that p < q; if not swap p and q and recompute u. */
+ if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0) {
+ gcry_mpi_swap (keyparms[3], keyparms[4]);
+ gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
+ }
+
+ /* Build the S-expression. */
+ err = gcry_sexp_build (&s_key, NULL,
+ "(key-data"
+ "(public-key(rsa(n%m)(e%m)))"
+ "(private-key(rsa(n%m)(e%m)"
+ /**/ "(d%m)(p%m)(q%m)(u%m)))"
+ ")",
+ keyparms[0], keyparms[1],
+ keyparms[0], keyparms[1],
+ keyparms[2], keyparms[3], keyparms[4], keyparms[7]
+ );
+ if (err) {
+ /* die ("error building S-expression: %s\n", gpg_strerror (err)); */
+ printf("ERROR - TODO\n");
+ goto done;
+ }
+
+ key_data = xmlSecKeyDataCreate(xmlSecGCryptKeyDataRsaId);
+ if(key_data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGCryptKeyDataRsaId");
+ goto done;
+ }
+
+ ret = xmlSecGCryptKeyDataRsaAdoptKey(key_data, s_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptKeyDataRsaAdoptKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGCryptKeyDataRsaId");
+ xmlSecKeyDataDestroy(key_data);
+ key_data = NULL;
+ goto done;
+ }
+ s_key = NULL; /* owned by key_data now */
+
+done:
+ if(s_key != NULL) {
+ gcry_sexp_release(s_key);
+ }
+
+ for (idx=0; idx < n_keyparms; idx++) {
+ if(keyparms[idx] != NULL) {
+ gcry_mpi_release (keyparms[idx]);
+ }
+ }
+
+ return(key_data);
+}
+
+#if 0
+/* Read the file FNAME assuming it is a PEM encoded public key file
+ and return an S-expression. With SHOW set, the key parameters are
+ printed. */
+static gcry_sexp_t
+read_public_key_file (const char *fname, int show)
+{
+ gcry_error_t err;
+ FILE *fp;
+ char *buffer;
+ size_t buflen;
+ const unsigned char *der;
+ size_t derlen;
+ struct tag_info ti;
+ gcry_mpi_t keyparms[2];
+ int n_keyparms = 2;
+ int idx;
+ gcry_sexp_t s_key;
+
+ fp = fopen (fname, binary_input?"rb":"r");
+ if (!fp)
+ die ("can't open `%s': %s\n", fname, strerror (errno));
+ buffer = read_file (fp, 0, &buflen);
+ if (!buffer)
+ die ("error reading `%s'\n", fname);
+ fclose (fp);
+
+ buflen = base64_decode (buffer, buflen);
+
+ /* Parse the ASN.1 structure. */
+ der = (const unsigned char*)buffer;
+ derlen = buflen;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+ /* We skip the description of the key parameters and assume it is RSA. */
+ der += ti.length; derlen -= ti.length;
+
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (ti.length < 1 || *der)
+ goto bad_asn1; /* The number of unused bits needs to be 0. */
+ der += 1; derlen -= 1;
+
+ /* Parse the BIT string. */
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+
+ for (idx=0; idx < n_keyparms; idx++)
+ {
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (show)
+ {
+ char prefix[2];
+
+ prefix[0] = idx < 2? "ne"[idx] : '?';
+ prefix[1] = 0;
+ showhex (prefix, der, ti.length);
+ }
+ err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
+ if (err)
+ die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
+ der += ti.length; derlen -= ti.length;
+ }
+ if (idx != n_keyparms)
+ die ("not enough RSA key parameters\n");
+
+ gcry_free (buffer);
+
+ /* Build the S-expression. */
+ err = gcry_sexp_build (&s_key, NULL,
+ "(public-key(rsa(n%m)(e%m)))",
+ keyparms[0], keyparms[1] );
+ if (err)
+ die ("error building S-expression: %s\n", gpg_strerror (err));
+
+ for (idx=0; idx < n_keyparms; idx++)
+ gcry_mpi_release (keyparms[idx]);
+
+ return s_key;
+
+ bad_asn1:
+ die ("invalid ASN.1 structure in `%s'\n", fname);
+ return NULL; /*NOTREACHED*/
+}
+#endif /* 0 */
+
/**
* xmlSecGCryptAppInit:
* @config: the path to GCrypt configuration (unused).
@@ -68,22 +434,52 @@ xmlSecGCryptAppKeyLoad(const char *filename, xmlSecKeyDataFormat format,
const char *pwd,
void* pwdCallback,
void* pwdCallbackCtx) {
+ xmlSecKeyPtr key;
+ xmlSecBuffer buffer;
+ int ret;
+
xmlSecAssert2(filename != NULL, NULL);
xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
+ ret = xmlSecBufferInitialize(&buffer, 4*1024);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
- if (format == xmlSecKeyDataFormatPkcs12) {
- return (xmlSecGCryptAppPkcs12Load(filename, pwd, pwdCallback,
- pwdCallbackCtx));
+ ret = xmlSecBufferReadFile(&buffer, filename);
+ if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferReadFile",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
}
- /* TODO */
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecGCryptAppKeyLoad",
- XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(NULL);
+ key = xmlSecGCryptAppKeyLoadMemory(xmlSecBufferGetData(&buffer),
+ xmlSecBufferGetSize(&buffer),
+ format, pwd, pwdCallback, pwdCallbackCtx);
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptAppKeyLoadMemory",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
+ }
+
+ /* cleanup */
+ xmlSecBufferFinalize(&buffer);
+ return(key);
}
/**
@@ -103,21 +499,67 @@ xmlSecKeyPtr
xmlSecGCryptAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
xmlSecKeyDataFormat format, const char *pwd,
void* pwdCallback, void* pwdCallbackCtx) {
+ xmlSecKeyPtr key = NULL;
+ xmlSecKeyDataPtr key_data = NULL;
+ int ret;
+
xmlSecAssert2(data != NULL, NULL);
+ xmlSecAssert2(dataSize > 0, NULL);
xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
- if (format == xmlSecKeyDataFormatPkcs12) {
- return (xmlSecGCryptAppPkcs12LoadMemory(data, dataSize, pwd,
- pwdCallback, pwdCallbackCtx));
+ switch(format) {
+ case xmlSecKeyDataFormatPem:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptAppKeyLoadMemory",
+ XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return (NULL);
+ case xmlSecKeyDataFormatDer:
+ key_data = read_private_key_file(data, dataSize);
+ break;
+#ifndef XMLSEC_NO_X509
+ case xmlSecKeyDataFormatPkcs12:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptAppKeyLoadMemory",
+ XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return (NULL);
+#endif /* XMLSEC_NO_X509 */
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_FORMAT,
+ "format=%d", format);
+ return(NULL);
}
- /* TODO */
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecGCryptAppKeyLoadMemory",
- XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(NULL);
+ key = xmlSecKeyCreate();
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDataDestroy(key_data);
+ return(NULL);
+ }
+
+ ret = xmlSecKeySetValue(key, key_data);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeySetValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "data=%s",
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(key_data)));
+ xmlSecKeyDestroy(key);
+ xmlSecKeyDataDestroy(key_data);
+ return(NULL);
+ }
+ return(key);
}
#ifndef XMLSEC_NO_X509
diff --git a/src/gcrypt/asymkeys.c b/src/gcrypt/asymkeys.c
index 0154a77..3da050f 100644
--- a/src/gcrypt/asymkeys.c
+++ b/src/gcrypt/asymkeys.c
@@ -27,7 +27,7 @@
* Helpers
*
*************************************************************************/
-static gcry_sexp_t xmlSecGCryptAsymSExpDup (gcry_sexp_t sexp);
+static gcry_sexp_t xmlSecGCryptAsymSExpDup (gcry_sexp_t sexp);
/**************************************************************************
@@ -340,7 +340,7 @@ xmlSecGCryptAsymKeyDataGetType(xmlSecKeyDataPtr data) {
xmlSecAssert2(ctx != NULL, xmlSecKeyDataTypeUnknown);
if((ctx->priv_key != NULL) && (ctx->pub_key != NULL)) {
- return (xmlSecKeyDataTypePrivate);
+ return (xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
} else if(ctx->pub_key != NULL) {
return (xmlSecKeyDataTypePublic);
}
diff --git a/src/gcrypt/crypto.c b/src/gcrypt/crypto.c
index ecd0e52..11def38 100644
--- a/src/gcrypt/crypto.c
+++ b/src/gcrypt/crypto.c
@@ -106,8 +106,6 @@ xmlSecCryptoGetFunctions_gcrypt(void) {
#endif /* XMLSEC_NO_DES */
/******************************* DSA ********************************/
-#ifdef ALEKSEY_TODO
-
#ifndef XMLSEC_NO_DSA
#ifndef XMLSEC_NO_SHA1
@@ -116,8 +114,6 @@ xmlSecCryptoGetFunctions_gcrypt(void) {
#endif /* XMLSEC_NO_DSA */
-#endif /* ALEKSEY_TODO */
-
/******************************* HMAC ********************************/
#ifndef XMLSEC_NO_HMAC
@@ -158,8 +154,6 @@ xmlSecCryptoGetFunctions_gcrypt(void) {
#endif /* XMLSEC_NO_RIPEMD160 */
/******************************* RSA ********************************/
-#ifdef ALEKSEY_TODO
-
#ifndef XMLSEC_NO_RSA
#ifndef XMLSEC_NO_MD5
@@ -174,10 +168,6 @@ xmlSecCryptoGetFunctions_gcrypt(void) {
gXmlSecGCryptFunctions->transformRsaSha1GetKlass = xmlSecGCryptTransformRsaSha1GetKlass;
#endif /* XMLSEC_NO_SHA1 */
-#ifndef XMLSEC_NO_SHA224
- gXmlSecGCryptFunctions->transformRsaSha224GetKlass = xmlSecGCryptTransformRsaSha224GetKlass;
-#endif /* XMLSEC_NO_SHA224 */
-
#ifndef XMLSEC_NO_SHA256
gXmlSecGCryptFunctions->transformRsaSha256GetKlass = xmlSecGCryptTransformRsaSha256GetKlass;
#endif /* XMLSEC_NO_SHA256 */
@@ -190,12 +180,8 @@ xmlSecCryptoGetFunctions_gcrypt(void) {
gXmlSecGCryptFunctions->transformRsaSha512GetKlass = xmlSecGCryptTransformRsaSha512GetKlass;
#endif /* XMLSEC_NO_SHA512 */
- gXmlSecGCryptFunctions->transformRsaPkcs1GetKlass = xmlSecGCryptTransformRsaPkcs1GetKlass;
- gXmlSecGCryptFunctions->transformRsaOaepGetKlass = xmlSecGCryptTransformRsaOaepGetKlass;
#endif /* XMLSEC_NO_RSA */
-#endif /* ALEKSEY_TODO */
-
/******************************* SHA ********************************/
#ifndef XMLSEC_NO_SHA1
gXmlSecGCryptFunctions->transformSha1GetKlass = xmlSecGCryptTransformSha1GetKlass;
diff --git a/src/gcrypt/digests.c b/src/gcrypt/digests.c
index caa8f26..0a14646 100644
--- a/src/gcrypt/digests.c
+++ b/src/gcrypt/digests.c
@@ -20,8 +20,6 @@
#include <xmlsec/gcrypt/app.h>
#include <xmlsec/gcrypt/crypto.h>
-#define XMLSEC_GCRYPT_MAX_DIGEST_SIZE 256
-
/**************************************************************************
*
* Internal GCRYPT Digest CTX
@@ -109,7 +107,7 @@ xmlSecGCryptDigestCheckId(xmlSecTransformPtr transform) {
static int
xmlSecGCryptDigestInitialize(xmlSecTransformPtr transform) {
xmlSecGCryptDigestCtxPtr ctx;
- gpg_err_code_t ret;
+ gpg_err_code_t err;
xmlSecAssert2(xmlSecGCryptDigestCheckId(transform), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptDigestSize), -1);
@@ -165,8 +163,9 @@ xmlSecGCryptDigestInitialize(xmlSecTransformPtr transform) {
return(-1);
}
- ret = gcry_md_open(&ctx->digestCtx, ctx->digest, GCRY_MD_FLAG_SECURE); /* we are paranoid */
- if(ret != GPG_ERR_NO_ERROR) {
+ /* create digest ctx */
+ err = gcry_md_open(&ctx->digestCtx, ctx->digest, GCRY_MD_FLAG_SECURE); /* we are paranoid */
+ if(err != GPG_ERR_NO_ERROR) {
xmlSecError(XMLSEC_ERRORS_HERE,
xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
"gcry_md_open",
@@ -275,7 +274,7 @@ xmlSecGCryptDigestExecute(xmlSecTransformPtr transform, int last, xmlSecTransfor
return(-1);
}
}
- if(last) {
+ if(last != 0) {
xmlSecByte* buf;
/* get the final digest */
diff --git a/src/gcrypt/globals.h b/src/gcrypt/globals.h
index 770b6db..13204ad 100644
--- a/src/gcrypt/globals.h
+++ b/src/gcrypt/globals.h
@@ -21,4 +21,8 @@
#define IN_XMLSEC_CRYPTO
#define XMLSEC_PRIVATE
+
+#define XMLSEC_GCRYPT_MAX_DIGEST_SIZE 256
+
+
#endif /* ! __XMLSEC_GLOBALS_H__ */
diff --git a/src/gcrypt/signatures.c b/src/gcrypt/signatures.c
new file mode 100644
index 0000000..45bdcb6
--- /dev/null
+++ b/src/gcrypt/signatures.c
@@ -0,0 +1,1182 @@
+/**
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2010 Aleksey Sanin <aleksey aleksey com>
+ */
+#include "globals.h"
+
+#include <string.h>
+
+#include <gcrypt.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gcrypt/crypto.h>
+
+
+/**************************************************************************
+ *
+ * Forward declarations for actual sign/verify implementations
+ *
+ *****************************************************************************/
+typedef int (*xmlSecGCryptPkSignMethod) (int digest,
+ xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst,
+ xmlSecSize dgstSize,
+ xmlSecBufferPtr out);
+typedef int (*xmlSecGCryptPkVerifyMethod) (int digest,
+ xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst,
+ xmlSecSize dgstSize,
+ const xmlSecByte* data,
+ xmlSecSize dataSize);
+
+#ifndef XMLSEC_NO_DSA
+static int xmlSecGCryptDsaPkSign (int digest,
+ xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst,
+ xmlSecSize dgstSize,
+ xmlSecBufferPtr out);
+static int xmlSecGCryptDsaPkVerify (int digest,
+ xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst,
+ xmlSecSize dgstSize,
+ const xmlSecByte* data,
+ xmlSecSize dataSize);
+#endif /* XMLSEC_NO_DSA */
+
+#ifndef XMLSEC_NO_RSA
+static int xmlSecGCryptRsaPkcs1PkSign (int digest,
+ xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst,
+ xmlSecSize dgstSize,
+ xmlSecBufferPtr out);
+static int xmlSecGCryptRsaPkcs1PkVerify (int digest,
+ xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst,
+ xmlSecSize dgstSize,
+ const xmlSecByte* data,
+ xmlSecSize dataSize);
+#endif /* XMLSEC_NO_RSA */
+
+
+/**************************************************************************
+ *
+ * Internal GCrypt signatures ctx
+ *
+ *****************************************************************************/
+typedef struct _xmlSecGCryptPkSignatureCtx xmlSecGCryptPkSignatureCtx,
+ *xmlSecGCryptPkSignatureCtxPtr;
+
+
+struct _xmlSecGCryptPkSignatureCtx {
+ int digest;
+ xmlSecKeyDataId keyId;
+ xmlSecGCryptPkSignMethod sign;
+ xmlSecGCryptPkVerifyMethod verify;
+
+ gcry_md_hd_t digestCtx;
+ xmlSecKeyDataPtr key_data;
+
+ xmlSecByte dgst[XMLSEC_GCRYPT_MAX_DIGEST_SIZE];
+ xmlSecSize dgstSize; /* dgst size in bytes */
+};
+
+
+/******************************************************************************
+ *
+ * Pk Signature transforms
+ *
+ * xmlSecGCryptPkSignatureCtx is located after xmlSecTransform
+ *
+ *****************************************************************************/
+#define xmlSecGCryptPkSignatureSize \
+ (sizeof(xmlSecTransform) + sizeof(xmlSecGCryptPkSignatureCtx))
+#define xmlSecGCryptPkSignatureGetCtx(transform) \
+ ((xmlSecGCryptPkSignatureCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
+
+static int xmlSecGCryptPkSignatureCheckId (xmlSecTransformPtr transform);
+static int xmlSecGCryptPkSignatureInitialize (xmlSecTransformPtr transform);
+static void xmlSecGCryptPkSignatureFinalize (xmlSecTransformPtr transform);
+static int xmlSecGCryptPkSignatureSetKeyReq (xmlSecTransformPtr transform,
+ xmlSecKeyReqPtr keyReq);
+static int xmlSecGCryptPkSignatureSetKey (xmlSecTransformPtr transform,
+ xmlSecKeyPtr key);
+static int xmlSecGCryptPkSignatureVerify (xmlSecTransformPtr transform,
+ const xmlSecByte* data,
+ xmlSecSize dataSize,
+ xmlSecTransformCtxPtr transformCtx);
+static int xmlSecGCryptPkSignatureExecute (xmlSecTransformPtr transform,
+ int last,
+ xmlSecTransformCtxPtr transformCtx);
+
+static int
+xmlSecGCryptPkSignatureCheckId(xmlSecTransformPtr transform) {
+#ifndef XMLSEC_NO_DSA
+
+#ifndef XMLSEC_NO_SHA1
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformDsaSha1Id)) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_SHA1 */
+
+#endif /* XMLSEC_NO_DSA */
+
+#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaMd5Id)) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_RIPEMD160
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaRipemd160Id)) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+#ifndef XMLSEC_NO_SHA1
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaSha1Id)) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaSha256Id)) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaSha384Id)) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaSha512Id)) {
+ return(1);
+ } else
+#endif /* XMLSEC_NO_SHA512 */
+
+#endif /* XMLSEC_NO_RSA */
+
+ {
+ return(0);
+ }
+
+ return(0);
+}
+
+static int
+xmlSecGCryptPkSignatureInitialize(xmlSecTransformPtr transform) {
+ xmlSecGCryptPkSignatureCtxPtr ctx;
+ gpg_err_code_t err;
+
+ xmlSecAssert2(xmlSecGCryptPkSignatureCheckId(transform), -1);
+ xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptPkSignatureSize), -1);
+
+ ctx = xmlSecGCryptPkSignatureGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ memset(ctx, 0, sizeof(xmlSecGCryptPkSignatureCtx));
+
+#ifndef XMLSEC_NO_DSA
+
+#ifndef XMLSEC_NO_SHA1
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformDsaSha1Id)) {
+ ctx->digest = GCRY_MD_SHA1;
+ ctx->keyId = xmlSecGCryptKeyDataDsaId;
+ ctx->sign = xmlSecGCryptDsaPkSign;
+ ctx->verify = xmlSecGCryptDsaPkVerify;
+ } else
+#endif /* XMLSEC_NO_SHA1 */
+
+#endif /* XMLSEC_NO_DSA */
+
+#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaMd5Id)) {
+ ctx->digest = GCRY_MD_MD5;
+ ctx->keyId = xmlSecGCryptKeyDataRsaId;
+ ctx->sign = xmlSecGCryptRsaPkcs1PkSign;
+ ctx->verify = xmlSecGCryptRsaPkcs1PkVerify;
+ } else
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_RIPEMD160
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaRipemd160Id)) {
+ ctx->digest = GCRY_MD_RMD160;
+ ctx->keyId = xmlSecGCryptKeyDataRsaId;
+ ctx->sign = xmlSecGCryptRsaPkcs1PkSign;
+ ctx->verify = xmlSecGCryptRsaPkcs1PkVerify;
+ } else
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+#ifndef XMLSEC_NO_SHA1
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaSha1Id)) {
+ ctx->digest = GCRY_MD_SHA1;
+ ctx->keyId = xmlSecGCryptKeyDataRsaId;
+ ctx->sign = xmlSecGCryptRsaPkcs1PkSign;
+ ctx->verify = xmlSecGCryptRsaPkcs1PkVerify;
+ } else
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaSha256Id)) {
+ ctx->digest = GCRY_MD_SHA256;
+ ctx->keyId = xmlSecGCryptKeyDataRsaId;
+ ctx->sign = xmlSecGCryptRsaPkcs1PkSign;
+ ctx->verify = xmlSecGCryptRsaPkcs1PkVerify;
+ } else
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaSha384Id)) {
+ ctx->digest = GCRY_MD_SHA384;
+ ctx->keyId = xmlSecGCryptKeyDataRsaId;
+ ctx->sign = xmlSecGCryptRsaPkcs1PkSign;
+ ctx->verify = xmlSecGCryptRsaPkcs1PkVerify;
+ } else
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+ if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformRsaSha512Id)) {
+ ctx->digest = GCRY_MD_SHA512;
+ ctx->keyId = xmlSecGCryptKeyDataRsaId;
+ ctx->sign = xmlSecGCryptRsaPkcs1PkSign;
+ ctx->verify = xmlSecGCryptRsaPkcs1PkVerify;
+ } else
+#endif /* XMLSEC_NO_SHA512 */
+
+#endif /* XMLSEC_NO_RSA */
+
+ if(1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_TRANSFORM,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* create digest ctx */
+ err = gcry_md_open(&ctx->digestCtx, ctx->digest, GCRY_MD_FLAG_SECURE); /* we are paranoid */
+ if(err != GPG_ERR_NO_ERROR) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "gcry_md_open",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ return(-1);
+ }
+
+ /* done */
+ return(0);
+}
+
+static void
+xmlSecGCryptPkSignatureFinalize(xmlSecTransformPtr transform) {
+ xmlSecGCryptPkSignatureCtxPtr ctx;
+
+ xmlSecAssert(xmlSecGCryptPkSignatureCheckId(transform));
+ xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecGCryptPkSignatureSize));
+
+ ctx = xmlSecGCryptPkSignatureGetCtx(transform);
+ xmlSecAssert(ctx != NULL);
+
+ if(ctx->key_data != NULL) {
+ xmlSecKeyDataDestroy(ctx->key_data);
+ }
+ if(ctx->digestCtx != NULL) {
+ gcry_md_close(ctx->digestCtx);
+ }
+
+ memset(ctx, 0, sizeof(xmlSecGCryptPkSignatureCtx));
+}
+
+static int
+xmlSecGCryptPkSignatureSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
+ xmlSecGCryptPkSignatureCtxPtr ctx;
+ xmlSecKeyDataPtr key_data;
+
+ xmlSecAssert2(xmlSecGCryptPkSignatureCheckId(transform), -1);
+ xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
+ xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptPkSignatureSize), -1);
+ xmlSecAssert2(key != NULL, -1);
+
+ ctx = xmlSecGCryptPkSignatureGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(ctx->keyId != NULL, -1);
+ xmlSecAssert2(xmlSecKeyCheckId(key, ctx->keyId), -1);
+
+ key_data = xmlSecKeyGetValue(key);
+ xmlSecAssert2(key_data != NULL, -1);
+
+ if(ctx->key_data != NULL) {
+ xmlSecKeyDataDestroy(ctx->key_data);
+ }
+
+ ctx->key_data = xmlSecKeyDataDuplicate(key_data);
+ if(ctx->key_data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecKeyDataDuplicate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+static int
+xmlSecGCryptPkSignatureSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) {
+ xmlSecGCryptPkSignatureCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecGCryptPkSignatureCheckId(transform), -1);
+ xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
+ xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptPkSignatureSize), -1);
+ xmlSecAssert2(keyReq != NULL, -1);
+
+ ctx = xmlSecGCryptPkSignatureGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(ctx->keyId != NULL, -1);
+
+ keyReq->keyId = ctx->keyId;
+ if(transform->operation == xmlSecTransformOperationSign) {
+ keyReq->keyType = xmlSecKeyDataTypePrivate;
+ keyReq->keyUsage = xmlSecKeyUsageSign;
+ } else {
+ keyReq->keyType = xmlSecKeyDataTypePublic;
+ keyReq->keyUsage = xmlSecKeyUsageVerify;
+ }
+ return(0);
+}
+
+
+static int
+xmlSecGCryptPkSignatureVerify(xmlSecTransformPtr transform,
+ const xmlSecByte* data, xmlSecSize dataSize,
+ xmlSecTransformCtxPtr transformCtx) {
+ xmlSecGCryptPkSignatureCtxPtr ctx;
+ int ret;
+
+ xmlSecAssert2(xmlSecGCryptPkSignatureCheckId(transform), -1);
+ xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1);
+ xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptPkSignatureSize), -1);
+ xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1);
+ xmlSecAssert2(data != NULL, -1);
+ xmlSecAssert2(transformCtx != NULL, -1);
+
+ ctx = xmlSecGCryptPkSignatureGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(ctx->sign != NULL, -1);
+ xmlSecAssert2(ctx->verify != NULL, -1);
+ xmlSecAssert2(ctx->dgstSize > 0, -1);
+ xmlSecAssert2(ctx->key_data != NULL, -1);
+
+ ret = ctx->verify(ctx->digest, ctx->key_data, ctx->dgst, ctx->dgstSize, data, dataSize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "ctx->verify",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* check result */
+ if(ret == 1) {
+ transform->status = xmlSecTransformStatusOk;
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "ctx->verify",
+ XMLSEC_ERRORS_R_DATA_NOT_MATCH,
+ "signature do not match");
+ transform->status = xmlSecTransformStatusFail;
+ }
+
+ /* done */
+ return(0);
+}
+
+static int
+xmlSecGCryptPkSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
+ xmlSecGCryptPkSignatureCtxPtr ctx;
+ xmlSecBufferPtr in, out;
+ xmlSecSize inSize;
+ xmlSecSize outSize;
+ int ret;
+
+ xmlSecAssert2(xmlSecGCryptPkSignatureCheckId(transform), -1);
+ xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
+ xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptPkSignatureSize), -1);
+ xmlSecAssert2(transformCtx != NULL, -1);
+
+ ctx = xmlSecGCryptPkSignatureGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(ctx->sign != NULL, -1);
+ xmlSecAssert2(ctx->verify != NULL, -1);
+
+ in = &(transform->inBuf);
+ out = &(transform->outBuf);
+ inSize = xmlSecBufferGetSize(in);
+ outSize = xmlSecBufferGetSize(out);
+
+ ctx = xmlSecGCryptPkSignatureGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(ctx->key_data != NULL, -1);
+
+ if(transform->status == xmlSecTransformStatusNone) {
+ /* do nothing, already initialized */
+ transform->status = xmlSecTransformStatusWorking;
+ }
+
+ if(transform->status == xmlSecTransformStatusWorking) {
+ xmlSecAssert2(outSize == 0, -1);
+
+ /* update the digest */
+ if(inSize > 0) {
+ gcry_md_write(ctx->digestCtx, xmlSecBufferGetData(in), inSize);
+
+ ret = xmlSecBufferRemoveHead(in, inSize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecBufferRemoveHead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", inSize);
+ return(-1);
+ }
+ }
+
+ /* generate digest and signature */
+ if(last != 0) {
+ xmlSecByte* buf;
+
+ /* get the final digest */
+ gcry_md_final(ctx->digestCtx);
+ buf = gcry_md_read(ctx->digestCtx, ctx->digest);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "gcry_md_read",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* copy it to our internal buffer */
+ ctx->dgstSize = gcry_md_get_algo_dlen(ctx->digest);
+ xmlSecAssert2(ctx->dgstSize > 0, -1);
+ xmlSecAssert2(ctx->dgstSize <= sizeof(ctx->dgst), -1);
+ memcpy(ctx->dgst, buf, ctx->dgstSize);
+
+ xmlSecAssert2(outSize == 0, -1);
+ if(transform->operation == xmlSecTransformOperationSign) {
+ ret = ctx->sign(ctx->digest, ctx->key_data, ctx->dgst, ctx->dgstSize, out);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "ctx->sign",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ /* done */
+ transform->status = xmlSecTransformStatusFinished;
+ }
+ }
+
+ if((transform->status == xmlSecTransformStatusWorking) || (transform->status == xmlSecTransformStatusFinished)) {
+ /* the only way we can get here is if there is no input */
+ xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_STATUS,
+ "status=%d", transform->status);
+ return(-1);
+ }
+
+ return(0);
+}
+
+#ifndef XMLSEC_NO_DSA
+
+#ifndef XMLSEC_NO_SHA1
+/****************************************************************************
+ *
+ * DSA-SHA1 signature transform
+ *
+ * http://www.w3.org/TR/xmldsig-core/#sec-SignatureAlg:
+ *
+ * The output of the DSA algorithm consists of a pair of integers
+ * usually referred by the pair (r, s). The signature value consists of
+ * the base64 encoding of the concatenation of two octet-streams that
+ * respectively result from the octet-encoding of the values r and s in
+ * that order. Integer to octet-stream conversion must be done according
+ * to the I2OSP operation defined in the RFC 2437 [PKCS1] specification
+ * with a l parameter equal to 20. For example, the SignatureValue element
+ * for a DSA signature (r, s) with values specified in hexadecimal:
+ *
+ * r = 8BAC1AB6 6410435C B7181F95 B16AB97C 92B341C0
+ * s = 41E2345F 1F56DF24 58F426D1 55B4BA2D B6DCD8C8
+ *
+ * from the example in Appendix 5 of the DSS standard would be
+ *
+ * <SignatureValue>i6watmQQQ1y3GB+VsWq5fJKzQcBB4jRfH1bfJFj0JtFVtLotttzYyA==</SignatureValue>
+ *
+ ***************************************************************************/
+static int
+xmlSecGCryptDsaPkSign(int digest, xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst, xmlSecSize dgstSize,
+ xmlSecBufferPtr out) {
+ xmlSecAssert2(key_data != NULL, -1);
+ xmlSecAssert2(dgst != NULL, -1);
+ xmlSecAssert2(dgstSize > 0, -1);
+ xmlSecAssert2(out != NULL, -1);
+
+ /* ALEKSEY_TODO */
+ return(-1);
+}
+
+static int
+xmlSecGCryptDsaPkVerify(int digest, xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst, xmlSecSize dgstSize,
+ const xmlSecByte* data, xmlSecSize dataSize) {
+ xmlSecAssert2(key_data != NULL, -1);
+ xmlSecAssert2(dgst != NULL, -1);
+ xmlSecAssert2(dgstSize > 0, -1);
+ xmlSecAssert2(data != NULL, -1);
+ xmlSecAssert2(dataSize > 0, -1);
+
+ /* ALEKSEY_TODO */
+ return(-1);
+}
+
+
+static xmlSecTransformKlass xmlSecGCryptDsaSha1Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecGCryptPkSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameDsaSha1, /* const xmlChar* name; */
+ xmlSecHrefDsaSha1, /* const xmlChar* href; */
+ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
+
+ xmlSecGCryptPkSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecGCryptPkSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecGCryptPkSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ xmlSecGCryptPkSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecGCryptPkSignatureVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecGCryptPkSignatureExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGCryptTransformDsaSha1GetKlass:
+ *
+ * The DSA-SHA1 signature transform klass.
+ *
+ * Returns: DSA-SHA1 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGCryptTransformDsaSha1GetKlass(void) {
+ return(&xmlSecGCryptDsaSha1Klass);
+}
+
+#endif /* XMLSEC_NO_SHA1 */
+
+#endif /* XMLSEC_NO_DSA */
+
+#ifndef XMLSEC_NO_RSA
+
+/****************************************************************************
+ *
+ * RSA-SHA1 signature transform
+ *
+ * http://www.w3.org/TR/xmldsig-core/#sec-SignatureAlg:
+ *
+ * The SignatureValue content for an RSA signature is the base64 [MIME]
+ * encoding of the octet string computed as per RFC 2437 [PKCS1,
+ * section 8.1.1: Signature generation for the RSASSA-PKCS1-v1_5 signature
+ * scheme]. As specified in the EMSA-PKCS1-V1_5-ENCODE function RFC 2437
+ * [PKCS1, section 9.2.1], the value input to the signature function MUST
+ * contain a pre-pended algorithm object identifier for the hash function,
+ * but the availability of an ASN.1 parser and recognition of OIDs is not
+ * required of a signature verifier. The PKCS#1 v1.5 representation appears
+ * as:
+ *
+ * CRYPT (PAD (ASN.1 (OID, DIGEST (data))))
+ *
+ * Note that the padded ASN.1 will be of the following form:
+ *
+ * 01 | FF* | 00 | prefix | hash
+ *
+ * where "|" is concatenation, "01", "FF", and "00" are fixed octets of
+ * the corresponding hexadecimal value, "hash" is the SHA1 digest of the
+ * data, and "prefix" is the ASN.1 BER SHA1 algorithm designator prefix
+ * required in PKCS1 [RFC 2437], that is,
+ *
+ * hex 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14
+ *
+ * This prefix is included to make it easier to use standard cryptographic
+ * libraries. The FF octet MUST be repeated the maximum number of times such
+ * that the value of the quantity being CRYPTed is one octet shorter than
+ * the RSA modulus.
+ *
+ ***************************************************************************/
+static int
+xmlSecGCryptRsaPkcs1PkSign(int digest, xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst, xmlSecSize dgstSize,
+ xmlSecBufferPtr out) {
+ gcry_sexp_t s_data = NULL;
+ gcry_mpi_t m_sig = NULL;
+ gcry_sexp_t s_sig = NULL;
+ gcry_sexp_t s_tmp;
+ size_t written = 0;
+ gpg_error_t err;
+ int ret;
+ int res = -1;
+
+ xmlSecAssert2(key_data != NULL, -1);
+ xmlSecAssert2(xmlSecGCryptKeyDataRsaGetPrivateKey(key_data) != NULL, -1);
+ xmlSecAssert2(dgst != NULL, -1);
+ xmlSecAssert2(dgstSize > 0, -1);
+ xmlSecAssert2(out != NULL, -1);
+
+ /* get the current digest */
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags pkcs1)(hash %s %b))",
+ gcry_md_algo_name(digest),
+ (int)dgstSize, dgst);
+ if((err != GPG_ERR_NO_ERROR) || (s_data == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(data)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ goto done;
+ }
+
+ /* create signature */
+ err = gcry_pk_sign(&s_sig, s_data, xmlSecGCryptKeyDataRsaGetPrivateKey(key_data));
+ if(err != GPG_ERR_NO_ERROR) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_pk_sign",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ goto done;
+ }
+
+ /* find signature value */
+ s_tmp = gcry_sexp_find_token(s_sig, "sig-val", 0);
+ if(s_tmp == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_find_token(sig-val)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ gcry_sexp_release(s_sig);
+ s_sig = s_tmp;
+
+ s_tmp = gcry_sexp_find_token(s_sig, "rsa", 0);
+ if(s_tmp == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_find_token(rsa)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ gcry_sexp_release(s_sig);
+ s_sig = s_tmp;
+
+ s_tmp = gcry_sexp_find_token(s_sig, "s", 0);
+ if(s_tmp == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_find_token(s)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ gcry_sexp_release(s_sig);
+ s_sig = s_tmp;
+
+ m_sig = gcry_sexp_nth_mpi(s_sig, 1, GCRYMPI_FMT_USG);
+ if(m_sig == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_nth_mpi(1)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* write out */
+ written = 0;
+ err = gcry_mpi_print(GCRYMPI_FMT_USG, NULL, 0, &written, m_sig);
+ if((err != GPG_ERR_NO_ERROR) || (written == 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_mpi_print",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ goto done;
+ }
+
+ ret = xmlSecBufferSetMaxSize(out, written + 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferSetMaxSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", (int)written + 1);
+ goto done;
+ }
+
+ written = 0;
+ err = gcry_mpi_print(GCRYMPI_FMT_USG,
+ xmlSecBufferGetData(out),
+ xmlSecBufferGetMaxSize(out),
+ &written, m_sig);
+ if((err != GPG_ERR_NO_ERROR) || (written == 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_mpi_print",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d,size=%d",
+ (int)err,
+ (int)xmlSecBufferGetMaxSize(out));
+ goto done;
+ }
+
+ ret = xmlSecBufferSetSize(out, written);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferSetSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "written=%d",
+ (int)written);
+ goto done;
+ }
+
+ /* done */
+ res = 0;
+
+done:
+ if(m_sig != NULL) {
+ gcry_mpi_release(m_sig);
+ }
+
+ if(s_data != NULL) {
+ gcry_sexp_release(s_data);
+ }
+ if(s_sig != NULL) {
+ gcry_sexp_release(s_sig);
+ }
+
+ return(res);
+}
+
+static int
+xmlSecGCryptRsaPkcs1PkVerify(int digest, xmlSecKeyDataPtr key_data,
+ const xmlSecByte* dgst, xmlSecSize dgstSize,
+ const xmlSecByte* data, xmlSecSize dataSize) {
+ gcry_sexp_t s_data = NULL;
+ gcry_mpi_t m_sig = NULL;
+ gcry_sexp_t s_sig = NULL;
+ gpg_error_t err;
+ int res = -1;
+
+ xmlSecAssert2(key_data != NULL, -1);
+ xmlSecAssert2(xmlSecGCryptKeyDataRsaGetPublicKey(key_data) != NULL, -1);
+ xmlSecAssert2(dgst != NULL, -1);
+ xmlSecAssert2(dgstSize > 0, -1);
+ xmlSecAssert2(data != NULL, -1);
+ xmlSecAssert2(dataSize > 0, -1);
+
+ /* get the current digest */
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags pkcs1)(hash %s %b))",
+ gcry_md_algo_name(digest),
+ (int)dgstSize, dgst);
+ if((err != GPG_ERR_NO_ERROR) || (s_data == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(data)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ goto done;
+ }
+
+ /* get the existing signature */
+ err = gcry_mpi_scan(&m_sig, GCRYMPI_FMT_USG, data, dataSize, NULL);
+ if((err != GPG_ERR_NO_ERROR) || (m_sig == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_mpi_scan",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ goto done;
+ }
+
+ err = gcry_sexp_build (&s_sig, NULL,
+ "(sig-val(rsa(s %m)))",
+ m_sig);
+ if((err != GPG_ERR_NO_ERROR) || (s_sig == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(sig-val)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ goto done;
+ }
+
+ /* verify signature */
+ err = gcry_pk_verify(s_sig, s_data, xmlSecGCryptKeyDataRsaGetPublicKey(key_data));
+ if(err == GPG_ERR_NO_ERROR) {
+ res = 1; /* good signature */
+ } else if(err == GPG_ERR_BAD_SIGNATURE) {
+ res = 0; /* bad signature */
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_pk_verify",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ goto done;
+ }
+
+ /* done */
+done:
+ if(m_sig != NULL) {
+ gcry_mpi_release(m_sig);
+ }
+
+ if(s_data != NULL) {
+ gcry_sexp_release(s_data);
+ }
+ if(s_sig != NULL) {
+ gcry_sexp_release(s_sig);
+ }
+
+ return(res);
+}
+
+
+#ifndef XMLSEC_NO_MD5
+/****************************************************************************
+ *
+ * RSA-MD5 signature transform
+ *
+ ***************************************************************************/
+static xmlSecTransformKlass xmlSecGCryptRsaMd5Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecGCryptPkSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameRsaMd5, /* const xmlChar* name; */
+ xmlSecHrefRsaMd5, /* const xmlChar* href; */
+ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
+
+ xmlSecGCryptPkSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecGCryptPkSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecGCryptPkSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ xmlSecGCryptPkSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecGCryptPkSignatureVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecGCryptPkSignatureExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGCryptTransformRsaMd5GetKlass:
+ *
+ * The RSA-MD5 signature transform klass.
+ *
+ * Returns: RSA-MD5 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGCryptTransformRsaMd5GetKlass(void) {
+ return(&xmlSecGCryptRsaMd5Klass);
+}
+
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_RIPEMD160
+/****************************************************************************
+ *
+ * RSA-RIPEMD160 signature transform
+ *
+ ***************************************************************************/
+static xmlSecTransformKlass xmlSecGCryptRsaRipemd160Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecGCryptPkSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameRsaRipemd160, /* const xmlChar* name; */
+ xmlSecHrefRsaRipemd160, /* const xmlChar* href; */
+ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
+
+ xmlSecGCryptPkSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecGCryptPkSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecGCryptPkSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ xmlSecGCryptPkSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecGCryptPkSignatureVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecGCryptPkSignatureExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGCryptTransformRsaRipemd160GetKlass:
+ *
+ * The RSA-RIPEMD160 signature transform klass.
+ *
+ * Returns: RSA-RIPEMD160 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGCryptTransformRsaRipemd160GetKlass(void) {
+ return(&xmlSecGCryptRsaRipemd160Klass);
+}
+
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+#ifndef XMLSEC_NO_SHA1
+/****************************************************************************
+ *
+ * RSA-SHA1 signature transform
+ *
+ ***************************************************************************/
+static xmlSecTransformKlass xmlSecGCryptRsaSha1Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecGCryptPkSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameRsaSha1, /* const xmlChar* name; */
+ xmlSecHrefRsaSha1, /* const xmlChar* href; */
+ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
+
+ xmlSecGCryptPkSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecGCryptPkSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecGCryptPkSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ xmlSecGCryptPkSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecGCryptPkSignatureVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecGCryptPkSignatureExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGCryptTransformRsaSha1GetKlass:
+ *
+ * The RSA-SHA1 signature transform klass.
+ *
+ * Returns: RSA-SHA1 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGCryptTransformRsaSha1GetKlass(void) {
+ return(&xmlSecGCryptRsaSha1Klass);
+}
+
+#endif /* XMLSEC_NO_SHA1 */
+
+
+#ifndef XMLSEC_NO_SHA256
+/****************************************************************************
+ *
+ * RSA-SHA256 signature transform
+ *
+ ***************************************************************************/
+static xmlSecTransformKlass xmlSecGCryptRsaSha256Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecGCryptPkSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameRsaSha256, /* const xmlChar* name; */
+ xmlSecHrefRsaSha256, /* const xmlChar* href; */
+ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
+
+ xmlSecGCryptPkSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecGCryptPkSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecGCryptPkSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ xmlSecGCryptPkSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecGCryptPkSignatureVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecGCryptPkSignatureExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGCryptTransformRsaSha256GetKlass:
+ *
+ * The RSA-SHA256 signature transform klass.
+ *
+ * Returns: RSA-SHA256 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGCryptTransformRsaSha256GetKlass(void) {
+ return(&xmlSecGCryptRsaSha256Klass);
+}
+
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+/****************************************************************************
+ *
+ * RSA-SHA384 signature transform
+ *
+ ***************************************************************************/
+static xmlSecTransformKlass xmlSecGCryptRsaSha384Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecGCryptPkSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameRsaSha384, /* const xmlChar* name; */
+ xmlSecHrefRsaSha384, /* const xmlChar* href; */
+ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
+
+ xmlSecGCryptPkSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecGCryptPkSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecGCryptPkSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ xmlSecGCryptPkSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecGCryptPkSignatureVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecGCryptPkSignatureExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGCryptTransformRsaSha384GetKlass:
+ *
+ * The RSA-SHA384 signature transform klass.
+ *
+ * Returns: RSA-SHA384 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGCryptTransformRsaSha384GetKlass(void) {
+ return(&xmlSecGCryptRsaSha384Klass);
+}
+
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+/****************************************************************************
+ *
+ * RSA-SHA512 signature transform
+ *
+ ***************************************************************************/
+static xmlSecTransformKlass xmlSecGCryptRsaSha512Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecGCryptPkSignatureSize, /* xmlSecSize objSize */
+
+ xmlSecNameRsaSha512, /* const xmlChar* name; */
+ xmlSecHrefRsaSha512, /* const xmlChar* href; */
+ xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
+
+ xmlSecGCryptPkSignatureInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecGCryptPkSignatureFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecGCryptPkSignatureSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ xmlSecGCryptPkSignatureSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ xmlSecGCryptPkSignatureVerify, /* xmlSecTransformVerifyMethod verify; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecGCryptPkSignatureExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGCryptTransformRsaSha512GetKlass:
+ *
+ * The RSA-SHA512 signature transform klass.
+ *
+ * Returns: RSA-SHA512 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGCryptTransformRsaSha512GetKlass(void) {
+ return(&xmlSecGCryptRsaSha512Klass);
+}
+
+#endif /* XMLSEC_NO_SHA512 */
+
+#endif /* XMLSEC_NO_RSA */
+
+
+
diff --git a/src/gnutls/crypto.c b/src/gnutls/crypto.c
index 3687c65..25d8f65 100644
--- a/src/gnutls/crypto.c
+++ b/src/gnutls/crypto.c
@@ -108,7 +108,6 @@ xmlSecCryptoGetFunctions_gnutls(void) {
/******************************* DSA ********************************/
#ifdef ALEKSEY_TODO
-
#ifndef XMLSEC_NO_DSA
#ifndef XMLSEC_NO_SHA1
@@ -116,7 +115,6 @@ xmlSecCryptoGetFunctions_gnutls(void) {
#endif /* XMLSEC_NO_SHA1 */
#endif /* XMLSEC_NO_DSA */
-
#endif /* ALEKSEY_TODO */
/******************************* HMAC ********************************/
@@ -160,7 +158,6 @@ xmlSecCryptoGetFunctions_gnutls(void) {
/******************************* RSA ********************************/
#ifdef ALEKSEY_TODO
-
#ifndef XMLSEC_NO_RSA
#ifndef XMLSEC_NO_MD5
@@ -175,10 +172,6 @@ xmlSecCryptoGetFunctions_gnutls(void) {
gXmlSecGnuTLSFunctions->transformRsaSha1GetKlass = xmlSecGnuTLSTransformRsaSha1GetKlass;
#endif /* XMLSEC_NO_SHA1 */
-#ifndef XMLSEC_NO_SHA224
- gXmlSecGnuTLSFunctions->transformRsaSha224GetKlass = xmlSecGnuTLSTransformRsaSha224GetKlass;
-#endif /* XMLSEC_NO_SHA224 */
-
#ifndef XMLSEC_NO_SHA256
gXmlSecGnuTLSFunctions->transformRsaSha256GetKlass = xmlSecGnuTLSTransformRsaSha256GetKlass;
#endif /* XMLSEC_NO_SHA256 */
@@ -191,10 +184,7 @@ xmlSecCryptoGetFunctions_gnutls(void) {
gXmlSecGnuTLSFunctions->transformRsaSha512GetKlass = xmlSecGnuTLSTransformRsaSha512GetKlass;
#endif /* XMLSEC_NO_SHA512 */
- gXmlSecGnuTLSFunctions->transformRsaPkcs1GetKlass = xmlSecGnuTLSTransformRsaPkcs1GetKlass;
- gXmlSecGnuTLSFunctions->transformRsaOaepGetKlass = xmlSecGnuTLSTransformRsaOaepGetKlass;
#endif /* XMLSEC_NO_RSA */
-
#endif /* ALEKSEY_TODO */
/******************************* SHA ********************************/
diff --git a/tests/testrun.sh b/tests/testrun.sh
index 1e4e7ea..d72d868 100755
--- a/tests/testrun.sh
+++ b/tests/testrun.sh
@@ -19,28 +19,6 @@ if [ "z$OS_ARCH" = "zCygwin" ] ; then
fi
#
-# Setup keys config
-#
-pub_key_format=$file_format
-cert_format=$file_format
-priv_key_option="--pkcs12"
-priv_key_format="p12"
-
-# On Windows, one needs to specify Crypto Service Provider (CSP)
-# in the pkcs12 file to ensure it is loaded correctly to be used
-# with SHA2 algorithms. Worse, the CSP is different for XP and older
-# versions
-if [ "z$OS_ARCH" = "zCygwin" ] ; then
- if [ "z$OS_KERNEL" = "zCYGWIN_NT-5.1" ] ; then
- priv_key_suffix="-winxp"
- else
- priv_key_suffix="-win"
- fi
-else
- priv_key_suffix=""
-fi
-
-#
# Prepare folders
#
if [ "z$TMPFOLDER" = "z" ] ; then
@@ -72,15 +50,47 @@ fi
#
crypto_config=$TMPFOLDER/xmlsec-crypto-config
keysfile=$crypto_config/keys.xml
-if [ "z$crypto" == "zdefault" -a "z$XMLSEC_DEFAULT_CRYPTO" != "z" ] ; then
+if [ "z$XMLSEC_DEFAULT_CRYPTO" != "z" ] ; then
crypto="$XMLSEC_DEFAULT_CRYPTO"
-fi
-if [ "z$crypto" != "z" -a "z$crypto" != "zdefault" ] ; then
+elif [ "z$crypto" != "z" ] ; then
xmlsec_params="$xmlsec_params --crypto $crypto"
fi
xmlsec_params="$xmlsec_params --crypto-config $crypto_config"
#
+# Setup keys config
+#
+pub_key_format=$file_format
+cert_format=$file_format
+
+#
+# GCrypt only supports DER format for now, others are good to go with PKCS12
+#
+if [ "z$crypto" != "zgcrypt" ] ; then
+ priv_key_option="--pkcs12"
+ priv_key_format="p12"
+else
+ priv_key_option="--privkey-der"
+ priv_key_format="der"
+ pub_key_format="der"
+fi
+
+# On Windows, one needs to specify Crypto Service Provider (CSP)
+# in the pkcs12 file to ensure it is loaded correctly to be used
+# with SHA2 algorithms. Worse, the CSP is different for XP and older
+# versions
+if [ "z$OS_ARCH" = "zCygwin" ] ; then
+ if [ "z$OS_KERNEL" = "zCYGWIN_NT-5.1" ] ; then
+ priv_key_suffix="-winxp"
+ else
+ priv_key_suffix="-win"
+ fi
+else
+ priv_key_suffix=""
+fi
+
+
+#
# Misc
#
if [ -n "$PERF_TEST" ] ; then
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]