[xmlsec] Added DSA/SHA1 for xmlsec-gcrypt



commit b700d21ac9deab01df1b866d05a23f2e9de95ae4
Author: Aleksey Sanin <aleksey aleksey com>
Date:   Mon May 10 21:49:59 2010 -0700

    Added DSA/SHA1 for xmlsec-gcrypt

 ChangeLog               |    1 +
 TODO                    |   14 +-
 docs/xmldsig.html       |    4 +-
 src/gcrypt/app.c        |    2 +-
 src/gcrypt/asn1.c       |  573 ++++++++++++++++++++++++++++++-----------------
 src/gcrypt/asn1.h       |   15 +-
 src/gcrypt/signatures.c |  390 ++++++++++++++++++++++++++++----
 src/gcrypt/symkeys.c    |    1 +
 8 files changed, 723 insertions(+), 277 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 2a0fb2a..73a661b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 2010-05-10  Aleksey Sanin  <aleksey aleksey com>
 	* Added RSA/SHA1/SHA256/SHA384/SHA512/MD5/RIPEMD160 for xmlsec-gcrypt
+	* Added DSA/SHA1 for xmlsec-gcrypt
 
 2010-05-09  Aleksey Sanin  <aleksey aleksey com>
 	* Added DES KW support for xmlsec-mscrypto
diff --git a/TODO b/TODO
index acaa223..9041f84 100644
--- a/TODO
+++ b/TODO
@@ -161,11 +161,7 @@ aleksey-xmldsig-01/enveloping-sha512-rsa-sha512
 aleksey-xmldsig-01/enveloping-expired-cert
 aleksey-xmldsig-01/x509data-test
 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-external-b64-dsa
-merlin-xmldsig-twenty-three/signature-external-dsa
+
 merlin-xmldsig-twenty-three/signature-keyname
 merlin-xmldsig-twenty-three/signature-x509-crt
 merlin-xmldsig-twenty-three/signature-x509-sn
@@ -173,12 +169,8 @@ merlin-xmldsig-twenty-three/signature-x509-is
 merlin-xmldsig-twenty-three/signature-x509-ski
 merlin-xmldsig-twenty-three/signature-retrievalmethod-rawx509crt
 merlin-xmldsig-twenty-three/signature
-merlin-xmlenc-five/encsig-ripemd160-hmac-ripemd160-kw-tripledes
-merlin-exc-c14n-one/exc-signature
-merlin-exc-c14n-one/exc-signature
-merlin-c14n-three/signature
-merlin-xpath-filter2-three/sign-xfdl
-merlin-xpath-filter2-three/sign-spec
+merlin-xmlenc-five/encsig-hmac-sha256-rsa-1_5
+merlin-xmlenc-five/encsig-hmac-sha256-rsa-oaep-mgf1p
 phaos-xmldsig-three/signature-big
 phaos-xmldsig-three/signature-dsa-detached
 phaos-xmldsig-three/signature-dsa-enveloped
diff --git a/docs/xmldsig.html b/docs/xmldsig.html
index 5b6a589..4edc3b9 100644
--- a/docs/xmldsig.html
+++ b/docs/xmldsig.html
@@ -329,7 +329,7 @@ X509Data)<br>
 </td>
                 </tr>
 <tr>
-<td style="width: 40%;" align="left" valign="top">DSAwithSHA1<br>
+<td style="width: 40%;" align="left" valign="top">DSA with SHA1<br>
 (DSS) <br>
 </td>
                   <td align="left" valign="top">Y<a href="#dsa-sha1"><sup>(1)</sup></a>
