File indexing completed on 2024-04-28 04:43:51

0001 /*
0002  * Copyright (C) 2008  Michael Leupold <lemma@confuego.org>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Lesser General Public License for more details.
0013  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
0014  *
0015  */
0016 
0017 #include <QtCrypto>
0018 #include <QtPlugin>
0019 
0020 #include <qstringlist.h>
0021 
0022 #ifdef Q_OS_WIN32
0023 
0024 #include <wincrypt.h>
0025 
0026 //-----------------------------------------------------------
0027 class WinCryptoRandomContext : public QCA::RandomContext
0028 {
0029 public:
0030     WinCryptoRandomContext(QCA::Provider *p)
0031         : RandomContext(p)
0032     {
0033     }
0034 
0035     Context *clone() const
0036     {
0037         return new WinCryptoRandomContext(*this);
0038     }
0039 
0040     QCA::SecureArray nextBytes(int size)
0041     {
0042         QCA::SecureArray buf(size);
0043         HCRYPTPROV       hProv;
0044 
0045         /* FIXME: currently loop while there's an error. */
0046         while (true) {
0047             // acquire the crypto context
0048             if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
0049                 continue;
0050 
0051             if (CryptGenRandom(hProv, static_cast<DWORD>(size), (BYTE *)buf.data())) {
0052                 break;
0053             }
0054         }
0055 
0056         // release the crypto context
0057         CryptReleaseContext(hProv, 0);
0058 
0059         return buf;
0060     }
0061 };
0062 
0063 //-----------------------------------------------------------
0064 class WinCryptoProvider : public QCA::Provider
0065 {
0066 public:
0067     void init()
0068     {
0069     }
0070 
0071     ~WinCryptoProvider()
0072     {
0073     }
0074 
0075     int qcaVersion() const
0076     {
0077         return QCA_VERSION;
0078     }
0079 
0080     QString name() const
0081     {
0082         return "qca-wincrypto";
0083     }
0084 
0085     QStringList features() const
0086     {
0087         QStringList list;
0088         list += "random";
0089         return list;
0090     }
0091 
0092     Context *createContext(const QString &type)
0093     {
0094         if (type == "random")
0095             return new WinCryptoRandomContext(this);
0096         else
0097             return 0;
0098     }
0099 };
0100 
0101 //-----------------------------------------------------------
0102 class WinCryptoPlugin : public QObject, public QCAPlugin
0103 {
0104     Q_OBJECT
0105     Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0")
0106     Q_INTERFACES(QCAPlugin)
0107 
0108 public:
0109     virtual QCA::Provider *createProvider()
0110     {
0111         return new WinCryptoProvider;
0112     }
0113 };
0114 
0115 Q_EXPORT_PLUGIN2(qca_wincrypto, WinCryptoPlugin);
0116 
0117 #endif // Q_OS_WIN32