References #2
This commit is contained in:
BIN
Sample_Executables/Win32/engine_act.dll
Normal file
BIN
Sample_Executables/Win32/engine_act.dll
Normal file
Binary file not shown.
108
openssl-act-engine/CardKey.cpp
Normal file
108
openssl-act-engine/CardKey.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
|
||||||
|
#include "CardKey.h"
|
||||||
|
#include "SecOpGuard.h"
|
||||||
|
|
||||||
|
#include <actITokenKey.h>
|
||||||
|
#include <actIToken.h>
|
||||||
|
#include <actDebug.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
CardKey::CardKey(act::ITokenKey* key)
|
||||||
|
: m_token_key(key)
|
||||||
|
{
|
||||||
|
ACT_ASSERT(key != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardKey::~CardKey()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardKey::setPin(char *pin)
|
||||||
|
{
|
||||||
|
int plen = strlen(pin);
|
||||||
|
act::Blob(pin, pin+plen).swap(m_pin);
|
||||||
|
std::fill(pin, pin+plen, '*'); // Whiten out the source contents as soon as the PIN is in our domain
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardKey::setPin(const act::Blob& pin)
|
||||||
|
{
|
||||||
|
m_pin = pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardKey::setPin(UI_METHOD *ui_method, void *callback_data)
|
||||||
|
{
|
||||||
|
int maxlen=200;
|
||||||
|
std::vector<char> buf(maxlen+1);
|
||||||
|
char* buffer = &buf[0];
|
||||||
|
|
||||||
|
UI *ui;
|
||||||
|
struct mycb_t {
|
||||||
|
const char *password;
|
||||||
|
const char *prompt_info;
|
||||||
|
} *mycb;
|
||||||
|
|
||||||
|
mycb = reinterpret_cast<mycb_t*>(callback_data);
|
||||||
|
|
||||||
|
/* pin in the call back data, copy and use */
|
||||||
|
if (mycb != NULL && mycb->password) {
|
||||||
|
act::Blob(mycb->password, mycb->password+strlen(mycb->password)).swap(m_pin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call ui to ask for a pin */
|
||||||
|
ui = UI_new();
|
||||||
|
if (ui_method != NULL)
|
||||||
|
UI_set_method(ui, ui_method);
|
||||||
|
if (callback_data != NULL)
|
||||||
|
UI_set_app_data(ui, callback_data);
|
||||||
|
|
||||||
|
// Fall back to an own, quite meaningless, prompt if we aren't provided one.
|
||||||
|
const char *prompt_info = (mycb && mycb->prompt_info) ? mycb->prompt_info : "Token PIN: ";
|
||||||
|
|
||||||
|
if (!UI_add_input_string
|
||||||
|
(ui, prompt_info, 0, buffer, 1, maxlen)) {
|
||||||
|
fprintf(stderr, "UI_add_input_string failed\n");
|
||||||
|
UI_free(ui);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (UI_process(ui)) {
|
||||||
|
fprintf(stderr, "UI_process failed\n");
|
||||||
|
UI_free(ui);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
act::Blob(buffer, buffer+strlen(buffer)).swap(m_pin);
|
||||||
|
UI_free(ui);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardKey::Authenticate(SecOpGuard& where)
|
||||||
|
{
|
||||||
|
// We assume to get along without a PIN. If the security operation fails we'll see early enough.
|
||||||
|
if(m_pin.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
act::ITokenPIN* token_pin = m_token_key->GetPin();
|
||||||
|
|
||||||
|
// Fall back to token's User PIN if nothing else given
|
||||||
|
if(token_pin == NULL)
|
||||||
|
{
|
||||||
|
act::IToken* token = m_token_key->GetToken();
|
||||||
|
|
||||||
|
ACT_ASSERT(token != NULL);
|
||||||
|
|
||||||
|
token_pin = token->GetUserPin();
|
||||||
|
}
|
||||||
|
|
||||||
|
ACT_ASSERT(token_pin != NULL);
|
||||||
|
|
||||||
|
bool result = where.Authenticate(token_pin, m_pin);
|
||||||
|
|
||||||
|
// TODO: UP FOR DISCUSSION: PIN has been used up, erase it? Or keep it as long as the key itself?
|
||||||
|
// m_pin.clear();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
46
openssl-act-engine/CardKey.h
Normal file
46
openssl-act-engine/CardKey.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef __CARDKEY_H__
|
||||||
|
#define __CARDKEY_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <actBlob.h>
|
||||||
|
|
||||||
|
//#include <openssl/crypto.h>
|
||||||
|
//#include <openssl/objects.h>
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
class ITokenKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retains a single RSA key pair and (maybe) the provided PIN which is used to authenticate for usage of
|
||||||
|
* this key
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SecOpGuard;
|
||||||
|
|
||||||
|
class CardKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CardKey(act::ITokenKey* token_key);
|
||||||
|
~CardKey();
|
||||||
|
|
||||||
|
inline act::ITokenKey* getKey() const { return m_token_key.get(); }
|
||||||
|
|
||||||
|
// NOTE: Contents of source string will be overwritten for security reasons
|
||||||
|
void setPin(char *pin);
|
||||||
|
void setPin(const act::Blob& pin);
|
||||||
|
void setPin(UI_METHOD *ui_method, void *callback_data);
|
||||||
|
|
||||||
|
bool Authenticate(SecOpGuard& where);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::auto_ptr<act::ITokenKey> m_token_key;
|
||||||
|
act::Blob m_pin;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
144
openssl-act-engine/CardObject.cpp
Normal file
144
openssl-act-engine/CardObject.cpp
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
|
||||||
|
#include <actITokenKey.h>
|
||||||
|
#include <actIToken.h>
|
||||||
|
#include <actISlot.h>
|
||||||
|
#include <actUtility.h>
|
||||||
|
#include <actDebug.h>
|
||||||
|
#include <actMode.h>
|
||||||
|
#include <actCertificate.h>
|
||||||
|
|
||||||
|
#include "CardObject.h"
|
||||||
|
#include "SlotList.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
CardObject::CardObject(SlotList *sl)
|
||||||
|
: m_search_type(0)
|
||||||
|
, m_selected_token(NULL)
|
||||||
|
, m_found_key(NULL)
|
||||||
|
, m_slot_list(sl)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CardObject::~CardObject()
|
||||||
|
{
|
||||||
|
// We keep ownership of the token object itself but we're expected to pawn off the resulting key
|
||||||
|
// or certificate object we find.
|
||||||
|
if(m_selected_token)
|
||||||
|
m_selected_token->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardObject::searchFor(int searchType, const char *s_key_id)
|
||||||
|
{
|
||||||
|
// Only one successful search operation allowed
|
||||||
|
ACT_ASSERT(m_selected_token == NULL);
|
||||||
|
|
||||||
|
if(m_selected_token != NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string key_id_string(s_key_id);
|
||||||
|
|
||||||
|
act::ISlot* selected_slot = NULL;
|
||||||
|
act::ITokenKey* selected_key = NULL;
|
||||||
|
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
// Slot selection: Currently only "slot_<decimalno>" supported
|
||||||
|
if(key_id_string.substr(pos,5) == "slot-")
|
||||||
|
{
|
||||||
|
pos += 5;
|
||||||
|
size_t slot_num = 0;
|
||||||
|
|
||||||
|
while(pos < key_id_string.length() && key_id_string[pos] >= '0' && key_id_string[pos] <= '9')
|
||||||
|
slot_num = slot_num * 10 + (key_id_string[pos++] - '0');
|
||||||
|
|
||||||
|
m_selected_token = m_slot_list->getToken(slot_num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Bail out if the selected slot is a dud.
|
||||||
|
if(!m_selected_token)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Key (or cert) selection with "id_<hexid>"
|
||||||
|
if(key_id_string.substr(pos,4) == "-id-")
|
||||||
|
{
|
||||||
|
pos += 4;
|
||||||
|
act::Blob id_blob;
|
||||||
|
|
||||||
|
act::hex2blob(key_id_string.substr(pos).c_str()).swap(id_blob);
|
||||||
|
|
||||||
|
if(searchType != act::CERTIFICATE)
|
||||||
|
{
|
||||||
|
for(int i=m_selected_token->GetKeyNumber();i--;)
|
||||||
|
{
|
||||||
|
act::ITokenKey* key = dynamic_cast<act::ITokenKey*>(m_selected_token->GetKey(i));
|
||||||
|
|
||||||
|
if(key == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(key->GetType() != act::KEY_RSA || key->GetID() != id_blob)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Found it, deposit a copy for the caller's retrieval
|
||||||
|
m_found_key = key->Clone();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i=m_selected_token->GetCertificateNumber();i--;)
|
||||||
|
{
|
||||||
|
act::CertEntry ce(m_selected_token->GetCertificate(i));
|
||||||
|
|
||||||
|
std::auto_ptr<act::Certificate> cert(new act::Certificate("X509", ce.certblob));
|
||||||
|
|
||||||
|
if(cert.get() == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
act::Blob serno;
|
||||||
|
cert->GetParam(act::SERIALNR, serno);
|
||||||
|
|
||||||
|
if(serno != id_blob)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Else we found what we're looking for, deposit a pointer for the caller's retrieval
|
||||||
|
m_found_certificate = ce.certblob;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(key_id_string.substr(pos,6) == "-name-") // Key selection with "name-<keyname>"
|
||||||
|
{
|
||||||
|
pos += 6;
|
||||||
|
|
||||||
|
std::string name(key_id_string.substr(pos));
|
||||||
|
|
||||||
|
ACT_ASSERT(searchType != act::CERTIFICATE);
|
||||||
|
|
||||||
|
for(int i=m_selected_token->GetKeyNumber();i--;)
|
||||||
|
{
|
||||||
|
act::ITokenKey* key = dynamic_cast<act::ITokenKey*>(m_selected_token->GetKey(i));
|
||||||
|
|
||||||
|
if(key == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(key->GetType() != act::KEY_RSA || name != key->GetName())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Found it, deposit a copy for the caller's retrieval
|
||||||
|
m_found_key = key->Clone();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
40
openssl-act-engine/CardObject.h
Normal file
40
openssl-act-engine/CardObject.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
#ifndef __CARDOBJECT_H__
|
||||||
|
#define __CARDOBJECT_H__
|
||||||
|
|
||||||
|
#include <actBlob.h>
|
||||||
|
|
||||||
|
class SlotList;
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
class IToken;
|
||||||
|
class ITokenKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Provides the search functionality over slots and keys
|
||||||
|
*/
|
||||||
|
class CardObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CardObject(SlotList *sl);
|
||||||
|
~CardObject();
|
||||||
|
|
||||||
|
// act::PRIVATEKEY, act::PUBLICKEY or act::CERTIFICATE
|
||||||
|
bool searchFor(int searchType, const char *s_key_id);
|
||||||
|
|
||||||
|
inline act::ITokenKey* getKey() const { return m_found_key; }
|
||||||
|
inline const act::Blob& getCertBlob() const { return m_found_certificate; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_search_type;
|
||||||
|
act::IToken* m_selected_token;
|
||||||
|
act::ITokenKey* m_found_key;
|
||||||
|
act::Blob m_found_certificate;
|
||||||
|
SlotList* m_slot_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
179
openssl-act-engine/CertificateList.cpp
Normal file
179
openssl-act-engine/CertificateList.cpp
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
|
||||||
|
#include "engine_sct.h"
|
||||||
|
#include "CertificateList.h"
|
||||||
|
#include "SlotList.h"
|
||||||
|
#include "SecOpGuard.h"
|
||||||
|
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
|
||||||
|
#ifdef U64
|
||||||
|
#undef U64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <actUtility.h>
|
||||||
|
#include <actITokenKey.h>
|
||||||
|
#include <actIToken.h>
|
||||||
|
#include <actISlot.h>
|
||||||
|
#include <actDebug.h>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
CertificateList::CertificateList()
|
||||||
|
: m_num_certs(0)
|
||||||
|
, m_enum_list(NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CertificateList::~CertificateList()
|
||||||
|
{
|
||||||
|
release_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CertificateList::release_list()
|
||||||
|
{
|
||||||
|
if(m_enum_list == NULL) return;
|
||||||
|
|
||||||
|
enum_cert_s* cert_p = m_enum_list->certificate;
|
||||||
|
|
||||||
|
// Can only happen if someone tampered with the returned structure.
|
||||||
|
ACT_ASSERT(m_num_certs == m_enum_list->num_certs);
|
||||||
|
|
||||||
|
// No matter, we just use our value in any case.
|
||||||
|
for(int i=m_num_certs;i--;)
|
||||||
|
{
|
||||||
|
free((void *)cert_p[i].id);
|
||||||
|
free((void *)cert_p[i].name);
|
||||||
|
X509_free(cert_p[i].cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(m_enum_list);
|
||||||
|
m_enum_list = NULL;
|
||||||
|
m_num_certs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CertificateList::init(SlotList& slots)
|
||||||
|
{
|
||||||
|
cert_map_t cert_temp_map;
|
||||||
|
|
||||||
|
|
||||||
|
for(size_t i=slots.getNumSlots();i--;)
|
||||||
|
{
|
||||||
|
act::IToken* token = slots.getToken(i);
|
||||||
|
|
||||||
|
if(!token)
|
||||||
|
continue;
|
||||||
|
{
|
||||||
|
// Needs to be transacted
|
||||||
|
SecOpGuard guard(token);
|
||||||
|
|
||||||
|
// Iterate over the certificates on the token, adding them with empty ID
|
||||||
|
for(int j=token->GetCertificateNumber();j--;)
|
||||||
|
{
|
||||||
|
act::CertEntry ce(token->GetCertificate(j));
|
||||||
|
|
||||||
|
cert_tmp_s temp;
|
||||||
|
temp.slot_number = i;
|
||||||
|
|
||||||
|
cert_temp_map[ce.certblob] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over the keys and insert their ID's into the corresponding certificates
|
||||||
|
for(int j=token->GetKeyNumber();j--;)
|
||||||
|
{
|
||||||
|
act::ITokenKey* key = dynamic_cast<act::ITokenKey*>(token->GetKey(j));
|
||||||
|
|
||||||
|
if(key == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
act::Blob certblob(key->GetCertificate());
|
||||||
|
|
||||||
|
cert_map_t::iterator it = cert_temp_map.find(certblob);
|
||||||
|
|
||||||
|
// Sort key ID into the certificate data if found
|
||||||
|
if(it != cert_temp_map.end())
|
||||||
|
{
|
||||||
|
it->second.name = key->GetName();
|
||||||
|
it->second.id = key->GetID();
|
||||||
|
}
|
||||||
|
// What about keypairs without a certificate? We could add entries with no certs...?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
token->Destroy();
|
||||||
|
|
||||||
|
}
|
||||||
|
// Now we have a map of all certificates. Those with IDs are connected to a keypair, those without
|
||||||
|
// are just stored on the card, probably CA certificates or somesuch.
|
||||||
|
|
||||||
|
m_num_certs = cert_temp_map.size();
|
||||||
|
|
||||||
|
ACT_ASSERT(m_enum_list == NULL);
|
||||||
|
|
||||||
|
// Allocate the needed memory to hold the structure heading plus the certificate pointers themselves
|
||||||
|
m_enum_list = reinterpret_cast<enum_certs_s*>(
|
||||||
|
malloc(sizeof(enum_certs_s) + m_num_certs * sizeof(enum_cert_s)));
|
||||||
|
|
||||||
|
// Bail out if we can't allocate.
|
||||||
|
if(!m_enum_list)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_enum_list->num_certs = m_num_certs;
|
||||||
|
enum_cert_s* cert_p = &m_enum_list->certificate[0];
|
||||||
|
|
||||||
|
// Now place the decoded certificates and key id's (if applicable) into a neat structure.
|
||||||
|
for(cert_map_t::const_iterator it = cert_temp_map.begin(); it != cert_temp_map.end();++it)
|
||||||
|
{
|
||||||
|
const act::Blob& certblob = it->first;
|
||||||
|
const unsigned char *cbp = &certblob[0];
|
||||||
|
|
||||||
|
cert_p->cert = d2i_X509(NULL, &cbp, certblob.size());
|
||||||
|
|
||||||
|
const cert_tmp_s& id_tmp = it->second;
|
||||||
|
|
||||||
|
cert_p->id = NULL;
|
||||||
|
if(!id_tmp.id.empty())
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << "slot-" << id_tmp.slot_number << "-id-" << act::blob2hex(id_tmp.id);
|
||||||
|
|
||||||
|
std::string id_str(ss.str());
|
||||||
|
|
||||||
|
size_t len = id_str.length();
|
||||||
|
const char *src_p = id_str.c_str();
|
||||||
|
char *p = reinterpret_cast<char *>(malloc(len+1 * sizeof(char)));
|
||||||
|
if(p)
|
||||||
|
{
|
||||||
|
p[len]=0;
|
||||||
|
std::copy(src_p, src_p+len, p);
|
||||||
|
cert_p->id = (const char *)p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cert_p->name = NULL;
|
||||||
|
if(!id_tmp.name.empty())
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << "slot-" << id_tmp.slot_number << "-name-" << id_tmp.name;
|
||||||
|
std::string name_str(ss.str());
|
||||||
|
size_t len = name_str.length();
|
||||||
|
const char *src_p = name_str.c_str();
|
||||||
|
char *p = reinterpret_cast<char *>(malloc(len+1 * sizeof(char)));
|
||||||
|
if(p)
|
||||||
|
{
|
||||||
|
p[len]=0;
|
||||||
|
std::copy(src_p, src_p+len, p);
|
||||||
|
cert_p->name = (const char *)p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cert_p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
40
openssl-act-engine/CertificateList.h
Normal file
40
openssl-act-engine/CertificateList.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef __CERTIFICATELIST_H__
|
||||||
|
#define __CERTIFICATELIST_H__
|
||||||
|
|
||||||
|
#include <actBlob.h>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct enum_certs_s;
|
||||||
|
class SlotList;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Builds up and owns the structure returned by ENUM_CERTS
|
||||||
|
*/
|
||||||
|
class CertificateList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CertificateList();
|
||||||
|
~CertificateList();
|
||||||
|
|
||||||
|
void init(SlotList& slots);
|
||||||
|
|
||||||
|
inline enum_certs_s* getEnumList() { return m_enum_list; }
|
||||||
|
private:
|
||||||
|
struct cert_tmp_s
|
||||||
|
{
|
||||||
|
size_t slot_number;
|
||||||
|
act::Blob id;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<act::Blob, cert_tmp_s> cert_map_t;
|
||||||
|
|
||||||
|
void release_list();
|
||||||
|
|
||||||
|
int m_num_certs; // Copy of the number of certs embedded in the returned structure
|
||||||
|
enum_certs_s* m_enum_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
225
openssl-act-engine/Init_Engine.h
Normal file
225
openssl-act-engine/Init_Engine.h
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: actInit.h
|
||||||
|
// Product: cv act library
|
||||||
|
// Purpose: initialize the map entries of the objects
|
||||||
|
//
|
||||||
|
// Copyright: (c) 2007 cv cryptovision GmbH
|
||||||
|
// all rights reserved
|
||||||
|
// Licence: The conditions for the use of this software are regulated
|
||||||
|
// in the cv act library licence agreement.
|
||||||
|
// remarks:
|
||||||
|
// declare NO_SMARTCARD: no smartcard support required.
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef actInit_h
|
||||||
|
#define actInit_h
|
||||||
|
|
||||||
|
#include "actKeyKit.h"
|
||||||
|
#include "actKeyReg.h"
|
||||||
|
#include "actHashKit.h"
|
||||||
|
#include "actHashReg.h"
|
||||||
|
#include "actEMSAReg.h"
|
||||||
|
#include "actEMSAKit.h"
|
||||||
|
#include "actPaddingReg.h"
|
||||||
|
#include "actPaddingKit.h"
|
||||||
|
#include "actCertificateReg.h"
|
||||||
|
#include "actCertificateKit.h"
|
||||||
|
#include "actDefaultRNG.h"
|
||||||
|
#include "actRNGKit.h"
|
||||||
|
|
||||||
|
#ifndef NO_SMARTCARD
|
||||||
|
// NOTE: To Enable support for additional smartcards / profiles define:
|
||||||
|
// ACT_SUPPORT_TCOS_NETKEY30
|
||||||
|
# include "actSCardOSReg.h"
|
||||||
|
# include "actSCardOSKit.h"
|
||||||
|
# include "actSCardTokenReg.h"
|
||||||
|
# include "actSCardTokenKit.h"
|
||||||
|
# include "actSubsystemReg.h"
|
||||||
|
# include "actSubsystemKit.h"
|
||||||
|
# include "actSlotMonitorReg.h"
|
||||||
|
# include "actSlotMonitorKit.h"
|
||||||
|
# include "actTokenExtensionReg.h"
|
||||||
|
# include "actTokenExtensionKit.h"
|
||||||
|
# include "actTokenAuthProtocolReg.h"
|
||||||
|
# include "actTokenAuthProtocolKit.h"
|
||||||
|
# include "actPKCS15BehaviorReg.h"
|
||||||
|
# include "actPKCS15BehaviorKit.h"
|
||||||
|
#endif // NO_SMARTCARD
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const KeyMapEntry KeyMap[] =
|
||||||
|
{
|
||||||
|
{ "RSA" , CreateRSAKey },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const HashMapEntry HashMap[] =
|
||||||
|
{
|
||||||
|
{ "MD5" , CreateMD5 },
|
||||||
|
{ "SHA1" , CreateSHA1 },
|
||||||
|
{ "SHA224" , CreateSHA224 },
|
||||||
|
{ "SHA256" , CreateSHA256 },
|
||||||
|
{ "SHA384" , CreateSHA384 },
|
||||||
|
{ "SHA512" , CreateSHA512 },
|
||||||
|
{ "DummyHash" , CreateDummyHash },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const EMSAMapEntry EMSAMap[] =
|
||||||
|
{
|
||||||
|
{ "EMSA1", CreateEMSA1 },
|
||||||
|
{ "PKCS1V1_5EMSA", CreatePKCS1V1_5EMSA },
|
||||||
|
{ "TLS_EMSA", CreateTLS_EMSA},
|
||||||
|
{ "PKCS1_PSS_EMSA", CreatePKCS1_PSS_EMSA },
|
||||||
|
{ "DummyEMSA" , CreateDummyEMSA }, // Used for "Hash on Card"
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const PaddingMapEntry PaddingMap[] =
|
||||||
|
{
|
||||||
|
{ "PKCS5", CreatePKCS5Pad },
|
||||||
|
{ "RSAES", CreatePKCS1V1_5EMEPad },
|
||||||
|
{ "ISO", CreateOneAndZerosPad },
|
||||||
|
{ "ISO9796", CreateISO9796Pad },
|
||||||
|
{ "NOPAD", CreateNoPad },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const CertificateMapEntry CertificateMap[] =
|
||||||
|
{
|
||||||
|
{ "X509", CreateX509Certificate },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef NO_SMARTCARD
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const SCardOSMapEntry SCardOSMap[] =
|
||||||
|
{
|
||||||
|
// CardOS
|
||||||
|
{ "c806", CreateCardOS_V4 }, // CardOS V4.2
|
||||||
|
{ "c807", CreateCardOS_V4 }, // CardOS V4.3
|
||||||
|
{ "c808", CreateCardOS_V4 }, // CardOS V4.3B
|
||||||
|
{ "c809", CreateCardOS_V4 }, // CardOS V4.2B
|
||||||
|
{ "c80a", CreateCardOS_V4 }, // CardOS V4.2B DI
|
||||||
|
{ "0000c80a3381b100", CreateCardOS_V4 }, // CardOS V4.2B DI contactless
|
||||||
|
{ "c80b", CreateCardOS_V4 }, // CardOS V4.2C
|
||||||
|
{ "c80d", CreateCardOS_V4 }, // CardOS V4.4
|
||||||
|
{ "56346376", CreateCardOS_V4 }, // CardOS V4.2/4.3/4.3B cv profile
|
||||||
|
{ "563432626376", CreateCardOS_V4 }, // CardOS V4.2b cv profile
|
||||||
|
{ "5634326244496376", CreateCardOS_V4 }, // CardOS V4.2b DI cv profile
|
||||||
|
{ "563432636376", CreateCardOS_V4 }, // CardOS V4.2c cv profile
|
||||||
|
{ "5634346376", CreateCardOS_V4 }, // CardOS V4.4 cv profile
|
||||||
|
{ "563463765f45", CreateCardOS_V4_ECC }, // CardOS V4.3B ECC cv profile
|
||||||
|
{ "006b0508c806012101434e53103180", CreateCardOS_V4 }, // CardOS V4.2 CNS profile, 2004.02.20
|
||||||
|
{ "006b0508c807012101434e53103180", CreateCardOS_V4 }, // CardOS V4.3 CNS profile, 2004.02.20
|
||||||
|
{ "006b0508c808012101434e53103180", CreateCardOS_V4 }, // CardOS V4.3B CNS profile, 2004.02.20
|
||||||
|
{ "006b0508c806011101434e53103180", CreateCardOS_V4 }, // CardOS V4.2 CNS profile, 2005.03.11
|
||||||
|
{ "006b0508c807011101434e53103180", CreateCardOS_V4 }, // CardOS V4.3 CNS profile, 2005.03.11
|
||||||
|
{ "006b0508c808011101434e53103180", CreateCardOS_V4 }, // CardOS V4.3B CNS profile, 2005.03.11
|
||||||
|
{ "006b0508c808011101434e53103180", CreateCardOS_V4 }, // CardOS V4.3B CNS profile, 2005.03.11
|
||||||
|
{ "4b53776973735369676e", CreateCardOS_V4 }, // CardOS V4.3B/V4.4 ATR by SwissSign
|
||||||
|
|
||||||
|
{ ACT_ISO7816OS_NAME, CreateISO7816OS }, // use act::ISO7816OS as fallback
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const SCardTokenMapEntry SCardTokenMap[] =
|
||||||
|
{
|
||||||
|
// PKCS#15
|
||||||
|
{ IsV4PKCS15ECProfile, CreateV4PKCS15ECProfile },
|
||||||
|
{ IsV4PKCS15Profile, CreateV4PKCS15Profile },
|
||||||
|
|
||||||
|
// CardOS
|
||||||
|
{ IsM4cvMoCProfile, CreateM4cvMoCProfile },
|
||||||
|
{ IsM4cvECProfile, CreateM4cvECProfile },
|
||||||
|
{ IsV4cvECProfile, CreateV4cvECProfile },
|
||||||
|
{ IsV4cvProfile, CreateV4cvProfile },
|
||||||
|
{ IsM4cvProfile, CreateM4cvProfile },
|
||||||
|
// { IsV4CNSProfile, CreateV4CNSProfile },
|
||||||
|
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const PKCS15BehaviorMapEntry PKCS15BehaviorMap[] =
|
||||||
|
{
|
||||||
|
{ "cv cryptovision gmbh (c) v1.0n", CreateV4PKCS15Behavior },
|
||||||
|
{ "", CreatePKCS15Behavior }, // default
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const TokenExtensionMapEntry TokenExtensionMap[] =
|
||||||
|
{
|
||||||
|
{ "MDProfileExt", CreateMDProfileExt }, // Minidriver FS Profile Extension
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const TokenAuthProtocolMapEntry TokenAuthProtocolMap[] =
|
||||||
|
{
|
||||||
|
{ "EAC 2.01 PACE", CreateTokenAuthPACE },
|
||||||
|
{ "EAC 2.01 TA", CreateTokenAuthTA },
|
||||||
|
{ "EAC 2.01 CA", CreateTokenAuthCA },
|
||||||
|
{ "BAC", CreateTokenAuthBAC },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const SubsystemMapEntry SubsystemMap[] =
|
||||||
|
{
|
||||||
|
{ "PCSC", CreatePCSCSystem, CreatePCSCSystemEx },
|
||||||
|
{ 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const SlotMonitorRegEntry SlotMonitorMap[] =
|
||||||
|
{
|
||||||
|
{ "PCSC", { CreatePCSCSlotMonitor, CreatePCSCSystemSlotMonitor } },
|
||||||
|
{ 0, { 0, 0 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NO_SMARTCARD
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Version: V1R4M4
|
||||||
|
const char* GetVersion();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
inline void Init(bool bAlwaysInit = false)
|
||||||
|
{
|
||||||
|
static bool loaded = false;
|
||||||
|
if(loaded == true && bAlwaysInit == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
KeyReg::Insert(KeyMap);
|
||||||
|
HashReg::Insert(HashMap);
|
||||||
|
EMSAReg::Insert(EMSAMap);
|
||||||
|
PaddingReg::Insert(PaddingMap);
|
||||||
|
CertificateReg::Insert(CertificateMap);
|
||||||
|
|
||||||
|
#ifndef NO_SMARTCARD
|
||||||
|
SubsystemReg::Insert(SubsystemMap);
|
||||||
|
SlotMonitorReg::Insert(SlotMonitorMap);
|
||||||
|
SCardOSReg::Insert(SCardOSMap);
|
||||||
|
SCardTokenReg::Insert(SCardTokenMap);
|
||||||
|
PKCS15BehaviorReg::Insert(PKCS15BehaviorMap);
|
||||||
|
TokenExtensionReg::Insert(TokenExtensionMap);
|
||||||
|
TokenAuthProtocolReg::Insert(TokenAuthProtocolMap);
|
||||||
|
#endif
|
||||||
|
CreateFastRNG = CreateFIPS186;
|
||||||
|
CreateStrongRNG = CreateBBS;
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace act
|
||||||
|
|
||||||
|
#endif // actInit_h
|
34
openssl-act-engine/Makefile
Normal file
34
openssl-act-engine/Makefile
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
CXXFLAGS=-pthread -g -O0 -DDEBUG
|
||||||
|
|
||||||
|
|
||||||
|
OPENSSL_LIBDIR=-L/home/carsten/openssl-0.9.8o
|
||||||
|
INCDIRS=-I/home/carsten/Devel/actlib/include/
|
||||||
|
|
||||||
|
LIBS=$(OPENSSL_LIBDIR) -L/home/carsten/Devel/actlib/lib -lact -ldl -lcrypto -lpthread
|
||||||
|
OBJS=engine_front.o engine_sct.o CardObject.o CardKey.o SlotList.o CertificateList.o SecOpGuard.o
|
||||||
|
TARGET=libengine_securetoken.so
|
||||||
|
|
||||||
|
TESTOBJS=test_engine.o
|
||||||
|
TESTTARGET=test_engine
|
||||||
|
TESTLIBS=$(OPENSSL_LIBDIR) -lcrypto -lssl -ldl -lpthread
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
test: $(TESTTARGET)
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(TARGET) $(TESTTARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CXX) --shared -o $(TARGET) $(OBJS) $(LIBS)
|
||||||
|
|
||||||
|
$(TESTTARGET): $(TESTOBJS)
|
||||||
|
$(CXX) -o $(TESTTARGET) $(TESTOBJS) $(TESTLIBS)
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCDIRS) $<
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) -c $(CFLAGS) $(INCDIRS) $<
|
||||||
|
|
||||||
|
|
41
openssl-act-engine/ReadMe.txt
Normal file
41
openssl-act-engine/ReadMe.txt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
========================================================================
|
||||||
|
DYNAMIC LINK LIBRARY : engine_securetoken Project Overview
|
||||||
|
========================================================================
|
||||||
|
|
||||||
|
AppWizard has created this engine_securetoken DLL for you.
|
||||||
|
|
||||||
|
This file contains a summary of what you will find in each of the files that
|
||||||
|
make up your engine_securetoken application.
|
||||||
|
|
||||||
|
|
||||||
|
engine_securetoken.vcproj
|
||||||
|
This is the main project file for VC++ projects generated using an Application Wizard.
|
||||||
|
It contains information about the version of Visual C++ that generated the file, and
|
||||||
|
information about the platforms, configurations, and project features selected with the
|
||||||
|
Application Wizard.
|
||||||
|
|
||||||
|
engine_securetoken.cpp
|
||||||
|
This is the main DLL source file.
|
||||||
|
|
||||||
|
When created, this DLL does not export any symbols. As a result, it
|
||||||
|
will not produce a .lib file when it is built. If you wish this project
|
||||||
|
to be a project dependency of some other project, you will either need to
|
||||||
|
add code to export some symbols from the DLL so that an export library
|
||||||
|
will be produced, or you can set the Ignore Input Library property to Yes
|
||||||
|
on the General propert page of the Linker folder in the project's Property
|
||||||
|
Pages dialog box.
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
Other standard files:
|
||||||
|
|
||||||
|
StdAfx.h, StdAfx.cpp
|
||||||
|
These files are used to build a precompiled header (PCH) file
|
||||||
|
named engine_securetoken.pch and a precompiled types file named StdAfx.obj.
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
Other notes:
|
||||||
|
|
||||||
|
AppWizard uses "TODO:" comments to indicate parts of the source code you
|
||||||
|
should add to or customize.
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
48
openssl-act-engine/SecOpGuard.cpp
Normal file
48
openssl-act-engine/SecOpGuard.cpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#include "SecOpGuard.h"
|
||||||
|
|
||||||
|
#include <actDebug.h>
|
||||||
|
#include <actIToken.h>
|
||||||
|
#include <actITokenAuth.h>
|
||||||
|
|
||||||
|
SecOpGuard::SecOpGuard(act::IToken* token)
|
||||||
|
: m_token(token)
|
||||||
|
, act::SCardLock(token->GetOS())
|
||||||
|
{
|
||||||
|
ACT_ASSERT(token != NULL);
|
||||||
|
|
||||||
|
m_token_auth = token->GetAuth();
|
||||||
|
}
|
||||||
|
|
||||||
|
SecOpGuard::~SecOpGuard()
|
||||||
|
{
|
||||||
|
if(!m_token_auth->IsAuthenticated())
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_token_auth->Logout();
|
||||||
|
}
|
||||||
|
catch(act::Exception& ACT_DEBUG_PARAM(e))
|
||||||
|
{
|
||||||
|
ACT_TRACE(e, "SecOpGuard::~SecOpGuard");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SecOpGuard::Authenticate(act::ITokenPIN* token_pin, const act::Blob& auth_data)
|
||||||
|
{
|
||||||
|
// Auth constraints, chained authorization, anyone?
|
||||||
|
if(m_token_auth->IsAuthenticated())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return (m_token_auth->Login(token_pin, auth_data));
|
||||||
|
}
|
||||||
|
catch(act::Exception& ACT_DEBUG_PARAM(e))
|
||||||
|
{
|
||||||
|
ACT_TRACE(e, "SecOpGuard::Authenticate");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
33
openssl-act-engine/SecOpGuard.h
Normal file
33
openssl-act-engine/SecOpGuard.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __SECOPGUARD_H__
|
||||||
|
#define __SECOPGUARD_H__
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
class IToken;
|
||||||
|
class ITokenAuth;
|
||||||
|
class ITokenPIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <actUtility.h>
|
||||||
|
#include <actSCardLock.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transaction guard and authenticator to a card
|
||||||
|
*/
|
||||||
|
class SecOpGuard : public act::SCardLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SecOpGuard(act::IToken* token);
|
||||||
|
~SecOpGuard();
|
||||||
|
|
||||||
|
bool Authenticate(act::ITokenPIN* token_pin, const act::Blob& auth_data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_status;
|
||||||
|
act::IToken* m_token;
|
||||||
|
act::ITokenAuth* m_token_auth;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
138
openssl-act-engine/SlotList.cpp
Normal file
138
openssl-act-engine/SlotList.cpp
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
#include "SlotList.h"
|
||||||
|
|
||||||
|
#include <actISlot.h>
|
||||||
|
#include <actIToken.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <actException.h>
|
||||||
|
#include <actDebug.h>
|
||||||
|
|
||||||
|
SlotEntry::SlotEntry()
|
||||||
|
: m_token(NULL)
|
||||||
|
, m_slot(NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SlotEntry::SlotEntry(const SlotEntry& old_entry)
|
||||||
|
: m_slot(NULL)
|
||||||
|
, m_token(NULL)
|
||||||
|
{
|
||||||
|
init(old_entry.m_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlotEntry::init(act::ISlot* slot_blueprint)
|
||||||
|
{
|
||||||
|
ACT_ASSERT(m_slot == NULL);
|
||||||
|
ACT_ASSERT(m_token == NULL);
|
||||||
|
|
||||||
|
if(!slot_blueprint)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_slot = slot_blueprint->Clone();
|
||||||
|
|
||||||
|
preload_token();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlotEntry::preload_token()
|
||||||
|
{
|
||||||
|
if(m_token != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(m_slot->IsTokenPresent())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_token = m_slot->CreateToken();
|
||||||
|
}
|
||||||
|
catch(act::Exception& ACT_DEBUG_PARAM(e))
|
||||||
|
{
|
||||||
|
ACT_TRACE(e,"SlotEntry::init");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SlotEntry::~SlotEntry()
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlotEntry::invalidate_token()
|
||||||
|
{
|
||||||
|
if(m_token)
|
||||||
|
m_token->Destroy();
|
||||||
|
m_token = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlotEntry::cleanup()
|
||||||
|
{
|
||||||
|
invalidate_token();
|
||||||
|
if(m_slot)
|
||||||
|
m_slot->Destroy();
|
||||||
|
m_slot = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
act::IToken* SlotEntry::getToken()
|
||||||
|
{
|
||||||
|
preload_token();
|
||||||
|
|
||||||
|
if(m_token != NULL)
|
||||||
|
m_token->IncReferenceCounter();
|
||||||
|
|
||||||
|
return m_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
SlotList::SlotList()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SlotList::SlotList(size_t expected_size)
|
||||||
|
{
|
||||||
|
m_slot_list.reserve(expected_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
SlotList::~SlotList()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlotList::reserve(size_t expected_size)
|
||||||
|
{
|
||||||
|
m_slot_list.reserve(expected_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlotList::addSlot(act::ISlot* slot)
|
||||||
|
{
|
||||||
|
m_slot_list.push_back(SlotEntry());
|
||||||
|
m_slot_list[m_slot_list.size()-1].init(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlotList::removeSlot(act::ISlot* slot)
|
||||||
|
{
|
||||||
|
for(slot_list_t::iterator it = m_slot_list.begin();it != m_slot_list.end();++it)
|
||||||
|
if(it->getSlot() == slot)
|
||||||
|
{
|
||||||
|
m_slot_list.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
act::ISlot* SlotList::getSlot(size_t index)
|
||||||
|
{
|
||||||
|
if(index >= m_slot_list.size()) return NULL;
|
||||||
|
|
||||||
|
return m_slot_list[index].getSlot();
|
||||||
|
}
|
||||||
|
|
||||||
|
act::IToken* SlotList::getToken(size_t index)
|
||||||
|
{
|
||||||
|
if(index >= m_slot_list.size()) return NULL;
|
||||||
|
|
||||||
|
return m_slot_list[index].getToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlotList::clear()
|
||||||
|
{
|
||||||
|
m_slot_list.clear();
|
||||||
|
}
|
64
openssl-act-engine/SlotList.h
Normal file
64
openssl-act-engine/SlotList.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#ifndef __SLOTLIST_H__
|
||||||
|
#define __SLOTLIST_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
class ISlot;
|
||||||
|
class IToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SlotEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SlotEntry();
|
||||||
|
SlotEntry(const SlotEntry& old_entry);
|
||||||
|
|
||||||
|
void init(act::ISlot* slot_blueprint);
|
||||||
|
~SlotEntry();
|
||||||
|
|
||||||
|
void invalidate_token();
|
||||||
|
void preload_token();
|
||||||
|
|
||||||
|
inline act::ISlot* getSlot() const { return m_slot; }
|
||||||
|
act::IToken* getToken();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
act::ISlot* m_slot;
|
||||||
|
act::IToken* m_token;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Holds a list of the present slots in the system
|
||||||
|
* TODO: Slot addition/removal detection
|
||||||
|
*/
|
||||||
|
class SlotList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<SlotEntry> slot_list_t;
|
||||||
|
|
||||||
|
SlotList();
|
||||||
|
SlotList(size_t expected_size);
|
||||||
|
~SlotList();
|
||||||
|
|
||||||
|
void reserve(size_t expected_size);
|
||||||
|
void addSlot(act::ISlot* slot);
|
||||||
|
void removeSlot(act::ISlot* slot);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
act::ISlot* getSlot(size_t index);
|
||||||
|
act::IToken* getToken(size_t index);
|
||||||
|
|
||||||
|
inline size_t getNumSlots() { return m_slot_list.size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
slot_list_t m_slot_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
184
openssl-act-engine/SyncObject.h
Normal file
184
openssl-act-engine/SyncObject.h
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: SyncObject.h
|
||||||
|
// Product: cv act library
|
||||||
|
// Purpose: Multithreading synchronization primitive for multiple Operating Systems.
|
||||||
|
//
|
||||||
|
// Copyright: (c) 2009 cv cryptovision GmbH
|
||||||
|
// all rights reserved
|
||||||
|
// Licence: The conditions for the use of this software are regulated
|
||||||
|
// in the cv act library licence agreement.
|
||||||
|
//
|
||||||
|
// Autor: Markus Tesche
|
||||||
|
// Date: 04/23/2009
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SyncObject_h
|
||||||
|
#define SyncObject_h
|
||||||
|
|
||||||
|
#include "actBasics.h"
|
||||||
|
|
||||||
|
#if defined(ACT_WIN32_WCE)
|
||||||
|
# include "SyncObjectWinCE.h"
|
||||||
|
|
||||||
|
#elif defined(ACT_WIN32)
|
||||||
|
# include "SyncObjectWin32.h"
|
||||||
|
|
||||||
|
#elif defined(ACT_SOLARIS)
|
||||||
|
# include "SyncObjectSloaris.h"
|
||||||
|
|
||||||
|
#elif defined(ACT_MACOSX)
|
||||||
|
# include "SyncObjectMacOS.h"
|
||||||
|
|
||||||
|
// posix has always to be last checked !
|
||||||
|
#elif defined(ACT_POSIX)
|
||||||
|
# include "SyncObjectPosix.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
# error SyncObject not implemented for this system
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "actHandle.h"
|
||||||
|
#include "actISynchronize.h"
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Synchronizeable<>
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename BaseT, /* ISynchronize or derived */
|
||||||
|
typename SyncObjectT = SyncObject
|
||||||
|
>
|
||||||
|
class Synchronizeable : public BaseT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SyncObjectT SyncObject;
|
||||||
|
typedef ValueHandle<SyncObjectT> SyncHandle;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
// ISynchronize methods
|
||||||
|
virtual void Lock() { syncObject().lock(); }
|
||||||
|
virtual void Unlock() { syncObject().unlock(); }
|
||||||
|
virtual long LockCount() const { return syncObject().lockCount(); }
|
||||||
|
|
||||||
|
virtual const Handle& syncHandle() const { return m_sync_handle; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SyncObjectT& syncObject() const { return m_sync_handle.valueRef(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ValueHandle<SyncObjectT> m_sync_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// GuardT<>
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class SyncObjectT,
|
||||||
|
class BaseT = void,
|
||||||
|
class TypeT = void
|
||||||
|
>
|
||||||
|
class GuardT;
|
||||||
|
|
||||||
|
//
|
||||||
|
// GuardT<>
|
||||||
|
template<class SyncObjectT>
|
||||||
|
class GuardT<SyncObjectT, void, void>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SyncObjectT SyncObject;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GuardT(const GuardT&);
|
||||||
|
GuardT& operator=(const GuardT&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
GuardT(SyncObjectT& sync_object)
|
||||||
|
: m_sync_object(sync_object)
|
||||||
|
{
|
||||||
|
m_sync_object.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
GuardT(const Handle& sync_handle)
|
||||||
|
: m_sync_object(sync_handle.requiredAs<SyncObjectT>())
|
||||||
|
{
|
||||||
|
m_sync_object.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
GuardT(const ValueHandle<SyncObjectT>& sync_handle)
|
||||||
|
: m_sync_object(sync_handle.valueRef())
|
||||||
|
{
|
||||||
|
m_sync_object.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~GuardT()
|
||||||
|
{
|
||||||
|
m_sync_object.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
long LockCount() const { return m_sync_object.lockCount(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SyncObjectT& m_sync_object;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// GuardT<>
|
||||||
|
template<class SyncObjectT>
|
||||||
|
class GuardT<SyncObjectT, ISynchronize, void>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SyncObjectT SyncObject;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GuardT(const GuardT&);
|
||||||
|
GuardT& operator=(const GuardT&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
GuardT(ISynchronize& synchronize)
|
||||||
|
: m_guard(synchronize.syncHandle())
|
||||||
|
{ }
|
||||||
|
|
||||||
|
GuardT(const ISynchronize& synchronize)
|
||||||
|
: m_guard(synchronize.syncHandle())
|
||||||
|
{ }
|
||||||
|
|
||||||
|
long LockCount() const { return m_guard.LockCount(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GuardT<SyncObjectT> m_guard;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// GuardT<>
|
||||||
|
template<class SyncObjectT, class TypeT>
|
||||||
|
class GuardT<SyncObjectT, ISynchronize, TypeT>
|
||||||
|
: public GuardT<SyncObjectT, ISynchronize, void>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GuardT(TypeT& synchronize)
|
||||||
|
: GuardT<SyncObjectT, ISynchronize, void>(synchronize)
|
||||||
|
, m_synchronized(synchronize)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
TypeT* operator->() const { return &m_synchronized; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TypeT& m_synchronized;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef GuardT<SyncObject> Guard;
|
||||||
|
typedef GuardT<SyncObject, ISynchronize> Synchronize;
|
||||||
|
|
||||||
|
template<typename TypeT>
|
||||||
|
GuardT<SyncObject, ISynchronize, TypeT> Synchronized(TypeT& synchronize)
|
||||||
|
{
|
||||||
|
return GuardT<SyncObject, ISynchronize, TypeT>(synchronize);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace act
|
||||||
|
|
||||||
|
#endif // SyncObject_h
|
46
openssl-act-engine/SyncObjectMacOS.h
Normal file
46
openssl-act-engine/SyncObjectMacOS.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef SyncObject_MacOS_h
|
||||||
|
#define SyncObject_MacOS_h
|
||||||
|
|
||||||
|
#ifndef SyncObject_h
|
||||||
|
# error include SyncObject.h instead
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <CoreServices/CoreServices.h>
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
class SyncObject
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SyncObject(const SyncObject&);
|
||||||
|
SyncObject& operator=(const SyncObject&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SyncObject();
|
||||||
|
~SyncObject();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
|
||||||
|
long lockCount() const { return m_lock_count; }
|
||||||
|
MPTaskID threadId() const { return m_thread_id; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
volatile long m_lock_count;
|
||||||
|
volatile MPTaskID m_thread_id;
|
||||||
|
MPCriticalRegionID m_sync;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Sleep(long msec);
|
||||||
|
|
||||||
|
} // namespace act
|
||||||
|
|
||||||
|
#ifdef verify
|
||||||
|
# undef verify
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef check
|
||||||
|
# undef check
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SyncObject_MacOS_h
|
38
openssl-act-engine/SyncObjectPosix.h
Normal file
38
openssl-act-engine/SyncObjectPosix.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef SyncObject_Posix_h
|
||||||
|
#define SyncObject_Posix_h
|
||||||
|
|
||||||
|
#ifndef SyncObject_h
|
||||||
|
# error include SyncObject.h instead
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
class SyncObject
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SyncObject(const SyncObject&);
|
||||||
|
SyncObject& operator=(const SyncObject&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SyncObject();
|
||||||
|
~SyncObject();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
|
||||||
|
long lockCount() const { return m_lock_count; }
|
||||||
|
pid_t threadId() const { return m_thread_id; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
volatile long m_lock_count;
|
||||||
|
volatile pid_t m_thread_id;
|
||||||
|
pthread_mutex_t m_sync;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Sleep(long msec);
|
||||||
|
|
||||||
|
} // namespace act
|
||||||
|
|
||||||
|
#endif // SyncObject_Posix_h
|
38
openssl-act-engine/SyncObjectSolaris.h
Normal file
38
openssl-act-engine/SyncObjectSolaris.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef SyncObject_Solaris_h
|
||||||
|
#define SyncObject_Solaris_h
|
||||||
|
|
||||||
|
#ifndef SyncObject_h
|
||||||
|
# error include SyncObject.h instead
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
class SyncObject
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SyncObject(const SyncObject&);
|
||||||
|
SyncObject& operator=(const SyncObject&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SyncObject();
|
||||||
|
~SyncObject();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
|
||||||
|
long lockCount() const { return m_lock_count; }
|
||||||
|
pid_t threadId() const { return m_thread_id; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
volatile long m_lock_count;
|
||||||
|
volatile pid_t m_thread_id;
|
||||||
|
pthread_mutex_t m_sync;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Sleep(long msec);
|
||||||
|
|
||||||
|
} // namespace act
|
||||||
|
|
||||||
|
#endif // SyncObject_Solaris_h
|
39
openssl-act-engine/SyncObjectWin32.h
Normal file
39
openssl-act-engine/SyncObjectWin32.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef SyncObject_Win32_h
|
||||||
|
#define SyncObject_Win32_h
|
||||||
|
|
||||||
|
#ifndef SyncObject_h
|
||||||
|
# error include SyncObject.h instead
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32_WINNT
|
||||||
|
# define _WIN32_WINNT 0x0403
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
class SyncObject
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SyncObject(const SyncObject&);
|
||||||
|
SyncObject& operator=(const SyncObject&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SyncObject();
|
||||||
|
~SyncObject();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
|
||||||
|
long lockCount() const { return m_lock_count; }
|
||||||
|
DWORD threadId() const { return m_thread_id; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
volatile long m_lock_count;
|
||||||
|
volatile DWORD m_thread_id;
|
||||||
|
CRITICAL_SECTION m_sync;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace act
|
||||||
|
|
||||||
|
#endif // SyncObject_Win32_h
|
36
openssl-act-engine/SyncObjectWinCE.h
Normal file
36
openssl-act-engine/SyncObjectWinCE.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef SyncObject_WinCE_h
|
||||||
|
#define SyncObject_WinCE_h
|
||||||
|
|
||||||
|
#ifndef SyncObject_h
|
||||||
|
# error include SyncObject.h instead
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
namespace act
|
||||||
|
{
|
||||||
|
class SyncObject
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SyncObject(const SyncObject&);
|
||||||
|
SyncObject& operator=(const SyncObject&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SyncObject();
|
||||||
|
~SyncObject();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
|
||||||
|
long lockCount() const { return m_lock_count; }
|
||||||
|
DWORD threadId() const { return m_thread_id; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
volatile long m_lock_count;
|
||||||
|
volatile DWORD m_thread_id;
|
||||||
|
CRITICAL_SECTION m_sync;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace act
|
||||||
|
|
||||||
|
#endif // SyncObject_WinCE_h
|
7
openssl-act-engine/Warns.h
Normal file
7
openssl-act-engine/Warns.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef __WARNS_H__
|
||||||
|
#define __WARNS_H__
|
||||||
|
|
||||||
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
|
#endif
|
19
openssl-act-engine/dllmain.cpp
Normal file
19
openssl-act-engine/dllmain.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||||
|
DWORD ul_reason_for_call,
|
||||||
|
LPVOID lpReserved
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (ul_reason_for_call)
|
||||||
|
{
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
case DLL_THREAD_ATTACH:
|
||||||
|
case DLL_THREAD_DETACH:
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
262
openssl-act-engine/engine_front.cpp
Normal file
262
openssl-act-engine/engine_front.cpp
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <cstring>
|
||||||
|
#include <openssl/dso.h>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
|
#include "engine_sct.h"
|
||||||
|
#include "engine_sct_internal.h"
|
||||||
|
|
||||||
|
#ifndef ENGINE_CMD_BASE
|
||||||
|
#error did not get engine.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SCT_ENGINE_ID "act"
|
||||||
|
#define SCT_ENGINE_NAME "cv act library SecureToken interface engine"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CMD_SO_PATH = ENGINE_CMD_BASE,
|
||||||
|
CMD_PIN,
|
||||||
|
CMD_VERBOSE,
|
||||||
|
CMD_QUIET,
|
||||||
|
CMD_LOAD_CERT_CTRL,
|
||||||
|
CMD_ENUM_CERTS,
|
||||||
|
CMD_INIT_ARGS
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::auto_ptr<SecureTokenEngine> g_engine;
|
||||||
|
|
||||||
|
static int sct_engine_construct(ENGINE *e);
|
||||||
|
static int sct_engine_destruct(ENGINE *e);
|
||||||
|
static int sct_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)() );
|
||||||
|
|
||||||
|
static const ENGINE_CMD_DEFN sct_cmd_defns[] = {
|
||||||
|
{
|
||||||
|
CMD_SO_PATH,
|
||||||
|
"SO_PATH",
|
||||||
|
"Specifies the path to the 'securetoken-engine' shared library",
|
||||||
|
ENGINE_CMD_FLAG_STRING
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CMD_PIN,
|
||||||
|
"PIN",
|
||||||
|
"Specifies the PIN to use for access",
|
||||||
|
ENGINE_CMD_FLAG_STRING
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CMD_VERBOSE,
|
||||||
|
"VERBOSE",
|
||||||
|
"Increases the amount of progress information",
|
||||||
|
ENGINE_CMD_FLAG_NO_INPUT
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CMD_LOAD_CERT_CTRL,
|
||||||
|
"LOAD_CERT_CTRL",
|
||||||
|
"Get the certificate from card",
|
||||||
|
ENGINE_CMD_FLAG_INTERNAL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CMD_ENUM_CERTS,
|
||||||
|
"ENUM_CERTS",
|
||||||
|
"Return the certificates and the ID's of the key pairs",
|
||||||
|
ENGINE_CMD_FLAG_INTERNAL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CMD_INIT_ARGS,
|
||||||
|
"INIT_ARGS",
|
||||||
|
"Additional initialization arguments",
|
||||||
|
ENGINE_CMD_FLAG_STRING
|
||||||
|
},
|
||||||
|
{ 0, NULL, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Encapsule a "return function()" statement with a catch-all block which will emit an error message and return
|
||||||
|
// a predefined (error) return value in that case.
|
||||||
|
#define CATCH_ALL(rettype, retval, function) \
|
||||||
|
do { \
|
||||||
|
rettype result = retval; \
|
||||||
|
try \
|
||||||
|
{ \
|
||||||
|
result = (function); \
|
||||||
|
} \
|
||||||
|
catch(...) \
|
||||||
|
{ \
|
||||||
|
fprintf(stderr, "Unhandled exception caught!\n"); \
|
||||||
|
} \
|
||||||
|
return result; \
|
||||||
|
} while(0) \
|
||||||
|
|
||||||
|
static int sct_engine_construct(ENGINE *e)
|
||||||
|
{
|
||||||
|
if(g_engine.get() != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
g_engine.reset(new SecureTokenEngine());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sct_engine_destruct(ENGINE *e)
|
||||||
|
{
|
||||||
|
g_engine.reset(0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sct_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)() )
|
||||||
|
{
|
||||||
|
switch(cmd)
|
||||||
|
{
|
||||||
|
case CMD_PIN:
|
||||||
|
return g_engine->setPin((char *) p);
|
||||||
|
case CMD_VERBOSE:
|
||||||
|
return g_engine->incVerbosity();
|
||||||
|
case CMD_LOAD_CERT_CTRL:
|
||||||
|
return g_engine->loadCertCtrl(e, (load_cert_params *)p);
|
||||||
|
case CMD_INIT_ARGS:
|
||||||
|
return g_engine->setInitArgs((const char *)p);
|
||||||
|
case CMD_ENUM_CERTS:
|
||||||
|
return g_engine->enumerate_certs(e, (enum_certs_s **)p);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sct_init(ENGINE *e)
|
||||||
|
{
|
||||||
|
CATCH_ALL(int,0,g_engine->init());
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sct_finish(ENGINE *e)
|
||||||
|
{
|
||||||
|
CATCH_ALL(int,0,g_engine->finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sct_rsa_finish(RSA *rsa)
|
||||||
|
{
|
||||||
|
CATCH_ALL(int,0,g_engine->rsa_finish(rsa));
|
||||||
|
}
|
||||||
|
|
||||||
|
static EVP_PKEY *sct_load_public_key(
|
||||||
|
ENGINE *e, const char *s_key_id, UI_METHOD *ui_method, void *callback_data)
|
||||||
|
{
|
||||||
|
CATCH_ALL(EVP_PKEY*,NULL,g_engine->load_pubkey(s_key_id, ui_method, callback_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static EVP_PKEY *sct_load_private_key(
|
||||||
|
ENGINE *e, const char *s_key_id, UI_METHOD *ui_method, void *callback_data)
|
||||||
|
{
|
||||||
|
CATCH_ALL(EVP_PKEY*,NULL,g_engine->load_privkey(s_key_id, ui_method, callback_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sct_rsa_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
|
||||||
|
{
|
||||||
|
CATCH_ALL(int,-1,g_engine->rsa_encrypt(flen, from, to, EXTRACT_CARD_KEY(rsa), padding));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sct_rsa_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
|
||||||
|
{
|
||||||
|
CATCH_ALL(int,-1,g_engine->rsa_decrypt(flen, from, to, EXTRACT_CARD_KEY(rsa), padding));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sct_rsa_sign(int type,
|
||||||
|
const unsigned char *msg, unsigned int msglen,
|
||||||
|
unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
|
||||||
|
{
|
||||||
|
CATCH_ALL(int,0,g_engine->rsa_sign(type, msg, msglen, sigret, siglen, EXTRACT_CARD_KEY(rsa)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sct_rsa_verify(int type,
|
||||||
|
const unsigned char *msg, unsigned int msglen,
|
||||||
|
unsigned char *signature, unsigned int siglen, const RSA *rsa)
|
||||||
|
{
|
||||||
|
CATCH_ALL(int,0,g_engine->rsa_verify(type, msg, msglen, signature, siglen, EXTRACT_CARD_KEY(rsa)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Following part is for binding the engine into OpenSSL
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Overlay the standard RSA operations with smartcard based ones
|
||||||
|
RSA_METHOD* RSA_get_sct_method()
|
||||||
|
{
|
||||||
|
static RSA_METHOD ops;
|
||||||
|
|
||||||
|
if(!ops.rsa_priv_enc)
|
||||||
|
{
|
||||||
|
ops = *RSA_get_default_method();
|
||||||
|
ops.rsa_pub_enc = sct_rsa_encrypt;
|
||||||
|
ops.rsa_priv_dec = sct_rsa_decrypt;
|
||||||
|
ops.rsa_pub_dec = NULL; // a.k.a Verify/Sign. actLibrary just allows the proper functions
|
||||||
|
ops.rsa_priv_enc = NULL; // and has this 'backdoor' closed. Breaks 'rsautl', sadly.
|
||||||
|
ops.rsa_sign = sct_rsa_sign;
|
||||||
|
ops.rsa_verify = sct_rsa_verify;
|
||||||
|
ops.finish = sct_rsa_finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ops;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bind_helper(ENGINE *e)
|
||||||
|
{
|
||||||
|
if(
|
||||||
|
!sct_engine_construct(e) ||
|
||||||
|
|
||||||
|
!ENGINE_set_id(e, SCT_ENGINE_ID) ||
|
||||||
|
!ENGINE_set_name(e, SCT_ENGINE_NAME) ||
|
||||||
|
!ENGINE_set_destroy_function(e, sct_engine_destruct) ||
|
||||||
|
!ENGINE_set_init_function(e, sct_init) ||
|
||||||
|
!ENGINE_set_finish_function(e, sct_finish) ||
|
||||||
|
!ENGINE_set_ctrl_function(e, sct_engine_ctrl) ||
|
||||||
|
!ENGINE_set_cmd_defns(e, sct_cmd_defns) ||
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_RSA
|
||||||
|
!ENGINE_set_RSA(e, RSA_get_sct_method()) ||
|
||||||
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_DSA
|
||||||
|
!ENGINE_set_DSA(e, DSA_get_default_method()) ||
|
||||||
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_DH
|
||||||
|
!ENGINE_set_DH(e, DH_get_default_method()) ||
|
||||||
|
#endif
|
||||||
|
!ENGINE_set_RAND(e, RAND_SSLeay()) ||
|
||||||
|
#if 0
|
||||||
|
!ENGINE_set_BN_mod_exp(e, BN_mod_exp) ||
|
||||||
|
#endif
|
||||||
|
!ENGINE_set_load_pubkey_function(e, sct_load_public_key) ||
|
||||||
|
!ENGINE_set_load_privkey_function(e, sct_load_private_key))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bind_fn(ENGINE * e, const char *id)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
if (id && (strcmp(id, SCT_ENGINE_ID) != 0)) {
|
||||||
|
fprintf(stderr, "bad engine id (%s vs. %s)\n", id, SCT_ENGINE_ID);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!bind_helper(e)) {
|
||||||
|
fprintf(stderr, "bind failed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
IMPLEMENT_DYNAMIC_CHECK_FN();
|
||||||
|
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
402
openssl-act-engine/engine_sct.cpp
Normal file
402
openssl-act-engine/engine_sct.cpp
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
|
||||||
|
#include "engine_sct.h"
|
||||||
|
#include "engine_sct_internal.h"
|
||||||
|
|
||||||
|
#include "Init_Engine.h"
|
||||||
|
|
||||||
|
#include "CardObject.h"
|
||||||
|
#include "CardKey.h"
|
||||||
|
#include "SlotList.h"
|
||||||
|
#include "CertificateList.h"
|
||||||
|
#include "SecOpGuard.h"
|
||||||
|
|
||||||
|
#include <actIToken.h>
|
||||||
|
#include <actITokenKey.h>
|
||||||
|
#include <actITokenPIN.h>
|
||||||
|
#include <actMode.h>
|
||||||
|
#include <actState.h>
|
||||||
|
#include <actUtility.h>
|
||||||
|
#include <actDebug.h>
|
||||||
|
#include <actSlotManager.h>
|
||||||
|
#include <actAlgorithm.h>
|
||||||
|
#include <actISlot.h>
|
||||||
|
|
||||||
|
// Provide thread synchronization
|
||||||
|
#include <SyncObject.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
EVP_PKEY *SecureTokenEngine::encapsule_CardKey(CardKey *ck)
|
||||||
|
{
|
||||||
|
EVP_PKEY* pk(EVP_PKEY_new());
|
||||||
|
RSA* rsa(RSA_new());
|
||||||
|
|
||||||
|
if(pk == NULL || rsa == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Initialize the RSA structure
|
||||||
|
{
|
||||||
|
|
||||||
|
RSA_set_method(rsa, RSA_get_sct_method());
|
||||||
|
RSA_set_app_data(rsa, ck);
|
||||||
|
|
||||||
|
// We need (at least) the public exponent and the modulus for OpenSSL itself because
|
||||||
|
// it calculates the I/O buffer sizes out of it.
|
||||||
|
act::ITokenKey* key = ck->getKey();
|
||||||
|
|
||||||
|
act::Blob publicExponent;
|
||||||
|
act::Blob modulus;
|
||||||
|
|
||||||
|
key->GetParam(act::PUBLICKEY, publicExponent);
|
||||||
|
key->GetParam(act::MODULO, modulus);
|
||||||
|
act::I2OSP(modulus);
|
||||||
|
act::I2OSP(publicExponent);
|
||||||
|
rsa->n = BN_bin2bn(&modulus[0], modulus.size(), rsa->n);
|
||||||
|
rsa->e = BN_bin2bn(&publicExponent[0], publicExponent.size(), rsa->e);
|
||||||
|
|
||||||
|
// Meh. Set it here. If we don't, OpenSSL tries to emulate sign/verify with
|
||||||
|
// private_encrypt and public_decrypt which we can't do.
|
||||||
|
rsa->flags |= RSA_FLAG_SIGN_VER;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY_set1_RSA(pk, rsa);
|
||||||
|
|
||||||
|
// Decreases refcount by one, i.e. transfers sole ownership to EVP_PKEY struct
|
||||||
|
RSA_free(rsa);
|
||||||
|
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::setPin(char *pin)
|
||||||
|
{
|
||||||
|
int plen = strlen(pin);
|
||||||
|
act::Blob(pin, pin+plen).swap(m_pin);
|
||||||
|
std::fill(pin, pin+plen, '*');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::incVerbosity()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::setInitArgs(const char *args)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SecureTokenEngine::init()
|
||||||
|
{
|
||||||
|
act::Init(true);
|
||||||
|
|
||||||
|
act::SlotManager slot_manager;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
slot_manager.Install(act::SubsystemReg::CreateSubsystem("PCSC", 0));
|
||||||
|
slot_manager.Refresh();
|
||||||
|
}
|
||||||
|
catch(act::Exception& ACT_DEBUG_PARAM(e))
|
||||||
|
{
|
||||||
|
ACT_TRACE(e, "SecureTokenEngine::Init");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int slots = slot_manager.GetSlotNumber();
|
||||||
|
|
||||||
|
for(int i = 0; i < slots; i++)
|
||||||
|
{
|
||||||
|
act::ISlot* slot(slot_manager.GetSlot(i)->Clone());
|
||||||
|
m_slot_list.addSlot(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::finish()
|
||||||
|
{
|
||||||
|
m_slot_list.clear();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::rsa_finish(RSA *rsa)
|
||||||
|
{
|
||||||
|
// This function is only called on freeing of 'our' own RSA keys which have been generated
|
||||||
|
// by encapsule_CardKey
|
||||||
|
|
||||||
|
// NB: If you use something like
|
||||||
|
//
|
||||||
|
// EVP_PKEY* pk_pub = ENGINE_load_public_key(e, key_id, NULL, NULL);
|
||||||
|
// RSA* pubkey = EVP_PKEY_get1_RSA(pk_pub);
|
||||||
|
//
|
||||||
|
// in the user code, you have to use both EVP_PKEY_free() and RSA_free() until the last traces are gone.
|
||||||
|
|
||||||
|
CardKey* ck(EXTRACT_CARD_KEY(rsa));
|
||||||
|
|
||||||
|
ACT_ASSERT(ck != 0);
|
||||||
|
|
||||||
|
delete ck;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::loadCertCtrl(ENGINE *e, load_cert_params *p)
|
||||||
|
{
|
||||||
|
CardObject co(&m_slot_list);
|
||||||
|
|
||||||
|
ACT_ASSERT(p != NULL);
|
||||||
|
ACT_ASSERT(p->s_token_cert_id != NULL);
|
||||||
|
|
||||||
|
if(p == NULL || p->s_token_cert_id == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!co.searchFor(act::CERTIFICATE, p->s_token_cert_id))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
const act::Blob& certblob = co.getCertBlob();
|
||||||
|
const unsigned char *cbp = &certblob[0];
|
||||||
|
|
||||||
|
p->cert = d2i_X509(NULL, &cbp, certblob.size());
|
||||||
|
|
||||||
|
return p->cert != NULL ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY *SecureTokenEngine::load_privkey(const char *s_key_id, UI_METHOD *ui_method, void *callback_data)
|
||||||
|
{
|
||||||
|
CardObject co(&m_slot_list);
|
||||||
|
|
||||||
|
if(!co.searchFor(act::PRIVATEKEY, s_key_id))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
std::auto_ptr<CardKey> ck(new CardKey(co.getKey()));
|
||||||
|
|
||||||
|
// Ask for the PIN if not already passed into the module
|
||||||
|
if(m_pin.empty())
|
||||||
|
ck->setPin(ui_method, callback_data);
|
||||||
|
else
|
||||||
|
ck->setPin(m_pin);
|
||||||
|
|
||||||
|
// Try to authenticate with the provided PIN. If we fail, don't return the key at all.
|
||||||
|
act::IToken* token = ck->getKey()->GetToken();
|
||||||
|
SecOpGuard guard(token);
|
||||||
|
act::Synchronize lock(*token);
|
||||||
|
|
||||||
|
if(!ck->Authenticate(guard))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
EVP_PKEY* pk = encapsule_CardKey(ck.get());
|
||||||
|
|
||||||
|
if(pk != NULL)
|
||||||
|
{
|
||||||
|
ck.release();
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY *SecureTokenEngine::load_pubkey(const char *s_key_id, UI_METHOD *ui_method, void *callback_data)
|
||||||
|
{
|
||||||
|
// Really. Same as above, but without asking/setting a PIN. Simply because one can use an instance of
|
||||||
|
// act::ITokenKey for both ways since private and public keys are interlinked internally.
|
||||||
|
CardObject co(&m_slot_list);
|
||||||
|
|
||||||
|
if(!co.searchFor(act::PUBLICKEY, s_key_id))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
std::auto_ptr<CardKey> ck(new CardKey(co.getKey()));
|
||||||
|
|
||||||
|
EVP_PKEY* pk = encapsule_CardKey(ck.get());
|
||||||
|
|
||||||
|
if(pk != NULL)
|
||||||
|
{
|
||||||
|
ck.release();
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::rsa_encrypt(int flen, const unsigned char *from, unsigned char *to, const CardKey* ck, int padding)
|
||||||
|
{
|
||||||
|
if(padding != RSA_PKCS1_PADDING)
|
||||||
|
{
|
||||||
|
ACT_TRACE("SecureTokenEngine::rsa_encrypt: Only RSA_PKCS1_PADDING allowed so far\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ck == NULL)
|
||||||
|
{
|
||||||
|
ACT_TRACE("SecureTokenEngine::rsa_encrypt: No CardKey given\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
act::Blob _plaintext(from, from+flen);
|
||||||
|
act::Blob _ciphertext;
|
||||||
|
int retlen = -1;
|
||||||
|
|
||||||
|
act::IToken* token = ck->getKey()->GetToken();
|
||||||
|
SecOpGuard guard(token);
|
||||||
|
act::Synchronize lock(*token);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
act::Algorithm alg(ck->getKey(), act::ENCRYPT);
|
||||||
|
alg << _plaintext << act::final >> _ciphertext;
|
||||||
|
retlen = _ciphertext.size();
|
||||||
|
|
||||||
|
// OpenSSL uses these operations for just one round and determines the buffer size from the
|
||||||
|
// key length. Still I'm not happy with it.
|
||||||
|
std::copy(_ciphertext.begin(), _ciphertext.end(), to);
|
||||||
|
}
|
||||||
|
catch(act::Exception& ACT_DEBUG_PARAM(e))
|
||||||
|
{
|
||||||
|
ACT_TRACE(e, "SecureTokenEngine::rsa_encrypt");
|
||||||
|
}
|
||||||
|
|
||||||
|
return retlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::rsa_decrypt(int flen, const unsigned char *from, unsigned char *to, CardKey* ck, int padding)
|
||||||
|
{
|
||||||
|
if(padding != RSA_PKCS1_PADDING)
|
||||||
|
{
|
||||||
|
ACT_TRACE("SecureTokenEngine::rsa_decrypt: Only RSA_PKCS1_PADDING allowed so far\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ck == NULL)
|
||||||
|
{
|
||||||
|
ACT_TRACE("SecureTokenEngine::rsa_decrypt: No CardKey given\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
act::IToken* token = ck->getKey()->GetToken();
|
||||||
|
SecOpGuard guard(token);
|
||||||
|
act::Synchronize lock(*token);
|
||||||
|
|
||||||
|
if(!ck->Authenticate(guard))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
act::Blob _ciphertext(from, from+flen);
|
||||||
|
act::Blob _plaintext;
|
||||||
|
int retlen = -1;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
act::Algorithm alg(ck->getKey(), act::DECRYPT);
|
||||||
|
alg << _ciphertext << act::final >> _plaintext;
|
||||||
|
retlen = _plaintext.size();
|
||||||
|
|
||||||
|
// Same as with rsa_encrypt
|
||||||
|
std::copy(_plaintext.begin(), _plaintext.end(), to);
|
||||||
|
}
|
||||||
|
catch(act::Exception& ACT_DEBUG_PARAM(e))
|
||||||
|
{
|
||||||
|
ACT_TRACE(e, "SecureTokenEngine::rsa_decrypt");
|
||||||
|
}
|
||||||
|
|
||||||
|
return retlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::rsa_sign(int type, const unsigned char *msg, unsigned int msglen, unsigned char *sigret, unsigned int *siglen, CardKey* ck)
|
||||||
|
{
|
||||||
|
if(ck == NULL)
|
||||||
|
{
|
||||||
|
ACT_TRACE("SecureTokenEngine::rsa_sign: No CardKey given\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
act::IToken* token = ck->getKey()->GetToken();
|
||||||
|
SecOpGuard guard(ck->getKey()->GetToken());
|
||||||
|
act::Synchronize lock(*token);
|
||||||
|
|
||||||
|
if(!ck->Authenticate(guard))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
act::Blob _plaintext(msg, msg+msglen);
|
||||||
|
act::Blob _signature;
|
||||||
|
unsigned int _siglen = 0;
|
||||||
|
|
||||||
|
// In that case the hashing is already done and we just need the lowlevel key operation
|
||||||
|
bool ssl = (type == NID_md5_sha1);
|
||||||
|
|
||||||
|
act::ITokenKey* key = ck->getKey();
|
||||||
|
act::Blob oldhash;
|
||||||
|
key->GetParam(act::HASH, oldhash);
|
||||||
|
|
||||||
|
if(ssl)
|
||||||
|
key->SetParam(act::HASH, "DummyHash");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
act::Algorithm alg(ck->getKey(), act::SIGN);
|
||||||
|
alg << _plaintext << act::final >> _signature;
|
||||||
|
_siglen = _signature.size();
|
||||||
|
|
||||||
|
// I won't repeat myself here....
|
||||||
|
std::copy(_signature.begin(), _signature.end(), sigret);
|
||||||
|
}
|
||||||
|
catch(act::Exception& ACT_DEBUG_PARAM(e))
|
||||||
|
{
|
||||||
|
ACT_TRACE(e, "SecureTokenEngine::rsa_sign");
|
||||||
|
}
|
||||||
|
|
||||||
|
key->SetParam(act::HASH, oldhash);
|
||||||
|
|
||||||
|
*siglen = _siglen;
|
||||||
|
return _siglen > 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::rsa_verify(int type, const unsigned char *msg, unsigned int msglen, unsigned char *signature, unsigned int siglen, const CardKey* ck)
|
||||||
|
{
|
||||||
|
if(ck == NULL)
|
||||||
|
{
|
||||||
|
ACT_TRACE("SecureTokenEngine::rsa_verify: No CardKey given\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
act::IToken* token = ck->getKey()->GetToken();
|
||||||
|
SecOpGuard guard(token);
|
||||||
|
act::Synchronize lock(*token);
|
||||||
|
|
||||||
|
act::Blob _plaintext(msg, msg+msglen);
|
||||||
|
act::Blob _signature(signature, signature+siglen);
|
||||||
|
bool sig_ok = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
act::Algorithm alg(ck->getKey(), act::VERIFY, _signature);
|
||||||
|
alg << _plaintext << act::final;
|
||||||
|
sig_ok = alg.GetStatus() == act::SIGNATURE_OK;
|
||||||
|
}
|
||||||
|
catch(act::Exception& ACT_DEBUG_PARAM(e))
|
||||||
|
{
|
||||||
|
ACT_TRACE(e, "SecureTokenEngine::rsa_verify");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!sig_ok)
|
||||||
|
RSAerr(RSA_F_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
|
||||||
|
|
||||||
|
return sig_ok ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureTokenEngine::enumerate_certs(ENGINE *e, enum_certs_s **p)
|
||||||
|
{
|
||||||
|
if(p == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Drop and free old instance (if present) and create a fresh one.
|
||||||
|
m_cert_list.reset(new CertificateList());
|
||||||
|
|
||||||
|
m_cert_list->init(m_slot_list);
|
||||||
|
|
||||||
|
*p = m_cert_list->getEnumList();
|
||||||
|
|
||||||
|
// Only way to return 0 would be that we ran out of memory. If there are no certificates to be found
|
||||||
|
// we would return successful, but with an empty list (num_certs == 0)
|
||||||
|
return *p ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
38
openssl-act-engine/engine_sct.h
Normal file
38
openssl-act-engine/engine_sct.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
#ifndef _ENGINE_SCT_H_
|
||||||
|
#define _ENGINE_SCT_H_
|
||||||
|
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
// Zero-sized array
|
||||||
|
#pragma warning(disable: 4200)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parameter structure to be passed to the engine call "LOAD_CERT_CTRL"
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct load_cert_params
|
||||||
|
{
|
||||||
|
const char* s_token_cert_id; // in
|
||||||
|
X509* cert; // out
|
||||||
|
};
|
||||||
|
|
||||||
|
struct enum_cert_s
|
||||||
|
{
|
||||||
|
const char* id; // ID which can be passed as key ID for crypto operations
|
||||||
|
const char* name; // Alternatively one can use the name, provided it's unique for the token.
|
||||||
|
X509* cert; // Decoded certificate
|
||||||
|
};
|
||||||
|
|
||||||
|
struct enum_certs_s
|
||||||
|
{
|
||||||
|
unsigned int num_certs; // Number of certificates present
|
||||||
|
enum_cert_s certificate[]; // Array of identifiers and certificates
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
90
openssl-act-engine/engine_sct_internal.h
Normal file
90
openssl-act-engine/engine_sct_internal.h
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
#ifndef _ENGINE_SCT_INTERNAL_H_
|
||||||
|
#define _ENGINE_SCT_INTERNAL_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma comment(lib, "libeay32.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef U64
|
||||||
|
#undef U64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <actBlob.h>
|
||||||
|
|
||||||
|
struct load_cert_params;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "SlotList.h"
|
||||||
|
#include "CertificateList.h"
|
||||||
|
|
||||||
|
class CardKey;
|
||||||
|
struct enum_certs_s;
|
||||||
|
|
||||||
|
#define EXTRACT_CARD_KEY(rsastruct) (reinterpret_cast<CardKey*>(RSA_get_app_data(rsastruct)))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Core module. Actual engine startup/finish code and crypto operations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SecureTokenEngine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SecureTokenEngine() { }
|
||||||
|
~SecureTokenEngine() { }
|
||||||
|
|
||||||
|
// NOTE: contents of source string will be overwritten for security reasons
|
||||||
|
int setPin(char *pin);
|
||||||
|
|
||||||
|
int incVerbosity();
|
||||||
|
int setInitArgs(const char *args);
|
||||||
|
|
||||||
|
int init();
|
||||||
|
int finish();
|
||||||
|
|
||||||
|
int rsa_finish(RSA *rsa);
|
||||||
|
|
||||||
|
int loadCertCtrl(ENGINE *e, load_cert_params *p);
|
||||||
|
EVP_PKEY *load_pubkey(const char *s_key_id, UI_METHOD *ui_method, void *callback_data);
|
||||||
|
EVP_PKEY *load_privkey(const char *s_key_id, UI_METHOD *ui_method, void *callback_data);
|
||||||
|
|
||||||
|
// Caller is required to provide an output buffer of sufficient size, depending on input data's length
|
||||||
|
// and used key material. Improper usage may cause buffer overruns. OpenSSL API's weakness.
|
||||||
|
|
||||||
|
// Encrypt/Decrypt return size of output data on success, -1 on failure.
|
||||||
|
int rsa_encrypt(int flen, const unsigned char *from, unsigned char *to, const CardKey* ck, int padding);
|
||||||
|
int rsa_decrypt(int flen, const unsigned char *from, unsigned char *to, CardKey* ck, int padding);
|
||||||
|
|
||||||
|
// Sign/Verify return 1 on success, 0 on failure.
|
||||||
|
int rsa_sign(int type, const unsigned char *msg, unsigned int msglen, unsigned char *sigret, unsigned int *siglen, CardKey* ck);
|
||||||
|
int rsa_verify(int type, const unsigned char *msg, unsigned int msglen, unsigned char *signature, unsigned int siglen, const CardKey* ck);
|
||||||
|
|
||||||
|
// Return a list of all certificates and the necessary IDs to use them
|
||||||
|
// !! frees up the memory of the previosly returned structure in subsequent calls !!
|
||||||
|
int enumerate_certs(ENGINE *e, enum_certs_s **p);
|
||||||
|
|
||||||
|
private:
|
||||||
|
EVP_PKEY *encapsule_CardKey(CardKey *ck);
|
||||||
|
|
||||||
|
act::Blob m_pin;
|
||||||
|
SlotList m_slot_list;
|
||||||
|
std::auto_ptr<CertificateList> m_cert_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Needed in SecureTokenEngine for creation of new RSA key (stubs) as well
|
||||||
|
RSA_METHOD* RSA_get_sct_method();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
6
openssl-act-engine/engine_securetoken.cpp
Normal file
6
openssl-act-engine/engine_securetoken.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// engine_securetoken.cpp : Defines the exported functions for the DLL application.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
|
24
openssl-act-engine/engine_securetoken.sln
Normal file
24
openssl-act-engine/engine_securetoken.sln
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "engine_securetoken", "engine_securetoken.vcproj", "{A1D90F74-60E0-4ED0-A93D-F626A754310D}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SubversionScc) = preSolution
|
||||||
|
Svn-Managed = True
|
||||||
|
Manager = AnkhSVN - Subversion Support for Visual Studio
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{A1D90F74-60E0-4ED0-A93D-F626A754310D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{A1D90F74-60E0-4ED0-A93D-F626A754310D}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{A1D90F74-60E0-4ED0-A93D-F626A754310D}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{A1D90F74-60E0-4ED0-A93D-F626A754310D}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
347
openssl-act-engine/engine_securetoken.vcproj
Normal file
347
openssl-act-engine/engine_securetoken.vcproj
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9,00"
|
||||||
|
Name="engine_securetoken"
|
||||||
|
ProjectGUID="{A1D90F74-60E0-4ED0-A93D-F626A754310D}"
|
||||||
|
RootNamespace="engine_securetoken"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="/actlibrary/Source/EMSA;/actlibrary/Source/Random;/actlibrary/Source/Padding;/actlibrary/Source/Certificate;/actlibrary/Source/Hash;/actlibrary/Source/PublicKey;/actlibrary/Source/SecureToken;/actlibrary/Source/Frame;/openssl/include"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;ENGINE_SECURETOKEN_EXPORTS;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="actvcmtd.lib"
|
||||||
|
OutputFile="$(OutDir)\engine_act.dll"
|
||||||
|
LinkIncremental="2"
|
||||||
|
AdditionalLibraryDirectories=""\actlibrary\Source\lib_VC_2008\$(PlatformName)";\openssl\lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="/actlibrary/Source/EMSA;/actlibrary/Source/Random;/actlibrary/Source/Padding;/actlibrary/Source/Certificate;/actlibrary/Source/Hash;/actlibrary/Source/PublicKey;/actlibrary/Source/SecureToken;/actlibrary/Source/Frame;/openssl/include"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;ENGINE_SECURETOKEN_EXPORTS;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="actvcmt.lib"
|
||||||
|
OutputFile="$(OutDir)\engine_act.dll"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories=""\actlibrary\Source\lib_VC_2008\$(PlatformName)";\openssl\lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\CardKey.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\CardObject.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\CertificateList.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\dllmain.cpp"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
CompileAsManaged="0"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
CompileAsManaged="0"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\engine_front.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\engine_sct.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\engine_securetoken.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\SecOpGuard.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\SlotList.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\stdafx.cpp"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
UsePrecompiledHeader="1"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
UsePrecompiledHeader="1"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\test_engine.cpp"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\CardKey.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\CardObject.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\CertificateList.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\engine_sct.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\engine_sct_internal.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Init_Engine.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\SecOpGuard.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\SlotList.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\stdafx.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\targetver.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Warns.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Misc"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Makefile"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ReadMe.txt"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
8
openssl-act-engine/stdafx.cpp
Normal file
8
openssl-act-engine/stdafx.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// stdafx.cpp : source file that includes just the standard includes
|
||||||
|
// engine_securetoken.pch will be the pre-compiled header
|
||||||
|
// stdafx.obj will contain the pre-compiled type information
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
// TODO: reference any additional headers you need in STDAFX.H
|
||||||
|
// and not in this file
|
16
openssl-act-engine/stdafx.h
Normal file
16
openssl-act-engine/stdafx.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// stdafx.h : include file for standard system include files,
|
||||||
|
// or project specific include files that are used frequently, but
|
||||||
|
// are changed infrequently
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "targetver.h"
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||||
|
// Windows Header Files:
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: reference additional headers your program requires here
|
24
openssl-act-engine/targetver.h
Normal file
24
openssl-act-engine/targetver.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// The following macros define the minimum required platform. The minimum required platform
|
||||||
|
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
|
||||||
|
// your application. The macros work by enabling all features available on platform versions up to and
|
||||||
|
// including the version specified.
|
||||||
|
|
||||||
|
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
||||||
|
// Refer to MSDN for the latest info on corresponding values for different platforms.
|
||||||
|
#ifndef WINVER // Specifies that the minimum required platform is Windows Vista.
|
||||||
|
#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
|
||||||
|
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98.
|
||||||
|
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0.
|
||||||
|
#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE.
|
||||||
|
#endif
|
84
openssl-act-engine/test_engine.cpp
Normal file
84
openssl-act-engine/test_engine.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
#include "engine_sct.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
ENGINE* e = NULL;
|
||||||
|
enum_certs_s* certs_found = NULL;
|
||||||
|
|
||||||
|
ENGINE_load_dynamic();
|
||||||
|
e = ENGINE_by_id("dynamic");
|
||||||
|
|
||||||
|
int res;
|
||||||
|
|
||||||
|
// Parameters to set for the dynamic loader
|
||||||
|
res = ENGINE_ctrl_cmd_string(e, "SO_PATH", "/home/carsten/engine_securetoken/libengine_securetoken.so", 0);
|
||||||
|
res = ENGINE_ctrl_cmd_string(e, "ID", "securetoken", 0);
|
||||||
|
res = ENGINE_ctrl_cmd_string(e, "LIST_ADD", "1", 0);
|
||||||
|
|
||||||
|
// Now actually load the SecureToken engine.
|
||||||
|
res = ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0);
|
||||||
|
|
||||||
|
// Following control commands go to the SecureToken engine rather than the dynamic loader
|
||||||
|
|
||||||
|
res = ENGINE_init(e);
|
||||||
|
|
||||||
|
res = ENGINE_ctrl_cmd(e, "ENUM_CERTS", 0, &certs_found, NULL, 0);
|
||||||
|
|
||||||
|
printf("Found %d certificates.\n", certs_found->num_certs);
|
||||||
|
|
||||||
|
enum_cert_s* selected_cert = NULL;
|
||||||
|
|
||||||
|
for(int i=0;i<certs_found->num_certs;i++)
|
||||||
|
{
|
||||||
|
printf("Certificate %d:\n", i);
|
||||||
|
printf(" Name: %s\n", certs_found->certificate[i].cert->name);
|
||||||
|
|
||||||
|
if(certs_found->certificate[i].id == NULL)
|
||||||
|
printf(" No key.\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(" Key access ID: %s\n", certs_found->certificate[i].id);
|
||||||
|
if(!selected_cert) selected_cert = &certs_found->certificate[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY* pk_pub = ENGINE_load_public_key(e, selected_cert->id, NULL, NULL);
|
||||||
|
RSA* pubkey = EVP_PKEY_get1_RSA(pk_pub);
|
||||||
|
|
||||||
|
const char* source = "Dies ist ein geheimer Testtext zum Verschlüsseln\n";
|
||||||
|
int srclen = strlen(source)+1;
|
||||||
|
|
||||||
|
unsigned char cipherbuf[srclen*2048];
|
||||||
|
int ciphlen = RSA_public_encrypt(srclen, (const unsigned char *) source, cipherbuf, pubkey, RSA_PKCS1_PADDING);
|
||||||
|
|
||||||
|
EVP_PKEY_free(pk_pub);
|
||||||
|
RSA_free(pubkey);
|
||||||
|
|
||||||
|
EVP_PKEY* pk_priv = ENGINE_load_private_key(e, selected_cert->id, NULL, NULL);
|
||||||
|
RSA* privkey = EVP_PKEY_get1_RSA(pk_priv);
|
||||||
|
|
||||||
|
char plainbuf[srclen*2];
|
||||||
|
int plainlen = RSA_private_decrypt(ciphlen, cipherbuf, (unsigned char *) plainbuf, privkey, RSA_PKCS1_PADDING);
|
||||||
|
|
||||||
|
EVP_PKEY_free(pk_priv);
|
||||||
|
RSA_free(privkey);
|
||||||
|
|
||||||
|
if(srclen != plainlen || strcmp(source, plainbuf))
|
||||||
|
printf("Unterschied in Ver/Entschlüsselung");
|
||||||
|
else
|
||||||
|
printf("%s",plainbuf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
res = ENGINE_finish(e);
|
||||||
|
|
||||||
|
ENGINE_cleanup();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user