[xmlsec] adding RSA keys support



commit 65d6a069d4d2854289881c70eaa3d0aa9190ee2c
Author: Aleksey Sanin <aleksey aleksey com>
Date:   Sun May 9 23:13:20 2010 -0700

    adding RSA keys support

 include/xmlsec/gnutls/crypto.h |   92 +++++++
 src/gnutls/asymkeys.c          |  512 ++++++++++++++++++++--------------------
 src/gnutls/crypto.c            |   49 ++++-
 3 files changed, 391 insertions(+), 262 deletions(-)
---
diff --git a/include/xmlsec/gnutls/crypto.h b/include/xmlsec/gnutls/crypto.h
index 23abd20..107ee0d 100644
--- a/include/xmlsec/gnutls/crypto.h
+++ b/include/xmlsec/gnutls/crypto.h
@@ -275,6 +275,98 @@ XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformHmacSha512GetKlass(v
 
 #endif /* XMLSEC_NO_HMAC */
 
+/********************************************************************
+ *
+ * RSA transforms
+ *
+ *******************************************************************/
+#ifndef XMLSEC_NO_RSA
+#include <gcrypt.h>
+
+/**
+ * xmlSecGnuTLSKeyDataRsaId:
+ *
+ * The RSA key klass.
+ */
+#define xmlSecGnuTLSKeyDataRsaId \
+        xmlSecGnuTLSKeyDataRsaGetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecKeyDataId    xmlSecGnuTLSKeyDataRsaGetKlass (void);
+XMLSEC_CRYPTO_EXPORT int                xmlSecGnuTLSKeyDataRsaAdoptKey          (xmlSecKeyDataPtr data,
+                                                                                 gcry_sexp_t rsa_key);
+XMLSEC_CRYPTO_EXPORT int                xmlSecGnuTLSKeyDataRsaAdoptKeyPair      (xmlSecKeyDataPtr data,
+                                                                                 gcry_sexp_t pub_key,
+                                                                                 gcry_sexp_t priv_key);
+XMLSEC_CRYPTO_EXPORT gcry_sexp_t        xmlSecGnuTLSKeyDataRsaGetPublicKey      (xmlSecKeyDataPtr data);
+XMLSEC_CRYPTO_EXPORT gcry_sexp_t        xmlSecGnuTLSKeyDataRsaGetPrivateKey     (xmlSecKeyDataPtr data);
+
+#ifndef XMLSEC_NO_MD5
+/**
+ * xmlSecGnuTLSTransformRsaMd5Id:
+ *
+ * The RSA-MD5 signature transform klass.
+ */
+#define xmlSecGnuTLSTransformRsaMd5Id  \
+        xmlSecGnuTLSTransformRsaMd5GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformRsaMd5GetKlass(void);
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_RIPEMD160
+/**
+ * xmlSecGnuTLSTransformRsaRipemd160Id:
+ *
+ * The RSA-RIPEMD160 signature transform klass.
+ */
+#define xmlSecGnuTLSTransformRsaRipemd160Id    \
+        xmlSecGnuTLSTransformRsaRipemd160GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformRsaRipemd160GetKlass(void);
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+#ifndef XMLSEC_NO_SHA1
+/**
+ * xmlSecGnuTLSTransformRsaSha1Id:
+ *
+ * The RSA-SHA1 signature transform klass.
+ */
+#define xmlSecGnuTLSTransformRsaSha1Id \
+        xmlSecGnuTLSTransformRsaSha1GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformRsaSha1GetKlass(void);
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+/**
+ * xmlSecGnuTLSTransformRsaSha256Id:
+ *
+ * The RSA-SHA256 signature transform klass.
+ */
+#define xmlSecGnuTLSTransformRsaSha256Id       \
+        xmlSecGnuTLSTransformRsaSha256GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformRsaSha256GetKlass(void);
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+/**
+ * xmlSecGnuTLSTransformRsaSha384Id:
+ *
+ * The RSA-SHA384 signature transform klass.
+ */
+#define xmlSecGnuTLSTransformRsaSha384Id       \
+        xmlSecGnuTLSTransformRsaSha384GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformRsaSha384GetKlass(void);
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+/**
+ * xmlSecGnuTLSTransformRsaSha512Id:
+ *
+ * The RSA-SHA512 signature transform klass.
+ */
+#define xmlSecGnuTLSTransformRsaSha512Id       \
+        xmlSecGnuTLSTransformRsaSha512GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformRsaSha512GetKlass(void);
+#endif /* XMLSEC_NO_SHA512 */
+
+#endif /* XMLSEC_NO_RSA */
+
 
 /********************************************************************
  *
diff --git a/src/gnutls/asymkeys.c b/src/gnutls/asymkeys.c
index 8c0b60d..992374b 100644
--- a/src/gnutls/asymkeys.c
+++ b/src/gnutls/asymkeys.c
@@ -215,7 +215,12 @@ xmlSecGnuTLSAsymKeyDataAdoptKeyPair(xmlSecKeyDataPtr data, gcry_sexp_t pub_key,
     xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize), -1);
     xmlSecAssert2(pub_key != NULL, -1); /* public key should present always */
+/*
+    aleksey - we don't set optional parameters for RSA keys (p, k, u) and
+    because of that we can't actually test the key
+
     xmlSecAssert2(((priv_key == NULL) || (gcry_pk_testkey(priv_key) == GPG_ERR_NO_ERROR)), -1);
+*/
 
     ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
     xmlSecAssert2(ctx != NULL, -1);
@@ -877,6 +882,45 @@ xmlSecGnuTLSKeyDataDsaFinalize(xmlSecKeyDataPtr data) {
     xmlSecGnuTLSAsymKeyDataFinalize(data);
 }
 
+static int
+xmlSecGnuTLSKeyDataDsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1);
+    xmlSecAssert2(sizeBits > 0, -1);
+
+    return xmlSecGnuTLSAsymKeyDataGenerate(data, "dsa", sizeBits);
+}
+
+static xmlSecKeyDataType
+xmlSecGnuTLSKeyDataDsaGetType(xmlSecKeyDataPtr data) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), xmlSecKeyDataTypeUnknown);
+
+    return xmlSecGnuTLSAsymKeyDataGetType(data);
+}
+
+static xmlSecSize
+xmlSecGnuTLSKeyDataDsaGetSize(xmlSecKeyDataPtr data) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), 0);
+
+    return xmlSecGnuTLSAsymKeyDataGetSize(data);
+}
+
+static void
+xmlSecGnuTLSKeyDataDsaDebugDump(xmlSecKeyDataPtr data, FILE* output) {
+    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId));
+    xmlSecAssert(output != NULL);
+
+    fprintf(output, "=== dsa key: size = %d\n",
+            xmlSecGnuTLSKeyDataDsaGetSize(data));
+}
+
+static void
+xmlSecGnuTLSKeyDataDsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
+    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId));
+    xmlSecAssert(output != NULL);
+
+    fprintf(output, "<DSAKeyValue size=\"%d\" />\n",
+            xmlSecGnuTLSKeyDataDsaGetSize(data));
+}
 
 static int
 xmlSecGnuTLSKeyDataDsaXmlRead(xmlSecKeyDataId id,
@@ -1311,50 +1355,9 @@ done:
     return(res);
 }
 
