You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.0 KiB
179 lines
4.0 KiB
|
|
#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++; |
|
} |
|
} |
|
|
|
|