|
|
|
@ -9,6 +9,7 @@ |
|
|
|
|
#define __OPENSSL_HXX__ |
|
|
|
|
|
|
|
|
|
#include <openssl/pkcs12.h> |
|
|
|
|
#include <openssl/pkcs7.h> |
|
|
|
|
#include <openssl/x509.h> |
|
|
|
|
#include "openssl/bio.h" |
|
|
|
|
#include "openssl/des.h" |
|
|
|
@ -72,6 +73,13 @@ namespace openssl { |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
class pkcs7_error: public openssl_error { |
|
|
|
|
public: |
|
|
|
|
pkcs7_error(const std::string& reason) throw(): |
|
|
|
|
openssl_error("pkcs7: "+reason) { |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
class x509_error: public openssl_error { |
|
|
|
|
public: |
|
|
|
|
x509_error(const std::string& reason) throw(): |
|
|
|
@ -180,6 +188,33 @@ namespace openssl { |
|
|
|
|
pkcs12_no_x509() throw(): pkcs12_error("no x509 certificate") {} |
|
|
|
|
}; |
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
class pkcs7_reading_failed: public pkcs7_error { |
|
|
|
|
public: |
|
|
|
|
pkcs7_reading_failed(const std::string& file) throw(): |
|
|
|
|
pkcs7_error("reading DER encoded p7 file failed: "+file) { |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
class pkcs7_parsing_failed: public pkcs7_error { |
|
|
|
|
public: |
|
|
|
|
pkcs7_parsing_failed() throw(): |
|
|
|
|
pkcs7_error("parsing DER encoded p7 failed") { |
|
|
|
|
} |
|
|
|
|
pkcs7_parsing_failed(const std::string& file) throw(): |
|
|
|
|
pkcs7_error("parsing DER encoded p7 file failed: "+file) { |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
class pkcs7_unsupported_format: public pkcs7_error { |
|
|
|
|
public: |
|
|
|
|
pkcs7_unsupported_format() throw(): pkcs7_error("format not supported") {} |
|
|
|
|
}; |
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
class pkcs7_no_x509: public pkcs7_error { |
|
|
|
|
public: |
|
|
|
|
pkcs7_no_x509() throw(): pkcs7_error("no x509 certificate") {} |
|
|
|
|
}; |
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
class cannot_open_file: public exception { |
|
|
|
|
public: |
|
|
|
|
cannot_open_file(const std::string& file) throw(): |
|
|
|
@ -774,6 +809,67 @@ namespace openssl { |
|
|
|
|
X509List _ca; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
class PKCS7 { |
|
|
|
|
|
|
|
|
|
//...............................................................typedefs
|
|
|
|
|
public: |
|
|
|
|
typedef std::vector<X509*> X509List; |
|
|
|
|
|
|
|
|
|
//................................................................methods
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
//! Read from a PKCS#7 (.p7) file.
|
|
|
|
|
PKCS7(std::string filename) { |
|
|
|
|
FILE* file(fopen(filename.c_str(), "rb")); |
|
|
|
|
if (!file) throw cannot_open_file(filename); |
|
|
|
|
::PKCS7 *p7(d2i_PKCS7_fp(file, 0)); |
|
|
|
|
fclose(file); |
|
|
|
|
if (!p7) throw pkcs7_reading_failed(filename); |
|
|
|
|
try { |
|
|
|
|
if (PKCS7_type_is_signed(p7)) while (p7->d.sign->cert->num>0) |
|
|
|
|
_certs.push_back(new X509((::X509*)sk_pop(p7->d.sign->cert))); |
|
|
|
|
else //! @todo to be implemented: check for other types
|
|
|
|
|
throw pkcs7_unsupported_format(); |
|
|
|
|
PKCS7_free(p7); |
|
|
|
|
} catch (...) { |
|
|
|
|
PKCS7_free(p7); |
|
|
|
|
throw; |
|
|
|
|
} |
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
//! Read PKCS#7 from memory.
|
|
|
|
|
PKCS7(const std::string& memory) { |
|
|
|
|
BIO* mem(BIO_new_mem_buf((void*)memory.data(), memory.size())); |
|
|
|
|
::PKCS7 *p7(d2i_PKCS7_bio(mem, 0)); |
|
|
|
|
BIO_free(mem); |
|
|
|
|
if (!p7) throw pkcs7_parsing_failed(); |
|
|
|
|
try { |
|
|
|
|
if (PKCS7_type_is_signed(p7)) while (p7->d.sign->cert->num>0) |
|
|
|
|
_certs.push_back(new X509((::X509*)sk_pop(p7->d.sign->cert))); |
|
|
|
|
else //! @todo to be implemented: check for other types
|
|
|
|
|
throw pkcs7_unsupported_format(); |
|
|
|
|
PKCS7_free(p7); |
|
|
|
|
} catch (...) { |
|
|
|
|
PKCS7_free(p7); |
|
|
|
|
throw; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
~PKCS7() { |
|
|
|
|
for (X509List::iterator it(_certs.begin()); it!=_certs.end(); ++it) |
|
|
|
|
delete *it; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const X509List& certs() const { |
|
|
|
|
return _certs; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
X509List _certs; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
class BIO { |
|
|
|
|
|
|
|
|
|