@@ -337,7 +337,7 @@ X509Data)<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>
diff --git a/src/gcrypt/app.c b/src/gcrypt/app.c
index e1a7c64..bf33f33 100644
--- a/src/gcrypt/app.c
+++ b/src/gcrypt/app.c
@@ -145,7 +145,7 @@ xmlSecGCryptAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
 
     switch(format) {
     case xmlSecKeyDataFormatDer:
-        key_data = xmlSecGCryptParseDer(data, dataSize);
+        key_data = xmlSecGCryptParseDer(data, dataSize, xmlSecGCryptDerKeyTypeAuto);
         if(key_data == NULL) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
diff --git a/src/gcrypt/asn1.c b/src/gcrypt/asn1.c
index 95e7650..795d2eb 100644
--- a/src/gcrypt/asn1.c
+++ b/src/gcrypt/asn1.c
@@ -91,14 +91,18 @@ xmlSecGCryptAsn1ParseTag (xmlSecByte const **buffer, xmlSecSize *buflen, struct
 {
     int c;
     unsigned long tag;
-    const xmlSecByte *buf = *buffer;
-    xmlSecSize length = *buflen;
+    const xmlSecByte *buf;
+    xmlSecSize length;
 
     xmlSecAssert2(buffer != NULL, -1);
     xmlSecAssert2((*buffer) != NULL, -1);
     xmlSecAssert2(buflen != NULL, -1);
     xmlSecAssert2(ti != NULL, -1);
 
+    /* initialize */
+    buf = *buffer;
+    length = *buflen;
+
     ti->length = 0;
     ti->ndef = 0;
     ti->nhdr = 0;
@@ -174,278 +178,425 @@ xmlSecGCryptAsn1ParseTag (xmlSecByte const **buffer, xmlSecSize *buflen, struct
     return(0);
 }
 
-xmlSecKeyDataPtr
-xmlSecGCryptParseDerPrivateKey(const xmlSecByte * der, xmlSecSize derlen) {
-    xmlSecKeyDataPtr key_data = NULL;
-    gcry_sexp_t s_key = NULL;
-    gcry_error_t err;
+static int
+xmlSecGCryptAsn1ParseIntegerSequence(xmlSecByte const **buffer, xmlSecSize *buflen,
+                                     gcry_mpi_t * params, int params_size) {
+    const xmlSecByte *buf;
+    xmlSecSize length;
     struct tag_info ti;
-    gcry_mpi_t keyparms[8] = {
-        NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL
-    } ;
-    int n_keyparms = sizeof(keyparms) / sizeof(keyparms[0]);
-    int idx;
+    gcry_error_t err;
+    int idx = 0;
     int ret;
 
-    xmlSecAssert2(der != NULL, NULL);
-    xmlSecAssert2(derlen > 0, NULL);
-
-    /* Parse the ASN.1 structure.  */
-    if(xmlSecGCryptAsn1ParseTag (&der, &derlen, &ti)
-       || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
-    {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    NULL,
-                    "xmlSecGCryptAsn1ParseTag",
-                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    "TAG_SEQUENCE is expected");
-        goto done;
-    }
+    xmlSecAssert2(buffer != NULL, -1);
+    xmlSecAssert2((*buffer) != NULL, -1);
+    xmlSecAssert2(buflen != NULL, -1);
+    xmlSecAssert2(params != NULL, -1);
+    xmlSecAssert2(params_size > 0, -1);
 
-    if (xmlSecGCryptAsn1ParseTag (&der, &derlen, &ti)
-       || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
-    {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    NULL,
-                    "xmlSecGCryptAsn1ParseTag",
-                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    "TAG_INTEGER is expected");
-        goto done;
-    }
+    /* initialize */
+    buf = *buffer;
+    length = *buflen;
 
-    if ((ti.length != 1) || ((*der) != 0)) {
-        /* The value of the first integer is no 0. */
+    /* read SEQUENCE */
+    memset(&ti, 0, sizeof(ti));
+    ret = xmlSecGCryptAsn1ParseTag (&buf, &length, &ti);
+    if((ret != 0)  || (ti.tag != TAG_SEQUENCE) || ti.class || !ti.cons || ti.ndef) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
                     "xmlSecGCryptAsn1ParseTag",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    "integer length=%d, value=%d",
-                    (int)ti.length, (int)(*der));
-        goto done;
+                    "TAG_SEQUENCE is expected: tag=%d",
+                    (int)ti.tag);
+        return(-1);
     }
-    der += ti.length; 
-    derlen -= ti.length;
 
-    /* read params */
-    for (idx=0; idx < n_keyparms; idx++) {
-        if ( xmlSecGCryptAsn1ParseTag (&der, &derlen, &ti)
-           || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+    /* read INTEGERs */
+    for (idx = 0; ((idx < params_size) && (length > 0)); idx++) {
+        memset(&ti, 0, sizeof(ti));
+        ret = xmlSecGCryptAsn1ParseTag (&buf, &length, &ti);
+        if((ret != 0) || (ti.tag != TAG_INTEGER) || ti.class || ti.cons || ti.ndef)
         {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
                         "xmlSecGCryptAsn1ParseTag",
                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                        "TAG_INTEGER is expected - index=%d",
-                        (int)idx);
-            goto done;
+                        "TAG_INTEGER is expected - index=%d, tag=%d",
+                        (int)idx, (int)ti.tag);
+            return(-1);
         }
 
-        err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
-        if (err) {
+        err = gcry_mpi_scan(&(params[idx]), GCRYMPI_FMT_USG, buf, ti.length, NULL);
+        if((err != GPG_ERR_NO_ERROR) || (params[idx] == NULL)) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
                         "gcry_mpi_scan",
                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
                         "err=%d", (int)err);
-            goto done;
+            return(-1);
         }
-        der += ti.length;
-        derlen -= ti.length;
+        buf += ti.length;
+        length -= ti.length;
     }
 
-    if (idx != n_keyparms) {
+    /* did we parse everything? */
+    if(length > 0) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
                     "xmlSecGCryptAsn1ParseTag",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    "Not enough params: index=%d, expected=%d",
-                    (int)idx, (int)n_keyparms);
-        goto done;
+                    "too many params - cur=%d, expected=%d",
+                    (int)(idx - 1), (int)params_size);
+        return(-1);
     }
 
