File indexing completed on 2025-03-09 04:48:08

0001 /*
0002  * SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
0003  * SPDX-License-Identifier: LGPL-2.0-or-later
0004  */
0005 
0006 #include "jwkloader_p.h"
0007 #include "logging.h"
0008 
0009 #include "openssl/bignum_p.h"
0010 
0011 #include <QFile>
0012 #include <QJsonDocument>
0013 #include <QJsonObject>
0014 
0015 #include <openssl/bn.h>
0016 #include <openssl/obj_mac.h>
0017 
0018 openssl::evp_pkey_ptr JwkLoader::loadPublicKey(const QString &fileName)
0019 {
0020     QFile f(fileName);
0021     if (!f.open(QFile::ReadOnly)) {
0022         qCWarning(Log) << f.errorString();
0023         return {};
0024     }
0025 
0026     return loadPublicKey(QJsonDocument::fromJson(f.readAll()).object());
0027 }
0028 
0029 openssl::evp_pkey_ptr JwkLoader::loadPublicKey(const QJsonObject &keyObj)
0030 {
0031     const auto kty = keyObj.value(QLatin1String("kty")).toString();
0032     if (kty == QLatin1String("EC")) {
0033         openssl::ec_key_ptr ecKey;
0034         const auto crv = keyObj.value(QLatin1String("crv")).toString();
0035         if (crv == QLatin1String("P-256")) {
0036             ecKey = openssl::ec_key_ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
0037         } else if (crv == QLatin1String("P-384")) {
0038             ecKey = openssl::ec_key_ptr(EC_KEY_new_by_curve_name(NID_secp384r1));
0039         } else if (crv == QLatin1String("P-521")) {
0040             ecKey = openssl::ec_key_ptr(EC_KEY_new_by_curve_name(NID_secp521r1));
0041         } else {
0042             qCWarning(Log) << "Unsupported curve type" << crv;
0043             return {};
0044         }
0045 
0046         const auto xData = QByteArray::fromBase64(keyObj.value(QLatin1String("x")).toString().toUtf8(), QByteArray::Base64UrlEncoding);
0047         const auto x = Bignum::fromByteArray(xData);
0048         const auto yData = QByteArray::fromBase64(keyObj.value(QLatin1String("y")).toString().toUtf8(), QByteArray::Base64UrlEncoding);
0049         const auto y = Bignum::fromByteArray(yData);
0050         EC_KEY_set_public_key_affine_coordinates(ecKey.get(), x.get(), y.get());
0051 
0052         openssl::evp_pkey_ptr evp(EVP_PKEY_new());
0053         EVP_PKEY_assign_EC_KEY(evp.get(), ecKey.release());
0054         return evp;
0055     } else {
0056         qCWarning(Log) << "unsuporrted key type:" << kty;
0057     }
0058 
0059     return {};
0060 }