Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
PIM
Kleopatra
Commits
42f5173f
Commit
42f5173f
authored
Aug 27, 2020
by
Ingo Klöcker
Browse files
Allow users to change the administration key of a PIV card
GnuPG-bug-id: 4794
parent
662d68fa
Pipeline
#32025
passed with stage
in 12 minutes and 36 seconds
Changes
7
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/CMakeLists.txt
View file @
42f5173f
...
...
@@ -231,6 +231,7 @@ set(_kleopatra_SRCS
commands/pivgeneratecardkeycommand.cpp
commands/changepincommand.cpp
commands/authenticatepivcardapplicationcommand.cpp
commands/setpivcardapplicationadministrationkeycommand.cpp
${
_kleopatra_uiserver_files
}
...
...
src/commands/authenticatepivcardapplicationcommand.cpp
View file @
42f5173f
...
...
@@ -51,6 +51,7 @@ private:
void
ensureDialogCreated
();
private:
QString
prompt
;
QPointer
<
PIVCardApplicationAdministrationKeyInputDialog
>
dialog
;
};
...
...
@@ -92,6 +93,11 @@ AuthenticatePIVCardApplicationCommand::~AuthenticatePIVCardApplicationCommand()
qCDebug
(
KLEOPATRA_LOG
)
<<
"AuthenticatePIVCardApplicationCommand::~AuthenticatePIVCardApplicationCommand()"
;
}
void
AuthenticatePIVCardApplicationCommand
::
setPrompt
(
const
QString
&
prompt
)
{
d
->
prompt
=
prompt
;
}
void
AuthenticatePIVCardApplicationCommand
::
doStart
()
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"AuthenticatePIVCardApplicationCommand::doStart()"
;
...
...
@@ -143,7 +149,9 @@ void AuthenticatePIVCardApplicationCommand::Private::ensureDialogCreated()
dialog
=
new
PIVCardApplicationAdministrationKeyInputDialog
(
parentWidget
());
dialog
->
setAttribute
(
Qt
::
WA_DeleteOnClose
);
dialog
->
setLabelText
(
i18n
(
"Please enter the PIV Card Application Administration Key in hex-encoded form."
));
dialog
->
setLabelText
(
prompt
.
isEmpty
()
?
i18n
(
"Please enter the PIV Card Application Administration Key in hex-encoded form."
)
:
prompt
);
connect
(
dialog
,
SIGNAL
(
accepted
()),
q
,
SLOT
(
slotDialogAccepted
()));
connect
(
dialog
,
SIGNAL
(
rejected
()),
q
,
SLOT
(
slotDialogRejected
()));
...
...
src/commands/authenticatepivcardapplicationcommand.h
View file @
42f5173f
...
...
@@ -28,6 +28,8 @@ public:
explicit
AuthenticatePIVCardApplicationCommand
(
const
std
::
string
&
serialNumber
,
QWidget
*
parent
);
~
AuthenticatePIVCardApplicationCommand
()
override
;
void
setPrompt
(
const
QString
&
prompt
);
private:
void
doStart
()
override
;
...
...
src/commands/setpivcardapplicationadministrationkeycommand.cpp
0 → 100644
View file @
42f5173f
/* commands/setpivcardapplicationadministrationkeycommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "setpivcardapplicationadministrationkeycommand.h"
#include "cardcommand_p.h"
#include "smartcard/readerstatus.h"
#include "commands/authenticatepivcardapplicationcommand.h"
#include "dialogs/pivcardapplicationadministrationkeyinputdialog.h"
#include <KLocalizedString>
#include <gpgme++/error.h>
#include "kleopatra_debug.h"
using
namespace
Kleo
;
using
namespace
Kleo
::
Commands
;
using
namespace
Kleo
::
Dialogs
;
using
namespace
Kleo
::
SmartCard
;
using
namespace
GpgME
;
class
SetPIVCardApplicationAdministrationKeyCommand
::
Private
:
public
CardCommand
::
Private
{
friend
class
::
Kleo
::
Commands
::
SetPIVCardApplicationAdministrationKeyCommand
;
SetPIVCardApplicationAdministrationKeyCommand
*
q_func
()
const
{
return
static_cast
<
SetPIVCardApplicationAdministrationKeyCommand
*>
(
q
);
}
public:
explicit
Private
(
SetPIVCardApplicationAdministrationKeyCommand
*
qq
,
const
std
::
string
&
serialNumber
,
QWidget
*
p
);
~
Private
();
void
init
();
private:
void
slotDialogAccepted
();
void
slotDialogRejected
();
void
slotResult
(
const
Error
&
err
);
private:
void
authenticate
();
void
authenticationFinished
();
void
authenticationCanceled
();
void
setAdminKey
();
void
ensureDialogCreated
();
private:
QByteArray
newAdminKey
;
QPointer
<
PIVCardApplicationAdministrationKeyInputDialog
>
dialog
;
bool
hasBeenCanceled
=
false
;
};
SetPIVCardApplicationAdministrationKeyCommand
::
Private
*
SetPIVCardApplicationAdministrationKeyCommand
::
d_func
()
{
return
static_cast
<
Private
*>
(
d
.
get
());
}
const
SetPIVCardApplicationAdministrationKeyCommand
::
Private
*
SetPIVCardApplicationAdministrationKeyCommand
::
d_func
()
const
{
return
static_cast
<
const
Private
*>
(
d
.
get
());
}
#define d d_func()
#define q q_func()
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
Private
(
SetPIVCardApplicationAdministrationKeyCommand
*
qq
,
const
std
::
string
&
serialNumber
,
QWidget
*
p
)
:
CardCommand
::
Private
(
qq
,
serialNumber
,
p
)
,
dialog
()
{
}
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::~
Private
()
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"SetPIVCardApplicationAdministrationKeyCommand::Private::~Private()"
;
}
SetPIVCardApplicationAdministrationKeyCommand
::
SetPIVCardApplicationAdministrationKeyCommand
(
const
std
::
string
&
serialNumber
,
QWidget
*
p
)
:
CardCommand
(
new
Private
(
this
,
serialNumber
,
p
))
{
d
->
init
();
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
init
()
{
}
SetPIVCardApplicationAdministrationKeyCommand
::~
SetPIVCardApplicationAdministrationKeyCommand
()
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"SetPIVCardApplicationAdministrationKeyCommand::~SetPIVCardApplicationAdministrationKeyCommand()"
;
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
doStart
()
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"SetPIVCardApplicationAdministrationKeyCommand::doStart()"
;
d
->
authenticate
();
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
authenticate
()
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"SetPIVCardApplicationAdministrationKeyCommand::authenticate()"
;
auto
cmd
=
new
AuthenticatePIVCardApplicationCommand
(
serialNumber
(),
parentWidget
());
cmd
->
setPrompt
(
i18n
(
"Please enter the old PIV Card Application Administration Key in hex-encoded form."
));
connect
(
cmd
,
&
AuthenticatePIVCardApplicationCommand
::
finished
,
q
,
[
this
]()
{
authenticationFinished
();
});
connect
(
cmd
,
&
AuthenticatePIVCardApplicationCommand
::
canceled
,
q
,
[
this
]()
{
authenticationCanceled
();
});
cmd
->
start
();
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
authenticationFinished
()
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"SetPIVCardApplicationAdministrationKeyCommand::authenticationFinished()"
;
if
(
!
hasBeenCanceled
)
{
setAdminKey
();
}
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
authenticationCanceled
()
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"SetPIVCardApplicationAdministrationKeyCommand::authenticationCanceled()"
;
hasBeenCanceled
=
true
;
canceled
();
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
setAdminKey
()
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"SetPIVCardApplicationAdministrationKeyCommand::setAdminKey()"
;
ensureDialogCreated
();
Q_ASSERT
(
dialog
);
dialog
->
show
();
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
ensureDialogCreated
()
{
if
(
dialog
)
{
return
;
}
dialog
=
new
PIVCardApplicationAdministrationKeyInputDialog
(
parentWidget
());
dialog
->
setAttribute
(
Qt
::
WA_DeleteOnClose
);
dialog
->
setLabelText
(
newAdminKey
.
isEmpty
()
?
i18n
(
"Please enter the new PIV Card Application Administration Key in hex-encoded form. "
"The key needs to consist of 24 bytes, i.e. 48 hex-characters."
)
:
i18n
(
"Please enter the new PIV Card Application Administration Key again."
));
connect
(
dialog
,
SIGNAL
(
accepted
()),
q
,
SLOT
(
slotDialogAccepted
()));
connect
(
dialog
,
SIGNAL
(
rejected
()),
q
,
SLOT
(
slotDialogRejected
()));
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
slotDialogAccepted
()
{
if
(
newAdminKey
.
isEmpty
())
{
newAdminKey
=
dialog
->
adminKey
();
dialog
=
nullptr
;
setAdminKey
();
return
;
}
const
QByteArray
newAdminKey2
=
dialog
->
adminKey
();
if
(
newAdminKey
!=
newAdminKey2
)
{
error
(
i18nc
(
"@info"
,
"The two keys you have entered do not match. Please retry."
),
i18nc
(
"@title"
,
"Error"
));
newAdminKey
.
clear
();
dialog
=
nullptr
;
setAdminKey
();
return
;
}
const
QByteArray
plusPercentEncodedAdminKey
=
newAdminKey
.
toPercentEncoding
().
replace
(
' '
,
'+'
);
const
QByteArray
command
=
QByteArray
(
"SCD SETATTR SET-ADM-KEY "
)
+
plusPercentEncodedAdminKey
;
ReaderStatus
::
mutableInstance
()
->
startSimpleTransaction
(
command
,
q
,
"slotResult"
);
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
slotDialogRejected
()
{
finished
();
}
void
SetPIVCardApplicationAdministrationKeyCommand
::
Private
::
slotResult
(
const
GpgME
::
Error
&
err
)
{
qCDebug
(
KLEOPATRA_LOG
)
<<
"SetPIVCardApplicationAdministrationKeyCommand::slotResult():"
<<
err
.
asString
()
<<
"("
<<
err
.
code
()
<<
")"
;
if
(
err
)
{
error
(
i18nc
(
"@info"
,
"Setting the PIV Card Application Administration Key failed: %1"
,
QString
::
fromLatin1
(
err
.
asString
())),
i18nc
(
"@title"
,
"Error"
));
}
else
if
(
!
err
.
isCanceled
())
{
information
(
i18nc
(
"@info"
,
"PIV Card Application Administration Key set successfully."
),
i18nc
(
"@title"
,
"Success"
));
ReaderStatus
::
mutableInstance
()
->
updateStatus
();
}
finished
();
}
#undef d
#undef q
#include "moc_setpivcardapplicationadministrationkeycommand.cpp"
src/commands/setpivcardapplicationadministrationkeycommand.h
0 → 100644
View file @
42f5173f
/* commands/setpivcardapplicationadministrationkeycommand.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef __KLEOPATRA_COMMMANDS_SETPIVCARDAPPLICATIONADMINISTRATIONKEYCOMMAND_H__
#define __KLEOPATRA_COMMMANDS_SETPIVCARDAPPLICATIONADMINISTRATIONKEYCOMMAND_H__
#include "cardcommand.h"
namespace
GpgME
{
class
Error
;
}
namespace
Kleo
{
namespace
Commands
{
class
SetPIVCardApplicationAdministrationKeyCommand
:
public
CardCommand
{
Q_OBJECT
public:
explicit
SetPIVCardApplicationAdministrationKeyCommand
(
const
std
::
string
&
serialNumber
,
QWidget
*
parent
);
~
SetPIVCardApplicationAdministrationKeyCommand
()
override
;
private:
void
doStart
()
override
;
private:
class
Private
;
inline
Private
*
d_func
();
inline
const
Private
*
d_func
()
const
;
Q_PRIVATE_SLOT
(
d_func
(),
void
slotDialogAccepted
())
Q_PRIVATE_SLOT
(
d_func
(),
void
slotDialogRejected
())
Q_PRIVATE_SLOT
(
d_func
(),
void
slotResult
(
GpgME
::
Error
))
};
}
// namespace Commands
}
// namespace Kleo
#endif // __KLEOPATRA_COMMMANDS_SETPIVCARDAPPLICATIONADMINISTRATIONKEYCOMMAND_H__
src/view/pivcardwidget.cpp
View file @
42f5173f
...
...
@@ -11,6 +11,7 @@
#include "commands/changepincommand.h"
#include "commands/pivgeneratecardkeycommand.h"
#include "commands/setpivcardapplicationadministrationkeycommand.h"
#include "smartcard/pivcard.h"
#include "smartcard/readerstatus.h"
...
...
@@ -147,15 +148,26 @@ PIVCardWidget::PIVCardWidget(QWidget *parent):
auto
actionLayout
=
new
QHBoxLayout
;
auto
pinButton
=
new
QPushButton
(
i18n
(
"Change PIN"
));
pinButton
->
setToolTip
(
i18n
(
"Change the PIV Card Application PIN that activates the PIV Card and enables private key operations using the stored keys."
));
actionLayout
->
addWidget
(
pinButton
);
connect
(
pinButton
,
&
QPushButton
::
clicked
,
this
,
[
this
]
()
{
changePin
(
PIVCard
::
pinKeyRef
());
});
auto
pukButton
=
new
QPushButton
(
i18n
(
"Change PUK"
));
pukButton
->
setToolTip
(
i18n
(
"Change the PIN Unblocking Key that enables a reset of the PIN."
));
actionLayout
->
addWidget
(
pukButton
);
connect
(
pukButton
,
&
QPushButton
::
clicked
,
this
,
[
this
]
()
{
changePin
(
PIVCard
::
pukKeyRef
());
});
{
auto
button
=
new
QPushButton
(
i18n
(
"Change PIN"
));
button
->
setToolTip
(
i18n
(
"Change the PIV Card Application PIN that activates the PIV Card and enables private key operations using the stored keys."
));
actionLayout
->
addWidget
(
button
);
connect
(
button
,
&
QPushButton
::
clicked
,
this
,
[
this
]
()
{
changePin
(
PIVCard
::
pinKeyRef
());
});
}
{
auto
button
=
new
QPushButton
(
i18n
(
"Change PUK"
));
button
->
setToolTip
(
i18n
(
"Change the PIN Unblocking Key that enables a reset of the PIN."
));
actionLayout
->
addWidget
(
button
);
connect
(
button
,
&
QPushButton
::
clicked
,
this
,
[
this
]
()
{
changePin
(
PIVCard
::
pukKeyRef
());
});
}
{
auto
button
=
new
QPushButton
(
i18n
(
"Change Admin Key"
));
button
->
setToolTip
(
i18n
(
"Change the PIV Card Application Administration Key that is used by the "
"PIV Card Application to authenticate the PIV Card Application Administrator and by the "
"administrator (resp. Kleopatra) to authenticate the PIV Card Application."
));
actionLayout
->
addWidget
(
button
);
connect
(
button
,
&
QPushButton
::
clicked
,
this
,
[
this
]
()
{
setAdminKey
();
});
}
actionLayout
->
addStretch
(
-
1
);
grid
->
addLayout
(
actionLayout
,
row
++
,
0
,
1
,
4
);
...
...
@@ -239,3 +251,14 @@ void PIVCardWidget::changePin(const std::string &keyRef)
cmd
->
setKeyRef
(
keyRef
);
cmd
->
start
();
}
void
PIVCardWidget
::
setAdminKey
()
{
auto
cmd
=
new
SetPIVCardApplicationAdministrationKeyCommand
(
mCardSerialNumber
,
this
);
this
->
setEnabled
(
false
);
connect
(
cmd
,
&
SetPIVCardApplicationAdministrationKeyCommand
::
finished
,
this
,
[
this
]()
{
this
->
setEnabled
(
true
);
});
cmd
->
start
();
}
src/view/pivcardwidget.h
View file @
42f5173f
...
...
@@ -37,6 +37,7 @@ private:
void
updateKey
(
const
std
::
string
&
keyRef
,
const
SmartCard
::
PIVCard
*
card
,
QLabel
*
label
,
QPushButton
*
button
);
void
generateKey
(
const
std
::
string
&
keyref
);
void
changePin
(
const
std
::
string
&
keyRef
);
void
setAdminKey
();
private
Q_SLOTS
:
void
generatePIVAuthenticationKey
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment