File indexing completed on 2024-05-05 04:45:09
0001 /* 0002 * Copyright (C) 2004-2007 Justin Karneges <justin@affinix.com> 0003 * Copyright (C) 2004-2006 Brad Hards <bradh@frogmouth.net> 0004 * Copyright (C) 2013-2016 Ivan Romanov <drizt@land.ru> 0005 * Copyright (C) 2017 Fabian Vogt <fabian@ritter-vogt.de> 0006 * 0007 * This library is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU Lesser General Public 0009 * License as published by the Free Software Foundation; either 0010 * version 2.1 of the License, or (at your option) any later version. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library; if not, write to the Free Software 0019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 0020 * 0021 */ 0022 0023 #include <QDebug> 0024 #include <QElapsedTimer> 0025 #include <QtCrypto> 0026 #include <QtPlugin> 0027 #include <qcaprovider.h> 0028 0029 #include <openssl/evp.h> 0030 #include <openssl/hmac.h> 0031 0032 #include <cstdio> 0033 #include <cstdlib> 0034 #include <iostream> 0035 #include <memory> 0036 0037 #include <openssl/err.h> 0038 #include <openssl/opensslv.h> 0039 #include <openssl/pem.h> 0040 #include <openssl/pkcs12.h> 0041 #include <openssl/rand.h> 0042 #include <openssl/ssl.h> 0043 #include <openssl/x509v3.h> 0044 #ifdef OPENSSL_VERSION_MAJOR 0045 #include <openssl/provider.h> 0046 #endif 0047 0048 #include <openssl/kdf.h> 0049 0050 using namespace QCA; 0051 0052 namespace { 0053 struct DsaDeleter 0054 { 0055 void operator()(DSA *pointer) 0056 { 0057 if (pointer) 0058 DSA_free(pointer); 0059 } 0060 }; 0061 0062 static bool s_legacyProviderAvailable = false; 0063 } // end of anonymous namespace 0064 0065 namespace opensslQCAPlugin { 0066 0067 //---------------------------------------------------------------------------- 0068 // Util 0069 //---------------------------------------------------------------------------- 0070 static SecureArray bio2buf(BIO *b) 0071 { 0072 SecureArray buf; 0073 while (true) { 0074 SecureArray block(1024); 0075 int ret = BIO_read(b, block.data(), block.size()); 0076 if (ret <= 0) 0077 break; 0078 block.resize(ret); 0079 buf.append(block); 0080 if (ret != 1024) 0081 break; 0082 } 0083 BIO_free(b); 0084 return buf; 0085 } 0086 0087 static QByteArray bio2ba(BIO *b) 0088 { 0089 QByteArray buf; 0090 while (true) { 0091 QByteArray block(1024, 0); 0092 int ret = BIO_read(b, block.data(), block.size()); 0093 if (ret <= 0) 0094 break; 0095 block.resize(ret); 0096 buf.append(block); 0097 if (ret != 1024) 0098 break; 0099 } 0100 BIO_free(b); 0101 return buf; 0102 } 0103 0104 static BigInteger bn2bi(const BIGNUM *n) 0105 { 0106 SecureArray buf(BN_num_bytes(n) + 1); 0107 buf[0] = 0; // positive 0108 BN_bn2bin(n, (unsigned char *)buf.data() + 1); 0109 return BigInteger(buf); 0110 } 0111 0112 static BigInteger bn2bi_free(BIGNUM *n) 0113 { 0114 BigInteger bi = bn2bi(n); 0115 BN_free(n); 0116 return bi; 0117 } 0118 0119 static BIGNUM *bi2bn(const BigInteger &n) 0120 { 0121 SecureArray buf = n.toArray(); 0122 return BN_bin2bn((const unsigned char *)buf.data(), buf.size(), nullptr); 0123 } 0124 0125 // take lowest bytes of BIGNUM to fit 0126 // pad with high byte zeroes to fit 0127 static SecureArray bn2fixedbuf(const BIGNUM *n, int size) 0128 { 0129 SecureArray buf(BN_num_bytes(n)); 0130 BN_bn2bin(n, (unsigned char *)buf.data()); 0131 0132 SecureArray out(size); 0133 memset(out.data(), 0, size); 0134 int len = qMin(size, buf.size()); 0135 memcpy(out.data() + (size - len), buf.data(), len); 0136 return out; 0137 } 0138 0139 static SecureArray dsasig_der_to_raw(const SecureArray &in) 0140 { 0141 DSA_SIG *sig = DSA_SIG_new(); 0142 const unsigned char *inp = (const unsigned char *)in.data(); 0143 d2i_DSA_SIG(&sig, &inp, in.size()); 0144 0145 const BIGNUM *bnr, *bns; 0146 DSA_SIG_get0(sig, &bnr, &bns); 0147 0148 SecureArray part_r = bn2fixedbuf(bnr, 20); 0149 SecureArray part_s = bn2fixedbuf(bns, 20); 0150 SecureArray result; 0151 result.append(part_r); 0152 result.append(part_s); 0153 0154 DSA_SIG_free(sig); 0155 return result; 0156 } 0157 0158 static SecureArray dsasig_raw_to_der(const SecureArray &in) 0159 { 0160 if (in.size() != 40) 0161 return SecureArray(); 0162 0163 DSA_SIG *sig = DSA_SIG_new(); 0164 SecureArray part_r(20); 0165 BIGNUM *bnr; 0166 SecureArray part_s(20); 0167 BIGNUM *bns; 0168 memcpy(part_r.data(), in.data(), 20); 0169 memcpy(part_s.data(), in.data() + 20, 20); 0170 bnr = BN_bin2bn((const unsigned char *)part_r.data(), part_r.size(), nullptr); 0171 bns = BN_bin2bn((const unsigned char *)part_s.data(), part_s.size(), nullptr); 0172 0173 if (DSA_SIG_set0(sig, bnr, bns) == 0) 0174 return SecureArray(); 0175 // Not documented what happens in the failure case, free bnr and bns? 0176 0177 int len = i2d_DSA_SIG(sig, nullptr); 0178 SecureArray result(len); 0179 unsigned char *p = (unsigned char *)result.data(); 0180 i2d_DSA_SIG(sig, &p); 0181 0182 DSA_SIG_free(sig); 0183 return result; 0184 } 0185 0186 static int passphrase_cb(char *buf, int size, int rwflag, void *u) 0187 { 0188 Q_UNUSED(buf); 0189 Q_UNUSED(size); 0190 Q_UNUSED(rwflag); 0191 Q_UNUSED(u); 0192 return 0; 0193 } 0194 0195 /*static bool is_basic_constraint(const ConstraintType &t) 0196 { 0197 bool basic = false; 0198 switch(t.known()) 0199 { 0200 case DigitalSignature: 0201 case NonRepudiation: 0202 case KeyEncipherment: 0203 case DataEncipherment: 0204 case KeyAgreement: 0205 case KeyCertificateSign: 0206 case CRLSign: 0207 case EncipherOnly: 0208 case DecipherOnly: 0209 basic = true; 0210 break; 0211 0212 case ServerAuth: 0213 case ClientAuth: 0214 case CodeSigning: 0215 case EmailProtection: 0216 case IPSecEndSystem: 0217 case IPSecTunnel: 0218 case IPSecUser: 0219 case TimeStamping: 0220 case OCSPSigning: 0221 break; 0222 } 0223 return basic; 0224 } 0225 0226 static Constraints basic_only(const Constraints &list) 0227 { 0228 Constraints out; 0229 for(int n = 0; n < list.count(); ++n) 0230 { 0231 if(is_basic_constraint(list[n])) 0232 out += list[n]; 0233 } 0234 return out; 0235 } 0236 0237 static Constraints ext_only(const Constraints &list) 0238 { 0239 Constraints out; 0240 for(int n = 0; n < list.count(); ++n) 0241 { 0242 if(!is_basic_constraint(list[n])) 0243 out += list[n]; 0244 } 0245 return out; 0246 }*/ 0247 0248 // logic from Botan 0249 /*static Constraints find_constraints(const PKeyContext &key, const Constraints &orig) 0250 { 0251 Constraints constraints; 0252 0253 if(key.key()->type() == PKey::RSA) 0254 constraints += KeyEncipherment; 0255 0256 if(key.key()->type() == PKey::DH) 0257 constraints += KeyAgreement; 0258 0259 if(key.key()->type() == PKey::RSA || key.key()->type() == PKey::DSA) 0260 { 0261 constraints += DigitalSignature; 0262 constraints += NonRepudiation; 0263 } 0264 0265 Constraints limits = basic_only(orig); 0266 Constraints the_rest = ext_only(orig); 0267 0268 if(!limits.isEmpty()) 0269 { 0270 Constraints reduced; 0271 for(int n = 0; n < constraints.count(); ++n) 0272 { 0273 if(limits.contains(constraints[n])) 0274 reduced += constraints[n]; 0275 } 0276 constraints = reduced; 0277 } 0278 0279 constraints += the_rest; 0280 0281 return constraints; 0282 }*/ 0283 0284 static void try_add_name_item(X509_NAME **name, int nid, const QString &val) 0285 { 0286 if (val.isEmpty()) 0287 return; 0288 const QByteArray buf = val.toLatin1(); 0289 if (!(*name)) 0290 *name = X509_NAME_new(); 0291 X509_NAME_add_entry_by_NID(*name, nid, MBSTRING_ASC, (const unsigned char *)buf.data(), buf.size(), -1, 0); 0292 } 0293 0294 static X509_NAME *new_cert_name(const CertificateInfo &info) 0295 { 0296 X509_NAME *name = nullptr; 0297 // FIXME support multiple items of each type 0298 try_add_name_item(&name, NID_commonName, info.value(CommonName)); 0299 try_add_name_item(&name, NID_countryName, info.value(Country)); 0300 try_add_name_item(&name, NID_localityName, info.value(Locality)); 0301 try_add_name_item(&name, NID_stateOrProvinceName, info.value(State)); 0302 try_add_name_item(&name, NID_organizationName, info.value(Organization)); 0303 try_add_name_item(&name, NID_organizationalUnitName, info.value(OrganizationalUnit)); 0304 return name; 0305 } 0306 0307 static void try_get_name_item(X509_NAME *name, int nid, const CertificateInfoType &t, CertificateInfo *info) 0308 { 0309 int loc; 0310 loc = -1; 0311 while ((loc = X509_NAME_get_index_by_NID(name, nid, loc)) != -1) { 0312 X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, loc); 0313 ASN1_STRING *data = X509_NAME_ENTRY_get_data(ne); 0314 QByteArray cs((const char *)data->data, data->length); 0315 info->insert(t, QString::fromLatin1(cs)); 0316 } 0317 } 0318 0319 static void 0320 try_get_name_item_by_oid(X509_NAME *name, const QString &oidText, const CertificateInfoType &t, CertificateInfo *info) 0321 { 0322 ASN1_OBJECT *oid = OBJ_txt2obj(oidText.toLatin1().data(), 1); // 1 = only accept dotted input 0323 if (!oid) 0324 return; 0325 0326 int loc; 0327 loc = -1; 0328 while ((loc = X509_NAME_get_index_by_OBJ(name, oid, loc)) != -1) { 0329 X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, loc); 0330 ASN1_STRING *data = X509_NAME_ENTRY_get_data(ne); 0331 QByteArray cs((const char *)data->data, data->length); 0332 info->insert(t, QString::fromLatin1(cs)); 0333 qDebug() << "oid: " << oidText << ", result: " << cs; 0334 } 0335 ASN1_OBJECT_free(oid); 0336 } 0337 0338 static CertificateInfo get_cert_name(X509_NAME *name) 0339 { 0340 CertificateInfo info; 0341 try_get_name_item(name, NID_commonName, CommonName, &info); 0342 try_get_name_item(name, NID_countryName, Country, &info); 0343 try_get_name_item_by_oid(name, QStringLiteral("1.3.6.1.4.1.311.60.2.1.3"), IncorporationCountry, &info); 0344 try_get_name_item(name, NID_localityName, Locality, &info); 0345 try_get_name_item_by_oid(name, QStringLiteral("1.3.6.1.4.1.311.60.2.1.1"), IncorporationLocality, &info); 0346 try_get_name_item(name, NID_stateOrProvinceName, State, &info); 0347 try_get_name_item_by_oid(name, QStringLiteral("1.3.6.1.4.1.311.60.2.1.2"), IncorporationState, &info); 0348 try_get_name_item(name, NID_organizationName, Organization, &info); 0349 try_get_name_item(name, NID_organizationalUnitName, OrganizationalUnit, &info); 0350 0351 // legacy email 0352 { 0353 CertificateInfo p9_info; 0354 try_get_name_item(name, NID_pkcs9_emailAddress, EmailLegacy, &p9_info); 0355 const QList<QString> emails = info.values(Email); 0356 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0357 QMultiMapIterator<CertificateInfoType, QString> it(p9_info); 0358 #else 0359 QMapIterator<CertificateInfoType, QString> it(p9_info); 0360 #endif 0361 while (it.hasNext()) { 0362 it.next(); 0363 if (!emails.contains(it.value())) 0364 info.insert(Email, it.value()); 0365 } 0366 } 0367 0368 return info; 0369 } 0370 0371 static X509_EXTENSION *new_subject_key_id(X509 *cert) 0372 { 0373 X509V3_CTX ctx; 0374 X509V3_set_ctx_nodb(&ctx); 0375 X509V3_set_ctx(&ctx, nullptr, cert, nullptr, nullptr, 0); 0376 X509_EXTENSION *ex = X509V3_EXT_conf_nid(nullptr, &ctx, NID_subject_key_identifier, (char *)"hash"); 0377 return ex; 0378 } 0379 0380 static X509_EXTENSION *new_basic_constraints(bool ca, int pathlen) 0381 { 0382 BASIC_CONSTRAINTS *bs = BASIC_CONSTRAINTS_new(); 0383 bs->ca = (ca ? 1 : 0); 0384 bs->pathlen = ASN1_INTEGER_new(); 0385 ASN1_INTEGER_set(bs->pathlen, pathlen); 0386 0387 X509_EXTENSION *ex = X509V3_EXT_i2d(NID_basic_constraints, 1, bs); // 1 = critical 0388 BASIC_CONSTRAINTS_free(bs); 0389 return ex; 0390 } 0391 0392 static void get_basic_constraints(X509_EXTENSION *ex, bool *ca, int *pathlen) 0393 { 0394 BASIC_CONSTRAINTS *bs = (BASIC_CONSTRAINTS *)X509V3_EXT_d2i(ex); 0395 *ca = (bs->ca ? true : false); 0396 if (bs->pathlen) 0397 *pathlen = ASN1_INTEGER_get(bs->pathlen); 0398 else 0399 *pathlen = 0; 0400 BASIC_CONSTRAINTS_free(bs); 0401 } 0402 0403 enum ConstraintBit 0404 { 0405 Bit_DigitalSignature = 0, 0406 Bit_NonRepudiation = 1, 0407 Bit_KeyEncipherment = 2, 0408 Bit_DataEncipherment = 3, 0409 Bit_KeyAgreement = 4, 0410 Bit_KeyCertificateSign = 5, 0411 Bit_CRLSign = 6, 0412 Bit_EncipherOnly = 7, 0413 Bit_DecipherOnly = 8 0414 }; 0415 0416 static QByteArray ipaddress_string_to_bytes(const QString &) 0417 { 0418 return QByteArray(4, 0); 0419 } 0420 0421 static GENERAL_NAME *new_general_name(const CertificateInfoType &t, const QString &val) 0422 { 0423 GENERAL_NAME *name = nullptr; 0424 switch (t.known()) { 0425 case Email: 0426 { 0427 const QByteArray buf = val.toLatin1(); 0428 0429 ASN1_IA5STRING *str = ASN1_IA5STRING_new(); 0430 ASN1_STRING_set((ASN1_STRING *)str, (const unsigned char *)buf.data(), buf.size()); 0431 0432 name = GENERAL_NAME_new(); 0433 name->type = GEN_EMAIL; 0434 name->d.rfc822Name = str; 0435 break; 0436 } 0437 case URI: 0438 { 0439 const QByteArray buf = val.toLatin1(); 0440 0441 ASN1_IA5STRING *str = ASN1_IA5STRING_new(); 0442 ASN1_STRING_set((ASN1_STRING *)str, (const unsigned char *)buf.data(), buf.size()); 0443 0444 name = GENERAL_NAME_new(); 0445 name->type = GEN_URI; 0446 name->d.uniformResourceIdentifier = str; 0447 break; 0448 } 0449 case DNS: 0450 { 0451 const QByteArray buf = val.toLatin1(); 0452 0453 ASN1_IA5STRING *str = ASN1_IA5STRING_new(); 0454 ASN1_STRING_set((ASN1_STRING *)str, (const unsigned char *)buf.data(), buf.size()); 0455 0456 name = GENERAL_NAME_new(); 0457 name->type = GEN_DNS; 0458 name->d.dNSName = str; 0459 break; 0460 } 0461 case IPAddress: 0462 { 0463 const QByteArray buf = ipaddress_string_to_bytes(val); 0464 0465 ASN1_OCTET_STRING *str = ASN1_OCTET_STRING_new(); 0466 ASN1_STRING_set((ASN1_STRING *)str, (const unsigned char *)buf.data(), buf.size()); 0467 0468 name = GENERAL_NAME_new(); 0469 name->type = GEN_IPADD; 0470 name->d.iPAddress = str; 0471 break; 0472 } 0473 case XMPP: 0474 { 0475 const QByteArray buf = val.toUtf8(); 0476 0477 ASN1_UTF8STRING *str = ASN1_UTF8STRING_new(); 0478 ASN1_STRING_set((ASN1_STRING *)str, (const unsigned char *)buf.data(), buf.size()); 0479 0480 ASN1_TYPE *at = ASN1_TYPE_new(); 0481 at->type = V_ASN1_UTF8STRING; 0482 at->value.utf8string = str; 0483 0484 OTHERNAME *other = OTHERNAME_new(); 0485 other->type_id = OBJ_txt2obj("1.3.6.1.5.5.7.8.5", 1); // 1 = only accept dotted input 0486 other->value = at; 0487 0488 name = GENERAL_NAME_new(); 0489 name->type = GEN_OTHERNAME; 0490 name->d.otherName = other; 0491 break; 0492 } 0493 default: 0494 break; 0495 } 0496 return name; 0497 } 0498 0499 static void try_add_general_name(GENERAL_NAMES **gn, const CertificateInfoType &t, const QString &val) 0500 { 0501 if (val.isEmpty()) 0502 return; 0503 GENERAL_NAME *name = new_general_name(t, val); 0504 if (name) { 0505 if (!(*gn)) 0506 *gn = sk_GENERAL_NAME_new_null(); 0507 sk_GENERAL_NAME_push(*gn, name); 0508 } 0509 } 0510 0511 static X509_EXTENSION *new_cert_subject_alt_name(const CertificateInfo &info) 0512 { 0513 GENERAL_NAMES *gn = nullptr; 0514 // FIXME support multiple items of each type 0515 try_add_general_name(&gn, Email, info.value(Email)); 0516 try_add_general_name(&gn, URI, info.value(URI)); 0517 try_add_general_name(&gn, DNS, info.value(DNS)); 0518 try_add_general_name(&gn, IPAddress, info.value(IPAddress)); 0519 try_add_general_name(&gn, XMPP, info.value(XMPP)); 0520 if (!gn) 0521 return nullptr; 0522 0523 X509_EXTENSION *ex = X509V3_EXT_i2d(NID_subject_alt_name, 0, gn); 0524 sk_GENERAL_NAME_pop_free(gn, GENERAL_NAME_free); 0525 return ex; 0526 } 0527 0528 static GENERAL_NAME *find_next_general_name(GENERAL_NAMES *names, int type, int *pos) 0529 { 0530 int temp = *pos; 0531 GENERAL_NAME *gn = nullptr; 0532 *pos = -1; 0533 for (int n = temp; n < sk_GENERAL_NAME_num(names); ++n) { 0534 GENERAL_NAME *i = sk_GENERAL_NAME_value(names, n); 0535 if (i->type == type) { 0536 gn = i; 0537 *pos = n; 0538 break; 0539 } 0540 } 0541 return gn; 0542 } 0543 0544 static QByteArray qca_ASN1_STRING_toByteArray(ASN1_STRING *x) 0545 { 0546 return QByteArray(reinterpret_cast<const char *>(ASN1_STRING_get0_data(x)), ASN1_STRING_length(x)); 0547 } 0548 0549 static void try_get_general_name(GENERAL_NAMES *names, const CertificateInfoType &t, CertificateInfo *info) 0550 { 0551 switch (t.known()) { 0552 case Email: 0553 { 0554 int pos = 0; 0555 while (pos != -1) { 0556 GENERAL_NAME *gn = find_next_general_name(names, GEN_EMAIL, &pos); 0557 if (pos != -1) { 0558 const QByteArray cs = qca_ASN1_STRING_toByteArray(gn->d.rfc822Name); 0559 info->insert(t, QString::fromLatin1(cs)); 0560 ++pos; 0561 } 0562 } 0563 break; 0564 } 0565 case URI: 0566 { 0567 int pos = 0; 0568 while (pos != -1) { 0569 GENERAL_NAME *gn = find_next_general_name(names, GEN_URI, &pos); 0570 if (pos != -1) { 0571 const QByteArray cs = qca_ASN1_STRING_toByteArray(gn->d.uniformResourceIdentifier); 0572 info->insert(t, QString::fromLatin1(cs)); 0573 ++pos; 0574 } 0575 } 0576 break; 0577 } 0578 case DNS: 0579 { 0580 int pos = 0; 0581 while (pos != -1) { 0582 GENERAL_NAME *gn = find_next_general_name(names, GEN_DNS, &pos); 0583 if (pos != -1) { 0584 const QByteArray cs = qca_ASN1_STRING_toByteArray(gn->d.dNSName); 0585 info->insert(t, QString::fromLatin1(cs)); 0586 ++pos; 0587 } 0588 } 0589 break; 0590 } 0591 case IPAddress: 0592 { 0593 int pos = 0; 0594 while (pos != -1) { 0595 GENERAL_NAME *gn = find_next_general_name(names, GEN_IPADD, &pos); 0596 if (pos != -1) { 0597 ASN1_OCTET_STRING *str = gn->d.iPAddress; 0598 const QByteArray buf = qca_ASN1_STRING_toByteArray(str); 0599 0600 QString out; 0601 // IPv4 (TODO: handle IPv6) 0602 if (buf.size() == 4) { 0603 out = QStringLiteral("0.0.0.0"); 0604 } else 0605 break; 0606 info->insert(t, out); 0607 ++pos; 0608 } 0609 } 0610 break; 0611 } 0612 case XMPP: 0613 { 0614 int pos = 0; 0615 while (pos != -1) { 0616 GENERAL_NAME *gn = find_next_general_name(names, GEN_OTHERNAME, &pos); 0617 if (pos != -1) { 0618 OTHERNAME *other = gn->d.otherName; 0619 if (!other) 0620 break; 0621 0622 ASN1_OBJECT *obj = OBJ_txt2obj("1.3.6.1.5.5.7.8.5", 1); // 1 = only accept dotted input 0623 if (OBJ_cmp(other->type_id, obj) != 0) 0624 break; 0625 ASN1_OBJECT_free(obj); 0626 0627 ASN1_TYPE *at = other->value; 0628 if (at->type != V_ASN1_UTF8STRING) 0629 break; 0630 0631 ASN1_UTF8STRING *str = at->value.utf8string; 0632 const QByteArray buf = qca_ASN1_STRING_toByteArray(str); 0633 info->insert(t, QString::fromUtf8(buf)); 0634 ++pos; 0635 } 0636 } 0637 break; 0638 } 0639 default: 0640 break; 0641 } 0642 } 0643 0644 static CertificateInfo get_cert_alt_name(X509_EXTENSION *ex) 0645 { 0646 CertificateInfo info; 0647 GENERAL_NAMES *gn = (GENERAL_NAMES *)X509V3_EXT_d2i(ex); 0648 try_get_general_name(gn, Email, &info); 0649 try_get_general_name(gn, URI, &info); 0650 try_get_general_name(gn, DNS, &info); 0651 try_get_general_name(gn, IPAddress, &info); 0652 try_get_general_name(gn, XMPP, &info); 0653 GENERAL_NAMES_free(gn); 0654 return info; 0655 } 0656 0657 static X509_EXTENSION *new_cert_key_usage(const Constraints &constraints) 0658 { 0659 ASN1_BIT_STRING *keyusage = nullptr; 0660 for (int n = 0; n < constraints.count(); ++n) { 0661 int bit = -1; 0662 switch (constraints[n].known()) { 0663 case DigitalSignature: 0664 bit = Bit_DigitalSignature; 0665 break; 0666 case NonRepudiation: 0667 bit = Bit_NonRepudiation; 0668 break; 0669 case KeyEncipherment: 0670 bit = Bit_KeyEncipherment; 0671 break; 0672 case DataEncipherment: 0673 bit = Bit_DataEncipherment; 0674 break; 0675 case KeyAgreement: 0676 bit = Bit_KeyAgreement; 0677 break; 0678 case KeyCertificateSign: 0679 bit = Bit_KeyCertificateSign; 0680 break; 0681 case CRLSign: 0682 bit = Bit_CRLSign; 0683 break; 0684 case EncipherOnly: 0685 bit = Bit_EncipherOnly; 0686 break; 0687 case DecipherOnly: 0688 bit = Bit_DecipherOnly; 0689 break; 0690 default: 0691 break; 0692 } 0693 if (bit != -1) { 0694 if (!keyusage) 0695 keyusage = ASN1_BIT_STRING_new(); 0696 ASN1_BIT_STRING_set_bit(keyusage, bit, 1); 0697 } 0698 } 0699 if (!keyusage) 0700 return nullptr; 0701 0702 X509_EXTENSION *ex = X509V3_EXT_i2d(NID_key_usage, 1, keyusage); // 1 = critical 0703 ASN1_BIT_STRING_free(keyusage); 0704 return ex; 0705 } 0706 0707 static Constraints get_cert_key_usage(X509_EXTENSION *ex) 0708 { 0709 Constraints constraints; 0710 int bit_table[9] = {DigitalSignature, 0711 NonRepudiation, 0712 KeyEncipherment, 0713 DataEncipherment, 0714 KeyAgreement, 0715 KeyCertificateSign, 0716 CRLSign, 0717 EncipherOnly, 0718 DecipherOnly}; 0719 0720 ASN1_BIT_STRING *keyusage = (ASN1_BIT_STRING *)X509V3_EXT_d2i(ex); 0721 for (int n = 0; n < 9; ++n) { 0722 if (ASN1_BIT_STRING_get_bit(keyusage, n)) 0723 constraints += ConstraintType((ConstraintTypeKnown)bit_table[n]); 0724 } 0725 ASN1_BIT_STRING_free(keyusage); 0726 return constraints; 0727 } 0728 0729 static X509_EXTENSION *new_cert_ext_key_usage(const Constraints &constraints) 0730 { 0731 EXTENDED_KEY_USAGE *extkeyusage = nullptr; 0732 for (int n = 0; n < constraints.count(); ++n) { 0733 int nid = -1; 0734 // TODO: don't use known/nid, and instead just use OIDs 0735 switch (constraints[n].known()) { 0736 case ServerAuth: 0737 nid = NID_server_auth; 0738 break; 0739 case ClientAuth: 0740 nid = NID_client_auth; 0741 break; 0742 case CodeSigning: 0743 nid = NID_code_sign; 0744 break; 0745 case EmailProtection: 0746 nid = NID_email_protect; 0747 break; 0748 case IPSecEndSystem: 0749 nid = NID_ipsecEndSystem; 0750 break; 0751 case IPSecTunnel: 0752 nid = NID_ipsecTunnel; 0753 break; 0754 case IPSecUser: 0755 nid = NID_ipsecUser; 0756 break; 0757 case TimeStamping: 0758 nid = NID_time_stamp; 0759 break; 0760 case OCSPSigning: 0761 nid = NID_OCSP_sign; 0762 break; 0763 default: 0764 break; 0765 } 0766 if (nid != -1) { 0767 if (!extkeyusage) 0768 extkeyusage = sk_ASN1_OBJECT_new_null(); 0769 ASN1_OBJECT *obj = OBJ_nid2obj(nid); 0770 sk_ASN1_OBJECT_push(extkeyusage, obj); 0771 } 0772 } 0773 if (!extkeyusage) 0774 return nullptr; 0775 0776 X509_EXTENSION *ex = X509V3_EXT_i2d(NID_ext_key_usage, 0, extkeyusage); // 0 = not critical 0777 sk_ASN1_OBJECT_pop_free(extkeyusage, ASN1_OBJECT_free); 0778 return ex; 0779 } 0780 0781 static Constraints get_cert_ext_key_usage(X509_EXTENSION *ex) 0782 { 0783 Constraints constraints; 0784 0785 EXTENDED_KEY_USAGE *extkeyusage = (EXTENDED_KEY_USAGE *)X509V3_EXT_d2i(ex); 0786 for (int n = 0; n < sk_ASN1_OBJECT_num(extkeyusage); ++n) { 0787 ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(extkeyusage, n); 0788 int nid = OBJ_obj2nid(obj); 0789 if (nid == NID_undef) 0790 continue; 0791 0792 // TODO: don't use known/nid, and instead just use OIDs 0793 int t = -1; 0794 switch (nid) { 0795 case NID_server_auth: 0796 t = ServerAuth; 0797 break; 0798 case NID_client_auth: 0799 t = ClientAuth; 0800 break; 0801 case NID_code_sign: 0802 t = CodeSigning; 0803 break; 0804 case NID_email_protect: 0805 t = EmailProtection; 0806 break; 0807 case NID_ipsecEndSystem: 0808 t = IPSecEndSystem; 0809 break; 0810 case NID_ipsecTunnel: 0811 t = IPSecTunnel; 0812 break; 0813 case NID_ipsecUser: 0814 t = IPSecUser; 0815 break; 0816 case NID_time_stamp: 0817 t = TimeStamping; 0818 break; 0819 case NID_OCSP_sign: 0820 t = OCSPSigning; 0821 break; 0822 }; 0823 0824 if (t == -1) 0825 continue; 0826 0827 constraints.append(ConstraintType((ConstraintTypeKnown)t)); 0828 } 0829 sk_ASN1_OBJECT_pop_free(extkeyusage, ASN1_OBJECT_free); 0830 return constraints; 0831 } 0832 0833 static X509_EXTENSION *new_cert_policies(const QStringList &policies) 0834 { 0835 STACK_OF(POLICYINFO) *pols = nullptr; 0836 for (int n = 0; n < policies.count(); ++n) { 0837 const QByteArray cs = policies[n].toLatin1(); 0838 ASN1_OBJECT *obj = OBJ_txt2obj(cs.data(), 1); // 1 = only accept dotted input 0839 if (!obj) 0840 continue; 0841 if (!pols) 0842 pols = sk_POLICYINFO_new_null(); 0843 POLICYINFO *pol = POLICYINFO_new(); 0844 pol->policyid = obj; 0845 sk_POLICYINFO_push(pols, pol); 0846 } 0847 if (!pols) 0848 return nullptr; 0849 0850 X509_EXTENSION *ex = X509V3_EXT_i2d(NID_certificate_policies, 0, pols); // 0 = not critical 0851 sk_POLICYINFO_pop_free(pols, POLICYINFO_free); 0852 return ex; 0853 } 0854 0855 static QStringList get_cert_policies(X509_EXTENSION *ex) 0856 { 0857 QStringList out; 0858 STACK_OF(POLICYINFO) *pols = (STACK_OF(POLICYINFO) *)X509V3_EXT_d2i(ex); 0859 for (int n = 0; n < sk_POLICYINFO_num(pols); ++n) { 0860 POLICYINFO *pol = sk_POLICYINFO_value(pols, n); 0861 QByteArray buf(128, 0); 0862 const auto len = OBJ_obj2txt((char *)buf.data(), buf.size(), pol->policyid, 1); // 1 = only accept dotted input 0863 if (len > 0) 0864 out += QString::fromLatin1(buf.left(len)); 0865 } 0866 sk_POLICYINFO_pop_free(pols, POLICYINFO_free); 0867 return out; 0868 } 0869 0870 static QByteArray get_cert_subject_key_id(X509_EXTENSION *ex) 0871 { 0872 ASN1_OCTET_STRING *skid = (ASN1_OCTET_STRING *)X509V3_EXT_d2i(ex); 0873 const QByteArray out = qca_ASN1_STRING_toByteArray(skid); 0874 ASN1_OCTET_STRING_free(skid); 0875 return out; 0876 } 0877 0878 // If you get any more crashes in this code, please provide a copy 0879 // of the cert to bradh AT frogmouth.net 0880 static QByteArray get_cert_issuer_key_id(X509_EXTENSION *ex) 0881 { 0882 AUTHORITY_KEYID *akid = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ex); 0883 QByteArray out; 0884 if (akid->keyid) 0885 out = qca_ASN1_STRING_toByteArray(akid->keyid); 0886 AUTHORITY_KEYID_free(akid); 0887 return out; 0888 } 0889 0890 static Validity convert_verify_error(int err) 0891 { 0892 // TODO: ErrorExpiredCA 0893 Validity rc; 0894 switch (err) { 0895 case X509_V_ERR_CERT_REJECTED: 0896 rc = ErrorRejected; 0897 break; 0898 case X509_V_ERR_CERT_UNTRUSTED: 0899 rc = ErrorUntrusted; 0900 break; 0901 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: 0902 case X509_V_ERR_CERT_SIGNATURE_FAILURE: 0903 case X509_V_ERR_CRL_SIGNATURE_FAILURE: 0904 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: 0905 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: 0906 rc = ErrorSignatureFailed; 0907 break; 0908 case X509_V_ERR_INVALID_CA: 0909 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 0910 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: 0911 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 0912 rc = ErrorInvalidCA; 0913 break; 0914 case X509_V_ERR_INVALID_PURPOSE: // note: not used by store verify 0915 rc = ErrorInvalidPurpose; 0916 break; 0917 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 0918 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 0919 rc = ErrorSelfSigned; 0920 break; 0921 case X509_V_ERR_CERT_REVOKED: 0922 rc = ErrorRevoked; 0923 break; 0924 case X509_V_ERR_PATH_LENGTH_EXCEEDED: 0925 rc = ErrorPathLengthExceeded; 0926 break; 0927 case X509_V_ERR_CERT_NOT_YET_VALID: 0928 case X509_V_ERR_CERT_HAS_EXPIRED: 0929 case X509_V_ERR_CRL_NOT_YET_VALID: 0930 case X509_V_ERR_CRL_HAS_EXPIRED: 0931 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 0932 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 0933 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: 0934 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: 0935 rc = ErrorExpired; 0936 break; 0937 case X509_V_ERR_APPLICATION_VERIFICATION: 0938 case X509_V_ERR_OUT_OF_MEM: 0939 case X509_V_ERR_UNABLE_TO_GET_CRL: 0940 case X509_V_ERR_CERT_CHAIN_TOO_LONG: 0941 default: 0942 rc = ErrorValidityUnknown; 0943 break; 0944 } 0945 return rc; 0946 } 0947 0948 EVP_PKEY *qca_d2i_PKCS8PrivateKey(const SecureArray &in, EVP_PKEY **x, pem_password_cb *cb, void *u) 0949 { 0950 PKCS8_PRIV_KEY_INFO *p8inf; 0951 0952 // first try unencrypted form 0953 BIO *bi = BIO_new(BIO_s_mem()); 0954 BIO_write(bi, in.data(), in.size()); 0955 p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(bi, nullptr); 0956 BIO_free(bi); 0957 if (!p8inf) { 0958 X509_SIG *p8; 0959 0960 // now try encrypted form 0961 bi = BIO_new(BIO_s_mem()); 0962 BIO_write(bi, in.data(), in.size()); 0963 p8 = d2i_PKCS8_bio(bi, nullptr); 0964 BIO_free(bi); 0965 if (!p8) 0966 return nullptr; 0967 0968 // get passphrase 0969 char psbuf[PEM_BUFSIZE]; 0970 int klen; 0971 if (cb) 0972 klen = cb(psbuf, PEM_BUFSIZE, 0, u); 0973 else 0974 klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); 0975 if (klen <= 0) { 0976 PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); 0977 X509_SIG_free(p8); 0978 return nullptr; 0979 } 0980 0981 // decrypt it 0982 p8inf = PKCS8_decrypt(p8, psbuf, klen); 0983 X509_SIG_free(p8); 0984 if (!p8inf) 0985 return nullptr; 0986 } 0987 0988 EVP_PKEY *ret = EVP_PKCS82PKEY(p8inf); 0989 PKCS8_PRIV_KEY_INFO_free(p8inf); 0990 if (!ret) 0991 return nullptr; 0992 if (x) { 0993 if (*x) 0994 EVP_PKEY_free(*x); 0995 *x = ret; 0996 } 0997 return ret; 0998 } 0999 1000 class opensslHashContext : public HashContext 1001 { 1002 Q_OBJECT 1003 public: 1004 opensslHashContext(const EVP_MD *algorithm, Provider *p, const QString &type) 1005 : HashContext(p, type) 1006 { 1007 m_algorithm = algorithm; 1008 m_context = EVP_MD_CTX_new(); 1009 EVP_DigestInit(m_context, m_algorithm); 1010 } 1011 1012 opensslHashContext(const opensslHashContext &other) 1013 : HashContext(other) 1014 { 1015 m_algorithm = other.m_algorithm; 1016 m_context = EVP_MD_CTX_new(); 1017 EVP_MD_CTX_copy_ex(m_context, other.m_context); 1018 } 1019 1020 ~opensslHashContext() override 1021 { 1022 EVP_MD_CTX_free(m_context); 1023 } 1024 1025 void clear() override 1026 { 1027 EVP_MD_CTX_free(m_context); 1028 m_context = EVP_MD_CTX_new(); 1029 EVP_DigestInit(m_context, m_algorithm); 1030 } 1031 1032 void update(const MemoryRegion &a) override 1033 { 1034 EVP_DigestUpdate(m_context, (unsigned char *)a.data(), a.size()); 1035 } 1036 1037 MemoryRegion final() override 1038 { 1039 SecureArray a(EVP_MD_size(m_algorithm)); 1040 EVP_DigestFinal(m_context, (unsigned char *)a.data(), nullptr); 1041 return a; 1042 } 1043 1044 Provider::Context *clone() const override 1045 { 1046 return new opensslHashContext(*this); 1047 } 1048 1049 protected: 1050 const EVP_MD *m_algorithm; 1051 EVP_MD_CTX *m_context; 1052 }; 1053 1054 class opensslPbkdf1Context : public KDFContext 1055 { 1056 Q_OBJECT 1057 public: 1058 opensslPbkdf1Context(const EVP_MD *algorithm, Provider *p, const QString &type) 1059 : KDFContext(p, type) 1060 { 1061 Q_ASSERT(s_legacyProviderAvailable); 1062 m_algorithm = algorithm; 1063 m_context = EVP_MD_CTX_new(); 1064 EVP_DigestInit(m_context, m_algorithm); 1065 } 1066 1067 opensslPbkdf1Context(const opensslPbkdf1Context &other) 1068 : KDFContext(other) 1069 { 1070 m_algorithm = other.m_algorithm; 1071 m_context = EVP_MD_CTX_new(); 1072 EVP_MD_CTX_copy(m_context, other.m_context); 1073 } 1074 1075 ~opensslPbkdf1Context() override 1076 { 1077 EVP_MD_CTX_free(m_context); 1078 } 1079 1080 Provider::Context *clone() const override 1081 { 1082 return new opensslPbkdf1Context(*this); 1083 } 1084 1085 SymmetricKey makeKey(const SecureArray &secret, 1086 const InitializationVector &salt, 1087 unsigned int keyLength, 1088 unsigned int iterationCount) override 1089 { 1090 /* from RFC2898: 1091 Steps: 1092 1093 1. If dkLen > 16 for MD2 and MD5, or dkLen > 20 for SHA-1, output 1094 "derived key too long" and stop. 1095 */ 1096 if (keyLength > (unsigned int)EVP_MD_size(m_algorithm)) { 1097 std::cout << "derived key too long" << std::endl; 1098 return SymmetricKey(); 1099 } 1100 1101 /* 1102 2. Apply the underlying hash function Hash for c iterations to the 1103 concatenation of the password P and the salt S, then extract 1104 the first dkLen octets to produce a derived key DK: 1105 1106 T_1 = Hash (P || S) , 1107 T_2 = Hash (T_1) , 1108 ... 1109 T_c = Hash (T_{c-1}) , 1110 DK = Tc<0..dkLen-1> 1111 */ 1112 // calculate T_1 1113 EVP_DigestUpdate(m_context, (unsigned char *)secret.data(), secret.size()); 1114 EVP_DigestUpdate(m_context, (unsigned char *)salt.data(), salt.size()); 1115 SecureArray a(EVP_MD_size(m_algorithm)); 1116 EVP_DigestFinal(m_context, (unsigned char *)a.data(), nullptr); 1117 1118 // calculate T_2 up to T_c 1119 for (unsigned int i = 2; i <= iterationCount; ++i) { 1120 EVP_DigestInit(m_context, m_algorithm); 1121 EVP_DigestUpdate(m_context, (unsigned char *)a.data(), a.size()); 1122 EVP_DigestFinal(m_context, (unsigned char *)a.data(), nullptr); 1123 } 1124 1125 // shrink a to become DK, of the required length 1126 a.resize(keyLength); 1127 1128 /* 1129 3. Output the derived key DK. 1130 */ 1131 return a; 1132 } 1133 1134 SymmetricKey makeKey(const SecureArray &secret, 1135 const InitializationVector &salt, 1136 unsigned int keyLength, 1137 int msecInterval, 1138 unsigned int *iterationCount) override 1139 { 1140 Q_ASSERT(iterationCount != nullptr); 1141 QElapsedTimer timer; 1142 1143 /* from RFC2898: 1144 Steps: 1145 1146 1. If dkLen > 16 for MD2 and MD5, or dkLen > 20 for SHA-1, output 1147 "derived key too long" and stop. 1148 */ 1149 if (keyLength > (unsigned int)EVP_MD_size(m_algorithm)) { 1150 std::cout << "derived key too long" << std::endl; 1151 return SymmetricKey(); 1152 } 1153 1154 /* 1155 2. Apply the underlying hash function Hash for M milliseconds 1156 to the concatenation of the password P and the salt S, incrementing c, 1157 then extract the first dkLen octets to produce a derived key DK: 1158 1159 time from M to 0 1160 T_1 = Hash (P || S) , 1161 T_2 = Hash (T_1) , 1162 ... 1163 T_c = Hash (T_{c-1}) , 1164 when time = 0: stop, 1165 DK = Tc<0..dkLen-1> 1166 */ 1167 // calculate T_1 1168 EVP_DigestUpdate(m_context, (unsigned char *)secret.data(), secret.size()); 1169 EVP_DigestUpdate(m_context, (unsigned char *)salt.data(), salt.size()); 1170 SecureArray a(EVP_MD_size(m_algorithm)); 1171 EVP_DigestFinal(m_context, (unsigned char *)a.data(), nullptr); 1172 1173 // calculate T_2 up to T_c 1174 *iterationCount = 2 - 1; // <- Have to remove 1, unless it computes one 1175 timer.start(); // ^ time more than the base function 1176 // ^ with the same iterationCount 1177 while (timer.elapsed() < msecInterval) { 1178 EVP_DigestInit(m_context, m_algorithm); 1179 EVP_DigestUpdate(m_context, (unsigned char *)a.data(), a.size()); 1180 EVP_DigestFinal(m_context, (unsigned char *)a.data(), nullptr); 1181 ++(*iterationCount); 1182 } 1183 1184 // shrink a to become DK, of the required length 1185 a.resize(keyLength); 1186 1187 /* 1188 3. Output the derived key DK. 1189 */ 1190 return a; 1191 } 1192 1193 protected: 1194 const EVP_MD *m_algorithm; 1195 EVP_MD_CTX *m_context; 1196 }; 1197 1198 class opensslPbkdf2Context : public KDFContext 1199 { 1200 Q_OBJECT 1201 public: 1202 opensslPbkdf2Context(Provider *p, const QString &type) 1203 : KDFContext(p, type) 1204 { 1205 } 1206 1207 Provider::Context *clone() const override 1208 { 1209 return new opensslPbkdf2Context(*this); 1210 } 1211 1212 SymmetricKey makeKey(const SecureArray &secret, 1213 const InitializationVector &salt, 1214 unsigned int keyLength, 1215 unsigned int iterationCount) override 1216 { 1217 SecureArray out(keyLength); 1218 PKCS5_PBKDF2_HMAC_SHA1((char *)secret.data(), 1219 secret.size(), 1220 (unsigned char *)salt.data(), 1221 salt.size(), 1222 iterationCount, 1223 keyLength, 1224 (unsigned char *)out.data()); 1225 return out; 1226 } 1227 1228 SymmetricKey makeKey(const SecureArray &secret, 1229 const InitializationVector &salt, 1230 unsigned int keyLength, 1231 int msecInterval, 1232 unsigned int *iterationCount) override 1233 { 1234 Q_ASSERT(iterationCount != nullptr); 1235 QElapsedTimer timer; 1236 SecureArray out(keyLength); 1237 1238 *iterationCount = 0; 1239 timer.start(); 1240 1241 // PBKDF2 needs an iterationCount itself, unless PBKDF1. 1242 // So we need to calculate first the number of iterations for 1243 // That time interval, then feed the iterationCounts to PBKDF2 1244 while (timer.elapsed() < msecInterval) { 1245 PKCS5_PBKDF2_HMAC_SHA1((char *)secret.data(), 1246 secret.size(), 1247 (unsigned char *)salt.data(), 1248 salt.size(), 1249 1, 1250 keyLength, 1251 (unsigned char *)out.data()); 1252 ++(*iterationCount); 1253 } 1254 1255 // Now we can directely call makeKey base function, 1256 // as we now have the iterationCount 1257 out = makeKey(secret, salt, keyLength, *iterationCount); 1258 1259 return out; 1260 } 1261 1262 protected: 1263 }; 1264 1265 class opensslHkdfContext : public HKDFContext 1266 { 1267 Q_OBJECT 1268 public: 1269 opensslHkdfContext(Provider *p, const QString &type) 1270 : HKDFContext(p, type) 1271 { 1272 } 1273 1274 Provider::Context *clone() const override 1275 { 1276 return new opensslHkdfContext(*this); 1277 } 1278 1279 SymmetricKey makeKey(const SecureArray &secret, 1280 const InitializationVector &salt, 1281 const InitializationVector &info, 1282 unsigned int keyLength) override 1283 { 1284 SecureArray out(keyLength); 1285 EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr); 1286 EVP_PKEY_derive_init(pctx); 1287 EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()); 1288 EVP_PKEY_CTX_set1_hkdf_salt(pctx, (const unsigned char *)salt.data(), int(salt.size())); 1289 EVP_PKEY_CTX_set1_hkdf_key(pctx, (const unsigned char *)secret.data(), int(secret.size())); 1290 EVP_PKEY_CTX_add1_hkdf_info(pctx, (const unsigned char *)info.data(), int(info.size())); 1291 size_t outlen = out.size(); 1292 EVP_PKEY_derive(pctx, reinterpret_cast<unsigned char *>(out.data()), &outlen); 1293 EVP_PKEY_CTX_free(pctx); 1294 return out; 1295 } 1296 }; 1297 1298 class opensslHMACContext : public MACContext 1299 { 1300 Q_OBJECT 1301 public: 1302 opensslHMACContext(const EVP_MD *algorithm, Provider *p, const QString &type) 1303 : MACContext(p, type) 1304 { 1305 m_algorithm = algorithm; 1306 m_context = HMAC_CTX_new(); 1307 } 1308 1309 opensslHMACContext(const opensslHMACContext &other) 1310 : MACContext(other) 1311 { 1312 m_algorithm = other.m_algorithm; 1313 m_context = HMAC_CTX_new(); 1314 HMAC_CTX_copy(m_context, other.m_context); 1315 } 1316 1317 ~opensslHMACContext() override 1318 { 1319 HMAC_CTX_free(m_context); 1320 } 1321 1322 void setup(const SymmetricKey &key) override 1323 { 1324 HMAC_Init_ex(m_context, key.data(), key.size(), m_algorithm, nullptr); 1325 } 1326 1327 KeyLength keyLength() const override 1328 { 1329 return anyKeyLength(); 1330 } 1331 1332 void update(const MemoryRegion &a) override 1333 { 1334 HMAC_Update(m_context, (unsigned char *)a.data(), a.size()); 1335 } 1336 1337 void final(MemoryRegion *out) override 1338 { 1339 SecureArray sa(EVP_MD_size(m_algorithm), 0); 1340 HMAC_Final(m_context, (unsigned char *)sa.data(), nullptr); 1341 HMAC_CTX_reset(m_context); 1342 *out = sa; 1343 } 1344 1345 Provider::Context *clone() const override 1346 { 1347 return new opensslHMACContext(*this); 1348 } 1349 1350 protected: 1351 HMAC_CTX *m_context; 1352 const EVP_MD *m_algorithm; 1353 }; 1354 1355 //---------------------------------------------------------------------------- 1356 // EVPKey 1357 //---------------------------------------------------------------------------- 1358 1359 // note: this class squelches processing errors, since QCA doesn't care about them 1360 class EVPKey 1361 { 1362 public: 1363 enum State 1364 { 1365 Idle, 1366 SignActive, 1367 SignError, 1368 VerifyActive, 1369 VerifyError 1370 }; 1371 EVP_PKEY *pkey; 1372 EVP_MD_CTX *mdctx; 1373 State state; 1374 bool raw_type; 1375 SecureArray raw; 1376 1377 EVPKey() 1378 { 1379 pkey = nullptr; 1380 raw_type = false; 1381 state = Idle; 1382 mdctx = EVP_MD_CTX_new(); 1383 } 1384 1385 EVPKey(const EVPKey &from) 1386 { 1387 pkey = from.pkey; 1388 EVP_PKEY_up_ref(pkey); 1389 raw_type = false; 1390 state = Idle; 1391 mdctx = EVP_MD_CTX_new(); 1392 EVP_MD_CTX_copy(mdctx, from.mdctx); 1393 } 1394 1395 EVPKey &operator=(const EVPKey &from) = delete; 1396 1397 ~EVPKey() 1398 { 1399 reset(); 1400 EVP_MD_CTX_free(mdctx); 1401 } 1402 1403 void reset() 1404 { 1405 if (pkey) 1406 EVP_PKEY_free(pkey); 1407 pkey = nullptr; 1408 raw.clear(); 1409 raw_type = false; 1410 } 1411 1412 void startSign(const EVP_MD *type) 1413 { 1414 state = SignActive; 1415 if (!type) { 1416 raw_type = true; 1417 raw.clear(); 1418 } else { 1419 raw_type = false; 1420 EVP_MD_CTX_init(mdctx); 1421 if (!EVP_SignInit_ex(mdctx, type, nullptr)) 1422 state = SignError; 1423 } 1424 } 1425 1426 void startVerify(const EVP_MD *type) 1427 { 1428 state = VerifyActive; 1429 if (!type) { 1430 raw_type = true; 1431 raw.clear(); 1432 } else { 1433 raw_type = false; 1434 EVP_MD_CTX_init(mdctx); 1435 if (!EVP_VerifyInit_ex(mdctx, type, nullptr)) 1436 state = VerifyError; 1437 } 1438 } 1439 1440 void update(const MemoryRegion &in) 1441 { 1442 if (state == SignActive) { 1443 if (raw_type) 1444 raw += in; 1445 else if (!EVP_SignUpdate(mdctx, in.data(), (unsigned int)in.size())) 1446 state = SignError; 1447 } else if (state == VerifyActive) { 1448 if (raw_type) 1449 raw += in; 1450 else if (!EVP_VerifyUpdate(mdctx, in.data(), (unsigned int)in.size())) 1451 state = VerifyError; 1452 } 1453 } 1454 1455 SecureArray endSign() 1456 { 1457 if (state == SignActive) { 1458 SecureArray out(EVP_PKEY_size(pkey)); 1459 unsigned int len = out.size(); 1460 if (raw_type) { 1461 int type = EVP_PKEY_id(pkey); 1462 1463 if (type == EVP_PKEY_RSA) { 1464 const RSA *rsa = EVP_PKEY_get0_RSA(pkey); 1465 if (RSA_private_encrypt(raw.size(), 1466 (unsigned char *)raw.data(), 1467 (unsigned char *)out.data(), 1468 (RSA *)rsa, 1469 RSA_PKCS1_PADDING) == -1) { 1470 state = SignError; 1471 return SecureArray(); 1472 } 1473 } else if (type == EVP_PKEY_DSA) { 1474 state = SignError; 1475 return SecureArray(); 1476 } else { 1477 state = SignError; 1478 return SecureArray(); 1479 } 1480 } else { 1481 if (!EVP_SignFinal(mdctx, (unsigned char *)out.data(), &len, pkey)) { 1482 state = SignError; 1483 return SecureArray(); 1484 } 1485 } 1486 out.resize(len); 1487 state = Idle; 1488 return out; 1489 } else 1490 return SecureArray(); 1491 } 1492 1493 bool endVerify(const SecureArray &sig) 1494 { 1495 if (state == VerifyActive) { 1496 if (raw_type) { 1497 SecureArray out(EVP_PKEY_size(pkey)); 1498 int len = 0; 1499 1500 int type = EVP_PKEY_id(pkey); 1501 1502 if (type == EVP_PKEY_RSA) { 1503 const RSA *rsa = EVP_PKEY_get0_RSA(pkey); 1504 if ((len = RSA_public_decrypt(sig.size(), 1505 (unsigned char *)sig.data(), 1506 (unsigned char *)out.data(), 1507 (RSA *)rsa, 1508 RSA_PKCS1_PADDING)) == -1) { 1509 state = VerifyError; 1510 return false; 1511 } 1512 } else if (type == EVP_PKEY_DSA) { 1513 state = VerifyError; 1514 return false; 1515 } else { 1516 state = VerifyError; 1517 return false; 1518 } 1519 1520 out.resize(len); 1521 1522 if (out != raw) { 1523 state = VerifyError; 1524 return false; 1525 } 1526 } else { 1527 if (EVP_VerifyFinal(mdctx, (unsigned char *)sig.data(), (unsigned int)sig.size(), pkey) != 1) { 1528 state = VerifyError; 1529 return false; 1530 } 1531 } 1532 state = Idle; 1533 return true; 1534 } else 1535 return false; 1536 } 1537 }; 1538 1539 //---------------------------------------------------------------------------- 1540 // MyDLGroup 1541 //---------------------------------------------------------------------------- 1542 1543 // IETF primes from Botan 1544 static const char *IETF_1024_PRIME = 1545 "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" 1546 "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" 1547 "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" 1548 "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" 1549 "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381" 1550 "FFFFFFFF FFFFFFFF"; 1551 1552 static const char *IETF_2048_PRIME = 1553 "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" 1554 "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" 1555 "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" 1556 "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" 1557 "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" 1558 "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" 1559 "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" 1560 "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" 1561 "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" 1562 "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" 1563 "15728E5A 8AACAA68 FFFFFFFF FFFFFFFF"; 1564 1565 static const char *IETF_4096_PRIME = 1566 "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" 1567 "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" 1568 "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" 1569 "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" 1570 "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" 1571 "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" 1572 "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" 1573 "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" 1574 "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" 1575 "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" 1576 "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" 1577 "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" 1578 "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" 1579 "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" 1580 "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" 1581 "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" 1582 "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" 1583 "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" 1584 "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" 1585 "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" 1586 "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" 1587 "FFFFFFFF FFFFFFFF"; 1588 1589 #ifndef OPENSSL_FIPS 1590 // JCE seeds from Botan 1591 static const char *JCE_512_SEED = "B869C82B 35D70E1B 1FF91B28 E37A62EC DC34409B"; 1592 static const int JCE_512_COUNTER = 123; 1593 1594 static const char *JCE_768_SEED = "77D0F8C4 DAD15EB8 C4F2F8D6 726CEFD9 6D5BB399"; 1595 static const int JCE_768_COUNTER = 263; 1596 1597 static const char *JCE_1024_SEED = "8D515589 4229D5E6 89EE01E6 018A237E 2CAE64CD"; 1598 static const int JCE_1024_COUNTER = 92; 1599 #endif 1600 1601 static QByteArray dehex(const QByteArray &hex) 1602 { 1603 QString str; 1604 for (const char c : hex) { 1605 if (c != ' ') 1606 str += QLatin1Char(c); 1607 } 1608 return hexToArray(str); 1609 } 1610 1611 static BigInteger decode(const QByteArray &prime) 1612 { 1613 QByteArray a(1, 0); // 1 byte of zero padding 1614 a.append(dehex(prime)); 1615 return BigInteger(SecureArray(a)); 1616 } 1617 1618 #ifndef OPENSSL_FIPS 1619 static QByteArray decode_seed(const QByteArray &hex_seed) 1620 { 1621 return dehex(hex_seed); 1622 } 1623 #endif 1624 1625 class DLParams 1626 { 1627 public: 1628 BigInteger p, q, g; 1629 }; 1630 1631 #ifndef OPENSSL_FIPS 1632 1633 static bool make_dlgroup(const QByteArray &seed, int bits, int counter, DLParams *params) 1634 { 1635 int ret_counter; 1636 std::unique_ptr<DSA, DsaDeleter> dsa(DSA_new()); 1637 if (!dsa) 1638 return false; 1639 1640 if (DSA_generate_parameters_ex( 1641 dsa.get(), bits, (const unsigned char *)seed.data(), seed.size(), &ret_counter, nullptr, nullptr) != 1) 1642 return false; 1643 1644 if (ret_counter != counter) 1645 return false; 1646 1647 const BIGNUM *bnp, *bnq, *bng; 1648 DSA_get0_pqg(dsa.get(), &bnp, &bnq, &bng); 1649 params->p = bn2bi(bnp); 1650 params->q = bn2bi(bnq); 1651 params->g = bn2bi(bng); 1652 1653 return true; 1654 } 1655 #endif 1656 1657 static bool get_dlgroup(const BigInteger &p, const BigInteger &g, DLParams *params) 1658 { 1659 params->p = p; 1660 params->q = BigInteger(0); 1661 params->g = g; 1662 return true; 1663 } 1664 1665 class DLGroupMaker : public QThread 1666 { 1667 Q_OBJECT 1668 public: 1669 DLGroupSet set; 1670 bool ok; 1671 DLParams params; 1672 1673 DLGroupMaker(DLGroupSet _set) 1674 { 1675 set = _set; 1676 } 1677 1678 ~DLGroupMaker() override 1679 { 1680 wait(); 1681 } 1682 1683 void run() override 1684 { 1685 switch (set) { 1686 #ifndef OPENSSL_FIPS 1687 case DSA_512: 1688 ok = make_dlgroup(decode_seed(JCE_512_SEED), 512, JCE_512_COUNTER, ¶ms); 1689 break; 1690 1691 case DSA_768: 1692 ok = make_dlgroup(decode_seed(JCE_768_SEED), 768, JCE_768_COUNTER, ¶ms); 1693 break; 1694 1695 case DSA_1024: 1696 ok = make_dlgroup(decode_seed(JCE_1024_SEED), 1024, JCE_1024_COUNTER, ¶ms); 1697 break; 1698 #endif 1699 1700 case IETF_1024: 1701 ok = get_dlgroup(decode(IETF_1024_PRIME), 2, ¶ms); 1702 break; 1703 1704 case IETF_2048: 1705 ok = get_dlgroup(decode(IETF_2048_PRIME), 2, ¶ms); 1706 break; 1707 1708 case IETF_4096: 1709 ok = get_dlgroup(decode(IETF_4096_PRIME), 2, ¶ms); 1710 break; 1711 1712 default: 1713 ok = false; 1714 break; 1715 } 1716 } 1717 }; 1718 1719 class MyDLGroup : public DLGroupContext 1720 { 1721 Q_OBJECT 1722 public: 1723 DLGroupMaker *gm; 1724 bool wasBlocking; 1725 DLParams params; 1726 bool empty; 1727 1728 MyDLGroup(Provider *p) 1729 : DLGroupContext(p) 1730 { 1731 gm = nullptr; 1732 empty = true; 1733 } 1734 1735 MyDLGroup(const MyDLGroup &from) 1736 : DLGroupContext(from.provider()) 1737 { 1738 gm = nullptr; 1739 empty = true; 1740 } 1741 1742 ~MyDLGroup() override 1743 { 1744 delete gm; 1745 } 1746 1747 Provider::Context *clone() const override 1748 { 1749 return new MyDLGroup(*this); 1750 } 1751 1752 QList<DLGroupSet> supportedGroupSets() const override 1753 { 1754 QList<DLGroupSet> list; 1755 1756 // DSA_* was removed in FIPS specification 1757 // https://bugzilla.redhat.com/show_bug.cgi?id=1144655 1758 #ifndef OPENSSL_FIPS 1759 list += DSA_512; 1760 list += DSA_768; 1761 list += DSA_1024; 1762 #endif 1763 list += IETF_1024; 1764 list += IETF_2048; 1765 list += IETF_4096; 1766 return list; 1767 } 1768 1769 bool isNull() const override 1770 { 1771 return empty; 1772 } 1773 1774 void fetchGroup(DLGroupSet set, bool block) override 1775 { 1776 params = DLParams(); 1777 empty = true; 1778 1779 gm = new DLGroupMaker(set); 1780 wasBlocking = block; 1781 if (block) { 1782 gm->run(); 1783 gm_finished(); 1784 } else { 1785 connect(gm, &DLGroupMaker::finished, this, &MyDLGroup::gm_finished); 1786 gm->start(); 1787 } 1788 } 1789 1790 void getResult(BigInteger *p, BigInteger *q, BigInteger *g) const override 1791 { 1792 *p = params.p; 1793 *q = params.q; 1794 *g = params.g; 1795 } 1796 1797 private Q_SLOTS: 1798 void gm_finished() 1799 { 1800 bool ok = gm->ok; 1801 if (ok) { 1802 params = gm->params; 1803 empty = false; 1804 } 1805 1806 if (wasBlocking) 1807 delete gm; 1808 else 1809 gm->deleteLater(); 1810 gm = nullptr; 1811 1812 if (!wasBlocking) 1813 emit finished(); 1814 } 1815 }; 1816 1817 //---------------------------------------------------------------------------- 1818 // RSAKey 1819 //---------------------------------------------------------------------------- 1820 namespace { 1821 static const auto RsaDeleter = [](RSA *pointer) { 1822 if (pointer) 1823 RSA_free((RSA *)pointer); 1824 }; 1825 1826 static const auto BnDeleter = [](BIGNUM *pointer) { 1827 if (pointer) 1828 BN_free((BIGNUM *)pointer); 1829 }; 1830 } // end of anonymous namespace 1831 1832 class RSAKeyMaker : public QThread 1833 { 1834 Q_OBJECT 1835 public: 1836 RSA *result; 1837 int bits, exp; 1838 1839 RSAKeyMaker(int _bits, int _exp, QObject *parent = nullptr) 1840 : QThread(parent) 1841 , result(nullptr) 1842 , bits(_bits) 1843 , exp(_exp) 1844 { 1845 } 1846 1847 ~RSAKeyMaker() override 1848 { 1849 wait(); 1850 if (result) 1851 RSA_free(result); 1852 } 1853 1854 void run() override 1855 { 1856 std::unique_ptr<RSA, decltype(RsaDeleter)> rsa(RSA_new(), RsaDeleter); 1857 if (!rsa) 1858 return; 1859 1860 std::unique_ptr<BIGNUM, decltype(BnDeleter)> e(BN_new(), BnDeleter); 1861 if (!e) 1862 return; 1863 1864 BN_clear(e.get()); 1865 if (BN_set_word(e.get(), exp) != 1) 1866 return; 1867 1868 if (RSA_generate_key_ex(rsa.get(), bits, e.get(), nullptr) == 0) { 1869 return; 1870 } 1871 1872 result = rsa.release(); 1873 } 1874 1875 RSA *takeResult() 1876 { 1877 RSA *rsa = result; 1878 result = nullptr; 1879 return rsa; 1880 } 1881 }; 1882 1883 class RSAKey : public RSAContext 1884 { 1885 Q_OBJECT 1886 public: 1887 EVPKey evp; 1888 RSAKeyMaker *keymaker; 1889 bool wasBlocking; 1890 bool sec; 1891 1892 RSAKey(Provider *p) 1893 : RSAContext(p) 1894 { 1895 keymaker = nullptr; 1896 sec = false; 1897 } 1898 1899 RSAKey(const RSAKey &from) 1900 : RSAContext(from.provider()) 1901 , evp(from.evp) 1902 { 1903 keymaker = nullptr; 1904 sec = from.sec; 1905 } 1906 1907 ~RSAKey() override 1908 { 1909 delete keymaker; 1910 } 1911 1912 Provider::Context *clone() const override 1913 { 1914 return new RSAKey(*this); 1915 } 1916 1917 bool isNull() const override 1918 { 1919 return (evp.pkey ? false : true); 1920 } 1921 1922 PKey::Type type() const override 1923 { 1924 return PKey::RSA; 1925 } 1926 1927 bool isPrivate() const override 1928 { 1929 return sec; 1930 } 1931 1932 bool canExport() const override 1933 { 1934 return true; 1935 } 1936 1937 void convertToPublic() override 1938 { 1939 if (!sec) 1940 return; 1941 1942 // extract the public key into DER format 1943 const RSA *rsa_pkey = EVP_PKEY_get0_RSA(evp.pkey); 1944 int len = i2d_RSAPublicKey(rsa_pkey, nullptr); 1945 SecureArray result(len); 1946 unsigned char *p = (unsigned char *)result.data(); 1947 i2d_RSAPublicKey(rsa_pkey, &p); 1948 p = (unsigned char *)result.data(); 1949 1950 // put the DER public key back into openssl 1951 evp.reset(); 1952 RSA *rsa = d2i_RSAPublicKey(nullptr, (const unsigned char **)&p, result.size()); 1953 evp.pkey = EVP_PKEY_new(); 1954 EVP_PKEY_assign_RSA(evp.pkey, rsa); 1955 sec = false; 1956 } 1957 1958 int bits() const override 1959 { 1960 return EVP_PKEY_bits(evp.pkey); 1961 } 1962 1963 int maximumEncryptSize(EncryptionAlgorithm alg) const override 1964 { 1965 const RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); 1966 int size = 0; 1967 switch (alg) { 1968 case EME_PKCS1v15: 1969 size = RSA_size(rsa) - 11 - 1; 1970 break; 1971 case EME_PKCS1_OAEP: 1972 size = RSA_size(rsa) - 41 - 1; 1973 break; 1974 case EME_PKCS1v15_SSL: 1975 size = RSA_size(rsa) - 11 - 1; 1976 break; 1977 case EME_NO_PADDING: 1978 size = RSA_size(rsa) - 1; 1979 break; 1980 } 1981 1982 return size; 1983 } 1984 1985 SecureArray encrypt(const SecureArray &in, EncryptionAlgorithm alg) override 1986 { 1987 const RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); 1988 SecureArray buf = in; 1989 int max = maximumEncryptSize(alg); 1990 1991 if (buf.size() > max) 1992 buf.resize(max); 1993 SecureArray result(RSA_size(rsa)); 1994 1995 int pad; 1996 switch (alg) { 1997 case EME_PKCS1v15: 1998 pad = RSA_PKCS1_PADDING; 1999 break; 2000 case EME_PKCS1_OAEP: 2001 pad = RSA_PKCS1_OAEP_PADDING; 2002 break; 2003 // OPENSSL_VERSION_MAJOR is only defined on openssl > 3.0 2004 // that doesn't have RSA_SSLV23_PADDING so we can use it negatively here 2005 #ifndef OPENSSL_VERSION_MAJOR 2006 case EME_PKCS1v15_SSL: 2007 pad = RSA_SSLV23_PADDING; 2008 break; 2009 #endif 2010 case EME_NO_PADDING: 2011 pad = RSA_NO_PADDING; 2012 break; 2013 default: 2014 return SecureArray(); 2015 break; 2016 } 2017 2018 int ret; 2019 if (isPrivate()) 2020 ret = RSA_private_encrypt( 2021 buf.size(), (unsigned char *)buf.data(), (unsigned char *)result.data(), (RSA *)rsa, pad); 2022 else 2023 ret = RSA_public_encrypt( 2024 buf.size(), (unsigned char *)buf.data(), (unsigned char *)result.data(), (RSA *)rsa, pad); 2025 2026 if (ret < 0) 2027 return SecureArray(); 2028 result.resize(ret); 2029 2030 return result; 2031 } 2032 2033 bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg) override 2034 { 2035 const RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); 2036 SecureArray result(RSA_size(rsa)); 2037 int pad; 2038 2039 switch (alg) { 2040 case EME_PKCS1v15: 2041 pad = RSA_PKCS1_PADDING; 2042 break; 2043 case EME_PKCS1_OAEP: 2044 pad = RSA_PKCS1_OAEP_PADDING; 2045 break; 2046 // OPENSSL_VERSION_MAJOR is only defined on openssl > 3.0 2047 // that doesn't have RSA_SSLV23_PADDING so we can use it negatively here 2048 #ifndef OPENSSL_VERSION_MAJOR 2049 case EME_PKCS1v15_SSL: 2050 pad = RSA_SSLV23_PADDING; 2051 break; 2052 #endif 2053 case EME_NO_PADDING: 2054 pad = RSA_NO_PADDING; 2055 break; 2056 default: 2057 return false; 2058 break; 2059 } 2060 2061 int ret; 2062 if (isPrivate()) 2063 ret = RSA_private_decrypt( 2064 in.size(), (unsigned char *)in.data(), (unsigned char *)result.data(), (RSA *)rsa, pad); 2065 else 2066 ret = RSA_public_decrypt( 2067 in.size(), (unsigned char *)in.data(), (unsigned char *)result.data(), (RSA *)rsa, pad); 2068 2069 if (ret < 0) 2070 return false; 2071 result.resize(ret); 2072 2073 *out = result; 2074 return true; 2075 } 2076 2077 void startSign(SignatureAlgorithm alg, SignatureFormat) override 2078 { 2079 const EVP_MD *md = nullptr; 2080 if (alg == EMSA3_SHA1) 2081 md = EVP_sha1(); 2082 else if (alg == EMSA3_MD5) 2083 md = EVP_md5(); 2084 else if (alg == EMSA3_SHA224) 2085 md = EVP_sha224(); 2086 else if (alg == EMSA3_SHA256) 2087 md = EVP_sha256(); 2088 else if (alg == EMSA3_SHA384) 2089 md = EVP_sha384(); 2090 else if (alg == EMSA3_SHA512) 2091 md = EVP_sha512(); 2092 else if (alg == EMSA3_Raw) { 2093 // md = 0 2094 } else if (s_legacyProviderAvailable) { 2095 if (alg == EMSA3_RIPEMD160) 2096 md = EVP_ripemd160(); 2097 #ifdef HAVE_OPENSSL_MD2 2098 else if (alg == EMSA3_MD2) 2099 md = EVP_md2(); 2100 #endif 2101 } 2102 2103 evp.startSign(md); 2104 } 2105 2106 void startVerify(SignatureAlgorithm alg, SignatureFormat) override 2107 { 2108 const EVP_MD *md = nullptr; 2109 if (alg == EMSA3_SHA1) 2110 md = EVP_sha1(); 2111 else if (alg == EMSA3_MD5) 2112 md = EVP_md5(); 2113 else if (alg == EMSA3_SHA224) 2114 md = EVP_sha224(); 2115 else if (alg == EMSA3_SHA256) 2116 md = EVP_sha256(); 2117 else if (alg == EMSA3_SHA384) 2118 md = EVP_sha384(); 2119 else if (alg == EMSA3_SHA512) 2120 md = EVP_sha512(); 2121 else if (alg == EMSA3_Raw) { 2122 // md = 0 2123 } else if (s_legacyProviderAvailable) { 2124 if (alg == EMSA3_RIPEMD160) 2125 md = EVP_ripemd160(); 2126 #ifdef HAVE_OPENSSL_MD2 2127 else if (alg == EMSA3_MD2) 2128 md = EVP_md2(); 2129 #endif 2130 } 2131 evp.startVerify(md); 2132 } 2133 2134 void update(const MemoryRegion &in) override 2135 { 2136 evp.update(in); 2137 } 2138 2139 QByteArray endSign() override 2140 { 2141 return evp.endSign().toByteArray(); 2142 } 2143 2144 bool endVerify(const QByteArray &sig) override 2145 { 2146 return evp.endVerify(sig); 2147 } 2148 2149 void createPrivate(int bits, int exp, bool block) override 2150 { 2151 evp.reset(); 2152 2153 keymaker = new RSAKeyMaker(bits, exp, !block ? this : nullptr); 2154 wasBlocking = block; 2155 if (block) { 2156 keymaker->run(); 2157 km_finished(); 2158 } else { 2159 connect(keymaker, &RSAKeyMaker::finished, this, &RSAKey::km_finished); 2160 keymaker->start(); 2161 } 2162 } 2163 2164 void createPrivate(const BigInteger &n, 2165 const BigInteger &e, 2166 const BigInteger &p, 2167 const BigInteger &q, 2168 const BigInteger &d) override 2169 { 2170 evp.reset(); 2171 2172 RSA *rsa = RSA_new(); 2173 if (RSA_set0_key(rsa, bi2bn(n), bi2bn(e), bi2bn(d)) == 0 || RSA_set0_factors(rsa, bi2bn(p), bi2bn(q)) == 0) { 2174 // Free BIGNUMS? 2175 RSA_free(rsa); 2176 return; 2177 } 2178 2179 // When private key has no Public Exponent (e) or Private Exponent (d) 2180 // need to disable blinding. Otherwise decryption will be broken. 2181 // http://www.mail-archive.com/openssl-users@openssl.org/msg63530.html 2182 if (e == BigInteger(0) || d == BigInteger(0)) 2183 RSA_blinding_off(rsa); 2184 2185 evp.pkey = EVP_PKEY_new(); 2186 EVP_PKEY_assign_RSA(evp.pkey, rsa); 2187 sec = true; 2188 } 2189 2190 void createPublic(const BigInteger &n, const BigInteger &e) override 2191 { 2192 evp.reset(); 2193 2194 RSA *rsa = RSA_new(); 2195 if (RSA_set0_key(rsa, bi2bn(n), bi2bn(e), nullptr) == 0) { 2196 RSA_free(rsa); 2197 return; 2198 } 2199 2200 evp.pkey = EVP_PKEY_new(); 2201 EVP_PKEY_assign_RSA(evp.pkey, rsa); 2202 sec = false; 2203 } 2204 2205 BigInteger n() const override 2206 { 2207 const RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); 2208 const BIGNUM *bnn; 2209 RSA_get0_key(rsa, &bnn, nullptr, nullptr); 2210 return bn2bi(bnn); 2211 } 2212 2213 BigInteger e() const override 2214 { 2215 const RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); 2216 const BIGNUM *bne; 2217 RSA_get0_key(rsa, nullptr, &bne, nullptr); 2218 return bn2bi(bne); 2219 } 2220 2221 BigInteger p() const override 2222 { 2223 const RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); 2224 const BIGNUM *bnp; 2225 RSA_get0_factors(rsa, &bnp, nullptr); 2226 return bn2bi(bnp); 2227 } 2228 2229 BigInteger q() const override 2230 { 2231 const RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); 2232 const BIGNUM *bnq; 2233 RSA_get0_factors(rsa, nullptr, &bnq); 2234 return bn2bi(bnq); 2235 } 2236 2237 BigInteger d() const override 2238 { 2239 const RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); 2240 const BIGNUM *bnd; 2241 RSA_get0_key(rsa, nullptr, nullptr, &bnd); 2242 return bn2bi(bnd); 2243 } 2244 2245 private Q_SLOTS: 2246 void km_finished() 2247 { 2248 RSA *rsa = keymaker->takeResult(); 2249 if (wasBlocking) 2250 delete keymaker; 2251 else 2252 keymaker->deleteLater(); 2253 keymaker = nullptr; 2254 2255 if (rsa) { 2256 evp.pkey = EVP_PKEY_new(); 2257 EVP_PKEY_assign_RSA(evp.pkey, rsa); 2258 sec = true; 2259 } 2260 2261 if (!wasBlocking) 2262 emit finished(); 2263 } 2264 }; 2265 2266 //---------------------------------------------------------------------------- 2267 // DSAKey 2268 //---------------------------------------------------------------------------- 2269 class DSAKeyMaker : public QThread 2270 { 2271 Q_OBJECT 2272 public: 2273 DLGroup domain; 2274 DSA *result; 2275 2276 DSAKeyMaker(const DLGroup &_domain, QObject *parent = nullptr) 2277 : QThread(parent) 2278 , domain(_domain) 2279 , result(nullptr) 2280 { 2281 } 2282 2283 ~DSAKeyMaker() override 2284 { 2285 wait(); 2286 if (result) 2287 DSA_free(result); 2288 } 2289 2290 void run() override 2291 { 2292 std::unique_ptr<DSA, DsaDeleter> dsa(DSA_new()); 2293 BIGNUM *pne = bi2bn(domain.p()), *qne = bi2bn(domain.q()), *gne = bi2bn(domain.g()); 2294 2295 if (!DSA_set0_pqg(dsa.get(), pne, qne, gne)) { 2296 return; 2297 } 2298 if (!DSA_generate_key(dsa.get())) { 2299 // OPENSSL_VERSION_MAJOR is only defined in openssl3 2300 #ifdef OPENSSL_VERSION_MAJOR 2301 // HACK 2302 // in openssl3 there is an internal flag for "legacy" values 2303 // bits < 2048 && seed_len <= 20 2304 // set in ossl_ffc_params_FIPS186_2_generate (called by DSA_generate_parameters_ex) 2305 // that we have no way to get or set, so if the bits are smaller than 2048 we generate 2306 // a dsa from a dummy seed and then override the p/q/g with the ones we want 2307 // so we can reuse the internal flag 2308 if (BN_num_bits(pne) < 2048) { 2309 int dummy; 2310 dsa.reset(DSA_new()); 2311 if (DSA_generate_parameters_ex( 2312 dsa.get(), 512, (const unsigned char *)"THIS_IS_A_DUMMY_SEED", 20, &dummy, nullptr, nullptr) != 2313 1) { 2314 return; 2315 } 2316 pne = bi2bn(domain.p()); 2317 qne = bi2bn(domain.q()); 2318 gne = bi2bn(domain.g()); 2319 if (!DSA_set0_pqg(dsa.get(), pne, qne, gne)) { 2320 return; 2321 } 2322 if (!DSA_generate_key(dsa.get())) { 2323 return; 2324 } 2325 } else { 2326 return; 2327 } 2328 #else 2329 return; 2330 #endif 2331 } 2332 result = dsa.release(); 2333 } 2334 2335 DSA *takeResult() 2336 { 2337 DSA *dsa = result; 2338 result = nullptr; 2339 return dsa; 2340 } 2341 }; 2342 2343 // note: DSA doesn't use SignatureAlgorithm, since EMSA1 is always assumed 2344 class DSAKey : public DSAContext 2345 { 2346 Q_OBJECT 2347 public: 2348 EVPKey evp; 2349 DSAKeyMaker *keymaker; 2350 bool wasBlocking; 2351 bool transformsig; 2352 bool sec; 2353 2354 DSAKey(Provider *p) 2355 : DSAContext(p) 2356 { 2357 keymaker = nullptr; 2358 sec = false; 2359 } 2360 2361 DSAKey(const DSAKey &from) 2362 : DSAContext(from.provider()) 2363 , evp(from.evp) 2364 { 2365 keymaker = nullptr; 2366 sec = from.sec; 2367 } 2368 2369 ~DSAKey() override 2370 { 2371 delete keymaker; 2372 } 2373 2374 Provider::Context *clone() const override 2375 { 2376 return new DSAKey(*this); 2377 } 2378 2379 bool isNull() const override 2380 { 2381 return (evp.pkey ? false : true); 2382 } 2383 2384 PKey::Type type() const override 2385 { 2386 return PKey::DSA; 2387 } 2388 2389 bool isPrivate() const override 2390 { 2391 return sec; 2392 } 2393 2394 bool canExport() const override 2395 { 2396 return true; 2397 } 2398 2399 void convertToPublic() override 2400 { 2401 if (!sec) 2402 return; 2403 2404 // extract the public key into DER format 2405 const DSA *dsa_pkey = EVP_PKEY_get0_DSA(evp.pkey); 2406 int len = i2d_DSAPublicKey(dsa_pkey, nullptr); 2407 SecureArray result(len); 2408 unsigned char *p = (unsigned char *)result.data(); 2409 i2d_DSAPublicKey(dsa_pkey, &p); 2410 p = (unsigned char *)result.data(); 2411 2412 // put the DER public key back into openssl 2413 evp.reset(); 2414 DSA *dsa = d2i_DSAPublicKey(nullptr, (const unsigned char **)&p, result.size()); 2415 evp.pkey = EVP_PKEY_new(); 2416 EVP_PKEY_assign_DSA(evp.pkey, dsa); 2417 sec = false; 2418 } 2419 2420 int bits() const override 2421 { 2422 return EVP_PKEY_bits(evp.pkey); 2423 } 2424 2425 void startSign(SignatureAlgorithm, SignatureFormat format) override 2426 { 2427 // openssl native format is DER, so transform otherwise 2428 if (format != DERSequence) 2429 transformsig = true; 2430 else 2431 transformsig = false; 2432 2433 evp.startSign(EVP_sha1()); 2434 } 2435 2436 void startVerify(SignatureAlgorithm, SignatureFormat format) override 2437 { 2438 // openssl native format is DER, so transform otherwise 2439 if (format != DERSequence) 2440 transformsig = true; 2441 else 2442 transformsig = false; 2443 2444 evp.startVerify(EVP_sha1()); 2445 } 2446 2447 void update(const MemoryRegion &in) override 2448 { 2449 evp.update(in); 2450 } 2451 2452 QByteArray endSign() override 2453 { 2454 SecureArray out = evp.endSign(); 2455 if (transformsig) 2456 return dsasig_der_to_raw(out).toByteArray(); 2457 else 2458 return out.toByteArray(); 2459 } 2460 2461 bool endVerify(const QByteArray &sig) override 2462 { 2463 SecureArray in; 2464 if (transformsig) 2465 in = dsasig_raw_to_der(sig); 2466 else 2467 in = sig; 2468 return evp.endVerify(in); 2469 } 2470 2471 void createPrivate(const DLGroup &domain, bool block) override 2472 { 2473 evp.reset(); 2474 2475 keymaker = new DSAKeyMaker(domain, !block ? this : nullptr); 2476 wasBlocking = block; 2477 if (block) { 2478 keymaker->run(); 2479 km_finished(); 2480 } else { 2481 connect(keymaker, &DSAKeyMaker::finished, this, &DSAKey::km_finished); 2482 keymaker->start(); 2483 } 2484 } 2485 2486 void createPrivate(const DLGroup &domain, const BigInteger &y, const BigInteger &x) override 2487 { 2488 evp.reset(); 2489 2490 DSA *dsa = DSA_new(); 2491 BIGNUM *bnp = bi2bn(domain.p()); 2492 BIGNUM *bnq = bi2bn(domain.q()); 2493 BIGNUM *bng = bi2bn(domain.g()); 2494 BIGNUM *bnpub_key = bi2bn(y); 2495 BIGNUM *bnpriv_key = bi2bn(x); 2496 2497 if (!DSA_set0_pqg(dsa, bnp, bnq, bng) || !DSA_set0_key(dsa, bnpub_key, bnpriv_key)) { 2498 DSA_free(dsa); 2499 return; 2500 } 2501 2502 evp.pkey = EVP_PKEY_new(); 2503 EVP_PKEY_assign_DSA(evp.pkey, dsa); 2504 sec = true; 2505 } 2506 2507 void createPublic(const DLGroup &domain, const BigInteger &y) override 2508 { 2509 evp.reset(); 2510 2511 DSA *dsa = DSA_new(); 2512 BIGNUM *bnp = bi2bn(domain.p()); 2513 BIGNUM *bnq = bi2bn(domain.q()); 2514 BIGNUM *bng = bi2bn(domain.g()); 2515 BIGNUM *bnpub_key = bi2bn(y); 2516 2517 if (!DSA_set0_pqg(dsa, bnp, bnq, bng) || !DSA_set0_key(dsa, bnpub_key, nullptr)) { 2518 DSA_free(dsa); 2519 return; 2520 } 2521 2522 evp.pkey = EVP_PKEY_new(); 2523 EVP_PKEY_assign_DSA(evp.pkey, dsa); 2524 sec = false; 2525 } 2526 2527 DLGroup domain() const override 2528 { 2529 const DSA *dsa = EVP_PKEY_get0_DSA(evp.pkey); 2530 const BIGNUM *bnp, *bnq, *bng; 2531 DSA_get0_pqg(dsa, &bnp, &bnq, &bng); 2532 return DLGroup(bn2bi(bnp), bn2bi(bnq), bn2bi(bng)); 2533 } 2534 2535 BigInteger y() const override 2536 { 2537 const DSA *dsa = EVP_PKEY_get0_DSA(evp.pkey); 2538 const BIGNUM *bnpub_key; 2539 DSA_get0_key(dsa, &bnpub_key, nullptr); 2540 return bn2bi(bnpub_key); 2541 } 2542 2543 BigInteger x() const override 2544 { 2545 const DSA *dsa = EVP_PKEY_get0_DSA(evp.pkey); 2546 const BIGNUM *bnpriv_key; 2547 DSA_get0_key(dsa, nullptr, &bnpriv_key); 2548 return bn2bi(bnpriv_key); 2549 } 2550 2551 private Q_SLOTS: 2552 void km_finished() 2553 { 2554 DSA *dsa = keymaker->takeResult(); 2555 if (wasBlocking) 2556 delete keymaker; 2557 else 2558 keymaker->deleteLater(); 2559 keymaker = nullptr; 2560 2561 if (dsa) { 2562 evp.pkey = EVP_PKEY_new(); 2563 EVP_PKEY_assign_DSA(evp.pkey, dsa); 2564 sec = true; 2565 } 2566 2567 if (!wasBlocking) 2568 emit finished(); 2569 } 2570 }; 2571 2572 //---------------------------------------------------------------------------- 2573 // DHKey 2574 //---------------------------------------------------------------------------- 2575 class DHKeyMaker : public QThread 2576 { 2577 Q_OBJECT 2578 public: 2579 DLGroup domain; 2580 DH *result; 2581 2582 DHKeyMaker(const DLGroup &_domain, QObject *parent = nullptr) 2583 : QThread(parent) 2584 , domain(_domain) 2585 , result(nullptr) 2586 { 2587 } 2588 2589 ~DHKeyMaker() override 2590 { 2591 wait(); 2592 if (result) 2593 DH_free(result); 2594 } 2595 2596 void run() override 2597 { 2598 DH *dh = DH_new(); 2599 BIGNUM *bnp = bi2bn(domain.p()); 2600 BIGNUM *bng = bi2bn(domain.g()); 2601 if (!DH_set0_pqg(dh, bnp, nullptr, bng) || !DH_generate_key(dh)) { 2602 DH_free(dh); 2603 return; 2604 } 2605 result = dh; 2606 } 2607 2608 DH *takeResult() 2609 { 2610 DH *dh = result; 2611 result = nullptr; 2612 return dh; 2613 } 2614 }; 2615 2616 class DHKey : public DHContext 2617 { 2618 Q_OBJECT 2619 public: 2620 EVPKey evp; 2621 DHKeyMaker *keymaker; 2622 bool wasBlocking; 2623 bool sec; 2624 2625 DHKey(Provider *p) 2626 : DHContext(p) 2627 { 2628 keymaker = nullptr; 2629 sec = false; 2630 } 2631 2632 DHKey(const DHKey &from) 2633 : DHContext(from.provider()) 2634 , evp(from.evp) 2635 { 2636 keymaker = nullptr; 2637 sec = from.sec; 2638 } 2639 2640 ~DHKey() override 2641 { 2642 delete keymaker; 2643 } 2644 2645 Provider::Context *clone() const override 2646 { 2647 return new DHKey(*this); 2648 } 2649 2650 bool isNull() const override 2651 { 2652 return (evp.pkey ? false : true); 2653 } 2654 2655 PKey::Type type() const override 2656 { 2657 return PKey::DH; 2658 } 2659 2660 bool isPrivate() const override 2661 { 2662 return sec; 2663 } 2664 2665 bool canExport() const override 2666 { 2667 return true; 2668 } 2669 2670 void convertToPublic() override 2671 { 2672 if (!sec) 2673 return; 2674 2675 const DH *orig = EVP_PKEY_get0_DH(evp.pkey); 2676 DH *dh = DH_new(); 2677 const BIGNUM *bnp, *bng, *bnpub_key; 2678 DH_get0_pqg(orig, &bnp, nullptr, &bng); 2679 DH_get0_key(orig, &bnpub_key, nullptr); 2680 2681 DH_set0_key(dh, BN_dup(bnpub_key), nullptr); 2682 DH_set0_pqg(dh, BN_dup(bnp), nullptr, BN_dup(bng)); 2683 2684 evp.reset(); 2685 2686 evp.pkey = EVP_PKEY_new(); 2687 EVP_PKEY_assign_DH(evp.pkey, dh); 2688 sec = false; 2689 } 2690 2691 int bits() const override 2692 { 2693 return EVP_PKEY_bits(evp.pkey); 2694 } 2695 2696 SymmetricKey deriveKey(const PKeyBase &theirs) override 2697 { 2698 const DH *dh = EVP_PKEY_get0_DH(evp.pkey); 2699 const DH *them = EVP_PKEY_get0_DH(static_cast<const DHKey *>(&theirs)->evp.pkey); 2700 const BIGNUM *bnpub_key; 2701 DH_get0_key(them, &bnpub_key, nullptr); 2702 2703 SecureArray result(DH_size(dh)); 2704 int ret = DH_compute_key((unsigned char *)result.data(), bnpub_key, (DH *)dh); 2705 if (ret <= 0) 2706 return SymmetricKey(); 2707 result.resize(ret); 2708 return SymmetricKey(result); 2709 } 2710 2711 void createPrivate(const DLGroup &domain, bool block) override 2712 { 2713 evp.reset(); 2714 2715 keymaker = new DHKeyMaker(domain, !block ? this : nullptr); 2716 wasBlocking = block; 2717 if (block) { 2718 keymaker->run(); 2719 km_finished(); 2720 } else { 2721 connect(keymaker, &DHKeyMaker::finished, this, &DHKey::km_finished); 2722 keymaker->start(); 2723 } 2724 } 2725 2726 void createPrivate(const DLGroup &domain, const BigInteger &y, const BigInteger &x) override 2727 { 2728 evp.reset(); 2729 2730 DH *dh = DH_new(); 2731 BIGNUM *bnp = bi2bn(domain.p()); 2732 BIGNUM *bng = bi2bn(domain.g()); 2733 BIGNUM *bnpub_key = bi2bn(y); 2734 BIGNUM *bnpriv_key = bi2bn(x); 2735 2736 if (!DH_set0_key(dh, bnpub_key, bnpriv_key) || !DH_set0_pqg(dh, bnp, nullptr, bng)) { 2737 DH_free(dh); 2738 return; 2739 } 2740 2741 evp.pkey = EVP_PKEY_new(); 2742 EVP_PKEY_assign_DH(evp.pkey, dh); 2743 sec = true; 2744 } 2745 2746 void createPublic(const DLGroup &domain, const BigInteger &y) override 2747 { 2748 evp.reset(); 2749 2750 DH *dh = DH_new(); 2751 BIGNUM *bnp = bi2bn(domain.p()); 2752 BIGNUM *bng = bi2bn(domain.g()); 2753 BIGNUM *bnpub_key = bi2bn(y); 2754 2755 if (!DH_set0_key(dh, bnpub_key, nullptr) || !DH_set0_pqg(dh, bnp, nullptr, bng)) { 2756 DH_free(dh); 2757 return; 2758 } 2759 2760 evp.pkey = EVP_PKEY_new(); 2761 EVP_PKEY_assign_DH(evp.pkey, dh); 2762 sec = false; 2763 } 2764 2765 DLGroup domain() const override 2766 { 2767 const DH *dh = EVP_PKEY_get0_DH(evp.pkey); 2768 const BIGNUM *bnp, *bng; 2769 DH_get0_pqg(dh, &bnp, nullptr, &bng); 2770 return DLGroup(bn2bi(bnp), bn2bi(bng)); 2771 } 2772 2773 BigInteger y() const override 2774 { 2775 const DH *dh = EVP_PKEY_get0_DH(evp.pkey); 2776 const BIGNUM *bnpub_key; 2777 DH_get0_key(dh, &bnpub_key, nullptr); 2778 return bn2bi(bnpub_key); 2779 } 2780 2781 BigInteger x() const override 2782 { 2783 const DH *dh = EVP_PKEY_get0_DH(evp.pkey); 2784 const BIGNUM *bnpriv_key; 2785 DH_get0_key(dh, nullptr, &bnpriv_key); 2786 return bn2bi(bnpriv_key); 2787 } 2788 2789 private Q_SLOTS: 2790 void km_finished() 2791 { 2792 DH *dh = keymaker->takeResult(); 2793 if (wasBlocking) 2794 delete keymaker; 2795 else 2796 keymaker->deleteLater(); 2797 keymaker = nullptr; 2798 2799 if (dh) { 2800 evp.pkey = EVP_PKEY_new(); 2801 EVP_PKEY_assign_DH(evp.pkey, dh); 2802 sec = true; 2803 } 2804 2805 if (!wasBlocking) 2806 emit finished(); 2807 } 2808 }; 2809 2810 //---------------------------------------------------------------------------- 2811 // QCA-based RSA_METHOD 2812 //---------------------------------------------------------------------------- 2813 2814 // only supports EMSA3_Raw for now 2815 class QCA_RSA_METHOD 2816 { 2817 public: 2818 RSAPrivateKey key; 2819 2820 QCA_RSA_METHOD(const RSAPrivateKey &_key, RSA *rsa) 2821 { 2822 key = _key; 2823 RSA_set_method(rsa, rsa_method()); 2824 RSA_set_app_data(rsa, this); 2825 BIGNUM *bnn = bi2bn(_key.n()); 2826 BIGNUM *bne = bi2bn(_key.e()); 2827 2828 RSA_set0_key(rsa, bnn, bne, nullptr); 2829 } 2830 2831 RSA_METHOD *rsa_method() 2832 { 2833 static RSA_METHOD *ops = nullptr; 2834 2835 if (!ops) { 2836 ops = RSA_meth_dup(RSA_get_default_method()); 2837 RSA_meth_set_priv_enc(ops, nullptr); // pkcs11_rsa_encrypt 2838 RSA_meth_set_priv_dec(ops, rsa_priv_dec); // pkcs11_rsa_encrypt 2839 RSA_meth_set_sign(ops, nullptr); 2840 RSA_meth_set_verify(ops, nullptr); // pkcs11_rsa_verify 2841 RSA_meth_set_finish(ops, rsa_finish); 2842 } 2843 return ops; 2844 } 2845 2846 static int rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) 2847 { 2848 QCA::EncryptionAlgorithm algo; 2849 2850 if (padding == RSA_PKCS1_PADDING) { 2851 algo = QCA::EME_PKCS1v15; 2852 } else if (padding == RSA_PKCS1_OAEP_PADDING) { 2853 algo = QCA::EME_PKCS1_OAEP; 2854 } else { 2855 RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); 2856 return -1; 2857 } 2858 2859 QCA_RSA_METHOD *self = (QCA_RSA_METHOD *)RSA_get_app_data(rsa); 2860 2861 QCA::SecureArray input; 2862 input.resize(flen); 2863 memcpy(input.data(), from, input.size()); 2864 2865 QCA::SecureArray output; 2866 2867 if (self->key.decrypt(input, &output, algo)) { 2868 memcpy(to, output.data(), output.size()); 2869 return output.size(); 2870 } 2871 2872 // XXX: An error should be set in this case too. 2873 return -1; 2874 } 2875 2876 static int rsa_finish(RSA *rsa) 2877 { 2878 QCA_RSA_METHOD *self = (QCA_RSA_METHOD *)RSA_get_app_data(rsa); 2879 delete self; 2880 return 1; 2881 } 2882 }; 2883 2884 static RSA *createFromExisting(const RSAPrivateKey &key) 2885 { 2886 RSA *r = RSA_new(); 2887 new QCA_RSA_METHOD(key, r); // will delete itself on RSA_free 2888 return r; 2889 } 2890 2891 //---------------------------------------------------------------------------- 2892 // MyPKeyContext 2893 //---------------------------------------------------------------------------- 2894 class MyPKeyContext : public PKeyContext 2895 { 2896 Q_OBJECT 2897 public: 2898 PKeyBase *k; 2899 2900 MyPKeyContext(Provider *p) 2901 : PKeyContext(p) 2902 { 2903 k = nullptr; 2904 } 2905 2906 ~MyPKeyContext() override 2907 { 2908 delete k; 2909 } 2910 2911 Provider::Context *clone() const override 2912 { 2913 MyPKeyContext *c = new MyPKeyContext(*this); 2914 c->k = (PKeyBase *)k->clone(); 2915 return c; 2916 } 2917 2918 QList<PKey::Type> supportedTypes() const override 2919 { 2920 QList<PKey::Type> list; 2921 list += PKey::RSA; 2922 list += PKey::DSA; 2923 list += PKey::DH; 2924 return list; 2925 } 2926 2927 QList<PKey::Type> supportedIOTypes() const override 2928 { 2929 QList<PKey::Type> list; 2930 list += PKey::RSA; 2931 list += PKey::DSA; 2932 return list; 2933 } 2934 2935 QList<PBEAlgorithm> supportedPBEAlgorithms() const override 2936 { 2937 QList<PBEAlgorithm> list; 2938 list += PBES2_DES_SHA1; 2939 list += PBES2_TripleDES_SHA1; 2940 return list; 2941 } 2942 2943 PKeyBase *key() override 2944 { 2945 return k; 2946 } 2947 2948 const PKeyBase *key() const override 2949 { 2950 return k; 2951 } 2952 2953 void setKey(PKeyBase *key) override 2954 { 2955 k = key; 2956 } 2957 2958 bool importKey(const PKeyBase *key) override 2959 { 2960 Q_UNUSED(key); 2961 return false; 2962 } 2963 2964 EVP_PKEY *get_pkey() const 2965 { 2966 PKey::Type t = k->type(); 2967 if (t == PKey::RSA) 2968 return static_cast<RSAKey *>(k)->evp.pkey; 2969 else if (t == PKey::DSA) 2970 return static_cast<DSAKey *>(k)->evp.pkey; 2971 else 2972 return static_cast<DHKey *>(k)->evp.pkey; 2973 } 2974 2975 PKeyBase *pkeyToBase(EVP_PKEY *pkey, bool sec) const 2976 { 2977 PKeyBase *nk = nullptr; 2978 int pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey)); 2979 if (pkey_type == EVP_PKEY_RSA) { 2980 RSAKey *c = new RSAKey(provider()); 2981 c->evp.pkey = pkey; 2982 c->sec = sec; 2983 nk = c; 2984 } else if (pkey_type == EVP_PKEY_DSA) { 2985 DSAKey *c = new DSAKey(provider()); 2986 c->evp.pkey = pkey; 2987 c->sec = sec; 2988 nk = c; 2989 } else if (pkey_type == EVP_PKEY_DH) { 2990 DHKey *c = new DHKey(provider()); 2991 c->evp.pkey = pkey; 2992 c->sec = sec; 2993 nk = c; 2994 } else { 2995 EVP_PKEY_free(pkey); 2996 } 2997 return nk; 2998 } 2999 3000 QByteArray publicToDER() const override 3001 { 3002 EVP_PKEY *pkey = get_pkey(); 3003 3004 int pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey)); 3005 3006 // OpenSSL does not have DH import/export support 3007 if (pkey_type == EVP_PKEY_DH) 3008 return QByteArray(); 3009 3010 BIO *bo = BIO_new(BIO_s_mem()); 3011 i2d_PUBKEY_bio(bo, pkey); 3012 const QByteArray buf = bio2ba(bo); 3013 return buf; 3014 } 3015 3016 QString publicToPEM() const override 3017 { 3018 EVP_PKEY *pkey = get_pkey(); 3019 3020 int pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey)); 3021 3022 // OpenSSL does not have DH import/export support 3023 if (pkey_type == EVP_PKEY_DH) 3024 return QString(); 3025 3026 BIO *bo = BIO_new(BIO_s_mem()); 3027 PEM_write_bio_PUBKEY(bo, pkey); 3028 const QByteArray buf = bio2ba(bo); 3029 return QString::fromLatin1(buf); 3030 } 3031 3032 ConvertResult publicFromDER(const QByteArray &in) override 3033 { 3034 delete k; 3035 k = nullptr; 3036 3037 BIO *bi = BIO_new(BIO_s_mem()); 3038 BIO_write(bi, in.data(), in.size()); 3039 EVP_PKEY *pkey = d2i_PUBKEY_bio(bi, nullptr); 3040 BIO_free(bi); 3041 3042 if (!pkey) 3043 return ErrorDecode; 3044 3045 k = pkeyToBase(pkey, false); 3046 if (k) 3047 return ConvertGood; 3048 else 3049 return ErrorDecode; 3050 } 3051 3052 ConvertResult publicFromPEM(const QString &s) override 3053 { 3054 delete k; 3055 k = nullptr; 3056 3057 const QByteArray in = s.toLatin1(); 3058 BIO *bi = BIO_new(BIO_s_mem()); 3059 BIO_write(bi, in.data(), in.size()); 3060 EVP_PKEY *pkey = PEM_read_bio_PUBKEY(bi, nullptr, passphrase_cb, nullptr); 3061 BIO_free(bi); 3062 3063 if (!pkey) 3064 return ErrorDecode; 3065 3066 k = pkeyToBase(pkey, false); 3067 if (k) 3068 return ConvertGood; 3069 else 3070 return ErrorDecode; 3071 } 3072 3073 SecureArray privateToDER(const SecureArray &passphrase, PBEAlgorithm pbe) const override 3074 { 3075 // if(pbe == PBEDefault) 3076 // pbe = PBES2_TripleDES_SHA1; 3077 3078 const EVP_CIPHER *cipher = nullptr; 3079 if (pbe == PBES2_TripleDES_SHA1) 3080 cipher = EVP_des_ede3_cbc(); 3081 else if (pbe == PBES2_DES_SHA1) 3082 cipher = EVP_des_cbc(); 3083 3084 if (!cipher) 3085 return SecureArray(); 3086 3087 EVP_PKEY *pkey = get_pkey(); 3088 int pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey)); 3089 3090 // OpenSSL does not have DH import/export support 3091 if (pkey_type == EVP_PKEY_DH) 3092 return SecureArray(); 3093 3094 BIO *bo = BIO_new(BIO_s_mem()); 3095 if (!passphrase.isEmpty()) 3096 i2d_PKCS8PrivateKey_bio(bo, pkey, cipher, nullptr, 0, nullptr, (void *)passphrase.data()); 3097 else 3098 i2d_PKCS8PrivateKey_bio(bo, pkey, nullptr, nullptr, 0, nullptr, nullptr); 3099 SecureArray buf = bio2buf(bo); 3100 return buf; 3101 } 3102 3103 QString privateToPEM(const SecureArray &passphrase, PBEAlgorithm pbe) const override 3104 { 3105 // if(pbe == PBEDefault) 3106 // pbe = PBES2_TripleDES_SHA1; 3107 3108 const EVP_CIPHER *cipher = nullptr; 3109 if (pbe == PBES2_TripleDES_SHA1) 3110 cipher = EVP_des_ede3_cbc(); 3111 else if (pbe == PBES2_DES_SHA1) 3112 cipher = EVP_des_cbc(); 3113 3114 if (!cipher) 3115 return QString(); 3116 3117 EVP_PKEY *pkey = get_pkey(); 3118 int pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey)); 3119 3120 // OpenSSL does not have DH import/export support 3121 if (pkey_type == EVP_PKEY_DH) 3122 return QString(); 3123 3124 BIO *bo = BIO_new(BIO_s_mem()); 3125 if (!passphrase.isEmpty()) 3126 PEM_write_bio_PKCS8PrivateKey(bo, pkey, cipher, nullptr, 0, nullptr, (void *)passphrase.data()); 3127 else 3128 PEM_write_bio_PKCS8PrivateKey(bo, pkey, nullptr, nullptr, 0, nullptr, nullptr); 3129 SecureArray buf = bio2buf(bo); 3130 return QString::fromLatin1(buf.toByteArray()); 3131 } 3132 3133 ConvertResult privateFromDER(const SecureArray &in, const SecureArray &passphrase) override 3134 { 3135 delete k; 3136 k = nullptr; 3137 3138 EVP_PKEY *pkey; 3139 if (!passphrase.isEmpty()) 3140 pkey = qca_d2i_PKCS8PrivateKey(in, nullptr, nullptr, (void *)passphrase.data()); 3141 else 3142 pkey = qca_d2i_PKCS8PrivateKey(in, nullptr, passphrase_cb, nullptr); 3143 3144 if (!pkey) 3145 return ErrorDecode; 3146 3147 k = pkeyToBase(pkey, true); 3148 if (k) 3149 return ConvertGood; 3150 else 3151 return ErrorDecode; 3152 } 3153 3154 ConvertResult privateFromPEM(const QString &s, const SecureArray &passphrase) override 3155 { 3156 delete k; 3157 k = nullptr; 3158 3159 const QByteArray in = s.toLatin1(); 3160 BIO *bi = BIO_new(BIO_s_mem()); 3161 BIO_write(bi, in.data(), in.size()); 3162 EVP_PKEY *pkey; 3163 if (!passphrase.isEmpty()) 3164 pkey = PEM_read_bio_PrivateKey(bi, nullptr, nullptr, (void *)passphrase.data()); 3165 else 3166 pkey = PEM_read_bio_PrivateKey(bi, nullptr, passphrase_cb, nullptr); 3167 BIO_free(bi); 3168 3169 if (!pkey) 3170 return ErrorDecode; 3171 3172 k = pkeyToBase(pkey, true); 3173 if (k) 3174 return ConvertGood; 3175 else 3176 return ErrorDecode; 3177 } 3178 }; 3179 3180 //---------------------------------------------------------------------------- 3181 // MyCertContext 3182 //---------------------------------------------------------------------------- 3183 class X509Item 3184 { 3185 public: 3186 X509 *cert; 3187 X509_REQ *req; 3188 X509_CRL *crl; 3189 3190 enum Type 3191 { 3192 TypeCert, 3193 TypeReq, 3194 TypeCRL 3195 }; 3196 3197 X509Item() 3198 { 3199 cert = nullptr; 3200 req = nullptr; 3201 crl = nullptr; 3202 } 3203 3204 X509Item(const X509Item &from) 3205 { 3206 cert = nullptr; 3207 req = nullptr; 3208 crl = nullptr; 3209 *this = from; 3210 } 3211 3212 ~X509Item() 3213 { 3214 reset(); 3215 } 3216 3217 X509Item &operator=(const X509Item &from) 3218 { 3219 if (this != &from) { 3220 reset(); 3221 cert = from.cert; 3222 req = from.req; 3223 crl = from.crl; 3224 3225 if (cert) 3226 X509_up_ref(cert); 3227 if (req) { 3228 // Not exposed, so copy 3229 req = X509_REQ_dup(req); 3230 } 3231 if (crl) 3232 X509_CRL_up_ref(crl); 3233 } 3234 3235 return *this; 3236 } 3237 3238 void reset() 3239 { 3240 if (cert) { 3241 X509_free(cert); 3242 cert = nullptr; 3243 } 3244 if (req) { 3245 X509_REQ_free(req); 3246 req = nullptr; 3247 } 3248 if (crl) { 3249 X509_CRL_free(crl); 3250 crl = nullptr; 3251 } 3252 } 3253 3254 bool isNull() const 3255 { 3256 return (!cert && !req && !crl); 3257 } 3258 3259 QByteArray toDER() const 3260 { 3261 BIO *bo = BIO_new(BIO_s_mem()); 3262 if (cert) 3263 i2d_X509_bio(bo, cert); 3264 else if (req) 3265 i2d_X509_REQ_bio(bo, req); 3266 else if (crl) 3267 i2d_X509_CRL_bio(bo, crl); 3268 const QByteArray buf = bio2ba(bo); 3269 return buf; 3270 } 3271 3272 QString toPEM() const 3273 { 3274 BIO *bo = BIO_new(BIO_s_mem()); 3275 if (cert) 3276 PEM_write_bio_X509(bo, cert); 3277 else if (req) 3278 PEM_write_bio_X509_REQ(bo, req); 3279 else if (crl) 3280 PEM_write_bio_X509_CRL(bo, crl); 3281 const QByteArray buf = bio2ba(bo); 3282 return QString::fromLatin1(buf); 3283 } 3284 3285 ConvertResult fromDER(const QByteArray &in, Type t) 3286 { 3287 reset(); 3288 3289 BIO *bi = BIO_new(BIO_s_mem()); 3290 BIO_write(bi, in.data(), in.size()); 3291 3292 if (t == TypeCert) 3293 cert = d2i_X509_bio(bi, nullptr); 3294 else if (t == TypeReq) 3295 req = d2i_X509_REQ_bio(bi, nullptr); 3296 else if (t == TypeCRL) 3297 crl = d2i_X509_CRL_bio(bi, nullptr); 3298 3299 BIO_free(bi); 3300 3301 if (isNull()) 3302 return ErrorDecode; 3303 3304 return ConvertGood; 3305 } 3306 3307 ConvertResult fromPEM(const QString &s, Type t) 3308 { 3309 reset(); 3310 3311 const QByteArray in = s.toLatin1(); 3312 BIO *bi = BIO_new(BIO_s_mem()); 3313 BIO_write(bi, in.data(), in.size()); 3314 3315 if (t == TypeCert) 3316 cert = PEM_read_bio_X509(bi, nullptr, passphrase_cb, nullptr); 3317 else if (t == TypeReq) 3318 req = PEM_read_bio_X509_REQ(bi, nullptr, passphrase_cb, nullptr); 3319 else if (t == TypeCRL) 3320 crl = PEM_read_bio_X509_CRL(bi, nullptr, passphrase_cb, nullptr); 3321 3322 BIO_free(bi); 3323 3324 if (isNull()) 3325 return ErrorDecode; 3326 3327 return ConvertGood; 3328 } 3329 }; 3330 3331 // (taken from kdelibs) -- Justin 3332 // 3333 // This code is mostly taken from OpenSSL v0.9.5a 3334 // by Eric Young 3335 QDateTime ASN1_UTCTIME_QDateTime(const ASN1_UTCTIME *tm, int *isGmt) 3336 { 3337 QDateTime qdt; 3338 char *v; 3339 int gmt = 0; 3340 int i; 3341 int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; 3342 QDate qdate; 3343 QTime qtime; 3344 3345 i = tm->length; 3346 v = (char *)tm->data; 3347 3348 if (i < 10) 3349 goto auq_err; 3350 if (v[i - 1] == 'Z') 3351 gmt = 1; 3352 for (i = 0; i < 10; i++) 3353 if ((v[i] > '9') || (v[i] < '0')) 3354 goto auq_err; 3355 y = (v[0] - '0') * 10 + (v[1] - '0'); 3356 if (y < 50) 3357 y += 100; 3358 M = (v[2] - '0') * 10 + (v[3] - '0'); 3359 if ((M > 12) || (M < 1)) 3360 goto auq_err; 3361 d = (v[4] - '0') * 10 + (v[5] - '0'); 3362 h = (v[6] - '0') * 10 + (v[7] - '0'); 3363 m = (v[8] - '0') * 10 + (v[9] - '0'); 3364 if ((v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9')) 3365 s = (v[10] - '0') * 10 + (v[11] - '0'); 3366 3367 // localize the date and display it. 3368 qdate.setDate(y + 1900, M, d); 3369 qtime.setHMS(h, m, s); 3370 qdt.setDate(qdate); 3371 qdt.setTime(qtime); 3372 if (gmt) 3373 qdt.setTimeSpec(Qt::UTC); 3374 auq_err: 3375 if (isGmt) 3376 *isGmt = gmt; 3377 return qdt; 3378 } 3379 3380 class MyCertContext; 3381 static bool sameChain(STACK_OF(X509) * ossl, const QList<const MyCertContext *> &qca); 3382 3383 // TODO: support read/write of multiple info values with the same name 3384 class MyCertContext : public CertContext 3385 { 3386 Q_OBJECT 3387 public: 3388 X509Item item; 3389 CertContextProps _props; 3390 3391 MyCertContext(Provider *p) 3392 : CertContext(p) 3393 { 3394 // printf("[%p] ** created\n", this); 3395 } 3396 3397 MyCertContext(const MyCertContext &from) 3398 : CertContext(from) 3399 , item(from.item) 3400 , _props(from._props) 3401 { 3402 // printf("[%p] ** created as copy (from [%p])\n", this, &from); 3403 } 3404 3405 ~MyCertContext() override 3406 { 3407 // printf("[%p] ** deleted\n", this); 3408 } 3409 3410 Provider::Context *clone() const override 3411 { 3412 return new MyCertContext(*this); 3413 } 3414 3415 QByteArray toDER() const override 3416 { 3417 return item.toDER(); 3418 } 3419 3420 QString toPEM() const override 3421 { 3422 return item.toPEM(); 3423 } 3424 3425 ConvertResult fromDER(const QByteArray &a) override 3426 { 3427 _props = CertContextProps(); 3428 ConvertResult r = item.fromDER(a, X509Item::TypeCert); 3429 if (r == ConvertGood) 3430 make_props(); 3431 return r; 3432 } 3433 3434 ConvertResult fromPEM(const QString &s) override 3435 { 3436 _props = CertContextProps(); 3437 ConvertResult r = item.fromPEM(s, X509Item::TypeCert); 3438 if (r == ConvertGood) 3439 make_props(); 3440 return r; 3441 } 3442 3443 void fromX509(X509 *x) 3444 { 3445 X509_up_ref(x); 3446 item.cert = x; 3447 make_props(); 3448 } 3449 3450 bool createSelfSigned(const CertificateOptions &opts, const PKeyContext &priv) override 3451 { 3452 _props = CertContextProps(); 3453 item.reset(); 3454 3455 CertificateInfo info = opts.info(); 3456 3457 // Note: removing default constraints, let the app choose these if it wants 3458 Constraints constraints = opts.constraints(); 3459 // constraints - logic from Botan 3460 /*Constraints constraints; 3461 if(opts.isCA()) 3462 { 3463 constraints += KeyCertificateSign; 3464 constraints += CRLSign; 3465 } 3466 else 3467 constraints = find_constraints(priv, opts.constraints());*/ 3468 3469 EVP_PKEY *pk = static_cast<const MyPKeyContext *>(&priv)->get_pkey(); 3470 X509_EXTENSION *ex; 3471 3472 const EVP_MD *md; 3473 if (priv.key()->type() == PKey::RSA || priv.key()->type() == PKey::DSA) 3474 md = EVP_sha256(); 3475 else 3476 return false; 3477 3478 // create 3479 X509 *x = X509_new(); 3480 X509_set_version(x, 2); 3481 3482 // serial 3483 BIGNUM *bn = bi2bn(opts.serialNumber()); 3484 BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(x)); 3485 BN_free(bn); 3486 3487 // validity period 3488 ASN1_TIME_set(X509_get_notBefore(x), opts.notValidBefore().toSecsSinceEpoch()); 3489 ASN1_TIME_set(X509_get_notAfter(x), opts.notValidAfter().toSecsSinceEpoch()); 3490 3491 // public key 3492 X509_set_pubkey(x, pk); 3493 3494 // subject 3495 X509_NAME *name = new_cert_name(info); 3496 X509_set_subject_name(x, name); 3497 3498 // issuer == subject 3499 X509_set_issuer_name(x, name); 3500 3501 // subject key id 3502 ex = new_subject_key_id(x); 3503 { 3504 X509_add_ext(x, ex, -1); 3505 X509_EXTENSION_free(ex); 3506 } 3507 3508 // CA mode 3509 ex = new_basic_constraints(opts.isCA(), opts.pathLimit()); 3510 if (ex) { 3511 X509_add_ext(x, ex, -1); 3512 X509_EXTENSION_free(ex); 3513 } 3514 3515 // subject alt name 3516 ex = new_cert_subject_alt_name(info); 3517 if (ex) { 3518 X509_add_ext(x, ex, -1); 3519 X509_EXTENSION_free(ex); 3520 } 3521 3522 // key usage 3523 ex = new_cert_key_usage(constraints); 3524 if (ex) { 3525 X509_add_ext(x, ex, -1); 3526 X509_EXTENSION_free(ex); 3527 } 3528 3529 // extended key usage 3530 ex = new_cert_ext_key_usage(constraints); 3531 if (ex) { 3532 X509_add_ext(x, ex, -1); 3533 X509_EXTENSION_free(ex); 3534 } 3535 3536 // policies 3537 ex = new_cert_policies(opts.policies()); 3538 if (ex) { 3539 X509_add_ext(x, ex, -1); 3540 X509_EXTENSION_free(ex); 3541 } 3542 3543 // finished 3544 X509_sign(x, pk, md); 3545 3546 item.cert = x; 3547 make_props(); 3548 return true; 3549 } 3550 3551 const CertContextProps *props() const override 3552 { 3553 // printf("[%p] grabbing props\n", this); 3554 return &_props; 3555 } 3556 3557 bool compare(const CertContext *other) const override 3558 { 3559 const CertContextProps *a = &_props; 3560 const CertContextProps *b = other->props(); 3561 3562 PublicKey akey, bkey; 3563 PKeyContext *ac = subjectPublicKey(); 3564 akey.change(ac); 3565 PKeyContext *bc = other->subjectPublicKey(); 3566 bkey.change(bc); 3567 3568 // logic from Botan 3569 if (a->sig != b->sig || a->sigalgo != b->sigalgo || akey != bkey) 3570 return false; 3571 3572 if (a->issuer != b->issuer || a->subject != b->subject) 3573 return false; 3574 if (a->serial != b->serial || a->version != b->version) 3575 return false; 3576 if (a->start != b->start || a->end != b->end) 3577 return false; 3578 3579 return true; 3580 } 3581 3582 // does a new 3583 PKeyContext *subjectPublicKey() const override 3584 { 3585 MyPKeyContext *kc = new MyPKeyContext(provider()); 3586 EVP_PKEY *pkey = X509_get_pubkey(item.cert); 3587 PKeyBase *kb = kc->pkeyToBase(pkey, false); 3588 kc->setKey(kb); 3589 return kc; 3590 } 3591 3592 bool isIssuerOf(const CertContext *other) const override 3593 { 3594 // to check a single issuer, we make a list of 1 3595 STACK_OF(X509) *untrusted_list = sk_X509_new_null(); 3596 3597 const MyCertContext *our_cc = this; 3598 X509 *x = our_cc->item.cert; 3599 X509_up_ref(x); 3600 sk_X509_push(untrusted_list, x); 3601 3602 const MyCertContext *other_cc = static_cast<const MyCertContext *>(other); 3603 X509 *ox = other_cc->item.cert; 3604 3605 X509_STORE *store = X509_STORE_new(); 3606 3607 X509_STORE_CTX *ctx = X509_STORE_CTX_new(); 3608 X509_STORE_CTX_init(ctx, store, ox, untrusted_list); 3609 3610 // we don't care about the verify result here 3611 X509_verify_cert(ctx); 3612 3613 // grab the chain, which may not be fully populated 3614 STACK_OF(X509) *chain = X509_STORE_CTX_get_chain(ctx); 3615 3616 bool ok = false; 3617 3618 // chain should be exactly 2 items 3619 QList<const MyCertContext *> expected; 3620 expected += other_cc; 3621 expected += our_cc; 3622 if (chain && sameChain(chain, expected)) 3623 ok = true; 3624 3625 // cleanup 3626 X509_STORE_CTX_free(ctx); 3627 X509_STORE_free(store); 3628 sk_X509_pop_free(untrusted_list, X509_free); 3629 3630 return ok; 3631 } 3632 3633 // implemented later because it depends on MyCRLContext 3634 Validity validate(const QList<CertContext *> &trusted, 3635 const QList<CertContext *> &untrusted, 3636 const QList<CRLContext *> &crls, 3637 UsageMode u, 3638 ValidateFlags vf) const override; 3639 3640 Validity validate_chain(const QList<CertContext *> &chain, 3641 const QList<CertContext *> &trusted, 3642 const QList<CRLContext *> &crls, 3643 UsageMode u, 3644 ValidateFlags vf) const override; 3645 3646 void make_props() 3647 { 3648 X509 *x = item.cert; 3649 CertContextProps p; 3650 3651 p.version = X509_get_version(x); 3652 3653 ASN1_INTEGER *ai = X509_get_serialNumber(x); 3654 if (ai) { 3655 char *rep = i2s_ASN1_INTEGER(nullptr, ai); 3656 QString str = QString::fromLatin1(rep); 3657 OPENSSL_free(rep); 3658 p.serial.fromString(str); 3659 } 3660 3661 p.start = ASN1_UTCTIME_QDateTime(X509_get_notBefore(x), nullptr); 3662 p.end = ASN1_UTCTIME_QDateTime(X509_get_notAfter(x), nullptr); 3663 3664 CertificateInfo subject, issuer; 3665 3666 subject = get_cert_name(X509_get_subject_name(x)); 3667 issuer = get_cert_name(X509_get_issuer_name(x)); 3668 3669 p.isSelfSigned = (X509_V_OK == X509_check_issued(x, x)); 3670 3671 p.isCA = false; 3672 p.pathLimit = 0; 3673 int pos = X509_get_ext_by_NID(x, NID_basic_constraints, -1); 3674 if (pos != -1) { 3675 X509_EXTENSION *ex = X509_get_ext(x, pos); 3676 if (ex) 3677 get_basic_constraints(ex, &p.isCA, &p.pathLimit); 3678 } 3679 3680 pos = X509_get_ext_by_NID(x, NID_subject_alt_name, -1); 3681 if (pos != -1) { 3682 X509_EXTENSION *ex = X509_get_ext(x, pos); 3683 if (ex) 3684 subject.unite(get_cert_alt_name(ex)); 3685 } 3686 3687 pos = X509_get_ext_by_NID(x, NID_issuer_alt_name, -1); 3688 if (pos != -1) { 3689 X509_EXTENSION *ex = X509_get_ext(x, pos); 3690 if (ex) 3691 issuer.unite(get_cert_alt_name(ex)); 3692 } 3693 3694 pos = X509_get_ext_by_NID(x, NID_key_usage, -1); 3695 if (pos != -1) { 3696 X509_EXTENSION *ex = X509_get_ext(x, pos); 3697 if (ex) 3698 p.constraints = get_cert_key_usage(ex); 3699 } 3700 3701 pos = X509_get_ext_by_NID(x, NID_ext_key_usage, -1); 3702 if (pos != -1) { 3703 X509_EXTENSION *ex = X509_get_ext(x, pos); 3704 if (ex) 3705 p.constraints += get_cert_ext_key_usage(ex); 3706 } 3707 3708 pos = X509_get_ext_by_NID(x, NID_certificate_policies, -1); 3709 if (pos != -1) { 3710 X509_EXTENSION *ex = X509_get_ext(x, pos); 3711 if (ex) 3712 p.policies = get_cert_policies(ex); 3713 } 3714 3715 const ASN1_BIT_STRING *signature; 3716 3717 X509_get0_signature(&signature, nullptr, x); 3718 if (signature) { 3719 p.sig = QByteArray(signature->length, 0); 3720 for (int i = 0; i < signature->length; i++) 3721 p.sig[i] = signature->data[i]; 3722 } 3723 3724 switch (X509_get_signature_nid(x)) { 3725 case NID_sha1WithRSAEncryption: 3726 p.sigalgo = QCA::EMSA3_SHA1; 3727 break; 3728 case NID_md5WithRSAEncryption: 3729 p.sigalgo = QCA::EMSA3_MD5; 3730 break; 3731 #ifdef HAVE_OPENSSL_MD2 3732 case NID_md2WithRSAEncryption: 3733 p.sigalgo = s_legacyProviderAvailable ? QCA::EMSA3_MD2 : QCA::SignatureUnknown; 3734 break; 3735 #endif 3736 case NID_ripemd160WithRSA: 3737 p.sigalgo = s_legacyProviderAvailable ? QCA::EMSA3_RIPEMD160 : QCA::SignatureUnknown; 3738 break; 3739 case NID_dsaWithSHA1: 3740 p.sigalgo = QCA::EMSA1_SHA1; 3741 break; 3742 case NID_sha224WithRSAEncryption: 3743 p.sigalgo = QCA::EMSA3_SHA224; 3744 break; 3745 case NID_sha256WithRSAEncryption: 3746 p.sigalgo = QCA::EMSA3_SHA256; 3747 break; 3748 case NID_sha384WithRSAEncryption: 3749 p.sigalgo = QCA::EMSA3_SHA384; 3750 break; 3751 case NID_sha512WithRSAEncryption: 3752 p.sigalgo = QCA::EMSA3_SHA512; 3753 break; 3754 default: 3755 qDebug() << "Unknown signature value: " << X509_get_signature_nid(x); 3756 p.sigalgo = QCA::SignatureUnknown; 3757 } 3758 3759 pos = X509_get_ext_by_NID(x, NID_subject_key_identifier, -1); 3760 if (pos != -1) { 3761 X509_EXTENSION *ex = X509_get_ext(x, pos); 3762 if (ex) 3763 p.subjectId += get_cert_subject_key_id(ex); 3764 } 3765 3766 pos = X509_get_ext_by_NID(x, NID_authority_key_identifier, -1); 3767 if (pos != -1) { 3768 X509_EXTENSION *ex = X509_get_ext(x, pos); 3769 if (ex) 3770 p.issuerId += get_cert_issuer_key_id(ex); 3771 } 3772 3773 // FIXME: super hack 3774 CertificateOptions opts; 3775 opts.setInfo(subject); 3776 p.subject = opts.infoOrdered(); 3777 opts.setInfo(issuer); 3778 p.issuer = opts.infoOrdered(); 3779 3780 _props = p; 3781 // printf("[%p] made props: [%s]\n", this, _props.subject[CommonName].toLatin1().data()); 3782 } 3783 }; 3784 3785 bool sameChain(STACK_OF(X509) * ossl, const QList<const MyCertContext *> &qca) 3786 { 3787 if (sk_X509_num(ossl) != qca.count()) 3788 return false; 3789 3790 for (int n = 0; n < sk_X509_num(ossl); ++n) { 3791 X509 *a = sk_X509_value(ossl, n); 3792 X509 *b = qca[n]->item.cert; 3793 if (X509_cmp(a, b) != 0) 3794 return false; 3795 } 3796 3797 return true; 3798 } 3799 3800 //---------------------------------------------------------------------------- 3801 // MyCAContext 3802 //---------------------------------------------------------------------------- 3803 // Thanks to Pascal Patry 3804 class MyCAContext : public CAContext 3805 { 3806 Q_OBJECT 3807 public: 3808 X509Item caCert; 3809 MyPKeyContext *privateKey; 3810 3811 MyCAContext(Provider *p) 3812 : CAContext(p) 3813 { 3814 privateKey = nullptr; 3815 } 3816 3817 MyCAContext(const MyCAContext &from) 3818 : CAContext(from) 3819 , caCert(from.caCert) 3820 { 3821 privateKey = static_cast<MyPKeyContext *>(from.privateKey->clone()); 3822 } 3823 3824 ~MyCAContext() override 3825 { 3826 delete privateKey; 3827 } 3828 3829 CertContext *certificate() const override 3830 { 3831 MyCertContext *cert = new MyCertContext(provider()); 3832 3833 cert->fromX509(caCert.cert); 3834 return cert; 3835 } 3836 3837 CertContext *createCertificate(const PKeyContext &pub, const CertificateOptions &opts) const override 3838 { 3839 // TODO: implement 3840 Q_UNUSED(pub) 3841 Q_UNUSED(opts) 3842 return nullptr; 3843 } 3844 3845 CRLContext *createCRL(const QDateTime &nextUpdate) const override 3846 { 3847 // TODO: implement 3848 Q_UNUSED(nextUpdate) 3849 return nullptr; 3850 } 3851 3852 void setup(const CertContext &cert, const PKeyContext &priv) override 3853 { 3854 caCert = static_cast<const MyCertContext &>(cert).item; 3855 delete privateKey; 3856 privateKey = nullptr; 3857 privateKey = static_cast<MyPKeyContext *>(priv.clone()); 3858 } 3859 3860 CertContext *signRequest(const CSRContext &req, const QDateTime ¬ValidAfter) const override 3861 { 3862 MyCertContext *cert = nullptr; 3863 const EVP_MD *md = nullptr; 3864 X509 *x = nullptr; 3865 const CertContextProps &props = *req.props(); 3866 CertificateOptions subjectOpts; 3867 X509_NAME *subjectName = nullptr; 3868 X509_EXTENSION *ex = nullptr; 3869 3870 if (privateKey->key()->type() == PKey::RSA) 3871 md = EVP_sha1(); 3872 else if (privateKey->key()->type() == PKey::DSA) 3873 md = EVP_sha1(); 3874 else 3875 return nullptr; 3876 3877 cert = new MyCertContext(provider()); 3878 3879 subjectOpts.setInfoOrdered(props.subject); 3880 subjectName = new_cert_name(subjectOpts.info()); 3881 3882 // create 3883 x = X509_new(); 3884 X509_set_version(x, 2); 3885 3886 // serial 3887 BIGNUM *bn = bi2bn(props.serial); 3888 BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(x)); 3889 BN_free(bn); 3890 3891 // validity period 3892 ASN1_TIME_set(X509_get_notBefore(x), QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); 3893 ASN1_TIME_set(X509_get_notAfter(x), notValidAfter.toSecsSinceEpoch()); 3894 3895 X509_set_pubkey(x, static_cast<const MyPKeyContext *>(req.subjectPublicKey())->get_pkey()); 3896 X509_set_subject_name(x, subjectName); 3897 X509_set_issuer_name(x, X509_get_subject_name(caCert.cert)); 3898 3899 // subject key id 3900 ex = new_subject_key_id(x); 3901 { 3902 X509_add_ext(x, ex, -1); 3903 X509_EXTENSION_free(ex); 3904 } 3905 3906 // CA mode 3907 ex = new_basic_constraints(props.isCA, props.pathLimit); 3908 if (ex) { 3909 X509_add_ext(x, ex, -1); 3910 X509_EXTENSION_free(ex); 3911 } 3912 3913 // subject alt name 3914 ex = new_cert_subject_alt_name(subjectOpts.info()); 3915 if (ex) { 3916 X509_add_ext(x, ex, -1); 3917 X509_EXTENSION_free(ex); 3918 } 3919 3920 // key usage 3921 ex = new_cert_key_usage(props.constraints); 3922 if (ex) { 3923 X509_add_ext(x, ex, -1); 3924 X509_EXTENSION_free(ex); 3925 } 3926 3927 // extended key usage 3928 ex = new_cert_ext_key_usage(props.constraints); 3929 if (ex) { 3930 X509_add_ext(x, ex, -1); 3931 X509_EXTENSION_free(ex); 3932 } 3933 3934 // policies 3935 ex = new_cert_policies(props.policies); 3936 if (ex) { 3937 X509_add_ext(x, ex, -1); 3938 X509_EXTENSION_free(ex); 3939 } 3940 3941 if (!X509_sign(x, privateKey->get_pkey(), md)) { 3942 X509_free(x); 3943 delete cert; 3944 return nullptr; 3945 } 3946 3947 cert->fromX509(x); 3948 X509_free(x); 3949 return cert; 3950 } 3951 3952 CRLContext * 3953 updateCRL(const CRLContext &crl, const QList<CRLEntry> &entries, const QDateTime &nextUpdate) const override 3954 { 3955 // TODO: implement 3956 Q_UNUSED(crl) 3957 Q_UNUSED(entries) 3958 Q_UNUSED(nextUpdate) 3959 return nullptr; 3960 } 3961 3962 Provider::Context *clone() const override 3963 { 3964 return new MyCAContext(*this); 3965 } 3966 }; 3967 3968 //---------------------------------------------------------------------------- 3969 // MyCSRContext 3970 //---------------------------------------------------------------------------- 3971 class MyCSRContext : public CSRContext 3972 { 3973 Q_OBJECT 3974 public: 3975 X509Item item; 3976 CertContextProps _props; 3977 3978 MyCSRContext(Provider *p) 3979 : CSRContext(p) 3980 { 3981 } 3982 3983 MyCSRContext(const MyCSRContext &from) 3984 : CSRContext(from) 3985 , item(from.item) 3986 , _props(from._props) 3987 { 3988 } 3989 3990 Provider::Context *clone() const override 3991 { 3992 return new MyCSRContext(*this); 3993 } 3994 3995 QByteArray toDER() const override 3996 { 3997 return item.toDER(); 3998 } 3999 4000 QString toPEM() const override 4001 { 4002 return item.toPEM(); 4003 } 4004 4005 ConvertResult fromDER(const QByteArray &a) override 4006 { 4007 _props = CertContextProps(); 4008 ConvertResult r = item.fromDER(a, X509Item::TypeReq); 4009 if (r == ConvertGood) 4010 make_props(); 4011 return r; 4012 } 4013 4014 ConvertResult fromPEM(const QString &s) override 4015 { 4016 _props = CertContextProps(); 4017 ConvertResult r = item.fromPEM(s, X509Item::TypeReq); 4018 if (r == ConvertGood) 4019 make_props(); 4020 return r; 4021 } 4022 4023 bool canUseFormat(CertificateRequestFormat f) const override 4024 { 4025 if (f == PKCS10) 4026 return true; 4027 return false; 4028 } 4029 4030 bool createRequest(const CertificateOptions &opts, const PKeyContext &priv) override 4031 { 4032 _props = CertContextProps(); 4033 item.reset(); 4034 4035 CertificateInfo info = opts.info(); 4036 4037 // Note: removing default constraints, let the app choose these if it wants 4038 Constraints constraints = opts.constraints(); 4039 // constraints - logic from Botan 4040 /*Constraints constraints; 4041 if(opts.isCA()) 4042 { 4043 constraints += KeyCertificateSign; 4044 constraints += CRLSign; 4045 } 4046 else 4047 constraints = find_constraints(priv, opts.constraints());*/ 4048 4049 EVP_PKEY *pk = static_cast<const MyPKeyContext *>(&priv)->get_pkey(); 4050 X509_EXTENSION *ex; 4051 4052 const EVP_MD *md; 4053 if (priv.key()->type() == PKey::RSA) 4054 md = EVP_sha1(); 4055 else if (priv.key()->type() == PKey::DSA) 4056 md = EVP_sha1(); 4057 else 4058 return false; 4059 4060 // create 4061 X509_REQ *x = X509_REQ_new(); 4062 4063 // public key 4064 X509_REQ_set_pubkey(x, pk); 4065 4066 // subject 4067 X509_NAME *name = new_cert_name(info); 4068 X509_REQ_set_subject_name(x, name); 4069 4070 // challenge 4071 const QByteArray cs = opts.challenge().toLatin1(); 4072 if (!cs.isEmpty()) 4073 X509_REQ_add1_attr_by_NID( 4074 x, NID_pkcs9_challengePassword, MBSTRING_UTF8, (const unsigned char *)cs.data(), -1); 4075 4076 STACK_OF(X509_EXTENSION) *exts = sk_X509_EXTENSION_new_null(); 4077 4078 // CA mode 4079 ex = new_basic_constraints(opts.isCA(), opts.pathLimit()); 4080 if (ex) 4081 sk_X509_EXTENSION_push(exts, ex); 4082 4083 // subject alt name 4084 ex = new_cert_subject_alt_name(info); 4085 if (ex) 4086 sk_X509_EXTENSION_push(exts, ex); 4087 4088 // key usage 4089 ex = new_cert_key_usage(constraints); 4090 if (ex) 4091 sk_X509_EXTENSION_push(exts, ex); 4092 4093 // extended key usage 4094 ex = new_cert_ext_key_usage(constraints); 4095 if (ex) 4096 sk_X509_EXTENSION_push(exts, ex); 4097 4098 // policies 4099 ex = new_cert_policies(opts.policies()); 4100 if (ex) 4101 sk_X509_EXTENSION_push(exts, ex); 4102 4103 if (sk_X509_EXTENSION_num(exts) > 0) 4104 X509_REQ_add_extensions(x, exts); 4105 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); 4106 4107 // finished 4108 X509_REQ_sign(x, pk, md); 4109 4110 item.req = x; 4111 make_props(); 4112 return true; 4113 } 4114 4115 const CertContextProps *props() const override 4116 { 4117 return &_props; 4118 } 4119 4120 bool compare(const CSRContext *other) const override 4121 { 4122 const CertContextProps *a = &_props; 4123 const CertContextProps *b = other->props(); 4124 4125 PublicKey akey, bkey; 4126 PKeyContext *ac = subjectPublicKey(); 4127 akey.change(ac); 4128 PKeyContext *bc = other->subjectPublicKey(); 4129 bkey.change(bc); 4130 4131 if (a->sig != b->sig || a->sigalgo != b->sigalgo || akey != bkey) 4132 return false; 4133 4134 // TODO: Anything else we should compare? 4135 4136 return true; 4137 } 4138 4139 PKeyContext *subjectPublicKey() const override // does a new 4140 { 4141 MyPKeyContext *kc = new MyPKeyContext(provider()); 4142 EVP_PKEY *pkey = X509_REQ_get_pubkey(item.req); 4143 PKeyBase *kb = kc->pkeyToBase(pkey, false); 4144 kc->setKey(kb); 4145 return kc; 4146 } 4147 4148 QString toSPKAC() const override 4149 { 4150 return QString(); 4151 } 4152 4153 ConvertResult fromSPKAC(const QString &s) override 4154 { 4155 Q_UNUSED(s); 4156 return ErrorDecode; 4157 } 4158 4159 void make_props() 4160 { 4161 X509_REQ *x = item.req; 4162 CertContextProps p; 4163 4164 // TODO: QString challenge; 4165 4166 p.format = PKCS10; 4167 4168 CertificateInfo subject; 4169 4170 subject = get_cert_name(X509_REQ_get_subject_name(x)); 4171 4172 STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(x); 4173 4174 p.isCA = false; 4175 p.pathLimit = 0; 4176 int pos = X509v3_get_ext_by_NID(exts, NID_basic_constraints, -1); 4177 if (pos != -1) { 4178 X509_EXTENSION *ex = X509v3_get_ext(exts, pos); 4179 if (ex) 4180 get_basic_constraints(ex, &p.isCA, &p.pathLimit); 4181 } 4182 4183 pos = X509v3_get_ext_by_NID(exts, NID_subject_alt_name, -1); 4184 if (pos != -1) { 4185 X509_EXTENSION *ex = X509v3_get_ext(exts, pos); 4186 if (ex) 4187 subject.unite(get_cert_alt_name(ex)); 4188 } 4189 4190 pos = X509v3_get_ext_by_NID(exts, NID_key_usage, -1); 4191 if (pos != -1) { 4192 X509_EXTENSION *ex = X509v3_get_ext(exts, pos); 4193 if (ex) 4194 p.constraints = get_cert_key_usage(ex); 4195 } 4196 4197 pos = X509v3_get_ext_by_NID(exts, NID_ext_key_usage, -1); 4198 if (pos != -1) { 4199 X509_EXTENSION *ex = X509v3_get_ext(exts, pos); 4200 if (ex) 4201 p.constraints += get_cert_ext_key_usage(ex); 4202 } 4203 4204 pos = X509v3_get_ext_by_NID(exts, NID_certificate_policies, -1); 4205 if (pos != -1) { 4206 X509_EXTENSION *ex = X509v3_get_ext(exts, pos); 4207 if (ex) 4208 p.policies = get_cert_policies(ex); 4209 } 4210 4211 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); 4212 4213 const ASN1_BIT_STRING *signature; 4214 4215 X509_REQ_get0_signature(x, &signature, nullptr); 4216 if (signature) { 4217 p.sig = QByteArray(signature->length, 0); 4218 for (int i = 0; i < signature->length; i++) 4219 p.sig[i] = signature->data[i]; 4220 } 4221 4222 switch (X509_REQ_get_signature_nid(x)) { 4223 case NID_sha1WithRSAEncryption: 4224 p.sigalgo = QCA::EMSA3_SHA1; 4225 break; 4226 case NID_md5WithRSAEncryption: 4227 p.sigalgo = QCA::EMSA3_MD5; 4228 break; 4229 #ifdef HAVE_OPENSSL_MD2 4230 case NID_md2WithRSAEncryption: 4231 p.sigalgo = s_legacyProviderAvailable ? QCA::EMSA3_MD2 : QCA::SignatureUnknown; 4232 break; 4233 #endif 4234 case NID_ripemd160WithRSA: 4235 p.sigalgo = s_legacyProviderAvailable ? QCA::EMSA3_RIPEMD160 : QCA::SignatureUnknown; 4236 break; 4237 case NID_dsaWithSHA1: 4238 p.sigalgo = QCA::EMSA1_SHA1; 4239 break; 4240 default: 4241 qDebug() << "Unknown signature value: " << X509_REQ_get_signature_nid(x); 4242 p.sigalgo = QCA::SignatureUnknown; 4243 } 4244 4245 // FIXME: super hack 4246 CertificateOptions opts; 4247 opts.setInfo(subject); 4248 p.subject = opts.infoOrdered(); 4249 4250 _props = p; 4251 } 4252 }; 4253 4254 //---------------------------------------------------------------------------- 4255 // MyCRLContext 4256 //---------------------------------------------------------------------------- 4257 class MyCRLContext : public CRLContext 4258 { 4259 Q_OBJECT 4260 public: 4261 X509Item item; 4262 CRLContextProps _props; 4263 4264 MyCRLContext(Provider *p) 4265 : CRLContext(p) 4266 { 4267 } 4268 4269 MyCRLContext(const MyCRLContext &from) 4270 : CRLContext(from) 4271 , item(from.item) 4272 { 4273 } 4274 4275 Provider::Context *clone() const override 4276 { 4277 return new MyCRLContext(*this); 4278 } 4279 4280 QByteArray toDER() const override 4281 { 4282 return item.toDER(); 4283 } 4284 4285 QString toPEM() const override 4286 { 4287 return item.toPEM(); 4288 } 4289 4290 ConvertResult fromDER(const QByteArray &a) override 4291 { 4292 _props = CRLContextProps(); 4293 ConvertResult r = item.fromDER(a, X509Item::TypeCRL); 4294 if (r == ConvertGood) 4295 make_props(); 4296 return r; 4297 } 4298 4299 ConvertResult fromPEM(const QString &s) override 4300 { 4301 ConvertResult r = item.fromPEM(s, X509Item::TypeCRL); 4302 if (r == ConvertGood) 4303 make_props(); 4304 return r; 4305 } 4306 4307 void fromX509(X509_CRL *x) 4308 { 4309 X509_CRL_up_ref(x); 4310 item.crl = x; 4311 make_props(); 4312 } 4313 4314 const CRLContextProps *props() const override 4315 { 4316 return &_props; 4317 } 4318 4319 bool compare(const CRLContext *other) const override 4320 { 4321 const CRLContextProps *a = &_props; 4322 const CRLContextProps *b = other->props(); 4323 4324 if (a->issuer != b->issuer) 4325 return false; 4326 if (a->number != b->number) 4327 return false; 4328 if (a->thisUpdate != b->thisUpdate) 4329 return false; 4330 if (a->nextUpdate != b->nextUpdate) 4331 return false; 4332 if (a->revoked != b->revoked) 4333 return false; 4334 if (a->sig != b->sig) 4335 return false; 4336 if (a->sigalgo != b->sigalgo) 4337 return false; 4338 if (a->issuerId != b->issuerId) 4339 return false; 4340 4341 return true; 4342 } 4343 4344 void make_props() 4345 { 4346 X509_CRL *x = item.crl; 4347 4348 CRLContextProps p; 4349 4350 CertificateInfo issuer; 4351 4352 issuer = get_cert_name(X509_CRL_get_issuer(x)); 4353 4354 p.thisUpdate = ASN1_UTCTIME_QDateTime(X509_CRL_get0_lastUpdate(x), nullptr); 4355 p.nextUpdate = ASN1_UTCTIME_QDateTime(X509_CRL_get0_nextUpdate(x), nullptr); 4356 4357 STACK_OF(X509_REVOKED) *revokeStack = X509_CRL_get_REVOKED(x); 4358 4359 for (int i = 0; i < sk_X509_REVOKED_num(revokeStack); ++i) { 4360 X509_REVOKED *rev = sk_X509_REVOKED_value(revokeStack, i); 4361 BigInteger serial = bn2bi_free(ASN1_INTEGER_to_BN(X509_REVOKED_get0_serialNumber(rev), nullptr)); 4362 QDateTime time = ASN1_UTCTIME_QDateTime(X509_REVOKED_get0_revocationDate(rev), nullptr); 4363 QCA::CRLEntry::Reason reason = QCA::CRLEntry::Unspecified; 4364 int pos = X509_REVOKED_get_ext_by_NID(rev, NID_crl_reason, -1); 4365 if (pos != -1) { 4366 X509_EXTENSION *ex = X509_REVOKED_get_ext(rev, pos); 4367 if (ex) { 4368 ASN1_ENUMERATED *result = (ASN1_ENUMERATED *)X509V3_EXT_d2i(ex); 4369 switch (ASN1_ENUMERATED_get(result)) { 4370 case CRL_REASON_UNSPECIFIED: 4371 reason = QCA::CRLEntry::Unspecified; 4372 break; 4373 case CRL_REASON_KEY_COMPROMISE: 4374 reason = QCA::CRLEntry::KeyCompromise; 4375 break; 4376 case CRL_REASON_CA_COMPROMISE: 4377 reason = QCA::CRLEntry::CACompromise; 4378 break; 4379 case CRL_REASON_AFFILIATION_CHANGED: 4380 reason = QCA::CRLEntry::AffiliationChanged; 4381 break; 4382 case CRL_REASON_SUPERSEDED: 4383 reason = QCA::CRLEntry::Superseded; 4384 break; 4385 case CRL_REASON_CESSATION_OF_OPERATION: 4386 reason = QCA::CRLEntry::CessationOfOperation; 4387 break; 4388 case CRL_REASON_CERTIFICATE_HOLD: 4389 reason = QCA::CRLEntry::CertificateHold; 4390 break; 4391 case CRL_REASON_REMOVE_FROM_CRL: 4392 reason = QCA::CRLEntry::RemoveFromCRL; 4393 break; 4394 case CRL_REASON_PRIVILEGE_WITHDRAWN: 4395 reason = QCA::CRLEntry::PrivilegeWithdrawn; 4396 break; 4397 case CRL_REASON_AA_COMPROMISE: 4398 reason = QCA::CRLEntry::AACompromise; 4399 break; 4400 default: 4401 reason = QCA::CRLEntry::Unspecified; 4402 break; 4403 } 4404 ASN1_ENUMERATED_free(result); 4405 } 4406 } 4407 CRLEntry thisEntry(serial, time, reason); 4408 p.revoked.append(thisEntry); 4409 } 4410 4411 const ASN1_BIT_STRING *signature; 4412 4413 X509_CRL_get0_signature(x, &signature, nullptr); 4414 if (signature) { 4415 p.sig = QByteArray(signature->length, 0); 4416 for (int i = 0; i < signature->length; i++) 4417 p.sig[i] = signature->data[i]; 4418 } 4419 4420 switch (X509_CRL_get_signature_nid(x)) { 4421 case NID_sha1WithRSAEncryption: 4422 p.sigalgo = QCA::EMSA3_SHA1; 4423 break; 4424 case NID_md5WithRSAEncryption: 4425 p.sigalgo = QCA::EMSA3_MD5; 4426 break; 4427 #ifdef HAVE_OPENSSL_MD2 4428 case NID_md2WithRSAEncryption: 4429 p.sigalgo = s_legacyProviderAvailable ? QCA::EMSA3_MD2 : QCA::SignatureUnknown; 4430 break; 4431 #endif 4432 case NID_ripemd160WithRSA: 4433 p.sigalgo = s_legacyProviderAvailable ? QCA::EMSA3_RIPEMD160 : QCA::SignatureUnknown; 4434 break; 4435 case NID_dsaWithSHA1: 4436 p.sigalgo = QCA::EMSA1_SHA1; 4437 break; 4438 case NID_sha224WithRSAEncryption: 4439 p.sigalgo = QCA::EMSA3_SHA224; 4440 break; 4441 case NID_sha256WithRSAEncryption: 4442 p.sigalgo = QCA::EMSA3_SHA256; 4443 break; 4444 case NID_sha384WithRSAEncryption: 4445 p.sigalgo = QCA::EMSA3_SHA384; 4446 break; 4447 case NID_sha512WithRSAEncryption: 4448 p.sigalgo = QCA::EMSA3_SHA512; 4449 break; 4450 default: 4451 qWarning() << "Unknown signature value: " << X509_CRL_get_signature_nid(x); 4452 p.sigalgo = QCA::SignatureUnknown; 4453 } 4454 4455 int pos = X509_CRL_get_ext_by_NID(x, NID_authority_key_identifier, -1); 4456 if (pos != -1) { 4457 X509_EXTENSION *ex = X509_CRL_get_ext(x, pos); 4458 if (ex) 4459 p.issuerId += get_cert_issuer_key_id(ex); 4460 } 4461 4462 p.number = -1; 4463 pos = X509_CRL_get_ext_by_NID(x, NID_crl_number, -1); 4464 if (pos != -1) { 4465 X509_EXTENSION *ex = X509_CRL_get_ext(x, pos); 4466 if (ex) { 4467 ASN1_INTEGER *result = (ASN1_INTEGER *)X509V3_EXT_d2i(ex); 4468 p.number = ASN1_INTEGER_get(result); 4469 ASN1_INTEGER_free(result); 4470 } 4471 } 4472 4473 // FIXME: super hack 4474 CertificateOptions opts; 4475 opts.setInfo(issuer); 4476 p.issuer = opts.infoOrdered(); 4477 4478 _props = p; 4479 } 4480 }; 4481 4482 //---------------------------------------------------------------------------- 4483 // MyCertCollectionContext 4484 //---------------------------------------------------------------------------- 4485 class MyCertCollectionContext : public CertCollectionContext 4486 { 4487 Q_OBJECT 4488 public: 4489 MyCertCollectionContext(Provider *p) 4490 : CertCollectionContext(p) 4491 { 4492 } 4493 4494 Provider::Context *clone() const override 4495 { 4496 return new MyCertCollectionContext(*this); 4497 } 4498 4499 QByteArray toPKCS7(const QList<CertContext *> &certs, const QList<CRLContext *> &crls) const override 4500 { 4501 // TODO: implement 4502 Q_UNUSED(certs); 4503 Q_UNUSED(crls); 4504 return QByteArray(); 4505 } 4506 4507 ConvertResult fromPKCS7(const QByteArray &a, QList<CertContext *> *certs, QList<CRLContext *> *crls) const override 4508 { 4509 BIO *bi = BIO_new(BIO_s_mem()); 4510 BIO_write(bi, a.data(), a.size()); 4511 PKCS7 *p7 = d2i_PKCS7_bio(bi, nullptr); 4512 BIO_free(bi); 4513 if (!p7) 4514 return ErrorDecode; 4515 4516 STACK_OF(X509) *xcerts = nullptr; 4517 STACK_OF(X509_CRL) *xcrls = nullptr; 4518 4519 int i = OBJ_obj2nid(p7->type); 4520 if (i == NID_pkcs7_signed) { 4521 xcerts = p7->d.sign->cert; 4522 xcrls = p7->d.sign->crl; 4523 } else if (i == NID_pkcs7_signedAndEnveloped) { 4524 xcerts = p7->d.signed_and_enveloped->cert; 4525 xcrls = p7->d.signed_and_enveloped->crl; 4526 } 4527 4528 QList<CertContext *> _certs; 4529 QList<CRLContext *> _crls; 4530 4531 if (xcerts) { 4532 for (int n = 0; n < sk_X509_num(xcerts); ++n) { 4533 MyCertContext *cc = new MyCertContext(provider()); 4534 cc->fromX509(sk_X509_value(xcerts, n)); 4535 _certs += cc; 4536 } 4537 } 4538 if (xcrls) { 4539 for (int n = 0; n < sk_X509_CRL_num(xcrls); ++n) { 4540 MyCRLContext *cc = new MyCRLContext(provider()); 4541 cc->fromX509(sk_X509_CRL_value(xcrls, n)); 4542 _crls += cc; 4543 } 4544 } 4545 4546 PKCS7_free(p7); 4547 4548 *certs = _certs; 4549 *crls = _crls; 4550 4551 return ConvertGood; 4552 } 4553 }; 4554 4555 static bool usage_check(const MyCertContext &cc, UsageMode u) 4556 { 4557 if (cc._props.constraints.isEmpty()) { 4558 // then any usage is OK 4559 return true; 4560 } 4561 4562 switch (u) { 4563 case UsageAny: 4564 return true; 4565 break; 4566 case UsageTLSServer: 4567 return cc._props.constraints.contains(ServerAuth); 4568 break; 4569 case UsageTLSClient: 4570 return cc._props.constraints.contains(ClientAuth); 4571 break; 4572 case UsageCodeSigning: 4573 return cc._props.constraints.contains(CodeSigning); 4574 break; 4575 case UsageEmailProtection: 4576 return cc._props.constraints.contains(EmailProtection); 4577 break; 4578 case UsageTimeStamping: 4579 return cc._props.constraints.contains(TimeStamping); 4580 break; 4581 case UsageCRLSigning: 4582 return cc._props.constraints.contains(CRLSign); 4583 break; 4584 default: 4585 return true; 4586 } 4587 } 4588 4589 Validity MyCertContext::validate(const QList<CertContext *> &trusted, 4590 const QList<CertContext *> &untrusted, 4591 const QList<CRLContext *> &crls, 4592 UsageMode u, 4593 ValidateFlags vf) const 4594 { 4595 // TODO 4596 Q_UNUSED(vf); 4597 4598 STACK_OF(X509) *trusted_list = sk_X509_new_null(); 4599 STACK_OF(X509) *untrusted_list = sk_X509_new_null(); 4600 QList<X509_CRL *> crl_list; 4601 4602 int n; 4603 for (n = 0; n < trusted.count(); ++n) { 4604 const MyCertContext *cc = static_cast<const MyCertContext *>(trusted[n]); 4605 X509 *x = cc->item.cert; 4606 X509_up_ref(x); 4607 sk_X509_push(trusted_list, x); 4608 } 4609 for (n = 0; n < untrusted.count(); ++n) { 4610 const MyCertContext *cc = static_cast<const MyCertContext *>(untrusted[n]); 4611 X509 *x = cc->item.cert; 4612 X509_up_ref(x); 4613 sk_X509_push(untrusted_list, x); 4614 } 4615 for (n = 0; n < crls.count(); ++n) { 4616 const MyCRLContext *cc = static_cast<const MyCRLContext *>(crls[n]); 4617 X509_CRL *x = cc->item.crl; 4618 X509_CRL_up_ref(x); 4619 crl_list.append(x); 4620 } 4621 4622 const MyCertContext *cc = this; 4623 X509 *x = cc->item.cert; 4624 4625 // verification happens through a store "context" 4626 X509_STORE_CTX *ctx = X509_STORE_CTX_new(); 4627 4628 // make a store of crls 4629 X509_STORE *store = X509_STORE_new(); 4630 for (int n = 0; n < crl_list.count(); ++n) 4631 X509_STORE_add_crl(store, crl_list[n]); 4632 4633 // the first initialization handles untrusted certs, crls, and target cert 4634 X509_STORE_CTX_init(ctx, store, x, untrusted_list); 4635 4636 // this initializes the trusted certs 4637 X509_STORE_CTX_trusted_stack(ctx, trusted_list); 4638 4639 // verify! 4640 int ret = X509_verify_cert(ctx); 4641 int err = -1; 4642 if (!ret) 4643 err = X509_STORE_CTX_get_error(ctx); 4644 4645 // cleanup 4646 X509_STORE_CTX_free(ctx); 4647 X509_STORE_free(store); 4648 4649 sk_X509_pop_free(trusted_list, X509_free); 4650 sk_X509_pop_free(untrusted_list, X509_free); 4651 for (int n = 0; n < crl_list.count(); ++n) 4652 X509_CRL_free(crl_list[n]); 4653 4654 if (!ret) 4655 return convert_verify_error(err); 4656 4657 if (!usage_check(*cc, u)) 4658 return ErrorInvalidPurpose; 4659 4660 return ValidityGood; 4661 } 4662 4663 Validity MyCertContext::validate_chain(const QList<CertContext *> &chain, 4664 const QList<CertContext *> &trusted, 4665 const QList<CRLContext *> &crls, 4666 UsageMode u, 4667 ValidateFlags vf) const 4668 { 4669 // TODO 4670 Q_UNUSED(vf); 4671 4672 STACK_OF(X509) *trusted_list = sk_X509_new_null(); 4673 STACK_OF(X509) *untrusted_list = sk_X509_new_null(); 4674 QList<X509_CRL *> crl_list; 4675 4676 int n; 4677 for (n = 0; n < trusted.count(); ++n) { 4678 const MyCertContext *cc = static_cast<const MyCertContext *>(trusted[n]); 4679 X509 *x = cc->item.cert; 4680 X509_up_ref(x); 4681 sk_X509_push(trusted_list, x); 4682 } 4683 for (n = 1; n < chain.count(); ++n) { 4684 const MyCertContext *cc = static_cast<const MyCertContext *>(chain[n]); 4685 X509 *x = cc->item.cert; 4686 X509_up_ref(x); 4687 sk_X509_push(untrusted_list, x); 4688 } 4689 for (n = 0; n < crls.count(); ++n) { 4690 const MyCRLContext *cc = static_cast<const MyCRLContext *>(crls[n]); 4691 X509_CRL *x = cc->item.crl; 4692 X509_CRL_up_ref(x); 4693 crl_list.append(x); 4694 } 4695 4696 const MyCertContext *cc = static_cast<const MyCertContext *>(chain[0]); 4697 X509 *x = cc->item.cert; 4698 4699 // verification happens through a store "context" 4700 X509_STORE_CTX *ctx = X509_STORE_CTX_new(); 4701 4702 // make a store of crls 4703 X509_STORE *store = X509_STORE_new(); 4704 for (int n = 0; n < crl_list.count(); ++n) 4705 X509_STORE_add_crl(store, crl_list[n]); 4706 4707 // the first initialization handles untrusted certs, crls, and target cert 4708 X509_STORE_CTX_init(ctx, store, x, untrusted_list); 4709 4710 // this initializes the trusted certs 4711 X509_STORE_CTX_trusted_stack(ctx, trusted_list); 4712 4713 // verify! 4714 int ret = X509_verify_cert(ctx); 4715 int err = -1; 4716 if (!ret) 4717 err = X509_STORE_CTX_get_error(ctx); 4718 4719 // grab the chain, which may not be fully populated 4720 STACK_OF(X509) *xchain = X509_STORE_CTX_get_chain(ctx); 4721 4722 // make sure the chain is what we expect. the reason we need to do 4723 // this is because I don't think openssl cares about the order of 4724 // input. that is, if there's a chain A<-B<-C, and we input A as 4725 // the base cert, with B and C as the issuers, we will get a 4726 // successful validation regardless of whether the issuer list is 4727 // in the order B,C or C,B. we don't want an input chain of A,C,B 4728 // to be considered correct, so we must account for that here. 4729 QList<const MyCertContext *> expected; 4730 for (int n = 0; n < chain.count(); ++n) 4731 expected += static_cast<const MyCertContext *>(chain[n]); 4732 if (!xchain || !sameChain(xchain, expected)) 4733 err = ErrorValidityUnknown; 4734 4735 // cleanup 4736 X509_STORE_CTX_free(ctx); 4737 X509_STORE_free(store); 4738 4739 sk_X509_pop_free(trusted_list, X509_free); 4740 sk_X509_pop_free(untrusted_list, X509_free); 4741 for (int n = 0; n < crl_list.count(); ++n) 4742 X509_CRL_free(crl_list[n]); 4743 4744 if (!ret) 4745 return convert_verify_error(err); 4746 4747 if (!usage_check(*cc, u)) 4748 return ErrorInvalidPurpose; 4749 4750 return ValidityGood; 4751 } 4752 4753 class MyPKCS12Context : public PKCS12Context 4754 { 4755 Q_OBJECT 4756 public: 4757 MyPKCS12Context(Provider *p) 4758 : PKCS12Context(p) 4759 { 4760 } 4761 4762 ~MyPKCS12Context() override 4763 { 4764 } 4765 4766 Provider::Context *clone() const override 4767 { 4768 return nullptr; 4769 } 4770 4771 QByteArray toPKCS12(const QString &name, 4772 const QList<const CertContext *> &chain, 4773 const PKeyContext &priv, 4774 const SecureArray &passphrase) const override 4775 { 4776 if (chain.count() < 1) 4777 return QByteArray(); 4778 4779 X509 *cert = static_cast<const MyCertContext *>(chain[0])->item.cert; 4780 STACK_OF(X509) *ca = sk_X509_new_null(); 4781 if (chain.count() > 1) { 4782 for (int n = 1; n < chain.count(); ++n) { 4783 X509 *x = static_cast<const MyCertContext *>(chain[n])->item.cert; 4784 X509_up_ref(x); 4785 sk_X509_push(ca, x); 4786 } 4787 } 4788 const MyPKeyContext &pk = static_cast<const MyPKeyContext &>(priv); 4789 PKCS12 *p12 = PKCS12_create( 4790 (char *)passphrase.data(), (char *)name.toLatin1().data(), pk.get_pkey(), cert, ca, 0, 0, 0, 0, 0); 4791 sk_X509_pop_free(ca, X509_free); 4792 4793 if (!p12) 4794 return QByteArray(); 4795 4796 BIO *bo = BIO_new(BIO_s_mem()); 4797 i2d_PKCS12_bio(bo, p12); 4798 const QByteArray out = bio2ba(bo); 4799 return out; 4800 } 4801 4802 ConvertResult fromPKCS12(const QByteArray &in, 4803 const SecureArray &passphrase, 4804 QString *name, 4805 QList<CertContext *> *chain, 4806 PKeyContext **priv) const override 4807 { 4808 BIO *bi = BIO_new(BIO_s_mem()); 4809 BIO_write(bi, in.data(), in.size()); 4810 PKCS12 *p12 = d2i_PKCS12_bio(bi, nullptr); 4811 BIO_free(bi); 4812 if (!p12) 4813 return ErrorDecode; 4814 4815 EVP_PKEY *pkey; 4816 X509 *cert; 4817 STACK_OF(X509) *ca = nullptr; 4818 if (!PKCS12_parse(p12, passphrase.data(), &pkey, &cert, &ca)) { 4819 PKCS12_free(p12); 4820 return ErrorDecode; 4821 } 4822 PKCS12_free(p12); 4823 4824 // require private key 4825 if (!pkey) { 4826 if (cert) 4827 X509_free(cert); 4828 if (ca) 4829 sk_X509_pop_free(ca, X509_free); 4830 return ErrorDecode; 4831 } 4832 4833 // TODO: require cert 4834 4835 int aliasLength; 4836 char *aliasData = (char *)X509_alias_get0(cert, &aliasLength); 4837 *name = QString::fromLatin1(aliasData, aliasLength); 4838 4839 MyPKeyContext *pk = new MyPKeyContext(provider()); 4840 PKeyBase *k = pk->pkeyToBase(pkey, true); // does an EVP_PKEY_free() 4841 if (!k) { 4842 delete pk; 4843 if (cert) 4844 X509_free(cert); 4845 if (ca) 4846 sk_X509_pop_free(ca, X509_free); 4847 return ErrorDecode; 4848 } 4849 pk->k = k; 4850 *priv = pk; 4851 4852 QList<CertContext *> certs; 4853 if (cert) { 4854 MyCertContext *cc = new MyCertContext(provider()); 4855 cc->fromX509(cert); 4856 certs.append(cc); 4857 X509_free(cert); 4858 } 4859 if (ca) { 4860 // TODO: reorder in chain-order? 4861 // TODO: throw out certs that don't fit the chain? 4862 for (int n = 0; n < sk_X509_num(ca); ++n) { 4863 MyCertContext *cc = new MyCertContext(provider()); 4864 cc->fromX509(sk_X509_value(ca, n)); 4865 certs.append(cc); 4866 } 4867 sk_X509_pop_free(ca, X509_free); 4868 } 4869 4870 // reorder, throw out 4871 QCA::CertificateChain ch; 4872 for (int n = 0; n < certs.count(); ++n) { 4873 QCA::Certificate cert; 4874 cert.change(certs[n]); 4875 ch += cert; 4876 } 4877 certs.clear(); 4878 ch = ch.complete(QList<QCA::Certificate>()); 4879 for (int n = 0; n < ch.count(); ++n) { 4880 MyCertContext *cc = (MyCertContext *)ch[n].context(); 4881 certs += (new MyCertContext(*cc)); 4882 } 4883 ch.clear(); 4884 4885 *chain = certs; 4886 return ConvertGood; 4887 } 4888 }; 4889 4890 // TODO: test to ensure there is no cert-test lag 4891 static bool ssl_init = false; 4892 class MyTLSContext : public TLSContext 4893 { 4894 Q_OBJECT 4895 public: 4896 enum 4897 { 4898 Good, 4899 TryAgain, 4900 Bad 4901 }; 4902 enum 4903 { 4904 Idle, 4905 Connect, 4906 Accept, 4907 Handshake, 4908 Active, 4909 Closing 4910 }; 4911 4912 bool serv; // true if we are acting as a server 4913 int mode; 4914 QByteArray sendQueue; 4915 QByteArray recvQueue; 4916 4917 CertificateCollection trusted; 4918 Certificate cert, peercert; // TODO: support cert chains 4919 PrivateKey key; 4920 QString targetHostName; 4921 4922 Result result_result; 4923 QByteArray result_to_net; 4924 int result_encoded; 4925 QByteArray result_plain; 4926 4927 SSL *ssl; 4928 const SSL_METHOD *method; 4929 SSL_CTX *context; 4930 BIO *rbio, *wbio; 4931 Validity vr; 4932 bool v_eof; 4933 4934 MyTLSContext(Provider *p) 4935 : TLSContext(p, QStringLiteral("tls")) 4936 { 4937 if (!ssl_init) { 4938 SSL_library_init(); 4939 SSL_load_error_strings(); 4940 ssl_init = true; 4941 } 4942 4943 ssl = nullptr; 4944 context = nullptr; 4945 reset(); 4946 } 4947 4948 ~MyTLSContext() override 4949 { 4950 reset(); 4951 } 4952 4953 Provider::Context *clone() const override 4954 { 4955 return nullptr; 4956 } 4957 4958 void reset() override 4959 { 4960 if (ssl) { 4961 SSL_free(ssl); 4962 ssl = nullptr; 4963 } 4964 if (context) { 4965 SSL_CTX_free(context); 4966 context = nullptr; 4967 } 4968 4969 cert = Certificate(); 4970 key = PrivateKey(); 4971 4972 sendQueue.resize(0); 4973 recvQueue.resize(0); 4974 mode = Idle; 4975 peercert = Certificate(); 4976 vr = ErrorValidityUnknown; 4977 v_eof = false; 4978 } 4979 4980 // dummy verification function for SSL_set_verify() 4981 static int ssl_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) 4982 { 4983 Q_UNUSED(preverify_ok); 4984 Q_UNUSED(x509_ctx); 4985 4986 // don't terminate handshake in case of verification failure 4987 return 1; 4988 } 4989 4990 QStringList supportedCipherSuites(const TLS::Version &version) const override 4991 { 4992 OpenSSL_add_ssl_algorithms(); 4993 SSL_CTX *ctx = nullptr; 4994 switch (version) { 4995 #ifndef OPENSSL_NO_SSL3_METHOD 4996 case TLS::SSL_v3: 4997 // Here should be used TLS_client_method() but on Fedora 4998 // it doesn't return any SSL ciphers. 4999 ctx = SSL_CTX_new(SSLv3_client_method()); 5000 SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION); 5001 SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION); 5002 break; 5003 #endif 5004 case TLS::TLS_v1: 5005 ctx = SSL_CTX_new(TLS_client_method()); 5006 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); 5007 SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION); 5008 break; 5009 case TLS::DTLS_v1: 5010 default: 5011 /* should not happen - should be in a "dtls" provider*/ 5012 qWarning("Unexpected enum in cipherSuites"); 5013 ctx = nullptr; 5014 } 5015 if (nullptr == ctx) 5016 return QStringList(); 5017 5018 SSL *ssl = SSL_new(ctx); 5019 if (nullptr == ssl) { 5020 SSL_CTX_free(ctx); 5021 return QStringList(); 5022 } 5023 5024 STACK_OF(SSL_CIPHER) *sk = SSL_get1_supported_ciphers(ssl); 5025 QStringList cipherList; 5026 for (int i = 0; i < sk_SSL_CIPHER_num(sk); ++i) { 5027 const SSL_CIPHER *thisCipher = sk_SSL_CIPHER_value(sk, i); 5028 cipherList += QString::fromLatin1(SSL_CIPHER_standard_name(thisCipher)); 5029 } 5030 sk_SSL_CIPHER_free(sk); 5031 5032 SSL_free(ssl); 5033 SSL_CTX_free(ctx); 5034 5035 return cipherList; 5036 } 5037 5038 bool canCompress() const override 5039 { 5040 // TODO 5041 return false; 5042 } 5043 5044 bool canSetHostName() const override 5045 { 5046 // TODO 5047 return false; 5048 } 5049 5050 int maxSSF() const override 5051 { 5052 // TODO 5053 return 256; 5054 } 5055 5056 void setConstraints(int minSSF, int maxSSF) override 5057 { 5058 // TODO 5059 Q_UNUSED(minSSF); 5060 Q_UNUSED(maxSSF); 5061 } 5062 5063 void setConstraints(const QStringList &cipherSuiteList) override 5064 { 5065 // TODO 5066 Q_UNUSED(cipherSuiteList); 5067 } 5068 5069 void setup(bool serverMode, const QString &hostName, bool compress) override 5070 { 5071 serv = serverMode; 5072 if (false == serverMode) { 5073 // client 5074 targetHostName = hostName; 5075 } 5076 Q_UNUSED(compress); // TODO 5077 } 5078 5079 void setTrustedCertificates(const CertificateCollection &_trusted) override 5080 { 5081 trusted = _trusted; 5082 } 5083 5084 void setIssuerList(const QList<CertificateInfoOrdered> &issuerList) override 5085 { 5086 Q_UNUSED(issuerList); // TODO 5087 } 5088 5089 void setCertificate(const CertificateChain &_cert, const PrivateKey &_key) override 5090 { 5091 if (!_cert.isEmpty()) 5092 cert = _cert.primary(); // TODO: take the whole chain 5093 key = _key; 5094 } 5095 5096 void setSessionId(const TLSSessionContext &id) override 5097 { 5098 // TODO 5099 Q_UNUSED(id); 5100 } 5101 5102 void shutdown() override 5103 { 5104 mode = Closing; 5105 } 5106 5107 void start() override 5108 { 5109 bool ok; 5110 if (serv) 5111 ok = priv_startServer(); 5112 else 5113 ok = priv_startClient(); 5114 result_result = ok ? Success : Error; 5115 5116 doResultsReady(); 5117 } 5118 5119 void update(const QByteArray &from_net, const QByteArray &from_app) override 5120 { 5121 if (mode == Active) { 5122 bool ok = true; 5123 if (!from_app.isEmpty()) 5124 ok = priv_encode(from_app, &result_to_net, &result_encoded); 5125 if (ok) 5126 ok = priv_decode(from_net, &result_plain, &result_to_net); 5127 result_result = ok ? Success : Error; 5128 } else if (mode == Closing) 5129 result_result = priv_shutdown(from_net, &result_to_net); 5130 else 5131 result_result = priv_handshake(from_net, &result_to_net); 5132 5133 // printf("update (from_net=%d, to_net=%d, from_app=%d, to_app=%d)\n", from_net.size(), result_to_net.size(), 5134 // from_app.size(), result_plain.size()); 5135 5136 doResultsReady(); 5137 } 5138 5139 bool priv_startClient() 5140 { 5141 // serv = false; 5142 method = SSLv23_client_method(); 5143 if (!init()) 5144 return false; 5145 mode = Connect; 5146 return true; 5147 } 5148 5149 bool priv_startServer() 5150 { 5151 // serv = true; 5152 method = SSLv23_server_method(); 5153 if (!init()) 5154 return false; 5155 mode = Accept; 5156 return true; 5157 } 5158 5159 Result priv_handshake(const QByteArray &from_net, QByteArray *to_net) 5160 { 5161 if (!from_net.isEmpty()) 5162 BIO_write(rbio, from_net.data(), from_net.size()); 5163 5164 if (mode == Connect) { 5165 int ret = doConnect(); 5166 if (ret == Good) { 5167 mode = Handshake; 5168 } else if (ret == Bad) { 5169 reset(); 5170 return Error; 5171 } 5172 } 5173 5174 if (mode == Accept) { 5175 int ret = doAccept(); 5176 if (ret == Good) { 5177 getCert(); 5178 mode = Active; 5179 } else if (ret == Bad) { 5180 reset(); 5181 return Error; 5182 } 5183 } 5184 5185 if (mode == Handshake) { 5186 int ret = doHandshake(); 5187 if (ret == Good) { 5188 getCert(); 5189 mode = Active; 5190 } else if (ret == Bad) { 5191 reset(); 5192 return Error; 5193 } 5194 } 5195 5196 // process outgoing 5197 *to_net = readOutgoing(); 5198 5199 if (mode == Active) 5200 return Success; 5201 else 5202 return Continue; 5203 } 5204 5205 Result priv_shutdown(const QByteArray &from_net, QByteArray *to_net) 5206 { 5207 if (!from_net.isEmpty()) 5208 BIO_write(rbio, from_net.data(), from_net.size()); 5209 5210 int ret = doShutdown(); 5211 if (ret == Bad) { 5212 reset(); 5213 return Error; 5214 } 5215 5216 *to_net = readOutgoing(); 5217 5218 if (ret == Good) { 5219 mode = Idle; 5220 return Success; 5221 } else { 5222 // mode = Closing; 5223 return Continue; 5224 } 5225 } 5226 5227 bool priv_encode(const QByteArray &plain, QByteArray *to_net, int *enc) 5228 { 5229 if (mode != Active) 5230 return false; 5231 sendQueue.append(plain); 5232 5233 int encoded = 0; 5234 if (sendQueue.size() > 0) { 5235 int ret = SSL_write(ssl, sendQueue.data(), sendQueue.size()); 5236 5237 enum 5238 { 5239 Good, 5240 Continue, 5241 Done, 5242 Error 5243 }; 5244 int m; 5245 if (ret <= 0) { 5246 int x = SSL_get_error(ssl, ret); 5247 if (x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE) 5248 m = Continue; 5249 else if (x == SSL_ERROR_ZERO_RETURN) 5250 m = Done; 5251 else 5252 m = Error; 5253 } else { 5254 m = Good; 5255 encoded = ret; 5256 int newsize = sendQueue.size() - encoded; 5257 char *r = sendQueue.data(); 5258 memmove(r, r + encoded, newsize); 5259 sendQueue.resize(newsize); 5260 } 5261 5262 if (m == Done) { 5263 sendQueue.resize(0); 5264 v_eof = true; 5265 return false; 5266 } 5267 if (m == Error) { 5268 sendQueue.resize(0); 5269 return false; 5270 } 5271 } 5272 5273 *to_net += readOutgoing(); 5274 *enc = encoded; 5275 return true; 5276 } 5277 5278 bool priv_decode(const QByteArray &from_net, QByteArray *plain, QByteArray *to_net) 5279 { 5280 if (mode != Active) 5281 return false; 5282 if (!from_net.isEmpty()) 5283 BIO_write(rbio, from_net.data(), from_net.size()); 5284 5285 QByteArray a; 5286 while (!v_eof) { 5287 a.resize(8192); 5288 int ret = SSL_read(ssl, a.data(), a.size()); 5289 // printf("SSL_read = %d\n", ret); 5290 if (ret > 0) { 5291 if (ret != (int)a.size()) 5292 a.resize(ret); 5293 // printf("SSL_read chunk: [%s]\n", qPrintable(arrayToHex(a))); 5294 recvQueue.append(a); 5295 } else if (ret <= 0) { 5296 ERR_print_errors_fp(stdout); 5297 int x = SSL_get_error(ssl, ret); 5298 // printf("SSL_read error = %d\n", x); 5299 if (x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE) 5300 break; 5301 else if (x == SSL_ERROR_ZERO_RETURN) 5302 v_eof = true; 5303 else 5304 return false; 5305 } 5306 } 5307 5308 *plain = recvQueue; 5309 recvQueue.resize(0); 5310 5311 // could be outgoing data also 5312 *to_net += readOutgoing(); 5313 return true; 5314 } 5315 5316 bool waitForResultsReady(int msecs) override 5317 { 5318 // TODO: for now, all operations block anyway 5319 Q_UNUSED(msecs); 5320 return true; 5321 } 5322 5323 Result result() const override 5324 { 5325 return result_result; 5326 } 5327 5328 QByteArray to_net() override 5329 { 5330 const QByteArray a = result_to_net; 5331 result_to_net.clear(); 5332 return a; 5333 } 5334 5335 int encoded() const override 5336 { 5337 return result_encoded; 5338 } 5339 5340 QByteArray to_app() override 5341 { 5342 const QByteArray a = result_plain; 5343 result_plain.clear(); 5344 return a; 5345 } 5346 5347 bool eof() const override 5348 { 5349 return v_eof; 5350 } 5351 5352 bool clientHelloReceived() const override 5353 { 5354 // TODO 5355 return false; 5356 } 5357 5358 bool serverHelloReceived() const override 5359 { 5360 // TODO 5361 return false; 5362 } 5363 5364 QString hostName() const override 5365 { 5366 // TODO 5367 return QString(); 5368 } 5369 5370 bool certificateRequested() const override 5371 { 5372 // TODO 5373 return false; 5374 } 5375 5376 QList<CertificateInfoOrdered> issuerList() const override 5377 { 5378 // TODO 5379 return QList<CertificateInfoOrdered>(); 5380 } 5381 5382 SessionInfo sessionInfo() const override 5383 { 5384 SessionInfo sessInfo; 5385 5386 SSL_SESSION *session = SSL_get0_session(ssl); 5387 sessInfo.isCompressed = (0 != SSL_SESSION_get_compress_id(session)); 5388 int ssl_version = SSL_version(ssl); 5389 5390 if (ssl_version == TLS1_VERSION) 5391 sessInfo.version = TLS::TLS_v1; 5392 else if (ssl_version == SSL3_VERSION) 5393 sessInfo.version = TLS::SSL_v3; 5394 else if (ssl_version == SSL2_VERSION) 5395 sessInfo.version = TLS::SSL_v2; 5396 else { 5397 qDebug("unexpected version response"); 5398 sessInfo.version = TLS::TLS_v1; 5399 } 5400 5401 sessInfo.cipherSuite = QString::fromLatin1(SSL_CIPHER_standard_name(SSL_get_current_cipher(ssl))); 5402 5403 sessInfo.cipherMaxBits = SSL_get_cipher_bits(ssl, &(sessInfo.cipherBits)); 5404 5405 sessInfo.id = nullptr; // TODO: session resuming 5406 5407 return sessInfo; 5408 } 5409 5410 QByteArray unprocessed() override 5411 { 5412 QByteArray a; 5413 int size = BIO_pending(rbio); 5414 if (size <= 0) 5415 return a; 5416 a.resize(size); 5417 5418 int r = BIO_read(rbio, a.data(), size); 5419 if (r <= 0) { 5420 a.resize(0); 5421 return a; 5422 } 5423 if (r != size) 5424 a.resize(r); 5425 return a; 5426 } 5427 5428 Validity peerCertificateValidity() const override 5429 { 5430 return vr; 5431 } 5432 5433 CertificateChain peerCertificateChain() const override 5434 { 5435 // TODO: support whole chain 5436 CertificateChain chain; 5437 chain.append(peercert); 5438 return chain; 5439 } 5440 5441 void doResultsReady() 5442 { 5443 QMetaObject::invokeMethod(this, "resultsReady", Qt::QueuedConnection); 5444 } 5445 5446 bool init() 5447 { 5448 context = SSL_CTX_new(method); 5449 if (!context) 5450 return false; 5451 5452 // setup the cert store 5453 { 5454 X509_STORE *store = SSL_CTX_get_cert_store(context); 5455 const QList<Certificate> cert_list = trusted.certificates(); 5456 const QList<CRL> crl_list = trusted.crls(); 5457 int n; 5458 for (n = 0; n < cert_list.count(); ++n) { 5459 const MyCertContext *cc = static_cast<const MyCertContext *>(cert_list[n].context()); 5460 X509 *x = cc->item.cert; 5461 // CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 5462 X509_STORE_add_cert(store, x); 5463 } 5464 for (n = 0; n < crl_list.count(); ++n) { 5465 const MyCRLContext *cc = static_cast<const MyCRLContext *>(crl_list[n].context()); 5466 X509_CRL *x = cc->item.crl; 5467 // CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); 5468 X509_STORE_add_crl(store, x); 5469 } 5470 } 5471 5472 ssl = SSL_new(context); 5473 if (!ssl) { 5474 SSL_CTX_free(context); 5475 context = nullptr; 5476 return false; 5477 } 5478 SSL_set_ssl_method(ssl, method); // can this return error? 5479 5480 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME 5481 if (targetHostName.isEmpty() == false) { 5482 // we have a target 5483 // this might fail, but we ignore that for now 5484 char *hostname = targetHostName.toLatin1().data(); 5485 SSL_set_tlsext_host_name(ssl, hostname); 5486 } 5487 #endif 5488 5489 // setup the memory bio 5490 rbio = BIO_new(BIO_s_mem()); 5491 wbio = BIO_new(BIO_s_mem()); 5492 5493 // this passes control of the bios to ssl. we don't need to free them. 5494 SSL_set_bio(ssl, rbio, wbio); 5495 5496 // FIXME: move this to after server hello 5497 // setup the cert to send 5498 if (!cert.isNull() && !key.isNull()) { 5499 PrivateKey nkey = key; 5500 5501 const PKeyContext *tmp_kc = static_cast<const PKeyContext *>(nkey.context()); 5502 5503 if (!tmp_kc->sameProvider(this)) { 5504 // fprintf(stderr, "experimental: private key supplied by a different provider\n"); 5505 5506 // make a pkey pointing to the existing private key 5507 EVP_PKEY *pkey; 5508 pkey = EVP_PKEY_new(); 5509 EVP_PKEY_assign_RSA(pkey, createFromExisting(nkey.toRSA())); 5510 5511 // make a new private key object to hold it 5512 MyPKeyContext *pk = new MyPKeyContext(provider()); 5513 PKeyBase *k = pk->pkeyToBase(pkey, true); // does an EVP_PKEY_free() 5514 pk->k = k; 5515 nkey.change(pk); 5516 } 5517 5518 const MyCertContext *cc = static_cast<const MyCertContext *>(cert.context()); 5519 const MyPKeyContext *kc = static_cast<const MyPKeyContext *>(nkey.context()); 5520 5521 if (SSL_use_certificate(ssl, cc->item.cert) != 1) { 5522 SSL_free(ssl); 5523 SSL_CTX_free(context); 5524 return false; 5525 } 5526 if (SSL_use_PrivateKey(ssl, kc->get_pkey()) != 1) { 5527 SSL_free(ssl); 5528 SSL_CTX_free(context); 5529 return false; 5530 } 5531 } 5532 5533 // request a certificate from the client, if in server mode 5534 if (serv) { 5535 SSL_set_verify(ssl, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, ssl_verify_callback); 5536 } 5537 5538 return true; 5539 } 5540 5541 void getCert() 5542 { 5543 // verify the certificate 5544 Validity code = ErrorValidityUnknown; 5545 STACK_OF(X509) *x_chain = SSL_get_peer_cert_chain(ssl); 5546 // X509 *x = SSL_get_peer_certificate(ssl); 5547 if (x_chain) { 5548 CertificateChain chain; 5549 5550 if (serv) { 5551 X509 *x = SSL_get_peer_certificate(ssl); 5552 MyCertContext *cc = new MyCertContext(provider()); 5553 cc->fromX509(x); 5554 Certificate cert; 5555 cert.change(cc); 5556 chain += cert; 5557 } 5558 5559 for (int n = 0; n < sk_X509_num(x_chain); ++n) { 5560 X509 *x = sk_X509_value(x_chain, n); 5561 MyCertContext *cc = new MyCertContext(provider()); 5562 cc->fromX509(x); 5563 Certificate cert; 5564 cert.change(cc); 5565 chain += cert; 5566 } 5567 5568 peercert = chain.primary(); 5569 5570 #ifdef Q_OS_MAC 5571 code = chain.validate(trusted); 5572 #else 5573 int ret = SSL_get_verify_result(ssl); 5574 if (ret == X509_V_OK) 5575 code = ValidityGood; 5576 else 5577 code = convert_verify_error(ret); 5578 #endif 5579 } else { 5580 peercert = Certificate(); 5581 } 5582 vr = code; 5583 } 5584 5585 int doConnect() 5586 { 5587 int ret = SSL_connect(ssl); 5588 if (ret < 0) { 5589 int x = SSL_get_error(ssl, ret); 5590 if (x == SSL_ERROR_WANT_CONNECT || x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE) 5591 return TryAgain; 5592 else 5593 return Bad; 5594 } else if (ret == 0) 5595 return Bad; 5596 return Good; 5597 } 5598 5599 int doAccept() 5600 { 5601 int ret = SSL_accept(ssl); 5602 if (ret < 0) { 5603 int x = SSL_get_error(ssl, ret); 5604 if (x == SSL_ERROR_WANT_CONNECT || x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE) 5605 return TryAgain; 5606 else 5607 return Bad; 5608 } else if (ret == 0) 5609 return Bad; 5610 return Good; 5611 } 5612 5613 int doHandshake() 5614 { 5615 int ret = SSL_do_handshake(ssl); 5616 if (ret < 0) { 5617 int x = SSL_get_error(ssl, ret); 5618 if (x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE) 5619 return TryAgain; 5620 else 5621 return Bad; 5622 } else if (ret == 0) 5623 return Bad; 5624 return Good; 5625 } 5626 5627 int doShutdown() 5628 { 5629 int ret = SSL_shutdown(ssl); 5630 if (ret >= 1) 5631 return Good; 5632 else { 5633 if (ret == 0) 5634 return TryAgain; 5635 int x = SSL_get_error(ssl, ret); 5636 if (x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE) 5637 return TryAgain; 5638 return Bad; 5639 } 5640 } 5641 5642 QByteArray readOutgoing() 5643 { 5644 QByteArray a; 5645 int size = BIO_pending(wbio); 5646 if (size <= 0) 5647 return a; 5648 a.resize(size); 5649 5650 int r = BIO_read(wbio, a.data(), size); 5651 if (r <= 0) { 5652 a.resize(0); 5653 return a; 5654 } 5655 if (r != size) 5656 a.resize(r); 5657 return a; 5658 } 5659 }; 5660 5661 class CMSContext : public SMSContext 5662 { 5663 Q_OBJECT 5664 public: 5665 CertificateCollection trustedCerts; 5666 CertificateCollection untrustedCerts; 5667 QList<SecureMessageKey> privateKeys; 5668 5669 CMSContext(Provider *p) 5670 : SMSContext(p, QStringLiteral("cms")) 5671 { 5672 } 5673 5674 ~CMSContext() override 5675 { 5676 } 5677 5678 Provider::Context *clone() const override 5679 { 5680 return nullptr; 5681 } 5682 5683 void setTrustedCertificates(const CertificateCollection &trusted) override 5684 { 5685 trustedCerts = trusted; 5686 } 5687 5688 void setUntrustedCertificates(const CertificateCollection &untrusted) override 5689 { 5690 untrustedCerts = untrusted; 5691 } 5692 5693 void setPrivateKeys(const QList<SecureMessageKey> &keys) override 5694 { 5695 privateKeys = keys; 5696 } 5697 5698 MessageContext *createMessage() override; 5699 }; 5700 5701 STACK_OF(X509) * get_pk7_certs(PKCS7 *p7) 5702 { 5703 int i = OBJ_obj2nid(p7->type); 5704 if (i == NID_pkcs7_signed) 5705 return p7->d.sign->cert; 5706 else if (i == NID_pkcs7_signedAndEnveloped) 5707 return p7->d.signed_and_enveloped->cert; 5708 else 5709 return nullptr; 5710 } 5711 5712 class MyMessageContextThread : public QThread 5713 { 5714 Q_OBJECT 5715 public: 5716 SecureMessage::Format format; 5717 SecureMessage::SignMode signMode; 5718 Certificate cert; 5719 PrivateKey key; 5720 STACK_OF(X509) * other_certs; 5721 BIO *bi; 5722 int flags; 5723 PKCS7 *p7; 5724 bool ok; 5725 QByteArray out, sig; 5726 5727 MyMessageContextThread(QObject *parent = nullptr) 5728 : QThread(parent) 5729 , ok(false) 5730 { 5731 } 5732 5733 protected: 5734 void run() override 5735 { 5736 MyCertContext *cc = static_cast<MyCertContext *>(cert.context()); 5737 MyPKeyContext *kc = static_cast<MyPKeyContext *>(key.context()); 5738 X509 *cx = cc->item.cert; 5739 EVP_PKEY *kx = kc->get_pkey(); 5740 5741 p7 = PKCS7_sign(cx, kx, other_certs, bi, flags); 5742 5743 BIO_free(bi); 5744 sk_X509_pop_free(other_certs, X509_free); 5745 5746 if (p7) { 5747 // printf("good\n"); 5748 BIO *bo; 5749 5750 // BIO *bo = BIO_new(BIO_s_mem()); 5751 // i2d_PKCS7_bio(bo, p7); 5752 // PEM_write_bio_PKCS7(bo, p7); 5753 // SecureArray buf = bio2buf(bo); 5754 // printf("[%s]\n", buf.data()); 5755 5756 bo = BIO_new(BIO_s_mem()); 5757 if (format == SecureMessage::Binary) 5758 i2d_PKCS7_bio(bo, p7); 5759 else // Ascii 5760 PEM_write_bio_PKCS7(bo, p7); 5761 5762 if (SecureMessage::Detached == signMode) 5763 sig = bio2ba(bo); 5764 else 5765 out = bio2ba(bo); 5766 5767 ok = true; 5768 } else { 5769 printf("bad here\n"); 5770 ERR_print_errors_fp(stdout); 5771 } 5772 } 5773 }; 5774 5775 class MyMessageContext : public MessageContext 5776 { 5777 Q_OBJECT 5778 public: 5779 CMSContext *cms; 5780 SecureMessageKey signer; 5781 SecureMessageKeyList to; 5782 SecureMessage::SignMode signMode; 5783 bool bundleSigner; 5784 bool smime; 5785 SecureMessage::Format format; 5786 5787 Operation op; 5788 bool _finished; 5789 5790 QByteArray in, out; 5791 QByteArray sig; 5792 int total; 5793 5794 CertificateChain signerChain; 5795 int ver_ret; 5796 5797 MyMessageContextThread *thread; 5798 5799 MyMessageContext(CMSContext *_cms, Provider *p) 5800 : MessageContext(p, QStringLiteral("cmsmsg")) 5801 { 5802 cms = _cms; 5803 5804 total = 0; 5805 5806 ver_ret = 0; 5807 5808 thread = nullptr; 5809 } 5810 5811 ~MyMessageContext() override 5812 { 5813 } 5814 5815 Provider::Context *clone() const override 5816 { 5817 return nullptr; 5818 } 5819 5820 bool canSignMultiple() const override 5821 { 5822 return false; 5823 } 5824 5825 SecureMessage::Type type() const override 5826 { 5827 return SecureMessage::CMS; 5828 } 5829 5830 void reset() override 5831 { 5832 } 5833 5834 void setupEncrypt(const SecureMessageKeyList &keys) override 5835 { 5836 to = keys; 5837 } 5838 5839 void setupSign(const SecureMessageKeyList &keys, SecureMessage::SignMode m, bool bundleSigner, bool smime) override 5840 { 5841 signer = keys.first(); 5842 signMode = m; 5843 this->bundleSigner = bundleSigner; 5844 this->smime = smime; 5845 } 5846 5847 void setupVerify(const QByteArray &detachedSig) override 5848 { 5849 // TODO 5850 sig = detachedSig; 5851 } 5852 5853 void start(SecureMessage::Format f, Operation op) override 5854 { 5855 format = f; 5856 _finished = false; 5857 5858 // TODO: other operations 5859 // if(op == Sign) 5860 //{ 5861 this->op = op; 5862 //} 5863 // else if(op == Encrypt) 5864 //{ 5865 // this->op = op; 5866 //} 5867 } 5868 5869 void update(const QByteArray &in) override 5870 { 5871 this->in.append(in); 5872 total += in.size(); 5873 QMetaObject::invokeMethod(this, "updated", Qt::QueuedConnection); 5874 } 5875 5876 QByteArray read() override 5877 { 5878 return out; 5879 } 5880 5881 int written() override 5882 { 5883 int x = total; 5884 total = 0; 5885 return x; 5886 } 5887 5888 void end() override 5889 { 5890 _finished = true; 5891 5892 // sign 5893 if (op == Sign) { 5894 const CertificateChain chain = signer.x509CertificateChain(); 5895 Certificate cert = chain.primary(); 5896 QList<Certificate> nonroots; 5897 if (chain.count() > 1) { 5898 for (int n = 1; n < chain.count(); ++n) 5899 nonroots.append(chain[n]); 5900 } 5901 PrivateKey key = signer.x509PrivateKey(); 5902 5903 const PKeyContext *tmp_kc = static_cast<const PKeyContext *>(key.context()); 5904 5905 if (!tmp_kc->sameProvider(this)) { 5906 // fprintf(stderr, "experimental: private key supplied by a different provider\n"); 5907 5908 // make a pkey pointing to the existing private key 5909 EVP_PKEY *pkey; 5910 pkey = EVP_PKEY_new(); 5911 EVP_PKEY_assign_RSA(pkey, createFromExisting(key.toRSA())); 5912 5913 // make a new private key object to hold it 5914 MyPKeyContext *pk = new MyPKeyContext(provider()); 5915 PKeyBase *k = pk->pkeyToBase(pkey, true); // does an EVP_PKEY_free() 5916 pk->k = k; 5917 key.change(pk); 5918 } 5919 5920 // allow different cert provider. this is just a 5921 // quick hack, enough to please qca-test 5922 if (!cert.context()->sameProvider(this)) { 5923 // fprintf(stderr, "experimental: cert supplied by a different provider\n"); 5924 cert = Certificate::fromDER(cert.toDER()); 5925 if (cert.isNull() || !cert.context()->sameProvider(this)) { 5926 // fprintf(stderr, "error converting cert\n"); 5927 } 5928 } 5929 5930 // MyCertContext *cc = static_cast<MyCertContext *>(cert.context()); 5931 // MyPKeyContext *kc = static_cast<MyPKeyContext *>(key.context()); 5932 5933 // X509 *cx = cc->item.cert; 5934 // EVP_PKEY *kx = kc->get_pkey(); 5935 5936 STACK_OF(X509) * other_certs; 5937 BIO *bi; 5938 int flags; 5939 // PKCS7 *p7; 5940 5941 // nonroots 5942 other_certs = sk_X509_new_null(); 5943 for (int n = 0; n < nonroots.count(); ++n) { 5944 X509 *x = static_cast<MyCertContext *>(nonroots[n].context())->item.cert; 5945 X509_up_ref(x); 5946 sk_X509_push(other_certs, x); 5947 } 5948 5949 // printf("bundling %d other_certs\n", sk_X509_num(other_certs)); 5950 5951 bi = BIO_new(BIO_s_mem()); 5952 BIO_write(bi, in.data(), in.size()); 5953 5954 flags = 0; 5955 flags |= PKCS7_BINARY; 5956 if (SecureMessage::Detached == signMode) { 5957 flags |= PKCS7_DETACHED; 5958 } 5959 if (false == bundleSigner) 5960 flags |= PKCS7_NOCERTS; 5961 5962 if (thread) 5963 delete thread; 5964 thread = new MyMessageContextThread(this); 5965 thread->format = format; 5966 thread->signMode = signMode; 5967 thread->cert = cert; 5968 thread->key = key; 5969 thread->other_certs = other_certs; 5970 thread->bi = bi; 5971 thread->flags = flags; 5972 connect(thread, &MyMessageContextThread::finished, this, &MyMessageContext::thread_finished); 5973 thread->start(); 5974 } else if (op == Encrypt) { 5975 // TODO: support multiple recipients 5976 Certificate target = to.first().x509CertificateChain().primary(); 5977 5978 STACK_OF(X509) * other_certs; 5979 BIO *bi; 5980 int flags; 5981 PKCS7 *p7; 5982 5983 other_certs = sk_X509_new_null(); 5984 X509 *x = static_cast<MyCertContext *>(target.context())->item.cert; 5985 X509_up_ref(x); 5986 sk_X509_push(other_certs, x); 5987 5988 bi = BIO_new(BIO_s_mem()); 5989 BIO_write(bi, in.data(), in.size()); 5990 5991 flags = 0; 5992 flags |= PKCS7_BINARY; 5993 p7 = PKCS7_encrypt(other_certs, bi, EVP_des_ede3_cbc(), flags); // TODO: cipher? 5994 5995 BIO_free(bi); 5996 sk_X509_pop_free(other_certs, X509_free); 5997 5998 if (p7) { 5999 // FIXME: format 6000 BIO *bo = BIO_new(BIO_s_mem()); 6001 i2d_PKCS7_bio(bo, p7); 6002 // PEM_write_bio_PKCS7(bo, p7); 6003 out = bio2ba(bo); 6004 PKCS7_free(p7); 6005 } else { 6006 printf("bad\n"); 6007 return; 6008 } 6009 } else if (op == Verify) { 6010 // TODO: support non-detached sigs 6011 6012 BIO *out = BIO_new(BIO_s_mem()); 6013 BIO *bi = BIO_new(BIO_s_mem()); 6014 if (false == sig.isEmpty()) { 6015 // We have detached signature 6016 BIO_write(bi, sig.data(), sig.size()); 6017 } else { 6018 BIO_write(bi, in.data(), in.size()); 6019 } 6020 PKCS7 *p7; 6021 if (format == SecureMessage::Binary) 6022 p7 = d2i_PKCS7_bio(bi, nullptr); 6023 else // Ascii 6024 p7 = PEM_read_bio_PKCS7(bi, nullptr, passphrase_cb, nullptr); 6025 BIO_free(bi); 6026 6027 if (!p7) { 6028 // TODO 6029 printf("bad1\n"); 6030 QMetaObject::invokeMethod(this, "updated", Qt::QueuedConnection); 6031 return; 6032 } 6033 6034 // intermediates/signers that may not be in the blob 6035 STACK_OF(X509) *other_certs = sk_X509_new_null(); 6036 QList<Certificate> untrusted_list = cms->untrustedCerts.certificates(); 6037 const QList<CRL> untrusted_crls = cms->untrustedCerts.crls(); // we'll use the crls later 6038 for (int n = 0; n < untrusted_list.count(); ++n) { 6039 X509 *x = static_cast<MyCertContext *>(untrusted_list[n].context())->item.cert; 6040 X509_up_ref(x); 6041 sk_X509_push(other_certs, x); 6042 } 6043 6044 // get the possible message signers 6045 QList<Certificate> signers; 6046 STACK_OF(X509) *xs = PKCS7_get0_signers(p7, other_certs, 0); 6047 if (xs) { 6048 for (int n = 0; n < sk_X509_num(xs); ++n) { 6049 MyCertContext *cc = new MyCertContext(provider()); 6050 cc->fromX509(sk_X509_value(xs, n)); 6051 Certificate cert; 6052 cert.change(cc); 6053 // printf("signer: [%s]\n", qPrintable(cert.commonName())); 6054 signers.append(cert); 6055 } 6056 sk_X509_free(xs); 6057 } 6058 6059 // get the rest of the certificates lying around 6060 QList<Certificate> others; 6061 xs = get_pk7_certs(p7); // don't free 6062 if (xs) { 6063 for (int n = 0; n < sk_X509_num(xs); ++n) { 6064 MyCertContext *cc = new MyCertContext(provider()); 6065 cc->fromX509(sk_X509_value(xs, n)); 6066 Certificate cert; 6067 cert.change(cc); 6068 others.append(cert); 6069 // printf("other: [%s]\n", qPrintable(cert.commonName())); 6070 } 6071 } 6072 6073 // signer needs to be supplied in the message itself 6074 // or via cms->untrustedCerts 6075 if (signers.isEmpty()) { 6076 QMetaObject::invokeMethod(this, "updated", Qt::QueuedConnection); 6077 return; 6078 } 6079 6080 // FIXME: handle more than one signer 6081 CertificateChain chain; 6082 chain += signers[0]; 6083 6084 // build chain 6085 chain = chain.complete(others); 6086 6087 signerChain = chain; 6088 6089 X509_STORE *store = X509_STORE_new(); 6090 const QList<Certificate> cert_list = cms->trustedCerts.certificates(); 6091 QList<CRL> crl_list = cms->trustedCerts.crls(); 6092 for (int n = 0; n < cert_list.count(); ++n) { 6093 // printf("trusted: [%s]\n", qPrintable(cert_list[n].commonName())); 6094 const MyCertContext *cc = static_cast<const MyCertContext *>(cert_list[n].context()); 6095 X509 *x = cc->item.cert; 6096 // CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 6097 X509_STORE_add_cert(store, x); 6098 } 6099 for (int n = 0; n < crl_list.count(); ++n) { 6100 const MyCRLContext *cc = static_cast<const MyCRLContext *>(crl_list[n].context()); 6101 X509_CRL *x = cc->item.crl; 6102 // CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); 6103 X509_STORE_add_crl(store, x); 6104 } 6105 // add these crls also 6106 crl_list = untrusted_crls; 6107 for (int n = 0; n < crl_list.count(); ++n) { 6108 const MyCRLContext *cc = static_cast<const MyCRLContext *>(crl_list[n].context()); 6109 X509_CRL *x = cc->item.crl; 6110 // CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); 6111 X509_STORE_add_crl(store, x); 6112 } 6113 6114 int ret; 6115 if (!sig.isEmpty()) { 6116 // Detached signMode 6117 bi = BIO_new(BIO_s_mem()); 6118 BIO_write(bi, in.data(), in.size()); 6119 ret = PKCS7_verify(p7, other_certs, store, bi, nullptr, 0); 6120 BIO_free(bi); 6121 } else { 6122 ret = PKCS7_verify(p7, other_certs, store, nullptr, out, 0); 6123 // qDebug() << "Verify: " << ret; 6124 } 6125 // if(!ret) 6126 // ERR_print_errors_fp(stdout); 6127 sk_X509_pop_free(other_certs, X509_free); 6128 X509_STORE_free(store); 6129 PKCS7_free(p7); 6130 6131 ver_ret = ret; 6132 // TODO 6133 6134 QMetaObject::invokeMethod(this, "updated", Qt::QueuedConnection); 6135 } else if (op == Decrypt) { 6136 bool ok = false; 6137 for (int n = 0; n < cms->privateKeys.count(); ++n) { 6138 CertificateChain chain = cms->privateKeys[n].x509CertificateChain(); 6139 Certificate cert = chain.primary(); 6140 PrivateKey key = cms->privateKeys[n].x509PrivateKey(); 6141 6142 MyCertContext *cc = static_cast<MyCertContext *>(cert.context()); 6143 MyPKeyContext *kc = static_cast<MyPKeyContext *>(key.context()); 6144 6145 X509 *cx = cc->item.cert; 6146 EVP_PKEY *kx = kc->get_pkey(); 6147 6148 BIO *bi = BIO_new(BIO_s_mem()); 6149 BIO_write(bi, in.data(), in.size()); 6150 PKCS7 *p7 = d2i_PKCS7_bio(bi, nullptr); 6151 BIO_free(bi); 6152 6153 if (!p7) { 6154 // TODO 6155 printf("bad1\n"); 6156 return; 6157 } 6158 6159 BIO *bo = BIO_new(BIO_s_mem()); 6160 int ret = PKCS7_decrypt(p7, kx, cx, bo, 0); 6161 PKCS7_free(p7); 6162 if (!ret) 6163 continue; 6164 6165 ok = true; 6166 out = bio2ba(bo); 6167 break; 6168 } 6169 6170 if (!ok) { 6171 // TODO 6172 printf("bad2\n"); 6173 return; 6174 } 6175 } 6176 } 6177 6178 bool finished() const override 6179 { 6180 return _finished; 6181 } 6182 6183 bool waitForFinished(int msecs) override 6184 { 6185 // TODO 6186 Q_UNUSED(msecs); 6187 6188 if (thread) { 6189 thread->wait(); 6190 getresults(); 6191 } 6192 return true; 6193 } 6194 6195 bool success() const override 6196 { 6197 // TODO 6198 return true; 6199 } 6200 6201 SecureMessage::Error errorCode() const override 6202 { 6203 // TODO 6204 return SecureMessage::ErrorUnknown; 6205 } 6206 6207 QByteArray signature() const override 6208 { 6209 return sig; 6210 } 6211 6212 QString hashName() const override 6213 { 6214 // TODO 6215 return QStringLiteral("sha1"); 6216 } 6217 6218 SecureMessageSignatureList signers() const override 6219 { 6220 // only report signers for verify 6221 if (op != Verify) 6222 return SecureMessageSignatureList(); 6223 6224 SecureMessageKey key; 6225 if (!signerChain.isEmpty()) 6226 key.setX509CertificateChain(signerChain); 6227 6228 // TODO/FIXME !!! InvalidSignature might be used here even 6229 // if the signature is just fine, and the key is invalid 6230 // (we need to use InvalidKey instead). 6231 6232 Validity vr = ErrorValidityUnknown; 6233 if (!signerChain.isEmpty()) 6234 vr = signerChain.validate(cms->trustedCerts, cms->untrustedCerts.crls()); 6235 6236 SecureMessageSignature::IdentityResult ir; 6237 if (vr == ValidityGood) 6238 ir = SecureMessageSignature::Valid; 6239 else 6240 ir = SecureMessageSignature::InvalidKey; 6241 6242 if (!ver_ret) 6243 ir = SecureMessageSignature::InvalidSignature; 6244 6245 SecureMessageSignature s(ir, vr, key, QDateTime::currentDateTime()); 6246 6247 // TODO 6248 return SecureMessageSignatureList() << s; 6249 } 6250 6251 void getresults() 6252 { 6253 sig = thread->sig; 6254 out = thread->out; 6255 } 6256 6257 private Q_SLOTS: 6258 void thread_finished() 6259 { 6260 getresults(); 6261 emit updated(); 6262 } 6263 }; 6264 6265 MessageContext *CMSContext::createMessage() 6266 { 6267 return new MyMessageContext(this, provider()); 6268 } 6269 6270 class opensslCipherContext : public CipherContext 6271 { 6272 Q_OBJECT 6273 public: 6274 opensslCipherContext(const EVP_CIPHER *algorithm, const int pad, Provider *p, const QString &type) 6275 : CipherContext(p, type) 6276 { 6277 m_cryptoAlgorithm = algorithm; 6278 m_context = EVP_CIPHER_CTX_new(); 6279 EVP_CIPHER_CTX_init(m_context); 6280 m_pad = pad; 6281 m_type = type; 6282 } 6283 6284 opensslCipherContext(const opensslCipherContext &other) 6285 : CipherContext(other) 6286 { 6287 m_cryptoAlgorithm = other.m_cryptoAlgorithm; 6288 m_context = EVP_CIPHER_CTX_new(); 6289 EVP_CIPHER_CTX_copy(m_context, other.m_context); 6290 m_direction = other.m_direction; 6291 m_pad = other.m_pad; 6292 m_type = other.m_type; 6293 m_tag = other.m_tag; 6294 } 6295 6296 ~opensslCipherContext() override 6297 { 6298 EVP_CIPHER_CTX_cleanup(m_context); 6299 EVP_CIPHER_CTX_free(m_context); 6300 } 6301 6302 void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv, const AuthTag &tag) override 6303 { 6304 m_tag = tag; 6305 m_direction = dir; 6306 if ((m_cryptoAlgorithm == EVP_des_ede3()) && (key.size() == 16)) { 6307 // this is really a two key version of triple DES. 6308 m_cryptoAlgorithm = EVP_des_ede(); 6309 } 6310 if (Encode == m_direction) { 6311 EVP_EncryptInit_ex(m_context, m_cryptoAlgorithm, nullptr, nullptr, nullptr); 6312 EVP_CIPHER_CTX_set_key_length(m_context, key.size()); 6313 if (m_type.endsWith(QLatin1String("gcm")) || m_type.endsWith(QLatin1String("ccm"))) { 6314 int parameter = m_type.endsWith(QLatin1String("gcm")) ? EVP_CTRL_GCM_SET_IVLEN : EVP_CTRL_CCM_SET_IVLEN; 6315 EVP_CIPHER_CTX_ctrl(m_context, parameter, iv.size(), nullptr); 6316 } 6317 EVP_EncryptInit_ex( 6318 m_context, nullptr, nullptr, (const unsigned char *)(key.data()), (const unsigned char *)(iv.data())); 6319 } else { 6320 EVP_DecryptInit_ex(m_context, m_cryptoAlgorithm, nullptr, nullptr, nullptr); 6321 EVP_CIPHER_CTX_set_key_length(m_context, key.size()); 6322 if (m_type.endsWith(QLatin1String("gcm")) || m_type.endsWith(QLatin1String("ccm"))) { 6323 int parameter = m_type.endsWith(QLatin1String("gcm")) ? EVP_CTRL_GCM_SET_IVLEN : EVP_CTRL_CCM_SET_IVLEN; 6324 EVP_CIPHER_CTX_ctrl(m_context, parameter, iv.size(), nullptr); 6325 } 6326 EVP_DecryptInit_ex( 6327 m_context, nullptr, nullptr, (const unsigned char *)(key.data()), (const unsigned char *)(iv.data())); 6328 } 6329 6330 EVP_CIPHER_CTX_set_padding(m_context, m_pad); 6331 } 6332 6333 Provider::Context *clone() const override 6334 { 6335 return new opensslCipherContext(*this); 6336 } 6337 6338 int blockSize() const override 6339 { 6340 return EVP_CIPHER_CTX_block_size(m_context); 6341 } 6342 6343 AuthTag tag() const override 6344 { 6345 return m_tag; 6346 } 6347 6348 bool update(const SecureArray &in, SecureArray *out) override 6349 { 6350 // This works around a problem in OpenSSL, where it asserts if 6351 // there is nothing to encrypt. 6352 if (0 == in.size()) 6353 return true; 6354 6355 out->resize(in.size() + blockSize()); 6356 int resultLength; 6357 if (Encode == m_direction) { 6358 if (0 == 6359 EVP_EncryptUpdate( 6360 m_context, (unsigned char *)out->data(), &resultLength, (unsigned char *)in.data(), in.size())) { 6361 return false; 6362 } 6363 } else { 6364 if (0 == 6365 EVP_DecryptUpdate( 6366 m_context, (unsigned char *)out->data(), &resultLength, (unsigned char *)in.data(), in.size())) { 6367 return false; 6368 } 6369 } 6370 out->resize(resultLength); 6371 return true; 6372 } 6373 6374 bool final(SecureArray *out) override 6375 { 6376 out->resize(blockSize()); 6377 int resultLength; 6378 if (Encode == m_direction) { 6379 if (0 == EVP_EncryptFinal_ex(m_context, (unsigned char *)out->data(), &resultLength)) { 6380 return false; 6381 } 6382 if (m_tag.size() && (m_type.endsWith(QLatin1String("gcm")) || m_type.endsWith(QLatin1String("ccm")))) { 6383 int parameter = m_type.endsWith(QLatin1String("gcm")) ? EVP_CTRL_GCM_GET_TAG : EVP_CTRL_CCM_GET_TAG; 6384 if (0 == EVP_CIPHER_CTX_ctrl(m_context, parameter, m_tag.size(), (unsigned char *)m_tag.data())) { 6385 return false; 6386 } 6387 } 6388 } else { 6389 if (m_tag.size() && (m_type.endsWith(QLatin1String("gcm")) || m_type.endsWith(QLatin1String("ccm")))) { 6390 int parameter = m_type.endsWith(QLatin1String("gcm")) ? EVP_CTRL_GCM_SET_TAG : EVP_CTRL_CCM_SET_TAG; 6391 if (0 == EVP_CIPHER_CTX_ctrl(m_context, parameter, m_tag.size(), m_tag.data())) { 6392 return false; 6393 } 6394 } 6395 if (0 == EVP_DecryptFinal_ex(m_context, (unsigned char *)out->data(), &resultLength)) { 6396 return false; 6397 } 6398 } 6399 out->resize(resultLength); 6400 return true; 6401 } 6402 6403 // Change cipher names 6404 KeyLength keyLength() const override 6405 { 6406 if (s_legacyProviderAvailable) { 6407 if (m_type.left(4) == QLatin1String("des-")) { 6408 return KeyLength(8, 8, 1); 6409 } else if (m_type.left(5) == QLatin1String("cast5")) { 6410 return KeyLength(5, 16, 1); 6411 } else if (m_type.left(8) == QLatin1String("blowfish")) { 6412 // Don't know - TODO 6413 return KeyLength(1, 32, 1); 6414 } 6415 } 6416 if (m_type.left(6) == QLatin1String("aes128")) { 6417 return KeyLength(16, 16, 1); 6418 } else if (m_type.left(6) == QLatin1String("aes192")) { 6419 return KeyLength(24, 24, 1); 6420 } else if (m_type.left(6) == QLatin1String("aes256")) { 6421 return KeyLength(32, 32, 1); 6422 } else if (m_type.left(9) == QLatin1String("tripledes")) { 6423 return KeyLength(16, 24, 1); 6424 } 6425 return KeyLength(0, 1, 1); 6426 } 6427 6428 protected: 6429 EVP_CIPHER_CTX *m_context; 6430 const EVP_CIPHER *m_cryptoAlgorithm; 6431 Direction m_direction; 6432 int m_pad; 6433 QString m_type; 6434 AuthTag m_tag; 6435 }; 6436 6437 static QStringList all_hash_types() 6438 { 6439 QStringList list; 6440 list += QStringLiteral("sha1"); 6441 #ifdef HAVE_OPENSSL_SHA0 6442 list += QStringLiteral("sha0"); 6443 #endif 6444 list += QStringLiteral("md5"); 6445 #ifdef SHA224_DIGEST_LENGTH 6446 list += QStringLiteral("sha224"); 6447 #endif 6448 #ifdef SHA256_DIGEST_LENGTH 6449 list += QStringLiteral("sha256"); 6450 #endif 6451 #ifdef SHA384_DIGEST_LENGTH 6452 list += QStringLiteral("sha384"); 6453 #endif 6454 #ifdef SHA512_DIGEST_LENGTH 6455 list += QStringLiteral("sha512"); 6456 #endif 6457 if (s_legacyProviderAvailable) { 6458 list += QStringLiteral("ripemd160"); 6459 #ifdef HAVE_OPENSSL_MD2 6460 list += QStringLiteral("md2"); 6461 #endif 6462 list += QStringLiteral("md4"); 6463 #ifdef OBJ_whirlpool 6464 list += QStringLiteral("whirlpool"); 6465 #endif 6466 } 6467 6468 return list; 6469 } 6470 6471 static QStringList all_cipher_types() 6472 { 6473 QStringList list; 6474 list += QStringLiteral("aes128-ecb"); 6475 list += QStringLiteral("aes128-cfb"); 6476 list += QStringLiteral("aes128-cbc"); 6477 list += QStringLiteral("aes128-cbc-pkcs7"); 6478 list += QStringLiteral("aes128-ofb"); 6479 #ifdef HAVE_OPENSSL_AES_CTR 6480 list += QStringLiteral("aes128-ctr"); 6481 #endif 6482 #ifdef HAVE_OPENSSL_AES_GCM 6483 list += QStringLiteral("aes128-gcm"); 6484 #endif 6485 #ifdef HAVE_OPENSSL_AES_CCM 6486 list += QStringLiteral("aes128-ccm"); 6487 #endif 6488 list += QStringLiteral("aes192-ecb"); 6489 list += QStringLiteral("aes192-cfb"); 6490 list += QStringLiteral("aes192-cbc"); 6491 list += QStringLiteral("aes192-cbc-pkcs7"); 6492 list += QStringLiteral("aes192-ofb"); 6493 #ifdef HAVE_OPENSSL_AES_CTR 6494 list += QStringLiteral("aes192-ctr"); 6495 #endif 6496 #ifdef HAVE_OPENSSL_AES_GCM 6497 list += QStringLiteral("aes192-gcm"); 6498 #endif 6499 #ifdef HAVE_OPENSSL_AES_CCM 6500 list += QStringLiteral("aes192-ccm"); 6501 #endif 6502 list += QStringLiteral("aes256-ecb"); 6503 list += QStringLiteral("aes256-cbc"); 6504 list += QStringLiteral("aes256-cbc-pkcs7"); 6505 list += QStringLiteral("aes256-cfb"); 6506 list += QStringLiteral("aes256-ofb"); 6507 #ifdef HAVE_OPENSSL_AES_CTR 6508 list += QStringLiteral("aes256-ctr"); 6509 #endif 6510 #ifdef HAVE_OPENSSL_AES_GCM 6511 list += QStringLiteral("aes256-gcm"); 6512 #endif 6513 #ifdef HAVE_OPENSSL_AES_CCM 6514 list += QStringLiteral("aes256-ccm"); 6515 #endif 6516 list += QStringLiteral("tripledes-ecb"); 6517 list += QStringLiteral("tripledes-cbc"); 6518 if (s_legacyProviderAvailable) { 6519 list += QStringLiteral("blowfish-ecb"); 6520 list += QStringLiteral("blowfish-cbc-pkcs7"); 6521 list += QStringLiteral("blowfish-cbc"); 6522 list += QStringLiteral("blowfish-cfb"); 6523 list += QStringLiteral("blowfish-ofb"); 6524 list += QStringLiteral("des-ecb"); 6525 list += QStringLiteral("des-ecb-pkcs7"); 6526 list += QStringLiteral("des-cbc"); 6527 list += QStringLiteral("des-cbc-pkcs7"); 6528 list += QStringLiteral("des-cfb"); 6529 list += QStringLiteral("des-ofb"); 6530 #ifndef OPENSSL_NO_CAST 6531 list += QStringLiteral("cast5-ecb"); 6532 list += QStringLiteral("cast5-cbc"); 6533 list += QStringLiteral("cast5-cbc-pkcs7"); 6534 list += QStringLiteral("cast5-cfb"); 6535 list += QStringLiteral("cast5-ofb"); 6536 #endif 6537 } 6538 return list; 6539 } 6540 6541 static QStringList all_mac_types() 6542 { 6543 QStringList list; 6544 list += QStringLiteral("hmac(md5)"); 6545 list += QStringLiteral("hmac(sha1)"); 6546 #ifdef SHA224_DIGEST_LENGTH 6547 list += QStringLiteral("hmac(sha224)"); 6548 #endif 6549 #ifdef SHA256_DIGEST_LENGTH 6550 list += QStringLiteral("hmac(sha256)"); 6551 #endif 6552 #ifdef SHA384_DIGEST_LENGTH 6553 list += QStringLiteral("hmac(sha384)"); 6554 #endif 6555 #ifdef SHA512_DIGEST_LENGTH 6556 list += QStringLiteral("hmac(sha512)"); 6557 #endif 6558 if (s_legacyProviderAvailable) { 6559 list += QStringLiteral("hmac(ripemd160)"); 6560 } 6561 return list; 6562 } 6563 6564 class opensslInfoContext : public InfoContext 6565 { 6566 Q_OBJECT 6567 public: 6568 opensslInfoContext(Provider *p) 6569 : InfoContext(p) 6570 { 6571 } 6572 6573 Provider::Context *clone() const override 6574 { 6575 return new opensslInfoContext(*this); 6576 } 6577 6578 QStringList supportedHashTypes() const override 6579 { 6580 return all_hash_types(); 6581 } 6582 6583 QStringList supportedCipherTypes() const override 6584 { 6585 return all_cipher_types(); 6586 } 6587 6588 QStringList supportedMACTypes() const override 6589 { 6590 return all_mac_types(); 6591 } 6592 }; 6593 6594 class opensslRandomContext : public RandomContext 6595 { 6596 Q_OBJECT 6597 public: 6598 opensslRandomContext(QCA::Provider *p) 6599 : RandomContext(p) 6600 { 6601 } 6602 6603 Context *clone() const override 6604 { 6605 return new opensslRandomContext(*this); 6606 } 6607 6608 QCA::SecureArray nextBytes(int size) override 6609 { 6610 QCA::SecureArray buf(size); 6611 int r; 6612 // FIXME: loop while we don't have enough random bytes. 6613 while (true) { 6614 r = RAND_bytes((unsigned char *)(buf.data()), size); 6615 if (r == 1) 6616 break; // success 6617 } 6618 return buf; 6619 } 6620 }; 6621 6622 } 6623 6624 using namespace opensslQCAPlugin; 6625 6626 class opensslProvider : public Provider 6627 { 6628 public: 6629 bool openssl_initted; 6630 6631 opensslProvider() 6632 { 6633 openssl_initted = false; 6634 // OPENSSL_VERSION_MAJOR is only defined in openssl3 6635 #ifdef OPENSSL_VERSION_MAJOR 6636 /* Load the legacy providers into the default (NULL) library context */ 6637 if (OSSL_PROVIDER_try_load(nullptr, "legacy", 1)) { 6638 s_legacyProviderAvailable = true; 6639 } 6640 #else 6641 s_legacyProviderAvailable = true; 6642 #endif 6643 } 6644 6645 void init() override 6646 { 6647 OpenSSL_add_all_algorithms(); 6648 ERR_load_crypto_strings(); 6649 6650 // seed the RNG if it's not seeded yet 6651 if (RAND_status() == 0) { 6652 std::srand(time(nullptr)); 6653 char buf[128]; 6654 for (char &n : buf) 6655 n = std::rand(); 6656 RAND_seed(buf, 128); 6657 } 6658 6659 openssl_initted = true; 6660 } 6661 6662 ~opensslProvider() override 6663 { 6664 // FIXME: ? for now we never deinit, in case other libs/code 6665 // are using openssl 6666 /*if(!openssl_initted) 6667 return; 6668 // todo: any other shutdown? 6669 EVP_cleanup(); 6670 //ENGINE_cleanup(); 6671 CRYPTO_cleanup_all_ex_data(); 6672 ERR_remove_state(0); 6673 ERR_free_strings();*/ 6674 } 6675 6676 int qcaVersion() const override 6677 { 6678 return QCA_VERSION; 6679 } 6680 6681 QString name() const override 6682 { 6683 return QStringLiteral("qca-ossl"); 6684 } 6685 6686 QString credit() const override 6687 { 6688 return QStringLiteral( 6689 "This product includes cryptographic software " 6690 "written by Eric Young (eay@cryptsoft.com)"); 6691 } 6692 6693 QStringList features() const override 6694 { 6695 QStringList list; 6696 list += QStringLiteral("random"); 6697 list += all_hash_types(); 6698 list += all_mac_types(); 6699 list += all_cipher_types(); 6700 if (s_legacyProviderAvailable) { 6701 #ifdef HAVE_OPENSSL_MD2 6702 list += QStringLiteral("pbkdf1(md2)"); 6703 #endif 6704 list += QStringLiteral("pbkdf1(sha1)"); 6705 } 6706 list += QStringLiteral("pkcs12"); 6707 list += QStringLiteral("pbkdf2(sha1)"); 6708 list += QStringLiteral("hkdf(sha256)"); 6709 list += QStringLiteral("pkey"); 6710 list += QStringLiteral("dlgroup"); 6711 list += QStringLiteral("rsa"); 6712 list += QStringLiteral("dsa"); 6713 list += QStringLiteral("dh"); 6714 list += QStringLiteral("cert"); 6715 list += QStringLiteral("csr"); 6716 list += QStringLiteral("crl"); 6717 list += QStringLiteral("certcollection"); 6718 list += QStringLiteral("tls"); 6719 list += QStringLiteral("cms"); 6720 list += QStringLiteral("ca"); 6721 6722 return list; 6723 } 6724 6725 Context *createContext(const QString &type) override 6726 { 6727 // OpenSSL_add_all_digests(); 6728 if (type == QLatin1String("random")) 6729 return new opensslRandomContext(this); 6730 else if (type == QLatin1String("info")) 6731 return new opensslInfoContext(this); 6732 else if (type == QLatin1String("sha1")) 6733 return new opensslHashContext(EVP_sha1(), this, type); 6734 #ifdef HAVE_OPENSSL_SHA0 6735 else if (type == QLatin1String("sha0")) 6736 return new opensslHashContext(EVP_sha(), this, type); 6737 #endif 6738 else if (type == QLatin1String("md5")) 6739 return new opensslHashContext(EVP_md5(), this, type); 6740 #ifdef SHA224_DIGEST_LENGTH 6741 else if (type == QLatin1String("sha224")) 6742 return new opensslHashContext(EVP_sha224(), this, type); 6743 #endif 6744 #ifdef SHA256_DIGEST_LENGTH 6745 else if (type == QLatin1String("sha256")) 6746 return new opensslHashContext(EVP_sha256(), this, type); 6747 #endif 6748 #ifdef SHA384_DIGEST_LENGTH 6749 else if (type == QLatin1String("sha384")) 6750 return new opensslHashContext(EVP_sha384(), this, type); 6751 #endif 6752 #ifdef SHA512_DIGEST_LENGTH 6753 else if (type == QLatin1String("sha512")) 6754 return new opensslHashContext(EVP_sha512(), this, type); 6755 #endif 6756 else if (type == QLatin1String("pbkdf2(sha1)")) 6757 return new opensslPbkdf2Context(this, type); 6758 else if (type == QLatin1String("hkdf(sha256)")) 6759 return new opensslHkdfContext(this, type); 6760 else if (type == QLatin1String("hmac(md5)")) 6761 return new opensslHMACContext(EVP_md5(), this, type); 6762 else if (type == QLatin1String("hmac(sha1)")) 6763 return new opensslHMACContext(EVP_sha1(), this, type); 6764 #ifdef SHA224_DIGEST_LENGTH 6765 else if (type == QLatin1String("hmac(sha224)")) 6766 return new opensslHMACContext(EVP_sha224(), this, type); 6767 #endif 6768 #ifdef SHA256_DIGEST_LENGTH 6769 else if (type == QLatin1String("hmac(sha256)")) 6770 return new opensslHMACContext(EVP_sha256(), this, type); 6771 #endif 6772 #ifdef SHA384_DIGEST_LENGTH 6773 else if (type == QLatin1String("hmac(sha384)")) 6774 return new opensslHMACContext(EVP_sha384(), this, type); 6775 #endif 6776 #ifdef SHA512_DIGEST_LENGTH 6777 else if (type == QLatin1String("hmac(sha512)")) 6778 return new opensslHMACContext(EVP_sha512(), this, type); 6779 #endif 6780 else if (type == QLatin1String("aes128-ecb")) 6781 return new opensslCipherContext(EVP_aes_128_ecb(), 0, this, type); 6782 else if (type == QLatin1String("aes128-cfb")) 6783 return new opensslCipherContext(EVP_aes_128_cfb(), 0, this, type); 6784 else if (type == QLatin1String("aes128-cbc")) 6785 return new opensslCipherContext(EVP_aes_128_cbc(), 0, this, type); 6786 else if (type == QLatin1String("aes128-cbc-pkcs7")) 6787 return new opensslCipherContext(EVP_aes_128_cbc(), 1, this, type); 6788 else if (type == QLatin1String("aes128-ofb")) 6789 return new opensslCipherContext(EVP_aes_128_ofb(), 0, this, type); 6790 #ifdef HAVE_OPENSSL_AES_CTR 6791 else if (type == QLatin1String("aes128-ctr")) 6792 return new opensslCipherContext(EVP_aes_128_ctr(), 0, this, type); 6793 #endif 6794 #ifdef HAVE_OPENSSL_AES_GCM 6795 else if (type == QLatin1String("aes128-gcm")) 6796 return new opensslCipherContext(EVP_aes_128_gcm(), 0, this, type); 6797 #endif 6798 #ifdef HAVE_OPENSSL_AES_CCM 6799 else if (type == QLatin1String("aes128-ccm")) 6800 return new opensslCipherContext(EVP_aes_128_ccm(), 0, this, type); 6801 #endif 6802 else if (type == QLatin1String("aes192-ecb")) 6803 return new opensslCipherContext(EVP_aes_192_ecb(), 0, this, type); 6804 else if (type == QLatin1String("aes192-cfb")) 6805 return new opensslCipherContext(EVP_aes_192_cfb(), 0, this, type); 6806 else if (type == QLatin1String("aes192-cbc")) 6807 return new opensslCipherContext(EVP_aes_192_cbc(), 0, this, type); 6808 else if (type == QLatin1String("aes192-cbc-pkcs7")) 6809 return new opensslCipherContext(EVP_aes_192_cbc(), 1, this, type); 6810 else if (type == QLatin1String("aes192-ofb")) 6811 return new opensslCipherContext(EVP_aes_192_ofb(), 0, this, type); 6812 #ifdef HAVE_OPENSSL_AES_CTR 6813 else if (type == QLatin1String("aes192-ctr")) 6814 return new opensslCipherContext(EVP_aes_192_ctr(), 0, this, type); 6815 #endif 6816 #ifdef HAVE_OPENSSL_AES_GCM 6817 else if (type == QLatin1String("aes192-gcm")) 6818 return new opensslCipherContext(EVP_aes_192_gcm(), 0, this, type); 6819 #endif 6820 #ifdef HAVE_OPENSSL_AES_CCM 6821 else if (type == QLatin1String("aes192-ccm")) 6822 return new opensslCipherContext(EVP_aes_192_ccm(), 0, this, type); 6823 #endif 6824 else if (type == QLatin1String("aes256-ecb")) 6825 return new opensslCipherContext(EVP_aes_256_ecb(), 0, this, type); 6826 else if (type == QLatin1String("aes256-cfb")) 6827 return new opensslCipherContext(EVP_aes_256_cfb(), 0, this, type); 6828 else if (type == QLatin1String("aes256-cbc")) 6829 return new opensslCipherContext(EVP_aes_256_cbc(), 0, this, type); 6830 else if (type == QLatin1String("aes256-cbc-pkcs7")) 6831 return new opensslCipherContext(EVP_aes_256_cbc(), 1, this, type); 6832 else if (type == QLatin1String("aes256-ofb")) 6833 return new opensslCipherContext(EVP_aes_256_ofb(), 0, this, type); 6834 #ifdef HAVE_OPENSSL_AES_CTR 6835 else if (type == QLatin1String("aes256-ctr")) 6836 return new opensslCipherContext(EVP_aes_256_ctr(), 0, this, type); 6837 #endif 6838 #ifdef HAVE_OPENSSL_AES_GCM 6839 else if (type == QLatin1String("aes256-gcm")) 6840 return new opensslCipherContext(EVP_aes_256_gcm(), 0, this, type); 6841 #endif 6842 #ifdef HAVE_OPENSSL_AES_CCM 6843 else if (type == QLatin1String("aes256-ccm")) 6844 return new opensslCipherContext(EVP_aes_256_ccm(), 0, this, type); 6845 #endif 6846 else if (type == QLatin1String("pkey")) 6847 return new MyPKeyContext(this); 6848 else if (type == QLatin1String("dlgroup")) 6849 return new MyDLGroup(this); 6850 else if (type == QLatin1String("rsa")) 6851 return new RSAKey(this); 6852 else if (type == QLatin1String("dsa")) 6853 return new DSAKey(this); 6854 else if (type == QLatin1String("dh")) 6855 return new DHKey(this); 6856 else if (type == QLatin1String("cert")) 6857 return new MyCertContext(this); 6858 else if (type == QLatin1String("csr")) 6859 return new MyCSRContext(this); 6860 else if (type == QLatin1String("crl")) 6861 return new MyCRLContext(this); 6862 else if (type == QLatin1String("certcollection")) 6863 return new MyCertCollectionContext(this); 6864 else if (type == QLatin1String("tls")) 6865 return new MyTLSContext(this); 6866 else if (type == QLatin1String("cms")) 6867 return new CMSContext(this); 6868 else if (type == QLatin1String("ca")) 6869 return new MyCAContext(this); 6870 else if (type == QLatin1String("tripledes-ecb")) 6871 return new opensslCipherContext(EVP_des_ede3(), 0, this, type); 6872 else if (type == QLatin1String("tripledes-cbc")) 6873 return new opensslCipherContext(EVP_des_ede3_cbc(), 0, this, type); 6874 else if (type == QLatin1String("pkcs12")) 6875 return new MyPKCS12Context(this); 6876 6877 else if (s_legacyProviderAvailable) { 6878 if (type == QLatin1String("blowfish-ecb")) 6879 return new opensslCipherContext(EVP_bf_ecb(), 0, this, type); 6880 else if (type == QLatin1String("blowfish-cfb")) 6881 return new opensslCipherContext(EVP_bf_cfb(), 0, this, type); 6882 else if (type == QLatin1String("blowfish-ofb")) 6883 return new opensslCipherContext(EVP_bf_ofb(), 0, this, type); 6884 else if (type == QLatin1String("blowfish-cbc")) 6885 return new opensslCipherContext(EVP_bf_cbc(), 0, this, type); 6886 else if (type == QLatin1String("blowfish-cbc-pkcs7")) 6887 return new opensslCipherContext(EVP_bf_cbc(), 1, this, type); 6888 else if (type == QLatin1String("des-ecb")) 6889 return new opensslCipherContext(EVP_des_ecb(), 0, this, type); 6890 else if (type == QLatin1String("des-ecb-pkcs7")) 6891 return new opensslCipherContext(EVP_des_ecb(), 1, this, type); 6892 else if (type == QLatin1String("des-cbc")) 6893 return new opensslCipherContext(EVP_des_cbc(), 0, this, type); 6894 else if (type == QLatin1String("des-cbc-pkcs7")) 6895 return new opensslCipherContext(EVP_des_cbc(), 1, this, type); 6896 else if (type == QLatin1String("des-cfb")) 6897 return new opensslCipherContext(EVP_des_cfb(), 0, this, type); 6898 else if (type == QLatin1String("des-ofb")) 6899 return new opensslCipherContext(EVP_des_ofb(), 0, this, type); 6900 #ifndef OPENSSL_NO_CAST 6901 else if (type == QLatin1String("cast5-ecb")) 6902 return new opensslCipherContext(EVP_cast5_ecb(), 0, this, type); 6903 else if (type == QLatin1String("cast5-cbc")) 6904 return new opensslCipherContext(EVP_cast5_cbc(), 0, this, type); 6905 else if (type == QLatin1String("cast5-cbc-pkcs7")) 6906 return new opensslCipherContext(EVP_cast5_cbc(), 1, this, type); 6907 else if (type == QLatin1String("cast5-cfb")) 6908 return new opensslCipherContext(EVP_cast5_cfb(), 0, this, type); 6909 else if (type == QLatin1String("cast5-ofb")) 6910 return new opensslCipherContext(EVP_cast5_ofb(), 0, this, type); 6911 #endif 6912 else if (type == QLatin1String("hmac(ripemd160)")) 6913 return new opensslHMACContext(EVP_ripemd160(), this, type); 6914 else if (type == QLatin1String("ripemd160")) 6915 return new opensslHashContext(EVP_ripemd160(), this, type); 6916 #ifdef HAVE_OPENSSL_MD2 6917 else if (type == QLatin1String("md2")) 6918 return new opensslHashContext(EVP_md2(), this, type); 6919 else if (type == QLatin1String("pbkdf1(md2)")) 6920 return new opensslPbkdf1Context(EVP_md2(), this, type); 6921 #endif 6922 else if (type == QLatin1String("md4")) 6923 return new opensslHashContext(EVP_md4(), this, type); 6924 #ifdef OBJ_whirlpool 6925 else if (type == QLatin1String("whirlpool")) 6926 return new opensslHashContext(EVP_whirlpool(), this, type); 6927 #endif 6928 else if (type == QLatin1String("pbkdf1(sha1)")) 6929 return new opensslPbkdf1Context(EVP_sha1(), this, type); 6930 } 6931 6932 return nullptr; 6933 } 6934 }; 6935 6936 class opensslPlugin : public QObject, public QCAPlugin 6937 { 6938 Q_OBJECT 6939 Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0") 6940 Q_INTERFACES(QCAPlugin) 6941 public: 6942 Provider *createProvider() override 6943 { 6944 return new opensslProvider; 6945 } 6946 }; 6947 6948 #include "qca-ossl.moc"