📄 qca-ossl.cpp
字号:
dh->p = bi2bn(domain.p()); dh->g = bi2bn(domain.g()); dh->pub_key = bi2bn(y); dh->priv_key = bi2bn(x); if(!dh->p || !dh->g || !dh->pub_key || !dh->priv_key) { DH_free(dh); return; } evp.pkey = EVP_PKEY_new(); EVP_PKEY_assign_DH(evp.pkey, dh); sec = true; } virtual void createPublic(const DLGroup &domain, const BigInteger &y) { evp.reset(); DH *dh = DH_new(); dh->p = bi2bn(domain.p()); dh->g = bi2bn(domain.g()); dh->pub_key = bi2bn(y); if(!dh->p || !dh->g || !dh->pub_key) { DH_free(dh); return; } evp.pkey = EVP_PKEY_new(); EVP_PKEY_assign_DH(evp.pkey, dh); sec = false; } virtual DLGroup domain() const { return DLGroup(bn2bi(evp.pkey->pkey.dh->p), bn2bi(evp.pkey->pkey.dh->g)); } virtual BigInteger y() const { return bn2bi(evp.pkey->pkey.dh->pub_key); } virtual BigInteger x() const { return bn2bi(evp.pkey->pkey.dh->priv_key); }private slots: void km_finished() { DH *dh = keymaker->takeResult(); if(wasBlocking) delete keymaker; else keymaker->deleteLater(); keymaker = 0; if(dh) { evp.pkey = EVP_PKEY_new(); EVP_PKEY_assign_DH(evp.pkey, dh); sec = true; } if(!wasBlocking) emit finished(); }};//----------------------------------------------------------------------------// QCA-based RSA_METHOD//----------------------------------------------------------------------------// only supports EMSA3_Raw for nowclass QCA_RSA_METHOD{public: RSAPrivateKey key; QCA_RSA_METHOD(RSAPrivateKey _key, RSA *rsa) { key = _key; RSA_set_method(rsa, rsa_method()); rsa->flags |= RSA_FLAG_SIGN_VER; RSA_set_app_data(rsa, this); rsa->n = bi2bn(_key.n()); rsa->e = bi2bn(_key.e()); } RSA_METHOD *rsa_method() { static RSA_METHOD *ops = 0; if(!ops) { ops = new RSA_METHOD(*RSA_get_default_method()); ops->rsa_priv_enc = 0;//pkcs11_rsa_encrypt; ops->rsa_priv_dec = 0;//pkcs11_rsa_decrypt; ops->rsa_sign = rsa_sign; ops->rsa_verify = 0;//pkcs11_rsa_verify; ops->finish = rsa_finish; } return ops; } static int rsa_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, const RSA *rsa) { QCA_RSA_METHOD *self = (QCA_RSA_METHOD *)RSA_get_app_data(rsa); // TODO: this is disgusting unsigned char *p, *tmps = NULL; const unsigned char *s = NULL; int i,j; j = 0; if(type == NID_md5_sha1) { } else { // make X509 packet X509_SIG sig; ASN1_TYPE parameter; X509_ALGOR algor; ASN1_OCTET_STRING digest; int rsa_size = RSA_size(rsa); //int rsa_size = 128; //CK_ULONG sigsize = rsa_size; sig.algor= &algor; sig.algor->algorithm=OBJ_nid2obj(type); if (sig.algor->algorithm == NULL) { //RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); return 0; } if (sig.algor->algorithm->length == 0) { //RSAerr(RSA_F_RSA_SIGN,RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); return 0; } parameter.type=V_ASN1_NULL; parameter.value.ptr=NULL; sig.algor->parameter= ¶meter; sig.digest= &digest; sig.digest->data=(unsigned char *)m; /* TMP UGLY CAST */ sig.digest->length=m_len; i=i2d_X509_SIG(&sig,NULL); j=rsa_size; if (i > (j-RSA_PKCS1_PADDING_SIZE)) { //RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return 0; } tmps=(unsigned char *)OPENSSL_malloc((unsigned int)j+1); if (tmps == NULL) { //RSAerr(RSA_F_RSA_SIGN,ERR_R_MALLOC_FAILURE); return 0; } p=tmps; i2d_X509_SIG(&sig,&p); s=tmps; m = s; m_len = i; } SecureArray input; input.resize(m_len); memcpy(input.data(), m, input.size()); SecureArray result = self->key.signMessage(input, EMSA3_Raw); if(tmps) { OPENSSL_cleanse(tmps,(unsigned int)j+1); OPENSSL_free(tmps); } // TODO: even though we return error here, PKCS7_sign will // not return error. what gives? if(result.isEmpty()) return 0; memcpy(sigret, result.data(), result.size()); *siglen = result.size(); return 1; } static int rsa_finish(RSA *rsa) { QCA_RSA_METHOD *self = (QCA_RSA_METHOD *)RSA_get_app_data(rsa); delete self; return 1; }};static RSA *createFromExisting(const RSAPrivateKey &key){ RSA *r = RSA_new(); new QCA_RSA_METHOD(key, r); // will delete itself on RSA_free return r;}//----------------------------------------------------------------------------// MyPKeyContext//----------------------------------------------------------------------------class MyPKeyContext : public PKeyContext{public: PKeyBase *k; MyPKeyContext(Provider *p) : PKeyContext(p) { k = 0; } ~MyPKeyContext() { delete k; } virtual Provider::Context *clone() const { MyPKeyContext *c = new MyPKeyContext(*this); c->k = (PKeyBase *)k->clone(); return c; } virtual QList<PKey::Type> supportedTypes() const { QList<PKey::Type> list; list += PKey::RSA; list += PKey::DSA; list += PKey::DH; return list; } virtual QList<PKey::Type> supportedIOTypes() const { QList<PKey::Type> list; list += PKey::RSA; list += PKey::DSA; return list; } virtual QList<PBEAlgorithm> supportedPBEAlgorithms() const { QList<PBEAlgorithm> list; list += PBES2_DES_SHA1; list += PBES2_TripleDES_SHA1; return list; } virtual PKeyBase *key() { return k; } virtual const PKeyBase *key() const { return k; } virtual void setKey(PKeyBase *key) { k = key; } virtual bool importKey(const PKeyBase *key) { Q_UNUSED(key); return false; } EVP_PKEY *get_pkey() const { PKey::Type t = k->type(); if(t == PKey::RSA) return static_cast<RSAKey *>(k)->evp.pkey; else if(t == PKey::DSA) return static_cast<DSAKey *>(k)->evp.pkey; else return static_cast<DHKey *>(k)->evp.pkey; } PKeyBase *pkeyToBase(EVP_PKEY *pkey, bool sec) const { PKeyBase *nk = 0; if(pkey->type == EVP_PKEY_RSA) { RSAKey *c = new RSAKey(provider()); c->evp.pkey = pkey; c->sec = sec; nk = c; } else if(pkey->type == EVP_PKEY_DSA) { DSAKey *c = new DSAKey(provider()); c->evp.pkey = pkey; c->sec = sec; nk = c; } else if(pkey->type == EVP_PKEY_DH) { DHKey *c = new DHKey(provider()); c->evp.pkey = pkey; c->sec = sec; nk = c; } else { EVP_PKEY_free(pkey); } return nk; } virtual QByteArray publicToDER() const { EVP_PKEY *pkey = get_pkey(); // OpenSSL does not have DH import/export support if(pkey->type == EVP_PKEY_DH) return QByteArray(); BIO *bo = BIO_new(BIO_s_mem()); i2d_PUBKEY_bio(bo, pkey); QByteArray buf = bio2ba(bo); return buf; } virtual QString publicToPEM() const { EVP_PKEY *pkey = get_pkey(); // OpenSSL does not have DH import/export support if(pkey->type == EVP_PKEY_DH) return QString(); BIO *bo = BIO_new(BIO_s_mem()); PEM_write_bio_PUBKEY(bo, pkey); QByteArray buf = bio2ba(bo); return QString::fromLatin1(buf); } virtual ConvertResult publicFromDER(const QByteArray &in) { delete k; k = 0; BIO *bi = BIO_new(BIO_s_mem()); BIO_write(bi, in.data(), in.size()); EVP_PKEY *pkey = d2i_PUBKEY_bio(bi, NULL); BIO_free(bi); if(!pkey) return ErrorDecode; k = pkeyToBase(pkey, false); if(k) return ConvertGood; else return ErrorDecode; } virtual ConvertResult publicFromPEM(const QString &s) { delete k; k = 0; QByteArray in = s.toLatin1(); BIO *bi = BIO_new(BIO_s_mem()); BIO_write(bi, in.data(), in.size()); EVP_PKEY *pkey = PEM_read_bio_PUBKEY(bi, NULL, passphrase_cb, NULL); BIO_free(bi); if(!pkey) return ErrorDecode; k = pkeyToBase(pkey, false); if(k) return ConvertGood; else return ErrorDecode; } virtual SecureArray privateToDER(const SecureArray &passphrase, PBEAlgorithm pbe) const { //if(pbe == PBEDefault) // pbe = PBES2_TripleDES_SHA1; const EVP_CIPHER *cipher = 0; if(pbe == PBES2_TripleDES_SHA1) cipher = EVP_des_ede3_cbc(); else if(pbe == PBES2_DES_SHA1) cipher = EVP_des_cbc(); if(!cipher) return SecureArray(); EVP_PKEY *pkey = get_pkey(); // OpenSSL does not have DH import/export support if(pkey->type == EVP_PKEY_DH) return SecureArray(); BIO *bo = BIO_new(BIO_s_mem()); if(!passphrase.isEmpty()) i2d_PKCS8PrivateKey_bio(bo, pkey, cipher, NULL, 0, NULL, (void *)passphrase.data()); else i2d_PKCS8PrivateKey_bio(bo, pkey, NULL, NULL, 0, NULL, NULL); SecureArray buf = bio2buf(bo); return buf; } virtual QString privateToPEM(const SecureArray &passphrase, PBEAlgorithm pbe) const { //if(pbe == PBEDefault) // pbe = PBES2_TripleDES_SHA1; const EVP_CIPHER *cipher = 0; if(pbe == PBES2_TripleDES_SHA1) cipher = EVP_des_ede3_cbc(); else if(pbe == PBES2_DES_SHA1) cipher = EVP_des_cbc(); if(!cipher) return QString(); EVP_PKEY *pkey = get_pkey(); // OpenSSL does not have DH import/export support if(pkey->type == EVP_PKEY_DH) return QString(); BIO *bo = BIO_new(BIO_s_mem()); if(!passphrase.isEmpty()) PEM_write_bio_PKCS8PrivateKey(bo, pkey, cipher, NULL, 0, NULL, (void *)passphrase.data()); else PEM_write_bio_PKCS8PrivateKey(bo, pkey, NULL, NULL, 0, NULL, NULL); SecureArray buf = bio2buf(bo); return QString::fromLatin1(buf.toByteArray()); } virtual ConvertResult privateFromDER(const SecureArray &in, const SecureArray &passphrase) { delete k; k = 0; EVP_PKEY *pkey; if(!passphrase.isEmpty()) pkey = qca_d2i_PKCS8PrivateKey(in, NULL, NULL, (void *)passphrase.data()); else pkey = qca_d2i_PKCS8PrivateKey(in, NULL, passphrase_cb, NULL); if(!pkey) return ErrorDecode; k = pkeyToBase(pkey, true); if(k) return ConvertGood; else return ErrorDecode; } virtual ConvertResult privateFromPEM(const QString &s, const SecureArray &passphrase) { delete k; k = 0; QByteArray in = s.toLatin1(); BIO *bi = BIO_new(BIO_s_mem()); BIO_write(bi, in.data(), in.size()); EVP_PKEY *pkey; if(!passphrase.isEmpty()) pkey = PEM_read_bio_PrivateKey(bi, NULL, NULL, (void *)passphrase.data()); else pkey = PEM_read_bio_PrivateKey(bi, NULL, passphrase_cb, NULL); BIO_free(bi); if(!pkey) return ErrorDecode; k = pkeyToBase(pkey, true); if(k) return ConvertGood; else return ErrorDecode; }};//----------------------------------------------------------------------------// MyCertContext//----------------------------------------------------------------------------class X509Item{public: X509 *cert; X509_REQ *req; X509_CRL *crl; enum Type { TypeCert, TypeReq, TypeCRL }; X509Item() { cert = 0; req = 0; crl = 0; } X509Item(const X509Item &from) { cert = 0; req = 0; crl = 0; *this = from; } ~X509Item() { reset(); } X509Item & operator=(const X509Item &from) { if(this != &from) { reset(); cert = from.cert; req = from.req; crl = from.crl; if(cert) CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); if(req) CRYPTO_add(&req->references, 1, CRYPTO_LOCK_X509_REQ); if(crl) CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); } return *this; } void reset() { if(cert) { X509_free(cert); cert = 0; } if(req) { X509_REQ_free(req); req = 0; } if(crl) { X509_CRL_free(crl); crl = 0; } } bool isNull() const { return (!cert && !req && !crl); } QByteArray toDER() const { BIO *bo = BIO_new(BIO_s_mem()); if(ce
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -