Beispiel #1
0
static SigVerifyResult verify_signature_with_key(const char *path,
                                                 const char *sig_path,
                                                 EVP_PKEY &public_key)
{
    ScopedBIO bio_data_in(BIO_new_file(path, "rb"), BIO_free);
    if (!bio_data_in) {
        LOGE("%s: Failed to open input file", path);
        openssl_log_errors();
        return SigVerifyResult::Failure;
    }

    ScopedBIO bio_sig_in(BIO_new_file(sig_path, "rb"), BIO_free);
    if (!bio_sig_in) {
        LOGE("%s: Failed to open signature file", sig_path);
        openssl_log_errors();
        return SigVerifyResult::Failure;
    }

    auto ret = sign::verify_data(*bio_data_in, *bio_sig_in, public_key);
    if (!ret) {
        if (ret.error().ec == sign::Error::BadSignature) {
            return SigVerifyResult::Invalid;
        } else {
            LOGE("%s: Failed to verify signature: %s", sig_path,
                 ret.error().ec.message().c_str());
            if (ret.error().has_openssl_error) {
                openssl_log_errors();
            }
            return SigVerifyResult::Failure;
        }
    }

    return SigVerifyResult::Valid;
}
Beispiel #2
0
SigVerifyResult verify_signature(const char *path, const char *sig_path)
{
    for (const std::string &hex_der : valid_certs) {
        std::string der;
        if (!hex2bin(hex_der, der)) {
            LOGE("Failed to convert hex-encoded certificate to binary: %s",
                 hex_der.c_str());
            return SigVerifyResult::Failure;
        }

        // Cast to (void *) is okay since BIO_new_mem_buf() creates a read-only
        // BIO object
        ScopedBIO bio_x509_cert(BIO_new_mem_buf(
                der.data(), static_cast<int>(der.size())), BIO_free);
        if (!bio_x509_cert) {
            LOGE("Failed to create BIO for X509 certificate: %s",
                 hex_der.c_str());
            openssl_log_errors();
            return SigVerifyResult::Failure;
        }

        // Load DER-encoded certificate
        ScopedX509 cert(d2i_X509_bio(bio_x509_cert.get(), nullptr), X509_free);
        if (!cert) {
            LOGE("Failed to load X509 certificate: %s", hex_der.c_str());
            openssl_log_errors();
            return SigVerifyResult::Failure;
        }

        // Get public key from certificate
        ScopedEVP_PKEY public_key(X509_get_pubkey(cert.get()), EVP_PKEY_free);
        if (!public_key) {
            LOGE("Failed to load public key from X509 certificate: %s",
                 hex_der.c_str());
            openssl_log_errors();
            return SigVerifyResult::Failure;
        }

        SigVerifyResult result =
                verify_signature_with_key(path, sig_path, *public_key);
        if (result == SigVerifyResult::Invalid) {
            // Keep trying ...
            continue;
        }

        return result;
    }

    return SigVerifyResult::Invalid;
}
Beispiel #3
0
static bool generate_keys(ScopedEVP_PKEY &private_key_out,
                          ScopedEVP_PKEY &public_key_out)
{
    ScopedEVP_PKEY private_key(EVP_PKEY_new(), EVP_PKEY_free);
    ScopedEVP_PKEY public_key(EVP_PKEY_new(), EVP_PKEY_free);
    ScopedRSA rsa(RSA_new(), RSA_free);
    ScopedBIGNUM e(BN_new(), BN_free);

    if (!private_key) {
        LOGE("Failed to allocate private key");
        openssl_log_errors();
        return false;
    }

    if (!public_key) {
        LOGE("Failed to allocate public key");
        openssl_log_errors();
        return false;
    }

    if (!rsa) {
        LOGE("Failed to allocate RSA");
        openssl_log_errors();
        return false;
    }

    if (!e) {
        LOGE("Failed to allocate BIGNUM");
        openssl_log_errors();
        return false;
    }

    BN_set_word(e.get(), RSA_F4);

    if (RSA_generate_key_ex(rsa.get(), 2048, e.get(), nullptr) < 0) {
        LOGE("RSA_generate_key_ex() failed");
        openssl_log_errors();
        return false;
    }

    if (!EVP_PKEY_assign_RSA(private_key.get(), RSAPrivateKey_dup(rsa.get()))) {
        LOGE("EVP_PKEY_assign_RSA() failed for private key");
        openssl_log_errors();
        return false;
    }

    if (!EVP_PKEY_assign_RSA(public_key.get(), RSAPublicKey_dup(rsa.get()))) {
        LOGE("EVP_PKEY_assign_RSA() failed for public key");
        openssl_log_errors();
        return false;
    }

    private_key_out = std::move(private_key);
    public_key_out = std::move(public_key);
    return true;
}