wiki:revisionSoftwareXCA

Revisión de software XCA

XCA options

Add, Remove, Search.

Options.cpp

addLib(QString fname)

pkcs11:load_lib(fname, false)


class pkcs11
{
	friend class pk11_attribute;
	friend class pk11_attr_ulong;
	friend class pk11_attr_data;

	private:
		static pkcs11_lib_list libs;
		slotid p11slot;
		CK_SESSION_HANDLE session;
		CK_OBJECT_HANDLE p11obj;

	public:
		pkcs11();
		~pkcs11();

		static bool loaded() {
			return libs.count() != 0;
		}
		static pkcs11_lib *load_lib(QString fname, bool silent);
		static pkcs11_lib *get_lib(QString fname)
		{
			return libs.get_lib(fname);
		}
		static bool remove_lib(QString fname)
		{
			return libs.remove_lib(fname);
		}
		static void remove_libs()
		{
			while (!libs.isEmpty())
				delete libs.takeFirst();
		}
		static void load_libs(QString list, bool silent);
		static pkcs11_lib_list get_libs()
		{
			return libs;
		}
		tkInfo tokenInfo(slotid slot);
		tkInfo tokenInfo()
		{
			return tokenInfo(p11slot);
		}
		QString driverInfo(slotid slot)
		{
			return slot.lib->driverInfo();
		}
		slotidList getSlotList()
		{
			return libs.getSlotList();
		}

		bool selectToken(slotid *slot, QWidget *w);
		void changePin(slotid slot, bool so);
		void initPin(slotid slot);
		void initToken(slotid slot, unsigned char *pin,
			int pinlen, QString label);
		QList<CK_MECHANISM_TYPE> mechanismList(slotid slot);
		void mechanismInfo(slotid slot, CK_MECHANISM_TYPE m,
			CK_MECHANISM_INFO *info);
		void startSession(slotid slot, bool rw = false);

		/* Session based functions */
		void loadAttribute(pk11_attribute &attribute,
				   CK_OBJECT_HANDLE object);
		void storeAttribute(pk11_attribute &attribute,
				   CK_OBJECT_HANDLE object);
		QList<CK_OBJECT_HANDLE> objectList(pk11_attlist &atts);
		QString tokenLogin(QString name, bool so, bool force=false);
		void getRandom();
		void logout();
		bool needsLogin(bool so);
		void login(unsigned char *pin, unsigned long pinlen, bool so);

		void setPin(unsigned char *oldPin, unsigned long oldPinLen,
			unsigned char *pin, unsigned long pinLen);
		CK_OBJECT_HANDLE createObject(pk11_attlist &attrs);
		pk11_attr_data findUniqueID(unsigned long oclass);
		pk11_attr_data generateKey(QString name,
			unsigned long ec_rsa_mech, unsigned long bits, int nid);
		int deleteObjects(QList<CK_OBJECT_HANDLE> objects);
		EVP_PKEY *getPrivateKey(EVP_PKEY *pub, CK_OBJECT_HANDLE obj);
		int encrypt(int flen, const unsigned char *from,
				unsigned char *to, int tolen, unsigned long m);
		int decrypt(int flen, const unsigned char *from,
				unsigned char *to, int tolen, unsigned long m);

};



Search

bool searchThread::checkLib(QString file)
{
	qint64 siz;
	int r = -1;

	QFile qf(file);
	siz = qf.size();
	if (qf.open(QIODevice::ReadOnly)) {
		uchar *p = qf.map(0, siz);
		r = QByteArray::fromRawData((char*)p, siz)
			.indexOf("C_GetFunctionList");
		qf.unmap(p);
		qf.close();
	}
	return r != -1;
}

https://github.com/open-eid/browser-token-signing/blob/master/common/esteid_sign.c

