From 98967c39595e4aa12bfbcb962a6f23ee9f260931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Thu, 21 Apr 2011 06:30:51 +0000 Subject: [PATCH] done in first release; closes #11 --- src/cryptoki.hxx | 285 +++++++++++++++++++++++------------------ src/openssl-engine.hxx | 28 ++-- src/openssl.hxx | 87 +++++++++---- 3 files changed, 239 insertions(+), 161 deletions(-) diff --git a/src/cryptoki.hxx b/src/cryptoki.hxx index bbc58e7..6b7f67b 100644 --- a/src/cryptoki.hxx +++ b/src/cryptoki.hxx @@ -1229,118 +1229,6 @@ namespace cryptoki { CRYPTOKI_FN_LOG("C_SetPIN")); } @endcode */ - - std::string sign(std::string in) { - CRYPTOKI_LOG("log"); - std::string res; - res.resize(in.size()); - CK_ULONG size(res.size()); //! @todo check if size is ok - //! calls @c C_Sign - check(_slot._init->_fn->C_Sign - (_session, - (unsigned char*)&in[0], in.size(), - (unsigned char*)&res[0], &size), - CRYPTOKI_FN_LOG("C_Sign")); - res.resize(size); - return res; - } - - std::string signencryptupdate(std::string in) { - CRYPTOKI_LOG("log"); - std::string res; - res.resize(in.size()); - CK_ULONG size(res.size()); //! @todo check if size is ok - //! calls @c C_SignEncryptUpdate - check(_slot._init->_fn->C_SignEncryptUpdate - (_session, - (unsigned char*)&in[0], in.size(), - (unsigned char*)&res[0], &size), - CRYPTOKI_FN_LOG("C_SignEncryptUpdate")); - res.resize(size); - return res; - } - - /*! @todo Not implemented: - @code - bool signfinal() { - CRYPTOKI_LOG("log"); - //! calls @c C_SignFinal - return check(_slot._init->_fn->C_SignFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR), - CRYPTOKI_FN_LOG("C_SignFinal")); - } - @endcode */ - - std::string signrecover(std::string in) { - CRYPTOKI_LOG("log"); - std::string res; - res.resize(in.size()); - CK_ULONG size(res.size()); //! @todo check if size is ok - //! calls @c C_SignRecover - check(_slot._init->_fn->C_SignRecover - (_session, - (unsigned char*)&in[0], in.size(), - (unsigned char*)&res[0], &size), - CRYPTOKI_FN_LOG("C_SignRecover")); - res.resize(size); - return res; - } - - /*! @todo Not implemented: - @code - bool signupdate() { - CRYPTOKI_LOG("log"); - //! calls @c C_SignUpdate - return check(_slot._init->_fn->C_SignUpdate(_session, CK_BYTE_PTR, CK_ULONG), - CRYPTOKI_FN_LOG("C_SignUpdate")); - } - @endcode */ - - /*! @todo Not implemented: - @code - bool verify() { - CRYPTOKI_LOG("log"); - //! calls @c C_Verify - return check(_slot._init->_fn->C_Verify(_session, CK_BYTE_PTR, CK_ULONG, - CK_BYTE_PTR, CK_ULONG), - CRYPTOKI_FN_LOG("C_Verify")); - } - @endcode */ - - /*! @todo Not implemented: - @code - bool verifyfinal() { - CRYPTOKI_LOG("log"); - //! calls @c C_VerifyFinal - return check(_slot._init->_fn->C_VerifyFinal(_session, CK_BYTE_PTR, CK_ULONG), - CRYPTOKI_FN_LOG("C_VerifyFinal")); - } - @endcode */ - - std::string verifyrecover(std::string in) { - CRYPTOKI_LOG("log"); - std::string res; - res.resize(in.size()); - CK_ULONG size(res.size()); //! @todo check if size is ok - //! calls @c C_VerifyRecover - check(_slot._init->_fn->C_VerifyRecover - (_session, - (unsigned char*)&in[0], in.size(), - (unsigned char*)&res[0], &size), - CRYPTOKI_FN_LOG("C_VerifyRecover")); - res.resize(size); - return res; - } - - /*! @todo Not implemented: - @code - bool verifyupdate() { - CRYPTOKI_LOG("log"); - //! calls @c C_VerifyUpdate - return check(_slot._init->_fn->C_VerifyUpdate(_session, CK_BYTE_PTR, CK_ULONG), - CRYPTOKI_FN_LOG("C_VerifyUpdate")); - } - @endcode */ - //@} }; class Object { @@ -1399,6 +1287,27 @@ namespace cryptoki { //! @todo don't call decryptfinal()? } + std::string sign(const std::string& data, CK_MECHANISM_TYPE type, + const std::string& param=std::string()) { + CRYPTOKI_LOG("log"); + CRYPTOKI_LOG("signinit"); + signinit(type, param); + CRYPTOKI_LOG("sign"); + return sign(data); + //! @todo don't call signfinal()? + } + + bool verify(const std::string& data, const std::string& signature, + CK_MECHANISM_TYPE type, + const std::string& param=std::string()) { + CRYPTOKI_LOG("log"); + CRYPTOKI_LOG("verifyinit"); + verifyinit(type, param); + CRYPTOKI_LOG("verify"); + return verify(data, signature); + //! @todo don't call verifyfinal()? + } + //@} /*! @name C Like Error Handling @@ -1530,6 +1439,124 @@ namespace cryptoki { return res; } + + std::string sign(std::string in) { + CRYPTOKI_LOG("log"); + std::string res; + CK_ULONG size(0); + check(_session->_slot._init->_fn->C_Sign + (_session->_session, + (unsigned char*)&in[0], in.size(),0, &size), + CRYPTOKI_FN_LOG("C_Sign")); + CRYPTOKI_LOG("maximum size is "<_slot._init->_fn->C_Sign + (_session->_session, + (unsigned char*)&in[0], in.size(), + (unsigned char*)&res[0], &size), + CRYPTOKI_FN_LOG("C_Sign")); + CRYPTOKI_LOG("exact size is "<_slot._init->_fn->C_SignEncryptUpdate + (_session->_session, + (unsigned char*)&in[0], in.size(), + (unsigned char*)&res[0], &size), + CRYPTOKI_FN_LOG("C_SignEncryptUpdate")); + res.resize(size); + return res; + } + + /*! @todo Not implemented: + @code + bool signfinal() { + CRYPTOKI_LOG("log"); + //! calls @c C_SignFinal + return check(_slot._init->_fn->C_SignFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_SignFinal")); + } + @endcode */ + + std::string signrecover(std::string in) { + CRYPTOKI_LOG("log"); + std::string res; + res.resize(in.size()); + CK_ULONG size(res.size()); //! @todo check if size is ok + //! calls @c C_SignRecover + check(_session->_slot._init->_fn->C_SignRecover + (_session->_session, + (unsigned char*)&in[0], in.size(), + (unsigned char*)&res[0], &size), + CRYPTOKI_FN_LOG("C_SignRecover")); + res.resize(size); + return res; + } + + /*! @todo Not implemented: + @code + bool signupdate() { + CRYPTOKI_LOG("log"); + //! calls @c C_SignUpdate + return check(_session->_slot._init->_fn->C_SignUpdate(_session->_session, CK_BYTE_PTR, CK_ULONG), + CRYPTOKI_FN_LOG("C_SignUpdate")); + } + @endcode */ + + bool verify(std::string data, std::string signature) { + CRYPTOKI_LOG("log"); + //! calls @c C_Verify + return check(_session->_slot._init->_fn->C_Verify + (_session->_session, + (unsigned char*)&data[0], data.size(), + (unsigned char*)&signature[0], signature.size()), + CRYPTOKI_FN_LOG("C_Verify")); + } + + /*! @todo Not implemented: + @code + bool verifyfinal() { + CRYPTOKI_LOG("log"); + //! calls @c C_VerifyFinal + return check(_session->_slot._init->_fn->C_VerifyFinal(_session->_session, CK_BYTE_PTR, CK_ULONG), + CRYPTOKI_FN_LOG("C_VerifyFinal")); + } + @endcode */ + + std::string verifyrecover(std::string in) { + CRYPTOKI_LOG("log"); + std::string res; + res.resize(in.size()); + CK_ULONG size(res.size()); //! @todo check if size is ok + //! calls @c C_VerifyRecover + check(_session->_slot._init->_fn->C_VerifyRecover + (_session->_session, + (unsigned char*)&in[0], in.size(), + (unsigned char*)&res[0], &size), + CRYPTOKI_FN_LOG("C_VerifyRecover")); + res.resize(size); + return res; + } + + /*! @todo Not implemented: + @code + bool verifyupdate() { + CRYPTOKI_LOG("log"); + //! calls @c C_VerifyUpdate + return check(_session->_slot._init->_fn->C_VerifyUpdate(_session->_session, CK_BYTE_PTR, CK_ULONG), + CRYPTOKI_FN_LOG("C_VerifyUpdate")); + } + @endcode */ + //@} + /*! @todo Not implemented: @code bool derivekey() { @@ -1881,16 +1908,18 @@ namespace cryptoki { } @endcode */ - /*! @todo Not implemented: - @code - bool signinit() { - CRYPTOKI_LOG("log"); + bool signinit(CK_MECHANISM_TYPE type, std::string param) { + CRYPTOKI_LOG("log"); + CK_MECHANISM mech = { + type, param.size()?¶m[0]:0, param.size() + }; + CRYPTOKI_LOG("signinit: type="<_slot._init->_fn->C_SignInit(_session->_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE), + return check(_session->_slot._init->_fn->C_SignInit + (_session->_session, &mech, _object), CRYPTOKI_FN_LOG("C_SignInit")); } - @endcode */ - /*! @todo Not implemented: @code @@ -1914,16 +1943,18 @@ namespace cryptoki { } @endcode */ - /*! @todo Not implemented: - @code - bool verifyinit() { - CRYPTOKI_LOG("log"); - //! calls @c C_VerifyInit - return check(_session->_slot._init->_fn->C_VerifyInit(_session->_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE), + bool verifyinit(CK_MECHANISM_TYPE type, std::string param) { + CRYPTOKI_LOG("log"); + CK_MECHANISM mech = { + type, param.size()?¶m[0]:0, param.size() + }; + CRYPTOKI_LOG("verifyinit: type="<_slot._init->_fn->C_VerifyInit + (_session->_session, &mech, _object), CRYPTOKI_FN_LOG("C_VerifyInit")); } - @endcode */ - /*! @todo Not implemented: @code diff --git a/src/openssl-engine.hxx b/src/openssl-engine.hxx index 3431fb4..3100f77 100644 --- a/src/openssl-engine.hxx +++ b/src/openssl-engine.hxx @@ -114,9 +114,9 @@ namespace openssl { OPENSSL_LOG("log"); return 1; } - virtual int rsaSign() { + virtual std::string rsaSign(const std::string&, unsigned int) { OPENSSL_LOG("log"); - return 1; + throw std::runtime_error("rsaSign not implemented"); } virtual int rsaVerify() { OPENSSL_LOG("log"); @@ -127,7 +127,7 @@ namespace openssl { return 1; } - private: + protected: friend class EngineMapper; ENGINE* _e; @@ -208,13 +208,25 @@ namespace openssl { OPENSSL_LOG("log"); return _map[rsa->engine]->rsaDecrypt(); } - static int rsaSign(int flen, const unsigned char *from, - unsigned int, + static int rsaSign(int type, const unsigned char *from, + unsigned int flen, unsigned char *to, - unsigned int*, + unsigned int*tlen, const RSA *rsa) { OPENSSL_LOG("log"); - return _map[rsa->engine]->rsaSign(); + try { + std::string res(_map[rsa->engine] + ->rsaSign(std::string((const char*)from, flen), + type)); + OPENSSL_LOG("to="<<(void*)to<<"; len="<<*tlen); + OPENSSL_LOG("siglen="<engine]->rsaFinish(); } - private: + protected: static RSA_METHOD* rsa() { OPENSSL_LOG("log"); diff --git a/src/openssl.hxx b/src/openssl.hxx index af45769..9728786 100644 --- a/src/openssl.hxx +++ b/src/openssl.hxx @@ -520,6 +520,40 @@ namespace openssl { } }; + //! Bignumber operations + class BigNum { + public: + BigNum(): + _bn(BN_new()) { + } + BigNum(const std::string& num): + _bn(BN_bin2bn((const unsigned char*)num.data(), num.size(), 0)) { + } + ~BigNum() { + BN_free(_bn); + } + int size() const { + return size(_bn); + } + static int size(BIGNUM* n) { + return BN_num_bytes(n); + } + std::string string() const { + return string(_bn); + } + static std::string string(BIGNUM* a) { + OPENSSL_LOG("log"); + std::string res(BN_num_bytes(a), '0'); + BN_bn2bin(a, (unsigned char*)res.begin().operator->()); + return res; + } + private: + BigNum(const BigNum& o); + BigNum& operator=(const BigNum& o); + private: + BIGNUM* _bn; + }; + class CBlock8 { public: CBlock8() { @@ -746,12 +780,13 @@ namespace openssl { } X509(const X509& o): _x509(0) { OPENSSL_LOG("log"); - unsigned char* d(0); - int len(i2d_X509(o._x509, &d)); - if (!len) throw x509_copy_failed(); - V0_CONST unsigned char* d2(d); - _x509 = d2i_X509(0, &d2, len); - OPENSSL_free(d); + _x509 = X509_dup(o._x509); + // unsigned char* d(0); + // int len(i2d_X509(o._x509, &d)); + // if (!len) throw x509_copy_failed(); + // V0_CONST unsigned char* d2(d); + // _x509 = d2i_X509(0, &d2, len); + // OPENSSL_free(d); if (!_x509) throw x509_copy_failed(); } //! Take over OpenSSL allocated certificate. @@ -767,14 +802,20 @@ namespace openssl { OPENSSL_LOG("log"); X509_free(_x509); _x509 = 0; - unsigned char* d(0); - int len(i2d_X509(o._x509, &d)); - if (!len) throw x509_copy_failed(); - V0_CONST unsigned char* d2(d); - _x509 = d2i_X509(0, &d2, len); - OPENSSL_free(d); + _x509 = X509_dup(o._x509); + // unsigned char* d(0); + // int len(i2d_X509(o._x509, &d)); + // if (!len) throw x509_copy_failed(); + // V0_CONST unsigned char* d2(d); + // _x509 = d2i_X509(0, &d2, len); + // OPENSSL_free(d); if (!_x509) throw x509_copy_failed(); } + //! Get a copy of the OpenSSL low level certificate + /*! @note you are responsible to free the certificate */ + ::X509* lowLevelCopy() const { + return X509_dup(_x509); + } //! Get DER encoded subject. std::string subjectDER() const { OPENSSL_LOG("log"); @@ -957,35 +998,35 @@ namespace openssl { } std::string modulus() const { OPENSSL_LOG("log"); - return string(rsa()->n); + return BigNum::string(rsa()->n); } std::string publicExponent() const { OPENSSL_LOG("log"); - return string(rsa()->e); + return BigNum::string(rsa()->e); } std::string privateExponent() const { OPENSSL_LOG("log"); - return string(rsa()->d); + return BigNum::string(rsa()->d); } std::string prime1() const { OPENSSL_LOG("log"); - return string(rsa()->p); + return BigNum::string(rsa()->p); } std::string prime2() const { OPENSSL_LOG("log"); - return string(rsa()->q); + return BigNum::string(rsa()->q); } std::string exponent1() const { OPENSSL_LOG("log"); - return string(rsa()->dmp1); + return BigNum::string(rsa()->dmp1); } std::string exponent2() const { OPENSSL_LOG("log"); - return string(rsa()->dmq1); + return BigNum::string(rsa()->dmq1); } std::string coefficient() const { OPENSSL_LOG("log"); - return string(rsa()->iqmp); + return BigNum::string(rsa()->iqmp); } private: void copy(const PrivateKey& o) { @@ -997,12 +1038,6 @@ namespace openssl { dh(o); /*ec(o);*/ } - std::string string(BIGNUM* a) const { - OPENSSL_LOG("log"); - std::string res(BN_num_bytes(a), '0'); - BN_bn2bin(a, (unsigned char*)res.begin().operator->()); - return res; - } void rsa(const PrivateKey& o) { OPENSSL_LOG("log"); //! @todo throw exception if 0?