diff options
Diffstat (limited to 'src/openssl/crypto.c')
-rw-r--r-- | src/openssl/crypto.c | 491 |
1 files changed, 491 insertions, 0 deletions
diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c new file mode 100644 index 00000000..aac8d09f --- /dev/null +++ b/src/openssl/crypto.c @@ -0,0 +1,491 @@ +/** + * 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 <openssl/evp.h> +#include <openssl/rand.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/keys.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/transforms.h> +#include <xmlsec/errors.h> +#include <xmlsec/dl.h> +#include <xmlsec/private.h> + +#include <xmlsec/openssl/app.h> +#include <xmlsec/openssl/crypto.h> +#include <xmlsec/openssl/x509.h> + +static int xmlSecOpenSSLErrorsInit (void); + +static xmlSecCryptoDLFunctionsPtr gXmlSecOpenSSLFunctions = NULL; +static xmlChar* gXmlSecOpenSSLTrustedCertsFolder = NULL; + +/** + * xmlSecCryptoGetFunctions_openssl: + * + * Gets the pointer to xmlsec-openssl functions table. + * + * Returns: the xmlsec-openssl functions table or NULL if an error occurs. + */ +xmlSecCryptoDLFunctionsPtr +xmlSecCryptoGetFunctions_openssl(void) { + static xmlSecCryptoDLFunctions functions; + + if(gXmlSecOpenSSLFunctions != NULL) { + return(gXmlSecOpenSSLFunctions); + } + + memset(&functions, 0, sizeof(functions)); + gXmlSecOpenSSLFunctions = &functions; + + /******************************************************************** + * + * Crypto Init/shutdown + * + ********************************************************************/ + gXmlSecOpenSSLFunctions->cryptoInit = xmlSecOpenSSLInit; + gXmlSecOpenSSLFunctions->cryptoShutdown = xmlSecOpenSSLShutdown; + gXmlSecOpenSSLFunctions->cryptoKeysMngrInit = xmlSecOpenSSLKeysMngrInit; + + /******************************************************************** + * + * Key data ids + * + ********************************************************************/ +#ifndef XMLSEC_NO_AES + gXmlSecOpenSSLFunctions->keyDataAesGetKlass = xmlSecOpenSSLKeyDataAesGetKlass; +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + gXmlSecOpenSSLFunctions->keyDataDesGetKlass = xmlSecOpenSSLKeyDataDesGetKlass; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_DSA + gXmlSecOpenSSLFunctions->keyDataDsaGetKlass = xmlSecOpenSSLKeyDataDsaGetKlass; +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecOpenSSLFunctions->keyDataHmacGetKlass = xmlSecOpenSSLKeyDataHmacGetKlass; +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_RSA + gXmlSecOpenSSLFunctions->keyDataRsaGetKlass = xmlSecOpenSSLKeyDataRsaGetKlass; +#endif /* XMLSEC_NO_RSA */ + +#ifndef XMLSEC_NO_X509 + gXmlSecOpenSSLFunctions->keyDataX509GetKlass = xmlSecOpenSSLKeyDataX509GetKlass; + gXmlSecOpenSSLFunctions->keyDataRawX509CertGetKlass = xmlSecOpenSSLKeyDataRawX509CertGetKlass; +#endif /* XMLSEC_NO_X509 */ + + /******************************************************************** + * + * Key data store ids + * + ********************************************************************/ +#ifndef XMLSEC_NO_X509 + gXmlSecOpenSSLFunctions->x509StoreGetKlass = xmlSecOpenSSLX509StoreGetKlass; +#endif /* XMLSEC_NO_X509 */ + + /******************************************************************** + * + * Crypto transforms ids + * + ********************************************************************/ + + /******************************* AES ********************************/ +#ifndef XMLSEC_NO_AES + gXmlSecOpenSSLFunctions->transformAes128CbcGetKlass = xmlSecOpenSSLTransformAes128CbcGetKlass; + gXmlSecOpenSSLFunctions->transformAes192CbcGetKlass = xmlSecOpenSSLTransformAes192CbcGetKlass; + gXmlSecOpenSSLFunctions->transformAes256CbcGetKlass = xmlSecOpenSSLTransformAes256CbcGetKlass; + gXmlSecOpenSSLFunctions->transformKWAes128GetKlass = xmlSecOpenSSLTransformKWAes128GetKlass; + gXmlSecOpenSSLFunctions->transformKWAes192GetKlass = xmlSecOpenSSLTransformKWAes192GetKlass; + gXmlSecOpenSSLFunctions->transformKWAes256GetKlass = xmlSecOpenSSLTransformKWAes256GetKlass; +#endif /* XMLSEC_NO_AES */ + + /******************************* DES ********************************/ +#ifndef XMLSEC_NO_DES + gXmlSecOpenSSLFunctions->transformDes3CbcGetKlass = xmlSecOpenSSLTransformDes3CbcGetKlass; + gXmlSecOpenSSLFunctions->transformKWDes3GetKlass = xmlSecOpenSSLTransformKWDes3GetKlass; +#endif /* XMLSEC_NO_DES */ + + /******************************* DSA ********************************/ +#ifndef XMLSEC_NO_DSA + +#ifndef XMLSEC_NO_SHA1 + gXmlSecOpenSSLFunctions->transformDsaSha1GetKlass = xmlSecOpenSSLTransformDsaSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + +#endif /* XMLSEC_NO_DSA */ + + /******************************* HMAC ********************************/ +#ifndef XMLSEC_NO_HMAC + +#ifndef XMLSEC_NO_MD5 + gXmlSecOpenSSLFunctions->transformHmacMd5GetKlass = xmlSecOpenSSLTransformHmacMd5GetKlass; +#endif /* XMLSEC_NO_MD5 */ + +#ifndef XMLSEC_NO_RIPEMD160 + gXmlSecOpenSSLFunctions->transformHmacRipemd160GetKlass = xmlSecOpenSSLTransformHmacRipemd160GetKlass; +#endif /* XMLSEC_NO_RIPEMD160 */ + +#ifndef XMLSEC_NO_SHA1 + gXmlSecOpenSSLFunctions->transformHmacSha1GetKlass = xmlSecOpenSSLTransformHmacSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + +#ifndef XMLSEC_NO_SHA224 + gXmlSecOpenSSLFunctions->transformHmacSha224GetKlass = xmlSecOpenSSLTransformHmacSha224GetKlass; +#endif /* XMLSEC_NO_SHA224 */ + +#ifndef XMLSEC_NO_SHA256 + gXmlSecOpenSSLFunctions->transformHmacSha256GetKlass = xmlSecOpenSSLTransformHmacSha256GetKlass; +#endif /* XMLSEC_NO_SHA256 */ + +#ifndef XMLSEC_NO_SHA384 + gXmlSecOpenSSLFunctions->transformHmacSha384GetKlass = xmlSecOpenSSLTransformHmacSha384GetKlass; +#endif /* XMLSEC_NO_SHA384 */ + +#ifndef XMLSEC_NO_SHA512 + gXmlSecOpenSSLFunctions->transformHmacSha512GetKlass = xmlSecOpenSSLTransformHmacSha512GetKlass; +#endif /* XMLSEC_NO_SHA512 */ + +#endif /* XMLSEC_NO_HMAC */ + + /******************************* MD5 ********************************/ +#ifndef XMLSEC_NO_MD5 + gXmlSecOpenSSLFunctions->transformMd5GetKlass = xmlSecOpenSSLTransformMd5GetKlass; +#endif /* XMLSEC_NO_MD5 */ + + /******************************* RIPEMD160 ********************************/ +#ifndef XMLSEC_NO_RIPEMD160 + gXmlSecOpenSSLFunctions->transformRipemd160GetKlass = xmlSecOpenSSLTransformRipemd160GetKlass; +#endif /* XMLSEC_NO_RIPEMD160 */ + + /******************************* RSA ********************************/ +#ifndef XMLSEC_NO_RSA + +#ifndef XMLSEC_NO_MD5 + gXmlSecOpenSSLFunctions->transformRsaMd5GetKlass = xmlSecOpenSSLTransformRsaMd5GetKlass; +#endif /* XMLSEC_NO_MD5 */ + +#ifndef XMLSEC_NO_RIPEMD160 + gXmlSecOpenSSLFunctions->transformRsaRipemd160GetKlass = xmlSecOpenSSLTransformRsaRipemd160GetKlass; +#endif /* XMLSEC_NO_RIPEMD160 */ + +#ifndef XMLSEC_NO_SHA1 + gXmlSecOpenSSLFunctions->transformRsaSha1GetKlass = xmlSecOpenSSLTransformRsaSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + +#ifndef XMLSEC_NO_SHA224 + gXmlSecOpenSSLFunctions->transformRsaSha224GetKlass = xmlSecOpenSSLTransformRsaSha224GetKlass; +#endif /* XMLSEC_NO_SHA224 */ + +#ifndef XMLSEC_NO_SHA256 + gXmlSecOpenSSLFunctions->transformRsaSha256GetKlass = xmlSecOpenSSLTransformRsaSha256GetKlass; +#endif /* XMLSEC_NO_SHA256 */ + +#ifndef XMLSEC_NO_SHA384 + gXmlSecOpenSSLFunctions->transformRsaSha384GetKlass = xmlSecOpenSSLTransformRsaSha384GetKlass; +#endif /* XMLSEC_NO_SHA384 */ + +#ifndef XMLSEC_NO_SHA512 + gXmlSecOpenSSLFunctions->transformRsaSha512GetKlass = xmlSecOpenSSLTransformRsaSha512GetKlass; +#endif /* XMLSEC_NO_SHA512 */ + + gXmlSecOpenSSLFunctions->transformRsaPkcs1GetKlass = xmlSecOpenSSLTransformRsaPkcs1GetKlass; + gXmlSecOpenSSLFunctions->transformRsaOaepGetKlass = xmlSecOpenSSLTransformRsaOaepGetKlass; +#endif /* XMLSEC_NO_RSA */ + + /******************************* SHA ********************************/ +#ifndef XMLSEC_NO_SHA1 + gXmlSecOpenSSLFunctions->transformSha1GetKlass = xmlSecOpenSSLTransformSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + +#ifndef XMLSEC_NO_SHA224 + gXmlSecOpenSSLFunctions->transformSha224GetKlass = xmlSecOpenSSLTransformSha224GetKlass; +#endif /* XMLSEC_NO_SHA224 */ + +#ifndef XMLSEC_NO_SHA256 + gXmlSecOpenSSLFunctions->transformSha256GetKlass = xmlSecOpenSSLTransformSha256GetKlass; +#endif /* XMLSEC_NO_SHA256 */ + +#ifndef XMLSEC_NO_SHA384 + gXmlSecOpenSSLFunctions->transformSha384GetKlass = xmlSecOpenSSLTransformSha384GetKlass; +#endif /* XMLSEC_NO_SHA384 */ + +#ifndef XMLSEC_NO_SHA512 + gXmlSecOpenSSLFunctions->transformSha512GetKlass = xmlSecOpenSSLTransformSha512GetKlass; +#endif /* XMLSEC_NO_SHA512 */ + + /******************************************************************** + * + * High level routines form xmlsec command line utility + * + ********************************************************************/ + gXmlSecOpenSSLFunctions->cryptoAppInit = xmlSecOpenSSLAppInit; + gXmlSecOpenSSLFunctions->cryptoAppShutdown = xmlSecOpenSSLAppShutdown; + gXmlSecOpenSSLFunctions->cryptoAppDefaultKeysMngrInit = xmlSecOpenSSLAppDefaultKeysMngrInit; + gXmlSecOpenSSLFunctions->cryptoAppDefaultKeysMngrAdoptKey = xmlSecOpenSSLAppDefaultKeysMngrAdoptKey; + gXmlSecOpenSSLFunctions->cryptoAppDefaultKeysMngrLoad = xmlSecOpenSSLAppDefaultKeysMngrLoad; + gXmlSecOpenSSLFunctions->cryptoAppDefaultKeysMngrSave = xmlSecOpenSSLAppDefaultKeysMngrSave; +#ifndef XMLSEC_NO_X509 + gXmlSecOpenSSLFunctions->cryptoAppKeysMngrCertLoad = xmlSecOpenSSLAppKeysMngrCertLoad; + gXmlSecOpenSSLFunctions->cryptoAppKeysMngrCertLoadMemory = xmlSecOpenSSLAppKeysMngrCertLoadMemory; + gXmlSecOpenSSLFunctions->cryptoAppPkcs12Load = xmlSecOpenSSLAppPkcs12Load; + gXmlSecOpenSSLFunctions->cryptoAppPkcs12LoadMemory = xmlSecOpenSSLAppPkcs12LoadMemory; + gXmlSecOpenSSLFunctions->cryptoAppKeyCertLoad = xmlSecOpenSSLAppKeyCertLoad; + gXmlSecOpenSSLFunctions->cryptoAppKeyCertLoadMemory = xmlSecOpenSSLAppKeyCertLoadMemory; +#endif /* XMLSEC_NO_X509 */ + gXmlSecOpenSSLFunctions->cryptoAppKeyLoad = xmlSecOpenSSLAppKeyLoad; + gXmlSecOpenSSLFunctions->cryptoAppKeyLoadMemory = xmlSecOpenSSLAppKeyLoadMemory; + gXmlSecOpenSSLFunctions->cryptoAppDefaultPwdCallback = (void*)xmlSecOpenSSLAppGetDefaultPwdCallback(); + + return(gXmlSecOpenSSLFunctions); +} + +/** + * xmlSecOpenSSLInit: + * + * XMLSec library specific crypto engine initialization. + * + * Returns: 0 on success or a negative value otherwise. + */ +int +xmlSecOpenSSLInit (void) { + /* Check loaded xmlsec library version */ + if(xmlSecCheckVersionExact() != 1) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCheckVersionExact", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if(xmlSecOpenSSLErrorsInit() < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecOpenSSLErrorsInit", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + /* register our klasses */ + if(xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(xmlSecCryptoGetFunctions_openssl()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(0); +} + +/** + * xmlSecOpenSSLShutdown: + * + * XMLSec library specific crypto engine shutdown. + * + * Returns: 0 on success or a negative value otherwise. + */ +int +xmlSecOpenSSLShutdown(void) { + xmlSecOpenSSLSetDefaultTrustedCertsFolder(NULL); + return(0); +} + +/** + * xmlSecOpenSSLKeysMngrInit: + * @mngr: the pointer to keys manager. + * + * Adds OpenSSL specific key data stores in keys manager. + * + * Returns: 0 on success or a negative value otherwise. + */ +int +xmlSecOpenSSLKeysMngrInit(xmlSecKeysMngrPtr mngr) { + int ret; + + xmlSecAssert2(mngr != NULL, -1); + +#ifndef XMLSEC_NO_X509 + /* create x509 store if needed */ + if(xmlSecKeysMngrGetDataStore(mngr, xmlSecOpenSSLX509StoreId) == NULL) { + xmlSecKeyDataStorePtr x509Store; + + x509Store = xmlSecKeyDataStoreCreate(xmlSecOpenSSLX509StoreId); + if(x509Store == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataStoreCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecOpenSSLX509StoreId"); + return(-1); + } + + ret = xmlSecKeysMngrAdoptDataStore(mngr, x509Store); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrAdoptDataStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataStoreDestroy(x509Store); + return(-1); + } + } +#endif /* XMLSEC_NO_X509 */ + return(0); +} + +/** + * xmlSecOpenSSLGenerateRandom: + * @buffer: the destination buffer. + * @size: the numer of bytes to generate. + * + * Generates @size random bytes and puts result in @buffer. + * + * Returns: 0 on success or a negative value otherwise. + */ +int +xmlSecOpenSSLGenerateRandom(xmlSecBufferPtr buffer, xmlSecSize size) { + int ret; + + xmlSecAssert2(buffer != NULL, -1); + xmlSecAssert2(size > 0, -1); + + ret = xmlSecBufferSetSize(buffer, size); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferSetSize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=%d", size); + return(-1); + } + + /* get random data */ + ret = RAND_bytes((xmlSecByte*)xmlSecBufferGetData(buffer), size); + if(ret != 1) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "RAND_bytes", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "size=%d", size); + return(-1); + } + return(0); +} + +/** + * xmlSecOpenSSLErrorsDefaultCallback: + * @file: the error location file name (__FILE__ macro). + * @line: the error location line number (__LINE__ macro). + * @func: the error location function name (__FUNCTION__ macro). + * @errorObject: the error specific error object + * @errorSubject: the error specific error subject. + * @reason: the error code. + * @msg: the additional error message. + * + * The default OpenSSL errors reporting callback function. + */ +void +xmlSecOpenSSLErrorsDefaultCallback(const char* file, int line, const char* func, + const char* errorObject, const char* errorSubject, + int reason, const char* msg) { + + ERR_put_error(XMLSEC_OPENSSL_ERRORS_LIB, + XMLSEC_OPENSSL_ERRORS_FUNCTION, + reason, file, line); + xmlSecErrorsDefaultCallback(file, line, func, + errorObject, errorSubject, + reason, msg); +} + +static int +xmlSecOpenSSLErrorsInit(void) { + static ERR_STRING_DATA xmlSecOpenSSLStrReasons[XMLSEC_ERRORS_MAX_NUMBER + 1]; + static ERR_STRING_DATA xmlSecOpenSSLStrLib[]= { + { ERR_PACK(XMLSEC_OPENSSL_ERRORS_LIB,0,0), "xmlsec routines"}, + { 0, NULL} + }; + static ERR_STRING_DATA xmlSecOpenSSLStrDefReason[]= { + { XMLSEC_OPENSSL_ERRORS_LIB, "xmlsec lib"}, + { 0, NULL} + }; + xmlSecSize pos; + + /* initialize reasons array */ + memset(xmlSecOpenSSLStrReasons, 0, sizeof(xmlSecOpenSSLStrReasons)); + for(pos = 0; (pos < XMLSEC_ERRORS_MAX_NUMBER) && (xmlSecErrorsGetMsg(pos) != NULL); ++pos) { + xmlSecOpenSSLStrReasons[pos].error = xmlSecErrorsGetCode(pos); + xmlSecOpenSSLStrReasons[pos].string = xmlSecErrorsGetMsg(pos); + } + + /* finally load xmlsec strings in OpenSSL */ + ERR_load_strings(XMLSEC_OPENSSL_ERRORS_LIB, xmlSecOpenSSLStrLib); /* define xmlsec lib name */ + ERR_load_strings(XMLSEC_OPENSSL_ERRORS_LIB, xmlSecOpenSSLStrDefReason); /* define default reason */ + ERR_load_strings(XMLSEC_OPENSSL_ERRORS_LIB, xmlSecOpenSSLStrReasons); + + /* and set default errors callback for xmlsec to us */ + xmlSecErrorsSetCallback(xmlSecOpenSSLErrorsDefaultCallback); + + return(0); +} + +/** + * xmlSecOpenSSLSetDefaultTrustedCertsFolder: + * @path: the default trusted certs path. + * + * Sets the default trusted certs folder. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecOpenSSLSetDefaultTrustedCertsFolder(const xmlChar* path) { + if(gXmlSecOpenSSLTrustedCertsFolder != NULL) { + xmlFree(gXmlSecOpenSSLTrustedCertsFolder); + gXmlSecOpenSSLTrustedCertsFolder = NULL; + } + + if(path != NULL) { + gXmlSecOpenSSLTrustedCertsFolder = xmlStrdup(BAD_CAST path); + if(gXmlSecOpenSSLTrustedCertsFolder == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlStrdup", + XMLSEC_ERRORS_R_MALLOC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + + return(0); +} + +/** + * xmlSecOpenSSLGetDefaultTrustedCertsFolder: + * + * Gets the default trusted certs folder. + * + * Returns: the default trusted cert folder. + */ +const xmlChar* +xmlSecOpenSSLGetDefaultTrustedCertsFolder(void) { + return(gXmlSecOpenSSLTrustedCertsFolder); +} + + + |