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();
 | 
			
		||||
        logon(transportPin(), pin);
 | 
			
		||||
        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();
 | 
			
		||||
        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
 | 
			
		||||
@@ -1171,7 +1173,11 @@ namespace cardos {
 | 
			
		||||
        CRYPTOLOG("log");
 | 
			
		||||
        pcsc::Connection::Reader::Transaction lock(_reader);
 | 
			
		||||
        selectMF();
 | 
			
		||||
        logon(puk(), pin);
 | 
			
		||||
        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();
 | 
			
		||||
        logon(pkcs15Pin(), pin);
 | 
			
		||||
        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,22 +1225,54 @@ 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);
 | 
			
		||||
          try {
 | 
			
		||||
            if (sigGPinRetries()!=-1)   changeSigGPin(newPin, oldPin);
 | 
			
		||||
          } catch (...) {
 | 
			
		||||
            // undo PKCS#15 PIN change
 | 
			
		||||
            if (pkcs15PinRetries()!=-1) changePkcs15Pin(oldPin, newPin);
 | 
			
		||||
            throw;
 | 
			
		||||
          }
 | 
			
		||||
          if (pkcs15PinRetries()!=-1) { // normal pin change
 | 
			
		||||
            changePkcs15Pin(newPin, oldPin);
 | 
			
		||||
            try {
 | 
			
		||||
              if (sigGPinRetries()!=-1) changeSigGPin(newPin, oldPin);
 | 
			
		||||
            } catch (...) {
 | 
			
		||||
              // undo PKCS#15 PIN change
 | 
			
		||||
              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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -545,10 +545,10 @@ namespace suisseid {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /// install certificates on the card
 | 
			
		||||
      /** @param reinstall whether to force reinstallation of existing
 | 
			
		||||
                           certificates
 | 
			
		||||
      /** 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