[xmlsec] adding DSA keys support
- From: Aleksey Sanin <aleksey src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [xmlsec] adding DSA keys support
- Date: Tue, 11 May 2010 04:53:00 +0000 (UTC)
commit bff3494b90ec049f691951ec7ffe208c3acc30ed
Author: Aleksey Sanin <aleksey aleksey com>
Date: Sun May 9 22:34:44 2010 -0700
adding DSA keys support
include/xmlsec/gnutls/crypto.h | 38 +
src/gnutls/Makefile.am | 1 +
src/gnutls/asymkeys.c | 1930 ++++++++++++++++++++++++++++++++++++++++
src/gnutls/crypto.c | 39 +-
4 files changed, 1996 insertions(+), 12 deletions(-)
---
diff --git a/include/xmlsec/gnutls/crypto.h b/include/xmlsec/gnutls/crypto.h
index f7e4efd..23abd20 100644
--- a/include/xmlsec/gnutls/crypto.h
+++ b/include/xmlsec/gnutls/crypto.h
@@ -145,6 +145,44 @@ XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformKWDes3GetKlass(void)
#endif /* XMLSEC_NO_DES */
+/********************************************************************
+ *
+ * DSA transform
+ *
+ *******************************************************************/
+#ifndef XMLSEC_NO_DSA
+#include <gcrypt.h>
+
+/**
+ * xmlSecGnuTLSKeyDataDsaId:
+ *
+ * The DSA key klass.
+ */
+#define xmlSecGnuTLSKeyDataDsaId \
+ xmlSecGnuTLSKeyDataDsaGetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecKeyDataId xmlSecGnuTLSKeyDataDsaGetKlass (void);
+XMLSEC_CRYPTO_EXPORT int xmlSecGnuTLSKeyDataDsaAdoptKey (xmlSecKeyDataPtr data,
+ gcry_sexp_t dsa_key);
+XMLSEC_CRYPTO_EXPORT int xmlSecGnuTLSKeyDataDsaAdoptKeyPair (xmlSecKeyDataPtr data,
+ gcry_sexp_t pub_key,
+ gcry_sexp_t priv_key);
+XMLSEC_CRYPTO_EXPORT gcry_sexp_t xmlSecGnuTLSKeyDataDsaGetPublicKey (xmlSecKeyDataPtr data);
+XMLSEC_CRYPTO_EXPORT gcry_sexp_t xmlSecGnuTLSKeyDataDsaGetPrivateKey (xmlSecKeyDataPtr data);
+
+#ifndef XMLSEC_NO_SHA1
+/**
+ * xmlSecGnuTLSTransformDsaSha1Id:
+ *
+ * The DSA SHA1 signature transform klass.
+ */
+#define xmlSecGnuTLSTransformDsaSha1Id \
+ xmlSecGnuTLSTransformDsaSha1GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecGnuTLSTransformDsaSha1GetKlass(void);
+#endif /* XMLSEC_NO_SHA1 */
+
+#endif /* XMLSEC_NO_DSA */
+
+
/********************************************************************
*
diff --git a/src/gnutls/Makefile.am b/src/gnutls/Makefile.am
index 19750a7..4e12161 100644
--- a/src/gnutls/Makefile.am
+++ b/src/gnutls/Makefile.am
@@ -27,6 +27,7 @@ libxmlsec1_gnutls_la_SOURCES =\
kw_aes.c \
kw_des.c \
symkeys.c \
+ asymkeys.c \
globals.h \
$(NULL)
diff --git a/src/gnutls/asymkeys.c b/src/gnutls/asymkeys.c
new file mode 100644
index 0000000..8c0b60d
--- /dev/null
+++ b/src/gnutls/asymkeys.c
@@ -0,0 +1,1930 @@
+/**
+ * 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 <gnutls/gnutls.h>
+#include <gcrypt.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/base64.h>
+#include <xmlsec/keyinfo.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/crypto.h>
+
+/**************************************************************************
+ *
+ * Helpers
+ *
+ *************************************************************************/
+static gcry_sexp_t xmlSecGnuTLSAsymSExpDup (gcry_sexp_t sexp);
+
+
+/**************************************************************************
+ *
+ * Internal GnuTLS asym key CTX
+ *
+ *************************************************************************/
+typedef struct _xmlSecGnuTLSAsymKeyDataCtx xmlSecGnuTLSAsymKeyDataCtx,
+ *xmlSecGnuTLSAsymKeyDataCtxPtr;
+struct _xmlSecGnuTLSAsymKeyDataCtx {
+ gcry_sexp_t pub_key;
+ gcry_sexp_t priv_key;
+};
+
+/******************************************************************************
+ *
+ * Asym key (dsa/rsa)
+ *
+ * xmlSecGnuTLSAsymKeyDataCtx is located after xmlSecTransform
+ *
+ *****************************************************************************/
+#define xmlSecGnuTLSAsymKeyDataSize \
+ (sizeof(xmlSecKeyData) + sizeof(xmlSecGnuTLSAsymKeyDataCtx))
+#define xmlSecGnuTLSAsymKeyDataGetCtx(data) \
+ ((xmlSecGnuTLSAsymKeyDataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData)))
+
+static int xmlSecGnuTLSAsymKeyDataInitialize (xmlSecKeyDataPtr data);
+static int xmlSecGnuTLSAsymKeyDataDuplicate (xmlSecKeyDataPtr dst,
+ xmlSecKeyDataPtr src);
+static void xmlSecGnuTLSAsymKeyDataFinalize (xmlSecKeyDataPtr data);
+
+static int xmlSecGnuTLSAsymKeyDataAdoptKey (xmlSecKeyDataPtr data,
+ gcry_sexp_t key_pair);
+static int xmlSecGnuTLSAsymKeyDataAdoptKeyPair (xmlSecKeyDataPtr data,
+ gcry_sexp_t pub_key,
+ gcry_sexp_t priv_key);
+static gcry_sexp_t xmlSecGnuTLSAsymKeyDataGetPublicKey (xmlSecKeyDataPtr data);
+static gcry_sexp_t xmlSecGnuTLSAsymKeyDataGetPrivateKey (xmlSecKeyDataPtr data);
+static int xmlSecGnuTLSAsymKeyDataGenerate (xmlSecKeyDataPtr data,
+ const char * alg,
+ xmlSecSize key_size);
+static xmlSecKeyDataType xmlSecGnuTLSAsymKeyDataGetType (xmlSecKeyDataPtr data);
+static xmlSecSize xmlSecGnuTLSAsymKeyDataGetSize (xmlSecKeyDataPtr data);
+
+
+static int
+xmlSecGnuTLSAsymKeyDataInitialize(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize), -1);
+
+ ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ memset(ctx, 0, sizeof(xmlSecGnuTLSAsymKeyDataCtx));
+
+ return(0);
+}
+
+static int
+xmlSecGnuTLSAsymKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctxDst;
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctxSrc;
+
+ xmlSecAssert2(xmlSecKeyDataIsValid(dst), -1);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(dst, xmlSecGnuTLSAsymKeyDataSize), -1);
+ xmlSecAssert2(xmlSecKeyDataIsValid(src), -1);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(src, xmlSecGnuTLSAsymKeyDataSize), -1);
+
+ ctxDst = xmlSecGnuTLSAsymKeyDataGetCtx(dst);
+ xmlSecAssert2(ctxDst != NULL, -1);
+ xmlSecAssert2(ctxDst->pub_key == NULL, -1);
+ xmlSecAssert2(ctxDst->priv_key == NULL, -1);
+
+ ctxSrc = xmlSecGnuTLSAsymKeyDataGetCtx(src);
+ xmlSecAssert2(ctxSrc != NULL, -1);
+
+ if(ctxSrc->pub_key != NULL) {
+ ctxDst->pub_key = xmlSecGnuTLSAsymSExpDup(ctxSrc->pub_key);
+ if(ctxDst->pub_key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
+ "xmlSecGnuTLSAsymSExpDup(pub_key)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ if(ctxSrc->priv_key != NULL) {
+ ctxDst->priv_key = xmlSecGnuTLSAsymSExpDup(ctxSrc->priv_key);
+ if(ctxDst->priv_key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
+ "xmlSecGnuTLSAsymSExpDup(priv_key)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ return(0);
+}
+
+static void
+xmlSecGnuTLSAsymKeyDataFinalize(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
+
+ xmlSecAssert(xmlSecKeyDataIsValid(data));
+ xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize));
+
+ ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
+ xmlSecAssert(ctx != NULL);
+
+ if(ctx->pub_key != NULL) {
+ gcry_sexp_release(ctx->pub_key);
+ }
+ if(ctx->priv_key != NULL) {
+ gcry_sexp_release(ctx->priv_key);
+ }
+ memset(ctx, 0, sizeof(xmlSecGnuTLSAsymKeyDataCtx));
+}
+
+static int
+xmlSecGnuTLSAsymKeyDataAdoptKey(xmlSecKeyDataPtr data, gcry_sexp_t key_pair) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
+ gcry_sexp_t pub_key = NULL;
+ gcry_sexp_t priv_key = NULL;
+ int res = -1;
+
+ xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize), -1);
+ xmlSecAssert2(key_pair != NULL, -1);
+
+ ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ /* split the key pair, public part should be always present, private might
+ not be present */
+ pub_key = gcry_sexp_find_token(key_pair, "public-key", 0);
+ if(pub_key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_find_token(public-key)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ priv_key = gcry_sexp_find_token(key_pair, "private-key", 0);
+
+ /* assign */
+ if(xmlSecGnuTLSAsymKeyDataAdoptKeyPair(data, pub_key, priv_key) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSAsymKeyDataAdoptKeyPair",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ pub_key = NULL; /* data owns it now */
+ priv_key = NULL; /* data owns it now */
+
+ /* success */
+ res = 0;
+
+done:
+ if(pub_key != NULL) {
+ gcry_sexp_release(pub_key);
+ }
+
+ if(priv_key != NULL) {
+ gcry_sexp_release(priv_key);
+ }
+
+ /* done */
+ return(res);
+}
+
+static int
+xmlSecGnuTLSAsymKeyDataAdoptKeyPair(xmlSecKeyDataPtr data, gcry_sexp_t pub_key, gcry_sexp_t priv_key) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize), -1);
+ xmlSecAssert2(pub_key != NULL, -1); /* public key should present always */
+ xmlSecAssert2(((priv_key == NULL) || (gcry_pk_testkey(priv_key) == GPG_ERR_NO_ERROR)), -1);
+
+ ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ /* release prev values and assign new ones */
+ if(ctx->pub_key != NULL) {
+ gcry_sexp_release(ctx->pub_key);
+ }
+ if(ctx->priv_key != NULL) {
+ gcry_sexp_release(ctx->priv_key);
+ }
+
+ ctx->pub_key = pub_key;
+ ctx->priv_key = priv_key;
+
+ /* done */
+ return(0);
+}
+
+static gcry_sexp_t
+xmlSecGnuTLSAsymKeyDataGetPublicKey(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize), NULL);
+
+ ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, NULL);
+
+ return(ctx->pub_key);
+}
+
+static gcry_sexp_t
+xmlSecGnuTLSAsymKeyDataGetPrivateKey(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize), NULL);
+
+ ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, NULL);
+
+ return(ctx->priv_key);
+}
+
+static int
+xmlSecGnuTLSAsymKeyDataGenerate(xmlSecKeyDataPtr data, const char * alg, xmlSecSize key_size) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
+ gcry_sexp_t key_spec = NULL;
+ gcry_sexp_t key_pair = NULL;
+ gcry_error_t err;
+ int ret;
+ int res = -1;
+
+ xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize), -1);
+ xmlSecAssert2(alg != NULL, -1);
+ xmlSecAssert2(key_size > 0, -1);
+
+ ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ err = gcry_sexp_build(&key_spec, NULL,
+ "(genkey (%s (nbits %d)(transient-key)))",
+ alg, (int)key_size);
+ if((err != GPG_ERR_NO_ERROR) || (key_spec == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(genkey)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ goto done;
+ }
+
+ err = gcry_pk_genkey(&key_pair, key_spec);
+ if((err != GPG_ERR_NO_ERROR) || (key_pair == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_pk_genkey",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ goto done;
+ }
+
+ ret = xmlSecGnuTLSAsymKeyDataAdoptKey(data, key_pair);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSAsymKeyDataAdopt",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "ret=%d", (int)ret);
+ goto done;
+ }
+ key_pair = NULL; /* now owned by data */
+
+ /* success */
+ res = 0;
+
+done:
+ if(key_spec != NULL) {
+ gcry_sexp_release(key_spec);
+ }
+ if(key_pair != NULL) {
+ gcry_sexp_release(key_pair);
+ }
+
+ return(res);
+}
+
+static xmlSecKeyDataType
+xmlSecGnuTLSAsymKeyDataGetType(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize), xmlSecKeyDataTypeUnknown);
+
+ ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, xmlSecKeyDataTypeUnknown);
+
+ if((ctx->priv_key != NULL) && (ctx->pub_key != NULL)) {
+ return (xmlSecKeyDataTypePrivate);
+ } else if(ctx->pub_key != NULL) {
+ return (xmlSecKeyDataTypePublic);
+ }
+
+ return (xmlSecKeyDataTypeUnknown);
+}
+
+static xmlSecSize
+xmlSecGnuTLSAsymKeyDataGetSize(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
+ xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGnuTLSAsymKeyDataSize), xmlSecKeyDataTypeUnknown);
+
+ ctx = xmlSecGnuTLSAsymKeyDataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, 0);
+
+ /* use pub key since it is more often you have it than not */
+ return (ctx->pub_key != NULL) ? gcry_pk_get_nbits(ctx->pub_key) : 0;
+}
+
+/******************************************************************************
+ *
+ * helper functions
+ *
+ *****************************************************************************/
+static gcry_sexp_t
+xmlSecGnuTLSAsymSExpDup(gcry_sexp_t pKey) {
+ gcry_sexp_t res = NULL;
+ xmlSecByte *buf = NULL;
+ gcry_error_t ret;
+ size_t size;
+
+ xmlSecAssert2(pKey != NULL, NULL);
+
+ size = gcry_sexp_sprint(pKey, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ if(size == 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_sprint",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ buf = (xmlSecByte *)xmlMalloc(size);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)size);
+ goto done;
+ }
+
+ size = gcry_sexp_sprint(pKey, GCRYSEXP_FMT_ADVANCED, buf, size);
+ if(size == 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_sprint",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "size=%d", (int)size);
+ goto done;
+ }
+
+ ret = gcry_sexp_new(&res, buf, size, 1);
+ if((ret != GPG_ERR_NO_ERROR) || (res == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_new",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "ret=%d", (int)ret);
+ goto done;
+ }
+
+done:
+ if(buf != NULL) {
+ xmlFree(buf);
+ }
+ return (res);
+}
+
+/**
+ * xmlSecGnuTLSNodeGetMpiValue:
+ * @cur: the poitner to an XML node.
+ *
+ * Converts the node content from CryptoBinary format
+ * (http://www.w3.org/TR/xmldsig-core/#sec-CryptoBinary)
+ * to a BIGNUM. If no BIGNUM buffer provided then a new
+ * BIGNUM is created (caller is responsible for freeing it).
+ *
+ * Returns: a pointer to MPI produced from CryptoBinary string
+ * or NULL if an error occurs.
+ */
+static gcry_mpi_t
+xmlSecGnuTLSNodeGetMpiValue(const xmlNodePtr cur) {
+ xmlSecBuffer buf;
+ gcry_mpi_t res = NULL;
+ gcry_error_t err;
+ int ret;
+
+ xmlSecAssert2(cur != NULL, NULL);
+
+ ret = xmlSecBufferInitialize(&buf, 128);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ ret = xmlSecBufferBase64NodeContentRead(&buf, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferBase64NodeContentRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecBufferFinalize(&buf);
+ return(NULL);
+ }
+
+ err = gcry_mpi_scan(&res, GCRYMPI_FMT_USG,
+ xmlSecBufferGetData(&buf),
+ xmlSecBufferGetSize(&buf),
+ NULL);
+ if((err != GPG_ERR_NO_ERROR) || (res == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_mpi_scan",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "err=%d", (int)err);
+ xmlSecBufferFinalize(&buf);
+ return(NULL);
+ }
+
+ /* done */
+ xmlSecBufferFinalize(&buf);
+ return(res);
+}
+
+/**
+ * xmlSecGnuTLSNodeSetMpiValue:
+ * @cur: the pointer to an XML node.
+ * @a: the mpi value
+ * @addLineBreaks: if the flag is equal to 1 then
+ * linebreaks will be added before and after
+ * new buffer content.
+ *
+ * Converts MPI to CryptoBinary string
+ * (http://www.w3.org/TR/xmldsig-core/#sec-CryptoBinary)
+ * and sets it as the content of the given node. If the
+ * addLineBreaks is set then line breaks are added
+ * before and after the CryptoBinary string.
+ *
+ * Returns: 0 on success or -1 otherwise.
+ */
+static int
+xmlSecGnuTLSNodeSetMpiValue(xmlNodePtr cur, const gcry_mpi_t a, int addLineBreaks) {
+ xmlSecBuffer buf;
+ gcry_error_t err;
+ size_t written = 0;
+ int ret;
+
+ xmlSecAssert2(a != NULL, -1);
+ xmlSecAssert2(cur != NULL, -1);
+
+ 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);
+ }
+
+ ret = xmlSecBufferInitialize(&buf, written + 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", (int)written + 1);
+ return(-1);
+ }
+
+ written = 0;
+ err = gcry_mpi_print(GCRYMPI_FMT_USG,
+ xmlSecBufferGetData(&buf),
+ xmlSecBufferGetMaxSize(&buf),
+ &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(&buf));
+ xmlSecBufferFinalize(&buf);
+ return(-1);
+ }
+
+ ret = xmlSecBufferSetSize(&buf, written);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferSetSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "written=%d", (int)written);
+ xmlSecBufferFinalize(&buf);
+ return(-1);
+ }
+
+ if(addLineBreaks) {
+ xmlNodeSetContent(cur, xmlSecStringCR);
+ } else {
+ xmlNodeSetContent(cur, xmlSecStringEmpty);
+ }
+
+ ret = xmlSecBufferBase64NodeContentWrite(&buf, cur, xmlSecBase64GetDefaultLineSize());
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferBase64NodeContentWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecBufferFinalize(&buf);
+ return(-1);
+ }
+
+ if(addLineBreaks) {
+ xmlNodeAddContent(cur, xmlSecStringCR);
+ }
+
+ xmlSecBufferFinalize(&buf);
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSNodeSetSExpTokValue:
+ * @cur: the pointer to an XML node.
+ * @sexp: the sexp
+ * @tok: the token
+ * @addLineBreaks: if the flag is equal to 1 then
+ * linebreaks will be added before and after
+ * new buffer content.
+ *
+ * Converts MPI to CryptoBinary string
+ * (http://www.w3.org/TR/xmldsig-core/#sec-CryptoBinary)
+ * and sets it as the content of the given node. If the
+ * addLineBreaks is set then line breaks are added
+ * before and after the CryptoBinary string.
+ *
+ * Returns: 0 on success or -1 otherwise.
+ */
+static int
+xmlSecGnuTLSNodeSetSExpTokValue(xmlNodePtr cur, const gcry_sexp_t sexp,
+ const char * tok, int addLineBreaks)
+{
+ gcry_sexp_t val = NULL;
+ gcry_mpi_t mpi = NULL;
+ int res = -1;
+
+ xmlSecAssert2(cur != NULL, -1);
+ xmlSecAssert2(sexp != NULL, -1);
+ xmlSecAssert2(tok != NULL, -1);
+
+ val = gcry_sexp_find_token(sexp, tok, 0);
+ if(val == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_find_token",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "tok=%s",
+ xmlSecErrorsSafeString(tok));
+ goto done;
+ }
+
+ mpi = gcry_sexp_nth_mpi(val, 1, GCRYMPI_FMT_USG);
+ if(mpi == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_nth_mpi",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "tok=%s",
+ xmlSecErrorsSafeString(tok));
+ goto done;
+ }
+
+ /* almost done */
+ res = xmlSecGnuTLSNodeSetMpiValue(cur, mpi, addLineBreaks);
+
+done:
+ if(mpi != NULL) {
+ gcry_mpi_release(mpi);
+ }
+ if(val != NULL) {
+ gcry_sexp_release(val);
+ }
+
+ return(res);
+}
+
+#ifndef XMLSEC_NO_DSA
+/**************************************************************************
+ *
+ * <dsig:DSAKeyValue> processing
+ *
+ *
+ * The DSAKeyValue Element (http://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue)
+ *
+ * DSA keys and the DSA signature algorithm are specified in [DSS].
+ * DSA public key values can have the following fields:
+ *
+ * * P - a prime modulus meeting the [DSS] requirements
+ * * Q - an integer in the range 2**159 < Q < 2**160 which is a prime
+ * divisor of P-1
+ * * G - an integer with certain properties with respect to P and Q
+ * * Y - G**X mod P (where X is part of the private key and not made
+ * public)
+ * * J - (P - 1) / Q
+ * * seed - a DSA prime generation seed
+ * * pgenCounter - a DSA prime generation counter
+ *
+ * Parameter J is available for inclusion solely for efficiency as it is
+ * calculatable from P and Q. Parameters seed and pgenCounter are used in the
+ * DSA prime number generation algorithm specified in [DSS]. As such, they are
+ * optional but must either both be present or both be absent. This prime
+ * generation algorithm is designed to provide assurance that a weak prime is
+ * not being used and it yields a P and Q value. Parameters P, Q, and G can be
+ * public and common to a group of users. They might be known from application
+ * context. As such, they are optional but P and Q must either both appear or
+ * both be absent. If all of P, Q, seed, and pgenCounter are present,
+ * implementations are not required to check if they are consistent and are
+ * free to use either P and Q or seed and pgenCounter. All parameters are
+ * encoded as base64 [MIME] values.
+ *
+ * Arbitrary-length integers (e.g. "bignums" such as RSA moduli) are
+ * represented in XML as octet strings as defined by the ds:CryptoBinary type.
+ *
+ * Schema Definition:
+ *
+ * <element name="DSAKeyValue" type="ds:DSAKeyValueType"/>
+ * <complexType name="DSAKeyValueType">
+ * <sequence>
+ * <sequence minOccurs="0">
+ * <element name="P" type="ds:CryptoBinary"/>
+ * <element name="Q" type="ds:CryptoBinary"/>
+ * </sequence>
+ * <element name="G" type="ds:CryptoBinary" minOccurs="0"/>
+ * <element name="Y" type="ds:CryptoBinary"/>
+ * <element name="J" type="ds:CryptoBinary" minOccurs="0"/>
+ * <sequence minOccurs="0">
+ * <element name="Seed" type="ds:CryptoBinary"/>
+ * <element name="PgenCounter" type="ds:CryptoBinary"/>
+ * </sequence>
+ * </sequence>
+ * </complexType>
+ *
+ * DTD Definition:
+ *
+ * <!ELEMENT DSAKeyValue ((P, Q)?, G?, Y, J?, (Seed, PgenCounter)?) >
+ * <!ELEMENT P (#PCDATA) >
+ * <!ELEMENT Q (#PCDATA) >
+ * <!ELEMENT G (#PCDATA) >
+ * <!ELEMENT Y (#PCDATA) >
+ * <!ELEMENT J (#PCDATA) >
+ * <!ELEMENT Seed (#PCDATA) >
+ * <!ELEMENT PgenCounter (#PCDATA) >
+ *
+ * ============================================================================
+ *
+ * To support reading/writing private keys an X element added (before Y).
+ * todo: The current implementation does not support Seed and PgenCounter!
+ * by this the P, Q and G are *required*!
+ *
+ *************************************************************************/
+static int xmlSecGnuTLSKeyDataDsaInitialize (xmlSecKeyDataPtr data);
+static int xmlSecGnuTLSKeyDataDsaDuplicate (xmlSecKeyDataPtr dst,
+ xmlSecKeyDataPtr src);
+static void xmlSecGnuTLSKeyDataDsaFinalize (xmlSecKeyDataPtr data);
+static int xmlSecGnuTLSKeyDataDsaXmlRead (xmlSecKeyDataId id,
+ xmlSecKeyPtr key,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSKeyDataDsaXmlWrite (xmlSecKeyDataId id,
+ xmlSecKeyPtr key,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSKeyDataDsaGenerate (xmlSecKeyDataPtr data,
+ xmlSecSize sizeBits,
+ xmlSecKeyDataType type);
+
+static xmlSecKeyDataType xmlSecGnuTLSKeyDataDsaGetType (xmlSecKeyDataPtr data);
+static xmlSecSize xmlSecGnuTLSKeyDataDsaGetSize (xmlSecKeyDataPtr data);
+static void xmlSecGnuTLSKeyDataDsaDebugDump (xmlSecKeyDataPtr data,
+ FILE* output);
+static void xmlSecGnuTLSKeyDataDsaDebugXmlDump (xmlSecKeyDataPtr data,
+ FILE* output);
+
+static xmlSecKeyDataKlass xmlSecGnuTLSKeyDataDsaKlass = {
+ sizeof(xmlSecKeyDataKlass),
+ xmlSecGnuTLSAsymKeyDataSize,
+
+ /* data */
+ xmlSecNameDSAKeyValue,
+ xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
+ /* xmlSecKeyDataUsage usage; */
+ xmlSecHrefDSAKeyValue, /* const xmlChar* href; */
+ xmlSecNodeDSAKeyValue, /* const xmlChar* dataNodeName; */
+ xmlSecDSigNs, /* const xmlChar* dataNodeNs; */
+
+ /* constructors/destructor */
+ xmlSecGnuTLSKeyDataDsaInitialize, /* xmlSecKeyDataInitializeMethod initialize; */
+ xmlSecGnuTLSKeyDataDsaDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */
+ xmlSecGnuTLSKeyDataDsaFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */
+ xmlSecGnuTLSKeyDataDsaGenerate, /* xmlSecKeyDataGenerateMethod generate; */
+
+ /* get info */
+ xmlSecGnuTLSKeyDataDsaGetType, /* xmlSecKeyDataGetTypeMethod getType; */
+ xmlSecGnuTLSKeyDataDsaGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */
+ NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */
+
+ /* read/write */
+ xmlSecGnuTLSKeyDataDsaXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */
+ xmlSecGnuTLSKeyDataDsaXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
+ NULL, /* xmlSecKeyDataBinReadMethod binRead; */
+ NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */
+
+ /* debug */
+ xmlSecGnuTLSKeyDataDsaDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */
+ xmlSecGnuTLSKeyDataDsaDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
+
+ /* reserved for the future */
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGnuTLSKeyDataDsaGetKlass:
+ *
+ * The DSA key data klass.
+ *
+ * Returns: pointer to DSA key data klass.
+ */
+xmlSecKeyDataId
+xmlSecGnuTLSKeyDataDsaGetKlass(void) {
+ return(&xmlSecGnuTLSKeyDataDsaKlass);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataDsaAdoptKey:
+ * @data: the pointer to DSA key data.
+ * @dsa_key: the pointer to GnuTLS DSA key.
+ *
+ * Sets the value of DSA key data.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSKeyDataDsaAdoptKey(xmlSecKeyDataPtr data, gcry_sexp_t dsa_key) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1);
+ xmlSecAssert2(dsa_key != NULL, -1);
+
+ return xmlSecGnuTLSAsymKeyDataAdoptKey(data, dsa_key);
+}
+
+
+/**
+ * xmlSecGnuTLSKeyDataDsaAdoptKeyPair:
+ * @data: the pointer to DSA key data.
+ * @pub_key: the pointer to GnuTLS DSA pub key.
+ * @priv_key: the pointer to GnuTLS DSA priv key.
+ *
+ * Sets the value of DSA key data.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSKeyDataDsaAdoptKeyPair(xmlSecKeyDataPtr data, gcry_sexp_t pub_key, gcry_sexp_t priv_key) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1);
+ xmlSecAssert2(pub_key != NULL, -1);
+
+ return xmlSecGnuTLSAsymKeyDataAdoptKeyPair(data, pub_key, priv_key);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataDsaGetPublicKey:
+ * @data: the pointer to DSA key data.
+ *
+ * Gets the GnuTLS DSA public key from DSA key data.
+ *
+ * Returns: pointer to GnuTLS public DSA key or NULL if an error occurs.
+ */
+gcry_sexp_t
+xmlSecGnuTLSKeyDataDsaGetPublicKey(xmlSecKeyDataPtr data) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), NULL);
+ return xmlSecGnuTLSAsymKeyDataGetPublicKey(data);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataDsaGetPrivateKey:
+ * @data: the pointer to DSA key data.
+ *
+ * Gets the GnuTLS DSA private key from DSA key data.
+ *
+ * Returns: pointer to GnuTLS private DSA key or NULL if an error occurs.
+ */
+gcry_sexp_t
+xmlSecGnuTLSKeyDataDsaGetPrivateKey(xmlSecKeyDataPtr data) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), NULL);
+ return xmlSecGnuTLSAsymKeyDataGetPrivateKey(data);
+}
+
+static int
+xmlSecGnuTLSKeyDataDsaInitialize(xmlSecKeyDataPtr data) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1);
+
+ return(xmlSecGnuTLSAsymKeyDataInitialize(data));
+}
+
+static int
+xmlSecGnuTLSKeyDataDsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecGnuTLSKeyDataDsaId), -1);
+ xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecGnuTLSKeyDataDsaId), -1);
+
+ return(xmlSecGnuTLSAsymKeyDataDuplicate(dst, src));
+}
+
+static void
+xmlSecGnuTLSKeyDataDsaFinalize(xmlSecKeyDataPtr data) {
+ xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId));
+
+ xmlSecGnuTLSAsymKeyDataFinalize(data);
+}
+
+
+static int
+xmlSecGnuTLSKeyDataDsaXmlRead(xmlSecKeyDataId id,
+ xmlSecKeyPtr key,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx)
+{
+ xmlNodePtr cur;
+ xmlSecKeyDataPtr data = NULL;
+ gcry_mpi_t p = NULL;
+ gcry_mpi_t q = NULL;
+ gcry_mpi_t g = NULL;
+ gcry_mpi_t x = NULL;
+ gcry_mpi_t y = NULL;
+ gcry_sexp_t pub_key = NULL;
+ gcry_sexp_t priv_key = NULL;
+ gcry_error_t err;
+ int res = -1;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecGnuTLSKeyDataDsaId, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ if(xmlSecKeyGetValue(key) != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_KEY_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ cur = xmlSecGetNextElementNode(node->children);
+
+ /* first is P node. It is REQUIRED because we do not support Seed and PgenCounter*/
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAP, xmlSecDSigNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAP));
+ goto done;
+ }
+ p = xmlSecGnuTLSNodeGetMpiValue(cur);
+ if(p == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeGetMpiValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAP));
+ goto done;
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* next is Q node. It is REQUIRED because we do not support Seed and PgenCounter*/
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAQ, xmlSecDSigNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAQ));
+ goto done;
+ }
+ q = xmlSecGnuTLSNodeGetMpiValue(cur);
+ if(q == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeGetMpiValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAQ));
+ goto done;
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* next is G node. It is REQUIRED because we do not support Seed and PgenCounter*/
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAG, xmlSecDSigNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAG));
+ goto done;
+ }
+ g = xmlSecGnuTLSNodeGetMpiValue(cur);
+ if(g == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeGetMpiValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAG));
+ goto done;
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAX, xmlSecNs))) {
+ /* next is X node. It is REQUIRED for private key but
+ * we are not sure exactly what do we read */
+ x = xmlSecGnuTLSNodeGetMpiValue(cur);
+ if(x == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeGetMpiValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAX));
+ goto done;
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* next is Y node. */
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAY, xmlSecDSigNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAY));
+ goto done;
+ }
+ y = xmlSecGnuTLSNodeGetMpiValue(cur);
+ if(y == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeGetMpiValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s", xmlSecErrorsSafeString(xmlSecNodeDSAY));
+ goto done;
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* todo: add support for J */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAJ, xmlSecDSigNs))) {
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* todo: add support for seed */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSASeed, xmlSecDSigNs))) {
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* todo: add support for pgencounter */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAPgenCounter, xmlSecDSigNs))) {
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+
+ /* construct pub/priv key pairs */
+ err = gcry_sexp_build(&pub_key, NULL,
+ "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+ p, q, g, y);
+ 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(x != NULL) {
+ err = gcry_sexp_build(&priv_key, NULL,
+ "(private-key(dsa(p%m)(q%m)(g%m)(x%m)(y%m)))",
+ p, q, g, x, y);
+ 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,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ ret = xmlSecGnuTLSKeyDataDsaAdoptKeyPair(data, pub_key, priv_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataDsaAdoptKeyPair",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ 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(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(p != NULL) {
+ gcry_mpi_release(p);
+ }
+
+ if(q != NULL) {
+ gcry_mpi_release(q);
+ }
+
+ if(g != NULL) {
+ gcry_mpi_release(g);
+ }
+
+ if(x != NULL) {
+ gcry_mpi_release(x);
+ }
+
+ if(y != NULL) {
+ gcry_mpi_release(y);
+ }
+
+ if(pub_key != NULL) {
+ gcry_sexp_release(pub_key);
+ }
+
+ if(priv_key != NULL) {
+ gcry_sexp_release(priv_key);
+ }
+
+ if(data != NULL) {
+ xmlSecKeyDataDestroy(data);
+ }
+ return(res);
+}
+
+static int
+xmlSecGnuTLSKeyDataDsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
+ xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlNodePtr cur;
+ gcry_sexp_t pub_priv_key;
+ gcry_sexp_t dsa = NULL;
+ int private = 0;
+ int res = -1;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecGnuTLSKeyDataDsaId, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecGnuTLSKeyDataDsaId), -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != 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 = xmlSecGnuTLSKeyDataDsaGetPrivateKey(xmlSecKeyGetValue(key));
+ if(pub_priv_key == NULL) {
+ pub_priv_key = xmlSecGnuTLSKeyDataDsaGetPublicKey(xmlSecKeyGetValue(key));
+ if(pub_priv_key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSKeyDataDsaGetPublicKey()",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ } else {
+ private = 1;
+ }
+
+ dsa = gcry_sexp_find_token(pub_priv_key, "dsa", 0);
+ if(dsa == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "gcry_sexp_find_token(dsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* first is P node */
+ cur = xmlSecAddChild(node, xmlSecNodeDSAP, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAP));
+ goto done;
+ }
+ ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, dsa, "p", 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeSetSExpTokValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAP));
+ goto done;
+ }
+
+ /* next is Q node. */
+ cur = xmlSecAddChild(node, xmlSecNodeDSAQ, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAQ));
+ goto done;
+ }
+ ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, dsa, "q", 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeSetSExpTokValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAQ));
+ goto done;
+ }
+
+ /* next is G node. */
+ cur = xmlSecAddChild(node, xmlSecNodeDSAG, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAG));
+ goto done;
+ }
+ ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, dsa, "g", 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeSetSExpTokValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAG));
+ goto done;
+ }
+
+ /* next is X node: write it ONLY for private keys and ONLY if it is requested */
+ if(((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) && (private != 0)) {
+ cur = xmlSecAddChild(node, xmlSecNodeDSAX, xmlSecNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAX));
+ goto done;
+ }
+ ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, dsa, "x", 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeSetSExpTokValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAX));
+ goto done;
+ }
+ }
+
+ /* next is Y node. */
+ cur = xmlSecAddChild(node, xmlSecNodeDSAY, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAY));
+ goto done;
+ }
+ ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, dsa, "y", 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeSetSExpTokValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDSAY));
+ goto done;
+ }
+
+ /* success */
+ res = 0;
+
+done:
+ if(dsa != NULL) {
+ gcry_sexp_release(dsa);
+ }
+
+ 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
+/**************************************************************************
+ *
+ * <dsig:RSAKeyValue> processing
+ *
+ * http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
+ * The RSAKeyValue Element
+ *
+ * RSA key values have two fields: Modulus and Exponent.
+ *
+ * <RSAKeyValue>
+ * <Modulus>xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6W
+ * jubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV
+ * 5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U=
+ * </Modulus>
+ * <Exponent>AQAB</Exponent>
+ * </RSAKeyValue>
+ *
+ * Arbitrary-length integers (e.g. "bignums" such as RSA moduli) are
+ * represented in XML as octet strings as defined by the ds:CryptoBinary type.
+ *
+ * Schema Definition:
+ *
+ * <element name="RSAKeyValue" type="ds:RSAKeyValueType"/>
+ * <complexType name="RSAKeyValueType">
+ * <sequence>
+ * <element name="Modulus" type="ds:CryptoBinary"/>
+ * <element name="Exponent" type="ds:CryptoBinary"/>
+ * </sequence>
+ * </complexType>
+ *
+ * DTD Definition:
+ *
+ * <!ELEMENT RSAKeyValue (Modulus, Exponent) >
+ * <!ELEMENT Modulus (#PCDATA) >
+ * <!ELEMENT Exponent (#PCDATA) >
+ *
+ * ============================================================================
+ *
+ * To support reading/writing private keys an PrivateExponent element is added
+ * to the end
+ *
+ *************************************************************************/
+
+static int xmlSecGnuTLSKeyDataRsaInitialize (xmlSecKeyDataPtr data);
+static int xmlSecGnuTLSKeyDataRsaDuplicate (xmlSecKeyDataPtr dst,
+ xmlSecKeyDataPtr src);
+static void xmlSecGnuTLSKeyDataRsaFinalize (xmlSecKeyDataPtr data);
+static int xmlSecGnuTLSKeyDataRsaXmlRead (xmlSecKeyDataId id,
+ xmlSecKeyPtr key,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSKeyDataRsaXmlWrite (xmlSecKeyDataId id,
+ xmlSecKeyPtr key,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSKeyDataRsaGenerate (xmlSecKeyDataPtr data,
+ xmlSecSize sizeBits,
+ xmlSecKeyDataType type);
+
+static xmlSecKeyDataType xmlSecGnuTLSKeyDataRsaGetType (xmlSecKeyDataPtr data);
+static xmlSecSize xmlSecGnuTLSKeyDataRsaGetSize (xmlSecKeyDataPtr data);
+static void xmlSecGnuTLSKeyDataRsaDebugDump (xmlSecKeyDataPtr data,
+ FILE* output);
+static void xmlSecGnuTLSKeyDataRsaDebugXmlDump (xmlSecKeyDataPtr data,
+ FILE* output);
+static xmlSecKeyDataKlass xmlSecGnuTLSKeyDataRsaKlass = {
+ sizeof(xmlSecKeyDataKlass),
+ xmlSecGnuTLSAsymKeyDataSize,
+
+ /* data */
+ xmlSecNameRSAKeyValue,
+ xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
+ /* xmlSecKeyDataUsage usage; */
+ xmlSecHrefRSAKeyValue, /* const xmlChar* href; */
+ xmlSecNodeRSAKeyValue, /* const xmlChar* dataNodeName; */
+ xmlSecDSigNs, /* const xmlChar* dataNodeNs; */
+
+ /* constructors/destructor */
+ xmlSecGnuTLSKeyDataRsaInitialize, /* xmlSecKeyDataInitializeMethod initialize; */
+ xmlSecGnuTLSKeyDataRsaDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */
+ xmlSecGnuTLSKeyDataRsaFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */
+ xmlSecGnuTLSKeyDataRsaGenerate, /* xmlSecKeyDataGenerateMethod generate; */
+
+ /* get info */
+ xmlSecGnuTLSKeyDataRsaGetType, /* xmlSecKeyDataGetTypeMethod getType; */
+ xmlSecGnuTLSKeyDataRsaGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */
+ NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */
+
+ /* read/write */
+ xmlSecGnuTLSKeyDataRsaXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */
+ xmlSecGnuTLSKeyDataRsaXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
+ NULL, /* xmlSecKeyDataBinReadMethod binRead; */
+ NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */
+
+ /* debug */
+ xmlSecGnuTLSKeyDataRsaDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */
+ xmlSecGnuTLSKeyDataRsaDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
+
+ /* reserved for the future */
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGnuTLSKeyDataRsaGetKlass:
+ *
+ * The GnuTLS RSA key data klass.
+ *
+ * Returns: pointer to GnuTLS RSA key data klass.
+ */
+xmlSecKeyDataId
+xmlSecGnuTLSKeyDataRsaGetKlass(void) {
+ return(&xmlSecGnuTLSKeyDataRsaKlass);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataRsaAdoptRsa:
+ * @data: the pointer to RSA key data.
+ * @rsa: 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;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -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);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataRsaGetRsa:
+ * @data: the pointer to RSA key data.
+ *
+ * Gets the GnuTLS RSA key from RSA key data.
+ *
+ * Returns: pointer to GnuTLS RSA key or NULL if an error occurs.
+ */
+RSA*
+xmlSecGnuTLSKeyDataRsaGetRsa(xmlSecKeyDataPtr data) {
+ EVP_PKEY* pKey;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), NULL);
+
+ pKey = xmlSecGnuTLSKeyDataRsaGetEvp(data);
+ xmlSecAssert2((pKey == NULL) || (pKey->type == EVP_PKEY_RSA), NULL);
+
+ return((pKey != NULL) ? pKey->pkey.rsa : (RSA*)NULL);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataRsaAdoptEvp:
+ * @data: the pointer to RSA key data.
+ * @pKey: the pointer to GnuTLS EVP key.
+ *
+ * Sets the RSA key data value to GnuTLS EVP key.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+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));
+}
+
+/**
+ * xmlSecGnuTLSKeyDataRsaGetEvp:
+ * @data: the pointer to RSA key data.
+ *
+ * Gets the GnuTLS EVP key from RSA key data.
+ *
+ * Returns: pointer to GnuTLS EVP key or NULL if an error occurs.
+ */
+EVP_PKEY*
+xmlSecGnuTLSKeyDataRsaGetEvp(xmlSecKeyDataPtr data) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), NULL);
+
+ return(xmlSecGnuTLSAsymKeyDataGetEvp(data));
+}
+
+static int
+xmlSecGnuTLSKeyDataRsaInitialize(xmlSecKeyDataPtr data) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
+
+ return(xmlSecGnuTLSAsymKeyDataInitialize(data));
+}
+
+static int
+xmlSecGnuTLSKeyDataRsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecGnuTLSKeyDataRsaId), -1);
+ xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecGnuTLSKeyDataRsaId), -1);
+
+ return(xmlSecGnuTLSAsymKeyDataDuplicate(dst, src));
+}
+
+static void
+xmlSecGnuTLSKeyDataRsaFinalize(xmlSecKeyDataPtr data) {
+ xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId));
+
+ xmlSecGnuTLSAsymKeyDataFinalize(data);
+}
+
+static int
+xmlSecGnuTLSKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
+ xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecKeyDataPtr data;
+ xmlNodePtr cur;
+ RSA *rsa;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecGnuTLSKeyDataRsaId, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ if(xmlSecKeyGetValue(key) != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ 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);
+ }
+
+ cur = xmlSecGetNextElementNode(node->children);
+
+ /* first is Modulus node. It is REQUIRED because we do not support Seed and PgenCounter*/
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeRSAModulus, xmlSecDSigNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAModulus));
+ RSA_free(rsa);
+ return(-1);
+ }
+ if(xmlSecGnuTLSNodeGetMpiValue(cur, &(rsa->n)) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeGetMpiValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAModulus));
+ RSA_free(rsa);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* next is Exponent node. It is REQUIRED because we do not support Seed and PgenCounter*/
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeRSAExponent, xmlSecDSigNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAExponent));
+ RSA_free(rsa);
+ return(-1);
+ }
+ if(xmlSecGnuTLSNodeGetMpiValue(cur, &(rsa->e)) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeGetMpiValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAExponent));
+ RSA_free(rsa);
+ return(-1);
+ }
+ 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) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeGetMpiValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent));
+ RSA_free(rsa);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "no nodes expected");
+ RSA_free(rsa);
+ return(-1);
+ }
+
+ data = xmlSecKeyDataCreate(id);
+ if(data == NULL ) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ RSA_free(rsa);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataRsaAdoptRsa(data, rsa);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSKeyDataRsaAdoptRsa",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDataDestroy(data);
+ RSA_free(rsa);
+ return(-1);
+ }
+
+ ret = xmlSecKeySetValue(key, data);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecKeySetValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDataDestroy(data);
+ return(-1);
+ }
+
+ return(0);
+}
+
+static int
+xmlSecGnuTLSKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
+ xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlNodePtr cur;
+ RSA* rsa;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecGnuTLSKeyDataRsaId, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecGnuTLSKeyDataRsaId), -1);
+ 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);
+ }
+
+ /* first is Modulus node */
+ cur = xmlSecAddChild(node, xmlSecNodeRSAModulus, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAModulus));
+ return(-1);
+ }
+ ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, rsa->n, 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeSetSExpTokValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAModulus));
+ return(-1);
+ }
+
+ /* next is Exponent node. */
+ cur = xmlSecAddChild(node, xmlSecNodeRSAExponent, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAExponent));
+ return(-1);
+ }
+ ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, rsa->e, 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeSetSExpTokValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAExponent));
+ return(-1);
+ }
+
+ /* 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)) {
+ cur = xmlSecAddChild(node, xmlSecNodeRSAPrivateExponent, xmlSecNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent));
+ return(-1);
+ }
+ ret = xmlSecGnuTLSNodeSetSExpTokValue(cur, rsa->d, 1);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSNodeSetSExpTokValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent));
+ return(-1);
+ }
+ }
+
+ 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);
+
+ rsa = xmlSecGnuTLSKeyDataRsaGetRsa(data);
+ if((rsa != NULL) && (rsa->n != NULL)) {
+ return(BN_num_bits(rsa->n));
+ }
+ 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));
+}
+
+#endif /* XMLSEC_NO_RSA */
+#endif /* ALEKSEY_TODO */
+
+
diff --git a/src/gnutls/crypto.c b/src/gnutls/crypto.c
index e56b190..a4c345e 100644
--- a/src/gnutls/crypto.c
+++ b/src/gnutls/crypto.c
@@ -65,6 +65,10 @@ xmlSecCryptoGetFunctions_gnutls(void) {
gXmlSecGnuTLSFunctions->keyDataDesGetKlass = xmlSecGnuTLSKeyDataDesGetKlass;
#endif /* XMLSEC_NO_DES */
+#ifndef XMLSEC_NO_DSA
+ gXmlSecGnuTLSFunctions->keyDataDsaGetKlass = xmlSecGnuTLSKeyDataDsaGetKlass;
+#endif /* XMLSEC_NO_DSA */
+
#ifndef XMLSEC_NO_HMAC
gXmlSecGnuTLSFunctions->keyDataHmacGetKlass = xmlSecGnuTLSKeyDataHmacGetKlass;
#endif /* XMLSEC_NO_HMAC */
@@ -97,61 +101,72 @@ xmlSecCryptoGetFunctions_gnutls(void) {
gXmlSecGnuTLSFunctions->transformKWDes3GetKlass = xmlSecGnuTLSTransformKWDes3GetKlass;
#endif /* XMLSEC_NO_DES */
+ /******************************* DSA ********************************/
+#ifndef XMLSEC_NO_DSA
+
+#ifndef XMLSEC_NO_SHA1
+/* ALEKSEY_TODO
+ gXmlSecGnuTLSFunctions->transformDsaSha1GetKlass = xmlSecGnuTLSTransformDsaSha1GetKlass;
+*/
+#endif /* XMLSEC_NO_SHA1 */
+
+#endif /* XMLSEC_NO_DSA */
+
/******************************* HMAC ********************************/
#ifndef XMLSEC_NO_HMAC
#ifndef XMLSEC_NO_MD5
- gXmlSecGnuTLSFunctions->transformHmacMd5GetKlass = xmlSecGnuTLSTransformHmacMd5GetKlass;
+ gXmlSecGnuTLSFunctions->transformHmacMd5GetKlass = xmlSecGnuTLSTransformHmacMd5GetKlass;
#endif /* XMLSEC_NO_MD5 */
#ifndef XMLSEC_NO_RIPEMD160
- gXmlSecGnuTLSFunctions->transformHmacRipemd160GetKlass = xmlSecGnuTLSTransformHmacRipemd160GetKlass;
+ gXmlSecGnuTLSFunctions->transformHmacRipemd160GetKlass = xmlSecGnuTLSTransformHmacRipemd160GetKlass;
#endif /* XMLSEC_NO_RIPEMD160 */
#ifndef XMLSEC_NO_SHA1
- gXmlSecGnuTLSFunctions->transformHmacSha1GetKlass = xmlSecGnuTLSTransformHmacSha1GetKlass;
+ gXmlSecGnuTLSFunctions->transformHmacSha1GetKlass = xmlSecGnuTLSTransformHmacSha1GetKlass;
#endif /* XMLSEC_NO_SHA1 */
#ifndef XMLSEC_NO_SHA256
- gXmlSecGnuTLSFunctions->transformHmacSha256GetKlass = xmlSecGnuTLSTransformHmacSha256GetKlass;
+ gXmlSecGnuTLSFunctions->transformHmacSha256GetKlass = xmlSecGnuTLSTransformHmacSha256GetKlass;
#endif /* XMLSEC_NO_SHA256 */
#ifndef XMLSEC_NO_SHA384
- gXmlSecGnuTLSFunctions->transformHmacSha384GetKlass = xmlSecGnuTLSTransformHmacSha384GetKlass;
+ gXmlSecGnuTLSFunctions->transformHmacSha384GetKlass = xmlSecGnuTLSTransformHmacSha384GetKlass;
#endif /* XMLSEC_NO_SHA384 */
#ifndef XMLSEC_NO_SHA512
- gXmlSecGnuTLSFunctions->transformHmacSha512GetKlass = xmlSecGnuTLSTransformHmacSha512GetKlass;
+ gXmlSecGnuTLSFunctions->transformHmacSha512GetKlass = xmlSecGnuTLSTransformHmacSha512GetKlass;
#endif /* XMLSEC_NO_SHA512 */
#endif /* XMLSEC_NO_HMAC */
/******************************* MD5 ********************************/
#ifndef XMLSEC_NO_MD5
- gXmlSecGnuTLSFunctions->transformMd5GetKlass = xmlSecGnuTLSTransformMd5GetKlass;
+ gXmlSecGnuTLSFunctions->transformMd5GetKlass = xmlSecGnuTLSTransformMd5GetKlass;
#endif /* XMLSEC_NO_MD5 */
/******************************* RIPEMD160 ********************************/
#ifndef XMLSEC_NO_RIPEMD160
- gXmlSecGnuTLSFunctions->transformRipemd160GetKlass = xmlSecGnuTLSTransformRipemd160GetKlass;
+ gXmlSecGnuTLSFunctions->transformRipemd160GetKlass = xmlSecGnuTLSTransformRipemd160GetKlass;
#endif /* XMLSEC_NO_RIPEMD160 */
/******************************* SHA ********************************/
#ifndef XMLSEC_NO_SHA1
- gXmlSecGnuTLSFunctions->transformSha1GetKlass = xmlSecGnuTLSTransformSha1GetKlass;
+ gXmlSecGnuTLSFunctions->transformSha1GetKlass = xmlSecGnuTLSTransformSha1GetKlass;
#endif /* XMLSEC_NO_SHA1 */
#ifndef XMLSEC_NO_SHA256
- gXmlSecGnuTLSFunctions->transformSha256GetKlass = xmlSecGnuTLSTransformSha256GetKlass;
+ gXmlSecGnuTLSFunctions->transformSha256GetKlass = xmlSecGnuTLSTransformSha256GetKlass;
#endif /* XMLSEC_NO_SHA256 */
#ifndef XMLSEC_NO_SHA384
- gXmlSecGnuTLSFunctions->transformSha384GetKlass = xmlSecGnuTLSTransformSha384GetKlass;
+ gXmlSecGnuTLSFunctions->transformSha384GetKlass = xmlSecGnuTLSTransformSha384GetKlass;
#endif /* XMLSEC_NO_SHA384 */
#ifndef XMLSEC_NO_SHA512
- gXmlSecGnuTLSFunctions->transformSha512GetKlass = xmlSecGnuTLSTransformSha512GetKlass;
+ gXmlSecGnuTLSFunctions->transformSha512GetKlass = xmlSecGnuTLSTransformSha512GetKlass;
#endif /* XMLSEC_NO_SHA512 */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]