puk-unlock forgotten - added; refs #30

master
Marc Wäckerlin 11 years ago
parent f2a1435cf4
commit 245dde6f5b
  1. 76
      src/cardos.hxx
  2. 6
      src/suisseid.hxx

@ -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();
try {
logon(transportPin(), pin); 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();
try {
logon(sigGPin(), pin); 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();
try {
logon(puk(), pin); 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();
try {
logon(pkcs15Pin(), pin); 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,13 +1225,14 @@ 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
changePkcs15Pin(newPin, oldPin);
try { try {
if (sigGPinRetries()!=-1) changeSigGPin(newPin, oldPin); if (sigGPinRetries()!=-1) changeSigGPin(newPin, oldPin);
} catch (...) { } catch (...) {
@ -1229,7 +1240,38 @@ namespace cardos {
if (pkcs15PinRetries()!=-1) changePkcs15Pin(oldPin, newPin); if (pkcs15PinRetries()!=-1) changePkcs15Pin(oldPin, newPin);
throw; 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

@ -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();
} }

Loading…
Cancel
Save