int EstEID_signHash(char **signature, unsigned int *signatureLength, CK_SLOT_ID slotID, EstEID_Map cert, const char *hash, unsigned int hashLength, EstEID_PINPromptData pinPromptData) {
        CK_SESSION_HANDLE session = 0L;
        CK_RV loginResult = CKR_FUNCTION_CANCELED;
        char *name;
        char message[1024];
        int remainingTries = -1;
        int attempt = 0, blocked = FALSE;
        int isPinPad;
    unsigned int privateKeyIndex;
#ifdef _WIN32
        EstEID_PINPromptDataEx pinPromptDataEx;
#endif


        LOG_LOCATION;

        if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE;

        name = EstEID_getFullNameWithPersonalCode(cert);
    privateKeyIndex = (unsigned)atoi(EstEID_mapGet(cert, "privateKeyIndex"));
    remainingTries = EstEID_getRemainingTries(slotID);
        for (attempt = 0;; attempt++) {
                if (remainingTries == -1)
                        CLOSE_SESSION_AND_RETURN(FAILURE);
                if (!remainingTries || blocked) {
                        sprintf(EstEID_error, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED);
                        pinPromptData.alertFunction(pinPromptData.nativeWindowHandle, l10n("PIN2 blocked, cannot sign!"));
                        CLOSE_SESSION_AND_RETURN(FAILURE);
                }
                if (remainingTries < 3 || attempt) {
                        sprintf(message, "%s%s %i", (attempt ? l10n("Incorrect PIN2! ") : ""), l10n("Tries left:"), remainingTries);
                }
                else {
                        message[0] = 0;
                }
                isPinPad = EstEID_isPinPad(slotID);
                if(!isPinPad) {
                        // Simple card reader
                        char *pin = pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, (unsigned)atoi(EstEID_mapGet(cert, "minPinLen")), isPinPad);
                        if (!pin || strlen(pin) == 0) {
                                free(pin);
                                setUserCancelErrorCodeAndMessage();
                                CLOSE_SESSION_AND_RETURN(FAILURE);
                        }
                        loginResult = fl->C_Login(session, CKU_USER, (unsigned char *)pin, strlen(pin));
                        free(pin);
                }
                else {
                        // PIN pad                      
#ifdef _WIN32
                        EstEID_log("creating pinpad dialog UI thread");
                        pinpad_thread_result = -1;
                        FAIL_IF_THREAD_ERROR("CreateMutex", (pinpad_thread_mutex = CreateMutex(NULL, FALSE, NULL)));
#else
                        EstEID_log("creating pinpad worker thread");
                        pinpad_thread_result = -1;
                        FAIL_IF_PTHREAD_ERROR("pthread_mutex_init", pthread_mutex_init(&pinpad_thread_mutex, NULL));
                        FAIL_IF_PTHREAD_ERROR("pthread_cond_init", pthread_cond_init(&pinpad_thread_condition, NULL));
                        pthread_t pinpad_thread;
                        EstEID_PINPadThreadData threadData;
                        threadData.session = session;
                        threadData.result = CKR_OK;
#endif
                        EstEID_log("thread launched");
#ifdef _WIN32
                        /*
                        NB! Due to Firefox for Windows specific behaviour C_Login() is launched from main thread
                        and UI code is running in separate thread if running on Windows.
                        */
                        pinPromptDataEx.pinPromptData = pinPromptData;
                        pinPromptDataEx.message = message;
                        pinPromptDataEx.name = name;
                        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&EstEID_pinPadLogin, (LPVOID)&pinPromptDataEx, 0, NULL);
                        loginResult = fl->C_Login(session, CKU_USER, NULL, 0);
                        //closePinPadModalSheet();
#else
                        FAIL_IF_PTHREAD_ERROR("pthread_create", pthread_create(&pinpad_thread, NULL, EstEID_pinPadLogin, (void*)&threadData));
                        pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, 0, isPinPad);
                        loginResult = threadData.result;
