Index: signHash/cryptotoken.cpp
===================================================================
--- signHash/cryptotoken.cpp	(revision 0f7c727c0d57693908ed558bf64f6b0bdc9e6606)
+++ signHash/cryptotoken.cpp	(revision f626f58c237e35cbbd3875f861e5cc047dc63313)
@@ -3,4 +3,12 @@
 #include <assert.h>
 #include <iostream>
+#include <stdexcept>
+
+#define BINARY_SHA1_LENGTH 20
+#define BINARY_SHA224_LENGTH 28
+#define BINARY_SHA256_LENGTH 32
+#define BINARY_SHA384_LENGTH 48
+#define BINARY_SHA512_LENGTH 64
+
 
 CryptoToken::CryptoToken()
@@ -257,5 +265,5 @@
 
     // definicion del algoritmo de firma
-    CK_MECHANISM signMechanism = { CKM_SHA1_RSA_PKCS, NULL_PTR, 0};
+    CK_MECHANISM signMechanism = { CKM_RSA_PKCS /*CKM_SHA1_RSA_PKCS*/, 0 /*NULL_PTR*/, 0};
 
     rv = C_SignInit(hSession, &signMechanism, privateKey);
@@ -305,4 +313,152 @@
 
 }
+
+
+std::vector<unsigned char> CryptoToken::signHash(QString hashToSign, QString pin, QString label)
+{
+
+    std::vector<unsigned char> hash = fromHex(hashToSign);
+
+    QString error("");
+    CK_RV rv;
+
+    CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
+    CK_SLOT_ID slotID;
+
+    // initialize criptoki
+    rv = C_Initialize(NULL_PTR);
+    if (rv != CKR_OK)
+    {
+        if (rv == CKR_DEVICE_ERROR)
+        {
+            error = returnErrorToQString(rv);
+            qDebug(qPrintable(error));
+            throw std::runtime_error(qPrintable(error));
+        }
+        error = returnErrorToQString(rv);
+        qDebug(qPrintable(error));
+        throw std::runtime_error(qPrintable(error));
+    }
+
+    hSession = openSession((char *) qPrintable(pin), slotID);
+    if (hSession == CK_INVALID_HANDLE)
+    {
+        qDebug("Fallo ptr_SC->openSession");
+        rv = C_Finalize(NULL_PTR);
+        qDebug("C_Finalize: rv = %x",rv);
+        assert(rv == CKR_OK);
+        throw std::runtime_error("Error openning a session");
+    }
+
+    // obtencion de la clave privada para firmar los datos
+    CK_OBJECT_HANDLE privateKey = CK_INVALID_HANDLE;
+
+    //QString label = "New Key aaraujo";
+    privateKey = getPrivateKey(hSession, slotID, label);
+
+    // https://github.com/open-eid/chrome-token-signing/blob/master/host-shared/PKCS11CardManager.h
+
+    if (privateKey == CK_INVALID_HANDLE)
+    {
+        qDebug("Fallo ptr_SC->getPrivateKey");
+        rv = C_CloseSession(hSession);
+        qDebug("C_CloseSession: rv = %x",rv);
+        assert(rv == CKR_OK);
+        rv = C_Finalize(NULL_PTR);
+        qDebug("C_Finalize: rv = %x",rv);
+        assert(rv == CKR_OK);
+        throw std::runtime_error("Error finding private key");
+    }
+
+    CK_MECHANISM mechanism = {CKM_RSA_PKCS, 0, 0};
+
+
+    rv = C_SignInit(hSession, &mechanism, privateKey);
+
+    if (rv != CKR_OK) {
+        qDebug("C_SignInit: rv = 0x%.8X\n", rv);
+        rv = C_CloseSession(hSession);
+        qDebug ("C_CloseSession: rv = %x",rv);
+        qDebug ("\n");
+        assert(rv == CKR_OK);
+        rv = C_Finalize(NULL_PTR);
+        qDebug ("C_Finalize: rv = %x",rv);
+        qDebug ("\n");
+        assert(rv == CKR_OK);
+        throw std::runtime_error("Error C_SignInit");
+    }
+
+    qDebug("C_SignInit: rv = 0x%.8X\n", rv);
+    qDebug ("\n");
+    assert(rv==CKR_OK);
+
+    std::vector<unsigned char> hashWithPadding;
+    switch (hash.size()) {
+        case BINARY_SHA1_LENGTH:
+            hashWithPadding = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
+            break;
+        case BINARY_SHA224_LENGTH:
+            hashWithPadding = {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c};
+            break;
+        case BINARY_SHA256_LENGTH:
+            hashWithPadding = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
+            break;
+        case BINARY_SHA384_LENGTH:
+            hashWithPadding = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
+            break;
+        case BINARY_SHA512_LENGTH:
+            hashWithPadding = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
+            break;
+        default:
+            throw std::runtime_error("incorrect digest length, dropping padding");
+    }
+    hashWithPadding.insert(hashWithPadding.end(), hash.begin(), hash.end());
+
+    CK_ULONG signatureLength = 0;
+
+
+    rv = C_Sign(hSession, hashWithPadding.data(), hashWithPadding.size(), nullptr, &signatureLength);
+
+    if (rv != CKR_OK) {
+        qDebug("C_Sign: rv = 0x%.8X\n", rv);
+        rv = C_CloseSession(hSession);
+        qDebug ("C_CloseSession: rv = %x",rv);
+        qDebug ("\n");
+        assert(rv == CKR_OK);
+        rv = C_Finalize(NULL_PTR);
+        qDebug ("C_Finalize: rv = %x",rv);
+        qDebug ("\n");
+        assert(rv == CKR_OK);
+        throw std::runtime_error("Error C_Sign1");
+    }
+
+    std::vector<unsigned char> signature(signatureLength, 0);
+
+    rv = C_Sign(hSession, hashWithPadding.data(), hashWithPadding.size(), signature.data(), &signatureLength);
+
+    if (rv != CKR_OK) {
+        qDebug("C_Sign: rv = 0x%.8X\n", rv);
+        rv = C_CloseSession(hSession);
+        qDebug ("C_CloseSession: rv = %x",rv);
+        qDebug ("\n");
+        assert(rv == CKR_OK);
+        rv = C_Finalize(NULL_PTR);
+        qDebug ("C_Finalize: rv = %x",rv);
+        qDebug ("\n");
+        assert(rv == CKR_OK);
+        throw std::runtime_error("Error C_Sign2");
+    }
+
+
+    qDebug("C_Sign: rv = 0x%.8X\n", rv);
+    qDebug ("\n");
+    assert(rv==CKR_OK);
+
+    closeSession(hSession);
+
+    return signature;
+
+}
+
 
 // slot para obtener informacion del modulo PKCS11
@@ -695,2 +851,14 @@
     return x;
 }
+
+
+QByteArray CryptoToken::toHex(const std::vector<unsigned char> &data)
+{
+    return QByteArray((const char*)data.data(), data.size()).toHex();
+}
+
+std::vector<unsigned char> CryptoToken::fromHex(const QString &data)
+{
+    QByteArray bin = QByteArray::fromHex(data.toLatin1());
+    return std::vector<unsigned char>(bin.constData(), bin.constData() + bin.size());
+}
