/* Copyright (C) 2003 Frédéric Giudicelli (contact_nos@yahoo.com). All rights reserved. This product includes cryptographic software written by Eric Young (eay@cryptsoft.com) This program is released under the GPL with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // NewPKIStore.h: interface for the NewPKIStore class. // ////////////////////////////////////////////////////////////////////// #ifndef NEWPKISTORE_H #define NEWPKISTORE_H #include #include #include #include #include #include #include "SQL/SQL_Conn.h" #include "EntityLog.h" #include "MailInfo.h" #include "AsynchJobs.h" #include "NewPKIStore_ASN1.h" class AsynchJobs; /*! This class holds the basic functionnalities for a requester and a responder */ class NewPKIStore { public: /*! \brief This is the constructor. * \param EntityName [IN] The name of the entity. * \param e [IN] The ENGINE, can be NULL. * \param Type [IN] The type. */ NewPKIStore(const mString & EntityName, ENGINE * e, unsigned long Type); /*! \brief This is the destructor. */ virtual ~NewPKIStore(); /*! \brief This function returns the type of store. * \return The type of store. */ unsigned long get_Type(); /*! \brief Checks if the mailer is up and running. * \return true on success, false on failure. */ bool MailerIsUp(); /*! \brief This function creates the tables needed to work. * \param DbConn [IN] A SQL connection. * \return true on success, false on failure. */ virtual bool CreateTables(const SQL_Connection * DbConn)=0; /*! \brief This function sets the AsynchJobs instance, used to send emails. * \param Jobs [IN] The AsynchJobs instance. */ void set_Jobs(AsynchJobs * Jobs); /*! \brief This function converts binary datas to a string. * \param datas [IN] The binary datas. * \param len [IN] The binary datas length. * \param strId [OUT] The result string. * \return true on success, false on failure. */ static bool BINARYtoString(const unsigned char * datas, int len, mString &strId); /*! \brief This function converts a string to binary datas. * \param strId [IN] The string. * \param len [OUT] The binary datas length. * \return The binary datas or NULL on failure. */ static unsigned char * StringtoBINARY(const mString & strId, int & len); /*! \brief This function converts a ASN1_BIT_STRING to a string. * \param bit [IN] The ASN1_BIT_STRING. * \param strId [OUT] The result string. * \return true on success, false on failure. */ static bool ASN1_BIT_STRINGtoString(const ASN1_BIT_STRING * bit, mString &strId); /*! \brief This function converts a string to a ASN1_BIT_STRING. * \param strId [IN] The string. * \return The ASN1_BIT_STRING or NULL on failure. */ static ASN1_BIT_STRING * StringtoASN1_BIT_STRING(const mString & strId); /*! \brief This function converts a string to a Asn1OctetString. * \param strId [IN] The string. * \param transactionID [OUT] The result Asn1OctetString. * \return true on success, false on failure. */ static bool StringtoTransactionID(const mString & strId, Asn1OctetString & transactionID); /*! \brief This function converts a Asn1OctetString to a string. * \param transactionID [IN] The Asn1OctetString. * \param strId [OUT] The result string. * \return true on success, false on failure. */ static bool transactionIDtoString(const Asn1OctetString & transactionID, mString & strId); /*! \brief This function converts an EVP_PKEY to a hash string. * \param pubKey [IN] The EVP_PKEY. * \param strKey [OUT] The result string. * \return true on success, false on failure. */ static bool EVP_PKEYtoHash(const EVP_PKEY * pubKey, mString &strKey); /*! \brief This function converts a X509_PUBKEY to a hash string. * \param pubKey [IN] The X509_PUBKEY. * \param strKey [OUT] The result string. * \return true on success, false on failure. */ static bool X509_PUBKEYtoHash(const X509_PUBKEY * pubKey, mString &strKey); /*! \brief This function converts Binary a X509_NAME to a hash string. * \param dn [IN] The X509_NAME. * \param strHash [OUT] The result string. * \return true on success, false on failure. */ static bool X509_NAMEtoHash(const X509_NAME * dn, mString &strHash); /*! \brief This function sets the SQL connection. * \param DbConn [IN] A SQL connection. * \return true on success, false on failure. */ bool SetDbConn(const SQL_Connection * DbConn); /*! \brief This function sets the logging class. * \param Logging [IN] The logging class. */ void set_Logging(const EntityLog * Logging); /*! \brief This function sets the certificate of the entity using this class. * \param EntityCert [IN] The certificate of the entity. */ void SetEntityCert(const PKI_CERT & EntityCert); /*! \brief This function is used to get the list of known transactions. * \param transactionIDs [OUT] The transaction Ids. * \return true on success, false on failure. */ bool Responder_GetKnownTIDs(TransactionIds &transactionIDs); /*! \brief This function inserts a new request to be treated. * \param Request [IN] The request. * \return true on success, false on failure. */ bool Responder_InsertRequest(const WorkingRequest & Request); /*! \brief This function returns the requests that haven't been processed yet. * \param Requests [OUT] The un-processed requests. * \return true on success, false on failure. */ bool Responder_GetRequests(mVector & Requests); /*! \brief This function returns the responses that haven't been sent yet. * \param Responses [OUT] The unsent responses. * \param index [IN] The position of datas to send. * \param max [IN] The maximum number of entries to return. * \return true on success, false on failure. */ bool Responder_GetUnsentResponses(mVector & Responses, int index = 0, int max = 0); /*! \brief This function sets a response. * \param Response [IN] The new response. * \return true on success, false on failure. */ bool Responder_SetResponse(const CryptedNewpkiResponse & Response); /*! \brief This function gets a response. * \param TransactionID [IN] The transaction ID. * \param Response [OUT] The response. * \return The response on success, NULL on failure. */ bool Responder_GetResponse(const Asn1OctetString & TransactionID, CryptedNewpkiResponse & Response); /*! \brief This function marks a response as sent. * \param TransactionID [IN] The ID of the sent response. * \return true on success, false on failure. */ bool Responder_ResponseSent(const Asn1OctetString & TransactionID); /*! \brief This function gets the status of a transaction. * \param TransactionID [IN] The transaction ID. * \param Status [OUT] The status of the transaction. * \return true on success, false on failure. */ bool Responder_GetTransactionStatus(const Asn1OctetString & TransactionID, TRANSACTION_STATUS & Status); /*! \brief This function inserts a new request. * \param Request [IN/OUT] The request, the member internalID will be set. * \param priv_attr [IN] A private value used by children. * \return true on success, false on failure. */ bool Requester_InsertRequest(CryptedNewpkiRequest & Request, unsigned long priv_attr); /*! \brief This functions returns the list of requests for which we're expecting a response. * \param transactionIDs [OUT] The un-responded transaction Ids. * \return true on success, false on failure. */ bool Requester_GetWaitingTIDs(TransactionIds &transactionIDs); /*! \brief This function marks the request as sent an assign it the transactionID given by the Respository. * \param req_id [IN] The internal ID of the request. * \return true on success, false on failure. */ bool Requester_RequestSent(unsigned long req_id); /*! \brief This function is used to delete a request. * \param req_id [IN] The internal ID of the request. * \return true on success, false on failure. */ bool Requester_DeleteTransaction(unsigned long req_id); /*! \brief This function is used to delete a request matching priv_attr. * \param priv_attr [IN] A private value used by children. * \return true on success, false on failure. */ bool Requester_DeleteTransactionPrivAttr(unsigned long priv_attr); /*! \brief This function returns the requests that haven't been sent yet. * \param Requests [OUT] The unsent requests. * \param index [IN] The position of datas to send. * \param max [IN] The maximum number of entries to return. * \return true on success, false on failure. */ bool Requester_GetUnsentRequests(mVector & Requests, int index = 0, int max = 0); /*! \brief This function marks a request as having been processed by the responder. * \param TransactionID [IN] The processed request. * \return true on success, false on failure. */ bool Requester_RequestWasResponded(const Asn1OctetString & TransactionID); /*! \brief This function gets the status of a transaction. * \param TransactionID [IN] The transaction ID. * \param Status [OUT] The status of the transaction. * \return true on success, false on failure. */ bool Requester_GetTransactionStatus(const Asn1OctetString & TransactionID, TRANSACTION_STATUS & Status); protected: #define RESPONDER_TABLE "responder" #define REQUESTER_TABLE "requester" #define REQUESTER_PRIV_ATTR "priv_attr" #define REQUESTER_TID "transactionID" #define MAX_TID_LEN SHA_DIGEST_LENGTH mString m_EntityName; const EntityLog * m_Logging; ENGINE * m_Engine; bool SendMail(const mString & Author, const MailInfo & Mail, bool AdminMail); PKI_CERT m_EntityCert; SQL_Connection * m_DbConn; bool GenerateTransactionID(Asn1OctetString & transactionID, const X509_PUBKEY *sender, const X509_PUBKEY *recipient, unsigned long counter); bool CommonCreateTables(const SQL_Connection * DbConn); private: AsynchJobs * m_Jobs; unsigned long m_Type; bool CreateRequester(const SQL_Connection * DbConn); bool CreateResponder(const SQL_Connection * DbConn); #define NEWPKISTORE_CREATE_1 "create table "RESPONDER_TABLE" (req_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, transactionID VARCHAR(41) NOT NULL, status INT UNSIGNED NOT NULL, request LONGBLOB NOT NULL, response LONGBLOB NOT NULL, INDEX (transactionID), INDEX(status));" #define NEWPKISTORE_CREATE_2 "create table "REQUESTER_TABLE" (req_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, "REQUESTER_TID" VARCHAR(41) NOT NULL, "REQUESTER_PRIV_ATTR" INT UNSIGNED NOT NULL, status INT UNSIGNED NOT NULL, request LONGBLOB NOT NULL, INDEX ("REQUESTER_TID"), INDEX(status));" #define RESPONDER_NEWPKISTORE_INSERT_REQ "INSERT INTO "RESPONDER_TABLE" (transactionID, status, request, response) VALUES ('%s', %d, '%s', '');" #define RESPONDER_NEWPKISTORE_GET_TIDS "SELECT transactionID FROM "RESPONDER_TABLE" WHERE status <> %d;" #define RESPONDER_NEWPKISTORE_SET_RESPONSE "UPDATE "RESPONDER_TABLE" SET status='%d', response='%s', request='' WHERE transactionID='%s';" #define RESPONDER_NEWPKISTORE_GET_RESPONSE "SELECT response FROM "RESPONDER_TABLE" WHERE transactionID='%s';" #define RESPONDER_NEWPKISTORE_SET_STATUS "UPDATE "RESPONDER_TABLE" SET status='%d', response='' WHERE transactionID='%s';" #define RESPONDER_NEWPKISTORE_GET_REQS_BY_STATE "SELECT request FROM "RESPONDER_TABLE" WHERE status='%d' ORDER BY req_id DESC LIMIT 5;" #define RESPONDER_NEWPKISTORE_GET_RESP_BY_STATE "SELECT response FROM "RESPONDER_TABLE" WHERE status='%d' ORDER BY req_id ASC %s;" #define RESPONDER_NEWPKISTORE_GET_TID_STATUS "SELECT status FROM "RESPONDER_TABLE" WHERE transactionID='%s';" #define REQUESTER_NEWPKISTORE_INSERT_REQ "INSERT INTO "REQUESTER_TABLE" ("REQUESTER_TID", status, "REQUESTER_PRIV_ATTR") VALUES ('', %d, '%ld');" #define REQUESTER_NEWPKISTORE_SET_REQ "UPDATE "REQUESTER_TABLE" SET "REQUESTER_TID"='%s', request='%s' WHERE req_id='%ld';" #define REQUESTER_NEWPKISTORE_GET_TIDS_BY_STATE "SELECT "REQUESTER_TID" FROM "REQUESTER_TABLE" WHERE status='%d' ORDER BY req_id ASC LIMIT 0,20;" #define REQUESTER_NEWPKISTORE_SET_SENT "UPDATE "REQUESTER_TABLE" SET status='%d', request='' WHERE req_id='%ld';" #define REQUESTER_NEWPKISTORE_SET_TID_STATUS "UPDATE "REQUESTER_TABLE" SET status='%d' WHERE "REQUESTER_TID"='%s';" #define REQUESTER_NEWPKISTORE_DELETE_REQ "DELETE FROM "REQUESTER_TABLE" WHERE req_id='%ld';" #define REQUESTER_NEWPKISTORE_GET_REQS_BY_STATE "SELECT req_id, request FROM "REQUESTER_TABLE" WHERE status='%d' ORDER BY req_id ASC %s;" #define REQUESTER_NEWPKISTORE_SET_REQ_STATE "UPDATE "REQUESTER_TABLE" SET status='%d' WHERE "REQUESTER_TID"='%s';" #define REQUESTER_NEWPKISTORE_DELETE_REQ_PRIV_ATTR "DELETE FROM "REQUESTER_TABLE" WHERE "REQUESTER_PRIV_ATTR"='%ld';" #define REQUESTER_NEWPKISTORE_GET_TID_STATUS "SELECT status FROM "REQUESTER_TABLE" WHERE transactionID='%s';" }; #endif