-static int
-xmlSecGnuTLSKeyDataDsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
-    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1);
-    xmlSecAssert2(sizeBits > 0, -1);
-
-    return xmlSecGnuTLSAsymKeyDataGenerate(data, "dsa", sizeBits);
-}
-
-static xmlSecKeyDataType
-xmlSecGnuTLSKeyDataDsaGetType(xmlSecKeyDataPtr data) {
-    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), xmlSecKeyDataTypeUnknown);
-
-    return xmlSecGnuTLSAsymKeyDataGetType(data);
-}
-
-static xmlSecSize
-xmlSecGnuTLSKeyDataDsaGetSize(xmlSecKeyDataPtr data) {
-    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), 0);
-
-    return xmlSecGnuTLSAsymKeyDataGetSize(data);
-}
-
-static void
-xmlSecGnuTLSKeyDataDsaDebugDump(xmlSecKeyDataPtr data, FILE* output) {
-    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId));
-    xmlSecAssert(output != NULL);
-
-    fprintf(output, "=== dsa key: size = %d\n",
-            xmlSecGnuTLSKeyDataDsaGetSize(data));
-}
-
-static void
-xmlSecGnuTLSKeyDataDsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
-    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId));
-    xmlSecAssert(output != NULL);
-
-    fprintf(output, "<DSAKeyValue size=\"%d\" />\n",
-            xmlSecGnuTLSKeyDataDsaGetSize(data));
-}
-
 #endif /* XMLSEC_NO_DSA */
 
 
