11use chrono:: NaiveDateTime ;
2- use log:: error;
2+ use log:: { debug , error} ;
33use polyproto:: {
44 certs:: { PublicKeyInfo , idcert:: IdCert } ,
55 der:: Encode ,
@@ -10,7 +10,7 @@ use polyproto::{
1010use sqlx:: query;
1111
1212use crate :: {
13- database:: { AlgorithmIdentifier , Database , Issuer } ,
13+ database:: { AlgorithmIdentifier , Database , Issuer , SerialNumber } ,
1414 errors:: { ALGORITHM_IDENTIFER_TO_DER_ERROR_MESSAGE , Context , Error } ,
1515} ;
1616
@@ -82,23 +82,34 @@ impl HomeServerCert {
8282 . map ( Some )
8383 }
8484
85- /// Insert an [IdCert] into the database without performing validation
86- /// checks.
85+ /// Insert an [IdCert] into the database without performing __any__
86+ /// validation checks.
8787 ///
8888 /// This function bypasses certificate validation and directly inserts the
8989 /// certificate into the database. It extracts the signature algorithm
9090 /// information from the certificate and ensures it's supported by the
9191 /// server before insertion.
9292 ///
93- /// # Parameters
94- /// * `db` - Database connection reference
95- /// * `cert` - The [IdCert] to insert into the database
93+ /// ## ⚠️ Warning ⚠️
9694 ///
97- /// # Returns
95+ /// **Never** use this function standalone, without any additional
96+ /// verification. At least the following things must be ensured, before
97+ /// calling this function:
98+ ///
99+ /// 1. The entity trying to perform the INSERT operation is who they say
100+ /// they are, and are permitted to perform the operation
101+ /// 2. The [IdCert] is valid and well-formed.
102+ ///
103+ /// Calling this function without proper verification will likely enable an
104+ /// attack vector enabling hostile takeover of actor accounts or the entire
105+ /// home server altogether. The method exists purely to be used in
106+ /// conjunction with those steps.
107+ ///
108+ /// ## Returns
98109 /// * `Ok(())` if the certificate was successfully inserted
99110 /// * `Err(Error)` if the signature algorithm is unsupported or insertion
100111 /// fails
101- pub ( crate ) async fn insert_idcert_unchecked < S : Signature , P : PublicKey < S > > (
112+ pub ( super ) async fn insert_idcert_unchecked < S : Signature , P : PublicKey < S > > (
102113 db : & Database ,
103114 cert : IdCert < S , P > ,
104115 ) -> Result < ( ) , Error > {
@@ -135,6 +146,26 @@ impl HomeServerCert {
135146 let issuer = Issuer :: get_own ( db) . await ?. expect (
136147 "The issuer entry for this sonata instance should have been added to the database on startup!" ,
137148 ) ;
149+ let cert_serial = SerialNumber :: from ( cert. id_cert_tbs . serial_number ) ;
150+ if query ! (
151+ "SELECT serial_number FROM idcsr WHERE serial_number = $1" ,
152+ cert_serial. as_bigdecimal( )
153+ )
154+ . fetch_optional ( & db. pool )
155+ . await ?
156+ . is_some ( )
157+ {
158+ debug ! (
159+ "ID-Cert with serial_number {} already exists; aborting" ,
160+ cert_serial. as_bigdecimal( )
161+ ) ;
162+ return Err ( Error :: new_duplicate_error ( Some ( & format ! (
163+ "An ID-Cert with serial number {} already exists" ,
164+ cert_serial. as_bigdecimal( )
165+ ) ) ) ) ;
166+ } ;
167+ // TODO: get pem_encoded string of cert and then I think we can actually insert
168+ // it into the DB!
138169 todo ! ( )
139170 }
140171}
0 commit comments