Skip to content

Commit

Permalink
Unsupported
Browse files Browse the repository at this point in the history
Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Nov 13, 2024
1 parent cd27604 commit f0000e6
Show file tree
Hide file tree
Showing 12 changed files with 40 additions and 59 deletions.
41 changes: 14 additions & 27 deletions client/CDoc1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ const QString CDoc1::AES128GCM_MTH = QStringLiteral("http://www.w3.org/2009/xmle
const QString CDoc1::AES192GCM_MTH = QStringLiteral("http://www.w3.org/2009/xmlenc11#aes192-gcm");
const QString CDoc1::AES256GCM_MTH = QStringLiteral("http://www.w3.org/2009/xmlenc11#aes256-gcm");
const QString CDoc1::RSA_MTH = QStringLiteral("http://www.w3.org/2001/04/xmlenc#rsa-1_5");
const QString CDoc1::KWAES128_MTH = QStringLiteral("http://www.w3.org/2001/04/xmlenc#kw-aes128");
const QString CDoc1::KWAES192_MTH = QStringLiteral("http://www.w3.org/2001/04/xmlenc#kw-aes192");
const QString CDoc1::KWAES256_MTH = QStringLiteral("http://www.w3.org/2001/04/xmlenc#kw-aes256");
const QString CDoc1::CONCATKDF_MTH = QStringLiteral("http://www.w3.org/2009/xmlenc11#ConcatKDF");
const QString CDoc1::AGREEMENT_MTH = QStringLiteral("http://www.w3.org/2009/xmlenc11#ECDH-ES");
Expand All @@ -66,7 +64,6 @@ const QHash<QString, const EVP_CIPHER*> CDoc1::ENC_MTH{
const QHash<QString, QCryptographicHash::Algorithm> CDoc1::SHA_MTH{
{SHA256_MTH, QCryptographicHash::Sha256}, {SHA384_MTH, QCryptographicHash::Sha384}, {SHA512_MTH, QCryptographicHash::Sha512}
};
const QHash<QString, quint32> CDoc1::KWAES_SIZE{{KWAES128_MTH, 16}, {KWAES192_MTH, 24}, {KWAES256_MTH, 32}};

CDoc1::CDoc1(const QString &path)
: QFile(path)
Expand Down Expand Up @@ -108,7 +105,6 @@ CDoc1::CDoc1(const QString &path)
return;

CKey key;
key.id = xml.attributes().value(QLatin1String("Id")).toString();
key.recipient = xml.attributes().value(QLatin1String("Recipient")).toString();
while(!xml.atEnd())
{
Expand All @@ -117,18 +113,17 @@ CDoc1::CDoc1(const QString &path)
break;
if(!xml.isStartElement())
continue;
// EncryptedData/KeyInfo/KeyName
if(xml.name() == QLatin1String("KeyName"))
key.name = xml.readElementText();
// EncryptedData/KeyInfo/EncryptedKey/EncryptionMethod
else if(xml.name() == QLatin1String("EncryptionMethod"))
key.method = xml.attributes().value(QLatin1String("Algorithm")).toString();
if(xml.name() == QLatin1String("EncryptionMethod"))
{
auto method = xml.attributes().value(QLatin1String("Algorithm"));
key.unsupported = std::max(key.unsupported, method != KWAES256_MTH || method != RSA_MTH);
}
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/AgreementMethod
else if(xml.name() == QLatin1String("AgreementMethod"))
key.agreement = xml.attributes().value(QLatin1String("Algorithm")).toString();
key.unsupported = std::max(key.unsupported, xml.attributes().value(QLatin1String("Algorithm")) != AGREEMENT_MTH);
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/AgreementMethod/KeyDerivationMethod
else if(xml.name() == QLatin1String("KeyDerivationMethod"))
key.derive = xml.attributes().value(QLatin1String("Algorithm")).toString();
key.unsupported = std::max(key.unsupported, xml.attributes().value(QLatin1String("Algorithm")) != CONCATKDF_MTH);
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/AgreementMethod/KeyDerivationMethod/ConcatKDFParams
else if(xml.name() == QLatin1String("ConcatKDFParams"))
{
Expand Down Expand Up @@ -273,16 +268,13 @@ CKey CDoc1::canDecrypt(const QSslCertificate &cert) const
{
if(!ENC_MTH.contains(method) ||
k.cert != cert ||
k.cipher.isEmpty())
k.cipher.isEmpty() ||
k.unsupported)
continue;
if(cert.publicKey().algorithm() == QSsl::Rsa &&
k.method == RSA_MTH)
if(cert.publicKey().algorithm() == QSsl::Rsa)
return k;
if(cert.publicKey().algorithm() == QSsl::Ec &&
!k.publicKey.isEmpty() &&
KWAES_SIZE.contains(k.method) &&
k.derive == CONCATKDF_MTH &&
k.agreement == AGREEMENT_MTH)
!k.publicKey.isEmpty())
return k;
}
return {};
Expand Down Expand Up @@ -432,8 +424,6 @@ bool CDoc1::save(const QString &path)
for(const CKey &k: qAsConst(keys))
{
writeElement(w, DENC, QStringLiteral("EncryptedKey"), [&]{
if(!k.id.isEmpty())
w.writeAttribute(QStringLiteral("Id"), k.id);
if(!k.recipient.isEmpty())
w.writeAttribute(QStringLiteral("Recipient"), k.recipient);
QByteArray cipher;
Expand All @@ -446,8 +436,6 @@ bool CDoc1::save(const QString &path)
{QStringLiteral("Algorithm"), RSA_MTH},
});
writeElement(w, DS, QStringLiteral("KeyInfo"), [&]{
if(!k.name.isEmpty())
w.writeTextElement(DS, QStringLiteral("KeyName"), k.name);
writeElement(w, DS, QStringLiteral("X509Data"), [&]{
writeBase64Element(w, DS, QStringLiteral("X509Certificate"), k.cert.toDer());
});
Expand All @@ -464,14 +452,13 @@ bool CDoc1::save(const QString &path)
QByteArray oid = Crypto::curve_oid(peerPKey);
QByteArray SsDer = Crypto::toPublicKeyDer(priv.get());

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

writeElement(w, DENC, QStringLiteral("EncryptionMethod"), {
{QStringLiteral("Algorithm"), encryptionMethod},
{QStringLiteral("Algorithm"), KWAES256_MTH},
});
writeElement(w, DS, QStringLiteral("KeyInfo"), [&]{
writeElement(w, DENC, QStringLiteral("AgreementMethod"), {
Expand Down Expand Up @@ -553,7 +540,7 @@ QByteArray CDoc1::transportKey(const CKey &key)
if(key.isRSA)
return backend->decrypt(key.cipher, false);
return backend->deriveConcatKDF(key.publicKey, SHA_MTH[key.concatDigest],
int(KWAES_SIZE[key.method]), key.AlgorithmID, key.PartyUInfo, key.PartyVInfo);
key.AlgorithmID, key.PartyUInfo, key.PartyVInfo);
});
if(decryptedKey.isEmpty())
{
Expand Down
4 changes: 1 addition & 3 deletions client/CDoc1.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,10 @@ class CDoc1 final: public CDoc, private QFile
static const QString
AES128CBC_MTH, AES192CBC_MTH, AES256CBC_MTH,
AES128GCM_MTH, AES192GCM_MTH, AES256GCM_MTH,
KWAES128_MTH, KWAES192_MTH, KWAES256_MTH,
SHA256_MTH, SHA384_MTH, SHA512_MTH,
RSA_MTH, CONCATKDF_MTH, AGREEMENT_MTH;
RSA_MTH, CONCATKDF_MTH, AGREEMENT_MTH, KWAES256_MTH;
static const QString DS, DENC, DSIG11, XENC11;
static const QString MIME_ZLIB, MIME_DDOC, MIME_DDOC_OLD;
static const QHash<QString, const EVP_CIPHER*> ENC_MTH;
static const QHash<QString, QCryptographicHash::Algorithm> SHA_MTH;
static const QHash<QString, quint32> KWAES_SIZE;
};
22 changes: 9 additions & 13 deletions client/CDoc2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,26 +432,23 @@ CDoc2::CDoc2(const QString &path)
for(const auto *recipient: *recipients){
if(recipient->fmk_encryption_method() != FMKEncryptionMethod::XOR)
{
keys.append(CKey::unsupportedKey);
qWarning() << "Unsupported FMK encryption method: skipping";
continue;
}
auto fillRecipient = [&] (auto key, bool isRSA) {
auto fillRecipient = [&] (auto key, bool isRSA, bool unsupported = false) {
CKey k(toByteArray(key->recipient_public_key()), isRSA);
k.recipient = toString(recipient->key_label());
k.cipher = toByteArray(recipient->encrypted_fmk());
k.unsupported = unsupported;
return k;
};
switch(recipient->capsule_type())
{
case Capsule::ECCPublicKeyCapsule:
if(const auto *key = recipient->capsule_as_ECCPublicKeyCapsule())
{
if(key->curve() != EllipticCurve::secp384r1)
{
qWarning() << "Unsupported ECC curve: skipping";
continue;
}
CKey k = fillRecipient(key, false);
CKey k = fillRecipient(key, false, key->curve() != EllipticCurve::secp384r1);
k.publicKey = toByteArray(key->sender_public_key());
keys.append(std::move(k));
}
Expand All @@ -467,8 +464,8 @@ CDoc2::CDoc2(const QString &path)
case Capsule::KeyServerCapsule:
if(const auto *server = recipient->capsule_as_KeyServerCapsule())
{
auto fillKeyServer = [&] (auto key, bool isRSA) {
CKey k = fillRecipient(key, isRSA);
auto fillKeyServer = [&] (auto key, bool isRSA, bool unsupported = false) {
CKey k = fillRecipient(key, isRSA, unsupported);
k.keyserver_id = toString(server->keyserver_id());
k.transaction_id = toString(server->transaction_id());
return k;
Expand All @@ -477,21 +474,20 @@ CDoc2::CDoc2(const QString &path)
{
case ServerDetailsUnion::ServerEccDetails:
if(const auto *eccDetails = server->recipient_key_details_as_ServerEccDetails())
{
if(eccDetails->curve() == EllipticCurve::secp384r1)
keys.append(fillKeyServer(eccDetails, false));
}
keys.append(fillKeyServer(eccDetails, false, eccDetails->curve() != EllipticCurve::secp384r1));
break;
case ServerDetailsUnion::ServerRsaDetails:
if(const auto *rsaDetails = server->recipient_key_details_as_ServerRsaDetails())
keys.append(fillKeyServer(rsaDetails, true));
break;
default:
keys.append(CKey::unsupportedKey);
qWarning() << "Unsupported Key Server Details: skipping";
}
}
break;
default:
keys.append(CKey::unsupportedKey);
qWarning() << "Unsupported Key Details: skipping";
}
}
Expand Down
3 changes: 2 additions & 1 deletion client/Crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,11 @@ QByteArray Crypto::cipher(const EVP_CIPHER *cipher, const QByteArray &key, QByte
return data;
}

QByteArray Crypto::concatKDF(QCryptographicHash::Algorithm hashAlg, quint32 keyDataLen, const QByteArray &z, const QByteArray &otherInfo)
QByteArray Crypto::concatKDF(QCryptographicHash::Algorithm hashAlg, const QByteArray &z, const QByteArray &otherInfo)
{
if(z.isEmpty())
return z;
quint32 keyDataLen = 32;
auto hashLen = quint32(QCryptographicHash::hashLength(hashAlg));
auto reps = quint32(std::ceil(double(keyDataLen) / double(hashLen)));
QCryptographicHash md(hashAlg);
Expand Down
3 changes: 1 addition & 2 deletions client/Crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ class Crypto
static QByteArray aes_wrap(const QByteArray &key, const QByteArray &data, bool encrypt);
static QByteArray cipher(const EVP_CIPHER *cipher, const QByteArray &key, QByteArray &data, bool encrypt);
static QByteArray curve_oid(EVP_PKEY *key);
static QByteArray concatKDF(QCryptographicHash::Algorithm digestMethod,
quint32 keyDataLen, const QByteArray &z, const QByteArray &otherInfo);
static QByteArray concatKDF(QCryptographicHash::Algorithm digestMethod, const QByteArray &z, const QByteArray &otherInfo);
static QByteArray derive(EVP_PKEY *priv, EVP_PKEY *pub);
static QByteArray encrypt(EVP_PKEY *pub, int padding, const QByteArray &data);
static QByteArray expand(const QByteArray &key, const QByteArray &info, int len = 32);
Expand Down
2 changes: 2 additions & 0 deletions client/CryptoDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ void CKey::setCert(const QSslCertificate &c)
isRSA = k.algorithm() == QSsl::Rsa;
}

const CKey CKey::unsupportedKey = {};


CryptoDoc::CryptoDoc( QObject *parent )
: QObject(parent)
Expand Down
6 changes: 4 additions & 2 deletions client/CryptoDoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ class CKey

void setCert(const QSslCertificate &c);

static const CKey unsupportedKey;

QByteArray key, cipher, publicKey;
QSslCertificate cert;
bool isRSA = false;
bool isRSA = false, unsupported = false;
QString recipient;
// CDoc1
QString agreement, concatDigest, derive, method, id, name;
QString concatDigest;
QByteArray AlgorithmID, PartyUInfo, PartyVInfo;
// CDoc2
QByteArray encrypted_kek;
Expand Down
4 changes: 2 additions & 2 deletions client/QCryptoBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class QCryptoBackend: public QObject
{
Q_OBJECT
public:
enum PinStatus
enum PinStatus : quint8
{
PinOK,
PinCanceled,
Expand All @@ -43,7 +43,7 @@ class QCryptoBackend: public QObject

virtual QList<TokenData> tokens() const = 0;
virtual QByteArray decrypt(const QByteArray &data, bool oaep) const = 0;
virtual QByteArray deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest, int keySize,
virtual QByteArray deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest,
const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const = 0;
virtual QByteArray deriveHMACExtract(const QByteArray &publicKey, const QByteArray &salt, int keySize) const = 0;
virtual PinStatus lastError() const { return PinOK; }
Expand Down
4 changes: 2 additions & 2 deletions client/QPKCS11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ QByteArray QPKCS11::derive(const QByteArray &publicKey) const
}

QByteArray QPKCS11::deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest,
int keySize, const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const
const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const
{
return Crypto::concatKDF(digest, quint32(keySize), derive(publicKey), algorithmID + partyUInfo + partyVInfo);
return Crypto::concatKDF(digest, derive(publicKey), algorithmID + partyUInfo + partyVInfo);
}

QByteArray QPKCS11::deriveHMACExtract(const QByteArray &publicKey, const QByteArray &salt, int keySize) const
Expand Down
2 changes: 1 addition & 1 deletion client/QPKCS11.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class QPKCS11 final: public QCryptoBackend

QByteArray decrypt(const QByteArray &data, bool oaep) const final;
QByteArray derive(const QByteArray &publicKey) const;
QByteArray deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest, int keySize,
QByteArray deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash::Algorithm digest,
const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const final;
QByteArray deriveHMACExtract(const QByteArray &publicKey, const QByteArray &salt, int keySize) const final;
bool isLoaded() const;
Expand Down
6 changes: 1 addition & 5 deletions client/dialogs/KeyDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,11 @@ KeyDialog::KeyDialog( const CKey &k, QWidget *parent )
};

addItem(tr("Recipient"), k.recipient);
addItem(tr("Crypto method"), k.method);
addItem(tr("Agreement method"), k.agreement);
addItem(tr("Key derivation method"), k.derive);
addItem(tr("ConcatKDF digest method"), k.concatDigest);
addItem(tr("Key server ID"), k.keyserver_id);
addItem(tr("Transaction ID"), k.transaction_id);
addItem(tr("Expiry date"), k.cert.expiryDate().toLocalTime().toString(QStringLiteral("dd.MM.yyyy hh:mm:ss")));
addItem(tr("Issuer"), SslCertificate(k.cert).issuerInfo(QSslCertificate::CommonName));
d->view->resizeColumnToContents( 0 );
if(!k.agreement.isEmpty())
adjustSize();
adjustSize();
}
2 changes: 1 addition & 1 deletion common
Submodule common updated 0 files

0 comments on commit f0000e6

Please sign in to comment.