-#ifdef ALEKSEY_TODO
 #ifndef XMLSEC_NO_RSA
 /**************************************************************************
  *
@@ -1472,110 +1475,67 @@ xmlSecGnuTLSKeyDataRsaGetKlass(void) {
 }
 
 /**
- * xmlSecGnuTLSKeyDataRsaAdoptRsa:
+ * xmlSecGnuTLSKeyDataRsaAdoptKey:
  * @data:               the pointer to RSA key data.
- * @rsa:                the pointer to GnuTLS RSA key.
+ * @rsa_key:            the pointer to GnuTLS RSA key.
  *
  * Sets the value of RSA key data.
  *
  * Returns: 0 on success or a negative value otherwise.
  */
 int
-xmlSecGnuTLSKeyDataRsaAdoptRsa(xmlSecKeyDataPtr data, RSA* rsa) {
-    EVP_PKEY* pKey = NULL;
-    int ret;
-
+xmlSecGnuTLSKeyDataRsaAdoptKey(xmlSecKeyDataPtr data, gcry_sexp_t rsa_key) {
     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
+    xmlSecAssert2(rsa_key != NULL, -1);
 
-    /* construct new EVP_PKEY */
-    if(rsa != NULL) {
-        pKey = EVP_PKEY_new();
-        if(pKey == NULL) {
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-                        "EVP_PKEY_new",
-                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
-            return(-1);
-        }
-
-        ret = EVP_PKEY_assign_RSA(pKey, rsa);
-        if(ret != 1) {
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-                        "EVP_PKEY_assign_RSA",
-                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
-            return(-1);
-        }
-    }
-
-    ret = xmlSecGnuTLSKeyDataRsaAdoptEvp(data, pKey);
-    if(ret < 0) {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-                    "xmlSecGnuTLSKeyDataRsaAdoptEvp",
-                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
-        if(pKey != NULL) {
-            EVP_PKEY_free(pKey);
-        }
-        return(-1);
-    }
-    return(0);
+    return xmlSecGnuTLSAsymKeyDataAdoptKey(data, rsa_key);
 }
 
+
 /**
- * xmlSecGnuTLSKeyDataRsaGetRsa:
+ * xmlSecGnuTLSKeyDataRsaAdoptKeyPair:
  * @data:               the pointer to RSA key data.
+ * @pub_key:            the pointer to GnuTLS RSA pub key.
+ * @priv_key:           the pointer to GnuTLS RSA priv key.
  *
- * Gets the GnuTLS RSA key from RSA key data.
+ * Sets the value of RSA key data.
  *
- * Returns: pointer to GnuTLS RSA key or NULL if an error occurs.
+ * Returns: 0 on success or a negative value otherwise.
  */
-RSA*
-xmlSecGnuTLSKeyDataRsaGetRsa(xmlSecKeyDataPtr data) {
-    EVP_PKEY* pKey;
-
-    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), NULL);
-
-    pKey = xmlSecGnuTLSKeyDataRsaGetEvp(data);
-    xmlSecAssert2((pKey == NULL) || (pKey->type == EVP_PKEY_RSA), NULL);
+int
+xmlSecGnuTLSKeyDataRsaAdoptKeyPair(xmlSecKeyDataPtr data, gcry_sexp_t pub_key, gcry_sexp_t priv_key) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
+    xmlSecAssert2(pub_key != NULL, -1);
 
-    return((pKey != NULL) ? pKey->pkey.rsa : (RSA*)NULL);
+    return xmlSecGnuTLSAsymKeyDataAdoptKeyPair(data, pub_key, priv_key);
 }
 
 /**
- * xmlSecGnuTLSKeyDataRsaAdoptEvp:
+ * xmlSecGnuTLSKeyDataRsaGetPublicKey:
  * @data:               the pointer to RSA key data.
- * @pKey:               the pointer to GnuTLS EVP key.
  *
- * Sets the RSA key data value to GnuTLS EVP key.
+ * Gets the GnuTLS RSA public key from RSA key data.
  *
- * Returns: 0 on success or a negative value otherwise.
+ * Returns: pointer to GnuTLS public RSA key or NULL if an error occurs.
  */