-    /* 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]);
-    }
+    /* done */
+    *buffer = buf;
+    *buflen = length;
+    return(idx);
+}
 
-    /* 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) {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    NULL,
-                    "gcry_sexp_build",
-                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    "err=%d", (int)err);
-        goto done;
-    }
+xmlSecKeyDataPtr
+xmlSecGCryptParseDer(const xmlSecByte * der, xmlSecSize derlen,
+                     enum xmlSecGCryptDerKeyType type) {
+    xmlSecKeyDataPtr key_data = NULL;
+    gcry_sexp_t s_pub_key = NULL;
+    gcry_sexp_t s_priv_key = NULL;
+    gcry_error_t err;
+    gcry_mpi_t keyparms[20];
+    int keyparms_num;
+    unsigned int idx;
+    int ret;
+
+    xmlSecAssert2(der != NULL, NULL);
+    xmlSecAssert2(derlen > 0, NULL);
 
-    key_data = xmlSecKeyDataCreate(xmlSecGCryptKeyDataRsaId);
-    if(key_data == NULL) {
+    /* Parse the ASN.1 structure.  */
+    memset(&keyparms, 0, sizeof(keyparms));
+    ret = xmlSecGCryptAsn1ParseIntegerSequence(
+        &der, &derlen,
+        keyparms,  sizeof(keyparms) / sizeof(keyparms[0])
+    );
+    if(ret < 0) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
-                    "xmlSecKeyDataCreate",
+                    "xmlSecGCryptAsn1ParseIntegerSequence",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    "xmlSecGCryptKeyDataRsaId");
+                    XMLSEC_ERRORS_NO_MESSAGE);
         goto done;
     }
+    keyparms_num = ret;
 
-    ret = xmlSecGCryptKeyDataRsaAdoptKey(key_data, s_key);
-    if(ret < 0) {
+    /* The value of the first integer should be 0. */
+    if ((keyparms_num < 1) || (gcry_mpi_cmp_ui(keyparms[0], 0) != 0)) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
-                    "xmlSecGCryptKeyDataRsaAdoptKey",
+                    "xmlSecGCryptAsn1ParseTag",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    "xmlSecGCryptKeyDataRsaId");
-        xmlSecKeyDataDestroy(key_data);
-        key_data = NULL;
+                    "num=%d",
+                    (int)keyparms_num);
         goto done;
     }
-    s_key = NULL; /* owned by key_data now */
 
