Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e77e5eb2 authored by Andrew Scull's avatar Andrew Scull Committed by Automerger Merge Worker
Browse files

Merge "Support to get EC public key from the UdsCertchain." into...

Merge "Support to get EC public key from the UdsCertchain." into stage-aosp-udc-ts-dev am: 1dc9c9f7

Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/interfaces/+/23895312



Change-Id: Iecf480d38a522a00474b34f3fb1f52c04e224fa0
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents b74b27e0 1dc9c9f7
Loading
Loading
Loading
Loading
+63 −12
Original line number Original line Diff line number Diff line
@@ -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 "";