-int
-xmlSecGnuTLSKeyDataRsaAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) {
-    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
-    xmlSecAssert2(pKey != NULL, -1);
-    xmlSecAssert2(pKey->type == EVP_PKEY_RSA, -1);
-
-    return(xmlSecGnuTLSAsymKeyDataAdoptEvp(data, pKey));
+gcry_sexp_t
+xmlSecGnuTLSKeyDataRsaGetPublicKey(xmlSecKeyDataPtr data) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), NULL);
+    return xmlSecGnuTLSAsymKeyDataGetPublicKey(data);
 }
 
 /**
- * xmlSecGnuTLSKeyDataRsaGetEvp:
+ * xmlSecGnuTLSKeyDataRsaGetPrivateKey:
  * @data:               the pointer to RSA key data.
  *
- * Gets the GnuTLS EVP key from RSA key data.
+ * Gets the GnuTLS RSA private key from RSA key data.
  *
- * Returns: pointer to GnuTLS EVP key or NULL if an error occurs.
+ * Returns: pointer to GnuTLS private RSA key or NULL if an error occurs.
  */
-EVP_PKEY*
-xmlSecGnuTLSKeyDataRsaGetEvp(xmlSecKeyDataPtr data) {
+gcry_sexp_t
+xmlSecGnuTLSKeyDataRsaGetPrivateKey(xmlSecKeyDataPtr data) {
     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), NULL);
-
-    return(xmlSecGnuTLSAsymKeyDataGetEvp(data));
+    return xmlSecGnuTLSAsymKeyDataGetPrivateKey(data);
 }
 
 static int
@@ -1601,11 +1561,57 @@ xmlSecGnuTLSKeyDataRsaFinalize(xmlSecKeyDataPtr data) {
 }
 
 static int
+xmlSecGnuTLSKeyDataRsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
+    xmlSecAssert2(sizeBits > 0, -1);
+
+    return xmlSecGnuTLSAsymKeyDataGenerate(data, "rsa", sizeBits);
+}
+
+static xmlSecKeyDataType
+xmlSecGnuTLSKeyDataRsaGetType(xmlSecKeyDataPtr data) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), xmlSecKeyDataTypeUnknown);
+
+    return xmlSecGnuTLSAsymKeyDataGetType(data);
+}
+
+static xmlSecSize
+xmlSecGnuTLSKeyDataRsaGetSize(xmlSecKeyDataPtr data) {
+    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), 0);
+
+    return xmlSecGnuTLSAsymKeyDataGetSize(data);
+}
+
+static void
+xmlSecGnuTLSKeyDataRsaDebugDump(xmlSecKeyDataPtr data, FILE* output) {
+    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId));
+    xmlSecAssert(output != NULL);
+
+    fprintf(output, "=== rsa key: size = %d\n",
+            xmlSecGnuTLSKeyDataRsaGetSize(data));
+}
+
+static void
+xmlSecGnuTLSKeyDataRsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
+    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId));
+    xmlSecAssert(output != NULL);
+
+    fprintf(output, "<RSAKeyValue size=\"%d\" />\n",
+            xmlSecGnuTLSKeyDataRsaGetSize(data));
+}
+
+static int
 xmlSecGnuTLSKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
                                     xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
-    xmlSecKeyDataPtr data;
     xmlNodePtr cur;
-    RSA *rsa;
+    xmlSecKeyDataPtr data = NULL;
+    gcry_mpi_t n = NULL;
+    gcry_mpi_t e = NULL;
+    gcry_mpi_t d = NULL;
+    gcry_sexp_t pub_key = NULL;
+    gcry_sexp_t priv_key = NULL;
+    gcry_error_t err;
+    int res = -1;
     int ret;
 
     xmlSecAssert2(id == xmlSecGnuTLSKeyDataRsaId, -1);
