#ifndef SSLKEYGEN_H #define SSLKEYGEN_H #include <QtGui/QDialog> #include <QSslKey> #include <QMap> #include <QSslCertificate> #include <QWizard> #include <QWizardPage> #include <QProgressBar> #include <QDir> #include <QFileDialog> #include <QFileInfo> #include <QFile> #include <QLabel> bool isPrivateKeyCorrespondsToCertificate(QSslCertificate cert, QSslKey key); class CertificateGeneratorWizard : public QWizard { Q_OBJECT public: CertificateGeneratorWizard(QWidget * parent=0); QSslKey getPrivateKey(){return pkey;} QSslCertificate getCertificate(){return cert;} void accept(); private: QSslKey pkey; QSslCertificate cert; }; class RandSeeder : public QObject { Q_OBJECT public: void startSeeding(QList<QWidget *> w, int lim); void stop(); bool isCompleted() const{return (counter>=maximum);} protected: QMap<QWidget *, bool> wdgs; int counter; int maximum; bool eventFilter(QObject *obj, QEvent *event); signals: void step(); void stopped(); }; class getCertDataPage : public QWizardPage { Q_OBJECT public: getCertDataPage(QWidget *parent=0); }; class randomizePage : public QWizardPage { Q_OBJECT public: randomizePage(QWidget *parent=0); virtual void cleanupPage(); virtual void initializePage(); virtual bool isComplete() const; private: QProgressBar * progressBar; QLabel * label; RandSeeder seeder; private slots: void seedStep(); void seedStopped(); }; #endif // SSLKEYGEN_H
bool isPrivateKeyCorrespondsToCertificate( QSslCertificate cert, QSslKey key ) { X509 *x; EVP_PKEY *k; x=(X509 *)cert.handle(); k=EVP_PKEY_new(); if(key.algorithm() == QSsl::Rsa) EVP_PKEY_assign_RSA(k, (RSA *)key.handle()); else EVP_PKEY_assign_DSA(k, (DSA *)key.handle()); if(X509_check_private_key(x,k)==1) return true; return false; }
QByteArray QByteArray_from_X509(X509 *x509) { if (!x509) return QByteArray(); // Use i2d_X509 to convert the X509 to an array. int length = i2d_X509(x509, 0); QByteArray array; array.resize(length); char *data = array.data(); char **dataP = &data; unsigned char **dataPu = (unsigned char **)dataP; if (i2d_X509(x509, dataPu) < 0) return QByteArray(); // Convert to Base64 - wrap at 64 characters. array = array.toBase64(); QByteArray tmp; for (int i = 0; i < array.size() - 64; i += 64) { tmp += QByteArray::fromRawData(array.data() + i, 64); tmp += "\n"; } if (int remainder = array.size() % 64) { tmp += QByteArray::fromRawData(array.data() + array.size() - remainder, remainder); tmp += "\n"; } return "-----BEGIN CERTIFICATE-----\n" + tmp + "-----END CERTIFICATE-----\n"; }
getCertDataPage::getCertDataPage( QWidget *parent ) : QWizardPage(parent) { setTitle(" "); QVBoxLayout * verticalLayout = new QVBoxLayout(); QLabel * label = new QLabel(tr(" . .")); label->setWordWrap(true); verticalLayout->addWidget(label); QHBoxLayout * horizontalLayout = new QHBoxLayout(); label = new QLabel(tr("&:")); label->setMinimumSize(QSize(80, 0)); horizontalLayout->addWidget(label); QLineEdit * lineEdit = new QLineEdit(); horizontalLayout->addWidget(lineEdit); label->setBuddy(lineEdit); verticalLayout->addLayout(horizontalLayout); registerField("certSubject*",lineEdit); horizontalLayout = new QHBoxLayout(); label = new QLabel(tr("&:")); label->setMinimumSize(QSize(80, 0)); horizontalLayout->addWidget(label); lineEdit = new QLineEdit(); horizontalLayout->addWidget(lineEdit); label->setBuddy(lineEdit); verticalLayout->addLayout(horizontalLayout); registerField("certOrganization*",lineEdit); horizontalLayout = new QHBoxLayout(); label = new QLabel(tr("&E-Mail:")); label->setMinimumSize(QSize(80, 0)); horizontalLayout->addWidget(label); lineEdit = new QLineEdit(); horizontalLayout->addWidget(lineEdit); label->setBuddy(lineEdit); verticalLayout->addLayout(horizontalLayout); registerField("certEMail*",lineEdit); setLayout(verticalLayout); }
bool RandSeeder::eventFilter( QObject *obj, QEvent *event ) { if(event->type() == QEvent::MouseMove) { uint addition=QDateTime::currentDateTime().toTime_t(); QMouseEvent *mEvent = static_cast<QMouseEvent *>(event); addition*=mEvent->globalX(); addition*=mEvent->globalY(); RAND_seed(&addition,sizeof(uint)); counter++; emit step(); if(counter>maximum) stop(); return true; } else return QObject::eventFilter(obj, event); } void RandSeeder::startSeeding( QList<QWidget *> w, int lim ) { counter=0; if(lim<512) lim=512; maximum=lim; int i; for(i=0;i<w.count();i++) { wdgs.insert(w.at(i),w.at(i)->hasMouseTracking()); w.at(i)->installEventFilter(this); w.at(i)->setMouseTracking(true); } } void RandSeeder::stop() { QList<QWidget *> w=wdgs.keys(); int i; bool mt; for(i=0;i<w.count();i++) { mt=wdgs.value(w.at(i)); wdgs.remove(w.at(i)); w.at(i)->setMouseTracking(mt); w.at(i)->removeEventFilter(this); } emit stopped(); }
randomizePage::randomizePage( QWidget *parent ) : QWizardPage(parent) { setTitle(" "); setFinalPage(true); QVBoxLayout * verticalLayout = new QVBoxLayout(); label = new QLabel(tr(" .")); label->setWordWrap(true); verticalLayout->addWidget(label); progressBar = new QProgressBar(); progressBar->setMaximum(1024); progressBar->setValue(0); verticalLayout->addWidget(progressBar); setLayout(verticalLayout); connect(&seeder, SIGNAL(step()), this, SLOT(seedStep())); connect(&seeder, SIGNAL(stopped()), this, SLOT(seedStopped())); } void randomizePage::seedStep() { progressBar->setValue(progressBar->value()+1); } void randomizePage::cleanupPage() { seeder.stop(); progressBar->setValue(0); } void randomizePage::initializePage() { progressBar->setValue(0); progressBar->setMaximum(1024); QList<QWidget *> wlst, chwdg; wlst << this << wizard() << progressBar << label; int i; chwdg=wizard()->findChildren<QWidget *>(); for(i=0;i<chwdg.count();i++) { if(!wlst.contains(chwdg.at(i))) wlst.append(chwdg.at(i)); } seeder.startSeeding(wlst ,1024); } void randomizePage::seedStopped() { if(seeder.isCompleted()) emit completeChanged(); } bool randomizePage::isComplete() const { if(seeder.isCompleted()) return true; return false; }
CertificateGeneratorWizard::CertificateGeneratorWizard(QWidget * parent) : QWizard(parent) { setOption(QWizard::NoCancelButton, false); setOption(QWizard::NoDefaultButton, false); setOption(QWizard::CancelButtonOnLeft, true); addPage(new getCertDataPage); addPage(new randomizePage); setWindowTitle(tr(" ")); }
void CertificateGeneratorWizard::accept() { EVP_PKEY *pk; RSA *rsa; X509 *x; X509_NAME *name=NULL; bool ok; //parameters int bits=4096; long serial=57; long days=1895; setCursor(Qt::WaitCursor); //create private key pk=EVP_PKEY_new(); rsa=RSA_generate_key(bits,RSA_F4,NULL,NULL); EVP_PKEY_assign_RSA(pk,rsa); { //save it to QSslKey BIO *bio = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(bio, rsa, (const EVP_CIPHER *)0, NULL, 0, 0, 0); QByteArray pem; char *data; long size = BIO_get_mem_data(bio, &data); pem = QByteArray(data, size); BIO_free(bio); pkey=QSslKey(pem,QSsl::Rsa); ok=!pkey.isNull(); } x=X509_new(); X509_set_version(x,2); ASN1_INTEGER_set(X509_get_serialNumber(x),serial); X509_gmtime_adj(X509_get_notBefore(x),(long)60*60*24*(-2)); X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days); X509_set_pubkey(x,pk); name=X509_get_subject_name(x); QVariant fldVal=field("certSubject"); X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, fldVal.toString().toLatin1().constData(), -1, -1, 0); fldVal=field("certOrganization"); if(!fldVal.isNull()) X509_NAME_add_entry_by_txt(name,"O", MBSTRING_ASC, fldVal.toString().toLatin1().constData(), -1, -1, 0); fldVal=field("certEMail"); if(!fldVal.isNull()) { X509_NAME_add_entry_by_txt(name,"emailAddress", MBSTRING_ASC, fldVal.toString().toLatin1().constData(), -1, -1, 0); } X509_set_issuer_name(x,name); X509_sign(x,pk,EVP_md5()); { QByteArray crt=QByteArray_from_X509(x); cert=QSslCertificate(crt); ok=cert.isValid(); } ok=isPrivateKeyCorrespondsToCertificate(cert,pkey); QWizard::accept(); }
Source: https://habr.com/ru/post/104036/
All Articles