Skip to main content

zlicenser_server/http/
enroll.rs

1use std::sync::Arc;
2
3use axum::{
4    Json,
5    extract::{Path, State},
6    http::StatusCode,
7    response::{IntoResponse, Response},
8};
9use serde::Serialize;
10use uuid::Uuid;
11
12use crate::issuance::handlers::{ConsentInput, HandlerContext, LicenseReceipt, LicenseRequest};
13use crate::storage::Storage;
14
15pub async fn request_handler<S: Storage + Clone + Send + Sync + 'static>(
16    State(ctx): State<Arc<HandlerContext<S>>>,
17    Json(req): Json<LicenseRequest>,
18) -> Response {
19    match crate::issuance::handlers::handle_license_request(&ctx, req).await {
20        Ok(offer) => (StatusCode::OK, Json(offer)).into_response(),
21        Err(e) => e.into_response(),
22    }
23}
24
25#[derive(serde::Deserialize)]
26pub struct ReceiptBody {
27    pub offer_nonce: Vec<u8>,
28    pub customer_signature: Vec<u8>,
29    pub consent: ConsentInput,
30}
31
32pub async fn receipt_handler<S: Storage + Clone + Send + Sync + 'static>(
33    State(ctx): State<Arc<HandlerContext<S>>>,
34    Path(session_id): Path<Uuid>,
35    Json(body): Json<ReceiptBody>,
36) -> Response {
37    let customer_signature: [u8; 64] = match body.customer_signature.try_into() {
38        Ok(sig) => sig,
39        Err(_) => return crate::Error::InvalidReceiptSignature.into_response(),
40    };
41    let receipt = LicenseReceipt {
42        offer_nonce: body.offer_nonce,
43        customer_signature,
44        consent: body.consent,
45    };
46    match crate::issuance::handlers::handle_license_receipt(&ctx, session_id, receipt).await {
47        Ok(grant) => {
48            #[derive(Serialize)]
49            struct GrantResponse {
50                license_id: String,
51                binding_cert_bytes: Vec<u8>,
52                tsa_token: Vec<u8>,
53                wrapped_ephemeral_pubkey: Option<Vec<u8>>,
54                wrapped_ciphertext: Option<Vec<u8>>,
55            }
56            (
57                StatusCode::OK,
58                Json(GrantResponse {
59                    license_id: grant.license_id.to_string(),
60                    binding_cert_bytes: grant.binding_cert.to_bytes(),
61                    tsa_token: grant.tsa_token,
62                    wrapped_ephemeral_pubkey: grant
63                        .wrapped_secret
64                        .as_ref()
65                        .map(|w| w.ephemeral_pubkey.to_vec()),
66                    wrapped_ciphertext: grant.wrapped_secret.map(|w| w.ciphertext),
67                }),
68            )
69                .into_response()
70        }
71        Err(e) => e.into_response(),
72    }
73}