-done:
-    if(s_key != NULL) {
-        gcry_sexp_release(s_key);
+    /* do we need to guess the key type? not robust but the best we can do */
+    if(type == xmlSecGCryptDerKeyTypeAuto) {
+        switch(keyparms_num) {
+        case 3:
+            /* Public RSA */
+            type = xmlSecGCryptDerKeyTypePublicRsa;
+        case 5:
+            /* Public DSA */
+            type = xmlSecGCryptDerKeyTypePublicDsa;
+        case 6:
+            /* Private DSA */
+            type = xmlSecGCryptDerKeyTypePrivateDsa;
+            break;
+        case 9:
+            /* Private RSA */
+            type = xmlSecGCryptDerKeyTypePrivateRsa;
+            break;
+        default:
+            /* unknown */
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "Unexpected number of parameters, unknown key type",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "keyparms_num=%d", (int)keyparms_num);
+            goto done;
+        }
     }
 
-    for (idx=0; idx < n_keyparms; idx++) {
-        if(keyparms[idx] != NULL) {
-            gcry_mpi_release (keyparms[idx]);
+
+    switch(type) {
+#ifndef XMLSEC_NO_DSA
+    case xmlSecGCryptDerKeyTypePrivateDsa:
+        /* check we have enough params */
+        if(keyparms_num != 6) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "Private DSA key: 6 parameters exepcted",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "parms_num=%d", (int)keyparms_num);
+            goto done;
         }
-    }
 
-    return(key_data);
-}
+        /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
+        /* First check that x < y; if not swap x and y  */
+        if (gcry_mpi_cmp (keyparms[4], keyparms[5]) > 0) {
+            gcry_mpi_swap (keyparms[4], keyparms[5]);
+        }
 
+        /* Build the S-expressions  */
+        err = gcry_sexp_build (&s_priv_key, NULL,
+                "(private-key(dsa(p%m)(q%m)(g%m)(x%m)(y%m)))",
+                keyparms[1], keyparms[2], keyparms[3], keyparms[4], keyparms[5]
+        );
+        if((err != GPG_ERR_NO_ERROR) || (s_priv_key == NULL)) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "gcry_sexp_build(private-key/dsa)",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        "err=%d", (int)err);
+            goto done;
+        }
 
-xmlSecKeyDataPtr
-xmlSecGCryptParseDerPublicKey(const xmlSecByte * der, xmlSecSize derlen) {
-    xmlSecAssert2(der != NULL, NULL);
-    xmlSecAssert2(derlen > 0, NULL);
+        err = gcry_sexp_build (&s_pub_key, NULL,
+                "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+                keyparms[1], keyparms[2], keyparms[3], keyparms[5]
+        );
+        if((err != GPG_ERR_NO_ERROR) || (s_pub_key == NULL)) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "gcry_sexp_build(public-key/dsa)",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        "err=%d", (int)err);
+            goto done;
+        }
 
-    /* aleksey todo */
-    return(NULL);
-}
+        /* construct key and key data */
+        key_data = xmlSecKeyDataCreate(xmlSecGCryptKeyDataDsaId);
+        if(key_data == NULL) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "xmlSecKeyDataCreate",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "xmlSecGCryptKeyDataDsaId");
+            goto done;
+        }
 
