blob: 9058b3c47ac14288657b398d6fed6a1198e0f77c [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* XSEC
*
* OpenSSLCryptoProvider := Base class to define an OpenSSL module
*
* Author(s): Berin Lautenbach
*
* $Id$
*
*/
#include <xsec/framework/XSECDefs.hpp>
#if defined (XSEC_HAVE_OPENSSL)
#include <xsec/framework/XSECError.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoProvider.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoHash.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoHashHMAC.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoBase64.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyEC.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyHMAC.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp>
#include <xsec/enc/OpenSSL/OpenSSLSupport.hpp>
#include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
#include <xsec/enc/XSECCryptoException.hpp>
#include <xercesc/util/Janitor.hpp>
XSEC_USING_XERCES(ArrayJanitor);
XSEC_USING_XERCES(Janitor);
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/obj_mac.h>
OpenSSLCryptoProvider::OpenSSLCryptoProvider() {
OpenSSL_add_all_algorithms(); // Initialise Openssl
ERR_load_crypto_strings();
//SSLeay_add_all_algorithms();
#ifdef XSEC_OPENSSL_HAVE_EC
// Populate curve names.
m_namedCurveMap["urn:oid:1.3.132.0.6"] = NID_secp112r1;
m_namedCurveMap["urn:oid:1.3.132.0.7"] = NID_secp112r2;
m_namedCurveMap["urn:oid:1.3.132.0.28"] = NID_secp128r1;
m_namedCurveMap["urn:oid:1.3.132.0.29"] = NID_secp128r2;
m_namedCurveMap["urn:oid:1.3.132.0.9"] = NID_secp160k1;
m_namedCurveMap["urn:oid:1.3.132.0.8"] = NID_secp160r1;
m_namedCurveMap["urn:oid:1.3.132.0.30"] = NID_secp160r2;
m_namedCurveMap["urn:oid:1.3.132.0.31"] = NID_secp192k1;
m_namedCurveMap["urn:oid:1.3.132.0.32"] = NID_secp224k1;
m_namedCurveMap["urn:oid:1.3.132.0.33"] = NID_secp224r1;
m_namedCurveMap["urn:oid:1.3.132.0.10"] = NID_secp256k1;
m_namedCurveMap["urn:oid:1.3.132.0.34"] = NID_secp384r1;
m_namedCurveMap["urn:oid:1.3.132.0.35"] = NID_secp521r1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.1.1"] = NID_X9_62_prime192v1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.1.2"] = NID_X9_62_prime192v2;
m_namedCurveMap["urn:oid:1.2.840.10045.3.1.3"] = NID_X9_62_prime192v3;
m_namedCurveMap["urn:oid:1.2.840.10045.3.1.4"] = NID_X9_62_prime239v1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.1.5"] = NID_X9_62_prime239v2;
m_namedCurveMap["urn:oid:1.2.840.10045.3.1.6"] = NID_X9_62_prime239v3;
m_namedCurveMap["urn:oid:1.2.840.10045.3.1.7"] = NID_X9_62_prime256v1;
m_namedCurveMap["urn:oid:1.3.132.0.4"] = NID_sect113r1;
m_namedCurveMap["urn:oid:1.3.132.0.5"] = NID_sect113r2;
m_namedCurveMap["urn:oid:1.3.132.0.22"] = NID_sect131r1;
m_namedCurveMap["urn:oid:1.3.132.0.23"] = NID_sect131r2;
m_namedCurveMap["urn:oid:1.3.132.0.1"] = NID_sect163k1;
m_namedCurveMap["urn:oid:1.3.132.0.2"] = NID_sect163r1;
m_namedCurveMap["urn:oid:1.3.132.0.15"] = NID_sect163r2;
m_namedCurveMap["urn:oid:1.3.132.0.24"] = NID_sect193r1;
m_namedCurveMap["urn:oid:1.3.132.0.25"] = NID_sect193r2;
m_namedCurveMap["urn:oid:1.3.132.0.26"] = NID_sect233k1;
m_namedCurveMap["urn:oid:1.3.132.0.27"] = NID_sect233r1;
m_namedCurveMap["urn:oid:1.3.132.0.3"] = NID_sect239k1;
m_namedCurveMap["urn:oid:1.3.132.0.16"] = NID_sect283k1;
m_namedCurveMap["urn:oid:1.3.132.0.17"] = NID_sect283r1;
m_namedCurveMap["urn:oid:1.3.132.0.36"] = NID_sect409k1;
m_namedCurveMap["urn:oid:1.3.132.0.37"] = NID_sect409r1;
m_namedCurveMap["urn:oid:1.3.132.0.38"] = NID_sect571k1;
m_namedCurveMap["urn:oid:1.3.132.0.39"] = NID_sect571r1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.1"] = NID_X9_62_c2pnb163v1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.2"] = NID_X9_62_c2pnb163v2;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.3"] = NID_X9_62_c2pnb163v3;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.4"] = NID_X9_62_c2pnb176v1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.5"] = NID_X9_62_c2tnb191v1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.6"] = NID_X9_62_c2tnb191v2;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.7"] = NID_X9_62_c2tnb191v3;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.8"] = NID_X9_62_c2onb191v4;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.9"] = NID_X9_62_c2onb191v5;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.10"] = NID_X9_62_c2pnb208w1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.11"] = NID_X9_62_c2tnb239v1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.12"] = NID_X9_62_c2tnb239v2;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.13"] = NID_X9_62_c2tnb239v3;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.14"] = NID_X9_62_c2onb239v4;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.15"] = NID_X9_62_c2onb239v5;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.16"] = NID_X9_62_c2pnb272w1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.17"] = NID_X9_62_c2pnb304w1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.18"] = NID_X9_62_c2tnb359v1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.19"] = NID_X9_62_c2pnb368w1;
m_namedCurveMap["urn:oid:1.2.840.10045.3.0.20"] = NID_X9_62_c2tnb431r1;
m_namedCurveMap["urn:oid:2.23.43.1.4.1"] = NID_wap_wsg_idm_ecid_wtls1;
m_namedCurveMap["urn:oid:2.23.43.1.4.3"] = NID_wap_wsg_idm_ecid_wtls3;
m_namedCurveMap["urn:oid:2.23.43.1.4.4"] = NID_wap_wsg_idm_ecid_wtls4;
m_namedCurveMap["urn:oid:2.23.43.1.4.5"] = NID_wap_wsg_idm_ecid_wtls5;
m_namedCurveMap["urn:oid:2.23.43.1.4.6"] = NID_wap_wsg_idm_ecid_wtls6;
m_namedCurveMap["urn:oid:2.23.43.1.4.7"] = NID_wap_wsg_idm_ecid_wtls7;
m_namedCurveMap["urn:oid:2.23.43.1.4.8"] = NID_wap_wsg_idm_ecid_wtls8;
m_namedCurveMap["urn:oid:2.23.43.1.4.9"] = NID_wap_wsg_idm_ecid_wtls9;
m_namedCurveMap["urn:oid:2.23.43.1.4.10"] = NID_wap_wsg_idm_ecid_wtls10;
m_namedCurveMap["urn:oid:2.23.43.1.4.11"] = NID_wap_wsg_idm_ecid_wtls11;
m_namedCurveMap["urn:oid:2.23.43.1.4.12"] = NID_wap_wsg_idm_ecid_wtls12;
#endif
}
OpenSSLCryptoProvider::~OpenSSLCryptoProvider() {
EVP_cleanup();
ERR_free_strings();
/* As suggested by Jesse Pelton */
#if defined(XSEC_OPENSSL_HAVE_CRYPTO_CLEANUP_ALL_EX_DATA)
CRYPTO_cleanup_all_ex_data();
#endif
RAND_cleanup();
X509_TRUST_cleanup();
ERR_remove_state(0);
}
#ifdef XSEC_OPENSSL_HAVE_EC
int OpenSSLCryptoProvider::curveNameToNID(const char* curveName) const {
std::map<std::string,int>::const_iterator i = m_namedCurveMap.find(curveName);
if (i == m_namedCurveMap.end())
throw XSECCryptoException(XSECCryptoException::UnsupportedError,
"OpenSSLCryptoProvider::curveNameToNID - curve name not recognized");
return i->second;
}
#endif
const XMLCh * OpenSSLCryptoProvider::getProviderName() const {
return DSIGConstants::s_unicodeStrPROVOpenSSL;
}
// Hashing classes
unsigned int OpenSSLCryptoProvider::getMaxHashSize() const {
return 128;
}
XSECCryptoHash * OpenSSLCryptoProvider::hash(XSECCryptoHash::HashType type) const {
OpenSSLCryptoHash* ret;
XSECnew(ret, OpenSSLCryptoHash(type));
return ret;
}
XSECCryptoHash * OpenSSLCryptoProvider::HMAC(XSECCryptoHash::HashType type) const {
OpenSSLCryptoHashHMAC* ret;
XSECnew(ret, OpenSSLCryptoHashHMAC(type));
return ret;
}
XSECCryptoKeyHMAC * OpenSSLCryptoProvider::keyHMAC(void) const {
OpenSSLCryptoKeyHMAC * ret;
XSECnew(ret, OpenSSLCryptoKeyHMAC);
return ret;
}
XSECCryptoKeyDSA * OpenSSLCryptoProvider::keyDSA() const {
OpenSSLCryptoKeyDSA * ret;
XSECnew(ret, OpenSSLCryptoKeyDSA());
return ret;
}
XSECCryptoKeyRSA * OpenSSLCryptoProvider::keyRSA() const {
OpenSSLCryptoKeyRSA * ret;
XSECnew(ret, OpenSSLCryptoKeyRSA());
return ret;
}
XSECCryptoKeyEC * OpenSSLCryptoProvider::keyEC() const {
#ifdef XSEC_OPENSSL_HAVE_EC
OpenSSLCryptoKeyEC * ret;
XSECnew(ret, OpenSSLCryptoKeyEC());
return ret;
#else
throw XSECCryptoException(XSECCryptoException::UnsupportedError,
"OpenSSLCryptoProvider::keyEC - EC support not available");
#endif
}
XSECCryptoKey* OpenSSLCryptoProvider::keyDER(const char* buf, unsigned long len, bool base64) const {
EVP_PKEY* pkey = NULL;
if (base64) {
int bufLen = len;
unsigned char * outBuf;
XSECnew(outBuf, unsigned char[len + 1]);
ArrayJanitor<unsigned char> j_outBuf(outBuf);
/* Had to move to our own Base64 decoder because it handles non-wrapped b64
better. Grrr. */
XSCryptCryptoBase64 *b64;
XSECnew(b64, XSCryptCryptoBase64);
Janitor<XSCryptCryptoBase64> j_b64(b64);
b64->decodeInit();
bufLen = b64->decode((unsigned char *) buf, len, outBuf, len);
bufLen += b64->decodeFinish(&outBuf[bufLen], len-bufLen);
BIO* b = BIO_new_mem_buf((void*)outBuf, bufLen);
pkey = d2i_PUBKEY_bio(b, NULL);
BIO_free(b);
}
else {
BIO* b = BIO_new_mem_buf((void*)buf, len);
pkey = d2i_PUBKEY_bio(b, NULL);
BIO_free(b);
}
if (pkey) {
XSECCryptoKey* ret = NULL;
try {
switch (EVP_PKEY_id(pkey)) {
case EVP_PKEY_RSA:
ret = new OpenSSLCryptoKeyRSA(pkey);
break;
case EVP_PKEY_DSA:
ret = new OpenSSLCryptoKeyDSA(pkey);
break;
#if defined(XSEC_OPENSSL_HAVE_EC)
case EVP_PKEY_EC:
ret = new OpenSSLCryptoKeyEC(pkey);
break;
#endif
}
}
catch (const XSECCryptoException&) {
EVP_PKEY_free(pkey);
throw;
}
EVP_PKEY_free(pkey);
return ret;
}
throw XSECCryptoException(XSECCryptoException::UnsupportedError,
"OpenSSLCryptoProvider::keyDER - Error decoding public key");
}
XSECCryptoX509 * OpenSSLCryptoProvider::X509() const {
OpenSSLCryptoX509 * ret;
XSECnew(ret, OpenSSLCryptoX509());
return ret;
}
XSECCryptoBase64 * OpenSSLCryptoProvider::base64() const {
XSCryptCryptoBase64 *ret;
XSECnew(ret, XSCryptCryptoBase64);
return ret;
}
bool OpenSSLCryptoProvider::algorithmSupported(XSECCryptoSymmetricKey::SymmetricKeyType alg) const {
switch (alg) {
case (XSECCryptoSymmetricKey::KEY_AES_128) :
case (XSECCryptoSymmetricKey::KEY_AES_192) :
case (XSECCryptoSymmetricKey::KEY_AES_256) :
#if !defined (XSEC_OPENSSL_HAVE_AES)
return false;
#endif
case (XSECCryptoSymmetricKey::KEY_3DES_192) :
return true;
default:
return false;
}
return false;
}
bool OpenSSLCryptoProvider::algorithmSupported(XSECCryptoHash::HashType alg) const {
switch (alg) {
case (XSECCryptoHash::HASH_SHA1) :
case (XSECCryptoHash::HASH_MD5) :
return true;
case (XSECCryptoHash::HASH_SHA224) :
case (XSECCryptoHash::HASH_SHA256) :
#if defined(XSEC_OPENSSL_HAVE_SHA2) && !defined(OPENSSL_NO_SHA256)
return true;
#else
return false;
#endif
case (XSECCryptoHash::HASH_SHA384) :
case (XSECCryptoHash::HASH_SHA512) :
#if defined(XSEC_OPENSSL_HAVE_SHA2) && !defined(OPENSSL_NO_SHA512)
return true;
#else
return false;
#endif
default:
return false;
}
return false;
}
XSECCryptoSymmetricKey * OpenSSLCryptoProvider::keySymmetric(XSECCryptoSymmetricKey::SymmetricKeyType alg) const {
OpenSSLCryptoSymmetricKey * ret;
XSECnew(ret, OpenSSLCryptoSymmetricKey(alg));
return ret;
}
unsigned int OpenSSLCryptoProvider::getRandom(unsigned char * buffer, unsigned int numOctets) const {
if (RAND_status() != 1) {
throw XSECCryptoException(XSECCryptoException::GeneralError,
"OpenSSLCryptoProvider::getRandom - OpenSSL random not properly initialised");
}
int res = RAND_bytes(buffer, numOctets);
if (res == 0) {
throw XSECCryptoException(XSECCryptoException::GeneralError,
"OpenSSLCryptoProvider::getRandom - Error obtaining random octets");
}
return numOctets;
}
#endif /* XSEC_HAVE_OPENSSL */