@@ -1619,22 +1625,12 @@ xmlSecGnuTLSKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
                     NULL,
                     XMLSEC_ERRORS_R_INVALID_KEY_DATA,
                     "key already has a value");
-        return(-1);
-    }
-
-    rsa = RSA_new();
-    if(rsa == NULL) {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-                    "RSA_new",
-                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
-        return(-1);
+        goto done;
     }
 
     cur = xmlSecGetNextElementNode(node->children);
 
-    /* first is Modulus node. It is REQUIRED because we do not support Seed and PgenCounter*/
+    /* first is Modulus node. It is REQUIRED */
     if((cur == NULL) || (!xmlSecCheckNodeName(cur,  xmlSecNodeRSAModulus, xmlSecDSigNs))) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
@@ -1642,22 +1638,21 @@ xmlSecGnuTLSKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
                     XMLSEC_ERRORS_R_INVALID_NODE,
                     "node=%s",
                     xmlSecErrorsSafeString(xmlSecNodeRSAModulus));
-        RSA_free(rsa);
-        return(-1);
+        goto done;
     }
-    if(xmlSecGnuTLSNodeGetMpiValue(cur, &(rsa->n)) == NULL) {
+    n = xmlSecGnuTLSNodeGetMpiValue(cur);
+    if(n == NULL) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
                     "xmlSecGnuTLSNodeGetMpiValue",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     "node=%s",
                     xmlSecErrorsSafeString(xmlSecNodeRSAModulus));
-        RSA_free(rsa);
-        return(-1);
+        goto done;
     }
     cur = xmlSecGetNextElementNode(cur->next);
 
-    /* next is Exponent node. It is REQUIRED because we do not support Seed and PgenCounter*/
+    /* next is Exponent node. It is REQUIRED */
     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeRSAExponent, xmlSecDSigNs))) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
@@ -1665,33 +1660,31 @@ xmlSecGnuTLSKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
                     XMLSEC_ERRORS_R_INVALID_NODE,
                     "node=%s",
                     xmlSecErrorsSafeString(xmlSecNodeRSAExponent));
-        RSA_free(rsa);
-        return(-1);
+        goto done;
     }
-    if(xmlSecGnuTLSNodeGetMpiValue(cur, &(rsa->e)) == NULL) {
+    e = xmlSecGnuTLSNodeGetMpiValue(cur);
+    if(e == NULL) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
                     "xmlSecGnuTLSNodeGetMpiValue",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     "node=%s",
                     xmlSecErrorsSafeString(xmlSecNodeRSAExponent));
-        RSA_free(rsa);
-        return(-1);
+        goto done;
     }
     cur = xmlSecGetNextElementNode(cur->next);
 
     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeRSAPrivateExponent, xmlSecNs))) {
-        /* next is X node. It is REQUIRED for private key but
-         * we are not sure exactly what do we read */
-        if(xmlSecGnuTLSNodeGetMpiValue(cur, &(rsa->d)) == NULL) {
+        /* next is PrivateExponent node. It is REQUIRED for private key */
+        d = xmlSecGnuTLSNodeGetMpiValue(cur);
+        if(d == NULL) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
                         "xmlSecGnuTLSNodeGetMpiValue",
                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
                         "node=%s",
                         xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent));
-            RSA_free(rsa);
-            return(-1);
+            goto done;
         }
         cur = xmlSecGetNextElementNode(cur->next);
     }
@@ -1702,10 +1695,37 @@ xmlSecGnuTLSKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
                     XMLSEC_ERRORS_R_INVALID_NODE,
                     "no nodes expected");
-        RSA_free(rsa);
-        return(-1);
+        goto done;
     }
 
+    /* construct pub/priv key pairs */
+    err = gcry_sexp_build(&pub_key, NULL,
+             "(public-key(rsa(n%m)(e%m)))",
+             n, e);
+    if((err != GPG_ERR_NO_ERROR) || (pub_key == NULL)) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+                    "gcry_sexp_build(public)",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+    if(d != NULL) {
+        err = gcry_sexp_build(&priv_key, NULL,
+                 "(private-key(rsa(n%m)(e%m)(d%m)))",
+                 n, e, d);
+        if((err != GPG_ERR_NO_ERROR) || (priv_key == NULL)) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+                        "gcry_sexp_build(private)",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        XMLSEC_ERRORS_NO_MESSAGE);
+            goto done;
+        }
+    }
+
+
+    /* create key data */
     data = xmlSecKeyDataCreate(id);
     if(data == NULL ) {
         xmlSecError(XMLSEC_ERRORS_HERE,
@@ -1713,41 +1733,74 @@ xmlSecGnuTLSKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
                     "xmlSecKeyDataCreate",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     XMLSEC_ERRORS_NO_MESSAGE);
-        RSA_free(rsa);
-        return(-1);
+        goto done;
     }
 
