this repo has no description
1use crate::state::AppState; 2use axum::{ 3 Json, 4 extract::State, 5 http::StatusCode, 6 response::{IntoResponse, Response}, 7}; 8use chrono::{Duration, Utc}; 9use k256::ecdsa::SigningKey; 10use serde::{Deserialize, Serialize}; 11use serde_json::json; 12use tracing::{error, info}; 13 14const SECP256K1_MULTICODEC_PREFIX: [u8; 2] = [0xe7, 0x01]; 15 16fn public_key_to_did_key(signing_key: &SigningKey) -> String { 17 let verifying_key = signing_key.verifying_key(); 18 let compressed_pubkey = verifying_key.to_sec1_bytes(); 19 let mut multicodec_key = Vec::with_capacity(2 + compressed_pubkey.len()); 20 multicodec_key.extend_from_slice(&SECP256K1_MULTICODEC_PREFIX); 21 multicodec_key.extend_from_slice(&compressed_pubkey); 22 let encoded = multibase::encode(multibase::Base::Base58Btc, &multicodec_key); 23 format!("did:key:{}", encoded) 24} 25 26#[derive(Deserialize)] 27pub struct ReserveSigningKeyInput { 28 pub did: Option<String>, 29} 30 31#[derive(Serialize)] 32#[serde(rename_all = "camelCase")] 33pub struct ReserveSigningKeyOutput { 34 pub signing_key: String, 35} 36 37pub async fn reserve_signing_key( 38 State(state): State<AppState>, 39 Json(input): Json<ReserveSigningKeyInput>, 40) -> Response { 41 let signing_key = SigningKey::random(&mut rand::thread_rng()); 42 let private_key_bytes = signing_key.to_bytes(); 43 let public_key_did_key = public_key_to_did_key(&signing_key); 44 let expires_at = Utc::now() + Duration::hours(24); 45 let private_bytes: &[u8] = &private_key_bytes; 46 let result = sqlx::query!( 47 r#" 48 INSERT INTO reserved_signing_keys (did, public_key_did_key, private_key_bytes, expires_at) 49 VALUES ($1, $2, $3, $4) 50 RETURNING id 51 "#, 52 input.did, 53 public_key_did_key, 54 private_bytes, 55 expires_at 56 ) 57 .fetch_one(&state.db) 58 .await; 59 match result { 60 Ok(row) => { 61 info!("Reserved signing key {} for did {:?}", row.id, input.did); 62 ( 63 StatusCode::OK, 64 Json(ReserveSigningKeyOutput { 65 signing_key: public_key_did_key, 66 }), 67 ) 68 .into_response() 69 } 70 Err(e) => { 71 error!("DB error in reserve_signing_key: {:?}", e); 72 ( 73 StatusCode::INTERNAL_SERVER_ERROR, 74 Json(json!({"error": "InternalError"})), 75 ) 76 .into_response() 77 } 78 } 79}