-#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 ( xmlSecGCryptAsn1ParseTag (&der, &derlen, &ti)
-       || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
-    goto bad_asn1;
-  if ( xmlSecGCryptAsn1ParseTag (&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 ( xmlSecGCryptAsn1ParseTag (&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 ( xmlSecGCryptAsn1ParseTag (&der, &derlen, &ti)
-       || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
-    goto bad_asn1;
-
-  for (idx=0; idx < n_keyparms; idx++)
-    {
-      if ( xmlSecGCryptAsn1ParseTag (&der, &derlen, &ti)
-           || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
-        goto bad_asn1;
-      if (show)
-        {
-          char prefix[2];
+        ret = xmlSecGCryptKeyDataDsaAdoptKeyPair(key_data, s_pub_key, s_priv_key);
+        if(ret < 0) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "xmlSecGCryptKeyDataDsaAdoptKey",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "xmlSecGCryptKeyDataDsaId");
+            xmlSecKeyDataDestroy(key_data);
+            key_data = NULL;
+            goto done;
+        }
+        s_pub_key = NULL; /* owned by key_data now */
+        s_priv_key = NULL; /* owned by key_data now */
+        break;
 
-          prefix[0] = idx < 2? "ne"[idx] : '?';
-          prefix[1] = 0;
-          showhex (prefix, der, ti.length);
+    case xmlSecGCryptDerKeyTypePublicDsa:
+        /* check we have enough params */
+        if(keyparms_num != 5) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "Public DSA key: 5 parameters exepcted",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "parms_num=%d", (int)keyparms_num);
+            goto done;
+        }
+
+        /* Build the S-expression.  */
+        err = gcry_sexp_build (&s_pub_key, NULL,
+                "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+                keyparms[2], keyparms[3], keyparms[4], keyparms[1]
+        );
+        if((err != GPG_ERR_NO_ERROR) || (s_pub_key == NULL)) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "gcry_sexp_build(public-key/dsa)",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        "err=%d", (int)err);
+            goto done;
+        }
+
+        /* construct key and key data */
+        key_data = xmlSecKeyDataCreate(xmlSecGCryptKeyDataDsaId);
+        if(key_data == NULL) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "xmlSecKeyDataCreate",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "xmlSecGCryptKeyDataDsaId");
+            goto done;
+        }
+
+        ret = xmlSecGCryptKeyDataDsaAdoptKeyPair(key_data, s_pub_key, NULL);
+        if(ret < 0) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "xmlSecGCryptKeyDataDsaAdoptKey",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "xmlSecGCryptKeyDataDsaId");
+            xmlSecKeyDataDestroy(key_data);
+            key_data = NULL;
+            goto done;
+        }
+        s_pub_key = NULL; /* owned by key_data now */
+        break;
+#endif /* XMLSEC_NO_DSA */
+
+#ifndef XMLSEC_NO_RSA
+    case xmlSecGCryptDerKeyTypePrivateRsa:
+        /* check we have enough params */
+        if(keyparms_num != 9) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "Private RSA key: 9 parameters exepcted",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "parms_num=%d", (int)keyparms_num);
+            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[4], keyparms[5]) > 0) {
+            gcry_mpi_swap (keyparms[4], keyparms[5]);
+            gcry_mpi_invm (keyparms[8], keyparms[4], keyparms[5]);
         }
-      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_priv_key, NULL,
+                         "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
+                         keyparms[1], keyparms[2],
+                         keyparms[3], keyparms[4],
+                         keyparms[5], keyparms[8]
+        );
+        if((err != GPG_ERR_NO_ERROR) || (s_priv_key == NULL)) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "gcry_sexp_build(private-key/rsa)",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        "err=%d", (int)err);
+            goto done;
+        }
 
-  /* Build the S-expression.  */
-  err = gcry_sexp_build (&s_key, NULL,
+        err = gcry_sexp_build (&s_pub_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 */
+                         keyparms[1], keyparms[2]
+        );
+        if((err != GPG_ERR_NO_ERROR) || (s_pub_key == NULL)) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "gcry_sexp_build(public-key/rsa)",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        "err=%d", (int)err);
+            goto done;
+        }
+
+        /* construct key and key data */
+        key_data = xmlSecKeyDataCreate(xmlSecGCryptKeyDataRsaId);
+        if(key_data == NULL) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "xmlSecKeyDataCreate",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "xmlSecGCryptKeyDataRsaId");
+            goto done;
+        }
 
+        ret = xmlSecGCryptKeyDataRsaAdoptKeyPair(key_data, s_pub_key, s_priv_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_pub_key = NULL; /* owned by key_data now */
+        s_priv_key = NULL; /* owned by key_data now */
+        break;
 
-xmlSecKeyDataPtr
-xmlSecGCryptParseDer(const xmlSecByte * der, xmlSecSize derlen) {
-    xmlSecKeyDataPtr res = NULL;
+    case xmlSecGCryptDerKeyTypePublicRsa:
+        /* check we have enough params */
+        if(keyparms_num != 3) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "Public RSA key: 3 parameters exepcted",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "parms_num=%d", (int)keyparms_num);
+            goto done;
+        }
 