-    ret = xmlSecGnuTLSKeyDataRsaAdoptRsa(data, rsa);
+    ret = xmlSecGnuTLSKeyDataRsaAdoptKeyPair(data, pub_key, priv_key);
     if(ret < 0) {
         xmlSecError(XMLSEC_ERRORS_HERE,
-                    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
-                    "xmlSecGnuTLSKeyDataRsaAdoptRsa",
+                    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+                    "xmlSecGnuTLSKeyDataRsaAdoptKeyPair",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     XMLSEC_ERRORS_NO_MESSAGE);
-        xmlSecKeyDataDestroy(data);
-        RSA_free(rsa);
-        return(-1);
+        goto done;
     }
+    pub_key = NULL; /* pub_key is owned by data now */
+    priv_key = NULL; /* priv_key is owned by data now */
 
+    /* set key */
     ret = xmlSecKeySetValue(key, data);
     if(ret < 0) {
         xmlSecError(XMLSEC_ERRORS_HERE,
-                    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+                    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
                     "xmlSecKeySetValue",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+    data = NULL; /* data is owned by key now */
+
+
+    /* success */
+    res = 0;
+
+done:
+    /* cleanup */
+    if(n != NULL) {
+        gcry_mpi_release(n);
+    }
+
+    if(e != NULL) {
+        gcry_mpi_release(e);
+    }
+
+    if(d != NULL) {
+        gcry_mpi_release(d);
+    }
+
+    if(pub_key != NULL) {
+        gcry_sexp_release(pub_key);
+    }
+
+    if(priv_key != NULL) {
+        gcry_sexp_release(priv_key);
+    }
+
+    if(data != NULL) {
         xmlSecKeyDataDestroy(data);
-        return(-1);
     }
+    return(res);
 
-    return(0);
 }
 
 static int
 xmlSecGnuTLSKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
                             xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     xmlNodePtr cur;
-    RSA* rsa;
+    gcry_sexp_t pub_priv_key;
+    gcry_sexp_t rsa = NULL;
+    int private = 0;
+    int res = -1;
     int ret;
 
     xmlSecAssert2(id == xmlSecGnuTLSKeyDataRsaId, -1);
@@ -1756,14 +1809,37 @@ xmlSecGnuTLSKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
     xmlSecAssert2(node != NULL, -1);
     xmlSecAssert2(keyInfoCtx != NULL, -1);
 
-    rsa = xmlSecGnuTLSKeyDataRsaGetRsa(xmlSecKeyGetValue(key));
-    xmlSecAssert2(rsa != NULL, -1);
-
     if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) {
         /* we can have only private key or public key */
         return(0);
     }
 
+    /* find the private or public key */
+    pub_priv_key = xmlSecGnuTLSKeyDataRsaGetPrivateKey(xmlSecKeyGetValue(key));
+    if(pub_priv_key == NULL) {
+        pub_priv_key = xmlSecGnuTLSKeyDataRsaGetPublicKey(xmlSecKeyGetValue(key));
+        if(pub_priv_key == NULL) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+                        "xmlSecGnuTLSKeyDataRsaGetPublicKey()",
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        XMLSEC_ERRORS_NO_MESSAGE);
+            goto done;
+        }
+    } else {
+        private = 1;
+    }
+
+    rsa = gcry_sexp_find_token(pub_priv_key, "rsa", 0);
+    if(rsa == NULL) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+                    "gcry_sexp_find_token(rsa)",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+
     /* first is Modulus node */
     cur = xmlSecAddChild(node, xmlSecNodeRSAModulus, xmlSecDSigNs);
     if(cur == NULL) {
@@ -1773,9 +1849,9 @@ xmlSecGnuTLSKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     "node=%s",
                     xmlSecErrorsSafeString(xmlSecNodeRSAModulus));
