fix(gamestream): generate the RSA host identity via the rsa crate, not rcgen (ring can't RSA-keygen)
apple / screenshots (push) Successful in 6m30s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 7m54s
android / android (push) Successful in 13m24s
windows-host / package (push) Successful in 18m37s
deb / build-publish (push) Successful in 12m42s
arch / build-publish (push) Successful in 16m12s
ci / rust (push) Successful in 27m16s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 20m18s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m29s
docker / deploy-docs (push) Successful in 27s
ci / web (push) Successful in 1m22s
apple / swift (push) Successful in 1m27s
ci / docs-site (push) Successful in 1m29s
decky / build-publish (push) Successful in 26s
ci / bench (push) Successful in 6m16s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 12s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 12s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 11s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 14s
apple / screenshots (push) Successful in 6m30s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 7m54s
android / android (push) Successful in 13m24s
windows-host / package (push) Successful in 18m37s
deb / build-publish (push) Successful in 12m42s
arch / build-publish (push) Successful in 16m12s
ci / rust (push) Successful in 27m16s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 20m18s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m29s
docker / deploy-docs (push) Successful in 27s
ci / web (push) Successful in 1m22s
apple / swift (push) Successful in 1m27s
ci / docs-site (push) Successful in 1m29s
decky / build-publish (push) Successful in 26s
ci / bench (push) Successful in 6m16s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 12s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 12s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 11s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 14s
The workspace went ring-only in 0.13.0 (aws-lc-sys breaks Windows CI), and
`ring` can sign with an existing RSA key but cannot *generate* one —
rcgen's ring backend returns `KeyGenerationUnavailable` for
`generate_for(&PKCS_RSA_SHA256)`. So `ServerIdentity::{load_or_create,
ephemeral}` panics with "rcgen RSA keygen / There is no support for
generating keys for the given algorithm" on any host without an existing
`cert.pem`. This is the shared trust root for both the GameStream TLS cert
and the QUIC identity clients pin, so a *fresh* 0.13.0 install can't start
the host at all (existing dev boxes survive only because they already have
a cert on disk); in CI every test that builds a `ServerIdentity` (all of
`mgmt::tests`, `gamestream::nvhttp`, and the `native::tests` synthetic host
via `serve()`) failed — 30 failures from this one cause.
Moonlight requires an RSA-2048 identity, so generate the key with the
pure-Rust `rsa` crate (already a dependency for the pairing signer) and
hand its PKCS#8 PEM to rcgen, whose ring backend *can* load and self-sign
with an externally supplied RSA key (`from_pkcs8_pem_and_sign_algo` →
`RsaKeyPair::from_pkcs8`). Return that same PEM so it stays byte-identical
to what `from_pems` re-parses.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use pf_paths::config_dir;
|
use pf_paths::config_dir;
|
||||||
use rsa::pkcs1v15::SigningKey;
|
use rsa::pkcs1v15::SigningKey;
|
||||||
use rsa::pkcs8::DecodePrivateKey;
|
use rsa::pkcs8::{DecodePrivateKey, EncodePrivateKey, LineEnding};
|
||||||
use rsa::RsaPrivateKey;
|
use rsa::RsaPrivateKey;
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@@ -70,7 +70,20 @@ impl ServerIdentity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate() -> Result<(String, String)> {
|
fn generate() -> Result<(String, String)> {
|
||||||
let key = rcgen::KeyPair::generate_for(&rcgen::PKCS_RSA_SHA256).context("rcgen RSA keygen")?;
|
// The workspace is ring-only (aws-lc-sys breaks Windows CI — see the rustls/rcgen pins), and
|
||||||
|
// `ring` can *sign* with an existing RSA key but cannot *generate* one: rcgen's ring backend
|
||||||
|
// returns `KeyGenerationUnavailable` for `generate_for(&PKCS_RSA_SHA256)`. Moonlight requires an
|
||||||
|
// RSA-2048 identity, so generate the key with the pure-Rust `rsa` crate (already a dep for the
|
||||||
|
// pairing signer) and hand the PKCS#8 PEM to rcgen, whose ring backend *can* load + self-sign
|
||||||
|
// with it. Returning that same PEM keeps it byte-identical to what `from_pems` re-parses.
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let priv_key = RsaPrivateKey::new(&mut rng, 2048).context("generate RSA-2048 host key")?;
|
||||||
|
let key_pem = priv_key
|
||||||
|
.to_pkcs8_pem(LineEnding::LF)
|
||||||
|
.context("encode host key as PKCS#8 PEM")?
|
||||||
|
.to_string();
|
||||||
|
let key = rcgen::KeyPair::from_pkcs8_pem_and_sign_algo(&key_pem, &rcgen::PKCS_RSA_SHA256)
|
||||||
|
.context("load RSA host key into rcgen")?;
|
||||||
let mut params = rcgen::CertificateParams::new(Vec::<String>::new()).context("cert params")?;
|
let mut params = rcgen::CertificateParams::new(Vec::<String>::new()).context("cert params")?;
|
||||||
params
|
params
|
||||||
.distinguished_name
|
.distinguished_name
|
||||||
@@ -78,7 +91,7 @@ fn generate() -> Result<(String, String)> {
|
|||||||
params.not_before = rcgen::date_time_ymd(2020, 1, 1);
|
params.not_before = rcgen::date_time_ymd(2020, 1, 1);
|
||||||
params.not_after = rcgen::date_time_ymd(2040, 1, 1);
|
params.not_after = rcgen::date_time_ymd(2040, 1, 1);
|
||||||
let cert = params.self_signed(&key).context("self-sign cert")?;
|
let cert = params.self_signed(&key).context("self-sign cert")?;
|
||||||
Ok((cert.pem(), key.serialize_pem()))
|
Ok((cert.pem(), key_pem))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the X.509 `signatureValue` bytes from a cert PEM.
|
/// Extract the X.509 `signatureValue` bytes from a cert PEM.
|
||||||
|
|||||||
Reference in New Issue
Block a user