-    xmlSecAssert2(der != NULL, NULL);
-    xmlSecAssert2(derlen > 0, NULL);
+        /* Build the S-expression.  */
+        err = gcry_sexp_build (&s_pub_key, NULL,
+                         "(public-key(rsa(n%m)(e%m)))",
+                         keyparms[1], keyparms[2]
+        );
+        if((err != GPG_ERR_NO_ERROR) || (s_pub_key == NULL)) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "gcry_sexp_build(public-key/rsa)",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        "err=%d", (int)err);
+            goto done;
+        }
+
+        /* construct key and key data */
+        key_data = xmlSecKeyDataCreate(xmlSecGCryptKeyDataRsaId);
+        if(key_data == NULL) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "xmlSecKeyDataCreate",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "xmlSecGCryptKeyDataRsaId");
+            goto done;
+        }
+
+        ret = xmlSecGCryptKeyDataRsaAdoptKeyPair(key_data, s_pub_key, NULL);
+        if(ret < 0) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "xmlSecGCryptKeyDataRsaAdoptKey",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "xmlSecGCryptKeyDataRsaId");
+            xmlSecKeyDataDestroy(key_data);
+            key_data = NULL;
+            goto done;
+        }
+        s_pub_key = NULL; /* owned by key_data now */
+        break;
+#endif /* XMLSEC_NO_RSA */
+
+    default:
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "Unsupported key type",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    "type=%d", (int)type);
+        goto done;
+        break;
+    }
 
-    /* try private key first */
-    res = xmlSecGCryptParseDerPrivateKey(der, derlen);
-    if(res == NULL) {
-        res = xmlSecGCryptParseDerPublicKey(der, derlen);
+done:
+    if(s_priv_key != NULL) {
+        gcry_sexp_release(s_priv_key);
+    }
+    if(s_pub_key != NULL) {
+        gcry_sexp_release(s_pub_key);
+    }
+    for (idx = 0; idx < sizeof(keyparms) / sizeof(keyparms[0]); idx++) {
+        if(keyparms[idx] != NULL) {
+            gcry_mpi_release (keyparms[idx]);
+        }
     }
 
-    return(res);
+    return(key_data);
 }
-
diff --git a/src/gcrypt/asn1.h b/src/gcrypt/asn1.h
index 47af8ac..d05b530 100644
--- a/src/gcrypt/asn1.h
+++ b/src/gcrypt/asn1.h
@@ -19,12 +19,17 @@
 extern "C" {
 #endif /* __cplusplus */
 
-xmlSecKeyDataPtr        xmlSecGCryptParseDerPrivateKey  (const xmlSecByte * der,
-                                                         xmlSecSize derlen);
-xmlSecKeyDataPtr        xmlSecGCryptParseDerPublicKey   (const xmlSecByte * der,
-                                                         xmlSecSize derlen);
+enum xmlSecGCryptDerKeyType {
+    xmlSecGCryptDerKeyTypeAuto = 0,
+    xmlSecGCryptDerKeyTypePublicDsa,
+    xmlSecGCryptDerKeyTypePublicRsa,
+    xmlSecGCryptDerKeyTypePrivateDsa,
+    xmlSecGCryptDerKeyTypePrivateRsa
+};
+
 xmlSecKeyDataPtr        xmlSecGCryptParseDer            (const xmlSecByte * der,
-                                                         xmlSecSize derlen);
+                                                         xmlSecSize derlen,
+                                                         enum xmlSecGCryptDerKeyType type);
 
 #ifdef __cplusplus
 }
diff --git a/src/gcrypt/signatures.c b/src/gcrypt/signatures.c
index 45bdcb6..3f6ead2 100644
--- a/src/gcrypt/signatures.c
+++ b/src/gcrypt/signatures.c
@@ -515,6 +515,82 @@ xmlSecGCryptPkSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTra
     return(0);
 }
 
+/*****************************************************************************
+ *
+ * Helper
+ *
+ ****************************************************************************/
+static int
+xmlSecGCryptAppendMpi(gcry_mpi_t a, xmlSecBufferPtr out) {
+    xmlSecSize outSize;
+    size_t written;
+    gpg_error_t err;
+    int ret;
+    int res = -1;
+
+    xmlSecAssert2(a != NULL, -1);
+    xmlSecAssert2(out != NULL, -1);
+
+    /* current size */
+    outSize = xmlSecBufferGetSize(out);
+
+    /* figure out how much space we need */
+    written = 0;
+    err = gcry_mpi_print(GCRYMPI_FMT_USG, NULL, 0, &written, a);
+    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);
+        return(-1);
+    }
+
+    /* allocate space */
+    ret = xmlSecBufferSetMaxSize(out, outSize + written + 1);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecBufferSetMaxSize",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    "size=%d", (int)(outSize + written + 1));
+        return(-1);
+    }
+    xmlSecAssert2(xmlSecBufferGetMaxSize(out) > outSize, -1);
+
+    /* write out */
+    written = 0;
+    err = gcry_mpi_print(GCRYMPI_FMT_USG,
+            xmlSecBufferGetData(out) + outSize,
+            xmlSecBufferGetMaxSize(out) - outSize,
+            &written, a);
+    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) - outSize));
+        return(-1);
+    }
+
+    /* reset size */
+    ret = xmlSecBufferSetSize(out, outSize + written);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecBufferSetSize",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    "size=%d",
+                    (int)(outSize + written));
+        return(-1);
+    }
+
+    /* done */
+    return(0);
+}
+
 #ifndef XMLSEC_NO_DSA
 
 #ifndef XMLSEC_NO_SHA1