#endif
                        EstEID_log("pinpad sheet/dialog closed");
                        if (loginResult == CKR_FUNCTION_CANCELED) {
                                setUserCancelErrorCodeAndMessage();
                                CLOSE_SESSION_AND_RETURN(FAILURE);
                        }
                }
                EstEID_log("loginResult = %s", pkcs11_error_message(loginResult));
                switch (loginResult) {
                        case CKR_PIN_LOCKED:
                                blocked = TRUE;
                        case CKR_PIN_INCORRECT:
                remainingTries--;
                        case CKR_PIN_INVALID:
                        case CKR_PIN_LEN_RANGE:
                                EstEID_log("this was attempt %i, loginResult causes to run next round", attempt);
                                continue;
                        default:
                                if (EstEID_CK_failure("C_Login", loginResult)) CLOSE_SESSION_AND_RETURN(FAILURE);
                }
                break; // Login successful - correct PIN supplied
        }

        return EstEID_RealSign(session, signature, signatureLength, hash, hashLength, name, privateKeyIndex);
}


int EstEID_RealSign(CK_SESSION_HANDLE session, char **signature, unsigned int *signatureLength, const char *hash, unsigned int hashLength, char* name, unsigned int privateKeyIndex) {
        CK_ULONG objectCount;
        unsigned int hashWithPaddingLength = 0;
        char *hashWithPadding;
        CK_MECHANISM mechanism = {CKM_RSA_PKCS, 0, 0};
        CK_OBJECT_CLASS objectClass = CKO_PRIVATE_KEY;
        CK_ATTRIBUTE searchAttribute = {CKA_CLASS, &objectClass, sizeof(objectClass)};

    unsigned int max = privateKeyIndex + 1;
    CK_OBJECT_HANDLE privateKeyHandle[max];

        if (EstEID_CK_failure("C_FindObjectsInit", fl->C_FindObjectsInit(session, &searchAttribute, 1))) CLOSE_SESSION_AND_RETURN(FAILURE);

        if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, privateKeyHandle, max, &objectCount))) CLOSE_SESSION_AND_RETURN(FAILURE);
        if (EstEID_CK_failure("C_FindObjectsFinal", fl->C_FindObjectsFinal(session))) CLOSE_SESSION_AND_RETURN(FAILURE);

        if (objectCount == 0) CLOSE_SESSION_AND_RETURN(FAILURE); // todo ?? set error message
    EstEID_log("found %i private keys in slot, using key in position %i", objectCount, privateKeyIndex);

    if (EstEID_CK_failure("C_SignInit", fl->C_SignInit(session, &mechanism, privateKeyHandle[privateKeyIndex]))) CLOSE_SESSION_AND_RETURN(FAILURE);

        hashWithPadding = EstEID_addPadding(hash, hashLength, &hashWithPaddingLength);
        if (hashWithPadding) { // This is additional safeguard, as digest length is checked already before calling EstEID_addPadding()
                CK_ULONG len;
                if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, NULL, &len))) {
                        free(hashWithPadding);
                        CLOSE_SESSION_AND_RETURN(FAILURE);
                }
                *signature = (char *)malloc(len);
                if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, (CK_BYTE_PTR) * signature, &len))) {
                        free(hashWithPadding);
                        CLOSE_SESSION_AND_RETURN(FAILURE);
                }
                *signatureLength = len;
                free(hashWithPadding);
        }

        if (session) {
                if (EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))) {
                        return FAILURE;
                }
        }

        if(name) {
                free(name);
        }

        if (!hashWithPaddingLength) { // This is additional safeguard, as digest length is checked already before calling EstEID_addPadding()
                EstEID_log("will not sign due to incorrect incoming message digest length");
                return FAILURE;
        }
        EstEID_log("successfully signed");
        return SUCCESS;
}



Last modified 7 years ago Last modified on May 3, 2017, 10:37:23 AM

Attachments (1)

Download all attachments as: .zip