-        return(-1);
+       goto done;
     }
-    ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, rsa->n, 1);
+    ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, rsa, "n", 1);
     if(ret < 0) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
@@ -1783,7 +1859,7 @@ xmlSecGnuTLSKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     "node=%s",
                     xmlSecErrorsSafeString(xmlSecNodeRSAModulus));
-        return(-1);
+        goto done;
     }
 
     /* next is Exponent node. */
@@ -1795,9 +1871,9 @@ xmlSecGnuTLSKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     "node=%s",
                     xmlSecErrorsSafeString(xmlSecNodeRSAExponent));
-        return(-1);
+       goto done;
     }
-    ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, rsa->e, 1);
+    ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, rsa, "e", 1);
     if(ret < 0) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
@@ -1805,11 +1881,11 @@ xmlSecGnuTLSKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     "node=%s",
                     xmlSecErrorsSafeString(xmlSecNodeRSAExponent));
-        return(-1);
+       goto done;
     }
 
     /* next is PrivateExponent node: write it ONLY for private keys and ONLY if it is requested */
-    if(((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) && (rsa->d != NULL)) {
+    if(((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) && (private != 0)) {
         cur = xmlSecAddChild(node, xmlSecNodeRSAPrivateExponent, xmlSecNs);
         if(cur == NULL) {
             xmlSecError(XMLSEC_ERRORS_HERE,
@@ -1818,9 +1894,9 @@ xmlSecGnuTLSKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
                         "node=%s",
                         xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent));
-            return(-1);
+           goto done;
         }
-        ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, rsa->d, 1);
+        ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, rsa, "d", 1);
         if(ret < 0) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
@@ -1828,103 +1904,19 @@ xmlSecGnuTLSKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
                         "node=%s",
                         xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent));
-            return(-1);
+           goto done;
         }
     }
 
-    return(0);
-}
-
-static int
-xmlSecGnuTLSKeyDataRsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
-    RSA* rsa;
-    int ret;
-
-    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
-    xmlSecAssert2(sizeBits > 0, -1);
-
-    rsa = RSA_generate_key(sizeBits, 3, NULL, NULL);
-    if(rsa == NULL) {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-                    "RSA_generate_key",
-                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    "sizeBits=%d", sizeBits);
-        return(-1);
-    }
-
-    ret = xmlSecGnuTLSKeyDataRsaAdoptRsa(data, rsa);
-    if(ret < 0) {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
-                    "xmlSecGnuTLSKeyDataRsaAdoptRsa",
-                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
-        RSA_free(rsa);
-        return(-1);
-    }
-
-    return(0);
-}
-
-static xmlSecKeyDataType
-xmlSecGnuTLSKeyDataRsaGetType(xmlSecKeyDataPtr data) {
-    RSA* rsa;
-
-    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), xmlSecKeyDataTypeUnknown);
-
-    rsa = xmlSecGnuTLSKeyDataRsaGetRsa(data);
-    if((rsa != NULL) && (rsa->n != NULL) && (rsa->e != NULL)) {
-        if(rsa->d != NULL) {
-            return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
-        } else if(rsa->engine != NULL) {
-            /*
-             * !!! HACK !!! Also see DSA key
-             * We assume here that engine *always* has private key.
-             * This might be incorrect but it seems that there is no
-             * way to ask engine if given key is private or not.
-             */
-            return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
-        } else {
-            return(xmlSecKeyDataTypePublic);
-        }
-    }
-
-    return(xmlSecKeyDataTypeUnknown);
-}
-
-static xmlSecSize
-xmlSecGnuTLSKeyDataRsaGetSize(xmlSecKeyDataPtr data) {
-    RSA* rsa;
-
-    xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), 0);
+    /* success */
+    res = 0;
 
