From 962ea5690cb9351822c30da534ecae7aeeba667d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Tue, 18 Nov 2014 10:18:18 +0100 Subject: Add elliptic curve support to QSsl Add possibility to get length and other information of EC based certificates. Also it is possible to parse those public/private keys from PEM and DER encoded files. Based on patch by Remco Bloemen [ChangeLog][QtNetwork][SSL/TLS support] It is now possible to parse elliptic curve certificates. Change-Id: I4b11f726296aecda89c3cbd195d7c817ae6fc47b Task-number: QTBUG-18972 Reviewed-by: Thiago Macieira --- src/network/ssl/qssl.cpp | 1 + src/network/ssl/qssl.h | 3 +- src/network/ssl/qsslcertificate_openssl.cpp | 6 +++ src/network/ssl/qsslcontext_openssl.cpp | 6 ++- src/network/ssl/qsslkey_openssl.cpp | 60 ++++++++++++++++++++++++-- src/network/ssl/qsslkey_p.cpp | 18 ++++++-- src/network/ssl/qsslkey_p.h | 6 +++ src/network/ssl/qsslsocket_openssl_symbols.cpp | 52 ++++++++++++++++++++++ src/network/ssl/qsslsocket_openssl_symbols_p.h | 24 +++++++++++ 9 files changed, 167 insertions(+), 9 deletions(-) (limited to 'src/network') diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index 98be348e19..f76674f500 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -65,6 +65,7 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); \value Rsa The RSA algorithm. \value Dsa The DSA algorithm. + \value Ec The Elliptic Curve algorithm \value Opaque A key that should be treated as a 'black box' by QSslKey. The opaque key facility allows applications to add support for facilities diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h index b0a35075fc..b626b884dc 100644 --- a/src/network/ssl/qssl.h +++ b/src/network/ssl/qssl.h @@ -55,7 +55,8 @@ namespace QSsl { enum KeyAlgorithm { Opaque, Rsa, - Dsa + Dsa, + Ec }; enum AlternativeNameEntryType { diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index 065f0bfd04..4cb2e525eb 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -249,6 +249,12 @@ QSslKey QSslCertificate::publicKey() const key.d->dsa = q_EVP_PKEY_get1_DSA(pkey); key.d->algorithm = QSsl::Dsa; key.d->isNull = false; +#ifndef OPENSSL_NO_EC + } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_EC) { + key.d->ec = q_EVP_PKEY_get1_EC_KEY(pkey); + key.d->algorithm = QSsl::Ec; + key.d->isNull = false; +#endif } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_DH) { // DH unsupported } else { diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 0a687082b7..d5328901a7 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -269,8 +269,12 @@ init_context: // take ownership of the RSA/DSA key instance because the QSslKey already has ownership. if (configuration.d->privateKey.algorithm() == QSsl::Rsa) q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); - else + else if (configuration.d->privateKey.algorithm() == QSsl::Dsa) q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); +#ifndef OPENSSL_NO_EC + else if (configuration.d->privateKey.algorithm() == QSsl::Ec) + q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); +#endif } if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) { diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp index e4d30ff229..ee4e8efa7c 100644 --- a/src/network/ssl/qsslkey_openssl.cpp +++ b/src/network/ssl/qsslkey_openssl.cpp @@ -70,6 +70,13 @@ void QSslKeyPrivate::clear(bool deep) q_DSA_free(dsa); dsa = 0; } +#ifndef OPENSSL_NO_EC + if (ec) { + if (deep) + q_EC_KEY_free(ec); + ec = 0; + } +#endif if (opaque) { if (deep) q_EVP_PKEY_free(opaque); @@ -99,6 +106,16 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey) return true; } +#ifndef OPENSSL_NO_EC + else if (pkey->type == EVP_PKEY_EC) { + isNull = false; + algorithm = QSsl::Ec; + type = QSsl::PrivateKey; + ec = q_EC_KEY_dup(q_EVP_PKEY_get1_EC_KEY(pkey)); + + return true; + } +#endif else { // Unknown key type. This could be handled as opaque, but then // we'd eventually leak memory since we wouldn't be able to free @@ -138,12 +155,20 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra : q_PEM_read_bio_RSAPrivateKey(bio, &rsa, 0, phrase); if (rsa && rsa == result) isNull = false; - } else { + } else if (algorithm == QSsl::Dsa) { DSA *result = (type == QSsl::PublicKey) ? q_PEM_read_bio_DSA_PUBKEY(bio, &dsa, 0, phrase) : q_PEM_read_bio_DSAPrivateKey(bio, &dsa, 0, phrase); if (dsa && dsa == result) isNull = false; +#ifndef OPENSSL_NO_EC + } else if (algorithm == QSsl::Ec) { + EC_KEY *result = (type == QSsl::PublicKey) + ? q_PEM_read_bio_EC_PUBKEY(bio, &ec, 0, phrase) + : q_PEM_read_bio_ECPrivateKey(bio, &ec, 0, phrase); + if (ec && ec == result) + isNull = false; +#endif } q_BIO_free(bio); @@ -154,8 +179,14 @@ int QSslKeyPrivate::length() const if (isNull || algorithm == QSsl::Opaque) return -1; - return (algorithm == QSsl::Rsa) - ? q_BN_num_bits(rsa->n) : q_BN_num_bits(dsa->p); + switch (algorithm) { + case QSsl::Rsa: return q_BN_num_bits(rsa->n); + case QSsl::Dsa: return q_BN_num_bits(dsa->p); +#ifndef OPENSSL_NO_EC + case QSsl::Ec: return q_EC_GROUP_get_degree(q_EC_KEY_get0_group(ec)); +#endif + default: return -1; + } } QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const @@ -182,7 +213,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const fail = true; } } - } else { + } else if (algorithm == QSsl::Dsa) { if (type == QSsl::PublicKey) { if (!q_PEM_write_bio_DSA_PUBKEY(bio, dsa)) fail = true; @@ -195,6 +226,23 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const fail = true; } } +#ifndef OPENSSL_NO_EC + } else if (algorithm == QSsl::Ec) { + if (type == QSsl::PublicKey) { + if (!q_PEM_write_bio_EC_PUBKEY(bio, ec)) + fail = true; + } else { + if (!q_PEM_write_bio_ECPrivateKey( + bio, ec, + // ### the cipher should be selectable in the API: + passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : q_EVP_des_ede3_cbc(), + (uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) { + fail = true; + } + } +#endif + } else { + fail = true; } QByteArray pem; @@ -216,6 +264,10 @@ Qt::HANDLE QSslKeyPrivate::handle() const return Qt::HANDLE(rsa); case QSsl::Dsa: return Qt::HANDLE(dsa); +#ifndef OPENSSL_NO_EC + case QSsl::Ec: + return Qt::HANDLE(ec); +#endif default: return Qt::HANDLE(NULL); } diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp index 6162034fd7..99d502e8f9 100644 --- a/src/network/ssl/qsslkey_p.cpp +++ b/src/network/ssl/qsslkey_p.cpp @@ -103,7 +103,13 @@ QByteArray QSslKeyPrivate::pemHeader() const return QByteArrayLiteral("-----BEGIN PUBLIC KEY-----"); else if (algorithm == QSsl::Rsa) return QByteArrayLiteral("-----BEGIN RSA PRIVATE KEY-----"); - return QByteArrayLiteral("-----BEGIN DSA PRIVATE KEY-----"); + else if (algorithm == QSsl::Dsa) + return QByteArrayLiteral("-----BEGIN DSA PRIVATE KEY-----"); + else if (algorithm == QSsl::Ec) + return QByteArrayLiteral("-----BEGIN EC PRIVATE KEY-----"); + + Q_UNREACHABLE(); + return QByteArray(); } /*! @@ -115,7 +121,13 @@ QByteArray QSslKeyPrivate::pemFooter() const return QByteArrayLiteral("-----END PUBLIC KEY-----"); else if (algorithm == QSsl::Rsa) return QByteArrayLiteral("-----END RSA PRIVATE KEY-----"); - return QByteArrayLiteral("-----END DSA PRIVATE KEY-----"); + else if (algorithm == QSsl::Dsa) + return QByteArrayLiteral("-----END DSA PRIVATE KEY-----"); + else if (algorithm == QSsl::Ec) + return QByteArrayLiteral("-----END EC PRIVATE KEY-----"); + + Q_UNREACHABLE(); + return QByteArray(); } /*! @@ -438,7 +450,7 @@ QDebug operator<<(QDebug debug, const QSslKey &key) debug << "QSslKey(" << (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey") << ", " << (key.algorithm() == QSsl::Opaque ? "OPAQUE" : - (key.algorithm() == QSsl::Rsa ? "RSA" : "DSA")) + (key.algorithm() == QSsl::Rsa ? "RSA" : ((key.algorithm() == QSsl::Dsa) ? "DSA" : "EC"))) << ", " << key.length() << ')'; return debug; diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h index 1254b33dfb..9cea860867 100644 --- a/src/network/ssl/qsslkey_p.h +++ b/src/network/ssl/qsslkey_p.h @@ -65,6 +65,9 @@ public: #ifndef QT_NO_OPENSSL , rsa(0) , dsa(0) +#ifndef OPENSSL_NO_EC + , ec(0) +#endif #endif { clear(); @@ -97,6 +100,9 @@ public: EVP_PKEY *opaque; RSA *rsa; DSA *dsa; +#ifndef OPENSSL_NO_EC + EC_KEY *ec; +#endif #else enum Cipher { DesCbc, diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 91de3b2743..ef87e77a3e 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -142,6 +142,10 @@ DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return) DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return) DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return) DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return) +#ifndef OPENSSL_NO_EC +DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return 0, return) +DEFINEFUNC(int, EC_GROUP_get_degree, const EC_GROUP* g, g, return 0, return) +#endif DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG) DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG) @@ -160,9 +164,15 @@ DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, r DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return) DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return) DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return) +#ifndef OPENSSL_NO_EC +DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return) +#endif DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG) DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return 0, return) DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return 0, return) +#ifndef OPENSSL_NO_EC +DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return 0, return) +#endif DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(int, EVP_PKEY_type, int a, a, return NID_undef, return) DEFINEFUNC2(int, i2d_X509, X509 *a, a, unsigned char **b, b, return -1, return) @@ -179,13 +189,25 @@ DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO #else DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return) DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return) +#ifndef OPENSSL_NO_EC +DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return) +#endif DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return) DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return) +#ifndef OPENSSL_NO_EC +DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return) +#endif #endif DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return) DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return) +#ifndef OPENSSL_NO_EC +DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return) +#endif DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return) DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return) +#ifndef OPENSSL_NO_EC +DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, return) +#endif DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG) DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return) DEFINEFUNC(RSA *, RSA_new, DUMMYARG, DUMMYARG, return 0, return) @@ -343,8 +365,14 @@ DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return 0, r #ifdef SSLEAY_MACROS DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return) DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return) +#ifndef OPENSSL_NO_EC +DEFINEFUNC2(int, i2d_ECPrivateKey, const EC_KEY *a, a, unsigned char **b, b, return -1, return) +#endif DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return) DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return) +#ifndef OPENSSL_NO_EC +DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return 0, return) +#endif #endif DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG) DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG) @@ -371,6 +399,7 @@ DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG) DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return 0, return) #ifndef OPENSSL_NO_EC +DEFINEFUNC(EC_KEY *, EC_KEY_dup, const EC_KEY *ec, ec, return 0, return) DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return 0, return) DEFINEFUNC(void, EC_KEY_free, EC_KEY *ecdh, ecdh, return, DUMMYARG) DEFINEFUNC2(size_t, EC_get_builtin_curves, EC_builtin_curve * r, r, size_t nitems, nitems, return 0, return) @@ -713,6 +742,10 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(BIO_read) RESOLVEFUNC(BIO_s_mem) RESOLVEFUNC(BIO_write) +#ifndef OPENSSL_NO_EC + RESOLVEFUNC(EC_KEY_get0_group) + RESOLVEFUNC(EC_GROUP_get_degree) +#endif RESOLVEFUNC(BN_num_bits) RESOLVEFUNC(CRYPTO_free) RESOLVEFUNC(CRYPTO_num_locks) @@ -727,9 +760,15 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(EVP_PKEY_assign) RESOLVEFUNC(EVP_PKEY_set1_RSA) RESOLVEFUNC(EVP_PKEY_set1_DSA) +#ifndef OPENSSL_NO_EC + RESOLVEFUNC(EVP_PKEY_set1_EC_KEY) +#endif RESOLVEFUNC(EVP_PKEY_free) RESOLVEFUNC(EVP_PKEY_get1_DSA) RESOLVEFUNC(EVP_PKEY_get1_RSA) +#ifndef OPENSSL_NO_EC + RESOLVEFUNC(EVP_PKEY_get1_EC_KEY) +#endif RESOLVEFUNC(EVP_PKEY_new) RESOLVEFUNC(EVP_PKEY_type) RESOLVEFUNC(OBJ_nid2sn) @@ -743,13 +782,25 @@ bool q_resolveOpenSslSymbols() #else RESOLVEFUNC(PEM_read_bio_DSAPrivateKey) RESOLVEFUNC(PEM_read_bio_RSAPrivateKey) +#ifndef OPENSSL_NO_EC + RESOLVEFUNC(PEM_read_bio_ECPrivateKey) +#endif RESOLVEFUNC(PEM_write_bio_DSAPrivateKey) RESOLVEFUNC(PEM_write_bio_RSAPrivateKey) +#ifndef OPENSSL_NO_EC + RESOLVEFUNC(PEM_write_bio_ECPrivateKey) +#endif #endif RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY) RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY) +#ifndef OPENSSL_NO_EC + RESOLVEFUNC(PEM_read_bio_EC_PUBKEY) +#endif RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY) RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY) +#ifndef OPENSSL_NO_EC + RESOLVEFUNC(PEM_write_bio_EC_PUBKEY) +#endif RESOLVEFUNC(RAND_seed) RESOLVEFUNC(RAND_status) RESOLVEFUNC(RSA_new) @@ -883,6 +934,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(DH_free) RESOLVEFUNC(BN_bin2bn) #ifndef OPENSSL_NO_EC + RESOLVEFUNC(EC_KEY_dup) RESOLVEFUNC(EC_KEY_new_by_curve_name) RESOLVEFUNC(EC_KEY_free) RESOLVEFUNC(EC_get_builtin_curves) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index ee19345e4a..04cfd83de5 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -221,6 +221,10 @@ int q_BIO_read(BIO *a, void *b, int c); BIO_METHOD *q_BIO_s_mem(); int q_BIO_write(BIO *a, const void *b, int c); int q_BN_num_bits(const BIGNUM *a); +#ifndef OPENSSL_NO_EC +const EC_GROUP* q_EC_KEY_get0_group(const EC_KEY* k); +int q_EC_GROUP_get_degree(const EC_GROUP* g); +#endif int q_CRYPTO_num_locks(); void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int)); void q_CRYPTO_set_id_callback(unsigned long (*a)()); @@ -240,9 +244,15 @@ const EVP_CIPHER *q_EVP_des_ede3_cbc(); int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c); Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b); int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); +#ifndef OPENSSL_NO_EC +int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b); +#endif void q_EVP_PKEY_free(EVP_PKEY *a); RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a); DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a); +#ifndef OPENSSL_NO_EC +EC_KEY *q_EVP_PKEY_get1_EC_KEY(EVP_PKEY *a); +#endif int q_EVP_PKEY_type(int a); Q_AUTOTEST_EXPORT EVP_PKEY *q_EVP_PKEY_new(); int q_i2d_X509(X509 *a, unsigned char **b); @@ -260,15 +270,28 @@ void *q_PEM_ASN1_read_bio(d2i_of_void *a, const char *b, BIO *c, void **d, pem_p #else DSA *q_PEM_read_bio_DSAPrivateKey(BIO *a, DSA **b, pem_password_cb *c, void *d); RSA *q_PEM_read_bio_RSAPrivateKey(BIO *a, RSA **b, pem_password_cb *c, void *d); +#ifndef OPENSSL_NO_EC +EC_KEY *q_PEM_read_bio_ECPrivateKey(BIO *a, EC_KEY **b, pem_password_cb *c, void *d); +#endif int q_PEM_write_bio_DSAPrivateKey(BIO *a, DSA *b, const EVP_CIPHER *c, unsigned char *d, int e, pem_password_cb *f, void *g); int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned char *d, int e, pem_password_cb *f, void *g); +#ifndef OPENSSL_NO_EC +int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d, + int e, pem_password_cb *f, void *g); +#endif #endif DSA *q_PEM_read_bio_DSA_PUBKEY(BIO *a, DSA **b, pem_password_cb *c, void *d); RSA *q_PEM_read_bio_RSA_PUBKEY(BIO *a, RSA **b, pem_password_cb *c, void *d); +#ifndef OPENSSL_NO_EC +EC_KEY *q_PEM_read_bio_EC_PUBKEY(BIO *a, EC_KEY **b, pem_password_cb *c, void *d); +#endif int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b); int q_PEM_write_bio_RSA_PUBKEY(BIO *a, RSA *b); +#ifndef OPENSSL_NO_EC +int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b); +#endif void q_RAND_seed(const void *a, int b); int q_RAND_status(); RSA *q_RSA_new(); @@ -433,6 +456,7 @@ BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); #ifndef OPENSSL_NO_EC // EC Diffie-Hellman support +EC_KEY *q_EC_KEY_dup(const EC_KEY *src); EC_KEY *q_EC_KEY_new_by_curve_name(int nid); void q_EC_KEY_free(EC_KEY *ecdh); #define q_SSL_CTX_set_tmp_ecdh(ctx, ecdh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_ECDH, 0, (char *)ecdh) -- cgit v1.2.3