diff --git a/src/openssl.hxx b/src/openssl.hxx index 0406e31..f151fc1 100644 --- a/src/openssl.hxx +++ b/src/openssl.hxx @@ -9,6 +9,7 @@ #define __OPENSSL_HXX__ #include +#include #include #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 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 {