-    rsa = xmlSecGnuTLSKeyDataRsaGetRsa(data);
-    if((rsa != NULL) && (rsa->n != NULL)) {
-        return(BN_num_bits(rsa->n));
+done:
+    if(rsa != NULL) {
+        gcry_sexp_release(rsa);
     }
-    return(0);
-}
-
-static void
-xmlSecGnuTLSKeyDataRsaDebugDump(xmlSecKeyDataPtr data, FILE* output) {
-    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId));
-    xmlSecAssert(output != NULL);
-
-    fprintf(output, "=== rsa key: size = %d\n",
-            xmlSecGnuTLSKeyDataRsaGetSize(data));
-}
-
-static void
-xmlSecGnuTLSKeyDataRsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
-    xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId));
-    xmlSecAssert(output != NULL);
 
-    fprintf(output, "<RSAKeyValue size=\"%d\" />\n",
-            xmlSecGnuTLSKeyDataRsaGetSize(data));
+    return(res);
 }
 
 #endif /* XMLSEC_NO_RSA */
-#endif /* ALEKSEY_TODO */
-
-
diff --git a/src/gnutls/crypto.c b/src/gnutls/crypto.c
index a4c345e..3687c65 100644
--- a/src/gnutls/crypto.c
+++ b/src/gnutls/crypto.c
@@ -73,6 +73,11 @@ xmlSecCryptoGetFunctions_gnutls(void) {
     gXmlSecGnuTLSFunctions->keyDataHmacGetKlass         = xmlSecGnuTLSKeyDataHmacGetKlass;
 #endif /* XMLSEC_NO_HMAC */
 
+#ifndef XMLSEC_NO_RSA
+    gXmlSecGnuTLSFunctions->keyDataRsaGetKlass          = xmlSecGnuTLSKeyDataRsaGetKlass;
+#endif /* XMLSEC_NO_RSA */
+
+
     /********************************************************************
      *
      * Key data store ids
@@ -102,16 +107,18 @@ xmlSecCryptoGetFunctions_gnutls(void) {
 #endif /* XMLSEC_NO_DES */
 
     /******************************* DSA ********************************/
+#ifdef ALEKSEY_TODO
+
 #ifndef XMLSEC_NO_DSA
 
 #ifndef XMLSEC_NO_SHA1
-/* ALEKSEY_TODO
     gXmlSecGnuTLSFunctions->transformDsaSha1GetKlass            = xmlSecGnuTLSTransformDsaSha1GetKlass;
-*/
 #endif /* XMLSEC_NO_SHA1 */
 
 #endif /* XMLSEC_NO_DSA */
 
+#endif /* ALEKSEY_TODO */
+
     /******************************* HMAC ********************************/
 #ifndef XMLSEC_NO_HMAC
 
@@ -151,6 +158,44 @@ xmlSecCryptoGetFunctions_gnutls(void) {
     gXmlSecGnuTLSFunctions->transformRipemd160GetKlass          = xmlSecGnuTLSTransformRipemd160GetKlass;
 #endif /* XMLSEC_NO_RIPEMD160 */
 
+    /******************************* RSA ********************************/
+#ifdef ALEKSEY_TODO
+
+#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+    gXmlSecGnuTLSFunctions->transformRsaMd5GetKlass            = xmlSecGnuTLSTransformRsaMd5GetKlass;
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_RIPEMD160
+    gXmlSecGnuTLSFunctions->transformRsaRipemd160GetKlass      = xmlSecGnuTLSTransformRsaRipemd160GetKlass;
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+#ifndef XMLSEC_NO_SHA1
+    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 */
+
+#ifndef XMLSEC_NO_SHA384
+    gXmlSecGnuTLSFunctions->transformRsaSha384GetKlass         = xmlSecGnuTLSTransformRsaSha384GetKlass;
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+    gXmlSecGnuTLSFunctions->transformRsaSha512GetKlass         = xmlSecGnuTLSTransformRsaSha512GetKlass;
+#endif /* XMLSEC_NO_SHA512 */
+
+    gXmlSecGnuTLSFunctions->transformRsaPkcs1GetKlass          = xmlSecGnuTLSTransformRsaPkcs1GetKlass;
+    gXmlSecGnuTLSFunctions->transformRsaOaepGetKlass           = xmlSecGnuTLSTransformRsaOaepGetKlass;
+#endif /* XMLSEC_NO_RSA */
+
+#endif /* ALEKSEY_TODO */
 
     /******************************* SHA ********************************/
 #ifndef XMLSEC_NO_SHA1



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