QString pki_key::getMsg(msg_type msg) { /* * We do not construct english sentences (just a little bit) * from fragments to allow proper translations. * The drawback are all the slightly different duplicated messages * * %1 will be replaced by "RSA", "DSA", "EC" * %2 is the internal name of the key */ QString ktype = getTypeString(); if (isPubKey()) { switch (msg) { case msg_import: return tr("Successfully imported the %1 public key '%2'").arg(ktype); case msg_delete: return tr("Delete the %1 public key '%2'?").arg(ktype); default: break; } } else { switch (msg) { case msg_import: return tr("Successfully imported the %1 private key '%2'").arg(ktype); case msg_delete: return tr("Delete the %1 private key '%2'?").arg(ktype); case msg_create: return tr("Successfully created the %1 private key '%2'").arg(ktype); default: break; } } if (msg == msg_delete_multi) { /* %1: Number of keys; %2: list of keynames */ return tr("Delete the %1 keys: %2?"); } return pki_base::getMsg(msg); }
void pki_evp::setOwnPass(enum passType x) { EVP_PKEY *pk=NULL, *pk_back = key; int oldOwnPass = ownPass; if (ownPass == x || isPubKey()) return; try { pk = decryptKey(); if (pk == NULL) return; key = pk; ownPass = x; encryptKey(); } catch (errorEx &err) { if (pk) EVP_PKEY_free(pk); key = pk_back; ownPass = oldOwnPass; throw(err); } EVP_PKEY_free(pk_back); }
QVariant pki_evp::getIcon(int id) { if (id != HD_internal_name) return QVariant(); int pixnum= isPubKey() ? 1 : 0; return QVariant(*icon[pixnum]); }
void pki_evp::writeKey(const QString fname, const EVP_CIPHER *enc, pem_password_cb *cb, bool pem) { EVP_PKEY *pkey; pass_info p(XCA_TITLE, tr("Please enter the export password for the private key '%1'").arg(getIntName())); if (isPubKey()) { writePublic(fname, pem); return; } FILE *fp = fopen(QString2filename(fname), "w"); if (!fp) { fopen_error(fname); return; } if (key){ pkey = decryptKey(); if (pkey) { if (pem) { PEM_write_PrivateKey(fp, pkey, enc, NULL, 0, cb, &p); } else { i2d_PrivateKey_fp(fp, pkey); } EVP_PKEY_free(pkey); } pki_openssl_error(); } fclose(fp); }
QVariant pki_key::column_data(dbheader *hd) { QStringList sl; sl << tr("Common") << tr("Private") << tr("Bogus") << tr("PIN"); switch (hd->id) { case HD_key_type: return QVariant(getTypeString()); case HD_key_size: return QVariant(length()); case HD_key_use: return QVariant(getUcount()); case HD_key_passwd: if (isPubKey()) return QVariant(tr("No password")); if (ownPass<0 || ownPass>3) return QVariant("Holla die Waldfee"); return QVariant(sl[ownPass]); } return pki_base::column_data(hd); }
bool pki_key::isPrivKey() const { return !isPubKey(); }
QString pki_key::getIntNameWithType() { return QString("%1 (%2%3)").arg(getIntName()).arg(getTypeString()). arg(isPubKey() ? QString(" ") + tr("public key") : QString("")); }
EVP_PKEY *pki_evp::decryptKey() const { unsigned char *p; const unsigned char *p1; int outl, decsize; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char ckey[EVP_MAX_KEY_LENGTH]; EVP_PKEY *tmpkey; EVP_CIPHER_CTX ctx; const EVP_CIPHER *cipher = EVP_des_ede3_cbc(); char ownPassBuf[MAX_PASS_LENGTH] = ""; if (isPubKey()) { unsigned char *q; outl = i2d_PUBKEY(key, NULL); p = q = (unsigned char *)OPENSSL_malloc(outl); check_oom(q); i2d_PUBKEY(key, &p); p = q; tmpkey = d2i_PUBKEY(NULL, (const unsigned char**)&p, outl); OPENSSL_free(q); return tmpkey; } /* This key has its own password */ if (ownPass == ptPrivate) { int ret; pass_info pi(XCA_TITLE, qApp->translate("MainWindow", "Please enter the password to decrypt the private key: '%1'").arg(getIntName())); ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &pi); if (ret < 0) throw errorEx(tr("Password input aborted"), class_name); } else if (ownPass == ptBogus) { // BOGUS pass ownPassBuf[0] = '\0'; } else { memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH); //printf("Orig password: '******' len:%d\n", passwd, strlen(passwd)); while (md5passwd(ownPassBuf) != passHash && sha512passwd(ownPassBuf, passHash) != passHash) { int ret; //printf("Passhash= '%s', new hash= '%s', passwd= '%s'\n", //CCHAR(passHash), CCHAR(md5passwd(ownPassBuf)), ownPassBuf); pass_info p(XCA_TITLE, tr("Please enter the database password for decrypting the key '%1'").arg(getIntName())); ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &p); if (ret < 0) throw errorEx(tr("Password input aborted"), class_name); } } //printf("Using decrypt Pass: %s\n", ownPassBuf); p = (unsigned char *)OPENSSL_malloc(encKey.count()); check_oom(p); pki_openssl_error(); p1 = p; memset(iv, 0, EVP_MAX_IV_LENGTH); memcpy(iv, encKey.constData(), 8); /* recover the iv */ /* generate the key */ EVP_BytesToKey(cipher, EVP_sha1(), iv, (unsigned char *)ownPassBuf, strlen(ownPassBuf), 1, ckey,NULL); /* we use sha1 as message digest, * because an md5 version of the password is * stored in the database... */ EVP_CIPHER_CTX_init(&ctx); EVP_DecryptInit(&ctx, cipher, ckey, iv); EVP_DecryptUpdate(&ctx, p , &outl, (const unsigned char*)encKey.constData() +8, encKey.count() -8); decsize = outl; EVP_DecryptFinal(&ctx, p + decsize , &outl); decsize += outl; //printf("Decrypt decsize=%d, encKey_len=%d\n", decsize, encKey_len); pki_openssl_error(); tmpkey = d2i_PrivateKey(key->type, NULL, &p1, decsize); pki_openssl_error(); OPENSSL_free(p); EVP_CIPHER_CTX_cleanup(&ctx); pki_openssl_error(); if (EVP_PKEY_type(tmpkey->type) == EVP_PKEY_RSA) RSA_blinding_on(tmpkey->pkey.rsa, NULL); return tmpkey; }