Ejemplo n.º 1
0
pki_pkcs12::pki_pkcs12(const QString fname)
	:pki_base(fname)
{
	FILE *fp;
	Passwd pass;
	EVP_PKEY *mykey = NULL;
	X509 *mycert = NULL;
	key=NULL; cert=NULL;
	class_name="pki_pkcs12";
	certstack = sk_X509_new_null();
	pass_info p(XCA_TITLE, tr("Please enter the password to decrypt the PKCS#12 file:\n%1").arg(compressFilename(fname)));
	fp = fopen(QString2filename(fname), "rb");
	if (fp) {
		PKCS12 *pkcs12 = d2i_PKCS12_fp(fp, NULL);
		fclose(fp);
		if (ign_openssl_error()) {
			if (pkcs12)
				PKCS12_free(pkcs12);
			throw errorEx(tr("Unable to load the PKCS#12 (pfx) file %1.").arg(fname));
		}
		if (PKCS12_verify_mac(pkcs12, "", 0) || PKCS12_verify_mac(pkcs12, NULL, 0))
			pass.clear();
		else if (PwDialog::execute(&p, &pass) != 1) {
			/* cancel pressed */
			PKCS12_free(pkcs12);
			throw errorEx("","", E_PASSWD);
		}
		PKCS12_parse(pkcs12, pass.constData(), &mykey, &mycert, &certstack);
		int error = ERR_peek_error();
		if (ERR_GET_REASON(error) == PKCS12_R_MAC_VERIFY_FAILURE) {
			ign_openssl_error();
			PKCS12_free(pkcs12);
			throw errorEx(getClassName(), tr("The supplied password was wrong (%1)").arg(ERR_reason_error_string(error)), E_PASSWD);
		}
		ign_openssl_error();
		if (mycert) {
			if (mycert->aux && mycert->aux->alias) {
				alias = asn1ToQString(mycert->aux->alias);
				alias = QString::fromUtf8(alias.toAscii());
			}
			cert = new pki_x509(mycert);
			if (alias.isEmpty()) {
				cert->autoIntName();
			} else {
				cert->setIntName(alias);
			}
			alias = cert->getIntName();
		}
		if (mykey) {
			key = new pki_evp(mykey);
			key->setIntName(alias + "_key");
			key->bogusEncryptKey();
		}
		PKCS12_free(pkcs12);
	} else
		fopen_error(fname);
}
Ejemplo n.º 2
0
void pki_pkcs7::signBio(pki_x509 *crt, BIO *bio)
{
	pki_key *privkey;
	EVP_PKEY *pk;
	STACK_OF(X509) *certstack;
	if (!crt)
		return;
	privkey = crt->getRefKey();
	if (!privkey)
		throw errorEx("No private key for signing found", getClassName());
	certstack = sk_X509_new_null();

	pki_x509 *signer = crt->getSigner();
	if (signer == crt)
		signer = NULL;
	while (signer != NULL ) {
		sk_X509_push(certstack, signer->getCert());
	        openssl_error();
		if (signer == signer->getSigner() )
			signer = NULL;
		else
			signer = signer->getSigner();
	}
	if (p7)
		PKCS7_free(p7);
	pk = privkey->decryptKey();
	p7 = PKCS7_sign(crt->getCert(), pk, certstack, bio, PKCS7_BINARY);
	EVP_PKEY_free(pk);
	openssl_error();
	sk_X509_free(certstack);
}
Ejemplo n.º 3
0
void pki_x509req::fload(const QString fname)
{
	FILE *fp = fopen_read(fname);
	X509_REQ *_req;
	int ret = 0;

	if (fp != NULL) {
		_req = PEM_read_X509_REQ(fp, NULL, NULL, NULL);
		if (!_req) {
			pki_ign_openssl_error();
			rewind(fp);
			_req = d2i_X509_REQ_fp(fp, NULL);
		}
		fclose(fp);
		if (ret || pki_ign_openssl_error()) {
			if (_req)
				X509_REQ_free(_req);
			throw errorEx(tr("Unable to load the certificate request in file %1. Tried PEM, DER and SPKAC format.").arg(fname));
		}
	} else {
		fopen_error(fname);
		return;
	}

	if (_req) {
		X509_REQ_free(request);
		request = _req;
	}
	autoIntName();
	if (getIntName().isEmpty())
		setIntName(rmslashdot(fname));
	openssl_error(fname);
}
Ejemplo n.º 4
0
void pki_base::my_error(const QString error) const
{
	if (!error.isEmpty()) {
		fprintf(stderr, "%s\n", CCHAR(tr("Error: ") + error));
		throw errorEx(error, class_name);
	}
}
Ejemplo n.º 5
0
void pki_crl::fload(const QString fname)
{
	FILE *fp = fopen(QString2filename(fname), "r");
	X509_CRL *_crl;
	if (fp != NULL) {
		_crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL);
		if (!_crl) {
			pki_ign_openssl_error();
			rewind(fp);
			_crl = d2i_X509_CRL_fp(fp, NULL);
		}
		fclose(fp);
		if (pki_ign_openssl_error()) {
			if (_crl)
				X509_CRL_free(_crl);
			throw errorEx(tr("Unable to load the revokation list in file %1. Tried PEM and DER formatted CRL.").arg(fname));
		}
		if (crl)
			X509_CRL_free(crl);
		crl = _crl;
		setIntName(rmslashdot(fname));
		pki_openssl_error();
	} else
		fopen_error(fname);
}
Ejemplo n.º 6
0
void pki_multi::fromPEM_BIO(BIO *bio, QString name)
{
	QString text;
	pki_base *item = NULL;
	char buf[BUFLEN];
	int len, startpos;
	for (;;) {
		try {
			int pos = BIO_tell(bio);
			len = BIO_read(bio, buf, BUFLEN-1);
			buf[len] = '\0';
			text = buf;
			item = pkiByPEM(text, &startpos);
			if (!item) {
				if (startpos <= 0)
					break;
				if (BIO_seek(bio, pos + startpos) == -1)
					throw errorEx(tr("Seek failed"));
				continue;
			}
			pos += startpos;
			if (BIO_seek(bio, pos) == -1)
				throw errorEx(tr("Seek failed"));
			item->fromPEM_BIO(bio, name);
			if (pos == BIO_tell(bio)) {
				/* No progress, do it manually */
				if (BIO_seek(bio, pos + 1))
					throw errorEx(tr("Seek failed"));
				printf("Could not load: %s\n",
						CCHAR(item->getClassName()));
				delete item;
				continue;
			}
			openssl_error();
			multi.append(item);
		} catch (errorEx &err) {
			MainWindow::Error(err);
			if (item)
				delete item;
			item = NULL;
		}
	}
	if (multi.size() == 0)
		throw errorEx(tr("No known PEM encoded items found"));
}
Ejemplo n.º 7
0
void db_key::__setOwnPass(enum pki_key::passType x)
{
	pki_evp *targetKey;
	if (!currentIdx.isValid())
		        return;
	targetKey = static_cast<pki_evp*>(currentIdx.internalPointer());
	if (targetKey->isToken()) {
		throw errorEx(tr("Tried to change password of a token"));
	}
	targetKey->setOwnPass(x);
	updatePKI(targetKey);
}
Ejemplo n.º 8
0
void db_key::changeSoPin()
{
	pki_scard *scard;
	if (!currentIdx.isValid())
		        return;
	scard = static_cast<pki_scard*>(currentIdx.internalPointer());
	try {
		if (!scard->isToken()) {
			throw errorEx(tr("Tried to change SO PIN of a key"));
		}
		scard->changeSoPin();
	} catch (errorEx &err) {
		mainwin->Error(err);
	}
}
Ejemplo n.º 9
0
Archivo: db.cpp Proyecto: bizonix/xca
void db::rename(enum pki_type type, QString name, QString n)
{
	qint64 ret;

	first();
	if (find(type, n) == 0) {
		throw errorEx(QObject::tr("DB: Rename: '%1' already in use").arg(n));
	}
	first();
	if (find(type, name) != 0) {
		throw errorEx(QObject::tr("DB: Entry to rename not found: %1").arg(name));
	}
	strncpy(head.name, n.toUtf8(), NAMELEN);
	head.name[NAMELEN-1] = '\0';
	file.seek(head_offset);
	ret = file.write((char*)&head, sizeof(head));
	if (ret < 0) {
		fileIOerr("write");
	}
	if (ret != sizeof head) {
		throw errorEx(QObject::tr("DB: Write error %1 - %2"
				).arg(ret).arg(sizeof(head)));
	}
}
Ejemplo n.º 10
0
Archivo: func.cpp Proyecto: jbfavre/xca
void _openssl_error(const QString txt, const char *file, int line)
{
	QString error;

	while (int i = ERR_get_error() ) {
		error += QString(ERR_error_string(i, NULL)) + "\n";
		fputs(CCHAR(QString("OpenSSL error (%1:%2) : %3\n").
			arg(file).arg(line).arg(ERR_error_string(i, NULL))),
			stderr);
	}
	if (!error.isEmpty()) {
		if (!txt.isEmpty())
			error = txt + "\n" + error + "\n" +
				QString("(%1:%2)").arg(file).arg(line);
		throw errorEx(error);
	}
}
Ejemplo n.º 11
0
void pki_pkcs7::fload(const QString fname)
{
	PKCS7 *_p7;
	XFile file(fname);
	file.open_read();
	_p7 = PEM_read_PKCS7(file.fp(), NULL, NULL, NULL);
	if (!_p7) {
		ign_openssl_error();
		file.retry_read();
		_p7 = d2i_PKCS7_fp(file.fp(), NULL);
	}
	if (ign_openssl_error()) {
		if (_p7)
			PKCS7_free(_p7);
		throw errorEx(tr("Unable to load the PKCS#7 file %1. Tried PEM and DER format.").arg(fname));
	}
	if (p7)
		PKCS7_free(p7);
	p7 = _p7;
}
Ejemplo n.º 12
0
int read_dump(const char *filename, db_base **dbs, char *md5, int md5_len)
{
	char *p;
	int ret = -1, retlen = 0;
	int kv=0;
	bool md5sum = false;
	pki_base *pki = NULL;
	db_base *db;
	QFile file;
	QString line;

	file.setFileName(filename);
	if (! file.open(QIODevice::ReadOnly)) {
		throw errorEx(filename, strerror(errno));
		return -1;
	}
	for (;;) {
		line = readLine(&file);
		//printf("Line: '%s'\n", CCHAR(line));
		if (line.isNull()) {
			ret = 0;
			break;
		}

		//printf("FIRST char = '%c'\n", CCHAR(line)[0]);
		if (line[0] == ' ') {
			if (database >= 0 && database < 5)
				db = dbs[database];
			else
				db = NULL;
			kv ^= 1;
			p = read_data(CCHAR(line.trimmed()), &retlen);
			if (db && !md5) {
				if (kv) {
					pki = db->newPKI();
					if (!pki) {
						break;
					}
					pki->setIntName(p);
				} else {
					try {
						pki->oldFromData((unsigned char*)p, retlen);
						db->insert(pki);
					} catch (errorEx &err) {
						printf("Error catched for '%s'\n", CCHAR(pki->getIntName()));
					}
				}
			} else if (md5) {
				if (database == 5) {
					p = read_data(CCHAR(line.trimmed()), &retlen);
					if (kv)
						md5sum = (!strcmp(p, "pwhash")) ? true : false;
					if (!kv && md5sum) {
						strncpy(md5, p, md5_len);
						ret = 0;
						break;
					}
				}
			}
			free(p);
		} else {
			if (kv) {
				printf("Binary value expected\n");
				break;
			}
			handle_option(line);
		}
	}
	file.close();
	if (ret <0) {
		throw errorEx(filename, strerror(errno));
		return -1;
	}
	return 0;
}
Ejemplo n.º 13
0
Archivo: db.cpp Proyecto: bizonix/xca
void db::fileIOerr(QString s)
{
	errstr = QString("DB ") + s + "() '" + file.fileName() + "'";
	dberrno = errno;
	throw errorEx(errstr, strerror(errno));
}
Ejemplo n.º 14
0
void pki_evp::encryptKey(const char *password)
{
	int outl, keylen;
	EVP_PKEY *pkey1 = NULL;
	EVP_CIPHER_CTX ctx;
	const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
	unsigned char iv[EVP_MAX_IV_LENGTH], *punenc, *punenc1;
	unsigned char ckey[EVP_MAX_KEY_LENGTH];
	char ownPassBuf[MAX_PASS_LENGTH];

	/* This key has its own, private password */
	if (ownPass == ptPrivate) {
		int ret;
		pass_info p(XCA_TITLE, tr("Please enter the password to protect the private key: '%1'").
			arg(getIntName()));
		ret = MainWindow::passWrite(ownPassBuf, MAX_PASS_LENGTH, 0, &p);
		if (ret < 0)
			throw errorEx("Password input aborted", class_name);
	} else if (ownPass == ptBogus) { // BOGUS password
		ownPassBuf[0] = '\0';
	} else {
		if (password) {
			/* use the password parameter if this is a common password */
			strncpy(ownPassBuf, password, MAX_PASS_LENGTH);
		} else {
			int ret = 0;
			memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH);
			pass_info p(XCA_TITLE, tr("Please enter the database password for encrypting the key"));
			while (md5passwd(ownPassBuf) != passHash &&
				sha512passwd(ownPassBuf, passHash) != passHash )
			{
				ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0,&p);
				if (ret < 0)
					throw errorEx("Password input aborted", class_name);
			}
		}
	}

	/* Prepare Encryption */
	memset(iv, 0, EVP_MAX_IV_LENGTH);
	RAND_pseudo_bytes(iv,8);      /* Generate a salt */
	EVP_BytesToKey(cipher, EVP_sha1(), iv, (unsigned char *)ownPassBuf,
			strlen(ownPassBuf), 1, ckey, NULL);
	EVP_CIPHER_CTX_init (&ctx);
	pki_openssl_error();

	/* reserve space for unencrypted and encrypted key */
	keylen = i2d_PrivateKey(key, NULL);
	encKey.resize(keylen + EVP_MAX_KEY_LENGTH + 8);
	punenc1 = punenc = (unsigned char *)OPENSSL_malloc(keylen);
	check_oom(punenc);
	keylen = i2d_PrivateKey(key, &punenc1);
	pki_openssl_error();

	memcpy(encKey.data(), iv, 8); /* store the iv */
	/*
	 * Now DER version of privkey is in punenc
	 * and privkey is still in key
	 */

	/* do the encryption */
	/* store key right after the iv */
	EVP_EncryptInit(&ctx, cipher, ckey, iv);
	unsigned char *penc = (unsigned char *)encKey.data() +8;
	EVP_EncryptUpdate(&ctx, penc, &outl, punenc, keylen);
	int encKey_len = outl;
	EVP_EncryptFinal(&ctx, penc + encKey_len, &outl);
	encKey.resize(encKey_len + outl +8);
	/* Cleanup */
	EVP_CIPHER_CTX_cleanup(&ctx);
	/* wipe out the memory */
	memset(punenc, 0, keylen);
	OPENSSL_free(punenc);
	pki_openssl_error();

	pkey1 = priv2pub(key);
	check_oom(pkey1);
	EVP_PKEY_free(key);
	key = pkey1;
	pki_openssl_error();

	//CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);

	//printf("Encrypt: encKey_len=%d\n", encKey_len);
	return;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
