/*! @file

    @id $Id$
*/
//       1         2         3         4         5         6         7         8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890

#ifndef __QBROWSERLIB_CERTS_HXX__
#define __QBROWSERLIB_CERTS_HXX__

#include <cryptoki.hxx>
#include <QtCore/QList>
#include <QtNetwork/QSslCertificate>

namespace qbrowserlib {

  extern const QString LIBNAME;

  //! Access certificate information from cryptoki library.
  /*! Advice: Keep one instance per executable, because library is
      loaded, instanciated and unloaded on each object creation or
      deletion. */
  class Certs {
      
    public:

      //! Initialize cryptoki library.
      /*! Advice: Keep one instance per executable, because library is
          loaded, instanciated and unloaded on each object creation or
          deletion.
          
          @throws throws std::exception in case of error */
      Certs(const QString& lib = LIBNAME): _cryptoki(lib.toStdString()) {}

      //! Get a list of authentification certificates.
      /*! @throws throws std::exception in case of error */
      QList<QSslCertificate> auth() {
        QList<QSslCertificate> authCerts;
        cryptoki::SlotList slotlist(_cryptoki.slotList());
        for (cryptoki::SlotList::iterator slot(slotlist.begin());
             slot!=slotlist.end(); ++slot) {
          cryptoki::Session session(*slot);
          cryptoki::ObjectList certs(session.find
                                     (cryptoki::Attribute(CKA_CLASS)
                                      .from<CK_OBJECT_CLASS>(CKO_CERTIFICATE)));
          for (cryptoki::ObjectList::iterator cert(certs.begin());
               cert!=certs.end(); ++cert) {
            cryptoki::Attribute label(cert->attribute(CKA_LABEL));
            if (label.value.find("auth")==0 ||
                label.value.find("Authentication")!=std::string::npos) {
              std::string data(cert->attribute(CKA_VALUE).value);
              authCerts.push_back(QSslCertificate(QByteArray(data.data(),
                                                             data.size()),
                                                  QSsl::Der));
            }
          }
        }
        return authCerts;
      }
      
    private:
      
      cryptoki::Init _cryptoki;
      
  };
  
}
#endif
