[xmlsec] Added RSA/SHA1/SHA256/SHA384/SHA512/MD5/RIPEMD160 for xmlsec-gcrypt



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]