diff options
Diffstat (limited to 'src/gnutls/app.c')
-rw-r--r-- | src/gnutls/app.c | 1047 |
1 files changed, 773 insertions, 274 deletions
diff --git a/src/gnutls/app.c b/src/gnutls/app.c index 54da1999..856257f3 100644 --- a/src/gnutls/app.c +++ b/src/gnutls/app.c @@ -1,17 +1,15 @@ -/** +/** * XMLSec library * * This is free software; see Copyright file in the source * distribution for preciese wording. - * + * * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> */ #include "globals.h" #include <string.h> -#include <gnutls/gnutls.h> - #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> @@ -19,38 +17,56 @@ #include <xmlsec/gnutls/app.h> #include <xmlsec/gnutls/crypto.h> +#include <xmlsec/gnutls/x509.h> + +#include "x509utils.h" + +/************************************************************************** + * + * We use xmlsec-gcrypt for all the basic crypto ops + * + *****************************************************************************/ +#include <xmlsec/gcrypt/crypto.h> +#include <xmlsec/gcrypt/app.h> + +static xmlSecKeyPtr xmlSecGnuTLSAppKeyFromCertLoad (const char *filename, + xmlSecKeyDataFormat format); +static xmlSecKeyPtr xmlSecGnuTLSAppKeyFromCertLoadMemory (const xmlSecByte* data, + xmlSecSize dataSize, + xmlSecKeyDataFormat format); /** * xmlSecGnuTLSAppInit: - * @config: the path to GnuTLS configuration (unused). - * + * @config: the path to GnuTLS configuration (unused). + * * General crypto engine initialization. This function is used - * by XMLSec command line utility and called before + * by XMLSec command line utility and called before * @xmlSecInit function. * * Returns: 0 on success or a negative value otherwise. */ int -xmlSecGnuTLSAppInit(const char* config ATTRIBUTE_UNUSED) { - int ret; - - ret = gnutls_global_init(); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "gnutls_global_init", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); +xmlSecGnuTLSAppInit(const char* config) { + int err; + + err = gnutls_global_init(); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_global_init", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(-1); } - return(0); + + return(xmlSecGCryptAppInit(config)); } /** * xmlSecGnuTLSAppShutdown: - * + * * General crypto engine shutdown. This function is used - * by XMLSec command line utility and called after + * by XMLSec command line utility and called after * @xmlSecShutdown function. * * Returns: 0 on success or a negative value otherwise. @@ -58,304 +74,787 @@ xmlSecGnuTLSAppInit(const char* config ATTRIBUTE_UNUSED) { int xmlSecGnuTLSAppShutdown(void) { gnutls_global_deinit(); - return(0); + + return(xmlSecGCryptAppShutdown()); } /** * xmlSecGnuTLSAppKeyLoad: - * @filename: the key filename. - * @format: the key file format. - * @pwd: the key file password. - * @pwdCallback: the key password callback. - * @pwdCallbackCtx: the user context for password callback. + * @filename: the key filename. + * @format: the key file format. + * @pwd: the key file password. + * @pwdCallback: the key password callback. + * @pwdCallbackCtx: the user context for password callback. * - * Reads key from the a file (not implemented yet). + * Reads key from the a file. * * Returns: pointer to the key or NULL if an error occurs. */ xmlSecKeyPtr xmlSecGnuTLSAppKeyLoad(const char *filename, xmlSecKeyDataFormat format, - const char *pwd, - void* pwdCallback, - void* pwdCallbackCtx) { + const char *pwd, + void* pwdCallback, + void* pwdCallbackCtx) { + xmlSecKeyPtr key; + xmlSecAssert2(filename != NULL, NULL); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL); - - if (format == xmlSecKeyDataFormatPkcs12) { - return (xmlSecGnuTLSAppPkcs12Load(filename, pwd, pwdCallback, - pwdCallbackCtx)); + switch(format) { +#ifndef XMLSEC_NO_X509 + case xmlSecKeyDataFormatPkcs12: + key = xmlSecGnuTLSAppPkcs12Load(filename, pwd, pwdCallback, pwdCallbackCtx); + break; + case xmlSecKeyDataFormatCertPem: + case xmlSecKeyDataFormatCertDer: + key = xmlSecGnuTLSAppKeyFromCertLoad(filename, format); + break; +#endif /* XMLSEC_NO_X509 */ + default: + key = xmlSecGCryptAppKeyLoad(filename, format, pwd, pwdCallback, pwdCallbackCtx); + break; } - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeyLoad", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); + return(key); } /** * xmlSecGnuTLSAppKeyLoadMemory: - * @data: the binary key data. - * @dataSize: the size of binary key. - * @format: the key file format. - * @pwd: the key file password. - * @pwdCallback: the key password callback. - * @pwdCallbackCtx: the user context for password callback. + * @data: the binary key data. + * @dataSize: the size of binary key. + * @format: the key file format. + * @pwd: the key file password. + * @pwdCallback: the key password callback. + * @pwdCallbackCtx: the user context for password callback. * - * Reads key from the memory buffer (not implemented yet). + * Reads key from the memory buffer. * * Returns: pointer to the key or NULL if an error occurs. */ xmlSecKeyPtr -xmlSecGnuTLSAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize, - xmlSecKeyDataFormat format, const char *pwd, - void* pwdCallback, void* pwdCallbackCtx) { +xmlSecGnuTLSAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize, + xmlSecKeyDataFormat format, const char *pwd, + void* pwdCallback, void* pwdCallbackCtx) { + xmlSecKeyPtr key; + xmlSecAssert2(data != NULL, NULL); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL); - if (format == xmlSecKeyDataFormatPkcs12) { - return (xmlSecGnuTLSAppPkcs12LoadMemory(data, dataSize, pwd, - pwdCallback, pwdCallbackCtx)); + switch(format) { +#ifndef XMLSEC_NO_X509 + case xmlSecKeyDataFormatPkcs12: + key = xmlSecGnuTLSAppPkcs12LoadMemory(data, dataSize, pwd, pwdCallback, pwdCallbackCtx); + break; + case xmlSecKeyDataFormatCertPem: + case xmlSecKeyDataFormatCertDer: + key = xmlSecGnuTLSAppKeyFromCertLoadMemory(data, dataSize, format); + break; +#endif /* XMLSEC_NO_X509 */ + default: + key = xmlSecGCryptAppKeyLoadMemory(data, dataSize, format, pwd, pwdCallback, pwdCallbackCtx); + break; } - - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeyLoadMemory", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); + return(key); } #ifndef XMLSEC_NO_X509 /** * xmlSecGnuTLSAppKeyCertLoad: - * @key: the pointer to key. - * @filename: the certificate filename. - * @format: the certificate file format. + * @key: the pointer to key. + * @filename: the certificate filename. + * @format: the certificate file format. + * + * Reads the certificate from $@filename and adds it to key. * - * Reads the certificate from $@filename and adds it to key - * (not implemented yet). - * * Returns: 0 on success or a negative value otherwise. */ -int -xmlSecGnuTLSAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, - xmlSecKeyDataFormat format) { +int +xmlSecGnuTLSAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, + xmlSecKeyDataFormat format) { + xmlSecBuffer buffer; + int ret; + xmlSecAssert2(key != NULL, -1); xmlSecAssert2(filename != NULL, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); - - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeyCertLoad", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + + ret = xmlSecBufferInitialize(&buffer, 4*1024); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecBufferReadFile(&buffer, filename); + if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferReadFile", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(-1); + } + + ret = xmlSecGnuTLSAppKeyCertLoadMemory(key, + xmlSecBufferGetData(&buffer), + xmlSecBufferGetSize(&buffer), + format); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSAppKeyCertLoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(-1); + } + + /* cleanup */ + xmlSecBufferFinalize(&buffer); + return(0); } /** * xmlSecGnuTLSAppKeyCertLoadMemory: - * @key: the pointer to key. - * @data: the certificate binary data. - * @dataSize: the certificate binary data size. - * @format: the certificate file format. + * @key: the pointer to key. + * @data: the certificate binary data. + * @dataSize: the certificate binary data size. + * @format: the certificate file format. + * + * Reads the certificate from memory buffer and adds it to key. * - * Reads the certificate from memory buffer and adds it to key (not implemented yet). - * * Returns: 0 on success or a negative value otherwise. */ -int -xmlSecGnuTLSAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSecSize dataSize, - xmlSecKeyDataFormat format) { +int +xmlSecGnuTLSAppKeyCertLoadMemory(xmlSecKeyPtr key, + const xmlSecByte* data, + xmlSecSize dataSize, + xmlSecKeyDataFormat format) { + gnutls_x509_crt_t cert; + xmlSecKeyDataPtr keyData; + int ret; + xmlSecAssert2(key != NULL, -1); xmlSecAssert2(data != NULL, -1); + xmlSecAssert2(dataSize > 0, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeyCertLoadMemory", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + keyData = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id); + if(keyData == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyEnsureData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + cert = xmlSecGnuTLSX509CertRead(data, dataSize, format); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCert(keyData, cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataX509AdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert); + return(-1); + } + + return(0); } /** * xmlSecGnuTLSAppPkcs12Load: - * @filename: the PKCS12 key filename. - * @pwd: the PKCS12 file password. - * @pwdCallback: the password callback. - * @pwdCallbackCtx: the user context for password callback. + * @filename: the PKCS12 key filename. + * @pwd: the PKCS12 file password. + * @pwdCallback: the password callback. + * @pwdCallbackCtx: the user context for password callback. * - * Reads key and all associated certificates from the PKCS12 file - * (not implemented yet). + * Reads key and all associated certificates from the PKCS12 file. * For uniformity, call xmlSecGnuTLSAppKeyLoad instead of this function. Pass * in format=xmlSecKeyDataFormatPkcs12. * * Returns: pointer to the key or NULL if an error occurs. */ -xmlSecKeyPtr -xmlSecGnuTLSAppPkcs12Load(const char *filename, - const char *pwd ATTRIBUTE_UNUSED, - void* pwdCallback ATTRIBUTE_UNUSED, - void* pwdCallbackCtx ATTRIBUTE_UNUSED) { +xmlSecKeyPtr +xmlSecGnuTLSAppPkcs12Load(const char *filename, + const char *pwd, + void* pwdCallback, + void* pwdCallbackCtx) { + xmlSecKeyPtr key; + xmlSecBuffer buffer; + int ret; + xmlSecAssert2(filename != NULL, NULL); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppPkcs12Load", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); + ret = xmlSecBufferInitialize(&buffer, 4*1024); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + ret = xmlSecBufferReadFile(&buffer, filename); + if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferReadFile", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(NULL); + } + + key = xmlSecGnuTLSAppPkcs12LoadMemory(xmlSecBufferGetData(&buffer), + xmlSecBufferGetSize(&buffer), + pwd, pwdCallback, pwdCallbackCtx); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSAppPkcs12LoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(NULL); + } + + /* cleanup */ + xmlSecBufferFinalize(&buffer); + return(key); } /** * xmlSecGnuTLSAppPkcs12LoadMemory: - * @data: the PKCS12 binary data. - * @dataSize: the PKCS12 binary data size. - * @pwd: the PKCS12 file password. - * @pwdCallback: the password callback. - * @pwdCallbackCtx: the user context for password callback. + * @data: the PKCS12 binary data. + * @dataSize: the PKCS12 binary data size. + * @pwd: the PKCS12 file password. + * @pwdCallback: the password callback. + * @pwdCallbackCtx: the user context for password callback. * * Reads key and all associated certificates from the PKCS12 data in memory buffer. * For uniformity, call xmlSecGnuTLSAppKeyLoadMemory instead of this function. Pass - * in format=xmlSecKeyDataFormatPkcs12 (not implemented yet). + * in format=xmlSecKeyDataFormatPkcs12. * * Returns: pointer to the key or NULL if an error occurs. */ -xmlSecKeyPtr -xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize, - const char *pwd, void* pwdCallback, - void* pwdCallbackCtx) { +xmlSecKeyPtr +xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize, + const char *pwd, + void* pwdCallback ATTRIBUTE_UNUSED, + void* pwdCallbackCtx ATTRIBUTE_UNUSED) +{ + xmlSecKeyPtr key = NULL; + xmlSecKeyPtr res = NULL; + xmlSecPtrList certsList; + xmlSecKeyDataPtr keyData = NULL; + xmlSecKeyDataPtr x509Data = NULL; + gnutls_x509_privkey_t priv_key = NULL; + gnutls_x509_crt_t key_cert = NULL; + xmlSecSize certsSize; + int ret; + xmlSecAssert2(data != NULL, NULL); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppPkcs12LoadMemory", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); + xmlSecAssert2(dataSize > 0, NULL); + + /* prepare */ + ret = xmlSecPtrListInitialize(&(certsList), xmlSecGnuTLSX509CrtListId); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecPtrListInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "certsList"); + return(NULL); + } + + /* load pkcs12 */ + ret = xmlSecGnuTLSPkcs12LoadMemory(data, dataSize, pwd, &priv_key, &key_cert, &certsList); + if((ret < 0) || (priv_key == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSPkcs12LoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* create key */ + key = xmlSecKeyCreate(); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* create key value data */ + keyData = xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(priv_key); + if(keyData == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + priv_key = NULL; /* owned by keyData now */ + + ret = xmlSecKeySetValue(key, keyData); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeySetValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "data=%s", + xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); + goto done; + } + keyData = NULL; /* owned by key now */ + + + /* create x509 certs data */ + certsSize = xmlSecPtrListGetSize(&certsList); + if((certsSize > 0) || (key_cert != NULL)) { + xmlSecSize ii; + + x509Data = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataX509Id); + if(x509Data == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataX509Id)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* set key's cert */ + if(key_cert != NULL) { + ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, key_cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataX509AdoptKeyCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + key_cert = NULL; /* owned by x509Data now */ + } + + /* copy all other certs */ + for(ii = 0; ii < certsSize; ++ii) { + gnutls_x509_crt_t cert = xmlSecPtrListRemoveAndReturn(&certsList, ii); + if(cert == NULL) { + continue; + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCert(x509Data, cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataX509AdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert); + goto done; + } + } + + /* set in the key */ + ret = xmlSecKeyAdoptData(key, x509Data); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyAdoptData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "data=%s", + xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); + goto done; + } + x509Data = NULL; /* owned by key now */ + } + + /* success!!! */ + res = key; + key = NULL; + +done: + if(key_cert != NULL) { + gnutls_x509_crt_deinit(key_cert); + } + if(priv_key != NULL) { + gnutls_x509_privkey_deinit(priv_key); + } + if(keyData != NULL) { + xmlSecKeyDataDestroy(keyData); + } + if(x509Data != NULL) { + xmlSecKeyDataDestroy(x509Data); + } + if(key != NULL) { + xmlSecKeyDestroy(key); + } + xmlSecPtrListFinalize(&certsList); + return(res); +} + +static xmlSecKeyPtr +xmlSecGnuTLSAppKeyFromCertLoad(const char *filename, + xmlSecKeyDataFormat format) +{ + xmlSecKeyPtr key; + xmlSecBuffer buffer; + int ret; + + xmlSecAssert2(filename != NULL, NULL); + + ret = xmlSecBufferInitialize(&buffer, 4*1024); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + ret = xmlSecBufferReadFile(&buffer, filename); + if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferReadFile", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(NULL); + } + + key = xmlSecGnuTLSAppKeyFromCertLoadMemory( + xmlSecBufferGetData(&buffer), + xmlSecBufferGetSize(&buffer), + format); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSAppKeyFromCertLoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(NULL); + } + + /* cleanup */ + xmlSecBufferFinalize(&buffer); + return(key); +} + +static xmlSecKeyPtr +xmlSecGnuTLSAppKeyFromCertLoadMemory(const xmlSecByte* data, + xmlSecSize dataSize, + xmlSecKeyDataFormat format) +{ + xmlSecKeyPtr key = NULL; + xmlSecKeyDataPtr keyData = NULL; + xmlSecKeyDataPtr x509Data = NULL; + gnutls_x509_crt_t cert = NULL; + xmlSecKeyPtr res = NULL; + int ret; + + xmlSecAssert2(data != NULL, NULL); + xmlSecAssert2(dataSize > 0, NULL); + xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL); + + /* read cert */ + cert = xmlSecGnuTLSX509CertRead(data, dataSize, format); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* create key */ + key = xmlSecKeyCreate(); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* create key value data */ + keyData = xmlSecGnuTLSX509CertGetKey(cert); + if(keyData == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + ret = xmlSecKeySetValue(key, keyData); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeySetValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "data=%s", + xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); + goto done; + } + keyData = NULL; /* owned by key now */ + + /* create x509 data */ + x509Data = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id); + if(x509Data == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyEnsureData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataX509AdoptKeyCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + cert = NULL; /* owned by x509Data now */ + + /* success */ + res = key; + key = NULL; + +done: + if(cert != NULL) { + gnutls_x509_crt_deinit(cert); + } + if(keyData != NULL) { + xmlSecKeyDataDestroy(keyData); + } + if(key != NULL) { + xmlSecKeyDestroy(key); + } + return(res); } /** * xmlSecGnuTLSAppKeysMngrCertLoad: - * @mngr: the keys manager. - * @filename: the certificate file. - * @format: the certificate file format. - * @type: the flag that indicates is the certificate in @filename - * trusted or not. - * + * @mngr: the keys manager. + * @filename: the certificate file. + * @format: the certificate file format. + * @type: the flag that indicates is the certificate in @filename + * trusted or not. + * * Reads cert from @filename and adds to the list of trusted or known - * untrusted certs in @store (not implemented yet). + * untrusted certs in @store. * * Returns: 0 on success or a negative value otherwise. */ int -xmlSecGnuTLSAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename, - xmlSecKeyDataFormat format, - xmlSecKeyDataType type ATTRIBUTE_UNUSED) { +xmlSecGnuTLSAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, + const char *filename, + xmlSecKeyDataFormat format, + xmlSecKeyDataType type) { + xmlSecBuffer buffer; + int ret; + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeysMngrCertLoad", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + ret = xmlSecBufferInitialize(&buffer, 4*1024); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecBufferReadFile(&buffer, filename); + if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferReadFile", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(-1); + } + + ret = xmlSecGnuTLSAppKeysMngrCertLoadMemory(mngr, + xmlSecBufferGetData(&buffer), + xmlSecBufferGetSize(&buffer), + format, + type); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSAppKeysMngrCertLoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(-1); + } + + /* cleanup */ + xmlSecBufferFinalize(&buffer); + return(0); } /** * xmlSecGnuTLSAppKeysMngrCertLoadMemory: - * @mngr: the keys manager. - * @data: the certificate binary data. - * @dataSize: the certificate binary data size. - * @format: the certificate file format. - * @type: the flag that indicates is the certificate trusted or not. - * + * @mngr: the keys manager. + * @data: the certificate binary data. + * @dataSize: the certificate binary data size. + * @format: the certificate file format. + * @type: the flag that indicates is the certificate trusted or not. + * * Reads cert from binary buffer @data and adds to the list of trusted or known - * untrusted certs in @store (not implemented yet). + * untrusted certs in @store. * * Returns: 0 on success or a negative value otherwise. */ int -xmlSecGnuTLSAppKeysMngrCertLoadMemory(xmlSecKeysMngrPtr mngr, const xmlSecByte* data, - xmlSecSize dataSize, xmlSecKeyDataFormat format, - xmlSecKeyDataType type) { +xmlSecGnuTLSAppKeysMngrCertLoadMemory(xmlSecKeysMngrPtr mngr, + const xmlSecByte* data, + xmlSecSize dataSize, + xmlSecKeyDataFormat format, + xmlSecKeyDataType type) { + xmlSecKeyDataStorePtr x509Store; + gnutls_x509_crt_t cert; + int ret; + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(data != NULL, -1); + xmlSecAssert2(dataSize > 0, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeysMngrCertLoadMemory", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecGnuTLSX509StoreId); + if(x509Store == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrGetDataStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecGnuTLSX509StoreId"); + return(-1); + } + + cert = xmlSecGnuTLSX509CertRead(data, dataSize, format); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecGnuTLSX509StoreAdoptCert(x509Store, cert, type); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509StoreAdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert); + return(-1); + } + + return(0); } #endif /* XMLSEC_NO_X509 */ /** * xmlSecGnuTLSAppDefaultKeysMngrInit: - * @mngr: the pointer to keys manager. + * @mngr: the pointer to keys manager. * * Initializes @mngr with simple keys store #xmlSecSimpleKeysStoreId * and a default GnuTLS crypto key data stores. * * Returns: 0 on success or a negative value otherwise. - */ + */ int xmlSecGnuTLSAppDefaultKeysMngrInit(xmlSecKeysMngrPtr mngr) { int ret; - + xmlSecAssert2(mngr != NULL, -1); - /* create simple keys store if needed */ + /* create simple keys store if needed */ if(xmlSecKeysMngrGetKeysStore(mngr) == NULL) { - xmlSecKeyStorePtr keysStore; - - keysStore = xmlSecKeyStoreCreate(xmlSecSimpleKeysStoreId); - if(keysStore == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeyStoreCreate", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "xmlSecSimpleKeysStoreId"); - return(-1); - } - - ret = xmlSecKeysMngrAdoptKeysStore(mngr, keysStore); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeysMngrAdoptKeysStore", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlSecKeyStoreDestroy(keysStore); - return(-1); - } - } - - ret = xmlSecGnuTLSKeysMngrInit(mngr); + xmlSecKeyStorePtr keysStore; + + keysStore = xmlSecKeyStoreCreate(xmlSecSimpleKeysStoreId); + if(keysStore == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyStoreCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecSimpleKeysStoreId"); + return(-1); + } + + ret = xmlSecKeysMngrAdoptKeysStore(mngr, keysStore); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrAdoptKeysStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyStoreDestroy(keysStore); + return(-1); + } + } + + ret = xmlSecGnuTLSKeysMngrInit(mngr); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSKeysMngrInit", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeysMngrInit", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + /* TODO */ mngr->getKey = xmlSecKeysMngrGetKey; return(0); @@ -363,125 +862,125 @@ xmlSecGnuTLSAppDefaultKeysMngrInit(xmlSecKeysMngrPtr mngr) { /** * xmlSecGnuTLSAppDefaultKeysMngrAdoptKey: - * @mngr: the pointer to keys manager. - * @key: the pointer to key. + * @mngr: the pointer to keys manager. + * @key: the pointer to key. * * Adds @key to the keys manager @mngr created with #xmlSecGnuTLSAppDefaultKeysMngrInit * function. - * + * * Returns: 0 on success or a negative value otherwise. - */ -int + */ +int xmlSecGnuTLSAppDefaultKeysMngrAdoptKey(xmlSecKeysMngrPtr mngr, xmlSecKeyPtr key) { xmlSecKeyStorePtr store; int ret; - + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(key != NULL, -1); - + store = xmlSecKeysMngrGetKeysStore(mngr); if(store == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeysMngrGetKeysStore", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrGetKeysStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + ret = xmlSecSimpleKeysStoreAdoptKey(store, key); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecSimpleKeysStoreAdoptKey", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecSimpleKeysStoreAdoptKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + return(0); } /** * xmlSecGnuTLSAppDefaultKeysMngrLoad: - * @mngr: the pointer to keys manager. - * @uri: the uri. + * @mngr: the pointer to keys manager. + * @uri: the uri. * - * Loads XML keys file from @uri to the keys manager @mngr created + * Loads XML keys file from @uri to the keys manager @mngr created * with #xmlSecGnuTLSAppDefaultKeysMngrInit function. - * + * * Returns: 0 on success or a negative value otherwise. - */ -int + */ +int xmlSecGnuTLSAppDefaultKeysMngrLoad(xmlSecKeysMngrPtr mngr, const char* uri) { xmlSecKeyStorePtr store; int ret; - + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(uri != NULL, -1); - + store = xmlSecKeysMngrGetKeysStore(mngr); if(store == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeysMngrGetKeysStore", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrGetKeysStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + ret = xmlSecSimpleKeysStoreLoad(store, uri, mngr); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecSimpleKeysStoreLoad", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "uri=%s", xmlSecErrorsSafeString(uri)); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecSimpleKeysStoreLoad", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "uri=%s", xmlSecErrorsSafeString(uri)); + return(-1); + } + return(0); } /** * xmlSecGnuTLSAppDefaultKeysMngrSave: - * @mngr: the pointer to keys manager. - * @filename: the destination filename. - * @type: the type of keys to save (public/private/symmetric). + * @mngr: the pointer to keys manager. + * @filename: the destination filename. + * @type: the type of keys to save (public/private/symmetric). * * Saves keys from @mngr to XML keys file. - * + * * Returns: 0 on success or a negative value otherwise. - */ -int + */ +int xmlSecGnuTLSAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename, xmlSecKeyDataType type) { xmlSecKeyStorePtr store; int ret; - + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); - + store = xmlSecKeysMngrGetKeysStore(mngr); if(store == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeysMngrGetKeysStore", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrGetKeysStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + ret = xmlSecSimpleKeysStoreSave(store, filename, type); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecSimpleKeysStoreSave", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "filename=%s", - xmlSecErrorsSafeString(filename)); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecSimpleKeysStoreSave", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + return(-1); + } + return(0); } |