puk-unlock forgotten - added; refs #30
This commit is contained in:
@@ -50,15 +50,14 @@ namespace cardos {
|
|||||||
wrong_pin(const std::string& s) throw(): exception("wrong pin "+s) {}
|
wrong_pin(const std::string& s) throw(): exception("wrong pin "+s) {}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class user_pin_locked: public exception {
|
class pin_locked: public exception {
|
||||||
public:
|
public:
|
||||||
user_pin_locked(const std::string& s) throw():
|
pin_locked() throw(): exception("pin is locked and cannot be changed") {}
|
||||||
exception("user pin locked "+s) {}
|
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class wrong_puk: public exception {
|
class wrong_puk: public wrong_pin {
|
||||||
public:
|
public:
|
||||||
wrong_puk(const std::string& s) throw(): exception("wrong puk "+s) {}
|
wrong_puk(const std::string& s) throw(): wrong_pin("wrong puk "+s) {}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class wrong_result: public exception {
|
class wrong_result: public exception {
|
||||||
@@ -116,11 +115,6 @@ namespace cardos {
|
|||||||
+"; length: "+mrw::string(j)) {
|
+"; length: "+mrw::string(j)) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
class pin_locked: public exception {
|
|
||||||
public:
|
|
||||||
pin_locked() throw(): exception("pin is locked and cannot be changed") {}
|
|
||||||
};
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
@@ -1088,7 +1082,7 @@ namespace cardos {
|
|||||||
//! Performs a PIN test (CHV test)
|
//! Performs a PIN test (CHV test)
|
||||||
void verify(std::string pin, unsigned char id,
|
void verify(std::string pin, unsigned char id,
|
||||||
VerifyMode mode = SEARCH_FROM_DF) {
|
VerifyMode mode = SEARCH_FROM_DF) {
|
||||||
CRYPTOLOG("log");
|
CRYPTOLOG("log pin=\""<<pin<<"\" id=\""<<std::hex<<(int)id<<"\"");
|
||||||
check(send(0x00, 0x20, 0x00, (unsigned char)(id|mode), pin));
|
check(send(0x00, 0x20, 0x00, (unsigned char)(id|mode), pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1152,10 +1146,14 @@ namespace cardos {
|
|||||||
|
|
||||||
/// Logon with transport PIN
|
/// Logon with transport PIN
|
||||||
void logonTransport(std::string pin) {
|
void logonTransport(std::string pin) {
|
||||||
CRYPTOLOG("log");
|
CRYPTOLOG("log pin=\""<<pin<<"\"");
|
||||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectSigG();
|
selectSigG();
|
||||||
logon(transportPin(), pin);
|
try {
|
||||||
|
logon(transportPin(), pin);
|
||||||
|
} catch (std::exception& x) {
|
||||||
|
throw wrong_pin(x.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logon with SigG (Signaturgesetz) secure PIN
|
/// Logon with SigG (Signaturgesetz) secure PIN
|
||||||
@@ -1163,7 +1161,11 @@ namespace cardos {
|
|||||||
CRYPTOLOG("log");
|
CRYPTOLOG("log");
|
||||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectSigG();
|
selectSigG();
|
||||||
logon(sigGPin(), pin);
|
try {
|
||||||
|
logon(sigGPin(), pin);
|
||||||
|
} catch (std::exception& x) {
|
||||||
|
throw wrong_pin(x.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logon with PKCS#15 user PUK to unlock user PIN
|
/// Logon with PKCS#15 user PUK to unlock user PIN
|
||||||
@@ -1171,7 +1173,11 @@ namespace cardos {
|
|||||||
CRYPTOLOG("log");
|
CRYPTOLOG("log");
|
||||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectMF();
|
selectMF();
|
||||||
logon(puk(), pin);
|
try {
|
||||||
|
logon(puk(), pin);
|
||||||
|
} catch (std::exception& x) {
|
||||||
|
throw wrong_puk(x.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logon with PKCS#15 user PIN
|
/// Logon with PKCS#15 user PIN
|
||||||
@@ -1179,7 +1185,11 @@ namespace cardos {
|
|||||||
CRYPTOLOG("log");
|
CRYPTOLOG("log");
|
||||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectMF();
|
selectMF();
|
||||||
logon(pkcs15Pin(), pin);
|
try {
|
||||||
|
logon(pkcs15Pin(), pin);
|
||||||
|
} catch (std::exception& x) {
|
||||||
|
throw wrong_pin(x.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change SigG (Signaturgesetz) secure PIN
|
/// Change SigG (Signaturgesetz) secure PIN
|
||||||
@@ -1187,7 +1197,7 @@ namespace cardos {
|
|||||||
transport PIN and then the card is unlocked and the
|
transport PIN and then the card is unlocked and the
|
||||||
transport state is unset. */
|
transport state is unset. */
|
||||||
void changeSigGPin(std::string newPin, std::string oldPin) {
|
void changeSigGPin(std::string newPin, std::string oldPin) {
|
||||||
CRYPTOLOG("log");
|
CRYPTOLOG("log newPin=\""<<newPin<<"\" oldPin=\""<<oldPin<<"\"");
|
||||||
if (transportState()) { // first time use, reset transport state
|
if (transportState()) { // first time use, reset transport state
|
||||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
logonTransport(oldPin);
|
logonTransport(oldPin);
|
||||||
@@ -1203,7 +1213,7 @@ namespace cardos {
|
|||||||
|
|
||||||
/// Change PKCS#15 user PIN
|
/// Change PKCS#15 user PIN
|
||||||
void changePkcs15Pin(std::string newPin, std::string oldPin) {
|
void changePkcs15Pin(std::string newPin, std::string oldPin) {
|
||||||
CRYPTOLOG("log");
|
CRYPTOLOG("log newPin=\""<<newPin<<"\" oldPin=\""<<oldPin<<"\"");
|
||||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectMF();
|
selectMF();
|
||||||
changeReferenceData(pkcs15Pin(), newPin, oldPin);
|
changeReferenceData(pkcs15Pin(), newPin, oldPin);
|
||||||
@@ -1215,22 +1225,54 @@ namespace cardos {
|
|||||||
change PIN on PKCS#15 and SigG from the same old PIN to the
|
change PIN on PKCS#15 and SigG from the same old PIN to the
|
||||||
same new PIN. */
|
same new PIN. */
|
||||||
void changePins(std::string newPin, std::string oldPin) {
|
void changePins(std::string newPin, std::string oldPin) {
|
||||||
CRYPTOLOG("log");
|
CRYPTOLOG("log newPin=\""<<newPin<<"\" oldPin=\""<<oldPin<<"\"");
|
||||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
if (transportState()) {
|
if (transportState()) { // transport state
|
||||||
changeSigGPin(newPin, oldPin);
|
changeSigGPin(newPin, oldPin);
|
||||||
changePkcs15Pin(newPin, oldPin);
|
changePkcs15Pin(newPin, oldPin);
|
||||||
} else {
|
} else {
|
||||||
if (pkcs15PinRetries()!=-1) changePkcs15Pin(newPin, oldPin);
|
if (pkcs15PinRetries()!=-1) { // normal pin change
|
||||||
try {
|
changePkcs15Pin(newPin, oldPin);
|
||||||
if (sigGPinRetries()!=-1) changeSigGPin(newPin, oldPin);
|
try {
|
||||||
} catch (...) {
|
if (sigGPinRetries()!=-1) changeSigGPin(newPin, oldPin);
|
||||||
// undo PKCS#15 PIN change
|
} catch (...) {
|
||||||
if (pkcs15PinRetries()!=-1) changePkcs15Pin(oldPin, newPin);
|
// undo PKCS#15 PIN change
|
||||||
throw;
|
if (pkcs15PinRetries()!=-1) changePkcs15Pin(oldPin, newPin);
|
||||||
}
|
throw;
|
||||||
|
}
|
||||||
|
} else if (pukRetries()==-1 && sigGPinRetries()!=-1) {
|
||||||
|
changeSigGPin(newPin, oldPin); // only valid sigg left
|
||||||
|
} else throw pin_locked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Unlock PKCS#15 PIN using PUK
|
||||||
|
/** If the PIN is still the same as the old PIN was, SigG PIN
|
||||||
|
can be saved. If you have forgotten your SigG PIN, just use
|
||||||
|
@c force to completely break it. Otherwise PIN will first be
|
||||||
|
applied to SigG, if that works, PKCS#15 will be changed
|
||||||
|
accordingly. */
|
||||||
|
void unlock(std::string pin, std::string puk, bool force=false) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
if (pkcs15PinRetries()!=-1) return; // all ok
|
||||||
|
if (pukRetries()==-1) throw pin_locked(); // too late, puk broken
|
||||||
|
logonPuk(puk);
|
||||||
|
CRYPTOLOG("PUK accepted");
|
||||||
|
while (sigGPinRetries()!=-1) try {
|
||||||
|
logonSigG(pin); // check SigG
|
||||||
|
CRYPTOLOG("SigG successfully checked");
|
||||||
|
break; // SigG still works
|
||||||
|
} catch (...) {
|
||||||
|
CRYPTOLOG("SigG PIN failed");
|
||||||
|
if (!force) throw; // don't enforce, abort after one try
|
||||||
|
// otherwise break the SigG PUK now
|
||||||
|
// continue until SigG is broken
|
||||||
|
CRYPTOLOG("Force kill SigG");
|
||||||
|
}
|
||||||
|
selectMF();
|
||||||
|
changeReferenceData(pkcs15Pin(), pin);
|
||||||
|
CRYPTOLOG("Successfully restored PKCS#15 PIN");
|
||||||
|
}
|
||||||
|
|
||||||
/// Select a file in the PKCS#15 part on the smart card
|
/// Select a file in the PKCS#15 part on the smart card
|
||||||
void selectPkcs15File(std::string file) {
|
void selectPkcs15File(std::string file) {
|
||||||
|
@@ -545,10 +545,10 @@ namespace suisseid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// install certificates on the card
|
/// install certificates on the card
|
||||||
/** @param reinstall whether to force reinstallation of existing
|
/** parameter @c bool whether to force reinstallation of existing
|
||||||
certificates
|
certificates
|
||||||
@return @c true on success */
|
@return @c true on success */
|
||||||
virtual bool installCerts(bool reinstall = true) {
|
virtual bool installCerts(bool = true) {
|
||||||
CRYPTOLOG("log");
|
CRYPTOLOG("log");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -617,7 +617,7 @@ namespace suisseid {
|
|||||||
return pukLocked(), false;
|
return pukLocked(), false;
|
||||||
PinPukChange pins(pinChangePuk());
|
PinPukChange pins(pinChangePuk());
|
||||||
if (!pins.valid()) return false;
|
if (!pins.valid()) return false;
|
||||||
_card->changePins(pins.newpin, pins.oldpin);
|
_card->unlock(pins.newpin, pins.oldpin);
|
||||||
return start();
|
return start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user