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 20 let mut multicodec_key = Vec::with_capacity(2 + compressed_pubkey.len()); 21 multicodec_key.extend_from_slice(&SECP256K1_MULTICODEC_PREFIX); 22 multicodec_key.extend_from_slice(&compressed_pubkey); 23 24 let encoded = multibase::encode(multibase::Base::Base58Btc, &multicodec_key); 25 26 format!("did:key:{}", encoded) 27} 28 29#[derive(Deserialize)] 30pub struct ReserveSigningKeyInput { 31 pub did: Option<String>, 32} 33 34#[derive(Serialize)] 35#[serde(rename_all = "camelCase")] 36pub struct ReserveSigningKeyOutput { 37 pub signing_key: String, 38} 39 40pub async fn reserve_signing_key( 41 State(state): State<AppState>, 42 Json(input): Json<ReserveSigningKeyInput>, 43) -> Response { 44 let signing_key = SigningKey::random(&mut rand::thread_rng()); 45 let private_key_bytes = signing_key.to_bytes(); 46 let public_key_did_key = public_key_to_did_key(&signing_key); 47 48 let expires_at = Utc::now() + Duration::hours(24); 49 50 let private_bytes: &[u8] = &private_key_bytes; 51 52 let result = sqlx::query!( 53 r#" 54 INSERT INTO reserved_signing_keys (did, public_key_did_key, private_key_bytes, expires_at) 55 VALUES ($1, $2, $3, $4) 56 RETURNING id 57 "#, 58 input.did, 59 public_key_did_key, 60 private_bytes, 61 expires_at 62 ) 63 .fetch_one(&state.db) 64 .await; 65 66 match result { 67 Ok(row) => { 68 info!( 69 "Reserved signing key {} for did {:?}", 70 row.id, 71 input.did 72 ); 73 ( 74 StatusCode::OK, 75 Json(ReserveSigningKeyOutput { 76 signing_key: public_key_did_key, 77 }), 78 ) 79 .into_response() 80 } 81 Err(e) => { 82 error!("DB error in reserve_signing_key: {:?}", e); 83 ( 84 StatusCode::INTERNAL_SERVER_ERROR, 85 Json(json!({"error": "InternalError"})), 86 ) 87 .into_response() 88 } 89 } 90}