Changes between Version 3 and Version 4 of revisionSoftwareXCA


Ignore:
Timestamp:
May 3, 2017, 10:37:23 AM (7 years ago)
Author:
aaraujo
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • revisionSoftwareXCA

    v3 v4  
    136136
    137137
    138 
    139 
    140 
    141 
     138'''https://github.com/open-eid/browser-token-signing/blob/master/common/esteid_sign.c'''
     139{{{
     140int EstEID_signHash(char **signature, unsigned int *signatureLength, CK_SLOT_ID slotID, EstEID_Map cert, const char *hash, unsigned int hashLength, EstEID_PINPromptData pinPromptData) {
     141        CK_SESSION_HANDLE session = 0L;
     142        CK_RV loginResult = CKR_FUNCTION_CANCELED;
     143        char *name;
     144        char message[1024];
     145        int remainingTries = -1;
     146        int attempt = 0, blocked = FALSE;
     147        int isPinPad;
     148    unsigned int privateKeyIndex;
     149#ifdef _WIN32
     150        EstEID_PINPromptDataEx pinPromptDataEx;
     151#endif
     152
     153
     154        LOG_LOCATION;
     155
     156        if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE;
     157
     158        name = EstEID_getFullNameWithPersonalCode(cert);
     159    privateKeyIndex = (unsigned)atoi(EstEID_mapGet(cert, "privateKeyIndex"));
     160    remainingTries = EstEID_getRemainingTries(slotID);
     161        for (attempt = 0;; attempt++) {
     162                if (remainingTries == -1)
     163                        CLOSE_SESSION_AND_RETURN(FAILURE);
     164                if (!remainingTries || blocked) {
     165                        sprintf(EstEID_error, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED);
     166                        pinPromptData.alertFunction(pinPromptData.nativeWindowHandle, l10n("PIN2 blocked, cannot sign!"));
     167                        CLOSE_SESSION_AND_RETURN(FAILURE);
     168                }
     169                if (remainingTries < 3 || attempt) {
     170                        sprintf(message, "%s%s %i", (attempt ? l10n("Incorrect PIN2! ") : ""), l10n("Tries left:"), remainingTries);
     171                }
     172                else {
     173                        message[0] = 0;
     174                }
     175                isPinPad = EstEID_isPinPad(slotID);
     176                if(!isPinPad) {
     177                        // Simple card reader
     178                        char *pin = pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, (unsigned)atoi(EstEID_mapGet(cert, "minPinLen")), isPinPad);
     179                        if (!pin || strlen(pin) == 0) {
     180                                free(pin);
     181                                setUserCancelErrorCodeAndMessage();
     182                                CLOSE_SESSION_AND_RETURN(FAILURE);
     183                        }
     184                        loginResult = fl->C_Login(session, CKU_USER, (unsigned char *)pin, strlen(pin));
     185                        free(pin);
     186                }
     187                else {
     188                        // PIN pad                     
     189#ifdef _WIN32
     190                        EstEID_log("creating pinpad dialog UI thread");
     191                        pinpad_thread_result = -1;
     192                        FAIL_IF_THREAD_ERROR("CreateMutex", (pinpad_thread_mutex = CreateMutex(NULL, FALSE, NULL)));
     193#else
     194                        EstEID_log("creating pinpad worker thread");
     195                        pinpad_thread_result = -1;
     196                        FAIL_IF_PTHREAD_ERROR("pthread_mutex_init", pthread_mutex_init(&pinpad_thread_mutex, NULL));
     197                        FAIL_IF_PTHREAD_ERROR("pthread_cond_init", pthread_cond_init(&pinpad_thread_condition, NULL));
     198                        pthread_t pinpad_thread;
     199                        EstEID_PINPadThreadData threadData;
     200                        threadData.session = session;
     201                        threadData.result = CKR_OK;
     202#endif
     203                        EstEID_log("thread launched");
     204#ifdef _WIN32
     205                        /*
     206                        NB! Due to Firefox for Windows specific behaviour C_Login() is launched from main thread
     207                        and UI code is running in separate thread if running on Windows.
     208                        */
     209                        pinPromptDataEx.pinPromptData = pinPromptData;
     210                        pinPromptDataEx.message = message;
     211                        pinPromptDataEx.name = name;
     212                        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&EstEID_pinPadLogin, (LPVOID)&pinPromptDataEx, 0, NULL);
     213                        loginResult = fl->C_Login(session, CKU_USER, NULL, 0);
     214                        //closePinPadModalSheet();
     215#else
     216                        FAIL_IF_PTHREAD_ERROR("pthread_create", pthread_create(&pinpad_thread, NULL, EstEID_pinPadLogin, (void*)&threadData));
     217                        pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, 0, isPinPad);
     218                        loginResult = threadData.result;
     219#endif
     220                        EstEID_log("pinpad sheet/dialog closed");
     221                        if (loginResult == CKR_FUNCTION_CANCELED) {
     222                                setUserCancelErrorCodeAndMessage();
     223                                CLOSE_SESSION_AND_RETURN(FAILURE);
     224                        }
     225                }
     226                EstEID_log("loginResult = %s", pkcs11_error_message(loginResult));
     227                switch (loginResult) {
     228                        case CKR_PIN_LOCKED:
     229                                blocked = TRUE;
     230                        case CKR_PIN_INCORRECT:
     231                remainingTries--;
     232                        case CKR_PIN_INVALID:
     233                        case CKR_PIN_LEN_RANGE:
     234                                EstEID_log("this was attempt %i, loginResult causes to run next round", attempt);
     235                                continue;
     236                        default:
     237                                if (EstEID_CK_failure("C_Login", loginResult)) CLOSE_SESSION_AND_RETURN(FAILURE);
     238                }
     239                break; // Login successful - correct PIN supplied
     240        }
     241
     242        return EstEID_RealSign(session, signature, signatureLength, hash, hashLength, name, privateKeyIndex);
     243}
     244
     245
     246int EstEID_RealSign(CK_SESSION_HANDLE session, char **signature, unsigned int *signatureLength, const char *hash, unsigned int hashLength, char* name, unsigned int privateKeyIndex) {
     247        CK_ULONG objectCount;
     248        unsigned int hashWithPaddingLength = 0;
     249        char *hashWithPadding;
     250        CK_MECHANISM mechanism = {CKM_RSA_PKCS, 0, 0};
     251        CK_OBJECT_CLASS objectClass = CKO_PRIVATE_KEY;
     252        CK_ATTRIBUTE searchAttribute = {CKA_CLASS, &objectClass, sizeof(objectClass)};
     253
     254    unsigned int max = privateKeyIndex + 1;
     255    CK_OBJECT_HANDLE privateKeyHandle[max];
     256
     257        if (EstEID_CK_failure("C_FindObjectsInit", fl->C_FindObjectsInit(session, &searchAttribute, 1))) CLOSE_SESSION_AND_RETURN(FAILURE);
     258
     259        if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, privateKeyHandle, max, &objectCount))) CLOSE_SESSION_AND_RETURN(FAILURE);
     260        if (EstEID_CK_failure("C_FindObjectsFinal", fl->C_FindObjectsFinal(session))) CLOSE_SESSION_AND_RETURN(FAILURE);
     261
     262        if (objectCount == 0) CLOSE_SESSION_AND_RETURN(FAILURE); // todo ?? set error message
     263    EstEID_log("found %i private keys in slot, using key in position %i", objectCount, privateKeyIndex);
     264
     265    if (EstEID_CK_failure("C_SignInit", fl->C_SignInit(session, &mechanism, privateKeyHandle[privateKeyIndex]))) CLOSE_SESSION_AND_RETURN(FAILURE);
     266
     267        hashWithPadding = EstEID_addPadding(hash, hashLength, &hashWithPaddingLength);
     268        if (hashWithPadding) { // This is additional safeguard, as digest length is checked already before calling EstEID_addPadding()
     269                CK_ULONG len;
     270                if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, NULL, &len))) {
     271                        free(hashWithPadding);
     272                        CLOSE_SESSION_AND_RETURN(FAILURE);
     273                }
     274                *signature = (char *)malloc(len);
     275                if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, (CK_BYTE_PTR) * signature, &len))) {
     276                        free(hashWithPadding);
     277                        CLOSE_SESSION_AND_RETURN(FAILURE);
     278                }
     279                *signatureLength = len;
     280                free(hashWithPadding);
     281        }
     282
     283        if (session) {
     284                if (EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))) {
     285                        return FAILURE;
     286                }
     287        }
     288
     289        if(name) {
     290                free(name);
     291        }
     292
     293        if (!hashWithPaddingLength) { // This is additional safeguard, as digest length is checked already before calling EstEID_addPadding()
     294                EstEID_log("will not sign due to incorrect incoming message digest length");
     295                return FAILURE;
     296        }
     297        EstEID_log("successfully signed");
     298        return SUCCESS;
     299}
     300
     301
     302
     303}}}
     304
     305
     306
     307
     308