mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 22:04:26 +00:00
Merge "Support to get EC public key from the UdsCertchain." am: 1acca5c139 am: 8426045977
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2615472 Change-Id: I4b151dbfba422fb6c6d6b35da8f73e2fa2196211 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -115,6 +115,36 @@ ErrMsgOr<std::tuple<bytevec, bytevec>> getAffineCoordinates(const bytevec& pubKe
|
|||||||
return std::make_tuple(std::move(pubX), std::move(pubY));
|
return std::make_tuple(std::move(pubX), std::move(pubY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrMsgOr<bytevec> getRawPublicKey(const EVP_PKEY_Ptr& pubKey) {
|
||||||
|
if (pubKey.get() == nullptr) {
|
||||||
|
return "pkey is null.";
|
||||||
|
}
|
||||||
|
int keyType = EVP_PKEY_base_id(pubKey.get());
|
||||||
|
switch (keyType) {
|
||||||
|
case EVP_PKEY_EC: {
|
||||||
|
auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pubKey.get()));
|
||||||
|
if (ecKey.get() == nullptr) {
|
||||||
|
return "Failed to get ec key";
|
||||||
|
}
|
||||||
|
return ecKeyGetPublicKey(ecKey.get());
|
||||||
|
}
|
||||||
|
case EVP_PKEY_ED25519: {
|
||||||
|
bytevec rawPubKey;
|
||||||
|
size_t rawKeySize = 0;
|
||||||
|
if (!EVP_PKEY_get_raw_public_key(pubKey.get(), NULL, &rawKeySize)) {
|
||||||
|
return "Failed to get raw public key.";
|
||||||
|
}
|
||||||
|
rawPubKey.resize(rawKeySize);
|
||||||
|
if (!EVP_PKEY_get_raw_public_key(pubKey.get(), rawPubKey.data(), &rawKeySize)) {
|
||||||
|
return "Failed to get raw public key.";
|
||||||
|
}
|
||||||
|
return rawPubKey;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return "Unknown key type.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ErrMsgOr<std::tuple<bytevec, bytevec>> generateEc256KeyPair() {
|
ErrMsgOr<std::tuple<bytevec, bytevec>> generateEc256KeyPair() {
|
||||||
auto ec_key = EC_KEY_Ptr(EC_KEY_new());
|
auto ec_key = EC_KEY_Ptr(EC_KEY_new());
|
||||||
if (ec_key.get() == nullptr) {
|
if (ec_key.get() == nullptr) {
|
||||||
@@ -706,11 +736,10 @@ std::string getX509SubjectName(const X509_Ptr& cert) {
|
|||||||
|
|
||||||
// Validates the certificate chain and returns the leaf public key.
|
// Validates the certificate chain and returns the leaf public key.
|
||||||
ErrMsgOr<bytevec> validateCertChain(const cppbor::Array& chain) {
|
ErrMsgOr<bytevec> validateCertChain(const cppbor::Array& chain) {
|
||||||
uint8_t rawPubKey[64];
|
bytevec rawPubKey;
|
||||||
size_t rawPubKeySize = sizeof(rawPubKey);
|
|
||||||
for (size_t i = 0; i < chain.size(); ++i) {
|
for (size_t i = 0; i < chain.size(); ++i) {
|
||||||
// Root must be self-signed.
|
// Root must be self-signed.
|
||||||
size_t signingCertIndex = (i > 1) ? i - 1 : i;
|
size_t signingCertIndex = (i > 0) ? i - 1 : i;
|
||||||
auto& keyCertItem = chain[i];
|
auto& keyCertItem = chain[i];
|
||||||
auto& signingCertItem = chain[signingCertIndex];
|
auto& signingCertItem = chain[signingCertIndex];
|
||||||
if (!keyCertItem || !keyCertItem->asBstr()) {
|
if (!keyCertItem || !keyCertItem->asBstr()) {
|
||||||
@@ -724,7 +753,7 @@ ErrMsgOr<bytevec> validateCertChain(const cppbor::Array& chain) {
|
|||||||
if (!keyCert) {
|
if (!keyCert) {
|
||||||
return keyCert.message();
|
return keyCert.message();
|
||||||
}
|
}
|
||||||
auto signingCert = parseX509Cert(keyCertItem->asBstr()->value());
|
auto signingCert = parseX509Cert(signingCertItem->asBstr()->value());
|
||||||
if (!signingCert) {
|
if (!signingCert) {
|
||||||
return signingCert.message();
|
return signingCert.message();
|
||||||
}
|
}
|
||||||
@@ -749,17 +778,16 @@ ErrMsgOr<bytevec> validateCertChain(const cppbor::Array& chain) {
|
|||||||
return "Certificate " + std::to_string(i) + " has wrong issuer. Signer subject is " +
|
return "Certificate " + std::to_string(i) + " has wrong issuer. Signer subject is " +
|
||||||
signerSubj + " Issuer subject is " + certIssuer;
|
signerSubj + " Issuer subject is " + certIssuer;
|
||||||
}
|
}
|
||||||
|
if (i == chain.size() - 1) {
|
||||||
rawPubKeySize = sizeof(rawPubKey);
|
auto key = getRawPublicKey(pubKey);
|
||||||
if (!EVP_PKEY_get_raw_public_key(pubKey.get(), rawPubKey, &rawPubKeySize)) {
|
if (!key) key.moveMessage();
|
||||||
return "Failed to get raw public key.";
|
rawPubKey = key.moveValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return rawPubKey;
|
||||||
return bytevec(rawPubKey, rawPubKey + rawPubKeySize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string validateUdsCerts(const cppbor::Map& udsCerts, const bytevec& udsPub) {
|
std::string validateUdsCerts(const cppbor::Map& udsCerts, const bytevec& udsCoseKeyBytes) {
|
||||||
for (const auto& [signerName, udsCertChain] : udsCerts) {
|
for (const auto& [signerName, udsCertChain] : udsCerts) {
|
||||||
if (!signerName || !signerName->asTstr()) {
|
if (!signerName || !signerName->asTstr()) {
|
||||||
return "Signer Name must be a Tstr.";
|
return "Signer Name must be a Tstr.";
|
||||||
@@ -775,8 +803,31 @@ std::string validateUdsCerts(const cppbor::Map& udsCerts, const bytevec& udsPub)
|
|||||||
if (!leafPubKey) {
|
if (!leafPubKey) {
|
||||||
return leafPubKey.message();
|
return leafPubKey.message();
|
||||||
}
|
}
|
||||||
|
auto coseKey = CoseKey::parse(udsCoseKeyBytes);
|
||||||
|
if (!coseKey) return coseKey.moveMessage();
|
||||||
|
|
||||||
|
auto curve = coseKey->getIntValue(CoseKey::CURVE);
|
||||||
|
if (!curve) {
|
||||||
|
return "CoseKey must contain curve.";
|
||||||
|
}
|
||||||
|
bytevec udsPub;
|
||||||
|
if (curve == CoseKeyCurve::P256 || curve == CoseKeyCurve::P384) {
|
||||||
|
auto pubKey = coseKey->getEcPublicKey();
|
||||||
|
if (!pubKey) return pubKey.moveMessage();
|
||||||
|
// convert public key to uncompressed form by prepending 0x04 at begin.
|
||||||
|
pubKey->insert(pubKey->begin(), 0x04);
|
||||||
|
udsPub = pubKey.moveValue();
|
||||||
|
} else if (curve == CoseKeyCurve::ED25519) {
|
||||||
|
auto& pubkey = coseKey->getMap().get(cppcose::CoseKey::PUBKEY_X);
|
||||||
|
if (!pubkey || !pubkey->asBstr()) {
|
||||||
|
return "Invalid public key.";
|
||||||
|
}
|
||||||
|
udsPub = pubkey->asBstr()->value();
|
||||||
|
} else {
|
||||||
|
return "Unknown curve.";
|
||||||
|
}
|
||||||
if (*leafPubKey != udsPub) {
|
if (*leafPubKey != udsPub) {
|
||||||
return "Leaf public key in UDS certificat chain doesn't match UDS public key.";
|
return "Leaf public key in UDS certificate chain doesn't match UDS public key.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
Reference in New Issue
Block a user