auxiliaries are now in cryptaux.hxx; some get methods for openssl::X509
This commit is contained in:
@@ -39,7 +39,7 @@ int main(int argc, char const*const*const argv) try {
|
||||
<<"label: \""<<info.label<<'"'<<std::endl
|
||||
<<"manufacturerID: \""<<info.manufacturerID<<'"'<<std::endl
|
||||
<<"model: \""<<info.model<<'"'<<std::endl
|
||||
<<"serialNumber: \""<<cryptoki::readable(info.serialNumber)
|
||||
<<"serialNumber: \""<<crypto::readable(info.serialNumber)
|
||||
<<'"'<<std::endl
|
||||
<<"flags: \""<<info.flags<<'"'<<std::endl
|
||||
<<"maxSessionCount: \""<<info.maxSessionCount<<'"'<<std::endl
|
||||
@@ -57,7 +57,7 @@ int main(int argc, char const*const*const argv) try {
|
||||
<<'.'<<(int)info.hardwareVersion.minor<<'"'<<std::endl
|
||||
<<"firmwareVersion: \""<<(int)info.firmwareVersion.major
|
||||
<<'.'<<(int)info.firmwareVersion.minor<<'"'<<std::endl
|
||||
<<"utcTime: \""<<cryptoki::readable(info.utcTime)
|
||||
<<"utcTime: \""<<crypto::readable(info.utcTime)
|
||||
<<'"'<<std::endl;
|
||||
cryptoki::MechanismList mechs(it->mechanismlist());
|
||||
for (cryptoki::MechanismList::iterator it2(mechs.begin());
|
||||
@@ -80,7 +80,7 @@ int main(int argc, char const*const*const argv) try {
|
||||
for (cryptoki::AttributeMap::iterator it(attrs.begin());
|
||||
it!=attrs.end(); ++it) {
|
||||
std::cout<<" - attribute: "<<it->second.name()<<"=\""
|
||||
<<cryptoki::readable(it->second.value)<<'"'<<std::endl;
|
||||
<<crypto::readable(it->second.value)<<'"'<<std::endl;
|
||||
}
|
||||
}
|
||||
std::cout<<"**** Success"<<std::endl;
|
||||
|
64
src/cryptaux.hxx
Normal file
64
src/cryptaux.hxx
Normal file
@@ -0,0 +1,64 @@
|
||||
/*! @file
|
||||
|
||||
@id $Id$
|
||||
*/
|
||||
// 1 2 3 4 5 6 7 8
|
||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
|
||||
#ifndef __CRYPTAUX_HXX__
|
||||
#define __CRYPTAUX_HXX__
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
/*! @defgroup gcrypto Auxiliary Crypto-Functions */
|
||||
//@{
|
||||
|
||||
//! @see gcrypto
|
||||
namespace crypto {
|
||||
|
||||
static const std::string LETTER_CHARS
|
||||
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
|
||||
static const std::string NUMBER_CHARS
|
||||
("0123456789");
|
||||
//! Contains @c @ in addition to standard characters.
|
||||
static const std::string GRAFIC_CHARS
|
||||
("!\"#%&'()*+,-./:;<=>?[\\]^_{|}~@");
|
||||
static const std::string BLANK_CHARS
|
||||
(" ");
|
||||
static const std::string VALID_CHARS
|
||||
(LETTER_CHARS+NUMBER_CHARS+GRAFIC_CHARS+BLANK_CHARS);
|
||||
|
||||
inline std::string hex(const std::string& data,
|
||||
std::string::size_type len=20) {
|
||||
std::stringstream res;
|
||||
std::string::size_type pos(0);
|
||||
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) {
|
||||
res<<std::hex<<std::setfill('0')<<std::setw(2)
|
||||
<<(unsigned int)(unsigned char)*it;
|
||||
++pos;
|
||||
if (pos%len==0 || pos==data.size()) {
|
||||
res<<std::string(2*(len-(pos-1)%len), ' ');
|
||||
for (std::string::size_type i(pos-(pos-1)%len-1); i<pos; ++i)
|
||||
res<<(VALID_CHARS.find(data[i])==std::string::npos?'.':data[i]);
|
||||
if (pos!=data.size()) res<<std::endl;
|
||||
}
|
||||
}
|
||||
return res.str();
|
||||
}
|
||||
|
||||
inline std::string readable(const std::string& data,
|
||||
std::string::size_type len=20) {
|
||||
if (!data.size())
|
||||
return "<empty>";
|
||||
else if (data.find_first_not_of(VALID_CHARS)<data.size())
|
||||
return hex(data);
|
||||
else
|
||||
return "\""+data+"\"";
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
#endif
|
@@ -240,15 +240,24 @@ namespace cryptoki {
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Object Session::createCertificate(const std::string& derSubject,
|
||||
const std::string& desValue) {
|
||||
Object Session::create(const openssl::X509& cert) {
|
||||
AttributeList attrs;
|
||||
/*
|
||||
attrs.push_back(Attribute(CKA_CLASS)
|
||||
.from<CK_OBJECT_CLASS>(CKO_CERTIFICATE));
|
||||
attrs.push_back(Attribute(CKA_CERTIFICATE_TYPE)
|
||||
.from<CK_CERTIFICATE_TYPE>(CKC_X_509));
|
||||
attrs.push_back(Attribute(CKA_SUBJECT, derSubject));
|
||||
attrs.push_back(Attribute(CKA_VALUE, desValue));
|
||||
*/
|
||||
return create(attrs);
|
||||
}
|
||||
Object Session::create(const openssl::PrivateKey& key) {
|
||||
AttributeList attrs;
|
||||
return create(attrs);
|
||||
}
|
||||
Object Session::create(const openssl::PKCS12& p12) {
|
||||
AttributeList attrs;
|
||||
return create(attrs);
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,7 @@
|
||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
|
||||
// interface
|
||||
#include <openssl.hxx>
|
||||
#include <pkcs11/apiclient.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -20,6 +21,7 @@
|
||||
#include <cstring> // memset
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <cryptaux.hxx>
|
||||
|
||||
#include <iostream> // debug
|
||||
|
||||
@@ -45,46 +47,6 @@ namespace cryptoki {
|
||||
|
||||
//! @addtogroup cryptokitypes
|
||||
//@{
|
||||
|
||||
static const std::string LETTER_CHARS
|
||||
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
|
||||
static const std::string NUMBER_CHARS
|
||||
("0123456789");
|
||||
//! Contains @c @ in addition to standard characters.
|
||||
static const std::string GRAFIC_CHARS
|
||||
("!\"#%&'()*+,-./:;<=>?[\\]^_{|}~@");
|
||||
static const std::string BLANK_CHARS
|
||||
(" ");
|
||||
static const std::string VALID_CHARS
|
||||
(LETTER_CHARS+NUMBER_CHARS+GRAFIC_CHARS+BLANK_CHARS);
|
||||
|
||||
inline std::string hex(const std::string& data,
|
||||
std::string::size_type len=20) {
|
||||
std::stringstream res;
|
||||
std::string::size_type pos(0);
|
||||
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) {
|
||||
res<<std::hex<<std::setfill('0')<<std::setw(2)
|
||||
<<(unsigned int)(unsigned char)*it;
|
||||
++pos;
|
||||
if (pos%len==0 || pos==data.size()) {
|
||||
res<<std::string(2*(len-(pos-1)%len), ' ');
|
||||
for (std::string::size_type i(pos-(pos-1)%len-1); i<pos; ++i)
|
||||
res<<(VALID_CHARS.find(data[i])==std::string::npos?'.':data[i]);
|
||||
if (pos!=data.size()) res<<std::endl;
|
||||
}
|
||||
}
|
||||
return res.str();
|
||||
}
|
||||
|
||||
inline std::string readable(const std::string& data,
|
||||
std::string::size_type len=20) {
|
||||
if (!data.size())
|
||||
return "<empty>";
|
||||
else if (data.find_first_not_of(VALID_CHARS)<data.size())
|
||||
return hex(data);
|
||||
else
|
||||
return "\""+data+"\"";
|
||||
}
|
||||
|
||||
inline std::string string(CK_ULONG num) {
|
||||
switch (num) {
|
||||
@@ -256,7 +218,7 @@ namespace cryptoki {
|
||||
case CKO_VENDOR_DEFINED: return "VENDOR_DEFINED";
|
||||
default: "unknown";
|
||||
}
|
||||
default: return readable(value);
|
||||
default: return crypto::readable(value);
|
||||
}
|
||||
}
|
||||
template<typename TYPE> Attribute from(const TYPE& v) {
|
||||
@@ -904,8 +866,11 @@ namespace cryptoki {
|
||||
ObjectList find(const AttributeList& attrs=AttributeList());
|
||||
|
||||
//! Create a new Certificate Object.
|
||||
Object createCertificate(const std::string& derSubject,
|
||||
const std::string& desValue);
|
||||
Object create(const openssl::X509& cert);
|
||||
//! Create a new PrivateKey Object.
|
||||
Object create(const openssl::PrivateKey& key);
|
||||
//! Create a new Certificate and optional PrivateKey Object.
|
||||
Object create(const openssl::PKCS12& p12);
|
||||
|
||||
//@}
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
## 1 2 3 4 5 6 7 8
|
||||
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
|
||||
include_HEADERS = pcsc.hxx cryptoki.hxx openssl.hxx
|
||||
include_HEADERS = pcsc.hxx cryptoki.hxx openssl.hxx cryptaux.hxx
|
||||
pkcs11_HEADERS = pkcs11/pkcs11.h pkcs11/pkcs11types.h pkcs11/apiclient.h
|
||||
pkcs11dir = ${includedir}/pkcs11
|
||||
|
||||
|
@@ -10,10 +10,12 @@
|
||||
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "openssl/bio.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include <openssl/err.h>
|
||||
#include <vector>
|
||||
|
||||
#include <cryptaux.hxx>
|
||||
#include <cstdio>
|
||||
|
||||
/*! @defgroup gopenssl C++ Wrapper around OpenSSL API */
|
||||
@@ -85,6 +87,13 @@ namespace openssl {
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class x509_decoding_failed: public x509_error {
|
||||
public:
|
||||
x509_decoding_failed(const std::string& der) throw():
|
||||
x509_error("certificate decoding failed:\n"+crypto::readable(der)) {
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class undefined_certificate: public x509_error {
|
||||
public:
|
||||
undefined_certificate() throw():
|
||||
@@ -199,6 +208,13 @@ namespace openssl {
|
||||
X509(): _x509(X509_new()) {
|
||||
if (!_x509) throw allocation_failed();
|
||||
}
|
||||
//! Initialize from DER encoded cerificate.
|
||||
X509(const std::string& der): _x509(0) {
|
||||
const unsigned char* c((const unsigned char*)der.begin().operator->());
|
||||
if (!(_x509=d2i_X509(0, &c, der.size())) ||
|
||||
(const char*)c!=der.begin().operator->()+der.size())
|
||||
throw x509_decoding_failed(der);
|
||||
}
|
||||
X509(const X509& o): _x509(0) {
|
||||
unsigned char* d(0);
|
||||
int len(i2d_X509(o._x509, &d));
|
||||
@@ -222,18 +238,58 @@ namespace openssl {
|
||||
int len(i2d_X509(o._x509, &d));
|
||||
if (!len) throw x509_copy_failed();
|
||||
const unsigned char* d2(d);
|
||||
free(d);
|
||||
_x509 = d2i_X509(0, &d2, len);
|
||||
OPENSSL_free(d);
|
||||
if (!_x509) throw x509_copy_failed();
|
||||
}
|
||||
//! Get DER encoded subject.
|
||||
std::string subjectDER() const {
|
||||
char* c(0);
|
||||
unsigned char* c(0);
|
||||
int len(i2d_X509_NAME(X509_get_subject_name(_x509), &c));
|
||||
std::String res(c, len);
|
||||
std::string res((char*)c, len);
|
||||
OPENSSL_free(c);
|
||||
return res;
|
||||
}
|
||||
//! Get DER encoded issuer.
|
||||
std::string issuerDER() const {
|
||||
unsigned char* c(0);
|
||||
int len(i2d_X509_NAME(X509_get_issuer_name(_x509), &c));
|
||||
std::string res((char*)c, len);
|
||||
OPENSSL_free(c);
|
||||
return res;
|
||||
}
|
||||
//! Get DER encoded value.
|
||||
std::string valueDER() const {
|
||||
unsigned char* c(0);
|
||||
int len(i2d_X509(_x509, &c));
|
||||
std::string res((char*)c, len);
|
||||
OPENSSL_free(c);
|
||||
return res;
|
||||
}
|
||||
//! Get serial number.
|
||||
std::string serial() const {
|
||||
/* @bug http://albistechnologies.com reports: «could be a
|
||||
failure in openSSL: len too short by 1 if serial number
|
||||
starts with 00 ASN1_INTEGER* ser =
|
||||
X509_get_serialNumber(_x509);» */
|
||||
ASN1_INTEGER* ser(X509_get_serialNumber(_x509));
|
||||
//! @todo requires memory free?
|
||||
/*! @todo ser->type?!? http://albistechnologies.com prepends
|
||||
tag and length in the first two char-fields. */
|
||||
return std::string((char*)ser->data, ser->length);
|
||||
}
|
||||
//! Get id.
|
||||
std::string id() const {
|
||||
unsigned char c[SHA_DIGEST_LENGTH];
|
||||
SHA1(_x509->cert_info->key->public_key->data,
|
||||
_x509->cert_info->key->public_key->length,
|
||||
c);
|
||||
return std::string((char*)c, SHA_DIGEST_LENGTH);
|
||||
}
|
||||
//! Get label.
|
||||
std::string label() const {
|
||||
return std::string();
|
||||
}
|
||||
private:
|
||||
::X509* _x509;
|
||||
};
|
||||
|
20
src/pcsc.hxx
20
src/pcsc.hxx
@@ -10,6 +10,8 @@
|
||||
#ifndef PCSC_HXX
|
||||
#define PCSC_HXX
|
||||
|
||||
#include <cryptaux.hxx>
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -68,25 +70,11 @@
|
||||
best fits the common needs. */
|
||||
//@{
|
||||
/*! @defgroup pcsclib PCSC C++ Library */
|
||||
/*! @defgroup pcsctypes PCSC Types and Auxiliary */
|
||||
/*! @defgroup pcscexceptions PCSC Exceptions */
|
||||
|
||||
//! @see gpcsc
|
||||
namespace pcsc {
|
||||
|
||||
//! @addtogroup pcsctypes
|
||||
//@{
|
||||
|
||||
std::string hex(const std::string& data) {
|
||||
std::stringstream res;
|
||||
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it)
|
||||
res<<std::hex<<std::setfill('0')<<std::setw(2)
|
||||
<<(unsigned int)(unsigned char)*it;
|
||||
return res.str();
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//============================================================================
|
||||
//! @addtogroup pcsclib
|
||||
//@{
|
||||
@@ -236,7 +224,7 @@ namespace pcsc {
|
||||
check(SCardTransmit(_id, &rPci,
|
||||
(unsigned char*)in.c_str(), in.size(),
|
||||
0, buff, &len),
|
||||
"smartcard transmit message "+hex(in));
|
||||
"smartcard transmit message "+crypto::hex(in));
|
||||
return std::string((char*)buff, len);
|
||||
}
|
||||
|
||||
@@ -312,7 +300,7 @@ namespace pcsc {
|
||||
check(SCardConnect(_connection._id, strconv(name).c_str(),
|
||||
mode, protocol,
|
||||
&_id, &_protocol),
|
||||
"connect smartcard \""+name+"\" ("+hex(name)+")");
|
||||
"connect smartcard \""+name+"\" ("+crypto::hex(name)+")");
|
||||
}
|
||||
|
||||
//! forbidden
|
||||
|
Reference in New Issue
Block a user