@@ -545,27 +621,286 @@ static int
 xmlSecGCryptDsaPkSign(int digest, xmlSecKeyDataPtr key_data,
                       const xmlSecByte* dgst, xmlSecSize dgstSize,
                       xmlSecBufferPtr out) {
+    gcry_mpi_t m_hash = NULL;
+    gcry_sexp_t s_data = NULL;
+    gcry_sexp_t s_sig = NULL;
+    gcry_sexp_t s_r = NULL;
+    gcry_sexp_t s_s = NULL;
+    gcry_mpi_t m_r = NULL;
+    gcry_mpi_t m_s = NULL;
+    gcry_sexp_t s_tmp;
+    gpg_error_t err;
+    int ret;
+    int res = -1;
+
     xmlSecAssert2(key_data != NULL, -1);
+    xmlSecAssert2(xmlSecGCryptKeyDataDsaGetPrivateKey(key_data) != NULL, -1);
     xmlSecAssert2(dgst != NULL, -1);
     xmlSecAssert2(dgstSize > 0, -1);
     xmlSecAssert2(out != NULL, -1);
 
-    /* ALEKSEY_TODO */
-    return(-1);
+    /* get the current digest, can't use "hash" :( */
+    err = gcry_mpi_scan(&m_hash, GCRYMPI_FMT_USG, dgst, dgstSize, NULL);
+    if((err != GPG_ERR_NO_ERROR) || (m_hash == NULL)) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_mpi_scan(hash)",
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                    "err=%d", (int)err);
+        goto done;
+    }
+
+    err = gcry_sexp_build (&s_data, NULL,
+                           "(data (flags raw)(value %m))",
+                           m_hash);
+    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, xmlSecGCryptKeyDataDsaGetPrivateKey(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, "dsa", 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;
+
+    /* r */
+    s_r = gcry_sexp_find_token(s_sig, "r", 0);
+    if(s_r == NULL) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_sexp_find_token(r)",
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+
+    m_r = gcry_sexp_nth_mpi(s_r, 1, GCRYMPI_FMT_USG);
+    if(m_r == NULL) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_sexp_nth_mpi(r)",
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+
+    /* s */
+    s_s = gcry_sexp_find_token(s_sig, "s", 0);
+    if(s_s == NULL) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_sexp_find_token(s)",
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+
+    m_s = gcry_sexp_nth_mpi(s_s, 1, GCRYMPI_FMT_USG);
+    if(m_s == NULL) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_sexp_nth_mpi(s)",
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+
+    /* write out: r + s */
+    ret = xmlSecGCryptAppendMpi(m_r, out);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecGCryptAppendMpi",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+    xmlSecAssert2(xmlSecBufferGetSize(out), 20);
+    ret = xmlSecGCryptAppendMpi(m_s, out);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecGCryptAppendMpi",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+    xmlSecAssert2(xmlSecBufferGetSize(out), 40);
+
+    /* done */
+    res = 0;
+
+done:
+    if(m_hash != NULL) {
+        gcry_mpi_release(m_hash);
+    }
+    if(m_r != NULL) {
+        gcry_mpi_release(m_r);
+    }
+    if(m_s != NULL) {
+        gcry_mpi_release(m_s);
+    }
+
+    if(s_data != NULL) {
+        gcry_sexp_release(s_data);
+    }
+    if(s_sig != NULL) {
+        gcry_sexp_release(s_sig);
+    }
+    if(s_r != NULL) {
+        gcry_sexp_release(s_r);
+    }
+    if(s_s != NULL) {
+        gcry_sexp_release(s_s);
+    }
+
+    return(res);
 }
 
 static int
 xmlSecGCryptDsaPkVerify(int digest, xmlSecKeyDataPtr key_data,
                         const xmlSecByte* dgst, xmlSecSize dgstSize,
                         const xmlSecByte* data, xmlSecSize dataSize) {
+    gcry_mpi_t m_hash = NULL;
+    gcry_sexp_t s_data = NULL;
+    gcry_mpi_t m_sig_r = NULL;
+    gcry_mpi_t m_sig_s = NULL;
+    gcry_sexp_t s_sig = NULL;
+    gpg_error_t err;
+    int res = -1;
+
     xmlSecAssert2(key_data != NULL, -1);
+    xmlSecAssert2(xmlSecGCryptKeyDataDsaGetPublicKey(key_data) != NULL, -1);
     xmlSecAssert2(dgst != NULL, -1);
     xmlSecAssert2(dgstSize > 0, -1);
     xmlSecAssert2(data != NULL, -1);
-    xmlSecAssert2(dataSize > 0, -1);
+    xmlSecAssert2(dataSize == (20 + 20), -1);
+
+    /* get the current digest, can't use "hash" :( */
+    err = gcry_mpi_scan(&m_hash, GCRYMPI_FMT_USG, dgst, dgstSize, NULL);
+    if((err != GPG_ERR_NO_ERROR) || (m_hash == NULL)) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_mpi_scan(hash)",
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                    "err=%d", (int)err);
+        goto done;
+    }
+
+    err = gcry_sexp_build (&s_data, NULL,
+                           "(data (flags raw)(value %m))",
+                           m_hash);
+    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_r, GCRYMPI_FMT_USG, data, 20, NULL);
+    if((err != GPG_ERR_NO_ERROR) || (m_sig_r == NULL)) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_mpi_scan(r)",
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                    "err=%d", (int)err);
+        goto done;
+    }
+    err = gcry_mpi_scan(&m_sig_s, GCRYMPI_FMT_USG, data + 20, 20, NULL);
+    if((err != GPG_ERR_NO_ERROR) || (m_sig_s == NULL)) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_mpi_scan(s)",
+                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                    "err=%d", (int)err);
+        goto done;
+    }
 