void pki_evp::fload(const QString fname)
{
	pass_info p(XCA_TITLE, qApp->translate("MainWindow",
		"Please enter the password to decrypt the private key: '%1'").
		arg(fname));
	pem_password_cb *cb = MainWindow::passRead;
	FILE *fp = fopen(QString2filename(fname), "r");
	EVP_PKEY *pkey;

	pki_ign_openssl_error();
	if (!fp) {
		fopen_error(fname);
		return;
	}
	pkey = PEM_read_PrivateKey(fp, NULL, cb, &p);
	if (!pkey) {
		if (ERR_get_error() == 0x06065064) {
			fclose(fp);
			pki_ign_openssl_error();
			throw errorEx(tr("Failed to decrypt the key (bad password) ") +
					fname, class_name);
		}
	}
	if (!pkey) {
		pki_ign_openssl_error();
		rewind(fp);
		pkey = d2i_PrivateKey_fp(fp, NULL);
	}
	if (!pkey) {
		pki_ign_openssl_error();
		rewind(fp);
		pkey = d2i_PKCS8PrivateKey_fp(fp, NULL, cb, &p);
	}
	if (!pkey) {
		PKCS8_PRIV_KEY_INFO *p8inf;
		pki_ign_openssl_error();
		rewind(fp);
		p8inf = d2i_PKCS8_PRIV_KEY_INFO_fp(fp, NULL);
		if (p8inf) {
			pkey = EVP_PKCS82PKEY(p8inf);
			PKCS8_PRIV_KEY_INFO_free(p8inf);
		}
	}
	if (!pkey) {
		pki_ign_openssl_error();
		rewind(fp);
		pkey = PEM_read_PUBKEY(fp, NULL, cb, &p);
	}
	if (!pkey) {
		pki_ign_openssl_error();
		rewind(fp);
		pkey = d2i_PUBKEY_fp(fp, NULL);
	}
	fclose(fp);
	if (pki_ign_openssl_error()) {
		if (pkey)
			EVP_PKEY_free(pkey);
		throw errorEx(tr("Unable to load the private key in file %1. Tried PEM and DER private, public and PKCS#8 key types.").arg(fname));
	}
	if (pkey){
		if (pkey->type == EVP_PKEY_EC)
			search_ec_oid(pkey->pkey.ec);
		if (key)
			EVP_PKEY_free(key);
		key = pkey;
		if (EVP_PKEY_isPrivKey(key))
			bogusEncryptKey();
		setIntName(rmslashdot(fname));
	}
}