diff options
Diffstat (limited to 'src/gcrypt/asymkeys.c')
-rw-r--r-- | src/gcrypt/asymkeys.c | 1920 |
1 files changed, 0 insertions, 1920 deletions
diff --git a/src/gcrypt/asymkeys.c b/src/gcrypt/asymkeys.c deleted file mode 100644 index 8f0cec88..00000000 --- a/src/gcrypt/asymkeys.c +++ /dev/null @@ -1,1920 +0,0 @@ -/** - * XMLSec library - * - * This is free software; see Copyright file in the source - * distribution for preciese wording. - * - * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com> - */ -#include "globals.h" - -#include <string.h> - -#include <gcrypt.h> - -#include <xmlsec/xmlsec.h> -#include <xmlsec/xmltree.h> -#include <xmlsec/keys.h> -#include <xmlsec/base64.h> -#include <xmlsec/keyinfo.h> -#include <xmlsec/transforms.h> -#include <xmlsec/errors.h> - -#include <xmlsec/gcrypt/crypto.h> - -/************************************************************************** - * - * Helpers - * - *************************************************************************/ -static gcry_sexp_t xmlSecGCryptAsymSExpDup (gcry_sexp_t sexp); - - -/************************************************************************** - * - * Internal GCrypt asym key CTX - * - *************************************************************************/ -typedef struct _xmlSecGCryptAsymKeyDataCtx xmlSecGCryptAsymKeyDataCtx, - *xmlSecGCryptAsymKeyDataCtxPtr; -struct _xmlSecGCryptAsymKeyDataCtx { - gcry_sexp_t pub_key; - gcry_sexp_t priv_key; -}; - -/****************************************************************************** - * - * Asym key (dsa/rsa) - * - * xmlSecGCryptAsymKeyDataCtx is located after xmlSecTransform - * - *****************************************************************************/ -#define xmlSecGCryptAsymKeyDataSize \ - (sizeof(xmlSecKeyData) + sizeof(xmlSecGCryptAsymKeyDataCtx)) -#define xmlSecGCryptAsymKeyDataGetCtx(data) \ - ((xmlSecGCryptAsymKeyDataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData))) - -static int xmlSecGCryptAsymKeyDataInitialize (xmlSecKeyDataPtr data); -static int xmlSecGCryptAsymKeyDataDuplicate (xmlSecKeyDataPtr dst, - xmlSecKeyDataPtr src); -static void xmlSecGCryptAsymKeyDataFinalize (xmlSecKeyDataPtr data); - -static int xmlSecGCryptAsymKeyDataAdoptKey (xmlSecKeyDataPtr data, - gcry_sexp_t key_pair); -static int xmlSecGCryptAsymKeyDataAdoptKeyPair (xmlSecKeyDataPtr data, - gcry_sexp_t pub_key, - gcry_sexp_t priv_key); -static gcry_sexp_t xmlSecGCryptAsymKeyDataGetPublicKey (xmlSecKeyDataPtr data); -static gcry_sexp_t xmlSecGCryptAsymKeyDataGetPrivateKey (xmlSecKeyDataPtr data); -static int xmlSecGCryptAsymKeyDataGenerate (xmlSecKeyDataPtr data, - const char * alg, - xmlSecSize key_size); -static xmlSecKeyDataType xmlSecGCryptAsymKeyDataGetType (xmlSecKeyDataPtr data); -static xmlSecSize xmlSecGCryptAsymKeyDataGetSize (xmlSecKeyDataPtr data); - - -static int -xmlSecGCryptAsymKeyDataInitialize(xmlSecKeyDataPtr data) { - xmlSecGCryptAsymKeyDataCtxPtr ctx; - - xmlSecAssert2(xmlSecKeyDataIsValid(data), -1); - xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGCryptAsymKeyDataSize), -1); - - ctx = xmlSecGCryptAsymKeyDataGetCtx(data); - xmlSecAssert2(ctx != NULL, -1); - - memset(ctx, 0, sizeof(xmlSecGCryptAsymKeyDataCtx)); - - return(0); -} - -static int -xmlSecGCryptAsymKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { - xmlSecGCryptAsymKeyDataCtxPtr ctxDst; - xmlSecGCryptAsymKeyDataCtxPtr ctxSrc; - - xmlSecAssert2(xmlSecKeyDataIsValid(dst), -1); - xmlSecAssert2(xmlSecKeyDataCheckSize(dst, xmlSecGCryptAsymKeyDataSize), -1); - xmlSecAssert2(xmlSecKeyDataIsValid(src), -1); - xmlSecAssert2(xmlSecKeyDataCheckSize(src, xmlSecGCryptAsymKeyDataSize), -1); - - ctxDst = xmlSecGCryptAsymKeyDataGetCtx(dst); - xmlSecAssert2(ctxDst != NULL, -1); - xmlSecAssert2(ctxDst->pub_key == NULL, -1); - xmlSecAssert2(ctxDst->priv_key == NULL, -1); - - ctxSrc = xmlSecGCryptAsymKeyDataGetCtx(src); - xmlSecAssert2(ctxSrc != NULL, -1); - - if(ctxSrc->pub_key != NULL) { - ctxDst->pub_key = xmlSecGCryptAsymSExpDup(ctxSrc->pub_key); - if(ctxDst->pub_key == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)), - "xmlSecGCryptAsymSExpDup(pub_key)", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - } - - if(ctxSrc->priv_key != NULL) { - ctxDst->priv_key = xmlSecGCryptAsymSExpDup(ctxSrc->priv_key); - if(ctxDst->priv_key == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)), - "xmlSecGCryptAsymSExpDup(priv_key)", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - } - - return(0); -} - -static void -xmlSecGCryptAsymKeyDataFinalize(xmlSecKeyDataPtr data) { - xmlSecGCryptAsymKeyDataCtxPtr ctx; - - xmlSecAssert(xmlSecKeyDataIsValid(data)); - xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecGCryptAsymKeyDataSize)); - - ctx = xmlSecGCryptAsymKeyDataGetCtx(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(xmlSecGCryptAsymKeyDataCtx)); -} - -static int -xmlSecGCryptAsymKeyDataAdoptKey(xmlSecKeyDataPtr data, gcry_sexp_t key_pair) { - xmlSecGCryptAsymKeyDataCtxPtr ctx; - gcry_sexp_t pub_key = NULL; - gcry_sexp_t priv_key = NULL; - int res = -1; - - xmlSecAssert2(xmlSecKeyDataIsValid(data), -1); - xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGCryptAsymKeyDataSize), -1); - xmlSecAssert2(key_pair != NULL, -1); - - ctx = xmlSecGCryptAsymKeyDataGetCtx(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(xmlSecGCryptAsymKeyDataAdoptKeyPair(data, pub_key, priv_key) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGCryptAsymKeyDataAdoptKeyPair", - 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 -xmlSecGCryptAsymKeyDataAdoptKeyPair(xmlSecKeyDataPtr data, gcry_sexp_t pub_key, gcry_sexp_t priv_key) { - xmlSecGCryptAsymKeyDataCtxPtr ctx; - - xmlSecAssert2(xmlSecKeyDataIsValid(data), -1); - xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGCryptAsymKeyDataSize), -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 = xmlSecGCryptAsymKeyDataGetCtx(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 -xmlSecGCryptAsymKeyDataGetPublicKey(xmlSecKeyDataPtr data) { - xmlSecGCryptAsymKeyDataCtxPtr ctx; - - xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL); - xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGCryptAsymKeyDataSize), NULL); - - ctx = xmlSecGCryptAsymKeyDataGetCtx(data); - xmlSecAssert2(ctx != NULL, NULL); - - return(ctx->pub_key); -} - -static gcry_sexp_t -xmlSecGCryptAsymKeyDataGetPrivateKey(xmlSecKeyDataPtr data) { - xmlSecGCryptAsymKeyDataCtxPtr ctx; - - xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL); - xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGCryptAsymKeyDataSize), NULL); - - ctx = xmlSecGCryptAsymKeyDataGetCtx(data); - xmlSecAssert2(ctx != NULL, NULL); - - return(ctx->priv_key); -} - -static int -xmlSecGCryptAsymKeyDataGenerate(xmlSecKeyDataPtr data, const char * alg, xmlSecSize key_size) { - xmlSecGCryptAsymKeyDataCtxPtr 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, xmlSecGCryptAsymKeyDataSize), -1); - xmlSecAssert2(alg != NULL, -1); - xmlSecAssert2(key_size > 0, -1); - - ctx = xmlSecGCryptAsymKeyDataGetCtx(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, - XMLSEC_GCRYPT_REPORT_ERROR(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, - XMLSEC_GCRYPT_REPORT_ERROR(err)); - goto done; - } - - ret = xmlSecGCryptAsymKeyDataAdoptKey(data, key_pair); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGCryptAsymKeyDataAdopt", - 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 -xmlSecGCryptAsymKeyDataGetType(xmlSecKeyDataPtr data) { - xmlSecGCryptAsymKeyDataCtxPtr ctx; - - xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown); - xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGCryptAsymKeyDataSize), xmlSecKeyDataTypeUnknown); - - ctx = xmlSecGCryptAsymKeyDataGetCtx(data); - xmlSecAssert2(ctx != NULL, xmlSecKeyDataTypeUnknown); - - if((ctx->priv_key != NULL) && (ctx->pub_key != NULL)) { - return (xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); - } else if(ctx->pub_key != NULL) { - return (xmlSecKeyDataTypePublic); - } - - return (xmlSecKeyDataTypeUnknown); -} - -static xmlSecSize -xmlSecGCryptAsymKeyDataGetSize(xmlSecKeyDataPtr data) { - xmlSecGCryptAsymKeyDataCtxPtr ctx; - - xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown); - xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecGCryptAsymKeyDataSize), xmlSecKeyDataTypeUnknown); - - ctx = xmlSecGCryptAsymKeyDataGetCtx(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 -xmlSecGCryptAsymSExpDup(gcry_sexp_t pKey) { - gcry_sexp_t res = NULL; - xmlSecByte *buf = NULL; - gcry_error_t err; - 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; - } - - err = gcry_sexp_new(&res, buf, size, 1); - if((err != GPG_ERR_NO_ERROR) || (res == NULL)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "gcry_sexp_new", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_GCRYPT_REPORT_ERROR(err)); - goto done; - } - -done: - if(buf != NULL) { - xmlFree(buf); - } - return (res); -} - -/** - * xmlSecGCryptNodeGetMpiValue: - * @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 -xmlSecGCryptNodeGetMpiValue(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, - XMLSEC_GCRYPT_REPORT_ERROR(err)); - xmlSecBufferFinalize(&buf); - return(NULL); - } - - /* done */ - xmlSecBufferFinalize(&buf); - return(res); -} - -/** - * xmlSecGCryptNodeSetMpiValue: - * @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 -xmlSecGCryptNodeSetMpiValue(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, - XMLSEC_GCRYPT_REPORT_ERROR(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, - XMLSEC_GCRYPT_REPORT_ERROR(err)); - 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); -} - -/** - * xmlSecGCryptNodeSetSExpTokValue: - * @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 -xmlSecGCryptNodeSetSExpTokValue(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 = xmlSecGCryptNodeSetMpiValue(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 xmlSecGCryptKeyDataDsaInitialize (xmlSecKeyDataPtr data); -static int xmlSecGCryptKeyDataDsaDuplicate (xmlSecKeyDataPtr dst, - xmlSecKeyDataPtr src); -static void xmlSecGCryptKeyDataDsaFinalize (xmlSecKeyDataPtr data); -static int xmlSecGCryptKeyDataDsaXmlRead (xmlSecKeyDataId id, - xmlSecKeyPtr key, - xmlNodePtr node, - xmlSecKeyInfoCtxPtr keyInfoCtx); -static int xmlSecGCryptKeyDataDsaXmlWrite (xmlSecKeyDataId id, - xmlSecKeyPtr key, - xmlNodePtr node, - xmlSecKeyInfoCtxPtr keyInfoCtx); -static int xmlSecGCryptKeyDataDsaGenerate (xmlSecKeyDataPtr data, - xmlSecSize sizeBits, - xmlSecKeyDataType type); - -static xmlSecKeyDataType xmlSecGCryptKeyDataDsaGetType (xmlSecKeyDataPtr data); -static xmlSecSize xmlSecGCryptKeyDataDsaGetSize (xmlSecKeyDataPtr data); -static void xmlSecGCryptKeyDataDsaDebugDump (xmlSecKeyDataPtr data, - FILE* output); -static void xmlSecGCryptKeyDataDsaDebugXmlDump (xmlSecKeyDataPtr data, - FILE* output); - -static xmlSecKeyDataKlass xmlSecGCryptKeyDataDsaKlass = { - sizeof(xmlSecKeyDataKlass), - xmlSecGCryptAsymKeyDataSize, - - /* data */ - xmlSecNameDSAKeyValue, - xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, - /* xmlSecKeyDataUsage usage; */ - xmlSecHrefDSAKeyValue, /* const xmlChar* href; */ - xmlSecNodeDSAKeyValue, /* const xmlChar* dataNodeName; */ - xmlSecDSigNs, /* const xmlChar* dataNodeNs; */ - - /* constructors/destructor */ - xmlSecGCryptKeyDataDsaInitialize, /* xmlSecKeyDataInitializeMethod initialize; */ - xmlSecGCryptKeyDataDsaDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */ - xmlSecGCryptKeyDataDsaFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */ - xmlSecGCryptKeyDataDsaGenerate, /* xmlSecKeyDataGenerateMethod generate; */ - - /* get info */ - xmlSecGCryptKeyDataDsaGetType, /* xmlSecKeyDataGetTypeMethod getType; */ - xmlSecGCryptKeyDataDsaGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */ - NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */ - - /* read/write */ - xmlSecGCryptKeyDataDsaXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */ - xmlSecGCryptKeyDataDsaXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ - NULL, /* xmlSecKeyDataBinReadMethod binRead; */ - NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */ - - /* debug */ - xmlSecGCryptKeyDataDsaDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */ - xmlSecGCryptKeyDataDsaDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ - - /* reserved for the future */ - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; - -/** - * xmlSecGCryptKeyDataDsaGetKlass: - * - * The DSA key data klass. - * - * Returns: pointer to DSA key data klass. - */ -xmlSecKeyDataId -xmlSecGCryptKeyDataDsaGetKlass(void) { - return(&xmlSecGCryptKeyDataDsaKlass); -} - -/** - * xmlSecGCryptKeyDataDsaAdoptKey: - * @data: the pointer to DSA key data. - * @dsa_key: the pointer to GCrypt DSA key. - * - * Sets the value of DSA key data. - * - * Returns: 0 on success or a negative value otherwise. - */ -int -xmlSecGCryptKeyDataDsaAdoptKey(xmlSecKeyDataPtr data, gcry_sexp_t dsa_key) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId), -1); - xmlSecAssert2(dsa_key != NULL, -1); - - return xmlSecGCryptAsymKeyDataAdoptKey(data, dsa_key); -} - - -/** - * xmlSecGCryptKeyDataDsaAdoptKeyPair: - * @data: the pointer to DSA key data. - * @pub_key: the pointer to GCrypt DSA pub key. - * @priv_key: the pointer to GCrypt DSA priv key. - * - * Sets the value of DSA key data. - * - * Returns: 0 on success or a negative value otherwise. - */ -int -xmlSecGCryptKeyDataDsaAdoptKeyPair(xmlSecKeyDataPtr data, gcry_sexp_t pub_key, gcry_sexp_t priv_key) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId), -1); - xmlSecAssert2(pub_key != NULL, -1); - - return xmlSecGCryptAsymKeyDataAdoptKeyPair(data, pub_key, priv_key); -} - -/** - * xmlSecGCryptKeyDataDsaGetPublicKey: - * @data: the pointer to DSA key data. - * - * Gets the GCrypt DSA public key from DSA key data. - * - * Returns: pointer to GCrypt public DSA key or NULL if an error occurs. - */ -gcry_sexp_t -xmlSecGCryptKeyDataDsaGetPublicKey(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId), NULL); - return xmlSecGCryptAsymKeyDataGetPublicKey(data); -} - -/** - * xmlSecGCryptKeyDataDsaGetPrivateKey: - * @data: the pointer to DSA key data. - * - * Gets the GCrypt DSA private key from DSA key data. - * - * Returns: pointer to GCrypt private DSA key or NULL if an error occurs. - */ -gcry_sexp_t -xmlSecGCryptKeyDataDsaGetPrivateKey(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId), NULL); - return xmlSecGCryptAsymKeyDataGetPrivateKey(data); -} - -static int -xmlSecGCryptKeyDataDsaInitialize(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId), -1); - - return(xmlSecGCryptAsymKeyDataInitialize(data)); -} - -static int -xmlSecGCryptKeyDataDsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { - xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecGCryptKeyDataDsaId), -1); - xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecGCryptKeyDataDsaId), -1); - - return(xmlSecGCryptAsymKeyDataDuplicate(dst, src)); -} - -static void -xmlSecGCryptKeyDataDsaFinalize(xmlSecKeyDataPtr data) { - xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId)); - - xmlSecGCryptAsymKeyDataFinalize(data); -} - -static int -xmlSecGCryptKeyDataDsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId), -1); - xmlSecAssert2(sizeBits > 0, -1); - - return xmlSecGCryptAsymKeyDataGenerate(data, "dsa", sizeBits); -} - -static xmlSecKeyDataType -xmlSecGCryptKeyDataDsaGetType(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId), xmlSecKeyDataTypeUnknown); - - return xmlSecGCryptAsymKeyDataGetType(data); -} - -static xmlSecSize -xmlSecGCryptKeyDataDsaGetSize(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId), 0); - - return xmlSecGCryptAsymKeyDataGetSize(data); -} - -static void -xmlSecGCryptKeyDataDsaDebugDump(xmlSecKeyDataPtr data, FILE* output) { - xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId)); - xmlSecAssert(output != NULL); - - fprintf(output, "=== dsa key: size = %d\n", - xmlSecGCryptKeyDataDsaGetSize(data)); -} - -static void -xmlSecGCryptKeyDataDsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) { - xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDsaId)); - xmlSecAssert(output != NULL); - - fprintf(output, "<DSAKeyValue size=\"%d\" />\n", - xmlSecGCryptKeyDataDsaGetSize(data)); -} - -static int -xmlSecGCryptKeyDataDsaXmlRead(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 == xmlSecGCryptKeyDataDsaId, -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 = xmlSecGCryptNodeGetMpiValue(cur); - if(p == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeGetMpiValue", - 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 = xmlSecGCryptNodeGetMpiValue(cur); - if(q == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeGetMpiValue", - 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 = xmlSecGCryptNodeGetMpiValue(cur); - if(g == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeGetMpiValue", - 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 = xmlSecGCryptNodeGetMpiValue(cur); - if(x == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeGetMpiValue", - 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 = xmlSecGCryptNodeGetMpiValue(cur); - if(y == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeGetMpiValue", - 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_GCRYPT_REPORT_ERROR(err)); - 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_GCRYPT_REPORT_ERROR(err)); - 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 = xmlSecGCryptKeyDataDsaAdoptKeyPair(data, pub_key, priv_key); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), - "xmlSecGCryptKeyDataDsaAdoptKeyPair", - 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 -xmlSecGCryptKeyDataDsaXmlWrite(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 == xmlSecGCryptKeyDataDsaId, -1); - xmlSecAssert2(key != NULL, -1); - xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecGCryptKeyDataDsaId), -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 = xmlSecGCryptKeyDataDsaGetPrivateKey(xmlSecKeyGetValue(key)); - if(pub_priv_key == NULL) { - pub_priv_key = xmlSecGCryptKeyDataDsaGetPublicKey(xmlSecKeyGetValue(key)); - if(pub_priv_key == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptKeyDataDsaGetPublicKey()", - 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 = xmlSecGCryptNodeSetSExpTokValue(cur, dsa, "p", 1); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeSetSExpTokValue", - 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 = xmlSecGCryptNodeSetSExpTokValue(cur, dsa, "q", 1); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeSetSExpTokValue", - 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 = xmlSecGCryptNodeSetSExpTokValue(cur, dsa, "g", 1); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeSetSExpTokValue", - 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 = xmlSecGCryptNodeSetSExpTokValue(cur, dsa, "x", 1); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeSetSExpTokValue", - 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 = xmlSecGCryptNodeSetSExpTokValue(cur, dsa, "y", 1); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeSetSExpTokValue", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeDSAY)); - goto done; - } - - /* success */ - res = 0; - -done: - if(dsa != NULL) { - gcry_sexp_release(dsa); - } - - return(res); -} - -#endif /* XMLSEC_NO_DSA */ - - -#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 xmlSecGCryptKeyDataRsaInitialize (xmlSecKeyDataPtr data); -static int xmlSecGCryptKeyDataRsaDuplicate (xmlSecKeyDataPtr dst, - xmlSecKeyDataPtr src); -static void xmlSecGCryptKeyDataRsaFinalize (xmlSecKeyDataPtr data); -static int xmlSecGCryptKeyDataRsaXmlRead (xmlSecKeyDataId id, - xmlSecKeyPtr key, - xmlNodePtr node, - xmlSecKeyInfoCtxPtr keyInfoCtx); -static int xmlSecGCryptKeyDataRsaXmlWrite (xmlSecKeyDataId id, - xmlSecKeyPtr key, - xmlNodePtr node, - xmlSecKeyInfoCtxPtr keyInfoCtx); -static int xmlSecGCryptKeyDataRsaGenerate (xmlSecKeyDataPtr data, - xmlSecSize sizeBits, - xmlSecKeyDataType type); - -static xmlSecKeyDataType xmlSecGCryptKeyDataRsaGetType (xmlSecKeyDataPtr data); -static xmlSecSize xmlSecGCryptKeyDataRsaGetSize (xmlSecKeyDataPtr data); -static void xmlSecGCryptKeyDataRsaDebugDump (xmlSecKeyDataPtr data, - FILE* output); -static void xmlSecGCryptKeyDataRsaDebugXmlDump (xmlSecKeyDataPtr data, - FILE* output); -static xmlSecKeyDataKlass xmlSecGCryptKeyDataRsaKlass = { - sizeof(xmlSecKeyDataKlass), - xmlSecGCryptAsymKeyDataSize, - - /* data */ - xmlSecNameRSAKeyValue, - xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, - /* xmlSecKeyDataUsage usage; */ - xmlSecHrefRSAKeyValue, /* const xmlChar* href; */ - xmlSecNodeRSAKeyValue, /* const xmlChar* dataNodeName; */ - xmlSecDSigNs, /* const xmlChar* dataNodeNs; */ - - /* constructors/destructor */ - xmlSecGCryptKeyDataRsaInitialize, /* xmlSecKeyDataInitializeMethod initialize; */ - xmlSecGCryptKeyDataRsaDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */ - xmlSecGCryptKeyDataRsaFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */ - xmlSecGCryptKeyDataRsaGenerate, /* xmlSecKeyDataGenerateMethod generate; */ - - /* get info */ - xmlSecGCryptKeyDataRsaGetType, /* xmlSecKeyDataGetTypeMethod getType; */ - xmlSecGCryptKeyDataRsaGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */ - NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */ - - /* read/write */ - xmlSecGCryptKeyDataRsaXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */ - xmlSecGCryptKeyDataRsaXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ - NULL, /* xmlSecKeyDataBinReadMethod binRead; */ - NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */ - - /* debug */ - xmlSecGCryptKeyDataRsaDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */ - xmlSecGCryptKeyDataRsaDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ - - /* reserved for the future */ - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; - -/** - * xmlSecGCryptKeyDataRsaGetKlass: - * - * The GCrypt RSA key data klass. - * - * Returns: pointer to GCrypt RSA key data klass. - */ -xmlSecKeyDataId -xmlSecGCryptKeyDataRsaGetKlass(void) { - return(&xmlSecGCryptKeyDataRsaKlass); -} - -/** - * xmlSecGCryptKeyDataRsaAdoptKey: - * @data: the pointer to RSA key data. - * @rsa_key: the pointer to GCrypt RSA key. - * - * Sets the value of RSA key data. - * - * Returns: 0 on success or a negative value otherwise. - */ -int -xmlSecGCryptKeyDataRsaAdoptKey(xmlSecKeyDataPtr data, gcry_sexp_t rsa_key) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId), -1); - xmlSecAssert2(rsa_key != NULL, -1); - - return xmlSecGCryptAsymKeyDataAdoptKey(data, rsa_key); -} - - -/** - * xmlSecGCryptKeyDataRsaAdoptKeyPair: - * @data: the pointer to RSA key data. - * @pub_key: the pointer to GCrypt RSA pub key. - * @priv_key: the pointer to GCrypt RSA priv key. - * - * Sets the value of RSA key data. - * - * Returns: 0 on success or a negative value otherwise. - */ -int -xmlSecGCryptKeyDataRsaAdoptKeyPair(xmlSecKeyDataPtr data, gcry_sexp_t pub_key, gcry_sexp_t priv_key) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId), -1); - xmlSecAssert2(pub_key != NULL, -1); - - return xmlSecGCryptAsymKeyDataAdoptKeyPair(data, pub_key, priv_key); -} - -/** - * xmlSecGCryptKeyDataRsaGetPublicKey: - * @data: the pointer to RSA key data. - * - * Gets the GCrypt RSA public key from RSA key data. - * - * Returns: pointer to GCrypt public RSA key or NULL if an error occurs. - */ -gcry_sexp_t -xmlSecGCryptKeyDataRsaGetPublicKey(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId), NULL); - return xmlSecGCryptAsymKeyDataGetPublicKey(data); -} - -/** - * xmlSecGCryptKeyDataRsaGetPrivateKey: - * @data: the pointer to RSA key data. - * - * Gets the GCrypt RSA private key from RSA key data. - * - * Returns: pointer to GCrypt private RSA key or NULL if an error occurs. - */ -gcry_sexp_t -xmlSecGCryptKeyDataRsaGetPrivateKey(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId), NULL); - return xmlSecGCryptAsymKeyDataGetPrivateKey(data); -} - -static int -xmlSecGCryptKeyDataRsaInitialize(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId), -1); - - return(xmlSecGCryptAsymKeyDataInitialize(data)); -} - -static int -xmlSecGCryptKeyDataRsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { - xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecGCryptKeyDataRsaId), -1); - xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecGCryptKeyDataRsaId), -1); - - return(xmlSecGCryptAsymKeyDataDuplicate(dst, src)); -} - -static void -xmlSecGCryptKeyDataRsaFinalize(xmlSecKeyDataPtr data) { - xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId)); - - xmlSecGCryptAsymKeyDataFinalize(data); -} - -static int -xmlSecGCryptKeyDataRsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId), -1); - xmlSecAssert2(sizeBits > 0, -1); - - return xmlSecGCryptAsymKeyDataGenerate(data, "rsa", sizeBits); -} - -static xmlSecKeyDataType -xmlSecGCryptKeyDataRsaGetType(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId), xmlSecKeyDataTypeUnknown); - - return xmlSecGCryptAsymKeyDataGetType(data); -} - -static xmlSecSize -xmlSecGCryptKeyDataRsaGetSize(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId), 0); - - return xmlSecGCryptAsymKeyDataGetSize(data); -} - -static void -xmlSecGCryptKeyDataRsaDebugDump(xmlSecKeyDataPtr data, FILE* output) { - xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId)); - xmlSecAssert(output != NULL); - - fprintf(output, "=== rsa key: size = %d\n", - xmlSecGCryptKeyDataRsaGetSize(data)); -} - -static void -xmlSecGCryptKeyDataRsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) { - xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataRsaId)); - xmlSecAssert(output != NULL); - - fprintf(output, "<RSAKeyValue size=\"%d\" />\n", - xmlSecGCryptKeyDataRsaGetSize(data)); -} - -static int -xmlSecGCryptKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, - xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { - xmlNodePtr cur; - 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 == xmlSecGCryptKeyDataRsaId, -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"); - goto done; - } - - cur = xmlSecGetNextElementNode(node->children); - - /* first is Modulus node. It is REQUIRED */ - 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)); - goto done; - } - n = xmlSecGCryptNodeGetMpiValue(cur); - if(n == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeGetMpiValue", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); - goto done; - } - cur = xmlSecGetNextElementNode(cur->next); - - /* next is Exponent node. It is REQUIRED */ - 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)); - goto done; - } - e = xmlSecGCryptNodeGetMpiValue(cur); - if(e == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeGetMpiValue", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); - goto done; - } - cur = xmlSecGetNextElementNode(cur->next); - - if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeRSAPrivateExponent, xmlSecNs))) { - /* next is PrivateExponent node. It is REQUIRED for private key */ - d = xmlSecGCryptNodeGetMpiValue(cur); - if(d == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeGetMpiValue", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent)); - goto done; - } - 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"); - 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_GCRYPT_REPORT_ERROR(err)); - 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_GCRYPT_REPORT_ERROR(err)); - 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 = xmlSecGCryptKeyDataRsaAdoptKeyPair(data, pub_key, priv_key); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), - "xmlSecGCryptKeyDataRsaAdoptKeyPair", - 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(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(res); - -} - -static int -xmlSecGCryptKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, - xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { - xmlNodePtr cur; - gcry_sexp_t pub_priv_key; - gcry_sexp_t rsa = NULL; - int private = 0; - int res = -1; - int ret; - - xmlSecAssert2(id == xmlSecGCryptKeyDataRsaId, -1); - xmlSecAssert2(key != NULL, -1); - xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecGCryptKeyDataRsaId), -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 = xmlSecGCryptKeyDataRsaGetPrivateKey(xmlSecKeyGetValue(key)); - if(pub_priv_key == NULL) { - pub_priv_key = xmlSecGCryptKeyDataRsaGetPublicKey(xmlSecKeyGetValue(key)); - if(pub_priv_key == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptKeyDataRsaGetPublicKey()", - 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) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecAddChild", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); - goto done; - } - ret = xmlSecGCryptNodeSetSExpTokValue(cur, rsa, "n", 1); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeSetSExpTokValue", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); - goto done; - } - - /* 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)); - goto done; - } - ret = xmlSecGCryptNodeSetSExpTokValue(cur, rsa, "e", 1); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeSetSExpTokValue", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); - goto done; - } - - /* next is PrivateExponent node: write it ONLY for private keys and ONLY if it is requested */ - if(((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) && (private != 0)) { - 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)); - goto done; - } - ret = xmlSecGCryptNodeSetSExpTokValue(cur, rsa, "d", 1); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), - "xmlSecGCryptNodeSetSExpTokValue", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent)); - goto done; - } - } - - /* success */ - res = 0; - -done: - if(rsa != NULL) { - gcry_sexp_release(rsa); - } - - return(res); -} - -#endif /* XMLSEC_NO_RSA */ |