-    /* ALEKSEY_TODO */
-    return(-1);
+    err = gcry_sexp_build (&s_sig, NULL,
+                           "(sig-val(dsa(r %m)(s %m)))",
+                           m_sig_r, m_sig_s);
+    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, xmlSecGCryptKeyDataDsaGetPublicKey(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_hash != NULL) {
+        gcry_mpi_release(m_hash);
+    }
+    if(m_sig_r != NULL) {
+        gcry_mpi_release(m_sig_r);
+    }
+    if(m_sig_s != NULL) {
+        gcry_mpi_release(m_sig_s);
+    }
+
+    if(s_data != NULL) {
+        gcry_sexp_release(s_data);
+    }
+    if(s_sig != NULL) {
+        gcry_sexp_release(s_sig);
+    }
+
+    return(res);
 }
 
 
@@ -657,7 +992,6 @@ xmlSecGCryptRsaPkcs1PkSign(int digest, xmlSecKeyDataPtr key_data,
     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;
@@ -741,51 +1075,13 @@ xmlSecGCryptRsaPkcs1PkSign(int digest, xmlSecKeyDataPtr key_data,
     }
 
     /* 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);
+    ret = xmlSecGCryptAppendMpi(m_sig, out);
     if(ret < 0) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
-                    "xmlSecBufferSetMaxSize",
+                    "xmlSecGCryptAppendMpi",
                     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);
+                    XMLSEC_ERRORS_NO_MESSAGE);
         goto done;
     }
 
diff --git a/src/gcrypt/symkeys.c b/src/gcrypt/symkeys.c
index 8ef48e6..88272fe 100644
--- a/src/gcrypt/symkeys.c
+++ b/src/gcrypt/symkeys.c
@@ -24,6 +24,7 @@
 
 #include <xmlsec/gcrypt/crypto.h>
 
+
 /*****************************************************************************
  *
  * Symmetic (binary) keys - just a wrapper for xmlSecKeyDataBinary



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]