1 /* vi: set sw=4 ts=4:
2  *
3  * Copyright (C) 2001 - 2020 Christian Hohnstaedt.
4  *
5  * All rights reserved.
6  */
7 
8 
9 #include "pki_evp.h"
10 #include "pass_info.h"
11 #include "func.h"
12 #include "db.h"
13 #include "entropy.h"
14 #include "BioByteArray.h"
15 #include "widgets/PwDialog.h"
16 #include "widgets/XcaWarning.h"
17 #include "widgets/XcaProgress.h"
18 
19 #include <openssl/rand.h>
20 #include <openssl/evp.h>
21 #include <openssl/pem.h>
22 #include <openssl/pkcs12.h>
23 #include <openssl/err.h>
24 
25 #include "openssl_compat.h"
26 
27 Passwd pki_evp::passwd;
28 Passwd pki_evp::oldpasswd;
29 
30 QString pki_evp::passHash = QString();
31 
init()32 void pki_evp::init()
33 {
34 	ownPass = ptCommon;
35 	pkiType = asym_key;
36 }
37 
setOwnPass(enum passType x)38 void pki_evp::setOwnPass(enum passType x)
39 {
40 	EVP_PKEY *pk=NULL, *pk_back = key;
41 	enum passType oldOwnPass = ownPass;
42 
43 	if (ownPass == x || isPubKey())
44 		return;
45 
46 	try {
47 		pk = decryptKey();
48 		if (pk == NULL)
49 			return;
50 
51 		key = pk;
52 		ownPass = x;
53 		encryptKey();
54 	}
55 	catch (errorEx &err) {
56 		if (pk)
57 			EVP_PKEY_free(pk);
58 		key = pk_back;
59 		ownPass = oldOwnPass;
60 		throw(err);
61 	}
62 }
63 
sqlUpdatePrivateKey()64 bool pki_evp::sqlUpdatePrivateKey()
65 {
66 	Transaction;
67 	if (!TransBegin())
68 		return false;
69 	XSqlQuery q;
70 	SQL_PREPARE(q, "UPDATE private_keys SET private=?, ownPass=? "
71 		"WHERE item=?");
72 	q.bindValue(0, encKey_b64());
73 	q.bindValue(1, ownPass);
74 	q.bindValue(2, sqlItemId);
75 	AffectedItems(sqlItemId);
76 	q.exec();
77 
78 	encKey.fill(0);
79 	encKey.clear();
80 
81 	if (!q.lastError().isValid() && q.numRowsAffected() == 1) {
82 		TransCommit();
83 		return true;
84 	}
85 	return false;
86 }
87 
generate(const keyjob & task)88 void pki_evp::generate(const keyjob &task)
89 {
90 	Entropy::seed_rng();
91 	XcaProgress progress;
92 
93 #if OPENSSL_VERSION_NUMBER < 0x10100000L
94 	BN_GENCB _bar, *bar = &_bar;
95 #else
96 	BN_GENCB *bar = BN_GENCB_new();
97 #endif
98 	BN_GENCB_set_old(bar, XcaProgress::inc, &progress);
99 
100 	switch (task.ktype.type) {
101 	case EVP_PKEY_RSA: {
102 		RSA *rsakey = RSA_new();
103 		BIGNUM *e = BN_new();
104 		BN_set_word(e, 0x10001);
105 		if (RSA_generate_key_ex(rsakey, task.size, e, bar))
106 			EVP_PKEY_assign_RSA(key, rsakey);
107 		else
108 			RSA_free(rsakey);
109 		BN_free(e);
110 		break;
111 	}
112 	case EVP_PKEY_DSA: {
113 		DSA *dsakey = DSA_new();
114 		if (DSA_generate_parameters_ex(dsakey, task.size, NULL, 0,
115 			 NULL, NULL, bar) && DSA_generate_key(dsakey))
116 				EVP_PKEY_assign_DSA(key, dsakey);
117 		else
118 			DSA_free(dsakey);
119 		break;
120 	}
121 #ifndef OPENSSL_NO_EC
122 	case EVP_PKEY_EC: {
123 		EC_KEY *eckey;
124 		EC_GROUP *group = EC_GROUP_new_by_curve_name(task.ec_nid);
125 		if (!group)
126 			break;
127 		eckey = EC_KEY_new();
128 		if (eckey == NULL) {
129 			EC_GROUP_free(group);
130 			break;
131 		}
132 		EC_GROUP_set_asn1_flag(group, 1);
133 		if (EC_KEY_set_group(eckey, group)) {
134 			if (EC_KEY_generate_key(eckey)) {
135 				EVP_PKEY_assign_EC_KEY(key, eckey);
136 				EC_GROUP_free(group);
137 				break;
138 			}
139 		}
140 		EC_KEY_free(eckey);
141 		EC_GROUP_free(group);
142 		break;
143 	}
144 #ifdef EVP_PKEY_ED25519
145 	case EVP_PKEY_ED25519: {
146 		EVP_PKEY *pkey = NULL;
147 		EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
148 		EVP_PKEY_keygen_init(pctx);
149 		EVP_PKEY_keygen(pctx, &pkey);
150 		EVP_PKEY_CTX_free(pctx);
151 		EVP_PKEY_free(key);
152 		key = pkey;
153 	}
154 #endif
155 #endif
156 	}
157 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
158 	BN_GENCB_free(bar);
159 #endif
160 	isPub = false;
161 	pkiSource = generated;
162 	pki_openssl_error();
163 	encryptKey();
164 }
165 
pki_evp(const pki_evp * pk)166 pki_evp::pki_evp(const pki_evp *pk)
167 	:pki_key(pk)
168 {
169 	init();
170 	pki_openssl_error();
171 	ownPass = pk->ownPass;
172 	isPub = pk->isPub;
173 	encKey = pk->getEncKey();
174 }
175 
pki_evp(const QString & n,int type)176 pki_evp::pki_evp(const QString &n, int type)
177 	:pki_key(n)
178 {
179 	init();
180 	EVP_PKEY_set_type(key, type);
181 	pki_openssl_error();
182 }
183 
184 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
EVP_PKEY_isPrivKey(EVP_PKEY * key)185 static bool EVP_PKEY_isPrivKey(EVP_PKEY *key)
186 {
187 	const BIGNUM *b;
188 	int keytype = EVP_PKEY_id(key);
189 
190 	switch (EVP_PKEY_type(keytype)) {
191 		case EVP_PKEY_RSA:
192 			RSA_get0_key(EVP_PKEY_get0_RSA(key), NULL, NULL, &b);
193 			return b ? true: false;
194 		case EVP_PKEY_DSA:
195 			DSA_get0_key(EVP_PKEY_get0_DSA(key), NULL, &b);
196 			return b ? true: false;
197 #ifndef OPENSSL_NO_EC
198 		case EVP_PKEY_EC:
199 			return EC_KEY_get0_private_key(
200 				EVP_PKEY_get0_EC_KEY(key)) ? true: false;
201 #ifdef EVP_PKEY_ED25519
202 		case EVP_PKEY_ED25519: {
203 			unsigned char buf[ED25519_KEYLEN];
204 			size_t len = sizeof buf;
205 			int ret = EVP_PKEY_get_raw_private_key(key, buf, &len);
206 			ign_openssl_error();
207 			return ret && len == ED25519_KEYLEN;
208 		}
209 #endif
210 #endif
211 	}
212 	return false;
213 }
214 
215 #else
216 
EVP_PKEY_isPrivKey(EVP_PKEY * key)217 static bool EVP_PKEY_isPrivKey(EVP_PKEY *key)
218 {
219 	int keytype;
220 
221 	keytype = EVP_PKEY_id(key);
222 
223 	switch (EVP_PKEY_type(keytype)) {
224 		case EVP_PKEY_RSA:
225 			return key->pkey.rsa->d ? true: false;
226 		case EVP_PKEY_DSA:
227 			return key->pkey.dsa->priv_key ? true: false;
228 #ifndef OPENSSL_NO_EC
229 		case EVP_PKEY_EC:
230 			return EC_KEY_get0_private_key(key->pkey.ec) ? true: false;
231 #endif
232 	}
233 	return false;
234 }
235 #endif
236 
pki_evp(EVP_PKEY * pkey)237 pki_evp::pki_evp(EVP_PKEY *pkey)
238 	:pki_key()
239 {
240 	init();
241 	set_EVP_PKEY(pkey);
242 }
243 
openssl_pw_error() const244 bool pki_evp::openssl_pw_error() const
245 {
246 	switch (ERR_peek_error() & 0xff000fff) {
247 	case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_DECRYPT):
248 	case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_PASSWORD_READ):
249 	case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT):
250 		pki_ign_openssl_error();
251 		return true;
252 	}
253 	return false;
254 }
255 
fromPEMbyteArray(const QByteArray & ba,const QString & name)256 void pki_evp::fromPEMbyteArray(const QByteArray &ba, const QString &name)
257 {
258 	EVP_PKEY *pkey;
259 	pass_info p(XCA_TITLE,
260 		tr("Please enter the password to decrypt the private key %1.")
261 			.arg(name));
262 	pkey = load_ssh_ed25519_privatekey(ba, p);
263 
264 	while (!pkey) {
265 		pkey = PEM_read_bio_PrivateKey(BioByteArray(ba).ro(), NULL,
266 						PwDialog::pwCallback, &p);
267 		if (openssl_pw_error())
268 			XCA_PASSWD_ERROR();
269 		if (p.getResult() != pw_ok)
270 			throw p.getResult();
271 		if (pki_ign_openssl_error())
272 			break;
273 	}
274 	if (!pkey) {
275 		pki_ign_openssl_error();
276 		pkey = PEM_read_bio_PUBKEY(BioByteArray(ba).ro(), NULL, NULL,0);
277 	}
278 	pki_openssl_error();
279 	set_EVP_PKEY(pkey, name);
280 }
281 
search_ec_oid(EVP_PKEY * pkey)282 static void search_ec_oid(EVP_PKEY *pkey)
283 {
284 #ifndef OPENSSL_NO_EC
285 	EC_KEY *ec;
286 	EC_GROUP *builtin;
287 	const EC_GROUP *ec_group;
288 
289 	int keytype = EVP_PKEY_id(pkey);
290 
291 	if (keytype != EVP_PKEY_EC)
292 		return;
293 
294 	ec = EVP_PKEY_get0_EC_KEY(pkey);
295 	if (!ec)
296 		return;
297 
298 	ec_group = EC_KEY_get0_group(ec);
299 	if (!ec_group)
300 		return;
301 	if (EC_GROUP_get_curve_name(ec_group))
302 		return;
303 	/* There is an EC_GROUP with a missing OID
304 	 * because of explicit parameters */
305 	foreach(builtin_curve curve, builtinCurves) {
306 		builtin = EC_GROUP_new_by_curve_name(curve.nid);
307 		if (EC_GROUP_cmp(builtin, ec_group, NULL) == 0) {
308 			EC_GROUP_set_curve_name((EC_GROUP *)ec_group, curve.nid);
309 			EC_GROUP_set_asn1_flag((EC_GROUP *)ec_group, 1);
310 			EC_GROUP_free(builtin);
311 			break;
312 		}
313 		EC_GROUP_free(builtin);
314 	}
315 #else
316 	(void)pkey;
317 #endif
318 }
319 
set_EVP_PKEY(EVP_PKEY * pkey,QString name)320 void pki_evp::set_EVP_PKEY(EVP_PKEY *pkey, QString name)
321 {
322 	if (!pkey)
323 		return;
324 	if (!verify(pkey)) {
325 		pki_ign_openssl_error();
326 		EVP_PKEY_free(pkey);
327 		throw errorEx(tr("The key from file '%1' is incomplete or inconsistent.").arg(name));
328 	}
329 	if (key)
330 		EVP_PKEY_free(key);
331 	key = pkey;
332 	isPub = !EVP_PKEY_isPrivKey(key);
333 	if (!isPub)
334 		bogusEncryptKey();
335 	search_ec_oid(pkey);
336 
337 	autoIntName(name);
338 	setFilename(name);
339 	pki_openssl_error();
340 }
341 
load_ssh_ed25519_privatekey(const QByteArray & ba,const pass_info & p)342 EVP_PKEY *pki_evp::load_ssh_ed25519_privatekey(const QByteArray &ba,
343 						const pass_info &p)
344 {
345 	EVP_PKEY *pkey = NULL;
346 	unsigned char *pdata;
347 	long plen;
348 	QByteArray chunk, enc_algo, kdfname, kdf, pub, priv;
349 
350 	(void)p; // Will be used later for decryption
351 	if (!PEM_bytes_read_bio(&pdata, &plen, NULL, PEM_STRING_OPENSSH_KEY,
352 				BioByteArray(ba).ro(), NULL, NULL))
353 		return NULL;
354 
355 	QByteArray content((const char*)pdata, plen);
356 	OPENSSL_free(pdata);
357 
358 	if (!content.startsWith("openssh-key-v1") ||
359 	     // also check trailing \0
360 	     content.constData()[sizeof "openssh-key-v1" -1])
361 		return NULL;
362 
363 	content.remove(0, sizeof "openssh-key-v1");
364 	// encryption: "none", "aes256-ctr"
365 	enc_algo = ssh_key_next_chunk(&content);
366 	// KDFName "bcrypt"
367 	kdfname = ssh_key_next_chunk(&content);
368 	kdf = ssh_key_next_chunk(&content);
369 
370 	if (enc_algo != "none" || kdfname != "none") {
371 		qCritical("Encrypted SSH ED25519 keys not supported, yet");
372 		return NULL;
373 	}
374 	// check bytes 00 00 00 01
375 	const char *d = content.constData();
376 	if (d[0] || d[1] || d[2] || d[3] != 1)
377 		return NULL;
378 	content.remove(0, 4);
379 	// Handle first occurance of the public key
380 	pub = ssh_key_next_chunk(&content);
381 	ssh_key_check_chunk(&pub, "ssh-ed25519");
382 	pub = ssh_key_next_chunk(&pub);
383 	if (pub.count() != ED25519_KEYLEN)
384 		return NULL;
385 
386 	// Followed by the private key
387 	priv = ssh_key_next_chunk(&content);
388 	// Drop 64bit random nonce
389 	priv.remove(0, 8);
390 
391 	ssh_key_check_chunk(&priv, "ssh-ed25519");
392 	// The first pubkey must match the second occurance
393 	// in front of the private one
394 	if (pub != ssh_key_next_chunk(&priv))
395 		return NULL;
396 	priv = ssh_key_next_chunk(&priv);
397 	// The private key is concatenated by the public key in one chunk
398 	if (priv.count() != 2 * ED25519_KEYLEN)
399 		return NULL;
400 	// The last ED25519_KEYLEN bytes must match the public key
401 	if (pub != priv.mid(ED25519_KEYLEN))
402 		return NULL;
403 	// The first ED25519_KEYLEN octets are the private key
404 #ifndef OPENSSL_NO_EC
405 #ifdef EVP_PKEY_ED25519
406 	pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL,
407 		(const unsigned char *)priv.constData(), ED25519_KEYLEN);
408 #endif
409 #endif
410 	pki_openssl_error();
411 	return pkey;
412 }
413 
fload(const QString & fname)414 void pki_evp::fload(const QString &fname)
415 {
416 	pass_info p(XCA_TITLE, tr("Please enter the password to decrypt the private key from file:\n%1").
417 		arg(compressFilename(fname)));
418 	pem_password_cb *cb = PwDialog::pwCallback;
419 
420 	pki_ign_openssl_error();
421 	XFile file(fname);
422 	file.open_read();
423 	EVP_PKEY *pkey;
424 
425 	do {
426 		pkey = PEM_read_PrivateKey(file.fp(), NULL, cb, &p);
427 		if (openssl_pw_error())
428 			XCA_PASSWD_ERROR();
429 		if (p.getResult() != pw_ok)
430 			throw p.getResult();
431 		if (pki_ign_openssl_error())
432 			break;
433 		file.retry_read();
434 	} while (!pkey);
435 
436 	if (!pkey) {
437 		pki_ign_openssl_error();
438 		file.retry_read();
439 		pkey = d2i_PrivateKey_fp(file.fp(), NULL);
440 	}
441 	if (!pkey) {
442 		pki_ign_openssl_error();
443 		file.retry_read();
444 		pkey = d2i_PKCS8PrivateKey_fp(file.fp(), NULL, cb, &p);
445 	}
446 	if (!pkey) {
447 		PKCS8_PRIV_KEY_INFO *p8inf;
448 		pki_ign_openssl_error();
449 		file.retry_read();
450 		p8inf = d2i_PKCS8_PRIV_KEY_INFO_fp(file.fp(), NULL);
451 		if (p8inf) {
452 			pkey = EVP_PKCS82PKEY(p8inf);
453 			PKCS8_PRIV_KEY_INFO_free(p8inf);
454 		}
455 	}
456 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
457 	if (!pkey) {
458 		pki_ign_openssl_error();
459 		file.retry_read();
460 		pkey = b2i_PVK_bio(file.bio(), cb, &p);
461 	}
462 	if (!pkey) {
463 		pki_ign_openssl_error();
464 		file.retry_read();
465 		pkey = load_ssh_ed25519_privatekey(file.read(10000), p);
466 	}
467 #endif
468 	if (!pkey) {
469 		pki_ign_openssl_error();
470 		file.retry_read();
471 		pkey = PEM_read_PUBKEY(file.fp(), NULL, cb, &p);
472 	}
473 	if (!pkey) {
474 		pki_ign_openssl_error();
475 		file.retry_read();
476 		pkey = d2i_PUBKEY_fp(file.fp(), NULL);
477 	}
478 	if (!pkey) {
479 		pki_ign_openssl_error();
480 		file.retry_read();
481 		pkey = load_ssh2_key(file);
482 	}
483 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
484 	if (!pkey) {
485 		pki_ign_openssl_error();
486 		file.retry_read();
487 		pkey = b2i_PublicKey_bio(file.bio());
488 	}
489 #endif
490 	if (pki_ign_openssl_error() || !pkey) {
491 		if (pkey)
492 			EVP_PKEY_free(pkey);
493 		throw errorEx(tr("Unable to load the private key in file %1. Tried PEM and DER private, public, PKCS#8 key types and SSH2 format.").arg(fname));
494 	}
495 	set_EVP_PKEY(pkey, fname);
496 }
497 
fromData(const unsigned char * p,db_header_t * head)498 void pki_evp::fromData(const unsigned char *p, db_header_t *head)
499 {
500 	int version, type, size;
501 	void *ptr = NULL;
502 
503 	if (key)
504 		EVP_PKEY_free(key);
505 	key = NULL;
506 
507 	size = head->len - sizeof(db_header_t);
508 	version = head->version;
509 
510 	QByteArray ba((const char*)p, size);
511 
512 	type = db::intFromData(ba);
513 	ownPass = (enum passType)db::intFromData(ba);
514 	if (version < 2) {
515 		d2i_old(ba, type);
516 	} else {
517 		d2i(ba);
518 	}
519 	pki_openssl_error();
520 
521 	if (key)
522 		ptr = EVP_PKEY_get0(key);
523 	if (!ptr)
524 		throw errorEx(tr("Ignoring unsupported private key"));
525 
526 	encKey = ba;
527 	isPub = encKey.size() == 0;
528 }
529 
decryptKey() const530 EVP_PKEY *pki_evp::decryptKey() const
531 {
532 	Passwd ownPassBuf;
533 	int ret;
534 
535 	if (isPubKey()) {
536 		QByteArray ba = i2d_bytearray(I2D_VOID(i2d_PUBKEY), key);
537 		return (EVP_PKEY*)d2i_bytearray(D2I_VOID(d2i_PUBKEY), ba);
538 	}
539 	/* This key has its own password */
540 	if (ownPass == ptPrivate) {
541 		pass_info pi(XCA_TITLE, tr("Please enter the password to decrypt the private key: '%1'").arg(getIntName()));
542 		ret = PwDialog::execute(&pi, &ownPassBuf, false);
543 		if (ret != 1)
544 			throw errorEx(tr("Password input aborted"),
545 					getClassName());
546 	} else if (ownPass == ptBogus) { // BOGUS pass
547 		ownPassBuf = "Bogus";
548 	} else {
549 		ownPassBuf = passwd;
550 		while (passHash.isEmpty() ||
551 			(sha512passwT(ownPassBuf, passHash) != passHash &&
552 			 sha512passwd(ownPassBuf, passHash) != passHash))
553 		{
554 			pass_info p(XCA_TITLE, tr("Please enter the database password for decrypting the key '%1'").arg(getIntName()));
555 			ret = PwDialog::execute(&p, &ownPassBuf,
556 							passHash.isEmpty());
557 			if (ret != 1)
558 				throw errorEx(tr("Password input aborted"),
559 						getClassName());
560 		}
561 	}
562 	QByteArray myencKey = getEncKey();
563 	qDebug() << "myencKey.count()"<<myencKey.count();
564 	if (myencKey.count() == 0)
565 		return NULL;
566 	EVP_PKEY *priv = NULL;
567 	X509_SIG *p8 = d2i_PKCS8_bio(BioByteArray(myencKey).ro(), NULL);
568 	if (p8) {
569 		PKCS8_PRIV_KEY_INFO *p8inf = PKCS8_decrypt(p8,
570 				ownPassBuf.constData(), ownPassBuf.size());
571 		if (p8inf) {
572 			priv = EVP_PKCS82PKEY(p8inf);
573 			PKCS8_PRIV_KEY_INFO_free(p8inf);
574 		}
575 		X509_SIG_free(p8);
576 	}
577 	if (priv)
578 		return priv;
579 	pki_ign_openssl_error();
580 	return legacyDecryptKey(myencKey, ownPassBuf);
581 }
582 
legacyDecryptKey(QByteArray & myencKey,Passwd & ownPassBuf) const583 EVP_PKEY *pki_evp::legacyDecryptKey(QByteArray &myencKey,
584 				    Passwd &ownPassBuf) const
585 {
586 	unsigned char *p;
587 	const unsigned char *p1;
588 	int outl, decsize;
589 	unsigned char iv[EVP_MAX_IV_LENGTH];
590 	unsigned char ckey[EVP_MAX_KEY_LENGTH];
591 
592 	EVP_PKEY *tmpkey;
593 	EVP_CIPHER_CTX *ctx;
594 	const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
595 	p = (unsigned char *)OPENSSL_malloc(myencKey.count());
596 	check_oom(p);
597 	pki_openssl_error();
598 	p1 = p;
599 	memset(iv, 0, EVP_MAX_IV_LENGTH);
600 
601 	memcpy(iv, myencKey.constData(), 8); /* recover the iv */
602 	/* generate the key */
603 	EVP_BytesToKey(cipher, EVP_sha1(), iv,
604 		ownPassBuf.constUchar(), ownPassBuf.size(), 1, ckey, NULL);
605 	ctx = EVP_CIPHER_CTX_new();
606 	EVP_DecryptInit(ctx, cipher, ckey, iv);
607 	EVP_DecryptUpdate(ctx, p , &outl,
608 		(const unsigned char*)myencKey.constData() +8,
609 		myencKey.count() -8);
610 	decsize = outl;
611 	EVP_DecryptFinal_ex(ctx, p + decsize , &outl);
612 
613 	EVP_CIPHER_CTX_cleanup(ctx);
614 	decsize += outl;
615 	pki_openssl_error();
616 	tmpkey = d2i_PrivateKey(getKeyType(), NULL, &p1, decsize);
617 	pki_openssl_error();
618 	OPENSSL_cleanse(p, myencKey.count());
619 	OPENSSL_free(p);
620 	EVP_CIPHER_CTX_free(ctx);
621 
622 	pki_openssl_error();
623 	if (EVP_PKEY_type(getKeyType()) == EVP_PKEY_RSA) {
624 		RSA *rsa = EVP_PKEY_get0_RSA(tmpkey);
625 		RSA_blinding_on(rsa, NULL);
626 	}
627 	myencKey.fill(0);
628 	return tmpkey;
629 }
630 
priv2pub(EVP_PKEY * key)631 EVP_PKEY *pki_evp::priv2pub(EVP_PKEY* key)
632 {
633 	int keylen;
634 	unsigned char *p, *p1;
635 	EVP_PKEY *pubkey;
636 
637 	keylen = i2d_PUBKEY(key, NULL);
638 	p1 = p = (unsigned char *)OPENSSL_malloc(keylen);
639 	check_oom(p);
640 
641 	/* convert rsa/dsa/ec to Pubkey */
642 	keylen = i2d_PUBKEY(key, &p);
643 	pki_openssl_error();
644 	p = p1;
645 	pubkey = d2i_PUBKEY(NULL, (const unsigned char**)&p, keylen);
646 	OPENSSL_free(p1);
647 	pki_openssl_error();
648 	return pubkey;
649 }
650 
encryptKey(const char * password)651 void pki_evp::encryptKey(const char *password)
652 {
653 	Passwd ownPassBuf;
654 
655 	pki_openssl_error();
656 	/* This key has its own, private password */
657 	if (ownPass == ptPrivate) {
658 		int ret;
659 		pass_info p(XCA_TITLE, tr("Please enter the password to protect the private key: '%1'").
660 			arg(getIntName()));
661 		ret = PwDialog::execute(&p, &ownPassBuf, true);
662 		if (ret != 1)
663 			throw errorEx("Password input aborted", getClassName());
664 		pki_openssl_error();
665 	} else if (ownPass == ptBogus) { // BOGUS password
666 		ownPassBuf = "Bogus";
667 		pki_openssl_error();
668 	} else {
669 		if (password) {
670 			/* use the password parameter
671 			 * if this is a common password */
672 			ownPassBuf = password;
673 			pki_openssl_error();
674 		} else {
675 			int ret = 0;
676 			ownPassBuf = passwd;
677 			pass_info p(XCA_TITLE, tr("Please enter the database password for encrypting the key"));
678 			while (passHash.isEmpty() ||
679 				(sha512passwT(ownPassBuf, passHash) != passHash &&
680 				 sha512passwd(ownPassBuf, passHash) != passHash))
681 			{
682 				ret = PwDialog::execute(&p, &ownPassBuf,
683 							passHash.isEmpty());
684 				if (ret != 1)
685 					throw errorEx("Password input aborted",
686 							getClassName());
687 			}
688 		}
689 	}
690 
691 	/* Convert private key to DER(PKCS8-aes) */
692 	BioByteArray bba;
693 	i2d_PKCS8PrivateKey_bio(bba, key, EVP_aes_256_cbc(),
694 		ownPassBuf.data(), ownPassBuf.size(), NULL, 0);
695 	pki_openssl_error();
696 	encKey = bba;
697 
698 	/* Replace private key by public key and
699 	   have the encrypted private in "encKey"
700 	 */
701 	EVP_PKEY *pkey1 = priv2pub(key);
702 	check_oom(pkey1);
703 	EVP_PKEY_free(key);
704 	key = pkey1;
705 	pki_openssl_error();
706 }
707 
set_evp_key(EVP_PKEY * pkey)708 void pki_evp::set_evp_key(EVP_PKEY *pkey)
709 {
710 	if (key)
711 		free(key);
712 	key = pkey;
713 }
714 
bogusEncryptKey()715 void pki_evp::bogusEncryptKey()
716 {
717 	ownPass = ptBogus;
718 	isPub = false;
719 	encryptKey();
720 }
721 
~pki_evp()722 pki_evp::~pki_evp()
723 {
724 	encKey.fill(0);
725 }
726 
insertSqlData()727 QSqlError pki_evp::insertSqlData()
728 {
729 	XSqlQuery q;
730 	QSqlError e = pki_key::insertSqlData();
731 	if (e.isValid())
732 		return e;
733 	if (isPubKey())
734 		return QSqlError();
735 
736 	SQL_PREPARE(q, "INSERT INTO private_keys (item, ownPass, private) "
737 		  "VALUES (?, ?, ?)");
738 	q.bindValue(0, sqlItemId);
739 	q.bindValue(1, ownPass);
740 	q.bindValue(2, encKey_b64());
741 	q.exec();
742 	encKey.fill(0);
743 	encKey.clear();
744 	return q.lastError();
745 }
746 
restoreSql(const QSqlRecord & rec)747 void pki_evp::restoreSql(const QSqlRecord &rec)
748 {
749 	pki_key::restoreSql(rec);
750 	isPub = rec.isNull(VIEW_private_ownpass);
751 	if (!isPub)
752 		ownPass =(enum passType)rec.value(VIEW_private_ownpass).toInt();
753 }
754 
getEncKey() const755 QByteArray pki_evp::getEncKey() const
756 {
757 	XSqlQuery q;
758 	QSqlError e;
759 	QByteArray ba;
760 
761 	if (encKey.count() > 0 || !sqlItemId.isValid())
762 		return encKey;
763 
764 	SQL_PREPARE(q, "SELECT private FROM private_keys WHERE item=?");
765 	q.bindValue(0, sqlItemId);
766 	q.exec();
767 	e = q.lastError();
768 	if (e.isValid() || !q.first())
769 		return QByteArray();
770 	return QByteArray::fromBase64(q.value(0).toByteArray().trimmed());
771 }
772 
deleteSqlData()773 QSqlError pki_evp::deleteSqlData()
774 {
775 	XSqlQuery q;
776 	QSqlError e = pki_key::deleteSqlData();
777 	if (e.isValid())
778 		return e;
779 	SQL_PREPARE(q, "DELETE FROM private_keys WHERE item=?");
780 	q.bindValue(0, sqlItemId);
781 	q.exec();
782 	return q.lastError();
783 }
784 
writePKCS8(XFile & file,const EVP_CIPHER * enc,pem_password_cb * cb,bool pem) const785 void pki_evp::writePKCS8(XFile &file, const EVP_CIPHER *enc,
786 		pem_password_cb *cb, bool pem) const
787 {
788 	pass_info p(XCA_TITLE,
789 		tr("Please enter the password protecting the PKCS#8 key '%1'")
790 			.arg(getIntName()));
791 	EVP_PKEY *pkey = decryptKey();
792 	if (!pkey) {
793 		pki_openssl_error();
794 		return;
795 	}
796 	if (pem) {
797 		PEM_file_comment(file);
798 		PEM_write_PKCS8PrivateKey(file.fp(), pkey, enc, NULL, 0,cb,&p);
799 	} else {
800 		i2d_PKCS8PrivateKey_fp(file.fp(), pkey, enc, NULL, 0, cb, &p);
801 	}
802 	EVP_PKEY_free(pkey);
803 }
804 
writePVKprivate(XFile & file,pem_password_cb * cb) const805 void pki_evp::writePVKprivate(XFile &file, pem_password_cb *cb) const
806 {
807 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
808 	pass_info p(XCA_TITLE, tr("Please enter the password protecting the Microsoft PVK key '%1'").arg(getIntName()));
809 
810 	int enc = cb ? 2 /* pvk-strong */ : 0 /* pvk-none */;
811 	EVP_PKEY *pkey = decryptKey();
812 	if (!pkey) {
813 		pki_openssl_error();
814 		return;
815 	}
816 	/* In case of success! the error
817 	 *   PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE)
818 	 * is set. Workaround this behavior */
819 	if (i2b_PVK_bio(file.bio(), pkey, enc, cb, &p) == -1) {
820 		pki_openssl_error();
821 		PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
822 		pki_openssl_error();
823 	}
824 	ign_openssl_error();
825 	EVP_PKEY_free(pkey);
826 #else
827 	(void)file;
828 	(void)cb;
829 	throw errorEx("Internal Error");
830 #endif
831 }
mycb(char * buf,int size,int,void *)832 static int mycb(char *buf, int size, int, void *)
833 {
834 	strncpy(buf, pki_evp::passwd, size);
835 	return strlen(pki_evp::passwd);
836 }
837 
writeDefault(const QString & dirname) const838 void pki_evp::writeDefault(const QString &dirname) const
839 {
840 	XFile file(get_dump_filename(dirname, ".pem"));
841 	file.open_key();
842 	writeKey(file, pki_evp::passwd[0] ? EVP_des_ede3_cbc() : NULL,
843 			mycb, true);
844 }
845 
846 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
PEM_write_bio_PrivateKey_traditional(BIO * bp,EVP_PKEY * x,const EVP_CIPHER * enc,unsigned char * kstr,int klen,pem_password_cb * cb,void * u)847 int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x,
848                                          const EVP_CIPHER *enc,
849                                          unsigned char *kstr, int klen,
850                                          pem_password_cb *cb, void *u)
851 {
852 	QString pem = keytype::byPKEY(x).traditionalPemName();
853 
854 	return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
855 			pem.toLatin1(), bp, (char*)x, enc, kstr, klen, cb, u);
856 }
857 #endif
858 
writeKey(XFile & file,const EVP_CIPHER * enc,pem_password_cb * cb,bool pem) const859 void pki_evp::writeKey(XFile &file, const EVP_CIPHER *enc,
860 			pem_password_cb *cb, bool pem) const
861 {
862 	pass_info p(XCA_TITLE,
863 		tr("Please enter the export password for the private key '%1'")
864 			.arg(getIntName()));
865 
866 	if (isPubKey()) {
867 		writePublic(file, pem);
868 		return;
869 	}
870 	EVP_PKEY *pkey = key ? decryptKey() : NULL;
871 	if (!pkey) {
872 	        pki_openssl_error();
873 		return;
874 	}
875 	if (pem) {
876 		PEM_file_comment(file);
877 		PEM_write_bio_PrivateKey_traditional(file.bio(), pkey, enc,
878 						NULL, 0, cb, &p);
879 	} else {
880 		i2d_PrivateKey_fp(file.fp(), pkey);
881 	}
882 	EVP_PKEY_free(pkey);
883 	pki_openssl_error();
884 }
885 
verify_priv(EVP_PKEY * pkey) const886 bool pki_evp::verify_priv(EVP_PKEY *pkey) const
887 {
888 	bool verify = true;
889 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
890 	unsigned char data[32], sig[1024];
891 	size_t datalen = sizeof data, siglen = sizeof sig;
892 	EVP_MD_CTX *ctx = NULL;
893 	const EVP_MD *md = EVP_sha256();
894 	EVP_PKEY_CTX *pkctx = NULL;
895 
896 	if (!EVP_PKEY_isPrivKey(pkey))
897 		return true;
898 	do {
899 		ctx = EVP_MD_CTX_new();
900 		pki_ign_openssl_error();
901 		RAND_bytes(data, datalen);
902 		check_oom(ctx);
903 		verify = false;
904 
905 		/* Sign some random data in "data" */
906 #ifdef EVP_PKEY_ED25519
907 		if (EVP_PKEY_id(pkey) == EVP_PKEY_ED25519)
908 			md = NULL;
909 #endif
910 		if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
911 			break;
912 
913 		if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA)
914 			EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PADDING);
915 
916 		if (!EVP_DigestSign(ctx, sig, &siglen, data, datalen))
917 			break;
918 
919 		/* Verify the signature */
920 		if (!EVP_DigestVerifyInit(ctx, NULL, md, NULL, pkey))
921 			break;
922 
923 		if (EVP_DigestVerify(ctx, sig, siglen, data, datalen) != 1)
924 			break;
925 
926 		verify = true;
927 	} while (0);
928 
929 	if (ctx)
930 		EVP_MD_CTX_free(ctx);
931 #endif
932 	if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_isPrivKey(pkey)) {
933 		RSA *rsa = EVP_PKEY_get0_RSA(pkey);
934 		if (RSA_check_key(rsa) != 1)
935 			verify = false;
936 	}
937 	pki_openssl_error();
938 	return verify;
939 }
940 
getIcon(const dbheader * hd) const941 QVariant pki_evp::getIcon(const dbheader *hd) const
942 {
943 	if (hd->id != HD_internal_name)
944 		return QVariant();
945 
946 	return QVariant(QPixmap(isPubKey() ? ":pubkeyIco" : ":keyIco"));
947 }
948 
md5passwd(QByteArray pass)949 QString pki_evp::md5passwd(QByteArray pass)
950 {
951 	return formatHash(Digest(pass, EVP_md5()));
952 }
953 
_sha512passwd(QByteArray pass,QString salt,int size,int repeat)954 QString pki_evp::_sha512passwd(QByteArray pass, QString salt,
955 				int size, int repeat)
956 {
957 	if (salt.length() < size)
958 		return QString();
959 
960 	salt = salt.left(size);
961 	pass = salt.toLatin1() + pass;
962 
963 	while (repeat--)
964 		pass = Digest(pass, EVP_sha512());
965 
966 	return salt + formatHash(pass, "");
967 }
968 
sha512passwd(QByteArray pass,QString salt)969 QString pki_evp::sha512passwd(QByteArray pass, QString salt)
970 {
971 	return _sha512passwd(pass, salt, 5, 1);
972 }
973 
sha512passwT(QByteArray pass,QString salt)974 QString pki_evp::sha512passwT(QByteArray pass, QString salt)
975 {
976 	return _sha512passwd(pass, salt, 17, 8000);
977 }
978