Skip to content

Commit f0000e6

Browse files
committed
Unsupported
Signed-off-by: Raul Metsma <[email protected]>
1 parent cd27604 commit f0000e6

File tree

12 files changed

+40
-59
lines changed

12 files changed

+40
-59
lines changed

client/CDoc1.cpp

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ const QString CDoc1::AES128GCM_MTH = QStringLiteral("http://www.w3.org/2009/xmle
4141
const QString CDoc1::AES192GCM_MTH = QStringLiteral("http://www.w3.org/2009/xmlenc11#aes192-gcm");
4242
const QString CDoc1::AES256GCM_MTH = QStringLiteral("http://www.w3.org/2009/xmlenc11#aes256-gcm");
4343
const QString CDoc1::RSA_MTH = QStringLiteral("http://www.w3.org/2001/04/xmlenc#rsa-1_5");
44-
const QString CDoc1::KWAES128_MTH = QStringLiteral("http://www.w3.org/2001/04/xmlenc#kw-aes128");
45-
const QString CDoc1::KWAES192_MTH = QStringLiteral("http://www.w3.org/2001/04/xmlenc#kw-aes192");
4644
const QString CDoc1::KWAES256_MTH = QStringLiteral("http://www.w3.org/2001/04/xmlenc#kw-aes256");
4745
const QString CDoc1::CONCATKDF_MTH = QStringLiteral("http://www.w3.org/2009/xmlenc11#ConcatKDF");
4846
const QString CDoc1::AGREEMENT_MTH = QStringLiteral("http://www.w3.org/2009/xmlenc11#ECDH-ES");
@@ -66,7 +64,6 @@ const QHash<QString, const EVP_CIPHER*> CDoc1::ENC_MTH{
6664
const QHash<QString, QCryptographicHash::Algorithm> CDoc1::SHA_MTH{
6765
{SHA256_MTH, QCryptographicHash::Sha256}, {SHA384_MTH, QCryptographicHash::Sha384}, {SHA512_MTH, QCryptographicHash::Sha512}
6866
};
69-
const QHash<QString, quint32> CDoc1::KWAES_SIZE{{KWAES128_MTH, 16}, {KWAES192_MTH, 24}, {KWAES256_MTH, 32}};
7067

7168
CDoc1::CDoc1(const QString &path)
7269
: QFile(path)
@@ -108,7 +105,6 @@ CDoc1::CDoc1(const QString &path)
108105
return;
109106

110107
CKey key;
111-
key.id = xml.attributes().value(QLatin1String("Id")).toString();
112108
key.recipient = xml.attributes().value(QLatin1String("Recipient")).toString();
113109
while(!xml.atEnd())
114110
{
@@ -117,18 +113,17 @@ CDoc1::CDoc1(const QString &path)
117113
break;
118114
if(!xml.isStartElement())
119115
continue;
120-
// EncryptedData/KeyInfo/KeyName
121-
if(xml.name() == QLatin1String("KeyName"))
122-
key.name = xml.readElementText();
123-
// EncryptedData/KeyInfo/EncryptedKey/EncryptionMethod
124-
else if(xml.name() == QLatin1String("EncryptionMethod"))
125-
key.method = xml.attributes().value(QLatin1String("Algorithm")).toString();
116+
if(xml.name() == QLatin1String("EncryptionMethod"))
117+
{
118+
auto method = xml.attributes().value(QLatin1String("Algorithm"));
119+
key.unsupported = std::max(key.unsupported, method != KWAES256_MTH || method != RSA_MTH);
120+
}
126121
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/AgreementMethod
127122
else if(xml.name() == QLatin1String("AgreementMethod"))
128-
key.agreement = xml.attributes().value(QLatin1String("Algorithm")).toString();
123+
key.unsupported = std::max(key.unsupported, xml.attributes().value(QLatin1String("Algorithm")) != AGREEMENT_MTH);
129124
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/AgreementMethod/KeyDerivationMethod
130125
else if(xml.name() == QLatin1String("KeyDerivationMethod"))
131-
key.derive = xml.attributes().value(QLatin1String("Algorithm")).toString();
126+
key.unsupported = std::max(key.unsupported, xml.attributes().value(QLatin1String("Algorithm")) != CONCATKDF_MTH);
132127
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/AgreementMethod/KeyDerivationMethod/ConcatKDFParams
133128
else if(xml.name() == QLatin1String("ConcatKDFParams"))
134129
{
@@ -273,16 +268,13 @@ CKey CDoc1::canDecrypt(const QSslCertificate &cert) const
273268
{
274269
if(!ENC_MTH.contains(method) ||
275270
k.cert != cert ||
276-
k.cipher.isEmpty())
271+
k.cipher.isEmpty() ||
272+
k.unsupported)
277273
continue;
278-
if(cert.publicKey().algorithm() == QSsl::Rsa &&
279-
k.method == RSA_MTH)
274+
if(cert.publicKey().algorithm() == QSsl::Rsa)
280275
return k;
281276
if(cert.publicKey().algorithm() == QSsl::Ec &&
282-
!k.publicKey.isEmpty() &&
283-
KWAES_SIZE.contains(k.method) &&
284-
k.derive == CONCATKDF_MTH &&
285-
k.agreement == AGREEMENT_MTH)
277+
!k.publicKey.isEmpty())
286278
return k;
287279
}
288280
return {};
@@ -432,8 +424,6 @@ bool CDoc1::save(const QString &path)
432424
for(const CKey &k: qAsConst(keys))
433425
{
434426
writeElement(w, DENC, QStringLiteral("EncryptedKey"), [&]{
435-
if(!k.id.isEmpty())
436-
w.writeAttribute(QStringLiteral("Id"), k.id);
437427
if(!k.recipient.isEmpty())
438428
w.writeAttribute(QStringLiteral("Recipient"), k.recipient);
439429
QByteArray cipher;
@@ -446,8 +436,6 @@ bool CDoc1::save(const QString &path)
446436
{QStringLiteral("Algorithm"), RSA_MTH},
447437
});
448438
writeElement(w, DS, QStringLiteral("KeyInfo"), [&]{
449-
if(!k.name.isEmpty())
450-
w.writeTextElement(DS, QStringLiteral("KeyName"), k.name);
451439
writeElement(w, DS, QStringLiteral("X509Data"), [&]{
452440
writeBase64Element(w, DS, QStringLiteral("X509Certificate"), k.cert.toDer());
453441
});
@@ -464,14 +452,13 @@ bool CDoc1::save(const QString &path)
464452
QByteArray oid = Crypto::curve_oid(peerPKey);
465453
QByteArray SsDer = Crypto::toPublicKeyDer(priv.get());
466454

467-
const QString encryptionMethod = KWAES256_MTH;
468455
QString concatDigest = SHA384_MTH;
469456
switch((SsDer.size() - 1) / 2) {
470457
case 32: concatDigest = SHA256_MTH; break;
471458
case 48: concatDigest = SHA384_MTH; break;
472459
default: concatDigest = SHA512_MTH; break;
473460
}
474-
QByteArray encryptionKey = Crypto::concatKDF(SHA_MTH[concatDigest], KWAES_SIZE[encryptionMethod],
461+
QByteArray encryptionKey = Crypto::concatKDF(SHA_MTH[concatDigest],
475462
sharedSecret, props.value(QStringLiteral("DocumentFormat")).toUtf8() + SsDer + k.cert.toDer());
476463
#ifndef NDEBUG
477464
qDebug() << "ENC Ss" << SsDer.toHex();
@@ -484,7 +471,7 @@ bool CDoc1::save(const QString &path)
484471
return;
485472

486473
writeElement(w, DENC, QStringLiteral("EncryptionMethod"), {
487-
{QStringLiteral("Algorithm"), encryptionMethod},
474+
{QStringLiteral("Algorithm"), KWAES256_MTH},
488475
});
489476
writeElement(w, DS, QStringLiteral("KeyInfo"), [&]{
490477
writeElement(w, DENC, QStringLiteral("AgreementMethod"), {
@@ -553,7 +540,7 @@ QByteArray CDoc1::transportKey(const CKey &key)
553540
if(key.isRSA)
554541
return backend->decrypt(key.cipher, false);
555542
return backend->deriveConcatKDF(key.publicKey, SHA_MTH[key.concatDigest],
556-
int(KWAES_SIZE[key.method]), key.AlgorithmID, key.PartyUInfo, key.PartyVInfo);
543+
key.AlgorithmID, key.PartyUInfo, key.PartyVInfo);
557544
});
558545
if(decryptedKey.isEmpty())
559546
{

client/CDoc1.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,10 @@ class CDoc1 final: public CDoc, private QFile
5757
static const QString
5858
AES128CBC_MTH, AES192CBC_MTH, AES256CBC_MTH,
5959
AES128GCM_MTH, AES192GCM_MTH, AES256GCM_MTH,
60-
KWAES128_MTH, KWAES192_MTH, KWAES256_MTH,
6160
SHA256_MTH, SHA384_MTH, SHA512_MTH,
62-
RSA_MTH, CONCATKDF_MTH, AGREEMENT_MTH;
61+
RSA_MTH, CONCATKDF_MTH, AGREEMENT_MTH, KWAES256_MTH;
6362
static const QString DS, DENC, DSIG11, XENC11;
6463
static const QString MIME_ZLIB, MIME_DDOC, MIME_DDOC_OLD;
6564
static const QHash<QString, const EVP_CIPHER*> ENC_MTH;
6665
static const QHash<QString, QCryptographicHash::Algorithm> SHA_MTH;
67-
static const QHash<QString, quint32> KWAES_SIZE;
6866
};

client/CDoc2.cpp

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -432,26 +432,23 @@ CDoc2::CDoc2(const QString &path)
432432
for(const auto *recipient: *recipients){
433433
if(recipient->fmk_encryption_method() != FMKEncryptionMethod::XOR)
434434
{
435+
keys.append(CKey::unsupportedKey);
435436
qWarning() << "Unsupported FMK encryption method: skipping";
436437
continue;
437438
}
438-
auto fillRecipient = [&] (auto key, bool isRSA) {
439+
auto fillRecipient = [&] (auto key, bool isRSA, bool unsupported = false) {
439440
CKey k(toByteArray(key->recipient_public_key()), isRSA);
440441
k.recipient = toString(recipient->key_label());
441442
k.cipher = toByteArray(recipient->encrypted_fmk());
443+
k.unsupported = unsupported;
442444
return k;
443445
};
444446
switch(recipient->capsule_type())
445447
{
446448
case Capsule::ECCPublicKeyCapsule:
447449
if(const auto *key = recipient->capsule_as_ECCPublicKeyCapsule())
448450
{
449-
if(key->curve() != EllipticCurve::secp384r1)
450-
{
451-
qWarning() << "Unsupported ECC curve: skipping";
452-
continue;
453-
}
454-
CKey k = fillRecipient(key, false);
451+
CKey k = fillRecipient(key, false, key->curve() != EllipticCurve::secp384r1);
455452
k.publicKey = toByteArray(key->sender_public_key());
456453
keys.append(std::move(k));
457454
}
@@ -467,8 +464,8 @@ CDoc2::CDoc2(const QString &path)
467464
case Capsule::KeyServerCapsule:
468465
if(const auto *server = recipient->capsule_as_KeyServerCapsule())
469466
{
470-
auto fillKeyServer = [&] (auto key, bool isRSA) {
471-
CKey k = fillRecipient(key, isRSA);
467+
auto fillKeyServer = [&] (auto key, bool isRSA, bool unsupported = false) {
468+
CKey k = fillRecipient(key, isRSA, unsupported);
472469
k.keyserver_id = toString(server->keyserver_id());
473470
k.transaction_id = toString(server->transaction_id());
474471
return k;
@@ -477,21 +474,20 @@ CDoc2::CDoc2(const QString &path)
477474
{
478475
case ServerDetailsUnion::ServerEccDetails:
479476
if(const auto *eccDetails = server->recipient_key_details_as_ServerEccDetails())
480-
{
481-
if(eccDetails->curve() == EllipticCurve::secp384r1)
482-
keys.append(fillKeyServer(eccDetails, false));
483-
}
477+
keys.append(fillKeyServer(eccDetails, false, eccDetails->curve() != EllipticCurve::secp384r1));
484478
break;
485479
case ServerDetailsUnion::ServerRsaDetails:
486480
if(const auto *rsaDetails = server->recipient_key_details_as_ServerRsaDetails())
487481
keys.append(fillKeyServer(rsaDetails, true));
488482
break;
489483
default:
484+
keys.append(CKey::unsupportedKey);
490485
qWarning() << "Unsupported Key Server Details: skipping";
491486
}
492487
}
493488
break;
494489
default:
490+
keys.append(CKey::unsupportedKey);
495491
qWarning() << "Unsupported Key Details: skipping";
496492
}
497493
}

client/Crypto.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,11 @@ QByteArray Crypto::cipher(const EVP_CIPHER *cipher, const QByteArray &key, QByte
144144
return data;
145145
}
146146

147-
QByteArray Crypto::concatKDF(QCryptographicHash::Algorithm hashAlg, quint32 keyDataLen, const QByteArray &z, const QByteArray &otherInfo)
147+
QByteArray Crypto::concatKDF(QCryptographicHash::Algorithm hashAlg, const QByteArray &z, const QByteArray &otherInfo)
148148
{
149149
if(z.isEmpty())
150150
return z;
151+
quint32 keyDataLen = 32;
151152
auto hashLen = quint32(QCryptographicHash::hashLength(hashAlg));
152153
auto reps = quint32(std::ceil(double(keyDataLen) / double(hashLen)));
153154
QCryptographicHash md(hashAlg);

client/Crypto.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ class Crypto
5353
static QByteArray aes_wrap(const QByteArray &key, const QByteArray &data, bool encrypt);
5454
static QByteArray cipher(const EVP_CIPHER *cipher, const QByteArray &key, QByteArray &data, bool encrypt);
5555
static QByteArray curve_oid(EVP_PKEY *key);
56-
static QByteArray concatKDF(QCryptographicHash::Algorithm digestMethod,
57-
quint32 keyDataLen, const QByteArray &z, const QByteArray &otherInfo);
56+
static QByteArray concatKDF(QCryptographicHash::Algorithm digestMethod, const QByteArray &z, const QByteArray &otherInfo);
5857
static QByteArray derive(EVP_PKEY *priv, EVP_PKEY *pub);
5958
static QByteArray encrypt(EVP_PKEY *pub, int padding, const QByteArray &data);
6059
static QByteArray expand(const QByteArray &key, const QByteArray &info, int len = 32);

client/CryptoDoc.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ void CKey::setCert(const QSslCertificate &c)
246246
isRSA = k.algorithm() == QSsl::Rsa;
247247
}
248248

249+
const CKey CKey::unsupportedKey = {};
250+
249251

250252
CryptoDoc::CryptoDoc( QObject *parent )
251253
: QObject(parent)

client/CryptoDoc.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@ class CKey
3939

4040
void setCert(const QSslCertificate &c);
4141

42+
static const CKey unsupportedKey;
43+
4244
QByteArray key, cipher, publicKey;
4345
QSslCertificate cert;
44-
bool isRSA = false;
46+
bool isRSA = false, unsupported = false;
4547
QString recipient;
4648
// CDoc1
47-
QString agreement, concatDigest, derive, method, id, name;
49+
QString concatDigest;
4850
QByteArray AlgorithmID, PartyUInfo, PartyVInfo;
4951
// CDoc2
5052
QByteArray encrypted_kek;

client/QCryptoBackend.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class QCryptoBackend: public QObject
2828
{
2929
Q_OBJECT
3030
public:
31-
enum PinStatus
31+
enum PinStatus : quint8
3232
{
3333
PinOK,
3434
PinCanceled,
@@ -43,7 +43,7 @@ class QCryptoBackend: public QObject
4343

4444
virtual QList<TokenData> tokens() const = 0;
4545
virtual QByteArray decrypt(const QByteArray &data, bool oaep) const = 0;
46-
virtual QByteArray deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest, int keySize,
46+
virtual QByteArray deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest,
4747
const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const = 0;
4848
virtual QByteArray deriveHMACExtract(const QByteArray &publicKey, const QByteArray &salt, int keySize) const = 0;
4949
virtual PinStatus lastError() const { return PinOK; }

client/QPKCS11.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,9 @@ QByteArray QPKCS11::derive(const QByteArray &publicKey) const
141141
}
142142

143143
QByteArray QPKCS11::deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest,
144-
int keySize, const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const
144+
const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const
145145
{
146-
return Crypto::concatKDF(digest, quint32(keySize), derive(publicKey), algorithmID + partyUInfo + partyVInfo);
146+
return Crypto::concatKDF(digest, derive(publicKey), algorithmID + partyUInfo + partyVInfo);
147147
}
148148

149149
QByteArray QPKCS11::deriveHMACExtract(const QByteArray &publicKey, const QByteArray &salt, int keySize) const

client/QPKCS11.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class QPKCS11 final: public QCryptoBackend
3030

3131
QByteArray decrypt(const QByteArray &data, bool oaep) const final;
3232
QByteArray derive(const QByteArray &publicKey) const;
33-
QByteArray deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest, int keySize,
33+
QByteArray deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest,
3434
const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const final;
3535
QByteArray deriveHMACExtract(const QByteArray &publicKey, const QByteArray &salt, int keySize) const final;
3636
bool isLoaded() const;

0 commit comments

Comments
 (0)