Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F37954784
newopenpgpcertificatedetailsdialog.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
12 KB
Subscribers
None
newopenpgpcertificatedetailsdialog.cpp
View Options
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/newopenpgpcertificatedetailsdialog.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2022 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include
<config-kleopatra.h>
#include
"newopenpgpcertificatedetailsdialog.h"
#include
"nameandemailwidget.h"
#include
"newcertificatewizard/advancedsettingsdialog_p.h"
#include
"newcertificatewizard/keyalgo_p.h"
#include
"utils/keyparameters.h"
#include
"utils/keyusage.h"
#include
"utils/scrollarea.h"
#include
<settings.h>
#include
<Libkleo/Compat>
#include
<KConfigGroup>
#include
<KLocalizedString>
#include
<KMessageBox>
#include
<KSeparator>
#include
<KSharedConfig>
#include
<QCheckBox>
#include
<QDialogButtonBox>
#include
<QLabel>
#include
<QPushButton>
#include
<QVBoxLayout>
#include
<QGpgME/CryptoConfig>
#include
<QGpgME/Protocol>
#include
"kleopatra_debug.h"
using
namespace
Kleo
;
using
namespace
Kleo
::
NewCertificateUi
;
class
NewOpenPGPCertificateDetailsDialog
::
Private
{
friend
class
::
Kleo
::
NewOpenPGPCertificateDetailsDialog
;
NewOpenPGPCertificateDetailsDialog
*
const
q
;
struct
UI
{
QLabel
*
infoLabel
;
ScrollArea
*
scrollArea
;
NameAndEmailWidget
*
nameAndEmail
;
QCheckBox
*
withPassCheckBox
;
QPushButton
*
advancedButton
;
QDialogButtonBox
*
buttonBox
;
UI
(
QWidget
*
dialog
)
{
auto
mainLayout
=
new
QVBoxLayout
{
dialog
};
infoLabel
=
new
QLabel
{
dialog
};
infoLabel
->
setWordWrap
(
true
);
mainLayout
->
addWidget
(
infoLabel
);
mainLayout
->
addWidget
(
new
KSeparator
{
Qt
::
Horizontal
,
dialog
});
scrollArea
=
new
ScrollArea
{
dialog
};
scrollArea
->
setFocusPolicy
(
Qt
::
NoFocus
);
scrollArea
->
setFrameStyle
(
QFrame
::
NoFrame
);
scrollArea
->
setBackgroundRole
(
dialog
->
backgroundRole
());
scrollArea
->
setHorizontalScrollBarPolicy
(
Qt
::
ScrollBarAlwaysOff
);
scrollArea
->
setSizeAdjustPolicy
(
QScrollArea
::
AdjustToContents
);
auto
scrollAreaLayout
=
qobject_cast
<
QBoxLayout
*>
(
scrollArea
->
widget
()
->
layout
());
scrollAreaLayout
->
setContentsMargins
(
0
,
0
,
0
,
0
);
nameAndEmail
=
new
NameAndEmailWidget
{
dialog
};
nameAndEmail
->
layout
()
->
setContentsMargins
(
0
,
0
,
0
,
0
);
scrollAreaLayout
->
addWidget
(
nameAndEmail
);
withPassCheckBox
=
new
QCheckBox
{
i18n
(
"Protect the generated key with a passphrase."
),
dialog
};
withPassCheckBox
->
setToolTip
(
i18n
(
"Encrypts the secret key with an unrecoverable passphrase. You will be asked for the passphrase during key generation."
));
scrollAreaLayout
->
addWidget
(
withPassCheckBox
);
{
auto
layout
=
new
QHBoxLayout
;
advancedButton
=
new
QPushButton
{
i18n
(
"Advanced Settings..."
),
dialog
};
advancedButton
->
setAutoDefault
(
false
);
layout
->
addStretch
(
1
);
layout
->
addWidget
(
advancedButton
);
scrollAreaLayout
->
addLayout
(
layout
);
}
scrollAreaLayout
->
addStretch
(
1
);
mainLayout
->
addWidget
(
scrollArea
);
mainLayout
->
addWidget
(
new
KSeparator
{
Qt
::
Horizontal
,
dialog
});
buttonBox
=
new
QDialogButtonBox
{
QDialogButtonBox
::
Ok
|
QDialogButtonBox
::
Cancel
,
dialog
};
mainLayout
->
addWidget
(
buttonBox
);
}
}
ui
;
public
:
explicit
Private
(
NewOpenPGPCertificateDetailsDialog
*
qq
)
:
q
{
qq
}
,
ui
{
qq
}
,
advancedSettingsDlg
{
new
AdvancedSettingsDialog
{
qq
}}
,
technicalParameters
{
KeyParameters
::
OpenPGP
}
{
q
->
setWindowTitle
(
i18nc
(
"title:window"
,
"Create OpenPGP Certificate"
));
const
KConfigGroup
config
{
KSharedConfig
::
openConfig
(),
"CertificateCreationWizard"
};
const
auto
attrOrder
=
config
.
readEntry
(
"OpenPGPAttributeOrder"
,
QStringList
{});
const
auto
nameIsRequired
=
attrOrder
.
contains
(
QLatin1String
{
"NAME!"
},
Qt
::
CaseInsensitive
);
const
auto
emailIsRequired
=
attrOrder
.
contains
(
QLatin1String
{
"EMAIL!"
},
Qt
::
CaseInsensitive
);
ui
.
infoLabel
->
setText
(
nameIsRequired
||
emailIsRequired
//
?
i18n
(
"Enter a name and an email address to use for the certificate."
)
:
i18n
(
"Enter a name and/or an email address to use for the certificate."
));
ui
.
nameAndEmail
->
setNameIsRequired
(
nameIsRequired
);
ui
.
nameAndEmail
->
setNameLabel
(
config
.
readEntry
(
"NAME_label"
));
ui
.
nameAndEmail
->
setNameHint
(
config
.
readEntry
(
"NAME_hint"
,
config
.
readEntry
(
"NAME_placeholder"
)));
ui
.
nameAndEmail
->
setNamePattern
(
config
.
readEntry
(
"NAME_regex"
));
ui
.
nameAndEmail
->
setEmailIsRequired
(
emailIsRequired
);
ui
.
nameAndEmail
->
setEmailLabel
(
config
.
readEntry
(
"EMAIL_label"
));
ui
.
nameAndEmail
->
setEmailHint
(
config
.
readEntry
(
"EMAIL_hint"
,
config
.
readEntry
(
"EMAIL_placeholder"
)));
ui
.
nameAndEmail
->
setEmailPattern
(
config
.
readEntry
(
"EMAIL_regex"
));
Settings
settings
;
ui
.
advancedButton
->
setVisible
(
!
settings
.
hideAdvanced
());
const
auto
conf
=
QGpgME
::
cryptoConfig
();
const
auto
entry
=
getCryptoConfigEntry
(
conf
,
"gpg-agent"
,
"enforce-passphrase-constraints"
);
if
(
entry
&&
entry
->
boolValue
())
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"Disabling passphrase check box because of agent config."
;
ui
.
withPassCheckBox
->
setEnabled
(
false
);
ui
.
withPassCheckBox
->
setChecked
(
true
);
}
else
{
ui
.
withPassCheckBox
->
setChecked
(
config
.
readEntry
(
"WithPassphrase"
,
false
));
ui
.
withPassCheckBox
->
setEnabled
(
!
config
.
isEntryImmutable
(
"WithPassphrase"
));
}
advancedSettingsDlg
->
setProtocol
(
GpgME
::
OpenPGP
);
updateTechnicalParameters
();
// set key parameters to default values for OpenPGP
connect
(
advancedSettingsDlg
,
&
QDialog
::
accepted
,
q
,
[
this
]()
{
updateTechnicalParameters
();
});
connect
(
ui
.
advancedButton
,
&
QPushButton
::
clicked
,
q
,
[
this
]()
{
advancedSettingsDlg
->
open
();
});
connect
(
ui
.
buttonBox
,
&
QDialogButtonBox
::
accepted
,
q
,
[
this
]()
{
checkAccept
();
});
connect
(
ui
.
buttonBox
,
&
QDialogButtonBox
::
rejected
,
q
,
&
QDialog
::
reject
);
}
private
:
KeyUsage
keyUsage
()
const
{
KeyUsage
usage
;
if
(
advancedSettingsDlg
->
signingAllowed
())
{
usage
.
setCanSign
(
true
);
}
if
(
advancedSettingsDlg
->
encryptionAllowed
()
//
&&
!
is_ecdh
(
advancedSettingsDlg
->
subkeyType
())
&&
!
is_dsa
(
advancedSettingsDlg
->
keyType
())
&&
!
is_rsa
(
advancedSettingsDlg
->
subkeyType
()))
{
usage
.
setCanEncrypt
(
true
);
}
if
(
advancedSettingsDlg
->
authenticationAllowed
())
{
usage
.
setCanAuthenticate
(
true
);
}
if
(
advancedSettingsDlg
->
certificationAllowed
())
{
usage
.
setCanCertify
(
true
);
}
return
usage
;
}
KeyUsage
subkeyUsage
()
const
{
KeyUsage
usage
;
if
(
advancedSettingsDlg
->
encryptionAllowed
()
&&
(
is_dsa
(
advancedSettingsDlg
->
keyType
())
||
is_rsa
(
advancedSettingsDlg
->
subkeyType
())
||
is_ecdh
(
advancedSettingsDlg
->
subkeyType
())))
{
Q_ASSERT
(
advancedSettingsDlg
->
subkeyType
());
usage
.
setCanEncrypt
(
true
);
}
return
usage
;
}
void
updateTechnicalParameters
()
{
technicalParameters
=
KeyParameters
{
KeyParameters
::
OpenPGP
};
const
auto
keyType
=
advancedSettingsDlg
->
keyType
();
technicalParameters
.
setKeyType
(
keyType
);
if
(
is_ecdsa
(
keyType
)
||
is_eddsa
(
keyType
))
{
technicalParameters
.
setKeyCurve
(
advancedSettingsDlg
->
keyCurve
());
}
else
if
(
const
unsigned
int
strength
=
advancedSettingsDlg
->
keyStrength
())
{
technicalParameters
.
setKeyLength
(
strength
);
}
technicalParameters
.
setKeyUsage
(
keyUsage
());
const
auto
subkeyType
=
advancedSettingsDlg
->
subkeyType
();
if
(
subkeyType
)
{
technicalParameters
.
setSubkeyType
(
subkeyType
);
if
(
is_ecdh
(
subkeyType
))
{
technicalParameters
.
setSubkeyCurve
(
advancedSettingsDlg
->
subkeyCurve
());
}
else
if
(
const
unsigned
int
strength
=
advancedSettingsDlg
->
subkeyStrength
())
{
technicalParameters
.
setSubkeyLength
(
strength
);
}
technicalParameters
.
setSubkeyUsage
(
subkeyUsage
());
}
if
(
advancedSettingsDlg
->
expiryDate
().
isValid
())
{
technicalParameters
.
setExpirationDate
(
advancedSettingsDlg
->
expiryDate
());
}
// name and email are set later
}
void
setTechnicalParameters
(
const
KeyParameters
&
parameters
)
{
advancedSettingsDlg
->
setKeyType
(
parameters
.
keyType
());
advancedSettingsDlg
->
setKeyStrength
(
parameters
.
keyLength
());
advancedSettingsDlg
->
setKeyCurve
(
parameters
.
keyCurve
());
advancedSettingsDlg
->
setSubkeyType
(
parameters
.
subkeyType
());
advancedSettingsDlg
->
setSubkeyStrength
(
parameters
.
subkeyLength
());
advancedSettingsDlg
->
setSubkeyCurve
(
parameters
.
subkeyCurve
());
advancedSettingsDlg
->
setSigningAllowed
(
parameters
.
keyUsage
().
canSign
()
||
parameters
.
subkeyUsage
().
canSign
());
advancedSettingsDlg
->
setEncryptionAllowed
(
parameters
.
keyUsage
().
canEncrypt
()
||
parameters
.
subkeyUsage
().
canEncrypt
());
advancedSettingsDlg
->
setCertificationAllowed
(
parameters
.
keyUsage
().
canCertify
()
||
parameters
.
subkeyUsage
().
canCertify
());
advancedSettingsDlg
->
setAuthenticationAllowed
(
parameters
.
keyUsage
().
canAuthenticate
()
||
parameters
.
subkeyUsage
().
canAuthenticate
());
advancedSettingsDlg
->
setExpiryDate
(
parameters
.
expirationDate
());
}
void
checkAccept
()
{
QStringList
errors
;
if
(
ui
.
nameAndEmail
->
userID
().
isEmpty
()
&&
!
ui
.
nameAndEmail
->
nameIsRequired
()
&&
!
ui
.
nameAndEmail
->
emailIsRequired
())
{
errors
.
push_back
(
i18n
(
"Enter a name or an email address."
));
}
const
auto
nameError
=
ui
.
nameAndEmail
->
nameError
();
if
(
!
nameError
.
isEmpty
())
{
errors
.
push_back
(
nameError
);
}
const
auto
emailError
=
ui
.
nameAndEmail
->
emailError
();
if
(
!
emailError
.
isEmpty
())
{
errors
.
push_back
(
emailError
);
}
if
(
errors
.
size
()
>
1
)
{
KMessageBox
::
errorList
(
q
,
i18n
(
"There is a problem."
),
errors
);
}
else
if
(
!
errors
.
empty
())
{
KMessageBox
::
error
(
q
,
errors
.
first
());
}
else
{
q
->
accept
();
}
}
private
:
AdvancedSettingsDialog
*
const
advancedSettingsDlg
;
KeyParameters
technicalParameters
;
};
NewOpenPGPCertificateDetailsDialog
::
NewOpenPGPCertificateDetailsDialog
(
QWidget
*
parent
,
Qt
::
WindowFlags
f
)
:
QDialog
{
parent
,
f
}
,
d
(
new
Private
{
this
})
{
}
NewOpenPGPCertificateDetailsDialog
::~
NewOpenPGPCertificateDetailsDialog
()
=
default
;
void
NewOpenPGPCertificateDetailsDialog
::
setName
(
const
QString
&
name
)
{
d
->
ui
.
nameAndEmail
->
setName
(
name
);
}
QString
NewOpenPGPCertificateDetailsDialog
::
name
()
const
{
return
d
->
ui
.
nameAndEmail
->
name
();
}
void
NewOpenPGPCertificateDetailsDialog
::
setEmail
(
const
QString
&
email
)
{
d
->
ui
.
nameAndEmail
->
setEmail
(
email
);
}
QString
NewOpenPGPCertificateDetailsDialog
::
email
()
const
{
return
d
->
ui
.
nameAndEmail
->
email
();
}
void
Kleo
::
NewOpenPGPCertificateDetailsDialog
::
setKeyParameters
(
const
Kleo
::
KeyParameters
&
parameters
)
{
setName
(
parameters
.
name
());
const
auto
emails
=
parameters
.
emails
();
if
(
!
emails
.
empty
())
{
setEmail
(
emails
.
front
());
}
d
->
setTechnicalParameters
(
parameters
);
}
KeyParameters
NewOpenPGPCertificateDetailsDialog
::
keyParameters
()
const
{
// set name and email on a copy of the technical parameters
auto
parameters
=
d
->
technicalParameters
;
if
(
!
name
().
isEmpty
())
{
parameters
.
setName
(
name
());
}
if
(
!
email
().
isEmpty
())
{
parameters
.
setEmail
(
email
());
}
return
parameters
;
}
void
Kleo
::
NewOpenPGPCertificateDetailsDialog
::
setProtectKeyWithPassword
(
bool
protectKey
)
{
d
->
ui
.
withPassCheckBox
->
setChecked
(
protectKey
);
}
bool
NewOpenPGPCertificateDetailsDialog
::
protectKeyWithPassword
()
const
{
return
d
->
ui
.
withPassCheckBox
->
isChecked
();
}
#include
"moc_newopenpgpcertificatedetailsdialog.cpp"
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Thu, Mar 19, 6:03 PM (18 h, 51 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
e5/6e/6ff7119f42d0a28e4d28e9e0d479
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment