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) {}
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class user_pin_locked: public exception {
|
||||
class pin_locked: public exception {
|
||||
public:
|
||||
user_pin_locked(const std::string& s) throw():
|
||||
exception("user pin locked "+s) {}
|
||||
pin_locked() throw(): exception("pin is locked and cannot be changed") {}
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class wrong_puk: public exception {
|
||||
class wrong_puk: public wrong_pin {
|
||||
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 {
|
||||
@@ -116,11 +115,6 @@ namespace cardos {
|
||||
+"; 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)
|
||||
void verify(std::string pin, unsigned char id,
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -1152,10 +1146,14 @@ namespace cardos {
|
||||
|
||||
/// Logon with transport PIN
|
||||
void logonTransport(std::string pin) {
|
||||
CRYPTOLOG("log");
|
||||
CRYPTOLOG("log pin=\""<<pin<<"\"");
|
||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||
selectSigG();
|
||||
try {
|
||||
logon(transportPin(), pin);
|
||||
} catch (std::exception& x) {
|
||||
throw wrong_pin(x.what());
|
||||
}
|
||||
}
|
||||
|
||||
/// Logon with SigG (Signaturgesetz) secure PIN
|
||||
@@ -1163,7 +1161,11 @@ namespace cardos {
|
||||
CRYPTOLOG("log");
|
||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||
selectSigG();
|
||||
try {
|
||||
logon(sigGPin(), pin);
|
||||
} catch (std::exception& x) {
|
||||
throw wrong_pin(x.what());
|
||||
}
|
||||
}
|
||||
|
||||
/// Logon with PKCS#15 user PUK to unlock user PIN
|
||||
@@ -1171,7 +1173,11 @@ namespace cardos {
|
||||
CRYPTOLOG("log");
|
||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||
selectMF();
|
||||
try {
|
||||
logon(puk(), pin);
|
||||
} catch (std::exception& x) {
|
||||
throw wrong_puk(x.what());
|
||||
}
|
||||
}
|
||||
|
||||
/// Logon with PKCS#15 user PIN
|
||||
@@ -1179,7 +1185,11 @@ namespace cardos {
|
||||
CRYPTOLOG("log");
|
||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||
selectMF();
|
||||
try {
|
||||
logon(pkcs15Pin(), pin);
|
||||
} catch (std::exception& x) {
|
||||
throw wrong_pin(x.what());
|
||||
}
|
||||
}
|
||||
|
||||
/// Change SigG (Signaturgesetz) secure PIN
|
||||
@@ -1187,7 +1197,7 @@ namespace cardos {
|
||||
transport PIN and then the card is unlocked and the
|
||||
transport state is unset. */
|
||||
void changeSigGPin(std::string newPin, std::string oldPin) {
|
||||
CRYPTOLOG("log");
|
||||
CRYPTOLOG("log newPin=\""<<newPin<<"\" oldPin=\""<<oldPin<<"\"");
|
||||
if (transportState()) { // first time use, reset transport state
|
||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||
logonTransport(oldPin);
|
||||
@@ -1203,7 +1213,7 @@ namespace cardos {
|
||||
|
||||
/// Change PKCS#15 user PIN
|
||||
void changePkcs15Pin(std::string newPin, std::string oldPin) {
|
||||
CRYPTOLOG("log");
|
||||
CRYPTOLOG("log newPin=\""<<newPin<<"\" oldPin=\""<<oldPin<<"\"");
|
||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||
selectMF();
|
||||
changeReferenceData(pkcs15Pin(), newPin, oldPin);
|
||||
@@ -1215,13 +1225,14 @@ namespace cardos {
|
||||
change PIN on PKCS#15 and SigG from the same old PIN to the
|
||||
same new PIN. */
|
||||
void changePins(std::string newPin, std::string oldPin) {
|
||||
CRYPTOLOG("log");
|
||||
CRYPTOLOG("log newPin=\""<<newPin<<"\" oldPin=\""<<oldPin<<"\"");
|
||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||
if (transportState()) {
|
||||
if (transportState()) { // transport state
|
||||
changeSigGPin(newPin, oldPin);
|
||||
changePkcs15Pin(newPin, oldPin);
|
||||
} else {
|
||||
if (pkcs15PinRetries()!=-1) changePkcs15Pin(newPin, oldPin);
|
||||
if (pkcs15PinRetries()!=-1) { // normal pin change
|
||||
changePkcs15Pin(newPin, oldPin);
|
||||
try {
|
||||
if (sigGPinRetries()!=-1) changeSigGPin(newPin, oldPin);
|
||||
} catch (...) {
|
||||
@@ -1229,9 +1240,40 @@ namespace cardos {
|
||||
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
|
||||
void selectPkcs15File(std::string file) {
|
||||
CRYPTOLOG("log");
|
||||
|
@@ -545,10 +545,10 @@ namespace suisseid {
|
||||
}
|
||||
|
||||
/// install certificates on the card
|
||||
/** @param reinstall whether to force reinstallation of existing
|
||||
/** parameter @c bool whether to force reinstallation of existing
|
||||
certificates
|
||||
@return @c true on success */
|
||||
virtual bool installCerts(bool reinstall = true) {
|
||||
virtual bool installCerts(bool = true) {
|
||||
CRYPTOLOG("log");
|
||||
return false;
|
||||
}
|
||||
@@ -617,7 +617,7 @@ namespace suisseid {
|
||||
return pukLocked(), false;
|
||||
PinPukChange pins(pinChangePuk());
|
||||
if (!pins.valid()) return false;
|
||||
_card->changePins(pins.newpin, pins.oldpin);
|
||||
_card->unlock(pins.newpin, pins.oldpin);
|
||||
return start();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user