first cleanup; still missing: RPM/Debian packages, pkgconfig, version compiled-in-version-info; refs #7
This commit is contained in:
108
openssl-act-engine/src/CardKey.cpp
Normal file
108
openssl-act-engine/src/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/src/CardKey.h
Normal file
46
openssl-act-engine/src/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/src/CardObject.cpp
Normal file
144
openssl-act-engine/src/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->Release();
|
||||
}
|
||||
|
||||
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/src/CardObject.h
Normal file
40
openssl-act-engine/src/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/src/CertificateList.cpp
Normal file
179
openssl-act-engine/src/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->Release();
|
||||
|
||||
}
|
||||
// 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/src/CertificateList.h
Normal file
40
openssl-act-engine/src/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/src/Init_Engine.h
Normal file
225
openssl-act-engine/src/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
|
48
openssl-act-engine/src/SecOpGuard.cpp
Normal file
48
openssl-act-engine/src/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/src/SecOpGuard.h
Normal file
33
openssl-act-engine/src/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/src/SlotList.cpp
Normal file
138
openssl-act-engine/src/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->Release();
|
||||
m_token = NULL;
|
||||
}
|
||||
|
||||
void SlotEntry::cleanup()
|
||||
{
|
||||
invalidate_token();
|
||||
if(m_slot)
|
||||
m_slot->Release();
|
||||
m_slot = NULL;
|
||||
}
|
||||
|
||||
act::IToken* SlotEntry::getToken()
|
||||
{
|
||||
preload_token();
|
||||
|
||||
if(m_token != NULL)
|
||||
m_token->AddRef();
|
||||
|
||||
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/src/SlotList.h
Normal file
64
openssl-act-engine/src/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/src/SyncObject.h
Normal file
184
openssl-act-engine/src/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/src/SyncObjectMacOS.h
Normal file
46
openssl-act-engine/src/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/src/SyncObjectPosix.h
Normal file
38
openssl-act-engine/src/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/src/SyncObjectSolaris.h
Normal file
38
openssl-act-engine/src/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/src/SyncObjectWin32.h
Normal file
39
openssl-act-engine/src/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/src/SyncObjectWinCE.h
Normal file
36
openssl-act-engine/src/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/src/Warns.h
Normal file
7
openssl-act-engine/src/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
|
654
openssl-act-engine/src/actUtility.h
Normal file
654
openssl-act-engine/src/actUtility.h
Normal file
@@ -0,0 +1,654 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Name: actUtility.h
|
||||
// Product: cv act library
|
||||
// Purpose: useful global functions
|
||||
//
|
||||
// Copyright: (c) 2000-2001 cv cryptovision GmbH
|
||||
// all rights reserved
|
||||
// Licence: The conditions for the use of this software are regulated
|
||||
// in the cv act library licence agreement.
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ACT_Utility_h
|
||||
#define ACT_Utility_h
|
||||
|
||||
#include "actBlob.h"
|
||||
#include "actBasics.h"
|
||||
#include "actException.h"
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cwctype>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ < 4)
|
||||
namespace act { typedef std::basic_string<wchar_t> wstring; }
|
||||
#else
|
||||
namespace act { using std::wstring; }
|
||||
#endif
|
||||
|
||||
namespace act
|
||||
{
|
||||
class IParam;
|
||||
|
||||
//
|
||||
// Const Values
|
||||
//
|
||||
|
||||
extern const size_t sizeof_uuid;
|
||||
|
||||
//
|
||||
// Prototypes
|
||||
//
|
||||
|
||||
const char* get_string_param(paramid_t id, IParam* owner);
|
||||
|
||||
// Converts an unsigned hexadecimal number (independent of prefix "0x")
|
||||
// into a Blob and backwards.
|
||||
// - for blob2hex: the user has to allocate hexnumber
|
||||
Blob& hex2blob(const char* hexnumber, Blob& b);
|
||||
inline Blob& hex2blob(const std::string& hexnumber, Blob& b)
|
||||
{
|
||||
return hex2blob(hexnumber.c_str(), b);
|
||||
}
|
||||
inline Blob hex2blob(const char* hexnumber)
|
||||
{
|
||||
Blob b;
|
||||
return move(hex2blob(hexnumber, b));
|
||||
}
|
||||
|
||||
void blob2hex(const Blob& b, char* hexnumber);
|
||||
std::string blob2hex(const Blob& b);
|
||||
|
||||
// file i/o for act::Blob
|
||||
bool file2blob(const char* filename, Blob &blob);
|
||||
bool blob2file(const char* filename, const act::Blob &blob);
|
||||
|
||||
// Create an ISO 9834-8 / RFC 4122 version 4 (pseudo random) UUID.
|
||||
// Output string format is "xxxxxxxx-xxxx-4xxx-vxxx-xxxxxxxxxxxx", where
|
||||
// x is random hex char 0 <= x <= f and v an element of { 8, 9, a, b}.
|
||||
void createPseudoRandomUUID(Blob& uuid, bool network_byte_order = true);
|
||||
std::string createPseudoRandomUUID();
|
||||
std::string uuid2string(const Blob& uuid, bool is_network_byte_order = true);
|
||||
void swapTimeFields(Blob& uuid);
|
||||
|
||||
std::string serno2string(const act::Blob& serno);
|
||||
std::string id2string(const act::Blob& id, bool is_network_byte_order = true);
|
||||
|
||||
// CBCMAC with ISO padding
|
||||
void iCBCMAC(const char* cipher, const Blob& iv, const Blob& mac_key,
|
||||
const Blob& mac_data, Blob& mac);
|
||||
|
||||
void SetDESKeyParity(Blob &key);
|
||||
bool CheckDESKeyParity(const Blob &key);
|
||||
|
||||
void get_string_seq(const std::string& s, const std::string start, const std::string end,
|
||||
std::string& result, bool case_sens);
|
||||
|
||||
bool wstr2utf8(const wchar_t* str, std::string& utf8);
|
||||
bool utf82wstr(const char* utf8, act::wstring& wstr);
|
||||
|
||||
void ASN1ToSequenceOf(Blob& asn1_data);
|
||||
Blob GetASN1SequenceOf(const Blob& asn1_data);
|
||||
Blob GetASN1EncodedLength(size_t length);
|
||||
|
||||
size_t SkipTagLength(byte tag, const byte* tlv_data, size_t tlv_data_len);
|
||||
size_t SkipTLVElement(byte tag, const byte* tlv_data, size_t tlv_data_len, bool skip_value = true);
|
||||
int FindTlvTemplate(Blob& contentb, const Blob& inb, int intag, int counts);
|
||||
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
template<typename ConverterT, typename RegistryT, typename TypeT>
|
||||
const Blob SafeGetName(TypeT* instance)
|
||||
{
|
||||
Blob name;
|
||||
if(instance != 0)
|
||||
{
|
||||
const char* cname = RegistryT::GetName(instance->GetCreatePointer());
|
||||
if(cname != 0) ConverterT(cname).swap(name);
|
||||
}
|
||||
return move(name);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<typename TypeT>
|
||||
struct is_whitespace : is_whitespace<typename TypeT::value_type>
|
||||
{
|
||||
typedef typename TypeT::value_type argument_type;
|
||||
using is_whitespace<typename TypeT::value_type>::operator();
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_whitespace<char>
|
||||
{
|
||||
typedef char argument_type;
|
||||
bool operator()(unsigned char value) const { return std::isspace(value) != 0; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_whitespace<wchar_t>
|
||||
{
|
||||
typedef wchar_t argument_type;
|
||||
bool operator()(wchar_t value) const { return std::iswspace(value) != 0; }
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<typename PredicateT, typename TypeT>
|
||||
inline TypeT& erase_right(const PredicateT& predicate, TypeT& value)
|
||||
{
|
||||
value.erase(std::find_if(value.rbegin(), value.rend(), predicate).base(), value.end());
|
||||
return value;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<typename TypeT>
|
||||
inline void fill(TypeT* begin, size_t length, byte value)
|
||||
{
|
||||
ACT_ASSERT(begin != 0);
|
||||
std::fill(reinterpret_cast<act::byte*>(begin),
|
||||
reinterpret_cast<act::byte*>(begin) + length, value);
|
||||
}
|
||||
|
||||
//
|
||||
// scoped_delete<PointerT>
|
||||
// ---------------------------------------------------------------------------
|
||||
template<typename PointerT>
|
||||
struct scoped_delete<PointerT, void, 1>
|
||||
{
|
||||
PointerT _ptr;
|
||||
|
||||
explicit scoped_delete(PointerT ptr) : _ptr(ptr) { }
|
||||
~scoped_delete() { delete _ptr; }
|
||||
|
||||
PointerT operator->() const
|
||||
{
|
||||
if(_ptr == 0) throw NullPointerException();
|
||||
return _ptr;
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<typename PointerT>
|
||||
scoped_delete<PointerT, void, 1> checked_delete(PointerT& ptr_ref)
|
||||
{
|
||||
PointerT ptr = ptr_ref; ptr_ref = 0;
|
||||
return scoped_delete<PointerT, void, 1>(ptr);
|
||||
}
|
||||
|
||||
//
|
||||
// scoped_delete<AutoPtrT>
|
||||
// ---------------------------------------------------------------------------
|
||||
template
|
||||
<
|
||||
template<class> class AutoPtrT,
|
||||
class TypeT
|
||||
>
|
||||
struct scoped_delete<AutoPtrT<TypeT>, void, 1>
|
||||
{
|
||||
AutoPtrT<TypeT> _ptr;
|
||||
|
||||
explicit scoped_delete(AutoPtrT<TypeT>& ptr) : _ptr(ptr) { }
|
||||
~scoped_delete() { AutoPtrT<TypeT>(_ptr); }
|
||||
|
||||
TypeT* operator->() const
|
||||
{
|
||||
TypeT* ptr = _ptr.get();
|
||||
if(ptr == 0) throw NullPointerException();
|
||||
return ptr;
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template
|
||||
<
|
||||
template<class> class AutoPtrT,
|
||||
class TypeT
|
||||
>
|
||||
scoped_delete<AutoPtrT<TypeT>, void, 1> checked_delete(AutoPtrT<TypeT>& ptr_ref)
|
||||
{
|
||||
return scoped_delete<AutoPtrT<TypeT>, void, 1>(ptr_ref);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// scoped_delete<ArrayT<TypeT*> >
|
||||
// ---------------------------------------------------------------------------
|
||||
template
|
||||
<
|
||||
template<class, class> class ArrayT,
|
||||
class TypeT, class AllocatorT,
|
||||
typename DestructF
|
||||
>
|
||||
struct scoped_delete<ArrayT<TypeT, AllocatorT>, DestructF, 3>
|
||||
{
|
||||
typedef ArrayT<TypeT, AllocatorT> container_type;
|
||||
typedef DestructF destruct_func;
|
||||
|
||||
explicit scoped_delete(container_type& _container, const destruct_func& _destruct)
|
||||
: destruct(_destruct)
|
||||
{ container.swap(_container); }
|
||||
|
||||
~scoped_delete()
|
||||
{ release(container, destruct); }
|
||||
|
||||
static void release(container_type& container, const destruct_func& destruct)
|
||||
{
|
||||
if(container.empty() == true) return;
|
||||
|
||||
container_type failed;
|
||||
typedef typename container_type::const_iterator const_iterator;
|
||||
for(const_iterator i(container.begin()), end(container.end()); i != end; ++i)
|
||||
try { destruct(*i); }
|
||||
catch(Exception&) { failed.push_back(*i); }
|
||||
|
||||
container.swap(failed);
|
||||
}
|
||||
|
||||
destruct_func destruct;
|
||||
container_type container;
|
||||
};
|
||||
|
||||
//
|
||||
// checked_delete(array_of_ptr_to_type, std::mem_fun(&type::destruct));
|
||||
// ---------------------------------------------------------------------------
|
||||
template
|
||||
<
|
||||
template<class, class> class ArrayT,
|
||||
class TypeT, class AllocatorT,
|
||||
typename DestructF
|
||||
>
|
||||
scoped_delete<ArrayT<TypeT, AllocatorT>, DestructF, 3>
|
||||
checked_delete(ArrayT<TypeT, AllocatorT>& container, const DestructF& destruct)
|
||||
{
|
||||
return scoped_delete<ArrayT<TypeT, AllocatorT>, DestructF, 3>(container, destruct);
|
||||
}
|
||||
|
||||
//
|
||||
// scoped_delete<MapT<TypeT*> >
|
||||
// ---------------------------------------------------------------------------
|
||||
template
|
||||
<
|
||||
template<class, class, class, class> class MapT,
|
||||
class KeyT, class TypeT, class PredT, class AllocatorT,
|
||||
typename DestructF
|
||||
>
|
||||
struct scoped_delete<MapT<KeyT, TypeT, PredT, AllocatorT>, DestructF, 4>
|
||||
{
|
||||
typedef MapT<KeyT, TypeT, PredT, AllocatorT> container_type;
|
||||
typedef DestructF destruct_func;
|
||||
|
||||
explicit scoped_delete(container_type& _container, const destruct_func& _destruct)
|
||||
: destruct(_destruct)
|
||||
{ container.swap(_container); }
|
||||
|
||||
~scoped_delete()
|
||||
{ release(container, destruct); }
|
||||
|
||||
static void release(container_type& container, const destruct_func& destruct)
|
||||
{
|
||||
if(container.empty() == true) return;
|
||||
|
||||
container_type failed;
|
||||
typedef typename container_type::const_iterator const_iterator;
|
||||
for(const_iterator i(container.begin()), end(container.end()); i != end; ++i)
|
||||
try { destruct(i->second); }
|
||||
catch(Exception&) { failed.insert(*i); }
|
||||
|
||||
container.swap(failed);
|
||||
}
|
||||
|
||||
destruct_func destruct;
|
||||
container_type container;
|
||||
};
|
||||
|
||||
//
|
||||
// checked_delete_map(map_of_ptr_to_type, std::mem_fun(&type::destruct));
|
||||
// ---------------------------------------------------------------------------
|
||||
template
|
||||
<
|
||||
template<class, class, class, class> class MapT,
|
||||
class KeyT, class TypeT, class PredT, class AllocatorT,
|
||||
typename DestructF
|
||||
>
|
||||
scoped_delete<MapT<KeyT, TypeT, PredT, AllocatorT>, DestructF, 4>
|
||||
checked_delete_map(MapT<KeyT, TypeT, PredT, AllocatorT>& map_ref, const DestructF& destruct)
|
||||
{
|
||||
return scoped_delete<MapT<KeyT, TypeT, PredT, AllocatorT>, DestructF, 4>(map_ref, destruct);
|
||||
}
|
||||
|
||||
//
|
||||
// scoped_delete<>
|
||||
// ---------------------------------------------------------------------------
|
||||
template<typename TypeT, typename DestructF>
|
||||
struct scoped_delete<TypeT, DestructF, 0>
|
||||
{
|
||||
scoped_delete(const DestructF& _destruct)
|
||||
: destruct(_destruct)
|
||||
{ }
|
||||
|
||||
~scoped_delete()
|
||||
{ if(value.empty() == false) checked_delete(value, destruct); }
|
||||
|
||||
DestructF destruct;
|
||||
TypeT value;
|
||||
};
|
||||
|
||||
//
|
||||
// checked_static_cast<>
|
||||
// ---------------------------------------------------------------------------
|
||||
template<class U, class V>
|
||||
inline U checked_static_cast(V p)
|
||||
{
|
||||
ACT_ASSERT(p != 0);
|
||||
ACT_ASSERT(dynamic_cast<U>(p) != 0);
|
||||
return static_cast<U>(p);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<typename TypeT>
|
||||
inline TypeT& byref(const TypeT& e)
|
||||
{
|
||||
return const_cast<TypeT&>(e);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline int max_int()
|
||||
{
|
||||
return int((unsigned(1) << (8 * sizeof(int) - 1)) - 1);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void OS2IP(Blob& number)
|
||||
{
|
||||
// octet string to integer presentation
|
||||
if((number.at(0) & byte(0x80)) != 0)
|
||||
number.insert(number.begin(), 0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void I2OSP(Blob& number)
|
||||
{
|
||||
// integer to octet string presentation
|
||||
if(number.at(0) == byte(0))
|
||||
number.erase(number.begin());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void byte2long(const byte *in, size_t input_len, uint32 *out)
|
||||
{
|
||||
size_t i, output_len = input_len / 4;
|
||||
for(i = 0; i < output_len; i++)
|
||||
out[i]= in[i*4] | (in[i*4+1] << 8) | (in[i*4+2] << 16) | (in[i*4+3] << 24);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void long2byte(const uint32 *in, size_t input_len, byte *out)
|
||||
{
|
||||
size_t i, output_len = input_len * 4;
|
||||
for(i = 0; i < output_len; i++)
|
||||
out[i] = byte(in[i/4] >> (8*(i%4)));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void sweep(void* Mem,size_t l)
|
||||
{
|
||||
std::fill_n(reinterpret_cast<byte*>(Mem), l, byte(0));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<class TypeT>
|
||||
inline const TypeT Min(const TypeT& a, const TypeT& b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<class TypeT>
|
||||
inline const TypeT& Max(const TypeT& a, const TypeT& b)
|
||||
{
|
||||
return (a<b)? b : a;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<class T1, class T2, class T3>
|
||||
inline void xor_n(T1 a, T2 len, T3 b)
|
||||
{
|
||||
for(T2 i = 0; i < len; i++) b[i] ^= a[i];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<class T1, class T3> inline void Xor (T1 a, T1 a_end, T3 b)
|
||||
{
|
||||
while(a < a_end)
|
||||
*b++ ^= *a++;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline const char* blob2char(Blob& b)
|
||||
{
|
||||
b.push_back(byte(0));
|
||||
return reinterpret_cast<const char*>(&b[0]);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline std::string blob2string(const Blob& value)
|
||||
{
|
||||
return value.empty() == false ?
|
||||
std::string(reinterpret_cast<const std::string::value_type*>(&value.at(0)),
|
||||
reinterpret_cast<const std::string::value_type*>(&value[0] + value.size())) :
|
||||
std::string();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline std::string byte2hex(const byte i)
|
||||
{
|
||||
char tmp[3];
|
||||
sprintf(tmp, "%02x", i);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline bool isHex(const byte c)
|
||||
{
|
||||
if((c < byte('0') || c > byte('9'))
|
||||
&& (c < byte('a') || c > byte('f'))
|
||||
&& (c < byte('A') || c > byte('F')))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline bool isHex(const Blob& b)
|
||||
{
|
||||
size_t i, b_len = b.size();
|
||||
|
||||
for(i = 0; i < b_len; ++i)
|
||||
if(!isHex(b[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline bool isAlphanumeric(const byte c)
|
||||
{
|
||||
if((c < byte('0') || c > byte('9'))
|
||||
&& (c < byte('a') || c > byte('z'))
|
||||
&& (c < byte('A') || c > byte('Z')))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline bool isAlphanumeric(const Blob& b)
|
||||
{
|
||||
size_t i, b_len = b.size();
|
||||
|
||||
for(i = 0; i < b_len; ++i)
|
||||
if(!isAlphanumeric(b[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline bool isPrintable(const Blob& b)
|
||||
{
|
||||
size_t i, b_len = b.size();
|
||||
|
||||
for(i = 0; i < b_len; ++i)
|
||||
if(isprint(int(b[i])) == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline bool isUUIDFormat(const Blob& b)
|
||||
{
|
||||
size_t b_len = b.size();
|
||||
|
||||
if(b_len != sizeof_uuid)
|
||||
return false;
|
||||
|
||||
// check if the Blob contains only hexadecimal characters,
|
||||
// separated by '-' (UUID string representation)
|
||||
for(size_t i = 0; i < b_len; ++i)
|
||||
if(!isHex(b[i]) && (b[i] != byte('-')))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline std::string short2hex(const unsigned short i)
|
||||
{
|
||||
char tmp[5];
|
||||
sprintf(tmp,"%04x",i);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline std::string long2hex(const unsigned long i)
|
||||
{
|
||||
char tmp[9];
|
||||
sprintf(tmp,"%08lx",i);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline unsigned long blob2long(const Blob& b)
|
||||
{
|
||||
if(b.size() == 0)
|
||||
throw LogicalException("bad size","blob2long");
|
||||
|
||||
Blob tmp(b);
|
||||
while(tmp[0] == 0 && tmp.size() > sizeof(long))
|
||||
tmp.erase(tmp.begin());
|
||||
|
||||
if(tmp.size() > sizeof(long))
|
||||
throw LogicalException("bad size", "blob2long");
|
||||
|
||||
unsigned long n = tmp[0];
|
||||
for(unsigned int i = 1; i < tmp.size(); ++i)
|
||||
{
|
||||
n <<= 8;
|
||||
n |= tmp[i];
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline Blob& long2blob(unsigned long n, Blob& value)
|
||||
{
|
||||
value.resize(sizeof(long));
|
||||
for(size_t i = sizeof(long) - 1, j = 0; j < sizeof(long); --i, ++j)
|
||||
value[j] = byte((n >> (8 * i)) & 0xff);
|
||||
return value;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline Blob long2blob(unsigned long n)
|
||||
{
|
||||
Blob value;
|
||||
return move(long2blob(n, value));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline Blob size2blob(size_t size)
|
||||
{
|
||||
Blob tmp;
|
||||
tmp.reserve(8);
|
||||
|
||||
if(size == 0)
|
||||
{
|
||||
tmp.resize(1);
|
||||
return move(tmp);
|
||||
}
|
||||
size_t remaining = size;
|
||||
while(remaining > 0)
|
||||
{
|
||||
tmp.insert(tmp.begin(), byte(remaining & 0xFF));
|
||||
remaining >>= 8;
|
||||
}
|
||||
return move(tmp);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline unsigned short blob2short(const Blob& b)
|
||||
{
|
||||
if(b.size() != sizeof(short))
|
||||
throw LogicalException("bad size", "blob2short");
|
||||
|
||||
unsigned short n = b[1];
|
||||
n += (b[0] << 8);
|
||||
return n;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Input: a (big endian byte arrays)
|
||||
// Output: ++a (increment with carry)
|
||||
inline byte memincr(byte* a, int len)
|
||||
{
|
||||
int i = len-1;
|
||||
byte carry;
|
||||
do {
|
||||
carry = ++a[i] == 0 ? 1 : 0;
|
||||
} while( --i >= 0 && carry != 0);
|
||||
return carry;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Input: a, b (big endian byte arrays)
|
||||
// Output: a += b (add with carry)
|
||||
inline byte memadd(byte* a, const byte* b, int len, byte carry = 0)
|
||||
{
|
||||
int i = len - 1;
|
||||
unsigned long tmp;
|
||||
for(; i >= 0; --i)
|
||||
{
|
||||
tmp = a[i] + b[i] + carry;
|
||||
a[i] = byte(tmp & 0xff);
|
||||
carry = byte(tmp >> 8);
|
||||
}
|
||||
return carry;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void convert_to_upper(std::string& s)
|
||||
{
|
||||
for(std::string::iterator it = s.begin(); it != s.end() ; ++it)
|
||||
*it = toupper(*it);
|
||||
}
|
||||
|
||||
} //namespace act
|
||||
|
||||
#endif // ACT_Utility_h
|
19
openssl-act-engine/src/dllmain.cpp
Normal file
19
openssl-act-engine/src/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/src/engine_front.cpp
Normal file
262
openssl-act-engine/src/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/src/engine_sct.cpp
Normal file
402
openssl-act-engine/src/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/src/engine_sct.h
Normal file
38
openssl-act-engine/src/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/src/engine_sct_internal.h
Normal file
90
openssl-act-engine/src/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/src/engine_securetoken.cpp
Normal file
6
openssl-act-engine/src/engine_securetoken.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
// engine_securetoken.cpp : Defines the exported functions for the DLL application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
26
openssl-act-engine/src/makefile.am
Normal file
26
openssl-act-engine/src/makefile.am
Normal file
@@ -0,0 +1,26 @@
|
||||
## @id $Id$
|
||||
|
||||
## 1 2 3 4 5 6 7 8
|
||||
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
|
||||
AM_CXXFLAGS += -I ${top_srcdir}/src -I ${top_srcdir}/../actlibrary/include
|
||||
|
||||
lib_LTLIBRARIES = libengine_act.la
|
||||
noinst_PROGRAMS = test_engine
|
||||
|
||||
noinst_HEADERS = actUtility.h CardKey.h CardObject.h CertificateList.h \
|
||||
engine_sct.h engine_sct_internal.h Init_Engine.h \
|
||||
SecOpGuard.h SlotList.h stdafx.h SyncObject.h \
|
||||
SyncObjectMacOS.h SyncObjectPosix.h \
|
||||
SyncObjectSolaris.h SyncObjectWin32.h \
|
||||
SyncObjectWinCE.h targetver.h Warns.h
|
||||
|
||||
libengine_act_la_SOURCES = engine_front.cpp engine_sct.cpp \
|
||||
CardObject.cpp CardKey.cpp SlotList.cpp \
|
||||
CertificateList.cpp SecOpGuard.cpp
|
||||
libengine_act_la_LDFLAGS = -version-info @LIB_VERSION@
|
||||
|
||||
test_engine_SOURCES = test_engine.cpp
|
||||
test_engine_LDADD = -lssl
|
||||
|
||||
MAINTAINERCLEANFILES = makefile.in
|
8
openssl-act-engine/src/stdafx.cpp
Normal file
8
openssl-act-engine/src/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/src/stdafx.h
Normal file
16
openssl-act-engine/src/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/src/targetver.h
Normal file
24
openssl-act-engine/src/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
|
85
openssl-act-engine/src/test_engine.cpp
Normal file
85
openssl-act-engine/src/test_engine.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
#include "engine_sct.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/engine.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