| Crates.io | playready-macros |
| lib.rs | playready-macros |
| version | 0.2.1 |
| created_at | 2025-02-10 18:17:38.235248+00 |
| updated_at | 2025-06-30 16:30:34.924078+00 |
| description | Implementation of PlayReady DRM system based on pyplayready (helper macros) |
| homepage | https://codeberg.org/dobo/playready-rs |
| repository | https://codeberg.org/dobo/playready-rs |
| max_upload_size | |
| id | 1550481 |
| size | 8,076 |
Rust port of pyplayready.
As a proof of concept it has been integrated with Kodi. Implementation is available on fork of inputstream.adaptive.
use isahc::{ReadResponseExt, Request, RequestExt};
use playready::{cdm::Cdm, Device, Pssh};
const TEST_PSSH: &str = concat!(
"AAADfHBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAA1xcAwAAAQABAFIDPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AH",
"QAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABh",
"AHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUg",
"BPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQA",
"UgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgA0AFIAcABsAGIAKwBUAGIATgBFAFMAOAB0AE",
"cAawBOAEYAVwBUAEUASABBAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEsATABqADMAUQB6AFEAUAAvAE4AQQA9ADwALwBD",
"AEgARQBDAEsAUwBVAE0APgA8AEwAQQBfAFUAUgBMAD4AaAB0AHQAcABzADoALwAvAHAAcgBvAGYAZgBpAGMAaQBhAGwAcwBpAHQAZQAuAGsAZQ",
"B5AGQAZQBsAGkAdgBlAHIAeQAuAG0AZQBkAGkAYQBzAGUAcgB2AGkAYwBlAHMALgB3AGkAbgBkAG8AdwBzAC4AbgBlAHQALwBQAGwAYQB5AFIA",
"ZQBhAGQAeQAvADwALwBMAEEAXwBVAFIATAA+ADwAQwBVAFMAVABPAE0AQQBUAFQAUgBJAEIAVQBUAEUAUwA+ADwASQBJAFMAXwBEAFIATQBfAF",
"YARQBSAFMASQBPAE4APgA4AC4AMQAuADIAMwAwADQALgAzADEAPAAvAEkASQBTAF8ARABSAE0AXwBWAEUAUgBTAEkATwBOAD4APAAvAEMAVQBT",
"AFQATwBNAEEAVABUAFIASQBCAFUAVABFAFMAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==");
const TEST_SERVER_URL: &str =
"https://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(persist:false,sl:2000)";
fn main() {
let device = Device::from_prd("device.prd").unwrap();
println!("Device: {}", device.name().unwrap());
println!("Security level: {}", device.security_level().unwrap());
println!("Device verification: {:?}", device.verify());
let pssh = Pssh::from_b64(TEST_PSSH.as_bytes()).unwrap();
let wrm_header = pssh.wrm_headers()[0].clone();
let cdm = Cdm::from_device(device);
let session = cdm.open_session();
let challenge = session.get_license_challenge(wrm_header).unwrap();
let request = Request::post(TEST_SERVER_URL)
.header("Content-Type", "text/xml; charset=utf-8")
.body(challenge)
.unwrap();
let response = String::from_utf8(request.send().unwrap().bytes().unwrap()).unwrap();
let keys = session
.get_keys_from_challenge_response(response.as_str())
.unwrap();
println!("Content keys:");
for (kid, ck) in &keys {
println!("{}:{}", kid, ck);
}
}
If you want to test your .prd file by connecting to Microsoft's test server, run:
$ cd crates/playready-cli
$ cargo run test-device /path/to/device.prd
[*] Device: Test Device
[*] Security level: 0000
[*] Device verification: successful
[*] Content keys:
[*] xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
To create new .prd device run:
$ cd crates/playready-cli
$ cargo run create-device -c /path/to/bgroupcert.dat -k /path/to/zgpriv.dat -o /path/to/output_device.prd
[*] Trying to provision device
[*] Provisioned successfully
[*] Device: Test Device
[*] Security level: 0000
In order to reprovision device:
$ cd crates/playready-cli
$ cargo run reprovision-device /path/to/device.prd
[*] Device: Test Device
[*] Security level: 0000
[*] Reprovisioned successfully
Available at CodeBerg Pages and docs.rs.