-/*
- * Copyright 2001-2010 Internet2
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
*
- * Licensed 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
+ * UCAID 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
+ * 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.
+ * 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.
*/
/**
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
#include <xercesc/util/Base64.hpp>
+#ifdef WIN32
+# if (OPENSSL_VERSION_NUMBER >= 0x00907000)
+# define XMLTOOLING_OPENSSL_HAVE_EC 1
+# endif
+#endif
+
+#if defined(XMLTOOLING_XMLSEC_ECC) && defined(XMLTOOLING_OPENSSL_HAVE_EC)
+# include <xsec/enc/OpenSSL/OpenSSLCryptoKeyEC.hpp>
+#endif
+
using namespace xmltooling::logging;
using namespace xmltooling;
using namespace std;
ret=new OpenSSLCryptoKeyDSA(pkey);
break;
+#if defined(XMLTOOLING_XMLSEC_ECC) && defined(XMLTOOLING_OPENSSL_HAVE_EC)
+ case EVP_PKEY_EC:
+ ret=new OpenSSLCryptoKeyEC(pkey);
+ break;
+#endif
default:
log.error("unsupported private key type");
}
return (dsa1 && dsa2 && BN_cmp(dsa1->priv_key,dsa2->priv_key) == 0);
}
+#if defined(XMLTOOLING_XMLSEC_ECC) && defined(XMLTOOLING_OPENSSL_HAVE_EC)
+ // If one key is public or both, just compare the public key half.
+ if (key1.getKeyType()==XSECCryptoKey::KEY_EC_PUBLIC || key1.getKeyType()==XSECCryptoKey::KEY_EC_PAIR) {
+ if (key2.getKeyType()!=XSECCryptoKey::KEY_EC_PUBLIC && key2.getKeyType()!=XSECCryptoKey::KEY_EC_PAIR)
+ return false;
+ const EC_KEY* ec1 = static_cast<const OpenSSLCryptoKeyEC&>(key1).getOpenSSLEC();
+ const EC_KEY* ec2 = static_cast<const OpenSSLCryptoKeyEC&>(key2).getOpenSSLEC();
+ if (!ec1 || !ec2)
+ return false;
+ if (EC_GROUP_cmp(EC_KEY_get0_group(ec1), EC_KEY_get0_group(ec2), nullptr) != 0)
+ return false;
+ return (EC_POINT_cmp(EC_KEY_get0_group(ec1), EC_KEY_get0_public_key(ec1), EC_KEY_get0_public_key(ec2), nullptr) == 0);
+ }
+
+ // For a private key, compare the private half.
+ if (key1.getKeyType()==XSECCryptoKey::KEY_EC_PRIVATE) {
+ if (key2.getKeyType()!=XSECCryptoKey::KEY_EC_PRIVATE && key2.getKeyType()!=XSECCryptoKey::KEY_EC_PAIR)
+ return false;
+ const EC_KEY* ec1 = static_cast<const OpenSSLCryptoKeyEC&>(key1).getOpenSSLEC();
+ const EC_KEY* ec2 = static_cast<const OpenSSLCryptoKeyEC&>(key2).getOpenSSLEC();
+ return (ec1 && ec2 && BN_cmp(EC_KEY_get0_private_key(ec1), EC_KEY_get0_private_key(ec2)) == 0);
+ }
+#endif
+
Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("unsupported key type for comparison");
return false;
}
return ret;
}
+ const RSA* rsa = nullptr;
+ const DSA* dsa = nullptr;
+#if defined(XMLTOOLING_XMLSEC_ECC) && defined(XMLTOOLING_OPENSSL_HAVE_EC)
+ const EC_KEY* ec = nullptr;
+#endif
+
if (key.getKeyType() == XSECCryptoKey::KEY_RSA_PUBLIC || key.getKeyType() == XSECCryptoKey::KEY_RSA_PAIR) {
- const RSA* rsa = static_cast<const OpenSSLCryptoKeyRSA&>(key).getOpenSSLRSA();
+ rsa = static_cast<const OpenSSLCryptoKeyRSA&>(key).getOpenSSLRSA();
if (!rsa) {
Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("key was not populated");
return ret;
}
- const EVP_MD* md=nullptr;
- if (hash) {
- md = EVP_get_digestbyname(hash);
- if (!md) {
- Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error("hash algorithm (%s) not available", hash);
- return ret;
- }
- }
- BIO* chain = BIO_new(BIO_s_mem());
- BIO* b = BIO_new(BIO_f_base64());
- if (nowrap)
- BIO_set_flags(b, BIO_FLAGS_BASE64_NO_NL);
- chain = BIO_push(b, chain);
- if (md) {
- b = BIO_new(BIO_f_md());
- BIO_set_md(b, md);
- chain = BIO_push(b, chain);
- }
- i2d_RSA_PUBKEY_bio(chain, const_cast<RSA*>(rsa));
- BIO_flush(chain);
- if (md) {
- char digest[EVP_MAX_MD_SIZE];
- int len = BIO_gets(chain, digest, EVP_MD_size(md));
- if (len != EVP_MD_size(md)) {
- BIO_free_all(chain);
- return ret;
- }
- b = BIO_pop(chain);
- BIO_free(chain);
- chain = b;
- BIO_reset(chain);
- BIO_write(chain, digest, len);
- BIO_flush(chain);
- }
- BUF_MEM* bptr=nullptr;
- BIO_get_mem_ptr(chain, &bptr);
- if (bptr && bptr->length > 0)
- ret.append(bptr->data, bptr->length);
- BIO_free_all(chain);
}
else if (key.getKeyType() == XSECCryptoKey::KEY_DSA_PUBLIC || key.getKeyType() == XSECCryptoKey::KEY_DSA_PAIR) {
- const DSA* dsa = static_cast<const OpenSSLCryptoKeyDSA&>(key).getOpenSSLDSA();
+ dsa = static_cast<const OpenSSLCryptoKeyDSA&>(key).getOpenSSLDSA();
if (!dsa) {
Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("key was not populated");
return ret;
}
- const EVP_MD* md=nullptr;
- if (hash) {
- md = EVP_get_digestbyname(hash);
- if (!md) {
- Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error("hash algorithm (%s) not available", hash);
- return ret;
- }
+ }
+#if defined(XMLTOOLING_XMLSEC_ECC) && defined(XMLTOOLING_OPENSSL_HAVE_EC)
+ else if (key.getKeyType() == XSECCryptoKey::KEY_EC_PUBLIC || key.getKeyType() == XSECCryptoKey::KEY_EC_PAIR) {
+ ec = static_cast<const OpenSSLCryptoKeyEC&>(key).getOpenSSLEC();
+ if (!ec) {
+ Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("key was not populated");
+ return ret;
}
- BIO* chain = BIO_new(BIO_s_mem());
- BIO* b = BIO_new(BIO_f_base64());
- if (nowrap)
- BIO_set_flags(b, BIO_FLAGS_BASE64_NO_NL);
- chain = BIO_push(b, chain);
- if (md) {
- b = BIO_new(BIO_f_md());
- BIO_set_md(b, md);
- chain = BIO_push(b, chain);
+ }
+#endif
+ else {
+ Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("public key type not supported");
+ return ret;
+ }
+
+ const EVP_MD* md=nullptr;
+ if (hash) {
+ md = EVP_get_digestbyname(hash);
+ if (!md) {
+ Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error("hash algorithm (%s) not available", hash);
+ return ret;
}
+ }
+
+ BIO* chain = BIO_new(BIO_s_mem());
+ BIO* b = BIO_new(BIO_f_base64());
+ if (nowrap)
+ BIO_set_flags(b, BIO_FLAGS_BASE64_NO_NL);
+ chain = BIO_push(b, chain);
+ if (md) {
+ b = BIO_new(BIO_f_md());
+ BIO_set_md(b, md);
+ chain = BIO_push(b, chain);
+ }
+
+ if (rsa)
+ i2d_RSA_PUBKEY_bio(chain, const_cast<RSA*>(rsa));
+ else if (dsa)
i2d_DSA_PUBKEY_bio(chain, const_cast<DSA*>(dsa));
- BIO_flush(chain);
- if (md) {
- char digest[EVP_MAX_MD_SIZE];
- int len = BIO_gets(chain, digest, EVP_MD_size(md));
- if (len != EVP_MD_size(md)) {
- BIO_free_all(chain);
- return ret;
- }
- b = BIO_pop(chain);
- BIO_free(chain);
- chain = b;
- BIO_reset(chain);
- BIO_write(chain, digest, len);
- BIO_flush(chain);
+#if defined(XMLTOOLING_XMLSEC_ECC) && defined(XMLTOOLING_OPENSSL_HAVE_EC)
+ else
+ i2d_EC_PUBKEY_bio(chain, const_cast<EC_KEY*>(ec));
+#endif
+
+ BIO_flush(chain);
+ if (md) {
+ char digest[EVP_MAX_MD_SIZE];
+ int len = BIO_gets(chain, digest, EVP_MD_size(md));
+ if (len != EVP_MD_size(md)) {
+ BIO_free_all(chain);
+ return ret;
}
- BUF_MEM* bptr=nullptr;
- BIO_get_mem_ptr(chain, &bptr);
- if (bptr && bptr->length > 0)
- ret.append(bptr->data, bptr->length);
- BIO_free_all(chain);
- }
- else {
- Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("encoding of non-RSA/DSA public keys not supported");
+ b = BIO_pop(chain);
+ BIO_free(chain);
+ chain = b;
+ BIO_reset(chain);
+ BIO_write(chain, digest, len);
+ BIO_flush(chain);
}
+ BUF_MEM* bptr=nullptr;
+ BIO_get_mem_ptr(chain, &bptr);
+ if (bptr && bptr->length > 0)
+ ret.append(bptr->data, bptr->length);
+ BIO_free_all(chain);
+
return ret;
}
ret = new OpenSSLCryptoKeyDSA(pkey);
break;
+#if defined(XMLTOOLING_XMLSEC_ECC) && defined(XMLTOOLING_OPENSSL_HAVE_EC)
+ case EVP_PKEY_EC:
+ ret = new OpenSSLCryptoKeyEC(pkey);
+ break;
+#endif
default:
Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error("unsupported public key type");
}