Ejemplo n.º 1
0
/*! \fn     addNewUserAndNewSmartCard(volatile uint16_t* pin_code)
*   \brief  Add a new user with a new smart card
*   \param  pin_code The new pin code
*   \return success or not
*/
RET_TYPE addNewUserAndNewSmartCard(volatile uint16_t* pin_code)
{
    uint8_t temp_buffer[AES_KEY_LENGTH/8];
    uint8_t temp_nonce[AES256_CTR_LENGTH];
    uint8_t new_user_id;
    
    // When inserting a new user and a new card, we need to setup the following elements
    // - AES encryption key, stored in the smartcard
    // - AES next available CTR, stored in the user profile
    // - AES nonce, stored in the eeprom along with the user ID
    // - Smartcard CPZ, randomly generated and stored in our eeprom along with user id & nonce
    
    // The next part can take quite a while
    guiDisplayProcessingScreen();
    
    // Get new user id if possible
    if (findAvailableUserId(&new_user_id) == RETURN_NOK)
    {
        return RETURN_NOK;
    }
    
    // Create user profile in flash, CTR is set to 0 by the library
    formatUserProfileMemory(new_user_id);

    // Initialize user flash context, that inits the node mgmt handle and the ctr value
    initUserFlashContext(new_user_id);

    // Generate random CPZ value
    fillArrayWithRandomBytes(temp_buffer, SMARTCARD_CPZ_LENGTH);

    // Generate random nonce to be stored in the eeprom
    fillArrayWithRandomBytes(temp_nonce, AES256_CTR_LENGTH);
    
    // Store User ID <> SMC CPZ & AES CTR <> user id
    if (writeSmartCardCPZForUserId(temp_buffer, temp_nonce, new_user_id) != RETURN_OK)
    {
        return RETURN_NOK;
    }
    
    // Write random bytes in the code protected zone in the smart card
    writeCodeProtectedZone(temp_buffer);
    
    // Generate a new random AES key, write it in the smartcard
    fillArrayWithRandomBytes(temp_buffer, AES_KEY_LENGTH/8);
    writeAES256BitsKey(temp_buffer);
    
    // Initialize encryption handling
    initEncryptionHandling(temp_buffer, temp_nonce);
    
    // Write new pin code
    writeSecurityCode(pin_code);
    
    return RETURN_OK;
}
Ejemplo n.º 2
0
/*! \fn     guiScreenLoop(uint8_t input_interface_result)
*   \brief  Function called to handle screen changes
*   \param  input_interface_result Touch detection result
*/
void guiScreenLoop(uint8_t input_interface_result)
{
    // If no press, you can return!
    if ((input_interface_result == WHEEL_ACTION_NONE) || (currentScreen == SCREEN_DEFAULT_INSERTED_INVALID) || (currentScreen == SCREEN_DEFAULT_INSERTED_UNKNOWN))
    {
        return;
    }

    if (currentScreen == SCREEN_DEFAULT_NINSERTED)
    {
        // No smart card inserted, ask the user to insert one
        guiDisplayInsertSmartCardScreenAndWait();
    }
    else if (currentScreen == SCREEN_MEMORY_MGMT)
    {
        // Currently in memory management mode, tell the user to finish it via the plugin/app
        guiDisplayInformationOnScreenAndWait(ID_STRING_CLOSEMEMMGMT);
        guiGetBackToCurrentScreen();
        miniWheelClearDetections();
    }
    else if (currentScreen == SCREEN_DEFAULT_INSERTED_LCK)
    {
        // Locked screen and a detection happened, check that the user hasn't removed his card, launch unlocking process
        if ((cardDetectedRoutine() == RETURN_MOOLTIPASS_USER) && (validCardDetectedFunction(0, TRUE) == RETURN_VCARD_OK))
        {
            // User approved his pin
            unlockFeatureCheck();
            currentScreen = SCREEN_DEFAULT_INSERTED_NLCK;
        }
            
        // Go to the new screen
        guiGetBackToCurrentScreen();
    }
    else
    {
        if (input_interface_result == WHEEL_ACTION_UP)
        {
            // We can do that because of defines and bitmap order (see logic_fw_flash_storage and gui.h)
            if (currentScreen == SCREEN_LOCK)
            {
                currentScreen = SCREEN_SETTINGS;
            } 
            else if (currentScreen == SCREEN_SETTINGS_CHANGE_PIN)
            {
                currentScreen = SCREEN_SETTINGS_ERASE;
            }
            else
            {
                currentScreen--;
            }
            // We can do that because of defines and bitmap order (see logic_fw_flash_storage and gui.h)
            for (uint8_t i = 0; i < NB_BMPS_PER_TRANSITION; i++)
            {
                miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK+NB_BMPS_PER_TRANSITION-1-i, OLED_SCROLL_FLIP);
                timerBasedDelayMs(12);
            }
        }
        else if (input_interface_result == WHEEL_ACTION_DOWN)
        {
            // We can do that because of defines and bitmap order (see logic_fw_flash_storage and gui.h)
            for (uint8_t i = 0; i < NB_BMPS_PER_TRANSITION-1; i++)
            {
                miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK+1+i, OLED_SCROLL_FLIP);
                timerBasedDelayMs(12);
            }
            if (currentScreen == SCREEN_SETTINGS)
            {
                currentScreen = SCREEN_LOCK;
            }
            else if (currentScreen == SCREEN_SETTINGS_ERASE)
            {
                currentScreen = SCREEN_SETTINGS_CHANGE_PIN;
            }
            else
            {
                currentScreen++;
            }
            miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_FLIP);              
        }
        else if (input_interface_result == WHEEL_ACTION_LONG_CLICK)
        {
            // Long press in main menu : lock, long press in settings menu: go back to login screen
            if ((currentScreen >= SCREEN_SETTINGS_CHANGE_PIN) && (currentScreen <= SCREEN_SETTINGS_ERASE))
            {
                currentScreen = SCREEN_LOGIN;
                miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_UP);
            }
        }
        else if (input_interface_result == WHEEL_ACTION_SHORT_CLICK)
        {
            switch(currentScreen)
            {
                case SCREEN_LOCK:
                {
                    // User wants to lock his mooltipass
                    currentScreen = SCREEN_DEFAULT_INSERTED_LCK;
                    handleSmartcardRemoved();
                    guiGetBackToCurrentScreen();
                    break;
                }
                case SCREEN_LOGIN:
                {
                    // User wants to go to the login menu
                    if (getStartingParentAddress() != NODE_ADDR_NULL)
                    {
                        loginSelectLogic();
                    }
                    else
                    {
                        guiDisplayInformationOnScreenAndWait(ID_STRING_NO_CREDS);
                    }
                    guiGetBackToCurrentScreen();
                    break;
                }
                case SCREEN_FAVORITES:
                {
                    // User wants to go to the favorite menu
                    #if defined(ENABLE_CREDENTIAL_MANAGEMENT) && defined(REPLACE_FAVORITES_WITH_CREDENTIAL_MANAGEMENT)
                        managementActionPickingLogic();
                    #else
                        favoritePickingLogic();
                    #endif
                    guiGetBackToCurrentScreen();
                    break;
                }
                case SCREEN_SETTINGS:
                {
                    currentScreen = SCREEN_SETTINGS_CHANGE_PIN;
                    miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_UP);
                    break;
                }
                case SCREEN_SETTINGS_HOME:
                {
                    currentScreen = SCREEN_LOGIN;
                    miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_UP);
                    break;
                }
                case SCREEN_SETTINGS_CHANGE_PIN:
                {
                    // User wants to change his PIN code
                        
                    // Reauth user
                    if (removeCardAndReAuthUser() == RETURN_OK)
                    {
                        // User approved his pin, ask his new one
                        volatile uint16_t pin_code;
                            
                        if (guiAskForNewPin(&pin_code, ID_STRING_NEW_PINQ) == RETURN_NEW_PIN_OK)
                        {
                            // User successfully entered a new pin
                            writeSecurityCode(&pin_code);
                            // Inform of success
                            guiDisplayInformationOnScreenAndWait(ID_STRING_PIN_CHANGED);
                        }
                        else
                        {
                            // Inform of fail
                            guiDisplayInformationOnScreenAndWait(ID_STRING_PIN_NCGHANGED);
                        }
                        pin_code = 0x0000;
                    }
                    else
                    {
                        currentScreen = SCREEN_DEFAULT_INSERTED_LCK;
                    }
                    guiGetBackToCurrentScreen();
                    break;
                }
                case SCREEN_SETTINGS_BACKUP:
                {
                    // User wants to clone his smartcard
                    volatile uint16_t pin_code;
                    RET_TYPE temp_rettype;
                        
                    // Reauth user
                    if (removeCardAndReAuthUser() == RETURN_OK)
                    {
                        // Ask for new pin
                        temp_rettype = guiAskForNewPin(&pin_code, ID_STRING_PIN_NEW_CARD);
                        if (temp_rettype == RETURN_NEW_PIN_OK)
                        {
                            // Start the cloning process
                            if (cloneSmartCardProcess(&pin_code) == RETURN_OK)
                            {
                                // Well it worked....
                            }
                            else
                            {
                                currentScreen = SCREEN_DEFAULT_INSERTED_LCK;
                                guiDisplayInformationOnScreen(ID_STRING_TGT_CARD_NBL);
                            }
                            pin_code = 0x0000;
                        }
                        else if (temp_rettype == RETURN_NEW_PIN_DIFF)
                        {
                            currentScreen = SCREEN_DEFAULT_INSERTED_LCK;
                            guiDisplayInformationOnScreen(ID_STRING_PIN_DIFF);
                        }
                        else
                        {
                            guiGetBackToCurrentScreen();
                            return;
                        }
                    }
                    else
                    {
                        currentScreen = SCREEN_DEFAULT_INSERTED_LCK;
                        guiDisplayInformationOnScreen(ID_STRING_FAILED);
                    }
                    userViewDelay();
                    guiGetBackToCurrentScreen();
                    break;
                }
                case SCREEN_SETTINGS_ERASE:
                {
                    // User wants to delete his profile in flash / eeprom....
                    if ((guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_AREYOUSURE)) == RETURN_OK) && (removeCardAndReAuthUser() == RETURN_OK) && (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_AREYOURLSURE)) == RETURN_OK))
                    {
                        uint8_t currentuserid = getCurrentUserID();
                        guiDisplayProcessingScreen();
                        deleteCurrentUserFromFlash();
                            
                        if (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_ERASE_TCARD)) == RETURN_OK)
                        {
                            guiDisplayProcessingScreen();
                            eraseSmartCard();
                                
                            // Erase other smartcards
                            while (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_OTHECARDFUSER)) == RETURN_OK)
                            {
                                // Ask the user to insert other smartcards
                                guiDisplayInformationOnScreen(ID_STRING_INSERT_OTHER);
                                    
                                // Wait for the user to remove and enter another smartcard
                                while (isCardPlugged() != RETURN_JRELEASED);
                                    
                                // Wait for the user to insert a new smart card
                                while (isCardPlugged() != RETURN_JDETECT);
                                guiDisplayProcessingScreen();
                                    
                                // Check the card type & ask user to enter his pin, check that the new user id loaded by validCardDetectedFunction is still the same
                                if ((cardDetectedRoutine() == RETURN_MOOLTIPASS_USER) && (validCardDetectedFunction(0, FALSE) == RETURN_VCARD_OK) && (currentuserid == getCurrentUserID()))
                                {
                                    eraseSmartCard();
                                }
                            }
                        }
                            
                        // Delete LUT entries
                        guiDisplayProcessingScreen();
                        deleteUserIdFromSMCUIDLUT(currentuserid);
                            
                        // Go to invalid screen
                        currentScreen = SCREEN_DEFAULT_INSERTED_INVALID;
                    }
                    else
                    {
                        currentScreen = SCREEN_DEFAULT_INSERTED_LCK;
                    }
                    userViewDelay();
                    handleSmartcardRemoved();
                    guiGetBackToCurrentScreen();
                    break;
                }

                default: break;
            }                
        }
    }
}