Files
qt-creator/src/plugins/android/androidcreatekeystorecertificate.cpp

274 lines
10 KiB
C++
Raw Normal View History

/****************************************************************************
**
** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "androidcreatekeystorecertificate.h"
#include "androidconfigurations.h"
#include "ui_androidcreatekeystorecertificate.h"
#include <utils/qtcprocess.h>
#include <QFileDialog>
#include <QRegularExpression>
#include <QMessageBox>
using namespace Utils;
using namespace Android::Internal;
AndroidCreateKeystoreCertificate::AndroidCreateKeystoreCertificate(QWidget *parent) :
QDialog(parent),
ui(new Ui::AndroidCreateKeystoreCertificate)
{
ui->setupUi(this);
ui->infoLabel->setType(InfoLabel::Error);
ui->infoLabel->hide();
connect(ui->keystorePassLineEdit, &QLineEdit::textChanged,
this, &AndroidCreateKeystoreCertificate::checkKeystorePassword);
connect(ui->keystoreRetypePassLineEdit, &QLineEdit::textChanged,
this, &AndroidCreateKeystoreCertificate::checkKeystorePassword);
connect(ui->certificatePassLineEdit, &QLineEdit::textChanged,
this, &AndroidCreateKeystoreCertificate::checkCertificatePassword);
connect(ui->certificateRetypePassLineEdit, &QLineEdit::textChanged,
this, &AndroidCreateKeystoreCertificate::checkCertificatePassword);
connect(ui->certificateAliasLineEdit, &QLineEdit::textChanged,
this, &AndroidCreateKeystoreCertificate::checkCertificateAlias);
connect(ui->countryLineEdit, &QLineEdit::textChanged,
this, &AndroidCreateKeystoreCertificate::checkCountryCode);
connect(ui->keystoreShowPassCheckBox, &QCheckBox::stateChanged,
this, &AndroidCreateKeystoreCertificate::keystoreShowPassStateChanged);
connect(ui->certificateShowPassCheckBox, &QCheckBox::stateChanged,
this, &AndroidCreateKeystoreCertificate::certificateShowPassStateChanged);
connect(ui->samePasswordCheckBox, &QCheckBox::stateChanged,
this, &AndroidCreateKeystoreCertificate::samePasswordStateChanged);
connect(ui->buttonBox, &QDialogButtonBox::accepted,
this, &AndroidCreateKeystoreCertificate::buttonBoxAccepted);
connect(ui->buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject);
connect(ui->keystorePassLineEdit,
&QLineEdit::editingFinished,
ui->keystoreRetypePassLineEdit,
QOverload<>::of(&QLineEdit::setFocus));
}
AndroidCreateKeystoreCertificate::~AndroidCreateKeystoreCertificate()
{
delete ui;
}
Utils::FilePath AndroidCreateKeystoreCertificate::keystoreFilePath()
{
return m_keystoreFilePath;
}
QString AndroidCreateKeystoreCertificate::keystorePassword()
{
return ui->keystorePassLineEdit->text();
}
QString AndroidCreateKeystoreCertificate::certificateAlias()
{
return ui->certificateAliasLineEdit->text();
}
QString AndroidCreateKeystoreCertificate::certificatePassword()
{
return (ui->samePasswordCheckBox->checkState() == Qt::Checked)
? keystorePassword()
: ui->certificatePassLineEdit->text();
}
AndroidCreateKeystoreCertificate::PasswordStatus AndroidCreateKeystoreCertificate::checkKeystorePassword()
{
if (ui->keystorePassLineEdit->text().length() < 6) {
ui->infoLabel->show();
ui->infoLabel->setText(tr("Keystore password is too short."));
return Invalid;
}
if (ui->keystorePassLineEdit->text() != ui->keystoreRetypePassLineEdit->text()) {
ui->infoLabel->show();
ui->infoLabel->setText(tr("Keystore passwords do not match."));
return NoMatch;
}
ui->infoLabel->hide();
return Match;
}
AndroidCreateKeystoreCertificate::PasswordStatus AndroidCreateKeystoreCertificate::checkCertificatePassword()
{
if (ui->samePasswordCheckBox->checkState() == Qt::Checked)
return Match;
if (ui->certificatePassLineEdit->text().length() < 6) {
ui->infoLabel->show();
ui->infoLabel->setText(tr("Certificate password is too short."));
return Invalid;
}
if (ui->certificatePassLineEdit->text() != ui->certificateRetypePassLineEdit->text()) {
ui->infoLabel->show();
ui->infoLabel->setText(tr("Certificate passwords do not match."));
return NoMatch;
}
ui->infoLabel->hide();
return Match;
}
bool AndroidCreateKeystoreCertificate::checkCertificateAlias()
{
if (ui->certificateAliasLineEdit->text().length() == 0) {
ui->infoLabel->show();
ui->infoLabel->setText(tr("Certificate alias is missing."));
return false;
}
ui->infoLabel->hide();
return true;
}
bool AndroidCreateKeystoreCertificate::checkCountryCode()
{
if (!ui->countryLineEdit->text().contains(QRegularExpression("[A-Z]{2}"))) {
ui->infoLabel->show();
ui->infoLabel->setText(tr("Invalid country code."));
return false;
}
ui->infoLabel->hide();
return true;
}
void AndroidCreateKeystoreCertificate::keystoreShowPassStateChanged(int state)
{
ui->keystorePassLineEdit->setEchoMode(state == Qt::Checked ? QLineEdit::Normal : QLineEdit::Password);
ui->keystoreRetypePassLineEdit->setEchoMode(ui->keystorePassLineEdit->echoMode());
}
void AndroidCreateKeystoreCertificate::certificateShowPassStateChanged(int state)
{
ui->certificatePassLineEdit->setEchoMode(state == Qt::Checked ? QLineEdit::Normal : QLineEdit::Password);
ui->certificateRetypePassLineEdit->setEchoMode(ui->certificatePassLineEdit->echoMode());
}
void AndroidCreateKeystoreCertificate::buttonBoxAccepted()
{
if (!validateUserInput())
return;
m_keystoreFilePath = FileUtils::getSaveFilePath(this, tr("Keystore Filename"),
FileUtils::homePath() / "android_release.keystore",
tr("Keystore files (*.keystore *.jks)"));
if (m_keystoreFilePath.isEmpty())
return;
QString distinguishedNames(QString::fromLatin1("CN=%1, O=%2, L=%3, C=%4")
.arg(ui->commonNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,")))
.arg(ui->organizationNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,")))
.arg(ui->localityNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,")))
.arg(ui->countryLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,"))));
if (!ui->organizationUnitLineEdit->text().isEmpty())
distinguishedNames += QLatin1String(", OU=") + ui->organizationUnitLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,"));
if (!ui->stateNameLineEdit->text().isEmpty())
distinguishedNames += QLatin1String(", S=") + ui->stateNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,"));
const CommandLine command(AndroidConfigurations::currentConfig().keytoolPath(),
{ "-genkey", "-keyalg", "RSA",
"-keystore", m_keystoreFilePath.toString(),
"-storepass", keystorePassword(),
"-alias", certificateAlias(),
"-keysize", ui->keySizeSpinBox->text(),
"-validity", ui->validitySpinBox->text(),
"-keypass", certificatePassword(),
"-dname", distinguishedNames});
QtcProcess genKeyCertProc;
genKeyCertProc.setTimeoutS(15);
genKeyCertProc.setCommand(command);
genKeyCertProc.runBlocking(EventLoopMode::On);
if (genKeyCertProc.result() != ProcessResult::FinishedWithSuccess) {
QMessageBox::critical(this, tr("Error"),
genKeyCertProc.exitMessage() + '\n' + genKeyCertProc.allOutput());
return;
}
accept();
}
void AndroidCreateKeystoreCertificate::samePasswordStateChanged(int state)
{
if (state == Qt::Checked) {
ui->certificatePassLineEdit->setDisabled(true);
ui->certificateRetypePassLineEdit->setDisabled(true);
ui->certificateShowPassCheckBox->setDisabled(true);
}
if (state == Qt::Unchecked) {
ui->certificatePassLineEdit->setEnabled(true);
ui->certificateRetypePassLineEdit->setEnabled(true);
ui->certificateShowPassCheckBox->setEnabled(true);
}
validateUserInput();
}
bool AndroidCreateKeystoreCertificate::validateUserInput()
{
switch (checkKeystorePassword()) {
case Invalid:
ui->keystorePassLineEdit->setFocus();
return false;
case NoMatch:
ui->keystoreRetypePassLineEdit->setFocus();
return false;
default:
break;
}
if (!checkCertificateAlias()) {
ui->certificateAliasLineEdit->setFocus();
return false;
}
switch (checkCertificatePassword()) {
case Invalid:
ui->certificatePassLineEdit->setFocus();
return false;
case NoMatch:
ui->certificateRetypePassLineEdit->setFocus();
return false;
default:
break;
}
if (!checkCountryCode()) {
ui->countryLineEdit->setFocus();
return false;
}
return true;
}